AnsweredAssumed Answered

OpenGL SSBO not working

Question asked by rodrigoloc on Jul 15, 2014

I'm trying to use SSBO but it looks like they don't work. I don't know if it's my fault or driver's fault (I'm using Catalyst 14.4).

 

 

Here's application side:

GLuint nBuffer;
glGenBuffers(1, &nBuffer);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, nBuffer);
GLfloat mfParameters[] = { 640.f, 480.f };
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(mfParameters), mfParameters, GL_STATIC_DRAW);
GLint nBinding = 7;
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, nBinding, nBuffer);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);



 

And here's GLSL code:

layout (binding = 7, std430) buffer Window
{
    vec2 vSize;
} u_Window;



 

When I try to get the data from GLSL I get zeros:

// Fragment shader:

// It's always true.
if (0.f == u_Window.vSize.x)
{
     return vec4(1.f, 0.f, 0.f, 1.f);
}



 

It's OpenGL 4.4 core profile and GLSL 4.4 core.

 

 

Edit: Here's a full example:

#include <cstdio>
#include <cstdlib>
#include <cstring>

#include <GL/glew.h>

#include <SDL2/SDL.h>

#include <glm/glm.hpp>
#include <glm/ext.hpp>



SDL_Window *g_pWindow;
SDL_GLContext g_Context;
SDL_Renderer *g_pRenderer;

GLuint g_iWorld_Pipeline;
GLuint g_iWorld_VS;
GLuint g_iWorld_FS;

GLuint g_iProjectionMatrix;
GLuint g_iViewMatrix;

GLuint g_iWorld_Geometry;
GLuint g_iWorld_VAO;

const GLchar *g_szWorld_VS_Source =
    "#version 440 core\n"
    "layout (location = 0) in vec3 in_vVertex;"
    "layout (location = 0) out gl_PerVertex {"
    "    vec4 gl_Position;"
    "};"
    "layout (std430, binding = 0) buffer Projection { mat4 u_mProjection; };"
    "layout (std140, binding = 1) uniform View { mat4 u_mView; };"
    "void main() {"
    "    gl_Position = u_mProjection * u_mView * vec4(in_vVertex, 1.0f);"
    "}";
const GLchar *g_szWorld_FS_Source =
    "#version 440 core\n"
    "layout (location = 0) out vec4 out_vColor;"
    "void main() {"
    "    out_vColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);"
    "}";

const GLfloat g_mfWorld_Geometry[] =
{
    -1.0f, -1.0f, 0.0f, 1.0f,
    0.0f, 1.0f, 0.0f, 1.0f,
    1.0f, -1.0f, 0.0f, 1.0f
};


void init_window()
{
    if (SDL_Init(SDL_INIT_VIDEO) < 0)
    {
        fprintf(stderr, "SDL error: %s\n", SDL_GetError());
        exit(1);
    }

    g_pWindow = SDL_CreateWindow("Test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
        640, 480, SDL_WINDOW_OPENGL);
    g_Context = SDL_GL_CreateContext(g_pWindow);

    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);

    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, SDL_TRUE);

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 4);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);

    g_pRenderer = SDL_CreateRenderer(g_pWindow, -1, 0);

    SDL_GL_SetSwapInterval(SDL_TRUE);
}


void init_gl()
{
    glewExperimental = 1;
    glewInit();
    while (glGetError());


    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);

    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
}


void init_shaders()
{
    g_iWorld_VS = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &g_szWorld_VS_Source);
    g_iWorld_FS = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &g_szWorld_FS_Source);

    glGenProgramPipelines(1, &g_iWorld_Pipeline);
    glBindProgramPipeline(g_iWorld_Pipeline);

    glUseProgramStages(g_iWorld_Pipeline, GL_VERTEX_SHADER_BIT, g_iWorld_VS);
    glUseProgramStages(g_iWorld_Pipeline, GL_FRAGMENT_SHADER_BIT, g_iWorld_FS);
}


void load_matrices()
{
    glm::mat4 ProjectionMatrix = glm::frustum(-1.33f, 1.33f, -1.0f, 1.0f, 1.0f, 100.0f);

    glm::vec3 vEye(0.0f, 0.0f, -8.0f);
    glm::vec3 vCenter(0.0f, 0.0f, 0.0f);
    glm::vec3 vUp(0.0f, 1.0f, 0.0f);
    glm::mat4 ViewMatix = glm::lookAt(vEye, vCenter, vUp);

    GLuint miBuffers[2];
    glGenBuffers(2, miBuffers);
    g_iProjectionMatrix = miBuffers[0];
    g_iViewMatrix = miBuffers[1];

    glBindBuffer(GL_SHADER_STORAGE_BUFFER, g_iProjectionMatrix);
    glBufferData(GL_SHADER_STORAGE_BUFFER, 4 * 4 * sizeof(GLfloat), glm::value_ptr(ProjectionMatrix), GL_STATIC_DRAW);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
  
    glBindBuffer(GL_UNIFORM_BUFFER, g_iViewMatrix);
    glBufferData(GL_UNIFORM_BUFFER, 4 * 4 * sizeof(GLfloat), glm::value_ptr(ViewMatix), GL_STATIC_DRAW);
    glBindBuffer(GL_UNIFORM_BUFFER, 0);

    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, g_iProjectionMatrix);
    glBindBufferBase(GL_UNIFORM_BUFFER, 1, g_iViewMatrix);
}


void init_world_geometry()
{
    glGenBuffers(1, &g_iWorld_Geometry);
    glBindBuffer(GL_ARRAY_BUFFER, g_iWorld_Geometry);
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_mfWorld_Geometry), g_mfWorld_Geometry, GL_STATIC_DRAW);

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

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);


    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}


int main(int argc, char **argv)
{
    init_window();
    init_gl();

    init_shaders();
    load_matrices();

    init_world_geometry();

    bool bKeepRunning = true;
    while (bKeepRunning)
    {
        SDL_Event Event;
        while (SDL_PollEvent(&Event))
        {
            switch (Event.type)
            {
                case SDL_QUIT:
                    bKeepRunning = false;
                    break;
            }
        }

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glBindVertexArray(g_iWorld_VAO);
        glDrawArrays(GL_TRIANGLES, 0, 3);

        SDL_GL_SwapWindow(g_pWindow);
    }

    return 0;
}



Outcomes