2015-05-12 2 views
1

Я хотел сделать 3D-куб на моем sceen. К сожалению, после объединения кода с разных сайтов я все еще не могу сделать куб.Создание 3D-куба с использованием Android OpenGL ES 2.0

Может кто-нибудь взглянуть на мой код и совет, что я делаю неправильно? Моя идея состоит в том, чтобы сделать каждую грань куба разного цвета, и все сосредоточено на экране.

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

В настоящее время я получаю такой результат:

enter image description here

ответ

8

Ваши показатели просто не совпадают с вашими вершинами. Давайте просто посмотрим на первое лицо. Координаты первых 4 вершин:

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

Составление эскиза этого в х/у плоскости, причем индексы показали:

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

Записи в массиве индекса для первого лица являются:

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

Mapping, что в предыдущем рисунке, эти показатели определяют следующие два треугольника:

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

Как вы можете сказать, два треугольника перекрываются и не покрывают весь квад. Что вам нужно следующее:

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

Так одна правильная последовательность индекса для этой грани:

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

Первые 3 и вторые 3 индексы теперь соответствуют два треугольника. Также обратите внимание, что оба они перечислены в направлении против часовой стрелки, что становится важным, если вы когда-либо позволяете отбрасывать обратную сторону. Вам нужно будет исправить последовательность индексов таким же образом для всех других лиц.

Там есть вторичная проблема в вашем коде, что позволит предотвратить цвета от работы, как только вы индексы выясняли:

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

Так как вы ничего не рисовать после установки каждого однородного значения, имеющая петлю здесь не является полезным. В конце, последнее значение будет установлено для цвета, а другие цвета не будут использоваться ни для чего.

Чтобы получить эту работу, вам придется либо рисовать только одну грань (6 индексов) за один раз внутри этого цикла. Или вы должны ввести атрибут вершины для цветов, как тот, который вы используете для позиций.

+0

Спасибо. Теперь работает. – sebap123

0

Правильно будет:

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, // 2. left-top-front 
     1.0f, -1.0f, 1.0f, // 1. right-bottom-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, // 7. right-top-back 
     -1.0f, -1.0f, -1.0f, // 4. left-bottom-back 
     -1.0f, -1.0f, -1.0f, // 4. left-bottom-back 
     -1.0f, 1.0f, -1.0f, // 5. left-top-back 
     1.0f, 1.0f, -1.0f, // 7. right-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, // 2. left-top-front 
     -1.0f, 1.0f, 1.0f, // 2. left-top-front 
     -1.0f, 1.0f, -1.0f, // 5. left-top-back 
     -1.0f, -1.0f, -1.0f, // 4. left-bottom-back 
     // 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, // 7. right-top-back 
     1.0f, 1.0f, -1.0f, // 7. right-top-back 
     1.0f, 1.0f, 1.0f, // 3. right-top-front 
     1.0f, -1.0f, 1.0f, // 1. right-bottom-front 
     // 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, // 7. right-top-back 
     1.0f, 1.0f, -1.0f, // 7. right-top-back 
     -1.0f, 1.0f, -1.0f, // 5. left-top-back 
     -1.0f, 1.0f, 1.0f, // 2. left-top-front 
     // 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, // 1. right-bottom-front 
     1.0f, -1.0f, 1.0f, // 1. right-bottom-front 
     -1.0f, -1.0f, 1.0f, // 0. left-bottom-front 
     -1.0f, -1.0f, -1.0f // 4. left-bottom-back 
}; 
Смежные вопросы