diff --git a/main.cpp b/main.cpp index d3a98af..979a036 100644 --- a/main.cpp +++ b/main.cpp @@ -56,18 +56,30 @@ static const char *vertex_shader = " coord.xy = vertexPosition_modelspace.xy;\n" "}"; -static const char *fragment_shader = "#version 460\n" - "out vec3 color;\n" - "in vec2 coord;\n" - "layout (std430, binding = 2) restrict readonly buffer shader_data\n" - "{\n" - " int c[];\n" - "};\n" +static const char *fragment_shader = + "#version 460\n" + "out vec3 color;\n" + "in vec2 coord;\n" + "layout (std430, binding = 2) restrict readonly buffer shader_data\n" + "{\n" + " int c[];\n" + "};\n" - "void main(){\n" - " int x = int(255. * (coord.x + 1.) / 2.);" - " color = vec3(c[x]/255., 0.5,0.5);\n" - "}"; + "void main(){\n" + " int x = int(255. * (coord.x + 1.) / 2.);" + " color = vec3(c[x]/255., 0.5,0.5);\n" + "}"; + +static const char *compute_shader = + "#version 460\n" + "layout(local_size_x = 1, local_size_y = 1) in;\n" + "layout (std430, binding = 2) restrict buffer shader_data\n" + "{\n" + " int c[];\n" + "};\n" + "void main(){\n" + " c[gl_GlobalInvocationID.x] = (c[gl_GlobalInvocationID.x] + 1) % 256;\n" + "}\n"; int main() { glewExperimental = true; @@ -117,6 +129,10 @@ int main() { loadShader(fragment_shader, GL_FRAGMENT_SHADER), }); + GLuint computeProgramId = loadProgram({ + loadShader(compute_shader, GL_COMPUTE_SHADER), + }); + int c[256]; for (size_t i = 0; i < 256; ++i) { @@ -126,31 +142,35 @@ int main() { GLuint ssbo = 0; glGenBuffers(1, &ssbo); glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int)*256, &c,GL_DYNAMIC_COPY); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int) * 256, &c, + GL_DYNAMIC_COPY); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); - unsigned int block_index = glGetProgramResourceIndex(programId, GL_SHADER_STORAGE_BLOCK, "shader_data"); + unsigned int block_index = glGetProgramResourceIndex( + programId, GL_SHADER_STORAGE_BLOCK, "shader_data"); GLuint ssbo_binding_point_index = 2; glBindBufferBase(GL_SHADER_STORAGE_BUFFER, ssbo_binding_point_index, ssbo); glShaderStorageBlockBinding(programId, block_index, ssbo_binding_point_index); + glUseProgram(computeProgramId); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, ssbo_binding_point_index, ssbo); + unsigned int compute_block_index = glGetProgramResourceIndex( + programId, GL_SHADER_STORAGE_BLOCK, "shader_data"); + glShaderStorageBlockBinding(computeProgramId, compute_block_index, + ssbo_binding_point_index); + do { glClear(GL_COLOR_BUFFER_BIT); + + glUseProgram(computeProgramId); + glDispatchCompute(255, 1, 1); + glUseProgram(programId); - for (int & i : c) { - i = (i + 1) % 256; - } - - glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo); - GLvoid *p = glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY); - std::memcpy(p, &c, sizeof(int) * 256); - glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); - glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); - glDrawArrays(GL_TRIANGLES, 0,3); + glDrawArrays(GL_TRIANGLES, 0, 3); glDisableVertexAttribArray(0); glfwSwapBuffers(window);