简体   繁体   中英

OpenGL ES: Rotating does not seem to take Z axis into consideration?

I'm trying to learn OpenGL ES as part of my foray into Android development.

So far, I've created the following Android application by cutting and pasting from various tutorials I found.

The application is supposed to create 2 coloured squares (1 red square and 1 blue square) and rotate them around a central point. So during part of the rotation, the red square should be in front while during another part of the rotation, the blue square should be in front.

When I run my application in the Android simulator however, it only shows the blue square in front.

Does anyone know what I'm missing?

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);
        }
    }
}

The reason you only see the blue one in front is because something is going wrong with the depth testing, and the blue one is simply drawn last (over everything else).

Where you say

gl.glClearDepthf(GL10.GL_DEPTH_TEST);      // enable depth testing 

you probably mean

gl.glEnable(GL10.GL_DEPTH_TEST);

and possibly

gl.glClearDepthf(1.0f);

but that's the default anyway.

Cheers, Aert.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM