//关于思想,整体思想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;
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) );
ScapePatch* Other;
//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 )
{
//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 )
{
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 )
{
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 )
{
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;
}
分享到:
相关推荐
C语言经典问题及代码解析C语言经典问题及代码解析C语言经典问题及代码解析C语言经典问题及代码解析
欣赏并分析1987年,贝尔实验室的David Korn提交的获奖代码。
数据结构经典程序解析(含代码),我们学校的内部资料,很有用的,对学习数据结构很好
C语言经典问题回答及代码解析,包括基础、排序、文件、预编译等
Visual.C#.NET数据库开发经典案例解析(代码)
《Delphi数据库经典案例解析》光盘代码。
Macromedia 大师群英会 Flash经典作品解析 第1章源代码
C++ Builder数据库开发经典案例解析示例代码(配套光盘全)
Delphi 7经典问题解析 Delphi 7数据库应用技术与实例 源代码.
Visual C#.NET数据库开发经典案例解析配套书籍源代码
C++代码实现对IP数据包的详细解析,经典
《SAS开发经典案例解析》以经典案例的形式讲解SAS的实际应用。《SAS开发经典案例解析》共分12章,主要内容包括SAS概述与整体架构、SAS编程语法基础、数据步基础与案例、过程步基础与案例、函数基础与案例、宏基础与...
Visual C#.NET数据库开发经典案例解析 王晟编著
java经典例题解析,包含答案,分析,代码以及详细的注释,适合初学者快速学习以及了解java循环,嵌套,遍历控制输出等基础流程,并可以在此基础上代码复用,完成其他相关的程序设计,是初学者编程指导的不二选择。
一本经典书籍,对linux源代码的解析。阅读后,相信会对linux的理解更加的深入
C++ Builder数据库开发经典案例解析 好书,好代码。
北京工业大学考研专业课893中数据结构算法经典问题总结,含代码解析,按照考研大纲顺序排列