程序员爱装B

写装A程序 做装C的事情

[搬家文] 第六课 小结-part_1

原文地址:http://www.videotutorialsrock.com/opengl_tutorial/cube/home.php

视频下载:http://www.videotutorialsrock.com/opengl_tutorial/cube/video.flv

文本:http://www.videotutorialsrock.com/opengl_tutorial/cube/text.php

源码下载:http://www.videotutorialsrock.com/opengl_tutorial/cube/cube.zip

译文:

    我们已经学习了不少东西。现在我们简单的回顾一下前几课学习的东西,确保我们了解所有的知识。你也可以跳过这一课,但你也许想巩固下我们所学的知识。

    既然我们这么喜爱旋转的物体,我们想使一个旋转的立方体两边都有纹理,颜色,和过渡色。


    现在来看下源码。我们将简要的解释所有的代码(除了顶部的注释)。

#include <iostream>
#include <stdlib.h>

#ifdef __APPLE__
#include <OpenGL/OpenGL.h>
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif

#include "imageloader.h"

using namespace
std;

    包含的头文件,另外,我们在我们的main.cpp文件顶部使用using namespace std。

const float BOX_SIZE = 7.0f; //The length of each side of the cube
float _angle; //The rotation of the box
GLuint _textureId; //The OpenGL id of the texture

    BOX_SIZE是一个保存箱子每个边长度的变量。_angle保存当前箱子旋转的角度。_textureId是我们在两个面上使用纹理的id。

void handleKeypress(unsigned char key, int x, int y) {
switch
(key) {
case
27: //Escape key
exit(0);
}
}

    处理按键事件,当用户按下escape键时推出程序。

//Makes the image into a texture, and returns the id of the texture
GLuint loadTexture(Image *image) {
GLuint textureId;
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glTexImage2D(GL_TEXTURE_2D,
0
,
GL_RGB,
image->width, image->height,
0
,
GL_RGB,
GL_UNSIGNED_BYTE,
image->pixels);
return
textureId;
}

    从一个Image对象中载入一个纹理。

void initRendering() {
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);

Image *image = loadBMP("vtr.bmp");
_textureId = loadTexture(image);
delete
image;
}

    初始化渲染函数。使用depth test,颜色,光照,光源等模式。然后我们将一个vtr.bmp文件载入一个Image对象,并将其作为一个纹理加载入OpenGL,并删除Image对象,因为我们不在需要它。

void handleResize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (float)w / (float)h, 1.0, 200.0);
}

    处理窗口变化大小的函数,在不同的程序中这个函数并没有怎么变化。

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

    drawScene是绘画3D场景的函数。首先总是调用glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)清楚上次画图的信息。

    glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

    我们切换为普通的转换模式,重置变换这样我们就处于原点并面向z轴的负方向。

    glTranslatef(0.0f, 0.0f, -20.0f);

    我们向前移动20个单位,这样我们的立方体就在镜头前面20个单位。

    GLfloat ambientLight[] = {0.3f, 0.3f, 0.3f, 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);

    我们设置场景的背景光(环境光),每个点强度为0.3。

    GLfloat lightColor[] = {0.7f, 0.7f, 0.7f, 1.0f};
GLfloat lightPos[] = {-2 * BOX_SIZE, BOX_SIZE, 4 * BOX_SIZE, 1.0f};
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);

    我们在相对立方体中心(-2*BOX_SIZE,BOX_SIZE,4*BOX_SIZE)的地方放置强度为0.7的光源。

    glRotatef(-_angle, 1.0f, 1.0f, 0.0f);

    我们将物体围绕向量(1,1,0)以当前角度旋转,这样就产生立方体的旋转动作。

    glBegin(GL_QUADS);

//Top face
glColor3f(1.0f, 1.0f, 0.0f);
glNormal3f(0.0, 1.0f, 0.0f);
glVertex3f(-BOX_SIZE / 2, BOX_SIZE / 2, -BOX_SIZE / 2);
glVertex3f(-BOX_SIZE / 2, BOX_SIZE / 2, BOX_SIZE / 2);
glVertex3f(BOX_SIZE / 2, BOX_SIZE / 2, BOX_SIZE / 2);
glVertex3f(BOX_SIZE / 2, BOX_SIZE / 2, -BOX_SIZE / 2);

//Bottom face
glColor3f(1.0f, 0.0f, 1.0f);
glNormal3f(0.0, -1.0f, 0.0f);
glVertex3f(-BOX_SIZE / 2, -BOX_SIZE / 2, -BOX_SIZE / 2);
glVertex3f(BOX_SIZE / 2, -BOX_SIZE / 2, -BOX_SIZE / 2);
glVertex3f(BOX_SIZE / 2, -BOX_SIZE / 2, BOX_SIZE / 2);
glVertex3f(-BOX_SIZE / 2, -BOX_SIZE / 2, BOX_SIZE / 2);

    我们绘制顶部和底部面,使用固定的颜色。在使用glVertex3f指定每个面的坐标之前,我们需要设定他们的颜色和法向量(模为1)。

posted on 2010-07-19 20:26 camel 阅读(101) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2010年11月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

统计

常用链接

留言簿

随笔档案

文章档案

搜索

最新评论

阅读排行榜

评论排行榜