许多立方体对象的

时间:2018-01-05 20:36:55

标签: c++ opengl opengl-es

我正在构建一个渲染器,它会接收许多对象并批量渲染它们到屏幕上。完整的渲染器代码 - > https://github.com/rob-DEV/OpenGL-Model-Viewer/tree/master/OpenGL-Model-Viewer/src/graphics/renderer

在每次帧调用时将对象(所有包含索引顶点(8)和36个索引的多维数据集)推送到渲染器。     //加载模型     for(int j = 0; j< 5; j ++)     {             models.push_back(ObjModel(" test-models / box.obj",glm :: vec3(i * 5,i,j * 5)));     }

renderer.begin();

for (int i = 0; i < models.size(); i++)
{
    //add to render call
    renderer.submit(models[i]);
}

renderer.end();

renderer.flush();

渲染init()

// Enable depth test
glEnable(GL_DEPTH_TEST);
// Accept fragment if it closer to the camera than the former one
glDepthFunc(GL_LESS);

glGenVertexArrays(1, &m_VAO);
glGenBuffers(1, &m_VBO);

glBindVertexArray(m_VAO);
glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
glBufferData(GL_ARRAY_BUFFER, RENDERER_BUFFER_SIZE, NULL, GL_STATIC_DRAW);
glEnableVertexAttribArray(SHADER_VERTEX_INDEX);
glEnableVertexAttribArray(SHADER_COLOR_INDEX);
glVertexAttribPointer(SHADER_VERTEX_INDEX, 3, GL_FLOAT, GL_FALSE, RENDERER_VERTEX_SIZE, (const GLvoid*)0);
glVertexAttribPointer(SHADER_COLOR_INDEX, 4, GL_UNSIGNED_BYTE, GL_TRUE, RENDERER_VERTEX_SIZE, (const GLvoid*)(offsetof(VertexData, VertexData::colour)));
glBindBuffer(GL_ARRAY_BUFFER, 0);

//setup element
glGenBuffers(1, &m_IBO);

glBindVertexArray(0);

提交对象

void Renderer::submit(ObjModel& object)
{
    //a vector of vec3 vertices // these are indexed all objects are cubes so 8 verts per object
    std::vector<glm::vec3> vertices = object.get_vertices();
    std::vector<unsigned int> indices = object.get_indices();
    std::vector<unsigned int> colours = object.get_colours();

    //adjust the postion and give each picture a random colour & add to buffer
    for (unsigned int i = 0; i < vertices.size(); i++)
    { 
        vertices[i] += object.position;
        m_VertexBuffer->vertex = vertices[i];

        m_VertexBuffer->colour = colours[i];
        m_VertexBuffer++;
        m_VertexDataCount++;

    }
    m_IndiceCount += indices.size();
    indiceData.insert(indiceData.end(), indices.begin(), indices.end());
}

你可以看到我将每个顶点(在世界中添加位置)和颜色放入一个简单的结构(VertexData *)中,然后将索引添加到矢量中。

这是实际的抽奖

void Renderer::flush()
{
    glBindVertexArray(m_VBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_IndiceCount * sizeof(unsigned int), &indiceData[0], GL_STATIC_DRAW);

    // Draw the triangles !
    glDrawElements(
    GL_TRIANGLES,      // mode
    m_IndiceCount,    // count
    GL_UNSIGNED_INT,   // type
    (void*)0           // element array buffer offset
    );

    indiceData.clear();
    m_IndiceCount = 0;
    m_VertexDataCount = 0;
}

我意识到长度,但我的问题是,为什么这个位置只适用于第一个立方体(要么是在彼此之上绘制,要么只是第一个立方体绘制)我无法解决这个问题。我是否有更好的方法出于创意:)

1 个答案:

答案 0 :(得分:1)

  

为什么该位置仅适用于第一个多维数据集(相互之间绘制或仅绘制第一个多维数据集)

因为您只绘制了这些第一个顶点,只需几次:

  

在每次帧调用时将对象(所有包含索引顶点(8)和36个索引的多维数据集)推送到渲染器。

每次调用submit时,在顶点数组的末尾添加这8个顶点,只需将36个索引复制到索引数组的末尾:

m_IndiceCount += indices.size();
indiceData.insert(indiceData.end(), indices.begin(), indices.end());

对于第一个立方体,所有索引将在0到7的范围内,这很好。但是对于所有后续多维数据集,您还将仅使用索引0到7(因为这是仅本地对象的正确索引)。但是,第二个立方体的顶点在全局顶点数组中的索引为8到15。因此,当您一次绘制两个立方体时,它将重新绘制第一个立方体两次。

因此,应该很容易看到解决方案:您只需要将索引数组中的每个索引与全局顶点数组中顶点的实际基本偏移量进行偏移。