与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程序相关推荐

  1. 计算机图形学(光栅显示系统、基于GLUT的OpenGL程序框架、基本图元光栅化)

    1.光栅显示系统 图形显示设备–CRT光栅扫描显示器(阴极射线管显示器) 电子束轰击屏幕表面的荧光物质,从而产生不同亮度的光点,这些光点是显示器可以控制的最小单位,称为像素.光点会逐渐变暗,需要不断刷 ...

  2. python编程(编写opengl程序)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] opengl作为跨平台的代表,本身使用很多.记得云风,也就是之前网易的主程,他写过一个ejoy2 ...

  3. 基于Win32框架的OpenGL程序

    本示例提供一个稳定的基于Win32的OpenGL程序框架结构,开发工具是Visual Studio 2010,编程之前应该确保OpenGL所使用的库函数都已被正确配置: 第一步,安装GLUT工具包: ...

  4. 基于glut的OpenGL框架(一)

    基于glut的OpenGL框架(一) --面向对象框架的搭建 我是一名OpenGL的初学者,在看完<OpenGL超级宝典>的前几章后,开始迫不及待地动手验证一下书上程序的代码了.我发现书上 ...

  5. OpenGL程序:实例练习

    说起编程作图,大概还有很多人想起TC的#include <graphics.h>吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640*480分辨率.16色 ...

  6. 成功解决基于VS2015(Visual Studio2015)编写C++程序调试时弹出窗口一闪而过的问题

    成功解决基于VS2015(Visual Studio2015)编写C++程序调试时弹出窗口一闪而过的问题 目录 解决问题 解决方法 T1.修改配置属性的控制台

  7. 基于Ubuntu(x86)系统和STM32(Keil)编写C程序分别进行编程、验证

    文章目录 实验内容 一.基本概念 (一).全局变量 (二).局部变量 (三).堆和栈 二.编程验证 (一).基于Ubuntu用Linux系统编写C程序 (二).基于STM32用Keil编写C程序 三. ...

  8. python识别ppt文件格式 ——(专栏:基于python编写简单office阅卷程序③)

    ● 研二在读学生,非工科非计算机专业,故代码简陋初级勿喷,本文仅为记录和快乐分享. ○ 感谢肯定,感谢点赞收藏分享,转载请注明本页出处即可. ____Ⓙ即刻@王昭没有君 本文仅为笔者摸索总结-欢迎订正 ...

  9. arm裸机与嵌入式linux驱动开发,如何编写基于ARM的裸机程序和基于Linux的驱动程序?...

    在嵌入式开发中,ADC应用比较频繁,本文主要讲解ADC的基本原理以及如何编写基于ARM的裸机程序和基于Linux的驱动程序. ARM架构:Cortex-A9Linux内核:3.14 在讲述ADC之前, ...

最新文章

  1. 双稳态电路的两个稳定状态是什么_振荡器基础4——什么是多谐振荡器(又称:弛张振荡器)?...
  2. C#学习笔记:多态与隐藏,覆盖
  3. 线性代数同济第六版_线性代数考试内容与课后习题
  4. php web框架 symfony简介
  5. 成绩查询系统源java代码_基于jsp的成绩查询系统-JavaEE实现成绩查询系统 - java项目源码...
  6. Delphi捕捉DLL执行所抛出的异常。
  7. 如何使用extern在源文件之间共享变量?
  8. Xen Server 7.0 一直无法退出维护模式
  9. 论文笔记_S2D.64_2021_MonoRec_动态环境下单目移动相机的半监督稠密重建
  10. Zookeeper案例之分布式全局唯一ID生成
  11. 去银行写代码是种什么体验?
  12. C语言图形编程中的绘图函数~
  13. 零基础英语语法速成(一)
  14. 简单的选课系统(6)——选课界面和管理员界面
  15. Travelling Salesman Problem(旅行商问题)
  16. 百度绿萝算法更新 众多网站摊上事了
  17. java 四舍六入五成双_EXCEL实现四舍六入五成双修约规则的方法
  18. java 二义性_Java接口默认方法带来的问题分析【二义性问题】
  19. 在启动MYSQL时出现问题:“ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)”
  20. 4h上手C++版Opencv

热门文章

  1. 13款经典JavaScript图形和图表绘制工具
  2. Elasticsearch: 权威指南 » 聚合 » Doc Values and Fielddata » 聚合与分析
  3. 数据库复习1——数据库体系结构和关系系统
  4. puppet安装与配置
  5. Win7旗舰版中的IIS配置asp.net的运行环境
  6. 线程安全的理论讲解(volatile)
  7. spring中的quartz调度问题
  8. python 报错 cannot import name ‘byte_string‘ from ‘Crypto.Util.py3compat‘ 解决方法
  9. linux auditd 审计 简介
  10. python sys模块 输入输出 错误流