OpenGL ES实现三棱锥纹理贴图
生活随笔
收集整理的這篇文章主要介紹了
OpenGL ES实现三棱锥纹理贴图
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
這是老師布置的課后作業,閑來無事分享出來,也加深一遍自己的印象~
自己定義一個MyRenderer.java類:
package com.example.shiyan3_2;import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.opengl.GLSurfaceView.Renderer; import android.opengl.GLUtils;import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.IntBuffer;import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10;public class MyRenderer implements Renderer {// 定義三棱椎的4個頂點float[] taperVertices = new float[] {0.0f, 0.5f, 0.0f,-0.5f, -0.5f, -0.2f,0.5f, -0.5f, -0.2f,0.0f, -0.2f, 0.2f};// 定義三棱椎的4個三角面(沒有使用)private byte[] taperFacets = new byte[]{0, 1, 2, // 0、1、2三個頂點組成一個面0, 1, 3, // 0、1、3三個頂點組成一個面1, 2, 3, // 1、2、3三個頂點組成一個面0, 2, 3 // 0、2、3三個頂點組成一個面};//定義紋理貼圖的坐標數據private float[] taperTextures = {1.0000f,1.0000f,1.0000f,0.0000f,0.0000f,0.0000f,0.0000f,1.0000f};// 分別定義三棱椎的4個三角面ByteBuffer i1=ByteBuffer.wrap(new byte[]{0,1,2,});ByteBuffer i2=ByteBuffer.wrap(new byte[]{0,1,3,});ByteBuffer i3=ByteBuffer.wrap(new byte[]{1,2,3});ByteBuffer i4=ByteBuffer.wrap(new byte[]{0,2,3,});Context context;// 定義Open GL ES繪制所需要的Buffer對象FloatBuffer taperVerticesBuffer;//IntBuffer taperColorsBuffer;ByteBuffer taperFacetsBuffer;FloatBuffer taperTexturesBuffer;// 控制旋轉的角度private float rotate;//定義本程序所使用的紋理private int texture;public MyRenderer(Context main){this.context = main;// 將三棱椎的頂點位置數據數組包裝成FloatBuffertaperVerticesBuffer = floatBufferUtil(taperVertices);// 將三棱椎的4個面的數組包裝成ByteBuffertaperFacetsBuffer = ByteBuffer.wrap(taperFacets);//將立方體的紋理貼圖的坐標數據包裝成FLoatBuffertaperTexturesBuffer = floatBufferUtil(taperTextures);}@Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config){// 關閉抗抖動gl.glDisable(GL10.GL_DITHER);// 設置系統對透視進行修正gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);gl.glClearColor(0, 0, 0, 0);// 設置陰影平滑模式gl.glShadeModel(GL10.GL_SMOOTH);// 啟用深度測試gl.glEnable(GL10.GL_DEPTH_TEST);// 設置深度測試的類型gl.glDepthFunc(GL10.GL_LEQUAL);//啟用2D紋理貼圖gl.glEnable(GL10.GL_TEXTURE_2D);//裝載紋理loadTexture(gl);}@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height){// 設置3D視窗的大小及位置gl.glViewport(0, 0, width, height);// 將當前矩陣模式設為投影矩陣gl.glMatrixMode(GL10.GL_PROJECTION);// 初始化單位矩陣gl.glLoadIdentity();// 計算透視視窗的寬度、高度比float ratio = (float) width / height;// 調用此方法設置透視視窗的空間大小。gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);}// 繪制圖形的方法int[] tex_id = new int[4];@Overridepublic void onDrawFrame(GL10 gl){// 清除屏幕緩存和深度緩存gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);// 啟用頂點坐標數據gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//啟用貼圖坐標數組數據gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); // ①// 設置當前矩陣模式為模型視圖。gl.glMatrixMode(GL10.GL_MODELVIEW);// --------------------繪制圖形---------------------// 重置當前的模型視圖矩陣gl.glLoadIdentity();gl.glTranslatef(0.0f, 0.0f, -1.5f);// 沿著Y軸旋轉gl.glRotatef(rotate, 0f, 0.2f, 0f);// 設置頂點的位置數據gl.glVertexPointer(3, GL10.GL_FLOAT, 0, taperVerticesBuffer);//設置貼圖的坐標數據gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, taperTexturesBuffer); // ②//執行紋理貼圖gl.glBindTexture(GL10.GL_TEXTURE_2D, tex_id[0]); // ③// 按taperFacetsBuffer指定的面繪制三角形gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, i1.remaining(),GL10.GL_UNSIGNED_BYTE, i1);gl.glBindTexture(GL10.GL_TEXTURE_2D, tex_id[1]); // ③// 按taperFacetsBuffer指定的面繪制三角形gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, i2.remaining(),GL10.GL_UNSIGNED_BYTE, i2);gl.glBindTexture(GL10.GL_TEXTURE_2D, tex_id[2]); // ③// 按taperFacetsBuffer指定的面繪制三角形gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, i3.remaining(),GL10.GL_UNSIGNED_BYTE, i3);gl.glBindTexture(GL10.GL_TEXTURE_2D, tex_id[3]); // ③// 按taperFacetsBuffer指定的面繪制三角形gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, i4.remaining(),GL10.GL_UNSIGNED_BYTE, i4);// 繪制結束gl.glFinish();//禁用頂點、紋理坐標數組gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);// 旋轉角度增加1rotate+=1;}private void loadTexture(GL10 gl){// 加載位圖Bitmap[] bm = new Bitmap[4];bm[0]=BitmapFactory.decodeResource(context.getResources(),R.drawable.img1);bm[1]=BitmapFactory.decodeResource(context.getResources(),R.drawable.img2);bm[2]=BitmapFactory.decodeResource(context.getResources(),R.drawable.img3);bm[3]=BitmapFactory.decodeResource(context.getResources(),R.drawable.img4);try{int[] textures = new int[1];// 指定生成N個紋理(第一個參數指定生成一個紋理)// textures數組將負責存儲所有紋理的代號IntBuffer textureBuffer = IntBuffer.allocate(4);gl.glGenTextures(4,textureBuffer);tex_id = textureBuffer.array();for(int i=0;i<4;i++){// 獲取textures紋理數組中的第一個紋理//texture = textures[i];// 通知OpenGL將texture紋理綁定到GL10.GL_TEXTURE_2D目標中gl.glBindTexture(GL10.GL_TEXTURE_2D, tex_id[i]);//gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);// 設置紋理被縮小(距離視點很遠時被縮小)時的濾波方式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_LINEAR);// 設置在橫向、縱向上都是平鋪紋理gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,GL10.GL_REPEAT);gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,GL10.GL_REPEAT);// 加載位圖生成紋理GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bm[i], 0);if (bm[i] != null)bm[i].recycle();}}finally {//生成紋理之后,回收位圖}}// 定義一個工具方法,將float[]數組轉換為OpenGL ES所需的FloatBufferprivate FloatBuffer floatBufferUtil(float[] arr){FloatBuffer mBuffer;// 初始化ByteBuffer,長度為arr數組的長度*4,因為一個int占4個字節ByteBuffer qbb = ByteBuffer.allocateDirect(arr.length * 4);// 數組排列用nativeOrderqbb.order(ByteOrder.nativeOrder());mBuffer = qbb.asFloatBuffer();mBuffer.put(arr);mBuffer.position(0);return mBuffer;} }接下來是MainActivity.java:
package com.example.shiyan3_2;import android.app.Activity; import android.opengl.GLSurfaceView; import android.os.Bundle;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);// 創建一個GLSurfaceView,用于顯示OpenGL繪制的圖形GLSurfaceView glView = new GLSurfaceView(this);// 創建GLSurfaceView的內容繪制器MyRenderer myRender = new MyRenderer(this);// 為GLSurfaceView設置繪制器glView.setRenderer(myRender);setContentView(glView);} }記得加入紋理貼圖,這里圖片的格式是256x256的:
最后展示一下運行結果:
? ? ??
? ?
總結
以上是生活随笔為你收集整理的OpenGL ES实现三棱锥纹理贴图的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言acii 码转化为字母,C语言字符
- 下一篇: Leaflet创建,tileLayer,