当前位置

网站首页> 程序设计 > 开源项目 > 程序开发 > 浏览文章

OpenGL ES2 学习教程1——Android入口 - 游戏生活

作者:小梦 来源: 网络 时间: 2024-08-25 阅读:

本教程适用于学习opengles,采用c++语言。基于Android平台。源码可以从这里获取。

创建工程

可以使用android-studio,eclipse去创建一个工程,这里我使用命令行(Android的环境配置略)。

# create android projectmkdir GlesTutorialcd GlesTutorialandroid create project --target android-19 --name GlesTutorial --path ./ --package com.richard.glestutorial --activity AppActivity# jni portmkdir jni# core c++ codemkdir core

在项目的根目录下创建一个jni目录,用来放jni相关的文件,core为我们以后主要使用的编程目录,将只存放c++代码。

这里run没问题就继续。

创建SurfaceView

我们不再使用sdk中的api去创建view,而是利用opengl-es来创建我们的view。android里可以用到GLSurfaceView,这是给Opengl专用的。

在AppActivity中采用我们自己的view,并将一些生命周期状态发送给我们自己的View:

package com.richard.glestutorial;import android.app.Activity;import android.os.Bundle;public class AppActivity extends Activity{    protected AppSurfaceView mView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        mView = new AppSurfaceView(getApplication());        setContentView(mView);    }    @Override    protected void onPause() {        super.onPause();        mView.onPause();    }    @Override    protected void onResume() {        super.onResume();        mView.onResume();    }    @Override    protected void onDestroy() {        super.onDestroy();    }}

创建AppSurfaceView.java 继承GLSurfaceView:

package com.richard.glestutorial;import android.content.Context;import android.opengl.GLSurfaceView;public class AppSurfaceView extends GLSurfaceView {    protected GLRenderer mRender;    public AppSurfaceView(Context context) {        super(context);        setEGLContextClientVersion(2); // set OpenGLES version    mRender = new GLRenderer();    // SurfaceView 需要设置一个渲染对象,待会自己实现一个SurfaceView.Renderer        setRenderer(mRender);    }    @Override    public void onPause() {        super.onPause();        mRender.handleOnPause();    }    @Override    public void onResume() {        super.onResume();        mRender.handleOnResume();    }}

GLRendder.java:

package com.richard.glestutorial;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;import android.opengl.GLSurfaceView.Renderer;import android.util.Log;public class GLRenderer implements Renderer {    static {        System.loadLibrary("gltutorial");  // 一起来就加载c++库文件,待会来指定这个库    }    @Override    public void onSurfaceCreated(GL10 gl, EGLConfig config) {        GLRenderer.nativeInit();    }    @Override    public void onSurfaceChanged(GL10 gl, int width, int height) {        GLRenderer.nativeOnReSize(width, height);    }    @Override    public void onDrawFrame(GL10 gl) {        GLRenderer.nativeUpdate();    }    public void handleOnPause() {        GLRenderer.nativeOnPause();    }    public void handleOnResume() {        Log.v("GLES Tutorial", "nativeOnResume");        GLRenderer.nativeOnResume();    }        // ------------------------------------------------------------    // Native Method    private static native void nativeInit();    private static native void nativeOnReSize(int width, int height);    private static native void nativeUpdate();    private static native void nativeOnPause();    private static native void nativeOnResume();}

这里设置了GLRenderer中声明了5个native方法,分别为:初始化;重绘制时设置view大小;每帧更新;暂停(退出前台);继续(回到前台)。将这些必备的状态通知给C++。以便我们进行绘制。

编写库

好了,接下来先编写Android.mk,用以生成libgltutorial.so这个库。在jni目录下新建Android.mk:

LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE    := gltutorialLOCAL_LDLIBS    := -llog -lGLESv2LOCAL_CFLAGS    := -WerrorLOCAL_CPPFLAGS  := -std=c++11include $(BUILD_SHARED_LIBRARY)

LOCAL_MODULE 指定了这个库的名字并添加了log库,opengl-es2这两个库给c++使用。LOCAL_CFLAGS是c/c++编译选项,Werror是警告也作为错误信息在编译时给出。BUILD_SHARED_LIBRARY是指定编译为动态库。

native实现

库是有了,还没有添加内容,这里要将GLRenderer中的native的实现以及我们自己定义的C++代码全部作为库。

先实现native方法:在bin下找到java源码build后的位置classes,运行javah生成native头文件: com_richard_glestutorial_GLRenderer.h

cd bin/classesjavah -classpath ~/dev/android/android-sdk-macosx/platforms/android-19/android.jar:. com.richard.glestutorial.GLRenderermv com_richard_glestutorial_GLRenderer.h ../../jni/

编写实现代码:com_richard_glestutorial_GLRenderer.cpp:这里为了以后使用方便,新建一个Director在根目录的core/中。

#include "com_richard_glestutorial_GLRenderer.h"#include "../core/Director.h"JNIEXPORT void JNICALL Java_com_richard_glestutorial_GLRenderer_nativeInit  (JNIEnv *env, jclass thiz){    Director::getInstance();}JNIEXPORT void JNICALL Java_com_richard_glestutorial_GLRenderer_nativeOnReSize  (JNIEnv *env, jclass thiz, jint width, jint height){    Director::getInstance()->setFrameSize(width, height);}JNIEXPORT void JNICALL Java_com_richard_glestutorial_GLRenderer_nativeUpdate  (JNIEnv *env, jclass thiz){    Director::getInstance()->mainLoop();}JNIEXPORT void JNICALL Java_com_richard_glestutorial_GLRenderer_nativeOnPause  (JNIEnv *env, jclass thiz){    Director::getInstance()->onEnterBackground();}JNIEXPORT void JNICALL Java_com_richard_glestutorial_GLRenderer_nativeOnResume  (JNIEnv *env, jclass thiz){    Director::getInstance()->onEnterForeground();}

Director的定义如下:

Director.h:

#ifndef _DRECTOR_H__#define _DRECTOR_H__class Director{public:    static Director* getInstance();    void init();    void setFrameSize(float width, float height);    void mainLoop();    void onEnterForeground();    void onEnterBackground();private:    Director();    ~Director();    float _fFrameWidth;    float _fFrameHeight;};

其实现可以添加一些log。可以用于查看。

最后要在Android.mk中指定所有的c++代码:

LOCAL_SRC_FILES := \com_richard_glestutorial_GLRenderer.cpp \../core/Director.cpp    LOCAL_C_INCLUDES := \$(LOCAL_PATH)

Run

最后运行,我们就可以看到一个空白的view的界面。以后我们就可以在上面写界面了。

热点阅读

网友最爱