To access the other five arrays, there are five similar routines:
void glColorPointer(GLint size , GLenum type , GLsizei stride , const GLvoid * pointer ); void glIndexPointer(GLenum type , GLsizei stride , const GLvoid * pointer ); void glNormalPointer(GLenum type , GLsizei stride , const GLvoid * pointer ); void glTexCoordPointer(GLint size , GLenum type , GLsizei stride , const GLvoid * pointer ); void glEdgeFlagPointer(GLsizei stride , const GLvoid * pointer ); Specifies where spatial coordinate data can be accessed. 等等。 2.指定渲染路径索引表。(多重渲染用 glMultiTexCoordPointer) 3.渲染。(glDrawElements); 4.LOSE OF Detail 发生在最后的渲染过程。。。 int CScape::RenderPatch( int i ) { int FacesRendered = 0; static unsigned short Indices[INDICES_LOD_HIGH]; ScapePatch* Patch = &m_Patches[i]; unsigned short* IndexPtr; glVertexPointer( 3, GL_FLOAT, sizeof(ScapeVertex), m_Buffer->GetPointer() + (PATCH_VERTS * i * sizeof(ScapeVertex)) ); int CurIndices; //unsigned short* IndexPtr; if( Patch->LoD == SCAPE_LOD_HIGH ) { CurIndices = INDICES_LOD_HIGH; IndexPtr = m_Indices[0]; } else if( Patch->LoD == SCAPE_LOD_MED ) { CurIndices = INDICES_LOD_MED; IndexPtr = m_Indices[1]; } else if( Patch->LoD == SCAPE_LOD_LOW ) { CurIndices = INDICES_LOD_LOW; IndexPtr = m_Indices[2]; } else if( Patch->LoD == SCAPE_LOD_XTRALOW ) { CurIndices = INDICES_LOD_XTRALOW; IndexPtr = m_Indices[3]; } else if( Patch->LoD == SCAPE_LOD_MIN ) { CurIndices = INDICES_LOD_MIN; IndexPtr = m_Indices[4]; } memcpy( Indices, IndexPtr, CurIndices * sizeof(unsigned short) ); //GenIndices( Patch->LoD, Indices ); ScapePatch* Other; //ok, now to work out some adjacency LoD issues //If an adjacent patch is at a lower LoD, shift indices around //to avoid cracks in the landscape. //i是patch的序列号,m_HeightPatches是地图在z方向patch数量 //如果i比m_HeightPatches大。 if( i >= m_HeightPatches ) { //other是它的left的patch Other = &m_Patches[i-m_HeightPatches]; //如果left的patch的level of detail >current.level of detail //也就是说更模糊。 if( Other->LoD > Patch->LoD ) { //the patch to the left is at a lower LoD //we need to reduce our left detail level //降低我们的左边细节等级,也就相当于更多的细节。(呵呵,有些拗口) //遍历现在所有的渲染点列表。 // (PATCH_SIZE*PATCH_SIZE*2*3) //小正方形个数是PATCH_SIZE个 //三角形个数是PATCH_SIE*2个 //渲染一个三角形需要3个顶点,因此是PATCH_SIZE*PATCH_ZIE*2*3个顶点。 //CurIndices,根据SIZE进行调整, #define INDICES_LOD_HIGH (PATCH_SIZE*PATCH_SIZE*2*3) #define INDICES_LOD_MED (INDICES_LOD_HIGH / 4) #define INDICES_LOD_LOW (INDICES_LOD_MED / 4) #define INDICES_LOD_XTRALOW (INDICES_LOD_LOW / 4) #define INDICES_LOD_MIN (INDICES_LOD_XTRALOW / 4) for( int n = 0; n < CurIndices; ++n ) { //Indices[n]是经过memcopy的。 //下面这块代码用来生成不同ScapeLoD,不同level,patch上边上两个点之间的间隔。 inline void GenIndices( int ScapeLoD, unsigned short* Buffer ) { int x, z, i, j; i = 0; for( z = 0; z < PATCH_SIZE; z+=ScapeLoD ) { for( x = 0; x < PATCH_SIZE; x+=ScapeLoD ) { //逆时针哦!! //指出6个点。一个正方形中的六个 //找出每个正方形点(左上角)的索引(这个索引是)。 j = PINDEX(x,z); //下边的点 //也就是说PATCH_SIZE+1经过ScapeLod行。 Buffer[i++] = j + (PATCH_SIZE+1) * ScapeLoD; //右边的点 Buffer[i++] = j + 1 * ScapeLoD; //本点。 Buffer[i++] = j; //右下角的点: Buffer[i++] = j + (PATCH_SIZE+2) * ScapeLoD; //正右方的点。 Buffer[i++] = j + 1 * ScapeLoD; //正下方的点。 Buffer[i++] = j + (PATCH_SIZE+1) * ScapeLoD; } } } //下面这个代码是核心。 //n表示三角形绘制中用到的第n个顶点的索引(也就是在patch中的位置),如果这个顶点的索引,小于PATCH_SIZE+1。说明在第 //说明在第一列。(上面是列进行三角形绘制的。); //并且这个索引不能被左边的间隔整除。 //说明是非公用点。 if( (Indices[n] < (PATCH_SIZE+1)) && (Indices[n] % Other->LoD) != 0 ) { //进行调整为: //比如说10,6; //取整点 //去除这个点。(需要深刻思考) //也就是把本来一个正方形有两个三角。 //把它和斜角拉成一条线!退化三角为直线。 Indices[n] -= Indices[n] % Other->LoD; } } } } //下面就不分析了,都一样。。。。 if( i <= m_NumPatches - m_HeightPatches ) { Other = &m_Patches[i+m_HeightPatches]; if( Other->LoD > Patch->LoD ) { //Patch to the right is at a lower LoD //reduce right edge detail for( int n = 0; n < CurIndices; ++n ) { if( (Indices[n] > ((PATCH_SIZE+1)*PATCH_SIZE) ) && (Indices[n] % Other->LoD) != 0 ) { Indices[n] -= Indices[n] % Other->LoD; } } } } if( i % m_HeightPatches ) { Other = &m_Patches[i-1]; if( Other->LoD > Patch->LoD ) { //the patch to the top is at a lower LoD //we need to reduce our top detail level for( int n = 0; n < CurIndices; ++n ) { if( (Indices[n] % (PATCH_SIZE+1) == 0) && (Indices[n] % (Other->LoD * (PATCH_SIZE+1))) != 0) { Indices[n] -= (PATCH_SIZE+1) * Indices[n] % (Other->LoD * (PATCH_SIZE+1)); } } } } if( (i + 1) % m_HeightPatches ) { Other = &m_Patches[i+1]; if( Other->LoD > Patch->LoD ) { //the patch to the bottom is at a lower LoD //we need to reduce our bottom detail level for( int n = 0; n < CurIndices; ++n ) { if( ((Indices[n] + 1) % (PATCH_SIZE+1) == 0) && (Indices[n] % (Other->LoD * (PATCH_SIZE+1))) != 0) { Indices[n] -= (PATCH_SIZE+1) * Indices[n] % (Other->LoD * (PATCH_SIZE+1)); } } } } glDrawElements( GL_TRIANGLES, CurIndices, GL_UNSIGNED_SHORT, Indices ); FacesRendered = CurIndices / 3; return FacesRendered; }