2017-10-14 1 views
0

C++과 OpenGL을 사용하여 3D 체스 게임을 만들려고하는데,이 과정에서 삼각형 (체스 조각) 그리기 실 거예요 그리고 나는 빈 화면으로 남아있다. 피스 클래스가 아닌 main 함수에서 메쉬 개체를 만들면 문제없이 작동하지만 피스 클래스에있을 때는 그렇지 않습니다. 포인터에 문제가 있습니까? C++ OpenGL 객체 내에 vbo와 vao가 저장된 드로잉 메쉬를 사용합니다.

그래서 메인에 내가 메시가 루프에 그려진 주요 방법에

Piece piece = Piece(vec3(0, 0, 0)); //Create a chess peice 

나중에 체스의 peice를 만들

(그리기 방법이 표시됩니다 : 여기

내 코드입니다 나중에이 게시물에서)

piece.GetMesh().Draw(); //Draw the chess peice 

내가 메시 정보와 객체 생성 체스의 peice 헤더 :

//Mesh information 
vector <vec3> verticies; 
vector <unsigned int> indicies; 
Mesh mesh; 

체스 피스의 .cpp 파일에서 메쉬 오브젝트 을 만듭니다. verticies는 vec3 벡터이고 indicies는 부호없는 int 벡터입니다.

mesh = Mesh(verticies, indicies); //Create the mesh object 

메쉬 생성자

Mesh::Mesh(vector <vec3> verticies, vector <unsigned int> indicies) 
{ 
    unsigned int numVerticies = verticies.size(); 
    unsigned int numIndicies = indicies.size(); 

    vector <vec2> texCoords; 

    //set the tex coords 
    unsigned int texCoordsIndex = 0; 

    for (unsigned int i = 0; i < numIndicies; i++) 
    { 
     switch (texCoordsIndex) 
     { 
     case 0: 
      texCoords.push_back(vec2(0, 0)); 
      texCoordsIndex++; 
      break; 
     case 1: 
      texCoords.push_back(vec2(0, 1)); 
      texCoordsIndex++; 
      break; 
     case 2: 
      texCoords.push_back(vec2(1, 1)); 
      texCoordsIndex = 0; 
      break; 
     } 
    } 

    //Sends the mesh to the buffer 
    drawCount = indicies.size(); 

    glGenVertexArrays(1, &vao); 
    glBindVertexArray(vao); 

    glGenBuffers(NUM_BUFFERS, vbo); 
    glBindBuffer(GL_ARRAY_BUFFER, vbo[POSITION_VB]); 
    glBufferData(GL_ARRAY_BUFFER, verticies.size() * sizeof(verticies[0]), &verticies[0], GL_STATIC_DRAW); 

    glEnableVertexAttribArray(0); 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); 

    glBindBuffer(GL_ARRAY_BUFFER, vbo[TEXCOORD_VB]); 
    glBufferData(GL_ARRAY_BUFFER, texCoords.size() * sizeof(texCoords[0]), &texCoords[0], GL_STATIC_DRAW); 

    glEnableVertexAttribArray(1); 
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0); 

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[INDEX_VB]); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicies.size() * sizeof(indicies[0]), &indicies[0], GL_STATIC_DRAW); 

    glBindVertexArray(0); 
} 

이며, 여기에 내가 제공 한 코드가 부족하면 그냥 물어 메쉬 클래스

void Mesh::Draw() 
{ 
    glBindVertexArray(vao); 
    glDrawElements(GL_TRIANGLES, drawCount, GL_UNSIGNED_INT, 0); 
    glBindVertexArray(0); 
} 

내 방법입니다 whitch 그리기 기능입니다 코드 섹션을 스레드에 추가 할 수 있습니다.

감사합니다.

답변

1

은 어쩌면 엉덩이 슛,하지만 당신은 클래스 Mesh의 생성자에서 glGenVertexArrays을 사용하기 때문에, 나는 당신이 클래스 Mesh의 소멸자에서 glDeleteVertexArrays를 사용한다고 가정합니다. 이 라인에서
:

mesh = Mesh(verticies, indicies); 

다음과 같은 상황이 발생합니다

당신은 생성자에서 정점 배열 객체를 생성 임시 Mesh 객체를 생성합니다. 이 시점에서 모든 데이터가 유효하고 정점 배열 객체가 생성됩니다 (GPU). 개체를 할당하면 임시 개체의 멤버가 대상 개체에 복사됩니다. 이제 2 개의 동일한 객체가 존재합니다. 이 작업이 수행 된 직후에 임시 객체의 소멸자가 임시 Mesh 객체를 파괴하고 정점 배열 객체를 삭제합니다 ( glDeleteVertexArrays). 이 시점에서 모든 데이터가 사라졌습니다.

destrutor Mesh::~Mesh에 중단 점을 넣으면 만료를 추적 할 수 있습니다.

클래스를 복사 할 수 없도록 만들고 복사 할 수 없도록 만들고 이동 생성자와 이동 연산자를 지정합니다.

class Mesh 
{ 
    Mesh(const Mesh &) = delete; 
    Mesh & operator = (const Mesh &) = delete; 

    Mesh(Mesh &&); 
    Mesh & operator = (Mesh &&); 

    .... 
}; 

참조 :

+1

: 아니, 그렇게하지 않는다 "* 제거 glDeleteVertexArrays *이 메쉬의 소멸자를 형성" . 소멸자에서 삭제하면이 디자인에 적합합니다. 문제는이 경우처럼 부적절하게 소멸자를 호출하는 것입니다. 이것은 이동 전용 형식이어야하므로 한 인스턴스에서 다른 인스턴스로 VAO를 이동하기위한 이동 생성자/연산자가 있어야합니다. –

+0

@ NicolBolas 나는 맞지 않을 수 있습니다. 물론 당신이 옳습니다. – Rabbid76

관련 문제