OpenGL: 绘制3D物体、鼠标交互、反向变换

/*  reference http://nehe.gamedev.net/article/using_gluunproject/16013/
*/


#include <windows.h>   // windows系统要加这个。因为下面2个头文件的一些宏是在这个文件中定义的
#include <gl/Gl.h>
#include <gl/glut.h>    //这两个头文件在OpenGL程序中几乎必加。

#include <cstdio>    //标准输入输出,用来打印坐标
//<<<<<<<<<<<<<<<<<<<<<<< myInit >>>>>>>>>>>>>>>>>>>>    初始化
void myInit(void)
{
    glClearColor(0.0,0.0,0.0,0.0);       // 设置背景色:黑色。 
    glShadeModel(GL_SMOOTH);             // 设置着色模式,可选GL_SMOOTH(默认)或GL_FLAT。采用恒定着色时(即GL_FLAT),使用图元中某个顶点的颜色来渲染整个图元。

}
//<<<<<<<<<<<<<<<<<<<<<<<< myDisplay >>>>>>>>>>>>>>>>> 绘制
void myDisplay(void)
{
    glEnable(GL_DEPTH_TEST);        //开启深度测试
    glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);      // 将屏幕清除为背景色
    glColor3f(1.0f, 0.0f, 0.0f);    // 绘制颜色:红色
    glLoadIdentity();

    gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0 ,1.0, 0.0); //设置eye,相机位置,和向上up向量,可调不同参数来观察会有什么变化
    glScalef(1.0, 2.0, 1.0);        //表示y坐标值扩大两倍,这样原本方的物体就变成长的了。 
    glutSolidSphere(1.0, 30, 50);   //cube的边长

    glFlush();                      // send all output to display 把数据从缓冲区弄到屏幕上
}

//<<<<<<<<<<<<<<<<<<<<<<<< reshape >>>>>>>>>>>>>>>>>    视图变换
void myReshape(int w, int h)
{
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);        //设置视口大小
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);        //将当前矩阵与一个透视矩阵相乘,把当前矩阵转变成透视矩阵
    glMatrixMode(GL_MODELVIEW);
}

//<<<<<<<<<<<<<<<<<<<<<<<< GetOGLPos >>>>>>>>>>>>>>>>>    由屏幕坐标得到OpenGL坐标
void GetOGLPos(int x, int y)
{
    GLint viewport[4];
    GLdouble modelview[16];
    GLdouble projection[16];
    GLfloat winX, winY, winZ;
    GLdouble posX, posY, posZ;

    glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
    glGetDoublev( GL_PROJECTION_MATRIX, projection );
    glGetIntegerv( GL_VIEWPORT, viewport );

    winX = (float)x;
    winY = (float)viewport[3] - (float)y;
    glReadPixels( x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );

    gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);

    //return CVector3(posX, posY, posZ);
    printf("x:%f y:%f z:%f\n",posX, posY, posZ);
    return;

}


//<<<<<<<<<<<<<<<<<<<<<<<< reshape >>>>>>>>>>>>>>>>>    鼠标点击
void myMouse(int button, int state, int x, int y)
{
    if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
        GetOGLPos(x,y);

}


//<<<<<<<<<<<<<<<<<<<<<<<< main >>>>>>>>>>>>>>>>>>>>>>
void main(int argc, char** argv)
{
    glutInit(&argc, argv);          // ***对GLUT进行初始化
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA |GLUT_DEPTH); // ***set display mode,单缓冲/双缓冲,颜色索引模式,深度等
    glutInitWindowSize(480,480);     // ***设置窗口大小
    glutInitWindowPosition(100, 150); // ***设置窗口位置
    glutCreateWindow("my cube attempt"); // ***创建窗口
    myInit();  

    glutDisplayFunc(myDisplay);     // 显示事件回调函数
    glutReshapeFunc(myReshape);        //当窗口改变时的回调函数
    glutMouseFunc(myMouse);            //当鼠标交互时的回调函数
    glutMainLoop();              // ***启动程序,检测事件并进行处理
}

http://www.cnblogs.com/difei/p/3718966.html
展开阅读全文

没有更多推荐了,返回首页