#![doc(
html_logo_url = "https://raw.githubusercontent.com/plopgrizzly\
/res/master/res/icon.png",
html_favicon_url = "https://raw.githubusercontent.com/plopgrizzly\
/res/master/res/symbol.png",
html_root_url = "http://plopgrizzly.com/res/"
)]
mod sheet;
use std::io::Write;
use std::path::Path;
fn save(filename: &str, content: &[u8]) {
let mut filename2 = std::env::var("OUT_DIR").unwrap();
filename2.push('/');
filename2.push_str(filename);
let mut file = std::fs::File::create(filename2).unwrap();
file.write_all(content).unwrap();
}
#[must_use]
pub struct ShaderBuilder {
name: String,
transform: u8,
tint: bool,
gradient: bool,
graphic: bool,
depth: bool,
blend: bool,
}
impl ShaderBuilder {
fn new(name: &str) -> ShaderBuilder {
ShaderBuilder {
name: name.to_string(),
transform: 0,
tint: false,
gradient: false,
graphic: false,
depth: false,
blend: false,
}
}
pub const fn transform(mut self) -> Self {
self.transform += 1;
self
}
pub fn tint(mut self) -> Self {
assert_eq!(self.tint, false);
self.tint = true;
self
}
pub fn gradient(mut self) -> Self {
assert_eq!(self.gradient, false);
self.gradient = true;
self
}
pub fn graphic(mut self) -> Self {
assert_eq!(self.graphic, false);
self.graphic = true;
self
}
pub fn depth(mut self) -> Self {
assert_eq!(self.depth, false);
self.depth = true;
self
}
pub fn blend(mut self) -> Self {
assert_eq!(self.blend, false);
self.blend = true;
self
}
fn gen(&self) {
let mut opengl_frag = "precision mediump float;\n".to_string();
if self.tint {
opengl_frag.push_str("uniform vec4 tint;\n");
}
if self.graphic {
opengl_frag.push_str("uniform sampler2D tex;");
opengl_frag.push_str("varying vec2 texcoord;\n");
}
if self.gradient {
opengl_frag.push_str("varying vec4 v_gradient;\n");
}
opengl_frag.push_str("void main() {\n gl_FragColor = ");
if self.gradient && self.graphic {
if self.tint {
opengl_frag.push_str("tint * ");
}
opengl_frag.push_str("v_gradient * texture2D(tex, texcoord)");
} else if self.gradient {
if self.tint {
opengl_frag.push_str("tint * ");
}
opengl_frag.push_str("v_gradient");
} else if self.graphic {
if self.tint {
opengl_frag.push_str("tint * ");
}
opengl_frag.push_str("texture2D(tex, texcoord)");
} else if self.tint {
opengl_frag.push_str("tint");
} else {
opengl_frag.push_str("vec4(1.0, 1.0, 1.0, 1.0)");
}
opengl_frag.push_str(";\n}\\0");
let mut opengl_vert = "uniform mat4 cam;\n".to_string();
if self.depth {
opengl_vert.push_str("attribute vec3 pos;\n");
} else {
opengl_vert.push_str("attribute vec2 pos;\n");
}
if self.graphic {
opengl_vert
.push_str("varying vec2 texcoord;\nattribute vec2 texpos;\n");
}
if self.gradient {
opengl_vert
.push_str("varying vec4 v_gradient;\n");
if self.blend {
opengl_vert.push_str("attribute vec4 col;\n");
} else {
opengl_vert.push_str("attribute vec3 col;\n");
}
}
opengl_vert.push_str("void main() {\n");
if self.gradient {
if self.blend {
opengl_vert.push_str("v_gradient = col;\n");
} else {
opengl_vert.push_str("v_gradient = vec4(col.r, col.g, col.b, 1.0);\n");
}
}
if self.graphic {
opengl_vert.push_str("texcoord = texpos;\n");
}
opengl_vert.push_str("gl_Position = cam * ");
if self.depth {
opengl_vert.push_str("vec4(pos, 1.0);\n");
} else {
opengl_vert.push_str("vec4(pos, 0.0, 1.0);\n");
}
opengl_vert.push_str("}\\0");
save(&format!("res/{}.rs", self.name), format!("ShaderBuilder {{tint:{},gradient:{},graphic:{},depth:{},blend:{},opengl_frag:\"{}\",opengl_vert:\"{}\"}}", self.tint, self.gradient, self.graphic, self.depth, self.blend, opengl_frag, opengl_vert).as_bytes());
}
}
pub fn shader(name: &str) -> ShaderBuilder {
ShaderBuilder::new(name)
}
pub fn generate(shader_builders: &[ShaderBuilder]) {
println!("cargo:rerun-if-changed=build.rs");
let mut filename2 = std::env::var("OUT_DIR").unwrap();
filename2.push_str("/res");
std::fs::create_dir_all(filename2).unwrap();
for shader_builder in shader_builders.iter() {
shader_builder.gen();
}
let mut output = "".to_string();
if Path::new("./res/texture/").exists() {
output.push_str(&sheet::write());
}
let mut filename = std::env::var("OUT_DIR").unwrap();
filename.push_str("/res.rs");
std::fs::write(filename, output).unwrap();
}