OpenGL 教程 —— 一个在线教育工具.doc
武汉科技大学本科毕业论文外文翻译本科毕业论文外文翻译外文译文题目:OpenGL教程 一个在线教育工具学 院:计算机科学与技术专 业:计算机科学与技术(电)学 号:201312237035学生姓名: 指导教师: 日 期:二一七年六月OpenGL Tutorial - An Online Education ToolHarish MuseboyinaOpenGL Tutorial - An Online Education tool, Harish Museboyina. Montana State University, 2012OpenGL 教程 一个在线教育工具哈里斯·穆塞博伊纳OpenGL 教程 一个在线教育工具,哈里斯·穆塞博伊纳蒙大拿州立大学,20121 简单光源(无材质效果)1.1 代码举例下面的代码是用来产生一束简单的光照,它又被投射到一个球体上。由于这是第一个光照实例,因此我们现在并不关注材质效果,这将在下一节再进行描述。OpenGL的实现需要至少8个主要灯光从GL_LIGHT0到GL_LIGHT7。为了能在代码中使用光照,我们必须首先通过调用程序glEnable(GL_LIGHTING)来开启光照。glLookAt()程序用来设置相机位置,我们可以使用glLightfv()来设置光照的位置。这个程序实际是用来设置光照的方向,而并不是光照的实际位置。虽然我们好像能够将光源设置在一个位置,但它实际表现出来反而像在无限远处。#include "stdafx.h"#include <GL/glut.h>static double yVal = 50.0;void drawSphere()GLUquadricObj* cyl;GLfloat light_position = 0.0, 20.0, yVal, 10.0 ;glLightfv(GL_LIGHT0, GL_POSITION, light_position); / Using lighting (effects all the objects drawn below)glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(35.0, 1.0, 1.0, 100.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(20.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);cyl = gluNewQuadric();gluQuadricDrawStyle(cyl, GLU_FILL);gluSphere(cyl, 2.0, 50, 100);glFlush();void display(void)/* clear all pixels */glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);drawSphere();glFlush();void init(void)glClearColor(0.5, 0.5, 0.5, 0.0);glEnable(GL_DEPTH_TEST);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluLookAt(30.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);void keyboard(unsigned char key, int x, int y)switch (key)case 27:/ "esc" on keyboardexit(0);break;case 97:/ "a" on keyboardyVal = yVal - 5.0;glutPostRedisplay();break;int main(int argc, char* argv)glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowSize(600, 600);glutInitWindowPosition(100, 100);glutCreateWindow("Simple Light.");init();glutDisplayFunc(display);glutKeyboardFunc(keyboard);glutMainLoop();return 0;1.2 输出1.3 使用的关键方法void glLightfv(GLenum light, GLenum pname, const GLfloat *params)2 光照(材质效果)2.1 材质材质参数指定表面如何反射光。应用可以更改OpenGL的材质参数用以模拟不同颜色的材料、光泽平坦的材料、高光泽材料如泳池球等。程序glColor3f()用来设置原色,只要我们不使用光照效果,调用这个程序就是个好方法。OpenGL的光照不会使用原色,而是使用材料颜色。因此在谈论光照时介绍材料是很重要的。2.2 代码举例到目前为止,我们已经看到了一个没有物质影响的简单照明示例。但是,为了使场景更具吸引力,我们必须利用材料。在下面的代码中,我们就使用了一个绿色的材料。我们根据实际要求使用GL_SPECULAR, GL_AMBIENT, GL_SHININESS等参数。相同的参数也适用于照明方法。#include "stdafx.h"#include <GL/glut.h>static double yVal = 50.0;void drawSphere()GLUquadricObj* cyl;GLfloat light_position = 0.0, 40.0, yVal, 0.0 ;glLightfv(GL_LIGHT0, GL_POSITION, light_position);GLfloat mat_specular = 0.3f, 1.0f, 0.3f, 1.0f ; / Green color materialGLfloat mat_shininess = 70.0 ; / Defines shininessglMaterialfv(GL_FLOAT, GL_SPECULAR, mat_specular);/ Using materialsglMaterialfv(GL_FRONT, GL_AMBIENT, mat_specular);glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(35.0, 1.0, 1.0, 100.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(30.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);cyl = gluNewQuadric();gluQuadricDrawStyle(cyl, GLU_FILL);gluSphere(cyl, 2.0, 10, 10);glFlush();void display(void)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);drawSphere();glFlush();void init(void)glClearColor(0.5, 0.5, 0.5, 0.0);glEnable(GL_DEPTH_TEST); / enabling z-bufferglMatrixMode(GL_PROJECTION);glLoadIdentity();gluLookAt(30.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);void keyboard(unsigned char key, int x, int y)switch (key)case 27:/ "esc" on keyboardexit(0);break;case 97:/ "a" on keyboardyVal = yVal - 5.0;glutPostRedisplay();break;int main(int argc, char* argv)glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowSize(600, 600);glutInitWindowPosition(100, 100);glutCreateWindow("Light Material effect.");init();glutDisplayFunc(display);glutKeyboardFunc(keyboard);glutMainLoop();return 0;2.3 输出2.4 不同的材料3 点光源到目前为止,我们已经看到了具有以下属性的照明效果:l 光线是从无线远的距离投射出来的。l 圆周上亮度的消失速度是非常慢的。但是,我们可能想要生成的灯光,它们在场景中与一个位置,而并不会像我们迄今为止看到的普通光照一样,从一个无限远的光源投影出来。就像一盏书房台灯或是台球桌上的点光源等。对于点光源,它发射的射线被限制在一个锥形区域内,在锥形区域外,点光源不会发射光线。因此,为了是普通光源表现得像一个点光源,我们必须对代码进行一些修改。3.1 代码举例对以下代码的修改是为了引入诸如GL_SPOT_CUTOFF的参数,该参数定义了以点光源放置的地方为中心发射光线形成的椎体的角度。GL_SPOT_EXPONENT参数则定义了光的集中程度。#include "stdafx.h"#include <GL/glut.h>static double yVal = 1.0;int spot(double a, double b, double c, double d, double e, double f)/*a, b and c - x, y and z co-ordinates for light positiond, e and f - x, y and z co-ordinates for spot light position*/GLfloat mat_specular = 0.3, 1.0, 0.3, 1.0 ;GLfloat mat_shininess = 50.0 ;GLfloat light_position = a, b, c, 1.0 ;GLfloat spotDir = d, e, f ;glClearColor(0.5, 0.5, 0.5, 0.0);glShadeModel(GL_SMOOTH);glLightfv(GL_LIGHT0, GL_SPECULAR, mat_specular);glLightfv(GL_LIGHT0, GL_POSITION, light_position);glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);/ Defining spotlight attributesglLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 95.0);glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 2.0);glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spotDir);glEnable(GL_COLOR_MATERIAL);glEnable(GL_DEPTH_TEST);return 0;void drawSphere()GLUquadricObj* cyl;glClearColor(0.5, 0.5, 0.5, 0.5);GLfloat light_position = 50.0, 50.0, 0.0, 1.0 ;GLfloat mat_specular = 0.3, 0.3, 1.0, 1.0 ;GLfloat mat_shininess = 100.0 ; GLfloat spotDir = 50.0, 30.0, 0.0 ;glShadeModel(GL_SMOOTH);spot(yVal, 5.0, 1.5, 10.0, 1.0, 10.0);glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(35.0, 1.0, 1.0, 100.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(30.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);cyl = gluNewQuadric();gluQuadricDrawStyle(cyl, GLU_FILL);glPopMatrix();glFlush();void display(void)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);drawSphere();glFlush();void init(void)glClearColor(0.5, 0.5, 0.5, 0.0);glEnable(GL_DEPTH_TEST); / enabling z-buffer/* initialize viewing values */glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(35.0, 1.0, 1.0, 100.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(30.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);void keyboard(unsigned char key, int x, int y)switch (key)case 27:/ "esc" on keyboardexit(0);break;case 97:/ "a" on keyboardyVal = yVal - 5.0;glutPostRedisplay();break;int main(int argc, char* argv)glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowSize(600, 600);glutInitWindowPosition(100, 100);glutCreateWindow("Spot Light.");init();glutDisplayFunc(display);glutKeyboardFunc(keyboard);glutMainLoop();return 0;3.2 输出4 多种光源为了使场景看起来更好,我们必须利用多个灯光。所以,这些灯在3D空间内都有它们自己的位置和照明效果。4.1 代码举例在下面的代码中,我们在单个光源和多个光源之间切换。因为我们在这里将使用多个光源,所以我们必须启用我们打算在代码中使用的光源数量。该代码启用了两个光源GL_LIGHT0和GL_LIGHT1。我们启用/禁用每个光源以进行切换效果。#include "stdafx.h"#include <GL/glut.h>int change = 0;void drawSphere()float mat_specular = 0.3, 1.0, 0.3, 1.0 ;float mat_shininess = 100.0 ;float mat_surface = 1.0, 1.0, 0.0, 0.0 ;float blue_light = 0.0, 0.0, 1.0, 1.0 ;float red_light = 1.0, 0.0, 0.0, 1.0 ;float light_position0 = 0.0, 40.0, 50.0, 0.0 ;float light_position1 = 0.0, 40.0, -50.0, 0.0 ;glClearColor(0.5, 0.5, 0.5, 0.0);glShadeModel(GL_SMOOTH);glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);glMaterialfv(GL_FRONT, GL_AMBIENT, mat_surface);glLightfv(GL_LIGHT1, GL_POSITION, light_position0);glLightfv(GL_LIGHT0, GL_DIFFUSE, blue_light);glLightfv(GL_LIGHT1, GL_POSITION, light_position1);glLightfv(GL_LIGHT1, GL_DIFFUSE, red_light);if (change)glDisable(GL_LIGHT1);elseglEnable(GL_LIGHT1);glutSolidTeapot(0.80);glFlush();void display(void)/* clear all pixels */glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);drawSphere();glFlush();void init(void)/* select clearing color */glClearColor(0.5, 0.5, 0.5, 0.0);glEnable(GL_DEPTH_TEST); / enabling z-buffer/* initialize viewing values */glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(35.0, 1.0, 1.0, 100.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(6.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);/ Defining two lights for multiple light effectsglEnable(GL_LIGHT0);glEnable(GL_LIGHT1);void keyboard(unsigned char key, int x, int y)switch (key)case 27:/ "esc" on keyboardexit(0);break;case 97:/ "a" on keyboardchange = 1 - change;glutPostRedisplay();break;int main(int argc, char* argv)glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowSize(600, 600);glutInitWindowPosition(100, 100);glutCreateWindow("Mult Lights.");init();glutDisplayFunc(display);glutKeyboardFunc(keyboard);glutMainLoop();return 0;4.2 输出19