一個簡單的OpenGL ES 3.0 示例 (Android NDK jni)
OpenGL ES 3.0 上的一個三角形例子,網上可以下載到android skd 版(java)和 android ndk (c&c++版)
為了瞭解一下JNI,於是寫了如下小程式。
這個例子是使用jni, java中呼叫c中的程式碼完成三角形的渲染, 其中shader程式碼儲存在assets目錄下,如下目錄圖:
其中,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 <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <GLES3/gl3.h>
#include <android/asset_manager_jni.h>
#include <android/log.h>
#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__)
GLint g_programObject;
jint g_width;
jint g_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 es
precision 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)
程式執行的效果和書上給的完全一樣,一個紅三角形 ! ! !
相關推薦
一個簡單的OpenGL ES 3.0 示例 (Android NDK jni)
OpenGL ES 3.0 上的一個三角形例子,網上可以下載到android skd 版(java)和 android ndk (c&c++版) 為了瞭解一下JNI,於是寫了如下小程式。 這個例子是使用jni, java中呼叫c中的程式碼完成三角形的渲染, 其中sh
android studio | openGL es 3.0增強現實(AR)開發 (1) 建立一個openGL es 3.0開發環境
1.什麼是NDK,什麼是JNI? NDK:Native Development Kit(原生開發工具包), NDK允許使用者使用類似C / C++之類的原生程式碼語言執行部分程式。它包括下面的部分(1)從C / C++生成原生程式碼庫所需要的工具和buil
Android 為例編寫一個 OpenGL ES 3.0 例項,Native & Java 兩種實現
一、簡介 通過這個 Sample,你將瞭解到 Android 中是怎麼使用 OpenGL ES 通過繪製一個簡單的靜態三角形,來簡單入門和了解它大致的流程(類似於 HelloWorld 工程) 介紹使用 Native 層 和 Java 層 兩種方式來分別實現
通俗易懂的 OpenGL ES 3.0(二)渲染三角形
前言 學習了OpenGL有一段時間,在繪製出屬於自己的三角形之前,會接觸許多理論上的知識。用簡單的方式寫下自己對OpenGL的一些見解。望大家取其精華去其糟粕 最終效果:改變背景色,並且繪製渲染一個暗紅色的三角形 必備知識 OpenGL需要我們至少設定一個
OpenGL ES 3.0 簡單的頂點和片段著色器
char fShaderStr[] = 1、 "#version 300 es \n" 2、 "precision mediump float; \n" 3、 "out vec4 fragColor;
通俗易懂的 OpenGL ES 3.0(一)入門必備知識!!
前言 opengl的入門是個難點,因為在繪製出圖形之前,你必須要學習一大堆的概念,以及部分圖形知識。以至於在程式碼中不迷路-v-!!.接下來就通俗的講解下部分概念知識。希望大家取其精華去其糟粕 頂點(Vertex) opengl物體圖形都由點、線
iOS下OpenGL ES 3.0程式設計入門(一):構建Hello World環境
OpenGL ES簡介: OpenGL ES (OpenGL for Embedded Systems) 是 OpenGL三維圖形 API 的子集,針對手機、PDA和遊戲主機等嵌入式裝置而設計。該API由Khronos集團定義推廣,Khronos是一個圖形軟硬體
android平臺下OpenGL ES 3.0從零開始
OpenGL ES 3.0學習實踐 android平臺下OpenGL ES 3.0從零開始 android平臺下OpenGL ES 3.0繪製純色背景 android平臺下OpenGL ES 3.0繪製圓點、直線和三角形 android平臺下OpenGL E
android平臺下OpenGL ES 3.0繪製純色背景
OpenGL ES 3.0學習實踐 android平臺下OpenGL ES 3.0從零開始 android平臺下OpenGL ES 3.0繪製純色背景 android平臺下OpenGL ES 3.0繪製圓點、直線和三角形 android平臺下OpenGL E
android平臺下OpenGL ES 3.0從矩形中看矩陣和座標系
OpenGL ES 3.0學習實踐 android平臺下OpenGL ES 3.0從零開始 android平臺下OpenGL ES 3.0繪製純色背景 android平臺下OpenGL ES 3.0繪製圓點、直線和三角形 android平臺下OpenGL E
android平臺下OpenGL ES 3.0繪製彩色三角形
OpenGL ES 3.0學習實踐 android平臺下OpenGL ES 3.0從零開始 android平臺下OpenGL ES 3.0繪製純色背景 android平臺下OpenGL ES 3.0繪製圓點、直線和三角形 android平臺下OpenGL E
android平臺下OpenGL ES 3.0繪製圓點、直線和三角形
OpenGL ES 3.0學習實踐 android平臺下OpenGL ES 3.0從零開始 android平臺下OpenGL ES 3.0繪製純色背景 android平臺下OpenGL ES 3.0繪製圓點、直線和三角形 android平臺下OpenGL E
android平臺下OpenGL ES 3.0著色語言基礎知識(下)
OpenGL ES 3.0學習實踐 android平臺下OpenGL ES 3.0從零開始 android平臺下OpenGL ES 3.0繪製純色背景 android平臺下OpenGL ES 3.0繪製圓點、直線和三角形 android平臺下OpenGL E
android平臺下OpenGL ES 3.0例項詳解頂點屬性、頂點陣列
OpenGL ES 3.0學習實踐 android平臺下OpenGL ES 3.0從零開始 android平臺下OpenGL ES 3.0繪製純色背景 android平臺下OpenGL ES 3.0繪製圓點、直線和三角形 android平臺下OpenGL E
android平臺下OpenGL ES 3.0例項詳解頂點緩衝區物件(VBO)和頂點陣列物件(VAO)
OpenGL ES 3.0學習實踐 android平臺下OpenGL ES 3.0從零開始 android平臺下OpenGL ES 3.0繪製純色背景 android平臺下OpenGL ES 3.0繪製圓點、直線和三角形 android平臺下OpenGL E
android平臺下OpenGL ES 3.0繪製立方體的幾種方式
OpenGL ES 3.0學習實踐 android平臺下OpenGL ES 3.0從零開始 android平臺下OpenGL ES 3.0繪製純色背景 android平臺下OpenGL ES 3.0繪製圓點、直線和三角形 android平臺下OpenGL E
android平臺下OpenGL ES 3.0使用GLSurfaceView對相機Camera預覽實時處理
OpenGL ES 3.0學習實踐 android平臺下OpenGL ES 3.0從零開始 android平臺下OpenGL ES 3.0繪製純色背景 android平臺下OpenGL ES 3.0繪製圓點、直線和三角形 android平臺下OpenGL E
android平臺下OpenGL ES 3.0使用TextureView對相機Camera預覽實時處理
OpenGL ES 3.0學習實踐 android平臺下OpenGL ES 3.0從零開始 android平臺下OpenGL ES 3.0繪製純色背景 android平臺下OpenGL ES 3.0繪製圓點、直線和三角形 android平臺下OpenGL E
android平臺下OpenGL ES 3.0實現2D紋理貼圖顯示bitmap
OpenGL ES 3.0學習實踐 android平臺下OpenGL ES 3.0從零開始 android平臺下OpenGL ES 3.0繪製純色背景 android平臺下OpenGL ES 3.0繪製圓點、直線和三角形 android平臺下OpenGL E
OpenGL ES 3.0 渲染管線介紹
一、前言 OpenGL 1.x 系列採用的還是固定功能管線。 從 OpenGL ES 2.0 開始採用了可程式設計圖形管線。 而 OpenGL ES 3.0 相容了 2.0,並加入了很多 2.0 不具備的功能。 Android 4.3 之後開始支援 Open