PDA

View Full Version : Cube picking



fortikur
07-23-2005, 06:00 AM
I want to pick a cube on the screen with the mouse under Borland CBuilder. There are 5*5 cubes on the screen in one row, but when I click on one of them, I get 25 as a "hit" number. But where is it coming from???
I post a simpified code here, I hope someone will know what I'm doing wrong...

[I]
void __fastcall TForm1::FormClick(TObject *Sender)
{
GLuint buffer[512];
GLint hits;
GLint viewport[4];

glSelectBuffer(512, buffer);
(void) glRenderMode(GL_SELECT);

glInitNames();
glPushName(-1);

glPushMatrix ();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//CAM SETTINGS
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 80, 1.3, 1,1000.0 );
gluLookAt(source_x, source_y, source_z,
dest_x, dest_y, dest_z,
0,1,0);
//CAM SETTINGS end here

cubes.draw_cubes();

glPopMatrix ();

hits=glRenderMode(GL_RENDER);

Edit1->Text=hits;
}

[\I]

I know, there are some 'efficiency errors' in the code, but first, i just want to see how picking works, cleaning comes after it.

Thanks for any help in advance

dvm
07-23-2005, 06:27 AM
Well, how are you drawing your cubes? Could you post the code for cubes.draw_cubes()?
I haven't had much time with picking, apart from the redbook example, but my guess is that all 25 of them have the same name?
Also, by taking a look at the definition I saw the name parameter is a GLuint. It's unsigned, so passing it -1 is certainly not -1 but something else.

fortikur
07-23-2005, 06:46 AM
Ok. Here is how I draw the cubes:


void ALLCUBES::draw_cubes(ENGINE en){
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glDisable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);

glTranslated(0-((en.cubenum+en.cubenum*CUBEGAP)/2),
0-((en.cubenum+en.cubenum*CUBEGAP)/2),
0);

for(int p=0;p<en.cubenum*en.cubenum;p++){
glLoadName(p);
cube[p].draw_cube(texture,en);
}
glEnable(GL_LIGHTING);
}One cube is drawn like this:


void CUBE::draw_cube(GLuint *texture,ENGINE en){
for(int p=0;p<6;p++)
quad[p].draw_quad(texture,p,en);
}And finally draw_quad just contains some texcoords and vertex3ds between a glBegin and a glEnd.

well, the call to the first function had a parameter. I just left it out in my previous post to make the code as simple as it can be.

dvm
07-23-2005, 01:24 PM
Well, I can't offer any more advice. I'm sorry :(
Last chance: check for error in every frame, maybe this shows something.

fortikur
07-24-2005, 08:23 AM
I found something. If I push the cubes out of the screen leaving only the 5 leftmost cubes visible, I get 5 for 'hits'. This means, that the things I've done were right, and the value of 'hits' is the total of the cubes drawn on the screen.
So, I tried gluPickMatrix. Nothing changed.

Can it be, that i used gluPickMatrix in a wrong way?


glSelectBuffer(512, buffer);
(void) glRenderMode(GL_SELECT);

glInitNames();
glPushName(0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

gluPickMatrix((GLdouble) Mouse->CursorPos.x,
(GLdouble) (viewport[3]-Mouse->CursorPos.y),
0.1f,0.1f, viewport);

glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
cam.use_cam();
cubes.draw_cubes(en);
SwapBuffers(DCvalue);

hits=glRenderMode(GL_RENDER);

07-24-2005, 08:31 AM
The pick matrix needs to be the applied to the projection matrix first, before gluPerspective/glOrtho.

http://www.lighthouse3d.com/opengl/picking/index.php?openglway2

fortikur
07-24-2005, 08:45 AM
Thanks Hlz. The tutorial told me the answer. My use_cam was actually loading the identity matrix before setting the perspective. It 'destroyed' the view.

Drakkhen
07-25-2005, 07:18 PM
The trick I use to pick objects is simply to get ZBuff value on mouse X,Y before drawing world, then in drawing routine code, after each object has been drawn, I just check if ZBuff changed and if so, I keep the pointer/ID of the last drawn instance and continue until the whole scene is drawn. The last pointer (or ID) I have is the mouse pointed objet one.

It works however complex the models are and uses only draw loop.