OpenGL 代码不是每次都显示相同的东西吗?
OpenGL code doesn't display the same thing every time?
当 运行 程序两次时,它在 运行 时显示的结果不同,即使我使用的是相同的可执行文件。
这里有一些背景信息:
我正在使用 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 使用顶点着色器的方式的问题,但我不能肯定。
glm::mat4
的默认构造函数不初始化矩阵。在class Render
的构造函数中调用void Renderer::CreateProjectionMatrix()
之前,_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
的所有字段。
此外,您还必须在构造函数中初始化 class Camera
的成员 _position
、_pitch
、_yaw
和 _roll
:
Camera()
: _position(0.0f, 0.0f, 0.0f)
, _pitch(0.0f)
, _yaw(0.0f)
, _roll(0.0f)
{};
方法中ShaderProgram::CompileShader
是另外一个问题。 ShaderProgram::ReadShader
的 return 值的类型是 std::string
。所以 ReadShader( shaderPath ).c_str()
将 return 一个指向临时对象的指针,该对象在赋值语句结束时立即被破坏。 std::string
对象被破坏,指针指向任何地方。
将ShaderProgram::ReadShader
的return值赋给一个局部变量,并在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);
// [...]
}
当 运行 程序两次时,它在 运行 时显示的结果不同,即使我使用的是相同的可执行文件。
这里有一些背景信息:
我正在使用 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 使用顶点着色器的方式的问题,但我不能肯定。
glm::mat4
的默认构造函数不初始化矩阵。在class Render
的构造函数中调用void Renderer::CreateProjectionMatrix()
之前,_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
的所有字段。
此外,您还必须在构造函数中初始化 class Camera
的成员 _position
、_pitch
、_yaw
和 _roll
:
Camera()
: _position(0.0f, 0.0f, 0.0f)
, _pitch(0.0f)
, _yaw(0.0f)
, _roll(0.0f)
{};
方法中ShaderProgram::CompileShader
是另外一个问题。 ShaderProgram::ReadShader
的 return 值的类型是 std::string
。所以 ReadShader( shaderPath ).c_str()
将 return 一个指向临时对象的指针,该对象在赋值语句结束时立即被破坏。 std::string
对象被破坏,指针指向任何地方。
将ShaderProgram::ReadShader
的return值赋给一个局部变量,并在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);
// [...]
}