diff options
| author | hachem <im@hachem.wtf> | 2025-08-13 18:20:54 +0200 |
|---|---|---|
| committer | hachem <im@hachem.wtf> | 2025-08-13 18:20:54 +0200 |
| commit | f1517709556827fb8b7bab00bdee4a9794d88dd1 (patch) | |
| tree | a1b2325c8bc693bff0ace1fd98ea7dac91f76286 | |
| parent | 1ad6bc34323f5b30d463ebe47a58d47ff9d4f328 (diff) | |
[add]: Compute shaders and Compute Textures
| -rw-r--r-- | assets/Compute.glsl | 24 | ||||
| -rw-r--r-- | assets/ImageProcessing.glsl | 31 | ||||
| -rw-r--r-- | assets/ParticleSystem.glsl | 58 | ||||
| -rw-r--r-- | assets/TextureProcessor.glsl | 43 | ||||
| -rw-r--r-- | src/Core/Application.cpp | 122 | ||||
| -rw-r--r-- | src/Core/Application.h | 8 | ||||
| -rw-r--r-- | src/Core/Event.h | 42 | ||||
| -rw-r--r-- | src/Platform/OpenGL/OpenGLShader.cpp | 30 | ||||
| -rw-r--r-- | src/Platform/OpenGL/OpenGLShader.h | 6 | ||||
| -rw-r--r-- | src/Platform/OpenGL/OpenGLTexture.cpp | 9 | ||||
| -rw-r--r-- | src/Platform/OpenGL/OpenGLTexture.h | 4 | ||||
| -rw-r--r-- | src/Rendering/Shader.cpp | 11 | ||||
| -rw-r--r-- | src/Rendering/Shader.h | 11 | ||||
| -rw-r--r-- | src/Rendering/Texture.h | 4 |
14 files changed, 366 insertions, 37 deletions
diff --git a/assets/Compute.glsl b/assets/Compute.glsl new file mode 100644 index 0000000..9a36a84 --- /dev/null +++ b/assets/Compute.glsl @@ -0,0 +1,24 @@ +#type compute +#version 430 core + +layout(local_size_x = 256) in; + +layout(std430, binding = 0) buffer InputBuffer +{ + float data[]; +} inputBuffer; + +layout(std430, binding = 1) buffer OutputBuffer +{ + float data[]; +} outputBuffer; + +uniform float u_Scale; +uniform float u_Offset; + +void main() +{ + uint index = gl_GlobalInvocationID.x; + float inputValue = inputBuffer.data[index]; + outputBuffer.data[index] = inputValue * u_Scale + u_Offset; +} diff --git a/assets/ImageProcessing.glsl b/assets/ImageProcessing.glsl new file mode 100644 index 0000000..3a05425 --- /dev/null +++ b/assets/ImageProcessing.glsl @@ -0,0 +1,31 @@ +#type compute +#version 430 core + +layout(local_size_x = 16, local_size_y = 16) in; + +layout(binding = 0) uniform sampler2D u_InputTexture; +layout(binding = 1, rgba8) uniform image2D u_OutputTexture; + +uniform vec2 u_TextureSize; +uniform float u_Brightness; +uniform float u_Contrast; +uniform float u_Saturation; + +void main() +{ + ivec2 pixelCoord = ivec2(gl_GlobalInvocationID.xy); + + if (pixelCoord.x >= int(u_TextureSize.x) || pixelCoord.y >= int(u_TextureSize.y)) + return; + + vec2 texCoord = (vec2(pixelCoord) + 0.5) / u_TextureSize; + vec4 color = texture(u_InputTexture, texCoord); + + color.rgb = (color.rgb - 0.5) * u_Contrast + 0.5 + u_Brightness; + + float luminance = dot(color.rgb, vec3(0.299, 0.587, 0.114)); + color.rgb = mix(vec3(luminance), color.rgb, u_Saturation); + color.rgb = clamp(color.rgb, 0.0, 1.0); + + imageStore(u_OutputTexture, pixelCoord, color); +} diff --git a/assets/ParticleSystem.glsl b/assets/ParticleSystem.glsl new file mode 100644 index 0000000..d40726d --- /dev/null +++ b/assets/ParticleSystem.glsl @@ -0,0 +1,58 @@ +#type compute +#version 430 core + +layout(local_size_x = 256) in; + +struct Particle +{ + vec4 position; // xyz = position, w = lifetime + vec4 velocity; // xyz = velocity, w = mass + vec4 color; // rgba = color +}; + +layout(std430, binding = 0) buffer ParticleBuffer +{ + Particle particles[]; +} particleBuffer; + +uniform float u_DeltaTime; +uniform vec3 u_Gravity; +uniform vec3 u_EmitterPosition; +uniform float u_EmissionRate; +uniform float u_ParticleLifetime; +uniform float u_Time; + +void main() +{ + uint index = gl_GlobalInvocationID.x; + + if (index >= particles.length()) + return; + + Particle particle = particleBuffer.particles[index]; + + particle.position.w -= u_DeltaTime; + + if (particle.position.w <= 0.0) + { + particle.position.xyz = u_EmitterPosition; + particle.position.w = u_ParticleLifetime; + + float angle = fract(sin(dot(vec2(index, u_Time), vec2(12.9898, 78.233))) * 43758.5453) * 2.0 * 3.14159; + float speed = 2.0 + fract(sin(dot(vec2(index + 1, u_Time), vec2(12.9898, 78.233))) * 43758.5453) * 3.0; + particle.velocity.xyz = vec3(cos(angle) * speed, 5.0, sin(angle) * speed); + particle.velocity.w = 1.0; + + particle.color = vec4(1.0, 0.5 + 0.5 * fract(sin(index * 123.456) * 43758.5453), 0.2, 1.0); + } + else + { + particle.velocity.xyz += u_Gravity * u_DeltaTime; + particle.position.xyz += particle.velocity.xyz * u_DeltaTime; + + float lifeRatio = particle.position.w / u_ParticleLifetime; + particle.color.a = lifeRatio; + } + + particleBuffer.particles[index] = particle; +} diff --git a/assets/TextureProcessor.glsl b/assets/TextureProcessor.glsl new file mode 100644 index 0000000..a234ac8 --- /dev/null +++ b/assets/TextureProcessor.glsl @@ -0,0 +1,43 @@ +#type compute +#version 430 core + +layout(local_size_x = 16, local_size_y = 16) in; + +layout(binding = 0) uniform sampler2D u_InputTexture; +layout(binding = 1, rgba8) uniform image2D u_OutputTexture; + +uniform vec2 u_TextureSize; +uniform float u_Time; +uniform float u_Brightness; +uniform float u_Contrast; +uniform float u_Saturation; + +void main() +{ + ivec2 pixelCoord = ivec2(gl_GlobalInvocationID.xy); + + if (pixelCoord.x >= int(u_TextureSize.x) || pixelCoord.y >= int(u_TextureSize.y)) + return; + + vec2 texCoord = (vec2(pixelCoord) + 0.5) / u_TextureSize; + vec4 color = texture(u_InputTexture, texCoord); + + float time = u_Time * 2.0f; + float u = texCoord.x; + float v = texCoord.y; + + float wave = sin(u * 10.0f + time) * cos(v * 10.0f + time * 0.5f); + wave = (wave + 1.0f) * 0.5f; + + vec4 animatedColor = vec4(wave, 1.0f - wave, (u + v) * 0.5f, 1.0f); + color = mix(color, animatedColor, 0.3f); + + color.rgb = (color.rgb - 0.5) * u_Contrast + 0.5 + u_Brightness; + + float luminance = dot(color.rgb, vec3(0.299, 0.587, 0.114)); + color.rgb = mix(vec3(luminance), color.rgb, u_Saturation); + + color.rgb = clamp(color.rgb, 0.0, 1.0); + + imageStore(u_OutputTexture, pixelCoord, color); +} diff --git a/src/Core/Application.cpp b/src/Core/Application.cpp index 0fd0023..4db79a5 100644 --- a/src/Core/Application.cpp +++ b/src/Core/Application.cpp @@ -224,6 +224,30 @@ namespace Donut m_Texture->SetData(pixelData, 256 * 256 * 4); delete[] pixelData; + + m_ComputeShader = std::shared_ptr<Shader>(Shader::Create("assets/TextureProcessor.glsl")); + + if (!m_ComputeShader) + { + std::cout << "Failed to create compute shader! Falling back to CPU texture generation." << std::endl; + m_UseComputeShader = false; + } + else + std::cout << "Compute shader created successfully!" << std::endl; + + m_ProcessedTexture = Texture2D::Create(256, 256); + m_ComputeBrightness = 0.0f; + m_ComputeContrast = 1.0f; + m_ComputeSaturation = 1.0f; + m_UseComputeShader = true; + + std::cout << "=== Compute Shader Test ===" << std::endl; + std::cout << "C - Toggle compute shader on/off" << std::endl; + std::cout << "Arrow Keys - Adjust brightness (Up/Down) and contrast (Left/Right)" << std::endl; + std::cout << "Q/E - Adjust saturation" << std::endl; + std::cout << "WASD - Move camera" << std::endl; + std::cout << "Mouse - Look around" << std::endl; + std::cout << "==========================" << std::endl; } void Application::OnShutdown() @@ -253,6 +277,42 @@ namespace Donut m_Camera->MoveDown(m_DeltaTime); } + static bool cKeyPressed = false; + if (m_Keys[GLFW_KEY_C] && !cKeyPressed) + { + m_UseComputeShader = !m_UseComputeShader; + std::cout << "Compute shader: " << (m_UseComputeShader ? "ON" : "OFF") << std::endl; + cKeyPressed = true; + } + if (!m_Keys[GLFW_KEY_C]) + cKeyPressed = false; + if (m_Keys[GLFW_KEY_UP]) + m_ComputeBrightness += m_DeltaTime * 0.5f; + if (m_Keys[GLFW_KEY_DOWN]) + m_ComputeBrightness -= m_DeltaTime * 0.5f; + if (m_Keys[GLFW_KEY_LEFT]) + m_ComputeContrast -= m_DeltaTime * 0.5f; + if (m_Keys[GLFW_KEY_RIGHT]) + m_ComputeContrast += m_DeltaTime * 0.5f; + if (m_Keys[GLFW_KEY_Q]) + m_ComputeSaturation -= m_DeltaTime * 0.5f; + if (m_Keys[GLFW_KEY_E]) + m_ComputeSaturation += m_DeltaTime * 0.5f; + + m_ComputeBrightness = glm::clamp(m_ComputeBrightness, -1.0f, 1.0f); + m_ComputeContrast = glm::clamp(m_ComputeContrast, 0.1f, 3.0f); + m_ComputeSaturation = glm::clamp(m_ComputeSaturation, 0.0f, 2.0f); + + static float statusTimer = 0.0f; + statusTimer += m_DeltaTime; + if (statusTimer > 2.0f) + { + std::cout << "Compute Shader Status - Brightness: " << m_ComputeBrightness + << ", Contrast: " << m_ComputeContrast + << ", Saturation: " << m_ComputeSaturation << std::endl; + statusTimer = 0.0f; + } + UpdateTexture(); } @@ -261,7 +321,12 @@ namespace Donut Renderer::SetClearColor({ 0.0f, 0.0f, 0.0f, 1.0f }); Renderer::Clear(); - if (m_Texture) + if (m_UseComputeShader && m_ProcessedTexture) + { + m_ProcessedTexture->Bind(0); + m_Shader->SetInt("u_Texture", 0); + } + else if (m_Texture) { m_Texture->Bind(0); m_Shader->SetInt("u_Texture", 0); @@ -300,28 +365,45 @@ namespace Donut m_TextureTime += m_DeltaTime; - uint32_t* pixelData = new uint32_t[256 * 256]; - for (int y = 0; y < 256; y++) + if (m_UseComputeShader && m_ComputeShader && m_ProcessedTexture) { - for (int x = 0; x < 256; x++) + m_ComputeShader->Bind(); + m_Texture->Bind(0); + m_ComputeShader->SetInt("u_InputTexture", 0); + m_ProcessedTexture->BindAsImage(1, false); + m_ComputeShader->SetFloat2("u_TextureSize", glm::vec2(256.0f, 256.0f)); + m_ComputeShader->SetFloat("u_Time", m_TextureTime); + m_ComputeShader->SetFloat("u_Brightness", m_ComputeBrightness); + m_ComputeShader->SetFloat("u_Contrast", m_ComputeContrast); + m_ComputeShader->SetFloat("u_Saturation", m_ComputeSaturation); + m_ComputeShader->Dispatch(16, 16, 1); + m_ComputeShader->MemoryBarrier(IMAGE_ACCESS_BARRIER_BIT); + } + else + { + uint32_t* pixelData = new uint32_t[256 * 256]; + for (int y = 0; y < 256; y++) { - float time = m_TextureTime * 2.0f; - float u = (float)x / 256.0f; - float v = (float)y / 256.0f; - - float wave = sin(u * 10.0f + time) * cos(v * 10.0f + time * 0.5f); - wave = (wave + 1.0f) * 0.5f; - - uint8_t r = (uint8_t)(wave * 255); - uint8_t g = (uint8_t)((1.0f - wave) * 255); - uint8_t b = (uint8_t)((u + v) * 0.5f * 255); - uint8_t a = 255; - - pixelData[y * 256 + x] = (a << 24) | (b << 16) | (g << 8) | r; + for (int x = 0; x < 256; x++) + { + float time = m_TextureTime * 2.0f; + float u = (float)x / 256.0f; + float v = (float)y / 256.0f; + + float wave = sin(u * 10.0f + time) * cos(v * 10.0f + time * 0.5f); + wave = (wave + 1.0f) * 0.5f; + + uint8_t r = (uint8_t)(wave * 255); + uint8_t g = (uint8_t)((1.0f - wave) * 255); + uint8_t b = (uint8_t)((u + v) * 0.5f * 255); + uint8_t a = 255; + + pixelData[y * 256 + x] = (a << 24) | (b << 16) | (g << 8) | r; + } } + + m_Texture->SetData(pixelData, 256 * 256 * 4); + delete[] pixelData; } - - m_Texture->SetData(pixelData, 256 * 256 * 4); - delete[] pixelData; } } diff --git a/src/Core/Application.h b/src/Core/Application.h index 7406136..922af67 100644 --- a/src/Core/Application.h +++ b/src/Core/Application.h @@ -47,6 +47,14 @@ namespace Donut std::shared_ptr<Shader> m_Shader; std::shared_ptr<Texture2D> m_Texture; + // Compute shader related members + std::shared_ptr<Shader> m_ComputeShader; + std::shared_ptr<Texture2D> m_ProcessedTexture; + float m_ComputeBrightness; + float m_ComputeContrast; + float m_ComputeSaturation; + bool m_UseComputeShader; + std::unique_ptr<Camera> m_Camera; bool m_Keys[1024] = { false }; diff --git a/src/Core/Event.h b/src/Core/Event.h index 32cdde4..60d446d 100644 --- a/src/Core/Event.h +++ b/src/Core/Event.h @@ -81,7 +81,8 @@ namespace Donut virtual int GetCategoryFlags() const override { return EventCategoryKeyboard | \ EventCategoryInput; } - class WindowResizeEvent : public Event + class WindowResizeEvent + : public Event { public: WindowResizeEvent(unsigned int width, unsigned int height) @@ -101,28 +102,32 @@ namespace Donut unsigned int m_Width, m_Height; }; - class WindowCloseEvent : public Event + class WindowCloseEvent + : public Event { public: WindowCloseEvent() = default; APPLICATION_EVENT_CLASS_TYPE(WindowClose) }; - class WindowFocusEvent : public Event + class WindowFocusEvent + : public Event { public: WindowFocusEvent() = default; APPLICATION_EVENT_CLASS_TYPE(WindowFocus) }; - class WindowLostFocusEvent : public Event + class WindowLostFocusEvent + : public Event { public: WindowLostFocusEvent() = default; APPLICATION_EVENT_CLASS_TYPE(WindowLostFocus) }; - class WindowMovedEvent : public Event + class WindowMovedEvent + : public Event { public: WindowMovedEvent(int x, int y) @@ -142,7 +147,8 @@ namespace Donut int m_X, m_Y; }; - class KeyEvent : public Event + class KeyEvent + : public Event { public: int GetKeyCode() const { return m_KeyCode; } @@ -154,7 +160,8 @@ namespace Donut int m_KeyCode; }; - class KeyPressedEvent : public KeyEvent + class KeyPressedEvent + : public KeyEvent { public: KeyPressedEvent(int keycode, bool isRepeat = false) @@ -174,7 +181,8 @@ namespace Donut bool m_IsRepeat; }; - class KeyReleasedEvent : public KeyEvent + class KeyReleasedEvent + : public KeyEvent { public: KeyReleasedEvent(int keycode) : KeyEvent(keycode) { } @@ -187,7 +195,8 @@ namespace Donut KEYBOARD_EVENT_CLASS_TYPE(KeyReleased) }; - class KeyTypedEvent : public KeyEvent + class KeyTypedEvent + : public KeyEvent { public: KeyTypedEvent(int keycode) : KeyEvent(keycode) { } @@ -200,7 +209,8 @@ namespace Donut KEYBOARD_EVENT_CLASS_TYPE(KeyTyped) }; - class MouseMovedEvent : public Event + class MouseMovedEvent + : public Event { public: MouseMovedEvent(float x, float y) @@ -220,7 +230,8 @@ namespace Donut float m_MouseX, m_MouseY; }; - class MouseScrolledEvent : public Event + class MouseScrolledEvent + : public Event { public: MouseScrolledEvent(float xOffset, float yOffset) @@ -241,7 +252,8 @@ namespace Donut float m_XOffset, m_YOffset; }; - class MouseButtonEvent : public Event + class MouseButtonEvent + : public Event { public: int GetMouseButton() const { return m_Button; } @@ -254,7 +266,8 @@ namespace Donut int m_Button; }; - class MouseButtonPressedEvent : public MouseButtonEvent + class MouseButtonPressedEvent + : public MouseButtonEvent { public: MouseButtonPressedEvent(int button) : MouseButtonEvent(button) { } @@ -267,7 +280,8 @@ namespace Donut MOUSE_BUTTON_EVENT_CLASS_TYPE(MouseButtonPressed) }; - class MouseButtonReleasedEvent : public MouseButtonEvent + class MouseButtonReleasedEvent + : public MouseButtonEvent { public: MouseButtonReleasedEvent(int button) : MouseButtonEvent(button) { } diff --git a/src/Platform/OpenGL/OpenGLShader.cpp b/src/Platform/OpenGL/OpenGLShader.cpp index 39e95b7..6fcaa74 100644 --- a/src/Platform/OpenGL/OpenGLShader.cpp +++ b/src/Platform/OpenGL/OpenGLShader.cpp @@ -12,6 +12,8 @@ namespace Donut return GL_VERTEX_SHADER; if (type == "fragment" || type == "pixel") return GL_FRAGMENT_SHADER; + if (type == "compute") + return GL_COMPUTE_SHADER; return 0; } @@ -37,6 +39,14 @@ namespace Donut Compile(sources); } + OpenGLShader::OpenGLShader(const std::string& name, const std::string& computeSrc) + : m_Name(name) + { + std::unordered_map<uint32_t, std::string> sources; + sources[GL_COMPUTE_SHADER] = computeSrc; + Compile(sources); + } + OpenGLShader::~OpenGLShader() { glDeleteProgram(m_RendererID); @@ -160,6 +170,11 @@ namespace Donut UploadUniformFloat(name, value); } + void OpenGLShader::SetFloat2(const std::string& name, const glm::vec2& value) + { + UploadUniformFloat2(name, value); + } + void OpenGLShader::SetFloat3(const std::string& name, const glm::vec3& value) { UploadUniformFloat3(name, value); @@ -222,4 +237,19 @@ namespace Donut int location = glGetUniformLocation(m_RendererID, name.c_str()); glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(matrix)); } + + void OpenGLShader::Dispatch(uint32_t x, uint32_t y, uint32_t z) + { + glDispatchCompute(x, y, z); + } + + void OpenGLShader::DispatchIndirect(uint32_t offset) + { + glDispatchComputeIndirect(offset); + } + + void OpenGLShader::MemoryBarrier(uint32_t barriers) + { + glMemoryBarrier(barriers); + } }; diff --git a/src/Platform/OpenGL/OpenGLShader.h b/src/Platform/OpenGL/OpenGLShader.h index 2ebde12..bd58834 100644 --- a/src/Platform/OpenGL/OpenGLShader.h +++ b/src/Platform/OpenGL/OpenGLShader.h @@ -12,6 +12,7 @@ namespace Donut public: OpenGLShader(const std::string& filepath); OpenGLShader(const std::string& name, const std::string& vertexSrc, const std::string& fragmentSrc); + OpenGLShader(const std::string& name, const std::string& computeSrc); virtual ~OpenGLShader(); virtual void Bind() const override; @@ -20,10 +21,15 @@ namespace Donut virtual void SetInt(const std::string& name, int value) override; virtual void SetIntArray(const std::string& name, int* values, uint32_t count) override; virtual void SetFloat(const std::string& name, float value) override; + virtual void SetFloat2(const std::string& name, const glm::vec2& value) override; virtual void SetFloat3(const std::string& name, const glm::vec3& value) override; virtual void SetFloat4(const std::string& name, const glm::vec4& value) override; virtual void SetMat4(const std::string& name, const glm::mat4& value) override; + virtual void Dispatch(uint32_t x, uint32_t y = 1, uint32_t z = 1) override; + virtual void DispatchIndirect(uint32_t offset = 0) override; + virtual void MemoryBarrier(uint32_t barriers) override; + virtual const std::string& GetName() const override { return m_Name; } void UploadUniformInt(const std::string& name, int value); diff --git a/src/Platform/OpenGL/OpenGLTexture.cpp b/src/Platform/OpenGL/OpenGLTexture.cpp index 02252d1..7e2dea0 100644 --- a/src/Platform/OpenGL/OpenGLTexture.cpp +++ b/src/Platform/OpenGL/OpenGLTexture.cpp @@ -19,7 +19,7 @@ namespace Donut glTextureParameteri(m_RendererID, GL_TEXTURE_WRAP_T, GL_REPEAT); } - // TODO: Texture Loading + // TODO(Hachem): Texture Loading OpenGLTexture2D::OpenGLTexture2D(const std::string& path) : m_Path(path) { @@ -56,6 +56,7 @@ namespace Donut std::cout << "Data must be entire texture!" << std::endl; return; } + glTextureSubImage2D(m_RendererID, 0, 0, 0, m_Width, m_Height, m_DataFormat, GL_UNSIGNED_BYTE, data); } @@ -63,4 +64,10 @@ namespace Donut { glBindTextureUnit(slot, m_RendererID); } + + void OpenGLTexture2D::BindAsImage(uint32_t slot, bool readOnly) const + { + GLenum access = readOnly ? GL_READ_ONLY : GL_WRITE_ONLY; + glBindImageTexture(slot, m_RendererID, 0, GL_FALSE, 0, access, m_InternalFormat); + } };
\ No newline at end of file diff --git a/src/Platform/OpenGL/OpenGLTexture.h b/src/Platform/OpenGL/OpenGLTexture.h index 4a95ab4..b27bb16 100644 --- a/src/Platform/OpenGL/OpenGLTexture.h +++ b/src/Platform/OpenGL/OpenGLTexture.h @@ -5,7 +5,8 @@ namespace Donut { - class OpenGLTexture2D : public Texture2D + class OpenGLTexture2D + : public Texture2D { public: OpenGLTexture2D(uint32_t width, uint32_t height); @@ -18,6 +19,7 @@ namespace Donut virtual void SetData(void* data, uint32_t size) override; virtual void Bind(uint32_t slot = 0) const override; + virtual void BindAsImage(uint32_t slot = 0, bool readOnly = false) const override; virtual bool operator==(const Texture& other) const override { diff --git a/src/Rendering/Shader.cpp b/src/Rendering/Shader.cpp index b055fe4..a791c98 100644 --- a/src/Rendering/Shader.cpp +++ b/src/Rendering/Shader.cpp @@ -27,6 +27,17 @@ namespace Donut } } + Shader* Shader::CreateCompute(const std::string& name, const std::string& computeSrc) + { + switch (Renderer::GetAPI()) + { + case RendererAPI::API::OpenGL: + return new OpenGLShader(name, computeSrc); + default: + return nullptr; + } + } + void ShaderLibrary::Add(const std::shared_ptr<Shader>& shader) { auto& name = shader->GetName(); diff --git a/src/Rendering/Shader.h b/src/Rendering/Shader.h index a6b287a..aa46f07 100644 --- a/src/Rendering/Shader.h +++ b/src/Rendering/Shader.h @@ -5,6 +5,11 @@ #include <memory> #include <glm/glm.hpp> +#define SHADER_STORAGE_BARRIER_BIT 0x00002000 +#define UNIFORM_BARRIER_BIT 0x00000004 +#define TEXTURE_FETCH_BARRIER_BIT 0x00000008 +#define IMAGE_ACCESS_BARRIER_BIT 0x00000020 + namespace Donut { class Shader @@ -18,14 +23,20 @@ namespace Donut virtual void SetInt(const std::string& name, int value) = 0; virtual void SetIntArray(const std::string& name, int* values, uint32_t count) = 0; virtual void SetFloat(const std::string& name, float value) = 0; + virtual void SetFloat2(const std::string& name, const glm::vec2& value) = 0; virtual void SetFloat3(const std::string& name, const glm::vec3& value) = 0; virtual void SetFloat4(const std::string& name, const glm::vec4& value) = 0; virtual void SetMat4(const std::string& name, const glm::mat4& value) = 0; + virtual void Dispatch(uint32_t x, uint32_t y = 1, uint32_t z = 1) = 0; + virtual void DispatchIndirect(uint32_t offset = 0) = 0; + virtual void MemoryBarrier(uint32_t barriers) = 0; + virtual const std::string& GetName() const = 0; static Shader* Create(const std::string& filepath); static Shader* Create(const std::string& name, const std::string& vertexSrc, const std::string& fragmentSrc); + static Shader* CreateCompute(const std::string& name, const std::string& computeSrc); }; class ShaderLibrary diff --git a/src/Rendering/Texture.h b/src/Rendering/Texture.h index eebce85..f17bb1d 100644 --- a/src/Rendering/Texture.h +++ b/src/Rendering/Texture.h @@ -17,11 +17,13 @@ namespace Donut virtual void SetData(void* data, uint32_t size) = 0; virtual void Bind(uint32_t slot = 0) const = 0; + virtual void BindAsImage(uint32_t slot = 0, bool readOnly = false) const = 0; virtual bool operator==(const Texture& other) const = 0; }; - class Texture2D : public Texture + class Texture2D + : public Texture { public: static std::shared_ptr<Texture2D> Create(uint32_t width, uint32_t height); |
