www.pudn.com > MYLOD.rar > LOD.CPP
// Lod.cpp: implementation of the CLod class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "MyLOD.h" #include "Lod.h" #include "LandTex.h" #include#ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// extern int quadtree[]; extern int location[]; extern int lod_level; extern CLandTex lt; extern COLOUR *colour_map; extern int *y; CLod::CLod() { } CLod::~CLod() { } void CLod::reset_quad_tree(void) { int i; for(i=0; i<(QUAD_MAP * QUAD_MAP); i++) { quadtree[i] = UNKNOWN; } } void CLod::setup_quadtree(int x, int z, int width) { int width2; int v1[3]; v1[0] = x; v1[2] = z; width2 = width / 2; if((width > 1) && DISTANCE(v1, location) < width * lod_level) { quadtree[IX_QT(x, z)] = NODE_POINT; quadtree[IX_QT(x - width2, z - width2)] = EDGE_POINT; quadtree[IX_QT(x + width2, z - width2)] = EDGE_POINT; quadtree[IX_QT(x - width2, z + width2)] = EDGE_POINT; quadtree[IX_QT(x + width2, z + width2)] = EDGE_POINT; setup_quadtree(x - width2, z - width2, width2); setup_quadtree(x + width2, z - width2, width2); setup_quadtree(x - width2, z + width2, width2); setup_quadtree(x + width2, z + width2, width2); } else { quadtree[IX_QT(x, z)] = EDGE_POINT; } } void CLod::draw(int x, int z, int width, int direction) { int width2; if(width > 1) { if(width > 16) { glBindTexture(GL_TEXTURE_2D, lt.texture_name[(int)((x) / 64)][(int)((z) / 64)]); } width2 = width / 2; if(quadtree[IX_QT(x, z)] == NODE_POINT) { // NORTH if(quadtree[IX_QT(x - width2, z - width2)] == EDGE_POINT && quadtree[IX_QT(x + width2, z - width2)] == EDGE_POINT) { if(quadtree[IX_QT(x, z - width*2)] == NODE_POINT || (z-width)%MAP==0) { draw_point(x, z, width, NORTH_L); draw_point(x, z, width, NORTH_R); } else { draw_point(x, z, width, NORTH); } } else if(quadtree[IX_QT(x - width2, z - width2)] == EDGE_POINT) { draw_point(x, z, width, NORTH_L); } else if(quadtree[IX_QT(x + width2, z - width2)] == EDGE_POINT) { draw_point(x, z, width, NORTH_R); } // SOUTH if(quadtree[IX_QT(x - width2, z + width2)] == EDGE_POINT && quadtree[IX_QT(x + width2, z + width2)] == EDGE_POINT) { if(quadtree[IX_QT(x, z + width*2)] == NODE_POINT || (z+width)%MAP==0) { draw_point(x, z, width, SOUTH_L); draw_point(x, z, width, SOUTH_R); } else { draw_point(x, z, width, SOUTH); } } else if(quadtree[IX_QT(x - width2, z + width2)] == EDGE_POINT) { draw_point(x, z, width, SOUTH_L); } else if(quadtree[IX_QT(x + width2, z + width2)] == EDGE_POINT) { draw_point(x, z, width, SOUTH_R); } // EAST if(quadtree[IX_QT(x + width2, z - width2)] == EDGE_POINT && quadtree[IX_QT(x + width2, z + width2)] == EDGE_POINT) { if(quadtree[IX_QT(x + width*2, z)] == NODE_POINT || (x+width)%MAP==0) { draw_point(x, z, width, EAST_T); draw_point(x, z, width, EAST_B); } else { draw_point(x, z, width, EAST); } } else if(quadtree[IX_QT(x + width2, z - width2)] == EDGE_POINT) { draw_point(x, z, width, EAST_T); } else if(quadtree[IX_QT(x + width2, z + width2)] == EDGE_POINT) { draw_point(x, z, width, EAST_B); } // WEST if(quadtree[IX_QT(x - width2, z - width2)] == EDGE_POINT && quadtree[IX_QT(x - width2, z + width2)] == EDGE_POINT) { if(quadtree[IX_QT(x - width*2, z)] == NODE_POINT || (x-width)%MAP==0) { draw_point(x, z, width, WEST_T); draw_point(x, z, width, WEST_B); } else { draw_point(x, z, width, WEST); } } else if(quadtree[IX_QT(x - width2, z - width2)] == EDGE_POINT) { draw_point(x, z, width, WEST_T); } else if(quadtree[IX_QT(x - width2, z + width2)] == EDGE_POINT) { draw_point(x, z, width, WEST_B); } } else { return; } draw(x - width2, z - width2, width2, NW); draw(x + width2, z - width2, width2, NE); draw(x - width2, z + width2, width2, SW); draw(x + width2, z + width2, width2, SE); } } // 纹理形式的三角形绘制函数 void CLod::triangle1(int x1, int z1, int x2, int z2, int x3, int z3) { glBegin(GL_TRIANGLES); glTexCoord2f(x1/(texScale), z1/(texScale)); setColor(x1, z1); setVertex(x1, z1); glTexCoord2f(x2/(texScale), z2/(texScale)); setColor(x2, z2); setVertex(x2, z2); glTexCoord2f(x3/(texScale), z3/(texScale)); setColor(x3, z3); setVertex(x3, z3); glEnd(); } // 线框形式的三角形绘制函数 void CLod::triangle2(int x1, int z1, int x2, int z2, int x3, int z3) { glBegin(GL_LINE_LOOP); setVertex(x1, z1); setVertex(x2, z2); setVertex(x3, z3); glEnd(); } void CLod::draw_point(int x, int z, int width, int direction) { switch(direction) { case NORTH: if(m_bFlag) triangle1(x, z, x + width, z - width, x - width, z - width); else triangle2(x, z, x + width, z - width, x - width, z - width); return; case SOUTH: if(m_bFlag) triangle1(x, z, x - width, z + width, x + width, z + width); else triangle2(x, z, x - width, z + width, x + width, z + width); return; case EAST: if(m_bFlag) triangle1(x, z, x + width, z + width, x + width, z - width); else triangle2(x, z, x + width, z + width, x + width, z - width); return; case WEST: if(m_bFlag) triangle1(x, z, x - width, z - width, x - width, z + width); else triangle2(x, z, x - width, z - width, x - width, z + width); return; case NORTH_L: if(m_bFlag) triangle1(x, z, x, z - width, x - width, z - width); else triangle2(x, z, x, z - width, x - width, z - width); return; case NORTH_R: if(m_bFlag) triangle1(x, z, x + width, z - width, x, z - width); else triangle2(x, z, x + width, z - width, x, z - width); return; case SOUTH_L: if(m_bFlag) triangle1(x, z, x - width, z + width, x, z + width); else triangle2(x, z, x - width, z + width, x, z + width); return; case SOUTH_R: if(m_bFlag) triangle1(x, z, x, z + width, x + width, z + width); else triangle2(x, z, x, z + width, x + width, z + width); return; case EAST_T: if(m_bFlag) triangle1(x, z, x + width, z, x + width, z - width); else triangle2(x, z, x + width, z, x + width, z - width); return; case EAST_B: if(m_bFlag) triangle1(x, z, x + width, z + width, x + width, z); else triangle2(x, z, x + width, z + width, x + width, z); return; case WEST_T: if(m_bFlag) triangle1(x, z, x - width, z - width, x - width, z); else triangle2(x, z, x - width, z - width, x - width, z); return; case WEST_B: if(m_bFlag) triangle1(x, z, x - width, z, x - width, z + width); else triangle2(x, z, x - width, z, x - width, z + width); return; default: break; }; } void CLod::setColor(int x, int z) { glColor3ub(colour_map[IX(x, z)].r, colour_map[IX(x, z)].g, colour_map[IX(x, z)].b); } void CLod::setVertex(int x, int z) { glVertex3f((x << SHIFT), y[IX(x, z)] * 8, (z << SHIFT)); }