简体   繁体   English

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

[英]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. 我正在尝试学习OpenGL ES,这是我进军Android开发的一部分。

So far, I've created the following Android application by cutting and pasting from various tutorials I found. 到目前为止,我已经通过剪切和粘贴我发现的各种教程创建了以下Android应用程序。

The application is supposed to create 2 coloured squares (1 red square and 1 blue square) and rotate them around a central point. 该应用程序应该创建2个彩色正方形(1个红色正方形和1个蓝色正方形)并围绕中心点旋转它们。 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. 但是,当我在Android模拟器中运行应用程序时,它仅在前面显示蓝色方块。

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. 干杯,Aert。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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