font.cpp
上传用户:qccn516
上传日期:2013-05-02
资源大小:3382k
文件大小:5k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. /* Font
  2.  *
  3.  * Copyright (C) 2003-2004, Alexander Zaprjagaev <frustum@frustum.org>
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  */
  19. #include <stdio.h>
  20. #include <stdarg.h>
  21. #include "texture.h"
  22. #include "font.h"
  23. Font::Font(const char *name) {
  24. int width,height;
  25. unsigned char *data = Texture::load(name,width,height);
  26. if(!data) {
  27. fprintf(stderr,"Font::Font(): can`t open "%s" filen",name);
  28. return;
  29. }
  30. glGenTextures(1,&tex_id);
  31. glBindTexture(GL_TEXTURE_2D,tex_id);
  32. glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
  33. glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  34. glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
  35. glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
  36. glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,data);
  37. int size = width;
  38. step = size / 16;
  39. for(int y = 0, i = 0; y < 16; y++) {
  40. for(int x = 0; x < 16; x++, i++) {
  41. unsigned char *ptr;
  42. space[i][0] = 0;
  43. for(int j = 0; j < step; j++) {
  44. ptr = data + (size * y * step + x * step + j) * 4;
  45. int k;
  46. for(k = 0; k < step; k++) {
  47. if(*(ptr + 3) != 0) break;
  48. ptr += size * 4;
  49. }
  50. if(k != step) break;
  51. space[i][0]++;
  52. }
  53. space[i][1] = 0;
  54. if(space[i][0] == step) continue;
  55. for(int j = step - 1; j >= 0; j--) {
  56. ptr = data + (size * y * step + x * step + j) * 4;
  57. int k;
  58. for(k = 0; k < step; k++) {
  59. if(*(ptr + 3) != 0) break;
  60. ptr += size * 4;
  61. }
  62. if(k != step) break;
  63. space[i][1]++;
  64. }
  65. space[i][1] = step - space[i][0] - space[i][1];
  66. }
  67. }
  68. delete data;
  69. list_id = glGenLists(256);
  70. for(int y = 0, i = 0; y < 16; y++) {
  71. for(int x = 0; x < 16; x++, i++) {
  72. float s = (float)x / 16.0f + (float)space[i][0] / (float)size;
  73. float t = (float)y / 16.0f;
  74. float ds = (float)space[i][1] / (float)size;
  75. float dt = 1.0 / 16.0;
  76. glNewList(list_id + i,GL_COMPILE);
  77. glBegin(GL_QUADS);
  78. glTexCoord2f(s,t);
  79. glVertex2i(0,0);
  80. glTexCoord2f(s,t + dt);
  81. glVertex2i(0,step);
  82. glTexCoord2f(s + ds,t + dt);
  83. glVertex2i(space[i][1],step);
  84. glTexCoord2f(s + ds,t);
  85. glVertex2i(space[i][1],0);
  86. glEnd();
  87. glTranslatef(space[i][1],0,0);
  88. glEndList();
  89. }
  90. }
  91. }
  92. Font::~Font() {
  93. glDeleteTextures(1,&tex_id);
  94. glDeleteLists(256,list_id);
  95. }
  96. /*
  97.  */
  98. void Font::enable(int w,int h) {
  99. width = w;
  100. height = h;
  101. glGetFloatv(GL_PROJECTION_MATRIX,projection);
  102. glGetFloatv(GL_MODELVIEW_MATRIX,modelview);
  103. glMatrixMode(GL_PROJECTION);
  104. glLoadIdentity();
  105. glOrtho(0,width,height,0,-1,1);
  106. glMatrixMode(GL_MODELVIEW);
  107. glLoadIdentity();
  108. glDisable(GL_DEPTH_TEST);
  109. glDepthMask(GL_FALSE);
  110. glEnable(GL_BLEND);
  111. glEnable(GL_TEXTURE_2D);
  112. glBindTexture(GL_TEXTURE_2D,tex_id);
  113. }
  114. void Font::disable() {
  115. glDisable(GL_TEXTURE_2D);
  116. glDisable(GL_BLEND);
  117. glDepthMask(GL_TRUE);
  118. glEnable(GL_DEPTH_TEST);
  119. glMatrixMode(GL_PROJECTION);
  120. glLoadMatrixf(projection);
  121. glMatrixMode(GL_MODELVIEW);
  122. glLoadMatrixf(modelview);
  123. }
  124. /*
  125.  */
  126. void Font::puts(float x,float y,const char *str) {
  127. for(int i = 0; i < 2; i++) {
  128. if(i == 0) glBlendFunc(GL_ZERO,GL_ONE_MINUS_SRC_ALPHA);
  129. else glBlendFunc(GL_ONE,GL_ONE);
  130. glPushMatrix();
  131. glTranslatef(x,y,0);
  132. char *s = (char*)str;
  133. for(int lines = 0; *s; s++) {
  134. if(*s == 'n') {
  135. lines++;
  136. glLoadIdentity();
  137. glTranslatef(x,y + step * lines,0);
  138. } else if(*s == 'r') {
  139. glLoadIdentity();
  140. glTranslatef(x,y + step * lines,0);
  141. } else if(*s == 't') {
  142. glTranslatef(step * 2,0,0);
  143. } else if(*s == ' ') {
  144. glTranslatef(step / 2,0,0);
  145. } else {
  146. glCallList(list_id + *(unsigned char*)s);
  147. }
  148. }
  149. glPopMatrix();
  150. }
  151. }
  152. /*
  153.  */
  154. void Font::printf(float x,float y,const char *format,...) {
  155. char buf[1024];
  156. va_list argptr;
  157. va_start(argptr,format);
  158. vsprintf(buf,format,argptr);
  159. va_end(argptr);
  160. puts(x,y,buf);
  161. }
  162. /*
  163.  */
  164. void Font::printfc(float x,float y,const char *format,...) {
  165. char buf[1024];
  166. va_list argptr;
  167. va_start(argptr,format);
  168. vsprintf(buf,format,argptr);
  169. va_end(argptr);
  170. char *s = buf;
  171. char *line = buf;
  172. for(int length = 0, lines = 0;; s++) {
  173. if(*s != 'n' && *s != '') {
  174. if(*s == ' ') length += step / 2;
  175. else if(*s == 't') length += step * 2;
  176. else length += space[*(unsigned char*)s][1];
  177. }
  178. else {
  179. if(*s == '') {
  180. printf(x - length / 2,y + step * lines,"%s",line);
  181. break;
  182. }
  183. *s = '';
  184. puts(x - length / 2,y + step * lines,line);
  185. line = s + 1;
  186. length = 0;
  187. lines++;
  188. }
  189. }
  190. }