diff options
author | pommicket <pommicket@gmail.com> | 2022-12-16 21:41:17 -0500 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2022-12-16 21:41:17 -0500 |
commit | 1e54105088c429fd4773a5bf6271c145b191aa66 (patch) | |
tree | ffbc2118cee383b5729e907a2d26b7a2ef4ce87b /src | |
parent | 9640172fa1429ae1271ac90bb5c9d5d7c21f50a4 (diff) |
start framebuffer stuff
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 10 | ||||
-rw-r--r-- | src/win.rs | 153 |
2 files changed, 127 insertions, 36 deletions
diff --git a/src/main.rs b/src/main.rs index 26abb34..d3700bb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,6 +28,11 @@ commit d7f810524a30843417253f80e454f1d9173aaeb3 "more functions" 2607779313513160780 16956394651920792998 3714031566539178742 +--- +the era of serialization +a263736466a169536d6f6f74684d696e82a169536d6f6f74684d696e82a1634d696e82a166537068657265a163463332fa3ee5212ca167436f6d706f736583a167436f6d706f736582a167436f6d706f736582684964656e74697479684964656e74697479675369676d6f6964a166537068657265a163463332fa3f7bf840684964656e74697479a1634d697883a165546f727573a266726164697573a163463332fa3f1b29f269746869636b6e657373a163463332fa3e08d8c8a167436f6d706f736583a16f496e66696e6974654d6972726f7273a163463332fa3e59bc38a16443756265a163463332fa3f155e80684964656e74697479a163463332fa3f42e49aa168426f784672616d65a26473697a65a163463332fa4034884d69746869636b6e657373a163463332fa3d0bd15a6e636f6c6f725f66756e6374696f6ea167436f6d706f736582a16641726374616ea163463332fa3eea41e4a16f496e66696e6974654d6972726f7273a163463332fa3f5ddffe +a263736466a167436f6d706f736583a166526f7461746583a163463332fa3f76cab2a163463332fa3d81cad0a163463332fa3f76ebd4a1634d696e82a167436f6d706f736583675369676d6f6964a1634d696e82a1634d697883a167436f6d706f736583684964656e74697479a166537068657265a163463332fa3e5a3e68684964656e74697479a167436f6d706f736583684964656e74697479a166537068657265a163463332fa3f46ade4684964656e74697479a163463332fa3f551da4a1634d696e82a167436f6d706f736583684964656e74697479a166537068657265a163463332fa3f306be8684964656e74697479a167436f6d706f736583684964656e74697479a166537068657265a163463332fa3ca99ac0684964656e74697479684964656e74697479a167436f6d706f736583a16f496e66696e6974654d6972726f7273a163463332fa3e9febeca167436f6d706f736583a16f496e66696e6974654d6972726f7273a163463332fa3ee05424a167436f6d706f736583675369676d6f6964a1634d696e82a166537068657265a163463332fa3e16dcf0a166537068657265a163463332fa3f48f0dc684964656e74697479684964656e74697479684964656e74697479684964656e746974796e636f6c6f725f66756e6374696f6ea167436f6d706f736582a16353696ea163463332fa3f1c2a8e675369676d6f6964 +a263736466a167436f6d706f736583a165537153696ea163463332fa3e784c98a1634d697883a166537068657265a163463332fa3ea1ce4ca1634d696e82a166537068657265a163463332fa3f55f124a167436f6d706f736583675369676d6f6964a166537068657265a163463332fa3ef84fb0684964656e74697479a163463332fa3d2f72c0684964656e746974796e636f6c6f725f66756e6374696f6ea16f496e66696e6974654d6972726f7273a163463332fa3e9d85d0 */ extern crate nalgebra; @@ -203,7 +208,9 @@ void main() { float threshold = 0.02; if (min_dist < threshold) { vec3 N = normal(p); - vec3 light_direction = normalize(vec3(.8,1,.6)); + // light direction = towards player + // this makes it seem like the player is pointing a flashlight at the object. + vec3 light_direction = u_rotation * vec3(0.0, 0.0, 1.0); float L_diffuse = max(0., dot(N, light_direction)); // Phong lighting vec3 R = reflect(light_direction, N); @@ -379,6 +386,7 @@ fn try_main() -> Result<(), String> { window.uniform1f("u_fov", std::f32::consts::PI * 0.25); window.uniform1f("u_focal_length", 1.0); window.uniform1f("u_level_set", view.level_set); + window.uniform1i("u_hsv", 0); window.uniform3x3f("u_rotation", view.rotation().as_slice()); window.uniform3f_slice("u_translation", view.pos.as_slice()); @@ -652,6 +652,49 @@ pub struct Texture { params: TextureParams, } +impl Texture { + unsafe fn bind(&self) { + gl::BindTexture(gl::TEXTURE_2D, self.id); + } + + unsafe fn set_data(&mut self, data: &[u8], width: usize, height: usize) -> Result<(), String> { + let width = width as GLsizei; + let height = height as GLsizei; + let expected_len = 4 * width * height; + if data.len() as GLsizei != expected_len { + return Err(format!( + "bad data length (expected {}, got {})", + expected_len, + data.len() + )); + } + let params = &self.params; + self.bind(); + gl::TexImage2D( + gl::TEXTURE_2D, + 0, + gl::RGBA as _, + width, + height, + 0, + gl::RGBA, + gl::UNSIGNED_BYTE, + data.as_ptr() as _, + ); + gl::TexParameteri( + gl::TEXTURE_2D, + gl::TEXTURE_MIN_FILTER, + params.min_filter.to_gl(), + ); + gl::TexParameteri( + gl::TEXTURE_2D, + gl::TEXTURE_MAG_FILTER, + params.mag_filter.to_gl(), + ); + Ok(()) + } +} + impl Drop for Texture { fn drop(&mut self) { unsafe { gl::DeleteTextures(1, (&self.id) as *const GLuint) }; @@ -689,6 +732,69 @@ impl Default for TextureParams { } } +#[derive(Clone, Copy)] +pub enum FramebufferAttachment { + // 8 color attachments ought to be enough for anyone. + Color0, + Color1, + Color2, + Color3, + Color4, + Color5, + Color6, + Color7, + Depth, + Stencil, + DepthStencil +} + +impl FramebufferAttachment { + fn to_gl(self) -> GLenum { + use FramebufferAttachment::*; + match self { + Color0 => gl::COLOR_ATTACHMENT0, + Color1 => gl::COLOR_ATTACHMENT1, + Color2 => gl::COLOR_ATTACHMENT2, + Color3 => gl::COLOR_ATTACHMENT3, + Color4 => gl::COLOR_ATTACHMENT4, + Color5 => gl::COLOR_ATTACHMENT5, + Color6 => gl::COLOR_ATTACHMENT6, + Color7 => gl::COLOR_ATTACHMENT7, + Depth => gl::DEPTH_ATTACHMENT, + Stencil => gl::STENCIL_ATTACHMENT, + DepthStencil => gl::DEPTH_STENCIL_ATTACHMENT, + } + } +} + +pub struct Framebuffer { + id: GLuint +} + +impl Framebuffer { + unsafe fn new() -> Self { + let mut id: GLuint = 0; + gl::GenFramebuffers(1, (&mut id) as *mut GLuint); + Self { id } + } + + unsafe fn bind(&self) { + gl::BindTexture(gl::FRAMEBUFFER, self.id); + } + + unsafe fn set_texture(&mut self, attachment: FramebufferAttachment, texture: &Texture) { + self.bind(); + texture.bind(); + gl::FramebufferTexture2D(gl::FRAMEBUFFER, attachment.to_gl(), gl::TEXTURE_2D, texture.id, 0); + } +} + +impl Drop for Framebuffer { + fn drop(&mut self) { + unsafe { gl::DeleteFramebuffers(1, (&self.id) as *const GLuint) }; + } +} + impl Window { pub fn new(title: &str, width: i32, height: i32, shown: bool) -> Result<Self, String> { { @@ -816,6 +922,17 @@ impl Window { pub fn array_attrib4f(&mut self, array: &mut VertexArray, name: &str, offset: usize) -> bool { self.array_attribnf(array, 4, name, offset) } + + pub fn create_framebuffer(&mut self) -> Framebuffer { + unsafe { Framebuffer::new() } + } + + /// Attach texture to framebuffer. + /// In theory this should check that `framebuffer` does not outlive `texture`, + /// but that would be difficult to do in a nice way. + pub fn set_framebuffer_texture(&mut self, framebuffer: &mut Framebuffer, attachment: FramebufferAttachment, texture: &Texture) { + unsafe { framebuffer.set_texture(attachment, texture) }; + } pub fn size(&self) -> (i32, i32) { let mut x = 0; @@ -893,41 +1010,7 @@ impl Window { width: usize, height: usize, ) -> Result<(), String> { - let width = width as GLsizei; - let height = height as GLsizei; - let expected_len = 4 * width * height; - if data.len() as GLsizei != expected_len { - return Err(format!( - "bad data length (expected {}, got {})", - expected_len, - data.len() - )); - } - let params = &texture.params; - unsafe { - gl::BindTexture(gl::TEXTURE_2D, texture.id); - gl::TexImage2D( - gl::TEXTURE_2D, - 0, - gl::RGBA as _, - width, - height, - 0, - gl::RGBA, - gl::UNSIGNED_BYTE, - data.as_ptr() as _, - ); - gl::TexParameteri( - gl::TEXTURE_2D, - gl::TEXTURE_MIN_FILTER, - params.min_filter.to_gl(), - ); - gl::TexParameteri( - gl::TEXTURE_2D, - gl::TEXTURE_MAG_FILTER, - params.mag_filter.to_gl(), - ); - } + unsafe { texture.set_data(data, width, height) }?; Ok(()) } |