OpenGL ES2.0 初步

最近工作要用到OpenGL的技術,現在開始學習一些OpenGL  ES的基礎知識,並記錄。

所有參考:

 

Android入門(4)OpenGL ES編程環境搭建 

http://blog.csdn.net/silangquan/article/details/7938332


一步一步學android OpenGL ES2.0編程(1)http://blog.csdn.net/niu_gao/article/details/8533126





1、Android Mainfest如下: 

重點:<uses-feature android:glEsVersion="0x00020000" android:required="true"/>指明使用OpenGL的版本

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.test.opengl01"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="17"
        android:targetSdkVersion="17" />
    <uses-feature android:glEsVersion="0x00020000" android:required="true"/>
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
            <activity
            android:name="com.test.opengl.MainActivity"
            android:label="@string/app_name"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
         </activity>
    </application>
</manifest>
2、MainActivity裏,只要定義GLSurfaceView mGLView即可,繪圖用的控件
package com.test.opengl;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
public class MainActivity extends Activity {
	private GLSurfaceView mGLView;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mGLView = new MyCLSurfaceView(this);
		setContentView(mGLView);
	}
	
	@Override
	protected void onPause() {
		super.onPause();
		mGLView.onPause();
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		mGLView.onResume();
	}
}

3、MyCLSurfaceView,繼承自GLSurfaceView,只要創建OpenGL 的上下文對象,設置繪圖對象,並在繪製數據改變時才重繪MyCLSurfaceView

package com.test.opengl;
import android.content.Context;
import android.opengl.GLSurfaceView;
public class MyCLSurfaceView extends GLSurfaceView {
	public MyCLSurfaceView(Context context) {
		super(context);
		// 創建一個OpenGL ES 2.0 context
		setEGLContextClientVersion(2);
		//設置Renderer到GLSurfaceView
		setRenderer(new MyGL20Renderer());
		//只有在繪製數據改變時才繪製view
		setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
	}
}
4、MyGL20Renderer,Renderer,所有的繪圖步驟全部在這裏實現

package com.test.opengl;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLES20;
import android.opengl.GLSurfaceView;

/*此類控制向GLSurfaceView的繪製工作。它有三個方法被Android系統調用來計算在
 * GLSurfaceView上畫什麼以及如何畫。
 * onSurfaceCreated()- 僅調用一次,用於設置view的OpenGLES環境。
 *onDrawFrame()- 每次View被重繪時被調用。
 *onSurfaceChanged()- 如果view的幾和形狀發生變化了就調用,例如當豎屏變爲橫屏時。
 */
public class MyGL20Renderer implements GLSurfaceView.Renderer{

	@Override
	public void onDrawFrame(GL10 gl) {
		//重繪背景色
		GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
		mTriangle.draw();
	}

	@Override
	public void onSurfaceChanged(GL10 gl, int width, int height) {
		// TODO Auto-generated method stub
		GLES20.glViewport(0, 0, width, height);
	}

	Triangle mTriangle = null;
	@Override
	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		//設置背景的顏色
//		GLES20.glClearColor(red, green, blue, alpha)
		GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
		 // 初始化一個三角形
	    mTriangle = new Triangle();
	}
	
	public static int loadShader(int type, String shaderCode){
	    // 創建一個vertex shader類型(GLES20.GL_VERTEX_SHADER)
	    // 或fragment shader類型(GLES20.GL_FRAGMENT_SHADER)
	    int shader = GLES20.glCreateShader(type);
	    // 將源碼添加到shader並編譯之
	    GLES20.glShaderSource(shader, shaderCode);
	    GLES20.glCompileShader(shader);
	    return shader;
	}
}

5、如果要繪製某種形狀。則要自定義類來實現,所有繪圖的詳細過程在自定義類中實現。

package com.test.opengl;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import android.opengl.GLES20;
public class Triangle {
	private FloatBuffer vertexBuffer;
	//數組中每個頂點的座標數
	static final int COORDS_PER_VERTEX = 3;
	private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;  
    private final int vertexStride = COORDS_PER_VERTEX * 4; // bytes per vertex  
	static float triangleCoords[] = {//逆時針
		 0.0f,  0.6f, 0.0f,//top
		-0.5f, -0.3f, 0.0f,
		 0.5f, -0.3f, 0.0f
	};
	 
	float color[] = {0.6f,0.7f,0.2f,1.0f};
	private final String vertexShaderCode =
		    "attribute vec4 vPosition;" +
		    "void main() {" +
		    "  gl_Position = vPosition;" +
		    "}";

		private final String fragmentShaderCode =
		    "precision mediump float;" +
		    "uniform vec4 vColor;" +
		    "void main() {" +
		    "  gl_FragColor = vColor;" +
		    "}";
		
	public Triangle(){
		
		//爲存放形狀的座標,初始化頂點字節座標
		ByteBuffer bb = ByteBuffer.allocateDirect(triangleCoords.length *4);
	
		//設置設備的頂點字節序
		bb.order(ByteOrder.nativeOrder());
		
		//從ByteBuffer創建一個浮點緩衝
		vertexBuffer = bb.asFloatBuffer();
		
		//把所有座標加入FloatBuffer中
		vertexBuffer.put(triangleCoords);
		
		//設置buffer爲從第一個座標讀起
		vertexBuffer.position(0);
		
		int vertexShader = MyGL20Renderer.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
	    int fragmentShader = MyGL20Renderer.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);

	    mProgram = GLES20.glCreateProgram();             // 創建一個空的OpenGL ES Program
	    GLES20.glAttachShader(mProgram, vertexShader);   // 將vertex shader添加到program
	    GLES20.glAttachShader(mProgram, fragmentShader); // 將fragment shader添加到program
	    GLES20.glLinkProgram(mProgram);                  // 創建可執行的 OpenGL ES program
	    
	}
	
	private final int mProgram;
	private  int mPositionHandle;
	private int mColorHandle;//?????
	
	public void draw() {
	    // 將program加入OpenGL ES環境中
	    GLES20.glUseProgram(mProgram);

	    // 獲取指向vertex shader的成員vPosition的 handle
	    mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");

	    // 啓用一個指向三角形的頂點數組的handle
	    GLES20.glEnableVertexAttribArray(mPositionHandle);

	    // 準備三角形的座標數據
	    GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
	                                 GLES20.GL_FLOAT, false,
	                                 vertexStride, vertexBuffer);//????

	    // 獲取指向fragment shader的成員vColor的handle 
	    mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");

	    // 設置三角形的顏色
	    GLES20.glUniform4fv(mColorHandle, 1, color, 0);

	    // 畫三角形
	    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);//??????

	    // 禁用指向三角形的頂點數組
	    GLES20.glDisableVertexAttribArray(mPositionHandle);
	}
}







發佈了76 篇原創文章 · 獲贊 28 · 訪問量 33萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章