This commit is contained in:
Piotr 2020-09-26 18:38:39 +02:00
parent f0a510d2a1
commit 3c884ed3f0
6 changed files with 196 additions and 12 deletions

View File

@ -0,0 +1,11 @@
#version 330 core
out vec4 FragColor;
in vec3 TexCoords;
uniform samplerCube skybox;
void main()
{
FragColor = texture(skybox, TexCoords);
}

View File

@ -0,0 +1,14 @@
#version 330 core
layout (location = 0) in vec3 aPos;
out vec3 TexCoords;
uniform mat4 projection;
uniform mat4 view;
void main()
{
TexCoords = aPos;
vec4 pos = projection * view * vec4(aPos, 1.0);
gl_Position = pos.xyww;
}

View File

@ -4,6 +4,7 @@ use crate::gaia::client::Client;
use crate::gaia::components::{ModelComponent, Transform}; use crate::gaia::components::{ModelComponent, Transform};
use crate::gaia::consts; use crate::gaia::consts;
use crate::gaia::engine::Engine; use crate::gaia::engine::Engine;
use crate::gaia::sky::Sky;
use crate::gaia::*; use crate::gaia::*;
use cgmath::{perspective, vec3, Deg, Matrix4, Point3}; use cgmath::{perspective, vec3, Deg, Matrix4, Point3};
use imgui_glfw_rs::glfw; use imgui_glfw_rs::glfw;
@ -12,6 +13,7 @@ pub struct ExampleClient {
models: Vec<ModelComponent>, models: Vec<ModelComponent>,
camera: Camera, camera: Camera,
shader: shader::Shader, shader: shader::Shader,
sky: Sky,
show_object_info: bool, show_object_info: bool,
show_camera_info: bool, show_camera_info: bool,
object_info_id: i32, object_info_id: i32,
@ -19,6 +21,10 @@ pub struct ExampleClient {
impl ExampleClient { impl ExampleClient {
pub fn create() -> ExampleClient { pub fn create() -> ExampleClient {
let sky;
unsafe {
sky = Sky::new();
}
ExampleClient { ExampleClient {
object_info_id: 0, object_info_id: 0,
show_camera_info: true, show_camera_info: true,
@ -37,6 +43,7 @@ impl ExampleClient {
"resources/shaders/model_loading.vs", "resources/shaders/model_loading.vs",
"resources/shaders/model_loading.fs", "resources/shaders/model_loading.fs",
), ),
sky: sky,
} }
} }
} }
@ -60,10 +67,7 @@ impl Client for ExampleClient {
scale: vec3(2.5, 2.5, 2.5), scale: vec3(2.5, 2.5, 2.5),
..Transform::default() ..Transform::default()
}, },
model: cache.get_model_ext( model: cache.get_model_ext("resources/objects/tree/tree_6_d.obj", Some("tree_e.png")),
"resources/objects/tree/tree_6_d.obj",
Some("tree_e.png")
),
}; };
let tree2 = ModelComponent { let tree2 = ModelComponent {
transform: Transform { transform: Transform {
@ -71,10 +75,7 @@ impl Client for ExampleClient {
scale: vec3(2.5, 2.5, 2.5), scale: vec3(2.5, 2.5, 2.5),
..Transform::default() ..Transform::default()
}, },
model: cache.get_model_ext( model: cache.get_model_ext("resources/objects/tree/tree_6_c.obj", Some("tree_e.png")),
"resources/objects/tree/tree_6_c.obj",
Some("tree_e.png")
),
}; };
let tree3 = ModelComponent { let tree3 = ModelComponent {
transform: Transform { transform: Transform {
@ -82,10 +83,7 @@ impl Client for ExampleClient {
scale: vec3(2.5, 2.5, 2.5), scale: vec3(2.5, 2.5, 2.5),
..Transform::default() ..Transform::default()
}, },
model: cache.get_model_ext( model: cache.get_model_ext("resources/objects/tree/tree_6_c.obj", Some("tree_e.png")),
"resources/objects/tree/tree_6_c.obj",
Some("tree_e.png")
),
}; };
self.models = vec![tree, tree2, tree3, ground, robot]; self.models = vec![tree, tree2, tree3, ground, robot];
} }
@ -107,6 +105,7 @@ impl Client for ExampleClient {
for model in self.models.iter() { for model in self.models.iter() {
model.draw(&self.shader); model.draw(&self.shader);
} }
self.sky.draw(view, projection);
} }
fn update(&mut self, _engine: &mut Engine) {} fn update(&mut self, _engine: &mut Engine) {}

View File

@ -10,4 +10,5 @@ pub mod engine;
pub mod mesh; pub mod mesh;
pub mod model; pub mod model;
pub mod shader; pub mod shader;
pub mod sky;
pub mod utils; pub mod utils;

95
src/gaia/sky.rs Normal file
View File

@ -0,0 +1,95 @@
use crate::gaia::camera::*;
use crate::gaia::shader::*;
use crate::gaia::utils::*;
use cgmath::Matrix4;
use gl::types::*;
use std::mem;
use std::os::raw::c_void;
use std::ptr;
pub struct Sky {
shader: Shader,
texture_id: u32,
vao: u32,
vbo: u32,
}
impl Drop for Sky {
fn drop(&mut self) {
unsafe {
gl::DeleteVertexArrays(1, &self.vao);
gl::DeleteBuffers(1, &self.vbo);
}
}
}
impl Sky {
pub unsafe fn new() -> Sky {
let shader =
Shader::from_file("resources/shaders/skybox.vs", "resources/shaders/skybox.fs");
let skybox_vertices: [f32; 108] = [
// positions
-1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0,
-1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0,
-1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0,
1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0,
-1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0,
];
// skybox VAO
let (mut skybox_vao, mut skybox_vbo) = (0, 0);
gl::GenVertexArrays(1, &mut skybox_vao);
gl::GenBuffers(1, &mut skybox_vbo);
gl::BindVertexArray(skybox_vao);
gl::BindBuffer(gl::ARRAY_BUFFER, skybox_vbo);
gl::BufferData(
gl::ARRAY_BUFFER,
(skybox_vertices.len() * mem::size_of::<GLfloat>()) as GLsizeiptr,
&skybox_vertices[0] as *const f32 as *const c_void,
gl::STATIC_DRAW,
);
gl::EnableVertexAttribArray(0);
let stride = 3 * mem::size_of::<GLfloat>() as GLsizei;
gl::VertexAttribPointer(0, 3, gl::FLOAT, gl::FALSE, stride, ptr::null());
let faces = [
"resources/textures/skybox/right.jpg",
"resources/textures/skybox/left.jpg",
"resources/textures/skybox/top.jpg",
"resources/textures/skybox/bottom.jpg",
"resources/textures/skybox/back.jpg",
"resources/textures/skybox/front.jpg",
];
let cubemap_texture = load_cubemap(&faces);
shader.use_program();
shader.setInt(c_str!("skybox"), 0);
Sky {
shader: shader,
texture_id: cubemap_texture,
vao: skybox_vao,
vbo: skybox_vbo,
}
}
pub unsafe fn draw(&mut self, mut view: Matrix4<f32>, projection: Matrix4<f32>) {
gl::DepthFunc(gl::LEQUAL); // change depth function so depth test passes when values are equal to depth buffer's content
self.shader.use_program();
// remove translation from the view matrix
view.w[0] = 0.0;
view.w[1] = 0.0;
view.w[2] = 0.0;
self.shader.set_mat4(c_str!("view"), &view);
self.shader.set_mat4(c_str!("projection"), &projection);
// skybox cube
gl::BindVertexArray(self.vao);
gl::ActiveTexture(gl::TEXTURE0);
gl::BindTexture(gl::TEXTURE_CUBE_MAP, self.texture_id);
gl::DrawArrays(gl::TRIANGLES, 0, 36);
gl::BindVertexArray(0);
gl::DepthFunc(gl::LESS); // set depth function back to default
}
}

View File

@ -61,3 +61,67 @@ pub unsafe fn load_texture_from_dir(filename: &str, directory: &str) -> u32 {
load_texture(&fullpath, format) load_texture(&fullpath, format)
} }
/// loads a cubemap texture from 6 individual texture faces
/// order:
/// +X (right)
/// -X (left)
/// +Y (top)
/// -Y (bottom)
/// +Z (front)
/// -Z (back)
/// -------------------------------------------------------
pub unsafe fn load_cubemap(faces: &[&str]) -> u32 {
let mut texture_id = 0;
gl::GenTextures(1, &mut texture_id);
gl::BindTexture(gl::TEXTURE_CUBE_MAP, texture_id);
for (i, face) in faces.iter().enumerate() {
let (data, dim) = {
let img: ImagePtr<u8, Rgb> = io::read_u8(face).unwrap();
let img_data = img.data().to_vec();
let (x, y, _) = img.shape();
(img_data, (x as i32, y as i32))
};
gl::TexImage2D(
gl::TEXTURE_CUBE_MAP_POSITIVE_X + i as u32,
0,
gl::RGB as i32,
dim.0,
dim.1,
0,
gl::RGB,
gl::UNSIGNED_BYTE,
&data[0] as *const u8 as *const c_void,
);
}
gl::TexParameteri(
gl::TEXTURE_CUBE_MAP,
gl::TEXTURE_MIN_FILTER,
gl::LINEAR as i32,
);
gl::TexParameteri(
gl::TEXTURE_CUBE_MAP,
gl::TEXTURE_MAG_FILTER,
gl::LINEAR as i32,
);
gl::TexParameteri(
gl::TEXTURE_CUBE_MAP,
gl::TEXTURE_WRAP_S,
gl::CLAMP_TO_EDGE as i32,
);
gl::TexParameteri(
gl::TEXTURE_CUBE_MAP,
gl::TEXTURE_WRAP_T,
gl::CLAMP_TO_EDGE as i32,
);
gl::TexParameteri(
gl::TEXTURE_CUBE_MAP,
gl::TEXTURE_WRAP_R,
gl::CLAMP_TO_EDGE as i32,
);
texture_id
}