Opengles2.0入门「建议收藏」

Opengles2.0入门「建议收藏」一二三四Opengles2.0渲染管线简单画图步骤着色器语言简单介绍镜像技术一OpenGLES2.0渲染管线1.基本处理初始化3D空间中物体的顶点坐标,顶点对应的颜色,顶点的纹

大家好,又见面了,我是你们的朋友全栈君。

一 二 三 四 Opengles2.0渲染管线 简单画图步骤 着色器语言简单介绍 镜像技术

一 OpenGLES2.0渲染管线
1.基本处理
初始化3D空间中物体的 顶点坐标,顶点对应的颜色,顶点的纹理坐标等属性 1.1 顶点缓冲对象(可选):缓冲顶点数据,提高渲染效率

2.顶点着色器:

顶点变换,法向量计算,纹理坐标变换,光照与材质的应用 3.图元装配
3.1 图元组装:组装点,线,三角形 3.2 图元处理:主要是裁剪

4.光栅化:将投影结果离散化为一个个小片元 5.片元着色器:纹理处理,颜色求和,雾效果 6.剪裁测试:丢弃在帧缓冲位置不在剪裁窗口中的片元 7.深度测试与模板测试:
深度测试就是判断新片元的深度是否小于深度缓冲区里面的片元深度,小于则能通过 深度测试,否则新片元将被丢弃。 深度就是指物体距照相机的位置,深度缓冲区的片元深度,是指第一个被绘制的物体 的片元深度,新的通过深度测试的片元,将会成为深度缓冲区的片元深度。 镜像技术一定要关闭深度检测。

8.颜色缓冲混合 9.抖动 10.帧缓冲

二 简单绘图步骤
绘制一个用户可以旋转的三角形的步骤如下: 1.用 GLSurfaceView and GLSurfaceView.Render创建一个Activity,为 GLSurfaceView子类增加onTouchEvent事件 2.初始化顶点坐标,颜色坐标并缓冲坐标数据 3.编写顶点着色器,片元着色器语言并加载,编译顶点,片元shader 4.创建着色器程序,并关联shader 5.产生摄像机9参数位置矩阵 6.产生透视投影矩阵 7.产生最终的模型视图投影矩阵,绘制三角形

步骤二:初始化顶点坐标,颜色坐标并缓冲坐标数据 顶点坐标 float triangleCoords[] = { // X, Y, Z -1.0f, 1.0f, 0.0f, // 0, Top Left -1.0f, -1.0f, 0.0f, // 1, Bottom Left 1.0f, -1.0f, 0.0f, // 2, Bottom Right 1.0f, 1.0f, 0.0f, // 3, Top Right }; ByteBuffer vbb = ByteBuffer.allocateDirect( vbb.order(ByteOrder.nativeOrder()); FloatBuffer triangleVB = vbb.asFloatBuffer(); ByteBuffer triangleVB.put(triangleCoords); triangleVB.position(0);

步骤三:编写顶点着色器,片元着色器语言并加载,编译顶点,片元shader ? private final String vertexShaderCode = ? // This matrix member variable provides a hook to manipulate ? // the coordinates of the objects that use this vertex shader ? “uniform mat4 uMVPMatrix; \n” + ? “attribute vec4 aColor;\n” + ? “varying vec4 vColor;\n” + ? “attribute vec4 vPosition; \n” + ? “void main(){ \n” + ? // the matrix must be included as a modifier of gl_Position ? ” gl_Position = uMVPMatrix * vPosition; \n” + ? ” vColor = aColor;\n” + ? “} \n”; ? ? private final String fragmentShaderCode = ? “precision mediump float; \n” + ? “varying vec4 vColor;\n” + ? “void main(){ \n” + ? ” gl_FragColor = vColor; \n” + ? “} \n”;

步骤四:创建着色器程序,并关联shader
mProgram = GLES20.glCreateProgram(); GLES20.glAttachShader(mProgram, vertexShader GLES20.glAttachShader(mProgram, fragmentShader); GLES20.glLinkProgram(mProgram); // 从OpenGLES引擎里面获取vPosition属性的句柄,便于下面赋值 maPositionHandle = GLES20.glGetAttribLocation(mProgram, “vPosition”); // 从OpenGLES引擎里面获取aColor属性的句柄,便于下面赋值 maColorHandle = GLES20.glGetAttribLocation(mProgram, “aColor”);

步骤五:产生摄像机9参数位置矩阵 Matrix.setLookAtM(mVMatrix, 0, 0f, 0f, 7f, 0f, 0f, 0f, 0.0f, 1.0f, 0.0f);

步骤五:产生透视投影矩阵
//为投影矩阵赋值,ratio为设备屏幕的宽高比, Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7); //获取最终的模型视图投影矩阵uMVPMatrix的句柄, muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, “uMVPMatrix”);

视景体的如下:

步骤七:产生最终的模型视图投影矩阵,绘制三角形
public void onDrawFrame(GL10 gl) { GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); // 重 绘背景色 GLES20.glUseProgram(mProgram);//把着色器程序添加到OpenGL环境中 // 将顶点数据缓冲里面的数据赋值给opengl引擎里面的顶点位置句柄 GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, 12, triangleVB); GLES20.glEnableVertexAttribArray(maPositionHandle);//启用该顶点位置属性 // 将颜色缓冲数据赋值给引擎的颜色句柄 GLES20.glVertexAttribPointer(maColorHandle, 4, GLES20.GL_FLOAT, false, 16, colorBuffer); GLES20.glEnableVertexAttribArray(maColorHandle);//启用该顶点颜色位置属性 //根据模型旋转角度为模型矩阵赋值 Matrix.setRotateM(mMMatrix, 0, mAngle, 0, 0, 1.0f); //将模型矩阵和视图矩阵合并为一个矩阵 Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0); //再和投影矩阵合并,最终形成模型视图投影矩阵 Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0); GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);、 //绘制三角形 GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3); }

三 着色器语言简单介绍
OpenGL ES着色语言时一种高级的过程语言,基于C/C++语言。 数据类型: 向量:由同样类型的标量组成,标量为bool,int,float。每个向量可以有2个,3个或者4 个相同的标量组成。例如: Vec4:包含了四个浮点数的向量 ivec2:包含了两个整数的向量 矩阵:3D场景中物体的移位,旋转,缩放等变换都是有矩阵的运算来实现的。 例如:Mat2:2×2的浮点矩阵 mat4:4×4的浮点矩阵 限定符: Attribute:一般用于每个顶点都不相同的量,如顶点坐标,颜色,纹理坐标,法向量等 该限定符只用于顶点着色器。 Uniform:一般用于对同一组顶点组成的单个3D物体中所有顶点都相同的量,如当前的 光源位置。该限定符可用于顶点着色器和片元着色器。 Varying:用于从顶点着色器传递到片元着色器的量。 内建变量: 顶点着色器的内建输出变量: gl_Position:在顶点着色器里面为其赋值后,该变量传递到渲染管线供后续处理。 片元着色器的内建输出变量: gl_FragColor:在片元着色器里面为其赋值后,该变量传递到渲染管线供后续处理。

四 镜像技术

形成镜像的原因是反射,经过反射形成的像与其对应的实体相对于反射面是对称 的,因此可以根据实体和反射面的位置计算出镜像的位置。

镜像效果的绘制顺序最好为:首先绘制反射面,其次绘制镜像体,最后绘制实体。 最关键的就是要关闭深度测试。 在打开深度测试后,会开不见镜像体的原因: 如果先绘制里照相机较近的反射面,则此时在深度缓冲区里面会记录较小的深度 值,当绘制里照相机较远的镜像体时,因为其片元的深度值大于此时缓冲区 里面的值,于是将不会通过深度测试,片元将被丢弃。 如果先绘制镜像体然后绘制反射面的话,深度测试能够通过,但是反射面过大会 覆盖镜像体的片元,导致镜像体被部分或全部遮挡。

关闭深度测试后,也要先绘制反射面,再绘制镜像体,此时在混色时镜像体能够 可见,否则,反射面将完全遮挡镜像体。
对于实体的绘制最好放在最后,具体原因有待考证。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/154856.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • LLDP协议、STP协议 笔记

    LLDP协议、STP协议 笔记参考:数据链路层学习之LLDP生成树协议LLDP协议、STP协议笔记LLDP提出背景:随着网络技术的发展,接入网络的设备的种类越来越多,配置越来越复杂,来自不同设备厂商的设备也往往会增加自己特有的功能,这就导致在一个网络中往往会有很多具有不同特性的、来自不同厂商的设备,为了方便对这样的网络进行管理,就需要使得不同厂商的设备能够在网络中相互发现并交互各自的系统及配置信息。L…

    2022年6月2日
  • phpstorm 2021.4.2激活码_通用破解码

    phpstorm 2021.4.2激活码_通用破解码,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月16日
  • 神经网络loss函数意义_lossfunction

    神经网络loss函数意义_lossfunctionL1Loss平均绝对误差(MAE),用于回归模型对于包含NNN个样本的batch数据D(x,y)D(x,y)D(x,y),losslossloss计算如下:loss=1N∑n=1Nlnloss=\frac{1}{N}\sum_{n=1}^{N}l_{n}loss=N1​∑n=1N​ln​其中,ln=∣xn−yn∣l_{n}=\left|x_{n}-y_{n}\right|ln​=∣xn​−yn​∣classL1Loss(_Loss):__constants__=[‘redu

    2022年9月18日
  • 配置NFS固定端口[通俗易懂]

    配置NFS固定端口[通俗易懂]NFS启动时会随机启动多个端口并向RPC注册,为了设置安全组以及iptables规则,需要设置NFS固定端口。NFS服务需要开启mountd,nfs,nlockmgr,portmapper,rquotad这5个服务,其中nfs、portmapper的端口是固定的,另外三个服务的端口是随机分配的,所以需要给mountd,nlockmgr,rquotad设置固定的端口。其中,给mountd、rq…

    2022年6月27日
  • MMC卡SPI模式「建议收藏」

    MMC卡SPI模式「建议收藏」MMC/SD卡简单SPI模式驱动1. SPI模式下CRC检验无效的。 2. 命令格式是6个字节,采用大端法进行数据传输。3. 第一个是(命令号|0x40)。4. 第2-5个是有些命令需要地址,用来设置地址的,而其他的可以任意填充。5. 最后一个字节是CRC校验位,除了CMD0为95H外,其他可以任意填充。6.命令发送函数。1).片选拉低

    2022年6月2日
  • 华为AAA认证典型配置举例

    华为AAA认证典型配置举例2.5AAA典型配置举例2.5.1Telnet/SSH用户通过RADIUS服务器认证的应用配置&说明:SSH用户和Telnet用户通过RADIUS服务器进行认证的配置方法类似,下面的描述以Telnet用户的远端认证为例。1.组网需求在图2-1所示的环境中,需要通过配置交换机实现RADIUS服务器对登录交换机的Telne…

    2022年5月18日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号