2016-07-03 7 views
1

Я работаю над маленькой системой частиц с использованием OpenGL.
Проблема в том, что обновление позиций в вычислительном шейдере не работает.Запись SSBO не видна

Вот код:

  1. Буферы

    struct ParticleInfo { 
    
        Vec4f position; // w: s coordinate 
        Vec4f normal; // w: t coordinate 
        float materialIndex; 
        Vec3f oldPosition; 
    
    }; 
    
  2. Init буферы

    glGenVertexArrays(1, &mParticleVAO); 
    glBindVertexArray(mParticleVAO); 
    
    glGenBuffers(1, &mParticleVBO); 
    glBindBuffer(GL_ARRAY_BUFFER, mParticleVBO); 
    
    glBufferData(GL_ARRAY_BUFFER, sizeof(ParticleInfo) * mNumParticles, particleData.data(), GL_STATIC_DRAW); 
    
    glEnableVertexAttribArray(0); 
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(ParticleInfo), (void*)NULL); 
    
    glEnableVertexAttribArray(1); 
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(ParticleInfo), (void*)(NULL + sizeof(Vec4f))); 
    
    glEnableVertexAttribArray(2); 
    glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleInfo), (void*)(NULL + 2*sizeof(Vec4f))); 
    
    glBindBuffer(GL_ARRAY_BUFFER, 0); 
    glBindVertexArray(0); 
    
  3. обновление буферов с Compute Shader

     gl->setUniform(mParticleMoveProgram->getUniformLoc("numParticles"), mNumParticles); 
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, mParticleVBO); 
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, mAttractorSSBO); 
    
    int localSizeX = 64*8; 
    
    int groupSizeX = (mNumParticles + localSizeX - 1)/localSizeX; 
    
    glDispatchCompute(groupSizeX, 1, 1); 
    glMemoryBarrier(GL_ALL_BARRIER_BITS); 
    
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0); 
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, 0); 
    
  4. шейдер код

    #version 450 
    
    layout(local_size_x = 64) in; 
    
    struct ParticleInfo { 
    
        vec4 position; // modify only the position; 
        vec4 normal; 
        float materialIndex; 
        vec3 oldPosition; 
    
    }; 
    
    struct Attractor { 
    
        vec3 position; 
        float mass; 
    
    }; 
    
    layout(binding = 0, std430) buffer ParticleArray { 
    
        ParticleInfo particles[]; 
    
    }; 
    
    layout(binding = 1, std430) buffer AttractorArray { 
    
        Attractor attractors[]; 
    
    }; 
    
    uniform int numParticles; 
    
    
    vec3 verlet(in vec3 a, in vec3 x, in vec3 xOld, in float dt) { 
    
        return 2.0 * x - xOld + a * dt*dt; 
    
    } 
    
    void main() { 
    
        const int PARTICLES_PER_THREAD = 8; 
    
        int index = int(gl_LocalInvocationIndex)*PARTICLES_PER_THREAD; 
    
        if (index >= numParticles) return; 
    
        Attractor attr = attractors[0]; 
    
        const float G = 9.8; 
    
        for (int i = 0; i < PARTICLES_PER_THREAD; ++i) 
        { 
    
    
         particles[i+index].position = vec4(0.0); 
         particles[i+index].normal = vec4(0.0); 
         particles[i+index].oldPosition = vec3(0.0); 
        } 
    
    
    
    } 
    
+0

Не работает: Я имею в виду, что частицы остаются в том же начальном положении, где я хотел бы установить все их в положение 0. –

+0

Откуда вы знаете, что они находятся в одном положении? Вы это делаете и не видите, что они двигаются? –

+0

Частицы напоминают определенную форму. Все они отбираются из треугольников в некоторой сетке. –

ответ

1

Это как @derhass прокомментировал. Структура памяти не совпала. Казалось, что также существует проблема с правильным индексированием на поток. Я установил его, установив индекс на нить как:

index = PARTICLES_PER_THREAD * int(gl_WorkGroupSize.x * gl_WorkGroupID.x + gl_LocalInvocationID.x); 

Спасибо за помощь.