当前位置: 首页 > news >正文

.la域名的门户网站web成品网站源码免费

.la域名的门户网站,web成品网站源码免费,程序开发步骤不包括,广州网站建设的价格1 前言 Android 中,GLSurfaceView 封装了 EGL 环境,使得我们省去了复杂的 EGL 环境搭建。如果我们不用 GLSurfaceView,该如何渲染 OpenGL ES 图像?在回答此问题前,我们先了解下 EGL。 EGL 是 Khronos Group 定义的平台…

1 前言

        Android 中,GLSurfaceView 封装了 EGL 环境,使得我们省去了复杂的 EGL 环境搭建。如果我们不用 GLSurfaceView,该如何渲染 OpenGL ES 图像?在回答此问题前,我们先了解下 EGL。

        EGL 是 Khronos Group 定义的平台无关接口,作为 OpenGL ES 和本地窗口系统之间的桥梁,主要功能如下。

  • 管理图形上下文
  • 创建和管理渲染表面 (surface)
  • 同步渲染与平台显示系统

        EGL 提供了两种渲染方式,分别是离屏渲染和窗口渲染,分别对应 eglCreatePbufferSurface 和 eglCreateWindowSurface。对于离屏渲染方案,详见 → EGL+FBO离屏渲染。eglCreateWindowSurface 函数的源码如下。

public static EGLSurface eglCreateWindowSurface(EGLDisplay dpy,EGLConfig config, Object win, int[] attrib_list, int offset){Surface sur = null;if (win instanceof SurfaceView) {SurfaceView surfaceView = (SurfaceView)win;sur = surfaceView.getHolder().getSurface();} else if (win instanceof SurfaceHolder) {SurfaceHolder holder = (SurfaceHolder)win;sur = holder.getSurface();} else if (win instanceof Surface) {sur = (Surface) win;}EGLSurface surface;if (sur != null) {surface = _eglCreateWindowSurface(dpy, config, sur, attrib_list, offset);} else if (win instanceof SurfaceTexture) {surface = _eglCreateWindowSurfaceTexture(dpy, config,win, attrib_list, offset);} else {throw new java.lang.UnsupportedOperationException("eglCreateWindowSurface() can only be called with an instance of " +"Surface, SurfaceView, SurfaceTexture or SurfaceHolder at the moment, " +"this will be fixed later.");}return surface;
}

        主要留意 win 参数,可以看到它可以是 SurfaceView、SurfaceHolder、Surface,本质都是为了获取 Surface。因此我们提供了以下两种渲染图像的方案。

  • 继承 SurfaceView 方案:自定义一个 View 继承 SurfaceView,并实现 SurfaceHolder.Callback 接口,在 surfaceCreated 方法中将 this 或 getHolder() 传给 eglCreateWindowSurface 函数。
  • 继承 TextureView 方案:自定义一个 View 继承 TextureView,并实现 TextureView.SurfaceTextureListener 接口,在 onSurfaceTextureAvailable 方法中会提供 SurfaceTexture,我们可以创建一个 Surface,并将 SurfaceTexture 传给 Surface,然后将创建的 Surface 传给 eglCreateWindowSurface 函数。

        本文完整代码详见 → 不用GLSurfaceView,如何渲染图像。

2 继承 SurfaceView 方案

        自定义一个 View 继承 SurfaceView,并实现 SurfaceHolder.Callback 接口,在 surfaceCreated 方法中将 this 或 getHolder() 传给 eglCreateWindowSurface 函数。

        由于 GLSurfaceView 继承 SurfaceView,所以该方案很容易想到,只需要将 GLSurfaceView 的核心代码扣出来就行。

        MainActivity.java

package com.zhyan8.egldemo;import android.os.Bundle;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {private EGLSurfaceView mEglSurfaceView;protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mEglSurfaceView = new EGLSurfaceView(this);setContentView(mEglSurfaceView);mEglSurfaceView.setRenderer(new MyRenderer(this));mEglSurfaceView.requestRender();//mEglSurfaceView.startRender();}@Overrideprotected void onResume() {super.onResume();mEglSurfaceView.requestRender();//mEglSurfaceView.startRender();}@Overrideprotected void onPause() {super.onPause();mEglSurfaceView.stopRender();}
}

        EGLSurfaceView.java

package com.zhyan8.egldemo;import android.content.Context;
import android.opengl.EGL14;
import android.opengl.EGLConfig;
import android.opengl.EGLContext;
import android.opengl.EGLDisplay;
import android.opengl.EGLExt;
import android.opengl.EGLSurface;
import android.util.Log;
import android.view.Choreographer;
import android.view.SurfaceHolder;
import android.view.SurfaceView;import androidx.annotation.NonNull;/*** @author little fat sheep* 承载EGL环境的View, 类比GLSurfaceView*/
public class EGLSurfaceView extends SurfaceView implements SurfaceHolder.Callback {private static final String TAG = "EGLSurfaceView";protected EGLDisplay mEGLDisplay;protected EGLConfig mEGLConfig;protected EGLContext mEGLContext;protected EGLSurface mEGLSurface;protected Context mContext;protected Renderer mRenderer;protected boolean mFirstCreateSurface = true;public EGLSurfaceView(Context context) {super(context);mContext = context;getHolder().addCallback(this);}// 设置渲染器public void setRenderer(Renderer renderer) {mRenderer = renderer;}// 开始持续渲染public void startRender() {Choreographer.getInstance().postFrameCallback(mFrameCallback);}// 暂停持续渲染public void stopRender() {Choreographer.getInstance().removeFrameCallback(mFrameCallback);}// 请求渲染一帧public void requestRender() {mFrameCallback.doFrame(System.nanoTime());}@Overrideprotected void onAttachedToWindow() {super.onAttachedToWindow();createDisplay();createConfig();createContext();}@Overridepublic void surfaceCreated(@NonNull SurfaceHolder holder) { // 每次activity resume都会调用一次Log.i(TAG, "surfaceCreated, surface=" + holder.getSurface());createSurface();makeCurrent();if (mFirstCreateSurface) {mRenderer.onSurfaceCreated();mFirstCreateSurface = false;}}@Overridepublic void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {Log.i(TAG, "surfaceChanged, width=" + width + ", height=" + height);mRenderer.onSurfaceChanged(width, height);}@Overridepublic void surfaceDestroyed(@NonNull SurfaceHolder holder) { // 每次activity pause都会调用一次Log.i(TAG, "surfaceDestroyed");if (mEGLDisplay != null && mEGLDisplay != EGL14.EGL_NO_DISPLAY) {// 与显示设备解绑EGL14.eglMakeCurrent(mEGLDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT);// 销毁 EGLSurfaceif (mEGLSurface != null && mEGLSurface != EGL14.EGL_NO_SURFACE) {EGL14.eglDestroySurface(mEGLDisplay, mEGLSurface);checkoutConfig("eglDestroySurface");mEGLSurface = null;}}}@Overridepublic void onDetachedFromWindow() {super.onDetachedFromWindow();Log.i(TAG, "onDetachedFromWindow");getHolder().removeCallback(this);if (mEGLDisplay != null && mEGLDisplay != EGL14.EGL_NO_DISPLAY) {// 与显示设备解绑EGL14.eglMakeCurrent(mEGLDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT);// 销毁 EGLSurfaceif (mEGLSurface != null && mEGLSurface != EGL14.EGL_NO_SURFACE) {EGL14.eglDestroySurface(mEGLDisplay, mEGLSurface);checkoutConfig("eglDestroySurface");mEGLSurface = null;}// 销毁 EGLContextif (mEGLContext != null && mEGLContext != EGL14.EGL_NO_CONTEXT) {EGL14.eglDestroyContext(mEGLDisplay, mEGLContext);checkoutConfig("eglDestroyContext");mEGLContext = null;}// 销毁 EGLDisplay (显示设备)EGL14.eglTerminate(mEGLDisplay);checkoutConfig("eglTerminate");mEGLDisplay = null;}}// 1.创建EGLDisplayprivate void createDisplay() {mEGLDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);int[] versions = new int[2];EGL14.eglInitialize(mEGLDisplay, versions,0, versions, 1);checkoutConfig("eglInitialize");}// 2.创建EGLConfigprivate void createConfig() {if (mEGLDisplay != null && mEGLDisplay != EGL14.EGL_NO_DISPLAY) {EGLConfig[] configs = new EGLConfig[1];int[] configNum = new int[1];EGL14.eglChooseConfig(mEGLDisplay, mEGLConfigAttrs, 0, configs, 0,1,  configNum, 0);if (configNum[0] > 0) {mEGLConfig = configs[0];}checkoutConfig("eglChooseConfig");}}// 3.创建EGLContextprivate void createContext() {if (mEGLConfig != null) {mEGLContext = EGL14.eglCreateContext(mEGLDisplay, mEGLConfig, EGL14.EGL_NO_CONTEXT, mEGLContextAttrs, 0);checkoutConfig("eglCreateContext");}}// 4.创建EGLSurfaceprivate void createSurface() {if (mEGLContext != null && mEGLContext != EGL14.EGL_NO_CONTEXT) {int[] eglSurfaceAttrs = { EGL14.EGL_NONE };//mEGLSurface = EGL14.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, getHolder(), eglSurfaceAttrs, 0);mEGLSurface = EGL14.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, this, eglSurfaceAttrs, 0);checkoutConfig("eglCreateWindowSurface");}}// 5.绑定EGLSurface和EGLContext到显示设备(EGLDisplay)private void makeCurrent() {if (mEGLSurface != null && mEGLSurface != EGL14.EGL_NO_SURFACE) {EGL14.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext);checkoutConfig("eglMakeCurrent");}}private void checkoutConfig(String tag) {int error = EGL14.eglGetError();if (error != EGL14.EGL_SUCCESS) {Log.e(TAG, tag + " error=0x" + Integer.toHexString(error));}}// EGLConfig参数private int[] mEGLConfigAttrs = {EGL14.EGL_RED_SIZE, 8,EGL14.EGL_GREEN_SIZE, 8,EGL14.EGL_BLUE_SIZE, 8,EGL14.EGL_ALPHA_SIZE, 8,EGL14.EGL_DEPTH_SIZE, 8,//EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,EGL14.EGL_RENDERABLE_TYPE, EGLExt.EGL_OPENGL_ES3_BIT_KHR,EGL14.EGL_NONE};// EGLContext参数private int[] mEGLContextAttrs = {EGL14.EGL_CONTEXT_CLIENT_VERSION, 3,EGL14.EGL_NONE};Choreographer.FrameCallback mFrameCallback = new Choreographer.FrameCallback() {@Overridepublic void doFrame(long frameTimeNanos) {Choreographer.getInstance().postFrameCallback(mFrameCallback);if (mEGLSurface != null) {mRenderer.onDrawFrame();EGL14.eglSwapBuffers(mEGLDisplay, mEGLSurface);checkoutConfig("eglSwapBuffers");}}};/*** @author little fat sheep* 渲染器接口, 类比GLSurfaceView.Renderer*/interface Renderer {void onSurfaceCreated();void onSurfaceChanged(int width, int height);void onDrawFrame();}
}

        MyRenderer.java

package com.zhyan8.egldemo;import android.content.Context;
import android.opengl.GLES30;import java.nio.FloatBuffer;public class MyRenderer implements EGLSurfaceView.Renderer {private FloatBuffer vertexBuffer;private FloatBuffer textureBuffer;private MyGLUtils mGLUtils;private int mTextureId;public MyRenderer(Context context) {mGLUtils = new MyGLUtils(context);getFloatBuffer();}@Overridepublic void onSurfaceCreated() {//设置背景颜色GLES30.glClearColor(0.1f, 0.2f, 0.3f, 0.4f);//编译着色器final int vertexShaderId = mGLUtils.compileShader(GLES30.GL_VERTEX_SHADER, R.raw.vertex_shader);final int fragmentShaderId = mGLUtils.compileShader(GLES30.GL_FRAGMENT_SHADER, R.raw.fragment_shader);//链接程序片段int programId = mGLUtils.linkProgram(vertexShaderId, fragmentShaderId);GLES30.glUseProgram(programId);mTextureId = mGLUtils.loadTexture(R.raw.girl);}@Overridepublic void onSurfaceChanged(int width, int height) {//设置视图窗口GLES30.glViewport(0, 0, width, height);}@Overridepublic void onDrawFrame() {//将颜色缓冲区设置为预设的颜色GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);//启用顶点的数组句柄GLES30.glEnableVertexAttribArray(0);GLES30.glEnableVertexAttribArray(1);//准备顶点坐标和纹理坐标GLES30.glVertexAttribPointer(0, 3, GLES30.GL_FLOAT, false, 0, vertexBuffer);GLES30.glVertexAttribPointer(1, 2, GLES30.GL_FLOAT, false, 0, textureBuffer);//激活纹理GLES30.glActiveTexture(GLES30.GL_TEXTURE);//绑定纹理GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, mTextureId);//绘制贴图GLES30.glDrawArrays(GLES30.GL_TRIANGLE_FAN, 0, 4);//禁止顶点数组句柄GLES30.glDisableVertexAttribArray(0);GLES30.glDisableVertexAttribArray(1);}private void getFloatBuffer() {float[] vertex = new float[] {1f, 1f, 0f,     //V0-1f, 1f, 0f,    //V1-1f, -1f, 0f,   //V21f, -1f, 0f     //V3};float[] texture = {1f, 0f,     //V00f, 0f,     //V10f, 1.0f,   //V21f, 1.0f    //V3};vertexBuffer = mGLUtils.getFloatBuffer(vertex);textureBuffer = mGLUtils.getFloatBuffer(texture);}
}

        MyGLUtils.java

package com.zhyan8.egldemo;import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES30;
import android.opengl.GLUtils;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;public class MyGLUtils {private Context mContext;private Bitmap mBitmap;public MyGLUtils(Context context) {mContext = context;}public FloatBuffer getFloatBuffer(float[] floatArr) {FloatBuffer fb = ByteBuffer.allocateDirect(floatArr.length * Float.BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();fb.put(floatArr);fb.position(0);return fb;}//通过代码片段编译着色器public int compileShader(int type, String shaderCode){int shader = GLES30.glCreateShader(type);GLES30.glShaderSource(shader, shaderCode);GLES30.glCompileShader(shader);return shader;}//通过外部资源编译着色器public int compileShader(int type, int shaderId){String shaderCode = readShaderFromResource(shaderId);return compileShader(type, shaderCode);}//链接到着色器public int linkProgram(int vertexShaderId, int fragmentShaderId) {final int programId = GLES30.glCreateProgram();//将顶点着色器加入到程序GLES30.glAttachShader(programId, vertexShaderId);//将片元着色器加入到程序GLES30.glAttachShader(programId, fragmentShaderId);//链接着色器程序GLES30.glLinkProgram(programId);return programId;}//从shader文件读出字符串private String readShaderFromResource(int shaderId) {InputStream is = mContext.getResources().openRawResource(shaderId);BufferedReader br = new BufferedReader(new InputStreamReader(is));String line;StringBuilder sb = new StringBuilder();try {while ((line = br.readLine()) != null) {sb.append(line);sb.append("\n");}br.close();} catch (Exception e) {e.printStackTrace();}return sb.toString();}//加载纹理贴图public int loadTexture(int resourceId) {BitmapFactory.Options options = new BitmapFactory.Options();options.inScaled = false;mBitmap = BitmapFactory.decodeResource(mContext.getResources(), resourceId, options);final int[] textureIds = new int[1];// 生成纹理idGLES30.glGenTextures(1, textureIds, 0);// 绑定纹理到OpenGLGLES30.glBindTexture(GLES30.GL_TEXTURE_2D, textureIds[0]);GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_LINEAR_MIPMAP_LINEAR);GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_LINEAR);// 加载bitmap到纹理中GLUtils.texImage2D(GLES30.GL_TEXTURE_2D, 0, mBitmap, 0);// 生成MIP贴图GLES30.glGenerateMipmap(GLES30.GL_TEXTURE_2D);// 取消绑定纹理GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, 0);return textureIds[0];}
}

        vertex_shader.glsl

precision mediump float;
uniform sampler2D uTextureUnit;
varying vec2 vTexCoord;
void main() {gl_FragColor = texture2D(uTextureUnit, vTexCoord);
}

        fragment_shader.glsl

attribute vec4 aPosition;
attribute vec2 aTextureCoord;
varying vec2 vTexCoord;
void main() {gl_Position = aPosition;vTexCoord = aTextureCoord;
}

        运行效果如下。

3 继承 TextureView 方案

        自定义一个 View 继承 TextureView,并实现 TextureView.SurfaceTextureListener 接口,在 onSurfaceTextureAvailable 方法中会提供 SurfaceTexture,我们可以创建一个 Surface,并将 SurfaceTexture 传给 Surface,然后将创建的 Surface 传给 eglCreateWindowSurface 函数。

        前段时间在看 Rive 的源码,详见 → rive-android源码分析,了解到 Rive 底层是通过 OpenGL ES 渲染图像,并且也没有使用 GLSurfaceView,由此借鉴而来。该方案主要参考 Rive 中 RiveTextureView 的实现,eglCreateWindowSurface 参考 thread_state_egl.cpp。

        与第二节相比,只有 EGLSurfaceView 类有差异,因此本节仅展示 EGLSurfaceView 的代码。

        EGLSurfaceView.java

package com.zhyan8.egldemo;import android.content.Context;
import android.graphics.SurfaceTexture;
import android.opengl.EGL14;
import android.opengl.EGLConfig;
import android.opengl.EGLContext;
import android.opengl.EGLDisplay;
import android.opengl.EGLExt;
import android.opengl.EGLSurface;
import android.util.Log;
import android.view.Choreographer;
import android.view.Surface;
import android.view.TextureView;import androidx.annotation.NonNull;/*** @author little fat sheep* 承载EGL环境的View, 类比GLSurfaceView*/
public class EGLSurfaceView extends TextureView implements TextureView.SurfaceTextureListener {private static final String TAG = "EGLSurfaceView";protected EGLDisplay mEGLDisplay;protected EGLConfig mEGLConfig;protected EGLContext mEGLContext;protected EGLSurface mEGLSurface;protected Context mContext;protected Surface mSurface;protected Renderer mRenderer;public EGLSurfaceView(Context context) {super(context);mContext = context;setSurfaceTextureListener(this);}// 设置渲染器public void setRenderer(Renderer renderer) {mRenderer = renderer;}// 开始持续渲染public void startRender() {Choreographer.getInstance().postFrameCallback(mFrameCallback);}// 暂停持续渲染public void stopRender() {Choreographer.getInstance().removeFrameCallback(mFrameCallback);}// 请求渲染一帧public void requestRender() {mFrameCallback.doFrame(System.nanoTime());}@Overrideprotected void onAttachedToWindow() {super.onAttachedToWindow();Log.i(TAG, "onAttachedToWindow");createDisplay();createConfig();createContext();}@Overridepublic void onSurfaceTextureAvailable(@NonNull SurfaceTexture surface, int width, int height) {Log.i(TAG, "onSurfaceTextureAvailable");mSurface = new Surface(surface);createSurface();makeCurrent();mRenderer.onSurfaceCreated();}@Overridepublic void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width, int height) {Log.i(TAG, "onSurfaceTextureSizeChanged, width=" + width + ", height=" + height);mRenderer.onSurfaceChanged(width, height);}@Overridepublic boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) {Log.i(TAG, "onSurfaceTextureDestroyed");return false;}@Overridepublic void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {}@Overrideprotected void onDetachedFromWindow() {super.onDetachedFromWindow();Log.i(TAG, "onDetachedFromWindow");setSurfaceTextureListener(null);mSurface.release();if (mEGLDisplay != null && mEGLDisplay != EGL14.EGL_NO_DISPLAY) {// 与显示设备解绑EGL14.eglMakeCurrent(mEGLDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT);// 销毁 EGLSurfaceif (mEGLSurface != null && mEGLSurface != EGL14.EGL_NO_SURFACE) {EGL14.eglDestroySurface(mEGLDisplay, mEGLSurface);checkoutConfig("eglDestroySurface");mEGLSurface = null;}// 销毁 EGLContextif (mEGLContext != null && mEGLContext != EGL14.EGL_NO_CONTEXT) {EGL14.eglDestroyContext(mEGLDisplay, mEGLContext);checkoutConfig("eglDestroyContext");mEGLContext = null;}// 销毁 EGLDisplay (显示设备)EGL14.eglTerminate(mEGLDisplay);checkoutConfig("eglTerminate");mEGLDisplay = null;}}// 1.创建EGLDisplayprivate void createDisplay() {mEGLDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);int[] versions = new int[2];EGL14.eglInitialize(mEGLDisplay, versions,0, versions, 1);checkoutConfig("eglInitialize");}// 2.创建EGLConfigprivate void createConfig() {if (mEGLDisplay != null && mEGLDisplay != EGL14.EGL_NO_DISPLAY) {EGLConfig[] configs = new EGLConfig[1];int[] configNum = new int[1];EGL14.eglChooseConfig(mEGLDisplay, mEGLConfigAttrs, 0, configs, 0,1,  configNum, 0);if (configNum[0] > 0) {mEGLConfig = configs[0];}checkoutConfig("eglChooseConfig");}}// 3.创建EGLContextprivate void createContext() {if (mEGLConfig != null) {mEGLContext = EGL14.eglCreateContext(mEGLDisplay, mEGLConfig, EGL14.EGL_NO_CONTEXT, mEGLContextAttrs, 0);checkoutConfig("eglCreateContext");}}// 4.创建EGLSurfaceprivate void createSurface() {if (mEGLContext != null && mEGLContext != EGL14.EGL_NO_CONTEXT) {int[] eglSurfaceAttrs = { EGL14.EGL_NONE };mEGLSurface = EGL14.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, mSurface, eglSurfaceAttrs, 0);checkoutConfig("eglCreateWindowSurface");}}// 5.绑定EGLSurface和EGLContext到显示设备(EGLDisplay)private void makeCurrent() {if (mEGLSurface != null && mEGLSurface != EGL14.EGL_NO_SURFACE) {EGL14.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext);checkoutConfig("eglMakeCurrent");}}private void checkoutConfig(String tag) {int error = EGL14.eglGetError();if (error != EGL14.EGL_SUCCESS) {Log.e(TAG, tag + " error=0x" + Integer.toHexString(error));}}// EGLConfig参数private int[] mEGLConfigAttrs = {EGL14.EGL_RED_SIZE, 8,EGL14.EGL_GREEN_SIZE, 8,EGL14.EGL_BLUE_SIZE, 8,EGL14.EGL_ALPHA_SIZE, 8,EGL14.EGL_DEPTH_SIZE, 8,//EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,EGL14.EGL_RENDERABLE_TYPE, EGLExt.EGL_OPENGL_ES3_BIT_KHR,EGL14.EGL_NONE};// EGLContext参数private int[] mEGLContextAttrs = {EGL14.EGL_CONTEXT_CLIENT_VERSION, 3,EGL14.EGL_NONE};Choreographer.FrameCallback mFrameCallback = new Choreographer.FrameCallback() {@Overridepublic void doFrame(long frameTimeNanos) {Choreographer.getInstance().postFrameCallback(mFrameCallback);if (mEGLSurface != null) {mRenderer.onDrawFrame();EGL14.eglSwapBuffers(mEGLDisplay, mEGLSurface);checkoutConfig("eglSwapBuffers");}}};/*** @author little fat sheep* 渲染器接口, 类比GLSurfaceView.Renderer*/interface Renderer {void onSurfaceCreated();void onSurfaceChanged(int width, int height);void onDrawFrame();}
}

        运行效果如下。

http://www.hrbkazy.com/news/12988.html

相关文章:

  • 北京智联招聘官方网站做家政民生热点新闻
  • 南宁网站建设教学百度收录域名
  • 潍坊网站制作企业sem是什么检测分析
  • 网站图片滚动是怎么做的产品网络推广方式
  • 网站建设app哪个好用软文广告例子
  • 代购网站怎么做的网站推广怎么做有效果
  • 做不规则几何图形的网站域名注册需要哪些条件
  • 网站设计英文报告seo长沙
  • 东莞网站制作支付通道网络营销公司名称
  • 做医院的系统网站怎么做seo技术培训课程
  • 集团做网站怎么建立网站?
  • 无锡网站搜索优化2023年百度小说风云榜
  • 郑州网站建设行情站长之家论坛
  • 网页设计图片居中代码百度关键字优化
  • 网站发展趋势和前景培训机构招生7个方法
  • 北京做网站比较有名的公司有哪些今日头条搜索优化
  • 广州网站建设公司排行惠州seo博客
  • 少女前线b站服百度搜索风云榜电视剧
  • 网站内的链接怎么做网络服务器图片
  • 移动端web app网站开发重庆seo论坛
  • 摄影网页设计方案上海单个关键词优化
  • 怎么把网站做成软件厦门seo优化
  • 内蒙古知名网站建设seo代理计费系统
  • 做网站推广电话什么是整合营销概念
  • phpcms 友情链接 网站名称字数抖音怎么推广引流
  • 权威的企业网站建设营销型网站推广方案
  • 自己建网站能赚钱吗软文范例大全800
  • 婚庆公司网站模板seo技巧分享
  • wordpress找不到对象西安seo托管
  • 邯郸做网站哪儿好制定营销推广方案