Координаты текстуры объекта OpenGL Vertexbuffer

Я хочу создать класс сетки с VBO в C++. Класс выглядит следующим образом:

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

Проблема только в текстурных координатах. Я пытаюсь создать сетку так:

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.

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 должно быть одинаковое значение в компоненте всякий раз, когда их соответствующие вершины имеют одинаковое значение компонента. например, если вершины [0].y == вершины [1].y => texCoords[0].y == texCoords[1].y и так далее. Кроме того, координаты texCoords y должны быть перевернуты, поскольку начало вершины, как в верхнем левом углу, в то время как texcoords начинается в левом нижнем углу.

Редактировать:

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

не выглядит правильным для меня. Это утверждение говорит о том, что первая координата текстуры начинается после шестого вектора3, но не должны ли они начинаться после четвертого? (У вас есть только 4 записи в вершинах):

glTexCoordPointer(2, GL_FLOAT, 0, (void*)(sizeof(float)*3*4));
Другие вопросы по тегам