转自:http://blog.csdn.net/mnorst/article/details/40346641
【实例讲解】
OpenglES要求生成纹理的图片长宽为2的n次方,支持各种格式(BMP, GIF, JPEG, PNG...)
本例中使用的图片为png格式,尺寸为128*128
本例中,在上层GLJNIView.java中生成纹理,将纹理句柄传递给Native层进行绘制,详见
- private void genTexture(GL10 gl, Context context)
【实例源码】
[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();
- }
- }
- /*
- * 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 java.io.IOException;
- import java.io.InputStream;
- import javax.microedition.khronos.egl.EGLConfig;
- import javax.microedition.khronos.opengles.GL10;
- import com.android.gljni.GLJNILib;
- import com.android.gljnidemo06.R;
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.opengl.GLSurfaceView;
- import android.opengl.GLUtils;
- import android.util.Log;
- /**
- * 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 {
- //用于纹理映射的绑定,并把绑定后的ID传递给C++代码,供其调用
- private int[] mTexture = new int[2];
- //用于加载Bitmap的context
- private Context mContext;
- public Renderer(Context ctx) {
- mContext = 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) {
- //用来绑定Bitmap纹理
- genTexture(gl, mContext);
- //调用本地setTexture方法,把纹理绑定的ID传递给C++代码,以供其调用
- GLJNILib.setTexture(mTexture);
- GLJNILib.init();
- }
- /**
- * 加载Bitmap的方法,
- * 用来从res中加载Bitmap资源
- * */
- private Bitmap loadBitmap(Context context, int resourceId) {
- InputStream is = context.getResources().openRawResource(resourceId);
- Bitmap bitmap = null;
- try {
- // 利用BitmapFactory生成Bitmap
- bitmap = BitmapFactory.decodeStream(is);
- } finally {
- try {
- // 关闭流
- is.close();
- is = null;
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- return bitmap;
- }
- /**
- * 绑定Bitmap纹理
- * */
- private void genTexture(GL10 gl, Context context) {
- //生成纹理
- gl.glGenTextures(2, mTexture, 0);
- //加载Bitmap
- Bitmap bitmap = loadBitmap(context, R.drawable.logo);
- if (bitmap != null) {
- //如果bitmap加载成功,则生成此bitmap的纹理映射
- gl.glBindTexture(GL10.GL_TEXTURE_2D, mTexture[0]);
- //设置纹理映射的属性
- gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
- GL10.GL_NEAREST);
- gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
- GL10.GL_NEAREST);
- //生成纹理映射
- GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
- //释放bitmap资源
- bitmap.recycle();
- }
- }
- }
- }
- /*
- * 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);
- /**
- * render
- */
- public static native void step();
- /**
- * init
- */
- public static native void init();
- /**
- * set the texture
- * @param texture texture id
- */
- public static native void setTexture(int[] texture);
- }
[[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/10/20
- * purpose: 纹理的使用
- */
- // 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__)
- //初始化纹理数组
- GLuint *gTexture = 0;
- // 定义π
- const GLfloat PI = 3.1415f;
- // 旋转角度
- static GLfloat gAngle = 0.0f;
- // 顶点数组
- const GLfloat gVertices[] = {
- 0.0f, 1.0f, 0.0f, // 上
- -1.0f,-1.0f, 0.0f, // 左下
- 1.0f,-1.0f, 0.0f, // 右下
- };
- const GLfloat gVerticesSquare[] = {
- -1.0f, -1.0f, 0.0f, // 左下
- 1.0f, -1.0f, 0.0f, // 右下
- -1.0f, 1.0f, 0.0f, // 左上
- 1.0f, 1.0f, 0.0f // 右上
- };
- // 纹理坐标
- // 纹理坐标原点会因不同系统环境而有所不同。
- // 比如在iOS以及Android上,纹理坐标原点(0, 0)是在左上角
- // 而在OS X上,纹理坐标的原点是在左下角
- const GLfloat gTextureCoord[] = {
- 0.5f,0.0f,
- 0.0f,1.0f,
- 1.0f,1.0f,
- };
- const GLfloat gTextureSquareCoord[] = {
- 0.0f,1.0f,
- 1.0f,1.0f,
- 0.0f,0.0f,
- 1.0f,0.0f,
- };
- /************************************************************************/
- /* C++代码 */
- /************************************************************************/
- static void printGLString(const char *name, GLenum s) {
- const char *v = (const char *) glGetString(s);
- LOGI("GL %s = %s ", name, v);
- }
- static void checkGlError(const char* op) {
- for (GLint error = glGetError(); error; error
- = glGetError()) {
- LOGI("after %s() glError (0x%x) ", 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();
- // 设置视口的大小
- _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();
- // 启用顶点数组
- glEnableClientState(GL_VERTEX_ARRAY);
- glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- // 纹理设置
- glEnable(GL_TEXTURE_2D); // 启用纹理映射
- glBindTexture(GL_TEXTURE_2D, gTexture[0]); // 选择纹理
- glEnableClientState(GL_TEXTURE_COORD_ARRAY); // 启用纹理坐标数组
- // 绘制三角形
- glTranslatef(0.0f,2.0f,-10.0f); // 设置三角形位置
- glRotatef(gAngle,0.0f,1.0f,0.0f); // 旋转三角形
- glVertexPointer(3, GL_FLOAT, 0, gVertices); // 指定顶点数组
- glTexCoordPointer(2, GL_FLOAT, 0, gTextureCoord); // 设置纹理坐标
- glDrawArrays(GL_TRIANGLES, 0, 3); // 绘制三角形
- // 绘制正方形
- glTranslatef(0.0f,-4.0f,0.0f); // 设置正方形位置
- glRotatef(-gAngle*2,0.0f,1.0f,0.0f); // 旋转正方形
- glVertexPointer(3, GL_FLOAT, 0, gVerticesSquare); // 指定顶点数组
- glTexCoordPointer(2, GL_FLOAT, 0, gTextureSquareCoord); // 设置纹理坐标
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // 绘制正方形
- // 关闭顶点数组
- glDisableClientState(GL_VERTEX_ARRAY);
- // 关闭纹理数组
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisable(GL_TEXTURE_2D);
- // 增加旋转角度
- gAngle += 2.0f;
- }
- /************************************************************************/
- /* 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_setTexture(JNIEnv * env, jclass obj, jintArray tex);
- };
- 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();
- }
- JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_setTexture(JNIEnv * env, jclass obj, jintArray tex)
- {
- gTexture = (GLuint *)env->GetIntArrayElements(tex,0);
- }