LINUX.ORG.RU

Opengl ES

 , , ,


0

1

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

 package ru.sedano.opengl;

import android.opengl.GLES20;
import android.util.Log;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.Random;

/**
 * Created by oxid on 03.01.16.
 */
public class Serpinsky {
    private FloatBuffer vertexBuffer;
    private int mProgram;
    final Random random = new Random();

    private final String vertexShaderCode =
            "attribute vec3 vPosition; // The position variable has attribute position 0\n" +
                    "\n" + "\n" +
                    "void main()\n" +
                    "{\n" +
                    "    gl_Position = vec4(vPosition, 1.0);\n" +
                    "} ";

    private final String fragmentShaderCode =
            "precision mediump float;\n" +
                    "void main()\n" +
                    "{\n" +
                    "gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"+
                    "}\n";

    public Serpinsky() {
        int numPoints = 5000;

        ByteBuffer bb = ByteBuffer.allocateDirect(
                // (number of coordinate values * 4 bytes per float)
                numPoints * 3 * 4);

        // use the device hardware's native byte order
        bb.order(ByteOrder.nativeOrder());

        // create a floating point buffer from the ByteBuffer
        vertexBuffer = bb.asFloatBuffer();

        // A triangle in the plane z= 0

        Vector3f vertices[] = new Vector3f[] {

                new Vector3f(-1.0f, -1.0f, 0.0f),
                new Vector3f(0.0f, 1.0f, 0.0f),
                new Vector3f(1.0f, -1.0f, 0.0f)
        };

        Vector3f prev;
        // An arbitrary initial point inside the triangle
        prev = new Vector3f(0.25f, 0.5f, 0.0f);

        vertexBuffer.put(prev.x());
        vertexBuffer.put(prev.y());
        vertexBuffer.put(prev.z());

        // compute and store NumPoints-1 new points
        for (int k = 1; k < numPoints; k++) {
            int j = random.nextInt(3); // pick a vertex at random
            // Compute the point halfway between selected
            // vertex and previous point
            Vector3f current = (prev.plus(vertices[j])).divide(2.0f);

            Log.v("SERP", "x="+current.x()+" y="+current.y()+" z="+current.z());

            vertexBuffer.put(current.x());
            vertexBuffer.put(current.y());
            vertexBuffer.put(current.z());

            prev = current;
        }

        int vertexShader = MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER,
                vertexShaderCode);

        int fragmentShader = MyGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,
                fragmentShaderCode);

        // create empty OpenGL ES Program
        mProgram = GLES20.glCreateProgram();

        // add the vertex shader to program
        GLES20.glAttachShader(mProgram, vertexShader);

        // add the fragment shader to program
        GLES20.glAttachShader(mProgram, fragmentShader);

        // Bind attributes
        GLES20.glBindAttribLocation(mProgram, 0, "vPosition");

        // creates OpenGL ES program executables
        GLES20.glLinkProgram(mProgram);

    }

    private int mPositionHandle;

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

        MyGLRenderer.checkGlError("glUseProgram");
        // get handle to vertex shader's vPosition member
        mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
        MyGLRenderer.checkGlError("glgetAttribLocation");

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

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

        // Draw the gasket
        GLES20.glDrawArrays(GLES20.GL_POINTS, 0, 5000);

        try {
            Thread.sleep(25);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

★★★★

Ответ на: комментарий от stevejobs

Там надо ещё классов добавить чтобы скомпилировать, могу выложить куда нибудь

OxiD ★★★★
() автор топика

Здесь может быть 100500 мест где возможный косяки.
1. не понятно скомпилился шейдер или нет. Есть ли там проверка что шейдер id не равен нулю?
2. VBO адрес массива в памяти, т.е. это либо int[], либо IntBuffer.
3. Ну или вообще не понимаю что делаешь с vertexBuffer... Да и зачем тебе сначала ByteBuffer?
4. GLES20.glEnableVertexAttribArray(mPositionHandle); - А вот это вообще что? :) Очень похоже как будто ты хотел активировать VAO, только причём тут ссылка на отрибут шейдера?
5. Проверка на ошибки делается не совсем так. Да и проверки эти нужно на подготовительной стадии проводить. пока грузятся шейдеры и программа. В цикле отрисовки это не нужно. После операции с видеокартой нужно проверить нет ли ошибки и если есть получить её текст. Только так. Вот пример:

LOG.debug("Linking program");
        gl.glLinkProgram(programId);

        LOG.debug("Checking for errors");
        int[] error = new int[1];
        gl.glGetProgramiv(programId, GL_LINK_STATUS, error, 0);
        if (GL_FALSE == error[0]) {
            LOG.debug("Linking Error!");
            String errorLog = ShaderUtil.getProgramInfoLog(gl, programId);

            int temp = programId;
            gl.glDeleteProgram(programId);
            gl.glDeleteShader(vertexShaderId);
            gl.glDeleteShader(fragmentShaderId);

            throw new GLException(String.format("Failed to link GLSL program with id : %s\n Error: %s", temp, errorLog));
        }
Код ShaderUtils гдето здесь: https://github.com/sgothel/jogl/blob/master/src/jogl/classes/com/jogamp/openg... 6. Не нужно стопать поток во время отрисовки. Для поддержания заданого FPS просто не вызывай лишний раз draw();
7. И самое главное - внимательно изучи материалы с этого ресурса, как минимум конкретно эту статью: http://learnopengl.com/#!Getting-started/Hello-Triangle.

ii8_ ★★★★
()
Последнее исправление: ii8_ (всего исправлений: 1)
Ответ на: комментарий от ii8_

Проблемы было две. Во первых я забыл сделать gl_PointSize = 2.0 в шейдере. Видимо там по умолчанию 0 или что-то маленькое.

Во вторых надо было сделать vertexBuffer.position(0) перед glVertexAttribPointer

Спасибо!

OxiD ★★★★
() автор топика
Ответ на: комментарий от ii8_

1. Добавил проверку, все ок. 2. Я пока только изучаю это все) 3. В ByteBuffer есть метод allocateDirect который выделяет память нативным способом. Потом FloatBuffer будет ссылаться на этот кусок памяти. С таким буфером потом работа идет быстрее, нет лишних копирований и преобразований. 6. Спасибо)

Спасибо огромное и с Новым Годом!!

OxiD ★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.