代码参考自
http://www.cnblogs.com/bpasser/archive/2011/09/25/2189941.html
自定义GLSurface 并没有实现让surface 一直渲染 只在surfacecreate 时 渲染一次
package com.opengl;
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 android.content.Context;
import android.graphics.PixelFormat;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;
public class GLSurface extends SurfaceView implements Callback{
private Render render;
private EGL10 egl;
private EGLDisplay eglDisplay;
private EGLSurface eglSurface;
private EGLContext eglContext;
private String TAG = "GLSurface";
private boolean DEBUG = true;
private int surfaceWidth = 0;
private int surfaceHeight = 0;
public GLSurface(Context context) {
super(context);
// TODO Auto-generated constructor stub
SurfaceHolder holder = this.getHolder();
holder.addCallback(this);
holder.setFormat(PixelFormat.RGBA_8888);
}
public void surfaceChanged(SurfaceHolder arg0, int arg1, int width, int height) {
// TODO Auto-generated method stub
Log.e(TAG,"Surface changed");
if (width > 0 && height > 0
&& (width != this.surfaceWidth || height != this.surfaceHeight)) {
if (0 == this.surfaceWidth && 0 == this.surfaceHeight) {
this.surfaceWidth = width;
this.surfaceHeight = height;
}
}
else
{
this.surfaceWidth = width;
this.surfaceHeight = height;
}
//render.Resize(width, height);
}
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub
Log.e(TAG,"pre Surface create");
InitEGL();
render.Init();
if (null != render) {
render.Resize(surfaceWidth, surfaceHeight);
}
render.Render();
egl.eglSwapBuffers(eglDisplay, eglSurface);
}
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
Log.d(TAG, "pre surfaceDestroyed()...");
destroyEGL();
}
private boolean InitEGL() {
egl = (EGL10) EGLContext.getEGL();
//
eglDisplay = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
if (EGL10.EGL_NO_DISPLAY == eglDisplay) {
Log.e(TAG, "eglGetDisplay() failed");
destroyEGL();
return false;
}
//
int[] eglVersions = new int[2];
if (egl.eglInitialize(eglDisplay, eglVersions)) {
if (DEBUG) {
Log.d(TAG, "EGL version = "
+ eglVersions[0] + "." + eglVersions[1]);
}
} else {
Log.e(TAG, "eglInitialize() failed");
destroyEGL();
return false;
}
//
EGLConfig eglConfig;
int[] attrList = new int[] { //
EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT, //
EGL10.EGL_RED_SIZE, 5, //
EGL10.EGL_GREEN_SIZE, 6, //
EGL10.EGL_BLUE_SIZE, 5, //
//EGL10.EGL_ALPHA_SIZE, 0, //
EGL10.EGL_DEPTH_SIZE, 16,//
//EGL10.EGL_STENCIL_SIZE, 0 ,//
//EGL10.EGL_RENDERABLE_TYPE, 4 /* EGL_OPENGL_ES2_BIT */,
// EGL10.EGL_SAMPLE_BUFFERS, 1 /* true */,
//EGL10.EGL_SAMPLES, 2,
EGL10.EGL_NONE
//
// EGL10.EGL_NONE //
};
EGLConfig[] configs = new EGLConfig[1];
int[] numConfig = new int[1];
if (egl.eglChooseConfig(eglDisplay, attrList, configs, 1, numConfig)
&& numConfig[0] > 0) {
eglConfig = configs[0];
} else {
Log.e(TAG, "eglChooseConfig() failed");
destroyEGL();
return false;
}
//
eglContext = egl.eglCreateContext(eglDisplay, eglConfig,
EGL10.EGL_NO_CONTEXT, null);
if (EGL10.EGL_NO_CONTEXT == eglContext) {
Log.e(TAG, "eglCreateContext() failed");
destroyEGL();
return false;
}
//
eglSurface = egl.eglCreateWindowSurface(eglDisplay, eglConfig,
getHolder(), null);
if (EGL10.EGL_NO_SURFACE == eglSurface) {
Log.e(TAG, "eglCreateWindowSurface() failed");
destroyEGL();
return false;
}
//
if (!egl.eglMakeCurrent(eglDisplay, eglSurface, eglSurface,
eglContext)) {
Log.e(TAG, "eglMakeCurrent() failed");
destroyEGL();
return false;
}
return true;
// TODO Auto-generated method stub
}
private void destroyEGL() {
// TODO Auto-generated method stub
egl.eglMakeCurrent(eglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
egl.eglDestroySurface(eglDisplay, eglSurface);
egl.eglDestroyContext(eglDisplay, eglContext);
egl.eglTerminate(eglDisplay);
}
public void setRender(Render render) {
this.render = render;
}
public void onresume()
{
}
public void onpause()
{
}
}
Render 在Native 代码中实现
package com.opengl;
public class CustomRender implements Render{
static
{
System.loadLibrary("MyRender");
}
public native void Init();
public native void Render();
public native void Resize(int width, int height);
}
native 代码
com_opengl_CustomRender.c
#include "com_opengl_CustomRender.h"
#include "MyRender.h"
JNIEXPORT void JNICALL Java_com_opengl_CustomRender_Init
(JNIEnv *env, jobject obj)
{
Init();
}
JNIEXPORT void JNICALL Java_com_opengl_CustomRender_Render
(JNIEnv *env, jobject obj)
{
Render();
}
JNIEXPORT void JNICALL Java_com_opengl_CustomRender_Resize
(JNIEnv *env, jobject obj, jint width, jint height)
{
Resize(width, height);
}
MyRender.c
#include "MyRender.h"// size -- 顶点尺寸 x,y,z
//#include <GLES/glext.h>
#include <GLES/gl.h>
void Init()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glEnableClientState(GL_VERTEX_ARRAY); //开启顶点设置功能
}
void Resize(int width, int height)
{
// glViewport(0, 0, width, height);
float ratio = width/(float)height;
glMatrixMode(GL_PROJECTION); // set matrix to projection mode
glLoadIdentity(); // reset the matrix to its default state //重置阴影矩阵
glFrustumf(-ratio, ratio, -1, 1, -1, 7); // apply the projection matrix
}
static float triangleCoords[] = {
-0.25f, -0.25f, 0, //
0.25f, -0.25f, 0, //
0.0f, 0.433012702f, 0 //
};
static float square[] = {
-0.25f, -0.25f, 0.0f,
0.25f, -0.25f, 0.0f,
0.25f, 0.25f, 0.0f,
-0.25f, 0.25f, 0.0f
};
void Render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor4f(1.0f, 1.0f, 1.0f, 0.0f);
glVertexPointer(3, GL_FLOAT, 0, triangleCoords); // glVertexPointer(size, type, stride, points);
// type -- 顶点类型
// stride -- 步长
// points -- 顶点缓存
glTranslatef(-0.5f, 0.0f, 0.0f );
glDrawArrays(GL_TRIANGLES, 0, 3); //绘制
GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
glVertexPointer(3, GL_FLOAT, 0, square);
glTranslatef(1.0f, 0.0f, 0.0f);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
}