DrawData is passed to main draw function

This commit is contained in:
Yousef Khadadeh 2026-02-25 13:26:35 +03:00
parent 8ce9bd8aa3
commit 23dbfcfede
13 changed files with 86 additions and 111 deletions

View file

@ -56,7 +56,7 @@ void BrushStrokeCanvasComponent::draw(SkCanvas* canvas, const DrawData& drawData
unsigned mipmapLevel = compContainer ? compContainer->get_mipmap_level(drawData) : 0;
if(mipmapLevel == 0 || drawData.dontUseDrawProgCache) // check dontUseDrawProgCache, to make sure that SVG screenshots dont use LOD
if(mipmapLevel == 0 || drawData.takingScreenshot) // check takingScreenshot, to make sure that screenshots dont use LOD
canvas->drawPath(*brushPath, paint);
else
canvas->drawPath(*brushPathLOD[mipmapLevel - 1], paint);

View file

@ -12,10 +12,11 @@ struct DrawData {
DrawCamera cam;
ResourceManager* rMan;
MainProgram* main;
bool takingScreenshot = false;
bool isSVGRender = false;
bool dontUseDrawProgCache = false;
bool clampDrawBetween = true;
bool drawGrids = true;
bool transparentBackground = false;
WorldScalar clampDrawMinimum;
WorldScalar mipMapLevelOne;
WorldScalar mipMapLevelTwo;

View file

@ -586,7 +586,7 @@ void DrawingProgram::get_used_resources(std::unordered_set<NetworkingObjects::Ne
}
void DrawingProgram::draw(SkCanvas* canvas, const DrawData& drawData) {
if(drawData.dontUseDrawProgCache)
if(drawData.takingScreenshot)
layerMan.draw(canvas, drawData);
else {
canvas->saveLayer(nullptr, nullptr);
@ -597,23 +597,20 @@ void DrawingProgram::draw(SkCanvas* canvas, const DrawData& drawData) {
canvas->restore();
canvas->restore();
if(!drawData.main->takingScreenshot) {
for(auto& droppedDownFile : droppedDownloadingFiles)
static_cast<ImageCanvasComponent&>(droppedDownFile.comp->obj->get_comp()).draw_download_progress_bar(canvas, drawData, droppedDownFile.downData->progress);
for(auto& droppedDownFile : droppedDownloadingFiles)
static_cast<ImageCanvasComponent&>(droppedDownFile.comp->obj->get_comp()).draw_download_progress_bar(canvas, drawData, droppedDownFile.downData->progress);
for(auto& c : updateableComponents) {
if(c->obj->get_comp().get_type() == CanvasComponentType::IMAGE) {
auto& img = static_cast<ImageCanvasComponent&>(c->obj->get_comp());
float progress = drawData.main->world->rMan.get_resource_retrieval_progress(img.d.imageID);
img.draw_download_progress_bar(canvas, drawData, progress);
}
for(auto& c : updateableComponents) {
if(c->obj->get_comp().get_type() == CanvasComponentType::IMAGE) {
auto& img = static_cast<ImageCanvasComponent&>(c->obj->get_comp());
float progress = drawData.main->world->rMan.get_resource_retrieval_progress(img.d.imageID);
img.draw_download_progress_bar(canvas, drawData, progress);
}
}
selection.draw_gui(canvas, drawData);
drawTool->draw(canvas, drawData);
}
drawTool->draw(canvas, drawData);
}
Vector4f* DrawingProgram::get_foreground_color_ptr() {

View file

@ -64,9 +64,9 @@ void EyeDropperTool::tool_update() {
int yPos = std::clamp<int>(drawP.world.main.input.mouse.pos.y(), 0, drawP.world.main.window.size.y() - 1);
eyeDropperCanvas->save();
drawP.world.drawData.dontUseDrawProgCache = true;
drawP.world.main.draw(eyeDropperCanvas);
drawP.world.drawData.dontUseDrawProgCache = false;
DrawData d = drawP.world.drawData;
d.takingScreenshot = true;
drawP.world.main.draw(eyeDropperCanvas, drawP.world.main.world, d);
eyeDropperCanvas->restore();
//drawP.world.main.window.ctx->flush();

View file

@ -240,7 +240,6 @@ void ScreenshotTool::take_screenshot_svg(SkCanvas* canvas, bool transparentBackg
Vector2f canvasSize{controls.rectX2 - controls.rectX1, controls.rectY2 - controls.rectY1};
DrawData d = drawP.world.drawData;
WorldVec topLeft = controls.coords.from_space({secRectX1, secRectY1});
WorldVec topRight = controls.coords.from_space({secRectX2, secRectY1});
WorldVec bottomLeft = controls.coords.from_space({secRectX1, secRectY2});
@ -254,23 +253,15 @@ void ScreenshotTool::take_screenshot_svg(SkCanvas* canvas, bool transparentBackg
vectorZoom.y() = distY / WorldScalar(canvasSize.y() * 0.5);
WorldScalar newInverseScale = (vectorZoom.x() + vectorZoom.y()) * WorldScalar(0.5);
drawP.world.drawData.cam.set_based_on_properties(drawP.world, topLeft, newInverseScale, controls.coords.rotation);
drawP.world.drawData.cam.set_viewing_area(canvasSize);
drawP.world.drawData.refresh_draw_optimizing_values();
bool oldDrawGrids = drawP.world.drawData.drawGrids;
drawP.world.main.takingScreenshot = true;
drawP.world.main.transparentBackground = transparentBackground;
drawP.world.drawData.drawGrids = false;
drawP.world.drawData.dontUseDrawProgCache = true;
drawP.world.drawData.isSVGRender = true;
drawP.world.main.draw(canvas);
drawP.world.drawData.isSVGRender = false;
drawP.world.main.takingScreenshot = false;
drawP.world.main.transparentBackground = false;
drawP.world.drawData.drawGrids = oldDrawGrids;
drawP.world.drawData = d;
DrawData screenshotDrawData = drawP.world.drawData;
screenshotDrawData.cam.set_based_on_properties(drawP.world, topLeft, newInverseScale, controls.coords.rotation);
screenshotDrawData.cam.set_viewing_area(canvasSize);
screenshotDrawData.takingScreenshot = true;
screenshotDrawData.transparentBackground = transparentBackground;
screenshotDrawData.drawGrids = false;
screenshotDrawData.isSVGRender = true;
screenshotDrawData.refresh_draw_optimizing_values();
drawP.world.main.draw(canvas, drawP.world.main.world, screenshotDrawData);
}
void ScreenshotTool::take_screenshot_area_hw(const sk_sp<SkSurface>& surface, SkCanvas* canvas, void* fullImgRawData, const Vector2i& fullImageSize, const Vector2i& sectionImagePos, const Vector2i& sectionImageSize, const Vector2i& canvasSize, bool transparentBackground) {
@ -281,7 +272,6 @@ void ScreenshotTool::take_screenshot_area_hw(const sk_sp<SkSurface>& surface, Sk
float secRectY1 = controls.rectY1 + (controls.rectY2 - controls.rectY1) * (sectionImagePos.y() / (double)fullImageSize.y());
float secRectY2 = controls.rectY1 + (controls.rectY2 - controls.rectY1) * ((sectionImagePos.y() + canvasSize.y()) / (double)fullImageSize.y());
DrawData d = drawP.world.drawData;
WorldVec topLeft = controls.coords.from_space({secRectX1, secRectY1});
WorldVec topRight = controls.coords.from_space({secRectX2, secRectY1});
WorldVec bottomLeft = controls.coords.from_space({secRectX1, secRectY2});
@ -295,21 +285,14 @@ void ScreenshotTool::take_screenshot_area_hw(const sk_sp<SkSurface>& surface, Sk
vectorZoom.y() = distY / WorldScalar(canvasSize.y() * 0.5);
WorldScalar newInverseScale = (vectorZoom.x() + vectorZoom.y()) * WorldScalar(0.5);
drawP.world.drawData.cam.set_based_on_properties(drawP.world, topLeft, newInverseScale, controls.coords.rotation);
drawP.world.drawData.cam.set_viewing_area(sectionImageSize.cast<float>());
drawP.world.drawData.refresh_draw_optimizing_values();
bool oldDrawGrids = drawP.world.drawData.drawGrids;
drawP.world.main.takingScreenshot = true;
drawP.world.main.transparentBackground = transparentBackground;
drawP.world.drawData.drawGrids = controls.displayGrid;
drawP.world.drawData.dontUseDrawProgCache = true;
drawP.world.main.draw(canvas);
drawP.world.main.takingScreenshot = false;
drawP.world.main.transparentBackground = false;
drawP.world.drawData.drawGrids = oldDrawGrids;
drawP.world.drawData = d;
DrawData screenshotDrawData = drawP.world.drawData;
screenshotDrawData.cam.set_based_on_properties(drawP.world, topLeft, newInverseScale, controls.coords.rotation);
screenshotDrawData.cam.set_viewing_area(sectionImageSize.cast<float>());
screenshotDrawData.takingScreenshot = true;
screenshotDrawData.transparentBackground = transparentBackground;
screenshotDrawData.drawGrids = controls.displayGrid;
screenshotDrawData.refresh_draw_optimizing_values();
drawP.world.main.draw(canvas, drawP.world.main.world, screenshotDrawData);
SkImageInfo aaImgInfo = SkImageInfo::Make(sectionImageSize.x(), sectionImageSize.y(), kRGBA_8888_SkColorType, kPremul_SkAlphaType);
void* fullImgRawDataStartPt = (uint8_t*)fullImgRawData + 4 * (size_t)sectionImagePos.x() + 4 * (size_t)fullImageSize.x() * (size_t)sectionImagePos.y();
@ -478,42 +461,40 @@ bool ScreenshotTool::prevent_undo_or_redo() {
}
void ScreenshotTool::draw(SkCanvas* canvas, const DrawData& drawData) {
if(!drawData.main->takingScreenshot) {
if(controls.selectionMode == 0) {
SkPaint paint1;
paint1.setColor4f({0.0f, 0.0f, 0.0f, 0.3f});
canvas->drawPaint(paint1);
}
else {
canvas->save();
controls.coords.transform_sk_canvas(canvas, drawData);
float x1 = std::min(controls.rectX1, controls.rectX2);
float x2 = std::max(controls.rectX1, controls.rectX2);
float y1 = std::min(controls.rectY1, controls.rectY2);
float y2 = std::max(controls.rectY1, controls.rectY2);
SkPoint p1{x1, y1};
SkPoint p2{x2, y2};
SkPathBuilder path1B;
path1B.addRect(SkRect::MakeLTRB(p1.x(), p1.y(), p2.x(), p2.y()));
path1B.setFillType(SkPathFillType::kInverseWinding);
SkPath path1 = path1B.detach();
SkPaint paint1;
paint1.setColor4f({0.0f, 0.0f, 0.0f, 0.3f});
canvas->drawPath(path1, paint1);
if(controls.selectionMode == 0) {
SkPaint paint1;
paint1.setColor4f({0.0f, 0.0f, 0.0f, 0.3f});
canvas->drawPaint(paint1);
}
else {
canvas->save();
controls.coords.transform_sk_canvas(canvas, drawData);
float x1 = std::min(controls.rectX1, controls.rectX2);
float x2 = std::max(controls.rectX1, controls.rectX2);
float y1 = std::min(controls.rectY1, controls.rectY2);
float y2 = std::max(controls.rectY1, controls.rectY2);
SkPoint p1{x1, y1};
SkPoint p2{x2, y2};
SkPathBuilder path1B;
path1B.addRect(SkRect::MakeLTRB(p1.x(), p1.y(), p2.x(), p2.y()));
path1B.setFillType(SkPathFillType::kInverseWinding);
SkPath path1 = path1B.detach();
SkPaint paint1;
paint1.setColor4f({0.0f, 0.0f, 0.0f, 0.3f});
canvas->drawPath(path1, paint1);
path1.setFillType(SkPathFillType::kWinding);
SkPaint paint2;
paint2.setColor4f({1.0f, 1.0f, 1.0f, 0.9f});
paint2.setStyle(SkPaint::kStroke_Style);
canvas->drawPath(path1, paint2);
path1.setFillType(SkPathFillType::kWinding);
SkPaint paint2;
paint2.setColor4f({1.0f, 1.0f, 1.0f, 0.9f});
paint2.setStyle(SkPaint::kStroke_Style);
canvas->drawPath(path1, paint2);
canvas->restore();
canvas->restore();
if(controls.selectionMode == 2) {
paint2.setStyle(SkPaint::kFill_Style);
for(auto& circ : controls.circles)
drawP.draw_drag_circle(canvas, circ.pos, {0.1f, 0.9f, 0.9f, 1.0f}, drawData, 1.0f);
}
if(controls.selectionMode == 2) {
paint2.setStyle(SkPaint::kFill_Style);
for(auto& circ : controls.circles)
drawP.draw_drag_circle(canvas, circ.pos, {0.1f, 0.9f, 0.9f, 1.0f}, drawData, 1.0f);
}
}
}

View file

@ -285,10 +285,11 @@ float MainProgram::get_scale_and_density_factor_gui() {
return window.scale * window.density;
}
void MainProgram::draw(SkCanvas* canvas) {
canvas->clear(transparentBackground ? SkColor4f{0.0f, 0.0f, 0.0f, 0.0f} : world->canvasTheme.get_back_color());
world->draw(canvas);
toolbar.draw(canvas);
void MainProgram::draw(SkCanvas* canvas, std::shared_ptr<World> worldToDraw, const DrawData& drawData) {
canvas->clear(drawData.transparentBackground ? SkColor4f{0.0f, 0.0f, 0.0f, 0.0f} : worldToDraw->canvasTheme.get_back_color());
worldToDraw->draw(canvas, drawData);
if(!drawData.takingScreenshot)
toolbar.draw(canvas);
}
sk_sp<SkSurface> MainProgram::create_native_surface(Vector2i resolution, bool isMSAA) {

View file

@ -85,7 +85,7 @@ class MainProgram {
MainProgram();
void update();
void draw(SkCanvas* canvas);
void draw(SkCanvas* canvas, std::shared_ptr<World> worldToDraw, const DrawData& drawData);
sk_sp<SkSurface> create_native_surface(Vector2i resolution, bool isMSAA);
bool setToQuit = false;
@ -112,8 +112,6 @@ class MainProgram {
std::filesystem::path documentsPath;
bool drawGui = true;
bool takingScreenshot = false;
bool transparentBackground = false;
Vector3f defaultCanvasBackgroundColor = DEFAULT_CANVAS_BACKGROUND_COLOR;

View file

@ -204,7 +204,7 @@ void ImageResourceDisplay::draw(SkCanvas* canvas, const DrawData& drawData, cons
unsigned mipmapLevel = get_exact_mipmap_level_for_dimensions({imRectPixelSize.width(), imRectPixelSize.height()});
auto& frame = frames[frameIndex];
unsigned closestMipmapLevel = get_best_allocated_mipmap_level(mipmapLevel);
if(drawData.main->takingScreenshot) {
if(drawData.takingScreenshot) {
if(closestMipmapLevel == mipmapLevel) {
if(closestMipmapLevel == get_smallest_mipmap_level())
canvas->drawImageRect(frame.smallestMipmapLevel, imRect, {SkFilterMode::kLinear, SkMipmapMode::kLinear});

View file

@ -2298,10 +2298,8 @@ void Toolbar::end_gui() {
}
void Toolbar::draw(SkCanvas* canvas) {
if(!main.takingScreenshot) {
canvas->save();
canvas->scale(final_gui_scale(), final_gui_scale());
gui.draw(canvas);
canvas->restore();
}
canvas->save();
canvas->scale(final_gui_scale(), final_gui_scale());
gui.draw(canvas);
canvas->restore();
}

View file

@ -544,17 +544,16 @@ void World::list_debug_test_update() {
}
#endif
void World::draw(SkCanvas* canvas) {
drawData.refresh_draw_optimizing_values();
void World::draw(SkCanvas* canvas, const DrawData& calledDrawData) {
if(!clientStillConnecting) {
if(drawData.drawGrids)
gridMan.draw_back(canvas, drawData);
drawProg.draw(canvas, drawData);
if(drawData.drawGrids) {
gridMan.draw_front(canvas, drawData);
gridMan.draw_coordinates(canvas, drawData);
if(calledDrawData.drawGrids)
gridMan.draw_back(canvas, calledDrawData);
drawProg.draw(canvas, calledDrawData);
if(calledDrawData.drawGrids) {
gridMan.draw_front(canvas, calledDrawData);
gridMan.draw_coordinates(canvas, calledDrawData);
}
if(!main.takingScreenshot)
draw_other_player_cursors(canvas, drawData);
if(!drawData.takingScreenshot)
draw_other_player_cursors(canvas, calledDrawData);
}
}

View file

@ -68,7 +68,7 @@ class World {
void unfocus_update();
void on_switch_out();
void draw(SkCanvas* canvas);
void draw(SkCanvas* canvas, const DrawData& calledDrawData);
void early_destroy();
bool clientStillConnecting = false;

View file

@ -336,7 +336,7 @@ void WorldGrid::draw(GridManager& gMan, SkCanvas* canvas, const DrawData& drawDa
canvas->rotate(-drawData.cam.c.rotation * 180.0 / std::numbers::pi);
canvas->drawPaint(linePaint);
canvas->restore();
if(showCoordinates && drawData.cam.c.rotation == 0.0 && !drawData.main->takingScreenshot) {
if(showCoordinates && drawData.cam.c.rotation == 0.0 && !drawData.takingScreenshot) {
coordinatesWillBeDrawn = true;
WorldVec worldWindowEndPos = drawData.cam.c.pos + drawData.cam.c.dir_from_space(drawData.cam.viewingArea);
coordinatesAxisOnBounds = bounds.has_value() && !bounds.value().fully_contains_aabb(SCollision::AABB<WorldScalar>(drawData.cam.c.pos, worldWindowEndPos));

View file

@ -589,7 +589,7 @@ SDL_AppResult SDL_AppIterate(void *appstate) {
mS.m->input.text.lastAcceptingTextInputVal = mS.m->input.text.get_accepting_input();
mS.intermediateCanvas->save();
mS.m->draw(mS.intermediateCanvas);
mS.m->draw(mS.intermediateCanvas, mS.m->world, mS.m->world->drawData);
mS.intermediateCanvas->restore();
#ifdef USE_BACKEND_VULKAN