0

I am learning OpenGL recently. In one of my exercise, I try to load a texture image and map it onto 6 surfaces of a cube. I also applied simple transformation matrix to the vertex shader.

But it turns out that none of the 6 surfaces got right output. Please see the image.

enter image description here

I suspect that something wrong with the indices and texture coordinate vector, but I checked multiple times, cannot find where the error comes from. Can anyone help me find out the issue? Thanks.

The code:

GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
int width, height;
unsigned char * image = SOIL_load_image("./challenger.jpg", &width, &height, 0, SOIL_LOAD_RGB);
if(image == NULL) { std::cout << "Failed to load image" << std::endl; return -1; }

// Transfer texture data to texture object.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
SOIL_free_image_data(image);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);

//Prepare data    
GLfloat vertices[] = {
    // front plane
    0.5f, 0.5f, 0.5f,
    0.5f, -0.5f, 0.5f,
    -0.5f, -0.5f, 0.5f,
    -0.5f, 0.5f, 0.5f, 
    // back plane
    0.5f, 0.5f, -0.5f,
    0.5f, -0.5f, -0.5f,
    -0.5f, -0.5f, -0.5f,
    -0.5f, 0.5f, -0.5f,
};

// This is my cube.
/*    7       4
 * 3        0
 *   _________
 *  /________/|
 * |        | |
 * |        | |
 * |        | |
 * |________|/  
 *   6        5
 * 2        1  
 */

GLuint indices [] = {
    // top
    4, 0, 3, 
    3, 7, 4,
    // bottom
    5, 1, 2,
    2, 6, 5, 
    // front
    0, 1, 2,
    2, 3, 0,
    // back
    4, 5, 6,
    6, 7, 4,
    // left
    3, 2, 6, 
    6, 7, 3,
    // right
    4, 5, 1,
    1, 0, 4
};

GLfloat texCoords [] = {
    // top
    1.0f, 1.0f,
    1.0f, 0.0f,
    0.0f, 0.0f,
    0.0f, 0.0f,
    0.0f, 1.0f,
    1.0f, 1.0f,
    // bottom
    1.0f, 1.0f,
    1.0f, 0.0f,
    0.0f, 0.0f,
    0.0f, 0.0f,
    0.0f, 1.0f,
    1.0f, 1.0f,
    // front
    1.0f, 1.0f,
    1.0f, 0.0f,
    0.0f, 0.0f,
    0.0f, 0.0f,
    0.0f, 1.0f,
    1.0f, 1.0f,
    // back
    1.0f, 1.0f,
    1.0f, 0.0f,
    0.0f, 0.0f,
    0.0f, 0.0f,
    0.0f, 1.0f,
    1.0f, 1.0f,
    // left
    1.0f, 1.0f,
    1.0f, 0.0f,
    0.0f, 0.0f,
    0.0f, 0.0f,
    0.0f, 1.0f,
    1.0f, 1.0f,
    // right
    1.0f, 1.0f,
    1.0f, 0.0f,
    0.0f, 0.0f,
    0.0f, 0.0f,
    0.0f, 1.0f,
    1.0f, 1.0f
};


// Define VBO, EBO and VAO.
GLuint vbo, ebo, vao;
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);
glGenBuffers(1, &ebo);

GLuint vbo_tex_coords;
glGenBuffers(1, &vbo_tex_coords);

glBindVertexArray(vao);
{
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    GLint posAttribPtrLoc = program.getAttribLocation("position"); 
    glVertexAttribPointer(posAttribPtrLoc, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(posAttribPtrLoc);

    glBindBuffer(GL_ARRAY_BUFFER, vbo_tex_coords);
    glBufferData(GL_ARRAY_BUFFER, sizeof(texCoords), texCoords, GL_STATIC_DRAW);
    GLint texAttribPtrLoc = program.getAttribLocation("texCoord"); 
    glVertexAttribPointer(texAttribPtrLoc, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(texAttribPtrLoc);
}
glBindVertexArray(0);

program.use();

// Create a game loop.
double lastTime = glfwGetTime();
int frame = 0;
while(!glfwWindowShouldClose(window))
{
    glfwPollEvents();

    // Rendering
    glEnable(GL_DEPTH_TEST);
    glClearColor(0.80f, 0.80f, 0.80f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // This uniform should be defined here. Not outside the loop.
    // Define my transform matrix.
    glm::mat4 model, view, projection;
    model = glm::rotate(model, (GLfloat)glfwGetTime() * 1.0f, glm::vec3(1.0f, 1.0f, 1.0f));
    view = glm::translate(view, glm::vec3(0.0f, 0.0f, -2.0f));
    projection = glm::perspective(45.0f, 800.0f/600, 0.1f, 100.0f);
    glm::mat4 transform = projection * view * model;
    GLuint transformLoc = program.getUniformLocation("transform");
    glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform));

    glBindTexture(GL_TEXTURE_2D, texture);
    glBindVertexArray(vao);
    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (GLvoid*)0);
    glBindVertexArray(0);
    glBindTexture(GL_TEXTURE_2D, 0);

    // Finish rendering
    glfwSwapBuffers(window);
    showFPS(window, lastTime, frame);
}

Vertex shader

const GLchar * vsSource = SHADER_SOURCE(
    layout(location = 0) in vec3 position;
    layout(location = 2) in vec2 texCoord;

    out vec2 myTexCoord;
    uniform mat4 transform;

    void main()
    {
        gl_Position = transform * vec4(position.xyz, 1.0f);
        myTexCoord = texCoord;
    }
);

Fragment shader

const GLchar * fsSource = SHADER_SOURCE(
    in vec2 myTexCoord;
    out vec4 color;
    uniform sampler2D sampler;
    void main()
    {
        color = texture(sampler, vec2(myTexCoord.x, 1.0f - myTexCoord.y));
    }
);
Robert Wang
  • 1,121
  • 9
  • 14
  • at GLfloat vertices[] = {} which column represents what? x,y,z coordinate, normalvector x,y,z and u,v texturecoordinate? – Thomas Jun 19 '16 at 20:29
  • 1
    this error looks like your texturecoordinates are set wrong. When you are using ibo, your texture is correct at 2 sides, the other to sides are mirrored and top and bottom are ruined – Thomas Jun 19 '16 at 20:31
  • 1
    The indices are the same for all vertex attributes. So you need to define 24 vertices that contain coordinates, colors, and texture coordinates for each vertex. See for example here: http://stackoverflow.com/questions/25349620/use-one-gl-element-array-buffer-to-reference-each-attribute-from-0. – Reto Koradi Jun 19 '16 at 21:22
  • @RetoKoradi I read your answer in the link. But didn't quite understand that. what does this mean "The indices are the same for all vertex attributes."? Now I started to realize my issue, I guess it is because in the vertex shader, only 8 vertex indices are used, so actually only the first 8 of the tex coordinates are used (all the remaining ones are not touched at all), that's why I got weird tex mapping. is my understanding correct? thanks. – Robert Wang Jun 20 '16 at 05:36
  • @Thomas actually, none of the 6 sides are correct. They all have different and strange looking. I modified the code a bit, the original code contains some unnecessary legacy code. If you can be more specific, it will be highly appreciated. Thanks. – Robert Wang Jun 20 '16 at 05:40

0 Answers0