【问题标题】:glDrawArrays segmentation faultglDrawArrays 分段错误
【发布时间】:2015-08-07 08:27:22
【问题描述】:

我正在尝试使用 OpenGL 3.3 渲染一个简单的三角形,但是当我调用 glDrawArrays 时,我的程序因分段错误而崩溃。我使用的语言是 C++,我使用库 SDL、glew 和 glm。 我认为发生的事情是,绘图调用试图访问不属于我设置的顶点缓冲区的数据。 出于无关紧要的原因,我无法提供程序的完整源代码。不过,我可以提供一些相关的 sn-ps 和使用 Apitrace 工具生成的 OpenGL 调用跟踪。

[...]

glClearColor(red = 0, green = 0, blue = 0.5, alpha = 1)
glClear(mask = COLOR_BUFFER_BIT)

glGenVertexArrays(n = 1, arrays = &1)
glBindVertexArray(array = 1)
glGenBuffers(n = 1, buffer = &1)
glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 1)
glBufferData(target = GL_ARRAY_BUFFER, size = 72, data = blob(72), usage = GL_STATIC_DRAW)
glVertexAttribPointer(index = 0, size = 3, type = GL_FLOAT, normalized = GL_FALSE, stride = 24, pointer = NULL)
glVertexAttribPointer(index = 1, size = 3, type = GL_FLOAT, normalized = GL_FALSE, stride = 24, pointer = 0xc)
glEnableVertexAttribArray(index = 0)
glEnableVertexAttribArray(index = 1)

glCreateShader(type = GL_VERTEX_SHADER) = 1
glShaderSource(shader = 1, count = 1, string = &"#version 330

layout (location = 0) in vec3 iPosition;
layout (location = 1) in vec3 iNormal;

void main() {
  gl_Position = vec4(iPosition.x, iPosition.y, iPosition.z, iNormal.z * -1.0);
}", length = NULL)
glCreateShader(type = GL_FRAGMENT_SHADER) = 2
glShaderSource(shader = 2, count = 1, string = &"#version 330

out vec4 oFragColor;

void main() {
  oFragColor = vec4(1.0, 0.0, 0.0, 1.0);
}", length = NULL)
glCompileShader(shader = 1)
glGetShaderiv(shader = 1, pname = GL_COMPILE_STATUS, params = &1)
glCompileShader(shader = 2)
glGetShaderiv(shader = 2, pname = GL_COMPILE_STATUS, params = &1)
glCreateProgram() = 3
glAttachShader(program = 3, shader = 1)
glAttachShader(program = 3, shader = 2)
glBindAttribLocation(program = 3, index = 1, name = "iNormal")
glBindAttribLocation(program = 3, index = 0, name = "iPosition")
glLinkProgram(program = 3)
glGetProgramiv(program = 3, pname = GL_LINK_STATUS, params = &1)
glGetAttribLocation(program = 3, name = "iPosition") = 0
glGetAttribLocation(program = 3, name = "iNormal") = 1

glGetIntegerv(pname = GL_CURRENT_PROGRAM, params = &0)
glUseProgram(program = 3)
glBindVertexArray(array = 1)
glClear(mask = GL_COLOR_BUFFER_BIT)
glDrawArrays(mode = GL_TRIANGLES, first = 0, count = 3) //incomplete (segfault here)

正如我所说,我认为问题在于,绘图调用试图以错误的方式访问数据。我已经使用 glGetBufferSubData 检查了顶点缓冲区中的数据。所以这是我用来设置 VAO 的代码:

Mesh::Mesh(const std::vector<Triangle>& triangles): _vao(0), _vbo(0) {
  glGenVertexArrays(1, &_vao);
  glBindVertexArray(_vao);

  glGenBuffers(1, &_vbo);
  glBindBuffer(GL_ARRAY_BUFFER, _vbo);

  struct Vertex {
    glm::vec3 position;
    glm::vec3 normal;
  }

  Vertex* vertecies = new Vertex[triangles.size() * 3];

  // [...]
  // Convert triangles to vertecies, store them in the array.

  glBufferData(GL_ARRAY_BUFFER, triangles.size() * 3 * sizeof(Vertex), vertecies, GL_STATIC_DRAW);

  delete[] vertecies;

  //Position
  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(0));
  //Normal
  glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(3 * sizeof(GL_FLOAT)));

  glEnableVertexAttribArray(0);
  glEnableVertexAttribArray(1);
}

我怀疑错误出在我调用 glVertexAttribPointer 的方式上。 如果程序的其他部分需要回答,请给我留言,我会看看我能做些什么来提供它们。

【问题讨论】:

  • 首先,在shader和glBindAttribLocation调用中绑定不同位置的属性。 (着色器:iPosition = 0iNormal = 1,glBindAttribLocation:iNormal = 0iPosition = 1)。
  • 这实际上只是我在复制跟踪时犯的一个错误。事实上,我什至从未自己调用 glBindAttribLocation。这似乎是 OpenGL 在着色器中处理 (location = 0) 的方式。

标签: c++ opengl


【解决方案1】:

我看不出你的代码有什么问题。当我的上下文设置不正确时,我通常会遇到这个问题。例如,当我没有正确设置 GLEW 时。这对你来说可能是同样的问题。

【讨论】:

  • 这让我走上了正轨。我忘记调用 SDL_INIT(),它可以防止在创建 OpenGL 上下文时引发错误。抛出错误是因为我没有使用 nvidia 驱动程序,即使我安装了它们。最后,我不得不将我的用户添加到视频组以使其工作(该死的,为什么官方 wiki 中没有记录如此重要的步骤?)。我的屏幕上仍然没有三角形,但我相信我能弄清楚。至少程序不再出现段错误。
猜你喜欢
  • 1970-01-01
  • 2017-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-14
  • 1970-01-01
  • 1970-01-01
  • 2017-08-01
相关资源
最近更新 更多