diff --git a/src/assets/renderable_object.rs b/src/assets/renderable_object.rs index f683a5abde..bde92866d1 100644 --- a/src/assets/renderable_object.rs +++ b/src/assets/renderable_object.rs @@ -13,6 +13,7 @@ use std::ptr::null; use image::{DynamicImage, Pixel, Rgba, RgbaImage, ImageBuffer, RgbImage}; use crate::opengl::wrapper::uniform::Uniform; use image::imageops::{flip_horizontal, flip_vertical}; +use crate::opengl::wrapper::attribute::Attribute; /// A collection of all the graphics-related data to render: vertices, normals, etc. pub struct RenderableObject { @@ -99,6 +100,21 @@ impl RenderableObject { } } + pub fn set_vertex_type(&mut self, vertex_type: &Uniform) { + /*self.vao.bind(); + let loc = vertex_type.id(); + println!("Uniform location: {}", loc); + + unsafe { + //gl::EnableVertexAttribArray(loc as u32); + //gl::VertexAttribIPointer(loc as u32, 1, gl::UNSIGNED_BYTE, 0, null()); + //gl::VertexAttribI1ui(loc as u32, 0); + //gl::Uniform1i(loc, 1); + }*/ + + //vertex_type.set_uint(0); + } + pub fn load_texture_coordinates(&mut self, vertex_data: &Vec, shader_id: GLuint) { self.vao.bind(); self.texture_coords_buffer.bind_as_array_buffer(); diff --git a/src/opengl/wrapper/attribute.rs b/src/opengl/wrapper/attribute.rs index 63a09365e5..bfe9177238 100644 --- a/src/opengl/wrapper/attribute.rs +++ b/src/opengl/wrapper/attribute.rs @@ -5,6 +5,13 @@ use std::os::raw::c_char; use std::ffi::CString; /// A typesafe handle on attribute IDs with convenience methods. +/// +/// Unlike "Uniforms", which are global in GLSL, "Attributes" are applied on a per-vertex basis. +/// They can be used to convey typical information (eg. normals) or completely custom information +/// (eg. tangents or whatever). +/// +/// https://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/attributes.php +/// #[derive(Clone, Debug, Copy)] pub struct Attribute { id: GLint, @@ -32,4 +39,11 @@ impl Attribute { pub fn id(&self) -> GLint { self.id } + + /*pub fn set_uint(&self, value: GLuint) { + let loc = self.id() as GLuint; + unsafe { + gl::VertexAttribI1ui(loc, value); + } + }*/ } diff --git a/src/point_cloud/point_cloud_renderer.rs b/src/point_cloud/point_cloud_renderer.rs index beb188a9af..e5d1df6505 100644 --- a/src/point_cloud/point_cloud_renderer.rs +++ b/src/point_cloud/point_cloud_renderer.rs @@ -113,6 +113,12 @@ pub struct PointCloudRenderer { /// Uniform location in the shader program. model_transform_id: Uniform, + /// An integer uniform that tells GLSL what type of data it's dealing with. + /// This should allow us to mix Point Cloud data and Geometric Objects + /// 1 = object + /// 2 = pointCloud + uniform_vertex_type: Uniform, + /// Uniform for object textures in the shader program. object_texture_uniform: Uniform, /// Location of the texture coordinate input @@ -188,6 +194,8 @@ impl PointCloudRenderer { let texture_coordinate_attribute = Attribute::lookup("vTextureCoord", program_id)?; + let uniform_vertex_type = Uniform::lookup("vertexType", program_id)?; + let color_vertex_attribute_location = unsafe { let location = gl::GetAttribLocation(program_id, COLOR_LOCATION_PTR); @@ -218,6 +226,7 @@ impl PointCloudRenderer { fragment_shader_id, object_texture_uniform, texture_coordinates_attribute: texture_coordinate_attribute, + uniform_vertex_type, point_size: 1, enable_shading: false, view_transform_id: view_transform, @@ -257,7 +266,7 @@ impl PointCloudRenderer { let filename = "/home/bt/dev/storyteller/assets/n64_smash_bros/pika.obj"; // MISSHAPEN! let filename = "/home/bt/dev/storyteller/assets/n64_pokemon_snap_bulbasaur/Bulbasaur/bulbasaur.obj"; - { + if false { let filename = "/home/bt/dev/storyteller/assets/bundled/objects/n64_mario64_yoshi/yoshi.obj"; let path = Path::new(filename); @@ -278,7 +287,7 @@ impl PointCloudRenderer { self.renderable_objects.push(positionable_object); } - { + if false { let filename = "/home/bt/dev/storyteller/assets/bundled/objects/gamecube_ssbm_pichu/pichu.obj"; let path = Path::new(filename); @@ -298,7 +307,7 @@ impl PointCloudRenderer { self.renderable_objects.push(positionable_object); } - { + if false { let filename = "/home/bt/dev/storyteller/assets/bundled/objects/n64_zelda_oot_king_dodongo/King_Dodongo.obj"; let path = Path::new(filename); @@ -318,7 +327,7 @@ impl PointCloudRenderer { self.renderable_objects.push(positionable_object); } - { + if false { let filename = "/home/bt/dev/storyteller/assets/bundled/objects/n64_zelda_oot_poe/poe.obj"; let path = Path::new(filename); @@ -349,6 +358,8 @@ impl PointCloudRenderer { let filename = "/home/bt/dev/storyteller/assets/bundled/levels/n64_zelda_oot_kokiri_bridge/bridge_grp.png"; renderable_object.load_texture(filename, &self.object_texture_uniform)?; + renderable_object.set_vertex_type(&self.uniform_vertex_type); + let mut positionable_object = PositionableObject::new(renderable_object); positionable_object.object_type = ObjectType::Level; @@ -521,22 +532,27 @@ impl PointCloudRenderer { gl::Uniform1i(self.enable_shading_index, enable_shading); - /*for i in 0 .. self.num_cameras { + // Tell GLSL we're doing point clouds + gl::Uniform1i(self.uniform_vertex_type.id() as GLint, 1); + + for i in 0 .. self.num_cameras { let vao = self.vertex_array_objects.get(i).unwrap(); let vertex_array_size_bytes = self.vertex_arrays_size_bytes.get(i).unwrap(); let size = vertex_array_size_bytes / size_of::() as i32; vao.bind(); gl::DrawArrays(gl::POINTS, 0, size); - }*/ + } gl::BindVertexArray(0); + // Now tell GLSL we're doing objects + gl::Uniform1i(self.uniform_vertex_type.id() as GLint, 0); + for positionable in self.renderable_objects.iter() { positionable.draw(self.model_transform_id); } - gl_get_error() .map_err(|err| PointCloudRendererError::OpenGlError(err)) } diff --git a/src/point_cloud/shaders/point_cloud_fragment_shader.glsl b/src/point_cloud/shaders/point_cloud_fragment_shader.glsl index fce1bdee63..b671b873dc 100644 --- a/src/point_cloud/shaders/point_cloud_fragment_shader.glsl +++ b/src/point_cloud/shaders/point_cloud_fragment_shader.glsl @@ -18,13 +18,20 @@ void main() discard; } - //fragmentColor = vec4(texCoord.r, texCoord.g, 127, 255); - //fragmentColor = texture2D(objTexture, texCoord); // * 0.80 + color * 0.20; - //fragmentColor = 0.5 * texture2D(objTexture, texCoord) + 0.01 * vec4(texCoord.r, texCoord.g, 0, 255); - //vec2 coord = vec2(texCoord.g, texCoord.g); - vec2 coord = texCoord; - fragmentColor = texture2D(objTexture, coord); - //fragmentColor = vertexColor; + if (vertexColor.a == 0.0f) { + fragmentColor = vertexColor; + } else { + + //fragmentColor = vec4(texCoord.r, texCoord.g, 127, 255); + //fragmentColor = texture2D(objTexture, texCoord); // * 0.80 + color * 0.20; + //fragmentColor = 0.5 * texture2D(objTexture, texCoord) + 0.01 * vec4(texCoord.r, texCoord.g, 0, 255); + //vec2 coord = vec2(texCoord.g, texCoord.g); + + // Wavefront Objects + vec2 coord = texCoord; + fragmentColor = texture2D(objTexture, coord); + + } if (fragmentColor.a == 0.0f) { discard; diff --git a/src/point_cloud/shaders/point_cloud_vertex_shader.glsl b/src/point_cloud/shaders/point_cloud_vertex_shader.glsl index a61ae82375..1a38f61b7c 100644 --- a/src/point_cloud/shaders/point_cloud_vertex_shader.glsl +++ b/src/point_cloud/shaders/point_cloud_vertex_shader.glsl @@ -21,6 +21,9 @@ uniform mat4 model; uniform mat4 view; uniform mat4 projection; +// 1 = object, 2 = pointCloud +uniform int vertexType; + layout(rgba32f, binding=0) readonly uniform image2D pointCloudTexture0; layout(rgba32f, binding=1) readonly uniform image2D pointCloudTexture1; @@ -55,7 +58,7 @@ void main() // cameras. This effectively 'downsamples' each camera. We need to find a way to double this. // I hate drawing like this //if (gl_VertexID < pointCloudLength0) { // TODO - this is the one to enable - if (gl_VertexID %2 == 0) { + if (gl_VertexID < 10) { // Camera #0 ivec2 currentDepthPixelCoordinates = ivec2(gl_VertexID % pointCloudSize0.x, gl_VertexID / pointCloudSize0.x); @@ -90,9 +93,19 @@ void main() 127, 255 ); + + vertexPosition = position; + } + + if (vertexType != 0) { + colorOut = vec4( + 127, + 127, + 127, + 0 + ); } - vertexPosition = position; // Scale up while model view matrices not implemented. //vertexPosition.x *= 2.0 + 10.0; @@ -105,9 +118,8 @@ void main() } gl_Position = projection * view * model * vec4(vertexPosition, 1); + vertexColor = colorOut; - - texCoord = vTextureCoord; // Pass along the 'invalid pixel' flag as the alpha channel