Creation d'un objet 3d : le torus

Description

voila ce que l'on peut faire avec seulement des triangles !

Source / Exemple :


#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glaux.h>
#include <math.h>

//------------------------------------------------------------
#define PI		3.1415926535897932384626433832795
//------------------------------------------------------------
#define EPSILON                 0.001
#define TIME_PER_TURN           10
//------------------------------------------------------------
#define MY_TORUS                1
//------------------------------------------------------------
void RePaint(HDC DC,double zoom,double theta,double phi)
{
static double q;

if(TRUE)
  {
  static DWORD  oldCall;
  DWORD t;

  t = GetTickCount();

  q += (360.*((double)(t - oldCall)))/(1000.*((double)TIME_PER_TURN));

  oldCall = t;
  }

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);  
glLoadIdentity();
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);

glPushAttrib(GL_CURRENT_BIT);

// position de l'oeil
gluLookAt(zoom*cos(theta)*cos(phi),zoom*sin(theta)*cos(phi),zoom*sin(phi),0,0,0,cos(theta-PI)*cos(PI/2.-phi),sin(theta-PI)*cos(PI/2.-phi),sin(PI/2.-phi));

// les axes
if(TRUE)
  {
  glColor3d(1.,1.,1.); // blanc
  glBegin(GL_LINES);

    glVertex3d(-500,0,0);
    glVertex3d(+500,0,0);

    glVertex3d(0,-500,0);
    glVertex3d(0,+500,0);

    glVertex3d(0,0,-500);
    glVertex3d(0,0,+500);

  glEnd();
  }

// les torus
if(TRUE)
  {
  glPushMatrix();
    glCallList(MY_TORUS);
  glPopMatrix();
  }

// fin du dessinage
glPopAttrib();
glPopMatrix();

SwapBuffers(DC);
}
//------------------------------------------------------------
void InitPixelFormat(HDC hdc)
{ 
PIXELFORMATDESCRIPTOR pfd = {sizeof (PIXELFORMATDESCRIPTOR),1,PFD_SUPPORT_OPENGL | PFD_TYPE_RGBA | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER,16,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0};
SetPixelFormat(hdc,ChoosePixelFormat(hdc,&pfd),&pfd);
}
//------------------------------------------------------------
static void CalcPointTorus(double R,double r,double t,double a,double z)
{
glVertex3d(
          (R + r*cos(a))*cos(t),
          (R + r*cos(a))*sin(t),
          z+r*sin(a)
          );
}
//------------------------------------------------------------
// creer un torus d'axes z de grand rayon <R> et de petit rayon <r>
// le commencement de fait a z=0 et la fin a z=<dz>
void MyCreateTorus(double R,double r,int nVertex,int slices,double angleBegin,double angleEnd,double dz)
{
double theta,stepTheta,oldTheta;
double stepAlpha;
double z,oldZ,stepDz;

stepTheta = (angleEnd - angleBegin)/((double)nVertex);
stepAlpha = 2.*PI/slices;
stepDz    = dz/((double)nVertex);

glBegin(GL_TRIANGLE_STRIP);

oldTheta = angleBegin;
oldZ     = 0.;
z        = stepDz;

for(theta=angleBegin+stepTheta;theta<=angleEnd+EPSILON;theta+=stepTheta)
  {
  double a,b; // alpha,beta

  for(a=0.,b=0.5*stepAlpha;a<=2.*PI+EPSILON;a+=stepAlpha,b+=stepAlpha)
    {
    CalcPointTorus(R,r,oldTheta ,b,oldZ);
    CalcPointTorus(R,r,theta    ,a,z);
    }

  oldTheta  = theta;
  oldZ      = z;
  z        += stepDz;
  }

glEnd();
}
//------------------------------------------------------------  
LRESULT CALLBACK WindowProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam)
{
static HDC            hdc;
static HGLRC          hrc;
static int            cxClient,cyClient;
static double         zoom,theta,phi,_theta,_phi;
static BOOL           isMouseDown;
static int            xMouseStart,yMouseStart;

// traitement des messages
switch (iMsg)
  {
  case WM_CREATE:
    {
    hdc=GetDC(hwnd);
    InitPixelFormat(hdc);
    hrc = wglCreateContext(hdc);
    wglMakeCurrent(hdc,hrc);
    glEnable(GL_DEPTH_TEST); 
    glClearColor(0,0,0,0); 

    // creation des torus
    if(TRUE)
      {
      // support
      glNewList(MY_TORUS,GL_COMPILE);

        // premier figure
        glColor3d(1.,1.,0.1); // jaune
        glPushMatrix();
          MyCreateTorus(125.,4.,32,10,0.,2.*PI,0.);
          glRotated(90.,1.,0.,0.);
          MyCreateTorus(125.,4.,32,10,0.,2.*PI,0.);
          glRotated(90.,0.,1.,0.);
          MyCreateTorus(125.,4.,32,10,0.,2.*PI,0.);
        glPopMatrix();

        glColor3d(0.1,1.,0.1); // vert
        glPushMatrix();
          glTranslated(250.,0.,-250.);
          MyCreateTorus(125.,4.,200,10,0.,8.*PI,500.);
        glPopMatrix();

        glColor3d(1.,0.1,0.1); // rouge
        glPushMatrix();
          MyCreateTorus(500.,4.,32,10,0.,PI,0.);
          glRotated(120.,1.,0.,0.);
          MyCreateTorus(500.,4.,32,10,0.,PI,0.);
          glRotated(120.,1.,0.,0.);
          MyCreateTorus(500.,4.,32,10,0.,PI,0.);
        glPopMatrix();

        glColor3d(0.1,0.1,1.); // bleu
        glPushMatrix();
          glTranslated(-250.,0.,0.);
          glPushMatrix();
            glTranslated(0.,0.,-100.);
            MyCreateTorus(100.,4.,32,10,0.,2.*PI,0.);
            glTranslated(0.,0.,200.);
            MyCreateTorus(100.,4.,32,10,0.,2.*PI,0.);
          glPopMatrix();
          glRotated(90.,1.,0.,0.);
          glPushMatrix();
            glTranslated(0.,0.,-100.);
            MyCreateTorus(100.,4.,32,10,0.,2.*PI,0.);
            glTranslated(0.,0.,200.);
            MyCreateTorus(100.,4.,32,10,0.,2.*PI,0.);
          glPopMatrix();
          glRotated(90.,0.,1.,0.);
          glPushMatrix();
            glTranslated(0.,0.,-100.);
            MyCreateTorus(100.,4.,32,10,0.,2.*PI,0.);
            glTranslated(0.,0.,200.);
            MyCreateTorus(100.,4.,32,10,0.,2.*PI,0.);
          glPopMatrix();
        glPopMatrix();

      glEndList();
      }
    

    zoom  = 1400.;
    // on veut les coordonnees de l'ecran (meme direction)
    theta = -PI/2;
    phi   = -PI/2;

    break;
    }
  case WM_SIZE:
    {
    double r;

    cxClient = LOWORD(lParam);  cxClient = (cxClient ? cxClient : 1);
    cyClient = HIWORD(lParam);  cyClient = (cyClient ? cyClient : 1);
    glViewport(0,0,cxClient,cyClient);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    if(1 > (r = (float)(cxClient)/(float)(cyClient)))
      {
      //r = (float)(cyClient)/(float)(cxClient);
      }

    gluPerspective(45.,r,100.,100000.);
    break;
    }
  case WM_CHAR:
    {
    switch((char)wParam)
      {
      case 'a':
        {
        zoom -= 10.;
        return 0;
        }
      case 'q':
        {
        zoom += 10.;
        return 0;
        }
      }
    break;
    }
  case WM_LBUTTONDOWN:
    {
    xMouseStart = LOWORD(lParam);
    yMouseStart = HIWORD(lParam);
    // on sauvegarde les angles
    _theta  = theta;
    _phi    = phi;
    isMouseDown = TRUE;
    SetCapture(hwnd);
    return 0;
    }
  case WM_LBUTTONUP:
    {
    if(isMouseDown)
      {
      ReleaseCapture();
      isMouseDown = FALSE;
      }
    return 0;
    }
  case WM_MOUSEMOVE:
    {
    if(isMouseDown)
      {
      int x,y;
      x = (int) (__int16) LOWORD(lParam);
      y = (int) (__int16) HIWORD(lParam);

      // attention, comme les coordonnees en Y
      // client sont inversees (de haut en bas)
      // il faut faire -, et non +
      // comme pout le X
      theta = _theta + ((xMouseStart - x)*2*PI)/(double)cxClient;
      phi   = _phi   - ((yMouseStart - y)*2*PI)/(double)cyClient;
      }
    return 0;
    }
  case WM_PAINT:
    {
    RePaint(hdc,zoom,theta,phi);
    return 0;
    }
  case WM_DESTROY:
    {

    glDeleteLists(MY_TORUS,1);

    wglMakeCurrent(NULL, NULL);
    wglDeleteContext(hrc);
    ReleaseDC(hwnd,hdc);
    PostQuitMessage(0);
    break;
    }
  }
return DefWindowProc(hwnd,iMsg,wParam,lParam);
} 
//------------------------------------------------------------
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int CmdShow)
{
WNDCLASS  wc;
MSG       msg;
HWND      hWnd;

wc.style          = CS_OWNDC;
wc.lpfnWndProc    = WindowProc;
wc.cbClsExtra     = 0;
wc.cbWndExtra     = 0;
wc.hInstance      = hInstance;
wc.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground  = NULL;
wc.lpszMenuName   = NULL;
wc.lpszClassName  = "jcdTorus";

RegisterClass(&wc);

hWnd = CreateWindow("jcdTorus","Objet 3D en OpenGL : Torus",
                    WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                    CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
                    NULL,NULL,hInstance,NULL
                    );

ShowWindow(hWnd,SW_SHOWMAXIMIZED);
UpdateWindow(hWnd);

while(GetMessage(&msg,NULL,0,0))
  {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
  }
  
return 0;
}

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.