我正试图破解和修改一个旧的opengl固定管道游戏的几个渲染功能,通过连接到opengl调用,我目前的任务是实现着色器照明。我已经创建了一个适当的着色程序,可以正确地照亮我的大多数物体,但是这个游戏的地形是在没有提供正常数据的情况下绘制的。
游戏调用
void glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer);
和
void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices);`
来定义和绘制地形,因此我把这些函数都钩住了,我希望在指针上循环给定的顶点数组,并计算每个表面的法线,在每个DrawElements调用或VertexPointer调用上,但是我遇到了麻烦,提出了一种方法来做到这一点-具体来说,如何读取,迭代,并理解指针上的数据。在本例中,glVertexPointer
调用的常用参数为size = 3, type = GL_float, stride = 16, pointer = some pointer
。hook glVertexPointer,我不知道如何通过指针迭代并抓取网格的所有顶点,考虑到我不知道所有顶点的总数,我也不理解在给定步幅的指针上数据是如何结构的-类似地,我应该如何构建正常数组
尝试计算索引数组中每个指定索引的抽取中的法线是一个更好的主意吗?
根据您的顶点数组构建过程,索引将是构建法线的唯一相关信息。
定义一个顶点的平均值是很简单的,如果你在你的顶点数组中添加一个法线字段,并将解析你的索引数组的所有正常计算加起来。
你必须用每个法线和除以索引中重复的次数,你可以保存在顶点索引之后的临时数组中的计数(每次法线添加到顶点时增加)
所以更清楚:
Vertex[vertexCount]: {Pos,Normal}
normalCount[vertexCount]: int count
Indices[indecesCount]: int vertexIndex
每个顶点可能有6个法线,所以添加一个临时的法线数组来平均每个顶点的法线数组:
NormalTemp[vertexCount][6] {x,y,z}
而不是解析索引数组(如果是三角形数组):
for i=0 to indicesCount step 3
for each triangle top (t from 0 to 2)
NormalTemp[indices[i + t]][normalCount[indices[i+t]]+1] = normal calculation with cross product of vectors ending with other summits or this triangle
normalCount[indices[i+t]]++
你必须把你的总和除以计数
for i=0 to vertexCount step 1
for j=0 to NormalCount[i] step 1
sum += NormalTemp[i][j]
normal[i] = sum / normacount[i]
虽然我喜欢并投票赞成j-p的答案,但我仍然想指出,你可以计算每个面一个法线,并且只使用所有3个顶点。这样会更快,更容易,有时甚至更准确。