日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android OpenGL ES 2.0绘制简单三角形

發布時間:2025/4/16 Android 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android OpenGL ES 2.0绘制简单三角形 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


實現步驟

l? 實現一個工具類ShalderUtil,用于將著色器代碼加載進顯卡進行編譯

l? 實現一個三角形Triangle類 在該類中加載著色器、初始化頂點數據、初始化著色器以及繪制三角形方法

l? 實現一個視圖類,繼承GLSurfaceView類,并通過內部類SceneRenderer創建渲染器。

l? 實現MainActivity類,將視圖類加載進Activity中

?

實現代碼

l? ShalderUtil.java

? package com.flying.opengl_1;

?

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.InputStream;

import android.content.res.Resources;

import android.opengl.GLES20;

import android.util.Log;

/**

?* 將著色器腳本加載進顯卡并編譯? 加載定點和片元著色器類

?* @author min

?*

?*/

public class ShaderUtil {

?? public static final String=DEBUG_ES20_ERROR="ES20_ERROR";

?? /**

?? ?* 加載指定著色器方法

?? ?* @param shaderType 著色器類型

?? ?* @param source 著色器腳本資源

?? ?* @return返回著色器id

?? ?*/

?? public static int loadShader(int shaderType,String source){

?? ?? int shader=GLES20.glCreateShader(shaderType);? //創建一個著色器并返回id

???? if(shader!=0)

???? {

??????? GLES20.glShaderSource(shader, source); //加載著色器源代碼

??????? GLES20.glCompileShader(shader); //編譯

??????? int []compiled=new int[1];

??????? GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);

??????? if(compiled[0]==0) //編譯失敗

??????? {

????????? Log.e(DEBUG_ES20_ERROR, "Counld not Compiled Shader "+shaderType +":"+GLES20.glGetShaderInfoLog(shader));

????????? GLES20.glDeleteShader(shader);

????????? shader=0;

??????? }

???? }

???? return shader;

???? }

?? /**

?? ?* 創建著色器程序

?? ?* @param vertexSource?? 頂點著色器腳本

?? ?* @param fragmentSource? 片元著色器腳本

?? ?* @return

?? ?*/

?? public static int createProgram(String vertexSource,String fragmentSource){

???? int vertextShader=loadShader(GLES20.GL_VERTEX_SHADER, vertexSource); //加載頂點著色器

???? if(vertextShader==0){

??????? return 0;

???? }

???? int pixelShader=loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource); //加載片元著色器

???? if(pixelShader==0)

???? {

??????? return 0;

???? }

???? int program=GLES20.glCreateProgram(); //創建程序

???? if(program!=0)

???? {

??????? GLES20.glAttachShader(program, vertextShader); //向程序中加載頂點著色器

??????? checkGlError("glAttachShader");

??????? GLES20.glAttachShader(program, pixelShader); //向程序中加載片元著色器

??????? checkGlError("glAttachShader");

??????? GLES20.glLinkProgram(program);? //鏈接程序

??????? int []linkStatus=new int[1];

??????? GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus,0);

??????? if(linkStatus[0]!=GLES20.GL_TRUE)

??????? {

????????? Log.e(DEBUG_ES20_ERROR, "Cound link program");

????????? Log.e(DEBUG_ES20_ERROR, GLES20.glGetProgramInfoLog(program));

????????? GLES20.glDeleteProgram(program);? //刪除程序

????????? return 0;

??????? }

???????

???? }

???? return program;

???? }

?? //檢查每步操作是否有錯誤

?? public static void checkGlError(String op){

???? int error;

???? while((error=GLES20.glGetError())!=GLES20.GL_NO_ERROR){

??????? Log.e(DEBUG_ES20_ERROR, op+": gkError"+ error);

??????? throw new RuntimeException(op+": gkError"+ error);? //拋出異常

???? }

???????

?? }

?? //sh腳本加載著色器內容的方法

?? public static String loadFromAssetsFile(String fname,Resources r){

???? String result=null;

???? ByteArrayOutputStream baos=null;

???? InputStream in=null;

???? try {

??????? in=r.getAssets().open(fname);//assets文件夾中讀取

??????? int ch=0;

??????? baos=new ByteArrayOutputStream();

??????? while((ch=in.read())!=-1)

??????? {

????????? baos.write(ch);

??????? }

??????? byte[] buff=baos.toByteArray();

??????? result=new String(buff,"UTF-8");

??????? result=result.replaceAll("\\r\\n", "\n");

???? } catch (IOException e) {

??????? e.printStackTrace();

???? }

???? finally{

??????? try {

????????? baos.close();

??????? } catch (IOException e) {

????????? e.printStackTrace();

??????? }

??????? try {

????????? in.close();

??????? } catch (IOException e) {

????????? e.printStackTrace();

??????? }

???? }

????

???? return result;

?? }

??

}

?????????????????????????????????????????????????????????????????????????????????

l? Triangle.java類

?

?

package com.flying.opengl_1;

?

import java.nio.ByteBuffer;

import java.nio.ByteOrder;

import java.nio.FloatBuffer;

?

import android.opengl.GLES20;

import android.opengl.GLSurfaceView;

import android.opengl.Matrix;

import android.util.Log;

?

/**

?* 三角形類

?* @author min

?*

?*/

public class Triangle {

?? public static final String DEBUG="Triangle";

?? public static float[] mProjMatrix=new float[16] ; //4*4投影矩陣

?? public static float[] mVMMatrix=new float[16] ; //攝像機位置朝向的參數矩陣

?? public static float[] mMVPMatrix; //總變換矩陣

?? int mProgram; //自定義渲染管線著色器程序 id

?? int muMVPMatrixHandle ; //總變換矩陣引用

?? int maPositionHandle ; //頂點位置屬性引用

?? int maColorHandle;? //頂點顏色屬性引用

?? String mVertexShader ;//頂點著色器腳本代碼

?? String mFragmentShader ;//片元著色器腳本代碼

?? static float []mMMatrix=new float[16]; //具體物體的3D變換矩陣包括旋轉平移縮放

?? FloatBuffer mVertexBuff ;//頂點坐標數據緩沖

?? FloatBuffer mColorBuff ;// 頂點著色數據緩沖

?? int vCount=0; //頂點數量

??

?? float xAngle=0; //x軸旋轉角度

??

?? public Triangle(GLSurfaceView mv) {

???? initVertexData();

???? initShader(mv);

?? }

??

?? /*

?? ?* 自定義初始化頂點數據方法

?? ?*/

?? public void initVertexData(){

???? Log.d(DEBUG, "---------initVertexData-------------");

???? ? vCount=3;?

?? ??????? final float UNIT_SIZE=0.2f;

?? ??????? float vertices[]=new float[]

?? ??????? {

?? ??????? -4*UNIT_SIZE,0,

?? ??????? 0,0,-4*UNIT_SIZE,

?? ??????? 0,4*UNIT_SIZE,0,0

?? ??????? };

???????

?? ??????? ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);

?? ??????? vbb.order(ByteOrder.nativeOrder());

?? ??????? mVertexBuff = vbb.asFloatBuffer();

?? ??????? mVertexBuff.put(vertices);

?? ??????? mVertexBuff.position(0);

?? ???????

?? ??????? float colors[]=new float[]

?? ??????? {

?? ??????? ??? 1,1,1,0,

?? ??????? ??? 0,0,1,0,

?? ??????? ??? 0,1,0,0

?? ??????? };

?? ???????

?? ??????? ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);

?? ??????? cbb.order(ByteOrder.nativeOrder());

?? ??????? mColorBuff = cbb.asFloatBuffer();

?? ??????? mColorBuff.put(colors);

?? ??????? mColorBuff.position(0);

?? }

??

?? //初始化著色器以及繪制圖形方法

?? public void initShader(GLSurfaceView mv)

?? {

???? Log.d(DEBUG, "---------initShader-------------");

?? ?? mVertexShader=ShaderUtil.loadFromAssetsFile("vertex.sh", mv.getResources());

?? ?? mFragmentShader=ShaderUtil.loadFromAssetsFile("frag.sh", mv.getResources());

???? mProgram=ShaderUtil.createProgram(mVertexShader, mFragmentShader);

???? maPositionHandle=GLES20.glGetAttribLocation(mProgram, "aPosition");

???? maColorHandle=GLES20.glGetAttribLocation(mProgram, "aColor");

?? ?? muMVPMatrixHandle=GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");

?? }

??

?? public void drawSelf(){

???? //Log.d(DEBUG, "---------drawSelf-------------");

???? GLES20.glUseProgram(mProgram);

???? Matrix.setRotateM(mMMatrix, 0, 0, 0, 1, 0); //初始化變換矩陣

???? Matrix.translateM(mMMatrix, 0, 0, 0, 1) ;? //初始化沿Z軸正向位移

???? Matrix.rotateM(mMMatrix, 0, xAngle, 1, 0, 0); //設置繞x軸旋轉

???? GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, Triangle.getFinalMatrix(mMMatrix),0);

???? GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false,3*4, mVertexBuff);

???? GLES20.glVertexAttribPointer(maColorHandle, 3, GLES20.GL_FLOAT, false,4*4, mColorBuff);

???? GLES20.glEnableVertexAttribArray(maPositionHandle);

???? GLES20.glEnableVertexAttribArray(maColorHandle);

???? GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);

?? }

??

??

?? /**

?? ?* 產生最終變換矩陣方法

?? ?* @param spec

?? ?* @return

?? ?*/

?? public static float[]getFinalMatrix(float []spec){

???? mMVPMatrix=new float[16];

???? Matrix.multiplyMM(mMVPMatrix, 0, mVMMatrix, 0, spec, 0);?

???? Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);

???? return mMVPMatrix;

?? }

}

l? MyTDView.java類

?

public class MyTDView extends GLSurfaceView {

?? public static final String DEBUG="MyTDView";

?? final float ANGLE_SPAN=0.375f; //每次三角形旋轉角度

?? RotateThread rThread; //自定義線程類

?? SceneRenderer mRenderer; //自定義渲染器

??

?? public MyTDView(Context context) {

???? super(context);

???? this.setEGLContextClientVersion(2); //使用 OpenGl 2.0 需設置該值為2

???? mRenderer=new SceneRenderer();

???? this.setRenderer(mRenderer);

???? this.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);

?? }

??

?? public class SceneRenderer implements GLSurfaceView.Renderer{

?

???? Triangle tle;

???? //一直持續執行

???? @Override

???? public void onDrawFrame(GL10 gl) {

??????? //Log.d(DEBUG, "--------onDrawFrame------");

???? ?? GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT|GLES20.GL_COLOR_BUFFER_BIT);

??????? tle.drawSelf(); //繪制三角形

???????

???????

???? }

????

???? @Override

???? public void onSurfaceCreated(GL10 gl, EGLConfig config) {

??????? Log.d(DEBUG, "--------onSurfaceCreated------");

??????? GLES20.glClearColor(0, 0, 0, 1.0F); //設置背景色

??????? tle=new Triangle(MyTDView.this);

??????? GLES20.glEnable(GLES20.GL_DEPTH_TEST);

??????? rThread=new RotateThread();

??????? rThread.start();

???? }

?

???? @Override

???? public void onSurfaceChanged(GL10 gl, int width, int height) {

??????? Log.d(DEBUG, "--------onSurfaceChanged------");

??????? GLES20.glViewport(0, 0, width, height);? //設置視口

??????? float ratio=(float)width/height;

??????? Matrix.frustumM(Triangle.mProjMatrix, 0, -ratio, ratio, -1, 1, 1, 10); //設置透視投影

??????? Matrix.setLookAtM(Triangle.mVMMatrix,0,0 ,0, 3, 0f, 0f, 0f, 0f, 1.0f, 0.0f); //設置攝影機

???????

???????

???? }

?

?

????

?? }

?? public class RotateThread extends Thread{

???? public boolean flag=true;

?

???? @Override

???? public void run() {

???????

??????? super.run();

??????? while (flag) {

????????? mRenderer.tle.xAngle=mRenderer.tle.xAngle+ANGLE_SPAN;

????????? try {

???????????? Thread.sleep(20);

????????? } catch (InterruptedException e) {

???????????? // TODO Auto-generated catch block

???????????? e.printStackTrace();

????????? }

?????????

??????? }

???? }

????

?? }

}

?

l? 最后就是MainActivity.java類

?

public class MainActivity extends Activity {

?

?? @Override

?? protected void onCreate(Bundle savedInstanceState) {

???? super.onCreate(savedInstanceState);

?? ?? setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

???? MyTDView mv=new MyTDView(this);

???? mv.requestFocus();

???? mv.setFocusableInTouchMode(true);

???? setContentView(mv);

?? }

}

}

?

?

l? 最后就是頂點著色器和片元著色器

?

片元著色器 ?frag.sh

precision mediump float;

varying? vec4 vColor; //接收從頂點著色器過來的參數

?

void main()????????????????????????

{??????????????????????

?? gl_FragColor = vColor;//給此片元顏色值

}

?

? 頂點著色器? vertex.sh

?

uniform mat4 uMVPMatrix;

attribute vec3 aPosition ;

attribute vec4 aColor;

varying vec4 vColor ;

void main(){

?? gl_Position=uMVPMatrix *vec4(aPosition,1);

?? vColor =aColor; }

注意,著色器文件放在assets文件夾中。以sh為后綴。有關著色器語法的詳細介紹,請參照http://blog.csdn.net/xy849288321/article/details/8598948里面有詳細的介紹。

?

至此,一個簡單的三角形繪制完畢。。。(參考 吳亞峰編著《android 3d游戲開發技術寶典》)

總結

以上是生活随笔為你收集整理的Android OpenGL ES 2.0绘制简单三角形的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。