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 ★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.