cancel
Showing results for 
Search instead for 
Did you mean: 

Archives Discussions

manny85
Journeyman III

glReadPixels does different work in ATI card.

I have implemented opengl picking using FBO and glReadPixels.

(I referred tutorial site : http://ogldev.atspace.co.uk/www/tutorial29/tutorial29.html)

It works fine in NVIDIA card(GTX580). But it works strangely in ATI card(HD 7970).

---------------------------------------------------------------------------------------------------------------------

[Problem 1]

It works strangely when internalFormat is 'GL_RGB32UI'. The code like below.

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, WindowWidth, WindowHeight, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, NULL);

This is a part of initialization of FBO texture of tutorial I mentioned.

It also works ATI when glReadPixels get only 1 pixel. The code like below.

glReadPixels(x, y, 1, 1, GL_RGB_INTEGER, GL_UNSIGNED_INT, &Pixel);

 

But I want to get any range of pixels. The code like below.

glReadPixels(x, y, w, h, GL_RGB_INTEGER, GL_UNSIGNED_INT, pPixel);

 

But It works strangely. Anyway I fixed this like below.

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32I, WindowWidth, WindowHeight, 0, GL_RGBA_INTEGER, GL_INT, NULL);

glReadPixels(x, y, w, h, GL_RGBA_INTEGER, GL_INT, pPixel);

Also fixed fragment shader : uvec3 -> ivec4

---------------------------------------------------------------------------------------------------------------------

Unfortunatly, it is not the end. there is serious problem I couldn't fix.

[Problem 2]

My application pick polygons of mesh. The problem occur when the mesh has a number of polygons(eg. over 3 million polygons). My Application picked rectangle range has a lot of holes and sometimes it doesn't pick nothing.

I guess glReadpixels doesn't work normally. Writing to FBO texture is no matter according to some tests I have done. The problem is not occur in NVIDIA GTX580.

Does anybody know why this problem happend and how to fix it? Any comment would be helpful for me.

0 Likes
10 Replies

What return a function glGetError() after calling glTexImage2D/glReadPixels ?

Whar return a function glCheckFramebufferStatus?

Try to simplify the code, without the complex mesh. Try to select pixels from one polygon.

First, thank you for your advice.

There is no gl error and glCheckFramebufferStatus is GL_FRAMEBUFFER_COMPLETE.

But, I was worng. It is not matter of reading pixels phase. It is matter of writing phase using FBO texture.

Sorry, I knew problem of glReadPixels but it isn't. Here is my FBO initialize code(same as tutorial I mentioned before).

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);

// color buffer(texture) init

glBindTexture(GL_TEXTURE_2D, m_pickingTexture);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32I, WindowWidth, WindowHeight, 0, GL_RGBA_INTEGER, GL_INT, NULL);

glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_pickingTexture, 0);

// depthbuffer init

glBindTexture(GL_TEXTURE_2D, m_depthTexture);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, WindowWidth, WindowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);

    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthTexture, 0);

And new bug I found. In shader code. 'uvec4' means four unsigned int, explaned opengl 4.2 reference.

So, max value can be 4,294,967,295. In ATI, however, 2,147,483,647 is max value and over 2,147,483,647 cause 'Invalid operation' gl error.

Anyway, I wonder why FBO texture writing work different between ATI and NVIDIA.

0 Likes

>cause 'Invalid operation' gl error.

When was this error? after a calling of glUseProgram/glUseProgramObject ? or after other calls ?

May be try to change a shader code:

#version 420

#extension GL_EXT_gpu_shader4 : enable

out uvec4 FragColor;

uniform uint gDrawIndex;

uniform uint gObjectIndex;

void main()

{

    FragColor = uvec4(float(gObjectIndex), float(gDrawIndex), float(gl_PrimitiveID + 1), 1);

}

May be need to convert a "unsigned int" type to a "float" type in an explicit form.

Try to check this shader in AMD GPU Shader Analizer.

In the present time i have not the ATI Card, but i  have the ATI 5670 at the home, i can check this shader later.

It was error in fragment shader.

when the code is below..

FragColor = uvec4(float(4194967295), float(gDrawIndex), float(gl_PrimitiveID + 1), 255);

error log is..

Fragment shader failed to compile with the following errors:

ERROR: 0:22: error(#88) Syntax error ERROR___INTEGER_CONST_OVERFLOW

ERROR: error(#273) 1 compilation errors.  No code generated

but '2,147,483,647' is ok. So uvec4 works in interger range.

0 Likes
manny85
Journeyman III

Here is result of gl_PrimitiveID generation between ATI and NVIDIA.

plane3m_ATI.PNG

     <ATI>

plane3m_NVIDIA.PNG

     <NVIDIA>

fragment shader is like that..

float fColor = gl_PrimitiveID / fMeshSize;

vFragColor = vec4(fColor, fColor, fColor, 1);

fMeshSize is the number of faces(3,189,760).

So, I could insist there is something different of generating gl_PrimitiveID between ATI and NVIDIA.

It represent only when face size is large. In a case of low face mesh it works fine.

Thus, I guess gl_PrimitiveID has a limit value in ATI.

I also found that there is same gl_PrimitiveID when render large mesh. I believe each face(primitive) has a unique gl_PrimitiveID.

0 Likes

Red box is result of pick&selection area.

glReadPixels(x, y, 100, 100, GL_RGBA_INTEGER, GL_UNSIGNED_INT, m_pPixelInfo);

0 Likes

Hi,

Is there any way you can make your example application available to us? We will attempt to debug the issue directly using your application.

Thanks,

Graham

0 Likes

Hi,

I attemped file 'pickingdemo.zip'.

I made this program based on Nehe Lesson 48, arcball.

- Right click is writiing to FBO texture.

- Left click is Read pixel range 100x100.

It is not perfect code. So you shoud test this without rotation.

But it could reproduct bug well, in a mesh of over 300million polygons.

I also corfirmed that NVIDIA works well in my demo program.

Thanks,

0 Likes

I have a question about gl_primitiveID.

How does GPU make gl_primitiveID?

I want the detail of the algorithm making gl_primitiveID in GPU.

Ultimately, I want to match GPU gl_primitiveID with CPU faceID that I managing in my application.

0 Likes

ATI 5670, Windows 7 32 bit (Driver 12.8):

pickdemo.jpg

0 Likes