Add an interface for view-independent rendering.
To actually achieve improved performance with the OpenGL 2 renderer, we have to cache geometry that doesn't change when the viewport does (note that the rendered pixels can change quite dramatically because we can reconfigure shaders; e.g. stippling can be drawn in screen coordinates). This commit adds a BatchCanvas interface that can be implemented by renderers, and uses it for drawing entities such as lines and points.single-window
parent
6d2c2aecff
commit
52557ee979
|
@ -80,6 +80,7 @@ void TextWindow::ScreenChangeFixExportColors(int link, uint32_t v) {
|
|||
|
||||
void TextWindow::ScreenChangeBackFaces(int link, uint32_t v) {
|
||||
SS.drawBackFaces = !SS.drawBackFaces;
|
||||
SS.GW.persistentDirty = true;
|
||||
InvalidateGraphics();
|
||||
}
|
||||
|
||||
|
|
32
src/draw.cpp
32
src/draw.cpp
|
@ -562,12 +562,9 @@ void GraphicsWindow::DrawSnapGrid(Canvas *canvas) {
|
|||
}
|
||||
}
|
||||
|
||||
void GraphicsWindow::DrawPersistent(Canvas *canvas) {
|
||||
// Draw the active group; this does stuff like the mesh and edges.
|
||||
SK.GetGroup(activeGroup)->Draw(canvas);
|
||||
|
||||
// Now draw the entities.
|
||||
void GraphicsWindow::DrawEntities(Canvas *canvas, bool persistent) {
|
||||
for(Entity &e : SK.entity) {
|
||||
if(persistent == (e.IsNormal() || e.IsWorkplane())) continue;
|
||||
switch(SS.GW.drawOccludedAs) {
|
||||
case DrawOccludedAs::VISIBLE:
|
||||
e.Draw(Entity::DrawAs::OVERLAY, canvas);
|
||||
|
@ -581,6 +578,14 @@ void GraphicsWindow::DrawPersistent(Canvas *canvas) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsWindow::DrawPersistent(Canvas *canvas) {
|
||||
// Draw the active group; this does stuff like the mesh and edges.
|
||||
SK.GetGroup(activeGroup)->Draw(canvas);
|
||||
|
||||
// Now draw the entities that don't change with viewport.
|
||||
DrawEntities(canvas, /*persistent=*/true);
|
||||
|
||||
// Draw filled paths in all groups, when those filled paths were requested
|
||||
// specially by assigning a style with a fill color, or when the filled
|
||||
|
@ -629,7 +634,22 @@ void GraphicsWindow::Draw(Canvas *canvas) {
|
|||
if(showSnapGrid) DrawSnapGrid(canvas);
|
||||
|
||||
// Draw all the things that don't change when we rotate.
|
||||
DrawPersistent(canvas);
|
||||
if(persistentCanvas != NULL) {
|
||||
if(persistentDirty) {
|
||||
persistentDirty = false;
|
||||
|
||||
persistentCanvas->Clear();
|
||||
DrawPersistent(&*persistentCanvas);
|
||||
persistentCanvas->Finalize();
|
||||
}
|
||||
|
||||
persistentCanvas->Draw();
|
||||
} else {
|
||||
DrawPersistent(canvas);
|
||||
}
|
||||
|
||||
// Draw the entities that do change with viewport.
|
||||
DrawEntities(canvas, /*persistent=*/false);
|
||||
|
||||
// Draw the polygon errors.
|
||||
if(SS.checkClosedContour) {
|
||||
|
|
|
@ -352,6 +352,8 @@ void SolveSpaceUI::GenerateAll(Generate type, bool andFindFree, bool genForBBox)
|
|||
|
||||
FreeAllTemporary();
|
||||
allConsistent = true;
|
||||
SS.GW.persistentDirty = true;
|
||||
|
||||
endMillis = GetMilliseconds();
|
||||
|
||||
if(endMillis - startMillis > 30) {
|
||||
|
|
|
@ -206,6 +206,10 @@ std::string SolveSpace::MakeAcceleratorLabel(int accel) {
|
|||
|
||||
void GraphicsWindow::Init() {
|
||||
canvas = CreateRenderer();
|
||||
if(canvas) {
|
||||
persistentCanvas = canvas->CreateBatch();
|
||||
persistentDirty = true;
|
||||
}
|
||||
|
||||
scale = 5;
|
||||
offset = Vector::From(0, 0, 0);
|
||||
|
|
|
@ -211,6 +211,18 @@ Canvas::hFill Canvas::GetFill(const Fill &fill) {
|
|||
return fills.AddAndAssignId(&fillCopy);
|
||||
}
|
||||
|
||||
std::shared_ptr<BatchCanvas> Canvas::CreateBatch() {
|
||||
return std::shared_ptr<BatchCanvas>();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// An interface for view-independent visualization
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const Camera &BatchCanvas::GetCamera() const {
|
||||
ssassert(false, "Geometry drawn on BatchCanvas must be independent from camera");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A wrapper around Canvas that simplifies drawing UI in screen coordinates
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -50,6 +50,8 @@ public:
|
|||
Vector lightDirection[2];
|
||||
};
|
||||
|
||||
class BatchCanvas;
|
||||
|
||||
// An interface for populating a drawing area with geometry.
|
||||
class Canvas {
|
||||
public:
|
||||
|
@ -162,9 +164,11 @@ public:
|
|||
const Vector &o, const Vector &u, const Vector &v,
|
||||
const Point2d &ta, const Point2d &tb, hFill hcf) = 0;
|
||||
virtual void InvalidatePixmap(std::shared_ptr<const Pixmap> pm) = 0;
|
||||
|
||||
virtual std::shared_ptr<BatchCanvas> CreateBatch();
|
||||
};
|
||||
|
||||
// An interface for view-dependent visualization
|
||||
// An interface for view-dependent visualization.
|
||||
class ViewportCanvas : public Canvas {
|
||||
public:
|
||||
virtual void SetCamera(const Camera &camera, bool filp = FLIP_FRAMEBUFFER) = 0;
|
||||
|
@ -177,6 +181,15 @@ public:
|
|||
virtual void GetIdent(const char **vendor, const char **renderer, const char **version) = 0;
|
||||
};
|
||||
|
||||
// An interface for view-independent visualization.
|
||||
class BatchCanvas : public Canvas {
|
||||
public:
|
||||
const Camera &GetCamera() const override;
|
||||
|
||||
virtual void Finalize() = 0;
|
||||
virtual void Draw() = 0;
|
||||
};
|
||||
|
||||
// A wrapper around Canvas that simplifies drawing UI in screen coordinates.
|
||||
class UiCanvas {
|
||||
public:
|
||||
|
|
|
@ -491,6 +491,7 @@ void TextWindow::ScreenChangeStylePatternType(int link, uint32_t v) {
|
|||
hStyle hs = { v };
|
||||
Style *s = Style::Get(hs);
|
||||
s->stippleType = (StipplePattern)(link - 1);
|
||||
SS.GW.persistentDirty = true;
|
||||
}
|
||||
|
||||
void TextWindow::ScreenChangeStyleMetric(int link, uint32_t v) {
|
||||
|
@ -639,6 +640,7 @@ void TextWindow::ScreenChangeStyleYesNo(int link, uint32_t v) {
|
|||
s->textOrigin = (Style::TextOrigin)((uint32_t)s->textOrigin | (uint32_t)Style::TextOrigin::TOP);
|
||||
break;
|
||||
}
|
||||
SS.GW.persistentDirty = true;
|
||||
InvalidateGraphics();
|
||||
}
|
||||
|
||||
|
@ -721,6 +723,7 @@ bool TextWindow::EditControlDoneForStyles(const char *str) {
|
|||
}
|
||||
default: return false;
|
||||
}
|
||||
SS.GW.persistentDirty = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@ void TextWindow::ScreenShowGroupsSpecial(int link, uint32_t v) {
|
|||
Group *g = SK.GetGroup(SK.groupOrder.elem[i]);
|
||||
g->visible = state;
|
||||
}
|
||||
SS.GW.persistentDirty = true;
|
||||
}
|
||||
void TextWindow::ScreenActivateGroup(int link, uint32_t v) {
|
||||
SS.GW.activeGroup.v = v;
|
||||
|
|
3
src/ui.h
3
src/ui.h
|
@ -501,6 +501,8 @@ public:
|
|||
static void MenuClipboard(Command id);
|
||||
|
||||
std::shared_ptr<ViewportCanvas> canvas;
|
||||
std::shared_ptr<BatchCanvas> persistentCanvas;
|
||||
bool persistentDirty;
|
||||
|
||||
// The width and height (in pixels) of the window.
|
||||
double width, height;
|
||||
|
@ -738,6 +740,7 @@ public:
|
|||
void UpdateDraggedNum(Vector *pos, double mx, double my);
|
||||
void UpdateDraggedPoint(hEntity hp, double mx, double my);
|
||||
|
||||
void DrawEntities(Canvas *canvas, bool persistent);
|
||||
void DrawPersistent(Canvas *canvas);
|
||||
void Draw(Canvas *canvas);
|
||||
|
||||
|
|
Loading…
Reference in New Issue