Texte en opengl

Soyez le premier à donner votre avis sur cette source.

Vue 4 472 fois - Téléchargée 395 fois

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

Ajouter un commentaire Commentaires
Messages postés
1329
Date d'inscription
vendredi 15 août 2003
Statut
Membre
Dernière intervention
16 juin 2010
2
ben ouais les tga fonts! yen a de déja toutes faites, et c'est itou pour le code, voir hoverbike et Cube (Belzel; je connais plus l'adresse dee son site.);c'est pour ecrire en 2D, mais doit pas y avoir de pb pour le mettre en 3D
Messages postés
3006
Date d'inscription
dimanche 14 avril 2002
Statut
Membre
Dernière intervention
31 décembre 2008

suis déçu, tu utilises les fct de l'API windows, j'espérais trouver une nvlle solution, parce que celle-là est déjà sur le site de NeHe, et ne me satisfait pas, dommage :-(

note aux gens qui comme moi cherchent autre chose, je me suis rabattu sur les bitmap fonts (en m'appropriant l'idée de Funto ;-)), je crée une texture de 16 * 16 cases de 16*16 pixels, chaque case contient le caractère correspondant au numéro de sa case en ASCII, puis j'ai écrit une classe qui s'occupe de sélectionner la bonne partie de la texure et de la coller au bon endroit. c'est pas dur à coder, ça m'a pris qq ch comme 2-3 heures, mais qu'est-ce que c'est BOURRANT de faire les textures O_o j'ai généré les miens avec une appli console, mais il faut tjs ajuster!

si qq un connait mieux, c'est bienvenu! (en portable, tjs)
Messages postés
55
Date d'inscription
lundi 15 septembre 2003
Statut
Membre
Dernière intervention
11 mai 2008

Excelent travaille , depuis le temp que je cherche une bonne facon de gerer du test en openGL merci mr !!
Messages postés
3011
Date d'inscription
jeudi 26 septembre 2002
Statut
Membre
Dernière intervention
27 novembre 2004
8
salut , c'est trop bien mais il faut absolument que tu rajoute une lumiere car ca rendra 10 fois mieux avec les lettres en reliefs

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.