File: S3OTextureHandler.cpp

package info (click to toggle)
spring 98.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 41,928 kB
  • ctags: 60,665
  • sloc: cpp: 356,167; ansic: 39,434; python: 12,228; java: 12,203; awk: 5,856; sh: 1,719; xml: 997; perl: 405; php: 253; objc: 194; makefile: 72; sed: 2
file content (174 lines) | stat: -rw-r--r-- 5,255 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */


#include "S3OTextureHandler.h"

#include "System/FileSystem/FileHandler.h"
#include "System/FileSystem/SimpleParser.h"
#include "Rendering/ShadowHandler.h"
#include "Rendering/UnitDrawer.h"
#include "Rendering/Models/3DModel.h"
#include "Rendering/Textures/Bitmap.h"
#include "System/Util.h"
#include "System/Exceptions.h"
#include "System/Log/ILog.h"
#include "System/Platform/Threading.h"

#include <algorithm>
#include <cctype>
#include <set>
#include <sstream>

#define LOG_SECTION_TEXTURE "Texture"
LOG_REGISTER_SECTION_GLOBAL(LOG_SECTION_TEXTURE)
#ifdef LOG_SECTION_CURRENT
        #undef LOG_SECTION_CURRENT
#endif
#define LOG_SECTION_CURRENT LOG_SECTION_TEXTURE

#define TEX_MAT_UID(pTxID, sTxID) ((boost::uint64_t(pTxID) << 32u) | sTxID)
#define TEX_TBL_UID(pIter, sIter) TEX_MAT_UID((pIter->second).texID, (sIter->second).texID)


// The S3O texture handler uses two textures.
// The first contains diffuse color (RGB) and teamcolor (A)
// The second contains glow (R), reflectivity (G) and 1-bit Alpha (A).

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CS3OTextureHandler* texturehandlerS3O = NULL;

CS3OTextureHandler::CS3OTextureHandler()
{
	// dummies
	textures.push_back(new S3OTexMat());
	textures.push_back(new S3OTexMat());
}

CS3OTextureHandler::~CS3OTextureHandler()
{
	for (int i = 0; i < textures.size(); ++i){
		glDeleteTextures(1, &textures[i]->tex1);
		glDeleteTextures(1, &textures[i]->tex2);
		delete textures[i];
	}
}

void CS3OTextureHandler::LoadS3OTexture(S3DModel* model) {
	model->textureType = LoadS3OTextureNow(model);
}

int CS3OTextureHandler::LoadS3OTextureNow(const S3DModel* model)
{
	LOG_L(L_INFO, "Load S3O texture now (Flip Y Axis: %s, Invert Team Alpha: %s)",
			model->invertTexYAxis ? "yes" : "no",
			model->invertTexAlpha ? "yes" : "no");

	CBitmap texBitMaps[2];
	TextureCacheIt texCacheIters[2] = {
		textureCache.find(model->tex1),
		textureCache.find(model->tex2),
	};
	TextureTableIt texTableIter;

	if (texCacheIters[0] == textureCache.end()) {
		if (!texBitMaps[0].Load(model->tex1)) {
			if (!texBitMaps[0].Load("unittextures/" + model->tex1)) {
				LOG_L(L_WARNING, "[%s] could not load texture \"%s\" from model \"%s\"",
					__FUNCTION__, model->tex1.c_str(), model->name.c_str());

				// file not found (or headless build), set single pixel to red so unit is visible
				texBitMaps[0].AllocDummy(SColor(255, 0, 0, 255));
			}
		}

		if (model->invertTexAlpha)
			texBitMaps[0].InvertAlpha();
		if (model->invertTexYAxis)
			texBitMaps[0].ReverseYAxis();

		textureCache[model->tex1] = {
			texBitMaps[0].CreateTexture(true),
			static_cast<unsigned int>(texBitMaps[0].xsize),
			static_cast<unsigned int>(texBitMaps[0].ysize)
		};
	}

	if (texCacheIters[1] == textureCache.end()) {
		if (!texBitMaps[1].Load(model->tex2)) {
			if (!texBitMaps[1].Load("unittextures/" + model->tex2)) {
				texBitMaps[1].AllocDummy(SColor(0, 0, 0, 255));
			}
		}

		if (model->invertTexYAxis)
			texBitMaps[1].ReverseYAxis();

		textureCache[model->tex2] = {
			texBitMaps[1].CreateTexture(true),
			static_cast<unsigned int>(texBitMaps[1].xsize),
			static_cast<unsigned int>(texBitMaps[1].ysize)
		};
	}

	if (texCacheIters[0] == textureCache.end() || texCacheIters[1] == textureCache.end()) {
		// at least one texture was newly loaded, create new material
		// (note: at this point the cache has grown to contain both)
		return (InsertTextureMat(model)->num);
	}
	if ((texTableIter = textureTable.find(TEX_TBL_UID(texCacheIters[0], texCacheIters[1]))) == textureTable.end()) {
		// both textures were already loaded as parts of other models
		// one possible example where this can happen would be e.g.:
		//   model 1 uses textures A and B and gets loaded 1st
		//   model 2 uses textures B and C and gets loaded 2nd
		//   model 3 uses textures A and C and gets loaded 3rd
		//   --> (A,C) is a new pair consisting of old textures
		return (InsertTextureMat(model)->num);
	}

	return ((texTableIter->second)->num);
}

CS3OTextureHandler::S3OTexMat* CS3OTextureHandler::InsertTextureMat(const S3DModel* model)
{
	const CachedS3OTex& tex1 = textureCache[model->tex1];
	const CachedS3OTex& tex2 = textureCache[model->tex2];

	S3OTexMat* texMat = new S3OTexMat();
	texMat->num       = textures.size();
	texMat->tex1      = tex1.texID;
	texMat->tex2      = tex2.texID;
	texMat->tex1SizeX = tex1.xsize;
	texMat->tex1SizeY = tex1.ysize;
	texMat->tex2SizeX = tex2.xsize;
	texMat->tex2SizeY = tex2.ysize;

	textures.push_back(texMat);
	textureTable[TEX_MAT_UID(texMat->tex1, texMat->tex2)] = texMat;

	return texMat;
}

inline void DoSetTexture(const CS3OTextureHandler::S3OTexMat* texMat) {
	if (shadowHandler->inShadowPass) {
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, texMat->tex2);
	} else {
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, texMat->tex2);
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, texMat->tex1);
	}
}


void CS3OTextureHandler::SetS3oTexture(int num)
{
	DoSetTexture(textures[num]);
}

void CS3OTextureHandler::UpdateDraw() {
}