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