toeplitz
toeplitz

Reputation: 787

OpenGL texturing using VBO and element array indexing

I am trying to use element indexes with my vertex and texture coordinates stored in a vector type.

My problem is that the texture is not rendering properly on my rectangle.

Here is the relevant shader initialization:

prog = f.compile_shaders(vshader, fshader);
const char* uniform_name = "mvp";
this->uni_mvp = glGetUniformLocation(prog, uniform_name);
if (this->uni_mvp == -1) {
    fprintf(stderr, "Could not bind uniform %s\n", uniform_name);
    return;
}

uniform_name = "texData";
this->uni_texdata = glGetUniformLocation(prog, uniform_name);
if (this->uni_texdata == -1) {
    fprintf(stderr, "Could not bind uniform %s\n", uniform_name);
    return;
}

And vertex shader:

layout(location = 0) in vec4 coord3d;
layout(location = 1) in vec2 texcoord;
uniform mat4 mvp;
out vec2 uv;

void main(void) {
    gl_Position = mvp * coord3d;
    uv = texcoord;
}

And fragment shader:

in vec2 uv;
out vec3 color;

uniform sampler2D texData;

void main(){
    color = texture2D(texData, uv).rgb;
}

Here is my relevant BUFFER initialization code:

    glGenVertexArrays(1, &this->vao);
    glBindVertexArray(this->vao);

    glm::vec2 bar;
    bar.x = 0.0; bar.y = 0.0;
    texcoords.push_back(bar);
    bar.x = 1.0; bar.y = 0.0;
    texcoords.push_back(bar);
    bar.x = 1.0; bar.y = 1.0;
    texcoords.push_back(bar);
    bar.x = 0.0; bar.y = 1.0;
    texcoords.push_back(bar);


    glm::vec4 foo;
    foo.x = 0.0; foo.y = 0.0; foo.z = 0; foo.w = 1.0;
    vertices.push_back(foo);
    foo.x = 10.0; foo.y = 0.0; foo.z = 0; foo.w = 1.0;
    vertices.push_back(foo);
    foo.x = 10.0; foo.y = 10.0; foo.z = 0; foo.w = 1.0;
    vertices.push_back(foo);
    foo.x = 0.0; foo.y = 10.0; foo.z = 0; foo.w = 1.0;
    vertices.push_back(foo);

    elements.push_back(0);
    elements.push_back(1);
    elements.push_back(2);
    elements.push_back(3);

    glGenBuffers(1, &this->tbo);
    glBindBuffer(GL_ARRAY_BUFFER, this->tbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(texcoords) * sizeof(texcoords[0]), texcoords.data(), GL_STATIC_DRAW);

    glGenBuffers(1, &this->vbo);
    glBindBuffer(GL_ARRAY_BUFFER, this->vbo);
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(vertices[0]), vertices.data(), GL_STATIC_DRAW);

    glGenBuffers(1, &this->ibo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, elements.size() * sizeof(elements[0]), elements.data(), GL_STATIC_DRAW);

Here is my relevant TEXTURE initialization code:

    glGenTextures(1, &this->texture_id);
glBindTexture(GL_TEXTURE_2D, this->texture_id);

int k = 12;
GLubyte image[12][12][3];
for ( int i = 0; i < k; i++ ) {
    for ( int j = 0; j < k; j++ ) {
        GLubyte c = (((i & 0x8) == 0) ^ ((j & 0x8)  == 0)) * 255;
        image[i][j][0]  = c;
        image[i][j][1]  = c;
        image[i][j][2]  = c;
    }
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);    
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, k, k, 0, GL_RGB, GL_UNSIGNED_BYTE, image);

Here is the relevant rendering/display code:

    glUseProgram(this->prog);
glBindVertexArray(this->vao);
glUniformMatrix4fv(this->uni_mvp, 1, GL_FALSE, glm::value_ptr(f.mvp));

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,  this->texture_id);
glUniform1i(this->uni_texdata, 0);

glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, this->vbo);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);

glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, this->tbo);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->ibo);
glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
glDrawElements(GL_QUADS, size / sizeof(GLushort), GL_UNSIGNED_SHORT, 0);

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);

glBindVertexArray(0);

This code render my rectangle with the texture, however the texture is wrong (just not displaying properly on the rectangle). The texturing coordinates should be correct for this simple example by my knowledge. Is there a problem with indexing and texture - vertex coordinates in how I do this?

Here is a picture of the rendering on my green background:

enter image description here

I am expecting a rectangular black and white checkerboard (12 parts).

Ok, after adding the last texture coordinate the rendering looks like this:

enter image description here

UDPATE: When creating the checkerboard texture bigger for example GLubyte image[16][16][3]; I get the following rendering:

enter image description here

I also notice that my .raw files render correctly. Still I am expecting to see 16 x 16 squares in my checkerboard texture?

Upvotes: 1

Views: 1201

Answers (1)

Tim
Tim

Reputation: 35933

I don't think there's anything wrong with your OpenGL anymore, though your texture generating function I don't think does what you expect.

for ( int i = 0; i < k; i++ ) {
    for ( int j = 0; j < k; j++ ) {
        GLubyte c = (((i & 0x8) == 0) ^ ((j & 0x8)  == 0)) * 255;
        ...
    }
}

You've got 16 texels from left to right, and you alternate the color every 8 in the X or Y direction.

Why do you think this will generate 12 (or 16) checkers across? You should remove the & 0x8 if you want to alternate color on every increment.

Upvotes: 1

Related Questions