/** * Begin a rendering pass * * @param inPassName The rendering pass */ void RenderManager::BeginRendering(RenderPass inPass) { // Create any additional render states here static DepthStencilState noZNoStencil= DepthStencilState(false, false, CMP_Always, false, STENCILOP_Keep, STENCILOP_Keep, STENCILOP_Keep, CMP_Always, 0); static BlendState alphaBlend = BlendState(true, BLENDOP_Add, WEIGHT_SrcAlpha, WEIGHT_InvSrcAlpha, BLENDOP_Add, WEIGHT_SrcAlpha, WEIGHT_InvSrcAlpha,false, true, true, true, true); static BlendState additiveColorBlend = BlendState(true, BLENDOP_Add, WEIGHT_One, WEIGHT_One, BLENDOP_Add, WEIGHT_One, WEIGHT_Zero,false, true, true, true, true); switch(inPass) { case RENDERPASS_Geometry: gRenderAPI->BeginPerfEvent("Geometry Pass"); gRenderAPI->SetViewport(0,0,fullScreenBufferSizeX,fullScreenBufferSizeY); gRenderAPI->SetRenderBuffers(gBuffer, defaultSceneDepthBuffer); gRenderAPI->SetDepthStencilState(DepthStencilState::Default); gRenderAPI->SetBlendState(BlendState::Default); gRenderAPI->SetRasterizerState(RasterizerState::Default); gRenderAPI->Clear(true, ColorVector(0.0,0.0,0.0), true, 1.f); break; case RENDERPASS_Lighting: gRenderAPI->BeginPerfEvent("Lighting Pass"); gRenderAPI->SetViewport(0,0,fullScreenBufferSizeX,fullScreenBufferSizeY); gRenderAPI->SetRenderBuffers(defaultSceneColorBuffer, NULL); gRenderAPI->SetDepthStencilState(noZNoStencil); gRenderAPI->SetBlendState(additiveColorBlend); gRenderAPI->SetRasterizerState(RasterizerState::Default); gRenderAPI->Clear(true, ColorVector(0.0,0.0,0.0), false); break; case RENDERPASS_SceneColor: gRenderAPI->BeginPerfEvent("Scene Pass"); gRenderAPI->SetViewport(0,0,fullScreenBufferSizeX,fullScreenBufferSizeY); gRenderAPI->SetRenderBuffers(defaultSceneColorBuffer, defaultSceneDepthBuffer); gRenderAPI->SetDepthStencilState(DepthStencilState::Default); gRenderAPI->SetBlendState(BlendState::Default); gRenderAPI->SetRasterizerState(RasterizerState::Default); break; case RENDERPASS_GeometryWireframe: gRenderAPI->BeginPerfEvent("Wireframe Pass"); gRenderAPI->SetViewport(0,0,fullScreenBufferSizeX,fullScreenBufferSizeY); gRenderAPI->SetRenderBuffers(gBuffer, defaultSceneDepthBuffer); gRenderAPI->SetDepthStencilState(noZNoStencil); gRenderAPI->SetBlendState(BlendState::Default); gRenderAPI->SetRasterizerState(RasterizerState::Wireframe); gRenderAPI->Clear(true, ColorVector(0.0,0.0,0.0), false); break; case RENDERPASS_UI: gRenderAPI->BeginPerfEvent("UI Pass"); gRenderAPI->SetViewport(0,0,fullScreenBufferSizeX,fullScreenBufferSizeY); gRenderAPI->SetRenderBuffers(defaultSceneColorBuffer, defaultSceneDepthBuffer); gRenderAPI->SetDepthStencilState(noZNoStencil); gRenderAPI->SetBlendState(alphaBlend); gRenderAPI->SetRasterizerState(RasterizerState::Default); break; } gRenderAPI->BeginDraw(); }
Font::Font(std::string _fontName) : m_texture("texture/"+_fontName+".png"), m_effect( "shader/font.vs", "shader/font.ps", "shader/font.gs") { m_effect.SetRasterizerState(RasterizerState(RasterizerState::CULL_MODE::NONE, RasterizerState::FILL_MODE::SOLID)); m_effect.SetBlendState(BlendState(BlendState::BLEND_OPERATION::ADD, BlendState::BLEND::SRC_ALPHA, BlendState::BLEND::INV_SRC_ALPHA)); m_effect.SetDepthStencilState(DepthStencilState(DepthStencilState::COMPARISON_FUNC::ALWAYS, false)); m_effect.BindTexture( "u_characterTex", 7, Graphic::Resources::GetSamplerState(SamplerStates::LINEAR) ); m_effect.BindUniformBuffer( Graphic::Resources::GetUBO(UniformBuffers::GLOBAL) ); Jo::Files::HDDFile file("texture/"+_fontName+".sraw"); Jo::Files::MetaFileWrapper Wrap( file, Jo::Files::Format::SRAW ); auto& PosX = Wrap.RootNode[std::string("positionX")]; auto& PosY = Wrap.RootNode[std::string("positionY")]; auto& sizeX = Wrap.RootNode[std::string("sizeX")]; auto& sizeY = Wrap.RootNode[std::string("sizeY")]; //get values for(int i = 0; i < 256; i++) { m_sizeTable[i] = Vec2(sizeX[i],sizeY[i]); // Half pixel offset necessary - otherwise rounding errors in shader m_coordTable[i] = Vec2(float(PosX[i]) + 0.5f/m_texture.Width(),PosY[i]); // m_sizeTable[i] = Vec2(1-0.01f*i,i*0.01f);//0.1; 0.25 // m_coordTable[i] = Vec2(0.f,0.25f); } }
void LightsourceSimplePass::setup(GraphicContext &gc) { Size viewport_size = viewport->get_size(); if (fb.is_null() || !gc.is_frame_buffer_owner(fb) || final_color.updated() || zbuffer.updated() || diffuse_color_gbuffer.updated()) { final_color.set(Texture2D(gc, viewport->get_width(), viewport->get_height(), tf_rgba16f)); fb = FrameBuffer(gc); fb.attach_color(0, final_color.get()); fb.attach_depth(zbuffer.get()); BlendStateDescription blend_desc; blend_desc.enable_blending(true); blend_desc.set_blend_function(blend_one, blend_one, blend_one, blend_one); blend_state = BlendState(gc, blend_desc); DepthStencilStateDescription icosahedron_depth_stencil_desc; icosahedron_depth_stencil_desc.enable_depth_write(false); icosahedron_depth_stencil_desc.enable_depth_test(true); icosahedron_depth_stencil_desc.set_depth_compare_function(compare_lequal); icosahedron_depth_stencil_state = DepthStencilState(gc, icosahedron_depth_stencil_desc); RasterizerStateDescription icosahedron_rasterizer_desc; icosahedron_rasterizer_desc.set_culled(true); icosahedron_rasterizer_state = RasterizerState(gc, icosahedron_rasterizer_desc); DepthStencilStateDescription rect_depth_stencil_desc; rect_depth_stencil_desc.enable_depth_write(false); rect_depth_stencil_desc.enable_depth_test(false); rect_depth_stencil_state = DepthStencilState(gc, rect_depth_stencil_desc); RasterizerStateDescription rect_rasterizer_desc; rect_rasterizer_desc.set_culled(false); rect_rasterizer_state = RasterizerState(gc, rect_rasterizer_desc); uniforms = UniformVector<Uniforms>(gc, 1); icosahedron_prim_array = PrimitivesArray(gc); icosahedron_prim_array.set_attributes(0, icosahedron->vertices); Vec4f positions[6] = { Vec4f(-1.0f, -1.0f, 1.0f, 1.0f), Vec4f( 1.0f, -1.0f, 1.0f, 1.0f), Vec4f(-1.0f, 1.0f, 1.0f, 1.0f), Vec4f( 1.0f, -1.0f, 1.0f, 1.0f), Vec4f(-1.0f, 1.0f, 1.0f, 1.0f), Vec4f( 1.0f, 1.0f, 1.0f, 1.0f) }; rect_positions = VertexArrayVector<Vec4f>(gc, positions, 6); rect_prim_array = PrimitivesArray(gc); rect_prim_array.set_attributes(0, rect_positions); } }
ShaderEffect::ShaderEffect(GraphicContext &gc, const ShaderEffectDescription &description) : impl(std::make_shared<ShaderEffect_Impl>(gc)) { impl->create_shaders(gc, description.impl.get()); impl->create_primitives_array(gc, description.impl.get()); impl->create_frame_buffer(gc, description.impl.get()); impl->elements = description.impl->elements; impl->elements_type = description.impl->elements_type; impl->rasterizer_state = RasterizerState(gc, description.impl->rasterizer_state); impl->blend_state = BlendState(gc, description.impl->blend_state); impl->depth_stencil_state = DepthStencilState(gc, description.impl->depth_stencil_state); }
void RenderBatchTriangle::flush(GraphicContext &gc) { if (position > 0) { gc.set_program_object(program_sprite); int gpu_index; VertexArrayVector<SpriteVertex> gpu_vertices(batch_buffer->get_vertex_buffer(gc, gpu_index)); if (prim_array[gpu_index].is_null()) { prim_array[gpu_index] = PrimitivesArray(gc); prim_array[gpu_index].set_attributes(0, gpu_vertices, cl_offsetof(SpriteVertex, position)); prim_array[gpu_index].set_attributes(1, gpu_vertices, cl_offsetof(SpriteVertex, color)); prim_array[gpu_index].set_attributes(2, gpu_vertices, cl_offsetof(SpriteVertex, texcoord)); prim_array[gpu_index].set_attributes(3, gpu_vertices, cl_offsetof(SpriteVertex, texindex)); if (glyph_blend.is_null()) { BlendStateDescription blend_desc; blend_desc.set_blend_function(blend_constant_color, blend_one_minus_src_color, blend_zero, blend_one); glyph_blend = BlendState(gc, blend_desc); } } gpu_vertices.upload_data(gc, 0, vertices, position); for (int i = 0; i < num_current_textures; i++) gc.set_texture(i, current_textures[i]); if (use_glyph_program) { gc.set_blend_state(glyph_blend, constant_color); gc.draw_primitives(type_triangles, position, prim_array[gpu_index]); gc.reset_blend_state(); } else { gc.draw_primitives(type_triangles, position, prim_array[gpu_index]); } for (int i = 0; i < num_current_textures; i++) gc.reset_texture(i); gc.reset_program_object(); position = 0; for (int i = 0; i < num_current_textures; i++) current_textures[i] = Texture2D(); num_current_textures = 0; } }
GraphicContext::GraphicContext(GraphicContextProvider *provider) : impl(new GraphicContext_Impl(provider)) { impl->default_rasterizer_state = RasterizerState(*this, RasterizerStateDescription()); impl->default_blend_state = BlendState(*this, BlendStateDescription()); impl->default_depth_stencil_state = DepthStencilState(*this, DepthStencilStateDescription()); reset_rasterizer_state(); reset_blend_state(); reset_depth_stencil_state(); }
void ParticleEmitterPass::setup(GraphicContext &gc) { if (program.is_null()) { std::string vertex_filename = PathHelp::combine(shader_path, "ParticleEmitter/vertex.hlsl"); std::string fragment_filename = PathHelp::combine(shader_path, "ParticleEmitter/fragment.hlsl"); program = ProgramObject::load(gc, vertex_filename, fragment_filename); program.bind_attribute_location(0, "AttrPosition"); program.bind_frag_data_location(0, "FragColor"); if (!program.link()) throw Exception(string_format("Particle emitter program failed to link: %1", program.get_info_log())); program.set_uniform_buffer_index("Uniforms", 0); program.set_uniform1i("NormalZTexture", 0); program.set_uniform1i("InstanceTexture", 1); program.set_uniform1i("ParticleTexture", 2); program.set_uniform1i("ParticleSampler", 2); program.set_uniform1i("ColorGradientTexture", 3); program.set_uniform1i("ColorGradientSampler", 3); billboard_positions = VertexArrayVector<Vec3f>(gc, cpu_billboard_positions, 6); } Size viewport_size = viewport->get_size(); if (fb.is_null() || !gc.is_frame_buffer_owner(fb) || final_color.updated() || zbuffer.updated()) { fb = FrameBuffer(gc); fb.attach_color(0, final_color.get()); fb.attach_depth(zbuffer.get()); BlendStateDescription blend_desc; blend_desc.enable_blending(true); blend_desc.set_blend_function(blend_src_alpha, blend_one_minus_src_alpha, blend_zero, blend_zero); blend_state = BlendState(gc, blend_desc); DepthStencilStateDescription depth_stencil_desc; depth_stencil_desc.enable_depth_write(false); depth_stencil_desc.enable_depth_test(true); depth_stencil_desc.set_depth_compare_function(compare_lequal); depth_stencil_state = DepthStencilState(gc, depth_stencil_desc); RasterizerStateDescription rasterizer_desc; rasterizer_desc.set_culled(false); rasterizer_state = RasterizerState(gc, rasterizer_desc); prim_array = PrimitivesArray(gc); prim_array.set_attributes(0, billboard_positions); } }
BloomPass::BloomPass(GraphicContext &gc, const std::string &shader_path, ResourceContainer &inout) { viewport = inout.get<Rect>("Viewport"); final_color = inout.get<Texture2D>("FinalColor"); bloom_contribution = inout.get<Texture2D>("BloomContribution"); if (gc.get_shader_language() == shader_glsl) { bloom_shader = ShaderSetup::compile(gc, "", PathHelp::combine(shader_path, "Final/vertex_present.glsl"), PathHelp::combine(shader_path, "Bloom/fragment_bloom_extract.glsl"), ""); bloom_shader.bind_frag_data_location(0, "FragColor"); } else { bloom_shader = ShaderSetup::compile(gc, "", PathHelp::combine(shader_path, "Final/vertex_present.hlsl"), PathHelp::combine(shader_path, "Bloom/fragment_bloom_extract.hlsl"), ""); } ShaderSetup::link(bloom_shader, "bloom extract program"); bloom_shader.bind_attribute_location(0, "PositionInProjection"); bloom_shader.set_uniform1i("FinalColors", 0); bloom_shader.set_uniform1i("FinalColorsSampler", 0); bloom_shader.set_uniform1i("LogAverageLight", 1); Vec4f positions[6] = { Vec4f(-1.0f, -1.0f, 1.0f, 1.0f), Vec4f( 1.0f, -1.0f, 1.0f, 1.0f), Vec4f(-1.0f, 1.0f, 1.0f, 1.0f), Vec4f( 1.0f, -1.0f, 1.0f, 1.0f), Vec4f(-1.0f, 1.0f, 1.0f, 1.0f), Vec4f( 1.0f, 1.0f, 1.0f, 1.0f) }; rect_positions = VertexArrayVector<Vec4f>(gc, positions, 6); rect_primarray = PrimitivesArray(gc); rect_primarray.set_attributes(0, rect_positions); bloom_blur.input = bloom_contribution; BlendStateDescription blend_desc; blend_desc.enable_blending(false); blend_state = BlendState(gc, blend_desc); }
App::App() { #if defined(WIN32) && !defined(__MINGW32__) clan::D3DTarget::set_current(); #else clan::OpenGLTarget::set_current(); #endif DisplayWindowDescription win_desc; win_desc.set_allow_resize(true); win_desc.set_title("Font Example Application"); win_desc.set_size(Size( 1000, 700 ), false); window = DisplayWindow(win_desc); slots.connect(window.sig_window_close(), this, &App::on_window_close); slots.connect(window.get_keyboard().sig_key_up(), this, &App::on_input_up); clan::XMLResourceFactory::set_display(); resources = clan::XMLResourceManager::create(clan::XMLResourceDocument("Resources/resources.xml")); canvas = Canvas(window); clan::Texture2D gui_texture = clan::Texture2D(canvas, (int)std::round(250 * canvas.get_pixel_ratio()), (int)std::round(500 * canvas.get_pixel_ratio())); gui_texture.set_pixel_ratio(canvas.get_pixel_ratio()); gui_image = clan::Image(gui_texture, gui_texture.get_size()); clan::FrameBuffer gui_framebuffer = clan::FrameBuffer(canvas); gui_framebuffer.attach_color(0, gui_texture); gui_canvas = clan::Canvas(canvas, gui_framebuffer); clan::FileResourceDocument doc(clan::FileSystem("../../ThemeAero")); clan::ResourceManager resources = clan::FileResourceManager::create(doc); ui_thread = clan::UIThread(resources); root = std::make_shared<clan::TextureWindow>(gui_canvas); root->set_window(window); root->set_viewport(gui_image.get_size()); int offset_x = 10; int offset_y = 8; int width = 220; int small_width = 70; int height = 20; const int gap = 38; auto button_class_system = Theme::create_button(); button_class_system->style()->set("position: absolute; left:%1px; top:%2px; width:%3px; height:auto;", offset_x, offset_y, width); button_class_system->func_clicked() = clan::bind_member(this, &App::on_button_clicked_class_system); button_class_system->label()->set_text("Class: System"); root->add_child(button_class_system); offset_y += gap; auto button_class_sprite = Theme::create_button(); button_class_sprite->style()->set("position: absolute; left:%1px; top:%2px; width:%3px; height:auto;", offset_x, offset_y, width); button_class_sprite->func_clicked() = bind_member(this, &App::on_button_clicked_class_sprite); button_class_sprite->label()->set_text("Class: Sprite"); root->add_child(button_class_sprite); offset_y += gap; button_typeface_tahoma = Theme::create_button(); button_typeface_tahoma->style()->set("position: absolute; left:%1px; top:%2px; width:%3px; height:auto;", offset_x, offset_y, width); button_typeface_tahoma->func_clicked() = bind_member(this, &App::on_button_clicked_typeface_tahoma); button_typeface_tahoma->label()->set_text("Typeface: Tahoma"); root->add_child(button_typeface_tahoma); offset_y += gap; button_typeface_sans = Theme::create_button(); button_typeface_sans->style()->set("position: absolute; left:%1px; top:%2px; width:%3px; height:auto;", offset_x, offset_y, width); button_typeface_sans->func_clicked() = bind_member(this, &App::on_button_clicked_typeface_sans); button_typeface_sans->label()->set_text("Typeface: Microsoft Sans Serif"); root->add_child(button_typeface_sans); offset_y += gap; button_typeface_bitstream = Theme::create_button(); button_typeface_bitstream->style()->set("position: absolute; left:%1px; top:%2px; width:%3px; height:auto;", offset_x, offset_y, width); button_typeface_bitstream->func_clicked() = bind_member(this, &App::on_button_clicked_typeface_bitstream); button_typeface_bitstream->label()->set_text("Typeface: Bitstream Vera Sans"); root->add_child(button_typeface_bitstream); offset_y += gap; checkbox_italic = Theme::create_checkbox(); checkbox_italic->style()->set("position: absolute; left:%1px; top:%2px", offset_x, offset_y); checkbox_italic->func_state_changed() = bind_member(this, &App::on_checkbox_state_italic); root->add_child(checkbox_italic); auto label = Theme::create_label(); label->set_text("Italic"); label->style()->set("position: absolute; left:%1px; top:%2px", offset_x + 16, offset_y - 3); root->add_child(label); checkbox_antialias = Theme::create_checkbox(); checkbox_antialias->set_check(true); checkbox_antialias->style()->set("position: absolute; left:%1px; top:%2px", offset_x + 100, offset_y); checkbox_antialias->func_state_changed() = bind_member(this, &App::on_checkbox_state_antialias); root->add_child(checkbox_antialias); label = Theme::create_label(); label->set_text("Anti Alias"); label->style()->set("position: absolute; left:%1px; top:%2px", offset_x + 100+ 16, offset_y - 3); root->add_child(label); offset_y += gap; checkbox_subpixel = Theme::create_checkbox(); checkbox_subpixel->set_check(true); checkbox_subpixel->style()->set("position: absolute; left:%1px; top:%2px", offset_x, offset_y); checkbox_subpixel->func_state_changed() = bind_member(this, &App::on_checkbox_state_subpixel); root->add_child(checkbox_subpixel); label = Theme::create_label(); label->set_text("SubPixel Rendering"); label->style()->set("position: absolute; left:%1px; top:%2px", offset_x + 16, offset_y - 3); root->add_child(label); offset_y += gap; auto button_weight_light = Theme::create_button(); button_weight_light->style()->set("position: absolute; left:%1px; top:%2px; width:%3px; height:auto;", offset_x, offset_y, small_width); button_weight_light->func_clicked() = bind_member(this, &App::on_button_clicked_weight_light); button_weight_light->label()->set_text("Light"); root->add_child(button_weight_light); auto button_weight_normal = Theme::create_button(); button_weight_normal->style()->set("position: absolute; left:%1px; top:%2px; width:%3px; height:auto;", offset_x + small_width + 5, offset_y, small_width); button_weight_normal->func_clicked() = bind_member(this, &App::on_button_clicked_weight_normal); button_weight_normal->label()->set_text("Normal"); root->add_child(button_weight_normal); auto button_weight_bold = Theme::create_button(); button_weight_bold->style()->set("position: absolute; left:%1px; top:%2px; width:%3px; height:auto;", offset_x + (small_width + 5) * 2, offset_y, small_width); button_weight_bold->func_clicked() = bind_member(this, &App::on_button_clicked_weight_bold); button_weight_bold->label()->set_text("Bold"); root->add_child(button_weight_bold); offset_y += gap; auto button_size_16 = Theme::create_button(); button_size_16->style()->set("position: absolute; left:%1px; top:%2px; width:%3px; height:auto;", offset_x, offset_y, small_width); button_size_16->func_clicked() = bind_member(this, &App::on_button_clicked_size_16); button_size_16->label()->set_text("Size 16"); root->add_child(button_size_16); auto button_size_32 = Theme::create_button(); button_size_32->style()->set("position: absolute; left:%1px; top:%2px; width:%3px; height:auto;", offset_x + small_width + 5, offset_y, small_width); button_size_32->func_clicked() = bind_member(this, &App::on_button_clicked_size_32); button_size_32->label()->set_text("Size 32"); root->add_child(button_size_32); auto button_size_64 = Theme::create_button(); button_size_64->style()->set("position: absolute; left:%1px; top:%2px; width:%3px; height:auto;", offset_x + (small_width + 5) * 2, offset_y, small_width); button_size_64->func_clicked() = bind_member(this, &App::on_button_clicked_size_64); button_size_64->label()->set_text("Size 64"); root->add_child(button_size_64); offset_y += gap + 8; lineedit_text = std::make_shared<clan::TextFieldView>(); lineedit_text->style()->set("font: 11px/20px 'Segoe UI'"); lineedit_text->style()->set("margin: 5px"); lineedit_text->style()->set("background: #efefef"); lineedit_text->style()->set("border: 1px solid black"); lineedit_text->style()->set("border-radius: 3px"); lineedit_text->style()->set("padding: 2px 5px 2px 5px"); lineedit_text->style()->set("width: 128px"); lineedit_text->style()->set("box-shadow: 0 0 5px rgba(100,100,200,0.2)"); lineedit_text->style()->set("position: absolute; left:%1px; top:%2px; width:%3px; height:auto;", offset_x, offset_y, width); font_text = "Ω(The quick brown fox 0123456789)"; lineedit_text->set_text(font_text); slots.connect(lineedit_text->sig_selection_changed(), bind_member(this, &App::on_lineedit_changed)); root->add_child(lineedit_text); last_fps = 0.0f; selected_fontclass = font_ttf; font_typeface = "Microsoft Sans Serif"; font_filename = ""; font_desc.set_height(32); font_desc.set_weight(clan::FontWeight::normal); select_font(); small_font = clan::Font("Tahoma", 16); premultiply_src_blend = BlendState(canvas, BlendStateDescription::blend(true)); game_time.reset(); }
BlendState BlendState::disabled() { return BlendState(); }
RenderPass RenderStage::createRenderPassFromJson(const JSONValue& renderPassJSON) { GraphicSystem& graphicSystem = renderer.getGraphicSystem(); RenderPass renderPass; auto clearColorJSON = renderPassJSON.getJSONValue("clearColor"); auto colorWriteJSON = renderPassJSON.getJSONValue("colorWrite"); auto depthWriteJSON = renderPassJSON.getJSONValue("depthWrite"); auto renderTargetLayerJSON = renderPassJSON.getJSONValue("renderTargetLayer"); auto flagsJSON = renderPassJSON.getJSONValue("flags"); if(!clearColorJSON.isNull()) renderPass.clearColor = clearColorJSON.getVector4(); if(!colorWriteJSON.isNull()) renderPass.colorWrite = colorWriteJSON.getBool(); if(!depthWriteJSON.isNull()) renderPass.depthWrite = depthWriteJSON.getBool(); if(!renderTargetLayerJSON.isNull()) renderPass.renderTargetLayer = renderTargetLayerJSON.getInt(); if(!flagsJSON.isNull()) { unsigned int flags = 0; for(unsigned int i = 0; i < flagsJSON.getSize(); ++i) { if(flagsJSON.getJSONArrayItem(i).getString().compare("CLEAR_COLOR") == 0) flags |= CLEAR_COLOR; if(flagsJSON.getJSONArrayItem(i).getString().compare("CLEAR_DEPTH") == 0) flags |= CLEAR_DEPTH; } renderPass.flags = flags; } auto viewPortJSON = renderPassJSON.getJSONValue("viewPort"); if(!viewPortJSON.isNull()) { FixedArray<int, 4> viewPort = viewPortJSON.getInt4(); renderPass.viewPort.set(viewPort[0], viewPort[1], viewPort[2], viewPort[3]); } else renderPass.viewPort = renderer.getScreenViewPort(); auto renderTargetJSON = renderPassJSON.getJSONValue("renderTarget"); renderPass.renderTarget = graphicSystem.createRenderTarget(renderTargetJSON); auto shaderPasses = renderPassJSON.getJSONValue("shaderPasses"); if(!shaderPasses.isNull()) { for(unsigned int i = 0; i < shaderPasses.getSize(); ++i) { auto shaderPassJSON = shaderPasses.getJSONArrayItem(i); auto programJSON = shaderPassJSON.getJSONValue("shaderProgram"); auto vertexDataJSON = shaderPassJSON.getJSONValue("vertexData"); auto rasterStateJSON = shaderPassJSON.getJSONValue("rasterState"); auto shaderParameterBlocksJSON = shaderPassJSON.getJSONValue("shaderParameterBlocks"); auto texturesJSON = shaderPassJSON.getJSONValue("textures"); ShaderPass shaderPass; if(!vertexDataJSON.isNull()) { if(vertexDataJSON.getString().compare("fullScreenQuad") == 0) shaderPass.vertexData = renderer.getFullScreenQuad(); } if(!rasterStateJSON.isNull()) { auto blendFunctionJSON = rasterStateJSON.getJSONValue("blendFunction"); auto compareFunctionJSON = rasterStateJSON.getJSONValue("compareFunction"); auto cullFaceJSON = rasterStateJSON.getJSONValue("cullFace"); auto blendState = !blendFunctionJSON.isNull() ? BlendState(true, enumFromString<BlendFunction>(blendFunctionJSON.getString())) : BlendState(false, BlendFunction::Replace); auto compareState = !compareFunctionJSON.isNull() ? CompareState(true, enumFromString<CompareFunction>(compareFunctionJSON.getString())) : CompareState(false, CompareFunction::Never); auto cullState = !cullFaceJSON.isNull() ? CullState(true, enumFromString<CullFace>(cullFaceJSON.getString())) : CullState(false, CullFace::Back); shaderPass.rasterState = RasterState(blendState, compareState, cullState); } if(!shaderParameterBlocksJSON.isNull()) { for(unsigned int j = 0; j < shaderParameterBlocksJSON.getSize(); ++j) { ShaderParameterBlock* block = graphicSystem.createShaderParameterBlock(shaderParameterBlocksJSON.getJSONArrayItem(j)); if(block) shaderPass.shaderParameterBlocks.pushBack(block); } } if(!texturesJSON.isNull()) { for(unsigned int j = 0; j < texturesJSON.getSize(); ++j) { Texture* texture = graphicSystem.createTexture(texturesJSON.getJSONArrayItem(j)); if(texture) shaderPass.textures.pushBack(texture); } } if(!programJSON.isNull()) shaderPass.program = graphicSystem.createShaderProgram(programJSON); renderPass.shaderPasses.pushBack(shaderPass); } } return renderPass; }