From 5c16a91fd63ddfe1af0c3d8a723cc36828d2e8ec Mon Sep 17 00:00:00 2001 From: Ronald Kinard Date: Wed, 1 Apr 2015 20:48:54 -0500 Subject: [PATCH] Render most flats and sides with texture arrays. This breaks stencil buffer clipping, transparent flats, the whole nine yards. Unfortunately, this is about as far as I will be taking this approach to cleaning up OpenGL. It's unfortunate, but this renderer is basically unsalvagable. I will have to rewrite it completely from scratch to get what I want out of this. --- src/hardware/hw_defs.h | 6 +++ src/hardware/hw_draw.c | 20 ++++----- src/hardware/hw_drv.h | 2 +- src/hardware/hw_light.c | 8 ++-- src/hardware/hw_main.c | 76 +++++++++++++++++++++++--------- src/hardware/hw_vertarray.c | 38 +++++++++++++--- src/hardware/hw_vertbuckets.c | 8 +++- src/hardware/hw_vertbuckets.h | 1 + src/hardware/r_opengl/r_opengl.c | 17 +++++-- src/win32/win_dll.c | 2 +- 10 files changed, 129 insertions(+), 49 deletions(-) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 70d776d9e..302e75016 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -159,6 +159,12 @@ enum EPolyFlags PF_Debug = 0x80000000 // print debug message in driver :) }; +enum EPolygonPrimitive +{ + PP_TriangleFan = 0, + PP_Triangles +}; + enum ESurfFlags { diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index e6a26e605..f1e82aa5c 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -132,7 +132,7 @@ void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option) flags |= PF_ForceWrapY; // clip it since it is used for bunny scroll in doom I - HWD.pfnDrawPolygon(NULL, v, 4, flags); + HWD.pfnDrawPolygon(NULL, v, 4, flags, PP_TriangleFan); } void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, INT32 option, const UINT8 *colormap) @@ -229,10 +229,10 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, else if (alphalevel == 15) Surf.FlatColor.s.alpha = softwaretranstogl_hi[cv_translucenthud.value]; else Surf.FlatColor.s.alpha = softwaretranstogl[10-alphalevel]; flags |= PF_Modulated; - HWD.pfnDrawPolygon(&Surf, v, 4, flags); + HWD.pfnDrawPolygon(&Surf, v, 4, flags, PP_TriangleFan); } else - HWD.pfnDrawPolygon(NULL, v, 4, flags); + HWD.pfnDrawPolygon(NULL, v, 4, flags, PP_TriangleFan); } void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, INT32 option, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h) @@ -305,10 +305,10 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal else if (alphalevel == 15) Surf.FlatColor.s.alpha = softwaretranstogl_hi[cv_translucenthud.value]; else Surf.FlatColor.s.alpha = softwaretranstogl[10-alphalevel]; flags |= PF_Modulated; - HWD.pfnDrawPolygon(&Surf, v, 4, flags); + HWD.pfnDrawPolygon(&Surf, v, 4, flags, PP_TriangleFan); } else - HWD.pfnDrawPolygon(NULL, v, 4, flags); + HWD.pfnDrawPolygon(NULL, v, 4, flags, PP_TriangleFan); } void HWR_DrawPic(INT32 x, INT32 y, lumpnum_t lumpnum) @@ -343,7 +343,7 @@ void HWR_DrawPic(INT32 x, INT32 y, lumpnum_t lumpnum) // But then, the question is: why not 0 instead of PF_Masked ? // or maybe PF_Environment ??? (like what I said above) // BP: PF_Environment don't change anything ! and 0 is undifined - HWD.pfnDrawPolygon(NULL, v, 4, BLENDMODE | PF_NoDepthTest | PF_Clip | PF_NoZClip); + HWD.pfnDrawPolygon(NULL, v, 4, BLENDMODE | PF_NoDepthTest | PF_Clip | PF_NoZClip, PP_TriangleFan); } // ========================================================================== @@ -419,7 +419,7 @@ void HWR_DrawFlatFill (INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum // BTW, I see we put 0 for PFs, and If I'm right, that // means we take the previous PFs as default // how can we be sure they are ok? - HWD.pfnDrawPolygon(NULL, v, 4, PF_NoDepthTest); //PF_Translucent); + HWD.pfnDrawPolygon(NULL, v, 4, PF_NoDepthTest, PP_TriangleFan); //PF_Translucent); } @@ -452,7 +452,7 @@ void HWR_FadeScreenMenuBack(UINT32 color, INT32 height) Surf.FlatColor.rgba = UINT2RGBA(color); Surf.FlatColor.s.alpha = (UINT8)((0xff/2) * ((float)height / vid.height)); //calum: varies console alpha - HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); + HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest, PP_TriangleFan); } // Draw the console background with translucency support @@ -479,7 +479,7 @@ void HWR_DrawConsoleBack(UINT32 color, INT32 height) Surf.FlatColor.rgba = UINT2RGBA(color); Surf.FlatColor.s.alpha = 0x80; - HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); + HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest, PP_TriangleFan); } @@ -678,7 +678,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) Surf.FlatColor = V_GetColor(color); HWD.pfnDrawPolygon(&Surf, v, 4, - PF_Modulated|PF_NoTexture|PF_NoDepthTest); + PF_Modulated|PF_NoTexture|PF_NoDepthTest, PP_TriangleFan); } #ifdef HAVE_PNG diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 188aeff98..cb75c21a5 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -53,7 +53,7 @@ EXPORT void HWRAPI(SetPalette) (RGBA_t *ppal, RGBA_t *pgamma); #endif EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl); EXPORT void HWRAPI(Draw2DLine) (F2DCoord *v1, F2DCoord *v2, RGBA_t Color); -EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags); +EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, int PrimitiveType); EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags); EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat *ClearColor); EXPORT void HWRAPI(SetTexture) (FTextureInfo *TexInfo); diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index fb369387f..70c03ed39 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -768,7 +768,7 @@ void HWR_WallLighting(FOutVector *wlVerts) if (dynlights->mo[j]->state->nextstate == S_NULL) Surf.FlatColor.s.alpha = (UINT8)(((float)dynlights->mo[j]->tics/(float)dynlights->mo[j]->state->tics)*Surf.FlatColor.s.alpha); - HWD.pfnDrawPolygon (&Surf, wlVerts, 4, LIGHTMAPFLAGS); + HWD.pfnDrawPolygon (&Surf, wlVerts, 4, LIGHTMAPFLAGS, PP_TriangleFan); } // end for (j = 0; j < dynlights->nb; j++) } @@ -831,7 +831,7 @@ void HWR_PlaneLighting(FOutVector *clVerts, int nrClipVerts) if ((dynlights->mo[j]->state->nextstate == S_NULL)) Surf.FlatColor.s.alpha = (unsigned char)(((float)dynlights->mo[j]->tics/(float)dynlights->mo[j]->state->tics)*Surf.FlatColor.s.alpha); - HWD.pfnDrawPolygon (&Surf, clVerts, nrClipVerts, LIGHTMAPFLAGS); + HWD.pfnDrawPolygon (&Surf, clVerts, nrClipVerts, LIGHTMAPFLAGS, PP_TriangleFan); } // end for (j = 0; j < dynlights->nb; j++) } @@ -928,7 +928,7 @@ void HWR_DoCoronasLighting(FOutVector *outVerts, gr_vissprite_t *spr) HWR_GetPic(coronalumpnum); /// \todo use different coronas - HWD.pfnDrawPolygon (&Surf, light, 4, PF_Modulated | PF_Additive | PF_Clip | PF_Corona | PF_NoDepthTest); + HWD.pfnDrawPolygon (&Surf, light, 4, PF_Modulated | PF_Additive | PF_Clip | PF_Corona | PF_NoDepthTest, PP_TriangleFan); } } #endif @@ -1008,7 +1008,7 @@ void HWR_DrawCoronas(void) light[3].y = cy+size*1.33f; light[3].sow = 0.0f; light[3].tow = 1.0f; - HWD.pfnDrawPolygon (&Surf, light, 4, PF_Modulated | PF_Additive | PF_Clip | PF_NoDepthTest | PF_Corona); + HWD.pfnDrawPolygon (&Surf, light, 4, PF_Modulated | PF_Additive | PF_Clip | PF_NoDepthTest | PF_Corona, PP_TriangleFan); } } #endif diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 549b4ac2a..00668daf9 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -24,6 +24,7 @@ #include "hw_glob.h" #include "hw_light.h" #include "hw_drv.h" +#include "hw_vertbuckets.h" #include "../i_video.h" // for rendermode == render_glide #include "../v_video.h" @@ -758,7 +759,8 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, fixed_t fi else PolyFlags |= PF_Masked|PF_Modulated|PF_Clip; - HWD.pfnDrawPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags); + //HWD.pfnDrawPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags); + HWR_InsertVertexArray(HWR_GetVertexArrayForFlat(lumpnum), nrPlaneVerts, planeVerts); #ifdef ALAM_LIGHTING // add here code for dynamic lighting on planes @@ -807,7 +809,7 @@ static void HWR_RenderSkyPlane(extrasubsector_t *xsub, fixed_t fixedheight) } HWD.pfnDrawPolygon(NULL, planeVerts, nrPlaneVerts, - PF_Clip|PF_Invisible|PF_NoTexture|PF_Occlude); + PF_Clip|PF_Invisible|PF_NoTexture|PF_Occlude, PP_TriangleFan); } #endif //polysky @@ -897,7 +899,7 @@ static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf) break; } - HWD.pfnDrawPolygon(&pSurf2, trVerts, 4, i|PF_Modulated|PF_Clip|PF_Decal); + HWD.pfnDrawPolygon(&pSurf2, trVerts, 4, i|PF_Modulated|PF_Clip|PF_Decal, PP_TriangleFan); } } #endif @@ -942,7 +944,7 @@ static void HWR_AddTransparentWall(wallVert3D *wallVerts, FSurfaceInfo * pSurf, */ static void HWR_ProjectWall(wallVert3D * wallVerts, FSurfaceInfo * pSurf, - FBITFIELD blendmode, INT32 lightlevel, extracolormap_t *wallcolormap) + FBITFIELD blendmode, INT32 lightlevel, extracolormap_t *wallcolormap, int texnum) { FOutVector trVerts[4]; FOutVector *wv; @@ -988,7 +990,14 @@ static void HWR_ProjectWall(wallVert3D * wallVerts, pSurf->FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); } - HWD.pfnDrawPolygon(pSurf, trVerts, 4, blendmode|PF_Modulated|PF_Occlude|PF_Clip); + if (texnum == -1) + { + //HWD.pfnDrawPolygon(pSurf, trVerts, 4, blendmode|PF_Modulated|PF_Occlude|PF_Clip, PP_TriangleFan); + } + else + { + HWR_InsertVertexArray(HWR_GetVertexArrayForTexture(texnum), 4, trVerts); + } #ifdef WALLSPLATS if (gr_curline->linedef->splats && cv_splats.value) @@ -1144,7 +1153,7 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, else if (glTex->mipmap.flags & TF_TRANSPARENT) HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Environment, false, lightnum, colormap); else - HWR_ProjectWall(wallVerts, Surf, PF_Masked, lightnum, colormap); + HWR_ProjectWall(wallVerts, Surf, PF_Masked, lightnum, colormap, texnum); if (solid) top = bheight; @@ -1181,7 +1190,7 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, else if (glTex->mipmap.flags & TF_TRANSPARENT) HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Environment, false, lightnum, colormap); else - HWR_ProjectWall(wallVerts, Surf, PF_Masked, lightnum, colormap); + HWR_ProjectWall(wallVerts, Surf, PF_Masked, lightnum, colormap, texnum); } // @@ -1301,7 +1310,7 @@ static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf, fixed_t b // set top/bottom coords wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(top); // No real way to find the correct height of this wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(bottom); // worldlow/bottom because it needs to cover up the lower thok barrier wall - HWR_ProjectWall(wallVerts, Surf, PF_Invisible|PF_Clip|PF_NoTexture, 255, NULL); + HWR_ProjectWall(wallVerts, Surf, PF_Invisible|PF_Clip|PF_NoTexture, 255, NULL, -1); // PF_Invisible so it's not drawn into the colour buffer // PF_NoTexture for no texture // PF_Occlude is set in HWR_ProjectWall to draw into the depth buffer @@ -1448,7 +1457,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) else if (grTex->mipmap.flags & TF_TRANSPARENT) HWR_AddTransparentWall(wallVerts, &Surf, texturetranslation[gr_sidedef->toptexture], PF_Environment, false, lightnum, colormap); else - HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap); + HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap, texturetranslation[gr_sidedef->toptexture]); } // check BOTTOM TEXTURE @@ -1486,7 +1495,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) else if (grTex->mipmap.flags & TF_TRANSPARENT) HWR_AddTransparentWall(wallVerts, &Surf, texturetranslation[gr_sidedef->bottomtexture], PF_Environment, false, lightnum, colormap); else - HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap); + HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap, texturetranslation[gr_sidedef->bottomtexture]); } gr_midtexture = texturetranslation[gr_sidedef->midtexture]; if (gr_midtexture) @@ -1686,7 +1695,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) else if (!(blendmode & PF_Masked)) HWR_AddTransparentWall(wallVerts, &Surf, gr_midtexture, blendmode, false, lightnum, colormap); else - HWR_ProjectWall(wallVerts, &Surf, blendmode, lightnum, colormap); + HWR_ProjectWall(wallVerts, &Surf, blendmode, lightnum, colormap, gr_midtexture); // If there is a colormap change, remove it. /* if (!(Surf.FlatColor.s.red + Surf.FlatColor.s.green + Surf.FlatColor.s.blue == Surf.FlatColor.s.red/3) @@ -1810,7 +1819,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) if (grTex->mipmap.flags & TF_TRANSPARENT) HWR_AddTransparentWall(wallVerts, &Surf, gr_midtexture, PF_Environment, false, lightnum, colormap); else - HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap); + HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap, gr_midtexture); } } @@ -1936,7 +1945,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) if (blendmode != PF_Masked) HWR_AddTransparentWall(wallVerts, &Surf, texnum, blendmode, false, lightnum, colormap); else - HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap); + HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap, texnum); } } } @@ -2042,7 +2051,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) if (blendmode != PF_Masked) HWR_AddTransparentWall(wallVerts, &Surf, texnum, blendmode, false, lightnum, colormap); else - HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap); + HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap, texnum); } } } @@ -2785,7 +2794,7 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, fixed_t fixedheight else blendmode |= PF_Masked|PF_Modulated|PF_Clip; - HWD.pfnDrawPolygon(&Surf, planeVerts, nrPlaneVerts, blendmode); + HWD.pfnDrawPolygon(&Surf, planeVerts, nrPlaneVerts, blendmode, PP_TriangleFan); } static void HWR_AddPolyObjectPlanes(void) @@ -2979,6 +2988,7 @@ static void HWR_Subsector(size_t num) { if (sub->validcount != validcount) { + HWR_GetFlat(levelflats[gr_frontsector->floorpic].lumpnum); HWR_RenderPlane(gr_frontsector, &extrasubsectors[num], locFloorHeight, PF_Occlude, floorlightlevel, levelflats[gr_frontsector->floorpic].lumpnum, NULL, 255, false, floorcolormap); } @@ -3814,7 +3824,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) if (sSurf.FlatColor.s.alpha > floorheight/4) { sSurf.FlatColor.s.alpha = (UINT8)(sSurf.FlatColor.s.alpha - floorheight/4); - HWD.pfnDrawPolygon(&sSurf, swallVerts, 4, PF_Translucent|PF_Modulated|PF_Clip); + HWD.pfnDrawPolygon(&sSurf, swallVerts, 4, PF_Translucent|PF_Modulated|PF_Clip, PP_TriangleFan); } } } @@ -3886,7 +3896,7 @@ noshadow: blend = PF_Translucent|PF_Occlude; } - HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip); + HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip, PP_TriangleFan); } } @@ -3986,7 +3996,7 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) blend = PF_Translucent|PF_Occlude; } - HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip); + HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip, PP_TriangleFan); } #endif @@ -4883,7 +4893,7 @@ static void HWR_DrawSkyBackground(player_t *player) v[0].tow = v[1].tow -= ((float) angle / angleturn); } - HWD.pfnDrawPolygon(NULL, v, 4, 0); + HWD.pfnDrawPolygon(NULL, v, 4, 0, PP_TriangleFan); } @@ -5075,7 +5085,9 @@ if (0) validcount++; + HWR_ResetVertexBuckets(); HWR_RenderBSPNode((INT32)numnodes-1); + HWR_DrawVertexBuckets(); // Make a viewangle int so we can render things based on mouselook if (player == &players[consoleplayer]) @@ -5088,18 +5100,27 @@ if (0) { dup_viewangle += ANGLE_90; HWR_ClearClipSegs(); + + HWR_ResetVertexBuckets(); HWR_RenderBSPNode((INT32)numnodes-1); //left + HWR_DrawVertexBuckets(); dup_viewangle += ANGLE_90; if (((INT32)aimingangle > ANGLE_45 || (INT32)aimingangle<-ANGLE_45)) { HWR_ClearClipSegs(); + + HWR_ResetVertexBuckets(); HWR_RenderBSPNode((INT32)numnodes-1); //back + HWR_DrawVertexBuckets(); } dup_viewangle += ANGLE_90; HWR_ClearClipSegs(); + + HWR_ResetVertexBuckets(); HWR_RenderBSPNode((INT32)numnodes-1); //right + HWR_DrawVertexBuckets(); dup_viewangle += ANGLE_90; } @@ -5305,7 +5326,9 @@ if (0) validcount++; + HWR_ResetVertexBuckets(); HWR_RenderBSPNode((INT32)numnodes-1); + HWR_DrawVertexBuckets(); // Make a viewangle int so we can render things based on mouselook if (player == &players[consoleplayer]) @@ -5318,18 +5341,27 @@ if (0) { dup_viewangle += ANGLE_90; HWR_ClearClipSegs(); + + HWR_ResetVertexBuckets(); HWR_RenderBSPNode((INT32)numnodes-1); //left + HWR_DrawVertexBuckets(); dup_viewangle += ANGLE_90; if (((INT32)aimingangle > ANGLE_45 || (INT32)aimingangle<-ANGLE_45)) { HWR_ClearClipSegs(); + + HWR_ResetVertexBuckets(); HWR_RenderBSPNode((INT32)numnodes-1); //back + HWR_DrawVertexBuckets(); } dup_viewangle += ANGLE_90; HWR_ClearClipSegs(); + + HWR_ResetVertexBuckets(); HWR_RenderBSPNode((INT32)numnodes-1); //right + HWR_DrawVertexBuckets(); dup_viewangle += ANGLE_90; } @@ -5774,9 +5806,9 @@ static void HWR_RenderWall(wallVert3D *wallVerts, FSurfaceInfo *pSurf, FBITFIE pSurf->FlatColor.s.alpha = alpha; // put the alpha back after lighting if (blend & PF_Environment) - HWD.pfnDrawPolygon(pSurf, trVerts, 4, blend|PF_Modulated|PF_Clip|PF_Occlude); // PF_Occlude must be used for solid objects + HWD.pfnDrawPolygon(pSurf, trVerts, 4, blend|PF_Modulated|PF_Clip|PF_Occlude, PP_TriangleFan); // PF_Occlude must be used for solid objects else - HWD.pfnDrawPolygon(pSurf, trVerts, 4, blend|PF_Modulated|PF_Clip); // No PF_Occlude means overlapping (incorrect) transparency + HWD.pfnDrawPolygon(pSurf, trVerts, 4, blend|PF_Modulated|PF_Clip, PP_TriangleFan); // No PF_Occlude means overlapping (incorrect) transparency #ifdef WALLSPLATS if (gr_curline->linedef->splats && cv_splats.value) @@ -5830,7 +5862,7 @@ void HWR_DoPostProcessor(player_t *player) Surf.FlatColor.s.alpha = 0xc0; // match software mode - HWD.pfnDrawPolygon(&Surf, v, 4, PF_Modulated|PF_Additive|PF_NoTexture|PF_NoDepthTest|PF_Clip|PF_NoZClip); + HWD.pfnDrawPolygon(&Surf, v, 4, PF_Modulated|PF_Additive|PF_NoTexture|PF_NoDepthTest|PF_Clip|PF_NoZClip, PP_TriangleFan); } // Capture the screen for intermission and screen waving diff --git a/src/hardware/hw_vertarray.c b/src/hardware/hw_vertarray.c index 07b9e4fa8..70e514c41 100644 --- a/src/hardware/hw_vertarray.c +++ b/src/hardware/hw_vertarray.c @@ -28,7 +28,7 @@ void HWR_InitVertexArray(FVertexArray * varray, unsigned int initialSize) { varray->size = initialSize; varray->used = 0; - varray->buffer = Z_Malloc(varray->size * sizeof(FOutVector), PU_STATIC, varray); + varray->buffer = (FOutVector *) Z_Malloc(varray->size * sizeof(FOutVector), PU_STATIC, varray); } void HWR_FreeVertexArray(FVertexArray * varray) @@ -39,16 +39,40 @@ void HWR_FreeVertexArray(FVertexArray * varray) void HWR_InsertVertexArray(FVertexArray * varray, int numElements, FOutVector * elements) { int i = 0; - if (varray->used + numElements >= varray->size) + FOutVector * actualElements = NULL; + int numActualElements = numElements; + + // Expand array from fan to triangles + // Not optimal... but the overhead will make up for it significantly { - varray->size *= RESIZE_FACTOR; - varray->buffer = Z_Realloc(varray->buffer, varray->size * sizeof(FOutVector), PU_STATIC, varray); + int j = 0; + int k = 0; + numActualElements -= 3; + numActualElements *= 3; + numActualElements += 3; + + actualElements = (FOutVector *) Z_Malloc(numActualElements * sizeof(FOutVector), PU_STATIC, NULL); + + for (j = 2; j < numElements; j++) + { + actualElements[k] = elements[0]; + actualElements[k+1] = elements[j-1]; + actualElements[k+2] = elements[j]; + k += 3; + } } - for (i = 0; i < numElements; i++) + while (varray->used + numActualElements >= varray->size) { - varray->buffer[i + varray->used] = elements[i]; + varray->buffer = (FOutVector *) Z_Realloc(varray->buffer, varray->size * RESIZE_FACTOR * sizeof(FOutVector), PU_STATIC, varray); + varray->size *= RESIZE_FACTOR; + } + + for (i = 0; i < numActualElements; i++) + { + varray->buffer[i + varray->used] = actualElements[i]; } - varray->used += numElements; + varray->used += numActualElements; + Z_Free(actualElements); } diff --git a/src/hardware/hw_vertbuckets.c b/src/hardware/hw_vertbuckets.c index c74569ab3..d1274a719 100644 --- a/src/hardware/hw_vertbuckets.c +++ b/src/hardware/hw_vertbuckets.c @@ -57,6 +57,12 @@ static void DrawArraysFunc(INT32 key, void * value) FVertexArray * varray = (FVertexArray *) value; FSurfaceInfo surf; + if (varray->used == 0) + { + return; + } + + surf.FlatColor.rgba = 0xFFFFFFFF; if (rmode == RMODE_FLAT) @@ -68,7 +74,7 @@ static void DrawArraysFunc(INT32 key, void * value) HWR_GetTexture(key); } // TODO support flags, translucency, etc - HWD.pfnDrawPolygon(&surf, varray->buffer, varray->used, 0); + HWD.pfnDrawPolygon(&surf, varray->buffer, varray->used, PF_Occlude, PP_Triangles); } static FVertexArray * GetVArray(aatree_t * tree, int index) diff --git a/src/hardware/hw_vertbuckets.h b/src/hardware/hw_vertbuckets.h index c93f19d30..95775ced1 100644 --- a/src/hardware/hw_vertbuckets.h +++ b/src/hardware/hw_vertbuckets.h @@ -33,6 +33,7 @@ * should be called before rendering any BSP node. */ void HWR_ResetVertexBuckets(void); +FVertexArray * HWR_GetVertexArrayForFlat(lumpnum_t lumpnum); /** Get a pointer to the vertex array used for a given texture number. */ FVertexArray * HWR_GetVertexArrayForTexture(int texNum); diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index c5b2dfa0d..687031373 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1335,7 +1335,8 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, //FTextureInfo *pTexInfo, FOutVector *pOutVerts, FUINT iNumPts, - FBITFIELD PolyFlags) + FBITFIELD PolyFlags, + int PrimitiveType) { FUINT i; FUINT j; @@ -1423,7 +1424,17 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, pglEnableClientState(GL_TEXTURE_COORD_ARRAY); pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].x); pglTexCoordPointer(2, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].sow); - pglDrawArrays(GL_TRIANGLE_FAN, 0, iNumPts); + switch (PrimitiveType) + { + case PP_TriangleFan: + pglDrawArrays(GL_TRIANGLE_FAN, 0, iNumPts); + break; + case PP_Triangles: + pglDrawArrays(GL_TRIANGLES, 0, iNumPts); + break; + default: + break; + } pglDisableClientState(GL_TEXTURE_COORD_ARRAY); pglDisableClientState(GL_VERTEX_ARRAY); @@ -1648,7 +1659,7 @@ EXPORT void HWRAPI(DrawMD2i) (INT32 *gl_cmd_buffer, md2_frame_t *frame, UINT32 d #endif } - DrawPolygon(NULL, NULL, 0, PF_Masked|PF_Modulated|PF_Occlude|PF_Clip); + DrawPolygon(NULL, NULL, 0, PF_Masked|PF_Modulated|PF_Occlude|PF_Clip, PP_TriangleFan); pglPushMatrix(); // should be the same as glLoadIdentity //Hurdler: now it seems to work diff --git a/src/win32/win_dll.c b/src/win32/win_dll.c index 7f9ed002b..7f5decd21 100644 --- a/src/win32/win_dll.c +++ b/src/win32/win_dll.c @@ -101,7 +101,7 @@ static loadfunc_t hwdFuncTable[] = { {"SetPalette@8", &hwdriver.pfnSetPalette}, {"FinishUpdate@4", &hwdriver.pfnFinishUpdate}, {"Draw2DLine@12", &hwdriver.pfnDraw2DLine}, - {"DrawPolygon@16", &hwdriver.pfnDrawPolygon}, + {"DrawPolygon@20", &hwdriver.pfnDrawPolygon}, {"SetBlend@4", &hwdriver.pfnSetBlend}, {"ClearBuffer@12", &hwdriver.pfnClearBuffer}, {"SetTexture@4", &hwdriver.pfnSetTexture},