From bb1108abb2ae455500a65fc1c51e5f0bfd9456a9 Mon Sep 17 00:00:00 2001 From: Adrien Prokopowicz Date: Mon, 25 Mar 2024 19:09:03 +0100 Subject: [PATCH] Fix windows OpenGL context creation --- src/gl/win.rs | 12 ++++-------- src/win/win32_window.rs | 29 ++++++++++++++++++++++++++++- src/win/window.rs | 14 +++++--------- 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/gl/win.rs b/src/gl/win.rs index 655a8071..34ccaaa0 100644 --- a/src/gl/win.rs +++ b/src/gl/win.rs @@ -1,7 +1,7 @@ use std::ffi::{c_void, CString, OsStr}; use std::os::windows::ffi::OsStrExt; -use raw_window_handle::RawWindowHandle; +use raw_window_handle::{RawWindowHandle, Win32WindowHandle}; use winapi::shared::minwindef::{HINSTANCE, HMODULE}; use winapi::shared::ntdef::WCHAR; @@ -77,13 +77,9 @@ extern "C" { } impl GlContext { - pub unsafe fn create(parent: &RawWindowHandle, config: GlConfig) -> Result { - let handle = if let RawWindowHandle::Win32(handle) = parent { - handle - } else { - return Err(GlError::InvalidWindowHandle); - }; - + pub unsafe fn create( + handle: &Win32WindowHandle, config: GlConfig, + ) -> Result { if handle.hwnd.is_null() { return Err(GlError::InvalidWindowHandle); } diff --git a/src/win/win32_window.rs b/src/win/win32_window.rs index 1baba2fc..24445648 100644 --- a/src/win/win32_window.rs +++ b/src/win/win32_window.rs @@ -1,6 +1,8 @@ use crate::win::util::to_wstr; use crate::{PhySize, Size, WindowInfo, WindowOpenOptions, WindowScalePolicy}; +use raw_window_handle::{RawWindowHandle, Win32WindowHandle}; use std::cell::Cell; +use std::ffi::c_void; use std::ptr::null_mut; use winapi::shared::minwindef::{DWORD, UINT}; use winapi::shared::windef::{HWND, RECT}; @@ -23,6 +25,9 @@ pub(crate) struct Win32Window { scale_policy: WindowScalePolicy, frame_timer_started: Cell, + + #[cfg(feature = "opengl")] + pub(crate) gl_context: Option>, } impl Win32Window { @@ -77,13 +82,15 @@ impl Win32Window { }; // TODO: GL context - let window = Self { + let mut window = Self { _class: class, handle, style_flags, current_size: Cell::new(initial_size), scale_policy: options.scale, frame_timer_started: Cell::new(false), + #[cfg(feature = "opengl")] + gl_context: None, }; // FIXME: this should NOT be changed if the window is part of an host @@ -96,6 +103,9 @@ impl Win32Window { // Now we can get the actual dpi of the window. window.check_for_dpi_changes(); + + #[cfg(feature = "opengl")] + window.create_gl_context(options); window.start_frame_timer(); window @@ -107,6 +117,23 @@ impl Win32Window { dpi as f64 / 96.0 } + pub fn raw_window_handle(&self) -> Win32WindowHandle { + let mut handle = Win32WindowHandle::empty(); + handle.hwnd = self.handle() as *mut c_void; + handle + } + + #[cfg(feature = "opengl")] + fn create_gl_context(&mut self, options: &WindowOpenOptions) { + self.gl_context = options.gl_config.as_ref().map(|gl_config| { + let ctx = + // SAFETY: TODO + unsafe { crate::gl::win::GlContext::create(&self.raw_window_handle(), gl_config.clone()) } + .expect("Could not create OpenGL context"); + std::rc::Rc::new(ctx) + }); + } + fn resize(&self, size: PhySize) { let window_size = client_size_to_window_size(size, self.style_flags); diff --git a/src/win/window.rs b/src/win/window.rs index 0a2d0e9e..95302936 100644 --- a/src/win/window.rs +++ b/src/win/window.rs @@ -3,16 +3,15 @@ use winapi::um::ole2::OleInitialize; use std::cell::RefCell; use std::collections::VecDeque; -use std::ffi::c_void; use std::ptr::null_mut; use std::rc::Rc; use raw_window_handle::{ - HasRawWindowHandle, RawDisplayHandle, RawWindowHandle, Win32WindowHandle, WindowsDisplayHandle, + HasRawWindowHandle, RawDisplayHandle, RawWindowHandle, WindowsDisplayHandle, }; #[cfg(feature = "opengl")] -use crate::gl::GlContext; +use crate::gl::win::GlContext; use crate::win::handle::{WindowHandle, WindowHandleTransmitter}; use crate::win::proc::ProcState; use crate::win::win32_window::Win32Window; @@ -104,15 +103,12 @@ impl Window { } #[cfg(feature = "opengl")] - pub fn gl_context(&self) -> Option<&GlContext> { - self.state.gl_context.as_ref() + pub fn gl_context(&self) -> Option> { + self.win32_window.gl_context.as_ref().map(Rc::downgrade) } pub fn raw_window_handle(&self) -> RawWindowHandle { - let mut handle = Win32WindowHandle::empty(); - handle.hwnd = self.win32_window.handle() as *mut c_void; - - handle.into() + self.win32_window.raw_window_handle().into() } pub fn raw_display_handle(&self) -> RawDisplayHandle { WindowsDisplayHandle::empty().into()