#java #opengl #vbo
Вопрос:
Я использую LWJGL
и рисую кубики с glBegin/glEnd
помощью , но я слышал, что этот метод очень неэффективен, и я должен начать использовать VBO. Я понятия не имею, как это работает.
Я хочу рисовать кубы разных размеров и положений (без поворота), и я думаю, что для этого мне следует использовать VBO
s.
Может ли кто-нибудь дать мне пример кода или представление о том, как использовать VBO
s с Java
или даже если VBO
s-лучший выбор?
Комментарии:
1. Почему бы не поискать в Интернете? Я уверен, что существует множество учебных пособий по VBO (даже для Java). Вы не узнаете слишком много из короткого ответа с некоторыми строками примера кода, которые ничего не объясняют. Тогда завтра вы спросите, как изменить этот код, чтобы добиться чего-то другого.
2. Команды в стиле glBegin/glEnd немедленного режима работают медленнее, чем VBO, но в целом все еще довольно быстро — если вы действительно не рисуете очень большое количество объектов на кадр, вы можете не заметить разницы…..
Ответ №1:
Это код, который я написал для тестирования VBO на Java. Он использует JOGL вместо LWJGL, но это мелочь.
В дополнение к glVertexPointer вы также можете использовать glTexCoordPointer и glNormalPointer, чтобы указать данные для координат текстуры и нормалей и включить их с помощью glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY) и glEnableClientState(GL.GL_NORMAL_ARRAY).
import com.sun.opengl.util.*;
import javax.media.opengl.*;
import javax.swing.*;
import java.nio.*;
public class VBOTest implements GLEventListener {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
GLCanvas canvas = new GLCanvas();
canvas.addGLEventListener(new VBOTest());
frame.add(canvas);
frame.setSize(640, 480);
frame.setVisible(true);
}
private FloatBuffer vertices;
private ShortBuffer indices;
private int VBOVertices;
private int VBOIndices;
public void init(GLAutoDrawable drawable) {
float[] vertexArray = {-0.5f, 0.5f, 0,
0.5f, 0.5f, 0,
0.5f, -0.5f, 0,
-0.5f, -0.5f, 0};
vertices = BufferUtil.newFloatBuffer(vertexArray.length);
vertices.put(vertexArray);
vertices.flip();
short[] indexArray = {0, 1, 2, 0, 2, 3};
indices = BufferUtil.newShortBuffer(indexArray.length);
indices.put(indexArray);
indices.flip();
GL gl = drawable.getGL();
int[] temp = new int[2];
gl.glGenBuffers(2, temp, 0);
VBOVertices = temp[0];
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, VBOVertices);
gl.glBufferData(GL.GL_ARRAY_BUFFER, vertices.capacity() * BufferUtil.SIZEOF_FLOAT,
vertices, GL.GL_STATIC_DRAW);
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
VBOIndices = temp[1];
gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, VBOIndices);
gl.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, indices.capacity() * BufferUtil.SIZEOF_SHORT,
indices, GL.GL_STATIC_DRAW);
gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);
}
public void display(GLAutoDrawable drawable) {
GL gl = drawable.getGL();
gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, VBOVertices);
gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0);
gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, VBOIndices);
gl.glDrawElements(GL.GL_TRIANGLES, indices.capacity(), GL.GL_UNSIGNED_SHORT, 0);
gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {}
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {}
}
Комментарии:
1. Я думаю, что в вашей терминологии есть некоторая путаница. VAOS-это набор состояний привязки VBO и атрибутов. Они вообще не используются в вашем коде. Резервный вариант от VBO, который вы используете, просто основан на обработке вершин с фиксированной функцией и хранит массивы вершин (которые являются просто наборами данных, хранящихся в VBO, когда они активны) в памяти клиента. Я не знаю, есть ли для этого название, но это не VAOs. В качестве примечания, вся обработка с фиксированной функцией, включая использование клиентской памяти в качестве цели для расположения атрибутов, устарела с OpenGL 3 .
2. @Bethor: Спасибо, что указали на это. Я отредактировал ответ, чтобы удалить эту ложную информацию.
3. Это действительно отличный пример для быстрого запуска и работы с VBO в JOGL. Миллион раз спасибо!
Ответ №2:
Поиск в Google для OpenGL VBO дает полезные результаты, подобные этому
Ответ №3:
Jzy3d позволяет легко рисовать VBO на Java на основе JOGL.
Вот пример, который я написал, показывающий, как создать точечную диаграмму VBO. Этот разброс основан на универсальном DrawableVBO, который может быть расширен для установки вашей собственной геометрии/сетки.