opengl 放大镜
Exercise 6:放大镜功能
要求:
- 在练习5的基础上,实现放大镜功能,放大场景中的任意部分;
- 放大镜可以通过鼠标键盘进行控制;
考察目的:
- 对OpenGL坐标系变换的理解;
我的思路就是,获取屏幕坐标,转换成opengl 坐标。移动glulookat到相应的位置,然后拉近摄像头距离,实现放大
不过,不能是正交投影,正交投影下,照相机远近不能影响大小。
特别坑爹,感觉肯定有其他方法实现。
屏幕坐标的转换,参考http://nehe.gamedev.net/article/using_gluunproject/16013/
pos就是转换后的结果
1 void GLPOS(int x,int y,GLdouble pos[3]) 2 { 3 GLint viewport[4]; 4 GLdouble modelview[16]; 5 GLdouble projection[16]; 6 GLfloat winX,winY,winZ; 7 8 glGetDoublev(GL_MODELVIEW_MATRIX,modelview); 9 glGetDoublev(GL_PROJECTION_MATRIX,projection); 10 glGetIntegerv(GL_VIEWPORT,viewport); 11 12 winX = (float)x; 13 winY = viewport[3]-(float)y; 14 glReadPixels((int)x,(int)y,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,&winZ); 15 gluUnProject(winX,winY,winZ,modelview,projection,viewport,&pos[0],&pos[1],&pos[2]); 16 }
本来是想画一个 小的十字 去跟踪鼠标。
结果,透视投影下面,用上面坐标转换的方法,跟踪鼠标,因为是视景体是梯形,所以效果不好
正交投影下,十字可以跟着鼠标走,但是又没办法放大了。
全部代码如下:
1 #include <windows.h> 2 #include <GL/glut.h> 3 #include <GL/glext.h> 4 #include <GL/SOIL.h> 5 #include <cstdio> 6 7 /* 正方体旋转*/ 8 GLfloat xrot1 = 0.0f; 9 GLfloat yrot1 = 0.0f; 10 GLfloat xrot2 = 0.0f; 11 GLfloat yrot2 = 0.0f; 12 GLfloat xrot3 = 0.0f; 13 GLfloat yrot3 = 0.0f; 14 GLfloat xrot4 = 0.0f; 15 GLfloat yrot4 = 0.0f; 16 /*旋转速度*/ 17 GLfloat xspeed = 5.0f; 18 GLfloat yspeed = 5.0f; 19 /*放大相关*/ 20 GLdouble eyex = 0.0f; 21 GLdouble eyey = 0.0f; 22 GLdouble centerx = 0.0f; 23 GLdouble centery = 0.0f; 24 25 GLdouble eyez = 15.0f;//放大镜值 26 /*焦点*/ 27 GLfloat focusx = 0.0f; 28 GLfloat focusy = 0.0f; 29 GLfloat focusz = 15.0f; 30 31 GLuint texture[1]; 32 33 int loadGLTextures() 34 { 35 for(int i=0; i<3; i++) 36 { 37 texture[i] = SOIL_load_OGL_texture 38 ( 39 "F://LI//opengl-test//practice_big//Crate.bmp", 40 SOIL_LOAD_AUTO, 41 SOIL_CREATE_NEW_ID, 42 SOIL_FLAG_INVERT_Y 43 ); 44 } 45 46 if(texture[0] == 0) 47 { 48 printf("load error"); 49 return 0; 50 } 51 glBindTexture(GL_TEXTURE_2D, texture[0]); 52 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 53 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 54 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); 55 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); 56 57 return true; 58 } 59 60 void init () 61 { 62 loadGLTextures(); 63 glEnable(GL_TEXTURE_2D); 64 glShadeModel(GL_SMOOTH); 65 glClearColor(0.0,0.0,0.0,0.0); 66 glClearDepth(1.0); 67 glEnable(GL_DEPTH_TEST); 68 glDepthFunc(GL_LEQUAL); 69 glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); 70 } 71 void reshape(int w,int h) 72 { 73 glViewport(0,0,(GLsizei)w,(GLsizei)h); 74 glMatrixMode(GL_PROJECTION); 75 glLoadIdentity(); 76 gluPerspective(45.0,(GLfloat)w/(GLfloat)h,0.1,100.0); 77 // glOrtho(-10.0f,10.0f,-10.0f*(GLfloat)h/(GLfloat)w,10.0f*(GLfloat)h/(GLfloat)w,0.1,100.0); 78 glMatrixMode(GL_MODELVIEW); 79 } 80 void drawQuads(GLfloat xrot,GLfloat yrot) 81 { 82 glTranslatef(0.0f,0.0f,0.0f); 83 glRotatef(xrot1,1.0f,0.0f,0.0f); 84 glRotatef(yrot1,0.0f,1.0f,0.0f); 85 glBindTexture(GL_TEXTURE_2D,texture[0]); 86 glBegin(GL_QUADS); 87 // 前侧面 88 glNormal3f( 0.0f, 0.0f, 1.0f); // 法线指向观察者 89 glTexCoord2f(0.0f, 0.0f);glVertex3f(-1.0f, -1.0f, 1.0f); 90 glTexCoord2f(1.0f, 0.0f);glVertex3f( 1.0f, -1.0f, 1.0f); 91 glTexCoord2f(1.0f, 1.0f);glVertex3f( 1.0f, 1.0f, 1.0f); 92 glTexCoord2f(0.0f, 1.0f);glVertex3f(-1.0f, 1.0f, 1.0f); 93 // 后侧面 94 glNormal3f( 0.0f, 0.0f,-1.0f); // 法线背向观察者 95 glTexCoord2f(1.0f, 0.0f); 96 glVertex3f(-1.0f, -1.0f, -1.0f); 97 glTexCoord2f(1.0f, 1.0f); 98 glVertex3f(-1.0f, 1.0f, -1.0f); 99 glTexCoord2f(0.0f, 1.0f); 100 glVertex3f( 1.0f, 1.0f, -1.0f); 101 glTexCoord2f(0.0f, 0.0f); 102 glVertex3f( 1.0f, -1.0f, -1.0f); 103 // 顶面 104 glNormal3f( 0.0f, 1.0f, 0.0f); // 法线向上 105 glTexCoord2f(0.0f, 1.0f); 106 glVertex3f(-1.0f, 1.0f, -1.0f); 107 glTexCoord2f(0.0f, 0.0f); 108 glVertex3f(-1.0f, 1.0f, 1.0f); 109 glTexCoord2f(1.0f, 0.0f); 110 glVertex3f( 1.0f, 1.0f, 1.0f); 111 glTexCoord2f(1.0f, 1.0f); 112 glVertex3f( 1.0f, 1.0f, -1.0f); 113 // 底面 114 glNormal3f( 0.0f,-1.0f, 0.0f); // 法线朝下 115 glTexCoord2f(1.0f, 1.0f); 116 glVertex3f(-1.0f, -1.0f, -1.0f); 117 glTexCoord2f(0.0f, 1.0f); 118 glVertex3f( 1.0f, -1.0f, -1.0f); 119 glTexCoord2f(0.0f, 0.0f); 120 glVertex3f( 1.0f, -1.0f, 1.0f); 121 glTexCoord2f(1.0f, 0.0f); 122 glVertex3f(-1.0f, -1.0f, 1.0f); 123 // 右侧面 124 glNormal3f( 1.0f, 0.0f, 0.0f); // 法线朝右 125 glTexCoord2f(1.0f, 0.0f); 126 glVertex3f( 1.0f, -1.0f, -1.0f); 127 glTexCoord2f(1.0f, 1.0f); 128 glVertex3f( 1.0f, 1.0f, -1.0f); 129 glTexCoord2f(0.0f, 1.0f); 130 glVertex3f( 1.0f, 1.0f, 1.0f); 131 glTexCoord2f(0.0f, 0.0f); 132 glVertex3f( 1.0f, -1.0f, 1.0f); 133 // 左侧面 134 glNormal3f(-1.0f, 0.0f, 0.0f); // 法线朝左 135 glTexCoord2f(0.0f, 0.0f); 136 glVertex3f(-1.0f, -1.0f, -1.0f); 137 glTexCoord2f(1.0f, 0.0f); 138 glVertex3f(-1.0f, -1.0f, 1.0f); 139 glTexCoord2f(1.0f, 1.0f); 140 glVertex3f(-1.0f, 1.0f, 1.0f); 141 glTexCoord2f(0.0f, 1.0f); 142 glVertex3f(-1.0f, 1.0f, -1.0f); 143 glEnd(); 144 145 } 146 147 void drawFocus() 148 { 149 GLfloat a = 1.0f; 150 glColor3f(1.0f,1.0f,1.0f); 151 glLineWidth(1.0f); 152 glBegin(GL_LINES); 153 glVertex3f(-1.0f/a,1.0f/a,0.0f); 154 glVertex3f(-1.0f/a,3.0f/a,0.0f); 155 glEnd(); 156 glBegin(GL_LINES); 157 glVertex3f(-1.0f/a,1.0f/a,0.0f); 158 glVertex3f(-3.0f/a,1.0f/a,0.0f); 159 glEnd(); 160 glBegin(GL_LINES); 161 glVertex3f(1.0f/a,1.0f/a,0.0f); 162 glVertex3f(1.0f/a,3.0f/a,0.0f); 163 glEnd(); 164 glBegin(GL_LINES); 165 glVertex3f(1.0f/a,1.0f/a,0.0f); 166 glVertex3f(3.0f/a,1.0f/a,0.0f); 167 glEnd(); 168 glBegin(GL_LINES); 169 glVertex3f(-1.0f/a,-1.0f/a,0.0f); 170 glVertex3f(-1.0f/a,-3.0f/a,0.0f); 171 glEnd(); 172 glBegin(GL_LINES); 173 glVertex3f(-1.0f/a,-1.0f/a,0.0f); 174 glVertex3f(-3.0f/a,-1.0f/a,0.0f); 175 glEnd(); 176 177 glBegin(GL_LINES); 178 glVertex3f(1.0f/a,-1.0f/a,0.0f); 179 glVertex3f(1.0f/a,-3.0f/a,0.0f); 180 glEnd(); 181 glBegin(GL_LINES); 182 glVertex3f(1.0f/a,-1.0f/a,0.0f); 183 glVertex3f(3.0f/a,-1.0f/a,0.0f); 184 glEnd(); 185 } 186 187 void display() 188 { 189 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 190 glLoadIdentity(); 191 192 /*glPushMatrix(); 193 glDisable(GL_TEXTURE_2D); 194 glTranslatef(focusx,focusy,focusz); 195 drawFocus(); 196 glEnable(GL_TEXTURE_2D); 197 glPopMatrix();*/ 198 199 gluLookAt(eyex,eyey,eyez,centerx,centery,-1.0f,0.0f,1.0f,0.0f); 200 201 /*glPushMatrix(); 202 glPointSize(5.0f); 203 glBegin(GL_POINTS); 204 glVertex3f(9.0f,0.0f,0.0f); 205 glEnd(); 206 glPopMatrix();*/ 207 208 glPushMatrix(); 209 glTranslatef(-3.5f,2.5f,0.0f); 210 drawQuads(xrot1,yrot1); 211 glPopMatrix(); 212 213 glPushMatrix(); 214 glTranslatef(3.5f,2.5f,0.0f); 215 drawQuads(xrot2,yrot2); 216 glPopMatrix(); 217 218 glPushMatrix(); 219 glTranslatef(-3.5f,-2.5f,0.0f); 220 drawQuads(xrot3,yrot3); 221 glPopMatrix(); 222 223 glPushMatrix(); 224 glTranslatef(3.5f,-2.5f,0.0f); 225 drawQuads(xrot4,yrot4); 226 glPopMatrix(); 227 228 glFlush(); 229 230 } 231 232 void GLPOS(int x,int y,GLdouble pos[3]) 233 { 234 GLint viewport[4]; 235 GLdouble modelview[16]; 236 GLdouble projection[16]; 237 GLfloat winX,winY,winZ; 238 239 glGetDoublev(GL_MODELVIEW_MATRIX,modelview); 240 glGetDoublev(GL_PROJECTION_MATRIX,projection); 241 glGetIntegerv(GL_VIEWPORT,viewport); 242 243 winX = (float)x; 244 winY = viewport[3]-(float)y; 245 glReadPixels((int)x,(int)y,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,&winZ); 246 gluUnProject(winX,winY,winZ,modelview,projection,viewport,&pos[0],&pos[1],&pos[2]); 247 } 248 void mouse(int button,int state,int x,int y) 249 { 250 251 switch(button) 252 { 253 case GLUT_LEFT_BUTTON: 254 if(state == GLUT_DOWN) 255 { 256 printf("%d,%d\n",x,y); 257 GLdouble *pos = new GLdouble[3]; 258 GLPOS(x,y,pos); 259 printf("%f,%f,%f\n",pos[0],pos[1],pos[2]); 260 eyex = pos[0]; 261 eyey = pos[1]; 262 centerx = pos[0]; 263 centery = pos[1]; 264 glutPostRedisplay(); 265 } 266 break; 267 case GLUT_RIGHT_BUTTON: 268 if(state == GLUT_DOWN) 269 { 270 eyex = 0.0f; 271 eyey = 0.0f; 272 centerx = 0.0f; 273 centery = 0.0f; 274 glutPostRedisplay(); 275 } 276 break; 277 } 278 } 279 void mouse_move(int x,int y) 280 { 281 GLdouble *pos = new GLdouble[3]; 282 GLPOS(x,y,pos); 283 printf("%f,%f,%f\n",pos[0],pos[1],pos[2]); 284 focusx = (GLfloat)pos[0]; 285 focusy = (GLfloat)pos[1]; 286 focusz = (GLfloat)pos[2]; 287 delete [] pos; 288 glutPostRedisplay(); 289 } 290 291 void keyboard(unsigned char key,int x,int y) 292 { 293 switch(key) 294 { 295 case 'u': 296 eyez-=0.5f; 297 break; 298 case 'd': 299 eyez+=0.5f; 300 break; 301 case 27: 302 exit(0); 303 break; 304 } 305 glutPostRedisplay(); 306 } 307 int main(int argc,char **argv) 308 { 309 glutInit(&argc,argv); 310 glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); 311 glutInitWindowSize(900,600); 312 glutInitWindowPosition(400,100); 313 glutCreateWindow("hello world"); 314 init(); 315 glutDisplayFunc(display); 316 glutReshapeFunc(reshape); 317 glutKeyboardFunc(keyboard); 318 glutMouseFunc(mouse); 319 //glutPassiveMotionFunc(mouse_move); 320 glutMainLoop(); 321 return 0; 322 }