0

Techniques for drawing large numbers of objects in OpenGL

I am wondering what techniques or methods I could use to draw many objects on OpenGL.

For example, I may have a class which represents a brick, and maybe another which represents a tree, or something else random which I would like to draw like a lamppost. Then say, I have many bricks to draw, or lampposts or something like that... Calling a draw method for each one would lead to very long code.

At the moment I am using a glut callback function to draw the "stuff" in the world, like a brick or tree.

Using a globally accessible vector of base pointers

One idea I had was to have all the classes inherit from a base class, and put base pointers into a vector - then have the vector global. That way I could do something like:

for(int i = 0; i < vector_of_objects.size(); i ++)
    vector_of_objects[i]->draw();

Each object could have a draw function, which draws all the OpenGL primitives.

An example of such a class would be something like this. (This is what I have been experimenting with.)

class box {
    public:
        void draw() { // Do the drawing of a box }
    // Other members etc
}

Alternatives?

This doesn't seem like a good idea, since creating a new class for something like a house, would require the user to remember to add a draw function called 'draw'... Although this is a trivial point, not necessarily a big problem.

Are different techniques used in industry or games development? The advantage I see to this method is once the for loop is put in the draw function, you can forget about it - only having to worry about placing more items (or pointers) in the globally accessible vector.

Does anyone have any suggestions for a better alternative?

Mark Ingram
  • 65,792
  • 48
  • 164
  • 225
FreelanceConsultant
  • 9,832
  • 22
  • 88
  • 173
  • 4
    This would be better off on http://gamedev.stackexchange.com as it doesn't ask about a specific programming problem. – Mark Ingram Jul 11 '13 at 13:34

3 Answers3

1

Create an interface for your Stuff and inherit classes from that. This way nobody will forget that a draw method needs to be implemented.

Lajos Arpad
  • 45,912
  • 26
  • 82
  • 148
  • That is an excellent idea! I can also use the interface to create a base pointer. What defines an interface? What makes it different from a class? – FreelanceConsultant Jul 11 '13 at 00:21
  • 1
    An interface is an abstract description. You cannot instantiate an interface. For instance, you know a Bird can fly, but cannot define its flight due to the many types of Birds and Bird.fly(). So you define an interface called Bird where you declare its attributes (members) and methods. You can do this with class too, but there is no point to do that, as your draw() method is abstract and will be implemented in the inherited classes. Read more here: http://stackoverflow.com/questions/318064/how-do-you-declare-an-interface-in-c – Lajos Arpad Jul 11 '13 at 00:49
0

Create an abstract base class that contains a pure virtual function used for rendering the object. This forces the derived classes to implement the function in order for then to be instantiated.

class shape
{
public:
    virtual void draw( /* parameters */ ) = 0; // pure virtual

    // other member functions 
};

class box : public shape
{
public:
    virtual void draw( /* parameters same as in shape */ )
    {
        // rendering code goes here
    }
};

Now you can use it like so...

std::vector<shape*> vector_of_objects;

for(int i = 0; i < vector_of_objects.size(); i ++)
    vector_of_objects[i]->draw( /* arguments */ );
Captain Obvlious
  • 18,485
  • 5
  • 36
  • 70
0

It it more complicated question :)

From opengl point of view object cube, box, tree... those are ony triangles pushed to the pipeline. Do you really need to have them separated? Probably you need but only for the logic of the game/app, not for the rendering.

So in general object in game can be declared like this:

class Object {
    Model3D m_mesh;
    PhysicsModel m_physicsModel;
    ...

    doStuff();
}

Model3D - mesh loaded from some file probably, contains triangles + materials + shaders + textures, etc. It is used to draw object.

PhysicsModel - physical representation of the object, used in physics engine.

From that you can derive your own objects. When you want to render the whole bunch of objects you push m_mesh-es to the rendering queue.

In general you have some entity + its various representations (rendering, physics).

RenderQueue collects meshes to render, can sort them by the material (shader, texture, etc) and do the efficient rendering. It can use instancing, culling techniques, etc, etc.

after objects are updated you will add them to rendering queue:

for(int i = 0; i < vector_of_objects.size(); i++)
    rendering_queue->add(object[i].m_mesh);

then in rendering code you will call:

rendering_queue->renderAll();

See nice presentation here about benefits of data driven engine

fen
  • 8,812
  • 5
  • 29
  • 53