两次运行程序时,即使我使用相同的可执行文件,运行时也不会显示相同的结果。
这里有一些上下文:
我正在使用Sierra 10.13在MacAir上进行编程,而我的IDE是Xcode 10.1。
我发现我的问题是由顶点着色器中添加的转换矩阵引起的:
// This code is not working
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 textureCoords;
out vec2 pass_textureCoords;
uniform mat4 transformM;
void main() {
gl_Position = transformM * vec4(position, 1.0);
pass_textureCoords = textureCoords;
}
然后我以这种方式加载 transformM 矩阵(我正在使用GLM数学库):
void LoadMatrix(int location, glm::mat4 matrix) {
glUniformMatrix4fv(location, 1, GL_FALSE, &matrix[0][0]);
}
其中位置是:
uniformName = "transformM";
location = glGetUniformLocation(_shaderID, uniformName.c_str());
(我保持简单,但您可以在此处找到完整的代码:https://github.com/Cuiyere/Ecosystem)
实际上,我希望我的代码能够渲染一个立方体并旋转它,但是它并没有像50%的时间那样显示。
我不知道为什么会发生此问题。我检查了一百次代码,检查了docs.gl网站,将ThinMatrix的代码与我的代码进行了比较(即使它是用Java编写的,其总体结构和OpenGL函数仍然相同),检查了OpenGL论坛,但据我所知瞧,没人遇到这个问题。
我认为OpenGL使用顶点着色器的方式存在问题,但我不能肯定。
答案 0 :(得分:5)
glm::mat4
的默认构造函数不会初始化矩阵。在void Renderer::CreateProjectionMatrix()
的构造函数中调用class Render
之前,_projectionMatrix
未初始化。
方法void Renderer::CreateProjectionMatrix()
不会初始化矩阵_projectionMatrix
的所有字段。矩阵中未初始化的字段会导致未定义的行为。
在函数开始时将identity matrix分配给_projectionMatrix
,以确保所有字段都
初始化:
void Renderer::CreateProjectionMatrix() {
_projectionMatrix = glm::mat4(1.0f);
// [...]
}
或使用构造函数初始化矩阵:
Renderer::Renderer (Shaders::StaticShader shader)
: _projectionMatrix(1.0f)
{
CreateProjectionMatrix();
// [...]
}
但是请注意,如果一个方法名为CreateProjectionMatrix
,则应设置成员_projectionMatrix
的所有字段。
此外,您必须初始化构造函数中_position
的成员_pitch
,_yaw
,_roll
和class Camera
的成员:
Camera()
: _position(0.0f, 0.0f, 0.0f)
, _pitch(0.0f)
, _yaw(0.0f)
, _roll(0.0f)
{};
在方法ShaderProgram::CompileShader
中是另一个问题。返回值ShaderProgram::ReadShader
的类型为std::string
。因此ReadShader( shaderPath ).c_str()
将返回一个指向临时对象的指针,该指针在赋值语句的结尾立即被销毁。 std::string
对象被破坏,指针指向无处。
将ShaderProgram::ReadShader
的返回值分配给一个局部变量,并使用一个指向此局部变量内容的指针,将其设置为ShaderProgram::CompileShader
的作用域:
unsigned int ShaderProgram::CompileShader (unsigned int type, const std::string & shaderPath) {
unsigned int id = glCreateShader(type);
std::string code = ReadShader( shaderPath );
const char* src = code.c_str();
glShaderSource(id, 1, &src, nullptr);
glCompileShader(id);
// [...]
}