Texte en opengl

Description

voila, cette source permet d'ecrire tu texte en 3D

Source / Exemple :


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

#ifndef _UTIL_H_
  #include "util.h"
#endif // _UTIL_H_

#ifndef _MATH_H_
  #include "math.h"
#endif // _MATH_H_

//------------------------------------------------------------
typedef struct tagRECT_FLOAT
  {
  FLOAT x,y,cx,cy;
  }RECT_FLOAT,*P_RECT_FLOAT,**PP_RECT_FLOAT;

//------------------------------------------------------------
#define EPSILON                 0.001
#define TIME_PER_TURN           10
//------------------------------------------------------------
#define MY_NUM_NAMES        4
#define MY_NUM_STRING       1000
//------------------------------------------------------------
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));

glBegin(GL_LINES);
  glColor3d(1.,1.,1.);
  // axes
  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 noms
if(TRUE)
  {
  glPushMatrix();
    glRotated(q,1,0,0);
    glCallList(MY_NUM_NAMES);
  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);
}
//------------------------------------------------------------  
void CreatePave(double a,double b,double c)
{
glBegin(GL_QUAD_STRIP);
  glVertex3d(-a,+b,-c);
  glVertex3d(+a,+b,-c);

  glVertex3d(-a,-b,-c);
  glVertex3d(+a,-b,-c);

  glVertex3d(-a,-b,+c);
  glVertex3d(+a,-b,+c);

  glVertex3d(-a,+b,+c);
  glVertex3d(+a,+b,+c);

  glVertex3d(-a,+b,-c);
  glVertex3d(+a,+b,-c);

glEnd();

glBegin(GL_QUADS);
  glVertex3d(-a,-b,-c);
  glVertex3d(-a,+b,-c);
  glVertex3d(-a,+b,+c);
  glVertex3d(-a,-b,+c);

  glVertex3d(+a,-b,-c);
  glVertex3d(+a,+b,-c);
  glVertex3d(+a,+b,+c);
  glVertex3d(+a,-b,+c);
glEnd();
}
//------------------------------------------------------------
int MyCalcText(GLYPHMETRICSFLOAT *pGmf,char *text,P_RECT_FLOAT pRect)
{
int    len;
FLOAT  cx,cy;
FLOAT  tX,tY; // tranlation

len = 0;

cx        = 0.;
cy        = 0.;
tX        = 0.;
tY        = 0.;

while(*text != '\0')
  {
  GLYPHMETRICSFLOAT *p;
  p = pGmf + ((unsigned char)*text);
  
  cx += p->gmfCellIncX;
  cy  = max(cy,p->gmfBlackBoxY);
  tY  = min(tY,(p->gmfptGlyphOrigin.y)-cy);
  
  text  ++;
  len   ++;
  }

// l'eventuelle translation
pRect->x  = tX;
pRect->y  = tY;
// la largeur
pRect->cx = cx;
pRect->cy = cy;

return len;
}
//------------------------------------------------------------  
void PrintTextInBox(GLYPHMETRICSFLOAT *pGmf,char *text,FLOAT trueCx,FLOAT trueCy)
{
int         len;
RECT_FLOAT  rc;

glPushMatrix();
  len = MyCalcText(pGmf,text,&rc);
  glTranslated(-rc.x,-rc.y,0.);
  glScalef(trueCx/rc.cx,trueCy/rc.cy,1.);
  glListBase(MY_NUM_STRING);
  glCallLists(len,GL_UNSIGNED_BYTE,text);
glPopMatrix();
}
//------------------------------------------------------------  
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;
static HFONT          font,oldFont;

// traitement des messages
switch (iMsg)
  {
  case WM_CREATE:
    {
    GLYPHMETRICSFLOAT gmf[256];

    hdc=GetDC(hwnd);
    InitPixelFormat(hdc);
    hrc = wglCreateContext(hdc);
    wglMakeCurrent(hdc,hrc);
    glEnable(GL_DEPTH_TEST); 
    glClearColor(0,0,0,0); 

    font = CreateFont(
                      40,
                      30,
                      0,        //  inclinaison du texte
                      0,        //  genre 'italique programmable'
                      1,        //  graisse
                      FALSE,    //  italic
                      FALSE,    //  souligne
                      FALSE,    //  barre
                      DEFAULT_CHARSET,
                      OUT_DEFAULT_PRECIS,
                      CLIP_DEFAULT_PRECIS,
                      DEFAULT_QUALITY,
                      VARIABLE_PITCH+FF_SWISS,
                      "Arial"
                      );
    Assert(NULL != font);
    oldFont = SelectObject(hdc,font);

    // create bitmaps for the device context font's first 256 glyphs 
    if(!wglUseFontOutlines(
                            hdc,
                            0,
                            256,
                            1000,
                            0.01F,
                            5.F,
                            WGL_FONT_POLYGONS,
                            gmf
                            )
      )
      {
      Error((NULL));
      }
      

    // creation des noms
    if(TRUE)
      {
      char *tabName[] =  {
                          "jcdJCD",
                          "Texte en OpenGL",
                          "www.cppfrance.com",
                          "Vive le langage C/C++"
                          };
      int i;

      glNewList(MY_NUM_NAMES,GL_COMPILE);

        glPushMatrix();
          glColor3d(1.,0.,0.);
          CreatePave(500.,70.,70.);
        glPopMatrix();

        glColor3d(1.,1.,1.);

        for(i=0;i<4;i++)
          {
          glPushMatrix();
            glRotated(((double)i)*90.,1.,0.,0.);
            glTranslated(-450.,-40.,75.);
            PrintTextInBox(gmf,tabName[i],900.,80.);
          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:
    {
    DeleteObject(SelectObject(hdc,oldFont));

    glDeleteLists(MY_NUM_NAMES    ,1);
    // delete our 256 glyph display lists 
    glDeleteLists(MY_NUM_STRING, 256); 

    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;

srand((unsigned)GetTickCount());

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  = "jcdText";

RegisterClass(&wc);

hWnd = CreateWindow("jcdText","Texte en OpenGL",
                    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;
}

Conclusion :


les lettres avec des "pieds" comme j,q,p .... ne sont pas pris en compte, il ne sont pas dans le rectangle

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.