use sdl2::event::Event; use sdl2::keyboard::Keycode; use std::convert::TryInto; use std::time::Duration; const VERT_SHADER_SRC: &str = " #define lowp #define mediump #define highp #line 0 uniform highp mat4 uni_model; uniform highp mat4 uni_viewproj; attribute highp vec4 attr_pos; attribute mediump vec2 attr_uv; attribute lowp vec3 attr_normal; varying lowp vec4 vary_color; varying mediump vec2 vary_uv; void main (void) { vary_uv = attr_uv; lowp vec4 light_color = vec4 (1.0); vary_color = light_color; vec4 world_pos = uni_model * attr_pos; gl_Position = uni_viewproj * world_pos; }"; const FRAG_SHADER_SRC: &str = " #define lowp #define mediump #define highp #line 0 uniform lowp sampler2D uni_texture; varying lowp vec4 vary_color; varying mediump vec2 vary_uv; void main (void) { gl_FragColor = texture2D (uni_texture, vary_uv) * vary_color; //gl_FragColor = vec4 (1.0, 0.0, 1.0, 1.0); } "; pub struct ShaderObject { id: u32, } impl ShaderObject { pub fn id (&self) -> u32 { self.id } pub fn new (shader_type: u32, source: &str) -> Result { let id = unsafe { gl::CreateShader (shader_type) }; let sources = [ source.as_ptr () as *const i8, ]; let lengths = [ source.len ().try_into ().unwrap (), ]; let success = unsafe { gl::ShaderSource (id, sources.len ().try_into ().unwrap (), sources.as_ptr (), lengths.as_ptr ()); gl::CompileShader (id); let mut success = 0; gl::GetShaderiv (id, gl::COMPILE_STATUS, &mut success); success == 1 }; if success { Ok (ShaderObject { id, }) } else { let mut info_log = vec! [0u8; 4096]; let mut log_length = 0; unsafe { gl::GetShaderInfoLog (id, (info_log.len () - 1).try_into ().unwrap (), &mut log_length, info_log.as_mut_ptr () as *mut i8); } info_log.truncate (log_length.try_into ().unwrap ()); let info = String::from_utf8 (info_log).unwrap (); Err (info) } } } impl Drop for ShaderObject { fn drop (&mut self) { unsafe { gl::DeleteShader (self.id); } } } fn main () { let sdl_context = sdl2::init ().unwrap (); let video_subsystem = sdl_context.video ().unwrap (); let window = video_subsystem.window ("OpenGL? In my Rust?", 1280, 720) .position_centered () .opengl () .build () .unwrap (); gl::load_with (|s| { let result = video_subsystem.gl_get_proc_address (s) as *const _; //println! ("{:?}", result); result }); assert! (gl::ClearColor::is_loaded ()); let gl_ctx = window.gl_create_context ().unwrap (); window.gl_make_current (&gl_ctx).unwrap (); let vert_shader = ShaderObject::new (gl::VERTEX_SHADER, VERT_SHADER_SRC).unwrap (); let frag_shader = ShaderObject::new (gl::FRAGMENT_SHADER, FRAG_SHADER_SRC).unwrap (); let mut event_pump = sdl_context.event_pump ().unwrap (); 'running: loop { let _mouse = event_pump.mouse_state (); for event in event_pump.poll_iter() { match event { Event::Quit {..} | Event::KeyDown { keycode: Some (Keycode::Escape), .. } => { break 'running }, _ => (), } } window.gl_make_current (&gl_ctx).unwrap (); unsafe { gl::ClearColor (1.0f32, 0.0f32, 1.0f32, 1.0f32); gl::Clear (gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT); } window.gl_swap_window (); ::std::thread::sleep (Duration::from_millis (15)); } }