1 #ifndef __TREMAINMODEL_H__
2 #define __TREMAINMODEL_H__
3 
4 #include <TRE/TREModel.h>
5 #include <TCFoundation/TCImage.h>
6 #include <TCFoundation/TCStlIncludes.h>
7 
8 #ifdef USE_CPP11
9 #include <thread>
10 #include <mutex>
11 #include <condition_variable>
12 #include <vector>
13 #else
14 #if defined(_MSC_VER) && _MSC_VER <= 1200	// VS 6
15 #define _NO_TRE_THREADS
16 #else  // VS 6
17 #ifdef _NO_BOOST
18 #define _NO_TRE_THREADS
19 #endif // _NO_BOOST
20 #endif // VS 6
21 #ifndef _NO_TRE_THREADS
22 #ifdef WIN32
23 #pragma warning(push)
24 #pragma warning(disable:4244 4512)
25 #endif // WIN32
26 #include <boost/thread.hpp>
27 #include <boost/thread/condition.hpp>
28 #ifdef WIN32
29 #pragma warning(pop)
30 #endif // WIN32
31 #endif // !_NO_TRE_THREADS
32 #endif
33 
34 class TCDictionary;
35 class TREVertexStore;
36 class TREColoredShapeGroup;
37 class TRETransShapeGroup;
38 class TRETexmappedShapeGroup;
39 class TCImage;
40 
41 extern const GLfloat POLYGON_OFFSET_FACTOR;
42 extern const GLfloat POLYGON_OFFSET_UNITS;
43 
44 typedef std::list<TCVector> TCVectorList;
45 typedef std::list<TREMSection> SectionList;
46 
47 class TREMainModel : public TREModel
48 {
49 public:
50 	TREMainModel(void);
51 	//TREMainModel(const TREMainModel &other);
52 	virtual TCObject *copy(void) const;
53 	virtual TCDictionary* getLoadedModels(bool bfc);
54 	void draw(void);
getVertexStore(void)55 	virtual TREVertexStore *getVertexStore(void) { return m_vertexStore; }
getStudVertexStore(void)56 	virtual TREVertexStore *getStudVertexStore(void)
57 	{
58 		return m_studVertexStore;
59 	}
getColoredStudVertexStore(void)60 	virtual TREVertexStore *getColoredStudVertexStore(void)
61 	{
62 		return m_coloredStudVertexStore;
63 	}
64 	virtual TREModel *modelNamed(const char *name, bool bfc);
65 	virtual void registerModel(TREModel *model, bool bfc);
setCompilePartsFlag(bool value)66 	void setCompilePartsFlag(bool value) { m_mainFlags.compileParts = value; }
getCompilePartsFlag(void)67 	bool getCompilePartsFlag(void) const
68 	{
69 		return m_mainFlags.compileParts != false;
70 	}
setCompileAllFlag(bool value)71 	void setCompileAllFlag(bool value) { m_mainFlags.compileAll = value; }
getCompileAllFlag(void)72 	bool getCompileAllFlag(void) const
73 	{
74 		return m_mainFlags.compileAll != false;
75 	}
setFlattenConditionalsFlag(bool value)76 	void setFlattenConditionalsFlag(bool value)
77 	{
78 		m_mainFlags.flattenConditionals = value;
79 	}
getFlattenConditionalsFlag(void)80 	bool getFlattenConditionalsFlag(void) const
81 	{
82 		return m_mainFlags.flattenConditionals != false;
83 	}
setEdgeLinesFlag(bool value)84 	void setEdgeLinesFlag(bool value) { m_mainFlags.edgeLines = value; }
getEdgeLinesFlag(void)85 	bool getEdgeLinesFlag(void) { return m_mainFlags.edgeLines != false; }
setEdgesOnlyFlag(bool value)86 	void setEdgesOnlyFlag(bool value) { m_mainFlags.edgesOnly = value; }
getEdgesOnlyFlag(void)87 	bool getEdgesOnlyFlag(void)
88 	{
89 		return m_mainFlags.edgesOnly != false && getEdgeLinesFlag();
90 	}
91 	void setTwoSidedLightingFlag(bool value);
getTwoSidedLightingFlag(void)92 	bool getTwoSidedLightingFlag(void)
93 	{
94 		return m_mainFlags.twoSidedLighting != false;
95 	}
96 	void setLightingFlag(bool value);
getLightingFlag(void)97 	bool getLightingFlag(void) { return m_mainFlags.lighting != false; }
setUseStripsFlag(bool value)98 	void setUseStripsFlag(bool value) { m_mainFlags.useStrips = value; }
getUseStripsFlag(void)99 	bool getUseStripsFlag(void) { return m_mainFlags.useStrips != false; }
setDisableStrips(bool value)100 	void setDisableStrips(bool value) { m_mainFlags.disableStrips = value; }
getUseTriFansFlag(void)101 	bool getUseTriFansFlag(void)
102 	{
103 		return m_mainFlags.useStrips && !m_mainFlags.disableStrips &&
104 			m_mainFlags.useTriFans;
105 	}
getUseTriStripsFlag(void)106 	bool getUseTriStripsFlag(void)
107 	{
108 		return m_mainFlags.useStrips && !m_mainFlags.disableStrips &&
109 			m_mainFlags.useTriStrips;
110 	}
getUseQuadStripsFlag(void)111 	bool getUseQuadStripsFlag(void)
112 	{
113 		return m_mainFlags.useStrips && !m_mainFlags.disableStrips &&
114 			m_mainFlags.useQuadStrips;
115 	}
setUseFlatStripsFlag(bool value)116 	void setUseFlatStripsFlag(bool value) { m_mainFlags.useFlatStrips = value; }
getUseFlatStripsFlag(void)117 	bool getUseFlatStripsFlag(void)
118 	{
119 		return m_mainFlags.useFlatStrips != false;
120 	}
setBFCFlag(bool value)121 	void setBFCFlag(bool value) { m_mainFlags.bfc = value; }
getBFCFlag(void)122 	bool getBFCFlag(void) { return m_mainFlags.bfc != false; }
setRedBackFacesFlag(bool value)123 	void setRedBackFacesFlag(bool value) { m_mainFlags.redBackFaces = value; }
getRedBackFacesFlag(void)124 	bool getRedBackFacesFlag(void) { return m_mainFlags.redBackFaces != false; }
setGreenFrontFacesFlag(bool value)125 	void setGreenFrontFacesFlag(bool value)
126 	{
127 		m_mainFlags.greenFrontFaces = value;
128 	}
getGreenFrontFacesFlag(void)129 	bool getGreenFrontFacesFlag(void)
130 	{
131 		return m_mainFlags.greenFrontFaces != false;
132 	}
setBlueNeutralFacesFlag(bool value)133 	void setBlueNeutralFacesFlag(bool value)
134 	{
135 		m_mainFlags.blueNeutralFaces = value;
136 	}
getBlueNeutralFacesFlag(void)137 	bool getBlueNeutralFacesFlag(void)
138 	{
139 		return m_mainFlags.blueNeutralFaces != false &&
140 			m_mainFlags.bfc != false;
141 	}
setDrawNormalsFlag(bool value)142 	void setDrawNormalsFlag(bool value) { m_mainFlags.drawNormals = value; }
getDrawNormalsFlag(void)143 	bool getDrawNormalsFlag(void) { return m_mainFlags.drawNormals != false; }
setStencilConditionalsFlag(bool value)144 	void setStencilConditionalsFlag(bool value)
145 	{
146 		m_mainFlags.stencilConditionals = value;
147 	}
148 	bool getStencilConditionalsFlag(void);
setVertexArrayEdgeFlagsFlag(bool value)149 	void setVertexArrayEdgeFlagsFlag(bool value)
150 	{
151 		m_mainFlags.vertexArrayEdgeFlags = value;
152 	}
getVertexArrayEdgeFlagsFlag(void)153 	bool getVertexArrayEdgeFlagsFlag(void)
154 	{
155 		return m_mainFlags.vertexArrayEdgeFlags != false;
156 	}
setMultiThreadedFlag(bool value)157 	void setMultiThreadedFlag(bool value) { m_mainFlags.multiThreaded = value; }
getMultiThreadedFlag(void)158 	bool getMultiThreadedFlag(void) const
159 	{
160 		return m_mainFlags.multiThreaded != false;
161 	}
setSaveAlphaFlag(bool value)162 	void setSaveAlphaFlag(bool value) { m_mainFlags.saveAlpha = value; }
getSaveAlphaFlag(void)163 	bool getSaveAlphaFlag(void) { return m_mainFlags.saveAlpha != false; }
setGl2psFlag(bool value)164 	void setGl2psFlag(bool value) { m_mainFlags.gl2ps = value; }
getGl2psFlag(void)165 	bool getGl2psFlag(void) const { return m_mainFlags.gl2ps != false; }
setSendProgressFlag(bool value)166 	void setSendProgressFlag(bool value) { m_mainFlags.sendProgress = value; }
getSendProgressFlag(void)167 	bool getSendProgressFlag(void) const
168 	{
169 		return m_mainFlags.sendProgress != false;
170 	}
setLineJoinsFlag(bool value)171 	void setLineJoinsFlag(bool value) { m_mainFlags.lineJoins = value; }
getLineJoinsFlag(void)172 	bool getLineJoinsFlag(void) { return m_mainFlags.lineJoins != false; }
getActiveLineJoinsFlag(void)173 	bool getActiveLineJoinsFlag(void)
174 	{
175 		return m_mainFlags.activeLineJoins != false;
176 	}
setAALinesFlag(bool value)177 	void setAALinesFlag(bool value) { m_mainFlags.aaLines = value; }
getAALinesFlag(void)178 	bool getAALinesFlag(void) { return m_mainFlags.aaLines != false; }
setSortTransparentFlag(bool value)179 	void setSortTransparentFlag(bool value)
180 	{
181 		m_mainFlags.sortTransparent = value;
182 	}
getSortTransparentFlag(void)183 	bool getSortTransparentFlag(void)
184 	{
185 		return m_mainFlags.sortTransparent != false;
186 	}
setStippleFlag(bool value)187 	void setStippleFlag(bool value) { m_mainFlags.stipple = value; }
getStippleFlag(void)188 	bool getStippleFlag(void) { return m_mainFlags.stipple != false; }
setWireframeFlag(bool value)189 	void setWireframeFlag(bool value) { m_mainFlags.wireframe = value; }
getWireframeFlag(void)190 	bool getWireframeFlag(void) { return m_mainFlags.wireframe != false; }
setConditionalLinesFlag(bool value)191 	void setConditionalLinesFlag(bool value)
192 	{
193 		m_mainFlags.conditionalLines = value;
194 	}
getConditionalLinesFlag(void)195 	bool getConditionalLinesFlag(void)
196 	{
197 		return m_mainFlags.conditionalLines != false && getEdgeLinesFlag();
198 	}
setSmoothCurvesFlag(bool value)199 	void setSmoothCurvesFlag(bool value) { m_mainFlags.smoothCurves = value; }
getSmoothCurvesFlag(void)200 	bool getSmoothCurvesFlag(void) { return m_mainFlags.smoothCurves != false; }
201 	void setShowAllConditionalFlag(bool value);
getShowAllConditionalFlag(void)202 	bool getShowAllConditionalFlag(void)
203 	{
204 		return m_mainFlags.showAllConditional != false &&
205 			getConditionalLinesFlag();
206 	}
207 	void setConditionalControlPointsFlag(bool value);
getConditionalControlPointsFlag(void)208 	bool getConditionalControlPointsFlag(void)
209 	{
210 		return m_mainFlags.conditionalControlPoints != false &&
211 			getConditionalLinesFlag();
212 	}
setPolygonOffsetFlag(bool value)213 	void setPolygonOffsetFlag(bool value)
214 	{
215 		m_mainFlags.polygonOffset = value;
216 	}
getPolygonOffsetFlag(void)217 	bool getPolygonOffsetFlag(void)
218 	{
219 		return m_mainFlags.polygonOffset != false;
220 	}
setStudLogoFlag(bool value)221 	void setStudLogoFlag(bool value) { m_mainFlags.studLogo = value; }
getStudLogoFlag(void)222 	bool getStudLogoFlag(void) { return m_mainFlags.studLogo != false; }
setRemovingHiddenLines(bool value)223 	void setRemovingHiddenLines(bool value)
224 	{
225 		m_mainFlags.removingHiddenLines = value;
226 	}
getRemovingHiddenLines(void)227 	bool getRemovingHiddenLines(void)
228 	{
229 		return m_mainFlags.removingHiddenLines != false;
230 	}
setCutawayDrawFlag(bool value)231 	void setCutawayDrawFlag(bool value) { m_mainFlags.cutawayDraw = value; }
getCutawayDrawFlag(void)232 	bool getCutawayDrawFlag(void) { return m_mainFlags.cutawayDraw != false; }
setEdgeLineWidth(GLfloat value)233 	void setEdgeLineWidth(GLfloat value) { m_edgeLineWidth = value; }
getEdgeLineWidth(void)234 	TCFloat getEdgeLineWidth(void) { return m_edgeLineWidth; }
setStudAnisoLevel(GLfloat value)235 	void setStudAnisoLevel(GLfloat value) { m_studAnisoLevel = value; }
getStudAnisoLevel(void)236 	TCFloat getStudAnisoLevel(void) { return m_studAnisoLevel; }
setStudTextureFilter(int value)237 	void setStudTextureFilter(int value) { m_studTextureFilter = value; }
getStudTextureFilter(void)238 	int getStudTextureFilter(void) { return m_studTextureFilter; }
getCompiled(void)239 	virtual bool getCompiled(void) const
240 	{
241 		return m_mainFlags.compiled != false;
242 	}
getCompiling(void)243 	virtual bool getCompiling(void) { return m_mainFlags.compiling != false; }
setTextureOffsetFactor(TCFloat value)244 	void setTextureOffsetFactor(TCFloat value)
245 	{
246 		m_textureOffsetFactor = value;
247 	}
getTextureOffsetFactor(void)248 	TCFloat getTextureOffsetFactor(void) const { return m_textureOffsetFactor; }
249 	virtual TCFloat getMaxRadiusSquared(const TCVector &center);
250 	virtual TCFloat getMaxRadius(const TCVector &center);
getColoredVertexStore(void)251 	TREVertexStore *getColoredVertexStore(void)
252 	{
253 		return m_coloredVertexStore;
254 	}
getTransVertexStore(void)255 	TREVertexStore *getTransVertexStore(void)
256 	{
257 		return m_transVertexStore;
258 	}
259 	void setColor(TCULong color, TCULong edgeColor);
260 	TCULong getColor(void);
261 	TCULong getEdgeColor(void);
262 	bool postProcess(void);
263 	void compile(void);
264 	void recompile(void);
265 	virtual void addTransferTriangle(TREShapeGroup::TRESTransferType type,
266 		TCULong color, const TCVector vertices[], const TCVector normals[],
267 		bool bfc, const TCVector *textureCoords, const TCFloat *matrix);
268 	virtual bool shouldLoadConditionalLines(void);
isStudSection(TREMSection section)269 	bool isStudSection(TREMSection section)
270 	{
271 		return section == TREMStud || section == TREMStudBFC;
272 	}
273 	virtual void openGlWillEnd(void);
274 	virtual void finish(void);
275 	virtual void addLight(const TCVector &location, TCULong color);
getLightLocations(void)276 	virtual const TCVectorList &getLightLocations(void) const
277 	{
278 		return m_lightLocations;
279 	}
getLightColors(void)280 	virtual const TCULongList &getLightColors(void) const
281 	{
282 		return m_lightColors;
283 	}
getCurrentModelViewMatrix(void)284 	const TCFloat *getCurrentModelViewMatrix(void) const
285 	{
286 		return m_currentModelViewMatrix;
287 	}
getCurrentProjectionMatrix(void)288 	const TCFloat *getCurrentProjectionMatrix(void) const
289 	{
290 		return m_currentProjectionMatrix;
291 	}
292 	bool hasWorkerThreads(void);
293 	void waitForSort(void);
294 	void waitForConditionals(int step);
getActiveConditionals(int step)295 	const TCULongArray *getActiveConditionals(int step) const
296 	{
297 		return m_activeConditionals[step];
298 	}
getActiveColorConditionals(int step)299 	const TCULongArray *getActiveColorConditionals(int step) const
300 	{
301 		return m_activeColorConditionals[step];
302 	}
303 	bool doingBackgroundConditionals(void);
getAlertSender(void)304 	virtual TCObject *getAlertSender(void) { return m_alertSender; }
setAlertSender(TCObject * value)305 	virtual void setAlertSender(TCObject *value) { m_alertSender = value; }
getStep(void)306 	int getStep(void) const { return m_step; }
307 	void setStep(int value);
getNumSteps(void)308 	int getNumSteps(void) const { return m_numSteps; }
309 	void transferPrep(void);
310 	void updateModelTransferStep(int subModelIndex,
311 		bool isConditionals = false);
312 	bool onLastStep(void);
313 	virtual void nextStep(void);
314 
315 	virtual void addLine(const TCVector *vertices);
316 	virtual void addLine(TCULong color, const TCVector *vertices);
317 	virtual void addEdgeLine(const TCVector *vertices, TCULong color = 0);
318 	virtual void addTriangle(const TCVector *vertices);
319 	virtual void addTriangle(const TCVector *vertices,
320 		const TCVector *normals);
321 	virtual void addTriangle(TCULong color, const TCVector *vertices);
322 	virtual void addTriangle(TCULong color, const TCVector *vertices,
323 		const TCVector *normals);
324 	virtual void addBFCTriangle(const TCVector *vertices);
325 	virtual void addBFCTriangle(const TCVector *vertices,
326 		const TCVector *normals);
327 	virtual void addBFCTriangle(TCULong color, const TCVector *vertices);
328 	virtual void addBFCTriangle(TCULong color, const TCVector *vertices,
329 		const TCVector *normals);
330 	virtual void addQuad(const TCVector *vertices);
331 	virtual void addQuad(TCULong color, const TCVector *vertices);
332 	virtual void addBFCQuad(const TCVector *vertices);
333 	virtual void addBFCQuad(TCULong color, const TCVector *vertices);
334 	virtual void addConditionalLine(const TCVector *vertices,
335 		const TCVector *controlPoints, TCULong color = 0);
336 	virtual void addTriangleStrip(const TCVector *vertices,
337 		const TCVector *normals, int count, bool flat = false);
338 	virtual void addTriangleStrip(TREShapeGroup *shapeGroup,
339 		const TCVector *vertices, const TCVector *normals, int count,
340 		bool flat = false);
341 	virtual void addBFCTriangleStrip(const TCVector *vertices,
342 		const TCVector *normals, int count, bool flat = false);
343 	virtual void addTriangleFan(const TCVector *vertices,
344 		const TCVector *normals, const TCVector *textureCoords, int count,
345 		bool flat = false);
346 	virtual void addTriangleFan(TCULong color, const TCVector *vertices,
347 		const TCVector *normals, int count, bool flat = false);
348 	virtual void addTriangleFan(TREShapeGroup *shapeGroup,
349 		const TCVector *vertices, const TCVector *normals,
350 		const TCVector *textureCoords, int count, bool flat = false);
351 	virtual void addTriangleFan(TREColoredShapeGroup *shapeGroup, TCULong color,
352 		const TCVector *vertices, const TCVector *normals, int count,
353 		bool flat = false);
354 	virtual void addBFCTriangleFan(const TCVector *vertices,
355 		const TCVector *normals, const TCVector *textureCoords, int count,
356 		bool flat = false);
357 	virtual void addBFCTriangleFan(TCULong color, const TCVector *vertices,
358 		const TCVector *normals, int count, bool flat = false);
359 	virtual void addQuadStrip(const TCVector *vertices, const TCVector *normals,
360 		int count, bool flat = false);
361 	virtual void addQuadStrip(TREShapeGroup *shapeGroup,
362 		const TCVector *vertices, const TCVector *normals, int count,
363 		bool flat);
364 	virtual void addQuadStrip(TCULong color, const TCVector *vertices,
365 		const TCVector *normals, int count, bool flat = false);
366 	virtual void addQuadStrip(TREColoredShapeGroup *shapeGroup, TCULong color,
367 		const TCVector *vertices, const TCVector *normals, int count,
368 		bool flat = false);
369 	virtual void addBFCQuadStrip(const TCVector *vertices,
370 		const TCVector *normals, int count, bool flat = false);
371 	virtual void addBFCQuadStrip(TCULong color, const TCVector *vertices,
372 		const TCVector *normals, int count, bool flat = false);
373 	void loadTexture(const std::string &filename, TCImage *image);
374 	void startTexture(const std::string &filename, TCImage *image);
375 	bool endTexture(void);
376 	const std::string *getActiveTextureFilename(void) const;
377 	GLuint getTexmapTextureID(const std::string &filename) const;
378 	const TCImage *getTexmapImage(const std::string &filename) const;
379 	virtual void startTexture(int type, const std::string &filename,
380 		TCImage *image, const TCVector *points, const TCFloat *extra);
381 	void setTransferTexmapInfo(const TexmapInfo &texmapInfo, bool bfc,
382 		const TCFloat *matrix);
setModelTexmapTransferFlag(bool value)383 	void setModelTexmapTransferFlag(bool value)
384 	{
385 		m_mainFlags.modelTexmapTransfer = value;
386 	}
getModelTexmapTransferFlag(void)387 	bool getModelTexmapTransferFlag(void) const
388 	{
389 		return m_mainFlags.modelTexmapTransfer != false;
390 	}
setFlattenPartsFlag(bool value)391 	void setFlattenPartsFlag(bool value) { m_mainFlags.flattenParts = value; }
getFlattenPartsFlag(void)392 	bool getFlattenPartsFlag(void) const
393 	{
394 		return m_mainFlags.flattenParts != false;
395 	}
setTexturesAfterTransparentFlag(bool value)396 	void setTexturesAfterTransparentFlag(bool value) { m_mainFlags.texturesAfterTransparent = value; }
getTexturesAfterTransparentFlag(void)397 	bool getTexturesAfterTransparentFlag(void) const
398 	{
399 		return m_mainFlags.texturesAfterTransparent != false;
400 	}
setNoDepthEdgeLinesFlag(bool value)401 	void setNoDepthEdgeLinesFlag(bool value) { m_mainFlags.noDepthEdgeLines = value; }
getNoDepthEdgeLinesFlag(void)402 	bool getNoDepthEdgeLinesFlag(void) const
403 	{
404 		return m_mainFlags.noDepthEdgeLines != false;
405 	}
setSeamWidth(TCFloat value)406 	void setSeamWidth(TCFloat value) { m_seamWidth = value; }
getSeamWidth(void)407 	TCFloat getSeamWidth(void) const { return m_seamWidth; }
getTexClampMode(void)408 	GLint getTexClampMode(void) const { return m_texClampMode; }
409 
410 	static void loadStudTexture(const char *filename);
411 	static void setStudTextureData(TCByte *data, long length);
412 	static void setRawStudTextureData(TCByte *data, long length);
getStudTextures(void)413 	static TCImageArray *getStudTextures(void) { return sm_studTextures; }
getStudTextureID(void)414 	static unsigned getStudTextureID(void) { return sm_studTextureID; }
415 protected:
416 	typedef enum
417 	{
418 		TPOPMain,
419 		TPOPTransparent,
420 		TPOPTexmaps
421 	} TREPolygonOffsetPurpose;
422 	GLfloat getPolygonOffsetFactor(TREPolygonOffsetPurpose purpose);
423 	void populateTrianglesMap(TRETexmappedShapeGroup *shapeGroup,
424 		TRETrianglesMap &triangles);
425 	void transferSmoothNormals(const TRETrianglesMap triangles[]);
426 	void transferSmoothNormals(const TRETrianglesMap triangles[],
427 		TREModel *model, const TCFloat *matrix);
428 	void transferSmoothNormals(const TRETrianglesMap &triangles,
429 		TREShapeGroup *shapeGroup, const TCFloat *matrix);
430 	void transferSmoothNormals(const TRETrianglesMap &triangles,
431 		TREShapeGroup *shapeGroup, TREShapeType shapeType,
432 		int shapeSize, const TCFloat *matrix);
433 	bool transferSmoothNormals(
434 		const TRETrianglesMap &triangles,
435 		TREVertexStore *vertexStore,
436 		TCULongArray *indices,
437 		TREVertexStore *dstVertexStore,
438 		TCULongArray *dstIndices,
439 		int i0,
440 		int i1,
441 		int i2,
442 		const TCFloat *matrix);
443 
444 	struct TexmapImageInfo
445 	{
TexmapImageInfoTexmapImageInfo446 		TexmapImageInfo(void) : image(NULL) {}
TexmapImageInfoTexmapImageInfo447 		TexmapImageInfo(const std::string &filename, TCImage *image)
448 			: filename(filename)
449 			, image(TCObject::retain(image))
450 			, textureID(0)
451 		{}
TexmapImageInfoTexmapImageInfo452 		TexmapImageInfo(const TexmapImageInfo &other)
453 			: filename(other.filename)
454 			, image(TCObject::retain(other.image))
455 			, textureID(other.textureID)
456 		{}
457 		TexmapImageInfo &operator=(const TexmapImageInfo &other)
458 		{
459 			filename = other.filename;
460 			image = TCObject::retain(other.image);
461 			textureID = other.textureID;
462 			return *this;
463 		}
~TexmapImageInfoTexmapImageInfo464 		~TexmapImageInfo()
465 		{
466 			TCObject::release(image);
467 		}
468 		std::string filename;
469 		TCImage *image;
470 		GLuint textureID;
471 	};
472 	typedef std::map<std::string, TexmapImageInfo> TexmapImageInfoMap;
473 	virtual ~TREMainModel(void);
474 	virtual void dealloc(void);
475 	void scanMaxRadiusSquaredPoint(const TCVector &point);
476 	virtual void activateBFC(void);
477 	virtual void deactivateBFC(bool transparent = false);
478 	void transferTransparent(void);
479 	virtual void transferTransparent(const SectionList &sectionList);
480 	void transferTexmapped(void);
481 	virtual void transferTexmapped(const SectionList &sectionList);
482 	virtual void drawTransparent(int pass = -1);
483 	virtual void drawLines(int pass = -1);
484 	virtual void drawSolid(void);
485 	virtual void enableLineSmooth(int pass = -1);
486 	virtual void bindStudTexture(void);
487 	void bindTexmaps(void);
488 	void configTexmaps(void);
489 	void configTextureFilters(void);
490 	void deleteGLTexmaps(void);
491 	virtual void configureStudTexture(bool allowMipMap = true);
492 	virtual bool shouldCompileSection(TREMSection section);
493 	virtual void passOnePrep(void);
494 	virtual void passTwoPrep(void);
495 	virtual void passThreePrep(void);
496 #if defined(USE_CPP11) || !defined(_NO_TRE_THREADS)
497 	template <class _ScopedLock> bool workerThreadDoWork(_ScopedLock &lock);
498 	template <class _ScopedLock> void nextConditionalsStep(_ScopedLock &lock);
499 	void workerThreadProc(void);
500 #endif // USE_CPP11 || !_NO_TRE_THREADS
501 	void launchWorkerThreads(void);
502 	int getNumWorkerThreads(void);
503 	int getNumBackgroundTasks(void);
504 	void triggerWorkerThreads(void);
505 	bool backgroundSortNeeded(void);
506 	bool backgroundConditionalsNeeded(void);
507 	void flattenConditionals(void);
508 	void backgroundConditionals(int step);
509 	TCULongArray *backgroundConditionals(TREShapeGroup *shapes, int step);
510 	TREModel *getCurGeomModel(void);
511 	void drawTexmapped(bool transparent);
512 	void drawTexmappedInternal(bool texture, bool colorMaterialOff,
513 		bool transparent);
514 
515 	void enable(GLenum cap);
516 	void disable(GLenum cap);
517 	void blendFunc(GLenum sfactor, GLenum dfactor);
518 	void lineWidth(GLfloat width);
519 	void pointSize(GLfloat size);
520 
521 	static void loadStudMipTextures(TCImage *mainImage);
522 
523 	TCObject *m_alertSender;
524 	TCDictionary *m_loadedModels;
525 	TCDictionary *m_loadedBFCModels;
526 	TREVertexStore *m_vertexStore;
527 	TREVertexStore *m_studVertexStore;
528 	TREVertexStore *m_coloredVertexStore;
529 	TREVertexStore *m_coloredStudVertexStore;
530 	TREVertexStore *m_transVertexStore;
531 	TREVertexStore *m_texmapVertexStore;
532 	TCULong m_color;
533 	TCULong m_edgeColor;
534 	TCFloat m_maxRadiusSquared;
535 	TCFloat m_textureOffsetFactor;
536 	TCVector m_center;
537 	GLfloat m_edgeLineWidth;
538 	GLfloat m_studAnisoLevel;
539 	bool m_abort;	// Easier not to be a bit field.  A pointer to it is passed
540 					// into other functions, and that doesn't work with a bit
541 					// field.
542 	GLint m_studTextureFilter;
543 	TCVectorList m_lightLocations;
544 	TCULongList m_lightColors;
545 	TCFloat m_currentModelViewMatrix[16];
546 	TCFloat m_currentProjectionMatrix[16];
547 	TCULong m_conditionalsDone;
548 	int m_conditionalsStep;
549 	TCULongArray *m_activeConditionals[32];
550 	TCULongArray *m_activeColorConditionals[32];
551 	int m_step;
552 	int m_numSteps;
553 	int m_transferStep;
554 	IntVector m_transStepCounts;
555 	IntVector m_texmappedStepCounts[3];
556 	TREModel *m_curGeomModel;
557 	TexmapImageInfoMap m_texmapImages;
558 	StringList m_activeTextures;
559 	TRETexmappedShapeGroup *m_texmappedShapes[3];
560 	TexmapInfoList m_mainTexmapInfos;
561 	GLint m_texClampMode;
562 	TCFloat m_seamWidth;
563 #if defined(USE_CPP11) || !defined(_NO_TRE_THREADS)
564 #ifdef USE_CPP11
565     std::vector<std::thread> *m_threads;
566 	std::mutex *m_workerMutex;
567 	std::condition_variable *m_workerCondition;
568 	std::condition_variable *m_sortCondition;
569 	std::condition_variable *m_conditionalsCondition;
570 #else
571 	boost::thread_group *m_threadGroup;
572 	boost::mutex *m_workerMutex;
573 	boost::condition *m_workerCondition;
574 	boost::condition *m_sortCondition;
575 	boost::condition *m_conditionalsCondition;
576 #endif
577 	bool m_exiting;
578 #endif // USE_CPP11 || !_NO_TRE_THREADS
579 	struct
580 	{
581 		// The following are temporal
582 		bool compiling:1;
583 		bool compiled:1;
584 		bool removingHiddenLines:1;	// This one is changed externally
585 		bool cutawayDraw:1;			// This one is changed externally
586 		bool activeLineJoins:1;
587 		bool frameSorted:1;
588 		bool frameSortStarted:1;
589 		bool frameStarted:1;
590 		// The following aren't temporal
591 		bool compileParts:1;
592 		bool compileAll:1;
593 		bool flattenConditionals:1;
594 		bool edgeLines:1;
595 		bool edgesOnly:1;
596 		bool twoSidedLighting:1;
597 		bool lighting:1;
598 		bool useStrips:1;
599 		bool disableStrips:1;
600 		bool useTriStrips:1;
601 		bool useTriFans:1;
602 		bool useQuadStrips:1;
603 		bool useFlatStrips:1;
604 		bool bfc:1;
605 		bool aaLines:1;
606 		bool sortTransparent:1;
607 		bool stipple:1;
608 		bool wireframe:1;
609 		bool conditionalLines:1;
610 		bool smoothCurves:1;
611 		bool showAllConditional:1;
612 		bool conditionalControlPoints:1;
613 		bool polygonOffset:1;
614 		bool studLogo:1;
615 		bool redBackFaces:1;
616 		bool greenFrontFaces:1;
617 		bool blueNeutralFaces:1;
618 		bool lineJoins:1;
619 		bool drawNormals:1;
620 		bool stencilConditionals:1;
621 		bool vertexArrayEdgeFlags:1;
622 		bool multiThreaded:1;
623 		bool saveAlpha:1;
624 		bool gl2ps:1;
625 		bool sendProgress:1;
626 		bool modelTexmapTransfer:1;
627 		bool flattenParts:1;
628 		bool texturesAfterTransparent:1;
629 		bool noDepthEdgeLines:1;
630 	} m_mainFlags;
631 
632 	static TCImageArray *sm_studTextures;
633 	static GLuint sm_studTextureID;
634 	static class TREMainModelCleanup
635 	{
636 	public:
637 		~TREMainModelCleanup(void);
638 	} sm_mainModelCleanup;
639 	friend class TREMainModelCleanup;
640 };
641 
642 #endif // __TREMAINMODEL_H__
643