diff --git a/common/3d/instance.cpp b/common/3d/instance.cpp index ee75924b0..70fb9f5a9 100644 --- a/common/3d/instance.cpp +++ b/common/3d/instance.cpp @@ -18,31 +18,16 @@ namespace dcx { -namespace { - -struct instance_context { - vms_matrix m; - vms_vector p; -}; - -} - -static std::array instance_stack; - -int instance_depth = 0; - //instance at specified point with specified orientation //if matrix==NULL, don't modify matrix. This will be like doing an offset -void g3_start_instance_matrix() +g3_instance_context g3_start_instance_matrix() { - auto &s = instance_stack.at(instance_depth++); - s.m = View_matrix; - s.p = View_position; + return {View_matrix, View_position}; } -void g3_start_instance_matrix(const vms_vector &pos, const vms_matrix &orient) +g3_instance_context g3_start_instance_matrix(const vms_vector &pos, const vms_matrix &orient) { - g3_start_instance_matrix(); + auto r = g3_start_instance_matrix(); //step 1: subtract object position from view position const auto tempv = vm_vec_sub(View_position, pos); @@ -52,28 +37,24 @@ void g3_start_instance_matrix(const vms_vector &pos, const vms_matrix &orient) //step 3: rotate object matrix through view_matrix (vm = ob * vm) View_matrix = vm_matrix_x_matrix(vm_transposed_matrix(orient), View_matrix); + return r; } //instance at specified point with specified orientation //if angles==NULL, don't modify matrix. This will be like doing an offset -void g3_start_instance_angles(const vms_vector &pos, const vms_angvec &angles) +g3_instance_context g3_start_instance_angles(const vms_vector &pos, const vms_angvec &angles) { const auto &&tm = vm_angles_2_matrix(angles); - g3_start_instance_matrix(pos, tm); + return g3_start_instance_matrix(pos, tm); } //pops the old context -void g3_done_instance() +void g3_done_instance(const g3_instance_context &ctx) { - instance_depth--; - - Assert(instance_depth >= 0); - - View_position = instance_stack[instance_depth].p; - View_matrix = instance_stack[instance_depth].m; + View_position = ctx.position; + View_matrix = ctx.matrix; } - } diff --git a/common/include/3d.h b/common/include/3d.h index 351623ded..010db36bf 100644 --- a/common/include/3d.h +++ b/common/include/3d.h @@ -99,6 +99,12 @@ struct g3s_point { namespace dcx { +struct g3_instance_context +{ + const vms_matrix matrix; + const vms_vector position; +}; + #if DXX_USE_OGL typedef const g3s_point cg3s_point; #else @@ -121,14 +127,17 @@ void g3_set_view_matrix(const vms_vector &view_pos,const vms_matrix &view_matrix //Instancing //instance at specified point with specified orientation -void g3_start_instance_matrix(); -void g3_start_instance_matrix(const vms_vector &pos, const vms_matrix &orient); +[[nodiscard]] +g3_instance_context g3_start_instance_matrix(); +[[nodiscard]] +g3_instance_context g3_start_instance_matrix(const vms_vector &pos, const vms_matrix &orient); //instance at specified point with specified orientation -void g3_start_instance_angles(const vms_vector &pos, const vms_angvec &angles); +[[nodiscard]] +g3_instance_context g3_start_instance_angles(const vms_vector &pos, const vms_angvec &angles); //pops the old context -void g3_done_instance(); +void g3_done_instance(const g3_instance_context &); //Misc utility functions: diff --git a/similar/3d/interp.cpp b/similar/3d/interp.cpp index e12168059..a0372db5e 100644 --- a/similar/3d/interp.cpp +++ b/similar/3d/interp.cpp @@ -299,9 +299,9 @@ protected: } void op_subcall(const uint8_t *const p, const glow_values_t *const glow_values) { - g3_start_instance_angles(*vp(p + 4), anim_angles ? anim_angles[w(p + 2)] : zero_angles); + auto &&ctx = g3_start_instance_angles(*vp(p + 4), anim_angles ? anim_angles[w(p + 2)] : zero_angles); g3_draw_polygon_model(model_bitmaps, Interp_point_list, canvas, anim_angles, model_light, glow_values, p + w(p + 16)); - g3_done_instance(); + g3_done_instance(ctx); } }; diff --git a/similar/main/endlevel.cpp b/similar/main/endlevel.cpp index 5b3fb460b..ee51a7b4a 100644 --- a/similar/main/endlevel.cpp +++ b/similar/main/endlevel.cpp @@ -596,9 +596,11 @@ static void render_external_scene(fvcobjptridx &vcobjptridx, grs_canvas &canvas, //g3_draw_horizon(BM_XRGB(0,0,0),BM_XRGB(16,16,16)); //,-1); gr_clear_canvas(canvas, BM_XRGB(0,0,0)); - g3_start_instance_matrix(vmd_zero_vector, surface_orient); - draw_stars(canvas, UniqueEndlevelState.stars); - g3_done_instance(); + { + auto &&ctx = g3_start_instance_matrix(vmd_zero_vector, surface_orient); + draw_stars(canvas, UniqueEndlevelState.stars); + g3_done_instance(ctx); + } { //draw satellite diff --git a/similar/main/morph.cpp b/similar/main/morph.cpp index dc3e2c95e..11e7487fb 100644 --- a/similar/main/morph.cpp +++ b/similar/main/morph.cpp @@ -575,9 +575,9 @@ static void draw_model(grs_canvas &canvas, polygon_model_points &robot_points, p } else { const auto &&orient = vm_angles_2_matrix(anim_angles[mn]); - g3_start_instance_matrix(pm->submodel_offsets[mn], orient); + auto &&ctx = g3_start_instance_matrix(pm->submodel_offsets[mn], orient); draw_model(canvas, robot_points,pm,mn,anim_angles,light,md); - g3_done_instance(); + g3_done_instance(ctx); } } @@ -604,11 +604,12 @@ void draw_morph_object(grs_canvas &canvas, const d_level_unique_light_state &Lev const auto light = compute_object_light(LevelUniqueLightState, obj); - g3_start_instance_matrix(obj->pos, obj->orient); + { + auto &&ctx = g3_start_instance_matrix(obj->pos, obj->orient); polygon_model_points robot_points; draw_model(canvas, robot_points, po, 0, obj->rtype.pobj_info.anim_angles, light, md); - - g3_done_instance(); + g3_done_instance(ctx); + } if (Newdemo_state == ND_STATE_RECORDING) newdemo_record_morph_frame(obj); diff --git a/similar/main/polyobj.cpp b/similar/main/polyobj.cpp index 3dab3aafe..f8729ac87 100644 --- a/similar/main/polyobj.cpp +++ b/similar/main/polyobj.cpp @@ -462,7 +462,7 @@ void draw_polygon_model(grs_canvas &canvas, const vms_vector &pos, const vms_mat // so we need to reread them all in. // Make sure that they can all fit in memory. - g3_start_instance_matrix(pos, orient); + auto &&ctx = g3_start_instance_matrix(pos, orient); polygon_model_points robot_points; @@ -476,16 +476,12 @@ void draw_polygon_model(grs_canvas &canvas, const vms_vector &pos, const vms_mat Assert(i < po->n_models); //if submodel, rotate around its center point, not pivot point - - g3_start_instance_matrix(); - + auto &&subctx = g3_start_instance_matrix(); g3_draw_polygon_model(&texture_list[0], robot_points, canvas, anim_angles, light, glow_values, &po->model_data[po->submodel_ptrs[i]]); - - g3_done_instance(); + g3_done_instance(subctx); } } - - g3_done_instance(); + g3_done_instance(ctx); } void free_polygon_models(d_level_shared_polygon_model_state &LevelSharedPolygonModelState)