世界变化真快,前段时间windows开发技术热还在如火如荼,web技术就开始来势汹汹,正当web呈现欣欣向荣之际,安卓小机器人,咬过一口的苹果,winPhone开发平台又如闪电般划破了混沌的web世界。

相信很多开发者都在疑问,为什么世界不是围着我转?而是我在围着世界转。我的答案是,少林寺的和尚学打架,首先要学会站桩。要练功,先占三年桩。少林寺的和尚打架从来不围着别人转,而是别人围着他转。

世界的原理都是相通的,开发者一样,要做到脚下生根。

最近几天在看OpenGL的投影矩阵,自己也实现了一个投影矩阵:

【1 0 0 0】

【0 1 0 0】

【0 0 1 1/d]

[0 0 0 0]

其中d代表的是近平面的距离也就是near。

做任何事情,必须带着疑问去学习,这是我的原则,不然就不要学,尽信书不如无书,是懂非懂不如不懂。我的疑问是为什么OpenGL的投影矩阵那么复杂,我想复杂必然有其复杂的道理。经过一番研究,其根本原因是为了将实景体映射到一个立方体,范围是【-1,1】的边长为2的立方体。而不是直接变换到屏幕上。这就是OpenGL的想法。因此,像我那样直接转换到屏幕上就不对了。x,y经过这个变换后到-1,1. 而z的变换则必须满足线性变换的规则。这个推导的过程并不复杂。原理是,x,y按照线性比例进行压缩。z轴则进行一次线性变换以满足线性矩阵的要求。这些推导很简单,就不说了。

接下来要讲的东西更加出人意外,因为既然研究UI的底层实现,不能仅仅限于OpenGL。于是我又追根究底地剖解了一下Skia库。Skia库在3D上可以说在OpenGL面前就是小菜一碟。但是它在2D图形处理上,可以说OpenGL就是小菜一碟。因此互为补充。当然我研究的是Skia也增加了一些在2D图形进行3D特效的东东。其中有一些矩阵变换。刚好印证了我的矩阵是多么的正确。具体参照SkCamera.cpp这个文件。具体里面的那些数学矩阵运算怎么怎么进行的就不说了。根本原理就是我上面提到的那个投影矩阵。

这些东西很简单。不是吗?

具体OpenGL是怎么算的,稍微有点线性代数知识的人,高等代数等都可以看懂,下面是这个链接。

http://hi.baidu.com/dych_cnu/item/a7b78ba58a86e0208819d30f

  1. void SkCamera3D::patchToMatrix(const SkPatch3D& quilt, SkMatrix* matrix) const {
  2. if (fNeedToUpdate) {
  3. this->doUpdate();
  4. fNeedToUpdate = false;
  5. }
  6. const SkScalar* mapPtr = (const SkScalar*)(const void*)&fOrientation;
  7. const SkScalar* patchPtr;
  8. SkPoint3D       diff;
  9. SkScalar        dot;
  10. diff.fX = quilt.fOrigin.fX - fLocation.fX;
  11. diff.fY = quilt.fOrigin.fY - fLocation.fY;
  12. diff.fZ = quilt.fOrigin.fZ - fLocation.fZ;
  13. dot = SkUnit3D::Dot(*(const SkUnit3D*)(const void*)&diff,
  14. *(const SkUnit3D*)(((const SkScalar*)(const void*)&fOrientation) + 6));
  15. //  patchPtr的结构为{U,V,ORIGIN}其中U,V 代表列向量
  16. // ORIGIN 是坐标原点
  17. patchPtr = (const SkScalar*)&quilt;
  18. /*
  19. 其中matrix表示一个3x3的矩阵
  20. 第一行代表U的系数,第二行是V的系数,第三行是diff 的系数
  21. matrix 的每一列代表的是一个坐标轴。
  22. */
  23. //第一列
  24. matrix->set(SkMatrix::kMScaleX, SkScalarDotDiv(3, patchPtr, 1, mapPtr, 1, dot));
  25. matrix->set(SkMatrix::kMSkewY,  SkScalarDotDiv(3, patchPtr, 1, mapPtr+3, 1, dot));
  26. matrix->set(SkMatrix::kMPersp0, SkScalarDotDiv(3, patchPtr, 1, mapPtr+6, 1, dot));
  27. //第二列
  28. patchPtr += 3;
  29. matrix->set(SkMatrix::kMSkewX,  SkScalarDotDiv(3, patchPtr, 1, mapPtr, 1, dot));
  30. matrix->set(SkMatrix::kMScaleY, SkScalarDotDiv(3, patchPtr, 1, mapPtr+3, 1, dot));
  31. matrix->set(SkMatrix::kMPersp1, SkScalarDotDiv(3, patchPtr, 1, mapPtr+6, 1, dot));
  32. //第三列
  33. patchPtr = (const SkScalar*)(const void*)&diff;
  34. matrix->set(SkMatrix::kMTransX, SkScalarDotDiv(3, patchPtr, 1, mapPtr, 1, dot));
  35. matrix->set(SkMatrix::kMTransY, SkScalarDotDiv(3, patchPtr, 1, mapPtr+3, 1, dot));
  36. matrix->set(SkMatrix::kMPersp2, SK_UnitScalar1);
  37. }

【脚下生根】之深度探索安卓OpenGL投影矩阵的更多相关文章

  1. OpenGL投影矩阵【转】

    OpenGL投影矩阵 概述 透视投影 正交投影 概述 计算机显示器是一个2D平面.OpenGL渲染的3D场景必须以2D图像方式投影到计算机屏幕上.GL_PROJECTION矩阵用于该投影变换.首先,它 ...

  2. OpenGL投影矩阵

    概述 透视投影 正交投影 概述 计算机显示器是一个2D平面.OpenGL渲染的3D场景必须以2D图像方式投影到计算机屏幕上.GL_PROJECTION矩阵用于该投影变换.首先,它将所有定点数据从观察坐 ...

  3. OpenGL投影矩阵(Projection Matrix)构造方法

    (翻译,图片也来自原文) 一.概述 绝大部分计算机的显示器是二维的(a 2D surface).在OpenGL中一个3D场景需要被投影到屏幕上成为一个2D图像(image).这称为投影变换(参见这或这 ...

  4. 关于Opengl投影矩阵

    读 http://www.songho.ca/opengl/gl_projectionmatrix.html 0.投影矩阵的功能: 将眼睛空间中的坐标点 [图A的视椎体]     映射到     一个 ...

  5. DX与OpenGL投影矩阵的区别

    之前学习DX和OpenGL时到是知道一点,但是没仔细研究过,只是跟着教程抄个公式就过了,看双API引擎时发现转换时是个问题,必须搞懂,gamedev上找了个解释,希望用得上. https://www. ...

  6. Pascal Hexagrammum Mysticum 的深度探索

        PASCAL . Hexagrammum Mysticum . (六角迷魂图) . 的深度探索 . 英中对比.英文蓝色,译文黑色,译者补充说明用紫红色 (已校完,但尚未定稿,想再整理并补充内容 ...

  7. [OpenGL](翻译+补充)投影矩阵的推导

    1.简介 基本是翻译和补充 http://www.songho.ca/opengl/gl_projectionmatrix.html 计算机显示器是一个2D的平面,一个3D的场景要被OpenGL渲染必 ...

  8. 读书笔记《深度探索c++对象模型》 概述

    <深度探索c++对象模型>这本书是我工作一段时间后想更深入了解C++的底层实现知识,如内存布局.模型.内存大小.继承.虚函数表等而阅读的:此外在很多面试或者工作中,对底层的知识的足够了解也 ...

  9. 《Android深度探索》(卷1)HAL与驱动开发读后感:

    第一章:安卓系统移植与驱动开发概述 全书分为4篇,分别从搭建开发环境,Linux驱动和Android HAL的基础知识,开发Linux驱动的高级技术和分析典型的Linux驱动源代码4个方面介绍Andr ...

随机推荐

  1. 'Lock wait timeout exceeded; try restarting transaction'问题

    OperationalError: (1205, 'Lock wait timeout exceeded; try restarting transaction') 原因很简单,太多错误,意外处理没有 ...

  2. CSS中的图片路径问题

      CSS中的背景图片写了相对路径,为什么不显示那?   [解决方法] CSS中的背景图片路径应该写成相对于当前CSS文件的路径,而不是针对网站根目录的相对路径.

  3. External component has thrown an exception

    C#调用c++的DLL报错:External component has thrown an exception, 也没有log产生,怎么回事那? [解决方法] 这是因为c++的程序报错了,而且没有c ...

  4. JavaScript中一个对象如何继承另外一个对象

    如题,JavaScript中一个对象a如何继承另外一个对象b.即将b中的属性和方法复制到a中去. 面试中遇到了这个问题,当时脑子里的想法是: 1.除了循环遍历复制,还能怎样 2.javascript中 ...

  5. AI单挑Dota 2世界冠军:被电脑虐哭……

    OpenAI的机器人刚刚在 Dota2 1v1 比赛中战胜了人类顶级职业玩家 Denti.以建设安全的通用人工智能为己任的 OpenAI,通过“Self-Play”的方式,从零开始训练出了这个机器人. ...

  6. iOS社交app技术合伙人笔试题

    理想状况当然是找到有管理能力且还在写代码的架构师了,然而假设有这种人,他自己能发起项目了.你要拉上他还真难.满足一定条件就可以了,别追求完美. 还有比这更完美的吗?请生产这种机器人: 性格开朗(开朗≠ ...

  7. Android 为何比 iOS 卡?【转载】

    Android 卡是必须的,当你的手机装了 20 多个 app,那不卡才叫见鬼了呢,我手机微信都打不开,手机直接自动重启啦~哪种东西生来就是完美的呢?即便是台式机,也是越用越慢.换句话,如果没有特别原 ...

  8. JSP与Servlet之间的关系事例说明

    Servlet Servlet 没有 main 方法,不能够独立的运行,它的运行需要容器的支持,Tomcat 是最常用的 JSP/Servlet 容器.Servlet 运行在 Servlet 容器中, ...

  9. Python 入门必学的8个知识点

        文章来源:刘俊涛的博客 欢迎关注,有问题一起学习欢迎留言.评论

  10. Percona-XtraBackup系列三:增量备份恢复

    1:创建测试表和测试库如果需要快速建立测试表和库的话,参考之前写的这篇博客:http://www.cnblogs.com/xiaoit/p/3376685.html create database b ...