1

( Segmentation fault with glBufferData() )有一个类似的帖子,但它没有解决我的问题。

当我glBingBuffer()在下面调用第二个参数为 0 以取消绑定程序 SEGFAULTS 的缓冲区时。如果我取消注释这些行,那么程序将正常运行。为什么是这样?

QtRenderer::QtRenderer() :
  QGLWidget(){
}

QtRenderer::~QtRenderer() {
}

void QtRenderer::initializeGL() {
  makeCurrent();

  const char* vertexSource =
    "#version 150\n"
    "in vec2 position;"
    "void main() {"
    "   gl_Position = vec4( position, 0.0, 1.0 );"
    "}";
  const char* fragmentSource =
    "#version 150\n"
    "out vec4 outColor;"
    "void main() {"
    "   outColor = vec4( 1.0, 1.0, 1.0, 1.0 );"
    "}";

  glextensions_loader::load_gl_extensions();

  glGenBuffers( 1, &vbo );

  float vertices[] = {
    0.0f, 0.5f,
    0.5f, -0.5f,
    -0.5f, -0.5f
  };

  glBindBuffer( GL_ARRAY_BUFFER, vbo );
  glBufferData( GL_ARRAY_BUFFER, sizeof( vertices ), vertices, GL_STATIC_DRAW );
  glBindBuffer( GL_ARRAY_BUFFER, 0 ); // <-----------SEGFAULT

  // Create and compile the vertex shader
  GLuint vertexShader = glCreateShader( GL_VERTEX_SHADER );
  glShaderSource( vertexShader, 1, &vertexSource, NULL );
  glCompileShader( vertexShader );

  // Create and compile the fragment shader
  GLuint fragmentShader = glCreateShader( GL_FRAGMENT_SHADER );
  glShaderSource( fragmentShader, 1, &fragmentSource, NULL );
  glCompileShader( fragmentShader );

  // Link the vertex and fragment shader into a shader program
  GLuint shaderProgram = glCreateProgram();
  glAttachShader( shaderProgram, vertexShader );
  glAttachShader( shaderProgram, fragmentShader );
  //glBindFragDataLocation( shaderProgram, 0, "outColor" );
  glLinkProgram( shaderProgram );
  glUseProgram( shaderProgram );

  GLint posAttrib = glGetAttribLocation( shaderProgram, "position" );
  glEnableVertexAttribArray( posAttrib );
  glVertexAttribPointer( posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0 );
}

void QtRenderer::paintGL() {
  makeCurrent();

  // Clear the screen to black
  glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
  glClear( GL_COLOR_BUFFER_BIT );

  // Draw a triangle from the 3 vertices
  glBindBuffer( GL_ARRAY_BUFFER, vbo );
  glDrawArrays( GL_TRIANGLES, 0, 3 );
  glBindBuffer( GL_ARRAY_BUFFER, 0 );  // <-----------SEGFAULT
}

void QtRenderer::updateGL() {
  paintGL();
}

更新

我不知道核心文件在 RHEL 6.3 中的位置,但我正在寻找它。与此同时,我拥有的 gdb 信息是:

[mehoggan@localhost online_samples_delete_later]$ gdb ./test
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-56.el6)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/mehoggan/Devel/GLExtensions/demos/online_samples_delete_later/test...done.
(gdb) r
Starting program: /home/mehoggan/Devel/GLExtensions/demos/online_samples_delete_later/test 
[Thread debugging using libthread_db enabled]

Program received signal SIGSEGV, Segmentation fault.
0x002eeef1 in ?? ()
Missing separate debuginfos, use: debuginfo-install GConf2-2.28.0-6.el6.i686 ORBit2-2.14.17-3.1.el6.i686 PackageKit-gtk-module-0.5.8-21.el6.i686 atk-1.28.0-2.el6.i686 avahi-glib-0.6.25-11.el6.i686 avahi-libs-0.6.25-11.el6.i686 cairo-1.8.8-3.1.el6.i686 dbus-glib-0.86-5.el6.i686 dbus-libs-1.2.24-5.el6_1.i686 expat-2.0.1-11.el6_2.i686 fontconfig-2.8.0-3.el6.i686 freetype-2.3.11-14.el6_3.1.i686 glib2-2.22.5-7.el6.i686 glibc-2.12-1.80.el6.i686 gnome-keyring-2.28.2-7.el6.i686 gnome-vfs2-2.24.2-6.el6.i686 gtk2-2.18.9-10.el6.i686 gtk2-engines-2.18.4-5.el6.i686 keyutils-libs-1.4-4.el6.i686 krb5-libs-1.10.3-10.el6.i686 libICE-1.0.6-1.el6.i686 libSM-1.2.1-2.el6.i686 libX11-1.5.0-4.el6.i686 libXau-1.0.5-1.el6.i686 libXcomposite-0.4.1-2.el6.i686 libXcursor-1.1.10-2.el6.i686 libXdamage-1.1.2-1.el6.i686 libXext-1.1-3.el6.i686 libXfixes-4.0.4-1.el6.i686 libXi-1.6.1-3.el6.i686 libXinerama-1.1-1.el6.i686 libXrandr-1.4.0-1.el6.i686 libXrender-0.9.7-2.el6.i686 libart_lgpl-2.3.20-5.1.el6.i686 libbonobo-2.24.2-5.el6.i686 libbonoboui-2.24.2-3.el6.i686 libcanberra-0.22-1.el6.i686 libcanberra-gtk2-0.22-1.el6.i686 libcom_err-1.41.12-12.el6.i686 libgcc-4.4.7-3.el6.i686 libgnome-2.28.0-11.el6.i686 libgnomecanvas-2.26.0-4.el6.i686 libgnomeui-2.24.1-4.el6.i686 libogg-1.1.4-2.1.el6.i686 libpng-1.2.49-1.el6_2.i686 libselinux-2.0.94-5.3.el6.i686 libstdc++-4.4.7-3.el6.i686 libtdb-1.2.10-1.el6.i686 libtool-ltdl-2.2.6-15.5.el6.i686 libuuid-2.17.2-12.7.el6.i686 libvorbis-1.2.3-4.el6_2.1.i686 libxcb-1.5-1.el6.i686 libxml2-2.7.6-4.el6_2.4.i686 mesa-libGLU-7.11-5.el6.i686 nss-softokn-freebl-3.12.9-11.el6.i686 openssl-1.0.0-20.el6_2.5.i686 pango-1.28.1-3.el6_0.5.i686 pixman-0.18.4-1.el6_0.1.i686 popt-1.13-7.el6.i686 qt-4.6.2-25.el6.i686 qt-x11-4.6.2-25.el6.i686 zlib-1.2.3-29.el6.i686
(gdb) where
#0  0x002eeef1 in ?? ()
#1  0x066422e7 in ?? () from /usr/lib/libnvidia-glcore.so.295.59
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
4

1 回答 1

1

答案来自http://www.opengl.org/wiki/Buffer_Object

映射缓冲区时,您可以自由地取消绑定缓冲区。但是,您不能调用任何会导致 OpenGL 在映射时读取、修改或写入该缓冲区的函数。因此,调用 glBufferData​ 已被淘汰,因为使用任何会导致 OpenGL 从中读取的函数(使用使用它的 VAO 进行渲染等)也是如此。

因此,必须对代码进行必要的更改。

void QtRenderer::initializeGL() {
  makeCurrent();

  const char* vertexSource =
    "#version 150\n"
    "in vec2 position;"
    "void main() {"
    "   gl_Position = vec4( position, 0.0, 1.0 );"
    "}";
  const char* fragmentSource =
    "#version 150\n"
    "out vec4 outColor;"
    "void main() {"
    "   outColor = vec4( 1.0, 1.0, 1.0, 1.0 );"
    "}";

  glextensions_loader::load_gl_extensions();

  glGenBuffers( 1, &vbo );

  float vertices[] = {
    0.0f, 0.5f,
    0.5f, -0.5f,
    -0.5f, -0.5f
  };

  glBindBuffer( GL_ARRAY_BUFFER, vbo );
  glBufferData( GL_ARRAY_BUFFER, sizeof( vertices ), vertices, GL_STATIC_DRAW );

  // Create and compile the vertex shader
  GLuint vertexShader = glCreateShader( GL_VERTEX_SHADER );
  glShaderSource( vertexShader, 1, &vertexSource, NULL );
  glCompileShader( vertexShader );

  // Create and compile the fragment shader
  GLuint fragmentShader = glCreateShader( GL_FRAGMENT_SHADER );
  glShaderSource( fragmentShader, 1, &fragmentSource, NULL );
  glCompileShader( fragmentShader );

  // Link the vertex and fragment shader into a shader program
  GLuint shaderProgram = glCreateProgram();
  glAttachShader( shaderProgram, vertexShader );
  glAttachShader( shaderProgram, fragmentShader );
  //glBindFragDataLocation( shaderProgram, 0, "outColor" );
  glLinkProgram( shaderProgram );
  glUseProgram( shaderProgram );

  GLint posAttrib = glGetAttribLocation( shaderProgram, "position" );
  glEnableVertexAttribArray( posAttrib );
  glVertexAttribPointer( posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0 );

  glBindBuffer( GL_ARRAY_BUFFER, 0 ); // <-----------NO SEGFAULT
}

void QtRenderer::paintGL() {
  makeCurrent();

  // Clear the screen to black
  glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
  glClear( GL_COLOR_BUFFER_BIT );

  // Draw a triangle from the 3 vertices
  glBindBuffer( GL_ARRAY_BUFFER, vbo );
  glDrawArrays( GL_TRIANGLES, 0, 3 );
  glBindBuffer( GL_ARRAY_BUFFER, 0 ); // <-----------NO SEGFAULT
}
于 2013-05-16T19:49:03.793 回答