OpenGL:ルーペ機能

9617 ワード

要求: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
",x,y); GLdouble *pos = new GLdouble[3]; GLPOS(x,y,pos); printf("%f,%f,%f
",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
",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; }