--- 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);