最近研究fastcv的sample,其中用到了opengl es,而自己又是opengl es的小白,所以第一接触opengl es的话,我想以一个最简单的例子帮助自己入门!
首先,创建一个自己的MyGLSurfaceView,继承GLSurfaceView,其中所做的工作非常的简单,就是为我的MyGLSurfaceView设置渲染器Renderer,而此Renderer也是我自己重新创建的MyRenderer,它实现了GLSurfaceView.Renderer接口。
MyGLSurfaceView.java
package org.hwm.app.opengldemo;
import android.content.Context;
import android.opengl.GLSurfaceView;
public class MyGLSurfaceView extends GLSurfaceView{
MyRenderer mRenderer;
public MyGLSurfaceView(Context context) {
super(context);
mRenderer = new MyRenderer(context);
setRenderer(mRenderer);
}
}
MyRenderer.java
package org.hwm.app.opengldemo;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.opengl.GLSurfaceView;
public class MyRenderer implements GLSurfaceView.Renderer{
static {
System.loadLibrary("opengl_process");
}
public MyRenderer(Context context) {
}
@Override
public void onDrawFrame(GL10 arg0) {
draw();
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
resize(width, height);
}
@Override
public void onSurfaceCreated(GL10 arg0, EGLConfig arg1) {
init();
}
public static native void draw();
public static native void resize(int width, int height);
public static native void init();
}
其中的System.LoadLibrary("opengl_process")是一定要记得执行的,此行的作用是加载C++生成的库,就是对应的lib文件夹中的.os文件,而"opengl_process"要和Android.mk文件中的LOCAL_MODULE名字相同才行!
拉下来就是我的C++文件了,其实就是实现上上述的3个native方法
#include "MyRenderer.h"
#include <android/log.h>
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <math.h>
static const GLfloat PI = 3.1415f;
static float _angle = 60.0f;
static float _cameraAngle = 0.0f;
static void _gluPerspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar)
{
GLfloat top = zNear * ((GLfloat) tan(fovy * PI / 360.0));
GLfloat bottom = -top;
GLfloat left = bottom * aspect;
GLfloat right = top * aspect;
glFrustumf(left, right, bottom, top, zNear, zFar);
}
bool init() {
glEnable(GL_DEPTH_TEST);
// important
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
return true;
}
void resize(int width, int height)
{
if (height==0){
height=1;
}
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
_gluPerspective(45.0, (double)width / (double)height, 1.0, 200.0);
}
void draw() {
_angle += 2.0f;
if (_angle > 360) {
_angle -= 360;
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
glLoadIdentity(); //Reset the drawing perspective
glTranslatef(0.0f, 0.0f, -5.0f); //Move forward 5 units
glRotatef(-_cameraAngle, 0.0f, 1.0f, 0.0f); //Rotate the camera
glRotatef(_angle, 1.0f, 2.0f, 3.0f); //Rotate about the the vector (1, 2, 3)
//Triangle
glEnableClientState(GL_VERTEX_ARRAY);
const GLfloat gVertices[] = {
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
};
glVertexPointer(3, GL_FLOAT, 0, gVertices);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableClientState(GL_VERTEX_ARRAY);
}
JNIEXPORT void JNICALL Java_org_hwm_app_opengldemo_MyRenderer_draw
(JNIEnv * env, jclass obj) {
draw();
}
JNIEXPORT void JNICALL Java_org_hwm_app_opengldemo_MyRenderer_resize
(JNIEnv * ebv, jclass obj, jint width, jint height) {
resize(width, height);
}
JNIEXPORT void JNICALL Java_org_hwm_app_opengldemo_MyRenderer_init
(JNIEnv * env, jclass obj) {
init();
}
以及我的Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := opengl_process
LOCAL_CFLAGS := -Werror
LOCAL_SRC_FILES := process.cpp
LOCAL_LDLIBS := -llog -lGLESv2 -lGLESv1_CM
include $(BUILD_SHARED_LIBRARY)
下面是我的Activity代码,其中实例化了一个Timer,并设置任务用以不断旋转三角形。
package org.hwm.app.opengldemo;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
MyGLSurfaceView mGLSurfaceView;
static {
System.loadLibrary("opengl_process");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGLSurfaceView = new MyGLSurfaceView(this);
setContentView(mGLSurfaceView);
new Timer().schedule(new TimerTask(){
@Override
public void run() {
mGLSurfaceView.requestRender();
}
}, 25);
}
@Override
public void onResume() {
super.onResume();
mGLSurfaceView.onResume();
}
@Override
public void onPause() {
super.onPause();
mGLSurfaceView.onPause();
}
}
是不是很简单?当然,再学习opengl es之前还是应该学学opengl,这样才会有助于理解!