stevenarella/src/render/clouds.rs

227 lines
6.7 KiB
Rust
Raw Normal View History

2016-04-01 15:00:13 -04:00
use std::sync::{Arc, RwLock};
use super::glsl;
use crate::gl;
use byteorder::{NativeEndian, WriteBytesExt};
use cgmath::{Matrix4, Point3};
use log::error;
2016-04-01 15:00:13 -04:00
pub struct Clouds {
program: gl::Program,
// Shader props
_a_position: gl::Attribute,
u_perspective_matrix: gl::Uniform,
u_camera_matrix: gl::Uniform,
u_light_level: gl::Uniform,
u_sky_offset: gl::Uniform,
u_offset: gl::Uniform,
u_texture_info: gl::Uniform,
u_atlas: gl::Uniform,
u_textures: gl::Uniform,
u_cloud_map: gl::Uniform,
u_cloud_offset: gl::Uniform,
array: gl::VertexArray,
_buffer: gl::Buffer,
textures: Arc<RwLock<super::TextureManager>>,
texture: gl::Texture,
pub heightmap_data: Vec<u8>,
pub dirty: bool,
offset: f64,
num_points: usize,
}
impl Clouds {
pub fn new(greg: &glsl::Registry, textures: Arc<RwLock<super::TextureManager>>) -> Clouds {
let program = gl::Program::new();
let vertex = greg.get("clouds_vertex");
let geo = greg.get("clouds_geo");
let fragment = greg.get("clouds_frag");
let v = gl::Shader::new(gl::VERTEX_SHADER);
v.set_source(&vertex);
v.compile();
Use glow, GL on Whatever (#262) Replaces the use of gl_generator with the glow wrapper: * Add glow dependency, based on glow 0.6.1 * Pin version of glow fork for https://github.com/iceiix/glow/pull/1 until #442 renderbuffer * Remove gl module, steven_gl Porting details: * Initialize glow in src/gl/mod.rs * Call gl methods on glow context * glow uses camelcase * Import glow::HasContext trait, finds draw_elements etc. * Fix mismatched types, glow uses Option and &str instead of raw pointers * Fix uniform_location, glow already returns Some(u32) * uniform_location: convert i32 to u32 for Uniform * Fix attribute_location * Fix shader creation Result u32 type * Fix passing GLvoid and 2d/3d * Fix missing Options type mismatches * Offsets are i32 in glow, not GLvoid * Fix clear_buffer using _f32_slice * Delete methods are singular not plural * glBufferData -> buffer_data_u8_slice * buffer_sub_data_u8_slice * Update more glow method wrapper names found by reviewing glow native platform * Remove unused multi_draw_elements, can be replaced by draw_elements in a loop and it has no WebGL equivalent * glow implements glMapBufferRange * Remove unused read_buffer * glow's deletes automatically pass 1 and take no reference * shader_source() accepts &str directly; removes last of std::ptr * Pass uniform Option<u32> * Fix bool passing normalized parameter * Fix draw_buffers parameter * Stop unnecessarily returning context from gl::init * Getting shader info is unsafe * Unwrapping static mut is unsafe * Use unsafe raw pointers for global mutable context * Fix initializing GL objects wrappers from glow wrappers * Unbinding framebuffers uses None * Uppercase global to fix warning * Shaders return Some instead of None * Unbox the context to a raw pointer * Use tex_image_2d_multisample added in glow fork * Implement uniform_location, fixing unwrap None failed * Add tex_sub_image_3d, using PixelUnpackData::Slice * set_matrix4: transmute the Matrix4 since it is repr(C) * get_pixels -> get_tex_image -> glGetTexImage, with PixelPackData::Slice * Wrap sub_image_2d (glTexSubImage2D) and fix warnings * Implement set_float_multi_raw and set_matrix4_multi, using from_raw_parts
2020-12-25 13:00:22 -05:00
if !v.get_shader_compile_status() {
error!("Src: {}", vertex);
2016-04-01 15:00:13 -04:00
panic!("Shader error: {}", v.get_info_log());
} else {
let log = v.get_info_log();
let log = log.trim().trim_matches('\u{0}');
if !log.is_empty() {
error!("{}", log);
2016-04-01 15:00:13 -04:00
}
}
let g = gl::Shader::new(gl::GEOMETRY_SHADER);
g.set_source(&geo);
g.compile();
Use glow, GL on Whatever (#262) Replaces the use of gl_generator with the glow wrapper: * Add glow dependency, based on glow 0.6.1 * Pin version of glow fork for https://github.com/iceiix/glow/pull/1 until #442 renderbuffer * Remove gl module, steven_gl Porting details: * Initialize glow in src/gl/mod.rs * Call gl methods on glow context * glow uses camelcase * Import glow::HasContext trait, finds draw_elements etc. * Fix mismatched types, glow uses Option and &str instead of raw pointers * Fix uniform_location, glow already returns Some(u32) * uniform_location: convert i32 to u32 for Uniform * Fix attribute_location * Fix shader creation Result u32 type * Fix passing GLvoid and 2d/3d * Fix missing Options type mismatches * Offsets are i32 in glow, not GLvoid * Fix clear_buffer using _f32_slice * Delete methods are singular not plural * glBufferData -> buffer_data_u8_slice * buffer_sub_data_u8_slice * Update more glow method wrapper names found by reviewing glow native platform * Remove unused multi_draw_elements, can be replaced by draw_elements in a loop and it has no WebGL equivalent * glow implements glMapBufferRange * Remove unused read_buffer * glow's deletes automatically pass 1 and take no reference * shader_source() accepts &str directly; removes last of std::ptr * Pass uniform Option<u32> * Fix bool passing normalized parameter * Fix draw_buffers parameter * Stop unnecessarily returning context from gl::init * Getting shader info is unsafe * Unwrapping static mut is unsafe * Use unsafe raw pointers for global mutable context * Fix initializing GL objects wrappers from glow wrappers * Unbinding framebuffers uses None * Uppercase global to fix warning * Shaders return Some instead of None * Unbox the context to a raw pointer * Use tex_image_2d_multisample added in glow fork * Implement uniform_location, fixing unwrap None failed * Add tex_sub_image_3d, using PixelUnpackData::Slice * set_matrix4: transmute the Matrix4 since it is repr(C) * get_pixels -> get_tex_image -> glGetTexImage, with PixelPackData::Slice * Wrap sub_image_2d (glTexSubImage2D) and fix warnings * Implement set_float_multi_raw and set_matrix4_multi, using from_raw_parts
2020-12-25 13:00:22 -05:00
if !g.get_shader_compile_status() {
error!("Src: {}", geo);
2016-04-01 15:00:13 -04:00
panic!("Shader error: {}", g.get_info_log());
} else {
let log = g.get_info_log();
let log = log.trim().trim_matches('\u{0}');
if !log.is_empty() {
error!("{}", log);
2016-04-01 15:00:13 -04:00
}
}
let f = gl::Shader::new(gl::FRAGMENT_SHADER);
f.set_source(&fragment);
f.compile();
Use glow, GL on Whatever (#262) Replaces the use of gl_generator with the glow wrapper: * Add glow dependency, based on glow 0.6.1 * Pin version of glow fork for https://github.com/iceiix/glow/pull/1 until #442 renderbuffer * Remove gl module, steven_gl Porting details: * Initialize glow in src/gl/mod.rs * Call gl methods on glow context * glow uses camelcase * Import glow::HasContext trait, finds draw_elements etc. * Fix mismatched types, glow uses Option and &str instead of raw pointers * Fix uniform_location, glow already returns Some(u32) * uniform_location: convert i32 to u32 for Uniform * Fix attribute_location * Fix shader creation Result u32 type * Fix passing GLvoid and 2d/3d * Fix missing Options type mismatches * Offsets are i32 in glow, not GLvoid * Fix clear_buffer using _f32_slice * Delete methods are singular not plural * glBufferData -> buffer_data_u8_slice * buffer_sub_data_u8_slice * Update more glow method wrapper names found by reviewing glow native platform * Remove unused multi_draw_elements, can be replaced by draw_elements in a loop and it has no WebGL equivalent * glow implements glMapBufferRange * Remove unused read_buffer * glow's deletes automatically pass 1 and take no reference * shader_source() accepts &str directly; removes last of std::ptr * Pass uniform Option<u32> * Fix bool passing normalized parameter * Fix draw_buffers parameter * Stop unnecessarily returning context from gl::init * Getting shader info is unsafe * Unwrapping static mut is unsafe * Use unsafe raw pointers for global mutable context * Fix initializing GL objects wrappers from glow wrappers * Unbinding framebuffers uses None * Uppercase global to fix warning * Shaders return Some instead of None * Unbox the context to a raw pointer * Use tex_image_2d_multisample added in glow fork * Implement uniform_location, fixing unwrap None failed * Add tex_sub_image_3d, using PixelUnpackData::Slice * set_matrix4: transmute the Matrix4 since it is repr(C) * get_pixels -> get_tex_image -> glGetTexImage, with PixelPackData::Slice * Wrap sub_image_2d (glTexSubImage2D) and fix warnings * Implement set_float_multi_raw and set_matrix4_multi, using from_raw_parts
2020-12-25 13:00:22 -05:00
if !f.get_shader_compile_status() {
error!("Src: {}", fragment);
2016-04-01 15:00:13 -04:00
panic!("Shader error: {}", f.get_info_log());
} else {
let log = f.get_info_log();
let log = log.trim().trim_matches('\u{0}');
if !log.is_empty() {
error!("{}", log);
2016-04-01 15:00:13 -04:00
}
}
program.attach_shader(v);
program.attach_shader(g);
program.attach_shader(f);
program.link();
program.use_program();
let a_position = program.attribute_location("aPosition").unwrap();
let u_perspective_matrix = program.uniform_location("perspectiveMatrix").unwrap();
let u_camera_matrix = program.uniform_location("cameraMatrix").unwrap();
let u_light_level = program.uniform_location("lightLevel").unwrap();
let u_sky_offset = program.uniform_location("skyOffset").unwrap();
let u_offset = program.uniform_location("offset").unwrap();
let u_texture_info = program.uniform_location("textureInfo").unwrap();
let u_atlas = program.uniform_location("atlas").unwrap();
let u_textures = program.uniform_location("textures").unwrap();
let u_cloud_map = program.uniform_location("cloudMap").unwrap();
let u_cloud_offset = program.uniform_location("cloudOffset").unwrap();
2016-04-01 15:00:13 -04:00
let array = gl::VertexArray::new();
array.bind();
let buffer = gl::Buffer::new();
buffer.bind(gl::ARRAY_BUFFER);
a_position.enable();
a_position.vertex_pointer(3, gl::FLOAT, false, 12, 0);
let mut data = vec![];
let mut num_points = 0;
for x in -160..160 {
for z in -160..160 {
2016-04-01 15:00:13 -04:00
let _ = data.write_f32::<NativeEndian>(x as f32);
let _ = data.write_f32::<NativeEndian>(128.0);
let _ = data.write_f32::<NativeEndian>(z as f32);
num_points += 1;
}
}
buffer.set_data(gl::ARRAY_BUFFER, &data, gl::STATIC_DRAW);
let heightmap_data = vec![0; 512 * 512];
2016-04-01 15:00:13 -04:00
let texture = gl::Texture::new();
texture.bind(gl::TEXTURE_2D);
texture.image_2d(
gl::TEXTURE_2D,
0,
512,
512,
gl::RED,
gl::UNSIGNED_BYTE,
Some(&heightmap_data),
);
2016-04-01 15:00:13 -04:00
texture.set_parameter(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST);
texture.set_parameter(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST);
Clouds {
program,
2016-04-01 15:00:13 -04:00
// Shader props
_a_position: a_position,
u_perspective_matrix,
u_camera_matrix,
u_light_level,
u_sky_offset,
u_offset,
u_texture_info,
u_atlas,
u_textures,
u_cloud_map,
u_cloud_offset,
array,
2016-04-01 15:00:13 -04:00
_buffer: buffer,
textures,
2016-04-01 15:00:13 -04:00
texture,
heightmap_data,
2016-04-01 15:00:13 -04:00
dirty: false,
offset: 0.0,
num_points,
2016-04-01 15:00:13 -04:00
}
}
pub fn draw(
&mut self,
camera_pos: &Point3<f64>,
perspective_matrix: &Matrix4<f32>,
camera_matrix: &Matrix4<f32>,
light_level: f32,
sky_offset: f32,
delta: f64,
) {
2016-04-01 15:00:13 -04:00
self.offset += delta;
let tex = super::Renderer::get_texture(&self.textures, "steven:environment/clouds");
self.program.use_program();
self.u_perspective_matrix.set_matrix4(perspective_matrix);
self.u_camera_matrix.set_matrix4(camera_matrix);
self.u_sky_offset.set_float(sky_offset);
self.u_light_level.set_float(light_level);
self.u_offset.set_float3(
camera_pos.x.floor() as f32,
0.0,
camera_pos.z.floor() as f32,
);
2016-04-01 15:00:13 -04:00
self.u_texture_info.set_float4(
tex.get_x() as f32,
tex.get_y() as f32,
tex.get_width() as f32,
tex.get_height() as f32,
2016-04-01 15:00:13 -04:00
);
self.u_atlas.set_float(tex.atlas as f32);
self.u_cloud_offset.set_float((self.offset / 60.0) as f32);
self.u_textures.set_int(0);
gl::active_texture(1);
self.texture.bind(gl::TEXTURE_2D);
if self.dirty {
self.texture.sub_image_2d(
gl::TEXTURE_2D,
0,
0,
0,
512,
512,
gl::RED,
gl::UNSIGNED_BYTE,
&self.heightmap_data,
);
2016-04-01 15:00:13 -04:00
self.dirty = false;
}
self.u_cloud_map.set_int(1);
self.array.bind();
gl::draw_arrays(gl::POINTS, 0, self.num_points);
}
}