<p>You need to round down the mipmap sizes.
In your case the correct sequence is 200, 100, 50, 25, 12, 6, 3, 1.</p>

CC BY-SA 3.0
2017-07-08T18:26:23.773Z
2017-07-08T18:26:23.773Z
Azarien
<p>This question has an answer here:<br />
<a href="https://stackoverflow.com/questions/42596516/generating-mipmaps-manually">https://stackoverflow.com/questions/42596516/generating-mipmaps-manually</a><br />
It was a silly mistake. Sorry for the inconvenience.</p>

<p>OpenGL is fairly difficult to learn.<br />
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.</p>

<p>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?</p>

<p>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 :(</p>

<pre>
<code>#include &lt;iostream&gt;

#define GLEW_STATIC
#include &lt;GL/glew.h&gt;

#include &lt;GLFW/glfw3.h&gt;

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()
{
    //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(800, 600, "", nullptr, nullptr);
    glfwMakeContextCurrent(window);
    glewExperimental = GL_TRUE;
    glewInit();
    glViewport(0, 0, 800, 600);



    //THE MOST INTERESTING PART
    GLuint texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);

    //Our image for the mipmap with level 0 and white color
    //The dimensions are 200 x 200 and is multiplied by 3 because I defined R,G and B colors
    unsigned char imageArray[200*200*3];
    for(int i = 0; i &lt; 200*200*3; i++){
        imageArray[i] = 255;
    }

    //Our image for the mipmap with level 1-8 and blue color
    unsigned char imageArray2[100*100*3];
    for(int i = 0; i &lt; 100*100*3; i++){
        if((i+1)%3 == 0)
            imageArray2[i] = 255;
        else
            imageArray2[i] = 0;
    }

    //All mipmap levels
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 200, 200, 0, GL_RGB, GL_UNSIGNED_BYTE, imageArray);
    glTexImage2D(GL_TEXTURE_2D, 1, GL_RGB, 100, 100, 0, GL_RGB, GL_UNSIGNED_BYTE, imageArray2);
    glTexImage2D(GL_TEXTURE_2D, 2, GL_RGB, 50,  50,  0, GL_RGB, GL_UNSIGNED_BYTE, imageArray2);
    glTexImage2D(GL_TEXTURE_2D, 3, GL_RGB, 25,  25,  0, GL_RGB, GL_UNSIGNED_BYTE, imageArray2);
    glTexImage2D(GL_TEXTURE_2D, 4, GL_RGB, 13,  13,  0, GL_RGB, GL_UNSIGNED_BYTE, imageArray2);
    glTexImage2D(GL_TEXTURE_2D, 5, GL_RGB, 7,   7,   0, GL_RGB, GL_UNSIGNED_BYTE, imageArray2);
    glTexImage2D(GL_TEXTURE_2D, 6, GL_RGB, 4,   4,   0, GL_RGB, GL_UNSIGNED_BYTE, imageArray2);
    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, imageArray2);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    //If I comment the line above and uncomment the following, the program will show a black triangle. Why?
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);

    GLfloat vertices[] =
    //(un)comment the first and second lines of vertex coords to swap between a bigger or smaller triangle
    //It doesn't matter, this program always take the first mipmap level
    //But... Why? the triangle should be closer to any other mipmap level :( why does not take it?
    {
//          -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 1.0f,      //Bigger triangle
            -0.05f, -0.05f, 0.05f, -0.05f, 0.0f, 0.05f, //Smaller triangle
            -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 1.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;
}

</code>
</pre>

<p>For any reason, these two lines doesn't work together</p>

<pre><code>glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);
</code></pre>

<p><strong><h1>EDIT:</h1></strong> I think that the two lines above doesn't work because mipmaps only works with GL_TEXTURE_MIN_FILTER. However, when I replace</p>

<pre><code>glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//If I comment the line above and uncomment the following, the program will show a black triangle. Why?
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);
</code></pre>

<p>with</p>

<pre><code>glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
</code></pre>

<p>it shows a black triangle :(</p>

<p>I used glGetError as Dan Hulme stated in the comments but with the last change I made to my code I have not errors returned by glGetError but still showing a black triangle.</p>

<p><strong><h1>EDIT 2:</h1></strong> I solved the problem setting the sizes by powers of 2. However, it now takes only the first mipmap level. Here is the new source code:</p>

<pre>
<code>#include &lt;iostream&gt;

#define GLEW_STATIC
#include &lt;GL/glew.h&gt;

#include &lt;GLFW/glfw3.h&gt;

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 &lt; 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 &lt; 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;
}

</code>
</pre>

CC BY-SA 3.0
2017-03-03T10:35:24.940Z
Unrelated, but your `imageArray2` loop would be faster as `for (int i = 0; i < 100 * 100 * 3; i += 3) { imageArray2[i] = 0; imageArray2[i + 1] = 0; imageArray[i + 2] = 255; }` because it avoids a division inside the loop. I think it's clearer this way too.
Dan Hulme
CC BY-SA 3.0
2017-03-03T10:37:35.947Z
Obviously mipmaps are turned off in the program as-is: the thing you're debugging is why you get a black screen when you uncomment the line that turns them on. First rule of GL debugging is to use [`glGetError`](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glGetError.xhtml) everywhere and see if any of the gl* function calls are failing.
Dan Hulme
CC BY-SA 3.0
2017-03-03T23:36:23.977Z
@Dan Hulme How can I turn on mipmaps? The tutorial I'm following doesn't make mention of how to turn on/off mipmaps.
Adrian
CC BY-SA 3.0
2017-03-04T09:47:34.247Z
Setting the `GL_TEXTURE_MIN_FILTER` to `GL_NEAREST` means the mipmaps won't be used, which is why you only see level 0 when you do this.
Dan Hulme
<opengl><c++>
How can I generate mipmaps manually?
Adrian
# How can I generate mipmaps manually?

(Asked by: username_0 on 2017-03-02)

This question has an answer here:  
<https://stackoverflow.com/questions/42596516/generating-mipmaps-manually>  
It was a silly mistake. Sorry for the inconvenience.

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()
{
    //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(800, 600, "", nullptr, nullptr);
    glfwMakeContextCurrent(window);
    glewExperimental = GL_TRUE;
    glewInit();
    glViewport(0, 0, 800, 600);

    //THE MOST INTERESTING PART
    GLuint texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);

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

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

    //All mipmap levels
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 200, 200, 0, GL_RGB, GL_UNSIGNED_BYTE, imageArray);
    glTexImage2D(GL_TEXTURE_2D, 1, GL_RGB, 100, 100, 0, GL_RGB, GL_UNSIGNED_BYTE, imageArray2);
    glTexImage2D(GL_TEXTURE_2D, 2, GL_RGB, 50,  50,  0, GL_RGB, GL_UNSIGNED_BYTE, imageArray2);
    glTexImage2D(GL_TEXTURE_2D, 3, GL_RGB, 25,  25,  0, GL_RGB, GL_UNSIGNED_BYTE, imageArray2);
    glTexImage2D(GL_TEXTURE_2D, 4, GL_RGB, 13,  13,  0, GL_RGB, GL_UNSIGNED_BYTE, imageArray2);
    glTexImage2D(GL_TEXTURE_2D, 5, GL_RGB, 7,   7,   0, GL_RGB, GL_UNSIGNED_BYTE, imageArray2);
    glTexImage2D(GL_TEXTURE_2D, 6, GL_RGB, 4,   4,   0, GL_RGB, GL_UNSIGNED_BYTE, imageArray2);
    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, imageArray2);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    //If I comment the line above and uncomment the following, the program will show a black triangle. Why?
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);

    GLfloat vertices[] =
    //(un)comment the first and second lines of vertex coords to swap between a bigger or smaller triangle
    //It doesn't matter, this program always take the first mipmap level
    //But... Why? the triangle should be closer to any other mipmap level :( why does not take it?
    {
//          -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 1.0f,      //Bigger triangle
            -0.05f, -0.05f, 0.05f, -0.05f, 0.0f, 0.05f, //Smaller triangle
            -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 1.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;
}

```

For any reason, these two lines doesn't work together

```
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);

```

**# EDIT:** I think that the two lines above doesn't work because mipmaps only works with GL\_TEXTURE\_MIN\_FILTER. However, when I replace

```
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//If I comment the line above and uncomment the following, the program will show a black triangle. Why?
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);

```

with

```
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

```

it shows a black triangle :(

I used glGetError as Dan username_1 stated in the comments but with the last change I made to my code I have not errors returned by glGetError but still showing a black triangle.

**# EDIT 2:** I solved the problem setting the sizes by powers of 2. However, it now takes only the first mipmap level. Here is the new source code:

```

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

```

**Tags:** opengl, c++

> **Comments:**
> **username_1**: Unrelated, but your `imageArray2` loop would be faster as `for (int i = 0; i < 100 * 100 * 3; i += 3) { imageArray2[i] = 0; imageArray2[i + 1] = 0; imageArray[i + 2] = 255; }` because it avoids a division inside the loop. I think it's clearer this way too.  
> **username_1**: Obviously mipmaps are turned off in the program as-is: the thing you're debugging is why you get a black screen when you uncomment the line that turns them on. First rule of GL debugging is to use [`glGetError`](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glGetError.xhtml) everywhere and see if any of the gl* function calls are failing.  
> **username_0**: @username_1 How can I turn on mipmaps? The tutorial I'm following doesn't make mention of how to turn on/off mipmaps.  
> **username_1**: Setting the `GL_TEXTURE_MIN_FILTER` to `GL_NEAREST` means the mipmaps won't be used, which is why you only see level 0 when you do this.  

---

## 1 answers

### Answer by username_2 on 2017-07-08. Score: 3

You need to round down the mipmap sizes.
In your case the correct sequence is 200, 100, 50, 25, 12, 6, 3, 1.


---

