WEBGL 2D游戏引擎研发系列 第三章 <正交视口>

作者:HTML5游戏开发者社区-白泽

转载请注明出处:http://html5gamedev.org/

目录

  • 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,朋友,上一个章节怎么样了?是不是感觉进入了新的一个领域,而且复杂度一下就上升了呢?当然了,要做高品质高帧率的游戏当然就得付出更多的努力了,教你一个小技巧,把第一章的内容背下来,这样可以在你脑海里形成一个思维体系,某一些API还不理解不要紧,经验在于实战,用多了就会感悟了,今天本章的内容是2D游戏很关键的一部分,没有这一步,就没有2D游戏,这也是2D和3D开始分解的关键点,正交视口,通常在这里你使用的引擎或者看到的教程都会告诉你需要导入一个外部库,因为这里需要矩阵的计算,在3D教程中,和本章类似的部分通常会告诉你一个3D空间的坐标系,还有一个透视的投影原理等等,不过我建议你最好还是提前了解一个大概,网上已经有很多教程了,在3D空间中,物体遵循近大远小的规律,但是在2D游戏是没有Z轴的,所以没有这个概念,并且你也不希望你的显示对象上下左右移动时会越来越小吧,所以我们会使用一个叫正交的投影原理,正交也就是除去近大远小的规律,物体投影的点始终以水平线投影到目标上,这正好符合我们2D游戏的规律,那么,你现在最需要的什么,就是一段4*4的正交视口转换的矩阵模型,下面是公式:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
 * 正交视口模型矩阵
 * @param m 正交的一维数组
 * @param left 左边界
 * @param right 右边界
 * @param bottom 底边界
 * @param top 上边界
 * @param near 近截面
 * @param far 远截面
 */
function orthoM(m,left,right,bottom,top,near,far)
{
    m[0] = 2.0*1.0/(right - left);
    m[5] = 2.0*1.0/(top - bottom);
    m[10] = 1.0/(far - near);
  
    m[12] = (right + left)/(right - left);
    m[13] = (bottom + top)/(bottom - top);
    m[14] = near/(near - far);
  
    m[1] = m[2] = m[3] = m[4] =m[6] = m[7] = m[8] = m[9] = m[11] = 0;
    m[15] = 1.0;
}

实际上4*4的矩阵是二维的,为什么我们要使用一维的呢,因为如果你考虑跨平台通用性,就必须考虑使用一维的数组,有一些平台是只支持一维数组,现在你需要创建这么一个数组

打开DisplayerObjectGL.js

加入新的变量

?
1
2
//正交矩阵
var oRMatrixList=[];

为了使用正交矩阵的公式,你还需要一个场景的宽度和高度的比例

?
1
var ratio=1024/768;

然后在刷新函数里去调用这个函数

?
1
orthoM(oRMatrixList,-ratio,ratio,-1,1, -10, 1000);

第一个参数我们把刚才初始化的一维数组传递进来,第二个参数是左右的缩放的系数,通常我们使用场景的高度为确定值,宽度则是利用场景的宽度/高度这样的系数动态改变,通常的参数分为左边和右边,后面的-1,1是高度比,上面和下面,这里有一个小技巧你可以同时给这4个参数加上一个值来做镜头的移动,最后2个参数是近截面和远截面,什么意思呢?因为我们人类观察物体是有一个盲区的,比如,你可以把你的手机近距离的靠近你的眼睛,这时候你是看不清楚手机的,你甚至无法分辨它是一个手机还是一个其他的物体,并且会产生重影,如果你把手机放远了看,你一样是看不清,所以我们人类观察任何物体都是在离人眼一定距离和范围之内的,在3D中,小于这个范围的为了节省性能会被删除掉不显示,远了也一样,否则显示器不像人眼,你永远无法让你的手机无限的靠近你的眼球,因为你有鼻梁,有骨骼,而在显示器里则会无限制的放大,但其实这是无意义的,所以你在玩某个3D游戏穿越某个物体时它在一定的距离后会消失不见就是这个原因.现在,正交视口通过我们的公式已经处理完毕了,我们需要上传到顶点着色器 :

?
1
2
3
//上传正交矩阵,先在着色器中查询对应的矩阵寄存器名称然后把结果上传,后面的参数是否转置矩阵,默认吧,最后的参数是接受
    //一个一维数组,也就是我们计算4*4的矩阵,长度为16的一维数组
    gl.uniformMatrix4fv(gl.getUniformLocation(shaderProgram, "oRMatrix"),false,oRMatrixList);

我们把矩阵信息传递给一个叫oRMatrix的寄存器,我们最终需要让这个矩阵寄存器和我们的坐标向量相乘,比如这样

?
1
2
3
4
5
6
7
8
9
10
11
12
//正交矩阵,注意了,类型不同了,这里是mat4,也就是4*4的矩阵意思
   uniform mat4 oRMatrix;
   //执行的代码片段放这里
   void main(void) {
       //gl_Position是内置寄存器,它是一个4维的寄存器,但实际上我们的2D游戏只用到了2维,所以我们可以强制转换类型,
       //把前面2维的寄存器丢进去,因为还有剩下的2维,所以你可以填入默认值,1,1
       //把矩阵和坐标向量相乘得出了最终的坐标
       gl_Position =  oRMatrix*vec4(aVertexPosition,1.0,1.0);
       //这是一个神奇的过程,你看不到插值计算你只要把UV信息给这个寄存去,它传递到像素着色器时再获取就是插值后的坐标了
       vTextureCoord = aTextureUv;
   }

如果你的代码没有出现问题的话,现在你的画面应该是这个样子了

发现区别了吗,我们的图像不再填充整个画面,而是显示出了正确的宽度高度比,这就是正交视口的功能,但是还是不对,我们上传的图片是512*512的,这里明显大了哦,那是因为我们的顶点坐标还没有改变,我们现在的四角形的高也就是2,2是等于场景的高度的,也就算是768,所以我们需要计算出512实际在768的比例是多少,比如512/768,然后让顶点坐标都乘以这个比例系数

?
1
2
3
4
5
6
var vertices = [
       -1.0*512/768, -1.0*512/768,//左下角
       1.0*512/768, -1.0*512/768,//右下角
       1.0*512/768,  1.0*512/768,//右上角
       -1.0*512/768,  1.0*512/768//左上角
   ];

看到了吗,很简单,为了方便你的观看,我就直接写在这里了,但实际上在引擎中,这里的只是需要交给一个矩阵去代理的,因为你最终需要通过顶点对这个显示对象去旋转缩放倾斜等等,加入这段代码之后你现在显示的图片应该就是正常的大小了

因为本教程是以最简短的方式呈现的代码,所以里面的结构不代表最终的引擎结构,有很多细节是需要优化的,而这些优化是直接关系到你的引擎效率问题,但是目前来看,我们暂时不需要关注,重要的是你是否掌握了使用方法呢?下一章节,我们需要自己写一个矩阵类,来操作这个图片了,有了它就可以实现游戏的基本功能了,下面是DEMO和源码地址,演示地址建议用谷歌浏览器打开.

在线演示 源码下载

转载请注明:HTML5游戏开发者社区 » WEBGL 2D游戏引擎研发系列 第三章 <正交视口>

WEBGL 2D游戏引擎研发系列 第三章 正交视口相关推荐

  1. WEBGL 2D游戏引擎研发系列 第四章 感想以及矩阵

    WEBGL 2D游戏引擎研发系列 第四章 <感想以及矩阵> HTML5游戏开发者社区(群号:326492427) 转载请注明出处:http://html5gamedev.org/ HTML ...

  2. WEBGL 2D游戏引擎研发系列 第一章 新的开始

    WEBGL 2D游戏引擎研发系列 第一章 <新的开始> ~\(≥▽≤)/~HTML5游戏开发者社区(群号:326492427) 转载请注明出处:http://html5gamedev.or ...

  3. HTML5 2D游戏引擎研发系列 第五章

    HTML5 2D游戏引擎研发系列 第五章 <Canvas技术篇-画布技术-纹理集复杂动画> 作者:HTML5游戏开发者社区-白泽 转载请注明出处:http://html5gamedev.o ...

  4. HTML5 2D游戏引擎研发系列 第四章 Canvas技术篇-画布技术-基于手动切片动画

    作者:HTML5游戏开发者社区-白泽 转载请注明出处:http://html5gamedev.or HTML5 2D游戏引擎研发系列 第四章 <Canvas技术篇-画布技术-基于手动切片动画&g ...

  5. HTML5 2D游戏引擎研发系列 第一章

     HI,大家好,我是白泽,一名游戏设计师,一直专注各平台的2D游戏引擎研发,HTML5是我准备进入的新领域,我有个习惯,刚接触的新领域我都会习惯自己写一套游戏引擎,而不用第三方提供的,为了方便自己学习 ...

  6. 如何用UE4制作2D游戏文档(三)——角色篇

    一.前言 首先感谢B站马克镇镇长的视频讲解清晰把很多细节都照顾到了,我本来自己做的时候没有视频说的那么细,参考他的全套系列视频之后完善了很多内容. 视频指路:https://www.bilibili. ...

  7. 对金玺曾版《Unity3D手机游戏开发》第三章“第一人称射击游戏”修改,使支持僵尸连续攻击

    我个人觉得这本书写的至少很和我口味,而且他的光盘资料也很详尽,比如,一个实例,不仅有一个完整的实现工程,还有一份供作练习的工程(该工程中没有要练习的部分,而资源啥的都有),让人感觉很好. 这本书下载电 ...

  8. jQuery系列 第三章 jQuery框架操作CSS

    第三章 jQuery框架操作CSS 3.1 jQuery框架的CSS方法 jQuery框架提供了css方法,我们通过调用该方法传递对应的参数,可以方便的来批量设置标签的CSS样式. 使用JavaScr ...

  9. SwiftUI 教程系列-第三章

    第三章: 用Swift语言和SwiftUI框架创建你的第一个app ​ 到目前为止, 你应该对xcode工具和swift语言有所了解,如果你没看过前面2节, 建议先看看,这章,会深入了解一下Swift ...

最新文章

  1. Ubuntu 中的 dpkg 安装deb、删除deb、显示已安装包列表、解压deb文件、显示deb包内文件列表、配置deb软件包
  2. 论文翻译 | Mask-SLAM:基于语义分割掩模的鲁棒特征单目SLAM
  3. 科学出版社c语言实验答案,程序设计基础c语言第三章程序结构教材习题答案科学出版社...
  4. java生成dex_Java反编译Dex – jadx
  5. 问题解决: 此文件来自其他计算机,可能被阻止以帮助保护该计算机
  6. python中stacked_python – Django管理员StackedInline定制
  7. 优秀的程序员是如何处理技术 Bug 的?
  8. 编译GDAL使用最新的HDF库配置文件
  9. SciPy 积分 | Python技能树征题
  10. vue实现搜索框搜索新增_基于Vue el-autocomplete 实现类似百度搜索框功能_含真_前端开发者...
  11. 数据挖掘常用聚类算法性能比较
  12. Nodejs Web模块( readFile 根据请求跳转到响应html )
  13. Kettle (1) - 读取 CSV 文件
  14. 2019年Robomaster江苏省赛总结
  15. IE11不兼容css3渐变属性
  16. Chrome浏览器通过EasyPlayer播放多路flv视频流后浏览器崩溃是什么原因?
  17. StackOverflowError与OutOfMemoryError区别
  18. 用python可以免费下载音乐吗-使用python实现下载我们想听的歌曲,速度超快
  19. 英文网站推广常用方法有哪些
  20. MERGER INTO语法

热门文章

  1. html如何调用特殊字体,网页中如何调用一些特殊字体或艺术字体?
  2. hp rx8640_使用rx-java的异步抽象
  3. 思科ASA5520防火墙telnet、SSH及DHCP设置
  4. iphone 开发之过滤html标签
  5. eladmin 后台管理 -- 登录
  6. windows10自带输入法变成了繁体怎么改回来
  7. iOS开发者申请发布证书及真机调试 图文详解
  8. python 斗地主(1)
  9. Win10无法登录微软账号错误代码0x80190001的解决方法
  10. 18650锂电池的充电规则