<p>I figured it out. All I had to do was add <code>glUseProgram(0)</code> at the very end of the draw cylinder function. After more than 3 weeks of looking into this.</p>

CC BY-SA 4.0
2018-12-06T17:09:57.663Z
2018-12-06T17:09:57.663Z
Josh Aston
<p>If I try to read the screen with <code>glreadpixels</code> and then draw the same thing again using <code>gldrawpixels</code> it works, BUT if and only if I use anything else to draw than <code>gldrawarrays</code> and <code>gldrawelements</code> (<code>gluSphere/gluCylinder</code> work just fine). I'm trying to draw an object to the screen and save the pixels in an array. </p>

<p>I tried reading/writing to front/back buffers, reading after I swap buffers, all to no avail.</p>

<p>here is the code that I use to draw the object: (please note that I do not use any kind of buffers outside of this scope).</p>

<pre><code> void CCssample5View::DrawCylinder(Model obj)
    {
    GLuint VertexArrayID;
    glGenVertexArrays(1, &amp;VertexArrayID);
    glBindVertexArray(VertexArrayID);

    Shader castingShader("casting.vs", "casting.fs");
    Shader lightShader("light.vs", "light.fs");

    GLuint MatrixID = glGetUniformLocation(castingShader.ID, "MVP");
    GLuint ViewMatrixID = glGetUniformLocation(castingShader.ID, "V");
    GLuint ModelMatrixID = glGetUniformLocation(castingShader.ID, "M");

    GLuint textur = loadBMP_custom("flower.bmp");
    GLuint TextureID = glGetUniformLocation(castingShader.ID , "myTextureSampler");


    indexVBO(obj.vertices, obj.uvs, obj.normals, obj.indices, obj.indexed_vertices, obj.indexed_uvs, obj.indexed_normals);

    GLuint vertexbuffer;
    glGenBuffers(1, &amp;vertexbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glBufferData(GL_ARRAY_BUFFER, obj.indexed_vertices.size() * sizeof(glm::vec3), &amp;obj.indexed_vertices[0], GL_STATIC_DRAW);

    GLuint uvbuffer;
    glGenBuffers(1, &amp;uvbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
    glBufferData(GL_ARRAY_BUFFER, obj.indexed_uvs.size() * sizeof(glm::vec2), &amp;obj.indexed_uvs[0], GL_STATIC_DRAW);

    GLuint normalbuffer;
    glGenBuffers(1, &amp;normalbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
    glBufferData(GL_ARRAY_BUFFER, obj.indexed_normals.size() * sizeof(glm::vec3), &amp;obj.indexed_normals[0], GL_STATIC_DRAW);

    GLuint elementbuffer;
    glGenBuffers(1, &amp;elementbuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, obj.indices.size() * sizeof(unsigned short), &amp;obj.indices[0], GL_STATIC_DRAW);



    castingShader.use();

    GLuint LightID = glGetUniformLocation(castingShader.ID, "LightPosition_worldspace");
    computeMatricesFromInputs();
    GLfloat gProjectionMatrix[16];
    glGetFloatv(GL_PROJECTION_MATRIX, gProjectionMatrix);
    glm::mat4 ProjectionMatrix = glm::make_mat4(gProjectionMatrix);// = glm::mat4(gProjectionMatrix);   

    GLfloat gViewMatrix[16];
    glGetFloatv(GL_MODELVIEW_MATRIX, gViewMatrix);
    glm::mat4 ViewMatrix = glm::make_mat4(gViewMatrix);// = glm::mat4(gProjectionMatrix);

    glm::vec3 lightPos = glm::vec3(4, 4, 4);
    glUniform3f(LightID, lightPos.x, lightPos.y, lightPos.z);
    glUniformMatrix4fv(ViewMatrixID, 1, GL_FALSE, &amp;ViewMatrix[0][0]);

    glm::mat4 ModelMatrix1 = glm::mat4(1.0);
    glm::mat4 MVP1 = ProjectionMatrix * ViewMatrix * ModelMatrix1;


    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, textur);

    glUniform1i(TextureID, 0);
    // Send our transformation to the currently bound shader, 
    // in the "MVP" uniform
    glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &amp;MVP1[0][0]);
    glUniformMatrix4fv(ModelMatrixID, 1, GL_FALSE, &amp;ModelMatrix1[0][0]);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glVertexAttribPointer(
        0,                  // attribute
        3,                  // size
        GL_FLOAT,           // type
        GL_FALSE,           // normalized?
        0,                  // stride
        (void*)0            // array buffer offset
    );

    // 2nd attribute buffer : UVs
    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
    glVertexAttribPointer(
        1,                                // attribute
        2,                                // size
        GL_FLOAT,                         // type
        GL_FALSE,                         // normalized?
        0,                                // stride
        (void*)0                          // array buffer offset
    );

    // 3rd attribute buffer : normals
    glEnableVertexAttribArray(2);
    glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
    glVertexAttribPointer(
        2,                                // attribute
        3,                                // size
        GL_FLOAT,                         // type
        GL_FALSE,                         // normalized?
        0,                                // stride
        (void*)0                          // array buffer offset
    );

    // Index buffer
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);

    // Draw the triangles !
    glDrawElements(
        GL_TRIANGLES,      // mode
        obj.indices.size(),    // count
        GL_UNSIGNED_SHORT,   // type
        (void*)0           // element array buffer offset
    );

    //glFlush(); glFinish(); readScreen(screen, GL_RGB, true);

    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(2);

    glDeleteBuffers(1, &amp;vertexbuffer);
    glDeleteBuffers(1, &amp;uvbuffer);
    glDeleteBuffers(1, &amp;normalbuffer);
    glDeleteBuffers(1, &amp;elementbuffer);
    glDeleteProgram(castingShader.ID);
    glDeleteTextures(1, &amp;textur);
    glDeleteVertexArrays(1, &amp;VertexArrayID);
}
</code></pre>

<p>These are my read and draw screen functions:</p>

<pre><code>void CCssample5View::readScreen(GLubyte* screen, GLenum format, bool back)
{
    check();


    if (format == GL_RGB) {


        check();
        if (back) {
            glReadBuffer(GL_BACK);
            check();
        }
        else {
            glReadBuffer(GL_FRONT);
            check();
        }

    }
    //glRasterPos2i(00, 00);
    //glDisable(GL_DEPTH_TEST);
    glPixelStorei(GL_PACK_ALIGNMENT, 1);
    glReadPixels(0, 0, w, h, format, GL_UNSIGNED_BYTE, screen);


    glFlush();
    glFinish();
    bool found = false;
    for (size_t u = 0; u &lt;= w * h * 4; u++) {
        if (screen[u] != 0) {
            found = true;
            break;
        }
    }
    assert(found);
    check();


}
void CCssample5View::drawScreen(GLubyte *screen, GLenum format, bool back)
{


    glClear(GL_COLOR_BUFFER_BIT);
    //glGetIntegerv(GL_CURRENT_RASTER_POSITION, rasterpos);
    if (back) {
        glDrawBuffer(GL_BACK);
    }
    else {
        glDrawBuffer(GL_FRONT);
    }    

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glDrawPixels(w, h, format, GL_UNSIGNED_BYTE, screen);
    check();

    glFlush();
    glFinish();
}
</code></pre>

<p>Can not seem to figure out whats wrong when the drawing is perfect except the reading screen part..</p>

CC BY-SA 4.0
2018-12-04T09:54:49.380Z
This is quite a big chunk a code to debug. You will rarely find someone that will take on this kind of task here unless it's smaller snippets. That said, there should not be any link between `glReadPixels` and what you draw. To me, this hints at a possible problem with buffer bindings because that is what `glDrawArrays` uses and not the `glu` draw functions. By the way, if you're starting a new project, you should find a more modern replacement to glu if you can (like GLFW).
bernie
CC BY-SA 4.0
2018-12-04T23:16:19.303Z
Yeah I thought it was a lot and I honestly did not want to post any code at all as I wanted conceptual answers. It's for a course that I'm taking anyway (that's why I'm using GLEW so I just wanted to know what's wrong and learn how to fix it.
I will look more into the buffer bindings. I tried using a framebuffer object but still figuring it out.
Josh Aston
CC BY-SA 4.0
2018-12-05T09:02:32.507Z
GLEW is still totally up to date. GLEW gives access to OpenGL functions. *GLU* is out of date.
bernie
<opengl>
Why is glreadpixels only working in certain cases?
Josh Aston
# Why is glreadpixels only working in certain cases?

(Asked by: username_0 on 2018-12-03)

If I try to read the screen with `glreadpixels` and then draw the same thing again using `gldrawpixels` it works, BUT if and only if I use anything else to draw than `gldrawarrays` and `gldrawelements` (`gluSphere/gluCylinder` work just fine). I'm trying to draw an object to the screen and save the pixels in an array.

I tried reading/writing to front/back buffers, reading after I swap buffers, all to no avail.

here is the code that I use to draw the object: (please note that I do not use any kind of buffers outside of this scope).

```
 void CCssample5View::DrawCylinder(Model obj)
    {
    GLuint VertexArrayID;
    glGenVertexArrays(1, &VertexArrayID);
    glBindVertexArray(VertexArrayID);

    Shader castingShader("casting.vs", "casting.fs");
    Shader lightShader("light.vs", "light.fs");

    GLuint MatrixID = glGetUniformLocation(castingShader.ID, "MVP");
    GLuint ViewMatrixID = glGetUniformLocation(castingShader.ID, "V");
    GLuint ModelMatrixID = glGetUniformLocation(castingShader.ID, "M");

    GLuint textur = loadBMP_custom("flower.bmp");
    GLuint TextureID = glGetUniformLocation(castingShader.ID , "myTextureSampler");

    indexVBO(obj.vertices, obj.uvs, obj.normals, obj.indices, obj.indexed_vertices, obj.indexed_uvs, obj.indexed_normals);

    GLuint vertexbuffer;
    glGenBuffers(1, &vertexbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glBufferData(GL_ARRAY_BUFFER, obj.indexed_vertices.size() * sizeof(glm::vec3), &obj.indexed_vertices[0], GL_STATIC_DRAW);

    GLuint uvbuffer;
    glGenBuffers(1, &uvbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
    glBufferData(GL_ARRAY_BUFFER, obj.indexed_uvs.size() * sizeof(glm::vec2), &obj.indexed_uvs[0], GL_STATIC_DRAW);

    GLuint normalbuffer;
    glGenBuffers(1, &normalbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
    glBufferData(GL_ARRAY_BUFFER, obj.indexed_normals.size() * sizeof(glm::vec3), &obj.indexed_normals[0], GL_STATIC_DRAW);

    GLuint elementbuffer;
    glGenBuffers(1, &elementbuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, obj.indices.size() * sizeof(unsigned short), &obj.indices[0], GL_STATIC_DRAW);

    castingShader.use();

    GLuint LightID = glGetUniformLocation(castingShader.ID, "LightPosition_worldspace");
    computeMatricesFromInputs();
    GLfloat gProjectionMatrix[16];
    glGetFloatv(GL_PROJECTION_MATRIX, gProjectionMatrix);
    glm::mat4 ProjectionMatrix = glm::make_mat4(gProjectionMatrix);// = glm::mat4(gProjectionMatrix);   

    GLfloat gViewMatrix[16];
    glGetFloatv(GL_MODELVIEW_MATRIX, gViewMatrix);
    glm::mat4 ViewMatrix = glm::make_mat4(gViewMatrix);// = glm::mat4(gProjectionMatrix);

    glm::vec3 lightPos = glm::vec3(4, 4, 4);
    glUniform3f(LightID, lightPos.x, lightPos.y, lightPos.z);
    glUniformMatrix4fv(ViewMatrixID, 1, GL_FALSE, &ViewMatrix[0][0]);

    glm::mat4 ModelMatrix1 = glm::mat4(1.0);
    glm::mat4 MVP1 = ProjectionMatrix * ViewMatrix * ModelMatrix1;

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, textur);

    glUniform1i(TextureID, 0);
    // Send our transformation to the currently bound shader, 
    // in the "MVP" uniform
    glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP1[0][0]);
    glUniformMatrix4fv(ModelMatrixID, 1, GL_FALSE, &ModelMatrix1[0][0]);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glVertexAttribPointer(
        0,                  // attribute
        3,                  // size
        GL_FLOAT,           // type
        GL_FALSE,           // normalized?
        0,                  // stride
        (void*)0            // array buffer offset
    );

    // 2nd attribute buffer : UVs
    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
    glVertexAttribPointer(
        1,                                // attribute
        2,                                // size
        GL_FLOAT,                         // type
        GL_FALSE,                         // normalized?
        0,                                // stride
        (void*)0                          // array buffer offset
    );

    // 3rd attribute buffer : normals
    glEnableVertexAttribArray(2);
    glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
    glVertexAttribPointer(
        2,                                // attribute
        3,                                // size
        GL_FLOAT,                         // type
        GL_FALSE,                         // normalized?
        0,                                // stride
        (void*)0                          // array buffer offset
    );

    // Index buffer
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);

    // Draw the triangles !
    glDrawElements(
        GL_TRIANGLES,      // mode
        obj.indices.size(),    // count
        GL_UNSIGNED_SHORT,   // type
        (void*)0           // element array buffer offset
    );

    //glFlush(); glFinish(); readScreen(screen, GL_RGB, true);

    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(2);

    glDeleteBuffers(1, &vertexbuffer);
    glDeleteBuffers(1, &uvbuffer);
    glDeleteBuffers(1, &normalbuffer);
    glDeleteBuffers(1, &elementbuffer);
    glDeleteProgram(castingShader.ID);
    glDeleteTextures(1, &textur);
    glDeleteVertexArrays(1, &VertexArrayID);
}

```

These are my read and draw screen functions:

```
void CCssample5View::readScreen(GLubyte* screen, GLenum format, bool back)
{
    check();

    if (format == GL_RGB) {

        check();
        if (back) {
            glReadBuffer(GL_BACK);
            check();
        }
        else {
            glReadBuffer(GL_FRONT);
            check();
        }

    }
    //glRasterPos2i(00, 00);
    //glDisable(GL_DEPTH_TEST);
    glPixelStorei(GL_PACK_ALIGNMENT, 1);
    glReadPixels(0, 0, w, h, format, GL_UNSIGNED_BYTE, screen);

    glFlush();
    glFinish();
    bool found = false;
    for (size_t u = 0; u <= w * h * 4; u++) {
        if (screen[u] != 0) {
            found = true;
            break;
        }
    }
    assert(found);
    check();

}
void CCssample5View::drawScreen(GLubyte *screen, GLenum format, bool back)
{

    glClear(GL_COLOR_BUFFER_BIT);
    //glGetIntegerv(GL_CURRENT_RASTER_POSITION, rasterpos);
    if (back) {
        glDrawBuffer(GL_BACK);
    }
    else {
        glDrawBuffer(GL_FRONT);
    }    

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glDrawPixels(w, h, format, GL_UNSIGNED_BYTE, screen);
    check();

    glFlush();
    glFinish();
}

```

Can not seem to figure out whats wrong when the drawing is perfect except the reading screen part..

**Tags:** opengl

> **Comments:**
> **username_1**: This is quite a big chunk a code to debug. You will rarely find someone that will take on this kind of task here unless it's smaller snippets. That said, there should not be any link between `glReadPixels` and what you draw. To me, this hints at a possible problem with buffer bindings because that is what `glDrawArrays` uses and not the `glu` draw functions. By the way, if you're starting a new project, you should find a more modern replacement to glu if you can (like GLFW).  
> **username_0**: Yeah I thought it was a lot and I honestly did not want to post any code at all as I wanted conceptual answers. It's for a course that I'm taking anyway (that's why I'm using GLEW so I just wanted to know what's wrong and learn how to fix it. I will look more into the buffer bindings. I tried using a framebuffer object but still figuring it out.  
> **username_1**: GLEW is still totally up to date. GLEW gives access to OpenGL functions. *GLU* is out of date.  

---

## 1 answers

### Answer by username_0 on 2018-12-06. Score: 0 | Accepted answer

I figured it out. All I had to do was add `glUseProgram(0)` at the very end of the draw cylinder function. After more than 3 weeks of looking into this.


---

