android jni opengles,一個簡單的OpenGL ES 3.0 示例 (Android NDK jni)

OpenGL ES 3.0 上的一個三角形例子,網上可以下載到android skd 版(java)和 android ndk (c&c++版)

為了了解一下JNI,於是寫了如下小程序。

這個例子是使用jni, java中調用c中的代碼完成三角形的渲染, 其中shader代碼保存在assets目錄下,如下目錄圖:

36b211439a4dcf221060f132ee3b4b71.jpe

其中,com_jnirenderer_RendererJNI.h 是 使用javah命令生成的,進入bin/classes目錄下運行如下命令:

javah -classpath "D:\Program Files (x86)\Android\android-sdk\platforms\android-20\android.jar";. -jni PackageName.ClassName  (注意路徑、包名以及類名的替換)

MainActivity.java代碼如下:

package com.jnirenderer;

import android.app.Activity;

import android.app.ActivityManager;

import android.content.Context;

import android.content.pm.ConfigurationInfo;

import android.opengl.GLSurfaceView;

import android.os.Bundle;

import android.util.Log;

public class MainActivity extends Activity {

private final int CONTEXT_CLIENT_VERSION = 3;

private GLSurfaceView mGLSurfaceView;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

mGLSurfaceView = new GLSurfaceView(this);

if (detectOpenGLES30()) {

mGLSurfaceView.setEGLContextClientVersion(CONTEXT_CLIENT_VERSION);

mGLSurfaceView.setRenderer(new RendererJNI(this));

} else {

Log.e("opengles30", "OpenGL ES 3.0 not supported on device. Exiting...");

finish();

}

setContentView(mGLSurfaceView);

}

@Override

protected void onResume() {

// TODO Auto-generated method stub

super.onResume();

mGLSurfaceView.onResume();

}

@Override

protected void onPause() {

// TODO Auto-generated method stub

super.onPause();

mGLSurfaceView.onPause();

}

private boolean detectOpenGLES30() {

ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);

ConfigurationInfo info = am.getDeviceConfigurationInfo();

return (info.reqGlEsVersion >= 0x30000);

}

}

RendererJNI.java代碼如下:

package com.jnirenderer;

import javax.microedition.khronos.egl.EGLConfig;

import javax.microedition.khronos.opengles.GL10;

import android.content.Context;

import android.content.res.AssetManager;

import android.opengl.GLSurfaceView;

import android.util.Log;

public class RendererJNI implements GLSurfaceView.Renderer {

static {

System.loadLibrary("JNIOpenGLES30");

}

private AssetManager mAssetMgr = null;

private final String mLogTag = "ndk-build";

public native void glesInit();

public native void glesRender();

public native void glesResize(int width, int height);

public native void readShaderFile(AssetManager assetMgr);

public RendererJNI(Context context) {

mAssetMgr = context.getAssets();

if (null == mAssetMgr) {

Log.e(mLogTag, "getAssets() return null !");

}

}

@Override

public void onSurfaceCreated(GL10 gl, EGLConfig config) {

// TODO Auto-generated method stub

readShaderFile(mAssetMgr);

glesInit();

}

@Override

public void onSurfaceChanged(GL10 gl, int width, int height) {

// TODO Auto-generated method stub

glesResize(width, height);

}

@Override

public void onDrawFrame(GL10 gl) {

// TODO Auto-generated method stub

glesRender();

}

}

com_jnirenderer_RendererJNI.c 代碼如下:

#include "com_jnirenderer_RendererJNI.h"

#include

#include

#include

#include

#include

#include

#define LOG_TAG "ndk-build"

#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

GLintg_programObject;

jintg_width;

jintg_height;

AAssetManager* g_pAssetManager = NULL;

char* readShaderSrcFile(char *shaderFile, AAssetManager *pAssetManager)

{

AAsset *pAsset = NULL;

char *pBuffer = NULL;

off_t size = -1;

int numByte = -1;

if (NULL == pAssetManager)

{

LOGE("pAssetManager is null!");

return NULL;

}

pAsset = AAssetManager_open(pAssetManager, shaderFile, AASSET_MODE_UNKNOWN);

//LOGI("after AAssetManager_open");

size = AAsset_getLength(pAsset);

LOGI("after AAssetManager_open");

pBuffer = (char *)malloc(size+1);

pBuffer[size] = '\0';

numByte = AAsset_read(pAsset, pBuffer, size);

LOGI("%s : [%s]", shaderFile, pBuffer);

AAsset_close(pAsset);

return pBuffer;

}

GLuint LoadShader ( GLenum type, const char *shaderSrc )

{

GLuint shader;

GLint compiled;

// Create the shader object

shader = glCreateShader ( type );

if ( shader == 0 )

{

return 0;

}

// Load the shader source

glShaderSource ( shader, 1, &shaderSrc, NULL );

// Compile the shader

glCompileShader ( shader );

// Check the compile status

glGetShaderiv ( shader, GL_COMPILE_STATUS, &compiled );

if ( !compiled )

{

GLint infoLen = 0;

glGetShaderiv ( shader, GL_INFO_LOG_LENGTH, &infoLen );

if ( infoLen > 1 )

{

char *infoLog = malloc ( sizeof ( char ) * infoLen );

glGetShaderInfoLog ( shader, infoLen, NULL, infoLog );

LOGE("Error compiling shader:[%s]", infoLog );

free ( infoLog );

}

glDeleteShader ( shader );

return 0;

}

return shader;

}

//*********************************************************************************

//

JNIEXPORT void JNICALL Java_com_jnirenderer_RendererJNI_readShaderFile(JNIEnv *env, jobject self, jobject assetManager)

{

if (assetManager && env)

{

//LOGI("before AAssetManager_fromJava");

g_pAssetManager = AAssetManager_fromJava(env, assetManager);

//LOGI("after AAssetManager_fromJava");

if (NULL == g_pAssetManager)

{

LOGE("AAssetManager_fromJava() return null !");

}

}

else

{

LOGE("assetManager is null !");

}

}

//*********************************************************************************

//

JNIEXPORT void JNICALL Java_com_jnirenderer_RendererJNI_glesInit(JNIEnv *pEnv, jobject obj)

{

char vShaderStr[] =

"#version 300 es \n"

"layout(location = 0) in vec4 vPosition; \n"

"void main() \n"

"{ \n"

" gl_Position = vPosition; \n"

"} \n";

char fShaderStr[] =

"#version 300 es \n"

"precision mediump float; \n"

"out vec4 fragColor; \n"

"void main() \n"

"{ \n"

" fragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 ); \n"

"} \n";

char *pVertexShader = readShaderSrcFile("shader/vs.glsl", g_pAssetManager);

char *pFragmentShader = readShaderSrcFile("shader/fs.glsl", g_pAssetManager);

GLuint vertexShader;

GLuint fragmentShader;

GLuint programObject;

GLint linked;

// Load the vertex/fragment shaders

//vertexShader = LoadShader ( GL_VERTEX_SHADER, vShaderStr );

//fragmentShader = LoadShader ( GL_FRAGMENT_SHADER, fShaderStr );

vertexShader = LoadShader ( GL_VERTEX_SHADER, pVertexShader );

fragmentShader = LoadShader ( GL_FRAGMENT_SHADER, pFragmentShader );

// Create the program object

programObject = glCreateProgram ( );

if ( programObject == 0 )

{

return;

}

glAttachShader ( programObject, vertexShader );

glAttachShader ( programObject, fragmentShader );

// Link the program

glLinkProgram ( programObject );

// Check the link status

glGetProgramiv ( programObject, GL_LINK_STATUS, &linked );

if ( !linked )

{

GLint infoLen = 0;

glGetProgramiv ( programObject, GL_INFO_LOG_LENGTH, &infoLen );

if ( infoLen > 1 )

{

char *infoLog = malloc ( sizeof ( char ) * infoLen );

glGetProgramInfoLog ( programObject, infoLen, NULL, infoLog );

LOGE("Error linking program:[%s]", infoLog );

free ( infoLog );

}

glDeleteProgram ( programObject );

return;

}

// Store the program object

g_programObject = programObject;

glClearColor ( 1.0f, 1.0f, 1.0f, 0.0f );

}

//*********************************************************************************

//

JNIEXPORT void JNICALL Java_com_jnirenderer_RendererJNI_glesRender(JNIEnv *pEnv, jobject obj)

{

GLfloat vVertices[] = { 0.0f, 0.5f, 0.0f,

-0.5f, -0.5f, 0.0f,

0.5f, -0.5f, 0.0f

};

// Set the viewport

glViewport ( 0, 0, g_width, g_height );

// Clear the color buffer

glClear ( GL_COLOR_BUFFER_BIT );

// Use the program object

glUseProgram ( g_programObject );

// Load the vertex data

glVertexAttribPointer ( 0, 3, GL_FLOAT, GL_FALSE, 0, vVertices );

glEnableVertexAttribArray ( 0 );

glDrawArrays ( GL_TRIANGLES, 0, 3 );

}

//*********************************************************************************

//

JNIEXPORT void JNICALL Java_com_jnirenderer_RendererJNI_glesResize(JNIEnv *pEnv, jobject obj, jint width, jint height)

{

g_width = width;

g_height = height;

}

vs.glsl 和 fs.glsl 中的shader代碼分別如下:

#version 300 es

layout(location = 0) in vec4 vPosition;

void main()

{

gl_Position = vPosition;

}

#version 300 esprecision mediump float;out vec4 fragColor;void main(){fragColor = vec4(1.0, 0.0, 0.0, 1.0);}

Android.mk 如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := JNIOpenGLES30

LOCAL_SRC_FILES := com_jnirenderer_RendererJNI.c

LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv3

include $(BUILD_SHARED_LIBRARY)

程序運行的效果和書上給的完全一樣,一個紅三角形 ! ! !

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值