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