opengl 放大镜

Exercise 6:放大镜功能

要求:

  1. 在练习5的基础上,实现放大镜功能,放大场景中的任意部分;
  2. 放大镜可以通过鼠标键盘进行控制;

考察目的:

  1. 对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 }
View Code

 

 

posted @ 2013-05-19 21:07  细胞核  阅读(696)  评论(0编辑  收藏  举报