Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions 02.2-Flyweight.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Tags: 游戏编程 设计模式 游戏开发
#再探Flyweight模式
============================
迷雾消散,一个古老而壮丽的原始森林呈现在了我们的面前。不计其数的古老的铁杉,像一座塔尖林立的绿色大教堂。在巨大的树干面前,以至于,你只有往后拉开一段距离,才能从树干之间的缝隙中辨认出这是一个巨大的森林。
这是游戏开发者梦想中的世外桃源般的设计,而正是一个设计模式使得这一梦想中的场景得以在现实中得到实现。而这个模式的名字却再低调不过了:Flayweight(享元模式)。
这是游戏开发者梦想中的世外桃源般的设计,而正是一个设计模式使得这一梦想中的场景得以在现实中得到实现。而这个模式的名字却再低调不过了:Flyweight(享元模式)。
#化木为林
我可以很轻描淡写地就描绘了一个无边的森林场景,但是在一个实时的游戏中实现起来就是另一回事了。你在电脑前看到的是满屏的树木,而在图形程序员的严重,他们却是数以百万计的多边形,这些多边形必须以1/60秒的速度载入到GPU中。

Expand Down Expand Up @@ -59,7 +59,7 @@ private:
class Tree
{
private:
**TreeModel*** model_;
TreeModel* model_;

Vector position_;
double height_;
Expand All @@ -71,7 +71,6 @@ private:
对于上面的代码,你可以想象成如下方式:

![此处输入图片的描述][2]

这样处理之后,就很好的解决了在内存中的存储问题,但是这个方式对渲染于事无补。在森林被画到屏幕上之前,它必须要先被传入GPU,我们需要把共享的资源展开成显卡能够识别的格式。

#一千个实例
Expand All @@ -81,14 +80,14 @@ private:

在这两个平台提供的API中,你需要提供两个数据流。第一个是将被渲染多次的公用数据块——我们例子中的模型和纹理。第二个数据流包含了一个实例列表以及它们个性化的参数,它们可以将每棵树都区分处理。这样,经过一次绘制,整个森林就长出来了。

#Flyweiht模式
#Flyweight模式
现在,我们手里有了一个例子,接下来让我们来演练一下,看看你是否真的掌握了这个设计思想。Flyweight,就像它的名字一样,主要适用于当我们有大量的对象需要被缩减的时候。

通过*instance rendering* 技术,我们可以不再占用过多的内存,就像不再占用过多的总线传送时间一样。其基本思路是一致的。

Flayweight模式通过将一个对象的数据分成两类来解决问题。第一类不是单个实例个性化的数据,他们可以在所有实例间共享。GoF把这类数据叫做固有属性,但我更喜欢称之为*上下文无关*。在这个例子里,就是那些树的几何模型和纹理贴图。

剩下的数据就是外部属性,这部分每一个实例都是独一无饿=二的。在这个例子中,就是树的位置、大小、颜色。就像上面那段代码展示的那样,这个模式通过在每一个出现的对象中共享固定属性,来达到节省内存的目的。
剩下的数据就是外部属性,这部分每一个实例都是独一无二的。在这个例子中,就是树的位置、大小、颜色。就像上面那段代码展示的那样,这个模式通过在每一个出现的对象中共享固定属性,来达到节省内存的目的。

到现在为止,这个方法就像是最基本的资源共享,其实很难被称之为一个设计模式。这可能使因为在这个例子中,我们很容易地分辨出哪一部分应该共享:*TreeModel*

Expand Down