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; }
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; }
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); }
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; }
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; }
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; }
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); }
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); }
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; }
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; }
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(), §ion->vtable, 10, 20, 0); if (IS_FAIL(r)) { err_printn(__FILE__, __LINE__, RET_OUTOFMEMORY); return 0; } r = arr_create(mem_heap(), §ion->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; }
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; }
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; }
/************************************************************************************************* * 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; }
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; }
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; }
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; }
/** * 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; }
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; }
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; }
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(¶ms->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(¶ms->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; }
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; }
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; }
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; }
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; }
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; }
/************************************************************************************************* * 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; }