Вычислительный шейдер не записывает в буфер

Мне нужна помощь в вызове вычислительного шейдера из Qt с использованием QOpenGLFunctions_4

    computeProgram_ = new QOpenGLShaderProgram();
    computeProgram_->addShaderFromSourceFile(QOpenGLShader::Compute, "../app/shaders/pointcloud.comp");
    computeProgram_->bindAttributeLocation("Particles", 0);
    m_ParticlesLoc = 0;

    computeProgram_->link();
Core функций OpenGL.

В частности, мой вызов glDispatchCompute(1024, 1, 1);, похоже, не влияет на связанный с ним буфер. Как связать буфер с вычислительным шейдером в QT, чтобы результаты шейдера можно было прочитать обратно в C ++?

Я создаю свою программу и связываю ее с помощью (Squircle.cpp):

    computeProgram_ = new QOpenGLShaderProgram();
    computeProgram_->addShaderFromSourceFile(QOpenGLShader::Compute, "../app/shaders/pointcloud.comp");
    computeProgram_->bindAttributeLocation("Particles", 0);
    m_ParticlesLoc = 0;

    computeProgram_->link();

А затем свяжите мой QOpenGLBuffer с помощью (Squircle.cpp):

    // Setup our vertex buffer object.
    pointOpenGLBuffer_.create();
    pointOpenGLBuffer_.bind();
    pointOpenGLBuffer_.allocate(pointBuffer_.data(), pointBuffer_.vertexCount() * pointBuffer_.stride_);

Затем я вызываю вычислительный шейдер с помощью (Squircle.cpp):

computeProgram_->bind();

// ... 

pointOpenGLBuffer_.bind();

glDispatchCompute(1024, 1, 1);

Но когда я читаю свой буфер с помощью read() или map()'ing, значения никогда не меняются, это просто то, что я вставил изначально.

С точки зрения вычислительного шейдера я принимаю свой ввод с помощью (pointcloud.comp):

#version 430

layout(local_size_x = 1024) in;

struct ParticleData
{
    vec4 position;
};

// Particles from previous frame
layout (std430, binding = 0) coherent buffer Particles
{
    ParticleData particles[];
} data;

Возможно, я неправильно привязываю свой буфер? Или есть еще одна команда OpenGL, которую нужно вызвать для фактического выполнения вычислений? Я пробовал разные способы использования и т. Д.

Я разместил весь соответствующий код здесь.


person Matt    schedule 24.02.2017    source источник


Ответы (1)


Похоже, проблема в неправильном понимании привязки буфера.

pointOpenGLBuffer_.bind(); 

связывает ваш буфер только с вашим контекстом OGL, а не с буфером шейдера, его вызов дважды не поможет.

Второй раз вместо привязки нужно позвонить

glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, pointOpenGLBuffer_.bufferId());

где 0 берется из вашего макета (std430, binding = 0)

person Crazy Sage    schedule 25.02.2017
comment
Это сработало! Вчера вечером я тоже читал эту функцию, но по какой-то причине не пробовал. Я также думаю, что мое внимание привлекло то, что Format я использовал (я указываю Core4.3, но текущий буфер использует Compatibility4.5) Но да, спасибо! ~ 16 часов моих собственных усилий упустили это решение. :) - person Matt; 25.02.2017