编程苦手GW——OpenGL学习练习,落地变色的弹跳小球

来源:互联网 发布:java web实现消息推送 编辑:程序博客网 时间:2024/04/27 23:09

落地变色的弹跳小球

开始学习OpenGL的状态中,还并未开始系统梳理。作为个人完成的第一次作业,其中有大量冗杂、不完美之处,待深入学习后再返回完善。。

```/*绘制一个二维小球从高空落地、弹起、再落地…不断反复,直到小球静止在地面上的过程。要求:(1)小球每次接触地面之后,即随机改遍颜色;(2)如果可能,小球接触地面时,会发生挤压变形;*/#include <GL/glut.h>#include <stdlib.h>#include <math.h>#include <time.h>float windowWidth = 600.0f, windowHeight = 600.0f;  //屏幕宽度,高度const GLfloat Pi = 3.1415926f;  //定义圆周率  const int N = 30;  //绘制圆形所用点数,N越大,越近似圆float x[N], y[N];GLfloat cx = 20.0f, cy = 550.0f;  //圆心坐标GLfloat R1 = 20.0f, R2 = 20.0f;  //圆半径GLfloat a = 1.0f, b = 0.0f, c = 1.0f;  //圆初始颜色设置GLfloat vx = 3.0f, vy = 0.0f;  //设置x、y方向的初始速度。即步长void init(void){    glClearColor(1.0, 1.0, 1.0, 0.0);}void DrawBall(GLfloat cx,GLfloat cy,GLfloat a,GLfloat b,GLfloat c)  //画圆{    glEnable(GL_BLEND);  //启用混合功能,将图形周围颜色混合    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);    glEnable(GL_POINT_SMOOTH);  //点抗锯齿    glEnable(GL_LINE_SMOOTH);  //线抗锯齿    glEnable(GL_POLYGON_SMOOTH);  //多边形抗锯齿    glColor3f(a, b, c);    glBegin(GL_POLYGON);  //连成多边形    for (int i = 0; i < N; i++)  //画出圆周的N个点    {        x[i] = cx + R1*cos(2 * Pi*i / N);        y[i] = cy + R2*sin(2 * Pi*i / N);        glVertex2f(x[i], y[i]);    }    glEnd();}void display(void)  //显示{    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer    DrawBall(cx,cy,a,b,c);    glutSwapBuffers();  //双缓冲下使用该函数交换两个缓冲区内容    glFlush();}void timerFunc(int value)  //定时器{    R1 = R2 = 20;  //正常状态下,小球为正圆形    if (vy < 0)  //上抛时,速度减慢        vy--;    else  //下落时,速度增快        vy=vy-1.5;    srand((unsigned)time(NULL));  //用时间做种,每次产生随机数不一样    if (cx > windowWidth - R1 || cx < R1)  //定义小球碰到边界折返        vx = -vx;    if (cy > windowHeight - R2|| cy < R2)        vy = -vy;    if (cx > windowWidth - R1)        cx = windowWidth - R1 - 1;    if (cy > windowHeight - R2)        cy = windowHeight - R2 - 1;    if (cy <= 20&&vx!=0)  //落地随机变色与变形    {        R1 = 23; R2 = 17;  //半径改变        a = rand() % 100 / 100.0;        b = rand() % 100 / 100.0;        c = rand() % 100 / 100.0;    }    if (cy<=R2&&vy<9)  //设定小球的停止条件    {         vx = 0; vy = 0;    }    cx += vx;  //小球位置的改变    cy += vy;    glutPostRedisplay();  //标记当前窗口需要重新绘制    glutTimerFunc(33, timerFunc, 1);  //创建定时器回调函数}void reshape(int w, int h)  //重新调整视窗{    if (h == 0)        h = 1;    glViewport(0, 0, w, h);    glMatrixMode(GL_PROJECTION);    glLoadIdentity();    if (w <= h)  //构建三维坐标        glOrtho(0.0f, windowWidth, 0.0f, windowHeight * h / w, 1.0f, -1.0f);    else        glOrtho(0.0f, windowWidth * w / h, 0.0f, windowHeight, 1.0f, -1.0f);    glMatrixMode(GL_MODELVIEW);  //设定当前矩阵为视景矩阵    glLoadIdentity();}int main(int argc, char** argv){    glutInit(&argc, argv);  //对GLUT进行初始化,并处理所有的命令行参数;调用于其他任何GLUT函数前    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);  //指定使用RGBA模式或颜色索引模式,使用单缓冲或双缓冲窗口    glutInitWindowSize(windowWidth, windowHeight);  //指定窗口大小,以像素为单位    glutInitWindowPosition(100, 100);  //指定窗口左上角的屏幕位置    glutCreateWindow("Whatever");  //argv[0]显示可执行程序路径;创建一个支持OpenGL渲染环境的窗口,返回一个唯一的标识符标识窗口;在调用glutMainLoop()函数前,该窗口并不显示    glutDisplayFunc(display);  //显示回调函数,每当GLUT确定一个窗口的内容需要重新显示时,通过该函数注册的那个回调函数就会被执行    glutReshapeFunc(reshape);  //当窗口大小发生改变时采取行动    glutTimerFunc(33, timerFunc, 1);  //设置定时器回调函数    init();    glutMainLoop();  //调用以启动程序,所以已经创建的窗口将会在这时显示,对这些窗口的渲染也开始生效。事件处理循环开始启动,已注册的显示回调函数被触发    return 0;}

落地变形过程还不太圆润。。
过程截图如下:
这里写图片描述
这里写图片描述

——続く——

0 0