使用DirectX或OpenGL显示100个浮动立方体

vuv7lop3  于 2022-09-26  发布在  其他
关注(0)|答案(4)|浏览(169)

我想使用DirectXOpenGL显示100个浮动立方体。

我正在寻找一些样本源代码,或技术的描述。我无法让多个立方体正确显示。

我在网上搜索了一系列很好的教程,虽然他们谈到了如何做3D原语,但我找不到关于如何做大量3D原语的信息-cubesspherespyramids等等。

nwsw7zdq

nwsw7zdq1#

你说你很难找到一个立方体来展示...所以我不知道你们有没有要展示的。

基本上..。将编写立方体的代码放在一个函数中,然后只需调用该函数100次。

void DrawCube()
{
    //code to draw the cube
}

void DisplayCubes()
{
    for(int i = 0; i < 10; ++i)
    {   
         for(int j = 0; j < 10; ++j)
         {
             glPushMatrix();
             //alter these values depending on the size of your cubes.
             //This call makes sure that your cubes aren't drawn overtop of each other
             glTranslatef(i*5.0, j*5.0, 0);
             DrawCube();
             glPopMatrix();
         }
    }              
}

这就是你如何着手做这件事的基本轮廓。如果你想要更有效率的东西,一旦你搞清楚了基本知识,找个时间看看展示列表:)

y4ekin9u

y4ekin9u2#

只需使用glTranslatef(或DirectX等效物)使用相同的代码绘制一个立方体,但移动绘制它的相对点。也许有一种更好的方法可以做到这一点,但我对OpenGL还很陌生。一定要设置您的视点,这样您就可以全部看到它们。

vxf3dgd4

vxf3dgd43#

是的,如果你是高效的,你会把所有东西都放在同一个顶点缓冲区中,但我不认为绘制100个立方体会推动过去5年生产的任何GPU,所以你应该可以遵循上面的建议。

编写一个基本的穿透顶点着色器,在像素着色器中随心所欲地着色。要么传入世界矩阵并在顶点着色器中进行平移,要么只计算CPU端的世界空间顶点位置(如果立方体将保持固定,则执行此操作)。

你可以变得花哨,然后做geometry instancing等,但首先要做的是基本的事情。

qnzebej0

qnzebej04#

这个答案不仅仅是针对OP的问题。它还回答了一个更一般的问题--显示许多立方体通常

绘制多个立方体网格

这可能是最天真的做事方式。我们使用许多不同的变换矩阵绘制相同的立方体网格:

prepare();

for (int i = 0; i < numCubes; i++) {
    setTransformation(matrices[i]);
    drawCube();
}
/* and so on... */

好的是,这非常容易实现,而且不会太慢(至少对100个立方体来说是这样)。我推荐这个作为开胃菜。

问题所在

好的,但是假设你想做一个《我的世界》的克隆,或者至少是某种需要渲染数千个立方体(如果不是数万个立方体)的项目。这就是性能开始下降的地方。问题是,每个DrawCube()都向GPU发送一个绘制调用,而每个绘制调用中的时间加起来,最终会让人无法忍受。

然而,我们可以解决这个问题。解决方案是“批处理”,这是一种只对所有立方体执行一次绘制调用的方法。

批量处理

我们将所有(变换后的)立方体连接到一个网格中。这意味着我们将只需处理一次平局,而不是数千次。以下是执行此操作的一些伪代码:

vector<float> transformedVerts;

for (int i = 0; i < numCubes; i++) {
    cubeData = cubes[i];
    for (int j = 0; j < numVertsPerCube; j++) {
        vert = verts[j];
        /* We transform the position by the transformation matrix. */
        vec3 vposition = matrices[i] * verts.position; 
        transformedVerts.push(vposition);

        /* We don't need to transform the colors, so we just directly push them. */
        transformedVerts.push(vert.color);
    }
}

...
sendDataToBuffer(transformedVerts);

如果多维数据集正在移动,或者添加或删除了其中一个多维数据集,则必须重新计算transformedVerts,然后将其重新发送到缓冲区-但这是次要的。

然后在最后,我们在一次绘制调用中绘制整个聚集在一起的网格,而不是很多次。

相关问题