Question

With all of my objects that are to be rendered, I use glDrawElements. However, my venture into Compute Shaders has left me a setup that uses glDrawArrays. As with many who are breaching the topic, I used this PDF as a basis. The problem is that when it is rendered, nothing appears.

#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();
}

The header contains the needed structures and other variables so they do not fall out of scope for the specific object.

Here is the compute shader itself.

#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;
}

For testing purposes I lowered the gravity. I believe that nothing is out of scope, nor is there a needed bind, but yet it alludes me to why the particles are not drawing. In addition, I also added a geometry shader that constructs a quad around each point but it did not solve anything.

Was it helpful?

Solution

Last 5 lines seems to me problematic:

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 );

My guess is You are trying to use old way of doing things in programmable pipeline.I am not sure how it is stated in OpenGL specs but it seems that in the newer versions (GL4.2) you are forced to bind your vertex buffers to VAO(may be that is vendor specific rules?).Once I needed to implement OIT and tried Cyril Crassin's demo which was using buffers with elements draw-just like you.I am using GL4.2 and NVidia cards.Nothing was showing up.I then bound them to a VAO and the issue was gone.So that is what I suggest you to try.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top