Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

true isometric projection with opengl

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..

like image 573
someone Avatar asked Jun 29 '09 16:06

someone


People also ask

What is OpenGL projection?

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.

Why is isometric view 30 degrees?

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.

What is true length in isometric projection?

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.

What are the 3 isometric views?

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.


4 Answers

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

alt text

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();

alt text

like image 99
cobbal Avatar answered Sep 19 '22 11:09

cobbal


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.

like image 20
Reed Copsey Avatar answered Sep 19 '22 11:09

Reed Copsey


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);
like image 33
Bob Somers Avatar answered Sep 22 '22 11:09

Bob Somers


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();
}
like image 27
Goblinhack Avatar answered Sep 21 '22 11:09

Goblinhack