#include "precompiled.h" #include "InfoBox.h" #include "ui/UIGlobals.h" #include "types.h" #include "ogl.h" #include "timer.h" #include "NPFont.h" #include "NPFontManager.h" #include "OverlayText.h" #include "Renderer.h" static const char* DefaultFontName="mods/official/fonts/verdana18.fnt"; CInfoBox::CInfoBox() : m_Font(0), m_Visible(false) { m_LastFPSTime=0; m_Stats.Reset(); } void CInfoBox::Initialise() { m_Font=NPFontManager::instance().add(DefaultFontName); } void CInfoBox::Render() { if (!m_Visible) return; const u32 panelColor=0x80f9527d; const u32 borderColor=0xfffa0043; // setup renderstate glDisable(GL_DEPTH_TEST); glDepthMask(0); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); // load identity modelview glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); // setup ortho view glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); int w=g_Renderer.GetWidth(); int h=g_Renderer.GetHeight(); glOrtho(0,w,0,h,-1,1); glColor4ubv((const GLubyte*) &panelColor); // render infobox as quad glBegin(GL_QUADS); glVertex2i(3,h-180); glVertex2i(150,h-180); glVertex2i(150,h-2); glVertex2i(3,h-2); glEnd(); // render border glColor4ubv((const GLubyte*) &borderColor); glLineWidth(2); glBegin(GL_LINE_LOOP); glVertex2i(1,h-182); glVertex2i(152,h-182); glVertex2i(152,h-1); glVertex2i(1,h-1); glEnd(); // render any info now, assuming we've got a font if (m_Font) { RenderInfo(); } // restore matrices glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); // restore renderstate glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); glDepthMask(1); } void render(COverlayText* overlaytext) { // get font on overlay NPFont* font=overlaytext->GetFont(); if (!font) return; const CStr& str=overlaytext->GetString(); int len=(int)str.Length(); if (len==0) return; // bind to font texture g_Renderer.SetTexture(0,&font->texture()); // setup texenv glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE); glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PRIMARY_COLOR); glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); // get overlay's position float x,y; overlaytext->GetPosition(x,y); // setup color const CColor& color=overlaytext->GetColor(); glColor4fv((float*) &color); float x0=x; float ftw=float(font->textureWidth()); float fth=float(font->textureHeight()); float fdy=float(font->height())/fth; // submit quad verts for each character glBegin(GL_QUADS); for (int i=0;ichardata(str[i]); const int* cw=&cdata._widthA; if (cw[0]>0) x0+=cw[0]; // find the tile for this character unsigned char c0=unsigned char(str[i]-32); int ix=c0%font->numCols(); int iy=c0/font->numCols(); // calc UV coords of character in texture float u0=float(ix*font->maxcharwidth()+cw[0]-1)/ftw; float v0=float(iy*(font->height()+1))/fth; float u1=u0+float(cw[1]+1)/ftw; float v1=v0+fdy; glTexCoord2f(u0,v0); glVertex2f(x0,y); glTexCoord2f(u1,v0); glVertex2f(x0+float(cw[1]+1),y); glTexCoord2f(u1,v1); glVertex2f(x0+float(cw[1]+1),y+font->height()); glTexCoord2f(u0,v1); glVertex2f(x0,y+font->height()); // translate such that next character is rendered in correct position x0+=float(cw[1]+1); if (cw[2]>0) x0+=cw[2]; } glEnd(); // unbind texture .. g_Renderer.SetTexture(0,0); } void CInfoBox::RenderInfo() { int w=g_Renderer.GetWidth(); int h=g_Renderer.GetHeight(); char buf[32]; if (m_LastStats.m_Counter) { u32 dy=m_Font->height()+2; float y=float(h-dy); sprintf(buf,"FPS: %d",int(m_LastStats.m_Counter/m_LastTickTime)); COverlayText fpstext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1)); render(&fpstext); y-=dy; sprintf(buf,"FT: %.2f",1000*m_LastTickTime/float(m_LastStats.m_Counter)); COverlayText fttext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1)); render(&fttext); y-=dy; u32 totalTris=(u32)(m_LastStats.m_TerrainTris+m_LastStats.m_ModelTris); sprintf(buf,"TPF: %d",int(totalTris/m_LastStats.m_Counter)); COverlayText tpftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1)); render(&tpftext); y-=dy; sprintf(buf,"TeTPF: %d",int(m_LastStats.m_TerrainTris/m_LastStats.m_Counter)); COverlayText tetpftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1)); render(&tetpftext); y-=dy; sprintf(buf,"MTPF: %d",int(m_LastStats.m_ModelTris/m_LastStats.m_Counter)); COverlayText mtpftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1)); render(&mtpftext); y-=dy; sprintf(buf,"DCPF: %d",int(m_LastStats.m_DrawCalls/m_LastStats.m_Counter)); COverlayText dcpftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1)); render(&dcpftext); y-=dy; sprintf(buf,"SPPF: %d",int(m_LastStats.m_BlendSplats/m_LastStats.m_Counter)); COverlayText sppftext(5,y,0,DefaultFontName,buf,CColor(1,1,1,1)); render(&sppftext); y-=dy; } } void CInfoBox::OnFrameComplete() { // accumulate stats m_Stats+=g_Renderer.GetStats(); // fps check double cur_time=get_time(); if (cur_time-m_LastFPSTime>1) { // save tick time m_LastTickTime=cur_time-m_LastFPSTime; // save stats m_LastStats=m_Stats; // save time m_LastFPSTime=cur_time; // reset stats m_Stats.Reset(); } }