gpt4 book ai didi

c++ - 最小的 C++ OpenGL 段错误

转载 作者:太空狗 更新时间:2023-10-29 20:54:43 25 4
gpt4 key购买 nike

我正在关注 Tom Dalling's Modern OpenGL tutorial 中的第一期当我下载他的代码时,它运行良好。因此,我想创建自己的最小版本,以帮助我了解它是如何工作的。

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <GLM/glm.hpp>

#include <stdexcept>

GLFWwindow* gWindow = NULL;

GLint gProgram = 0;

GLuint gVertexShader = 0;
GLuint gFragmentShader = 0;

GLuint gVAO = 0;
GLuint gVBO = 0;

int main() {
/** Initialise GLFW **/
if (!glfwInit()){
throw std::runtime_error("GLFW not initialised.");
}
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
gWindow = glfwCreateWindow(800, 600, "OpenGL 3.2", NULL, NULL);
if(!gWindow) {
throw std::runtime_error("glfwCreateWindow failed.");
}
glfwMakeContextCurrent(gWindow);

/** Initialise GLEW **/
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
throw std::runtime_error("Glew not initialised.");
}
if (!GLEW_VERSION_3_2) {
throw std::runtime_error("OpenGL 3.2 not supported.");
}

/** Set up shaders **/
gVertexShader = glCreateShader(GL_VERTEX_SHADER); //Segmentation fault here
gFragmentShader = glCreateShader(GL_FRAGMENT_SHADER);

glShaderSource(gVertexShader, 1, (const GLchar* const*)R"(
#version 150

in vec3 vertexPos

out vec colour;

void main() {
colour = vertexPos;
gl_Position = vec4(vertexPos, 1);
}
)", NULL);
glShaderSource(gFragmentShader, 1, (const GLchar* const*)R"(
#version 150

in vec3 colour;

out vec4 fragColour;

void main() {
fragColour = colour;
}
)", NULL);

glCompileShader(gVertexShader);
glCompileShader(gFragmentShader);

/** Set up program **/
gProgram = glCreateProgram();

glAttachShader(gProgram, gVertexShader);
glAttachShader(gProgram, gFragmentShader);

glLinkProgram(gProgram);

glDetachShader(gProgram, gVertexShader);
glDetachShader(gProgram, gFragmentShader);

glDeleteShader(gVertexShader);
glDeleteShader(gFragmentShader);

/** Set up VAO and VBO **/
float vertexData[] = {
// X, Y, Z
0.2f, 0.2f, 0.0f,
0.8f, 0.2f, 0.0f,
0.5f, 0.8f, 0.0f,
};

glGenVertexArrays(1, &gVAO);
glBindVertexArray(gVAO);

glGenBuffers(1, &gVBO);
glBindBuffer(GL_ARRAY_BUFFER, gVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(GL_FLOAT)*9, vertexData, GL_STATIC_DRAW);

glVertexAttribPointer(glGetAttribLocation(gProgram, "vertexPos"), 3, GL_FLOAT, GL_FALSE, 0, NULL);

/** Main Loop **/
while (!glfwWindowShouldClose(gWindow)) {
glfwPollEvents();

glBindBuffer(GL_ARRAY_BUFFER, gVBO);
glDrawArrays(GL_TRIANGLES, 0, 1);
glfwSwapBuffers(gWindow);
}

return 0;
}

这是我创建的并且构建正确。但是,在运行它时,我在调用 glCreateShader 时遇到了段错误。

我已经做了很多搜索来找到解决这个问题的方法,到目前为止我发现了发生这种情况的两个主要原因:

  • 一个是 glewExperimental 需要设置为 GL_TRUE,但是添加此行后没有任何变化。
  • 第二个原因是没有设置 OpenGL 上下文,但我相信对 glfwMakeContextCurrent 的调用涵盖了这一点。

从这里我不知道该怎么做,所以任何提示都会有很大帮助!

编辑:谢谢大家的帮助!我最终设法让它工作并将代码上传到 pastebin以备将来引用。

最佳答案

问题解决

您的程序不是在您指向的行崩溃,而是在第一次 glShaderSource 调用时崩溃。您实际上传递了一个指向字符串的指针作为第三个参数,将其转换为 (const GLchar* const*)。这不是 glShaderSource 所期望的。它需要一个指向字符串指针数组的指针,其(指针数组)长度应作为第二个参数传递(参见 documentation )。

作为对您的代码的快速修复,我声明了以下内容:

const char *vs_source[] = {
"#version 150\n",
"in vec3 vertexPos\n",
"out vec colour;\n",
"void main() {\n",
" colour = vertexPos;\n",
" gl_Position = vec4(vertexPos, 1);\n",
"}\n"};

const char *fs_source[] = {
"#version 150\n",
"in vec3 colour;\n",
"out vec4 fragColour;\n",
"void main() {\n",
" fragColour = colour;\n",
"}\n"};

并将对 glShaderSource 的调用替换为

glShaderSource(gVertexShader, 7, (const char**)vs_source, NULL);
glShaderSource(gFragmentShader, 6, (const char**)fs_source, NULL);

现在程序运行正常并按预期显示窗口。

提示

  • 由于将字符串文字转换为 (const GLchar* const*),您的代码甚至无法在我的机器上编译(我使用 gcc 4.8.3 @ Linux)。因此,请尝试在您的编译器选项中设置更多限制性标志,并注意编译器警告。此外,将警告视为错误。

  • 使用某种内存分析器来确定崩溃的确切位置。例如,我使用 Valgrind 来定位问题。

关于c++ - 最小的 C++ OpenGL 段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38291436/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com