OpenGL织梦之旅【第四章】第2节.简单的3D动画
2013-03-04 15:36
393 查看
上一小节中,我们已经成功地搭建好了一个“小剧场”,“观众席”已经设置好了,但是“演员”还没有到位。所以这一小节,我们就来请一些“演员”,让他们做一些“动作”。
还记得读取纹理那章的内容吧~2D纹理在这里同样是可以使用的。为了方便,我把LoadBitmap函数放到了"bmpLoader.h"中,这样方便调用。
在bmpLoader.h中:
具体的函数内容就不写出来了。
在init()函数中,调用boxTexture=LoadBitmap("Box.bmp");把纹理保存到boxTexture中。
再重写一下DrawBox函数,给他加上3个参数,让他可以在指定位置画箱子,添上纹理
随后,只需要调用void
DrawBox(float bx,float by,float
bz),就能够在指定的位置画箱子了。为了管理方便,再定义一个结构体,用来保存3维坐标。
演员的坐标就用这个结构体来管理。
所以在定义3个全局point3D,在init函数中,给他们个初值。
这个时候,编译运行就能看见,“演员”已经就位了!
(按a和d键可以调整视角)
但是,我们还没有给他“剧本”,所以他们是不会动的!
在这个init()-Update()-Draw()框架中,Update()函数会每分钟执行很多次,Update来负责这个给定剧本工作的。
给定一个静态变量count,用于更新箱子的位置。
现在再编译运行就能看到效果了,这就是简单的3D动画。
附本节全部代码:
作者:plusplus7
日期:2013年3月1日
转载请注明出处
还记得读取纹理那章的内容吧~2D纹理在这里同样是可以使用的。为了方便,我把LoadBitmap函数放到了"bmpLoader.h"中,这样方便调用。
在bmpLoader.h中:
#include <windows.h> #define BITMAP_ID 0x4D42 int LoadBitmap(const char *file) { /*。。。*/ }
具体的函数内容就不写出来了。
在init()函数中,调用boxTexture=LoadBitmap("Box.bmp");把纹理保存到boxTexture中。
再重写一下DrawBox函数,给他加上3个参数,让他可以在指定位置画箱子,添上纹理
void DrawBox(float bx,float by,float bz) { glPushAttrib(GL_CURRENT_BIT); glPushMatrix(); glTranslatef(bx,by,bz); //在指定位置画箱子 glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, boxTexture); //指定纹理 glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glEnd(); glPopMatrix(); glPopAttrib(); glDisable(GL_TEXTURE_2D); }
随后,只需要调用void
DrawBox(float bx,float by,float
bz),就能够在指定的位置画箱子了。为了管理方便,再定义一个结构体,用来保存3维坐标。
演员的坐标就用这个结构体来管理。
所以在定义3个全局point3D,在init函数中,给他们个初值。
struct point3D { double x; double y; double z; }; point3D box[3]; void init() { glClearColor(0.0,0.0,0.0,0.0); glEnable(GL_DEPTH_TEST); setAll(20,1.75,0,0,1.75,0,0,1,0); boxTexture=LoadBitmap("Box.bmp"); box[0].x=-2.0; box[0].y=0.5; box[0].z=0.0; box[1].x=0.0; box[1].y=0.5; box[1].z=0.0; box[2].x=2.0; box[2].y=0.5; box[2].z=0.0; }
这个时候,编译运行就能看见,“演员”已经就位了!
(按a和d键可以调整视角)
但是,我们还没有给他“剧本”,所以他们是不会动的!
在这个init()-Update()-Draw()框架中,Update()函数会每分钟执行很多次,Update来负责这个给定剧本工作的。
void Update() { static int count; if (count >= 0) { box[0].y+=0.02; box[1].y+=0.04; box[2].y+=0.08; } else { box[0].y-=0.02; box[1].y-=0.04; box[2].y-=0.08; } count++; if (count == 100) count=-count; glLoadIdentity(); setLookAt(); glutPostRedisplay(); }
给定一个静态变量count,用于更新箱子的位置。
现在再编译运行就能看到效果了,这就是简单的3D动画。
附本节全部代码:
#include <GL/glut.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <iostream>
#include "bmpLoader.h"
#define PI 3.1415926
int WinWidth,WinHeight;
double posX,posY,posZ,viewX,viewY,viewZ,upX,upY,upZ;
struct point3D
{
double x;
double y;
double z;
};
point3D box[3];
GLint boxTexture;
void setAll(double px,double py,double pz,
double vx,double vy,double vz,
double ux,double uy,double uz)
{
posX=px;
posY=py;
posZ=pz;
viewX=vx;
viewY=vy;
viewZ=vz;
upX=ux;
upY=uy;
upZ=uz;
}
void setLookAt()
{
gluLookAt(posX,posY,posZ,
viewX,viewY,viewZ,
upX,upY,upZ);
}
void setPos(double x,double y,double z)
{
posX=x;
posY=y;
posZ=z;
}
void DrawBox(float bx,float by,float bz)
{
glPushAttrib(GL_CURRENT_BIT);
glPushMatrix();
glTranslatef(bx,by,bz);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, boxTexture);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
glPopMatrix();
glPopAttrib();
glDisable(GL_TEXTURE_2D);
}
void DrawGrid()
{
glPushAttrib(GL_CURRENT_BIT);
glLineWidth(2);
glColor3f(0.0,1.0,1.0);
for (int i=-100; i<=100; i+=10)
{
glBegin(GL_LINES);
glVertex3f(i,0.0f,-100.0f);
glVertex3f(i,0.0f,100.0f);
glEnd();
glBegin(GL_LINES);
glVertex3f(-100.0f,0.0f,i);
glVertex3f(100.0f,0.0f,i);
glEnd();
}
glPopAttrib();
}
void Draw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
DrawBox(box[0].x,box[0].y,box[0].z);
DrawBox(box[1].x,box[1].y,box[1].z);
DrawBox(box[2].x,box[2].y,box[2].z);
DrawGrid();
glutSwapBuffers();
}
void Update() { static int count; if (count >= 0) { box[0].y+=0.02; box[1].y+=0.04; box[2].y+=0.08; } else { box[0].y-=0.02; box[1].y-=0.04; box[2].y-=0.08; } count++; if (count == 100) count=-count; glLoadIdentity(); setLookAt(); glutPostRedisplay(); }void Reshape(int w,int h)
{
WinWidth=w;
WinHeight=h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0,0,w,h);
gluPerspective(45,1.0*w/h,1,1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void init()
{
glClearColor(0.0,0.0,0.0,0.0);
glEnable(GL_DEPTH_TEST);
setAll(20,1.75,0,0,1.75,0,0,1,0);
boxTexture=LoadBitmap("Box.bmp");
box[0].x=-2.0;
box[0].y=0.5;
box[0].z=0.0;
box[1].x=0.0;
box[1].y=0.5;
box[1].z=0.0;
box[2].x=2.0;
box[2].y=0.5;
box[2].z=0.0;
}
void ProcessKeyboard(unsigned char key,int x,int y)
{
static double delta;
if (key == 'a')
{
delta+=0.03;
}
if (key == 'd')
{
delta-=0.03;
}
setPos(20*cos(delta),posY,20*sin(delta));
}
int main(int argc, char *argv[])
{
WinWidth=400;
WinHeight=400;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_RGB | GLUT_DOUBLE);
glutInitWindowPosition(100, 100);
glutInitWindowSize(WinWidth, WinHeight);
glutCreateWindow("HelloOpenGL");
glutReshapeFunc(&Reshape);
glutIdleFunc(&Update);
glutDisplayFunc(&Draw);
glutKeyboardFunc(&ProcessKeyboard);
init();
glutMainLoop();
return 0;
}
作者:plusplus7
日期:2013年3月1日
转载请注明出处
相关文章推荐
- OpenGL织梦之旅【第二章】第2节.实现动画
- WPF 3D:简单的Point3D和Vector3D动画创造一个旋转的正方体
- 学习OpenGL(二)应用OpenGL和GLUT制作简单动画
- OpenGL织梦之旅【第四章】编写一个自己的小剧场
- Android 简单的3D动画效果
- 一种简单有效的3D模型的动画多线程方案
- Android动画 —— 十几行代码的简单3D旋转动画
- 简单的阐述CoreAnimation中的3D动画
- OpenGL 鼠标3D旋转简单实现
- 第三部分:Android 应用程序接口指南---第四节:动画和图形---第四章 OpenGL
- Animation简单的3D动画旋转
- 一种简单有效的3D模型的动画多线程方案
- 第四个程序opengl简单的动画效果。
- WPF 3D:简单的Point3D和Vector3D动画创造一个旋转的正方体
- OpenGL织梦之旅【第四章】第1节.设置视点函数gluLookAt
- 一种简单有效的3D模型的动画多线程方案
- 【Android开发小记--7】动画--简单的button移动和图片3D翻转
- 一种简单有效的3D模型的动画多线程方案
- mac上学用opengl(4)-画一个简单的动画
- 【Qt OpenGL】Qt Creator中的3D绘图及动画教程