【发布时间】:2014-03-27 21:50:11
【问题描述】:
我正在尝试在 OpenGL 2.1 和 Qt5 中渲染一个简单的地图。但我在非常基本的问题上失败了。我在这里介绍的是表面法线。
我有 4 个由单个三角形几何构成的对象。简单来说,geoetry 是一个动态分配的 Vertex 数组,其中一个顶点是两个 QVector3D 的组合,这是 Qt 中预定义的 3D 位置类。
struct Vertex
{
QVector3D position;
QVector3D normal;
};
我通过使用从该顶点到下一个或上一个顶点的两个向量的叉积来计算顶点的法线。通过调试或将结果打印到控制台,结构的正常计算似乎很好。
QVector3D(-2, -2, -2) has normal QVector3D(0, 0, 1)
QVector3D(2, -2, -2) has normal QVector3D(0, 0, 1)
QVector3D(-2, 2, -2) has normal QVector3D(0, 0, 1)
...
但是当我将数据提供给着色器时,结果很荒谬!这是在每个位置用正常值着色的多边形的图片:
与法线贴图一样,红色=x,绿色=y,蓝色=z。黑色方块的左上角是世界的起源。如您所见,某个点的法线似乎只是该点的位置,没有 z 值。你能提示我可能出了什么问题,知道绘画代码是:
glUseProgram(program.programId());
glEnableClientState(GL_NORMAL_ARRAY);
program.setUniformValue("modelViewProjectionMatrix", viewCamera);
program.setUniformValue("entityBaseColor", QColor(0,120,233));
program.setUniformValue("sunColor", QColor("white"));
program.setUniformValue("sunBrightness", 1.0f);
static QVector3D tmpSunDir = QVector3D(0.2,-0.2,1.0).normalized();
program.setUniformValue("sunDir",tmpSunDir);
for( size_t i = 0; i < m_numberOfBoundaries; ++i)
{
glBindBuffer(GL_ARRAY_BUFFER, m_bufferObjects[i]);
int vertexLocation = program.attributeLocation("vertexPosition");
program.setAttributeArray( vertexLocation, GL_FLOAT, &(m_boundaries[i].data->position), sizeof(Vertex) );
program.enableAttributeArray(vertexLocation);
glVertexAttribPointer( vertexLocation, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0 );
int vertexNormal = program.attributeLocation("vertexNormal");
program.setAttributeArray( vertexNormal, GL_FLOAT, &(m_boundaries[i].data->normal), sizeof(Vertex) );
program.enableAttributeArray(vertexNormal);
glVertexAttribPointer( vertexNormal, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0 );
glDrawArrays( GL_POLYGON, 0, m_boundaries[i].sizeOfData );
}
glDisableClientState(GL_NORMAL_ARRAY);
其中边界是多边形的几何连通分量。 program 是 QOpenGLShaderProgram,Qt abstraction for shader programs。每个边界都绑定到一个缓冲区对象。缓冲区对象编号存储在数组m_bufferObjects 中。多边形“边界”在数组m_boundaries 中存储为struct。它们有两个字段:data,指向循环顶点数组开始的指针,以及sizeOfData,多边形的点数。
【问题讨论】:
-
将图片上传到 imgur.com 或类似网站,我会将其编辑到您的问题中。
-
嗯,我清理了代码,现在我设法获得了看起来有些正确的 z 坐标,但没有更多的 x-y 坐标。代码如下:
int vertexNormal = program.attributeLocation("vertexNormal"); int normalOffset = (GLbyte const*)(&m_boundaries[i].data->normal) - (GLbyte const*)(m_boundaries[i].data) ; glVertexAttribPointer( vertexNormal, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLbyte const*)(normalOffset) ); glEnableVertexAttribArray( vertexNormal );