安卓平台OpenGL ES的调用

  • 开发游戏如果直接使用OpenGL是比较痛苦的,最好的办法是使用封装好的引擎,但很有必要了解在安卓java代码直接调用OpenGL的渲染方法
  • 固定渲染管线只可通过配置实现不同的效果,而可编程渲染管线通过一般编程的方式实现,可以实现更加灵活的效果

OpenGL ES

  • OpenGL从3.0开始,而OpenGL ES从2.0开始,支持可编程管线
  • 下图中橙色两块儿即为可编程部分,而顶点和片段着色器要相互配合好才能发挥最大性能

  • 一般通用编程模式为写好两个shader的代码,每次运行程序时即时编译运行

代码框架

  • 在manifest中声明OpenGL ES <uses-feature android:glEsVersion="0x00020000" android:required="true" />
  • 在入口Acitvity中需要使用GLSurfaceView作为主视图
  • 在GLSurfaceView中可以扩展出一些其他函数,需要创建一个GLSurfaceView.Renderer的派生类对象负责显示
  • GLSurfaceView.Renderer需要关注三个函数:
    • onSurfaceCreated:仅调用一次
    • onDrawFrame:每次显示都调用
    • onSurfaceChanged:view大小变化时调用

3D坐标变换

  • 安卓同样有对应坐标变换的库Matrix
  • MVP变换的实际乘法顺序是PVM
  • V可以通过setLookAtM得到
  • P则是orthoM frustumM/perspectiveM生成,其中perspectiveM是对frustumM的封装,只是在API Level 14后才存在
  • M如果不是I的话,表明模型有位置偏移

使用shader画图

  • 需要创建一个顶点shader、一个片段shader,以及一个program
  • 通过glCreateShader可以创建一个shader,之后调用glShaderSourceglCompileShader分别设置shader代码和编译
  • progam则通过glCreateProgram创建,调用glAttachShader添加这两个shader,调用glLinkProgram进行“链接”生成可执行指令,使用时要glUseProgram

示例代码

  • OpenGLES20Activity.java

    package com.example.androiddeveloper;//import android.support.v7.app.ActionBarActivity;
    import android.os.Bundle;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.MotionEvent;import javax.microedition.khronos.opengles.GL10;import android.app.Activity;
    import android.content.Context;
    import android.opengl.*;public class OpenGLES20Activity extends Activity {private GLSurfaceView mGLView;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// Create a GLSurfaceView instance and set it// as the ContentView for this Activity.mGLView = new MyGLSurfaceView(this);setContentView(mGLView);}
    }class MyGLSurfaceView extends GLSurfaceView {private final MyGLRenderer mRenderer;public MyGLSurfaceView(Context context){super(context);// Create an OpenGL ES 2.0 contextsetEGLContextClientVersion(2);//setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);mRenderer = new MyGLRenderer();// Set the Renderer for drawing on the GLSurfaceViewsetRenderer(mRenderer);}private final float TOUCH_SCALE_FACTOR = 180.0f / 320;private float mPreviousX;private float mPreviousY;@Overridepublic boolean onTouchEvent(MotionEvent e) {// MotionEvent reports input details from the touch screen// and other input controls. In this case, you are only// interested in events where the touch position changed.float x = e.getX();float y = e.getY();switch (e.getAction()) {case MotionEvent.ACTION_MOVE:float dx = x - mPreviousX;float dy = y - mPreviousY;// reverse direction of rotation above the mid-lineif (y > getHeight() / 2) {dx = dx * -1 ;}// reverse direction of rotation to left of the mid-lineif (x < getWidth() / 2) {dy = dy * -1 ;}mRenderer.setAngle(mRenderer.getAngle() +((dx + dy) * TOUCH_SCALE_FACTOR));requestRender();}mPreviousX = x;mPreviousY = y;return true;}
    }
    
  • MyGLRenderer.java

    package com.example.androiddeveloper;import javax.microedition.khronos.opengles.GL10;import android.opengl.GLES20;
    import android.opengl.GLSurfaceView;
    import android.opengl.Matrix;
    import android.os.SystemClock;public class MyGLRenderer implements GLSurfaceView.Renderer {private Triangle mTriangle;private final float[] mMVPMatrix = new float[16];private final float[] mProjectionMatrix = new float[16];private final float[] mViewMatrix = new float[16];public void onSurfaceCreated(GL10 unused, javax.microedition.khronos.egl.EGLConfig config) {// Set the background frame colorGLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);mTriangle = new Triangle();}private float[] mRotationMatrix = new float[16];public void onDrawFrame(GL10 unused) {float[] scratch = new float[16];long time = SystemClock.uptimeMillis() % 4000L;float angle = 0.090f * ((int) time);Matrix.setRotateM(mRotationMatrix, 0, mAngle, 0, 0, -1.0f);GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);Matrix.multiplyMM(scratch, 0, mMVPMatrix, 0, mRotationMatrix, 0);mTriangle.draw(scratch);}public void onSurfaceChanged(GL10 unused, int width, int height) {GLES20.glViewport(0, 0, width, height);float ratio = (float) width / height;Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);}public static int loadShader(int type, String shaderCode){// create a vertex shader type (GLES20.GL_VERTEX_SHADER)// or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)int shader = GLES20.glCreateShader(type);// add the source code to the shader and compile itGLES20.glShaderSource(shader, shaderCode);GLES20.glCompileShader(shader);return shader;}public volatile float mAngle;public float getAngle() {return mAngle;}public void setAngle(float angle) {mAngle = angle;}
    }
    
  • Triangle.java

    package com.example.androiddeveloper;import java.nio.ByteBuffer;
    import java.nio.ByteOrder;
    import java.nio.FloatBuffer;import android.opengl.GLES20;public class Triangle {private FloatBuffer vertexBuffer;// number of coordinates per vertex in this arraystatic final int COORDS_PER_VERTEX = 3;static float triangleCoords[] = {   // in counterclockwise order:0.0f,  0.622008459f, 0.0f, // top-0.5f, -0.311004243f, 0.0f, // bottom left0.5f, -0.311004243f, 0.0f  // bottom right};// Set color with red, green, blue and alpha (opacity) valuesfloat color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };private final int mProgram;public Triangle() {// initialize vertex byte buffer for shape coordinatesByteBuffer bb = ByteBuffer.allocateDirect(// (number of coordinate values * 4 bytes per float)triangleCoords.length * 4);// use the device hardware's native byte orderbb.order(ByteOrder.nativeOrder());// create a floating point buffer from the ByteBuffervertexBuffer = bb.asFloatBuffer();// add the coordinates to the FloatBuffervertexBuffer.put(triangleCoords);// set the buffer to read the first coordinatevertexBuffer.position(0);int vertexShader = MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER,vertexShaderCode);int fragmentShader = MyGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,fragmentShaderCode);// create empty OpenGL ES ProgrammProgram = GLES20.glCreateProgram();// add the vertex shader to programGLES20.glAttachShader(mProgram, vertexShader);// add the fragment shader to programGLES20.glAttachShader(mProgram, fragmentShader);// creates OpenGL ES program executablesGLES20.glLinkProgram(mProgram);}private final String vertexShaderCode ="uniform mat4 uMVPMatrix;" +"attribute vec4 vPosition;" +"void main() {" +"  gl_Position = uMVPMatrix * vPosition;" +"}";private final String fragmentShaderCode ="precision mediump float;" +"uniform vec4 vColor;" +"void main() {" +"  gl_FragColor = vColor;" +"}";private int mPositionHandle;private int mColorHandle;private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertexprivate int mMVPMatrixHandle;public void draw(float[] mvpMatrix) {// Add program to OpenGL ES environmentGLES20.glUseProgram(mProgram);// get handle to vertex shader's vPosition membermPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");// Enable a handle to the triangle verticesGLES20.glEnableVertexAttribArray(mPositionHandle);// Prepare the triangle coordinate dataGLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,GLES20.GL_FLOAT, false,vertexStride, vertexBuffer);// get handle to fragment shader's vColor membermColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");// Set color for drawing the triangleGLES20.glUniform4fv(mColorHandle, 1, color, 0);mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);// Draw the triangleGLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);// Disable vertex arrayGLES20.glDisableVertexAttribArray(mPositionHandle);}
    }
    

作者Focustc,来自于CSDN

安卓平台OpenGL ES的调用相关推荐

  1. Android平台OpenGL ES图像处理(improving)

    在Android平台一般使用OpenGL ES进行图像处理.在OpenGL ES中编写算法,实现效果,最后将处理的结果传输给 CPU,然后生成最终的照片. 直播中的美颜,对性能有很高的要求,无法使用特 ...

  2. android平台opengl es读取纹理数据并保存图片

    在AR云渲染服务中,有时候需要把生成的纹理保存到图片来进行调试. 那就想办法看看存成图片,很多人说用glGetTexImage这个函数可以直接读取纹理的数据,但是我们用到了opengl es 32版本 ...

  3. android opengl图片,Android平台openGL ES实现全景图片

    全景又被称为3D实景,是一种新兴的富媒体技术,其与视频,声音,图片等传统的流媒体最大的区别是"可操作,可交互". 全景分为虚拟现实和3D实景两种.虚拟现实是利用maya等软件,制作 ...

  4. 关于openGL, openGL ES, openVG及android中2D调用关系的报告

    关于openGL, openGL ES, openVG及android中2D调用关系的报告 http://blog.chinaunix.net/u3/99423/showart_2203591.htm ...

  5. OpenGL ES EGL 简介

    目录 一.EGL 简介 二.EGL 跨平台之 ANGLE 1.ANGLE 支持跨平台 2.ANGLE 支持渲染器 3.ANGLE 下载地址 三.EGL 坐标系 四.EGL 绘图步骤 五.猜你喜欢 零基 ...

  6. 调试OpenGL ES应用程序

    大家好,今天小白给大家简单介绍下几种调试OpenGL ES应用程序的方法,欢迎一起交流学习. 一, 使用glGetError OpenGL ES API是一个严格的C API,这意味着它检测到的任何错 ...

  7. centos 8 的图形操作界面在哪_商显首款基于安卓系统的图形化调用API软件—智微智能SPIRIT测评...

    出色优美的数字显示可谓是商业展示的灵魂所在,可迅速吸引人们的目光,智能多样化地进行信息展示.随着各种数字显示产品与技术的进步,新型数字商用显示在生活中随处可见.各类数字标牌.POS设备.自助服务终端. ...

  8. 安卓学习笔记37:利用OpenGL ES绘制平面图形

    文章目录 零.学习目标 一.OpenGL概述 二.了解三维直角坐标系 三.案例演示 - 绘制三角形 (一)运行效果 (二)实现步骤 1.创建安卓应用[DrawTriangle] 2.建模:创建三角形类 ...

  9. 在 Android* 平台上设置原生 OpenGL ES*

    Setting up Native OpenGL ES* on Android* Platforms final.docx BSD2.0.txt ParticleSystemNDK.zip READM ...

最新文章

  1. ssacnf和sprintf实战取ip地址
  2. oracle登陆无效参数是啥意思,关于参数无效的详细介绍
  3. RPC框架几行代码就够了
  4. mysql联表查询多记录显示_数据库:MySQL(多表的表记录的查询)(三)
  5. php ppt read_php怎么读取ppt文字内容并在浏览器中显示出来?
  6. MIT Kimera阅读笔记
  7. 一张纸一幅图,竟然提高了10倍的学习和工作效率!?
  8. 2 android学习资料
  9. Java 理论与实践:您的小数点到哪里去了?(转载)
  10. 利用c语言建立交易系统,【图】手把手教会你构建自己的交易系统 - 4_股票论坛,炒股公式,股票指标,股票公式,选股公式_数据、教程交流论坛_理想论坛 - 股票论坛...
  11. 调整了canvas的高度页面变化后还原_Web 页面录屏实现
  12. 策略模式Strategy——坐什么车回家?
  13. python猜数字1001untitled_如何利用Matlab GUI制作猜数字游戏
  14. AIM Tech Round 5 (rated, Div. 1 + Div. 2)
  15. 2013中国电商盘点回顾
  16. Powerdesigner pdm视图看不到表注释comment问题
  17. 【论文阅读】Structured Pruning Learns Compact and Accurate Models
  18. 学计算机的目标作文,计算机学习计划作文三篇
  19. SwiftUI 语音合成与语言识别教程之 03 实现录音文件转文字(含完整项目源码)SFSpeechURLRecognitionRequest
  20. dz邮箱验证怎么设置_Discuz X3.2如何设置邮箱验证的具体方法

热门文章

  1. yum安装elasticsearch慢_ELK elasticsearch yum 安装(4th)
  2. simulink接收串口数据_JLink RTT连接Simulink
  3. 【java基础知识】java分层思想
  4. Matrix Factorization: A Simple Tutorial and Implementation in Python
  5. 使用嵌套循环,打印 5 行 5 列的直角三角形
  6. 如何从零搭建一个hexo博客网站01
  7. ibm服务器无显示器,IBM 2128彩色显示器,无论有无连机信号输入均黑屏
  8. js显示PHP源代码命令,layedit富文本编辑器中如何添加显示源码功能(代码)
  9. linux centos7上安装sql developer
  10. 节能与新能源汽车技术路线图2.0 pdf_《节能与新能源汽车技术路线图(2.0版)》正式发布...