Rev 5056 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
278 | Plagman | 1 | // blah |
1609 | plagman | 2 | |
1820 | terminx | 3 | #ifdef USE_OPENGL |
686 | plagman | 4 | |
2985 | helixhorne | 5 | #include <math.h> |
6 | |||
686 | plagman | 7 | #define POLYMER_C |
286 | terminx | 8 | #include "polymer.h" |
1298 | plagman | 9 | #include "engine_priv.h" |
4387 | terminx | 10 | #include "xxhash.h" |
3758 | terminx | 11 | #include "texcache.h" |
286 | terminx | 12 | |
304 | Plagman | 13 | // CVARS |
1307 | plagman | 14 | int32_t pr_lighting = 1; |
15 | int32_t pr_normalmapping = 1; |
||
16 | int32_t pr_specularmapping = 1; |
||
17 | int32_t pr_shadows = 1; |
||
18 | int32_t pr_shadowcount = 5; |
||
1350 | terminx | 19 | int32_t pr_shadowdetail = 4; |
1408 | plagman | 20 | int32_t pr_shadowfiltering = 1; |
1454 | terminx | 21 | int32_t pr_maxlightpasses = 10; |
1305 | plagman | 22 | int32_t pr_maxlightpriority = PR_MAXLIGHTPRIORITY; |
1212 | plagman | 23 | int32_t pr_fov = 426; // appears to be the classic setting. |
3769 | terminx | 24 | double pr_customaspect = 0.0f; |
1212 | plagman | 25 | int32_t pr_billboardingmode = 1; |
26 | int32_t pr_verbosity = 1; // 0: silent, 1: errors and one-times, 2: multiple-times, 3: flood |
||
27 | int32_t pr_wireframe = 0; |
||
28 | int32_t pr_vbos = 2; |
||
29 | int32_t pr_gpusmoothing = 1; |
||
1284 | plagman | 30 | int32_t pr_overrideparallax = 0; |
1285 | plagman | 31 | float pr_parallaxscale = 0.1f; |
32 | float pr_parallaxbias = 0.0f; |
||
33 | int32_t pr_overridespecular = 0; |
||
34 | float pr_specularpower = 15.0f; |
||
35 | float pr_specularfactor = 1.0f; |
||
1748 | plagman | 36 | int32_t pr_highpalookups = 1; |
3737 | Plagman | 37 | int32_t pr_artmapping = 1; |
1814 | plagman | 38 | int32_t pr_overridehud = 0; |
39 | float pr_hudxadd = 0.0f; |
||
40 | float pr_hudyadd = 0.0f; |
||
41 | float pr_hudzadd = 0.0f; |
||
42 | int32_t pr_hudangadd = 0; |
||
43 | int32_t pr_hudfov = 426; |
||
1818 | plagman | 44 | float pr_overridemodelscale = 0.0f; |
1445 | plagman | 45 | int32_t pr_ati_fboworkaround = 0; |
1446 | plagman | 46 | int32_t pr_ati_nodepthoffset = 0; |
1789 | helixhorne | 47 | #ifdef __APPLE__ |
48 | int32_t pr_ati_textureformat_one = 0; |
||
49 | #endif |
||
278 | Plagman | 50 | |
1425 | terminx | 51 | int32_t r_pr_maxlightpasses = 5; // value of the cvar (not live value), used to detect changes |
52 | |||
741 | plagman | 53 | GLenum mapvbousage = GL_STREAM_DRAW_ARB; |
754 | plagman | 54 | GLenum modelvbousage = GL_STATIC_DRAW_ARB; |
741 | plagman | 55 | |
1153 | plagman | 56 | // BUILD DATA |
304 | Plagman | 57 | _prsector *prsectors[MAXSECTORS]; |
58 | _prwall *prwalls[MAXWALLS]; |
||
1676 | terminx | 59 | _prsprite *prsprites[MAXSPRITES]; |
1165 | plagman | 60 | _prmaterial mdspritematerial; |
1782 | plagman | 61 | _prhighpalookup prhighpalookups[MAXBASEPALS][MAXPALOOKUPS]; |
733 | plagman | 62 | |
3729 | Plagman | 63 | // One U8 texture per tile |
64 | GLuint prartmaps[MAXTILES]; |
||
65 | // 256 U8U8U8 values per basepal |
||
66 | GLuint prbasepalmaps[MAXBASEPALS]; |
||
67 | // numshades full indirections (32*256) per lookup |
||
68 | GLuint prlookups[MAXPALOOKUPS]; |
||
69 | |||
1676 | terminx | 70 | static const GLfloat vertsprite[4 * 5] = |
723 | terminx | 71 | { |
683 | plagman | 72 | -0.5f, 0.0f, 0.0f, |
723 | terminx | 73 | 0.0f, 1.0f, |
74 | 0.5f, 0.0f, 0.0f, |
||
75 | 1.0f, 1.0f, |
||
76 | 0.5f, 1.0f, 0.0f, |
||
77 | 1.0f, 0.0f, |
||
683 | plagman | 78 | -0.5f, 1.0f, 0.0f, |
723 | terminx | 79 | 0.0f, 0.0f, |
683 | plagman | 80 | }; |
81 | |||
1676 | terminx | 82 | static const GLfloat horizsprite[4 * 5] = |
723 | terminx | 83 | { |
1371 | plagman | 84 | -0.5f, 0.0f, 0.5f, |
85 | 0.0f, 0.0f, |
||
86 | 0.5f, 0.0f, 0.5f, |
||
87 | 1.0f, 0.0f, |
||
88 | 0.5f, 0.0f, -0.5f, |
||
89 | 1.0f, 1.0f, |
||
697 | plagman | 90 | -0.5f, 0.0f, -0.5f, |
723 | terminx | 91 | 0.0f, 1.0f, |
683 | plagman | 92 | }; |
93 | |||
1676 | terminx | 94 | static const GLfloat skyboxdata[4 * 5 * 6] = |
779 | plagman | 95 | { |
96 | // -ZY |
||
97 | -0.5f, -0.5f, 0.5f, |
||
98 | 0.0f, 1.0f, |
||
99 | -0.5f, -0.5f, -0.5f, |
||
100 | 1.0f, 1.0f, |
||
101 | -0.5f, 0.5f, -0.5f, |
||
102 | 1.0f, 0.0f, |
||
103 | -0.5f, 0.5f, 0.5f, |
||
104 | 0.0f, 0.0f, |
||
105 | |||
106 | // XY |
||
107 | -0.5f, -0.5f, -0.5f, |
||
108 | 0.0f, 1.0f, |
||
109 | 0.5f, -0.5f, -0.5f, |
||
110 | 1.0f, 1.0f, |
||
111 | 0.5f, 0.5f, -0.5f, |
||
112 | 1.0f, 0.0f, |
||
113 | -0.5f, 0.5f, -0.5f, |
||
114 | 0.0f, 0.0f, |
||
115 | |||
116 | // ZY |
||
117 | 0.5f, -0.5f, -0.5f, |
||
118 | 0.0f, 1.0f, |
||
119 | 0.5f, -0.5f, 0.5f, |
||
120 | 1.0f, 1.0f, |
||
121 | 0.5f, 0.5f, 0.5f, |
||
122 | 1.0f, 0.0f, |
||
123 | 0.5f, 0.5f, -0.5f, |
||
124 | 0.0f, 0.0f, |
||
125 | |||
126 | // -XY |
||
127 | 0.5f, -0.5f, 0.5f, |
||
128 | 0.0f, 1.0f, |
||
129 | -0.5f, -0.5f, 0.5f, |
||
130 | 1.0f, 1.0f, |
||
131 | -0.5f, 0.5f, 0.5f, |
||
132 | 1.0f, 0.0f, |
||
133 | 0.5f, 0.5f, 0.5f, |
||
134 | 0.0f, 0.0f, |
||
135 | |||
136 | // XZ |
||
137 | -0.5f, 0.5f, -0.5f, |
||
138 | 1.0f, 1.0f, |
||
139 | 0.5f, 0.5f, -0.5f, |
||
140 | 1.0f, 0.0f, |
||
141 | 0.5f, 0.5f, 0.5f, |
||
142 | 0.0f, 0.0f, |
||
143 | -0.5f, 0.5f, 0.5f, |
||
144 | 0.0f, 1.0f, |
||
145 | |||
146 | // X-Z |
||
147 | -0.5f, -0.5f, 0.5f, |
||
148 | 0.0f, 0.0f, |
||
149 | 0.5f, -0.5f, 0.5f, |
||
150 | 0.0f, 1.0f, |
||
151 | 0.5f, -0.5f, -0.5f, |
||
152 | 1.0f, 1.0f, |
||
153 | -0.5f, -0.5f, -0.5f, |
||
154 | 1.0f, 0.0f, |
||
155 | }; |
||
156 | |||
780 | plagman | 157 | GLuint skyboxdatavbo; |
158 | |||
779 | plagman | 159 | GLfloat artskydata[16]; |
160 | |||
1153 | plagman | 161 | // LIGHTS |
4600 | terminx | 162 | static _prplanelist *plpool; |
1457 | terminx | 163 | #pragma pack(push,1) |
1152 | plagman | 164 | _prlight prlights[PR_MAXLIGHTS]; |
1212 | plagman | 165 | int32_t lightcount; |
1242 | plagman | 166 | int32_t curlight; |
1457 | terminx | 167 | #pragma pack(pop) |
1288 | plagman | 168 | |
1676 | terminx | 169 | static const GLfloat shadowBias[] = |
1268 | plagman | 170 | { |
171 | 0.5, 0.0, 0.0, 0.0, |
||
172 | 0.0, 0.5, 0.0, 0.0, |
||
173 | 0.0, 0.0, 0.5, 0.0, |
||
174 | 0.5, 0.5, 0.5, 1.0 |
||
175 | }; |
||
176 | |||
1163 | plagman | 177 | // MATERIALS |
4600 | terminx | 178 | static const _prprogrambit prprogrambits[PR_BIT_COUNT] = { |
1152 | plagman | 179 | { |
1222 | plagman | 180 | 1 << PR_BIT_HEADER, |
181 | // vert_def |
||
182 | "#version 120\n" |
||
1255 | plagman | 183 | "#extension GL_ARB_texture_rectangle : enable\n" |
1222 | plagman | 184 | "\n", |
185 | // vert_prog |
||
186 | "", |
||
187 | // frag_def |
||
188 | "#version 120\n" |
||
1255 | plagman | 189 | "#extension GL_ARB_texture_rectangle : enable\n" |
1222 | plagman | 190 | "\n", |
191 | // frag_prog |
||
192 | "", |
||
193 | }, |
||
194 | { |
||
1167 | plagman | 195 | 1 << PR_BIT_ANIM_INTERPOLATION, |
196 | // vert_def |
||
197 | "attribute vec4 nextFrameData;\n" |
||
1239 | plagman | 198 | "attribute vec4 nextFrameNormal;\n" |
1167 | plagman | 199 | "uniform float frameProgress;\n" |
200 | "\n", |
||
201 | // vert_prog |
||
202 | " vec4 currentFramePosition;\n" |
||
203 | " vec4 nextFramePosition;\n" |
||
1169 | plagman | 204 | "\n" |
1239 | plagman | 205 | " currentFramePosition = curVertex * (1.0 - frameProgress);\n" |
1167 | plagman | 206 | " nextFramePosition = nextFrameData * frameProgress;\n" |
1239 | plagman | 207 | " curVertex = currentFramePosition + nextFramePosition;\n" |
208 | "\n" |
||
209 | " currentFramePosition = vec4(curNormal, 1.0) * (1.0 - frameProgress);\n" |
||
210 | " nextFramePosition = nextFrameNormal * frameProgress;\n" |
||
211 | " curNormal = vec3(currentFramePosition + nextFramePosition);\n" |
||
1167 | plagman | 212 | "\n", |
213 | // frag_def |
||
214 | "", |
||
215 | // frag_prog |
||
216 | "", |
||
217 | }, |
||
218 | { |
||
1242 | plagman | 219 | 1 << PR_BIT_LIGHTING_PASS, |
220 | // vert_def |
||
221 | "", |
||
222 | // vert_prog |
||
223 | "", |
||
224 | // frag_def |
||
225 | "", |
||
226 | // frag_prog |
||
227 | " isLightingPass = 1;\n" |
||
228 | " result = vec4(0.0, 0.0, 0.0, 1.0);\n" |
||
229 | "\n", |
||
230 | }, |
||
231 | { |
||
1244 | plagman | 232 | 1 << PR_BIT_NORMAL_MAP, |
233 | // vert_def |
||
234 | "attribute vec3 T;\n" |
||
235 | "attribute vec3 B;\n" |
||
236 | "attribute vec3 N;\n" |
||
1283 | plagman | 237 | "uniform vec3 eyePosition;\n" |
1284 | plagman | 238 | "varying vec3 tangentSpaceEyeVec;\n" |
1244 | plagman | 239 | "\n", |
240 | // vert_prog |
||
1591 | plagman | 241 | " TBN = mat3(T, B, N);\n" |
1284 | plagman | 242 | " tangentSpaceEyeVec = eyePosition - vec3(curVertex);\n" |
243 | " tangentSpaceEyeVec = TBN * tangentSpaceEyeVec;\n" |
||
1244 | plagman | 244 | "\n" |
245 | " isNormalMapped = 1;\n" |
||
246 | "\n", |
||
247 | // frag_def |
||
248 | "uniform sampler2D normalMap;\n" |
||
1284 | plagman | 249 | "uniform vec2 normalBias;\n" |
250 | "varying vec3 tangentSpaceEyeVec;\n" |
||
1244 | plagman | 251 | "\n", |
252 | // frag_prog |
||
1284 | plagman | 253 | " vec4 normalStep;\n" |
254 | " float biasedHeight;\n" |
||
1283 | plagman | 255 | "\n" |
1284 | plagman | 256 | " eyeVec = normalize(tangentSpaceEyeVec);\n" |
257 | "\n" |
||
258 | " for (int i = 0; i < 4; i++) {\n" |
||
259 | " normalStep = texture2D(normalMap, commonTexCoord.st);\n" |
||
260 | " biasedHeight = normalStep.a * normalBias.x - normalBias.y;\n" |
||
261 | " commonTexCoord += (biasedHeight - commonTexCoord.z) * normalStep.z * eyeVec;\n" |
||
262 | " }\n" |
||
263 | "\n" |
||
264 | " normalTexel = texture2D(normalMap, commonTexCoord.st);\n" |
||
265 | "\n" |
||
1244 | plagman | 266 | " isNormalMapped = 1;\n" |
267 | "\n", |
||
268 | }, |
||
269 | { |
||
3729 | Plagman | 270 | 1 << PR_BIT_ART_MAP, |
271 | // vert_def |
||
3739 | Plagman | 272 | "varying vec3 horizDistance;\n" |
3729 | Plagman | 273 | "\n", |
274 | // vert_prog |
||
3737 | Plagman | 275 | " gl_TexCoord[0] = gl_MultiTexCoord0;\n" |
3739 | Plagman | 276 | " horizDistance = vec3(gl_ModelViewMatrix * curVertex);\n" |
3729 | Plagman | 277 | "\n", |
278 | // frag_def |
||
279 | "uniform sampler2D artMap;\n" |
||
280 | "uniform sampler2D basePalMap;\n" |
||
3740 | Plagman | 281 | "uniform sampler2DRect lookupMap;\n" |
3737 | Plagman | 282 | "uniform float shadeOffset;\n" |
283 | "uniform float visibility;\n" |
||
3739 | Plagman | 284 | "varying vec3 horizDistance;\n" |
3729 | Plagman | 285 | "\n", |
286 | // frag_prog |
||
3962 | helixhorne | 287 | |
288 | // NOTE: the denominator was 1.024, but we increase it towards a bit |
||
289 | // farther far clipoff distance to account for the fact that the |
||
290 | // distance to the fragment is the common Euclidean one, as opposed to |
||
291 | // the "ortho" distance of Build. |
||
292 | " float shadeLookup = length(horizDistance) / 1.07 * visibility;\n" |
||
3740 | Plagman | 293 | " shadeLookup = shadeLookup + shadeOffset;\n" |
3737 | Plagman | 294 | "\n" |
3740 | Plagman | 295 | " float colorIndex = texture2D(artMap, commonTexCoord.st).r * 256.0;\n" |
296 | " float colorIndexNear = texture2DRect(lookupMap, vec2(colorIndex, floor(shadeLookup))).r;\n" |
||
297 | " float colorIndexFar = texture2DRect(lookupMap, vec2(colorIndex, floor(shadeLookup + 1.0))).r;\n" |
||
298 | " float colorIndexFullbright = texture2DRect(lookupMap, vec2(colorIndex, 0.0)).r;\n" |
||
3729 | Plagman | 299 | "\n" |
3737 | Plagman | 300 | " vec3 texelNear = texture2D(basePalMap, vec2(colorIndexNear, 0.5)).rgb;\n" |
301 | " vec3 texelFar = texture2D(basePalMap, vec2(colorIndexFar, 0.5)).rgb;\n" |
||
3738 | Plagman | 302 | " diffuseTexel.rgb = texture2D(basePalMap, vec2(colorIndexFullbright, 0.5)).rgb * 4.0;\n" |
303 | "\n" |
||
304 | " if (isLightingPass == 0) {\n" |
||
305 | " result.rgb = mix(texelNear, texelFar, fract(shadeLookup)) * 4.0;\n" |
||
306 | " result.a = 1.0;\n" |
||
3740 | Plagman | 307 | " if (colorIndex == 256.0)\n" |
3738 | Plagman | 308 | " result.a = 0.0;\n" |
309 | " }\n" |
||
3729 | Plagman | 310 | "\n", |
311 | }, |
||
312 | { |
||
1162 | plagman | 313 | 1 << PR_BIT_DIFFUSE_MAP, |
314 | // vert_def |
||
1168 | plagman | 315 | "uniform vec2 diffuseScale;\n" |
316 | "\n", |
||
1162 | plagman | 317 | // vert_prog |
1280 | plagman | 318 | " gl_TexCoord[0] = vec4(diffuseScale, 1.0, 1.0) * gl_MultiTexCoord0;\n" |
1162 | plagman | 319 | "\n", |
320 | // frag_def |
||
321 | "uniform sampler2D diffuseMap;\n" |
||
322 | "\n", |
||
323 | // frag_prog |
||
1284 | plagman | 324 | " diffuseTexel = texture2D(diffuseMap, commonTexCoord.st);\n" |
1745 | plagman | 325 | "\n", |
326 | }, |
||
327 | { |
||
1757 | plagman | 328 | 1 << PR_BIT_DIFFUSE_DETAIL_MAP, |
1745 | plagman | 329 | // vert_def |
1757 | plagman | 330 | "uniform vec2 detailScale;\n" |
331 | "varying vec2 fragDetailScale;\n" |
||
332 | "\n", |
||
1745 | plagman | 333 | // vert_prog |
1757 | plagman | 334 | " fragDetailScale = detailScale;\n" |
335 | " if (isNormalMapped == 0)\n" |
||
336 | " gl_TexCoord[1] = vec4(detailScale, 1.0, 1.0) * gl_MultiTexCoord0;\n" |
||
337 | "\n", |
||
1745 | plagman | 338 | // frag_def |
1757 | plagman | 339 | "uniform sampler2D detailMap;\n" |
340 | "varying vec2 fragDetailScale;\n" |
||
1745 | plagman | 341 | "\n", |
342 | // frag_prog |
||
1757 | plagman | 343 | " if (isNormalMapped == 0)\n" |
344 | " diffuseTexel *= texture2D(detailMap, gl_TexCoord[1].st);\n" |
||
345 | " else\n" |
||
346 | " diffuseTexel *= texture2D(detailMap, commonTexCoord.st * fragDetailScale);\n" |
||
347 | " diffuseTexel.rgb *= 2.0;\n" |
||
1745 | plagman | 348 | "\n", |
349 | }, |
||
350 | { |
||
1757 | plagman | 351 | 1 << PR_BIT_DIFFUSE_MODULATION, |
1745 | plagman | 352 | // vert_def |
353 | "", |
||
354 | // vert_prog |
||
1757 | plagman | 355 | " gl_FrontColor = gl_Color;\n" |
356 | "\n", |
||
1745 | plagman | 357 | // frag_def |
358 | "", |
||
359 | // frag_prog |
||
1242 | plagman | 360 | " if (isLightingPass == 0)\n" |
1773 | plagman | 361 | " result *= vec4(gl_Color);\n" |
1162 | plagman | 362 | "\n", |
363 | }, |
||
364 | { |
||
1773 | plagman | 365 | 1 << PR_BIT_DIFFUSE_MAP2, |
1168 | plagman | 366 | // vert_def |
1757 | plagman | 367 | "", |
1168 | plagman | 368 | // vert_prog |
1757 | plagman | 369 | "", |
1168 | plagman | 370 | // frag_def |
1773 | plagman | 371 | "", |
1168 | plagman | 372 | // frag_prog |
1773 | plagman | 373 | " if (isLightingPass == 0)\n" |
374 | " result *= diffuseTexel;\n" |
||
1168 | plagman | 375 | "\n", |
376 | }, |
||
377 | { |
||
1773 | plagman | 378 | 1 << PR_BIT_HIGHPALOOKUP_MAP, |
1160 | plagman | 379 | // vert_def |
380 | "", |
||
381 | // vert_prog |
||
1757 | plagman | 382 | "", |
1160 | plagman | 383 | // frag_def |
1773 | plagman | 384 | "uniform sampler3D highPalookupMap;\n" |
385 | "\n", |
||
1160 | plagman | 386 | // frag_prog |
1783 | plagman | 387 | " float highPalScale = 0.9921875; // for 6 bits\n" |
388 | " float highPalBias = 0.00390625;\n" |
||
389 | "\n" |
||
1242 | plagman | 390 | " if (isLightingPass == 0)\n" |
1783 | plagman | 391 | " result.rgb = texture3D(highPalookupMap, result.rgb * highPalScale + highPalBias).rgb;\n" |
392 | " diffuseTexel.rgb = texture3D(highPalookupMap, diffuseTexel.rgb * highPalScale + highPalBias).rgb;\n" |
||
1160 | plagman | 393 | "\n", |
1154 | plagman | 394 | }, |
395 | { |
||
1281 | plagman | 396 | 1 << PR_BIT_SPECULAR_MAP, |
397 | // vert_def |
||
398 | "", |
||
399 | // vert_prog |
||
400 | "", |
||
401 | // frag_def |
||
402 | "uniform sampler2D specMap;\n" |
||
403 | "\n", |
||
404 | // frag_prog |
||
1284 | plagman | 405 | " specTexel = texture2D(specMap, commonTexCoord.st);\n" |
1382 | plagman | 406 | "\n" |
407 | " isSpecularMapped = 1;\n" |
||
1281 | plagman | 408 | "\n", |
409 | }, |
||
410 | { |
||
1278 | plagman | 411 | 1 << PR_BIT_SPECULAR_MATERIAL, |
412 | // vert_def |
||
413 | "", |
||
414 | // vert_prog |
||
415 | "", |
||
416 | // frag_def |
||
417 | "uniform vec2 specMaterial;\n" |
||
418 | "\n", |
||
419 | // frag_prog |
||
420 | " specularMaterial = specMaterial;\n" |
||
421 | "\n", |
||
422 | }, |
||
423 | { |
||
1277 | plagman | 424 | 1 << PR_BIT_MIRROR_MAP, |
1255 | plagman | 425 | // vert_def |
426 | "", |
||
427 | // vert_prog |
||
428 | "", |
||
429 | // frag_def |
||
430 | "uniform sampler2DRect mirrorMap;\n" |
||
431 | "\n", |
||
432 | // frag_prog |
||
433 | " vec4 mirrorTexel;\n" |
||
434 | " vec2 mirrorCoords;\n" |
||
435 | "\n" |
||
436 | " mirrorCoords = gl_FragCoord.st;\n" |
||
437 | " if (isNormalMapped == 1) {\n" |
||
438 | " mirrorCoords += 100.0 * (normalTexel.rg - 0.5);\n" |
||
439 | " }\n" |
||
440 | " mirrorTexel = texture2DRect(mirrorMap, mirrorCoords);\n" |
||
1282 | plagman | 441 | " result = vec4((result.rgb * (1.0 - specTexel.a)) + (mirrorTexel.rgb * specTexel.rgb * specTexel.a), result.a);\n" |
1255 | plagman | 442 | "\n", |
443 | }, |
||
444 | { |
||
1298 | plagman | 445 | 1 << PR_BIT_FOG, |
446 | // vert_def |
||
447 | "", |
||
448 | // vert_prog |
||
449 | "", |
||
450 | // frag_def |
||
3301 | helixhorne | 451 | #ifdef PR_LINEAR_FOG |
452 | "uniform bool linearFog;\n" |
||
453 | #endif |
||
1298 | plagman | 454 | "", |
455 | // frag_prog |
||
456 | " float fragDepth;\n" |
||
457 | " float fogFactor;\n" |
||
458 | "\n" |
||
1323 | plagman | 459 | " fragDepth = gl_FragCoord.z / gl_FragCoord.w / 35.0;\n" |
3301 | helixhorne | 460 | #ifdef PR_LINEAR_FOG |
461 | " if (!linearFog) {\n" |
||
462 | #endif |
||
463 | " fragDepth *= fragDepth;\n" |
||
464 | " fogFactor = exp2(-gl_Fog.density * gl_Fog.density * fragDepth * 1.442695);\n" |
||
465 | #ifdef PR_LINEAR_FOG |
||
466 | /* 0.65127==150/230, another constant found out by experiment. :/ |
||
3307 | helixhorne | 467 | * (150 is Polymost's old FOGDISTCONST.) */ |
3301 | helixhorne | 468 | " } else {\n" |
469 | " fogFactor = gl_Fog.scale * (gl_Fog.end - fragDepth*0.65217);\n" |
||
470 | " fogFactor = clamp(fogFactor, 0.0, 1.0);" |
||
471 | " }\n" |
||
472 | #endif |
||
1298 | plagman | 473 | " result.rgb = mix(gl_Fog.color.rgb, result.rgb, fogFactor);\n" |
474 | "\n", |
||
475 | }, |
||
476 | { |
||
1277 | plagman | 477 | 1 << PR_BIT_GLOW_MAP, |
1242 | plagman | 478 | // vert_def |
479 | "", |
||
480 | // vert_prog |
||
1280 | plagman | 481 | "", |
1242 | plagman | 482 | // frag_def |
483 | "uniform sampler2D glowMap;\n" |
||
484 | "\n", |
||
485 | // frag_prog |
||
486 | " vec4 glowTexel;\n" |
||
487 | "\n" |
||
1284 | plagman | 488 | " glowTexel = texture2D(glowMap, commonTexCoord.st);\n" |
1242 | plagman | 489 | " result = vec4((result.rgb * (1.0 - glowTexel.a)) + (glowTexel.rgb * glowTexel.a), result.a);\n" |
490 | "\n", |
||
491 | }, |
||
492 | { |
||
1674 | plagman | 493 | 1 << PR_BIT_PROJECTION_MAP, |
1268 | plagman | 494 | // vert_def |
495 | "uniform mat4 shadowProjMatrix;\n" |
||
496 | "\n", |
||
497 | // vert_prog |
||
1323 | plagman | 498 | " gl_TexCoord[2] = shadowProjMatrix * curVertex;\n" |
1268 | plagman | 499 | "\n", |
500 | // frag_def |
||
1674 | plagman | 501 | "", |
502 | // frag_prog |
||
503 | "", |
||
504 | }, |
||
505 | { |
||
506 | 1 << PR_BIT_SHADOW_MAP, |
||
507 | // vert_def |
||
508 | "", |
||
509 | // vert_prog |
||
510 | "", |
||
511 | // frag_def |
||
1268 | plagman | 512 | "uniform sampler2DShadow shadowMap;\n" |
513 | "\n", |
||
514 | // frag_prog |
||
1323 | plagman | 515 | " shadowResult = shadow2DProj(shadowMap, gl_TexCoord[2]).a;\n" |
1268 | plagman | 516 | "\n", |
517 | }, |
||
518 | { |
||
1377 | plagman | 519 | 1 << PR_BIT_LIGHT_MAP, |
520 | // vert_def |
||
521 | "", |
||
522 | // vert_prog |
||
523 | "", |
||
524 | // frag_def |
||
525 | "uniform sampler2D lightMap;\n" |
||
526 | "\n", |
||
527 | // frag_prog |
||
2055 | plagman | 528 | " lightTexel = texture2D(lightMap, vec2(gl_TexCoord[2].s, -gl_TexCoord[2].t) / gl_TexCoord[2].q).rgb;\n" |
1377 | plagman | 529 | "\n", |
530 | }, |
||
531 | { |
||
1266 | plagman | 532 | 1 << PR_BIT_SPOT_LIGHT, |
533 | // vert_def |
||
534 | "", |
||
535 | // vert_prog |
||
536 | "", |
||
537 | // frag_def |
||
538 | "uniform vec3 spotDir;\n" |
||
539 | "uniform vec2 spotRadius;\n" |
||
540 | "\n", |
||
541 | // frag_prog |
||
542 | " spotVector = spotDir;\n" |
||
543 | " spotCosRadius = spotRadius;\n" |
||
544 | " isSpotLight = 1;\n" |
||
545 | "\n", |
||
546 | }, |
||
547 | { |
||
1170 | plagman | 548 | 1 << PR_BIT_POINT_LIGHT, |
549 | // vert_def |
||
550 | "varying vec3 vertexNormal;\n" |
||
1243 | plagman | 551 | "varying vec3 eyeVector;\n" |
552 | "varying vec3 lightVector;\n" |
||
1244 | plagman | 553 | "varying vec3 tangentSpaceLightVector;\n" |
1170 | plagman | 554 | "\n", |
555 | // vert_prog |
||
1243 | plagman | 556 | " vec3 vertexPos;\n" |
557 | "\n" |
||
1239 | plagman | 558 | " vertexPos = vec3(gl_ModelViewMatrix * curVertex);\n" |
1243 | plagman | 559 | " eyeVector = -vertexPos;\n" |
560 | " lightVector = gl_LightSource[0].ambient.rgb - vertexPos;\n" |
||
1244 | plagman | 561 | "\n" |
562 | " if (isNormalMapped == 1) {\n" |
||
1283 | plagman | 563 | " tangentSpaceLightVector = gl_LightSource[0].specular.rgb - vec3(curVertex);\n" |
564 | " tangentSpaceLightVector = TBN * tangentSpaceLightVector;\n" |
||
1244 | plagman | 565 | " } else\n" |
566 | " vertexNormal = normalize(gl_NormalMatrix * curNormal);\n" |
||
1170 | plagman | 567 | "\n", |
568 | // frag_def |
||
569 | "varying vec3 vertexNormal;\n" |
||
1243 | plagman | 570 | "varying vec3 eyeVector;\n" |
571 | "varying vec3 lightVector;\n" |
||
1244 | plagman | 572 | "varying vec3 tangentSpaceLightVector;\n" |
1170 | plagman | 573 | "\n", |
574 | // frag_prog |
||
1243 | plagman | 575 | " float pointLightDistance;\n" |
1170 | plagman | 576 | " float lightAttenuation;\n" |
1266 | plagman | 577 | " float spotAttenuation;\n" |
578 | " vec3 N, L, E, R, D;\n" |
||
1243 | plagman | 579 | " vec3 lightDiffuse;\n" |
580 | " float lightSpecular;\n" |
||
581 | " float NdotL;\n" |
||
1266 | plagman | 582 | " float spotCosAngle;\n" |
1170 | plagman | 583 | "\n" |
1243 | plagman | 584 | " L = normalize(lightVector);\n" |
1211 | plagman | 585 | "\n" |
1406 | plagman | 586 | " pointLightDistance = dot(lightVector,lightVector);\n" |
587 | " lightAttenuation = clamp(1.0 - pointLightDistance * gl_LightSource[0].linearAttenuation, 0.0, 1.0);\n" |
||
1266 | plagman | 588 | " spotAttenuation = 1.0;\n" |
1243 | plagman | 589 | "\n" |
1266 | plagman | 590 | " if (isSpotLight == 1) {\n" |
591 | " D = normalize(spotVector);\n" |
||
592 | " spotCosAngle = dot(-L, D);\n" |
||
593 | " spotAttenuation = clamp((spotCosAngle - spotCosRadius.x) * spotCosRadius.y, 0.0, 1.0);\n" |
||
594 | " }\n" |
||
595 | "\n" |
||
1265 | plagman | 596 | " if (isNormalMapped == 1) {\n" |
1284 | plagman | 597 | " E = eyeVec;\n" |
1283 | plagman | 598 | " N = normalize(2.0 * (normalTexel.rgb - 0.5));\n" |
599 | " L = normalize(tangentSpaceLightVector);\n" |
||
1284 | plagman | 600 | " } else {\n" |
601 | " E = normalize(eyeVector);\n" |
||
1265 | plagman | 602 | " N = normalize(vertexNormal);\n" |
1284 | plagman | 603 | " }\n" |
1265 | plagman | 604 | " NdotL = max(dot(N, L), 0.0);\n" |
1243 | plagman | 605 | "\n" |
1265 | plagman | 606 | " R = reflect(-L, N);\n" |
1243 | plagman | 607 | "\n" |
1381 | plagman | 608 | " lightDiffuse = gl_Color.a * shadowResult * lightTexel *\n" |
1266 | plagman | 609 | " gl_LightSource[0].diffuse.rgb * lightAttenuation * spotAttenuation;\n" |
1381 | plagman | 610 | " result += vec4(lightDiffuse * diffuseTexel.a * diffuseTexel.rgb * NdotL, 0.0);\n" |
1243 | plagman | 611 | "\n" |
1383 | plagman | 612 | " if (isSpecularMapped == 0)\n" |
1382 | plagman | 613 | " specTexel.rgb = diffuseTexel.rgb * diffuseTexel.a;\n" |
614 | "\n" |
||
1281 | plagman | 615 | " lightSpecular = pow( max(dot(R, E), 0.0), specularMaterial.x * specTexel.a) * specularMaterial.y;\n" |
1380 | plagman | 616 | " result += vec4(lightDiffuse * specTexel.rgb * lightSpecular, 0.0);\n" |
1170 | plagman | 617 | "\n", |
618 | }, |
||
619 | { |
||
1222 | plagman | 620 | 1 << PR_BIT_FOOTER, |
1160 | plagman | 621 | // vert_def |
622 | "void main(void)\n" |
||
1167 | plagman | 623 | "{\n" |
1239 | plagman | 624 | " vec4 curVertex = gl_Vertex;\n" |
625 | " vec3 curNormal = gl_Normal;\n" |
||
1244 | plagman | 626 | " int isNormalMapped = 0;\n" |
627 | " mat3 TBN;\n" |
||
1280 | plagman | 628 | "\n" |
629 | " gl_TexCoord[0] = gl_MultiTexCoord0;\n" |
||
1167 | plagman | 630 | "\n", |
1160 | plagman | 631 | // vert_prog |
1239 | plagman | 632 | " gl_Position = gl_ModelViewProjectionMatrix * curVertex;\n" |
1160 | plagman | 633 | "}\n", |
634 | // frag_def |
||
635 | "void main(void)\n" |
||
636 | "{\n" |
||
1284 | plagman | 637 | " vec3 commonTexCoord = vec3(gl_TexCoord[0].st, 0.0);\n" |
1160 | plagman | 638 | " vec4 result = vec4(1.0, 1.0, 1.0, 1.0);\n" |
1233 | plagman | 639 | " vec4 diffuseTexel = vec4(1.0, 1.0, 1.0, 1.0);\n" |
1281 | plagman | 640 | " vec4 specTexel = vec4(1.0, 1.0, 1.0, 1.0);\n" |
1244 | plagman | 641 | " vec4 normalTexel;\n" |
1242 | plagman | 642 | " int isLightingPass = 0;\n" |
1244 | plagman | 643 | " int isNormalMapped = 0;\n" |
1382 | plagman | 644 | " int isSpecularMapped = 0;\n" |
1284 | plagman | 645 | " vec3 eyeVec;\n" |
1266 | plagman | 646 | " int isSpotLight = 0;\n" |
647 | " vec3 spotVector;\n" |
||
648 | " vec2 spotCosRadius;\n" |
||
1323 | plagman | 649 | " float shadowResult = 1.0;\n" |
1285 | plagman | 650 | " vec2 specularMaterial = vec2(15.0, 1.0);\n" |
1377 | plagman | 651 | " vec3 lightTexel = vec3(1.0, 1.0, 1.0);\n" |
1160 | plagman | 652 | "\n", |
653 | // frag_prog |
||
654 | " gl_FragColor = result;\n" |
||
655 | "}\n", |
||
1152 | plagman | 656 | } |
657 | }; |
||
658 | |||
1162 | plagman | 659 | _prprograminfo prprograms[1 << PR_BIT_COUNT]; |
1152 | plagman | 660 | |
1252 | plagman | 661 | int32_t overridematerial; |
1554 | plagman | 662 | int32_t globaloldoverridematerial; |
1252 | plagman | 663 | |
1812 | plagman | 664 | int32_t rotatespritematerialbits; |
665 | |||
1255 | plagman | 666 | // RENDER TARGETS |
667 | _prrt *prrts; |
||
668 | |||
311 | Plagman | 669 | // CONTROL |
1211 | plagman | 670 | GLfloat spritemodelview[16]; |
1594 | plagman | 671 | GLfloat mdspritespace[4][4]; |
1211 | plagman | 672 | GLfloat rootmodelviewmatrix[16]; |
673 | GLfloat *curmodelviewmatrix; |
||
1373 | plagman | 674 | GLfloat rootskymodelviewmatrix[16]; |
675 | GLfloat *curskymodelviewmatrix; |
||
525 | Plagman | 676 | |
1313 | plagman | 677 | static int16_t sectorqueue[MAXSECTORS]; |
678 | static int16_t querydelay[MAXSECTORS]; |
||
679 | static GLuint queryid[MAXWALLS]; |
||
680 | static int16_t drawingstate[MAXSECTORS]; |
||
681 | |||
1980 | plagman | 682 | int16_t *cursectormasks; |
683 | int16_t *cursectormaskcount; |
||
684 | |||
1235 | plagman | 685 | float horizang; |
1306 | plagman | 686 | int16_t viewangle; |
1235 | plagman | 687 | |
1212 | plagman | 688 | int32_t depth; |
1255 | plagman | 689 | _prmirror mirrors[10]; |
311 | Plagman | 690 | |
4644 | hendricks2 | 691 | #if defined __clang__ && defined __APPLE__ |
692 | // XXX: OS X 10.9 deprecated GLUtesselator. |
||
693 | #pragma clang diagnostic push |
||
694 | #pragma clang diagnostic ignored "-Wdeprecated-declarations" |
||
695 | #endif |
||
283 | Plagman | 696 | GLUtesselator* prtess; |
4644 | hendricks2 | 697 | #if defined __clang__ && defined __APPLE__ |
698 | #pragma clang diagnostic pop |
||
699 | #endif |
||
278 | Plagman | 700 | |
3977 | helixhorne | 701 | static int16_t cursky; |
702 | static char curskypal; |
||
703 | static int8_t curskyshade; |
||
704 | static float curskyangmul = 1; |
||
551 | Plagman | 705 | |
697 | plagman | 706 | _pranimatespritesinfo asi; |
707 | |||
1554 | plagman | 708 | int32_t polymersearching; |
1456 | helixhorne | 709 | |
2032 | plagman | 710 | int32_t culledface; |
711 | |||
304 | Plagman | 712 | // EXTERNAL FUNCTIONS |
1212 | plagman | 713 | int32_t polymer_init(void) |
278 | Plagman | 714 | { |
2045 | helixhorne | 715 | int32_t i, j, t = getticks(); |
278 | Plagman | 716 | |
1361 | terminx | 717 | if (pr_verbosity >= 1) OSD_Printf("Initializing Polymer subsystem...\n"); |
278 | Plagman | 718 | |
1506 | plagman | 719 | if (!glinfo.texnpot || |
720 | !glinfo.depthtex || |
||
721 | !glinfo.shadow || |
||
722 | !glinfo.fbos || |
||
723 | !glinfo.rect || |
||
724 | !glinfo.multitex || |
||
725 | !glinfo.vbos || |
||
726 | !glinfo.occlusionqueries || |
||
727 | !glinfo.glsl) |
||
728 | { |
||
729 | OSD_Printf("PR : Your video card driver/combo doesn't support the necessary features!\n"); |
||
730 | OSD_Printf("PR : Disabling Polymer...\n"); |
||
731 | return (0); |
||
732 | } |
||
733 | |||
1943 | helixhorne | 734 | // clean up existing stuff since it will be initialized again if we're re-entering here |
735 | polymer_uninit(); |
||
1942 | helixhorne | 736 | |
1330 | terminx | 737 | Bmemset(&prsectors[0], 0, sizeof(prsectors[0]) * MAXSECTORS); |
738 | Bmemset(&prwalls[0], 0, sizeof(prwalls[0]) * MAXWALLS); |
||
283 | Plagman | 739 | |
462 | terminx | 740 | prtess = bgluNewTess(); |
283 | Plagman | 741 | if (prtess == 0) |
742 | { |
||
1361 | terminx | 743 | OSD_Printf("PR : Tessellation object initialization failed!\n"); |
283 | Plagman | 744 | return (0); |
745 | } |
||
746 | |||
304 | Plagman | 747 | polymer_loadboard(); |
748 | |||
779 | plagman | 749 | polymer_initartsky(); |
1300 | plagman | 750 | skyboxdatavbo = 0; |
316 | Plagman | 751 | |
1300 | plagman | 752 | i = 0; |
1301 | plagman | 753 | while (i < nextmodelid) |
754 | { |
||
755 | if (models[i]) |
||
756 | { |
||
757 | md3model_t* m; |
||
758 | |||
759 | m = (md3model_t*)models[i]; |
||
760 | m->indices = NULL; |
||
761 | } |
||
762 | i++; |
||
763 | } |
||
764 | |||
765 | i = 0; |
||
1300 | plagman | 766 | while (i < (1 << PR_BIT_COUNT)) |
767 | { |
||
768 | prprograms[i].handle = 0; |
||
769 | i++; |
||
770 | } |
||
771 | |||
1252 | plagman | 772 | overridematerial = 0xFFFFFFFF; |
773 | |||
1554 | plagman | 774 | polymersearching = FALSE; |
775 | |||
1307 | plagman | 776 | polymer_initrendertargets(pr_shadowcount + 1); |
1943 | helixhorne | 777 | |
1748 | plagman | 778 | // Prime highpalookup maps |
779 | i = 0; |
||
1782 | plagman | 780 | while (i < MAXBASEPALS) |
1748 | plagman | 781 | { |
1782 | plagman | 782 | j = 0; |
783 | while (j < MAXPALOOKUPS) |
||
1748 | plagman | 784 | { |
1782 | plagman | 785 | if (prhighpalookups[i][j].data) |
786 | { |
||
787 | bglGenTextures(1, &prhighpalookups[i][j].map); |
||
788 | bglBindTexture(GL_TEXTURE_3D, prhighpalookups[i][j].map); |
||
789 | bglTexImage3D(GL_TEXTURE_3D, // target |
||
790 | 0, // mip level |
||
791 | GL_RGBA, // internalFormat |
||
792 | PR_HIGHPALOOKUP_DIM, // width |
||
793 | PR_HIGHPALOOKUP_DIM, // height |
||
794 | PR_HIGHPALOOKUP_DIM, // depth |
||
795 | 0, // border |
||
796 | GL_BGRA, // upload format |
||
797 | GL_UNSIGNED_BYTE, // upload component type |
||
798 | prhighpalookups[i][j].data); // data pointer |
||
799 | bglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
||
800 | bglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
||
801 | bglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, glinfo.clamptoedge?GL_CLAMP_TO_EDGE:GL_CLAMP); |
||
802 | bglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, glinfo.clamptoedge?GL_CLAMP_TO_EDGE:GL_CLAMP); |
||
803 | bglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, glinfo.clamptoedge?GL_CLAMP_TO_EDGE:GL_CLAMP); |
||
804 | bglBindTexture(GL_TEXTURE_3D, 0); |
||
805 | } |
||
806 | j++; |
||
1745 | plagman | 807 | } |
1748 | plagman | 808 | i++; |
1745 | plagman | 809 | } |
810 | |||
2073 | helixhorne | 811 | #ifndef __APPLE__ |
2056 | plagman | 812 | if (glinfo.debugoutput) { |
813 | // Enable everything. |
||
814 | bglDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE); |
||
815 | bglDebugMessageCallbackARB(polymer_debugoutputcallback, NULL); |
||
816 | } |
||
2073 | helixhorne | 817 | #endif |
2056 | plagman | 818 | |
2045 | helixhorne | 819 | if (pr_verbosity >= 1) OSD_Printf("PR : Initialization complete in %d ms.\n", getticks()-t); |
1554 | plagman | 820 | |
283 | Plagman | 821 | return (1); |
278 | Plagman | 822 | } |
823 | |||
1390 | terminx | 824 | void polymer_uninit(void) |
825 | { |
||
1782 | plagman | 826 | int32_t i, j; |
1748 | plagman | 827 | |
1943 | helixhorne | 828 | if (prtess) |
829 | { |
||
830 | bgluDeleteTess(prtess); |
||
831 | prtess = NULL; |
||
832 | } |
||
833 | |||
1390 | terminx | 834 | polymer_freeboard(); |
1943 | helixhorne | 835 | |
836 | polymer_initrendertargets(0); |
||
837 | |||
1748 | plagman | 838 | i = 0; |
1782 | plagman | 839 | while (i < MAXBASEPALS) |
1748 | plagman | 840 | { |
1782 | plagman | 841 | j = 0; |
842 | while (j < MAXPALOOKUPS) |
||
843 | { |
||
1969 | helixhorne | 844 | // if (prhighpalookups[i][j].data) { |
845 | // Bfree(prhighpalookups[i][j].data); |
||
846 | // prhighpalookups[i][j].data = NULL; |
||
847 | // } |
||
1782 | plagman | 848 | if (prhighpalookups[i][j].map) { |
849 | bglDeleteTextures(1, &prhighpalookups[i][j].map); |
||
2045 | helixhorne | 850 | prhighpalookups[i][j].map = 0; |
1782 | plagman | 851 | } |
852 | j++; |
||
853 | } |
||
1748 | plagman | 854 | i++; |
855 | } |
||
4600 | terminx | 856 | |
857 | i = 0; |
||
858 | while (plpool) |
||
859 | { |
||
860 | _prplanelist* next = plpool->n; |
||
861 | |||
862 | Bfree(plpool); |
||
863 | plpool = next; |
||
864 | i++; |
||
865 | } |
||
866 | |||
867 | if (pr_verbosity >= 3) |
||
868 | OSD_Printf("PR: freed %d planelists\n", i); |
||
1390 | terminx | 869 | } |
870 | |||
1814 | plagman | 871 | void polymer_setaspect(int32_t ang) |
99 | terminx | 872 | { |
1507 | plagman | 873 | float aspect; |
3179 | helixhorne | 874 | float fang = (float)ang * atanf((float)viewingrange/65536.0f)/(PI/4); |
1507 | plagman | 875 | |
1814 | plagman | 876 | if (pr_customaspect != 0.0f) |
877 | aspect = pr_customaspect; |
||
878 | else |
||
879 | aspect = (float)(windowx2-windowx1+1) / |
||
880 | (float)(windowy2-windowy1+1); |
||
881 | |||
882 | bglMatrixMode(GL_PROJECTION); |
||
883 | bglLoadIdentity(); |
||
2078 | helixhorne | 884 | bgluPerspective(fang / (2048.0f / 360.0f), aspect, 0.01f, 100.0f); |
1814 | plagman | 885 | } |
886 | |||
887 | void polymer_glinit(void) |
||
888 | { |
||
99 | terminx | 889 | bglClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
307 | Plagman | 890 | bglClearStencil(0); |
891 | bglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |
||
1504 | plagman | 892 | bglViewport(windowx1, yres-(windowy2+1),windowx2-windowx1+1, windowy2-windowy1+1); |
283 | Plagman | 893 | |
894 | // texturing |
||
301 | Plagman | 895 | bglEnable(GL_TEXTURE_2D); |
283 | Plagman | 896 | |
99 | terminx | 897 | bglEnable(GL_DEPTH_TEST); |
320 | Plagman | 898 | bglDepthFunc(GL_LEQUAL); |
899 | |||
1255 | plagman | 900 | bglDisable(GL_BLEND); |
901 | bglDisable(GL_ALPHA_TEST); |
||
902 | |||
283 | Plagman | 903 | if (pr_wireframe) |
904 | bglPolygonMode(GL_FRONT_AND_BACK, GL_LINE); |
||
905 | else |
||
906 | bglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); |
||
2032 | plagman | 907 | |
1814 | plagman | 908 | polymer_setaspect(pr_fov); |
283 | Plagman | 909 | |
99 | terminx | 910 | bglMatrixMode(GL_MODELVIEW); |
911 | bglLoadIdentity(); |
||
304 | Plagman | 912 | |
913 | bglEnableClientState(GL_VERTEX_ARRAY); |
||
914 | bglEnableClientState(GL_TEXTURE_COORD_ARRAY); |
||
915 | |||
316 | Plagman | 916 | bglDisable(GL_FOG); |
917 | |||
2032 | plagman | 918 | culledface = GL_BACK; |
919 | bglCullFace(GL_BACK); |
||
5011 | terminx | 920 | bglFrontFace(GL_CCW); |
2032 | plagman | 921 | |
307 | Plagman | 922 | bglEnable(GL_CULL_FACE); |
99 | terminx | 923 | } |
286 | terminx | 924 | |
1596 | plagman | 925 | void polymer_resetlights(void) |
926 | { |
||
927 | int32_t i; |
||
928 | _prsector *s; |
||
929 | _prwall *w; |
||
930 | |||
931 | i = 0; |
||
932 | while (i < numsectors) |
||
933 | { |
||
934 | s = prsectors[i]; |
||
935 | |||
936 | if (!s) { |
||
937 | i++; |
||
938 | continue; |
||
939 | } |
||
940 | |||
941 | polymer_resetplanelights(&s->floor); |
||
942 | polymer_resetplanelights(&s->ceil); |
||
943 | |||
944 | i++; |
||
945 | } |
||
946 | |||
947 | i = 0; |
||
948 | while (i < numwalls) |
||
949 | { |
||
950 | w = prwalls[i]; |
||
951 | |||
952 | if (!w) { |
||
953 | i++; |
||
954 | continue; |
||
955 | } |
||
956 | |||
957 | polymer_resetplanelights(&w->wall); |
||
958 | polymer_resetplanelights(&w->over); |
||
959 | polymer_resetplanelights(&w->mask); |
||
960 | |||
961 | i++; |
||
962 | } |
||
963 | |||
964 | i = 0; |
||
965 | while (i < PR_MAXLIGHTS) |
||
966 | { |
||
967 | prlights[i].flags.active = 0; |
||
968 | i++; |
||
969 | } |
||
970 | |||
971 | lightcount = 0; |
||
1652 | terminx | 972 | |
2236 | helixhorne | 973 | if (!loadmaphack(NULL)) |
974 | OSD_Printf("polymer_resetlights: reloaded maphack\n"); |
||
1596 | plagman | 975 | } |
976 | |||
304 | Plagman | 977 | void polymer_loadboard(void) |
286 | terminx | 978 | { |
1212 | plagman | 979 | int32_t i; |
286 | terminx | 980 | |
1390 | terminx | 981 | polymer_freeboard(); |
1385 | terminx | 982 | |
304 | Plagman | 983 | i = 0; |
984 | while (i < numsectors) |
||
985 | { |
||
986 | polymer_initsector(i); |
||
987 | polymer_updatesector(i); |
||
988 | i++; |
||
989 | } |
||
990 | |||
991 | i = 0; |
||
992 | while (i < numwalls) |
||
993 | { |
||
994 | polymer_initwall(i); |
||
995 | polymer_updatewall(i); |
||
996 | i++; |
||
997 | } |
||
998 | |||
320 | Plagman | 999 | polymer_getsky(); |
1000 | |||
1397 | plagman | 1001 | polymer_resetlights(); |
1002 | |||
1645 | terminx | 1003 | if (pr_verbosity >= 1 && numsectors) OSD_Printf("PR : Board loaded.\n"); |
304 | Plagman | 1004 | } |
662 | plagman | 1005 | |
3977 | helixhorne | 1006 | // The parallaxed ART sky angle divisor corresponding to a horizfrac of 32768. |
1007 | #define DEFAULT_ARTSKY_ANGDIV 4.3027f |
||
1008 | |||
1205 | terminx | 1009 | void polymer_drawrooms(int32_t daposx, int32_t daposy, int32_t daposz, int16_t daang, int32_t dahoriz, int16_t dacursectnum) |
304 | Plagman | 1010 | { |
1212 | plagman | 1011 | int16_t cursectnum; |
1291 | plagman | 1012 | int32_t i, cursectflorz, cursectceilz; |
1374 | plagman | 1013 | float skyhoriz, ang, tiltang; |
696 | plagman | 1014 | float pos[3]; |
1374 | plagman | 1015 | pthtyp* pth; |
304 | Plagman | 1016 | |
3784 | terminx | 1017 | if (getrendermode() == REND_CLASSIC) return; |
1337 | terminx | 1018 | |
1019 | begindrawing(); |
||
1020 | |||
1338 | terminx | 1021 | // TODO: support for screen resizing |
1022 | // frameoffset = frameplace + windowy1*bytesperline + windowx1; |
||
1023 | |||
304 | Plagman | 1024 | if (pr_verbosity >= 3) OSD_Printf("PR : Drawing rooms...\n"); |
1025 | |||
1298 | plagman | 1026 | // fogcalc needs this |
1027 | gvisibility = ((float)globalvisibility)*FOGSCALE; |
||
1028 | |||
310 | Plagman | 1029 | ang = (float)(daang) / (2048.0f / 360.0f); |
1223 | plagman | 1030 | horizang = (float)(-getangle(128, dahoriz-100)) / (2048.0f / 360.0f); |
310 | Plagman | 1031 | tiltang = (gtang * 90.0f); |
1032 | |||
1457 | terminx | 1033 | pos[0] = (float)daposy; |
697 | plagman | 1034 | pos[1] = -(float)(daposz) / 16.0f; |
1457 | terminx | 1035 | pos[2] = -(float)daposx; |
310 | Plagman | 1036 | |
1397 | plagman | 1037 | polymer_updatelights(); |
1304 | plagman | 1038 | |
1397 | plagman | 1039 | // polymer_resetlights(); |
1040 | // if (pr_lighting) |
||
1041 | // polymer_applylights(); |
||
1042 | |||
1268 | plagman | 1043 | depth = 0; |
1044 | |||
1332 | plagman | 1045 | if (pr_shadows && lightcount && (pr_shadowcount > 0)) |
1307 | plagman | 1046 | polymer_prepareshadows(); |
1047 | |||
1374 | plagman | 1048 | // hack for parallax skies |
1049 | skyhoriz = horizang; |
||
1050 | if (skyhoriz < -180.0f) |
||
1051 | skyhoriz += 360.0f; |
||
1052 | |||
1053 | drawingskybox = 1; |
||
4600 | terminx | 1054 | pth = texcache_fetch(cursky, 0, 0, 0); |
1374 | plagman | 1055 | drawingskybox = 0; |
1056 | |||
1057 | // if it's not a skybox, make the sky parallax |
||
3977 | helixhorne | 1058 | // DEFAULT_ARTSKY_ANGDIV is computed from eyeballed values |
1374 | plagman | 1059 | // need to recompute it if we ever change the max horiz amplitude |
4486 | helixhorne | 1060 | if (!pth || !(pth->flags & PTH_SKYBOX)) |
3977 | helixhorne | 1061 | skyhoriz *= curskyangmul; |
1374 | plagman | 1062 | |
310 | Plagman | 1063 | bglMatrixMode(GL_MODELVIEW); |
1064 | bglLoadIdentity(); |
||
1065 | |||
311 | Plagman | 1066 | bglRotatef(tiltang, 0.0f, 0.0f, -1.0f); |
1374 | plagman | 1067 | bglRotatef(skyhoriz, 1.0f, 0.0f, 0.0f); |
310 | Plagman | 1068 | bglRotatef(ang, 0.0f, 1.0f, 0.0f); |
1069 | |||
1373 | plagman | 1070 | bglScalef(1.0f / 1000.0f, 1.0f / 1000.0f, 1.0f / 1000.0f); |
1071 | bglTranslatef(-pos[0], -pos[1], -pos[2]); |
||
316 | Plagman | 1072 | |
1373 | plagman | 1073 | bglGetFloatv(GL_MODELVIEW_MATRIX, rootskymodelviewmatrix); |
4600 | terminx | 1074 | |
1373 | plagman | 1075 | curskymodelviewmatrix = rootskymodelviewmatrix; |
1076 | |||
1077 | bglMatrixMode(GL_MODELVIEW); |
||
1078 | bglLoadIdentity(); |
||
1079 | |||
1080 | bglRotatef(tiltang, 0.0f, 0.0f, -1.0f); |
||
1081 | bglRotatef(horizang, 1.0f, 0.0f, 0.0f); |
||
1082 | bglRotatef(ang, 0.0f, 1.0f, 0.0f); |
||
1083 | |||
697 | plagman | 1084 | bglScalef(1.0f / 1000.0f, 1.0f / 1000.0f, 1.0f / 1000.0f); |
595 | plagman | 1085 | bglTranslatef(-pos[0], -pos[1], -pos[2]); |
310 | Plagman | 1086 | |
1211 | plagman | 1087 | bglGetFloatv(GL_MODELVIEW_MATRIX, rootmodelviewmatrix); |
525 | Plagman | 1088 | |
689 | plagman | 1089 | cursectnum = dacursectnum; |
3037 | helixhorne | 1090 | updatesectorbreadth(daposx, daposy, &cursectnum); |
1091 | |||
1092 | if (cursectnum >= 0 && cursectnum < numsectors) |
||
689 | plagman | 1093 | dacursectnum = cursectnum; |
2256 | helixhorne | 1094 | else if (pr_verbosity>=2) |
1095 | OSD_Printf("PR : got sector %d after update!\n", cursectnum); |
||
689 | plagman | 1096 | |
717 | plagman | 1097 | // unflag all sectors |
1425 | terminx | 1098 | i = numsectors-1; |
1099 | while (i >= 0) |
||
717 | plagman | 1100 | { |
1428 | plagman | 1101 | prsectors[i]->flags.uptodate = 0; |
717 | plagman | 1102 | prsectors[i]->wallsproffset = 0.0f; |
1103 | prsectors[i]->floorsproffset = 0.0f; |
||
1425 | terminx | 1104 | i--; |
717 | plagman | 1105 | } |
1425 | terminx | 1106 | i = numwalls-1; |
1107 | while (i >= 0) |
||
717 | plagman | 1108 | { |
1428 | plagman | 1109 | prwalls[i]->flags.uptodate = 0; |
1425 | terminx | 1110 | i--; |
717 | plagman | 1111 | } |
1112 | |||
1554 | plagman | 1113 | if (searchit == 2 && !polymersearching) |
1114 | { |
||
1115 | globaloldoverridematerial = overridematerial; |
||
1116 | overridematerial = prprogrambits[PR_BIT_DIFFUSE_MODULATION].bit; |
||
1758 | plagman | 1117 | overridematerial |= prprogrambits[PR_BIT_DIFFUSE_MAP2].bit; |
1554 | plagman | 1118 | polymersearching = TRUE; |
1119 | } |
||
1120 | if (!searchit && polymersearching) { |
||
1121 | overridematerial = globaloldoverridematerial; |
||
1122 | polymersearching = FALSE; |
||
1123 | } |
||
1124 | |||
1657 | terminx | 1125 | if (dacursectnum > -1 && dacursectnum < numsectors) |
1126 | getzsofslope(dacursectnum, daposx, daposy, &cursectceilz, &cursectflorz); |
||
1291 | plagman | 1127 | |
689 | plagman | 1128 | // external view (editor) |
717 | plagman | 1129 | if ((dacursectnum < 0) || (dacursectnum >= numsectors) || |
1291 | plagman | 1130 | (daposz > cursectflorz) || |
1131 | (daposz < cursectceilz)) |
||
311 | Plagman | 1132 | { |
2256 | helixhorne | 1133 | if (!editstatus && pr_verbosity>=1) |
2565 | helixhorne | 1134 | { |
1135 | if ((unsigned)dacursectnum < (unsigned)numsectors) |
||
1136 | OSD_Printf("PR : EXT sec=%d z=%d (%d, %d)\n", dacursectnum, daposz, cursectflorz, cursectceilz); |
||
1137 | else |
||
2566 | helixhorne | 1138 | OSD_Printf("PR : EXT sec=%d z=%d\n", dacursectnum, daposz); |
2565 | helixhorne | 1139 | } |
2256 | helixhorne | 1140 | |
1569 | plagman | 1141 | curmodelviewmatrix = rootmodelviewmatrix; |
1425 | terminx | 1142 | i = numsectors-1; |
1143 | while (i >= 0) |
||
311 | Plagman | 1144 | { |
1145 | polymer_updatesector(i); |
||
1980 | plagman | 1146 | polymer_drawsector(i, FALSE); |
697 | plagman | 1147 | polymer_scansprites(i, tsprite, &spritesortcnt); |
1425 | terminx | 1148 | i--; |
311 | Plagman | 1149 | } |
1150 | |||
1425 | terminx | 1151 | i = numwalls-1; |
1152 | while (i >= 0) |
||
311 | Plagman | 1153 | { |
1154 | polymer_updatewall(i); |
||
699 | plagman | 1155 | polymer_drawwall(sectorofwall(i), i); |
1425 | terminx | 1156 | i--; |
320 | Plagman | 1157 | } |
696 | plagman | 1158 | viewangle = daang; |
1337 | terminx | 1159 | enddrawing(); |
320 | Plagman | 1160 | return; |
1161 | } |
||
331 | terminx | 1162 | |
696 | plagman | 1163 | // GO! |
1164 | polymer_displayrooms(dacursectnum); |
||
525 | Plagman | 1165 | |
1224 | plagman | 1166 | curmodelviewmatrix = rootmodelviewmatrix; |
1167 | |||
1168 | // build globals used by rotatesprite |
||
696 | plagman | 1169 | viewangle = daang; |
3471 | helixhorne | 1170 | set_globalang(daang); |
662 | plagman | 1171 | |
1224 | plagman | 1172 | // polymost globals used by polymost_dorotatesprite |
4600 | terminx | 1173 | gcosang = ((float)cosglobalang)/262144.f; |
1174 | gsinang = ((float)singlobalang)/262144.f; |
||
1175 | gcosang2 = gcosang*((float)viewingrange)/65536.f; |
||
1176 | gsinang2 = gsinang*((float)viewingrange)/65536.f; |
||
1224 | plagman | 1177 | |
551 | Plagman | 1178 | if (pr_verbosity >= 3) OSD_Printf("PR : Rooms drawn.\n"); |
1337 | terminx | 1179 | enddrawing(); |
525 | Plagman | 1180 | } |
1181 | |||
666 | plagman | 1182 | void polymer_drawmasks(void) |
1183 | { |
||
670 | plagman | 1184 | bglEnable(GL_ALPHA_TEST); |
1185 | bglEnable(GL_BLEND); |
||
1980 | plagman | 1186 | // bglEnable(GL_POLYGON_OFFSET_FILL); |
670 | plagman | 1187 | |
1980 | plagman | 1188 | // while (--spritesortcnt) |
1189 | // { |
||
1190 | // tspriteptr[spritesortcnt] = &tsprite[spritesortcnt]; |
||
1191 | // polymer_drawsprite(spritesortcnt); |
||
1192 | // } |
||
1193 | |||
1990 | plagman | 1194 | bglEnable(GL_CULL_FACE); |
1195 | |||
1982 | plagman | 1196 | if (cursectormaskcount) { |
1197 | // We (kind of) queue sector masks near to far, so drawing them in reverse |
||
1198 | // order is the sane approach here. Of course impossible cases will arise. |
||
1199 | while (*cursectormaskcount) { |
||
1200 | polymer_drawsector(cursectormasks[--(*cursectormaskcount)], TRUE); |
||
1201 | } |
||
1202 | |||
1203 | // This should _always_ be called after a corresponding pr_displayrooms() |
||
1204 | // unless we're in "external view" mode, which was checked above. |
||
1205 | // Both the top-level game drawrooms and the recursive internal passes |
||
1206 | // should be accounted for here. If these free cause corruption, there's |
||
1207 | // an accounting bug somewhere. |
||
1208 | Bfree(cursectormaskcount); |
||
1209 | cursectormaskcount = NULL; |
||
1210 | Bfree(cursectormasks); |
||
1211 | cursectormasks = NULL; |
||
666 | plagman | 1212 | } |
670 | plagman | 1213 | |
1990 | plagman | 1214 | bglDisable(GL_CULL_FACE); |
1215 | |||
1980 | plagman | 1216 | // bglDisable(GL_POLYGON_OFFSET_FILL); |
670 | plagman | 1217 | bglDisable(GL_BLEND); |
1218 | bglDisable(GL_ALPHA_TEST); |
||
666 | plagman | 1219 | } |
1220 | |||
1554 | plagman | 1221 | void polymer_editorpick(void) |
1222 | { |
||
1223 | GLubyte picked[3]; |
||
1224 | int16_t num; |
||
1225 | |||
1226 | bglReadPixels(searchx, ydim - searchy, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, picked); |
||
1227 | |||
1228 | num = *(int16_t *)(&picked[1]); |
||
1229 | |||
1230 | searchstat = picked[0]; |
||
1231 | |||
1232 | switch (searchstat) { |
||
1233 | case 0: // wall |
||
1794 | plagman | 1234 | case 5: // botomwall |
1554 | plagman | 1235 | case 4: // 1-way/masked wall |
1575 | plagman | 1236 | searchsector = sectorofwall(num); |
1554 | plagman | 1237 | searchbottomwall = searchwall = num; |
1848 | helixhorne | 1238 | searchisbottom = (searchstat==5); |
1794 | plagman | 1239 | if (searchstat == 5) { |
1240 | searchstat = 0; |
||
1241 | if (wall[num].nextwall >= 0 && (wall[num].cstat & 2)) { |
||
1242 | searchbottomwall = wall[num].nextwall; |
||
1243 | } |
||
1244 | } |
||
1554 | plagman | 1245 | break; |
1246 | case 1: // floor |
||
1247 | case 2: // ceiling |
||
1248 | searchsector = num; |
||
1710 | helixhorne | 1249 | |
1250 | // Apologies to Plagman for littering here, but this feature is quite essential |
||
1251 | { |
||
1252 | GLdouble model[16]; |
||
1253 | GLdouble proj[16]; |
||
1254 | GLint view[4]; |
||
1255 | |||
1256 | GLdouble x,y,z; |
||
1257 | GLfloat scr[3], scrv[3]; |
||
1258 | GLdouble scrx,scry,scrz; |
||
1259 | GLfloat dadepth; |
||
1260 | |||
1261 | int16_t k, bestk=0; |
||
3178 | helixhorne | 1262 | GLfloat bestwdistsq = (GLfloat)3.4e38, wdistsq; |
1710 | helixhorne | 1263 | GLfloat w1[2], w2[2], w21[2], pw1[2], pw2[2]; |
1264 | GLfloat ptonline[2]; |
||
1265 | GLfloat scrvxz[2]; |
||
1266 | GLfloat scrvxznorm, scrvxzn[2], scrpxz[2]; |
||
1267 | GLfloat w1d, w2d; |
||
1268 | walltype *wal = &wall[sector[searchsector].wallptr]; |
||
1269 | |||
1270 | GLfloat t, svcoeff, p[2]; |
||
1271 | GLfloat *pl; |
||
1272 | |||
1273 | bglGetDoublev(GL_MODELVIEW_MATRIX, model); |
||
1274 | bglGetDoublev(GL_PROJECTION_MATRIX, proj); |
||
1275 | bglGetIntegerv(GL_VIEWPORT, view); |
||
1276 | |||
1277 | bglReadPixels(searchx, ydim-searchy, 1,1, GL_DEPTH_COMPONENT, GL_FLOAT, &dadepth); |
||
1278 | bgluUnProject(searchx, ydim-searchy, dadepth, model, proj, view, &x, &y, &z); |
||
1279 | bgluUnProject(searchx, ydim-searchy, 0.0, model, proj, view, &scrx, &scry, &scrz); |
||
1280 | |||
1281 | scr[0]=scrx, scr[1]=scry, scr[2]=scrz; |
||
1282 | |||
1283 | scrv[0] = x-scrx; |
||
1284 | scrv[1] = y-scry; |
||
1285 | scrv[2] = z-scrz; |
||
1286 | |||
1287 | scrvxz[0] = x-scrx; |
||
1288 | scrvxz[1] = z-scrz; |
||
1289 | |||
1843 | helixhorne | 1290 | if (prsectors[searchsector]==NULL) |
1291 | { |
||
1292 | //OSD_Printf("polymer_editorpick: prsectors[searchsector]==NULL !!!\n"); |
||
1293 | searchwall = sector[num].wallptr; |
||
1294 | } |
||
1710 | helixhorne | 1295 | else |
1843 | helixhorne | 1296 | { |
1297 | if (searchstat==1) |
||
2610 | helixhorne | 1298 | pl = prsectors[searchsector]->ceil.plane; |
1843 | helixhorne | 1299 | else |
2610 | helixhorne | 1300 | pl = prsectors[searchsector]->floor.plane; |
1710 | helixhorne | 1301 | |
2610 | helixhorne | 1302 | if (pl == NULL) |
1303 | { |
||
1304 | searchwall = sector[num].wallptr; |
||
1305 | return; |
||
1306 | } |
||
1307 | |||
1843 | helixhorne | 1308 | t = dot3f(pl,scrv); |
1309 | svcoeff = -(dot3f(pl,scr)+pl[3])/t; |
||
1710 | helixhorne | 1310 | |
1843 | helixhorne | 1311 | // point on plane (x and z) |
1312 | p[0] = scrx + svcoeff*scrv[0]; |
||
1313 | p[1] = scrz + svcoeff*scrv[2]; |
||
1710 | helixhorne | 1314 | |
1843 | helixhorne | 1315 | for (k=0; k<sector[searchsector].wallnum; k++) |
1316 | { |
||
1317 | w1[1] = -(float)wal[k].x; |
||
1318 | w1[0] = (float)wal[k].y; |
||
1319 | w2[1] = -(float)wall[wal[k].point2].x; |
||
1320 | w2[0] = (float)wall[wal[k].point2].y; |
||
1710 | helixhorne | 1321 | |
1843 | helixhorne | 1322 | scrvxznorm = sqrt(dot2f(scrvxz,scrvxz)); |
1323 | scrvxzn[0] = scrvxz[1]/scrvxznorm; |
||
1324 | scrvxzn[1] = -scrvxz[0]/scrvxznorm; |
||
1710 | helixhorne | 1325 | |
1843 | helixhorne | 1326 | relvec2f(p,w1, pw1); |
1327 | relvec2f(p,w2, pw2); |
||
1328 | relvec2f(w2,w1, w21); |
||
1710 | helixhorne | 1329 | |
1843 | helixhorne | 1330 | w1d = dot2f(scrvxzn,pw1); |
1331 | w2d = dot2f(scrvxzn,pw2); |
||
1332 | w2d = -w2d; |
||
1333 | if (w1d <= 0 || w2d <= 0) |
||
1334 | continue; |
||
1710 | helixhorne | 1335 | |
1843 | helixhorne | 1336 | ptonline[0] = w2[0]+(w2d/(w1d+w2d))*w21[0]; |
1337 | ptonline[1] = w2[1]+(w2d/(w1d+w2d))*w21[1]; |
||
1338 | relvec2f(p,ptonline, scrpxz); |
||
1339 | if (dot2f(scrvxz,scrpxz)<0) |
||
1340 | continue; |
||
1710 | helixhorne | 1341 | |
1843 | helixhorne | 1342 | wdistsq = dot2f(scrpxz,scrpxz); |
1343 | if (wdistsq < bestwdistsq) |
||
1344 | { |
||
1345 | bestk = k; |
||
1346 | bestwdistsq = wdistsq; |
||
1347 | } |
||
1710 | helixhorne | 1348 | } |
1843 | helixhorne | 1349 | |
1350 | searchwall = sector[searchsector].wallptr + bestk; |
||
1710 | helixhorne | 1351 | } |
1352 | } |
||
1353 | // :P |
||
1354 | |||
1355 | // searchwall = sector[num].wallptr; |
||
1554 | plagman | 1356 | break; |
1357 | case 3: |
||
1358 | // sprite |
||
1575 | plagman | 1359 | searchsector = sprite[num].sectnum; |
1554 | plagman | 1360 | searchwall = num; |
1361 | break; |
||
1362 | } |
||
1363 | |||
1364 | searchit = 0; |
||
1365 | } |
||
1366 | |||
1812 | plagman | 1367 | void polymer_inb4rotatesprite(int16_t tilenum, char pal, int8_t shade) |
310 | Plagman | 1368 | { |
1812 | plagman | 1369 | _prmaterial rotatespritematerial; |
1370 | |||
4489 | helixhorne | 1371 | polymer_getbuildmaterial(&rotatespritematerial, tilenum, pal, shade, 0, DAMETH_CLAMPED); |
1812 | plagman | 1372 | |
4600 | terminx | 1373 | rotatespritematerialbits = polymer_bindmaterial(&rotatespritematerial, NULL, 0); |
310 | Plagman | 1374 | } |
1375 | |||
1812 | plagman | 1376 | void polymer_postrotatesprite(void) |
1377 | { |
||
1378 | polymer_unbindmaterial(rotatespritematerialbits); |
||
1379 | } |
||
1380 | |||
4600 | terminx | 1381 | static void polymer_drawsearchplane(_prplane *plane, GLubyte *oldcolor, GLubyte modulation, GLubyte *data) |
1382 | { |
||
1383 | if (oldcolor) |
||
1384 | Bmemcpy(oldcolor, plane->material.diffusemodulation, sizeof(GLubyte) * 4); |
||
1385 | |||
1386 | plane->material.diffusemodulation[0] = modulation; |
||
1387 | plane->material.diffusemodulation[1] = ((GLubyte *) data)[0]; |
||
1388 | plane->material.diffusemodulation[2] = ((GLubyte *) data)[1]; |
||
1389 | plane->material.diffusemodulation[3] = 0xFF; |
||
1390 | |||
1391 | polymer_drawplane(plane); |
||
1392 | |||
1393 | if (oldcolor) |
||
1394 | Bmemcpy(plane->material.diffusemodulation, oldcolor, sizeof(GLubyte) * 4); |
||
1395 | |||
1396 | } |
||
1397 | |||
1205 | terminx | 1398 | void polymer_drawmaskwall(int32_t damaskwallcnt) |
310 | Plagman | 1399 | { |
5072 | terminx | 1400 | tsectortype *sec; |
1298 | plagman | 1401 | walltype *wal; |
687 | plagman | 1402 | _prwall *w; |
1554 | plagman | 1403 | GLubyte oldcolor[4]; |
687 | plagman | 1404 | |
1405 | if (pr_verbosity >= 3) OSD_Printf("PR : Masked wall %i...\n", damaskwallcnt); |
||
1406 | |||
5072 | terminx | 1407 | sec = (tsectortype *)§or[sectorofwall(maskwall[damaskwallcnt])]; |
1298 | plagman | 1408 | wal = &wall[maskwall[damaskwallcnt]]; |
687 | plagman | 1409 | w = prwalls[maskwall[damaskwallcnt]]; |
1410 | |||
1255 | plagman | 1411 | bglEnable(GL_CULL_FACE); |
1412 | |||
1554 | plagman | 1413 | if (searchit == 2) { |
4600 | terminx | 1414 | polymer_drawsearchplane(&w->mask, oldcolor, 0x04, (GLubyte *)&maskwall[damaskwallcnt]); |
1978 | plagman | 1415 | } else { |
4460 | helixhorne | 1416 | calc_and_apply_fog(wal->picnum, fogpal_shade(sec, wal->shade), sec->visibility, get_floor_fogpal(sec)); |
4600 | terminx | 1417 | polymer_drawplane(&w->mask); |
1554 | plagman | 1418 | } |
1419 | |||
1255 | plagman | 1420 | bglDisable(GL_CULL_FACE); |
310 | Plagman | 1421 | } |
1422 | |||
1676 | terminx | 1423 | void polymer_drawsprite(int32_t snum) |
1424 | { |
||
1425 | int32_t i, j, cs; |
||
1426 | _prsprite *s; |
||
1397 | plagman | 1427 | |
4898 | terminx | 1428 | tspritetype *const tspr = tspriteptr[snum]; |
5072 | terminx | 1429 | const tsectortype *sec; |
3722 | helixhorne | 1430 | |
1676 | terminx | 1431 | if (pr_verbosity >= 3) OSD_Printf("PR : Sprite %i...\n", snum); |
1405 | plagman | 1432 | |
3717 | helixhorne | 1433 | if (bad_tspr(tspr)) |
1434 | return; |
||
1676 | terminx | 1435 | |
1436 | if ((tspr->cstat & 8192) && (depth && !mirrors[depth-1].plane)) |
||
1437 | return; |
||
1438 | |||
1439 | if ((tspr->cstat & 16384) && (!depth || mirrors[depth-1].plane)) |
||
1440 | return; |
||
1441 | |||
3580 | hendricks2 | 1442 | DO_TILE_ANIM(tspr->picnum, tspr->owner+32768); |
1443 | |||
5072 | terminx | 1444 | sec = (tsectortype *)§or[tspr->sectnum]; |
4460 | helixhorne | 1445 | calc_and_apply_fog(tspr->picnum, fogpal_shade(sec, tspr->shade), sec->visibility, |
5072 | terminx | 1446 | get_floor_fogpal((tsectortype *)§or[tspr->sectnum])); |
1676 | terminx | 1447 | |
1680 | plagman | 1448 | if (usemodels && tile2model[Ptile2tile(tspr->picnum,tspr->pal)].modelid >= 0 && |
1449 | tile2model[Ptile2tile(tspr->picnum,tspr->pal)].framenum >= 0 && |
||
1700 | plagman | 1450 | !(spriteext[tspr->owner].flags & SPREXT_NOTMD)) |
1235 | plagman | 1451 | { |
2032 | plagman | 1452 | bglEnable(GL_CULL_FACE); |
1453 | SWITCH_CULL_DIRECTION; |
||
1676 | terminx | 1454 | polymer_drawmdsprite(tspr); |
2032 | plagman | 1455 | SWITCH_CULL_DIRECTION; |
1456 | bglDisable(GL_CULL_FACE); |
||
1676 | terminx | 1457 | return; |
1458 | } |
||
1459 | |||
1460 | cs = tspr->cstat; |
||
1461 | |||
1681 | plagman | 1462 | // I think messing with the tspr is safe at this point? |
1463 | // If not, change that to modify a temp position in updatesprite itself. |
||
1464 | // I don't think this flags are meant to change on the fly so it'd possibly |
||
1465 | // be safe to cache a plane that has them applied. |
||
1466 | if (spriteext[tspr->owner].flags & SPREXT_AWAY1) |
||
1467 | { |
||
1468 | tspr->x += sintable[(tspr->ang + 512) & 2047] >> 13; |
||
1469 | tspr->y += sintable[tspr->ang & 2047] >> 13; |
||
1470 | } |
||
1471 | else if (spriteext[tspr->owner].flags & SPREXT_AWAY2) |
||
1472 | { |
||
1473 | tspr->x -= sintable[(tspr->ang + 512) & 2047] >> 13; |
||
1474 | tspr->y -= sintable[tspr->ang & 2047] >> 13; |
||
1475 | } |
||
1476 | |||
1676 | terminx | 1477 | polymer_updatesprite(snum); |
1478 | |||
3722 | helixhorne | 1479 | Bassert(tspr->owner < MAXSPRITES); |
1480 | s = prsprites[tspr->owner]; |
||
1481 | |||
1482 | if (s == NULL) |
||
1676 | terminx | 1483 | return; |
1484 | |||
1485 | switch ((tspr->cstat>>4) & 3) |
||
1486 | { |
||
1487 | case 1: |
||
1488 | prsectors[tspr->sectnum]->wallsproffset += 0.5f; |
||
1489 | if (!depth || mirrors[depth-1].plane) |
||
1490 | bglPolygonOffset(-1.0f, -1.0f); |
||
1491 | break; |
||
1492 | case 2: |
||
1493 | prsectors[tspr->sectnum]->floorsproffset += 0.5f; |
||
1494 | if (!depth || mirrors[depth-1].plane) |
||
1495 | bglPolygonOffset(-1.0f, -1.0f); |
||
1496 | break; |
||
1497 | } |
||
1498 | |||
1499 | if ((cs & 48) == 0) |
||
1500 | { |
||
1501 | int32_t curpriority = 0; |
||
1502 | |||
1503 | s->plane.lightcount = 0; |
||
1504 | |||
1505 | while ((curpriority < pr_maxlightpriority) && (!depth || mirrors[depth-1].plane)) |
||
1405 | plagman | 1506 | { |
1676 | terminx | 1507 | i = j = 0; |
1508 | while (j < lightcount) |
||
1509 | { |
||
1680 | plagman | 1510 | while (!prlights[i].flags.active) |
1511 | i++; |
||
1405 | plagman | 1512 | |
1680 | plagman | 1513 | if (prlights[i].priority != curpriority) |
1514 | { |
||
1515 | i++; |
||
1516 | j++; |
||
1517 | continue; |
||
1518 | } |
||
1519 | |||
1676 | terminx | 1520 | if (polymer_planeinlight(&s->plane, &prlights[i])) |
1680 | plagman | 1521 | s->plane.lights[s->plane.lightcount++] = i; |
1522 | |||
1405 | plagman | 1523 | i++; |
1524 | j++; |
||
1525 | } |
||
1676 | terminx | 1526 | curpriority++; |
1397 | plagman | 1527 | } |
1235 | plagman | 1528 | } |
1529 | |||
3869 | helixhorne | 1530 | if ((tspr->cstat & 64) && (tspr->cstat & SPR_ALIGN_MASK)) |
1531 | { |
||
1532 | if ((tspr->cstat & SPR_ALIGN_MASK)==SPR_FLOOR && (tspr->cstat & SPR_YFLIP)) |
||
1533 | SWITCH_CULL_DIRECTION; |
||
691 | plagman | 1534 | bglEnable(GL_CULL_FACE); |
3869 | helixhorne | 1535 | } |
691 | plagman | 1536 | |
1676 | terminx | 1537 | if ((!depth || mirrors[depth-1].plane) && !pr_ati_nodepthoffset) |
1274 | plagman | 1538 | bglEnable(GL_POLYGON_OFFSET_FILL); |
774 | plagman | 1539 | |
1676 | terminx | 1540 | polymer_drawplane(&s->plane); |
667 | plagman | 1541 | |
1676 | terminx | 1542 | if ((!depth || mirrors[depth-1].plane) && !pr_ati_nodepthoffset) |
1274 | plagman | 1543 | bglDisable(GL_POLYGON_OFFSET_FILL); |
774 | plagman | 1544 | |
3869 | helixhorne | 1545 | if ((tspr->cstat & 64) && (tspr->cstat & SPR_ALIGN_MASK)) |
1546 | { |
||
1547 | if ((tspr->cstat & SPR_ALIGN_MASK)==SPR_FLOOR && (tspr->cstat & SPR_YFLIP)) |
||
1548 | SWITCH_CULL_DIRECTION; |
||
691 | plagman | 1549 | bglDisable(GL_CULL_FACE); |
3869 | helixhorne | 1550 | } |
310 | Plagman | 1551 | } |
1552 | |||
1205 | terminx | 1553 | void polymer_setanimatesprites(animatespritesptr animatesprites, int32_t x, int32_t y, int32_t a, int32_t smoothratio) |
697 | plagman | 1554 | { |
1555 | asi.animatesprites = animatesprites; |
||
1556 | asi.x = x; |
||
1557 | asi.y = y; |
||
1558 | asi.a = a; |
||
1559 | asi.smoothratio = smoothratio; |
||
1560 | } |
||
1561 | |||
1397 | plagman | 1562 | int16_t polymer_addlight(_prlight* light) |
1563 | { |
||
1457 | terminx | 1564 | int32_t lighti; |
1397 | plagman | 1565 | |
1425 | terminx | 1566 | if (lightcount >= PR_MAXLIGHTS || light->priority > pr_maxlightpriority || !pr_lighting) |
1417 | plagman | 1567 | return (-1); |
1568 | |||
1397 | plagman | 1569 | if ((light->sector == -1) || (light->sector >= numsectors)) |
1570 | return (-1); |
||
1571 | |||
1572 | lighti = 0; |
||
1676 | terminx | 1573 | while ((lighti < PR_MAXLIGHTS) && (prlights[lighti].flags.active)) |
1397 | plagman | 1574 | lighti++; |
1575 | |||
1576 | if (lighti == PR_MAXLIGHTS) |
||
1577 | return (-1); |
||
3381 | helixhorne | 1578 | #if 0 |
3027 | helixhorne | 1579 | // Spot lights disabled on ATI cards because they cause crashes with |
1580 | // Catalyst 12.8 drivers. |
||
1581 | // See: http://forums.duke4.net/topic/5723-hrp-polymer-crash/ |
||
1582 | if (pr_ati_fboworkaround && light->radius) |
||
1583 | return (-1); |
||
3381 | helixhorne | 1584 | #endif |
1425 | terminx | 1585 | Bmemcpy(&prlights[lighti], light, sizeof(_prlight)); |
1397 | plagman | 1586 | |
3093 | Plagman | 1587 | if (light->radius) { |
1397 | plagman | 1588 | polymer_processspotlight(&prlights[lighti]); |
1589 | |||
2058 | plagman | 1590 | // get the texture handle for the lightmap |
1591 | if (light->tilenum > 0) { |
||
1592 | int16_t picnum = light->tilenum; |
||
1593 | pthtyp* pth; |
||
1594 | |||
3186 | helixhorne | 1595 | DO_TILE_ANIM(picnum, 0); |
2058 | plagman | 1596 | |
1597 | if (!waloff[picnum]) |
||
1598 | loadtile(picnum); |
||
1599 | |||
1600 | pth = NULL; |
||
3761 | terminx | 1601 | pth = texcache_fetch(picnum, 0, 0, 0); |
2058 | plagman | 1602 | |
1603 | if (pth) |
||
1604 | light->lightmap = pth->glpic; |
||
1605 | } |
||
1606 | } |
||
1607 | |||
1397 | plagman | 1608 | prlights[lighti].flags.isinview = 0; |
1609 | prlights[lighti].flags.active = 1; |
||
1610 | |||
2069 | helixhorne | 1611 | prlights[lighti].flags.invalidate = 0; |
1612 | |||
1413 | plagman | 1613 | prlights[lighti].planecount = 0; |
1614 | prlights[lighti].planelist = NULL; |
||
1615 | |||
1397 | plagman | 1616 | polymer_culllight(lighti); |
1617 | |||
1618 | lightcount++; |
||
1619 | |||
1620 | return (lighti); |
||
1621 | } |
||
1622 | |||
1623 | void polymer_deletelight(int16_t lighti) |
||
1624 | { |
||
1404 | plagman | 1625 | if (!prlights[lighti].flags.active) |
2236 | helixhorne | 1626 | { |
1627 | #ifdef DEBUGGINGAIDS |
||
2250 | helixhorne | 1628 | if (pr_verbosity >= 2) |
2236 | helixhorne | 1629 | OSD_Printf("PR : Called polymer_deletelight on inactive light\n"); |
1630 | // currently known cases: when reloading maphack lights (didn't set maphacklightcnt=0 |
||
1631 | // but did loadmaphack()->delete_maphack_lights() after polymer_resetlights()) |
||
1632 | #endif |
||
1404 | plagman | 1633 | return; |
2236 | helixhorne | 1634 | } |
1404 | plagman | 1635 | |
1397 | plagman | 1636 | polymer_removelight(lighti); |
1637 | |||
1638 | prlights[lighti].flags.active = 0; |
||
1639 | |||
1640 | lightcount--; |
||
1641 | } |
||
1642 | |||
1425 | terminx | 1643 | void polymer_invalidatelights(void) |
1644 | { |
||
1645 | int32_t i = PR_MAXLIGHTS-1; |
||
1646 | |||
1647 | do |
||
1676 | terminx | 1648 | prlights[i].flags.invalidate = prlights[i].flags.active; |
1425 | terminx | 1649 | while (i--); |
1650 | } |
||
1651 | |||
1428 | plagman | 1652 | void polymer_texinvalidate(void) |
1653 | { |
||
2053 | plagman | 1654 | int32_t i; |
1428 | plagman | 1655 | |
2053 | plagman | 1656 | i = 0; |
1657 | |||
1658 | while (i < MAXSPRITES) { |
||
4303 | helixhorne | 1659 | polymer_invalidatesprite(i); |
2053 | plagman | 1660 | i++; |
1661 | } |
||
1662 | |||
1663 | i = numsectors - 1; |
||
1664 | |||
1676 | terminx | 1665 | if (!numsectors || !prsectors[i]) |
1430 | terminx | 1666 | return; |
2053 | plagman | 1667 | |
1676 | terminx | 1668 | do |
1669 | prsectors[i--]->flags.invalidtex = 1; |
||
1670 | while (i >= 0); |
||
1430 | terminx | 1671 | |
2053 | plagman | 1672 | i = numwalls - 1; |
1676 | terminx | 1673 | do |
1674 | prwalls[i--]->flags.invalidtex = 1; |
||
1675 | while (i >= 0); |
||
1428 | plagman | 1676 | } |
1677 | |||
1782 | plagman | 1678 | void polymer_definehighpalookup(char basepalnum, char palnum, char *data) |
1748 | plagman | 1679 | { |
4491 | helixhorne | 1680 | prhighpalookups[basepalnum][palnum].data = (char *)Xmalloc(PR_HIGHPALOOKUP_DATA_SIZE); |
1748 | plagman | 1681 | |
1782 | plagman | 1682 | Bmemcpy(prhighpalookups[basepalnum][palnum].data, data, PR_HIGHPALOOKUP_DATA_SIZE); |
1748 | plagman | 1683 | } |
1684 | |||
2056 | plagman | 1685 | int32_t polymer_havehighpalookup(int32_t basepalnum, int32_t palnum) |
2045 | helixhorne | 1686 | { |
1687 | if ((uint32_t)basepalnum >= MAXBASEPALS || (uint32_t)palnum >= MAXPALOOKUPS) |
||
1688 | return 0; |
||
1689 | |||
1690 | return (prhighpalookups[basepalnum][palnum].data != NULL); |
||
1691 | } |
||
1692 | |||
1693 | |||
696 | plagman | 1694 | // CORE |
4600 | terminx | 1695 | static void polymer_displayrooms(const int16_t dacursectnum) |
696 | plagman | 1696 | { |
5072 | terminx | 1697 | tsectortype *sec; |
1252 | plagman | 1698 | int32_t i; |
1975 | plagman | 1699 | int16_t bunchnum; |
1700 | int16_t ns; |
||
696 | plagman | 1701 | GLint result; |
1252 | plagman | 1702 | int16_t doquery; |
1212 | plagman | 1703 | int32_t front; |
1704 | int32_t back; |
||
1373 | plagman | 1705 | GLfloat localskymodelviewmatrix[16]; |
1211 | plagman | 1706 | GLfloat localmodelviewmatrix[16]; |
1268 | plagman | 1707 | GLfloat localprojectionmatrix[16]; |
696 | plagman | 1708 | float frustum[5 * 4]; |
1212 | plagman | 1709 | int32_t localspritesortcnt; |
4898 | terminx | 1710 | tspritetype localtsprite[MAXSPRITESONSCREEN]; |
1313 | plagman | 1711 | int16_t localmaskwall[MAXWALLSB]; |
1312 | terminx | 1712 | int16_t localmaskwallcnt; |
1255 | plagman | 1713 | _prmirror mirrorlist[10]; |
1714 | int mirrorcount; |
||
1980 | plagman | 1715 | int16_t *localsectormasks; |
1716 | int16_t *localsectormaskcount; |
||
1255 | plagman | 1717 | int32_t gx, gy, gz, px, py, pz; |
1718 | GLdouble plane[4]; |
||
1719 | float coeff; |
||
696 | plagman | 1720 | |
1268 | plagman | 1721 | curmodelviewmatrix = localmodelviewmatrix; |
1722 | bglGetFloatv(GL_MODELVIEW_MATRIX, localmodelviewmatrix); |
||
1723 | bglGetFloatv(GL_PROJECTION_MATRIX, localprojectionmatrix); |
||
696 | plagman | 1724 | |
1268 | plagman | 1725 | polymer_extractfrustum(localmodelviewmatrix, localprojectionmatrix, frustum); |
696 | plagman | 1726 | |
1332 | plagman | 1727 | Bmemset(querydelay, 0, sizeof(int16_t) * numsectors); |
1728 | Bmemset(queryid, 0, sizeof(GLuint) * numwalls); |
||
1729 | Bmemset(drawingstate, 0, sizeof(int16_t) * numsectors); |
||
696 | plagman | 1730 | |
1731 | front = 0; |
||
1252 | plagman | 1732 | back = 1; |
1733 | sectorqueue[0] = dacursectnum; |
||
696 | plagman | 1734 | drawingstate[dacursectnum] = 1; |
1735 | |||
1252 | plagman | 1736 | localspritesortcnt = localmaskwallcnt = 0; |
696 | plagman | 1737 | |
1255 | plagman | 1738 | mirrorcount = 0; |
1739 | |||
4491 | helixhorne | 1740 | localsectormasks = (int16_t *)Xmalloc(sizeof(int16_t) * numsectors); |
1741 | localsectormaskcount = (int16_t *)Xcalloc(sizeof(int16_t), 1); |
||
1980 | plagman | 1742 | cursectormasks = localsectormasks; |
1743 | cursectormaskcount = localsectormaskcount; |
||
1744 | |||
1373 | plagman | 1745 | bglDisable(GL_DEPTH_TEST); |
1746 | bglColor4f(1.0f, 1.0f, 1.0f, 1.0f); |
||
1418 | plagman | 1747 | polymer_drawsky(cursky, curskypal, curskyshade); |
1373 | plagman | 1748 | bglEnable(GL_DEPTH_TEST); |
1749 | |||
1252 | plagman | 1750 | // depth-only occlusion testing pass |
1255 | plagman | 1751 | // overridematerial = 0; |
696 | plagman | 1752 | |
1332 | plagman | 1753 | while (front != back) |
696 | plagman | 1754 | { |
5072 | terminx | 1755 | sec = (tsectortype *)§or[sectorqueue[front]]; |
696 | plagman | 1756 | |
1757 | polymer_pokesector(sectorqueue[front]); |
||
1980 | plagman | 1758 | polymer_drawsector(sectorqueue[front], FALSE); |
697 | plagman | 1759 | polymer_scansprites(sectorqueue[front], localtsprite, &localspritesortcnt); |
696 | plagman | 1760 | |
1252 | plagman | 1761 | doquery = 0; |
696 | plagman | 1762 | |
1425 | terminx | 1763 | i = sec->wallnum-1; |
1412 | terminx | 1764 | do |
696 | plagman | 1765 | { |
1413 | plagman | 1766 | // if we have a level boundary somewhere in the sector, |
1767 | // consider these walls as visportals |
||
1550 | plagman | 1768 | if (wall[sec->wallptr + i].nextsector < 0) |
1413 | plagman | 1769 | doquery = 1; |
1252 | plagman | 1770 | } |
1676 | terminx | 1771 | while (--i >= 0); |
1252 | plagman | 1772 | |
1425 | terminx | 1773 | i = sec->wallnum-1; |
1774 | while (i >= 0) |
||
1252 | plagman | 1775 | { |
1550 | plagman | 1776 | if ((wall[sec->wallptr + i].nextsector >= 0) && |
1394 | plagman | 1777 | (wallvisible(globalposx, globalposy, sec->wallptr + i)) && |
1267 | plagman | 1778 | (polymer_planeinfrustum(&prwalls[sec->wallptr + i]->mask, frustum))) |
696 | plagman | 1779 | { |
1328 | plagman | 1780 | if ((prwalls[sec->wallptr + i]->mask.vertcount == 4) && |
1781 | !(prwalls[sec->wallptr + i]->underover & 4) && |
||
1782 | !(prwalls[sec->wallptr + i]->underover & 8)) |
||
1320 | plagman | 1783 | { |
1328 | plagman | 1784 | // early exit for closed sectors |
1320 | plagman | 1785 | _prwall *w; |
1786 | |||
1787 | w = prwalls[sec->wallptr + i]; |
||
1788 | |||
1789 | if ((w->mask.buffer[(0 * 5) + 1] >= w->mask.buffer[(3 * 5) + 1]) && |
||
1790 | (w->mask.buffer[(1 * 5) + 1] >= w->mask.buffer[(2 * 5) + 1])) |
||
1791 | { |
||
1425 | terminx | 1792 | i--; |
1320 | plagman | 1793 | continue; |
1794 | } |
||
1795 | } |
||
1796 | |||
1979 | plagman | 1797 | if ((wall[sec->wallptr + i].cstat & 48) == 16) |
4830 | helixhorne | 1798 | { |
1799 | int pic = wall[sec->wallptr + i].overpicnum; |
||
1255 | plagman | 1800 | |
4830 | helixhorne | 1801 | if (tilesiz[pic].x > 0 && tilesiz[pic].y > 0) |
1802 | localmaskwall[localmaskwallcnt++] = sec->wallptr + i; |
||
1803 | } |
||
1804 | |||
1277 | plagman | 1805 | if (!depth && (overridematerial & prprogrambits[PR_BIT_MIRROR_MAP].bit) && |
1255 | plagman | 1806 | wall[sec->wallptr + i].overpicnum == 560 && |
1287 | plagman | 1807 | wall[sec->wallptr + i].cstat & 32) |
1255 | plagman | 1808 | { |
1287 | plagman | 1809 | mirrorlist[mirrorcount].plane = &prwalls[sec->wallptr + i]->mask; |
1255 | plagman | 1810 | mirrorlist[mirrorcount].sectnum = sectorqueue[front]; |
1811 | mirrorlist[mirrorcount].wallnum = sec->wallptr + i; |
||
1812 | mirrorcount++; |
||
1813 | } |
||
1814 | |||
1328 | plagman | 1815 | if (!(wall[sec->wallptr + i].cstat & 32)) { |
1816 | if (doquery && (!drawingstate[wall[sec->wallptr + i].nextsector])) |
||
1817 | { |
||
1818 | float pos[3], sqdist; |
||
1819 | int32_t oldoverridematerial; |
||
696 | plagman | 1820 | |
1457 | terminx | 1821 | pos[0] = (float)globalposy; |
1328 | plagman | 1822 | pos[1] = -(float)(globalposz) / 16.0f; |
1457 | terminx | 1823 | pos[2] = -(float)globalposx; |
696 | plagman | 1824 | |
1328 | plagman | 1825 | sqdist = prwalls[sec->wallptr + i]->mask.plane[0] * pos[0] + |
1826 | prwalls[sec->wallptr + i]->mask.plane[1] * pos[1] + |
||
1827 | prwalls[sec->wallptr + i]->mask.plane[2] * pos[2] + |
||
1828 | prwalls[sec->wallptr + i]->mask.plane[3]; |
||
704 | plagman | 1829 | |
1328 | plagman | 1830 | // hack to avoid occlusion querying portals that are too close to the viewpoint |
1831 | // this is needed because of the near z-clipping plane; |
||
1832 | if (sqdist < 100) |
||
1833 | queryid[sec->wallptr + i] = 0xFFFFFFFF; |
||
1834 | else { |
||
1835 | _prwall *w; |
||
1255 | plagman | 1836 | |
1328 | plagman | 1837 | w = prwalls[sec->wallptr + i]; |
1255 | plagman | 1838 | |
1328 | plagman | 1839 | bglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); |
1840 | bglDepthMask(GL_FALSE); |
||
696 | plagman | 1841 | |
1328 | plagman | 1842 | bglGenQueriesARB(1, &queryid[sec->wallptr + i]); |
1843 | bglBeginQueryARB(GL_SAMPLES_PASSED_ARB, queryid[sec->wallptr + i]); |
||
1270 | plagman | 1844 | |
1328 | plagman | 1845 | oldoverridematerial = overridematerial; |
1846 | overridematerial = 0; |
||
1270 | plagman | 1847 | |
1328 | plagman | 1848 | if ((w->underover & 4) && (w->underover & 1)) |
1849 | polymer_drawplane(&w->wall); |
||
1850 | polymer_drawplane(&w->mask); |
||
1851 | if ((w->underover & 8) && (w->underover & 2)) |
||
1852 | polymer_drawplane(&w->over); |
||
1270 | plagman | 1853 | |
1328 | plagman | 1854 | overridematerial = oldoverridematerial; |
1855 | |||
1856 | bglEndQueryARB(GL_SAMPLES_PASSED_ARB); |
||
1857 | |||
1858 | bglDepthMask(GL_TRUE); |
||
1859 | bglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
||
1860 | } |
||
1861 | } else |
||
1993 | plagman | 1862 | queryid[sec->wallptr + i] = 0xFFFFFFFF; |
1328 | plagman | 1863 | } |
1252 | plagman | 1864 | } |
696 | plagman | 1865 | |
1425 | terminx | 1866 | i--; |
1252 | plagman | 1867 | } |
741 | plagman | 1868 | |
1976 | plagman | 1869 | // Cram as much CPU or GPU work as we can between queuing the |
1870 | // occlusion queries and reaping them. |
||
1871 | i = sec->wallnum-1; |
||
1872 | do |
||
1873 | { |
||
1874 | if (wallvisible(globalposx, globalposy, sec->wallptr + i)) |
||
1875 | polymer_drawwall(sectorqueue[front], sec->wallptr + i); |
||
1876 | } |
||
1877 | while (--i >= 0); |
||
2204 | helixhorne | 1878 | #ifdef YAX_ENABLE |
1975 | plagman | 1879 | // queue ROR neighbors |
3658 | helixhorne | 1880 | if ((bunchnum = yax_getbunch(sectorqueue[front], YAX_FLOOR)) >= 0) { |
1975 | plagman | 1881 | |
1882 | for (SECTORS_OF_BUNCH(bunchnum, YAX_CEILING, ns)) { |
||
1883 | |||
1884 | if (ns >= 0 && !drawingstate[ns] && |
||
1885 | polymer_planeinfrustum(&prsectors[ns]->ceil, frustum)) { |
||
1886 | |||
1887 | sectorqueue[back++] = ns; |
||
1888 | drawingstate[ns] = 1; |
||
1889 | } |
||
1890 | } |
||
1891 | } |
||
1892 | |||
3658 | helixhorne | 1893 | if ((bunchnum = yax_getbunch(sectorqueue[front], YAX_CEILING)) >= 0) { |
1975 | plagman | 1894 | |
1895 | for (SECTORS_OF_BUNCH(bunchnum, YAX_FLOOR, ns)) { |
||
1896 | |||
1897 | if (ns >= 0 && !drawingstate[ns] && |
||
1898 | polymer_planeinfrustum(&prsectors[ns]->floor, frustum)) { |
||
1899 | |||
1900 | sectorqueue[back++] = ns; |
||
1901 | drawingstate[ns] = 1; |
||
1902 | } |
||
1903 | } |
||
1904 | } |
||
2204 | helixhorne | 1905 | #endif |
1425 | terminx | 1906 | i = sec->wallnum-1; |
1412 | terminx | 1907 | do |
1252 | plagman | 1908 | { |
1909 | if ((queryid[sec->wallptr + i]) && |
||
1910 | (!drawingstate[wall[sec->wallptr + i].nextsector])) |
||
1911 | { |
||
1912 | // REAP |
||
1913 | result = 0; |
||
1301 | plagman | 1914 | if (doquery && (queryid[sec->wallptr + i] != 0xFFFFFFFF)) |
1252 | plagman | 1915 | { |
1916 | bglGetQueryObjectivARB(queryid[sec->wallptr + i], |
||
1917 | GL_QUERY_RESULT_ARB, |
||
1918 | &result); |
||
1919 | bglDeleteQueriesARB(1, &queryid[sec->wallptr + i]); |
||
1301 | plagman | 1920 | } else if (queryid[sec->wallptr + i] == 0xFFFFFFFF) |
1270 | plagman | 1921 | result = 1; |
1922 | |||
1252 | plagman | 1923 | queryid[sec->wallptr + i] = 0; |
741 | plagman | 1924 | |
1252 | plagman | 1925 | if (result || !doquery) |
1926 | { |
||
1927 | sectorqueue[back++] = wall[sec->wallptr + i].nextsector; |
||
1928 | drawingstate[wall[sec->wallptr + i].nextsector] = 1; |
||
1929 | } |
||
1993 | plagman | 1930 | } else if (queryid[sec->wallptr + i] && |
1931 | queryid[sec->wallptr + i] != 0xFFFFFFFF) |
||
1932 | { |
||
1933 | bglDeleteQueriesARB(1, &queryid[sec->wallptr + i]); |
||
1934 | queryid[sec->wallptr + i] = 0; |
||
1252 | plagman | 1935 | } |
1936 | } |
||
1676 | terminx | 1937 | while (--i >= 0); |
696 | plagman | 1938 | |
1252 | plagman | 1939 | front++; |
1940 | } |
||
696 | plagman | 1941 | |
1252 | plagman | 1942 | // do the actual shaded drawing |
1255 | plagman | 1943 | // overridematerial = 0xFFFFFFFF; |
696 | plagman | 1944 | |
1252 | plagman | 1945 | // go through the sector queue again |
1255 | plagman | 1946 | // front = 0; |
1947 | // while (front < back) |
||
1948 | // { |
||
1949 | // sec = §or[sectorqueue[front]]; |
||
1950 | // |
||
1951 | // polymer_drawsector(sectorqueue[front]); |
||
1952 | // |
||
1953 | // i = 0; |
||
1954 | // while (i < sec->wallnum) |
||
1955 | // { |
||
1956 | // polymer_drawwall(sectorqueue[front], sec->wallptr + i); |
||
1957 | // |
||
1958 | // i++; |
||
1959 | // } |
||
1960 | // |
||
1961 | // front++; |
||
1962 | // } |
||
1963 | |||
1425 | terminx | 1964 | i = mirrorcount-1; |
1965 | while (i >= 0) |
||
1252 | plagman | 1966 | { |
1255 | plagman | 1967 | bglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, prrts[0].fbo); |
1968 | bglPushAttrib(GL_VIEWPORT_BIT); |
||
1505 | plagman | 1969 | bglViewport(windowx1, yres-(windowy2+1),windowx2-windowx1+1, windowy2-windowy1+1); |
1252 | plagman | 1970 | |
1255 | plagman | 1971 | bglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
1252 | plagman | 1972 | |
1373 | plagman | 1973 | Bmemcpy(localskymodelviewmatrix, curskymodelviewmatrix, sizeof(GLfloat) * 16); |
1974 | curskymodelviewmatrix = localskymodelviewmatrix; |
||
1975 | |||
1255 | plagman | 1976 | bglMatrixMode(GL_MODELVIEW); |
1977 | bglPushMatrix(); |
||
1252 | plagman | 1978 | |
1255 | plagman | 1979 | plane[0] = mirrorlist[i].plane->plane[0]; |
1980 | plane[1] = mirrorlist[i].plane->plane[1]; |
||
1981 | plane[2] = mirrorlist[i].plane->plane[2]; |
||
1982 | plane[3] = mirrorlist[i].plane->plane[3]; |
||
1252 | plagman | 1983 | |
1255 | plagman | 1984 | bglClipPlane(GL_CLIP_PLANE0, plane); |
1985 | polymer_inb4mirror(mirrorlist[i].plane->buffer, mirrorlist[i].plane->plane); |
||
2032 | plagman | 1986 | SWITCH_CULL_DIRECTION; |
1373 | plagman | 1987 | //bglEnable(GL_CLIP_PLANE0); |
1255 | plagman | 1988 | |
1989 | if (mirrorlist[i].wallnum >= 0) |
||
3719 | helixhorne | 1990 | preparemirror(globalposx, globalposy, globalang, |
1991 | mirrorlist[i].wallnum, &gx, &gy, &viewangle); |
||
1255 | plagman | 1992 | |
1993 | gx = globalposx; |
||
1994 | gy = globalposy; |
||
1995 | gz = globalposz; |
||
1996 | |||
1997 | // map the player pos from build to polymer |
||
1998 | px = globalposy; |
||
1999 | py = -globalposz / 16; |
||
2000 | pz = -globalposx; |
||
2001 | |||
2002 | // calculate new player position on the other side of the mirror |
||
2003 | // this way the basic build visibility shit can be used (wallvisible) |
||
2004 | coeff = mirrorlist[i].plane->plane[0] * px + |
||
2005 | mirrorlist[i].plane->plane[1] * py + |
||
2006 | mirrorlist[i].plane->plane[2] * pz + |
||
2007 | mirrorlist[i].plane->plane[3]; |
||
2008 | |||
2009 | coeff /= (float)(mirrorlist[i].plane->plane[0] * mirrorlist[i].plane->plane[0] + |
||
2010 | mirrorlist[i].plane->plane[1] * mirrorlist[i].plane->plane[1] + |
||
2011 | mirrorlist[i].plane->plane[2] * mirrorlist[i].plane->plane[2]); |
||
2012 | |||
1457 | terminx | 2013 | px = (int32_t)(-coeff*mirrorlist[i].plane->plane[0]*2 + px); |
2014 | py = (int32_t)(-coeff*mirrorlist[i].plane->plane[1]*2 + py); |
||
2015 | pz = (int32_t)(-coeff*mirrorlist[i].plane->plane[2]*2 + pz); |
||
1255 | plagman | 2016 | |
2017 | // map back from polymer to build |
||
4667 | terminx | 2018 | set_globalpos(-pz, px, -py * 16); |
1255 | plagman | 2019 | |
2020 | mirrors[depth++] = mirrorlist[i]; |
||
2021 | polymer_displayrooms(mirrorlist[i].sectnum); |
||
2022 | depth--; |
||
2023 | |||
1980 | plagman | 2024 | cursectormasks = localsectormasks; |
2025 | cursectormaskcount = localsectormaskcount; |
||
2026 | |||
4667 | terminx | 2027 | set_globalpos(gx, gy, gz); |
1255 | plagman | 2028 | |
2029 | bglDisable(GL_CLIP_PLANE0); |
||
2032 | plagman | 2030 | SWITCH_CULL_DIRECTION; |
1255 | plagman | 2031 | bglMatrixMode(GL_MODELVIEW); |
2032 | bglPopMatrix(); |
||
2033 | |||
2034 | bglPopAttrib(); |
||
2035 | bglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); |
||
2036 | |||
2037 | mirrorlist[i].plane->material.mirrormap = prrts[0].color; |
||
2038 | polymer_drawplane(mirrorlist[i].plane); |
||
2039 | mirrorlist[i].plane->material.mirrormap = 0; |
||
2040 | |||
1425 | terminx | 2041 | i--; |
696 | plagman | 2042 | } |
2043 | |||
697 | plagman | 2044 | spritesortcnt = localspritesortcnt; |
1332 | plagman | 2045 | Bmemcpy(tsprite, localtsprite, sizeof(spritetype) * spritesortcnt); |
697 | plagman | 2046 | maskwallcnt = localmaskwallcnt; |
1332 | plagman | 2047 | Bmemcpy(maskwall, localmaskwall, sizeof(int16_t) * maskwallcnt); |
697 | plagman | 2048 | |
1255 | plagman | 2049 | if (depth) |
2050 | { |
||
3471 | helixhorne | 2051 | set_globalang(viewangle); |
1255 | plagman | 2052 | |
1272 | plagman | 2053 | if (mirrors[depth - 1].plane) |
2054 | display_mirror = 1; |
||
1255 | plagman | 2055 | polymer_animatesprites(); |
1272 | plagman | 2056 | if (mirrors[depth - 1].plane) |
2057 | display_mirror = 0; |
||
1255 | plagman | 2058 | |
2059 | bglDisable(GL_CULL_FACE); |
||
2060 | drawmasks(); |
||
2061 | bglEnable(GL_CULL_FACE); |
||
2062 | } |
||
1252 | plagman | 2063 | return; |
696 | plagman | 2064 | } |
2065 | |||
1255 | plagman | 2066 | static void polymer_drawplane(_prplane* plane) |
696 | plagman | 2067 | { |
1212 | plagman | 2068 | int32_t materialbits; |
699 | plagman | 2069 | |
1241 | plagman | 2070 | // debug code for drawing plane inverse TBN |
2071 | // bglDisable(GL_TEXTURE_2D); |
||
2072 | // bglBegin(GL_LINES); |
||
2073 | // bglColor4f(1.0, 0.0, 0.0, 1.0); |
||
2074 | // bglVertex3f(plane->buffer[0], |
||
2075 | // plane->buffer[1], |
||
2076 | // plane->buffer[2]); |
||
2077 | // bglVertex3f(plane->buffer[0] + plane->t[0] * 50, |
||
2078 | // plane->buffer[1] + plane->t[1] * 50, |
||
2079 | // plane->buffer[2] + plane->t[2] * 50); |
||
2080 | // bglColor4f(0.0, 1.0, 0.0, 1.0); |
||
2081 | // bglVertex3f(plane->buffer[0], |
||
2082 | // plane->buffer[1], |
||
2083 | // plane->buffer[2]); |
||
2084 | // bglVertex3f(plane->buffer[0] + plane->b[0] * 50, |
||
2085 | // plane->buffer[1] + plane->b[1] * 50, |
||
2086 | // plane->buffer[2] + plane->b[2] * 50); |
||
2087 | // bglColor4f(0.0, 0.0, 1.0, 1.0); |
||
2088 | // bglVertex3f(plane->buffer[0], |
||
2089 | // plane->buffer[1], |
||
2090 | // plane->buffer[2]); |
||
2091 | // bglVertex3f(plane->buffer[0] + plane->n[0] * 50, |
||
2092 | // plane->buffer[1] + plane->n[1] * 50, |
||
2093 | // plane->buffer[2] + plane->n[2] * 50); |
||
2094 | // bglEnd(); |
||
2095 | // bglEnable(GL_TEXTURE_2D); |
||
2096 | |||
2097 | // debug code for drawing plane normals |
||
2098 | // bglDisable(GL_TEXTURE_2D); |
||
2099 | // bglBegin(GL_LINES); |
||
2100 | // bglColor4f(1.0, 1.0, 1.0, 1.0); |
||
2101 | // bglVertex3f(plane->buffer[0], |
||
2102 | // plane->buffer[1], |
||
2103 | // plane->buffer[2]); |
||
2104 | // bglVertex3f(plane->buffer[0] + plane->plane[0] * 50, |
||
2105 | // plane->buffer[1] + plane->plane[1] * 50, |
||
2106 | // plane->buffer[2] + plane->plane[2] * 50); |
||
2107 | // bglEnd(); |
||
2108 | // bglEnable(GL_TEXTURE_2D); |
||
2109 | |||
1242 | plagman | 2110 | bglNormal3f((float)(plane->plane[0]), (float)(plane->plane[1]), (float)(plane->plane[2])); |
699 | plagman | 2111 | |
1263 | plagman | 2112 | if (plane->vbo && (pr_vbos > 0)) |
2113 | { |
||
2114 | bglBindBufferARB(GL_ARRAY_BUFFER_ARB, plane->vbo); |
||
2115 | bglVertexPointer(3, GL_FLOAT, 5 * sizeof(GLfloat), NULL); |
||
2116 | bglTexCoordPointer(2, GL_FLOAT, 5 * sizeof(GLfloat), (GLfloat*)(3 * sizeof(GLfloat))); |
||
2117 | if (plane->indices) |
||
2118 | bglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, plane->ivbo); |
||
2119 | } else { |
||
2120 | bglVertexPointer(3, GL_FLOAT, 5 * sizeof(GLfloat), plane->buffer); |
||
2121 | bglTexCoordPointer(2, GL_FLOAT, 5 * sizeof(GLfloat), &plane->buffer[3]); |
||
2122 | } |
||
2123 | |||
1413 | plagman | 2124 | curlight = 0; |
2125 | do { |
||
4600 | terminx | 2126 | materialbits = polymer_bindmaterial(&plane->material, plane->lights, plane->lightcount); |
1242 | plagman | 2127 | |
1244 | plagman | 2128 | if (materialbits & prprogrambits[PR_BIT_NORMAL_MAP].bit) |
2129 | { |
||
1594 | plagman | 2130 | bglVertexAttrib3fvARB(prprograms[materialbits].attrib_T, &plane->tbn[0][0]); |
2131 | bglVertexAttrib3fvARB(prprograms[materialbits].attrib_B, &plane->tbn[1][0]); |
||
2132 | bglVertexAttrib3fvARB(prprograms[materialbits].attrib_N, &plane->tbn[2][0]); |
||
1244 | plagman | 2133 | } |
2134 | |||
1263 | plagman | 2135 | if (plane->indices) |
1242 | plagman | 2136 | { |
1263 | plagman | 2137 | if (plane->vbo && (pr_vbos > 0)) |
2138 | bglDrawElements(GL_TRIANGLES, plane->indicescount, GL_UNSIGNED_SHORT, NULL); |
||
2139 | else |
||
2140 | bglDrawElements(GL_TRIANGLES, plane->indicescount, GL_UNSIGNED_SHORT, plane->indices); |
||
2141 | } else |
||
2142 | bglDrawArrays(GL_QUADS, 0, 4); |
||
1242 | plagman | 2143 | |
2144 | polymer_unbindmaterial(materialbits); |
||
2145 | |||
1397 | plagman | 2146 | if (plane->lightcount && (!depth || mirrors[depth-1].plane)) |
2147 | prlights[plane->lights[curlight]].flags.isinview = 1; |
||
2148 | |||
1242 | plagman | 2149 | curlight++; |
1416 | plagman | 2150 | } while ((curlight < plane->lightcount) && (curlight < pr_maxlightpasses) && (!depth || mirrors[depth-1].plane)); |
1263 | plagman | 2151 | |
2152 | if (plane->vbo && (pr_vbos > 0)) |
||
2153 | { |
||
2154 | bglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); |
||
2155 | if (plane->indices) |
||
2156 | bglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); |
||
2157 | } |
||
699 | plagman | 2158 | } |
2159 | |||
1313 | plagman | 2160 | static inline void polymer_inb4mirror(GLfloat* buffer, GLfloat* plane) |
699 | plagman | 2161 | { |
696 | plagman | 2162 | float pv; |
2163 | float reflectionmatrix[16]; |
||
2164 | |||
699 | plagman | 2165 | pv = buffer[0] * plane[0] + |
2166 | buffer[1] * plane[1] + |
||
2167 | buffer[2] * plane[2]; |
||
696 | plagman | 2168 | |
699 | plagman | 2169 | reflectionmatrix[0] = 1 - (2 * plane[0] * plane[0]); |
2170 | reflectionmatrix[1] = -2 * plane[0] * plane[1]; |
||
2171 | reflectionmatrix[2] = -2 * plane[0] * plane[2]; |
||
696 | plagman | 2172 | reflectionmatrix[3] = 0; |
2173 | |||
699 | plagman | 2174 | reflectionmatrix[4] = -2 * plane[0] * plane[1]; |
2175 | reflectionmatrix[5] = 1 - (2 * plane[1] * plane[1]); |
||
2176 | reflectionmatrix[6] = -2 * plane[1] * plane[2]; |
||
696 | plagman | 2177 | reflectionmatrix[7] = 0; |
2178 | |||
699 | plagman | 2179 | reflectionmatrix[8] = -2 * plane[0] * plane[2]; |
2180 | reflectionmatrix[9] = -2 * plane[1] * plane[2]; |
||
2181 | reflectionmatrix[10] = 1 - (2 * plane[2] * plane[2]); |
||
696 | plagman | 2182 | reflectionmatrix[11] = 0; |
2183 | |||
699 | plagman | 2184 | reflectionmatrix[12] = 2 * pv * plane[0]; |
2185 | reflectionmatrix[13] = 2 * pv * plane[1]; |
||
2186 | reflectionmatrix[14] = 2 * pv * plane[2]; |
||
696 | plagman | 2187 | reflectionmatrix[15] = 1; |
2188 | |||
2189 | bglMultMatrixf(reflectionmatrix); |
||
1373 | plagman | 2190 | |
2191 | bglPushMatrix(); |
||
2192 | bglLoadMatrixf(curskymodelviewmatrix); |
||
2193 | bglMultMatrixf(reflectionmatrix); |
||
2194 | bglGetFloatv(GL_MODELVIEW_MATRIX, curskymodelviewmatrix); |
||
2195 | bglPopMatrix(); |
||
696 | plagman | 2196 | } |
2197 | |||
697 | plagman | 2198 | static void polymer_animatesprites(void) |
2199 | { |
||
719 | plagman | 2200 | if (asi.animatesprites) |
2201 | asi.animatesprites(globalposx, globalposy, viewangle, asi.smoothratio); |
||
697 | plagman | 2202 | } |
2203 | |||
1390 | terminx | 2204 | static void polymer_freeboard(void) |
1387 | plagman | 2205 | { |
2206 | int32_t i; |
||
2207 | |||
2208 | i = 0; |
||
2209 | while (i < MAXSECTORS) |
||
2210 | { |
||
2211 | if (prsectors[i]) |
||
2212 | { |
||
1533 | plagman | 2213 | if (prsectors[i]->verts) Bfree(prsectors[i]->verts); |
2214 | if (prsectors[i]->floor.buffer) Bfree(prsectors[i]->floor.buffer); |
||
2215 | if (prsectors[i]->ceil.buffer) Bfree(prsectors[i]->ceil.buffer); |
||
2216 | if (prsectors[i]->floor.indices) Bfree(prsectors[i]->floor.indices); |
||
2217 | if (prsectors[i]->ceil.indices) Bfree(prsectors[i]->ceil.indices); |
||
1387 | plagman | 2218 | if (prsectors[i]->ceil.vbo) bglDeleteBuffersARB(1, &prsectors[i]->ceil.vbo); |
2219 | if (prsectors[i]->ceil.ivbo) bglDeleteBuffersARB(1, &prsectors[i]->ceil.ivbo); |
||
2220 | if (prsectors[i]->floor.vbo) bglDeleteBuffersARB(1, &prsectors[i]->floor.vbo); |
||
2221 | if (prsectors[i]->floor.ivbo) bglDeleteBuffersARB(1, &prsectors[i]->floor.ivbo); |
||
2222 | |||
1533 | plagman | 2223 | Bfree(prsectors[i]); |
1387 | plagman | 2224 | prsectors[i] = NULL; |
2225 | } |
||
2226 | |||
2227 | i++; |
||
2228 | } |
||
2229 | |||
2230 | i = 0; |
||
2231 | while (i < MAXWALLS) |
||
2232 | { |
||
2233 | if (prwalls[i]) |
||
2234 | { |
||
1533 | plagman | 2235 | if (prwalls[i]->bigportal) Bfree(prwalls[i]->bigportal); |
2236 | if (prwalls[i]->mask.buffer) Bfree(prwalls[i]->mask.buffer); |
||
1942 | helixhorne | 2237 | if (prwalls[i]->over.buffer) Bfree(prwalls[i]->over.buffer); |
1533 | plagman | 2238 | if (prwalls[i]->cap) Bfree(prwalls[i]->cap); |
2239 | if (prwalls[i]->wall.buffer) Bfree(prwalls[i]->wall.buffer); |
||
1387 | plagman | 2240 | if (prwalls[i]->wall.vbo) bglDeleteBuffersARB(1, &prwalls[i]->wall.vbo); |
2241 | if (prwalls[i]->over.vbo) bglDeleteBuffersARB(1, &prwalls[i]->over.vbo); |
||
2242 | if (prwalls[i]->mask.vbo) bglDeleteBuffersARB(1, &prwalls[i]->mask.vbo); |
||
2243 | if (prwalls[i]->stuffvbo) bglDeleteBuffersARB(1, &prwalls[i]->stuffvbo); |
||
2244 | |||
1533 | plagman | 2245 | Bfree(prwalls[i]); |
1387 | plagman | 2246 | prwalls[i] = NULL; |
2247 | } |
||
2248 | |||
2249 | i++; |
||
2250 | } |
||
1676 | terminx | 2251 | |
2252 | i = 0; |
||
2253 | while (i < MAXSPRITES) |
||
2254 | { |
||
2255 | if (prsprites[i]) |
||
2256 | { |
||
2257 | if (prsprites[i]->plane.buffer) Bfree(prsprites[i]->plane.buffer); |
||
2258 | if (prsprites[i]->plane.vbo) bglDeleteBuffersARB(1, &prsprites[i]->plane.vbo); |
||
2259 | Bfree(prsprites[i]); |
||
2260 | prsprites[i] = NULL; |
||
2261 | } |
||
2262 | |||
2263 | i++; |
||
2264 | } |
||
2265 | |||
3737 | Plagman | 2266 | i = 0; |
2267 | while (i < MAXTILES) |
||
2268 | { |
||
4304 | helixhorne | 2269 | polymer_invalidateartmap(i); |
3737 | Plagman | 2270 | i++; |
2271 | } |
||
2272 | |||
2273 | i = 0; |
||
2274 | while (i < MAXBASEPALS) |
||
2275 | { |
||
2276 | if (prbasepalmaps[i]) |
||
2277 | { |
||
2278 | bglDeleteTextures(1, &prbasepalmaps[i]); |
||
2279 | prbasepalmaps[i] = 0; |
||
2280 | } |
||
2281 | |||
2282 | i++; |
||
2283 | } |
||
2284 | |||
2285 | i = 0; |
||
2286 | while (i < MAXPALOOKUPS) |
||
2287 | { |
||
2288 | if (prlookups[i]) |
||
2289 | { |
||
2290 | bglDeleteTextures(1, &prlookups[i]); |
||
2291 | prlookups[i] = 0; |
||
2292 | } |
||
2293 | |||
2294 | i++; |
||
2295 | } |
||
1387 | plagman | 2296 | } |
2297 | |||
311 | Plagman | 2298 | // SECTORS |
1212 | plagman | 2299 | static int32_t polymer_initsector(int16_t sectnum) |
304 | Plagman | 2300 | { |
5072 | terminx | 2301 | tsectortype *sec; |
304 | Plagman | 2302 | _prsector* s; |
2303 | |||
1676 | terminx | 2304 | if (pr_verbosity >= 2) OSD_Printf("PR : Initializing sector %i...\n", sectnum); |
304 | Plagman | 2305 | |
5072 | terminx | 2306 | sec = (tsectortype *)§or[sectnum]; |
4491 | helixhorne | 2307 | s = (_prsector *)Xcalloc(1, sizeof(_prsector)); |
304 | Plagman | 2308 | |
4491 | helixhorne | 2309 | s->verts = (GLdouble *)Xcalloc(sec->wallnum, sizeof(GLdouble) * 3); |
2310 | s->floor.buffer = (GLfloat *)Xcalloc(sec->wallnum, sizeof(GLfloat) * 5); |
||
1233 | plagman | 2311 | s->floor.vertcount = sec->wallnum; |
4491 | helixhorne | 2312 | s->ceil.buffer = (GLfloat *)Xcalloc(sec->wallnum, sizeof(GLfloat) * 5); |
1233 | plagman | 2313 | s->ceil.vertcount = sec->wallnum; |
4491 | helixhorne | 2314 | |
733 | plagman | 2315 | bglGenBuffersARB(1, &s->floor.vbo); |
2316 | bglGenBuffersARB(1, &s->ceil.vbo); |
||
2317 | bglGenBuffersARB(1, &s->floor.ivbo); |
||
2318 | bglGenBuffersARB(1, &s->ceil.ivbo); |
||
331 | terminx | 2319 | |
751 | plagman | 2320 | bglBindBufferARB(GL_ARRAY_BUFFER_ARB, s->floor.vbo); |
2321 | bglBufferDataARB(GL_ARRAY_BUFFER_ARB, sec->wallnum * sizeof(GLfloat) * 5, NULL, mapvbousage); |
||
2322 | |||
2323 | bglBindBufferARB(GL_ARRAY_BUFFER_ARB, s->ceil.vbo); |
||
2324 | bglBufferDataARB(GL_ARRAY_BUFFER_ARB, sec->wallnum * sizeof(GLfloat) * 5, NULL, mapvbousage); |
||
2325 | |||
2326 | bglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); |
||
2327 | |||
1428 | plagman | 2328 | s->flags.empty = 1; // let updatesector know that everything needs to go |
304 | Plagman | 2329 | |
2330 | prsectors[sectnum] = s; |
||
2331 | |||
1676 | terminx | 2332 | if (pr_verbosity >= 2) OSD_Printf("PR : Initialized sector %i.\n", sectnum); |
304 | Plagman | 2333 | |
2334 | return (1); |
||
2335 | } |
||
2336 | |||
1264 | plagman | 2337 | static int32_t polymer_updatesector(int16_t sectnum) |
2338 | { |
||
304 | Plagman | 2339 | _prsector* s; |
5072 | terminx | 2340 | tsectortype *sec; |
304 | Plagman | 2341 | walltype *wal; |
1212 | plagman | 2342 | int32_t i, j; |
2343 | int32_t ceilz, florz; |
||
2344 | int32_t tex, tey, heidiff; |
||
719 | plagman | 2345 | float secangcos, secangsin, scalecoef, xpancoef, ypancoef; |
1212 | plagman | 2346 | int32_t ang, needfloor, wallinvalidate; |
2347 | int16_t curstat, curpicnum, floorpicnum, ceilingpicnum; |
||
304 | Plagman | 2348 | char curxpanning, curypanning; |
2349 | GLfloat* curbuffer; |
||
2350 | |||
286 | terminx | 2351 | s = prsectors[sectnum]; |
5072 | terminx | 2352 | sec = (tsectortype *)§or[sectnum]; |
286 | terminx | 2353 | |
684 | plagman | 2354 | secangcos = secangsin = 2; |
301 | Plagman | 2355 | |
286 | terminx | 2356 | if (s == NULL) |
2357 | { |
||
2358 | if (pr_verbosity >= 1) OSD_Printf("PR : Can't update uninitialized sector %i.\n", sectnum); |
||
2359 | return (-1); |
||
2360 | } |
||
2361 | |||
684 | plagman | 2362 | needfloor = wallinvalidate = 0; |
311 | Plagman | 2363 | |
304 | Plagman | 2364 | // geometry |
684 | plagman | 2365 | wal = &wall[sec->wallptr]; |
286 | terminx | 2366 | i = 0; |
1332 | plagman | 2367 | while (i < sec->wallnum) |
286 | terminx | 2368 | { |
315 | Plagman | 2369 | if ((-wal->x != s->verts[(i*3)+2])) |
311 | Plagman | 2370 | { |
1457 | terminx | 2371 | s->verts[(i*3)+2] = s->floor.buffer[(i*5)+2] = s->ceil.buffer[(i*5)+2] = -(float)wal->x; |
684 | plagman | 2372 | needfloor = wallinvalidate = 1; |
311 | Plagman | 2373 | } |
315 | Plagman | 2374 | if ((wal->y != s->verts[i*3])) |
311 | Plagman | 2375 | { |
1457 | terminx | 2376 | s->verts[i*3] = s->floor.buffer[i*5] = s->ceil.buffer[i*5] = (float)wal->y; |
684 | plagman | 2377 | needfloor = wallinvalidate = 1; |
311 | Plagman | 2378 | } |
286 | terminx | 2379 | |
684 | plagman | 2380 | i++; |
2381 | wal = &wall[sec->wallptr + i]; |
||
2382 | } |
||
2383 | |||
1428 | plagman | 2384 | if ((s->flags.empty) || |
1264 | plagman | 2385 | needfloor || |
723 | terminx | 2386 | (sec->floorz != s->floorz) || |
2387 | (sec->ceilingz != s->ceilingz) || |
||
2388 | (sec->floorheinum != s->floorheinum) || |
||
2389 | (sec->ceilingheinum != s->ceilingheinum)) |
||
684 | plagman | 2390 | { |
2391 | wallinvalidate = 1; |
||
2392 | |||
2393 | wal = &wall[sec->wallptr]; |
||
2394 | i = 0; |
||
1332 | plagman | 2395 | while (i < sec->wallnum) |
684 | plagman | 2396 | { |
2397 | getzsofslope(sectnum, wal->x, wal->y, &ceilz, &florz); |
||
733 | plagman | 2398 | s->floor.buffer[(i*5)+1] = -(float)(florz) / 16.0f; |
2399 | s->ceil.buffer[(i*5)+1] = -(float)(ceilz) / 16.0f; |
||
684 | plagman | 2400 | |
2401 | i++; |
||
2402 | wal = &wall[sec->wallptr + i]; |
||
2403 | } |
||
2404 | |||
2405 | s->floorz = sec->floorz; |
||
2406 | s->ceilingz = sec->ceilingz; |
||
2407 | s->floorheinum = sec->floorheinum; |
||
2408 | s->ceilingheinum = sec->ceilingheinum; |
||
2409 | } |