Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 30 additions & 24 deletions citro3d/examples/cube.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use citro3d::macros::include_shader;
use citro3d::math::{
AspectRatio, ClipPlanes, CoordinateOrientation, FVec3, Matrix4, Projection, StereoDisplacement,
};
use citro3d::render::ClearFlags;
use citro3d::{attrib, buffer, render, shader, texenv};
use citro3d::render::{ClearFlags, RenderPass, Target};
use citro3d::{attrib, buffer, shader, texenv};
use ctru::prelude::*;
use ctru::services::gfx::{RawFrameBuffer, Screen, TopScreen3D};

Expand Down Expand Up @@ -104,7 +104,7 @@ fn main() {
let vertex_shader = shader.get(0).unwrap();

let program = shader::Program::new(vertex_shader).unwrap();
instance.bind_program(&program);

let mut vbo_data = Vec::with_capacity_in(VERTS.len(), ctru::linear::LinearAllocator);
for vert in VERTS.iter().enumerate().map(|(i, v)| Vertex {
pos: Vec3 {
Expand All @@ -126,14 +126,6 @@ fn main() {
let mut buf_info = buffer::Info::new();
let vbo_slice = buf_info.add(&vbo_data, &attr_info).unwrap();

// Configure the first fragment shading substage to just pass through the vertex color
// See https://www.opengl.org/sdk/docs/man2/xhtml/glTexEnv.xml for more insight
let stage0 = texenv::Stage::new(0).unwrap();
instance
.texenv(stage0)
.src(texenv::Mode::BOTH, texenv::Source::PrimaryColor, None, None)
.func(texenv::Mode::BOTH, texenv::CombineFunc::Replace);

let projection_uniform_idx = program.get_uniform("projection").unwrap();
let camera_transform = Matrix4::looking_at(
FVec3::new(1.8, 1.8, 1.8),
Expand All @@ -158,31 +150,45 @@ fn main() {
break;
}

instance.render_frame_with(|instance| {
let mut render_to = |target: &mut render::Target, projection| {
instance.render_frame_with(|mut pass| {
fn cast_lifetime_to_closure<'pass, T>(x: T) -> T
where
T: Fn(&mut RenderPass<'pass>, &'pass mut Target<'_>, &Matrix4),
{
x
}

let render_to = cast_lifetime_to_closure(|pass, target, projection| {
target.clear(ClearFlags::ALL, CLEAR_COLOR, 0);

instance
.select_render_target(target)
pass.select_render_target(target)
.expect("failed to set render target");

instance.bind_vertex_uniform(projection_uniform_idx, projection * camera_transform);
pass.bind_vertex_uniform(projection_uniform_idx, projection * camera_transform);

pass.set_attr_info(&attr_info);

instance.set_attr_info(&attr_info);
unsafe {
instance.draw_elements(buffer::Primitive::Triangles, vbo_slice, &index_buffer);
}
};
pass.draw_elements(buffer::Primitive::Triangles, vbo_slice, &index_buffer);
});

pass.bind_program(&program);

let stage0 = texenv::Stage::new(0).unwrap();
pass.texenv(stage0)
.src(texenv::Mode::BOTH, texenv::Source::PrimaryColor, None, None)
.func(texenv::Mode::BOTH, texenv::CombineFunc::Replace);

let Projections {
left_eye,
right_eye,
center,
} = calculate_projections();

render_to(&mut top_left_target, &left_eye);
render_to(&mut top_right_target, &right_eye);
render_to(&mut bottom_target, &center);
render_to(&mut pass, &mut top_left_target, &left_eye);
render_to(&mut pass, &mut top_right_target, &right_eye);
render_to(&mut pass, &mut bottom_target, &center);

pass
});
}
}
Expand Down
80 changes: 37 additions & 43 deletions citro3d/examples/fragment-light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use citro3d::{
color::Color,
light::{DistanceAttenuation, LightEnv, Lut, LutId, LutInput, Material, Spotlight},
math::{AspectRatio, ClipPlanes, FVec3, Matrix4, Projection, StereoDisplacement},
render::{self, ClearFlags},
render::{ClearFlags, DepthFormat, RenderPass, Target},
shader, texenv,
};
use citro3d_macros::include_shader;
Expand Down Expand Up @@ -260,22 +260,12 @@ fn main() {

let RawFrameBuffer { width, height, .. } = top_left.raw_framebuffer();
let mut top_left_target = instance
.render_target(
width,
height,
top_left,
Some(render::DepthFormat::Depth24Stencil8),
)
.render_target(width, height, top_left, Some(DepthFormat::Depth24Stencil8))
.expect("failed to create render target");

let RawFrameBuffer { width, height, .. } = top_right.raw_framebuffer();
let mut top_right_target = instance
.render_target(
width,
height,
top_right,
Some(render::DepthFormat::Depth24Stencil8),
)
.render_target(width, height, top_right, Some(DepthFormat::Depth24Stencil8))
.expect("failed to create render target");

let mut bottom_screen = gfx.bottom_screen.borrow_mut();
Expand All @@ -286,15 +276,14 @@ fn main() {
width,
height,
bottom_screen,
Some(render::DepthFormat::Depth24Stencil8),
Some(DepthFormat::Depth24Stencil8),
)
.expect("failed to create bottom screen render target");

let shader = shader::Library::from_bytes(SHADER_BYTES).unwrap();
let vertex_shader = shader.get(0).unwrap();

let program = shader::Program::new(vertex_shader).unwrap();
instance.bind_program(&program);

let mut vbo_data = Vec::with_capacity_in(VERTICES.len(), ctru::linear::LinearAllocator);
vbo_data.extend_from_slice(VERTICES);
Expand Down Expand Up @@ -344,25 +333,10 @@ fn main() {
(1.0 / (0.5 * PI * d * d)).min(1.0) // We use a less aggressive attenuation to highlight the spotlight
})));

// Bind the lighting environment for use
instance.bind_light_env(Some(light_env));

// Setup the rotating view of the cube
let mut view = Matrix4::identity();
let model_idx = program.get_uniform("modelView").unwrap();
view.translate(0.0, 0.0, -2.0);
instance.bind_vertex_uniform(model_idx, view);

let stage0 = texenv::Stage::new(0).unwrap();
instance
.texenv(stage0)
.src(
texenv::Mode::BOTH,
texenv::Source::FragmentPrimaryColor,
Some(texenv::Source::FragmentSecondaryColor),
None,
)
.func(texenv::Mode::BOTH, texenv::CombineFunc::Add);

let projection_uniform_idx = program.get_uniform("projection").unwrap();

Expand All @@ -373,31 +347,51 @@ fn main() {
break;
}

instance.render_frame_with(|instance| {
let mut render_to = |target: &mut render::Target, projection| {
target.clear(ClearFlags::ALL, 0, 0);
instance.render_frame_with(|mut pass| {
fn cast_lifetime_to_closure<'pass, T>(x: T) -> T
where
T: Fn(&mut RenderPass<'pass>, &'pass mut Target<'_>, &Matrix4),
{
x
}

instance
.select_render_target(target)
let render_to = cast_lifetime_to_closure(|pass, target, projection| {
target.clear(ClearFlags::ALL, 0, 0);
pass.select_render_target(target)
.expect("failed to set render target");

instance.bind_vertex_uniform(projection_uniform_idx, projection);
instance.bind_vertex_uniform(model_idx, view);
pass.bind_vertex_uniform(projection_uniform_idx, projection);
pass.bind_vertex_uniform(model_idx, view);

instance.set_attr_info(&attr_info);
pass.set_attr_info(&attr_info);

instance.draw_arrays(buffer::Primitive::Triangles, vbo_data);
};
pass.draw_arrays(buffer::Primitive::Triangles, vbo_data);
});

pass.bind_program(&program);
pass.bind_light_env(Some(light_env.as_mut()));

let stage0 = texenv::Stage::new(0).unwrap();
pass.texenv(stage0)
.src(
texenv::Mode::BOTH,
texenv::Source::FragmentPrimaryColor,
Some(texenv::Source::FragmentSecondaryColor),
None,
)
.func(texenv::Mode::BOTH, texenv::CombineFunc::Add);

let Projections {
left_eye,
right_eye,
center,
} = calculate_projections();

render_to(&mut top_left_target, &left_eye);
render_to(&mut top_right_target, &right_eye);
render_to(&mut bottom_target, &center);
render_to(&mut pass, &mut top_left_target, &left_eye);
render_to(&mut pass, &mut top_right_target, &right_eye);
render_to(&mut pass, &mut bottom_target, &center);

pass
});

// Rotate the modelView
Expand Down
57 changes: 33 additions & 24 deletions citro3d/examples/triangle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

use citro3d::macros::include_shader;
use citro3d::math::{AspectRatio, ClipPlanes, Matrix4, Projection, StereoDisplacement};
use citro3d::render::ClearFlags;
use citro3d::render::{ClearFlags, RenderPass, Target};
use citro3d::texenv;
use citro3d::{attrib, buffer, render, shader};
use citro3d::{attrib, buffer, shader};
use ctru::prelude::*;
use ctru::services::gfx::{RawFrameBuffer, Screen, TopScreen3D};

Expand Down Expand Up @@ -85,55 +85,64 @@ fn main() {
let vertex_shader = shader.get(0).unwrap();

let program = shader::Program::new(vertex_shader).unwrap();
instance.bind_program(&program);
let projection_uniform_idx = program.get_uniform("projection").unwrap();

let mut vbo_data = Vec::with_capacity_in(VERTICES.len(), ctru::linear::LinearAllocator);
vbo_data.extend_from_slice(VERTICES);

let mut buf_info = buffer::Info::new();
let (attr_info, vbo_data) = prepare_vbos(&mut buf_info, &vbo_data);

// Configure the first fragment shading substage to just pass through the vertex color
// See https://www.opengl.org/sdk/docs/man2/xhtml/glTexEnv.xml for more insight
let stage0 = texenv::Stage::new(0).unwrap();
instance
.texenv(stage0)
.src(texenv::Mode::BOTH, texenv::Source::PrimaryColor, None, None)
.func(texenv::Mode::BOTH, texenv::CombineFunc::Replace);

let projection_uniform_idx = program.get_uniform("projection").unwrap();

while apt.main_loop() {
hid.scan_input();

if hid.keys_down().contains(KeyPad::START) {
break;
}

instance.render_frame_with(|instance| {
let mut render_to = |target: &mut render::Target, projection| {
instance.render_frame_with(|mut pass| {
// Sadly closures can't have lifetime specifiers,
// so we wrap `render_to` in this function to force the borrow checker rules.
fn cast_lifetime_to_closure<'pass, T>(x: T) -> T
where
T: Fn(&mut RenderPass<'pass>, &'pass mut Target<'_>, &Matrix4),
{
x
}

let render_to = cast_lifetime_to_closure(|pass, target, projection| {
target.clear(ClearFlags::ALL, CLEAR_COLOR, 0);

instance
.select_render_target(target)
pass.select_render_target(target)
.expect("failed to set render target");
pass.bind_vertex_uniform(projection_uniform_idx, projection);

pass.set_attr_info(&attr_info);

instance.bind_vertex_uniform(projection_uniform_idx, projection);
pass.draw_arrays(buffer::Primitive::Triangles, vbo_data);
});

instance.set_attr_info(&attr_info);
// We bind the vertex shader.
pass.bind_program(&program);

instance.draw_arrays(buffer::Primitive::Triangles, vbo_data);
};
// Configure the first fragment shading substage to just pass through the vertex color
// See https://www.opengl.org/sdk/docs/man2/xhtml/glTexEnv.xml for more insight
let stage0 = texenv::Stage::new(0).unwrap();
pass.texenv(stage0)
.src(texenv::Mode::BOTH, texenv::Source::PrimaryColor, None, None)
.func(texenv::Mode::BOTH, texenv::CombineFunc::Replace);

let Projections {
left_eye,
right_eye,
center,
} = calculate_projections();

render_to(&mut top_left_target, &left_eye);
render_to(&mut top_right_target, &right_eye);
render_to(&mut bottom_target, &center);
render_to(&mut pass, &mut top_left_target, &left_eye);
render_to(&mut pass, &mut top_right_target, &right_eye);
render_to(&mut pass, &mut bottom_target, &center);

pass
});
}
}
Expand Down
Loading
Loading