`
daojin
  • 浏览: 678069 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

经典代码解析

阅读更多
//关于思想,整体思想patch
//先定义一系列的顶点:
//给这些点付给固定的纹理和颜色,
 
void glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); pointer is the memory address of the first coordinate of the first vertex in the array. type specifies the data type (GL_SHORT, GL_INT, GL_FLOAT, or GL_DOUBLE) of each coordinate in the array. size is the number of coordinates per vertex, which must be 2, 3, or 4. stride is the byte offset between consecutive vertexes. If stride is 0, the vertices are understood to be tightly packed in the array.

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;
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics