⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 terrain.cpp

📁 小型的3D游戏引擎
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		normalArray[j+1] = normal.y;
		normalArray[j+2] = normal.z;
		
		sum = zero;
		shared = 0;
		j += 3;
	}

	glEnableClientState(GL_NORMAL_ARRAY);

	delete [] tempNormal;
}

///////////////////////////////////////////////////////////////////////////////

void GcTerrain::InitFogArray()
{
	unsigned int x, z, i = 0;
	int height;
	int y;

	// Create the fog array
	fogCoordArray = (float*)memPool.Allocate(mapWidth * mapWidth * sizeof(float));

	// Init fog array
	for(z = 0; z < mapWidth; z++)
	{
		for(x = 0; x < mapWidth; x++)
		{
			// Get the hegiht
			height = Height(x * scale, z * scale);

			// Calculate the fog depth at the curretn vertex
			if(height > GcSettings::FogDepth()) { //settings.FogDepth()) {
				y = 0;
			}
			else {
				y = -(height - GcSettings::FogDepth()); //settings.FogDepth());
			}

			// Save it in the array
			fogCoordArray[i] = y;

			i++;
		}
	}
}

///////////////////////////////////////////////////////////////////////////////

void GcTerrain::InitNodes(GcQuadtree *tree)
{
	uint			count = 0;
	uint			numNodesSide;
	GcVector3		ext;
	GcVector3		trans;
	GcTerrainNode	*node;

	// Calculate the square width based on info from the quadtree
	squareWidth = tree->GetLeafSide() / scale + 1;

	// Calculate the nuber of vertices in one node
	numVertex = squareWidth * squareWidth * 2;

	// Calculate the number of nodes on one side
	numNodesSide = mapWidth / (squareWidth - 1);

	// Allocate memory for the nodes
	//nodeList = new GcTerrainNode[(numNodesSide - 1) * (numNodesSide - 1)];

	// Calculate the dimensions of the aabb
	ext.x = ((squareWidth - 1) / 2) * scale;
	ext.y = (255 / 2) * scale;
	ext.z = ((squareWidth - 1) / 2) * scale;

	// Loop throught all nodes and fill them with data
	for(int i = 0; i < numNodesSide - 1; i++)
	{
		for(int j = 0; j < numNodesSide - 1; j++)
		{
			int x = j * (squareWidth - 1);
			int y = i * (squareWidth - 1);

			// Allocate the node (can do it like this since the 
			// quadtree takes care of deleting it)
			node = new GcTerrainNode;

			// Give the node a link to the terrain class (this one)
			node->SetTerrain(this);

			// Save the array position to the node
			node->SetArrayPosition((y*mapWidth) + x);
			
			// Save the dimensions to the aabb
			node->SetExtents(ext);

			// Calculate the translation for the aabb
			trans.x = (x * scale);
			trans.y = 0;
			trans.z = (y * scale);

			// Save the translation to the aabb
			node->SetTranslation(trans);

			// Attach the node to the quadtree
			tree->AttachNode(node);
		}
	}
}

///////////////////////////////////////////////////////////////////////////////

void GcTerrain::RenderSquare(uint arrayPos, uint ssquareWidth, uint squareHeight)
{
	int i = 0;

	// One more square drawn
	drawnSquares++;

	// Set the array positions
	if(GcSettings::Light())
	{
		glNormalPointer(GL_FLOAT, 0, normalArray + arrayPos * 3);
	}

	if(GcSettings::ColorArray())
	{
		glColorPointer(3, GL_FLOAT, 0, colorArray + arrayPos * 3);
	}
	
	// Do the texturining (multitexturing if supported for details)
	SetupTexture(true);

	if(GcSettings::MultiTexture())
	{
		glClientActiveTextureARB(GL_TEXTURE0_ARB);
		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
		glTexCoordPointer(2, GL_FLOAT, 0, textArray + arrayPos * 2);

		glClientActiveTextureARB(GL_TEXTURE1_ARB);
		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
		glTexCoordPointer(2, GL_FLOAT, 0, textArray + arrayPos * 2);
	}
	else
	{
		glTexCoordPointer(2, GL_FLOAT, 0, textArray + arrayPos * 2);
	}

	// Apply the fog
	if(GcSettings::Fog())
	{
		glFogCoordPointerEXT(GL_FLOAT, 0, fogCoordArray + arrayPos);
	}

	// Give OpenGL the address to the vertex array
	glVertexPointer(3, GL_FLOAT, 0, vertexArray + arrayPos * 3); 


	// Render the square of terrain
	for(i = 0; i < squareWidth; i++)
	{
			glDrawElements(GL_TRIANGLE_STRIP, (squareWidth) * 2, 
						   GL_UNSIGNED_SHORT, &index[i * squareWidth * 2]);
			drawnTri += squareWidth * 2;
	}

	// Turn off multitexturing
	SetupTexture(false);
}

///////////////////////////////////////////////////////////////////////////////

void GcTerrain::RenderSquareImmediate(uint sx, uint sz)
{
	unsigned int	x = 0, z = 0;						// Looping vars
	float			vX = 0.0f, vZ = 0.0f, vY = 0.0f;	// Vertex possitions

	// One more square drawn
	drawnSquares++;

	// Set up the texturing
	SetupTexture(true);
	
	for(x = 0; x < squareWidth - 1; x++)
	{
		// Render the landscape
		glBegin(GL_TRIANGLE_STRIP);

		// Render the col from bottom to top
		for(z = 0; z < squareWidth; z++)
		{
			// Sett the cordinates for the bottom right vertex
			vX = (x + 1) * scale + sx;
			vZ = z * scale + sz;
			vY = Height(vX, vZ);
			
			// Set the texture and fog cords
			SetFogCoord(vY);
			SetTexCoord(vX, vZ);
			
			// Render the bottom right vertex
			glVertex3f(vX, vY, vZ);


			// Sett the cordinates for the bottom left vertex
			vX = x * scale + sx;
			vZ = z * scale + sz;
			vY = Height(vX , vZ);

			// Set the texture and fog cords
			SetFogCoord(vY);
			SetTexCoord(vX, vZ);

			// Render the bottom left vertex
			glVertex3f(vX, vY, vZ);
		}
		
		drawnTri += (squareWidth - 1) * 2;

		// Done rendering the tristrip
		glEnd();
	}

	// Turn off the texturing
	SetupTexture(false);
}

///////////////////////////////////////////////////////////////////////////////

void GcTerrain::SetTexCoord(float sx, float sz)
{
	// Calculate the coordinate
	float x =  (float)sx / ((float)mapWidth * scale);
	float z = -(float)sz / ((float)mapWidth * scale);

	// Give the coord to ogl
	if(GcSettings::MultiTexture()) {
		glMultiTexCoord2fARB(GL_TEXTURE0_ARB, x, z);
		glMultiTexCoord2fARB(GL_TEXTURE1_ARB, x, z);
	}
	else {
		glTexCoord2f(x,z);
	}
}

///////////////////////////////////////////////////////////////////////////////

void GcTerrain::SetupTexture(bool activate)
{
	if(GcSettings::MultiTexture())
	{
		if(activate == true)
		{
			// Set up for multi texturing
			glActiveTextureARB(GL_TEXTURE0_ARB);
			glEnable(GL_TEXTURE_2D);
			landTexture.Bind();

			glActiveTextureARB(GL_TEXTURE1_ARB);
			glEnable(GL_TEXTURE_2D);

			// Combine the two textures into one
			glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
			glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 2);

			detailTexture.Bind();

			glMatrixMode(GL_TEXTURE);
				
				glLoadIdentity();
				glScalef(GcSettings::TexDetail(),
						 GcSettings::TexDetail(),
						 GcSettings::TexDetail());

			glMatrixMode(GL_MODELVIEW);
		}
		else
		{
			// Turn multi texturing off
			glActiveTextureARB(GL_TEXTURE1_ARB);
			glDisable(GL_TEXTURE_2D);

			glActiveTextureARB(GL_TEXTURE0_ARB);
			glDisable(GL_TEXTURE_2D);
		}
	}
	else
	{
		landTexture.Bind();
	}
}

///////////////////////////////////////////////////////////////////////////////

void GcTerrain::SetFogCoord(float height)
{
	float y = 0;

	if(GcSettings::Fog())
	{
		// Make sure that no fog is putt on higher ground
		if(height > GcSettings::FogDepth()) {
			y = 0;
		}
		else {
			y = -(height - GcSettings::FogDepth());
		}

		// Pass the coordinate to OpenGL
		glFogCoordfEXT(y);
	}
}

///////////////////////////////////////////////////////////////////////////////

uint GcTerrain::CalcMemReq()
{
	// Calculate the memory req for the mem pool

	uint memPoolSize = mapWidth * mapWidth * 3 * sizeof(float) + 
					   mapWidth * mapWidth * 2 * sizeof(float);

	if(GcSettings::ColorArray()) {
		memPoolSize	+= mapWidth * mapWidth * 3 * sizeof(float);
	}

	if(GcSettings::Light()) {
		memPoolSize += mapWidth * mapWidth * 3 * sizeof(float);
	}

	if(GcSettings::Fog()) {
		memPoolSize += mapWidth * mapWidth * sizeof(float);
	}

	return memPoolSize;
}

///////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -