Jul 03, 2024

Wiki

Python

Aide

edit SideBar

Search

Placer Des Volumes


Introduction

Si OpenGL vous autorise à réaliser des figures planes, c'est bien sûr dans l'espace que toute la puissance de cette bibliothèque apparaît.

Cette représentation dans l'espace s'effectue en trois partie :

  1. modéliser l'objet et définir la position de la caméra,
  2. définir les textures de l'objet,
  3. et préciser enfin les options de la caméra (projection et cadrage).

En effet, pouvoir placer des objets à trois dimension dans la scène c'est bien, mais pouvoir se déplacer dans ladite scène, c'est mieux : un cube vu de face apparaît comme un carré, et il est donc inutile de travailler avec trois coordonnées et huit sommets, si on ne peut pas se déplacer autour du cube.

Ainsi, en OpenGL, on peut :

  • mettre les volumes à leur place dans la scène,
  • se déplacer dans ladite scène.

L'exemple du cube

Pour illustrer cela, on commence par placer un cube de de côté 1.0 centré à l'origine (c'est le programme cube.py) :

  from OpenGL.GL import *
  from OpenGL.GLUT import *
  from OpenGL.GLU import *
  import sys

  def ecran():
      glClearColor(0.5,0.5,0.5,0.5)
      glClear(GL_COLOR_BUFFER_BIT)
      glutWireCube(1.0)
      glFlush()

  def main():
      glutInit(sys.argv)
      glutInitDisplayMode(GLUT_RGBA)
      glutInitWindowPosition(100,100)
      glutInitWindowSize(320,320)
      glutCreateWindow("Un cube")
      glutDisplayFunc(ecran)
      glutMainLoop()

  main()

Le fond d'écran est gris (glClearColor(0.5,0.5,0.5,0.5)).

Comme on regarde le cube de face, il apparaît comme un carré.

C'est pourquoi il va falloir déplacer notre point de vue (notre caméra).

Changer le point de vue

Pour cela, on utilise gluLookAt(), qui permet de changer de point de vue (on étudiera précisément cette fonction dans un prochain TP), et on spécifie le mode de vision (perspective), pour donner une impression de 3d.

Il faut donc insérer une ligne dans la fonction ecran(), comme suit (c'est le programme cube1.py) :

  def ecran():
      glClearColor(0,0,0,0)
      glClear(GL_COLOR_BUFFER_BIT)
      glMatrixMode(GL_MODELVIEW)
      glLoadIdentity()
      gluLookAt(-3,0,0,0,0,0,0,1,0)
      glColor3d(1,0,0)
      glutWireCube(1.0)
      glFlush()

...et préciser encore que la vue doit être en perspective (et accessoirement définir les actions à réaliser en cas de redimensionnement de la fenêtre) comme cela :

  def reshape(*args):
      glViewport(0,0,args[0],args[1])
      glMatrixMode(GL_PROJECTION)
      glLoadIdentity()
      gluPerspective(60.0,float(args[0])/args[1],1.,10.)

en n'oubliant pas dans le main() :

  glutReshapeFunc(reshape)

Tout cela peut paraître compliqué, mais le résultat est ce que l'on souhaite :

Les prochains tps reviendront sur le sens de la fonction reshape(), mais pour l'instant nous nous occupons de placer des objets dans la scène, et non pas de la visualisation de ces objets.

Autres figures 3D

glutWireCube() n'est pas la seule fonction de ce genre. On trouve de même :

  • glutWireSphere() pour la sphère,
  • glutWireTorus() pour le tore,
  • glutWireCone() pour le cône,
  • glutWireDodecahedron() pour le dodécaèdre (polyèdre régulier à douze faces),
  • glutWireOctahedron() pour l'octaèdre (polyèdre régulier à huit faces),
  • glutWireTetrahedron() pour le tétraèdre (polyèdre régulier à quatre faces,
  • glutWireIcosahedron() pour l'icosaèdre,
  • et enfin glutWireTeapot() pour la théière (teapot.py) :

De plus, on peut remplacer, dans ces fonctions, Wire (c'est-à-dire en fil de fer) par Solid (en faces pleines).

Translations et rotations

Ces différents objets sont placés à l'origine dans notre scène

Si on veut les positionner ailleurs, il faut avoir recours aux applications de translation et de rotation : glTranslatef() et glRotatef().

Ainsi, pour poser une théière sur un cube (c'est le programme cubeEtPot.py) :

  def ecran():
      glClearColor(0,0,0,0)
      glClear(GL_COLOR_BUFFER_BIT)
      glMatrixMode(GL_MODELVIEW)
      glLoadIdentity()
      gluLookAt(0.4,0.4,3.,0.,0.,0.,0.,1.,0.)
      glColor3d(1,0,0)
      glutWireCube(1.0)
      glTranslatef(0.,0.7,0.)
      glutSolidTeapot(0.3)
      glFlush()

Ce qui donne :

Des Polyèdres

Une autre manière de procéder pour représenter des objets dans l'espace est d'utiliser comme précédemment :

  • un glBegin(mode),
  • suivi d'une liste de sommets (glVertex3f()),

mode définit la méthode pour relier lesdits sommets.

Par exemple, considérons le programme pyramide.py, qui représente une pyramide à base carrée :

On y trouve les différents triangles définis à la suite les uns des autres, et bien positionnés dans l'espace, comme suit

  glBegin(GL_LINE_LOOP)
  glVertex3f(0.5,0.5,0.0)
  glVertex3f(0.,0.,1.0)
  glVertex3f(0.5,-0.5,0.0)
  glVertex3f(0.5,0.5,0.0)
  glVertex3f(-0.5,0.5,0.0)
  glVertex3f(0.,0.,1.0)
  glVertex3f(-0.5,-0.5,0.0)
  glVertex3f(-0.5,0.5,0.0)
  glVertex3f(0.5,0.5,0.0)
  glVertex3f(0.5,-0.5,0.0)
  glVertex3f(-0.5,-0.5,0.0)
  glVertex3f(-0.5,0.5,0.0)
  glEnd()

Dans ce programme, différents points de vue sont accessibles : la variable pv passée en argument de gluLookAt() est modifiable par le clavier...

  def clavier(*args):
      global pv # Le point de vue
      if args[0] == 'q':
          sys.exit()
      elif args[0] == 'a':
          pv = (-2.,-1.,.0,0.,0.,0.,0.,0.,1.)
      elif args[0] == 'z':
          pv = (-2.,-1.,.5,0.,0.,0.,0.,0.,1.)
      elif args[0] == 'e':
          pv = (-2.,-1.,1.5,0.,0.,0.,0.,1.,1.)
      elif args[0] == 'r':
          pv = (-3.,-1.,.5,0.,0.,0.,0.,0.,1.)
      glutPostRedisplay()

Les touches a, z, e, et r changent ainsi pv (le point de vue).

Autres figures 3D

Certaines bibliothèques OpenGL possèdent plus de primitives graphiques que d'autres. Ainsi, si vous utilisez la bibliothèque OpenGLUT fournie dans la distribution Ubuntu GNU/Linux, vous n'aurez pas les fonctions glutWireCylinder(), ou encore glutSolidSierpinskiSponge(), par exemple.

En fait, OpenGL s'occupe de gérer le rendu d'une scène 3d, en permettant d'avoir un certain éclairage, la présence de brouillard, etc. mais ça n'est pas un logiciel de dessin : son rôle n'est pas de créer des objets 3d, mais de s'occuper de la scène contenant ces objets (qui sont fait dans la pratique sous Direct3d, ou Blender).

Vous pouvez à présent vous entrainer à placer ces figures élémentaires sur la scène, en ayant recours à glTranslatef() et glRotatef().

Page Actions

Recent Changes

Group & Page

Back Links