1 #ifndef polymost_h_
2 # define polymost_h_
3
4 #ifdef USE_OPENGL
5
6 #include "baselayer.h" // glinfo
7 #include "glad/glad.h"
8 #include "hightile.h"
9
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13
14 typedef struct { uint8_t r, g, b, a; } coltype;
15 typedef struct { float r, g, b, a; } coltypef;
16
17 extern int32_t rendmode;
18 extern float gtang;
19 extern int polymost2d;
20 extern double gxyaspect;
21 extern float grhalfxdown10x;
22 extern float gcosang, gsinang, gcosang2, gsinang2;
23 extern float gchang, gshang, gctang, gstang, gvisibility;
24 extern float gvrcorrection;
25
26 struct glfiltermodes {
27 const char *name;
28 int32_t min,mag;
29 };
30 #define NUMGLFILTERMODES 6
31 extern struct glfiltermodes glfiltermodes[NUMGLFILTERMODES];
32
33 extern void Polymost_prepare_loadboard(void);
34
35 void polymost_outputGLDebugMessage(uint8_t severity, const char* format, ...);
36
37 //void phex(char v, char *s);
38 void polymost_setuptexture(const int32_t dameth, int filter);
39 void uploadtexture(int32_t doalloc, vec2_t siz, int32_t texfmt, coltype *pic, vec2_t tsiz, int32_t dameth);
40 void uploadtextureindexed(int32_t doalloc, vec2_t offset, vec2_t siz, intptr_t tile);
41 void uploadbasepalette(int32_t basepalnum);
42 void uploadpalswap(int32_t palookupnum);
43 void polymost_drawsprite(int32_t snum);
44 void polymost_drawmaskwall(int32_t damaskwallcnt);
45 void polymost_dorotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
46 int8_t dashade, char dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend, int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2, int32_t uniqid);
47 void polymost_fillpolygon(int32_t npoints);
48 void polymost_initosdfuncs(void);
49 void polymost_drawrooms(void);
50 void polymost_prepareMirror(int32_t dax, int32_t day, int32_t daz, fix16_t daang, fix16_t dahoriz, int16_t mirrorWall);
51 void polymost_completeMirror();
52
53 int32_t polymost_maskWallHasTranslucency(uwalltype const * const wall);
54 int32_t polymost_spriteHasTranslucency(tspritetype const * const tspr);
55 int32_t polymost_spriteIsModelOrVoxel(tspritetype const * const tspr);
56
57 void polymost_resetVertexPointers(void);
58 void polymost_disableProgram(void);
59 void polymost_resetProgram(void);
60 void polymost_setTexturePosSize(vec4f_t const &texturePosSize);
61 void polymost_setHalfTexelSize(vec2f_t const &halfTexelSize);
62 char polymost_getClamp();
63 void polymost_setClamp(char clamp);
64 void polymost_setVisibility(float visibility);
65 void polymost_setFogEnabled(char fogEnabled);
66 void polymost_useColorOnly(char useColorOnly);
67 void polymost_usePaletteIndexing(char usePaletteIndexing);
68 void polymost_useDetailMapping(char useDetailMapping);
69 void polymost_useGlowMapping(char useGlowMapping);
70 void polymost_activeTexture(GLenum texture);
71 void polymost_bindTexture(GLenum target, uint32_t textureID);
72 void polymost_updatePalette(void);
73 void polymost_useShaderProgram(uint32_t shaderID);
74 GLuint polymost2_compileShader(GLenum shaderType, const char* const source, int* pLength = nullptr);
75
76 float* multiplyMatrix4f(float m0[4*4], const float m1[4*4]);
77
78 //POGOTODO: these wrappers won't be needed down the line -- remove them once proper draw call organization is finished
79 #undef glActiveTexture
80 #undef glBindTexture
81 #define glActiveTexture polymost_activeTexture
82 #define glBindTexture polymost_bindTexture
83
84 void polymost_glinit(void);
85 void polymost_glreset(void);
86
87 void polymost_init(void);
88
89 enum {
90 INVALIDATE_ALL,
91 INVALIDATE_ART,
92 INVALIDATE_ALL_NON_INDEXED,
93 INVALIDATE_ART_NON_INDEXED
94 };
95
96 void gltexinvalidate(int32_t dapicnum, int32_t dapalnum, int32_t dameth);
97 void gltexinvalidatetype(int32_t type);
98 int32_t polymost_printtext256(int32_t xpos, int32_t ypos, int16_t col, int16_t backcol, const char *name, char fontsize);
99
100 extern float curpolygonoffset;
101
102 extern float shadescale;
103 extern int32_t shadescale_unbounded;
104 extern uint8_t alphahackarray[MAXTILES];
105
106 extern int32_t r_usenewshading;
107 extern int32_t r_usetileshades;
108 extern int32_t r_npotwallmode;
109 extern int32_t r_brightnesshack;
110 extern int32_t polymostcenterhoriz;
111
112 extern int16_t globalpicnum;
113
114 extern float fogfactor[MAXPALOOKUPS];
115
116 // Compare with polymer_eligible_for_artmap()
eligible_for_tileshades(int32_t const picnum,int32_t const pal)117 static FORCE_INLINE int32_t eligible_for_tileshades(int32_t const picnum, int32_t const pal)
118 {
119 return !usehightile || !hicfindsubst(picnum, pal, hictinting[pal].f & HICTINT_ALWAYSUSEART);
120 }
121
polymost_usetileshades(void)122 static FORCE_INLINE int polymost_usetileshades(void)
123 {
124 return r_usetileshades && !(globalflags & GLOBAL_NO_GL_TILESHADES);
125 }
126
getshadefactor(int32_t const shade,int32_t const pal)127 static inline float getshadefactor(int32_t const shade, int32_t const pal)
128 {
129 // 8-bit tiles, i.e. non-hightiles and non-models, don't get additional
130 // glColor() shading with r_usetileshades!
131 if (videoGetRenderMode() == REND_POLYMOST && polymost_usetileshades() && eligible_for_tileshades(globalpicnum, globalpal))
132 return 1.f;
133
134 float const fshade = fogfactor[pal] != 0.f ? (float)shade / fogfactor[pal] : 0.f;
135
136 if (r_usenewshading == 4)
137 return max(min(1.f - (fshade * shadescale / frealmaxshade), 1.f), 0.f);
138
139 float const shadebound = (float)((shadescale_unbounded || shade>=numshades) ? numshades : numshades-1);
140 float const scaled_shade = fshade*shadescale;
141 float const clamped_shade = min(max(scaled_shade, 0.f), shadebound);
142
143 return ((float)(numshades-clamped_shade))/(float)numshades;
144 }
145
146 #define POLYMOST_CHOOSE_FOG_PAL(fogpal, pal) \
147 ((fogpal) ? (fogpal) : (pal))
get_floor_fogpal(usectorptr_t const sec)148 static FORCE_INLINE int32_t get_floor_fogpal(usectorptr_t const sec)
149 {
150 return POLYMOST_CHOOSE_FOG_PAL(sec->fogpal, sec->floorpal);
151 }
get_ceiling_fogpal(usectorptr_t const sec)152 static FORCE_INLINE int32_t get_ceiling_fogpal(usectorptr_t const sec)
153 {
154 return POLYMOST_CHOOSE_FOG_PAL(sec->fogpal, sec->ceilingpal);
155 }
fogshade(int32_t const shade,int32_t const pal)156 static FORCE_INLINE int32_t fogshade(int32_t const shade, int32_t const pal)
157 {
158 polytintflags_t const tintflags = hictinting[pal].f;
159 return (globalflags & GLOBAL_NO_GL_FOGSHADE || tintflags & HICTINT_NOFOGSHADE) ? 0 : shade;
160 }
161
check_nonpow2(int32_t const x)162 static FORCE_INLINE int check_nonpow2(int32_t const x)
163 {
164 return (x > 1 && (x&(x-1)));
165 }
166
167 // Are we using the mode that uploads non-power-of-two wall textures like they
168 // render in classic?
polymost_is_npotmode(void)169 static FORCE_INLINE int polymost_is_npotmode(void)
170 {
171 // The glinfo.texnpot check is so we don't have to deal with that case in
172 // gloadtile_art().
173 return glinfo.texnpot &&
174 // r_npotwallmode is NYI for hightiles. We require r_hightile off
175 // because in calc_ypanning(), the repeat would be multiplied by a
176 // factor even if no modified texture were loaded.
177 !usehightile &&
178 #ifdef NEW_MAP_FORMAT
179 g_loadedMapVersion < 10 &&
180 #endif
181 r_npotwallmode == 1;
182 }
183
polymost_invsqrt_approximation(float x)184 static inline float polymost_invsqrt_approximation(float x)
185 {
186 #ifdef B_LITTLE_ENDIAN
187 float const haf = x * .5f;
188 union { float f; uint32_t i; } n = { x };
189 n.i = 0x5f375a86 - (n.i >> 1);
190 return n.f * (1.5f - haf * (n.f * n.f));
191 #else
192 // this is the comment
193 return 1.f / Bsqrtf(x);
194 #endif
195 }
196
197 // Flags of the <dameth> argument of various functions
198 enum {
199 DAMETH_NOMASK = 0,
200 DAMETH_MASK = 1,
201 DAMETH_TRANS1 = 2,
202 DAMETH_TRANS2 = 3,
203
204 DAMETH_MASKPROPS = 3,
205
206 DAMETH_CLAMPED = 4,
207
208 DAMETH_WALL = 32, // signals a texture for a wall (for r_npotwallmode)
209
210 DAMETH_INDEXED = 512,
211
212 DAMETH_N64 = 1024,
213 DAMETH_N64_INTENSIVITY = 2048,
214 DAMETH_N64_SCALED = 2097152,
215
216 // used internally by polymost_domost
217 DAMETH_BACKFACECULL = -1,
218
219 // used internally by uploadtexture
220 DAMETH_NODOWNSIZE = 4096,
221 DAMETH_HI = 8192,
222 DAMETH_NOFIX = 16384,
223 DAMETH_NOTEXCOMPRESS = 32768,
224 DAMETH_HASALPHA = 65536,
225 DAMETH_ONEBITALPHA = 131072,
226 DAMETH_ARTIMMUNITY = 262144,
227
228 DAMETH_HASFULLBRIGHT = 524288,
229 DAMETH_NPOTWALL = 1048576,
230
231 DAMETH_UPLOADTEXTURE_MASK =
232 DAMETH_HI |
233 DAMETH_NODOWNSIZE |
234 DAMETH_NOFIX |
235 DAMETH_NOTEXCOMPRESS |
236 DAMETH_HASALPHA |
237 DAMETH_ONEBITALPHA |
238 DAMETH_ARTIMMUNITY |
239 DAMETH_HASFULLBRIGHT |
240 DAMETH_NPOTWALL,
241 };
242
243 #define DAMETH_NARROW_MASKPROPS(dameth) (((dameth)&(~DAMETH_TRANS1))|(((dameth)&DAMETH_TRANS1)>>1))
244 EDUKE32_STATIC_ASSERT(DAMETH_NARROW_MASKPROPS(DAMETH_MASKPROPS) == DAMETH_MASK);
245 EDUKE32_STATIC_ASSERT(DAMETH_NARROW_MASKPROPS(DAMETH_CLAMPED) == DAMETH_CLAMPED);
246
247 #define TO_DAMETH_NODOWNSIZE(hicr_flags) (((hicr_flags)&HICR_NODOWNSIZE)<<8)
248 EDUKE32_STATIC_ASSERT(TO_DAMETH_NODOWNSIZE(HICR_NODOWNSIZE) == DAMETH_NODOWNSIZE);
249 #define TO_DAMETH_NOTEXCOMPRESS(hicr_flags) (((hicr_flags)&HICR_NOTEXCOMPRESS)<<15)
250 EDUKE32_STATIC_ASSERT(TO_DAMETH_NOTEXCOMPRESS(HICR_NOTEXCOMPRESS) == DAMETH_NOTEXCOMPRESS);
251 #define TO_DAMETH_ARTIMMUNITY(hicr_flags) (((hicr_flags)&HICR_ARTIMMUNITY)<<13)
252 EDUKE32_STATIC_ASSERT(TO_DAMETH_ARTIMMUNITY(HICR_ARTIMMUNITY) == DAMETH_ARTIMMUNITY);
253
254 // Do we want a NPOT-y-as-classic texture for this <dameth> and <ysiz>?
polymost_want_npotytex(int32_t dameth,int32_t ysiz)255 static FORCE_INLINE int polymost_want_npotytex(int32_t dameth, int32_t ysiz)
256 {
257 return videoGetRenderMode() != REND_POLYMER && // r_npotwallmode NYI in Polymer
258 polymost_is_npotmode() && (dameth&DAMETH_WALL) && check_nonpow2(ysiz);
259 }
260
261 // pthtyp pth->flags bits
262 enum pthtyp_flags {
263 PTH_CLAMPED = 1,
264 PTH_HIGHTILE = 2,
265 PTH_SKYBOX = 4,
266 PTH_HASALPHA = 8,
267 PTH_HASFULLBRIGHT = 16,
268 PTH_NPOTWALL = DAMETH_WALL, // r_npotwallmode=1 generated texture
269 PTH_FORCEFILTER = 64,
270
271 PTH_INVALIDATED = 128,
272
273 PTH_NOTRANSFIX = 256, // fixtransparency() bypassed
274
275 PTH_INDEXED = 512,
276 PTH_ONEBITALPHA = 1024,
277
278 PTH_N64 = 2048,
279 PTH_N64_INTENSIVITY = 4096,
280 PTH_N64_SCALED = 8192,
281 };
282
283 typedef struct pthtyp_t
284 {
285 struct pthtyp_t *next;
286 struct pthtyp_t *ofb; // fullbright pixels
287 hicreplctyp *hicr;
288
289 uint32_t glpic;
290 vec2f_t scale;
291 vec2_t siz;
292 int16_t picnum;
293
294 uint16_t flags; // see pthtyp_flags
295 polytintflags_t effects;
296 char palnum;
297 char shade;
298 char skyface;
299 } pthtyp;
300
301 // DAMETH -> PTH conversions
302 #define TO_PTH_CLAMPED(dameth) (((dameth)&DAMETH_CLAMPED)>>2)
303 EDUKE32_STATIC_ASSERT(TO_PTH_CLAMPED(DAMETH_CLAMPED) == PTH_CLAMPED);
304 #define TO_PTH_NOTRANSFIX(dameth) ((((~(dameth))&DAMETH_MASK)<<8)&(((~(dameth))&DAMETH_TRANS1)<<7))
305 EDUKE32_STATIC_ASSERT(TO_PTH_NOTRANSFIX(DAMETH_NOMASK) == PTH_NOTRANSFIX);
306 EDUKE32_STATIC_ASSERT(TO_PTH_NOTRANSFIX(DAMETH_MASK) == 0);
307 EDUKE32_STATIC_ASSERT(TO_PTH_NOTRANSFIX(DAMETH_TRANS1) == 0);
308 EDUKE32_STATIC_ASSERT(TO_PTH_NOTRANSFIX(DAMETH_MASKPROPS) == 0);
309 #define TO_PTH_INDEXED(dameth) ((dameth)&DAMETH_INDEXED)
310 EDUKE32_STATIC_ASSERT(TO_PTH_INDEXED(DAMETH_INDEXED) == PTH_INDEXED);
311 #define TO_PTH_N64(dameth) (((dameth)&DAMETH_N64)<<1)
312 EDUKE32_STATIC_ASSERT(TO_PTH_N64(DAMETH_N64) == PTH_N64);
313 #define TO_PTH_N64_INTENSIVITY(dameth) (((dameth)&DAMETH_N64_INTENSIVITY)<<1)
314 EDUKE32_STATIC_ASSERT(TO_PTH_N64_INTENSIVITY(DAMETH_N64_INTENSIVITY) == PTH_N64_INTENSIVITY);
315 #define TO_PTH_N64_SCALED(dameth) (((dameth)&DAMETH_N64_SCALED)>>8)
316 EDUKE32_STATIC_ASSERT(TO_PTH_N64_SCALED(DAMETH_N64_SCALED) == PTH_N64_SCALED);
317
318 extern void gloadtile_art(int32_t,int32_t,int32_t,int32_t,int32_t,pthtyp *,int32_t);
319 extern int32_t gloadtile_hi(int32_t,int32_t,int32_t,hicreplctyp *,int32_t,pthtyp *,int32_t,polytintflags_t);
320
321 extern int32_t globalnoeffect;
322 extern int32_t drawingskybox;
323 extern int32_t hicprecaching;
324 extern float fcosglobalang, fsinglobalang;
325 extern float fxdim, fydim, fydimen, fviewingrange;
326
327 extern char ptempbuf[MAXWALLSB<<1];
328
329 extern hitdata_t polymost_hitdata;
330
331 #include "texcache.h"
332
333 extern void polymost_setupglowtexture(int32_t texunits, int32_t tex);
334 extern void polymost_setupdetailtexture(int32_t texunits, int32_t tex);
335
336 #ifdef __cplusplus
337 }
338 #endif
339
340 #endif
341
342 #endif
343