Подтвердить что ты не робот

Android OpenGL ES 2, рисовые квадраты

РЕДАКТИРОВАТЬ: проблема решена! Поэтому я прошел официальные обучающие программы OpenGL ES 2 для Android, и я попал в ту часть, которая включает в себя рисование фигур, но я не могу заставить квадрат работать. Вместо этого он рисует правый треугольник.

Я включил код, который я использую, чтобы определить и нарисовать фигуру, которая копируется почти точно из учебника. Класс Renderer просто создает экземпляр этой формы и вызывает метод draw.

По какой-то причине в учебнике не приводятся значения /declare для вершинногоStride и vertexCount, поэтому те, которые у меня есть, являются образованными догадками. Я пробовал несколько значений для vertexCount (от 1 до 12), и никто не работает.

Спасибо заранее.

            public class Square {

                private FloatBuffer vertexBuffer;
                private ShortBuffer drawListBuffer;

                // number of coordinates per vertex in this array
                static final int COORDS_PER_VERTEX = 3;
                static float squareCoords[] = { -0.5f,  0.5f, 0.0f,   // top left
                                                -0.5f, -0.5f, 0.0f,   // bottom left
                                                 0.5f, -0.5f, 0.0f,   // bottom right
                                                 0.5f,  0.5f, 0.0f }; // top right

                private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices
                float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };


                private final String vertexShaderCode =
                        "attribute vec4 vPosition;" +
                        "void main() {" +
                        "  gl_Position = vPosition;" +
                        "}";

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

                int mProgram;

                static final int vertexStride = COORDS_PER_VERTEX * 4;
                static final int vertexCount = 4;

                public Square() {
                    // initialize vertex byte buffer for shape coordinates
                    ByteBuffer bb = ByteBuffer.allocateDirect(squareCoords.length * 4); // (# of coordinate values * 4 bytes per float)
                    bb.order(ByteOrder.nativeOrder());
                    vertexBuffer = bb.asFloatBuffer();
                    vertexBuffer.put(squareCoords);
                    vertexBuffer.position(0);

                    // initialize byte buffer for the draw list
                    ByteBuffer dlb = ByteBuffer.allocateDirect(drawOrder.length * 2); // (# of coordinate values * 2 bytes per short)
                    dlb.order(ByteOrder.nativeOrder());
                    drawListBuffer = dlb.asShortBuffer();
                    drawListBuffer.put(drawOrder);
                    drawListBuffer.position(0);


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

                    mProgram = GLES20.glCreateProgram();             // create empty OpenGL ES Program
                    GLES20.glAttachShader(mProgram, vertexShader);   // add the vertex shader to program
                    GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
                    GLES20.glLinkProgram(mProgram);                  // creates OpenGL ES program executables
                }

                public static int loadShader(int type, String shaderCode){

                    // create a vertex shader type (GLES20.GL_VERTEX_SHADER)
                    // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
                    int shader = GLES20.glCreateShader(type);

                    // add the source code to the shader and compile it
                    GLES20.glShaderSource(shader, shaderCode);
                    GLES20.glCompileShader(shader);

                    return shader;
                }

                public void draw() {
                    // Add program to OpenGL ES environment
                    GLES20.glUseProgram(mProgram);

                    // get handle to vertex shader vPosition member
                    int mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");

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

                    // Prepare the triangle coordinate data
                    GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
                                                 GLES20.GL_FLOAT, false,
                                                 vertexStride, vertexBuffer);

                    // get handle to fragment shader vColor member
                    int mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");

                    // Set color for drawing the triangle
                    GLES20.glUniform4fv(mColorHandle, 1, color, 0);

                    // Draw the triangle
                    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);

                    // Disable vertex array
                    GLES20.glDisableVertexAttribArray(mPositionHandle);
                }
            }
4b9b3361

Ответ 1

vertexCount = squareCoords.length/COORDS_PER_VERTEX; //Vertex count is the array divided by the size of the vertex ex. (x,y) or (x,y,z) 
vertexStride = COORDS_PER_VERTEX * 4;                //4 are how many bytes in a float

Сообщите мне, если это сработало для вас, удачи.

Я думаю, что у вас также отсутствует матрица ModelViewProjection, используемая для преобразования 3D-пространства в пространство 2D-экрана. mvpMatrix должен быть передан функцией draw draw(float[] mvpMatrix) Забыв упомянуть, вы также должны использовать DrawElements(...) (используется в примере), если вы не нуждаетесь в счетчике или шаге, просто длина массива idicies и буфер рисования.

    // Get handle to shape transformation matrix
    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");

    // Apply the projection and view transformation
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);

    // Draw the square
    GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length,
                          GLES20.GL_UNSIGNED_SHORT, drawListBuffer);

Ответ 2

В учебнике отсутствуют некоторые шаги: окончательный код для квадрата здесь.

В качестве примера использовался glDrawElements вместо glDrawArrays, который обозначается наличием строки: private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices.

Этот массив задает нужные вершины из двух треугольников. 0, 1 и 2 для первого. Тогда 0, 2 и 3 для второго. GL_TRANGLE_FAN просто работает, потому что он будет рисовать следующий треугольник, используя первую вершину в буфере, последнюю вершину, используемую в предыдущем треугольнике и следующую вершину. Для второго треугольника это 0, 2 и 3. Тогда 0, 3 и 4 и т.д. Если бы вершина 2 была 5, 5 и вершина 3 была -5, 5, то полученный вентилятор не был бы квадратом.

Заменить эти строки:

// Draw the triangle
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);

При этом:

// Draw the square
GLES20.glDrawElements(
    GLES20.GL_TRIANGLES, drawOrder.length,
    GLES20.GL_UNSIGNED_SHORT, drawListBuffer);