Changed to SDL instead of glfw
parent
e363da01b5
commit
bcba7739c8
|
@ -11,5 +11,4 @@ image = "0.24.5"
|
||||||
cgmath = "0.18.0"
|
cgmath = "0.18.0"
|
||||||
tobj = "2.0.0"
|
tobj = "2.0.0"
|
||||||
glow = "0.12.1"
|
glow = "0.12.1"
|
||||||
[dependencies.glfw]
|
sdl2 = "0.35.2"
|
||||||
version = "*"
|
|
||||||
|
|
184
src/main.rs
184
src/main.rs
|
@ -1,15 +1,20 @@
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use glfw;
|
//use glfw;
|
||||||
use glfw::{Action, Context, Key};
|
//use glfw::{Action, Context, Key};
|
||||||
use cgmath::{Matrix4, vec3, Point3, Deg, perspective};
|
use cgmath::{Matrix4, vec3, Point3, Deg, perspective};
|
||||||
use cgmath::prelude::*;
|
use cgmath::prelude::*;
|
||||||
use std::rc::Rc;
|
use std::sync::Arc;
|
||||||
const SCR_WIDTH: u32 = 1600;
|
const SCR_WIDTH: u32 = 1600;
|
||||||
const SCR_HEIGHT: u32 = 900;
|
const SCR_HEIGHT: u32 = 900;
|
||||||
const TITLE: &str = "GLFWtest";
|
const TITLE: &str = "GLFWtest";
|
||||||
|
|
||||||
use glow::*;
|
|
||||||
|
|
||||||
|
use glow::*;
|
||||||
|
use sdl2;
|
||||||
|
use sdl2::pixels::Color;
|
||||||
|
|
||||||
|
use sdl2::keyboard::Keycode;
|
||||||
|
use sdl2::event::Event;
|
||||||
use std::sync::mpsc::Receiver;
|
use std::sync::mpsc::Receiver;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
@ -21,27 +26,57 @@ mod model;
|
||||||
mod camera;
|
mod camera;
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
||||||
let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();
|
//let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();
|
||||||
|
|
||||||
glfw.window_hint(glfw::WindowHint::ContextVersion(3, 3));
|
// glfw.window_hint(glfw::WindowHint::ContextVersion(3, 3));
|
||||||
glfw.window_hint(glfw::WindowHint::OpenGlProfile(glfw::OpenGlProfileHint::Core));
|
// glfw.window_hint(glfw::WindowHint::OpenGlProfile(glfw::OpenGlProfileHint::Core));
|
||||||
glfw.window_hint(glfw::WindowHint::OpenGlForwardCompat(true));
|
// glfw.window_hint(glfw::WindowHint::OpenGlForwardCompat(true));
|
||||||
glfw.window_hint(glfw::WindowHint::Resizable(false));
|
// glfw.window_hint(glfw::WindowHint::Resizable(false));
|
||||||
glfw.window_hint(glfw::WindowHint::TransparentFramebuffer(false));
|
// glfw.window_hint(glfw::WindowHint::TransparentFramebuffer(false));
|
||||||
glfw.window_hint(glfw::WindowHint::Decorated(true));
|
// glfw.window_hint(glfw::WindowHint::Decorated(true));
|
||||||
|
|
||||||
let (mut window, events) = glfw.create_window(SCR_WIDTH, SCR_HEIGHT, TITLE, glfw::WindowMode::Windowed).unwrap();
|
// let (mut window, events) = glfw.create_window(SCR_WIDTH, SCR_HEIGHT, TITLE, glfw::WindowMode::Windowed).unwrap();
|
||||||
|
|
||||||
let (screen_width, screen_height) = window.get_framebuffer_size();
|
//let (screen_width, screen_height) = window.get_framebuffer_size();
|
||||||
|
|
||||||
|
|
||||||
window.make_current();
|
let (gl, shader_version, window, mut events_loop, _context) = {
|
||||||
window.set_key_polling(true);
|
let sdl = match sdl2::init()
|
||||||
window.set_framebuffer_size_polling(true);
|
{
|
||||||
window.set_cursor_pos_polling(true);
|
Ok(sdl) => sdl,
|
||||||
window.set_cursor_mode(glfw::CursorMode::Disabled);
|
Err(s) => panic!("Error with Initializing SDL: {}", s),
|
||||||
|
};
|
||||||
|
let video = sdl.video().unwrap();
|
||||||
|
let gl_attr = video.gl_attr();
|
||||||
|
gl_attr.set_context_profile(sdl2::video::GLProfile::Core);
|
||||||
|
gl_attr.set_context_version(3, 3);
|
||||||
|
let window = match video
|
||||||
|
.window("DairyTest", SCR_WIDTH, SCR_HEIGHT)
|
||||||
|
.opengl()
|
||||||
|
.resizable()
|
||||||
|
.build() {
|
||||||
|
Ok(ret) => ret,
|
||||||
|
Err(s) => panic!("Error with Initializing SDL Window: {}", s),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
let gl_context = match window.gl_create_context()
|
||||||
|
{
|
||||||
|
Ok(ret) => ret,
|
||||||
|
Err(s) => panic!("Error with Initializing SDL Context: {}", s)
|
||||||
|
};
|
||||||
|
let gl = std::sync::Arc::new(unsafe{glow::Context::from_loader_function(|s| video.gl_get_proc_address(s) as *const _)});
|
||||||
|
|
||||||
|
let event_loop = match sdl.event_pump()
|
||||||
|
{
|
||||||
|
Ok(ret) => ret,
|
||||||
|
Err(s) => panic!("Error with Initializing SDL Event Loop: {}", s)
|
||||||
|
};
|
||||||
|
(gl, "#version 330", window, event_loop, gl_context)
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
let mut camera = camera::Camera {
|
let mut camera = camera::Camera {
|
||||||
Position: Point3::new(0.0, 0.40, 1.0),
|
Position: Point3::new(0.0, 0.40, 1.0),
|
||||||
Pitch: -20.0,
|
Pitch: -20.0,
|
||||||
|
@ -57,114 +92,59 @@ fn main() {
|
||||||
let mut lastFrame: f32 = 0.0;
|
let mut lastFrame: f32 = 0.0;
|
||||||
|
|
||||||
//gl::load_with(|ptr| window.get_proc_address(ptr) as *const _);
|
//gl::load_with(|ptr| window.get_proc_address(ptr) as *const _);
|
||||||
let gl = std::rc::Rc::new(unsafe{glow::Context::from_loader_function(|s| window.get_proc_address(s) as *const _)});
|
|
||||||
let (ourshader, ourModel) = unsafe {
|
let (ourshader, ourModel) = unsafe {
|
||||||
gl.enable(glow::DEPTH_TEST);
|
gl.enable(glow::DEPTH_TEST);
|
||||||
|
|
||||||
let ourShader = shader::shader::new("model", Rc::clone(&gl));
|
let ourShader = shader::shader::new("model", Arc::clone(&gl));
|
||||||
|
|
||||||
let ourModel = model::Model::new("resources/models/TestCarModel/CarW4.obj", Rc::clone(&gl));
|
let ourModel = model::Model::new("resources/models/TestCarModel/CarW4.obj", Arc::clone(&gl));
|
||||||
|
|
||||||
(ourShader, ourModel)
|
(ourShader, ourModel)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
let time = std::time::Instant::now();
|
||||||
|
|
||||||
let projection: Matrix4<f32> = perspective(Deg(45.0), SCR_WIDTH as f32/ SCR_HEIGHT as f32, 0.1, 100.0);
|
let projection: Matrix4<f32> = perspective(Deg(45.0), SCR_WIDTH as f32/ SCR_HEIGHT as f32, 0.1, 100.0);
|
||||||
println!("entering main loop");
|
println!("entering main loop");
|
||||||
|
// NOTE main loop here
|
||||||
while !window.should_close() {
|
'running: loop {
|
||||||
let currentFrame = glfw.get_time() as f32;
|
let currentFrame = time.elapsed().as_secs_f32();
|
||||||
deltaTime = currentFrame - lastFrame;
|
deltaTime = currentFrame - lastFrame;
|
||||||
lastFrame = currentFrame;
|
lastFrame = currentFrame;
|
||||||
|
|
||||||
processInput(&mut window, deltaTime, &mut camera);
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
gl.enable(glow::DEPTH_TEST);
|
|
||||||
gl.clear(glow::COLOR_BUFFER_BIT | glow::DEPTH_BUFFER_BIT);
|
|
||||||
|
|
||||||
// outline
|
|
||||||
|
|
||||||
ourshader.Use();
|
|
||||||
let Projection: Matrix4<f32> = perspective(Deg(camera.Zoom), SCR_WIDTH as f32 / SCR_HEIGHT as f32, 0.1, 100.0);
|
|
||||||
let view = camera.GetViewMatrix();
|
|
||||||
ourshader.setMat4("projection", &projection);
|
|
||||||
ourshader.setMat4("view", &view);
|
|
||||||
|
|
||||||
|
|
||||||
//let mut model = Matrix4::<f32>::from_translation(vec3(0.0, -0.3, 0.0));
|
unsafe{
|
||||||
let mut model: Matrix4<f32> = Matrix4::from_axis_angle(vec3(0.0, -1.0, 0.0).normalize(),
|
gl.enable(glow::DEPTH_TEST);
|
||||||
cgmath::Rad(glfw.get_time() as f32));
|
gl.clear(glow::COLOR_BUFFER_BIT | glow::DEPTH_BUFFER_BIT);
|
||||||
model = model * Matrix4::from_scale(0.2);
|
|
||||||
ourshader.setMat4("model", &model);
|
|
||||||
|
|
||||||
ourModel.Draw(&ourshader);
|
ourshader.Use();
|
||||||
|
let Projection: Matrix4<f32> = perspective(Deg(camera.Zoom), SCR_WIDTH as f32 / SCR_HEIGHT as f32, 0.1, 100.0);
|
||||||
|
|
||||||
}
|
let view = camera.GetViewMatrix();
|
||||||
|
ourshader.setMat4("projection", &projection);
|
||||||
|
ourshader.setMat4("view", &view);
|
||||||
|
|
||||||
|
|
||||||
window.swap_buffers();
|
let mut model: Matrix4<f32> = Matrix4::from_axis_angle(vec3(0.0, -1.0, 0.0).normalize(),
|
||||||
glfw.poll_events();
|
cgmath::Rad(time.elapsed().as_secs_f32()));
|
||||||
}
|
model = model * Matrix4::from_scale(0.2);
|
||||||
}
|
ourshader.setMat4("model", &model);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fn processInput(window: &mut glfw::Window, deltaTime: f32, camera: &mut camera::Camera) {
|
|
||||||
if window.get_key(Key::Escape) == Action::Press {
|
|
||||||
window.set_should_close(true)
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
if window.get_key(Key::W) == Action::Press {
|
|
||||||
camera.ProcessKeyboard(camera::Camera_Movement::FORWARD, deltaTime);
|
|
||||||
}
|
|
||||||
if window.get_key(Key::S) == Action::Press {
|
|
||||||
camera.ProcessKeyboard(camera::Camera_Movement::BACKWARD, deltaTime);
|
|
||||||
}
|
|
||||||
if window.get_key(Key::A) == Action::Press {
|
|
||||||
camera.ProcessKeyboard(camera::Camera_Movement::LEFT, deltaTime);
|
|
||||||
}
|
|
||||||
if window.get_key(Key::D) == Action::Press {
|
|
||||||
camera.ProcessKeyboard(camera::Camera_Movement::RIGHT, deltaTime);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
fn process_events(events: &Receiver<(f64, glfw::WindowEvent)>,
|
|
||||||
firstMouse: &mut bool,
|
|
||||||
lastX: &mut f32,
|
|
||||||
lastY: &mut f32,
|
|
||||||
camera: &mut camera::Camera) {
|
|
||||||
for (_, event) in glfw::flush_messages(events) {
|
|
||||||
match event {
|
|
||||||
glfw::WindowEvent::FramebufferSize(width, height) => {
|
|
||||||
// make sure the viewport matches the new window dimensions; note that width and
|
|
||||||
// height will be significantly larger than specified on retina displays.
|
|
||||||
unsafe { gl.viewport(0, 0, width, height) }
|
|
||||||
}
|
}
|
||||||
glfw::WindowEvent::CursorPos(xpos, ypos) => {
|
ourModel.Draw(&ourshader);
|
||||||
let (xpos, ypos) = (xpos as f32, ypos as f32);
|
|
||||||
if *firstMouse {
|
|
||||||
*lastX = xpos;
|
|
||||||
*lastY = ypos;
|
|
||||||
*firstMouse = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let xoffset = xpos - *lastX;
|
window.gl_swap_window();
|
||||||
let yoffset = *lastY - ypos; // reversed since y-coordinates go from bottom to top
|
for event in events_loop.poll_iter() {
|
||||||
|
|
||||||
*lastX = xpos;
|
|
||||||
*lastY = ypos;
|
|
||||||
|
|
||||||
camera.ProcessMouseMovement(xoffset, yoffset, true);
|
match event {
|
||||||
|
Event::Quit {..} |
|
||||||
|
Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
|
||||||
|
break 'running
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
glfw::WindowEvent::Scroll(_xoffset, yoffset) => {
|
|
||||||
camera.ProcessMouseScroll(yoffset as f32);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
22
src/model.rs
22
src/model.rs
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
use std::os::raw::c_void;
|
use std::os::raw::c_void;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::rc::Rc;
|
use std::sync::Arc;
|
||||||
use cgmath::{vec2, vec3};
|
use cgmath::{vec2, vec3};
|
||||||
use image;
|
use image;
|
||||||
use glow::*;
|
use glow::*;
|
||||||
|
@ -24,9 +24,9 @@ pub struct Model {
|
||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
/// constructor, expects a filepath to a 3D model.
|
/// constructor, expects a filepath to a 3D model.
|
||||||
pub fn new(path: &str, gl: std::rc::Rc<glow::Context>) -> Model {
|
pub fn new(path: &str, gl: std::sync::Arc<glow::Context>) -> Model {
|
||||||
let mut model = Model::default();
|
let mut model = Model::default();
|
||||||
model.loadModel(path, Rc::clone(&gl));
|
model.loadModel(path, Arc::clone(&gl));
|
||||||
model
|
model
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ impl Model {
|
||||||
}
|
}
|
||||||
|
|
||||||
// loads a model from file and stores the resulting meshes in the meshes vector.
|
// loads a model from file and stores the resulting meshes in the meshes vector.
|
||||||
fn loadModel(&mut self, path: &str, gl: std::rc::Rc<glow::Context>) {
|
fn loadModel(&mut self, path: &str, gl: Arc<glow::Context>) {
|
||||||
let path = Path::new(path);
|
let path = Path::new(path);
|
||||||
|
|
||||||
// retrieve the directory path of the filepath
|
// retrieve the directory path of the filepath
|
||||||
|
@ -71,28 +71,28 @@ impl Model {
|
||||||
|
|
||||||
// 1. diffuse map
|
// 1. diffuse map
|
||||||
if !material.diffuse_texture.is_empty() {
|
if !material.diffuse_texture.is_empty() {
|
||||||
let texture = self.loadMaterialTexture(&material.diffuse_texture, "texture_diffuse", Rc::clone(&gl));
|
let texture = self.loadMaterialTexture(&material.diffuse_texture, "texture_diffuse", Arc::clone(&gl));
|
||||||
textures.push(texture);
|
textures.push(texture);
|
||||||
}
|
}
|
||||||
// 2. specular map
|
// 2. specular map
|
||||||
if !material.specular_texture.is_empty() {
|
if !material.specular_texture.is_empty() {
|
||||||
let texture = self.loadMaterialTexture(&material.specular_texture, "texture_specular", Rc::clone(&gl));
|
let texture = self.loadMaterialTexture(&material.specular_texture, "texture_specular", Arc::clone(&gl));
|
||||||
textures.push(texture);
|
textures.push(texture);
|
||||||
}
|
}
|
||||||
// 3. normal map
|
// 3. normal map
|
||||||
if !material.normal_texture.is_empty() {
|
if !material.normal_texture.is_empty() {
|
||||||
let texture = self.loadMaterialTexture(&material.normal_texture, "texture_normal", Rc::clone(&gl));
|
let texture = self.loadMaterialTexture(&material.normal_texture, "texture_normal", Arc::clone(&gl));
|
||||||
textures.push(texture);
|
textures.push(texture);
|
||||||
}
|
}
|
||||||
// NOTE: no height maps
|
// NOTE: no height maps
|
||||||
}
|
}
|
||||||
|
|
||||||
self.meshes.push(Mesh::new(vertices, indices, textures, Rc::clone(&gl)));
|
self.meshes.push(Mesh::new(vertices, indices, textures, Arc::clone(&gl)));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn loadMaterialTexture(&mut self, path: &str, typeName: &str, gl: Rc<glow::Context>) -> Texture {
|
fn loadMaterialTexture(&mut self, path: &str, typeName: &str, gl: Arc<glow::Context>) -> Texture {
|
||||||
{
|
{
|
||||||
let texture = self.textures_loaded.iter().find(|t| t.path == path);
|
let texture = self.textures_loaded.iter().find(|t| t.path == path);
|
||||||
if let Some(texture) = texture {
|
if let Some(texture) = texture {
|
||||||
|
@ -101,7 +101,7 @@ impl Model {
|
||||||
}
|
}
|
||||||
|
|
||||||
let texture = Texture {
|
let texture = Texture {
|
||||||
id: unsafe { TextureFromFile(path, &self.directory, std::rc::Rc::clone(&gl)) },
|
id: unsafe { TextureFromFile(path, &self.directory, Arc::clone(&gl)) },
|
||||||
type_: typeName.into(),
|
type_: typeName.into(),
|
||||||
path: path.into()
|
path: path.into()
|
||||||
};
|
};
|
||||||
|
@ -110,7 +110,7 @@ impl Model {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn TextureFromFile(path: &str, directory: &str, gl: Rc<glow::Context>) -> glow::NativeTexture {
|
unsafe fn TextureFromFile(path: &str, directory: &str, gl: Arc<glow::Context>) -> glow::NativeTexture {
|
||||||
let filename = format!("{}/{}", directory, path);
|
let filename = format!("{}/{}", directory, path);
|
||||||
|
|
||||||
let mut textureID = gl.create_texture().unwrap();
|
let mut textureID = gl.create_texture().unwrap();
|
||||||
|
|
|
@ -61,7 +61,7 @@ pub struct Mesh {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mesh {
|
impl Mesh {
|
||||||
pub fn new(vertices: Vec<Vertex>, indices: Vec<u32>, textures: Vec<Texture>,gl: std::rc::Rc<glow::Context>) -> Mesh {
|
pub fn new(vertices: Vec<Vertex>, indices: Vec<u32>, textures: Vec<Texture>,gl: std::sync::Arc<glow::Context>) -> Mesh {
|
||||||
|
|
||||||
let mut mesh =
|
let mut mesh =
|
||||||
{
|
{
|
||||||
|
@ -124,7 +124,7 @@ impl Mesh {
|
||||||
shader.gl.active_texture(glow::TEXTURE0);
|
shader.gl.active_texture(glow::TEXTURE0);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn setupMesh(&mut self, gl: std::rc::Rc<glow::Context>) {
|
unsafe fn setupMesh(&mut self, gl: std::sync::Arc<glow::Context>) {
|
||||||
|
|
||||||
self.VAO = Some(gl.create_vertex_array().unwrap());
|
self.VAO = Some(gl.create_vertex_array().unwrap());
|
||||||
self.VBO = Some(gl.create_buffer().unwrap());
|
self.VBO = Some(gl.create_buffer().unwrap());
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
|
|
||||||
use glow::*;
|
use glow::*;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::rc::Rc;
|
use std::sync::Arc;
|
||||||
use std::str;
|
use std::str;
|
||||||
/// Shader Struct for creating and using shaders in the Context of engine
|
/// Shader Struct for creating and using shaders in the Context of engine
|
||||||
///
|
///
|
||||||
pub struct shader {
|
pub struct shader {
|
||||||
|
|
||||||
pub ID: NativeProgram,
|
pub ID: NativeProgram,
|
||||||
pub gl: Rc<glow::Context>
|
pub gl: Arc<glow::Context>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ use std::str;
|
||||||
/// `new(String::from("Example"))`
|
/// `new(String::from("Example"))`
|
||||||
/// if the String given was "Example" the Program expects both shaders to be in the directory "resources/shaders/Example/"
|
/// if the String given was "Example" the Program expects both shaders to be in the directory "resources/shaders/Example/"
|
||||||
/// with the vertex shader being called "shader.vert" and fragment "shader.frag"
|
/// with the vertex shader being called "shader.vert" and fragment "shader.frag"
|
||||||
pub fn new(path: &str, gl: Rc<glow::Context>) -> shader
|
pub fn new(path: &str, gl: Arc<glow::Context>) -> shader
|
||||||
{
|
{
|
||||||
//read file contents
|
//read file contents
|
||||||
let VERT_SHADER = fs::read_to_string(format!("resources/shaders/{path}/shader.vert")).unwrap();
|
let VERT_SHADER = fs::read_to_string(format!("resources/shaders/{path}/shader.vert")).unwrap();
|
||||||
|
@ -58,7 +58,7 @@ use std::str;
|
||||||
|
|
||||||
shader {
|
shader {
|
||||||
ID: shader_program,
|
ID: shader_program,
|
||||||
gl: Rc::clone(&gl),
|
gl: Arc::clone(&gl),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue