gate/renderer/core_renderer/sdl/
sprite_program.rs

1// Copyright 2017-2019 Matthew D. Michelotti
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//   http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::{ptr, str, mem};
16use std::os::raw::{c_void, c_char};
17
18use gl::types::*;
19use gl;
20
21use super::shader_util;
22use crate::renderer::shaders;
23
24pub struct SpriteProgram {
25    pub handle: GLuint,
26    pub vao: GLuint,
27    vs: GLuint,
28    fs: GLuint,
29    pub uniform_tex: GLint,
30    pub uniform_inv_tex_dims: GLint,
31}
32
33impl SpriteProgram {
34    pub fn new() -> SpriteProgram {
35        let vs = shader_util::compile_shader(shaders::VS_SPRITE_SRC, gl::VERTEX_SHADER);
36        let fs = shader_util::compile_shader(shaders::FS_SPRITE_SRC, gl::FRAGMENT_SHADER);
37        let handle = shader_util::link_program(vs, fs);
38        let vao = SpriteProgram::make_vao(handle);
39        unsafe {
40            SpriteProgram {
41                handle, vao, vs, fs,
42                uniform_tex: gl::GetUniformLocation(handle, c_str!("tex")),
43                uniform_inv_tex_dims: gl::GetUniformLocation(handle, c_str!("inv_tex_dims")),
44            }
45        }
46    }
47
48    fn make_vao(program_handle: GLuint) -> GLuint {
49        let mut vao = 0;
50        unsafe {
51            let attrib_vert = gl::GetAttribLocation(program_handle, c_str!("vert"));
52            let attrib_vs_inv_tex_sample_dims = gl::GetAttribLocation(program_handle, c_str!("vs_inv_tex_sample_dims"));
53            let attrib_vs_tex_vert_rb = gl::GetAttribLocation(program_handle, c_str!("vs_tex_vert_rb"));
54            let attrib_vs_flash_ratio = gl::GetAttribLocation(program_handle, c_str!("vs_flash_ratio"));
55
56            gl::GenVertexArrays(1, &mut vao);
57            gl::BindVertexArray(vao);
58
59            // TODO be consistent with the gl::TRUE/FALSE values in gl::VertexAttribPointer...
60
61            gl::EnableVertexAttribArray(attrib_vert as GLuint);
62            gl::VertexAttribPointer(attrib_vert as GLuint, 2, gl::FLOAT, gl::FALSE, 7*mem::size_of::<GLfloat>() as i32, ptr::null());
63
64            gl::EnableVertexAttribArray(attrib_vs_inv_tex_sample_dims as GLuint);
65            gl::VertexAttribPointer(attrib_vs_inv_tex_sample_dims as GLuint, 2, gl::FLOAT, gl::TRUE, 7*mem::size_of::<GLfloat>() as i32,
66                                    (2 * mem::size_of::<GLfloat>()) as *const c_void);
67
68            gl::EnableVertexAttribArray(attrib_vs_tex_vert_rb as GLuint);
69            gl::VertexAttribPointer(attrib_vs_tex_vert_rb as GLuint, 2, gl::FLOAT, gl::TRUE, 7*mem::size_of::<GLfloat>() as i32,
70                                    (4 * mem::size_of::<GLfloat>()) as *const c_void);
71
72            gl::EnableVertexAttribArray(attrib_vs_flash_ratio as GLuint);
73            gl::VertexAttribPointer(attrib_vs_flash_ratio as GLuint, 1, gl::FLOAT, gl::TRUE, 7*mem::size_of::<GLfloat>() as i32,
74                                    (6 * mem::size_of::<GLfloat>()) as *const c_void);
75
76            gl::BindVertexArray(0);
77        }
78        vao
79    }
80}
81
82impl Drop for SpriteProgram {
83    fn drop(&mut self) {
84        unsafe {
85            gl::DeleteProgram(self.handle);
86            gl::DeleteShader(self.fs);
87            gl::DeleteShader(self.vs);
88            gl::DeleteVertexArrays(1, &self.vao);
89        }
90    }
91}