簡體   English   中英

OpenGL Vertexbuffer 對象紋理坐標

[英]OpenGL Vertexbuffer object texture coordinates

我想在 C++ 中使用 VBO 創建網格類。 該類如下所示:

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);
}

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);
}

問題僅在於紋理坐標。 我正在嘗試像這樣創建網格:

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);

但是結果是錯誤的,如下圖左圖所示(右圖是想要的):

左邊圖片來自VBO,右邊是立即模式

頂點處於正交模式,所以頂點的坐標原點在左上角,紋理坐標的原點在左下角,就像在 OpenGL 中一樣。

當使用索引來尋址頂點位置時,紋理坐標也會被索引。 在您的情況下,這意味着您僅使用 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 就應該在一個組件上具有相同的值。 例如,如果 vertices[0].y == vertices[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));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM