mirror of
https://github.com/rust-windowing/winit.git
synced 2026-09-03 07:10:05 -04:00
Merge pull request #301 from tomaka/win32
Use the WGL API to determine extended pixel format, plus fix creation
This commit is contained in:
11
src/lib.rs
11
src/lib.rs
@@ -195,7 +195,9 @@ pub enum MouseCursor {
|
|||||||
|
|
||||||
/// Describes a possible format. Unused.
|
/// Describes a possible format. Unused.
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
pub struct PixelFormat {
|
pub struct PixelFormat {
|
||||||
|
pub hardware_accelerated: bool,
|
||||||
pub red_bits: u8,
|
pub red_bits: u8,
|
||||||
pub green_bits: u8,
|
pub green_bits: u8,
|
||||||
pub blue_bits: u8,
|
pub blue_bits: u8,
|
||||||
@@ -282,6 +284,7 @@ impl<'a> BuilderAttribs<'a> {
|
|||||||
where I: Iterator<Item=(T, PixelFormat)>, T: Clone
|
where I: Iterator<Item=(T, PixelFormat)>, T: Clone
|
||||||
{
|
{
|
||||||
let mut current_result = None;
|
let mut current_result = None;
|
||||||
|
let mut current_software_result = None;
|
||||||
|
|
||||||
// TODO: do this more properly
|
// TODO: do this more properly
|
||||||
for (id, format) in iter {
|
for (id, format) in iter {
|
||||||
@@ -309,9 +312,13 @@ impl<'a> BuilderAttribs<'a> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
current_result = Some((id, format));
|
current_software_result = Some((id.clone(), format.clone()));
|
||||||
|
if format.hardware_accelerated {
|
||||||
|
current_result = Some((id, format));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
current_result.expect("Could not find compliant pixel format")
|
current_result.or(current_software_result)
|
||||||
|
.expect("Could not find compliant pixel format")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,9 +99,8 @@ fn init(title: Vec<u16>, builder: BuilderAttribs<'static>, builder_sharelists: O
|
|||||||
// adjusting the window coordinates using the style
|
// adjusting the window coordinates using the style
|
||||||
unsafe { user32::AdjustWindowRectEx(&mut rect, style, 0, ex_style) };
|
unsafe { user32::AdjustWindowRectEx(&mut rect, style, 0, ex_style) };
|
||||||
|
|
||||||
// getting the address of wglCreateContextAttribsARB and the pixel format
|
// getting the address of wglCreateContextAttribsARB
|
||||||
// that we will use
|
let extra_functions = {
|
||||||
let (extra_functions, pixel_format) = {
|
|
||||||
// creating a dummy invisible window for GL initialization
|
// creating a dummy invisible window for GL initialization
|
||||||
let dummy_window = unsafe {
|
let dummy_window = unsafe {
|
||||||
let handle = user32::CreateWindowExW(ex_style, class_name.as_ptr(),
|
let handle = user32::CreateWindowExW(ex_style, class_name.as_ptr(),
|
||||||
@@ -132,32 +131,11 @@ fn init(title: Vec<u16>, builder: BuilderAttribs<'static>, builder_sharelists: O
|
|||||||
hdc
|
hdc
|
||||||
};
|
};
|
||||||
|
|
||||||
// getting the pixel format that we will use
|
// getting the pixel format that we will use and setting it
|
||||||
let pixel_format = {
|
{
|
||||||
let formats = enumerate_native_pixel_formats(dummy_hdc);
|
let formats = enumerate_native_pixel_formats(dummy_hdc);
|
||||||
let (id, _) = builder.choose_pixel_format(formats.into_iter().map(|(a, b)| (b, a)));
|
let (id, _) = builder.choose_pixel_format(formats.into_iter().map(|(a, b)| (b, a)));
|
||||||
|
try!(set_pixel_format(dummy_hdc, id));
|
||||||
let mut output: winapi::PIXELFORMATDESCRIPTOR = unsafe { mem::zeroed() };
|
|
||||||
if unsafe { gdi32::DescribePixelFormat(dummy_hdc, id,
|
|
||||||
mem::size_of::<winapi::PIXELFORMATDESCRIPTOR>() as winapi::UINT, &mut output) } == 0
|
|
||||||
{
|
|
||||||
let err = Err(OsError(format!("DescribePixelFormat function failed: {}",
|
|
||||||
os::error_string(os::errno()))));
|
|
||||||
unsafe { user32::DestroyWindow(dummy_window); }
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
output
|
|
||||||
};
|
|
||||||
|
|
||||||
// calling SetPixelFormat
|
|
||||||
unsafe {
|
|
||||||
if gdi32::SetPixelFormat(dummy_hdc, 1, &pixel_format) == 0 {
|
|
||||||
let err = Err(OsError(format!("SetPixelFormat function failed: {}",
|
|
||||||
os::error_string(os::errno()))));
|
|
||||||
user32::DestroyWindow(dummy_window);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// creating the dummy OpenGL context
|
// creating the dummy OpenGL context
|
||||||
@@ -186,7 +164,7 @@ fn init(title: Vec<u16>, builder: BuilderAttribs<'static>, builder_sharelists: O
|
|||||||
unsafe { user32::DestroyWindow(dummy_window); }
|
unsafe { user32::DestroyWindow(dummy_window); }
|
||||||
|
|
||||||
// returning the address
|
// returning the address
|
||||||
(extra_functions, pixel_format)
|
extra_functions
|
||||||
};
|
};
|
||||||
|
|
||||||
// creating the real window this time
|
// creating the real window this time
|
||||||
@@ -233,13 +211,15 @@ fn init(title: Vec<u16>, builder: BuilderAttribs<'static>, builder_sharelists: O
|
|||||||
};
|
};
|
||||||
|
|
||||||
// calling SetPixelFormat
|
// calling SetPixelFormat
|
||||||
unsafe {
|
{
|
||||||
if gdi32::SetPixelFormat(hdc, 1, &pixel_format) == 0 {
|
let formats = if extra_functions.GetPixelFormatAttribivARB.is_loaded() {
|
||||||
let err = Err(OsError(format!("SetPixelFormat function failed: {}",
|
enumerate_arb_pixel_formats(&extra_functions, hdc)
|
||||||
os::error_string(os::errno()))));
|
} else {
|
||||||
user32::DestroyWindow(real_window);
|
enumerate_native_pixel_formats(hdc)
|
||||||
return err;
|
};
|
||||||
}
|
|
||||||
|
let (id, _) = builder.choose_pixel_format(formats.into_iter().map(|(a, b)| (b, a)));
|
||||||
|
try!(set_pixel_format(hdc, id));
|
||||||
}
|
}
|
||||||
|
|
||||||
// creating the OpenGL context
|
// creating the OpenGL context
|
||||||
@@ -431,13 +411,8 @@ fn enumerate_native_pixel_formats(hdc: winapi::HDC) -> Vec<(PixelFormat, libc::c
|
|||||||
if (output.dwFlags & winapi::PFD_DRAW_TO_WINDOW) == 0 {
|
if (output.dwFlags & winapi::PFD_DRAW_TO_WINDOW) == 0 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (output.dwFlags & winapi::PFD_SUPPORT_OPENGL) == 0 {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (output.dwFlags & winapi::PFD_GENERIC_ACCELERATED) == 0 &&
|
if (output.dwFlags & winapi::PFD_SUPPORT_OPENGL) == 0 {
|
||||||
(output.dwFlags & winapi::PFD_GENERIC_FORMAT) == 0
|
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,6 +421,7 @@ fn enumerate_native_pixel_formats(hdc: winapi::HDC) -> Vec<(PixelFormat, libc::c
|
|||||||
}
|
}
|
||||||
|
|
||||||
result.push((PixelFormat {
|
result.push((PixelFormat {
|
||||||
|
hardware_accelerated: (output.dwFlags & winapi::PFD_GENERIC_FORMAT) == 0,
|
||||||
red_bits: output.cRedBits,
|
red_bits: output.cRedBits,
|
||||||
green_bits: output.cGreenBits,
|
green_bits: output.cGreenBits,
|
||||||
blue_bits: output.cBlueBits,
|
blue_bits: output.cBlueBits,
|
||||||
@@ -496,6 +472,7 @@ fn enumerate_arb_pixel_formats(extra: &gl::wgl_extra::Wgl, hdc: winapi::HDC)
|
|||||||
}
|
}
|
||||||
|
|
||||||
result.push((PixelFormat {
|
result.push((PixelFormat {
|
||||||
|
hardware_accelerated: true,
|
||||||
red_bits: get_info(index, gl::wgl_extra::RED_BITS_ARB) as u8,
|
red_bits: get_info(index, gl::wgl_extra::RED_BITS_ARB) as u8,
|
||||||
green_bits: get_info(index, gl::wgl_extra::GREEN_BITS_ARB) as u8,
|
green_bits: get_info(index, gl::wgl_extra::GREEN_BITS_ARB) as u8,
|
||||||
blue_bits: get_info(index, gl::wgl_extra::BLUE_BITS_ARB) as u8,
|
blue_bits: get_info(index, gl::wgl_extra::BLUE_BITS_ARB) as u8,
|
||||||
@@ -512,6 +489,24 @@ fn enumerate_arb_pixel_formats(extra: &gl::wgl_extra::Wgl, hdc: winapi::HDC)
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_pixel_format(hdc: winapi::HDC, id: libc::c_int) -> Result<(), CreationError> {
|
||||||
|
let mut output: winapi::PIXELFORMATDESCRIPTOR = unsafe { mem::zeroed() };
|
||||||
|
|
||||||
|
if unsafe { gdi32::DescribePixelFormat(hdc, id,
|
||||||
|
mem::size_of::<winapi::PIXELFORMATDESCRIPTOR>() as winapi::UINT, &mut output) } == 0
|
||||||
|
{
|
||||||
|
return Err(OsError(format!("DescribePixelFormat function failed: {}",
|
||||||
|
os::error_string(os::errno()))));
|
||||||
|
}
|
||||||
|
|
||||||
|
if unsafe { gdi32::SetPixelFormat(hdc, id, &output) } == 0 {
|
||||||
|
return Err(OsError(format!("SetPixelFormat function failed: {}",
|
||||||
|
os::error_string(os::errno()))));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn load_opengl32_dll() -> Result<winapi::HMODULE, CreationError> {
|
fn load_opengl32_dll() -> Result<winapi::HMODULE, CreationError> {
|
||||||
let name = "opengl32.dll".utf16_units().chain(Some(0).into_iter())
|
let name = "opengl32.dll".utf16_units().chain(Some(0).into_iter())
|
||||||
.collect::<Vec<u16>>().as_ptr();
|
.collect::<Vec<u16>>().as_ptr();
|
||||||
|
|||||||
Reference in New Issue
Block a user