Ignore background color when using glReadPixels?
#1 Members - Reputation: 106
Posted 15 April 2012 - 03:01 PM
To make it short.
Im using opengl color picking.
Im drawing my 3D objects using unique colors and picking them using glreadpixels.
My app also can have custom background color. Atm it has conflicts with object colors.
When user clicks on background color which is black for example: glClearColor(0,0,0, 1.0) then code "thinks" that user clicked on object at the same coordinate (X0,Y0,Z0). But actually he clicked on background. Which has same color with object.
So my question is: is it possible to make OpenGL to ignore background color?
I mean color what is used for glClearColor()?
Will the glDepthMask(true/false) help me on this one?
#2 Marketplace Seller - Reputation: 8925
Posted 15 April 2012 - 03:12 PM
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal
#3 Members - Reputation: 106
Posted 15 April 2012 - 03:21 PM
So i could set bgcolor to 255, 255, 8, but it's white, it will kill eyes. And it's very limited this way.
Of course not all of my objects are drawn at once, but it's just the way my picking works.
I already killed almost 3 months on finding good and fast picking for my app and only that worked was glColor3ub and glReadPixels. I don't want to kill this again. Im tired of messing and searching with/for picking code.
Is it really impossible to ignore bgcolor? I tried once glDepthMask for specific thing, and it ignored what i didn't need to detect.
But im not sure, if it will work on color.
#5 Marketplace Seller - Reputation: 8925
Posted 15 April 2012 - 03:32 PM
What does it matter what color the background is, on the invisible second screen?
You draw each object:
- Draw with textures, lighting, anti-aliasing, whatever...
And if it's pick-able, you draw it on a secondary screen as well:
- Draw as a solid color matching it's object ID.
When you pick the color, you pick it from the secondary screen. Otherwise, your program wont be able to use lighting (which would mess up the pixel colors with shadows), or textures (which are all sorts of different colors), or shader effects, or transparency, or anything else.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal
#6 Members - Reputation: 106
Posted 15 April 2012 - 03:33 PM
Could you post some pseudo code.
Will this slow things down?
Servant of the Lord
Yes, im using "background" buffer for colored objects, im not flipping it.
User doesn't see it.
But why is my code picking the background color then?
I specified background color with glClearColor(0.0f, 155.0/255.0, 102.0/255.0, 1.0f); for example and my picking code also picks it up.
My bug somewhere?
Should i use 2 different glClearColor()'s each time? For first and second buffer?
#7 Marketplace Seller - Reputation: 8925
Posted 15 April 2012 - 03:37 PM
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal
#8 Members - Reputation: 3688
Posted 15 April 2012 - 03:42 PM
You're probably following this tutorial, right? Have you downloaded the sourcecode?
Ah yeah, that one doesn't use a separate framebuffer for picking though, it just uses the normal backbuffer but doesn't swap it after rendering the colorcoded models. (That method might even be better unless the scene is mostly static)
pseudo code then would be:
renderloop:
cleartobackgroundcolor
draw everything normally
swapbuffers
end of renderloop
and then in the logic part of the code:
if mouseisclicked
disable lighting, textures, complex shaders, etc
render colorcoded models
call glReadPixels to get the selected color
do NOT swap the buffers
reenable everything you disabled.
The voices in my head may not be real, but they have some good ideas!
#9 Marketplace Seller - Reputation: 8925
Posted 15 April 2012 - 03:48 PM
Because you're saying:But why is my code picking the background color then?
1) Fill the entire screen with the color 'clearColor'.
2) Why is the point on the screen 'clearColor'!
The 'background color' just means, "Fill the entire screen at the beginning of each frame".
Just pretend it draws two really large triangles over the screen.
The background isn't 'nothing' that looks like the clearcolor, it's actually that color.
It doesn't bother wasting space by remembering what's the background and what's not. It just keeps the colors.
The entire screen is just a single image that you're drawing onto. All it knows is the color of any pixel... it doesn't know when that pixel was put there, or if it's a background pixel, a robot pixel, or a fireball pixel. It's just a pixel.
I mean, if you ask "What color is at this point?", it tells you the color. It's not going to lie and say, "Oh, uh, no color is here". The user (if the buffer gets flipped) would see a color. So why shouldn't it return the color that it actually is?
Try it and see if it works for you - that might be one solution.Should i use 2 different glClearColor()'s each time? For first and second buffer?
Oh, and note that you might not need to check the color under the mouse every frame. If your program is running really fast, you might only want to check the color 5 - 10 times a second, not every frame. But it should be pretty fast as it is.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal
#10 Members - Reputation: 106
Posted 15 April 2012 - 03:56 PM
Yes structure is same:
My snippet in rendering loop:
DrawStuff(mode);
if (mode == SELECT) {
ProcessPick();
mode = RENDER;
} else SwapBuffers(ghDC);So it's a bad way if i want to allow custom background colors?
And i should use really 2 buffers?
I used two glClearColors, once in place where i disabled some gl stuff (texturing etc) with white color.
And second in place where i enabled gl stuff (texturing etc) with my fav. bgcolor.
And result was like very ugly flickering of white and my fav. bg color.
Picking worked, but there was that very ugly flickering.
Exactly when i clicked, the flickering occurred.
#11 Marketplace Seller - Reputation: 8925
Posted 15 April 2012 - 04:12 PM
It should work fine the way you are doing it, but the ugly flickering shouldn't be there. Somewhere between the first draw and the second draw, the first draw is showing up on-screen.
It should go something like:
MyDrawFunction()
{
if(...time-to-pick...)
{
DrawPickingBackground();
DrawPickingColors();
ProcessPick();
}
DrawNormalBackground();
DrawNormal();
FlipBuffers(); //Only flipped after a normal draw.
}
I see you have a functon called SwapBuffer(), but are you sure your code is double buffered? Have you tested it to make sure it doesn't just look like it's working?
If you're using the Win32 SwapBuffers() function (which I'm not personally familiar with), did you actually enable double buffering?
The function documentation says:
"Specifies a device context. *If* the current pixel format for the window referenced by this device context includes a back buffer, the function exchanges the front and back buffers."
...
"If the current pixel format for the window referenced by the device context does not include a back buffer, this call has no effect and the content of the back buffer is undefined when the function returns."
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal
#12 Members - Reputation: 106
Posted 15 April 2012 - 04:26 PM
Something is really wrong in my code. Well it works but anyway, i also think that it shouldn't flicker.
I will take a look what's up with my pixelformat.
EDIT: yes, pixelfmt has the PFD_DOUBLEBUFFER included.
Dunno what is wrong with it. I will make some small test app. Something is very wrong there.
I will use your last pseudo code.
#13 Members - Reputation: 106
Posted 15 April 2012 - 05:27 PM
Z can only holds values from 0 to 7. So if i do simple logic like:
if(R<=255 & G<=255 & B >7) {
// Ignore All Three Color Values Read
// Because They Are Background Color Values.
}So basically do not allow user to choose color, which B (blue) is less than or equal to 7.
I think it will work and still it is possible to use a lot more colors than some very limited amount of colors for background.
But somebody's other thoughts on this will also help me.






