Android OpenGL ES2.0 繪製多紋理的三稜錐
效果
實現
使用openGL ES 2.0,分別畫出三稜錐的4個面(包括底面),分別給4個面塗上紋理。著色器
頂點著色器:aPosition用於存放頂點座標,uMvp為準換矩陣,aTextureCoord用於存放紋理座標; 片元著色器: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" +"}";
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