0

CGとOpenGLを学ぼうと試みた後、「インタラクティブコンピュータグラフィックス」という本を見つけました。これは初心者にとっては良い本だと思います。今、私は本の理論に従って、いわゆるシェルピンスキーのガスケットを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
4

1 に答える 1

5

簡単な答え:OpenGL呼び出しを。の後に移動しますglutCreateWindow

理論的根拠:OpenGLは、コンテキストと呼ばれるデータ構造を使用します。このデータ構造には、テクスチャ、シェーダー、状態設定などのすべての内部状態が格納されます。すべてのOpenGL関数は、操作を開始する前に現在のコンテキストにアクセスします。コンテキストの作成は、使用しているウィンドウシステムの関数であり、GLUTの場合はそのglutCreateWindow関数です。OPで起こっていることは、OpenGL実装がNULLポインターを効果的に逆参照し、例外を引き起こしていることです。

これはOpenGL実装にとっては悪い形式です。ほとんどの実装では、現在のコンテキストがない場合、通常はOpenGL関数がすぐに返されます。

于 2013-01-29T06:43:39.290 に答える