2011-05-30 86 views
4

我正在使用LWJGL并使用glBegin/glEnd绘制立方体,但我听说这种方法效率很低,我应该开始使用VBO。我不知道这是如何工作的。OpenGL Java VBO

我想绘制不同大小和位置的立方体(不旋转),我想我应该使用VBO s。

任何人都可以给我一些示例代码或洞察力如何使用VBO s与Java或即使VBO s是最好的选择吗?

+1

为什么不搜索网络?我确定有很多关于VBOs的教程(甚至是Java)。你不会从一些简短的答案中学到很多东西,只是用一些没有解释任何东西的示例代码。那么明天你会问,如何改变这个代码来实现不同的东西。 – 2011-05-30 13:38:45

+0

glBegin/glEnd即时模式样式命令比VBOs慢,但总体上还是非常快 - 除非你真的在每帧画出大量的对象,你可能没有注意到它们之间的区别..... – mikera 2011-05-30 13:56:30

回答

7

有用的结果,这是我写的与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) {} 
} 
+0

我认为有一些混淆在你的术语中。 VAO是VBO和属性绑定状态的集合。它们在你的代码中完全没有使用。您使用的VBO的后备工具只依赖于固定功能顶点处理,并在客户端内存中存储顶点数组(它们只是数据的集合,当它们处于活动状态时存储在VBO中)。我不知道是否有名称,但它不是VAO。 作为一个附注,所有固定功能处理,包括使用客户端内存作为属性位置的目标,从OpenGL 3+开始不推荐使用。 – 2011-05-30 10:34:33

+0

@Bethor:谢谢你指出这一点。我编辑了答案以删除这个虚假信息。 – msell 2011-05-30 12:42:54

+0

这是一个非常好的例子,可以快速启动并运行JOGL中的VBO。太感谢了! – 2014-02-14 01:53:38

0

Jzy3d允许在基于JOGL的Java中轻松绘制VBO。

Here is an example我写了如何创建一个VBO散点图。这个分布是基于一个通用的DrawableVBO,它可以扩展到设置你自己的几何/网格。