parent
6fbddb3c86
commit
116fd3bc45
|
@ -2,7 +2,7 @@
|
||||||
name = "opengl_rust"
|
name = "opengl_rust"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["_"]
|
authors = ["_"]
|
||||||
edition = "2018"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,96 @@
|
||||||
use opengl_rust::prelude::*;
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use maplit::hashmap;
|
||||||
|
|
||||||
|
use opengl_rust::{
|
||||||
|
prelude::*,
|
||||||
|
gl_state::*,
|
||||||
|
renderable_model::{
|
||||||
|
attributes,
|
||||||
|
RenderableModel,
|
||||||
|
},
|
||||||
|
shader_closure::ShaderLookup,
|
||||||
|
texture::Texture,
|
||||||
|
};
|
||||||
|
|
||||||
|
mod uniforms {
|
||||||
|
use iota::iota;
|
||||||
|
iota! {
|
||||||
|
pub const
|
||||||
|
MVP: u32 = iota;
|
||||||
|
, OBJECT_SPACE_LIGHT
|
||||||
|
, OBJECT_SPACE_SKY
|
||||||
|
, ALBEDO
|
||||||
|
, MIN_ALBEDO
|
||||||
|
, MIN_BRIGHT
|
||||||
|
, TEXTURE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GameGraphics {
|
||||||
|
passes: Vec <Pass>,
|
||||||
|
|
||||||
|
shaders: Vec <ShaderClosure>,
|
||||||
|
shader_lookup: HashMap <u32, usize>,
|
||||||
|
|
||||||
|
mesh_cube: RenderableModel,
|
||||||
|
mesh_sky: RenderableModel,
|
||||||
|
|
||||||
|
text_stream: TriangleStream,
|
||||||
|
|
||||||
|
texture_sky: Texture,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ShaderLookup for GameGraphics {
|
||||||
|
fn lookup <'a> (&'a self, id: u32) -> &'a ShaderClosure {
|
||||||
|
&self.shaders [self.shader_lookup [&id]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GameGraphics {
|
||||||
|
fn draw (
|
||||||
|
&self,
|
||||||
|
gl_state: &mut GlState,
|
||||||
|
) {
|
||||||
|
use uniforms as u;
|
||||||
|
|
||||||
|
let white = color_from_255 ((255.0, 255.0, 255.0));
|
||||||
|
let black = color_from_255 ((0.0, 0.0, 0.0));
|
||||||
|
|
||||||
|
let screen_size = (1280.0, 720.0);
|
||||||
|
|
||||||
|
let proj_mat = Mat4::perspective_rh_gl (30.0f32.to_radians (), screen_size.0 / screen_size.1, 0.125, 200.0);
|
||||||
|
|
||||||
|
let view_mat = proj_mat * Mat4::from_rotation_x (-90.0f32.to_radians ());
|
||||||
|
let world_model_mat = Mat4::IDENTITY;
|
||||||
|
|
||||||
|
self.passes [0].with (gl_state, || {
|
||||||
|
glezz::clear_color (1.0f32, 0.0f32, 1.0f32, 1.0f32);
|
||||||
|
glezz::clear (gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT | gl::STENCIL_BUFFER_BIT);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.passes [1].with_shader (gl_state, self, |shader_vars| {
|
||||||
|
let attrs = shader_vars.attrs;
|
||||||
|
let unis = shader_vars.unis;
|
||||||
|
|
||||||
|
{
|
||||||
|
let sky_mvp_mat = view_mat * Mat4::from_scale ((64.0, 64.0, 64.0).into ());
|
||||||
|
|
||||||
|
self.texture_sky.bind ();
|
||||||
|
glezz::uniform_matrix_4fv (unis [&u::MVP], &sky_mvp_mat);
|
||||||
|
glezz::uniform_3fv (unis [&u::ALBEDO], &white);
|
||||||
|
glezz::uniform_3fv (unis [&u::MIN_BRIGHT], &white);
|
||||||
|
glezz::uniform_3fv (unis [&u::MIN_ALBEDO], &black);
|
||||||
|
glezz::uniform_1i (unis [&u::TEXTURE], 0);
|
||||||
|
|
||||||
|
self.mesh_sky.draw_all (attrs, |_| true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main () -> Result <()> {
|
async fn main () -> Result <()> {
|
||||||
|
@ -29,10 +119,140 @@ async fn main () -> Result <()> {
|
||||||
let mut time_step = TimeStep::new (60, 1000);
|
let mut time_step = TimeStep::new (60, 1000);
|
||||||
let mut graphics_frames = 0;
|
let mut graphics_frames = 0;
|
||||||
|
|
||||||
let shader_program = shader::shader_from_files ("shaders/terrain-vert.glsl", "shaders/terrain-frag.glsl");
|
let uniform_names = {
|
||||||
let shader_locations = ShaderLocations::new (&shader_program)?;
|
vec! [
|
||||||
|
(uniforms::MVP, "uni_mvp"),
|
||||||
|
(uniforms::OBJECT_SPACE_LIGHT, "uni_object_space_light"),
|
||||||
|
(uniforms::OBJECT_SPACE_SKY, "uni_object_space_sky"),
|
||||||
|
(uniforms::ALBEDO, "uni_albedo"),
|
||||||
|
(uniforms::MIN_ALBEDO, "uni_min_albedo"),
|
||||||
|
(uniforms::MIN_BRIGHT, "uni_min_bright"),
|
||||||
|
(uniforms::TEXTURE, "uni_texture"),
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
let attr_names = {
|
||||||
|
vec! [
|
||||||
|
(attributes::POS, "attr_pos"),
|
||||||
|
(attributes::UV, "attr_uv"),
|
||||||
|
(attributes::NORMAL, "attr_normal"),
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
let shaders: Vec <_> = [
|
||||||
|
("shaders/pumpkin-vert.glsl", "shaders/pumpkin-frag.glsl"),
|
||||||
|
("shaders/shadow-vert.glsl", "shaders/shadow-frag.glsl"),
|
||||||
|
("shaders/terrain-vert.glsl", "shaders/terrain-frag.glsl"),
|
||||||
|
].into_iter ()
|
||||||
|
.map (|(v, f)| {
|
||||||
|
ShaderClosure::new (shader_from_files (v, f), &uniform_names, &attr_names)
|
||||||
|
})
|
||||||
|
.collect ();
|
||||||
|
|
||||||
let mesh_cube = renderable_from_iqm_file ("cube.iqm");
|
let mesh_cube = renderable_from_iqm_file ("cube.iqm");
|
||||||
|
let mesh_sky = renderable_from_iqm_file ("sky-sphere.iqm");
|
||||||
|
|
||||||
|
let passes = vec![
|
||||||
|
// Clear everything
|
||||||
|
Pass {
|
||||||
|
iso: IsoGlState {
|
||||||
|
shader_id: None,
|
||||||
|
flags: Default::default (),
|
||||||
|
front_face: None,
|
||||||
|
stencil: None,
|
||||||
|
depth_func: None,
|
||||||
|
color_mask: Some ((1, 1, 1, 1)),
|
||||||
|
depth_mask: Some (1),
|
||||||
|
stencil_mask: Some (255),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Draw world
|
||||||
|
Pass {
|
||||||
|
iso: IsoGlState {
|
||||||
|
shader_id: Some (shaders [0].get_id ()),
|
||||||
|
flags: hashmap! {
|
||||||
|
gl::CULL_FACE => true,
|
||||||
|
gl::DEPTH_TEST => true,
|
||||||
|
gl::TEXTURE_2D => true,
|
||||||
|
gl::STENCIL_TEST => false,
|
||||||
|
},
|
||||||
|
front_face: Some (FrontFace::Cw),
|
||||||
|
stencil: Some (StencilState {
|
||||||
|
func: StencilFuncState {
|
||||||
|
func: StencilFunc::Always,
|
||||||
|
reference: 0,
|
||||||
|
mask: 0,
|
||||||
|
},
|
||||||
|
op: StencilOpState {
|
||||||
|
sfail: StencilOp::Keep,
|
||||||
|
dpfail: StencilOp::Keep,
|
||||||
|
dppass: StencilOp::Keep,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
depth_func: Some (DepthFunc::Less),
|
||||||
|
color_mask: Some ((1, 1, 1, 1)),
|
||||||
|
depth_mask: Some (1),
|
||||||
|
stencil_mask: Some (0),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Draw UI
|
||||||
|
Pass {
|
||||||
|
iso: IsoGlState {
|
||||||
|
shader_id: Some (shaders [0].get_id ()),
|
||||||
|
flags: hashmap! {
|
||||||
|
gl::CULL_FACE => false,
|
||||||
|
gl::DEPTH_TEST => false,
|
||||||
|
gl::TEXTURE_2D => true,
|
||||||
|
gl::STENCIL_TEST => false,
|
||||||
|
},
|
||||||
|
front_face: None,
|
||||||
|
stencil: None,
|
||||||
|
depth_func: Some (DepthFunc::Less),
|
||||||
|
color_mask: Some ((1, 1, 1, 1)),
|
||||||
|
depth_mask: Some (1),
|
||||||
|
stencil_mask: Some (0),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
let text_stream = TriangleStream {
|
||||||
|
verts: gpu_buffers::VertexBuffer::streaming (4 * 5 * 6 * 1024),
|
||||||
|
indices: {
|
||||||
|
let quad = [
|
||||||
|
0, 1, 2,
|
||||||
|
0, 2, 3,
|
||||||
|
];
|
||||||
|
|
||||||
|
let v: Vec <u32> = (0u32..1024).map (|i| {
|
||||||
|
quad.iter ().map (move |j| 4 * i + j)
|
||||||
|
}).flatten ().collect ();
|
||||||
|
gpu_buffers::IndexBuffer::from_slice_u32 (&v)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let shader_lookup = HashMap::from_iter (shaders.iter ().enumerate ()
|
||||||
|
.map (|(i, s)| {
|
||||||
|
(s.get_id (), i)
|
||||||
|
}));
|
||||||
|
|
||||||
|
shaders [0].with (None, |shader_vars| {
|
||||||
|
let attrs = shader_vars.attrs;
|
||||||
|
glezz::enable_vertex_attrib_array (attrs [attributes::POS]);
|
||||||
|
glezz::enable_vertex_attrib_array (attrs [attributes::UV]);
|
||||||
|
glezz::enable_vertex_attrib_array (attrs [attributes::NORMAL]);
|
||||||
|
});
|
||||||
|
|
||||||
|
let graphics = GameGraphics {
|
||||||
|
mesh_cube,
|
||||||
|
mesh_sky,
|
||||||
|
passes,
|
||||||
|
shader_lookup,
|
||||||
|
shaders,
|
||||||
|
text_stream,
|
||||||
|
texture_sky: Texture::from_file ("sky.png"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut gl_state = Default::default ();
|
||||||
|
|
||||||
'running: loop {
|
'running: loop {
|
||||||
let _frames_to_do = time_step.step ();
|
let _frames_to_do = time_step.step ();
|
||||||
|
@ -49,12 +269,10 @@ async fn main () -> Result <()> {
|
||||||
|
|
||||||
window.gl_make_current (&gl_ctx).unwrap ();
|
window.gl_make_current (&gl_ctx).unwrap ();
|
||||||
|
|
||||||
glezz::enable (gl::DEPTH_TEST);
|
graphics.draw (&mut gl_state);
|
||||||
|
|
||||||
glezz::clear_color (0.392f32, 0.710f32, 0.965f32, 1.0f32);
|
|
||||||
glezz::clear (gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT | gl::STENCIL_BUFFER_BIT);
|
|
||||||
|
|
||||||
window.gl_swap_window ();
|
window.gl_swap_window ();
|
||||||
|
graphics_frames += 1;
|
||||||
|
|
||||||
tokio::time::sleep (Duration::from_millis (15)).await;
|
tokio::time::sleep (Duration::from_millis (15)).await;
|
||||||
}
|
}
|
||||||
|
@ -70,7 +288,7 @@ struct ShaderLocations {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ShaderLocations {
|
impl ShaderLocations {
|
||||||
pub fn new (shader_program: &shader::ShaderProgram) -> anyhow::Result <Self>
|
pub fn new (shader_program: &opengl_rust::shader::ShaderProgram) -> anyhow::Result <Self>
|
||||||
{
|
{
|
||||||
let attr = |name: &str| shader_program.get_attribute_location (&CString::new (name.as_bytes ())?).try_into ().context ("Attribute location negative");
|
let attr = |name: &str| shader_program.get_attribute_location (&CString::new (name.as_bytes ())?).try_into ().context ("Attribute location negative");
|
||||||
let uni = |name: &str| shader_program.get_uniform_location (&CString::new (name.as_bytes ())?).try_into ().context ("Uniform location bad");
|
let uni = |name: &str| shader_program.get_uniform_location (&CString::new (name.as_bytes ())?).try_into ().context ("Uniform location bad");
|
||||||
|
@ -83,3 +301,20 @@ impl ShaderLocations {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct TriangleStream {
|
||||||
|
pub verts: gpu_buffers::VertexBuffer,
|
||||||
|
pub indices: gpu_buffers::IndexBuffer,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn color_from_255 <V> (rgb: V) -> Vec3
|
||||||
|
where V: Into <Vec3>
|
||||||
|
{
|
||||||
|
let rgb: Vec3 = rgb.into ();
|
||||||
|
|
||||||
|
Vec3::from ((
|
||||||
|
rgb.x / 255.0,
|
||||||
|
rgb.y / 255.0,
|
||||||
|
rgb.z / 255.0
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ pub use crate::{
|
||||||
network_protocol::*,
|
network_protocol::*,
|
||||||
quinn_common::make_client_endpoint,
|
quinn_common::make_client_endpoint,
|
||||||
renderable_model::renderable_from_iqm_file,
|
renderable_model::renderable_from_iqm_file,
|
||||||
shader,
|
shader::shader_from_files,
|
||||||
|
shader_closure::ShaderClosure,
|
||||||
timestep::TimeStep,
|
timestep::TimeStep,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue