예제 #1
0
DWORD WINAPI thread_callback(void* param)
{
    result_t r;
    mt_thread thread = (mt_thread)param;

    if (thread->init_fn != NULL)   {
        r = thread->init_fn((mt_thread)param);
        if (IS_FAIL(r)) {
            _endthreadex(-1);
            return -1;
        }
    }

    while (WaitForMultipleObjects(2, thread->events, FALSE, INFINITE) !=
        (WAIT_OBJECT_0 + EVENT_STOP))
    {
        r = thread->kernel_fn((mt_thread)param);
        if (IS_FAIL(r))
            break;
    }

    if (thread->release_fn != NULL)
        thread->release_fn((mt_thread)param);

    ExitThread(0);
    return 0;
}
예제 #2
0
파일: prf-mgr.c 프로젝트: septag/darkhammer
result_t prf_initmgr()
{
	result_t r;

    /* samples */
    g_prf.samples_back = prf_create_samples();
    g_prf.samples_front = prf_create_samples();
    if (g_prf.samples_back == NULL || g_prf.samples_front == NULL)
        return RET_FAIL;

    mt_mutex_init(&g_prf.samples_mtx);

	/* web server */
	r = webserver_init(eng_get_params()->dev.webserver_port);
	if (IS_FAIL(r))
		return RET_FAIL;

	/* commands */
	r = arr_create(mem_heap(), &g_prf.cmds, sizeof(struct prf_cmd_desc), 20, 20, MID_PRF);
	if (IS_FAIL(r))
		return RET_OUTOFMEMORY;

	/* register commands */
	prf_register_cmd("mem-heap", prf_cmd_heapinfo);
    prf_register_cmd("mem-heap-sub", prf_cmd_heapsubinfo);
    prf_register_cmd("mem-gpu", prf_cmd_gpumem);
    prf_register_cmd("prf-gantt", prf_cmd_profilergantt);
    prf_register_cmd("mem-buffers", prf_cmd_buffersmem);
    prf_register_cmd("info-cam", prf_cmd_getcaminfo);

    MT_ATOMIC_SET(g_prf.init, TRUE);
	return RET_OK;
}
예제 #3
0
void save_pak(struct paki_args* args)
{
    result_t r;
    struct pak_file pak;

    path_norm(args->pakfile, args->pakfile);
    path_norm(args->path, args->path);

    r = pak_create(&pak, mem_heap(), args->pakfile, args->compress_mode, 0);
    if (IS_FAIL(r))     {
        err_sendtolog(FALSE);
        return;
    }


    r = compress_directory(&pak, args, "");
    if (IS_FAIL(r))     {
        err_sendtolog(FALSE);
        pak_close(&pak);
        return;
    }

    pak_close(&pak);

    // report
    printf(TERM_BOLDWHITE "Saved pak: '%s'\nTotal %d file(s) - %d Error(s), %d Warning(s)\n" TERM_RESET,
           args->pakfile, args->file_cnt, args->err_cnt, args->warn_cnt);
}
예제 #4
0
int main(int argc, char** argv)
{
    command_t cmd;
    command_init(&cmd, "dhcore-test", "1.0");    
    command_option_pos(&cmd, "test", "Choose unit test", TRUE, cmd_gettest);
    command_parse(&cmd, argc, argv, NULL);

    if (IS_FAIL(core_init(CORE_INIT_ALL)))     {
        printf("core init error.\n");
        return -1;
    }

    log_outputconsole(TRUE);

    if (g_testidx == -1)
        g_testidx = show_help();

    if (g_testidx != -1) 
        g_tests[g_testidx].test_fn();

#if defined(_DEBUG_)
    core_release(TRUE);
#else
    core_release(FALSE);
#endif
    return 1;
}
예제 #5
0
result_t cmp_anim_modify(struct cmp_obj* obj, struct allocator* alloc, struct allocator* tmp_alloc,
    void* data, cmphandle_t cur_hdl)
{
    result_t r;
    struct cmp_anim* a = (struct cmp_anim*)data;

    uint filehash = hash_str(a->filepath);
    int reload = (a->filepathhash == filehash);
    cmp_anim_destroydata(obj, a, cur_hdl, !reload);
    a->filepathhash = filehash;

    a->alloc = alloc;
    if (str_isempty(a->filepath))
        return RET_OK;

    if (!reload)
        a->clip_hdl = rs_load_animreel(a->filepath, 0);

    if (a->clip_hdl == INVALID_HANDLE)
        return RET_FAIL;

    /* bind */
    r = cmp_anim_bind(obj, a, alloc, tmp_alloc, cur_hdl);
    if (IS_FAIL(r)) {
        err_sendtolog(TRUE);
        log_print(LOG_WARNING, "binding anim-set failed");
        return RET_FAIL;
    }

    return RET_OK;
}
예제 #6
0
uint wld_register_var(uint section_id, const char* name, enum variant_type type,
                        pfn_wld_varchanged change_fn, void* param)
{
    ASSERT(section_id != 0);
    ASSERT(strlen(name) < 32);
    ASSERT(type != VAR_TYPE_NULL);

    struct wld_section* s = &((struct wld_section*)g_wld.sections.buffer)[section_id - 1];

    uint hashval = hash_str(name);
    struct hashtable_item* item = hashtable_open_find(&s->vtable, hashval);
    if (item != NULL)   {
        err_printf(__FILE__, __LINE__, "world-mgr: var '%s' already exists in '%s'", name, s->name);
        return 0;
    }

    struct wld_var* v = (struct wld_var*)arr_add(&s->vars);
    uint id = s->vars.item_cnt;
    if (v == NULL || IS_FAIL(hashtable_open_add(&s->vtable, hashval, id)))  {
        err_printn(__FILE__, __LINE__, RET_OUTOFMEMORY);
        return 0;
    }

    memset(v, 0x00, sizeof(struct wld_var));
    str_safecpy(v->name, sizeof(v->name), name);
    v->change_fn = change_fn;
    v->param = param;
    v->v.type = type;

    return id;
}
예제 #7
0
void list_pak(struct paki_args* args)
{
    result_t r;
    struct pak_file pak;
    r = pak_open(&pak, mem_heap(), args->pakfile, 0);
    if (IS_FAIL(r))     {
        err_sendtolog(FALSE);
        return;
    }

    uint cnt = INVALID_INDEX;
    char* filelist = pak_createfilelist(&pak, mem_heap(), &cnt);
    pak_close(&pak);
    if (cnt == 0)	{
        printf(TERM_BOLDWHITE "There are no files in the pak '%s'.\n" TERM_RESET, args->pakfile);
        return;
    }

    if (filelist == NULL)	{
        printf(TERM_BOLDRED "Not enough memory.\n" TERM_RESET);
        return;
    }

    for (uint i = 0; i < cnt; i++)	{
        printf(TERM_WHITE "%s\n" TERM_RESET, filelist + i*DH_PATH_MAX);
    }
    printf(TERM_BOLDWHITE "Total %d files in '%s'.\n" TERM_RESET, cnt, args->pakfile);
    FREE(filelist);
}
예제 #8
0
void load_pak(struct paki_args* args)
{
    result_t r;
    struct pak_file pak;
    char filename[DH_PATH_MAX];

    path_norm(args->pakfile, args->pakfile);
    path_tounix(args->path, args->path);

    r = pak_open(&pak, mem_heap(), args->pakfile, 0);
    if (IS_FAIL(r))     {
        err_sendtolog(FALSE);
        return;
    }

    uint file_id = pak_findfile(&pak, args->path);
    if (file_id == INVALID_INDEX)   {
        printf(TERM_BOLDRED "Extract failed: file '%s' not found in pak.\n" TERM_RESET, args->path);
        pak_close(&pak);
        return;
    }

    path_getfullfilename(filename, args->path);
    file_t f = fio_createdisk(filename);
    if (f == NULL)     {
        printf(TERM_BOLDRED "Extract failed: could not create '%s' for writing.\n" TERM_RESET,
               filename);
        pak_close(&pak);
        err_sendtolog(FALSE);
        return;
    }

    file_t src_file = pak_getfile(&pak, mem_heap(), mem_heap(), file_id, 0);
    if (src_file == NULL)   {
        pak_close(&pak);
        fio_close(f);
        err_sendtolog(FALSE);
        return;
    }

    size_t size;
    struct allocator* alloc;
    void* buffer = fio_detachmem(src_file, &size, &alloc);
    fio_write(f, buffer, size, 1);
    A_FREE(alloc, buffer);
    fio_close(f);

    pak_close(&pak);

    if (BIT_CHECK(args->usage, PAKI_USAGE_VERBOSE)) {
        printf(TERM_WHITE "%s -> %s\n" TERM_RESET, args->path, filename);
    }
    args->file_cnt ++;

    // report
    printf(TERM_BOLDWHITE "Finished: total %d file(s) - %d error(s), %d warning(s)\n" TERM_RESET,
           args->file_cnt, args->err_cnt, args->warn_cnt);
}
예제 #9
0
파일: gfx-csm.c 프로젝트: septag/darkhammer
result_t gfx_csm_resize(uint width, uint height)
{
	if (BIT_CHECK(eng_get_params()->flags, ENG_FLAG_DEV))	{
		csm_destroy_prevrt();
		if (IS_FAIL(csm_create_prevrt(width, height)))
			return RET_FAIL;
	}
	return RET_OK;
}
예제 #10
0
result_t compress_directory(struct pak_file* pak, struct paki_args* args, const char* subdir)
{
    result_t r;
    char directory[DH_PATH_MAX];
    char filepath[DH_PATH_MAX];
    char fullfilepath[DH_PATH_MAX];

    strcpy(directory, args->path);
    if (subdir[0] != 0)     {
        path_join(directory, directory, subdir, NULL);
    }

    WIN32_FIND_DATA fdata;
    char filter[DH_PATH_MAX];
    path_join(filter, directory, "*", NULL);
    HANDLE find_hdl = FindFirstFile(filter, &fdata);
    if (find_hdl == INVALID_HANDLE_VALUE)    {
        printf(TERM_BOLDRED "Creating pak failed: directory '%s' does not exist.\n" TERM_RESET,
               directory);
        return RET_FAIL;
    }

    /* read directory recuresively, and compress files into pak */
    BOOL fr = TRUE;
    while (fr)     {
        if (!str_isequal(fdata.cFileName, ".") && !str_isequal(fdata.cFileName, ".."))    {
            filepath[0] = 0;
            if (subdir[0] != 0)     {
                strcpy(filepath, subdir);
            }

            if (!BIT_CHECK(fdata.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY))  {
                /* put the file into the archive */
                path_join(filepath, filepath, fdata.cFileName, NULL);
                path_join(fullfilepath, directory, fdata.cFileName, NULL);

                r = archive_put(pak, args, fullfilepath, filepath);
                if (IS_OK(r) && BIT_CHECK(args->usage, PAKI_USAGE_VERBOSE))     {
                    puts(filepath);
                }   else if (IS_FAIL(r))  {
                    err_sendtolog(FALSE);
                    args->err_cnt ++;
                }
                args->file_cnt ++;
            }   else    {
                /* it's a directory, recurse */
                path_join(filepath, filepath, fdata.cFileName, NULL);
                compress_directory(pak, args, filepath);
            }
        }
        fr = FindNextFile(find_hdl, &fdata);
    }

    FindClose(find_hdl);
    return RET_OK;
}
예제 #11
0
uint wld_register_section(const char* name)
{
    ASSERT(strlen(name) < 32);

    result_t r;
    uint hashval = hash_str(name);
    struct hashtable_item* item = hashtable_open_find(&g_wld.stable, hashval);
    if (item != NULL)   {
        err_printf(__FILE__, __LINE__, "world-mgr: section '%s' already exists", name);
        return 0;
    }

    struct wld_section* section = (struct wld_section*)arr_add(&g_wld.sections);
    if (section == NULL)    {
        err_printn(__FILE__, __LINE__, RET_OUTOFMEMORY);
        return 0;
    }

    /* initialize section */
    str_safecpy(section->name, sizeof(section->name), name);
    r = hashtable_open_create(mem_heap(), &section->vtable, 10, 20, 0);
    if (IS_FAIL(r)) {
        err_printn(__FILE__, __LINE__, RET_OUTOFMEMORY);
        return 0;
    }
    r = arr_create(mem_heap(), &section->vars, sizeof(struct wld_var), 10, 20, 0);
    if (IS_FAIL(r)) {
        err_printn(__FILE__, __LINE__, RET_OUTOFMEMORY);
        wld_destroy_section(section);
        return 0;
    }

    /* add */
    uint id = g_wld.sections.item_cnt;
    if (IS_FAIL(hashtable_open_add(&g_wld.stable, hashval, id))) {
        err_printn(__FILE__, __LINE__, RET_OUTOFMEMORY);
        wld_destroy_section(section);
        return 0;
    }

    return id;
}
예제 #12
0
result_t compress_directory(struct pak_file* pak, struct paki_args* args, const char* subdir)
{
    result_t r;
    char directory[DH_PATH_MAX];
    char filepath[DH_PATH_MAX];
    char fullfilepath[DH_PATH_MAX];

    strcpy(directory, args->path);
    if (subdir[0] != 0)     {
        path_join(directory, path_norm(directory, directory), subdir, NULL);
    }

    DIR* dir = opendir(directory);
    if (dir == NULL)    {
        printf(TERM_BOLDRED "Creating pak failed: directory '%s' does not exist.\n" TERM_RESET,
               directory);
        return RET_FAIL;
    }

    /* read directory recuresively, and compress files into pak */
    struct dirent* ent = readdir(dir);
    while (ent != NULL)     {
        if (!str_isequal(ent->d_name, ".") && !str_isequal(ent->d_name, ".."))    {
            filepath[0] = 0;
            if (subdir[0] != 0)
                strcpy(filepath, subdir);

            if (ent->d_type != DT_DIR)  {
                // put the file into the archive
                path_join(filepath, filepath, ent->d_name, NULL);
                path_join(fullfilepath, directory, ent->d_name, NULL);
                r = archive_put(pak, args, fullfilepath, filepath);
                if (IS_OK(r) && BIT_CHECK(args->usage, PAKI_USAGE_VERBOSE))     {
                    puts(filepath);
                }   else if (IS_FAIL(r))  {
                    err_sendtolog(FALSE);
                    args->err_cnt ++;
                }
                args->file_cnt ++;
            }   else    {
                // it's a directory, recurse
                path_join(filepath, filepath, ent->d_name, NULL);
                compress_directory(pak, args, filepath);
            }
        }
        ent = readdir(dir);
    }

    closedir(dir);
    return RET_OK;
}
예제 #13
0
result_t wld_initmgr()
{
    result_t r;
    r = hashtable_open_create(mem_heap(), &g_wld.stable, 5, 10, 0);
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "Initializing world manager failed");
        return r;
    }

    r = arr_create(mem_heap(), &g_wld.sections, sizeof(struct wld_section), 5, 10, 0);
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "Initializing world manager failed");
        return r;
    }

    /* camera */
    struct vec3f pos;
    cam_init(&g_wld.default_cam, vec3_setf(&pos, 0.0f, 0.0f, -1.0f), &g_vec3_zero, CAM_NEAR,
        CAM_FAR, math_torad(CAM_FOV));
    g_wld.cam = &g_wld.default_cam;

    return RET_OK;
}
예제 #14
0
/*************************************************************************************************
 * Events
 */
mt_event mt_event_create(struct allocator* alloc)
{
    mt_event e = (mt_event)A_ALLOC(alloc, sizeof(struct mt_event_data), 0);
    if (e == NULL)
        return NULL;
    memset(e, 0x00, sizeof(struct mt_event_data));
    e->alloc = alloc;

    result_t r = arr_create(alloc, &e->signals, sizeof(HANDLE), 8, 16, 0);
    if (IS_FAIL(r)) {
        A_FREE(alloc, e);
        return NULL;
    }

    return e;
}
예제 #15
0
파일: prf-mgr.c 프로젝트: septag/darkhammer
struct prf_samples* prf_create_samples()
{
    struct prf_samples* s = (struct prf_samples*)ALLOC(sizeof(struct prf_samples), MID_PRF);
    if (s == NULL)
        return NULL;
    memset(s, 0x00, sizeof(struct prf_samples));

    result_t r;

    r = mem_stack_create(mem_heap(), &s->alloc, SAMPLES_BUFFER_SIZE, MID_PRF);
    if (IS_FAIL(r)) {
        prf_destroy_samples(s);
        return NULL;
    }

    return s;
}
예제 #16
0
파일: core.c 프로젝트: ataceyhun/libdhcore
result_t core_init(uint flags)
{
    if (BIT_CHECK(flags, CORE_INIT_CRASHDUMP))  {
        if (IS_FAIL(crash_init()))
            return RET_FAIL;
    }

    if (IS_FAIL(mem_init(BIT_CHECK(flags, CORE_INIT_TRACEMEM))))
        return RET_FAIL;

    if (IS_FAIL(log_init()))
        return RET_FAIL;

    if (BIT_CHECK(flags, CORE_INIT_ERRORS)) {
        if (IS_FAIL(err_init()))
            return RET_FAIL;
    }

    rand_seed();

    if (BIT_CHECK(flags, CORE_INIT_JSON))   {
        if (IS_FAIL(json_init()))
            return RET_FAIL;
    }

    if (BIT_CHECK(flags, CORE_INIT_FILEIO)) {
        if (IS_FAIL(fio_initmgr()))
            return RET_FAIL;
    }

    if (BIT_CHECK(flags, CORE_INIT_TIMER)) {
        if (IS_FAIL(timer_initmgr()))
            return RET_FAIL;
    }

    if (BIT_CHECK(flags, CORE_INIT_SOCKET)) {
        if (IS_FAIL(sock_init()))
            return RET_FAIL;
    }

    return RET_OK;
}
예제 #17
0
파일: res-mgr.c 프로젝트: septag/darkhammer
result_t rs_initmgr(uint flags, uint load_thread_cnt)
{
    result_t r;

    memset(&g_rs, 0x00, sizeof(g_rs));
    log_print(LOG_TEXT, "init res-mgr ...");

    r = arr_create(mem_heap(), &g_rs.ress, sizeof(struct rs_resource), 128, 256, MID_RES);
    r |= mem_pool_create(mem_heap(), &g_rs.freeslot_pool, sizeof(struct rs_freeslot_item),
        100, MID_RES);
    r |= mem_pool_create(mem_heap(), &g_rs.dict_itempool, sizeof(struct hashtable_item_chained),
        DICT_BLOCK_SIZE, MID_RES);
    mem_pool_bindalloc(&g_rs.dict_itempool, &g_rs.dict_itemalloc);
    r |= hashtable_chained_create(mem_heap(), &g_rs.dict_itemalloc, &g_rs.dict, 65521, MID_RES);
    r |= mem_pool_create(mem_heap(), &g_rs.load_data_pool, sizeof(struct rs_load_data), 256, MID_RES);
    if (IS_FAIL(r)) {
        err_printn(__FILE__, __LINE__, RET_OUTOFMEMORY);
        return r;
    }

    /* get maximum number of threads available for threaded loading */
    if (BIT_CHECK(flags, RS_FLAG_PREPARE_BGLOAD))   {
        g_rs.load_threads_max = maxui(load_thread_cnt, 1);
        g_rs.job_params.load_items = (struct rs_load_data**)ALLOC(
            sizeof(struct rs_load_data*)*load_thread_cnt, MID_RES);
        g_rs.job_result.ptrs = (void**)ALLOC(sizeof(void*)*load_thread_cnt, MID_RES);
        if (g_rs.job_params.load_items == NULL || g_rs.job_result.ptrs == NULL)    {
            err_printn(__FILE__, __LINE__, RET_OUTOFMEMORY);
            return RET_OUTOFMEMORY;
        }
    }

    g_rs.alloc = mem_heap();    /* default allocator is heap */
    g_rs.flags = flags;
    g_rs.init = TRUE;
    return RET_OK;
}
예제 #18
0
/**
 * Load tutorial data and setup scene
 */
int tut02_load_data()
{
    result_t r;

    uint scene_id = scn_getactive();
    ASSERT(scene_id != 0);

    /* Create ground plane model */
    cmp_obj* obj = scn_create_obj(scene_id, "ground", CMP_OBJTYPE_MODEL);
    if (obj == NULL)
        return FALSE;
    r = cmp_value_sets(cmp_findinstance_inobj(obj, "model"), "filepath", "plane.h3dm");
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "Loading models failed");
        return FALSE;
    }
    g_obj_ground = obj;

    /* Create physics debug plane, acts as an infinite physics ground for rigid objects */
    phx_create_debugplane(0.5f, 0.5f);

    /* Setup barrels */
    for (uint i = 0; i < BARREL_COUNT; i++)   {
        char name[32];
        sprintf(name, "barrel-%d", i);
        cmp_obj* barrel = scn_create_obj(scene_id, name, CMP_OBJTYPE_MODEL);
        if (barrel == NULL)
            return FALSE;
        /* Load barrel.h3dm as model file for objects
         * We set/modify the "filepath" value of the "model" component of the object */
        r = cmp_value_sets(cmp_findinstance_inobj(barrel, "model"), "filepath", "barrel.h3dm");
        if (IS_FAIL(r)) {
            scn_destroy_obj(barrel);
            err_print(__FILE__, __LINE__, "Loading barrel models failed");
            return FALSE;
        }

        /* Create rigid body physics component for the object */
#if 0
        cmphandle_t rbody_hdl = cmp_create_instance_forobj("rbody", barrel);
        if (rbody_hdl == INVALID_HANDLE)    {
            scn_destroy_obj(barrel);
            err_print(__FILE__, __LINE__, "Loading barrel models failed");
            return FALSE;
        }

        /* Load barrel.h3dp as physics object
         * We set/modify the "filepath" value of the "rbody" component of the object */
        r = cmp_value_sets(rbody_hdl, "filepath", "barrel.h3dp");
        if (IS_FAIL(r))    {
            scn_destroy_obj(barrel);
            err_print(__FILE__, __LINE__, "Loading barrel models failed");
            return FALSE;
        }
#endif      
        /* Place barrel randomly in space */
        cmp_xform_setposf(barrel,
            rand_getf(-5.0f, 5.0f), rand_getf(10.0f, 16.0f), rand_getf(-5.0f, 5.0f));
        cmp_xform_setrot(barrel, rand_getf(0, PI), 0.0f, rand_getf(0, PI));

        g_obj_barrels[i] = barrel;
    }

    return TRUE;
}
예제 #19
0
struct gfx_model* gfx_model_load(struct allocator* alloc, const char* h3dm_filepath,
    uint thread_id)
{
	struct allocator* tmp_alloc = tsk_get_tmpalloc(thread_id);
	A_SAVE(tmp_alloc);

	struct h3d_header header;
    struct h3d_model h3dmodel;
	struct gfx_model* model = NULL;
    uint renderable_idx = 0;
    struct stack_alloc stack_mem;
    struct allocator stack_alloc;
    result_t r;

    memset(&stack_mem, 0x00, sizeof(stack_mem));

	file_t f = fio_openmem(tmp_alloc, h3dm_filepath, FALSE, MID_GFX);
	if (f == NULL)	{
		err_printf(__FILE__, __LINE__, "load model '%s' failed: could not open file", h3dm_filepath);
		goto err_cleanup;
	}

	/* header */
    fio_read(f, &header, sizeof(header), 1);
	if (header.sign != H3D_SIGN || header.type != H3D_MESH)	{
		err_printf(__FILE__, __LINE__, "load model '%s' failed: invalid file format", h3dm_filepath);
		goto err_cleanup;
	}

    if (header.version != H3D_VERSION && header.version != H3D_VERSION_13)  {
        err_printf(__FILE__, __LINE__, "load model '%s' failed: file version not implemented/obsolete",
            h3dm_filepath);
        goto err_cleanup;
    }

    /* model */
    fio_read(f, &h3dmodel, sizeof(h3dmodel), 1);

    /* calculate size and create stack allocator for proceeding allocations */
    size_t total_sz =
        sizeof(struct gfx_model) +
        h3dmodel.node_cnt*sizeof(struct gfx_model_node) + 16 +
        h3dmodel.node_cnt*sizeof(uint) +
        h3dmodel.geo_cnt*sizeof(struct gfx_model_geo) +
        h3dmodel.mesh_cnt*sizeof(struct gfx_model_mesh) +
        h3dmodel.mtl_cnt*sizeof(struct gfx_model_mtl) +
        h3dmodel.has_occ*sizeof(struct gfx_model_occ) +
        h3dmodel.total_childidxs*sizeof(uint) +
        h3dmodel.total_geo_subsets*sizeof(struct gfx_model_geosubset) +
        h3dmodel.total_joints*sizeof(struct gfx_model_joint) +
        h3dmodel.total_joints*sizeof(struct mat3f) +
        h3dmodel.total_submeshes*sizeof(struct gfx_model_submesh) +
        h3dmodel.total_skeletons*sizeof(struct gfx_model_skeleton) +
        h3dmodel.total_skeletons*32 + /* 2 aligned allocs per skeleton */
        h3dmodel.total_maps*sizeof(struct gfx_model_map) +
        h3dmodel.occ_idx_cnt*sizeof(uint16) +
        h3dmodel.occ_vert_cnt*sizeof(struct vec3f) +
        h3dmodel.has_occ*16; /* 1 aligned alloc for occ */
    r = mem_stack_create(alloc, &stack_mem, total_sz, MID_GFX);
    if (IS_FAIL(r)) {
        err_printn(__FILE__, __LINE__, RET_OUTOFMEMORY);
        goto err_cleanup;
    }
    mem_stack_bindalloc(&stack_mem, &stack_alloc);

    /* */
    model = (struct gfx_model*)A_ALLOC(&stack_alloc, sizeof(struct gfx_model), MID_GFX);
    if (model == NULL)	{
        err_printn(__FILE__, __LINE__, RET_OUTOFMEMORY);
        goto err_cleanup;
    }
    memset(model, 0x00, sizeof(struct gfx_model));
    model->alloc = alloc;

	/* nodes */
	if (h3dmodel.node_cnt > 0)	{
		model->nodes = (struct gfx_model_node*)A_ALIGNED_ALLOC(&stack_alloc,
            sizeof(struct gfx_model_node)*h3dmodel.node_cnt, MID_GFX);
        ASSERT(model->nodes);
		memset(model->nodes, 0x00, sizeof(struct gfx_model_node)*h3dmodel.node_cnt);

		for (uint i = 0; i < h3dmodel.node_cnt; i++)	{
			struct gfx_model_node* node = &model->nodes[i];
			if (!model_loadnode(node, f, &stack_alloc))
				goto err_cleanup;

            /* NOTE: we set root matrix to identity and keep the old one as "root_mat" */
            if (i == 0) {
                mat3_setm(&model->root_mat, &node->local_mat);
                mat3_set_ident(&node->local_mat);
            }
			model->node_cnt ++;
		}
	}

	/* meshes */
	if (h3dmodel.mesh_cnt > 0)	{
		model->meshes = (struct gfx_model_mesh*)A_ALLOC(&stack_alloc,
            sizeof(struct gfx_model_mesh)*h3dmodel.mesh_cnt, MID_GFX);
		ASSERT(model->meshes);
		memset(model->meshes, 0x00, sizeof(struct gfx_model_mesh)*h3dmodel.mesh_cnt);
		uint idx = 0;

		for (uint i = 0; i < h3dmodel.mesh_cnt; i++)	{
			struct gfx_model_mesh* mesh = &model->meshes[i];
			if (!model_loadmesh(mesh, f, &stack_alloc))
				goto err_cleanup;

			/* assign global indexes */
			for (uint k = 0; k < mesh->submesh_cnt; k++)
				mesh->submeshes[k].offset_idx = idx++;

			model->mesh_cnt ++;
		}
	}

	/* geos */
	if (h3dmodel.geo_cnt > 0)	{
		model->geos = (struct gfx_model_geo*)A_ALLOC(&stack_alloc,
            sizeof(struct gfx_model_geo)*h3dmodel.geo_cnt, MID_GFX);
		ASSERT(model->geos);

		memset(model->geos, 0x00, sizeof(struct gfx_model_geo)*h3dmodel.geo_cnt);
		for (uint i = 0; i < h3dmodel.geo_cnt; i++)	{
			struct gfx_model_geo* geo = &model->geos[i];
			if (!model_loadgeo(geo, f, &stack_alloc, tmp_alloc, thread_id))
				goto err_cleanup;
			model->geo_cnt ++;
		}
	}

	/* materials */
	if (h3dmodel.mtl_cnt > 0)	{
		model->mtls = (struct gfx_model_mtl*)A_ALLOC(&stack_alloc,
            sizeof(struct gfx_model_mtl)*h3dmodel.mtl_cnt, MID_GFX);
		ASSERT(model->mtls);

		memset(model->mtls, 0x00, sizeof(struct gfx_model_mtl)*h3dmodel.mtl_cnt);
		for (uint i = 0; i < h3dmodel.mtl_cnt; i++)	{
			struct gfx_model_mtl* mtl = &model->mtls[i];
			if (!model_loadmtl(mtl, f, &stack_alloc))
                goto err_cleanup;
			model->mtl_cnt ++;
		}
	}

    if (header.version >= H3D_VERSION_11 && h3dmodel.has_occ)   {
        model->occ = (struct gfx_model_occ*)A_ALLOC(&stack_alloc, sizeof(struct gfx_model_occ),
            MID_GFX);
        ASSERT(model->occ);

        memset(model->occ, 0x00, sizeof(struct gfx_model_occ));
        if (!model_loadocc(model->occ, f, &stack_alloc))
            goto err_cleanup;
    }

    /* populate renderable nodes */
    model->renderable_idxs = (uint*)A_ALLOC(&stack_alloc, sizeof(uint)*h3dmodel.node_cnt,
        MID_GFX);
    ASSERT(model->renderable_idxs);

    for (uint i = 0; i < h3dmodel.node_cnt; i++)	{
        struct gfx_model_node* node = &model->nodes[i];
        if (node->mesh_id != INVALID_INDEX)
            model->renderable_idxs[renderable_idx++] = i;
    }
    model->renderable_cnt = renderable_idx;

    /* calculate sum of aabb(s) from renderable nodes */
	aabb_setzero(&model->bb);
    struct mat3f node_mat;  /* transform matrix, relative to model */
	for (uint i = 0; i < renderable_idx; i++)   {
        struct gfx_model_node* node = &model->nodes[model->renderable_idxs[i]];
        mat3_setm(&node_mat, &node->local_mat);
        struct gfx_model_node* pnode = node;
        while (pnode->parent_id != INVALID_INDEX)	{
            pnode = &model->nodes[pnode->parent_id];
            mat3_mul(&node_mat, &node_mat, &pnode->local_mat);
        }
        if (node->parent_id != INVALID_INDEX)
            mat3_mul(&node_mat, &node_mat, &model->root_mat);

        /* transform local box to model-relative bounding box and merge with final */
        struct aabb bb;
        aabb_xform(&bb, &model->nodes[model->renderable_idxs[i]].bb, &node_mat);
		aabb_merge(&model->bb, &model->bb, &bb);
    }
    /* for empty models, we set a minimal bounding-box */
    if (aabb_iszero(&model->bb))    {
        aabb_pushptf(&model->bb, 0.1f, 0.1f, 0.1f);
        aabb_pushptf(&model->bb, -0.1f, -0.1f, -0.1f);
    }

    fio_close(f);
	A_LOAD(tmp_alloc);

    if (thread_id != 0) {
        gfx_delayed_waitforobjects(thread_id);
        gfx_delayed_fillobjects(thread_id);
    }

	return model;

err_cleanup:
	if (f != NULL)
        fio_close(f);
	if (model != NULL)
		gfx_model_unload(model);
    mem_stack_destroy(&stack_mem);
	A_LOAD(tmp_alloc);
	return NULL;
}
예제 #20
0
struct gfx_model_instance* gfx_model_createinstance(struct allocator* alloc,
		struct allocator* tmp_alloc, reshandle_t model)
{
    struct gfx_model* m = rs_get_model(model);
    uint unique_cnt = 0;
    uint joint_cnt = 0;
    uint skeleton_cnt = 0;
    for (uint i = 0; i < m->mesh_cnt; i++)
        unique_cnt += m->meshes[i].submesh_cnt;
    for (uint i = 0; i < m->geo_cnt; i++) {
        if (m->geos[i].skeleton != NULL)    {
            joint_cnt += m->geos[i].skeleton->joint_cnt*3;
            skeleton_cnt ++;
        }
    }

    /* create stack memory for proceeding allocs and calculate size */
    struct stack_alloc stack_mem;
    struct allocator stack_alloc;
    size_t total_sz =
        sizeof(struct gfx_model_instance) +
        m->mtl_cnt*sizeof(struct gfx_model_mtlgpu) +
        m->geo_cnt*sizeof(struct gfx_model_posegpu) +
        sizeof(uint)*unique_cnt +
        sizeof(int)*m->renderable_cnt +
        skeleton_cnt*16 +
        joint_cnt*sizeof(struct mat3f)*3;

    if (IS_FAIL(mem_stack_create(alloc, &stack_mem, total_sz, MID_GFX)))
        return NULL;
    mem_stack_bindalloc(&stack_mem, &stack_alloc);

    /* */
	struct gfx_model_instance* inst = (struct gfx_model_instance*)A_ALLOC(&stack_alloc,
        sizeof(struct gfx_model_instance), MID_GFX);
    ASSERT(inst);
	memset(inst, 0x00, sizeof(struct gfx_model_instance));

	inst->alloc = alloc;
	inst->model = model;

	/* gpu materials */
	if (m->mtl_cnt > 0)	{
		inst->mtls = (struct gfx_model_mtlgpu**)A_ALLOC(&stack_alloc,
            sizeof(struct gfx_model_mtlgpu*)*m->mtl_cnt, MID_GFX);
		ASSERT(inst->mtls);
		memset(inst->mtls, 0x00, sizeof(struct gfx_model_mtlgpu*)*m->mtl_cnt);
	}

	if (m->geo_cnt > 0)	{
		inst->poses = (struct gfx_model_posegpu**)A_ALLOC(&stack_alloc,
            sizeof(struct gfx_model_posegpu*)*m->geo_cnt, MID_GFX);
		ASSERT(inst->poses);
		memset(inst->poses, 0x00, sizeof(struct gfx_model_posegpu*)*m->geo_cnt);
        inst->pose_cnt = m->geo_cnt;
	}

	for (uint i = 0; i < m->renderable_cnt; i++)	{
		struct gfx_model_node* n = &m->nodes[m->renderable_idxs[i]];
		struct gfx_model_mesh* mesh = &m->meshes[n->mesh_id];

		for (uint k = 0; k < mesh->submesh_cnt; k++)	{
			uint geo_id = mesh->geo_id;
			uint mtl_id = mesh->submeshes[k].mtl_id;
			uint rpath_flags = model_make_rpathflags(m, n->mesh_id, k);

			/* create material gpu data, if not created before */
			if (inst->mtls[mtl_id] == NULL)	{
				inst->mtls[mtl_id] = model_load_gpumtl(alloc, &stack_alloc, tmp_alloc,
                    &m->mtls[mtl_id], rpath_flags);
				if (inst->mtls[mtl_id] == NULL)	{
					gfx_model_destroyinstance(inst);
					return NULL;
				}
			}

			if (inst->poses[geo_id] == NULL && BIT_CHECK(rpath_flags, GFX_RPATH_SKINNED))	{
				inst->poses[geo_id] = model_load_gpupose(&stack_alloc, tmp_alloc, &m->geos[geo_id],
						rpath_flags);
				if (inst->poses[geo_id] == NULL)	{
					gfx_model_destroyinstance(inst);
					return NULL;
				}
			}
		}
	}

	/* create unique Ids */
	if (unique_cnt > 0)	{
		inst->unique_ids = (uint*)A_ALLOC(&stack_alloc, sizeof(uint)*unique_cnt, MID_GFX);
		if (inst->unique_ids == NULL)	{
			gfx_model_destroyinstance(inst);
			return NULL;
		}
		memset(inst->unique_ids, 0x00, sizeof(uint)*unique_cnt);
	}

    /* create alpha flags */
    inst->alpha_flags = (int*)A_ALLOC(&stack_alloc, sizeof(int)*m->renderable_cnt, MID_GFX);
    memset(inst->alpha_flags, 0x00, sizeof(int)*m->renderable_cnt);

	/* update data of materials */
	gfx_model_updatemtls(inst);

	return inst;
}
예제 #21
0
파일: engine.c 프로젝트: septag/darkhammer
result_t eng_init(const struct init_params* params)
{
    result_t r = RET_OK;

    ASSERT(g_eng == NULL);
    g_eng = (struct engine*)ALLOC(sizeof(struct engine), 0);
    if (g_eng == 0)
        return err_printn(__FILE__, __LINE__, RET_OUTOFMEMORY);
    memset(g_eng, 0x00, sizeof(struct engine));

    eng_zero();

    memcpy(&g_eng->params, params, sizeof(struct init_params));

    hw_getinfo(&g_eng->hwinfo, HWINFO_ALL);

    /* console (before anything else) */
    if (BIT_CHECK(params->flags, ENG_FLAG_CONSOLE))	{
		r |= con_init(params->console_lines_max);
		if (IS_FAIL(r))
			return RET_FAIL;
		log_outputfunc(TRUE, con_log, NULL);
    }

    /* show build options */
#if !defined(FULL_VERSION)
#error "must define FULL_VERSION macro"
#endif

    time_t raw_tm;
    time(&raw_tm);

    log_printf(LOG_TEXT, "init darkhammer engine v%s build[%s, %s, %s, %s], time: %s", 
        FULL_VERSION,
#if defined(_DEBUG_)
    		"debug"
#else
    		"release"
#endif
    		,
#if defined(_PROFILE_)
    		"profile"
#else
    		"no-profile"
#endif
    		,
#if defined(_X86_)
    		"x86"
#elif defined(_X64_)
    		"x64"
#endif
    		,
#if defined(_ENABLEASSERT_)
    		"assert"
#else
    		"no-assert"
#endif
            , asctime(localtime(&raw_tm)));

    /* hardware info */
    hw_printinfo(&g_eng->hwinfo, HWINFO_ALL);

    size_t tmp_sz = params->dev.buffsize_tmp;
    size_t data_sz = data_sz = params->dev.buffsize_data;
    tmp_sz = tmp_sz != 0 ? ((size_t)tmp_sz*1024) : FRAME_STACK_SIZE;
    data_sz = data_sz != 0 ? ((size_t)data_sz*1024) : DATA_SIZE;

    /* allocators */
    /* dynamic allocator for data in dev (editor) mode, stack allocator in game (normal) mode */
    if (BIT_CHECK(params->flags, ENG_FLAG_OPTIMIZEMEMORY))   {
        /* lsr (load-stay-resident) allocator for essential engine data */
        r |= mem_stack_create(mem_heap(), &g_eng->lsr_stack, LSR_SIZE, MID_DATA);
        mem_stack_bindalloc(&g_eng->lsr_stack, &g_eng->lsr_alloc);

        r |= mem_freelist_create(mem_heap(), &g_eng->data_freelist, data_sz, MID_DATA);
        mem_freelist_bindalloc(&g_eng->data_freelist, &g_eng->data_alloc);
    }   else    {
        mem_heap_bindalloc(&g_eng->data_alloc);
        mem_heap_bindalloc(&g_eng->lsr_alloc);

        g_eng->data_alloc.alloc_fn = eng_allocfn_data;
        g_eng->data_alloc.alignedalloc_fn = eng_alignedallocfn_data;
        g_eng->lsr_alloc.alloc_fn = eng_allocfn_lsr;
        g_eng->lsr_alloc.alignedalloc_fn = eng_alignedallocfn_lsr;

        r = RET_OK;
    }

    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "engine init failed: out of memory for allocators");
        return RET_FAIL;
    }

    /* timer manager and frame timer */
    g_eng->timer = timer_createinstance(TRUE);

    /* add engine's own data path to file-mgr */
    if (params->data_path != NULL)   {
        char data_path_ext[DH_PATH_MAX];
        path_getfileext(data_path_ext, params->data_path);
        if (str_isequal_nocase(data_path_ext, "pak"))    {
            if (IS_FAIL(pak_open(&g_eng->data_pak, mem_heap(), params->data_path, 0)))    {
                err_print(__FILE__, __LINE__, "engine init: could not open data pak");
                return RET_FAIL;
            }
        }   else   {
            if (!util_pathisdir(params->data_path)) {
                err_print(__FILE__, __LINE__, "engine init: data path is not valid");
                return RET_FAIL;
            }
            fio_addvdir(params->data_path, FALSE);
        }
        /* assume that share directory is same as data dir */
        path_getdir(g_eng->share_dir, params->data_path);
    }   else    {
        char data_path[DH_PATH_MAX];
        char share_dir[DH_PATH_MAX];
#ifndef SHARE_DIR
        char exe_dir[DH_PATH_MAX];
        path_join(share_dir, util_getexedir(exe_dir), "..", NULL);
        path_norm(share_dir, share_dir);
#else
        path_norm(share_dir, SHARE_DIR);
#endif
        path_join(data_path, share_dir, "data", NULL);
        if (!util_pathisdir(data_path)) {
            err_print(__FILE__, __LINE__, "engine init: data path is not valid");
            return RET_FAIL;
        }

        fio_addvdir(data_path, FALSE);  /* set default (config.h configured on build) data dir */
        strcpy(g_eng->share_dir, share_dir);
    }

    uint rs_flags = 0;
    /* activate hot loading in DEV mode */
    rs_flags |= BIT_CHECK(params->flags, ENG_FLAG_DEV) ? RS_FLAG_HOTLOADING : 0;
    if (!BIT_CHECK(params->flags, ENG_FLAG_DISABLEBGLOAD))  {
        rs_flags |= RS_FLAG_PREPARE_BGLOAD;
    }

    /* task manager */
    uint thread_cnt = maxui(g_eng->hwinfo.cpu_core_cnt - 1, 1);
    r = tsk_initmgr(thread_cnt, 0, tmp_sz, 0);
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "engine init failed: could not init task-mgr");
        return RET_FAIL;
    }
    struct allocator* tmp_alloc = tsk_get_tmpalloc(0);
    A_SAVE(tmp_alloc);

    /* resource manager (with only 1 thread for multi-thread loading) */
    r = rs_initmgr(rs_flags, 1);
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "engine init failed: could not init res-mgr");
        return RET_FAIL;
    }
    rs_set_dataalloc(&g_eng->lsr_alloc);

    /* graphics renderer */
    r = gfx_init(&params->gfx);
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "engine init failed: could not init gfx");
        return RET_FAIL;
    }

    /* debug HUD */
    r = hud_init(BIT_CHECK(params->flags, ENG_FLAG_CONSOLE));
    if (IS_FAIL(r))	{
        err_print(__FILE__, __LINE__, "engine init failed: could not init debug-hud");
        return RET_FAIL;
    }

    /* Physics */
    if (!BIT_CHECK(params->flags, ENG_FLAG_DISABLEPHX)) {
        r = phx_init(params);
        if (IS_FAIL(r)) {
            err_print(__FILE__, __LINE__, "engine init failed: could not init physics");
            return RET_FAIL;
        }
    }

    /* component manager */
    r = cmp_initmgr();
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "engine init failed: could not init cmp-mgr");
        return RET_FAIL;
    }
    cmp_set_globalalloc(&g_eng->data_alloc, tsk_get_tmpalloc(0));

    /* world manager */
    r = wld_initmgr();
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "engine init failed: could not init world-mgr");
        return RET_FAIL;
    }

    /* scene manager */
    r = scn_initmgr();
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "engine init failed: could not init scene-mgr");
        return RET_FAIL;
    }

    /* init lua */
    r = sct_init(&params->sct, BIT_CHECK(params->flags, ENG_FLAG_DEV) ? TRUE : FALSE);
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "engine init failed: could not init script engine");
        return RET_FAIL;
    }

    /* web-server */
#if defined(_PROFILE_)
    r = prf_initmgr();
    if (IS_FAIL(r))	{
    	log_print(LOG_WARNING, "profiler manager init failed: service will not be available");
    	prf_releasemgr();
    }
#endif

    /* lod-scheme */
    r = lod_initmgr();
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "engine init failed: could not init lod-scheme");
        return RET_FAIL;
    }

    /* init basic resources */
    r = rs_init_resources();
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "engine init failed: coult not init res-mgr resources");
        return RET_FAIL;
    }

    /* switch back to normal data allocator */
    rs_set_dataalloc(&g_eng->data_alloc);

    /* enable background-loading if res-mgr is prepared for (see above rs_initmgr) */
    if (gfx_check_feature(GFX_FEATURE_THREADED_CREATES))
        rs_add_flags(RS_FLAG_BGLOADING);
    log_print(LOG_TEXT, "init ok: ready.");

    /* init world vars */
    eng_world_regvars();

    /* engine specific console commnads */
    con_register_cmd("showfps", eng_console_showfps, NULL, "showfps [1*/0]");
    con_register_cmd("showft", eng_console_showft, NULL, "showft [1*/0]");
    con_register_cmd("showgraph", eng_console_showgraph, NULL, "showgraph [ft][fps][drawcalls]");
    con_register_cmd("lockfps", eng_console_lockfps, NULL, "lockfps [fps]");

    /* execute console commands - should be the final stage if initialization */
    if (BIT_CHECK(params->flags, ENG_FLAG_CONSOLE))	{
		for (uint i = 0; i < params->console_cmds_cnt; i++)	{
			con_exec(params->console_cmds + i*128);
		}
    }

    A_LOAD(tmp_alloc);
    return RET_OK;
}
예제 #22
0
bool MainWindow::connectLidar()
{
    // create the driver instance
    mDrv = RPlidarDriver::CreateDriver(RPlidarDriver::DRIVER_TYPE_SERIALPORT);

    if (!mDrv)
    {
        fprintf(stderr, "insufficent memory, exit\n");
        exit(-2);
    }

    if (IS_FAIL(mDrv->connect((const char*)mPath, mBaudrate)))
    {
        fprintf(stderr, "Error, cannot bind to the specified serial port %s.\n", mPath);
        return false;
    }
    mResult = mDrv->getDeviceInfo(mDevinfo);

    if (IS_FAIL(mResult))
    {
        if (mResult == RESULT_OPERATION_TIMEOUT)
        {
            // you can check the detailed failure reason
            fprintf(stderr, "Error, operation time out.\n");
        }
        else
        {
            fprintf(stderr, "Error, unexpected error, code: %x\n", mResult);
            // other unexpected result
        }
        return false;
    }

    printf("RPLIDAR S/N: ");
    for (int pos = 0; pos < 16 ;++pos)
    {
        printf("%02X", mDevinfo.serialnum[pos]);
    }

    printf("\n"
            "Version: "RPLIDAR_SDK_VERSION"\n"
            "Firmware Ver: %d.%02d\n"
            "Hardware Rev: %d\n"
            , mDevinfo.firmware_version>>8
            , mDevinfo.firmware_version & 0xFF
            , (int)mDevinfo.hardware_version);

    mResult = mDrv->getHealth(mHealthinfo);
    if (IS_OK(mResult))
    {   // the macro IS_OK is the preperred way to judge whether the operation is succeed.
        printf("RPLidar health status : ");
        switch (mHealthinfo.status)
        {
        case RPLIDAR_STATUS_OK:
            printf("OK.");
            break;
        case RPLIDAR_STATUS_WARNING:
            printf("Warning.");
            break;
        case RPLIDAR_STATUS_ERROR:
            printf("Error.");
            break;
        }
        printf(" (errorcode: %d)\n", mHealthinfo.error_code);

    }
    else
    {
        fprintf(stderr, "Error, cannot retrieve the lidar health code: %x\n", mResult);
        return false;
    }

    mDrv->startMotor();

    if (IS_FAIL(mDrv->startScan())) // you can force rplidar to perform scan operation regardless whether the motor is rotating
    {
        fprintf(stderr, "Error, cannot start the scan operation.\n");
        return false;
    }

    if (IS_FAIL(captureAndDisplay()))
    {
        fprintf(stderr, "Error, cannot grab scan data.\n");
        return false;
    }

    mRefreshTimer.start(200);
    connect(&mRefreshTimer, &QTimer::timeout, this, &MainWindow::captureAndDisplay);
    return true;
}
예제 #23
0
result_t app_init(const char* name, const struct init_params* params)
{
    ASSERT(g_app == NULL);
    if (g_app != NULL)  {
        err_print(__FILE__, __LINE__, "application already initialized");
        return RET_FAIL;
    }

    result_t r;

    log_print(LOG_TEXT, "init Direct3D app ...");
    /* create application */
    struct app_win* app = (struct app_win*)ALLOC(sizeof(struct app_win), 0);
    ASSERT(app);
    memset(app, 0x00, sizeof(struct app_win));

    g_app = app;
    str_safecpy(app->name, sizeof(app->name), name);

    uint width = params->gfx.width;
    uint height = params->gfx.height;
    if (width == 0)
        width = DEFAULT_WIDTH;
    if (height == 0)
        height = DEFAULT_HEIGHT;

    HINSTANCE myinst = GetModuleHandle(NULL);

    /* register window class */
    WNDCLASSEX wndcls;
    memset(&wndcls, 0x00, sizeof(WNDCLASSEX));
    wndcls.cbSize =  sizeof(WNDCLASSEX);
    wndcls.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    wndcls.lpfnWndProc = msg_callback;
    wndcls.cbClsExtra = 0;
    wndcls.cbWndExtra = 0;
    wndcls.hInstance = myinst;
    wndcls.hIcon = NULL;
    wndcls.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndcls.hbrBackground = (HBRUSH)(GetStockObject(WHITE_BRUSH));
    wndcls.lpszMenuName = NULL;
    wndcls.lpszClassName = app->name;
    wndcls.hIconSm = NULL;
    if (!RegisterClassEx(&wndcls))  {
        err_print(__FILE__, __LINE__, "win-app init failed");
        return RET_FAIL;
    }

    /* create window */
    RECT wndrc = {0, 0, width, height};
    uint x;
    uint y;

    AdjustWindowRect(&wndrc, WS_OVERLAPPEDWINDOW, FALSE);
    calc_screenpos(wndrc.right-wndrc.left, wndrc.bottom-wndrc.top, &x, &y);
    app->hwnd = CreateWindow(app->name,
                                name,
                                WS_OVERLAPPEDWINDOW,
                                x, y,
                                wndrc.right - wndrc.left,
                                wndrc.bottom - wndrc.top,
                                NULL, NULL,
                                myinst,
                                NULL);
    if (app->hwnd == NULL)  {
        err_print(__FILE__, __LINE__, "win-app init failed: could not create window");
        return RET_FAIL;
    }

    /* init DXGI */
    r = app_init_dxgi(params, &app->dxgi_factory, &app->dxgi_adapter, &app->dev, &app->main_ctx,
        &app->d3dver);
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "win-app init failed: init DXGI failed");
        return RET_FAIL;
    }
    app->d3d_dbg = BIT_CHECK(params->gfx.flags, GFX_FLAG_DEBUG);
    app->inst = myinst;
    app->width = width;
    app->height = height;
    app->always_active = TRUE;
    app->refresh_rate = params->gfx.refresh_rate;

    /* create default swapchain */
    r = app_init_swapchain(&app->schain, app->hwnd, width, height, params->gfx.refresh_rate,
        BIT_CHECK(params->gfx.flags, GFX_FLAG_FULLSCREEN),
        BIT_CHECK(params->gfx.flags, GFX_FLAG_VSYNC));
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "win-app init failed: init swapchain failed");
        return RET_FAIL;
    }

    struct app_swapchain* sc = &app->schain;
    app->main_ctx->OMSetRenderTargets(1, &sc->rtv, sc->dsv);
    app->vsync = BIT_CHECK(params->gfx.flags, GFX_FLAG_VSYNC);

    /* input */
    input_init();

    app->init = TRUE;
    return RET_OK;
}
예제 #24
0
파일: gfx-csm.c 프로젝트: septag/darkhammer
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;
}
예제 #25
0
result_t app_d3d_initdev(wnd_t hwnd, const char* name, const struct init_params* params)
{
    ASSERT(g_app == NULL);
    if (g_app != NULL)  {
        err_print(__FILE__, __LINE__, "application already initialized");
        return RET_FAIL;
    }

    result_t r;

    log_print(LOG_TEXT, "init Direct3D device only ...");

    /* create application */
    struct app_win* app = (struct app_win*)ALLOC(sizeof(struct app_win), 0);
    ASSERT(app);
    memset(app, 0x00, sizeof(struct app_win));

    g_app = app;
    app->dev_only = TRUE;
    str_safecpy(app->name, sizeof(app->name), name);

    uint width = params->gfx.width;
    uint height = params->gfx.height;
    if (width == 0)
        width = DEFAULT_WIDTH;
    if (height == 0)
        height = DEFAULT_HEIGHT;

    HINSTANCE myinst = GetModuleHandle(NULL);

    /* create window */
    RECT wndrc = {0, 0, width, height};

    /* init DXGI */
    r = app_init_dxgi(params, &app->dxgi_factory, &app->dxgi_adapter, &app->dev, &app->main_ctx,
        &app->d3dver);
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "win-app init failed: init DXGI failed");
        return RET_FAIL;
    }
    app->d3d_dbg = BIT_CHECK(params->gfx.flags, GFX_FLAG_DEBUG);
    app->inst = myinst;
    app->width = width;
    app->height = height;
    app->always_active = TRUE;
    app->refresh_rate = params->gfx.refresh_rate;

    /* create default swapchain */
    r = app_init_swapchain(&app->schain, hwnd, width, height, params->gfx.refresh_rate,
        BIT_CHECK(params->gfx.flags, GFX_FLAG_FULLSCREEN),
        BIT_CHECK(params->gfx.flags, GFX_FLAG_VSYNC));
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "win-app init failed: add swapchain failed");
        return RET_FAIL;
    }

    struct app_swapchain* sc = &app->schain;
    app->main_ctx->OMSetRenderTargets(1, &sc->rtv, sc->dsv);
    app->vsync = BIT_CHECK(params->gfx.flags, GFX_FLAG_VSYNC);

    app->init = TRUE;
    return RET_OK;
}
예제 #26
0
int main(int argc, char** argv)
{
    result_t r;
    memset(g_obj_barrels, 0x00, sizeof(g_obj_barrels));

    /* Init core library */
    r = core_init(CORE_INIT_ALL);

    /* After core init, you can set logging options */
    log_outputconsole(TRUE);
    set_logfile();

    /* load config file (json) */
    init_params* params = app_config_default();
    if (params == NULL) {
        err_sendtolog(FALSE);
        core_release(FALSE);
        return -1;
    }

    /* Add our stuff to init params
     * Engine's data directory must be changed
     */
    params->flags |= (ENG_FLAG_CONSOLE | ENG_FLAG_DEV);

    /* Initialize application (graphics device and rendering window)
     * Application name will also, be the name of the main window */
    r = app_init(APP_NAME, params);
    if (IS_FAIL(r)) {
        err_sendtolog(FALSE);
        core_release(FALSE);
        app_config_unload(params);
        return -1;
    }

    /* Initialize engine */
    r = eng_init(params);

    /* init params isn't needed anymore */
    app_config_unload(params);
    if (IS_FAIL(r)) {
        err_sendtolog(FALSE);
        eng_release();
        app_release();
        core_release(TRUE);
        return -1;
    }

    if (!init_scene())  {
        err_sendtolog(FALSE);
        eng_release();
        app_release();
        core_release(TRUE);
        return -1;
    }

    /* Set application callbacks */
    app_window_setupdatefn(update_callback);
    app_window_setkeypressfn(keypress_callback);
    app_window_setactivefn(activate_callback);
    app_window_setresizefn(resize_callback);
    gfx_set_debug_renderfunc(debug_view_callback);

    /* Initialize ok: show the main window */
    app_window_show();

    /* Enter message loop and update engine */
    app_window_run();

    /* cleanup */
    release_scene();
    eng_release();
    app_release();
    core_release(TRUE);
    return 0;
}
예제 #27
0
/*************************************************************************************************
 * Threads
 */
mt_thread mt_thread_create(
    pfn_mt_thread_kernel kernel_fn, pfn_mt_thread_init init_fn, pfn_mt_thread_release release_fn,
    enum mt_thread_priority pr, size_t local_mem_sz, size_t tmp_mem_sz, void* param1, void* param2)
{
    static uint count = 0;
    result_t r;
    mt_thread thread = (mt_thread)ALLOC(sizeof(struct mt_thread_data), 0);
    if (thread == NULL)
        return NULL;
    memset(thread, 0x00, sizeof(struct mt_thread_data));

    if (local_mem_sz > 0)   {
        r = mem_freelist_create(mem_heap(), &thread->local_mem, local_mem_sz, 0);
        if (IS_FAIL(r)) {
            FREE(thread);
            return NULL;
        }
        mem_freelist_bindalloc(&thread->local_mem, &thread->local_alloc);
    }

    if (tmp_mem_sz > 0) {
        r = mem_stack_create(mem_heap(), &thread->tmp_mem, tmp_mem_sz, 0);
        if (IS_FAIL(r)) {
            FREE(thread);
            return NULL;
        }
        mem_stack_bindalloc(&thread->tmp_mem, &thread->tmp_alloc);
    }

    thread->kernel_fn = kernel_fn;
    thread->init_fn = init_fn;
    thread->release_fn = release_fn;
    thread->param1 = param1;
    thread->param2 = param2;
    thread->pr = pr;

    char e1name[32];
    char e2name[32];
    sprintf(e1name, "stop:t(%d)", count);
    sprintf(e2name, "resume:t(%d)", count);
    count++;

    thread->events[EVENT_STOP] = CreateEvent(NULL, TRUE, FALSE, e1name);
    thread->events[EVENT_RESUME] = CreateEvent(NULL, TRUE, TRUE, e2name);

    if (thread->events[EVENT_STOP] == NULL || thread->events[EVENT_RESUME] == NULL)
        return NULL;

    HANDLE t = CreateThread(NULL, 0, thread_callback, thread, 0, (DWORD*)&thread->id);
    if (t == NULL) {
        mt_thread_destroy(thread);
        return NULL;
    }

    thread->t = t;

    switch (pr)   {
    case MT_THREAD_NORMAL:    SetThreadPriority(thread->t, THREAD_PRIORITY_NORMAL);    break;
    case MT_THREAD_HIGH:      SetThreadPriority(thread->t, THREAD_PRIORITY_HIGHEST);   break;
    case MT_THREAD_LOW:       SetThreadPriority(thread->t, THREAD_PRIORITY_LOWEST);    break;
    }

    return thread;
}