PDA

View Full Version : Optimal way of drawing shapes, some questions



Lefteris
01-20-2010, 11:44 AM
Hey all,

I am a little confused by some things mentioned in the red book. It mentions in there that we have to draw shapes in a Counter-clockwise method if we want the current shape to count as a front face. I know that this is for lighting and for other stuff but what exactly is considered a front face?
I mean ... you can look at it from both sides, right? How can you define which one is the front?

It also mentions in there that you have to draw shapes from back to front, so that you can disable depth testing and the shape can still appear all right. I guess disabling depth testing is for enabling Anti-aliasing with blending on, right? But how do you define back?

Say we got a square. How would you draw its 6 surfaces back to front? Draw surfaces with smaller Z first and then those with bigger Z?

Finally, what's the best way to draw any kind of primitive? I mean what's the best way to draw a rectangle for example? I can draw a rectangle with glBegin(GL_QUADS) or with (GL_TRIANGLES) e.t.c. Am I correct in assuming that the best way is the one that calls glVertex the least?

Phewww, I know I got a lot of question but they are piling up as I read the blue book, any help would be appreciated!

Rosario Leonardi
01-20-2010, 01:15 PM
The front and the back of a polygon (triangle) is defined by the normal. The normal is computed with
n = cross((b-a), c-a)
Where a, b, c are the vertex, and cross(v1, v2) is the cross product.
When you draw an opaque solid object you will never see the back face, and you don't want you card to lose time drawing useless stuff.
If your object are transparent you have to blend them together and the only correct way is to draw them back to front (from the farthest to the nearer to the camera).
With kind of anti-aliasing are you talking about?
Don't use GL_POLYGON_SMOOTH, is not a proper anti-aliasing and is not optimized.

For primitives, only triangle, triangle fan and triangle strip [edit: point, line, line_streep, line loop]. All the other has been deprecated with openGL 3.0 and removed in openGL 3.2
Also glVertex as been deprecated, use vertex buffer object (VBO) or vertex array object (VAO)

ZbuffeR
01-20-2010, 01:44 PM
The front and the back of a polygon (triangle) is defined by the normal.
This is wrong in OpenGL.

The normal has nothing to do with front- and back-facing of polygons. The normal only has something to do with lighting.

On the contrary, only the vertex order defines which side is front-facing the camera : it is the side on which vertices are defined in a counter-clockwise order. If you look at the same polygon but on the other side, its vertices will appear in a clockwise order, so it will marked "back".

To my knowledge, back and front facing is used for only 3 things in OpenGL :
- backface culling, very useful to optimize an opaque watertight meshes (only half the triangles have to be drawn, the ones facing the camera)
- two-sided lighting, in which back-facing polygons automatically get their normals reversed, only useful when backface culling is disabled
- two-sided materials, as you can set different material properties for frontfacing and backfacing polygons :
glMaterialfv(GL_BACK, ... )

Rosario Leonardi
01-20-2010, 02:06 PM
Ehm.. yes you are right, what I want to say is that to compute witch part is on the front and witch part is on the back openGl compute the normal with the cross product, then make the dot product with the eye space position. Is the dot product is > 0 the face is considered front (otherwise back).

[edit]: another (faster) way is to compute the signed area of the triangle on the screen, and probably they do in this way, but the explanation with the normal is clearer IMHO.

The normal (as vertex attribute) has nothing to do with backfacing.

Two side lighting and material as been deprecated as well. Don't speak about stuff of the old decade. :P
Also distinct mode for polymode for front and back are deprecated.
If I'm not wrong is used only for culling and the distinction between back and front is leaved to the shader.

Vadim
01-20-2010, 02:32 PM
For the majority of 3d solid objects you do not want to see both sides of a primitive so why spending resources on drawing them ?
For example if you draw a sphere there is no need to render inside surface.

Lefteris
01-20-2010, 02:51 PM
Hmm people thanks a lot for your input. But I am a little confused. I am reading the red book thinking that it is up to date and you just told me that most of the stuff I read are deprecated >_<

Isn't the red book located here: http://www.glprogramming.com/red/ up to date and a great way to understand and learn openGL? If not do you have any other resource to suggest?

As for the anti-aliasing I was talking about it is the one described here:
http://www.glprogramming.com/red/chapter06.html#name2


I have another question about general openGL coding.
Say you have a function that changes many attributes. Let's say it disables lighting, disables depth test, blending, changes viewport e.t.c.
After the function ends say that we want them all back. What would be better performance wise?



//METHOD 1
glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); ...e.t.c.
>>>function starts and ends>>>>>>
glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); ... e.t.c.

//METHOD 2
glPushAttrib(GL_LIGHTING_BIT);glPushAttrib(GL_DEPT H_BUFFER_BIT);...et.c.
>>function starts and ends>>>>>>
glPopAttrib();glPopAttrib();...e.t.c.

//METHOD3
glPushAttrib(GL_ALL_ATTRIB_BITS);
>>function starts and ends>>>>>>
glPopAttrib();


Apart from the obvious that the 2nd and especially the 3rd method don't know if the attributes were already set or not, they just save the state, what is the best way as far as performance is concerned?

Rosario Leonardi
01-20-2010, 03:34 PM
You can combine the attribute you want to push, so the faster way is


glPushAttrib(GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT | ...);
// do your stuff here
glPopAttrib();
You can combine any GL constant that end with _BIT. :)

push/pop all attribute can be slow and it's very rare that you change EVERY state.

About the red guide, the free online version is updated at openGL 1.1.. 1997, the old century... :-/
Is still good to learn the basic stuff (matrix transformation, texture, basic lighting and so on). But actually apart some CAD developer nobody use the fixed pipeline anymore (GL_LIGHTING, GL_MATERIAL).
GLSL shaders has been introduced in the core with OGL 2.0, actually with OGL 3.0 everything is done with shaders.
The latest version of the RED book is updated at 2.1 and there is an orange book that explain shaders.
http://www.3dshaders.com/home/

I don't know any updated book... I usually follow tutorial and lurk in the forums.

ps: To be able to enable true antialiasing you have to create a context with multisample pixel format (the procedure depend on the framework you are using, google for "multisample glut"). The one described on the red book only change the alpha of the pixel, so you have to draw all the object back to front.

Lefteris
01-20-2010, 04:02 PM
Hm yes doh, forgot I could combine them since they are bit flags O.o. So which would be faster? pushing and popping the attributes? Or glEnable() and then glDisable() them?

Thanks for you input. Actually my application is CAD-like and it's not a game so I really thought that by reading the free red-book I could get something. I want to have my app as optimized as possible and to follow the newest ways of doing things so I don't mind learning things the new way.

Would you recommend buying or borrowing the latest edition of the red book (http://www.amazon.com/OpenGL-Programming-Guide-Official-Learning/dp/0321552628/ref=dp_ob_title_bk)? I can swear I saw it in my previous uni's library. I could borrow it or even better buy it since it's something I would like to have.

Orange book? Are shaders as a topic that hard, that they need their own book? O.O

Hmmm as for the anti-aliasing I think I will have to investigate further and when I get a better understanding of it come back and ask again :)

ZbuffeR
01-20-2010, 04:28 PM
I found the Orange Book very good to understand and take advantage of the "paradigm shift" created by shaders.

On the topic of deprecation :
I do think that deprecated OpenGL is much easier to learn realtime computer graphics as a beginner. Just do not concentrate on the details and constraints, as these are very different in core OpenGL 3.x.
On the other side, when looking for performance, be sure to avoid any deprecated feature (aside from display lists) even on GL 2 !

Back to your precise case, avoid glPushAttrib/glPopAttrib for performance, and avoid any unnecessary glEnable/glDisable call. Wrapping it in your own checker can be useful.

About performance, never use immediate mode glVertex* but instead VBO.

http://www.opengl.org/wiki/VBO

Lefteris
01-20-2010, 04:55 PM
Oh I just read a bit on shaders and I now understand that they are the way to do the per-vertex operations since openGL 2.1.
All these stuff I read about glMaterial Lighting e.t.c are deprecated :( Just when I thought I had gotten the hang of it.

Hm never use glVertex either? All right then. Getting both the red book latest edition and this orange book which explains this new way of doing the per-vertex operations is a must.

Thanks for the advice zbuffer I will be sure to follow it.

ZbuffeR
01-20-2010, 05:12 PM
GLSL is not only for vertex but also per-fragment (pixel) operations, way nicer to do materials, lighting and a myriad of other effects.

I found this online series is a good read to start with GLSL :
http://www.lighthouse3d.com/opengl/glsl/

For VBO, more tutorials at the bottom of the page :
http://www.opengl.org/wiki/Vertex_Buffer_Objects

Back on the performance topic :
- first make it work
- only then make it work faster

Lefteris
01-20-2010, 05:54 PM
Thanks for the link ZbuffeR . I will take a look at them too. Having tutorials and examples is huge way towards understanding GLSL.

As for the performance thing, I had read from the red book 1.1 version until the NURBS chapter. And had implemented lots of what I learned in my app. Had started to form a system revolving around lighting and materials and generally all the functionalities described in the depecated openGL full context.

So I kind of saw it working, but establishing a system on something that's deprecated does not seem wise to me. That's why I want to get informed on the latest methods and correct my currently implemented system.

Again thanks for your help, your links will really help me towards this goal.

ZbuffeR
01-21-2010, 01:52 AM
To avoid basing stuff on obsolete GL, browse latest official documents :
OpenGL 3.2 Specification
OpenGL Shading Language Specification v1.50.11

http://www.opengl.org/documentation/specs/

No need to read everything yet, but a quick overview will give you clearer ideas on modern GL.