如何使用drawElements和索引数组使用OpenGL ES渲染四边形?

时间:2017-10-31 10:58:49

标签: java android opengl-es

我目前正在学习Android开发来编写基于磁贴的游戏,但我无法使OpenGLES正常工作。

所以我试图使用索引数组渲染四边形,但它只渲染四边形的第一个三角形而第二个缺失,所以我假设OpenGL没有得到某种方式我的索引阵列。或者也许我没有正确生成我的ibo,我不知道...... 以下是我认为问题可能存在的一些代码。如果您需要更多代码,请询问:

我的类渲染一个简单的四边形graphics.ModelSquare

package com.gametheque.mobilegameengine.graphics;

import android.opengl.GLES20;
import android.opengl.Matrix;
import com.gametheque.mobilegameengine.util.Color;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

public class ModelSquare extends Model {

    private float vertexArray[] = {
            0.0f,  1.0f, 0.0f,   // top left
            0.0f, 0.0f, 0.0f,   // bottom left
            1.0f, 0.0f, 0.0f,   // bottom right
            1.0f,  0.0f, 0.0f }; // top right
    private short indicesArray[] = { 0, 1, 2, 0, 2, 3 };

    private FloatBuffer vertexBuffer;
    private ShortBuffer indicesBuffer;
    private int indicesID[] = new int[1];
    private int verticesID[] = new int[1];

    float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };

    float[] modelViewMatrix = new float[16];

    public ModelSquare(){
        vertexBuffer = Util.loadFloatBuffer(vertexArray);
        indicesBuffer = Util.loadShortBuffer(indicesArray);
        Util.loadVBO(indicesID, indicesBuffer);
        Util.loadVBO(verticesID, vertexBuffer);
    }

    public void draw(ShaderProgram shader, float[] projectionMatrix, float[] viewMatrix, float[] modelMatrix, int hexcolor) {
        // Add program to OpenGL environment
        GLES20.glUseProgram(shader.getProgramID());

        // Enable a handle to the triangle vertices
        GLES20.glEnableVertexAttribArray(shader.getAttrib_location_vertices());

        // Prepare the triangle coordinate data
        GLES20.glVertexAttribPointer(
                shader.getAttrib_location_vertices(), COORDS_PER_VERTEX,
                GLES20.GL_FLOAT, false,
                COORDS_PER_VERTEX * 4, vertexBuffer);

        // Set color for drawing the triangle
        color[0] = Color.colorFromHex(hexcolor, 'r')/255;
        color[1] = Color.colorFromHex(hexcolor, 'g')/255;
        color[2] = Color.colorFromHex(hexcolor, 'b')/255;
        GLES20.glUniform4fv(shader.getUniform_location_color(), 1, color, 0);

        // Apply the projection and view transformation
        Matrix.multiplyMM(modelViewMatrix, 0, viewMatrix, 0, modelMatrix, 0);
        GLES20.glUniformMatrix4fv(shader.getUniform_location_projectionMatrix(), 1, false, projectionMatrix, 0);
        GLES20.glUniformMatrix4fv(shader.getUniform_location_ModelViewMatrix(), 1, false, modelViewMatrix, 0);

        // Draw the square
        GLES20.glDrawElements(GLES20.GL_TRIANGLES, indicesArray.length, GLES20.GL_UNSIGNED_SHORT, indicesBuffer);

        // Disable vertex array
        GLES20.glDisableVertexAttribArray(shader.getAttrib_location_vertices());
    }

}

我的班级创建了ibo graphics.Util

package com.gametheque.mobilegameengine.graphics;

import android.opengl.GLES20;

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

public class Util {

    public static FloatBuffer loadFloatBuffer(float[] array) {
        FloatBuffer floatBuffer;
        // initialize vertex byte buffer for shape coordinates
        ByteBuffer bb = ByteBuffer.allocateDirect(
                // (number of coordinate values * 4 bytes per float)
                array.length * 4);
        // use the device hardware's native byte order
        bb.order(ByteOrder.nativeOrder());

        // create a floating point buffer from the ByteBuffer
        floatBuffer = bb.asFloatBuffer();
        // add the coordinates to the FloatBuffer
        floatBuffer.put(array);
        // set the buffer to read the first coordinate
        floatBuffer.position(0);

        return floatBuffer;
    }

    public static ShortBuffer loadShortBuffer(short[] array) {
        ShortBuffer shortBuffer = ByteBuffer.allocateDirect(array.length * 2).order(ByteOrder.nativeOrder()).asShortBuffer();
        shortBuffer.put(array).position(0);
        return shortBuffer;
    }

    public static void loadVBO(int[] iboID, ShortBuffer buffer){

        int m_tailleBytes = buffer.limit() * 2;

        // Génération de l'ID
        GLES20.glGenBuffers(1, iboID, 0);

        // Verrouillage du VBO
        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, iboID[0]);

        // Allocation de la mémoire
        GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, m_tailleBytes, buffer, GLES20.GL_STATIC_DRAW);

        // Déverrouillage de l'objet
        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
    }

    public static void loadVBO(int[] vboID, FloatBuffer buffer){

        int m_tailleBytes = buffer.limit() * 4;

        // Génération de l'ID
        GLES20.glGenBuffers(1, vboID, 0);

        // Verrouillage du VBO
        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboID[0]);

        // Allocation de la mémoire
        GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, m_tailleBytes, buffer, GLES20.GL_STATIC_DRAW);

        // Déverrouillage de l'objet
        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
    }

}

以下是截图:

screenshot

1 个答案:

答案 0 :(得分:1)

我注意到最后一个顶点的坐标错误

 private float vertexArray[] = {
            0.0f,  1.0f, 0.0f,   // top left
            0.0f, 0.0f, 0.0f,   // bottom left
            1.0f, 0.0f, 0.0f,   // bottom right
            1.0f,  0.0f, 0.0f }; // top right  << Here

应该是

  1.0f,  1.0f, 0.0f }; // top right

所以对于你来说,你的第二个三角形会降级。