Abstract all (ex-OpenGL) drawing operations into a Canvas interface.
This has several desirable consequences:
* It is now possible to port SolveSpace to a later version of
OpenGL, such as OpenGLES 2, so that it runs on platforms that
only have that OpenGL version;
* The majority of geometry is now rendered without references to
the camera in C++ code, so a renderer can now submit it to
the video card once and re-rasterize with a different projection
matrix every time the projection is changed, avoiding expensive
reuploads;
* The DOGD (draw or get distance) interface is now
a straightforward Canvas implementation;
* There are no more direct references to SS.GW.(projection)
in sketch rendering code, which allows rendering to multiple
viewports;
* There are no more unnecessary framebuffer flips on CPU on Cocoa
and GTK;
* The platform-dependent GL code is now confined to rendergl1.cpp.
* The Microsoft and Apple headers required by it that are prone to
identifier conflicts are no longer included globally;
* The rendergl1.cpp implementation can now be omitted from
compilation to run SolveSpace headless or with a different
OpenGL version.
Note these implementation details of Canvas:
* GetCamera currently always returns a reference to the field
`Camera camera;`. This is so that a future renderer that caches
geometry in the video memory can define it as asserting, which
would provide assurance against code that could accidentally
put something projection-dependent in the cache;
* Line and triangle rendering is specified through a level of
indirection, hStroke and hFill. This is so that a future renderer
that batches geometry could cheaply group identical styles.
* DrawPixmap and DrawVectorText accept a (o,u,v) and not a matrix.
This is so that a future renderer into an output format that
uses 2d transforms (e.g. SVG) could easily derive those.
Some additional internal changes were required to enable this:
* Pixmap is now always passed as std::shared_ptr<{const ,}Pixmap>.
This is so that the renderer could cache uploaded textures
between API calls, which requires it to capture a (weak)
reference.
* The PlatformPathEqual function was properly extracted into
platform-specific code. This is so that the <windows.h> header
could be included only where needed (in platform/w32* as well
as rendergl1.cpp).
* The SBsp{2,3}::DebugDraw functions were removed. They can be
rewritten using the Canvas API if they are ever needed.
While no visual changes were originally intended, some minor fixes
happened anyway:
* The "emphasis" yellow line from top-left corner is now correctly
rendered much wider.
* The marquee rectangle is now pixel grid aligned.
* The hidden entities now do not clobber the depth buffer, removing
some minor artifacts.
* The workplane "tab" now scales with the font used to render
the workplane name.
* The workplane name font is now taken from the normals style.
* Workplane and constraint line stipple is insignificantly
different. This is so that it can reuse the existing stipple
codepaths; rendering of workplanes and constraints predates
those.
Some debug functionality was added:
* In graphics window, an fps counter that becomes red when
rendering under 60fps is drawn.
2016-05-31 00:55:13 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Backend-agnostic rendering interface, and various backends we use.
|
|
|
|
//
|
|
|
|
// Copyright 2016 whitequark
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#ifndef SOLVESPACE_RENDER_H
|
|
|
|
#define SOLVESPACE_RENDER_H
|
|
|
|
|
2016-07-21 20:27:53 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Interfaces and utilities common for all renderers.
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
Abstract all (ex-OpenGL) drawing operations into a Canvas interface.
This has several desirable consequences:
* It is now possible to port SolveSpace to a later version of
OpenGL, such as OpenGLES 2, so that it runs on platforms that
only have that OpenGL version;
* The majority of geometry is now rendered without references to
the camera in C++ code, so a renderer can now submit it to
the video card once and re-rasterize with a different projection
matrix every time the projection is changed, avoiding expensive
reuploads;
* The DOGD (draw or get distance) interface is now
a straightforward Canvas implementation;
* There are no more direct references to SS.GW.(projection)
in sketch rendering code, which allows rendering to multiple
viewports;
* There are no more unnecessary framebuffer flips on CPU on Cocoa
and GTK;
* The platform-dependent GL code is now confined to rendergl1.cpp.
* The Microsoft and Apple headers required by it that are prone to
identifier conflicts are no longer included globally;
* The rendergl1.cpp implementation can now be omitted from
compilation to run SolveSpace headless or with a different
OpenGL version.
Note these implementation details of Canvas:
* GetCamera currently always returns a reference to the field
`Camera camera;`. This is so that a future renderer that caches
geometry in the video memory can define it as asserting, which
would provide assurance against code that could accidentally
put something projection-dependent in the cache;
* Line and triangle rendering is specified through a level of
indirection, hStroke and hFill. This is so that a future renderer
that batches geometry could cheaply group identical styles.
* DrawPixmap and DrawVectorText accept a (o,u,v) and not a matrix.
This is so that a future renderer into an output format that
uses 2d transforms (e.g. SVG) could easily derive those.
Some additional internal changes were required to enable this:
* Pixmap is now always passed as std::shared_ptr<{const ,}Pixmap>.
This is so that the renderer could cache uploaded textures
between API calls, which requires it to capture a (weak)
reference.
* The PlatformPathEqual function was properly extracted into
platform-specific code. This is so that the <windows.h> header
could be included only where needed (in platform/w32* as well
as rendergl1.cpp).
* The SBsp{2,3}::DebugDraw functions were removed. They can be
rewritten using the Canvas API if they are ever needed.
While no visual changes were originally intended, some minor fixes
happened anyway:
* The "emphasis" yellow line from top-left corner is now correctly
rendered much wider.
* The marquee rectangle is now pixel grid aligned.
* The hidden entities now do not clobber the depth buffer, removing
some minor artifacts.
* The workplane "tab" now scales with the font used to render
the workplane name.
* The workplane name font is now taken from the normals style.
* Workplane and constraint line stipple is insignificantly
different. This is so that it can reuse the existing stipple
codepaths; rendering of workplanes and constraints predates
those.
Some debug functionality was added:
* In graphics window, an fps counter that becomes red when
rendering under 60fps is drawn.
2016-05-31 00:55:13 +00:00
|
|
|
enum class StipplePattern : uint32_t;
|
|
|
|
|
|
|
|
// A mapping from 3d sketch coordinates to 2d screen coordinates, using
|
|
|
|
// an axonometric projection.
|
|
|
|
class Camera {
|
|
|
|
public:
|
|
|
|
size_t width, height;
|
|
|
|
Vector offset;
|
|
|
|
Vector projRight;
|
|
|
|
Vector projUp;
|
|
|
|
double scale;
|
|
|
|
double tangent;
|
|
|
|
bool hasPixels;
|
|
|
|
|
|
|
|
bool IsPerspective() const { return tangent != 0.0; }
|
|
|
|
|
|
|
|
Point2d ProjectPoint(Vector p) const;
|
|
|
|
Vector ProjectPoint3(Vector p) const;
|
|
|
|
Vector ProjectPoint4(Vector p, double *w) const;
|
|
|
|
Vector UnProjectPoint(Point2d p) const;
|
|
|
|
Vector UnProjectPoint3(Vector p) const;
|
|
|
|
Vector VectorFromProjs(Vector rightUpForward) const;
|
|
|
|
Vector AlignToPixelGrid(Vector v) const;
|
|
|
|
|
2016-07-21 20:27:53 +00:00
|
|
|
SBezier ProjectBezier(SBezier b) const;
|
|
|
|
|
Abstract all (ex-OpenGL) drawing operations into a Canvas interface.
This has several desirable consequences:
* It is now possible to port SolveSpace to a later version of
OpenGL, such as OpenGLES 2, so that it runs on platforms that
only have that OpenGL version;
* The majority of geometry is now rendered without references to
the camera in C++ code, so a renderer can now submit it to
the video card once and re-rasterize with a different projection
matrix every time the projection is changed, avoiding expensive
reuploads;
* The DOGD (draw or get distance) interface is now
a straightforward Canvas implementation;
* There are no more direct references to SS.GW.(projection)
in sketch rendering code, which allows rendering to multiple
viewports;
* There are no more unnecessary framebuffer flips on CPU on Cocoa
and GTK;
* The platform-dependent GL code is now confined to rendergl1.cpp.
* The Microsoft and Apple headers required by it that are prone to
identifier conflicts are no longer included globally;
* The rendergl1.cpp implementation can now be omitted from
compilation to run SolveSpace headless or with a different
OpenGL version.
Note these implementation details of Canvas:
* GetCamera currently always returns a reference to the field
`Camera camera;`. This is so that a future renderer that caches
geometry in the video memory can define it as asserting, which
would provide assurance against code that could accidentally
put something projection-dependent in the cache;
* Line and triangle rendering is specified through a level of
indirection, hStroke and hFill. This is so that a future renderer
that batches geometry could cheaply group identical styles.
* DrawPixmap and DrawVectorText accept a (o,u,v) and not a matrix.
This is so that a future renderer into an output format that
uses 2d transforms (e.g. SVG) could easily derive those.
Some additional internal changes were required to enable this:
* Pixmap is now always passed as std::shared_ptr<{const ,}Pixmap>.
This is so that the renderer could cache uploaded textures
between API calls, which requires it to capture a (weak)
reference.
* The PlatformPathEqual function was properly extracted into
platform-specific code. This is so that the <windows.h> header
could be included only where needed (in platform/w32* as well
as rendergl1.cpp).
* The SBsp{2,3}::DebugDraw functions were removed. They can be
rewritten using the Canvas API if they are ever needed.
While no visual changes were originally intended, some minor fixes
happened anyway:
* The "emphasis" yellow line from top-left corner is now correctly
rendered much wider.
* The marquee rectangle is now pixel grid aligned.
* The hidden entities now do not clobber the depth buffer, removing
some minor artifacts.
* The workplane "tab" now scales with the font used to render
the workplane name.
* The workplane name font is now taken from the normals style.
* Workplane and constraint line stipple is insignificantly
different. This is so that it can reuse the existing stipple
codepaths; rendering of workplanes and constraints predates
those.
Some debug functionality was added:
* In graphics window, an fps counter that becomes red when
rendering under 60fps is drawn.
2016-05-31 00:55:13 +00:00
|
|
|
void LoadIdentity();
|
|
|
|
void NormalizeProjectionVectors();
|
|
|
|
};
|
|
|
|
|
|
|
|
// A description of scene lighting.
|
|
|
|
class Lighting {
|
|
|
|
public:
|
|
|
|
RgbaColor backgroundColor;
|
|
|
|
double ambientIntensity;
|
|
|
|
double lightIntensity[2];
|
|
|
|
Vector lightDirection[2];
|
|
|
|
};
|
|
|
|
|
|
|
|
// An interface for populating a drawing area with geometry.
|
|
|
|
class Canvas {
|
|
|
|
public:
|
|
|
|
// Stroke and fill styles are addressed with handles to be able to quickly
|
|
|
|
// group geometry into indexed draw calls.
|
|
|
|
class hStroke {
|
|
|
|
public:
|
|
|
|
uint32_t v;
|
|
|
|
};
|
|
|
|
|
|
|
|
class hFill {
|
|
|
|
public:
|
|
|
|
uint32_t v;
|
|
|
|
};
|
|
|
|
|
|
|
|
// The layer of a geometry describes how it occludes other geometry.
|
|
|
|
// Within a layer, geometry with higher z-index occludes geometry with lower z-index,
|
|
|
|
// or geometry drawn earlier if z-indexes match.
|
|
|
|
enum class Layer {
|
|
|
|
NORMAL, // Occluded by geometry with lower Z coordinate
|
|
|
|
OCCLUDED, // Only drawn over geometry with lower Z coordinate
|
|
|
|
DEPTH_ONLY, // Like NORMAL, but only affects future occlusion, not color
|
|
|
|
BACK, // Always drawn below all other geometry
|
|
|
|
FRONT, // Always drawn above all other geometry
|
|
|
|
};
|
|
|
|
|
2016-06-26 06:39:27 +00:00
|
|
|
// The outlines are the collection of all edges that may be drawn.
|
|
|
|
// Outlines can be classified as emphasized or not; emphasized outlines indicate an abrupt
|
|
|
|
// change in the surface curvature. These are indicated by the SOutline tag.
|
|
|
|
// Outlines can also be classified as contour or not; contour outlines indicate the boundary
|
|
|
|
// of the filled mesh. Whether an outline is a part of contour or not depends on point of view.
|
|
|
|
enum class DrawOutlinesAs {
|
|
|
|
EMPHASIZED_AND_CONTOUR, // Both emphasized and contour outlines
|
|
|
|
EMPHASIZED_WITHOUT_CONTOUR, // Emphasized outlines except those also belonging to contour
|
|
|
|
CONTOUR_ONLY // Contour outlines only
|
|
|
|
};
|
|
|
|
|
Abstract all (ex-OpenGL) drawing operations into a Canvas interface.
This has several desirable consequences:
* It is now possible to port SolveSpace to a later version of
OpenGL, such as OpenGLES 2, so that it runs on platforms that
only have that OpenGL version;
* The majority of geometry is now rendered without references to
the camera in C++ code, so a renderer can now submit it to
the video card once and re-rasterize with a different projection
matrix every time the projection is changed, avoiding expensive
reuploads;
* The DOGD (draw or get distance) interface is now
a straightforward Canvas implementation;
* There are no more direct references to SS.GW.(projection)
in sketch rendering code, which allows rendering to multiple
viewports;
* There are no more unnecessary framebuffer flips on CPU on Cocoa
and GTK;
* The platform-dependent GL code is now confined to rendergl1.cpp.
* The Microsoft and Apple headers required by it that are prone to
identifier conflicts are no longer included globally;
* The rendergl1.cpp implementation can now be omitted from
compilation to run SolveSpace headless or with a different
OpenGL version.
Note these implementation details of Canvas:
* GetCamera currently always returns a reference to the field
`Camera camera;`. This is so that a future renderer that caches
geometry in the video memory can define it as asserting, which
would provide assurance against code that could accidentally
put something projection-dependent in the cache;
* Line and triangle rendering is specified through a level of
indirection, hStroke and hFill. This is so that a future renderer
that batches geometry could cheaply group identical styles.
* DrawPixmap and DrawVectorText accept a (o,u,v) and not a matrix.
This is so that a future renderer into an output format that
uses 2d transforms (e.g. SVG) could easily derive those.
Some additional internal changes were required to enable this:
* Pixmap is now always passed as std::shared_ptr<{const ,}Pixmap>.
This is so that the renderer could cache uploaded textures
between API calls, which requires it to capture a (weak)
reference.
* The PlatformPathEqual function was properly extracted into
platform-specific code. This is so that the <windows.h> header
could be included only where needed (in platform/w32* as well
as rendergl1.cpp).
* The SBsp{2,3}::DebugDraw functions were removed. They can be
rewritten using the Canvas API if they are ever needed.
While no visual changes were originally intended, some minor fixes
happened anyway:
* The "emphasis" yellow line from top-left corner is now correctly
rendered much wider.
* The marquee rectangle is now pixel grid aligned.
* The hidden entities now do not clobber the depth buffer, removing
some minor artifacts.
* The workplane "tab" now scales with the font used to render
the workplane name.
* The workplane name font is now taken from the normals style.
* Workplane and constraint line stipple is insignificantly
different. This is so that it can reuse the existing stipple
codepaths; rendering of workplanes and constraints predates
those.
Some debug functionality was added:
* In graphics window, an fps counter that becomes red when
rendering under 60fps is drawn.
2016-05-31 00:55:13 +00:00
|
|
|
class Stroke {
|
|
|
|
public:
|
|
|
|
hStroke h;
|
|
|
|
|
|
|
|
Layer layer;
|
|
|
|
int zIndex;
|
|
|
|
RgbaColor color;
|
|
|
|
double width;
|
|
|
|
StipplePattern stipplePattern;
|
|
|
|
double stippleScale;
|
|
|
|
|
2016-08-01 03:52:12 +00:00
|
|
|
void Clear() { *this = {}; }
|
Abstract all (ex-OpenGL) drawing operations into a Canvas interface.
This has several desirable consequences:
* It is now possible to port SolveSpace to a later version of
OpenGL, such as OpenGLES 2, so that it runs on platforms that
only have that OpenGL version;
* The majority of geometry is now rendered without references to
the camera in C++ code, so a renderer can now submit it to
the video card once and re-rasterize with a different projection
matrix every time the projection is changed, avoiding expensive
reuploads;
* The DOGD (draw or get distance) interface is now
a straightforward Canvas implementation;
* There are no more direct references to SS.GW.(projection)
in sketch rendering code, which allows rendering to multiple
viewports;
* There are no more unnecessary framebuffer flips on CPU on Cocoa
and GTK;
* The platform-dependent GL code is now confined to rendergl1.cpp.
* The Microsoft and Apple headers required by it that are prone to
identifier conflicts are no longer included globally;
* The rendergl1.cpp implementation can now be omitted from
compilation to run SolveSpace headless or with a different
OpenGL version.
Note these implementation details of Canvas:
* GetCamera currently always returns a reference to the field
`Camera camera;`. This is so that a future renderer that caches
geometry in the video memory can define it as asserting, which
would provide assurance against code that could accidentally
put something projection-dependent in the cache;
* Line and triangle rendering is specified through a level of
indirection, hStroke and hFill. This is so that a future renderer
that batches geometry could cheaply group identical styles.
* DrawPixmap and DrawVectorText accept a (o,u,v) and not a matrix.
This is so that a future renderer into an output format that
uses 2d transforms (e.g. SVG) could easily derive those.
Some additional internal changes were required to enable this:
* Pixmap is now always passed as std::shared_ptr<{const ,}Pixmap>.
This is so that the renderer could cache uploaded textures
between API calls, which requires it to capture a (weak)
reference.
* The PlatformPathEqual function was properly extracted into
platform-specific code. This is so that the <windows.h> header
could be included only where needed (in platform/w32* as well
as rendergl1.cpp).
* The SBsp{2,3}::DebugDraw functions were removed. They can be
rewritten using the Canvas API if they are ever needed.
While no visual changes were originally intended, some minor fixes
happened anyway:
* The "emphasis" yellow line from top-left corner is now correctly
rendered much wider.
* The marquee rectangle is now pixel grid aligned.
* The hidden entities now do not clobber the depth buffer, removing
some minor artifacts.
* The workplane "tab" now scales with the font used to render
the workplane name.
* The workplane name font is now taken from the normals style.
* Workplane and constraint line stipple is insignificantly
different. This is so that it can reuse the existing stipple
codepaths; rendering of workplanes and constraints predates
those.
Some debug functionality was added:
* In graphics window, an fps counter that becomes red when
rendering under 60fps is drawn.
2016-05-31 00:55:13 +00:00
|
|
|
bool Equals(const Stroke &other) const;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class FillPattern {
|
|
|
|
SOLID, CHECKERED_A, CHECKERED_B
|
|
|
|
};
|
|
|
|
|
|
|
|
class Fill {
|
|
|
|
public:
|
|
|
|
hFill h;
|
|
|
|
|
|
|
|
Layer layer;
|
|
|
|
int zIndex;
|
|
|
|
RgbaColor color;
|
|
|
|
FillPattern pattern;
|
|
|
|
|
2016-08-01 03:52:12 +00:00
|
|
|
void Clear() { *this = {}; }
|
Abstract all (ex-OpenGL) drawing operations into a Canvas interface.
This has several desirable consequences:
* It is now possible to port SolveSpace to a later version of
OpenGL, such as OpenGLES 2, so that it runs on platforms that
only have that OpenGL version;
* The majority of geometry is now rendered without references to
the camera in C++ code, so a renderer can now submit it to
the video card once and re-rasterize with a different projection
matrix every time the projection is changed, avoiding expensive
reuploads;
* The DOGD (draw or get distance) interface is now
a straightforward Canvas implementation;
* There are no more direct references to SS.GW.(projection)
in sketch rendering code, which allows rendering to multiple
viewports;
* There are no more unnecessary framebuffer flips on CPU on Cocoa
and GTK;
* The platform-dependent GL code is now confined to rendergl1.cpp.
* The Microsoft and Apple headers required by it that are prone to
identifier conflicts are no longer included globally;
* The rendergl1.cpp implementation can now be omitted from
compilation to run SolveSpace headless or with a different
OpenGL version.
Note these implementation details of Canvas:
* GetCamera currently always returns a reference to the field
`Camera camera;`. This is so that a future renderer that caches
geometry in the video memory can define it as asserting, which
would provide assurance against code that could accidentally
put something projection-dependent in the cache;
* Line and triangle rendering is specified through a level of
indirection, hStroke and hFill. This is so that a future renderer
that batches geometry could cheaply group identical styles.
* DrawPixmap and DrawVectorText accept a (o,u,v) and not a matrix.
This is so that a future renderer into an output format that
uses 2d transforms (e.g. SVG) could easily derive those.
Some additional internal changes were required to enable this:
* Pixmap is now always passed as std::shared_ptr<{const ,}Pixmap>.
This is so that the renderer could cache uploaded textures
between API calls, which requires it to capture a (weak)
reference.
* The PlatformPathEqual function was properly extracted into
platform-specific code. This is so that the <windows.h> header
could be included only where needed (in platform/w32* as well
as rendergl1.cpp).
* The SBsp{2,3}::DebugDraw functions were removed. They can be
rewritten using the Canvas API if they are ever needed.
While no visual changes were originally intended, some minor fixes
happened anyway:
* The "emphasis" yellow line from top-left corner is now correctly
rendered much wider.
* The marquee rectangle is now pixel grid aligned.
* The hidden entities now do not clobber the depth buffer, removing
some minor artifacts.
* The workplane "tab" now scales with the font used to render
the workplane name.
* The workplane name font is now taken from the normals style.
* Workplane and constraint line stipple is insignificantly
different. This is so that it can reuse the existing stipple
codepaths; rendering of workplanes and constraints predates
those.
Some debug functionality was added:
* In graphics window, an fps counter that becomes red when
rendering under 60fps is drawn.
2016-05-31 00:55:13 +00:00
|
|
|
bool Equals(const Fill &other) const;
|
|
|
|
};
|
|
|
|
|
|
|
|
IdList<Stroke, hStroke> strokes;
|
|
|
|
IdList<Fill, hFill> fills;
|
|
|
|
|
2016-08-01 03:52:12 +00:00
|
|
|
Canvas() : strokes(), fills() {}
|
|
|
|
virtual void Clear();
|
Abstract all (ex-OpenGL) drawing operations into a Canvas interface.
This has several desirable consequences:
* It is now possible to port SolveSpace to a later version of
OpenGL, such as OpenGLES 2, so that it runs on platforms that
only have that OpenGL version;
* The majority of geometry is now rendered without references to
the camera in C++ code, so a renderer can now submit it to
the video card once and re-rasterize with a different projection
matrix every time the projection is changed, avoiding expensive
reuploads;
* The DOGD (draw or get distance) interface is now
a straightforward Canvas implementation;
* There are no more direct references to SS.GW.(projection)
in sketch rendering code, which allows rendering to multiple
viewports;
* There are no more unnecessary framebuffer flips on CPU on Cocoa
and GTK;
* The platform-dependent GL code is now confined to rendergl1.cpp.
* The Microsoft and Apple headers required by it that are prone to
identifier conflicts are no longer included globally;
* The rendergl1.cpp implementation can now be omitted from
compilation to run SolveSpace headless or with a different
OpenGL version.
Note these implementation details of Canvas:
* GetCamera currently always returns a reference to the field
`Camera camera;`. This is so that a future renderer that caches
geometry in the video memory can define it as asserting, which
would provide assurance against code that could accidentally
put something projection-dependent in the cache;
* Line and triangle rendering is specified through a level of
indirection, hStroke and hFill. This is so that a future renderer
that batches geometry could cheaply group identical styles.
* DrawPixmap and DrawVectorText accept a (o,u,v) and not a matrix.
This is so that a future renderer into an output format that
uses 2d transforms (e.g. SVG) could easily derive those.
Some additional internal changes were required to enable this:
* Pixmap is now always passed as std::shared_ptr<{const ,}Pixmap>.
This is so that the renderer could cache uploaded textures
between API calls, which requires it to capture a (weak)
reference.
* The PlatformPathEqual function was properly extracted into
platform-specific code. This is so that the <windows.h> header
could be included only where needed (in platform/w32* as well
as rendergl1.cpp).
* The SBsp{2,3}::DebugDraw functions were removed. They can be
rewritten using the Canvas API if they are ever needed.
While no visual changes were originally intended, some minor fixes
happened anyway:
* The "emphasis" yellow line from top-left corner is now correctly
rendered much wider.
* The marquee rectangle is now pixel grid aligned.
* The hidden entities now do not clobber the depth buffer, removing
some minor artifacts.
* The workplane "tab" now scales with the font used to render
the workplane name.
* The workplane name font is now taken from the normals style.
* Workplane and constraint line stipple is insignificantly
different. This is so that it can reuse the existing stipple
codepaths; rendering of workplanes and constraints predates
those.
Some debug functionality was added:
* In graphics window, an fps counter that becomes red when
rendering under 60fps is drawn.
2016-05-31 00:55:13 +00:00
|
|
|
|
|
|
|
hStroke GetStroke(const Stroke &stroke);
|
|
|
|
hFill GetFill(const Fill &fill);
|
|
|
|
|
|
|
|
virtual const Camera &GetCamera() const = 0;
|
|
|
|
|
|
|
|
virtual void DrawLine(const Vector &a, const Vector &b, hStroke hcs) = 0;
|
|
|
|
virtual void DrawEdges(const SEdgeList &el, hStroke hcs) = 0;
|
|
|
|
virtual bool DrawBeziers(const SBezierList &bl, hStroke hcs) = 0;
|
2016-06-26 06:39:27 +00:00
|
|
|
virtual void DrawOutlines(const SOutlineList &ol, hStroke hcs, DrawOutlinesAs drawAs) = 0;
|
Abstract all (ex-OpenGL) drawing operations into a Canvas interface.
This has several desirable consequences:
* It is now possible to port SolveSpace to a later version of
OpenGL, such as OpenGLES 2, so that it runs on platforms that
only have that OpenGL version;
* The majority of geometry is now rendered without references to
the camera in C++ code, so a renderer can now submit it to
the video card once and re-rasterize with a different projection
matrix every time the projection is changed, avoiding expensive
reuploads;
* The DOGD (draw or get distance) interface is now
a straightforward Canvas implementation;
* There are no more direct references to SS.GW.(projection)
in sketch rendering code, which allows rendering to multiple
viewports;
* There are no more unnecessary framebuffer flips on CPU on Cocoa
and GTK;
* The platform-dependent GL code is now confined to rendergl1.cpp.
* The Microsoft and Apple headers required by it that are prone to
identifier conflicts are no longer included globally;
* The rendergl1.cpp implementation can now be omitted from
compilation to run SolveSpace headless or with a different
OpenGL version.
Note these implementation details of Canvas:
* GetCamera currently always returns a reference to the field
`Camera camera;`. This is so that a future renderer that caches
geometry in the video memory can define it as asserting, which
would provide assurance against code that could accidentally
put something projection-dependent in the cache;
* Line and triangle rendering is specified through a level of
indirection, hStroke and hFill. This is so that a future renderer
that batches geometry could cheaply group identical styles.
* DrawPixmap and DrawVectorText accept a (o,u,v) and not a matrix.
This is so that a future renderer into an output format that
uses 2d transforms (e.g. SVG) could easily derive those.
Some additional internal changes were required to enable this:
* Pixmap is now always passed as std::shared_ptr<{const ,}Pixmap>.
This is so that the renderer could cache uploaded textures
between API calls, which requires it to capture a (weak)
reference.
* The PlatformPathEqual function was properly extracted into
platform-specific code. This is so that the <windows.h> header
could be included only where needed (in platform/w32* as well
as rendergl1.cpp).
* The SBsp{2,3}::DebugDraw functions were removed. They can be
rewritten using the Canvas API if they are ever needed.
While no visual changes were originally intended, some minor fixes
happened anyway:
* The "emphasis" yellow line from top-left corner is now correctly
rendered much wider.
* The marquee rectangle is now pixel grid aligned.
* The hidden entities now do not clobber the depth buffer, removing
some minor artifacts.
* The workplane "tab" now scales with the font used to render
the workplane name.
* The workplane name font is now taken from the normals style.
* Workplane and constraint line stipple is insignificantly
different. This is so that it can reuse the existing stipple
codepaths; rendering of workplanes and constraints predates
those.
Some debug functionality was added:
* In graphics window, an fps counter that becomes red when
rendering under 60fps is drawn.
2016-05-31 00:55:13 +00:00
|
|
|
virtual void DrawVectorText(const std::string &text, double height,
|
|
|
|
const Vector &o, const Vector &u, const Vector &v,
|
|
|
|
hStroke hcs) = 0;
|
|
|
|
|
|
|
|
virtual void DrawQuad(const Vector &a, const Vector &b, const Vector &c, const Vector &d,
|
|
|
|
hFill hcf) = 0;
|
2016-07-17 14:46:38 +00:00
|
|
|
virtual void DrawPoint(const Vector &o, hStroke hcs) = 0;
|
Abstract all (ex-OpenGL) drawing operations into a Canvas interface.
This has several desirable consequences:
* It is now possible to port SolveSpace to a later version of
OpenGL, such as OpenGLES 2, so that it runs on platforms that
only have that OpenGL version;
* The majority of geometry is now rendered without references to
the camera in C++ code, so a renderer can now submit it to
the video card once and re-rasterize with a different projection
matrix every time the projection is changed, avoiding expensive
reuploads;
* The DOGD (draw or get distance) interface is now
a straightforward Canvas implementation;
* There are no more direct references to SS.GW.(projection)
in sketch rendering code, which allows rendering to multiple
viewports;
* There are no more unnecessary framebuffer flips on CPU on Cocoa
and GTK;
* The platform-dependent GL code is now confined to rendergl1.cpp.
* The Microsoft and Apple headers required by it that are prone to
identifier conflicts are no longer included globally;
* The rendergl1.cpp implementation can now be omitted from
compilation to run SolveSpace headless or with a different
OpenGL version.
Note these implementation details of Canvas:
* GetCamera currently always returns a reference to the field
`Camera camera;`. This is so that a future renderer that caches
geometry in the video memory can define it as asserting, which
would provide assurance against code that could accidentally
put something projection-dependent in the cache;
* Line and triangle rendering is specified through a level of
indirection, hStroke and hFill. This is so that a future renderer
that batches geometry could cheaply group identical styles.
* DrawPixmap and DrawVectorText accept a (o,u,v) and not a matrix.
This is so that a future renderer into an output format that
uses 2d transforms (e.g. SVG) could easily derive those.
Some additional internal changes were required to enable this:
* Pixmap is now always passed as std::shared_ptr<{const ,}Pixmap>.
This is so that the renderer could cache uploaded textures
between API calls, which requires it to capture a (weak)
reference.
* The PlatformPathEqual function was properly extracted into
platform-specific code. This is so that the <windows.h> header
could be included only where needed (in platform/w32* as well
as rendergl1.cpp).
* The SBsp{2,3}::DebugDraw functions were removed. They can be
rewritten using the Canvas API if they are ever needed.
While no visual changes were originally intended, some minor fixes
happened anyway:
* The "emphasis" yellow line from top-left corner is now correctly
rendered much wider.
* The marquee rectangle is now pixel grid aligned.
* The hidden entities now do not clobber the depth buffer, removing
some minor artifacts.
* The workplane "tab" now scales with the font used to render
the workplane name.
* The workplane name font is now taken from the normals style.
* Workplane and constraint line stipple is insignificantly
different. This is so that it can reuse the existing stipple
codepaths; rendering of workplanes and constraints predates
those.
Some debug functionality was added:
* In graphics window, an fps counter that becomes red when
rendering under 60fps is drawn.
2016-05-31 00:55:13 +00:00
|
|
|
virtual void DrawPolygon(const SPolygon &p, hFill hcf) = 0;
|
|
|
|
virtual void DrawMesh(const SMesh &m, hFill hcfFront, hFill hcfBack = {},
|
|
|
|
hStroke hcsTriangles = {}) = 0;
|
|
|
|
virtual void DrawFaces(const SMesh &m, const std::vector<uint32_t> &faces, hFill hcf) = 0;
|
|
|
|
|
|
|
|
virtual void DrawPixmap(std::shared_ptr<const Pixmap> pm,
|
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
|
|
|
// A wrapper around Canvas that simplifies drawing UI in screen coordinates.
|
|
|
|
class UiCanvas {
|
|
|
|
public:
|
|
|
|
Canvas *canvas;
|
|
|
|
bool flip;
|
|
|
|
|
|
|
|
UiCanvas() : canvas(), flip() {};
|
|
|
|
|
|
|
|
void DrawLine(int x1, int y1, int x2, int y2, RgbaColor color, int width = 1);
|
|
|
|
void DrawRect(int l, int r, int t, int b, RgbaColor fillColor, RgbaColor outlineColor);
|
|
|
|
void DrawPixmap(std::shared_ptr<const Pixmap> pm, int x, int y);
|
|
|
|
void DrawBitmapChar(char32_t codepoint, int x, int y, RgbaColor color);
|
|
|
|
void DrawBitmapText(const std::string &str, int x, int y, RgbaColor color);
|
|
|
|
|
|
|
|
int Flip(int y) const { return flip ? (int)canvas->GetCamera().height - y : y; }
|
|
|
|
};
|
|
|
|
|
|
|
|
// A canvas that performs picking against drawn geometry.
|
|
|
|
class ObjectPicker : public Canvas {
|
|
|
|
public:
|
|
|
|
Camera camera;
|
|
|
|
// Configuration.
|
|
|
|
Point2d point;
|
|
|
|
double selRadius;
|
|
|
|
// Picking state.
|
|
|
|
double minDistance;
|
|
|
|
int maxZIndex;
|
|
|
|
uint32_t position;
|
|
|
|
|
|
|
|
ObjectPicker() : camera(), point(), selRadius(),
|
|
|
|
minDistance(), maxZIndex(), position() {}
|
|
|
|
|
|
|
|
const Camera &GetCamera() const override { return camera; }
|
|
|
|
|
|
|
|
void DrawLine(const Vector &a, const Vector &b, hStroke hcs) override;
|
|
|
|
void DrawEdges(const SEdgeList &el, hStroke hcs) override;
|
|
|
|
bool DrawBeziers(const SBezierList &bl, hStroke hcs) override { return false; }
|
2016-06-26 06:39:27 +00:00
|
|
|
void DrawOutlines(const SOutlineList &ol, hStroke hcs, DrawOutlinesAs drawAs) override;
|
Abstract all (ex-OpenGL) drawing operations into a Canvas interface.
This has several desirable consequences:
* It is now possible to port SolveSpace to a later version of
OpenGL, such as OpenGLES 2, so that it runs on platforms that
only have that OpenGL version;
* The majority of geometry is now rendered without references to
the camera in C++ code, so a renderer can now submit it to
the video card once and re-rasterize with a different projection
matrix every time the projection is changed, avoiding expensive
reuploads;
* The DOGD (draw or get distance) interface is now
a straightforward Canvas implementation;
* There are no more direct references to SS.GW.(projection)
in sketch rendering code, which allows rendering to multiple
viewports;
* There are no more unnecessary framebuffer flips on CPU on Cocoa
and GTK;
* The platform-dependent GL code is now confined to rendergl1.cpp.
* The Microsoft and Apple headers required by it that are prone to
identifier conflicts are no longer included globally;
* The rendergl1.cpp implementation can now be omitted from
compilation to run SolveSpace headless or with a different
OpenGL version.
Note these implementation details of Canvas:
* GetCamera currently always returns a reference to the field
`Camera camera;`. This is so that a future renderer that caches
geometry in the video memory can define it as asserting, which
would provide assurance against code that could accidentally
put something projection-dependent in the cache;
* Line and triangle rendering is specified through a level of
indirection, hStroke and hFill. This is so that a future renderer
that batches geometry could cheaply group identical styles.
* DrawPixmap and DrawVectorText accept a (o,u,v) and not a matrix.
This is so that a future renderer into an output format that
uses 2d transforms (e.g. SVG) could easily derive those.
Some additional internal changes were required to enable this:
* Pixmap is now always passed as std::shared_ptr<{const ,}Pixmap>.
This is so that the renderer could cache uploaded textures
between API calls, which requires it to capture a (weak)
reference.
* The PlatformPathEqual function was properly extracted into
platform-specific code. This is so that the <windows.h> header
could be included only where needed (in platform/w32* as well
as rendergl1.cpp).
* The SBsp{2,3}::DebugDraw functions were removed. They can be
rewritten using the Canvas API if they are ever needed.
While no visual changes were originally intended, some minor fixes
happened anyway:
* The "emphasis" yellow line from top-left corner is now correctly
rendered much wider.
* The marquee rectangle is now pixel grid aligned.
* The hidden entities now do not clobber the depth buffer, removing
some minor artifacts.
* The workplane "tab" now scales with the font used to render
the workplane name.
* The workplane name font is now taken from the normals style.
* Workplane and constraint line stipple is insignificantly
different. This is so that it can reuse the existing stipple
codepaths; rendering of workplanes and constraints predates
those.
Some debug functionality was added:
* In graphics window, an fps counter that becomes red when
rendering under 60fps is drawn.
2016-05-31 00:55:13 +00:00
|
|
|
void DrawVectorText(const std::string &text, double height,
|
|
|
|
const Vector &o, const Vector &u, const Vector &v,
|
|
|
|
hStroke hcs) override;
|
|
|
|
|
|
|
|
void DrawQuad(const Vector &a, const Vector &b, const Vector &c, const Vector &d,
|
|
|
|
hFill hcf) override;
|
2016-07-17 14:46:38 +00:00
|
|
|
void DrawPoint(const Vector &o, hStroke hcs) override;
|
Abstract all (ex-OpenGL) drawing operations into a Canvas interface.
This has several desirable consequences:
* It is now possible to port SolveSpace to a later version of
OpenGL, such as OpenGLES 2, so that it runs on platforms that
only have that OpenGL version;
* The majority of geometry is now rendered without references to
the camera in C++ code, so a renderer can now submit it to
the video card once and re-rasterize with a different projection
matrix every time the projection is changed, avoiding expensive
reuploads;
* The DOGD (draw or get distance) interface is now
a straightforward Canvas implementation;
* There are no more direct references to SS.GW.(projection)
in sketch rendering code, which allows rendering to multiple
viewports;
* There are no more unnecessary framebuffer flips on CPU on Cocoa
and GTK;
* The platform-dependent GL code is now confined to rendergl1.cpp.
* The Microsoft and Apple headers required by it that are prone to
identifier conflicts are no longer included globally;
* The rendergl1.cpp implementation can now be omitted from
compilation to run SolveSpace headless or with a different
OpenGL version.
Note these implementation details of Canvas:
* GetCamera currently always returns a reference to the field
`Camera camera;`. This is so that a future renderer that caches
geometry in the video memory can define it as asserting, which
would provide assurance against code that could accidentally
put something projection-dependent in the cache;
* Line and triangle rendering is specified through a level of
indirection, hStroke and hFill. This is so that a future renderer
that batches geometry could cheaply group identical styles.
* DrawPixmap and DrawVectorText accept a (o,u,v) and not a matrix.
This is so that a future renderer into an output format that
uses 2d transforms (e.g. SVG) could easily derive those.
Some additional internal changes were required to enable this:
* Pixmap is now always passed as std::shared_ptr<{const ,}Pixmap>.
This is so that the renderer could cache uploaded textures
between API calls, which requires it to capture a (weak)
reference.
* The PlatformPathEqual function was properly extracted into
platform-specific code. This is so that the <windows.h> header
could be included only where needed (in platform/w32* as well
as rendergl1.cpp).
* The SBsp{2,3}::DebugDraw functions were removed. They can be
rewritten using the Canvas API if they are ever needed.
While no visual changes were originally intended, some minor fixes
happened anyway:
* The "emphasis" yellow line from top-left corner is now correctly
rendered much wider.
* The marquee rectangle is now pixel grid aligned.
* The hidden entities now do not clobber the depth buffer, removing
some minor artifacts.
* The workplane "tab" now scales with the font used to render
the workplane name.
* The workplane name font is now taken from the normals style.
* Workplane and constraint line stipple is insignificantly
different. This is so that it can reuse the existing stipple
codepaths; rendering of workplanes and constraints predates
those.
Some debug functionality was added:
* In graphics window, an fps counter that becomes red when
rendering under 60fps is drawn.
2016-05-31 00:55:13 +00:00
|
|
|
void DrawPolygon(const SPolygon &p, hFill hcf) override;
|
|
|
|
void DrawMesh(const SMesh &m, hFill hcfFront, hFill hcfBack, hStroke hcsTriangles) override;
|
|
|
|
void DrawFaces(const SMesh &m, const std::vector<uint32_t> &faces, hFill hcf) override;
|
|
|
|
|
|
|
|
void DrawPixmap(std::shared_ptr<const Pixmap> pm,
|
|
|
|
const Vector &o, const Vector &u, const Vector &v,
|
|
|
|
const Point2d &ta, const Point2d &tb, hFill hcf) override;
|
|
|
|
void InvalidatePixmap(std::shared_ptr<const Pixmap> pm) override {}
|
|
|
|
|
|
|
|
void DoCompare(double distance, int zIndex, int comparePosition = 0);
|
|
|
|
void DoQuad(const Vector &a, const Vector &b, const Vector &c, const Vector &d,
|
|
|
|
int zIndex, int comparePosition = 0);
|
|
|
|
|
|
|
|
bool Pick(std::function<void()> drawFn);
|
|
|
|
};
|
|
|
|
|
2016-07-21 20:27:53 +00:00
|
|
|
// A canvas that renders onto a 2d surface, performing z-index sorting, occlusion testing, etc,
|
|
|
|
// on the CPU.
|
|
|
|
class SurfaceRenderer : public Canvas {
|
|
|
|
public:
|
|
|
|
Camera camera;
|
|
|
|
Lighting lighting;
|
|
|
|
// Chord tolerance, for converting beziers to pwl.
|
|
|
|
double chordTolerance;
|
|
|
|
// Render lists.
|
|
|
|
handle_map<hStroke, SEdgeList> edges;
|
|
|
|
handle_map<hStroke, SBezierList> beziers;
|
|
|
|
SMesh mesh;
|
|
|
|
// State.
|
|
|
|
BBox bbox;
|
|
|
|
|
|
|
|
SurfaceRenderer() : camera(), lighting(), chordTolerance(), mesh(), bbox() {}
|
2016-08-01 03:52:12 +00:00
|
|
|
void Clear() override;
|
2016-07-21 20:27:53 +00:00
|
|
|
|
|
|
|
// Canvas interface.
|
|
|
|
const Camera &GetCamera() const override { return camera; }
|
|
|
|
|
|
|
|
void DrawLine(const Vector &a, const Vector &b, hStroke hcs) override;
|
|
|
|
void DrawEdges(const SEdgeList &el, hStroke hcs) override;
|
|
|
|
bool DrawBeziers(const SBezierList &bl, hStroke hcs) override;
|
|
|
|
void DrawOutlines(const SOutlineList &ol, hStroke hcs, DrawOutlinesAs drawAs) override;
|
|
|
|
void DrawVectorText(const std::string &text, double height,
|
|
|
|
const Vector &o, const Vector &u, const Vector &v,
|
|
|
|
hStroke hcs) override;
|
|
|
|
|
|
|
|
void DrawQuad(const Vector &a, const Vector &b, const Vector &c, const Vector &d,
|
|
|
|
hFill hcf) override;
|
2016-07-17 14:46:38 +00:00
|
|
|
void DrawPoint(const Vector &o, hStroke hcs) override;
|
2016-07-21 20:27:53 +00:00
|
|
|
void DrawPolygon(const SPolygon &p, hFill hcf) override;
|
|
|
|
void DrawMesh(const SMesh &m, hFill hcfFront, hFill hcfBack, hStroke hcsTriangles) override;
|
|
|
|
void DrawFaces(const SMesh &m, const std::vector<uint32_t> &faces, hFill hcf) override;
|
|
|
|
|
|
|
|
void DrawPixmap(std::shared_ptr<const Pixmap> pm,
|
|
|
|
const Vector &o, const Vector &u, const Vector &v,
|
|
|
|
const Point2d &ta, const Point2d &tb, hFill hcf) override;
|
|
|
|
void InvalidatePixmap(std::shared_ptr<const Pixmap> pm) override;
|
|
|
|
|
|
|
|
// Geometry manipulation.
|
|
|
|
void CalculateBBox();
|
|
|
|
void ConvertBeziersToEdges();
|
|
|
|
void CullOccludedStrokes();
|
|
|
|
|
|
|
|
// Renderer operations.
|
|
|
|
void OutputInPaintOrder();
|
|
|
|
|
|
|
|
virtual bool CanOutputCurves() const = 0;
|
|
|
|
virtual bool CanOutputTriangles() const = 0;
|
|
|
|
|
|
|
|
virtual void OutputStart() = 0;
|
|
|
|
virtual void OutputBezier(const SBezier &b, hStroke hcs) = 0;
|
|
|
|
virtual void OutputTriangle(const STriangle &tr) = 0;
|
|
|
|
virtual void OutputEnd() = 0;
|
|
|
|
|
|
|
|
void OutputBezierAsNonrationalCubic(const SBezier &b, hStroke hcs);
|
|
|
|
};
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2016-07-24 13:17:52 +00:00
|
|
|
// 2d renderers.
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
class CairoRenderer : public SurfaceRenderer {
|
|
|
|
public:
|
|
|
|
cairo_t *context;
|
2016-07-25 19:37:48 +00:00
|
|
|
// Renderer configuration.
|
|
|
|
bool antialias;
|
2016-07-24 13:17:52 +00:00
|
|
|
// Renderer state.
|
|
|
|
struct {
|
|
|
|
hStroke hcs;
|
|
|
|
} current;
|
|
|
|
|
|
|
|
CairoRenderer() : context(), current() {}
|
|
|
|
|
|
|
|
void SelectStroke(hStroke hcs);
|
|
|
|
void MoveTo(Vector p);
|
|
|
|
void FinishPath();
|
|
|
|
|
|
|
|
bool CanOutputCurves() const override { return true; }
|
|
|
|
bool CanOutputTriangles() const override { return true; }
|
|
|
|
|
|
|
|
void OutputStart() override;
|
|
|
|
void OutputBezier(const SBezier &b, hStroke hcs) override;
|
|
|
|
void OutputTriangle(const STriangle &tr) override;
|
|
|
|
void OutputEnd() override;
|
|
|
|
};
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2016-07-21 20:27:53 +00:00
|
|
|
// 3d renderers.
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
2016-07-24 14:42:44 +00:00
|
|
|
// An offscreen renderer based on OpenGL framebuffers.
|
|
|
|
class GlOffscreen {
|
|
|
|
public:
|
|
|
|
unsigned int framebuffer;
|
|
|
|
unsigned int colorRenderbuffer, depthRenderbuffer;
|
|
|
|
std::vector<uint8_t> data;
|
|
|
|
|
|
|
|
bool Render(int width, int height, std::function<void()> renderFn);
|
|
|
|
void Clear();
|
|
|
|
};
|
|
|
|
|
Abstract all (ex-OpenGL) drawing operations into a Canvas interface.
This has several desirable consequences:
* It is now possible to port SolveSpace to a later version of
OpenGL, such as OpenGLES 2, so that it runs on platforms that
only have that OpenGL version;
* The majority of geometry is now rendered without references to
the camera in C++ code, so a renderer can now submit it to
the video card once and re-rasterize with a different projection
matrix every time the projection is changed, avoiding expensive
reuploads;
* The DOGD (draw or get distance) interface is now
a straightforward Canvas implementation;
* There are no more direct references to SS.GW.(projection)
in sketch rendering code, which allows rendering to multiple
viewports;
* There are no more unnecessary framebuffer flips on CPU on Cocoa
and GTK;
* The platform-dependent GL code is now confined to rendergl1.cpp.
* The Microsoft and Apple headers required by it that are prone to
identifier conflicts are no longer included globally;
* The rendergl1.cpp implementation can now be omitted from
compilation to run SolveSpace headless or with a different
OpenGL version.
Note these implementation details of Canvas:
* GetCamera currently always returns a reference to the field
`Camera camera;`. This is so that a future renderer that caches
geometry in the video memory can define it as asserting, which
would provide assurance against code that could accidentally
put something projection-dependent in the cache;
* Line and triangle rendering is specified through a level of
indirection, hStroke and hFill. This is so that a future renderer
that batches geometry could cheaply group identical styles.
* DrawPixmap and DrawVectorText accept a (o,u,v) and not a matrix.
This is so that a future renderer into an output format that
uses 2d transforms (e.g. SVG) could easily derive those.
Some additional internal changes were required to enable this:
* Pixmap is now always passed as std::shared_ptr<{const ,}Pixmap>.
This is so that the renderer could cache uploaded textures
between API calls, which requires it to capture a (weak)
reference.
* The PlatformPathEqual function was properly extracted into
platform-specific code. This is so that the <windows.h> header
could be included only where needed (in platform/w32* as well
as rendergl1.cpp).
* The SBsp{2,3}::DebugDraw functions were removed. They can be
rewritten using the Canvas API if they are ever needed.
While no visual changes were originally intended, some minor fixes
happened anyway:
* The "emphasis" yellow line from top-left corner is now correctly
rendered much wider.
* The marquee rectangle is now pixel grid aligned.
* The hidden entities now do not clobber the depth buffer, removing
some minor artifacts.
* The workplane "tab" now scales with the font used to render
the workplane name.
* The workplane name font is now taken from the normals style.
* Workplane and constraint line stipple is insignificantly
different. This is so that it can reuse the existing stipple
codepaths; rendering of workplanes and constraints predates
those.
Some debug functionality was added:
* In graphics window, an fps counter that becomes red when
rendering under 60fps is drawn.
2016-05-31 00:55:13 +00:00
|
|
|
// A canvas that uses the core OpenGL profile, for desktop systems.
|
|
|
|
class OpenGl1Renderer : public Canvas {
|
|
|
|
public:
|
|
|
|
Camera camera;
|
|
|
|
Lighting lighting;
|
|
|
|
// Cached OpenGL state.
|
|
|
|
struct {
|
|
|
|
bool drawing;
|
|
|
|
unsigned mode; // GLenum, but we don't include GL.h globally
|
|
|
|
hStroke hcs;
|
|
|
|
Stroke *stroke;
|
|
|
|
hFill hcf;
|
|
|
|
Fill *fill;
|
|
|
|
std::weak_ptr<const Pixmap> texture;
|
|
|
|
} current;
|
|
|
|
|
|
|
|
OpenGl1Renderer() : camera(), lighting(), current() {}
|
|
|
|
|
|
|
|
const Camera &GetCamera() const override { return camera; }
|
|
|
|
|
|
|
|
void DrawLine(const Vector &a, const Vector &b, hStroke hcs) override;
|
|
|
|
void DrawEdges(const SEdgeList &el, hStroke hcs) override;
|
|
|
|
bool DrawBeziers(const SBezierList &bl, hStroke hcs) override { return false; }
|
2016-06-26 06:39:27 +00:00
|
|
|
void DrawOutlines(const SOutlineList &ol, hStroke hcs, DrawOutlinesAs drawAs) override;
|
Abstract all (ex-OpenGL) drawing operations into a Canvas interface.
This has several desirable consequences:
* It is now possible to port SolveSpace to a later version of
OpenGL, such as OpenGLES 2, so that it runs on platforms that
only have that OpenGL version;
* The majority of geometry is now rendered without references to
the camera in C++ code, so a renderer can now submit it to
the video card once and re-rasterize with a different projection
matrix every time the projection is changed, avoiding expensive
reuploads;
* The DOGD (draw or get distance) interface is now
a straightforward Canvas implementation;
* There are no more direct references to SS.GW.(projection)
in sketch rendering code, which allows rendering to multiple
viewports;
* There are no more unnecessary framebuffer flips on CPU on Cocoa
and GTK;
* The platform-dependent GL code is now confined to rendergl1.cpp.
* The Microsoft and Apple headers required by it that are prone to
identifier conflicts are no longer included globally;
* The rendergl1.cpp implementation can now be omitted from
compilation to run SolveSpace headless or with a different
OpenGL version.
Note these implementation details of Canvas:
* GetCamera currently always returns a reference to the field
`Camera camera;`. This is so that a future renderer that caches
geometry in the video memory can define it as asserting, which
would provide assurance against code that could accidentally
put something projection-dependent in the cache;
* Line and triangle rendering is specified through a level of
indirection, hStroke and hFill. This is so that a future renderer
that batches geometry could cheaply group identical styles.
* DrawPixmap and DrawVectorText accept a (o,u,v) and not a matrix.
This is so that a future renderer into an output format that
uses 2d transforms (e.g. SVG) could easily derive those.
Some additional internal changes were required to enable this:
* Pixmap is now always passed as std::shared_ptr<{const ,}Pixmap>.
This is so that the renderer could cache uploaded textures
between API calls, which requires it to capture a (weak)
reference.
* The PlatformPathEqual function was properly extracted into
platform-specific code. This is so that the <windows.h> header
could be included only where needed (in platform/w32* as well
as rendergl1.cpp).
* The SBsp{2,3}::DebugDraw functions were removed. They can be
rewritten using the Canvas API if they are ever needed.
While no visual changes were originally intended, some minor fixes
happened anyway:
* The "emphasis" yellow line from top-left corner is now correctly
rendered much wider.
* The marquee rectangle is now pixel grid aligned.
* The hidden entities now do not clobber the depth buffer, removing
some minor artifacts.
* The workplane "tab" now scales with the font used to render
the workplane name.
* The workplane name font is now taken from the normals style.
* Workplane and constraint line stipple is insignificantly
different. This is so that it can reuse the existing stipple
codepaths; rendering of workplanes and constraints predates
those.
Some debug functionality was added:
* In graphics window, an fps counter that becomes red when
rendering under 60fps is drawn.
2016-05-31 00:55:13 +00:00
|
|
|
void DrawVectorText(const std::string &text, double height,
|
|
|
|
const Vector &o, const Vector &u, const Vector &v,
|
|
|
|
hStroke hcs) override;
|
|
|
|
|
|
|
|
void DrawQuad(const Vector &a, const Vector &b, const Vector &c, const Vector &d,
|
|
|
|
hFill hcf) override;
|
2016-07-17 14:46:38 +00:00
|
|
|
void DrawPoint(const Vector &o, hStroke hcs) override;
|
Abstract all (ex-OpenGL) drawing operations into a Canvas interface.
This has several desirable consequences:
* It is now possible to port SolveSpace to a later version of
OpenGL, such as OpenGLES 2, so that it runs on platforms that
only have that OpenGL version;
* The majority of geometry is now rendered without references to
the camera in C++ code, so a renderer can now submit it to
the video card once and re-rasterize with a different projection
matrix every time the projection is changed, avoiding expensive
reuploads;
* The DOGD (draw or get distance) interface is now
a straightforward Canvas implementation;
* There are no more direct references to SS.GW.(projection)
in sketch rendering code, which allows rendering to multiple
viewports;
* There are no more unnecessary framebuffer flips on CPU on Cocoa
and GTK;
* The platform-dependent GL code is now confined to rendergl1.cpp.
* The Microsoft and Apple headers required by it that are prone to
identifier conflicts are no longer included globally;
* The rendergl1.cpp implementation can now be omitted from
compilation to run SolveSpace headless or with a different
OpenGL version.
Note these implementation details of Canvas:
* GetCamera currently always returns a reference to the field
`Camera camera;`. This is so that a future renderer that caches
geometry in the video memory can define it as asserting, which
would provide assurance against code that could accidentally
put something projection-dependent in the cache;
* Line and triangle rendering is specified through a level of
indirection, hStroke and hFill. This is so that a future renderer
that batches geometry could cheaply group identical styles.
* DrawPixmap and DrawVectorText accept a (o,u,v) and not a matrix.
This is so that a future renderer into an output format that
uses 2d transforms (e.g. SVG) could easily derive those.
Some additional internal changes were required to enable this:
* Pixmap is now always passed as std::shared_ptr<{const ,}Pixmap>.
This is so that the renderer could cache uploaded textures
between API calls, which requires it to capture a (weak)
reference.
* The PlatformPathEqual function was properly extracted into
platform-specific code. This is so that the <windows.h> header
could be included only where needed (in platform/w32* as well
as rendergl1.cpp).
* The SBsp{2,3}::DebugDraw functions were removed. They can be
rewritten using the Canvas API if they are ever needed.
While no visual changes were originally intended, some minor fixes
happened anyway:
* The "emphasis" yellow line from top-left corner is now correctly
rendered much wider.
* The marquee rectangle is now pixel grid aligned.
* The hidden entities now do not clobber the depth buffer, removing
some minor artifacts.
* The workplane "tab" now scales with the font used to render
the workplane name.
* The workplane name font is now taken from the normals style.
* Workplane and constraint line stipple is insignificantly
different. This is so that it can reuse the existing stipple
codepaths; rendering of workplanes and constraints predates
those.
Some debug functionality was added:
* In graphics window, an fps counter that becomes red when
rendering under 60fps is drawn.
2016-05-31 00:55:13 +00:00
|
|
|
void DrawPolygon(const SPolygon &p, hFill hcf) override;
|
|
|
|
void DrawMesh(const SMesh &m, hFill hcfFront, hFill hcfBack, hStroke hcsTriangles) override;
|
|
|
|
void DrawFaces(const SMesh &m, const std::vector<uint32_t> &faces, hFill hcf) override;
|
|
|
|
void DrawPixmap(std::shared_ptr<const Pixmap> pm,
|
|
|
|
const Vector &o, const Vector &u, const Vector &v,
|
|
|
|
const Point2d &ta, const Point2d &tb, hFill hcf) override;
|
|
|
|
void InvalidatePixmap(std::shared_ptr<const Pixmap> pm) override;
|
|
|
|
|
|
|
|
void SelectPrimitive(unsigned mode);
|
|
|
|
void UnSelectPrimitive();
|
|
|
|
Stroke *SelectStroke(hStroke hcs);
|
|
|
|
Fill *SelectFill(hFill hcf);
|
|
|
|
void SelectTexture(std::shared_ptr<const Pixmap> pm);
|
|
|
|
void DoFatLineEndcap(const Vector &p, const Vector &u, const Vector &v);
|
|
|
|
void DoFatLine(const Vector &a, const Vector &b, double width);
|
|
|
|
void DoLine(const Vector &a, const Vector &b, hStroke hcs);
|
|
|
|
void DoPoint(Vector p, double radius);
|
|
|
|
void DoStippledLine(const Vector &a, const Vector &b, hStroke hcs);
|
|
|
|
|
|
|
|
void UpdateProjection(bool flip = FLIP_FRAMEBUFFER);
|
|
|
|
void BeginFrame();
|
|
|
|
void EndFrame();
|
|
|
|
std::shared_ptr<Pixmap> ReadFrame();
|
|
|
|
|
|
|
|
static void GetIdent(const char **vendor, const char **renderer, const char **version);
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|