//Draw the outline of a rectangle using the specified color. void drawRectOutline( const Rect &rect, const GFXColor &color, float lineWidth ) { GFXDisable( TEXTURE0 ); GFXLineWidth( lineWidth ); GFXColorf( color ); const float verts[5 * 3] = { rect.left(), rect.top(), 0, rect.right(), rect.top(), 0, rect.right(), rect.bottom(), 0, rect.left(), rect.bottom(), 0, rect.left(), rect.top(), 0, }; GFXDraw( GFXLINESTRIP, verts, 5 ); GFXEnable( TEXTURE0 ); }
void TextArea::RenderTextItem( TextAreaItem *current, int level ) { static int count = 0; float new_y = 0, new_x = 0; int max = 0; int cur = 0; if (current == 0) return; if (level == 0) count = 0; if ( (count-top_item_number) >= max_lines ) return; if (level > 0) { if (count < top_item_number) {count++; } else { new_y = ycoord[5]-( text_spacing*(count+1-top_item_number) )+horizontal_spacer; new_x = xcoord[5]+( horizontal_per_level*(level-1) ); GFXColorf( current->col ); ShowText( new_x, new_y, width[5], font_size, current->description, do_multiline ); count++; } } max = current->child_count; if (max <= 0) return; for (cur = 0; cur < max; cur++) RenderTextItem( current->child[cur], level+1 ); }
void SphereDisplay::DrawBackground(const Sensor& sensor, const ViewArea& radarView) { // Split crosshair if (!radarView.IsActive()) return; GFXColor groundColor = radarView.GetColor(); float velocity = sensor.GetPlayer()->GetWarpVelocity().Magnitude(); float logvelocity = 3.0; // std::log10(1000.0); if (velocity > 1000.0) { // Max logvelocity is log10(speed_of_light) = 10.46 logvelocity = std::log10(velocity); } const float size = 3.0 * logvelocity; // [9; 31] const float xground = size / g_game.x_resolution; const float yground = size / g_game.y_resolution; Vector center = radarView.Scale(Vector(0.0, 0.0, 0.0)); GFXEnable(SMOOTH); GFXLineWidth(1); GFXColorf(groundColor); GFXBegin(GFXLINE); GFXVertexf(Vector(center.x - 2.0 * xground, center.y, center.z)); GFXVertexf(Vector(center.x - xground, center.y, center.z)); GFXVertexf(Vector(center.x + 2.0 * xground, center.y, center.z)); GFXVertexf(Vector(center.x + xground, center.y, center.z)); GFXVertexf(Vector(center.x, center.y - 2.0 * yground, center.z)); GFXVertexf(Vector(center.x, center.y - yground, center.z)); GFXVertexf(Vector(center.x, center.y + 2.0 * yground, center.z)); GFXVertexf(Vector(center.x, center.y + yground, center.z)); GFXEnd(); GFXDisable(SMOOTH); }
void SphereDisplay::DrawTrack(const Sensor& sensor, const ViewArea& radarView, const Track& track, bool negate_z) { if (!radarView.IsActive()) return; GFXColor color = sensor.GetColor(track); Vector position = track.GetPosition(); if (negate_z) position.z=-position.z; if (position.z < 0){ static bool negate_z = XMLSupport::parse_bool( vs_config->getVariable( "graphics", "hud", "show_negative_blips_as_positive", "true" )); if (negate_z) position.z=-position.z; else position.z = .125; } const float trackSize = 2.0; // FIXME: Jitter only on boundary, not in center if (sensor.InsideNebula()) { Jitter(0.02, 0.04, position); } else { const bool isNebula = (track.GetType() == Track::Type::Nebula); const bool isEcmActive = track.HasActiveECM(); if (isNebula || isEcmActive) { float error = 0.02 * trackSize; Jitter(error, error, position); } } // The magnitude is used to calculate the unit vector. With subtle scaling // of the magnitude we generate a unit vector whose length will vary from // innerSphere to 1.0, depending on the distance to the object. Combined // with the OpenGL z-buffering, this will ensure that close tracks are drawn // on top of distant tracks. float magnitude = position.Magnitude(); float scaleFactor = 0.0; // [0; 1] where 0 = border, 1 = center const float maxRange = sensor.GetMaxRange(); if (magnitude <= maxRange) { // [innerSphere; 1] scaleFactor = (1.0 - innerSphere) * (maxRange - magnitude) / maxRange; magnitude /= (1.0 - scaleFactor); } Vector scaledPosition = Vector(-position.x, position.y, position.z) / magnitude; Vector head = radarView.Scale(scaledPosition); GFXColor headColor = color; if (sensor.UseThreatAssessment()) { float dangerRate = GetDangerRate(sensor.IdentifyThreat(track)); if (dangerRate > 0.0) { // Blinking track headColor.a *= cosf(dangerRate * radarTime); } } // Fade out dying ships if (track.IsExploding()) { headColor.a *= (1.0 - track.ExplodingProgress()); } GFXColorf(headColor); if (sensor.IsTracking(track)) { DrawTargetMarker(head, trackSize); } GFXPointSize(trackSize); GFXBegin(GFXPOINT); GFXVertexf(head); GFXEnd(); }
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; }
// Draw specified lines of text. void PaintText::drawLines(int start, int count) const { // Make sure we hav a display list. calcLayoutIfNeeded(); // Make sure we have something to do. if(m_lines.empty()) { return; } // Initialize the graphics state. GFXToggleTexture(false,0); if(gl_options.smooth_lines) { glEnable(GL_LINE_SMOOTH); } GFXPushBlendMode(); GFXBlendMode(SRCALPHA,INVSRCALPHA); glPushMatrix(); // Keep track of line position. float lineTop = m_rect.top(); // Figure ending line index. const int end = guiMin(start + count, m_lines.size()); // Loop through the display list lines. for(int i=start; i<end; i++) { const TextLine& line = m_lines[i]; // Make sure we can paint this line in the vertical space we have left. if(lineTop - line.height*LINE_HEIGHT_EPSILON < m_rect.origin.y) { // Not enough space to draw this line. break; } // Position at the start of the line. glLoadIdentity(); glTranslatef(m_rect.origin.x+line.x, lineTop-line.baseLine, 0.0); if (line.fragments.size()) { GFXColorf(line.fragments[0].color); } if (!useStroke()){ glRasterPos2f(0,0); }else glScaled(m_horizontalScaling, m_verticalScaling, 1.0); float rasterpos=0; // Draw each fragment. for(vector<TextFragment>::const_iterator frag=line.fragments.begin(); frag!=line.fragments.end(); frag++) { if(frag->start == ELLIPSIS_FRAGMENT) { // We have a special-case for the ellipsis at the end of a line. drawChars(ELLIPSIS_STRING, 0, 2, frag->font, frag->color,rasterpos); } else { rasterpos=drawChars(m_text, frag->start, frag->end, frag->font, frag->color,rasterpos); } } // Top of next line. lineTop -= line.height; } glRasterPos2f(0,0); // Undo graphics state GFXPopBlendMode(); if(gl_options.smooth_lines) { glDisable(GL_LINE_SMOOTH); } glPopMatrix(); GFXToggleTexture(true,0); }