int TextPlane::Draw(const string & newText, int offset,bool startlower, bool force_highquality, bool automatte) { int retval=1; bool drawbg = (bgcol.a!=0); static unsigned int * display_lists=CreateLists (); // some stuff to draw the text stuff string::const_iterator text_it = newText.begin(); static bool use_bit = force_highquality||XMLSupport::parse_bool(vs_config->getVariable ("graphics","high_quality_font","false")); static float font_point = XMLSupport::parse_float (vs_config->getVariable ("graphics","font_point","16")); static bool font_antialias = XMLSupport::parse_bool (vs_config->getVariable ("graphics","font_antialias","true")); void * fnt = getFont(); static float std_wid=glutStrokeWidth (GLUT_STROKE_ROMAN,'W'); myFontMetrics.i=font_point*std_wid/(119.05+33.33); if (use_bit) myFontMetrics.i=glutBitmapWidth(fnt,'W'); myFontMetrics.j=font_point; myFontMetrics.i/=.5*g_game.x_resolution; myFontMetrics.j/=.5*g_game.y_resolution; float tmp,row, col; float origcol,origrow; GetPos (row,col); GetPos(row,origcol); float rowheight=use_bit?getFontHeight():myFontMetrics.j; myFontMetrics.j=rowheight; if (startlower) { row -= rowheight; } GFXPushBlendMode(); glLineWidth (1); if (!use_bit&&font_antialias) { GFXBlendMode (SRCALPHA,INVSRCALPHA); if(gl_options.smooth_lines) { glEnable(GL_LINE_SMOOTH); } }else { GFXBlendMode (SRCALPHA,INVSRCALPHA); if(gl_options.smooth_lines) { glDisable(GL_LINE_SMOOTH); } } GFXColorf(this->col); GFXDisable (DEPTHTEST); GFXDisable (CULLFACE); GFXDisable (LIGHTING); GFXDisable (TEXTURE0); GFXDisable (TEXTURE1); glPushMatrix(); glLoadIdentity(); if (!automatte&&drawbg) { GFXColorf(this->bgcol); DrawSquare(col,this->myDims.i,row-rowheight*.25,row+rowheight); } GFXColorf(this->col); int entercount=0; for (;entercount<offset&&text_it!=newText.end();text_it++) { if (*text_it=='\n') entercount++; } glTranslatef(col,row,0); // glRasterPos2f (g_game.x_resolution*(1-(col+1)/2),g_game.y_resolution*(row+1)/2); glRasterPos2f (0,0); float scalex=1; float scaley=1; int potentialincrease=0; if (!use_bit) { int numplayers=1; if (_Universe) // _Universe can be NULL during bootstrap. numplayers = (_Universe->numPlayers()>3?_Universe->numPlayers()/2: _Universe->numPlayers()); scalex=numplayers*myFontMetrics.i/std_wid; scaley=myFontMetrics.j/(119.05+33.33); } glScalef (scalex,scaley,1); bool firstThroughLoop=true; GFXColor currentCol (this->col); while(text_it != newText.end() && (firstThroughLoop||row>myDims.j-rowheight*.25)) { unsigned char myc = *text_it; if (myc=='_') { myc = ' '; } float shadowlen = 0; if(myc=='\t') { shadowlen=glutBitmapWidth(fnt,' ')*5./(.5*g_game.x_resolution); } else { if (use_bit) { shadowlen = glutBitmapWidth (fnt,myc)/(float)(.5*g_game.x_resolution); // need to use myc -- could have transformed '_' to ' ' } else { shadowlen = myFontMetrics.i*glutStrokeWidth(GLUT_STROKE_ROMAN,myc)/std_wid; } } if (*text_it=='#') { if (newText.end()-text_it>6) { float r,g,b; r = TwoCharToFloat (*(text_it+1),*(text_it+2)); g = TwoCharToFloat (*(text_it+3),*(text_it+4)); b = TwoCharToFloat (*(text_it+5),*(text_it+6)); if (r==0&&g==0&&b==0) { currentCol = this->col; }else { currentCol = GFXColor(r, g, b, this->col.a); } GFXColorf(currentCol); static bool setRasterPos= XMLSupport::parse_bool(vs_config->getVariable("graphics","set_raster_text_color","true")); if (use_bit&&setRasterPos) glRasterPos2f(col-origcol,0); text_it = text_it+6; } else { break; } text_it++; continue; }else if(*text_it>=32) {//always true if(automatte){ GFXColorf(this->bgcol); DrawSquare(col-origcol,col-origcol+shadowlen/scalex,-rowheight*.25/scaley,rowheight*.75/scaley); GFXColorf(currentCol); } //glutStrokeCharacter (GLUT_STROKE_ROMAN,*text_it); retval+=potentialincrease; potentialincrease=0; int lists = display_lists[myc+(isInside()?128:0)]; if (lists) { GFXCallList(lists); }else{ if (use_bit){ glutBitmapCharacter (fnt,myc); } else{ glutStrokeCharacter (GLUT_STROKE_ROMAN,myc); } } } if(*text_it=='\t') { if(automatte){ GFXColorf(this->bgcol); DrawSquare(col-origcol,col-origcol+shadowlen*5/(.5*g_game.x_resolution),-rowheight*.25/scaley,rowheight*.75/scaley); GFXColorf(currentCol); } col+=shadowlen; glutBitmapCharacter (fnt,' '); glutBitmapCharacter (fnt,' '); glutBitmapCharacter (fnt,' '); glutBitmapCharacter (fnt,' '); glutBitmapCharacter (fnt,' '); } else { col+=shadowlen; } if(doNewLine(text_it,newText.end(),col,myDims.i, myFontMetrics.i,row-rowheight<=myDims.j)){ GetPos (tmp,col); firstThroughLoop=false; row -= rowheight; glPopMatrix(); glPushMatrix (); glLoadIdentity(); if (!automatte&&drawbg) { GFXColorf(this->bgcol); DrawSquare(col,this->myDims.i,row-rowheight*.25,row+rowheight*.75); } if (*text_it=='\n') { currentCol = this->col; } GFXColorf(currentCol); glTranslatef (col,row,0); glScalef(scalex,scaley,1); glRasterPos2f(0,0); potentialincrease++; } text_it++; } if(gl_options.smooth_lines) { glDisable(GL_LINE_SMOOTH); } glPopMatrix(); GFXPopBlendMode(); GFXColorf(this->col); return retval; }
void GFXVertexList::Draw( enum POLYTYPE *mode, const INDEX index, const int numlists, const int *offsets ) { //Hardware support for this seems... sketchy if (vbo_data == 0 && display_list != 0) { //Big issue: display lists cannot discriminate between lines/points/triangles, //so, for now, we'll limit smoothing to single-mode GFXVertexLists, which, by the way, //are the only ones being used, AFAIK. bool blendchange = false; if ( unique_mode && (numlists > 0) ) { switch (*mode) { case GFXLINE: case GFXLINESTRIP: case GFXPOLY: case GFXPOINT: if ( ( (*mode == GFXPOINT) && gl_options.smooth_points ) || ( (*mode != GFXPOINT) && gl_options.smooth_lines ) ) { BLENDFUNC src, dst; GFXGetBlendMode( src, dst ); if ( (dst != ZERO) && ( (src == ONE) || (src == SRCALPHA) ) ) { GFXPushBlendMode(); GFXBlendMode( SRCALPHA, dst ); GFXEnable( SMOOTH ); blendchange = true; } } break; default: break; } } GFXCallList( display_list ); if (blendchange) { GFXPopBlendMode(); GFXDisable( SMOOTH ); } ++gl_batches_this_frame; } else { int totoffset = 0; if (changed&HAS_INDEX) { long stride = changed&HAS_INDEX; GLenum indextype = (changed&INDEX_BYTE) ? GL_UNSIGNED_BYTE : ( (changed&INDEX_SHORT) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT ); bool use_vbo = vbo_data != 0; use_vbo = use_vbo && memcmp( &index, &this->index, sizeof (INDEX) ) == 0; if (use_vbo) { #ifndef NO_VBO_SUPPORT GFXBindElementBuffer( display_list ); #else use_vbo = false; #endif } else { #ifndef NO_VBO_SUPPORT if (vbo_data) GFXBindElementBuffer( 0 ); #endif } if (glMultiDrawElements_p != NULL && numlists > 1) { static std::vector< bool > drawn; static std::vector< const GLvoid* >glindices; static std::vector< GLsizei >glcounts; drawn.clear(); drawn.resize( numlists, false ); for (int i = 0; i < numlists; totoffset += offsets[i++]) if (!drawn[i]) { glindices.clear(); glcounts.clear(); int totcount = 0; for (long j = i, offs = totoffset; j < numlists; offs += offsets[j++]) { totcount += offsets[j]; if ( !drawn[j] && (mode[j] == mode[i]) ) { glindices.push_back( use_vbo ? (GLvoid*) (stride*offs) : (GLvoid*) &index.b[stride*offs] ); glcounts.push_back( offsets[j] ); drawn[j] = true; } } if (glindices.size() == 1) glDrawElements( PolyLookup( mode[i] ), glcounts[0], indextype, glindices[0] ); else glMultiDrawElements_p( PolyLookup( mode[i] ), &glcounts[0], indextype, &glindices[0], glindices.size() ); ++gl_batches_this_frame; gl_vertices_this_frame += totcount; } } else { for (int i = 0; i < numlists; i++) { glDrawElements( PolyLookup( mode[i] ), offsets[i], indextype, use_vbo ? (GLvoid*) (stride*totoffset) : (GLvoid*)&index.b[stride*totoffset] ); //changed&INDEX_BYTE == stride! totoffset += offsets[i]; ++gl_batches_this_frame; gl_vertices_this_frame += offsets[i]; } } } else { if (glMultiDrawArrays_p) { static std::vector< bool > drawn; static std::vector< GLint > gloffsets; static std::vector< GLsizei >glcounts; drawn.clear(); drawn.resize( numlists, false ); for (int i = 0; i < numlists; totoffset += offsets[i++]) if (!drawn[i]) { gloffsets.clear(); glcounts.clear(); int totcount = 0; for (int j = i, offs = totoffset; j < numlists; offs += offsets[j++]) { totcount += offsets[j]; if ( !drawn[j] && (mode[j] == mode[i]) ) { gloffsets.push_back( offs ); glcounts.push_back( offsets[j] ); drawn[j] = true; } } bool blendchange = false; switch (mode[i]) { case GFXLINE: case GFXLINESTRIP: case GFXPOLY: case GFXPOINT: if ( ( (mode[i] == GFXPOINT) && gl_options.smooth_points ) || ( (mode[i] != GFXPOINT) && gl_options.smooth_lines ) ) { BLENDFUNC src, dst; GFXGetBlendMode( src, dst ); if ( (dst != ZERO) && ( (src == ONE) || (src == SRCALPHA) ) ) { GFXPushBlendMode(); GFXBlendMode( SRCALPHA, dst ); GFXEnable( SMOOTH ); blendchange = true; } } break; default: break; } if (gloffsets.size() == 1) glDrawArrays( PolyLookup( mode[i] ), gloffsets[0], glcounts[0] ); else glMultiDrawArrays_p( PolyLookup( mode[i] ), &gloffsets[0], &glcounts[0], gloffsets.size() ); if (blendchange) { GFXPopBlendMode(); GFXDisable( SMOOTH ); } ++gl_batches_this_frame; gl_vertices_this_frame += totcount; } } else { for (int i = 0; i < numlists; i++) { bool blendchange = false; switch (mode[i]) { case GFXLINE: case GFXLINESTRIP: case GFXPOLY: case GFXPOINT: if ( ( (mode[i] == GFXPOINT) && gl_options.smooth_points ) || ( (mode[i] != GFXPOINT) && gl_options.smooth_lines ) ) { BLENDFUNC src, dst; GFXGetBlendMode( src, dst ); if ( (dst != ZERO) && ( (src == ONE) || (src == SRCALPHA) ) ) { GFXPushBlendMode(); GFXBlendMode( SRCALPHA, dst ); GFXEnable( SMOOTH ); blendchange = true; } } break; default: break; } glDrawArrays( PolyLookup( mode[i] ), totoffset, offsets[i] ); totoffset += offsets[i]; if (blendchange) { GFXPopBlendMode(); GFXDisable( SMOOTH ); } ++gl_batches_this_frame; gl_vertices_this_frame += offsets[i]; } } } } }