1. 程式人生 > >OpenGLES兩種方式畫立方體

OpenGLES兩種方式畫立方體

OpenGlES,終於能把這東西畫出來奮鬥

其實兩種方法都是畫12個三角形畫出來的,在OpenGL ES中,只支援三角形,所以任何複雜多邊形都是由三角形畫出來的。

第一種:頂點法

把一個四邊形當成一個面,而一個面由兩個三角形組成。一個三角形是不是有3個頂點?,所以一個面就有了3+3個頂點,一個立方體有6個面,6*6個頂點

此立方體的顏色也是根據頂點所渲染,正如定義這個立方體的頂點一樣,不過它的引數可不是和定義頂點的一樣哦,它的引數型別是:R,G,B,A,代表的是顏色值

public class OpenGlEsDemoActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        GLSurfaceView glview = new GLSurfaceView(this);
        glview.setRenderer(new OpenGlRender());
        setContentView(glview);
    }
}
public class OpenGlRender implements GLSurfaceView.Renderer{
	//每一個面畫兩個三角形,立方體有6個面
	private float[] vertices={
			-1.0f,1.0f,1f, // top left
			-1.0f,-1.0f,1f, // bottom left
			1.0f,-1.0f,1f,  //top right
			-1.0f,1.0f,1f, //bottom left
			1.0f,-1.0f,1f, //bottom right
			1.0f,1.0f,1f,	//top right	//前面
			
			1.0f,1.0f,1f,
			1.0f,-1.0f,1f,
			1.0f,-1.0f,-1f,
			1.0f,1.0f,1f,
			1.0f,-1.0f,-1.0f,
			1.0f,1.0f,-1f,		//右面
			
			-1.0f,1.0f,-1.0f,
			-1.0f,-1.0f,-1.0f,
			-1.0f,1.0f,1.0f,
			-1.0f,-1.0f,-1.0f,
			-1.0f,-1.0f,1.0f,
			-1.0f,1.0f,1.0f,  //左面
			
			1.0f,1.0f,-1.0f,
			1.0f,-1.0f,-1.0f,
			-1.0f,-1.0f,-1.0f,
			1.0f,1.0f,-1.0f,
			-1.0f,-1.0f,-1.0f,
			-1.0f,1.0f,-1.0f,   //後面
			
			-1.0f,1.0f,-1.0f,	// top left
			-1.0f,1.0f,1.0f,    //bottom left
			1.0f,1.0f,-1.0f,	//top right
			-1.0f,1.0f,1.0f,	//bottom left
			1.0f,1.0f,1.0f,		//top right
			1.0f,1.0f,-1.0f,	// -top right上面
			
			-1.0f,-1.0f,1.0f,
			-1.0f,-1.0f,-1.0f,
			1.0f,-1.0f,-1.0f,
			-1.0f,-1.0f,1.0f,
			1.0f,-1.0f,-1.0f,
			1.0f,-1.0f,1.0f,	//下面
	};
	//立方體的頂點顏色
	private float[] colors={
			1f,0f,0f,1f,
			1f,0f,0f,1f,
			1f,0f,0f,1f,
			1f,0f,0f,1f,
			1f,0f,0f,1f,
			1f,0f,0f,1f,
			
			1f,0f,1f,1f,
			1f,0f,1f,1f,
			1f,0f,1f,1f,
			1f,0f,1f,1f,
			1f,0f,1f,1f,
			1f,0f,1f,1f,
			
			0f,1f,0f,1f,
			0f,1f,0f,1f,
			0f,1f,0f,1f,
			0f,1f,0f,1f,
			0f,1f,0f,1f,
			0f,1f,0f,1f,
			
			0f,0f,1f,1f,
			0f,0f,1f,1f,
			0f,0f,1f,1f,
			0f,0f,1f,1f,
			0f,0f,1f,1f,
			0f,0f,1f,1f,
			
			0.5f,0f,1f,1f,
			0.5f,0f,1f,1f,
			0.5f,0f,1f,1f,
			0.5f,0f,1f,1f,
			0.5f,0f,1f,1f,
			0.5f,0f,1f,1f,
			
			1f,0f,0.5f,1f,
			1f,0f,0.5f,1f,
			1f,0f,0.5f,1f,
			1f,0f,0.5f,1f,
			1f,0f,0.5f,1f,
			1f,0f,0.5f,1f,
	};
	
	FloatBuffer vertBuffer;//頂點緩衝
	FloatBuffer colorBuffer;//顏色緩衝
	float rx=-70f;//旋轉角度
	
	public OpenGlRender(){
		ByteBuffer vbb=ByteBuffer.allocateDirect(vertices.length*4);
		vbb.order(ByteOrder.nativeOrder());
		vertBuffer=vbb.asFloatBuffer();
		vertBuffer.put(vertices);
		vertBuffer.position(0);
		
		ByteBuffer cbb= ByteBuffer.allocateDirect(colors.length*4);
		cbb.order(ByteOrder.nativeOrder());
		colorBuffer = cbb.asFloatBuffer();
		colorBuffer.put(colors);
		colorBuffer.position(0);
	}
	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		//啟用深度測試
		gl.glEnable(GL10.GL_DEPTH_TEST);
		// 所做深度測試的型別 
		gl.glDepthFunc(GL10.GL_DITHER);
		//黑色背景
		gl.glClearColor(0f, 0f, 0f, 0.5f);
		//啟用陰影平滑
		gl.glShadeModel(GL10.GL_SMOOTH);
		//清除深度快取	
		gl.glClearDepthf(1.0f);
		
		gl.glEnable(GL10.GL_TEXTURE_2D);
		//告訴系統對透視進行修正
		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
	}
	public void draw(GL10 gl){
		gl.glFrontFace(GL10.GL_CCW);
		gl.glEnable(GL10.GL_CULL_FACE);
		gl.glCullFace(GL10.GL_BACK);  
		//開啟頂點和紋理緩衝
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertBuffer);
		gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);
		gl.glLoadIdentity();
		gl.glTranslatef(0, 0, -5);
		gl.glRotatef(45f, 0f, 1f, 0f);//往右邊(y軸)傾斜45度C
		gl.glRotatef(rx,1f, 0f, 0f);//往上面傾斜(x軸)傾斜,根據每次得到的角度
		
		gl.glDrawArrays(GL10.GL_TRIANGLES, 0,vertices.length);
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
		gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		gl.glDisable(GL10.GL_CULL_FACE);
		rx--;//旋轉角度減1
	}
	
	public void onDrawFrame(GL10 gl) {
		// 清除深度和顏色快取
		gl.glClearColor(0f, 0f, 0f, 0.5f);
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
		gl.glMatrixMode(GL10.GL_MODELVIEW);  //設定矩陣模式
		draw(gl);
	}
	public void onSurfaceChanged(GL10 gl, int width, int height) {
		gl.glViewport(0, 0, width, height);
		gl.glMatrixMode(GL10.GL_PROJECTION);
		gl.glLoadIdentity();
		GLU.gluPerspective(gl, 45.0f, (float)width/(float)height, 0.1f, 100.f);
		gl.glMatrixMode(GL10.GL_MODELVIEW);
		gl.glLoadIdentity();
	}

第二種:索引法

畫出來的效果與 上面是一樣的,不過它是通過索引所畫出來的

還是分成6個面來畫,一個面畫2個三角形。

-1f,1f,1f,//0
			-1f,-1f,1f,//1
			1f,-1f,1f,//2
			1f,1f,1f,//3
這裡畫出來的是這個立方體的最前面,對應的還是x,y,z軸。
private short[] indices={
			0,1,2,
			0,2,3,}
只不過的是在這個indices中指定了它的索引位置,所以它才會乖乖聽話把四邊形畫出來

0是左上角的座標,1是左下角,2是右下角,3是右上角

public class Demo extends Activity{
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		GLSurfaceView v = new GLSurfaceView(this);
		v.setRenderer(new OpenGlRender2(null));
		setContentView(v);
	}
}

public class OpenGlRender2 implements Renderer{
	//頂點座標x,y,z
	private float[] vertices=
	{
			-1f,1f,1f,
			-1f,-1f,1f,
			1f,-1f,1f,
			1f,1f,1f,		//前面
			
			1f,1f,1f,
			1f,-1f,1f,
			1f,-1f,-1f,	
			1f,1f,-1f,		//右面
			
			1f,1f,-1f,
			1f,-1f,-1f,
			-1f,-1f,-1f,
			-1f,1f,-1f,		//後面
			
			-1f,1f,-1f,
			-1f,-1f,-1f,
			-1f,-1f,1f,
			-1f,1f,1f,		//左面
			
			-1f,1f,-1f,
			-1f,1f,1f,
			1f,1f,1f,
			1f,1f,-1f,		//上面
			
			-1f,-1f,1f,
			-1f,-1f,-1f,
			1f,-1f,-1f,
			1f,-1f,1f,		//下面
	};
	//頂點顏色,R,G,B,A
	private float[] colors={
			0.2f,0f,0.7f,1f,
			0f,0.4f,0.3f,1f,
			0.8f,0.1f,0.1f,1f,
			1f,1f,1f,1f,		//前面
			
			0f,1f,0f,1f,
			0f,1f,0f,1f,
			0f,1f,0f,1f,
			0f,1f,0f,1f,		//後面
			
			0f,0f,1f,1f,
			0f,0f,1f,1f,
			0f,0f,1f,1f,
			0f,0f,1f,1f,		//左面
			
			0.3f,0.5f,1f,1f,
			0.3f,0.5f,1f,1f,
			0.3f,0.5f,1f,1f,
			0.3f,0.5f,1f,1f,	//上面
			
			0f,0.2f,0.3f,1f,
			0f,0.4f,0.3f,1f,
			0f,0.3f,0.3f,1f,
			0f,0.4f,0.3f,1f,	//下面
			
	};
	
	private short[] indices={
			0,1,2,
			0,2,3,
			4,5,6,
			4,6,7,
			8,9,10,
			8,10,11,
			12,13,14,
			12,14,15,
			16,17,18,
			16,18,19,
			20,21,22,
			20,22,23,
	};
	
	private FloatBuffer mVertexBuffer,mColorBuffer;
	private ShortBuffer mIndixBuffer;
	private float rx=45.0f;
	
	public OpenGlRender2(Bitmap bitmap){
		ByteBuffer vbb=ByteBuffer.allocateDirect(vertices.length*4);
		vbb.order(ByteOrder.nativeOrder());
		mVertexBuffer=vbb.asFloatBuffer();
		mVertexBuffer.put(vertices);
		mVertexBuffer.position(0);
		
		ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length*2);
		ibb.order(ByteOrder.nativeOrder());
		mIndixBuffer=ibb.asShortBuffer();
		mIndixBuffer.put(indices);
		mIndixBuffer.position(0);
		
		ByteBuffer cbb=ByteBuffer.allocateDirect(colors.length*4);
		cbb.order(ByteOrder.nativeOrder());
		mColorBuffer=cbb.asFloatBuffer();
		mColorBuffer.put(colors);
		mColorBuffer.position(0);
	}

	public void onDrawFrame(GL10 gl) {
		gl.glClearColor(0f, 0f, 0f, 0.5f);  
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);  
		gl.glFrontFace(GL10.GL_CCW);
		gl.glEnable(GL10.GL_CULL_FACE);
		gl.glCullFace(GL10.GL_BACK);
		
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glVertexPointer(3,GL10.GL_FLOAT, 0, mVertexBuffer);
		gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
		gl.glColorPointer(4, GL10.GL_FLOAT, 0, mColorBuffer);
		gl.glLoadIdentity();
//		gl.glColor4f(1f, 0f, 0f, 1f);
		gl.glTranslatef(0f, 0f, -5f);
		gl.glRotatef(-45f, 0f, 1f, 0f);
		gl.glRotatef(rx, 1f, 0f, 0f);
		
		gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_SHORT, mIndixBuffer);
		
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glDisable(GL10.GL_CULL_FACE);
		rx++;
	}

	public void onSurfaceChanged(GL10 gl, int width, int height) {
		gl.glViewport(0, 0, width, height);
		gl.glMatrixMode(GL10.GL_PROJECTION);
		gl.glLoadIdentity();
		GLU.gluPerspective(gl, 45.0f, (float)width/(float)height, 0.1f, 100.f);
		gl.glMatrixMode(GL10.GL_MODELVIEW);
		gl.glLoadIdentity();
	}

	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		//啟用深度測試
		gl.glEnable(GL10.GL_DEPTH_TEST);
		// 所做深度測試的型別 
		gl.glDepthFunc(GL10.GL_DITHER);
		//黑色背景
		gl.glClearColor(1f, 0f, 0f, 1f);
		//啟用陰影平滑
		gl.glShadeModel(GL10.GL_SMOOTH);
		//清除深度快取	
		gl.glClearDepthf(1.0f);
	}