LINUX.ORG.RU

# Opengl ES

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

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

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

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

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

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

// creates OpenGL ES program executables

}

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

GLES20.glDrawArrays(GLES20.GL_POINTS, 0, 5000);

try {
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}

★★★★

хотел запустить посмотреть треугольники, а там метода main нету...(

stevejobs ★★★★☆ ()
Ответ на: комментарий от stevejobs

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

OxiD ★★★★ ()

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

LOG.debug("Checking for errors");
int[] error = new int[1];
if (GL_FALSE == error[0]) {

int temp = programId;
gl.glDeleteProgram(programId);

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 ★★★★ ()
Ответ на: комментарий от OxiD

Круто, с рождеством!

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