📄 terrain.cpp
字号:
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 + -