♻️ Extract texture.rs and add forgotten shader.rs
parent
593784917e
commit
358e139c9c
29
src/main.rs
29
src/main.rs
|
@ -12,10 +12,12 @@ use std::time::{Duration};
|
||||||
|
|
||||||
mod iqm;
|
mod iqm;
|
||||||
mod shader;
|
mod shader;
|
||||||
|
mod texture;
|
||||||
mod timestep;
|
mod timestep;
|
||||||
|
|
||||||
use iqm::Model;
|
use iqm::Model;
|
||||||
use shader::{ShaderProgram, ShaderObject};
|
use shader::{ShaderProgram, ShaderObject};
|
||||||
|
use texture::Texture;
|
||||||
use timestep::TimeStep;
|
use timestep::TimeStep;
|
||||||
|
|
||||||
pub fn load_small_file <P> (name: P) -> Vec <u8>
|
pub fn load_small_file <P> (name: P) -> Vec <u8>
|
||||||
|
@ -47,30 +49,6 @@ where V: Into <Vec3>
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ugly_load_texture <P> (name: P) -> u32
|
|
||||||
where P: AsRef <Path>
|
|
||||||
{
|
|
||||||
let decoder = png::Decoder::new (File::open (name).unwrap ());
|
|
||||||
let (info, mut reader) = decoder.read_info ().unwrap ();
|
|
||||||
// Allocate the output buffer.
|
|
||||||
let mut buf = vec! [0; info.buffer_size ()];
|
|
||||||
// Read the next frame. Currently this function should only called once.
|
|
||||||
// The default options
|
|
||||||
reader.next_frame (&mut buf).unwrap ();
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
gl::BindTexture (gl::TEXTURE_2D, 1);
|
|
||||||
gl::TexImage2D (gl::TEXTURE_2D, 0, gl::RGBA.try_into ().unwrap (), 1024, 1024, 0, gl::RGBA, gl::UNSIGNED_BYTE, &buf [0] as *const u8 as *const c_void);
|
|
||||||
|
|
||||||
gl::TexParameteri (gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as i32);
|
|
||||||
gl::TexParameteri (gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as i32);
|
|
||||||
gl::TexParameteri (gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as i32);
|
|
||||||
gl::TexParameteri (gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as i32);
|
|
||||||
}
|
|
||||||
|
|
||||||
1
|
|
||||||
}
|
|
||||||
|
|
||||||
const VERT_SHADER_SRC: &str =
|
const VERT_SHADER_SRC: &str =
|
||||||
"
|
"
|
||||||
#define lowp
|
#define lowp
|
||||||
|
@ -304,7 +282,8 @@ fn main () {
|
||||||
})
|
})
|
||||||
.collect ();
|
.collect ();
|
||||||
|
|
||||||
let texture = ugly_load_texture ("sky.png");
|
let texture = Texture::from_file ("sky.png");
|
||||||
|
texture.bind ();
|
||||||
|
|
||||||
let model_data = load_small_file ("pumpking.iqm");
|
let model_data = load_small_file ("pumpking.iqm");
|
||||||
let model = Model::from_slice (&model_data [..]);
|
let model = Model::from_slice (&model_data [..]);
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
use std::convert::TryInto;
|
||||||
|
use std::ffi::CStr;
|
||||||
|
|
||||||
|
pub struct ShaderObject {
|
||||||
|
id: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ShaderObject {
|
||||||
|
pub fn id (&self) -> u32 {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new (shader_type: u32, source: &str) -> Result <ShaderObject, String>
|
||||||
|
{
|
||||||
|
let id = unsafe {
|
||||||
|
gl::CreateShader (shader_type)
|
||||||
|
};
|
||||||
|
|
||||||
|
let sources = [
|
||||||
|
source.as_ptr () as *const i8,
|
||||||
|
];
|
||||||
|
|
||||||
|
let lengths = [
|
||||||
|
source.len ().try_into ().unwrap (),
|
||||||
|
];
|
||||||
|
|
||||||
|
let success = unsafe {
|
||||||
|
gl::ShaderSource (id, sources.len ().try_into ().unwrap (), sources.as_ptr (), lengths.as_ptr ());
|
||||||
|
gl::CompileShader (id);
|
||||||
|
|
||||||
|
let mut success = 0;
|
||||||
|
gl::GetShaderiv (id, gl::COMPILE_STATUS, &mut success);
|
||||||
|
success == 1
|
||||||
|
};
|
||||||
|
|
||||||
|
if success {
|
||||||
|
Ok (ShaderObject {
|
||||||
|
id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let mut info_log = vec! [0u8; 4096];
|
||||||
|
let mut log_length = 0;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
gl::GetShaderInfoLog (id, (info_log.len () - 1).try_into ().unwrap (), &mut log_length, info_log.as_mut_ptr () as *mut i8);
|
||||||
|
}
|
||||||
|
|
||||||
|
info_log.truncate (log_length.try_into ().unwrap ());
|
||||||
|
|
||||||
|
let info = String::from_utf8 (info_log).unwrap ();
|
||||||
|
|
||||||
|
Err (info)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for ShaderObject {
|
||||||
|
fn drop (&mut self) {
|
||||||
|
unsafe {
|
||||||
|
gl::DeleteShader (self.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ShaderProgram {
|
||||||
|
id: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ShaderProgram {
|
||||||
|
pub fn new (vert: &ShaderObject, frag: &ShaderObject)
|
||||||
|
-> Result <ShaderProgram, String>
|
||||||
|
{
|
||||||
|
let id = unsafe {
|
||||||
|
gl::CreateProgram ()
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
gl::AttachShader (id, vert.id ());
|
||||||
|
gl::AttachShader (id, frag.id ());
|
||||||
|
|
||||||
|
gl::LinkProgram (id);
|
||||||
|
}
|
||||||
|
|
||||||
|
let success = unsafe {
|
||||||
|
let mut success = 0;
|
||||||
|
gl::GetProgramiv (id, gl::LINK_STATUS, &mut success);
|
||||||
|
success == 1
|
||||||
|
};
|
||||||
|
|
||||||
|
if success {
|
||||||
|
Ok (ShaderProgram {
|
||||||
|
id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let mut info_log = vec! [0u8; 4096];
|
||||||
|
let mut log_length = 0;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
gl::GetProgramInfoLog (id, (info_log.len () - 1).try_into ().unwrap (), &mut log_length, info_log.as_mut_ptr () as *mut i8);
|
||||||
|
}
|
||||||
|
|
||||||
|
info_log.truncate (log_length.try_into ().unwrap ());
|
||||||
|
|
||||||
|
let info = String::from_utf8 (info_log).unwrap ();
|
||||||
|
|
||||||
|
Err (info)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_uniform_location (&self, name: &CStr) -> i32 {
|
||||||
|
unsafe {
|
||||||
|
gl::UseProgram (self.id);
|
||||||
|
gl::GetUniformLocation (self.id, name.as_ptr ())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_attribute_location (&self, name: &CStr) -> i32 {
|
||||||
|
unsafe {
|
||||||
|
gl::UseProgram (self.id);
|
||||||
|
gl::GetAttribLocation (self.id, name.as_ptr ())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for ShaderProgram {
|
||||||
|
fn drop (&mut self) {
|
||||||
|
unsafe {
|
||||||
|
gl::DeleteProgram (self.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
use std::convert::TryInto;
|
||||||
|
use std::ffi::c_void;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
pub struct Texture {
|
||||||
|
id: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Texture {
|
||||||
|
pub fn from_file <P> (name: P) -> Texture
|
||||||
|
where P: AsRef <Path>
|
||||||
|
{
|
||||||
|
let decoder = png::Decoder::new (File::open (name).unwrap ());
|
||||||
|
let (info, mut reader) = decoder.read_info ().unwrap ();
|
||||||
|
// Allocate the output buffer.
|
||||||
|
let mut buf = vec! [0; info.buffer_size ()];
|
||||||
|
// Read the next frame. Currently this function should only called once.
|
||||||
|
// The default options
|
||||||
|
reader.next_frame (&mut buf).unwrap ();
|
||||||
|
|
||||||
|
let id = unsafe {
|
||||||
|
let mut id = 0;
|
||||||
|
|
||||||
|
gl::GenTextures (1, &mut id);
|
||||||
|
assert! (id != 0);
|
||||||
|
|
||||||
|
gl::BindTexture (gl::TEXTURE_2D, id);
|
||||||
|
gl::TexImage2D (gl::TEXTURE_2D, 0, gl::RGBA.try_into ().unwrap (), 1024, 1024, 0, gl::RGBA, gl::UNSIGNED_BYTE, &buf [0] as *const u8 as *const c_void);
|
||||||
|
|
||||||
|
gl::TexParameteri (gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as i32);
|
||||||
|
gl::TexParameteri (gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as i32);
|
||||||
|
gl::TexParameteri (gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as i32);
|
||||||
|
gl::TexParameteri (gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as i32);
|
||||||
|
|
||||||
|
id
|
||||||
|
};
|
||||||
|
|
||||||
|
Texture {
|
||||||
|
id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind (&self) {
|
||||||
|
unsafe {
|
||||||
|
gl::BindTexture (gl::TEXTURE_2D, self.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for Texture {
|
||||||
|
fn drop (&mut self)
|
||||||
|
{
|
||||||
|
if self.id == 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
gl::DeleteTextures (1, &mut self.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.id = 0;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue