在OpenGL中绘制对象的技巧

时间:2013-07-11 00:01:27

标签: drawing

在OpenGL中绘制大量对象的技术

我想知道我可以使用什么技术或方法在OpenGL上绘制很多对象。

例如,我可能有一个代表砖块的类,也许是另一个代表树的类,或者我想要像灯柱一样随机抽取的东西。然后说,我有很多砖块可以绘制,或者灯柱或类似的东西......为每个砖块调用一个绘制方法会导致很长的代码。

目前我正在使用过剩回调函数来绘制世界中的“东西”,如砖块或树木。

使用全局可访问的基指针向量

我的一个想法是让所有类继承自基类,并将基本指针放入向量 - 然后将向量设置为全局。这样我可以做类似的事情:

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

每个对象都可以有一个绘制函数,它绘制所有OpenGL基元。

这样一个类的例子就是这样的。 (这是我一直在试验的。)

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

替代?

这似乎不是一个好主意,因为为像房子这样的东西创建一个新类,需要用户记住添加一个名为'draw'的绘图函数...虽然这是一个微不足道的观点,但不是一定是个大问题。

是否在工业或游戏开发中使用了不同的技术?我看到这个方法的优点是,一旦for循环被放入draw函数中,你就可以忘记它 - 只需要担心在全局可访问的向量中放置更多项(或指针)。

有没有人对更好的选择有任何建议?

3 个答案:

答案 0 :(得分:1)

为Stuff创建一个接口并从中继承类。这样,没有人会忘记需要实现绘制方法。

答案 1 :(得分:0)

创建一个抽象基类,其中包含用于呈现对象的纯虚函数。这会强制派生类实现该函数,以便然后进行实例化。

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
    }
};

现在你可以像这样使用它......

std::vector<shape*> vector_of_objects;

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

答案 2 :(得分:0)

这是一个更复杂的问题:)

从opengl的角度来看,对象立方体,盒子,树......那些被推到管道的ony三角形。 你真的需要将它们分开吗?可能你只需要游戏/应用程序的逻辑,而不是渲染。

所以一般来说游戏中的对象可以这样声明:

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

    doStuff();
}

Model3D - 可能从某个文件加载的网格,包含三角形+材质+着色器+纹理等。它用于绘制对象。

PhysicsModel - 物理引擎中使用的对象的物理表示。

由此您可以派生出自己的对象。 如果要渲染整组对象,请将m_mesh - es推送到渲染队列

一般来说,你有一些实体+它的各种表现形式(渲染,物理)。

RenderQueue 收集要渲染的网格,可以按材质(着色器,纹理等)对它们进行排序,并进行高效渲染。它可以使用实例化,剔除技术等等。

更新对象后,您将把它们添加到渲染队列:

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

然后在渲染代码中,您将调用:

rendering_queue->renderAll();

请参阅此处有关benefits of data driven engine

的精彩演示文稿