static void drawDebugBoundingBox(const EERIE_2D_BBOX & box, Color color = Color::white) { if(box.valid()) { drawLine2D(box.min.x, box.min.y, box.max.x, box.min.y, 0.01f, color); drawLine2D(box.max.x, box.min.y, box.max.x, box.max.y, 0.01f, color); drawLine2D(box.max.x, box.max.y, box.min.x, box.max.y, 0.01f, color); drawLine2D(box.min.x, box.max.y, box.min.x, box.min.y, 0.01f, color); } }
void ShowFpsGraph() { ARX_PROFILE_FUNC(); GRenderer->ResetTexture(0); static std::deque<float> lastFPSArray; lastFPSArray.push_front(1000 / arxtime.get_frame_delay()); Vec2i windowSize = mainApp->getWindow()->getSize(); if(lastFPSArray.size() == size_t(windowSize.x)) { lastFPSArray.pop_back(); } float avg = 0; float worst = lastFPSArray[0]; std::vector<TexturedVertex> vertices; vertices.resize(lastFPSArray.size()); const float SCALE_Y = 2.0f; for(size_t i = 0; i < lastFPSArray.size(); ++i) { float time = lastFPSArray[i]; avg += lastFPSArray[i]; worst = std::min(worst, lastFPSArray[i]); vertices[i].color = Color(255, 255, 255, 255).toRGBA(); vertices[i].p.x = i; vertices[i].p.y = windowSize.y - (time * SCALE_Y); vertices[i].p.z = 1.0f; vertices[i].rhw = 1.0f; } avg /= lastFPSArray.size(); EERIEDRAWPRIM(Renderer::LineStrip, &vertices[0], vertices.size()); Color avgColor = Color::blue * 0.5f + Color::white * 0.5f; float avgPos = windowSize.y - (avg * SCALE_Y); drawLine2D(0, avgPos, windowSize.x, avgPos, 1.0f, Color::blue); Color worstColor = Color::red * 0.5f + Color::white * 0.5f; float worstPos = windowSize.y - (worst * SCALE_Y); drawLine2D(0, worstPos, windowSize.x, worstPos, 1.0f, Color::red); Font * font = hFontDebug; float lineOffset = font->getLineHeight() + 2; std::string labels[3] = { "Average: ", "Worst: ", "Current: " }; Color colors[3] = { avgColor, worstColor, Color::white }; float values[3] = { avg, worst, lastFPSArray[0] }; std::string texts[3]; float widths[3]; static float labelWidth = 0.f; static float valueWidth = 0.f; for(size_t i = 0; i < 3; i++) { // Format value std::ostringstream oss; oss << std::fixed << std::setprecision(2) << values[i] << " FPS"; texts[i] = oss.str(); // Calculate widths (could be done more efficiently for monospace fonts...) labelWidth = std::max(labelWidth, float(font->getTextSize(labels[i]).x)); widths[i] = font->getTextSize(texts[i]).x; valueWidth = std::max(valueWidth, widths[i]); } float x = 10; float y = 10; float xend = x + labelWidth + 10 + valueWidth; for(size_t i = 0; i < 3; i++) { font->draw(Vec2i(x, y), labels[i], Color::gray(0.8f)); font->draw(Vec2i(xend - widths[i], y), texts[i], colors[i]); y += lineOffset; } }
static void drawDebugMaterials() { if(!ACTIVEBKG || !ACTIVEBKG->exist) { return; } PolyType skip = POLY_NODRAW | POLY_HIDE; if(GInput->isKeyPressed(Keyboard::Key_LeftShift)) { skip |= POLY_TRANS | POLY_WATER; } Vec2f point(DANAEMouse); Entity * owner = GetFirstInterAtPos(Vec2s(point)); TextureContainer * material = NULL; size_t count = 0; Vec2f pp[4]; Vec2f puv[4]; PolyType flags; float minz = std::numeric_limits<float>::max(); for(size_t k = 1; k < entities.size(); k++) { EntityHandle h = EntityHandle(k); if(!entities[h] || !entities[h]->obj) { continue; } Entity * entity = entities[h]; if((entity->ioflags & IO_CAMERA) || (entity->ioflags & IO_MARKER)) continue; if(!(entity->gameFlags & GFLAG_ISINTREATZONE)) continue; if((entity->gameFlags & GFLAG_INVISIBILITY)) continue; if((entity->gameFlags & GFLAG_MEGAHIDE)) continue; switch(entity->show) { case SHOW_FLAG_DESTROYED: continue; case SHOW_FLAG_IN_INVENTORY: continue; case SHOW_FLAG_ON_PLAYER: continue; case SHOW_FLAG_LINKED: break; case SHOW_FLAG_NOT_DRAWN: continue; case SHOW_FLAG_HIDDEN: continue; case SHOW_FLAG_MEGAHIDE: continue; case SHOW_FLAG_KILLED: continue; case SHOW_FLAG_IN_SCENE: break; case SHOW_FLAG_TELEPORTING: break; } if(!entity->bbox2D.valid()) { continue; } for(size_t j = 0; j < entity->obj->facelist.size(); j++) { const EERIE_FACE & face = entity->obj->facelist[j]; if(face.facetype & skip) { continue; } bool valid = true; bool bvalid = false; Vec3f p[3]; Vec2f uv[3]; for(size_t i = 0; i < 3; i++) { unsigned short v = face.vid[i]; valid = valid && v < entity->obj->vertexlist3.size(); if(valid) { if(entity->animlayer[0].cur_anim) { p[i] = entity->obj->vertexlist3[v].vert.p; uv[i] = entity->obj->vertexlist3[v].vert.uv; } else { p[i] = entity->obj->vertexlist[v].vert.p; uv[i] = entity->obj->vertexlist[v].vert.uv; } valid = valid && (p[i].z > 0.000001f); bvalid = bvalid || (p[i].x >= g_size.left && p[i].x < g_size.right && p[i].y >= g_size.top && p[i].y < g_size.bottom); } } if(!valid || !bvalid) { continue; } float z = pointInTriangle(point, p[0], p[1], p[2]); if(z > 0 && z <= minz) { count = 3; for(size_t i = 0; i < count; i++) { pp[i] = Vec2f(p[i].x, p[i].y); puv[i] = uv[i]; } if(face.texid >= 0 && size_t(face.texid) < entity->obj->texturecontainer.size()) { material = entity->obj->texturecontainer[face.texid]; } else { material = NULL; } owner = entity; minz = z; flags = face.facetype & ~(POLY_WATER | POLY_LAVA); } } } for(short z = 0; z < ACTIVEBKG->Zsize; z++) for(short x = 0; x < ACTIVEBKG->Xsize; x++) { const EERIE_BKG_INFO & feg = ACTIVEBKG->fastdata[x][z]; if(!feg.treat) { continue; } for(long l = 0; l < feg.nbpolyin; l++) { EERIEPOLY * ep = feg.polyin[l]; if(!ep) { continue; } if(ep->type & skip) { continue; } bool valid = true; bool bvalid = false; Vec3f p[4]; for(size_t i = 0; i < ((ep->type & POLY_QUAD) ? 4u : 3u); i++) { TexturedVertex tv; tv.p = EE_RT(ep->v[i].p); valid = valid && (tv.p.z > 0.000001f); EE_P(tv.p, tv); bvalid = bvalid || (tv.p.x >= g_size.left && tv.p.x < g_size.right && tv.p.y >= g_size.top && tv.p.y < g_size.bottom); p[i] = tv.p; } if(!valid || !bvalid) { continue; } float z = pointInTriangle(point, p[0], p[1], p[2]); if(z <= 0 && (ep->type & POLY_QUAD)) { z = pointInTriangle(point, p[1], p[3], p[2]); } if(z > 0 && z <= minz) { count = ((ep->type & POLY_QUAD) ? 4 : 3); for(size_t i = 0; i < count; i++) { pp[i] = Vec2f(p[i].x, p[i].y); puv[i] = ep->v[i].uv; } material = ep->tex; owner = NULL; minz = z; flags = ep->type; } } } if(count) { GRenderer->SetRenderState(Renderer::DepthTest, false); drawLine2D(pp[0], pp[1], 0.1f, Color::magenta); drawLine2D(pp[2], pp[0], 0.1f, Color::magenta); if(count == 4) { drawLine2D(pp[2], pp[3], 0.1f, Color::magenta); drawLine2D(pp[3], pp[1], 0.1f, Color::magenta); } else { drawLine2D(pp[1], pp[2], 0.1f, Color::magenta); } Vec2f c = Vec2f(0.f); float miny = std::numeric_limits<float>::max(); float maxy = std::numeric_limits<float>::min(); for(size_t i = 0; i < count; i++) { c += pp[i]; miny = std::min(miny, pp[i].y); maxy = std::max(maxy, pp[i].y); } c *= 1.f / count; Vec2f textpos(c.x, miny - 2 * hFontDebug->getLineHeight()); std::ostringstream oss; if(owner) { textpos.y -= hFontDebug->getLineHeight(); } if(material && material->m_pTexture) { textpos.y -= hFontDebug->getLineHeight(); } if((flags & (POLY_WATER | POLY_LAVA)) && enviro && enviro->m_pTexture) { textpos.y -= hFontDebug->getLineHeight(); } if(textpos.y < g_size.top + 5) { textpos.y = maxy + 2 * hFontDebug->getLineHeight(); } if(owner) { drawTextCentered(hFontDebug, textpos, owner->idString(), Color::cyan); textpos.y += hFontDebug->getLineHeight(); } if(material && material->m_pTexture) { drawDebugMaterialTexture(textpos, "Diffuse: ", *material->m_pTexture, Color::green); } if((flags & (POLY_WATER | POLY_LAVA)) && enviro && enviro->m_pTexture) { oss.str(std::string()); oss << "Animation: "; oss << ((flags & (POLY_LAVA)) ? "lava" : "water"); if(flags & POLY_FALL) { oss << " (flowing)"; } drawDebugMaterialTexture(textpos, oss.str(), *enviro->m_pTexture, Color::yellow); } (void)textpos; for(size_t i = 0; i < count; i++) { oss.str(std::string()); oss.setf(std::ios_base::fixed, std::ios_base::floatfield); oss.precision(2); oss << '(' << puv[i].x << ',' << puv[i].y << ')'; std::string text = oss.str(); Vec2f textpos = pp[i]; if(pp[i].y < c.y) { textpos.y -= hFontDebug->getLineHeight(); } if(pp[i].x < c.x) { Vec2i size = hFontDebug->getTextSize(text); textpos.x -= size.x; } hFontDebug->draw(textpos.x, textpos.y, text, Color::gray(0.7f)); } GRenderer->SetRenderState(Renderer::DepthTest, true); } }