Trouble making VBO rendering easier

I’m trying to make rendering VBOs a simpler task. I have this Drawer class with code to render a VBO quad each frame.

public class Drawer {
	static int vboVertexHandle;
	static int vertices;
	static int vertexSize;
	
	public static void drawQuad( int width, int height )
	{
		boolean initialized = false;
		if(!initialized)
		{
			final int vertices = 6;
			final int vertexSize = 6;
			
			FloatBuffer vertexData = BufferUtils.createFloatBuffer(vertices * vertexSize);
			vertexData.put(new float[]{0, 0, 0, width, 0, 0, width, height, 0, 0, height, 0});
			vertexData.flip();
			
			vboVertexHandle = glGenBuffers();
			glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
			glBufferData(GL_ARRAY_BUFFER, vertexData, GL_DYNAMIC_DRAW);
			glBindBuffer(GL_ARRAY_BUFFER, 0);
			System.out.println("boolean...do you work?");
			initialized = true;
		}
		
		glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
		glVertexPointer(vertexSize, GL_FLOAT, 0, 0L);
		
		glEnableClientState(GL_VERTEX_ARRAY);
		glDrawArrays(GL_TRIANGLES, 0, vertices);
		glDisableClientState(GL_VERTEX_ARRAY);
		
		
	}
}

I have that boolean there in hopes it wont initialize the VBOs each frame. When I call

Drawer.drawQuad(20, 20);

nothing appears. Why isn’t it working?

maybe make an SSCCE

I won’t go into whether or not this approach is a good practice, but initialised is a local variable that is always set to false. You probably want it to be outside of the function.

Furthermore, you are redeclaring vertices and vertexSize in the if-block, whereas the drawArrays call will use the static class variable (which remain 0).

Fix those two up and it should work.

public class Drawer {
static boolean initialized = false;
static final int vertices = 6;
static final int vertexSize = 6;
static int vboVertexHandle = glGenBuffers();

 public static void drawQuad( int width, int height )
   {
      
      if(!initialized)
      {
         
         
         FloatBuffer vertexData = BufferUtils.createFloatBuffer(vertices * vertexSize);
         vertexData.put(new float[]{0, 0, 0, width, 0, 0, width, height, 0, 0, height, 0});
         vertexData.flip();
         
         
         glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
         glBufferData(GL_ARRAY_BUFFER, vertexData, GL_DYNAMIC_DRAW);
         glBindBuffer(GL_ARRAY_BUFFER, 0);
         System.out.println("boolean...do you work?");
         initialized = true;
      }
      
      glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
      glVertexPointer(vertexSize, GL_FLOAT, 0, 0L);
      
      glEnableClientState(GL_VERTEX_ARRAY);
      glDrawArrays(GL_TRIANGLES, 0, vertices);
      glDisableClientState(GL_VERTEX_ARRAY);
      
      
   }

}

I think I’m doing something wrong still. This is crashing the JRE.

You can’t call glGenBuffers() in a static context.

Perhaps you should have a look at LibGDX, which will handle all this stuff for you, and uses good practices.

I’m confused. What exactly do you mean?


public class Drawer {
    static boolean initialized = false;
    static final int vertices = 6;
    static final int vertexSize = 6;
@@    static int vboVertexHandle = glGenBuffers();
    // snip
}

I’m pretty sure you need a GL context available to call that.

Since it’s a static variable, it is likely to be initialised before a Display or GLFW window is created. (I say likely because the JVM isn’t very deterministic with this sort of thing)

I see your point. The ‘static context’ is not relevant actually, it’s just a matter of whether the OpenGL context is current. You are correct in pointing out that it is highly unlikely that the OpenGL context is current at the time the static block is executed, and such code should be frowned upon regardless of whether one can guarantee (it’s deterministic, mind you) a context is current. Anyway, enough derailing :emo:

I believe your problem is here:

final int vertexSize = 6;

glVertexPointer(vertexSize, GL_FLOAT, 0, 0L);

vertexSize, when passed to glVertexPointer can only be 2, 3, or 4, according to the specification. Your triangles use 3 vertices each. We’re not quite ready for 6 dimensional rendering yet.

On a side note, once you’re comfortable with rendering the way you are, perhaps you may want to look at rendering through shaders.