# HG changeset patch # User alfadur # Date 1543114326 -10800 # Node ID b8871dd33ec4d7711813c68e15be39fe7e01f4bd # Parent 1d4f1d700cdcda177f4bef3455f47922ce5f143f add gfx setup ffi diff -r 1d4f1d700cdc -r b8871dd33ec4 rust/hwrunner/src/main.rs --- a/rust/hwrunner/src/main.rs Sun Nov 25 00:23:32 2018 +0100 +++ b/rust/hwrunner/src/main.rs Sun Nov 25 05:52:06 2018 +0300 @@ -15,7 +15,7 @@ use gfx_window_glutin::init_existing; -use hedgewars_engine::EngineInstance; +use hedgewars_engine::instance::EngineInstance; fn init(event_loop: &EventsLoop, size: LogicalSize) -> GlWindow { use glutin::{ diff -r 1d4f1d700cdc -r b8871dd33ec4 rust/lib-hedgewars-engine/src/instance.rs --- a/rust/lib-hedgewars-engine/src/instance.rs Sun Nov 25 00:23:32 2018 +0100 +++ b/rust/lib-hedgewars-engine/src/instance.rs Sun Nov 25 05:52:06 2018 +0300 @@ -3,12 +3,29 @@ UnorderedEngineMessage::*, UnsyncedEngineMessage::*, * }; +use gfx::{ + format::{R8_G8_B8_A8, D24, Unorm} +}; +use gfx_device_gl as gfx_gl; +use self::gfx_gl::{ + Resources, + CommandBuffer +}; + use super::{ipc::IPC, world::World}; -#[repr(C)] +pub struct EngineGlContext { + pub device: gfx_gl::Device, + pub factory: gfx_gl::Factory, + pub render_target: gfx::handle::RenderTargetView, + pub depth_buffer: gfx::handle::DepthStencilView, + pub command_buffer: gfx::Encoder +} + pub struct EngineInstance { pub world: World, pub ipc: IPC, + pub gl_context: Option } impl EngineInstance { @@ -17,18 +34,19 @@ Self { world, ipc: IPC::new(), + gl_context: None } } pub fn render( &self, - context: &mut gfx::Encoder, - target: &gfx::handle::RenderTargetView, + command_buffer: &mut gfx::Encoder, + render_target: &gfx::handle::RenderTargetView, ) where R: gfx::Resources, C: gfx::CommandBuffer, { - context.clear(target, [0.0, 0.5, 0.0, 1.0]); + command_buffer.clear(render_target, [0.0, 0.5, 0.0, 1.0]); } fn process_unordered_message(&mut self, message: &UnorderedEngineMessage) { diff -r 1d4f1d700cdc -r b8871dd33ec4 rust/lib-hedgewars-engine/src/lib.rs --- a/rust/lib-hedgewars-engine/src/lib.rs Sun Nov 25 00:23:32 2018 +0100 +++ b/rust/lib-hedgewars-engine/src/lib.rs Sun Nov 25 05:52:06 2018 +0300 @@ -1,10 +1,24 @@ mod ipc; mod world; -mod instance; +pub mod instance; -use std::io::{Read, Write}; +use std::{ + io::{Read, Write}, + ffi::{CString}, + os::raw::{c_void, c_char}, + mem::replace +}; +use gfx::{ + Encoder, + format::Formatted, +}; -use self::instance::EngineInstance; +use gfx_device_gl as gfx_gl; + +use self::instance::{ + EngineInstance, + EngineGlContext +}; #[repr(C)] #[derive(Copy, Clone)] @@ -60,6 +74,45 @@ } #[no_mangle] +pub extern "C" fn setup_current_gl_context( + engine_state: &mut EngineInstance, + width: u16, + height: u16, + gl_loader: extern "C" fn (*const c_char) -> *const c_void +) { + let (device, mut factory) = gfx_gl::create(|name| { + let c_name = CString::new(name).unwrap(); + gl_loader(c_name.as_ptr()) + }); + + let dimensions = (width, height, 1u16, gfx::texture::AaMode::Single); + let (render_target, depth_buffer) = gfx_gl::create_main_targets_raw( + dimensions, + gfx::format::Rgba8::get_format().0, + gfx::format::Depth::get_format().0 + ); + + let mut command_buffer: Encoder<_, _> = factory.create_command_buffer().into(); + + engine_state.gl_context = Some(EngineGlContext { + device, + factory, + render_target: gfx::memory::Typed::new(render_target), + depth_buffer: gfx::memory::Typed::new(depth_buffer), + command_buffer + }) +} + +#[no_mangle] +pub extern "C" fn render_frame(engine_state: &mut EngineInstance) { + let mut context = replace(&mut engine_state.gl_context, None); + if let Some(ref mut c) = context { + engine_state.render(&mut c.command_buffer, &mut c.render_target) + } + replace(&mut engine_state.gl_context, context); +} + +#[no_mangle] pub extern "C" fn cleanup(engine_state: *mut EngineInstance) { unsafe { Box::from_raw(engine_state);