glReadPixels

This topic contains 8 replies, has 2 voices, and was last updated by  dgu 5 years, 6 months ago.

Viewing 9 posts - 1 through 9 (of 9 total)
  • Author
    Posts
  • #30793

    dgu
    Member

    Hello

    i was trying to get picking object up to work by using glReadPixels

    GLbyte color[4];

                   GLfloat depth;

                   GLuint index;

                   GLint x = m_position[0]*640;

                   GLint y = m_position[1]*480;

                   glReadPixels(x, screen_height-y , 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,

                             color);

                   glReadPixels(x, screen_height-y , 1, 1, GL_DEPTH_COMPONENT,

                             GL_FLOAT, &depth);

                   glReadPixels(x, screen_height- y , 1, 1, GL_STENCIL_INDEX,

                             GL_UNSIGNED_INT, &index);

    the depth AND INDEX value are always equal to 0

    before to request glReadPixels

    during the init

            glEnable(GL_BLEND);

         glEnable(GL_DEPTH_TEST);

         glEnable(GL_STENCIL_TEST);

         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

         // Request Stencil Buffer support

         PVRShellSet(prefStencilBufferContext, true);

    during the rendering :

         glClearStencil(0);

         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

         glEnable(GL_STENCIL_TEST);

    …….

    glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);

    just before the draw

    glStencilFunc(GL_ALWAYS, i, -1);

    …..

    may you tell me why my stencil index is not properly working like the one i did using glu inspired by

    http://en.wikibooks.org/wiki/OpenGL_Programming/Object_selection

    Kind regards

    david

    #35623

    Joe Davis
    Member

    Hi David,

    I think that you may be seeing this problem because your glReadPixels() call for your color buffer is invalid. If you change the type from GL_UNSIGNED_BYTE to GL_UNSIGNED_SHORT_4_4_4_4, or GL_UNSIGNED_SHORT_5_5_5_1, it should resolve the problem.

    Thanks,
    Joe

    #35624

    dgu
    Member

    Hello JOE,

    the problem remain with the values you give to me ,

    REgards

    david

    #35625

    dgu
    Member

    I mean the pixel value is correct that is good but stencil value is not updated to the correct value

    #35626

    dgu
    Member
    dgu wrote:
    I mean the pixel value is correct that is good but stencil value is not updated to the correct value

    then render secrion is :

    bool Selection::RenderScene() {

         glClearColor(1.0, 1.0, 1.0, 1.0);

         glClearStencil(0);

         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

         glEnable(GL_STENCIL_TEST);

         glUseProgram(program);

         glUniform1i(uniform_mytexture, /*GL_TEXTURE*/0);

         glEnableVertexAttribArray(attribute_coord3d);

         // Describe our vertices array to OpenGL (it can’t guess its format automatically)

         glBindBuffer(GL_ARRAY_BUFFER, vbo_cube_vertices);

         glVertexAttribPointer(attribute_coord3d, // attribute

                   3, // number of elements per vertex, here (x,y,z)

                   GL_FLOAT, // the type of each element

                   GL_FALSE, // take our values as-is

                   0, // no extra data between each position

                   0 // offset of first element

                   );

         glEnableVertexAttribArray(attribute_texcoord);

         glBindBuffer(GL_ARRAY_BUFFER, vbo_cube_texcoords);

         glVertexAttribPointer(attribute_texcoord, // attribute

                   2, // number of elements per vertex, here (x,y)

                   GL_FLOAT, // the type of each element

                   GL_FALSE, // take our values as-is

                   0, // no extra data between each position

                   0 // offset of first element

                   );

         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_cube_elements);

         int size;

         glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);

         glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);

         glm::mat4 view = glm::lookAt(camera_position, glm::vec3(0.0, 0.0, 0.0),

                   glm::vec3(0.0, 1.0, 0.0));

         glm::mat4 projection = glm::perspective(45.0f,

                   1.0f * screen_width / screen_height, 0.1f, 10.0f);

         GLfloat color_normal[4] = { 1, 1, 1, 1 };

         GLfloat color_highlight[4] = { 2, 2, 2, 1 };

         for (int i = 0; i < NCUBES; i++) {

              glm::mat4 model = glm::scale(

                        glm::translate(glm::mat4(1.0f), positions),

                        glm::vec3(0.2, 0.2, 0.2));

              glm::mat4 anim = glm::rotate(glm::mat4(1.0f), angle * rotspeeds.x,

                        glm::vec3(1, 0, 0)) * // X axis

                        glm::rotate(glm::mat4(1.0f), angle * rotspeeds.y,

                                  glm::vec3(0, 1, 0)) * // Y axis

                        glm::rotate(glm::mat4(1.0f), angle * rotspeeds.z,

                                  glm::vec3(0, 0, 1)); // Z axis

              glm::mat4 mvp = projection * view * model * anim;

              glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, glm::value_ptr(mvp));

              if (highlight)

                   glUniform4fv(uniform_color, 1, color_highlight);

              else

                   glUniform4fv(uniform_color, 1, color_normal);

              glStencilFunc(GL_ALWAYS, i + 1, -1);

              /* Push each element in buffer_vertices to the vertex shader */

              glDrawElements(GL_TRIANGLES, size / sizeof(GLushort), GL_UNSIGNED_SHORT,

                        0);

         }

         float* m_position = (float*) this->PVRShellGet(prefPointerLocation);

         if (m_position) {

              /* Read color, depth and stencil index from the framebuffer */

              GLbyte color[4];

              GLfloat depth;

              GLuint index;

              GLint x = m_position[0] *640;

              GLint y = m_position[1] *480;

         //      printf(” click on x,y %i %i %fn”, x,y,depth);

               glReadPixels(x, screen_height-y , 1, 1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1,

               color);

               glReadPixels(x, screen_height-y , 1, 1, GL_DEPTH_COMPONENT,

               GL_FLOAT, &depth);

               glReadPixels(x, screen_height- y , 1, 1, GL_STENCIL_INDEX,

                         GL_UNSIGNED_SHORT_5_5_5_1, &index);

               printf(

               “Clicked on pixel %d, %d, color %02hhx %02hhx %02hhx %02hhx, depth %f, stencil index %un”,

               x, y, color[0], color[1], color[2], color[3], depth, index);

              /* Convert from window coordinates to object coordinates */

              glm::mat4 view = glm::lookAt(camera_position, glm::vec3(0.0, 0.0, 0.0),

                        glm::vec3(0.0, 1.0, 0.0));

              glm::mat4 projection = glm::perspective(45.0f,

                        1.0f * screen_width / screen_height, 0.1f, 10.0f);

              glm::vec4 viewport = glm::vec4(0, 0, screen_width, screen_height);

              glm::vec3 wincoord = glm::vec3(x, screen_height – y – 1, -1);

              glm::vec3 objcoord = glm::unProject(wincoord, view, projection,

                        viewport);

              /* Which box is nearest to those object coordinates? */

              int closest_i = 0;

         }

         glDisableVertexAttribArray(attribute_coord3d);

         glDisableVertexAttribArray(attribute_texcoord);

         return true;

    }

    #35627

    Joe Davis
    Member

    Hi David,

    The glReadPixels calls you are making for depth and stencil values are not valid. The formats supported by OpenGL ES 2.0 are GL_ALPHA, GL_RGB and GL_RGBA.
    You can find out more from the OpenGL ES 2.0 reference pages here and/or by reading the OpenGL ES 2.0 spec here

    #35628

    dgu
    Member

    Helo JOE,

    Thanks , i see :

    type

    Specifies the data type of the pixel data. Must be one of GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_4_4_4_4, or GL_UNSIGNED_SHORT_5_5_5_1.

    so it is set now but i still cannot get the depth and stencil value , how concretly will you do that ?

    thanks

    dave

    #35629

    Joe Davis
    Member

    It’s not possible to retrieve the depth and stencil buffers with glReadPixels() in OpenGL ES 2.0.

    As a work around for retrieving depth values, you could bind a depth texture to an FBO render pass, blit the depth texture to a colour buffer of the same resolution (e.g. a second FBO) and then use glReadPixels() to retrieve the colour buffer that contains your depth values.

    There are workarounds to retrieve stencil buffer values, but they are non-trivial (it would involve multiple render passes and stencil mask tricks, among other complexities)

    #35630

    dgu
    Member

    Thank you very much for your help, i will select then standard ray picking ;))))

Viewing 9 posts - 1 through 9 (of 9 total)
You must be logged in to reply to this topic.