昨天和今天在看法线纹理相关的内容,具体内容可参见法线纹理教程链接,在这个过程中,遇到一些问题,在此记录一下这些问题,避免以后再次出现类似的问题.
问题1:对glVertexAttribPointer函数参数理解错误
参见下述代码,
GLuint VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
auto vertexDataSize = this->_renderData.vertexs.size()
* sizeof(this->_renderData.vertexs[0]);
auto tangentSpaceDataSize = this->_tangentSpaces.size()
* sizeof(this->_tangentSpaces[0]);
GLuint VBO;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertexDataSize + tangentSpaceDataSize,
nullptr, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, vertexDataSize, &this->_renderData.vertexs[0]);
glBufferSubData(GL_ARRAY_BUFFER, vertexDataSize, tangentSpaceDataSize,
&this->_tangentSpaces[0]);
//Vertex相关数据在shader中使用固定的layout
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),BUFFER_OFFSET(0));
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(offsetof(Vertex, normal)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(offsetof(Vertex, texCoord)));
glEnableVertexAttribArray(2);
// 加入切线空间 ---- 2017.5.29
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(TangentSpace), BUFFER_OFFSET(0));
glEnableVertexAttribArray(3);
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(TangentSpace), BUFFER_OFFSET(offsetof(TangentSpace, bitangent)));
glEnableVertexAttribArray(4);
TangentSpace中包含切线和副切线数据,但经过对shader中传入的数据的分析,发现传入的数据出现了问题,运行结果如下截图(截图中用的是切线的坐标当做颜色输出的):
传入的数据是正确的(需要注意的是,每个顶点都必须有TangentSpace相关的数据),传入的切线是(1.0f,0.0f,0.0f),把其当做颜色输出.
最后发现,是自己对glVertexAttribPointer最后一个参数理解错误,正如我上述代码中几行
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(TangentSpace), BUFFER_OFFSET(0));
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(TangentSpace), BUFFER_OFFSET(offsetof(TangentSpace, bitangent)));
TangentSpace数据的是在_renderData.vertexs数据后,所以需要加入偏移量才正确,因为惯性思维,我一直填入了0,和结构体中变量的偏移量,正确的代码如下
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(TangentSpace), BUFFER_OFFSET(vertexDataSize));
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(TangentSpace), BUFFER_OFFSET(vertexDataSize + offsetof(TangentSpace, bitangent)));
修改后,结果运行正确
问题2:平面旋转过程中存在的问题
参见下述代码
glm::mat4 model(1.0f);
model = glm::translate(model, glm::vec3(0.0, -5.0, 0.0));
model = glm::rotate(model, 90.0f, glm::vec3(1.0f, 0.0f, 0.0f));
model = glm::scale(model, glm::vec3(5.0f));
//顶点,法向量,纹理坐标
//三角形绘制,2个三角形,6个顶点
GLfloat points[] = {
1.0f, 1.0f, -0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, -0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
-1.0f, -1.0f, -0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-1.0f, -1.0f, -0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.0f, -1.0f, -0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1.0f, 1.0f, -0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
};
旋转是绕着x轴(1.0,0.0,0.0)旋转90°(逆时针),平面的法向量是(0.0,0.0,1.0),旋转后的法向量为(0.0,-1.0,0.0),运行结果如下图:
说明光照数据出现问题,原因如上所述,将旋转角度修改,如下
...
model = glm::rotate(model, -90.0f, glm::vec3(1.0f, 0.0f, 0.0f));
...
修改后结果如下:
还有其它一些小问题,不过大部分都是粗心造成的,虽然上述也是粗心,但很难发现,故记录下来.
我在学习LearnOpenGL教程的过程中,自己在尝试将OpenGL API封装,具体可参见链接,目前还在边看教程边改进,自身能力不足,如有建议,还望提出来,在此表示感谢~