What am I doing wrong UniformBuffers

I’m having trouble drawing objects with uniformbuffers multiple times per frame (mapping the buffer calling glDrawElements, mapping to the buffer and calling glDrawElements again).

Generating the buffer:


	public UniformBuffer(GL4 gl, int buffer_draw, int binding_index, float[] data)
	{
		m_handle = new int[1];
		
		FloatBuffer buffer_data = SNumberUtils.convertToFloatBuffer(data);
		
		gl.glGenBuffers(1, m_handle, 0);
		gl.glBindBuffer(GL4.GL_UNIFORM_BUFFER, m_handle[0]);
      gl.glBufferData(GL4.GL_UNIFORM_BUFFER, data.length * Buffers.SIZEOF_FLOAT, buffer_data, buffer_draw);
		gl.glBindBuffer(GL4.GL_UNIFORM_BUFFER, 0);
	}

Mapping the buffer:

		
		gl.glBindBufferBase(GL4.GL_UNIFORM_BUFFER, block_index, m_handle[0]);
		gl.glUniformBlockBinding(program, bind_location, block_index);
      gl.glMapBuffer(GL4.GL_UNIFORM_BUFFER, GL4.GL_WRITE_ONLY).asFloatBuffer().put(data);
		gl.glUnmapBuffer(GL4.GL_UNIFORM_BUFFER);

Then binding before glDrawElements():

		gl.glBindBufferBase(GL4.GL_UNIFORM_BUFFER, block_index, m_handle[0]);
		gl.glUniformBlockBinding(program, bind_location, block_index);

render:


	public void render(GL4 gl, GLU glu)
	{
		if(m_ibo == null) return;
		bindTextures(gl);
		map(gl);
		gl.glPolygonMode(m_face, m_mode);
		gl.glEnable(GL4.GL_DEPTH_TEST);
		gl.glEnable(GL4.GL_CULL_FACE);
		gl.glEnable(GL4.GL_BLEND);
		gl.glBlendFunc(GL4.GL_SRC_ALPHA, GL4.GL_ONE_MINUS_SRC_ALPHA);

		Matrix4f projection_mat = m_camera.getProjectionMatrix();
		float[] projection_array = projection_mat.get(new float[16], 0);
		Matrix4f view_mat = new Matrix4f().identity();
		float[] view_array = view_mat.get(new float[16], 0);

		m_model_ubo.bind(gl, m_shader.getUniformBlockLocation("model_matrix_buff"), UniformBuffer.MODEL_INDEX, m_shader.getHandle());
		m_joint_ubo.bind(gl, m_shader.getUniformBlockLocation("anim_joint_buff"), UniformBuffer.JOINT_INDEX, m_shader.getHandle());
		m_inv_bind_ubo.bind(gl, m_shader.getUniformBlockLocation("inv_bind_buff"), UniformBuffer.INVERSE_BIND_INDEX, m_shader.getHandle());
		m_vao.bind(gl);
		m_ibo.bind(gl);
		m_shader.update(gl);
		m_shader.setUniformMatrix4f(gl, false, "projection_matrix", projection_array);
		m_shader.setUniformMatrix4f(gl, false, "view_matrix", view_array);
		gl.glDrawElements(GL4.GL_TRIANGLES, m_vert_count, GL4.GL_UNSIGNED_INT, 0);
		m_ibo.unbind(gl);
		m_vao.unbind(gl);
		m_inv_bind_ubo.unbind(gl);
		m_joint_ubo.unbind(gl);
		m_model_ubo.unbind(gl);
		//gl.glFinish();
	}

This way the only objects that end up on screen are the last ones to get drawn, if I add glFinish() to the end of each render pass then I get all of the objects on screen.

Edit: code formatting

i dont think i got it yet, … you’re drawing same thing multime times and not all passes work ?

Some tips:

  • use (int) direct buffers for handling opengl names, such as m_handle
  • no need to call glBindBufferBase and glUniformBlockBinding multiple time if the block_index is not used from other UBOs, same for the model_matrix, anim_joint and inv_bind
  • don’t query every time uniform locations
  • use explicit locations if available, this will avoid you a lot of uniform binding stuff
  • merge projection and view matrix in one unique UBO and upload them together
  • ibo is part of the vao, you don’t need to bind/unbind it

I see only one glDrawElements

@basil_: ah, my bad. No, this is how I’m rendering batches of animated objects, I call render each time I run out of space in the buffers.

@elect:

[quote]- use (int) direct buffers for handling opengl names, such as m_handle
[/quote]
Does this actually make any difference?

[quote]- no need to call glBindBufferBase and glUniformBlockBinding multiple time if the block_index is not used from other UBOs, same for the model_matrix, anim_joint and inv_bind
[/quote]
Makes sense, good to know

[quote]- don’t query every time uniform locations
[/quote]
I’m not I have a hashmap

[quote]- use explicit locations if available, this will avoid you a lot of uniform binding stuff
[/quote]
I am for the block index, I guess it would be good to set the bind locations also, but they seem to be fine right now.

[quote]- merge projection and view matrix in one unique UBO and upload them together
[/quote]
I seem to remember having a reason for this, but I’ll look into it again.

[quote]- ibo is part of the vao, you don’t need to bind/unbind it
[/quote]
Good point.

not getting there yet but … do you update (write to) the UBO’s within the render function. cannot spot any.

anyway, since glFinish helps, it’s a cpu<->sync issue. first thing that comes to my mind is buffer-mapping with the MAP_COHERENT_BIT. what happens if you use glFlush or if you change your mappings ?

jogl uses native buffers underneath to converse with opengl, I am pretty sure lwjgl needs to do the same, maybe basil or someother one may confirm

And if you don’t pass them a direct (int) buffer, they have to create it themselves and you will never have the security it will be freed once it isn’t needed anymore or not, but if you instantiate on your side, you can take care of its disallocation.

This is good, although I’d still go with a variable, because by a logic point of view, it doesn’t make sense, since you have already done the decision of which uniform locations to pick at the time you call the function by passing the corresponding string

Explicit locations will allow you to avoid any uniform location, this means no more glUniformBlockBinding, glUniform1i for textures, etc…

If you may need proj (and/or view alone), just upload all the different matrices in your UBO and pick the one you need in your shader

uniform Transform0 
{
   mat4 proj;
   mat4 view;
   mat4 projView;
} t0;

@basil_ it’s in the map function.

Here is how I build the arrays to map to the buffer:
http://pastebin.com/VV2TCLD8

and here is the map function:
http://pastebin.com/6ywicZqe

and here are the functions from the previous paste (they are in the first post of this thread too):
http://pastebin.com/XQ7gZvTS

How I end up calling render() multiple times is in this method
http://pastebin.com/JiFbF4x4

I also have realized that this is the wrong way to handle this. I should queue up the batches and go through each batch in the render method, but this function is called in my display method right before I call renderer.render(). As such I’m not sure this is the problem, but I will begin fixing this tonight.

I have stopped working on this problem directly, but I found that there are indeed some problems with the way I am mapping and drawing objects.

I consolidated my batch renderers into an abstract class and then extended that class with my animated batch renderer. Now I am drawing the first and last thirds of the objects I would like to render. Which is an improvement, so I don’t think anybody can really help me with this at this point.

Thanks for the advice!

would need more of a http://sscce.org/ to tell.