static void DrawProfiler() { font->SetTextColor(1,1,1,1); // draw the background of the window { CVertexArray* va = GetVertexArray(); va->Initialize(); va->AddVertex0(start_x, start_y + lineHeight + 0.005f, 0); va->AddVertex0(end_x, start_y + lineHeight + 0.005f, 0); va->AddVertex0(start_x, start_y - profiler.profile.size() * lineHeight - 0.01f, 0); va->AddVertex0(end_x, start_y - profiler.profile.size() * lineHeight - 0.01f, 0); glColor4f(0.0f, 0.0f, 0.5f, 0.5f); va->DrawArray0(GL_TRIANGLE_STRIP); } const float textSize = 0.5f; // table header { const float fStartY = start_y + 0.005f; float fStartX = start_x + 0.005f + 0.015f + 0.005f; // print total-time running since application start fStartX += 0.04f; font->glFormat(fStartX, fStartY, textSize, FONT_SHADOW | FONT_DESCENDER | FONT_SCALE | FONT_NORM | FONT_RIGHT, "totaltime"); // print percent of CPU time used within the last 500ms fStartX += 0.06f; font->glFormat(fStartX, fStartY, textSize, FONT_SHADOW | FONT_DESCENDER | FONT_SCALE | FONT_NORM | FONT_RIGHT, "cur-%%usage"); fStartX += 0.04f; font->glFormat(fStartX, fStartY, textSize, FONT_SHADOW | FONT_DESCENDER | FONT_SCALE | FONT_NORM | FONT_RIGHT, "max-%%usage"); fStartX += 0.04f; font->glFormat(fStartX, fStartY, textSize, FONT_SHADOW | FONT_DESCENDER | FONT_SCALE | FONT_NORM | FONT_RIGHT, "lag"); // print timer name fStartX += 0.01f; font->glFormat(fStartX, fStartY, textSize, FONT_SHADOW | FONT_DESCENDER | FONT_SCALE | FONT_NORM, "title"); } // draw the textual info (total-time, short-time percentual time, timer-name) int y = 1; for (auto pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi, ++y) { const auto& profileData = pi->second; const float fStartY = start_y - y * lineHeight; float fStartX = start_x + 0.005f + 0.015f + 0.005f; // print total-time running since application start fStartX += 0.04f; font->glFormat(fStartX, fStartY, textSize, FONT_DESCENDER | FONT_SCALE | FONT_NORM | FONT_RIGHT, "%.2fs", profileData.total.toSecsf()); // print percent of CPU time used within the last 500ms fStartX += 0.06f; font->glFormat(fStartX, fStartY, textSize, FONT_DESCENDER | FONT_SCALE | FONT_NORM | FONT_RIGHT, "%.2f%%", profileData.percent * 100); fStartX += 0.04f; font->glFormat(fStartX, fStartY, textSize, FONT_DESCENDER | FONT_SCALE | FONT_NORM | FONT_RIGHT, "\xff\xff%c%c%.2f%%", profileData.newPeak?1:255, profileData.newPeak?1:255, profileData.peak * 100); fStartX += 0.04f; font->glFormat(fStartX, fStartY, textSize, FONT_DESCENDER | FONT_SCALE | FONT_NORM | FONT_RIGHT, "\xff\xff%c%c%.0fms", profileData.newLagPeak?1:255, profileData.newLagPeak?1:255, profileData.maxLag); // print timer name fStartX += 0.01f; font->glFormat(fStartX, fStartY, textSize, FONT_DESCENDER | FONT_SCALE | FONT_NORM, pi->first); } // draw the Timer selection boxes const float boxSize = lineHeight*0.9; const float selOffset = boxSize*0.2; glPushMatrix(); glTranslatef(start_x + 0.005f, start_y + boxSize, 0); // we are now at upper left of first box CVertexArray* va = GetVertexArray(); CVertexArray* va2 = GetVertexArray(); va->Initialize(); va2->Initialize(); int i = 1; for (auto pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi, ++i){ auto& fc = pi->second.color; SColor c(fc[0], fc[1], fc[2]); va->AddVertexC(float3(0, -i*lineHeight, 0), c); // upper left va->AddVertexC(float3(0, -i*lineHeight-boxSize, 0), c); // lower left va->AddVertexC(float3(boxSize, -i*lineHeight-boxSize, 0), c); // lower right va->AddVertexC(float3(boxSize, -i*lineHeight, 0), c); // upper right if (pi->second.showGraph) { va2->AddVertex0(lineHeight+selOffset, -i*lineHeight-selOffset, 0); // upper left va2->AddVertex0(lineHeight+selOffset, -i*lineHeight-boxSize+selOffset, 0); // lower left va2->AddVertex0(lineHeight+boxSize-selOffset, -i*lineHeight-boxSize+selOffset, 0); // lower right va2->AddVertex0(lineHeight+boxSize-selOffset, -i*lineHeight-selOffset, 0); // upper right } } // draw the boxes va->DrawArrayC(GL_QUADS); // draw the 'graph view disabled' cross glColor3f(1,0,0); va2->DrawArray0(GL_QUADS); glPopMatrix(); // draw the graph glLineWidth(3.0f); for (auto pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi) { if (!pi->second.showGraph) { continue; } CVertexArray* va = GetVertexArray(); va->Initialize(); const float steps_x = (end_x - start_x) / CTimeProfiler::TimeRecord::frames_size; for (size_t a=0; a < CTimeProfiler::TimeRecord::frames_size; ++a) { // profile runtime; eg 0.5f means: uses 50% of a CPU (during that frame) // This may be more then 1.0f, in case an operation // which ran over many frames, ended in this one. const float p = pi->second.frames[a].toSecsf() * GAME_SPEED; const float x = start_x + (a * steps_x); const float y = 0.02f + (p * 0.96f); va->AddVertex0(x, y, 0.0f); } glColorf3((float3)pi->second.color); va->DrawArray0(GL_LINE_STRIP); } glLineWidth(1.0f); }