add gfx setup ffi
authoralfadur
Sun, 25 Nov 2018 05:52:06 +0300
changeset 14314 b8871dd33ec4
parent 14313 1d4f1d700cdc
child 14315 21be7838a127
add gfx setup ffi
rust/hwrunner/src/main.rs
rust/lib-hedgewars-engine/src/instance.rs
rust/lib-hedgewars-engine/src/lib.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::{
--- 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<Resources, (R8_G8_B8_A8, Unorm)>,
+    pub depth_buffer: gfx::handle::DepthStencilView<Resources, (D24, Unorm)>,
+    pub command_buffer: gfx::Encoder<Resources, CommandBuffer>
+}
+
 pub struct EngineInstance {
     pub world: World,
     pub ipc: IPC,
+    pub gl_context: Option<EngineGlContext>
 }
 
 impl EngineInstance {
@@ -17,18 +34,19 @@
         Self {
             world,
             ipc: IPC::new(),
+            gl_context: None
         }
     }
 
     pub fn render<R, C>(
         &self,
-        context: &mut gfx::Encoder<R, C>,
-        target: &gfx::handle::RenderTargetView<R, gfx::format::Rgba8>,
+        command_buffer: &mut gfx::Encoder<R, C>,
+        render_target: &gfx::handle::RenderTargetView<R, gfx::format::Rgba8>,
     ) where
         R: gfx::Resources,
         C: gfx::CommandBuffer<R>,
     {
-        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) {
--- 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);