2009-06-29 11 views
15

Je suis un débutant en programmation OpenGL avec C++ et pas très bon en mathématiques. Y a-t-il un moyen simple d'avoir une projection isométrique? Je veux dire the true isometric projection, pas la projection orthogonale générale.vraie projection isométrique avec opengl

(projection isométrique se produit que lorsque les projections de l'unité X, Y et vecteurs Z sont de même longueur et les angles entre eux sont exactement 120 degrés.)

extraits de code sont très appréciés ..

+0

double de http://www.allegro.cc/forums/thread/600737 – aib

Répondre

26

Essayez d'utiliser 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(); 

Résultats dans

alt text

Nous pouvons dessiner un cube pour vérifier que les lignes parallèles sont en effet parallèles

glPushMatrix(); 
glTranslated(0.5, 0.5, 0.5); 
glColor3d(0.5, 0.5, 0.5); 
glutWireCube(1); 
glPopMatrix(); 

alt text

+0

Cela vous ne donnera pas une projection isométrique, parce que les lignes parallèles, par exemple le long des axes x et y, n'apparaîtra parallèle, quand ils devraient en fait. –

+0

regardez l'image sur l'article wikipedia qui a été liée aussi dans la question, cela ressemble exactement à cette projection. Toutes les lignes parallèles apparaîtront parallèles car il s'agit d'une projection orthographique (http://en.wikipedia.org/wiki/Orthographic_projection). Les axes x et y ne sont pas parallèles. – cobbal

+0

Je ne veux pas dire que les axes x et y sont parallèles, mais que les lignes parallèles à l'axe x doivent apparaître parallèles dans une projection isométrique (et je ne pense pas qu'elles le seront dans le vôtre), et de même dans la direction y. –

3

Peut-être que je ne suis pas tout à fait grokking correctement les maths, mais ne pouvait pas vous suffit de positionner votre appareil photo comme explique dans ce lien Wikipédia et utilise une projection orthogonale standard?

Même si ce n'est pas la même chose, la pile de projection dépend entièrement de vous.

glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
// your isometric matrix here (see math on Wikipedia) 
glMatrixMode(GL_MODELVIEW); 
7

Une projection isométrique consiste simplement à utiliser une projection orthographique avec un angle de rotation spécifique.

Vous devriez être en mesure de choisir l'une des 8 orientations potentielles, avec une projection orthographique, et obtenir une vue isométrique parfaite de votre modèle. Il suffit de suivre les maths dans votre article Wiki référencé pour configurer la matrice de vue, et faire une projection orthographique pour votre matrice de projection, et vous êtes tous ensemble.

0

Si vous ne souhaitez pas utiliser GLU, voici les os nus en utilisant 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); 
} 

et appeler quelque chose comme ça

gl_enter_2_5d_mode() 
test() 
gl_leave_2_5d_mode() 

si vous voulez basculer entre les modes 2D et 2.5D (donc vous pouvez dessiner votre interface utilisateur) puis j'ai des fonctions similaires pour entrer et quitter le mode 2d par exemple

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