动画

静止的矩形

#include "stdafx.h"
#include<windows.h>
#include<gl/glut.h>
#include<gl/gl.h>
#include<gl/glu.h>
//头文件/表示在gl目录下的.h头文件

//函数用于在窗口中绘制需要的图形
//只是一个场景scene 并不会真正绘制到图形中去。
void RenderScene(void)
{
    //用当前清除颜色缓冲区,即设定窗口的背景颜色
    // 清除viewport的缓冲区
    //大概就是清除下面所要画的区域的缓冲区
    glClear(GL_COLOR_BUFFER_BIT);


    //设置当前绘图使用的GGB颜色  red
    glColor3f(1.0f,0.0f,0.0f);

    //使用当前的颜色绘制一个填充的矩形
    //绘制矩形,窗口坐标系是左下角(0,0),x向右,y向上
    //qt使用的是右上角(0,0)
    glRectf(100.0f,150.0f,150.0f,100.0f);

    //强制刷新OpenGL命令队列
    glFlush();
    /*
    简单地说glFlush()就是强制刷新,OpenGL是使用一条渲染管线[3]  线性处理命令的,一般情况下,
    我们提交给OpenGL的指令并不是马上送到驱动程序[4]  里执行的,而是放到一个缓冲区里面,
    等这个缓冲区满了再一次过发到驱动程序里执行;很多时候只有几条指令是填充不满那个缓冲区的,
    就是说这些指令根本没有被发送到驱动里,所以我们要调用glFlush来强制把这些指令送到驱动里进行处理。
    */
}
//函数ChangeSize是窗口大小改变时调用的登记函数
//GLsizeiGLsizei 是32位整数
void ChangeSize(GLsizei w, GLsizei h)
{
    //窗口的高度y不为0
    //去掉调试之后,还没发现有什么区别
    if (h == 0)  
        h = 1;


    //定义视区并指明尺寸
    //一般是充满整个屏幕
    glViewport(0,0,w,h); 

    /*
        glMatrixMode设置当前矩阵模式:
    GL_MODELVIEW, 对模型视景矩阵堆栈应用随后的矩阵操作.
        GL_PROJECTION, 对投影矩阵应用随后的矩阵操作.
        GL_TEXTURE, 对纹理矩阵堆栈应用随后的矩阵操作.
    与glLoadIdentity()一同使用
    glLoadIdentity():将当前的用户坐标系的原点移到了屏幕中心:类似于一个复位操作
    */
    //重置坐标系统,使投影变换复位
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();


    //建立修建空间的范围
    //glOrtho是在3D笛卡儿坐标空间定义
    if (w <= h)
        glOrtho(0.0f, 250.0f, 0.0f, 250.0f*h / w, 1.0f, -10.f);
    else
        glOrtho(0.0f, 250.0*w/h, 0.0f, 250.0f, 1.0f, -1.0f);

    //告诉OpenGL将来的所有变换都会影响模型
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}


//函数setupRC用于初始化,常用来设置场景渲染状态
void SetupRC(void)
{

    //这个函数用于设置清除窗口时使用的颜色,即设定窗口内的背景颜色
    //最后一个参数是alpha,主要用于混合的特殊效果,如半透明效果等
    //其实就是使用某种颜色 清空当前的所有颜色,或者说填充整个窗口
    glClearColor(0.0f,1.0f,0.0f,1.0f);
}

//主函数基本都是glut的框架
void main(void )
{
    //初始化GLUT库OpenGL窗口的显示模式
    //glutInitDisplayMode sets the initial display mode
    //创建窗口时使用单缓冲区GLUT_SINGLE并使用RGB颜色模式
    //一般双模式GLUT_DOUBLE是用于动画效果的场合
    //这是两个默认的参数
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);


    //创建一个名为GLRect的窗口
    glutCreateWindow("GLRect");


    //callback 
    //glutDisplayFunc sets the display callback for the current window
    //设置当前窗口的显示回调函数和窗口再整形回调函数

    //这样当要绘制窗口,就会调用自定义RenderScene函数  比如添加一个图形
    glutDisplayFunc(RenderScene); 

    //这样改变窗口,就会调用ChangeSize函数    比如放大或者缩小窗口
    // glutReshapeFunc(void (*func)(int width, int height));
    //The width and height parameters of the callback specify the new window size in pixels
    //回调函数会指定对应窗口的大小,然后通过参数传递给width,height.  大概是这个意思吧。
    //除了窗口大小改变会调用回调函数之外,当第一次创建窗口的时候,回调函数也会被调用。
    glutReshapeFunc(ChangeSize);

        //可以通过调式加深对这两个回调函数的理解。

    //SetupRC并不是GLUT的框架,是自定义的函数, 其作用是进行OpenGL初始化
    //OpenGL的初始化必须在渲染之前执行
    SetupRC();


    //启动主程序GLUT事件处理循环
    //该函数让GLUT框架开始运行,所有设置的回调函数开始工作,
    //直到用户终止程序为止
    //也就是说,SetupRC是在渲染之前执行的。
    glutMainLoop();
}

这里写图片描述


跳动的矩形

#include "stdafx.h"
#include <gl\glut.h>    
#include <gl\GLU.h>
#include <gl\GL.h>
#include <math.h>

const GLfloat PI = 3.141595654f;
const int windowWidth = 400;
const int windowHeight = 400;

GLfloat posX = 100.0f;
GLfloat posY = 200.0f;
GLsizei rsize = 50;

GLfloat xstep = 1.0f;
GLfloat ystep = 1.0f;

void myDisplay(void)
{
    // 用当前清除色清除颜色缓冲区,即设定窗口的背景色
    glClear(GL_COLOR_BUFFER_BIT);

    glColor3f(1.0f, 0, 0);
    glRectf(posX, posY, posX + rsize, posY + rsize);

    //glFlush();
    glutSwapBuffers(); // 双缓冲下使用该函数交换两个缓冲区的内容
}

void timerFunc(int value)
{
    if (posX > windowWidth - rsize || posX < 0)
        xstep = -xstep;
    if (posY > windowHeight - rsize || posY < 0)
        ystep = -ystep;

    if (posX > windowWidth - rsize)
        posX = windowWidth - rsize - 1;
    if (posY > windowHeight - rsize)
        posY = windowHeight - rsize - 1;

    posX += xstep;
    posY += ystep;

    /*
    glutPostRedisplay 标记当前窗口需要重新绘制。
    通过glutMainLoop下一次循环时,窗口显示将被回调以重新显示窗口的正常面板。
    */
    glutPostRedisplay();

    /*
    (1)如果用定时器的话,初始的时候注册一个定时器的回调函数,原型是
    glutTimerFunc(unsigned int millis, void (*func)(int value), int value);
    参数对应关系为:glutTimerFunc(毫秒数, 回调函数指针, 区别值);
    (2)写自己的回调函数 void OnTimer(int value);
    用value区分是哪个定时器
    (3)在函数里改变和位置有关的变量,然后调用glutPostRedisplay();用来重绘
    (4)最后再次调用glutTimerFunc,因为glut的定时器是调用一次才产生一次定时,所以如果要持续产生定时的话,

    在定时函数末尾再次调用glutTimerFunc

    */
    glutTimerFunc(33, timerFunc, 1);
}


int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    //glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); // 使用双缓冲

    glutInitWindowPosition(100, 100);
    glutInitWindowSize(windowWidth, windowHeight);

    glutCreateWindow("第一个OpenGL程序");

    gluOrtho2D(0.0, windowWidth, 0.0, windowHeight);

    glutDisplayFunc(&myDisplay);

    glutTimerFunc(33, timerFunc, 1);

    glutMainLoop();
    return 0;
}

说明:这个图是动图,红色矩形可以跳动
这里写图片描述


地球绕太阳转动_OpenGL

#include <gl/glut.h>

#define WIDTH 400
#define HEIGHT 400

static GLfloat angle = 0.0f;

void myDisplay(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // 创建透视效果视图
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(90.0f, 1.0f, 1.0f, 20.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0.0, 5.0, -10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

    // 定义太阳光源,它是一种白色的光源
    {
    GLfloat sun_light_position[] = {0.0f, 0.0f, 0.0f, 1.0f};
    GLfloat sun_light_ambient[]  = {0.0f, 0.0f, 0.0f, 1.0f};
    GLfloat sun_light_diffuse[]  = {1.0f, 1.0f, 1.0f, 1.0f};
    GLfloat sun_light_specular[] = {1.0f, 1.0f, 1.0f, 1.0f};

    glLightfv(GL_LIGHT0, GL_POSITION, sun_light_position);
    glLightfv(GL_LIGHT0, GL_AMBIENT,  sun_light_ambient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE,  sun_light_diffuse);
    glLightfv(GL_LIGHT0, GL_SPECULAR, sun_light_specular);

    glEnable(GL_LIGHT0);
    glEnable(GL_LIGHTING);
    glEnable(GL_DEPTH_TEST);
    }

    // 定义太阳的材质并绘制太阳
    {
        GLfloat sun_mat_ambient[]  = {0.0f, 0.0f, 0.0f, 1.0f};
        GLfloat sun_mat_diffuse[]  = {0.0f, 0.0f, 0.0f, 1.0f};
        GLfloat sun_mat_specular[] = {0.0f, 0.0f, 0.0f, 1.0f};
        GLfloat sun_mat_emission[] = {0.5f, 0.0f, 0.0f, 1.0f};
        GLfloat sun_mat_shininess  = 0.0f;

        glMaterialfv(GL_FRONT, GL_AMBIENT,   sun_mat_ambient);
        glMaterialfv(GL_FRONT, GL_DIFFUSE,   sun_mat_diffuse);
        glMaterialfv(GL_FRONT, GL_SPECULAR,  sun_mat_specular);
        glMaterialfv(GL_FRONT, GL_EMISSION,  sun_mat_emission);
        glMaterialf (GL_FRONT, GL_SHININESS, sun_mat_shininess);

        glutSolidSphere(2.0, 40, 32);
    }

    // 定义地球的材质并绘制地球
    {
        GLfloat earth_mat_ambient[]  = {0.0f, 0.0f, 0.5f, 1.0f};
        GLfloat earth_mat_diffuse[]  = {0.0f, 0.0f, 0.5f, 1.0f};
        GLfloat earth_mat_specular[] = {0.0f, 0.0f, 1.0f, 1.0f};
        GLfloat earth_mat_emission[] = {0.0f, 0.0f, 0.0f, 1.0f};
        GLfloat earth_mat_shininess  = 30.0f;

        glMaterialfv(GL_FRONT, GL_AMBIENT,   earth_mat_ambient);
        glMaterialfv(GL_FRONT, GL_DIFFUSE,   earth_mat_diffuse);
        glMaterialfv(GL_FRONT, GL_SPECULAR,  earth_mat_specular);
        glMaterialfv(GL_FRONT, GL_EMISSION,  earth_mat_emission);
        glMaterialf (GL_FRONT, GL_SHININESS, earth_mat_shininess);

        glRotatef(angle, 0.0f, -1.0f, 0.0f);
        glTranslatef(5.0f, 0.0f, 0.0f);
        glutSolidSphere(2.0, 40, 32);
    }

    glutSwapBuffers();
}
void myIdle(void)
{
    angle += 1.0f;
    if( angle >= 360.0f )
        angle = 0.0f;
    myDisplay();
}

int main(int argc, char* argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
    glutInitWindowPosition(200, 200);
    glutInitWindowSize(WIDTH, HEIGHT);
    glutCreateWindow("OpenGL光照演示");
    glutDisplayFunc(&myDisplay);
    glutIdleFunc(&myIdle);
    glutMainLoop();
    return 0;
}

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值