Skip to content

Commit 9e6f7d5

Browse files
committed
Initial commit
1 parent 3071036 commit 9e6f7d5

10 files changed

Lines changed: 414 additions & 2 deletions

File tree

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,7 @@ compile_commands.json
1010
CTestTestfile.cmake
1111
_deps
1212
CMakeUserPresets.json
13+
14+
# Visual Studio
15+
.vs/
16+
*.user

App/CMakeLists.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
# App
3+
4+
set(SOURCE_DIR "Source")
5+
6+
set(SOURCES
7+
Source/Main.cpp
8+
Source/Shader.h
9+
Source/Shader.cpp
10+
Source/Renderer.h
11+
Source/Renderer.cpp
12+
)
13+
14+
# Add the executable target
15+
add_executable(App ${SOURCES})
16+
target_link_libraries(App glfw)
17+
target_link_libraries(App glad)
18+
target_link_libraries(App glm)

App/Shaders/Compute.glsl

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#version 460 core
2+
3+
layout(rgba32f, binding = 0) uniform writeonly image2D outputImage;
4+
5+
layout(local_size_x = 16, local_size_y = 16) in;
6+
void main()
7+
{
8+
ivec2 pixelCoord = ivec2(gl_GlobalInvocationID.xy);
9+
10+
if (pixelCoord.x >= imageSize(outputImage).x || pixelCoord.y >= imageSize(outputImage).y)
11+
return;
12+
13+
ivec2 texSize = imageSize(outputImage);
14+
vec2 fTexSize = vec2(texSize);
15+
vec2 normalizedCoord = vec2(pixelCoord) / vec2(texSize);
16+
17+
vec4 O = vec4(0, 0, 0, 1);
18+
vec2 I = vec2(pixelCoord);
19+
20+
float iTime = 2.2;
21+
float i = 0.0, t=iTime;
22+
O *= i;
23+
for(vec2 a=fTexSize.xy, p=(I+I-a)/a.y; i++<20.;
24+
O += (cos(sin(i*.2+t)*vec4(0,4,3,1))+2.)
25+
/(i/1e3+abs(length(a-.5*min(a+a.yx,.1))-.05)))
26+
a.x = abs(a = (fract(.2*t+.3*p*i*mat2(cos(cos(.2*t+.2*i)+vec4(0,11,33,0))))-.5)).x;
27+
28+
O = tanh(O*O/2e5);
29+
30+
vec4 color = vec4(normalizedCoord, 0.0, 1.0);
31+
imageStore(outputImage, pixelCoord, O);
32+
}

App/Source/Main.cpp

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
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+
}

App/Source/Renderer.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#include "Renderer.h"
2+
3+
#include <iostream>
4+
5+
Texture CreateTexture(int width, int height)
6+
{
7+
Texture result;
8+
result.Width = width;
9+
result.Height = height;
10+
11+
glCreateTextures(GL_TEXTURE_2D, 1, &result.Handle);
12+
13+
glTextureStorage2D(result.Handle, 1, GL_RGBA32F, width, height);
14+
15+
glTextureParameteri(result.Handle, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
16+
glTextureParameteri(result.Handle, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
17+
18+
glTextureParameteri(result.Handle, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
19+
glTextureParameteri(result.Handle, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
20+
21+
return result;
22+
}
23+
24+
Framebuffer CreateFramebufferWithTexture(const Texture texture)
25+
{
26+
Framebuffer result;
27+
28+
glCreateFramebuffers(1, &result.Handle);
29+
30+
if (!AttachTextureToFramebuffer(result, texture))
31+
{
32+
glDeleteFramebuffers(1, &result.Handle);
33+
return {};
34+
}
35+
36+
return result;
37+
}
38+
39+
bool AttachTextureToFramebuffer(Framebuffer& framebuffer, const Texture texture)
40+
{
41+
glNamedFramebufferTexture(framebuffer.Handle, GL_COLOR_ATTACHMENT0, texture.Handle, 0);
42+
43+
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
44+
{
45+
std::cerr << "Framebuffer is not complete!" << std::endl;
46+
return false;
47+
}
48+
49+
framebuffer.ColorAttachment = texture;
50+
return true;
51+
}
52+
53+
void BlitFramebufferToSwapchain(const Framebuffer framebuffer)
54+
{
55+
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer.Handle);
56+
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); // swapchain
57+
58+
glBlitFramebuffer(0, 0, framebuffer.ColorAttachment.Width, framebuffer.ColorAttachment.Height, // Source rect
59+
0, 0, framebuffer.ColorAttachment.Width, framebuffer.ColorAttachment.Height, // Destination rect
60+
GL_COLOR_BUFFER_BIT, GL_NEAREST);
61+
}

App/Source/Renderer.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#pragma once
2+
3+
#include <glad/gl.h>
4+
#define GLFW_INCLUDE_NONE
5+
#include <GLFW/glfw3.h>
6+
7+
struct Texture
8+
{
9+
GLuint Handle = 0;
10+
uint32_t Width = 0;
11+
uint32_t Height = 0;
12+
};
13+
14+
struct Framebuffer
15+
{
16+
GLuint Handle = 0;
17+
Texture ColorAttachment;
18+
};
19+
20+
Texture CreateTexture(int width, int height);
21+
Framebuffer CreateFramebufferWithTexture(const Texture texture);
22+
bool AttachTextureToFramebuffer(Framebuffer& framebuffer, const Texture texture);
23+
void BlitFramebufferToSwapchain(const Framebuffer framebuffer);

App/Source/Shader.cpp

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#include "Shader.h"
2+
3+
#include <iostream>
4+
#include <fstream>
5+
6+
#include <glad/gl.h>
7+
8+
uint32_t CreateComputeShader(const std::filesystem::path& path)
9+
{
10+
std::ifstream file(path);
11+
12+
if (!file.is_open())
13+
{
14+
std::cerr << "Failed to open file: " << path.string() << std::endl;
15+
return -1;
16+
}
17+
18+
std::ostringstream contentStream;
19+
contentStream << file.rdbuf();
20+
std::string shaderSource = contentStream.str();
21+
22+
GLuint shaderHandle = glCreateShader(GL_COMPUTE_SHADER);
23+
24+
const GLchar* source = (const GLchar*)shaderSource.c_str();
25+
glShaderSource(shaderHandle, 1, &source, 0);
26+
27+
glCompileShader(shaderHandle);
28+
29+
GLint isCompiled = 0;
30+
glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &isCompiled);
31+
if (isCompiled == GL_FALSE)
32+
{
33+
GLint maxLength = 0;
34+
glGetShaderiv(shaderHandle, GL_INFO_LOG_LENGTH, &maxLength);
35+
36+
std::vector<GLchar> infoLog(maxLength);
37+
glGetShaderInfoLog(shaderHandle, maxLength, &maxLength, &infoLog[0]);
38+
39+
std::cerr << infoLog.data() << std::endl;
40+
41+
glDeleteShader(shaderHandle);
42+
return -1;
43+
}
44+
45+
GLuint program = glCreateProgram();
46+
glAttachShader(program, shaderHandle);
47+
glLinkProgram(program);
48+
49+
GLint isLinked = 0;
50+
glGetProgramiv(program, GL_LINK_STATUS, (int*)&isLinked);
51+
if (isLinked == GL_FALSE)
52+
{
53+
GLint maxLength = 0;
54+
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);
55+
56+
std::vector<GLchar> infoLog(maxLength);
57+
glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]);
58+
59+
std::cerr << infoLog.data() << std::endl;
60+
61+
glDeleteProgram(program);
62+
glDeleteShader(shaderHandle);
63+
64+
return -1;
65+
}
66+
67+
glDetachShader(program, shaderHandle);
68+
return program;
69+
}
70+
71+
uint32_t ReloadComputeShader(uint32_t shaderHandle, const std::filesystem::path& path)
72+
{
73+
uint32_t newShaderHandle = CreateComputeShader(path);
74+
75+
// Return old shader if compilation failed
76+
if (newShaderHandle == -1)
77+
return shaderHandle;
78+
79+
glDeleteProgram(shaderHandle);
80+
return newShaderHandle;
81+
}

App/Source/Shader.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#pragma once
2+
3+
#include <filesystem>
4+
5+
uint32_t CreateComputeShader(const std::filesystem::path& path);
6+
uint32_t ReloadComputeShader(uint32_t shaderHandle, const std::filesystem::path& path);

0 commit comments

Comments
 (0)