Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (480)
Games in Android Showcase (110)
games submitted by our members
Games in WIP (546)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  vertex array questions  (Read 1878 times)
0 Members and 1 Guest are viewing this topic.
Offline weston

Junior Member





« Posted 2005-03-19 06:30:46 »

After running -Xprof on my game and finding that 79% of my time is spent in org.lwjgl.opengl.Win32Display.swapbuffers, I decided to optimize my opengl code a bit. Optimization of choice: vertex arrays.

What I'm wondering is how to use vertex arrays with lots of sprites (and particles eventually).

Can I put all the vertices from my sprites into a single FloatBuffer and then just use glDrawArrays for each sprite, giving an offset however many vertices have already been used? Or should each sprite keep its own FloatBuffer of points (and tex coords etc.) and then I use glVertexPointer for each sprite?

I'm primarily concerned with just making it work at this point, but I'd certainly be interested in hearing about which way would be better for whatever reasons.


Also, am I going to see much of a performance difference by using vertex arrays? I created a test app that renders 810,000 points and I get exactly 14 fps with and without vertex arrays... is that expected or am I doing something wrong?

for(int i = 1; i > 0; i++)
{
System.out.println(i+" cups of java downed");
}
Offline tom
« Reply #1 - Posted 2005-03-19 11:01:00 »

Use a single vertex array and draw ALL your sprites using ONE call to glDrawArrays. That means all sprites need to be in the same "space". So you need to transform the sprites manually and store the world coordinates in the vertex array.

Offline weston

Junior Member





« Reply #2 - Posted 2005-03-19 16:23:07 »

hmm, does this mean I need to rotate the vertices and texture coordinates manually as well? I'm not even sure I know how to rotate the texture manually... So assuming I can just rotate the texture coordinates the same way I do the vertices, is trig going to be too slow for this? I don't know any matrix math yet, but is that how this would generally be accomplished?

for(int i = 1; i > 0; i++)
{
System.out.println(i+" cups of java downed");
}
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline tom
« Reply #3 - Posted 2005-03-19 17:30:11 »

Yes you have to rotate the vertices yourself. You only need to change the texture coordinates if you are using the texture matrix. They texture will stick to the goemetry when you move the vertices.

What math you need to use depends on what your rendering. Do you do 2d sprites, 3d geometry, billboards (sprites that always facing camera). They all use different math.

Java trig is known to be slow but it will be faster than drawing each sprite one by one.

Offline weston

Junior Member





« Reply #4 - Posted 2005-03-20 22:45:59 »

ok, I've got this mostly working (after spending much time reading a 3d math book :-/ ). However, I see a problem with just using one call to glDrawArrays(). I use a per vertex lighting system that effects my sprites so some of them have been tesselated, this means that I have to use GL_TRIANGLE_STRIP instead of GL_QUADS. Because of this, opengl won't know when one sprite's geometry ends and another starts. Does this mean I am going to have to use a call to glDrawArrays for each sprite? If theres another solution for this kind of problem, I'd love to hear about it Wink

for(int i = 1; i > 0; i++)
{
System.out.println(i+" cups of java downed");
}
Offline weston

Junior Member





« Reply #5 - Posted 2005-03-21 04:42:09 »

I have another question that may be a little bit off this topic... Using vertex arrays I can draw 800 texture mapped quads at about 75 frames per second, the program does nothing else. If I were to write a particle system it would probably use this same approach, vertex arrays with texture mapped quads. Now a particle system that that draws can only draw 800 particles while mainting a decent framerate seems pretty bad to me. So I tried decreasing the size of the quads to about 10 unit squares, this actually gave me a large boost in framerate. With quads this size I can draw about 2500 while maintaining 75fps. What I'm wondering is why having larger geometry makes such a big difference on the framerate and what sort of optimization I would need to use in order to speed that up. Also, being able to draw 2500 quads is certainly better, but still seems a bit low to me. What other sorts of optimizations can I make to speed this up?

edit: ok, I should have checked my profiler but I just assumed the bottleneck would be the same thing with a different number of quads (oops). Turns out that the bottleneck is Matrix4f.load()... followed by my transformVertices() method. If anyone has an example class that uses matrices for transforms I'd like to see it Smiley I'm not really sure how this should be done, I just learned how to do the math and other than that I have no experience with the subject.

for(int i = 1; i > 0; i++)
{
System.out.println(i+" cups of java downed");
}
Offline Orangy Tang

JGO Kernel


Medals: 56
Projects: 11


Monkey for a head


« Reply #6 - Posted 2005-03-21 06:24:05 »

Some notes:

- Your initial 'bottleneck' of 79% in swapBuffers was probably not a bottleneck, but actually your app waiting for the next vsync.

- Graphics cards like nice big chunks of geometry at a time. Stuff like immediate mode (glBegin etc.) and small vertex buffers (less than 100 verts) are all far to small to be efficient. So you've basically got to batch things up into as big a group as possible - which usually means making compromises like sticking to one texture or geometry type.

- Ideally your CPU wouldn't even touch individual vertices, but for a particle system thats pretty much unavoidable.

- State changes (like binding textures, matrix stack stuff) can be costly as well, so try and avoid them where possible.

- Larger particles mean more pixels touched, which basically means a greater fillrate required. Theres no easy way around this, but if you add alpha testing to low-alpha values that can help some.

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Offline tom
« Reply #7 - Posted 2005-03-21 11:25:29 »

Quote
ok, I've got this mostly working (after spending much time reading a 3d math book :-/ ). However, I see a problem with just using one call to glDrawArrays(). I use a per vertex lighting system that effects my sprites so some of them have been tesselated, this means that I have to use GL_TRIANGLE_STRIP instead of GL_QUADS. Because of this, opengl won't know when one sprite's geometry ends and another starts. Does this mean I am going to have to use a call to glDrawArrays for each sprite? If theres another solution for this kind of problem, I'd love to hear about it Wink

You can use GL_TRIANGLES instead. You will have to dublicate a lot of vertices and that will increase the amount of data transfered to the card. It might slow you down, but is better that making a call to glDrawArrays for each sprite.

Or you can use indexed arrays. Then you can draw with GL_TRIANGLES without dublicating the vertex data. It's the indexes that is dublicated instead and they are only 4 (possibly 2?) bytes per vertex.

Offline weston

Junior Member





« Reply #8 - Posted 2005-03-21 16:17:18 »

about spending 79% of the time on swap buffers, I didn't have vsync enabled although I still was pausing (for a very small amount of time) in my game loop, I used something like sync2(1000).

There is still one more thing that I'm confused about. Is it really going to be slower using something like glTranslate() than transforming the vertices myself? How I had it set up initially was that every sprite just translated itself (using glTranslatef()) before rendering instead of actually changing the vertices. If I were to do this then I would have a very small number of unique vertices and either way every sprite needs to be transformed. How is it more efficient for me to multiply every vertex by the transform matrix myself instead of letting opengl do it? I know that I can load the matrix into opengl using glMultMatrix, but I thought I was supposed to give the 'world space' coordinates to opengl when using glDrawArrays(), is that true?.

Also, lookes like I'll be switching to indexed arrays with GL_TRIANGLES, don't know why I didn't think of just using triangles instead of a triangle strip...

for(int i = 1; i > 0; i++)
{
System.out.println(i+" cups of java downed");
}
Offline tom
« Reply #9 - Posted 2005-03-21 16:57:25 »

Quote

There is still one more thing that I'm confused about. Is it really going to be slower using something like glTranslate() than transforming the vertices myself? How I had it set up initially was that every sprite just translated itself (using glTranslatef()) before rendering instead of actually changing the vertices. If I were to do this then I would have a very small number of unique vertices and either way every sprite needs to be transformed. How is it more efficient for me to multiply every vertex by the transform matrix myself instead of letting opengl do it? I know that I can load the matrix into opengl using glMultMatrix, but I thought I was supposed to give the 'world space' coordinates to opengl when using glDrawArrays(), is that true?.

It is not faster to transform the vertices yourself. But when all the vertices are in the same space they can be drawn using one call to glDrawArrays(). Instead of one call for every sprite. Doing the transformation yourself is a compromise you do to get the speed increase of batching up geometry.

The vertices don't have to be world space. But they do have to be in the same space since they are all rendered with the same matrix.

To sum up, assuming you are geometry limited and not filrate limited (you spend more time transfering vertices to the card than actually rendering):
few calls to drawArrays - good
many calls to drawArrays - bad

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline weston

Junior Member





« Reply #10 - Posted 2005-03-22 06:46:53 »

ok thanks for the help, I think I have a much better understanding of the situation now Wink

for(int i = 1; i > 0; i++)
{
System.out.println(i+" cups of java downed");
}
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

atombrot (23 views)
2014-08-19 09:29:53

Tekkerue (22 views)
2014-08-16 06:45:27

Tekkerue (21 views)
2014-08-16 06:22:17

Tekkerue (12 views)
2014-08-16 06:20:21

Tekkerue (19 views)
2014-08-16 06:12:11

Rayexar (57 views)
2014-08-11 02:49:23

BurntPizza (37 views)
2014-08-09 21:09:32

BurntPizza (29 views)
2014-08-08 02:01:56

Norakomi (36 views)
2014-08-06 19:49:38

BurntPizza (66 views)
2014-08-03 02:57:17
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!