www.pudn.com > ÈýάÌì¿ÕÓëµØÐÎ.zip > SkyDome.cpp, change:2001-10-15,size:5209b


// SkyDome Demo  -  October 2001 
// 
// Luis R. Sempé 
// visual@spheregames.com 
// Sphere Games (http://www.spheregames.com) 
//  
// You may use, copy, distribute or create derivative software 
// for any purpose. If you do, I'd appreciate it if you write me  
// and let me know what you do with it. Thanks! 
// Have fun! 
//////////////////////////////////////////////////// 
 
#include <math.h> 
 
#include "globals.h" 
#include "SkyDome.h" 
 
VERTEX *Vertices; 
int NumVertices; 
 
void GenerateDome(float radius, float dtheta, float dphi, float hTile, float vTile) 
{ 
	int theta, phi; 
 
	// Make sure our vertex array is clear 
	if (Vertices)  
	{ 
		delete Vertices; 
		Vertices = NULL; 
		NumVertices = 0; 
	} 
 
	// Initialize our Vertex array 
	NumVertices = (int)((360/dtheta)*(90/dphi)*4); 
	Vertices = new VERTEX[NumVertices]; 
	ZeroMemory(Vertices, sizeof(VERTEX)*NumVertices); 
 
	// Used to calculate the UV coordinates 
	float vx, vy, vz, mag; 
 
	// Generate the dome 
	int n = 0; 
	for (phi=0; phi <= 90 - dphi; phi += (int)dphi) 
	{ 
		for (theta=0; theta <= 360 - dtheta; theta += (int)dtheta) 
		{ 
			// Calculate the vertex at phi, theta 
			Vertices[n].x = radius * sinf(phi*DTOR) * cosf(DTOR*theta); 
			Vertices[n].y = radius * sinf(phi*DTOR) * sinf(DTOR*theta); 
			Vertices[n].z = radius * cosf(phi*DTOR); 
 
			// Create a vector from the origin to this vertex 
			vx = Vertices[n].x; 
			vy = Vertices[n].y; 
			vz = Vertices[n].z; 
 
			// Normalize the vector 
			mag = (float)sqrt(SQR(vx)+SQR(vy)+SQR(vz)); 
			vx /= mag; 
			vy /= mag; 
			vz /= mag; 
 
			// Calculate the spherical texture coordinates 
			Vertices[n].u = hTile * (float)(atan2(vx, vz)/(PI*2)) + 0.5f; 
			Vertices[n].v = vTile * (float)(asinf(vy) / PI) + 0.5f;		 
			n++; 
 
			// Calculate the vertex at phi+dphi, theta 
			Vertices[n].x = radius * sinf((phi+dphi)*DTOR) * cosf(theta*DTOR); 
			Vertices[n].y = radius * sinf((phi+dphi)*DTOR) * sinf(theta*DTOR); 
			Vertices[n].z = radius * cosf((phi+dphi)*DTOR); 
			 
			// Calculate the texture coordinates 
			vx = Vertices[n].x; 
			vy = Vertices[n].y; 
			vz = Vertices[n].z; 
 
			mag = (float)sqrt(SQR(vx)+SQR(vy)+SQR(vz)); 
			vx /= mag; 
			vy /= mag; 
			vz /= mag; 
 
			Vertices[n].u = hTile * (float)(atan2(vx, vz)/(PI*2)) + 0.5f; 
			Vertices[n].v = vTile * (float)(asinf(vy) / PI) + 0.5f;		 
			n++; 
 
			// Calculate the vertex at phi, theta+dtheta 
			Vertices[n].x = radius * sinf(DTOR*phi) * cosf(DTOR*(theta+dtheta)); 
			Vertices[n].y = radius * sinf(DTOR*phi) * sinf(DTOR*(theta+dtheta)); 
			Vertices[n].z = radius * cosf(DTOR*phi); 
			 
			// Calculate the texture coordinates 
			vx = Vertices[n].x; 
			vy = Vertices[n].y; 
			vz = Vertices[n].z; 
 
			mag = (float)sqrt(SQR(vx)+SQR(vy)+SQR(vz)); 
			vx /= mag; 
			vy /= mag; 
			vz /= mag; 
 
			Vertices[n].u = hTile * (float)(atan2(vx, vz)/(PI*2)) + 0.5f; 
			Vertices[n].v = vTile * (float)(asinf(vy) / PI) + 0.5f;		 
			n++; 
 
			if (phi > -90 && phi < 90) 
			{ 
				// Calculate the vertex at phi+dphi, theta+dtheta 
				Vertices[n].x = radius * sinf((phi+dphi)*DTOR) * cosf(DTOR*(theta+dtheta)); 
				Vertices[n].y = radius * sinf((phi+dphi)*DTOR) * sinf(DTOR*(theta+dtheta)); 
				Vertices[n].z = radius * cosf((phi+dphi)*DTOR); 
				 
				// Calculate the texture coordinates 
				vx = Vertices[n].x; 
				vy = Vertices[n].y; 
				vz = Vertices[n].z; 
 
				mag = (float)sqrt(SQR(vx)+SQR(vy)+SQR(vz)); 
				vx /= mag; 
				vy /= mag; 
				vz /= mag; 
 
				Vertices[n].u = hTile * (float)(atan2(vx, vz)/(PI*2)) + 0.5f; 
				Vertices[n].v = vTile * (float)(asinf(vy) / PI) + 0.5f;		 
				n++; 
			} 
		} 
	} 
 
	// Fix the problem at the seam 
	for (int i=0; i < NumVertices-3; i++) 
	{ 
		if (Vertices[i].u - Vertices[i+1].u > 0.9f) 
			Vertices[i+1].u += 1.0f; 
 
		if (Vertices[i+1].u - Vertices[i].u > 0.9f) 
			Vertices[i].u += 1.0f; 
 
		if (Vertices[i].u - Vertices[i+2].u > 0.9f) 
			Vertices[i+2].u += 1.0f; 
 
		if (Vertices[i+2].u - Vertices[i].u > 0.9f) 
			Vertices[i].u += 1.0f; 
 
		if (Vertices[i+1].u - Vertices[i+2].u > 0.9f) 
			Vertices[i+2].u += 1.0f; 
 
		if (Vertices[i+2].u - Vertices[i+1].u > 0.9f) 
			Vertices[i+1].u += 1.0f; 
 
		if (Vertices[i].v - Vertices[i+1].v > 0.8f) 
			Vertices[i+1].v += 1.0f; 
 
		if (Vertices[i+1].v - Vertices[i].v > 0.8f) 
			Vertices[i].v += 1.0f; 
 
		if (Vertices[i].v - Vertices[i+2].v > 0.8f) 
			Vertices[i+2].v += 1.0f; 
 
		if (Vertices[i+2].v - Vertices[i].v > 0.8f) 
			Vertices[i].v += 1.0f; 
 
		if (Vertices[i+1].v - Vertices[i+2].v > 0.8f) 
			Vertices[i+2].v += 1.0f; 
 
		if (Vertices[i+2].v - Vertices[i+1].v > 0.8f) 
			Vertices[i+1].v += 1.0f; 
	} 
} 
 
int RenderSkyDome() 
{ 
	glPushMatrix(); 
	glTranslatef(0.0f, -100.0f, 0.0f); 
	glRotatef(timeGetTime()/2000.0f,0.0f, 1.0f, 0.0f); 
	glRotatef(270, 1.0f, 0.0f, 0.0f); 
 
	glBegin(GL_TRIANGLE_STRIP); 
 
	for (int i=0; i < NumVertices; i++) 
	{ 
		glColor3f(1.0f, 1.0f, 1.0f); 
 
		glTexCoord2f(Vertices[i].u, Vertices[i].v); 
		glVertex3f(Vertices[i].x, Vertices[i].y, Vertices[i].z); 
	} 
 
	glEnd(); 
 
	glPopMatrix(); 
	return 1; 
} 
 
void ReleaseDome() 
{ 
	if (Vertices) 
	{ 
		delete Vertices; 
		Vertices = NULL; 
	} 
}