基于textureview编写opengl程序
与SurfaceView相比,TextureView并没有创建一个单独的Surface用来绘制,这使得它可以像一般的View一样执行一些变换操作,设置透明度等。
另外,Textureview必须在硬件加速开启的窗口中。下面的例子演示了通过TextureView来创建一个opengl程序。
基于TextureView的程序,我们需要实现TextureView.SurfaceTextureListener这个接口,首先给出Activity的代码,在该类中,我们实现了此接口:
package com.fyj.test;import java.util.concurrent.atomic.AtomicBoolean;import android.app.Activity;
import android.graphics.SurfaceTexture;
import android.os.Bundle;
import android.view.TextureView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;public class TextureviewtestActivity extends Activity implements TextureView.SurfaceTextureListener{private TextureView mTextureView;private Thread mProducerThread = null;private GLRendererImpl mRenderer;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); mTextureView = new TextureView(this);mTextureView.setSurfaceTextureListener(this);mTextureView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);//隐藏虚拟按键,即navigator barsetContentView(mTextureView);mRenderer = new GLRendererImpl(this);}@Overridepublic void onSurfaceTextureAvailable(SurfaceTexture surface, int width,int height) {// TODO Auto-generated method stubmRenderer.setViewport(width, height);mProducerThread = new GLProducerThread(surface, mRenderer, new AtomicBoolean(true));mProducerThread.start();}@Overridepublic boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {// TODO Auto-generated method stubmProducerThread = null;return true;}@Overridepublic void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width,int height) {// TODO Auto-generated method stubmRenderer.resize(width, height);}@Overridepublic void onSurfaceTextureUpdated(SurfaceTexture surface) {// TODO Auto-generated method stub}
}
其中,在方法onSurfaceTextureAvailable中,我们开启一个OpenGL线程,在该线程中执行OpenGL的一些操作,该线程的定义如下:
package com.fyj.test;import java.util.concurrent.atomic.AtomicBoolean;import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.egl.EGLSurface;
import javax.microedition.khronos.opengles.GL;import android.graphics.SurfaceTexture;
import android.opengl.GLUtils;public class GLProducerThread extends Thread {private AtomicBoolean mShouldRender;private SurfaceTexture mSurfaceTexture;private GLRenderer mRenderer;private EGL10 mEgl;private EGLDisplay mEglDisplay = EGL10.EGL_NO_DISPLAY;private EGLContext mEglContext = EGL10.EGL_NO_CONTEXT;private EGLSurface mEglSurface = EGL10.EGL_NO_SURFACE;private GL mGL;private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;private static final int EGL_OPENGL_ES2_BIT = 4;public interface GLRenderer {public void drawFrame();}public GLProducerThread(SurfaceTexture surfaceTexture, GLRenderer renderer, AtomicBoolean shouldRender) {mSurfaceTexture = surfaceTexture;mRenderer = renderer;mShouldRender = shouldRender;}private void initGL(){mEgl = (EGL10)EGLContext.getEGL();mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);if (mEglDisplay == EGL10.EGL_NO_DISPLAY) {throw new RuntimeException("eglGetdisplay failed : " + GLUtils.getEGLErrorString(mEgl.eglGetError()));}int []version = new int[2];if (!mEgl.eglInitialize(mEglDisplay, version)) {throw new RuntimeException("eglInitialize failed : " + GLUtils.getEGLErrorString(mEgl.eglGetError()));}int []configAttribs = {EGL10.EGL_BUFFER_SIZE, 32,EGL10.EGL_ALPHA_SIZE, 8,EGL10.EGL_BLUE_SIZE, 8,EGL10.EGL_GREEN_SIZE, 8,EGL10.EGL_RED_SIZE, 8,EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT,EGL10.EGL_NONE};int []numConfigs = new int[1];EGLConfig []configs = new EGLConfig[1]; if (!mEgl.eglChooseConfig(mEglDisplay, configAttribs, configs, 1, numConfigs)) {throw new RuntimeException("eglChooseConfig failed : " + GLUtils.getEGLErrorString(mEgl.eglGetError()));}int []contextAttribs = {EGL_CONTEXT_CLIENT_VERSION, 2,EGL10.EGL_NONE};mEglContext = mEgl.eglCreateContext(mEglDisplay, configs[0], EGL10.EGL_NO_CONTEXT, contextAttribs);mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, configs[0], mSurfaceTexture, null);if (mEglSurface == EGL10.EGL_NO_SURFACE || mEglContext == EGL10.EGL_NO_CONTEXT) {int error = mEgl.eglGetError();if (error == EGL10.EGL_BAD_NATIVE_WINDOW) {throw new RuntimeException("eglCreateWindowSurface returned EGL_BAD_NATIVE_WINDOW. " );}throw new RuntimeException("eglCreateWindowSurface failed : " + GLUtils.getEGLErrorString(mEgl.eglGetError()));}if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {throw new RuntimeException("eglMakeCurrent failed : " + GLUtils.getEGLErrorString(mEgl.eglGetError()));}mGL = mEglContext.getGL();}private void destoryGL() {mEgl.eglDestroyContext(mEglDisplay, mEglContext);mEgl.eglDestroySurface(mEglDisplay, mEglSurface);mEglContext = EGL10.EGL_NO_CONTEXT;mEglSurface = EGL10.EGL_NO_SURFACE;}public void run() {initGL();if (mRenderer != null) {((GLRendererImpl)mRenderer).initGL();}while (mShouldRender != null && mShouldRender.get() != false) {if (mRenderer != null)mRenderer.drawFrame();mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);try {sleep(5);} catch(InterruptedException e) {}}destoryGL();}
}
在该线程中,我们定义了GLRenderer接口,该接口的实现者负责具体的OpenGL绘制代码:
package com.fyj.test;import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES20;
import android.opengl.GLUtils;
import android.util.Log;import com.fyj.test.GLProducerThread.GLRenderer;public class GLRendererImpl implements GLRenderer {private int mProgramObject;private int mWidth;private int mHeight;private FloatBuffer mVertices;private ShortBuffer mTexCoords;private Context mContext;private int mTexID;private static String TAG = "GLRendererImpl";private final float[] mVerticesData = { -0.5f, -0.5f, 0, 0.5f, -0.5f, 0, -0.5f, 0.5f, 0, 0.5f, 0.5f, 0 };private final short[] mTexCoordsData = {0, 1, 1, 1, 0, 0, 1, 0};public GLRendererImpl(Context ctx){mVertices = ByteBuffer.allocateDirect(mVerticesData.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();mVertices.put(mVerticesData).position(0);mTexCoords = ByteBuffer.allocateDirect(mTexCoordsData.length * 2).order(ByteOrder.nativeOrder()).asShortBuffer();mTexCoords.put(mTexCoordsData).position(0);mContext = ctx;}public void setViewport(int width, int height) {mWidth = width;mHeight = height;}public void initGL(){comipleAndLinkProgram();loadTexture();GLES20.glClearColor(0, 0, 0, 0);}public void resize(int width, int height) {mWidth = width;mHeight = height;}@Overridepublic void drawFrame() {// TODO Auto-generated method stubGLES20.glViewport(0, 0, mWidth, mHeight);GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);GLES20.glUseProgram(mProgramObject);GLES20.glVertexAttribPointer(0, 3, GLES20.GL_FLOAT, false, 0, mVertices);GLES20.glEnableVertexAttribArray(0);GLES20.glVertexAttribPointer(1, 2, GLES20.GL_SHORT, false, 0, mTexCoords);GLES20.glEnableVertexAttribArray(1);GLES20.glActiveTexture(GLES20.GL_TEXTURE0);GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexID);int loc = GLES20.glGetUniformLocation(mProgramObject, "u_Texture");GLES20.glUniform1f(loc, 0);GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);Log.i("GLRendererImpl", "drawing..." + mWidth);}private void loadTexture() {Bitmap b = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_launcher);if (b != null) {int []texID = new int[1];GLES20.glGenTextures(1, texID, 0);GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texID[0]);mTexID = texID[0];GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,GLES20.GL_REPEAT);GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,GLES20.GL_REPEAT);GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, b, 0);b.recycle();}}private int loadShader(int shaderType, String shaderSource) {int shader;int[] compiled = new int[1];// Create the shader objectshader = GLES20.glCreateShader(shaderType);if (shader == 0)return 0;// Load the shader sourceGLES20.glShaderSource(shader, shaderSource);// Compile the shaderGLES20.glCompileShader(shader);// Check the compile statusGLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);if (compiled[0] == 0) {Log.e(TAG, GLES20.glGetShaderInfoLog(shader));GLES20.glDeleteShader(shader);return 0;}return shader;}private void comipleAndLinkProgram() {String vShaderStr = "attribute vec4 a_position; \n"+"attribute vec2 a_texCoords; \n"+"varying vec2 v_texCoords; \n"+ "void main() \n"+ "{ \n"+ " gl_Position = a_position; \n"+" v_texCoords = a_texCoords; \n"+ "} \n";String fShaderStr = "precision mediump float; \n"+"uniform sampler2D u_Texture; \n"+"varying vec2 v_texCoords; \n"+ "void main() \n"+ "{ \n"+ " gl_FragColor = texture2D(u_Texture, v_texCoords) ;\n"+ "} \n";int vertexShader;int fragmentShader;int programObject;int[] linked = new int[1];// Load the vertex/fragment shadersvertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vShaderStr);fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fShaderStr);// Create the program objectprogramObject = GLES20.glCreateProgram();if (programObject == 0)return ;GLES20.glAttachShader(programObject, vertexShader);GLES20.glAttachShader(programObject, fragmentShader);// Bind vPosition to attribute 0GLES20.glBindAttribLocation(programObject, 0, "a_position");GLES20.glBindAttribLocation(programObject, 1, "a_texCoords");// Link the programGLES20.glLinkProgram(programObject);// Check the link statusGLES20.glGetProgramiv(programObject, GLES20.GL_LINK_STATUS, linked, 0);if (linked[0] == 0) {Log.e(TAG, "Error linking program:");Log.e(TAG, GLES20.glGetProgramInfoLog(programObject));GLES20.glDeleteProgram(programObject);return ;}mProgramObject = programObject;}
}
需要注意的是,所有EGL及GL相关的操作必须置于GLThread线程中进行。
转载于:https://my.oschina.net/fuyajun1983cn/blog/263790
基于textureview编写opengl程序相关推荐
- 计算机图形学(光栅显示系统、基于GLUT的OpenGL程序框架、基本图元光栅化)
1.光栅显示系统 图形显示设备–CRT光栅扫描显示器(阴极射线管显示器) 电子束轰击屏幕表面的荧光物质,从而产生不同亮度的光点,这些光点是显示器可以控制的最小单位,称为像素.光点会逐渐变暗,需要不断刷 ...
- python编程(编写opengl程序)
[ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] opengl作为跨平台的代表,本身使用很多.记得云风,也就是之前网易的主程,他写过一个ejoy2 ...
- 基于Win32框架的OpenGL程序
本示例提供一个稳定的基于Win32的OpenGL程序框架结构,开发工具是Visual Studio 2010,编程之前应该确保OpenGL所使用的库函数都已被正确配置: 第一步,安装GLUT工具包: ...
- 基于glut的OpenGL框架(一)
基于glut的OpenGL框架(一) --面向对象框架的搭建 我是一名OpenGL的初学者,在看完<OpenGL超级宝典>的前几章后,开始迫不及待地动手验证一下书上程序的代码了.我发现书上 ...
- OpenGL程序:实例练习
说起编程作图,大概还有很多人想起TC的#include <graphics.h>吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640*480分辨率.16色 ...
- 成功解决基于VS2015(Visual Studio2015)编写C++程序调试时弹出窗口一闪而过的问题
成功解决基于VS2015(Visual Studio2015)编写C++程序调试时弹出窗口一闪而过的问题 目录 解决问题 解决方法 T1.修改配置属性的控制台
- 基于Ubuntu(x86)系统和STM32(Keil)编写C程序分别进行编程、验证
文章目录 实验内容 一.基本概念 (一).全局变量 (二).局部变量 (三).堆和栈 二.编程验证 (一).基于Ubuntu用Linux系统编写C程序 (二).基于STM32用Keil编写C程序 三. ...
- python识别ppt文件格式 ——(专栏:基于python编写简单office阅卷程序③)
● 研二在读学生,非工科非计算机专业,故代码简陋初级勿喷,本文仅为记录和快乐分享. ○ 感谢肯定,感谢点赞收藏分享,转载请注明本页出处即可. ____Ⓙ即刻@王昭没有君 本文仅为笔者摸索总结-欢迎订正 ...
- arm裸机与嵌入式linux驱动开发,如何编写基于ARM的裸机程序和基于Linux的驱动程序?...
在嵌入式开发中,ADC应用比较频繁,本文主要讲解ADC的基本原理以及如何编写基于ARM的裸机程序和基于Linux的驱动程序. ARM架构:Cortex-A9Linux内核:3.14 在讲述ADC之前, ...
最新文章
- 双稳态电路的两个稳定状态是什么_振荡器基础4——什么是多谐振荡器(又称:弛张振荡器)?...
- C#学习笔记:多态与隐藏,覆盖
- 线性代数同济第六版_线性代数考试内容与课后习题
- php web框架 symfony简介
- 成绩查询系统源java代码_基于jsp的成绩查询系统-JavaEE实现成绩查询系统 - java项目源码...
- Delphi捕捉DLL执行所抛出的异常。
- 如何使用extern在源文件之间共享变量?
- Xen Server 7.0 一直无法退出维护模式
- 论文笔记_S2D.64_2021_MonoRec_动态环境下单目移动相机的半监督稠密重建
- Zookeeper案例之分布式全局唯一ID生成
- 去银行写代码是种什么体验?
- C语言图形编程中的绘图函数~
- 零基础英语语法速成(一)
- 简单的选课系统(6)——选课界面和管理员界面
- Travelling Salesman Problem(旅行商问题)
- 百度绿萝算法更新 众多网站摊上事了
- java 四舍六入五成双_EXCEL实现四舍六入五成双修约规则的方法
- java 二义性_Java接口默认方法带来的问题分析【二义性问题】
- 在启动MYSQL时出现问题:“ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)”
- 4h上手C++版Opencv
热门文章
- 13款经典JavaScript图形和图表绘制工具
- Elasticsearch: 权威指南 » 聚合 » Doc Values and Fielddata » 聚合与分析
- 数据库复习1——数据库体系结构和关系系统
- puppet安装与配置
- Win7旗舰版中的IIS配置asp.net的运行环境
- 线程安全的理论讲解(volatile)
- spring中的quartz调度问题
- python 报错 cannot import name ‘byte_string‘ from ‘Crypto.Util.py3compat‘ 解决方法
- linux auditd 审计 简介
- python sys模块 输入输出 错误流