PDA

View Full Version : selection/picking and gluOrtho2D



blip
12-09-2003, 07:20 AM
I'm trying to add gl selection and texture mapped fonts to my program by using the Nehe tutorials as a guide. So far selection works fine with my 3d models but I'm having a problem when adding the text. When selecting a model I get 2 hits, one for the model and one for the text, even though they are in different areas of the screen. When I select an area where there is no model or text I get a hit for the text. When selecting the text I get a hit for the text. So basically the text always gets selected. http://www.opengl.org/discussion_boards/ubb/smile.gif I understand the selection code and model code. I mostly understand the font code. I'm not sure if switching to Ortho2D while in selection mode screws everything up. I would like to keep the font stuff in screen/pixel coordinates because the spacing between characters in the display list uses that. Any ideas why this isn't working? Thanks!




menu_entry *pick_meny_entry(int mousex, int mousey, menu_entry *menu)
{
GLint viewport[4];
GLint hits;
menu_entry *tmp = NULL;
menu_entry *pickedmenu = NULL;
GLuint buffer[512];
unsigned int i, closest;
GLint depth;

glGetIntegerv(GL_VIEWPORT, viewport);
glSelectBuffer(512, buffer);
glRenderMode(GL_SELECT);
glInitNames();
glPushName(0);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPickMatrix((GLdouble)mousex, (GLdouble)(viewport[3] - mousey), 1.0,
1.0, viewport);
gluPerspective(45.0, (GLfloat)(viewport[2] - viewport[0]) /
(GLfloat)(viewport[3] - viewport[1]), 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);

drawMenuBoundingBoxes(menu);

glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
hits = glRenderMode(GL_RENDER);

if(hits > 0) {
printf("hits: %d\n", hits);
/* find the closes object */
closest = 0;
for(i = 1; i < (unsigned int)hits; i++) {
if(buffer[i*4 + 1] < buffer[closest*4 + 1]) {
closest = i;
}
}

/* assign the object name to closest */
closest = buffer[closest*4 + 3];

/* selection names are the ith menu */
i = 0;
tmp = menu->child_menu;
while(i < closest) {
if(tmp == NULL) {
printf("%s: Failed finding the selected menu\n"
,__FUNCTION__);
return NULL;
}
i++;
tmp = tmp->next;
}
pickedmenu = tmp;
}
return pickedmenu;
}

/* loop through this menu's entries and draw their bouding boxes */
void drawMenuBoundingBoxes(menu_entry *menu)
{
menu_entry *tmp = menu->child_menu;
float bbox[6];
unsigned int name = 0;

while(tmp != NULL) {
if(tmp->model != NULL) {
glLoadIdentity();
glTranslatef(tmp->pos_x, tmp->pos_y, tmp->pos_z);
glLoadName(name);
drawbbox(tmp->model->bbox);
} else {
glLoadIdentity();
glLoadName(name);
printfGLft(ftfont, tmp->pos_x, tmp->pos_y, tmp->name);
}
name++;
tmp = tmp->next;
}
}

static inline void pushScreenCoordinateMatrix(void)
{
GLint viewport[4];

glPushAttrib(GL_TRANSFORM_BIT);
glGetIntegerv(GL_VIEWPORT, viewport);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(viewport[0],viewport[2],viewport[1],viewport[3]);
glPopAttrib();
}

/* Pops the projection matrix without changing the current MatrixMode. */
static inline void pop_projection_matrix()
{
glPushAttrib(GL_TRANSFORM_BIT);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glPopAttrib();
}

void printfGLft(ftFont *ft_font, float x, float y, char *fmt, ...)
{
GLuint ftfont;
float h;
char text[256];
float modelview_matrix[16];
unsigned int i;
va_list ap;

/* coordinate system where things corespond to window pixels. */
pushScreenCoordinateMatrix();

ftfont = ft_font->list_base;

if (fmt == NULL)
*text = 0;
else {
va_start(ap, fmt);
vsprintf(text, fmt, ap);
va_end(ap);
}

glPushAttrib(GL_LIST_BIT | GL_CURRENT_BIT | GL_ENABLE_BIT |
GL_TRANSFORM_BIT);
glMatrixMode(GL_MODELVIEW);
glDisable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glListBase(ftfont);

glGetFloatv(GL_MODELVIEW_MATRIX, modelview_matrix);

glPushMatrix();
glLoadIdentity();
glTranslatef(x,y,-1.0);
glMultMatrixf(modelview_matrix);

// The commented out raster position stuff can be useful if you needto
// know the length of the text that you are creating.
// If you decide to use it make sure to also uncomment the glBitmap
// command
// in make_dlist().
//glRasterPos2f(0,0);
glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);
//float rpos[4];
//glGetFloatv(GL_CURRENT_RASTER_POSITION ,rpos);
//float len=x-rpos[0];

glPopMatrix();

glPopAttrib();
pop_projection_matrix();
}

blip
12-09-2003, 11:33 AM
nevermind. I figured it out. I needed to add a gluPickMatrix call before the gluOrtho2D in the printing function. I just created a second print function. One for printing and one for printing in select mode.