This commit is contained in:
Piotr Siuszko 2020-08-18 18:20:22 +02:00
parent 75182b76e7
commit 4b606801ae
4 changed files with 243 additions and 262 deletions

200
Cargo.lock generated
View File

@ -1,20 +1,5 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
[[package]]
name = "addr2line"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072"
dependencies = [
"gimli",
]
[[package]]
name = "adler"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
[[package]] [[package]]
name = "adler32" name = "adler32"
version = "1.2.0" version = "1.2.0"
@ -33,20 +18,6 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
[[package]]
name = "backtrace"
version = "0.3.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46254cf2fdcdf1badb5934448c1bcbe046a56537b3987d96c51a7afc5d03f293"
dependencies = [
"addr2line",
"cfg-if",
"libc",
"miniz_oxide",
"object",
"rustc-demangle",
]
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.2.1" version = "1.2.1"
@ -82,15 +53,6 @@ dependencies = [
"rand", "rand",
] ]
[[package]]
name = "cloudabi"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
dependencies = [
"bitflags",
]
[[package]] [[package]]
name = "cmake" name = "cmake"
version = "0.1.44" version = "0.1.44"
@ -172,8 +134,6 @@ dependencies = [
"gl", "gl",
"glfw", "glfw",
"image", "image",
"imgui",
"imgui-glium-renderer",
] ]
[[package]] [[package]]
@ -191,12 +151,6 @@ dependencies = [
"num-traits 0.1.43", "num-traits 0.1.43",
] ]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]] [[package]]
name = "fuchsia-cprng" name = "fuchsia-cprng"
version = "0.1.1" version = "0.1.1"
@ -213,19 +167,13 @@ dependencies = [
"lzw", "lzw",
] ]
[[package]]
name = "gimli"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724"
[[package]] [[package]]
name = "gl" name = "gl"
version = "0.10.0" version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81457bb802910ad5b535eb48541c51830a761804aa5b7087adbc9d049aa57aca" checksum = "81457bb802910ad5b535eb48541c51830a761804aa5b7087adbc9d049aa57aca"
dependencies = [ dependencies = [
"gl_generator 0.9.0", "gl_generator",
] ]
[[package]] [[package]]
@ -234,20 +182,9 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a795170cbd85b5a7baa58d6d7525cae6a03e486859860c220f7ebbbdd379d0a" checksum = "7a795170cbd85b5a7baa58d6d7525cae6a03e486859860c220f7ebbbdd379d0a"
dependencies = [ dependencies = [
"khronos_api 2.2.0", "khronos_api",
"log", "log",
"xml-rs 0.7.0", "xml-rs",
]
[[package]]
name = "gl_generator"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d"
dependencies = [
"khronos_api 3.1.0",
"log",
"xml-rs 0.8.3",
] ]
[[package]] [[package]]
@ -274,21 +211,6 @@ dependencies = [
"cmake", "cmake",
] ]
[[package]]
name = "glium"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "030bb23a12fac7e589b002c5e131e89348df88f91b56e3f3dbc4249527eeebf9"
dependencies = [
"backtrace",
"fnv",
"gl_generator 0.14.0",
"lazy_static",
"memoffset",
"smallvec",
"takeable-option",
]
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.1.15" version = "0.1.15"
@ -316,38 +238,6 @@ dependencies = [
"scoped_threadpool", "scoped_threadpool",
] ]
[[package]]
name = "imgui"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fdb2bcc7e498e78137ce28705ae836d69e36ee2eac89d0d926cfabfcf550570"
dependencies = [
"bitflags",
"glium",
"imgui-sys",
"lazy_static",
"parking_lot",
]
[[package]]
name = "imgui-glium-renderer"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c73e47cb3db3e354e3977265b14d7e6ff8b55a83f06ab6c7d04b4d441d64f586"
dependencies = [
"glium",
"imgui",
]
[[package]]
name = "imgui-sys"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72be9671d64dd0ed26bb708cd10060a431262ac90ae70cf7c5912feefe6849da"
dependencies = [
"cc",
]
[[package]] [[package]]
name = "inflate" name = "inflate"
version = "0.4.5" version = "0.4.5"
@ -373,12 +263,6 @@ version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "037ab472c33f67b5fbd3e9163a2645319e5356fcd355efa6d4eb7fff4bbcb554" checksum = "037ab472c33f67b5fbd3e9163a2645319e5356fcd355efa6d4eb7fff4bbcb554"
[[package]]
name = "khronos_api"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.4.0" version = "1.4.0"
@ -391,15 +275,6 @@ version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2f02823cf78b754822df5f7f268fb59822e7296276d3e069d8e8cb26a14bd10" checksum = "a2f02823cf78b754822df5f7f268fb59822e7296276d3e069d8e8cb26a14bd10"
[[package]]
name = "lock_api"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75"
dependencies = [
"scopeguard",
]
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.11" version = "0.4.11"
@ -430,15 +305,6 @@ dependencies = [
"autocfg", "autocfg",
] ]
[[package]]
name = "miniz_oxide"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be0f75932c1f6cfae3c04000e40114adf955636e19040f9c0a2c380702aa1c7f"
dependencies = [
"adler",
]
[[package]] [[package]]
name = "nom" name = "nom"
version = "1.2.4" version = "1.2.4"
@ -553,36 +419,6 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "object"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5"
[[package]]
name = "parking_lot"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3"
dependencies = [
"cfg-if",
"cloudabi",
"libc",
"redox_syscall",
"smallvec",
"winapi",
]
[[package]] [[package]]
name = "png" name = "png"
version = "0.12.0" version = "0.12.0"
@ -675,18 +511,6 @@ dependencies = [
"rand_core 0.3.1", "rand_core 0.3.1",
] ]
[[package]]
name = "redox_syscall"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "rustc-demangle"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
[[package]] [[package]]
name = "rustc-serialize" name = "rustc-serialize"
version = "0.3.24" version = "0.3.24"
@ -714,12 +538,6 @@ dependencies = [
"nom", "nom",
] ]
[[package]]
name = "smallvec"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252"
[[package]] [[package]]
name = "syn" name = "syn"
version = "0.15.44" version = "0.15.44"
@ -731,12 +549,6 @@ dependencies = [
"unicode-xid", "unicode-xid",
] ]
[[package]]
name = "takeable-option"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36ae8932fcfea38b7d3883ae2ab357b0d57a02caaa18ebb4f5ece08beaec4aa0"
[[package]] [[package]]
name = "unicode-xid" name = "unicode-xid"
version = "0.1.0" version = "0.1.0"
@ -773,9 +585,3 @@ checksum = "3c1cb601d29fe2c2ac60a2b2e5e293994d87a1f6fa9687a31a15270f909be9c2"
dependencies = [ dependencies = [
"bitflags", "bitflags",
] ]
[[package]]
name = "xml-rs"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b07db065a5cf61a7e4ba64f29e67db906fb1787316516c4e6e5ff0fea1efcd8a"

View File

@ -14,6 +14,4 @@ image = "0.19.0"
# only needed from chapter 3 on # only needed from chapter 3 on
# tobj = "0.1.6" # tobj = "0.1.6"
# num = "0.2.0" # num = "0.2.0"
# rand = "0.5.5" # rand = "0.5.5"
imgui = "0.4.0"
imgui-glium-renderer = "0.4.0"

View File

@ -12,6 +12,7 @@ use std::mem;
use std::os::raw::c_void; use std::os::raw::c_void;
mod consts; mod consts;
mod shader;
pub fn main() { pub fn main() {
// glfw: initialize and configure // glfw: initialize and configure
@ -36,92 +37,72 @@ pub fn main() {
gl::load_with(|symbol| window.get_proc_address(symbol) as *const _); gl::load_with(|symbol| window.get_proc_address(symbol) as *const _);
let (shaderProgram, VAO) = unsafe { let (shaderObject, VAO) = unsafe {
let vertexShader = gl::CreateShader(gl::VERTEX_SHADER); let vShaderCode = CString::new(consts::VERTEX_SHADER_SRC.as_bytes()).unwrap();
let c_str_vertex = CString::new(consts::VERTEX_SHADER_SRC.as_bytes()).unwrap(); let fShaderCode = CString::new(consts::FRAGMENT_SHADER_SRC.as_bytes()).unwrap();
gl::ShaderSource(vertexShader, 1, &c_str_vertex.as_ptr(), ptr::null()); let shader = crate::shader::Shader::new(vShaderCode, fShaderCode);
gl::CompileShader(vertexShader);
// check for shader compile errors
let mut success = gl::FALSE as GLint;
let mut infoLog = Vec::with_capacity(512);
infoLog.set_len(512 - 1); // subtract 1 to skip the trailing null character
gl::GetShaderiv(vertexShader, gl::COMPILE_STATUS, &mut success);
if success != gl::TRUE as GLint {
gl::GetShaderInfoLog(vertexShader, 512, ptr::null_mut(), infoLog.as_mut_ptr() as *mut GLchar);
println!("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n{}", str::from_utf8(&infoLog).unwrap());
}
let fragmentShader = gl::CreateShader(gl::FRAGMENT_SHADER);
let c_str_fragment = CString::new(consts::FRAGMENT_SHADER_SRC.as_bytes()).unwrap();
gl::ShaderSource(fragmentShader,1, &c_str_fragment.as_ptr(), ptr::null());
gl::CompileShader(fragmentShader);
// check for shader compile errors
gl::GetShaderiv(fragmentShader, gl::COMPILE_STATUS, &mut success);
if success != gl::TRUE as GLint {
gl::GetShaderInfoLog(fragmentShader, 512, ptr::null_mut(), infoLog.as_mut_ptr() as *mut GLchar);
println!("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n{}", str::from_utf8(&infoLog).unwrap());
}
let shaderProgram = gl::CreateProgram();
gl::AttachShader(shaderProgram, vertexShader);
gl::AttachShader(shaderProgram, fragmentShader);
gl::LinkProgram(shaderProgram);
// check for linking errors
gl::GetProgramiv(shaderProgram, gl::LINK_STATUS, &mut success);
if success != gl::TRUE as GLint {
gl::GetProgramInfoLog(shaderProgram, 512, ptr::null_mut(), infoLog.as_mut_ptr() as *mut GLchar);
println!("ERROR::SHADER::PROGRAM::COMPILATION_FAILED\n{}", str::from_utf8(&infoLog).unwrap());
}
gl::DeleteShader(vertexShader);
gl::DeleteShader(fragmentShader);
// set up vertex data (and buffer(s)) and configure vertex attributes // set up vertex data (and buffer(s)) and configure vertex attributes
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// HINT: type annotation is crucial since default for float literals is f64 // HINT: type annotation is crucial since default for float literals is f64
let vertices: [f32; 9] = [ let vertices: [f32; 12] = [
-0.5, -0.5, 0.0, // left 0.5, 0.5, 0.0, // top right
0.5, -0.5, 0.0, // right 0.5, -0.5, 0.0, // bottom right
0.0, 0.5, 0.0 // top -0.5, -0.5, 0.0, // bottom left
-0.5, 0.5, 0.0 // top left
]; ];
let (mut VBO, mut VAO) = (0, 0); let indices = [ // note that we start from 0!
0, 1, 3, // first Triangle
1, 2, 3 // second Triangle
];
let (mut VBO, mut VAO, mut EBO) = (0, 0, 0);
gl::GenVertexArrays(1, &mut VAO); gl::GenVertexArrays(1, &mut VAO);
gl::GenBuffers(1, &mut VBO); gl::GenBuffers(1, &mut VBO);
gl::GenBuffers(1, &mut EBO);
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
gl::BindVertexArray(VAO); gl::BindVertexArray(VAO);
gl::BindBuffer(gl::ARRAY_BUFFER, VBO); gl::BindBuffer(gl::ARRAY_BUFFER, VBO);
gl::BufferData(gl::ARRAY_BUFFER, gl::BufferData(gl::ARRAY_BUFFER,
(vertices.len() * mem::size_of::<GLfloat>()) as GLsizeiptr, (vertices.len() * mem::size_of::<GLfloat>()) as GLsizeiptr,
&vertices[0] as *const f32 as *const c_void, &vertices[0] as *const f32 as *const c_void,
gl::STATIC_DRAW); gl::STATIC_DRAW);
gl::VertexAttribPointer(0,3,gl::FLOAT, gl::FALSE, 3 * mem::size_of::<GLfloat>() as GLsizei, ptr::null()); gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, EBO);
gl::BufferData(gl::ELEMENT_ARRAY_BUFFER,
(indices.len() * mem::size_of::<GLfloat>()) as GLsizeiptr,
&indices[0] as *const i32 as *const c_void,
gl::STATIC_DRAW);
gl::VertexAttribPointer(0, 3, gl::FLOAT, gl::FALSE, 3 * mem::size_of::<GLfloat>() as GLsizei, ptr::null());
gl::EnableVertexAttribArray(0); gl::EnableVertexAttribArray(0);
// note that this is allowed, the call to gl::VertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
gl::BindBuffer(gl::ARRAY_BUFFER, 0); gl::BindBuffer(gl::ARRAY_BUFFER, 0);
// remember: do NOT unbind the EBO while a VAO is active as the bound element buffer object IS stored in the VAO; keep the EBO bound.
// gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, 0);
// You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
// VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
gl::BindVertexArray(0);
// uncomment this call to draw in wireframe polygons. // uncomment this call to draw in wireframe polygons.
// gl::PolygonMode(gl::FRONT_AND_BACK, gl::LINE); // gl::PolygonMode(gl::FRONT_AND_BACK, gl::LINE);
(shaderProgram, VAO) (shader, VAO)
}; };
// render loop // render loop
// ----------- // -----------
let mut color_r = 0.0; let color_r = 0.3;
let mut color_g = 0.0; let color_g = 0.3;
let mut color_b = 0.0; let color_b = 0.6;
while !window.should_close() { while !window.should_close() {
// events // events
// ----- // -----
process_events(&mut window, &events); process_events(&mut window, &events);
color_r = (color_r + 0.03) % 1.0;
color_g = (color_g + 0.01) % 0.6;
color_b = (color_b + 0.02) % 1.0;
// render // render
// ------ // ------
unsafe { unsafe {
@ -129,9 +110,9 @@ pub fn main() {
gl::Clear(gl::COLOR_BUFFER_BIT); gl::Clear(gl::COLOR_BUFFER_BIT);
// draw our first triangle // draw our first triangle
gl::UseProgram(shaderProgram); shaderObject.useProgram();
gl::BindVertexArray(VAO); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized gl::BindVertexArray(VAO); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized
gl::DrawArrays(gl::TRIANGLES, 0, 3); gl::DrawElements(gl::TRIANGLES, 6, gl::UNSIGNED_INT, ptr::null());
} }
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.) // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)

196
src/shader.rs Normal file
View File

@ -0,0 +1,196 @@
#![allow(non_snake_case)]
use std::ffi::{CString, CStr};
use std::fs::File;
use std::io::Read;
use std::ptr;
use std::str;
use gl;
use gl::types::*;
use cgmath::{Matrix, Matrix4, Vector3};
use cgmath::prelude::*;
pub struct Shader {
pub ID: u32,
}
/// NOTE: mixture of `shader_s.h` and `shader_m.h` (the latter just contains
/// a few more setters for uniforms)
#[allow(dead_code)]
impl Shader {
pub fn new(vShaderCode: CString, fShaderCode: CString) -> Shader {
let mut shader = Shader { ID: 0 };
// 2. compile shaders
unsafe {
// vertex shader
let vertex = gl::CreateShader(gl::VERTEX_SHADER);
gl::ShaderSource(vertex, 1, &vShaderCode.as_ptr(), ptr::null());
gl::CompileShader(vertex);
shader.checkCompileErrors(vertex, "VERTEX");
// fragment Shader
let fragment = gl::CreateShader(gl::FRAGMENT_SHADER);
gl::ShaderSource(fragment, 1, &fShaderCode.as_ptr(), ptr::null());
gl::CompileShader(fragment);
shader.checkCompileErrors(fragment, "FRAGMENT");
// shader Program
let ID = gl::CreateProgram();
gl::AttachShader(ID, vertex);
gl::AttachShader(ID, fragment);
gl::LinkProgram(ID);
shader.checkCompileErrors(ID, "PROGRAM");
// delete the shaders as they're linked into our program now and no longer necessary
gl::DeleteShader(vertex);
gl::DeleteShader(fragment);
shader.ID = ID;
}
shader
}
pub fn from_file(vertexPath: &str, fragmentPath: &str) -> Shader {
// 1. retrieve the vertex/fragment source code from filesystem
let mut vShaderFile = File::open(vertexPath)
.unwrap_or_else(|_| panic!("Failed to open {}", vertexPath));
let mut fShaderFile = File::open(fragmentPath)
.unwrap_or_else(|_| panic!("Failed to open {}", fragmentPath));
let mut vertexCode = String::new();
let mut fragmentCode = String::new();
vShaderFile
.read_to_string(&mut vertexCode)
.expect("Failed to read vertex shader");
fShaderFile
.read_to_string(&mut fragmentCode)
.expect("Failed to read fragment shader");
let vShaderCode = CString::new(vertexCode.as_bytes()).unwrap();
let fShaderCode = CString::new(fragmentCode.as_bytes()).unwrap();
Shader::new(vShaderCode, fShaderCode)
}
/// activate the shader
/// ------------------------------------------------------------------------
pub unsafe fn useProgram(&self) {
gl::UseProgram(self.ID)
}
/// utility uniform functions
/// ------------------------------------------------------------------------
pub unsafe fn setBool(&self, name: &CStr, value: bool) {
gl::Uniform1i(gl::GetUniformLocation(self.ID, name.as_ptr()), value as i32);
}
/// ------------------------------------------------------------------------
pub unsafe fn setInt(&self, name: &CStr, value: i32) {
gl::Uniform1i(gl::GetUniformLocation(self.ID, name.as_ptr()), value);
}
/// ------------------------------------------------------------------------
pub unsafe fn setFloat(&self, name: &CStr, value: f32) {
gl::Uniform1f(gl::GetUniformLocation(self.ID, name.as_ptr()), value);
}
/// ------------------------------------------------------------------------
pub unsafe fn setVector3(&self, name: &CStr, value: &Vector3<f32>) {
gl::Uniform3fv(gl::GetUniformLocation(self.ID, name.as_ptr()), 1, value.as_ptr());
}
/// ------------------------------------------------------------------------
pub unsafe fn setVec3(&self, name: &CStr, x: f32, y: f32, z: f32) {
gl::Uniform3f(gl::GetUniformLocation(self.ID, name.as_ptr()), x, y, z);
}
/// ------------------------------------------------------------------------
pub unsafe fn setMat4(&self, name: &CStr, mat: &Matrix4<f32>) {
gl::UniformMatrix4fv(gl::GetUniformLocation(self.ID, name.as_ptr()), 1, gl::FALSE, mat.as_ptr());
}
/// utility function for checking shader compilation/linking errors.
/// ------------------------------------------------------------------------
unsafe fn checkCompileErrors(&self, shader: u32, type_: &str) {
let mut success = gl::FALSE as GLint;
let mut infoLog = Vec::with_capacity(1024);
infoLog.set_len(1024 - 1); // subtract 1 to skip the trailing null character
if type_ != "PROGRAM" {
gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut success);
if success != gl::TRUE as GLint {
gl::GetShaderInfoLog(shader, 1024, ptr::null_mut(), infoLog.as_mut_ptr() as *mut GLchar);
println!("ERROR::SHADER_COMPILATION_ERROR of type: {}\n{}\n \
-- --------------------------------------------------- -- ",
type_,
str::from_utf8(&infoLog).unwrap());
}
} else {
gl::GetProgramiv(shader, gl::LINK_STATUS, &mut success);
if success != gl::TRUE as GLint {
gl::GetProgramInfoLog(shader, 1024, ptr::null_mut(), infoLog.as_mut_ptr() as *mut GLchar);
println!("ERROR::PROGRAM_LINKING_ERROR of type: {}\n{}\n \
-- --------------------------------------------------- -- ",
type_,
str::from_utf8(&infoLog).unwrap());
}
}
}
/// Only used in 4.9 Geometry shaders - ignore until then (shader.h in original C++)
pub fn with_geometry_shader(vertexPath: &str, fragmentPath: &str, geometryPath: &str) -> Self {
let mut shader = Shader { ID: 0 };
// 1. retrieve the vertex/fragment source code from filesystem
let mut vShaderFile = File::open(vertexPath)
.unwrap_or_else(|_| panic!("Failed to open {}", vertexPath));
let mut fShaderFile = File::open(fragmentPath)
.unwrap_or_else(|_| panic!("Failed to open {}", fragmentPath));
let mut gShaderFile = File::open(geometryPath)
.unwrap_or_else(|_| panic!("Failed to open {}", geometryPath));
let mut vertexCode = String::new();
let mut fragmentCode = String::new();
let mut geometryCode = String::new();
vShaderFile
.read_to_string(&mut vertexCode)
.expect("Failed to read vertex shader");
fShaderFile
.read_to_string(&mut fragmentCode)
.expect("Failed to read fragment shader");
gShaderFile
.read_to_string(&mut geometryCode)
.expect("Failed to read geometry shader");
let vShaderCode = CString::new(vertexCode.as_bytes()).unwrap();
let fShaderCode = CString::new(fragmentCode.as_bytes()).unwrap();
let gShaderCode = CString::new(geometryCode.as_bytes()).unwrap();
// 2. compile shaders
unsafe {
// vertex shader
let vertex = gl::CreateShader(gl::VERTEX_SHADER);
gl::ShaderSource(vertex, 1, &vShaderCode.as_ptr(), ptr::null());
gl::CompileShader(vertex);
shader.checkCompileErrors(vertex, "VERTEX");
// fragment Shader
let fragment = gl::CreateShader(gl::FRAGMENT_SHADER);
gl::ShaderSource(fragment, 1, &fShaderCode.as_ptr(), ptr::null());
gl::CompileShader(fragment);
shader.checkCompileErrors(fragment, "FRAGMENT");
// geometry shader
let geometry = gl::CreateShader(gl::GEOMETRY_SHADER);
gl::ShaderSource(geometry, 1, &gShaderCode.as_ptr(), ptr::null());
gl::CompileShader(geometry);
shader.checkCompileErrors(geometry, "GEOMETRY");
// shader Program
let ID = gl::CreateProgram();
gl::AttachShader(ID, vertex);
gl::AttachShader(ID, fragment);
gl::AttachShader(ID, geometry);
gl::LinkProgram(ID);
shader.checkCompileErrors(ID, "PROGRAM");
// delete the shaders as they're linked into our program now and no longer necessary
gl::DeleteShader(vertex);
gl::DeleteShader(fragment);
gl::DeleteShader(geometry);
shader.ID = ID;
}
shader
}
}