diff options
| author | hachem <im@hachem.wtf> | 2026-08-18 15:00:34 +0200 |
|---|---|---|
| committer | hachem <im@hachem.wtf> | 2026-08-18 15:00:34 +0200 |
| commit | aabbeac3d9e2ac0f293ab43fec71e56091c823e8 (patch) | |
| tree | 4d986035f451e8511024076b2c94362dbf549712 /src | |
| parent | ecb6705c7fc4fb085184712567d0e936ea5d0d1f (diff) | |
fix: macOS compatibility
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/window.cpp | 13 | ||||
| -rw-r--r-- | src/engine/engine.cpp | 110 | ||||
| -rw-r--r-- | src/engine/engine.h | 12 | ||||
| -rw-r--r-- | src/platform/opengl/opengl_framebuffer.cpp | 16 | ||||
| -rw-r--r-- | src/platform/opengl/opengl_index_buffer.cpp | 2 | ||||
| -rw-r--r-- | src/platform/opengl/opengl_renderer_api.cpp | 4 | ||||
| -rw-r--r-- | src/platform/opengl/opengl_shader.cpp | 17 | ||||
| -rw-r--r-- | src/platform/opengl/opengl_shader.h | 2 | ||||
| -rw-r--r-- | src/platform/opengl/opengl_texture.cpp | 104 | ||||
| -rw-r--r-- | src/platform/opengl/opengl_vertex_array.cpp | 4 | ||||
| -rw-r--r-- | src/platform/opengl/opengl_vertex_buffer.cpp | 2 |
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); } |
