gdritter repos chenoska / b809ce5
Starting to document things kind of a bit Getty Ritter 6 years ago
2 changed file(s) with 57 addition(s) and 14 deletion(s). Collapse all Expand all
1313 use std::marker::PhantomData;
1414 use std::os::raw::c_void;
1515
16 //
17
16 /// Clear the screen to a generic color
1817 pub fn clear() {
1918 unsafe {
2019 gl::ClearColor(0.3, 0.3, 0.3, 1.0);
2221 }
2322 }
2423
24 /// Abstract over an OpenGL context as well as a basic event loop
2525 pub struct Window {
2626 events: glutin::EventsLoop,
2727 gl_window: glutin::GlWindow,
2828 }
2929
3030 impl Window {
31 /// Attempt to create a new window, and load all the relevant
32 /// OpenGL symbols in the process
3133 pub fn create() -> Result<Window, Error> {
3234 use glutin::GlContext;
3335 let events = glutin::EventsLoop::new();
4244 Ok(Window { events, gl_window })
4345 }
4446
47 /// Run the main event loop, calling the supplied callback with
48 /// every event
4549 pub fn run<F>(self, mut cb: F) -> Result<(), Error>
4650 where F: FnMut(glutin::Event) -> glutin::ControlFlow
4751 {
6670
6771 }
6872
73 /// Wrap an OpenGL shader. This will automatically be cleaned up from
74 /// the OpenGL state machine when it is dropped.
6975 pub struct Shader {
7076 pub n: gl::GLuint,
7177 }
7682 }
7783 }
7884
85 /// Right now, we're only concerned with either Fragment or Vertex
86 /// shaders. We might eventually want Geometry shaders, as well.
7987 #[derive(PartialEq, Eq, Debug, Copy, Clone)]
8088 pub enum ShaderType {
8189 Fragment,
8391 }
8492
8593 impl ShaderType {
94 /// Convert a ShaderType value to OpenGL's enum value for the same
8695 fn to_glenum(&self) -> gl::GLenum {
8796 match *self {
8897 ShaderType::Fragment => gl::FRAGMENT_SHADER,
92101 }
93102
94103 impl Shader {
104 /// Compile a shade string and provide our Rust-level handle to it
95105 pub fn compile(ty: ShaderType, src: &str) -> Result<Shader, Error> {
106 // this structure is gonna repeat a few times but also can't
107 // really get abstracted over in a clean way, so this comment
108 // could be consulted for the other functions, too.
96109 let shader;
97110 unsafe {
111 // we start by getting a new shader from OpenGL
98112 shader = gl::CreateShader(ty.to_glenum());
113 // and also get the C string version of the source code
99114 let c_str = ffi::CString::new(src.as_bytes())?;
115
116 // and then we compile it!
100117 gl::ShaderSource(shader, 1, &c_str.as_ptr(), ptr::null());
101118 gl::CompileShader(shader);
102119
120 // this is the common part: we now ask OpenGL for the
121 // status of that compile, which OpenGL gives us by
122 // updating a pointer
103123 let mut status = gl::FALSE as gl::GLint;
104124 gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut status);
105125
126 // If it's not good...
106127 if status != (gl::TRUE as gl::GLint) {
128 // then then need to get the length of the error
129 // message, which, again we fetch via pointer
107130 let mut len = 0;
108131 gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &mut len);
132
133 // create the buffer that's big enough for that
134 // message
109135 let mut buf = Vec::with_capacity(len as usize);
110136 buf.set_len((len as usize) - 1);
137 // and then fill it in via OpenGL's mechanisms
111138 gl::GetShaderInfoLog(
112139 shader,
113140 len,
114141 ptr::null_mut(),
115142 buf.as_mut_ptr() as *mut gl::GLchar
116143 );
144 // and finally return it!
117145 return Err(Error::CompileError(String::from_utf8(buf)?));
118146 }
119147 }
148
120149 Ok(Shader { n: shader })
121150 }
122151 }
124153
125154 //
126155
156 /// Represents a linked set of OpenGL shaders.
127157 pub struct Program {
128158 pub p: gl::GLuint,
129159 pub shaders: Vec<Shader>,
139169 }
140170
141171 impl Program {
172 /// Link several existing shaders into a single Program
142173 pub fn link(shaders: Vec<Shader>) -> Result<Program, Error> {
174 // the stuff in here looks a lot like Shader::compile, so
175 // consult the inline docs for that to figure out what's going on
143176 unsafe {
144177 let program = gl::CreateProgram();
145178 for s in shaders.iter() {
88
99 pub mod board;
1010 pub mod graphics;
11 pub mod pan {
12 pub use graphics::*;
13 }
11 use graphics::{
12 Error,
13 Shader,
14 ShaderType,
15 Program,
16 Texture,
17 VertexArray,
18 VertexBuffer,
19 Window,
20 clear,
21 };
1422 use graphics::vertices::V2D;
1523
1624 static TILE_DATA: [V2D; 4] = [
4553 out_color = texture(tex, t_uv);
4654 }";
4755
48 pub fn main_loop() -> Result<(), pan::Error> {
56 /// the main loop of the game, setting up and running the window and
57 /// event loop
58 pub fn main_loop() -> Result<(), Error> {
4959 let mut f = std::fs::File::open("sample.png")?;
5060 let texture: imagefmt::Image<u8> = imagefmt::png::read(
5161 &mut f,
5262 imagefmt::ColFmt::RGBA,
5363 )?;
5464
55 let window = pan::Window::create()?;
65 let window = Window::create()?;
5666
57 let vs = pan::Shader::compile(pan::ShaderType::Vertex, VS_SRC)?;
58 let fs = pan::Shader::compile(pan::ShaderType::Fragment, FS_SRC)?;
59 let program = pan::Program::link(vec![vs, fs])?;
67 let vs = Shader::compile(ShaderType::Vertex, VS_SRC)?;
68 let fs = Shader::compile(ShaderType::Fragment, FS_SRC)?;
69 let program = Program::link(vec![vs, fs])?;
6070
61 let tex = pan::Texture::new_from_bitmap(&texture);
71 let tex = Texture::new_from_bitmap(&texture);
6272
63 let vbo = pan::VertexBuffer::new_array_buffer(
64 pan::VertexArray::new(&program),
73 let vbo = VertexBuffer::new_array_buffer(
74 VertexArray::new(&program),
6575 &TILE_DATA,
6676 );
6777
95105 _ => (),
96106 }
97107
98 pan::clear();
108 clear();
99109 program.set_texture("tex", &tex).unwrap();
100110 vbo.draw();
101111