Clean up shader creation

This commit is contained in:
Thinkofdeath 2015-10-06 23:49:52 +01:00
parent f9e4f14e01
commit b9abf4b9a6
5 changed files with 162 additions and 69 deletions

8
gl/Cargo.lock generated
View File

@ -2,8 +2,8 @@
name = "steven_gl"
version = "0.0.1"
dependencies = [
"gl_common 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"gl_generator 0.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
"gl_common 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gl_generator 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"khronos_api 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -15,7 +15,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "gl_common"
version = "0.0.4"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
@ -23,7 +23,7 @@ dependencies = [
[[package]]
name = "gl_generator"
version = "0.0.27"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"khronos_api 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -141,6 +141,28 @@ pub fn blend_func(s_factor: Factor, d_factor: Factor) {
unsafe { gl::BlendFunc(s_factor, d_factor); }
}
// Face specifies a face to act on.
pub type Face = u32;
pub const BACK: Face = gl::BACK;
pub const FRONT: Face = gl::FRONT;
/// Sets the face to be culled by the gpu.
pub fn cull_face(face: Face) {
unsafe { gl::CullFace(face); }
}
// FaceDirection is used to specify an order of vertices, normally
// used to set which is considered to be the front face.
pub type FaceDirection = u32;
pub const CLOCK_WISE: FaceDirection = gl::CW;
pub const COUNTER_CLOCK_WISE: FaceDirection = gl::CCW;
/// Sets the direction of vertices used to specify the
/// front face (e.g. for culling).
pub fn front_face(dir: FaceDirection) {
unsafe { gl::FrontFace(dir) }
}
/// Type is a type of data used by various operations.
pub type Type = u32;
pub const UNSIGNED_BYTE: Type = gl::UNSIGNED_BYTE;

View File

@ -14,8 +14,9 @@
mod atlas;
pub mod glsl;
#[macro_use]
pub mod shaders;
pub mod ui;
mod shaders;
use std::collections::HashMap;
use std::sync::{Arc, RwLock};
@ -58,6 +59,20 @@ impl Renderer {
shaders::add_shaders(&mut greg);
let ui = ui::UIState::new(&greg, textures.clone(), res.clone());
gl::enable(gl::DEPTH_TEST);
gl::enable(gl::CULL_FACE_FLAG);
gl::cull_face(gl::BACK);
gl::front_face(gl::CLOCK_WISE);
// Shaders
// UI
// Line Drawer
// Models
// Clouds
gl::blend_func(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
Renderer {
resource_version: version,
textures: textures,
@ -556,44 +571,6 @@ impl Texture {
}
}
pub fn create_program(vertex: &str, fragment: &str) -> gl::Program {
let program = gl::Program::new();
let v = gl::Shader::new(gl::VERTEX_SHADER);
v.set_source(vertex);
v.compile();
if v.get_parameter(gl::COMPILE_STATUS) == 0 {
println!("Src: {}", vertex);
panic!("Shader error: {}", v.get_info_log());
} else {
let log = v.get_info_log();
if !log.is_empty() {
println!("{}", log);
}
}
let f = gl::Shader::new(gl::FRAGMENT_SHADER);
f.set_source(fragment);
f.compile();
if f.get_parameter(gl::COMPILE_STATUS) == 0 {
println!("Src: {}", fragment);
panic!("Shader error: {}", f.get_info_log());
} else {
let log = f.get_info_log();
if !log.is_empty() {
println!("{}", log);
}
}
program.attach_shader(v);
program.attach_shader(f);
program.link();
program.use_program();
program
}
#[allow(unused_must_use)]
pub fn generate_element_buffer(size: usize) -> (Vec<u8>, gl::Type) {
let mut ty = gl::UNSIGNED_SHORT;

View File

@ -13,6 +13,7 @@
// limitations under the License.
use render::glsl;
use gl;
pub fn add_shaders(reg: &mut glsl::Registry) {
reg.register("lookup_texture", include_str!("shaders/lookup_texture.glsl"));
@ -20,4 +21,89 @@ pub fn add_shaders(reg: &mut glsl::Registry) {
reg.register("ui_vertex", include_str!("shaders/ui_vertex.glsl"));
reg.register("ui_frag", include_str!("shaders/ui_frag.glsl"));
}
#[macro_export]
macro_rules! init_shader {
(
Program $name:ident {
vert = $vert:expr,
frag = $frag:expr,
attribute = {
$(
$field:ident => $glname:expr,
)*
},
uniform = {
$(
$ufield:ident => $uglname:expr,
)*
},
}
) => (
struct $name {
program: gl::Program,
$(
$field: gl::Attribute,
)+
$(
$ufield: gl::Uniform,
)+
}
impl $name {
pub fn new(reg: &glsl::Registry) -> $name {
let v = reg.get($vert);
let f = reg.get($frag);
let shader = shaders::create_program(&v, &f);
$name {
$(
$field: shader.attribute_location($glname),
)+
$(
$ufield: shader.uniform_location($uglname),
)+
program: shader,
}
}
}
)
}
pub fn create_program(vertex: &str, fragment: &str) -> gl::Program {
let program = gl::Program::new();
let v = gl::Shader::new(gl::VERTEX_SHADER);
v.set_source(vertex);
v.compile();
if v.get_parameter(gl::COMPILE_STATUS) == 0 {
println!("Src: {}", vertex);
panic!("Shader error: {}", v.get_info_log());
} else {
let log = v.get_info_log();
if !log.is_empty() {
println!("{}", log);
}
}
let f = gl::Shader::new(gl::FRAGMENT_SHADER);
f.set_source(fragment);
f.compile();
if f.get_parameter(gl::COMPILE_STATUS) == 0 {
println!("Src: {}", fragment);
panic!("Shader error: {}", f.get_info_log());
} else {
let log = f.get_info_log();
if !log.is_empty() {
println!("{}", log);
}
}
program.attach_shader(v);
program.attach_shader(f);
program.link();
program.use_program();
program
}

View File

@ -17,7 +17,10 @@ use std::io::Write;
use std::collections::HashMap;
use resources;
use gl;
#[macro_use]
use render;
use render::glsl;
use render::shaders;
use byteorder::{WriteBytesExt, NativeEndian};
use image;
use image::{GenericImage};
@ -40,9 +43,7 @@ pub struct UIState {
index_type: gl::Type,
max_index: usize,
shader: gl::Program,
s_texture: gl::Uniform,
s_screensize: gl::Uniform,
shader: UIShader,
// Font
font_pages: Vec<Option<render::Texture>>,
@ -52,30 +53,39 @@ pub struct UIState {
page_height: f64,
}
init_shader! {
Program UIShader {
vert = "ui_vertex",
frag = "ui_frag",
attribute = {
position => "aPosition",
texture_info => "aTextureInfo",
texture_offset => "aTextureOffset",
color => "aColor",
},
uniform = {
texture => "textures",
screensize => "screenSize",
},
}
}
impl UIState {
pub fn new(glsl: &super::glsl::Registry, textures: Arc<RwLock<render::TextureManager>>, res: Arc<RwLock<resources::Manager>>) -> UIState {
let v = glsl.get("ui_vertex");
let f = glsl.get("ui_frag");
let shader = super::create_program(&v, &f);
let s_position = shader.attribute_location("aPosition");
let s_texture_info = shader.attribute_location("aTextureInfo");
let s_texture_offset = shader.attribute_location("aTextureOffset");
let s_color = shader.attribute_location("aColor");
let s_texture = shader.uniform_location("textures");
let s_screensize = shader.uniform_location("screenSize");
pub fn new(glsl: &glsl::Registry, textures: Arc<RwLock<render::TextureManager>>, res: Arc<RwLock<resources::Manager>>) -> UIState {
let shader = UIShader::new(glsl);
let array = gl::VertexArray::new();
array.bind();
let buffer = gl::Buffer::new();
buffer.bind(gl::ARRAY_BUFFER);
s_position.enable();
s_texture_info.enable();
s_texture_offset.enable();
s_color.enable();
s_position.vertex_pointer_int(3, gl::SHORT, 28, 0);
s_texture_info.vertex_pointer(4, gl::UNSIGNED_SHORT, false, 28, 8);
s_texture_offset.vertex_pointer_int(3, gl::SHORT, 28, 16);
s_color.vertex_pointer(4, gl::UNSIGNED_BYTE, true, 28, 24);
shader.position.enable();
shader.texture_info.enable();
shader.texture_offset.enable();
shader.color.enable();
shader.position.vertex_pointer_int(3, gl::SHORT, 28, 0);
shader.texture_info.vertex_pointer(4, gl::UNSIGNED_SHORT, false, 28, 8);
shader.texture_offset.vertex_pointer_int(3, gl::SHORT, 28, 16);
shader.color.vertex_pointer(4, gl::UNSIGNED_BYTE, true, 28, 24);
let index_buffer = gl::Buffer::new();
index_buffer.bind(gl::ELEMENT_ARRAY_BUFFER);
@ -107,8 +117,6 @@ impl UIState {
max_index: 0,
shader: shader,
s_texture: s_texture,
s_screensize: s_screensize,
// Font
font_pages: pages,
@ -135,8 +143,8 @@ impl UIState {
gl::enable(gl::BLEND);
gl::blend_func(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
self.shader.use_program();
self.s_texture.set_int(0);
self.shader.program.use_program();
self.shader.texture.set_int(0);
if self.count > 0 {
self.array.bind();
if self.max_index < self.count {
@ -147,7 +155,7 @@ impl UIState {
self.max_index = self.count;
}
self.s_screensize.set_float2(width as f32, height as f32);
self.shader.screensize.set_float2(width as f32, height as f32);
self.buffer.bind(gl::ARRAY_BUFFER);
if self.data.len() > self.prev_size {