Make a shader storage buffer in different shader programs accessiblePyOpenGL - passing transformation matrix into shaderOpenGL ES 2.0 Failing to correctly assign the color attributeD3D11 Writing to buffer in geometry shaderOpenGL shader not passing variable from vertex to fragment shaderUsing glClear() when there are multiple shader programsRandom coloured blocksModifying a Shader Storage Buffer Object from within a Vertex Shaderlibgdx: mesh color not making it to vertex shaderHow does OpenGL differentiate binding points in VAO from ones defined with glBindBufferBase?Can I use different shader programs for the same rendering job?
Character is called by their first initial. How do I write it?
What does "a good player" mean in the movie Training day?
What was the rationale behind 36 bit computer architectures?
Commercial jet accompanied by small plane near Seattle
kids pooling money for Lego League and taxes
How do we explain the E major chord in this progression?
Memory capability and powers of 2
How to copy a file transactionally?
Other than a swing wing, what types of variable geometry have flown?
How can I make sure my players' decisions have consequences?
Explanation for a joke about a three-legged dog that walks into a bar
Is it normal practice to screen share with a client?
How can I receive packages while in France?
What should I say when a company asks you why someone (a friend) who was fired left?
Why no ";" after "do" in sh loops?
Why are off grid solar setups only 12, 24, 48 VDC?
Short story where man sells a baseball stadium
A planet illuminated by a black hole?
How can I tell if there was a power cut while I was out?
What do I do when a student working in my lab "ghosts" me?
Is it better to memorize verb's 1st person perfect tense?
(1 of 11: Numberlink) What is Pyramid Cult's Favorite Activity?
Where to place an artificial gland in the human body?
This message is flooding my syslog, how to find where it comes from?
Make a shader storage buffer in different shader programs accessible
PyOpenGL - passing transformation matrix into shaderOpenGL ES 2.0 Failing to correctly assign the color attributeD3D11 Writing to buffer in geometry shaderOpenGL shader not passing variable from vertex to fragment shaderUsing glClear() when there are multiple shader programsRandom coloured blocksModifying a Shader Storage Buffer Object from within a Vertex Shaderlibgdx: mesh color not making it to vertex shaderHow does OpenGL differentiate binding points in VAO from ones defined with glBindBufferBase?Can I use different shader programs for the same rendering job?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
What layout and binding do i have to do to make a (working) shader storage buffer readable in a second shader program?
I set up and populated a SSBO which i bound successfully and used in a geometry shader. That shader reads and writes to that SSBO - no problems so far. No rendering done there.
In the next step, my rendering pass (second shader program) shall have access to this data. The idea is to have a big data set while the vertex shader of the second program only uses some indices per render call to pick certain values of that SSBO.
Do i miss some specific binding commands or did i place them at the wrong spot?
Is the layout consistent in both programs? Did i mess up the instances?
I just can't find any examples of a SSBO used in two programs..
Creating, populating and binding:
float data[48000];
data[0] = -1.0;
data[1] = 1.0;
data[2] = -1.0;
data[3] = -1.0;
data[4] = 1.0;
data[5] = -1.0;
data[6] = 1.0;
data[7] = 1.0;
data[16000] = 0.0;
data[16001] = 1.0;
data[16002] = 0.0;
data[16003] = 0.0;
data[16004] = 1.0;
data[16005] = 0.0;
data[16006] = 1.0;
data[16007] = 1.0;
GLuint ssbo;
glGenBuffers(1, &ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), &data, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ssbo);
Instancing in geometry shader
layout(std140, binding = 1) buffer mesh
vec2 points[8000];
vec2 texs[8000];
vec4 colors_and_errors[8000];
mesh_data;
Second instance in the vertex shader of the other program
layout(std140, binding = 1) buffer mesh
vec2 points[8000];
vec2 texs[8000];
vec4 colors_and_errors[8000];
mesh_data;
Are the instances working against each other?
Right now am not posting my bindings done in the render loop since i am not sure what i am doing there. I tried to bind before/ after changing the used program; without success.
Does anybody have an idea?
EDIT: Do i also have to bind the SSBO to the second program outside of the render loop? In a different way than the first binding?
EDIT: Although i did not solve this particular problem, i found a work-around that might be even more in the sense of opengl.
I used the SSBO of the first program as vertex attributes in the second program. This and the indexed-rendering function of opengl solved this issue.
(Should this be marked as solved?)
opengl glsl shader shader-storage-buffer
add a comment |
What layout and binding do i have to do to make a (working) shader storage buffer readable in a second shader program?
I set up and populated a SSBO which i bound successfully and used in a geometry shader. That shader reads and writes to that SSBO - no problems so far. No rendering done there.
In the next step, my rendering pass (second shader program) shall have access to this data. The idea is to have a big data set while the vertex shader of the second program only uses some indices per render call to pick certain values of that SSBO.
Do i miss some specific binding commands or did i place them at the wrong spot?
Is the layout consistent in both programs? Did i mess up the instances?
I just can't find any examples of a SSBO used in two programs..
Creating, populating and binding:
float data[48000];
data[0] = -1.0;
data[1] = 1.0;
data[2] = -1.0;
data[3] = -1.0;
data[4] = 1.0;
data[5] = -1.0;
data[6] = 1.0;
data[7] = 1.0;
data[16000] = 0.0;
data[16001] = 1.0;
data[16002] = 0.0;
data[16003] = 0.0;
data[16004] = 1.0;
data[16005] = 0.0;
data[16006] = 1.0;
data[16007] = 1.0;
GLuint ssbo;
glGenBuffers(1, &ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), &data, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ssbo);
Instancing in geometry shader
layout(std140, binding = 1) buffer mesh
vec2 points[8000];
vec2 texs[8000];
vec4 colors_and_errors[8000];
mesh_data;
Second instance in the vertex shader of the other program
layout(std140, binding = 1) buffer mesh
vec2 points[8000];
vec2 texs[8000];
vec4 colors_and_errors[8000];
mesh_data;
Are the instances working against each other?
Right now am not posting my bindings done in the render loop since i am not sure what i am doing there. I tried to bind before/ after changing the used program; without success.
Does anybody have an idea?
EDIT: Do i also have to bind the SSBO to the second program outside of the render loop? In a different way than the first binding?
EDIT: Although i did not solve this particular problem, i found a work-around that might be even more in the sense of opengl.
I used the SSBO of the first program as vertex attributes in the second program. This and the indexed-rendering function of opengl solved this issue.
(Should this be marked as solved?)
opengl glsl shader shader-storage-buffer
add a comment |
What layout and binding do i have to do to make a (working) shader storage buffer readable in a second shader program?
I set up and populated a SSBO which i bound successfully and used in a geometry shader. That shader reads and writes to that SSBO - no problems so far. No rendering done there.
In the next step, my rendering pass (second shader program) shall have access to this data. The idea is to have a big data set while the vertex shader of the second program only uses some indices per render call to pick certain values of that SSBO.
Do i miss some specific binding commands or did i place them at the wrong spot?
Is the layout consistent in both programs? Did i mess up the instances?
I just can't find any examples of a SSBO used in two programs..
Creating, populating and binding:
float data[48000];
data[0] = -1.0;
data[1] = 1.0;
data[2] = -1.0;
data[3] = -1.0;
data[4] = 1.0;
data[5] = -1.0;
data[6] = 1.0;
data[7] = 1.0;
data[16000] = 0.0;
data[16001] = 1.0;
data[16002] = 0.0;
data[16003] = 0.0;
data[16004] = 1.0;
data[16005] = 0.0;
data[16006] = 1.0;
data[16007] = 1.0;
GLuint ssbo;
glGenBuffers(1, &ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), &data, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ssbo);
Instancing in geometry shader
layout(std140, binding = 1) buffer mesh
vec2 points[8000];
vec2 texs[8000];
vec4 colors_and_errors[8000];
mesh_data;
Second instance in the vertex shader of the other program
layout(std140, binding = 1) buffer mesh
vec2 points[8000];
vec2 texs[8000];
vec4 colors_and_errors[8000];
mesh_data;
Are the instances working against each other?
Right now am not posting my bindings done in the render loop since i am not sure what i am doing there. I tried to bind before/ after changing the used program; without success.
Does anybody have an idea?
EDIT: Do i also have to bind the SSBO to the second program outside of the render loop? In a different way than the first binding?
EDIT: Although i did not solve this particular problem, i found a work-around that might be even more in the sense of opengl.
I used the SSBO of the first program as vertex attributes in the second program. This and the indexed-rendering function of opengl solved this issue.
(Should this be marked as solved?)
opengl glsl shader shader-storage-buffer
What layout and binding do i have to do to make a (working) shader storage buffer readable in a second shader program?
I set up and populated a SSBO which i bound successfully and used in a geometry shader. That shader reads and writes to that SSBO - no problems so far. No rendering done there.
In the next step, my rendering pass (second shader program) shall have access to this data. The idea is to have a big data set while the vertex shader of the second program only uses some indices per render call to pick certain values of that SSBO.
Do i miss some specific binding commands or did i place them at the wrong spot?
Is the layout consistent in both programs? Did i mess up the instances?
I just can't find any examples of a SSBO used in two programs..
Creating, populating and binding:
float data[48000];
data[0] = -1.0;
data[1] = 1.0;
data[2] = -1.0;
data[3] = -1.0;
data[4] = 1.0;
data[5] = -1.0;
data[6] = 1.0;
data[7] = 1.0;
data[16000] = 0.0;
data[16001] = 1.0;
data[16002] = 0.0;
data[16003] = 0.0;
data[16004] = 1.0;
data[16005] = 0.0;
data[16006] = 1.0;
data[16007] = 1.0;
GLuint ssbo;
glGenBuffers(1, &ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), &data, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ssbo);
Instancing in geometry shader
layout(std140, binding = 1) buffer mesh
vec2 points[8000];
vec2 texs[8000];
vec4 colors_and_errors[8000];
mesh_data;
Second instance in the vertex shader of the other program
layout(std140, binding = 1) buffer mesh
vec2 points[8000];
vec2 texs[8000];
vec4 colors_and_errors[8000];
mesh_data;
Are the instances working against each other?
Right now am not posting my bindings done in the render loop since i am not sure what i am doing there. I tried to bind before/ after changing the used program; without success.
Does anybody have an idea?
EDIT: Do i also have to bind the SSBO to the second program outside of the render loop? In a different way than the first binding?
EDIT: Although i did not solve this particular problem, i found a work-around that might be even more in the sense of opengl.
I used the SSBO of the first program as vertex attributes in the second program. This and the indexed-rendering function of opengl solved this issue.
(Should this be marked as solved?)
opengl glsl shader shader-storage-buffer
opengl glsl shader shader-storage-buffer
edited Mar 26 at 16:32
prox
asked Mar 14 at 17:57
proxprox
13 bronze badges
13 bronze badges
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
It seems like you're most of the way there, but there are a few things you should watch out for.
Is the layout consistent in both programs?
layout(std140, binding = 1) buffer mesh
You need to be careful about this layout. std140 will round up alignments to vec4, so will no longer line up with the data you're providing from the C code. In this case, std430 should work for you.
Do i also have to bind the SSBO to the second program outside of the render loop? In a different way than the first binding?
Once you've bound the SSBO once, assuming both programs are using the same binding point (in your example, they are) then you should be fine. Sharing data between programs is fine, but synchronisation is required. You can enforce this with a memory barrier.
You don't mention VAOs, but you will only be able to use SSBOs after you've bound a VAO (not on the default one).
I think this might be best explained with an example.
Vertex shader for the first program. It uses the buffer data for its position and texture coords and then flips the positions in Y.
layout(std430, binding = 1) buffer mesh
vec4 points[3];
vec2 texs[3];
mesh_data;
out highp vec2 coords;
void main()
coords = mesh_data.texs[gl_VertexID];
gl_Position = mesh_data.points[gl_VertexID];
mesh_data.points[gl_VertexID] = vec4(gl_Position.x, -gl_Position.y, gl_Position.zw);
Verted shader for the second program. It just uses the data but doesn't modify it.
layout(std430, binding = 1) buffer mesh
vec4 points[3];
vec2 texs[3];
mesh_data;
out highp vec2 coords;
void main()
coords = mesh_data.texs[gl_VertexID];
gl_Position = mesh_data.points[gl_VertexID];
In the application, you need to bind a VAO.
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
Then setup your SSBO.
float const data[] =
-0.5f, -0.5f, 0.0f, 1.0,
0.0f, 0.5f, 0.0f, 1.0,
0.5f, -0.5f, 0.0f, 1.0,
0.0f, 0.0f,
0.5f, 1.0f,
1.0f, 0.0f
;
glGenBuffers(1, &ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ssbo);
Make the draw calls using the first program.
glUseProgram(first_program);
glDrawArrays(GL_TRIANGLES, 0, 3);
Insert a memory barrier to ensure the writes complete from the preceding draw call before the next draw call tries to read from the buffer.
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
Make the draw calls using the second program.
glUseProgram(second_program);
glDrawArrays(GL_TRIANGLES, 0, 3);
I hope that clarifies things! Let me know if you have any further questions.
Thank you for answering! I tried three layouts: std140, std430 and shared. Also i already used glMemoryBarrier and a separate VAO. Still not working. I found a work-around though, see 2nd edit.
– prox
Mar 26 at 16:27
Sorry to hear this didn't work for you. It works for me locally, so whilst I'm glad you've found a work around, I don't think the question should be marked as resolved, as the original question hasn't been solved. I take it glGetError is returning GL_NO_ERROR?
– Laurie
Mar 26 at 22:58
Yes, no error so far. Only some usage hints concerning the use of the storage buffers.
– prox
Mar 31 at 18:17
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55169145%2fmake-a-shader-storage-buffer-in-different-shader-programs-accessible%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
It seems like you're most of the way there, but there are a few things you should watch out for.
Is the layout consistent in both programs?
layout(std140, binding = 1) buffer mesh
You need to be careful about this layout. std140 will round up alignments to vec4, so will no longer line up with the data you're providing from the C code. In this case, std430 should work for you.
Do i also have to bind the SSBO to the second program outside of the render loop? In a different way than the first binding?
Once you've bound the SSBO once, assuming both programs are using the same binding point (in your example, they are) then you should be fine. Sharing data between programs is fine, but synchronisation is required. You can enforce this with a memory barrier.
You don't mention VAOs, but you will only be able to use SSBOs after you've bound a VAO (not on the default one).
I think this might be best explained with an example.
Vertex shader for the first program. It uses the buffer data for its position and texture coords and then flips the positions in Y.
layout(std430, binding = 1) buffer mesh
vec4 points[3];
vec2 texs[3];
mesh_data;
out highp vec2 coords;
void main()
coords = mesh_data.texs[gl_VertexID];
gl_Position = mesh_data.points[gl_VertexID];
mesh_data.points[gl_VertexID] = vec4(gl_Position.x, -gl_Position.y, gl_Position.zw);
Verted shader for the second program. It just uses the data but doesn't modify it.
layout(std430, binding = 1) buffer mesh
vec4 points[3];
vec2 texs[3];
mesh_data;
out highp vec2 coords;
void main()
coords = mesh_data.texs[gl_VertexID];
gl_Position = mesh_data.points[gl_VertexID];
In the application, you need to bind a VAO.
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
Then setup your SSBO.
float const data[] =
-0.5f, -0.5f, 0.0f, 1.0,
0.0f, 0.5f, 0.0f, 1.0,
0.5f, -0.5f, 0.0f, 1.0,
0.0f, 0.0f,
0.5f, 1.0f,
1.0f, 0.0f
;
glGenBuffers(1, &ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ssbo);
Make the draw calls using the first program.
glUseProgram(first_program);
glDrawArrays(GL_TRIANGLES, 0, 3);
Insert a memory barrier to ensure the writes complete from the preceding draw call before the next draw call tries to read from the buffer.
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
Make the draw calls using the second program.
glUseProgram(second_program);
glDrawArrays(GL_TRIANGLES, 0, 3);
I hope that clarifies things! Let me know if you have any further questions.
Thank you for answering! I tried three layouts: std140, std430 and shared. Also i already used glMemoryBarrier and a separate VAO. Still not working. I found a work-around though, see 2nd edit.
– prox
Mar 26 at 16:27
Sorry to hear this didn't work for you. It works for me locally, so whilst I'm glad you've found a work around, I don't think the question should be marked as resolved, as the original question hasn't been solved. I take it glGetError is returning GL_NO_ERROR?
– Laurie
Mar 26 at 22:58
Yes, no error so far. Only some usage hints concerning the use of the storage buffers.
– prox
Mar 31 at 18:17
add a comment |
It seems like you're most of the way there, but there are a few things you should watch out for.
Is the layout consistent in both programs?
layout(std140, binding = 1) buffer mesh
You need to be careful about this layout. std140 will round up alignments to vec4, so will no longer line up with the data you're providing from the C code. In this case, std430 should work for you.
Do i also have to bind the SSBO to the second program outside of the render loop? In a different way than the first binding?
Once you've bound the SSBO once, assuming both programs are using the same binding point (in your example, they are) then you should be fine. Sharing data between programs is fine, but synchronisation is required. You can enforce this with a memory barrier.
You don't mention VAOs, but you will only be able to use SSBOs after you've bound a VAO (not on the default one).
I think this might be best explained with an example.
Vertex shader for the first program. It uses the buffer data for its position and texture coords and then flips the positions in Y.
layout(std430, binding = 1) buffer mesh
vec4 points[3];
vec2 texs[3];
mesh_data;
out highp vec2 coords;
void main()
coords = mesh_data.texs[gl_VertexID];
gl_Position = mesh_data.points[gl_VertexID];
mesh_data.points[gl_VertexID] = vec4(gl_Position.x, -gl_Position.y, gl_Position.zw);
Verted shader for the second program. It just uses the data but doesn't modify it.
layout(std430, binding = 1) buffer mesh
vec4 points[3];
vec2 texs[3];
mesh_data;
out highp vec2 coords;
void main()
coords = mesh_data.texs[gl_VertexID];
gl_Position = mesh_data.points[gl_VertexID];
In the application, you need to bind a VAO.
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
Then setup your SSBO.
float const data[] =
-0.5f, -0.5f, 0.0f, 1.0,
0.0f, 0.5f, 0.0f, 1.0,
0.5f, -0.5f, 0.0f, 1.0,
0.0f, 0.0f,
0.5f, 1.0f,
1.0f, 0.0f
;
glGenBuffers(1, &ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ssbo);
Make the draw calls using the first program.
glUseProgram(first_program);
glDrawArrays(GL_TRIANGLES, 0, 3);
Insert a memory barrier to ensure the writes complete from the preceding draw call before the next draw call tries to read from the buffer.
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
Make the draw calls using the second program.
glUseProgram(second_program);
glDrawArrays(GL_TRIANGLES, 0, 3);
I hope that clarifies things! Let me know if you have any further questions.
Thank you for answering! I tried three layouts: std140, std430 and shared. Also i already used glMemoryBarrier and a separate VAO. Still not working. I found a work-around though, see 2nd edit.
– prox
Mar 26 at 16:27
Sorry to hear this didn't work for you. It works for me locally, so whilst I'm glad you've found a work around, I don't think the question should be marked as resolved, as the original question hasn't been solved. I take it glGetError is returning GL_NO_ERROR?
– Laurie
Mar 26 at 22:58
Yes, no error so far. Only some usage hints concerning the use of the storage buffers.
– prox
Mar 31 at 18:17
add a comment |
It seems like you're most of the way there, but there are a few things you should watch out for.
Is the layout consistent in both programs?
layout(std140, binding = 1) buffer mesh
You need to be careful about this layout. std140 will round up alignments to vec4, so will no longer line up with the data you're providing from the C code. In this case, std430 should work for you.
Do i also have to bind the SSBO to the second program outside of the render loop? In a different way than the first binding?
Once you've bound the SSBO once, assuming both programs are using the same binding point (in your example, they are) then you should be fine. Sharing data between programs is fine, but synchronisation is required. You can enforce this with a memory barrier.
You don't mention VAOs, but you will only be able to use SSBOs after you've bound a VAO (not on the default one).
I think this might be best explained with an example.
Vertex shader for the first program. It uses the buffer data for its position and texture coords and then flips the positions in Y.
layout(std430, binding = 1) buffer mesh
vec4 points[3];
vec2 texs[3];
mesh_data;
out highp vec2 coords;
void main()
coords = mesh_data.texs[gl_VertexID];
gl_Position = mesh_data.points[gl_VertexID];
mesh_data.points[gl_VertexID] = vec4(gl_Position.x, -gl_Position.y, gl_Position.zw);
Verted shader for the second program. It just uses the data but doesn't modify it.
layout(std430, binding = 1) buffer mesh
vec4 points[3];
vec2 texs[3];
mesh_data;
out highp vec2 coords;
void main()
coords = mesh_data.texs[gl_VertexID];
gl_Position = mesh_data.points[gl_VertexID];
In the application, you need to bind a VAO.
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
Then setup your SSBO.
float const data[] =
-0.5f, -0.5f, 0.0f, 1.0,
0.0f, 0.5f, 0.0f, 1.0,
0.5f, -0.5f, 0.0f, 1.0,
0.0f, 0.0f,
0.5f, 1.0f,
1.0f, 0.0f
;
glGenBuffers(1, &ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ssbo);
Make the draw calls using the first program.
glUseProgram(first_program);
glDrawArrays(GL_TRIANGLES, 0, 3);
Insert a memory barrier to ensure the writes complete from the preceding draw call before the next draw call tries to read from the buffer.
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
Make the draw calls using the second program.
glUseProgram(second_program);
glDrawArrays(GL_TRIANGLES, 0, 3);
I hope that clarifies things! Let me know if you have any further questions.
It seems like you're most of the way there, but there are a few things you should watch out for.
Is the layout consistent in both programs?
layout(std140, binding = 1) buffer mesh
You need to be careful about this layout. std140 will round up alignments to vec4, so will no longer line up with the data you're providing from the C code. In this case, std430 should work for you.
Do i also have to bind the SSBO to the second program outside of the render loop? In a different way than the first binding?
Once you've bound the SSBO once, assuming both programs are using the same binding point (in your example, they are) then you should be fine. Sharing data between programs is fine, but synchronisation is required. You can enforce this with a memory barrier.
You don't mention VAOs, but you will only be able to use SSBOs after you've bound a VAO (not on the default one).
I think this might be best explained with an example.
Vertex shader for the first program. It uses the buffer data for its position and texture coords and then flips the positions in Y.
layout(std430, binding = 1) buffer mesh
vec4 points[3];
vec2 texs[3];
mesh_data;
out highp vec2 coords;
void main()
coords = mesh_data.texs[gl_VertexID];
gl_Position = mesh_data.points[gl_VertexID];
mesh_data.points[gl_VertexID] = vec4(gl_Position.x, -gl_Position.y, gl_Position.zw);
Verted shader for the second program. It just uses the data but doesn't modify it.
layout(std430, binding = 1) buffer mesh
vec4 points[3];
vec2 texs[3];
mesh_data;
out highp vec2 coords;
void main()
coords = mesh_data.texs[gl_VertexID];
gl_Position = mesh_data.points[gl_VertexID];
In the application, you need to bind a VAO.
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
Then setup your SSBO.
float const data[] =
-0.5f, -0.5f, 0.0f, 1.0,
0.0f, 0.5f, 0.0f, 1.0,
0.5f, -0.5f, 0.0f, 1.0,
0.0f, 0.0f,
0.5f, 1.0f,
1.0f, 0.0f
;
glGenBuffers(1, &ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ssbo);
Make the draw calls using the first program.
glUseProgram(first_program);
glDrawArrays(GL_TRIANGLES, 0, 3);
Insert a memory barrier to ensure the writes complete from the preceding draw call before the next draw call tries to read from the buffer.
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
Make the draw calls using the second program.
glUseProgram(second_program);
glDrawArrays(GL_TRIANGLES, 0, 3);
I hope that clarifies things! Let me know if you have any further questions.
answered Mar 22 at 22:11
LaurieLaurie
562 silver badges2 bronze badges
562 silver badges2 bronze badges
Thank you for answering! I tried three layouts: std140, std430 and shared. Also i already used glMemoryBarrier and a separate VAO. Still not working. I found a work-around though, see 2nd edit.
– prox
Mar 26 at 16:27
Sorry to hear this didn't work for you. It works for me locally, so whilst I'm glad you've found a work around, I don't think the question should be marked as resolved, as the original question hasn't been solved. I take it glGetError is returning GL_NO_ERROR?
– Laurie
Mar 26 at 22:58
Yes, no error so far. Only some usage hints concerning the use of the storage buffers.
– prox
Mar 31 at 18:17
add a comment |
Thank you for answering! I tried three layouts: std140, std430 and shared. Also i already used glMemoryBarrier and a separate VAO. Still not working. I found a work-around though, see 2nd edit.
– prox
Mar 26 at 16:27
Sorry to hear this didn't work for you. It works for me locally, so whilst I'm glad you've found a work around, I don't think the question should be marked as resolved, as the original question hasn't been solved. I take it glGetError is returning GL_NO_ERROR?
– Laurie
Mar 26 at 22:58
Yes, no error so far. Only some usage hints concerning the use of the storage buffers.
– prox
Mar 31 at 18:17
Thank you for answering! I tried three layouts: std140, std430 and shared. Also i already used glMemoryBarrier and a separate VAO. Still not working. I found a work-around though, see 2nd edit.
– prox
Mar 26 at 16:27
Thank you for answering! I tried three layouts: std140, std430 and shared. Also i already used glMemoryBarrier and a separate VAO. Still not working. I found a work-around though, see 2nd edit.
– prox
Mar 26 at 16:27
Sorry to hear this didn't work for you. It works for me locally, so whilst I'm glad you've found a work around, I don't think the question should be marked as resolved, as the original question hasn't been solved. I take it glGetError is returning GL_NO_ERROR?
– Laurie
Mar 26 at 22:58
Sorry to hear this didn't work for you. It works for me locally, so whilst I'm glad you've found a work around, I don't think the question should be marked as resolved, as the original question hasn't been solved. I take it glGetError is returning GL_NO_ERROR?
– Laurie
Mar 26 at 22:58
Yes, no error so far. Only some usage hints concerning the use of the storage buffers.
– prox
Mar 31 at 18:17
Yes, no error so far. Only some usage hints concerning the use of the storage buffers.
– prox
Mar 31 at 18:17
add a comment |
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55169145%2fmake-a-shader-storage-buffer-in-different-shader-programs-accessible%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown