Using glOrtho, just trying to make a box

Started by
5 comments, last by dimebolt 18 years, 8 months ago
I'm working on some software that will make a 3D graph, but right now all I'm trying to do is setup the box containing the graph. The app can have many different graphs open at once, and I may want to rotate or fly through them independently. Also, for ease of coding, I wanted my OpenGL calls to be in sync with the graph data, so say glVertex2f(point.x, point.y) would go to the correct point on the graph without me having to do any other calculations. The way I'm doing this is by giving each graph it's own viewport. The code below works fine if I try just a 2D graph, but I've altered it for 3D and now the viewport is empty:

void Plot::Render()
{
	if(m_bHidden)
	{
		return;
	}
 
	double winx, winy, winz;
	GetWindowCoords(winx, winy, winz);
 
	GLfloat backupViewport[4];
	glGetFloatv(GL_VIEWPORT, backupViewport);
 
        // I know this is right because it works for 2D
	glViewport(winx, winy-m_height, m_width, m_height);
 
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
 
	glOrtho(GetHorizontalMin(), GetHorizontalMax(), GetVerticalMin(), GetVerticalMax(), GetDepthMin(), GetDepthMax());
 
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();
 
	glColor4ub(0, 0, 255, 255);
	glLineWidth(100.0);
	glBegin(GL_LINES);
		glVertex3f(GetHorizontalMin(), GetVerticalMin(), GetDepthMin());
		glVertex3f(GetHorizontalMax(), GetVerticalMin(), GetDepthMin());
 
		glVertex3f(GetHorizontalMin(), GetVerticalMin(), GetDepthMin());
		glVertex3f(GetHorizontalMin(), GetHorizontalMin(), GetDepthMin());
 
		glVertex3f(GetHorizontalMin(), GetVerticalMin(), GetDepthMin());
		glVertex3f(GetHorizontalMin(), GetHorizontalMin(), GetDepthMax());
	glEnd();
 
	glPopMatrix();
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
 
	glMatrixMode(GL_MODELVIEW);
 
	glViewport(backupViewport[0], backupViewport[1], backupViewport[2], backupViewport[3]);
}
The get Max/Min functions get the smallest and greatest values for the graph, and min is always less than max. Nothing shows up at all. Almost identical code that ignores depth works fine for 2D. I expect the GL_LINES part to draw the 3 axes of the graph, x,y,z. Any ideas why it doesn't work?
Advertisement
You seem to have made a mistake in your drawing code:
// Your code:glVertex3f(GetHorizontalMin(), GetVerticalMin(), GetDepthMin());glVertex3f(GetHorizontalMax(), GetVerticalMin(), GetDepthMin());glVertex3f(GetHorizontalMin(), GetVerticalMin(), GetDepthMin());glVertex3f(GetHorizontalMin(), GetHorizontalMin(), GetDepthMin()); // <-- mistakeglVertex3f(GetHorizontalMin(), GetVerticalMin(), GetDepthMin());glVertex3f(GetHorizontalMin(), GetHorizontalMin(), GetDepthMax()); // <-- mistake// should be:glVertex3f(GetHorizontalMin(), GetVerticalMin(), GetDepthMin());glVertex3f(GetHorizontalMax(), GetVerticalMin(), GetDepthMin());glVertex3f(GetHorizontalMin(), GetVerticalMin(), GetDepthMin());glVertex3f(GetHorizontalMin(), GetVerticalMax(), GetDepthMin()); glVertex3f(GetHorizontalMin(), GetVerticalMin(), GetDepthMin());glVertex3f(GetHorizontalMin(), GetVerticalMin(), GetDepthMax());

Note that the 3rd line (the z-axis) is never visible because there is no perspective when using glOrtho...

Tom
As I understand it, there's a difference between lack of perspective and lack of depth. If you use glOrtho2D or glOrtho with -1 and 1 for zfar and znear you basically have a 2D plane to draw on. But from what I've read glOrtho just means things farther away don't get shrunk -- but you can still have depth. Otherwise why would people say you can use glOrtho for isometric games? Maybe someone can correct my understanding?

I fixed the nonexisting line though, but still nothing is drawn in the viewport:

	glBegin(GL_LINES);		glVertex3f(GetHorizontalMin(), GetVerticalMin(), GetDepthMin());		glVertex3f(GetHorizontalMax(), GetVerticalMin(), GetDepthMin());		glVertex3f(GetHorizontalMin(), GetVerticalMin(), GetDepthMin());		glVertex3f(GetHorizontalMin(), GetVerticalMax(), GetDepthMin());		glVertex3f(GetHorizontalMin(), GetVerticalMin(), GetDepthMin());		glVertex3f(GetHorizontalMin(), GetVerticalMin(), GetDepthMax());	glEnd();
What do you have your glOrtho() set to? Post some code.

Use this

gluOrtho2D(0.0, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0);


This is equivalent to calling glOrtho with near = –1 and far = 1.

If you want to do some 3D objects and rotate them in a Ortho view do this

glOrtho(0.0, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0, -100.0, 100.0);


HTH...
Quote:Original post by Jengu
As I understand it, there's a difference between lack of perspective and lack of depth. If you use glOrtho2D or glOrtho with -1 and 1 for zfar and znear you basically have a 2D plane to draw on. But from what I've read glOrtho just means things farther away don't get shrunk -- but you can still have depth. Otherwise why would people say you can use glOrtho for isometric games? Maybe someone can correct my understanding?

Your understanding seems correct. glOrtho creates a 3D space without perspective (i.e. an object in the back of the space are just as large on the screen as it would be in the front). That's why you can't see the z-axis. It will go straight
into the screen drawing a single point at best.

Quote:Original post by Jengu
I fixed the nonexisting line though, but still nothing is drawn in the viewport:

*** code ***

I'm not sure what you mean with nonexisting line. My fix makes sure your three lines are in view. I actually tried running your code (using -1.0f for all Min() and 1.0f for all Max()) and it worked. It did simplify it a bit, like this:
	glMatrixMode(GL_PROJECTION);	glLoadIdentity(); 	glOrtho(GetHorizontalMin(), GetHorizontalMax(), GetVerticalMin(), GetVerticalMax(), GetDepthMin(), GetDepthMax()); 	glMatrixMode(GL_MODELVIEW);	glPushMatrix();	glLoadIdentity(); 	glColor4ub(255, 255, 0, 255);	glBegin(GL_LINES);            glVertex3f(GetHorizontalMin(), GetVerticalMin(), GetDepthMin());            glVertex3f(GetHorizontalMax(), GetVerticalMin(), GetDepthMin());            glVertex3f(GetHorizontalMin(), GetVerticalMin(), GetDepthMin());            glVertex3f(GetHorizontalMin(), GetVerticalMax(), GetDepthMin());             glVertex3f(GetHorizontalMin(), GetVerticalMin(), GetDepthMin());            glVertex3f(GetHorizontalMin(), GetVerticalMin(), GetDepthMax());	glEnd(); 	glPopMatrix();	glMatrixMode(GL_MODELVIEW);

This modified code worked perfectly, so if it doesn't work for you like this the problem must lie elswhere (for example in the viewport code that I completely removed).
Take special note of the line color that I changed to yellow. Blue happens to be the color of my WinXP borders, which made them hard to see.

Tom
I took a look at your code and you seem to be right. If you use -1 and 1, it does show up. But try substituting 1 and 100. Poof, the lines disappear. Why?

From the redbook: "Both near and far may be positive, negative, or even set to zero. However, near and far should not be the same value."

I did some testing, and it seems whenever min is greater than 0, nothing shows up.
Quote:Original post by Jengu
I took a look at your code and you seem to be right. If you use -1 and 1, it does show up. But try substituting 1 and 100. Poof, the lines disappear. Why?

From the redbook: "Both near and far may be positive, negative, or even set to zero. However, near and far should not be the same value."

I did some testing, and it seems whenever min is greater than 0, nothing shows up.

It seems that the z-values for the vertex calls must be inverted. The z-range for the lines is -1 to -100 (rather than the 1-100 specified for near and far). The reason is mentioned in the same section of the redbook that you quoted (note the '-' signs in front of near and far):
Quote:Redbook
Creates a matrix for an orthographic parallel viewing volume and multiplies the current matrix by it. The near clipping plane is a rectangle with the lower left corner at (left, bottom, -near) and the upper right corner at (right, top, -near). The far clipping plane is a rectangle with corners at (left, bottom, -far) and (right, top, -far). Both near and far can be positive or negative.


I believe a simple glScalef(1,1,-1) will fix your problem:
glScalef(1.0f, 1.0f, -1.0f);glBegin(GL_LINES);    glVertex3f(GetHorizontalMin(), GetVerticalMin(), GetDepthMin());    glVertex3f(GetHorizontalMax(), GetVerticalMin(), GetDepthMin());    glVertex3f(GetHorizontalMin(), GetVerticalMin(), GetDepthMin());    glVertex3f(GetHorizontalMin(), GetVerticalMax(), GetDepthMin());     glVertex3f(GetHorizontalMin(), GetVerticalMin(), GetDepthMin());    glVertex3f(GetHorizontalMin(), GetVerticalMin(), GetDepthMax());glEnd();


Tom

This topic is closed to new replies.

Advertisement