【问题标题】:OpenGL Vertexbuffer object texture coordinatesOpenGL顶点缓冲区对象纹理坐标
【发布时间】:2015-01-21 15:15:37
【问题描述】:

我想用 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);

但是结果是错误的,如下左图所示(右图是想要的):

顶点处于正交模式,因此顶点的坐标原点在左上角,而纹理坐标的原点在左下角,就像在 OpenGL 中一样。

【问题讨论】:

    标签: c++ opengl textures vbo


    【解决方案1】:

    当使用索引来处理顶点位置时,纹理坐标也会被索引。在您的情况下,这意味着您仅使用 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));
    

    【讨论】:

    • 所以我只需要 4 个纹理坐标而不是 6 个?即使我使用GL_TRIANGLES?我也尝试过使用 4 个纹理坐标,但也没有用。
    • 是的,您只需要 4 个纹理坐标。我在答案中添加了我对正确版本的建议
    • 我也用 4 tex coords 试过了,但是没用,所以我放回了 6 texcoords。我认为主要问题出在 VBO 类中......
    • +1,尽管还有第二个问题。查找纹理数据的偏移量是错误的。它试图超过 6 个顶点,但缓冲区中只有 4 个。
    • 我现在无法编译,所以我把它发给了我的朋友,他现在就尝试了所有的编辑,但它不起作用:/ 我将在 90 分钟后到家,所以我会试一试并回帖。他告诉我,纹理现在被水平拉伸了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-04
    • 1970-01-01
    • 2015-04-14
    • 2014-07-31
    • 1970-01-01
    相关资源
    最近更新 更多