OpenGL ES:旋转似乎不考虑Z轴?

时间:2011-06-23 03:06:38

标签: java android opengl-es

我正在尝试学习OpenGL ES,这是我进军Android开发的一部分。

到目前为止,我已经通过剪切和粘贴我发现的各种教程创建了以下Android应用程序。

该应用程序应该创建2个彩色方块(1个红色方块和1个蓝色方块)并围绕中心点旋转它们。 因此,在旋转的一部分中,红色方块应位于前方,而在旋转的另一部分中,蓝色方块应位于前方。

但是,当我在Android模拟器中运行我的应用程序时,它只显示前面的蓝色方块。

有谁知道我错过了什么?

package hello.world;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.app.Activity;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.os.Bundle;

public class HelloActivity extends Activity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new HelloView(this));
    }

    private class HelloView extends GLSurfaceView {

        private HelloRenderer renderer;

        public HelloView(Context context) {
            super(context);
            renderer = new HelloRenderer(context);
            setRenderer(renderer);
        }        
    }

    private class HelloRenderer implements GLSurfaceView.Renderer {

        public float xrot;             //X Rotation ( NEW )
        public float yrot;             //Y Rotation ( NEW )
        public float zrot;             //Z Rotation ( NEW )

        private List<ColoredQuad> quads;

        public HelloRenderer(Context context) {
            quads = new ArrayList<ColoredQuad>();

            quads.add(new ColoredQuad(
                new Vertex3D(-1.0f, -1.0f, 1.0f),
                new Vertex3D(1.0f, -1.0f, 1.0f),
                new Vertex3D(-1.0f, 1.0f, 1.0f),
                new Vertex3D(1.0f, 1.0f, 1.0f),
                new RGBA(1.0f, 0.0f, 0.0f)));

            quads.add(new ColoredQuad(
                new Vertex3D(-1.0f, -1.0f, -1.0f),
                new Vertex3D(1.0f, -1.0f, -1.0f),
                new Vertex3D(-1.0f, 1.0f, -1.0f),
                new Vertex3D(1.0f, 1.0f, -1.0f),
                new RGBA(0.0f, 0.0f, 1.0f)));
        }

        /**
         * Called whenever drawing is needed.
         */
        public void onDrawFrame(GL10 gl) {
            // clear screen and depth buffer
            gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
            gl.glLoadIdentity();

              //Drawing
            gl.glTranslatef(0.0f, 0.0f, -5.0f);     //move 5 units into the screen
            gl.glScalef(0.5f, 0.5f, 0.5f);          //scale the objects to 50 percent of original size

            //Rotate around the axis based on the rotation matrix (rotation, x, y, z)
            gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f);   //X
            gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f);   //Y
            gl.glRotatef(zrot, 0.0f, 0.0f, 1.0f);   //Z

            for (ColoredQuad quad : quads) {
                quad.draw(gl);
            }

            //Change rotation factors (nice rotation)
            xrot += 3.0f;
            yrot += 2.0f;
            zrot += 1.0f;
        }

        /**
         * Called when the surface has changed.
         * For example, when switching from portrait to landscape view.
         */ 
        public void onSurfaceChanged(GL10 gl, int width, int height) {
            gl.glViewport(0, 0, width, height);
        }

        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            gl.glEnable(GL10.GL_SMOOTH);               // enable smooth shading
            gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);   // black background
            gl.glClearDepthf(GL10.GL_DEPTH_TEST);      // enable depth testing
            gl.glDepthFunc(GL10.GL_LEQUAL);            // type of depth testing to do

            //Really Nice Perspective Calculations
            gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); 
        }
    }

    private class Vertex3D {
        public float x;
        public float y;
        public float z;

        public Vertex3D(float x, float y, float z) {
            this.x = x;
            this.y = y;
            this.z = z;
        }
    }

    public class RGBA {
        public float red;
        public float blue;
        public float green;
        public float alpha;

        public RGBA(float red, float green, float blue) {
            this.red   = red;
            this.blue  = blue;
            this.green = green;
            this.alpha = 1.0f;
        }
    }

    private ByteBuffer makeByteBuffer(byte[] array)
    {
        ByteBuffer bb = ByteBuffer.allocateDirect(array.length);
        bb.put(array);
        bb.position(0);

        return bb;
    }

    private FloatBuffer makeFloatBuffer(float[] array)
    {
        ByteBuffer bb = ByteBuffer.allocateDirect(array.length * 4);
        bb.order(ByteOrder.nativeOrder());
        FloatBuffer fb = bb.asFloatBuffer();
        fb.put(array);
        fb.position(0);

        return fb;
    }

    private class ColoredQuad {
        private FloatBuffer vertexBuffer;
        private FloatBuffer colorBuffer;
        private ByteBuffer  indexBuffer;

        private float[] vertices = new float[12]; // 4 vertices * XYZ (12)

        private float[] colors = new float[16];   // 4 vertices * RGBA (16)

        private byte[] indices = {
             0, 1, 2, 1, 2, 3
        };

        public ColoredQuad(Vertex3D bottomLeft, Vertex3D bottomRight, Vertex3D topLeft, Vertex3D topRight, RGBA color) {
            vertices[0] = bottomLeft.x; vertices[1] = bottomLeft.y; vertices[2] = bottomLeft.z;
            vertices[3] = bottomRight.x; vertices[4] = bottomRight.y; vertices[5] = bottomRight.z;
            vertices[6] = topLeft.x; vertices[7] = topLeft.y; vertices[8] = topLeft.z;
            vertices[9] = topRight.x; vertices[10]= topRight.y; vertices[11]= topRight.z;

            colors[0] = color.red; colors[1] = color.green; colors[2] = color.blue; colors[3] = color.alpha;
            colors[4] = color.red; colors[5] = color.green; colors[6] = color.blue; colors[7] = color.alpha;
            colors[8] = color.red; colors[9] = color.green; colors[10]= color.blue; colors[11]= color.alpha;
            colors[12]= color.red; colors[13]= color.green; colors[14]= color.blue; colors[15]= color.alpha;

            vertexBuffer = makeFloatBuffer(vertices);
            colorBuffer  = makeFloatBuffer(colors);            
            indexBuffer  = makeByteBuffer(indices);
        }

        public void draw(GL10 gl) {

            //Point to our buffers
            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
            gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

            //Set the face rotation
            gl.glFrontFace(GL10.GL_CCW);

            //Enable the vertex and texture state
            gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
            gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);

            //Draw the vertices as triangles, based on the Index Buffer information
            gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_BYTE, indexBuffer);

            //Disable the client state before leaving
            gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
            gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        }
    }
}

1 个答案:

答案 0 :(得分:1)

你只看到前面的蓝色的原因是因为深度测试出了问题,而蓝色的那个只是最后绘制(超过其他所有)。

你说的地方

gl.glClearDepthf(GL10.GL_DEPTH_TEST);      // enable depth testing 
你可能意味着

gl.glEnable(GL10.GL_DEPTH_TEST);

可能

gl.glClearDepthf(1.0f);

但无论如何这都是默认值。

干杯,阿尔特。