Skip to content

Commit

Permalink
Refactor replacement texture to a modelinstance parameter (scp-fs2ope…
Browse files Browse the repository at this point in the history
…n#6154)

* Move replacement textures from ship to modelinstance

* Actually set pmi

* Fix texture replace in fred as well

* Fix bad indent

* incorporate feedback
  • Loading branch information
BMagnu authored May 21, 2024
1 parent c1af431 commit 87704fc
Show file tree
Hide file tree
Showing 19 changed files with 293 additions and 294 deletions.
2 changes: 2 additions & 0 deletions code/asteroid/asteroid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1523,6 +1523,8 @@ void asteroid_render(object * obj, model_draw_list *scene)

render_info.set_object_number( OBJ_INDEX(obj) );
render_info.set_flags(MR_IS_ASTEROID);
if (asp->model_instance_num >= 0)
render_info.set_replacement_textures(model_get_instance(asp->model_instance_num)->texture_replace);

model_render_queue(&render_info, scene, Asteroid_info[asp->asteroid_type].model_num[asp->asteroid_subtype], &obj->orient, &obj->pos); // Replace MR_NORMAL with 0x07 for big yellow blobs
}
Expand Down
3 changes: 3 additions & 0 deletions code/debris/debris.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1197,6 +1197,9 @@ void debris_render(object * obj, model_draw_list *scene)
// render_info.set_flags(MR_NO_LIGHTING);
}

if (db->model_instance_num >= 0)
render_info.set_replacement_textures(model_get_instance(db->model_instance_num)->texture_replace);

submodel_render_queue( &render_info, scene, pm, pmi, db->submodel_num, &obj->orient, &obj->pos );

if (tbase != NULL && (swapped!=-1) && pm) {
Expand Down
2 changes: 1 addition & 1 deletion code/hud/hudshield.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,7 @@ void HudGaugeShield::showShields(object *objp, int mode)
model_render_params render_info;

render_info.set_flags(MR_NO_LIGHTING | MR_AUTOCENTER | MR_NO_FOGGING);
render_info.set_replacement_textures(sp->ship_replacement_textures);
render_info.set_replacement_textures(model_get_instance(sp->model_instance_num)->texture_replace);
render_info.set_detail_level_lock(1);
render_info.set_object_number(OBJ_INDEX(objp));

Expand Down
16 changes: 12 additions & 4 deletions code/hud/hudtargetbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -677,7 +677,7 @@ void HudGaugeTargetBox::renderTargetShip(object *target_objp)
if(target_sip->model_num_hud >= 0){
model_render_immediate( &render_info, target_sip->model_num_hud, &target_objp->orient, &obj_pos);
} else {
render_info.set_replacement_textures(target_shipp->ship_replacement_textures);
render_info.set_replacement_textures(model_get_instance(target_shipp->model_instance_num)->texture_replace);

model_render_immediate( &render_info, target_sip->model_num, &target_objp->orient, &obj_pos);
}
Expand Down Expand Up @@ -777,6 +777,9 @@ void HudGaugeTargetBox::renderTargetDebris(object *target_objp)

model_render_params render_info;

if (debrisp->model_instance_num >= 0)
render_info.set_replacement_textures(model_get_instance(debrisp->model_instance_num)->texture_replace);

color thisColor = GaugeWirecolor;
bool thisOverride = GaugeWirecolorOverride;

Expand Down Expand Up @@ -863,7 +866,7 @@ void HudGaugeTargetBox::renderTargetWeapon(object *target_objp)
weapon_info *target_wip = NULL;
weapon *wp = NULL;
object *viewer_obj, *viewed_obj;
int *replacement_textures = NULL;
std::shared_ptr<model_texture_replace> replacement_textures = nullptr;
int target_team, is_homing, is_player_missile, missile_view, viewed_model_num, hud_target_lod, w, h;
int flags=0;

Expand Down Expand Up @@ -902,10 +905,13 @@ void HudGaugeTargetBox::renderTargetWeapon(object *target_objp)
viewed_obj = wp->homing_object;
missile_view = TRUE;
viewed_model_num = homing_sip->model_num;
replacement_textures = homing_shipp->ship_replacement_textures;
hud_target_lod = homing_sip->hud_target_lod;
}

int pmi_id = object_get_model_instance(viewed_obj);
if (pmi_id >= 0)
replacement_textures = model_get_instance(pmi_id)->texture_replace;

// take the forward orientation to be the vector from the player to the current target
vm_vec_sub(&orient_vec, &viewed_obj->pos, &viewer_obj->pos);
vm_vec_normalize(&orient_vec);
Expand Down Expand Up @@ -1068,7 +1074,6 @@ void HudGaugeTargetBox::renderTargetWeapon(object *target_objp)
model_render_immediate( &render_info, homing_sip->model_num_hud, &viewed_obj->orient, &obj_pos);
} else {
render_info.set_flags(flags | MR_NO_FOGGING);
render_info.set_replacement_textures(homing_shipp->ship_replacement_textures);

model_render_immediate( &render_info, homing_sip->model_num, &viewed_obj->orient, &obj_pos );
}
Expand Down Expand Up @@ -1170,6 +1175,9 @@ void HudGaugeTargetBox::renderTargetAsteroid(object *target_objp)

model_render_params render_info;

if (asteroidp->model_instance_num >= 0)
render_info.set_replacement_textures(model_get_instance(asteroidp->model_instance_num)->texture_replace);

color thisColor = GaugeWirecolor;
bool thisOverride = GaugeWirecolorOverride;

Expand Down
43 changes: 27 additions & 16 deletions code/model/model.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,40 @@ struct submodel_instance
}
};

#define TM_BASE_TYPE 0 // the standard base map
#define TM_GLOW_TYPE 1 // optional glow map
#define TM_SPECULAR_TYPE 2 // optional specular map
#define TM_NORMAL_TYPE 3 // optional normal map
#define TM_HEIGHT_TYPE 4 // optional height map (for parallax mapping)
#define TM_MISC_TYPE 5 // optional utility map
#define TM_SPEC_GLOSS_TYPE 6 // optional reflectance map (specular and gloss)
#define TM_AMBIENT_TYPE 7 // optional ambient occlusion map with ambient occlusion and cavity occlusion factors for red and green channels.
#define TM_NUM_TYPES 8 //WMC - Number of texture_info objects in texture_map
//Used by scripting - if you change this, do a search
//to update switch() statement in lua.cpp

#define MAX_REPLACEMENT_TEXTURES MAX_MODEL_TEXTURES * TM_NUM_TYPES

// Goober5000 - since we need something < 0
#define REPLACE_WITH_INVISIBLE -47

class model_texture_replace : public std::array<int, MAX_REPLACEMENT_TEXTURES> {
public:
model_texture_replace() : std::array<int, MAX_REPLACEMENT_TEXTURES>() {
for (int& tex : *this)
tex = -1;
}
};

// Data specific to a particular instance of a model.
struct polymodel_instance
{
int id = -1; // global model_instance num index
int model_num = -1; // global model num index, same as polymodel->id
submodel_instance *submodel = nullptr; // array of submodel instances; mirrors the polymodel->submodel array

std::shared_ptr<model_texture_replace> texture_replace = nullptr;

int objnum; // id of the object using this pmi, or -1 if no object (e.g. skybox)
};

Expand Down Expand Up @@ -730,17 +757,6 @@ class texture_info
int SetTexture(int n_tex);
};

#define TM_BASE_TYPE 0 // the standard base map
#define TM_GLOW_TYPE 1 // optional glow map
#define TM_SPECULAR_TYPE 2 // optional specular map
#define TM_NORMAL_TYPE 3 // optional normal map
#define TM_HEIGHT_TYPE 4 // optional height map (for parallax mapping)
#define TM_MISC_TYPE 5 // optional utility map
#define TM_SPEC_GLOSS_TYPE 6 // optional reflectance map (specular and gloss)
#define TM_AMBIENT_TYPE 7 // optional ambient occlusion map with ambient occlusion and cavity occlusion factors for red and green channels.
#define TM_NUM_TYPES 8 //WMC - Number of texture_info objects in texture_map
//Used by scripting - if you change this, do a search
//to update switch() statement in lua.cpp
// taylor
//WMC - OOPified
class texture_map
Expand All @@ -765,11 +781,6 @@ class texture_map
{}
};

#define MAX_REPLACEMENT_TEXTURES MAX_MODEL_TEXTURES * TM_NUM_TYPES

// Goober5000 - since we need something < 0
#define REPLACE_WITH_INVISIBLE -47

//used to describe a polygon model
// NOTE: Because WMC OOPified the textures, this must now be treated as a class, rather than a struct.
// Additionally, a lot of model initialization and de-initialization is currently done in model_load or model_unload.
Expand Down
70 changes: 30 additions & 40 deletions code/model/modelrender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@ model_render_params::model_render_params() :
Xparent_alpha(1.0f),
Forced_bitmap(-1),
Insignia_bitmap(-1),
Replacement_textures(NULL),
Manage_replacement_textures(false),
Replacement_textures(nullptr),
Team_color_set(false),
Clip_plane_set(false),
Animated_effect(-1),
Expand All @@ -91,12 +90,6 @@ model_render_params::model_render_params() :
gr_init_color(&Color, 0, 0, 0);
}

model_render_params::~model_render_params()
{
if (Manage_replacement_textures)
vm_free(const_cast<int*>(Replacement_textures));
}

uint model_render_params::get_model_flags() const
{
return Model_flags;
Expand Down Expand Up @@ -157,7 +150,7 @@ int model_render_params::get_insignia_bitmap() const
return Insignia_bitmap;
}

const int* model_render_params::get_replacement_textures() const
std::shared_ptr<const model_texture_replace> model_render_params::get_replacement_textures() const
{
return Replacement_textures;
}
Expand Down Expand Up @@ -223,19 +216,14 @@ bool model_render_params::is_team_color_set() const
return Team_color_set;
}

void model_render_params::set_replacement_textures(const int *textures)
void model_render_params::set_replacement_textures(std::shared_ptr<const model_texture_replace> textures)
{
Replacement_textures = textures;
Replacement_textures = std::move(textures);
}

void model_render_params::set_replacement_textures(int modelnum, const SCP_vector<texture_replace>& replacement_textures)
{
auto textures = (int*)vm_malloc(MAX_REPLACEMENT_TEXTURES * sizeof(int));

for (int i = 0; i < MAX_REPLACEMENT_TEXTURES; i++)
textures[i] = -1;

Manage_replacement_textures = true;
auto textures = make_shared<model_texture_replace>();

polymodel* pm = model_get(modelnum);

Expand All @@ -247,11 +235,11 @@ void model_render_params::set_replacement_textures(int modelnum, const SCP_vecto

int tnum = tmap->FindTexture(tr.old_texture);
if (tnum > -1)
textures[i * TM_NUM_TYPES + tnum] = bm_load(tr.new_texture);
(*textures)[i * TM_NUM_TYPES + tnum] = bm_load(tr.new_texture);
}
}

Replacement_textures = textures;
Replacement_textures = std::move(textures);
}

void model_render_params::set_insignia_bitmap(int bitmap)
Expand Down Expand Up @@ -1054,7 +1042,7 @@ void model_render_buffers(model_draw_list* scene, model_material *rendering_mate

int texture_maps[TM_NUM_TYPES] = { -1 };
size_t buffer_size = buffer->tex_buf.size();
const int *replacement_textures = interp->get_replacement_textures();
const auto& replacement_textures = interp->get_replacement_textures();

for ( size_t i = 0; i < buffer_size; i++ ) {
int tmap_num = buffer->tex_buf[i].texture;
Expand All @@ -1081,12 +1069,12 @@ void model_render_buffers(model_draw_list* scene, model_material *rendering_mate

} else if ( !no_texturing ) {
// pick the texture, animating it if necessary
if ( (replacement_textures != NULL) && (replacement_textures[rt_begin_index + TM_BASE_TYPE] == REPLACE_WITH_INVISIBLE) ) {
if ( (replacement_textures != nullptr) && ((*replacement_textures)[rt_begin_index + TM_BASE_TYPE] == REPLACE_WITH_INVISIBLE) ) {
// invisible textures aren't rendered, but we still have to skip assigning the underlying model texture
texture_maps[TM_BASE_TYPE] = -1;
} else if ( (replacement_textures != NULL) && (replacement_textures[rt_begin_index + TM_BASE_TYPE] >= 0) ) {
} else if ( (replacement_textures != nullptr) && ((*replacement_textures)[rt_begin_index + TM_BASE_TYPE] >= 0) ) {
// an underlying texture is replaced with a real new texture
tex_replace[TM_BASE_TYPE] = texture_info(replacement_textures[rt_begin_index + TM_BASE_TYPE]);
tex_replace[TM_BASE_TYPE] = texture_info((*replacement_textures)[rt_begin_index + TM_BASE_TYPE]);
texture_maps[TM_BASE_TYPE] = model_interp_get_texture(&tex_replace[TM_BASE_TYPE], elapsed_time);
} else {
// we just use the underlying texture
Expand All @@ -1101,8 +1089,8 @@ void model_render_buffers(model_draw_list* scene, model_material *rendering_mate
if ( !(model_flags & MR_NO_GLOWMAPS) ) {
auto tglow = &tmap->textures[TM_GLOW_TYPE];

if ( (replacement_textures != NULL) && (replacement_textures[rt_begin_index + TM_GLOW_TYPE] >= 0) ) {
tex_replace[TM_GLOW_TYPE] = texture_info(replacement_textures[rt_begin_index + TM_GLOW_TYPE]);
if ( (replacement_textures != nullptr) && ((*replacement_textures)[rt_begin_index + TM_GLOW_TYPE] >= 0) ) {
tex_replace[TM_GLOW_TYPE] = texture_info((*replacement_textures)[rt_begin_index + TM_GLOW_TYPE]);
texture_maps[TM_GLOW_TYPE] = model_interp_get_texture(&tex_replace[TM_GLOW_TYPE], elapsed_time);
} else if (tglow->GetTexture() >= 0) {
// shockwaves are special, their current frame has to come out of the shockwave code to get the timing correct
Expand All @@ -1115,17 +1103,17 @@ void model_render_buffers(model_draw_list* scene, model_material *rendering_mate
}

if (!(debug_flags & MR_DEBUG_NO_SPEC)) {
if (replacement_textures != NULL && replacement_textures[rt_begin_index + TM_SPECULAR_TYPE] >= 0) {
tex_replace[TM_SPECULAR_TYPE] = texture_info(replacement_textures[rt_begin_index + TM_SPECULAR_TYPE]);
if (replacement_textures != nullptr && (*replacement_textures)[rt_begin_index + TM_SPECULAR_TYPE] >= 0) {
tex_replace[TM_SPECULAR_TYPE] = texture_info((*replacement_textures)[rt_begin_index + TM_SPECULAR_TYPE]);
texture_maps[TM_SPECULAR_TYPE] = model_interp_get_texture(&tex_replace[TM_SPECULAR_TYPE], elapsed_time);
}
else {
texture_maps[TM_SPECULAR_TYPE] = model_interp_get_texture(&tmap->textures[TM_SPECULAR_TYPE], elapsed_time);
}
}

if ( replacement_textures != NULL && replacement_textures[rt_begin_index + TM_SPEC_GLOSS_TYPE] >= 0 ) {
tex_replace[TM_SPEC_GLOSS_TYPE] = texture_info(replacement_textures[rt_begin_index + TM_SPEC_GLOSS_TYPE]);
if ( replacement_textures != nullptr && (*replacement_textures)[rt_begin_index + TM_SPEC_GLOSS_TYPE] >= 0 ) {
tex_replace[TM_SPEC_GLOSS_TYPE] = texture_info((*replacement_textures)[rt_begin_index + TM_SPEC_GLOSS_TYPE]);
texture_maps[TM_SPEC_GLOSS_TYPE] = model_interp_get_texture(&tex_replace[TM_SPEC_GLOSS_TYPE], elapsed_time);
} else {
texture_maps[TM_SPEC_GLOSS_TYPE] = model_interp_get_texture(&tmap->textures[TM_SPEC_GLOSS_TYPE], elapsed_time);
Expand All @@ -1138,24 +1126,25 @@ void model_render_buffers(model_draw_list* scene, model_material *rendering_mate
auto ambient_map = &tmap->textures[TM_AMBIENT_TYPE];
auto misc_map = &tmap->textures[TM_MISC_TYPE];

if (replacement_textures != NULL) {
if (replacement_textures[rt_begin_index + TM_NORMAL_TYPE] >= 0) {
tex_replace[TM_NORMAL_TYPE] = texture_info(replacement_textures[rt_begin_index + TM_NORMAL_TYPE]);
if (replacement_textures != nullptr) {
const auto& replacement_textures_deref = *replacement_textures;
if (replacement_textures_deref[rt_begin_index + TM_NORMAL_TYPE] >= 0) {
tex_replace[TM_NORMAL_TYPE] = texture_info(replacement_textures_deref[rt_begin_index + TM_NORMAL_TYPE]);
norm_map = &tex_replace[TM_NORMAL_TYPE];
}

if (replacement_textures[rt_begin_index + TM_HEIGHT_TYPE] >= 0) {
tex_replace[TM_HEIGHT_TYPE] = texture_info(replacement_textures[rt_begin_index + TM_HEIGHT_TYPE]);
if (replacement_textures_deref[rt_begin_index + TM_HEIGHT_TYPE] >= 0) {
tex_replace[TM_HEIGHT_TYPE] = texture_info(replacement_textures_deref[rt_begin_index + TM_HEIGHT_TYPE]);
height_map = &tex_replace[TM_HEIGHT_TYPE];
}

if (replacement_textures[rt_begin_index + TM_AMBIENT_TYPE] >= 0) {
tex_replace[TM_AMBIENT_TYPE] = texture_info(replacement_textures[rt_begin_index + TM_AMBIENT_TYPE]);
if (replacement_textures_deref[rt_begin_index + TM_AMBIENT_TYPE] >= 0) {
tex_replace[TM_AMBIENT_TYPE] = texture_info(replacement_textures_deref[rt_begin_index + TM_AMBIENT_TYPE]);
ambient_map = &tex_replace[TM_AMBIENT_TYPE];
}

if (replacement_textures[rt_begin_index + TM_MISC_TYPE] >= 0) {
tex_replace[TM_MISC_TYPE] = texture_info(replacement_textures[rt_begin_index + TM_MISC_TYPE]);
if (replacement_textures_deref[rt_begin_index + TM_MISC_TYPE] >= 0) {
tex_replace[TM_MISC_TYPE] = texture_info(replacement_textures_deref[rt_begin_index + TM_MISC_TYPE]);
misc_map = &tex_replace[TM_MISC_TYPE];
}
}
Expand All @@ -1174,8 +1163,8 @@ void model_render_buffers(model_draw_list* scene, model_material *rendering_mate

//Check for invisible or transparent textures so they don't show up in the shadow maps - Valathil
if ( Rendering_to_shadow_map ) {
if ( (replacement_textures != NULL) && (replacement_textures[rt_begin_index + TM_BASE_TYPE] >= 0) ) {
tex_replace[TM_BASE_TYPE] = texture_info(replacement_textures[rt_begin_index + TM_BASE_TYPE]);
if ( (replacement_textures != nullptr) && ((*replacement_textures)[rt_begin_index + TM_BASE_TYPE] >= 0) ) {
tex_replace[TM_BASE_TYPE] = texture_info((*replacement_textures)[rt_begin_index + TM_BASE_TYPE]);
texture_maps[TM_BASE_TYPE] = model_interp_get_texture(&tex_replace[TM_BASE_TYPE], elapsed_time);
} else {
texture_maps[TM_BASE_TYPE] = model_interp_get_texture(&tmap->textures[TM_BASE_TYPE], elapsed_time);
Expand Down Expand Up @@ -3113,6 +3102,7 @@ bool render_tech_model(tech_render_type model_type, int x1, int y1, int x2, int

// Make sure model is loaded
model_num = model_load(sip->pof_file, sip->n_subsystems, &sip->subsystems[0], 0);
render_info.set_replacement_textures(model_num, sip->replacement_textures);

break;

Expand Down
10 changes: 3 additions & 7 deletions code/model/modelrender.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,7 @@ class model_render_params

int Insignia_bitmap;

const int *Replacement_textures;
bool Manage_replacement_textures; // This is set when we are rendering a model without an associated ship object;
// in that case, model_render_params is responsible for allocating and destroying
// the Replacement_textures array (this is handled elsewhere otherwise)
std::shared_ptr<const model_texture_replace> Replacement_textures;

bool Team_color_set;
team_color Current_team_color;
Expand All @@ -109,7 +106,6 @@ class model_render_params
model_render_params& operator=(const model_render_params&) = delete;
public:
model_render_params();
~model_render_params();

void set_flags(uint flags);
void set_debug_flags(uint flags);
Expand All @@ -122,7 +118,7 @@ class model_render_params
void set_alpha(float alpha);
void set_forced_bitmap(int bitmap);
void set_insignia_bitmap(int bitmap);
void set_replacement_textures(const int *textures);
void set_replacement_textures(std::shared_ptr<const model_texture_replace> textures);
void set_replacement_textures(int modelnum, const SCP_vector<texture_replace>& replacement_textures);
void set_team_color(const team_color &clr);
void set_team_color(const SCP_string &team, const SCP_string &secondaryteam, fix timestamp, int fadetime);
Expand All @@ -149,7 +145,7 @@ class model_render_params
float get_alpha() const;
int get_forced_bitmap() const;
int get_insignia_bitmap() const;
const int* get_replacement_textures() const;
std::shared_ptr<const model_texture_replace> get_replacement_textures() const;
const team_color& get_team_color() const;
const vec3d& get_clip_plane_pos() const;
const vec3d& get_clip_plane_normal() const;
Expand Down
2 changes: 1 addition & 1 deletion code/scripting/api/objs/cockpit_display.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ bool cockpit_displays_h::isValid() const {
return false;
}

if ( Player_cockpit_textures == NULL ) {
if ( Player_cockpit_textures == nullptr ) {
return false;
}

Expand Down
Loading

0 comments on commit 87704fc

Please sign in to comment.