0
$\begingroup$

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..

$\endgroup$
  • $\begingroup$ 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). $\endgroup$ – bernie Dec 4 '18 at 9:54
  • $\begingroup$ 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. $\endgroup$ – Josh Aston Dec 4 '18 at 23:16
  • $\begingroup$ GLEW is still totally up to date. GLEW gives access to OpenGL functions. GLU is out of date. $\endgroup$ – bernie Dec 5 '18 at 9:02
0
$\begingroup$

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.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.