2017-12-09 7 views
-2

私はGLFWバージョン2を使用してOpenGLのビデオゲームを作る私はOpenGLのスレッド1:EXC_BAD_ACCESS(コード= 1、アドレス= 0x0の)

次のコードを理解していないエラーを取得していますが、次のとおりです。

// 
// GameWindow.cpp 
// RocketGame 
// 
// Created by Vaibhav Malhotra on 12/5/17. 
// Copyright © 2017 Vaibhav Malhotra. All rights reserved. 
// 

#include "GameWindow.hpp" 

typedef struct 
{ 
    GLfloat positionCoordinates[3]; 
    GLfloat textureCoordinates[2]; 
} vertexData; 

#define Square_Size 100 

vertexData vertices[] = { 
    {{0.0f,0.0f,0.0f}, {0.0f,0.0f}}, 
    {{Square_Size,0.0f,0.0f},{1.0f,0.0f}}, 
    {{Square_Size,Square_Size,0.0f},{1.0f,1.0f}}, 
    {{0.0f,Square_Size,0.0f},{0.0f,1.0f}} 


}; 

void GameWindow::setRunning(bool newRunning) 
{ 
    _running = newRunning; 
} 

bool GameWindow::getRunning() 
{ 
    return _running; 

} 

GLuint GameWindow::loadAndBufferImage(const char *filename) 
{ 
    GLFWimage imageData; 
    glfwReadImage(filename, &imageData, NULL); 
    GLuint textureBufferID; 
    glGenTextures(1, &textureBufferID); 
    glBindTexture(GL_TEXTURE_2D, textureBufferID); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageData.Width, imageData.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData.Data); 

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 

    glfwFreeImage(&imageData); 

    return textureBufferID; 



} 

GameWindow::GameWindow(bool running):_running(running),_height(800),_width(800*16/9),_vertexBufferID(0) 
{ 

    glClearColor(1.0f, 1.0f, 1.0f, 1.0f); 
    glViewport(0.0f, 0.0f, _width, _height); 

    glEnable(GL_TEXTURE_2D); 
    glEnable(GL_BLEND); 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 

    glMatrixMode(GL_PROJECTION); 
    gluOrtho2D(0, _width, 0, _height); 
    glMatrixMode(GL_MODELVIEW); 

    glGenBuffers(1, &_vertexBufferID); 
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferID); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 

    glEnableClientState(GL_VERTEX_ARRAY); 
    glVertexPointer(3, GL_FLOAT, sizeof(vertexData), (GLvoid *) offsetof(vertexData, positionCoordinates)); 

    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
    glVertexPointer(2, GL_FLOAT, sizeof(vertexData), (GLvoid *) offsetof(vertexData, textureCoordinates)); 

    _textureBufferID = loadAndBufferImage("rocket.tga"); 


} 

void GameWindow::render() 
{ 
    glClear(GL_COLOR_BUFFER_BIT); 

    //glColor3f(1.0f, 0.0f, 0.0f); 
    glDrawArrays(GL_QUADS, 0, 4); 

    glfwSwapBuffers(); 


} 

void GameWindow::update() 
{ 

} 

レンダリング機能の下でコードglDrawArrays(GL_QUADS, 0, 4);が実行時エラーThread 1: EXC_BAD_ACCESS (code=1, address=0x0)を返しています。

出力に関しては、黒い画面が表示されています。

なぜこのエラーが表示されますか?

+0

[mcve]で編集します。 – genpfault

答えて

0

レンダリング機能では、コードglDrawArrays(GL_QUADS、0、4);実行時エラースレッド1を返しています:EXC_BAD_ACCESS(コード= 1、アドレス= 0x0)。

glDrawArraysのメモリアクセス違反は、一般的にVBOや類似のストレージオブジェクトで何らかの問題を示唆しています。

私が言うことができるものから、あなたのコードを持つ3つの問題があります。

  • は、彼らがglDrawArrays前に、すべてのフレームと呼ばする必要がある場合にのみ、一度glEnableClientStateとそれに対応するgl*Pointerのコールを呼び出しています。一度だけ呼び出す場合は、Vertex Array Objects (VAOs)を参照してください.OpenGL 3以降でのみ使用できますが、glEnableClientStateの呼び出しを移動するときには、バッファがglBindBufferに再度バインドされていることを確認する必要があります。
  • 各クライアント状態には、対応するgl*Pointerコールがあります。 GL_VERTEX_ARRAYにはglVertexPointerを正しく使用しますが、GL_TEXTURE_COORD_ARRAYにはglTexCoordPointerが必要です。
  • glEnableClientStateコールには、対応するglDisableClientStateコールがありません。これは、glDrawArraysコールの後に、有効化コールの逆の順序でコールする必要があります。

はただ、サイドノートとして、GLUライブラリが廃止されました。あなたのgluOrtho2Dコールは、あなたがそれに依存する唯一のインスタンスであるように思われ、それが簡単に置き換えることができます。

glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
glOrtho(0, _width, 0, _height, -1.0f, 1.0f); 
0

それは何である、アドレス0のメモリを読み取ろうとするので、あなたはglDrawArraysで例外を取得していますあなたのコードは実際に指定します。

GLのテクスチャ座標アレイポインタは、NULLに初期化され、VBOはありません。レガシーGLを使用しているので、これはクライアントメモリアドレスとして解釈されます。それはとどまるので、glTexCoordPointerを今、あなたはGL_TEXCOORD_ARRAYを有効にするが、実際に設定されていないNULL

glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
glVertexPointer(2, GL_FLOAT, sizeof(vertexData), (GLvoid *) offsetof(vertexData, textureCoordinates)); 

迅速な解決策は、それがテクスチャcoordsのを指すことによって、あなたの頂点配列ポインタの状態を上書きしないことはもちろんであるが、指定しますtexcoord配列ポインタglTexCoordPointer経由。

リアル解決策は、10年後に廃止予定のレガシーGLをあきらめて、GL 3.2コアプロファイル以上を使用して「最新の」OpenGLに切り替えることです。

関連する問題