Add last state before I stopped
This commit is contained in:
parent
3704b9eeb8
commit
e9631f044d
|
@ -3,6 +3,7 @@ name = "steven"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cgmath 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"flate2 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"flate2 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"glutin 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glutin 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hyper 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hyper 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -74,6 +75,16 @@ dependencies = [
|
||||||
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cgmath"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"num 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cocoa"
|
name = "cocoa"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
|
|
|
@ -17,6 +17,7 @@ time = "0.1.32"
|
||||||
rand = "0.3.11"
|
rand = "0.3.11"
|
||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
log = "0.3.2"
|
log = "0.3.2"
|
||||||
|
cgmath = "0.3.1"
|
||||||
|
|
||||||
[dependencies.steven_gl]
|
[dependencies.steven_gl]
|
||||||
path = "./gl"
|
path = "./gl"
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
use std::any::*;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::collections::hash_state::HashState;
|
||||||
|
use std::hash::Hasher;
|
||||||
|
use std::ptr;
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut c = Container::new();
|
||||||
|
{
|
||||||
|
c.put("Hello world");
|
||||||
|
println!("{}", c.get::<&str>());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
c.put(55);
|
||||||
|
println!("{}", c.get::<i32>());
|
||||||
|
}
|
||||||
|
println!("{}", c.get::<&str>());
|
||||||
|
println!("{}", c.get::<i32>());
|
||||||
|
|
||||||
|
{
|
||||||
|
*c.get_mut::<i32>() = 82;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{}", c.get::<&str>());
|
||||||
|
println!("{}", c.get::<i32>());
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TypeIdState;
|
||||||
|
|
||||||
|
impl HashState for TypeIdState {
|
||||||
|
type Hasher = TypeIdHasher;
|
||||||
|
|
||||||
|
fn hasher(&self) -> TypeIdHasher {
|
||||||
|
TypeIdHasher { value: 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TypeIdHasher {
|
||||||
|
value: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Hasher for TypeIdHasher {
|
||||||
|
fn finish(&self) -> u64 {
|
||||||
|
self.value
|
||||||
|
}
|
||||||
|
fn write(&mut self, bytes: &[u8]) {
|
||||||
|
unsafe {
|
||||||
|
ptr::copy_nonoverlapping(&mut self.value, mem::transmute(&bytes[0]), 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Container {
|
||||||
|
elems: HashMap<TypeId, Box<Any>, TypeIdState>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Container {
|
||||||
|
pub fn new() -> Container {
|
||||||
|
Container {
|
||||||
|
elems: HashMap::with_hash_state(TypeIdState),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn put<T: Sized + Any>(&mut self, data: T) {
|
||||||
|
self.elems.insert(
|
||||||
|
TypeId::of::<T>(),
|
||||||
|
Box::new(data)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get<T: Sized + Any>(&self) -> &T {
|
||||||
|
self.elems.get(&TypeId::of::<T>()).unwrap().downcast_ref::<T>().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_mut<T: Sized + Any>(&mut self) -> & mut T {
|
||||||
|
self.elems.get_mut(&TypeId::of::<T>()).unwrap().downcast_mut::<T>().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use test::Bencher;
|
||||||
|
use test;
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
fn bench_put(b: &mut Bencher) {
|
||||||
|
let mut c = Container::new();
|
||||||
|
b.iter(|| c.put("Hello world"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
fn bench_get(b: &mut Bencher) {
|
||||||
|
let mut c = Container::new();
|
||||||
|
c.put("Hello world");
|
||||||
|
c.put(55);
|
||||||
|
b.iter(|| c.get::<&str>());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
fn bench_get_int(b: &mut Bencher) {
|
||||||
|
let mut c = Container::new();
|
||||||
|
c.put("Hello world");
|
||||||
|
c.put(55);
|
||||||
|
b.iter(|| c.get::<i32>());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
fn bench_get_mut(b: &mut Bencher) {
|
||||||
|
let mut c = Container::new();
|
||||||
|
c.put("Hello world");
|
||||||
|
c.put(55);
|
||||||
|
b.iter(|| *c.get_mut::<i32>());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
fn bench_alloc(b: &mut Bencher) {
|
||||||
|
b.iter(|| test::black_box(Container::new()));
|
||||||
|
}
|
||||||
|
}
|
113
src/gl/mod.rs
113
src/gl/mod.rs
|
@ -652,3 +652,116 @@ impl Drop for MappedBuffer {
|
||||||
mem::forget(mem::replace(&mut self.inner, Vec::new()));
|
mem::forget(mem::replace(&mut self.inner, Vec::new()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Frame buffers
|
||||||
|
|
||||||
|
pub type Attachment = u32;
|
||||||
|
pub const COLOR_ATTACHMENT_0: Attachment = gl::COLOR_ATTACHMENT0;
|
||||||
|
pub const COLOR_ATTACHMENT_1: Attachment = gl::COLOR_ATTACHMENT1;
|
||||||
|
pub const COLOR_ATTACHMENT_2: Attachment = gl::COLOR_ATTACHMENT2;
|
||||||
|
pub const DEPTH_ATTACHMENT: Attachment = gl::DEPTH_ATTACHMENT;
|
||||||
|
|
||||||
|
pub struct Framebuffer(u32);
|
||||||
|
|
||||||
|
impl Framebuffer {
|
||||||
|
pub fn new() -> Framebuffer {
|
||||||
|
let mut fb = Framebuffer(0);
|
||||||
|
unsafe {
|
||||||
|
gl::GenFramebuffers(1, &mut fb.0);
|
||||||
|
}
|
||||||
|
fb
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind(&self) {
|
||||||
|
unsafe {
|
||||||
|
gl::BindFramebuffer(gl::FRAMEBUFFER, self.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind_read(&self) {
|
||||||
|
unsafe {
|
||||||
|
gl::BindFramebuffer(gl::READ_FRAMEBUFFER, self.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind_draw(&self) {
|
||||||
|
unsafe {
|
||||||
|
gl::BindFramebuffer(gl::DRAW_FRAMEBUFFER, self.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn texture_2d(&self, attachment: Attachment, target: TextureTarget, tex: &Texture, level: i32) {
|
||||||
|
unsafe {
|
||||||
|
gl::FramebufferTexture2D(gl::FRAMEBUFFER, attachment, target, tex.0, level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for Framebuffer {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
gl::DeleteFramebuffers(1, &self.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unbind_framebuffer() {
|
||||||
|
unsafe {
|
||||||
|
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unbind_framebuffer_read() {
|
||||||
|
unsafe {
|
||||||
|
gl::BindFramebuffer(gl::READ_FRAMEBUFFER, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unbind_framebuffer_draw() {
|
||||||
|
unsafe {
|
||||||
|
gl::BindFramebuffer(gl::DRAW_FRAMEBUFFER, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_buffers(bufs: &[Attachment]) {
|
||||||
|
unsafe {
|
||||||
|
gl::DrawBuffers(
|
||||||
|
bufs.len() as i32,
|
||||||
|
bufs.as_ptr()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind_frag_data_location(p: &Program, cn: u32, name: &str) {
|
||||||
|
unsafe {
|
||||||
|
gl::BindFragDataLocation(p.0, cn, ffi::CString::new(name).unwrap().as_ptr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn blit_framebuffer(
|
||||||
|
sx0: i32, sy0: i32, sx1: i32, sy1: i32,
|
||||||
|
dx0: i32, dy0: i32, dx1: i32, dy1: i32,
|
||||||
|
mask: ClearFlags, filter: TextureValue) {
|
||||||
|
unsafe {
|
||||||
|
gl::BlitFramebuffer(
|
||||||
|
sx0, sy0, sx1, sy1,
|
||||||
|
dx0, dy0, dx1, dy1,
|
||||||
|
mask.internal(), filter as u32
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_buffer(a: Attachment) {
|
||||||
|
unsafe {
|
||||||
|
gl::ReadBuffer(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type TargetBuffer = u32;
|
||||||
|
pub const COLOR: TargetBuffer = gl::COLOR;
|
||||||
|
|
||||||
|
pub fn clear_buffer(buffer: TargetBuffer, draw_buffer: i32, values: &[f32]) {
|
||||||
|
unsafe {
|
||||||
|
gl::ClearBufferfv(buffer, draw_buffer, values.as_ptr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -12,6 +12,11 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
#![feature(test)]
|
||||||
|
#![feature(hashmap_hasher)]
|
||||||
|
extern crate test;
|
||||||
|
mod esc;
|
||||||
|
|
||||||
pub mod protocol;
|
pub mod protocol;
|
||||||
pub mod format;
|
pub mod format;
|
||||||
pub mod nbt;
|
pub mod nbt;
|
||||||
|
@ -35,6 +40,7 @@ extern crate hyper;
|
||||||
extern crate flate2;
|
extern crate flate2;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate rustc_serialize;
|
extern crate rustc_serialize;
|
||||||
|
extern crate cgmath;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ use image;
|
||||||
use image::GenericImage;
|
use image::GenericImage;
|
||||||
use byteorder::{WriteBytesExt, NativeEndian};
|
use byteorder::{WriteBytesExt, NativeEndian};
|
||||||
use serde_json;
|
use serde_json;
|
||||||
|
use cgmath;
|
||||||
|
|
||||||
const ATLAS_SIZE: usize = 1024;
|
const ATLAS_SIZE: usize = 1024;
|
||||||
|
|
||||||
|
@ -38,10 +39,61 @@ pub struct Renderer {
|
||||||
gl_texture: gl::Texture,
|
gl_texture: gl::Texture,
|
||||||
texture_layers: usize,
|
texture_layers: usize,
|
||||||
|
|
||||||
|
chunk_shader: ChunkShader,
|
||||||
|
chunk_shader_alpha: ChunkShaderAlpha,
|
||||||
|
|
||||||
|
perspective_matrix: cgmath::Matrix4<f32>,
|
||||||
|
|
||||||
|
trans: Option<TransInfo>,
|
||||||
|
|
||||||
last_width: u32,
|
last_width: u32,
|
||||||
last_height: u32,
|
last_height: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init_shader! {
|
||||||
|
Program ChunkShader {
|
||||||
|
vert = "chunk_vertex",
|
||||||
|
frag = "chunk_frag",
|
||||||
|
attribute = {
|
||||||
|
position => "aPosition",
|
||||||
|
texture_info => "aTextureInfo",
|
||||||
|
texture_offset => "aTextureOffset",
|
||||||
|
color => "aColor",
|
||||||
|
lighting => "aLighting",
|
||||||
|
},
|
||||||
|
uniform = {
|
||||||
|
perspective_matrix => "perspectiveMatrix",
|
||||||
|
camera_matrix => "cameraMatrix",
|
||||||
|
offset => "offset",
|
||||||
|
texture => "textures",
|
||||||
|
light_level => "lightLevel",
|
||||||
|
sky_offset => "sky_offset",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init_shader! {
|
||||||
|
Program ChunkShaderAlpha {
|
||||||
|
vert = "chunk_vertex",
|
||||||
|
frag = "chunk_frag", #alpha
|
||||||
|
attribute = {
|
||||||
|
position => "aPosition",
|
||||||
|
texture_info => "aTextureInfo",
|
||||||
|
texture_offset => "aTextureOffset",
|
||||||
|
color => "aColor",
|
||||||
|
lighting => "aLighting",
|
||||||
|
},
|
||||||
|
uniform = {
|
||||||
|
perspective_matrix => "perspectiveMatrix",
|
||||||
|
camera_matrix => "cameraMatrix",
|
||||||
|
offset => "offset",
|
||||||
|
texture => "textures",
|
||||||
|
light_level => "lightLevel",
|
||||||
|
sky_offset => "sky_offset",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Renderer {
|
impl Renderer {
|
||||||
pub fn new(res: Arc<RwLock<resources::Manager>>) -> Renderer {
|
pub fn new(res: Arc<RwLock<resources::Manager>>) -> Renderer {
|
||||||
let version = {
|
let version = {
|
||||||
|
@ -73,12 +125,14 @@ impl Renderer {
|
||||||
gl::cull_face(gl::BACK);
|
gl::cull_face(gl::BACK);
|
||||||
gl::front_face(gl::CLOCK_WISE);
|
gl::front_face(gl::CLOCK_WISE);
|
||||||
|
|
||||||
// Shaders
|
// Shaders
|
||||||
|
let chunk_shader = ChunkShader::new(&greg);
|
||||||
|
let chunk_shader_alpha = ChunkShaderAlpha::new(&greg);
|
||||||
|
|
||||||
// UI
|
// UI
|
||||||
// Line Drawer
|
// Line Drawer
|
||||||
// Models
|
// Models
|
||||||
// Clouds
|
// Clouds
|
||||||
|
|
||||||
gl::blend_func(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
|
gl::blend_func(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
@ -89,8 +143,16 @@ impl Renderer {
|
||||||
resources: res,
|
resources: res,
|
||||||
gl_texture: tex,
|
gl_texture: tex,
|
||||||
texture_layers: 1,
|
texture_layers: 1,
|
||||||
|
|
||||||
|
chunk_shader: chunk_shader,
|
||||||
|
chunk_shader_alpha: chunk_shader_alpha,
|
||||||
|
|
||||||
last_width: 0,
|
last_width: 0,
|
||||||
last_height: 0,
|
last_height: 0,
|
||||||
|
|
||||||
|
perspective_matrix: cgmath::Matrix4::zero(),
|
||||||
|
|
||||||
|
trans: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,21 +172,34 @@ impl Renderer {
|
||||||
self.last_width = width;
|
self.last_width = width;
|
||||||
self.last_height = height;
|
self.last_height = height;
|
||||||
gl::viewport(0, 0, width as i32, height as i32);
|
gl::viewport(0, 0, width as i32, height as i32);
|
||||||
|
|
||||||
|
self.perspective_matrix = cgmath::Matrix4::from(
|
||||||
|
cgmath::PerspectiveFov {
|
||||||
|
fovy: cgmath::Deg{s: 90f32},
|
||||||
|
aspect: (width / height) as f32,
|
||||||
|
near: 0.1f32,
|
||||||
|
far: 500.0f32,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
self.init_trans(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
gl::active_texture(0);
|
gl::active_texture(0);
|
||||||
self.gl_texture.bind(gl::TEXTURE_2D_ARRAY);
|
self.gl_texture.bind(gl::TEXTURE_2D_ARRAY);
|
||||||
|
|
||||||
|
gl::enable(gl::MULTISAMPLE);
|
||||||
|
|
||||||
gl::clear_color(14.0 / 255.0, 48.0 / 255.0, 92.0 / 255.0, 1.0);
|
gl::clear_color(14.0 / 255.0, 48.0 / 255.0, 92.0 / 255.0, 1.0);
|
||||||
gl::clear(gl::ClearFlags::Color | gl::ClearFlags::Depth);
|
gl::clear(gl::ClearFlags::Color | gl::ClearFlags::Depth);
|
||||||
|
|
||||||
self.ui.tick(width, height);
|
self.ui.tick(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_textures(&mut self, delta: f64) {
|
fn do_pending_textures(&mut self) {
|
||||||
self.gl_texture.bind(gl::TEXTURE_2D_ARRAY);
|
|
||||||
let len = {
|
let len = {
|
||||||
let tex = self.textures.read().unwrap();
|
let tex = self.textures.read().unwrap();
|
||||||
|
// Rebuild the texture if it needs resizing
|
||||||
if self.texture_layers != tex.atlases.len() {
|
if self.texture_layers != tex.atlases.len() {
|
||||||
let len = ATLAS_SIZE * ATLAS_SIZE * 4 * tex.atlases.len();
|
let len = ATLAS_SIZE * ATLAS_SIZE * 4 * tex.atlases.len();
|
||||||
let mut data = Vec::with_capacity(len);
|
let mut data = Vec::with_capacity(len);
|
||||||
|
@ -149,6 +224,7 @@ impl Renderer {
|
||||||
tex.pending_uploads.len()
|
tex.pending_uploads.len()
|
||||||
};
|
};
|
||||||
if len > 0 {
|
if len > 0 {
|
||||||
|
// Upload pending changes
|
||||||
let mut tex = self.textures.write().unwrap();
|
let mut tex = self.textures.write().unwrap();
|
||||||
for upload in &tex.pending_uploads {
|
for upload in &tex.pending_uploads {
|
||||||
let atlas = upload.0;
|
let atlas = upload.0;
|
||||||
|
@ -168,6 +244,11 @@ impl Renderer {
|
||||||
}
|
}
|
||||||
tex.pending_uploads.clear();
|
tex.pending_uploads.clear();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_textures(&mut self, delta: f64) {
|
||||||
|
self.gl_texture.bind(gl::TEXTURE_2D_ARRAY);
|
||||||
|
self.do_pending_textures();
|
||||||
|
|
||||||
for ani in &mut self.textures.write().unwrap().animated_textures {
|
for ani in &mut self.textures.write().unwrap().animated_textures {
|
||||||
if ani.remaining_time <= 0.0 {
|
if ani.remaining_time <= 0.0 {
|
||||||
|
@ -194,6 +275,11 @@ impl Renderer {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn init_trans(&mut self, width: u32, height: u32) {
|
||||||
|
self.trans = None;
|
||||||
|
self.trans = Some(TransInfo::new(width, height));
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_textures(&self) -> Arc<RwLock<TextureManager>> {
|
pub fn get_textures(&self) -> Arc<RwLock<TextureManager>> {
|
||||||
self.textures.clone()
|
self.textures.clone()
|
||||||
}
|
}
|
||||||
|
@ -224,8 +310,8 @@ impl Renderer {
|
||||||
Some(val) => val,
|
Some(val) => val,
|
||||||
None => {
|
None => {
|
||||||
let mut t = textures.write().unwrap();
|
let mut t = textures.write().unwrap();
|
||||||
// Make sure it hasn't already been loaded since we switched
|
// Make sure it hasn't already been loaded since we switched
|
||||||
// locks.
|
// locks.
|
||||||
if let Some(val) = t.get_texture(name) {
|
if let Some(val) = t.get_texture(name) {
|
||||||
val
|
val
|
||||||
} else {
|
} else {
|
||||||
|
@ -237,6 +323,48 @@ impl Renderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct TransInfo {
|
||||||
|
main: gl::Framebuffer,
|
||||||
|
fbColor: gl::Texture,
|
||||||
|
fbDepth: gl::Texture,
|
||||||
|
trans: gl::Framebuffer,
|
||||||
|
accum: gl::Texture,
|
||||||
|
revealage: gl::Texture,
|
||||||
|
depth: gl::Texture,
|
||||||
|
|
||||||
|
prgoram: TransShader,
|
||||||
|
array: gl::VertexArray,
|
||||||
|
buffer: gl::Buffer,
|
||||||
|
}
|
||||||
|
|
||||||
|
init_shader! {
|
||||||
|
Program TransShader {
|
||||||
|
vert = "trans_vertex",
|
||||||
|
frag = "trans_frag",
|
||||||
|
attribute = {
|
||||||
|
position => "aPosition",
|
||||||
|
},
|
||||||
|
uniform = {
|
||||||
|
accum => "taccum",
|
||||||
|
revealage => "trevealage",
|
||||||
|
color => "tcolor",
|
||||||
|
samples => "samples",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TransInfo {
|
||||||
|
pub fn new(width: u32, height: u32) -> TransInfo {
|
||||||
|
let trans = gl::Framebuffer::new();
|
||||||
|
trans.bind();
|
||||||
|
|
||||||
|
let accum = gl::Texture::new();
|
||||||
|
accum.bind(gl::TEXTURE_2D);
|
||||||
|
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct TextureManager {
|
pub struct TextureManager {
|
||||||
textures: HashMap<String, Texture>,
|
textures: HashMap<String, Texture>,
|
||||||
version: usize,
|
version: usize,
|
||||||
|
@ -273,18 +401,18 @@ impl TextureManager {
|
||||||
2,
|
2,
|
||||||
2,
|
2,
|
||||||
vec![
|
vec![
|
||||||
0, 0, 0, 255,
|
0, 0, 0, 255,
|
||||||
255, 0, 255, 255,
|
255, 0, 255, 255,
|
||||||
255, 0, 255, 255,
|
255, 0, 255, 255,
|
||||||
0, 0, 0, 255,
|
0, 0, 0, 255,
|
||||||
]);
|
]);
|
||||||
self.put_texture("steven",
|
self.put_texture("steven",
|
||||||
"solid",
|
"solid",
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
vec![
|
vec![
|
||||||
255, 255, 255, 255,
|
255, 255, 255, 255,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_textures(&mut self, version: usize) {
|
fn update_textures(&mut self, version: usize) {
|
||||||
|
@ -321,7 +449,7 @@ impl TextureManager {
|
||||||
val.read_to_end(&mut data).unwrap();
|
val.read_to_end(&mut data).unwrap();
|
||||||
if let Ok(img) = image::load_from_memory(&data) {
|
if let Ok(img) = image::load_from_memory(&data) {
|
||||||
let (width, height) = img.dimensions();
|
let (width, height) = img.dimensions();
|
||||||
// Might be animated
|
// Might be animated
|
||||||
if (name.starts_with("blocks/") || name.starts_with("items/")) && width != height {
|
if (name.starts_with("blocks/") || name.starts_with("items/")) && width != height {
|
||||||
let id = img.to_rgba().into_vec();
|
let id = img.to_rgba().into_vec();
|
||||||
let frame = id[..(width * width * 4) as usize].to_owned();
|
let frame = id[..(width * width * 4) as usize].to_owned();
|
||||||
|
@ -364,9 +492,9 @@ impl TextureManager {
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
out.push(AnimationFrame{
|
out.push(AnimationFrame{
|
||||||
index: frame.find("index").unwrap().as_i64().unwrap() as usize,
|
index: frame.find("index").unwrap().as_i64().unwrap() as usize,
|
||||||
time: frame_time * frame.find("frameTime").unwrap().as_i64().unwrap(),
|
time: frame_time * frame.find("frameTime").unwrap().as_i64().unwrap(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out
|
out
|
||||||
|
|
|
@ -22,14 +22,29 @@ pub fn add_shaders(reg: &mut glsl::Registry) {
|
||||||
|
|
||||||
reg.register("ui_vertex", include_str!("shaders/ui_vertex.glsl"));
|
reg.register("ui_vertex", include_str!("shaders/ui_vertex.glsl"));
|
||||||
reg.register("ui_frag", include_str!("shaders/ui_frag.glsl"));
|
reg.register("ui_frag", include_str!("shaders/ui_frag.glsl"));
|
||||||
|
|
||||||
|
reg.register("chunk_vertex", include_str!("shaders/chunk_vertex.glsl"));
|
||||||
|
reg.register("chunk_frag", include_str!("shaders/chunk_frag.glsl"));
|
||||||
|
|
||||||
|
reg.register("trans_vertex", include_str!("shaders/trans_vertex.glsl"));
|
||||||
|
reg.register("trans_frag", include_str!("shaders/trans_frag.glsl"));
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! get_shader {
|
||||||
|
($reg:ident, $name:expr) => (
|
||||||
|
$reg.get($name)
|
||||||
|
);
|
||||||
|
($reg:ident, $name:expr, $def:expr) => (
|
||||||
|
$reg.get_define($name, $def)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! init_shader {
|
macro_rules! init_shader {
|
||||||
(
|
(
|
||||||
Program $name:ident {
|
Program $name:ident {
|
||||||
vert = $vert:expr,
|
vert = $vert:expr, $(#$vdef:ident)*
|
||||||
frag = $frag:expr,
|
frag = $frag:expr, $(#$fdef:ident)*
|
||||||
attribute = {
|
attribute = {
|
||||||
$(
|
$(
|
||||||
$field:ident => $glname:expr,
|
$field:ident => $glname:expr,
|
||||||
|
@ -42,6 +57,7 @@ macro_rules! init_shader {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
) => (
|
) => (
|
||||||
|
#[allow(dead_code)]
|
||||||
struct $name {
|
struct $name {
|
||||||
program: gl::Program,
|
program: gl::Program,
|
||||||
$(
|
$(
|
||||||
|
@ -54,8 +70,8 @@ macro_rules! init_shader {
|
||||||
|
|
||||||
impl $name {
|
impl $name {
|
||||||
pub fn new(reg: &glsl::Registry) -> $name {
|
pub fn new(reg: &glsl::Registry) -> $name {
|
||||||
let v = reg.get($vert);
|
let v = get_shader!(reg, $vert $(,stringify!($vdef))*);
|
||||||
let f = reg.get($frag);
|
let f = get_shader!(reg, $frag $(,stringify!($fdef))*);
|
||||||
let shader = shaders::create_program(&v, &f);
|
let shader = shaders::create_program(&v, &f);
|
||||||
$name {
|
$name {
|
||||||
$(
|
$(
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
uniform sampler2DArray textures;
|
||||||
|
|
||||||
|
in vec3 vColor;
|
||||||
|
in vec4 vTextureInfo;
|
||||||
|
in vec2 vTextureOffset;
|
||||||
|
in float vAtlas;
|
||||||
|
in vec3 vLighting;
|
||||||
|
|
||||||
|
#ifndef alpha
|
||||||
|
out vec4 fragColor;
|
||||||
|
#else
|
||||||
|
out vec4 accum;
|
||||||
|
out float revealage;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include lookup_texture
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 col = atlasTexture();
|
||||||
|
#ifndef alpha
|
||||||
|
if (col.a < 0.5) discard;
|
||||||
|
#endif
|
||||||
|
col *= vec4(vColor, 1.0);
|
||||||
|
col.rgb *= vLighting;
|
||||||
|
|
||||||
|
#ifndef alpha
|
||||||
|
fragColor = col;
|
||||||
|
#else
|
||||||
|
float z = gl_FragCoord.z;
|
||||||
|
float al = col.a;
|
||||||
|
float weight = pow(al + 0.01f, 4.0f) +
|
||||||
|
max(0.01f, min(3000.0f, 0.3f / (0.00001f + pow(abs(z) / 800.0f, 4.0f))));
|
||||||
|
accum = vec4(col.rgb * al * weight, al);
|
||||||
|
revealage = weight * al;
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
in vec3 aPosition;
|
||||||
|
in vec4 aTextureInfo;
|
||||||
|
in vec3 aTextureOffset;
|
||||||
|
in vec3 aColor;
|
||||||
|
in vec2 aLighting;
|
||||||
|
|
||||||
|
uniform mat4 perspectiveMatrix;
|
||||||
|
uniform mat4 cameraMatrix;
|
||||||
|
uniform ivec3 offset;
|
||||||
|
uniform float lightLevel;
|
||||||
|
uniform float skyOffset;
|
||||||
|
|
||||||
|
out vec3 vColor;
|
||||||
|
out vec4 vTextureInfo;
|
||||||
|
out vec2 vTextureOffset;
|
||||||
|
out float vAtlas;
|
||||||
|
out vec3 vLighting;
|
||||||
|
|
||||||
|
#include get_light
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec3 pos = vec3(aPosition.x, -aPosition.y, aPosition.z);
|
||||||
|
vec3 o = vec3(offset.x, -offset.y / 4096.0, offset.z);
|
||||||
|
gl_Position = perspectiveMatrix * cameraMatrix * vec4(pos + o * 16.0, 1.0);
|
||||||
|
|
||||||
|
vColor = aColor;
|
||||||
|
vTextureInfo = aTextureInfo;
|
||||||
|
vTextureOffset = aTextureOffset.xy / 16.0;
|
||||||
|
vAtlas = aTextureOffset.z;
|
||||||
|
|
||||||
|
vLighting = getLight(aLighting / (4000.0));
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
uniform sampler2D taccum;
|
||||||
|
uniform sampler2D trevealage;
|
||||||
|
uniform sampler2DMS tcolor;
|
||||||
|
|
||||||
|
uniform int samples;
|
||||||
|
|
||||||
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
ivec2 C = ivec2(gl_FragCoord.xy);
|
||||||
|
vec4 accum = texelFetch(taccum, C, 0);
|
||||||
|
float aa = texelFetch(trevealage, C, 0).r;
|
||||||
|
vec4 col = texelFetch(tcolor, C, 0);
|
||||||
|
|
||||||
|
for (int i = 1; i < samples; i++) {
|
||||||
|
col += texelFetch(tcolor, C, i);
|
||||||
|
}
|
||||||
|
col /= float(samples);
|
||||||
|
|
||||||
|
float r = accum.a;
|
||||||
|
accum.a = aa;
|
||||||
|
if (r >= 1.0) {
|
||||||
|
fragColor = vec4(col.rgb, 0.0);
|
||||||
|
} else {
|
||||||
|
vec3 alp = clamp(accum.rgb / clamp(accum.a, 1e-4, 5e4), 0.0, 1.0);
|
||||||
|
fragColor = vec4(col.rgb * r + alp * (1.0 - r), 0.0);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
in vec2 aPosition;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = vec4(aPosition,0,1);
|
||||||
|
}
|
Loading…
Reference in New Issue