OpenGL: 放大镜功能

来源:互联网 发布:猎户座计划 知乎 编辑:程序博客网 时间:2024/05/17 15:59

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

考察目的:
1.对OpenGL坐标系变换的理解;

 

我的思路就是,获取屏幕坐标,转换成opengl 坐标。移动glulookat到相应的位置,然后拉近摄像头距离,实现放大

不过,不能是正交投影,正交投影下,照相机远近不能影响大小。

特别坑爹,感觉肯定有其他方法实现。

 

屏幕坐标的转换,参考http://nehe.gamedev.net/article/using_gluunproject/16013/

pos就是转换后的结果

void GLPOS(int x,int y,GLdouble pos[3]){    GLint viewport[4];    GLdouble modelview[16];    GLdouble projection[16];    GLfloat winX,winY,winZ;    glGetDoublev(GL_MODELVIEW_MATRIX,modelview);    glGetDoublev(GL_PROJECTION_MATRIX,projection);    glGetIntegerv(GL_VIEWPORT,viewport);    winX = (float)x;    winY = viewport[3]-(float)y;    glReadPixels((int)x,(int)y,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,&winZ);    gluUnProject(winX,winY,winZ,modelview,projection,viewport,&pos[0],&pos[1],&pos[2]);}

本来是想画一个  小的十字 去跟踪鼠标。

结果,透视投影下面,用上面坐标转换的方法,跟踪鼠标,因为是视景体是梯形,所以效果不好

正交投影下,十字可以跟着鼠标走,但是又没办法放大了。

全部代码如下:

#include <windows.h>#include <GL/glut.h>#include <GL/glext.h>#include <GL/SOIL.h>#include <cstdio>/* 正方体旋转*/GLfloat xrot1 = 0.0f;GLfloat yrot1 = 0.0f;GLfloat xrot2 = 0.0f;GLfloat yrot2 = 0.0f;GLfloat xrot3 = 0.0f;GLfloat yrot3 = 0.0f;GLfloat xrot4 = 0.0f;GLfloat yrot4 = 0.0f;/*旋转速度*/GLfloat xspeed = 5.0f;GLfloat yspeed = 5.0f;/*放大相关*/GLdouble eyex = 0.0f;GLdouble eyey = 0.0f;GLdouble centerx = 0.0f;GLdouble centery = 0.0f;GLdouble eyez = 15.0f;//放大镜值/*焦点*/GLfloat focusx = 0.0f;GLfloat focusy = 0.0f;GLfloat focusz = 15.0f;GLuint texture[1];int loadGLTextures(){    for(int i=0; i<3; i++)    {        texture[i] = SOIL_load_OGL_texture                     (                         "F://LI//opengl-test//practice_big//Crate.bmp",                         SOIL_LOAD_AUTO,                         SOIL_CREATE_NEW_ID,                         SOIL_FLAG_INVERT_Y                     );    }    if(texture[0] == 0)    {        printf("load  error");        return 0;    }    glBindTexture(GL_TEXTURE_2D, texture[0]);    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);    return true;}void  init (){    loadGLTextures();    glEnable(GL_TEXTURE_2D);    glShadeModel(GL_SMOOTH);    glClearColor(0.0,0.0,0.0,0.0);    glClearDepth(1.0);    glEnable(GL_DEPTH_TEST);    glDepthFunc(GL_LEQUAL);    glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);}void reshape(int w,int h){    glViewport(0,0,(GLsizei)w,(GLsizei)h);    glMatrixMode(GL_PROJECTION);    glLoadIdentity();    gluPerspective(45.0,(GLfloat)w/(GLfloat)h,0.1,100.0);   // glOrtho(-10.0f,10.0f,-10.0f*(GLfloat)h/(GLfloat)w,10.0f*(GLfloat)h/(GLfloat)w,0.1,100.0);    glMatrixMode(GL_MODELVIEW);}void drawQuads(GLfloat xrot,GLfloat yrot){    glTranslatef(0.0f,0.0f,0.0f);    glRotatef(xrot1,1.0f,0.0f,0.0f);    glRotatef(yrot1,0.0f,1.0f,0.0f);    glBindTexture(GL_TEXTURE_2D,texture[0]);    glBegin(GL_QUADS);    // 前侧面    glNormal3f( 0.0f, 0.0f, 1.0f);                    // 法线指向观察者    glTexCoord2f(0.0f, 0.0f);glVertex3f(-1.0f, -1.0f,  1.0f);    glTexCoord2f(1.0f, 0.0f);glVertex3f( 1.0f, -1.0f,  1.0f);    glTexCoord2f(1.0f, 1.0f);glVertex3f( 1.0f,  1.0f,  1.0f);    glTexCoord2f(0.0f, 1.0f);glVertex3f(-1.0f,  1.0f,  1.0f);    // 后侧面    glNormal3f( 0.0f, 0.0f,-1.0f);                    // 法线背向观察者    glTexCoord2f(1.0f, 0.0f);    glVertex3f(-1.0f, -1.0f, -1.0f);    glTexCoord2f(1.0f, 1.0f);    glVertex3f(-1.0f,  1.0f, -1.0f);    glTexCoord2f(0.0f, 1.0f);    glVertex3f( 1.0f,  1.0f, -1.0f);    glTexCoord2f(0.0f, 0.0f);    glVertex3f( 1.0f, -1.0f, -1.0f);    // 顶面    glNormal3f( 0.0f, 1.0f, 0.0f);                    // 法线向上    glTexCoord2f(0.0f, 1.0f);    glVertex3f(-1.0f,  1.0f, -1.0f);    glTexCoord2f(0.0f, 0.0f);    glVertex3f(-1.0f,  1.0f,  1.0f);    glTexCoord2f(1.0f, 0.0f);    glVertex3f( 1.0f,  1.0f,  1.0f);    glTexCoord2f(1.0f, 1.0f);    glVertex3f( 1.0f,  1.0f, -1.0f);    // 底面    glNormal3f( 0.0f,-1.0f, 0.0f);                    // 法线朝下    glTexCoord2f(1.0f, 1.0f);    glVertex3f(-1.0f, -1.0f, -1.0f);    glTexCoord2f(0.0f, 1.0f);    glVertex3f( 1.0f, -1.0f, -1.0f);    glTexCoord2f(0.0f, 0.0f);    glVertex3f( 1.0f, -1.0f,  1.0f);    glTexCoord2f(1.0f, 0.0f);    glVertex3f(-1.0f, -1.0f,  1.0f);    // 右侧面    glNormal3f( 1.0f, 0.0f, 0.0f);                    // 法线朝右    glTexCoord2f(1.0f, 0.0f);    glVertex3f( 1.0f, -1.0f, -1.0f);    glTexCoord2f(1.0f, 1.0f);    glVertex3f( 1.0f,  1.0f, -1.0f);    glTexCoord2f(0.0f, 1.0f);    glVertex3f( 1.0f,  1.0f,  1.0f);    glTexCoord2f(0.0f, 0.0f);    glVertex3f( 1.0f, -1.0f,  1.0f);    // 左侧面    glNormal3f(-1.0f, 0.0f, 0.0f);                    // 法线朝左    glTexCoord2f(0.0f, 0.0f);    glVertex3f(-1.0f, -1.0f, -1.0f);    glTexCoord2f(1.0f, 0.0f);    glVertex3f(-1.0f, -1.0f,  1.0f);    glTexCoord2f(1.0f, 1.0f);    glVertex3f(-1.0f,  1.0f,  1.0f);    glTexCoord2f(0.0f, 1.0f);    glVertex3f(-1.0f,  1.0f, -1.0f);    glEnd();}void drawFocus(){    GLfloat a = 1.0f;    glColor3f(1.0f,1.0f,1.0f);    glLineWidth(1.0f);    glBegin(GL_LINES);        glVertex3f(-1.0f/a,1.0f/a,0.0f);        glVertex3f(-1.0f/a,3.0f/a,0.0f);    glEnd();    glBegin(GL_LINES);        glVertex3f(-1.0f/a,1.0f/a,0.0f);        glVertex3f(-3.0f/a,1.0f/a,0.0f);    glEnd();    glBegin(GL_LINES);        glVertex3f(1.0f/a,1.0f/a,0.0f);        glVertex3f(1.0f/a,3.0f/a,0.0f);    glEnd();    glBegin(GL_LINES);        glVertex3f(1.0f/a,1.0f/a,0.0f);        glVertex3f(3.0f/a,1.0f/a,0.0f);    glEnd();    glBegin(GL_LINES);        glVertex3f(-1.0f/a,-1.0f/a,0.0f);        glVertex3f(-1.0f/a,-3.0f/a,0.0f);    glEnd();    glBegin(GL_LINES);        glVertex3f(-1.0f/a,-1.0f/a,0.0f);        glVertex3f(-3.0f/a,-1.0f/a,0.0f);    glEnd();    glBegin(GL_LINES);        glVertex3f(1.0f/a,-1.0f/a,0.0f);        glVertex3f(1.0f/a,-3.0f/a,0.0f);    glEnd();    glBegin(GL_LINES);        glVertex3f(1.0f/a,-1.0f/a,0.0f);        glVertex3f(3.0f/a,-1.0f/a,0.0f);    glEnd();}void display(){    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    glLoadIdentity();    /*glPushMatrix();        glDisable(GL_TEXTURE_2D);        glTranslatef(focusx,focusy,focusz);        drawFocus();        glEnable(GL_TEXTURE_2D);    glPopMatrix();*/    gluLookAt(eyex,eyey,eyez,centerx,centery,-1.0f,0.0f,1.0f,0.0f);    /*glPushMatrix();        glPointSize(5.0f);        glBegin(GL_POINTS);            glVertex3f(9.0f,0.0f,0.0f);        glEnd();    glPopMatrix();*/    glPushMatrix();        glTranslatef(-3.5f,2.5f,0.0f);        drawQuads(xrot1,yrot1);    glPopMatrix();    glPushMatrix();        glTranslatef(3.5f,2.5f,0.0f);        drawQuads(xrot2,yrot2);    glPopMatrix();    glPushMatrix();        glTranslatef(-3.5f,-2.5f,0.0f);        drawQuads(xrot3,yrot3);    glPopMatrix();    glPushMatrix();        glTranslatef(3.5f,-2.5f,0.0f);        drawQuads(xrot4,yrot4);    glPopMatrix();    glFlush();}void GLPOS(int x,int y,GLdouble pos[3]){    GLint viewport[4];    GLdouble modelview[16];    GLdouble projection[16];    GLfloat winX,winY,winZ;    glGetDoublev(GL_MODELVIEW_MATRIX,modelview);    glGetDoublev(GL_PROJECTION_MATRIX,projection);    glGetIntegerv(GL_VIEWPORT,viewport);    winX = (float)x;    winY = viewport[3]-(float)y;    glReadPixels((int)x,(int)y,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,&winZ);    gluUnProject(winX,winY,winZ,modelview,projection,viewport,&pos[0],&pos[1],&pos[2]);}void mouse(int button,int state,int x,int y){    switch(button)    {    case GLUT_LEFT_BUTTON:        if(state == GLUT_DOWN)        {            printf("%d,%d\n",x,y);            GLdouble *pos = new GLdouble[3];            GLPOS(x,y,pos);            printf("%f,%f,%f\n",pos[0],pos[1],pos[2]);            eyex = pos[0];            eyey = pos[1];            centerx = pos[0];            centery = pos[1];            glutPostRedisplay();        }        break;    case GLUT_RIGHT_BUTTON:        if(state == GLUT_DOWN)        {            eyex = 0.0f;            eyey = 0.0f;            centerx = 0.0f;            centery = 0.0f;            glutPostRedisplay();        }        break;    }}void mouse_move(int x,int y){    GLdouble *pos = new GLdouble[3];    GLPOS(x,y,pos);    printf("%f,%f,%f\n",pos[0],pos[1],pos[2]);    focusx = (GLfloat)pos[0];    focusy = (GLfloat)pos[1];    focusz = (GLfloat)pos[2];    delete [] pos;    glutPostRedisplay();}void keyboard(unsigned char key,int x,int y){    switch(key)    {    case 'u':        eyez-=0.5f;        break;    case 'd':        eyez+=0.5f;        break;    case 27:        exit(0);        break;    }    glutPostRedisplay();}int main(int argc,char **argv){    glutInit(&argc,argv);    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);    glutInitWindowSize(900,600);    glutInitWindowPosition(400,100);    glutCreateWindow("hello world");    init();    glutDisplayFunc(display);    glutReshapeFunc(reshape);    glutKeyboardFunc(keyboard);    glutMouseFunc(mouse);    //glutPassiveMotionFunc(mouse_move);    glutMainLoop();    return 0;}


 

0 0
原创粉丝点击