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("Linking program");

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