I am a newbie in OpenGL programming with C++ and not very good at mathematics. Is there a simple way to have isometric projection?
I mean the true isometric projection, not the general orthogonal projection.
(Isometric projection happens only when projections of unit X, Y and Z vectors are equally long and angles between them are exactly 120 degrees.)
Code snippets are highly appreciated..
A 3D scene rendered by OpenGL must be projected onto the computer screen as a 2D image. GL_PROJECTION matrix is used for this projection transformation. First, it transforms all vertex data from the eye coordinates to the clip coordinates.
Isometric drawing is a form of 3D drawing, which is set out using 30-degree angles. It is a type of axonometric drawing so the same scale is used for every axis, resulting in a non-distorted image.
3. The length in isometric drawing of line is 20 cm. What is the true length of it? Explanation: The ratio of isometric length to true length is 0.815 so here it is given isometric length of 20 cm.
An isometric drawing creates a top and two side views. The views are formed by using three axes. The three axes are formed from the predetermined vertical line and the connected horizontal lines. The three dimensions shown in an isometric drawing are width, height, and depth.
Try using gluLookAt
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
/* use this length so that camera is 1 unit away from origin */
double dist = sqrt(1 / 3.0);
gluLookAt(dist, dist, dist, /* position of camera */
0.0, 0.0, 0.0, /* where camera is pointing at */
0.0, 1.0, 0.0); /* which direction is up */
glMatrixMode(GL_MODELVIEW);
glBegin(GL_LINES);
glColor3d(1.0, 0.0, 0.0);
glVertex3d(0.0, 0.0, 0.0);
glVertex3d(1.0, 0.0, 0.0);
glColor3d(0.0, 1.0, 0.0);
glVertex3d(0.0, 0.0, 0.0);
glVertex3d(0.0, 1.0, 0.0);
glColor3d(0.0, 0.0, 1.0);
glVertex3d(0.0, 0.0, 0.0);
glVertex3d(0.0, 0.0, 1.0);
glEnd();
glFlush();
Results in
We can draw a cube to check that parallel lines are indeed parallel
glPushMatrix();
glTranslated(0.5, 0.5, 0.5);
glColor3d(0.5, 0.5, 0.5);
glutWireCube(1);
glPopMatrix();
An isometric projection is just a matter of using an orthographic projection with a specific rotation angle.
You should be able to choose any of the 8 potential orientations, with a orthographic projection, and get a perfect isometric view of your model. Just follow the math in your referenced Wiki article for setting up the view matrix, and do an orthographic projection for your projection matrix, and you're all set.
Maybe I'm not quite grokking the math correctly, but couldn't you just position your camera as it explains in that Wikipedia link and use a standard orthogonal projection?
Even if it's not the same, the projection stack is entirely up to you.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// your isometric matrix here (see math on Wikipedia)
glMatrixMode(GL_MODELVIEW);
If you do not want to use GLU, here is bare bones using glOrtho
void gl_enter_2_5d_mode (void)
{
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
double scale = 50;
glOrtho(-scale,
scale,
-scale * 0.7,
scale * 0.7,
-scale,
scale);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glRotatef(35.264f, 1.0f, 0.0f, 0.0f);
glRotatef(-45.0f, 0.0f, 1.0f, 0.0f);
}
void gl_leave_2_5d_mode (void)
{
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
}
then draw a cube in it
void cube (double size)
{
glBegin(GL_QUADS);
glVertex3f(size,size,size);
glVertex3f(-size,size,size);
glVertex3f(-size,-size,size);
glVertex3f(size,-size,size);
glVertex3f(size,size,-size);
glVertex3f(-size,size,-size);
glVertex3f(-size,-size,-size);
glVertex3f(size,-size,-size);
glVertex3f(size,size,size);
glVertex3f(size,-size,size);
glVertex3f(size,-size,-size);
glVertex3f(size,size,-size);
glVertex3f(-size,size,size);
glVertex3f(-size,-size,size);
glVertex3f(-size,-size,-size);
glVertex3f(-size,size,-size);
glVertex3f(size,size,size);
glVertex3f(-size,size,size);
glVertex3f(-size,size,-size);
glVertex3f(size,size,-size);
glVertex3f(size,-size,size);
glVertex3f(-size,-size,size);
glVertex3f(-size,-size,-size);
glVertex3f(size,-size,-size);
glEnd();
}
void test (void)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBindTexture(GL_TEXTURE_2D, 0);
cube(1.0);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
}
and call something like this
gl_enter_2_5d_mode()
test()
gl_leave_2_5d_mode()
should you want to toggle between 2d and 2.5d (so you can draw your UI) then I have similar functions to enter and leave 2d mode e.g.
void gl_init_2d_mode (void)
{
/*
* Enable Texture Mapping
*/
glEnable(GL_TEXTURE_2D);
/*
* Enable alpha blending for sprites
*/
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
/*
* Setup our viewport
*/
glViewport(0, 0, game.video_pix_width,
game.video_pix_height);
/*
* Make sure we're changing the model view and not the projection
*/
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
/*
* Reset the view
*/
glLoadIdentity();
gl_init_fbo();
}
void gl_enter_2d_mode (void)
{
/*
* Change to the projection matrix and set our viewing volume.
*/
glMatrixMode(GL_PROJECTION);
glPushMatrix();
/*
* Reset the view
*/
glLoadIdentity();
/*
* 2D projection
*/
glOrtho(0,
game.video_gl_width, game.video_gl_height,
0, -1200.0, 1200.0);
/*
* Make sure we're changing the model view and not the projection
*/
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
/*
* Reset the view
*/
glLoadIdentity();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With