1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
2
3 #include <map>
4 #include <boost/assign/list_of.hpp>
5
6 #include "LuaOpenGLUtils.h"
7
8 #include "LuaHandle.h"
9 #include "LuaTextures.h"
10 #include "Game/Camera.h"
11 #include "Map/BaseGroundDrawer.h"
12 #include "Map/HeightMapTexture.h"
13 #include "Map/ReadMap.h"
14 #include "Rendering/Fonts/glFont.h"
15 #include "Rendering/GlobalRendering.h"
16 #include "Rendering/IconHandler.h"
17 #include "Rendering/ShadowHandler.h"
18 #include "Rendering/UnitDrawer.h"
19 #include "Rendering/GL/GeometryBuffer.h"
20 #include "Rendering/Env/CubeMapHandler.h"
21 #include "Rendering/Models/3DModel.h"
22 #include "Rendering/Textures/NamedTextures.h"
23 #include "Rendering/Textures/3DOTextureHandler.h"
24 #include "Rendering/Textures/S3OTextureHandler.h"
25 #include "Sim/Features/FeatureDef.h"
26 #include "Sim/Features/FeatureHandler.h"
27 #include "Sim/Units/UnitDef.h"
28 #include "Sim/Units/UnitDefHandler.h"
29 #include "Sim/Units/UnitDefImage.h"
30 #include "System/Matrix44f.h"
31 #include "System/Util.h"
32 #include "System/Log/ILog.h"
33
34
35 /******************************************************************************/
36 /******************************************************************************/
37
38 enum LUAMATRICES {
39 LUAMATRICES_SHADOW,
40 LUAMATRICES_VIEW,
41 LUAMATRICES_VIEWINVERSE,
42 LUAMATRICES_PROJECTION,
43 LUAMATRICES_PROJECTIONINVERSE,
44 LUAMATRICES_VIEWPROJECTION,
45 LUAMATRICES_VIEWPROJECTIONINVERSE,
46 LUAMATRICES_BILLBOARD,
47 LUAMATRICES_NONE
48 };
49
50 static const std::map<std::string, LUAMATRICES> matrixNameToId = boost::assign::map_list_of
51 ("shadow", LUAMATRICES_SHADOW)
52 ("view", LUAMATRICES_VIEW)
53 ("viewinverse", LUAMATRICES_VIEWINVERSE)
54 ("projection", LUAMATRICES_PROJECTION)
55 ("projectioninverse", LUAMATRICES_PROJECTIONINVERSE)
56 ("viewprojection", LUAMATRICES_VIEWPROJECTION)
57 ("viewprojectioninverse", LUAMATRICES_VIEWPROJECTIONINVERSE)
58 ("billboard", LUAMATRICES_BILLBOARD)
59 // backward compability
60 ("camera", LUAMATRICES_VIEW)
61 ("caminv", LUAMATRICES_VIEWINVERSE)
62 ("camprj", LUAMATRICES_PROJECTION)
63 ("camprjinv", LUAMATRICES_PROJECTIONINVERSE)
64 ;
65
MatrixGetId(const std::string & name)66 inline static LUAMATRICES MatrixGetId(const std::string& name)
67 {
68 const std::map<std::string, LUAMATRICES>::const_iterator it = matrixNameToId.find(name);
69 if (it == matrixNameToId.end()) {
70 return LUAMATRICES_NONE;
71 }
72 return it->second;
73 }
74
75 /******************************************************************************/
76 /******************************************************************************/
77
GetNamedMatrix(const std::string & name)78 const CMatrix44f* LuaOpenGLUtils::GetNamedMatrix(const std::string& name)
79 {
80 //! don't do for performance reasons (this function gets called a lot)
81 //StringToLowerInPlace(name);
82
83 const LUAMATRICES mat = MatrixGetId(name);
84
85 switch (mat) {
86 case LUAMATRICES_SHADOW:
87 if (shadowHandler == NULL) {
88 break;
89 }
90 return &shadowHandler->shadowMatrix;
91 case LUAMATRICES_VIEW:
92 return &camera->GetViewMatrix();
93 case LUAMATRICES_VIEWINVERSE:
94 return &camera->GetViewMatrixInverse();
95 case LUAMATRICES_PROJECTION:
96 return &camera->GetProjectionMatrix();
97 case LUAMATRICES_PROJECTIONINVERSE:
98 return &camera->GetProjectionMatrixInverse();
99 case LUAMATRICES_VIEWPROJECTION:
100 return &camera->GetViewProjectionMatrix();
101 case LUAMATRICES_VIEWPROJECTIONINVERSE:
102 return &camera->GetViewProjectionMatrixInverse();
103 case LUAMATRICES_BILLBOARD:
104 return &camera->GetBillBoardMatrix();
105 case LUAMATRICES_NONE:
106 break;
107 }
108
109 return NULL;
110 }
111
112
ParseUnitTexture(LuaMatTexture & texUnit,const std::string & texture)113 bool ParseUnitTexture(LuaMatTexture& texUnit, const std::string& texture)
114 {
115 if (texture.length()<4) {
116 return false;
117 }
118
119 char* endPtr;
120 const char* startPtr = texture.c_str() + 1; // skip the '%'
121 const int id = (int)strtol(startPtr, &endPtr, 10);
122 if ((endPtr == startPtr) || (*endPtr != ':')) {
123 return false;
124 }
125
126 endPtr++; // skip the ':'
127 if ( (startPtr-1)+texture.length() <= endPtr ) {
128 return false; // ':' is end of string, but we expect '%num:0'
129 }
130
131 if (id == 0) {
132 texUnit.type = LuaMatTexture::LUATEX_3DOTEXTURE;
133 if (*endPtr == '0') {
134 texUnit.data = reinterpret_cast<const void*>(int(1));
135 }
136 else if (*endPtr == '1') {
137 texUnit.data = reinterpret_cast<const void*>(int(2));
138 }
139 return true;
140 }
141
142 S3DModel* model;
143
144 if (id < 0) {
145 const FeatureDef* fd = featureHandler->GetFeatureDefByID(-id);
146 if (fd == NULL) {
147 return false;
148 }
149 model = fd->LoadModel();
150 } else {
151 const UnitDef* ud = unitDefHandler->GetUnitDefByID(id);
152 if (ud == NULL) {
153 return false;
154 }
155 model = ud->LoadModel();
156 }
157
158 if (model == NULL) {
159 return false;
160 }
161
162 const unsigned int texType = model->textureType;
163 if (texType == 0) {
164 return false;
165 }
166
167 const CS3OTextureHandler::S3oTex* stex = texturehandlerS3O->GetS3oTex(texType);
168 if (stex == NULL) {
169 return false;
170 }
171
172 if (*endPtr == '0') {
173 texUnit.type = LuaMatTexture::LUATEX_UNITTEXTURE1;
174 texUnit.data = reinterpret_cast<const void*>(stex);
175 }
176 else if (*endPtr == '1') {
177 texUnit.type = LuaMatTexture::LUATEX_UNITTEXTURE2;
178 texUnit.data = reinterpret_cast<const void*>(stex);
179 }
180
181 return true;
182 }
183
184
ParseTextureImage(lua_State * L,LuaMatTexture & texUnit,const std::string & image)185 bool LuaOpenGLUtils::ParseTextureImage(lua_State* L, LuaMatTexture& texUnit, const std::string& image)
186 {
187 // NOTE: current formats:
188 //
189 // #12 -- unitDef 12 buildpic
190 // %34:0 -- unitDef 34 s3o tex1
191 // %-34:1 -- featureDef 34 s3o tex2
192 // !56 -- lua generated texture 56
193 // $shadow -- shadowmap
194 // $specular -- specular cube map
195 // $reflection -- reflection cube map
196 // $heightmap -- ground heightmap
197 // ... -- named textures
198 //
199
200 texUnit.type = LuaMatTexture::LUATEX_NONE;
201 texUnit.enable = false;
202 texUnit.data = 0;
203
204 if (image.empty()) {
205 return false;
206 }
207
208 if (image[0] == LuaTextures::prefix) {
209 // dynamic texture
210 LuaTextures& textures = CLuaHandle::GetActiveTextures(L);
211 const LuaTextures::Texture* texInfo = textures.GetInfo(image);
212 if (texInfo == NULL) {
213 return false;
214 }
215 texUnit.type = LuaMatTexture::LUATEX_LUATEXTURE;
216 texUnit.data = reinterpret_cast<const void*>(texInfo);
217 }
218 else if (image[0] == '%') {
219 return ParseUnitTexture(texUnit, image);
220 }
221 else if (image[0] == '#') {
222 // unit build picture
223 char* endPtr;
224 const char* startPtr = image.c_str() + 1; // skip the '#'
225 const int unitDefID = (int)strtol(startPtr, &endPtr, 10);
226 if (endPtr == startPtr) {
227 return false;
228 }
229 const UnitDef* ud = unitDefHandler->GetUnitDefByID(unitDefID);
230 if (ud == NULL) {
231 return false;
232 }
233 texUnit.type = LuaMatTexture::LUATEX_UNITBUILDPIC;
234 texUnit.data = reinterpret_cast<const void*>(ud);
235 }
236 else if (image[0] == '^') {
237 // unit icon
238 char* endPtr;
239 const char* startPtr = image.c_str() + 1; // skip the '^'
240 const int unitDefID = (int)strtol(startPtr, &endPtr, 10);
241 if (endPtr == startPtr) {
242 return false;
243 }
244 const UnitDef* ud = unitDefHandler->GetUnitDefByID(unitDefID);
245 if (ud == NULL) {
246 return false;
247 }
248 texUnit.type = LuaMatTexture::LUATEX_UNITRADARICON;
249 texUnit.data = reinterpret_cast<const void*>(ud);
250 }
251 else if (image[0] == '$') {
252 if (image == "$units" || image == "$units1") {
253 texUnit.type = LuaMatTexture::LUATEX_3DOTEXTURE;
254 texUnit.data = reinterpret_cast<const void*>(int(1));
255 }
256 else if (image == "$units2") {
257 texUnit.type = LuaMatTexture::LUATEX_3DOTEXTURE;
258 texUnit.data = reinterpret_cast<const void*>(int(2));
259 }
260 else if (image == "$shadow") {
261 texUnit.type = LuaMatTexture::LUATEX_SHADOWMAP;
262 }
263 else if (image == "$specular") {
264 texUnit.type = LuaMatTexture::LUATEX_SPECULAR;
265 }
266 else if (image == "$reflection") {
267 texUnit.type = LuaMatTexture::LUATEX_REFLECTION;
268 }
269 else if (image == "$heightmap") {
270 texUnit.type = LuaMatTexture::LUATEX_HEIGHTMAP;
271
272 if (heightMapTexture->GetTextureID() == 0) {
273 // it's optional, return false when not available
274 return false;
275 }
276 }
277 else if (image == "$shading") {
278 texUnit.type = LuaMatTexture::LUATEX_SHADING;
279 }
280 else if (image == "$grass") {
281 texUnit.type = LuaMatTexture::LUATEX_GRASS;
282 }
283 else if (image == "$minimap") {
284 texUnit.type = LuaMatTexture::LUATEX_MINIMAP;
285 }
286
287 else if (image == "$info" || image == "$extra" ) { texUnit.type = LuaMatTexture::LUATEX_INFOTEX_ACTIVE; }
288 else if (image == "$info_losmap" || image == "$extra_losmap") { texUnit.type = LuaMatTexture::LUATEX_INFOTEX_LOSMAP; }
289 else if (image == "$info_mtlmap" || image == "$extra_mtlmap") { texUnit.type = LuaMatTexture::LUATEX_INFOTEX_MTLMAP; }
290 else if (image == "$info_hgtmap" || image == "$extra_hgtmap") { texUnit.type = LuaMatTexture::LUATEX_INFOTEX_HGTMAP; }
291 else if (image == "$info_blkmap" || image == "$extra_blkmap") { texUnit.type = LuaMatTexture::LUATEX_INFOTEX_BLKMAP; }
292
293 else if (image == "$map_gb_nt" || image == "$map_gbuffer_normtex") { texUnit.type = LuaMatTexture::LUATEX_MAP_GBUFFER_NORMTEX; }
294 else if (image == "$map_gb_dt" || image == "$map_gbuffer_difftex") { texUnit.type = LuaMatTexture::LUATEX_MAP_GBUFFER_DIFFTEX; }
295 else if (image == "$map_gb_st" || image == "$map_gbuffer_spectex") { texUnit.type = LuaMatTexture::LUATEX_MAP_GBUFFER_SPECTEX; }
296 else if (image == "$map_gb_et" || image == "$map_gbuffer_emittex") { texUnit.type = LuaMatTexture::LUATEX_MAP_GBUFFER_EMITTEX; }
297 else if (image == "$map_gb_mt" || image == "$map_gbuffer_misctex") { texUnit.type = LuaMatTexture::LUATEX_MAP_GBUFFER_MISCTEX; }
298 else if (image == "$map_gb_zt" || image == "$map_gbuffer_zvaltex") { texUnit.type = LuaMatTexture::LUATEX_MAP_GBUFFER_ZVALTEX; }
299
300 else if (image == "$mdl_gb_nt" || image == "$model_gbuffer_normtex") { texUnit.type = LuaMatTexture::LUATEX_MODEL_GBUFFER_NORMTEX; }
301 else if (image == "$mdl_gb_dt" || image == "$model_gbuffer_difftex") { texUnit.type = LuaMatTexture::LUATEX_MODEL_GBUFFER_DIFFTEX; }
302 else if (image == "$mdl_gb_st" || image == "$model_gbuffer_spectex") { texUnit.type = LuaMatTexture::LUATEX_MODEL_GBUFFER_SPECTEX; }
303 else if (image == "$mdl_gb_et" || image == "$model_gbuffer_emittex") { texUnit.type = LuaMatTexture::LUATEX_MODEL_GBUFFER_EMITTEX; }
304 else if (image == "$mdl_gb_mt" || image == "$model_gbuffer_misctex") { texUnit.type = LuaMatTexture::LUATEX_MODEL_GBUFFER_MISCTEX; }
305 else if (image == "$mdl_gb_zt" || image == "$model_gbuffer_zvaltex") { texUnit.type = LuaMatTexture::LUATEX_MODEL_GBUFFER_ZVALTEX; }
306
307 else if (image == "$font") {
308 texUnit.type = LuaMatTexture::LUATEX_FONT;
309 }
310 else if (image == "$smallfont" || image == "$fontsmall") {
311 texUnit.type = LuaMatTexture::LUATEX_FONTSMALL;
312 }
313 else {
314 return false;
315 }
316 }
317 else {
318 const CNamedTextures::TexInfo* texInfo = CNamedTextures::GetInfo(image, true);
319 if (texInfo != NULL) {
320 texUnit.type = LuaMatTexture::LUATEX_NAMED;
321 texUnit.data = reinterpret_cast<const void*>(texInfo);
322 } else {
323 LOG_L(L_WARNING, "Lua: Couldn't load texture named \"%s\"!", image.c_str());
324 return false;
325 }
326 }
327
328 return true;
329 }
330
331
GetTextureID() const332 GLuint LuaMatTexture::GetTextureID() const
333 {
334 GLuint texID = 0;
335
336 #define groundDrawer (readMap->GetGroundDrawer())
337 #define gdGeomBuff (groundDrawer->GetGeometryBuffer())
338 #define udGeomBuff (unitDrawer->GetGeometryBuffer())
339
340 switch (type) {
341 case LUATEX_NONE: {
342 } break;
343 case LUATEX_NAMED: {
344 texID = reinterpret_cast<const CNamedTextures::TexInfo*>(data)->id;
345 } break;
346 case LUATEX_LUATEXTURE: {
347 texID = reinterpret_cast<const LuaTextures::Texture*>(data)->id;
348 } break;
349 case LUATEX_UNITTEXTURE1: {
350 auto stex = reinterpret_cast<const CS3OTextureHandler::S3oTex*>(data);
351 texID = stex->tex1;
352 } break;
353 case LUATEX_UNITTEXTURE2: {
354 auto stex = reinterpret_cast<const CS3OTextureHandler::S3oTex*>(data);
355 texID = stex->tex2;
356 } break;
357 case LUATEX_3DOTEXTURE: {
358 if (*reinterpret_cast<const int*>(&data) == 1) {
359 texID = texturehandler3DO->GetAtlasTex1ID();
360 } else {
361 texID = texturehandler3DO->GetAtlasTex2ID();
362 }
363 } break;
364 case LUATEX_UNITBUILDPIC: {
365 auto ud = reinterpret_cast<const UnitDef*>(data);
366 texID = unitDefHandler->GetUnitDefImage(ud);
367 } break;
368 case LUATEX_UNITRADARICON: {
369 auto ud = reinterpret_cast<const UnitDef*>(data);
370 texID = ud->iconType->GetTextureID();
371 } break;
372 case LUATEX_SHADOWMAP: {
373 texID = shadowHandler->shadowTexture;
374 } break;
375 case LUATEX_REFLECTION: {
376 texID = cubeMapHandler->GetEnvReflectionTextureID();
377 } break;
378 case LUATEX_SPECULAR: {
379 texID = cubeMapHandler->GetSpecularTextureID();
380 } break;
381 case LUATEX_HEIGHTMAP: {
382 if (heightMapTexture)
383 texID = heightMapTexture->GetTextureID();
384 } break;
385 case LUATEX_SHADING: {
386 texID = (readMap != NULL)? readMap->GetShadingTexture(): 0;
387 } break;
388 case LUATEX_GRASS: {
389 texID = (readMap != NULL)? readMap->GetGrassShadingTexture(): 0;
390 } break;
391 case LUATEX_FONT: {
392 texID = font->GetTexture();
393 } break;
394 case LUATEX_FONTSMALL: {
395 texID = smallFont->GetTexture();
396 } break;
397 case LUATEX_MINIMAP:
398 texID = (readMap != NULL)? readMap->GetMiniMapTexture(): 0;
399 break;
400
401 case LUATEX_INFOTEX_ACTIVE: { texID = (readMap != NULL)? groundDrawer->GetActiveInfoTexture() : 0; } break;
402 case LUATEX_INFOTEX_LOSMAP: { texID = (readMap != NULL)? groundDrawer->GetInfoTexture(CBaseGroundDrawer::drawLos ): 0; } break;
403 case LUATEX_INFOTEX_MTLMAP: { texID = (readMap != NULL)? groundDrawer->GetInfoTexture(CBaseGroundDrawer::drawMetal ): 0; } break;
404 case LUATEX_INFOTEX_HGTMAP: { texID = (readMap != NULL)? groundDrawer->GetInfoTexture(CBaseGroundDrawer::drawHeight ): 0; } break;
405 case LUATEX_INFOTEX_BLKMAP: { texID = (readMap != NULL)? groundDrawer->GetInfoTexture(CBaseGroundDrawer::drawPathTrav): 0; } break;
406
407 case LUATEX_MAP_GBUFFER_NORMTEX: { texID = gdGeomBuff->GetBufferTexture(GL::GeometryBuffer::ATTACHMENT_NORMTEX); } break;
408 case LUATEX_MAP_GBUFFER_DIFFTEX: { texID = gdGeomBuff->GetBufferTexture(GL::GeometryBuffer::ATTACHMENT_DIFFTEX); } break;
409 case LUATEX_MAP_GBUFFER_SPECTEX: { texID = gdGeomBuff->GetBufferTexture(GL::GeometryBuffer::ATTACHMENT_SPECTEX); } break;
410 case LUATEX_MAP_GBUFFER_EMITTEX: { texID = gdGeomBuff->GetBufferTexture(GL::GeometryBuffer::ATTACHMENT_EMITTEX); } break;
411 case LUATEX_MAP_GBUFFER_MISCTEX: { texID = gdGeomBuff->GetBufferTexture(GL::GeometryBuffer::ATTACHMENT_MISCTEX); } break;
412 case LUATEX_MAP_GBUFFER_ZVALTEX: { texID = gdGeomBuff->GetBufferTexture(GL::GeometryBuffer::ATTACHMENT_ZVALTEX); } break;
413
414 case LUATEX_MODEL_GBUFFER_NORMTEX: { texID = udGeomBuff->GetBufferTexture(GL::GeometryBuffer::ATTACHMENT_NORMTEX); } break;
415 case LUATEX_MODEL_GBUFFER_DIFFTEX: { texID = udGeomBuff->GetBufferTexture(GL::GeometryBuffer::ATTACHMENT_DIFFTEX); } break;
416 case LUATEX_MODEL_GBUFFER_SPECTEX: { texID = udGeomBuff->GetBufferTexture(GL::GeometryBuffer::ATTACHMENT_SPECTEX); } break;
417 case LUATEX_MODEL_GBUFFER_EMITTEX: { texID = udGeomBuff->GetBufferTexture(GL::GeometryBuffer::ATTACHMENT_EMITTEX); } break;
418 case LUATEX_MODEL_GBUFFER_MISCTEX: { texID = udGeomBuff->GetBufferTexture(GL::GeometryBuffer::ATTACHMENT_MISCTEX); } break;
419 case LUATEX_MODEL_GBUFFER_ZVALTEX: { texID = udGeomBuff->GetBufferTexture(GL::GeometryBuffer::ATTACHMENT_ZVALTEX); } break;
420
421 default:
422 assert(false);
423 }
424
425 #undef udGeomBuff
426 #undef gdGeomBuff
427 #undef groundDrawer
428
429 return texID;
430 }
431
432
GetTextureTarget() const433 GLuint LuaMatTexture::GetTextureTarget() const
434 {
435 GLuint texType = GL_TEXTURE_2D;
436
437 switch (type) {
438 case LUATEX_NAMED: {
439 texType = GL_TEXTURE_2D; //FIXME allow lua to load cubemaps!
440 } break;
441 case LUATEX_LUATEXTURE: {
442 texType = reinterpret_cast<const LuaTextures::Texture*>(data)->target;
443 } break;
444 case LUATEX_REFLECTION:
445 case LUATEX_SPECULAR: {
446 texType = GL_TEXTURE_CUBE_MAP_ARB;
447 } break;
448
449 case LUATEX_NONE:
450 case LUATEX_UNITTEXTURE1:
451 case LUATEX_UNITTEXTURE2:
452 case LUATEX_3DOTEXTURE:
453 case LUATEX_UNITBUILDPIC:
454 case LUATEX_UNITRADARICON:
455 case LUATEX_SHADOWMAP:
456 case LUATEX_HEIGHTMAP:
457 case LUATEX_SHADING:
458 case LUATEX_GRASS:
459 case LUATEX_FONT:
460 case LUATEX_FONTSMALL:
461 case LUATEX_MINIMAP:
462
463 case LUATEX_INFOTEX_ACTIVE:
464 case LUATEX_INFOTEX_LOSMAP:
465 case LUATEX_INFOTEX_MTLMAP:
466 case LUATEX_INFOTEX_HGTMAP:
467 case LUATEX_INFOTEX_BLKMAP: {
468 texType = GL_TEXTURE_2D;
469 } break;
470
471 case LUATEX_MAP_GBUFFER_NORMTEX:
472 case LUATEX_MAP_GBUFFER_DIFFTEX:
473 case LUATEX_MAP_GBUFFER_SPECTEX:
474 case LUATEX_MAP_GBUFFER_EMITTEX:
475 case LUATEX_MAP_GBUFFER_MISCTEX:
476 case LUATEX_MAP_GBUFFER_ZVALTEX: {
477 texType = GL_TEXTURE_2D;
478 } break;
479
480 case LUATEX_MODEL_GBUFFER_NORMTEX:
481 case LUATEX_MODEL_GBUFFER_DIFFTEX:
482 case LUATEX_MODEL_GBUFFER_SPECTEX:
483 case LUATEX_MODEL_GBUFFER_EMITTEX:
484 case LUATEX_MODEL_GBUFFER_MISCTEX:
485 case LUATEX_MODEL_GBUFFER_ZVALTEX: {
486 texType = GL_TEXTURE_2D;
487 } break;
488
489 default:
490 assert(false);
491 }
492
493 return texType;
494 }
495
496
Bind() const497 void LuaMatTexture::Bind() const
498 {
499 const GLuint texID = GetTextureID();
500 const GLuint texType = GetTextureTarget();
501
502 if (texID != 0) {
503 glBindTexture(texType, texID);
504 if (enable && (texType == GL_TEXTURE_2D)) {
505 glEnable(GL_TEXTURE_2D);
506 }
507 } else if (!enable && (texType == GL_TEXTURE_2D)) {
508 glDisable(GL_TEXTURE_2D);
509 }
510
511 if (enableTexParams && type == LUATEX_SHADOWMAP) {
512 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE);
513 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
514 glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
515 }
516 }
517
518
Unbind() const519 void LuaMatTexture::Unbind() const
520 {
521 if (type == LUATEX_NONE)
522 return;
523
524 if (enableTexParams && type == LUATEX_SHADOWMAP) {
525 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
526 glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
527 }
528
529 if (!enable)
530 return;
531
532 const GLuint texType = GetTextureTarget();
533 if (texType == GL_TEXTURE_2D)
534 glDisable(GL_TEXTURE_2D);
535 }
536
537
GetSize() const538 int2 LuaMatTexture::GetSize() const
539 {
540 #define sqint2(x) int2(x, x)
541 switch (type) {
542 case LUATEX_NAMED: {
543 const auto namedTex = reinterpret_cast<const CNamedTextures::TexInfo*>(data);
544 return int2(namedTex->xsize, namedTex->ysize);
545 } break;
546 case LUATEX_LUATEXTURE: {
547 const auto luaTex = reinterpret_cast<const LuaTextures::Texture*>(data);
548 return int2(luaTex->xsize, luaTex->ysize);
549 } break;
550 case LUATEX_UNITTEXTURE1: {
551 const auto stex = reinterpret_cast<const CS3OTextureHandler::S3oTex*>(data);
552 return int2(stex->tex1SizeX, stex->tex1SizeY);
553 } break;
554 case LUATEX_UNITTEXTURE2: {
555 const auto stex = reinterpret_cast<const CS3OTextureHandler::S3oTex*>(data);
556 return int2(stex->tex2SizeX, stex->tex2SizeY);
557 } break;
558 case LUATEX_3DOTEXTURE:
559 return int2(texturehandler3DO->GetAtlasTexSizeX(), texturehandler3DO->GetAtlasTexSizeY());
560 case LUATEX_UNITBUILDPIC: {
561 const auto ud = reinterpret_cast<const UnitDef*>(data);
562 unitDefHandler->GetUnitDefImage(ud); // forced existance
563 return int2(ud->buildPic->imageSizeX, ud->buildPic->imageSizeY);
564 } break;
565 case LUATEX_UNITRADARICON: {
566 const auto ud = reinterpret_cast<const UnitDef*>(data);
567 return int2(ud->iconType->GetSizeX(), ud->iconType->GetSizeY());
568 } break;
569 case LUATEX_SHADOWMAP:
570 return sqint2(shadowHandler->shadowMapSize);
571 case LUATEX_REFLECTION:
572 return sqint2(cubeMapHandler->GetReflectionTextureSize());
573 case LUATEX_SPECULAR:
574 return sqint2(cubeMapHandler->GetSpecularTextureSize());
575 case LUATEX_SHADING:
576 return int2(gs->pwr2mapx, gs->pwr2mapy);
577 case LUATEX_GRASS:
578 return int2(1024, 1024);
579 case LUATEX_FONT:
580 return int2(font->GetTextureWidth(), font->GetTextureHeight());
581 case LUATEX_FONTSMALL:
582 return int2(smallFont->GetTextureWidth(), smallFont->GetTextureHeight());
583 case LUATEX_MINIMAP:
584 if (readMap != NULL) {
585 return readMap->GetMiniMapTextureSize();
586 }
587 break;
588
589 case LUATEX_INFOTEX_ACTIVE:
590 case LUATEX_INFOTEX_LOSMAP:
591 case LUATEX_INFOTEX_MTLMAP:
592 case LUATEX_INFOTEX_HGTMAP:
593 case LUATEX_INFOTEX_BLKMAP: {
594 if (readMap != NULL) {
595 return (readMap->GetGroundDrawer()->GetInfoTexSize());
596 }
597 }
598
599 case LUATEX_MAP_GBUFFER_NORMTEX:
600 case LUATEX_MAP_GBUFFER_DIFFTEX:
601 case LUATEX_MAP_GBUFFER_SPECTEX:
602 case LUATEX_MAP_GBUFFER_EMITTEX:
603 case LUATEX_MAP_GBUFFER_MISCTEX:
604 case LUATEX_MAP_GBUFFER_ZVALTEX: {
605 if (readMap != NULL) {
606 return (readMap->GetGroundDrawer()->GetGeometryBuffer()->GetWantedSize(readMap->GetGroundDrawer()->DrawDeferred()));
607 }
608 }
609
610 case LUATEX_MODEL_GBUFFER_NORMTEX:
611 case LUATEX_MODEL_GBUFFER_DIFFTEX:
612 case LUATEX_MODEL_GBUFFER_SPECTEX:
613 case LUATEX_MODEL_GBUFFER_EMITTEX:
614 case LUATEX_MODEL_GBUFFER_MISCTEX:
615 case LUATEX_MODEL_GBUFFER_ZVALTEX: {
616 if (unitDrawer != NULL) {
617 return (unitDrawer->GetGeometryBuffer()->GetWantedSize(unitDrawer->DrawDeferred()));
618 }
619 }
620
621 case LUATEX_HEIGHTMAP:
622 if (heightMapTexture != NULL) {
623 return int2(heightMapTexture->GetSizeX(), heightMapTexture->GetSizeY());
624 }
625
626 case LUATEX_NONE:
627 default: break;
628 }
629
630 return int2(0, 0);
631 }
632
633
634
635 /******************************************************************************/
636 /******************************************************************************/
637 //
638 // LuaMatTexture
639 //
640
Finalize()641 void LuaMatTexture::Finalize()
642 {
643 //if (type == LUATEX_NONE) {
644 // enable = false;
645 //}
646 }
647
648
Compare(const LuaMatTexture & a,const LuaMatTexture & b)649 int LuaMatTexture::Compare(const LuaMatTexture& a, const LuaMatTexture& b)
650 {
651 if (a.type != b.type) {
652 return (a.type < b.type) ? -1 : +1;
653 }
654 if (a.data != b.data) {
655 return (a.data < b.data) ? -1 : +1;
656 }
657 if (a.enable != b.enable) {
658 return a.enable ? -1 : +1;
659 }
660 return 0;
661 }
662
663
Print(const string & indent) const664 void LuaMatTexture::Print(const string& indent) const
665 {
666 const char* typeName = "Unknown";
667
668 switch (type) {
669 #define STRING_CASE(ptr, x) case x: ptr = #x; break;
670 STRING_CASE(typeName, LUATEX_NONE);
671 STRING_CASE(typeName, LUATEX_NAMED);
672 STRING_CASE(typeName, LUATEX_LUATEXTURE);
673 STRING_CASE(typeName, LUATEX_UNITTEXTURE1);
674 STRING_CASE(typeName, LUATEX_UNITTEXTURE2);
675 STRING_CASE(typeName, LUATEX_3DOTEXTURE);
676 STRING_CASE(typeName, LUATEX_UNITBUILDPIC);
677 STRING_CASE(typeName, LUATEX_UNITRADARICON);
678 STRING_CASE(typeName, LUATEX_SHADOWMAP);
679 STRING_CASE(typeName, LUATEX_REFLECTION);
680 STRING_CASE(typeName, LUATEX_SPECULAR);
681 STRING_CASE(typeName, LUATEX_HEIGHTMAP);
682 STRING_CASE(typeName, LUATEX_SHADING);
683 STRING_CASE(typeName, LUATEX_GRASS);
684 STRING_CASE(typeName, LUATEX_FONT);
685 STRING_CASE(typeName, LUATEX_FONTSMALL);
686 STRING_CASE(typeName, LUATEX_MINIMAP);
687
688 STRING_CASE(typeName, LUATEX_INFOTEX_ACTIVE);
689 STRING_CASE(typeName, LUATEX_INFOTEX_LOSMAP);
690 STRING_CASE(typeName, LUATEX_INFOTEX_MTLMAP);
691 STRING_CASE(typeName, LUATEX_INFOTEX_HGTMAP);
692 STRING_CASE(typeName, LUATEX_INFOTEX_BLKMAP);
693
694 STRING_CASE(typeName, LUATEX_MAP_GBUFFER_NORMTEX);
695 STRING_CASE(typeName, LUATEX_MAP_GBUFFER_DIFFTEX);
696 STRING_CASE(typeName, LUATEX_MAP_GBUFFER_SPECTEX);
697 STRING_CASE(typeName, LUATEX_MAP_GBUFFER_EMITTEX);
698 STRING_CASE(typeName, LUATEX_MAP_GBUFFER_MISCTEX);
699 STRING_CASE(typeName, LUATEX_MAP_GBUFFER_ZVALTEX);
700
701 STRING_CASE(typeName, LUATEX_MODEL_GBUFFER_NORMTEX);
702 STRING_CASE(typeName, LUATEX_MODEL_GBUFFER_DIFFTEX);
703 STRING_CASE(typeName, LUATEX_MODEL_GBUFFER_SPECTEX);
704 STRING_CASE(typeName, LUATEX_MODEL_GBUFFER_EMITTEX);
705 STRING_CASE(typeName, LUATEX_MODEL_GBUFFER_MISCTEX);
706 STRING_CASE(typeName, LUATEX_MODEL_GBUFFER_ZVALTEX);
707 #undef STRING_CASE
708 }
709
710 LOG("%s%s %i %s", indent.c_str(), typeName, *reinterpret_cast<const GLuint*>(&data), (enable ? "true" : "false"));
711 }
712
713
714 /******************************************************************************/
715 /******************************************************************************/
716