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
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
Hello JOE,
the problem remain with the values you give to me ,
REgards
david
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;
}
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
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
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)
Thank you very much for your help, i will select then standard ray picking ;))))