Opengl ES 1.x NDK实例开发之一:搭建开发框架
2014-09-26 13:08
295 查看
大家好,我是无敌兔,从这一章开始讲在Android上进行Opengl ES 1.x的NDK开发实例,首先对这套开发实例教程的背景做一下说明。
Android SDK 提供了一套 OpenGL ES 接口,但该接口是基于 Java 的,速度非常慢,往往很难满足需要,所以采用NDK进行开发,底层的实现全部采用C++来编写。
该实例教程的java框架采用了Android NDK源码中的android-ndk-r9d\samples\hello-gl2,开发实例的编写采用了《Nehe的OpenGL中文教程》中的例子。本实例教程重在演示如何在NDK框架下进行Opengl ES的编程,关于实例的原理大家可以参考《Nehe的OpenGL中文教程》,本教程中的实例基本上在《Nehe的OpenGL中文教程》中可以找到相应的解释。
《Nehe的OpenGL中文教程》的在线地址:Nehe的OpenGL中文教程
一、开发环境
Eclipse 3.7.1
android-sdk_r23.0.0-windows
android-ndk-r9d
cygwin 1.7.9
二、框架介绍
src\com\android\gljni\GLJNIActivity.java 显示界面
src\com\android\gljni\GLJNILib.java JNI库
src\com\android\gljni\GLJNIView.java Opengl ES View
\jni\Android.mk NDK编译文件
\jni\gl_code.cpp JNI实现代码
三、实例介绍
![](http://img.blog.csdn.net/20140926132325759?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbW5vcnN0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
GLJNIActivity.java
GLJNIView.java
GLJNILib.java
gl_code.cpp
Android SDK 提供了一套 OpenGL ES 接口,但该接口是基于 Java 的,速度非常慢,往往很难满足需要,所以采用NDK进行开发,底层的实现全部采用C++来编写。
该实例教程的java框架采用了Android NDK源码中的android-ndk-r9d\samples\hello-gl2,开发实例的编写采用了《Nehe的OpenGL中文教程》中的例子。本实例教程重在演示如何在NDK框架下进行Opengl ES的编程,关于实例的原理大家可以参考《Nehe的OpenGL中文教程》,本教程中的实例基本上在《Nehe的OpenGL中文教程》中可以找到相应的解释。
《Nehe的OpenGL中文教程》的在线地址:Nehe的OpenGL中文教程
一、开发环境
Eclipse 3.7.1
android-sdk_r23.0.0-windows
android-ndk-r9d
cygwin 1.7.9
二、框架介绍
src\com\android\gljni\GLJNIActivity.java 显示界面
src\com\android\gljni\GLJNILib.java JNI库
src\com\android\gljni\GLJNIView.java Opengl ES View
\jni\Android.mk NDK编译文件
\jni\gl_code.cpp JNI实现代码
三、实例介绍
GLJNIActivity.java
/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * author: mnorst@foxmail.com */ package com.android.gljni; import com.android.gljni.GLJNIView; import android.app.Activity; import android.os.Bundle; public class GLJNIActivity extends Activity { GLJNIView mView; @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); mView = new GLJNIView(getApplication()); setContentView(mView); } @Override protected void onPause() { super.onPause(); mView.onPause(); } @Override protected void onResume() { super.onResume(); mView.onResume(); } }
GLJNIView.java
/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * author: mnorst@foxmail.com */ package com.android.gljni; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import com.android.gljni.GLJNILib; import android.content.Context; import android.opengl.GLSurfaceView; /** * A simple GLSurfaceView sub-class that demonstrate how to perform * OpenGL ES 1.x rendering into a GL Surface. */ public class GLJNIView extends GLSurfaceView { private static final String LOG_TAG = GLJNIView.class.getSimpleName(); private Renderer renderer; public GLJNIView(Context context) { super(context); // setEGLConfigChooser会对fps产生影响 setEGLConfigChooser(8, 8, 8, 8, 16, 0); renderer = new Renderer(context); setRenderer(renderer); } private static class Renderer implements GLSurfaceView.Renderer { public Renderer(Context ctx) { } public void onDrawFrame(GL10 gl) { GLJNILib.step(); } public void onSurfaceChanged(GL10 gl, int width, int height) { GLJNILib.resize(width, height); } public void onSurfaceCreated(GL10 gl, EGLConfig config) { GLJNILib.init(); } } }
GLJNILib.java
/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * author: mnorst@foxmail.com */ package com.android.gljni; //Wrapper for native library public class GLJNILib { static { System.loadLibrary("gljni"); } /** * @param width the current view width * @param height the current view height */ public static native void resize(int width, int height); public static native void step(); public static native void init(); }
gl_code.cpp
/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * author: mnorst@foxmail.com * created: 2014/09/26 * purpose: 搭建Opengl es 1.x NDK 开发框架 */ // OpenGL ES 1.x code #include <jni.h> #include <android/log.h> #include <GLES/gl.h> #include <GLES/glext.h> #include <stdio.h> #include <stdlib.h> #include <math.h> /************************************************************************/ /* 定义 */ /************************************************************************/ #define LOG_TAG "libgljni" #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) // 定义π const GLfloat PI = 3.1415f; // 顶点数组 const GLfloat gVertices[] = { 0.0f, 1.0f, 0.0f, -1.0f,-1.0f, 1.0f, 1.0f,-1.0f, 1.0f, }; /************************************************************************/ /* C++代码 */ /************************************************************************/ static void printGLString(const char *name, GLenum s) { const char *v = (const char *) glGetString(s); LOGI("GL %s = %s\n", name, v); } static void checkGlError(const char* op) { for (GLint error = glGetError(); error; error = glGetError()) { LOGI("after %s() glError (0x%x)\n", op, error); } } bool init() { printGLString("Version", GL_VERSION); printGLString("Vendor", GL_VENDOR); printGLString("Renderer", GL_RENDERER); printGLString("Extensions", GL_EXTENSIONS); // 启用阴影平滑 glShadeModel(GL_SMOOTH); // 黑色背景 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // 设置深度缓存 glClearDepthf(1.0f); // 启用深度测试 glEnable(GL_DEPTH_TEST); // 所作深度测试的类型 glDepthFunc(GL_LEQUAL); // 告诉系统对透视进行修正 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); return true; } 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); } void resize(int width, int height) { // 防止被零除 if (height==0) { height=1; } // 重置当前的视口 glViewport(0, 0, width, height); // 选择投影矩阵 glMatrixMode(GL_PROJECTION); // 重置投影矩阵 glLoadIdentity(); GLfloat ratio = (GLfloat)width/(GLfloat)height; // 设置视口的大小 _gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); // 选择模型观察矩阵 glMatrixMode(GL_MODELVIEW); // 重置模型观察矩阵 glLoadIdentity(); } void renderFrame() { // 清除屏幕及深度缓存 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 设置背景颜色为黑色 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // 重置当前的模型观察矩阵 glLoadIdentity(); // 移入屏幕 6.0 glTranslatef(0.0f,0.0f,-6.0f); // 启用顶点数组 glEnableClientState(GL_VERTEX_ARRAY); // 绘制三角形,图形的颜色默认为白色 glVertexPointer(3, GL_FLOAT, 0, gVertices); glDrawArrays(GL_TRIANGLES, 0, 3); // 关闭顶点数组 glDisableClientState(GL_VERTEX_ARRAY); } /************************************************************************/ /* JNI代码 */ /************************************************************************/ extern "C" { JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_resize(JNIEnv * env, jobject obj, jint width, jint height); JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_step(JNIEnv * env, jobject obj); JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_init(JNIEnv * env, jobject obj); }; JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_resize(JNIEnv * env, jobject obj, jint width, jint height) { resize(width, height); } JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_step(JNIEnv * env, jobject obj) { renderFrame(); } JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_init(JNIEnv * env, jobject obj) { init(); }Android.mk
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libgljni LOCAL_CFLAGS := -Werror LOCAL_SRC_FILES := gl_code.cpp LOCAL_LDLIBS := -llog -lGLESv1_CM include $(BUILD_SHARED_LIBRARY)
相关文章推荐
- Opengl ES 1.x NDK实例开发之一:搭建开发框架
- android Jni NDK开发环境搭建及其简单实例的编写
- Opengl ES 1.x NDK实例开发之五:顶点缓存VBO
- Opengl ES 1.x NDK实例开发之七:旋转的纹理立方体
- android Jni NDK开发环境搭建及其简单实例的编写
- Opengl ES 1.x NDK实例开发之四:立方体的旋转
- Opengl ES 1.x NDK实例开发之六:纹理贴图
- Opengl ES 1.x NDK实例开发之六:纹理贴图
- Opengl ES 1.x NDK实例开发之三:多边形的旋转
- Opengl ES 1.x NDK实例开发之二:颜色的使用
- Opengl ES 1.x NDK实例开发之七:旋转的纹理立方体
- Spring+SpringMVC+Mybatis(SSM)框架搭建教程(四)-应用功能开发实例
- Android OpenGL ES 开发教程(7):创建实例应用OpenGLDemos程序框架
- Opengl ES 1.x NDK实例开发之四:立方体的旋转
- android Jni NDK开发环境搭建及其简单实例的编写
- php开发设计介绍及实例介绍(一)基础框架的搭建
- Opengl ES 1.x NDK实例开发之五:顶点缓存VBO
- Opengl ES 1.x NDK实例开发之八:旋转的纹理金字塔
- Opengl ES 1.x NDK实例开发之六:纹理贴图
- Opengl ES 1.x NDK实例开发之二:颜色的使用