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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 二维数组指针详解

    二维数组指针详解二维数组指针 nbsp 概括的说 指针其实就是可变数组的首地址 说是可变数组 是 nbsp 指其包含内容的数量的可变的 并且是可动态申请和释放的 从而充 nbsp 分节约宝贵的内存资源 我一向喜欢一维数组 除非万不得已 我一 nbsp 般是不用二维数组的 多维的则更是很少涉足了 因为一维简单 容 nbsp 易理解 而用指针指向的多维数组就具有相当的复杂性了 也因此更 nbsp 具有讨论的必要 nbsp nbsp nbsp nbsp 闲话少说 这里我就以三

    2025年11月30日
    5
  • java的守护线程和非守护线程区别_java守护线程应用场景

    java的守护线程和非守护线程区别_java守护线程应用场景一、守护线程    java分为两种线程:用户线程和守护线程    守护线程是指在程序运行的时候在后台提供一种通用服务的线程,比如垃圾回收线程就是一个很称职的守护者,并且这种线程并不属于程序中不可或缺的部分。因此,当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程。反过来说,只要任何非守护线程还在运行,程序就不会终止。    守护线程和用户…

    2022年10月15日
    2
  • 24 eve 网络模拟器中的机器桥接到物理网络[通俗易懂]

    24 eve 网络模拟器中的机器桥接到物理网络[通俗易懂]

    2022年5月13日
    35
  • 网络信息安全——访问控制「建议收藏」

    网络信息安全——访问控制「建议收藏」**访问控制**访问控制是给出一套方法,将系统中的所有功能标识出来,组织起来,托管起来,将所有的数据组织起来标识出来托管起来,然后提供一个简单的唯一的接口,这个接口的一端是应用系统一端是权限引擎。权限引擎所回答的只是:谁是否对某资源具有实施某个动作(运动、计算)的权限。返回的结果只有:有、没有、权限引擎异常了。访问控制是几乎所有系统(包括计算机系统和非计算机系统)都需要用到的一种技术。访问控制是按用户身份及其所归属的某项定义组来限制用户对某些信息项的访问,或限制对某些控制功能的使用的一种技术。

    2022年7月23日
    13
  • rabbitmq使用案例_标点符号的正确使用方法及例子

    rabbitmq使用案例_标点符号的正确使用方法及例子一些概念:RabbiMQ的认知:首先要抛弃熟悉的客户端和服务器的观念。对于RabbitMQ应该认为是消息投递服务。、               其次:从应用程序角度来看RabbitMQ的话,应用程序要先决定是个消息的发送者还是消息的接受者。                    如果从RabbitMQ的角度来看的话…

    2022年10月3日
    2
  • Telerik字符压缩算法

    Telerik字符压缩算法

    2021年8月20日
    55

发表回复

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

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