overlay.cpp
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:6k
源码类别:

OpenGL

开发平台:

Visual C++

  1. // overlay.cpp
  2. //
  3. // Copyright (C) 2001, Chris Laurel <claurel@shatters.net>
  4. //
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the GNU General Public License
  7. // as published by the Free Software Foundation; either version 2
  8. // of the License, or (at your option) any later version.
  9. #include <cstring>
  10. #include <cstdarg>
  11. #include <cstdio>
  12. #include <celutil/utf8.h>
  13. #include "gl.h"
  14. #include "vecgl.h"
  15. #include "overlay.h"
  16. using namespace std;
  17. Overlay::Overlay() :
  18.     ostream(&sbuf),
  19.     windowWidth(1),
  20.     windowHeight(1),
  21.     font(NULL),
  22.     useTexture(false),
  23.     fontChanged(false),
  24.     textBlock(0)
  25. {
  26.     sbuf.setOverlay(this);
  27. }
  28. Overlay::~Overlay()
  29. {
  30. }
  31. void Overlay::begin()
  32. {
  33.     glMatrixMode(GL_PROJECTION);
  34.     glPushMatrix();
  35.     glLoadIdentity();
  36.     gluOrtho2D(0, windowWidth, 0, windowHeight);
  37.     glMatrixMode(GL_MODELVIEW);
  38.     glPushMatrix();
  39.     glLoadIdentity();
  40.     glTranslatef(0.125f, 0.125f, 0);
  41.     glDisable(GL_LIGHTING);
  42.     glDisable(GL_TEXTURE_2D);
  43.     glEnable(GL_BLEND);
  44.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  45.     useTexture = false;
  46. }
  47. void Overlay::end()
  48. {
  49.     glMatrixMode(GL_PROJECTION);
  50.     glPopMatrix();
  51.     glMatrixMode(GL_MODELVIEW);
  52.     glPopMatrix();
  53. }
  54. void Overlay::setWindowSize(int w, int h)
  55. {
  56.     windowWidth = w;
  57.     windowHeight = h;
  58. }
  59. void Overlay::setFont(TextureFont* f)
  60. {
  61.     if (f != font)
  62.     {
  63.         font = f;
  64.         fontChanged = true;
  65.     }
  66. }
  67. void Overlay::beginText()
  68. {
  69.     glPushMatrix();
  70.     textBlock++;
  71. }
  72. void Overlay::endText()
  73. {
  74.     if (textBlock > 0)
  75.     {
  76.         textBlock--;
  77.         glPopMatrix();
  78.     }
  79. }
  80. void Overlay::print(wchar_t c)
  81. {
  82.     if (font != NULL)
  83.     {
  84.         if (!useTexture || fontChanged)
  85.         {
  86.             glEnable(GL_TEXTURE_2D);
  87.             font->bind();
  88.             useTexture = true;
  89.             fontChanged = false;
  90.         }
  91.         switch (c)
  92.         {
  93.         case 'n':
  94.             if (textBlock > 0)
  95.             {
  96.                 glPopMatrix();
  97.                 glTranslatef(0.0f, (float) -(1 + font->getHeight()), 0.0f);
  98.                 glPushMatrix();
  99.             }
  100.             break;
  101.         default:
  102.             font->render(c);
  103.             break;
  104.         }
  105.     }
  106. }
  107. void Overlay::print(char c)
  108. {
  109.     if (font != NULL)
  110.     {
  111.         if (!useTexture || fontChanged)
  112.         {
  113.             glEnable(GL_TEXTURE_2D);
  114.             font->bind();
  115.             useTexture = true;
  116.             fontChanged = false;
  117.         }
  118.         switch (c)
  119.         {
  120.         case 'n':
  121.             if (textBlock > 0)
  122.             {
  123.                 glPopMatrix();
  124.                 glTranslatef(0.0f, (float) -(1 + font->getHeight()), 0.0f);
  125.                 glPushMatrix();
  126.             }
  127.             break;
  128.         default:
  129.             font->render(c);
  130.             break;
  131.         }
  132.     }
  133. }
  134. void Overlay::print(const char* s)
  135. {
  136. #if 0
  137.     while (*s != '')
  138.         print(*s++);
  139. #else
  140.     int length = strlen(s);
  141.     bool validChar = true;
  142.     int i = 0;
  143.     while (i < length && validChar)
  144.     {
  145.         wchar_t ch = 0;
  146.         validChar = UTF8Decode(s, i, length, ch);
  147.         i += UTF8EncodedSize(ch);
  148.         print(ch);
  149.     }
  150. #endif    
  151. }
  152. void Overlay::oprintf(const char* format, ...)
  153. {
  154.     va_list args;
  155.     va_start(args, format);
  156.     char buf[1024];
  157.     vsprintf(buf, format, args);
  158.     print(buf);
  159.     
  160.     va_end(args);
  161. }
  162. void Overlay::rect(float x, float y, float w, float h, bool fill)
  163. {
  164.     if (useTexture)
  165.     {
  166.         glDisable(GL_TEXTURE_2D);
  167.         useTexture = false;
  168.     }
  169.     if (fill)
  170.     {
  171.         glRectf(x, y, x + w, y + h);
  172.     }
  173.     else
  174.     {
  175.         glBegin(GL_LINE_LOOP);
  176.         glVertex3f(x, y, 0);
  177.         glVertex3f(x + w, y, 0);
  178.         glVertex3f(x + w, y + h, 0);
  179.         glVertex3f(x, y + h, 0);
  180.         glEnd();
  181.     }
  182. }
  183. //
  184. // OverlayStreamBuf implementation
  185. //
  186. OverlayStreamBuf::OverlayStreamBuf() :
  187.     overlay(NULL),
  188.     decodeState(UTF8DecodeStart)
  189. {
  190.     setbuf(0, 0);
  191. };
  192. void OverlayStreamBuf::setOverlay(Overlay* o)
  193. {
  194.     overlay = o;
  195. }
  196. int OverlayStreamBuf::overflow(int c)
  197. {
  198.     if (overlay != NULL)
  199.     {
  200.         switch (decodeState)
  201.         {
  202.         case UTF8DecodeStart:
  203.             if (c < 0x80)
  204.             {
  205.                 // Just a normal 7-bit character
  206.                 overlay->print((char) c);
  207.             }
  208.             else
  209.             {
  210.                 unsigned int count;
  211.                 if ((c & 0xe0) == 0xc0)
  212.                     count = 2;
  213.                 else if ((c & 0xf0) == 0xe0)
  214.                     count = 3;
  215.                 else if ((c & 0xf8) == 0xf0)
  216.                     count = 4;
  217.                 else if ((c & 0xfc) == 0xf8)
  218.                     count = 5;
  219.                 else if ((c & 0xfe) == 0xfc)
  220.                     count = 6;
  221.                 else
  222.                     count = 1; // Invalid byte
  223.                 if (count > 1)
  224.                 {
  225.                     unsigned int mask = (1 << (7 - count)) - 1;
  226.                     decodeShift = (count - 1) * 6;
  227.                     decodedChar = (c & mask) << decodeShift;
  228.                     decodeState = UTF8DecodeMultibyte;
  229.                 }
  230.                 else
  231.                 {
  232.                     // If the character isn't valid multibyte sequence head,
  233.                     // silently skip it by leaving the decoder state alone.
  234.                 }
  235.             }
  236.             break;
  237.         case UTF8DecodeMultibyte:
  238.             if ((c & 0xc0) == 0x80)
  239.             {
  240.                 // We have a valid non-head byte in the sequence
  241.                 decodeShift -= 6;
  242.                 decodedChar |= (c & 0x3f) << decodeShift;
  243.                 if (decodeShift == 0)
  244.                 {
  245.                     overlay->print(decodedChar);
  246.                     decodeState = UTF8DecodeStart;
  247.                 }
  248.             }
  249.             else
  250.             {
  251.                 // Bad byte in UTF-8 encoded sequence; we'll silently ignore
  252.                 // it and reset the state of the UTF-8 decoder.
  253.                 decodeState = UTF8DecodeStart;
  254.             }
  255.             break;
  256.         }
  257.     }
  258.     return c;
  259. }