1 /*
2 tile.h
3 Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4 */
5 
6 /*
7 This file is part of Freeminer.
8 
9 Freeminer is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Freeminer  is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Freeminer.  If not, see <http://www.gnu.org/licenses/>.
21 */
22 
23 #ifndef TILE_HEADER
24 #define TILE_HEADER
25 
26 #include "irrlichttypes.h"
27 #include "irr_v2d.h"
28 #include "irr_v3d.h"
29 #include <ITexture.h>
30 #include <IrrlichtDevice.h>
31 #include "threads.h"
32 #include <string>
33 #include <map>
34 
35 class IGameDef;
36 
37 /*
38 	tile.{h,cpp}: Texture handling stuff.
39 */
40 
41 /*
42 	Find out the full path of an image by trying different filename
43 	extensions.
44 
45 	If failed, return "".
46 
47 	TODO: Should probably be moved out from here, because things needing
48 	      this function do not need anything else from this header
49 */
50 std::string getImagePath(std::string path);
51 
52 /*
53 	Gets the path to a texture by first checking if the texture exists
54 	in texture_path and if not, using the data path.
55 
56 	Checks all supported extensions by replacing the original extension.
57 
58 	If not found, returns "".
59 
60 	Utilizes a thread-safe cache.
61 */
62 std::string getTexturePath(const std::string &filename);
63 
64 void clearTextureNameCache();
65 
66 /*
67 	ITextureSource::generateTextureFromMesh parameters
68 */
69 namespace irr {namespace scene {class IMesh;}}
70 struct TextureFromMeshParams
71 {
72 	scene::IMesh *mesh;
73 	core::dimension2d<u32> dim;
74 	std::string rtt_texture_name;
75 	bool delete_texture_on_shutdown;
76 	v3f camera_position;
77 	v3f camera_lookat;
78 	core::CMatrix4<f32> camera_projection_matrix;
79 	video::SColorf ambient_light;
80 	v3f light_position;
81 	video::SColorf light_color;
82 	f32 light_radius;
83 };
84 
85 /*
86 	Stores internal information about a texture.
87 */
88 struct TextureInfo
89 {
90 	std::string name;
91 	video::ITexture *texture;
92 	video::SColor color;
93 
94 	TextureInfo(
95 			const std::string &name_,
96 			video::ITexture *texture_=NULL,
97 			video::IImage *img=nullptr
98 		):
nameTextureInfo99 		name(name_),
100 		texture(texture_)
101 	{
102 		if(img!=NULL){
103 			color = img->getPixel(0,0); // TODO: avg here
104 		} else {
105 			color = video::SColor(0,0,0,0);
106 		}
107 	}
108 };
109 
110 /*
111 	TextureSource creates and caches textures.
112 */
113 
114 class ISimpleTextureSource
115 {
116 public:
ISimpleTextureSource()117 	ISimpleTextureSource(){}
~ISimpleTextureSource()118 	virtual ~ISimpleTextureSource(){}
119 	virtual video::ITexture* getTexture(
120 			const std::string &name, u32 *id = NULL) = 0;
121 };
122 
123 class ITextureSource : public ISimpleTextureSource
124 {
125 public:
ITextureSource()126 	ITextureSource(){}
~ITextureSource()127 	virtual ~ITextureSource(){}
128 	virtual u32 getTextureId(const std::string &name)=0;
129 	virtual std::string getTextureName(u32 id)=0;
130 	virtual video::ITexture* getTexture(u32 id)=0;
131 	virtual TextureInfo* getTextureInfo(u32 id)=0;
132 	virtual video::ITexture* getTexture(
133 			const std::string &name, u32 *id = NULL)=0;
134 	virtual IrrlichtDevice* getDevice()=0;
135 	virtual bool isKnownSourceImage(const std::string &name)=0;
136 	virtual video::ITexture* generateTextureFromMesh(
137 			const TextureFromMeshParams &params)=0;
138 	virtual video::ITexture* getNormalTexture(const std::string &name)=0;
139 };
140 
141 class IWritableTextureSource : public ITextureSource
142 {
143 public:
IWritableTextureSource()144 	IWritableTextureSource(){}
~IWritableTextureSource()145 	virtual ~IWritableTextureSource(){}
146 	virtual u32 getTextureId(const std::string &name)=0;
147 	virtual std::string getTextureName(u32 id)=0;
148 	virtual video::ITexture* getTexture(u32 id)=0;
149 	virtual video::ITexture* getTexture(
150 			const std::string &name, u32 *id = NULL)=0;
151 	virtual IrrlichtDevice* getDevice()=0;
152 	virtual bool isKnownSourceImage(const std::string &name)=0;
153 	virtual video::ITexture* generateTextureFromMesh(
154 			const TextureFromMeshParams &params)=0;
155 
156 	virtual void processQueue()=0;
157 	virtual void insertSourceImage(const std::string &name, video::IImage *img)=0;
158 	virtual void rebuildImagesAndTextures()=0;
159 	virtual video::ITexture* getNormalTexture(const std::string &name)=0;
160 };
161 
162 IWritableTextureSource* createTextureSource(IrrlichtDevice *device);
163 
164 #ifdef __ANDROID__
165 /**
166  * @param size get next npot2 value
167  * @return npot2 value
168  */
npot2(unsigned int size)169 inline unsigned int npot2(unsigned int size)
170 {
171 	if (size == 0) return 0;
172 	unsigned int npot = 1;
173 
174 	while ((size >>= 1) > 0) {
175 		npot <<= 1;
176 	}
177 	return npot;
178 }
179 
180 video::IImage * Align2Npot2(video::IImage * image, video::IVideoDriver* driver);
181 #endif
182 
183 enum MaterialType{
184 	TILE_MATERIAL_BASIC,
185 	TILE_MATERIAL_ALPHA,
186 	TILE_MATERIAL_LIQUID_TRANSPARENT,
187 	TILE_MATERIAL_LIQUID_OPAQUE,
188 	TILE_MATERIAL_WAVING_LEAVES,
189 	TILE_MATERIAL_WAVING_PLANTS
190 };
191 
192 // Material flags
193 // Should backface culling be enabled?
194 #define MATERIAL_FLAG_BACKFACE_CULLING 0x01
195 // Should a crack be drawn?
196 #define MATERIAL_FLAG_CRACK 0x02
197 // Should the crack be drawn on transparent pixels (unset) or not (set)?
198 // Ignored if MATERIAL_FLAG_CRACK is not set.
199 #define MATERIAL_FLAG_CRACK_OVERLAY 0x04
200 // Animation made up by splitting the texture to vertical frames, as
201 // defined by extra parameters
202 #define MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES 0x08
203 #define MATERIAL_FLAG_HIGHLIGHTED 0x10
204 
205 /*
206 	This fully defines the looks of a tile.
207 	The SMaterial of a tile is constructed according to this.
208 */
209 struct FrameSpec
210 {
FrameSpecFrameSpec211 	FrameSpec():
212 		texture_id(0),
213 		texture(NULL),
214 		normal_texture(NULL)
215 	{
216 	}
217 	u32 texture_id;
218 	video::ITexture *texture;
219 	video::ITexture *normal_texture;
220 };
221 
222 struct TileSpec
223 {
TileSpecTileSpec224 	TileSpec():
225 		texture_id(0),
226 		texture(NULL),
227 		normal_texture(NULL),
228 		alpha(255),
229 		material_type(TILE_MATERIAL_BASIC),
230 		material_flags(
231 			//0 // <- DEBUG, Use the one below
232 			MATERIAL_FLAG_BACKFACE_CULLING
233 		),
234 		shader_id(0),
235 		animation_frame_count(1),
236 		animation_frame_length_ms(0),
237 		rotation(0)
238 	{
239 	}
240 
241 	bool operator==(const TileSpec &other) const
242 	{
243 		return (
244 			texture_id == other.texture_id &&
245 			/* texture == other.texture && */
246 			alpha == other.alpha &&
247 			material_type == other.material_type &&
248 			material_flags == other.material_flags &&
249 			rotation == other.rotation
250 		);
251 	}
252 
253 	bool operator!=(const TileSpec &other) const
254 	{
255 		return !(*this == other);
256 	}
257 
258 	// Sets everything else except the texture in the material
applyMaterialOptionsTileSpec259 	void applyMaterialOptions(video::SMaterial &material) const
260 	{
261 		switch (material_type) {
262 		case TILE_MATERIAL_BASIC:
263 			material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
264 			break;
265 		case TILE_MATERIAL_ALPHA:
266 			material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
267 			break;
268 		case TILE_MATERIAL_LIQUID_TRANSPARENT:
269 			material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
270 			break;
271 		case TILE_MATERIAL_LIQUID_OPAQUE:
272 			material.MaterialType = video::EMT_SOLID;
273 			break;
274 		case TILE_MATERIAL_WAVING_LEAVES:
275 			material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
276 			break;
277 		case TILE_MATERIAL_WAVING_PLANTS:
278 			material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
279 			break;
280 		}
281 		material.BackfaceCulling = (material_flags & MATERIAL_FLAG_BACKFACE_CULLING)
282 			? true : false;
283 	}
284 
applyMaterialOptionsWithShadersTileSpec285 	void applyMaterialOptionsWithShaders(video::SMaterial &material) const
286 	{
287 		material.BackfaceCulling = (material_flags & MATERIAL_FLAG_BACKFACE_CULLING)
288 			? true : false;
289 	}
290 
291 	u32 texture_id;
292 	video::ITexture *texture;
293 	video::ITexture *normal_texture;
294 
295 	// Vertex alpha (when MATERIAL_ALPHA_VERTEX is used)
296 	u8 alpha;
297 	// Material parameters
298 	u8 material_type;
299 	u8 material_flags;
300 	u32 shader_id;
301 	// Animation parameters
302 	u8 animation_frame_count;
303 	u16 animation_frame_length_ms;
304 	std::map<u32, FrameSpec> frames;
305 
306 	u8 rotation;
307 };
308 
309 #endif
310