1

I want to create mesh class with VBO in C++. The class looks like following:

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

The problem is in the texture coordinates only. I'm trying to create the mesh like so:

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

But the result is wrong, as you can see in the left picture below (the picture on the right is the desired one):

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

The vertices are in ortho mode, so the coordinate origin for vertices is in top left corner and for texture coordinates the origin is in the bottom left just like in OpenGL.

1 Answer 1

5

When one is using indices to address the vertex positions, the texture coordinates also get indexed. In your case this means, that you are only using the first four entries in texCoords. The strange looking comes from texCoords[0] == texCoords[3].

The correct texCoords would most probably be

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

These can be derived from the vertex-coordinates: texCoords should have the same value at a component whenever their corresponding vertices have the same component value. e.g. if vertices[0].y == vertices[1].y => texCoords[0].y == texCoords[1].y and so on. In addition, the texCoords y coordinates have to be flipped, since vertex origin as on top-left while texcoords start at bottom left.

Edit:

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

does not look correct to me. This statement tells that the first texture coordinate starts after the sixth vector3, but shouldn't they start after the fourth one? (You only have 4 entries in vertices):

glTexCoordPointer(2, GL_FLOAT, 0, (void*)(sizeof(float)*3*4));
Sign up to request clarification or add additional context in comments.

7 Comments

So I only need 4 texture coords instead of 6? Even if I use GL_TRIANGLES? I have tried it with 4 texture coords as well, but it did not work either.
Yes, you only need 4 texture coordinates. I added my suggestion for the correct version to the answer
I have tried it with 4 tex coords as well, but it didn't work, so I put back the 6 texcoords. I think the main problem is in the VBO class....
+1, though there's a second issue. the offset to find the texture data is wrong. It's trying to go past 6 verts, but there are only 4 in the buffer.
I can't compile right now, so I sent it to my friend and he tried it right now with all the edits and it does not work :/ I will be at home in 90 minutes, so I will give it a try and post back. He tells me, that the texture is now stretched horizontally.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.