Advertisement
Guest User

lib.rs

a guest
Jan 14th, 2018
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 8.82 KB | None | 0 0
  1. #![allow(non_upper_case_globals)]
  2. #![allow(non_snake_case)]
  3.  
  4. extern crate gl;
  5. extern crate image;
  6. extern crate cgmath;
  7. extern crate tobj;
  8. extern crate libc;
  9.  
  10. mod common;
  11. mod shader;
  12. mod macros;
  13. mod camera;
  14. mod mesh;
  15. mod model;
  16. mod utils;
  17.  
  18. extern crate rand;
  19. use self::rand::Rng;
  20.  
  21. use std::process;
  22. use std::io::{self, Write};
  23. use std::ffi;
  24. use std::ffi::CStr;
  25. use std::mem;
  26. use std::os::raw::c_void;
  27. use std::ptr;
  28. use libc::{RTLD_NOW};
  29. use std::collections::HashMap;
  30. use std::sync::Mutex;
  31. #[macro_use]
  32. extern crate lazy_static;
  33.  
  34. use shader::Shader;
  35. use camera::Camera;
  36. use model::Model;
  37.  
  38. use cgmath::{Matrix4, vec3, Point3, Vector4, Deg, perspective};
  39. use cgmath::prelude::*;
  40.  
  41. struct Tab {
  42.     bufferHandle: u32,
  43. }
  44.  
  45. lazy_static! {
  46.     static ref tabs: Mutex<HashMap<usize, Tab>> = {
  47.         Mutex::new(HashMap::new())
  48.     };
  49. }
  50.  
  51. // settings
  52. const SCR_WIDTH: u32 = 1280;
  53. const SCR_HEIGHT: u32 = 720;
  54.  
  55. static mut oAsteroidShader: std::option::Option<Shader> = None;
  56. static mut oPlanetShader: std::option::Option<Shader> = None;
  57. static mut oRock: std::option::Option<Model> = None;
  58. static mut oPlanet: std::option::Option<Model> = None;
  59. static mut amount: usize = 100000;
  60.  
  61. #[no_mangle]
  62. pub extern "C" fn init() {
  63.     // gl: load all OpenGL function pointers
  64.     // ---------------------------------------
  65.     unsafe {
  66.         let handle = libc::dlopen(ffi::CStr::from_bytes_with_nul_unchecked("libGL.so.1\0".as_bytes()).as_ptr(), RTLD_NOW);
  67.         if handle.is_null () {
  68.             writeln!(&mut io::stderr(), "{}", ffi::CStr::from_ptr(libc::dlerror()).to_string_lossy().as_ref()).unwrap();
  69.             process::exit(1);
  70.         }
  71.        
  72.         gl::load_with(|symbol| libc::dlsym (handle, ffi::CString::new (symbol).unwrap().as_ptr()) as *const _);
  73.     }
  74.  
  75.     unsafe {
  76.         // configure global opengl state
  77.         // -----------------------------
  78.         gl::Enable(gl::DEPTH_TEST);
  79.  
  80.         // build and compile shaders
  81.         // -------------------------
  82.         oAsteroidShader = Some(Shader::new(
  83.             "resources/shaders/10.3.asteroids.vs",
  84.             "resources/shaders/10.3.asteroids.fs"));
  85.         oPlanetShader = Some(Shader::new(
  86.             "resources/shaders/10.3.planet.vs",
  87.             "resources/shaders/10.3.planet.fs"));
  88.  
  89.         // load models
  90.         // -----------
  91.         oRock = Some(Model::new("resources/objects/rock/rock.obj"));
  92.         oPlanet = Some(Model::new("resources/objects/planet/planet.obj"));
  93.     }
  94. }
  95.  
  96. #[no_mangle]
  97. pub unsafe extern "C" fn set_tab_seed(tabID: usize, seed: usize) {
  98.     let borrowedTabs = tabs.lock ().unwrap ();
  99.     let tab = borrowedTabs.get (&tabID).unwrap ();
  100.     gl::BindBuffer(gl::ARRAY_BUFFER, tab.bufferHandle);
  101.    
  102.     // generate a large list of semi-random model transformation matrices
  103.     // ------------------------------------------------------------------
  104.     let mut modelMatrices: Vec<Matrix4<f32>> = Vec::with_capacity(amount);
  105.     let mut rng: rand::StdRng = rand::SeedableRng::from_seed(&[seed][..]);
  106.     let radius = 150.0;
  107.     let offset: f32 = 25.0;
  108.     for i in 0..amount {
  109.         let angle = i as i32 as f32 / amount as f32 * 360.0;
  110.         let mut displacement = (rng.gen::<i32>() % (2.0 * offset * 100.0) as i32) as f32 / 100.0 - offset;
  111.         let x = angle.sin() * radius + displacement;
  112.         displacement = (rng.gen::<i32>() % (2.0 * offset * 100.0) as i32) as f32 / 100.0 - offset;
  113.         let y = displacement * 0.4; // keep height of asteroid field smaller compared to width of x and z
  114.         displacement = (rng.gen::<i32>() % (2.0 * offset * 100.0) as i32) as f32 / 100.0 - offset;
  115.         let z = angle.cos() * radius + displacement;
  116.         let mut model = Matrix4::<f32>::from_translation(vec3(x, y, z));
  117.  
  118.         // 2. scale: Scale between 0.05 and 0.25
  119.         let scale = (rng.gen::<i32>() % 20) as f32 / 100.0 + 0.05;
  120.         model = model * Matrix4::from_scale(scale);
  121.  
  122.         // 3. rotation: add random rotation around a (semi)randomly picked rotation axis vector
  123.         let rotAngle = (rng.gen::<i32>() % 360) as f32;
  124.         model = model * Matrix4::from_axis_angle(vec3(0.4, 0.6, 0.8).normalize(), Deg(rotAngle));
  125.  
  126.         // 4. now add to list of matrices
  127.         modelMatrices.push(model);
  128.     }
  129.  
  130.     // configure instanced array
  131.     // -------------------------
  132.     gl::BufferData(
  133.         gl::ARRAY_BUFFER,
  134.         (amount * mem::size_of::<Matrix4<f32>>()) as isize,
  135.         &modelMatrices[0] as *const Matrix4<f32> as *const c_void,
  136.         gl::STATIC_DRAW);
  137. }
  138.  
  139. #[no_mangle]
  140. pub unsafe extern "C" fn create_tab(tabID: usize) {
  141.     let mut buffer = 0;
  142.     gl::GenBuffers(1, &mut buffer);
  143.  
  144.     let mut borrowedTabs = tabs.lock ().unwrap ();
  145.     borrowedTabs.insert (tabID, Tab {bufferHandle: buffer});
  146. }
  147.  
  148. #[no_mangle]
  149. pub unsafe extern "C" fn close_tab(tabID: usize) {
  150.     let mut borrowedTabs = tabs.lock ().unwrap ();
  151.     {
  152.         let tab = borrowedTabs.get_mut (&tabID).unwrap ();
  153.         gl::DeleteBuffers (1, &tab.bufferHandle);
  154.     }
  155.     borrowedTabs.remove (&tabID);
  156. }
  157.  
  158. #[no_mangle]
  159. pub unsafe extern "C" fn switch_to_tab(tabID: usize) {
  160.     let borrowedTabs = tabs.lock ().unwrap ();
  161.     let tab = borrowedTabs.get (&tabID).unwrap ();
  162.     gl::BindBuffer(gl::ARRAY_BUFFER, tab.bufferHandle);
  163.    
  164.     let rock = match oRock {
  165.         Some (ref mut x) => &mut *x,
  166.         None => panic!(),
  167.     };
  168.  
  169.     // set transformation matrices as an instance vertex attribute (with divisor 1)
  170.     // note: we're cheating a little by taking the, now publicly declared, VAO of the model's mesh(es) and adding new vertexAttribPointers
  171.     // normally you'd want to do this in a more organized fashion, but for learning purposes this will do.
  172.     // -----------------------------------------------------------------------------------------------------------------------------------
  173.     let size_mat4 = mem::size_of::<Matrix4<f32>>() as i32;
  174.     let size_vec4 = mem::size_of::<Vector4<f32>>() as i32;
  175.     for mesh in &rock.meshes {
  176.         let VAO = mesh.VAO;
  177.         gl::BindVertexArray(VAO);
  178.         // set attribute pointers for matrix (4 times vec4)
  179.         gl::EnableVertexAttribArray(3);
  180.         gl::VertexAttribPointer(3, 4, gl::FLOAT, gl::FALSE, size_mat4, ptr::null());
  181.         gl::EnableVertexAttribArray(4);
  182.         gl::VertexAttribPointer(4, 4, gl::FLOAT, gl::FALSE, size_mat4, size_vec4 as *const c_void);
  183.         gl::EnableVertexAttribArray(5);
  184.         gl::VertexAttribPointer(5, 4, gl::FLOAT, gl::FALSE, size_mat4, (2 * size_vec4) as *const c_void);
  185.         gl::EnableVertexAttribArray(6);
  186.         gl::VertexAttribPointer(6, 4, gl::FLOAT, gl::FALSE, size_mat4, (3 * size_vec4) as *const c_void);
  187.  
  188.         gl::VertexAttribDivisor(3, 1);
  189.         gl::VertexAttribDivisor(4, 1);
  190.         gl::VertexAttribDivisor(5, 1);
  191.         gl::VertexAttribDivisor(6, 1);
  192.  
  193.         gl::BindVertexArray(0);
  194.     }
  195. }
  196.  
  197. #[no_mangle]
  198. pub unsafe extern "C" fn render() {
  199.     let camera = Camera {
  200.         Position: Point3::new(0.0, 0.0, 155.0),
  201.         ..Camera::default()
  202.     };
  203.  
  204.     gl::ClearColor(0.1, 0.1, 0.1, 1.0);
  205.     gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
  206.  
  207.     // configure transformation matrices
  208.     let projection: Matrix4<f32> = perspective(Deg(45.0), SCR_WIDTH as f32 / SCR_HEIGHT as f32, 0.1, 1000.0);
  209.     let view = camera.GetViewMatrix();
  210.  
  211.     let asteroidShader = match oAsteroidShader {
  212.         Some (ref mut x) => &mut *x,
  213.         None => panic!(),
  214.     };
  215.     let planetShader = match oPlanetShader {
  216.         Some (ref mut x) => &mut *x,
  217.         None => panic!(),
  218.     };
  219.     let rock = match oRock {
  220.         Some (ref mut x) => &mut *x,
  221.         None => panic!(),
  222.     };
  223.     let planet = match oPlanet {
  224.         Some (ref mut x) => &mut *x,
  225.         None => panic!(),
  226.     };
  227.    
  228.     asteroidShader.useProgram();
  229.     asteroidShader.setMat4(c_str!("projection"), &projection);
  230.     asteroidShader.setMat4(c_str!("view"), &view);
  231.     planetShader.useProgram();
  232.     planetShader.setMat4(c_str!("projection"), &projection);
  233.     planetShader.setMat4(c_str!("view"), &view);
  234.  
  235.     // draw planet
  236.     let mut model = Matrix4::<f32>::from_translation(vec3(0.0, -3.0, 0.0));
  237.     model = model * Matrix4::from_scale(4.0);
  238.     planetShader.setMat4(c_str!("model"), &model);
  239.     planet.Draw(&planetShader);
  240.  
  241.     // draw meteorites
  242.     asteroidShader.useProgram();
  243.     asteroidShader.setInt(c_str!("texture_diffuse1"), 0);
  244.     gl::ActiveTexture(gl::TEXTURE0);
  245.     gl::BindTexture(gl::TEXTURE_2D, rock.textures_loaded[0].id); // note: we also made the textures_loaded vector public (instead of private) from the model class.
  246.  
  247.     for mesh in &rock.meshes {
  248.         gl::BindVertexArray(mesh.VAO);
  249.         gl::DrawElementsInstanced(gl::TRIANGLES, mesh.indices.len() as i32, gl::UNSIGNED_INT, ptr::null(), amount as i32);
  250.         gl::BindVertexArray(0);
  251.     }
  252. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement