📄 render3d.c
字号:
/*scaling is still needed for bitmap*/ scaleX = gf_divfix(INT2FIX(sr->out_width), INT2FIX(sr->compositor->scene_width)); scaleY = gf_divfix(INT2FIX(sr->out_height), INT2FIX(sr->compositor->scene_height)); R3D_SetScaling(sr, scaleX, scaleY); return GF_OK;}void R3D_SceneReset(GF_VisualRenderer *vr){ Render3D *sr = (Render3D*)vr->user_priv; sr->main_surface_setup = 0;}void R3D_ReloadConfig(GF_VisualRenderer *vr){ const char *sOpt; Render3D *sr = (Render3D *)vr->user_priv; gf_sr_lock(sr->compositor, 1); /*currently: - no tesselator for GL-ES, so use raster outlines. - no support for npow2 textures, and no support for DrawPixels */#ifndef GPAC_USE_OGL_ES sOpt = gf_modules_get_option((GF_BaseInterface *)vr, "Render3D", "RasterOutlines"); sr->raster_outlines = (sOpt && !stricmp(sOpt, "yes") ) ? 1 : 0; sOpt = gf_modules_get_option((GF_BaseInterface *)vr, "Render3D", "EmulatePOW2"); sr->emul_pow2 = (sOpt && !stricmp(sOpt, "yes") ) ? 1 : 0; sOpt = gf_modules_get_option((GF_BaseInterface *)vr, "Render3D", "BitmapCopyPixels"); sr->bitmap_use_pixels = (sOpt && !stricmp(sOpt, "yes") ) ? 1 : 0;#else sr->raster_outlines = 1; sr->emul_pow2 = 1; sr->bitmap_use_pixels = 0;#endif sOpt = gf_modules_get_option((GF_BaseInterface *)vr, "Render3D", "PolygonAA"); sr->poly_aa = (sOpt && !stricmp(sOpt, "yes") ) ? 1 : 0; sOpt = gf_modules_get_option((GF_BaseInterface *)vr, "Render3D", "BackFaceCulling"); if (sOpt && !stricmp(sOpt, "Off")) sr->backcull = GF_BACK_CULL_OFF; else if (sOpt && !stricmp(sOpt, "Alpha")) sr->backcull = GF_BACK_CULL_ALPHA; else sr->backcull = GF_BACK_CULL_ON; sOpt = gf_modules_get_option((GF_BaseInterface *)vr, "Render3D", "Wireframe"); if (sOpt && !stricmp(sOpt, "WireOnly")) sr->wiremode = GF_WIREFRAME_ONLY; else if (sOpt && !stricmp(sOpt, "WireOnSolid")) sr->wiremode = GF_WIREFRAME_SOLID; else sr->wiremode = GF_WIREFRAME_NONE; sOpt = gf_modules_get_option((GF_BaseInterface *)vr, "Render3D", "DrawNormals"); if (sOpt && !stricmp(sOpt, "PerFace")) sr->draw_normals = GF_NORMALS_FACE; else if (sOpt && !stricmp(sOpt, "PerVertex")) sr->draw_normals = GF_NORMALS_VERTEX; else sr->draw_normals = GF_NORMALS_NONE; sOpt = gf_modules_get_option((GF_BaseInterface *)vr, "Render3D", "DisableRectExt"); sr->disable_rect_ext = (sOpt && !stricmp(sOpt, "yes") ) ? 1 : 0; /*RECT texture support - we must reload HW*/ gf_sr_reset_graphics(sr->compositor); gf_sr_lock(sr->compositor, 0);}GF_Err R3D_LoadRenderer(GF_VisualRenderer *vr, GF_Renderer *compositor){ Render3D *sr; if (vr->user_priv) return GF_BAD_PARAM; GF_SAFEALLOC(sr, Render3D); if (!sr) return GF_OUT_OF_MEM; sr->compositor = compositor; sr->strike_bank = gf_list_new(); /*create default unit sphere and box for bounds*/ sr->unit_bbox = new_mesh(); mesh_new_unit_bbox(sr->unit_bbox); sr->top_effect = effect3d_new(); sr->sensors = gf_list_new(); sr->prev_sensors = gf_list_new(); /*note we create main surface only when attached to scene*/ sr->surface = VS_New(); sr->surface->render = sr; sr->main_surface_setup = 0; /*default collision mode*/ sr->collide_mode = GF_COLLISION_DISPLACEMENT;// sr->collide_mode = GF_COLLISION_NORMAL; sr->gravity_on = 1; vr->user_priv = sr; R3D_ReloadConfig(vr); return GF_OK;}void R3D_UnloadRenderer(GF_VisualRenderer *vr){ Render3D *sr = (Render3D *)vr->user_priv; if (!sr) return; assert(!gf_list_count(sr->strike_bank)); gf_list_del(sr->strike_bank); if (sr->unit_bbox) mesh_free(sr->unit_bbox); effect3d_delete(sr->top_effect); gf_list_del(sr->sensors); gf_list_del(sr->prev_sensors); VS_Delete(sr->surface); free(sr); vr->user_priv = NULL;}void R3D_GraphicsReset(GF_VisualRenderer *vr){ Render3D *sr = (Render3D *)vr->user_priv; if (!sr) return; R3D_LoadExtensions(sr);}GF_Camera *R3D_GetCamera(Render3D *sr) { if (sr->active_layer) { return l3d_get_camera(sr->active_layer); } else { return &sr->surface->camera; }}GF_Err R3D_SetOption(GF_VisualRenderer *vr, u32 option, u32 value){ GF_Node *n; GF_Camera *cam; Render3D *sr = (Render3D *)vr->user_priv; switch (option) {#ifndef GPAC_USE_OGL_ES case GF_OPT_RASTER_OUTLINES: sr->raster_outlines = value; return GF_OK;#endif case GF_OPT_EMULATE_POW2: sr->emul_pow2 = value; return GF_OK; case GF_OPT_POLYGON_ANTIALIAS: sr->poly_aa = value; return GF_OK; case GF_OPT_BACK_CULL: sr->backcull = value; return GF_OK; case GF_OPT_WIREFRAME: sr->wiremode = value; return GF_OK; case GF_OPT_NORMALS: sr->draw_normals = value; return GF_OK; case GF_OPT_RELOAD_CONFIG: R3D_ReloadConfig(vr); return GF_OK; case GF_OPT_NO_RECT_TEXTURE: if (value != sr->disable_rect_ext) { sr->disable_rect_ext = value; /*RECT texture support - we must reload HW*/ gf_sr_reset_graphics(sr->compositor); } return GF_OK; case GF_OPT_BITMAP_COPY: sr->bitmap_use_pixels = value; return GF_OK; case GF_OPT_ORIGINAL_VIEW: R3D_ResetCamera(sr); return GF_OK; case GF_OPT_NAVIGATION_TYPE: if (!sr->surface) return GF_BAD_PARAM; R3D_ResetCamera(sr); return GF_OK; case GF_OPT_NAVIGATION: cam = R3D_GetCamera(sr); if (cam->navigation_flags & NAV_ANY) { /*if not specifying mode, try to (un)bind top*/ if (!value) { if (sr->active_layer) { l3d_bind_camera(sr->active_layer, 0, value); } else { n = (GF_Node*)gf_list_get(sr->surface->navigation_stack, 0); if (n) Bindable_SetSetBind(n, 0); else cam->navigate_mode = value; } } else { cam->navigate_mode = value; } return GF_OK; } return GF_NOT_SUPPORTED; case GF_OPT_HEADLIGHT: cam = R3D_GetCamera(sr); if (cam->navigation_flags & NAV_ANY) { if (value) cam->navigation_flags |= NAV_HEADLIGHT; else cam->navigation_flags &= ~NAV_HEADLIGHT; return GF_OK; } return GF_NOT_SUPPORTED; case GF_OPT_COLLISION: sr->collide_mode = value; return GF_OK; case GF_OPT_GRAVITY: cam = R3D_GetCamera(sr); sr->gravity_on = value; /*force collision pass*/ cam->last_pos.z -= 1; gf_sr_invalidate(sr->compositor, NULL); return GF_OK; default: return GF_BAD_PARAM; }}u32 R3D_GetOption(GF_VisualRenderer *vr, u32 option){ GF_Camera *cam; Render3D *sr = (Render3D *)vr->user_priv; switch (option) { case GF_OPT_RASTER_OUTLINES: return sr->raster_outlines;#ifndef GPAC_USE_OGL_ES return sr->raster_outlines;#else return 1;#endif case GF_OPT_EMULATE_POW2: return sr->emul_pow2; case GF_OPT_POLYGON_ANTIALIAS: return sr->poly_aa; case GF_OPT_BACK_CULL: return sr->backcull; case GF_OPT_WIREFRAME: return sr->wiremode; case GF_OPT_NORMALS: return sr->draw_normals; case GF_OPT_NO_RECT_TEXTURE: return sr->disable_rect_ext; case GF_OPT_BITMAP_COPY: return sr->bitmap_use_pixels; case GF_OPT_NAVIGATION_TYPE: cam = R3D_GetCamera(sr); if (!(cam->navigation_flags & NAV_ANY)) return GF_NAVIGATE_TYPE_NONE; return ((sr->root_is_3D || sr->active_layer) ? GF_NAVIGATE_TYPE_3D : GF_NAVIGATE_TYPE_2D); case GF_OPT_NAVIGATION: cam = R3D_GetCamera(sr); return cam->navigate_mode; case GF_OPT_HEADLIGHT: cam = R3D_GetCamera(sr); return (cam->navigation_flags & NAV_HEADLIGHT) ? 1 : 0; case GF_OPT_COLLISION: return sr->collide_mode; case GF_OPT_GRAVITY: return sr->gravity_on; default: return 0; }}GF_Err R3D_GetScreenBuffer(GF_VisualRenderer *vr, GF_VideoSurface *framebuffer);GF_Err R3D_ReleaseScreenBuffer(GF_VisualRenderer *vr, GF_VideoSurface *framebuffer);GF_Err R3D_GetViewpoint(GF_VisualRenderer *vr, u32 viewpoint_idx, const char **outName, Bool *is_bound);GF_Err R3D_SetViewpoint(GF_VisualRenderer *vr, u32 viewpoint_idx, const char *viewpoint_name);/*render inline scene*/void R3D_RenderInline(GF_VisualRenderer *vr, GF_Node *inline_parent, GF_Node *inline_root, void *rs){ Bool use_pm; u32 h, w; Fixed prev_scale; GF_Matrix gf_mx_bck, mx; GF_SceneGraph *in_scene; RenderEffect3D *eff = (RenderEffect3D *)rs; in_scene = gf_node_get_graph(inline_root); use_pm = gf_sg_use_pixel_metrics(in_scene); if (use_pm == eff->is_pixel_metrics) { gf_node_render(inline_root, rs); return; } gf_mx_copy(gf_mx_bck, eff->model_matrix); prev_scale = eff->min_hsize; /*override aspect ratio if any size info is given in the scene*/ if (gf_sg_get_scene_size_info(in_scene, &w, &h)) { Fixed scale = INT2FIX(MIN(w, h)) / 2; if (scale) eff->min_hsize = scale; } gf_mx_init(mx); /*apply meterMetrics<->pixelMetrics scale*/ if (!use_pm) { gf_mx_add_scale(&mx, eff->min_hsize, eff->min_hsize, eff->min_hsize); } else { Fixed inv_scale = gf_invfix(eff->min_hsize); gf_mx_add_scale(&mx, inv_scale, inv_scale, inv_scale); } eff->is_pixel_metrics = use_pm; gf_mx_add_matrix(&eff->model_matrix, &mx); if (eff->traversing_mode==TRAVERSE_SORT) { VS3D_PushMatrix(eff->surface); VS3D_MultMatrix(eff->surface, mx.m); gf_node_render(inline_root, rs); VS3D_PopMatrix(eff->surface); } else { gf_node_render(inline_root, rs); } eff->is_pixel_metrics = !use_pm; gf_mx_copy(eff->model_matrix, gf_mx_bck);}static Bool R3D_ScriptAction(GF_VisualRenderer *vr, u32 type, GF_Node *n, GF_JSAPIParam *param){ //Render3D *sr = (Render3D *)vr->user_priv; switch (type) { case GF_JSAPI_OP_LOAD_URL: { GF_Node *target; char *sub_url = strrchr(param->uri.url, '#'); if (!sub_url) return 0; target = gf_sg_find_node_by_name(gf_node_get_graph(n), sub_url+1); if (target) { switch (gf_node_get_tag(target)) { case TAG_MPEG4_Viewport: ((M_Viewport *)target)->set_bind = 1; ((M_Viewport *)target)->on_set_bind(n); return 1; case TAG_MPEG4_Viewpoint: case TAG_X3D_Viewpoint: ((M_Viewpoint *)target)->set_bind = 1; ((M_Viewpoint *)target)->on_set_bind(target); return 1; } } return 0; } default: return 0; }}/*interface query*/GF_EXPORTBool QueryInterface(u32 InterfaceType){ if (InterfaceType == GF_RENDERER_INTERFACE) return 1; return 0;}/*interface create*/GF_EXPORTGF_BaseInterface *LoadInterface(u32 InterfaceType){ GF_VisualRenderer *sr; if (InterfaceType != GF_RENDERER_INTERFACE) return NULL; GF_SAFEALLOC(sr, GF_VisualRenderer); if (!sr) return NULL; GF_REGISTER_MODULE_INTERFACE(sr, GF_RENDERER_INTERFACE, "GPAC 3D Renderer", "gpac distribution"); sr->LoadRenderer = R3D_LoadRenderer; sr->UnloadRenderer = R3D_UnloadRenderer; sr->GraphicsReset = R3D_GraphicsReset; sr->NodeChanged = R3D_NodeChanged; sr->NodeInit = R3D_NodeInit; sr->DrawScene = R3D_DrawScene; sr->RenderInline = R3D_RenderInline; sr->ExecuteEvent = R3D_ExecuteEvent; sr->RecomputeAR = R3D_RecomputeAR; sr->SceneReset = R3D_SceneReset; sr->AllocTexture = tx_allocate; sr->ReleaseTexture = tx_delete; sr->SetTextureData = R3D_SetTextureData; sr->TextureHWReset = R3D_TextureHWReset; sr->SetViewpoint = R3D_SetViewpoint; sr->GetViewpoint = R3D_GetViewpoint; sr->ScriptAction = R3D_ScriptAction; sr->SetOption = R3D_SetOption; sr->GetOption = R3D_GetOption; sr->GetScreenBuffer = R3D_GetScreenBuffer; sr->ReleaseScreenBuffer = R3D_ReleaseScreenBuffer; /*signal we need openGL*/ sr->bNeedsGL = 1; sr->user_priv = NULL; return (GF_BaseInterface *)sr;}/*interface destroy*/GF_EXPORTvoid ShutdownInterface(GF_BaseInterface *ifce){ GF_VisualRenderer *rend = (GF_VisualRenderer *)ifce; if (rend->InterfaceType != GF_RENDERER_INTERFACE) return; assert(rend->user_priv==NULL); free(rend);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -