PDA

View Full Version : unable to pick/select bitmap..



Kumar K
10-23-2007, 02:59 AM
I am unable to pick the bitmap rendered using glbitmap, is this because of glRasterPos3f...???

my code is something like this..
GLubyte rasters[24] = {
0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00,
0xff, 0x00, 0xff, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00,
0xff, 0xc0, 0xff, 0xc0};

glLoadName(BITMAP_IMAGE);
glColor3f (0.0, 1.0, 1.0);
glRasterPos3f (200, 200,200);
glBitmap (100, 120, 0.0, 0.0, 11.0, 0.0, rasters);
glFlush();

In the above case the hits are zero.
hits = glRenderMode (GL_RENDER);

I have No problems in picking other scene objects, Let me know how should i solve this.

Relic
10-23-2007, 05:16 AM
Directly from the OpenGL 2.1 specs:
"In selection mode, if a point, line, polygon, or the valid coordinates produced by a RasterPos command intersects the clip volume (section 2.12) then this primitive (or RasterPos command) causes a selection hit. WindowPos commands always generate a selection hit, since the resulting raster position is always valid."

Means, if your glRasterPos is not within the selection volume you get no hit.
Or you found a driver bug.

Kumar K
10-23-2007, 07:04 AM
Relic,
Thanks for your quick respose.


Means, if your glRasterPos is not within the selection volume you get no hit. This is not the case i have give glRasterPos3f as origin (0.0,0.0,0.0) which is the center of my viewing volume.


Or you found a driver bug. May be.... ,I have tried on different systems with different intel driver version, but no luck.

I have found that after making the rasterpos at orgin and place my mouse exactly at origin then i am able to hit and get the name correctly, but actually that is only the left botton point of the bitmap which was rendered using glBitmap, i want the selection to happen any where on the bitmap which is screen aligned and having some width and height.

I am not completely aware of what actually happens during these two calls..

glRasterPos3f();
glBitmap();

And importantly my pickmatrix is very small with 3 pixel surrouding the mouse x,y.
gluPickMatrix ((GLdouble) m_mouseLoc.x, (GLdouble) (viewport[3] - m_mouseLoc.y),
3.0, 3.0, viewport);

Relic
10-23-2007, 08:26 AM
have found that after making the rasterpos at orgin and place my mouse exactly at origin then i am able to hit and get the name correctly, Ok, in that case the rasterpos is within the frustum specified by your pick matrix and all is working as expected.


i want the selection to happen any where on the bitmap which is screen aligned and having some width and height.This is not what the selection does on a bitmap. To make that work with the OpenGL selection buffer you would need to render a real geometry instead of the bitmap matching the bitmap's screen area.
The problem you need to solve is to calculate the correct object coordinates which result in the original bitmap's corners.
gluProject and gluUnProject can help you there.

Kumar K
10-24-2007, 04:58 AM
Relic,
I have followed similar apporach and was able to generate the geometry in 3d and display it which is screen aligned bounding rec for bitmap region.
But during the selection process this is not selected,

I have added gluproject and gluUnProject code for gererating the geometry inside the renderer flow itself before rendering. Do you think these calls are ignored during GL_SELECT mode...?

Now also i can only select the botton left corner of geometry(polygon/rec where text is enclosed).

plasmonster
10-27-2007, 01:28 AM
Did you specify the pick matrix before applying your projection matrix?

Did you init stuff in the right order?


glSelectBuffer(...);
glRenderMode(GL_SELECT);
glInitNames();


You might work through one of the tutorials to see if you missed something simple along the way.

Kumar K
10-29-2007, 03:04 AM
guys problem is some thing like this which is still there :--

i am rendering a 3D rectangle object which is screen aligned text bounding rect, For rendering this i compute rect coods using gluproject.gluUnproject calls inside the render loop itself. Lets say
if i have global array like this "double boundBox[4][3];" and initialize them only during any mode expect selection mode then the values filled are correct, or else in selection mode I am getting in correct values. I cross checked the order of api calls and every thing seems okie.

Now my application works in this case :
while selection mode dont compute the boundbox rectangles again use already stored previous values.
<u>My render code looks like this.</u>
drawScene(void)
{
glRotatef(m_rAngle,0.0f,1.0f,0.2f);

glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glLoadIdentity();
GLubyte rasters[24] = {
0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00,
0xff, 0x00, 0xff, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00,
0xff, 0xc0, 0xff, 0xc0};

double dModelMatrix[16];
double dProjectionMatrix[16];
int iViewPort[4];
GLdouble dOutX, dOutY, dOutZ;


int ImageWidth,ImageHeight;
ImageWidth=ImageWidth=50;

glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
glGetDoublev(GL_MODELVIEW_MATRIX,&dModelMatrix[0]);
glGetDoublev(GL_PROJECTION_MATRIX,&dProjectionMatrix[0]);
glGetIntegerv(GL_VIEWPORT,&iViewPort[0]);

if(false == gluProject( 0.0,0.0,0.0,
dModelMatrix,dProjectionMatrix,iViewPort,
&dOutX,&dOutY,&dOutZ))
AfxMessageBox("Failed gluProject");


// now create the bitmap Rec geometry in 3D space.
//if(!initializedArrays)
if(1)
{

if(false == gluUnProject(dOutX+ImageWidth,dOutY,dOutZ,
dModelMatrix,dProjectionMatrix,iViewPort,
&rightBottom[0],&rightBottom[1],&rightBottom[2]))
AfxMessageBox("Failed gluUnProject");

if(false == gluUnProject(dOutX+ImageWidth,dOutY+ImageWidth,dOu tZ,
dModelMatrix,dProjectionMatrix,iViewPort,
&rightTop[0],&rightTop[1],&rightTop[2]))
AfxMessageBox("Failed gluUnProject");

if(false == gluUnProject(dOutX,dOutY+ImageWidth,dOutZ,
dModelMatrix,dProjectionMatrix,iViewPort,
&leftTop[0],&leftTop[1],&leftTop[2]))
AfxMessageBox("Failed gluUnProject");
}


glLoadName(DUMMY_OBJECT);
glColor4f(0.8f,0.1f,1.0f,0.5f); // Full Brightness, 50% Alpha ( NEW )
glBlendFunc(GL_SRC_ALPHA,GL_ONE); // Blending Function For Translucency Based On Source Alpha Value ( NEW )
glEnable(GL_BLEND);

glBegin(GL_POLYGON);
glVertex3d(0.0,0.0,0.0);
glVertex3d(rightBottom[0],rightBottom[1],rightBottom[2]);
glVertex3d(rightTop[0],rightTop[1],rightTop[2]);
glVertex3d(leftTop[0],leftTop[1],leftTop[2]);
glVertex3d(0.0,0.0,0.0);
glEnd();
glDisable(GL_BLEND);
glColor3f (0.0, 1.0, 1.0);
glRasterPos3f (0,0,0);
glBitmap (ImageWidth, ImageWidth, 0.0, 0.0, 0.0, 0.0, rasters);

glPopMatrix();
glFlush();
}

<u> Here my selection happens while mouse move itself..
This is where i initialize the other things</u>
OnMouseMove(UINT nFlags, CPoint point)
{
m_selEnabled= true;
initializedArrays = true;
renderSceneGraph();
initializedArrays = false;
m_selEnabled= false;
renderSceneGraph();
}

renderSceneGraph(void)
{
HGLRC hglrc = wglGetCurrentContext();
if(hglrc)
{
setVSync(0);
if(m_selEnabled)
{
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
gluLookAt(0,0,-5000,
0.0,0.0,0.0,
0,0,1);
}

int viewport[4];
if(m_selEnabled)
{
GLErrorCheck();
glGetIntegerv (GL_VIEWPORT, &viewport[0]);
GLErrorCheck();
glSelectBuffer (BUFSIZE, selectBuf);
(void) glRenderMode (GL_SELECT);
glInitNames();
glPushName(0);
}
glMatrixMode( GL_PROJECTION );
glPushMatrix ();
glLoadIdentity();
if(m_selEnabled)
{
gluPickMatrix ((GLdouble) m_mouseLoc.x, (GLdouble) (viewport[3] - m_mouseLoc.y),
3.0, 3.0, viewport);
}
glOrtho(-5000,5000,-5000, 5000, -5000, 5000);
glFlush();
// gl initialization required.
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Background
glClearDepth(1.0f); // Depth Buffer Setup
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glPolygonOffset(1.0,1.0);
glEnable(GL_POLYGON_OFFSET_FILL);
glFlush();
}

drawScene();
if(m_selEnabled)
{
GLint hits;
glMatrixMode (GL_PROJECTION);
glPopMatrix();
glFlush();
hits = glRenderMode (GL_RENDER);

}
}

Let me know where i have gone wrong in the above code.

Thank you,
kumar.k

Relic
10-30-2007, 10:16 AM
I didn't quite look through all the code, but the *three* cases you need to handle in the draw scene would be:

1.) When NOT in selection mode render the scene as usual.

2.) To generate the impostor rectangle (before switching to selection mode) just get the matrices and viewport at the time you would render your bitmap, no need to render anything in this step, only matrices and viewport are interesting.
Calculate your impostor rectangle coordinates.
Good that you calculated all four vertices, because bottom left (0,0,0) in your case and top right are not enough for rotated views. (Hold a piece of paper at opposing corners and rotate it and it gets clear. ;-))
This case 2 is a performance optimization because getting the matrices on each frame looks expensive.

3.) Switch to selection mode, setup your pickmatrix and in the draw scene render everthing as usual *except* for the bitmap which you replace with the quad impostor.

Kumar K
10-31-2007, 12:43 AM
Relic Thanks that you are back,

regarding your cases....

1.) When NOT in selection mode render the scene as usual.

i am doing the same see if(1) statement in red in my previous post.



To generate the impostor rectangle (before switching to selection mode) just get the matrices and viewport at the time you would render your bitmap, no need to render anything in this step, only matrices and viewport are interesting.
Calculate your impostor rectangle coordinates.
Good that you calculated all four vertices, because bottom left (0,0,0) in your case and top right are not enough for rotated views. (Hold a piece of paper at opposing corners and rotate it and it gets clear. ;-))
This case 2 is a performance optimization because getting the matrices on each frame looks expensive.

i am not worried about performance at this moment i want things to be working, however i would still like to know why my rect calculations are wrong in selection mode rendering.

See the log file for rect coordinates this is what happeing.

Enable selection = false ( general render mode)
LeftBottom 0,0,0
rightBottom 609.756113,0.000000,0.000000
rightTop 609.756113,1131.221748,0.000000
leftTop 0.000000,1131.221748,0.000000

On Mouse move() Func - START
Enable Selection = true
LeftBottom 0,0,0
rightBottom 2.230815,0.000000,0.000000
rightTop 2.230815,7.677976,0.000000
leftTop -0.000000,7.677976,0.000000

Enable Selection = false
LeftBottom 0,0,0
rightBottom 609.756113,0.000000,0.000000
rightTop 609.756113,1131.221748,0.000000
leftTop 0.000000,1131.221748,0.000000

On Mouse move() Func - END

Relic
10-31-2007, 07:17 AM
Of course. If you get the matrix *while* you have changed the matrices for picking and recalculate the quad coordinates with that, what do you expect? Don't do that.
You need the original object position for the imposter, because quads scale with the matrices, bitmaps don't they are screen space.
Rewrite the drawScene() routine to handle the three cases exactly as I said and your example should be fine.

Kumar K
10-31-2007, 07:52 AM
You need the original object position for the imposter, because quads scale with the matrices, bitmaps don't they are screen space.

clear ..... its expensive for me to maintain the bounding box for multiple text symbols in my scene graph structure boundBox[nTextSymbols][4][3];, thats why i thought to create them on fly( i know this itself is a stupid idea and performance killer).

okie now i know what I have to do. Sorry for the trouble and thanks for your solution.