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