• 热门专题

OpenglES1.xNDK实例开发之六:纹理贴图

作者:  发布日期:2014-10-21 19:47:41
Tag标签:纹理  实例  贴图  
  •  

    本章在第三章(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)

     

     

    【实例源码】

    [GLJNIActivity.java]

     

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
    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.  
    19. package com.android.gljni;
    20.  
    21. import com.android.gljni.GLJNIView;
    22.  
    23. import android.app.Activity;
    24. import android.os.Bundle;
    25.  
    26. public class GLJNIActivity extends Activity {
    27. GLJNIView mView;
    28.  
    29. @Override
    30. protected void onCreate(Bundle icicle) {
    31. super.onCreate(icicle);
    32. mView = new GLJNIView(getApplication());
    33. setContentView(mView);
    34. }
    35.  
    36. @Override
    37. protected void onPause() {
    38. super.onPause();
    39. mView.onPause();
    40. }
    41.  
    42. @Override
    43. protected void onResume() {
    44. super.onResume();
    45. mView.onResume();
    46. }
    47. } [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
      ", 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);
      }
      



       

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规