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