GLSurfaceView - 最簡單的jni OpenGL ES渲染

新建項目

該項目的github地址:
https://github.com/sz66cm/SimplestGLSurfaceUse.git
這裏寫圖片描述

按照NDK第一行代碼構建JNI環境

構建NDK環境地址:
http://blog.csdn.net/sz66cm/article/details/52599224

C代碼

#include <jni.h>
#include <android/log.h>
#include <GLES/gl.h>
#include <GLES/glext.h>

#define LOG_TAG "render.c"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)

void InitializeOpenGL();
void resizeViewport(jint, jint);
void renderFrame();

JNIEXPORT jint JNI_OnLoad(JavaVM* pVM, void* reserved) {
    LOGI("render.c JNI_OnLoad() start!");
    return JNI_VERSION_1_6;
}

JNIEXPORT void Java_com_cm_glsurfaceview_Libcm_init(JNIEnv* env, jobject thiz)
{
    LOGI("c init()");
    InitializeOpenGL();
}
JNIEXPORT void Java_com_cm_glsurfaceview_Libcm_resize(JNIEnv* env,
                                                        jobject thiz,
                                                        jint width,
                                                        jint height)
{
    LOGI("c resize()");
    resizeViewport(width, height);
}
JNIEXPORT void Java_com_cm_glsurfaceview_Libcm_render(JNIEnv* env, jobject thiz)
{
    LOGI("c render()");
    renderFrame();
}

void InitializeOpenGL()
{
    glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
}

void resizeViewport(jint w, jint h)
{
    glViewport(0, 0, w, h);
}

void renderFrame()
{
    glClear(GL_COLOR_BUFFER_BIT);
}

Java 調用 C 的包裝代碼:

package com.cm.glsurfaceview;

public class Libcm {
    static {
        System.loadLibrary("cmopengl");
    }
    public static native void init();
    public static native void resize(int width, int height);
    public static native void render();
}

GLSurfaceView使用代碼:

package com.cm.glsurfaceview;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends Activity {

    private GLSurfaceView view;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        view = new GLSurfaceView(MainActivity.this);
        view.setEGLContextClientVersion(2);//這一行代碼及其重要,不然可能會出現在JNI層,glCreateShader(...)一直返回0的問題
        //set the renderer
        view.setRenderer(new CMRenderer());
        setContentView(view);
    }

    @Override
    protected void onPause() {
        super.onPause();
        view.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        view.onResume();
    }

    class CMRenderer implements GLSurfaceView.Renderer {

        @Override
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            Libcm.init();
        }

        @Override
        public void onSurfaceChanged(GL10 gl, int width, int height) {
            Libcm.resize(width, height);
        }

        @Override
        public void onDrawFrame(GL10 gl) {
            Libcm.render();
        }
    }
}

Android.mk配置文件

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := cmopengl
LOCAL_SRC_FILES := ./cmopengles/render.c
LOCAL_LDLIBS += -llog 
LOCAL_LDLIBS += -lGLESv2
# use GL ext model
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES
include $(BUILD_SHARED_LIBRARY)

Application.mk配置文件

APP_ABI := all
# 以下該句不填寫,在執行ndk-build的時候上報"GLES/gl.h : NO such file"錯誤.
APP_PLATFORM := android-14

出現的問題

問題1 “GLES/gl.h : No such file”

解決:

在Application.mk文件中添加如下代碼:APP_PLATFORM := android-14

問題2 “將Apk燒入手機時報java.lang.UnsatisfiedLinkError”

解決:

將lib文件下所有的.so文件以及外層文件夾如:armeabi等刪除,重新ndk-build解決問題.

問題3 java.lang.UnsatisfiedLinkError 找不到相對應的方法

原因是Android.mk文件中的LOCAL_SRC_FILES寫成了LOCAL_SRC_FILE 少了個S,居然ndk-build沒有任何的報錯,還生成了.so包.我的天,搞了我一箇中午的時間.

發佈了74 篇原創文章 · 獲贊 4 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章