开发框架介绍请参见:Opengl ES NDK实例开发之一:搭建开发框架

本章在第六章(Opengl ES 1.x NDK实例开发之六:纹理贴图)的基础上绘制一个旋转的纹理立方体,原理和纹理贴图一样,需要注意的是定好正方体的顶点数组。

【实例讲解】

本实例添加了一个显示fps的小功能,在java层实现,原理是统计一分钟内屏幕刷新的次数

【实例源码】

[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 java.text.DecimalFormat;import com.android.gljni.GLJNIView;import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.ViewGroup.LayoutParams;
import android.widget.TextView;public class GLJNIActivity extends Activity {GLJNIView mView;TextView mTextView;@Overrideprotected void onCreate(Bundle icicle) {super.onCreate(icicle);mView = new GLJNIView(getApplication());setContentView(mView);mView.setHandler(new Handler(){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);// 显示fpsmTextView.setText("fps:"+msg.what);}});mTextView = new TextView(this);mTextView.setText("fps:0");addContentView(mTextView, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));}@Overrideprotected void onPause() {super.onPause();mView.onPause();}@Overrideprotected 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 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.gljnidemo07.R;import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
import android.os.Handler;
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);}public void setHandler( Handler handler){renderer.setHandler(handler);}private static class Renderer implements GLSurfaceView.Renderer {//用于纹理映射的绑定,并把绑定后的ID传递给C++代码,供其调用private int[] mTexture = new int[2];//用于加载Bitmap的contextprivate Context mContext;// 统计fpsprivate Handler mHandler;private long mStartMili;            private long mEndMili;private int mFps = 0;public Renderer(Context ctx) {mContext = ctx;mStartMili =System.currentTimeMillis();}public void setHandler( Handler handler){mHandler = handler;}public void onDrawFrame(GL10 gl) {GLJNILib.step();// 以一分钟绘制的帧数来统计fpsmEndMili = System.currentTimeMillis();if( mEndMili - mStartMili > 1000 ){mHandler.sendEmptyMessageDelayed(mFps, 100);mStartMili = mEndMili;mFps = 0;}mFps++;}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生成Bitmapbitmap = 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);//加载BitmapBitmap 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();}}}}

[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); /*** 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/27* 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;// 定义顶点坐标
#define pos 1.0f// 定义顶点坐标
// 一个正方体有8个顶点,6个面
#define one 1.0f
static GLfloat gVertices[] = {one, one, -one,   -one, one, -one, one, one, one, -one, one, one, one, -one,one,-one, -one, one,one, -one, -one, -one, -one, -one, one, one,one,-one, one, one,one, -one, one,-one, -one, one,one, -one,-one,-one, -one, -one,one, one, -one,-one, one, -one,-one, one,one,-one, one, -one,-one, -one, one, -one, -one, -one,one, one,-one,one, one, one,one, -one, -one,one, -one, one
};// 定义纹理坐标
// 纹理坐标原点会因不同系统环境而有所不同。
// 比如在iOS以及Android上,纹理坐标原点(0, 0)是在左上角
// 而在OS X上,纹理坐标的原点是在左下角
static GLfloat gTexCoords[] = {   0, one,                 one, one, 0, 0, one, 0, 0, one,                 one, one, 0, 0, one, 0, 0, one,                 one, one, 0, 0, one, 0, 0, one,                 one, one, 0, 0, one, 0, 0, one,                 one, one, 0, 0, one, 0, 0, one,                 one, one, 0, 0, one, 0, }; // 旋转角度
static GLfloat gAngle = 0.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();                           // 设置视口的大小_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);// 重置当前的模型观察矩阵glLoadIdentity();glTranslatef(0,0,-10.0f);glRotatef(gAngle, 0, 1.0F, 0);glRotatef(gAngle, 0, 0, 1.0F);// 启用顶点数组glEnableClientState(GL_VERTEX_ARRAY);//glEnableClientState(GL_COLOR_ARRAY);glEnableClientState(GL_TEXTURE_COORD_ARRAY);// 启用纹理映射glEnable(GL_TEXTURE_2D); // 选择纹理glBindTexture(GL_TEXTURE_2D, gTexture[0]); // 绘制正方体的六个面glVertexPointer(3,GL_FLOAT,0,gVertices);glTexCoordPointer(2, GL_FLOAT, 0, gTexCoords);for (int i = 0; i < 6; i++) {glDrawArrays(GL_TRIANGLE_STRIP, i * 4, 4);} // 关闭顶点数组glDisableClientState(GL_VERTEX_ARRAY);glDisableClientState(GL_TEXTURE_COORD_ARRAY);//glDisableClientState(GL_OLOR_ARRAY);gAngle += 5.f;
}/************************************************************************/
/*                          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);
}

源码工程: http://download.csdn.net/detail/mnorst/8123375

Opengl ES 1.x NDK实例开发之七:旋转的纹理立方体相关推荐

  1. Opengl ES 1.x NDK实例开发之八:旋转的纹理金字塔

    开发框架介绍请参见:Opengl ES NDK实例开发之一:搭建开发框架 本章在第六章(Opengl ES 1.x NDK实例开发之六:纹理贴图)的基础上绘制一个旋转的纹理金字塔,原理和纹理贴图一样, ...

  2. Android opengl es 3.0 + ndk 绘画涂鸦项目

    前言 写一个opengl es 3.0 + ndk 的绘画涂鸦项目,命名为白板哈哈哈,记录自己遇到的问题,顺便学到的知识整合一遍,算是对自己一段时间的总结. 项目地址:Whiteboard 如果对你有 ...

  3. OpenGl文章 Android OpenGL ES 简明开发教程

    Android OpenGL ES 简明开发教程 分类:android学习笔记2011-12-14 15:04375人阅读评论(0)收藏举报 ApiDemos 的Graphics示例中含有OpenGL ...

  4. Android项目开发教程之OpenGL ES

    视频课:[免费]跨平台APP JQuery Mobile开发-1-初探移动开发-张晨光的在线视频教程-CSDN程序员研修院 学习内容 OpenGL ES的基本概念 Android下3D开发的基本知识 ...

  5. OpenGL ES: (3) EGL、EGL绘图的基本步骤、EGLSurface、ANativeWindow

    1. EGL概述 EGL 是 OpenGL ES 渲染 API 和本地窗口系统(native platform window system)之间的一个中间接口层,它主要由系统制造商实现. EGL提供如 ...

  6. 借助 OpenGL* ES 2.0 实现动态分辨率渲染

    作者:omar-a-rodrigue 下载 借助 OpenGL* ES 2.0 实现动态分辨率渲染[PDF 677KB] 代码样本: dynamic-resolution.zip[ZIP 4MB] 像 ...

  7. Android OpenGL ES 从入门到精通系统性学习教程

    1 为什么要写这个教程 目前这个 OpenGL ES 极简教程的更新暂时告一段落,在此之前,很荣幸获得了阮一峰老师的推荐. 因为在工作中频繁使用 OpenGL ES 做一些特效.滤镜之类的效果,加上平 ...

  8. 【我的OpenGL学习进阶之旅】OpenGL ES 3.0新功能

    目录 1.1 纹理 1.2 着色器 1.3 几何形状 1.4 缓冲区对象 1.5 帧缓冲区 OpenGL ES 2.0 开创了手持设备可编程着色器的时代,在驱动大量设备的游戏.应用程序和用户接口中获得 ...

  9. android opengl es 2.0 编程指南,Android OpenGL ES 2.0 初次体验

    本文目录 一. OpenGL ES是什么? 二. OpenGL ES的版本 三. EGL是什么? 四. 需要知道的两个方法 五. 在Android中使用OpenGL ES的步骤 六. 例子1:简单的程 ...

最新文章

  1. 视+AR获近亿元A+轮融资,汽车之家领投
  2. 曲线抽稀 java_Python实现曲线点抽稀算法
  3. C#中Lambda表达式类型Expression不接受lambda函数
  4. 《CDN 之我见》原理篇——CDN的由来与调度
  5. 存储引擎:engine
  6. android node编码,android studio中的Node.js
  7. 【先到先得】这款课程版 iPhone XR 免费送给你!
  8. CVPR2022 Oral | CosFace、ArcFace的大统一升级,AdaFace解决低质量图像人脸识
  9. OPenDDS程序 的 实现+运行
  10. 【JY】反应谱的详解与介绍
  11. 谷歌开源 Embedding Projector 高维数据可视化--转自开源中国
  12. 数据库导出数据字典(MySQL)
  13. 万网域名绑定阿里云服务器
  14. 成为UiBot Store推广员,解锁全新赚钱方式
  15. 论文笔记 EMNLP 2021|Modeling Document-Level Context for Event Detection via Important Context Selection
  16. SpringMVC-转换器与格式化
  17. 特征工程-使用随机森林进行缺失值填补
  18. mysql命令行安装教程_MySQL命令行教程
  19. 寒假算法训练1-J(分棍子,求最长棍子的数量,另外学习map的排序方法)
  20. 思博伦报告:伴随运营商寻求差异化优势,5G发展不断加速

热门文章

  1. halcon灰度积分投影/垂直积分投影
  2. 又是一年“云智”时,我们是ABC,将与人类对话!
  3. 聊聊 ES6 解构(下)
  4. linux图形界面鼠标变成小手_Linux 的成长之路:试用 1993-2003 年之间的 Linux 老版本系统...
  5. 鸿蒙之境浩然溟涬攻略,神都夜行录鸿蒙之境80级古都凶煞怎么打 神都夜行录鸿蒙之境80级古都凶煞打法_游戏堡...
  6. 一篇带你了解BIM+GIS,倾斜摄影,3Ds Max模型数据处理
  7. AI - 主流深度学习框架简介
  8. python bytearray转为byte_python:将bytearray转换为ctypes Struct
  9. PushBack Animation View
  10. 不能篡改内容的pushBack——BufferedInputStream深入解析