OpenGL ESでCube
そんなわけでOpenGL ESをPapervision3Dみたいに扱いたい計画の続き。Cubeを作ってみた。
ソース見てもらうとわかるけど非常にめんどくさいしごちゃごちゃだし。どうにかならないかな。
そんで陰面除去するときに、cheprogrammingを参考に、
gl.glEnable(GL10.GL_DEPTH_TEST);
//描画処理
gl.glDisable(GL10.GL_DEPTH_TEST);
ってやったんだけど起動直後に終了するエラーが。
結局
gl.glCullFace(GL10.GL_BACK);
gl.glEnable(GL10.GL_CULL_FACE);
で対応しました。なんでうまく行かなかったんだろう?
これでそろそろ3D使ったゲームも作れるか。
ソースを動かす場合、本体部分はPlaneのときとほぼ同じですが、「gl.glDisable(GL10.GL_CULL_FACE);」を削除し、
上で書いた「gl.glCullFace(GL10.GL_BACK);〜」の二行を入れてください。
以下動作画面とCubeの中身のソースだけ掲載します。
http://screencast.com/t/DxaIDf9GBFv
ソース
package net.swelt.android.opengltest; import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.util.Random; import javax.microedition.khronos.opengles.GL10; public class Cube extends DisplayObject3D { private IntBuffer mVertexBuffer; private IntBuffer mColorBuffer; private ByteBuffer mIndexBuffer; private int mWidth; private int mHeight; private int mDepth; private int x; private int y; private int z; public Cube(int width, int height, int depth, int segX, int segY, int segZ) { mWidth = width; mHeight = height; mDepth = depth; create(segX, segY, segZ); } protected void create(int segX, int segY, int segZ) { int size = (segX*segY+segX*segZ+segY*segZ) * 2 * 2; int size1 = ((segX+1)*(segY+1)+(segX+1)*(segZ+1)+(segY+1)*(segZ+1)) * 2; int[] vertices = new int[size1 * 3]; int[] colors = new int[size1 * 4]; byte[] indices = new byte[size * 3]; int[] widths = {mWidth, mWidth, mHeight, mHeight, mDepth, mDepth}; int[] heights = {mHeight, mHeight, mDepth, mDepth, mWidth, mWidth}; int[] depths = {mDepth, -mDepth, mWidth, -mWidth, mHeight, -mHeight}; int[] segmentsW = {segX, segX, segY, segY, segZ, segZ}; int[] segmentsH = {segY, segY, segZ, segZ, segX, segX}; int cntV = 0; int cntC = 0; int cntI = 0; for( int i = 0; i < 6; ++ i ) { int oneX = widths[i] >> 1; int oneY = heights[i] >> 1; int gridU = segmentsW[i]; int gridV = segmentsH[i]; int gridU1 = gridU + 1; int gridV1 = gridV + 1; int incU = widths[i] / gridU; int incV = heights[i] / gridV; //vertices for( int iu = 0; iu < gridU1; ++ iu ) { for( int iv = 0; iv < gridV1; ++ iv ) { if( i == 0 || i == 1 ) { vertices[cntV++] = iu * incU - oneX; vertices[cntV++] = iv * incV - oneY; vertices[cntV++] = depths[i] / 2; } else if( i == 2 || i == 3 ) { vertices[cntV++] = depths[i] / 2; vertices[cntV++] = iu * incU - oneX; vertices[cntV++] = iv * incV - oneY; } else if( i == 4 || i == 5 ) { vertices[cntV++] = iv * incV - oneY; vertices[cntV++] = depths[i] / 2; vertices[cntV++] = iu * incU - oneX; } } } //faces int n = gridU1 * gridV1 * i; for( int iu = 0; iu < gridU; ++ iu ) { for( int iv = 0; iv < gridV; ++ iv ) { if( depths[i] > 0 ) { //Triangle A indices[cntI++] = (byte)(iu * gridV1 + iv + n); indices[cntI++] = (byte)(iu * gridV1 + (iv+1) + n); indices[cntI++] = (byte)((iu+1) * gridV1 + iv + n); //Triangle B indices[cntI++] = (byte)((iu+1) * gridV1 + (iv+1) + n); indices[cntI++] = (byte)((iu+1) * gridV1 + iv + n); indices[cntI++] = (byte)(iu * gridV1 + (iv+1) + n); } else { //Triangle A indices[cntI++] = (byte)(iu * gridV1 + iv + n); indices[cntI++] = (byte)((iu+1) * gridV1 + iv + n); indices[cntI++] = (byte)(iu * gridV1 + (iv+1) + n); //Triangle B indices[cntI++] = (byte)((iu+1) * gridV1 + (iv+1) + n); indices[cntI++] = (byte)(iu * gridV1 + (iv+1) + n); indices[cntI++] = (byte)((iu+1) * gridV1 + iv + n); } } } //colors Random rand = new Random(); for( int ic = 0; ic < gridU1 * gridV1; ++ ic ) { colors[cntC++] = rand.nextInt(); colors[cntC++] = rand.nextInt(); colors[cntC++] = rand.nextInt(); colors[cntC++] = 0x10000; } } mVertexBuffer = createIntBuffer(vertices); mColorBuffer = createIntBuffer(colors); mIndexBuffer = createByteBuffer(indices); } public void setX(int x) { int d = x - this.x; this.x = x; for( int i = 0; i < mVertexBuffer.capacity(); i += 3 ) { mVertexBuffer.put(i, mVertexBuffer.get(i) + d); } } public void setY(int y) { int d = y - this.y; this.y = y; for( int i = 1; i < mVertexBuffer.capacity(); i += 3 ) { mVertexBuffer.put(i, mVertexBuffer.get(i) +d ); } } public void setZ(int z) { int d = z - this.z; this.z = z; for( int i = 2; i < mVertexBuffer.capacity(); i += 3 ) { mVertexBuffer.put(i, mVertexBuffer.get(i) + d); } } public void draw(GL10 gl) { gl.glFrontFace(GL10.GL_CW); gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer); gl.glColorPointer(4, GL10.GL_FIXED, 0, mColorBuffer); gl.glDrawElements(GL10.GL_TRIANGLES, mIndexBuffer.capacity(), GL10.GL_UNSIGNED_BYTE, mIndexBuffer); } }