mirror of
https://github.com/doukutsu-rs/doukutsu-rs
synced 2025-12-04 10:57:15 +00:00
graphics::imgui_texture_id and soundness fixes
This commit is contained in:
parent
ebe3c2f2af
commit
e2afafdfa3
|
|
@ -1,3 +1,4 @@
|
||||||
|
use std::any::Any;
|
||||||
use imgui::DrawData;
|
use imgui::DrawData;
|
||||||
|
|
||||||
use crate::common::{Color, Rect};
|
use crate::common::{Color, Rect};
|
||||||
|
|
@ -17,7 +18,7 @@ pub struct VertexData {
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
pub enum BackendShader {
|
pub enum BackendShader {
|
||||||
Fill,
|
Fill,
|
||||||
Texture
|
Texture,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Backend {
|
pub trait Backend {
|
||||||
|
|
@ -57,13 +58,20 @@ pub trait BackendRenderer {
|
||||||
|
|
||||||
fn imgui(&self) -> GameResult<&mut imgui::Context>;
|
fn imgui(&self) -> GameResult<&mut imgui::Context>;
|
||||||
|
|
||||||
|
fn imgui_texture_id(&self, texture: &Box<dyn BackendTexture>) -> GameResult<imgui::TextureId>;
|
||||||
|
|
||||||
fn render_imgui(&mut self, draw_data: &DrawData) -> GameResult;
|
fn render_imgui(&mut self, draw_data: &DrawData) -> GameResult;
|
||||||
|
|
||||||
fn supports_vertex_draw(&self) -> bool {
|
fn supports_vertex_draw(&self) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_triangle_list(&mut self, vertices: Vec<VertexData>, texture: Option<&Box<dyn BackendTexture>>, shader: BackendShader) -> GameResult;
|
fn draw_triangle_list(
|
||||||
|
&mut self,
|
||||||
|
vertices: Vec<VertexData>,
|
||||||
|
texture: Option<&Box<dyn BackendTexture>>,
|
||||||
|
shader: BackendShader,
|
||||||
|
) -> GameResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait BackendTexture {
|
pub trait BackendTexture {
|
||||||
|
|
@ -74,6 +82,8 @@ pub trait BackendTexture {
|
||||||
fn clear(&mut self);
|
fn clear(&mut self);
|
||||||
|
|
||||||
fn draw(&mut self) -> GameResult;
|
fn draw(&mut self) -> GameResult;
|
||||||
|
|
||||||
|
fn as_any(&self) -> &dyn Any;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unreachable_code)]
|
#[allow(unreachable_code)]
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
|
use std::any::Any;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
use imgui::DrawData;
|
use imgui::{DrawData, TextureId};
|
||||||
|
|
||||||
use crate::common::{Color, Rect};
|
use crate::common::{Color, Rect};
|
||||||
use crate::framework::backend::{
|
use crate::framework::backend::{
|
||||||
|
|
@ -79,6 +80,10 @@ impl BackendTexture for NullTexture {
|
||||||
fn draw(&mut self) -> GameResult<()> {
|
fn draw(&mut self) -> GameResult<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct NullRenderer(RefCell<imgui::Context>);
|
pub struct NullRenderer(RefCell<imgui::Context>);
|
||||||
|
|
@ -126,6 +131,10 @@ impl BackendRenderer for NullRenderer {
|
||||||
unsafe { Ok(&mut *self.0.as_ptr()) }
|
unsafe { Ok(&mut *self.0.as_ptr()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn imgui_texture_id(&self, _texture: &Box<dyn BackendTexture>) -> GameResult<TextureId> {
|
||||||
|
Ok(TextureId::from(0))
|
||||||
|
}
|
||||||
|
|
||||||
fn render_imgui(&mut self, _draw_data: &DrawData) -> GameResult {
|
fn render_imgui(&mut self, _draw_data: &DrawData) -> GameResult {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
use core::mem;
|
use core::mem;
|
||||||
|
use std::any::Any;
|
||||||
|
use std::borrow::Borrow;
|
||||||
use std::cell::{RefCell, UnsafeCell};
|
use std::cell::{RefCell, UnsafeCell};
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::ffi::c_void;
|
use std::ffi::c_void;
|
||||||
|
use std::ops::Deref;
|
||||||
|
use std::ptr::null_mut;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
|
@ -11,7 +14,7 @@ use sdl2::event::{Event, WindowEvent};
|
||||||
use sdl2::keyboard::Scancode;
|
use sdl2::keyboard::Scancode;
|
||||||
use sdl2::mouse::{Cursor, SystemCursor};
|
use sdl2::mouse::{Cursor, SystemCursor};
|
||||||
use sdl2::pixels::PixelFormatEnum;
|
use sdl2::pixels::PixelFormatEnum;
|
||||||
use sdl2::render::{Texture, TextureCreator, WindowCanvas};
|
use sdl2::render::{Texture, TextureCreator, TextureQuery, WindowCanvas};
|
||||||
use sdl2::video::GLProfile;
|
use sdl2::video::GLProfile;
|
||||||
use sdl2::video::WindowContext;
|
use sdl2::video::WindowContext;
|
||||||
use sdl2::{keyboard, pixels, EventPump, Sdl, VideoSubsystem};
|
use sdl2::{keyboard, pixels, EventPump, Sdl, VideoSubsystem};
|
||||||
|
|
@ -27,6 +30,7 @@ use crate::framework::keyboard::ScanCode;
|
||||||
use crate::framework::render_opengl::{GLContext, OpenGLRenderer};
|
use crate::framework::render_opengl::{GLContext, OpenGLRenderer};
|
||||||
use crate::framework::ui::init_imgui;
|
use crate::framework::ui::init_imgui;
|
||||||
use crate::Game;
|
use crate::Game;
|
||||||
|
use crate::GameError::RenderError;
|
||||||
use crate::GAME_SUSPENDED;
|
use crate::GAME_SUSPENDED;
|
||||||
|
|
||||||
pub struct SDL2Backend {
|
pub struct SDL2Backend {
|
||||||
|
|
@ -119,7 +123,7 @@ impl BackendEventLoop for SDL2EventLoop {
|
||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
let (width, height) = self.refs.borrow().canvas.window().size();
|
let (width, height) = self.refs.deref().borrow().canvas.window().size();
|
||||||
ctx.screen_size = (width.max(1) as f32, height.max(1) as f32);
|
ctx.screen_size = (width.max(1) as f32, height.max(1) as f32);
|
||||||
|
|
||||||
imgui.io_mut().display_size = [ctx.screen_size.0, ctx.screen_size.1];
|
imgui.io_mut().display_size = [ctx.screen_size.0, ctx.screen_size.1];
|
||||||
|
|
@ -230,7 +234,7 @@ impl BackendEventLoop for SDL2EventLoop {
|
||||||
|
|
||||||
imgui_sdl2.prepare_frame(
|
imgui_sdl2.prepare_frame(
|
||||||
imgui.io_mut(),
|
imgui.io_mut(),
|
||||||
self.refs.borrow().canvas.window(),
|
self.refs.deref().borrow().canvas.window(),
|
||||||
&self.event_pump.mouse_state(),
|
&self.event_pump.mouse_state(),
|
||||||
);
|
);
|
||||||
game.draw(ctx).unwrap();
|
game.draw(ctx).unwrap();
|
||||||
|
|
@ -300,20 +304,18 @@ struct SDL2Renderer {
|
||||||
refs: Rc<RefCell<SDL2Context>>,
|
refs: Rc<RefCell<SDL2Context>>,
|
||||||
imgui: Rc<RefCell<imgui::Context>>,
|
imgui: Rc<RefCell<imgui::Context>>,
|
||||||
imgui_event: Rc<RefCell<ImguiSdl2>>,
|
imgui_event: Rc<RefCell<ImguiSdl2>>,
|
||||||
imgui_textures: HashMap<TextureId, SDL2Texture>,
|
imgui_font_tex: SDL2Texture,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SDL2Renderer {
|
impl SDL2Renderer {
|
||||||
#[allow(clippy::new_ret_no_self)]
|
#[allow(clippy::new_ret_no_self)]
|
||||||
pub fn new(refs: Rc<RefCell<SDL2Context>>) -> GameResult<Box<dyn BackendRenderer>> {
|
pub fn new(refs: Rc<RefCell<SDL2Context>>) -> GameResult<Box<dyn BackendRenderer>> {
|
||||||
let mut imgui = init_imgui()?;
|
let mut imgui = init_imgui()?;
|
||||||
let mut imgui_textures = HashMap::new();
|
|
||||||
|
|
||||||
imgui.set_renderer_name("SDL2Renderer".to_owned());
|
imgui.set_renderer_name("SDL2Renderer".to_owned());
|
||||||
{
|
let imgui_font_tex = {
|
||||||
let refs = refs.clone();
|
let refs = refs.clone();
|
||||||
let mut fonts = imgui.fonts();
|
let mut fonts = imgui.fonts();
|
||||||
let id = fonts.tex_id;
|
|
||||||
let font_tex = fonts.build_rgba32_texture();
|
let font_tex = fonts.build_rgba32_texture();
|
||||||
|
|
||||||
let mut texture = refs
|
let mut texture = refs
|
||||||
|
|
@ -339,17 +341,15 @@ impl SDL2Renderer {
|
||||||
})
|
})
|
||||||
.map_err(|e| GameError::RenderError(e.to_string()))?;
|
.map_err(|e| GameError::RenderError(e.to_string()))?;
|
||||||
|
|
||||||
imgui_textures.insert(
|
SDL2Texture {
|
||||||
id,
|
refs: refs.clone(),
|
||||||
SDL2Texture {
|
texture: Some(texture),
|
||||||
refs: refs.clone(),
|
width: font_tex.width as u16,
|
||||||
texture: Some(texture),
|
height: font_tex.height as u16,
|
||||||
width: font_tex.width as u16,
|
commands: vec![],
|
||||||
height: font_tex.height as u16,
|
}
|
||||||
commands: vec![],
|
};
|
||||||
},
|
imgui.fonts().tex_id = TextureId::new(imgui_font_tex.texture.as_ref().unwrap().raw() as usize);
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let imgui_sdl2 = unsafe {
|
let imgui_sdl2 = unsafe {
|
||||||
let refs = &mut *refs.as_ptr();
|
let refs = &mut *refs.as_ptr();
|
||||||
|
|
@ -360,7 +360,7 @@ impl SDL2Renderer {
|
||||||
refs,
|
refs,
|
||||||
imgui: Rc::new(RefCell::new(imgui)),
|
imgui: Rc::new(RefCell::new(imgui)),
|
||||||
imgui_event: Rc::new(RefCell::new(imgui_sdl2)),
|
imgui_event: Rc::new(RefCell::new(imgui_sdl2)),
|
||||||
imgui_textures,
|
imgui_font_tex,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -426,7 +426,6 @@ impl BackendRenderer for SDL2Renderer {
|
||||||
let mut refs = self.refs.borrow_mut();
|
let mut refs = self.refs.borrow_mut();
|
||||||
|
|
||||||
refs.canvas.set_clip_rect(Some(sdl2::rect::Rect::new(0, 0, width as u32, height as u32)));
|
refs.canvas.set_clip_rect(Some(sdl2::rect::Rect::new(0, 0, width as u32, height as u32)));
|
||||||
//refs.canvas.set_clip_rect(None);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -483,19 +482,23 @@ impl BackendRenderer for SDL2Renderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_render_target(&mut self, texture: Option<&Box<dyn BackendTexture>>) -> GameResult {
|
fn set_render_target(&mut self, texture: Option<&Box<dyn BackendTexture>>) -> GameResult {
|
||||||
let renderer = self.refs.borrow().canvas.raw();
|
let renderer = self.refs.deref().borrow().canvas.raw();
|
||||||
|
|
||||||
// todo: horribly unsafe
|
|
||||||
match texture {
|
match texture {
|
||||||
Some(texture) => unsafe {
|
Some(texture) => {
|
||||||
let sdl2_texture: &Box<SDL2Texture> = std::mem::transmute(texture);
|
let sdl2_texture = texture
|
||||||
|
.as_any()
|
||||||
|
.downcast_ref::<SDL2Texture>()
|
||||||
|
.ok_or(RenderError("This texture was not created by OpenGL backend.".to_string()))?;
|
||||||
|
|
||||||
if let Some(target) = sdl2_texture.texture.as_ref() {
|
unsafe {
|
||||||
set_raw_target(renderer, target.raw())?;
|
if let Some(target) = sdl2_texture.texture.as_ref() {
|
||||||
} else {
|
set_raw_target(renderer, target.raw())?;
|
||||||
set_raw_target(renderer, std::ptr::null_mut())?;
|
} else {
|
||||||
|
set_raw_target(renderer, std::ptr::null_mut())?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
None => unsafe {
|
None => unsafe {
|
||||||
set_raw_target(renderer, std::ptr::null_mut())?;
|
set_raw_target(renderer, std::ptr::null_mut())?;
|
||||||
},
|
},
|
||||||
|
|
@ -591,6 +594,15 @@ impl BackendRenderer for SDL2Renderer {
|
||||||
unsafe { Ok(&mut *self.imgui.as_ptr()) }
|
unsafe { Ok(&mut *self.imgui.as_ptr()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn imgui_texture_id(&self, texture: &Box<dyn BackendTexture>) -> GameResult<TextureId> {
|
||||||
|
let sdl_texture = texture
|
||||||
|
.as_any()
|
||||||
|
.downcast_ref::<SDL2Texture>()
|
||||||
|
.ok_or(GameError::RenderError("This texture was not created by SDL backend.".to_string()))?;
|
||||||
|
|
||||||
|
Ok(TextureId::new(sdl_texture.texture.as_ref().map(|t| t.raw()).unwrap_or(null_mut()) as usize))
|
||||||
|
}
|
||||||
|
|
||||||
fn render_imgui(&mut self, draw_data: &DrawData) -> GameResult {
|
fn render_imgui(&mut self, draw_data: &DrawData) -> GameResult {
|
||||||
let mut refs = self.refs.borrow_mut();
|
let mut refs = self.refs.borrow_mut();
|
||||||
|
|
||||||
|
|
@ -668,13 +680,17 @@ impl BackendRenderer for SDL2Renderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(surf) = self.imgui_textures.get_mut(&cmd_params.texture_id) {
|
let ptr = cmd_params.texture_id.id() as *mut sdl2::sys::SDL_Texture;
|
||||||
|
if !ptr.is_null() {
|
||||||
|
let mut surf = unsafe { refs.texture_creator.raw_create_texture(ptr) };
|
||||||
|
let TextureQuery { width, height, .. } = surf.query();
|
||||||
|
|
||||||
if is_rect {
|
if is_rect {
|
||||||
let src = sdl2::rect::Rect::new(
|
let src = sdl2::rect::Rect::new(
|
||||||
(tex_pos[0] * surf.width as f32) as i32,
|
(tex_pos[0] * width as f32) as i32,
|
||||||
(tex_pos[1] * surf.height as f32) as i32,
|
(tex_pos[1] * height as f32) as i32,
|
||||||
((tex_pos[2] - tex_pos[0]) * surf.width as f32) as u32,
|
((tex_pos[2] - tex_pos[0]) * width as f32) as u32,
|
||||||
((tex_pos[3] - tex_pos[1]) * surf.height as f32) as u32,
|
((tex_pos[3] - tex_pos[1]) * height as f32) as u32,
|
||||||
);
|
);
|
||||||
let dest = sdl2::rect::Rect::new(
|
let dest = sdl2::rect::Rect::new(
|
||||||
min[0] as i32,
|
min[0] as i32,
|
||||||
|
|
@ -683,12 +699,11 @@ impl BackendRenderer for SDL2Renderer {
|
||||||
(max[1] - min[1]) as u32,
|
(max[1] - min[1]) as u32,
|
||||||
);
|
);
|
||||||
|
|
||||||
let tex = surf.texture.as_mut().unwrap();
|
surf.set_color_mod(v1.col[0], v1.col[1], v1.col[2]);
|
||||||
tex.set_color_mod(v1.col[0], v1.col[1], v1.col[2]);
|
surf.set_alpha_mod(v1.col[3]);
|
||||||
tex.set_alpha_mod(v1.col[3]);
|
|
||||||
|
|
||||||
refs.canvas
|
refs.canvas
|
||||||
.copy(tex, src, dest)
|
.copy(&surf, src, dest)
|
||||||
.map_err(|e| GameError::RenderError(e.to_string()))?;
|
.map_err(|e| GameError::RenderError(e.to_string()))?;
|
||||||
} else {
|
} else {
|
||||||
/*sdl2::sys::gfx::primitives::filledPolygonRGBA(
|
/*sdl2::sys::gfx::primitives::filledPolygonRGBA(
|
||||||
|
|
@ -835,6 +850,10 @@ impl BackendTexture for SDL2Texture {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for SDL2Texture {
|
impl Drop for SDL2Texture {
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,14 @@ pub fn imgui_context(ctx: &Context) -> GameResult<&mut imgui::Context> {
|
||||||
Err(GameError::RenderError("Rendering backend hasn't been initialized yet.".to_string()))
|
Err(GameError::RenderError("Rendering backend hasn't been initialized yet.".to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn imgui_texture_id(ctx: &Context, texture: &Box<dyn BackendTexture>) -> GameResult<imgui::TextureId> {
|
||||||
|
if let Some(renderer) = ctx.renderer.as_ref() {
|
||||||
|
return renderer.imgui_texture_id(texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(GameError::RenderError("Rendering backend hasn't been initialized yet.".to_string()))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn render_imgui(ctx: &mut Context, draw_data: &imgui::DrawData) -> GameResult {
|
pub fn render_imgui(ctx: &mut Context, draw_data: &imgui::DrawData) -> GameResult {
|
||||||
if let Some(renderer) = ctx.renderer.as_mut() {
|
if let Some(renderer) = ctx.renderer.as_mut() {
|
||||||
return renderer.render_imgui(draw_data);
|
return renderer.render_imgui(draw_data);
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use std::any::Any;
|
||||||
use std::cell::{RefCell, UnsafeCell};
|
use std::cell::{RefCell, UnsafeCell};
|
||||||
use std::ffi::{c_void, CStr};
|
use std::ffi::{c_void, CStr};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
@ -5,7 +6,7 @@ use std::mem::MaybeUninit;
|
||||||
use std::ptr::null;
|
use std::ptr::null;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use imgui::{DrawCmd, DrawCmdParams, DrawData, DrawIdx, DrawVert};
|
use imgui::{DrawCmd, DrawCmdParams, DrawData, DrawIdx, DrawVert, TextureId};
|
||||||
|
|
||||||
use crate::common::{Color, Rect};
|
use crate::common::{Color, Rect};
|
||||||
use crate::framework::backend::{BackendRenderer, BackendShader, BackendTexture, SpriteBatchCommand, VertexData};
|
use crate::framework::backend::{BackendRenderer, BackendShader, BackendTexture, SpriteBatchCommand, VertexData};
|
||||||
|
|
@ -232,6 +233,10 @@ impl BackendTexture for OpenGLTexture {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for OpenGLTexture {
|
impl Drop for OpenGLTexture {
|
||||||
|
|
@ -882,7 +887,10 @@ impl BackendRenderer for OpenGLRenderer {
|
||||||
if let Some((_, gl)) = self.get_context() {
|
if let Some((_, gl)) = self.get_context() {
|
||||||
unsafe {
|
unsafe {
|
||||||
if let Some(texture) = texture {
|
if let Some(texture) = texture {
|
||||||
let gl_texture: &Box<OpenGLTexture> = std::mem::transmute(texture);
|
let gl_texture = texture
|
||||||
|
.as_any()
|
||||||
|
.downcast_ref::<OpenGLTexture>()
|
||||||
|
.ok_or(RenderError("This texture was not created by OpenGL backend.".to_string()))?;
|
||||||
|
|
||||||
self.curr_matrix = [
|
self.curr_matrix = [
|
||||||
[2.0 / (gl_texture.width as f32), 0.0, 0.0, 0.0],
|
[2.0 / (gl_texture.width as f32), 0.0, 0.0, 0.0],
|
||||||
|
|
@ -1015,10 +1023,36 @@ impl BackendRenderer for OpenGLRenderer {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_clip_rect(&mut self, rect: Option<Rect>) -> GameResult {
|
||||||
|
if let Some((_, gl)) = self.get_context() {
|
||||||
|
unsafe {
|
||||||
|
if let Some(rect) = &rect {
|
||||||
|
gl.gl.Enable(gl::SCISSOR_TEST);
|
||||||
|
gl.gl.Scissor(rect.left as GLint, rect.top as GLint, rect.width() as GLint, rect.height() as GLint);
|
||||||
|
} else {
|
||||||
|
gl.gl.Disable(gl::SCISSOR_TEST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(RenderError("No OpenGL context available!".to_string()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn imgui(&self) -> GameResult<&mut imgui::Context> {
|
fn imgui(&self) -> GameResult<&mut imgui::Context> {
|
||||||
unsafe { Ok(&mut *self.imgui.get()) }
|
unsafe { Ok(&mut *self.imgui.get()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn imgui_texture_id(&self, texture: &Box<dyn BackendTexture>) -> GameResult<TextureId> {
|
||||||
|
let gl_texture = texture
|
||||||
|
.as_any()
|
||||||
|
.downcast_ref::<OpenGLTexture>()
|
||||||
|
.ok_or(RenderError("This texture was not created by OpenGL backend.".to_string()))?;
|
||||||
|
|
||||||
|
Ok(TextureId::new(gl_texture.texture_id as usize))
|
||||||
|
}
|
||||||
|
|
||||||
fn render_imgui(&mut self, draw_data: &DrawData) -> GameResult {
|
fn render_imgui(&mut self, draw_data: &DrawData) -> GameResult {
|
||||||
// https://github.com/michaelfairley/rust-imgui-opengl-renderer
|
// https://github.com/michaelfairley/rust-imgui-opengl-renderer
|
||||||
if let Some((_, gl)) = self.get_context() {
|
if let Some((_, gl)) = self.get_context() {
|
||||||
|
|
@ -1147,39 +1181,22 @@ impl BackendRenderer for OpenGLRenderer {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn supports_vertex_draw(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
fn draw_triangle_list(
|
fn draw_triangle_list(
|
||||||
&mut self,
|
&mut self,
|
||||||
vertices: Vec<VertexData>,
|
vertices: Vec<VertexData>,
|
||||||
texture: Option<&Box<dyn BackendTexture>>,
|
texture: Option<&Box<dyn BackendTexture>>,
|
||||||
shader: BackendShader,
|
shader: BackendShader,
|
||||||
) -> GameResult<()> {
|
) -> GameResult<()> {
|
||||||
unsafe { self.draw_arrays(gl::TRIANGLES, vertices, texture, shader) }
|
self.draw_arrays(gl::TRIANGLES, vertices, texture, shader)
|
||||||
}
|
|
||||||
|
|
||||||
fn supports_vertex_draw(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_clip_rect(&mut self, rect: Option<Rect>) -> GameResult {
|
|
||||||
if let Some((_, gl)) = self.get_context() {
|
|
||||||
unsafe {
|
|
||||||
if let Some(rect) = &rect {
|
|
||||||
gl.gl.Enable(gl::SCISSOR_TEST);
|
|
||||||
gl.gl.Scissor(rect.left as GLint, rect.top as GLint, rect.width() as GLint, rect.height() as GLint);
|
|
||||||
} else {
|
|
||||||
gl.gl.Disable(gl::SCISSOR_TEST);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(RenderError("No OpenGL context available!".to_string()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OpenGLRenderer {
|
impl OpenGLRenderer {
|
||||||
unsafe fn draw_arrays(
|
fn draw_arrays(
|
||||||
&mut self,
|
&mut self,
|
||||||
vert_type: GLenum,
|
vert_type: GLenum,
|
||||||
vertices: Vec<VertexData>,
|
vertices: Vec<VertexData>,
|
||||||
|
|
@ -1191,13 +1208,17 @@ impl OpenGLRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
let texture_id = if let Some(texture) = texture {
|
let texture_id = if let Some(texture) = texture {
|
||||||
let gl_texture: &Box<OpenGLTexture> = std::mem::transmute(texture);
|
let gl_texture = texture
|
||||||
|
.as_any()
|
||||||
|
.downcast_ref::<OpenGLTexture>()
|
||||||
|
.ok_or(RenderError("This texture was not created by OpenGL backend.".to_string()))?;
|
||||||
|
|
||||||
gl_texture.texture_id
|
gl_texture.texture_id
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
self.draw_arrays_tex_id(vert_type, vertices, texture_id, shader)
|
unsafe { self.draw_arrays_tex_id(vert_type, vertices, texture_id, shader) }
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn draw_arrays_tex_id(
|
unsafe fn draw_arrays_tex_id(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue