Linux multi-monitor fullscreen support
[ryzomcore.git] / nel / tools / 3d / plugin_max / tile_utility / rgbadd.cpp
blob0f14805022497f7e50836877f0fdbc3ebf1a152e
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2019 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "tile_utility.h"
22 extern HINSTANCE hInstance;
23 TCHAR *GetString(int id);
25 #define NSUBTEX 2 // number of texture map slots
26 #define NCOLS 2
28 static int subTexId[NSUBTEX] = { IDC_MULT_TEX1, IDC_MULT_TEX2 };
30 #define ALPHA_FROM_1 0
31 #define ALPHA_FROM_2 1
32 #define ALPHA_FROM_MULT 2
34 //--------------------------------------------------------------
35 // RGBAdd: A Composite texture map
36 //--------------------------------------------------------------
37 class RGBAdd: public Texmap {
38 public:
39 BOOL Param1;
40 IParamBlock2 *pblock; // ref #0
41 Texmap* subTex[NSUBTEX]; // refs 1,2;
42 BOOL mapOn[NSUBTEX];
43 Color col[NCOLS];
44 Interval ivalid;
45 int alphaFrom;
46 BOOL rollScroll;
47 BOOL loadingOld;
48 RGBAdd();
49 ParamDlg* CreateParamDlg(HWND hwMtlEdit, IMtlParams *imp);
50 void Update(TimeValue t, Interval& valid);
51 void Init();
52 void Reset();
53 Interval Validity(TimeValue t) { Interval v; Update(t,v); return ivalid; }
55 void NotifyChanged();
57 void SetColor(int i, Color c, TimeValue t);
59 // Evaluate the color of map for the context.
60 AColor EvalColor(ShadeContext& sc);
61 float EvalMono(ShadeContext& sc);
62 AColor EvalFunction(ShadeContext& sc, float u, float v, float du, float dv);
64 // For Bump mapping, need a perturbation to apply to a normal.
65 // Leave it up to the Texmap to determine how to do this.
66 Point3 EvalNormalPerturb(ShadeContext& sc);
68 // Methods to access texture maps of material
69 int NumSubTexmaps() { return NSUBTEX; }
70 Texmap* GetSubTexmap(int i) { return subTex[i]; }
71 void SetSubTexmap(int i, Texmap *m);
72 TSTR GetSubTexmapSlotName(int i);
74 Class_ID ClassID() { return RGBAddClassID; }
75 SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
76 void GetClassName(TSTR& s) { s= _T("RGB Additive"); }
77 void DeleteThis() { delete this; }
79 int NumSubs() { return NSUBTEX+1; }
80 Animatable* SubAnim(int i);
81 TSTR SubAnimName(int i);
82 int SubNumToRefNum(int subNum) { return subNum; }
84 // From ref
85 int NumRefs() { return NSUBTEX+1; }
86 RefTargetHandle GetReference(int i);
87 void SetReference(int i, RefTargetHandle rtarg);
88 int RemapRefOnLoad(int iref);
90 RefTargetHandle Clone(RemapDir &remap = DefaultRemapDir());
91 RefResult NotifyRefChanged(NOTIFY_REF_PARAMS);
93 // IO
94 IOResult Save(ISave *isave);
95 IOResult Load(ILoad *iload);
97 // JBW: direct ParamBlock access is added
98 int NumParamBlocks() { return 1; } // return number of ParamBlocks in this instance
99 IParamBlock2* GetParamBlock(int i) { return pblock; } // return i'th ParamBlock
100 IParamBlock2* GetParamBlockByID(BlockID id) { return (pblock->ID() == id) ? pblock : NULL; } // return id'd ParamBlock
105 class RGBAddClassDesc:public ClassDesc2 {
106 public:
107 int IsPublic() { return 1; }
108 void * Create(BOOL loading) { return new RGBAdd; }
109 const TCHAR * ClassName() { return GetString(IDS_DS_RGBMULT_CDESC); } // mjm - 2.3.99
110 SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
111 Class_ID ClassID() { return RGBAddClassID; }
112 const MCHAR* Category() { return TEXMAP_CAT_COMP; }
113 // JBW: new descriptor data accessors added. Note that the
114 // internal name is hardwired since it must not be localized.
115 const MCHAR* InternalName() { return _M("RGBAdd"); } // returns fixed parsable name (scripter-visible name)
116 HINSTANCE HInstance() { return hInstance; } // returns owning module handle
119 static RGBAddClassDesc maskCD;
121 ClassDesc* GetRGBAddDesc() { return &maskCD; }
123 enum { RGBAdd_params }; // pblock ID
124 // RGBAdd_params param IDs
125 enum
127 RGBAdd_color1, RGBAdd_color2,
128 RGBAdd_map1, RGBAdd_map2,
129 RGBAdd_map1_on, RGBAdd_map2_on, // main grad params
130 RGBAdd_type,
134 static ParamBlockDesc2 RGBAdd_param_blk ( RGBAdd_params, _T("parameters"), 0, &maskCD, P_AUTO_CONSTRUCT + P_AUTO_UI, 0,
135 //rollout
136 IDD_RGBMULT, _T("RGB Additif Parameters"), 0, 0, NULL,
137 // params
138 RGBAdd_color1, _T("color1"), TYPE_RGBA, P_ANIMATABLE, IDS_DS_COLOR1,
139 p_default, Color(0,0,0),
140 p_ui, TYPE_COLORSWATCH, IDC_MULT_COL1,
141 nl_p_end,
142 RGBAdd_color2, _T("color2"), TYPE_RGBA, P_ANIMATABLE, IDS_DS_COLOR2,
143 p_default, Color(0.5,0.5,0.5),
144 p_ui, TYPE_COLORSWATCH, IDC_MULT_COL2,
145 nl_p_end,
146 RGBAdd_map1, _T("map1"), TYPE_TEXMAP, P_OWNERS_REF, IDS_JW_MAP1,
147 p_refno, 1,
148 p_subtexno, 0,
149 p_ui, TYPE_TEXMAPBUTTON, IDC_MULT_TEX1,
150 nl_p_end,
151 RGBAdd_map2, _T("map2"), TYPE_TEXMAP, P_OWNERS_REF, IDS_JW_MAP2,
152 p_refno, 2,
153 p_subtexno, 1,
154 p_ui, TYPE_TEXMAPBUTTON, IDC_MULT_TEX2,
155 nl_p_end,
156 RGBAdd_map1_on, _T("map1Enabled"), TYPE_BOOL, 0, IDS_JW_MAP1ENABLE,
157 p_default, TRUE,
158 p_ui, TYPE_SINGLECHEKBOX, IDC_MAPON1,
159 nl_p_end,
160 RGBAdd_map2_on, _T("map2Enabled"), TYPE_BOOL, 0, IDS_JW_MAP2ENABLE,
161 p_default, TRUE,
162 p_ui, TYPE_SINGLECHEKBOX, IDC_MAPON2,
163 nl_p_end,
164 RGBAdd_type, _T("alphaFrom"), TYPE_INT, 0, IDS_PW_ALPHAFROM,
165 p_default, 2,
166 p_range, 0, 2,
167 p_ui, TYPE_RADIO, 3, IDC_MULT_ALPHA1, IDC_MULT_ALPHA2, IDC_MULT_ALPHA3,
168 nl_p_end,
170 nl_p_end
174 //-----------------------------------------------------------------------------
175 // RGBAdd
176 //-----------------------------------------------------------------------------
177 #define NPARAMS 2
179 static int name_id[NPARAMS] = {IDS_DS_COLOR1, IDS_DS_COLOR2};
181 #define RGBAdd_VERSION 2
182 static ParamBlockDescID pbdesc[NPARAMS] = {
183 { TYPE_RGBA, NULL, TRUE,RGBAdd_color1 }, // col1
184 { TYPE_RGBA, NULL, TRUE,RGBAdd_color2 } // col2
187 static ParamVersionDesc versions[] = {
188 ParamVersionDesc(pbdesc,2,1), // Version 1 params
192 void RGBAdd::Init() {
193 ivalid.SetEmpty();
194 alphaFrom = ALPHA_FROM_MULT;
195 SetColor(0, Color(0.0f,0.0f,0.0f), TimeValue(0));
196 SetColor(1, Color(0.0f,0.0f,0.0f), TimeValue(0));
197 mapOn[0] = mapOn[1] = 1;
200 void RGBAdd::Reset() {
201 maskCD.Reset(this, TRUE); // reset all pb2's
202 DeleteReference(1); // get rid of maps
203 DeleteReference(2); // get rid of maps
204 Init();
207 void RGBAdd::NotifyChanged() {
208 NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
211 RGBAdd::RGBAdd()
213 for (int i=0; i<NSUBTEX; i++) subTex[i] = NULL;
214 pblock = NULL;
215 maskCD.MakeAutoParamBlocks(this); // make and intialize paramblock2
216 Init();
217 rollScroll=0;
221 static AColor white(1.0f,1.0f,1.0f,1.0f);
223 AColor RGBAdd::EvalColor(ShadeContext& sc)
225 if (gbufID) sc.SetGBufferID(gbufID);
226 AColor c0 = (subTex[0]&&mapOn[0])? subTex[0]->EvalColor(sc): col[0];
227 AColor c1 = (subTex[1]&&mapOn[1])? subTex[1]->EvalColor(sc): col[1];
228 AColor c;
229 c.r = c0.r+c1.r;
230 c.r = c.r > 1.f ? 1.f : c.r;
231 c.g = c0.g+c1.g;
232 c.g = c.g > 1.f ? 1.f : c.g;
233 c.b = c0.b+c1.b;
234 c.b = c.b > 1.f ? 1.f : c.b;
235 switch(alphaFrom) {
236 case ALPHA_FROM_1: c.a = c0.a; break;
237 case ALPHA_FROM_2: c.a = c1.a; break;
238 case ALPHA_FROM_MULT: c.a = c0.a*c1.a; break;
240 return c;
243 float RGBAdd::EvalMono(ShadeContext& sc)
245 if (gbufID) sc.SetGBufferID(gbufID);
246 float m = (subTex[1]&&mapOn[1])? subTex[1]->EvalMono(sc): Intens(col[0]);
247 float c0 = (subTex[0]&&mapOn[0])? subTex[0]->EvalMono(sc): Intens(col[1]);
248 return (m+c0) > 1.f ? 1.f : m+c0;
251 Point3 RGBAdd::EvalNormalPerturb(ShadeContext& sc) {
252 if (gbufID) sc.SetGBufferID(gbufID);
253 Point3 p0 = subTex[0]&&mapOn[0]? subTex[0]->EvalNormalPerturb(sc): Point3(0.0f,0.0f,0.0f);
254 Point3 p1 = subTex[1]&&mapOn[1]? subTex[1]->EvalNormalPerturb(sc): Point3(0.0f,0.0f,0.0f);
255 return p0+p1;
258 RefTargetHandle RGBAdd::Clone(RemapDir &remap) {
259 RGBAdd *mnew = new RGBAdd();
260 *((MtlBase*)mnew) = *((MtlBase*)this); // copy superclass stuff
261 mnew->ReplaceReference(0,remap.CloneRef(pblock));
262 mnew->ivalid.SetEmpty();
263 for (int i = 0; i<NSUBTEX; i++) {
264 mnew->subTex[i] = NULL;
265 if (subTex[i])
266 mnew->ReplaceReference(i+1,remap.CloneRef(subTex[i]));
267 mnew->mapOn[i] = mapOn[i];
269 mnew->alphaFrom = alphaFrom;
270 return (RefTargetHandle)mnew;
273 ParamDlg* RGBAdd::CreateParamDlg(HWND hwMtlEdit, IMtlParams *imp) {
274 IAutoMParamDlg* masterDlg = maskCD.CreateParamDlgs(hwMtlEdit, imp, this);
275 return masterDlg;
279 void RGBAdd::Update(TimeValue t, Interval& valid) {
281 if (Param1)
283 pblock->SetValue( RGBAdd_map1_on, 0, mapOn[0]);
284 pblock->SetValue( RGBAdd_map2_on, 0, mapOn[1]);
285 pblock->SetValue( RGBAdd_type, 0, alphaFrom);
286 Param1 = FALSE;
289 if (!ivalid.InInterval(t)) {
290 ivalid.SetInfinite();
291 pblock->GetValue( RGBAdd_color1, t, col[0], ivalid );
292 col[0].ClampMinMax();
293 pblock->GetValue( RGBAdd_color2, t, col[1], ivalid );
295 pblock->GetValue( RGBAdd_map1_on, t, mapOn[0], ivalid );
296 pblock->GetValue( RGBAdd_map2_on, t, mapOn[1], ivalid );
297 pblock->GetValue( RGBAdd_type, t, alphaFrom, ivalid );
300 col[1].ClampMinMax();
301 for (int i=0; i<NSUBTEX; i++) {
302 if (subTex[i])
303 subTex[i]->Update(t,ivalid);
306 valid &= ivalid;
309 void RGBAdd::SetColor(int i, Color c, TimeValue t) {
310 col[i] = c;
311 int id = i==0?RGBAdd_color1:RGBAdd_color2;
312 pblock->SetValue( id, t, c);
315 RefTargetHandle RGBAdd::GetReference(int i) {
316 if (i==0) return pblock;
317 else return subTex[i-1];
320 int RGBAdd::RemapRefOnLoad(int iref) {
321 if (loadingOld)
322 return iref+1;
323 else return iref;
326 void RGBAdd::SetReference(int i, RefTargetHandle rtarg) {
327 switch(i) {
328 case 0: pblock = (IParamBlock2 *)rtarg; break;
329 default: subTex[i-1] = (Texmap *)rtarg; break;
333 void RGBAdd::SetSubTexmap(int i, Texmap *m) {
334 ReplaceReference(i+1,m);
335 if (i==0)
337 RGBAdd_param_blk.InvalidateUI(RGBAdd_map1);
338 ivalid.SetEmpty();
340 else if (i==1)
342 RGBAdd_param_blk.InvalidateUI(RGBAdd_map2);
343 ivalid.SetEmpty();
348 TSTR RGBAdd::GetSubTexmapSlotName(int i) {
349 switch(i) {
350 case 0: return TSTR(GetString(IDS_DS_COLOR1));
351 case 1: return TSTR(GetString(IDS_DS_COLOR2));
352 default: return TSTR(_T(""));
356 Animatable* RGBAdd::SubAnim(int i) {
357 switch (i) {
358 case 0: return pblock;
359 default: return subTex[i-1];
363 TSTR RGBAdd::SubAnimName(int i) {
364 switch (i) {
365 case 0: return TSTR(GetString(IDS_DS_PARAMETERS));
366 default: return GetSubTexmapTVName(i-1);
370 RefResult RGBAdd::NotifyRefChanged(NOTIFY_REF_PARAMS)
372 switch (message)
374 case REFMSG_CHANGE:
375 ivalid.SetEmpty();
376 if (hTarget == pblock)
378 // see if this message came from a changing parameter in the pblock,
379 // if so, limit rollout update to the changing item and update any active viewport texture
380 ParamID changing_param = pblock->LastNotifyParamID();
381 RGBAdd_param_blk.InvalidateUI(changing_param);
382 // notify our dependents that we've changed
383 // NotifyChanged(); //DS this is redundant
386 break;
388 return(REF_SUCCEED);
392 #define MTL_HDR_CHUNK 0x4000
393 #define MAPOFF_CHUNK 0x1000
394 #define INVERT_RGBMULT_CHUNK 0x2000
395 #define ALPHA_FROM_CHUNK 0x2010
396 #define RGBAdd_VERSION_CHUNK 0x2020
397 #define PARAM2_CHUNK 0x2030
399 IOResult RGBAdd::Save(ISave *isave) {
400 IOResult res;
401 ULONG nb;
403 // Save common stuff
404 isave->BeginChunk(MTL_HDR_CHUNK);
405 res = MtlBase::Save(isave);
406 if (res!=IO_OK) return res;
407 isave->EndChunk();
409 int vers = RGBAdd_VERSION;
410 isave->BeginChunk(RGBAdd_VERSION_CHUNK);
411 isave->Write(&vers,sizeof(vers),&nb);
412 isave->EndChunk();
414 isave->BeginChunk(PARAM2_CHUNK);
415 isave->EndChunk();
416 return IO_OK;
419 class RGBAddPostLoad : public PostLoadCallback {
420 public:
421 RGBAdd *tm;
422 RGBAddPostLoad(RGBAdd *b) {tm=b;}
423 void proc(ILoad *iload) { tm->loadingOld = FALSE; delete this; }
426 class RGBAdd2PostLoad : public PostLoadCallback {
427 public:
428 RGBAdd *n;
429 RGBAdd2PostLoad(RGBAdd *ns) {n = ns;}
430 void proc(ILoad *iload) {
431 if (n->Param1)
433 n->pblock->SetValue( RGBAdd_map1_on, 0, n->mapOn[0]);
434 n->pblock->SetValue( RGBAdd_map2_on, 0, n->mapOn[1]);
435 n->pblock->SetValue( RGBAdd_type, 0, n->alphaFrom);
437 delete this;
445 IOResult RGBAdd::Load(ILoad *iload) {
446 ULONG nb;
447 IOResult res;
448 int id;
449 loadingOld = TRUE;
450 Param1 = TRUE;
451 while (IO_OK==(res=iload->OpenChunk())) {
452 switch(id = iload->CurChunkID()) {
453 case MTL_HDR_CHUNK:
454 res = MtlBase::Load(iload);
455 break;
456 case PARAM2_CHUNK:
457 Param1= FALSE;
458 break;
459 case RGBAdd_VERSION_CHUNK:
460 loadingOld = FALSE;
461 break;
462 case MAPOFF_CHUNK+0:
463 case MAPOFF_CHUNK+1:
464 mapOn[id-MAPOFF_CHUNK] = 0;
465 break;
466 case ALPHA_FROM_CHUNK:
467 res = iload->Read(&alphaFrom,sizeof(alphaFrom), &nb);
468 break;
470 iload->CloseChunk();
471 if (res!=IO_OK)
472 return res;
474 if (loadingOld)
475 iload->RegisterPostLoadCallback(new RGBAddPostLoad(this));
477 // JBW: register old version ParamBlock to ParamBlock2 converter
478 ParamBlock2PLCB* plcb = new ParamBlock2PLCB(versions, 1, &RGBAdd_param_blk, this, 0);
479 iload->RegisterPostLoadCallback(plcb);
481 // iload->RegisterPostLoadCallback(new RGBAdd2PostLoad(this));
485 return IO_OK;