Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In What Order Should I Send My Vertices To OpenGL for Culling

Tags:

c++

opengl

sdl

I'm learning a spot of 3d opengl, and it's going rather well, I've got a nice camera moving about and some simple cube objects, at the moment. Currently using vertex arrays, but I'm swapping to VBOs pretty quick here. I'm just trying to enable culling, however I'm not sure what order in which I ought to specify my vertices, right now this is what I'm doing:

void cube::update_verts(){ GLushort cur=0;  ///back face verts[cur++]=x; verts[cur++]=y; verts[cur++]=z; verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z; verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z; verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z;  ///right face verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z; verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z; verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z+sz; verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z+sz;  ///top face verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z; verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z; verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z+sz; verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z+sz;  ///front face verts[cur++]=x; verts[cur++]=y; verts[cur++]=z+sz; verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z+sz; verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z+sz; verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z+sz;  ///bottom face verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z; verts[cur++]=x; verts[cur++]=y; verts[cur++]=z; verts[cur++]=x; verts[cur++]=y; verts[cur++]=z+sz; verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z+sz;  ///left face verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z; verts[cur++]=x; verts[cur++]=y; verts[cur++]=z; verts[cur++]=x; verts[cur++]=y; verts[cur++]=z+sz; verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z+sz;   }  ///Drawing Code:  glVertexPointer(3,GL_FLOAT,0,object.verts); glColorPointer(3,GL_UNSIGNED_BYTE,0,object.colors); glDrawArrays(GL_QUADS,0,6*4); 

However it's definitely quite wrong, because when I glEnable(GL_CULL_FACE); my cubes don't show the correct faces (as seen below).

Normal Regular View From Top

Problem Child View From Side

With both of these images culling is enabled.

In what order should I specify the vertices?


(EDIT) Updated Working Function:

void cube::update_verts(){ GLushort cur=0;  ///top face verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z; verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z+sz; verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z+sz; verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z;   ///bottom face verts[cur++]=x; verts[cur++]=y; verts[cur++]=z; verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z; verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z+sz; verts[cur++]=x; verts[cur++]=y; verts[cur++]=z+sz;  ///left face verts[cur++]=x; verts[cur++]=y; verts[cur++]=z; verts[cur++]=x; verts[cur++]=y; verts[cur++]=z+sz; verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z+sz; verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z;  ///right face verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z; verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z; verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z+sz; verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z+sz;  ///front face verts[cur++]=x; verts[cur++]=y; verts[cur++]=z+sz; verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z+sz; verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z+sz; verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z+sz;   ///back face verts[cur++]=x; verts[cur++]=y; verts[cur++]=z; verts[cur++]=x; verts[cur++]=y+sy; verts[cur++]=z; verts[cur++]=x+sx; verts[cur++]=y+sy; verts[cur++]=z; verts[cur++]=x+sx; verts[cur++]=y; verts[cur++]=z;  } 
like image 855
ultifinitus Avatar asked Nov 15 '11 20:11

ultifinitus


People also ask

Does the order of vertices matter in OpenGL?

@Nikos: Nope, doesn't matter which vertex you start with.

What is winding order in OpenGL?

This is determined by the winding order of the triangle. Given an ordering of the triangle's three vertices, a triangle can appear to have a clockwise winding or counter-clockwise winding. Clockwise means that the three vertices, in order, rotate clockwise around the triangle's center.

Does OpenGL automatically cull?

By default, OpenGL expects counter-clockwise winding order for triangles that are facing forwards. With backface culling enabled, triangles facing the other direction will be automatically culled. This occurs before rasterization.


1 Answers

By default? In counter-clockwise order.

Consider a triangle facing the camera:

A |\ | \ |  \ B---C 

A->B->C would be front facing (counter-clockwise order), A->C->B would be rear-facing (clockwise order).

You can change which way OpenGL considers "front facing" via glFrontFace():

The projection of a polygon to window coordinates is said to have clockwise winding if an imaginary object following the path from its first vertex, its second vertex, and so on, to its last vertex, and finally back to its first vertex, moves in a clockwise direction about the interior of the polygon. The polygon's winding is said to be counterclockwise if the imaginary object following the same path moves in a counterclockwise direction about the interior of the polygon. glFrontFace specifies whether polygons with clockwise winding in window coordinates, or counterclockwise winding in window coordinates, are taken to be front-facing. Passing GL_CCW to mode selects counterclockwise polygons as front-facing; GL_CW selects clockwise polygons as front-facing.

By default, counterclockwise polygons are taken to be front-facing.

For ordering your vertices, consider an ideal cube:

  6---7  /|  /| 2---3 | | 4-|-5 |/  |/  0---1 

For each face mentally rotate it to face the camera (your mind's eye):

Sides: 2---3  3---7  7---6  6---2 |   |  |   |  |   |  |   | |   |  |   |  |   |  |   | 0---1  1---5  5---4  4---0  Bottom/Top 0---1  6---7 |   |  |   | |   |  |   | 4---5  2---3 

Then you can just visually read off the quads or triangle pairs in the right counter-clockwise order:

2---3                3         2---3  |   |  becomes      /|   and   |  /  |   |             /  |         |/  0---1            0---1         0   Triangles 0-1-3 and 0-3-2 Quad 0-1-3-2 

It doesn't matter which vertex you start the triangle/quad with, for example with the first triangle 0-1-3, 1-3-0, and 3-0-1 are all equally valid, front-facing triangles.

like image 130
genpfault Avatar answered Oct 05 '22 06:10

genpfault