sync
This commit is contained in:
parent
4c0fa9e6ee
commit
4b70b6f59f
8 changed files with 569 additions and 210 deletions
|
@ -10,7 +10,7 @@ title_name = "MineMod"
|
|||
# assets = "somewhere" # TODO make this a build.rs output folder so we can use build.rs to manage vita assets
|
||||
|
||||
[profile.release]
|
||||
opt-level = 2
|
||||
opt-level = 3
|
||||
lto = true
|
||||
codegen-units = 1
|
||||
# panic = "abort" # Vita platform doesnt support abort currently
|
||||
|
|
|
@ -1,13 +1,26 @@
|
|||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use std::time::Instant;
|
||||
|
||||
use glam::Vec3;
|
||||
use resources::*;
|
||||
|
||||
use crate::graphics_engines::Renderable;
|
||||
//use crate::graphics_engines::Renderable;
|
||||
|
||||
pub mod resources;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Cataclysm {
|
||||
pub chunks:HashMap<(u32, u32, u32), CataclysmChunk>,
|
||||
pub creation_time:Instant,
|
||||
textures: Arc<ResourceTable<GraphicsTexture>>,
|
||||
vertex_objects: Arc<ResourceTable<GraphicsVBO>>,
|
||||
shader_objects: Arc<ResourceTable<GraphicsShader>>,
|
||||
sounds: Arc<ResourceTable<AudioSFX>>,
|
||||
music: Arc<ResourceTable<AudioMusic>>,
|
||||
pub chunks: HashMap<(u32, u32, u32), CataclysmChunk>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CataclysmChunk {
|
||||
pub simple_blocks:HashMap<(u8, u8, u8), SimpleBlock>,
|
||||
pub fancy_blocks: HashMap<Vec3, FancyBlock>,
|
||||
|
@ -22,7 +35,13 @@ impl Cataclysm {
|
|||
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
chunks: HashMap::new()
|
||||
creation_time: Instant::now(),
|
||||
textures: ResourceTable::new(),
|
||||
vertex_objects:ResourceTable::new(),
|
||||
shader_objects:ResourceTable::new(),
|
||||
sounds: ResourceTable::new(),
|
||||
music: ResourceTable::new(),
|
||||
chunks: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,33 +49,31 @@ impl Cataclysm {
|
|||
impl CataclysmChunk {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
simple_blocks: HashMap::new(),
|
||||
simple_blocks:HashMap::new(),
|
||||
fancy_blocks: HashMap::new(),
|
||||
smart_blocks: HashMap::new(),
|
||||
entities: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SimpleBlock {}
|
||||
|
||||
pub struct SimpleBlock {
|
||||
|
||||
}
|
||||
|
||||
impl Renderable for SimpleBlock {
|
||||
#[rustfmt::skip]
|
||||
fn vertext_data<'a>() -> (&'a [f32], &'a [u32]) {
|
||||
//impl Renderable for SimpleBlock {
|
||||
#[rustfmt::skip]
|
||||
fn vertext_data<'a>() -> (&'a [f32], &'a [u32]) {
|
||||
(&[
|
||||
-1.0, -1.0, 0.5, //0
|
||||
1.0, -1.0, 0.5, //1
|
||||
-1.0, 1.0, 0.5, //2
|
||||
1.0, 1.0, 0.5, //3
|
||||
-1.0, -1.0, -0.5, //4
|
||||
1.0, -1.0, -0.5, //5
|
||||
1.0, -1.0, -0.5, //5
|
||||
-1.0, 1.0, -0.5, //6
|
||||
1.0, 1.0, -0.5 //7
|
||||
],
|
||||
&[
|
||||
//Top
|
||||
],
|
||||
&[
|
||||
//Top
|
||||
2, 6, 7,
|
||||
2, 3, 7,
|
||||
|
||||
|
@ -80,25 +97,18 @@ impl Renderable for SimpleBlock {
|
|||
4, 6, 7,
|
||||
4, 5, 7
|
||||
]
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
//}
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FancyBlock {
|
||||
pub pos:Vec3,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SmartBlock {
|
||||
pub pos:Vec3,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Entity {
|
||||
pub pos:Vec3,
|
||||
}
|
||||
|
||||
//pub enum ModelKind {
|
||||
// Cube,
|
||||
// Complex(),
|
||||
//}
|
||||
|
||||
//pub struct ResourceReference {}
|
||||
|
|
172
src/cataclysm/resources/mod.rs
Normal file
172
src/cataclysm/resources/mod.rs
Normal file
|
@ -0,0 +1,172 @@
|
|||
use ::std::collections::HashMap;
|
||||
|
||||
use ::std::sync::Arc;
|
||||
use ::std::sync::Weak;
|
||||
use ::std::sync::atomic::AtomicBool;
|
||||
|
||||
/// You should prefer cloning a resource out and replacing the resource when it becomes stale
|
||||
#[derive(Debug)]
|
||||
pub struct ResourceTable<T> {
|
||||
resources:HashMap<String, Resource<T>>,
|
||||
}
|
||||
|
||||
pub const DEFAULT_RESOURCE_NAME:&&'static str = &"resource.default";
|
||||
|
||||
impl<T> ResourceTable<T> {
|
||||
pub fn add_resource(self: &Arc<Self>, name:&dyn ToString, thing:T) {
|
||||
let resource = Resource {
|
||||
inner:Arc::new(ResourceInner::new(thing)),
|
||||
name: Arc::new(name.to_string()),
|
||||
table:Arc::downgrade(&self),
|
||||
};
|
||||
}
|
||||
|
||||
// could be a macro? id prefer if it could work on self like it does for add_resource
|
||||
pub fn upgrade(table:&Weak<Self>) -> Arc<Self> {
|
||||
if let Some(table) = table.upgrade() {
|
||||
table
|
||||
} else {
|
||||
panic!(
|
||||
"A resource replace was attempted but it appears the owning table doesnt exist? Please ensure the owning table is not dropped, this is not expected to occur."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
pub fn get_resource(&self, name:&dyn ToString) -> Option<Resource<T>> { self.resources.get(&name.to_string()).cloned() }
|
||||
|
||||
///
|
||||
pub fn get_resource_or_default(&self, name:&dyn ToString) -> Resource<T> {
|
||||
let resource = self.resources.get(&name.to_string());
|
||||
|
||||
// we do this instead of .unwrap_or(T) because unwrap_or is not lazy
|
||||
// and will calculate T immediately whether it is needed or not
|
||||
if let Some(resource) = resource {
|
||||
resource.clone()
|
||||
} else {
|
||||
if let Some(resource) = self.get_resource(DEFAULT_RESOURCE_NAME) {
|
||||
resource
|
||||
} else {
|
||||
unreachable!(
|
||||
"Since resource tables get created with the `{DEFAULT_RESOURCE_NAME}` resource and you cannot remove it, this situation is impossible to occur."
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Default> ResourceTable<T> {
|
||||
pub fn new() -> Arc<Self> {
|
||||
let table = Arc::new(Self { resources:HashMap::new() });
|
||||
table.add_resource(&"default", T::default());
|
||||
table
|
||||
}
|
||||
}
|
||||
|
||||
// make an enum when mutable resources pop up?
|
||||
// mutable resources are very strange since they are global
|
||||
// instead any mutable *instances* of resource should be just that, an instance
|
||||
// there is currently no valid reason for a mutable resource
|
||||
// game logic has no business here
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Resource<T> {
|
||||
inner: Arc<ResourceInner<T>>,
|
||||
name: Arc<String>,
|
||||
/// Fast access to the table the resource belongs to
|
||||
pub table:Weak<ResourceTable<T>>,
|
||||
}
|
||||
|
||||
impl<T> Resource<T> {
|
||||
pub fn is_stale(&self) -> bool { self.inner.stale.load(std::sync::atomic::Ordering::SeqCst) }
|
||||
|
||||
// This permanently marks this resource as stale and all usages of it should be upgraded via the replace function
|
||||
pub fn expire(&mut self) {
|
||||
//self.table
|
||||
self.inner.stale.store(true, std::sync::atomic::Ordering::SeqCst);
|
||||
}
|
||||
|
||||
// This function will fetch the new resource under the same name, or will return itself as an error if there is none
|
||||
// Typically you should prefer replace_or_default unless you have a specific reason to handle the failure/need to keep using the original on failure
|
||||
pub fn replace(self) -> Result<Self, Self> {
|
||||
let table = ResourceTable::upgrade(&self.table);
|
||||
if let Some(resource) = table.get_resource(&self.name) {
|
||||
Ok(resource)
|
||||
} else {
|
||||
Err(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Default> Resource<T> {
|
||||
pub fn replace_or_default(self) -> Self {
|
||||
if let Some(table) = self.table.upgrade() {
|
||||
table.get_resource_or_default(&self.name)
|
||||
} else {
|
||||
panic!(
|
||||
"A resource replace was attempted but it appears the owning table doesnt exist? Please ensure the owning table is not dropped, this is not expected to occur."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Clone for Resource<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
inner:self.inner.clone(),
|
||||
name: self.name.clone(),
|
||||
table:self.table.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ResourceInner<T> {
|
||||
stale:AtomicBool,
|
||||
thing:T,
|
||||
}
|
||||
|
||||
impl<T> ResourceInner<T> {
|
||||
fn new(thing:T) -> Self {
|
||||
Self {
|
||||
stale:AtomicBool::new(false),
|
||||
thing,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// should contain both source and compiled version?
|
||||
#[derive(Debug)]
|
||||
pub struct GraphicsShader {}
|
||||
|
||||
impl Default for GraphicsShader {
|
||||
fn default() -> Self { todo!() }
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GraphicsTexture {}
|
||||
|
||||
impl Default for GraphicsTexture {
|
||||
fn default() -> Self { todo!() }
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GraphicsVBO {}
|
||||
|
||||
impl Default for GraphicsVBO {
|
||||
fn default() -> Self { todo!() }
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AudioSFX {}
|
||||
|
||||
impl Default for AudioSFX {
|
||||
fn default() -> Self { todo!() }
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AudioMusic {}
|
||||
|
||||
impl Default for AudioMusic {
|
||||
fn default() -> Self { todo!() }
|
||||
}
|
|
@ -21,28 +21,66 @@ pub mod opengl;
|
|||
|
||||
#[cfg(target_os = "vita")] pub mod gxm;
|
||||
|
||||
pub trait Renderable {
|
||||
fn vertext_data<'a>() -> (&'a [f32], &'a [u32]);
|
||||
}
|
||||
type Vec2f = cgmath::Vector2<f32>;
|
||||
type Vec3f = cgmath::Vector3<f32>;
|
||||
type Vec4f = cgmath::Vector4<f32>;
|
||||
|
||||
type Vec2d = cgmath::Vector2<f64>;
|
||||
type Vec3d = cgmath::Vector3<f64>;
|
||||
type Vec4d = cgmath::Vector4<f64>;
|
||||
|
||||
type Mat2f = cgmath::Matrix2<f32>;
|
||||
type Mat3f = cgmath::Matrix3<f32>;
|
||||
type Mat4f = cgmath::Matrix4<f32>;
|
||||
|
||||
type Mat2d = cgmath::Matrix2<f64>;
|
||||
type Mat3d = cgmath::Matrix3<f64>;
|
||||
type Mat4d = cgmath::Matrix4<f64>;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct VertexData {
|
||||
verts: Box<[f32]>,
|
||||
indices:Box<[u32]>,
|
||||
pub verts: Box<[Vertex]>,
|
||||
pub indices:Box<[u32]>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Vertex {
|
||||
pub pos: Vec2f,
|
||||
pub color:Vec3f,
|
||||
}
|
||||
|
||||
impl Vertex {
|
||||
pub const fn new(pos:Vec2f, color:Vec3f) -> Self { Self { pos, color } }
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub trait GraphicsCommander {
|
||||
/// Used to halt all render calls and calculations
|
||||
/// May deallocate graphics memory
|
||||
fn suspend_rendering(&mut self);
|
||||
/// Used to resume all render calls and calculations
|
||||
/// May allocate graphics memory
|
||||
fn resume_rendering(&mut self);
|
||||
|
||||
/// The first called function, used to register self to window and collect needed info from the system
|
||||
fn initialize_controller_system(&mut self, window: &mut PWindow);
|
||||
|
||||
/// Returns a formatted multiline string detailing various aspects of the render system, meant to be immediately presented to the user through the engine
|
||||
fn get_renderer_information(&self) -> String;
|
||||
|
||||
/// Used to load and potentially compile a shader
|
||||
fn load_shader_program(&mut self);
|
||||
|
||||
// TODO cataclysm render object
|
||||
|
||||
// will need a reference to game engine objects
|
||||
// replace with generic draw call? draw call will draw instructions to image, image may be framebuffer or not, allows gpu accelerated dynamic texture stuff
|
||||
fn render(&mut self, window:&mut PWindow, cataclysm:&mut Cataclysm) -> Result<()>;
|
||||
|
||||
/// This function will clear all existing vbos and replace them with its own.
|
||||
fn register_vbos(&mut self, data:&[VertexData]);
|
||||
fn create_vxos(&mut self, data:&[VertexData]);
|
||||
fn destroy_vxos(&mut self);
|
||||
// make generic for assets?
|
||||
fn register_texture(&mut self);
|
||||
fn destroy_texture(&mut self);
|
||||
|
@ -52,6 +90,14 @@ pub trait GraphicsCommander {
|
|||
fn exit(&mut self);
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
struct UniformBufferObject {
|
||||
model:Mat4f,
|
||||
view: Mat4f,
|
||||
proj: Mat4f,
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
|
||||
pub enum GMode {
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
use crate::cataclysm::Cataclysm;
|
||||
use crate::graphics_engines::Vertex;
|
||||
|
||||
use super::GraphicsCommander;
|
||||
use super::Mat4f;
|
||||
use super::UniformBufferObject;
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
use glam::vec2;
|
||||
use glam::vec3;
|
||||
|
||||
use glam::Vec2;
|
||||
use glam::Vec3;
|
||||
use cgmath::point3;
|
||||
use cgmath::vec3;
|
||||
use cgmath::Deg;
|
||||
use glfw::Context;
|
||||
use glfw::PWindow;
|
||||
|
||||
|
@ -21,7 +22,7 @@ pub mod gl {
|
|||
pub use Gles2 as Gl;
|
||||
}
|
||||
|
||||
impl GraphicsCommander for Renderer {
|
||||
impl GraphicsCommander for CataclysmOGL {
|
||||
fn suspend_rendering(&mut self) {
|
||||
}
|
||||
|
||||
|
@ -29,23 +30,51 @@ impl GraphicsCommander for Renderer {
|
|||
}
|
||||
|
||||
fn render(&mut self, window:&mut glfw::PWindow, cataclysm:&mut Cataclysm) -> anyhow::Result<()> {
|
||||
let model = Mat4f::from_axis_angle(vec3(0.0, 0.0, 1.0), Deg(45.0) * cataclysm.creation_time.elapsed().as_secs_f32());
|
||||
|
||||
let view = Mat4f::look_at_rh(point3(2.0, 5.0, 2.0), point3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 1.0));
|
||||
|
||||
let mut proj = cgmath::perspective(
|
||||
Deg(45.0),
|
||||
self.data.swapchain_extent.width as f32 / self.data.swapchain_extent.height as f32,
|
||||
0.1,
|
||||
10.0,
|
||||
);
|
||||
|
||||
// cgmath was made with opengl in mind, this fixes it to work with vulkan
|
||||
proj[1][1] *= -1.0;
|
||||
|
||||
let ubo = UniformBufferObject { model, view, proj };
|
||||
|
||||
//let memory = self.device.map_memory(
|
||||
// self.data.uniform_buffers_memory[image_index],
|
||||
// 0,
|
||||
// size_of::<UniformBufferObject>() as u64,
|
||||
// vk::MemoryMapFlags::empty(),
|
||||
//)?;
|
||||
|
||||
//memcpy(&ubo, memory.cast(), 1);
|
||||
|
||||
//self.device.unmap_memory(self.data.uniform_buffers_memory[image_index]);
|
||||
|
||||
let (red, green, blue, alpha) = (0.0125, 0.0094, 0.0071, 1.0);
|
||||
trace!("Clearing screen with color {red}|{green}|{blue}|{alpha}.");
|
||||
unsafe {
|
||||
self.gl.UseProgram(self.program);
|
||||
|
||||
trace!("Bind.");
|
||||
self.gl.BindVertexArray(self.vao);
|
||||
self.gl.BindBuffer(gl::ARRAY_BUFFER, self.vbo);
|
||||
|
||||
trace!("ClearColor.");
|
||||
//info!("Clearing screen with color {red}|{green}|{blue}|{alpha}.");
|
||||
self.gl.ClearColor(red, green, blue, alpha);
|
||||
trace!("Clear.");
|
||||
self.gl.Clear(gl::COLOR_BUFFER_BIT);
|
||||
trace!("DrawArrays.");
|
||||
self.gl.DrawArrays(gl::TRIANGLES, 0, 3);
|
||||
|
||||
for vxo in &self.vxos {
|
||||
//info!("Bind.");
|
||||
self.gl.BindVertexArray(vxo.0);
|
||||
for vbo in &vxo.1 {
|
||||
self.gl.BindBuffer(gl::ARRAY_BUFFER, *vbo);
|
||||
//info!("DrawArrays.");
|
||||
self.gl.DrawArrays(gl::TRIANGLES, 0, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
trace!("Done clearing screen.");
|
||||
|
||||
window.swap_buffers();
|
||||
|
||||
|
@ -56,62 +85,75 @@ impl GraphicsCommander for Renderer {
|
|||
|
||||
fn destroy_texture(&mut self) { todo!() }
|
||||
|
||||
//fn cleanup(&mut self) { todo!() }
|
||||
|
||||
fn exit(&mut self) {
|
||||
trace!("Destroying OpenGL instance.");
|
||||
info!("Destroying OpenGL instance.");
|
||||
unsafe {
|
||||
self.gl.DeleteProgram(self.program);
|
||||
for vbo in self.vbos.iter().take(self.vbos.len()) {
|
||||
self.gl.DeleteBuffers(1, vbo);
|
||||
}
|
||||
self.gl.DeleteVertexArrays(1, &self.vao);
|
||||
self.destroy_vxos();
|
||||
}
|
||||
}
|
||||
|
||||
fn register_vbos(&mut self, data:&[super::VertexData]) {
|
||||
fn create_vxos(&mut self, data:&[super::VertexData]) {
|
||||
for data in data {
|
||||
trace!("Creating OpenGL VAO.");
|
||||
unsafe {
|
||||
info!("Creating OpenGL VAO.");
|
||||
let vao = unsafe {
|
||||
let mut vao = std::mem::zeroed();
|
||||
self.gl.GenVertexArrays(1, &mut vao);
|
||||
self.gl.BindVertexArray(vao);
|
||||
}
|
||||
trace!("Creating OpenGL VBO.");
|
||||
unsafe {
|
||||
vao
|
||||
};
|
||||
|
||||
info!("Creating OpenGL VBO for vertices.");
|
||||
let vbo = unsafe {
|
||||
let mut vbo = std::mem::zeroed();
|
||||
self.gl.GenBuffers(1, &mut vbo);
|
||||
self.gl.BindBuffer(gl::ARRAY_BUFFER, vbo);
|
||||
self.gl.BufferData(
|
||||
gl::ARRAY_BUFFER,
|
||||
(VERTEX_DATA.len() * std::mem::size_of::<Vertex>()) as gl::types::GLsizeiptr,
|
||||
VERTEX_DATA.as_ptr() as *const _,
|
||||
dbg!(data.verts.len() * std::mem::size_of::<Vertex>()) as gl::types::GLsizeiptr,
|
||||
data.verts.as_ptr() as *const _,
|
||||
gl::STATIC_DRAW,
|
||||
);
|
||||
}
|
||||
vbo
|
||||
};
|
||||
|
||||
unsafe {
|
||||
trace!("Applying shader attributes.");
|
||||
let pos_attrib = self.gl.GetAttribLocation( self.program, b"position\0".as_ptr() as *const _);
|
||||
let color_attrib = self.gl.GetAttribLocation(self.program, b"color\0".as_ptr() as *const _);
|
||||
let (pos, col) = unsafe {
|
||||
info!("Applying shader attributes.");
|
||||
let pos_attrib = self.gl.GetAttribLocation(self.program, b"position\0".as_ptr() as *const _);
|
||||
self.gl.EnableVertexAttribArray(pos_attrib as gl::types::GLuint);
|
||||
self.gl.VertexAttribPointer(
|
||||
pos_attrib as gl::types::GLuint,
|
||||
2,
|
||||
gl::FLOAT,
|
||||
0,
|
||||
std::mem::size_of::<Vertex>() as gl::types::GLsizei,
|
||||
gl::FALSE,
|
||||
std::mem::size_of::<f32>() as gl::types::GLsizei,
|
||||
std::ptr::null(),
|
||||
);
|
||||
let color_attrib = self.gl.GetAttribLocation(self.program, b"color\0".as_ptr() as *const _);
|
||||
self.gl.EnableVertexAttribArray(color_attrib as gl::types::GLuint);
|
||||
self.gl.VertexAttribPointer(
|
||||
color_attrib as gl::types::GLuint,
|
||||
3,
|
||||
gl::FLOAT,
|
||||
0,
|
||||
5 * std::mem::size_of::<f32>() as gl::types::GLsizei,
|
||||
gl::FALSE,
|
||||
std::mem::size_of::<f32>() as gl::types::GLsizei,
|
||||
(2 * std::mem::size_of::<f32>()) as *const () as *const _,
|
||||
);
|
||||
self.gl.EnableVertexAttribArray(pos_attrib as gl::types::GLuint);
|
||||
self.gl.EnableVertexAttribArray(color_attrib as gl::types::GLuint);
|
||||
(pos_attrib, color_attrib)
|
||||
};
|
||||
|
||||
self.vxos.push((vao, vec![vbo]));
|
||||
}
|
||||
}
|
||||
|
||||
fn destroy_vxos(&mut self) {
|
||||
unsafe {
|
||||
for _ in 0..self.vxos.len() {
|
||||
let vxo = self.vxos.remove(0);
|
||||
self.gl.DeleteVertexArrays(1, &vxo.0);
|
||||
for vbo in vxo.1.iter().take(vxo.1.len()) {
|
||||
self.gl.DeleteBuffers(1, vbo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -120,17 +162,18 @@ impl GraphicsCommander for Renderer {
|
|||
use std::ffi::CStr;
|
||||
use std::ops::Deref;
|
||||
|
||||
pub struct Renderer {
|
||||
type VAO = gl::types::GLuint;
|
||||
type VBO = gl::types::GLuint;
|
||||
|
||||
pub struct CataclysmOGL {
|
||||
program:gl::types::GLuint,
|
||||
vao: gl::types::GLuint,
|
||||
vbos: Vec<gl::types::GLuint>,
|
||||
//vbo: gl::types::GLuint,
|
||||
vxos: Vec<(VAO, Vec<VBO>)>,
|
||||
gl: gl::Gl,
|
||||
}
|
||||
|
||||
impl Renderer {
|
||||
impl CataclysmOGL {
|
||||
pub fn create(window:&mut PWindow) -> Result<Self> {
|
||||
trace!("Creating OpenGL renderer instance.");
|
||||
info!("Creating OpenGL renderer instance.");
|
||||
|
||||
unsafe {
|
||||
let gl = gl::Gl::load_with(|symbol| window.get_proc_address(symbol));
|
||||
|
@ -146,26 +189,29 @@ impl Renderer {
|
|||
info!("Shaders version on {}", shaders_version.to_string_lossy());
|
||||
}
|
||||
|
||||
trace!("Loading shaders.");
|
||||
info!("Loading shaders.");
|
||||
let vertex_shader = create_shader(&gl, gl::VERTEX_SHADER, VERTEX_SHADER_SOURCE);
|
||||
let fragment_shader = create_shader(&gl, gl::FRAGMENT_SHADER, FRAGMENT_SHADER_SOURCE);
|
||||
|
||||
trace!("Creating OpenGL shader program.");
|
||||
info!("Creating OpenGL shader program.");
|
||||
let program = gl.CreateProgram();
|
||||
|
||||
gl.AttachShader(program, vertex_shader);
|
||||
gl.AttachShader(program, fragment_shader);
|
||||
|
||||
gl.LinkProgram(program);
|
||||
|
||||
gl.UseProgram(program);
|
||||
|
||||
trace!("Deleting shader objects.");
|
||||
info!("Deleting shader objects.");
|
||||
gl.DeleteShader(vertex_shader);
|
||||
gl.DeleteShader(fragment_shader);
|
||||
|
||||
trace!("OpenGL renderer instance created.");
|
||||
Ok(Self { program, vao, vbos:vec![], gl })
|
||||
info!("Linking shader program.");
|
||||
gl.LinkProgram(program);
|
||||
|
||||
info!("OpenGL renderer instance created.");
|
||||
Ok(Self {
|
||||
program,
|
||||
vxos:vec![/*(vao, vec![vbo])*/],
|
||||
gl,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,7 +222,7 @@ impl Renderer {
|
|||
}
|
||||
}
|
||||
|
||||
impl Deref for Renderer {
|
||||
impl Deref for CataclysmOGL {
|
||||
type Target = gl::Gl;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.gl }
|
||||
|
@ -196,53 +242,6 @@ fn get_gl_string(gl:&gl::Gl, variant:gl::types::GLenum) -> Option<&'static CStr>
|
|||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
struct Vertex {
|
||||
pos: Vec2,
|
||||
color:Vec3,
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
static VERTEX_DATA: [Vertex; 3] = [
|
||||
//-0.5, -0.5, 1.0, 0.0, 0.0,
|
||||
// 0.0, 0.5, 0.0, 1.0, 0.0,
|
||||
// 0.5, -0.5, 0.0, 0.0, 1.0,
|
||||
Vertex::new(vec2(-0.5, -0.5), vec3(0.3, 0.0, 1.0)),
|
||||
Vertex::new(vec2(0.5, 0.5), vec3(0.3, 0.0, 1.0)),
|
||||
Vertex::new(vec2(0.5, -0.5), vec3(0.3, 0.0, 1.0)),
|
||||
//Vertex::new(vec2(-0.5, 0.5), vec3(0.3, 0.0, 1.0)),
|
||||
];
|
||||
impl Vertex {
|
||||
const fn new(pos:Vec2, color:Vec3) -> Self { Self { pos, color } }
|
||||
|
||||
//fn binding_description() -> vk::VertexInputBindingDescription {
|
||||
// vk::VertexInputBindingDescription::builder()
|
||||
// .binding(0)
|
||||
// .stride(size_of::<Vertex>() as u32)
|
||||
// .input_rate(vk::VertexInputRate::VERTEX)
|
||||
// .build()
|
||||
//}
|
||||
|
||||
//fn attribute_descriptions() -> [vk::VertexInputAttributeDescription; 2] {
|
||||
// let pos = vk::VertexInputAttributeDescription::builder()
|
||||
// .binding(0)
|
||||
// .location(0)
|
||||
// .format(vk::Format::R32G32_SFLOAT)
|
||||
// .offset(0)
|
||||
// .build();
|
||||
|
||||
// let color = vk::VertexInputAttributeDescription::builder()
|
||||
// .binding(0)
|
||||
// .location(1)
|
||||
// .format(vk::Format::R32G32B32_SFLOAT)
|
||||
// .offset(size_of::<Vec2f>() as u32)
|
||||
// .build();
|
||||
|
||||
// [pos, color]
|
||||
//}
|
||||
}
|
||||
|
||||
const VERTEX_SHADER_SOURCE2:&[u8] = b"
|
||||
#version 450
|
||||
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
use anyhow::Result;
|
||||
use anyhow::anyhow;
|
||||
|
||||
use cgmath::Deg;
|
||||
use cgmath::point3;
|
||||
use cgmath::vec2;
|
||||
use cgmath::vec3;
|
||||
|
||||
use cgmath::Deg;
|
||||
use glfw::PWindow;
|
||||
|
||||
use log::*;
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
@ -33,6 +34,9 @@ use vulkanalia::vk::KhrSwapchainExtension;
|
|||
use crate::cataclysm::Cataclysm;
|
||||
|
||||
use super::GraphicsCommander;
|
||||
use super::Mat4f;
|
||||
use super::Vec2f;
|
||||
use super::Vec3f;
|
||||
|
||||
const VALIDATION_ENABLED:bool = cfg!(debug_assertions); // add env support?
|
||||
const VALIDATION_LAYER:vk::ExtensionName = vk::ExtensionName::from_bytes(b"VK_LAYER_KHRONOS_validation");
|
||||
|
@ -44,21 +48,11 @@ const VK_APPLICATION_NAME:&'static [u8; 8] = b"minemod\0";
|
|||
const VK_ENGINE_NAME:&'static [u8; 10] = b"cataclysm\0";
|
||||
const MAX_FRAMES_IN_FLIGHT:usize = 2;
|
||||
|
||||
// static VERTICES:[Vertex; 3] = [
|
||||
// Vertex::new(vec2(0.0, -0.5), vec3(0.3, 0.0, 1.0)),
|
||||
// Vertex::new(vec2(0.5, 0.5), vec3(0.3, 0.0, 1.0)),
|
||||
// Vertex::new(vec2(-0.5, 0.5), vec3(0.3, 0.0, 1.0)),
|
||||
// ];
|
||||
|
||||
static VERTICES:[Vertex; 4] = [
|
||||
const VERTICES:[Vertex; 4] = [
|
||||
Vertex::new(vec2(-0.5, -0.5), vec3(0.3, 0.0, 1.0)),
|
||||
Vertex::new(vec2(0.5, -0.5), vec3(0.3, 0.0, 1.0)),
|
||||
Vertex::new(vec2(0.5, 0.5), vec3(0.3, 0.0, 1.0)),
|
||||
Vertex::new(vec2(-0.5, 0.5), vec3(0.3, 0.0, 1.0)),
|
||||
// Vertex::new(vec2(-1.0, -1.0),vec3(0.3, 0.0, 1.0)),
|
||||
// Vertex::new(vec2(1.0, -1.0), vec3(0.3, 0.0, 1.0)),
|
||||
// Vertex::new(vec2(1.0, 1.0), vec3(0.3, 0.0, 1.0)),
|
||||
// Vertex::new(vec2(-1.0, 1.0), vec3(0.3, 0.0, 1.0)),
|
||||
];
|
||||
const INDICES:&[u16] = &[0, 1, 2, 2, 3, 0];
|
||||
|
||||
|
@ -85,9 +79,13 @@ pub(crate) struct App {
|
|||
}
|
||||
|
||||
impl GraphicsCommander for App {
|
||||
fn suspend_rendering(&mut self) { info!("SUSPEND") }
|
||||
fn suspend_rendering(&mut self) {
|
||||
warn!("Unimplemented!");
|
||||
}
|
||||
|
||||
fn resume_rendering(&mut self) { info!("RESUME") }
|
||||
fn resume_rendering(&mut self) {
|
||||
warn!("Unimplemented!");
|
||||
}
|
||||
|
||||
/// Renders a frame for our Vulkan app.
|
||||
fn render(&mut self, window:&mut PWindow, cataclysm:&mut Cataclysm) -> Result<()> {
|
||||
|
@ -159,11 +157,21 @@ impl GraphicsCommander for App {
|
|||
}
|
||||
}
|
||||
|
||||
fn register_vbos(&mut self, data:&[super::VertexData]) { todo!() }
|
||||
fn create_vxos(&mut self, data:&[super::VertexData]) {
|
||||
warn!("Unimplemented!");
|
||||
}
|
||||
|
||||
fn register_texture(&mut self) { todo!() }
|
||||
fn destroy_vxos(&mut self) {
|
||||
warn!("Unimplemented!");
|
||||
}
|
||||
|
||||
fn destroy_texture(&mut self) { todo!() }
|
||||
fn register_texture(&mut self) {
|
||||
warn!("Unimplemented!");
|
||||
}
|
||||
|
||||
fn destroy_texture(&mut self) {
|
||||
warn!("Unimplemented!");
|
||||
}
|
||||
|
||||
fn exit(&mut self) {
|
||||
info!("Destroying Vulkan instance.");
|
||||
|
|
|
@ -63,3 +63,5 @@ fn init_logging() {
|
|||
// test BCn vs raw formats
|
||||
|
||||
// research why texture atlases exist, it seems like an easy way to reduce the allocation calls since they are limited, and it seems to provide better usage of memory overall
|
||||
|
||||
// multirender system where both vulkan and opengl are active at once, each rendering half of the screen, can use to compare the two systems while working on them
|
||||
|
|
|
@ -1,16 +1,24 @@
|
|||
use anyhow::Result;
|
||||
|
||||
use cgmath::vec2;
|
||||
use cgmath::vec3;
|
||||
|
||||
use glfw::Action;
|
||||
use glfw::Context;
|
||||
use glfw::Key;
|
||||
|
||||
use log::*;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::cataclysm::Cataclysm;
|
||||
use crate::cataclysm::CataclysmChunk;
|
||||
use crate::cataclysm::SimpleBlock;
|
||||
|
||||
use crate::graphics_engines::GMode;
|
||||
use crate::graphics_engines::GraphicsCommander;
|
||||
use crate::graphics_engines::Vertex;
|
||||
use crate::graphics_engines::VertexData;
|
||||
|
||||
//#[cfg(target_os = "linux")] mod linux;
|
||||
//#[cfg(target_os = "linux")] pub use linux::*;
|
||||
|
@ -22,6 +30,15 @@ use crate::graphics_engines::GraphicsCommander;
|
|||
pub const WINDOW_TITLE:&'static str = "MineMod";
|
||||
pub const WINDOW_DECORATION_LEFT:bool = false;
|
||||
|
||||
pub fn shutdown_handler(sender:std::sync::mpsc::Sender<()>) {
|
||||
static SHUTDOWN_COUNT:std::sync::atomic::AtomicU8 = std::sync::atomic::AtomicU8::new(1);
|
||||
if SHUTDOWN_COUNT.fetch_add(1, std::sync::atomic::Ordering::SeqCst) >= 3 {
|
||||
warn!("3 exit events have piled up. Forcing exit.");
|
||||
std::process::exit(-1);
|
||||
}
|
||||
sender.send(()).expect("Failed to send shutdown signal");
|
||||
}
|
||||
|
||||
pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
crate::init_logging();
|
||||
|
||||
|
@ -29,26 +46,25 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
|
||||
let (shutdown_tx, shutdown_rx) = std::sync::mpsc::channel();
|
||||
|
||||
ctrlc::set_handler(move || {
|
||||
shutdown_tx.send(()).expect("Failed to send shutdown signal");
|
||||
})
|
||||
.expect("Error setting Ctrl-C handler");
|
||||
{
|
||||
let tx = shutdown_tx.clone();
|
||||
ctrlc::set_handler(move || shutdown_handler(tx.clone())).expect("Error setting Ctrl-C handler");
|
||||
}
|
||||
//std::thread::sleep(std::time::Duration::from_secs(10));
|
||||
|
||||
let mut glfw = glfw::init(|err, string| match err {
|
||||
// we dont give a shit because we supply our own render system
|
||||
glfw::Error::NoWindowContext /*| glfw::Error::NoError*/ => warn!("GLFW Error: {err} {string}"),
|
||||
glfw::Error::NoWindowContext => warn!("GLFW Error: {err} {string}"),
|
||||
_ => panic!("GLFW Error! {err}, {string}"),
|
||||
})?;
|
||||
|
||||
let graphics_mode = GMode::OpenGL;
|
||||
let mut graphics_mode = GMode::OpenGL;
|
||||
|
||||
// if we do not want to use opengl, disable it
|
||||
if graphics_mode != GMode::OpenGL {
|
||||
glfw.window_hint(glfw::WindowHint::ClientApi(glfw::ClientApiHint::NoApi));
|
||||
}
|
||||
|
||||
if let GMode::OpenGL = graphics_mode {}
|
||||
|
||||
let (mut window, events) = if let Some(glfw) = glfw.create_window(1024, 768, &WINDOW_TITLE, glfw::WindowMode::Windowed) {
|
||||
glfw
|
||||
} else {
|
||||
|
@ -57,21 +73,115 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
|
||||
window.set_key_polling(true);
|
||||
window.make_current();
|
||||
window.set_close_callback(move |_| shutdown_handler(shutdown_tx.clone()));
|
||||
|
||||
let mut cmd = /*Some(*/make_graphics_commander(graphics_mode, &mut window)?/*)*/;
|
||||
let mut graphics_commander = make_graphics_commander(graphics_mode, &mut window)?;
|
||||
|
||||
let mut opengl_cache = None;
|
||||
|
||||
// Register models
|
||||
|
||||
let verts:Box<[Vertex]> = Box::new([
|
||||
Vertex::new(vec2(-0.5, -0.5), vec3(0.3, 0.0, 1.0)),
|
||||
Vertex::new(vec2(0.5, -0.5), vec3(0.3, 0.0, 1.0)),
|
||||
Vertex::new(vec2(0.5, 0.5), vec3(0.3, 0.0, 1.0)),
|
||||
Vertex::new(vec2(-0.5, 0.5), vec3(0.3, 0.0, 1.0)),
|
||||
]);
|
||||
|
||||
graphics_commander.create_vxos(&[VertexData { verts, ..Default::default() }]);
|
||||
|
||||
// create game world
|
||||
|
||||
let mut game_world = Cataclysm::new();
|
||||
|
||||
game_world.chunks.insert((0, 0, 0), CataclysmChunk::new());
|
||||
//let mut inners = vec![];
|
||||
//let mut mids = vec![];
|
||||
//let mut outers = vec![];
|
||||
|
||||
for x in 0..Cataclysm::CHUNK_SIZE {
|
||||
for y in 0..Cataclysm::CHUNK_SIZE {
|
||||
for z in 0..Cataclysm::CHUNK_SIZE {
|
||||
game_world.chunks.get_mut(&(0, 0, 0)).unwrap().simple_blocks.insert((x, y, z), SimpleBlock {});
|
||||
let mut threads = vec![];
|
||||
let (sender, recv) = std::sync::mpsc::channel();
|
||||
let instant = std::time::Instant::now();
|
||||
//let mut count = 0;
|
||||
const RANGE:std::ops::Range<u32> = 0..1;
|
||||
for x in RANGE {
|
||||
'ml: loop {
|
||||
if threads.len() >= 4 {
|
||||
//info!("MAX");
|
||||
recv.recv().unwrap();
|
||||
break 'ml;
|
||||
} else {
|
||||
break 'ml;
|
||||
}
|
||||
}
|
||||
let sender = sender.clone();
|
||||
threads.push(std::thread::spawn(move || {
|
||||
info!("Spawned");
|
||||
let mut chunks:HashMap<(u32, u32, u32), CataclysmChunk> = HashMap::new();
|
||||
|
||||
let instant = std::time::Instant::now();
|
||||
for y in RANGE {
|
||||
//let instant = std::time::Instant::now();
|
||||
for z in RANGE {
|
||||
//let instant = std::time::Instant::now();
|
||||
chunks.insert((x, y, z), CataclysmChunk::new());
|
||||
for bx in 0..Cataclysm::CHUNK_SIZE {
|
||||
for by in 0..Cataclysm::CHUNK_SIZE {
|
||||
for bz in 0..Cataclysm::CHUNK_SIZE {
|
||||
chunks.get_mut(&(x, y, z)).unwrap().simple_blocks.insert((bx, by, bz), SimpleBlock {});
|
||||
//count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
//inners.push(std::time::Instant::now() - instant);
|
||||
}
|
||||
//mids.push(std::time::Instant::now() - instant);
|
||||
}
|
||||
//outers.push(std::time::Instant::now() - instant);
|
||||
|
||||
sender.send(()).unwrap();
|
||||
chunks
|
||||
}));
|
||||
}
|
||||
//dbg!(count);
|
||||
|
||||
let mut master_chunkmap:HashMap<(u32, u32, u32), CataclysmChunk> = HashMap::new();
|
||||
for t in threads {
|
||||
let chunks = t.join().unwrap();
|
||||
for (_id, (key, value)) in chunks.iter().enumerate() {
|
||||
if let Some(val) = master_chunkmap.insert(*key, value.clone()) {
|
||||
warn!("Existing value present! {:?}", val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
game_world.chunks = master_chunkmap;
|
||||
|
||||
//{
|
||||
// let mut avg = 0.0;
|
||||
// for i in &inners {
|
||||
// avg += i.as_secs_f32();
|
||||
// }
|
||||
// avg = avg / inners.len() as f32;
|
||||
// info!("inners:{avg}");
|
||||
// avg = 0.0;
|
||||
// for i in &mids {
|
||||
// avg += i.as_secs_f32();
|
||||
// }
|
||||
// avg = avg / mids.len() as f32;
|
||||
// info!("mids:{avg}");
|
||||
// avg = 0.0;
|
||||
// for i in &outers {
|
||||
// avg += i.as_secs_f32();
|
||||
// }
|
||||
// avg = avg / outers.len() as f32;
|
||||
// info!("outers:{avg}");
|
||||
//}
|
||||
info!("MASTER: {}", (std::time::Instant::now() - instant).as_secs_f32());
|
||||
|
||||
//return Ok(());
|
||||
|
||||
let mut graphics_commander = Some(graphics_commander);
|
||||
|
||||
//'mainloop: while !window.should_close() {
|
||||
loop {
|
||||
if shutdown_rx.try_recv().is_ok() {
|
||||
|
@ -79,11 +189,8 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
window.set_should_close(true);
|
||||
}
|
||||
|
||||
// Swap front and back buffers
|
||||
//window.swap_buffers(); // cannot be used
|
||||
|
||||
// dont flood the logs
|
||||
//std::thread::sleep(Duration::from_secs(1));
|
||||
//std::thread::sleep(std::time::Duration::from_secs(1));
|
||||
|
||||
trace!("Polling GLFW events.");
|
||||
// Poll for and process events
|
||||
|
@ -93,38 +200,53 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
info!("GLFW Event: {:?}", event);
|
||||
match event {
|
||||
//glfw::WindowEvent::FramebufferSize(x, y) => {},
|
||||
//glfw::WindowEvent::Close => window.set_should_close(true),
|
||||
// minimize? doesnt appear to be
|
||||
glfw::WindowEvent::Iconify(e) =>
|
||||
//if let Some(cmd) = graphics_commander.as_mut() {
|
||||
if e {
|
||||
cmd.suspend_rendering();
|
||||
} else {
|
||||
cmd.resume_rendering();
|
||||
if let Some(graphics_commander) = graphics_commander.as_mut() {
|
||||
if e {
|
||||
graphics_commander.suspend_rendering();
|
||||
} else {
|
||||
graphics_commander.resume_rendering();
|
||||
}
|
||||
},
|
||||
//},
|
||||
glfw::WindowEvent::Key(key, _, Action::Press, _) => match key {
|
||||
Key::Escape | Key::Q => window.set_should_close(true),
|
||||
//Key::E => {
|
||||
//if let Some(cmd) = graphics_commander.as_mut() {
|
||||
// cmd.exit();
|
||||
//}
|
||||
//let _gc = graphics_commander.take();
|
||||
//match graphics_mode {
|
||||
// GMode::Vulkan => graphics_mode = GMode::OpenGL,
|
||||
// GMode::OpenGL => graphics_mode = GMode::Vulkan,
|
||||
// #[cfg(target_os = "macos")]
|
||||
// GMode::Metal => todo!(),
|
||||
// #[cfg(target_os = "windows")]
|
||||
// GMode::DirectX => todo!(),
|
||||
//}
|
||||
//graphics_commander = Some(make_graphics_commander(graphics_mode, &mut window)?);
|
||||
//},
|
||||
Key::E => {
|
||||
match graphics_mode {
|
||||
GMode::Vulkan => {
|
||||
info!("v1 mode{:?} cmd{} cache{}", graphics_mode, graphics_commander.is_some(), opengl_cache.is_some());
|
||||
|
||||
if let Some(mut graphics_commander) = graphics_commander.take() {
|
||||
graphics_commander.exit();
|
||||
}
|
||||
info!("v2 mode{:?} cmd{} cache{}", graphics_mode, graphics_commander.is_some(), opengl_cache.is_some());
|
||||
graphics_mode = GMode::OpenGL;
|
||||
graphics_commander = opengl_cache.take();
|
||||
if graphics_commander.is_none() {
|
||||
error!("OpenGL was expected but not present");
|
||||
graphics_commander = Some(make_graphics_commander(graphics_mode, &mut window)?);
|
||||
}
|
||||
info!("v3 mode{:?} cmd{} cache{}", graphics_mode, graphics_commander.is_some(), opengl_cache.is_some());
|
||||
},
|
||||
GMode::OpenGL => {
|
||||
info!("o1 mode{:?} cmd{} cache{}", graphics_mode, graphics_commander.is_some(), opengl_cache.is_some());
|
||||
//graphics_commander.clean();
|
||||
opengl_cache = graphics_commander.take();
|
||||
info!("o2 mode{:?} cmd{} cache{}", graphics_mode, graphics_commander.is_some(), opengl_cache.is_some());
|
||||
|
||||
graphics_mode = GMode::Vulkan;
|
||||
graphics_commander = Some(make_graphics_commander(graphics_mode, &mut window)?);
|
||||
info!("o3 mode{:?} cmd{} cache{}", graphics_mode, graphics_commander.is_some(), opengl_cache.is_some());
|
||||
},
|
||||
#[cfg(target_os = "macos")]
|
||||
GMode::Metal => todo!(),
|
||||
#[cfg(target_os = "windows")]
|
||||
GMode::DirectX => todo!(),
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
},
|
||||
event => {
|
||||
dbg!(event);
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,17 +255,17 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
break;
|
||||
}
|
||||
|
||||
//if let Some(cmd) = graphics_commander.as_mut() {
|
||||
trace!("Rendering.");
|
||||
//cmd.render_simple_blocks(game_world.chunks.get_mut(&(0, 0, 0)).unwrap().simple_blocks);
|
||||
cmd.render(&mut window, &mut game_world)?;
|
||||
//}
|
||||
if let Some(graphics_commander) = graphics_commander.as_mut() {
|
||||
trace!("Rendering.");
|
||||
//cmd.render_simple_blocks(game_world.chunks.get_mut(&(0, 0, 0)).unwrap().simple_blocks);
|
||||
graphics_commander.render(&mut window, &mut game_world)?;
|
||||
}
|
||||
}
|
||||
|
||||
//if let Some(cmd) = graphics_commander.as_mut() {
|
||||
info!("Closing GC instance.");
|
||||
cmd.exit();
|
||||
//}
|
||||
if let Some(graphics_commander) = graphics_commander.as_mut() {
|
||||
info!("Closing GC instance.");
|
||||
graphics_commander.exit();
|
||||
}
|
||||
|
||||
info!("Exiting.");
|
||||
Ok(())
|
||||
|
@ -152,7 +274,7 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
fn make_graphics_commander(graphics_mode:GMode, window:&mut glfw::PWindow) -> Result<Box<dyn GraphicsCommander>> {
|
||||
Ok(match graphics_mode {
|
||||
GMode::Vulkan => Box::new(unsafe { crate::graphics_engines::vulkan_gc::App::create(&window)? }),
|
||||
GMode::OpenGL => Box::new(crate::graphics_engines::opengl::Renderer::create(window)?),
|
||||
GMode::OpenGL => Box::new(crate::graphics_engines::opengl::CataclysmOGL::create(window)?),
|
||||
#[cfg(target_os = "macos")]
|
||||
GMode::Metal => todo!(),
|
||||
#[cfg(target_os = "windows")]
|
||||
|
|
Loading…
Add table
Reference in a new issue