2

我正在尝试通过挂钩 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. 挂钩 glVertexPointer,我不知道如何遍历指针并获取网格的所有顶点,因为我不知道所有顶点的总数,也不了解指针处的数据结构给定步幅 - 同样我应该如何构造普通数组

尝试为索引数组中的每个指定索引计算drawelements中的法线会更好吗?

4

2 回答 2

2

根据您的顶点数组构建过程,索引将是构建法线的唯一相关信息。

如果您在顶点数组中添加一个法线字段,并对解析索引数组的所有法线计算求和,那么为一个顶点定义法线平均值很简单。

您必须将每个法线总和除以索引中的重复次数,计算可以保存在顶点索引后的临时数组中的计数(每次将法线添加到顶点时递增)

所以要更清楚:

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]
于 2014-03-20T01:31:14.983 回答
0

虽然我喜欢并投票赞成 jp 的答案,但我仍然想指出,您可以通过计算每个面的一个法线并仅使用所有 3 个顶点来摆脱困境。它会更快,更容易,有时甚至更准确。

于 2014-11-01T19:10:28.933 回答