📄 background.c
字号:
} } if (pad) { vx.color = end_col; } else { frac = gf_divfix(angle - start_angle, next_angle - start_angle) ; vx.color.red = gf_mulfix(end_col.red - start_col.red, frac) + start_col.red; vx.color.green = gf_mulfix(end_col.green - start_col.green, frac) + start_col.green; vx.color.blue = gf_mulfix(end_col.blue - start_col.blue, frac) + start_col.blue; } vx.pos.y = gf_sin(GF_PI2 - angle); r = gf_sqrt(FIX_ONE - gf_mulfix(vx.pos.y, vx.pos.y)); new_idx = mesh->v_count; for (j = 0; j < step_div_h; j++) { Fixed lon = 2 * GF_PI * j / step_div_h; vx.pos.x = gf_mulfix(gf_sin(lon), r); vx.pos.z = gf_mulfix(gf_cos(lon), r); vx.normal = gf_vec_scale(vx.pos, FIX_ONE /*-FIX_ONE*/); gf_vec_norm(&vx.normal); mesh_set_vertex_vx(mesh, &vx); if (j) { if (i>1) { mesh_set_triangle(mesh, last_idx+j, new_idx+j, new_idx+j-1); mesh_set_triangle(mesh, last_idx+j, new_idx+j-1, last_idx+j-1); } else { mesh_set_triangle(mesh, 0, new_idx+j, new_idx+j-1); } } } if (i>1) { mesh_set_triangle(mesh, last_idx, new_idx, new_idx+step_div_h-1); mesh_set_triangle(mesh, last_idx, new_idx+step_div_h-1, last_idx+step_div_h-1); } else { mesh_set_triangle(mesh, 0, new_idx, new_idx+step_div_h-1); } last_idx = new_idx; } if (!ground_dome) { new_idx = mesh->v_count; vx.pos.x = vx.pos.z = 0; vx.pos.y = -FIX_ONE; vx.normal.x = vx.normal.z = 0; vx.normal.y = FIX_ONE; mesh_set_vertex_vx(mesh, &vx); for (j=1; j < step_div_h; j++) { mesh_set_triangle(mesh, last_idx+j-1, last_idx+j, new_idx); } mesh_set_triangle(mesh, last_idx+step_div_h-1, last_idx, new_idx); } mesh->flags |= MESH_HAS_COLOR | MESH_NO_TEXTURE; mesh_update_bounds(mesh);}static void back_draw_texture(RenderEffect3D *eff, GF_TextureHandler *txh, GF_Mesh *mesh){ if (tx_enable(txh, NULL)) { eff->mesh_has_texture = 1; VS3D_DrawMesh(eff, mesh); tx_disable(txh); eff->mesh_has_texture = 0; }}static void RenderBackground(GF_Node *node, void *rs, Bool is_destroy){ M_Background *bck; BackgroundStack *st; SFColor bcol; SFVec4f res; Fixed scale; Bool has_sky, has_ground, front_tx, back_tx, top_tx, bottom_tx, right_tx, left_tx; GF_Matrix mx; Render3D *sr; RenderEffect3D *eff = (RenderEffect3D *)rs; if (is_destroy) { DestroyBackground(node); return; } gf_node_dirty_clear(node, 0); bck = (M_Background *)node; st = (BackgroundStack *) gf_node_get_private(node); sr = (Render3D*)st->compositor->visual_renderer->user_priv; assert(eff->backgrounds); /*first traverse, bound if needed*/ if (gf_list_find(eff->backgrounds, node) < 0) { gf_list_add(eff->backgrounds, node); assert(gf_list_find(st->reg_stacks, eff->backgrounds)==-1); gf_list_add(st->reg_stacks, eff->backgrounds); /*only bound if we're on top*/ if (gf_list_get(eff->backgrounds, 0) == bck) { if (!bck->isBound) Bindable_SetIsBound(node, 1); } /*check streams*/ if (back_use_texture(&bck->frontUrl) && !st->txh_front.is_open) gf_sr_texture_play(&st->txh_front, &bck->frontUrl); if (back_use_texture(&bck->bottomUrl) && !st->txh_bottom.is_open) gf_sr_texture_play(&st->txh_bottom, &bck->bottomUrl); if (back_use_texture(&bck->backUrl) && !st->txh_back.is_open) gf_sr_texture_play(&st->txh_back, &bck->backUrl); if (back_use_texture(&bck->topUrl) && !st->txh_top.is_open) gf_sr_texture_play(&st->txh_top, &bck->topUrl); if (back_use_texture(&bck->rightUrl) && !st->txh_right.is_open) gf_sr_texture_play(&st->txh_right, &bck->rightUrl); if (back_use_texture(&bck->leftUrl) && !st->txh_left.is_open) gf_sr_texture_play(&st->txh_left, &bck->leftUrl); /*in any case don't draw the first time (since the background could have been declared last)*/ gf_sr_invalidate(st->compositor, NULL); return; } if (!bck->isBound) return; if (eff->traversing_mode != TRAVERSE_RENDER_BINDABLE) return; front_tx = back_gf_sr_texture_enabled(&bck->frontUrl, &st->txh_front); back_tx = back_gf_sr_texture_enabled(&bck->backUrl, &st->txh_back); top_tx = back_gf_sr_texture_enabled(&bck->topUrl, &st->txh_top); bottom_tx = back_gf_sr_texture_enabled(&bck->bottomUrl, &st->txh_bottom); right_tx = back_gf_sr_texture_enabled(&bck->rightUrl, &st->txh_right); left_tx = back_gf_sr_texture_enabled(&bck->leftUrl, &st->txh_left); has_sky = ((bck->skyColor.count>1) && bck->skyAngle.count) ? 1 : 0; has_ground = ((bck->groundColor.count>1) && bck->groundAngle.count) ? 1 : 0; bcol.red = bcol.green = bcol.blue = 0; if (bck->skyColor.count) bcol = bck->skyColor.vals[0]; /*if we clear the main surface clear it entirely - ONLY IF NOT IN LAYER*/ if ((eff->surface == sr->surface) && (eff->surface->back_stack == eff->backgrounds)) { VS3D_ClearSurface(eff->surface, bcol, FIX_ONE); if (!has_sky && !has_ground && !front_tx && !back_tx && !top_tx && !bottom_tx && !left_tx && !right_tx) { return; } } VS3D_SetState(eff->surface, F3D_LIGHT | F3D_BLEND, 0); /*undo translation*/ res.x = res.y = res.z = 0; res.q = FIX_ONE; gf_mx_apply_vec_4x4(&eff->camera->unprojection, &res); assert(res.q); res.x = gf_divfix(res.x, res.q); res.y = gf_divfix(res.y, res.q); res.z = gf_divfix(res.z, res.q); /*NB: we don't support local rotation of the background ...*/ if (has_sky) { if (!st->sky_mesh) { st->sky_mesh = new_mesh(); back_build_dome(st->sky_mesh, &bck->skyAngle, &bck->skyColor, 0); } VS3D_PushMatrix(eff->surface); gf_mx_init(mx); gf_mx_add_translation(&mx, res.x, res.y, res.z); /*CHECKME - not sure why, we need to scale less in fixed point otherwise z-far clipping occur - probably some rounding issues...*/#ifdef GPAC_FIXED_POINT scale = (eff->camera->z_far/10)*8;#else scale = 9*eff->camera->z_far/10;#endif gf_mx_add_scale(&mx, scale, scale, scale); VS3D_MultMatrix(eff->surface, mx.m); VS3D_DrawMesh(eff, st->sky_mesh); VS3D_PopMatrix(eff->surface); } if (has_ground) { if (!st->ground_mesh) { st->ground_mesh = new_mesh(); back_build_dome(st->ground_mesh, &bck->groundAngle, &bck->groundColor, 1); } VS3D_PushMatrix(eff->surface); gf_mx_init(mx); gf_mx_add_translation(&mx, res.x, res.y, res.z); /*cf above*/#ifdef GPAC_FIXED_POINT scale = (eff->camera->z_far/100)*70;#else scale = 85*eff->camera->z_far/100;#endif gf_mx_add_scale(&mx, scale, -scale, scale); VS3D_MultMatrix(eff->surface, mx.m); VS3D_DrawMesh(eff, st->ground_mesh); VS3D_PopMatrix(eff->surface); } if (front_tx || back_tx || left_tx || right_tx || top_tx || bottom_tx) { VS3D_PushMatrix(eff->surface); gf_mx_init(mx); gf_mx_add_translation(&mx, res.x, res.y, res.z);#ifdef GPAC_FIXED_POINT scale = (eff->camera->z_far/100)*70; gf_mx_add_scale(&mx, scale, scale, scale);#else gf_mx_add_scale(&mx, eff->camera->z_far, eff->camera->z_far, eff->camera->z_far);#endif VS3D_MultMatrix(eff->surface, mx.m); VS3D_SetAntiAlias(eff->surface, 1); if (front_tx) back_draw_texture(eff, &st->txh_front, st->front_mesh); if (back_tx) back_draw_texture(eff, &st->txh_back, st->back_mesh); if (top_tx) back_draw_texture(eff, &st->txh_top, st->top_mesh); if (bottom_tx) back_draw_texture(eff, &st->txh_bottom, st->bottom_mesh); if (left_tx) back_draw_texture(eff, &st->txh_left, st->left_mesh); if (right_tx) back_draw_texture(eff, &st->txh_right, st->right_mesh); VS3D_PopMatrix(eff->surface); }}static void back_set_bind(GF_Node *node){ BackgroundStack *st = (BackgroundStack *)gf_node_get_private(node); Bindable_OnSetBind(node, st->reg_stacks); /*and redraw scene*/ gf_sr_invalidate(st->compositor, NULL);}void R3D_InitBackground(Render3D *sr, GF_Node *node){ BackgroundStack *ptr; GF_SAFEALLOC(ptr, BackgroundStack); gf_sr_traversable_setup(ptr, node, sr->compositor); ptr->reg_stacks = gf_list_new(); ((M_Background *)node)->on_set_bind = back_set_bind; /*build texture cube*/ ptr->front_mesh = new_mesh(); mesh_set_vertex(ptr->front_mesh, -PLANE_HSIZE, -PLANE_HSIZE, -PLANE_HSIZE_LOW, 0, 0, FIX_ONE, 0, 0); mesh_set_vertex(ptr->front_mesh, PLANE_HSIZE, -PLANE_HSIZE, -PLANE_HSIZE_LOW, 0, 0, FIX_ONE, FIX_ONE, 0); mesh_set_vertex(ptr->front_mesh, PLANE_HSIZE, PLANE_HSIZE, -PLANE_HSIZE_LOW, 0, 0, FIX_ONE, FIX_ONE, FIX_ONE); mesh_set_vertex(ptr->front_mesh, -PLANE_HSIZE, PLANE_HSIZE, -PLANE_HSIZE_LOW, 0, 0, FIX_ONE, 0, FIX_ONE); mesh_set_triangle(ptr->front_mesh, 0, 1, 2); mesh_set_triangle(ptr->front_mesh, 0, 2, 3); mesh_update_bounds(ptr->front_mesh); ptr->back_mesh = new_mesh(); mesh_set_vertex(ptr->back_mesh, -PLANE_HSIZE, -PLANE_HSIZE, PLANE_HSIZE_LOW, 0, 0, -FIX_ONE, FIX_ONE, 0); mesh_set_vertex(ptr->back_mesh, PLANE_HSIZE, -PLANE_HSIZE, PLANE_HSIZE_LOW, 0, 0, -FIX_ONE, 0, 0); mesh_set_vertex(ptr->back_mesh, PLANE_HSIZE, PLANE_HSIZE, PLANE_HSIZE_LOW, 0, 0, -FIX_ONE, 0, FIX_ONE); mesh_set_vertex(ptr->back_mesh, -PLANE_HSIZE, PLANE_HSIZE, PLANE_HSIZE_LOW, 0, 0, -FIX_ONE, FIX_ONE, FIX_ONE); mesh_set_triangle(ptr->back_mesh, 0, 1, 2); mesh_set_triangle(ptr->back_mesh, 0, 2, 3); mesh_update_bounds(ptr->back_mesh); ptr->top_mesh = new_mesh(); mesh_set_vertex(ptr->top_mesh, -PLANE_HSIZE, PLANE_HSIZE_LOW, PLANE_HSIZE, 0, -FIX_ONE, 0, 0, 0); mesh_set_vertex(ptr->top_mesh, PLANE_HSIZE, PLANE_HSIZE_LOW, PLANE_HSIZE, 0, -FIX_ONE, 0, 0, FIX_ONE); mesh_set_vertex(ptr->top_mesh, PLANE_HSIZE, PLANE_HSIZE_LOW, -PLANE_HSIZE, 0, -FIX_ONE, 0, FIX_ONE, FIX_ONE); mesh_set_vertex(ptr->top_mesh, -PLANE_HSIZE, PLANE_HSIZE_LOW, -PLANE_HSIZE, 0, -FIX_ONE, 0, FIX_ONE, 0); mesh_set_triangle(ptr->top_mesh, 0, 1, 2); mesh_set_triangle(ptr->top_mesh, 0, 2, 3); mesh_update_bounds(ptr->top_mesh); ptr->bottom_mesh = new_mesh(); mesh_set_vertex(ptr->bottom_mesh, -PLANE_HSIZE, -PLANE_HSIZE_LOW, -PLANE_HSIZE, 0, FIX_ONE, 0, FIX_ONE, FIX_ONE); mesh_set_vertex(ptr->bottom_mesh, PLANE_HSIZE, -PLANE_HSIZE_LOW, -PLANE_HSIZE, 0, FIX_ONE, 0, FIX_ONE, 0); mesh_set_vertex(ptr->bottom_mesh, PLANE_HSIZE, -PLANE_HSIZE_LOW, PLANE_HSIZE, 0, FIX_ONE, 0, 0, 0); mesh_set_vertex(ptr->bottom_mesh, -PLANE_HSIZE, -PLANE_HSIZE_LOW, PLANE_HSIZE, 0, FIX_ONE, 0, 0, FIX_ONE); mesh_set_triangle(ptr->bottom_mesh, 0, 1, 2); mesh_set_triangle(ptr->bottom_mesh, 0, 2, 3); mesh_update_bounds(ptr->bottom_mesh); ptr->left_mesh = new_mesh(); mesh_set_vertex(ptr->left_mesh, -PLANE_HSIZE_LOW, -PLANE_HSIZE, -PLANE_HSIZE, FIX_ONE, 0, 0, FIX_ONE, 0); mesh_set_vertex(ptr->left_mesh, -PLANE_HSIZE_LOW, -PLANE_HSIZE, PLANE_HSIZE, FIX_ONE, 0, 0, 0, 0); mesh_set_vertex(ptr->left_mesh, -PLANE_HSIZE_LOW, PLANE_HSIZE, PLANE_HSIZE, FIX_ONE, 0, 0, 0, FIX_ONE); mesh_set_vertex(ptr->left_mesh, -PLANE_HSIZE_LOW, PLANE_HSIZE, -PLANE_HSIZE, FIX_ONE, 0, 0, FIX_ONE, FIX_ONE); mesh_set_triangle(ptr->left_mesh, 0, 1, 2); mesh_set_triangle(ptr->left_mesh, 0, 2, 3); mesh_update_bounds(ptr->left_mesh); ptr->right_mesh = new_mesh(); mesh_set_vertex(ptr->right_mesh, PLANE_HSIZE_LOW, -PLANE_HSIZE, PLANE_HSIZE, -FIX_ONE, 0, 0, FIX_ONE, 0); mesh_set_vertex(ptr->right_mesh, PLANE_HSIZE_LOW, -PLANE_HSIZE, -PLANE_HSIZE, -FIX_ONE, 0, 0, 0, 0); mesh_set_vertex(ptr->right_mesh, PLANE_HSIZE_LOW, PLANE_HSIZE, -PLANE_HSIZE, -FIX_ONE, 0, 0, 0, FIX_ONE); mesh_set_vertex(ptr->right_mesh, PLANE_HSIZE_LOW, PLANE_HSIZE, PLANE_HSIZE, -FIX_ONE, 0, 0, FIX_ONE, FIX_ONE); mesh_set_triangle(ptr->right_mesh, 0, 1, 2); mesh_set_triangle(ptr->right_mesh, 0, 2, 3); mesh_update_bounds(ptr->right_mesh); gf_sr_texture_setup(&ptr->txh_back, sr->compositor, node); ptr->txh_back.update_texture_fcnt = UpdateBackgroundTexture; gf_sr_texture_setup(&ptr->txh_front, sr->compositor, node); ptr->txh_front.update_texture_fcnt = UpdateBackgroundTexture; gf_sr_texture_setup(&ptr->txh_top, sr->compositor, node); ptr->txh_top.update_texture_fcnt = UpdateBackgroundTexture; gf_sr_texture_setup(&ptr->txh_bottom, sr->compositor, node); ptr->txh_bottom.update_texture_fcnt = UpdateBackgroundTexture; gf_sr_texture_setup(&ptr->txh_left, sr->compositor, node); ptr->txh_left.update_texture_fcnt = UpdateBackgroundTexture; gf_sr_texture_setup(&ptr->txh_right, sr->compositor, node); ptr->txh_right.update_texture_fcnt = UpdateBackgroundTexture; gf_node_set_private(node, ptr); gf_node_set_callback_function(node, RenderBackground);}void R3D_BackgroundModified(GF_Node *node){ M_Background *bck = (M_Background *)node; BackgroundStack *st = (BackgroundStack *) gf_node_get_private(node); if (!st) return; if (!gf_sg_vrml_field_equal(&bck->skyColor, &st->sky_col, GF_SG_VRML_MFCOLOR) || !gf_sg_vrml_field_equal(&bck->skyAngle, &st->sky_ang, GF_SG_VRML_MFFLOAT) ) { if (st->sky_mesh) mesh_free(st->sky_mesh); st->sky_mesh = NULL; gf_sg_vrml_field_copy(&st->sky_col, &bck->skyColor, GF_SG_VRML_MFCOLOR); gf_sg_vrml_field_copy(&st->sky_ang, &bck->skyAngle, GF_SG_VRML_MFFLOAT); } if (!gf_sg_vrml_field_equal(&bck->groundColor, &st->ground_col, GF_SG_VRML_MFCOLOR) || !gf_sg_vrml_field_equal(&bck->groundAngle, &st->ground_ang, GF_SG_VRML_MFFLOAT) ) { if (st->ground_mesh) mesh_free(st->ground_mesh); st->ground_mesh = NULL; gf_sg_vrml_field_copy(&st->ground_col, &bck->groundColor, GF_SG_VRML_MFCOLOR); gf_sg_vrml_field_copy(&st->ground_ang, &bck->groundAngle, GF_SG_VRML_MFFLOAT); } back_check_gf_sr_texture_change(&st->txh_front, &bck->frontUrl); back_check_gf_sr_texture_change(&st->txh_back, &bck->backUrl); back_check_gf_sr_texture_change(&st->txh_top, &bck->topUrl); back_check_gf_sr_texture_change(&st->txh_bottom, &bck->bottomUrl); back_check_gf_sr_texture_change(&st->txh_left, &bck->leftUrl); back_check_gf_sr_texture_change(&st->txh_right, &bck->rightUrl); gf_sr_invalidate(st->compositor, NULL);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -