Sign in to follow this  
Steedie

Points order for a cube in GL_LINES

Recommended Posts

Hey guys I'm stuck with an ordering problem I'm trying to draw a cube using GL_LINES with a set of 24 points for a cube It works in QUADS, but obviously with lines its different and I cant get the lines to connect properly, it only ever draws the front and back face Was wondering what sort of order it is I need for it to draw correctly The points I have are as follows:
        //front
	-1.0f,  1.0f,  1.0f,		
	 1.0f,  1.0f,  1.0f,		
	 1.0f, -1.0f,  1.0f,		
	-1.0f, -1.0f,  1.0f,		

	//right
	 1.0f,  1.0f,  1.0f,		
	 1.0f,  1.0f, -1.0f,		
	 1.0f, -1.0f, -1.0f,		
	 1.0f, -1.0f,  1.0f,		

	//back
	 1.0f,  1.0f, -1.0f,		
	-1.0f,  1.0f, -1.0f,		
	-1.0f, -1.0f, -1.0f,		
	 1.0f, -1.0f, -1.0f,		

	//left
	-1.0f,  1.0f, -1.0f,		
	-1.0f,  1.0f,  1.0f,		
	-1.0f, -1.0f,  1.0f,		
	-1.0f, -1.0f, -1.0f,		

	//top
	-1.0f,  1.0f, -1.0f,		
	 1.0f,  1.0,  -1.0f,		
	 1.0f,  1.0f,  1.0f,		
	-1.0f,  1.0f,  1.0f,		

	//bottom
	-1.0f, -1.0f,  1.0f,		
	 1.0f, -1.0f,  1.0f,		
	 1.0f, -1.0f, -1.0f,		
	-1.0f, -1.0f, -1.0f,		



I cant really use LINE_LOOP either as it doesnt work properly for my backface culling algorith :( If anyone could help I will be so grateful Cheers in advance

Share this post


Link to post
Share on other sites
Hi Steedie

I plugged those vertices you gave into the middle of the renderer function for the project I happened to have open (it's a map editor) and managed to fix them so they show up like you meant. This is with GL_LINES:

screenshot of cube

(Ignore the pointy yellow box, that's trying to showing the highlighted square on the map; which you can't see because I commented out the call to the map renderer so you could see the cube better).

What it is is, it's not an ordering problem you were having. The reason it's not showing up right is because GL_LINES requires 2 points for each line--each set of 2 vertices in glBegin()-glEnd() defines one line. Just like how for GL_QUADS, each set of 4 vertices makes one polygon. But in your code, it looks like what happened is you tried to plug in a set of coordinates that was designed for drawing GL_QUADS but you used it with GL_LINES instead. Well when you do that it doesn't define the endpoints of the lines properly and that's why they don't all show up, because it's not interpreting what you said the way you meant it to be taken.

When you draw a cube, or any shape that has connected points, with LINES, you must define every other point twice. So say you want to draw a rectangle, if you're using GL_QUADS (or GL_LINE_LOOP) you can say:

0, 0, 0 // the upper left
1, 0, 0, // upper right
1, 1, 0, // lower right
0, 1, 0, // lower left

This goes clockwise around the edge of the rectangle (well, actually, the Y coordinate is backwards; it should be 0 where I said 1 and vice versa, but I'm using a "more positive = down" system because it's clearer to me, being used to 2D games) and defines each point on the quad. But if you want to make the same thing out of lines then those coordinates will not work. Instead you have to do this:

// top left of the box to the top right
0, 0, 0,
1, 0, 0,

// top right to the bottom right
1, 0, 0,
1, 1, 0,

// bottom right to the bottom left
1, 1, 0
0, 1, 0

// bottom left back up to the top
0, 1, 0
0, 0, 0,

This is what GL_LINE_STRIP is for, because it sucks having to write all the points twice like this. And GL_LINE_LOOP makes it so you do not have to explicitly mention the last one-- that you want the bottom left corner to go back up to the top again.


Anyway, so this is the code that's generating that screenshot:
Quote:
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glColor3ub(0,255,0);
glScalef(4.0, 4.0, 4.0);

glBegin(GL_LINES);

//front
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);

glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);

glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);

glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);

//right
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);

glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);

glVertex3f(1.0f, -1.0f, -1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);

//back
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);

glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);

glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);

//left
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);

glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glEnd();

glEnable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
glColor3ub(255,255,255);
[/b](You may not need all those disables/enables around it, I did because the program I'm working on makes the assumption that those things are set a certain way on the entry to any function and if they're changed they have to be changed back before leaving the function, this is to keep things orderly because it's a very large code base and before there was that rule functions tended to randomly screw things up for other functions in weird and unpredictable ways and cause really tricky bugs).
You'll notice that not all of the sides have the same number of vertices anymore, and that there is no top or bottom at all. This is because as I fixed the sides one at a time the lines that were shared with the sides they touch were already there so there was no point in drawing them again. And by the time I got to the top and bottom sides, all the lines for them were already being drawn when I drew the other sides.

Now, most people will tell you that this is not a very good way to draw a cube. The reason is, when you use GL_LINES you are sending twice as many vertices as you need to. If you are drawing a lot of lines it is almost always better to use GL_LINE_STRIP or GL_LINE_LOOP because it makes your code much shorter and easier to follow, and most importantly for a game, a lot faster if you (and you probably do) plan on drawing more than just a cube.

However, if this particular case, for this particular object, I counted the vertices and by my count, because a bunch of the lines can be used to draw more than one side, you need 24 vertices whether you use LINES or LINE_LOOP. So although it is cleaner code to use LOOP, it's sending about the same amount of data to the accelerator so it doesn't really make that much difference speedwise either way and if you have a good reason to use LINES I would go ahead and use LINES. In fact it might actually be faster to use LINES because (see next paragraph) to use LOOP you must have multiple sets of glBegin...glEnd. This fact, however, only applies to this particular object and more complicated objects, like spaceships or people, would be horribly inefficient to draw this way.

You can draw this cube with GL_LINE_LOOP by drawing each side in it's own glBegin()..glEnd() set. If you do it this way, you can use the same set as coordinates as what you used to make it out of quads only each side has it's own glBegin(GL_LINE_LOOP)...glEnd() instead of them all being inside one big glBegin(GL_QUADS).

Now I know you said that GL_LINE_LOOP was not compatible with your backface culling. I'm not quite sure why that is (and I'm a little bit curious if you want to tell me) because in my experience lines don't often create this sort of problem, and I don't understand why GL_LINES wouldn't cause it but GL_LINE_LOOP would. Maybe you're doing your own culling and your engine can only support lines. In which case you might want to consider adding at least support for line strips, which shouldn't be that hard.

Just in case it helps you sometime and you don't know already, if you are using opengl's depth buffer for culling there are a few ways you can temporarily "turn it off" if it's starts getting in the way.

* You can set glDepthFunc(GL_ALWAYS). This continues updating the depth buffer, so object's behind whatever you draw will get clipped. However whatever you draw appears on top of anything drawn previously no matter whether it's behind it or not.

* You can set glDepthMask(GL_FALSE). This clips whatever you draw so that you can not see it when it goes behind some other object. However the objects you draw are not put in the depth buffer, so they can not clip anything else you draw later even if they're supposedly "in front of" the new object.

* You can set glDisable(GL_DEPTH_TEST). This turns off the depth buffer completely so that whatever you draw draws over anything that was previously drawn in the current frame, and whatever you draw after reenabling this option can draw right over anything you drew while it was on, even if the new object is "behind" what you drew.

You can turn either of these options on or off at any time while you're rendering, whatever you draw after you set one/both of them is drawn either obeying/updating/both/neither the depth buffer or not, whatever you said to do, until you say otherwise.

Sorry. I know this is a very long post (can you tell I decided to take a break from what I was working on for a minute [wow])...but I hope something in it helps you out a bit...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this