got SSBO working

This commit is contained in:
Gwendolyn 2023-05-03 17:30:39 +02:00
commit b66d918af8
4 changed files with 175 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/.idea
/cmake-*

11
CMakeLists.txt Normal file
View file

@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 3.24)
project(shader-automaton)
find_package(OpenGL REQUIRED)
find_package(GLEW REQUIRED)
find_package(glfw3 3.3 REQUIRED)
add_executable(shader-automaton main.cpp)
target_link_libraries(shader-automaton PRIVATE OpenGL::GL GLEW::GLEW glfw)

BIN
main Executable file

Binary file not shown.

162
main.cpp Normal file
View file

@ -0,0 +1,162 @@
#include <cstdio>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <cstdlib>
#include <cstring>
#include <vector>
GLuint loadShader(const char *source, GLenum shader_type) {
GLuint shaderId = glCreateShader(shader_type);
GLint result = GL_FALSE;
int infoLogLength;
// Compile Vertex Shader
glShaderSource(shaderId, 1, &source, nullptr);
glCompileShader(shaderId);
glGetShaderiv(shaderId, GL_COMPILE_STATUS, &result);
glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &infoLogLength);
if (infoLogLength > 0) {
std::vector<char> VertexShaderErrorMessage(infoLogLength + 1);
glGetShaderInfoLog(shaderId, infoLogLength, nullptr,
&VertexShaderErrorMessage[0]);
printf("%s\n", &VertexShaderErrorMessage[0]);
exit(-1);
}
return shaderId;
}
GLuint loadProgram(const std::vector<GLuint> &shaders) {
GLuint programId = glCreateProgram();
for (const auto &item : shaders) {
glAttachShader(programId, item);
}
glLinkProgram(programId);
GLint result = GL_FALSE;
int infoLogLength;
glGetProgramiv(programId, GL_LINK_STATUS, &result);
glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &infoLogLength);
if (infoLogLength > 0) {
std::vector<char> ProgramErrorMessage(infoLogLength + 1);
glGetProgramInfoLog(programId, infoLogLength, nullptr,
&ProgramErrorMessage[0]);
printf("%s\n", &ProgramErrorMessage[0]);
}
return programId;
}
static const char *vertex_shader =
"#version 460\n"
"layout(location = 0) in vec3 vertexPosition_modelspace;\n"
"out vec2 coord;\n"
"void main(){\n"
" gl_Position.xyz = vertexPosition_modelspace;\n"
" gl_Position.w = 1.0;\n"
" 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"
"void main(){\n"
" int x = int(255. * (coord.x + 1.) / 2.);"
" color = vec3(c[x]/255., 0.5,0.5);\n"
"}";
int main() {
glewExperimental = true;
if (!glfwInit()) {
fprintf(stderr, "Failed to initialize GLFW\n");
return -1;
}
glfwWindowHint(GLFW_SAMPLES, 0);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow *window =
glfwCreateWindow(1024, 768, "Tutorial 01", nullptr, nullptr);
if (window == nullptr) {
fprintf(stderr,
"Failed to open GLFW window. If you have an Intel GPU, they are "
"not 3.3 compatible. Try the 2.1 version of the tutorials.\n");
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window); // Initialize GLEW
glewExperimental = true; // Needed in core profile
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
return -1;
}
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
};
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data),
g_vertex_buffer_data, GL_STATIC_DRAW);
GLuint programId = loadProgram({
loadShader(vertex_shader, GL_VERTEX_SHADER),
loadShader(fragment_shader, GL_FRAGMENT_SHADER),
});
int c[256];
for (size_t i = 0; i < 256; ++i) {
c[i] = i;
}
GLuint ssbo = 0;
glGenBuffers(1, &ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
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");
GLuint ssbo_binding_point_index = 2;
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, ssbo_binding_point_index, ssbo);
glShaderStorageBlockBinding(programId, block_index, ssbo_binding_point_index);
do {
glClear(GL_COLOR_BUFFER_BIT);
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);
glDisableVertexAttribArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
} // Check if the ESC key was pressed or the window was closed
while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0);
}