summary refs log tree commit diff
path: root/src/Decals.cpp
blob: 1522053bb7b38f0aeff84b5345f833cac18c1e61 (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
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
#include <cmath>

#include "Camera.h"
#include "Constants.h"
#include "Decals.h"
#include "Fog.h"

extern float multiplier;
extern bool slomo;
extern Fog fog;
extern bool blood;
extern float fogcolorr;
extern float fogcolorg;
extern float fogcolorb;
//Functions
extern float sinefluct;
extern int environment;
extern Model gunmodels[10];
extern Camera camera;
extern float precipitationhorz;
extern float precipitationvert;
extern float precipitationdensity;
extern float snowdelay;

int Decals::MakeDecal(int atype, XYZ location, float size, XYZ normal, int poly, Model *model, XYZ move, float rotation){
	int major=0;
	float normalv[3];
	XYZ right;
	XYZ up;
	XYZ nothing;
	XYZ axis[3];
	XYZ temp;

	nothing = {};

	axis[0].x=1;
	axis[1].y=1;
	axis[2].z=1;

	normalv[0]=abs(normal.x);
	normalv[1]=abs(normal.y);
	normalv[2]=abs(normal.z);

	if(normalv[1]>normalv[major])major=1;
	if(normalv[2]>normalv[major])major=2;

	if (normalv[0] == 1 || normalv[1] == 1 || normalv[2] == 1) {
		if (major == 0 && normal.x > 0 || major == 1)
			right = {0.0f, 0.0f, -1.0f};
		else if (major == 0)
			right = {0.0f, 0.0f, 1.0f};
		else if (major == 0)
			right = {normal.z, 0.0f, 0.0f};
	} else {
		CrossProduct(axis[major], normal, &right);
	}

    CrossProduct(normal, right, &up);
    Normalise(&up);
    Normalise(&right);

	float count;
	float count2;
	float countinc=1/size;
	if(countinc<.01)countinc=.01;
	if(countinc>.2)countinc=.2;
	float normaloffset=.02;
	int good;

	numpoints[howmanydecals]=0;
    points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right - up) * (size/3) /*+ normal/100*/;
    texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 0;
    texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 0;
    if((move.x==0&&move.z==0&&rotation==0)||
    LineFacetd(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25, model->vertex[model->Triangles[poly].vertex[0]], model->vertex[model->Triangles[poly].vertex[1]], model->vertex[model->Triangles[poly].vertex[2]],normal,&temp)
    )numpoints[howmanydecals]++;
    else {
    	good=-1;
    	count=1-countinc;
    	while(good==-1&&count>-1){
    		texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 0;
    		texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5-count/2;
    		points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right - up*count) * (size/3);
    		count-=countinc;
    		good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation);
    	}
    	if(good!=-1)numpoints[howmanydecals]++;
    	good=-1;
    	count=1-countinc;
    	while(good==-1&&count>-1){
    		texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5-count/2;
    		texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 0;
    		points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right*count - up) * (size/3);
    		count-=countinc;
    		good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation);
    	}
    	if(good!=-1)numpoints[howmanydecals]++;
    	if(good==-1){
    		good=-1;
	    	count2=1-countinc;
	    	while(good==-1&&count2>-1){
	    		count=1-countinc;
		    	while(good==-1&&count>-1){
		    		texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5-count2/2;
		    		texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5-count/2;
		    		points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right*count2 - up*count) * (size/3);
		    		count-=countinc;
		    		good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation);
		    	}
		    	count2-=countinc;
		    }
	    	if(good!=-1)numpoints[howmanydecals]++;
    	}
    }

    points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right - up) * (size/3) /*+ normal/100*/;
    texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 1;
    texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 0;
    if((move.x==0&&move.y==0&&move.z==0&&rotation==0)||
    LineFacetd(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25, model->vertex[model->Triangles[poly].vertex[0]], model->vertex[model->Triangles[poly].vertex[1]], model->vertex[model->Triangles[poly].vertex[2]],normal,&temp)
    )numpoints[howmanydecals]++;
    else {
    	good=-1;
    	count=1-countinc;
    	while(good==-1&&count>-1){
    		texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5+count/2;
    		texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 0;
    		points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right*count - up) * (size/3);
    		count-=countinc;
    		good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation);
    	}
    	if(good!=-1)numpoints[howmanydecals]++;
    	good=-1;
    	count=1-countinc;
    	while(good==-1&&count>-1){
    		texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 1;
    		texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5-count/2;
    		points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right - up*count) * (size/3);
    		count-=countinc;
    		good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation);
    	}
    	if(good!=-1)numpoints[howmanydecals]++;
    	if(good==-1){
    		good=-1;
	    	count2=1-countinc;
	    	while(good==-1&&count2>-1){
	    		count=1-countinc;
		    	while(good==-1&&count>-1){
		    		texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5+count2/2;
		    		texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5-count/2;
		    		points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right*count2 - up*count) * (size/3);
		    		count-=countinc;
		    		good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation);
		    	}
		    	count2-=countinc;
		    }
	    	if(good!=-1)numpoints[howmanydecals]++;
    	}
    }

    points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right + up) * (size/3) /*+ normal/100*/;
    texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 1;
    texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 1;
    if((move.x==0&&move.y==0&&move.z==0&&rotation==0)||
    LineFacetd(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25, model->vertex[model->Triangles[poly].vertex[0]], model->vertex[model->Triangles[poly].vertex[1]], model->vertex[model->Triangles[poly].vertex[2]],normal,&temp)
    )numpoints[howmanydecals]++;
    else {
    	good=-1;
    	count=1-countinc;
    	while(good==-1&&count>-1){
    		texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 1;
    		texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5+count/2;
    		points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right + up*count) * (size/3);
    		count-=countinc;
    		good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation);
    	}
    	if(good!=-1)numpoints[howmanydecals]++;
    	good=-1;
    	count=1-countinc;
    	while(good==-1&&count>-1){
    		texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5+count/2;
    		texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 1;
    		points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right*count + up) * (size/3);
    		count-=countinc;
    		good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation);
    	}
    	if(good!=-1)numpoints[howmanydecals]++;
    	if(good==-1){
    		good=-1;
	    	count2=1-countinc;
	    	while(good==-1&&count2>-1){
	    		count=1-countinc;
		    	while(good==-1&&count>-1){
		    		texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5+count2/2;
		    		texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5+count/2;
		    		points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right*count2 + up*count) * (size/3);
		    		count-=countinc;
		    		good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation);
		    	}
		    	count2-=countinc;
		    }
	    	if(good!=-1)numpoints[howmanydecals]++;
    	}
    }

    points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right + up) * (size/3) /*+ normal/100*/;
	texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 0;
    texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 1;
    if((move.x==0&&move.y==0&&move.z==0&&rotation==0)||
    LineFacetd(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25, model->vertex[model->Triangles[poly].vertex[0]], model->vertex[model->Triangles[poly].vertex[1]], model->vertex[model->Triangles[poly].vertex[2]],normal,&temp)
    )numpoints[howmanydecals]++;
    else {
    	good=-1;
    	count=1-countinc;
    	while(good==-1&&count>-1){
    		texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5-count/2;
    		texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 1;
    		points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right*count + up) * (size/3);
    		count-=countinc;
    		good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation);
    	}
    	if(good!=-1)numpoints[howmanydecals]++;
    	good=-1;
    	count=1-countinc;
    	while(good==-1&&count>-1){
    		texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 0;
    		texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5+count/2;
    		points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right + up*count) * (size/3);
    		count-=countinc;
    		good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation);
    	}
    	if(good!=-1)numpoints[howmanydecals]++;
    	if(good==-1){
    		good=-1;
	    	count2=1-countinc;
	    	while(good==-1&&count2>-1){
	    		count=1-countinc;
		    	while(good==-1&&count>-1){
		    		texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5-count2/2;
		    		texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5+count/2;
		    		points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right*count2 + up*count) * (size/3);
		    		count-=countinc;
		    		good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation);
		    	}
		    	count2-=countinc;
		    }
	    	if(good!=-1)numpoints[howmanydecals]++;
    	}
    }
    for(int i=0;i<numpoints[howmanydecals];i++){
    	 points[howmanydecals*8+i] += normal*normaloffset;
    }

    type[howmanydecals]=atype;
	alivetime[howmanydecals]=0;
	if(howmanydecals<maxdecals){howmanydecals++;}

	return 0;
}

int Decals::DeleteDecal(int which){
	if(which>=0){
		numpoints[which]=numpoints[howmanydecals-1];
		alivetime[which]=alivetime[howmanydecals-1];
		type[which]=type[howmanydecals-1];
		for(int i=0;i<numpoints[which];i++){
			points[which*8+i] = points[howmanydecals*8-8+i];
		    texcoordsx[which*8+i] = texcoordsx[howmanydecals*8-8+i];
		    texcoordsy[which*8+i] = texcoordsy[howmanydecals*8-8+i];
	    }
		if(howmanydecals>0){howmanydecals--;}
	}

	return 0;
}

void Decals::DoStuff()
{
	for(int i=0;i<howmanydecals;i++){
		alivetime[i]+=multiplier;
		if(alivetime[i]>10&&(type[i]==bullethole||type[i]==crater))DeleteDecal(i);
		if(alivetime[i]>20&&(type[i]==bloodpool))DeleteDecal(i);
	}
}

void Decals::draw()
{
	glAlphaFunc(GL_GREATER, 0.01);

	float bloodpoolspeed=1;

	glDepthFunc(GL_LEQUAL);
	glEnable(GL_BLEND);
	glEnable(GL_CULL_FACE);
	glEnable(GL_TEXTURE_2D);
	glEnable(GL_LIGHTING);
	glDepthMask(0);
	glAlphaFunc(GL_GREATER, 0.01);
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
	glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
	glEnable(GL_POLYGON_OFFSET_FILL);
	for(int i=0;i<howmanydecals;i++){
		if(type[i]==bullethole)glBindTexture(GL_TEXTURE_2D, bulletholetextureptr);
		if(type[i]==crater)glBindTexture(GL_TEXTURE_2D, cratertextureptr);
		if(type[i]!=bloodpool)glColor4f(1,1,1,10-alivetime[i]);

		if(type[i]==bloodpool&&alivetime[i]<bloodpoolspeed*.2)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[0]);
		if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*.2&&alivetime[i]<bloodpoolspeed*.4)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[1]);
		if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*.4&&alivetime[i]<bloodpoolspeed*.6)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[2]);
		if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*.6&&alivetime[i]<bloodpoolspeed*.8)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[3]);
		if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*.8&&alivetime[i]<bloodpoolspeed*1)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[4]);
		if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1&&alivetime[i]<bloodpoolspeed*1.2)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[5]);
		if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1.2&&alivetime[i]<bloodpoolspeed*1.4)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[6]);
		if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1.4&&alivetime[i]<bloodpoolspeed*1.6)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[7]);
		if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1.6&&alivetime[i]<bloodpoolspeed*1.8)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[8]);
		if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1.8&&alivetime[i]<bloodpoolspeed*2.0)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[9]);
		if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*2.0)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[10]);
		if(type[i]==bloodpool&&alivetime[i]<bloodpoolspeed*2.0)glColor4f(1,1,1,1.5-(alivetime[i]*5/bloodpoolspeed-(int)(alivetime[i]*5/bloodpoolspeed)));
		if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*2.0)glColor4f(1,1,1,20-alivetime[i]);

		glPushMatrix();
		glBegin(GL_TRIANGLE_FAN);
			for(int j=0;j<numpoints[i];j++){
			 glTexCoord2f(texcoordsx[i*8+j], texcoordsy[i*8+j]); glVertex3f(points[i*8+j].x,points[i*8+j].y,points[i*8+j].z);
			}
		glEnd();
		glPopMatrix();

		if(type[i]==bloodpool&&alivetime[i]<bloodpoolspeed*2.0){
			if(type[i]==bloodpool&&alivetime[i]<bloodpoolspeed*.2)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[1]);
		if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*.2&&alivetime[i]<bloodpoolspeed*.4)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[2]);
		if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*.4&&alivetime[i]<bloodpoolspeed*.6)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[3]);
		if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*.6&&alivetime[i]<bloodpoolspeed*.8)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[4]);
		if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*.8&&alivetime[i]<bloodpoolspeed*1)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[5]);
		if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1&&alivetime[i]<bloodpoolspeed*1.2)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[6]);
		if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1.2&&alivetime[i]<bloodpoolspeed*1.4)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[7]);
		if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1.4&&alivetime[i]<bloodpoolspeed*1.6)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[8]);
		if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1.6&&alivetime[i]<bloodpoolspeed*1.8)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[9]);
		if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1.8&&alivetime[i]<bloodpoolspeed*2.0)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[10]);
		if(type[i]==bloodpool)glColor4f(1,1,1,alivetime[i]*5/bloodpoolspeed-(int)(alivetime[i]*5/bloodpoolspeed));

			glPushMatrix();
			glBegin(GL_TRIANGLE_FAN);
				for(int j=0;j<numpoints[i];j++){
				 glTexCoord2f(texcoordsx[i*8+j], texcoordsy[i*8+j]); glVertex3f(points[i*8+j].x,points[i*8+j].y,points[i*8+j].z);
				}
			glEnd();
			glPopMatrix();
		}
	}
	glDepthMask(1);
	glDisable(GL_TEXTURE_2D);
	glColor4f(1,1,1,1);
	glEnable(GL_CULL_FACE);
	glDisable(GL_POLYGON_OFFSET_FILL);
	glDepthFunc(GL_LEQUAL);
}

Decals::~Decals()
{
	const GLuint holes[] {bulletholetextureptr, cratertextureptr};
	glDeleteTextures(2, holes);
	glDeleteTextures(11, bloodtextureptr);
}