简体   繁体   中英

Object Oriented Programming and OpenGL

I want to use OpenGL as graphics of my project. But I really want to do it in a good style. How can I declare a member function "draw()" for each class to call it within OpenGL display function?

For example, I want something like this:

class Triangle
{
    public:
        void draw()
        {
           glBegin(GL_TRIANGLES);
              ...
           glEnd();
        }
};

Well, it also depends on how much time you have and what is required. Your approach is not bad, a little old-fashioned, though. Modern OpenGL uses shaders, but I this is not covered by your (school?) project, I guess. For that purpose, and for starters, your approach should be completely OK .

Besides shaders, if you wanted to progress a little further, you could also go in the direction of using more generic polygon objects, simply storing a list of vertices and combine that with a separate 'Renderer' class that would be capable of rendering polygons, consisting of triangles. The code would look like this:

renderer.draw(triangle);

Of course, a polygon can have some additional attributes like color, texture, transparency, etc. You can have some more specific polygon classes like TriangleStrip , TriangleFan , etc., also. Then all you need to do is to write a generic draw() method in your OpenGL Renderer that will be able to set all the states and push the vertices to rendering pipeline.

When I was working on my PhD, I wrote a simulator which did what you wanted to do. Just remember that even though your code may look object oriented, the OpenGL engine still renders things sequentially. Also, the sequential nature of matrix algrebra, which is under the hood in OpenGL, is sometimes not in the same order as you would logically think (when do I translate, when do I draw, when do I rotate, etc.?).

Remember LOGO back in the old days? It had a turtle, which was a pen, and you moved the turtle around and it would draw lines. If the pen was down, it drew, if the pen was up, it did not. That is how my mindset was when I worked on this program. I would start the "turtle" at a familiar coordinate (0, 0, 0), and use the math to translate it (move it around to the center of the object I want to draw), then call the draw() methods you are trying to write to draw my shape based on the relative coordinate system where the "turtle" is, not from absolute (0, 0, 0). Then I would move, the turtle, draw, etc. Hope that helps...

No, it won't work like this. The problem is that the GLUT Display function is exactly one function. So if you wanted to draw a bunch of triangles, you could still only register one of their draw() functions to be the GLUT display function. (Besides, pointers to member functions in C++ are a hard topic as well).

So as suggested above, go for a dedicated Renderer class. This class would know about all drawable objects in your application.

class Renderer {
   std::list<Drawable> _objects;

   public:
      drawAllObjects() {
         // iterate through _objects and call the respective draw() functions
      }
};

Your GLUT display function would then be a static function that calls drawAllObjects() on a (global or not) renderer object.

Ah, good old immediate-mode OpenGL. :) That routine there looks fine.

I would probably make the 'draw' method virtual, though, and inherit from a 'Drawable' base type that specifies the methods such classes have.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM