OpenGLES兩種方式畫立方體
阿新 • • 發佈:2019-01-25
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);
}