两种投影方式

我们知道,在图元装配之后的光栅化阶段前,首先需要把虚拟3D世界的物体投影到二维平面上。OpenGL ES中常用的投影模式有两种,分别是正交投影与透视投影:

正交投影

OpenGL ES 2.0中,根据应用程序提供的投影矩阵,管线会确定一个可视空间区域,称之为视景体。视景体是由6个平面确定的,这6个平面分别为:上平面(up),下平面(down),做平面(left),右平面(right),远平面(far),近平面(near)。

场景中处于视景体内的物体会被投影到近平面上(视景体外的物体将被裁剪掉),然后再将近平面上投影出的内容映射到屏幕上的视口中。
对于正交投影而言,视景体及近平面的情况如图:

我们可以看到,正交投影是平行投影的一种,其视景体是长方体,投影到近平面上的图形不会产生“近大远小”的效果。

我们可以这样来进行正交投影的设置:

Matrix.orthoM(mProjectMatirx, //投影矩阵0, //偏移量left,right,//near面的left,rightbottom,top,//near面的bottom,topnear,far//near面,far面与视点的距离);

透视投影

现实世界中,人眼观察物体时会有“近大远小”的效果,这种效果,是不能用正交投影来实现的,可以采用透视投影。透视投影的投影线是不平行的,他们相交于视点。

我们可以看到,透视投影的投影线互不平行,都相交于视点。因此同样尺寸大小的物体,近处的投影出来大,远处的投影出来小,从而产生了“近大远小”的效果。

我们可以这样来进行透视投影的设置:

Matrix.frustumM(mProjectMatirx, //投影矩阵0, //偏移量left,right,//near面的left,rightbottom,top,//near面的bottom,topnear,far//near面,far面与视点的距离);

有一张图,更能看清楚这两种投影的区别:

各种变换

平移变换

将P点沿X,Y,Z轴平移mx,my,mz:

其中我们把P矩阵前面的矩阵叫M矩阵

选择变换

OpenGL ES中,选择角度的正负可以用右手螺旋定制来确定:右手握住旋转轴,使大拇指指向旋转轴的正方向,4指环绕的方向即为旋转的正方向,也就是旋转角为正值

旋转的M矩阵为;

上诉矩阵表示将指定的点P绕轴向量u选择Θ°,其中的ux,uy,uz表示u向量在x,y,z轴上的分量。

缩放变换

变换的实质

变换实际上并不是直接针对物体进行的,而是针对坐标进行的。OpenGL ES中变换的实现机制可以理解为首先通过矩阵对坐标系进行变换,然后根据传入渲染管线的原始顶点坐标在最终变换结果坐标系中的位置来进行绘制。

绘制方式

  • GL_POINTS:点的唯一绘制方式,将其传入渲染管线的一系列顶点单独进行绘制
  • GL_LINES:将其传入渲染管线的一系列顶点按照顺序两两组织成线段进行绘制,若顶点个数为奇数,管线会自动忽略最后一个顶点

    • GL_LINE-STRIP:将其传入渲染管线的一系列顶点按照顺序依次组织成线段进行绘制。
  • GL_LINE_LOOP;将其传入渲染管线的一系列顶点按照顺序依次组合成线段进行绘制,然后最后一个顶点与第一个顶点相连,形成线段环。

  • GL_TRIANGLES;将其传入渲染管线的一系列顶点按照顺序每3个组成成一个三角形。

-GL_TRIANGLE_STRIP;将其传入渲染管线的一系列顶点按照顺序依次组成成三角形进行绘制

  • GL_TRIANGLE_FAN;将其传入渲染管线一系列顶点中的第一个顶点作为中心点,其他顶点作为边缘点绘制绘一系列组成扇形的相邻三角形

顶点法

调用glDrawArrays方法,此方法是按照传入渲染管线顶点本身的顺序及选用的绘制方式将顶点组织成图元进行绘制,也称为顶点法。
之前试手项目中有用过,参考之前的文章

索引法

调用glDrawElements方法绘制时,不但要将顶点序列传进去,还需要将索引传入管线。

这次,我们画一个正方形;

先看效果:

public class Square {private int mProgram;
private int maPositionHandle; //顶点位置的引用
private int maColorHandle; //顶点颜色属性引用private String mVertexShader = "uniform mat4 uMVPMatrix;" +"attribute vec3 aPosition;" +"attribute vec4 aColor;" +"varying vec4 vColor;" +"void main(){" +"gl_Position =  vec4(aPosition,1);" + //根据总变换矩阵计算此次绘制此顶点的位置"vColor = aColor;" +"}";
private String mFragmentShader = "precision mediump float;" +"varying vec4 vColor;" +"void main(){" +"gl_FragColor = vColor;" +"}";public static float[] mMMatrix = new float[16];//具体物体的3D变换矩阵private FloatBuffer mVertexBuffer;//顶点坐标数据缓冲
private FloatBuffer mFragmentBuffer;//顶点着色数据缓冲private ByteBuffer mIndexBuffer;//索引数据缓冲private int mvCount = 0;//顶点数量
private int miCount = 0;//索引数public  Square(){initVertex();initShader();
}private void initVertex(){mvCount = 4;float[] vertexs = new float[]{0.5f,0.5f,0,0.5f,-0.5f,0,-0.5f,-0.5f,0,-0.5f,0.5f,0};ByteBuffer vbb = ByteBuffer.allocateDirect(vertexs.length*4);vbb.order(ByteOrder.nativeOrder());mVertexBuffer = vbb.asFloatBuffer();mVertexBuffer.put(vertexs);mVertexBuffer.position(0);float[] colors = new float[]{1,0,0,1,0,1,0,1,0,1,1,1,0,0,1,1};ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);cbb.order(ByteOrder.nativeOrder());mFragmentBuffer= cbb.asFloatBuffer();mFragmentBuffer.put(colors);mFragmentBuffer.position(0);miCount = 6;byte[] index = new byte[]{ //顶点索引0,1,2,0,2,3};mIndexBuffer = ByteBuffer.allocateDirect(index.length);mIndexBuffer.order(ByteOrder.nativeOrder());mIndexBuffer.put(index);mIndexBuffer.position(0);}private void initShader(){mProgram = shaderUtil.createProgram(mVertexShader,mFragmentShader);maPositionHandle = GLES30.glGetAttribLocation(mProgram,"aPosition");maColorHandle = GLES30.glGetAttribLocation(mProgram,"aColor");
}public void drawSelf(){GLES30.glUseProgram(mProgram);//传入顶点位置数据GLES30.glVertexAttribPointer(maPositionHandle,3,GLES30.GL_FLOAT,false,3*4,mVertexBuffer);//传入顶点颜色数据GLES30.glVertexAttribPointer(maColorHandle,4,GLES30.GL_FLOAT,false,4*4,mFragmentBuffer);GLES30.glEnableVertexAttribArray(maPositionHandle);//启用顶点位置数据GLES30.glEnableVertexAttribArray(maColorHandle);//启用顶点颜色数据GLES30.glDrawElements(GLES30.GL_TRIANGLES,miCount,GLES30.GL_UNSIGNED_BYTE,mIndexBuffer);//开始绘制,传入索引
}
}

项目地址:https://github.com/vivianluomin/PracticeEveryDay/tree/master/LearnOpenGL

OpenGL ES 之投影及各种变换及绘制方式相关推荐

  1. [OpenGL ES 03]3D变换:模型,视图,投影与Viewport

    [OpenGL ES 03]3D变换:模型,视图,投影与Viewport 罗朝辉 (http://blog.csdn.net/kesalin) 本文遵循"署名-非商业用途-保持一致" ...

  2. Android VR Player(全景视频播放器) [10]: VR全景视频渲染播放的实现(exoplayer,glsurfaceview,opengl es)

    前言 此博客的大部分内容来自我的毕业设计论文,因此语言上会偏正式一点,如果您有任何问题或建议,欢迎留言.在此感谢实验室的聂师兄,全景视频render部分的代码设计主要参考了他所编写的代码来完成,他对视 ...

  3. OpenGL ES 2.0 总体概述

    文章目录 OpenGL ES 2.0 总体概述 1. OpenGL ES 的两个小伙伴 1.1 EGL 1.2 GLSL 2. 屏幕图片的本质和产生过程 3. OpenGL ES pipeline 3 ...

  4. 【OpenGL ES】入门及绘制一个三角形

    本文首发于个人博客:Lam's Blog - [OpenGL ES]入门及绘制一个三角形,文章由MarkDown语法编写,可能不同平台渲染效果不一,如果有存在排版错误图片无法显示等问题,烦请移至个人博 ...

  5. OpenGL ES基础教程,绘制三角形(补充,附代码)

    简介 OpenGL OpenGL(全写Open Graphics Library)是指定义了一个跨编程语言.跨平台的编程接口规格的专业的图形程序接口.它用于三维图像(二维亦可),是一个功能强大,调用方 ...

  6. OPENGL ES 2.0 知识串讲(1)――OPENGL ES 2.0 概括

    更多图形知识请关注我的公众号: 前言 电脑是做什么用的? 电脑又被称为计算机,那么最重要的工作就是计算.看过三体的同学都知道, 电脑中有无数纳米级别的计算单元,通过 0 和 1 的转换,完成加减乘除的 ...

  7. OpenGL ES SDK for Android - 4

    Integer Logic 该应用程序根据规则30使用OpenGL ES 3.0模拟细胞自动机现象. 它使用两个程序对象,这两个程序以乒乓方式使用两个纹理. 第一个程序将ping纹理(ping)作为输 ...

  8. 使用Android OpenGL ES 2.0绘图之三:绘制形状

    传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229 在定义好待绘制的形状之后,就要开始绘制它们了.使用OpenGL ES 2.0绘制形状可 ...

  9. Android OpenGL ES 画球体

    最近因为兴趣所向,开始学习OpenGL绘图.本文以"画球体"为点,小结一下最近所学. > 初识OpenGL ES 接触OpenGL是从Android开始的.众所周知,Andr ...

最新文章

  1. gvim 二进制_vim/gvim学习
  2. c primer plus(第五版)读书笔计 第四章(1)
  3. 机械制图手册_42条机械制图基础常识,带徒师傅必备!
  4. 14.Python抠图脚本
  5. 战争升级!Elasticsearch 从客户端向 AWS 开了一炮!
  6. java aop性能检测_Spring AOP 性能监控器
  7. 18.图像用户界面入门:EasyGui
  8. linux mysql卸载_Linux环境下安装Mysql8.0数据库
  9. ip 地址 192.168.1.255 代表( )。_判定IP地址合法性的三种方法
  10. 如何使用代码的方式删除 SAP CRM 订单 Text 数据
  11. HDU 1244 DP
  12. Oracle数据库一致性读的原理
  13. java 读取栅格,提取两个重叠栅格的数据
  14. 宽凳科技,这是前百度外卖董事长刘骏的新征途
  15. java for循环死循环_Java for循环进化
  16. java之Stream流
  17. LINUX编译opencore-amr
  18. Vrep/CoppeliaSim:基础操作(1)
  19. Nodejs学习记录: koa2
  20. 多功能雨伞项目计划书_多功能雨伞项目计划书_雨伞策划书范文

热门文章

  1. 99物联 REALTEK IOT8710B模块SDK下载
  2. python制作编程软件的方法_python代码能做成软件吗
  3. 汇总一下Intellij IDEA常用的牛逼插件
  4. 更改由oracle导入的dmp文件的版本
  5. 超宽带射频信号高速记录回放系统——模拟带宽3GHZ,记录回放速度高达6000MB/S!
  6. 2013年全球IT公司市值排行榜
  7. 三菱FX1N PLC 485与三菱变频器modbus通讯 对变频器进行频率设定,加减速时间设置,正反转,启停控制
  8. [业界动态]瑞萨发布用于手机开发的SH-MobileJ2多媒体加速器平台(转载)
  9. iOS Unity3D游戏引擎入门①
  10. 【Python小程序】怀旧经典 | 特色玩法,代码版本的钢琴小游戏了解下?初学钢琴,能提高双手协调与反应能力哦~(源码分享)