9.3.3编程实例-图形拾取
1 #include <GL/glut.h> 2 3 #include <stdlib.h> 4 5 #include<math.h> 6 7 #include <iostream> 8 9 using namespace std; 10 11 int SCREEN_WIDTH = 400; //屏幕尺寸 12 13 int SCREEN_HEIGHT = 400; 14 15 int posx1 = 150; 16 17 int posy1 = 200; 18 19 int posx2 = 250; 20 21 int posy2 = 200; 22 23 int select_point = 0; //1 是第一个点,2是第二个,以此类推 24 25 void init() 26 27 { glClearColor(1,1,1,1);} 28 29 void draw(GLenum mode) 30 31 { glPointSize(10.0f); 32 33 const static GLfloat color_selected[] = {1.0f,0.0f,0.0f}; 34 35 const static GLfloat color_unselected[] = {0.0f,0.0f,1.0f}; 36 37 for(int i=1;i<=5;i++)//5个点 38 39 { if (mode == GL_SELECT) glLoadName(i); 40 41 glColor3fv( (select_point == i)? color_selected : color_unselected ); 42 43 glBegin(GL_POINTS); 44 45 glVertex2f(i*70,200); 46 47 glEnd(); 48 49 } 50 51 } 52 53 void display() 54 55 { glClear(GL_COLOR_BUFFER_BIT); 56 57 draw(GL_RENDER); //设置渲染模式 58 59 glFlush(); 60 61 } 62 63 void reshape(int width, int height) 64 65 { glViewport(0, 0, width, height); 66 67 glMatrixMode(GL_PROJECTION); 68 69 glLoadIdentity(); 70 71 gluOrtho2D(0,SCREEN_WIDTH,0,SCREEN_HEIGHT); 72 73 glMatrixMode(GL_MODELVIEW); 74 75 } 76 77 void processHits(GLint hits, GLuint buffer[]) 78 79 { unsigned int i; 80 81 GLuint name; 82 83 for(i=0; i<hits;i++) 84 85 { name = buffer[3+i*4]; 86 87 select_point = name;//每个选中物体有占用名字栈中4个单位,第4个是物体名字值 88 89 cout<<"第"<<name<<"个点"<<endl; 90 91 } 92 93 } 94 95 #define SIZE 500 96 97 #define N 10 98 99 void mouse(int button, int state, int x, int y) 100 101 { GLuint selectBuffer[SIZE]; //存放物体名称的栈 102 103 GLint hits; //存放被选中对象个数 104 105 GLint viewport[4]; //存放可视区参数 106 107 if( state==GLUT_DOWN && button==GLUT_LEFT_BUTTON) //当鼠标左键按下时 108 109 {glGetIntegerv(GL_VIEWPORT,viewport); //获取当前视口坐标参数 110 111 glSelectBuffer(SIZE,selectBuffer); //选择名称栈存放被选中的名称 112 113 glRenderMode(GL_SELECT); //设置当前为选择模式 114 115 glInitNames(); //初始化名称栈 116 117 glPushName(0); 118 119 glMatrixMode(GL_PROJECTION); 120 121 glPushMatrix(); 122 123 glLoadIdentity(); 124 125 gluPickMatrix(x,viewport[3]-y,N,N,viewport); //创建用于选择的投影矩阵栈 126 127 gluOrtho2D(0,SCREEN_WIDTH,0,SCREEN_HEIGHT); //设置投影方式 128 129 draw(GL_SELECT); //绘制场景,选择模式 130 131 glPopMatrix(); 132 133 glFlush(); 134 135 hits = glRenderMode(GL_RENDER); 136 137 glMatrixMode(GL_MODELVIEW); 138 139 if(hits > 0) processHits(hits,selectBuffer); 140 141 glutPostRedisplay(); 142 143 } 144 145 if( state == GLUT_UP && button == GLUT_LEFT_BUTTON) //当鼠标左键抬起时 146 147 { select_point = 0; 148 149 glRenderMode(GL_RENDER); 150 151 draw(GL_RENDER); 152 153 glutPostRedisplay(); 154 155 } 156 157 } 158 159 int main(int argc, char *argv[]) 160 161 { glutInit(&argc, argv); 162 163 glutInitDisplayMode(GLUT_RGBA| GLUT_DEPTH ); 164 165 glutInitWindowSize(SCREEN_WIDTH,SCREEN_HEIGHT); 166 167 glutInitWindowPosition(0, 0); 168 169 glutCreateWindow("图形拾取编程实例"); 170 171 init(); 172 173 glutDisplayFunc(display); 174 175 glutReshapeFunc(reshape); 176 177 glutMouseFunc(mouse); 178 179 glutMainLoop(); 180 181 return 1; 182 183 }
附上本实验的VC++工程代码(VC++2008)