extern crate gl;
extern crate glutin;
extern crate rand;
extern crate e2rcore;
use std::fs::File;
use std::io::BufReader;
use std::str::FromStr;
use std::io::Read;
use std::str;
use rand::Rng;
use self::glutin::GlContext;
use self::e2rcore::interface::i_window::IWindow;
use self::e2rcore::implement::window::winglutin::WinGlutin;
use self::e2rcore::implement::capability::capability_gl;
use self::e2rcore::implement::render::util_gl;
pub fn file_open( file_path: & str ) -> Option<String> {
let path = File::open( file_path ).expect("file path open invalid");
let mut buf_reader = BufReader::new(path);
let mut contents = String::new();
match buf_reader.read_to_string( & mut contents ) {
Err( e ) => { println!("{}", e ); return None },
_ => (),
}
Some(contents)
}
#[allow(unused)]
fn main() {
let geom_vs_src = file_open( "core/example/shading/deferred_geometry_pass.vs" ).expect("geometry vertex shader not retrieved");
let geom_fs_src = file_open( "core/example/shading/deferred_geometry_pass.fs" ).expect("geometry fragment shader not retrieved");
let light_vs_src = file_open( "core/example/shading/deferred_light_pass.vs" ).expect("light vertex shader not retrieved");
let light_fs_src = file_open( "core/example/shading/deferred_light_pass.fs" ).expect("light fragment shader not retrieved");
let mut window : WinGlutin = IWindow::init( 500, 500 );
window.make_current().expect("window make_current failed");
let cap = capability_gl::query_gl();
println!( "{}", cap );
unsafe {
gl::Enable( gl::DEPTH_TEST );
}
let geom_vs = match util_gl::load_and_compile_shader( geom_vs_src.as_str(), util_gl::ShaderType::VERTEX ) { Ok( o ) => o, Err( o ) => { panic!( "{}", o ); } };
let geom_fs = match util_gl::load_and_compile_shader( geom_fs_src.as_str(), util_gl::ShaderType::FRAGMENT ) { Ok( o ) => o, Err( o ) => { panic!( "{}", o ); } };
let light_vs = match util_gl::load_and_compile_shader( light_vs_src.as_str(), util_gl::ShaderType::VERTEX ) { Ok( o ) => o, Err( o ) => { panic!( "{}", o ); } };
let light_fs = match util_gl::load_and_compile_shader( light_fs_src.as_str(), util_gl::ShaderType::FRAGMENT ) { Ok( o ) => o, Err( o ) => { panic!( "{}", o ); } };
let cam_pos = [ 0f32, 0f32, 5f32 ];
let mut quad_vao : u32 = 0;
let mut quad_vbo : u32 = 0;
let mut gl_program_geom = 0;
let mut gl_program_light = 0;
let mut g_buffer = 0;
let mut g_position = 0;
let mut g_normal = 0;
let mut g_albedo_spec = 0;
unsafe {
gl_program_geom = util_gl::create_program_from_shaders( &[ geom_vs, geom_fs ] );
gl_program_light = util_gl::create_program_from_shaders( &[ light_vs, light_fs ] );
gl::UseProgram( gl_program_geom );
util_gl::check_last_op();
gl::BindFramebuffer( gl::FRAMEBUFFER, 0 );
gl::GenFramebuffers(1, & mut g_buffer);
gl::BindFramebuffer(gl::FRAMEBUFFER, g_buffer);
gl::GenTextures( 1, & mut g_position );
gl::BindTexture( gl::TEXTURE_2D, g_position );
gl::TexImage2D( gl::TEXTURE_2D, 0, gl::RGB16F as i32, 500, 500, 0, gl::RGB, gl::FLOAT, std::ptr::null() );
gl::TexParameteri( gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as i32 );
gl::TexParameteri( gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as i32 );
gl::FramebufferTexture2D( gl::FRAMEBUFFER, gl::COLOR_ATTACHMENT0, gl::TEXTURE_2D, g_position, 0 );
gl::GenTextures( 1, & mut g_normal );
gl::BindTexture( gl::TEXTURE_2D, g_normal );
gl::TexImage2D( gl::TEXTURE_2D, 0, gl::RGB16F as i32, 500, 500, 0, gl::RGB, gl::FLOAT, std::ptr::null() );
gl::TexParameteri( gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as i32 );
gl::TexParameteri( gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as i32 );
gl::FramebufferTexture2D( gl::FRAMEBUFFER, gl::COLOR_ATTACHMENT1, gl::TEXTURE_2D, g_normal, 0);
gl::GenTextures( 1, & mut g_albedo_spec );
gl::BindTexture( gl::TEXTURE_2D, g_albedo_spec );
gl::TexImage2D( gl::TEXTURE_2D, 0, gl::RGBA as i32, 500, 500, 0, gl::RGBA, gl::UNSIGNED_BYTE, std::ptr::null() );
gl::TexParameteri( gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as i32 );
gl::TexParameteri( gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as i32 );
gl::FramebufferTexture2D( gl::FRAMEBUFFER, gl::COLOR_ATTACHMENT2, gl::TEXTURE_2D, g_albedo_spec, 0 );
let attachments : [u32;3] = [ gl::COLOR_ATTACHMENT0, gl::COLOR_ATTACHMENT1, gl::COLOR_ATTACHMENT2 ];
gl::DrawBuffers( 3, &attachments[0] );
let mut rbo_depth_stencil = 0;
gl::GenRenderbuffers( 1, & mut rbo_depth_stencil );
gl::BindRenderbuffer( gl::RENDERBUFFER, rbo_depth_stencil );
gl::RenderbufferStorage( gl::RENDERBUFFER, gl::DEPTH_COMPONENT32F, 500, 500 );
gl::FramebufferRenderbuffer( gl::FRAMEBUFFER, gl::DEPTH_ATTACHMENT, gl::RENDERBUFFER, rbo_depth_stencil );
if gl::FRAMEBUFFER_COMPLETE != gl::CheckFramebufferStatus( gl::FRAMEBUFFER ) {
panic!("frambuffer incomplete");
}
}
let mut light_position_colour : Vec<[f32;6]> = vec![];
let mut rng = rand::thread_rng();
for i in 0..50 {
let pos_x = ( (rng.gen::<u8>() % 100) as f32 / 100f32 ) * 6f32 - 3f32;
let pos_y = ( (rng.gen::<u8>() % 100) as f32 / 100f32 ) * 6f32 - 4f32;
let pos_z = ( (rng.gen::<u8>() % 100) as f32 / 100f32 ) * 6f32 - 3f32;
let colour_r = ( (rng.gen::<u8>() % 100) as f32 / 100f32 ) * 6f32 - 3f32;
let colour_g = ( (rng.gen::<u8>() % 100) as f32 / 100f32 ) * 6f32 - 4f32;
let colour_b = ( (rng.gen::<u8>() % 100) as f32 / 100f32 ) * 6f32 - 3f32;
light_position_colour.push( [ pos_x, pos_y, pos_z, colour_r, colour_g, colour_b ] );
}
unsafe {
gl::UseProgram( gl_program_light );
gl::Uniform1i( gl::GetUniformLocation( gl_program_light, "g_position".as_ptr() as * const i8 ), 0 );
gl::Uniform1i( gl::GetUniformLocation( gl_program_light, "g_normal".as_ptr() as * const i8 ), 1 );
gl::Uniform1i( gl::GetUniformLocation( gl_program_light, "g_albedo_spec".as_ptr() as * const i8 ), 2 );
}
unsafe {
let mut obj_vao = 0;
let mut obj_vbo = 0;
gl::GenVertexArrays( 1, & mut obj_vao );
gl::GenBuffers( 1, & mut obj_vbo );
gl::BindVertexArray( obj_vao );
gl::BindBuffer( gl::ARRAY_BUFFER, obj_vbo );
let data_ptr = [ -1f32, -1f32, -1f32, 1f32, -1f32, -1f32, -1f32, 1f32, -1f32,
1f32, 1f32, -1f32, -1f32, 1f32, -1f32, 1f32, -1f32, -1f32 ];
let data_length = data_ptr.len() * std::mem::size_of::<f32>();
gl::BufferData( gl::ARRAY_BUFFER, data_length as isize, data_ptr.as_ptr() as _, gl::STATIC_DRAW );
gl::EnableVertexAttribArray( 0 );
gl::BindVertexArray( 0 );
}
let mut obj_pos : Vec<[f32;3]> = vec![];
obj_pos.push( [-3f32, -3f32, -3f32] );
obj_pos.push( [ 0f32, -3f32, -3f32] );
obj_pos.push( [ 3f32, -3f32, -3f32] );
obj_pos.push( [-3f32, -3f32, 0f32] );
obj_pos.push( [ 0f32, -3f32, 0f32] );
obj_pos.push( [ 3f32, -3f32, 0f32] );
obj_pos.push( [-3f32, -3f32, 3f32] );
obj_pos.push( [ 0f32, -3f32, 3f32] );
obj_pos.push( [ 3f32, -3f32, 3f32] );
let mut running = true;
while running {
let mut new_win_dim = None;
window.handle_events( |event| {
match event {
glutin::Event::WindowEvent{ event, .. } => match event {
glutin::WindowEvent::Closed => running = false,
glutin::WindowEvent::Resized(w, h) => new_win_dim = Some( (w,h) ),
glutin::WindowEvent::KeyboardInput {
input: glutin::KeyboardInput {
state: glutin::ElementState::Pressed,
virtual_keycode: Some( glutin::VirtualKeyCode::Q ),
..
}, ..
} => running = false,
_ => (),
},
_ => ()
}
} );
if let Some( ( w, h ) ) = new_win_dim {
window._win._wingl.resize(w, h);
}
unsafe {
gl::ClearColor( 0.3, 0.3, 0.3, 1.0 );
gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
gl::BindFramebuffer( gl::FRAMEBUFFER, g_buffer );
{
gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
gl::UseProgram( gl_program_geom );
for ( i, v ) in obj_pos.iter().enumerate() {
}
}
gl::BindFramebuffer( gl::FRAMEBUFFER, 0 );
{
gl::Clear( gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT );
gl::UseProgram( gl_program_light );
gl::ActiveTexture( gl::TEXTURE0 );
gl::BindTexture( gl::TEXTURE_2D, g_position );
gl::ActiveTexture( gl::TEXTURE1 );
gl::BindTexture( gl::TEXTURE_2D, g_normal );
gl::ActiveTexture( gl::TEXTURE2 );
gl::BindTexture( gl::TEXTURE_2D, g_albedo_spec );
for ( i, v ) in light_position_colour.iter().enumerate() {
let mut uniform_light_pos = "lights[".to_owned();
uniform_light_pos.push_str( i.to_string().as_str() );
uniform_light_pos.push_str( String::from_str("].Position").unwrap().as_str() );
gl::Uniform3fv( gl::GetUniformLocation( gl_program_light, uniform_light_pos.as_ptr() as * const i8 ), 1, &v[0] );
let mut uniform_name_colour = "lights[".to_owned();
uniform_name_colour.push_str( i.to_string().as_str() );
uniform_name_colour.push_str( String::from_str("].Colour").unwrap().as_str() );
gl::Uniform3fv( gl::GetUniformLocation( gl_program_light, uniform_name_colour.as_ptr() as * const i8 ), 1, &v[0] );
let light_atten_const = 1.0;
let light_atten_linear = 0.7;
let light_atten_quadratic = 1.8;
let mut uniform_name_linear = "lights[".to_owned();
uniform_name_linear.push_str( i.to_string().as_str() );
uniform_name_linear.push_str( String::from_str("].Linear").unwrap().as_str() );
gl::Uniform3fv( gl::GetUniformLocation( gl_program_light, uniform_name_linear.as_ptr() as * const i8 ), 1, &v[0] );
let mut uniform_name_quadratic = "lights[".to_owned();
uniform_name_quadratic.push_str( i.to_string().as_str() );
uniform_name_quadratic.push_str( String::from_str("].Quadratic").unwrap().as_str() );
gl::Uniform3fv( gl::GetUniformLocation( gl_program_light, uniform_name_quadratic.as_ptr() as * const i8 ), 1, &v[0] );
}
gl::Uniform3fv( gl::GetUniformLocation( gl_program_light, "viewPos".as_ptr() as * const i8 ), 1, &cam_pos[0] );
}
{
if quad_vao == 0 {
let quad_vertices = [ -1f32, 1f32, 0f32, 0f32, 1f32,
-1f32, -1f32, 0f32, 0f32, 0f32,
1f32, 1f32, 0f32, 1f32, 1f32,
1f32, -1f32, 0f32, 1f32, 0f32, ];
gl::GenVertexArrays( 1, & mut quad_vao );
gl::GenBuffers( 1, & mut quad_vbo );
gl::BindVertexArray( quad_vao );
gl::BindBuffer( gl::ARRAY_BUFFER, quad_vbo );
gl::BufferData( gl::ARRAY_BUFFER, ( quad_vertices.len() * std::mem::size_of::<f32>() ) as isize, quad_vertices[..].as_ptr().offset(0) as _, gl::STATIC_DRAW );
gl::EnableVertexAttribArray( 0 );
gl::VertexAttribPointer( 0, 3, gl::FLOAT, gl::FALSE, ( 5 * std::mem::size_of::<f32>() ) as i32, std::ptr::null() );
gl::EnableVertexAttribArray( 1 );
gl::VertexAttribPointer( 1, 2, gl::FLOAT, gl::FALSE, ( 5 * std::mem::size_of::<f32>() ) as i32, ( 3 * std::mem::size_of::<f32>() ) as * const std::os::raw::c_void );
}
gl::BindVertexArray( quad_vao );
gl::DrawArrays( gl::TRIANGLE_STRIP, 0, 4 );
gl::BindVertexArray( 0 );
}
let buf_width = 500;
let buf_height = 500;
gl::BindFramebuffer( gl::READ_FRAMEBUFFER, g_buffer );
gl::BindFramebuffer( gl::DRAW_FRAMEBUFFER, 0 );
gl::BlitFramebuffer( 0, 0, buf_width, buf_height, 0, 0, buf_width, buf_height, gl::DEPTH_BUFFER_BIT, gl::NEAREST );
gl::BindFramebuffer( gl::FRAMEBUFFER, 0 );
}
window.swap_buf();
}
}