use crate::cx::*;
impl Cx {
pub fn render_view(
&mut self,
pass_id: usize,
view_id: usize,
scroll: Vec2,
clip: (Vec2, Vec2),
vr_is_presenting: bool,
zbias: &mut f32,
zbias_step: f32
) {
let draw_calls_len = self.views[view_id].draw_calls_len;
if vr_is_presenting {
self.views[view_id].uniform_view_transform(&Mat4::scale_translate(0.0005, -0.0005, 0.001, -0.3, 1.8, -0.4));
}
else {
self.views[view_id].uniform_view_transform(&Mat4::identity());
}
self.views[view_id].parent_scroll = scroll;
let local_scroll = self.views[view_id].get_local_scroll();
let clip = self.views[view_id].intersect_clip(clip);
for draw_call_id in 0..draw_calls_len {
let sub_view_id = self.views[view_id].draw_calls[draw_call_id].sub_view_id;
if sub_view_id != 0 {
self.render_view(
pass_id,
sub_view_id,
Vec2 {x: local_scroll.x + scroll.x, y: local_scroll.y + scroll.y},
clip,
vr_is_presenting,
zbias,
zbias_step
);
}
else {
let cxview = &mut self.views[view_id];
let draw_call = &mut cxview.draw_calls[draw_call_id];
let sh = &self.shaders[draw_call.shader_id];
if draw_call.instance_dirty {
draw_call.instance_dirty = false;
draw_call.platform.check_attached_vao(draw_call.shader_id, sh, &mut self.platform);
self.platform.from_wasm.alloc_array_buffer(
draw_call.platform.inst_vb_id,
draw_call.instance.len(),
draw_call.instance.as_ptr() as *const f32
);
}
draw_call.set_zbias(*zbias);
draw_call.set_local_scroll(scroll, local_scroll);
draw_call.set_clip(clip);
*zbias += zbias_step;
for texture_id in &draw_call.textures_2d {
let cxtexture = &mut self.textures[*texture_id as usize];
if cxtexture.update_image {
cxtexture.update_image = false;
self.platform.from_wasm.update_texture_image2d(*texture_id as usize, cxtexture);
}
}
let pass_uniforms = self.passes[pass_id].pass_uniforms.as_slice();
let view_uniforms = cxview.view_uniforms.as_slice();
let draw_uniforms = draw_call.draw_uniforms.as_slice();
self.platform.from_wasm.draw_call(
draw_call.shader_id,
draw_call.platform.vao_id,
pass_uniforms,
view_uniforms,
draw_uniforms,
&draw_call.uniforms,
&draw_call.textures_2d
);
}
}
}
pub fn setup_render_pass(&mut self, pass_id: usize, inherit_dpi_factor: f32) {
let pass_size = self.passes[pass_id].pass_size;
self.passes[pass_id].set_ortho_matrix(Vec2::default(), pass_size);
self.passes[pass_id].uniform_camera_view(&Mat4::identity());
self.passes[pass_id].paint_dirty = false;
let dpi_factor = if let Some(override_dpi_factor) = self.passes[pass_id].override_dpi_factor {
override_dpi_factor
}
else {
inherit_dpi_factor
};
self.passes[pass_id].set_dpi_factor(dpi_factor);
}
pub fn draw_pass_to_canvas(&mut self, pass_id: usize, vr_is_presenting: bool, dpi_factor: f32) {
let view_id = self.passes[pass_id].main_view_id.unwrap();
let clear_color = if self.passes[pass_id].color_textures.len() == 0 {
Color::default()
}
else {
match self.passes[pass_id].color_textures[0].clear_color {
ClearColor::InitWith(color) => color,
ClearColor::ClearWith(color) => color
}
};
let clear_depth = match self.passes[pass_id].clear_depth {
ClearDepth::InitWith(depth) => depth,
ClearDepth::ClearWith(depth) => depth
};
self.platform.from_wasm.begin_main_canvas(clear_color, clear_depth as f32);
self.setup_render_pass(pass_id, dpi_factor);
self.platform.from_wasm.set_default_depth_and_blend_mode();
let mut zbias = 0.0;
let zbias_step = self.passes[pass_id].zbias_step;
if vr_is_presenting {
self.platform.from_wasm.mark_vr_draw_eye();
}
self.render_view(
pass_id,
view_id,
Vec2::default(),
(Vec2 {x: -50000., y: -50000.}, Vec2 {x: 50000., y: 50000.}),
vr_is_presenting,
&mut zbias,
zbias_step
);
if vr_is_presenting {
self.platform.from_wasm.loop_vr_draw_eye();
}
}
pub fn draw_pass_to_texture(&mut self, pass_id: usize, dpi_factor: f32) {
let pass_size = self.passes[pass_id].pass_size;
let view_id = self.passes[pass_id].main_view_id.unwrap();
self.setup_render_pass(pass_id, dpi_factor);
self.platform.from_wasm.begin_render_targets(pass_id, (pass_size.x * dpi_factor) as usize, (pass_size.y * dpi_factor) as usize);
for color_texture in &self.passes[pass_id].color_textures {
match color_texture.clear_color {
ClearColor::InitWith(color) => {
self.platform.from_wasm.add_color_target(color_texture.texture_id, true, color);
},
ClearColor::ClearWith(color) => {
self.platform.from_wasm.add_color_target(color_texture.texture_id, false, color);
}
}
}
if let Some(depth_texture_id) = self.passes[pass_id].depth_texture {
match self.passes[pass_id].clear_depth {
ClearDepth::InitWith(depth_clear) => {
self.platform.from_wasm.set_depth_target(depth_texture_id, true, depth_clear as f32);
},
ClearDepth::ClearWith(depth_clear) => {
self.platform.from_wasm.set_depth_target(depth_texture_id, false, depth_clear as f32);
}
}
}
self.platform.from_wasm.end_render_targets();
self.platform.from_wasm.set_default_depth_and_blend_mode();
let mut zbias = 0.0;
let zbias_step = self.passes[pass_id].zbias_step;
self.render_view(
pass_id,
view_id,
Vec2::default(),
(Vec2{x:-50000.,y:-50000.},Vec2{x:50000.,y:50000.}),
false,
&mut zbias,
zbias_step
);
}
pub fn webgl_compile_all_shaders(&mut self) {
for (shader_id, sh) in self.shaders.iter_mut().enumerate() {
let glsh = Self::webgl_compile_shader(shader_id, sh, &mut self.platform);
if let Err(err) = glsh {
self.platform.from_wasm.log(&format!("Got GLSL shader compile error: {}", err.msg))
}
}
}
pub fn webgl_compile_shader(shader_id: usize, sh: &mut CxShader, platform: &mut CxPlatform) -> Result<(), SlErr> {
let (vertex, fragment, mapping) = Self::gl_assemble_shader(&sh.shader_gen, GLShaderType::WebGL1) ?;
platform.from_wasm.compile_webgl_shader(shader_id, &vertex, &fragment, &mapping);
let geom_ib_id = platform.get_free_index_buffer();
let geom_vb_id = platform.get_free_index_buffer();
platform.from_wasm.alloc_array_buffer(
geom_vb_id,
sh.shader_gen.geometry_vertices.len(),
sh.shader_gen.geometry_vertices.as_ptr() as *const f32
);
platform.from_wasm.alloc_index_buffer(
geom_ib_id,
sh.shader_gen.geometry_indices.len(),
sh.shader_gen.geometry_indices.as_ptr() as *const u32
);
sh.mapping = mapping;
sh.platform = Some(CxPlatformShader {
geom_vb_id: geom_vb_id,
geom_ib_id: geom_ib_id,
vertex: vertex,
fragment: fragment
});
Ok(())
}
}
#[derive(Default, Clone)]
pub struct CxPlatformPass {
}
#[derive(Clone, Default)]
pub struct CxPlatformView {
}
#[derive(Default, Clone)]
pub struct CxPlatformDrawCall {
pub resource_shader_id: Option<usize>,
pub vao_id: usize,
pub inst_vb_id: usize
}
#[derive(Clone)]
pub struct CxPlatformShader {
pub vertex: String,
pub fragment: String,
pub geom_vb_id: usize,
pub geom_ib_id: usize,
}
#[derive(Clone, Default)]
pub struct CxPlatformTexture {
}
impl CxPlatformDrawCall {
pub fn check_attached_vao(&mut self, shader_id: usize, sh: &CxShader, platform: &mut CxPlatform) {
if self.resource_shader_id.is_none() || self.resource_shader_id.unwrap() != shader_id {
self.free(platform);
self.resource_shader_id = Some(shader_id);
self.vao_id = platform.get_free_vao();
self.inst_vb_id = platform.get_free_index_buffer();
platform.from_wasm.alloc_array_buffer(
self.inst_vb_id,
0,
0 as *const f32
);
platform.from_wasm.alloc_vao(
shader_id,
self.vao_id,
sh.platform.as_ref().unwrap().geom_ib_id,
sh.platform.as_ref().unwrap().geom_vb_id,
self.inst_vb_id,
);
}
}
fn free(&mut self, platform: &mut CxPlatform) {
if self.vao_id != 0 {
platform.vaos_free.push(self.vao_id);
}
if self.inst_vb_id != 0 {
platform.vertex_buffers_free.push(self.inst_vb_id);
}
self.vao_id = 0;
self.inst_vb_id = 0;
}
}
use std::process::{Child};
pub fn spawn_process_command(_cmd: &str, _args: &[&str], _current_dir: &str) -> Result<Child, std::io::Error> {
Err(std::io::Error::new(std::io::ErrorKind::NotFound, ""))
}