3D-tekst
Tekst
Børre Stenseth
Forklaring av>Tekst>Tekst i Windows

Tekst i 3 dimensjoner

Hva
Image390
3D tekst i MSWindows

MS windows har et sterkt apparat for tekstbehandling og et godt fontbegrep. OpenGL på sin side har, som det framgår av OpenGL boka, et svakt apparat for å handtere tekst og fonter. Det er selvsagt ønskelig å kunne utnytte MS Windows muligheter i OpenGL-programmering. Det vil mer konkret si at vi ønsker å lage 3-dimensjonal tekst med basis i MS Windows font og tekst begreper.

Basisfunksjonene

Det er to av de funksjonene som binder OpenGL til MS Windows som er laget for dette formålet: wglUseFontOutlines() og wglUseFontBitmaps(). Vi skal konsenterer oss om den første.

Grunnlaget for det hele er at True-Type fonter i MS Windows er beskrevet ved kurver, enten som polygoner eller som bezierkurver. Dette er grunnlaget for at tegnene kan konstrueres fra samme beskrivelse for forskjellige størrelser og for forskjellige medier.

Det som skjer når vi kaller wglUseFontOutlines() er at det generers OpenGL-displaylister, en for hvert tegn. Når vi siden skal rendre tegnene i et OpenGL-vindu, kaller vi bare opp display-listene. En enkel skisse av aktuell kode:

GLYPHMETRICSFLOAT m_gmf[256];
wglUseFontOutlines(
   hdc,              // en dc med en TT-font selektert
   0,                // første ascii-tegn
   255,              // antall tegn
   LIST_START,       // startpunkt for GL-lister
   0.0f,             // avvik fra høy kvalitet
   m_extrude,        // tegnenes "dybde"
   WGL_FONT_POLYGONS,// polygoner
   m_gmf             // lagrinsstruktur
   )

og bruken i sin enkleste form slik:

  CString S="Hello";
  glListBase(LIST_START) ;
  glCallLists(S.GetLength(),GL_UNSIGNED_BYTE,S);

eller slik:

  CString S="Hello";
  for(int six=0;six< S.GetLength();six++)
    glCallList(LIST_START + __toascii(S[six]));

Koden over genererer 256 tegn. Dette krever både tid og plass. For spesielle formål kan det være hensiktsmessig å generere et begrenset utvalg av tegn.

Se dokumentasjonen av wglUseFontOutlines for å undersøke alle varianter og muligheter.

CAlfa

Det er skrevet en ganske fleksibel C++ klasse for å handtere text, CAlfa. Denne klassen tar seg av oppretting av displaylister, utskrift av teksten, samt en del varianter av layout og fonter.

For mange formål vil det være effektivt både med hensyn på tid og plass og plukke ut og spesialtilpasse kodebiter.

alfa.h

// Alfa.h : header file
// This class has a many functions:
//  - It generates the diplaylists for chars
//      CreateFont3D()
//  - It handles preparation of text:
//      CalculateString(), GetEssayWidth(), GetEssayHeight()
//      SetText(), GetText()
//  - It acually draws the text:
//      Draw3DText()
//  - It administrates change of font:
//      SetNewFont()
//  - It changes the "depth" of the text
//      SetExtrude()
//  - It can handle two different layouts (vert. and hor.):
//      SetLayout();
//  - It can display the text as boxes
//      DrawAsText(),DrawAsBoxes(),IsAsBoxes()
//
//----------------------------------------------------------
//  The text is drawn centered around origo
//  Vertical draw means that the text is drawn
//  in a plane parallell to xy-plane, const z
//  Horizontal (nonvertical) means that the text is drawn
//  in a plane parallell to  xz-plane, const y
//////////////////////////////////////////////////////////

class CAlfa : public CCmdTarget
{
public:
  CAlfa();   // standard constructor

protected:
  // the text
  CString  m_Txt;
  // character depth
  GLfloat m_extrude;
  // the lines
  CStringArray m_TList;
  // logical font
  LOGFONT m_lf;
  // keep lists
  GLYPHMETRICSFLOAT m_gmf[256];
  // start of fontlists
  int m_Start_List;
  // text metrics
  GLfloat m_leading, m_max_line_length;
  // character arrangement
  int m_bVertical;
  // characters may be drwan as boxes
  BOOL m_AsBox;

...

// Implementation
public:
  void CreateFont3D();

  void CalculateString();
  BOOL SetNewFont();

  void Draw3DText();

  GLfloat GetEssayWidth();
  GLfloat GetEssayHeight();

  void SetText(CString &S);
  void GetText(CString &S);

  void SetExtrude(GLfloat ext);
  GLfloat GetExtrude(){return m_extrude;}

  void SetLayout(BOOL bVertical=FALSE);
  BOOL GetLayout(){return m_bVertical;}

  void DrawAsText(){m_AsBox=FALSE;}
  void DrawAsBoxes(){m_AsBox=TRUE;}
  BOOL IsAsBoxes(){return m_AsBox;}

...
};

alfa.cpp

alfa.cpp

alfa1

Programmet alfa1 benytter klassen CAlfa, og har noen enkle menyfunksjoner som demonstrerer noe av funksjonaliteten i klassen.

Image391 Image392
Image393 Image394
Image395 Image396

Selve uttegningen:

void CAlfa1View::DrawScene()
{
  // Clear the color and depth buffers.
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  // Set up for scene
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  gluLookAt(  m_EyeX,m_EyeY,m_EyeZ,
      0.0f,0.0f,0.0f,
      0.0f,1.0f,0.0f); // z up

  // tilt it around x
  glRotatef(m_Vx,1.0f,0.0f,0.0f);
  // tilt it around y
  glRotatef(m_Vy,0.0f,1.0f,0.0f);

  /////////////////////////////
  // set material,
  m_MM.Do_Selection();

  /////////////////////////////
  // Draw the construction
  m_AA.Draw3DText();

  // finnish drawing
  glFlush();
}

m_MM er et materialobjekt og m_AA er et CAlfa objekt

Referanser
  1. The OpenGL Programming Guide, 6 editionDave Schreiner, Mason Woo,Jackie Neider,Tom Davies2007Addison-Wesley Professional0321481003www.opengl.org/documentation/red_book/14-03-2010
Vedlikehold
B.Stenseth, 2001
(Velkommen) Forklaring av>Tekst>Tekst i Windows (NURB)