鸿 网 互 联 www.68idc.cn

WEBGL 2D游戏引擎研发系列 第五章 <操作显示对象>

来源:互联网 作者:佚名 时间:2015-08-10 07:52
HTML5 2D游戏引擎研发系列 第一章 一切的开始 HTML5 2D游戏引擎研发系列 第二章 磨剑 HTML5 2D游戏引擎研发系列 第三章 Canvas技术篇-画布技术-显示图片 HTML5 2D游戏引擎研发系列 第四章Canvas技术篇-画布技术-基于手动切片动画 HTML5 2D游戏引擎研发系列
  • HTML5 2D游戏引擎研发系列  第一章 <一切的开始>
  • HTML5 2D游戏引擎研发系列 第二章 <磨剑>
  • HTML5 2D游戏引擎研发系列 第三章 <Canvas技术篇-画布技术-显示图片>
  • HTML5 2D游戏引擎研发系列 第四章 <Canvas技术篇-画布技术-基于手动切片动画>
  • HTML5 2D游戏引擎研发系列 第五章 <Canvas技术篇-画布技术-纹理集复杂动画>
  • HTML5 2D游戏引擎研发系列 第六章 <Canvas技术篇-画布技术-混色特效和粒子>
  • HTML5 2D游戏引擎研发系列 第七章 <Canvas技术篇-画布技术-鼠标侦听器>
  • HTML5 2D游戏引擎研发系列 第八章 <Canvas技术篇-基于顶点绘制与变形>
  • WEBGL 2D游戏引擎研发系列 第一章 <新的开始>
  • WEBGL 2D游戏引擎研发系列 第二章 <显示图片>
  • WEBGL 2D游戏引擎研发系列 第三章 <正交视口>
  • WEBGL 2D游戏引擎研发系列 第四章 <感想以及矩阵>
  • WEBGL 2D游戏引擎研发系列 第五章 <操作显示对象>
  • WEBGL 2D游戏引擎研发系列 第六章 <第一次封装>
  • WEBGL 2D游戏引擎研发系列 第七章 <混色>
  • WEBGL 2D游戏引擎研发系列 第八章 <批处理(影分身之术)>
  • WEBGL 2D游戏引擎研发系列 第九章 <基于UV的模拟切片>
  • WEBGL 2D游戏引擎研发系列 第十章 <纹理集动画>
  • WEBGL 2D游戏引擎研发系列 第十一章 <着色器-shader>
  • WEBGL 2D游戏引擎研发系列 第十二章 <粒子发射器>
  • WEBGL 2D游戏引擎研发系列 第十三章 <Shader分享>
  • 游戏技法 2D游戏引擎研发系列 第一章 <优化技巧>
  • 游戏技法 2D游戏引擎研发系列 第二章 <计时器>
  • 游戏技法 2D游戏引擎研发系列 第三章 <基于UV的无缝图像滚动>
  • 游戏技法 2D游戏引擎研发系列 第四章 <基于形状的碰撞检测>

                   HI,大家好,本章的内容我们就要开始动手写矩阵了,如果你理解了上一章的内容那本章的内容其实很简单了,有了矩阵的支持,我们的游戏引擎也就有了基本的雏形了,2D游戏中不管是什么类型的游戏,多么复杂的游戏,始终都离不开各种变换,比如旋转,缩放,倾斜,位移等等,所以只要我们把理解了这个就不会害怕引擎的开发了,可以说它甚至比开发一款游戏还简单,当然好的引擎是需要强大的效率和各种出彩的功能,但核心的本质就是变换,在开始讲解代码前,先告诉你一个使用矩阵变换最基本也是最核心的理论,叫指定式变换递增式变换,好吧,这又是我自己创造的词语,我不知道其他引擎开发者是怎么称呼他们的,现在我来解释一下,通常我们的游戏开发都是指定式变换,比如 mc.x=32,mc.rotation=45,mc.scaleX=2,这些变换的参数都是我们手动指定的,可能会用一个变量去代替他们,而这个指定我们通常会放在一个游戏循环里,所以mc.x=32的指定不管游戏循环多少次循环间隔是多少,mc的x始终是等于32的,因为这样我们才能方便的控制游戏的逻辑32什么时候变成其他的值,所以这个32是等待游戏的逻辑操作才会变化,也就是说这样游戏中所有的显示对象的变换值都是等待游戏前端的逻辑改变而改变,那么递增式变换则相反,它不会等待游戏的逻辑,而它更加是过程式的命令,也就是执行一次操作它的结果就会改变一次,而下一次操作是基于上一次操作的结果,比如第一指定mc.x=32,那么它mc.x的内部值就是32了,如果你再执行一次mc.x=32,那它的内部结果就是等于上一次的32+32=62,如此反复,当你把这句话放在游戏循环里时那么不用多久你的游戏所有显示对象都会消失不见,离开了画面,造成递增式的变换原因是我们每次都存储了上一次的运算结果,聪明的你是否已经发觉我要讲什么了?实际上我们的矩阵是不关心具体的目标点坐标信息的,它只关心的是A变换后到B,它只是关心过程,比如我们让A点(1,1),X位移5个单位,Y位移3个单位,这部分的操作就是矩阵负责的,它不关心你的目标点和最终点,它只负责你当前的点如何变换,所以这次变换后的结果A点等于(6,4)也就是在原坐标1,1的基础之上变换,如果你下一次再操作矩阵变换,那么A的结果就是(6+5,4+3),明白了吧,因为我们把A点的坐标信息存储下来了当作下一次的变换的基础值,现在我们有一个很好的解决方案,就是存储A点的初始化坐标,每次矩阵变换都是以初始化的坐标为起始点,这样就可以防止递增式的变换,如果用文字描述,我们可以分别这样描述,指定式变换=现在我们把A点移动到(5,3)这个位置,这是指定的坐标点,所以必须有一个坐标系和参考值,坐标系你可以用笛卡尔坐标系,用0,0为参考点或者叫原点,因为只有这样你才知道5,3究竟在什么位置,递增式变换=现在我们让A点X移动5个单位,Y移动3个单位,很明显了,这样的描述是不需要参考值或原点的,它不关心A点目前在什么位置,只关心往什么方向位移,好了,解释这么多,我相信你应该清楚了,我们的矩阵变换会经常用到这2个变换,所以我们使用矩阵变换时记得保留对象顶点的初始坐标,通常情况下我们不会改变它的初始坐标,但是比如需要设置显示对象的偏移量,内部旋转角度等等才会需要改变初始坐标,而在后面的基于XML的动画我们会经常用到偏移坐标这个属性,现在打开你DisplayerObjectGL.js,让我们添加新的代码,

Point2D类,用于存储我们的顶点

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
 * 2D点对象
 *
 */
function Point2D(){
    this.mX=0;
    this.mY=0;
    this.getX=function() {
        return this.mX;
    }
    this.setX=function(value) {
        this.mX = value;
    }
    this.getY=function() {
        return this.mY;
    }
    this.setY=function(value) {
        this.mY = value;
    }
}

Matrix2D 矩阵类,用于矩阵的计算

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/**
 * 矩阵类,矩阵的计算是你的引擎里面消耗最多的地方,所以也是重点优化的地方,矩阵优化得好对因的引擎效率提升非常大,现在我们使
 * 用的矩阵类是完全原始未优化的,它与优化后的效率相差非常之大,不过这个我会放在后面的优化篇讲解,为了不使你混乱,目前可以
 * 不用关注,只需要关注原理就好
 */
function Matrix2D(){
    //矩阵的原始信息
    this.rawData=[];
    //矩阵的旋转存储信息
    this.spinArray=[];
    //矩阵的位移缩放倾斜存储信息
    this.translationArray=[];
  
    /**
     * 重置矩阵
     */
    this.identity=function()
    {
        this.translationArray = [];
        this.spinArray = [];
        this.rawData = [];
    }
  
    /**
     * 3*3矩阵融合
     */
    this.add33=function(v1,v2)
    {
        var m33 = [];
        m33[0]=v1[0]*v2[0]+v1[1]*v2[3]+v1[2]*v2[6];
        m33[1]=v1[0]*v2[1]+v1[1]*v2[4]+v1[2]*v2[7];
        m33[2]=v1[0]*v2[2]+v1[1]*v2[5]+v1[2]*v2[8];
  
        m33[3]=v1[3]*v2[0]+v1[4]*v2[3]+v1[5]*v2[6];
        m33[4]=v1[3]*v2[1]+v1[4]*v2[4]+v1[5]*v2[7];
        m33[5]=v1[3]*v2[2]+v1[4]*v2[5]+v1[5]*v2[8];
  
        m33[6]=v1[6]*v2[0]+v1[7]*v2[3]+v1[8]*v2[6];
        m33[7]=v1[6]*v2[1]+v1[7]*v2[4]+v1[8]*v2[7];
        m33[8]=v1[6]*v2[2]+v1[7]*v2[5]+v1[8]*v2[8];
        return m33;
    }
  
    /**
     * 1*3矩阵融合
     */
    this.add13=function(v1,v2)
    {
        var m13 = [];
        m13[0]=v1[0]*v2[0]+v1[1]*v2[3]+v1[2]*v2[6];
        m13[1]=v1[0]*v2[1]+v1[1]*v2[4]+v1[2]*v2[7];
        m13[2]=v1[0]*v2[2]+v1[1]*v2[5]+v1[2]*v2[8];
        return m13;
    }
  
    /*
     *旋转
     */
    this.appendRotation=function(rotation)
    {
        var cos = Math.cos(rotation * Math.PI / 180);
        var sin = Math.sin(rotation * Math.PI / 180);
        //旋转
        this.spinArray[0]=cos;
        this.spinArray[1]=sin;
        this.spinArray[2]=0;
        this.spinArray[3]=-sin;
        this.spinArray[4]=cos;
        this.spinArray[5]=0;
        this.spinArray[6]=0;
        this.spinArray[7]=0;
        this.spinArray[8]=1;
    }
  
    //平移,缩放,倾斜
    this.appendTranslation=function(x,y,scaleX,scaleY,biasX,biasY)
    {
        this.translationArray[0]=scaleX;
        this.translationArray[1]=biasY;
        this.translationArray[2]=0;
        this.translationArray[3]=biasX;
        this.translationArray[4]=scaleY;
        this.translationArray[5]=0;
        this.translationArray[6]=x;
        this.translationArray[7]=y;
        this.translationArray[8] = 1;
    };
  
    /**
     * 更新矩阵信息
     */
    this.upDataBasrMatrix=function(rotation,x,y,scaleX,scaleY,biasX,biasY)
    {
        //计算旋转后的矩阵
        this.appendRotation(rotation);
  
        //计算位移等其他变换后的矩阵
        this.appendTranslation(x,y,scaleX,scaleY,biasX,biasY);
  
        //融合这2个变换矩阵
        this.rawData = this.add33(this.spinArray,this.translationArray);
    }
  
}

Panel类,实际上我们需要再矩阵基础之上再封装一层,我们可以把顶点add到这个面板中去,然后对这个面板进行矩阵的操作,通常这个面板会存放4个顶点,但理论上你可以addN个顶点来实现特定的效果

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
/**
 * 矩阵代理面板类,我们会把顶点push到这个面板类里,从而对这个面板实现顶点的变换操作
 */
function Panel()
{
    /**
     * 属性集合
     */
    this.mX = 0;
    this.mY= 0;
    this.mRotation = 0;
    this.mScaleX = 1;
    this.mScaleY = 1;
    this.mBiasX = 0;
    this.mBiasY = 0;
    this.mPivotX = 0;
    this.mPivotY = 0;
  
    //矩阵
    this.matrix2D=new Matrix2D();
  
    //元素列表
    this.itemList=[];
  
    //元素信息列表
    this.itemData=[];
  
    //原始元素信息列表
    this.itemDataAgency=[];
  
    //这个属性用于存放最终计算的出来的点,也就是屏幕上最终的坐标,[0]代表X,[1]代表Y,实际上这可以是一个对象
    this.point=[];
  
    //记录当前面板中有多少个点对象
    this.ids=0;
  
    /**
     * 获取矩阵信息
     */
    this.getMatrix2D=function()
    {
        return this.matrix2D;
    }
  
    /**
     * 设置矩阵信息
     */
    this.setMatrix2D=function(matrix2D)
    {
       this.matrix2D = matrix2D;
    }
  
    /**
     * 更新顶点缓存信息
     */
    this.upDataFrame=function(p)
    {
        this.itemData[this.ids]=new Point2D();
        this.itemData[this.ids].setX(p.getX());
        this.itemData[this.ids].setY(p.getY());
  
        this.itemDataAgency[this.ids]=new Point2D();
        this.itemDataAgency[this.ids].setX(p.getX());
        this.itemDataAgency[this.ids].setY(p.getY());
    }
  
    /**
     * 获得点数据
     */
    this.setPoint=function(value,point)
    {
        this.itemData[value]=point;
    }
  
    /**
     * 设置点数据
     */
    this.getPoint=function(value)
    {
        return this.itemData[value];
    }
  
    /**
     * 更新矩阵操作
     */
    this.upDataRaw=function()
    {
        for (var i = 0; i <this.ids; i++)
        {
            //零时缓存顶点的信息,实际上这一步在后期的优化中可以省略掉,毕竟每次做这样的操作还是很消耗的
            var cacheList=[];
            cacheList[0]=this.itemDataAgency[i].getX();
            cacheList[1]=this.itemDataAgency[i].getY();
            cacheList[2]=1;
  
            //存储1*3的矩阵计算后结果,也就是实际计算出来的屏幕坐标
            var point = this.matrix2D.add13(cacheList,this.matrix2D.rawData);
  
            //改变缓存里的顶点的坐标信息
            this.itemList[i].setX(point[0]);
            this.itemList[i].setY(point[1]);
        }
    }
  
    /**
     * 更新矩阵操作
     */
    this.upDataMatrix=function()
    {
        //根据输入的信息更新矩阵
        this.matrix2D.upDataBasrMatrix(this.mRotation,this.mX + this.mPivotX, this.mY + this.mPivotY, this.mScaleX,this.mScaleY, this.mBiasX, this.mBiasY);
        //然后更新顶点信息
        this.upDataRaw();
    }
  
    /**
     * 更新顶点的原始顶点坐标
     */
    this.upDataMatrixData=function(pivotX,pivotY,scaleX,scaleY,biasX,biasY)
    {
        this.matrix2D.upDataBasrMatrix(0,pivotX,pivotY, scaleX, scaleY, biasX, biasY);
        for (var i = 0; i <this.ids; i++)
        {
            var cacheList=[];
            cacheList[0]=this.itemData[i].getX();
            cacheList[1]=this.itemData[i].getY();
            cacheList[2]=1;
            var point = this.matrix2D.add13(cacheList,matrix2D.rawData);
            this.itemDataAgency[i].setX(point[0]);
            this.itemDataAgency[i].setY(point[1]);
        }
    }
  
    /**
     * 添加元素
     */
    this.addItem=function(obj)
    {
        this.itemList[this.ids]=obj;
        this.upDataFrame(obj);
        this.ids++;
    }
  
    /**
     * 更改或读取面板X坐标
     */
    this.getX=function(){return this.mX;};
    this.setX=function(value)
    {
        this.mX = value;
    }
  
    /**
     * 更改或读取面板Y坐标
     */
    this.getY=function() {return this.mY;};
    this.setY=function(value)
    {
         this.mY = value;
    }
  
    /**
     * 更改或读取面板角度
     */
    this.getRotation=function(){return this.mRotation;};
    this.setRotation=function(value)
    {
         this.mRotation = value;
    }
  
    /**
     * 更改或读取面板X比例
     */
    this.getScaleX=function() {return this.mScaleX;};
    this.setScaleX=function(value)
    {
        this.mScaleX = value;
    }
  
    /**
     * 更改或读取面板Y比例
     */
    this.getScaleY=function(){return this.mScaleY;};
    this.setScaleY=function(value)
    {
        this.mScaleY = value;
    }
  
    /**
     * 更改或读取面板X倾斜度
     */
    this.getBiasX=function() {return this.mBiasX;};
    this.setBiasX=function(value)
    {
        this.mBiasX = value;
    }
  
    /**
     * 更改或读取面板Y倾斜度
     */
    this.getBiasY=function(){return this.mBiasY;};
    this.setBiasY=function(value)
    {
        this.mBiasY = value;
    }
  
    /**
     * 更改或读取面板X偏移值
     */
    this.getPivotY=function() {return this.mPivotY;};
    this.setPivotY=function(value)
    {
        this.mPivotY = value;
    }
  
    /**
     * 更改或读取面板Y偏移值
     */
    this.getPivotX=function(){return this.mPivotX;};
    this.setPivotX=function(value)
    {
        this.mPivotX = value;
    }
}

最后,创建4个变量来存储上一章节我们固定写死的坐标吧,然后把这4个坐标push到这个面板里,比如这样

定义4个顶点和一个面板

?
1
2
3
4
5
var right_down_point;
var right_up_point;
var left_down_point;
var left_up_point;
var panel;

然后创建一个新的初始化函数

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//初始化坐标信息
function initData()
{
    //创建4个顶点
    right_down_point=new Point2D();
    right_up_point=new Point2D();
    left_down_point=new Point2D();
    left_up_point=new Point2D();
  
    //创建一个面板
    panel=new Panel();
  
    //设置4个顶点的初始化坐标
    left_down_point.setX(-1.0*512/768);
    left_down_point.setY(-1.0*512/768);
  
    right_down_point.setX(1.0*512/768);
    right_down_point.setY(-1.0*512/768);
  
    left_up_point.setX(-1.0*512/768);
    left_up_point.setY(1.0*512/768);
  
    right_up_point.setX(1.0*512/768);
    right_up_point.setY(1.0*512/768);
  
    //添加到面板里
    panel.addItem(right_down_point);
    panel.addItem(right_up_point);
    panel.addItem(left_down_point);
    panel.addItem(left_up_point);
  
    //测试,旋转面板
    panel.setRotation(45);
    //缩放面板
    panel.setScaleX(.5);
    panel.setScaleY(.5);
  
    //更新面板的矩阵信息
    panel.upDataMatrix();
}

然后在initBuffers函数里更改上传顶点的代码

?
1
2
3
4
5
6
var vertices = [
        left_down_point.getX(),left_down_point.getY(),//左下角
        right_down_point.getX(),right_down_point.getY(),//右下角
        right_up_point.getX(), right_up_point.getY(),//右上角
        left_up_point.getX(), left_up_point.getY()//左上角
    ];

最后再初始化函数里加入我们新的函数

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//启动函数
function webGLStart() {
  
    //初始化坐标信息
    initData();
  
    //初始化WEBGL和画布
    initGL();
  
    //初始化顶点数据缓存
    initBuffers();
  
    //初始化纹理
    initTexture();
  
    //初始化着色器
    initShaders();
  
    //游戏循环渲染
    setTimeout(drawScene,0);
  
}

因为我在初始化坐标信息函数里写了几个测试代码,让面板旋转45度,并且XY轴缩放0.5,如果你的代码没有错误,那么看起来应该就是这样了

 

激动吗,我们现在可以像之前操作显示对象一样去操作WEBGL的内容了,但这个效果只运动一次而已,因为我们实际上只是在初始化对顶点的缓存做了更改,实际操作中,你需要动态的更改这个缓存数组再上传到GPU,,如果你像我一样迫不及待的话,你可以在循环函数drawScene加入这几段代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
var angle=0;
//渲染函数,这里是循环调用的
function drawScene() {
  
    //指定面板旋转的角度
    angle+=1;
  
    //设置面板的角度
    panel.setRotation(angle);
  
    //别忘了操作面板后记得统一的更新的,这里是一个后期优化的重点,不过目前来说你可以不用理会
    panel.upDataMatrix();
  
    //这里只是测试代码,在实际操作中,不会反复创建顶点缓存,但是会根据顶点数据更改去更新缓存里的数据,如果你迫不及待想
    //看到效果或者你的电脑内存够大的话,你可以先加入这段初始化代码看看效果
    initBuffers();
  
    //清理画面
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  
    //上传顶点数据到WEBGL的状态机
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer);
  
    //设置顶点着色器接受缓存的数组并且上传到着色器,我们只用了二维,所以是2,类型为浮点数,flase是不需要转换为单位向量,这个
    //矩阵会用到,或者是法线贴图的数据,现在用不到,后面是开始位置和间隔位置,实际上你可以在一个缓存数组里放所有的信息
    //这样理论上会节省空间和提升效率,但我在其他平台上测试,分开的优势比较大,WEBGL的还没有测试过,现在默认是0,0
    gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,2, gl.FLOAT, false, 0, 0);
  
    //同上理,上传UV信息到WEBGL状态机
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexTextureUvdBuffer);
    //同上理
    gl.vertexAttribPointer(shaderProgram.textureCoordAttribute,2, gl.FLOAT, false, 0, 0);
  
    //上传纹理信息到WBEGL状态机
    gl.bindTexture(gl.TEXTURE_2D, newTexture);
  
    //这里是一个坑,因为是面向过程的,循序不能错,把纹理上传到WEBGL状态机后,要紧接着上传到着色器,uSampler是和像素着色器对应
    //好的寄存器名称,后面的参数,没见过,默认吧,默认吧,
    gl.uniform1i(gl.getUniformLocation(shaderProgram,"uSampler"), 0);
  
    //第一个参数我们把刚才初始化的一维数组传递进来,第二个参数是左右的缩放的系数,通常我们使用场景的高度为确定值,宽度则
    // 是利用场景的宽度/高度这样的系数动态改变,通常的参数分为左边和右边,后面的-1,1是高度比,上面和下面,这里有一个小技巧
    // 你可以同时给这4个参数加上一个值来做镜头的移动,最后2个参数是近截面和远截面,什么意思呢?因为我们人类观察物体是有一
    // 个盲区的,比如,你可以把你的手机近距离的靠近你的眼睛,这时候你是看不清楚手机的,你甚至无法分辨它是一个手机还是一个
    // 其他的物体,并且会产生重影,如果你把手机放远了看,你一样是看不清,所以我们人类观察任何物体都是在离人眼一定距离和范
    // 围之内的,在3D中,小于这个范围的为了节省性能会被删除掉不显示,远了也一样,否则显示器不像人眼,你永远无法让你的手机
    // 无限的靠近你的眼球,因为你有鼻梁,有骨骼,而在显示器里则会无限制的放大,但其实这是无意义的,所以你在玩某个3D游戏穿
    // 越某个物体时它在一定的距离后会消失不见就是这个原因.
    orthoM(oRMatrixList,-ratio,ratio,-1,1, -10, 1000);
  
    //上传正交矩阵,先在着色器中查询对应的矩阵寄存器名称然后把结果上传,后面的参数是否转置矩阵,默认吧,最后的参数是接受
    //一个一维数组,也就是我们计算4*4的矩阵,长度为16的一维数组
    gl.uniformMatrix4fv(gl.getUniformLocation(shaderProgram, "oRMatrix"),false,oRMatrixList);
  
    //上传顶点索引到WBEGL状态机
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer);
    //通过刚上传的顶点索引绘制三角形,一共有6个顶点,类型为整形,间隔为0
    gl.drawElements(gl.TRIANGLES,6, gl.UNSIGNED_SHORT, 0);
  
    //循环调用
    setTimeout(drawScene,0);
}

如果没有出错,你的图片现在应该就旋转起来,多么令人兴奋的旋转啊,好了,下面是本章的DEMO和代码,建议使用谷歌浏览器

在线演示 源码下载

HTML5游戏开发者社区 ? WEBGL 2D游戏引擎研发系列 第五章 <操作显示对象>

网友评论
<