Subversion Repositories eduke32

Rev

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 *)&sector[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 *)&sector[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 *)&sector[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 *)&sector[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 = &sector[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 *)&sector[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 *)&sector[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
    }