Jump to content

  • Log In with Google      Sign In   
  • Create Account

Picking and selecting objects


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
2 replies to this topic

#1 jorgechp   Members   -  Reputation: 102

Like
0Likes
Like

Posted 05 February 2014 - 07:09 AM

Hi.

I'm learning how to make OpenGL to interact with the user through the mouse. I've followed this guide:

http://www.glprogramming.com/red/chapter13.html#name1

But I can't get my code to work. This is my pick() function:
 

void pick(int x, int y)

{

       GLuint selectBuf[BUFSIZE];

   GLint hits;

   GLint viewport[4];





   glGetIntegerv (GL_VIEWPORT, viewport);



   glSelectBuffer (BUFSIZE, selectBuf);

   (void) glRenderMode (GL_SELECT);



   glInitNames();

   glPushName(0);



   glMatrixMode (GL_PROJECTION);

   glPushMatrix ();

   glLoadIdentity ();

/*  create 5x5 pixel picking region near cursor location      */

   gluPickMatrix ((GLdouble) x, (GLdouble) (viewport[3] - y),

                  5.0, 5.0, viewport);

   gluOrtho2D (0.0, 1.0, 0.0, 1.0);



[B]   draw_malla(GL_SELECT);[/B]



   glMatrixMode (GL_PROJECTION);

   glPopMatrix ();

   glFlush ();



   hits = glRenderMode (GL_RENDER);

   cout << hits << endl;

  // processHits (hits, selectBuf);

   glutPostRedisplay();



}

Which calls to "draw_malla()"
 

draw_malla(GLenum mode){

   if (mode == GL_SELECT)

      glLoadName(1);

   glBegin(GL_QUADS);

   glColor3f(1.0, 1.0, 0.0);

   glVertex3f(0.2, 0, 0);

   glVertex3f(0.2, 0.6, 0);

   glVertex3f(0.6, 0.6, 0);

   glVertex3f(0.6, 0.0, 0);

   glEnd();

}

When I execute, a square is drawn on the windows but when I click on it, no hits are register.

This is my complete code:




#include "stdlib.h"

#include "stdio.h"

#include <GL/glut.h>

#include <ctype.h>

#include "user_code.h"

#include "file_ply_stl.h"

#include "vertex.h"

#include <iostream>



using namespace std;



// tamaño de los ejes

const int AXIS_SIZE=5000;



int modo = 0;

bool estadoRaton;

int xc,yc;



// variables que definen la posicion de la camara en coordenadas polares

GLfloat Observer_distance;

GLfloat Observer_angle_x;

GLfloat Observer_angle_y;



Draw *d;



// variables que controlan la ventana y la transformacion de perspectiva

GLfloat Window_width,Window_height,Front_plane,Back_plane;



// variables que determninan la posicion y tamaño de la ventana X

int UI_window_pos_x=50,UI_window_pos_y=50,UI_window_width=500,UI_window_height=500;

vector<Punto> vectorFinalE;

vector<Cara> vectorCarasE;









// Process hit buffer to find record with smallest min-z value.

void findClosestHit(int hits, unsigned int buffer[])

{

    int highlightFrames;

   unsigned int closestName;

   unsigned int *ptr, minZ;

   

   minZ= 0xffffffff; // 2^32 - 1

   ptr = buffer;

   closestName = 0;

   for (int i = 0; i < hits; i++)                    

   {

      ptr++;

      if (*ptr < minZ)

      {

         minZ = *ptr;

         ptr += 2;

         closestName = *ptr;

         ptr++;

      }

      else ptr += 3;

   }

   if (closestName != 0) highlightFrames = 10;

}





void draw_malla(GLenum mode){



    if(mode == GL_SELECT)

        glLoadName(1);

   glBegin(GL_QUADS);

   glColor3f(1.0, 1.0, 0.0);

   glVertex3f(0.2, 0, 0);

   glVertex3f(0.2, 0.6, 0);

   glVertex3f(0.6, 0.6, 0);

   glVertex3f(0.6, 0, 0);

   glEnd();

    



    





}



#define BUFSIZE 5120







void ratonMovido(int x, int y){

    int x0 = Observer_angle_x*0.2;

    int y0 = Observer_angle_y *0.2;

    if ( estadoRaton )

        {

            //getCamara( &x0, &y0 );

            int yn = y0+(y-yc) ;

            int xn = x0-(x-xc) ;



            //setCamara( xn, yn );

            Observer_angle_x = yn ; Observer_angle_y = xn ;

            glutPostRedisplay();

        }

}









void clear_window()

{



glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

}



void change_projection()

{



glMatrixMode(GL_PROJECTION);

glLoadIdentity();



// formato(x_minimo,x_maximo, y_minimo, y_maximo,Front_plane, plano_traser)

//  Front_plane>0  Back_plane>PlanoDelantero)

glFrustum(-Window_width,Window_width,-Window_height,Window_height,Front_plane,Back_plane);

}



void change_observer()

{



// posicion del observador

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

glTranslatef(0,0,-Observer_distance);

glRotatef(Observer_angle_x,1,0,0);

glRotatef(Observer_angle_y,0,1,0);

}



void draw_axis()

{

glBegin(GL_LINES);

// eje X, color rojo

glColor3f(1,0,0);

glVertex3f(-AXIS_SIZE,0,0);

glVertex3f(AXIS_SIZE,0,0);

// eje Y, color verde

glColor3f(0,1,0);

glVertex3f(0,-AXIS_SIZE,0);

glVertex3f(0,AXIS_SIZE,0);

// eje Z, color azul

glColor3f(0,0,1);

glVertex3f(0,0,-AXIS_SIZE);

glVertex3f(0,0,AXIS_SIZE);

glEnd();

}











void draw_objects()

{    

        draw_malla(GL_RENDER);

       



    

}







void draw_scene(void)

{



clear_window();

change_observer();

draw_axis();

draw_objects();

glutSwapBuffers();

}











void change_window_size(int Ancho1,int Alto1)

{

change_projection();

glViewport(0,0,Ancho1,Alto1);

glutPostRedisplay();

}









void normal_keys(unsigned char Tecla1,int x,int y)

{



    if (toupper(Tecla1)=='Q') exit(0);

    if (toupper(Tecla1)=='C'){    

        modo = 0;

    }

    if (toupper(Tecla1)=='S'){

        modo = 1;

    }

    if (toupper(Tecla1)=='A'){

        modo = 2;

    }

    glutPostRedisplay();

}







void special_keys(int Tecla1,int x,int y)

{



switch (Tecla1){

    case GLUT_KEY_LEFT:Observer_angle_y--;break;

    case GLUT_KEY_RIGHT:Observer_angle_y++;break;

    case GLUT_KEY_UP:Observer_angle_x--;break;

    case GLUT_KEY_DOWN:Observer_angle_x++;break;

    case GLUT_KEY_PAGE_UP:Observer_distance*=1.2;break;

    case GLUT_KEY_PAGE_DOWN:Observer_distance/=1.2;break;

    }



glutPostRedisplay();

}







void initialize(void)

{

// se inicalizan la ventana y los planos de corte

Window_width=.5;

Window_height=.5;

Front_plane=1;

Back_plane=1000;



// se inicia la posicion del observador, en el eje z

Observer_distance=3*Front_plane;

Observer_angle_x=0;

Observer_angle_y=0;



// se indica cual sera el color para limpiar la ventana    (r,v,a,al)

// blanco=(1,1,1,1) rojo=(1,0,0,1), ...

glClearColor(1,1,1,1);



// se habilita el z-bufer

glEnable(GL_DEPTH_TEST);

change_projection();

glViewport(0,0,UI_window_width,UI_window_height);

}



void pick(int x, int y)

{

       GLuint selectBuf[BUFSIZE];

   GLint hits;

   GLint viewport[4];





   glGetIntegerv (GL_VIEWPORT, viewport);



   glSelectBuffer (BUFSIZE, selectBuf);

   (void) glRenderMode (GL_SELECT);



   glInitNames();

   glPushName(0);



   glMatrixMode (GL_PROJECTION);

   glPushMatrix ();

   glLoadIdentity ();

/*  create 5x5 pixel picking region near cursor location      */

   gluPickMatrix ((GLdouble) x, (GLdouble) (viewport[3] - y),

                  5.0, 5.0, viewport);

   gluOrtho2D (0.0, 1.0, 0.0, 1.0);

   draw_malla(GL_SELECT);



   glMatrixMode (GL_PROJECTION);

   glPopMatrix ();

   glFlush ();



   hits = glRenderMode (GL_RENDER);

   cout << hits << endl;

  // processHits (hits, selectBuf);

   glutPostRedisplay();



}





void clickRaton(int button, int state, int x, int y){

    if ( button == GLUT_RIGHT_BUTTON )

        { if ( state == GLUT_DOWN )

            {

                estadoRaton = true ;

                xc = x ; yc = y ;

            }

        }

    else{

        estadoRaton = false ;

                if(button == GLUT_LEFT_BUTTON ){

                    if(state == GLUT_DOWN)                    

                    {

                        GLuint *i = new GLuint[80];

                        pick(x,y);

                    }

                }

    }



}





int main(int argc, char **argv)

{



    // se llama a la inicialización de glut

    glutInit(&argc, argv);



    // se indica las caracteristicas que se desean para la visualización con OpenGL

    // Las posibilidades son:

    // GLUT_SIMPLE -> memoria de imagen simple

    // GLUT_DOUBLE -> memoria de imagen doble

    // GLUT_INDEX -> memoria de imagen con color indizado

    // GLUT_RGB -> memoria de imagen con componentes rojo, verde y azul para cada pixel

    // GLUT_RGBA -> memoria de imagen con componentes rojo, verde, azul y alfa para cada pixel

    // GLUT_DEPTH -> memoria de profundidad o z-bufer

    // GLUT_STENCIL -> memoria de estarcido

    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);



    // posicion de la esquina inferior izquierdad de la ventana

    glutInitWindowPosition(UI_window_pos_x,UI_window_pos_y);



    // tamaño de la ventana (ancho y alto)

    glutInitWindowSize(UI_window_width,UI_window_height);



    // llamada para crear la ventana, indicando el titulo (no se visualiza hasta que se llama

    // al bucle de eventos)

    glutCreateWindow("Práctica 1");



    // asignación de la funcion llamada "dibujar" al evento de dibujo

    glutDisplayFunc(draw_scene);

    // asignación de la funcion llamada "cambiar_tamanio_ventana" al evento correspondiente

    glutReshapeFunc(change_window_size);

    // asignación de la funcion llamada "tecla_normal" al evento correspondiente

    glutKeyboardFunc(normal_keys);

    // asignación de la funcion llamada "tecla_Especial" al evento correspondiente

    glutSpecialFunc(special_keys);



    // funcion de inicialización

    initialize();

    glutMouseFunc( clickRaton );

    glutMotionFunc( ratonMovido );



    // inicio del bucle de eventos

    glutMainLoop();

    delete d;

    return 0;

}





I think that this is the part which is wrong
 

   glPushMatrix ();

   glLoadIdentity ();

/*  create 5x5 pixel picking region near cursor location      */

   gluPickMatrix ((GLdouble) x, (GLdouble) (viewport[3] - y),

                  5.0, 5.0, viewport);

   gluOrtho2D (0.0, 1.0, 0.0, 1.0);



[B]   draw_malla(GL_SELECT);[/B]



   glMatrixMode (GL_PROJECTION);

   glPopMatrix ();

But I don't have any idea about what's happening.

Thanks!

 



Sponsor:

#2 richardurich   Members   -  Reputation: 1187

Like
0Likes
Like

Posted 05 February 2014 - 10:49 AM

While I can't help with your code (I only ever learned modern OpenGL), I can offer different tutorials on picking. The first tutorial linked is the method I think makes the most sense (using collision objects). It should also have full source. If the idea appeals to you, you can even learn it from non-OpenGL tutorials since it's tied to your physics library instead of OpenGL. The other tutorials I linked might be more tightly tied to OpenGL.



#3 WiredCat   Members   -  Reputation: 316

Like
0Likes
Like

Posted 06 February 2014 - 04:42 PM

I draw every face with different color then i check what i just hit with a mouse ( with glReadPixels)






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS