Add last state before I stopped

This commit is contained in:
Thinkofdeath 2016-03-16 17:33:06 +00:00
parent 3704b9eeb8
commit e9631f044d
11 changed files with 521 additions and 24 deletions

11
Cargo.lock generated
View File

@ -3,6 +3,7 @@ name = "steven"
version = "0.0.1"
dependencies = [
"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)",
"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)",
@ -74,6 +75,16 @@ dependencies = [
"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]]
name = "cocoa"
version = "0.1.5"

View File

@ -17,6 +17,7 @@ time = "0.1.32"
rand = "0.3.11"
rustc-serialize = "0.3"
log = "0.3.2"
cgmath = "0.3.1"
[dependencies.steven_gl]
path = "./gl"

121
src/esc.rs Normal file
View File

@ -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()));
}
}

View File

@ -652,3 +652,116 @@ impl Drop for MappedBuffer {
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());
}
}

View File

@ -12,6 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#![feature(test)]
#![feature(hashmap_hasher)]
extern crate test;
mod esc;
pub mod protocol;
pub mod format;
pub mod nbt;
@ -35,6 +40,7 @@ extern crate hyper;
extern crate flate2;
extern crate rand;
extern crate rustc_serialize;
extern crate cgmath;
#[macro_use]
extern crate log;

View File

@ -26,6 +26,7 @@ use image;
use image::GenericImage;
use byteorder::{WriteBytesExt, NativeEndian};
use serde_json;
use cgmath;
const ATLAS_SIZE: usize = 1024;
@ -38,10 +39,61 @@ pub struct Renderer {
gl_texture: gl::Texture,
texture_layers: usize,
chunk_shader: ChunkShader,
chunk_shader_alpha: ChunkShaderAlpha,
perspective_matrix: cgmath::Matrix4<f32>,
trans: Option<TransInfo>,
last_width: 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 {
pub fn new(res: Arc<RwLock<resources::Manager>>) -> Renderer {
let version = {
@ -73,12 +125,14 @@ impl Renderer {
gl::cull_face(gl::BACK);
gl::front_face(gl::CLOCK_WISE);
// Shaders
// Shaders
let chunk_shader = ChunkShader::new(&greg);
let chunk_shader_alpha = ChunkShaderAlpha::new(&greg);
// UI
// Line Drawer
// Models
// Clouds
// UI
// Line Drawer
// Models
// Clouds
gl::blend_func(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
@ -89,8 +143,16 @@ impl Renderer {
resources: res,
gl_texture: tex,
texture_layers: 1,
chunk_shader: chunk_shader,
chunk_shader_alpha: chunk_shader_alpha,
last_width: 0,
last_height: 0,
perspective_matrix: cgmath::Matrix4::zero(),
trans: None,
}
}
@ -110,21 +172,34 @@ impl Renderer {
self.last_width = width;
self.last_height = height;
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);
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(gl::ClearFlags::Color | gl::ClearFlags::Depth);
self.ui.tick(width, height);
}
fn update_textures(&mut self, delta: f64) {
self.gl_texture.bind(gl::TEXTURE_2D_ARRAY);
fn do_pending_textures(&mut self) {
let len = {
let tex = self.textures.read().unwrap();
// Rebuild the texture if it needs resizing
if self.texture_layers != tex.atlases.len() {
let len = ATLAS_SIZE * ATLAS_SIZE * 4 * tex.atlases.len();
let mut data = Vec::with_capacity(len);
@ -149,6 +224,7 @@ impl Renderer {
tex.pending_uploads.len()
};
if len > 0 {
// Upload pending changes
let mut tex = self.textures.write().unwrap();
for upload in &tex.pending_uploads {
let atlas = upload.0;
@ -168,6 +244,11 @@ impl Renderer {
}
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 {
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>> {
self.textures.clone()
}
@ -224,8 +310,8 @@ impl Renderer {
Some(val) => val,
None => {
let mut t = textures.write().unwrap();
// Make sure it hasn't already been loaded since we switched
// locks.
// Make sure it hasn't already been loaded since we switched
// locks.
if let Some(val) = t.get_texture(name) {
val
} 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 {
textures: HashMap<String, Texture>,
version: usize,
@ -273,18 +401,18 @@ impl TextureManager {
2,
2,
vec![
0, 0, 0, 255,
255, 0, 255, 255,
255, 0, 255, 255,
0, 0, 0, 255,
]);
0, 0, 0, 255,
255, 0, 255, 255,
255, 0, 255, 255,
0, 0, 0, 255,
]);
self.put_texture("steven",
"solid",
1,
1,
vec![
255, 255, 255, 255,
]);
255, 255, 255, 255,
]);
}
fn update_textures(&mut self, version: usize) {
@ -321,7 +449,7 @@ impl TextureManager {
val.read_to_end(&mut data).unwrap();
if let Ok(img) = image::load_from_memory(&data) {
let (width, height) = img.dimensions();
// Might be animated
// Might be animated
if (name.starts_with("blocks/") || name.starts_with("items/")) && width != height {
let id = img.to_rgba().into_vec();
let frame = id[..(width * width * 4) as usize].to_owned();
@ -364,9 +492,9 @@ impl TextureManager {
})
} else {
out.push(AnimationFrame{
index: frame.find("index").unwrap().as_i64().unwrap() as usize,
time: frame_time * frame.find("frameTime").unwrap().as_i64().unwrap(),
})
index: frame.find("index").unwrap().as_i64().unwrap() as usize,
time: frame_time * frame.find("frameTime").unwrap().as_i64().unwrap(),
})
}
}
out

View File

@ -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_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_rules! init_shader {
(
Program $name:ident {
vert = $vert:expr,
frag = $frag:expr,
vert = $vert:expr, $(#$vdef:ident)*
frag = $frag:expr, $(#$fdef:ident)*
attribute = {
$(
$field:ident => $glname:expr,
@ -42,6 +57,7 @@ macro_rules! init_shader {
},
}
) => (
#[allow(dead_code)]
struct $name {
program: gl::Program,
$(
@ -54,8 +70,8 @@ macro_rules! init_shader {
impl $name {
pub fn new(reg: &glsl::Registry) -> $name {
let v = reg.get($vert);
let f = reg.get($frag);
let v = get_shader!(reg, $vert $(,stringify!($vdef))*);
let f = get_shader!(reg, $frag $(,stringify!($fdef))*);
let shader = shaders::create_program(&v, &f);
$name {
$(

View File

@ -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
}

View File

@ -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));
}

View File

@ -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);
}
}

View File

@ -0,0 +1,5 @@
in vec2 aPosition;
void main() {
gl_Position = vec4(aPosition,0,1);
}