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

📄 landscape.cpp

📁 c++程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
		
				// Activate the landscape texture
				if (m_TextureCount != -1)
					m_TextureList[0].Use();

				// Set the triangle vertices based on the surface array
				glBegin(GL_TRIANGLES);
					
					for (unsigned int iY=iTileY * m_TilesPerSector; iY<=(iTileY + 1) * m_TilesPerSector - 1 && iY<=m_ArrayHeight-1; iY++)
					{
						// Set Y texture coord index
						iTexCoordY = iY % m_TilesPerTexture;

						for (unsigned int iX=iTileX * m_TilesPerSector; iX<=(iTileX + 1) * m_TilesPerSector - 1 && iX<=m_ArrayWidth-1; iX++)
						{
							// Set X texture coord index
							iTexCoordX = iX % m_TilesPerTexture;
								
							// Set vertices, normals and texture coordinates for the first triangle
							glTexCoord2f((float) iTexCoordX / m_TilesPerTexture, 
								(float) iTexCoordY / m_TilesPerTexture);
							glNormal3fv(cVertexNormals->m_Array[iX][iY]);
							glVertex3fv(cTriangles[iX][iY][0].m_Vertices[0]);

							glTexCoord2f(((float) iTexCoordX  + 1.0f) / m_TilesPerTexture, 
								((float) iTexCoordY  + 1.0f) / m_TilesPerTexture);
							glNormal3fv(cVertexNormals->m_Array[iX+1][iY+1]);
							glVertex3fv(cTriangles[iX][iY][0].m_Vertices[1]);

							glTexCoord2f((float) iTexCoordX / m_TilesPerTexture, 
								(float) (iTexCoordY + 1.0f) / m_TilesPerTexture);
							glNormal3fv(cVertexNormals->m_Array[iX][iY+1]);
							glVertex3fv(cTriangles[iX][iY][0].m_Vertices[2]);
									
							// Set vertices, normals and texture coordinates for the second triangle
							glTexCoord2f((float) (iTexCoordX  + 1.0f) / m_TilesPerTexture, 
								(float) iTexCoordY / m_TilesPerTexture);
							glNormal3fv(cVertexNormals->m_Array[iX+1][iY]);
							glVertex3fv(cTriangles[iX][iY][1].m_Vertices[0]);

							glTexCoord2f(((float) iTexCoordX  + 1.0f) / m_TilesPerTexture, 
								((float) iTexCoordY  + 1.0f) / m_TilesPerTexture);
							glNormal3fv(cVertexNormals->m_Array[iX+1][iY+1]);
							glVertex3fv(cTriangles[iX][iY][1].m_Vertices[1]);

							glTexCoord2f((float) iTexCoordX / m_TilesPerTexture, 
								(float) iTexCoordY / m_TilesPerTexture);
							glNormal3fv(cVertexNormals->m_Array[iX][iY]);
							glVertex3fv(cTriangles[iX][iY][1].m_Vertices[2]);
						}
					}

				glEnd();

			glEndList();
		}
		
		// Textures were disabled, restore state
		if (m_TextureCount == -1)
			glPopAttrib();
}

void CLandscape::LoadHeightmap(const char sHeightMapFileName[])
{
	// Load the passed terrain heightmap file and fill the surface height array
	// with it. The m_ArrayHeight and m_ArrayWidth member variables need to be set.

	// Load heightmap as a monochrome bitmap and select it into the heightmap DC
	HBITMAP hBitmap = (HBITMAP) LoadImage(NULL, sHeightMapFileName, IMAGE_BITMAP,
		0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION | LR_MONOCHROME);
	HDC hDC = CreateCompatibleDC(GetWindowDC(GetActiveWindow()));
	HGDIOBJ hOldObject = SelectObject(hDC, hBitmap);

	// Fill surface array with height values
	for (unsigned int iCols=0; iCols<=m_ArrayWidth; iCols++)
		for (unsigned int iRows=0; iRows<=m_ArrayHeight; iRows++)
		{
			// Get color at a given point on the heightmap
			COLORREF iColor = GetPixel(hDC, iCols, iRows);
			// Convert color to height value and set it. Only get the red
			// color component because in a grayscale image RGB are always equal.
			// Scale the height value so that it fits to the step size and the 
			// scaling constant.
			m_Surface->m_Array[iCols][iRows] = (float) RGB_GETRED(iColor) / 
				(255.0f / (m_StepSize * m_HeightMapHeightScaling));
		}

	// Destroy height map
	SelectObject(hDC, hOldObject);	// Select old object back into the DC
	DeleteObject(hBitmap);			// Delete heightmap
	DeleteDC(hDC);					// Delete heightmap DC
}

void CLandscape::DrawLandscape(float fYRotation, float fXViewer, float fYViewer, float fZViewer)
{
	// Call display list for the landscape

	for (unsigned int iCurSektor=m_LandscapeList; iCurSektor<=m_LandscapeList + (m_ArrayWidth / m_TilesPerSector) * (m_ArrayHeight / m_TilesPerSector) + 14; iCurSektor++)
		glCallList(iCurSektor);
}

bool CLandscape::RegisterTexture(char sFileName[])
{
	// Registers a new landscape texture

	// Has the maximum of loadable textures been reached ?
	if (m_TextureCount >= MAX_TEXTURE_COUNT)
		return FALSE;

	// Load & add the new texture
	if (m_TextureCount == -1)
	{
		// First texture
		m_TextureCount = 0;
		m_TextureList[m_TextureCount].LoadBMP(sFileName);
	}
	else
	{
		// Already one or more Texture(s) present
		m_TextureCount++;
		m_TextureList[m_TextureCount].LoadBMP(sFileName);
	}

	// Texture succesful added
	return TRUE;
}

int CLandscape::Rnd(int iMax)
{
	// Return an integer with a value between 0 and iMax
	return ((rand() * iMax) / RAND_MAX);
}

float CLandscape::GetSurfaceHeight(float fX, float fY)
{
	// Get the height of the surface at a given point

	// Has a surface been calculated ?
	if (!m_Surface)
		return -1.0f;

	// Is the given point on the surface ?
	if (fX < 0.0f ||
	fY < 0.0f ||
	fX > m_StepSize * m_ArrayWidth ||
	fY > m_StepSize * m_ArrayHeight)
		return -1.0f;

	// Get the four nearest height values
	float fHeight1 = m_Surface->m_Array[(int) floor(fX / m_StepSize)][(int) floor(fY / m_StepSize)];
	float fHeight2 = m_Surface->m_Array[(int) ceil(fX / m_StepSize)][(int) floor(fY / m_StepSize)];
	float fHeight3 = m_Surface->m_Array[(int) floor(fX / m_StepSize)][(int) ceil(fY / m_StepSize)];
	float fHeight4 = m_Surface->m_Array[(int) ceil(fX / m_StepSize)][(int) ceil(fY / m_StepSize)];

	// Calculate how much weight each height value has

	// Distribution between left and right height values
	float fHeight1Weight = (float) ceil(fX / m_StepSize) - (fX / m_StepSize);
	float fHeight2Weight = (fX / m_StepSize) - (float) floor(fX / m_StepSize);
	// Avoid error when floor() and ceil() return the same value
	if (fHeight1Weight == 0.0f && fHeight2Weight == 0.0f)
	{
		fHeight1Weight = 0.5f;
		fHeight2Weight = 0.5f;
	}
	
	// Distribution between top and bottom height values
	float fHeight3Weight = (float) ceil(fY / m_StepSize) - (fY / m_StepSize);
	float fHeight4Weight = (fY / m_StepSize) - (float) floor(fY / m_StepSize);
	// Avoid error when floor() and ceil() return the same value
	if (fHeight3Weight == 0.0f && fHeight4Weight == 0.0f)
	{
		fHeight3Weight = 0.5f;
		fHeight4Weight = 0.5f;
	}

	// Interpolate between the four nearest height values
	
	// Get the height for the given X position trough interpolation between
	// the left and the right height
	float fHeightBottom = (fHeight1 * fHeight1Weight + fHeight2 * fHeight2Weight);
	float fHeightTop    = (fHeight3 * fHeight1Weight + fHeight4 * fHeight2Weight);

	return (fHeightBottom * fHeight3Weight + fHeightTop * fHeight4Weight);
}

void CLandscape::SetStepSize(float fStepSize)
{
	// Set the step size

	// Check value
	if (fStepSize > 0.0f && fStepSize < 1000.0f)
		m_StepSize = fStepSize;
}

float CLandscape::GetStepSize()
{
	// Get the step size
	return m_StepSize;
}

void CLandscape::GetLandscapeDimensions(LPRECT lpRect)
{
	// Return the dimensions of the landscape

	lpRect->left = 0;
	lpRect->top = 0;
	lpRect->right = m_ArrayWidth;
	lpRect->bottom = m_ArrayHeight;
}

void CLandscape::SetHeightScaling(float fHeightScaling)
{
	m_HeightMapHeightScaling = fHeightScaling;
}

float CLandscape::GetHeightScaling()
{
	return m_HeightMapHeightScaling;
}

⌨️ 快捷键说明

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