Esempio n. 1
0
void csm_renderpreview(gfx_cmdqueue cmdqueue, const struct gfx_view_params* params)
{
    struct gfx_shader* shader = gfx_shader_get(g_csm->prev_shader);

    gfx_output_setrendertarget(cmdqueue, g_csm->prev_rt);
    gfx_output_setviewport(cmdqueue, 0, 0, CSM_PREV_SIZE, CSM_PREV_SIZE);
    gfx_shader_bind(cmdqueue, shader);

    /* constants */
    struct vec4f orthoparams[CSM_CASCADE_CNT];
    float max_fars[CSM_CASCADE_CNT];
    for (uint i = 0; i < CSM_CASCADE_CNT; i++)    {
        const struct mat4f* ortho = &g_csm->cascades[i].proj;
        vec4_setf(&orthoparams[i], ortho->m11, ortho->m22, ortho->m33, ortho->m43);
        max_fars[i] = g_csm->cascades[i].nfar;
    }

    gfx_shader_set4fv(shader, SHADER_NAME(c_orthoparams), orthoparams, CSM_CASCADE_CNT);
    gfx_shader_setfv(shader, SHADER_NAME(c_max_far), max_fars, CSM_CASCADE_CNT);
    gfx_shader_bindconstants(cmdqueue, shader);

    /* textures */
    gfx_shader_bindsamplertexture(cmdqueue, shader, SHADER_NAME(s_shadowmap), g_csm->sampl_linear,
        g_csm->shadow_tex);

    /* draw */
    gfx_draw_fullscreenquad();

    gfx_set_previewrenderflag();
}
Esempio n. 2
0
void gfx_csm_render(gfx_cmdqueue cmdqueue, gfx_rendertarget rt,
        const struct gfx_view_params* params, struct gfx_batch_item* batch_items, uint batch_cnt,
        void* userdata, OUT struct gfx_rpath_result* result)
{
    ASSERT(batch_cnt != 0);

    PRF_OPENSAMPLE("rpath-csm");

    int supports_shared_cbuff = gfx_check_feature(GFX_FEATURE_RANGED_CBUFFERS);
    if (supports_shared_cbuff)
        csm_submit_batchdata(cmdqueue, batch_items, batch_cnt, g_csm->sharedbuff);

    gfx_cmdqueue_resetsrvs(cmdqueue);
    gfx_output_setrendertarget(cmdqueue, g_csm->shadow_rt);
    gfx_output_setviewport(cmdqueue, 0, 0, CSM_SHADOW_SIZE, CSM_SHADOW_SIZE);
    gfx_output_setrasterstate(cmdqueue, g_csm->rs_bias);
    gfx_output_setdepthstencilstate(cmdqueue, g_csm->ds_depth, 0);
    gfx_output_clearrendertarget(cmdqueue, g_csm->shadow_rt, NULL, 1.0f, 0, GFX_CLEAR_DEPTH);

    struct gfx_cblock* cb_frame = g_csm->cb_frame;
    struct gfx_cblock* cb_frame_gs = g_csm->cb_frame_gs;
    struct mat3f* views[CSM_CASCADE_CNT];
    float fovfactors[4];
    float texelsz[4] = {1.0f / (float)CSM_SHADOW_SIZE, 0, 0, 0};
    for (uint i = 0; i < CSM_CASCADE_CNT && i < 4; i++)    {
        views[i] = &g_csm->cascades[i].view;
        fovfactors[i] = maxf(g_csm->cascades[i].proj.m11, g_csm->cascades[i].proj.m22);
    }

    gfx_cb_set4f(cb_frame, SHADER_NAME(c_texelsz), texelsz);
    gfx_cb_set4f(cb_frame, SHADER_NAME(c_fovfactors), fovfactors);
    gfx_cb_set4f(cb_frame, SHADER_NAME(c_lightdir), g_csm->light_dir.f);
    gfx_cb_set3mvp(cb_frame, SHADER_NAME(c_views), (const struct mat3f**)views, CSM_CASCADE_CNT);
    gfx_cb_set4mv(cb_frame, SHADER_NAME(c_cascade_mats), g_csm->cascade_vps, CSM_CASCADE_CNT);
    gfx_shader_updatecblock(cmdqueue, cb_frame);

    gfx_cb_set4fv(cb_frame_gs, SHADER_NAME(c_cascade_planes), g_csm->cascade_planes,
        4*CSM_CASCADE_CNT);
    gfx_shader_updatecblock(cmdqueue, cb_frame_gs);

    for (uint i = 0; i < batch_cnt; i++)  {
        struct gfx_batch_item* bitem = &batch_items[i];
        struct gfx_shader* shader = gfx_shader_get(bitem->shader_id);
        ASSERT(shader);
        gfx_shader_bind(cmdqueue, shader);

        /* do not send cb_xforms to shader if we are using shared buffer (bind later before draw) */
        struct gfx_cblock* cbs[3];
        uint xforms_shared_idx;
        if (supports_shared_cbuff)  {
            cbs[0] = cb_frame;
            cbs[1] = cb_frame_gs;
            xforms_shared_idx = 2;
        }   else    {
            cbs[0] = cb_frame;
            cbs[1] = cb_frame_gs;
            cbs[2] = g_csm->cb_xforms;
            xforms_shared_idx = 3;
        }
        gfx_shader_bindcblocks(cmdqueue, shader, (const struct gfx_cblock**)cbs, xforms_shared_idx);

        /* batch draw */
        for (int k = 0; k < bitem->nodes.item_cnt; k++)  {
            struct gfx_batch_node* bnode_first = &((struct gfx_batch_node*)bitem->nodes.buffer)[k];

            csm_preparebatchnode(cmdqueue, bnode_first, shader);
            if (bnode_first->poses[0] != NULL)  {
                gfx_shader_bindcblock_tbuffer(cmdqueue, shader, SHADER_NAME(tb_skins),
                    g_csm->tb_skins);
            }

            struct linked_list* node = bnode_first->bll;
            while (node != NULL)    {
                struct gfx_batch_node* bnode = (struct gfx_batch_node*)node->data;
                csm_drawbatchnode(cmdqueue, bnode, shader, xforms_shared_idx);
                node = node->next;
            }
        }
    }

    /* switch back */
    gfx_output_setrasterstate(cmdqueue, NULL);
    gfx_output_setdepthstencilstate(cmdqueue, NULL, 0);

    if (g_csm->debug_csm)
        csm_renderpreview(cmdqueue, params);

    PRF_CLOSESAMPLE();  /* csm */
}
GfxSkyMaterial::GfxSkyMaterial (const std::string &name)
  : GfxBaseMaterial(name, gfx_shader_get("/system/SkyDefault")),
    sceneBlend(GFX_SKY_MATERIAL_OPAQUE)
{
}
Esempio n. 4
0
result_t gfx_csm_init(uint width, uint height)
{
	result_t r;

    log_printf(LOG_INFO, "init csm render-path ...");

    struct allocator* lsr_alloc = eng_get_lsralloc();
    struct allocator* tmp_alloc = tsk_get_tmpalloc(0);

    g_csm = (struct gfx_csm*)ALIGNED_ALLOC(sizeof(struct gfx_csm), MID_GFX);
    if (g_csm == NULL)
        return RET_OUTOFMEMORY;
    memset(g_csm, 0x00, sizeof(struct gfx_csm));

    /* render targets and buffers */
	r = csm_create_shadowrt(CSM_SHADOW_SIZE, CSM_SHADOW_SIZE);
	if (IS_FAIL(r))	{
		err_print(__FILE__, __LINE__, "gfx-csm init failed: could not create shadow map buffers");
		return RET_FAIL;
	}

	if (BIT_CHECK(eng_get_params()->flags, ENG_FLAG_DEV))	{
        if (!csm_load_prev_shaders(lsr_alloc))  {
            err_print(__FILE__, __LINE__, "gfx-csm init failed: could not load preview shaders");
            return RET_FAIL;
        }

		r = csm_create_prevrt(CSM_PREV_SIZE, CSM_PREV_SIZE);
		if (IS_FAIL(r))	{
			err_print(__FILE__, __LINE__, "gfx-csm init failed: could not create prev buffers");
			return RET_FAIL;
		}

        /* console commands */
        con_register_cmd("gfx_debugcsm", csm_console_debugcsm, NULL, "gfx_debugcsm [1*/0]");
	}

    /* shaders */
    if (!csm_load_shaders(lsr_alloc))   {
        err_print(__FILE__, __LINE__, "gfx-csm init failed: could not load shaders");
        return RET_FAIL;
    }

    /* cblocks */
    if (gfx_check_feature(GFX_FEATURE_RANGED_CBUFFERS)) {
        g_csm->sharedbuff = gfx_sharedbuffer_create(GFX_DEFAULT_RENDER_OBJ_CNT*GFX_INSTANCES_MAX*48);
        if (g_csm->sharedbuff == NULL)  {
            err_print(__FILE__, __LINE__, "gfx-deferred init failed: could not create uniform buffer");
            return RET_FAIL;
        }
    }

    g_csm->cb_frame = gfx_shader_create_cblock(lsr_alloc, tmp_alloc,
        gfx_shader_get(g_csm->shaders[0].shader_id), "cb_frame", NULL);
    g_csm->cb_xforms = gfx_shader_create_cblock(lsr_alloc, tmp_alloc,
        gfx_shader_get(g_csm->shaders[0].shader_id), "cb_xforms", g_csm->sharedbuff);
    g_csm->cb_frame_gs = gfx_shader_create_cblock(lsr_alloc, tmp_alloc,
        gfx_shader_get(g_csm->shaders[0].shader_id), "cb_frame_gs", NULL);
    g_csm->tb_skins = gfx_shader_create_cblock_tbuffer(mem_heap(),
        gfx_shader_get(gfx_csm_getshader(CMP_OBJTYPE_MODEL, GFX_RPATH_SKINNED | GFX_RPATH_CSMSHADOW)),
        "tb_skins", sizeof(struct vec4f)*3*GFX_INSTANCES_MAX*GFX_SKIN_BONES_MAX);
    if (g_csm->cb_frame == NULL || g_csm->cb_xforms == NULL || g_csm->cb_frame_gs == NULL ||
        g_csm->tb_skins == NULL)
    {
        err_print(__FILE__, __LINE__, "gfx-csm init failed: could not create cblocks");
        return RET_FAIL;
    }

    /* states */
    r = csm_create_states();
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "gfx-csm init failed: could not create states");
        return RET_FAIL;
    }

    g_csm->shadowmap_size = (float)CSM_SHADOW_SIZE;

	return RET_OK;
}
Esempio n. 5
0
struct gfx_model_mtlgpu* model_load_gpumtl(struct allocator* main_alloc,
        struct allocator* alloc, struct allocator* tmp_alloc, const struct gfx_model_mtl* mtl,
        uint rpath_flags)
{
	struct gfx_model_mtlgpu* gmtl = (struct gfx_model_mtlgpu*)A_ALLOC(alloc,
        sizeof(struct gfx_model_mtlgpu), MID_GFX);
	ASSERT(gmtl);
	memset(gmtl, 0x00, sizeof(struct gfx_model_mtlgpu));

    for (uint i = 0; i < GFX_MODEL_MAX_MAPS; i++)
        gmtl->textures[i] = INVALID_HANDLE;

    /* load textures */
    for (uint i = 0; i < mtl->map_cnt; i++)	{
    	enum gfx_model_maptype type = mtl->maps[i].type;
        int srgb = FALSE;
        if (type == GFX_MODEL_DIFFUSEMAP || type == GFX_MODEL_REFLECTIONMAP ||
            type == GFX_MODEL_EMISSIVEMAP)
        {
            srgb = TRUE;
        }

    	gmtl->textures[type] = rs_load_texture(mtl->maps[i].filepath, 0, srgb, 0);
    	if (gmtl->textures[type] == INVALID_HANDLE)	{
    		model_destroy_gpumtl(alloc, gmtl);
    		return NULL;
    	}
    }

    const struct gfx_rpath* rpath;

    /* render-passes for each material */
    /* PRIMARY pass */
    rpath = gfx_rpath_detect(CMP_OBJTYPE_MODEL, rpath_flags);
    gmtl->passes[GFX_RENDERPASS_PRIMARY].rpath = rpath;
    if (rpath != NULL)	{
        gmtl->passes[GFX_RENDERPASS_PRIMARY].shader_id =
        		rpath->getshader_fn(CMP_OBJTYPE_MODEL, rpath_flags);
        if (gmtl->passes[GFX_RENDERPASS_PRIMARY].shader_id == 0) {
            log_printf(LOG_WARNING, "unsupported shader for render-path '%s' : %s", rpath->name,
                gfx_rpath_getflagstr(rpath_flags));
            model_destroy_gpumtl(alloc, gmtl);
            return NULL;
        }
    }

    /* sun shadow pass */
    rpath = gfx_rpath_detect(CMP_OBJTYPE_MODEL, rpath_flags | GFX_RPATH_CSMSHADOW);
    gmtl->passes[GFX_RENDERPASS_SUNSHADOW].rpath = rpath;
    if (rpath != NULL)	{
		gmtl->passes[GFX_RENDERPASS_SUNSHADOW].shader_id =
				rpath->getshader_fn(CMP_OBJTYPE_MODEL, rpath_flags | GFX_RPATH_CSMSHADOW);
    }

    /* spot shadow pass */
    rpath = gfx_rpath_detect(CMP_OBJTYPE_MODEL, rpath_flags | GFX_RPATH_SPOTSHADOW);
    gmtl->passes[GFX_RENDERPASS_SPOTSHADOW].rpath = rpath;
    if (rpath != NULL)	{
		gmtl->passes[GFX_RENDERPASS_SPOTSHADOW].shader_id =
				rpath->getshader_fn(CMP_OBJTYPE_MODEL, rpath_flags | GFX_RPATH_SPOTSHADOW);
    }

    /* point shadow pass */
    rpath = gfx_rpath_detect(CMP_OBJTYPE_MODEL, rpath_flags | GFX_RPATH_POINTSHADOW);
    gmtl->passes[GFX_RENDERPASS_POINTSHADOW].rpath = rpath;
    if (rpath != NULL)	{
		gmtl->passes[GFX_RENDERPASS_POINTSHADOW].shader_id =
				rpath->getshader_fn(CMP_OBJTYPE_MODEL, rpath_flags | GFX_RPATH_POINTSHADOW);
    }

    /* mirror/reflection pass */
    rpath = gfx_rpath_detect(CMP_OBJTYPE_MODEL, rpath_flags | GFX_RPATH_MIRROR);
    gmtl->passes[GFX_RENDERPASS_MIRROR].rpath = rpath;
    if (rpath != NULL)	{
		gmtl->passes[GFX_RENDERPASS_MIRROR].shader_id =
				rpath->getshader_fn(CMP_OBJTYPE_MODEL, rpath_flags | GFX_RPATH_MIRROR);
    }

    /* transparent pass */
    rpath = gfx_rpath_detect(CMP_OBJTYPE_MODEL, rpath_flags | GFX_RPATH_ALPHABLEND);
    gmtl->passes[GFX_RENDERPASS_TRANSPARENT].rpath = rpath;
    if (rpath != NULL)	{
		gmtl->passes[GFX_RENDERPASS_TRANSPARENT].shader_id =
				rpath->getshader_fn(CMP_OBJTYPE_MODEL, rpath_flags | GFX_RPATH_ALPHABLEND);
    }

    /* cblock for material: use primary shader for it's creation */
    /* note that cblock of mtl can be NULL, because some render-paths like deferred may not use it*/
    gmtl->cb = gfx_shader_create_cblock(main_alloc, tmp_alloc,
    		gfx_shader_get(gmtl->passes[GFX_RENDERPASS_PRIMARY].shader_id), "cb_mtl", NULL);

    /* if could not find 'cb_mtl' in the shader, try creating it in raw mode (w/o gpu_buffer) */
    if (gmtl->cb == NULL)   {
        static const struct gfx_constant_desc constants[] = {
            {"c_mtl_ambientclr", 0, GFX_CONSTANT_FLOAT4, 16, 1, 16, 0},
            {"c_mtl_diffuseclr", 0, GFX_CONSTANT_FLOAT4, 16, 1, 16, 16},
            {"c_mtl_specularclr", 0, GFX_CONSTANT_FLOAT4, 16, 1, 16, 32},
            {"c_mtl_emissiveclr", 0, GFX_CONSTANT_FLOAT4, 16, 1, 16, 48},
            {"c_mtl_props", 0, GFX_CONSTANT_FLOAT4, 16, 1, 16, 64}
        };
        gmtl->cb = gfx_shader_create_cblockraw(main_alloc, "cb_mtl", constants, 5);
    }

    return gmtl;
}