您的位置:首页 > 编程语言

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

2017-03-23 10:09 941 查看

落地变色的弹跳小球

开始学习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
, y
;
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;
}
9255
>

落地变形过程还不太圆润。。

过程截图如下:





——続く——
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  opengl