separate data from rendering

A

alessio211734

I wrote my spline class, now I think that it's not good put a draw method in this class because I would separate the spline data from the rendering that depend on the library that I could use.

class Spline
{
Spline(std::vector<Point3d>...)
.....
}

What's the best solution to separate rendering from spline data.
 
V

Victor Bazarov

I wrote my spline class, now I think that it's not good put a draw method in this class because I would separate the spline data from the rendering that depend on the library that I could use.

class Spline
{
Spline(std::vector<Point3d>...)
....
}

What's the best solution to separate rendering from spline data.

Generally, I'd probably go with the design that defines a drawing
mechanism - some kind of abstract "drawer" that is aware of your spline
and can be also implemented to accommodate the details of rendering
facility you want to use. Whether that "drawer" should know the details
(implementation) of 'Spline' or should request certain other kind of
data that represents your 'Spline' to the rendering facility is up to
you. OOH it could just have that extra dependency (i.e. it knows how to
extract the curve from 'Spline' to draw it) or OTOH you could add that
additional abstraction where the curve to be rendered is some kind of
low-level data that the "drawer" and 'Spline' exchange...

V
 
N

Nobody

I wrote my spline class, now I think that it's not good put a draw method
in this class because I would separate the spline data from the rendering
that depend on the library that I could use.

I certainly wouldn't make the geometry classes depend directly upon a
particular rendering API (OpenGL, DirectX, whatever).

You could implement a draw() method which operates by calling methods of
an abstract "canvas" object passed as a parameter. But even that risks
introducing a dependency; it's actually quite hard to design an abstract
rendering API which is a reasonable fit for concrete rendering APIs other
than the one(s) with which you're familiar.

But then simply returning data can have similar issues. Some APIs may just
need a pointer to the returned data, others may need it converted to a
different format or otherwise processed.

Allow for the possibility of renderers which can handle splines natively.
Even if it ends up subdividing into line segments, a tessellation shader
running on the GPU is likely to be more efficient than near-identical code
running on the CPU (if only because passing control points requires less
bandwidth and video memory than passing a polyline).
 
R

Rui Maciel

alessio211734 said:
I wrote my spline class, now I think that it's not good put a draw method
in this class because I would separate the spline data from the rendering
that depend on the library that I could use.

class Spline
{
Spline(std::vector<Point3d>...)
....
}

What's the best solution to separate rendering from spline data.

Here are my 0,02€.

A quick and dirty solution would be to define a class/function that would
act as an operator that, when passing a Spline object as an operand, would
churn out the code needed to render the spline object. If you go through
this route then it would be in your best interests to implement this through
a strategy pattern, dedicated to render the graphical objects in your scene.
You could pull off something like:

<pseudo-ish code>

class ObjectRenderingStrategy
{
public:
/* snip other members... */
virtual void spline(Spline const &) = 0;
};

/* a rendering strategy intended to render objects in a bland way */
class BlandRenderingConcreteStrategy
: public ObjectRenderingStrategy
{
public:
void spline(Spline const &);
};

void
BlandRenderingConcreteStrategy::spline(Spline const &spline)
{
// code to render a spline here
}

/* a rendering strategy intended to render objects in an awesome way */
class AwesomeRenderingConcreteStrategy
: public ObjectRenderingStrategy
{
public:
void spline(Spline const &);
};

void
AwesomeRenderingConcreteStrategy::spline(Spline const &spline)
{
// code to render a spline here
}

// now, the render loop

void some_sort_of_rendering_routine(void)
{
BlandRenderingConcreteStrategy bland;
AwesomeRenderingConcreteStrategy awesome;

ObjectRenderingStrategy *render = NULL;

/* whether you wish to render your splines the bland way or the awesome
way, the only thing you need to do is assign ObjectRenderingStrategy *render
to an object of one of of those strategies. This means that if you wish to
implement an entirely new way of rendering your graphical objects then all
you really need to do is define a new concrete strategy class and assign a
pointer to an object of that type. It may look needlessly complicated but it
will save a hefty amount of time in the medium and long run */

for(Spline &spline: my_list_of_spline_objects)
{
render->(spline); /* et voilá. spline rendered according to
the current render policy */
}
}
</pseudo-ish code>

In contrast, a more pristine solution would consist in implementing a model-
view-controller design pattern.

http://en.wikipedia.org/wiki/Model–view–controller

There are other alternatives, but this approach tends to be a bit more
forgiving to design changes in your code.


Hope this helps,
Rui Maciel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top