I'm trying to use glVertexAttribPointer to get both the position and texture coordinates from a single VBO into my vertex shader. The vertex shader is basic and doesn't do much other than transform and output.
The test scene is a few non-textured quads, a non-textured background quad, and several hundred textured quads. With the following code and no textured quads I get a solid ~2200 fps gl.glEnableVertexAttribArray(0); gl.glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0); gl.glMultiDrawArrays(buffObj.drawFunc.getGLCommand(), buffObj.vertIndices, 0, buffObj.vertNum, 0, buffObj.objCount); // disable arrays gl.glBindBuffer(GL_ARRAY_BUFFER, 0); gl.glDisableVertexAttribArray(0); Note: the VBOs for the non-textured quads are allocated to only hold position coordinates. Adding the tex coord vertex attribute drops it down to <100 fps: gl.glEnableVertexAttribArray(0); gl.glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0); if(texBound && texEnabled) { gl.glEnableVertexAttribArray(1); gl.glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, 2 * buffObj.nverts * Buffers.SIZEOF_FLOAT); } gl.glMultiDrawArrays(buffObj.drawFunc.getGLCommand(), buffObj.vertIndices, 0, buffObj.vertNum, 0, buffObj.objCount); // disable arrays gl.glBindBuffer(GL_ARRAY_BUFFER, 0); gl.glDisableVertexAttribArray(0); if(texBound && texEnableD) gl.glDisableVertexAttribArray(1); The load shouldn't be a problem. The same scene ran at ~2000 fps using fixed function glVertexPointer and glTexCoordPointer with the same VBO setup. Am I doing something wrong? What kind of state calls or optimizations should I consider with setting vertex attribute pointers? |
Administrator
|
Personally, I would do that:
if(texBound && texEnabled) { gl.glEnableVertexAttribArray(1); gl.glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, 2 * buffObj.nverts * Buffers.SIZEOF_FLOAT); } else { gl.glEnableVertexAttribArray(0); gl.glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0); } //same code ... if(texBound && texEnableD) gl.glDisableVertexAttribArray(1); else gl.glDisableVertexAttribArray(0); Why not looking at the source code of JMonkeyEngine 3 shader based JOGL renderer? I think I use these calls appropriately.
Julien Gouesse | Personal blog | Website
|
If I do that, the textured quads don't get drawn because the vertex position attribute doesn't get set.
I think the performance bottleneck is coming in large part from my fragment shader's lighting calculations, which I haven't tested with the large number of quads since it was much less complex. The odd thing still, however, is that the FPS start dropping each second while it's rendering. That seems to me like an indication of some kind of memory leak or misused pointer. Do you have any idea why that might happen? |
In reply to this post by gouessej
I'm looking at:
http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/jogl/com/jme3/renderer/jogl/JoglRenderer.java?spec=svn9910&r=9910 How many times does that glVertexAttribPointer get called? Is it called for just position? If so, how do you get texture coordinate data to the vertex shader? |
Administrator
|
It's called once but you should download the whole source code of the engine and look where the method containing this OpenGL call is called.
Julien Gouesse | Personal blog | Website
|
In reply to this post by bgroenks96
By concidence I am hunting a similar problem in my game-project. I had FPS degradation, over a few minutes it dropped very much. Turned out that I forgot to delete the vertex attribute buffers, eating GPU memory. Make sure every genBuffer you call is matched by a deleteBuffer. So yes, leaks somewhere can cause that type of FPS degradation. |
This post was updated on .
How many buffers are you creating?
With mine, I'm only generating three and then just reusing them. Could that still be an issue? I think I might have solved the issue for now by replacing glMapBuffer and glUnmapBuffer with glBufferSubData. I don't really know why that all of a sudden changed... How much performance difference should there be between glBufferSubData and writing everything to a local buffer and using glBufferData on draw? |
Administrator
|
I'm not completely surprised, maybe there is a leak in your driver that affects glMapBuffer & glUnmapBuffer, glBufferSubData doesn't do any memory allocation. In my humble opinion, you shouldn't rely on inconsistent speedups obtained by using glBufferData to invalidate the data store and resend the data, rather use glBufferSubData even to update the content of the whole buffer.
Julien Gouesse | Personal blog | Website
|
In reply to this post by bgroenks96
Not recommended to do what I'm doing : I create between 10-30 (very small) buffers each frame at 60 FPS. Unless I delete them correctly FPS drops after a few seconds I guess this will vary greatly between drivers. |
In reply to this post by gouessej
So you mean write individual object data to a local FloatBuffer then upload everything at once on the draw call via glBufferSubData? |
Administrator
|
Yes this is a possibility, pass the buffer once to glBufferData and call glBufferSubData to update the content. We do something similar in several engines. The only drawback is that you have to handle direct NIO buffers carefully to avoid running out of native memory.
Julien Gouesse | Personal blog | Website
|
Ok. If you store a single instance of the direct NIO Buffer, subsequent put calls should just overwrite data in existing memory correct? That seems like the most efficient way to handle an object that you update frequently with new vertex data.
|
Administrator
|
If you modify the data in the direct NIO buffer you created by yourself without passing them to OpenGL, the changes won't be reflected. Keep in mind that the direct NIO buffer on the CPU and the data store on the GPU are 2 different things.
Julien Gouesse | Personal blog | Website
|
Yes I know. Sorry, I should have clarified what I meant. I mean allocate a single instance of the NIO Buffer -> write changes to it -> on draw call, upload via glBufferSubData -> repeat I was referring to the memory being used by the NIO Buffer being kept on the client side. The one that you modify with updates and then write to VRAM once all updates have been made. |
Administrator
|
In reply to this post by gouessej
On 01/14/2014 08:23 PM, gouessej [via jogamp] wrote:
> Yes this is a possibility, pass the buffer once to glBufferData and call > glBufferSubData to update the content. Reason is, glBufferData recreates the GPU memory 'slot' ! ~Sven signature.asc (911 bytes) Download Attachment |
So that's what causes the memory leak? When is it appropriate then to make the glBufferData(..., ..., null, ...) call? Isn't it supposed to tell the driver to discard the previously held buffer data? |
Administrator
|
On 01/14/2014 10:50 PM, bgroenks96 [via jogamp] wrote:
> Sven Gothel wrote > Reason is, glBufferData recreates the GPU memory 'slot' ! > > So that's what causes the memory leak? > > When is it appropriate then to make the glBufferData(..., ..., null, ...) > call? Isn't it supposed to tell the driver to discard the previously held > buffer data? yes, sure - recreate == dispose+create Haven't said anything about a leak. But recreation takes more time for memory management where glBufferSubData simply updates the content. Thought this discussion was about performance .. ~Sven signature.asc (911 bytes) Download Attachment |
It is/was.
Leaks can cause performance degradation right? It's the only thing I can think of to explain the FPS drop over time. |
Administrator
|
On 01/15/2014 01:59 AM, bgroenks96 [via jogamp] wrote:
> It is/was. > > Leaks can cause performance degradation right? There is no simple yes/no answer to this question, sorry. > > It's the only thing I can think of to explain the FPS drop over time. Since I currently work on Bug 942 https://jogamp.org/bugzilla/show_bug.cgi?id=942 Bug 943 https://jogamp.org/bugzilla/show_bug.cgi?id=943 it may help if you can produce a small unit test demonstrating some use of BufferData etc .. in a shader based environment (core profile). We can use this one for some measurements .. leak detections. If MapBuffer is involved and issued multiple times, especially w/ multiple BufferData (new mapped buffers) there are chances for a leak - working on it. ~Sven signature.asc (911 bytes) Download Attachment |
I'll see what I can do. Do you want me to submit said unit test on Bugzilla?
|
Free forum by Nabble | Edit this page |