summaryrefslogtreecommitdiff
path: root/src/engine/lightmap.h
blob: d15c6a7bf12eea46d56e230c6cb2ca478f6d8dbf (plain) (blame)
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
#define LM_MINW 2
#define LM_MINH 2
#define LM_MAXW 128
#define LM_MAXH 128
#define LM_PACKW 512
#define LM_PACKH 512

struct PackNode {
	PackNode *child1, *child2;
	ushort x, y, w, h;
	int available;
	PackNode() : child1(0), child2(0), x(0), y(0), w(LM_PACKW), h(LM_PACKH), available(min(LM_PACKW, LM_PACKH)) {}
	PackNode(ushort x, ushort y, ushort w, ushort h) : child1(0), child2(0), x(x), y(y), w(w), h(h), available(min(w, h)) {}
	void clear() {
		DELETEP(child1);
		DELETEP(child2);
	}
	~PackNode() {
		clear();
	}
	bool insert(ushort &tx, ushort &ty, ushort tw, ushort th);
};

enum {
	LM_DIFFUSE = 0,
	LM_BUMPMAP0,
	LM_BUMPMAP1,
	LM_TYPE = 0x0F,
	LM_ALPHA = 1<<4,
	LM_FLAGS = 0xF0
};

struct LightMap {
	int type, bpp, tex, offsetx, offsety;
	PackNode packroot;
	uint lightmaps, lumels;
	int unlitx, unlity;
	uchar *data;
	LightMap()
	 : type(LM_DIFFUSE), bpp(3), tex(-1), offsetx(-1), offsety(-1),
	   lightmaps(0), lumels(0), unlitx(-1), unlity(-1),
	   data(NULL) {
	}
	~LightMap() {
		if(data) delete[] data;
	}
	void finalize() {
		packroot.clear();
		packroot.available = 0;
	}
	void copy(ushort tx, ushort ty, uchar *src, ushort tw, ushort th);
	bool insert(ushort &tx, ushort &ty, uchar *src, ushort tw, ushort th);
};

extern vector<LightMap> lightmaps;

struct LightMapTexture {
	int w, h, type;
	GLuint id;
	int unlitx, unlity;
	LightMapTexture()
	 : w(0), h(0), type(LM_DIFFUSE), id(0), unlitx(-1), unlity(-1) {
	}
};

extern vector<LightMapTexture> lightmaptexs;

extern bvec ambientcolor;

extern void clearlights();
extern void initlights();
extern void lightents(bool force = false);
extern void clearlightcache(int id = -1);
extern void resetlightmaps(bool fullclean = true);
extern void brightencube(cube &c);
extern void setsurfaces(cube &c, const surfaceinfo *surfs, const vertinfo *verts, int numverts);
extern void setsurface(cube &c, int orient, const surfaceinfo &surf, const vertinfo *verts, int numverts);

struct lerpvert {
	vec normal;
	vec2 tc;
	bool operator==(const lerpvert &l) const { return tc == l.tc;; }
	bool operator!=(const lerpvert &l) const { return tc != l.tc; }
};

struct lerpbounds {
	const lerpvert *min;
	const lerpvert *max;
	float u, ustep;
	vec normal, nstep;
	int winding;
};

extern void calcnormals(bool lerptjoints = false);
extern void clearnormals();
extern void findnormal(const vec &key, const vec &surface, vec &v);
extern void calclerpverts(const vec2 *c, const vec *n, lerpvert *lv, int &numv);
extern void initlerpbounds(float u, float v, const lerpvert *lv, int numv, lerpbounds &start, lerpbounds &end);
extern void lerpnormal(float u, float v, const lerpvert *lv, int numv, lerpbounds &start, lerpbounds &end, vec &normal, vec &nstep);

#define CHECK_CALCLIGHT_PROGRESS_LOCKED(exit, show_calclight_progress, before, after) \
	if(check_calclight_progress) { \
	 \
		if(!calclight_canceled) { \
		 \
			before; \
			show_calclight_progress(); \
			check_calclight_canceled(); \
			after; \
		} \
		if(calclight_canceled) { exit; } \
	}
#define CHECK_CALCLIGHT_PROGRESS(exit, show_calclight_progress) CHECK_CALCLIGHT_PROGRESS_LOCKED(exit, show_calclight_progress, , )

extern bool calclight_canceled;
extern volatile bool check_calclight_progress;

extern void check_calclight_canceled();

extern int lightmapping;