Rev 5055 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5 | Plagman | 1 | /************************************************************************************************** |
5001 | terminx | 2 | "POLYMOST" code originally written by Ken Silverman |
5 | Plagman | 3 | Ken Silverman's official web site: http://www.advsys.net/ken |
4 | **************************************************************************************************/ |
||
5 | |||
1173 | terminx | 6 | |
1820 | terminx | 7 | #ifdef USE_OPENGL |
1173 | terminx | 8 | |
9 | #include "compat.h" |
||
10 | #include "build.h" |
||
3758 | terminx | 11 | #include "glbuild.h" |
12 | #include "mdsprite.h" |
||
1173 | terminx | 13 | #include "pragmas.h" |
14 | #include "baselayer.h" |
||
15 | #include "osd.h" |
||
16 | #include "engine_priv.h" |
||
17 | #include "hightile.h" |
||
18 | #include "polymost.h" |
||
1593 | terminx | 19 | #include "polymer.h" |
1173 | terminx | 20 | #include "cache1d.h" |
21 | #include "kplib.h" |
||
3758 | terminx | 22 | #include "texcache.h" |
4652 | terminx | 23 | #include "common.h" |
1173 | terminx | 24 | |
5001 | terminx | 25 | #ifdef EDUKE32_GLES |
26 | #include "jwzgles.h" |
||
27 | #endif |
||
28 | |||
1652 | terminx | 29 | #ifndef _WIN32 |
30 | extern int32_t filelength(int h); // kplib.c |
||
31 | #endif |
||
32 | |||
1173 | terminx | 33 | extern char textfont[2048], smalltextfont[2048]; |
34 | |||
1205 | terminx | 35 | int32_t rendmode=0; |
4439 | terminx | 36 | #ifdef __ANDROID__ |
37 | int32_t usemodels=0; |
||
38 | #else |
||
39 | int32_t usemodels=1; |
||
40 | #endif |
||
41 | int32_t usehightile=1; |
||
4090 | hendricks2 | 42 | int32_t vsync=0; |
5 | Plagman | 43 | |
44 | #include <math.h> //<-important! |
||
4652 | terminx | 45 | #include <float.h> |
4605 | terminx | 46 | |
2002 | helixhorne | 47 | typedef struct { float x, cy[2], fy[2]; int32_t tag; int16_t n, p, ctag, ftag; } vsptyp; |
5 | Plagman | 48 | #define VSPMAX 4096 //<- careful! |
49 | static vsptyp vsp[VSPMAX]; |
||
2002 | helixhorne | 50 | static int32_t gtag; |
5 | Plagman | 51 | |
4605 | terminx | 52 | static float dxb1[MAXWALLSB], dxb2[MAXWALLSB]; |
5 | Plagman | 53 | |
4652 | terminx | 54 | #define SCISDIST .9999f //1.0: Close plane clipping distance |
5 | Plagman | 55 | |
3403 | helixhorne | 56 | float shadescale = 1.0f; |
1848 | helixhorne | 57 | int32_t shadescale_unbounded = 0; |
379 | terminx | 58 | |
4393 | helixhorne | 59 | int32_t r_usenewshading = 3; |
4459 | helixhorne | 60 | int32_t r_usetileshades = 2; |
4498 | helixhorne | 61 | int32_t r_npotwallmode = 0; |
1943 | helixhorne | 62 | |
4605 | terminx | 63 | static float gviewxrange; |
64 | static float ghoriz; |
||
65 | float gxyaspect; |
||
66 | float gyxscale, ghalfx, grhalfxdown10, grhalfxdown10x; |
||
67 | float gcosang, gsinang, gcosang2, gsinang2; |
||
68 | float gchang, gshang, gctang, gstang, gvisibility; |
||
69 | float gtang = 0.f; |
||
70 | static double guo, gux, guy; //Screen-based texture mapping parameters |
||
71 | static double gvo, gvx, gvy; |
||
72 | static double gdo, gdx, gdy; |
||
4667 | terminx | 73 | float fcosglobalang, fsinglobalang; |
4768 | hendricks2 | 74 | float fxdim, fydim, fydimen, fviewingrange; |
1706 | helixhorne | 75 | static int32_t preview_mouseaim=0; // when 1, displays a CROSSHAIR tsprite at the _real_ aimed position |
76 | |||
5 | Plagman | 77 | #ifdef USE_OPENGL |
1205 | terminx | 78 | static int32_t srepeat = 0, trepeat = 0; |
590 | plagman | 79 | |
4605 | terminx | 80 | #ifdef REDBLUEMODE |
1205 | terminx | 81 | int32_t glredbluemode = 0; |
82 | static int32_t lastglredbluemode = 0, redblueclearcnt = 0; |
||
4605 | terminx | 83 | #endif |
5 | Plagman | 84 | |
3041 | helixhorne | 85 | struct glfiltermodes glfiltermodes[NUMGLFILTERMODES] = |
584 | terminx | 86 | { |
87 | {"GL_NEAREST",GL_NEAREST,GL_NEAREST}, |
||
88 | {"GL_LINEAR",GL_LINEAR,GL_LINEAR}, |
||
89 | {"GL_NEAREST_MIPMAP_NEAREST",GL_NEAREST_MIPMAP_NEAREST,GL_NEAREST}, |
||
90 | {"GL_LINEAR_MIPMAP_NEAREST",GL_LINEAR_MIPMAP_NEAREST,GL_LINEAR}, |
||
91 | {"GL_NEAREST_MIPMAP_LINEAR",GL_NEAREST_MIPMAP_LINEAR,GL_NEAREST}, |
||
92 | {"GL_LINEAR_MIPMAP_LINEAR",GL_LINEAR_MIPMAP_LINEAR,GL_LINEAR} |
||
93 | }; |
||
5 | Plagman | 94 | |
1205 | terminx | 95 | int32_t glanisotropy = 1; // 0 = maximum supported by card |
5001 | terminx | 96 | int32_t gltexfiltermode = 2; // GL_NEAREST_MIPMAP_NEAREST |
97 | |||
98 | #ifdef EDUKE32_GLES |
||
99 | int32_t glusetexcompr = 0; |
||
100 | int32_t glusetexcache = 0, glusememcache = 0; |
||
101 | #else |
||
1205 | terminx | 102 | int32_t glusetexcompr = 1; |
2145 | helixhorne | 103 | int32_t glusetexcache = 2, glusememcache = 1; |
5001 | terminx | 104 | int32_t glpolygonmode = 0; // 0:GL_FILL,1:GL_LINE,2:GL_POINT //FUK |
1205 | terminx | 105 | int32_t glmultisample = 0, glnvmultisamplehint = 0; |
5001 | terminx | 106 | static int32_t lastglpolygonmode = 0; //FUK |
107 | int32_t r_detailmapping = 1; |
||
108 | int32_t r_glowmapping = 1; |
||
109 | #endif |
||
110 | |||
1205 | terminx | 111 | int32_t gltexmaxsize = 0; // 0 means autodetection on first run |
112 | int32_t gltexmiplevel = 0; // discards this many mipmap levels |
||
113 | int32_t glprojectionhacks = 1; |
||
5 | Plagman | 114 | static GLuint polymosttext = 0; |
3784 | terminx | 115 | int32_t glrendmode = REND_POLYMOST; |
228 | Plagman | 116 | |
3146 | helixhorne | 117 | // This variable, and 'shadeforfullbrightpass' control the drawing of |
118 | // fullbright tiles. Also see 'fullbrightloadingpass'. |
||
1205 | terminx | 119 | static int32_t fullbrightdrawingpass = 0; |
228 | Plagman | 120 | |
1205 | terminx | 121 | int32_t r_vertexarrays = 1; |
122 | int32_t r_vbos = 1; |
||
123 | int32_t r_vbocount = 64; |
||
124 | int32_t r_animsmoothing = 1; |
||
125 | int32_t r_fullbrights = 1; |
||
3387 | helixhorne | 126 | int32_t r_downsize = 0; |
1634 | terminx | 127 | int32_t r_downsizevar = -1; |
916 | terminx | 128 | |
1329 | terminx | 129 | // used for fogcalc |
4623 | terminx | 130 | static float fogresult, fogresult2, fogcol[4], fogtable[4*MAXPALOOKUPS]; |
5 | Plagman | 131 | #endif |
132 | |||
4623 | terminx | 133 | static const float float_trans[4] = { 1.0f, 1.0f, 0.66f, 0.33f }; |
134 | |||
3758 | terminx | 135 | char ptempbuf[MAXWALLSB<<1]; |
1173 | terminx | 136 | |
1064 | terminx | 137 | // polymost ART sky control |
1205 | terminx | 138 | int32_t r_parallaxskyclamping = 1; |
139 | int32_t r_parallaxskypanning = 0; |
||
1064 | terminx | 140 | |
2045 | helixhorne | 141 | #define MIN_CACHETIME_PRINT 10 |
1784 | helixhorne | 142 | |
4675 | terminx | 143 | // this was faster in MSVC but slower with GCC... currently unknown on ARM where both |
144 | // the FPU and possibly the optimization path in the compiler need improvement |
||
145 | #if 0 |
||
146 | static inline int32_t __float_as_int(float f) { return *(int32_t *) &f; } |
||
147 | static inline float __int_as_float(int32_t d) { return *(float *) &d; } |
||
148 | static inline float Bfabsf(float f) { return __int_as_float(__float_as_int(f)&0x7fffffff); } |
||
149 | #else |
||
150 | #define Bfabsf fabsf |
||
151 | #endif |
||
152 | |||
5 | Plagman | 153 | #ifdef USE_OPENGL |
1652 | terminx | 154 | int32_t mdtims, omdtims; |
155 | float alphahackarray[MAXTILES]; |
||
1205 | terminx | 156 | int32_t drawingskybox = 0; |
3758 | terminx | 157 | int32_t hicprecaching = 0; |
5 | Plagman | 158 | |
4690 | terminx | 159 | #if 0 |
1221 | terminx | 160 | static inline int32_t gltexmayhavealpha(int32_t dapicnum, int32_t dapalnum) |
5 | Plagman | 161 | { |
3146 | helixhorne | 162 | const int32_t j = (dapicnum&(GLTEXCACHEADSIZ-1)); |
109 | terminx | 163 | pthtyp *pth; |
5 | Plagman | 164 | |
3781 | terminx | 165 | for (pth=texcache.list[j]; pth; pth=pth->next) |
3146 | helixhorne | 166 | if (pth->picnum == dapicnum && pth->palnum == dapalnum) |
4486 | helixhorne | 167 | return ((pth->flags&PTH_HASALPHA) != 0); |
3146 | helixhorne | 168 | |
169 | return 1; |
||
5 | Plagman | 170 | } |
4690 | terminx | 171 | #endif |
5 | Plagman | 172 | |
1205 | terminx | 173 | void gltexinvalidate(int32_t dapicnum, int32_t dapalnum, int32_t dameth) |
5 | Plagman | 174 | { |
3146 | helixhorne | 175 | const int32_t j = (dapicnum&(GLTEXCACHEADSIZ-1)); |
109 | terminx | 176 | pthtyp *pth; |
5 | Plagman | 177 | |
3781 | terminx | 178 | for (pth=texcache.list[j]; pth; pth=pth->next) |
4486 | helixhorne | 179 | if (pth->picnum == dapicnum && pth->palnum == dapalnum && |
180 | (pth->flags & PTH_CLAMPED) == TO_PTH_CLAMPED(dameth)) |
||
248 | terminx | 181 | { |
4486 | helixhorne | 182 | pth->flags |= PTH_INVALIDATED; |
183 | if (pth->flags & PTH_HASFULLBRIGHT) |
||
184 | pth->ofb->flags |= PTH_INVALIDATED; |
||
248 | terminx | 185 | } |
5 | Plagman | 186 | } |
187 | |||
109 | terminx | 188 | //Make all textures "dirty" so they reload, but not re-allocate |
189 | //This should be much faster than polymost_glreset() |
||
190 | //Use this for palette effects ... but not ones that change every frame! |
||
3765 | terminx | 191 | void gltexinvalidatetype(int32_t type) |
5 | Plagman | 192 | { |
1205 | terminx | 193 | int32_t j; |
109 | terminx | 194 | pthtyp *pth; |
5 | Plagman | 195 | |
4667 | terminx | 196 | for (j=0; j<=GLTEXCACHEADSIZ-1; j++) |
3758 | terminx | 197 | { |
3781 | terminx | 198 | for (pth=texcache.list[j]; pth; pth=pth->next) |
248 | terminx | 199 | { |
3765 | terminx | 200 | if (type == INVALIDATE_ALL || (type == INVALIDATE_ART && pth->hicr == NULL)) |
415 | terminx | 201 | { |
4486 | helixhorne | 202 | pth->flags |= PTH_INVALIDATED; |
203 | if (pth->flags & PTH_HASFULLBRIGHT) |
||
204 | pth->ofb->flags |= PTH_INVALIDATED; |
||
415 | terminx | 205 | } |
206 | } |
||
3758 | terminx | 207 | } |
208 | |||
3765 | terminx | 209 | if (type == INVALIDATE_ALL) |
3758 | terminx | 210 | clearskins(); |
415 | terminx | 211 | #ifdef DEBUGGINGAIDS |
3758 | terminx | 212 | OSD_Printf("gltexinvalidateall()\n"); |
415 | terminx | 213 | #endif |
214 | } |
||
215 | |||
5001 | terminx | 216 | static void bind_2d_texture(GLuint texture, int filter) |
3041 | helixhorne | 217 | { |
5001 | terminx | 218 | if (filter == -1) |
219 | filter = gltexfiltermode; |
||
220 | |||
3041 | helixhorne | 221 | bglBindTexture(GL_TEXTURE_2D, texture); |
5001 | terminx | 222 | bglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glfiltermodes[filter].mag); |
223 | bglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glfiltermodes[filter].min); |
||
224 | #ifndef EDUKE32_GLES |
||
4605 | terminx | 225 | if (glinfo.maxanisotropy > 1.f) |
3041 | helixhorne | 226 | bglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, glanisotropy); |
5001 | terminx | 227 | #endif |
3041 | helixhorne | 228 | } |
229 | |||
584 | terminx | 230 | void gltexapplyprops(void) |
5 | Plagman | 231 | { |
1205 | terminx | 232 | int32_t i; |
109 | terminx | 233 | pthtyp *pth; |
5 | Plagman | 234 | |
3784 | terminx | 235 | if (getrendermode() == REND_CLASSIC) |
3628 | helixhorne | 236 | return; |
237 | |||
4605 | terminx | 238 | if (glinfo.maxanisotropy > 1.f) |
109 | terminx | 239 | { |
3041 | helixhorne | 240 | if (glanisotropy <= 0 || glanisotropy > glinfo.maxanisotropy) |
241 | glanisotropy = (int32_t)glinfo.maxanisotropy; |
||
109 | terminx | 242 | } |
5 | Plagman | 243 | |
3041 | helixhorne | 244 | gltexfiltermode = clamp(gltexfiltermode, 0, NUMGLFILTERMODES-1); |
245 | |||
4667 | terminx | 246 | for (i=0; i<=GLTEXCACHEADSIZ-1; i++) |
584 | terminx | 247 | { |
3781 | terminx | 248 | for (pth=texcache.list[i]; pth; pth=pth->next) |
584 | terminx | 249 | { |
5001 | terminx | 250 | #ifndef EDUKE32_TOUCH_DEVICES |
251 | bind_2d_texture(pth->glpic, -1); |
||
3041 | helixhorne | 252 | |
4486 | helixhorne | 253 | if (r_fullbrights && pth->flags & PTH_HASFULLBRIGHT) |
5001 | terminx | 254 | bind_2d_texture(pth->ofb->glpic, -1); |
255 | #else |
||
256 | bind_2d_texture(pth->glpic, pth->flags & PTH_HIGHTILE ? 5 : -1); |
||
257 | |||
258 | if (r_fullbrights && pth->flags & PTH_HASFULLBRIGHT) |
||
259 | bind_2d_texture(pth->ofb->glpic, pth->flags & PTH_HIGHTILE ? 5 : -1); |
||
260 | #endif |
||
109 | terminx | 261 | } |
262 | } |
||
5 | Plagman | 263 | |
5001 | terminx | 264 | int32_t j; |
265 | mdskinmap_t *sk; |
||
266 | md2model_t *m; |
||
267 | |||
268 | for (i=0; i<nextmodelid; i++) |
||
109 | terminx | 269 | { |
5001 | terminx | 270 | m = (md2model_t *)models[i]; |
271 | if (m->mdnum < 2) continue; |
||
272 | for (j=0; j<m->numskins*(HICEFFECTMASK+1); j++) |
||
273 | { |
||
274 | if (!m->texid[j]) continue; |
||
275 | bind_2d_texture(m->texid[j], -1); |
||
276 | } |
||
109 | terminx | 277 | |
5001 | terminx | 278 | for (sk=m->skinmap; sk; sk=sk->next) |
279 | for (j=0; j<(HICEFFECTMASK+1); j++) |
||
109 | terminx | 280 | { |
5001 | terminx | 281 | if (!sk->texid[j]) continue; |
282 | bind_2d_texture(sk->texid[j], -1); |
||
109 | terminx | 283 | } |
284 | } |
||
5 | Plagman | 285 | } |
286 | |||
287 | //-------------------------------------------------------------------------------------------------- |
||
3758 | terminx | 288 | |
1173 | terminx | 289 | float glox1, gloy1, glox2, gloy2; |
5 | Plagman | 290 | |
109 | terminx | 291 | //Use this for both initialization and uninitialization of OpenGL. |
1205 | terminx | 292 | static int32_t gltexcacnum = -1; |
1652 | terminx | 293 | |
584 | terminx | 294 | void polymost_glreset() |
5 | Plagman | 295 | { |
1205 | terminx | 296 | int32_t i; |
109 | terminx | 297 | pthtyp *pth, *next; |
1220 | terminx | 298 | |
4667 | terminx | 299 | for (i=0; i<=MAXPALOOKUPS-1; i++) |
1220 | terminx | 300 | { |
4667 | terminx | 301 | fogtable[i<<2] = palookupfog[i].r * (1.f/63.f); |
302 | fogtable[(i<<2)+1] = palookupfog[i].g * (1.f/63.f); |
||
303 | fogtable[(i<<2)+2] = palookupfog[i].b * (1.f/63.f); |
||
1220 | terminx | 304 | fogtable[(i<<2)+3] = 0; |
305 | } |
||
306 | |||
109 | terminx | 307 | //Reset if this is -1 (meaning 1st texture call ever), or > 0 (textures in memory) |
308 | if (gltexcacnum < 0) |
||
309 | { |
||
310 | gltexcacnum = 0; |
||
5 | Plagman | 311 | |
109 | terminx | 312 | //Hack for polymost_dorotatesprite calls before 1st polymost_drawrooms() |
4605 | terminx | 313 | gcosang = gcosang2 = 16384.f/262144.f; |
314 | gsinang = gsinang2 = 0.f/262144.f; |
||
109 | terminx | 315 | } |
316 | else |
||
317 | { |
||
4667 | terminx | 318 | for (i=0; i<=GLTEXCACHEADSIZ-1; i++) |
584 | terminx | 319 | { |
3781 | terminx | 320 | for (pth=texcache.list[i]; pth;) |
584 | terminx | 321 | { |
109 | terminx | 322 | next = pth->next; |
4486 | helixhorne | 323 | if (pth->flags & PTH_HASFULLBRIGHT) |
248 | terminx | 324 | { |
325 | bglDeleteTextures(1,&pth->ofb->glpic); |
||
1527 | terminx | 326 | Bfree(pth->ofb); |
248 | terminx | 327 | } |
2639 | helixhorne | 328 | |
109 | terminx | 329 | bglDeleteTextures(1,&pth->glpic); |
1527 | terminx | 330 | Bfree(pth); |
109 | terminx | 331 | pth = next; |
332 | } |
||
2639 | helixhorne | 333 | |
3781 | terminx | 334 | texcache.list[i] = NULL; |
109 | terminx | 335 | } |
336 | clearskins(); |
||
337 | } |
||
338 | |||
2639 | helixhorne | 339 | if (polymosttext) |
340 | bglDeleteTextures(1,&polymosttext); |
||
109 | terminx | 341 | polymosttext=0; |
342 | |||
4639 | terminx | 343 | md_freevbos(); |
1317 | terminx | 344 | |
4675 | terminx | 345 | Bmemset(texcache.list,0,sizeof(texcache.list)); |
109 | terminx | 346 | glox1 = -1; |
446 | Plagman | 347 | |
3758 | terminx | 348 | texcache_freeptrs(); |
5001 | terminx | 349 | texcache_syncmemcache(); |
1155 | terminx | 350 | |
2014 | helixhorne | 351 | #ifdef DEBUGGINGAIDS |
352 | OSD_Printf("polymost_glreset()\n"); |
||
353 | #endif |
||
5 | Plagman | 354 | } |
355 | |||
2240 | helixhorne | 356 | |
627 | terminx | 357 | // one-time initialization of OpenGL for polymost |
5 | Plagman | 358 | void polymost_glinit() |
359 | { |
||
5001 | terminx | 360 | bglHint(GL_FOG_HINT, GL_NICEST); |
4904 | terminx | 361 | bglFogi(GL_FOG_MODE, (r_usenewshading < 2) ? GL_EXP2 : GL_LINEAR); |
3301 | helixhorne | 362 | bglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
109 | terminx | 363 | |
2579 | plagman | 364 | bglPixelStorei(GL_PACK_ALIGNMENT, 1); |
3729 | Plagman | 365 | bglPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
2579 | plagman | 366 | |
118 | terminx | 367 | //bglHint(GL_LINE_SMOOTH_HINT, GL_NICEST); |
368 | //bglEnable(GL_LINE_SMOOTH); |
||
369 | |||
5001 | terminx | 370 | #ifndef EDUKE32_GLES |
584 | terminx | 371 | if (glmultisample > 0 && glinfo.multisample) |
372 | { |
||
109 | terminx | 373 | if (glinfo.nvmultisamplehint) |
374 | bglHint(GL_MULTISAMPLE_FILTER_HINT_NV, glnvmultisamplehint ? GL_NICEST:GL_FASTEST); |
||
375 | bglEnable(GL_MULTISAMPLE_ARB); |
||
376 | } |
||
439 | Plagman | 377 | |
497 | Plagman | 378 | if (r_detailmapping && (!glinfo.multitex || !glinfo.envcombine)) |
459 | Plagman | 379 | { |
380 | OSD_Printf("Your OpenGL implementation doesn't support detail mapping. Disabling...\n"); |
||
460 | Plagman | 381 | r_detailmapping = 0; |
459 | Plagman | 382 | } |
383 | |||
497 | Plagman | 384 | if (r_glowmapping && (!glinfo.multitex || !glinfo.envcombine)) |
385 | { |
||
386 | OSD_Printf("Your OpenGL implementation doesn't support glow mapping. Disabling...\n"); |
||
387 | r_glowmapping = 0; |
||
388 | } |
||
5001 | terminx | 389 | #endif |
497 | Plagman | 390 | |
519 | Plagman | 391 | if (r_vbos && (!glinfo.vbos)) |
392 | { |
||
393 | OSD_Printf("Your OpenGL implementation doesn't support Vertex Buffer Objects. Disabling...\n"); |
||
394 | r_vbos = 0; |
||
395 | } |
||
396 | |||
513 | Plagman | 397 | bglEnableClientState(GL_VERTEX_ARRAY); |
398 | bglEnableClientState(GL_TEXTURE_COORD_ARRAY); |
||
1155 | terminx | 399 | |
3758 | terminx | 400 | texcache_init(); |
401 | texcache_loadoffsets(); |
||
3761 | terminx | 402 | texcache_openfiles(); |
403 | |||
404 | texcache_setupmemcache(); |
||
405 | texcache_checkgarbage(); |
||
5 | Plagman | 406 | } |
407 | |||
3303 | helixhorne | 408 | ////////// VISIBILITY FOG ROUTINES ////////// |
4904 | terminx | 409 | extern int32_t nofog; // in windows/SDL layers |
3303 | helixhorne | 410 | |
4393 | helixhorne | 411 | // only for r_usenewshading < 2 (not preferred) |
3768 | terminx | 412 | static void fogcalc_old(int32_t shade, int32_t vis) |
3763 | terminx | 413 | { |
414 | float f; |
||
415 | |||
416 | if (r_usenewshading==1) |
||
417 | { |
||
418 | f = 0.9f * shade; |
||
419 | f = (vis > 239) ? (float)(gvisibility*((vis-240+f))) : |
||
420 | (float)(gvisibility*(vis+16+f)); |
||
421 | } |
||
422 | else |
||
423 | { |
||
424 | f = (shade < 0) ? shade * 3.5f : shade * .66f; |
||
425 | f = (vis > 239) ? (float)(gvisibility*((vis-240+f)/(klabs(vis-256)))) : |
||
426 | (float)(gvisibility*(vis+16+f)); |
||
427 | } |
||
428 | |||
429 | if (f < 0.001f) |
||
430 | f = 0.001f; |
||
431 | else if (f > 100.0f) |
||
432 | f = 100.0f; |
||
433 | |||
434 | fogresult = f; |
||
435 | } |
||
436 | |||
3303 | helixhorne | 437 | // For GL_LINEAR fog: |
3307 | helixhorne | 438 | #define FOGDISTCONST 600 |
3959 | helixhorne | 439 | #define FULLVIS_BEGIN 2.9e30 |
440 | #define FULLVIS_END 3.0e30 |
||
3303 | helixhorne | 441 | |
3763 | terminx | 442 | static inline void fogcalc(int32_t tile, int32_t shade, int32_t vis, int32_t pal) |
3303 | helixhorne | 443 | { |
4904 | terminx | 444 | if (shade > 0 && getrendermode() == REND_POLYMOST && r_usetileshades == 1 && |
5056 | hendricks2 | 445 | !(globalflags & GLOBAL_NO_GL_TILESHADES) && |
4605 | terminx | 446 | (!usehightile || !hicfindsubst(tile, pal)) && |
3982 | terminx | 447 | (!usemodels || md_tilehasmodel(tile, pal) < 0)) |
448 | shade >>= 1; |
||
449 | |||
4904 | terminx | 450 | Bmemcpy(fogcol, &fogtable[pal<<2], sizeof(fogcol)); |
451 | |||
4393 | helixhorne | 452 | if (r_usenewshading < 2) |
3768 | terminx | 453 | fogcalc_old(shade, vis); |
3763 | terminx | 454 | else |
455 | { |
||
4904 | terminx | 456 | float combvis = (float) globalvisibility * (uint8_t) (vis+16); |
3303 | helixhorne | 457 | |
458 | if (combvis == 0) |
||
459 | { |
||
4393 | helixhorne | 460 | if (r_usenewshading == 2 && shade > 0) |
3959 | helixhorne | 461 | { |
462 | // beg = -D*shade, end = D*(NUMSHADES-1-shade) |
||
463 | // => end/beg = -(NUMSHADES-1-shade)/shade |
||
4904 | terminx | 464 | fogresult = (float) -FULLVIS_BEGIN; |
465 | fogresult2 = FULLVIS_BEGIN * (float) (numshades-1-shade)/shade; |
||
3959 | helixhorne | 466 | } |
467 | else |
||
468 | { |
||
4904 | terminx | 469 | fogresult = (float) FULLVIS_BEGIN; |
470 | fogresult2 = (float) FULLVIS_END; |
||
3959 | helixhorne | 471 | } |
3303 | helixhorne | 472 | } |
4904 | terminx | 473 | else if (r_usenewshading == 3 && shade >= numshades-1) |
4452 | helixhorne | 474 | { |
475 | fogresult = -1; |
||
476 | fogresult2 = 0; |
||
477 | } |
||
478 | else |
||
479 | { |
||
4658 | terminx | 480 | combvis = 1.f/combvis; |
481 | fogresult = (r_usenewshading == 3 && shade > 0) ? 0 : -(FOGDISTCONST * shade) * combvis; |
||
482 | fogresult2 = (FOGDISTCONST * (numshades-1-shade)) * combvis; |
||
4452 | helixhorne | 483 | } |
3303 | helixhorne | 484 | } |
3763 | terminx | 485 | } |
3303 | helixhorne | 486 | |
3763 | terminx | 487 | void calc_and_apply_fog(int32_t tile, int32_t shade, int32_t vis, int32_t pal) |
488 | { |
||
489 | fogcalc(tile, shade, vis, pal); |
||
490 | bglFogfv(GL_FOG_COLOR, fogcol); |
||
3303 | helixhorne | 491 | |
4393 | helixhorne | 492 | if (r_usenewshading < 2) |
4904 | terminx | 493 | bglFogf(GL_FOG_DENSITY, fogresult); |
494 | else |
||
3763 | terminx | 495 | { |
4904 | terminx | 496 | bglFogf(GL_FOG_START, fogresult); |
497 | bglFogf(GL_FOG_END, fogresult2); |
||
3763 | terminx | 498 | } |
3303 | helixhorne | 499 | } |
500 | |||
3763 | terminx | 501 | void calc_and_apply_fog_factor(int32_t tile, int32_t shade, int32_t vis, int32_t pal, float factor) |
3303 | helixhorne | 502 | { |
4393 | helixhorne | 503 | // NOTE: for r_usenewshading >= 2, the fog beginning/ending distance results are |
3959 | helixhorne | 504 | // unused. |
3763 | terminx | 505 | fogcalc(tile, shade, vis, pal); |
506 | bglFogfv(GL_FOG_COLOR, fogcol); |
||
3303 | helixhorne | 507 | |
4393 | helixhorne | 508 | if (r_usenewshading < 2) |
4904 | terminx | 509 | bglFogf(GL_FOG_DENSITY, fogresult*factor); |
510 | else |
||
3303 | helixhorne | 511 | { |
4904 | terminx | 512 | bglFogf(GL_FOG_START, (GLfloat) FULLVIS_BEGIN); |
513 | bglFogf(GL_FOG_END, (GLfloat) FULLVIS_END); |
||
3763 | terminx | 514 | } |
3303 | helixhorne | 515 | } |
516 | //////////////////// |
||
517 | |||
1357 | terminx | 518 | |
3401 | helixhorne | 519 | static float get_projhack_ratio(void) |
520 | { |
||
4904 | terminx | 521 | float rv; |
522 | |||
3401 | helixhorne | 523 | if (glprojectionhacks == 1) |
524 | { |
||
4904 | terminx | 525 | float const mul = (gshang * gshang); |
526 | rv = 1.05f + mul * mul * mul * mul; |
||
3401 | helixhorne | 527 | } |
4904 | terminx | 528 | else if (glprojectionhacks == 2) |
3401 | helixhorne | 529 | { |
4904 | terminx | 530 | float const abs_shang = Bfabsf(gshang); |
4907 | terminx | 531 | rv = (abs_shang > 0.7f) ? |
532 | 1.05f + 4.f * (abs_shang - 0.7f) : 1.f; |
||
3401 | helixhorne | 533 | } |
4904 | terminx | 534 | else |
535 | rv = 1.f; |
||
3401 | helixhorne | 536 | |
537 | // No projection hacks (legacy or new-aspect) |
||
4904 | terminx | 538 | return rv; |
3401 | helixhorne | 539 | } |
540 | |||
3041 | helixhorne | 541 | static void resizeglcheck(void) |
5 | Plagman | 542 | { |
4605 | terminx | 543 | #ifdef REDBLUEMODE |
584 | terminx | 544 | if (glredbluemode < lastglredbluemode) |
545 | { |
||
109 | terminx | 546 | glox1 = -1; |
547 | bglColorMask(1,1,1,1); |
||
584 | terminx | 548 | } |
549 | else if (glredbluemode != lastglredbluemode) |
||
550 | { |
||
109 | terminx | 551 | redblueclearcnt = 0; |
552 | } |
||
553 | lastglredbluemode = glredbluemode; |
||
4605 | terminx | 554 | #endif |
5 | Plagman | 555 | |
5001 | terminx | 556 | #ifndef EDUKE32_GLES |
109 | terminx | 557 | //FUK |
558 | if (lastglpolygonmode != glpolygonmode) |
||
559 | { |
||
560 | lastglpolygonmode = glpolygonmode; |
||
331 | terminx | 561 | switch (glpolygonmode) |
109 | terminx | 562 | { |
563 | default: |
||
331 | terminx | 564 | case 0: |
565 | bglPolygonMode(GL_FRONT_AND_BACK,GL_FILL); break; |
||
566 | case 1: |
||
567 | bglPolygonMode(GL_FRONT_AND_BACK,GL_LINE); break; |
||
568 | case 2: |
||
569 | bglPolygonMode(GL_FRONT_AND_BACK,GL_POINT); break; |
||
109 | terminx | 570 | } |
571 | } |
||
572 | if (glpolygonmode) //FUK |
||
573 | { |
||
574 | bglClearColor(1.0,1.0,1.0,0.0); |
||
575 | bglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); |
||
576 | bglDisable(GL_TEXTURE_2D); |
||
577 | } |
||
5001 | terminx | 578 | #else |
579 | bglPolygonMode(GL_FRONT_AND_BACK,GL_FILL); |
||
580 | #endif |
||
5 | Plagman | 581 | |
109 | terminx | 582 | if ((glox1 != windowx1) || (gloy1 != windowy1) || (glox2 != windowx2) || (gloy2 != windowy2)) |
583 | { |
||
3401 | helixhorne | 584 | const int32_t ourxdimen = (windowx2-windowx1+1); |
4658 | terminx | 585 | float ratio = get_projhack_ratio(); |
3401 | helixhorne | 586 | const int32_t fovcorrect = (ratio==0) ? 0 : (int32_t)(ourxdimen*ratio - ourxdimen); |
4623 | terminx | 587 | float m[4][4]; |
1114 | terminx | 588 | |
1454 | terminx | 589 | glox1 = (float)windowx1; gloy1 = (float)windowy1; |
590 | glox2 = (float)windowx2; gloy2 = (float)windowy2; |
||
109 | terminx | 591 | |
1961 | helixhorne | 592 | bglViewport(windowx1-(fovcorrect/2), yres-(windowy2+1), |
3401 | helixhorne | 593 | ourxdimen+fovcorrect, windowy2-windowy1+1); |
5 | Plagman | 594 | |
109 | terminx | 595 | bglMatrixMode(GL_PROJECTION); |
4675 | terminx | 596 | Bmemset(m,0,sizeof(m)); |
4658 | terminx | 597 | ratio = 1.f/ratio; |
598 | m[0][0] = fydimen * ratio; m[0][2] = 1.f; |
||
4656 | terminx | 599 | m[1][1] = fxdimen; m[1][2] = 1.f; |
4658 | terminx | 600 | m[2][2] = 1.f; m[2][3] = fydimen * ratio; |
4605 | terminx | 601 | m[3][2] =-1.f; |
109 | terminx | 602 | bglLoadMatrixf(&m[0][0]); |
5 | Plagman | 603 | |
109 | terminx | 604 | bglMatrixMode(GL_MODELVIEW); |
605 | bglLoadIdentity(); |
||
5 | Plagman | 606 | |
1064 | terminx | 607 | #ifdef USE_OPENGL |
109 | terminx | 608 | if (!nofog) bglEnable(GL_FOG); |
1064 | terminx | 609 | #endif |
5 | Plagman | 610 | |
109 | terminx | 611 | //bglEnable(GL_TEXTURE_2D); |
612 | } |
||
5 | Plagman | 613 | } |
614 | |||
4639 | terminx | 615 | static void fixtransparency(coltype *dapic, vec2_t dasiz, vec2_t dasiz2, int32_t dameth) |
5 | Plagman | 616 | { |
4485 | helixhorne | 617 | int32_t y, naxsiz2; |
4639 | terminx | 618 | vec2_t doxy = { dasiz2.x-1, dasiz2.y-1 }; |
5 | Plagman | 619 | |
4639 | terminx | 620 | if (dameth&4) { doxy.x = min(doxy.x, dasiz.x); doxy.y = min(doxy.y, dasiz.y); } |
621 | else { dasiz = dasiz2; } //Make repeating textures duplicate top/left parts |
||
3695 | helixhorne | 622 | |
4639 | terminx | 623 | dasiz.x--; dasiz.y--; naxsiz2 = -dasiz2.x; //Hacks for optimization inside loop |
5 | Plagman | 624 | |
109 | terminx | 625 | //Set transparent pixels to average color of neighboring opaque pixels |
626 | //Doing this makes bilinear filtering look much better for masked textures (I.E. sprites) |
||
4639 | terminx | 627 | for (y=doxy.y; y>=0; y--) |
109 | terminx | 628 | { |
4485 | helixhorne | 629 | int32_t x; |
4639 | terminx | 630 | coltype * wpptr = &dapic[y*dasiz2.x+doxy.x]; |
4485 | helixhorne | 631 | |
4639 | terminx | 632 | for (x=doxy.x; x>=0; x--,wpptr--) |
109 | terminx | 633 | { |
4485 | helixhorne | 634 | int32_t r=0, g=0, b=0, j=0; |
635 | |||
109 | terminx | 636 | if (wpptr->a) continue; |
3111 | helixhorne | 637 | |
109 | terminx | 638 | r = g = b = j = 0; |
3041 | helixhorne | 639 | if ((x> 0) && (wpptr[ -1].a)) { r += wpptr[ -1].r; g += wpptr[ -1].g; b += wpptr[ -1].b; j++; } |
4639 | terminx | 640 | if ((x<dasiz.x) && (wpptr[ +1].a)) { r += wpptr[ +1].r; g += wpptr[ +1].g; b += wpptr[ +1].b; j++; } |
3041 | helixhorne | 641 | if ((y> 0) && (wpptr[naxsiz2].a)) { r += wpptr[naxsiz2].r; g += wpptr[naxsiz2].g; b += wpptr[naxsiz2].b; j++; } |
4639 | terminx | 642 | if ((y<dasiz.y) && (wpptr[dasiz2.x].a)) { r += wpptr[dasiz2.x].r; g += wpptr[dasiz2.x].g; b += wpptr[dasiz2.x].b; j++; } |
331 | terminx | 643 | switch (j) |
109 | terminx | 644 | { |
331 | terminx | 645 | case 1: |
646 | wpptr->r = r ; wpptr->g = g ; wpptr->b = b ; break; |
||
647 | case 2: |
||
648 | wpptr->r = ((r + 1)>>1); wpptr->g = ((g + 1)>>1); wpptr->b = ((b + 1)>>1); break; |
||
649 | case 3: |
||
650 | wpptr->r = ((r*85+128)>>8); wpptr->g = ((g*85+128)>>8); wpptr->b = ((b*85+128)>>8); break; |
||
651 | case 4: |
||
652 | wpptr->r = ((r + 2)>>2); wpptr->g = ((g + 2)>>2); wpptr->b = ((b + 2)>>2); break; |
||
109 | terminx | 653 | } |
654 | } |
||
655 | } |
||
5 | Plagman | 656 | } |
657 | |||
4488 | helixhorne | 658 | void uploadtexture(int32_t doalloc, int32_t xsiz, int32_t ysiz, int32_t intexfmt, int32_t texfmt, |
659 | coltype *pic, int32_t tsizx, int32_t tsizy, int32_t dameth) |
||
5 | Plagman | 660 | { |
4485 | helixhorne | 661 | int32_t x2, y2, j, js=0; |
4486 | helixhorne | 662 | const int32_t hi = (dameth & DAMETH_HI) ? 1 : 0; |
663 | const int32_t nocompress = (dameth & DAMETH_NOCOMPRESS) ? 1 : 0; |
||
5 | Plagman | 664 | |
4486 | helixhorne | 665 | dameth &= ~(DAMETH_HI|DAMETH_NOCOMPRESS); |
916 | terminx | 666 | |
584 | terminx | 667 | if (gltexmaxsize <= 0) |
668 | { |
||
109 | terminx | 669 | GLint i = 0; |
670 | bglGetIntegerv(GL_MAX_TEXTURE_SIZE, &i); |
||
671 | if (!i) gltexmaxsize = 6; // 2^6 = 64 == default GL max texture size |
||
584 | terminx | 672 | else |
673 | { |
||
109 | terminx | 674 | gltexmaxsize = 0; |
675 | for (; i>1; i>>=1) gltexmaxsize++; |
||
676 | } |
||
677 | } |
||
5 | Plagman | 678 | |
109 | terminx | 679 | js = max(0,min(gltexmaxsize-1,gltexmiplevel)); |
680 | gltexmiplevel = js; |
||
681 | while ((xsiz>>js) > (1<<gltexmaxsize) || (ysiz>>js) > (1<<gltexmaxsize)) js++; |
||
5 | Plagman | 682 | |
990 | terminx | 683 | if (hi && !nocompress) js = r_downsize; |
916 | terminx | 684 | |
109 | terminx | 685 | /* |
686 | OSD_Printf("Uploading %dx%d %s as %s\n", xsiz,ysiz, |
||
1625 | terminx | 687 | (texfmt==GL_RGBA?"GL_RGBA": |
688 | texfmt==GL_RGB?"GL_RGB": |
||
689 | texfmt==GL_BGR?"GL_BGR": |
||
690 | texfmt==GL_BGRA?"GL_BGRA":"other"), |
||
691 | (intexfmt==GL_RGBA?"GL_RGBA": |
||
692 | intexfmt==GL_RGB?"GL_RGB": |
||
693 | intexfmt==GL_COMPRESSED_RGBA_ARB?"GL_COMPRESSED_RGBA_ARB": |
||
694 | intexfmt==GL_COMPRESSED_RGB_ARB?"GL_COMPRESSED_RGB_ARB":"other")); |
||
109 | terminx | 695 | */ |
696 | |||
584 | terminx | 697 | if (js == 0) |
698 | { |
||
109 | terminx | 699 | if (doalloc&1) |
700 | bglTexImage2D(GL_TEXTURE_2D,0,intexfmt,xsiz,ysiz,0,texfmt,GL_UNSIGNED_BYTE,pic); //loading 1st time |
||
701 | else |
||
702 | bglTexSubImage2D(GL_TEXTURE_2D,0,0,0,xsiz,ysiz,texfmt,GL_UNSIGNED_BYTE,pic); //overwrite old texture |
||
703 | } |
||
704 | |||
5 | Plagman | 705 | #if 0 |
109 | terminx | 706 | gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA8,xsiz,ysiz,texfmt,GL_UNSIGNED_BYTE,pic); //Needs C++ to link? |
5 | Plagman | 707 | #elif 1 |
109 | terminx | 708 | x2 = xsiz; y2 = ysiz; |
1229 | terminx | 709 | for (j=1; (x2 > 1) || (y2 > 1); j++) |
109 | terminx | 710 | { |
4485 | helixhorne | 711 | int32_t y; |
712 | int32_t x3 = max(1, x2 >> 1), y3 = max(1, y2 >> 1); // this came from the GL_ARB_texture_non_power_of_two spec |
||
109 | terminx | 713 | //x3 = ((x2+1)>>1); y3 = ((y2+1)>>1); |
4485 | helixhorne | 714 | |
1229 | terminx | 715 | for (y=0; y<y3; y++) |
109 | terminx | 716 | { |
4485 | helixhorne | 717 | int32_t x; |
718 | coltype *wpptr = &pic[y*x3], *rpptr = &pic[(y<<1)*x2]; |
||
719 | |||
1229 | terminx | 720 | for (x=0; x<x3; x++,wpptr++,rpptr+=2) |
109 | terminx | 721 | { |
4485 | helixhorne | 722 | int32_t r=0, g=0, b=0, a=0, k=0; |
723 | |||
3041 | helixhorne | 724 | if (rpptr[0].a) { r += rpptr[0].r; g += rpptr[0].g; b += rpptr[0].b; a += rpptr[0].a; k++; } |
725 | if ((x+x+1 < x2) && (rpptr[1].a)) { r += rpptr[1].r; g += rpptr[1].g; b += rpptr[1].b; a += rpptr[1].a; k++; } |
||
109 | terminx | 726 | if (y+y+1 < y2) |
727 | { |
||
3041 | helixhorne | 728 | if ((rpptr[x2].a)) { r += rpptr[x2 ].r; g += rpptr[x2 ].g; b += rpptr[x2 ].b; a += rpptr[x2 ].a; k++; } |
729 | if ((x+x+1 < x2) && (rpptr[x2+1].a)) { r += rpptr[x2+1].r; g += rpptr[x2+1].g; b += rpptr[x2+1].b; a += rpptr[x2+1].a; k++; } |
||
109 | terminx | 730 | } |
331 | terminx | 731 | switch (k) |
109 | terminx | 732 | { |
733 | case 0: |
||
331 | terminx | 734 | case 1: |
735 | wpptr->r = r; wpptr->g = g; wpptr->b = b; wpptr->a = a; break; |
||
736 | case 2: |
||
737 | wpptr->r = ((r+1)>>1); wpptr->g = ((g+1)>>1); wpptr->b = ((b+1)>>1); wpptr->a = ((a+1)>>1); break; |
||
738 | case 3: |
||
739 | wpptr->r = ((r*85+128)>>8); wpptr->g = ((g*85+128)>>8); wpptr->b = ((b*85+128)>>8); wpptr->a = ((a*85+128)>>8); break; |
||
740 | case 4: |
||
741 | wpptr->r = ((r+2)>>2); wpptr->g = ((g+2)>>2); wpptr->b = ((b+2)>>2); wpptr->a = ((a+2)>>2); break; |
||
742 | default: |
||
4680 | terminx | 743 | EDUKE32_UNREACHABLE_SECTION(break); |
109 | terminx | 744 | } |
745 | //if (wpptr->a) wpptr->a = 255; |
||
746 | } |
||
747 | } |
||
4639 | terminx | 748 | |
749 | if (tsizx >= 0) |
||
750 | { |
||
751 | vec2_t tsizzle; |
||
752 | vec2_t mnizzle = { x3, y3 }; |
||
753 | |||
754 | tsizzle.x = (tsizx+(1<<j)-1)>>j; |
||
755 | tsizzle.y = (tsizy+(1<<j)-1)>>j; |
||
756 | fixtransparency(pic, tsizzle, mnizzle, dameth); |
||
757 | } |
||
758 | |||
584 | terminx | 759 | if (j >= js) |
760 | { |
||
109 | terminx | 761 | if (doalloc&1) |
762 | bglTexImage2D(GL_TEXTURE_2D,j-js,intexfmt,x3,y3,0,texfmt,GL_UNSIGNED_BYTE,pic); //loading 1st time |
||
763 | else |
||
764 | bglTexSubImage2D(GL_TEXTURE_2D,j-js,0,0,x3,y3,texfmt,GL_UNSIGNED_BYTE,pic); //overwrite old texture |
||
765 | } |
||
766 | x2 = x3; y2 = y3; |
||
767 | } |
||
5 | Plagman | 768 | #endif |
769 | } |
||
770 | |||
2141 | helixhorne | 771 | |
2142 | helixhorne | 772 | #if 0 |
2141 | helixhorne | 773 | // TODO: make configurable |
774 | static int32_t tile_is_sky(int32_t tilenum) |
||
775 | { |
||
2142 | helixhorne | 776 | return return (tilenum >= 78 /*CLOUDYOCEAN*/ && tilenum <= 99 /*REDSKY2*/); |
2141 | helixhorne | 777 | } |
2142 | helixhorne | 778 | #else |
779 | # define tile_is_sky(x) (0) |
||
780 | #endif |
||
2141 | helixhorne | 781 | |
5001 | terminx | 782 | static void texture_setup(const int32_t dameth, int filter) |
3041 | helixhorne | 783 | { |
4623 | terminx | 784 | const GLuint clamp_mode = glinfo.clamptoedge ? GL_CLAMP_TO_EDGE : GL_CLAMP; |
785 | |||
5001 | terminx | 786 | if (filter == -1) |
787 | filter = gltexfiltermode; |
||
3041 | helixhorne | 788 | |
5001 | terminx | 789 | gltexfiltermode = clamp(gltexfiltermode, 0, NUMGLFILTERMODES - 1); |
790 | bglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glfiltermodes[filter].mag); |
||
791 | bglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glfiltermodes[filter].min); |
||
792 | |||
793 | #ifndef EDUKE32_GLES |
||
4605 | terminx | 794 | if (glinfo.maxanisotropy > 1.f) |
3041 | helixhorne | 795 | { |
5001 | terminx | 796 | uint32_t i = (unsigned)Blrintf(glinfo.maxanisotropy); |
4623 | terminx | 797 | |
798 | if ((unsigned)glanisotropy > i) |
||
799 | glanisotropy = i; |
||
800 | |||
3041 | helixhorne | 801 | bglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, glanisotropy); |
802 | } |
||
5001 | terminx | 803 | #endif |
3041 | helixhorne | 804 | |
4486 | helixhorne | 805 | if (!(dameth & DAMETH_CLAMPED)) |
3041 | helixhorne | 806 | { |
4623 | terminx | 807 | bglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, !tile_is_sky(dapic) ? GL_REPEAT : clamp_mode); |
3041 | helixhorne | 808 | bglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); |
809 | } |
||
810 | else |
||
811 | { |
||
5001 | terminx | 812 | // For sprite textures, clamping looks better than wrapping |
4623 | terminx | 813 | bglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clamp_mode); |
814 | bglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clamp_mode); |
||
3041 | helixhorne | 815 | } |
816 | } |
||
817 | |||
4491 | helixhorne | 818 | void gloadtile_art(int32_t dapic, int32_t dapal, int32_t dashade, int32_t dameth, pthtyp *pth, int32_t doalloc) |
5 | Plagman | 819 | { |
3146 | helixhorne | 820 | static int32_t fullbrightloadingpass = 0; |
821 | |||
4639 | terminx | 822 | vec2_t siz, tsiz = tilesiz[dapic]; |
3146 | helixhorne | 823 | |
584 | terminx | 824 | if (!glinfo.texnpot) |
825 | { |
||
5001 | terminx | 826 | for (siz.x = 1; siz.x < tsiz.x; siz.x += siz.x); |
827 | for (siz.y = 1; siz.y < tsiz.y; siz.y += siz.y); |
||
584 | terminx | 828 | } |
829 | else |
||
830 | { |
||
4639 | terminx | 831 | if ((tsiz.x|tsiz.y) == 0) |
832 | siz.x = siz.y = 1; |
||
584 | terminx | 833 | else |
834 | { |
||
4639 | terminx | 835 | siz.x = tsiz.x; |
836 | siz.y = tsiz.y; |
||
109 | terminx | 837 | } |
838 | } |
||
5 | Plagman | 839 | |
5001 | terminx | 840 | coltype *pic = (coltype *)Xmalloc(siz.x*siz.y*sizeof(coltype)); |
841 | char hasalpha = 0, hasfullbright = 0; |
||
5 | Plagman | 842 | |
109 | terminx | 843 | if (!waloff[dapic]) |
844 | { |
||
845 | //Force invalid textures to draw something - an almost purely transparency texture |
||
846 | //This allows the Z-buffer to be updated for mirrors (which are invalidated textures) |
||
847 | pic[0].r = pic[0].g = pic[0].b = 0; pic[0].a = 1; |
||
4639 | terminx | 848 | tsiz.x = tsiz.y = 1; hasalpha = 1; |
109 | terminx | 849 | } |
850 | else |
||
851 | { |
||
5056 | hendricks2 | 852 | const int dofullbright = !(picanm[dapic].sf & PICANM_NOFULLBRIGHT_BIT) && !(globalflags & GLOBAL_NO_GL_FULLBRIGHT); |
3145 | helixhorne | 853 | |
4898 | terminx | 854 | for (int y = 0; y < siz.y; y++) |
109 | terminx | 855 | { |
4898 | terminx | 856 | coltype *wpptr = &pic[y * siz.x]; |
857 | int32_t y2 = (y < tsiz.y) ? y : y - tsiz.y; |
||
3146 | helixhorne | 858 | |
4898 | terminx | 859 | for (int x = 0; x < siz.x; x++, wpptr++) |
109 | terminx | 860 | { |
4485 | helixhorne | 861 | int32_t dacol; |
4639 | terminx | 862 | int32_t x2 = (x < tsiz.x) ? x : x-tsiz.x; |
3146 | helixhorne | 863 | |
4639 | terminx | 864 | if ((dameth & DAMETH_CLAMPED) && (x >= tsiz.x || y >= tsiz.y)) //Clamp texture |
4485 | helixhorne | 865 | { |
866 | wpptr->r = wpptr->g = wpptr->b = wpptr->a = 0; |
||
867 | continue; |
||
868 | } |
||
3146 | helixhorne | 869 | |
4639 | terminx | 870 | dacol = *(char *)(waloff[dapic]+x2*tsiz.y+y2); |
3146 | helixhorne | 871 | |
248 | terminx | 872 | if (!fullbrightloadingpass) |
584 | terminx | 873 | { |
874 | // regular texture |
||
3145 | helixhorne | 875 | if (dacol > 239 && dacol != 255 && dofullbright) |
248 | terminx | 876 | hasfullbright = 1; |
3146 | helixhorne | 877 | |
248 | terminx | 878 | wpptr->a = 255; |
879 | } |
||
3146 | helixhorne | 880 | else |
584 | terminx | 881 | { |
882 | // texture with only fullbright areas |
||
883 | if (dacol < 240) // regular colors |
||
884 | { |
||
3146 | helixhorne | 885 | wpptr->a = 0; |
886 | hasalpha = 1; |
||
584 | terminx | 887 | } |
888 | else // fullbright |
||
889 | { |
||
248 | terminx | 890 | wpptr->a = 255; |
891 | } |
||
892 | } |
||
3146 | helixhorne | 893 | |
248 | terminx | 894 | if (dacol != 255) |
584 | terminx | 895 | { |
3761 | terminx | 896 | char *p = (char *)(palookup[dapal])+(int32_t)(dashade<<8); |
897 | dacol = (uint8_t)p[dacol]; |
||
248 | terminx | 898 | } |
584 | terminx | 899 | else |
900 | { |
||
3146 | helixhorne | 901 | wpptr->a = 0; |
902 | hasalpha = 1; |
||
109 | terminx | 903 | } |
3146 | helixhorne | 904 | |
905 | bricolor((palette_t *)wpptr, dacol); |
||
109 | terminx | 906 | } |
907 | } |
||
908 | } |
||
5 | Plagman | 909 | |
1762 | terminx | 910 | if (doalloc) bglGenTextures(1,(GLuint *)&pth->glpic); //# of textures (make OpenGL allocate structure) |
109 | terminx | 911 | bglBindTexture(GL_TEXTURE_2D,pth->glpic); |
5 | Plagman | 912 | |
4639 | terminx | 913 | fixtransparency(pic,tsiz,siz,dameth); |
4498 | helixhorne | 914 | |
5001 | terminx | 915 | int32_t npoty = 0; |
916 | |||
4639 | terminx | 917 | if (polymost_want_npotytex(dameth, siz.y) && |
918 | tsiz.x==siz.x && tsiz.y==siz.y) // XXX |
||
4498 | helixhorne | 919 | { |
920 | const int32_t nextpoty = 1<<((picsiz[dapic]>>4)+1); |
||
4639 | terminx | 921 | const int32_t ydif = nextpoty - siz.y; |
4498 | helixhorne | 922 | coltype *paddedpic; |
923 | |||
4639 | terminx | 924 | Bassert(ydif > 0 && ydif < siz.y); |
4498 | helixhorne | 925 | |
4639 | terminx | 926 | paddedpic = (coltype*) Xrealloc(pic, siz.x*nextpoty*sizeof(coltype)); |
4498 | helixhorne | 927 | |
928 | pic = paddedpic; |
||
4639 | terminx | 929 | Bmemcpy(&pic[siz.x*siz.y], pic, siz.x*ydif*sizeof(coltype)); |
930 | siz.y = tsiz.y = nextpoty; |
||
4498 | helixhorne | 931 | |
932 | npoty = PTH_NPOTWALL; |
||
933 | } |
||
934 | |||
5001 | terminx | 935 | uploadtexture(doalloc, siz.x, siz.y, hasalpha ? GL_RGBA : GL_RGB, GL_RGBA, pic, tsiz.x, tsiz.y, dameth); |
5 | Plagman | 936 | |
2978 | helixhorne | 937 | Bfree(pic); |
5 | Plagman | 938 | |
5001 | terminx | 939 | texture_setup(dameth, -1); |
940 | |||
109 | terminx | 941 | pth->picnum = dapic; |
942 | pth->palnum = dapal; |
||
3761 | terminx | 943 | pth->shade = dashade; |
109 | terminx | 944 | pth->effects = 0; |
4498 | helixhorne | 945 | pth->flags = TO_PTH_CLAMPED(dameth) | (hasalpha*PTH_HASALPHA) | npoty; |
109 | terminx | 946 | pth->hicr = NULL; |
947 | |||
3146 | helixhorne | 948 | if (hasfullbright && !fullbrightloadingpass) |
248 | terminx | 949 | { |
3146 | helixhorne | 950 | // Load the ONLY texture that'll be assembled with the regular one to |
951 | // make the final texture with fullbright pixels. |
||
248 | terminx | 952 | fullbrightloadingpass = 1; |
4485 | helixhorne | 953 | |
4491 | helixhorne | 954 | pth->ofb = (pthtyp *)Xcalloc(1,sizeof(pthtyp)); |
4486 | helixhorne | 955 | pth->flags |= PTH_HASFULLBRIGHT; |
235 | Plagman | 956 | |
4491 | helixhorne | 957 | gloadtile_art(dapic, dapal, 0, dameth, pth->ofb, 1); |
4485 | helixhorne | 958 | |
248 | terminx | 959 | fullbrightloadingpass = 0; |
960 | } |
||
5 | Plagman | 961 | } |
962 | |||
3758 | terminx | 963 | int32_t gloadtile_hi(int32_t dapic,int32_t dapalnum, int32_t facen, hicreplctyp *hicr, |
2639 | helixhorne | 964 | int32_t dameth, pthtyp *pth, int32_t doalloc, char effect) |
5 | Plagman | 965 | { |
5001 | terminx | 966 | if (!hicr) return -1; |
967 | |||
4485 | helixhorne | 968 | coltype *pic = NULL; |
5 | Plagman | 969 | |
5001 | terminx | 970 | char *picfil = NULL, *fn; |
971 | int32_t picfillen, intexfmt = GL_RGBA, filh; |
||
5 | Plagman | 972 | |
1784 | helixhorne | 973 | int32_t startticks=0, willprint=0; |
1754 | helixhorne | 974 | |
584 | terminx | 975 | if (facen > 0) |
976 | { |
||
109 | terminx | 977 | if (!hicr->skybox) return -1; |
978 | if (facen > 6) return -1; |
||
979 | if (!hicr->skybox->face[facen-1]) return -1; |
||
980 | fn = hicr->skybox->face[facen-1]; |
||
584 | terminx | 981 | } |
982 | else |
||
983 | { |
||
109 | terminx | 984 | if (!hicr->filename) return -1; |
985 | fn = hicr->filename; |
||
986 | } |
||
5 | Plagman | 987 | |
4680 | terminx | 988 | if (EDUKE32_PREDICT_FALSE((filh = kopen4load(fn, 0)) < 0)) |
584 | terminx | 989 | { |
921 | terminx | 990 | OSD_Printf("hightile: %s (pic %d) not found\n", fn, dapic); |
4605 | terminx | 991 | return -2; |
109 | terminx | 992 | } |
4485 | helixhorne | 993 | |
109 | terminx | 994 | picfillen = kfilelength(filh); |
5 | Plagman | 995 | |
109 | terminx | 996 | kclose(filh); // FIXME: shouldn't have to do this. bug in cache1d.c |
5 | Plagman | 997 | |
5001 | terminx | 998 | char hasalpha = 255; |
999 | texcacheheader cachead; |
||
1000 | int32_t gotcache = texcache_readtexheader(fn, picfillen+(dapalnum<<8), dameth, effect, &cachead, 0); |
||
1001 | vec2_t siz ={ 0, 0 }, tsiz; |
||
4485 | helixhorne | 1002 | |
3758 | terminx | 1003 | if (gotcache && !texcache_loadtile(&cachead, &doalloc, pth)) |
584 | terminx | 1004 | { |
4639 | terminx | 1005 | tsiz.x = cachead.xdim; |
1006 | tsiz.y = cachead.ydim; |
||
4486 | helixhorne | 1007 | hasalpha = (cachead.flags & CACHEAD_HASALPHA) ? 0 : 255; |
584 | terminx | 1008 | } |
1009 | else |
||
1010 | { |
||
2639 | helixhorne | 1011 | int32_t r, g, b; |
4485 | helixhorne | 1012 | int32_t j, y; |
2639 | helixhorne | 1013 | |
3758 | terminx | 1014 | gotcache = 0; // the compressed version will be saved to disk |
5 | Plagman | 1015 | |
109 | terminx | 1016 | if ((filh = kopen4load(fn, 0)) < 0) return -1; |
5 | Plagman | 1017 | |
4491 | helixhorne | 1018 | picfil = (char *)Xmalloc(picfillen+1); |
4680 | terminx | 1019 | if (EDUKE32_PREDICT_FALSE(kread(filh, picfil, picfillen) != picfillen)) |
2069 | helixhorne | 1020 | initprintf("warning: didn't fully read %s\n", fn); |
1021 | // prevent |
||
1022 | // Conditional jump or move depends on uninitialised value(s) |
||
1023 | // at kpegrend (kplib.c:1655) |
||
1024 | picfil[picfillen] = 0; |
||
109 | terminx | 1025 | kclose(filh); |
5 | Plagman | 1026 | |
109 | terminx | 1027 | // tsizx/y = replacement texture's natural size |
1028 | // xsiz/y = 2^x size of replacement |
||
5 | Plagman | 1029 | |
4639 | terminx | 1030 | kpgetdim(picfil,picfillen,&tsiz.x,&tsiz.y); |
1031 | if (tsiz.x == 0 || tsiz.y == 0) { Bfree(picfil); return -1; } |
||
5 | Plagman | 1032 | |
4639 | terminx | 1033 | pth->siz.x = tsiz.x; |
1034 | pth->siz.y = tsiz.y; |
||
1035 | |||
584 | terminx | 1036 | if (!glinfo.texnpot) |
1037 | { |
||
4639 | terminx | 1038 | for (siz.x=1; siz.x<tsiz.x; siz.x+=siz.x); |
1039 | for (siz.y=1; siz.y<tsiz.y; siz.y+=siz.y); |
||
584 | terminx | 1040 | } |
1041 | else |
||
1042 | { |
||
4639 | terminx | 1043 | siz.x = tsiz.x; |
1044 | siz.y = tsiz.y; |
||
109 | terminx | 1045 | } |
4639 | terminx | 1046 | pic = (coltype *)Xcalloc(siz.x,siz.y*sizeof(coltype)); |
5 | Plagman | 1047 | |
1754 | helixhorne | 1048 | startticks = getticks(); |
1049 | |||
5001 | terminx | 1050 | static coltype *lastpic = NULL; |
1051 | static char *lastfn = NULL; |
||
1052 | static int32_t lastsize = 0; |
||
1053 | |||
1610 | helixhorne | 1054 | if (lastpic && lastfn && !Bstrcmp(lastfn,fn)) |
1055 | { |
||
1784 | helixhorne | 1056 | willprint=1; |
4639 | terminx | 1057 | Bmemcpy(pic, lastpic, siz.x*siz.y*sizeof(coltype)); |
1610 | helixhorne | 1058 | } |
1059 | else |
||
1060 | { |
||
4639 | terminx | 1061 | if (kprender(picfil,picfillen,(intptr_t)pic,siz.x*sizeof(coltype),siz.x,siz.y)) { Bfree(picfil); Bfree(pic); return -2; } |
1784 | helixhorne | 1062 | willprint=2; |
665 | terminx | 1063 | |
1610 | helixhorne | 1064 | if (hicprecaching) |
1065 | { |
||
1066 | lastfn = fn; // careful... |
||
1067 | if (!lastpic) |
||
1068 | { |
||
4639 | terminx | 1069 | lastpic = (coltype *)Bmalloc(siz.x*siz.y*sizeof(coltype)); |
1070 | lastsize = siz.x*siz.y; |
||
1610 | helixhorne | 1071 | } |
4639 | terminx | 1072 | else if (lastsize < siz.x*siz.y) |
1610 | helixhorne | 1073 | { |
1074 | Bfree(lastpic); |
||
4639 | terminx | 1075 | lastpic = (coltype *)Bmalloc(siz.x*siz.y*sizeof(coltype)); |
1610 | helixhorne | 1076 | } |
1077 | if (lastpic) |
||
4639 | terminx | 1078 | Bmemcpy(lastpic, pic, siz.x*siz.y*sizeof(coltype)); |
1610 | helixhorne | 1079 | } |
1080 | else if (lastpic) |
||
1081 | { |
||
1082 | Bfree(lastpic); lastpic=NULL; |
||
1083 | lastfn = NULL; |
||
1084 | lastsize = 0; |
||
1085 | } |
||
1086 | } |
||
1087 | |||
665 | terminx | 1088 | r=(glinfo.bgra)?hictinting[dapalnum].r:hictinting[dapalnum].b; |
1089 | g=hictinting[dapalnum].g; |
||
1090 | b=(glinfo.bgra)?hictinting[dapalnum].b:hictinting[dapalnum].r; |
||
4639 | terminx | 1091 | for (y=0,j=0; y<tsiz.y; y++,j+=siz.x) |
109 | terminx | 1092 | { |
1093 | coltype tcol; |
||
2639 | helixhorne | 1094 | char *cptr = britable[gammabrightness ? 0 : curbrightness]; |
4485 | helixhorne | 1095 | coltype *rpptr = &pic[j]; |
5 | Plagman | 1096 | |
4485 | helixhorne | 1097 | int32_t x; |
1098 | |||
4639 | terminx | 1099 | for (x=0; x<tsiz.x; x++) |
109 | terminx | 1100 | { |
1101 | tcol.b = cptr[rpptr[x].b]; |
||
1102 | tcol.g = cptr[rpptr[x].g]; |
||
1103 | tcol.r = cptr[rpptr[x].r]; |
||
4639 | terminx | 1104 | tcol.a = rpptr[x].a; |
1105 | hasalpha &= rpptr[x].a; |
||
5 | Plagman | 1106 | |
4486 | helixhorne | 1107 | if (effect & HICTINT_GRAYSCALE) |
584 | terminx | 1108 | { |
4889 | terminx | 1109 | tcol.g = tcol.r = tcol.b = (uint8_t) ((tcol.r * GRAYSCALE_COEFF_RED) + (tcol.g * GRAYSCALE_COEFF_GREEN) + |
1110 | (tcol.b * GRAYSCALE_COEFF_BLUE)); |
||
109 | terminx | 1111 | } |
4486 | helixhorne | 1112 | |
1113 | if (effect & HICTINT_INVERT) |
||
584 | terminx | 1114 | { |
109 | terminx | 1115 | tcol.b = 255-tcol.b; |
1116 | tcol.g = 255-tcol.g; |
||
1117 | tcol.r = 255-tcol.r; |
||
1118 | } |
||
4486 | helixhorne | 1119 | |
1120 | if (effect & HICTINT_COLORIZE) |
||
665 | terminx | 1121 | { |
1205 | terminx | 1122 | tcol.b = min((int32_t)((tcol.b)*r)/64,255); |
1123 | tcol.g = min((int32_t)((tcol.g)*g)/64,255); |
||
1124 | tcol.r = min((int32_t)((tcol.r)*b)/64,255); |
||
665 | terminx | 1125 | } |
5 | Plagman | 1126 | |
4639 | terminx | 1127 | rpptr[x] = tcol; |
109 | terminx | 1128 | } |
1129 | } |
||
2639 | helixhorne | 1130 | |
4486 | helixhorne | 1131 | if ((!(dameth & DAMETH_CLAMPED)) || facen) //Duplicate texture pixels (wrapping tricks for non power of 2 texture sizes) |
109 | terminx | 1132 | { |
4639 | terminx | 1133 | if (siz.x > tsiz.x) //Copy left to right |
109 | terminx | 1134 | { |
1205 | terminx | 1135 | int32_t *lptr = (int32_t *)pic; |
4639 | terminx | 1136 | for (y=0; y<tsiz.y; y++,lptr+=siz.x) |
1137 | Bmemcpy(&lptr[tsiz.x],lptr,(siz.x-tsiz.x)<<2); |
||
109 | terminx | 1138 | } |
4639 | terminx | 1139 | if (siz.y > tsiz.y) //Copy top to bottom |
1140 | Bmemcpy(&pic[siz.x*tsiz.y],pic,(siz.y-tsiz.y)*siz.x<<2); |
||
109 | terminx | 1141 | } |
2639 | helixhorne | 1142 | |
5001 | terminx | 1143 | int32_t texfmt; |
1144 | |||
584 | terminx | 1145 | if (!glinfo.bgra) |
1146 | { |
||
5001 | terminx | 1147 | texfmt = GL_RGBA; |
1148 | |||
4639 | terminx | 1149 | for (j=siz.x*siz.y-1; j>=0; j--) |
109 | terminx | 1150 | swapchar(&pic[j].r, &pic[j].b); |
584 | terminx | 1151 | } |
1152 | else texfmt = GL_BGRA; |
||
2639 | helixhorne | 1153 | |
1527 | terminx | 1154 | Bfree(picfil); picfil = 0; |
5 | Plagman | 1155 | |
4639 | terminx | 1156 | if (tsiz.x>>r_downsize <= tilesiz[dapic].x || tsiz.y>>r_downsize <= tilesiz[dapic].y) |
4486 | helixhorne | 1157 | hicr->flags |= (HICR_NOCOMPRESS + HICR_NOSAVE); |
1336 | terminx | 1158 | |
4486 | helixhorne | 1159 | if (glinfo.texcompr && glusetexcompr && !(hicr->flags & HICR_NOSAVE)) |
1761 | terminx | 1160 | intexfmt = (hasalpha == 255) ? GL_COMPRESSED_RGB_ARB : GL_COMPRESSED_RGBA_ARB; |
109 | terminx | 1161 | else if (hasalpha == 255) intexfmt = GL_RGB; |
5 | Plagman | 1162 | |
2639 | helixhorne | 1163 | if ((doalloc&3)==1) |
1164 | bglGenTextures(1, &pth->glpic); //# of textures (make OpenGL allocate structure) |
||
109 | terminx | 1165 | bglBindTexture(GL_TEXTURE_2D,pth->glpic); |
5 | Plagman | 1166 | |
4639 | terminx | 1167 | fixtransparency(pic,tsiz,siz,dameth); |
1168 | uploadtexture(doalloc,siz.x,siz.y,intexfmt,texfmt,pic,-1,tsiz.y, |
||
4486 | helixhorne | 1169 | dameth | DAMETH_HI | (hicr->flags & HICR_NOCOMPRESS ? DAMETH_NOCOMPRESS : 0)); |
109 | terminx | 1170 | } |
5 | Plagman | 1171 | |
109 | terminx | 1172 | // precalculate scaling parameters for replacement |
584 | terminx | 1173 | if (facen > 0) |
1174 | { |
||
4639 | terminx | 1175 | pth->scale.x = (float)tsiz.x * (1.0f/64.f); |
1176 | pth->scale.y = (float)tsiz.y * (1.0f/64.f); |
||
584 | terminx | 1177 | } |
1178 | else |
||
1179 | { |
||
4639 | terminx | 1180 | pth->scale.x = (float)tsiz.x / (float)tilesiz[dapic].x; |
1181 | pth->scale.y = (float)tsiz.y / (float)tilesiz[dapic].y; |
||
109 | terminx | 1182 | } |
5 | Plagman | 1183 | |
5001 | terminx | 1184 | #ifdef EDUKE32_TOUCH_DEVICES |
1185 | texture_setup(dameth, 5); |
||
1186 | #else |
||
1187 | texture_setup(dameth, -1); |
||
1188 | #endif |
||
2639 | helixhorne | 1189 | |
4623 | terminx | 1190 | DO_FREE_AND_NULL(pic); |
109 | terminx | 1191 | |
4639 | terminx | 1192 | if (tsiz.x>>r_downsize <= tilesiz[dapic].x || tsiz.y>>r_downsize <= tilesiz[dapic].y) |
1193 | hicr->flags |= HICR_NOCOMPRESS | HICR_NOSAVE; |
||
1336 | terminx | 1194 | |
109 | terminx | 1195 | pth->picnum = dapic; |
1196 | pth->effects = effect; |
||
4639 | terminx | 1197 | pth->flags = TO_PTH_CLAMPED(dameth) | PTH_HIGHTILE | ((facen>0) * PTH_SKYBOX) | ((hasalpha != 255) ? PTH_HASALPHA : 0); |
109 | terminx | 1198 | pth->skyface = facen; |
1199 | pth->hicr = hicr; |
||
1200 | |||
4752 | terminx | 1201 | if (!gotcache && glinfo.texcompr && glusetexcompr && glusetexcache && !(hicr->flags & HICR_NOSAVE)) |
1202 | { |
||
1203 | const int32_t nonpow2 = check_nonpow2(siz.x) || check_nonpow2(siz.y); |
||
4485 | helixhorne | 1204 | |
4752 | terminx | 1205 | // save off the compressed version |
1206 | cachead.quality = (hicr->flags & HICR_NOCOMPRESS) ? 0 : r_downsize; |
||
1207 | cachead.xdim = tsiz.x >> cachead.quality; |
||
1208 | cachead.ydim = tsiz.y >> cachead.quality; |
||
4485 | helixhorne | 1209 | |
4752 | terminx | 1210 | // handle nocompress: |
1211 | cachead.flags = nonpow2 * CACHEAD_NONPOW2 | (hasalpha != 255 ? CACHEAD_HASALPHA : 0) | |
||
1212 | (hicr->flags & HICR_NOCOMPRESS ? CACHEAD_NOCOMPRESS : 0); |
||
4486 | helixhorne | 1213 | |
4752 | terminx | 1214 | /// OSD_Printf("Caching \"%s\"\n", fn); |
1215 | texcache_writetex(fn, picfillen + (dapalnum << 8), dameth, effect, &cachead); |
||
1754 | helixhorne | 1216 | |
4752 | terminx | 1217 | if (willprint) |
1218 | { |
||
1219 | int32_t etime = getticks() - startticks; |
||
1220 | if (etime >= MIN_CACHETIME_PRINT) |
||
1221 | OSD_Printf("Load tile %4d: p%d-m%d-e%d %s... cached... %d ms\n", dapic, dapalnum, dameth, effect, |
||
1222 | willprint == 2 ? fn : "", etime); |
||
1223 | willprint = 0; |
||
109 | terminx | 1224 | } |
4752 | terminx | 1225 | else |
1226 | OSD_Printf("Cached \"%s\"\n", fn); |
||
1227 | } |
||
109 | terminx | 1228 | |
1784 | helixhorne | 1229 | if (willprint) |
1230 | { |
||
1231 | int32_t etime = getticks()-startticks; |
||
1232 | if (etime>=MIN_CACHETIME_PRINT) |
||
1233 | OSD_Printf("Load tile %4d: p%d-m%d-e%d %s... %d ms\n", dapic, dapalnum, dameth, effect, |
||
1234 | willprint==2 ? fn : "", etime); |
||
1235 | } |
||
1754 | helixhorne | 1236 | |
109 | terminx | 1237 | return 0; |
5 | Plagman | 1238 | } |
1239 | |||
4623 | terminx | 1240 | void polymost_setupdetailtexture(const int32_t texunits, const int32_t tex) |
1241 | { |
||
1242 | bglActiveTextureARB(texunits); |
||
1243 | |||
1244 | bglEnable(GL_TEXTURE_2D); |
||
1245 | bglBindTexture(GL_TEXTURE_2D, tex); |
||
1246 | |||
1247 | bglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); |
||
1248 | bglTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); |
||
1249 | |||
1250 | bglTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB); |
||
1251 | bglTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); |
||
1252 | |||
1253 | bglTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE); |
||
1254 | bglTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); |
||
1255 | |||
1256 | bglTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); |
||
1257 | bglTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB); |
||
1258 | bglTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); |
||
1259 | |||
1260 | bglTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 2.0f); |
||
1261 | |||
1262 | bglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); |
||
1263 | bglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); |
||
1264 | } |
||
1265 | |||
1266 | void polymost_setupglowtexture(const int32_t texunits, const int32_t tex) |
||
1267 | { |
||
1268 | bglActiveTextureARB(texunits); |
||
1269 | |||
1270 | bglEnable(GL_TEXTURE_2D); |
||
1271 | bglBindTexture(GL_TEXTURE_2D, tex); |
||
1272 | |||
1273 | bglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); |
||
1274 | bglTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB); |
||
1275 | |||
1276 | bglTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB); |
||
1277 | bglTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); |
||
1278 | |||
1279 | bglTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE); |
||
1280 | bglTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); |
||
1281 | |||
1282 | bglTexEnvf(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE); |
||
1283 | bglTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_ONE_MINUS_SRC_ALPHA); |
||
1284 | |||
1285 | bglTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE); |
||
1286 | bglTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB); |
||
1287 | bglTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); |
||
1288 | |||
1289 | bglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); |
||
1290 | bglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); |
||
1291 | } |
||
5 | Plagman | 1292 | #endif |
1293 | |||
109 | terminx | 1294 | //(dpx,dpy) specifies an n-sided polygon. The polygon must be a convex clockwise loop. |
1295 | // n must be <= 8 (assume clipping can double number of vertices) |
||
1296 | //method: 0:solid, 1:masked(255 is transparent), 2:transluscent #1, 3:transluscent #2 |
||
1297 | // +4 means it's a sprite, so wraparound isn't needed |
||
3543 | hendricks2 | 1298 | |
1299 | // drawpoly's hack globals |
||
1205 | terminx | 1300 | static int32_t pow2xsplit = 0, skyclamphack = 0; |
3543 | hendricks2 | 1301 | static float alpha = 0.f; |
5 | Plagman | 1302 | |
4640 | terminx | 1303 | static inline pthtyp *our_texcache_fetch(int32_t dameth) |
4010 | helixhorne | 1304 | { |
1305 | // r_usetileshades 1 is TX's method. |
||
5056 | hendricks2 | 1306 | return texcache_fetch(globalpicnum, globalpal, getpalookup((r_usetileshades == 1 && !(globalflags & GLOBAL_NO_GL_TILESHADES)) ? globvis>>3 : 0, globalshade), dameth); |
4010 | helixhorne | 1307 | } |
1308 | |||
4671 | terminx | 1309 | static void drawpoly(vec2f_t *dpxy, int32_t n, int32_t method) |
5 | Plagman | 1310 | { |
4623 | terminx | 1311 | const int32_t method_ = method; |
1312 | int32_t i, j, k; |
||
1313 | vec2_t tsiz; |
||
1314 | float f, r, ox, oy, oz, ox2, oy2, oz2, dd[16], uu[16], vv[16], px[16], py[16]; |
||
4406 | helixhorne | 1315 | |
2014 | helixhorne | 1316 | #ifdef YAX_ENABLE |
1317 | if (g_nodraw) return; |
||
1318 | #endif |
||
5 | Plagman | 1319 | |
4605 | terminx | 1320 | if (method == -1 || (uint32_t)globalpicnum >= MAXTILES) return; |
1321 | |||
109 | terminx | 1322 | if (n == 3) |
1323 | { |
||
4671 | terminx | 1324 | if ((dpxy[0].x-dpxy[1].x) * (dpxy[2].y-dpxy[1].y) >= |
1325 | (dpxy[2].x-dpxy[1].x) * (dpxy[0].y-dpxy[1].y)) return; //for triangle |
||
109 | terminx | 1326 | } |
1327 | else |
||
1328 | { |
||
1329 | f = 0; //f is area of polygon / 2 |
||
4671 | terminx | 1330 | for (i=n-2,j=n-1,k=0; k<n; i=j,j=k,k++) |
1331 | f += (dpxy[i].x-dpxy[k].x)*dpxy[j].y; |
||
109 | terminx | 1332 | if (f <= 0) return; |
1333 | } |
||
5 | Plagman | 1334 | |
109 | terminx | 1335 | //Load texture (globalpicnum) |
1336 | setgotpic(globalpicnum); |
||
4623 | terminx | 1337 | tsiz = tilesiz[globalpicnum]; |
1338 | |||
355 | terminx | 1339 | if (palookup[globalpal] == NULL) |
1340 | globalpal = 0; |
||
109 | terminx | 1341 | if (!waloff[globalpicnum]) |
1342 | { |
||
1343 | loadtile(globalpicnum); |
||
1344 | if (!waloff[globalpicnum]) |
||
1345 | { |
||
3784 | terminx | 1346 | if (getrendermode() < REND_POLYMOST) return; |
4623 | terminx | 1347 | tsiz.x = tsiz.y = 1; |
1348 | method = 1; //Hack to update Z-buffer for invalid mirror textures |
||
109 | terminx | 1349 | } |
1350 | } |
||
5 | Plagman | 1351 | |
4605 | terminx | 1352 | j = 0; |
1353 | |||
4623 | terminx | 1354 | for (i=0; i<n; i++) |
109 | terminx | 1355 | { |
4671 | terminx | 1356 | ox = dpxy[i].x-ghalfx; |
1357 | oy = dpxy[i].y-ghoriz; |
||
4623 | terminx | 1358 | oz = ghalfx; |
5 | Plagman | 1359 | |
4623 | terminx | 1360 | //Up/down rotation |
1361 | ox2 = ox; |
||
1362 | oy2 = oy*gchang - oz*gshang; |
||
1363 | oz2 = oy*gshang + oz*gchang; |
||
5 | Plagman | 1364 | |
4623 | terminx | 1365 | //Tilt rotation |
1366 | ox = ox2*gctang - oy2*gstang; |
||
1367 | oy = ox2*gstang + oy2*gctang; |
||
1368 | oz = oz2; |
||
5 | Plagman | 1369 | |
4623 | terminx | 1370 | r = ghalfx / oz; |
5 | Plagman | 1371 | |
4671 | terminx | 1372 | dd[j] = (dpxy[i].x*gdx + dpxy[i].y*gdy + gdo)*r; |
1373 | uu[j] = (dpxy[i].x*gux + dpxy[i].y*guy + guo)*r; |
||
1374 | vv[j] = (dpxy[i].x*gvx + dpxy[i].y*gvy + gvo)*r; |
||
5 | Plagman | 1375 | |
4623 | terminx | 1376 | px[j] = ox*r + ghalfx; |
1377 | py[j] = oy*r + ghoriz; |
||
1378 | if ((!j) || (px[j] != px[j-1]) || (py[j] != py[j-1])) j++; |
||
109 | terminx | 1379 | } |
4623 | terminx | 1380 | |
109 | terminx | 1381 | while ((j >= 3) && (px[j-1] == px[0]) && (py[j-1] == py[0])) j--; |
1382 | if (j < 3) return; |
||
5 | Plagman | 1383 | |
1384 | #ifdef USE_OPENGL |
||
3784 | terminx | 1385 | if (getrendermode() >= REND_POLYMOST) |
109 | terminx | 1386 | { |
4605 | terminx | 1387 | float hackscx = 1.f, hackscy = 1.f; |
4406 | helixhorne | 1388 | int32_t texunits = GL_TEXTURE0_ARB; |
4605 | terminx | 1389 | int32_t xx, yy; |
5 | Plagman | 1390 | |
4623 | terminx | 1391 | int32_t jj = j; |
1392 | |||
4489 | helixhorne | 1393 | if (skyclamphack) method |= DAMETH_CLAMPED; |
5001 | terminx | 1394 | pthtyp *pth = our_texcache_fetch(method&(~3)); |
244 | Plagman | 1395 | |
1920 | helixhorne | 1396 | if (!pth) |
1397 | { |
||
1398 | if (editstatus) |
||
1399 | { |
||
1400 | Bsprintf(ptempbuf, "pth==NULL! (bad pal?) pic=%d pal=%d", globalpicnum, globalpal); |
||
1401 | polymost_printext256(8,8, editorcolors[15],editorcolors[5], ptempbuf, 0); |
||
1402 | } |
||
1403 | return; |
||
1404 | } |
||
1405 | |||
4623 | terminx | 1406 | if (pth->flags & PTH_HASFULLBRIGHT && r_fullbrights && indrawroomsandmasks) |
1407 | { |
||
1408 | if (!fullbrightdrawingpass) |
||
1409 | fullbrightdrawingpass = 1; |
||
1410 | else if (fullbrightdrawingpass == 2) |
||
1411 | pth = pth->ofb; |
||
1412 | } |
||
244 | Plagman | 1413 | |
3741 | Plagman | 1414 | // If we aren't rendmode 3, we're in Polymer, which means this code is |
1415 | // used for rotatesprite only. Polymer handles all the material stuff, |
||
1416 | // just submit the geometry and don't mess with textures. |
||
3784 | terminx | 1417 | if (getrendermode() == REND_POLYMOST) |
3741 | Plagman | 1418 | { |
1419 | bglBindTexture(GL_TEXTURE_2D, pth ? pth->glpic : 0); |
||
5 | Plagman | 1420 | |
3741 | Plagman | 1421 | if (srepeat) |
1422 | bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); |
||
1423 | if (trepeat) |
||
1424 | bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); |
||
1425 | } |
||
590 | plagman | 1426 | |
504 | Plagman | 1427 | // texture scale by parkar request |
4680 | terminx | 1428 | if (pth && pth->hicr && !drawingskybox && ((pth->hicr->scale.x != 1.0f) || (pth->hicr->scale.y != 1.0f))) |
504 | Plagman | 1429 | { |
1430 | bglMatrixMode(GL_TEXTURE); |
||
1431 | bglLoadIdentity(); |
||
4680 | terminx | 1432 | bglScalef(pth->hicr->scale.x, pth->hicr->scale.y, 1.0f); |
504 | Plagman | 1433 | bglMatrixMode(GL_MODELVIEW); |
1434 | } |
||
1435 | |||
5001 | terminx | 1436 | #ifndef EDUKE32_GLES |
504 | Plagman | 1437 | // detail texture |
5001 | terminx | 1438 | pthtyp *detailpth = NULL; |
4605 | terminx | 1439 | if (r_detailmapping && usehightile && !drawingskybox && hicfindsubst(globalpicnum, DETAILPAL)) |
3761 | terminx | 1440 | detailpth = texcache_fetch(globalpicnum, DETAILPAL, 0, method&(~3)); |
459 | Plagman | 1441 | |
1226 | plagman | 1442 | if (detailpth && detailpth->hicr && (detailpth->hicr->palnum == DETAILPAL)) |
459 | Plagman | 1443 | { |
4623 | terminx | 1444 | polymost_setupdetailtexture(++texunits, detailpth ? detailpth->glpic : 0); |
459 | Plagman | 1445 | |
4680 | terminx | 1446 | f = detailpth ? detailpth->hicr->scale.x : 1.f; |
459 | Plagman | 1447 | |
497 | Plagman | 1448 | bglMatrixMode(GL_TEXTURE); |
1449 | bglLoadIdentity(); |
||
512 | Plagman | 1450 | |
4680 | terminx | 1451 | if (pth && pth->hicr && ((pth->hicr->scale.x != 1.0f) || (pth->hicr->scale.y != 1.0f))) |
1452 | bglScalef(pth->hicr->scale.x, pth->hicr->scale.y, 1.0f); |
||
512 | Plagman | 1453 | |
4680 | terminx | 1454 | if (detailpth && detailpth->hicr && ((detailpth->hicr->scale.x != 1.0f) || (detailpth->hicr->scale.y != 1.0f))) |
1455 | bglScalef(detailpth->hicr->scale.x, detailpth->hicr->scale.y, 1.0f); |
||
512 | Plagman | 1456 | |
497 | Plagman | 1457 | bglMatrixMode(GL_MODELVIEW); |
459 | Plagman | 1458 | } |
1459 | |||
504 | Plagman | 1460 | // glow texture |
5001 | terminx | 1461 | pthtyp *glowpth = NULL; |
4605 | terminx | 1462 | if (r_glowmapping && usehightile && !drawingskybox && hicfindsubst(globalpicnum, GLOWPAL)) |
3761 | terminx | 1463 | glowpth = texcache_fetch(globalpicnum, GLOWPAL, 0, method&(~3)); |
497 | Plagman | 1464 | |
1226 | plagman | 1465 | if (glowpth && glowpth->hicr && (glowpth->hicr->palnum == GLOWPAL)) |
4623 | terminx | 1466 | polymost_setupglowtexture(++texunits, glowpth ? glowpth->glpic : 0); |
5001 | terminx | 1467 | #endif |
497 | Plagman | 1468 | |
4486 | helixhorne | 1469 | if (pth && (pth->flags & PTH_HIGHTILE)) |
109 | terminx | 1470 | { |
4639 | terminx | 1471 | hackscx = pth->scale.x; |
1472 | hackscy = pth->scale.y; |
||
1473 | tsiz.x = pth->siz.x; |
||
1474 | tsiz.y = pth->siz.y; |
||
109 | terminx | 1475 | } |
5 | Plagman | 1476 | |
4623 | terminx | 1477 | xx = tsiz.x; |
1478 | yy = tsiz.y; |
||
4605 | terminx | 1479 | |
584 | terminx | 1480 | if (!glinfo.texnpot) |
1481 | { |
||
4623 | terminx | 1482 | for (xx=1; xx<tsiz.x; xx+=xx) |
2416 | helixhorne | 1483 | { |
1484 | /* do nothing */ |
||
1485 | } |
||
4623 | terminx | 1486 | for (yy=1; yy<tsiz.y; yy+=yy) |
2416 | helixhorne | 1487 | { |
1488 | /* do nothing */ |
||
1489 | } |
||
584 | terminx | 1490 | } |
5 | Plagman | 1491 | |
4605 | terminx | 1492 | ox2 = 1.0f/xx; |
1493 | oy2 = 1.0f/yy; |
||
1494 | |||
584 | terminx | 1495 | if ((!(method&3)) && (!fullbrightdrawingpass)) |
1496 | { |
||
475 | Plagman | 1497 | bglDisable(GL_BLEND); |
1229 | terminx | 1498 | bglDisable(GL_ALPHA_TEST); |
584 | terminx | 1499 | } |
1500 | else |
||
1501 | { |
||
4605 | terminx | 1502 | float al = 0.f; // PLAG : default alphacut was 0.32 before goodalpha |
1503 | if (pth && pth->hicr && pth->hicr->alphacut >= 0.f) al = pth->hicr->alphacut; |
||
109 | terminx | 1504 | if (alphahackarray[globalpicnum]) |
1505 | al=alphahackarray[globalpicnum]; |
||
4605 | terminx | 1506 | if (!waloff[globalpicnum]) al = 0.f; // invalid textures ignore the alpha cutoff settings |
1229 | terminx | 1507 | bglEnable(GL_BLEND); |
109 | terminx | 1508 | bglEnable(GL_ALPHA_TEST); |
1509 | bglAlphaFunc(GL_GREATER,al); |
||
1510 | } |
||
5 | Plagman | 1511 | |
109 | terminx | 1512 | { |
1513 | float pc[4]; |
||
3763 | terminx | 1514 | |
4394 | helixhorne | 1515 | #ifdef POLYMER |
5056 | hendricks2 | 1516 | if (getrendermode() == REND_POLYMER && pr_artmapping && !(globalflags & GLOBAL_NO_GL_TILESHADES) && polymer_eligible_for_artmap(globalpicnum, pth)) |
4394 | helixhorne | 1517 | pc[0] = pc[1] = pc[2] = 1.0f; |
1518 | else |
||
1519 | #endif |
||
1520 | pc[0] = pc[1] = pc[2] = getshadefactor(globalshade); |
||
1521 | |||
3543 | hendricks2 | 1522 | // spriteext full alpha control |
4623 | terminx | 1523 | pc[3] = float_trans[method&3] * (1.f - alpha); |
3543 | hendricks2 | 1524 | |
109 | terminx | 1525 | // tinting happens only to hightile textures, and only if the texture we're |
1526 | // rendering isn't for the same palette as what we asked for |
||
4486 | helixhorne | 1527 | if (!(hictinting[globalpal].f & HICTINT_COLORIZE)) |
943 | terminx | 1528 | { |
4486 | helixhorne | 1529 | if (pth && (pth->flags & PTH_HIGHTILE)) |
384 | terminx | 1530 | { |
5055 | hendricks2 | 1531 | if (pth->palnum != globalpal || (hictinting[globalpal].f & HICTINT_APPLYOVERALTPAL)) |
4487 | helixhorne | 1532 | hictinting_apply(pc, globalpal); |
1533 | |||
1534 | if (have_basepal_tint()) |
||
1535 | hictinting_apply(pc, MAXPALOOKUPS-1); |
||
384 | terminx | 1536 | } |
943 | terminx | 1537 | // hack: this is for drawing the 8-bit crosshair recolored in polymost |
4486 | helixhorne | 1538 | else if (hictinting[globalpal].f & HICTINT_USEONART) |
4487 | helixhorne | 1539 | hictinting_apply(pc, globalpal); |
943 | terminx | 1540 | } |
384 | terminx | 1541 | |
109 | terminx | 1542 | bglColor4f(pc[0],pc[1],pc[2],pc[3]); |
1543 | } |
||
5 | Plagman | 1544 | |
109 | terminx | 1545 | //Hack for walls&masked walls which use textures that are not a power of 2 |
4623 | terminx | 1546 | if ((pow2xsplit) && (tsiz.x != xx)) |
109 | terminx | 1547 | { |
4623 | terminx | 1548 | int32_t nn, ix0, ix1; |
5 | Plagman | 1549 | |
4623 | terminx | 1550 | float ngdx = 0.f, ngdy = 0.f, ngdo = 0.f, ngux = 0.f, nguy = 0.f, nguo = 0.f, uoffs; |
1551 | float ngvx = 0.f, ngvy = 0.f, ngvo = 0.f, dp, up, vp, du0 = 0.f, du1 = 0.f, dui, duj; |
||
1552 | |||
1553 | ox = py[1]-py[2]; oy = py[2]-py[0]; oz = py[0]-py[1]; |
||
1554 | r = 1.f / (ox*px[0] + oy*px[1] + oz*px[2]); |
||
1555 | ngdx = (ox*dd[0] + oy*dd[1] + oz*dd[2])*r; |
||
1556 | ngux = (ox*uu[0] + oy*uu[1] + oz*uu[2])*r; |
||
1557 | ngvx = (ox*vv[0] + oy*vv[1] + oz*vv[2])*r; |
||
1558 | ox = px[2]-px[1]; oy = px[0]-px[2]; oz = px[1]-px[0]; |
||
1559 | ngdy = (ox*dd[0] + oy*dd[1] + oz*dd[2])*r; |
||
1560 | nguy = (ox*uu[0] + oy*uu[1] + oz*uu[2])*r; |
||
1561 | ngvy = (ox*vv[0] + oy*vv[1] + oz*vv[2])*r; |
||
1562 | ox = px[0]-0.5f; oy = py[0]-0.5f; //.5 centers texture nicely |
||
1563 | ngdo = dd[0] - ox*ngdx - oy*ngdy; |
||
1564 | nguo = uu[0] - ox*ngux - oy*nguy; |
||
1565 | ngvo = vv[0] - ox*ngvx - oy*ngvy; |
||
1566 | |||
109 | terminx | 1567 | ngux *= hackscx; nguy *= hackscx; nguo *= hackscx; |
1568 | ngvx *= hackscy; ngvy *= hackscy; ngvo *= hackscy; |
||
4623 | terminx | 1569 | uoffs = ((float)(xx-tsiz.x)*0.5f); |
109 | terminx | 1570 | ngux -= ngdx*uoffs; |
1571 | nguy -= ngdy*uoffs; |
||
1572 | nguo -= ngdo*uoffs; |
||
5 | Plagman | 1573 | |
109 | terminx | 1574 | //Find min&max u coordinates (du0...du1) |
4623 | terminx | 1575 | for (i=0; i<jj; i++) |
109 | terminx | 1576 | { |
1577 | ox = px[i]; oy = py[i]; |
||
1578 | f = (ox*ngux + oy*nguy + nguo) / (ox*ngdx + oy*ngdy + ngdo); |
||
1579 | if (!i) { du0 = du1 = f; continue; } |
||
1580 | if (f < du0) du0 = f; |
||
1581 | else if (f > du1) du1 = f; |
||
1582 | } |
||
5 | Plagman | 1583 | |
4623 | terminx | 1584 | f = 1.0f/tsiz.x; |
4605 | terminx | 1585 | ix0 = Blrintf(floorf(du0*f)); |
1586 | ix1 = Blrintf(floorf(du1*f)); |
||
1229 | terminx | 1587 | for (; ix0<=ix1; ix0++) |
109 | terminx | 1588 | { |
4623 | terminx | 1589 | du0 = (float)(ix0*tsiz.x); // + uoffs; |
1590 | du1 = (float)((ix0+1)*tsiz.x); // + uoffs; |
||
5 | Plagman | 1591 | |
109 | terminx | 1592 | i = 0; nn = 0; |
1593 | duj = (px[i]*ngux + py[i]*nguy + nguo) / (px[i]*ngdx + py[i]*ngdy + ngdo); |
||
1594 | do |
||
1595 | { |
||
4623 | terminx | 1596 | j = i+1; if (j == jj) j = 0; |
5 | Plagman | 1597 | |
4605 | terminx | 1598 | dui = duj; |
1599 | duj = (px[j]*ngux + py[j]*nguy + nguo) / (px[j]*ngdx + py[j]*ngdy + ngdo); |
||
5 | Plagman | 1600 | |
4605 | terminx | 1601 | if ((du0 <= dui) && (dui <= du1)) |
1602 | { |
||
1603 | uu[nn] = px[i]; |
||
1604 | vv[nn] = py[i]; |
||
1605 | nn++; |
||
1606 | } |
||
1607 | |||
1608 | //ox*(ngux-ngdx*du1) + oy*(nguy-ngdy*du1) + (nguo-ngdo*du1) = 0 |
||
1609 | //(px[j]-px[i])*f + px[i] = ox |
||
1610 | //(py[j]-py[i])*f + py[i] = oy |
||
1611 | |||
1612 | ///Solve for f |
||
1613 | //((px[j]-px[i])*f + px[i])*(ngux-ngdx*du1) + |
||
1614 | //((py[j]-py[i])*f + py[i])*(nguy-ngdy*du1) + (nguo-ngdo*du1) = 0 |
||
1615 | |||
1616 | #define DRAWPOLY_MATH_BULLSHIT(X) do { f = -(px[i] *(ngux-ngdx*X) + py[i] *(nguy-ngdy*X) + (nguo-ngdo*X)) / ((px[j]-px[i])*(ngux-ngdx*X) + (py[j]-py[i])*(nguy-ngdy*X)); \ |
||
1617 | uu[nn] = (px[j]-px[i])*f + px[i]; vv[nn] = (py[j]-py[i])*f + py[i]; nn++; } while (0) |
||
1618 | |||
109 | terminx | 1619 | if (duj <= dui) |
1620 | { |
||
1621 | if ((du1 < duj) != (du1 < dui)) |
||
4605 | terminx | 1622 | DRAWPOLY_MATH_BULLSHIT(du1); |
109 | terminx | 1623 | if ((du0 < duj) != (du0 < dui)) |
4605 | terminx | 1624 | DRAWPOLY_MATH_BULLSHIT(du0); |
109 | terminx | 1625 | } |
1626 | else |
||
1627 | { |
||
1628 | if ((du0 < duj) != (du0 < dui)) |
||
4605 | terminx | 1629 | DRAWPOLY_MATH_BULLSHIT(du0); |
109 | terminx | 1630 | if ((du1 < duj) != (du1 < dui)) |
4605 | terminx | 1631 | DRAWPOLY_MATH_BULLSHIT(du1); |
109 | terminx | 1632 | } |
1633 | i = j; |
||
4605 | terminx | 1634 | |
1635 | #undef DRAWPOLY_MATH_BULLSHIT |
||
1636 | |||
584 | terminx | 1637 | } |
1638 | while (i); |
||
4605 | terminx | 1639 | |
109 | terminx | 1640 | if (nn < 3) continue; |
5 | Plagman | 1641 | |
109 | terminx | 1642 | bglBegin(GL_TRIANGLE_FAN); |
1229 | terminx | 1643 | for (i=0; i<nn; i++) |
109 | terminx | 1644 | { |
1645 | ox = uu[i]; oy = vv[i]; |
||
1646 | dp = ox*ngdx + oy*ngdy + ngdo; |
||
1647 | up = ox*ngux + oy*nguy + nguo; |
||
1648 | vp = ox*ngvx + oy*ngvy + ngvo; |
||
4605 | terminx | 1649 | r = 1.f/dp; |
497 | Plagman | 1650 | if (texunits > GL_TEXTURE0_ARB) |
459 | Plagman | 1651 | { |
497 | Plagman | 1652 | j = GL_TEXTURE0_ARB; |
1653 | while (j <= texunits) |
||
4605 | terminx | 1654 | bglMultiTexCoord2fARB(j++, (up*r-du0+uoffs)*ox2,vp*r*oy2); |
459 | Plagman | 1655 | } |
1656 | else |
||
4605 | terminx | 1657 | bglTexCoord2f((up*r-du0+uoffs)*ox2,vp*r*oy2); |
1658 | bglVertex3f((ox-ghalfx)*r*grhalfxdown10x,(ghoriz-oy)*r*grhalfxdown10,r*(1.f/1024.f)); |
||
109 | terminx | 1659 | } |
1660 | bglEnd(); |
||
1661 | } |
||
1662 | } |
||
1663 | else |
||
1664 | { |
||
1665 | ox2 *= hackscx; oy2 *= hackscy; |
||
1666 | bglBegin(GL_TRIANGLE_FAN); |
||
4623 | terminx | 1667 | for (i=0; i<jj; i++) |
109 | terminx | 1668 | { |
4605 | terminx | 1669 | r = 1.f/dd[i]; |
497 | Plagman | 1670 | if (texunits > GL_TEXTURE0_ARB) |
459 | Plagman | 1671 | { |
497 | Plagman | 1672 | j = GL_TEXTURE0_ARB; |
1673 | while (j <= texunits) |
||
4605 | terminx | 1674 | bglMultiTexCoord2fARB(j++, uu[i]*r*ox2,vv[i]*r*oy2); |
459 | Plagman | 1675 | } |
497 | Plagman | 1676 | else |
4605 | terminx | 1677 | bglTexCoord2f(uu[i]*r*ox2,vv[i]*r*oy2); |
1678 | bglVertex3f((px[i]-ghalfx)*r*grhalfxdown10x,(ghoriz-py[i])*r*grhalfxdown10,r*(1.f/1024.f)); |
||
109 | terminx | 1679 | } |
1680 | bglEnd(); |
||
1681 | } |
||
497 | Plagman | 1682 | |
504 | Plagman | 1683 | while (texunits >= GL_TEXTURE0_ARB) |
461 | Plagman | 1684 | { |
666 | plagman | 1685 | bglActiveTextureARB(texunits); |
504 | Plagman | 1686 | bglMatrixMode(GL_TEXTURE); |
1687 | bglLoadIdentity(); |
||
1688 | bglMatrixMode(GL_MODELVIEW); |
||
1689 | if (texunits > GL_TEXTURE0_ARB) |
||
497 | Plagman | 1690 | { |
501 | Plagman | 1691 | bglTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.0f); |
497 | Plagman | 1692 | bglDisable(GL_TEXTURE_2D); |
1693 | } |
||
666 | plagman | 1694 | texunits--; |
461 | Plagman | 1695 | } |
497 | Plagman | 1696 | |
3784 | terminx | 1697 | if (getrendermode() == REND_POLYMOST) |
3741 | Plagman | 1698 | { |
1699 | if (srepeat) |
||
1700 | bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,glinfo.clamptoedge?GL_CLAMP_TO_EDGE:GL_CLAMP); |
||
1701 | if (trepeat) |
||
1702 | bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,glinfo.clamptoedge?GL_CLAMP_TO_EDGE:GL_CLAMP); |
||
1703 | } |
||
590 | plagman | 1704 | |
248 | terminx | 1705 | if (fullbrightdrawingpass == 1) // tile has fullbright colors ? |
1706 | { |
||
3146 | helixhorne | 1707 | int32_t shadeforfullbrightpass = globalshade; // save the current shade |
248 | terminx | 1708 | fullbrightdrawingpass = 2; |
388 | terminx | 1709 | globalshade = -128; // fullbright |
621 | plagman | 1710 | bglDisable(GL_FOG); |
4671 | terminx | 1711 | drawpoly(dpxy, n, method_); // draw them afterwards, then. :) |
5001 | terminx | 1712 | if (!nofog) bglEnable(GL_FOG); |
248 | terminx | 1713 | globalshade = shadeforfullbrightpass; |
1714 | fullbrightdrawingpass = 0; |
||
1715 | } |
||
109 | terminx | 1716 | return; |
1717 | } |
||
5 | Plagman | 1718 | #endif |
1719 | } |
||
1720 | |||
2002 | helixhorne | 1721 | |
4898 | terminx | 1722 | static inline void vsp_finalize_init(vsptyp *vsp, int32_t vcnt) |
2002 | helixhorne | 1723 | { |
1724 | int32_t i; |
||
1725 | |||
1726 | for (i=0; i<vcnt; i++) |
||
1727 | { |
||
1728 | vsp[i].cy[1] = vsp[i+1].cy[0]; vsp[i].ctag = i; |
||
1729 | vsp[i].fy[1] = vsp[i+1].fy[0]; vsp[i].ftag = i; |
||
1730 | vsp[i].n = i+1; vsp[i].p = i-1; |
||
1731 | // vsp[i].tag = -1; |
||
1732 | } |
||
1733 | vsp[vcnt-1].n = 0; vsp[0].p = vcnt-1; |
||
1734 | |||
1735 | //VSPMAX-1 is dummy empty node |
||
1736 | for (i=vcnt; i<VSPMAX; i++) { vsp[i].n = i+1; vsp[i].p = i-1; } |
||
1737 | vsp[VSPMAX-1].n = vcnt; vsp[vcnt].p = VSPMAX-1; |
||
1738 | } |
||
1739 | |||
1740 | static inline void vsdel(vsptyp *vsp, int32_t i) |
||
5 | Plagman | 1741 | { |
109 | terminx | 1742 | //Delete i |
4623 | terminx | 1743 | vsp[vsp[i].n].p = vsp[i].p; |
1744 | vsp[vsp[i].p].n = vsp[i].n; |
||
5 | Plagman | 1745 | |
109 | terminx | 1746 | //Add i to empty list |
1747 | vsp[i].n = vsp[VSPMAX-1].n; |
||
1748 | vsp[i].p = VSPMAX-1; |
||
1749 | vsp[vsp[VSPMAX-1].n].p = i; |
||
1750 | vsp[VSPMAX-1].n = i; |
||
5 | Plagman | 1751 | } |
1752 | |||
2002 | helixhorne | 1753 | static inline int32_t vsinsaft(vsptyp *vsp, int32_t i) |
5 | Plagman | 1754 | { |
109 | terminx | 1755 | //i = next element from empty list |
4623 | terminx | 1756 | int32_t r = vsp[VSPMAX-1].n; |
109 | terminx | 1757 | vsp[vsp[r].n].p = VSPMAX-1; |
1758 | vsp[VSPMAX-1].n = vsp[r].n; |
||
5 | Plagman | 1759 | |
109 | terminx | 1760 | vsp[r] = vsp[i]; //copy i to r |
5 | Plagman | 1761 | |
109 | terminx | 1762 | //insert r after i |
1763 | vsp[r].p = i; vsp[r].n = vsp[i].n; |
||
1764 | vsp[vsp[i].n].p = r; vsp[i].n = r; |
||
5 | Plagman | 1765 | |
109 | terminx | 1766 | return(r); |
5 | Plagman | 1767 | } |
1768 | |||
1205 | terminx | 1769 | static int32_t domostpolymethod = 0; |
5 | Plagman | 1770 | |
584 | terminx | 1771 | void domost(float x0, float y0, float x1, float y1) |
5 | Plagman | 1772 | { |
4675 | terminx | 1773 | vec2f_t dpxy[4], n0, n1; |
1774 | float slop, dx; |
||
2002 | helixhorne | 1775 | float spx[4], /*spy[4],*/ cy[2], cv[2]; |
4675 | terminx | 1776 | int32_t i, k, z, vcnt = 0, scnt, newi, dir = 0, spt[4]; |
5 | Plagman | 1777 | |
3555 | hendricks2 | 1778 | alpha = 0.f; |
1779 | |||
109 | terminx | 1780 | if (x0 < x1) |
1781 | { |
||
1782 | dir = 1; //clip dmost (floor) |
||
4623 | terminx | 1783 | y0 -= .01f; |
1784 | y1 -= .01f; |
||
109 | terminx | 1785 | } |
1786 | else |
||
1787 | { |
||
1788 | if (x0 == x1) return; |
||
4605 | terminx | 1789 | swapfloat(&x0, &x1); |
1790 | swapfloat(&y0, &y1); |
||
4623 | terminx | 1791 | //dir = 0; //clip umost (ceiling) |
109 | terminx | 1792 | //y0 += .01; y1 += .01; //necessary? |
1793 | } |
||
5 | Plagman | 1794 | |
109 | terminx | 1795 | slop = (y1-y0)/(x1-x0); |
1229 | terminx | 1796 | for (i=vsp[0].n; i; i=newi) |
109 | terminx | 1797 | { |
4675 | terminx | 1798 | newi = vsp[i].n; n0.x = vsp[i].x; n1.x = vsp[newi].x; |
1799 | if ((x0 >= n1.x) || (n0.x >= x1) || (vsp[i].ctag <= 0)) continue; |
||
1800 | dx = n1.x-n0.x; |
||
109 | terminx | 1801 | cy[0] = vsp[i].cy[0]; cv[0] = vsp[i].cy[1]-cy[0]; |
1802 | cy[1] = vsp[i].fy[0]; cv[1] = vsp[i].fy[1]-cy[1]; |
||
5 | Plagman | 1803 | |
109 | terminx | 1804 | scnt = 0; |
5 | Plagman | 1805 | |
109 | terminx | 1806 | //Test if left edge requires split (x0,y0) (nx0,cy(0)),<dx,cv(0)> |
4675 | terminx | 1807 | if ((x0 > n0.x) && (x0 < n1.x)) |
109 | terminx | 1808 | { |
4675 | terminx | 1809 | const float t = (x0-n0.x)*cv[dir] - (y0-cy[dir])*dx; |
4623 | terminx | 1810 | if (((!dir) && (t < 0.f)) || ((dir) && (t > 0.f))) |
2002 | helixhorne | 1811 | { spx[scnt] = x0; /*spy[scnt] = y0;*/ spt[scnt] = -1; scnt++; } |
109 | terminx | 1812 | } |
5 | Plagman | 1813 | |
4675 | terminx | 1814 | //Test for intersection on umost (0) and dmost (1) |
1815 | |||
109 | terminx | 1816 | { |
4690 | terminx | 1817 | const float d[2] ={ |
4675 | terminx | 1818 | ((y0-y1) * dx) - ((x0-x1) * cv[0]), |
4690 | terminx | 1819 | ((y0-y1) * dx) - ((x0-x1) * cv[1]) |
4675 | terminx | 1820 | }; |
4623 | terminx | 1821 | |
4690 | terminx | 1822 | const float n[2] ={ |
4675 | terminx | 1823 | ((y0-cy[0]) * dx) - ((x0-n0.x) * cv[0]), |
4690 | terminx | 1824 | ((y0-cy[1]) * dx) - ((x0-n0.x) * cv[1]) |
4675 | terminx | 1825 | }; |
4671 | terminx | 1826 | |
4690 | terminx | 1827 | const float fnx[2] ={ |
4675 | terminx | 1828 | x0 + ((n[0]/d[0]) * (x1-x0)), |
4690 | terminx | 1829 | x0 + ((n[1]/d[1]) * (x1-x0)) |
4675 | terminx | 1830 | }; |
1831 | |||
1832 | if ((Bfabsf(d[0]) > Bfabsf(n[0])) && (d[0] * n[0] >= 0.f) && (fnx[0] > n0.x) && (fnx[0] < n1.x)) |
||
1833 | spx[scnt] = fnx[0], spt[scnt++] = 0; |
||
1834 | |||
1835 | if ((Bfabsf(d[1]) > Bfabsf(n[1])) && (d[1] * n[1] >= 0.f) && (fnx[1] > n0.x) && (fnx[1] < n1.x)) |
||
1836 | spx[scnt] = fnx[1], spt[scnt++] = 1; |
||
109 | terminx | 1837 | } |
5 | Plagman | 1838 | |
109 | terminx | 1839 | //Nice hack to avoid full sort later :) |
1840 | if ((scnt >= 2) && (spx[scnt-1] < spx[scnt-2])) |
||
1841 | { |
||
4605 | terminx | 1842 | swapfloat(&spx[scnt-1], &spx[scnt-2]); |
1843 | swaplong(&spt[scnt-1], &spt[scnt-2]); |
||
2002 | helixhorne | 1844 | /* f = spy[scnt-1]; spy[scnt-1] = spy[scnt-2]; spy[scnt-2] = f; */ |
109 | terminx | 1845 | } |
5 | Plagman | 1846 | |
109 | terminx | 1847 | //Test if right edge requires split |
4675 | terminx | 1848 | if ((x1 > n0.x) && (x1 < n1.x)) |
109 | terminx | 1849 | { |
4675 | terminx | 1850 | const float t = (x1-n0.x)*cv[dir] - (y1-cy[dir])*dx; |
109 | terminx | 1851 | if (((!dir) && (t < 0)) || ((dir) && (t > 0))) |
2002 | helixhorne | 1852 | { spx[scnt] = x1; /* spy[scnt] = y1; */ spt[scnt] = -1; scnt++; } |
109 | terminx | 1853 | } |
5 | Plagman | 1854 | |
109 | terminx | 1855 | vsp[i].tag = vsp[newi].tag = -1; |
4671 | terminx | 1856 | |
1857 | dx = 1.f/dx; |
||
1858 | |||
1229 | terminx | 1859 | for (z=0; z<=scnt; z++,i=vcnt) |
109 | terminx | 1860 | { |
4898 | terminx | 1861 | float t; |
4671 | terminx | 1862 | |
4675 | terminx | 1863 | if (z == scnt) |
1864 | goto skip; |
||
5 | Plagman | 1865 | |
4675 | terminx | 1866 | t = (spx[z]-n0.x)*dx; |
1867 | vcnt = vsinsaft(vsp, i); |
||
1868 | vsp[i].cy[1] = t*cv[0] + cy[0]; |
||
1869 | vsp[i].fy[1] = t*cv[1] + cy[1]; |
||
1870 | vsp[vcnt].x = spx[z]; |
||
1871 | vsp[vcnt].cy[0] = vsp[i].cy[1]; |
||
1872 | vsp[vcnt].fy[0] = vsp[i].fy[1]; |
||
1873 | vsp[vcnt].tag = spt[z]; |
||
1874 | |||
4930 | helixhorne | 1875 | skip: ; |
4898 | terminx | 1876 | int32_t ni = vsp[i].n; if (!ni) continue; //this 'if' fixes many bugs! |
1877 | float dx0 = vsp[i].x; if (x0 > dx0) continue; |
||
1878 | float dx1 = vsp[ni].x; if (x1 < dx1) continue; |
||
4675 | terminx | 1879 | n0.y = (dx0-x0)*slop + y0; |
1880 | n1.y = (dx1-x0)*slop + y0; |
||
5 | Plagman | 1881 | |
109 | terminx | 1882 | // dx0 dx1 |
1883 | // ~ ~ |
||
1884 | //---------------------------- |
||
1885 | // t0+=0 t1+=0 |
||
1886 | // vsp[i].cy[0] vsp[i].cy[1] |
||
1887 | //============================ |
||
1888 | // t0+=1 t1+=3 |
||
1889 | //============================ |
||
1890 | // vsp[i].fy[0] vsp[i].fy[1] |
||
1891 | // t0+=2 t1+=6 |
||
1892 | // |
||
1893 | // ny0 ? ny1 ? |
||
5 | Plagman | 1894 | |
109 | terminx | 1895 | k = 1+3; |
4675 | terminx | 1896 | if ((vsp[i].tag == 0) || (n0.y <= vsp[i].cy[0]+.01f)) k--; |
1897 | if ((vsp[i].tag == 1) || (n0.y >= vsp[i].fy[0]-.01f)) k++; |
||
1898 | if ((vsp[ni].tag == 0) || (n1.y <= vsp[i].cy[1]+.01f)) k -= 3; |
||
1899 | if ((vsp[ni].tag == 1) || (n1.y >= vsp[i].fy[1]-.01f)) k += 3; |
||
5 | Plagman | 1900 | |
4671 | terminx | 1901 | dpxy[0].x = dx0; |
1902 | dpxy[1].x = dx1; |
||
4605 | terminx | 1903 | |
109 | terminx | 1904 | if (!dir) |
1905 | { |
||
4671 | terminx | 1906 | dpxy[0].y = vsp[i].cy[0]; |
1907 | dpxy[1].y = vsp[i].cy[1]; |
||
2002 | helixhorne | 1908 | |
331 | terminx | 1909 | switch (k) |
109 | terminx | 1910 | { |
4675 | terminx | 1911 | case 4: |
1912 | case 5: |
||
1913 | case 7: |
||
1914 | dpxy[2].x = dx1; dpxy[3].x = dx0; |
||
1915 | dpxy[2].y = n1.y; dpxy[3].y = n0.y; |
||
1916 | vsp[i].cy[0] = n0.y; vsp[i].cy[1] = n1.y; vsp[i].ctag = gtag; |
||
1917 | drawpoly(dpxy, 4, domostpolymethod); |
||
1918 | break; |
||
331 | terminx | 1919 | case 1: |
1920 | case 2: |
||
4671 | terminx | 1921 | dpxy[2].x = dx0; |
4675 | terminx | 1922 | dpxy[2].y = n0.y; |
1923 | vsp[i].cy[0] = n0.y; vsp[i].ctag = gtag; |
||
4671 | terminx | 1924 | drawpoly(dpxy, 3, domostpolymethod); |
4623 | terminx | 1925 | break; |
331 | terminx | 1926 | case 3: |
1927 | case 6: |
||
4671 | terminx | 1928 | dpxy[2].x = dx1; |
4675 | terminx | 1929 | dpxy[2].y = n1.y; |
1930 | vsp[i].cy[1] = n1.y; vsp[i].ctag = gtag; |
||
4671 | terminx | 1931 | drawpoly(dpxy, 3, domostpolymethod); |
4623 | terminx | 1932 | break; |
109 | terminx | 1933 | case 8: |
4671 | terminx | 1934 | dpxy[2].x = dx1; dpxy[2].y = vsp[i].fy[1]; |
1935 | dpxy[3].x = dx0; dpxy[3].y = vsp[i].fy[0]; |
||
4623 | terminx | 1936 | vsp[i].ctag = vsp[i].ftag = -1; |
4671 | terminx | 1937 | drawpoly(dpxy, 4, domostpolymethod); |
331 | terminx | 1938 | default: |
4623 | terminx | 1939 | break; |
109 | terminx | 1940 | } |
1941 | } |
||
1942 | else |
||
1943 | { |
||
331 | terminx | 1944 | switch (k) |
109 | terminx | 1945 | { |
4675 | terminx | 1946 | case 4: |
1947 | case 3: |
||
1948 | case 1: |
||
1949 | dpxy[2].x = dx1; dpxy[3].x = dx0; |
||
1950 | dpxy[0].y = n0.y; dpxy[1].y = n1.y; dpxy[2].y = vsp[i].fy[1]; dpxy[3].y = vsp[i].fy[0]; |
||
1951 | vsp[i].fy[0] = n0.y; vsp[i].fy[1] = n1.y; vsp[i].ftag = gtag; |
||
1952 | drawpoly(dpxy, 4, domostpolymethod); |
||
1953 | break; |
||
331 | terminx | 1954 | case 7: |
1955 | case 6: |
||
4671 | terminx | 1956 | dpxy[2].x = dx0; |
4675 | terminx | 1957 | dpxy[0].y = n0.y; dpxy[1].y = vsp[i].fy[1]; dpxy[2].y = vsp[i].fy[0]; |
1958 | vsp[i].fy[0] = n0.y; vsp[i].ftag = gtag; |
||
4671 | terminx | 1959 | drawpoly(dpxy, 3, domostpolymethod); |
4623 | terminx | 1960 | break; |
331 | terminx | 1961 | case 5: |
1962 | case 2: |
||
4671 | terminx | 1963 | dpxy[2].x = dx1; |
4675 | terminx | 1964 | dpxy[0].y = vsp[i].fy[0]; dpxy[1].y = n1.y; dpxy[2].y = vsp[i].fy[1]; |
1965 | vsp[i].fy[1] = n1.y; vsp[i].ftag = gtag; |
||
4671 | terminx | 1966 | drawpoly(dpxy, 3, domostpolymethod); |
4623 | terminx | 1967 | break; |
109 | terminx | 1968 | case 0: |
4671 | terminx | 1969 | dpxy[2].x = dx1; dpxy[3].x = dx0; |
1970 | dpxy[0].y = vsp[i].cy[0]; dpxy[1].y = vsp[i].cy[1]; dpxy[2].y = vsp[i].fy[1]; dpxy[3].y = vsp[i].fy[0]; |
||
4623 | terminx | 1971 | vsp[i].ctag = vsp[i].ftag = -1; |
4671 | terminx | 1972 | drawpoly(dpxy, 4, domostpolymethod); |
331 | terminx | 1973 | default: |
4623 | terminx | 1974 | break; |
109 | terminx | 1975 | } |
1976 | } |
||
1977 | } |
||
1978 | } |
||
5 | Plagman | 1979 | |
109 | terminx | 1980 | gtag++; |
1981 | |||
1982 | //Combine neighboring vertical strips with matching collinear top&bottom edges |
||
1983 | //This prevents x-splits from propagating through the entire scan |
||
1984 | i = vsp[0].n; |
||
4623 | terminx | 1985 | |
109 | terminx | 1986 | while (i) |
1987 | { |
||
4671 | terminx | 1988 | int32_t ni = vsp[i].n; |
2002 | helixhorne | 1989 | |
1990 | if ((vsp[i].cy[0] >= vsp[i].fy[0]) && (vsp[i].cy[1] >= vsp[i].fy[1])) |
||
1991 | vsp[i].ctag = vsp[i].ftag = -1; |
||
1992 | |||
109 | terminx | 1993 | if ((vsp[i].ctag == vsp[ni].ctag) && (vsp[i].ftag == vsp[ni].ftag)) |
2002 | helixhorne | 1994 | { |
1995 | vsp[i].cy[1] = vsp[ni].cy[1]; |
||
1996 | vsp[i].fy[1] = vsp[ni].fy[1]; |
||
1997 | vsdel(vsp, ni); |
||
1998 | } |
||
109 | terminx | 1999 | else i = ni; |
2000 | } |
||
5 | Plagman | 2001 | } |
2002 | |||
4652 | terminx | 2003 | void polymost_editorfunc(void) |
2004 | { |
||
4656 | terminx | 2005 | vec3_t v; |
2006 | vec3f_t o, o2; |
||
4652 | terminx | 2007 | int32_t cz, fz; |
2008 | hitdata_t hit; |
||
2009 | vec3_t vect; |
||
2010 | const float ratio = get_projhack_ratio(); |
||
2011 | |||
2012 | o2.x = (searchx-ghalfx)/ratio; |
||
2013 | o2.y = (searchy-ghoriz)/ratio; // ghoriz is (ydimen>>1) here |
||
2014 | o2.z = ghalfx; |
||
2015 | |||
2016 | //Tilt rotation |
||
2017 | o.x = o2.x*gctang + o2.y*gstang; |
||
2018 | o.y = o2.y*gctang - o2.x*gstang; |
||
2019 | o.z = o2.z; |
||
2020 | |||
2021 | //Up/down rotation |
||
2022 | o2.x = o.z*gchang - o.y*gshang; |
||
2023 | o2.y = o.x; |
||
2024 | o2.z = o.y*gchang + o.z*gshang; |
||
2025 | |||
2026 | //Standard Left/right rotation |
||
4656 | terminx | 2027 | v.x = Blrintf (o2.x*fcosglobalang - o2.y*fsinglobalang); |
2028 | v.y = Blrintf (o2.x*fsinglobalang + o2.y*fcosglobalang); |
||
2029 | v.z = Blrintf (o2.z*16384.f); |
||
4652 | terminx | 2030 | |
2031 | vect.x = globalposx; |
||
2032 | vect.y = globalposy; |
||
2033 | vect.z = globalposz; |
||
2034 | |||
2035 | hitallsprites = 1; |
||
2036 | hitscan((const vec3_t *) &vect, globalcursectnum, //Start position |
||
2037 | v.x>>10, v.y>>10, v.z>>6, &hit, 0xffff0030); |
||
2038 | |||
2039 | if (hit.sect != -1) // if hitsect is -1, hitscan overflowed somewhere |
||
2040 | { |
||
2041 | getzsofslope(hit.sect, hit.pos.x, hit.pos.y, &cz, &fz); |
||
2042 | hitallsprites = 0; |
||
2043 | |||
2044 | searchsector = hit.sect; |
||
2045 | if (hit.pos.z<cz) searchstat = 1; |
||
2046 | else if (hit.pos.z>fz) searchstat = 2; |
||
2047 | else if (hit.wall >= 0) |
||
2048 | { |
||
2049 | searchbottomwall = searchwall = hit.wall; searchstat = 0; |
||
2050 | if (wall[hit.wall].nextwall >= 0) |
||
2051 | { |
||
2052 | int32_t cz, fz; |
||
2053 | getzsofslope(wall[hit.wall].nextsector, hit.pos.x, hit.pos.y, &cz, &fz); |
||
2054 | if (hit.pos.z > fz) |
||
2055 | { |
||
2056 | searchisbottom = 1; |
||
2057 | if (wall[hit.wall].cstat&2) //'2' bottoms of walls |
||
2058 | searchbottomwall = wall[hit.wall].nextwall; |
||
2059 | } |
||
2060 | else |
||
2061 | { |
||
2062 | searchisbottom = 0; |
||
2063 | if ((hit.pos.z > cz) && (wall[hit.wall].cstat&(16+32))) //masking or 1-way |
||
2064 | searchstat = |