一个vbo中有多个四边形

时间:2016-10-31 13:33:11

标签: c++ opengl voxel

我正在开发一个Minecraft-ish游戏,而且我一直在使用vbos工作。然而;在单个vbo中绘制多个面时,我似乎有点问题。

这是我的vbo代码:

glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, verts);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, verts * 9 * sizeof(GLfloat), NULL, GL_STATIC_DRAW);
void* ptr = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);

GLfloat*model = (GLfloat*)ptr;
GLfloat*tex = ((GLfloat*)ptr) + verts * 6;
GLfloat*color = ((GLfloat*)ptr) + verts * 3;
int p = 0;
int k = p * 3;

    for (int mcy = 0; mcy < 5; mcy++) {
        for (int mcx = 0; mcx < 5; mcx++) {
        double addonX = mcx*32.0; 
        double addonY = mcy*32.0; 
        int addonx = mcx * 32;
        int addony = mcy * 32;
        if (!(hill.get(addonX, addonY)*400.0 > 100 && hill.get(32 + addonX, addonY)*400.0 > 100 && hill.get(addonX, 32 + addonY)*400.0 > 100 && hill.get(32 + addonX, 32 + addonY)*400.0 > 100)) {
            draw = true;

            int biome1 = BiomeToColor(GetBiome(x, y, addonX, addonY), hill.get(addonX, addonY)*400.0);
            int biome2 = BiomeToColor(GetBiome(x, y, 32 + addonX, addonY), hill.get(32 + addonX, addonY)*400.0);
            int biome3 = BiomeToColor(GetBiome(x, y, addonX, 32 + addonY), hill.get(addonX, 32 + addonY)*400.0);
            int biome4 = BiomeToColor(GetBiome(x, y, 32 + addonX, 32 + addonY), hill.get(32 + addonY, 32 + addonY)*400.0);







            model[k] = addonx+ 32;
            model[k + 1] = addony;
            model[k + 2] = hill.get(addonX + 32, addonY)*400.0;

            color[k] = BiomeColors[biome2].r;
            color[k + 1] = BiomeColors[biome2].g;
            color[k + 2] = BiomeColors[biome2].b;


            p++;
            k = p * 3;



            model[k] = addonx + 32;
            model[k + 1] =  addony + 32;
            model[k + 2] = hill.get(addonX + 32, addonY + 32)*400.0;

            color[k] = BiomeColors[biome4].r;
            color[k + 1] = BiomeColors[biome4].g;
            color[k + 2] = BiomeColors[biome4].b;
            p++;
            k = p * 3;



            model[k] = addonx;
            model[k + 1] = addony + 32;
            model[k + 2] = hill.get(addonX, addonY + 32)*400.0;

            color[k] = BiomeColors[biome3].r;
            color[k + 1] = BiomeColors[biome3].g;
            color[k + 2] = BiomeColors[biome3].b;



            p++;
            k = p * 3;





            model[k] = addony;
            model[k + 1] = addony;
            model[k + 2] = hill.get(addonX, addonY)*400.0;

            color[k] = BiomeColors[biome1].r;
            color[k + 1] = BiomeColors[biome1].g;
            color[k + 2] = BiomeColors[biome1].b;


            p++; 
            k = p * 3;

        }
    }
}
glUnmapBuffer(GL_ARRAY_BUFFER);
glBindBuffer(GL_ARRAY_BUFFER, 0);

这是我用来绘制vbo的代码:

glBindBuffer(GL_ARRAY_BUFFER, VBO);

    glVertexPointer(3, GL_FLOAT, 0, 0);
    glTexCoordPointer(3, GL_FLOAT, 0, (char*)NULL + verts * 6 * sizeof(GLfloat));
    glColorPointer(3, GL_FLOAT, 0, (char*)NULL + verts * 3 * sizeof(GLfloat));

    glDrawArrays(GL_QUADS, 0, VBO);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

这是我想要的结果(在每个vbo中使用单个四元组):

unfortunatly I'm still new so you have to click this link :/

以下是我在每个vbo中使用多个四边形的结果:

image

那么为什么我要在一个vbo中绘制多个四边形? 一个词:性能,如果你比较两个图像真正弹出的东西(好吧,除了第二个图像的bug)是帧率计数器。我想把这个游戏变成一件大事,所以每个fps都对我很重要。

编辑: 哦,我真是太蠢了:

model[k] = addony;

一个非常简单的错误,但是如此顽固。 只是证明了如此小的东西可以制造游戏。 这一切现在都有效。

1 个答案:

答案 0 :(得分:0)

glDrawArrays(GL_QUADS, 0, VBO);

此次通话存在一些问题:

  1. glDrawArrays的第三个参数是你正在绘制的东西的数量,所以你实际上说的是:
  2. 从我的缓冲区中抽取四元组,直到VBO,然后停止。

    你应该说的是:

    从我的缓冲区中抽取四元组,直到缓冲区长度,然后停止

    所以现在它看起来像这样:

    glDrawArrays(GL_QUADS, 0, verts);
    

    &#39; VBO&#39;在您的代码中是您要使用的缓冲区的ID。 把它想象成一个你知道的指针,或者更确切地说是一个有ID的用户。

    1. GL_QUADS不是很好用GL_TRIANGLES后来GL_QUADS存在很多问题,特别是在手机和其他平台上,使你的三角形数据更好。
    2. 由于多种原因,您不应该使用GL_QUADS

      你为什么不使用VAO?您使用的是没有VAO的旧版OpenGL吗?否则我会建议在这里使用VAO而不是VBO,所以你不需要为每个绘制调用绑定指针。

      glBindBuffer(GL_ARRAY_BUFFER, verts);
      

      你在这里尝试的是绑定一个id:&#39; verts&#39;的VBO。成为我们现在的VBO。

      &#39;那么为什么我要在一个vbo中绘制多个四边形?一句话:表现&#39;

      您是否尝试使用实例绘制多个四边形? 因此,为每个形状发送模型矩阵,以便在着色器中而不是在缓冲区中修改它们的位置和形状。通过这种方式,您可以一次又一次地绘制一个vbo,只需通过一次绘制调用进行轻微转换。

      这是一个关于实例化的好教程:

      http://learnopengl.com/#!Advanced-OpenGL/Instancing

      出于好奇,但你为什么决定使用:

      glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
      

      而不是在glBufferData电话中缓冲您的数据?

      如果您以后需要缓冲数据,可以使用glBufferSubData

      老实说,虽然我认为你的表现问题源于一系列因素。

      我个人会使用glBufferData而不是地图数据,当我需要在运行期间而不是在加载期间这样做时,我会使用glBufferSubData。

      我会将颜色上传到着色器并使用不同的模型矩阵和颜色一次又一次地绘制SAME VBO的倍数,以便我实例化它。

      但是你不应该这样做。

      我建议用三角形和颜色组成数据,并将整个地面画成一个你似乎试图做的网格。您的问题很可能是由glDrawArrays长度设置为VBO的长度引起的。

      然而,在这种情况下,我将使用glBufferData构建一个VBO,其大小为块,然后我会使用glBufferSubData为每个带有颜色等的四边形。一旦我完成,我会在不同的块之间多次绘制。 / p>

      我认为你可以使用更多的OpenGL理论。