4 use sdl2::video::GLProfile;
14 static WIN_W : u32 = 800;
15 static WIN_H : u32 = 600;
17 static VERTEX_DATA : [GLfloat; 12] = [
27 static NUM_VERTICES : GLint = 6;
28 static VERTEX_LOC : u32 = 0;
32 static VS : &'static str =
34 attribute vec4 pos;\n\
39 static FS : &'static str =
43 color = vec4(0.0, 0.5, 0.8, 1.0);\n\
46 fn compile_sdr(src: &str, stage:GLenum) -> GLuint {
49 shader = gl::CreateShader(stage);
51 let s = std::ffi::CString::new(src).expect("CString::new failed");;
53 gl::ShaderSource(shader, 1, &s.as_ptr(), std::ptr::null());
54 gl::CompileShader(shader);
56 let mut status = gl::FALSE as GLint;
57 gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut status);
60 if status != (gl::TRUE as GLint) {
62 gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &mut len);
64 let mut buf: Vec<u8> = Vec::with_capacity((len + 1) as usize);
65 buf.extend([b' '].iter().cycle().take(len as usize));
66 let err: std::ffi::CString = std::ffi::CString::from_vec_unchecked(buf);
68 gl::GetShaderInfoLog(shader, len, std::ptr::null_mut(),
69 err.as_ptr() as *mut GLchar);
70 println!("{}", err.to_str().unwrap());
77 fn link_sdr_prog(vs: GLuint, fs: GLuint) -> GLuint {
79 let sdr_prog = gl::CreateProgram();
80 gl::AttachShader(sdr_prog, vs);
81 gl::AttachShader(sdr_prog, fs);
82 gl::LinkProgram(sdr_prog);
84 let mut status = gl::FALSE as GLint;
85 gl::GetProgramiv(sdr_prog, gl::LINK_STATUS, &mut status);
86 if status != (gl::TRUE as GLint) {
87 let mut len: GLint = 0;
88 gl::GetProgramiv(sdr_prog, gl::INFO_LOG_LENGTH, &mut len);
91 let mut buf: Vec<u8> = Vec::with_capacity((len + 1) as usize);
92 buf.extend([b' '].iter().cycle().take(len as usize));
93 let err: std::ffi::CString = std::ffi::CString::from_vec_unchecked(buf);
95 gl::GetProgramInfoLog(sdr_prog, len, std::ptr::null_mut(), err.as_ptr() as *mut GLchar);
96 println!("{}", err.to_str().unwrap());
103 let sdl_ctx = sdl2::init().unwrap();
104 let vid_sys = sdl_ctx.video().unwrap();
105 let gl_attr = vid_sys.gl_attr();
107 gl_attr.set_context_profile(GLProfile::Core);
110 .window("foobar", WIN_W, WIN_H)
111 .opengl() // add opengl flag
116 let _gl_ctx = win.gl_create_context().unwrap();
117 let _gl = gl::load_with(|s| vid_sys.gl_get_proc_address(s) as
118 *const std::os::raw::c_void);
128 gl::ClearColor(0.3, 0.1, 0.1, 1.0);
129 gl::GenVertexArrays(1, &mut vao);
130 gl::BindVertexArray(vao);
132 gl::GenBuffers(1, &mut vbo);
133 gl::BindBuffer(gl::ARRAY_BUFFER, vbo);
134 gl::BufferData(gl::ARRAY_BUFFER, (VERTEX_DATA.len() * std::mem::size_of::<GLfloat>()) as GLsizeiptr,
135 std::mem::transmute(&VERTEX_DATA[0]),
137 gl::BindBuffer(gl::ARRAY_BUFFER, 0);
139 vs = compile_sdr(VS, gl::VERTEX_SHADER);
140 fs = compile_sdr(FS, gl::FRAGMENT_SHADER);
142 sprog = link_sdr_prog(vs, fs);
143 let att_str = std::ffi::CString::new("position").unwrap();
145 gl::BindAttribLocation(sprog, VERTEX_LOC, att_str.as_ptr());
146 sprog = link_sdr_prog(vs, fs);
148 gl::UseProgram(sprog);
151 let mut event_pump = sdl_ctx.event_pump().unwrap();
153 for event in event_pump.poll_iter() {
154 // handle user input here
156 sdl2::event::Event::Quit {..} |
157 sdl2::event::Event::KeyDown {keycode:
158 Some(sdl2::keyboard::Keycode::Escape), ..} =>
165 gl::Clear(gl::COLOR_BUFFER_BIT);
166 gl::Viewport(0, 0, WIN_W as i32, WIN_H as i32);
168 gl::EnableVertexAttribArray(VERTEX_LOC);
169 gl::BindBuffer(gl::ARRAY_BUFFER, vbo);
170 gl::VertexAttribPointer(VERTEX_LOC, 2,
171 gl::FLOAT, gl::FALSE,
172 0 as i32, std::ptr::null());
174 gl::DrawArrays(gl::TRIANGLES, 0, NUM_VERTICES);
177 win.gl_swap_window();
181 gl::DeleteProgram(sprog);
182 gl::DeleteShader(vs);
183 gl::DeleteShader(fs);
184 gl::DeleteBuffers(1, &vbo);
185 gl::DeleteVertexArrays(1, &vao);