00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #if defined (WIN32)
00021 #include <windows.h>
00022 #endif
00023
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <string.h>
00027 #include <math.h>
00028 #include <GL/gl.h>
00029 #include <GL/glu.h>
00030 #include "glf.h"
00031
00032
00033
00034 #define MAX_FONTS 256
00035
00036
00037 struct color
00038 {
00039 float r, g, b, a;
00040 };
00041
00042
00043 struct one_symbol
00044 {
00045 unsigned char vertexs;
00046 unsigned char facets;
00047 unsigned char lines;
00048
00049 float *vdata;
00050 unsigned char *fdata;
00051 unsigned char *ldata;
00052
00053 float leftx;
00054 float rightx;
00055 float topy;
00056 float bottomy;
00057 };
00058
00059
00060 struct glf_font
00061 {
00062 char font_name [97];
00063 unsigned char sym_total;
00064 struct one_symbol *symbols[256];
00065 };
00066
00067
00068
00069 static float SymbolDist = 0.2f;
00070 static float SymbolDepth = 0.2f;
00071 static float SpaceSize = 2.0f;
00072 static float RotateAngle = 0.0f;
00073 static float RotateAngleB = 0.0f;
00074
00075
00076
00077
00078 static struct glf_font *fonts[MAX_FONTS];
00079 static int curfont;
00080 static char ap = GLF_CENTER;
00081 static GLboolean m_string_center;
00082 static GLboolean m_bitmap_string_center;
00083
00084 static GLuint m_direction;
00085
00086 static char console_msg = GLF_NO;
00087 static char texturing = GLF_NO;
00088 static char contouring = GLF_NO;
00089 static struct color contouring_color;
00090
00091
00092 static int conWidth, conHeight;
00093 static int conx = 0, cony = 0;
00094 static char *conData;
00095 static int conFont;
00096 static char conCursor = GLF_NO;
00097 static int conCursorBlink;
00098 static int conCursorCount;
00099 static char conCursorMode = GLF_NO;
00100
00101
00102 #define SEEK_SET_POS 4195
00103
00104 struct coord_rect
00105 {
00106 float x, y, width, height;
00107 };
00108
00109 struct widths
00110 {
00111 float *width;
00112 };
00113
00114
00115 static float sym_space=0.001f;
00116
00117
00118 static struct coord_rect Symbols[256];
00119 static GLboolean bmf_texturing;
00120 static int bmf_curfont;
00121 static GLuint bmf_texture[MAX_FONTS];
00122 static GLuint bmf_mask[MAX_FONTS];
00123 static char bmf_in_use[MAX_FONTS];
00124 static int list_base[MAX_FONTS];
00125 static GLfloat m_max_height[MAX_FONTS];
00126 static struct widths m_widths[MAX_FONTS];
00127
00128
00129
00130 void glfInit()
00131 {
00132 int i;
00133
00134 for (i=0; i<MAX_FONTS; i++)
00135 {
00136 fonts[i] = NULL;
00137 bmf_in_use[i] = 0;
00138 m_max_height[i] = 0;
00139 }
00140
00141 curfont = -1;
00142 bmf_curfont = -1;
00143 console_msg = GLF_NO;
00144 ap = GLF_CENTER;
00145 texturing = GLF_NO;
00146 contouring = GLF_NO;
00147 memset(&contouring_color, 0, sizeof(struct color));
00148 conData = NULL;
00149 glfSetConsoleParam(40, 20);
00150 glfConsoleClear();
00151 glfEnable(GLF_CONSOLE_CURSOR);
00152 glfSetCursorBlinkRate(10);
00153 glfStringCentering(GL_FALSE);
00154 glfBitmapStringCentering(GL_FALSE);
00155 glfStringDirection(GLF_LEFT);
00156 }
00157
00158
00159 void glfClose()
00160 {
00161 int i;
00162
00163 free(conData);
00164
00165 for (i=0; i<MAX_FONTS; i++) glfUnloadFontD(i);
00166 for (i=0; i<MAX_FONTS; i++) glfUnloadBMFFontD(i);
00167 }
00168
00169
00170
00171
00172
00173
00174 static int LittleEndian()
00175 {
00176 int endianTester = 1;
00177 char *endianChar = 0;
00178
00179 endianChar = (char *)&endianTester;
00180 if (*endianChar) return 1;
00181 return 0;
00182 }
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 static int ReadFont(char *font_name, struct glf_font *glff)
00197 {
00198
00199 FILE *fontf;
00200 char buffer[64];
00201 int i, j;
00202 unsigned char temp, code, verts, fcets, lns;
00203 float tempfx, tempfy;
00204 unsigned char *tp;
00205 int LEndian;
00206
00207 fontf = fopen(font_name, "rb");
00208 if (fontf == NULL) return GLF_ERROR;
00209
00210 fread(buffer, 3, 1, fontf);
00211 buffer[3] = 0;
00212 if (strcmp(buffer, "GLF"))
00213 {
00214
00215 if (console_msg) printf("Error reading font file: incorrect file format\n");
00216 return GLF_ERROR;
00217 }
00218
00219
00220 LEndian = LittleEndian();
00221
00222 fread(glff->font_name, 96, 1, fontf);
00223 glff->font_name[96] = 0;
00224
00225 fread(&glff->sym_total, 1, 1, fontf);
00226
00227 for (i=0; i<MAX_FONTS; i++) glff->symbols[(int)i] = NULL;
00228
00229 for (i=0; i<28; i++) fread(&temp, 1, 1, fontf);
00230
00231
00232
00233 for (i=0; i<glff->sym_total; i++)
00234 {
00235 fread(&code, 1, 1, fontf);
00236 fread(&verts, 1, 1, fontf);
00237 fread(&fcets, 1, 1, fontf);
00238 fread(&lns, 1, 1, fontf);
00239
00240 if (glff->symbols[(int)code] != NULL)
00241 {
00242 if (console_msg) printf("Error reading font file: encountered symbols in font\n");
00243 return GLF_ERROR;
00244 }
00245
00246 glff->symbols[(int)code] = (struct one_symbol *)malloc(sizeof(struct one_symbol));
00247 glff->symbols[(int)code]->vdata = (float *)malloc(8*verts);
00248 glff->symbols[(int)code]->fdata = (unsigned char *)malloc(3*fcets);
00249 glff->symbols[(int)code]->ldata = (unsigned char *)malloc(lns);
00250
00251 glff->symbols[(int)code]->vertexs = verts;
00252 glff->symbols[(int)code]->facets = fcets;
00253 glff->symbols[(int)code]->lines = lns;
00254
00255
00256 glff->symbols[(int)code]->leftx = 10;
00257 glff->symbols[(int)code]->rightx = -10;
00258 glff->symbols[(int)code]->topy = 10;
00259 glff->symbols[(int)code]->bottomy = -10;
00260
00261 for (j=0; j<verts; j++)
00262 {
00263 fread(&tempfx, 4, 1, fontf);
00264 fread(&tempfy, 4, 1, fontf);
00265
00266
00267
00268 if (!LEndian)
00269 {
00270 tp = (unsigned char *)&tempfx;
00271 temp = tp[0]; tp[0] = tp[3]; tp[3] = temp;
00272 temp = tp[1]; tp[1] = tp[2]; tp[2] = temp;
00273 tp = (unsigned char *)&tempfy;
00274 temp = tp[0]; tp[0] = tp[3]; tp[3] = temp;
00275 temp = tp[1]; tp[1] = tp[2]; tp[2] = temp;
00276 }
00277 glff->symbols[(int)code]->vdata[j*2] = tempfx;
00278 glff->symbols[(int)code]->vdata[j*2+1] = tempfy;
00279
00280 if (tempfx < glff->symbols[(int)code]->leftx) glff->symbols[(int)code]->leftx = tempfx;
00281 if (tempfx > glff->symbols[(int)code]->rightx) glff->symbols[(int)code]->rightx = tempfx;
00282 if (tempfy < glff->symbols[(int)code]->topy) glff->symbols[(int)code]->topy = tempfy;
00283 if (tempfy > glff->symbols[(int)code]->bottomy) glff->symbols[(int)code]->bottomy = tempfy;
00284 }
00285 for (j=0; j<fcets; j++)
00286 fread(&glff->symbols[(int)code]->fdata[j*3], 3, 1, fontf);
00287 for (j=0; j<lns; j++)
00288 fread(&glff->symbols[(int)code]->ldata[j], 1, 1, fontf);
00289 }
00290 fclose(fontf);
00291 return GLF_OK;
00292 }
00293
00294
00295
00296
00297
00298
00299
00300 int glfLoadFont(char *font_name)
00301 {
00302 int i;
00303 char flag;
00304
00305
00306 flag = 0;
00307 for (i=0; i<MAX_FONTS; i++)
00308 if (fonts[i] == NULL)
00309 {
00310
00311 fonts[i] = (struct glf_font *)malloc(sizeof(struct glf_font));
00312 flag = 1;
00313 break;
00314 }
00315
00316 if (!flag) return GLF_ERROR;
00317 if (ReadFont(font_name, fonts[i]) == GLF_OK)
00318 {
00319 curfont = i;
00320 return i;
00321 }
00322
00323 if (fonts[i] != NULL)
00324 {
00325 free(fonts[i]);
00326 fonts[i] = NULL;
00327 }
00328 return GLF_ERROR;
00329 }
00330
00331
00332
00333
00334
00335
00336 int glfUnloadFont()
00337 {
00338 int i;
00339
00340 if ((curfont<0) || (fonts[curfont] == NULL)) return GLF_ERROR;
00341
00342 for (i=0; i<256; i++)
00343 {
00344 if (fonts[curfont]->symbols[(int)i] != NULL)
00345 {
00346 free(fonts[curfont]->symbols[(int)i]->vdata);
00347 free(fonts[curfont]->symbols[(int)i]->fdata);
00348 free(fonts[curfont]->symbols[(int)i]->ldata);
00349 free(fonts[curfont]->symbols[(int)i]);
00350 }
00351 }
00352
00353 free(fonts[curfont]);
00354 fonts[curfont] = NULL;
00355 curfont = -1;
00356 return GLF_OK;
00357 }
00358
00359
00360 int glfUnloadFontD(int font_descriptor)
00361 {
00362 int temp;
00363
00364 if ((font_descriptor < 0) || (fonts[font_descriptor] == NULL)) return GLF_ERROR;
00365
00366 temp = curfont;
00367 curfont = font_descriptor;
00368 glfUnloadFont();
00369 if (temp != font_descriptor) curfont = temp;
00370 else curfont = -1;
00371 return GLF_OK;
00372 }
00373
00374 void glfDrawWiredSymbol(char s)
00375 {
00376 int i, cur_line;
00377 float *tvp;
00378 float x, y;
00379
00380 if ((curfont < 0) || (fonts[curfont] == NULL)) return;
00381 if (fonts[curfont]->symbols[(int)s] == NULL) return;
00382
00383 glBegin(GL_LINE_LOOP);
00384 tvp = fonts[curfont]->symbols[(int)s]->vdata;
00385 cur_line = 0;
00386 for (i=0; i<fonts[curfont]->symbols[(int)s]->vertexs; i++)
00387 {
00388 x = *tvp++;
00389 y = *tvp++;
00390 glVertex2f(x, y);
00391 if (fonts[curfont]->symbols[(int)s]->ldata[cur_line] == i)
00392 {
00393 glEnd();
00394 cur_line++;
00395 if (cur_line < fonts[curfont]->symbols[(int)s]->lines) glBegin(GL_LINE_LOOP);
00396 else break;
00397 }
00398 }
00399 }
00400
00401
00402 void glfDrawWiredSymbolF(int font_descriptor, char s)
00403 {
00404 int temp;
00405
00406 temp = curfont;
00407 curfont = font_descriptor;
00408 glfDrawWiredSymbol(s);
00409 curfont = temp;
00410 }
00411
00412 static void DrawString(char *s, void (*funct) (char s))
00413 {
00414 int i;
00415 float sda, sdb;
00416 float distance = 0;
00417
00418 if (!s) return;
00419 if (!*s) return;
00420 if (curfont == -1) return;
00421
00422
00423 if (m_string_center)
00424 {
00425 distance = 0;
00426 for (i=0; i<(int)strlen(s); i++)
00427 {
00428 if ((fonts[curfont]->symbols[(int)s[i]] == NULL) || (s[i] == ' '))
00429 {
00430 if (m_direction == GLF_LEFT || m_direction == GLF_UP) distance += SpaceSize;
00431 else distance -= SpaceSize;
00432 }
00433 else
00434 if (i < ((int)strlen(s)-1))
00435 if (s[i+1] == ' ')
00436 {
00437 if (m_direction == GLF_LEFT || m_direction == GLF_UP) distance += SymbolDist;
00438 else distance -= SymbolDist;
00439 }
00440 else
00441 {
00442 if (fonts[curfont]->symbols[(int)s[i+1]] == NULL) continue;
00443
00444 if (m_direction == GLF_LEFT || m_direction == GLF_RIGHT)
00445 {
00446 sda = (float)fabs(fonts[curfont]->symbols[(int)s[i]]->rightx);
00447 sdb = (float)fabs(fonts[curfont]->symbols[(int)s[i+1]]->leftx);
00448 if (m_direction == GLF_LEFT) distance += sda+sdb+SymbolDist;
00449 else distance -= sda+sdb+SymbolDist;
00450 }
00451 else
00452 {
00453 sda = (float)fabs(fonts[curfont]->symbols[(int)s[i]]->topy);
00454 sdb = (float)fabs(fonts[curfont]->symbols[(int)s[i]]->bottomy);
00455 if (m_direction == GLF_DOWN) distance -= sda+sdb+SymbolDist;
00456 else distance += sda+sdb+SymbolDist;
00457 }
00458 }
00459 }
00460 }
00461
00462 glPushMatrix();
00463
00464
00465 if (RotateAngle != 0.0f) glRotatef(RotateAngle, 0, 0, 1);
00466
00467
00468 if (m_string_center)
00469 {
00470 switch (m_direction)
00471 {
00472 case GLF_LEFT : glTranslatef(-distance/2, 0, 0); break;
00473 case GLF_RIGHT : glTranslatef(distance/2, 0, 0); break;
00474 case GLF_UP : glTranslatef(0, distance/2, 0); break;
00475 case GLF_DOWN : glTranslatef(0, -distance/2, 0); break;
00476 }
00477 }
00478 else if (s[0] != ' ')
00479 {
00480 switch (m_direction)
00481 {
00482 case GLF_LEFT : glTranslatef(-(1-(float)fabs(fonts[curfont]->symbols[(int)s[0]]->leftx)), 0, 0); break;
00483 case GLF_RIGHT : glTranslatef((1-(float)fabs(fonts[curfont]->symbols[(int)s[0]]->rightx)), 0, 0); break;
00484 case GLF_UP : glTranslatef(0, (1-(float)fabs(fonts[curfont]->symbols[(int)s[0]]->topy)), 0); break;
00485 case GLF_DOWN : glTranslatef(0, -(1-(float)fabs(fonts[curfont]->symbols[(int)s[0]]->bottomy)), 0); break;
00486 }
00487 }
00488
00489
00490 for (i=0; i<(int)strlen(s); i++)
00491 {
00492 if (s[i] != ' ') (*funct) (s[i]);
00493 if ((fonts[curfont]->symbols[(int)s[i]] == NULL) || (s[i] == ' '))
00494 {
00495 switch (m_direction)
00496 {
00497 case GLF_LEFT : glTranslatef(SpaceSize, 0, 0); break;
00498 case GLF_RIGHT : glTranslatef(-SpaceSize, 0, 0); break;
00499 case GLF_UP : glTranslatef(0, SpaceSize, 0); break;
00500 case GLF_DOWN : glTranslatef(0, -SpaceSize, 0); break;
00501 }
00502 }
00503 else
00504 if (i < ((int)strlen(s)-1))
00505 if (s[i+1] == ' ')
00506 {
00507 switch (m_direction)
00508 {
00509 case GLF_LEFT : glTranslatef(SymbolDist, 0, 0); break;
00510 case GLF_RIGHT : glTranslatef(-SymbolDist, 0, 0); break;
00511 case GLF_UP : glTranslatef(0, SymbolDist, 0); break;
00512 case GLF_DOWN : glTranslatef(0, -SymbolDist, 0); break;
00513 }
00514 }
00515 else
00516 {
00517 if (fonts[curfont]->symbols[(int)s[i+1]] == NULL) continue;
00518
00519 if (m_direction == GLF_LEFT || m_direction == GLF_RIGHT)
00520 {
00521 if (m_direction == GLF_LEFT)
00522 {
00523 sda = (float)fabs(fonts[curfont]->symbols[(int)s[i]]->rightx);
00524 sdb = (float)fabs(fonts[curfont]->symbols[(int)s[i+1]]->leftx);
00525 }
00526 else
00527 {
00528 sda = (float)fabs(fonts[curfont]->symbols[(int)s[i+1]]->rightx);
00529 sdb = (float)fabs(fonts[curfont]->symbols[(int)s[i]]->leftx);
00530 }
00531
00532 if (m_direction == GLF_LEFT) glTranslatef(sda+sdb+SymbolDist, 0, 0);
00533 else glTranslatef(-(sda+sdb+SymbolDist), 0, 0);
00534 }
00535 else
00536 {
00537 if (m_direction == GLF_DOWN)
00538 {
00539 sda = (float)fabs(fonts[curfont]->symbols[(int)s[i]]->topy);
00540 sdb = (float)fabs(fonts[curfont]->symbols[(int)s[i+1]]->bottomy);
00541 }
00542 else
00543 {
00544 sda = (float)fabs(fonts[curfont]->symbols[(int)s[i+1]]->topy);
00545 sdb = (float)fabs(fonts[curfont]->symbols[(int)s[i]]->bottomy);
00546 }
00547
00548 if (m_direction == GLF_DOWN) glTranslatef(0, -(sda+sdb+SymbolDist), 0);
00549 else glTranslatef(0, sda+sdb+SymbolDist, 0);
00550 }
00551
00552 }
00553 }
00554 glPopMatrix();
00555 }
00556
00557 void glfDrawWiredString(char *s)
00558 {
00559 DrawString(s, &glfDrawWiredSymbol);
00560 }
00561
00562
00563 void glfDrawWiredStringF(int font_descriptor, char *s)
00564 {
00565 int temp;
00566
00567 temp = curfont;
00568 curfont = font_descriptor;
00569 DrawString(s, &glfDrawWiredSymbol);
00570 curfont = temp;
00571 }
00572
00573 void glfDrawSolidSymbol(char s)
00574 {
00575 unsigned char *b;
00576 float *vp;
00577 int i, j;
00578 float x, y;
00579 float temp_color[4];
00580
00581 if ((curfont<0) || (fonts[curfont] == NULL)) return;
00582
00583 if (fonts[curfont]->symbols[(int)s] == NULL) return;
00584
00585 b = fonts[curfont]->symbols[(int)s]->fdata;
00586 vp = fonts[curfont]->symbols[(int)s]->vdata;
00587
00588 glBegin(GL_TRIANGLES);
00589 for (i=0; i<fonts[curfont]->symbols[(int)s]->facets; i++)
00590 {
00591 for (j=0; j<3; j++)
00592 {
00593 x = vp[*b*2];
00594 y = vp[*b*2+1];
00595 if (texturing == GLF_YES) glTexCoord2f((x+1)/2, (y+1)/2);
00596 glVertex2f(x, y);
00597 b++;
00598 }
00599 }
00600 glEnd();
00601
00602
00603 if (contouring == GLF_YES)
00604 {
00605 glGetFloatv(GL_CURRENT_COLOR, temp_color);
00606 glColor4f(contouring_color.r, contouring_color.g, contouring_color.b, contouring_color.a);
00607 glfDrawWiredSymbol(s);
00608 glColor4fv(temp_color);
00609 }
00610 }
00611
00612
00613 void glfDrawSolidSymbolF(int font_descriptor, char s)
00614 {
00615 int temp;
00616
00617 temp = curfont;
00618 curfont = font_descriptor;
00619 glfDrawSolidSymbol(s);
00620 curfont = temp;
00621 }
00622
00623 void glfDrawSolidString(char *s)
00624 {
00625 DrawString(s, &glfDrawSolidSymbol);
00626 }
00627
00628
00629 void glfDrawSolidStringF(int font_descriptor, char *s)
00630 {
00631 int temp;
00632
00633 temp = curfont;
00634 curfont = font_descriptor;
00635 DrawString(s, &glfDrawSolidSymbol);
00636 curfont = temp;
00637 }
00638
00639
00640
00641
00642 void glfDraw3DWiredSymbol(char s)
00643 {
00644 int i, cur_line;
00645 float *tvp;
00646 float x, y;
00647
00648 if ((curfont<0) || (fonts[curfont] == NULL)) return;
00649 if (fonts[curfont]->symbols[(int)s] == NULL) return;
00650
00651
00652 glBegin(GL_LINE_LOOP);
00653 tvp = fonts[curfont]->symbols[(int)s]->vdata;
00654 cur_line = 0;
00655 for (i=0; i<fonts[curfont]->symbols[(int)s]->vertexs; i++)
00656 {
00657 x = *tvp;
00658 tvp++;
00659 y = *tvp;
00660 tvp++;
00661 glVertex3f(x, y, 1);
00662 if (fonts[curfont]->symbols[(int)s]->ldata[cur_line] == i)
00663 {
00664 glEnd();
00665 cur_line++;
00666 if (cur_line < fonts[curfont]->symbols[(int)s]->lines) glBegin(GL_LINE_LOOP);
00667 else break;
00668 }
00669 }
00670
00671
00672 glBegin(GL_LINE_LOOP);
00673 tvp = fonts[curfont]->symbols[(int)s]->vdata;
00674 cur_line = 0;
00675 for (i=0; i<fonts[curfont]->symbols[(int)s]->vertexs; i++)
00676 {
00677 x = *tvp;
00678 tvp++;
00679 y = *tvp;
00680 tvp++;
00681 glVertex3f(x, y, 1+SymbolDepth);
00682 if (fonts[curfont]->symbols[(int)s]->ldata[cur_line] == i)
00683 {
00684 glEnd();
00685 cur_line++;
00686 if (cur_line < fonts[curfont]->symbols[(int)s]->lines) glBegin(GL_LINE_LOOP);
00687 else break;
00688 }
00689 }
00690
00691
00692 glBegin(GL_LINES);
00693 tvp = fonts[curfont]->symbols[(int)s]->vdata;
00694 for (i=0; i<fonts[curfont]->symbols[(int)s]->vertexs; i++)
00695 {
00696 x = *tvp;
00697 tvp++;
00698 y = *tvp;
00699 tvp++;
00700 glVertex3f(x, y, 1);
00701 glVertex3f(x, y, 1+SymbolDepth);
00702 }
00703 glEnd();
00704 }
00705
00706
00707 void glfDraw3DWiredSymbolF(int font_descriptor, char s)
00708 {
00709 int temp;
00710
00711 temp = curfont;
00712 curfont = font_descriptor;
00713 glfDraw3DWiredSymbol(s);
00714 curfont = temp;
00715 }
00716
00717 void glfDraw3DWiredString(char *s)
00718 {
00719 DrawString(s, &glfDraw3DWiredSymbol);
00720 }
00721
00722
00723 void glfDraw3DWiredStringF(int font_descriptor, char *s)
00724 {
00725 int temp;
00726
00727 temp = curfont;
00728 curfont = font_descriptor;
00729 DrawString(s, &glfDraw3DWiredSymbol);
00730 curfont = temp;
00731 }
00732
00733
00734
00735 void glfDraw3DSolidSymbol(char s)
00736 {
00737 int i, j, cur_line, flag;
00738 float x, y, bx=0, by=0;
00739 unsigned char *b;
00740 float *vp;
00741 float *tvp;
00742 float temp_color[4];
00743 GLboolean light_temp;
00744
00745 if ((curfont<0) || (fonts[curfont] == NULL)) return;
00746 if (fonts[curfont]->symbols[(int)s] == NULL) return;
00747
00748 b = fonts[curfont]->symbols[(int)s]->fdata;
00749 vp = fonts[curfont]->symbols[(int)s]->vdata;
00750
00751 glBegin(GL_TRIANGLES);
00752 glNormal3f(0, 0, 1);
00753 for (i=0; i<fonts[curfont]->symbols[(int)s]->facets; i++)
00754 {
00755 b += 2;
00756 for (j=0; j<3; j++)
00757 {
00758 x = vp[*b*2];
00759 y = vp[*b*2+1];
00760 glVertex3f(x, y, 1+SymbolDepth);
00761 b--;
00762 }
00763 b += 4;
00764 }
00765 glEnd();
00766
00767 b = fonts[curfont]->symbols[(int)s]->fdata;
00768 vp = fonts[curfont]->symbols[(int)s]->vdata;
00769
00770 glBegin(GL_TRIANGLES);
00771 glNormal3f(0, 0, -1);
00772 for (i=0; i<fonts[curfont]->symbols[(int)s]->facets; i++)
00773 {
00774 for (j=0; j<3; j++)
00775 {
00776 x = vp[*b*2];
00777 y = vp[*b*2+1];
00778 glVertex3f(x, y, 1);
00779 b++;
00780 }
00781 }
00782 glEnd();
00783
00784 flag = 0;
00785 glBegin(GL_QUAD_STRIP);
00786 tvp = fonts[curfont]->symbols[(int)s]->vdata;
00787 cur_line = 0;
00788 for (i=0; i<fonts[curfont]->symbols[(int)s]->vertexs; i++)
00789 {
00790 x = *tvp;
00791 tvp++;
00792 y = *tvp;
00793 tvp++;
00794 if (!flag)
00795 {
00796 bx = x;
00797 by = y;
00798 flag = 1;
00799 }
00800 glNormal3f(x, y, 0);
00801 glVertex3f(x, y, 1);
00802 glVertex3f(x, y, 1+SymbolDepth);
00803 if (fonts[curfont]->symbols[(int)s]->ldata[cur_line] == i)
00804 {
00805 glVertex3f(bx, by, 1);
00806 glVertex3f(bx, by, 1+SymbolDepth);
00807 flag = 0;
00808 glEnd();
00809 cur_line++;
00810 if (cur_line < fonts[curfont]->symbols[(int)s]->lines) glBegin(GL_QUAD_STRIP);
00811 else break;
00812 }
00813 }
00814
00815
00816 if (contouring == GLF_YES)
00817 {
00818 glGetBooleanv(GL_LIGHTING, &light_temp);
00819 glDisable(GL_LIGHTING);
00820 glGetFloatv(GL_CURRENT_COLOR, temp_color);
00821 glColor4f(contouring_color.r, contouring_color.g, contouring_color.b, contouring_color.a);
00822 glfDraw3DWiredSymbol(s);
00823 glColor4fv(temp_color);
00824 if (light_temp) glEnable(GL_LIGHTING);
00825 }
00826 }
00827
00828
00829 void glfDraw3DSolidSymbolF(int font_descriptor, char s)
00830 {
00831 int temp;
00832
00833 temp = curfont;
00834 curfont = font_descriptor;
00835 glfDraw3DSolidSymbol(s);
00836 curfont = temp;
00837 }
00838
00839 void glfDraw3DSolidString(char *s)
00840 {
00841 DrawString(s, &glfDraw3DSolidSymbol);
00842 }
00843
00844
00845 void glfDraw3DSolidStringF(int font_descriptor, char *s)
00846 {
00847 int temp;
00848
00849 temp = curfont;
00850 curfont = font_descriptor;
00851 DrawString(s, &glfDraw3DSolidSymbol);
00852 curfont = temp;
00853 }
00854
00855
00856 void glfGetStringBoundsF(int fd, char *s, float *minx, float *miny, float *maxx, float *maxy)
00857 {
00858 struct glf_font *font;
00859 int i;
00860 float sda, sdb, cw = 0, minxx = 10;
00861 float top = 10, bottom = -10;
00862
00863 if (fd < 0 || fd > (MAX_FONTS-1)) return;
00864 font = fonts[fd];
00865
00866 if (font == NULL) return;
00867
00868 if (font->symbols[(int)s[0]])
00869 minxx = -(float)(fabs(font->symbols[(int)s[0]]->leftx));
00870 else
00871 minxx = 0.0;
00872
00873 for (i=0; i<(int)strlen(s); i++)
00874 {
00875 if ((font->symbols[(int)s[i]] == NULL) || (s[i] == ' '))
00876 cw += SpaceSize;
00877 else
00878 {
00879 sdb = (float)fabs(font->symbols[(int)s[i]]->leftx);
00880 sda = (float)fabs(font->symbols[(int)s[i]]->rightx);
00881
00882 cw += sda+sdb+SymbolDist;
00883
00884
00885 if (font->symbols[(int)s[i]]->bottomy > bottom)
00886 bottom = font->symbols[(int)s[i]]->bottomy;
00887
00888 if (font->symbols[(int)s[i]]->topy < top)
00889 top = font->symbols[(int)s[i]]->topy;
00890 }
00891 }
00892
00893 cw += minxx + SymbolDist;
00894
00895 if ((maxx) && (maxy))
00896 {
00897 *maxx = cw;
00898 *maxy = bottom;
00899 }
00900
00901 if ((minx) && (miny))
00902 {
00903 *minx = minxx;
00904 *miny = top;
00905 }
00906 }
00907
00908 void glfGetStringBounds(char *s, float *minx, float *miny, float *maxx, float *maxy)
00909 {
00910 glfGetStringBoundsF(curfont, s, minx, miny, maxx, maxy);
00911 }
00912
00913 void glfSetSymbolSpace(float sp)
00914 {
00915 SymbolDist = sp;
00916 }
00917
00918 float glfGetSymbolSpace()
00919 {
00920 return SymbolDist;
00921 }
00922
00923 void glfSetSpaceSize(float sp)
00924 {
00925 SpaceSize = sp;
00926 }
00927
00928 float glfGetSpaceSize()
00929 {
00930 return SpaceSize;
00931 }
00932
00933 void glfSetSymbolDepth(float dpth)
00934 {
00935 SymbolDepth = dpth;
00936 }
00937
00938 float glfGetSymbolDepth()
00939 {
00940 return SymbolDepth;
00941 }
00942
00943 int glfSetCurrentFont(int Font_Descriptor)
00944 {
00945 if ((Font_Descriptor < 0) || (fonts[Font_Descriptor] == NULL)) return GLF_ERROR;
00946
00947 curfont = Font_Descriptor;
00948 return GLF_OK;
00949 }
00950
00951 int glfGetCurrentFont()
00952 {
00953 return curfont;
00954 }
00955
00956 void glfSetAnchorPoint(int anchp)
00957 {
00958 if ((anchp >= GLF_LEFT_UP) && (anchp <= GLF_RIGHT_DOWN))
00959 ap = anchp;
00960 }
00961
00962 void glfSetContourColor(float r, float g, float b, float a)
00963 {
00964 contouring_color.r = r;
00965 contouring_color.g = g;
00966 contouring_color.b = b;
00967 contouring_color.a = a;
00968 }
00969
00970 void glfEnable(int what)
00971 {
00972 switch (what)
00973 {
00974 case GLF_CONSOLE_MESSAGES: console_msg = GLF_YES; break;
00975 case GLF_TEXTURING: texturing = GLF_YES; break;
00976 case GLF_CONSOLE_CURSOR: conCursor = GLF_YES; break;
00977 case GLF_CONTOURING: contouring = GLF_YES; break;
00978 }
00979 }
00980
00981 void glfDisable(int what)
00982 {
00983 switch (what)
00984 {
00985 case GLF_CONSOLE_MESSAGES: console_msg = GLF_NO; break;
00986 case GLF_TEXTURING: texturing = GLF_NO; break;
00987 case GLF_CONSOLE_CURSOR: conCursor = GLF_NO; break;
00988 case GLF_CONTOURING: contouring = GLF_NO; break;
00989 }
00990 }
00991
00992
00993
00994 void glfSetConsoleParam(int width, int height)
00995 {
00996 if (conData) free(conData);
00997
00998 conWidth = width;
00999 conHeight = height;
01000 conData = (char *)malloc(width*height);
01001 glfConsoleClear();
01002 }
01003
01004 int glfSetConsoleFont(int Font_Descriptor)
01005 {
01006 if ((Font_Descriptor < 0) || (fonts[Font_Descriptor] == NULL)) return GLF_ERROR;
01007
01008 conFont = Font_Descriptor;
01009 return GLF_OK;
01010 }
01011
01012 void glfConsoleClear()
01013 {
01014 memset(conData, 0, conWidth*conHeight);
01015 conx = 0;
01016 cony = 0;
01017 }
01018
01019 void glfPrint(char *s, int lenght)
01020 {
01021 int i;
01022
01023 for (i=0; i<lenght; i++)
01024 {
01025 if (s[i] > 31)
01026 {
01027 conData[cony*conWidth+conx] = s[i];
01028 conx++;
01029 } else
01030 if (s[i] == '\n') conx = conWidth;
01031 if (conx >= conWidth)
01032 {
01033 conx = 0;
01034 cony++;
01035 if (cony >= conHeight)
01036 {
01037
01038 memcpy(conData, &conData[conWidth], conWidth*(conHeight-1));
01039
01040 memset(&conData[conWidth*(conHeight-1)], 0, conWidth);
01041 cony = conHeight-1;
01042 }
01043 }
01044 }
01045 }
01046
01047 void glfPrintString(char *s)
01048 {
01049 glfPrint(s, strlen(s));
01050 }
01051
01052 void glfPrintChar(char s)
01053 {
01054 glfPrint(&s, 1);
01055 }
01056
01057 void glfConsoleDraw()
01058 {
01059 int i, j;
01060 char s[512];
01061
01062 for (i=0; i<conHeight; i++)
01063 {
01064 memcpy(s, &conData[i*conWidth], conWidth);
01065 s[conWidth] = 0;
01066 if ((conCursor == GLF_YES) && (i == cony))
01067 {
01068 conCursorCount--;
01069 if (conCursorCount < 0)
01070 {
01071 conCursorCount = conCursorBlink;
01072 if (conCursorMode == GLF_YES) conCursorMode = GLF_NO;
01073 else conCursorMode = GLF_YES;
01074 }
01075
01076 if (conCursorMode == GLF_YES)
01077 for (j=0; j<conWidth; j++)
01078 {
01079 if (!s[j])
01080 {
01081 s[j] = '_';
01082 s[j+1] = 0;
01083 break;
01084 }
01085 }
01086 }
01087 glfDrawSolidStringF(conFont, s);
01088 glTranslatef(0, -2, 0);
01089 }
01090 }
01091
01092 void glfSetCursorBlinkRate(int Rate)
01093 {
01094 if (Rate > 0)
01095 {
01096 conCursorBlink = Rate;
01097 conCursorCount = Rate;
01098 conCursorMode = GLF_YES;
01099 }
01100 }
01101
01102
01103 void glfStringCentering(GLboolean center)
01104 {
01105 m_string_center = center;
01106 }
01107
01108
01109
01110 void glfStringDirection(GLuint direction)
01111 {
01112 if (direction == GLF_LEFT || direction == GLF_RIGHT ||
01113 direction == GLF_UP || direction == GLF_DOWN) m_direction = direction;
01114 }
01115
01116
01117 GLuint glfGetStringDirection()
01118 {
01119 return m_direction;
01120 }
01121
01122
01123
01124 GLboolean glfGetStringCentering()
01125 {
01126 return m_string_center;
01127 }
01128
01129
01130 void glfSetRotateAngle(float angle)
01131 {
01132 RotateAngle = angle;
01133 }
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144 static void bwtorgba(unsigned char *b,unsigned char *l,int n)
01145 {
01146 while (n--)
01147 {
01148 l[0] = *b; l[1] = *b;
01149 l[2] = *b; l[3] = 0xff;
01150 l += 4; b++;
01151 }
01152 }
01153
01154 static void latorgba(unsigned char *b, unsigned char *a,unsigned char *l,int n)
01155 {
01156 while(n--)
01157 {
01158 l[0] = *b; l[1] = *b;
01159 l[2] = *b; l[3] = *a;
01160 l += 4; b++; a++;
01161 }
01162 }
01163
01164 static void rgbtorgba(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *l,int n)
01165 {
01166 while(n--)
01167 {
01168 l[0] = r[0]; l[1] = g[0];
01169 l[2] = b[0]; l[3] = 0xff;
01170 l += 4; r++; g++; b++;
01171 }
01172 }
01173
01174 static void rgbatorgba(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *a,unsigned char *l,int n)
01175 {
01176 while(n--)
01177 {
01178 l[0] = r[0]; l[1] = g[0];
01179 l[2] = b[0]; l[3] = a[0];
01180 l += 4; r++; g++; b++; a++;
01181 }
01182 }
01183
01184 typedef struct _ImageRec
01185 {
01186 unsigned short imagic;
01187 unsigned short type;
01188 unsigned short dim;
01189 unsigned short xsize, ysize, zsize;
01190 unsigned int min, max;
01191 unsigned int wasteBytes;
01192 char name[80];
01193 unsigned long colorMap;
01194 FILE *file;
01195 unsigned char *tmp, *tmpR, *tmpG, *tmpB;
01196 unsigned long rleEnd;
01197 unsigned int *rowStart;
01198 int *rowSize;
01199 } ImageRec;
01200
01201 static void ConvertShort(unsigned short *array, long length)
01202 {
01203 unsigned b1, b2;
01204 unsigned char *ptr;
01205
01206 ptr = (unsigned char *)array;
01207 while (length--) {
01208 b1 = *ptr++;
01209 b2 = *ptr++;
01210 *array++ = (b1 << 8) | (b2);
01211 }
01212 }
01213
01214 static void ConvertLong(unsigned *array, long length)
01215 {
01216 unsigned b1, b2, b3, b4;
01217 unsigned char *ptr;
01218
01219 ptr = (unsigned char *)array;
01220 while (length--)
01221 {
01222 b1 = *ptr++;
01223 b2 = *ptr++;
01224 b3 = *ptr++;
01225 b4 = *ptr++;
01226 *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
01227 }
01228 }
01229
01230
01231 static ImageRec *ImageOpen(FILE *f)
01232 {
01233 union
01234 {
01235 int testWord;
01236 char testByte[4];
01237 } endianTest;
01238
01239 ImageRec *image;
01240 int swapFlag;
01241 int x;
01242
01243 endianTest.testWord = 1;
01244 if (endianTest.testByte[0] == 1) swapFlag = 1;
01245 else swapFlag = 0;
01246
01247 image = (ImageRec *)malloc(sizeof(ImageRec));
01248 if (image == NULL)
01249 {
01250 fprintf(stderr, "Out of memory!\n");
01251 exit(1);
01252 }
01253
01254 image->file = f;
01255
01256 fread(image, 1, 12, image->file);
01257
01258 if (swapFlag) ConvertShort(&image->imagic, 6);
01259
01260 image->tmp = (unsigned char *)malloc(image->xsize*256);
01261 image->tmpR = (unsigned char *)malloc(image->xsize*256);
01262 image->tmpG = (unsigned char *)malloc(image->xsize*256);
01263 image->tmpB = (unsigned char *)malloc(image->xsize*256);
01264 if (image->tmp == NULL || image->tmpR == NULL || image->tmpG == NULL ||
01265 image->tmpB == NULL)
01266 {
01267 fprintf(stderr, "Out of memory!\n");
01268 exit(1);
01269 }
01270
01271 if ((image->type & 0xFF00) == 0x0100)
01272 {
01273 x = image->ysize * image->zsize * sizeof(unsigned);
01274 image->rowStart = (unsigned *)malloc(x);
01275 image->rowSize = (int *)malloc(x);
01276 if (image->rowStart == NULL || image->rowSize == NULL)
01277 {
01278 fprintf(stderr, "Out of memory!\n");
01279 exit(1);
01280 }
01281 image->rleEnd = 512 + (2 * x);
01282 fseek(image->file, 512+SEEK_SET_POS, SEEK_SET);
01283 fread(image->rowStart, 1, x, image->file);
01284 fread(image->rowSize, 1, x, image->file);
01285 if (swapFlag)
01286 {
01287 ConvertLong(image->rowStart, x/(int)sizeof(unsigned));
01288 ConvertLong((unsigned *)image->rowSize, x/(int)sizeof(int));
01289 }
01290 }
01291 else
01292 {
01293 image->rowStart = NULL;
01294 image->rowSize = NULL;
01295 }
01296 return image;
01297 }
01298
01299
01300 static void ImageClose(ImageRec *image)
01301 {
01302 free(image->tmp);
01303 free(image->tmpR);
01304 free(image->tmpG);
01305 free(image->tmpB);
01306 free(image->rowSize);
01307 free(image->rowStart);
01308 free(image);
01309 }
01310
01311
01312 static void ImageGetRow(ImageRec *image, unsigned char *buf, int y, int z)
01313 {
01314 unsigned char *iPtr, *oPtr, pixel;
01315 int count;
01316
01317 if ((image->type & 0xFF00) == 0x0100)
01318 {
01319 fseek(image->file, (long)image->rowStart[y+z*image->ysize]+SEEK_SET_POS, SEEK_SET);
01320 fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize], image->file);
01321
01322 iPtr = image->tmp;
01323 oPtr = buf;
01324 for (;;)
01325 {
01326 pixel = *iPtr++;
01327 count = (int)(pixel & 0x7F);
01328 if (!count) return;
01329 if (pixel & 0x80) while (count--) *oPtr++ = *iPtr++;
01330 else
01331 {
01332 pixel = *iPtr++;
01333 while (count--) *oPtr++ = pixel;
01334 }
01335 }
01336 }
01337 else
01338 {
01339 fseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize)+SEEK_SET_POS, SEEK_SET);
01340 fread(buf, 1, image->xsize, image->file);
01341 }
01342 }
01343
01344
01345 static unsigned *read_texture(FILE *f, int *width, int *height, int *components)
01346 {
01347 unsigned *base, *lptr;
01348 unsigned char *rbuf, *gbuf, *bbuf, *abuf;
01349 ImageRec *image;
01350 int y;
01351
01352 image = ImageOpen(f);
01353
01354 if (!image) return NULL;
01355 (*width) = image->xsize;
01356 (*height) = image->ysize;
01357 (*components) = image->zsize;
01358
01359 base = (unsigned *)malloc(image->xsize*image->ysize*sizeof(unsigned));
01360 rbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
01361 gbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
01362 bbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
01363 abuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
01364
01365 if(!base || !rbuf || !gbuf || !bbuf) return NULL;
01366 lptr = base;
01367 for (y=0; y<image->ysize; y++)
01368 {
01369 if(image->zsize >= 4)
01370 {
01371 ImageGetRow(image, rbuf, y, 0);
01372 ImageGetRow(image, gbuf, y, 1);
01373 ImageGetRow(image, bbuf, y, 2);
01374 ImageGetRow(image, abuf, y, 3);
01375 rgbatorgba(rbuf,gbuf,bbuf,abuf,(unsigned char *)lptr,image->xsize);
01376 lptr += image->xsize;
01377 }
01378 else if(image->zsize == 3)
01379 {
01380 ImageGetRow(image,rbuf, y, 0);
01381 ImageGetRow(image,gbuf, y, 1);
01382 ImageGetRow(image,bbuf, y, 2);
01383 rgbtorgba(rbuf,gbuf,bbuf,(unsigned char *)lptr,image->xsize);
01384 lptr += image->xsize;
01385 }
01386 else if(image->zsize == 2)
01387 {
01388 ImageGetRow(image,rbuf, y, 0);
01389 ImageGetRow(image,abuf, y, 1);
01390 latorgba(rbuf,abuf,(unsigned char *)lptr,image->xsize);
01391 lptr += image->xsize;
01392 }
01393 else
01394 {
01395 ImageGetRow(image, rbuf, y, 0);
01396 bwtorgba(rbuf,(unsigned char *)lptr,image->xsize);
01397 lptr += image->xsize;
01398 }
01399 }
01400 ImageClose(image);
01401 free(rbuf);
01402 free(gbuf);
01403 free(bbuf);
01404 free(abuf);
01405
01406 return (unsigned *) base;
01407 }
01408
01409
01410 unsigned* texture_to_mask(unsigned* tex, int width, int height)
01411 {
01412 int nSize, i;
01413 unsigned *ret;
01414
01415 nSize = width * height;
01416 ret = (unsigned *)malloc(nSize * sizeof(unsigned));
01417 for (i=0; i<nSize; i++) ret[i] = tex[i] & 0x00ffffff ? 0 : 0x00ffffff;
01418
01419 return ret;
01420 }
01421
01422
01423 int glfLoadBMFFont(char *FName)
01424 {
01425 FILE *f;
01426 char Header[4];
01427 char FontName[97];
01428 int i, flag;
01429 int LEndian;
01430 float tx, ty, tw, th;
01431 unsigned char temp, *tp;
01432 unsigned *texture;
01433 unsigned *mask;
01434 int twidth, theight, tcomp;
01435 float *temp_width;
01436
01437 LEndian = LittleEndian();
01438
01439 f = fopen(FName, "rb");
01440 if (f == NULL) return GLF_ERROR;
01441
01442
01443 fread(Header, 1, 3, f);
01444 Header[3] = 0;
01445 if (strcmp(Header, "BMF")) return GLF_ERROR;
01446
01447
01448 fread(FontName, 1, 96, f);
01449 FontName[96] = 0;
01450
01451
01452
01453 temp_width = (float *)malloc(sizeof(float)*256);
01454
01455
01456 for (i=0; i<256; i++)
01457 {
01458 fread(&tx, 4, 1, f);
01459 fread(&ty, 4, 1, f);
01460 fread(&tw, 4, 1, f);
01461 fread(&th, 4, 1, f);
01462
01463 if (!LEndian)
01464 {
01465 tp = (unsigned char *)&tx;
01466 temp = tp[0]; tp[0] = tp[3]; tp[3] = temp;
01467 temp = tp[1]; tp[1] = tp[2]; tp[2] = temp;
01468 tp = (unsigned char *)&ty;
01469 temp = tp[0]; tp[0] = tp[3]; tp[3] = temp;
01470 temp = tp[1]; tp[1] = tp[2]; tp[2] = temp;
01471 tp = (unsigned char *)&tw;
01472 temp = tp[0]; tp[0] = tp[3]; tp[3] = temp;
01473 temp = tp[1]; tp[1] = tp[2]; tp[2] = temp;
01474 tp = (unsigned char *)&th;
01475 temp = tp[0]; tp[0] = tp[3]; tp[3] = temp;
01476 temp = tp[1]; tp[1] = tp[2]; tp[2] = temp;
01477 }
01478
01479 Symbols[(int)i].x = tx;
01480 Symbols[(int)i].y = ty;
01481 Symbols[(int)i].width = tw;
01482 Symbols[(int)i].height = th;
01483 temp_width[i] = tw;
01484 }
01485
01486
01487 texture = read_texture(f, &twidth, &theight, &tcomp);
01488
01489 mask = texture_to_mask(texture, twidth, theight);
01490
01491
01492 flag = 0;
01493 for (i=0; i<MAX_FONTS; i++)
01494 if (bmf_in_use[i] == 0)
01495 {
01496
01497 bmf_in_use[i] = 1;
01498 bmf_curfont = i;
01499 flag = 1;
01500 break;
01501 }
01502 if (!flag)
01503 {
01504 fclose(f);
01505 free(texture);
01506 free(mask);
01507 free(temp_width);
01508 return -1;
01509 }
01510
01511 m_widths[bmf_curfont].width = temp_width;
01512
01513
01514 glGenTextures(1, &bmf_texture[bmf_curfont]);
01515 glGenTextures(1, &bmf_mask[bmf_curfont]);
01516
01517
01518 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
01519
01520
01521 glBindTexture(GL_TEXTURE_2D, bmf_texture[bmf_curfont]);
01522 glTexImage2D(GL_TEXTURE_2D, 0, 3, twidth, theight, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
01523
01524
01525 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
01526 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
01527
01528
01529 glBindTexture(GL_TEXTURE_2D, bmf_mask[bmf_curfont]);
01530 glTexImage2D(GL_TEXTURE_2D, 0, 3, twidth, theight, 0, GL_RGBA, GL_UNSIGNED_BYTE, mask);
01531 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
01532 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
01533
01534 free(texture);
01535 free(mask);
01536 fclose(f);
01537
01538
01539 list_base[bmf_curfont] = glGenLists(256);
01540 for (i=0; i<256; i++)
01541 {
01542 glNewList(list_base[bmf_curfont]+i, GL_COMPILE);
01543
01544 glBegin(GL_QUADS);
01545 glTexCoord2f(Symbols[(int)i].x, Symbols[(int)i].y); glVertex2f(0, 0);
01546 glTexCoord2f(Symbols[(int)i].x+Symbols[(int)i].width, Symbols[(int)i].y); glVertex2f(Symbols[(int)i].width, 0);
01547 glTexCoord2f(Symbols[(int)i].x+Symbols[(int)i].width, Symbols[(int)i].y+Symbols[(int)i].height); glVertex2f(Symbols[(int)i].width, Symbols[(int)i].height);
01548 glTexCoord2f(Symbols[(int)i].x, Symbols[(int)i].y+Symbols[(int)i].height); glVertex2f(0, Symbols[(int)i].height);
01549 glEnd();
01550 glTranslatef(Symbols[(int)i].width+sym_space, 0, 0);
01551
01552 glEndList();
01553 if (Symbols[(int)i].height > m_max_height[bmf_curfont]) m_max_height[bmf_curfont] = Symbols[(int)i].height;
01554 }
01555 return bmf_curfont;
01556 }
01557
01558
01559 int glfUnloadBMFFontD(int bmf_descriptor)
01560 {
01561 if ((bmf_descriptor < 0) || (bmf_in_use[bmf_descriptor] == 0)) return GLF_ERROR;
01562
01563 bmf_in_use[bmf_descriptor] = 0;
01564
01565 glDeleteTextures(1, &bmf_texture[bmf_descriptor]);
01566 glDeleteTextures(1, &bmf_mask[bmf_descriptor]);
01567
01568 if (bmf_descriptor == bmf_curfont) bmf_curfont = -1;
01569
01570 return GLF_OK;
01571 }
01572
01573
01574 int glfUnloadBMFFont()
01575 {
01576 return glfUnloadBMFFontD(bmf_curfont);
01577 }
01578
01579
01580 void glfStartBitmapDrawing()
01581 {
01582
01583 glGetBooleanv(GL_TEXTURE_2D, &bmf_texturing);
01584 glEnable(GL_TEXTURE_2D);
01585
01586 glBindTexture(GL_TEXTURE_2D, bmf_texture[bmf_curfont]);
01587 }
01588
01589
01590 void glfStopBitmapDrawing()
01591 {
01592
01593 if (bmf_texturing) glEnable(GL_TEXTURE_2D);
01594 else glDisable(GL_TEXTURE_2D);
01595 }
01596
01597
01598 int glfSetCurrentBMFFont(int Font_Descriptor)
01599 {
01600 if ((Font_Descriptor < 0) || (bmf_in_use[Font_Descriptor] == 0)) return GLF_ERROR;
01601
01602 bmf_curfont = Font_Descriptor;
01603 return GLF_OK;
01604 }
01605
01606
01607 int glfGetCurrentBMFFont()
01608 {
01609 return bmf_curfont;
01610 }
01611
01612
01613 void glfDrawBSymbol(char s)
01614 {
01615 if ((bmf_curfont < 0) || (bmf_in_use[bmf_curfont] == 0)) return;
01616
01617 glCallList(list_base[bmf_curfont]+(unsigned char)s);
01618 }
01619
01620
01621 void glfDrawBString(char *s)
01622 {
01623 GLfloat temp_trans;
01624 int i;
01625
01626 temp_trans = 0;
01627
01628 if ((bmf_curfont < 0) || (bmf_in_use[bmf_curfont] == 0)) return;
01629
01630
01631 for (i=0; i<(int)strlen(s); i++)
01632 temp_trans += m_widths[bmf_curfont].width[s[i]] + sym_space;
01633
01634 glListBase(list_base[bmf_curfont]);
01635 if (m_bitmap_string_center == GL_TRUE)
01636 {
01637 glPushMatrix();
01638 glTranslatef(-temp_trans/2, 0, 0);
01639 }
01640 glCallLists(strlen(s), GL_UNSIGNED_BYTE, (unsigned char *)s);
01641 if (m_bitmap_string_center == GL_TRUE) glPopMatrix();
01642 }
01643
01644 void glfDrawBMaskSymbol(char s)
01645 {
01646 if ((bmf_curfont < 0) || (bmf_in_use[bmf_curfont] == 0)) return;
01647
01648 glPushMatrix();
01649 glPushAttrib(GL_CURRENT_BIT);
01650
01651
01652 glColor3ub(0xff, 0xff, 0xff);
01653 glBlendFunc(GL_DST_COLOR, GL_ZERO);
01654 glBindTexture(GL_TEXTURE_2D, bmf_mask[bmf_curfont]);
01655
01656 glCallList(list_base[bmf_curfont]+(unsigned char)s);
01657
01658 glPopAttrib();
01659 glPopMatrix();
01660
01661 glBindTexture(GL_TEXTURE_2D, bmf_texture[bmf_curfont]);
01662
01663
01664 glBlendFunc(GL_ONE, GL_ONE);
01665
01666 glCallList(list_base[bmf_curfont]+(unsigned char)s);
01667 }
01668
01669 void glfDrawBMaskString(char *s)
01670 {
01671 GLfloat temp_trans;
01672 int i;
01673
01674 temp_trans = 0;
01675
01676 if ((bmf_curfont < 0) || (bmf_in_use[bmf_curfont] == 0)) return;
01677
01678
01679 for (i=0; i<(int)strlen(s); i++)
01680 temp_trans += m_widths[bmf_curfont].width[s[i]] + sym_space;
01681
01682 glPushMatrix();
01683 glPushAttrib(GL_CURRENT_BIT);
01684
01685
01686 glColor3ub(0xff, 0xff, 0xff);
01687 glBlendFunc(GL_DST_COLOR, GL_ZERO);
01688 glBindTexture(GL_TEXTURE_2D, bmf_mask[bmf_curfont]);
01689
01690 glListBase(list_base[bmf_curfont]);
01691 if (m_bitmap_string_center == GL_TRUE)
01692 {
01693 glPushMatrix();
01694 glTranslatef(-temp_trans/2, 0, 0);
01695 }
01696 glCallLists(strlen(s), GL_UNSIGNED_BYTE, (unsigned char *)s);
01697 if (m_bitmap_string_center == GL_TRUE) glPopMatrix();
01698
01699 glPopAttrib();
01700 glPopMatrix();
01701
01702 glBindTexture(GL_TEXTURE_2D, bmf_texture[bmf_curfont]);
01703
01704
01705 glBlendFunc(GL_ONE, GL_ONE);
01706 glListBase(list_base[bmf_curfont]);
01707 if (m_bitmap_string_center == GL_TRUE)
01708 {
01709 glPushMatrix();
01710 glTranslatef(-temp_trans/2, 0, 0);
01711 }
01712 glCallLists(strlen(s), GL_UNSIGNED_BYTE, (unsigned char *)s);
01713 if (m_bitmap_string_center == GL_TRUE) glPopMatrix();
01714 }
01715
01716
01717 void glfBitmapStringCentering(GLboolean center)
01718 {
01719 m_bitmap_string_center = center;
01720 }
01721
01722
01723 GLboolean glfBitmapGetStringCentering()
01724 {
01725 return m_bitmap_string_center;
01726 }
01727
01728
01729 void glfSetBRotateAngle(float angle)
01730 {
01731 RotateAngleB = angle;
01732 }