// Here lies the slow as shit renderer! #ifndef polymer_h_ # define polymer_h_ # include "compat.h" # include "baselayer.h" # include "glad/glad.h" # include "build.h" # include "glbuild.h" # include "osd.h" # include "hightile.h" # include "mdsprite.h" # include "polymost.h" # include "pragmas.h" #ifdef __cplusplus extern "C" { #endif #define PR_LINEAR_FOG // CVARS extern int32_t pr_lighting; extern int32_t pr_normalmapping; extern int32_t pr_specularmapping; extern int32_t pr_shadows; extern int32_t pr_shadowcount; extern int32_t pr_shadowdetail; extern int32_t pr_shadowfiltering; extern int32_t pr_maxlightpasses; extern int32_t pr_maxlightpriority; extern int32_t pr_fov; extern double pr_customaspect; extern int32_t pr_billboardingmode; extern int32_t pr_verbosity; extern int32_t pr_wireframe; extern int32_t pr_vbos; extern int32_t pr_buckets; extern int32_t pr_gpusmoothing; extern int32_t pr_overrideparallax; extern float pr_parallaxscale; extern float pr_parallaxbias; extern int32_t pr_overridespecular; extern float pr_specularpower; extern float pr_specularfactor; extern int32_t pr_highpalookups; extern int32_t pr_artmapping; extern int32_t pr_overridehud; extern float pr_hudxadd; extern float pr_hudyadd; extern float pr_hudzadd; extern int32_t pr_hudangadd; extern int32_t pr_hudfov; extern float pr_overridemodelscale; extern int32_t pr_ati_fboworkaround; extern int32_t pr_ati_nodepthoffset; #ifdef __APPLE__ extern int32_t pr_ati_textureformat_one; #endif extern int32_t pr_nullrender; extern int32_t r_pr_maxlightpasses; // MATERIAL typedef enum { PR_BIT_HEADER, // must be first PR_BIT_ANIM_INTERPOLATION, PR_BIT_LIGHTING_PASS, PR_BIT_NORMAL_MAP, PR_BIT_ART_MAP, PR_BIT_DIFFUSE_MAP, PR_BIT_DIFFUSE_DETAIL_MAP, PR_BIT_DIFFUSE_MODULATION, PR_BIT_DIFFUSE_MAP2, PR_BIT_HIGHPALOOKUP_MAP, PR_BIT_SPECULAR_MAP, PR_BIT_SPECULAR_MATERIAL, PR_BIT_MIRROR_MAP, PR_BIT_FOG, PR_BIT_GLOW_MAP, PR_BIT_PROJECTION_MAP, PR_BIT_SHADOW_MAP, PR_BIT_LIGHT_MAP, PR_BIT_SPOT_LIGHT, PR_BIT_POINT_LIGHT, PR_BIT_FOOTER, // must be just before last PR_BIT_COUNT // must be last } prbittype; typedef struct s_prmaterial { // PR_BIT_ANIM_INTERPOLATION GLfloat frameprogress; GLfloat* nextframedata; // PR_BIT_NORMAL_MAP GLuint normalmap; GLfloat normalbias[2]; GLfloat* tbn; // PR_BIT_ART_MAP GLuint artmap; GLuint basepalmap; GLuint lookupmap; GLint shadeoffset; GLfloat visibility; // PR_BIT_DIFFUSE_MAP GLuint diffusemap; GLfloat diffusescale[2]; // PR_BIT_HIGHPALOOKUP_MAP GLuint highpalookupmap; // PR_BIT_DIFFUSE_DETAIL_MAP GLuint detailmap; GLfloat detailscale[2]; // PR_BIT_DIFFUSE_MODULATION GLubyte diffusemodulation[4]; // PR_BIT_SPECULAR_MAP GLuint specmap; // PR_BIT_SPECULAR_MATERIAL GLfloat specmaterial[2]; // PR_BIT_MIRROR_MAP GLuint mirrormap; // PR_BIT_GLOW_MAP GLuint glowmap; // PR_BIT_SHADOW_MAP GLboolean mdspritespace; } _prmaterial; typedef struct s_prrograminfo { GLuint handle; // PR_BIT_ANIM_INTERPOLATION GLint attrib_nextFrameData; GLint attrib_nextFrameNormal; GLint uniform_frameProgress; // PR_BIT_NORMAL_MAP GLint attrib_T; GLint attrib_B; GLint attrib_N; GLint uniform_eyePosition; GLint uniform_normalMap; GLint uniform_normalBias; // PR_BIT_ART_MAP GLuint uniform_artMap; GLuint uniform_basePalMap; GLuint uniform_lookupMap; GLuint uniform_shadeOffset; GLuint uniform_visibility; // PR_BIT_DIFFUSE_MAP GLint uniform_diffuseMap; GLint uniform_diffuseScale; // PR_BIT_HIGHPALOOKUP_MAP GLuint uniform_highPalookupMap; // PR_BIT_DIFFUSE_DETAIL_MAP GLint uniform_detailMap; GLint uniform_detailScale; // PR_BIT_SPECULAR_MAP GLint uniform_specMap; // PR_BIT_SPECULAR_MATERIAL GLint uniform_specMaterial; // PR_BIT_MIRROR_MAP GLint uniform_mirrorMap; #ifdef PR_LINEAR_FOG // PR_BIT_FOG GLint uniform_linearFog; #endif // PR_BIT_GLOW_MAP GLint uniform_glowMap; // PR_BIT_PROJECTION_MAP GLint uniform_shadowProjMatrix; // PR_BIT_SHADOW_MAP GLint uniform_shadowMap; // PR_BIT_LIGHT_MAP GLint uniform_lightMap; // PR_BIT_SPOT_LIGHT GLint uniform_spotDir; GLint uniform_spotRadius; } _prprograminfo; #define PR_INFO_LOG_BUFFER_SIZE 8192 // Think about changing highPal[Scale|Bias] in the program bit if you change this #define PR_HIGHPALOOKUP_BIT_DEPTH 6 #define PR_HIGHPALOOKUP_DIM (1 << PR_HIGHPALOOKUP_BIT_DEPTH) #define PR_HIGHPALOOKUP_DATA_SIZE (4 * PR_HIGHPALOOKUP_DIM * \ PR_HIGHPALOOKUP_DIM * \ PR_HIGHPALOOKUP_DIM) typedef struct s_prprogrambit { int32_t bit; const char* vert_def; const char* vert_prog; const char* frag_def; const char* frag_prog; } _prprogrambit; typedef struct s_prbucket { // index int16_t tilenum; char pal; _prmaterial material; int32_t invalidmaterial; // geom indices GLuint* indices; uint32_t count; uint32_t buffersize; GLuint* indiceoffset; struct s_prbucket* next; } _prbucket; #include "prlights.h" // RENDER TARGETS typedef struct s_prrt { GLenum target; GLuint color; GLuint z; GLuint fbo; int32_t xdim, ydim; } _prrt; // BUILD DATA typedef struct s_prvert { GLfloat x; GLfloat y; GLfloat z; GLfloat u; GLfloat v; GLubyte r; GLubyte g; GLubyte b; GLubyte a; } _prvert; typedef struct s_prplane { // geometry _prvert* buffer; int32_t vertcount; GLuint vbo; uint32_t mapvbo_vertoffset; _prbucket* bucket; // attributes GLfloat tbn[3][3]; GLfloat plane[4]; _prmaterial material; // elements GLushort* indices; int32_t indicescount; GLuint ivbo; // lights int16_t lights[PR_MAXLIGHTS]; uint16_t lightcount; } _prplane; typedef struct s_prsector { // polymer data GLdouble* verts; _prplane floor; _prplane ceil; int16_t curindice; int32_t indicescount; int32_t oldindicescount; // stuff float wallsproffset; float floorsproffset; // build sector data int32_t ceilingz, floorz; uint16_t ceilingstat, floorstat; int16_t ceilingpicnum, ceilingheinum; int8_t ceilingshade; uint8_t ceilingpal, ceilingxpanning, ceilingypanning; int16_t floorpicnum, floorheinum; int8_t floorshade; uint8_t floorpal, floorxpanning, floorypanning; uint8_t visibility; int16_t floorpicnum_anim, ceilingpicnum_anim; struct { int32_t empty : 1; int32_t uptodate : 1; int32_t invalidtex : 1; } flags; uint32_t invalidid; uint32_t trackedrev; } _prsector; typedef struct s_prwall { _prplane wall; _prplane over; _prplane mask; // stuff GLfloat* bigportal; //GLfloat* cap; GLuint stuffvbo; // build wall data uint16_t cstat; int16_t picnum, overpicnum; int8_t shade; uint8_t pal, xrepeat, yrepeat, xpanning, ypanning; // nextwall data int16_t nwallpicnum, nwallcstat; int8_t nwallxpanning, nwallypanning; int8_t nwallshade; int16_t picnum_anim, overpicnum_anim; char underover; uint32_t invalidid; struct { int32_t empty : 1; int32_t uptodate : 1; int32_t invalidtex : 1; } flags; uint32_t trackedrev; } _prwall; typedef struct s_prsprite { _prplane plane; uint32_t hash; } _prsprite; typedef struct s_prmirror { _prplane *plane; int16_t sectnum; int16_t wallnum; } _prmirror; typedef struct s_prhighpalookup { char *data; GLuint map; } _prhighpalookup; typedef void (*animatespritesptr)(int32_t, int32_t, int32_t, int32_t); typedef struct s_pranimatespritesinfo { animatespritesptr animatesprites; int32_t x, y, a, smoothratio; } _pranimatespritesinfo; // this one has to be provided by the application extern void G_Polymer_UnInit(void); // EXTERNAL FUNCTIONS int32_t polymer_init(void); void polymer_uninit(void); void polymer_setaspect(int32_t); void polymer_glinit(void); void polymer_resetlights(void); void polymer_loadboard(void); void polymer_drawrooms(int32_t daposx, int32_t daposy, int32_t daposz, int16_t daang, int32_t dahoriz, int16_t dacursectnum); void polymer_drawmasks(void); void polymer_editorpick(void); void polymer_inb4rotatesprite(int16_t tilenum, char pal, int8_t shade, int32_t method); void polymer_postrotatesprite(void); void polymer_drawmaskwall(int32_t damaskwallcnt); void polymer_drawsprite(int32_t snum); void polymer_setanimatesprites(animatespritesptr animatesprites, int32_t x, int32_t y, int32_t a, int32_t smoothratio); int16_t polymer_addlight(_prlight* light); void polymer_deletelight(int16_t lighti); void polymer_invalidatelights(void); void polymer_texinvalidate(void); void polymer_definehighpalookup(char basepalnum, char palnum, char *fn); int32_t polymer_havehighpalookup(int32_t basepalnum, int32_t palnum); extern _prsprite *prsprites[MAXSPRITES]; static inline void polymer_invalidatesprite(int32_t i) { if (prsprites[i]) prsprites[i]->hash = 0xDEADBEEF; } extern GLuint prartmaps[MAXTILES]; static inline void polymer_invalidateartmap(int32_t tilenum) { if (prartmaps[tilenum]) { glDeleteTextures(1, &prartmaps[tilenum]); prartmaps[tilenum] = 0; } } // Compare with eligible_for_tileshades() static inline int32_t polymer_eligible_for_artmap(int32_t tilenum, const pthtyp *pth) { return ((!pth || !pth->hicr) && tilenum < (MAXTILES - 4)); } # ifdef POLYMER_C // CORE static void polymer_displayrooms(int16_t sectnum); static void polymer_emptybuckets(void); static _prbucket* polymer_findbucket(int16_t tilenum, char pal); static void polymer_bucketplane(_prplane* plane); static void polymer_drawplane(_prplane* plane); static inline void polymer_inb4mirror(_prvert* buffer, GLfloat* plane); static void polymer_animatesprites(void); static void polymer_freeboard(void); // SECTORS static int32_t polymer_initsector(int16_t sectnum); static int32_t polymer_updatesector(int16_t sectnum); void PR_CALLBACK polymer_tesserror(GLenum error); void PR_CALLBACK polymer_tessedgeflag(GLenum error); void PR_CALLBACK polymer_tessvertex(void* vertex, void* sector); static int32_t polymer_buildfloor(int16_t sectnum); static void polymer_drawsector(int16_t sectnum, int32_t domasks); // WALLS static int32_t polymer_initwall(int16_t wallnum); static void polymer_updatewall(int16_t wallnum); static void polymer_drawwall(int16_t sectnum, int16_t wallnum); // HSR static void polymer_computeplane(_prplane* p); static inline void polymer_crossproduct(GLfloat* in_a, GLfloat* in_b, GLfloat* out); static inline void polymer_transformpoint(const float* inpos, float* pos, float* matrix); static inline void polymer_normalize(float* vec); static inline void polymer_pokesector(int16_t sectnum); static void polymer_extractfrustum(GLfloat* modelview, GLfloat* projection, float* frustum); static inline int32_t polymer_planeinfrustum(_prplane *plane, float* frustum); static inline void polymer_scansprites(int16_t sectnum, uspritetype* tsprite, int32_t* spritesortcnt); static void polymer_updatesprite(int32_t snum); // SKIES static void polymer_getsky(void); static void polymer_drawsky(int16_t tilenum, char palnum, int8_t shade); static void polymer_initartsky(void); static void polymer_drawartsky(int16_t tilenum, char palnum, int8_t shade); static void polymer_drawartskyquad(int32_t p1, int32_t p2, GLfloat height); static void polymer_drawskybox(int16_t tilenum, char palnum, int8_t shade); // MDSPRITES static void polymer_drawmdsprite(uspritetype *tspr); static void polymer_loadmodelvbos(md3model_t* m); // MATERIALS static void polymer_getscratchmaterial(_prmaterial* material); static _prbucket* polymer_getbuildmaterial(_prmaterial* material, int16_t tilenum, char pal, int8_t shade, int8_t vis, int32_t cmeth); static int32_t polymer_bindmaterial(const _prmaterial *material, int16_t* lights, int lightcount); static void polymer_unbindmaterial(int32_t programbits); static void polymer_compileprogram(int32_t programbits); // LIGHTS static void polymer_removelight(int16_t lighti); static void polymer_updatelights(void); static inline void polymer_resetplanelights(_prplane* plane); static void polymer_addplanelight(_prplane* plane, int16_t lighti); static inline void polymer_deleteplanelight(_prplane* plane, int16_t lighti); static int32_t polymer_planeinlight(_prplane* plane, _prlight* light); static void polymer_invalidateplanelights(_prplane* plane); static void polymer_invalidatesectorlights(int16_t sectnum); static void polymer_processspotlight(_prlight* light); static inline void polymer_culllight(int16_t lighti); static void polymer_prepareshadows(void); // RENDER TARGETS static void polymer_initrendertargets(int32_t count); // DEBUG OUTPUT void PR_CALLBACK polymer_debugoutputcallback(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam); #define INDICE(n) ((p->indices) ? (p->indices[(i+n)%p->indicescount]) : (((i+n)%p->vertcount))) #define SWITCH_CULL_DIRECTION { culledface = (culledface == GL_FRONT) ? GL_BACK : GL_FRONT; glCullFace(culledface); } static inline GLfloat dot2f(GLfloat *v1, GLfloat *v2) { return v1[0]*v2[0] + v1[1]*v2[1]; } static inline GLfloat dot3f(GLfloat *v1, GLfloat *v2) { return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; } static inline void relvec2f(GLfloat *v1, GLfloat *v2, GLfloat *out) { out[0] = v2[0]-v1[0]; out[1] = v2[1]-v1[1]; } // the following from gle/vvector.h /* ========================================================== */ /* determinant of matrix * * Computes determinant of matrix m, returning d */ #define DETERMINANT_3X3(d,m) \ { \ d = m[0][0] * (m[1][1]*m[2][2] - m[1][2] * m[2][1]); \ d -= m[0][1] * (m[1][0]*m[2][2] - m[1][2] * m[2][0]); \ d += m[0][2] * (m[1][0]*m[2][1] - m[1][1] * m[2][0]); \ } /* ========================================================== */ /* i,j,th cofactor of a 4x4 matrix * */ #define COFACTOR_4X4_IJ(fac,m,i,j) \ { \ int ii[4], jj[4], k; \ \ /* compute which row, columnt to skip */ \ for (k=0; k