OpenGL入门(三):图形随鼠标转动

void gluLookAt(GLdouble eyex,GLdouble eyey,GLdouble eyez,GLdouble centerx,GLdouble centery,GLdouble centerz,GLdouble upx,GLdouble upy,GLdouble upz);
函数功能:定义一个视图矩阵,并与当前矩阵相乘。
eyex,eyey,eyez表示相机在世界坐标系中的位置;
centerx,centery,centerz表示镜头对准的物体在世界坐标系中的位置;
upx,upy,upz相机顶部向上的方向在世界坐标系中的方向。

glColor3f(A,B,C);
函数功能:颜色设定,0.0不使用颜色成分,1.0使用颜色成分的最大值。

颜色
glColor3f(0.0,0.0,0.0) 黑色
glColor3f(1.0,0.0,0.0) 红色
glColor3f(0.0,1.0,0.0) 绿色
glColor3f(0.0,0.0,1.0) 蓝色
glColor3f(1.0,1.0,0.0) 黄色
glColor3f(1.0,0.0,1.0) 品红色
glColor3f(0.0,1.0,1.0) 青色
glColor3f(1.0,1.0,1.0) 白色
Static
//Example2
//File1第一个代码文件的代码
#include
void fn();  //声明fn函数
static int n;  //定义静态全局变量
void main()
{
    n=20;
    cout<//File2第二个代码文件的代码
#include
extern int n;//用extern声明不能使用静态全局变量
void fn()
{
    n++;
    printf("%d",n);
}
全局变量默认是有外部链接性的,作用域是整个工程,在一个文件内定义的全局变量,在另一个文件中,通过extern全局变量名的声明,就可以使用全局变量。
全局静态变量是显式用static修饰的全局变量,作用域是声明此变量所在的文件,其他的文件即使用extern声明也不能使用。

静态函数不能被其它文件所用;其它文件中可以定义相同名字的函数,不会发生冲突。

if(state == GLUT_DOWN) //相当于“如果某个鼠标键被按下”
if(state == GLUT_UP) //相当于“如果某个鼠标键被放开”
if(button == GLUT_LEFT_BUTTON) //相当于“如果鼠标左键被按下或者被放开”
if(button == GLUT_RIGHT_BUTTON) //相当于“如果鼠标右键被按下或被放开”
if(button == GLUT_MIDDLE_BUTTON) //相当于“如果鼠标中键被按下或者被放开”

void glEnable(GLenum cap);
函数功能:启用由参数决定的功能,与glDisable相对应,glDisable是用来关闭的,两个函数的参数取值是一致的。
参数说明:GLenum 是unsigned int类型;cap 是一个取值,由值决定启用功能。
说明:glEnable不能写在glBegin和glEnd两个函数中间。
参数cap的取值如下表所示:

类型 说明
GL_ALPHA_TEST 4864 跟据函数glAlphaFunc的条件要求来决定图形透明的层度是否显示
GL_AUTO_NORMAL 3456 执行后,图形能把光反射到各个方向
GL_BLEND 3042 启用颜色混合。例如实现半透明效果
GL_CLIP_PLANE0 ~ GL_CLIP_PLANE5 12288 ~ 12283 根据函数glClipPlane的条件要求,启用图形切割管道。这里指六种缓存管道
GL_COLOR_LOGIC_OP 3058 启用每一像素的色彩为位逻辑运算
GL_COLOR_MATERIAL 2930 执行后,图形(材料)将根据光线的照耀进行反射,反射要求由函数glColorMaterial进行设定
GL_CULL_FACE 2884 根据函数glCullFace要求启用隐藏图形材料的面
GL_DEPTH_TEST 2929 启用深度测试,根据坐标的远近自动隐藏被遮住的图形(材料)
GL_DITHER 3024 启用抖动
GL_FOG 2912 雾化效果,例如距离越远越模糊
GL_INDEX_LOGIC_OP 3057 逻辑操作
GL_LIGHT0 ~ GL_LIGHT7 16384 ~ 16391 启用0号灯到7号灯(光源),光源要求由函数glLight函数来完成
GL_LIGHTING 2896 启用灯源
GL_LINE_SMOOTH 2848 执行后,过虑线段的锯齿
GL_LINE_STIPPLE 2852 执行后,画虚线
GL_LOGIC_OP 3057 逻辑操作
GL_MAP1_COLOR_4 3472 根据函数Map1对贝赛尔曲线的设置,启用glEvalCoord1,glEvalMesh1,glEvalPoint1生成RGBA曲线
GL_MAP1_INDEX 3473 根据函数Map1对贝赛尔曲线的设置,启用glEvalCoord1,glEvalMesh1,glEvalPoint1生成颜色索引曲线
GL_MAP1_NORMAL 3474 根据函数Map1对贝赛尔曲线的设置,启用glEvalCoord1,glEvalMesh1,glEvalPoint1生成法线
GL_MAP1_TEXTURE_COORD_1 3475 根据函数Map1对贝赛尔曲线的设置,启用glEvalCoord1,glEvalMesh1,glEvalPoint1生成文理坐标
GL_MAP1_TEXTURE_COORD_2 3476 根据函数Map1对贝赛尔曲线的设置,启用glEvalCoord1,glEvalMesh1,glEvalPoint1生成文理坐标
GL_MAP1_TEXTURE_COORD_3 3477 根据函数Map1对贝赛尔曲线的设置,启用glEvalCoord1,glEvalMesh1,glEvalPoint1生成文理坐标
GL_MAP1_TEXTURE_COORD_4 3478 根据函数Map1对贝赛尔曲线的设置,启用glEvalCoord1,glEvalMesh1,glEvalPoint1生成文理坐标
GL_MAP1_VERTEX_3 3479 根据函数Map1对贝赛尔曲线的设置,启用glEvalCoord1,glEvalMesh1,glEvalPoint1在三维空间里生成曲线
GL_MAP1_VERTEX_4 3480 根据函数Map1对贝赛尔曲线的设置,启用glEvalCoord1,glEvalMesh1,glEvalPoint1在四维空间里生成法线
GL_MAP2_COLOR_4 3504 根据函数Map2对贝赛尔曲线的设置,启用glEvalCoord2,glEvalMesh2,glEvalPoint2生成RGBA曲线
GL_MAP2_INDEX 3505 根据函数Map2对贝赛尔曲线的设置,启用glEvalCoord2,glEvalMesh2,glEvalPoint2生成颜色索引
GL_MAP2_NORMAL 3506 根据函数Map2对贝赛尔曲线的设置,启用glEvalCoord2,glEvalMesh2,glEvalPoint2生成法线
GL_MAP2_TEXTURE_COORD_1 3507 根据函数Map2对贝赛尔曲线的设置,启用glEvalCoord2,glEvalMesh2,glEvalPoint2生成纹理坐标
GL_MAP2_TEXTURE_COORD_2 3508 根据函数Map2对贝赛尔曲线的设置,启用glEvalCoord2,glEvalMesh2,glEvalPoint2生成纹理坐标
GL_MAP2_TEXTURE_COORD_3 3509 根据函数Map2对贝赛尔曲线的设置,启用glEvalCoord2,glEvalMesh2,glEvalPoint2生成纹理坐标
GL_MAP2_TEXTURE_COORD_4 3510 根据函数Map2对贝赛尔曲线的设置,启用glEvalCoord2,glEvalMesh2,glEvalPoint2生成纹理坐标
GL_MAP2_VERTEX_3 3511 根据函数Map2对贝赛尔曲线的设置,启用glEvalCoord2,glEvalMesh2,glEvalPoint2在三维空间里生成曲线
GL_MAP2_VERTEX_4 3512 根据函数Map2对贝赛尔曲线的设置,启用glEvalCoord2,glEvalMesh2,glEvalPoint2在三维空间里生成曲线
GL_NORMALIZE 2977 根据函数glNormal的设置条件,启用法向量
GL_POINT_SMOOTH 2832 执行后,过虑线点的锯齿
GL_POLYGON_OFFSET_FILL 32823 根据函数glPolygonOffset的设置,启用面的深度偏移
GL_POLYGON_OFFSET_LINE 10754 根据函数glPolygonOffset的设置,启用线的深度偏移
GL_POLYGON_OFFSET_POINT 10753 根据函数glPolygonOffset的设置,启用点的深度偏移
GL_POLYGON_SMOOTH 2881 过虑图形(多边形)的锯齿
GL_POLYGON_STIPPLE 2882 执行后,多边形为矢量画图
GL_SCISSOR_TEST 3089 根据函数glScissor设置,启用图形剪切
GL_STENCIL_TEST 2960 启用模板测试
GL_TEXTURE_1D 3552 启用一维文理
GL_TEXTURE_2D 3553 启用二维文理
L_TEXTURE_GEN_Q 3171 根据函数glTexGen,启用纹理处理
GL_TEXTURE_GEN_R 3170 根据函数glTexGen,启用纹理处理
GL_TEXTURE_GEN_S 3168 根据函数glTexGen,启用纹理处理
GL_TEXTURE_GEN_T 3169 根据函数glTexGen,启用纹理处理

glViewport(GLint x,GLint y,GLsizei width,GLsizei height)
在屏幕上打开窗口的任务是由窗口系统,而不是OpenGL负责的,在默认情况下,视口被设置为占据打开窗口的整个像素矩形,窗口大小和设置视口大小相同。
x,y——以像素为单位,指定了视口的左下角。
width,height——表示这个视口矩形的宽度和高度。

glMatrixMode(Mode);
设置当前矩阵模式:
GL_MODELVIEW 对模型视景矩阵堆栈应用随后的矩阵操作.
GL_PROJECTION 对投影矩阵应用随后的矩阵操作.
GL_TEXTURE 对纹理矩阵堆栈应用随后的矩阵操作.
与glLoadIdentity()一同使用

glLoadIdentity();
函数功能:将图形的当前点移到了屏幕中心,类似于一个复位操作。
注意:用一个单位矩阵来替换当前矩阵的做法并非在任何场合下都可以使用
例如,已经进行了3次矩阵变换,而现在打算将当前矩阵恢复到第二次变换后的状态时,该方法将失效。此时可用glPushMatrix()命令将每次变换前的矩阵压入矩阵堆栈,在进行完新矩阵中的各种操作后,再利glPopMatrix()命令将栈顶的矩阵弹出矩阵堆栈,成为当前矩阵。

glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far)
函数功能:将当前的可视空间设置为正投影空间。
六个参数, 前两个是x轴最小坐标和最大坐标,中间两个是y轴,最后两个是z轴值
它创建一个平行视景体(就是一个长方体空间区域)。
实际上这个函数的操作是创建一个正射投影矩阵,并且用这个矩阵乘以当前矩阵。
其中近裁剪平面是一个矩形,矩形左下角点三维空间坐标是(left,bottom,-near),
右上角点是(right,top,-near);远裁剪平面也是一个矩形,左下角点空间坐标是(left,bottom,-far),右上角点是(right,top,-far)。
注意,所有的near和far值同时为正或同时为负, 值不能相同。如果没有其他变换,正射投影的方向平行于Z轴,且视点朝向Z负轴。这意味着物体在视点前面时far和near都为负值,物体在视点后面时far和near都为正值。
只有在视景体里的物体才能显示出来。
如果最后两个值是(0,0),也就是near和far值相同了,视景体深度没有了,整个视景体都被压成个平面了,就会显示不正确。

void glFrustum(GLdouble left, GLdouble Right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far);
函数功能:创建一个透视投影的矩阵,并且用这个矩阵乘以当前矩阵,这个函数的参数只定义近裁剪平面的左下角点和右上角点的三维空间坐标,即(left,bottom,-near)和(right,top,-near);最后一个参数far是远裁剪平面的离视点的距离值,其左下角点和右上角点空间坐标由函数根据透视投影原理自动生成。near和far表示离视点的远近,它们总为正值(near/far 必须>0)。
OpenGL入门(三):图形随鼠标转动_第1张图片

void gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear, GLdouble zFar);
函数功能:创建一个对称的透视型视景体,但它的参数定义于前面的不同,如图。其操作是创建一个对称的透视投影矩阵,并且用这个矩阵乘以当前矩阵。参数fovy定义视野在Y-Z平面的角度,范围是[0.0, 180.0];参数aspect是投影平面宽度与高度的比率;参数Near和Far分别是近远裁剪面到视点(沿Z负轴)的距离,它们总为正值。
OpenGL入门(三):图形随鼠标转动_第2张图片

代码如下:


#include  
#include 
#define PI 3.1415926535
static int du=90,OriX=-1,OriY=-1;   //du是视点和x轴的夹角
static float r=1.5,h=0.0;   //r是视点绕y轴的半径,h是视点高度即在y轴上的坐标
static float c=PI/180.0;    //弧度和角度转换参数

void renderScene(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除缓冲,GL_COLOR_BUFFER_BIT :颜色缓冲标志位
    glLoadIdentity();                                       //重置当前矩阵为4*4的单位矩阵
    //glRotatef(-135,0.5,0.0,0.0);                          //旋转
    //glTranslatef(0.5,0.5,0.0);                            //移动原点
    //glScalef(0.5,0.5,1);                                  //缩小
    /*glBegin(GL_TRIANGLES);
        glVertex3f(-0.5,-0.5,0.0);
        glVertex3f(0.5,0.0,0.0);
        glVertex3f(0.0,0.0,0.0);
    glEnd();*/
    gluLookAt(r*cos(c*du), h, r*sin(c*du), 0.0,0.0,0.0, 0.0,1.0,0.0);   //从视点看远点
    glColor3f(1.0,0.0,0.0);
    glutWireTeapot(0.5f);
    glutSwapBuffers();                                      //交换两个缓冲区指针
}

void Mouse(int button, int state, int x, int y)
{
    if(state == GLUT_DOWN)  //记录鼠标按下位置
        OriX = x,OriY = y;
}

void onMouseMove(int x,int y)   //处理鼠标拖动
{
    du += x - OriX; //鼠标在窗口x轴方向上的增量加到视点与x轴的夹角上,就可以左右转
    h +=0.03*(y-OriY);  //鼠标在窗口y轴方向上的改变加到视点y的坐标上,就可以上下转
    if(h>1.0)   h=1.0;  //对视点y坐标作一些限制,不会使视点太奇怪
    else if(h<-1.0) h=-1.0;
    OriX = x,OriY = y;  //将此时的坐标作为旧值,为下一次计算增量做准备
}

void init()
{
    glEnable(GL_DEPTH_TEST);    //启用深度,根据坐标的远近自动隐藏被遮住的图形(材料)
}

void reshape(int w,int h)
{
    glViewport(0,0,w,h);    //截图;1、2为视口的左下角;3、4为视口的宽度和高度
    glMatrixMode(GL_PROJECTION);    //将当前矩阵指定为投影矩阵
    glLoadIdentity();
    gluPerspective(75.0,(float)w/h,1.0,1000.0); //1、视野在Y-Z平面的角度[0,180];2、投影平面宽度与高度的比率;3、近截剪面到视点的距离;4、远截剪面到视点的距离
    glMatrixMode(GL_MODELVIEW);     //对模型视景矩阵堆栈应用随后的矩阵操作.
}

int main(int argc, char* argv[])
{
    glutInit(&argc, argv);                                          //初始化glut库
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);      //设置初始显示模式
    glutInitWindowPosition(100,100);
    glutInitWindowSize(600,600);
    glutCreateWindow("***************");
    init();
    glutReshapeFunc(reshape);       //
    glutDisplayFunc(renderScene);           //
    glutIdleFunc(renderScene);          //设置不断调用显示函数
    glutMouseFunc(Mouse);
    glutMotionFunc(onMouseMove);

    //glutDisplayFunc(renderScene);                                 //调用函数
    glutMainLoop();//enters the GLUT event processing loop.
    return 0;
}

运行结果:
OpenGL入门(三):图形随鼠标转动_第3张图片

你可能感兴趣的:(OpenGL)