separate data from rendering

Discussion in 'C++' started by alessio211734, Sep 20, 2012.

  1. 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.
     
    alessio211734, Sep 20, 2012
    #1
    1. Advertising

  2. On 9/20/2012 11:42 AM, alessio211734 wrote:
    > 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
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Sep 20, 2012
    #2
    1. Advertising

  3. alessio211734

    Nobody Guest

    On Thu, 20 Sep 2012 08:42:01 -0700, alessio211734 wrote:

    > 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).
     
    Nobody, Sep 21, 2012
    #3
  4. alessio211734

    Rui Maciel Guest

    alessio211734 wrote:

    > 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
     
    Rui Maciel, Sep 21, 2012
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John
    Replies:
    1
    Views:
    396
  2. Keith
    Replies:
    4
    Views:
    764
    DalePres
    May 2, 2004
  3. EvgueniB
    Replies:
    1
    Views:
    671
    Anthony Borla
    Dec 15, 2003
  4. Peter Mount
    Replies:
    4
    Views:
    1,000
    Peter Mount
    Jan 31, 2006
  5. Frank Fredstone
    Replies:
    1
    Views:
    466
    Jean-Francois Briere
    Jun 27, 2006
Loading...

Share This Page