2017-12-09 18 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 또는 이와 유사한 저장소 개체에서 발생하는 문제를 암시합니다.

  • 에만 glEnableClientState를 호출하고 그들이 glDrawArrays 전에 모든 프레임을 호출 할 필요가있을 때 그것의, 한 번 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)); 

빠른 해결책이는 텍스처 좌표를 가리함으로써 정점 배열 포인터 상태를 덮어하지 물론이지만,를 지정합니다 texcoord 배열 포인터 glTexCoordPointer 통해.

해결책은 10 년 후 deprecated0 인 GL을 포기하고 GL 3.2 코어 프로필 이상을 사용하여 "modern"OpenGL로 전환하는 것입니다.