Рисование с использованием хранилища шейдеров не работает

Со всеми моими объектами, которые должны быть отображены, я использую glDrawElements. Тем не менее, мое предприятие в Compute Shaders оставило мне установку, которая использует glDrawArrays. Как и многие, кто нарушает тему, я использовал этот PDF в качестве основы. Проблема в том, что когда он отображается, ничего не появляется.

#include "LogoTail.h"

LogoTail::LogoTail(int tag1) {
    tag = tag1;
    needLoad = false;
    shader = LoadShaders("vertex-shader[LogoTail].txt","fragment-shader[LogoTail].txt");
    shaderCompute = LoadShaders("compute-shader[LogoTail].txt");

    for( int i = 0; i < NUM_PARTICLES; i++ )
    {
        points[ i ].x = 0.0f;
        points[ i ].y = 0.0f;
        points[ i ].z = 0.0f;
        points[ i ].w = 1.0f;
    }

    glGenBuffers( 1, &posSSbo);
    glBindBuffer( GL_SHADER_STORAGE_BUFFER, posSSbo );
    glBufferData( GL_SHADER_STORAGE_BUFFER, sizeof(points), points, GL_STATIC_DRAW );
    glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);

    for( int i = 0; i < NUM_PARTICLES; i++ )
    {
        times[ i ].x = 0.0f;
    }

    glGenBuffers( 1, &birthSSbo);
    glBindBuffer( GL_SHADER_STORAGE_BUFFER, birthSSbo );
    glBufferData( GL_SHADER_STORAGE_BUFFER, sizeof(times), times, GL_STATIC_DRAW );
    glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);

    for( int i = 0; i < NUM_PARTICLES; i++ )
    {
        vels[ i ].vx = 0.0f;
        vels[ i ].vy = 0.0f;
        vels[ i ].vz = 0.0f;
        vels[ i ].vw = 0.0f;
    }

    glGenBuffers( 1, &velSSbo );
    glBindBuffer( GL_SHADER_STORAGE_BUFFER, velSSbo );
    glBufferData( GL_SHADER_STORAGE_BUFFER, sizeof(vels), vels, GL_STATIC_DRAW );
    glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
}

void LogoTail::Update(const double dt, float sunTime,glm::vec3 sunN) {
    position=glm::translate(glm::mat4(), glm::vec3(4.5f,0,0));
}

void LogoTail::Draw(shading::Camera& camera){
    shaderCompute->use();
    glBindBufferBase( GL_SHADER_STORAGE_BUFFER, 4, posSSbo );
    glBindBufferBase( GL_SHADER_STORAGE_BUFFER, 5, velSSbo );
    glBindBufferBase( GL_SHADER_STORAGE_BUFFER, 6, birthSSbo );

    glDispatchCompute( NUM_PARTICLES / WORK_GROUP_SIZE, 1, 1 );
    glMemoryBarrier( GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT );

    shaderCompute->stopUsing();
    shader->use();

    shader->setUniform("camera", camera.matrix());
    shader->setUniform("model",position);   

    glBindBuffer( GL_ARRAY_BUFFER, posSSbo );
    glVertexPointer( 4, GL_FLOAT, 0, (void *)0 );
    glEnableClientState( GL_VERTEX_ARRAY );
    glDrawArrays( GL_POINTS, 0, NUM_PARTICLES );
    glDisableClientState( GL_VERTEX_ARRAY );
    glBindBuffer( GL_ARRAY_BUFFER, 0 );
    shader->stopUsing();
}

Заголовок содержит необходимые структуры и другие переменные, поэтому они не выходят за рамки конкретного объекта.

Вот и сам вычислительный шейдер.

#version 430 core
#extension GL_ARB_compute_shader : enable
#extension GL_ARB_shader_storage_buffer_object : enable

layout( std140, binding=4 ) buffer Pos 
{
    vec4 Positions[ ]; // array of vec4 structures
};
layout( std140, binding=5 ) buffer Vel 
{
    vec4 Velocities[ ]; // array of vec4 structures
};
layout( std140, binding=6 ) buffer Tim
{
    float BirthTimes[ ]; // array of structures
};

layout( local_size_x = 128, local_size_y = 1, local_size_z = 1 ) in;

const vec3 G = vec3( 0., -0.2, 0. );
const float DT = 0.016666;

void main() {
    uint gid = gl_GlobalInvocationID.x; // the .y and .z are both 1
    vec3 p = Positions[ gid ].xyz;
    vec3 v = Velocities[ gid ].xyz;
    vec3 pp = p + v*DT + .5*DT*DT*G;
    vec3 vp = v + G*DT;
    Positions[ gid ].xyz = pp;
    Velocities[ gid ].xyz = vp;
}

В целях тестирования я снизил гравитацию. Я полагаю, что ничто не выходит за рамки, и при этом нет никакой необходимой связи, но все же это намекает мне на то, почему частицы не тянут. Кроме того, я также добавил геометрический шейдер, который строит четырехугольник вокруг каждой точки, но это ничего не решает.

1 ответ

Решение

Последние 5 строк мне кажутся проблемными:

glBindBuffer( GL_ARRAY_BUFFER, posSSbo );
glVertexPointer( 4, GL_FLOAT, 0, (void *)0 );
glEnableClientState( GL_VERTEX_ARRAY );
glDrawArrays( GL_POINTS, 0, NUM_PARTICLES );
glDisableClientState( GL_VERTEX_ARRAY );
glBindBuffer( GL_ARRAY_BUFFER, 0 );

Я предполагаю, что вы пытаетесь использовать старый способ работы в программируемом конвейере. Я не уверен, как это указано в спецификациях OpenGL, но кажется, что в более новых версиях (GL4.2) вы вынуждены привязывать свои вершинные буферы к VAO(может быть, это правила конкретного поставщика?). Однажды мне нужно было реализовать OIT и попробовать демо Cyril Crassin, в котором использовались буферы с элементами draw- как у вас. Я использую карты GL4.2 и NVidia. Ничего не появлялось. Затем я связал их с VAO, и проблема исчезла. Вот что я предлагаю вам попробовать.

Другие вопросы по тегам