OpenGL上机报告
- 格式:doc
- 大小:527.00 KB
- 文档页数:16
计算机图形学实验报告姓名:学号:班级:目录实验一OpenGL程序结构练习 (3)实验二基本图形生成 (6)实验三交互式控制 (9)实验四图形基本变换 (12)实验五三维图形生成及显示 (15)实验六三维图形生成及显示 (19)实验一OpenGL程序结构练习【实验目的】1.熟悉C语言环境下OpenGL的使用方法;2.了解OpenGL程序的基本结构。
【实验原理】绝大多数OpenGL程序具有类似的结构,包含下述函数main():定义回调函数,打开一个或多个具有指定属性的窗口,进入事件循环(最后一条可执行语句)init():设置状态变量、视图、属性、回调、显示函数、输入和窗口函数#include <GL/glut.h> // glut.h includes gl.h and glu.hvoid display(){ ……}void init(){ ……}int main( intargc, char **argv){ ……}【实验内容】1.了解程序中各个结构的功能;2.用OpenGL生成三角形。
【实验步骤及结果】1.导入OpenGL的glut32.lib和glut.h文件:将.lib文件存放到C 语言程序文件夹的Library下,.h文件放到Include下;导入应用程序扩展文件glut32.dll,存放到system文件夹下。
2.打开VC 6.0,新建工程,并命名为text1,如图1.图 13.在工程text1下新建源文件,并命名为text1.cpp。
4.编写代码并编译链接,如图2所示。
图 25.运行,结果如图3所示。
图 3实验二基本图形生成【实验目的】1.熟悉OpenGL的程序结构,并了解各部分的功能。
2.学会应用OpenGL语言绘制出点,线,多边形。
【实验原理】1.GLUT函数glutInit使得应用程序可以获取命令行参数并初始化系统。
glutInitDisplayMode设置窗口的属性、RGB颜色、单缓冲区、属性按照逻辑或组合在一起。
上机实验报告篇1用户名se××××学号姓名学院①实验名称:②实验目的:③算法描述(可用文字描述,也可用流程图):④源代码:(.c的文件)⑤用户屏幕(即程序运行时出现在机器上的画面):2.对c文件的要求:程序应具有以下特点:a可读性:有注释。
b交互性:有输入提示。
c结构化程序设计风格:分层缩进、隔行书写。
3.上交时间:12月26日下午1点-6点,工程设计中心三楼教学组。
请注意:过时不候哟!四、实验报告内容0.顺序表的插入。
1.顺序表的删除。
2.带头结点的单链表的\'插入。
3.带头结点的单链表的删除。
注意:1.每个人只需在实验报告中完成上述4个项目中的一个,具体安排为:将自己的序号对4求余,得到的数即为应完成的项目的序号。
例如:序号为85的同学,85%4=1,即在实验报告中应完成顺序表的删除。
2.实验报告中的源代码应是通过编译链接即可运行的。
3.提交到个人空间中的内容应是上机实验中的全部内容。
上机实验报告篇2一、《软件技术基础》上机实验内容1.顺序表的建立、插入、删除。
2.带头结点的单链表的建立(用尾插法)、插入、删除。
二、提交到个人10m硬盘空间的内容及截止时间1.分别建立二个文件夹,取名为顺序表和单链表。
2.在这二个文件夹中,分别存放上述二个实验的相关文件。
每个文件夹中应有三个文件(.c文件、.obj文件和.exe文件)。
3. 截止时间:12月28日(18周周日)晚上关机时为止,届时服务器将关闭。
三、实验报告要求及上交时间(用a4纸打印)1.格式:《计算机软件技术基础》上机实验报告用户名se××××学号姓名学院①实验名称:②实验目的:③算法描述(可用文字描述,也可用流程图):④源代码:(.c的文件)⑤用户屏幕(即程序运行时出现在机器上的画面):2.对c文件的要求:程序应具有以下特点:a 可读性:有注释。
b 交互性:有输入提示。
实验报告学生姓名:学号:专业班级:实验类型:□验证□综合□设计□创新实验日期:2018.11 实验成绩:一、实验名称实验三着色器编程二、实验内容1.利用OpenGL的顶点数组对象、顶点缓冲对象和索引缓冲对象组织图元数据,设置图元属性,进行核心模式的图元渲染。
2.编写顶点着色器、片段着色器代码,进行代码的编译和链接形成着色器程序,采用核心模式绘制OpenGL几何图元。
3.采用文件形式保存着色器代码,编写着色器类,在着色器类中实现着色器代码的加载、编译和链接。
三、实验目的1.掌握顶点数组对象、顶点缓冲对象和索引缓冲对象的创建、数据缓存、属性设置和绑定方法。
2.掌握顶点着色器和片段着色器的定义、代码加载、程序编译方法,着色器程序的定义、链接和使用方法。
3.掌握如何采用面向对象方法封装着色器的代码加载、程序编译方法和链接方法。
四、实验步骤1.新建项目OPengl02,在项目下添加opengl02.cpp文件和glad.c文件;2.在opengl02.cpp文件中,添加代码:(1)定义几何图元的顶点数据和索引数据GLfloat vertices[] = {0.5f, 0.5f, 0.0f, // Top Right0.5f, -0.5f, 0.0f, // Bottom Right-0.5f, -0.5f, 0.0f, // Bottom Left-0.5f, 0.5f, 0.0f // Top Left};GLuint indices[] = { // Note that we start from 0!0, 1, 3, // First Triangle1, 2, 3 // Second Triangle};(2)创建顶点数组对象、顶点缓冲对象和索引缓冲对象,绑定相关对象,缓存数据、设置顶点属性。
GLuint VBO, VAO, EBO;glGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);glGenBuffers(1, &EBO);// Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s).glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);glEnableVertexAttribArray(0);glBindBuffer(GL_ARRAY_BUFFER, 0);// Note that this is allowed, the call to glVertexAttribPointer registered VBO as thecurrently bound vertex buffer object so afterwards we can safely unbindglBindVertexArray(0);// Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs), remember: do NOT unbind the EBO, keep it bound to this VAO(3)编写顶点着色器、片段着色器代码。
目录1 OpenGL的基本框架1.1 OpenGL简介 (1)1.2 OpenGL的工作方式 (2)1.3 OpenGL的操作步骤 (3)1.4 OpenGL的组成 (3)1.5 OpenGL的数据类型 (4)1.6 OpenGL函数命名约定 (4)1.7 用OpenGL绘制图形 (4)1.8 用OpenGL制作动画 (9)2 图形的绘制2.1 空间点的绘制 (13)2.2 直线的绘制 (14)2.3多边形面的绘制 (18)2.4平面多面体的绘制 (24)3 图形变换3.1OpenGL中的变换 (30)3.2模型视图矩阵 (31)3.3 矩阵堆栈 (35)4 OpenGL中的颜色、光照和材质4.1 颜色 (42)4.2 光照模型 (42)4.3 材质属性 (43)4.4 使用光照 (43)4.5 使用光源 (48)附录:参考函数1.1 颜色使用 (58)1.2 绘制几何图元 (59)1.3 坐标转换 (63)1.4 堆栈操作 (66)1.5 使用光照和材质 (68)1.6 帧缓存操作 (72)1.7 查询函数 (72)1.8 窗口初始化和启动事件处理 (75)1.9 窗口管理 (77)1.10 菜单管理 (80)1.11 注册回调函数 (82)1.12 几何图形绘制 (84)1OpenGL的基本框架1.1OpenGL简介在计算机发展初期,人们就开始从事计算机图形的开发,但直到20世纪80年代末90年代初,三维图形才开始迅速发展。
于是各种三维图形工具软件包相继推出,如GL,RenderMan等,但没有一种软件包能够在三维图形建模能力和编程方便程度上与OpenGL相比拟。
OpenGL(Open Graphics Library,开放图形库),是一个三维的计算机图形和模型库,它源于SGI公司为其图形工作站开发的IRIS GL,在跨平台移植过程中发展成为OpenGL。
SGI公司在1992年6月发布1.0版,后成为工业标准。
Opengl实验报告及源代码实验七模型加载实验报告学⽣姓名:学号:专业班级:实验类型:□验证□综合□设计□创新实验⽇期:2018.11 实验成绩:⼀、实验名称实验七模型加载⼆、实验内容1.设计并实现Mesh类,利⽤该类实现模型⽹格的解析、加载、管理与渲染。
2.设计并实现Model类,利⽤该类实现⼏何模型的解析、加载、管理与渲染。
3.基于Mesh类和Model类,利⽤Assimp模型加载库,加载并渲染三维⼏何模型。
三、实验⽬的1.掌握3D模型⽹格数据的组织与渲染⽅法。
2.掌握3D模型数据的结构与组织,以及模型数据的解析与渲染⽅法。
3.了解Assimp库中管理3D模型的数据结构,掌握Assimp库的使⽤⽅法。
四、实验步骤1.定义⽹格类结构,并初始化class Mesh{Public:vector vertices;vector indices;vector textures;Mesh(vector vertices, vector indices, vector texture);Void Draw(Shader shader);private:GLuint VAO, VBO, EBO;void setupMesh();}void setupMesh(){glGenVertexArrays(1, &this->VAO);glGenBuffers(1, &this->VBO);glGenBuffers(1, &this->EBO);glBindVertexArray(this->VAO);glBindBuffer(GL_ARRAY_BUFFER, this->VBO);glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(Vertex),&this->vertices[0], GL_STATIC_DRAW);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->indices.size() * sizeof(GLuint), &this->indices[0], GL_STATIC_DRAW);// 设置顶点坐标指针glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),(GLvoid*)0);// 设置法线指针glEnableVertexAttribArray(1);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),(GLvoid*)offsetof(Vertex, Normal));// 设置顶点的纹理坐标glEnableVertexAttribArray(2);glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),(GLvoid*)offsetof(Vertex, TexCoords));glBindVertexArray(0);}2.定义⽤于渲染的函数:void Draw(Shader shader){GLuint diffuseNr = 1;GLuint specularNr = 1;for(GLuint i = 0; i < this->textures.size(); i++){glActiveTexture(GL_TEXTURE0 + i); // 在绑定纹理前需要激活适当的纹理单元// 检索纹理序列号(N in diffuse_textureN)stringstream ss;string number;string name = this->textures[i].type;if(name == "texture_diffuse")ss << diffuseNr++; // 将GLuin输⼊到string streamelse if(name == "texture_specular")ss << specularNr++; // 将GLuin输⼊到string streamnumber = ss.str();glUniform1f(glGetUniformLocation(shader.Program, ("material." + name + number).c_str()), i); glBindTexture(GL_TEXTURE_2D, this->textures[i].id);}glActiveTexture(GL_TEXTURE0);// 绘制MeshglBindVertexArray(this->VAO);glDrawElements(GL_TRIANGLES, this->indices.size(), GL_UNSIGNED_INT, 0); glBindVertexArray(0);3.编写顶点着⾊器和⽚段着⾊器的代码:#version 330 corelayout(location = 0) in vec3 position;layout(location = 1) in vec3 normal;layout(location = 2) in vec2 texCoords;out vec2 TexCoords;uniform mat4 model;uniform mat4 view;uniform mat4 projection;void main(){gl_Position = projection * view * model * vec4(position, 1.0f);TexCoords = texCoords;}#version 330 corein vec2 TexCoords;out vec4 color;uniform sampler2D texture_diffuse1;void main(){color = vec4(texture(texture_diffuse1, TexCoords));}4.把3D模型导⼊OpenGL:void loadModel(string path){Assimp::Importer import;const aiScene* scene = import.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs);if(!scene || scene->mFlags == AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {cout << "ERROR::ASSIMP::" << import.GetErrorString() << endl;return;}this->directory = path.substr(0, path.find_last_of('/'));this->processNode(scene->mRootNode, scene);}void processNode(aiNode* node, const aiScene* scene){// 添加当前节点中的所有Meshfor(GLuint i = 0; i < node->mNumMeshes; i++){aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];this->meshes.push_back(this->processMesh(mesh, scene));}// 递归处理该节点的⼦孙节点for(GLuint i = 0; i < node->mNumChildren; i++){this->processNode(node->mChildren[i], scene);}}5.优化:vector loadMaterialTextures(aiMaterial* mat, aiTextureType type, string typeName) { vector textures;for(GLuint i = 0; i < mat->GetTextureCount(type); i++){aiString str;mat->GetTexture(type, i, &str);GLboolean skip = false;for(GLuint j = 0; j < textures_loaded.size(); j++){if(textures_loaded[j].path == str){textures.push_back(textures_loaded[j]);skip = true;break;}}if(!skip){ // 如果纹理没有被加载过,加载之Texture texture;texture.id = TextureFromFile(str.C_Str(), this->directory);texture.type = typeName;texture.path = str;textures.push_back(texture);this->textures_loaded.push_back(texture); // 添加到纹理列表textures}}return textures;}五、实验结果六、实验体会这次实验是做模型加载,在之前的实验中,我们通过在程序中指定的⽴⽅体数据,绘制⽴⽅体,看起来还是很乏味。
opengl总结报告一.OpenGL是做什么的一种图形硬件的接口。
而不是像C和C++一样的编程语言,更像是一个运行库,提供一些预先封装的函数。
二.OpenGL的主要功能是什么建模,变换,颜色模式设置,光照和材质设置,纹理映射,位图显示和图像。
三.OpenGL的体系结构是什么最底层为图形硬件,第二层为操作系统,第三层为窗口系统,第四层为OpenGL,第五层为应用软件。
四.怎么样利用OpenGL来实现我们想要做的事情首先要明白一点,OpenGL是一个与平台无关的三维图形接口,操作系统必须提供像素格式管理和渲染环境管理。
因此要使用OpenGL来做我们想做的事情的时候,一定要先为OpenGL搭建一个窗口环境。
在这个窗口环境中,我们才能够使用OpenGL来实现我们自己的目的。
另外要注意的是OpenGL应用的不是保留模式,而是直接模式。
即我们去操作的并非是已经封装好的一些建好的图形信息,而仅是相当于操作一个图形界面。
也就是说如果我们要画一个复杂的形体,我们要把这个形体的几何信息,包括点、线和面的一些信息包括进去,然后使用一定的方法,把这些基本的信息合起来,构成我们要创建的那个物体。
五.绘制图元能干什么此处我们当明白,OpenGL能够绘制复杂和有趣的图形,但这些图形都是由几个为数不多的基本图形元素构建而成的。
所以,能够绘制图元是我们构建一个复杂有趣图形的一个基础。
这些基本的图元,包括点、线和面。
六.变换能干什么当我们绘制出一个复杂或者简单图形的时候,我们要把这个图形显示到我们的电脑屏幕上。
这个时候我们可能会需要用到变换,变换的目的是让我们能够从一个合适的角度,观察到我们对图形中所关注的那部分。
变换包括,视图变换,模型变换,投影变换。
经过这几个变换中的一个变换、几个变换或者几种变换的相互组合,我们可以得到我们想要达到的效果。
七.光照能干什么我们绘制图形的时候要深切地知道一个事情。
那就是我们做出的图形可能需要有3D效果,或者说需要让我们做出来的模型更加的`有立体感,并和实际的物体尽量的接近。
目录实验一中点算法 (2)一、实验目的和要求 (2)二、主要算法描述 (2)三、代码实现 (4)四、实验结果 (7)实验二Bezier曲线画茶壶 (11)一、实验目的和要求 (11)二、主要算法描述 (11)三、代码实现 (12)四、实验结果 (15)心得体会: (16)实验一 中点算法一、实验目的和要求学习使用OpenGL ,初步了解基本的OpenGL 编程方法。
熟练掌握中点算法,知道如何运用中点算法编程绘制直线、椭圆和圆。
编制中点画圆程序,上机实现在给定条件下下用中点算法画出圆形。
二、主要算法描述试验设计思路:圆是一个八分对称的图形,因此在计算圆上像素点的坐标时,可以只计算八分之一个圆,再依照对称原理算出其他七段的像素点(如下图)。
设圆方程的隐函数表示为 类似于中点法绘制直线的原理,我们将平面点划分为圆内和圆外(如下图):圆弧外的点:F(X ,Y)>0;圆弧内的点:F(X ,Y)<0;),(222=-+=R y x y x F假设在),(i i y x 绘制了一个像素,则下一步必须确定像素位置是),1(i i y x +还是)1,1(-+i i y x 更接近圆。
一次由两个点的中点决定,若中点)21,1(-+i i y x 在圆内,则说明)1,1(-+i i y x 更接近圆,否则说明),1(i i y x +更接近圆(如下图)。
为了在计算中避开计算圆的方程时会遇到的平方与开方,故运用迭代方法由式1211++=++i i i x p p 与111212+++-++=i i i i y x p p 计算决定参数。
试验编程思路:1. 输入圆半径r 和圆心),(c c y x ,并得到圆周(圆心在原点)上的第一个点:),0(),(00r y x =2. 计算决策参数的初值:r p -=103. 在每个k x 位置,从0=k 开始,完成下列测试:加入0<k p ,圆心在原点的下一个点位),(1k k y x +,并且1211++=++k k k x p p否则,圆的下一个点是)1,1(-+k k y x ,并且111212+++-++=k k k k y x p p其中11+=+k k x x 且11-=+k k y y4.确定其他七个八分圆中的对称点。
OPENGL计算机动画设计报告学院名称:贵大明德学院专业:计算机科学与技术班级:计科09151姓名:陈胜指导教师:班建兴摘要:软件工程专业经过两年的课程学习,已经积累了相关高级语言程序设计的基本知识。
画出圆柱面并使之颜色、角度改变,这一题目考察了程序设计自顶而下、逐步细化的相关基本思想。
题目难点在于实现可视化界面的交互、以及图像的旋转过程。
分析题目可以得出程序可以大致分为两个方面的内容:1.画出一个圆柱面。
2.使圆柱面可以实现颜色、角度的改变。
经过查找相关资料,本程序采用功能强大的图形库OPENGL并调用一系列WINDOWS API采用C/C++语言在Microsoft Visual C++6.0环境下编写。
很好的解决了用C/C++编写图形界面的难点问题。
关键词:正方体;旋转;可视化;OPENGL1.1引言随着专业课程学习的深入,相关高级语言程序设计的知识已经有所积累,如何更好的掌握并应用已经成为当务之急。
通过软件工程课程设计的过程能够学习程序设计的基本思想以及整体流程。
基本高级语言程序设计以及相关专业基础课程已经学习完毕,在学习过程中遇到的一些难点问题,为了综合以前学过的课程知识并融会贯通。
可以通过课程设计的独立完成来通过相关途径解决,从而能够更好的掌握程序设计的思想,提升编程能力。
2.1设计简介为了实现本程序的功能,计划采用OPENGL图形库并调用一系列WINDOWS API 采用C/C++语言编写。
首先,应熟悉OPENGL在WIN32平台下的相关API,以及其余WINDOWS窗口交互的相关接口方法,来构建窗口的内容。
其次,熟悉了解OPENGL库函数在窗体中实现绘图(既绘制圆柱面),实现圆柱面颜色、角度功能的相关函数。
最后,实现OPENGL与WINDOWS的交互的过程,完成程序及注释。
2.2 OPENGL基本结构OpenGL 程序的基本结构可分为三个部分:第一部分是初始化部分,主要是设置一些OpenGL 的状态开关,如颜色模式(RGBA 或ALPHA 等)的选择,是否作光照处理(若有的话,还需设置光源的特性),深度检验,裁剪等等。
实验1,opengl的基本语法实验报告心得体会实验1,opengl的基本语法实验报告心得体会篇一:图形学实验报告openGL的基本语法《计算机图形学基础》实验1 OpenGL的基本语法一、实验目的及要求1. 了解OpenGL的主要功能2. 了解OpenGL的绘制流程3. 掌握OpenGL的基本语法4. 通过以上内容,掌握 OpenGL的编程框架,实现简单的图形绘制二、实验环境主要是软件开发环境:VC三、实验内容OpenGL绘制矩形的简单例子。
四、实验结果五、程序代码#includevoid Initial(void){}void Display(void){glClear(GL_COLOR_BUFFER_BIT); //用当前背景色填充窗口glColor3f(, , );//设置当前的绘图颜色为红色glRectf(, , , ); //绘制一个矩形glFlush();//处理所有的OpenGL程序}int main(int argc, char* argv[]){glutInit(&argc, argv); glutInitDisplayMo(转载于: 小龙文档网:实验1,opengl的基本语法实验报告心得体会)de(GLUT_SINGLE | GLUT_RGB); //初始化glClearColor(, , , ); //设置窗口背景颜色为白色glMatrixMode(GL_PROJECTION);//设置投影参数gluOrtho2D(,,,); 窗口的显示模式glutInitWindowSize(400,300); //设置窗口的尺寸glutInitWindowPosition(100,120); //设置窗口的位置}glutCreateWindow("矩形"); //创建一个名为矩形的窗口glutDisplayFunc(Display); //设置当前窗口的显示回调函数Initial(); //完成窗口初始化glutMainLoop(); //启动主GLUT事件处理循环return 0;六、心得体会。
《高级计算机图形学》实验报告姓名:学号:班级:【实验报告要求】实验名称:高级计算机图形学室内场景实验目的:掌握使用OpenGL生成真实感复杂对象的方法,进一步熟练掌握构造实体几何表示法、扫描表示法、八叉树法、BSP树法等建模方法。
实验要求:要求利用OpenGL生成一个真实感的复杂对象及其周围场景,并显示观测点变化时的几何变换,要具备在一个纹理复杂的场景中漫游功能。
要求使用到光线跟踪算法、纹理映射技术以及实时绘制技术。
一、实验效果图图1:正面效果图图2:背面效果图图4:背面效果图图4:室内场景细节效果图图5:场景角度转换效果图二、源文件数据代码:共6个文件,其实现代码如下:1、DlgAbout.cpp#include "StdAfx.h"#include "DlgAbout.h"CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) {}void CAboutDlg::DoDataExchange(CDataExchange* pDX) {CDialog::DoDataExchange(pDX);}BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)END_MESSAGE_MAP()2、FormCommandView.cpp#include "stdafx.h"#include "Tool.h"#include "MainFrm.h"#include "FormCommandView.h"#include "ToolDoc.h"#include "RenderView.h"// Download by #ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif// CFormCommandViewIMPLEMENT_DYNCREATE(CFormCommandView, CFormView)CFormCommandView::CFormCommandView(): CFormView(CFormCommandView::IDD){//{{AFX_DATA_INIT(CFormCommandView)m_Smooth = FALSE;m_Antialias = FALSE;//}}AFX_DATA_INIT}CFormCommandView::~CFormCommandView(){}void CFormCommandView::DoDataExchange(CDataExchange* pDX){CFormView::DoDataExchange(pDX);//{{AFX_DATA_MAP(CFormCommandView)DDX_Control(pDX, IDC_FRAME_COLOR_BACK, m_ControlBackColor);DDX_Check(pDX, IDC_CHECK_SMOOTH, m_Smooth);DDX_Check(pDX, IDC_CHECK_ANTIALIAS, m_Antialias);//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CFormCommandView, CFormView)//{{AFX_MSG_MAP(CFormCommandView)ON_WM_PAINT()ON_WM_LBUTTONUP()ON_BN_CLICKED(IDC_RADIO_MODEL_1, OnRadioModel1)ON_BN_CLICKED(IDC_RADIO_MODEL_2, OnRadioModel2)ON_BN_CLICKED(IDC_CHECK_SMOOTH, OnCheckSmooth)ON_BN_CLICKED(IDC_CHECK_ANTIALIAS, OnCheckAntialias)//}}AFX_MSG_MAPEND_MESSAGE_MAP()///////////////////////////////////////////////////////////////////////// ////// CFormCommandView diagnostics#ifdef _DEBUGvoid CFormCommandView::AssertValid() const{CFormView::AssertValid();}void CFormCommandView::Dump(CDumpContext& dc) const{CFormView::Dump(dc);}CToolDoc* CFormCommandView::GetDocument() // non-debug version is inline {ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CToolDoc)));return (CToolDoc*)m_pDocument;}#endif //_DEBUG// OnPaintvoid CFormCommandView::OnPaint(){// Device context for paintingCPaintDC dc(this);// Options are stored in ApplicationCToolApp *pApp = (CToolApp *)AfxGetApp();CRect rect;// Color backm_ControlBackColor.GetWindowRect(&rect);ScreenToClient(&rect);CBrush BrushBack(pApp->m_OptionColorGlBack);dc.FillRect(&rect,&BrushBack);}// OnLButtonUpvoid CFormCommandView::OnLButtonUp(UINT nFlags,CPoint point){CRect rect;CToolApp *pApp = (CToolApp *)AfxGetApp();// Option back colorm_ControlBackColor.GetWindowRect(&rect);ScreenToClient(&rect);if(rect.PtInRect(point)){CColorDialog dlg(pApp->m_OptionColorGlBack);if(dlg.DoModal()==IDOK){pApp->m_OptionColorGlBack = dlg.GetColor();CRenderView *pView = (CRenderView *)GetRenderView();pView->m_ClearColorRed = (float)GetRValue(pApp->m_OptionColorGlBack) / 255.0f;pView->m_ClearColorGreen = (float)GetGValue(pApp->m_OptionColorGlBack) / 255.0f;pView->m_ClearColorBlue = (float)GetBValue(pApp->m_OptionColorGlBack) / 255.0f;this->InvalidateRect(&rect,FALSE);pView->InvalidateRect(NULL,FALSE);}}CFormView::OnLButtonUp(nFlags, point);}// GetRenderViewCView *CFormCommandView::GetRenderView(){CToolApp *pApp = (CToolApp *)AfxGetApp();CMainFrame *pFrame = (CMainFrame *)pApp->m_pMainWnd;CView *pView = (CView *)pFrame->m_wndSplitter.GetPane(0,1);return pView;}// Modelvoid CFormCommandView::OnRadioModel1(){glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);this->GetRenderView()->InvalidateRect(NULL,FALSE);}void CFormCommandView::OnRadioModel2(){glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);this->GetRenderView()->InvalidateRect(NULL,FALSE); }// OnCheckSmoothvoid CFormCommandView::OnCheckSmooth(){m_Smooth = !m_Smooth;if(m_Smooth)glShadeModel(GL_SMOOTH);elseglShadeModel(GL_FLAT);this->GetRenderView()->InvalidateRect(NULL,FALSE);}// OnCheckAntialias// Toggle antialiased linesvoid CFormCommandView::OnCheckAntialias(){m_Antialias = !m_Antialias;if(m_Antialias){glEnable(GL_LINE_SMOOTH);glEnable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);glLineWidth(1.5f);}else{glDisable(GL_LINE_SMOOTH);glDisable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);glLineWidth(1.0f);}GetRenderView()->InvalidateRect(NULL,FALSE);}3、MainFrm.cpp#include "stdafx.h"#include "Tool.h"// Download by #include "MainFrm.h"#include "FormCommandView.h"#include "RenderView.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif// CMainFrameIMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)//{{AFX_MSG_MAP(CMainFrame)ON_WM_CREATE()ON_WM_PAINT()//}}AFX_MSG_MAPEND_MESSAGE_MAP()static UINT indicators[] ={ID_SEPARATOR, // status line indicator ID_INDICATOR_CAPS,ID_INDICATOR_NUM,ID_INDICATOR_SCRL,};// CMainFrame construction/destruction CMainFrame::CMainFrame(){}CMainFrame::~CMainFrame(){}int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {if (CFrameWnd::OnCreate(lpCreateStruct) == -1)return -1;if (!m_wndToolBar.Create(this) ||!m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) {TRACE0("Failed to create toolbar\n");return -1; // fail to create}if (!m_wndStatusBar.Create(this) ||!m_wndStatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT))){TRACE0("Failed to create status bar\n");return -1; // fail to create}m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);return 0;}BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs){cs.cx = 600; cs.cy = 500;return CFrameWnd::PreCreateWindow(cs);}// CMainFrame diagnostics#ifdef _DEBUGvoid CMainFrame::AssertValid() const{CFrameWnd::AssertValid();}void CMainFrame::Dump(CDumpContext& dc) const{CFrameWnd::Dump(dc);}#endif //_DEBUG// CMainFrame message handlersvoid CMainFrame::OnPaint(){CPaintDC dc(this); // device context for painting}BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) {if (!m_wndSplitter.CreateStatic(this, 1, 2,WS_CHILD | WS_VISIBLE)){TRACE("Failed to CreateStaticSplitter\n");return FALSE;}// First splitter paneif (!m_wndSplitter.CreateView(0, 0,RUNTIME_CLASS(CRenderView), CSize(600,500), pContext)){TRACE("Failed to create command view pane\n");return FALSE;}if (!m_wndSplitter.CreateView(0, 1,RUNTIME_CLASS(CFormCommandView), CSize(0,0), pContext)){TRACE("Failed to create command view pane\n");return FALSE;}// Second splitter panereturn TRUE;}4、RenderView.cpp#include "stdafx.h"#include "Tool.h"#include <string.h>#include <time.h>#include <math.h>#include "ToolDoc.h"#include "RenderView.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endifextern void Render(void);// This is the holding space for the landscape colours.int WinWidth, WinHeigth;unsigned short int comp = 32; // Scale modifier.unsigned short int temp, texture_mapping = FALSE,land_fogging = TRUE, flat_shading = TRUE; float angle, Near, ex, ey, ez, cx, cy, cz;// Initial eye position and vector of sight.static GLfloat speed = 0;// The following code for mouse routines was contributed.// These are used for the motion function.#define FORWARD 1#define UP 2#define TURNLEFT 3#define LOOKUP 5// Mouse position and button.int oldmx = 0, oldmy = 0, mb;// CRenderViewIMPLEMENT_DYNCREATE(CRenderView, CView)BEGIN_MESSAGE_MAP(CRenderView, CView)//{{AFX_MSG_MAP(CRenderView)ON_WM_DESTROY()ON_WM_SIZE()ON_WM_LBUTTONDOWN()ON_WM_LBUTTONUP()ON_WM_MOUSEMOVE()ON_WM_PAINT()ON_WM_CREATE()//}}AFX_MSG_MAP// Standard printing commandsON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)END_MESSAGE_MAP()// CRenderView construction/destructionCRenderView::CRenderView(){// OpenGLm_hGLContext = NULL;m_GLPixelIndex = 0;// Mousem_LeftButtonDown = FALSE;m_RightButtonDown = FALSE;m_CursorRotation = AfxGetApp()->LoadCursor(IDC_CURSOR_ROTATION);// ColorsCToolApp *pApp = (CToolApp *)AfxGetApp();m_ClearColorRed = GetRValue(pApp->m_OptionColorGlBack);m_ClearColorGreen = GetGValue(pApp->m_OptionColorGlBack);m_ClearColorBlue = GetBValue(pApp->m_OptionColorGlBack); ReadData();WinWidth=1000;WinHeigth=800;LoadAllTexture();InitLookAt();}//============================================// InitGeometry//============================================void CRenderView::InitGeometry(void){GLfloat fogColor[4] = {0.75, 0.75, 1.0, 1.0};speed = 0;srand(224);srand((unsigned)time(NULL));glPixelStorei(GL_UNPACK_ALIGNMENT, 1);glEnable(GL_DEPTH_TEST);glShadeModel(GL_FLAT);glFogi(GL_FOG_MODE, GL_LINEAR);glFogfv(GL_FOG_COLOR, fogColor);glFogf(GL_FOG_DENSITY, 0.8f);glFogf(GL_FOG_START, 400.0f);glFogf(GL_FOG_END, 500.0f);glClearColor(0.75f, 0.75f, 1.0f, 1.0f);}CRenderView::~CRenderView(){FreeAllTexture();freelist();}BOOL CRenderView::PreCreateWindow(CREATESTRUCT& cs){return CView::PreCreateWindow(cs);}// CRenderView drawingvoid CRenderView::OnDraw(CDC* pDC){}BOOL CRenderView::OnPreparePrinting(CPrintInfo* pInfo){return DoPreparePrinting(pInfo);}void CRenderView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) {}void CRenderView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) {}// CRenderView diagnostics#ifdef _DEBUGvoid CRenderView::AssertValid() const{CView::AssertValid();}void CRenderView::Dump(CDumpContext& dc) const{CView::Dump(dc);}CToolDoc* CRenderView::GetDocument() // non-debug version is inline{if (m_pDocument){ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CToolDoc)));return (CToolDoc*)m_pDocument;}else return NULL;}#endif //_DEBUG// Create OpenGL rendering contextint CRenderView::OnCreate(LPCREATESTRUCT lpCreateStruct) {if (CView::OnCreate(lpCreateStruct) == -1)return -1;HWND hWnd = GetSafeHwnd();HDC hDC = ::GetDC(hWnd);if(SetWindowPixelFormat(hDC)==FALSE)return 0;if(CreateViewGLContext(hDC)==FALSE)return 0;// Default modeglPolygonMode(GL_FRONT,GL_FILL);glPolygonMode(GL_BACK,GL_FILL);glShadeModel(GL_FLAT);// light must be disabled// while rendering the terrain// because it has no normal definitionInitGeometry();glEnable(GL_TEXTURE_2D);glDisable(GL_LIGHTING);return 0;}BOOL CRenderView::SetWindowPixelFormat(HDC hDC){PIXELFORMATDESCRIPTOR pixelDesc;pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);pixelDesc.nVersion = 1;pixelDesc.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_STEREO_DONTCARE;pixelDesc.iPixelType = PFD_TYPE_RGBA;olorBits = 32;pixelDesc.cRedBits = 8;pixelDesc.cRedShift = 16;pixelDesc.cGreenBits = 8;pixelDesc.cGreenShift = 8;pixelDesc.cBlueBits = 8;pixelDesc.cBlueShift = 0;pixelDesc.cAlphaBits = 0;pixelDesc.cAlphaShift = 0;pixelDesc.cAccumBits = 64;pixelDesc.cAccumRedBits = 16;pixelDesc.cAccumGreenBits = 16;pixelDesc.cAccumBlueBits = 16;pixelDesc.cAccumAlphaBits = 0;pixelDesc.cDepthBits = 32;pixelDesc.cStencilBits = 8;pixelDesc.cAuxBuffers = 0;pixelDesc.iLayerType = PFD_MAIN_PLANE;pixelDesc.bReserved = 0;pixelDesc.dwLayerMask = 0;pixelDesc.dwVisibleMask = 0;pixelDesc.dwDamageMask = 0;m_GLPixelIndex = ChoosePixelFormat(hDC,&pixelDesc);if(m_GLPixelIndex == 0) // Choose default{m_GLPixelIndex = 1;if(DescribePixelFormat(hDC,m_GLPixelIndex,sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)==0)return FALSE;}if(!SetPixelFormat(hDC,m_GLPixelIndex,&pixelDesc))return FALSE;return TRUE;}// Create an OpenGL rendering contextBOOL CRenderView::CreateViewGLContext(HDC hDC){m_hGLContext = wglCreateContext(hDC);if(m_hGLContext==NULL)return FALSE;if(wglMakeCurrent(hDC,m_hGLContext)==FALSE)return FALSE;return TRUE;}// Cleanup every OpenGL rendering contextvoid CRenderView::OnDestroy(){if(wglGetCurrentContext() != NULL)wglMakeCurrent(NULL,NULL);if(m_hGLContext != NULL){wglDeleteContext(m_hGLContext);m_hGLContext = NULL;}CView::OnDestroy();}void CRenderView::OnSize(UINT nType, int cx, int cy) {CView::OnSize(nType, cx, cy);// Set OpenGL perspective, viewport and modeCSize size(cx,cy);double aspect;aspect = (cy == 0) ? (double)size.cx : (double)size.cx/(double)size.cy;glViewport(0, 0, (GLsizei) cx, (GLsizei) cy);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(60.0, (GLfloat) cx/(GLfloat) cy, 1.0f, 500.0f);glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt (ex, ey, ez, cx, cy, cz, 0.0f, 1.0f, 0.0f);}void CRenderView::OnLButtonDown(UINT nFlags, CPoint point){m_LeftButtonDown = TRUE;m_LeftDownPos = point;CView::OnLButtonDown(nFlags, point);}void CRenderView::OnLButtonUp(UINT nFlags,CPoint point){m_LeftButtonDown = FALSE;CView::OnLButtonUp(nFlags, point);}void CRenderView::OnMouseMove(UINT nFlags, CPoint point){switch(nFlags){case(MK_LBUTTON):MoveEye(FORWARD,(GLfloat)(oldmy-point.y)/5.0f,1);break;case(MK_RBUTTON):MoveEye(TURNLEFT, (GLfloat)(oldmx-point.x), 1);break;}oldmy = point.y;oldmx = point.x;Invalidate(FALSE);CView::OnMouseMove(nFlags, point);}void CRenderView::OnPaint(){// Device context for paintingCPaintDC dc(this);// Useful in singledoc templatesHWND hWnd = GetSafeHwnd();HDC hDC = ::GetDC(hWnd);wglMakeCurrent(hDC,m_hGLContext);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glClearColor(m_ClearColorRed,m_ClearColorGreen,m_ClearColorBlue,1.0f); glPushMatrix();glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);InitRenderWin();Render();// Double buffersSwapBuffers(hDC);}// Function that moves the eye or turns the angle of sight.// Updates scene if update != 0.void CRenderView::MoveEye(int type, GLfloat amount, int update){GLfloat a;switch(type){case FORWARD:a = sqrt((cx-ex)*(cx-ex)+(cz-ez)*(cz-ez));ex = (amount*(cx-ex)+a*ex) / a;ez = (amount*(cz-ez)+a*ez) / a;cx = (amount*(cx-ex)+a*cx) / a;cz = (amount*(cz-ez)+a*cz) / a;break;case TURNLEFT:cx = (cx-ex)*(float)cos(amount/360.0f) + (cz-ez)*(float)sin(amount/360.0f)+ex;cz = (cz-ez)*(float)cos(amount/360.0f) - (cx-ex)*(float)sin(amount/360.0f)+ez;break;case UP:ey += amount;break;case LOOKUP:cy += amount;break;}if (update){glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(ex, ey, ez, cx, cy, cz, 0.0f,1.0f,0.0f);}}TEXTURE_2D **TextureList;OBJECT *ObjectList; /* ObjectList[0]:isolated surfaces*/INT4S ObjectNum;char gEnergyFile[30];char sLookAtFN[100];char ImageName[30];void CRenderView::ReadData(){int i,j,l;FILE *fp;char stemp[100];POINT3D *plist;INT4U nAllVertexNum;INT4U *pchlist;strcpy(gEnergyFile,"room.ed");fp = fopen( gEnergyFile, "r" );if ( fp == NULL ){printf( "\n Can not open energy data file:%s\n", gEnergyFile); exit(0);}fseek( fp, 0, SEEK_SET);/****** read texture list ******/fscanf( fp, "%s", stemp);while( strcmp( stemp,"texnum" ) != 0) fscanf( fp, "%s", stemp);fscanf( fp, "%d", &texnum );TextureList = (TEXTURE_2D **)malloc( sizeof(TEXTURE_2D)*(texnum+1)); for(i=1; i<=texnum; i++){TextureList[i] = (TEXTURE_2D *)malloc( sizeof(TEXTURE_2D));fscanf( fp, "%s%s", TextureList[i]->fname, stemp );if ( strcmp( stemp,"REPEAT_TEXTURE" ) == 0)TextureList[i]->type = 1;else if ( strcmp( stemp,"CLAMP_TEXTURE" ) == 0)TextureList[i]->type = 0;}/****** Read object list ******/fscanf( fp, "%s", stemp);while( strcmp( stemp,"ObjectNum" ) != 0) fscanf(fp,"%s",stemp);fscanf( fp, "%ld", &ObjectNum);ObjectList = (OBJECT *)malloc( sizeof(OBJECT ) * ObjectNum);for(i = 0; i < ObjectNum; i ++ ){f scanf( fp, "%s", stemp);w hile( strcmp( stemp,"SurfaceNum" ) != 0) fscanf(fp,"%s",stemp);f scanf( fp, "%ld", &(ObjectList[i].SurfNum) );ObjectList[i].surflist = (SURFACE *)malloc( sizeof(SURFACE) * ObjectList[i].SurfNum);for(j = 0; j < ObjectList[i].SurfNum; j ++ ){/****** Read surface infor ******/fscanf( fp, "%s", stemp);while( strcmp( stemp,"TextureId" ) != 0) fscanf(fp,"%s",stemp);fscanf( fp, "%d", &(ObjectList[i].surflist[j].texId) );fscanf( fp, "%s", stemp);while( strcmp( stemp,"pointnum" ) != 0) fscanf(fp,"%s",stemp);fscanf( fp, "%d", &(ObjectList[i].surflist[j].pointn) );fscanf( fp, "%s", stemp);while( strcmp( stemp,"triangle" ) != 0) fscanf(fp,"%s",stemp);fscanf( fp, "%d", &(ObjectList[i].surflist[j].triangle) );fscanf( fp, "%s", stemp);while( strcmp( stemp,"quadrangle" ) != 0) fscanf(fp,"%s",stemp);fscanf( fp, "%d", &(ObjectList[i].surflist[j].quadric) );/****** Read point list ******/ObjectList[i].surflist[j].pointlist = (POINT3D*)malloc(sizeof(POINT3D) *ObjectList[i].surflist[j].pointn);plist = ObjectList[i].surflist[j].pointlist;for( l = 0; l < ObjectList[i].surflist[j].pointn ; l ++ )fscanf( fp, "%f%f%f%f%f%f%f%f",&(plist[l].r), &(plist[l].g), &(plist[l].b),&(plist[l].u), &(plist[l].v),&(plist[l].x), &(plist[l].y), &(plist[l].z) );/****** Read patchlist ******/nAllVertexNum = ObjectList[i].surflist[j].triangle * 3 +ObjectList[i].surflist[j].quadric *4 ;ObjectList[i].surflist[j].patchlist = (INT4U *)malloc( sizeof(INT4U) * nAllVertexNum);pchlist = ObjectList[i].surflist[j].patchlist;for( l = 0; l < nAllVertexNum; l ++ )fscanf( fp, "%ld", &(pchlist[l]) );}}fclose(fp);}void CRenderView::InitLookAt(){FILE *fp;strcpy(sLookAtFN,"room.lk");fp = fopen(sLookAtFN, "rb");if (fp == NULL){ex = ey = ez =1.0f;cx = cy = cz =0.0f;Near = 0.1f;angle = 30.0f;}else fscanf(fp, "%f%f%f%f%f%f%f%f", &angle, &Near, &ex, &ey, &ez, &cx, &cy, &cz);fclose(fp);}void C RenderView::InitRenderWin(){glShadeModel ( GL_SMOOTH );glDepthFunc ( GL_LESS );glEnable ( GL_DEPTH_TEST );glMatrixMode ( GL_PROJECTION );glLoadIdentity();glMatrixMode ( GL_MODELVIEW );glLoadIdentity();gluPerspective ( angle, (float)WinWidth/(float)WinHeigth, Near, 1000000000.0); gluLookAt( ex, ey, ez, cx, cy, cz, 0.0, 1.0, 0.0);}void C RenderView::Render(void){int i, j, k, l, m, TexIndex;POINT3D *plist;INT4U *pchlist;glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ACCUM_BUFFER_BIT);for(i = 0; i < ObjectNum; i ++ )for(j = 0; j < ObjectList[i].SurfNum; j ++ ){TexIndex = ObjectList[i].surflist[j].texId;if( TexIndex > 0 )InitTex( TexIndex );plist = ObjectList[i].surflist[j].pointlist;pchlist = ObjectList[i].surflist[j].patchlist;l = 0;for ( k = 0; k < ObjectList[i].surflist[j].triangle; k ++){glBegin( GL_TRIANGLES );for( m = 0; m < 3; m ++ ){glColor3f ( plist[pchlist[l]].r,plist[pchlist[l]].g,plist[pchlist[l]].b );glTexCoord2f( plist[pchlist[l]].u,plist[pchlist[l]].v );glVertex3f( plist[pchlist[l]].x,plist[pchlist[l]].y,plist[pchlist[l]].z );l ++;}/* m */glEnd();}/* k */for ( k = 0; k < ObjectList[i].surflist[j].quadric; k ++){glBegin( GL_QUADS );for( m = 0; m < 4; m ++ ){glColor3f ( plist[pchlist[l]].r,plist[pchlist[l]].g,plist[pchlist[l]].b );glTexCoord2f( plist[pchlist[l]].u,plist[pchlist[l]].v );glVertex3f( plist[pchlist[l]].x,plist[pchlist[l]].y,plist[pchlist[l]].z );l ++;}/* m */glEnd();}/* k */glFlush();CloseTex();}}void CRenderView::freelist(){int i, j;for( i=0; i<ObjectNum; i++){for( j=0; j<ObjectList[i].SurfNum; j++){free(ObjectList[i].surflist[j].pointlist);free(ObjectList[i].surflist[j].patchlist);}free( ObjectList[i].surflist );}free(ObjectList);for(i=1; i<=texnum; i++)free(TextureList[i]);free(TextureList);}extern TEXTURE_2D **TextureList;/********************************//* function : OpenTexImage *//********************************/unsigned char *CRenderView::OpenTexImage( INT2U TexIndex, INT2U *rslx, INT2U *rsly ){unsigned char *image;FILE *fp;INT2U srcx, srcy;INT4U i, j;char ImageName[30];unsigned char *SImageData;int rc;int width, height;strcpy( ImageName, TextureList[TexIndex]->fname);/* load a image */fp = fopen(ImageName,"rb");if(!fp) return 0;fseek(fp,18L,0);rc=fread(&width,sizeof(long),1,fp);rc=fread(&height,sizeof(long),1,fp);*rslx=srcx=width; *rsly=srcy=height;fseek(fp,54L,0);image = (unsigned char *)malloc(width*height*3);rc=fread(image,width*height*3,1,fp);fclose(fp);SImageData = (unsigned char *)malloc(srcx*srcy*3);for(i=0; i<srcx; i++) {for(j=0; j<srcy; j++) {(unsigned char)*(SImageData+i*srcx*3+j*3+0) = (unsignedchar)*(image+i*srcx*3+j*3+2);(unsigned char)*(SImageData+i*srcx*3+j*3+1) = (unsigned char)*(image+i*srcx*3+j*3+1);(unsigned char)*(SImageData+i*srcx*3+j*3+2) = (unsigned char)*(image+i*srcx*3+j*3+0);}}free(image);printf("%s : %ld=%ld\n", ImageName, srcx*srcy*3,i*j*3);return( SImageData );}/********************************//* function : InitTex *//********************************/void C RenderView::InitTex( int TexIndex ){INT2U TextType;unsigned char *ImageData;static int OldIndex = -1;if(TexIndex<=0) return;if(TexIndex == OldIndex){glEnable(GL_TEXTURE_2D);return;}ImageData = ImageDatas[TexIndex-1];TextType = TextureList[TexIndex]->type;glPixelStorei(GL_UNPACK_ALIGNMENT, 1);glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);if( TextType == CLAMP_TEXTURE ){glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);}else{glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);}glTexImage2D( GL_TEXTURE_2D, 0, 3, rslxs[TexIndex-1], rslys[TexIndex-1], 0,GL_RGB, GL_UNSIGNED_BYTE, ImageData );glEnable(GL_TEXTURE_2D);OldIndex = TexIndex;}/********************************//* function : CloseTex *//********************************/void C RenderView::CloseTex(){glDisable(GL_TEXTURE_2D);}void CRenderView::LoadAllTexture(){int i;for (i=0; i <texnum ; i++)ImageDatas[i] = OpenTexImage( i+1, &rslxs[i], &rslys[i] );}void CRenderView::FreeAllTexture(){int i;for (i=0; i <texnum ; i++)free(ImageDatas[i]);}5、StdAfx.cpp#include "stdafx.h"6、Tool.cpp#include "stdafx.h"#include "Tool.h"#include "DlgAbout.h"#include "MainFrm.h"#include "ToolDoc.h"#include "RenderView.h"// Download by #ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif// CToolAppCToolDoc *MyDocument;BEGIN_MESSAGE_MAP(CToolApp, CWinApp)//{{AFX_MSG_MAP(CToolApp)ON_COMMAND(ID_APP_ABOUT, OnAppAbout)//}}AFX_MSG_MAP// Standard file based document commands// Standard print setup commandON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup) END_MESSAGE_MAP()// CToolApp constructionCToolApp::CToolApp(){// Optionsm_OptionColorGlBack = RGB(0,0,255);}// The one and only CToolApp objectCToolApp theApp;// CToolApp initializationBOOL CToolApp::InitInstance(){AfxEnableControlContainer();// Standard initialization// If you are not using these features and wish to reduce the size// of your final executable, you should remove from the following// the specific initialization routines you do not need.#ifdef _AFXDLLEnable3dControls(); // Call this when using MFC in a shared DLL#elseEnable3dControlsStatic(); // Call this when linking to MFC statically#endif// Change the registry key under which our settings are stored.// You should modify this string to be something appropriate// such as the name of your company or organization.SetRegistryKey(_T("3D Toolbox"));LoadStdProfileSettings(10); // Load standard INI file options (including MRU)// Register the application's document templates. Document templates// serve as the connection between documents, frame windows and views.CSingleDocTemplate* pDocTemplate;// create main SDI Frame windowCMainFrame* pMainFrame = new CMainFrame;if (!pMainFrame->LoadFrame(IDR_MAINFRAME))return FALSE;m_pMainWnd = pMainFrame;pDocTemplate = new CSingleDocTemplate(IDR_MODELTYPE,RUNTIME_CLASS(CToolDoc),RUNTIME_CLASS(CMainFrame),RUNTIME_CLASS(CRenderView));AddDocTemplate(pDocTemplate);// The main window has been initialized, so show and update it.//pMainFrame->ShowWindow(SW_SHOWMAXIMIZED);pMainFrame->ShowWindow(SW_SHOW);pMainFrame->UpdateWindow();return TRUE;}// App command to run the dialogvoid CToolApp::OnAppAbout(){CAboutDlg aboutDlg;aboutDlg.DoModal();}6、ToolDoc.cpp#include "stdafx.h"#include "math.h"#include "Tool.h"#include "ToolDoc.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endifIMPLEMENT_DYNCREATE(CToolDoc, CDocument)BEGIN_MESSAGE_MAP(CToolDoc, CDocument)//{{AFX_MSG_MAP(CToolDoc)// NOTE - the ClassWizard will add and remove mapping macros here.// DO NOT EDIT what you see in these blocks of generated code!//}}AFX_MSG_MAPEND_MESSAGE_MAP()extern CToolApp theApp;// CToolDoc construction/destruction。
目录实验一中点算法 (2)一、实验目的和要求 (2)二、主要算法描述 (2)三、代码实现 (4)四、实验结果 (7)实验二Bezier曲线画茶壶 (11)一、实验目的和要求 (11)二、主要算法描述 (11)三、代码实现 (12)四、实验结果 (15)心得体会: (16)实验一 中点算法一、实验目的和要求学习使用OpenGL ,初步了解基本的OpenGL 编程方法。
熟练掌握中点算法,知道如何运用中点算法编程绘制直线、椭圆和圆。
编制中点画圆程序,上机实现在给定条件下下用中点算法画出圆形。
二、主要算法描述试验设计思路:圆是一个八分对称的图形,因此在计算圆上像素点的坐标时,可以只计算八分之一个圆,再依照对称原理算出其他七段的像素点(如下图)。
设圆方程的隐函数表示为 类似于中点法绘制直线的原理,我们将平面点划分为圆内和圆外(如下图):圆弧外的点:F(X ,Y)>0;圆弧内的点:F(X ,Y)<0;),(222=-+=R y x y x F假设在),(i i y x 绘制了一个像素,则下一步必须确定像素位置是),1(i i y x +还是)1,1(-+i i y x 更接近圆。
一次由两个点的中点决定,若中点)21,1(-+i i y x 在圆内,则说明)1,1(-+i i y x 更接近圆,否则说明),1(i i y x +更接近圆(如下图)。
为了在计算中避开计算圆的方程时会遇到的平方与开方,故运用迭代方法由式1211++=++i i i x p p 与111212+++-++=i i i i y x p p 计算决定参数。
试验编程思路:1. 输入圆半径r 和圆心),(c c y x ,并得到圆周(圆心在原点)上的第一个点:),0(),(00r y x =2. 计算决策参数的初值:r p -=103. 在每个k x 位置,从0=k 开始,完成下列测试:加入0<k p ,圆心在原点的下一个点位),(1k k y x +,并且1211++=++k k k x p p否则,圆的下一个点是)1,1(-+k k y x ,并且111212+++-++=k k k k y x p p其中11+=+k k x x 且11-=+k k y y4.确定其他七个八分圆中的对称点。
5. 将每个计算出的圆心在原点的像素位置平移至圆心在点),(c c y x 的圆上。
6. 重复上述3到5步骤,直至y x ≥。
三、代码实现程序中主要包括以下几部分:1. 声明包含的库文件#include <GL/glut.h>2. 程序中用到的数据结构struct circle{//圆心GLint xc;GLint yc;//半径GLint rc;};3. 画点函数void SetPixel(GLint x,GLint y){glBegin(GL_POINTS);glVertex2i(x,y);glEnd();}//根据圆的八对称性画其他7个点,总共绘制八个点void CirclePoints(circle c,GLint x,GLint y){SetPixel(x+c.xc,y+c.yc);SetPixel(y+c.xc,x+c.yc);SetPixel(c.xc-y,x+c.yc);SetPixel(c.xc-x,y+c.yc);SetPixel(c.xc-x,c.yc-y);SetPixel(c.xc-y,c.yc-x);SetPixel(y+c.xc,c.yc-x);SetPixel(x+c.xc,c.yc-y);}4.根据中点算法绘制八分之一圆弧,这是程序的核心。
void DrawCircle(circle c){int x,y;GLint r=c.rc;GLint p=1-r;x=0;y=r;CirclePoints(c,0,r);while(x<=y){if(p<0){p+=2*(x+1)+1;x=x+1;}else{p+=2*(x+1)+1-2*(y-1);x=x+1;y=y-1;}CirclePoints(c,x,y);}}5.窗口显示初始化void Init(){glClearColor(1.0f,1.0f,1.0f,0.0f); //初始化窗口背景色glMatrixMode(GL_PROJECTION);//改变剪裁窗口的大小gluOrtho2D(-400.0,400.0,-400.0,400.0);//gluOrtho2D(-100.0,100.0,-100.0,100.0);//gluOrtho2D(-50.0,50.0,-50.0,50.0);glMatrixMode(GL_MODELVIEW);}6.窗口中绘制需要的图形void Display(void){glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0f,0.0f,0.0f);glViewport(0,0,400,400);//视口固定//改变圆的半径,从而在剪裁窗口的大小改变时保证我们看到的圆的大小不变circle c={0,0,360};// circle c={0,0,90};// circle c={0,0,45};DrawCircle(c);glFlush();}7.主程序void main(int argc,char * argv[]){glutInit(&argc,argv);glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);glutInitWindowPosition(100,100);glutInitWindowSize(400,400);glutCreateWindow("MyOpenGL||尹帮虎200806020072");Init();glutDisplayFunc(Display);glutMainLoop();}四、实验结果1.视口与裁剪窗口大小相同时(结果如下图)。
在程序中选择:gluOrtho2D(-400.0,400.0,-400.0,400.0);//…..glViewport(0,0,400,400);circle c={0,0,360};2.视口与裁剪窗口为1:4时(结果如下图)。
在程序中选择:gluOrtho2D(-100.0,100.0,-100.0,100.0);//…..glViewport(0,0,400,400);circle c={0,0,90};3.视口与裁剪窗口为1:8时(结果如下图)。
在程序中选择:gluOrtho2D(-50.0,50.0,-50.0,50.0);//…..glViewport(0,0,400,400);circle c={0,0,45};实验二 Bezier 曲线画茶壶一、实验目的和要求学习使用OpenGL ,进一步了解基本的OpenGL 编程方法。
掌握使用Bezier 曲线画茶壶的算法,并编程实现。
二、主要算法描述首先,在做这个实验之前,我们必须了解使用Bezier 曲线拟合的原理与思想,Bezier 基函数的定义:如下n 次多项式称为n 次Bezier 基函数其中:Bezier 曲线的定义:下列n 次多项式曲线P (t )称为n 次Bezier 曲线为了深刻理解其控制点的含义,主要对课本上的范例进行尝试,得到了使用4个控制点得到1条Bezier 曲线的方法。
对于实现茶壶,主要考虑怎样实现壶体,壶盖,把手与壶嘴。
壶体:可以假定壶体表面是一个旋转面,因此只要在XZ 平面上找到用来生成旋转面的基本曲线就可以了。
我使用分段三次Bezier 曲线描述,由10个控制点控制三段曲线,每段分别由点〖1,2,3,4〗、〖4,5,6,7〗、〖7,8,9,10〗控制。
10点坐标已经给出(见下表a )。
]1,0[,)1()(,∈-=-t t t C t BEZ in ii n n i )!(!!i n i n C in -=]1,0[)()(0,∈⋅=∑=t t BEZ P t P ni n i i壶盖也可视为旋转面,它的外轮廓线由两段三次Bezier曲线组成,每段分别由点[1,2,3,4]、[4,5,6,7]控制,7个控制点已经给出(见上表b)。
把手与壶嘴:用Bezier曲面表示,剖面的外轮廓线有两条,每条有两段7个控制点(见下图cd),Y值为0.0,然后再增加两条外轮廓线,它们的X、Z坐标与前同,只是Y不同。
即实际由两片加对称的两片(-Y)组成。
但是如果根据课件中给出的数据会导致画出一个把手和壶嘴向外的不对称茶壶,这是由于其Y坐标的原因,在实现中可以将Y坐标平分,为-y和y即可达到对称的目的。
壶底为一平面圆,半径为1.5000。
三、代码实现程序中使用函数binomialCoeffs() 和beziercommon()计算Bezier的基函数BEZ i,n(t),然后使用函数computeBezPt()来根据控制点的坐标计算其Bezier函数。
壶体、壶盖、壶底的算法:对于壶体,主要函数为void drawTeapotBody(),通过给出Bezier曲线并旋转得到壶体。
对于壶盖,主要函数为void drawTeapotTop(),也是使用旋转的思想得到壶盖,壶底的实现较为简单,主要函数为void drawTeapotBottom(),就是一个半径为1.5000的平面圆,这一部分教员给了参考代码,为画壶嘴和壶把做出指导。
画壶体、壶盖的步骤如下:1、首先采用bezier曲线原理编程绘制一条bezier曲线。
a.通过distance函数计算给定控制点间的折线距离d,若d大于所要求的上限,则将该控制点进行差分得到两倍于原来的控制点数,并分成两组,转b。
否则绘制图线,此程序中每段曲线绘制100个点。
b.对于两组控制点,继续递归调用。
执行a。
2、将每两段间的分割点记录,便于后面绘制水平圆面。
3、将第一步中绘制的曲线进行旋转,得到纵向网格线,本程序中采用了纵向360度总共的20条线,每隔18度旋转一次。
4、用上面三步所述相同的方法来绘制壶体和壶底。
5、加入鼠标控制和键盘控制,同时自动更改视点,实现可旋转。
这样执行的结果是一个无把和嘴的壶,如下:壶把、壶嘴实现的算法:程序中主要有以下函数用来实现壶嘴和壶把,实现壶嘴的函数有:void drawTeapotMouth17011();void drawTeapotMouth17012();void drawTeapotMouth17021();void drawTeapotMouth17022();实现壶把的函数有:void drawTeapotMouth16011();void drawTeapotMouth16012();void drawTeapotMouth15021();void drawTeapotMouth15022();壶把、壶嘴用Bezier曲面表示,剖面的外轮廓线有两条,每条有两段7个控制点,Y值为0.0,然后再增加两条外轮廓线,它们的X、Z坐标与前同,只是Y不同。