Skip to content

Commit 703fc95

Browse files
committed
Render target
1 parent 3c5bffa commit 703fc95

File tree

11 files changed

+311
-2
lines changed

11 files changed

+311
-2
lines changed

Cargo.lock

Lines changed: 38 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lesson-25-x-terrain/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ edition = "2018"
66

77
[dependencies]
88
resources = { path = "../lib/resources", features = ["backend_filesystem_watch"] }
9+
winput = { path = "../lib/winput" }
10+
lesson_25_x_render_gl = { path = "render_gl" }
11+
lesson_25_x_render_gl_derive = { path = "render_gl_derive" }
912
gl = { path = "../lib/gl" }
1013
failure = "0.1.3"
1114
env_logger = "*"
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[package]
2+
name = "lesson_25_x_render_gl"
3+
version = "0.1.0"
4+
authors = []
5+
edition = "2018"
6+
7+
[dependencies]
8+
gl = { path = "../../lib/gl" }
9+
resources = { path = "../../lib/resources" }
10+
lesson_25_x_render_gl_derive = { path = "../render_gl_derive" }
11+
half = "1.1.1"
12+
vec-2-10-10-10 = "0.1.2"
13+
nalgebra = "0.16"
14+
ncollide3d = "0.17"
15+
failure = "0.1.3"
16+
font-kit = { version = "0.1.0" }
17+
euclid = "0.18.2"
18+
image = "0.20.1"
19+
lyon_tessellation = "0.11.0"
20+
lyon_path = "0.11.0"
21+
int_hash = "0.1.1"
22+
slotmap = "0.3"
23+
log = "0.4.6"
24+
floating-duration = "0.1.2"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#[macro_use] extern crate failure;
2+
3+
pub mod render_target;
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
use nalgebra as na;
2+
use failure;
3+
use gl;
4+
use gl::types::*;
5+
6+
#[derive(Debug, Fail)]
7+
pub enum Error {
8+
#[fail(display = "Render target creation failed. The framebuffer was not complete.")]
9+
TheFramebufferWasNotComplete,
10+
}
11+
12+
pub struct DefaultRenderTarget {
13+
size: na::Vector2<i32>,
14+
gl: gl::Gl,
15+
}
16+
17+
impl DefaultRenderTarget {
18+
pub fn new(gl: &gl::Gl, size: na::Vector2<i32>) -> DefaultRenderTarget {
19+
DefaultRenderTarget {
20+
size,
21+
gl: gl.clone(),
22+
}
23+
}
24+
25+
pub fn bind(&self) {
26+
unsafe {
27+
self.gl.BindFramebuffer(gl::FRAMEBUFFER, 0);
28+
}
29+
}
30+
}
31+
32+
pub struct FramebufferTarget {
33+
size: na::Vector2<i32>,
34+
fb: GLuint,
35+
tex: GLuint,
36+
gl: gl::Gl,
37+
}
38+
39+
impl FramebufferTarget {
40+
pub fn new(gl: &gl::Gl, size: na::Vector2<i32>) -> Result<FramebufferTarget, Error> {
41+
let mut tex = 0;
42+
let mut fb = 0;
43+
44+
unsafe {
45+
gl.GenFramebuffers(1, &mut fb);
46+
gl.BindFramebuffer(gl::FRAMEBUFFER, fb);
47+
48+
gl.GenTextures(1, &mut tex);
49+
gl.BindTexture(gl::TEXTURE_2D, tex);
50+
gl.TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as i32);
51+
gl.TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as i32);
52+
53+
gl.FramebufferTexture(gl::FRAMEBUFFER, gl::COLOR_ATTACHMENT0, tex, 0);
54+
55+
gl.TexImage2D(gl::TEXTURE_2D, 0, gl::RGBA as i32, size.x, size.y, 0, gl::RGBA, gl::UNSIGNED_BYTE, std::ptr::null());
56+
57+
let complete = gl.CheckFramebufferStatus(gl::FRAMEBUFFER);
58+
59+
gl.BindFramebuffer(gl::FRAMEBUFFER, 0);
60+
gl.BindTexture(gl::TEXTURE_2D, 0);
61+
62+
if complete != gl::FRAMEBUFFER_COMPLETE {
63+
return Err(Error::TheFramebufferWasNotComplete);
64+
}
65+
}
66+
67+
Ok(FramebufferTarget {
68+
size,
69+
fb,
70+
tex,
71+
gl: gl.clone(),
72+
})
73+
}
74+
75+
pub fn bind(&self) {
76+
unsafe {
77+
self.gl.BindFramebuffer(gl::FRAMEBUFFER, self.fb);
78+
}
79+
}
80+
}
81+
82+
impl Drop for FramebufferTarget
83+
{
84+
fn drop(&mut self){
85+
unsafe{
86+
self.gl.DeleteFramebuffers(1, &self.fb);
87+
self.gl.DeleteTextures(1, &self.tex);
88+
}
89+
}
90+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "lesson_25_x_render_gl_derive"
3+
version = "0.1.0"
4+
authors = []
5+
6+
[dependencies]
7+
quote = "0.3.15"
8+
syn = "0.11.11"
9+
10+
[lib]
11+
proc-macro = true
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
#![recursion_limit = "128"]
2+
3+
extern crate proc_macro;
4+
extern crate syn;
5+
#[macro_use]
6+
extern crate quote;
7+
8+
#[proc_macro_derive(VertexAttribPointers, attributes(location, divisor))]
9+
pub fn vertex_attrib_pointers_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
10+
let s = input.to_string();
11+
let ast = syn::parse_derive_input(&s).unwrap();
12+
let gen = generate_impl(&ast);
13+
gen.parse().unwrap()
14+
}
15+
16+
fn generate_impl(ast: &syn::DeriveInput) -> quote::Tokens {
17+
let ident = &ast.ident;
18+
let generics = &ast.generics;
19+
let where_clause = &ast.generics.where_clause;
20+
let fields_vertex_attrib_pointer = generate_vertex_attrib_pointer_calls(&ast.body);
21+
22+
quote!{
23+
impl #ident #generics #where_clause {
24+
#[allow(unused_variables)]
25+
pub fn vertex_attrib_pointers(gl: &::gl::Gl) {
26+
let stride = ::std::mem::size_of::<Self>();
27+
let offset = 0;
28+
29+
#(#fields_vertex_attrib_pointer)*
30+
}
31+
}
32+
}
33+
}
34+
35+
fn generate_vertex_attrib_pointer_calls(body: &syn::Body) -> Vec<quote::Tokens> {
36+
match body {
37+
&syn::Body::Enum(_) => panic!("VertexAttribPointers can not be implemented for enums"),
38+
&syn::Body::Struct(syn::VariantData::Unit) => {
39+
panic!("VertexAttribPointers can not be implemented for Unit structs")
40+
}
41+
&syn::Body::Struct(syn::VariantData::Tuple(_)) => {
42+
panic!("VertexAttribPointers can not be implemented for Tuple structs")
43+
}
44+
&syn::Body::Struct(syn::VariantData::Struct(ref s)) => s
45+
.iter()
46+
.map(generate_struct_field_vertex_attrib_pointer_call)
47+
.collect(),
48+
}
49+
}
50+
51+
fn generate_struct_field_vertex_attrib_pointer_call(field: &syn::Field) -> quote::Tokens {
52+
let field_name = match field.ident {
53+
Some(ref i) => format!("{}", i),
54+
None => String::from(""),
55+
};
56+
let field_ty = &field.ty;
57+
58+
if let Some(location_attr) = field
59+
.attrs
60+
.iter()
61+
.filter(|a| a.value.name() == "location")
62+
.next()
63+
{
64+
let location_value: usize = match location_attr.value {
65+
syn::MetaItem::NameValue(_, syn::Lit::Str(ref s, _)) => {
66+
s.parse().unwrap_or_else(|_| {
67+
panic!(
68+
"Field {} location attribute value must contain an integer",
69+
field_name
70+
)
71+
})
72+
}
73+
_ => panic!(
74+
"Field {} location attribute value must be a string literal",
75+
field_name
76+
),
77+
};
78+
79+
let divisor_call = match field
80+
.attrs
81+
.iter()
82+
.filter(|a| a.value.name() == "divisor")
83+
.next()
84+
{
85+
Some(attr) => {
86+
let divisor_value: u32 = match attr.value {
87+
syn::MetaItem::NameValue(_, syn::Lit::Str(ref s, _)) => {
88+
s.parse().unwrap_or_else(|_| {
89+
panic!(
90+
"Field {} divisor attribute value must contain an integer",
91+
field_name
92+
)
93+
})
94+
}
95+
_ => panic!(
96+
"Field {} divisor attribute value must be a string literal",
97+
field_name
98+
),
99+
};
100+
101+
quote! {
102+
gl.VertexAttribDivisor(#location_value as u32, #divisor_value);
103+
}
104+
}
105+
None => quote!{},
106+
};
107+
108+
quote! {
109+
let location = #location_value;
110+
unsafe {
111+
#field_ty::vertex_attrib_pointer(gl, stride, location, offset);
112+
#divisor_call
113+
}
114+
let offset = offset + ::std::mem::size_of::<#field_ty>();
115+
}
116+
} else {
117+
quote! {
118+
let offset = offset + ::std::mem::size_of::<#field_ty>();
119+
}
120+
}
121+
}

lesson-25-x-terrain/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use resources::{
33
Resources,
44
backend::FileSystem
55
};
6+
use winput;
67

78
mod debug;
89
mod onion;

lib/resources/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,7 @@ mod test {
246246
}
247247

248248
#[test]
249-
fn writing_resource_should_produce_change_sync_point_and_other_resource_proxies_should_see_it_as_modified(
250-
) {
249+
fn writing_resource_should_produce_change_sync_point_and_other_resource_proxies_should_see_it_as_modified() {
251250
let res =
252251
Resources::new().loaded_from("a", 0, backend::InMemory::new().with("name", b"hello"));
253252

lib/winput/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
name = "winput"
3+
version = "0.1.0"
4+
authors = []
5+
edition = "2018"
6+
7+
[dependencies]

0 commit comments

Comments
 (0)