1
0
mirror of https://github.com/LearnOpenGL-CN/LearnOpenGL-CN.git synced 2025-08-22 20:25:28 +08:00

Update 03-01

This commit is contained in:
Meow J
2017-06-26 02:22:13 +08:00
parent 82a1575c00
commit 1ea5f9db73
14 changed files with 69 additions and 62 deletions

View File

@@ -3,8 +3,8 @@
原文 | [OpenGL](http://learnopengl.com/#!Getting-started/OpenGL) 原文 | [OpenGL](http://learnopengl.com/#!Getting-started/OpenGL)
---|--- ---|---
作者 | JoeyDeVries 作者 | JoeyDeVries
翻译 | gjy_1992 翻译 | gjy_1992, Meow J
校对 | Geequlim 校对 | 暂未校对
在开始这段旅程之前我们先了解一下OpenGL到底是什么。一般它被认为是一个API(<def>Application Programming Interface</def>, 应用程序编程接口)包含了一系列可以操作图形、图像的函数。然而OpenGL本身并不是一个API它仅仅是一个由[Khronos组织](http://www.khronos.org/)制定并维护的规范(Specification)。 在开始这段旅程之前我们先了解一下OpenGL到底是什么。一般它被认为是一个API(<def>Application Programming Interface</def>, 应用程序编程接口)包含了一系列可以操作图形、图像的函数。然而OpenGL本身并不是一个API它仅仅是一个由[Khronos组织](http://www.khronos.org/)制定并维护的规范(Specification)。

View File

@@ -3,8 +3,8 @@
原文 | [Creating a window](http://learnopengl.com/#!Getting-started/Creating-a-window) 原文 | [Creating a window](http://learnopengl.com/#!Getting-started/Creating-a-window)
---|--- ---|---
作者 | JoeyDeVries 作者 | JoeyDeVries
翻译 | gjy_1992 翻译 | gjy_1992, Meow J
校对 | 未校对 校对 | 未校对
!!! note "译注" !!! note "译注"

View File

@@ -3,8 +3,8 @@
原文 | [Hello Window](http://learnopengl.com/#!Getting-started/Hello-Window) 原文 | [Hello Window](http://learnopengl.com/#!Getting-started/Hello-Window)
---|--- ---|---
作者 | JoeyDeVries 作者 | JoeyDeVries
翻译 | Geequlim 翻译 | Geequlim, Meow J
校对 | 未校对 校对 | 未校对
让我们试试能不能让GLFW正常工作。首先新建一个`.cpp`文件,然后把下面的代码粘贴到该文件的最前面。 让我们试试能不能让GLFW正常工作。首先新建一个`.cpp`文件,然后把下面的代码粘贴到该文件的最前面。

View File

@@ -3,8 +3,8 @@
原文 | [Hello Triangle](http://www.learnopengl.com/#!Getting-started/Hello-Triangle) 原文 | [Hello Triangle](http://www.learnopengl.com/#!Getting-started/Hello-Triangle)
---|--- ---|---
作者 | JoeyDeVries 作者 | JoeyDeVries
翻译 | [Django](http://bullteacher.com/) 翻译 | [Django](http://bullteacher.com/), Meow J, Geequlim
校对 | Geequlim 校对 | 暂未校对
!!! note "译注" !!! note "译注"

View File

@@ -3,8 +3,8 @@
原文 | [Shaders](http://learnopengl.com/#!Getting-started/Shaders) 原文 | [Shaders](http://learnopengl.com/#!Getting-started/Shaders)
---|--- ---|---
作者 | JoeyDeVries 作者 | JoeyDeVries
翻译 | [Django](http://bullteacher.com/) 翻译 | [Django](http://bullteacher.com/), Meow J, Geequlim
校对 | Geequlim 校对 | 暂未校对
在[Hello Triangle](04 Hello Triangle.md)教程中提到,着色器(Shader)是运行在GPU上的小程序。这些小程序为图形渲染管线的某个特定部分而运行。从基本意义上来说着色器只是一种把输入转化为输出的程序。着色器也是一种非常独立的程序因为它们之间不能相互通信它们之间唯一的沟通只有通过输入和输出。 在[Hello Triangle](04 Hello Triangle.md)教程中提到,着色器(Shader)是运行在GPU上的小程序。这些小程序为图形渲染管线的某个特定部分而运行。从基本意义上来说着色器只是一种把输入转化为输出的程序。着色器也是一种非常独立的程序因为它们之间不能相互通信它们之间唯一的沟通只有通过输入和输出。

View File

@@ -3,8 +3,8 @@
原文 | [Textures](http://learnopengl.com/#!Getting-started/Textures) 原文 | [Textures](http://learnopengl.com/#!Getting-started/Textures)
---|--- ---|---
作者 | JoeyDeVries 作者 | JoeyDeVries
翻译 | [Django](http://bullteacher.com/) 翻译 | [Django](http://bullteacher.com/), Meow J, Geequlim, [BLumia](https://github.com/blumia/)
校对 | Geequlim, [BLumia](https://github.com/blumia/) 校对 | 暂未校对
!!! note "译注" !!! note "译注"

View File

@@ -3,8 +3,8 @@
原文 | [Transformations](http://learnopengl.com/#!Getting-started/Transformations) 原文 | [Transformations](http://learnopengl.com/#!Getting-started/Transformations)
---|--- ---|---
作者 | JoeyDeVries 作者 | JoeyDeVries
翻译 | Django 翻译 | Django, Meow J, [BLumia](https://github.com/blumia/)
校对 | Meow J, [BLumia](https://github.com/blumia/) 校对 | 暂未校对
尽管我们现在已经知道了如何创建一个物体、着色、加入纹理,给它们一些细节的表现,但因为它们都还是静态的物体,仍是不够有趣。我们可以尝试着在每一帧改变物体的顶点并且重配置缓冲区从而使它们移动,但这太繁琐了,而且会消耗很多的处理时间。我们现在有一个更好的解决方案,使用(多个)<def>矩阵</def>(Matrix)对象可以更好的<def>变换</def>(Transform)一个物体。当然这并不是说我们会去讨论武术和数字虚拟世界译注Matrix同样也是电影「黑客帝国」的英文名电影中人类生活在数字虚拟世界主角会武术 尽管我们现在已经知道了如何创建一个物体、着色、加入纹理,给它们一些细节的表现,但因为它们都还是静态的物体,仍是不够有趣。我们可以尝试着在每一帧改变物体的顶点并且重配置缓冲区从而使它们移动,但这太繁琐了,而且会消耗很多的处理时间。我们现在有一个更好的解决方案,使用(多个)<def>矩阵</def>(Matrix)对象可以更好的<def>变换</def>(Transform)一个物体。当然这并不是说我们会去讨论武术和数字虚拟世界译注Matrix同样也是电影「黑客帝国」的英文名电影中人类生活在数字虚拟世界主角会武术

View File

@@ -3,8 +3,8 @@
原文 | [Coordinate Systems](http://learnopengl.com/#!Getting-started/Coordinate-Systems) 原文 | [Coordinate Systems](http://learnopengl.com/#!Getting-started/Coordinate-Systems)
---|--- ---|---
作者 | JoeyDeVries 作者 | JoeyDeVries
翻译 | linkoln 翻译 | linkoln, Geequlim, Meow J, [BLumia](https://github.com/blumia/)
校对 | Geequlim, Meow J, [BLumia](https://github.com/blumia/) 校对 | 暂未校对
在上一个教程中我们学习了如何有效地利用矩阵的变换来对所有顶点进行变换。OpenGL希望在每次顶点着色器运行后我们可见的所有顶点都为标准化设备坐标(Normalized Device Coordinate, NDC)。也就是说,每个顶点的**x****y****z**坐标都应该在**-1.0**到**1.0**之间,超出这个坐标范围的顶点都将不可见。我们通常会自己设定一个坐标的范围,之后再在顶点着色器中将这些坐标变换为标准化设备坐标。然后将这些标准化设备坐标传入光栅器(Rasterizer),将它们变换为屏幕上的二维坐标或像素。 在上一个教程中我们学习了如何有效地利用矩阵的变换来对所有顶点进行变换。OpenGL希望在每次顶点着色器运行后我们可见的所有顶点都为标准化设备坐标(Normalized Device Coordinate, NDC)。也就是说,每个顶点的**x****y****z**坐标都应该在**-1.0**到**1.0**之间,超出这个坐标范围的顶点都将不可见。我们通常会自己设定一个坐标的范围,之后再在顶点着色器中将这些坐标变换为标准化设备坐标。然后将这些标准化设备坐标传入光栅器(Rasterizer),将它们变换为屏幕上的二维坐标或像素。

View File

@@ -3,8 +3,8 @@
原文 | [Camera](http://learnopengl.com/#!Getting-started/Camera) 原文 | [Camera](http://learnopengl.com/#!Getting-started/Camera)
---|--- ---|---
作者 | JoeyDeVries 作者 | JoeyDeVries
翻译 | [Django](http://bullteacher.com/) 翻译 | [Django](http://bullteacher.com/), Meow J, Geequlim, [BLumia](https://github.com/blumia/)
校对 | Geequlim, [BLumia](https://github.com/blumia/) 校对 | 暂未校对
前面的教程中我们讨论了观察矩阵以及如何使用观察矩阵移动场景我们向后移动了一点。OpenGL本身没有**摄像机**(Camera)的概念,但我们可以通过把场景中的所有物体往相反方向移动的方式来模拟出摄像机,产生一种**我们**在移动的感觉,而不是场景在移动。 前面的教程中我们讨论了观察矩阵以及如何使用观察矩阵移动场景我们向后移动了一点。OpenGL本身没有**摄像机**(Camera)的概念,但我们可以通过把场景中的所有物体往相反方向移动的方式来模拟出摄像机,产生一种**我们**在移动的感觉,而不是场景在移动。

View File

@@ -3,8 +3,8 @@
原文 | [Colors](http://learnopengl.com/#!Lighting/Colors) 原文 | [Colors](http://learnopengl.com/#!Lighting/Colors)
---|--- ---|---
作者 | JoeyDeVries 作者 | JoeyDeVries
翻译 | [Geequlim](http://geequlim.com/) 翻译 | [Geequlim](http://geequlim.com/), Meow J
校对 | [Geequlim](http://geequlim.com/) 校对 | 暂未校对
在前面的教程中我们已经简要提到过该如何在OpenGL中使用颜色(Color),但是我们至今所接触到的都是很浅层的知识。本节我们将会更深入地讨论什么是颜色,并且还会为接下来的光照(Lighting)教程创建一个场景。 在前面的教程中我们已经简要提到过该如何在OpenGL中使用颜色(Color),但是我们至今所接触到的都是很浅层的知识。本节我们将会更深入地讨论什么是颜色,并且还会为接下来的光照(Lighting)教程创建一个场景。

View File

@@ -3,8 +3,8 @@
原文 | [Basic Lighting](http://learnopengl.com/#!Lighting/Basic-Lighting) 原文 | [Basic Lighting](http://learnopengl.com/#!Lighting/Basic-Lighting)
---|--- ---|---
作者 | JoeyDeVries 作者 | JoeyDeVries
翻译 | [Django](http://bullteacher.com/) 翻译 | [Django](http://bullteacher.com/), Meow J, Geequlim, [BLumia](https://github.com/blumia/)
校对 | Geequlim, [BLumia](https://github.com/blumia/) 校对 | 暂未校对
现实世界的光照是极其复杂的而且会受到诸多因素的影响这是我们有限的计算能力所无法模拟的。因此OpenGL的光照使用的是简化的模型对现实的情况进行近似这样处理起来会更容易一些而且看起来也差不多一样。这些光照模型都是基于我们对光的物理特性的理解。其中一个模型被称为<def>冯氏光照模型</def>(Phong Lighting Model)。冯氏光照模型的主要结构由3个分量组成环境(Ambient)、漫反射(Diffuse)和镜面(Specular)光照。下面这张图展示了这些光照分量看起来的样子: 现实世界的光照是极其复杂的而且会受到诸多因素的影响这是我们有限的计算能力所无法模拟的。因此OpenGL的光照使用的是简化的模型对现实的情况进行近似这样处理起来会更容易一些而且看起来也差不多一样。这些光照模型都是基于我们对光的物理特性的理解。其中一个模型被称为<def>冯氏光照模型</def>(Phong Lighting Model)。冯氏光照模型的主要结构由3个分量组成环境(Ambient)、漫反射(Diffuse)和镜面(Specular)光照。下面这张图展示了这些光照分量看起来的样子:

View File

@@ -4,7 +4,7 @@
---|--- ---|---
作者 | JoeyDeVries 作者 | JoeyDeVries
翻译 | Meow J 翻译 | Meow J
校对 | 未校对 校对 | 未校对
在现实世界里,每个物体会对光产生不同的反应。比如说,钢看起来通常会比陶瓷花瓶更闪闪发光,木头箱子也不会像钢制箱子那样对光产生很强的反射。每个物体对镜面高光也有不同的反应。有些物体反射光的时候不会有太多的散射(Scatter)因而产生一个较小的高光点而有些物体则会散射很多产生一个有着更大半径的高光点。如果我们想要在OpenGL中模拟多种类型的物体我们必须为每个物体分别定义一个<def>材质</def>(Material)属性。 在现实世界里,每个物体会对光产生不同的反应。比如说,钢看起来通常会比陶瓷花瓶更闪闪发光,木头箱子也不会像钢制箱子那样对光产生很强的反射。每个物体对镜面高光也有不同的反应。有些物体反射光的时候不会有太多的散射(Scatter)因而产生一个较小的高光点而有些物体则会散射很多产生一个有着更大半径的高光点。如果我们想要在OpenGL中模拟多种类型的物体我们必须为每个物体分别定义一个<def>材质</def>(Material)属性。

View File

@@ -3,73 +3,69 @@
原文 | [Assimp](http://learnopengl.com/#!Model-Loading/Assimp) 原文 | [Assimp](http://learnopengl.com/#!Model-Loading/Assimp)
---|--- ---|---
作者 | JoeyDeVries 作者 | JoeyDeVries
翻译 | Cocoonshu 翻译 | Cocoonshu, Meow J, [Geequlim](http://geequlim.com)
校对 | [Geequlim](http://geequlim.com) 校对 | 暂未校对
到目前为止的所有场景中,我们一直都在滥用我们的箱子朋友,但时间久了甚至是我们最好的朋友也会感到无聊。在日常的图形程序中,通常都会使用非常复杂且好玩的模型,它们比静态的箱子要好看多了。然而,和箱子对象不同,我们不太能够对像是房子、汽车或者人形角色这样的复杂形状手工定义所有的顶点、法线和纹理坐标。我们想要的是将这些模型(Model)**导入**(Import)到程序当中。模型通常都由3D艺术家在[Blender](http://www.blender.org/)、[3DS Max](http://www.autodesk.nl/products/3ds-max/overview)或者[Maya](http://www.autodesk.com/products/autodesk-maya/overview)这样的工具中精心制作。
到目前为止我们已经在所有的场景中大面积滥用了我们的容器盒小盆友但就是容器盒是我们的好朋友时间久了我们也会喜新厌旧。一些图形应用里经常会使用很多复杂且好玩儿的模型它们看起来比静态的容器盒可爱多了。但是我们无法像定义容器盒一样手动地去指定房子、货车或人形角色这些复杂模型的顶点、法线和纹理坐标。我们需要做的也是应该要做的是把这些模型导入到应用程序中而设计制作这些3D模型的工作应该交给像[Blender](http://www.blender.org/)、[3DS Max](http://www.autodesk.nl/products/3ds-max/overview)或者[Maya](http://www.autodesk.com/products/autodesk-maya/overview)这样的工具软件 这些所谓的<def>3D建模工具</def>(3D Modeling Tool)可以让艺术家创建复杂的形状,并使用一种叫做<def>UV映射</def>(uv-mapping)的手段来应用贴图。这些工具将会在导出到模型文件的时候自动生成所有的顶点坐标、顶点法线以及纹理坐标。这样子艺术家们即使不了解图形技术细节的情况下,也能拥有一套强大的工具来构建高品质的模型了。所有的技术细节都隐藏在了导出的模型文件中。但是,作为图形开发者,我们就**必须**要了解这些技术细节了
那些3D建模工具可以让美工们构建一些复杂的形状并将贴图应用到形状上去即纹理映射。然后在导出模型文件时,建模工具会自己生成所有的顶点坐标、顶点法线和纹理坐标。这样,美工们可以不用了解大量的图像技术细节,就能有大量的工具集去随心地构建高品质的模型。所有的技术细节内容都隐藏在里导出的模型文件里。而我们,这些图形开发者,就必须得去关注这些技术细节了 所以我们的工作就是解析这些导出的模型文件以及提取所有有用的信息将它们储存为OpenGL能够理解的格式。一个很常见的问题是模型文件格式有很多种,每一种都会以它们自己的方式来导出模型数据。像是[Wavefront的.obj](http://en.wikipedia.org/wiki/Wavefront_.obj_file)这样的模型格式,只包含了模型数据以及材质信息,像是模型颜色和漫反射/镜面光贴图。而以XML为基础的[Collada文件格式](http://en.wikipedia.org/wiki/COLLADA)则非常的丰富包含模型、光照、多种材质、动画数据、摄像机、完整的场景信息等等。Wavefront的.obj格式通常被认为是一个易于解析的模型格式。建议至少去Wavefront的wiki页面上看看文件格式的信息是如何封装的。这应该能让你认识到模型文件的基本结构
因此我们的工作就是去解析这些导出的模型文件并将其中的模型数据存储为OpenGL能够使用的数据。一个常见的问题是导出的模型文件通常有几十种格式不同的工具会根据不同的文件协议把模型数据导出到不同格式的模型文件中。有的模型文件格式只包含模型的静态形状数据和颜色、漫反射贴图、高光贴图这些基本的材质信息比如Wavefront的.obj文件。而有的模型文件则采用XML来记录数据且包含了丰富的模型、光照、各种材质、动画、摄像机信息和完整的场景信息等比如Collada文件格式。Wavefront的obj格式是为了考虑到通用性而设计的一种便于解析的模型格式。建议去Wavefront的Wiki上看看obj文件格式是如何封装的。这会给你形成一个对模型文件格式的一个基本概念和印象 总而言之,不同种类的文件格式有很多,它们之间通常并没有一个通用的结构。所以如果我们想从这些文件格式中导入模型的话,我们必须要去自己对每一种需要导入的文件格式写一个导入器。很幸运的是,正好有一个库专门处理这个问题
## 模型加载库 ## 模型加载库
现在市面上有一个很流行的模型加载库叫做Assimp全称为Open Asset Import Library。Assimp可以导入几十种不同格式的模型文件(同样也可以导出部分模型格式)。只要Assimp加载完模型文件,我们就可以从Assimp上获取所有我们需要的模型数据。Assimp把不同的模型文件都转换为一个统一的数据结构所有无论我们导入何种格式的模型文件都可以用同一方式访问我们需要的模型数据。 一个非常流行的模型导入库是[Assimp](http://assimp.org/),它是**Open Asset Import Library**(开放的资产导入库)的缩写。Assimp能够导入很多种不同的模型文件格式(并也能够导出部分格式)它会将所有的模型数据加载至Assimp的通用数据结构中。当Assimp加载完模型之后,我们就能够从Assimp的数据结构中提取我们所需的所有数据了。由于Assimp的数据结构保持不变不论导入的是什么种类的文件格式它都能够将我们从这些不同的文件格式中抽象出来用同一方式访问我们需要的数据。
当导入一个模型文件时即Assimp加载一整个包含所有模型和场景数据的模型文件到一个scene对象时Assimp会为这个模型文件中的所有场景节点、模型节点都生成一个具有对应关系的数据结构且将这些场景中的各种元素与模型数据对应起来。下图展示了一个简化的Assimp生成的模型文件数据结构
当使用Assimp导入一个模型的时候它通常会将整个模型加载进一个**场景**(Scene)对象,它会包含导入的模型/场景中的所有数据。Assimp会将场景载入为一系列的节点(Node)每个节点包含了场景对象中所储存数据的索引每个节点都可以有任意数量的子节点。Assimp数据结构的简化模型如下
![](../img/03/01/assimp_structure.png) ![](../img/03/01/assimp_structure.png)
- 和材质和网格(Mesh)一样,所有的场景/模型数据都包含在<u>Scene</u>对象中。<u>Scene</u>对象也包含了场景根节点的引用。
- 场景的<u>Root node</u>(根节点)可能包含子节点(和其它的节点一样),它会有一系列指向场景对象中<var>mMeshes</var>数组中储存的网格数据的索引。<u>Scene</u>下的<var>mMeshes</var>数组储存了真正的<u>Mesh</u>对象,节点中的<var>mMeshes</var>数组保存的只是场景中网格数组的索引。
- 一个<u>Mesh</u>对象本身包含了渲染所需要的所有相关数据,像是顶点位置、法向量、纹理坐标、面(Face)和物体的材质。
- 一个网格包含了多个面。<u>Face</u>代表的是物体的渲染图元(Primitive)(三角形、方形、点)。一个面包含了组成图元的顶点的索引。由于顶点和索引是分开的,使用一个索引缓冲来渲染是非常简单的(见[你好,三角形](../01 Getting started/04 Hello Triangle.md))。
- 最后,一个网格也包含了一个<u>Material</u>对象,它包含了一些函数能让我们获取物体的材质属性,比如说颜色和纹理贴图(比如漫反射和镜面光贴图)。
- 所有的模型、场景数据都包含在scene对象中如所有的材质和Mesh。同样场景的根节点引用也包含在这个scene对象中 所以,我们需要做的第一件事是将一个物体加载到<u>Scene</u>对象中,遍历节点,获取对应的<u>Mesh</u>对象(我们需要递归搜索每个节点的子节点),并处理每个<u>Mesh</u>对象来获取顶点数据、索引以及它的材质属性。最终的结果是一系列的网格数据,我们会将它们包含在一个`Model`对象中
- 场景的根节点可能也会包含很多子节点和一个指向保存模型点云数据mMeshes[]的索引集合。根节点上的mMeshes[]里保存了实际了Mesh对象而每个子节点上的mMesshes[]都只是指向根节点中的mMeshes[]的一个引用(译者注C/C++称为指针Java/C#称为引用)
- 一个Mesh对象本身包含渲染所需的所有相关数据比如顶点位置、法线向量、纹理坐标、面片及物体的材质
- 一个Mesh会包含多个面片。一个Face面片表示渲染中的一个最基本的形状单位即图元基本图元有点、线、三角面片、矩形面片。一个面片记录了一个图元的顶点索引通过这个索引可以在mMeshes[]中寻找到对应的顶点位置数据。顶点数据和索引分开存放可以便于我们使用缓存VBO、NBO、TBO、IBO来高速渲染物体。详见[Hello Triangle](http://www.learnopengl.com/#!Getting-started/Hello-Triangle)
- 一个Mesh还会包含一个Material材质对象用于指定物体的一些材质属性。如颜色、纹理贴图漫反射贴图、高光贴图等
所以我们要做的第一件事就是加载一个模型文件为scene对象然后获取每个节点对应的Mesh对象我们需要递归搜索每个节点的子节点来获取所有的节点并处理每个Mesh对象对应的顶点数据、索引以及它的材质属性。最终我们得到一个只包含我们需要的数据的Mesh集合。
!!! Important !!! Important
**网格(Mesh)** **网格**
用建模工具构建物体时,美工通常不会直接使用单个形状来构建一个完整的模型。一般来说,一个模型由几个子模型/形状组合拼接而成。而模型中的那些子模型/形状就是我们所说的一个网格。例如一个人形模型,美工通常会把头、四肢、衣服、武器这些组件都分别构建出来,然后在把所有的组件拼合在一起,形成最终的完整模型。一个网格(包含顶点、索引和材质属性)是我们在OpenGL中绘制物体的最小单位。一个模型通常多个网格组成 当使用建模工具对物体建模的时候,艺术家通常不会用单个形状创建出整个模型。通常每个模型由几个子模型/形状组合而成。组合模型的每个单独的形状就叫做一个<def>网格</def>(Mesh)。比如说有一个人形的角色:艺术家通常会将头部、四肢、衣服、武器建模为分开的组件,并将这些网格组合而成的结果表现为最终的模型。一个网格是我们在OpenGL中绘制物体所需的最小单位(顶点数据、索引和材质属性)。一个模型通常)会包括多个网格。
下一节教程中我们将用上述描述的数据结构来创建我们自己的Model类和Mesh类用于加载和保存那些导入的模型。如果我们想要绘制一个模型,我们不会去渲染整个模型而是去渲染这个模型所包含的所有独立的Mesh。不管怎样我们开始导入模型之前,我们需要先把Assimp导入到我们的工程中。 在[下一节](02 Mesh.md)中,我们将创建我们自己的<fun>Model</fun><fun>Mesh</fun>类来加载并使用刚刚介绍的结构储存导入的模型。如果我们想要绘制一个模型,我们不需要将整个模型渲染为一个整体,只需要渲染组成模型的每个独立的网格就可以了。然而,在我们开始导入模型之前,我们首先需要将Assimp包含到我们的工程中。
## 构建Assimp ## 构建Assimp
你可以在[Assimp的下载页面](http://assimp.sourceforge.net/main_downloads.html)选择一个想要的版本去下载Assimp库。到目前为止Assimp可用的最新版本3.1.1。我们建议你自己编译Assimp库因为Assimp官方的已编译库不能很好地覆盖在所有平台上运行。如果你忘记怎样使用CMake编译一个库,请详见[Creating a window(创建一个窗口)](http://www.learnopengl.com/#!Getting-started/Creating-a-window)教程 你可以在Assimp的[下载页面](http://assimp.org/main_downloads.html)选择相应的版本。在写作时使用的Assimp最高版本3.1.1。我们建议你自己编译Assimp库因为它们的预编译库在大部分系统上都是不能运行。如果你忘记如何使用CMake自己编译一个库的话,可以复习[创建窗口](../01 Getting started/02 Creating a window.md)小节
这里我们列出一些编译Assimp时可能遇到的问题以便大家参考和排除: 构建Assimp时可能会出现一些问题所以我会将它们的解决方案列在这里便于大家排除错误
- CMake在读取配置列表时报出DirectX库丢失相关的一些错误。报错如下: - CMake在读取配置列表时不断报出DirectX库丢失错误。报错如下:
``` ```
Could not locate DirecX Could not locate DirectX
CMake Error at cmake-modules/FindPkgMacros.cmake:110 (message): CMake Error at cmake-modules/FindPkgMacros.cmake:110 (message):
Required library DirectX not found! Install the library (including dev packages) and try again. If the library is already installed, set the missing variables manually in cmake. Required library DirectX not found! Install the library (including dev packages)
and try again. If the library is already installed, set the missing variables
manually in cmake.
``` ```
这个问题的解决方案:如果你之前没有安装DirectX SDK那么请安装。下载地址:[DirectX SDK](http://www.microsoft.com/en-us/download/details.aspx?id=6812)。 这个问题的解决方案安装DirectX SDK如果你之前没安装过的话。你可以从[这里](http://www.microsoft.com/en-us/download/details.aspx?id=6812)下载SDK
- 安装DirectX SDK时可能遇到一个错误码为<b>S1023</b>的错误。遇到这个问题请在安装DirectX SDK前先安装C++ Redistributable package(s)。 - 安装DirectX SDK时可能遇到一个错误码为`s1023`的错误。这种情况下请在安装SDK之前根据[这个](http://blogs.msdn.com/b/chuckw/archive/2011/12/09/known-issue-directx-sdk-june-2010-setup-and-the-s1023-error.aspx)先卸载C++ Redistributable package(s)。
问题解释:[已知问题DirectX SDK (June 2010) 安装及S1023错误](https://blogs.msdn.microsoft.com/chuckw/2011/12/09/known-issue-directx-sdk-june-2010-setup-and-the-s1023-error/) - 一旦配置完成你就可以生成解决方案文件了打开解决方案文件并编译Assimp库可以编译为Debug版本也可以编译为Release版本只要能工作就行
- 使用默认配置构建的Assimp是一个动态库(Dynamic Library),所以我们需要包含所生成的**assimp.dll**文件以及程序的二进制文件。你可以简单地将DLL复制到我们程序可执行文件的同一目录中。
- Assimp编译之后生成的库和DLL文件位于**code/Debug**或者**code/Release**文件夹中。
- 接着把编译好的LIB文件和DLL文件拷贝到工程的相应目录下并在解决方案中链接它们。并且记得把Assimp的头文件也复制到你的**include**目录中头文件可以在从Assimp中下载的**include**目录里找到)。
- 一旦配置完成你就可以生成解决方案文件了打开解决方案文件并编译Assimp库编译为Debug版本还是Release版本根据你的需要和心情来定吧 如果你仍遇到了未报告的错误,欢迎在评论区中寻求帮助
- 使用默认配置构建的Assimp是一个动态库所以我们需要把编译出来的assimp.dll文件拷贝到我们自己程序的可执行文件的同一目录里。
- 编译出来的Assimp的LIB文件和DLL文件可以在code/Debug或者code/Release里找到。
- 把编译好的LIB文件和DLL文件拷贝到工程的相应目录下并链接到你的解决方案中。同时还好记得把Assimp的头文件也拷贝到工程里去Assimp的头文件可以在include目录里找到
如果你还遇到了其他问题,可以在下面给出的链接里获取帮助。
!!! Important !!! Important
如果你想让Assimp使用多线程支持来提高性能,你可以使用<b>Boost</b>库来编译 Assimp。在[Boost安装页面](http://assimp.sourceforge.net/lib_html/install.html)你能找到关于Boost的完整安装介绍。 如果你想让Assimp使用多线程来获得更高的性能,你可以使用Boost库来编译Assimp。你可以在它们的[安装页面](http://assimp.org/lib_html/install.html)找到完整安装介绍。
现在,你应该已经能够编译Assimp库并链接Assimp到你的工程里去了。下一步:[导入完美的3D物件](02 Mesh.md) 现在,你应该已经编译Assimp库并将它链接到你的程序中了。下一步:[导入](02 Mesh.md)漂亮的3D物体

View File

@@ -19,7 +19,6 @@
- Primitive Type基元类型 - Primitive Type基元类型
- Option选项 - Option选项
- Modern现代 - Modern现代
## 01-02 ## 01-02
- Abstract抽象 - Abstract抽象
@@ -238,6 +237,18 @@
- Cutoff Angle切光角 - Cutoff Angle切光角
- Flashlight手电筒 - Flashlight手电筒
## 03-01
- Model模型
- Import导入
- 3D Modeling Tool3D建模工具
- uv-mappingUV映射
- AssimpAssimp
- Asset资产
- Node节点
- Mesh网格
- Face
## 06-01 ## 06-01
- Debugging调试 - Debugging调试