Beispiel #1
0
// --------------------------------------------------------------------------------------------------------------------
bool UntexturedObjectsGLDrawLoop::Init(const std::vector<UntexturedObjectsProblem::Vertex>& _vertices,
                                       const std::vector<UntexturedObjectsProblem::Index>& _indices,
                                       size_t _objectCount)
{
    if (!UntexturedObjectsSolution::Init(_vertices, _indices, _objectCount)) {
        return false;
    }

    // Program
    const char* kUniformNames[] = { "ViewProjection", nullptr };

    m_prog = CreateProgramT("cubes_gl_multi_draw_vs.glsl",
                            "cubes_gl_multi_draw_fs.glsl",
                            kUniformNames, &mUniformLocation);

    if (m_prog == 0) {
        console::warn("Unable to initialize solution '%s', shader compilation/linking failed.", GetName().c_str());
        return false;
    }

    glGenVertexArrays(1, &m_varray);
    glBindVertexArray(m_varray);

    // Buffers
    glGenBuffers(1, &m_vb);
    glBindBuffer(GL_ARRAY_BUFFER, m_vb);
    glBufferData(GL_ARRAY_BUFFER, _vertices.size() * sizeof(UntexturedObjectsProblem::Vertex), &*_vertices.begin(), GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(UntexturedObjectsProblem::Vertex), (void*) offsetof(UntexturedObjectsProblem::Vertex, pos));
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(UntexturedObjectsProblem::Vertex), (void*) offsetof(UntexturedObjectsProblem::Vertex, color));
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);

    std::vector<uint32_t> drawids(_objectCount);
    for (uint32_t i = 0; i < _objectCount; ++i) {
        drawids[i] = i;
    }

    glGenBuffers(1, &m_drawid);
    glBindBuffer(GL_ARRAY_BUFFER, m_drawid);
    glBufferData(GL_ARRAY_BUFFER, drawids.size() * sizeof(uint32_t), drawids.data(), GL_STATIC_DRAW);
    glVertexAttribIPointer(2, 1, GL_UNSIGNED_INT, sizeof(uint32_t), 0);
    glVertexAttribDivisor(2, 1);
    glEnableVertexAttribArray(2);

    glGenBuffers(1, &m_ib);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ib);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, _indices.size() * sizeof(UntexturedObjectsProblem::Index), &*_indices.begin(), GL_STATIC_DRAW);

    glGenBuffers(1, &m_transform_buffer);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_transform_buffer);

    return glGetError() == GL_NO_ERROR;
}
Beispiel #2
0
// --------------------------------------------------------------------------------------------------------------------
bool UntexturedObjectsGLBufferStorage::Init(const std::vector<UntexturedObjectsProblem::Vertex>& _vertices,
                                            const std::vector<UntexturedObjectsProblem::Index>& _indices,
                                            size_t _objectCount)
{
    if (glBufferStorage == nullptr) {
        console::warn("Unable to initialize solution '%s', glBufferStorage() unavailable.", GetName().c_str());
        return false;
    }

    if (!UntexturedObjectsSolution::Init(_vertices, _indices, _objectCount)) {
        return false;
    }

    if (mUseShaderDrawParameters && !HasExtension("GL_ARB_shader_draw_parameters")) {
        console::warn("Unable to initialize solution, ARB_shader_draw_parameters is required but not available.");
        return false;
    }

    // Program
    const char* kUniformNames[] = { "ViewProjection", nullptr };

    m_prog = CreateProgramT("cubes_gl_buffer_storage_vs.glsl",
                            "cubes_gl_buffer_storage_fs.glsl",
                            mUseShaderDrawParameters ? std::string("#define USE_SHADER_DRAW_PARAMETERS 1\n") : std::string(""),
                            kUniformNames, &mUniformLocation);

    if (m_prog == 0) {
        console::warn("Unable to initialize solution '%s', shader compilation/linking failed.", GetName().c_str());
        return false;
    }

    glGenVertexArrays(1, &m_varray);
    glBindVertexArray(m_varray);

    // Buffers
    glGenBuffers(1, &m_vb);
    glBindBuffer(GL_ARRAY_BUFFER, m_vb);
    glBufferData(GL_ARRAY_BUFFER, _vertices.size() * sizeof(UntexturedObjectsProblem::Vertex), &*_vertices.begin(), GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(UntexturedObjectsProblem::Vertex), (void*) offsetof(UntexturedObjectsProblem::Vertex, pos));
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(UntexturedObjectsProblem::Vertex), (void*) offsetof(UntexturedObjectsProblem::Vertex, color));
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);

    // If we aren't using shader draw parameters, use the workaround instead.
    if (!mUseShaderDrawParameters) {
        std::vector<uint32_t> drawids(_objectCount);
        for (uint32_t i = 0; i < _objectCount; ++i) {
            drawids[i] = i;
        }

        glGenBuffers(1, &m_drawid);
        glBindBuffer(GL_ARRAY_BUFFER, m_drawid);
        glBufferData(GL_ARRAY_BUFFER, drawids.size() * sizeof(uint32_t), drawids.data(), GL_STATIC_DRAW);
        glVertexAttribIPointer(2, 1, GL_UNSIGNED_INT, sizeof(uint32_t), 0);
        glVertexAttribDivisor(2, 1);
        glEnableVertexAttribArray(2);
    }

    glGenBuffers(1, &m_ib);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ib);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, _indices.size() * sizeof(UntexturedObjectsProblem::Index), &*_indices.begin(), GL_STATIC_DRAW);

    glGenBuffers(1, &m_transform_buffer);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_transform_buffer);
    glBufferStorage(GL_SHADER_STORAGE_BUFFER, _objectCount * 64, nullptr, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_DYNAMIC_STORAGE_BIT);
    m_transform_ptr = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, _objectCount * 64, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);

    glGenBuffers(1, &m_cmd_buffer);
    glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_cmd_buffer);
    glBufferStorage(GL_DRAW_INDIRECT_BUFFER, _objectCount * sizeof(DrawElementsIndirectCommand), nullptr, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_DYNAMIC_STORAGE_BIT);
    m_cmd_ptr = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, _objectCount * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);

    // Set the command buffer size.
    m_commands.resize(_objectCount);

    return glGetError() == GL_NO_ERROR;
}
// --------------------------------------------------------------------------------------------------------------------
bool TexturedQuadsGLSparseBindlessTextureArrayMultiDraw::Init(const std::vector<TexturedQuadsProblem::Vertex>& _vertices,
                                                              const std::vector<TexturedQuadsProblem::Index>& _indices,
                                                              const std::vector<TextureDetails*>& _textures,
                                                              size_t _objectCount)
{
    if (!TexturedQuadsSolution::Init(_vertices, _indices, _textures, _objectCount)) {
        return false;
    }

    // Prerequisites
    if (!mTexManager.Init()) {
        return false;
    }

    if (glGetTextureHandleARB == nullptr) {
        console::warn("Unable to initialize solution '%s', requires support for bindless textures (not present).", GetName().c_str());
        return false;
    }

    if (mUseShaderDrawParameters && !HasExtension(ARB_shader_draw_parameters)) {
        console::warn("Unable to initialize solution, ARB_shader_draw_parameters is required but not available.");
        return false;
    }

    // Program
    mProgram = CreateProgram("textures_gl_sparse_bindless_texture_array_multidraw_vs.glsl",
                             "textures_gl_sparse_bindless_texture_array_multidraw_fs.glsl",
                             mUseShaderDrawParameters ? std::string("#define USE_SHADER_DRAW_PARAMETERS 1\n") : std::string("")
                             );

    if (mProgram == 0) {
        console::warn("Unable to initialize solution '%s', shader compilation/linking failed.", GetName().c_str());
        return false;
    }

    // Textures
    for (auto it = _textures.begin(); it != _textures.end(); ++it) {
        mTextures.push_back(mTexManager.newTexture2DFromDetails(*it));
    }

    // Buffers
    mVertexBuffer = NewBufferFromVector(GL_ARRAY_BUFFER, _vertices, GL_STATIC_DRAW);
    mIndexBuffer = NewBufferFromVector(GL_ELEMENT_ARRAY_BUFFER, _indices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(TexturedQuadsProblem::Vertex), (void*)offsetof(TexturedQuadsProblem::Vertex, pos));
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedQuadsProblem::Vertex), (void*)offsetof(TexturedQuadsProblem::Vertex, tex));
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);

    // If we aren't using shader draw parameters, use the workaround instead.
    if (!mUseShaderDrawParameters) {
        std::vector<uint32_t> drawids(_objectCount);
        for (uint32_t i = 0; i < _objectCount; ++i) {
            drawids[i] = i;
        }

        mDrawIDBuffer = NewBufferFromVector(GL_ARRAY_BUFFER, drawids, GL_STATIC_DRAW);
        glVertexAttribIPointer(2, 1, GL_UNSIGNED_INT, sizeof(uint32_t), 0);
        glVertexAttribDivisor(2, 1);
        glEnableVertexAttribArray(2);
    }

    glGenBuffers(1, &mTransformBuffer);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, mTransformBuffer);

    auto srcIt = mTextures.cbegin();
    std::vector<TexAddress> texAddressContents(_objectCount);
    for (auto dstIt = texAddressContents.begin(); dstIt != texAddressContents.end(); ++dstIt) {
        if (srcIt == mTextures.cend()) {
            srcIt = mTextures.cbegin();
        }

        (*dstIt) = (*srcIt)->GetAddress();
        ++srcIt;
    }

    mTexAddressBuffer = NewBufferFromVector(GL_SHADER_STORAGE_BUFFER, texAddressContents, GL_DYNAMIC_DRAW);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, mTexAddressBuffer);

    mCommands.resize(_objectCount);

    return glGetError() == GL_NO_ERROR;
}
// --------------------------------------------------------------------------------------------------------------------
bool TexturedQuadsGLTextureArray::Init(const std::vector<TexturedQuadsProblem::Vertex>& _vertices,
                                       const std::vector<TexturedQuadsProblem::Index>& _indices,
                                       const std::vector<TextureDetails*>& _textures,
                                       size_t _objectCount)
{
    if (!TexturedQuadsSolution::Init(_vertices, _indices, _textures, _objectCount)) {
        return false;
    }

    // Prerequisites
    auto numTextures = _textures.size();
    if (!mTexManager.Init(false, numTextures)) {
        return false;
    }

    // Program
    const char* kUniformNames[] = { "ViewProjection", "TexContainer", nullptr };

    mProgram = CreateProgramT("textures_gl_texture_array_vs.glsl",
                              "textures_gl_texture_array_fs.glsl",
                              kUniformNames, &mUniformLocation);

    if (mProgram == 0) {
        console::warn("Unable to initialize solution '%s', shader compilation/linking failed.", GetName().c_str());
        return false;
    }

    // Textures
    for (auto it = _textures.begin(); it != _textures.end(); ++it) {
        mTextures.push_back(mTexManager.newTexture2DFromDetails(*it));
    }

    GLint lastTexId = -1;
    GLint lastTexUnit = -1;
    std::vector<DenseTexAddress> texAddress(numTextures);
    for (size_t i = 0; i < numTextures; ++i) {
        auto texture = mTextures[i];
        auto texId = texture->GetTexId();
        if (lastTexId != texId) {
            lastTexId = texId;
            lastTexUnit = (GLint) mTexUnits.size();

            glActiveTexture(GL_TEXTURE0 + lastTexUnit);
            glBindTexture(GL_TEXTURE_2D_ARRAY, texId);
            mTexUnits.push_back(lastTexUnit);
        }

        texAddress[i].m_container_index = lastTexUnit;
        texAddress[i].m_layer = ((float) texture->getSliceNum() + 0.5f) / numTextures;
    }

    std::vector<DenseTexAddress> texAddressContents(_objectCount);
    for (uint32_t i = 0; i < _objectCount; ++i) {
        texAddressContents[i] = texAddress[i % numTextures];
    }

    mTexAddressBuffer = NewBufferFromVector(GL_SHADER_STORAGE_BUFFER, texAddressContents, GL_DYNAMIC_DRAW);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, mTexAddressBuffer);

    // Buffers
    glGenVertexArrays(1, &mVertexArray);
    glBindVertexArray(mVertexArray);

    mVertexBuffer = NewBufferFromVector(GL_ARRAY_BUFFER, _vertices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(TexturedQuadsProblem::Vertex), (void*)offsetof(TexturedQuadsProblem::Vertex, pos));
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedQuadsProblem::Vertex), (void*)offsetof(TexturedQuadsProblem::Vertex, tex));
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);

    std::vector<uint32_t> drawids(_objectCount);
    for (uint32_t i = 0; i < _objectCount; ++i) {
        drawids[i] = i;
    }

    mDrawIDBuffer = NewBufferFromVector(GL_ARRAY_BUFFER, drawids, GL_STATIC_DRAW);
    glVertexAttribIPointer(2, 1, GL_UNSIGNED_INT, sizeof(uint32_t), 0);
    glVertexAttribDivisor(2, 1);
    glEnableVertexAttribArray(2);

    mIndexBuffer = NewBufferFromVector(GL_ELEMENT_ARRAY_BUFFER, _indices, GL_STATIC_DRAW);

    glGenBuffers(1, &mTransformBuffer);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, mTransformBuffer);

    return GLRenderer::GetApiError() == GL_NO_ERROR;
}