开发框架介绍请參见:Opengl ES NDK实例开发之中的一个:搭建开发框架

本章在第三章(Opengl ES 1.x NDK实例开发之三:多边形的旋转)的基础上演示怎样使用纹理贴图,分别实现了三角形纹理贴图和正方形纹理贴图。

【实例解说】

OpenglES要求生成纹理的图片长宽为2的n次方。支持各种格式(BMP, GIF, JPEG, PNG...)

本例中使用的图片为png格式,尺寸为128*128

本例中,在上层GLJNIView.java中生成纹理。将纹理句柄传递给Native层进行绘制。详见

private void genTexture(GL10 gl, Context context)

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbW5vcnN0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

【实例源代码】

[GLJNIActivity.java]

[java] view
plain
copy

  1. /*
  2. * Copyright (C) 2007 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. *      http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. * author: mnorst@foxmail.com
  17. */
  18. package com.android.gljni;
  19. import com.android.gljni.GLJNIView;
  20. import android.app.Activity;
  21. import android.os.Bundle;
  22. public class GLJNIActivity extends Activity {
  23. GLJNIView mView;
  24. @Override
  25. protected void onCreate(Bundle icicle) {
  26. super.onCreate(icicle);
  27. mView = new GLJNIView(getApplication());
  28. setContentView(mView);
  29. }
  30. @Override
  31. protected void onPause() {
  32. super.onPause();
  33. mView.onPause();
  34. }
  35. @Override
  36. protected void onResume() {
  37. super.onResume();
  38. mView.onResume();
  39. }
  40. }

[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.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();
} }
} }

[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/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\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);
// 设置背景颜色为黑色
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);
}

Opengl ES 1.x NDK实例开发之六:纹理贴图的更多相关文章

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

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

  2. (转)使用OpenGL显示图像(七)Android OpenGLES2.0——纹理贴图之显示图片

    转:http://blog.csdn.net/junzia/article/details/52842816 前面几篇博客,我们将了Android中利用OpenGL ES 2.0绘制各种形体,并在上一 ...

  3. OpenGL ES 画直线代码实例

    http://blog.csdn.net/yexiaozi_007/article/details/7978620 以画xyz坐标轴为例,很多人会遇到用glcolor设置了颜色,但是直线画出来还是黑色 ...

  4. OpenGL ES教程系列(经典合集)

    为了搞透播放器的开发,花了些时间收集这些资料,虽然我已经搞定opengles渲染视频的内容,但是想玩玩opengles,往深里玩,图像处理这块是个好的方向,所以opengles是值得好好学的.   O ...

  5. OpenGL ES

    前言 OpenGL ES是Khronos Group创建的一系列API中的一种(官方组织是:http://www.khronos.org/).在桌面计算机上有两套标准的 3DAPI:Direct3D和 ...

  6. OpenGL ES 2.0 渲染管线 学习笔记

    图中展示整个OpenGL ES 2.0可编程管线 图中Vertex Shader和Fragment Shader 是可编程管线: Vertex Array/Buffer objects 顶点数据来源, ...

  7. Android OpenGL ES 入门系列(二) --- 环境搭建

    转载请注明出处 本文出自Hansion的博客 本章介绍如何使用GLSurfaceView和GLSurfaceView.Renderer完成在Activity中的最简单实现. 1.在AndroidMan ...

  8. OpenGL ES 系列教程

    http://www.linuxgraphics.cn/graphics/opengles_tutorial_index.html 本文收集了一套 OpenGL ES 系列教程. www.play3d ...

  9. OpenGL ES: (1) OpenGL ES的由来 (转)

    1. 电脑是做什么用的? 电脑又被称为计算机,那么最重要的工作就是计算.看过三体的同学都知道, 电脑中有无数纳米级别的计算单元,通过 0 和 1 的转换,完成加减乘除的操作. 2. 是什么使电脑工作? ...

随机推荐

  1. [BZOJ 1901] Dynamic Rankings

    Link: BZOJ 1901 传送门 Solution: 带修改主席树的模板题 对于静态区间第$k$大直接上主席树就行了 但加上修改后会发现修改时复杂度不满足要求了: 去掉/增加第$i$位上的值时要 ...

  2. 【DFS】【DP】岳麓山上打水

    [vijos1159]岳麓山上打水 描述 今天天气好晴朗,处处好风光,好风光!蝴蝶儿忙啊,蜜蜂也忙,信息组的同学们更加忙.最近,由于XX原因,大家不得不到岳麓山去提水.55555555~,好累啊. 信 ...

  3. BZOJ 4027:[HEOI2015]兔子与樱花(贪心+树形DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4027 [题目大意] 樱花树由n个树枝分叉点组成,编号从0到n-1,这n个分叉点由n-1 ...

  4. bzoj 4401: 块的计数

    4401: 块的计数 Description 小Y最近从同学那里听说了一个十分牛B的高级数据结构——块状树.听说这种数据结构能在sqrt(N)的时间内维护树上的各种信息,十分的高效.当然,无聊的小Y对 ...

  5. JavaScript 开发的45个技巧2

    http://mp.weixin.qq.com/s?src=3&timestamp=1474692926&ver=1&signature=agI3W5rKmVC6GgbdTXh ...

  6. datetimepicker只显示日期,不显示时分秒

    HTML代码<div class="input-group date form_datetime form-date" data-link-field="dtp_i ...

  7. linux之rootfs (UBIFS)

    转:http://www.360doc.com/content/11/1208/15/3700464_170655736.shtml 大大小小事情一堆,好久不更新了,这次记录下移植ubifs文件系统步 ...

  8. nodesj中 中间件express-session的理解

    1.为什么使用session? session运行在服务器端,当客户端第一次访问服务器时,可以将客户的登录信息保存. 当客户访问其他页面时,可以判断客户的登录状态,做出提示,相当于登录拦截. sess ...

  9. Cisco路由技术基础知识详解

    第一部分 请写出568A的线序(接触网络第一天就应该会的,只要你掐过,想都能想出来) .网卡MAC地址长度是(  )个二进制位(16进制与2进制的换算关系,只是换种方式问,不用你拿笔去算) A.12  ...

  10. response letter模板

    Dear Dr. or Prof. XXXX (family name of the Editor or Editor-in-Chief who issued the decision letter) ...