Pages: 1
  Print  
Author Topic: How to properly use OpenGL  (Read 11043 times)
Offline (Unknown gender) luiscubal
Posted on: October 04, 2011, 03:35:58 pm
Member
Joined: Jun 2009
Posts: 452

View Profile Email
This is really a must-have these days.
Seriously, if you use or are planning to ever use OpenGL, this tutorial is a MUST.

http://duriansoftware.com/joe/An-intro-to-modern-OpenGL.-Table-of-Contents.html

It's sad that it was never completed, but every single chapter is totally worth it.

Remember: if you use glBegin/glVertex/glEnd, then you are doing it WRONG.

This has been a public service announcement. Thank you and have a nice day.
Logged
Offline (Unknown gender) TheExDeus
Reply #1 Posted on: October 04, 2011, 04:17:54 pm

Developer
Joined: Apr 2008
Posts: 1860

View Profile
I did test difference when not using immediate rendering (glBegin/glEnd) and use vertex arrays. The difference was negligible and/or worse than using begin/end. The reason for that is that we render sprites (for example) with draw functions which are basically immediate. We have to create an array, fill it with information, and only then draw it and that has to be done every step. If I precalculate the array and then draw, then it is a lot faster (as expected). But there isn't really much we can do. Though things like tiles could be drawn using vertex arrays and that would really speed them up. Maybe even default sprites for objects could be done this way (and updated only when position and such change), but I don't see how this can be done while using functions in draw event.
Although I wanted to add vertex array functions (which would be surface'ish) that would allow fast drawing of static (or semi-dynamic) sprites. That would of been cool for things like physics engines, where you would update drawing information only when you update physics information too.
Also, I did pressure Josh to make as few sprite textures as possible (so pack them in 512x512 or 1024x1024 textures not 1 texture per sprite). That would reduce texture flipping (which is also done in every draw function, every step) and that causes a lot of slowdown.
Logged
Offline (Male) Josh @ Dreamland
Reply #2 Posted on: October 04, 2011, 05:54:40 pm

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2950

View Profile Email
I told you that I intend to use lists for tiles. I'll bet you a hand of bananas it's faster than a VBO.

If you find a way to remove the texture flipping at the beginning of each draw function, you let me know.
Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Unknown gender) luiscubal
Reply #3 Posted on: October 04, 2011, 06:21:51 pm
Member
Joined: Jun 2009
Posts: 452

View Profile Email
First of all, this is a post about OpenGL, not ENIGMA. While ENIGMA may use OpenGL, this is targeted at people who want to learn OpenGL, not specifically ENIGMA developers. I recognize there may legitimate reasons for ENIGMA developers to use deprecated APIs, such as compatibility with OpenGL 1.x.

That said:

The difference is display lists are deprecated and VBOs are not.

Search "AMD – Introduction to OpenGL 3.0" and click first result(a PDF)

Go to the section "OpenGL 3.0 and deprecation".

Quote
Some of these deprecated features are:
- Fixed-function rendering
- Immediate mode
- Display lists
etc.

It's fine to have display lists and glVertex in code that must be compatible with OpenGL 1.x, but to actively encourage this method for people who are new to OpenGL? No way. glBegin/glVertex/etc. and display lists should be a fallback.

Also, in my own (admittedly limited) experience, display lists tend to be slower than directly using the equivalent code.

Quote
If you find a way to remove the texture flipping at the beginning of each draw function, you let me know.
I have no idea what you are talking about.
Logged
Offline (Male) Josh @ Dreamland
Reply #4 Posted on: October 04, 2011, 07:15:07 pm

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2950

View Profile Email
I was talking to HaRRi, luis. :P
He was the one that mentioned my name.

It may prove that VBO is more widely available as an extension now that Microsoft has their head out of their ass GL-wise. In the meantime, the deprecated, proven method is the way to go.

I don't believe for a minute that you've found any situation in which VBO would accelerate primitive drawings and lists wouldn't.
Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Unknown gender) luiscubal
Reply #5 Posted on: October 04, 2011, 07:36:32 pm
Member
Joined: Jun 2009
Posts: 452

View Profile Email
I haven't compared VBOs vs lists, but I did compare lists vs "repeat on every frame every GL call" and lists were a little bit slower. I'm guessing the drivers I've tested this in were not very good and implemented display lists the simplest way possible.
Again, actual benchmarking and testing beats any assumptions, so the best way to check is to try it yourself.

However, deprecation is deprecation. I'm guessing the people who made OpenGL had good reasons to declare display lists and immediate mode obsolete.
Logged
Offline (Unknown gender) TheExDeus
Reply #6 Posted on: October 05, 2011, 08:53:01 am

Developer
Joined: Apr 2008
Posts: 1860

View Profile
Quote
I told you that I intend to use lists for tiles. I'll bet you a hand of bananas it's faster than a VBO.
I remember you mentioning you wanted to just use quads, but either way, I doubt lists are faster than VBO (for the same reasons luiscubal already mentioned).

Quote
If you find a way to remove the texture flipping at the beginning of each draw function, you let me know.
Well the easiest method would be to just check if the sprite that is going to be drawn is on the bound texture, if not, then bind it. So if you have like 10 sprites that are on one texture and you draw them in any order, then we don't have to flip textures.  On the other hand if you draw sprites which are on different textures, then you just bind it. In the end it takes one "if" statement more. This would also work great when you draw a lot of the same sprites at once (like particles in a "for" or "with" statement).

edit: Also why I wanted this sprite packing is because some hardware (like phones or old PC's) still don't like non power of two textures. So if you have a sprite that is 65x64 pixels, then GL could end up generating 128x64, which of course is bad memory wise. So its better to do this ourselves. But I will benchmark the speed difference between binding only once, or doing it every time when the sprite is drawn. I doubt the speed increase will be phenomenal, but it could be faster when drawing a lot of sprites.

Also, I did test VBO when drawing particles and I could draw 100k static sprites without loss of FPS. I could check the difference between that and lists.
« Last Edit: October 05, 2011, 08:57:57 am by HaRRiKiRi » Logged
Offline (Male) Josh @ Dreamland
Reply #7 Posted on: October 05, 2011, 10:47:01 am

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2950

View Profile Email
I don't know if you've noticed, but the macro already does that.
#define untexture() if(enigma::bound_texture) glBindTexture(GL_TEXTURE_2D,enigma::bound_texture=0);

It's done that since the dawn of time.

While it's possible that VBO, being newer, could be faster than lists, I'm mostly concerned about support. Deprecated, maybe, but still supported to at least the point of working on the shittiest cards with the shittiest drivers. Any card that gives GL lists no boost probably doesn't bother offering the VBO extension. On top of that, I have no benchmark to suggest superior speed either way. Perhaps once I've actually implemented tiles, I can move to Windows and test one list implementation and one VBO implementation. I've got a pretty new graphics card (few months old), so I'm sure it'll be as fair a representative as one card could ever be.
Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Unknown gender) TheExDeus
Reply #8 Posted on: October 05, 2011, 11:13:02 am

Developer
Joined: Apr 2008
Posts: 1860

View Profile
Quote
I don't know if you've noticed, but the macro already does that.
#define untexture() if(enigma::bound_texture) glBindTexture(GL_TEXTURE_2D,enigma::bound_texture=0);
Well yes, but as we have one texture per sprite, then it is still flipped when we want to draw different sprites. If more sprites were on the texture, then those calls would be greatly reduced. Also, for sprite drawing untexture() wasn't defined, so it does the if statement in the function.


Quote
On top of that, I have no benchmark to suggest superior speed either way.
Yeah, but if VA ends up faster, then I would suggest maybe using that. I know you love support, and maybe we can have two GL implementations. One would be faster, but less supported, and the other would be slower, but using legacy functions. But that is a long way into the future, as we have to benchmark those functions first.
Logged
Offline (Unknown gender) luiscubal
Reply #9 Posted on: October 06, 2011, 08:24:38 am
Member
Joined: Jun 2009
Posts: 452

View Profile Email
Quote
now that Microsoft has their head out of their ass GL-wise
[citation needed]
Logged
Offline (Male) RetroX
Reply #10 Posted on: October 07, 2011, 02:17:14 pm

Master of all things Linux
Contributor
Location: US
Joined: Apr 2008
Posts: 1055
MSN Messenger - classixretrox@gmail.com
View Profile Email
JoshDreamland: VBOs are far faster than lists because things are less generalised.  Because the graphics pipeline doesn't have to go through loads of shit that isn't used (for example, transforming with identity matrices), it's much faster.  Either way, ith 2-D stuff, the performance is practically unnoticeable.

Either way, support-wise, you should always use lists over glBegin/glEnd because it's much faster.  The only case against it would be in cases draw_* functions.
Logged
My Box: Phenom II 3.4GHz X4 | ASUS ATI RadeonHD 5770, 1GB GDDR5 RAM | 1x4GB DDR3 SRAM | Arch Linux, x86_64 (Cube) / Windows 7 x64 (Blob)
Quote from: Fede-lasse
Why do all the pro-Microsoft people have troll avatars? :(
Pages: 1
  Print