Skip to content

Instantly share code, notes, and snippets.

@hikari-no-yume
Created December 31, 2022 12:34
Show Gist options
  • Save hikari-no-yume/9ed05e64c8b967a4b0a1315368139942 to your computer and use it in GitHub Desktop.
Save hikari-no-yume/9ed05e64c8b967a4b0a1315368139942 to your computer and use it in GitHub Desktop.
Test having multiple OpenGL versions in the same window with rust-sdl2 (spoiler: it works!)
use sdl2::video::{GLContext, GLProfile, Window};
use sdl2::{EventPump, VideoSubsystem};
use std::time::Instant;
fn test_opengl(
video_ctx: &VideoSubsystem,
window: &Window,
gl_ctx: &GLContext,
color: (f32, f32, f32, f32),
) {
window.gl_make_current(gl_ctx).unwrap();
#[allow(non_snake_case)]
unsafe {
let glClearColor: unsafe extern "C" fn(f32, f32, f32, f32) =
std::mem::transmute(video_ctx.gl_get_proc_address("glClearColor"));
let glClear: unsafe extern "C" fn(u32) =
std::mem::transmute(video_ctx.gl_get_proc_address("glClear"));
let glGetString: unsafe extern "C" fn(u32) -> *const u8 =
std::mem::transmute(video_ctx.gl_get_proc_address("glGetString"));
glClearColor(color.0, color.1, color.2, color.3);
// GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
glClear(0x00004000 | 0x00000400 | 0x00000100);
// GL_VERSION
let version_str = std::ffi::CStr::from_ptr(glGetString(0x1F02) as *const _);
println!("glGetString(GL_VERSION): {:?}", version_str.to_str());
}
window.gl_swap_window();
}
fn make_gl_ctx(
video_ctx: &VideoSubsystem,
window: &Window,
version: (u8, u8),
profile: GLProfile,
) -> GLContext {
let (major, minor) = version;
let attr = video_ctx.gl_attr();
attr.set_context_major_version(major);
attr.set_context_minor_version(minor);
attr.set_context_profile(profile);
window.gl_create_context().unwrap()
}
fn wait(pump: &mut EventPump, secs: u64) {
let start = Instant::now();
loop {
let _ = pump.poll_event();
if Instant::now().duration_since(start).as_secs() >= secs {
return;
}
}
}
pub fn main() {
let sdl_ctx = sdl2::init().unwrap();
let video_ctx = sdl_ctx.video().unwrap();
let window = video_ctx
.window("Test Window", 128, 128)
.opengl()
.build()
.unwrap();
let mut event_pump = sdl_ctx.event_pump().unwrap();
let ctx1 = make_gl_ctx(&video_ctx, &window, (2, 1), GLProfile::Compatibility);
test_opengl(&video_ctx, &window, &ctx1, (1.0, 0.0, 0.0, 0.0));
wait(&mut event_pump, 3);
let ctx2 = make_gl_ctx(&video_ctx, &window, (3, 2), sdl2::video::GLProfile::Core);
test_opengl(&video_ctx, &window, &ctx2, (0.0, 1.0, 0.0, 0.0));
wait(&mut event_pump, 3);
test_opengl(&video_ctx, &window, &ctx1, (0.0, 0.0, 1.0, 0.0));
wait(&mut event_pump, 3);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment