Creating 3D cube using Android OpenGL ES 2.0

sebap123

I wanted to make 3D cube on my sceen. Unfortunately after combining some code from various sites I am still unable to make cube.

Can someone take a look at my code and advice what am I doing wrong? My idea is to make each face of a cube in different color and everything centered on the screen.

import android.opengl.GLES20;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.opengles.GL10;

public class Cube {
    private FloatBuffer vertexBuffer;  // Buffer for vertex-array
    private ShortBuffer indexBuffer;
    private int numFaces = 6;
    private int colorHandle;
    private final String vertexShaderCode =
            "uniform mat4 uMVPMatrix;" +
                    "attribute vec4 vPosition;" +
                    "void main() {" +
                    "  gl_Position = uMVPMatrix * vPosition;" +
                    "}";

    private final String fragmentShaderCode =
            "precision mediump float;" +
                    "uniform vec4 vColor;" +
                    "void main() {" +
                    "  gl_FragColor = vColor;" +
                    "}";
    private int MVPMatrixHandle;
    private int positionHandle;
    private final int program;

    static final int COORDS_PER_VERTEX = 3;
    private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex

    private float[][] colors = {  // Colors of the 6 faces
            {1.0f, 0.5f, 0.0f, 1.0f},  // 0. orange
            {1.0f, 0.0f, 1.0f, 1.0f},  // 1. violet
            {0.0f, 1.0f, 0.0f, 1.0f},  // 2. green
            {0.0f, 0.0f, 1.0f, 1.0f},  // 3. blue
            {1.0f, 0.0f, 0.0f, 1.0f},  // 4. red
            {1.0f, 1.0f, 0.0f, 1.0f}   // 5. yellow
    };

    private float[] vertices = {  // Vertices of the 6 faces
            // FRONT
            -1.0f, -1.0f,  1.0f,  // 0. left-bottom-front
            1.0f, -1.0f,  1.0f,  // 1. right-bottom-front
            -1.0f,  1.0f,  1.0f,  // 2. left-top-front
            1.0f,  1.0f,  1.0f,  // 3. right-top-front
            // BACK
            1.0f, -1.0f, -1.0f,  // 6. right-bottom-back
            -1.0f, -1.0f, -1.0f,  // 4. left-bottom-back
            1.0f,  1.0f, -1.0f,  // 7. right-top-back
            -1.0f,  1.0f, -1.0f,  // 5. left-top-back
            // LEFT
            -1.0f, -1.0f, -1.0f,  // 4. left-bottom-back
            -1.0f, -1.0f,  1.0f,  // 0. left-bottom-front 
            -1.0f,  1.0f, -1.0f,  // 5. left-top-back
            -1.0f,  1.0f,  1.0f,  // 2. left-top-front
            // RIGHT
            1.0f, -1.0f,  1.0f,  // 1. right-bottom-front
            1.0f, -1.0f, -1.0f,  // 6. right-bottom-back
            1.0f,  1.0f,  1.0f,  // 3. right-top-front
            1.0f,  1.0f, -1.0f,  // 7. right-top-back
            // TOP
            -1.0f,  1.0f,  1.0f,  // 2. left-top-front
            1.0f,  1.0f,  1.0f,  // 3. right-top-front
            -1.0f,  1.0f, -1.0f,  // 5. left-top-back
            1.0f,  1.0f, -1.0f,  // 7. right-top-back
            // BOTTOM
            -1.0f, -1.0f, -1.0f,  // 4. left-bottom-back
            1.0f, -1.0f, -1.0f,  // 6. right-bottom-back
            -1.0f, -1.0f,  1.0f,  // 0. left-bottom-front
            1.0f, -1.0f,  1.0f   // 1. right-bottom-front
    };

    short[] indeces = {
            0, 1, 3, 1, 2, 3,
            4, 5, 7, 5, 6, 7,
            8, 9, 11, 9, 10, 11,
            12, 13, 15, 13, 14, 15,
            16, 17, 19, 17, 18, 19,
            20, 21, 23, 21, 22, 23,

    };

    // Constructor - Set up the buffers
    public Cube() {
        // Setup vertex-array buffer. Vertices in float. An float has 4 bytes
        ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
        vbb.order(ByteOrder.nativeOrder()); // Use native byte order
        vertexBuffer = vbb.asFloatBuffer(); // Convert from byte to float
        vertexBuffer.put(vertices);         // Copy data into buffer
        vertexBuffer.position(0);           // Rewind

        indexBuffer = ByteBuffer.allocateDirect(indeces.length * 2).order(ByteOrder.nativeOrder()).asShortBuffer();
        indexBuffer.put(indeces).position(0);

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

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

    // Draw the shape
    public void draw(float[] mvpMatrix) {
        GLES20.glUseProgram(program);

        positionHandle = GLES20.glGetAttribLocation(program, "vPosition");
        GLES20.glEnableVertexAttribArray(positionHandle);
        GLES20.glVertexAttribPointer(positionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);

        MVPMatrixHandle = GLES20.glGetUniformLocation(program, "uMVPMatrix");
        GLES20.glUniformMatrix4fv(MVPMatrixHandle, 1, false, mvpMatrix, 0);
        // Render all the faces
        for (int face = 0; face < numFaces; face++) {
            // Set the color for each of the faces
            colorHandle = GLES20.glGetUniformLocation(program, "vColor");
            GLES20.glUniform4fv(colorHandle, 1, colors[face], 0);
        }

        GLES20.glDrawElements(GLES20.GL_TRIANGLES, 36, GLES20.GL_UNSIGNED_SHORT, indexBuffer);

        GLES20.glDisableVertexAttribArray(positionHandle);
    }
}

Currently I am receiving such outcome:

enter image description here

Reto Koradi

Your indices simply do not match your vertices. Let's just look at the first face. The coordinates of the first 4 vertices are:

-1.0f, -1.0f,  1.0f,
 1.0f, -1.0f,  1.0f,
-1.0f,  1.0f,  1.0f,
 1.0f,  1.0f,  1.0f,

Drawing a sketch of this in the x/y plane, with the indices indicated:

2---3
|   |
|   |
|   |
0---1

The entries in the index array for the first face are:

0, 1, 3, 1, 2, 3,

Mapping that into the previous figure, these indices define the following two triangles:

    3    2---3
   /|     \  |
  / |      \ |
 /  |       \|
0---1        1

As you can tell, the two triangles overlap, and do not cover the entire quad. What you need is the following:

2---3
|\  |
| \ |
|  \|
0---1

So one correct index sequence for this face is:

0, 1, 2, 2, 1, 3,

The first 3 and second 3 indices now match the two triangles. Also note that both of them are enumerated in counter-clockwise direction, which becomes important if you ever enable backface culling. You will need to fix the index sequence in the same way for all other faces.

There's a secondary problem in your code that will prevent the colors from working once you have the indices sorted out:

for (int face = 0; face < numFaces; face++) {
    // Set the color for each of the faces
    colorHandle = GLES20.glGetUniformLocation(program, "vColor");
    GLES20.glUniform4fv(colorHandle, 1, colors[face], 0);
}

Since you're not drawing anything after setting each uniform value, having a loop here is not useful. At the end, the last value will be set for the color, and the other colors are not used for anything.

To get this working, you will either have to draw only one face (6 indices) at a time, inside this loop. Or you have to introduce a vertex attribute for the colors just like the one you use for the positions.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Drawing cube 3D using Opengl

From Dev

Android - How to renderer video texture on 3D cube with opengl-es?

From Dev

Cube not drawn in OpenGL ES 3.0 on android

From Dev

Render to cube map on iPhone using OpenGL ES

From Dev

OpenGL cube using a for loop

From Dev

How to Load a 3D Object in OpenGL ES 2.0 for Android?

From Dev

Android OpenGL ES 2.0 - Cannot see 3D Obect

From Dev

Labeling parts of 3D model with Android and OpenGL ES/Rajawali

From Dev

Android OpenGL ES 2. 0 VBO Not Rendering

From Dev

Only 1 opengl 3d cube is displaying

From Dev

Black Alpha in Textures on Android When Using OpenGL ES 2

From Dev

Displaying fixed location 2D text in a 3D OpenGL world using GLUT

From Dev

Using gluUnProject to map touches to x,y cords on z=0 plane in Android OpenGL ES 2.0

From Dev

rotate a 3d cube along finger android

From Dev

rotate a 3d cube along finger android

From Dev

Creating a 3D array using elements (excluding the first one) in a 2D array

From Dev

Dynamically creating a 3D object in Android

From Dev

OpenGL ES 2 on Android: how to use VBOs

From Dev

Multiple OpenGL ES 2 Android Renders

From Dev

Android OpenGL ES 2 Texture Quadrants Rotated

From Dev

Vertices in OpenGL es 2. Java for Android

From Dev

OpenGL ES 2 on Android: how to use VBOs

From Dev

Creating A Cube Using Only CSS Gradients

From Dev

Creating A Cube Using Only CSS Gradients

From Dev

OpenGL ES - set the width, height, depth of an object in 3D

From Dev

Colouring and texturing 3d shapes with OpenGL ES

From Dev

How to create a VAO in openGL ES 3 android

From Dev

Arches (2D or 3D) in OpenGL

From Dev

Draw 2D and 3D in the same OpenGL window

Related Related

HotTag

Archive