1. 程式人生 > >Android OpenGL ES2.0 繪製多紋理的三稜錐

Android OpenGL ES2.0 繪製多紋理的三稜錐

效果


實現

使用openGL ES 2.0,分別畫出三稜錐的4個面(包括底面),分別給4個面塗上紋理。

著色器

頂點著色器:
    private final String mVertexShaderWithTexture=
            "attribute vec3 aPosition;\n"
            +"uniform mat4 uMvp;\n"
            +"attribute vec2 aTextureCoord;\n"
            +"varying vec2 vTextureCoord;\n"
            +"void main(){\n"
            +"  vTextureCoord=aTextureCoord;"
            +"  vec4 vertex=vec4(aPosition[0],aPosition[1],aPosition[2],1.0);"
            +"  gl_Position = uMvp*vertex;\n"
            +"}";
aPosition用於存放頂點座標,uMvp為準換矩陣,aTextureCoord用於存放紋理座標; 片元著色器:
    private final String mFragmentShaderWithTexture=
            "precision mediump float;\n"
            +"uniform sampler2D uSample;\n"
            +"varying vec2 vTextureCoord;\n"
            +"void main(){\n"
            +"  gl_FragColor =texture2D(uSample,vTextureCoord);\n"
            +"}";

uSample為紋理採集器,vTextureCoord是頂點著色器傳過來的經過插值後的頂點座標。 由內建方法texture2D,通過紋理採集器和對應紋理座標得到紋理值給gl_FragColor賦值。

建立渲染程式

通過載入著色器原始碼,編譯著色器獲取頂點和片元著色器; 建立渲染程式,為其新增著色器,連結程式,從而得到需要使用的渲染程式。 基礎的東西,只羅列了步驟。

繪前準備

獲取著色器中對應變數的引用:
            mAPositionLoc=GLES20.glGetAttribLocation(mShader,"aPosition");
            mUMvpLoc=GLES20.glGetUniformLocation(mShader,"uMvp");
            mUSamplerLoc=GLES20.glGetUniformLocation(mShader,"uSample");
            mATextureCoordLoc=GLES20.glGetAttribLocation(mShader,"aTextureCoord");
準備資料:
            mVertexFB=transFloat(mVertex);
            parseVertexInd();
            mTextureCoordFB=transFloat(mTextureCoords);
其中,transFloat()將float的陣列轉換為FloatBuffer; 因為要單獨繪製出每個面,parseVertexInd()將頂點索引陣列劃分為4個索引陣列。
    private FloatBuffer transFloat(float[] floatArray){
        ByteBuffer bb = ByteBuffer.allocateDirect(floatArray.length * 4);
        bb.order(ByteOrder.nativeOrder());
        FloatBuffer fb = bb.asFloatBuffer();
        fb.put(floatArray);
        fb.position(0);
        return fb;
    }
    private void parseVertexInd(){
        m1stInd=Arrays.copyOfRange(mVertexInd,0,3);
        m1stSB=transShort(m1stInd);
        m2ndInd=Arrays.copyOfRange(mVertexInd,3,6);
        m2ndSB=transShort(m2ndInd);
        m3rdInd=Arrays.copyOfRange(mVertexInd,6,9);
        m3rdSB=transShort(m3rdInd);
        m4thInd=Arrays.copyOfRange(mVertexInd,9,12);
        m4thSB=transShort(m4thInd);
    }

開始繪製

        GLES20.glUseProgram(mShader);
        GLES20.glEnable(GLES20.GL_CULL_FACE);
        GLES20.glCullFace(GLES20.GL_BACK);
        GLES20.glFrontFace(GLES20.GL_CCW);
使用渲染程式,剔除背面,且設定逆時針方向繪製的面為正面。

設定轉換矩陣

            Matrix.setIdentityM(mRotateM,0);
            Matrix.multiplyMM(mRotateM,0,mRotateY,0,mRotateX,0);
            Matrix.multiplyMM(mRotateM,0,mRotateZ,0,mRotateM,0);
            Matrix.setIdentityM(mViewM,0);
            Matrix.setLookAtM(mViewM,0,mEyeX,mEyeY,mEyeZ,mDstX,mDstY,mDstZ,mUpX,mUpY,mUpZ);
            Matrix.setIdentityM(mProjectionM,0);
            Matrix.frustumM(mProjectionM,0,-mFrustumRatio/mDisplayRatio,mFrustumRatio/mDisplayRatio,-mFrustumRatio,
                    mFrustumRatio,mFrustumNear,mFrustumFar);
            Matrix.multiplyMM(mMvpMatrix,0,mViewM,0,mRotateM,0);
            Matrix.multiplyMM(mMvpMatrix,0,mProjectionM,0,mMvpMatrix,0);
mRotateX、mRotateY和mRotateZ是分別繞X、Y和Z軸旋轉的矩陣(呼叫了Matrix.rotateM()方法得到的結果); Matrix.setLookAtM()設定視線; Matrix.frustumM()設定透視矩陣。 最終將三種旋轉的結果存放在mMvpMatrix中。

建立Textures

            GLES20.glGenTextures(4,mTextureId,0);
            for (int i=0;i<4;i++){
                generateTexture(i);
            }
其中generateTexure()方法為如下:
    private void generateTexture(int index){
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,mTextureId[index]);
        GLES20.glPixelStorei(GLES20.GL_UNPACK_ALIGNMENT,1);
        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL_NEAREST);
        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MAG_FILTER,GLES20.GL_LINEAR);
        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_WRAP_S,GLES20.GL_REPEAT);
        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_WRAP_T,GLES20.GL_REPEAT);
        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D,0,mTextures[index],0);
    }
要繪製4個面,且4個面有不同的紋理,則需要4個Texture。

啟用紋理單元和紋理座標

        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLES20.glUniform1i(mUSamplerLoc,0);
        GLES20.glVertexAttribPointer(mATextureCoordLoc,2,GLES20.GL_FLOAT,false,0,mTextureCoordFB);
        GLES20.glEnableVertexAttribArray(mATextureCoordLoc);
激活了預設紋理單元0,並將片元著色器的sampler2D物件繫結至該紋理單元。繫結紋理座標的引用和值,並激活它。

逐面繪製

        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,mTextureId[0]);
        GLES20.glDrawElements(GLES20.GL_TRIANGLES,3,GLES20.GL_UNSIGNED_SHORT,m1stSB);

        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,mTextureId[1]);
        GLES20.glDrawElements(GLES20.GL_TRIANGLES,3,GLES20.GL_UNSIGNED_SHORT,m2ndSB);

        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,mTextureId[2]);
        GLES20.glDrawElements(GLES20.GL_TRIANGLES,3,GLES20.GL_UNSIGNED_SHORT,m3rdSB);

        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,mTextureId[3]);
        GLES20.glDrawElements(GLES20.GL_TRIANGLES,3,GLES20.GL_UNSIGNED_SHORT,m4thSB);
繪製每個面前,首先將特定紋理繫結至紋理單元0,讓sampler2D物件能採集到正確的資料; 接著呼叫drawElements方法,drawElements方法將使用之前繫結的頂點陣列。注意,最後1個引數是索引陣列,可以看到每次繪製時索引陣列都是不同的。 這些索引陣列是在parseVertexInd()方法中得到的。

完整demo

完整的demo在如下的地址中查詢: https://github.com/lyzirving/TrianglePyramidInAndroid.git
在完整的demo中,我將上述方法封裝到了Triangle類中,可以選擇通過顏色或是紋理來塗畫三稜錐的表面。 上述程式碼和demo中的程式碼並不完善,有所缺漏還請大家多多交流!









相關推薦

Android OpenGL ES2.0 繪製紋理稜錐

效果 實現 使用openGL ES 2.0,分別畫出三稜錐的4個面(包括底面),分別給4個面塗上紋理。 著色器 頂點著色器: private final String mVertexShaderWithTexture= "attribute

Android OpenGL ES2.0(一):詳細講解如何繪製一個三角形

一、Android OpenGL ES2.0簡介 1. 什麼是OpenGL? OpenGL(全寫Open Graphics Library)是指定義了一個跨程式語言、跨平臺的程式設計介面規格的專業的圖形程式介面。它用於三維影象(二維的亦可),是一個功能

Opengl es2.0 學習筆記()shader的使用

一.shader Opengl es渲染管線中有兩處可以程式設計,一個是頂點著色器 一個是畫素著色器/片圓著色器 不清楚的可以 看看OpenGLes 渲染管線 二.API //建立shader,返回shader Id //param: //GL_VERTE

Android OpenGL ES2.0基礎(一、最簡單的使用)

一、OpenGL ES是什麼 OpenGL(Open Graphics Library)是一個跨程式語言、跨平臺的3D圖形庫。廣泛應用於遊戲、娛樂、VR等領域.安卓系統中的核心庫層就有這個。OpenGL ES是在OpenGL基礎上針對移動端而裁剪的 。Open

一步一步學android OpenGL ES2.0程式設計(1)

建立OpenGL ES環境 使用幾乎是整合OpenGLES到你的應用的唯一方式。對於一個全屏或近全屏的graphicsview,它是最好的選擇。如果只是在某個小部分顯示OpenGLES圖形則可以考慮。當然如果你比較變態,你完全可以使用建立一個OpenGLES vi

Android OpenGL ES2.0 實現步驟

定義頂點資料 頂點資料描述了OpenGL世界中元素的位置,下面定義了繪製一個三角形所需要的頂點資料,x,y,z對應三角形的每個頂點座標,其中z代表深度,x1,y1對應著色器的顏色程式碼。 float vertices[] = {

Android openGL ES2.0 Matrix.frustumM和Matrix.setLookAtM解析

Android使用OpenGL ES2.0繪製3D影象或者載入3D模型時,為了達到立體效果往往需要設定視見轉換矩陣和投影轉換矩陣即 Matrix.setLookAtM(mVMatrix, 0, cx, cy, cz, tx, ty, tz, upx, upy,

OpenGL ES2.0實現文字繪製Android

OpenGL ES2.0是無法直接繪製文字的,我採用的方法是將文字轉為Bitmap,然後以圖貼的方式進行渲染。看到網上也有人是將文字生成點,一個個進行繪製的,個人覺得這種方法還是挺麻煩的。文章分為兩部分,一部分是在canvas中繪圖轉Bitmap,第二部分是貼圖紋理繪製。

OpenGL ES2.0入門之Android篇(一)——繪製三角形

OpenGL ES簡介 OpenGL ES是一個為行動式或嵌入式裝置例如:行動電話、監視器等發展的3D繪圖API。 在Android框架中有兩個基礎類用於使用OpenGL ES建立和處理圖形 GLSurfaceView類是OpenGL ES繪製圖形

OpenGL ES2 0程式設計步曲

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

OpenGL ES2.0實現手指滑動平移、雙指縮放Android

主要是實現了手指在螢幕上滑動實現平移,兩個手指進行縮放。主要是這部分矩陣還挺麻煩的。 效果圖如下所示: 核心部分程式碼如下 觸控事件處理: @SuppressLint("ClickableViewAccessibility") @Override

Opengl es2.0 學習筆記(七)基礎紋理

一.使用紋理過程 使用FreeImage.lib 讀取圖片,獲取調色盤.(windows顏色不是rgb是bgr,此處需要轉換) glGenTextures建立一個紋理控制代碼 gl

Cocos2dx-OpenGL ES2.0教程:紋理貼圖(6)

在上一篇文章中,我們介紹瞭如何繪製一個立方體,裡面涉及的知識點有VBO(Vertex Buffer Object)、IBO(Index Buffer Object)和MVP(Modile-View-Projection)變換。 本文將在教程4的基礎之上,新增紋理貼圖支

Eclipse中通過Android模擬器調用OpenGL ES2 0函數操作步驟

pro conf assign mod window nta target con ews 1、 先按照http://blog.csdn.net/fengbingchun/article/details/10439281中操作搭建好基本的Android開發環境; 2、

Android使用NDK OpenGL ES3.0繪製一個三角形

Android使用NDK  OpenGL ES3.0繪製一個三角形      網上已經有很多OpenCV的教程,不過大都是基於Java層呼叫openGL介面,若使用Java層openGL介面繪製三角形,還是比較簡單的,但要是使用NDK C++ 實現,還是有點複雜。  

Android OpenGL ES (二) 繪製維/空間座標系

 * 此檔案是關於3D座標軸的繪製,用jiasu.java和jiasu.xml實現了使用者介面  * 關於3D處理的所有程式都在此檔案中  *zjk 2014/03/04  */ public class Jiasudu implements Renderer {float x=-0.5f,y=-0.5f,z

Opengl es2.0 學習筆記(五)圖元裝配

文章目錄二、API三、注意四、虛擬碼 一、圖元型別 #define GL_POINTS 0x0000點 #define GL_LINES 0x0001線 #defi

Opengl es2.0 學習筆記(六)矩陣變化

一.座標系變化 openGL使用右手座標 從左到右,x遞增 從下到上,y遞增 從遠到近,z遞增 MVP 模型矩陣(Model):將區域性座標轉換為世界座標 觀察矩陣(View): 投影矩陣(Projection):正交還是透視投影 1.概述 為了將座標從一個座

Opengl es2.0 學習筆記(四)shader語法 GLSL

一、變數 GLSL的變數命名方式與C語言類似。變數的名稱可以使用字母,數字以及下劃線,但變數名不能以數字開頭,還有變數名不能以gl_作為字首,這個是GLSL保留的字首,用於GLSL的內部變數。當然還

Opengl es2.0 學習筆記(API篇)所有API的翻譯

包含了 gl2.h 和egl.h兩個標頭檔案 gl2.h gl2資料結構 /*------------------------------------------------------------------------- * Data type defi