hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2026-08-18 15:00:34 +0200
committerhachem <im@hachem.wtf>2026-08-18 15:00:34 +0200
commitaabbeac3d9e2ac0f293ab43fec71e56091c823e8 (patch)
tree4d986035f451e8511024076b2c94362dbf549712 /src
parentecb6705c7fc4fb085184712567d0e936ea5d0d1f (diff)
fix: macOS compatibility
Diffstat (limited to 'src')
-rw-r--r--src/core/window.cpp13
-rw-r--r--src/engine/engine.cpp110
-rw-r--r--src/engine/engine.h12
-rw-r--r--src/platform/opengl/opengl_framebuffer.cpp16
-rw-r--r--src/platform/opengl/opengl_index_buffer.cpp2
-rw-r--r--src/platform/opengl/opengl_renderer_api.cpp4
-rw-r--r--src/platform/opengl/opengl_shader.cpp17
-rw-r--r--src/platform/opengl/opengl_shader.h2
-rw-r--r--src/platform/opengl/opengl_texture.cpp104
-rw-r--r--src/platform/opengl/opengl_vertex_array.cpp4
-rw-r--r--src/platform/opengl/opengl_vertex_buffer.cpp2
11 files changed, 198 insertions, 88 deletions
diff --git a/src/core/window.cpp b/src/core/window.cpp
index c1d714a..cb93d04 100644
--- a/src/core/window.cpp
+++ b/src/core/window.cpp
@@ -42,6 +42,13 @@ namespace Donut
DONUT_INFO("GLFW initialized successfully");
}
+#ifdef __APPLE__
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
+ glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
+ glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
+#endif
+
m_window = glfwCreateWindow(m_width, m_height, m_title.c_str(), nullptr, nullptr);
if (!m_window)
{
@@ -118,7 +125,9 @@ namespace Donut
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
+#ifndef __APPLE__
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
+#endif
setup_im_gui_fonts();
ThemeManager::set_theme(Theme::Dark);
@@ -131,7 +140,11 @@ namespace Donut
}
ImGui_ImplGlfw_InitForOpenGL(m_window, true);
+#ifdef __APPLE__
+ ImGui_ImplOpenGL3_Init("#version 150");
+#else
ImGui_ImplOpenGL3_Init("#version 130");
+#endif
DONUT_INFO("ImGUI initialized successfully");
}
diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp
index 28cce2f..4b97a7a 100644
--- a/src/engine/engine.cpp
+++ b/src/engine/engine.cpp
@@ -33,7 +33,7 @@ namespace Donut
{ glm::vec4(0.00f, 0.00f, 0.00f, m_sag_a.m_rs), glm::vec4(0, 0, 0, 1), static_cast<float>(m_sag_a.m_mass) }
};
- m_compute_program = create_compute_program("assets/shaders/geodesic.glsl");
+ m_compute_program = Ref<Shader>(Shader::create("assets/shaders/geodesic.glsl"));
m_shader_program = Ref<Shader>(Shader::create("assets/shaders/textured_quad.glsl"));
m_blur_shader = Ref<Shader>(Shader::create("assets/shaders/blur.glsl"));
@@ -60,6 +60,23 @@ namespace Donut
auto result = quad_vao();
m_quad_vao = result.first;
m_texture = result.second;
+
+ if (m_compute_program)
+ {
+ uint32_t prog = m_compute_program->get_renderer_id();
+ struct { const char* name; uint32_t point; } blocks[] =
+ {
+ { "Camera", 1 }, { "Disk", 2 }, { "Objects", 3 }, { "Simulation", 4 }
+ };
+ for (const auto& b : blocks)
+ {
+ uint32_t idx = glGetUniformBlockIndex(prog, b.name);
+ if (idx != GL_INVALID_INDEX)
+ glUniformBlockBinding(prog, idx, b.point);
+ }
+ }
+
+ glGenFramebuffers(1, &m_geodesic_fbo);
}
void Engine::update_window_dimensions()
@@ -126,30 +143,61 @@ namespace Donut
RenderCommand::enable_depth_test();
}
+ void Engine::draw_geodesic_pass(int cw, int ch)
+ {
+ m_quad_vao->bind();
+ RenderCommand::disable_depth_test();
+
+#ifdef __APPLE__
+ const int tile = 24;
+ glEnable(GL_SCISSOR_TEST);
+ for (int y = 0; y < ch; y += tile)
+ {
+ int th = std::min(tile, ch - y);
+ for (int x = 0; x < cw; x += tile)
+ {
+ int tw = std::min(tile, cw - x);
+ glScissor(x, y, tw, th);
+ RenderCommand::draw_arrays(6);
+ glFinish();
+ }
+ }
+ glDisable(GL_SCISSOR_TEST);
+#else
+ RenderCommand::draw_arrays(6);
+#endif
+
+ RenderCommand::enable_depth_test();
+ }
+
void Engine::dispatch_compute(const Camera& cam)
{
auto& hdri_manager = HDRIManager::get();
m_hdri_environment = hdri_manager.get_current_hdri();
-
+
int cw = get_compute_width();
int ch = m_compute_height;
- m_texture->set_data(nullptr, cw * ch * 4);
+ glBindFramebuffer(GL_FRAMEBUFFER, m_geodesic_fbo);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture->get_renderer_id(), 0);
+ glViewport(0, 0, cw, ch);
m_compute_program->bind();
upload_camera_ubo(cam);
upload_disk_ubo();
upload_objects_ubo(m_objects);
upload_simulation_ubo();
- m_texture->bind_as_image(0, false);
-
+ m_compute_program->set_float2("u_Resolution", glm::vec2(static_cast<float>(cw), static_cast<float>(ch)));
+
if (m_hdri_environment)
+ {
m_hdri_environment->bind(5);
-
- uint32_t groups_x = static_cast<uint32_t>(std::ceil(cw / 16.0f));
- uint32_t groups_y = static_cast<uint32_t>(std::ceil(ch / 16.0f));
- m_compute_program->dispatch(groups_x, groups_y, 1);
- m_compute_program->memory_barrier(IMAGE_ACCESS_BARRIER_BIT);
+ m_compute_program->set_int("u_HDRIEnvironment", 5);
+ }
+
+ draw_geodesic_pass(cw, ch);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void Engine::upload_camera_ubo(const Camera& cam)
@@ -235,6 +283,11 @@ namespace Donut
data.early_exit_distance = m_early_exit_distance;
data.time = static_cast<float>(glfwGetTime()) * m_rotation_speed;
+#ifdef __APPLE__
+ data.max_steps_moving = std::min(data.max_steps_moving, 10000);
+ data.max_steps_static = std::min(data.max_steps_static, 10000);
+#endif
+
m_simulation_ubo->set_data(&data, sizeof(data));
m_simulation_ubo->bind(4);
}
@@ -427,21 +480,19 @@ namespace Donut
return;
}
- high_res_framebuffer->bind();
-
- RenderCommand::set_viewport(0, 0, width, height);
- RenderCommand::clear();
-
auto high_res_texture = Texture2D::create(compute_width, compute_height);
if (!high_res_texture)
{
DONUT_ERROR("Failed to create high-resolution texture");
return;
}
-
- high_res_texture->set_data(nullptr, compute_width * compute_height * 4);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, m_geodesic_fbo);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, high_res_texture->get_renderer_id(), 0);
+ glViewport(0, 0, compute_width, compute_height);
+
m_compute_program->bind();
-
+
struct UBOData
{
glm::vec3 pos; float _pad0;
@@ -469,17 +520,24 @@ namespace Donut
m_camera_ubo->set_data(&data, sizeof(UBOData));
m_camera_ubo->bind(1);
-
+
upload_disk_ubo();
upload_objects_ubo(m_objects);
upload_simulation_ubo();
- high_res_texture->bind_as_image(0, false);
-
- uint32_t groups_x = static_cast<uint32_t>(std::ceil(compute_width / 16.0f));
- uint32_t groups_y = static_cast<uint32_t>(std::ceil(compute_height / 16.0f));
- m_compute_program->dispatch(groups_x, groups_y, 1);
- m_compute_program->memory_barrier(IMAGE_ACCESS_BARRIER_BIT);
-
+ m_compute_program->set_float2("u_Resolution", glm::vec2(static_cast<float>(compute_width), static_cast<float>(compute_height)));
+
+ if (m_hdri_environment)
+ {
+ m_hdri_environment->bind(5);
+ m_compute_program->set_int("u_HDRIEnvironment", 5);
+ }
+
+ draw_geodesic_pass(compute_width, compute_height);
+
+ high_res_framebuffer->bind();
+ RenderCommand::set_viewport(0, 0, width, height);
+ RenderCommand::clear();
+
m_shader_program->bind();
m_quad_vao->bind();
diff --git a/src/engine/engine.h b/src/engine/engine.h
index 88e0058..0a50612 100644
--- a/src/engine/engine.h
+++ b/src/engine/engine.h
@@ -89,7 +89,13 @@ namespace Donut
void set_target_fps(int fps) { m_target_fps = fps; }
int get_target_fps() const { return m_target_fps; }
float get_current_fps() const { return m_current_fps; }
- void set_compute_height(int height) { m_compute_height = height; }
+ void set_compute_height(int height)
+ {
+#ifdef __APPLE__
+ if (height > 256) height = 256;
+#endif
+ m_compute_height = height;
+ }
int get_compute_height() const { return m_compute_height; }
int get_compute_width() const { return (m_width * m_compute_height) / m_height; }
void update_compute_dimensions();
@@ -125,6 +131,8 @@ namespace Donut
private:
Ref<Shader> create_compute_program(const char* path);
std::pair<Ref<VertexArray>, Ref<Texture2D>> quad_vao();
+
+ void draw_geodesic_pass(int cw, int ch);
private:
Ref<VertexArray> m_quad_vao;
Ref<Texture2D> m_texture;
@@ -137,6 +145,8 @@ namespace Donut
Ref<UniformBuffer> m_objects_ubo;
Ref<UniformBuffer> m_simulation_ubo;
+ uint32_t m_geodesic_fbo = 0;
+
int m_width;
int m_height;
float m_width_f = 100.0f*1e10f;
diff --git a/src/platform/opengl/opengl_framebuffer.cpp b/src/platform/opengl/opengl_framebuffer.cpp
index c5b8fe2..9040994 100644
--- a/src/platform/opengl/opengl_framebuffer.cpp
+++ b/src/platform/opengl/opengl_framebuffer.cpp
@@ -19,7 +19,7 @@ namespace Donut
static void create_textures(bool multisampled, uint32_t* out_id, uint32_t count)
{
- glCreateTextures(texture_target(multisampled), count, out_id);
+ glGenTextures(count, out_id);
}
static void attach_color_texture(uint32_t id, int samples, GLenum internal_format, GLenum format, uint32_t width, uint32_t height, int index)
@@ -31,7 +31,8 @@ namespace Donut
}
else
{
- glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, format, GL_UNSIGNED_BYTE, nullptr);
+ GLenum type = (format == GL_RED_INTEGER) ? GL_INT : GL_UNSIGNED_BYTE;
+ glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, format, type, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -52,7 +53,9 @@ namespace Donut
}
else
{
- glTexStorage2D(GL_TEXTURE_2D, 1, format, width, height);
+ GLenum depth_format = (format == GL_DEPTH24_STENCIL8) ? GL_DEPTH_STENCIL : GL_DEPTH_COMPONENT;
+ GLenum depth_type = (format == GL_DEPTH24_STENCIL8) ? GL_UNSIGNED_INT_24_8 : GL_FLOAT;
+ glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, depth_format, depth_type, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -118,7 +121,7 @@ namespace Donut
m_depth_attachment = 0;
}
- glCreateFramebuffers(1, &m_renderer_id);
+ glGenFramebuffers(1, &m_renderer_id);
glBindFramebuffer(GL_FRAMEBUFFER, m_renderer_id);
bool multisample = m_specification.Samples > 1;
@@ -230,8 +233,7 @@ namespace Donut
void OpenGLFramebuffer::clear_attachment(uint32_t attachment_index, int value)
{
- auto& spec = m_color_attachment_specifications[attachment_index];
- glClearTexImage(m_color_attachments[attachment_index], 0,
- Utils::donut_fb_texture_format_to_gl(spec.texture_format), GL_INT, &value);
+ glBindFramebuffer(GL_FRAMEBUFFER, m_renderer_id);
+ glClearBufferiv(GL_COLOR, static_cast<GLint>(attachment_index), &value);
}
};
diff --git a/src/platform/opengl/opengl_index_buffer.cpp b/src/platform/opengl/opengl_index_buffer.cpp
index fac0585..d8ecb1d 100644
--- a/src/platform/opengl/opengl_index_buffer.cpp
+++ b/src/platform/opengl/opengl_index_buffer.cpp
@@ -6,7 +6,7 @@ namespace Donut
OpenGLIndexBuffer::OpenGLIndexBuffer(const uint32_t* indices, uint32_t count)
: m_count(count)
{
- glCreateBuffers(1, &m_renderer_id);
+ glGenBuffers(1, &m_renderer_id);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_renderer_id);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, count * sizeof(uint32_t), indices, GL_STATIC_DRAW);
}
diff --git a/src/platform/opengl/opengl_renderer_api.cpp b/src/platform/opengl/opengl_renderer_api.cpp
index 0012911..ed5ce78 100644
--- a/src/platform/opengl/opengl_renderer_api.cpp
+++ b/src/platform/opengl/opengl_renderer_api.cpp
@@ -103,7 +103,9 @@ namespace Donut
void OpenGLRendererAPI::bind_image_texture(uint32_t texture_id, uint32_t slot, bool read_only)
{
- glBindImageTexture(slot, texture_id, 0, GL_FALSE, 0,
+ if (glBindImageTexture == nullptr)
+ return;
+ glBindImageTexture(slot, texture_id, 0, GL_FALSE, 0,
read_only ? GL_READ_ONLY : GL_WRITE_ONLY, GL_RGBA8);
}
diff --git a/src/platform/opengl/opengl_shader.cpp b/src/platform/opengl/opengl_shader.cpp
index 3b0108e..ddcd5e2 100644
--- a/src/platform/opengl/opengl_shader.cpp
+++ b/src/platform/opengl/opengl_shader.cpp
@@ -120,7 +120,12 @@ namespace Donut
std::vector<char> info_log(max_length);
glGetShaderInfoLog(shader, max_length, &max_length, &info_log[0]);
glDeleteShader(shader);
- std::cout << "Shader compilation failure!" << std::endl << info_log.data() << std::endl;
+ for (auto id : glShaderIDs)
+ glDeleteShader(id);
+ glDeleteProgram(program);
+ m_renderer_id = 0;
+ const char* log = info_log.empty() ? "" : info_log.data();
+ std::cout << "Shader compilation failure!" << std::endl << log << std::endl;
return;
}
glAttachShader(program, shader);
@@ -141,7 +146,9 @@ namespace Donut
glDeleteProgram(m_renderer_id);
for (auto id : glShaderIDs)
glDeleteShader(id);
- std::cout << "Shader link failure!" << std::endl << info_log.data() << std::endl;
+ m_renderer_id = 0;
+ const char* log = info_log.empty() ? "" : info_log.data();
+ std::cout << "Shader link failure!" << std::endl << log << std::endl;
return;
}
@@ -247,16 +254,22 @@ namespace Donut
void OpenGLShader::dispatch(uint32_t x, uint32_t y, uint32_t z)
{
+ if (m_renderer_id == 0 || glDispatchCompute == nullptr)
+ return;
glDispatchCompute(x, y, z);
}
void OpenGLShader::dispatch_indirect(uint32_t offset)
{
+ if (m_renderer_id == 0 || glDispatchComputeIndirect == nullptr)
+ return;
glDispatchComputeIndirect(offset);
}
void OpenGLShader::memory_barrier(uint32_t barriers)
{
+ if (glMemoryBarrier == nullptr)
+ return;
glMemoryBarrier(barriers);
}
};
diff --git a/src/platform/opengl/opengl_shader.h b/src/platform/opengl/opengl_shader.h
index 71e20a5..29c23a4 100644
--- a/src/platform/opengl/opengl_shader.h
+++ b/src/platform/opengl/opengl_shader.h
@@ -48,7 +48,7 @@ namespace Donut
std::unordered_map<uint32_t, std::string> pre_process(const std::string& source);
void compile(const std::unordered_map<uint32_t, std::string>& shader_sources);
private:
- uint32_t m_renderer_id;
+ uint32_t m_renderer_id = 0;
std::string m_name;
};
};
diff --git a/src/platform/opengl/opengl_texture.cpp b/src/platform/opengl/opengl_texture.cpp
index 34a5117..8471ee8 100644
--- a/src/platform/opengl/opengl_texture.cpp
+++ b/src/platform/opengl/opengl_texture.cpp
@@ -16,14 +16,14 @@ namespace Donut
m_internal_format = GL_RGBA8;
m_data_format = GL_RGBA;
- glCreateTextures(GL_TEXTURE_2D, 1, &m_renderer_id);
- glTextureStorage2D(m_renderer_id, 1, m_internal_format, m_width, m_height);
+ glGenTextures(1, &m_renderer_id);
+ glBindTexture(GL_TEXTURE_2D, m_renderer_id);
+ glTexImage2D(GL_TEXTURE_2D, 0, m_internal_format, m_width, m_height, 0, m_data_format, GL_UNSIGNED_BYTE, nullptr);
- glTextureParameteri(m_renderer_id, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTextureParameteri(m_renderer_id, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- glTextureParameteri(m_renderer_id, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTextureParameteri(m_renderer_id, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
OpenGLTexture2D::OpenGLTexture2D(const std::string& path)
@@ -34,17 +34,17 @@ namespace Donut
m_internal_format = GL_RGBA8;
m_data_format = GL_RGBA;
- glCreateTextures(GL_TEXTURE_2D, 1, &m_renderer_id);
- glTextureStorage2D(m_renderer_id, 1, m_internal_format, m_width, m_height);
-
- glTextureParameteri(m_renderer_id, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTextureParameteri(m_renderer_id, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glGenTextures(1, &m_renderer_id);
+ glBindTexture(GL_TEXTURE_2D, m_renderer_id);
+ glTexImage2D(GL_TEXTURE_2D, 0, m_internal_format, m_width, m_height, 0, m_data_format, GL_UNSIGNED_BYTE, nullptr);
- glTextureParameteri(m_renderer_id, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTextureParameteri(m_renderer_id, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
uint32_t white_pixel = 0xFFFFFFFF;
- glTextureSubImage2D(m_renderer_id, 0, 0, 0, m_width, m_height, m_data_format, GL_UNSIGNED_BYTE, &white_pixel);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_width, m_height, m_data_format, GL_UNSIGNED_BYTE, &white_pixel);
DONUT_INFO("Created default texture (stb_image not available for loading: ", path, ")");
}
@@ -62,17 +62,21 @@ namespace Donut
DONUT_ERROR("Data must be entire texture!");
return;
}
-
- glTextureSubImage2D(m_renderer_id, 0, 0, 0, m_width, m_height, m_data_format, GL_UNSIGNED_BYTE, data);
+
+ glBindTexture(GL_TEXTURE_2D, m_renderer_id);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_width, m_height, m_data_format, GL_UNSIGNED_BYTE, data);
}
void OpenGLTexture2D::bind(uint32_t slot) const
{
- glBindTextureUnit(slot, m_renderer_id);
+ glActiveTexture(GL_TEXTURE0 + slot);
+ glBindTexture(GL_TEXTURE_2D, m_renderer_id);
}
void OpenGLTexture2D::bind_as_image(uint32_t slot, bool read_only) const
{
+ if (glBindImageTexture == nullptr)
+ return;
GLenum access = read_only ? GL_READ_ONLY : GL_WRITE_ONLY;
glBindImageTexture(slot, m_renderer_id, 0, GL_FALSE, 0, access, m_internal_format);
}
@@ -80,17 +84,19 @@ namespace Donut
OpenGLCubemapTexture::OpenGLCubemapTexture(uint32_t width, uint32_t height)
: m_width(width), m_height(height)
{
- m_internal_format = GL_RGB16F;
- m_data_format = GL_RGB;
+ m_internal_format = GL_RGBA16F;
+ m_data_format = GL_RGBA;
- glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &m_renderer_id);
- glTextureStorage2D(m_renderer_id, 1, m_internal_format, m_width, m_height);
+ glGenTextures(1, &m_renderer_id);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, m_renderer_id);
+ for (uint32_t i = 0; i < 6; ++i)
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, m_internal_format, m_width, m_height, 0, m_data_format, GL_FLOAT, nullptr);
- glTextureParameteri(m_renderer_id, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTextureParameteri(m_renderer_id, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTextureParameteri(m_renderer_id, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTextureParameteri(m_renderer_id, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTextureParameteri(m_renderer_id, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
}
OpenGLCubemapTexture::OpenGLCubemapTexture(const std::string& path)
@@ -98,17 +104,19 @@ namespace Donut
{
m_width = 1024;
m_height = 1024;
- m_internal_format = GL_RGB16F;
- m_data_format = GL_RGB;
+ m_internal_format = GL_RGBA16F;
+ m_data_format = GL_RGBA;
- glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &m_renderer_id);
- glTextureStorage2D(m_renderer_id, 1, m_internal_format, m_width, m_height);
+ glGenTextures(1, &m_renderer_id);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, m_renderer_id);
+ for (uint32_t i = 0; i < 6; ++i)
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, m_internal_format, m_width, m_height, 0, m_data_format, GL_FLOAT, nullptr);
- glTextureParameteri(m_renderer_id, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTextureParameteri(m_renderer_id, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTextureParameteri(m_renderer_id, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTextureParameteri(m_renderer_id, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTextureParameteri(m_renderer_id, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
load_hdri(path);
}
@@ -123,11 +131,11 @@ namespace Donut
stbi_set_flip_vertically_on_load(true);
int width, height, channels;
float* hdr_data = stbi_loadf(path.c_str(), &width, &height, &channels, 3);
-
+
if (!hdr_data)
{
DONUT_ERROR("Failed to load HDRI: {}", path);
- float default_sky[6 * 4] =
+ float default_sky[6 * 4] =
{
0.5f, 0.7f, 1.0f, 1.0f,
0.5f, 0.7f, 1.0f, 1.0f,
@@ -136,15 +144,16 @@ namespace Donut
0.5f, 0.7f, 1.0f, 1.0f,
0.5f, 0.7f, 1.0f, 1.0f
};
-
+
+ glBindTexture(GL_TEXTURE_CUBE_MAP, m_renderer_id);
for (int i = 0; i < 6; ++i)
- glTextureSubImage3D(m_renderer_id, 0, 0, 0, i, 1, 1, 1, GL_RGBA, GL_FLOAT, &default_sky[i * 4]);
+ glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, 1, 1, GL_RGBA, GL_FLOAT, &default_sky[i * 4]);
return;
}
convert_equirectangular_to_cubemap(hdr_data, width, height);
stbi_image_free(hdr_data);
-
+
DONUT_INFO("Successfully loaded HDRI: {} ({}x{})", path, width, height);
}
@@ -174,10 +183,10 @@ namespace Donut
DONUT_ERROR("Failed to create equirectangular to cubemap shader");
return;
}
-
+
uint32_t shader_program = equirect_shader->get_renderer_id();
- float vertices[] =
+ float vertices[] =
{
-1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
@@ -197,7 +206,7 @@ namespace Donut
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glm::mat4 capture_projection = glm::perspective(glm::radians(90.0f), 1.0f, 0.1f, 10.0f);
- glm::mat4 capture_views[] =
+ glm::mat4 capture_views[] =
{
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3( 1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
@@ -224,10 +233,10 @@ namespace Donut
glDrawArrays(GL_TRIANGLES, 0, 36);
}
glBindVertexArray(0);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteVertexArrays(1, &cube_vao);
glDeleteBuffers(1, &cube_vbo);
- glDeleteProgram(shader_program);
glDeleteTextures(1, &hdr_texture);
glDeleteFramebuffers(1, &capture_fbo);
glDeleteRenderbuffers(1, &capture_rbo);
@@ -240,11 +249,14 @@ namespace Donut
void OpenGLCubemapTexture::bind(uint32_t slot) const
{
- glBindTextureUnit(slot, m_renderer_id);
+ glActiveTexture(GL_TEXTURE0 + slot);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, m_renderer_id);
}
void OpenGLCubemapTexture::bind_as_image(uint32_t slot, bool read_only) const
{
+ if (glBindImageTexture == nullptr)
+ return;
GLenum access = read_only ? GL_READ_ONLY : GL_WRITE_ONLY;
glBindImageTexture(slot, m_renderer_id, 0, GL_TRUE, 0, access, m_internal_format);
}
diff --git a/src/platform/opengl/opengl_vertex_array.cpp b/src/platform/opengl/opengl_vertex_array.cpp
index e2fb766..f3347f4 100644
--- a/src/platform/opengl/opengl_vertex_array.cpp
+++ b/src/platform/opengl/opengl_vertex_array.cpp
@@ -6,9 +6,9 @@
namespace Donut
{
- OpenGLVertexArray::OpenGLVertexArray()
+ OpenGLVertexArray::OpenGLVertexArray()
{
- glCreateVertexArrays(1, &m_renderer_id);
+ glGenVertexArrays(1, &m_renderer_id);
}
OpenGLVertexArray::~OpenGLVertexArray()
diff --git a/src/platform/opengl/opengl_vertex_buffer.cpp b/src/platform/opengl/opengl_vertex_buffer.cpp
index 543a7d6..643b315 100644
--- a/src/platform/opengl/opengl_vertex_buffer.cpp
+++ b/src/platform/opengl/opengl_vertex_buffer.cpp
@@ -7,7 +7,7 @@ namespace Donut
{
OpenGLVertexBuffer::OpenGLVertexBuffer(const void* data, uint32_t size)
{
- glCreateBuffers(1, &m_renderer_id);
+ glGenBuffers(1, &m_renderer_id);
glBindBuffer(GL_ARRAY_BUFFER, m_renderer_id);
glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
}