PRIVATE void add_rect_path(SvgRectRenderObject* render_object, GraphicsPath* path){
	COORDINATE x, y;
	LENGTH width, height, rx, ry;
	return_if_fail(render_object);
	width = svg_rect_render_object_get_width(render_object);
	height = svg_rect_render_object_get_height(render_object);
	x = svg_rect_render_object_get_x(render_object);
	y = svg_rect_render_object_get_y(render_object);
	rx = svg_rect_render_object_get_rx(render_object);
	ry = svg_rect_render_object_get_ry(render_object);
	ADJUST_X(width);
	ADJUST_Y(height);
	ADJUST_X(x);
	ADJUST_Y(y);
	ADJUST_X(rx);
	ADJUST_Y(ry);
	if(rx.number == 0 || ry.number == 0){
		rx.number = ry.number = 0;
	}else{
		if(rx.number > width.number / 2){
			rx.number = width.number / 2;
		}
		if(ry.number > height.number / 2){
			ry.number = height.number / 2;
		}
	}
	path->StartFigure();
	path->AddLine(x.number + rx.number, y.number, x.number + width.number - rx.number, y.number);//top border
	path->AddArc(x.number + width.number - 2 * rx.number, y.number, 2 * rx.number, 2 * ry.number, -90, 90);//top right corner
	path->AddLine(x.number + width.number, y.number + ry.number, x.number + width.number, y.number + height.number - ry.number);//right border
	path->AddArc(x.number + width.number - 2 * rx.number, y.number + height.number - 2 * ry.number, 2 * rx.number, 2 * ry.number, 0, 90);//bottom right corner
	path->AddLine(x.number + width.number - rx.number, y.number + height.number, x.number + rx.number, y.number + height.number);//bottom border
	path->AddArc(x.number, y.number + height.number - 2 * ry.number, 2 * rx.number, 2 * ry.number, 90, 90);//bottom left corner
	path->AddLine(x.number, y.number + height.number - ry.number, x.number, y.number + ry.number);//left border
	path->AddArc(x.number, y.number, 2 * rx.number, 2 * ry.number, -180, 90);//top left corner
	path->CloseFigure();
}
Exemple #2
0
namespace Falcor
{
    bool checkForViewportArray2Support()
    {
#ifdef FALCOR_D3D
        return false;
#elif defined FALCOR_VK
        return false;
#else
#error Unknown API
#endif
    }
    struct Vertex
    {
        glm::vec2 screenPos;
        glm::vec2 texCoord;
    };

    Buffer::SharedPtr FullScreenPass::spVertexBuffer;
    Vao::SharedPtr FullScreenPass::spVao;
    uint64_t FullScreenPass::sObjectCount = 0;

#ifdef FALCOR_VK
#define ADJUST_Y(a) (-(a))
#else
#define ADJUST_Y(a) a
#endif

    static const Vertex kVertices[] =
    {
        {glm::vec2(-1, ADJUST_Y( 1)), glm::vec2(0, 0)},
        {glm::vec2(-1, ADJUST_Y(-1)), glm::vec2(0, 1)},
        {glm::vec2( 1, ADJUST_Y( 1)), glm::vec2(1, 0)},
        {glm::vec2( 1, ADJUST_Y(-1)), glm::vec2(1, 1)},
    };
#undef ADJUST_Y

    static void initStaticObjects(Buffer::SharedPtr& pVB, Vao::SharedPtr& pVao)
    {
        // First time we got here. create VB and VAO
        const uint32_t vbSize = (uint32_t)(sizeof(Vertex)*arraysize(kVertices));
        pVB = Buffer::create(vbSize, Buffer::BindFlags::Vertex, Buffer::CpuAccess::Write, (void*)kVertices);

        // create VAO
        VertexLayout::SharedPtr pLayout = VertexLayout::create();
        VertexBufferLayout::SharedPtr pBufLayout = VertexBufferLayout::create();
        pBufLayout->addElement("POSITION", 0, ResourceFormat::RG32Float, 1, 0);
        pBufLayout->addElement("TEXCOORD", 8, ResourceFormat::RG32Float, 1, 1);
        pLayout->addBufferLayout(0, pBufLayout);

        Vao::BufferVec buffers{ pVB };
        pVao = Vao::create(Vao::Topology::TriangleStrip, pLayout, buffers);
    }

    FullScreenPass::~FullScreenPass() 
    {
#ifndef _AUTOTESTING
        assert(sObjectCount > 0);
#endif
        sObjectCount--;
        if (sObjectCount == 0)
        {
            spVao = nullptr;
            spVertexBuffer = nullptr;
        }
    }

    FullScreenPass::UniquePtr FullScreenPass::create(const std::string& psFile, const Program::DefineList& programDefines, bool disableDepth, bool disableStencil, uint32_t viewportMask, bool enableSPS)
    {
        return create("", psFile, programDefines, disableDepth, disableStencil, viewportMask, enableSPS);
    }

    FullScreenPass::UniquePtr FullScreenPass::create(const std::string& vsFile, const std::string& psFile, const Program::DefineList& programDefines, bool disableDepth, bool disableStencil, uint32_t viewportMask, bool enableSPS)
    {
        UniquePtr pPass = UniquePtr(new FullScreenPass());
        pPass->init(vsFile, psFile, programDefines, disableDepth, disableStencil, viewportMask, enableSPS);
        return pPass;
    }

    void FullScreenPass::init(const std::string& vsFile, const std::string& psFile, const Program::DefineList& programDefines, bool disableDepth, bool disableStencil, uint32_t viewportMask, bool enableSPS)
    {
        mpPipelineState = GraphicsState::create();
        mpPipelineState->toggleSinglePassStereo(enableSPS);

        // create depth stencil state
        DepthStencilState::Desc dsDesc;
        dsDesc.setDepthTest(!disableDepth);
        dsDesc.setDepthWriteMask(!disableDepth);
        dsDesc.setDepthFunc(DepthStencilState::Func::LessEqual);    // Equal is needed to allow overdraw when z is enabled (e.g., background pass etc.)
        dsDesc.setStencilTest(!disableStencil);
        dsDesc.setStencilWriteMask(!disableStencil);
        mpDepthStencilState = DepthStencilState::create(dsDesc);

        Program::DefineList defs = programDefines;
        std::string gs;

        if(viewportMask)
        {
            defs.add("_VIEWPORT_MASK", std::to_string(viewportMask));
            if(checkForViewportArray2Support())
            {
                defs.add("_USE_VP2_EXT");
            }
            else
            {
                defs.add("_OUTPUT_VERTEX_COUNT", std::to_string(3 * __popcnt(viewportMask)));
#ifdef FALCOR_VK
                gs = "Framework/Shaders/FullScreenPass.gs.glsl";
#else
                gs = "Framework/Shaders/FullScreenPass.gs.slang";
#endif
            }
        }

        const std::string vs(vsFile.empty() ? "Framework/Shaders/FullScreenPass.vs.slang" : vsFile);
        mpProgram = GraphicsProgram::createFromFile(vs, psFile, gs, "", "", defs);
        mpPipelineState->setProgram(mpProgram);

        if (FullScreenPass::spVertexBuffer == nullptr)
        {
            initStaticObjects(spVertexBuffer, spVao);
        }
        mpPipelineState->setVao(FullScreenPass::spVao);
    }

    void FullScreenPass::execute(RenderContext* pRenderContext, DepthStencilState::SharedPtr pDsState) const
    {
        mpPipelineState->pushFbo(pRenderContext->getGraphicsState()->getFbo(), false);
        mpPipelineState->setViewport(0, pRenderContext->getGraphicsState()->getViewport(0), false);
        mpPipelineState->setScissors(0, pRenderContext->getGraphicsState()->getScissors(0));

        mpPipelineState->setVao(spVao);
        mpPipelineState->setDepthStencilState(pDsState ? pDsState : mpDepthStencilState);
        pRenderContext->pushGraphicsState(mpPipelineState);
        pRenderContext->draw(arraysize(kVertices), 0);
        pRenderContext->popGraphicsState();
        mpPipelineState->popFbo(false);
    }
}