2015-01-21 4 views
1

C++에서 VBO로 메쉬 클래스를 만들고 싶습니다. 클래스는 다음과 같습니다.OpenGL Vertexbuffer 오브젝트 텍스처 좌표

mesh::mesh(std::vector<Vector3d>* Vertices, std::vector<unsigned int>* Indices, std::vector<Vector2d>* TextureCoords) 
{ 
    if(Vertices) this->vertices = *Vertices; 
    if(Indices) this->indices = *Indices; 
    if(TextureCoords) this->textureCoords = *TextureCoords; 
    chatbox.AddMessageToQueue("vertices.size() : %d", vertices.size()); 
    glGenBuffers(1, &VBO); 
    glBindBuffer(GL_ARRAY_BUFFER, VBO); 
    glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(Vector3d) + textureCoords.size()*sizeof(Vector2d), 0, GL_STATIC_DRAW); 
    glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size()*sizeof(Vector3d), vertices.data()); 
    glBufferSubData(GL_ARRAY_BUFFER, vertices.size()*sizeof(Vector3d), textureCoords.size()*sizeof(Vector2d), textureCoords.data()); 

    glGenBuffers(1, &IND); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IND); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(unsigned int), &indices[0], GL_STATIC_DRAW); 
} 

mesh::~mesh() 
{ 
    glDeleteBuffers(1, &VBO); 
    glDeleteBuffers(1, &IND); 
} 

void mesh::draw() 
{ 
    glEnableClientState(GL_VERTEX_ARRAY); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
    glBindBuffer(GL_ARRAY_BUFFER, VBO); 

    glVertexPointer(3, GL_FLOAT, 0, (void*)0); 
    glTexCoordPointer(2, GL_FLOAT, 0, (void*)(sizeof(float)*3*6)); 

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IND); 
    glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (unsigned int*)0 + 0); 

    glDisableClientState(GL_VERTEX_ARRAY); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
} 

문제는 텍스처 좌표에만 있습니다. 내가 그렇게 같은 메쉬 만들려고 해요 :

The image on the left side is from VBO, on the right side is immediate mode :

std::vector<unsigned int> indices; 
std::vector<mesh::Vector3d> vertices; 
std::vector<mesh::Vector2d> texCoords; 

vertices.push_back({PosX, PosY, 1.0}); 
vertices.push_back({PosX + SizeX, PosY, 1.0}); 
vertices.push_back({PosX + SizeX, PosY + SizeY, 1.0}); 
vertices.push_back({PosX, PosY + SizeY, 1.0}); 

indices.push_back(0); 
indices.push_back(1); 
indices.push_back(2); 

indices.push_back(0); 
indices.push_back(2); 
indices.push_back(3); 

texCoords.push_back({0, 1}); 
texCoords.push_back({1, 0}); 
texCoords.push_back({0, 0}); 

texCoords.push_back({0, 1}); 
texCoords.push_back({1, 1}); 
texCoords.push_back({1, 0}); 

gui_checkbox = new mesh(&vertices, &indices, &texCoords); 

을하지만, 아래 왼쪽 그림에서 볼 수있는 결과가 잘못 (오른쪽 사진이 원하는 일입니다)

정점은 정사 모드이므로 정점의 좌표 원점은 왼쪽 위 모서리에 있고 텍스처 좌표의 경우 원점은 OpenGL 에서처럼 맨 아래 왼쪽에 있습니다.

답변

5

인덱스를 사용하여 정점 위치를 지정하면 텍스처 좌표도 인덱싱됩니다. 귀하의 경우 이것은 texCoords의 처음 네 항목 만 사용하고 있다는 것을 의미합니다. 이상한보고는 texCoords [0] == texCoords [3]에서옵니다.

올바른 texCoords는 대부분의 아마

texCoords.push_back({0, 1}); 
texCoords.push_back({1, 1}); 
texCoords.push_back({1, 0}); 
texCoords.push_back({0, 0}); 

가 정점 좌표로부터 도출 될 수있을 것이다 : 해당 정점이 동일한 구성 요소 값을 가질 때마다 texCoords이 구성 요소에 동일한 값을 가져야한다. 예 : if vertex [0] .y == 꼭지점 [1] .y => texCoords [0] .y == texCoords [1] .y 등등. 또한 texCoords y 좌표는 뒤집어 져야합니다. 꼭지점 원점은 왼쪽 상단으로, texcoords는 왼쪽 하단부터 시작해야합니다.

편집 :

glTexCoordPointer(2, GL_FLOAT, 0, (void*)(sizeof(float)*3*6)); 

나에게 올바른 보이지 않는다. 이 문장은 첫 번째 텍스쳐 좌표가 여섯 번째 vector3 이후에 시작하지만 네 번째 텍스쳐 좌표가 네 번째 텍스쳐 좌표 뒤에 오면 안된다는 것을 알려줍니다. (정점에 4 개의 항목 만 있습니다.)

glTexCoordPointer(2, GL_FLOAT, 0, (void*)(sizeof(float)*3*4)); 
+0

그래서 6 대신 4 개의 텍스처 좌표 만 필요합니까? 'GL_TRIANGLES'을 사용하더라도? 나는 4 개의 텍스처 좌표로 시도했지만, 역시 작동하지 않았다. – ProXicT

+0

네, 텍스처 좌표가 4 개만 필요합니다. 나는 정확한 대답에 대한 제언을 – BDL

+0

에 추가했습니다. 4 텍스 코드로 시도했지만 작동하지 않아 6 텍스 코드를 되돌려 놓았습니다. VBO 클래스에서 주 문제가 있다고 생각합니다. – ProXicT