void TestGetNodeLocalIndex() { // Create nodes std::vector<Node<2>*> nodes; // This is a square nodes.push_back(new Node<2>(3, false, 0.0, 0.0)); nodes.push_back(new Node<2>(2, false, 1.0, 0.0)); nodes.push_back(new Node<2>(1, false, 1.0, 1.0)); nodes.push_back(new Node<2>(0, false, 0.0, 1.0)); // Create element VertexElement<2,2> vertex_element(INDEX_IS_NOT_USED, nodes); TS_ASSERT_EQUALS(vertex_element.GetNodeLocalIndex(0), 3u); TS_ASSERT_EQUALS(vertex_element.GetNodeLocalIndex(1), 2u); TS_ASSERT_EQUALS(vertex_element.GetNodeLocalIndex(2), 1u); TS_ASSERT_EQUALS(vertex_element.GetNodeLocalIndex(3), 0u); vertex_element.DeleteNode(3); // Removes (1,1) node TS_ASSERT_EQUALS(vertex_element.GetNodeLocalIndex(0), UINT_MAX); // Tidy up for (unsigned i=0; i<nodes.size(); i++) { delete nodes[i]; } }
void TestMarkAsDeleted() { // Create nodes std::vector<Node<2>*> nodes; nodes.push_back(new Node<2>(0, false, 0.0, 0.0)); nodes.push_back(new Node<2>(1, false, 1.0, 0.0)); nodes.push_back(new Node<2>(2, false, 1.0, 1.0)); nodes.push_back(new Node<2>(3, false, 0.0, 1.0)); // Create element VertexElement<2,2> vertex_element(0, nodes); vertex_element.RegisterWithNodes(); for (unsigned i=0; i<nodes.size(); i++) { TS_ASSERT_EQUALS(vertex_element.GetNode(i)->GetNumContainingElements(), 1u); } vertex_element.MarkAsDeleted(); for (unsigned i=0; i<nodes.size(); i++) { TS_ASSERT_EQUALS(vertex_element.GetNode(i)->GetNumContainingElements(), 0u); } // Tidy up for (unsigned i=0; i<nodes.size(); i++) { delete nodes[i]; } }
void TestUpdateNode() { // Create nodes std::vector<Node<2>*> nodes; nodes.push_back(new Node<2>(0, false, 0.0, 0.0)); nodes.push_back(new Node<2>(1, false, 1.0, 0.0)); nodes.push_back(new Node<2>(2, false, 1.0, 1.0)); nodes.push_back(new Node<2>(3, false, 0.0, 1.0)); // Create element VertexElement<2,2> vertex_element(0, nodes); vertex_element.RegisterWithNodes(); TS_ASSERT_DELTA(vertex_element.GetNode(2)->rGetLocation()[0], 1.0, 1e-12); TS_ASSERT_DELTA(vertex_element.GetNode(2)->rGetLocation()[0], 1.0, 1e-12); // Update location of node 2 Node<2>* p_node = new Node<2>(4, false, 1.2, 1.3); vertex_element.UpdateNode(2, p_node); TS_ASSERT_DELTA(vertex_element.GetNode(2)->rGetLocation()[0], 1.2, 1e-12); TS_ASSERT_DELTA(vertex_element.GetNode(2)->rGetLocation()[1], 1.3, 1e-12); // Tidy up for (unsigned i=0; i<nodes.size(); ++i) { delete nodes[i]; } delete p_node; }
void RenderableTriangle::Init() { RenderFactory& rf = Context::Instance().RenderFactoryInstance(); RenderEffectPtr effect = SyncLoadRenderEffect("RenderableHelper.fxml"); technique_ = simple_forward_tech_ = effect->TechniqueByName("LineTec"); v0_ep_ = effect->ParameterByName("v0"); v1_ep_ = effect->ParameterByName("v1"); v2_ep_ = effect->ParameterByName("v2"); color_ep_ = effect->ParameterByName("color"); mvp_param_ = effect->ParameterByName("mvp"); float vertices[] = { 0, 1, 2 }; ElementInitData init_data; init_data.row_pitch = sizeof(vertices); init_data.slice_pitch = 0; init_data.data = vertices; rl_ = rf.MakeRenderLayout(); rl_->TopologyType(RenderLayout::TT_TriangleList); GraphicsBufferPtr vb = rf.MakeVertexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data); rl_->BindVertexStream(vb, make_tuple(vertex_element(VEU_Position, 0, EF_R32F))); tc_aabb_ = AABBox(float3(0, 0, 0), float3(0, 0, 0)); *(effect->ParameterByName("pos_center")) = float3(0, 0, 0); *(effect->ParameterByName("pos_extent")) = float3(1, 1, 1); effect_attrs_ |= EA_SimpleForward; }
void TestAltenativeConstructor() { // Create element VertexElement<2,2> vertex_element(5); // Test member variables TS_ASSERT_EQUALS(vertex_element.GetIndex(), 5u); TS_ASSERT_EQUALS(vertex_element.GetNumNodes(), 0u); TS_ASSERT_EQUALS(vertex_element.GetNumFaces(), 0u); }
void RenderableLineBox::Init() { RenderFactory& rf = Context::Instance().RenderFactoryInstance(); RenderEffectPtr effect = SyncLoadRenderEffect("RenderableHelper.fxml"); technique_ = simple_forward_tech_ = effect->TechniqueByName("LineTec"); v0_ep_ = effect->ParameterByName("v0"); v1_ep_ = effect->ParameterByName("v1"); v2_ep_ = effect->ParameterByName("v2"); v3_ep_ = effect->ParameterByName("v3"); v4_ep_ = effect->ParameterByName("v4"); v5_ep_ = effect->ParameterByName("v5"); v6_ep_ = effect->ParameterByName("v6"); v7_ep_ = effect->ParameterByName("v7"); color_ep_ = effect->ParameterByName("color"); mvp_param_ = effect->ParameterByName("mvp"); float vertices[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; uint16_t indices[] = { 0, 1, 1, 3, 3, 2, 2, 0, 4, 5, 5, 7, 7, 6, 6, 4, 0, 4, 1, 5, 2, 6, 3, 7 }; rl_ = rf.MakeRenderLayout(); rl_->TopologyType(RenderLayout::TT_LineList); ElementInitData init_data; init_data.row_pitch = sizeof(vertices); init_data.slice_pitch = 0; init_data.data = vertices; GraphicsBufferPtr vb = rf.MakeVertexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data); rl_->BindVertexStream(vb, std::make_tuple(vertex_element(VEU_Position, 0, EF_R32F))); init_data.row_pitch = sizeof(indices); init_data.slice_pitch = 0; init_data.data = indices; GraphicsBufferPtr ib = rf.MakeIndexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data); rl_->BindIndexStream(ib, EF_R16UI); tc_aabb_ = AABBox(float3(0, 0, 0), float3(0, 0, 0)); *(effect->ParameterByName("pos_center")) = float3(0, 0, 0); *(effect->ParameterByName("pos_extent")) = float3(1, 1, 1); effect_attrs_ |= EA_SimpleForward; }
void TestVertexElementFaceConstructor() { // Create a regular hexagon std::vector<Node<2>*> nodes; std::vector<VertexElement<1,2>*> faces; std::vector<Node<2>*> face_nodes; std::vector<bool> orientations; unsigned num_nodes = 6; for (unsigned i=0; i<num_nodes; i++) { double theta = 2.0*M_PI*(double)(i)/(double)(num_nodes); nodes.push_back(new Node<2>(i, false, cos(theta), sin(theta))); } for (unsigned i=0; i<num_nodes-1; i++) { face_nodes.clear(); face_nodes.push_back(nodes[i]); face_nodes.push_back(nodes[i+1]); faces.push_back(new VertexElement<1,2>(i, face_nodes)); orientations.push_back(true); } // Create a face with negative orientation face_nodes.clear(); face_nodes.push_back(nodes[0]); face_nodes.push_back(nodes[num_nodes-1]); faces.push_back(new VertexElement<1,2>(num_nodes-1, face_nodes)); orientations.push_back(false); // Create element VertexElement<2,2> vertex_element(0, faces, orientations); TS_ASSERT_EQUALS(vertex_element.GetNumNodes(), 6u); TS_ASSERT_EQUALS(vertex_element.GetNumFaces(), 6u); // Test that each face has the correct orientation and number of nodes for (unsigned face_index=0; face_index<6; face_index++) { TS_ASSERT_EQUALS(vertex_element.GetFace(face_index)->GetNumNodes(), 2u); bool is_clockwise = (face_index==5) ? false : true; TS_ASSERT_EQUALS(vertex_element.FaceIsOrientatedClockwise(face_index), is_clockwise); } // Tidy up for (unsigned i=0; i<nodes.size(); i++) { delete nodes[i]; delete faces[i]; } }
GpuFftCS4::GpuFftCS4(uint32_t width, uint32_t height, bool forward) : width_(width), height_(height), forward_(forward) { RenderFactory& rf = Context::Instance().RenderFactoryInstance(); src_ = rf.MakeVertexBuffer(BU_Dynamic, EAH_GPU_Read | EAH_GPU_Unordered | EAH_GPU_Structured, nullptr, EF_GR32F); src_->Resize(3 * width * height * sizeof(float) * 2); dst_ = rf.MakeVertexBuffer(BU_Dynamic, EAH_GPU_Read | EAH_GPU_Unordered | EAH_GPU_Structured, nullptr, EF_GR32F); dst_->Resize(3 * width * height * sizeof(float) * 2); tmp_buffer_ = rf.MakeVertexBuffer(BU_Dynamic, EAH_GPU_Read | EAH_GPU_Unordered | EAH_GPU_Structured, nullptr, EF_GR32F); tmp_buffer_->Resize(3 * width * height * sizeof(float) * 2); quad_layout_ = rf.MakeRenderLayout(); quad_layout_->TopologyType(RenderLayout::TT_TriangleStrip); float2 xyzs[] = { float2(-1, +1), float2(+1, +1), float2(-1, -1), float2(+1, -1) }; ElementInitData init_data; init_data.row_pitch = sizeof(xyzs); init_data.slice_pitch = 0; init_data.data = xyzs; GraphicsBufferPtr quad_vb = rf.MakeVertexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data); quad_layout_->BindVertexStream(quad_vb, std::make_tuple(vertex_element(VEU_Position, 0, EF_GR32F))); tex_fb_ = rf.MakeFrameBuffer(); effect_ = SyncLoadRenderEffect("FFT.fxml"); buf2tex_tech_ = effect_->TechniqueByName("Buf2Tex"); radix008a_tech_ = effect_->TechniqueByName("FFTRadix008A4"); radix008a_first_tech_ = effect_->TechniqueByName("FFTRadix008AFirst4"); radix008a_final_tech_ = effect_->TechniqueByName("FFTRadix008AFinal4"); real_tex_ep_ = effect_->ParameterByName("real_tex"); imag_tex_ep_ = effect_->ParameterByName("imag_tex"); *(effect_->ParameterByName("input_buf")) = dst_; *(effect_->ParameterByName("tex_width_height")) = uint2(width, height); uint32_t n = width * height; *(effect_->ParameterByName("addr_offset")) = uint3(0 * n, 1 * n, 2 * n); *(effect_->ParameterByName("forward")) = static_cast<int32_t>(forward_); *(effect_->ParameterByName("scale")) = 1.0f / (width_ * height_); }
LensFlareRenderable::LensFlareRenderable() : RenderableHelper(L"LensFlare") { RenderFactory& rf = Context::Instance().RenderFactoryInstance(); rl_ = rf.MakeRenderLayout(); rl_->TopologyType(RenderLayout::TT_TriangleList); std::vector<float3> vertices; for (int i = 0; i < SUN_FLARENUM; ++ i) { vertices.push_back(float3(-1, +1, i + 0.1f)); vertices.push_back(float3(+1, +1, i + 0.1f)); vertices.push_back(float3(-1, -1, i + 0.1f)); vertices.push_back(float3(+1, -1, i + 0.1f)); } ElementInitData init_data; init_data.data = &vertices[0]; init_data.slice_pitch = init_data.row_pitch = static_cast<uint32_t>(vertices.size() * sizeof(vertices[0])); GraphicsBufferPtr pos_vb = rf.MakeVertexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data); rl_->BindVertexStream(pos_vb, std::make_tuple(vertex_element(VEU_Position, 0, EF_BGR32F))); std::vector<uint32_t> indices; for (int i = 0; i < SUN_FLARENUM; ++ i) { indices.push_back(i * 4 + 2); indices.push_back(i * 4 + 0); indices.push_back(i * 4 + 1); indices.push_back(i * 4 + 1); indices.push_back(i * 4 + 3); indices.push_back(i * 4 + 2); } init_data.data = &indices[0]; init_data.slice_pitch = init_data.row_pitch = static_cast<uint32_t>(indices.size() * sizeof(indices[0])); GraphicsBufferPtr ib = rf.MakeIndexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data); rl_->BindIndexStream(ib, EF_R32UI); simple_forward_tech_ = SyncLoadRenderEffect("LensFlare.fxml")->TechniqueByName("LensFlare"); technique_ = simple_forward_tech_; effect_attrs_ |= EA_SimpleForward; }
RenderableSkyBox::RenderableSkyBox() : RenderableHelper(L"SkyBox") { RenderFactory& rf = Context::Instance().RenderFactoryInstance(); RenderEffectPtr effect = SyncLoadRenderEffect("SkyBox.fxml"); if (deferred_effect_) { this->BindDeferredEffect(effect); depth_tech_ = effect->TechniqueByName("DepthSkyBoxTech"); gbuffer_rt0_tech_ = effect->TechniqueByName("GBufferSkyBoxRT0Tech"); gbuffer_rt1_tech_ = effect->TechniqueByName("GBufferSkyBoxRT1Tech"); gbuffer_mrt_tech_ = effect->TechniqueByName("GBufferSkyBoxMRTTech"); special_shading_tech_ = effect->TechniqueByName("SkyBoxTech"); this->Technique(gbuffer_rt0_tech_); effect_attrs_ |= EA_SpecialShading; } else { this->Technique(effect->TechniqueByName("SkyBoxTech")); } float3 xyzs[] = { float3(1.0f, 1.0f, 1.0f), float3(1.0f, -1.0f, 1.0f), float3(-1.0f, 1.0f, 1.0f), float3(-1.0f, -1.0f, 1.0f), }; ElementInitData init_data; init_data.row_pitch = sizeof(xyzs); init_data.slice_pitch = 0; init_data.data = xyzs; rl_ = rf.MakeRenderLayout(); rl_->TopologyType(RenderLayout::TT_TriangleStrip); GraphicsBufferPtr vb = rf.MakeVertexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data); rl_->BindVertexStream(vb, make_tuple(vertex_element(VEU_Position, 0, EF_BGR32F))); pos_aabb_ = MathLib::compute_aabbox(&xyzs[0], &xyzs[4]); tc_aabb_ = AABBox(float3(0, 0, 0), float3(0, 0, 0)); }
MultiResLayer::MultiResLayer() { RenderFactory& rf = Context::Instance().RenderFactoryInstance(); { rl_quad_ = rf.MakeRenderLayout(); rl_quad_->TopologyType(RenderLayout::TT_TriangleStrip); float3 pos[] = { float3(+1, +1, 1), float3(-1, +1, 1), float3(+1, -1, 1), float3(-1, -1, 1) }; ElementInitData init_data; init_data.row_pitch = static_cast<uint32_t>(sizeof(pos)); init_data.slice_pitch = 0; init_data.data = &pos[0]; rl_quad_->BindVertexStream(rf.MakeVertexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data), make_tuple(vertex_element(VEU_Position, 0, EF_BGR32F))); } gbuffer_to_depth_derivate_pp_ = SyncLoadPostProcess("MultiRes.ppml", "GBuffer2DepthDerivate"); depth_derivate_mipmap_pp_ = SyncLoadPostProcess("MultiRes.ppml", "DepthDerivateMipMap"); gbuffer_to_normal_cone_pp_ = SyncLoadPostProcess("MultiRes.ppml", "GBuffer2NormalCone"); normal_cone_mipmap_pp_ = SyncLoadPostProcess("MultiRes.ppml", "NormalConeMipMap"); RenderEffectPtr subsplat_stencil_effect = SyncLoadRenderEffect("MultiRes.fxml"); subsplat_stencil_tech_ = subsplat_stencil_effect->TechniqueByName("SetSubsplatStencil"); subsplat_cur_lower_level_param_ = subsplat_stencil_effect->ParameterByName("cur_lower_level"); subsplat_is_not_first_last_level_param_ = subsplat_stencil_effect->ParameterByName("is_not_first_last_level"); subsplat_depth_deriv_tex_param_ = subsplat_stencil_effect->ParameterByName("depth_deriv_tex"); subsplat_normal_cone_tex_param_ = subsplat_stencil_effect->ParameterByName("normal_cone_tex"); subsplat_depth_normal_threshold_param_ = subsplat_stencil_effect->ParameterByName("depth_normal_threshold"); subsplat_far_plane_param_ = subsplat_stencil_effect->ParameterByName("far_plane"); upsampling_pp_ = SyncLoadPostProcess("MultiRes.ppml", "Upsampling"); }
void TestVertexElementDeleteAndAddNode() { // Create nodes and Faces std::vector<Node<2>*> nodes; unsigned num_nodes = 6; for (unsigned i=0; i<num_nodes; i++) { double theta = 2.0*M_PI*(double)(i)/(double)(num_nodes); nodes.push_back(new Node<2>(i, false, cos(theta), sin(theta))); } // Create element VertexElement<2,2> vertex_element(0, nodes); TS_ASSERT_EQUALS(vertex_element.GetNumNodes(), 6u); vertex_element.DeleteNode(3); // Removes (-1,0) node vertex_element.DeleteNode(0); // Removes (1,0) node // Test node is removed TS_ASSERT_EQUALS(vertex_element.GetNumNodes(), 4u); // Test other nodes are updated TS_ASSERT_DELTA(vertex_element.GetNode(0)->GetPoint()[0], 0.5, 1e-9); TS_ASSERT_DELTA(vertex_element.GetNode(0)->GetPoint()[1], 0.5*sqrt(3.0), 1e-9); TS_ASSERT_DELTA(vertex_element.GetNode(1)->GetPoint()[0], -0.5, 1e-9); TS_ASSERT_DELTA(vertex_element.GetNode(1)->GetPoint()[1], 0.5*sqrt(3.0), 1e-9); TS_ASSERT_DELTA(vertex_element.GetNode(2)->GetPoint()[0], -0.5, 1e-9); TS_ASSERT_DELTA(vertex_element.GetNode(2)->GetPoint()[1], -0.5*sqrt(3.0), 1e-9); TS_ASSERT_DELTA(vertex_element.GetNode(3)->GetPoint()[0], 0.5, 1e-9); TS_ASSERT_DELTA(vertex_element.GetNode(3)->GetPoint()[1], -0.5*sqrt(3.0), 1e-9); // Add new node Node<2>* p_new_node = new Node<2>(4, false, 0.0, 0.0); vertex_element.AddNode(p_new_node, 3); // Add node at (0,0) between nodes 3 and 0 // Test node is added TS_ASSERT_EQUALS(vertex_element.GetNumNodes(), 5u); // Test other nodes are updated TS_ASSERT_DELTA(vertex_element.GetNode(0)->GetPoint()[0], 0.5, 1e-9); TS_ASSERT_DELTA(vertex_element.GetNode(0)->GetPoint()[1], 0.5*sqrt(3.0), 1e-9); TS_ASSERT_DELTA(vertex_element.GetNode(1)->GetPoint()[0], -0.5, 1e-9); TS_ASSERT_DELTA(vertex_element.GetNode(1)->GetPoint()[1], 0.5*sqrt(3.0), 1e-9); TS_ASSERT_DELTA(vertex_element.GetNode(2)->GetPoint()[0], -0.5, 1e-9); TS_ASSERT_DELTA(vertex_element.GetNode(2)->GetPoint()[1], -0.5*sqrt(3.0), 1e-9); TS_ASSERT_DELTA(vertex_element.GetNode(3)->GetPoint()[0], 0.5, 1e-9); TS_ASSERT_DELTA(vertex_element.GetNode(3)->GetPoint()[1], -0.5*sqrt(3.0), 1e-9); TS_ASSERT_DELTA(vertex_element.GetNode(4)->GetPoint()[0], 0.0, 1e-9); TS_ASSERT_DELTA(vertex_element.GetNode(4)->GetPoint()[1], 0.0, 1e-9); // Tidy up for (unsigned i=0; i<nodes.size(); i++) { delete nodes[i]; } delete p_new_node; }
// 建立渲染窗口 ///////////////////////////////////////////////////////////////////////////////// void RenderEngine::CreateRenderWindow(std::string const & name, RenderSettings& settings) { if (settings.stereo_method != STM_OculusVR) { stereo_separation_ = settings.stereo_separation; } this->DoCreateRenderWindow(name, settings); this->CheckConfig(settings); RenderDeviceCaps const & caps = this->DeviceCaps(); screen_frame_buffer_ = cur_frame_buffer_; uint32_t const screen_width = screen_frame_buffer_->Width(); uint32_t const screen_height = screen_frame_buffer_->Height(); float const screen_aspect = static_cast<float>(screen_width) / screen_height; if (!MathLib::equal(screen_aspect, static_cast<float>(settings.width) / settings.height)) { settings.width = static_cast<uint32_t>(settings.height * screen_aspect + 0.5f); } RenderFactory& rf = Context::Instance().RenderFactoryInstance(); pp_rl_ = rf.MakeRenderLayout(); pp_rl_->TopologyType(RenderLayout::TT_TriangleStrip); float2 pos[] = { float2(-1, +1), float2(+1, +1), float2(-1, -1), float2(+1, -1) }; GraphicsBufferPtr pp_pos_vb = rf.MakeVertexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, sizeof(pos), &pos[0]); pp_rl_->BindVertexStream(pp_pos_vb, std::make_tuple(vertex_element(VEU_Position, 0, EF_GR32F))); uint32_t const render_width = static_cast<uint32_t>(settings.width * default_render_width_scale_ + 0.5f); uint32_t const render_height = static_cast<uint32_t>(settings.height * default_render_height_scale_ + 0.5f); hdr_enabled_ = settings.hdr; if (settings.hdr) { hdr_pp_ = MakeSharedPtr<HDRPostProcess>(settings.fft_lens_effects); skip_hdr_pp_ = SyncLoadPostProcess("Copy.ppml", "copy"); } ppaa_enabled_ = settings.ppaa ? 1 : 0; gamma_enabled_ = settings.gamma; color_grading_enabled_ = settings.color_grading; if (settings.ppaa || settings.color_grading || settings.gamma) { for (size_t i = 0; i < 12; ++ i) { ldr_pps_[i] = SyncLoadPostProcess("PostToneMapping.ppml", "PostToneMapping" + boost::lexical_cast<std::string>(i)); } ldr_pp_ = ldr_pps_[ppaa_enabled_ * 4 + gamma_enabled_ * 2 + color_grading_enabled_]; } bool need_resize = false; if (!settings.hide_win) { need_resize = ((render_width != screen_width) || (render_height != screen_height)); resize_pps_[0] = SyncLoadPostProcess("Resizer.ppml", "bilinear"); resize_pps_[1] = MakeSharedPtr<BicubicFilteringPostProcess>(); float const scale_x = static_cast<float>(screen_width) / render_width; float const scale_y = static_cast<float>(screen_height) / render_height; float2 pos_scale; if (scale_x < scale_y) { pos_scale.x() = 1; pos_scale.y() = (scale_x * render_height) / screen_height; } else { pos_scale.x() = (scale_y * render_width) / screen_width; pos_scale.y() = 1; } for (size_t i = 0; i < 2; ++ i) { resize_pps_[i]->SetParam(0, pos_scale); } } for (int i = 0; i < 4; ++ i) { default_frame_buffers_[i] = screen_frame_buffer_; } RenderViewPtr ds_view; if (hdr_pp_ || ldr_pp_ || (settings.stereo_method != STM_None)) { ds_tex_ = this->ScreenDepthStencilTexture(); if (ds_tex_ && (screen_width == render_width) && (screen_height == render_height)) { ds_view = rf.Make2DDepthStencilRenderView(*ds_tex_, 0, 1, 0); } else { if (caps.texture_format_support(EF_D32F) || caps.texture_format_support(EF_D24S8) || caps.texture_format_support(EF_D16)) { ElementFormat fmt; if ((settings.depth_stencil_fmt != EF_Unknown) && caps.texture_format_support(settings.depth_stencil_fmt)) { fmt = settings.depth_stencil_fmt; } else { BOOST_ASSERT(caps.texture_format_support(EF_D16)); fmt = EF_D16; } ds_tex_ = rf.MakeTexture2D(render_width, render_height, 1, 1, fmt, 1, 0, EAH_GPU_Read | EAH_GPU_Write, nullptr); ds_view = rf.Make2DDepthStencilRenderView(*ds_tex_, 0, 1, 0); } else { ElementFormat fmt; if ((settings.depth_stencil_fmt != EF_Unknown) && caps.rendertarget_format_support(settings.depth_stencil_fmt, 1, 0)) { fmt = settings.depth_stencil_fmt; } else { BOOST_ASSERT(caps.rendertarget_format_support(EF_D16, 1, 0)); fmt = EF_D16; } ds_view = rf.Make2DDepthStencilRenderView(render_width, render_height, fmt, 1, 0); } } } if (settings.stereo_method != STM_None) { mono_frame_buffer_ = rf.MakeFrameBuffer(); mono_frame_buffer_->GetViewport()->camera = cur_frame_buffer_->GetViewport()->camera; ElementFormat fmt; if (caps.texture_format_support(settings.color_fmt) && caps.rendertarget_format_support(settings.color_fmt, 1, 0)) { fmt = settings.color_fmt; } else { if (caps.texture_format_support(EF_ABGR8) && caps.rendertarget_format_support(EF_ABGR8, 1, 0)) { fmt = EF_ABGR8; } else { BOOST_ASSERT(caps.texture_format_support(EF_ARGB8) && caps.rendertarget_format_support(EF_ARGB8, 1, 0)); fmt = EF_ARGB8; } } mono_tex_ = rf.MakeTexture2D(screen_width, screen_height, 1, 1, fmt, 1, 0, EAH_GPU_Read | EAH_GPU_Write, nullptr); mono_frame_buffer_->Attach(FrameBuffer::ATT_Color0, rf.Make2DRenderView(*mono_tex_, 0, 1, 0)); default_frame_buffers_[0] = default_frame_buffers_[1] = default_frame_buffers_[2] = mono_frame_buffer_; overlay_frame_buffer_ = rf.MakeFrameBuffer(); overlay_frame_buffer_->GetViewport()->camera = cur_frame_buffer_->GetViewport()->camera; overlay_tex_ = rf.MakeTexture2D(screen_width, screen_height, 1, 1, fmt, 1, 0, EAH_GPU_Read | EAH_GPU_Write, nullptr); overlay_frame_buffer_->Attach(FrameBuffer::ATT_Color0, rf.Make2DRenderView(*overlay_tex_, 0, 1, 0)); RenderViewPtr screen_size_ds_view; if (need_resize) { screen_size_ds_view = rf.Make2DDepthStencilRenderView(screen_width, screen_height, ds_view->Format(), 1, 0); } else { screen_size_ds_view = ds_view; } overlay_frame_buffer_->Attach(FrameBuffer::ATT_DepthStencil, screen_size_ds_view); } else { if (need_resize) { resize_frame_buffer_ = rf.MakeFrameBuffer(); resize_frame_buffer_->GetViewport()->camera = cur_frame_buffer_->GetViewport()->camera; ElementFormat fmt; if (caps.texture_format_support(EF_ABGR8) && caps.rendertarget_format_support(EF_ABGR8, 1, 0)) { fmt = EF_ABGR8; } else { BOOST_ASSERT(caps.texture_format_support(EF_ARGB8) && caps.rendertarget_format_support(EF_ARGB8, 1, 0)); fmt = EF_ARGB8; } resize_tex_ = rf.MakeTexture2D(render_width, render_height, 1, 1, fmt, 1, 0, EAH_GPU_Read | EAH_GPU_Write, nullptr); resize_frame_buffer_->Attach(FrameBuffer::ATT_Color0, rf.Make2DRenderView(*resize_tex_, 0, 1, 0)); ElementFormat ds_fmt; if ((settings.depth_stencil_fmt != EF_Unknown) && caps.rendertarget_format_support(settings.depth_stencil_fmt, 1, 0)) { ds_fmt = settings.depth_stencil_fmt; } else { BOOST_ASSERT(caps.rendertarget_format_support(EF_D16, 1, 0)); ds_fmt = EF_D16; } resize_frame_buffer_->Attach(FrameBuffer::ATT_DepthStencil, rf.Make2DDepthStencilRenderView(render_width, render_height, ds_fmt, 1, 0)); default_frame_buffers_[0] = default_frame_buffers_[1] = default_frame_buffers_[2] = resize_frame_buffer_; } } if (ldr_pp_) { ldr_frame_buffer_ = rf.MakeFrameBuffer(); ldr_frame_buffer_->GetViewport()->camera = cur_frame_buffer_->GetViewport()->camera; ElementFormat fmt; if (caps.texture_format_support(EF_ABGR8) && caps.rendertarget_format_support(EF_ABGR8, 1, 0)) { fmt = EF_ABGR8; } else { BOOST_ASSERT(caps.texture_format_support(EF_ARGB8) && caps.rendertarget_format_support(EF_ARGB8, 1, 0)); fmt = EF_ARGB8; } ElementFormat fmt_srgb = MakeSRGB(fmt); if (caps.texture_format_support(fmt_srgb) && caps.rendertarget_format_support(fmt_srgb, 1, 0)) { fmt = fmt_srgb; } ldr_tex_ = rf.MakeTexture2D(render_width, render_height, 1, 1, fmt, 1, 0, EAH_GPU_Read | EAH_GPU_Write, nullptr); ldr_frame_buffer_->Attach(FrameBuffer::ATT_Color0, rf.Make2DRenderView(*ldr_tex_, 0, 1, 0)); ldr_frame_buffer_->Attach(FrameBuffer::ATT_DepthStencil, ds_view); default_frame_buffers_[0] = default_frame_buffers_[1] = ldr_frame_buffer_; } if (hdr_pp_) { hdr_frame_buffer_ = rf.MakeFrameBuffer(); hdr_frame_buffer_->GetViewport()->camera = cur_frame_buffer_->GetViewport()->camera; ElementFormat fmt; if (caps.fp_color_support) { if (caps.texture_format_support(EF_B10G11R11F) && caps.rendertarget_format_support(EF_B10G11R11F, 1, 0)) { fmt = EF_B10G11R11F; } else { BOOST_ASSERT(caps.texture_format_support(EF_ABGR16F) && caps.rendertarget_format_support(EF_ABGR16F, 1, 0)); fmt = EF_ABGR16F; } } else { if (caps.texture_format_support(EF_ABGR8) && caps.rendertarget_format_support(EF_ABGR8, 1, 0)) { fmt = EF_ABGR8; } else { BOOST_ASSERT(caps.texture_format_support(EF_ARGB8) && caps.rendertarget_format_support(EF_ARGB8, 1, 0)); fmt = EF_ARGB8; } ElementFormat fmt_srgb = MakeSRGB(fmt); if (caps.rendertarget_format_support(fmt_srgb, 1, 0)) { fmt = fmt_srgb; } } hdr_tex_ = rf.MakeTexture2D(render_width, render_height, 4, 1, fmt, 1, 0, EAH_GPU_Read | EAH_GPU_Write | EAH_Generate_Mips, nullptr); hdr_frame_buffer_->Attach(FrameBuffer::ATT_Color0, rf.Make2DRenderView(*hdr_tex_, 0, 1, 0)); hdr_frame_buffer_->Attach(FrameBuffer::ATT_DepthStencil, ds_view); default_frame_buffers_[0] = hdr_frame_buffer_; } this->BindFrameBuffer(default_frame_buffers_[0]); this->Stereo(settings.stereo_method); #ifndef KLAYGE_SHIP PerfProfiler& profiler = PerfProfiler::Instance(); hdr_pp_perf_ = profiler.CreatePerfRange(0, "HDR PP"); ldr_pp_perf_ = profiler.CreatePerfRange(0, "LDR PP"); resize_pp_perf_ = profiler.CreatePerfRange(0, "Resize PP"); stereoscopic_pp_perf_ = profiler.CreatePerfRange(0, "Stereoscopic PP"); #endif }
RenderDecal::RenderDecal(TexturePtr const & normal_tex, TexturePtr const & diffuse_tex, float3 const & diffuse_clr, TexturePtr const & specular_tex, float3 const & specular_level, float shininess) : RenderableHelper(L"Decal") { this->BindDeferredEffect(SyncLoadRenderEffect("Decal.fxml")); gbuffer_alpha_test_rt0_tech_ = deferred_effect_->TechniqueByName("DecalGBufferAlphaTestRT0Tech"); gbuffer_alpha_test_rt1_tech_ = deferred_effect_->TechniqueByName("DecalGBufferAlphaTestRT1Tech"); gbuffer_alpha_test_mrt_tech_ = deferred_effect_->TechniqueByName("DecalGBufferAlphaTestMRTTech"); technique_ = gbuffer_alpha_test_rt0_tech_; pos_aabb_ = AABBox(float3(-1, -1, -1), float3(1, 1, 1)); tc_aabb_ = AABBox(float3(0, 0, 0), float3(1, 1, 0)); float3 xyzs[] = { pos_aabb_.Corner(0), pos_aabb_.Corner(1), pos_aabb_.Corner(2), pos_aabb_.Corner(3), pos_aabb_.Corner(4), pos_aabb_.Corner(5), pos_aabb_.Corner(6), pos_aabb_.Corner(7) }; uint16_t indices[] = { 0, 2, 3, 3, 1, 0, 5, 7, 6, 6, 4, 5, 4, 0, 1, 1, 5, 4, 4, 6, 2, 2, 0, 4, 2, 6, 7, 7, 3, 2, 1, 3, 7, 7, 5, 1 }; RenderFactory& rf = Context::Instance().RenderFactoryInstance(); rl_ = rf.MakeRenderLayout(); rl_->TopologyType(RenderLayout::TT_TriangleList); ElementInitData init_data; init_data.row_pitch = sizeof(xyzs); init_data.slice_pitch = 0; init_data.data = xyzs; GraphicsBufferPtr vb = rf.MakeVertexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data); rl_->BindVertexStream(vb, make_tuple(vertex_element(VEU_Position, 0, EF_BGR32F))); init_data.row_pitch = sizeof(indices); init_data.slice_pitch = 0; init_data.data = indices; GraphicsBufferPtr ib = rf.MakeIndexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data); rl_->BindIndexStream(ib, EF_R16UI); model_mat_ = float4x4::Identity(); effect_attrs_ |= EA_AlphaTest; inv_mv_ep_ = technique_->Effect().ParameterByName("inv_mv"); g_buffer_rt0_tex_param_ = deferred_effect_->ParameterByName("g_buffer_rt0_tex"); normal_tex_ = normal_tex; diffuse_tex_ = diffuse_tex; diffuse_clr_ = diffuse_clr; specular_tex_ = specular_tex; specular_level_ = specular_level.x(); shininess_ = shininess; }
RenderablePlane::RenderablePlane(float length, float width, int length_segs, int width_segs, bool has_tex_coord, bool has_tangent) : RenderableHelper(L"RenderablePlane") { RenderFactory& rf = Context::Instance().RenderFactoryInstance(); rl_ = rf.MakeRenderLayout(); rl_->TopologyType(RenderLayout::TT_TriangleList); std::vector<int16_t> positions; for (int y = 0; y < width_segs + 1; ++ y) { for (int x = 0; x < length_segs + 1; ++ x) { float3 pos(static_cast<float>(x) / length_segs, 1 - (static_cast<float>(y) / width_segs), 0.5f); int16_t s_pos[4] = { static_cast<int16_t>(MathLib::clamp<int32_t>(static_cast<int32_t>(pos.x() * 65535 - 32768), -32768, 32767)), static_cast<int16_t>(MathLib::clamp<int32_t>(static_cast<int32_t>(pos.y() * 65535 - 32768), -32768, 32767)), static_cast<int16_t>(MathLib::clamp<int32_t>(static_cast<int32_t>(pos.z() * 65535 - 32768), -32768, 32767)), 32767 }; positions.push_back(s_pos[0]); positions.push_back(s_pos[1]); positions.push_back(s_pos[2]); positions.push_back(s_pos[3]); } } ElementInitData init_data; init_data.row_pitch = static_cast<uint32_t>(positions.size() * sizeof(positions[0])); init_data.slice_pitch = 0; init_data.data = &positions[0]; GraphicsBufferPtr pos_vb = rf.MakeVertexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data); rl_->BindVertexStream(pos_vb, make_tuple(vertex_element(VEU_Position, 0, EF_SIGNED_ABGR16))); if (has_tex_coord) { std::vector<int16_t> tex_coords; for (int y = 0; y < width_segs + 1; ++ y) { for (int x = 0; x < length_segs + 1; ++ x) { float3 tex_coord(static_cast<float>(x) / length_segs * 0.5f + 0.5f, static_cast<float>(y) / width_segs * 0.5f + 0.5f, 0.5f); int16_t s_tc[2] = { static_cast<int16_t>(MathLib::clamp<int32_t>(static_cast<int32_t>(tex_coord.x() * 65535 - 32768), -32768, 32767)), static_cast<int16_t>(MathLib::clamp<int32_t>(static_cast<int32_t>(tex_coord.y() * 65535 - 32768), -32768, 32767)), }; tex_coords.push_back(s_tc[0]); tex_coords.push_back(s_tc[1]); } } init_data.row_pitch = static_cast<uint32_t>(tex_coords.size() * sizeof(tex_coords[0])); init_data.slice_pitch = 0; init_data.data = &tex_coords[0]; GraphicsBufferPtr tex_vb = rf.MakeVertexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data); rl_->BindVertexStream(tex_vb, make_tuple(vertex_element(VEU_TextureCoord, 0, EF_SIGNED_GR16))); } if (has_tangent) { std::vector<uint32_t> tangent(positions.size() / 4); ElementFormat fmt; if (rf.RenderEngineInstance().DeviceCaps().vertex_format_support(EF_ABGR8)) { fmt = EF_ABGR8; tangent.assign(tangent.size(), 0x807F7FFE); } else { BOOST_ASSERT(rf.RenderEngineInstance().DeviceCaps().vertex_format_support(EF_ARGB8)); fmt = EF_ARGB8; tangent.assign(tangent.size(), 0x80FE7F7F); } init_data.row_pitch = static_cast<uint32_t>(tangent.size() * sizeof(tangent[0])); init_data.slice_pitch = 0; init_data.data = &tangent[0]; GraphicsBufferPtr tex_vb = rf.MakeVertexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data); rl_->BindVertexStream(tex_vb, make_tuple(vertex_element(VEU_Tangent, 0, fmt))); } std::vector<uint16_t> index; for (int y = 0; y < width_segs; ++ y) { for (int x = 0; x < length_segs; ++ x) { index.push_back(static_cast<uint16_t>((y + 0) * (length_segs + 1) + (x + 0))); index.push_back(static_cast<uint16_t>((y + 0) * (length_segs + 1) + (x + 1))); index.push_back(static_cast<uint16_t>((y + 1) * (length_segs + 1) + (x + 1))); index.push_back(static_cast<uint16_t>((y + 1) * (length_segs + 1) + (x + 1))); index.push_back(static_cast<uint16_t>((y + 1) * (length_segs + 1) + (x + 0))); index.push_back(static_cast<uint16_t>((y + 0) * (length_segs + 1) + (x + 0))); } } init_data.row_pitch = static_cast<uint32_t>(index.size() * sizeof(index[0])); init_data.slice_pitch = 0; init_data.data = &index[0]; GraphicsBufferPtr ib = rf.MakeIndexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data); rl_->BindIndexStream(ib, EF_R16UI); pos_aabb_ = AABBox(float3(-length / 2, -width / 2, 0), float3(+length / 2, +width / 2, 0)); tc_aabb_ = AABBox(float3(0, 0, 0), float3(1, 1, 0)); }
MultiResSILLayer::MultiResSILLayer() { RenderFactory& rf = Context::Instance().RenderFactoryInstance(); RenderEngine& re = rf.RenderEngineInstance(); RenderDeviceCaps const & caps = re.DeviceCaps(); { rl_quad_ = rf.MakeRenderLayout(); rl_quad_->TopologyType(RenderLayout::TT_TriangleStrip); std::vector<float3> pos; std::vector<uint16_t> index; pos.push_back(float3(+1, +1, 1)); pos.push_back(float3(-1, +1, 1)); pos.push_back(float3(+1, -1, 1)); pos.push_back(float3(-1, -1, 1)); ElementInitData init_data; init_data.row_pitch = static_cast<uint32_t>(pos.size() * sizeof(pos[0])); init_data.slice_pitch = 0; init_data.data = &pos[0]; rl_quad_->BindVertexStream(rf.MakeVertexBuffer(BU_Static, EAH_GPU_Read | EAH_Immutable, &init_data), make_tuple(vertex_element(VEU_Position, 0, EF_BGR32F))); } vpl_tex_ = rf.MakeTexture2D(VPL_COUNT, 4, 1, 1, EF_ABGR16F, 1, 0, EAH_GPU_Read | EAH_GPU_Write, nullptr); gbuffer_to_depth_derivate_pp_ = SyncLoadPostProcess("MultiRes.ppml", "GBuffer2DepthDerivate"); depth_derivate_mipmap_pp_ = SyncLoadPostProcess("MultiRes.ppml", "DepthDerivateMipMap"); gbuffer_to_normal_cone_pp_ = SyncLoadPostProcess("MultiRes.ppml", "GBuffer2NormalCone"); normal_cone_mipmap_pp_ = SyncLoadPostProcess("MultiRes.ppml", "NormalConeMipMap"); RenderEffectPtr subsplat_stencil_effect = SyncLoadRenderEffect("MultiRes.fxml"); subsplat_stencil_tech_ = subsplat_stencil_effect->TechniqueByName("SetSubsplatStencil"); subsplat_cur_lower_level_param_ = subsplat_stencil_effect->ParameterByName("cur_lower_level"); subsplat_is_not_first_last_level_param_ = subsplat_stencil_effect->ParameterByName("is_not_first_last_level"); subsplat_depth_deriv_tex_param_ = subsplat_stencil_effect->ParameterByName("depth_deriv_tex"); subsplat_normal_cone_tex_param_ = subsplat_stencil_effect->ParameterByName("normal_cone_tex"); subsplat_depth_normal_threshold_param_ = subsplat_stencil_effect->ParameterByName("depth_normal_threshold"); RenderEffectPtr vpls_lighting_effect = SyncLoadRenderEffect("VPLsLighting.fxml"); vpls_lighting_instance_id_tech_ = vpls_lighting_effect->TechniqueByName("VPLsLightingInstanceID"); vpls_lighting_no_instance_id_tech_ = vpls_lighting_effect->TechniqueByName("VPLsLightingNoInstanceID"); vpl_view_param_ = vpls_lighting_effect->ParameterByName("view"); vpl_proj_param_ = vpls_lighting_effect->ParameterByName("proj"); vpl_depth_near_far_invfar_param_ = vpls_lighting_effect->ParameterByName("depth_near_far_invfar"); vpl_light_pos_es_param_ = vpls_lighting_effect->ParameterByName("light_pos_es"); vpl_light_color_param_ = vpls_lighting_effect->ParameterByName("light_color"); vpl_light_falloff_param_ = vpls_lighting_effect->ParameterByName("light_falloff"); vpl_x_coord_param_ = vpls_lighting_effect->ParameterByName("x_coord"); vpl_gbuffer_tex_param_ = vpls_lighting_effect->ParameterByName("gbuffer_tex"); vpl_depth_tex_param_ = vpls_lighting_effect->ParameterByName("depth_tex"); *(vpls_lighting_effect->ParameterByName("vpls_tex")) = vpl_tex_; *(vpls_lighting_effect->ParameterByName("vpl_params")) = float2(1.0f / VPL_COUNT, 0.5f / VPL_COUNT); upsampling_pp_ = SyncLoadPostProcess("MultiRes.ppml", "Upsampling"); rl_vpl_ = SyncLoadModel("indirect_light_proxy.meshml", EAH_GPU_Read | EAH_Immutable, CreateModelFactory<RenderModel>(), CreateMeshFactory<StaticMesh>())->Mesh(0)->GetRenderLayout(); if (caps.instance_id_support) { rl_vpl_->NumInstances(VPL_COUNT); } }