|
| 1 | +#include <iostream> |
| 2 | + |
| 3 | +#include <glm/glm.hpp> |
| 4 | + |
| 5 | +#include "Shader.h" |
| 6 | +#include "Renderer.h" |
| 7 | + |
| 8 | +static uint32_t s_ComputeShader = -1; |
| 9 | +static const std::filesystem::path s_ComputeShaderPath = "Shaders/Compute.glsl"; |
| 10 | + |
| 11 | +static void ErrorCallback(int error, const char* description) |
| 12 | +{ |
| 13 | + std::cerr << "Error: " << description << std::endl; |
| 14 | +} |
| 15 | + |
| 16 | +static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) |
| 17 | +{ |
| 18 | + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) |
| 19 | + glfwSetWindowShouldClose(window, GLFW_TRUE); |
| 20 | + |
| 21 | + if (key == GLFW_KEY_R) |
| 22 | + s_ComputeShader = ReloadComputeShader(s_ComputeShader, s_ComputeShaderPath); |
| 23 | +} |
| 24 | + |
| 25 | +int main() |
| 26 | +{ |
| 27 | + glfwSetErrorCallback(ErrorCallback); |
| 28 | + |
| 29 | + if (!glfwInit()) |
| 30 | + exit(EXIT_FAILURE); |
| 31 | + |
| 32 | + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); |
| 33 | + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); |
| 34 | + |
| 35 | + int width = 1280; |
| 36 | + int height = 720; |
| 37 | + |
| 38 | + GLFWwindow* window = glfwCreateWindow(width, height, "Compute", NULL, NULL); |
| 39 | + if (!window) |
| 40 | + { |
| 41 | + glfwTerminate(); |
| 42 | + exit(EXIT_FAILURE); |
| 43 | + } |
| 44 | + |
| 45 | + glfwSetKeyCallback(window, KeyCallback); |
| 46 | + |
| 47 | + glfwMakeContextCurrent(window); |
| 48 | + gladLoadGL(glfwGetProcAddress); |
| 49 | + glfwSwapInterval(1); |
| 50 | + |
| 51 | + s_ComputeShader = CreateComputeShader(s_ComputeShaderPath); |
| 52 | + if (s_ComputeShader == -1) |
| 53 | + { |
| 54 | + std::cerr << "Compute shader failed\n"; |
| 55 | + return -1; |
| 56 | + } |
| 57 | + |
| 58 | + Texture computeShaderTexture = CreateTexture(width, height); |
| 59 | + Framebuffer fb = CreateFramebufferWithTexture(computeShaderTexture); |
| 60 | + |
| 61 | + while (!glfwWindowShouldClose(window)) |
| 62 | + { |
| 63 | + glfwGetFramebufferSize(window, &width, &height); |
| 64 | + |
| 65 | + // Resize texture |
| 66 | + if (width != computeShaderTexture.Width || height != computeShaderTexture.Height) |
| 67 | + { |
| 68 | + glDeleteTextures(1, &computeShaderTexture.Handle); |
| 69 | + computeShaderTexture = CreateTexture(width, height); |
| 70 | + AttachTextureToFramebuffer(fb, computeShaderTexture); |
| 71 | + } |
| 72 | + |
| 73 | + // Compute |
| 74 | + { |
| 75 | + glUseProgram(s_ComputeShader); |
| 76 | + glBindImageTexture(0, fb.ColorAttachment.Handle, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); |
| 77 | + |
| 78 | + const GLuint workGroupSizeX = 16; |
| 79 | + const GLuint workGroupSizeY = 16; |
| 80 | + |
| 81 | + GLuint numGroupsX = (width + workGroupSizeX - 1) / workGroupSizeX; |
| 82 | + GLuint numGroupsY = (height + workGroupSizeY - 1) / workGroupSizeY; |
| 83 | + |
| 84 | + glDispatchCompute(numGroupsX, numGroupsY, 1); |
| 85 | + |
| 86 | + // Ensure all writes to the image are complete |
| 87 | + glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); |
| 88 | + } |
| 89 | + |
| 90 | + // Blit |
| 91 | + { |
| 92 | + BlitFramebufferToSwapchain(fb); |
| 93 | + } |
| 94 | + |
| 95 | + glfwSwapBuffers(window); |
| 96 | + glfwPollEvents(); |
| 97 | + } |
| 98 | + |
| 99 | + glfwDestroyWindow(window); |
| 100 | + |
| 101 | + glfwTerminate(); |
| 102 | +} |
0 commit comments