2013-02-08 91 views
0

我正在嘗試使用OpenGL ES2繪製3D立方體,並且我的代碼僅繪製了此立方體的正面(正方形),如此image中所示。我無法弄清楚什麼是錯的。我也嘗試過基於其他教程實現我的多維數據集,但沒有運氣。Android Opengl:只顯示我3D立方體的正面

我的代碼有什麼問題?我錯過了重要的代碼行嗎?

@Override 
public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
    // TODO Auto-generated method stub 
    GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); 

    GLES20.glEnable(GLES20.GL_DEPTH_TEST); 
    GLES20.glDepthFunc(GLES20.GL_LEQUAL); 


    GLES20.glFrontFace(GLES20.GL_CCW); 
    GLES20.glCullFace(GLES20.GL_BACK); 
    GLES20.glEnable(GLES20.GL_CULL_FACE); 


    Matrix.setLookAtM(mVMatrix,0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ); 
} 

並條機方法

@Override 
public void onDrawFrame(GL10 gl) { 
    // TODO Auto-generated method stub 
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT|GLES20.GL_DEPTH_BUFFER_BIT); 

    // Calculate the projection and view transformation 
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0); 

    //Calling draw method of shapes 
    square.draw(mMVPMatrix); 
} 

立方類

       // x, y, z 
static float squareCoords[] = {-1f, -1f, 1f,//Bottom Left 
           1f, -1f, 1f, //Bottom Right 
           1f, 1f, 1f, //Top Right 
           -1f, 1f, 1f, //Top left 

           -1f, -1f, -1f,//Bottom Left 
           1f, -1f, -1f, //Bottom Right 
           1f, 1f, -1f, //Top Right 
           -1f, 1f, -1f //Top left 
           }; 



private short drawOrder[] = {0,1,2, 0,2,3,//front 
          0,3,7, 0,7,4,//Left  
          0,1,5, 0,5,4,//Bottom 

          6,7,4, 6,4,5,//Back 
          6,7,3, 6,3,2,//top 
          6,2,1, 6,1,5//right 
}; //Order to draw vertices 



private int vertaxCount = 0; //Vertex count is the array divided by the size of the vertex ex. (x,y) or (x,y,z) 
private int vertaxStride = 0; //4 are how many bytes in a float 

private float [] color = new float[]{ 
    0.1f, 0.5f, 1.0f, 1.0f, 
    0.0f, 0.0f, 1.0f, 1.0f, 
    0.0f, 10.0f, 0.0f, 1.0f, 
    0.0f, 1.0f, 1.0f, 1.0f, 
    1.0f, 0.0f, 0.0f, 1.0f, 
    1.0f, 0.0f, 1.0f, 1.0f, 
    1.0f, 1.0f, 0.0f, 1.0f, 
    1.0f, 1.0f, 1.0f, 1.0f 
}; 

public Square() 
{ 
    //initialising vertex byte buffer for shape coordinates 
    // (number of coordinate values * 4 bytes per float) 
    ByteBuffer bb = ByteBuffer.allocateDirect(squareCoords.length * 4); 

    bb.order(ByteOrder.nativeOrder()); 

    vertexBuffer = bb.asFloatBuffer(); 
    vertexBuffer.put(squareCoords); 
    vertexBuffer.position(0); 


    //Initialise byte buffer for the draw list 
    //(number of draw values * 2 bytes per short) 
    ByteBuffer dlb = ByteBuffer.allocateDirect(drawOrder.length * 2); 

    dlb.order(ByteOrder.nativeOrder()); 
    drawListBuffer = dlb.asShortBuffer(); 
    drawListBuffer.put(drawOrder); 
    drawListBuffer.position(0); 


    ByteBuffer colors = ByteBuffer.allocateDirect(color.length * 4); 
    colors.order(ByteOrder.nativeOrder()); 
    bufferColor = colors.asFloatBuffer(); 
    bufferColor.put(color); 
    bufferColor.position(0); 



    int vertexShader = Shaders.loadShader(GLES20.GL_VERTEX_SHADER, Shaders.vertexShaderCode); 
    int fragmentShader = Shaders.loadShader(GLES20.GL_FRAGMENT_SHADER, Shaders.fragmentShaderCode); 

    mProg = GLES20.glCreateProgram(); 
    GLES20.glAttachShader(mProg, vertexShader); 
    GLES20.glAttachShader(mProg, fragmentShader); 
    GLES20.glLinkProgram(mProg); 

    vertaxCount = squareCoords.length/COORDS_PER_VERTEX; //Vertex count is the array divided by the size of the vertex ex. (x,y) or (x,y,z) 
    vertaxStride = COORDS_PER_VERTEX * 4; //4 are how many bytes in a float 


} 

public void draw(float[] mMVPMatrix) 
{ 
    //Add program to OpenGL environment 
    GLES20.glUseProgram(mProg); 

    //Get Handle to the vertices 
    int mPositionHandle = GLES20.glGetAttribLocation(mProg, "vPosition"); 



    //Prepare the shape coordinate data 
    GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, 
            GLES20.GL_FLOAT, false, 
            vertaxStride, vertexBuffer); 

    //Enable a handle to the shape vertices 
    GLES20.glEnableVertexAttribArray(mPositionHandle); 


    int mColorHandle = GLES20.glGetUniformLocation(mProg, "v_color"); 

    GLES20.glVertexAttribPointer(mColorHandle, 3, GLES20.GL_FLOAT, false, 0, bufferColor); 
    GLES20.glEnableVertexAttribArray(mColorHandle); 


    float [] tm = new float[16]; 
    float [] rm = new float[16]; 

    Matrix.scaleM(mMVPMatrix, 0, 0.35f, 0.35f, 0); 
    Matrix.translateM(tm, 0, mMVPMatrix, 0, 0f, 0f, 0); 
    Matrix.rotateM(rm, 0, tm, 0, 45f, 0, 0, 1); 

    // get handle to shape's transformation matrix 
    int mMVPMatrixHandle = GLES20.glGetUniformLocation(mProg, "u_MVPMatrix"); 

    // Apply the projection and view transformation 
    //GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0); 
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, rm, 0); 


    //Draw the shape 
    //GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, vertaxCount); 
    GLES20.glDrawElements(GLES20.GL_TRIANGLES, 36, GLES20.GL_UNSIGNED_SHORT, drawListBuffer); 

    //Disable vertex array 
    GLES20.glDisableVertexAttribArray(mPositionHandle); 

} 
+0

如果您只繪製1,2,3,... glDrawElements(...)中的前18個三角形,那麼該怎麼辦?我的意思是,它也可能表明你的z緩衝區正在工作。 – 2013-02-08 13:22:23

+0

是因爲你在看立方體頭部嗎?如果你旋轉立方體怎麼辦? – mbeckish 2013-02-08 14:04:17

+0

您的意思是將glDrawElements()方法中的值36更改爲18?...如果是這種情況,我確實將其更改爲18,但仍得到相同的結果 – drew 2013-02-08 14:04:33

回答

0
class Cube { 

private FloatBuffer mVertexBuffer; 
private FloatBuffer mColorBuffer; 
private ShortBuffer mIndexBuffer; 
private int mProgram, mPositionHandle, mColorHandle, mMVPMatrixHandle ; 

private final String vertexShaderCode = 
     "uniform mat4 uMVPMatrix;" + 
     "attribute vec4 vPosition;" + 
     "attribute vec4 aColor;" + 
     "varying vec4 vColor;" + 

     "void main() {" + 
     "vColor = aColor;" + 
     "gl_Position = vPosition * uMVPMatrix;" + 
     "}"; 

    private final String fragmentShaderCode = 
     "precision mediump float;" + 
     "varying vec4 vColor;" + 
     "void main() {" + 
     "gl_FragColor = vColor;" + // vec4(0.0, 1.0, 0.0, 1.0);" + 
     "}"; 

private float vertices[] = { 
     -0.5f, -0.5f, 0.5f,//Bottom Left 
     0.5f, -0.5f, 0.5f, //Bottom Right 
     0.5f, 0.5f, 0.5f, //Top Right 
     -0.5f, 0.5f, 0.5f, //Top left 

     -0.5f, -0.5f, -0.5f,//Bottom Left 
     0.5f, -0.5f, -0.5f, //Bottom Right 
     0.5f, 0.5f, -0.5f, //Top Right 
     -0.5f, 0.5f, -0.5f //Top left 
          }; 

private float colors[] = { 
          0.0f, 1.0f, 0.0f, 1.0f, 
          0.0f, 1.0f, 0.0f, 1.0f, 
          1.0f, 0.5f, 0.0f, 1.0f, 
          1.0f, 0.5f, 0.0f, 1.0f, 
          1.0f, 0.0f, 0.0f, 1.0f, 
          1.0f, 0.0f, 0.0f, 1.0f, 
          0.0f, 0.0f, 1.0f, 1.0f, 
          1.0f, 0.0f, 1.0f, 1.0f 
         }; 

private short indices[] = { 
     0,1,2, 0,2,3,//front 
     0,3,7, 0,7,4,//Left  
     0,1,5, 0,5,4,//Bottom 

     6,7,4, 6,4,5,//Back 
     6,7,3, 6,3,2,//top 
     6,2,1, 6,1,5//right 
          }; 

public Cube() { 

     ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4); 
     byteBuf.order(ByteOrder.nativeOrder()); 
     mVertexBuffer = byteBuf.asFloatBuffer(); 
     mVertexBuffer.put(vertices); 
     mVertexBuffer.position(0); 

     byteBuf = ByteBuffer.allocateDirect(colors.length * 4); 
     byteBuf.order(ByteOrder.nativeOrder()); 
     mColorBuffer = byteBuf.asFloatBuffer(); 
     mColorBuffer.put(colors); 
     mColorBuffer.position(0); 

     byteBuf = ByteBuffer.allocateDirect(indices.length * 4); 
     byteBuf.order(ByteOrder.nativeOrder()); 
     mIndexBuffer = byteBuf.asShortBuffer(); 
     mIndexBuffer.put(indices); 
     mIndexBuffer.position(0); 

     int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode); 
     int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode); 

     mProgram = GLES20.glCreateProgram();    // create empty OpenGL ES Program 
     GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program 
     GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program 
     GLES20.glLinkProgram(mProgram); 

} 


public static int loadShader(int type, String shaderCode){ 

    int shader = GLES20.glCreateShader(type); 
    GLES20.glShaderSource(shader, shaderCode); 
    GLES20.glCompileShader(shader); 
    return shader; 
} 

public void draw (float[] mvpMatrix){ 

    //GLES20.glFrontFace(GLES20.GL_CCW); 



    GLES20.glUseProgram(mProgram); 

    // get handle to vertex shader's vPosition member 
    mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition"); 

    // Enable a handle to the triangle vertices 
    GLES20.glEnableVertexAttribArray(mPositionHandle); 

    // Prepare the triangle coordinate data 
    GLES20.glVertexAttribPointer(mPositionHandle, 3, 
           GLES20.GL_FLOAT, false, 
           12, mVertexBuffer); 

    // get handle to fragment shader's vColor member 
    mColorHandle = GLES20.glGetAttribLocation(mProgram, "aColor"); 

    GLES20.glEnableVertexAttribArray(mColorHandle); 

    // Prepare the triangle coordinate data 
    GLES20.glVertexAttribPointer(mColorHandle, 4, 
           GLES20.GL_FLOAT, false, 
           0, mColorBuffer); 

    // Set color for drawing the triangle 
//  GLES20.glUniform2fv(mColorHandle, 1,colors, 0); 

    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); 

    // Apply the projection and view transformation 
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0); 



    // Draw the triangle 
    GLES20.glDrawElements(GLES20.GL_TRIANGLES, 36, GLES20.GL_UNSIGNED_SHORT, mIndexBuffer); 

    // Disable vertex array 
    GLES20.glDisableVertexAttribArray(mPositionHandle); 
    GLES20.glDisableVertexAttribArray(mColorHandle); 

} 

} 

public abstract class GLRenderer implements GLSurfaceView.Renderer { 

boolean mFirstDraw; 
boolean mSurfaceCreated; 
int mWidth; 
int mHeight; 
long mLastTime; 
int mFPS; 
float[] mProjMatrix = new float[16]; 
float[] mVMatrix = new float[16]; 
float[] mMVPMatrix = new float[16]; 
private float[] rotationMatrix = new float[16]; 
private float angle = 0f; 

GLRenderer() { 
    mFirstDraw = true; 
    mSurfaceCreated = false; 
    mWidth = -1; 
    mHeight = -1; 
    mLastTime = System.currentTimeMillis(); 
    mFPS = 0; 
} 

@Override 
public void onDrawFrame(GL10 arg0) { 
    // TODO Auto-generated method stub 
    Cube mCube = new Cube(); 
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT|GLES20.GL_DEPTH_BUFFER_BIT); 

    if (mFirstDraw) 
     mFirstDraw = false; 

    angle += 0.7f; 
    if (angle > 360f) 
     angle = 0f; 
    Matrix.setLookAtM(mVMatrix, 0, 0f, 0f, 4f, 0f, 0f, 0f, 0f, 1f, 0f); 
    // projection x view = modelView 
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0); 
    // Creating rotation matrix 
    Matrix.setRotateM(rotationMatrix, 0, angle, 0f, 0f, -1f); 

    // rotation x camera = modelView 
    float[] duplicateMatrix = Arrays.copyOf(mMVPMatrix, 16); 

    Matrix.multiplyMM(mMVPMatrix, 0, duplicateMatrix, 0, rotationMatrix, 0); 

    Matrix.setRotateM(rotationMatrix, 0, angle, 0f, -1f, 0f); 
    duplicateMatrix = Arrays.copyOf(mMVPMatrix, 16); 
    Matrix.multiplyMM(mMVPMatrix, 0, duplicateMatrix, 0, rotationMatrix, 0); 

    Matrix.setRotateM(rotationMatrix, 0, angle, -1f, 0f, 0f); 
    duplicateMatrix = Arrays.copyOf(mMVPMatrix, 16); 
    Matrix.multiplyMM(mMVPMatrix, 0, duplicateMatrix, 0, rotationMatrix, 0); 
    // rotation x camera = modelView 
    mCube.draw(mMVPMatrix); 




} 

@Override 
public void onSurfaceChanged(GL10 arg0, int arg1, int arg2) { 
    // TODO Auto-generated method stub 

    mWidth = arg1; 
    mHeight = arg2; 

    GLES20.glViewport(0, 0, mWidth, mHeight); 

    float ratio = (float) mWidth/mHeight; 

    // this projection matrix is applied to object coordinates 
    // in the onDrawFrame() method 
    Matrix.frustumM(mProjMatrix, 0, -1, 1, -1, 1, 3, 7); 

} 



@Override 
public void onSurfaceCreated(GL10 arg0, EGLConfig arg1) { 
    // TODO Auto-generated method stub 

    mSurfaceCreated = true; 
    mWidth = -1; 
    mHeight = -1; 
    GLES20.glClearColor(0f, 0f, 0f, 0f); 
    GLES20.glEnable(GLES20.GL_DEPTH_TEST); 
} 

} 

public class MainActivity extends Activity { 

GLSurfaceView glView; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN); 
    if(hasGL20()){ 
     glView = new GLSurfaceView(getApplicationContext()); 
     glView.setEGLContextClientVersion(2); 
     glView.setPreserveEGLContextOnPause(true); 
     glView.setRenderer(new GL20Renderer()); 

    }else{ 
     Log.v ("No Req Version",""); 
    } 

    setContentView(glView); 
} 

@Override 
protected void onPause() { 
    super.onPause(); 
    if(glView != null) 
     glView.onPause(); 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
    if(glView != null) 
     glView.onResume(); 

} 

private boolean hasGL20(){ 
    ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); 
    ConfigurationInfo info = am.getDeviceConfigurationInfo(); 
    return info.reqGlEsVersion >= 0x20000; 
} 


} 
0

這可能是因爲你的三角形是不是一致的方向的所有傷口。嘗試禁用背面剔除:

GLES20.glDisable(GLES20.GL_CULL_FACE); 

或者扭轉CullFace向前:

GLES20.glCullFace(GLES20.GL_FRONT); 

如果這個變化,這立方體的兩側被渲染,那麼你的三角形是不是一致的方向的所有傷口。