【问题标题】:Xcode 4.5 - OpenGL glEnable(GL_DEPTH_TEST) EXC_BAD_ACCESSXcode 4.5 - OpenGL glEnable(GL_DEPTH_TEST) EXC_BAD_ACCESS
【发布时间】:2013-01-27 20:39:02
【问题描述】:

在我尝试学习 CG 和 OpenGL 之后,我找到了 the book "Interactive Computer Graphics",我认为这对初学者来说是一个不错的选择。现在,我正在尝试按照书中的理论创建所谓的 3D 谢尔宾斯基垫片。该项目在 Xcode 4.5 中构建并运行良好,但是当它到达 glEnable(GL_DEPTH_TEST) 行时,它崩溃并且 Xcode 显示错误 Exc_bad_access

我的代码如下所示:

//
//  main.cpp
//  SierpinskiGasket
//
//  Created by Federico Martinez on 24.01.13.
//  Copyright (c) 2013 ParallelDev. All rights reserved.
//

#include "Angel.h"

const int NumTimesToSubdivide = 3;
const int NumTriangles = 27;  // 3^5 triangles generated
const int NumVertices  = 3 * NumTriangles;

vec3 points[NumVertices];
vec3 base_colors[4] = {
    vec3(1.0, 0.0, 0.0),
    vec3(0.0, 1.0, 0.0),
    vec3(0.0, 0.0, 1.0),
    vec3(0.0, 0.0, 0.0)
};
vec3 colors[NumVertices];

int Index = 0;
int colorIndex;

//----------------------------------------------------------------------------

void triangle( const vec3& a, const vec3& b, const vec3& c ){
    colors[Index] = base_colors[colorIndex];
    points[Index++] = a;
    colors[Index] = base_colors[colorIndex];
    points[Index++] = b;
    colors[Index] = base_colors[colorIndex];
    points[Index++] = c;
}
//----------------------------------------------------------------------------

void tetra(vec3 a, vec3 b, vec3 c, vec3 d){
    colorIndex = 0;
    triangle(a, b, c);
    colorIndex = 1;
    triangle(a, c, d);
    colorIndex = 2;
    triangle(a, d, b);
    colorIndex = 3;
    triangle(b, d, c);
}
//----------------------------------------------------------------------------

void divide_tetra(const vec3& a, const vec3& b, const vec3& c, const vec3& d, int count){
    if ( count > 0 ) {
        vec3 mid[6];

        mid[0] = (a+b) / 2.0;
        mid[1] = (a+c) / 2.0;
        mid[2] = (a+d) / 2.0;
        mid[3] = (b+c) / 2.0;
        mid[4] = (c+d) / 2.0;
        mid[5] = (b+d) / 2.0;

        divide_tetra(a, mid[0], mid[1], mid[2], count-1);
        divide_tetra(mid[0], b, mid[3], mid[5], count-1);
        divide_tetra(mid[1], mid[3], c, mid[4], count-1);
        divide_tetra(mid[2], mid[5], mid[5], d, count-1);

    }else {
        tetra(a, b, c, d);    // draw tetrahedron at end of recursion
    }
}

//----------------------------------------------------------------------------

void
init( void )
{
    vec3 vertices[4] = {
        vec3(-1.0, -1.0, -1.0),
        vec3(1.0, -1.0, -1.0),
        vec3(0.0, 1.0, -1.0),
        vec3(0.0, 0.0, 1.0)
    };

    // Subdivide the original triangle
    divide_tetra(vertices[0], vertices[1], vertices[2], vertices[3], NumVertices);

    // Create a vertex array object
    GLuint vao;
    glGenVertexArrays( 1, &vao );
    glBindVertexArray( vao );

    // Create and initialize a buffer object
    GLuint buffer;
    glGenBuffers( 1, &buffer );
    glBindBuffer( GL_ARRAY_BUFFER, buffer );

    glBufferData( GL_ARRAY_BUFFER, sizeof(points)+sizeof(colors), NULL, GL_STATIC_DRAW );
    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(points), points);
    glBufferSubData(GL_ARRAY_BUFFER, sizeof(points), sizeof(colors), colors);

    // Load shaders and use the resulting shader program
    GLuint program = InitShader( "vertex.glsl", "fragment.glsl" );
    glUseProgram( program );

    // Initialize the vertex position attribute from the vertex shader
    GLuint loc = glGetAttribLocation( program, "vPosition" );
    glEnableVertexAttribArray( loc );
    glVertexAttribPointer( loc, 3, GL_FLOAT, GL_FALSE, 0,
                          BUFFER_OFFSET(0) );


    GLuint loc2 = glGetAttribLocation(program, "vColor");
    glEnableVertexAttribArray(loc2);
    glVertexAttribPointer(loc2, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(points)));

    glClearColor( 1.0, 1.0, 1.0, 1.0 ); /* white background */
}

void display(){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glDrawArrays(GL_TRIANGLES, 0, NumVertices);
    glFlush();
}

int main(int argc, char** argv){

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_3_2_CORE_PROFILE | GLUT_DEPTH);
    glEnable(GL_DEPTH_TEST);
    glutInitWindowSize(640, 480);
    glutCreateWindow("Sierpinski Gasket Recursive");

    init();

    glutDisplayFunc(display);

    glutMainLoop();

    return 0;
}

大部分代码来自本书。 Angel.hInitShader.cpp 文件提供了大部分着色器和矢量实用程序,它们由本书的作者提供。

Exc_bad_access 是什么意思?代码中是否有任何错误可能导致此问题?

更新 GDB 堆栈跟踪

(gdb) t a a bt

Thread 5 (process 60424):
#0  0x00007fff8ecce6d6 in __workq_kernreturn ()
#1  0x00007fff8e5fdeec in _pthread_workq_return ()
#2  0x00007fff8e5fdcb3 in _pthread_wqthread ()
#3  0x00007fff8e5e8171 in start_wqthread ()

Thread 4 (process 60424):
#0  0x00007fff8ecce6d6 in __workq_kernreturn ()
#1  0x00007fff8e5fdeec in _pthread_workq_return ()
#2  0x00007fff8e5fdcb3 in _pthread_wqthread ()
#3  0x00007fff8e5e8171 in start_wqthread ()

Thread 3 (process 60424):
#0  0x00007fff8ecce6d6 in __workq_kernreturn ()
#1  0x00007fff8e5fdeec in _pthread_workq_return ()
#2  0x00007fff8e5fdcb3 in _pthread_wqthread ()
#3  0x00007fff8e5e8171 in start_wqthread ()

Thread 2 (process 60424):
#0  0x00007fff8ecced16 in kevent ()
#1  0x00007fff8d6b0dea in _dispatch_mgr_invoke ()
#2  0x00007fff8d6b09ee in _dispatch_mgr_thread ()

Thread 1 (process 60424):
#0  0x00007fff8ecf03d7 in glEnable ()
#1  0x000000010000212a in main (argc=1, argv=0x7fff5fbff800) at /Users/BRabbit27/Documents/COURSERA/ComputerGraphicsBook/SierpinskiGasket3D/SierpinskiGasket3D/main.cpp:129

更新 LLDB 堆栈跟踪

(lldb) bt all
* thread #1: tid = 0x2e03, 0x00007fff8ecf03d7 libGL.dylib`glEnable + 15, stop reason = EXC_BAD_ACCESS (code=1, address=0x248)
    frame #0: 0x00007fff8ecf03d7 libGL.dylib`glEnable + 15
    frame #1: 0x000000010000212a SierpinskiGasket3D`main + 58 at main.cpp:129
    frame #2: 0x00007fff8fd5e7e1 libdyld.dylib`start + 1

  thread #2: tid = 0x3103, 0x00007fff8ecced16 libsystem_kernel.dylib`kevent + 10
    frame #0: 0x00007fff8ecced16 libsystem_kernel.dylib`kevent + 10
    frame #1: 0x00007fff8d6b0dea libdispatch.dylib`_dispatch_mgr_invoke + 883
    frame #2: 0x00007fff8d6b09ee libdispatch.dylib`_dispatch_mgr_thread + 54

  thread #3: tid = 0x3203, 0x00007fff8ecce6d6 libsystem_kernel.dylib`__workq_kernreturn + 10
    frame #0: 0x00007fff8ecce6d6 libsystem_kernel.dylib`__workq_kernreturn + 10
    frame #1: 0x00007fff8e5fdeec libsystem_c.dylib`_pthread_workq_return + 25
    frame #2: 0x00007fff8e5fdcb3 libsystem_c.dylib`_pthread_wqthread + 412
    frame #3: 0x00007fff8e5e8171 libsystem_c.dylib`start_wqthread + 13

  thread #4: tid = 0x3303, 0x00007fff8ecce6d6 libsystem_kernel.dylib`__workq_kernreturn + 10
    frame #0: 0x00007fff8ecce6d6 libsystem_kernel.dylib`__workq_kernreturn + 10
    frame #1: 0x00007fff8e5fdeec libsystem_c.dylib`_pthread_workq_return + 25
    frame #2: 0x00007fff8e5fdcb3 libsystem_c.dylib`_pthread_wqthread + 412
    frame #3: 0x00007fff8e5e8171 libsystem_c.dylib`start_wqthread + 13

  thread #5: tid = 0x3403, 0x00007fff8ecce6d6 libsystem_kernel.dylib`__workq_kernreturn + 10
    frame #0: 0x00007fff8ecce6d6 libsystem_kernel.dylib`__workq_kernreturn + 10
    frame #1: 0x00007fff8e5fdeec libsystem_c.dylib`_pthread_workq_return + 25
    frame #2: 0x00007fff8e5fdcb3 libsystem_c.dylib`_pthread_wqthread + 412
    frame #3: 0x00007fff8e5e8171 libsystem_c.dylib`start_wqthread + 13

【问题讨论】:

  • 你能发布崩溃的堆栈跟踪吗?这不是我希望自己崩溃的功能。
  • 您能告诉我如何在 Xcode 中打印堆栈跟踪吗?
  • 在调试器提示符下键入“t a bt”,这将显示应用程序中所有线程的所有堆栈。
  • 抱歉,我应该这样输入吗?如果是这样,我得到这个(lldb) t a a bt Ambiguous command 't'. Possible matches: target thread type
  • 我想我明白了,检查我的更新。

标签: opengl xcode4.5 osx-mountain-lion glut


【解决方案1】:

简答:将所有 OpenGL 调用移到 glutCreateWindow 之后。

基本原理:OpenGL 使用一种称为 context 的数据结构,它存储了它的所有内部状态:纹理、着色器、状态设置等。每个 OpenGL 函数都会在启动它之前访问当前上下文手术。创建上下文是您正在使用的窗口系统的一个功能,或者在 GLUT 的情况下,glutCreateWindow 功能。 OP 中发生的情况是 OpenGL 实现有效地取消引用 NULL 指针,并导致异常。

这对于 OpenGL 实现来说是一种糟糕的形式 - 如果没有当前上下文,大多数实现通常只会让任何 OpenGL 函数立即返回。

【讨论】:

猜你喜欢
  • 2014-07-30
  • 2013-03-07
  • 2020-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-03
相关资源
最近更新 更多