Skip to content

Commit bdf3833

Browse files
Merge pull request #171 from xr-lucy/lucy-game-object-shader-texture-changing
Lucy game object shader texture changing
2 parents fa94e39 + f4dece4 commit bdf3833

33 files changed

+396
-70
lines changed

gamedata/scripts/lua_help_ex.script

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,8 @@
389389
// Shader/Textures
390390
function get_shaders(bool)
391391
function set_shader(number, string, string, bool)
392+
function get_default_shaders(bool)
393+
function reset_shader(number, bool)
392394

393395
get_shaders(hud_mode)
394396
hud_mode is optional and will default to false
@@ -406,10 +408,16 @@
406408
},
407409
},
408410

411+
get_default_shaders(hud_mode)
412+
returns similar table as get_shaders but containing the default shader and texture names, even after they were changed by set_shader
413+
409414
set_shader(id, shader, texture, hud_mode) can assign a new shader/texture to the submesh ID
410415
id can be -1 to apply the shader/texture to all submeshes at once
411416
shader/texture can be nil if you only want to apply one of them
412417
hud_mode is optional and will default to false
418+
419+
reset_shader(id, hud_mode)
420+
same as set_shader but resets to the default shader/texture values, so you don't need to store them in a table to reset them later
413421
}
414422

415423
class CArtefact : CGameObject {
@@ -651,6 +659,10 @@
651659
function set_ui_position();
652660
function set_ui_rotation(vector);
653661
function set_ui_rotation(number, number, number);
662+
function get_shaders()
663+
function get_default_shaders()
664+
function set_shader(number, string, string)
665+
function reset_shader(number)
654666
}
655667

656668
flags:

src/Include/xrRender/RenderVisual.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,14 @@ class IRenderVisual
3232
#endif
3333
virtual LPCSTR _BCL getDebugShader() { return nullptr; }
3434
virtual LPCSTR _BCL getDebugTexture() { return nullptr; }
35+
36+
virtual LPCSTR _BCL getDebugShaderDef() { return nullptr; }
37+
virtual LPCSTR _BCL getDebugTextureDef() { return nullptr; }
3538

3639
virtual xr_vector<IRenderVisual*>* get_children() { return nullptr; };
3740

38-
virtual void SetShaderTexture(char* shader, LPCSTR texture) {};
41+
virtual void SetShaderTexture(LPCSTR shader, LPCSTR texture) {};
42+
virtual void ResetShaderTexture() {};
3943
virtual void MarkAsHot(bool is_hot) {}; //--DSR-- HeatVision
4044
virtual void MarkAsGlowing(bool is_glowing) {}; //--DSR-- SilencerOverheat
4145

src/Layers/xrRender/FBasicVisual.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ void dxRender_Visual::Load(const char* N, IReader* data, u32)
6868
string256 fnT, fnS;
6969
data->r_stringZ(fnT, sizeof(fnT));
7070
data->r_stringZ(fnS, sizeof(fnS));
71-
SetShaderTexture(fnS, fnT);
71+
dbg_shader_def = fnS;
72+
dbg_texture_def = fnT;
73+
ResetShaderTexture();
7274
}
7375

7476
// desc
@@ -117,11 +119,12 @@ void dxRender_Visual::MarkAsGlowing(bool is_glowing)
117119
}
118120
//--DSR-- SilencerOverheat_end
119121

120-
void dxRender_Visual::SetShaderTexture(char* s_shader, LPCSTR s_texture)
122+
void dxRender_Visual::SetShaderTexture(LPCSTR s_shader, LPCSTR s_texture)
121123
{
122124
if (s_shader && strlen(s_shader))
123125
{
124-
char* no_shadow = strstr(s_shader, "$no_shadows");
126+
char* shader = xr_strdup(s_shader);
127+
char* no_shadow = strstr(shader, "$no_shadows");
125128

126129
if (no_shadow)
127130
{
@@ -131,7 +134,8 @@ void dxRender_Visual::SetShaderTexture(char* s_shader, LPCSTR s_texture)
131134
else
132135
flags.set(IRenderVisualFlags::eNoShadow, FALSE);
133136

134-
dbg_shader = s_shader;
137+
dbg_shader = shader;
138+
xr_delete(shader);
135139
}
136140

137141
if (s_texture && strlen(s_texture))
@@ -143,6 +147,12 @@ void dxRender_Visual::SetShaderTexture(char* s_shader, LPCSTR s_texture)
143147
shader.create(*dbg_shader, *dbg_texture);
144148
}
145149

150+
void dxRender_Visual::ResetShaderTexture()
151+
{
152+
if (!dbg_shader.equal(dbg_shader_def) || !dbg_texture.equal(dbg_texture_def))
153+
SetShaderTexture(*dbg_shader_def, *dbg_texture_def);
154+
}
155+
146156
#define PCOPY(a) a = pFrom->a
147157

148158
void dxRender_Visual::Copy(dxRender_Visual* pFrom)
@@ -156,6 +166,8 @@ void dxRender_Visual::Copy(dxRender_Visual* pFrom)
156166
PCOPY(flags);
157167
PCOPY(dbg_name);
158168
PCOPY(dbg_shader);
169+
PCOPY(dbg_shader_def);
159170
PCOPY(dbg_texture);
171+
PCOPY(dbg_texture_def);
160172
PCOPY(skinning);
161173
}

src/Layers/xrRender/FBasicVisual.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,13 @@ class ECORE_API dxRender_Visual : public IRenderVisual
5151
shared_str dbg_name ;
5252
shared_str dbg_shader ;
5353
shared_str dbg_texture ;
54+
shared_str dbg_shader_def ;
55+
shared_str dbg_texture_def ;
5456
virtual shared_str _BCL getDebugName() { return dbg_name; }
5557
virtual LPCSTR _BCL getDebugShader() { return *dbg_shader; }
5658
virtual LPCSTR _BCL getDebugTexture() { return *dbg_texture; }
59+
virtual LPCSTR _BCL getDebugShaderDef() { return *dbg_shader_def; }
60+
virtual LPCSTR _BCL getDebugTextureDef() { return *dbg_texture_def; }
5761
public:
5862
// Common data for rendering
5963
u32 Type; // visual's type
@@ -80,7 +84,8 @@ class ECORE_API dxRender_Visual : public IRenderVisual
8084
// virtual CKinematicsAnimated*dcast_PKinematicsAnimated () { return 0; }
8185
// virtual IParticleCustom* dcast_ParticleCustom () { return 0; }
8286

83-
virtual void SetShaderTexture(char* shader, LPCSTR texture);
87+
virtual void SetShaderTexture(LPCSTR shader, LPCSTR texture);
88+
virtual void ResetShaderTexture();
8489

8590
virtual vis_data& _BCL getVisData() { return vis; }
8691
virtual u32 getType() { return Type; }

src/Layers/xrRender/ModelPool.cpp

Lines changed: 78 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ void CModelPool::Instance_Register(LPCSTR N, dxRender_Visual* V)
171171

172172
void CModelPool::Destroy()
173173
{
174+
// Pool
175+
Pool.clear();
176+
174177
// Registry
175178
while (!Registry.empty())
176179
{
@@ -237,21 +240,37 @@ dxRender_Visual* CModelPool::Create(const char* name, IReader* data)
237240
strlwr(low_name);
238241
if (strext(low_name)) *strext(low_name) = 0;
239242

240-
// 1. Search for already loaded model (reference, base model)
241-
dxRender_Visual* Base = Instance_Find(low_name);
242-
if (0 == Base)
243+
// 0. Search POOL
244+
POOL_IT it = Pool.find(low_name);
245+
if (it != Pool.end())
243246
{
244-
// 2. If not found
245-
bAllowChildrenDuplicate = FALSE;
246-
if (data) Base = Instance_Load(low_name, data, TRUE);
247-
else Base = Instance_Load(low_name, TRUE);
248-
bAllowChildrenDuplicate = TRUE;
247+
// 1. Instance found
248+
dxRender_Visual* Model = it->second;
249+
Model->Spawn();
250+
Pool.erase(it);
251+
return Model;
249252
}
253+
else
254+
{
255+
// 1. Search for already loaded model (reference, base model)
256+
dxRender_Visual* Base = Instance_Find(low_name);
250257

251-
// 3. If found - return (cloned) reference
252-
dxRender_Visual* Model = Instance_Duplicate(Base);
253-
Registry.insert(mk_pair(Model, low_name));
254-
return Model;
258+
if (0 == Base)
259+
{
260+
// 2. If not found
261+
bAllowChildrenDuplicate = FALSE;
262+
if (data) Base = Instance_Load(low_name, data, TRUE);
263+
else Base = Instance_Load(low_name, TRUE);
264+
bAllowChildrenDuplicate = TRUE;
265+
#ifdef _EDITOR
266+
if (!Base) return 0;
267+
#endif
268+
}
269+
// 3. If found - return (cloned) reference
270+
dxRender_Visual* Model = Instance_Duplicate(Base);
271+
Registry.insert(mk_pair(Model, low_name));
272+
return Model;
273+
}
255274
}
256275

257276
dxRender_Visual* CModelPool::CreateChild(LPCSTR name, IReader* data)
@@ -282,7 +301,32 @@ void CModelPool::DeleteInternal(dxRender_Visual* & V, BOOL bDiscard)
282301
VERIFY(!g_bRendering);
283302
if (!V) return;
284303
V->Depart();
285-
Discard(V, bDiscard || bForceDiscard);
304+
if (bDiscard || bForceDiscard)
305+
{
306+
Discard(V, TRUE);
307+
}
308+
else
309+
{
310+
//
311+
REGISTRY_IT it = Registry.find(V);
312+
if (it != Registry.end())
313+
{
314+
// Registry entry found - move it to pool and reset changed shader/texture if necessary
315+
xr_vector<IRenderVisual*>* children = V->get_children();
316+
if (children)
317+
for (auto* child : *children)
318+
child->ResetShaderTexture();
319+
else
320+
V->ResetShaderTexture();
321+
322+
Pool.insert(mk_pair(it->second, V));
323+
}
324+
else
325+
{
326+
// Registry entry not-found - just special type of visual / particles / etc.
327+
xr_delete(V);
328+
}
329+
}
286330
V = NULL;
287331
}
288332

@@ -291,18 +335,20 @@ void CModelPool::Delete(dxRender_Visual* & V, BOOL bDiscard)
291335
if (NULL == V) return;
292336
if (g_bRendering)
293337
{
294-
ModelsToDelete.insert(mk_pair(V, !!bDiscard));
338+
VERIFY(!bDiscard);
339+
ModelsToDelete.push_back(V);
295340
}
296341
else
297342
{
298343
DeleteInternal(V, bDiscard);
299344
}
345+
V = NULL;
300346
}
301347

302348
void CModelPool::DeleteQueue()
303349
{
304-
for (xr_map<dxRender_Visual*, bool>::iterator it = ModelsToDelete.begin(); it != ModelsToDelete.end(); it++)
305-
DeleteInternal((dxRender_Visual*)it->first, it->second);
350+
for (u32 it = 0; it < ModelsToDelete.size(); it++)
351+
DeleteInternal(ModelsToDelete[it]);
306352
ModelsToDelete.clear();
307353
}
308354

@@ -391,6 +437,17 @@ dxRender_Visual* CModelPool::CreatePG(PS::CPGDef* source)
391437
return V;
392438
}
393439

440+
void CModelPool::ClearPool(BOOL b_complete)
441+
{
442+
POOL_IT _I = Pool.begin();
443+
POOL_IT _E = Pool.end();
444+
for (; _I != _E; _I++)
445+
{
446+
Discard(_I->second, b_complete);
447+
}
448+
Pool.clear();
449+
}
450+
394451
void CModelPool::dump()
395452
{
396453
Log("--- model pool --- begin:");
@@ -409,6 +466,7 @@ void CModelPool::dump()
409466
Msg("--- models: %d, mem usage: %d Kb ", k, sz / 1024);
410467
sz = 0;
411468
k = 0;
469+
int free_cnt = 0;
412470
for (REGISTRY_IT it = Registry.begin(); it != Registry.end(); it++)
413471
{
414472
CKinematics* K = PCKinematics((dxRender_Visual*)it->first);
@@ -417,10 +475,12 @@ void CModelPool::dump()
417475
{
418476
u32 cur = K->mem_usage(true);
419477
sz += cur;
420-
Msg("#%3d: [%5d Kb] - %s", k++, cur / 1024, it->second.c_str());
478+
bool b_free = (Pool.find(it->second) != Pool.end());
479+
if (b_free) ++free_cnt;
480+
Msg("#%3d: [%s] [%5d Kb] - %s", k++, (b_free) ? "free" : "used", cur / 1024, it->second.c_str());
421481
}
422482
}
423-
Msg("--- instances: %d, mem usage: %d Kb ", k, sz / 1024);
483+
Msg("--- instances: %d, free %d, mem usage: %d Kb ", k, free_cnt, sz / 1024);
424484
Log("--- model pool --- end.");
425485
}
426486

src/Layers/xrRender/ModelPool.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ class ECORE_API CModelPool
1818
private:
1919
friend class CRender;
2020

21+
struct str_pred : public std::binary_function<const shared_str&, const shared_str&, bool>
22+
{
23+
IC bool operator()(const shared_str& x, const shared_str& y) const
24+
{
25+
return xr_strcmp(x, y) < 0;
26+
}
27+
};
28+
2129
struct ModelDef
2230
{
2331
shared_str name;
@@ -31,12 +39,15 @@ class ECORE_API CModelPool
3139
}
3240
};
3341

42+
typedef xr_multimap<shared_str, dxRender_Visual*, str_pred> POOL;
43+
typedef POOL::iterator POOL_IT;
3444
typedef xr_map<dxRender_Visual*, shared_str> REGISTRY;
3545
typedef REGISTRY::iterator REGISTRY_IT;
3646
private:
3747
xr_vector<ModelDef> Models; // Reference / Base
38-
xr_map<dxRender_Visual*, bool> ModelsToDelete; //
48+
xr_vector<dxRender_Visual*> ModelsToDelete; //
3949
REGISTRY Registry; // Just pairing of pointer / Name
50+
POOL Pool; // Unused / Inactive
4051
BOOL bLogging;
4152
BOOL bForceDiscard;
4253
BOOL bAllowChildrenDuplicate;
@@ -65,6 +76,7 @@ class ECORE_API CModelPool
6576

6677
void Prefetch();
6778
void Prefetch_One(LPCSTR N);
79+
void ClearPool(BOOL b_complete);
6880

6981
void dump();
7082

src/Layers/xrRenderPC_R1/FStaticRender.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,6 @@ void CRender::ros_destroy(IRender_ObjectSpecific* & p) { xr_delete(p); }
184184
IRenderVisual* CRender::model_Create(LPCSTR name, IReader* data) { return Models->Create(name, data); }
185185
IRenderVisual* CRender::model_CreateChild(LPCSTR name, IReader* data) { return Models->CreateChild(name, data); }
186186
IRenderVisual* CRender::model_Duplicate(IRenderVisual* V) { return Models->Instance_Duplicate((dxRender_Visual*)V); }
187-
IRenderVisual* CRender::model_Instance(LPCSTR name) { return Models->Instance_Find(name); }
188187

189188
void CRender::model_Delete(IRenderVisual* & V, BOOL bDiscard)
190189
{
@@ -232,6 +231,7 @@ IRenderVisual* CRender::model_CreateParticles(LPCSTR name)
232231

233232
void CRender::models_Prefetch() { Models->Prefetch(); }
234233
void CRender::models_PrefetchOne(LPCSTR name) { Models->Prefetch_One(name); }
234+
void CRender::models_Clear(BOOL b_complete) { Models->ClearPool(b_complete); }
235235

236236
ref_shader CRender::getShader(int id)
237237
{

src/Layers/xrRenderPC_R1/FStaticRender.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,12 +198,12 @@ class CRender : public R_dsgraph_structure
198198
virtual IRenderVisual* model_Create(LPCSTR name, IReader* data = 0);
199199
virtual IRenderVisual* model_CreateChild(LPCSTR name, IReader* data);
200200
virtual IRenderVisual* model_Duplicate(IRenderVisual* V);
201-
virtual IRenderVisual* model_Instance(LPCSTR name);
202201
virtual void model_Delete(IRenderVisual* & V, BOOL bDiscard);
203202
virtual void model_Delete(IRender_DetailModel* & F);
204203
virtual void model_Logging(BOOL bEnable) { Models->Logging(bEnable); }
205204
virtual void models_Prefetch();
206205
virtual void models_PrefetchOne(LPCSTR name);
206+
virtual void models_Clear(BOOL b_complete);
207207

208208
// Occlusion culling
209209
virtual BOOL occ_visible(vis_data& V);

src/Layers/xrRenderPC_R2/r2.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,6 @@ void CRender::ros_destroy(IRender_ObjectSpecific* & p) { xr_delete(p); }
478478
IRenderVisual* CRender::model_Create(LPCSTR name, IReader* data) { return Models->Create(name, data); }
479479
IRenderVisual* CRender::model_CreateChild(LPCSTR name, IReader* data) { return Models->CreateChild(name, data); }
480480
IRenderVisual* CRender::model_Duplicate(IRenderVisual* V) { return Models->Instance_Duplicate((dxRender_Visual*)V); }
481-
IRenderVisual* CRender::model_Instance(LPCSTR name) { return Models->Instance_Find(name); }
482481

483482
void CRender::model_Delete(IRenderVisual* & V, BOOL bDiscard)
484483
{
@@ -526,6 +525,7 @@ IRenderVisual* CRender::model_CreateParticles(LPCSTR name)
526525

527526
void CRender::models_Prefetch() { Models->Prefetch(); }
528527
void CRender::models_PrefetchOne(LPCTSTR name) { Models->Prefetch_One(name); }
528+
void CRender::models_Clear(BOOL b_complete) { Models->ClearPool(b_complete); }
529529

530530
ref_shader CRender::getShader(int id)
531531
{

src/Layers/xrRenderPC_R2/r2.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,12 +296,12 @@ class CRender : public R_dsgraph_structure
296296
virtual IRenderVisual* model_Create(LPCSTR name, IReader* data = 0);
297297
virtual IRenderVisual* model_CreateChild(LPCSTR name, IReader* data);
298298
virtual IRenderVisual* model_Duplicate(IRenderVisual* V);
299-
virtual IRenderVisual* model_Instance(LPCSTR name);
300299
virtual void model_Delete(IRenderVisual* & V, BOOL bDiscard);
301300
virtual void model_Delete(IRender_DetailModel* & F);
302301
virtual void model_Logging(BOOL bEnable) { Models->Logging(bEnable); }
303302
virtual void models_Prefetch();
304303
virtual void models_PrefetchOne(LPCSTR name);
304+
virtual void models_Clear(BOOL b_complete);
305305

306306
// Occlusion culling
307307
virtual BOOL occ_visible(vis_data& V);

0 commit comments

Comments
 (0)