2
votes

Original post:
https://computergraphics.stackexchange.com/questions/4793/how-can-i-generate-mipmaps-manually
It was a silly mistake, I forgot to set all texture coordinates :P

OpenGL is fairly difficult to learn. According to my understanding of mipmaps, I can set each mipmap level manually, so I could change the image to use when my texture looks greater or smaller.

I tried the following code but doesn't matter the size of the triangle, it always take the first mipmap level. Why? if the triangle is closer to any other mipmap level, why does not take it?

I really hate putting a bunch of code in my questions because I force others to waste time analyzing the code instead of putting the most revelant snippet code, but I don't know where is the problem and I have not alternative. Sorry :(

#include <iostream>

#define GLEW_STATIC
#include <GL/glew.h>

#include <GLFW/glfw3.h>

const GLchar* VERTEX_SHADER_SOURCE =
        "#version 330 core                           \n"
        "layout (location = 0) in vec2 position;     \n"
        "layout (location = 1) in vec2 myTexCoord;   \n"
        "                                            \n"
        "out vec2 TexCoord;                          \n"
        "                                            \n"
        "void main()                                 \n"
        "{                                           \n"
        "    gl_Position = vec4(position,0.0f, 1.0f);\n"
        "    TexCoord = myTexCoord;                  \n"
        "}                                           \n";

const GLchar* FRAGMENT_SHADER_SOURCE =
        "#version 330 core                         \n"
        "in vec2 TexCoord;                         \n"
        "                                          \n"
        "out vec4 color;                           \n"
        "                                          \n"
        "uniform sampler2D ourTexture;             \n"
        "                                          \n"
        "void main()                               \n"
        "{                                         \n"
        "    color = texture(ourTexture, TexCoord);\n"
        "}                                         \n";

int main()
{
    //Change the value of size by 1,2,4,8,16,32,64,128 or 256 and see how the color of the triangle doesn't change. Why does it happen?
    GLint size = 128;

    //INIT STUFFS
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    GLFWwindow* window = glfwCreateWindow(size,size, "", nullptr, nullptr);
    glfwMakeContextCurrent(window);
    glewExperimental = GL_TRUE;
    glewInit();
    glViewport(0, 0,size,size);



    GLuint texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);

    //Our image for the mipmap with odd level and green color
    //The dimensions are 256 x 256 and is multiplied by 3 because I defined R,G and B colors
    unsigned char imageArray[256*256*3];
    for(int i = 0; i < 256*256*3; i++){
        if((i+2)%3 == 0)
            imageArray[i] = 255;
        else
            imageArray[i] = 0;
    }

    //Our image for the mipmap with pair level and red color
    unsigned char imageArray2[256*256*3];
    for(int i = 0; i < 256*256*3; i++){
        if(i%3 == 0)
            imageArray2[i] = 255;
        else
            imageArray2[i] = 0;
    }

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 8);

    //All mipmap levels defined by hand
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, imageArray);
    glTexImage2D(GL_TEXTURE_2D, 1, GL_RGB, 128, 128, 0, GL_RGB, GL_UNSIGNED_BYTE, imageArray2);
    glTexImage2D(GL_TEXTURE_2D, 2, GL_RGB, 64,  64,  0, GL_RGB, GL_UNSIGNED_BYTE, imageArray);
    glTexImage2D(GL_TEXTURE_2D, 3, GL_RGB, 32,  32,  0, GL_RGB, GL_UNSIGNED_BYTE, imageArray2);
    glTexImage2D(GL_TEXTURE_2D, 4, GL_RGB, 16,  16,  0, GL_RGB, GL_UNSIGNED_BYTE, imageArray);
    glTexImage2D(GL_TEXTURE_2D, 5, GL_RGB, 8,   8,   0, GL_RGB, GL_UNSIGNED_BYTE, imageArray2);
    glTexImage2D(GL_TEXTURE_2D, 6, GL_RGB, 4,   4,   0, GL_RGB, GL_UNSIGNED_BYTE, imageArray);
    glTexImage2D(GL_TEXTURE_2D, 7, GL_RGB, 2,   2,   0, GL_RGB, GL_UNSIGNED_BYTE, imageArray2);
    glTexImage2D(GL_TEXTURE_2D, 8, GL_RGB, 1,   1,   0, GL_RGB, GL_UNSIGNED_BYTE, imageArray);

    GLfloat vertices[] = {
            -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 1.0f,  //vertex coordinates
            0.0f, 0.0f                              //Triangle's texture coordinates
    };



    //VAOs AND VBOs
    GLuint VAO, VBO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)0);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)(sizeof(GLfloat)*3*2));

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);



    //SHADERS
    GLuint program;
    GLuint vertex, fragment;

    vertex = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertex, 1, &VERTEX_SHADER_SOURCE, NULL);
    glCompileShader(vertex);

    fragment = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragment, 1, &FRAGMENT_SHADER_SOURCE, NULL);
    glCompileShader(fragment);

    program = glCreateProgram();
    glAttachShader(program, vertex);
    glAttachShader(program, fragment);
    glLinkProgram(program);

    glDeleteShader(vertex);
    glDeleteShader(fragment);
    glUseProgram(program);



    //DRAWING OUR TRIANGLE
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glDrawArrays(GL_TRIANGLES, 0,3);
    glfwSwapBuffers(window);
    while (!glfwWindowShouldClose(window))
        glfwPollEvents();



    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glfwTerminate();
    return 0;
}


1
It looks like there is only one set of texture coordinates instead of three.pleluron
@pleluron You are right, that was my error. Post it as answer, please.Adrian

1 Answers

3
votes

Your mipmap setup looks ok.But I see you have this:

  GLfloat vertices[] = {
        -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 1.0f,  //vertex coordinates
        0.0f, 0.0f                              //Triangle's texture coordinates
  };

It looks like you're missing UVs for 2 other vertices. Also,I wouldn't bother with manual mipmap generation,unless you want fully control the filtering technique etc.