// Quick print function. Limited to 8-bit characters (0-255), left alignment, one line. void font_data::qprint(float x, float y, int align, const char *fmt, ...) { // We want a coordinate system where things coresponding to window pixels. pushScreenCoordinateMatrix(); char text[256]; // Holds the string (max of 255 bytes) va_list ap; // Pointer to list of arguments if (fmt == NULL) // If there's no text *text=0; // do nothing else { va_start(ap, fmt); // Parses the string for variables vsprintf(text, fmt, ap); // and converts symbols to actual numbers va_end(ap); // Results are stored in text } glPushAttrib(GL_LIST_BIT | GL_CURRENT_BIT | GL_ENABLE_BIT | GL_TRANSFORM_BIT); glMatrixMode(GL_MODELVIEW); glDisable(GL_LIGHTING); glEnable(GL_TEXTURE_2D); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glListBase(list_base); float modelview_matrix[16]; glGetFloatv(GL_MODELVIEW_MATRIX, modelview_matrix); glPushMatrix(); glLoadIdentity(); glTranslatef(x,y,0); glMultMatrixf(modelview_matrix); // Call the display lists using the 8-bit text line. glCallLists((GLsizei) strlen(text), GL_UNSIGNED_BYTE, text); glPopMatrix(); glPopAttrib(); pop_projection_matrix(); }
void dsMessageBox::render() { GLfloat alpha; switch (status) { case disappeared: return; break; case appearing: alpha = fading_speed * timer.getDurationSecf(); if (alpha > showing_alpha) { status = showing; timer.recordTime(); } break; case showing: alpha = showing_alpha; if (timer.getDurationSecf() > lasting_time) { status = disappearing; timer.recordTime(); } break; case disappearing: alpha = showing_alpha - fading_speed * timer.getDurationSecf(); if (alpha < 0.0f) { status = disappeared; } break; } x = static_cast<GLfloat>(window_width) / 2.0f; y = window_height - height - 50.0f; extern dsTextManager dstext; pushScreenCoordinateMatrix(); glPushAttrib(GL_LIST_BIT | GL_CURRENT_BIT | GL_ENABLE_BIT | GL_TRANSFORM_BIT); glMatrixMode(GL_MODELVIEW); glEnable(GL_BLEND); glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glDisable(GL_DEPTH_TEST); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glPushMatrix(); glLoadIdentity(); glColor4f(1.0f, 1.0f, 1.0f, alpha); glBegin(GL_QUADS); glVertex2f(x - width / 2, y); glVertex2f(x - width / 2, y + height); glVertex2f(x - width / 2 + width, y + height); glVertex2f(x - width / 2 + width, y); glEnd(); glColor4f(0.0f, 0.0f, 0.0f, alpha / showing_alpha); dstext.print(x - width / 2 + 20.0f, y + 13.0f, message); glPopMatrix(); glPopAttrib(); pop_projection_matrix(); }
///Much like Nehe's glPrint function, but modified to work ///with freetype fonts. void print(const font_data &ft_font, float x, float y, const char *fmt, ...) { // We want a coordinate system where things coresponding to window pixels. pushScreenCoordinateMatrix(); GLuint font=ft_font.list_base; float h=ft_font.h/.63f; //We make the height about 1.5* that of char text[256]; // Holds Our String va_list ap; // Pointer To List Of Arguments if (fmt == NULL) // If There's No Text *text=0; // Do Nothing else { va_start(ap, fmt); // Parses The String For Variables vsprintf(text, fmt, ap); // And Converts Symbols To Actual Numbers va_end(ap); // Results Are Stored In Text } //Here is some code to split the text that we have been //given into a set of lines. //This could be made much neater by using //a regular expression library such as the one avliable from //boost.org (I've only done it out by hand to avoid complicating //this tutorial with unnecessary library dependencies). const char *start_line=text; vector<string> lines; const char * c = text;; //for(const char *c=text;*c;c++) { for(; *c; c++) { if(*c=='\n') { string line; for(const char *n=start_line; n<c; n++) line.append(1,*n); lines.push_back(line); start_line=c+1; } } if(start_line) { string line; for(const char *n=start_line; n<c; n++) line.append(1,*n); lines.push_back(line); } glPushAttrib(GL_LIST_BIT | GL_CURRENT_BIT | GL_ENABLE_BIT | GL_TRANSFORM_BIT); glMatrixMode(GL_MODELVIEW); glDisable(GL_LIGHTING); glEnable(GL_TEXTURE_2D); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glListBase(font); float modelview_matrix[16]; glGetFloatv(GL_MODELVIEW_MATRIX, modelview_matrix); //This is where the text display actually happens. //For each line of text we reset the modelview matrix //so that the line's text will start in the correct position. //Notice that we need to reset the matrix, rather than just translating //down by h. This is because when each character is //draw it modifies the current matrix so that the next character //will be drawn immediatly after it. for(unsigned int i=0; i<lines.size(); i++) { glPushMatrix(); glLoadIdentity(); glTranslatef(x,y-h*i,0); glMultMatrixf(modelview_matrix); // The commented out raster position stuff can be useful if you need to // know the length of the text that you are creating. // If you decide to use it make sure to also uncomment the glBitmap command // in make_dlist(). // glRasterPos2f(0,0); glCallLists(lines[i].length(), GL_UNSIGNED_BYTE, lines[i].c_str()); // float rpos[4]; // glGetFloatv(GL_CURRENT_RASTER_POSITION ,rpos); // float len=x-rpos[0]; glPopMatrix(); } glPopAttrib(); pop_projection_matrix(); }
// Much like Nehe's glPrint function, but modified to work // with freetype fonts. void font_data::print(float x, float y, int align, const char *fmt, ...) { // We want a coordinate system where things coresponding to window pixels. pushScreenCoordinateMatrix(); //We make the height about 1.5* that of float ht= h/.63f; char text[256]; // Holds the string (max of 255 bytes) va_list ap; // Pointer to list of arguments if (fmt == NULL) // If there's no text *text=0; // do nothing else { va_start(ap, fmt); // Parses the string for variables vsprintf(text, fmt, ap); // and converts symbols to actual numbers va_end(ap); // Results are stored in text } vector<ucs2string> lines; vector<int> widths; split_and_convert((uchar*) text, lines, widths); glPushAttrib(GL_LIST_BIT | GL_CURRENT_BIT | GL_ENABLE_BIT | GL_TRANSFORM_BIT); glMatrixMode(GL_MODELVIEW); glDisable(GL_LIGHTING); glEnable(GL_TEXTURE_2D); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glListBase(list_base); float modelview_matrix[16]; glGetFloatv(GL_MODELVIEW_MATRIX, modelview_matrix); //This is where the text display actually happens. //For each line of text we reset the modelview matrix //so that the line's text will start in the correct position. //Notice that we need to reset the matrix, rather than just translating //down by h. This is because when each character is //draw it modifies the current matrix so that the next character //will be drawn immediatly after it. for (unsigned int i = 0; i < lines.size(); ++i) { float xmod = x; float len = (float) widths[i]; //= text_length(lines[i].c_str()); if ( align == CENTER ) xmod -= floor(len / 2); else if ( align == RIGHT ) xmod -= len; glPushMatrix(); glLoadIdentity(); glTranslatef(xmod,y-ht*i,0); glMultMatrixf(modelview_matrix); // Call the display lists using the UCS-2 line. glCallLists((GLsizei)lines[i].length(), GL_UNSIGNED_SHORT, lines[i].c_str()); glPopMatrix(); } glPopAttrib(); pop_projection_matrix(); }
void print(font_data *ft_font, int color, int XALIGN, int YALIGN, int x, int y, int length, const char *text, bool onHUD) { int i=0,j,textlength; fontbounds returnval,dummy; float xoff = 0.0,yoff = 0.0; int start,end,toklen; int X,Y; GLuint font; returnval.width = 0.0; returnval.height = 0.0; if (!(textlength = MIN(strlen(text),length))) return; font=ft_font->list_base; returnval = nprintsize(ft_font,length,"%s",text); yoff = (returnval.height/2.0f)*((float)YALIGN) - ft_font->h; glListBase(font); if (onHUD) pushScreenCoordinateMatrix(); glPushAttrib(GL_LIST_BIT | GL_CURRENT_BIT | GL_ENABLE_BIT | GL_TRANSFORM_BIT); glMatrixMode(GL_MODELVIEW); glDisable(GL_LIGHTING); glEnable(GL_TEXTURE_2D); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glGetFloatv(GL_MODELVIEW_MATRIX, modelview_matrix); /* This is where the text display actually happens. * For each line of text we reset the modelview matrix * so that the line's text will start in the correct position. * Notice that we need to reset the matrix, rather than just translating * down by h. This is because when each character is * draw it modifies the current matrix so that the next character * will be drawn immediatly after it. */ /* make sure not to use mytok until we are done!!! */ start = 0; for (;;) { for (end=start;end<textlength;++end) if (text[end] == '\n') { break; } toklen = end - start; dummy.width = 0.0; for (j=start;j<=end-1;++j) dummy.width = dummy.width + ft_font->W[(GLubyte)text[j]]; xoff = - (dummy.width/2.0f)*((float)XALIGN); glPushMatrix(); glLoadIdentity(); X = (int)(x + xoff); Y = (int)(y - ft_font->linespacing*i + yoff); if (color) set_alphacolor(color); if (onHUD) glTranslatef(X, Y, 0); else glTranslatef(X * clData.scale,Y * clData.scale, 0); glMultMatrixf(modelview_matrix); glCallLists(toklen, GL_UNSIGNED_BYTE, (GLubyte *) &text[start]); glPopMatrix(); ++i; if (end >= textlength - 1) break; start = end + 1; } glPopAttrib(); if (onHUD) pop_projection_matrix(); }