00001
00006
00007
00008
00009
00010
00011 #include <iostream>
00012 #include <stdlib.h>
00013 #include <GL/glut.h>
00014
00015 using namespace std;
00016
00017 class Scene{
00018 public:
00019 GLfloat spinG_x, spinG_y;
00020 GLint selected;
00021 int mouse_x, mouse_y;
00022 int mode_selection;
00023 GLfloat x0,y0,z0,x1,y1,z1;
00024
00025 Scene(){
00026 spinG_x = spinG_y = 0;
00027 selected = -1;
00028 x0 = y0 = z0 = -2;
00029 x1 = y1 = z1 = 2;
00030 mode_selection = false;
00031 }
00032 void Init(){
00033
00034 glPointSize(10);
00035
00036 glLineWidth(2.0);
00037 }
00038 void setProjection(){
00039 glOrtho(-5, 5, -5, 5, -5, 5);
00040 }
00041 void Draw(GLenum mode);
00042
00043 ~Scene(){};
00044 };
00045
00046
00047
00048 void Scene::Draw(GLenum mode)
00049 {
00050 glPushMatrix();
00051 {
00052
00053 glRotatef(spinG_y, 1, 0, 0);
00054 glRotatef(spinG_x, 0, 1, 0);
00055
00056
00057 if (mode == GL_RENDER)
00058 {
00059
00060 glColor3f(1, 1, 1);
00061 glBegin(GL_LINES);
00062 glVertex3f(x0, y0, z0);
00063 glVertex3f(x1, y1, z1);
00064 glEnd();
00065
00066
00067 glBegin(GL_POINTS);
00068 if (selected == 1)
00069 glColor3f(1, 1, 0);
00070 else
00071 glColor3f(0, 0, .8);
00072 glVertex3f(x0, y0, z0);
00073
00074 if (selected == 2)
00075 glColor3f(1, 1, 0);
00076 else
00077 glColor3f(0, 0, .8);
00078 glVertex3f(x1, y1, z1);
00079 glEnd();
00080
00081 glColor3f(0, 0, .8);
00082 }
00083 else
00084 {
00085
00086
00087
00088 glLoadName(1);
00089 glBegin(GL_POINTS);
00090 glVertex3f(x0, y0, z0);
00091 glEnd();
00092
00093 glLoadName(2);
00094 glBegin(GL_POINTS);
00095 glVertex3f(x1, y1, z1);
00096 glEnd();
00097 }
00098 }
00099 glPopMatrix();
00100
00101 }
00102
00103
00104 Scene s;
00105
00106
00107
00108 void myReshapeFunc(int w,int h)
00109 {
00110 glViewport(0,0,(GLint) w,(GLint) h);
00111
00112 glMatrixMode( GL_PROJECTION );
00113 glLoadIdentity();
00114
00115 s.setProjection();
00116
00117 glMatrixMode( GL_MODELVIEW );
00118 }
00119
00120
00121
00122 void myDisplayFunc()
00123 {
00124
00125 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00126
00127
00128 s.Draw(GL_RENDER);
00129
00130
00131 glutSwapBuffers();
00132
00133 }
00134
00135
00136
00137 void processHits (GLint hits, GLuint buffer[])
00138 {
00139 GLuint i, nb_names, name, *ptr;
00140 GLdouble z1, z2;
00141
00142
00143 s.selected = -1;
00144
00145
00146
00147 printf ("hits = %d\n", hits);
00148 ptr = (GLuint *) buffer;
00149 for (i = 0; i < hits; i++) {
00150 nb_names = ptr[0];
00151 if (nb_names != 1) {
00152 cerr << "erreur, ce programme ne supporte qu'un seul nom dans la pile, et non pas " << nb_names << endl;
00153 exit(1);
00154 }
00155
00156 z1 = (double) ptr[1]/0x7fffffff;
00157 z2 = (double) ptr[2]/0x7fffffff;
00158 cout << "zmin = " << z1 << ", zmax= " << z2 << endl;
00159
00160 name = ptr[3];
00161 s.selected = name;
00162 cout << "selected = " << s.selected << endl;
00163 }
00164 }
00165
00166 #define BUFSIZE 512
00167
00168
00169 void myPick(int x, int y){
00170 GLuint selectBuf[BUFSIZE];
00171 GLint hits;
00172 GLint viewport[4];
00173
00174
00175 glGetIntegerv(GL_VIEWPORT, viewport);
00176
00177 glSelectBuffer(BUFSIZE, selectBuf);
00178 (void) glRenderMode(GL_SELECT);
00179
00180
00181 glInitNames();
00182 glPushName(0);
00183
00184 glMatrixMode(GL_PROJECTION);
00185 glPushMatrix();
00186 glLoadIdentity();
00187
00188 gluPickMatrix((GLdouble) x, (GLdouble) (viewport[3] - y),
00189 10.0, 10.0, viewport);
00190
00191 s.setProjection();
00192 glMatrixMode(GL_MODELVIEW);
00193
00194
00195 s.Draw(GL_SELECT);
00196
00197 glMatrixMode(GL_PROJECTION);
00198 glPopMatrix();
00199 glMatrixMode(GL_MODELVIEW);
00200
00201
00202 glFlush();
00203
00204 hits = glRenderMode(GL_RENDER);
00205
00206
00207 processHits (hits, selectBuf);
00208
00209 glutPostRedisplay();
00210 }
00211
00212 void myKeyboardFunc(unsigned char k,int x,int y)
00213 {
00214 switch(k)
00215 {
00216 case 27 : exit(0);break;
00217 default: break;
00218 }
00219
00220 glutPostRedisplay();
00221
00222 }
00223
00224
00225 void myMouseFunc(int button, int state, int x, int y)
00226 {
00227 if ((button == GLUT_RIGHT_BUTTON)
00228 && (state == GLUT_DOWN)){
00229
00230 s.mode_selection = true;
00231
00232 cout << "Picking" <<endl;
00233 myPick(x, y);
00234 }
00235
00236 if ((button == GLUT_LEFT_BUTTON)
00237 && (state == GLUT_DOWN)){
00238 s.mode_selection = false;
00239
00240 s.mouse_x = x;
00241 s.mouse_y = y;
00242
00243
00244 }
00245 glutPostRedisplay();
00246 }
00247
00248 void myMotionFunc(int x, int y){
00249 if (!s.mode_selection){
00250 s.spinG_x += (s.mouse_x - x);
00251 if (s.spinG_x > 360.0) s.spinG_x -= 360.0;
00252 if (s.spinG_x < -360.0) s.spinG_x += 360.0;
00253
00254 s.spinG_y += (s.mouse_y - y);
00255 if (s.spinG_y > 360.0) s.spinG_y -= 360.0;
00256 if (s.spinG_y < -360.0) s.spinG_y += 360.0;
00257
00258 s.mouse_x = x;
00259 s.mouse_y = y;
00260
00261
00262
00263 glutPostRedisplay();
00264 }
00265 }
00266
00267
00268 void init(int argc,char** argv)
00269 {
00270 glutInit(&argc,argv);
00271
00272 glutInitDisplayMode( GLUT_DOUBLE |GLUT_DEPTH );
00273
00274 glutInitWindowSize(500, 500);
00275
00276 glutInitWindowPosition(50,50);
00277
00278 glutCreateWindow("Selection et Picking");
00279
00280
00281 glutReshapeFunc(myReshapeFunc);
00282 glutDisplayFunc(myDisplayFunc);
00283 glutKeyboardFunc(myKeyboardFunc);
00284 glutMouseFunc(myMouseFunc);
00285 glutMotionFunc(myMotionFunc);
00286
00287
00288 glClearColor(.5, 0, 0, 1);
00289
00290
00291 glEnable(GL_DEPTH_TEST);
00292
00293
00294 s.Init();
00295
00296 }
00297
00298 int main(int argc,char **argv)
00299 {
00300 init(argc,argv);
00301 glutMainLoop();
00302 return 0;
00303
00304 }
00305