clear color buffer on vid refresh

This commit is contained in:
lifning 2021-08-20 22:17:38 -07:00
parent f954fe9ffb
commit 0c5d0b5338
2 changed files with 33 additions and 9 deletions

View File

@ -210,6 +210,12 @@ impl RetroCallbacks for RetroComponentBase {
}
}
fn video_refresh_hw(&mut self, width: c_uint, height: c_uint) {
for comp in &mut self.components {
comp.video_refresh_hw(width, height);
}
}
fn audio_sample(&mut self, left: i16, right: i16) {
for comp in &mut self.components {
comp.audio_sample(left, right);

View File

@ -4,9 +4,14 @@ use crate::prelude::*;
use std::ffi::CStr;
use std::os::raw::c_uint;
use sdl2::{Sdl, VideoSubsystem};
use sdl2::Sdl;
use sdl2::video::{GLContext, Window};
// TODO: get these from somewhere better without pulling in too much of a mess for the sdl2 feature
const GL_FRAMEBUFFER_BINDING: c_uint = 0x8CA6;
const GL_COLOR_BUFFER_BIT: c_uint = 0x00004000;
#[allow(non_snake_case)]
pub struct SimpleSdl2OpenglComponent {
window: Window,
window_fbo: c_uint,
@ -14,6 +19,8 @@ pub struct SimpleSdl2OpenglComponent {
pixel_format: sdl2::pixels::PixelFormatEnum,
hw_context_reset_fn: Option<HwContextResetFn>,
hw_context_destroy_fn: Option<HwContextResetFn>,
glGetIntegerv: unsafe extern "C" fn(c_uint, *mut c_uint),
glClear: unsafe extern "C" fn(c_uint),
}
impl SimpleSdl2OpenglComponent {
@ -33,10 +40,19 @@ impl SimpleSdl2OpenglComponent {
.opengl()
.build()?;
#[allow(non_snake_case)]
let glGetIntegerv: unsafe extern "C" fn(c_uint, *mut c_uint) = unsafe {
std::mem::transmute(video.gl_get_proc_address("glGetIntegerv"))
};
#[allow(non_snake_case)]
let glClear: unsafe extern "C" fn(c_uint) = unsafe {
std::mem::transmute(video.gl_get_proc_address("glClear"))
};
// http://forums.libsdl.org/viewtopic.php?p=43353
// likely to remain `0` on any platform that isn't iOS, but we'll do it anyhow
let gl_context = window.gl_create_context()?;
let window_fbo = Self::current_framebuffer_binding(&video);
let window_fbo = unsafe { let mut fbo = 0; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &mut fbo); fbo };
Ok(SimpleSdl2OpenglComponent {
window,
@ -45,18 +61,16 @@ impl SimpleSdl2OpenglComponent {
pixel_format,
hw_context_reset_fn: None,
hw_context_destroy_fn: None,
glGetIntegerv,
glClear,
})
}
fn current_framebuffer_binding(video: &VideoSubsystem) -> c_uint {
fn current_framebuffer_binding(&self) -> c_uint {
let mut fbo: c_uint = 0;
unsafe {
const GL_FRAMEBUFFER_BINDING: c_uint = 0x8CA6;
#[allow(non_snake_case)]
let glGetIntegerv: unsafe extern "C" fn(c_uint, *mut c_uint) = std::mem::transmute(
video.gl_get_proc_address("glGetIntegerv")
);
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &mut fbo);
(self.glGetIntegerv)(GL_FRAMEBUFFER_BINDING, &mut fbo);
}
eprintln!("get_framebuffer_binding: {}", fbo);
fbo
@ -72,6 +86,10 @@ impl SimpleSdl2OpenglComponent {
}
impl RetroCallbacks for SimpleSdl2OpenglComponent {
fn video_refresh_hw(&mut self, _width: c_uint, _height: c_uint) {
unsafe { (self.glClear)(GL_COLOR_BUFFER_BIT); }
}
fn set_pixel_format(&mut self, pix_fmt: PixelFormat) -> Option<bool> {
self.pixel_format = match pix_fmt {
PixelFormat::ARGB1555 => sdl2::pixels::PixelFormatEnum::RGB555,
@ -106,7 +124,7 @@ impl RetroCallbacks for SimpleSdl2OpenglComponent {
self.window.set_size(geom.base_width, geom.base_height).ok()?;
self.call_context_destroy()?;
self.gl_context = self.window.gl_create_context().ok()?;
self.window_fbo = Self::current_framebuffer_binding(self.window.subsystem());
self.window_fbo = self.current_framebuffer_binding();
self.call_context_reset()?;
Some(true)
}