Thread: Polymorphism - Can't Articulate Problem

  1. #1
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465

    Polymorphism - Can't Articulate Problem

    Okay. here's a problem I can't wrap my mind around. I think I basically need all of my opengl transformations to be isolated by glPushMatrix and glPopMatrix. So I have stuff like this:

    Code:
    abstract base object has virtual void draw() = 0
    
    class stuff extends object and implements draw
    class sturf extends object and implements draw
    class stcrf extends object and implements draw
    
    application has array of objects and draws them
    I need each drawing routine to be encased in a glPushMatrix and glPopMatrix. I think I understand that this is kind of simplistic in it's approach, and even still I can't figure it out, and if there's a better design, suggestions are welcomed.

  2. #2
    Registered User
    Join Date
    May 2006
    Posts
    903
    You could do something like this:

    Code:
    void DrawObjects(std::list<Object*> ls) {
      std::list<Object*>::iterator it;
      for(it = ls.begin(); it != ls.end(); it++) {
        glPushMatrix();
          (*it)->Draw();
        glPopMatrix();
      }
    }

  3. #3
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    If I understood your problem, you can maintain the pure virtual but still implement it on the ABC.

    Your deriveds will then be able to implement their own draw() and call base:: Draw() from within, where appropriate.

    EDIT: Is there any way to avoid the annoyance of having to put a space to avoid the smiley on base:raw()?
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  4. #4
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    Quote Originally Posted by Tonto
    Okay. here's a problem I can't wrap my mind around. I think I basically need all of my opengl transformations to be isolated by glPushMatrix and glPopMatrix. So I have stuff like this:

    Code:
    abstract base object has virtual void draw() = 0
    
    class stuff extends object and implements draw
    class sturf extends object and implements draw
    class stcrf extends object and implements draw
    
    application has array of objects and draws them
    I need each drawing routine to be encased in a glPushMatrix and glPopMatrix. I think I understand that this is kind of simplistic in it's approach, and even still I can't figure it out, and if there's a better design, suggestions are welcomed.
    One thing you could do would be:

    Code:
    void Base::Paint(){
        BeginDraw();
        Draw();
        EndDraw();
    }
    
    virtual void Base::BeginDraw(){
        glPushMatrix();
    }
    
    virtual void Base::Draw() = 0;
    
    virtual void Base::EndDraw(){
        glPopMatrix();
    }
    If your child classes implement BeginDraw/EndDraw (to do their own init/cleanup) then they should call the base class at the beginning of BeginDraw and the end of EndDraw.
    You ever try a pink golf ball, Wally? Why, the wind shear on a pink ball alone can take the head clean off a 90 pound midget at 300 yards.

  5. #5
    The superhaterodyne twomers's Avatar
    Join Date
    Dec 2005
    Location
    Ireland
    Posts
    2,273
    >> EDIT: Is there any way to avoid the annoyance of having to put a space to avoid the smiley on base:raw()?

    I can never tell when you're being sarcastic or not, so try this the next time: [noparse]:D[/noparse] I think it's not worth the effort to do. Besides, some people find that syntax aesthetic ...

    std :: vector< std :: string :: size_tpye var > d;

    Just confusing, in my opinion.

  6. #6
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Perfect! Thanks.

    I wasn't being sarcastic this time
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Disable smilies in text. :D

  8. #8
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Even better, thanks!
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  9. #9
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597
    how about something like this

    Code:
    class DrawableObject
    {
    public:
        virtual void Draw(void) const = 0; // drawing should not affect state of object
    };
    
    // lots of classes that derive from DrawableObject and implement Draw()
    
    class GlPainter
    public:
        GlPainter(void)
        {
             glPushMatrix();
        }
    
        ~GlPainter(void)
        {
             glPopMatrix();
        }
    
        void operator()(const DrawableObject& obj)
        {
             obj->Draw();
        }
    };
    
    void DoPainting(const DrawableObject& obj)
    {
        GlPainter paint;
        paint();
    }
    
    typedef boost::ptr_vector<DrawableObject> DrawingColl;
    
    void Paint(const DrawingColl& coll)
    {
        std::for_each(coll.begin(), coll.end(), DoPainting);
    }
    while it could use some fine tuning, it has the advantage of being exception safe
    "I saw a sign that said 'Drink Canada Dry', so I started"
    -- Brendan Behan

    Free Compiler: Visual C++ 2005 Express
    If you program in C++, you need Boost. You should also know how to use the Standard Library (STL). Want to make games? After reading this, I don't like WxWidgets anymore. Want to add some scripting to your App?

  10. #10
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    For some reason I didn't really understand that I could just do exactly what Desolation mentioned. Haha. But, there are lots of ways to do it, as you guys have shown. That begindraw/enddraw thing could be useful if specialized initialization would be necessary, and the safety of ce's is good. I may consider looking into boost libraries some time.

  11. #11
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    On top of that, check also the Bridge Pattern. I'm not quiet sure if it isn't too much for your current needs, but sure makes an interesting reading for more complex needs.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  12. #12
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Using this simple class (or some variant of it), is a simple addition to Desolation's code that makes at least the popping of the matrix exception safe:
    Code:
    class GlPainter {
    public:
        GlPainter(void)
        {
             glPushMatrix();
        }
        ~GlPainter(void)
        {
             glPopMatrix();
        }
    };
    
    void DrawObjects(std::list<Object*> ls) {
      std::list<Object*>::iterator it;
      for(it = ls.begin(); it != ls.end(); it++) {
        GlPainter paint;
        (*it)->Draw();
      }
    }

  13. #13
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    I don't get the point of the bridge pattern.

    Anyway, here's another thing you can do:
    Code:
    class Drawable
    {
    public:
      void draw() {
        glPushMatrix();
        do_draw();
        glPopMatrix();
      }
    protected:
      virtual void do_draw() = 0;
    };
    Subclasses override not draw() but do_draw(). Because do_draw() is protected, it cannot be called directly from the outside; all calls must go through draw(), which performs the wrapping operation.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  14. #14
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    I like that option the best. You might actually want to make do_draw private instead of protected. There shouldn't be any do_draw-ing happening outside of the draw() function.

  15. #15
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    > I don't get the point of the bridge pattern.

    Could you elaborate on that CornedBee?
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Someone having same problem with Code Block?
    By ofayto in forum C++ Programming
    Replies: 1
    Last Post: 07-12-2007, 08:38 AM
  2. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  3. Polymorphism Problem
    By ltanusaputra in forum C++ Programming
    Replies: 3
    Last Post: 04-25-2007, 11:36 AM
  4. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM
  5. beginner problem
    By The_Nymph in forum C Programming
    Replies: 4
    Last Post: 03-05-2002, 05:46 PM