add texturing to gear renderer
authoralfadur
Sat, 14 Nov 2020 03:46:01 +0300
changeset 15786 b10bbfb2b354
parent 15785 f6af9d05b03c
child 15787 713f89f6c6ab
add texturing to gear renderer
rust/lib-hedgewars-engine/src/render/gear.rs
rust/lib-hedgewars-engine/src/render/gl.rs
rust/lib-hedgewars-engine/src/world.rs
--- a/rust/lib-hedgewars-engine/src/render/gear.rs	Fri Nov 13 20:59:13 2020 +0300
+++ b/rust/lib-hedgewars-engine/src/render/gear.rs	Sat Nov 14 03:46:01 2020 +0300
@@ -4,6 +4,7 @@
     gl::{
         Buffer, BufferType, BufferUsage, InputElement, InputFormat, InputLayout, PipelineState,
         Shader, Texture2D, TextureDataType, TextureFilter, TextureFormat, TextureInternalFormat,
+        VariableBinding,
     },
 };
 
@@ -24,11 +25,15 @@
 const VERTEX_SHADER: &'static str = r#"
 #version 330 core
 
-layout(location = 0) in vec2 position;
-
 uniform mat4 projection;
 
+layout(location = 0) in vec2 position;
+layout(location = 1) in vec2 texCoords;
+
+out vec2 varTexCoords;
+
 void main() {
+    varTexCoords = texCoords;
 	gl_Position = projection * vec4(position, 0.0, 1.0);
 }
 "#;
@@ -36,17 +41,22 @@
 const PIXEL_SHADER: &'static str = r#"
 #version 330 core
 
+uniform sampler2D texture;
+
+in vec2 varTexCoords;
+
 out vec4 outColor;
 
 void main() {
-	 outColor = vec4(0.0, 1.0, 0.0, 1.0);
+	 outColor = texture2D(texture, varTexCoords);
 }
 "#;
 
 #[repr(C)]
 #[derive(Copy, Clone)]
 struct Vertex {
-    pos: [f32; 2],
+    position: [f32; 2],
+    tex_coords: [f32; 2],
 }
 
 #[derive(PartialEq, Debug, Clone, Copy)]
@@ -86,6 +96,7 @@
 
 pub struct GearRenderer {
     atlas: AtlasCollection,
+    texture: Texture2D,
     allocation: Box<[SpriteLocation; MAX_SPRITES]>,
     shader: Shader,
     layout: InputLayout,
@@ -119,13 +130,12 @@
                 .expect(&format!("Could not store sprite {:?}", sprite));
             let (texture_index, rect) = atlas.get_rect(index).unwrap();
 
-            let mut pixels = vec![0; size.area()].into_boxed_slice();
-            load_sprite_pixels(path, mapgen::theme::slice_u32_to_u8_mut(&mut pixels[..]))
-                .expect("Unable to load Graphics");
+            let mut pixels = vec![255u8; size.area() * 4].into_boxed_slice();
+            load_sprite_pixels(path, &mut pixels).expect("Unable to load Graphics");
 
             texture.update(
                 rect,
-                mapgen::theme::slice_u32_to_u8_mut(&mut pixels[..]),
+                &pixels,
                 None,
                 TextureFormat::Rgba,
                 TextureDataType::UnsignedByte,
@@ -134,10 +144,14 @@
             allocation[*sprite as usize] = (texture_index, rect);
         }
 
-        let shader = Shader::new(VERTEX_SHADER, Some(PIXEL_SHADER), &[]).unwrap();
+        let shader = Shader::new(
+            VERTEX_SHADER,
+            Some(PIXEL_SHADER),
+            &[VariableBinding::Sampler("texture", 0)],
+        )
+        .unwrap();
 
         let layout = InputLayout::new(vec![
-            // position
             InputElement {
                 shader_slot: 0,
                 buffer_slot: 0,
@@ -146,12 +160,21 @@
                 stride: size_of::<Vertex>() as u32,
                 offset: 0,
             },
+            InputElement {
+                shader_slot: 1,
+                buffer_slot: 0,
+                format: InputFormat::Float(gl::FLOAT, false),
+                components: 2,
+                stride: size_of::<Vertex>() as u32,
+                offset: size_of::<[f32; 2]>() as u32,
+            },
         ]);
 
         let vertex_buffer = Buffer::empty(BufferType::Array, BufferUsage::DynamicDraw);
 
         Self {
             atlas,
+            texture,
             allocation,
             shader,
             layout,
@@ -160,50 +183,51 @@
     }
 
     pub fn render(&mut self, camera: &Camera, entries: &[GearEntry]) {
+        let mut data = Vec::with_capacity(entries.len() * 6);
+
+        for entry in entries {
+            let v = [
+                Vertex {
+                    position: [
+                        entry.position[0] - entry.size.width as f32 / 2.0,
+                        entry.position[1] + entry.size.height as f32 / 2.0,
+                    ],
+                    tex_coords: [0.0, 0.015625],
+                },
+                Vertex {
+                    position: [
+                        entry.position[0] + entry.size.width as f32 / 2.0,
+                        entry.position[1] + entry.size.height as f32 / 2.0,
+                    ],
+                    tex_coords: [0.015625, 0.015625],
+                },
+                Vertex {
+                    position: [
+                        entry.position[0] - entry.size.width as f32 / 2.0,
+                        entry.position[1] - entry.size.height as f32 / 2.0,
+                    ],
+                    tex_coords: [0.0, 0.0],
+                },
+                Vertex {
+                    position: [
+                        entry.position[0] + entry.size.width as f32 / 2.0,
+                        entry.position[1] - entry.size.height as f32 / 2.0,
+                    ],
+                    tex_coords: [0.015625, 0.0],
+                },
+            ];
+
+            data.extend_from_slice(&[v[0], v[1], v[2], v[1], v[3], v[2]]);
+        }
+
         let projection = camera.projection();
         self.shader.bind();
         self.shader.set_matrix("projection", projection.as_ptr());
-
-        let mut data = Vec::with_capacity(entries.len() * 12);
-
-        for entry in entries {
-            let vertices = [
-                [
-                    entry.position[0] - entry.size.width as f32 / 2.0,
-                    entry.position[1] + entry.size.height as f32 / 2.0,
-                ],
-                [
-                    entry.position[0] + entry.size.width as f32 / 2.0,
-                    entry.position[1] + entry.size.height as f32 / 2.0,
-                ],
-                [
-                    entry.position[0] - entry.size.width as f32 / 2.0,
-                    entry.position[1] - entry.size.height as f32 / 2.0,
-                ],
-                [
-                    entry.position[0] + entry.size.width as f32 / 2.0,
-                    entry.position[1] - entry.size.height as f32 / 2.0,
-                ],
-            ];
-
-            data.extend_from_slice(&[
-                vertices[0][0],
-                vertices[0][1],
-                vertices[1][0],
-                vertices[1][1],
-                vertices[2][0],
-                vertices[2][1],
-                vertices[1][0],
-                vertices[1][1],
-                vertices[3][0],
-                vertices[3][1],
-                vertices[2][0],
-                vertices[2][1],
-            ]);
-        }
+        self.shader.bind_texture_2d(0, &self.texture);
 
         self.vertex_buffer.write_typed(&data);
         let _buffer_bind = self.layout.bind(&[(0, &self.vertex_buffer)], None);
+
         let _state = PipelineState::new().with_blend();
 
         unsafe {
--- a/rust/lib-hedgewars-engine/src/render/gl.rs	Fri Nov 13 20:59:13 2020 +0300
+++ b/rust/lib-hedgewars-engine/src/render/gl.rs	Sat Nov 14 03:46:01 2020 +0300
@@ -173,10 +173,6 @@
         format: TextureFormat,
         data_type: TextureDataType,
     ) {
-        if is_out_of_bounds(data, data_stride, self.size) {
-            return;
-        }
-
         if let Some(handle) = self.handle {
             unsafe {
                 gl::BindTexture(gl::TEXTURE_2D, handle.get());
--- a/rust/lib-hedgewars-engine/src/world.rs	Fri Nov 13 20:59:13 2020 +0300
+++ b/rust/lib-hedgewars-engine/src/world.rs	Sat Nov 14 03:46:01 2020 +0300
@@ -140,7 +140,7 @@
                         gear_entries.push(GearEntry::new(
                             f64::from(pos.0.x()) as f32,
                             f64::from(pos.0.y()) as f32,
-                            Size::square(128),
+                            Size::square(256),
                         ))
                     });
             }