mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-03-17 08:21:28 +00:00
Merge branch 'master' of https://github.com/coelckers/gzdoom
This commit is contained in:
commit
e42a820b31
65 changed files with 1254 additions and 1012 deletions
|
@ -120,9 +120,26 @@ Note: All <bool> fields default to false unless mentioned otherwise.
|
|||
blockhitscan = <bool>; // Line blocks hitscan attacks
|
||||
locknumber = <int>; // Line special is locked
|
||||
arg0str = <string>; // Alternate string-based version of arg0
|
||||
moreids = <string>; // Additional line IDs, specified as a space separated list of numbers (e.g. "2 666 1003 4505")
|
||||
moreids = <string>; // Additional line IDs, specified as a space separated list of numbers (e.g. "2 666 1003 4505")
|
||||
|
||||
transparent = <bool>; // true = line is a Strife transparent line (alpha 0.25)
|
||||
transparent = <bool>; // true = line is a Strife transparent line (alpha 0.25)
|
||||
|
||||
automapstyle = <integer>; // Explicit automap style. Possible values can be
|
||||
// 0: Automap style is based on line properties (default).
|
||||
// 1: One-sided wall.
|
||||
// 2: Two-sided wall.
|
||||
// 3: Floor levels of front and back sectors are different.
|
||||
// 4: Ceiling levels of front and back sectors are different.
|
||||
// 5: 3D floor border.
|
||||
// 6: Wall with special non-door action.
|
||||
// 7: Secret door.
|
||||
// 8: Wall not seen yet.
|
||||
// 9: Locked door.
|
||||
// 10: Intra-level teleporter.
|
||||
// 11: Inter-level or game-ending teleporter.
|
||||
// 12: Unexplored secret wall.
|
||||
// 13: Portal line.
|
||||
revealed = <bool>; // true = line is initially visible on automap.
|
||||
|
||||
* Note about arg0str
|
||||
|
||||
|
@ -171,14 +188,14 @@ Note: All <bool> fields default to false unless mentioned otherwise.
|
|||
yscaleceiling = <float>; // Y texture scale of ceiling texture, Default = 1.0.
|
||||
rotationfloor = <float>; // Rotation of floor texture in degrees, Default = 0.0.
|
||||
rotationceiling = <float>; // Rotation of ceiling texture in degrees, Default = 0.0.
|
||||
ceilingplane_a = <float>; // Define the plane equation for the sector's ceiling. Default is a horizontal plane at 'heightceiling'.
|
||||
ceilingplane_b = <float>; // 'heightceiling' will still be used to calculate texture alignment.
|
||||
ceilingplane_c = <float>; // The plane equation will only be used if all 4 values are given.
|
||||
ceilingplane_d = <float>;
|
||||
floorplane_a = <float>; // Define the plane equation for the sector's floor. Default is a horizontal plane at 'heightfloor'.
|
||||
floorplane_b = <float>; // 'heightfloor' will still be used to calculate texture alignment.
|
||||
floorplane_c = <float>; // The plane equation will only be used if all 4 values are given.
|
||||
floorplane_d = <float>;
|
||||
ceilingplane_a = <float>; // Define the plane equation for the sector's ceiling. Default is a horizontal plane at 'heightceiling'.
|
||||
ceilingplane_b = <float>; // 'heightceiling' will still be used to calculate texture alignment.
|
||||
ceilingplane_c = <float>; // The plane equation will only be used if all 4 values are given.
|
||||
ceilingplane_d = <float>;
|
||||
floorplane_a = <float>; // Define the plane equation for the sector's floor. Default is a horizontal plane at 'heightfloor'.
|
||||
floorplane_b = <float>; // 'heightfloor' will still be used to calculate texture alignment.
|
||||
floorplane_c = <float>; // The plane equation will only be used if all 4 values are given.
|
||||
floorplane_d = <float>;
|
||||
lightfloor = <integer>; // The floor's light level. Default is 0.
|
||||
lightceiling = <integer>; // The ceiling's light level. Default is 0.
|
||||
lightfloorabsolute = <bool>; // true = 'lightfloor' is an absolute value. Default is
|
||||
|
@ -196,8 +213,8 @@ Note: All <bool> fields default to false unless mentioned otherwise.
|
|||
fadecolor = <integer>; // Sector's fog color as RRGGBB value, default = 0x000000.
|
||||
desaturation = <float>; // Color desaturation factor. 0 = none, 1 = full, default = 0.
|
||||
silent = <bool>; // Actors in this sector make no sound,
|
||||
nofallingdamage = <bool>; // Falling damage is disabled in this sector
|
||||
noattack = <bool>; // Blocks monster attacks in this sector.
|
||||
nofallingdamage = <bool>; // Falling damage is disabled in this sector
|
||||
noattack = <bool>; // Blocks monster attacks in this sector.
|
||||
dropactors = <bool>; // Actors drop with instantly moving floors (*)
|
||||
norespawn = <bool>; // Players can not respawn in this sector
|
||||
soundsequence = <string>; // The sound sequence to play when this sector moves. Placing a
|
||||
|
@ -215,21 +232,21 @@ Note: All <bool> fields default to false unless mentioned otherwise.
|
|||
damagehazard = <bool>; // Changes damage model to Strife's delayed damage for the given sector. Default = false.
|
||||
floorterrain = <string>; // Sets the terrain for the sector's floor. Default = 'use the flat texture's terrain definition.'
|
||||
ceilingterrain = <string>; // Sets the terrain for the sector's ceiling. Default = 'use the flat texture's terrain definition.'
|
||||
floor_reflect = <float>; // reflectiveness of floor (OpenGL only, not functional on sloped sectors)
|
||||
ceiling_reflect = <float>; // reflectiveness of ceiling (OpenGL only, not functional on sloped sectors)
|
||||
fogdensity = <integer>; // Sets an explicit fog density for the sector, overriding the default calculation from the light level. Value range is 0-510,
|
||||
// 0 meaning that the default is to be used, 2 equalling the density of a light level of 250, and 255 equalling the density of
|
||||
// a light level of 0. (OpenGL only)
|
||||
floorglowcolor = <integer>; // Sector's floor glow color as RRGGBB value, default = 'use texture's definition'. Set to -1 to disable glowing. (OpenGL 3.x and newer only)
|
||||
floorglowheight = <float>; // Height of floor glow. This only has an effect for the sector's own glow color, but not for a texture based glow. (OpenGL 3.x and newer only)
|
||||
ceilingglowcolor = <integer>; // Sector's ceiling glow color as RRGGBB value, default = 'use texture's definition'. Set to -1 to disable glowing. (OpenGL 3.x and newer only)
|
||||
ceilingglowheight = <float>; // Height of ceiling glow. This only has an effect for the sector's own glow color, but not for a texture based glow. (OpenGL 3.x and newer only)
|
||||
color_floor = <int>; // Material color of sector's floor. Default is white (0xffffff)
|
||||
color_ceiling = <int>; // Material color of sector's ceiling. Default is white (0xffffff)
|
||||
color_walltop = <int>; // Material color of top of sector's sidedefs. In OpenGL 2.x and the software renderer this will define the entire wall's color) Default is white (0xffffff)
|
||||
color_wallbottom = <int>; // Material color of bottom of sector's sidedefs (OpenGL 3.x and later only) Default is white (0xffffff)
|
||||
color_sprites = <int>; // Material color of sprites in sector. Default is white (0xffffff)
|
||||
|
||||
floor_reflect = <float>; // reflectiveness of floor (OpenGL only, not functional on sloped sectors)
|
||||
ceiling_reflect = <float>; // reflectiveness of ceiling (OpenGL only, not functional on sloped sectors)
|
||||
fogdensity = <integer>; // Sets an explicit fog density for the sector, overriding the default calculation from the light level. Value range is 0-510,
|
||||
// 0 meaning that the default is to be used, 2 equalling the density of a light level of 250, and 255 equalling the density of
|
||||
// a light level of 0. (OpenGL only)
|
||||
floorglowcolor = <integer>; // Sector's floor glow color as RRGGBB value, default = 'use texture's definition'. Set to -1 to disable glowing. (OpenGL 3.x and newer only)
|
||||
floorglowheight = <float>; // Height of floor glow. This only has an effect for the sector's own glow color, but not for a texture based glow. (OpenGL 3.x and newer only)
|
||||
ceilingglowcolor = <integer>; // Sector's ceiling glow color as RRGGBB value, default = 'use texture's definition'. Set to -1 to disable glowing. (OpenGL 3.x and newer only)
|
||||
ceilingglowheight = <float>; // Height of ceiling glow. This only has an effect for the sector's own glow color, but not for a texture based glow. (OpenGL 3.x and newer only)
|
||||
color_floor = <int>; // Material color of sector's floor. Default is white (0xffffff)
|
||||
color_ceiling = <int>; // Material color of sector's ceiling. Default is white (0xffffff)
|
||||
color_walltop = <int>; // Material color of top of sector's sidedefs. In OpenGL 2.x and the software renderer this will define the entire wall's color) Default is white (0xffffff)
|
||||
color_wallbottom = <int>; // Material color of bottom of sector's sidedefs (OpenGL 3.x and later only) Default is white (0xffffff)
|
||||
color_sprites = <int>; // Material color of sprites in sector. Default is white (0xffffff)
|
||||
|
||||
|
||||
portal_ceil_blocksound = <bool> // ceiling portal blocks sound.
|
||||
portal_ceil_disabled = <bool> // ceiling portal disabled.
|
||||
|
@ -241,8 +258,8 @@ Note: All <bool> fields default to false unless mentioned otherwise.
|
|||
portal_floor_nopass = <bool> // ceiling portal blocks movement if true.
|
||||
portal_floor_norender = <bool> // ceiling portal not rendered.
|
||||
portal_floor_overlaytype = <string> // defines translucency style, can either be "translucent" or "additive". Default is "translucent".
|
||||
|
||||
|
||||
|
||||
|
||||
* Note about dropactors
|
||||
|
||||
The spec requires this to be false by default. Currently, however, ZDoom assumes this to be true
|
||||
|
@ -253,37 +270,37 @@ Note: All <bool> fields default to false unless mentioned otherwise.
|
|||
|
||||
thing
|
||||
{
|
||||
skill# = <bool> // Unlike the base spec, # can range from 1-16.
|
||||
class# = <bool> // Unlike the base spec, # can range from 1-16.
|
||||
conversation = <int> // Assigns a conversation dialogue to this thing.
|
||||
skill# = <bool> // Unlike the base spec, # can range from 1-16.
|
||||
class# = <bool> // Unlike the base spec, # can range from 1-16.
|
||||
conversation = <int> // Assigns a conversation dialogue to this thing.
|
||||
// Parameter is the conversation ID, 0 meaning none.
|
||||
countsecret = <bool>; // Picking up this actor counts as a secret.
|
||||
arg0str = <string>; // Alternate string-based version of arg0
|
||||
gravity = <float>; // Set per-actor gravity. Positive values are multiplied with the class's property,
|
||||
// negative values are used as their absolute. Default = 1.0.
|
||||
|
||||
health = <float>; // Set per-actor health. Positive values are multiplied with the class's property,
|
||||
// negative values are used as their absolute. Default = 1.
|
||||
|
||||
renderstyle = <string>; // Set per-actor render style, overriding the class default. Possible values can be "normal",
|
||||
// "none", "add" or "additive", "subtract" or "subtractive", "stencil", "translucentstencil",
|
||||
// "addstencil", "shaded", "addshaded", "translucent", "fuzzy", "optfuzzy", "soultrans" and "shadow".
|
||||
// Default is an empty string for no change.
|
||||
fillcolor = <integer>; // Fill color used by the "stencil", "addstencil" and "translucentstencil" rendestyles, as RRGGBB value, default = 0x000000.
|
||||
alpha = <float>; // Translucency of this actor (if applicable to renderstyle), default is 1.0.
|
||||
score = <int>; // Score value of this actor, overriding the class default if not null. Default = 0.
|
||||
pitch = <integer>; // Pitch of thing in degrees. Default = 0 (horizontal).
|
||||
roll = <integer>; // Pitch of thing in degrees. Default = 0 (horizontal).
|
||||
scalex = <float>; // Vertical scaling on thing. Default = 0 (ignored).
|
||||
scaley = <float>; // Horizontal scaling on thing. Default = 0 (ignored).
|
||||
scale = <float>; // Vertical and horizontal scaling on thing. Default = 0 (ignored).
|
||||
floatbobphase = <int>; // Sets the thing's floatbobphase. Valid phase values are 0-63. Default = -1 (use actor class default).
|
||||
gravity = <float>; // Set per-actor gravity. Positive values are multiplied with the class's property,
|
||||
// negative values are used as their absolute. Default = 1.0.
|
||||
|
||||
health = <float>; // Set per-actor health. Positive values are multiplied with the class's property,
|
||||
// negative values are used as their absolute. Default = 1.
|
||||
|
||||
renderstyle = <string>; // Set per-actor render style, overriding the class default. Possible values can be "normal",
|
||||
// "none", "add" or "additive", "subtract" or "subtractive", "stencil", "translucentstencil",
|
||||
// "addstencil", "shaded", "addshaded", "translucent", "fuzzy", "optfuzzy", "soultrans" and "shadow".
|
||||
// Default is an empty string for no change.
|
||||
fillcolor = <integer>; // Fill color used by the "stencil", "addstencil" and "translucentstencil" rendestyles, as RRGGBB value, default = 0x000000.
|
||||
alpha = <float>; // Translucency of this actor (if applicable to renderstyle), default is 1.0.
|
||||
score = <int>; // Score value of this actor, overriding the class default if not null. Default = 0.
|
||||
pitch = <integer>; // Pitch of thing in degrees. Default = 0 (horizontal).
|
||||
roll = <integer>; // Pitch of thing in degrees. Default = 0 (horizontal).
|
||||
scalex = <float>; // Vertical scaling on thing. Default = 0 (ignored).
|
||||
scaley = <float>; // Horizontal scaling on thing. Default = 0 (ignored).
|
||||
scale = <float>; // Vertical and horizontal scaling on thing. Default = 0 (ignored).
|
||||
floatbobphase = <int>; // Sets the thing's floatbobphase. Valid phase values are 0-63. Default = -1 (use actor class default).
|
||||
|
||||
* Note about arg0str
|
||||
|
||||
For things with ACS specials (80-86 and 226), if arg0str is present and non-null, it
|
||||
will be used as the name of the script to execute, and arg0 will be ignored.
|
||||
On dynamic lights, arg0str can be used to set a color by name, this will supersede all args which are normally used to define a color.
|
||||
On dynamic lights, arg0str can be used to set a color by name, this will supersede all args which are normally used to define a color.
|
||||
}
|
||||
|
||||
|
||||
|
@ -430,6 +447,10 @@ sector material colors.
|
|||
1.29 04.02.2018
|
||||
arg0str in dynamic lights.
|
||||
|
||||
1.30 20.05.2018
|
||||
Added automapstyle and revealed linedef properties.
|
||||
Replaced tabs with spaces.
|
||||
|
||||
===============================================================================
|
||||
EOF
|
||||
===============================================================================
|
||||
|
|
|
@ -809,7 +809,6 @@ set( FASTMATH_SOURCES
|
|||
textures/hires/hqnx/hq4x.cpp
|
||||
textures/hires/xbr/xbrz.cpp
|
||||
textures/hires/xbr/xbrz_old.cpp
|
||||
gl/scene/gl_bsp.cpp
|
||||
gl/scene/gl_drawinfo.cpp
|
||||
gl/scene/gl_flats.cpp
|
||||
gl/scene/gl_sprite.cpp
|
||||
|
@ -819,7 +818,10 @@ set( FASTMATH_SOURCES
|
|||
gl/scene/gl_portal.cpp
|
||||
gl/scene/gl_walls_draw.cpp
|
||||
gl_load/gl_load.c
|
||||
hwrenderer/postprocessing/hw_postprocess_cvars.cpp
|
||||
hwrenderer/postprocessing/hw_postprocessshader.cpp
|
||||
hwrenderer/dynlights/hw_dynlightdata.cpp
|
||||
hwrenderer/scene/hw_bsp.cpp
|
||||
hwrenderer/scene/hw_fakeflat.cpp
|
||||
hwrenderer/scene/hw_decal.cpp
|
||||
hwrenderer/scene/hw_drawlist.cpp
|
||||
|
|
|
@ -324,6 +324,30 @@ struct AMColorset
|
|||
}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// automap colors forced by linedef
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
static const int AUTOMAP_LINE_COLORS[AMLS_COUNT] =
|
||||
{
|
||||
-1, // AMLS_Default (unused)
|
||||
AMColorset::WallColor, // AMLS_OneSided,
|
||||
AMColorset::TSWallColor, // AMLS_TwoSided
|
||||
AMColorset::FDWallColor, // AMLS_FloorDiff
|
||||
AMColorset::CDWallColor, // AMLS_CeilingDiff
|
||||
AMColorset::EFWallColor, // AMLS_ExtraFloor
|
||||
AMColorset::SpecialWallColor, // AMLS_Special
|
||||
AMColorset::SecretWallColor, // AMLS_Secret
|
||||
AMColorset::NotSeenColor, // AMLS_NotSeen
|
||||
AMColorset::LockedColor, // AMLS_Locked
|
||||
AMColorset::IntraTeleportColor, // AMLS_IntraTeleport
|
||||
AMColorset::InterTeleportColor, // AMLS_InterTeleport
|
||||
AMColorset::UnexploredSecretColor, // AMLS_UnexploredSecret
|
||||
AMColorset::PortalColor, // AMLS_Portal
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// predefined colorsets
|
||||
|
@ -2583,6 +2607,13 @@ void AM_drawWalls (bool allmap)
|
|||
}
|
||||
}
|
||||
|
||||
if (line.automapstyle > AMLS_Default && line.automapstyle < AMLS_COUNT
|
||||
&& (am_cheat == 0 || am_cheat >= 4))
|
||||
{
|
||||
AM_drawMline(&l, AUTOMAP_LINE_COLORS[line.automapstyle]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (portalmode)
|
||||
{
|
||||
AM_drawMline(&l, AMColors.PortalColor);
|
||||
|
@ -2658,7 +2689,7 @@ void AM_drawWalls (bool allmap)
|
|||
AM_drawMline(&l, AMColors.TSWallColor);
|
||||
}
|
||||
}
|
||||
else if (allmap)
|
||||
else if (allmap || (line.flags & ML_REVEALED))
|
||||
{
|
||||
if ((line.flags & ML_DONTDRAW) && (am_cheat == 0 || am_cheat >= 4))
|
||||
{
|
||||
|
|
|
@ -170,6 +170,7 @@ enum ELineFlags : unsigned
|
|||
ML_BLOCKSIGHT = 0x04000000, // blocks monster line of sight
|
||||
ML_BLOCKHITSCAN = 0x08000000, // blocks hitscan attacks
|
||||
ML_3DMIDTEX_IMPASS = 0x10000000, // [TP] if 3D midtex, behaves like a height-restricted ML_BLOCKING
|
||||
ML_REVEALED = 0x20000000, // set if revealed in automap
|
||||
|
||||
ML_PORTALCONNECT = 0x80000000, // for internal use only: This line connects to a sector with a linked portal (used to speed up sight checks.)
|
||||
};
|
||||
|
|
|
@ -586,8 +586,9 @@ bool FDrawInfo::PutFlatCompat(GLFlat *flat, bool fog)
|
|||
|
||||
|
||||
int list = list_indices[masked][foggy];
|
||||
auto newflat = gl_drawinfo->dldrawlists[list].NewFlat();
|
||||
auto newflat = dldrawlists[list].NewFlat();
|
||||
*newflat = *flat;
|
||||
newflat->iboindex = -1; // don't use the vertex buffer with legacy lights to ensure all passes use the same render logic.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -720,7 +721,7 @@ void FDrawInfo::DrawLightsCompat(GLFlat *flat, int pass)
|
|||
for (int i = 0; i<flat->sector->subsectorcount; i++)
|
||||
{
|
||||
subsector_t * sub = flat->sector->subsectors[i];
|
||||
if (gl_drawinfo->ss_renderflags[sub->Index()] & flat->renderflags)
|
||||
if (ss_renderflags[sub->Index()] & flat->renderflags)
|
||||
{
|
||||
DrawSubsectorLights(flat, sub, pass);
|
||||
}
|
||||
|
@ -730,8 +731,8 @@ void FDrawInfo::DrawLightsCompat(GLFlat *flat, int pass)
|
|||
if (!(flat->renderflags&SSRF_RENDER3DPLANES))
|
||||
{
|
||||
gl_subsectorrendernode * node = (flat->renderflags&SSRF_RENDERFLOOR) ?
|
||||
gl_drawinfo->GetOtherFloorPlanes(flat->sector->sectornum) :
|
||||
gl_drawinfo->GetOtherCeilingPlanes(flat->sector->sectornum);
|
||||
GetOtherFloorPlanes(flat->sector->sectornum) :
|
||||
GetOtherCeilingPlanes(flat->sector->sectornum);
|
||||
|
||||
while (node)
|
||||
{
|
||||
|
@ -854,7 +855,7 @@ void FDrawInfo::RenderLightsCompat(GLWall *wall, int pass)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLSceneDrawer::RenderMultipassStuff()
|
||||
void GLSceneDrawer::RenderMultipassStuff(FDrawInfo *di)
|
||||
{
|
||||
// First pass: empty background with sector light only
|
||||
|
||||
|
@ -864,8 +865,8 @@ void GLSceneDrawer::RenderMultipassStuff()
|
|||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.EnableBrightmap(false);
|
||||
gl_RenderState.Apply();
|
||||
gl_drawinfo->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(gl_drawinfo, GLPASS_ALL);
|
||||
gl_drawinfo->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(gl_drawinfo, GLPASS_ALL);
|
||||
di->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(di, GLPASS_ALL);
|
||||
di->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(di, GLPASS_ALL);
|
||||
|
||||
// Part 2: masked geometry. This is set up so that only pixels with alpha>0.5 will show
|
||||
// This creates a blank surface that only fills the nontransparent parts of the texture
|
||||
|
@ -873,18 +874,18 @@ void GLSceneDrawer::RenderMultipassStuff()
|
|||
gl_RenderState.SetTextureMode(TM_MASK);
|
||||
gl_RenderState.EnableBrightmap(true);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
|
||||
gl_drawinfo->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(gl_drawinfo, GLPASS_ALL);
|
||||
gl_drawinfo->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(gl_drawinfo, GLPASS_ALL);
|
||||
di->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(di, GLPASS_ALL);
|
||||
di->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(di, GLPASS_ALL);
|
||||
|
||||
// Part 3: The base of fogged surfaces, including the texture
|
||||
gl_RenderState.EnableBrightmap(false);
|
||||
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0);
|
||||
gl_drawinfo->dldrawlists[GLLDL_WALLS_FOG].DrawWalls(gl_drawinfo, GLPASS_ALL);
|
||||
gl_drawinfo->dldrawlists[GLLDL_FLATS_FOG].DrawFlats(gl_drawinfo, GLPASS_ALL);
|
||||
di->dldrawlists[GLLDL_WALLS_FOG].DrawWalls(di, GLPASS_ALL);
|
||||
di->dldrawlists[GLLDL_FLATS_FOG].DrawFlats(di, GLPASS_ALL);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
|
||||
gl_drawinfo->dldrawlists[GLLDL_WALLS_FOGMASKED].DrawWalls(gl_drawinfo, GLPASS_ALL);
|
||||
gl_drawinfo->dldrawlists[GLLDL_FLATS_FOGMASKED].DrawFlats(gl_drawinfo, GLPASS_ALL);
|
||||
di->dldrawlists[GLLDL_WALLS_FOGMASKED].DrawWalls(di, GLPASS_ALL);
|
||||
di->dldrawlists[GLLDL_FLATS_FOGMASKED].DrawFlats(di, GLPASS_ALL);
|
||||
|
||||
// second pass: draw lights
|
||||
glDepthMask(false);
|
||||
|
@ -895,10 +896,10 @@ void GLSceneDrawer::RenderMultipassStuff()
|
|||
gl_RenderState.BlendFunc(GL_ONE, GL_ONE);
|
||||
glDepthFunc(GL_EQUAL);
|
||||
if (level.lightmode == 8) gl_RenderState.SetSoftLightLevel(255);
|
||||
gl_drawinfo->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(gl_drawinfo, GLPASS_LIGHTTEX);
|
||||
gl_drawinfo->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(gl_drawinfo, GLPASS_LIGHTTEX);
|
||||
gl_drawinfo->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(gl_drawinfo, GLPASS_LIGHTTEX);
|
||||
gl_drawinfo->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(gl_drawinfo, GLPASS_LIGHTTEX);
|
||||
di->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(di, GLPASS_LIGHTTEX);
|
||||
di->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(di, GLPASS_LIGHTTEX);
|
||||
di->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(di, GLPASS_LIGHTTEX);
|
||||
di->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(di, GLPASS_LIGHTTEX);
|
||||
gl_RenderState.BlendEquation(GL_FUNC_ADD);
|
||||
}
|
||||
else gl_lights = false;
|
||||
|
@ -910,11 +911,11 @@ void GLSceneDrawer::RenderMultipassStuff()
|
|||
gl_RenderState.EnableFog(false);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
gl_drawinfo->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(gl_drawinfo, GLPASS_TEXONLY);
|
||||
gl_drawinfo->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(gl_drawinfo, GLPASS_TEXONLY);
|
||||
di->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(di, GLPASS_TEXONLY);
|
||||
di->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(di, GLPASS_TEXONLY);
|
||||
gl_RenderState.AlphaFunc(GL_GREATER, gl_mask_threshold);
|
||||
gl_drawinfo->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(gl_drawinfo, GLPASS_TEXONLY);
|
||||
gl_drawinfo->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(gl_drawinfo, GLPASS_TEXONLY);
|
||||
di->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(di, GLPASS_TEXONLY);
|
||||
di->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(di, GLPASS_TEXONLY);
|
||||
|
||||
// fourth pass: additive lights
|
||||
gl_RenderState.EnableFog(true);
|
||||
|
@ -922,14 +923,14 @@ void GLSceneDrawer::RenderMultipassStuff()
|
|||
glDepthFunc(GL_EQUAL);
|
||||
if (gl_SetupLightTexture())
|
||||
{
|
||||
gl_drawinfo->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(gl_drawinfo, GLPASS_LIGHTTEX_ADDITIVE);
|
||||
gl_drawinfo->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(gl_drawinfo, GLPASS_LIGHTTEX_ADDITIVE);
|
||||
gl_drawinfo->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(gl_drawinfo, GLPASS_LIGHTTEX_ADDITIVE);
|
||||
gl_drawinfo->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(gl_drawinfo, GLPASS_LIGHTTEX_ADDITIVE);
|
||||
gl_drawinfo->dldrawlists[GLLDL_WALLS_FOG].DrawWalls(gl_drawinfo, GLPASS_LIGHTTEX_FOGGY);
|
||||
gl_drawinfo->dldrawlists[GLLDL_WALLS_FOGMASKED].DrawWalls(gl_drawinfo, GLPASS_LIGHTTEX_FOGGY);
|
||||
gl_drawinfo->dldrawlists[GLLDL_FLATS_FOG].DrawFlats(gl_drawinfo, GLPASS_LIGHTTEX_FOGGY);
|
||||
gl_drawinfo->dldrawlists[GLLDL_FLATS_FOGMASKED].DrawFlats(gl_drawinfo, GLPASS_LIGHTTEX_FOGGY);
|
||||
di->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(di, GLPASS_LIGHTTEX_ADDITIVE);
|
||||
di->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(di, GLPASS_LIGHTTEX_ADDITIVE);
|
||||
di->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(di, GLPASS_LIGHTTEX_ADDITIVE);
|
||||
di->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(di, GLPASS_LIGHTTEX_ADDITIVE);
|
||||
di->dldrawlists[GLLDL_WALLS_FOG].DrawWalls(di, GLPASS_LIGHTTEX_FOGGY);
|
||||
di->dldrawlists[GLLDL_WALLS_FOGMASKED].DrawWalls(di, GLPASS_LIGHTTEX_FOGGY);
|
||||
di->dldrawlists[GLLDL_FLATS_FOG].DrawFlats(di, GLPASS_LIGHTTEX_FOGGY);
|
||||
di->dldrawlists[GLLDL_FLATS_FOGMASKED].DrawFlats(di, GLPASS_LIGHTTEX_FOGGY);
|
||||
}
|
||||
else gl_lights = false;
|
||||
|
||||
|
|
|
@ -125,6 +125,8 @@ void FSimpleVertexBuffer::set(FSimpleVertex *verts, int count)
|
|||
FFlatVertexBuffer::FFlatVertexBuffer(int width, int height)
|
||||
: FVertexBuffer(!gl.legacyMode), FFlatVertexGenerator(width, height)
|
||||
{
|
||||
ibo_id = 0;
|
||||
if (gl.buffermethod != BM_LEGACY) glGenBuffers(1, &ibo_id);
|
||||
switch (gl.buffermethod)
|
||||
{
|
||||
case BM_PERSISTENT:
|
||||
|
@ -157,6 +159,7 @@ FFlatVertexBuffer::FFlatVertexBuffer(int width, int height)
|
|||
mIndex = mCurIndex = 0;
|
||||
mNumReserved = NUM_RESERVED;
|
||||
|
||||
mMap = map;
|
||||
Map();
|
||||
memcpy(map, &vbo_shadowdata[0], mNumReserved * sizeof(FFlatVertex));
|
||||
Unmap();
|
||||
|
@ -170,6 +173,11 @@ FFlatVertexBuffer::~FFlatVertexBuffer()
|
|||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
if (ibo_id != 0)
|
||||
{
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glDeleteBuffers(1, &ibo_id);
|
||||
}
|
||||
if (gl.legacyMode)
|
||||
{
|
||||
delete[] map;
|
||||
|
@ -188,6 +196,7 @@ void FFlatVertexBuffer::OutputResized(int width, int height)
|
|||
void FFlatVertexBuffer::BindVBO()
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id);
|
||||
if (!gl.legacyMode)
|
||||
{
|
||||
glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->x);
|
||||
|
@ -215,7 +224,7 @@ void FFlatVertexBuffer::Map()
|
|||
unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
gl_RenderState.ResetVertexBuffer();
|
||||
map = (FFlatVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, bytesize, GL_MAP_WRITE_BIT|GL_MAP_UNSYNCHRONIZED_BIT);
|
||||
mMap = map = (FFlatVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, bytesize, GL_MAP_WRITE_BIT|GL_MAP_UNSYNCHRONIZED_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,7 +236,7 @@ void FFlatVertexBuffer::Unmap()
|
|||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
gl_RenderState.ResetVertexBuffer();
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
map = nullptr;
|
||||
mMap = map = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -240,9 +249,17 @@ void FFlatVertexBuffer::Unmap()
|
|||
void FFlatVertexBuffer::CreateVBO()
|
||||
{
|
||||
vbo_shadowdata.Resize(mNumReserved);
|
||||
FFlatVertexGenerator::CreateVertices();
|
||||
if (!gl.legacyMode)
|
||||
{
|
||||
FFlatVertexGenerator::CreateVertices();
|
||||
}
|
||||
mCurIndex = mIndex = vbo_shadowdata.Size();
|
||||
Map();
|
||||
memcpy(map, &vbo_shadowdata[0], vbo_shadowdata.Size() * sizeof(FFlatVertex));
|
||||
Unmap();
|
||||
if (ibo_id > 0)
|
||||
{
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, ibo_data.Size() * sizeof(uint32_t), &ibo_data[0], GL_STATIC_DRAW);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,6 +95,7 @@ public:
|
|||
|
||||
class FFlatVertexBuffer : public FVertexBuffer, public FFlatVertexGenerator
|
||||
{
|
||||
unsigned int ibo_id;
|
||||
FFlatVertex *map;
|
||||
unsigned int mIndex;
|
||||
std::atomic<unsigned int> mCurIndex;
|
||||
|
@ -177,14 +178,9 @@ public:
|
|||
|
||||
#endif
|
||||
|
||||
void CheckPlanes(sector_t *sector)
|
||||
uint32_t *GetIndexPointer() const
|
||||
{
|
||||
FFlatVertexGenerator::CheckPlanes(sector, map);
|
||||
}
|
||||
|
||||
void CheckUpdate(sector_t *sector)
|
||||
{
|
||||
FFlatVertexGenerator::CheckUpdate(sector, map);
|
||||
return ibo_id == 0 ? &ibo_data[0] : nullptr;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
|
|
|
@ -36,6 +36,7 @@ class FGLModelRenderer : public FModelRenderer
|
|||
public:
|
||||
FGLModelRenderer(int mli) : modellightindex(mli)
|
||||
{}
|
||||
ModelRendererType GetType() const override { return GLModelRendererType; }
|
||||
void BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix) override;
|
||||
void EndDrawModel(AActor *actor, FSpriteModelFrame *smf) override;
|
||||
IModelVertexBuffer *CreateVertexBuffer(bool needindex, bool singleframe) override;
|
||||
|
|
|
@ -85,7 +85,6 @@ extern bool NoInterpolateView;
|
|||
FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb)
|
||||
{
|
||||
framebuffer = fb;
|
||||
mClipPortal = nullptr;
|
||||
mCurrentPortal = nullptr;
|
||||
mMirrorCount = 0;
|
||||
mPlaneMirrorCount = 0;
|
||||
|
@ -121,9 +120,6 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb)
|
|||
mCustomPostProcessShaders = nullptr;
|
||||
}
|
||||
|
||||
void gl_LoadModels();
|
||||
void gl_FlushModels();
|
||||
|
||||
void FGLRenderer::Initialize(int width, int height)
|
||||
{
|
||||
mBuffers = new FGLRenderBuffers();
|
||||
|
@ -175,7 +171,6 @@ void FGLRenderer::Initialize(int width, int height)
|
|||
SetupLevel();
|
||||
mShaderManager = new FShaderManager;
|
||||
mSamplerManager = new FSamplerManager;
|
||||
gl_LoadModels();
|
||||
|
||||
GLPortal::Initialize();
|
||||
}
|
||||
|
@ -184,7 +179,7 @@ FGLRenderer::~FGLRenderer()
|
|||
{
|
||||
GLPortal::Shutdown();
|
||||
|
||||
gl_FlushModels();
|
||||
FlushModels();
|
||||
AActor::DeleteAllAttachedLights();
|
||||
FMaterial::FlushAll();
|
||||
if (legacyShaders) delete legacyShaders;
|
||||
|
|
|
@ -87,7 +87,7 @@ class FGLRenderer
|
|||
public:
|
||||
|
||||
OpenGLFrameBuffer *framebuffer;
|
||||
GLPortal *mClipPortal;
|
||||
//GLPortal *mClipPortal;
|
||||
GLPortal *mCurrentPortal;
|
||||
int mMirrorCount;
|
||||
int mPlaneMirrorCount;
|
||||
|
|
|
@ -62,7 +62,7 @@ static void matrixToGL(const VSMatrix &mat, int loc)
|
|||
void FRenderState::Reset()
|
||||
{
|
||||
mTextureEnabled = true;
|
||||
mClipLineEnabled = mSplitEnabled = mBrightmapEnabled = mFogEnabled = mGlowEnabled = false;
|
||||
mClipLineShouldBeActive = mClipLineEnabled = mSplitEnabled = mBrightmapEnabled = mFogEnabled = mGlowEnabled = false;
|
||||
mColorMask[0] = mColorMask[1] = mColorMask[2] = mColorMask[3] = true;
|
||||
currentColorMask[0] = currentColorMask[1] = currentColorMask[2] = currentColorMask[3] = true;
|
||||
mFogColor.d = -1;
|
||||
|
|
|
@ -81,6 +81,7 @@ class FRenderState
|
|||
bool mGlowEnabled;
|
||||
bool mSplitEnabled;
|
||||
bool mClipLineEnabled;
|
||||
bool mClipLineShouldBeActive;
|
||||
bool mBrightmapEnabled;
|
||||
bool mColorMask[4];
|
||||
bool currentColorMask[4];
|
||||
|
@ -201,6 +202,11 @@ public:
|
|||
return mClipLineEnabled;
|
||||
}
|
||||
|
||||
bool GetClipLineShouldBeActive()
|
||||
{
|
||||
return mClipLineShouldBeActive;
|
||||
}
|
||||
|
||||
void SetClipHeight(float height, float direction);
|
||||
|
||||
void SetNormal(FVector3 norm)
|
||||
|
@ -326,6 +332,11 @@ public:
|
|||
glDisable(GL_CLIP_DISTANCE0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// this needs to be flagged because in this case per-sector plane rendering needs to be disabled if a clip plane is active.
|
||||
mClipLineShouldBeActive = on;
|
||||
}
|
||||
}
|
||||
|
||||
void EnableBrightmap(bool on)
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#include "gl/renderer/gl_quaddrawer.h"
|
||||
#include "gl/dynlights/gl_lightbuffer.h"
|
||||
|
||||
FDrawInfo * gl_drawinfo;
|
||||
static FDrawInfo * gl_drawinfo;
|
||||
FDrawInfoList di_list;
|
||||
|
||||
//==========================================================================
|
||||
|
@ -81,13 +81,13 @@ void FDrawInfo::DoDrawSorted(HWDrawList *dl, SortNode * head)
|
|||
DoDrawSorted(dl, head->left);
|
||||
gl_RenderState.SetClipSplit(clipsplit);
|
||||
}
|
||||
dl->DoDraw(gl_drawinfo, GLPASS_TRANSLUCENT, head->itemindex, true);
|
||||
dl->DoDraw(this, GLPASS_TRANSLUCENT, head->itemindex, true);
|
||||
if (head->equal)
|
||||
{
|
||||
SortNode * ehead=head->equal;
|
||||
while (ehead)
|
||||
{
|
||||
dl->DoDraw(gl_drawinfo, GLPASS_TRANSLUCENT, ehead->itemindex, true);
|
||||
dl->DoDraw(this, GLPASS_TRANSLUCENT, ehead->itemindex, true);
|
||||
ehead=ehead->equal;
|
||||
}
|
||||
}
|
||||
|
@ -191,26 +191,26 @@ FDrawInfo::~FDrawInfo()
|
|||
// Sets up a new drawinfo struct
|
||||
//
|
||||
//==========================================================================
|
||||
void FDrawInfo::StartDrawInfo(GLSceneDrawer *drawer)
|
||||
|
||||
// OpenGL has no use for multiple clippers so use the same one for all DrawInfos.
|
||||
static Clipper staticClipper;
|
||||
|
||||
FDrawInfo *FDrawInfo::StartDrawInfo(GLSceneDrawer *drawer)
|
||||
{
|
||||
FDrawInfo *di=di_list.GetNew();
|
||||
di->mDrawer = drawer;
|
||||
di->mVBO = GLRenderer->mVBO;
|
||||
di->mClipper = &staticClipper;
|
||||
staticClipper.Clear();
|
||||
di->FixedColormap = drawer->FixedColormap;
|
||||
di->StartScene();
|
||||
return di;
|
||||
}
|
||||
|
||||
void FDrawInfo::StartScene()
|
||||
{
|
||||
ClearBuffers();
|
||||
|
||||
sectorrenderflags.Resize(level.sectors.Size());
|
||||
ss_renderflags.Resize(level.subsectors.Size());
|
||||
no_renderflags.Resize(level.subsectors.Size());
|
||||
|
||||
memset(§orrenderflags[0], 0, level.sectors.Size() * sizeof(sectorrenderflags[0]));
|
||||
memset(&ss_renderflags[0], 0, level.subsectors.Size() * sizeof(ss_renderflags[0]));
|
||||
memset(&no_renderflags[0], 0, level.nodes.Size() * sizeof(no_renderflags[0]));
|
||||
|
||||
next = gl_drawinfo;
|
||||
gl_drawinfo = this;
|
||||
for (int i = 0; i < GLDL_TYPES; i++) drawlists[i].Reset();
|
||||
|
@ -392,8 +392,8 @@ void FDrawInfo::FloodUpperGap(seg_t * seg)
|
|||
{
|
||||
wallseg ws;
|
||||
sector_t ffake, bfake;
|
||||
sector_t * fakefsector = hw_FakeFlat(seg->frontsector, &ffake, mDrawer->in_area, true);
|
||||
sector_t * fakebsector = hw_FakeFlat(seg->backsector, &bfake, mDrawer->in_area, false);
|
||||
sector_t * fakefsector = hw_FakeFlat(seg->frontsector, &ffake, in_area, true);
|
||||
sector_t * fakebsector = hw_FakeFlat(seg->backsector, &bfake, in_area, false);
|
||||
|
||||
vertex_t * v1, * v2;
|
||||
|
||||
|
@ -444,8 +444,8 @@ void FDrawInfo::FloodLowerGap(seg_t * seg)
|
|||
{
|
||||
wallseg ws;
|
||||
sector_t ffake, bfake;
|
||||
sector_t * fakefsector = hw_FakeFlat(seg->frontsector, &ffake, mDrawer->in_area, true);
|
||||
sector_t * fakebsector = hw_FakeFlat(seg->backsector, &bfake, mDrawer->in_area, false);
|
||||
sector_t * fakefsector = hw_FakeFlat(seg->frontsector, &ffake, in_area, true);
|
||||
sector_t * fakebsector = hw_FakeFlat(seg->backsector, &bfake, in_area, false);
|
||||
|
||||
vertex_t * v1, * v2;
|
||||
|
||||
|
@ -505,12 +505,6 @@ void FDrawInfo::AddSubsectorToPortal(FSectorPortalGroup *portal, subsector_t *su
|
|||
portal->GetRenderState()->AddSubsector(sub);
|
||||
}
|
||||
|
||||
int FDrawInfo::ClipPoint(const DVector3 &pos)
|
||||
{
|
||||
return GLRenderer->mClipPortal->ClipPoint(pos);
|
||||
}
|
||||
|
||||
|
||||
std::pair<FFlatVertex *, unsigned int> FDrawInfo::AllocVertices(unsigned int count)
|
||||
{
|
||||
unsigned int index = -1;
|
||||
|
|
|
@ -121,6 +121,7 @@ struct FDrawInfo : public HWDrawInfo
|
|||
void ProcessLights(GLFlat *flat, bool istrans);
|
||||
void DrawSubsector(GLFlat *flat, subsector_t * sub);
|
||||
void SetupSubsectorLights(GLFlat *flat, int pass, subsector_t * sub, int *dli);
|
||||
void SetupSectorLights(GLFlat *flat, int pass, int *dli);
|
||||
|
||||
// Sprite drawer
|
||||
void DrawSprite(GLSprite *sprite, int pass);
|
||||
|
@ -133,9 +134,8 @@ struct FDrawInfo : public HWDrawInfo
|
|||
// These two may be moved to the API independent part of the renderer later.
|
||||
void ProcessLowerMinisegs(TArray<seg_t *> &lowersegs) override;
|
||||
void AddSubsectorToPortal(FSectorPortalGroup *portal, subsector_t *sub) override;
|
||||
int ClipPoint(const DVector3 &pos) override;
|
||||
|
||||
static void StartDrawInfo(GLSceneDrawer *drawer);
|
||||
static FDrawInfo *StartDrawInfo(GLSceneDrawer *drawer);
|
||||
static void EndDrawInfo();
|
||||
|
||||
gl_subsectorrendernode * GetOtherFloorPlanes(unsigned int sector)
|
||||
|
@ -162,8 +162,6 @@ public:
|
|||
};
|
||||
|
||||
|
||||
extern FDrawInfo * gl_drawinfo;
|
||||
|
||||
void gl_SetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblending);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -82,6 +82,34 @@ void FDrawInfo::SetupSubsectorLights(GLFlat *flat, int pass, subsector_t * sub,
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FDrawInfo::SetupSectorLights(GLFlat *flat, int pass, int *dli)
|
||||
{
|
||||
if (dli != NULL && *dli != -1)
|
||||
{
|
||||
gl_RenderState.ApplyLightIndex(GLRenderer->mLights->GetIndex(*dli));
|
||||
(*dli)++;
|
||||
return;
|
||||
}
|
||||
if (flat->SetupSectorLights(pass, flat->sector, lightdata))
|
||||
{
|
||||
int d = GLRenderer->mLights->UploadLights(lightdata);
|
||||
if (pass == GLPASS_LIGHTSONLY)
|
||||
{
|
||||
GLRenderer->mLights->StoreIndex(d);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_RenderState.ApplyLightIndex(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FDrawInfo::DrawSubsector(GLFlat *flat, subsector_t * sub)
|
||||
{
|
||||
if (gl.buffermethod != BM_DEFERRED)
|
||||
|
@ -136,23 +164,30 @@ void FDrawInfo::DrawSubsector(GLFlat *flat, subsector_t * sub)
|
|||
void FDrawInfo::ProcessLights(GLFlat *flat, bool istrans)
|
||||
{
|
||||
flat->dynlightindex = GLRenderer->mLights->GetIndexPtr();
|
||||
|
||||
// Draw the subsectors belonging to this sector
|
||||
for (int i=0; i< flat->sector->subsectorcount; i++)
|
||||
|
||||
if (flat->sector->ibocount > 0 && !gl_RenderState.GetClipLineShouldBeActive())
|
||||
{
|
||||
subsector_t * sub = flat->sector->subsectors[i];
|
||||
if (gl_drawinfo->ss_renderflags[sub->Index()]& flat->renderflags || istrans)
|
||||
SetupSectorLights(flat, GLPASS_LIGHTSONLY, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw the subsectors belonging to this sector
|
||||
for (int i = 0; i < flat->sector->subsectorcount; i++)
|
||||
{
|
||||
SetupSubsectorLights(flat, GLPASS_LIGHTSONLY, sub, nullptr);
|
||||
subsector_t * sub = flat->sector->subsectors[i];
|
||||
if (ss_renderflags[sub->Index()] & flat->renderflags || istrans)
|
||||
{
|
||||
SetupSubsectorLights(flat, GLPASS_LIGHTSONLY, sub, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Draw the subsectors assigned to it due to missing textures
|
||||
if (!(flat->renderflags&SSRF_RENDER3DPLANES))
|
||||
{
|
||||
gl_subsectorrendernode * node = (flat->renderflags&SSRF_RENDERFLOOR)?
|
||||
gl_drawinfo->GetOtherFloorPlanes(flat->sector->sectornum) :
|
||||
gl_drawinfo->GetOtherCeilingPlanes(flat->sector->sectornum);
|
||||
GetOtherFloorPlanes(flat->sector->sectornum) :
|
||||
GetOtherCeilingPlanes(flat->sector->sectornum);
|
||||
|
||||
while (node)
|
||||
{
|
||||
|
@ -175,33 +210,44 @@ void FDrawInfo::DrawSubsectors(GLFlat *flat, int pass, bool processlights, bool
|
|||
|
||||
gl_RenderState.Apply();
|
||||
if (gl.legacyMode) processlights = false;
|
||||
if (flat->vboindex >= 0)
|
||||
|
||||
auto vcount = flat->sector->ibocount;
|
||||
if (vcount > 0 && !gl_RenderState.GetClipLineShouldBeActive())
|
||||
{
|
||||
int index = flat->vboindex;
|
||||
if (processlights) SetupSectorLights(flat, GLPASS_ALL, &dli);
|
||||
drawcalls.Clock();
|
||||
glDrawElements(GL_TRIANGLES, vcount, GL_UNSIGNED_INT, GLRenderer->mVBO->GetIndexPointer() + flat->iboindex);
|
||||
drawcalls.Unclock();
|
||||
flatvertices += vcount;
|
||||
flatprimitives++;
|
||||
}
|
||||
else if (flat->iboindex >= 0)
|
||||
{
|
||||
int index = flat->iboindex;
|
||||
for (int i=0; i<flat->sector->subsectorcount; i++)
|
||||
{
|
||||
subsector_t * sub = flat->sector->subsectors[i];
|
||||
if (sub->numlines <= 2) continue;
|
||||
|
||||
if (gl_drawinfo->ss_renderflags[sub->Index()]& flat->renderflags || istrans)
|
||||
if (ss_renderflags[sub->Index()]& flat->renderflags || istrans)
|
||||
{
|
||||
if (processlights) SetupSubsectorLights(flat, GLPASS_ALL, sub, &dli);
|
||||
drawcalls.Clock();
|
||||
glDrawArrays(GL_TRIANGLE_FAN, index, sub->numlines);
|
||||
glDrawElements(GL_TRIANGLES, (sub->numlines - 2) * 3, GL_UNSIGNED_INT, GLRenderer->mVBO->GetIndexPointer() + index);
|
||||
drawcalls.Unclock();
|
||||
flatvertices += sub->numlines;
|
||||
flatprimitives++;
|
||||
}
|
||||
index += sub->numlines;
|
||||
index += (sub->numlines - 2) * 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw the subsectors belonging to this sector
|
||||
// (can this case even happen?)
|
||||
for (int i=0; i<flat->sector->subsectorcount; i++)
|
||||
{
|
||||
subsector_t * sub = flat->sector->subsectors[i];
|
||||
if (gl_drawinfo->ss_renderflags[sub->Index()]& flat->renderflags || istrans)
|
||||
if (ss_renderflags[sub->Index()]& flat->renderflags || istrans)
|
||||
{
|
||||
if (processlights) SetupSubsectorLights(flat, GLPASS_ALL, sub, &dli);
|
||||
DrawSubsector(flat, sub);
|
||||
|
@ -213,8 +259,8 @@ void FDrawInfo::DrawSubsectors(GLFlat *flat, int pass, bool processlights, bool
|
|||
if (!(flat->renderflags&SSRF_RENDER3DPLANES))
|
||||
{
|
||||
gl_subsectorrendernode * node = (flat->renderflags&SSRF_RENDERFLOOR)?
|
||||
gl_drawinfo->GetOtherFloorPlanes(flat->sector->sectornum) :
|
||||
gl_drawinfo->GetOtherCeilingPlanes(flat->sector->sectornum);
|
||||
GetOtherFloorPlanes(flat->sector->sectornum) :
|
||||
GetOtherCeilingPlanes(flat->sector->sectornum);
|
||||
|
||||
while (node)
|
||||
{
|
||||
|
@ -399,7 +445,7 @@ void FDrawInfo::AddFlat(GLFlat *flat, bool fog)
|
|||
bool masked = flat->gltexture->isMasked() && ((flat->renderflags&SSRF_RENDER3DPLANES) || flat->stack);
|
||||
list = masked ? GLDL_MASKEDFLATS : GLDL_PLAINFLATS;
|
||||
}
|
||||
auto newflat = gl_drawinfo->drawlists[list].NewFlat();
|
||||
auto newflat = drawlists[list].NewFlat();
|
||||
*newflat = *flat;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "hwrenderer/scene/hw_clipper.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
#include "gl/scene/gl_portal.h"
|
||||
#include "gl/scene/gl_scenedrawer.h"
|
||||
#include "gl/stereo3d/scoped_color_mask.h"
|
||||
|
@ -160,8 +159,9 @@ void GLPortal::DrawPortalStencil()
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool GLPortal::Start(bool usestencil, bool doquery)
|
||||
bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo **pDi)
|
||||
{
|
||||
*pDi = nullptr;
|
||||
rendered_portals++;
|
||||
Clocker c(PortalAll);
|
||||
if (usestencil)
|
||||
|
@ -228,7 +228,7 @@ bool GLPortal::Start(bool usestencil, bool doquery)
|
|||
return false;
|
||||
}
|
||||
}
|
||||
FDrawInfo::StartDrawInfo(drawer);
|
||||
*pDi = FDrawInfo::StartDrawInfo(drawer);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -256,7 +256,7 @@ bool GLPortal::Start(bool usestencil, bool doquery)
|
|||
{
|
||||
if (NeedDepthBuffer())
|
||||
{
|
||||
FDrawInfo::StartDrawInfo(drawer);
|
||||
*pDi = FDrawInfo::StartDrawInfo(drawer);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -271,15 +271,12 @@ bool GLPortal::Start(bool usestencil, bool doquery)
|
|||
savedshowviewer = r_viewpoint.showviewer;
|
||||
savedAngles = r_viewpoint.Angles;
|
||||
savedviewactor=GLRenderer->mViewActor;
|
||||
savedviewarea=drawer->in_area;
|
||||
savedviewpath[0] = r_viewpoint.Path[0];
|
||||
savedviewpath[1] = r_viewpoint.Path[1];
|
||||
savedvisibility = r_viewpoint.camera ? r_viewpoint.camera->renderflags & RF_MAYBEINVISIBLE : ActorRenderFlags::FromInt(0);
|
||||
|
||||
|
||||
PrevPortal = GLRenderer->mCurrentPortal;
|
||||
PrevClipPortal = GLRenderer->mClipPortal;
|
||||
GLRenderer->mClipPortal = NULL; // Portals which need this have to set it themselves
|
||||
GLRenderer->mCurrentPortal = this;
|
||||
|
||||
if (PrevPortal != NULL) PrevPortal->PushState();
|
||||
|
@ -287,14 +284,14 @@ bool GLPortal::Start(bool usestencil, bool doquery)
|
|||
}
|
||||
|
||||
|
||||
inline void GLPortal::ClearClipper()
|
||||
inline void GLPortal::ClearClipper(FDrawInfo *di)
|
||||
{
|
||||
DAngle angleOffset = deltaangle(savedAngles.Yaw, r_viewpoint.Angles.Yaw);
|
||||
|
||||
drawer->clipper.Clear();
|
||||
di->mClipper->Clear();
|
||||
|
||||
// Set the clipper to the minimal visible area
|
||||
drawer->clipper.SafeAddClipRange(0,0xffffffff);
|
||||
di->mClipper->SafeAddClipRange(0,0xffffffff);
|
||||
for (unsigned int i = 0; i < lines.Size(); i++)
|
||||
{
|
||||
DAngle startAngle = (DVector2(lines[i].glseg.x2, lines[i].glseg.y2) - savedViewPos).Angle() + angleOffset;
|
||||
|
@ -302,16 +299,16 @@ inline void GLPortal::ClearClipper()
|
|||
|
||||
if (deltaangle(endAngle, startAngle) < 0)
|
||||
{
|
||||
drawer->clipper.SafeRemoveClipRangeRealAngles(startAngle.BAMs(), endAngle.BAMs());
|
||||
di->mClipper->SafeRemoveClipRangeRealAngles(startAngle.BAMs(), endAngle.BAMs());
|
||||
}
|
||||
}
|
||||
|
||||
// and finally clip it to the visible area
|
||||
angle_t a1 = drawer->FrustumAngle();
|
||||
if (a1 < ANGLE_180) drawer->clipper.SafeAddClipRangeRealAngles(r_viewpoint.Angles.Yaw.BAMs() + a1, r_viewpoint.Angles.Yaw.BAMs() - a1);
|
||||
if (a1 < ANGLE_180) di->mClipper->SafeAddClipRangeRealAngles(r_viewpoint.Angles.Yaw.BAMs() + a1, r_viewpoint.Angles.Yaw.BAMs() - a1);
|
||||
|
||||
// lock the parts that have just been clipped out.
|
||||
drawer->clipper.SetSilhouette();
|
||||
di->mClipper->SetSilhouette();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -326,7 +323,6 @@ void GLPortal::End(bool usestencil)
|
|||
Clocker c(PortalAll);
|
||||
if (PrevPortal != NULL) PrevPortal->PopState();
|
||||
GLRenderer->mCurrentPortal = PrevPortal;
|
||||
GLRenderer->mClipPortal = PrevClipPortal;
|
||||
|
||||
if (usestencil)
|
||||
{
|
||||
|
@ -340,7 +336,6 @@ void GLPortal::End(bool usestencil)
|
|||
r_viewpoint.ActorPos = savedViewActorPos;
|
||||
r_viewpoint.Angles = savedAngles;
|
||||
GLRenderer->mViewActor=savedviewactor;
|
||||
drawer->in_area=savedviewarea;
|
||||
if (r_viewpoint.camera != nullptr) r_viewpoint.camera->renderflags = (r_viewpoint.camera->renderflags & ~RF_MAYBEINVISIBLE) | savedvisibility;
|
||||
drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
|
||||
|
||||
|
@ -399,7 +394,6 @@ void GLPortal::End(bool usestencil)
|
|||
r_viewpoint.Pos = savedViewPos;
|
||||
r_viewpoint.Angles = savedAngles;
|
||||
GLRenderer->mViewActor=savedviewactor;
|
||||
drawer->in_area=savedviewarea;
|
||||
if (r_viewpoint.camera != nullptr) r_viewpoint.camera->renderflags |= savedvisibility;
|
||||
drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
|
||||
|
||||
|
@ -432,11 +426,11 @@ void GLPortal::End(bool usestencil)
|
|||
//-----------------------------------------------------------------------------
|
||||
void GLPortal::StartFrame()
|
||||
{
|
||||
GLPortal * p=NULL;
|
||||
GLPortal * p = nullptr;
|
||||
portals.Push(p);
|
||||
if (renderdepth==0)
|
||||
if (renderdepth == 0)
|
||||
{
|
||||
inskybox=false;
|
||||
inskybox = false;
|
||||
screen->instack[sector_t::floor] = screen->instack[sector_t::ceiling] = 0;
|
||||
}
|
||||
renderdepth++;
|
||||
|
@ -560,26 +554,6 @@ GLPortal * GLPortal::FindPortal(const void * src)
|
|||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Save/RestoreMapSection
|
||||
//
|
||||
// saves CurrentMapSection for a recursive call of SceneDrawer::DrawScene
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void GLPortal::SaveMapSection()
|
||||
{
|
||||
SavedMapSection = std::move(drawer->CurrentMapSections);
|
||||
drawer->CurrentMapSections.Resize(SavedMapSection.Size());
|
||||
drawer->CurrentMapSections.Zero();
|
||||
}
|
||||
|
||||
void GLPortal::RestoreMapSection()
|
||||
{
|
||||
drawer->CurrentMapSections = std::move(SavedMapSection);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
|
@ -596,7 +570,7 @@ void GLPortal::RestoreMapSection()
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void GLSkyboxPortal::DrawContents()
|
||||
void GLSkyboxPortal::DrawContents(FDrawInfo *di)
|
||||
{
|
||||
int old_pm = PlaneMirrorMode;
|
||||
int saved_extralight = r_viewpoint.extralight;
|
||||
|
@ -629,15 +603,15 @@ void GLSkyboxPortal::DrawContents()
|
|||
|
||||
inskybox = true;
|
||||
drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
|
||||
drawer->SetViewArea();
|
||||
ClearClipper();
|
||||
di->SetViewArea();
|
||||
ClearClipper(di);
|
||||
|
||||
int mapsection = R_PointInSubsector(r_viewpoint.Pos)->mapsection;
|
||||
|
||||
SaveMapSection();
|
||||
drawer->CurrentMapSections.Set(mapsection);
|
||||
di->CurrentMapSections.Zero();
|
||||
di->CurrentMapSections.Set(mapsection);
|
||||
|
||||
drawer->DrawScene(DM_SKYPORTAL);
|
||||
drawer->DrawScene(di, DM_SKYPORTAL);
|
||||
portal->mFlags &= ~PORTSF_INSKYBOX;
|
||||
inskybox = false;
|
||||
gl_RenderState.SetDepthClamp(oldclamp);
|
||||
|
@ -645,8 +619,6 @@ void GLSkyboxPortal::DrawContents()
|
|||
|
||||
PlaneMirrorMode = old_pm;
|
||||
r_viewpoint.extralight = saved_extralight;
|
||||
|
||||
RestoreMapSection();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -688,7 +660,7 @@ GLSectorStackPortal::~GLSectorStackPortal()
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static uint8_t SetCoverage(void *node)
|
||||
static uint8_t SetCoverage(FDrawInfo *di, void *node)
|
||||
{
|
||||
if (level.nodes.Size() == 0)
|
||||
{
|
||||
|
@ -697,18 +669,18 @@ static uint8_t SetCoverage(void *node)
|
|||
if (!((size_t)node & 1)) // Keep going until found a subsector
|
||||
{
|
||||
node_t *bsp = (node_t *)node;
|
||||
uint8_t coverage = SetCoverage(bsp->children[0]) | SetCoverage(bsp->children[1]);
|
||||
gl_drawinfo->no_renderflags[bsp->Index()] = coverage;
|
||||
uint8_t coverage = SetCoverage(di, bsp->children[0]) | SetCoverage(di, bsp->children[1]);
|
||||
di->no_renderflags[bsp->Index()] = coverage;
|
||||
return coverage;
|
||||
}
|
||||
else
|
||||
{
|
||||
subsector_t *sub = (subsector_t *)((uint8_t *)node - 1);
|
||||
return gl_drawinfo->ss_renderflags[sub->Index()] & SSRF_SEEN;
|
||||
return di->ss_renderflags[sub->Index()] & SSRF_SEEN;
|
||||
}
|
||||
}
|
||||
|
||||
void GLSectorStackPortal::SetupCoverage()
|
||||
void GLSectorStackPortal::SetupCoverage(FDrawInfo *di)
|
||||
{
|
||||
for(unsigned i=0; i<subsectors.Size(); i++)
|
||||
{
|
||||
|
@ -717,11 +689,11 @@ void GLSectorStackPortal::SetupCoverage()
|
|||
for(int j=0;j<sub->portalcoverage[plane].sscount; j++)
|
||||
{
|
||||
subsector_t *dsub = &::level.subsectors[sub->portalcoverage[plane].subsectors[j]];
|
||||
drawer->CurrentMapSections.Set(dsub->mapsection);
|
||||
gl_drawinfo->ss_renderflags[dsub->Index()] |= SSRF_SEEN;
|
||||
di->CurrentMapSections.Set(dsub->mapsection);
|
||||
di->ss_renderflags[dsub->Index()] |= SSRF_SEEN;
|
||||
}
|
||||
}
|
||||
SetCoverage(::level.HeadNode());
|
||||
SetCoverage(di, ::level.HeadNode());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -729,7 +701,7 @@ void GLSectorStackPortal::SetupCoverage()
|
|||
// GLSectorStackPortal::DrawContents
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void GLSectorStackPortal::DrawContents()
|
||||
void GLSectorStackPortal::DrawContents(FDrawInfo *di)
|
||||
{
|
||||
FSectorPortalGroup *portal = origin;
|
||||
|
||||
|
@ -741,21 +713,19 @@ void GLSectorStackPortal::DrawContents()
|
|||
if (origin->plane != -1) screen->instack[origin->plane]++;
|
||||
|
||||
drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
|
||||
SaveMapSection();
|
||||
SetupCoverage();
|
||||
ClearClipper();
|
||||
SetupCoverage(di);
|
||||
ClearClipper(di);
|
||||
|
||||
// If the viewpoint is not within the portal, we need to invalidate the entire clip area.
|
||||
// The portal will re-validate the necessary parts when its subsectors get traversed.
|
||||
subsector_t *sub = R_PointInSubsector(r_viewpoint.Pos);
|
||||
if (!(gl_drawinfo->ss_renderflags[sub->Index()] & SSRF_SEEN))
|
||||
if (!(di->ss_renderflags[sub->Index()] & SSRF_SEEN))
|
||||
{
|
||||
drawer->clipper.SafeAddClipRange(0, ANGLE_MAX);
|
||||
drawer->clipper.SetBlocked(true);
|
||||
di->mClipper->SafeAddClipRange(0, ANGLE_MAX);
|
||||
di->mClipper->SetBlocked(true);
|
||||
}
|
||||
|
||||
drawer->DrawScene(DM_PORTAL);
|
||||
RestoreMapSection();
|
||||
drawer->DrawScene(di, DM_PORTAL);
|
||||
|
||||
if (origin->plane != -1) screen->instack[origin->plane]--;
|
||||
}
|
||||
|
@ -776,7 +746,7 @@ void GLSectorStackPortal::DrawContents()
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void GLPlaneMirrorPortal::DrawContents()
|
||||
void GLPlaneMirrorPortal::DrawContents(FDrawInfo *di)
|
||||
{
|
||||
if (renderdepth > r_mirror_recursions)
|
||||
{
|
||||
|
@ -798,10 +768,10 @@ void GLPlaneMirrorPortal::DrawContents()
|
|||
|
||||
PlaneMirrorFlag++;
|
||||
drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
|
||||
ClearClipper();
|
||||
ClearClipper(di);
|
||||
|
||||
gl_RenderState.SetClipHeight(planez, PlaneMirrorMode < 0 ? -1.f : 1.f);
|
||||
drawer->DrawScene(DM_PORTAL);
|
||||
drawer->DrawScene(di, DM_PORTAL);
|
||||
gl_RenderState.SetClipHeight(0.f, 0.f);
|
||||
PlaneMirrorFlag--;
|
||||
PlaneMirrorMode = old_pm;
|
||||
|
@ -897,7 +867,7 @@ int GLLinePortal::ClipPoint(const DVector2 &pos)
|
|||
// R_EnterMirror
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void GLMirrorPortal::DrawContents()
|
||||
void GLMirrorPortal::DrawContents(FDrawInfo *di)
|
||||
{
|
||||
if (renderdepth>r_mirror_recursions)
|
||||
{
|
||||
|
@ -905,7 +875,7 @@ void GLMirrorPortal::DrawContents()
|
|||
return;
|
||||
}
|
||||
|
||||
GLRenderer->mClipPortal = this;
|
||||
di->mClipPortal = this;
|
||||
DAngle StartAngle = r_viewpoint.Angles.Yaw;
|
||||
DVector3 StartPos = r_viewpoint.Pos;
|
||||
|
||||
|
@ -965,18 +935,18 @@ void GLMirrorPortal::DrawContents()
|
|||
MirrorFlag++;
|
||||
drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
|
||||
|
||||
drawer->clipper.Clear();
|
||||
di->mClipper->Clear();
|
||||
|
||||
angle_t af = drawer->FrustumAngle();
|
||||
if (af<ANGLE_180) drawer->clipper.SafeAddClipRangeRealAngles(r_viewpoint.Angles.Yaw.BAMs()+af, r_viewpoint.Angles.Yaw.BAMs()-af);
|
||||
if (af<ANGLE_180) di->mClipper->SafeAddClipRangeRealAngles(r_viewpoint.Angles.Yaw.BAMs()+af, r_viewpoint.Angles.Yaw.BAMs()-af);
|
||||
|
||||
angle_t a2 = linedef->v1->GetClipAngle();
|
||||
angle_t a1 = linedef->v2->GetClipAngle();
|
||||
drawer->clipper.SafeAddClipRange(a1,a2);
|
||||
di->mClipper->SafeAddClipRange(a1,a2);
|
||||
|
||||
gl_RenderState.SetClipLine(linedef);
|
||||
gl_RenderState.EnableClipLine(true);
|
||||
drawer->DrawScene(DM_PORTAL);
|
||||
drawer->DrawScene(di, DM_PORTAL);
|
||||
gl_RenderState.EnableClipLine(false);
|
||||
|
||||
MirrorFlag--;
|
||||
|
@ -997,7 +967,7 @@ void GLMirrorPortal::DrawContents()
|
|||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void GLLineToLinePortal::DrawContents()
|
||||
void GLLineToLinePortal::DrawContents(FDrawInfo *di)
|
||||
{
|
||||
// TODO: Handle recursion more intelligently
|
||||
if (renderdepth>r_mirror_recursions)
|
||||
|
@ -1006,7 +976,7 @@ void GLLineToLinePortal::DrawContents()
|
|||
return;
|
||||
}
|
||||
|
||||
GLRenderer->mClipPortal = this;
|
||||
di->mClipPortal = this;
|
||||
|
||||
line_t *origin = glport->lines[0]->mOrigin;
|
||||
P_TranslatePortalXY(origin, r_viewpoint.Pos.X, r_viewpoint.Pos.Y);
|
||||
|
@ -1031,8 +1001,6 @@ void GLLineToLinePortal::DrawContents()
|
|||
}
|
||||
|
||||
|
||||
SaveMapSection();
|
||||
|
||||
for (unsigned i = 0; i < lines.Size(); i++)
|
||||
{
|
||||
line_t *line = lines[i].seg->linedef->getPortalDestination();
|
||||
|
@ -1040,23 +1008,22 @@ void GLLineToLinePortal::DrawContents()
|
|||
if (line->sidedef[0]->Flags & WALLF_POLYOBJ)
|
||||
sub = R_PointInSubsector(line->v1->fixX(), line->v1->fixY());
|
||||
else sub = line->frontsector->subsectors[0];
|
||||
drawer->CurrentMapSections.Set(sub->mapsection);
|
||||
di->CurrentMapSections.Set(sub->mapsection);
|
||||
}
|
||||
|
||||
GLRenderer->mViewActor = nullptr;
|
||||
drawer->SetupView(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, r_viewpoint.Angles.Yaw, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
|
||||
|
||||
ClearClipper();
|
||||
ClearClipper(di);
|
||||
gl_RenderState.SetClipLine(glport->lines[0]->mDestination);
|
||||
gl_RenderState.EnableClipLine(true);
|
||||
drawer->DrawScene(DM_PORTAL);
|
||||
drawer->DrawScene(di, DM_PORTAL);
|
||||
gl_RenderState.EnableClipLine(false);
|
||||
RestoreMapSection();
|
||||
}
|
||||
|
||||
void GLLineToLinePortal::RenderAttached()
|
||||
void GLLineToLinePortal::RenderAttached(FDrawInfo *di)
|
||||
{
|
||||
gl_drawinfo->ProcessActorsInPortal(glport, gl_drawinfo->mDrawer->in_area);
|
||||
di->ProcessActorsInPortal(glport, di->in_area);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -1145,7 +1112,7 @@ GLHorizonPortal::GLHorizonPortal(GLHorizonInfo * pt, bool local)
|
|||
// GLHorizonPortal::DrawContents
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void GLHorizonPortal::DrawContents()
|
||||
void GLHorizonPortal::DrawContents(FDrawInfo *di)
|
||||
{
|
||||
Clocker c(PortalAll);
|
||||
|
||||
|
@ -1216,7 +1183,7 @@ void GLHorizonPortal::DrawContents()
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void GLEEHorizonPortal::DrawContents()
|
||||
void GLEEHorizonPortal::DrawContents(FDrawInfo *di)
|
||||
{
|
||||
sector_t *sector = portal->mOrigin;
|
||||
if (sector->GetTexture(sector_t::floor) == skyflatnum ||
|
||||
|
@ -1225,7 +1192,7 @@ void GLEEHorizonPortal::DrawContents()
|
|||
GLSkyInfo skyinfo;
|
||||
skyinfo.init(sector->sky, 0);
|
||||
GLSkyPortal sky(&skyinfo, true);
|
||||
sky.DrawContents();
|
||||
sky.DrawContents(di);
|
||||
}
|
||||
if (sector->GetTexture(sector_t::ceiling) != skyflatnum)
|
||||
{
|
||||
|
@ -1239,7 +1206,7 @@ void GLEEHorizonPortal::DrawContents()
|
|||
horz.plane.Texheight = r_viewpoint.Pos.Z + fabs(horz.plane.Texheight);
|
||||
}
|
||||
GLHorizonPortal ceil(&horz, true);
|
||||
ceil.DrawContents();
|
||||
ceil.DrawContents(di);
|
||||
}
|
||||
if (sector->GetTexture(sector_t::floor) != skyflatnum)
|
||||
{
|
||||
|
@ -1253,7 +1220,7 @@ void GLEEHorizonPortal::DrawContents()
|
|||
horz.plane.Texheight = r_viewpoint.Pos.Z - fabs(horz.plane.Texheight);
|
||||
}
|
||||
GLHorizonPortal floor(&horz, true);
|
||||
floor.DrawContents();
|
||||
floor.DrawContents(di);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1281,3 +1248,9 @@ const char *GLLineToLinePortal::GetName() { return "LineToLine"; }
|
|||
const char *GLHorizonPortal::GetName() { return "Horizon"; }
|
||||
const char *GLEEHorizonPortal::GetName() { return "EEHorizon"; }
|
||||
|
||||
// This needs to remain on the renderer side until the portal interface can be abstracted.
|
||||
void FSectorPortalGroup::AddSubsector(subsector_t *sub)
|
||||
{
|
||||
GLSectorStackPortal *glportal = GetRenderState();
|
||||
glportal->AddSubsector(sub);
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ extern UniqueList<secplane_t> UniquePlaneMirrors;
|
|||
struct GLEEHorizonPortal;
|
||||
class GLSceneDrawer;
|
||||
|
||||
class GLPortal
|
||||
class GLPortal : public IPortal
|
||||
{
|
||||
static TArray<GLPortal *> portals;
|
||||
static int recursion;
|
||||
|
@ -75,11 +75,8 @@ private:
|
|||
DRotator savedAngles;
|
||||
bool savedshowviewer;
|
||||
AActor * savedviewactor;
|
||||
area_t savedviewarea;
|
||||
ActorRenderFlags savedvisibility;
|
||||
GLPortal *PrevPortal;
|
||||
GLPortal *PrevClipPortal;
|
||||
BitArray SavedMapSection;
|
||||
TArray<unsigned int> mPrimIndices;
|
||||
|
||||
protected:
|
||||
|
@ -89,18 +86,16 @@ protected:
|
|||
GLPortal(bool local = false) { if (!local) portals.Push(this); }
|
||||
virtual ~GLPortal() { }
|
||||
|
||||
bool Start(bool usestencil, bool doquery);
|
||||
bool Start(bool usestencil, bool doquery, FDrawInfo **pDi);
|
||||
void End(bool usestencil);
|
||||
virtual void DrawContents()=0;
|
||||
virtual void DrawContents(FDrawInfo *di)=0;
|
||||
virtual void * GetSource() const =0; // GetSource MUST be implemented!
|
||||
void ClearClipper();
|
||||
void ClearClipper(FDrawInfo *di);
|
||||
virtual bool IsSky() { return false; }
|
||||
virtual bool NeedCap() { return true; }
|
||||
virtual bool NeedDepthBuffer() { return true; }
|
||||
void ClearScreen();
|
||||
virtual const char *GetName() = 0;
|
||||
void SaveMapSection();
|
||||
void RestoreMapSection();
|
||||
virtual void PushState() {}
|
||||
virtual void PopState() {}
|
||||
|
||||
|
@ -111,9 +106,10 @@ public:
|
|||
// Start may perform an occlusion query. If that returns 0 there
|
||||
// is no need to draw the stencil's contents and there's also no
|
||||
// need to restore the affected area becasue there is none!
|
||||
if (Start(usestencil, doquery))
|
||||
FDrawInfo *di;
|
||||
if (Start(usestencil, doquery, &di))
|
||||
{
|
||||
DrawContents();
|
||||
DrawContents(di);
|
||||
End(usestencil);
|
||||
}
|
||||
}
|
||||
|
@ -130,11 +126,7 @@ public:
|
|||
|
||||
static bool isMirrored() { return !!((MirrorFlag ^ PlaneMirrorFlag) & 1); }
|
||||
|
||||
virtual int ClipSeg(seg_t *seg) { return PClip_Inside; }
|
||||
virtual int ClipSubsector(subsector_t *sub) { return PClip_Inside; }
|
||||
virtual int ClipPoint(const DVector2 &pos) { return PClip_Inside; }
|
||||
virtual line_t *ClipLine() { return NULL; }
|
||||
virtual void RenderAttached() {}
|
||||
virtual void RenderAttached(FDrawInfo *di) {}
|
||||
|
||||
static void BeginScene();
|
||||
static void StartFrame();
|
||||
|
@ -205,7 +197,7 @@ struct GLMirrorPortal : public GLLinePortal
|
|||
line_t * linedef;
|
||||
|
||||
protected:
|
||||
virtual void DrawContents();
|
||||
virtual void DrawContents(FDrawInfo *di);
|
||||
virtual void * GetSource() const { return linedef; }
|
||||
virtual const char *GetName();
|
||||
|
||||
|
@ -223,11 +215,11 @@ struct GLLineToLinePortal : public GLLinePortal
|
|||
{
|
||||
FLinePortalSpan *glport;
|
||||
protected:
|
||||
virtual void DrawContents();
|
||||
virtual void DrawContents(FDrawInfo *di);
|
||||
virtual void * GetSource() const { return glport; }
|
||||
virtual const char *GetName();
|
||||
virtual line_t *ClipLine() { return line(); }
|
||||
virtual void RenderAttached();
|
||||
virtual void RenderAttached(FDrawInfo *di);
|
||||
|
||||
public:
|
||||
|
||||
|
@ -244,7 +236,7 @@ struct GLSkyboxPortal : public GLPortal
|
|||
FSectorPortal * portal;
|
||||
|
||||
protected:
|
||||
virtual void DrawContents();
|
||||
virtual void DrawContents(FDrawInfo *di);
|
||||
virtual void * GetSource() const { return portal; }
|
||||
virtual bool IsSky() { return true; }
|
||||
virtual const char *GetName();
|
||||
|
@ -266,7 +258,7 @@ struct GLSkyPortal : public GLPortal
|
|||
friend struct GLEEHorizonPortal;
|
||||
|
||||
protected:
|
||||
virtual void DrawContents();
|
||||
virtual void DrawContents(FDrawInfo *di);
|
||||
virtual void * GetSource() const { return origin; }
|
||||
virtual bool IsSky() { return true; }
|
||||
virtual bool NeedDepthBuffer() { return false; }
|
||||
|
@ -290,7 +282,7 @@ struct GLSectorStackPortal : public GLPortal
|
|||
TArray<subsector_t *> subsectors;
|
||||
protected:
|
||||
virtual ~GLSectorStackPortal();
|
||||
virtual void DrawContents();
|
||||
virtual void DrawContents(FDrawInfo *di);
|
||||
virtual void * GetSource() const { return origin; }
|
||||
virtual bool IsSky() { return true; } // although this isn't a real sky it can be handled as one.
|
||||
virtual const char *GetName();
|
||||
|
@ -302,7 +294,7 @@ public:
|
|||
{
|
||||
origin=pt;
|
||||
}
|
||||
void SetupCoverage();
|
||||
void SetupCoverage(FDrawInfo *di);
|
||||
void AddSubsector(subsector_t *sub)
|
||||
{
|
||||
subsectors.Push(sub);
|
||||
|
@ -313,7 +305,7 @@ public:
|
|||
struct GLPlaneMirrorPortal : public GLPortal
|
||||
{
|
||||
protected:
|
||||
virtual void DrawContents();
|
||||
virtual void DrawContents(FDrawInfo *di);
|
||||
virtual void * GetSource() const { return origin; }
|
||||
virtual const char *GetName();
|
||||
virtual void PushState();
|
||||
|
@ -338,7 +330,7 @@ struct GLHorizonPortal : public GLPortal
|
|||
friend struct GLEEHorizonPortal;
|
||||
|
||||
protected:
|
||||
virtual void DrawContents();
|
||||
virtual void DrawContents(FDrawInfo *di);
|
||||
virtual void * GetSource() const { return origin; }
|
||||
virtual bool NeedDepthBuffer() { return false; }
|
||||
virtual bool NeedCap() { return false; }
|
||||
|
@ -354,7 +346,7 @@ struct GLEEHorizonPortal : public GLPortal
|
|||
FSectorPortal * portal;
|
||||
|
||||
protected:
|
||||
virtual void DrawContents();
|
||||
virtual void DrawContents(FDrawInfo *di);
|
||||
virtual void * GetSource() const { return portal; }
|
||||
virtual bool NeedDepthBuffer() { return false; }
|
||||
virtual bool NeedCap() { return false; }
|
||||
|
|
|
@ -92,29 +92,6 @@ angle_t GLSceneDrawer::FrustumAngle()
|
|||
return a1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Sets the area the camera is in
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void GLSceneDrawer::SetViewArea()
|
||||
{
|
||||
// The render_sector is better suited to represent the current position in GL
|
||||
r_viewpoint.sector = R_PointInSubsector(r_viewpoint.Pos)->render_sector;
|
||||
|
||||
// Get the heightsec state from the render sector, not the current one!
|
||||
if (r_viewpoint.sector->GetHeightSec())
|
||||
{
|
||||
in_area = r_viewpoint.Pos.Z <= r_viewpoint.sector->heightsec->floorplane.ZatPoint(r_viewpoint.Pos) ? area_below :
|
||||
(r_viewpoint.Pos.Z > r_viewpoint.sector->heightsec->ceilingplane.ZatPoint(r_viewpoint.Pos) &&
|
||||
!(r_viewpoint.sector->heightsec->MoreFlags&SECMF_FAKEFLOORONLY)) ? area_above : area_normal;
|
||||
}
|
||||
else
|
||||
{
|
||||
in_area = level.HasHeightSecs? area_default : area_normal; // depends on exposed lower sectors, if map contains heightsecs.
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// resets the 3D viewport
|
||||
|
@ -234,10 +211,10 @@ void GLSceneDrawer::SetupView(float vx, float vy, float vz, DAngle va, bool mirr
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void GLSceneDrawer::CreateScene()
|
||||
void GLSceneDrawer::CreateScene(FDrawInfo *di)
|
||||
{
|
||||
angle_t a1 = FrustumAngle();
|
||||
InitClipper(r_viewpoint.Angles.Yaw.BAMs() + a1, r_viewpoint.Angles.Yaw.BAMs() - a1);
|
||||
di->mClipper->SafeAddClipRangeRealAngles(r_viewpoint.Angles.Yaw.BAMs() + a1, r_viewpoint.Angles.Yaw.BAMs() - a1);
|
||||
|
||||
// reset the portal manager
|
||||
GLPortal::StartFrame();
|
||||
|
@ -251,29 +228,31 @@ void GLSceneDrawer::CreateScene()
|
|||
GLRenderer->mVBO->Map();
|
||||
GLRenderer->mLights->Begin();
|
||||
|
||||
SetView();
|
||||
// Give the DrawInfo the viewpoint in fixed point because that's what the nodes are.
|
||||
di->viewx = FLOAT2FIXED(r_viewpoint.Pos.X);
|
||||
di->viewy = FLOAT2FIXED(r_viewpoint.Pos.Y);
|
||||
|
||||
validcount++; // used for processing sidedefs only once by the renderer.
|
||||
|
||||
di->mAngles = GLRenderer->mAngles;
|
||||
di->mViewVector = GLRenderer->mViewVector;
|
||||
di->mViewActor = GLRenderer->mViewActor;
|
||||
di->mShadowMap = &GLRenderer->mShadowMap;
|
||||
|
||||
gl_drawinfo->clipPortal = !!GLRenderer->mClipPortal;
|
||||
gl_drawinfo->mAngles = GLRenderer->mAngles;
|
||||
gl_drawinfo->mViewVector = GLRenderer->mViewVector;
|
||||
gl_drawinfo->mViewActor = GLRenderer->mViewActor;
|
||||
gl_drawinfo->mShadowMap = &GLRenderer->mShadowMap;
|
||||
|
||||
RenderBSPNode (level.HeadNode());
|
||||
gl_drawinfo->PreparePlayerSprites(r_viewpoint.sector, in_area);
|
||||
di->RenderBSPNode (level.HeadNode());
|
||||
di->PreparePlayerSprites(r_viewpoint.sector, di->in_area);
|
||||
|
||||
// Process all the sprites on the current portal's back side which touch the portal.
|
||||
if (GLRenderer->mCurrentPortal != NULL) GLRenderer->mCurrentPortal->RenderAttached();
|
||||
if (GLRenderer->mCurrentPortal != NULL) GLRenderer->mCurrentPortal->RenderAttached(di);
|
||||
Bsp.Unclock();
|
||||
|
||||
// And now the crappy hacks that have to be done to avoid rendering anomalies.
|
||||
// These cannot be multithreaded when the time comes because all these depend
|
||||
// on the global 'validcount' variable.
|
||||
|
||||
gl_drawinfo->HandleMissingTextures(in_area); // Missing upper/lower textures
|
||||
gl_drawinfo->HandleHackedSubsectors(); // open sector hacks for deep water
|
||||
gl_drawinfo->ProcessSectorStacks(in_area); // merge visplanes of sector stacks
|
||||
di->HandleMissingTextures(di->in_area); // Missing upper/lower textures
|
||||
di->HandleHackedSubsectors(); // open sector hacks for deep water
|
||||
di->ProcessSectorStacks(di->in_area); // merge visplanes of sector stacks
|
||||
GLRenderer->mLights->Finish();
|
||||
GLRenderer->mVBO->Unmap();
|
||||
|
||||
|
@ -289,7 +268,7 @@ void GLSceneDrawer::CreateScene()
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void GLSceneDrawer::RenderScene(int recursion)
|
||||
void GLSceneDrawer::RenderScene(FDrawInfo *di, int recursion)
|
||||
{
|
||||
RenderAll.Clock();
|
||||
|
||||
|
@ -303,11 +282,11 @@ void GLSceneDrawer::RenderScene(int recursion)
|
|||
|
||||
if (gl_sort_textures)
|
||||
{
|
||||
gl_drawinfo->drawlists[GLDL_PLAINWALLS].SortWalls();
|
||||
gl_drawinfo->drawlists[GLDL_PLAINFLATS].SortFlats();
|
||||
gl_drawinfo->drawlists[GLDL_MASKEDWALLS].SortWalls();
|
||||
gl_drawinfo->drawlists[GLDL_MASKEDFLATS].SortFlats();
|
||||
gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].SortWalls();
|
||||
di->drawlists[GLDL_PLAINWALLS].SortWalls();
|
||||
di->drawlists[GLDL_PLAINFLATS].SortFlats();
|
||||
di->drawlists[GLDL_MASKEDWALLS].SortWalls();
|
||||
di->drawlists[GLDL_MASKEDFLATS].SortFlats();
|
||||
di->drawlists[GLDL_MASKEDWALLSOFS].SortWalls();
|
||||
}
|
||||
|
||||
// if we don't have a persistently mapped buffer, we have to process all the dynamic lights up front,
|
||||
|
@ -315,10 +294,10 @@ void GLSceneDrawer::RenderScene(int recursion)
|
|||
if (gl.lightmethod == LM_DEFERRED && level.HasDynamicLights && FixedColormap == CM_DEFAULT)
|
||||
{
|
||||
GLRenderer->mLights->Begin();
|
||||
gl_drawinfo->drawlists[GLDL_PLAINFLATS].DrawFlats(gl_drawinfo, GLPASS_LIGHTSONLY);
|
||||
gl_drawinfo->drawlists[GLDL_MASKEDFLATS].DrawFlats(gl_drawinfo, GLPASS_LIGHTSONLY);
|
||||
gl_drawinfo->drawlists[GLDL_TRANSLUCENTBORDER].Draw(gl_drawinfo, GLPASS_LIGHTSONLY);
|
||||
gl_drawinfo->drawlists[GLDL_TRANSLUCENT].Draw(gl_drawinfo, GLPASS_LIGHTSONLY, true);
|
||||
di->drawlists[GLDL_PLAINFLATS].DrawFlats(di, GLPASS_LIGHTSONLY);
|
||||
di->drawlists[GLDL_MASKEDFLATS].DrawFlats(di, GLPASS_LIGHTSONLY);
|
||||
di->drawlists[GLDL_TRANSLUCENTBORDER].Draw(di, GLPASS_LIGHTSONLY);
|
||||
di->drawlists[GLDL_TRANSLUCENT].Draw(di, GLPASS_LIGHTSONLY, true);
|
||||
GLRenderer->mLights->Finish();
|
||||
}
|
||||
|
||||
|
@ -336,7 +315,7 @@ void GLSceneDrawer::RenderScene(int recursion)
|
|||
else // GL 2.x legacy mode
|
||||
{
|
||||
// process everything that needs to handle textured dynamic lights.
|
||||
if (level.HasDynamicLights) RenderMultipassStuff();
|
||||
if (level.HasDynamicLights) RenderMultipassStuff(di);
|
||||
|
||||
// The remaining lists which are unaffected by dynamic lights are just processed as normal.
|
||||
pass = GLPASS_ALL;
|
||||
|
@ -344,8 +323,8 @@ void GLSceneDrawer::RenderScene(int recursion)
|
|||
|
||||
gl_RenderState.EnableTexture(gl_texture);
|
||||
gl_RenderState.EnableBrightmap(true);
|
||||
gl_drawinfo->drawlists[GLDL_PLAINWALLS].DrawWalls(gl_drawinfo, pass);
|
||||
gl_drawinfo->drawlists[GLDL_PLAINFLATS].DrawFlats(gl_drawinfo, pass);
|
||||
di->drawlists[GLDL_PLAINWALLS].DrawWalls(di, pass);
|
||||
di->drawlists[GLDL_PLAINFLATS].DrawFlats(di, pass);
|
||||
|
||||
|
||||
// Part 2: masked geometry. This is set up so that only pixels with alpha>gl_mask_threshold will show
|
||||
|
@ -355,20 +334,20 @@ void GLSceneDrawer::RenderScene(int recursion)
|
|||
gl_RenderState.SetTextureMode(TM_MASK);
|
||||
}
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
|
||||
gl_drawinfo->drawlists[GLDL_MASKEDWALLS].DrawWalls(gl_drawinfo, pass);
|
||||
gl_drawinfo->drawlists[GLDL_MASKEDFLATS].DrawFlats(gl_drawinfo, pass);
|
||||
di->drawlists[GLDL_MASKEDWALLS].DrawWalls(di, pass);
|
||||
di->drawlists[GLDL_MASKEDFLATS].DrawFlats(di, pass);
|
||||
|
||||
// Part 3: masked geometry with polygon offset. This list is empty most of the time so only waste time on it when in use.
|
||||
if (gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].Size() > 0)
|
||||
if (di->drawlists[GLDL_MASKEDWALLSOFS].Size() > 0)
|
||||
{
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(-1.0f, -128.0f);
|
||||
gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].DrawWalls(gl_drawinfo, pass);
|
||||
di->drawlists[GLDL_MASKEDWALLSOFS].DrawWalls(di, pass);
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(0, 0);
|
||||
}
|
||||
|
||||
gl_drawinfo->drawlists[GLDL_MODELS].Draw(gl_drawinfo, pass);
|
||||
di->drawlists[GLDL_MODELS].Draw(di, pass);
|
||||
|
||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
|
@ -377,7 +356,7 @@ void GLSceneDrawer::RenderScene(int recursion)
|
|||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(-1.0f, -128.0f);
|
||||
glDepthMask(false);
|
||||
gl_drawinfo->DrawDecals();
|
||||
di->DrawDecals();
|
||||
|
||||
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||
|
||||
|
@ -395,7 +374,7 @@ void GLSceneDrawer::RenderScene(int recursion)
|
|||
gl_RenderState.EnableFog(true);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
gl_RenderState.BlendFunc(GL_ONE,GL_ZERO);
|
||||
gl_drawinfo->DrawUnhandledMissingTextures();
|
||||
di->DrawUnhandledMissingTextures();
|
||||
glDepthMask(true);
|
||||
|
||||
glPolygonOffset(0.0f, 0.0f);
|
||||
|
@ -412,7 +391,7 @@ void GLSceneDrawer::RenderScene(int recursion)
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void GLSceneDrawer::RenderTranslucent()
|
||||
void GLSceneDrawer::RenderTranslucent(FDrawInfo *di)
|
||||
{
|
||||
RenderAll.Clock();
|
||||
|
||||
|
@ -424,8 +403,8 @@ void GLSceneDrawer::RenderTranslucent()
|
|||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
gl_RenderState.EnableBrightmap(true);
|
||||
gl_drawinfo->drawlists[GLDL_TRANSLUCENTBORDER].Draw(gl_drawinfo, GLPASS_TRANSLUCENT);
|
||||
gl_drawinfo->DrawSorted(GLDL_TRANSLUCENT);
|
||||
di->drawlists[GLDL_TRANSLUCENTBORDER].Draw(di, GLPASS_TRANSLUCENT);
|
||||
di->DrawSorted(GLDL_TRANSLUCENT);
|
||||
gl_RenderState.EnableBrightmap(false);
|
||||
|
||||
|
||||
|
@ -445,7 +424,7 @@ void GLSceneDrawer::RenderTranslucent()
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void GLSceneDrawer::DrawScene(int drawmode)
|
||||
void GLSceneDrawer::DrawScene(FDrawInfo *di, int drawmode)
|
||||
{
|
||||
static int recursion=0;
|
||||
static int ssao_portals_available = 0;
|
||||
|
@ -469,16 +448,15 @@ void GLSceneDrawer::DrawScene(int drawmode)
|
|||
if (r_viewpoint.camera != nullptr)
|
||||
{
|
||||
ActorRenderFlags savedflags = r_viewpoint.camera->renderflags;
|
||||
CreateScene();
|
||||
CreateScene(di);
|
||||
r_viewpoint.camera->renderflags = savedflags;
|
||||
}
|
||||
else
|
||||
{
|
||||
CreateScene();
|
||||
CreateScene(di);
|
||||
}
|
||||
GLRenderer->mClipPortal = NULL; // this must be reset before any portal recursion takes place.
|
||||
|
||||
RenderScene(recursion);
|
||||
RenderScene(di, recursion);
|
||||
|
||||
if (applySSAO && gl_RenderState.GetPassType() == GBUFFER_PASS)
|
||||
{
|
||||
|
@ -495,7 +473,7 @@ void GLSceneDrawer::DrawScene(int drawmode)
|
|||
recursion++;
|
||||
GLPortal::EndFrame();
|
||||
recursion--;
|
||||
RenderTranslucent();
|
||||
RenderTranslucent(di);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -505,17 +483,17 @@ void GLSceneDrawer::DrawScene(int drawmode)
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void GLSceneDrawer::EndDrawScene(sector_t * viewsector)
|
||||
void GLSceneDrawer::EndDrawScene(FDrawInfo *di, sector_t * viewsector)
|
||||
{
|
||||
gl_RenderState.EnableFog(false);
|
||||
|
||||
// [BB] HUD models need to be rendered here.
|
||||
const bool renderHUDModel = gl_IsHUDModelForPlayerAvailable( players[consoleplayer].camera->player );
|
||||
const bool renderHUDModel = IsHUDModelForPlayerAvailable( players[consoleplayer].camera->player );
|
||||
if ( renderHUDModel )
|
||||
{
|
||||
// [BB] The HUD model should be drawn over everything else already drawn.
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
gl_drawinfo->DrawPlayerSprites(true);
|
||||
di->DrawPlayerSprites(true);
|
||||
}
|
||||
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
|
@ -525,7 +503,7 @@ void GLSceneDrawer::EndDrawScene(sector_t * viewsector)
|
|||
// Delay drawing psprites until after bloom has been applied, if enabled.
|
||||
if (!FGLRenderBuffers::IsEnabled() || !gl_bloom || FixedColormap != CM_DEFAULT)
|
||||
{
|
||||
DrawEndScene2D(viewsector);
|
||||
DrawEndScene2D(di, viewsector);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -537,9 +515,9 @@ void GLSceneDrawer::EndDrawScene(sector_t * viewsector)
|
|||
}
|
||||
}
|
||||
|
||||
void GLSceneDrawer::DrawEndScene2D(sector_t * viewsector)
|
||||
void GLSceneDrawer::DrawEndScene2D(FDrawInfo *di, sector_t * viewsector)
|
||||
{
|
||||
const bool renderHUDModel = gl_IsHUDModelForPlayerAvailable(players[consoleplayer].camera->player);
|
||||
const bool renderHUDModel = IsHUDModelForPlayerAvailable(players[consoleplayer].camera->player);
|
||||
|
||||
// This should be removed once all 2D stuff is really done through the 2D interface.
|
||||
gl_RenderState.mViewMatrix.loadIdentity();
|
||||
|
@ -549,7 +527,7 @@ void GLSceneDrawer::DrawEndScene2D(sector_t * viewsector)
|
|||
glDisable(GL_MULTISAMPLE);
|
||||
|
||||
|
||||
gl_drawinfo->DrawPlayerSprites(false);
|
||||
di->DrawPlayerSprites(false);
|
||||
|
||||
if (gl.legacyMode)
|
||||
{
|
||||
|
@ -572,16 +550,15 @@ void GLSceneDrawer::DrawEndScene2D(sector_t * viewsector)
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void GLSceneDrawer::ProcessScene(bool toscreen)
|
||||
void GLSceneDrawer::ProcessScene(FDrawInfo *di, bool toscreen)
|
||||
{
|
||||
iter_dlightf = iter_dlight = draw_dlight = draw_dlightf = 0;
|
||||
GLPortal::BeginScene();
|
||||
|
||||
int mapsection = R_PointInSubsector(r_viewpoint.Pos)->mapsection;
|
||||
CurrentMapSections.Resize(level.NumMapSections);
|
||||
CurrentMapSections.Zero();
|
||||
CurrentMapSections.Set(mapsection);
|
||||
DrawScene(toscreen ? DM_MAINVIEW : DM_OFFSCREEN);
|
||||
di->CurrentMapSections.Set(mapsection);
|
||||
GLRenderer->mCurrentPortal = nullptr;
|
||||
DrawScene(di, toscreen ? DM_MAINVIEW : DM_OFFSCREEN);
|
||||
|
||||
}
|
||||
|
||||
|
@ -644,7 +621,6 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, IntRect * bounds, fl
|
|||
GLRenderer->mSceneClearColor[1] = 0.0f;
|
||||
GLRenderer->mSceneClearColor[2] = 0.0f;
|
||||
R_SetupFrame (r_viewpoint, r_viewwindow, camera);
|
||||
SetViewArea();
|
||||
|
||||
GLRenderer->mGlobVis = R_GetGlobVis(r_viewwindow, r_visibility);
|
||||
|
||||
|
@ -684,6 +660,10 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, IntRect * bounds, fl
|
|||
Set3DViewport(mainview);
|
||||
GLRenderer->mDrawingScene2D = true;
|
||||
GLRenderer->mCurrentFoV = fov;
|
||||
|
||||
FDrawInfo *di = FDrawInfo::StartDrawInfo(this);
|
||||
di->SetViewArea();
|
||||
|
||||
// Stereo mode specific perspective projection
|
||||
SetProjection( eye->GetProjection(fov, ratio, fovratio) );
|
||||
// SetProjection(fov, ratio, fovratio); // switch to perspective mode and set up clipper
|
||||
|
@ -694,13 +674,12 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, IntRect * bounds, fl
|
|||
SetViewMatrix(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z, false, false);
|
||||
gl_RenderState.ApplyMatrices();
|
||||
|
||||
FDrawInfo::StartDrawInfo(this);
|
||||
ProcessScene(toscreen);
|
||||
if (mainview && toscreen) EndDrawScene(lviewsector); // do not call this for camera textures.
|
||||
ProcessScene(di, toscreen);
|
||||
if (mainview && toscreen) EndDrawScene(di, lviewsector); // do not call this for camera textures.
|
||||
|
||||
if (mainview && FGLRenderBuffers::IsEnabled())
|
||||
{
|
||||
GLRenderer->PostProcessScene(FixedColormap, [&]() { if (gl_bloom && FixedColormap == CM_DEFAULT) DrawEndScene2D(lviewsector); });
|
||||
GLRenderer->PostProcessScene(FixedColormap, [&]() { if (gl_bloom && FixedColormap == CM_DEFAULT) DrawEndScene2D(di, lviewsector); });
|
||||
|
||||
// This should be done after postprocessing, not before.
|
||||
GLRenderer->mBuffers->BindCurrentFB();
|
||||
|
|
|
@ -13,30 +13,14 @@ struct HUDSprite;
|
|||
|
||||
class GLSceneDrawer
|
||||
{
|
||||
fixed_t viewx, viewy; // since the nodes are still fixed point, keeping the view position also fixed point for node traversal is faster.
|
||||
|
||||
subsector_t *currentsubsector; // used by the line processing code.
|
||||
sector_t *currentsector;
|
||||
|
||||
TMap<DPSprite*, int> weapondynlightindex;
|
||||
|
||||
void RenderMultipassStuff();
|
||||
void RenderMultipassStuff(FDrawInfo *di);
|
||||
|
||||
void UnclipSubsector(subsector_t *sub);
|
||||
void AddLine (seg_t *seg, bool portalclip);
|
||||
void PolySubsector(subsector_t * sub);
|
||||
void RenderPolyBSPNode (void *node);
|
||||
void AddPolyobjs(subsector_t *sub);
|
||||
void AddLines(subsector_t * sub, sector_t * sector);
|
||||
void AddSpecialPortalLines(subsector_t * sub, sector_t * sector, line_t *line);
|
||||
void RenderThings(subsector_t * sub, sector_t * sector);
|
||||
void DoSubsector(subsector_t * sub);
|
||||
void RenderBSPNode(void *node);
|
||||
void RenderScene(FDrawInfo *di, int recursion);
|
||||
void RenderTranslucent(FDrawInfo *di);
|
||||
|
||||
void RenderScene(int recursion);
|
||||
void RenderTranslucent();
|
||||
|
||||
void CreateScene();
|
||||
void CreateScene(FDrawInfo *di);
|
||||
|
||||
public:
|
||||
GLSceneDrawer()
|
||||
|
@ -44,10 +28,7 @@ public:
|
|||
GLPortal::drawer = this;
|
||||
}
|
||||
|
||||
Clipper clipper;
|
||||
int FixedColormap;
|
||||
area_t in_area;
|
||||
BitArray CurrentMapSections; // this cannot be a single number, because a group of portals with the same displacement may link different sections.
|
||||
|
||||
angle_t FrustumAngle();
|
||||
void SetViewMatrix(float vx, float vy, float vz, bool mirror, bool planemirror);
|
||||
|
@ -58,27 +39,15 @@ public:
|
|||
void Set3DViewport(bool mainview);
|
||||
void Reset3DViewport();
|
||||
void SetFixedColormap(player_t *player);
|
||||
void DrawScene(int drawmode);
|
||||
void ProcessScene(bool toscreen = false);
|
||||
void EndDrawScene(sector_t * viewsector);
|
||||
void DrawEndScene2D(sector_t * viewsector);
|
||||
void DrawScene(FDrawInfo *di, int drawmode);
|
||||
void ProcessScene(FDrawInfo *di, bool toscreen = false);
|
||||
void EndDrawScene(FDrawInfo *di, sector_t * viewsector);
|
||||
void DrawEndScene2D(FDrawInfo *di, sector_t * viewsector);
|
||||
|
||||
sector_t *RenderViewpoint(AActor * camera, IntRect * bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen);
|
||||
sector_t *RenderView(player_t *player);
|
||||
void WriteSavePic(player_t *player, FileWriter *file, int width, int height);
|
||||
|
||||
void InitClipper(angle_t a1, angle_t a2)
|
||||
{
|
||||
clipper.Clear();
|
||||
clipper.SafeAddClipRangeRealAngles(a1, a2);
|
||||
}
|
||||
|
||||
void SetView()
|
||||
{
|
||||
viewx = FLOAT2FIXED(r_viewpoint.Pos.X);
|
||||
viewy = FLOAT2FIXED(r_viewpoint.Pos.Y);
|
||||
}
|
||||
|
||||
void SetColor(int light, int rellight, const FColormap &cm, float alpha, bool weapon = false)
|
||||
{
|
||||
gl_SetColor(light, rellight, FixedColormap != CM_DEFAULT, cm, alpha, weapon);
|
||||
|
|
|
@ -271,7 +271,7 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool
|
|||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void GLSkyPortal::DrawContents()
|
||||
void GLSkyPortal::DrawContents(FDrawInfo *di)
|
||||
{
|
||||
bool drawBoth = false;
|
||||
|
||||
|
|
|
@ -327,7 +327,7 @@ void FDrawInfo::AddSprite(GLSprite *sprite, bool translucent)
|
|||
list = GLDL_MODELS;
|
||||
}
|
||||
|
||||
auto newsprt = gl_drawinfo->drawlists[list].NewSprite();
|
||||
auto newsprt = drawlists[list].NewSprite();
|
||||
*newsprt = *sprite;
|
||||
}
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@ void FDrawInfo::RenderMirrorSurface(GLWall *wall)
|
|||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(-1.0f, -128.0f);
|
||||
glDepthMask(false);
|
||||
gl_drawinfo->DrawDecalsForMirror(wall);
|
||||
DrawDecalsForMirror(wall);
|
||||
glDepthMask(true);
|
||||
glPolygonOffset(0.0f, 0.0f);
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
|
@ -293,7 +293,7 @@ void FDrawInfo::DrawWall(GLWall *wall, int pass)
|
|||
case GLPASS_LIGHTTEX:
|
||||
case GLPASS_LIGHTTEX_ADDITIVE:
|
||||
case GLPASS_LIGHTTEX_FOGGY:
|
||||
gl_drawinfo->RenderLightsCompat(wall, pass);
|
||||
RenderLightsCompat(wall, pass);
|
||||
break;
|
||||
|
||||
case GLPASS_TEXONLY:
|
||||
|
@ -426,7 +426,7 @@ void FDrawInfo::AddPortal(GLWall *wall, int ptype)
|
|||
line_t *otherside = wall->lineportal->lines[0]->mDestination;
|
||||
if (otherside != NULL && otherside->portalindex < level.linePortals.Size())
|
||||
{
|
||||
ProcessActorsInPortal(otherside->getPortal()->mGroup, mDrawer->in_area);
|
||||
ProcessActorsInPortal(otherside->getPortal()->mGroup, in_area);
|
||||
}
|
||||
portal = new GLLineToLinePortal(wall->lineportal);
|
||||
}
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
#include "gl/stereo3d/gl_interleaved3d.h"
|
||||
#include "version.h"
|
||||
|
||||
EXTERN_CVAR(Bool, vr_enable_quadbuffered)
|
||||
|
||||
// Set up 3D-specific console variables:
|
||||
CVAR(Int, vr_mode, 0, CVAR_GLOBALCONFIG)
|
||||
|
||||
|
|
|
@ -470,16 +470,16 @@ void OpenGLFrameBuffer::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch,
|
|||
int sx = u * viewport.width;
|
||||
int sy = v * viewport.height;
|
||||
int sindex = (sx + sy * viewport.width) * 3;
|
||||
int dindex = (x + y * w) * 3;
|
||||
int dindex = (x + (h - y - 1) * w) * 3;
|
||||
ScreenshotBuffer[dindex] = pixels[sindex];
|
||||
ScreenshotBuffer[dindex + 1] = pixels[sindex + 1];
|
||||
ScreenshotBuffer[dindex + 2] = pixels[sindex + 2];
|
||||
}
|
||||
}
|
||||
|
||||
pitch = -w*3;
|
||||
pitch = w * 3;
|
||||
color_type = SS_RGB;
|
||||
buffer = ScreenshotBuffer + w * 3 * (h - 1);
|
||||
buffer = ScreenshotBuffer;
|
||||
|
||||
// Screenshot should not use gamma correction if it was already applied to rendered image
|
||||
EXTERN_CVAR(Bool, fullscreen);
|
||||
|
|
|
@ -64,7 +64,6 @@ public:
|
|||
bool HWGammaActive = false; // Are we using hardware or software gamma?
|
||||
std::shared_ptr<FGLDebug> mDebug; // Debug API
|
||||
private:
|
||||
uint8_t *ScreenshotBuffer; // What the name says. This must be maintained because the software renderer can return a locked canvas surface which the caller cannot release.
|
||||
int camtexcount = 0;
|
||||
|
||||
class Wiper
|
||||
|
|
|
@ -238,7 +238,12 @@ void gl_LoadExtensions()
|
|||
// Intel's GLSL compiler is a bit broken with extensions, so unlock the feature only if not on Intel or having GL 4.3.
|
||||
if (strstr(gl.vendorstring, "Intel") == NULL || gl_version >= 4.3f)
|
||||
{
|
||||
gl.flags |= RFL_SHADER_STORAGE_BUFFER;
|
||||
// Mesa implements shader storage only for fragment shaders.
|
||||
// Just disable the feature there. The light buffer may just use a uniform buffer without any adverse effects.
|
||||
int v;
|
||||
glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &v);
|
||||
if (v > 0)
|
||||
gl.flags |= RFL_SHADER_STORAGE_BUFFER;
|
||||
}
|
||||
}
|
||||
gl.flags |= RFL_BUFFER_STORAGE;
|
||||
|
|
|
@ -118,13 +118,22 @@ static F3DFloor *Find3DFloor(sector_t *target, sector_t *model)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
int FFlatVertexGenerator::CreateSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor)
|
||||
int FFlatVertexGenerator::CreateIndexedSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor, int vi, FFlatVertexGenerator::FIndexGenerationInfo &gen)
|
||||
{
|
||||
int idx = vbo_shadowdata.Reserve(sub->numlines);
|
||||
for(unsigned int k=0; k<sub->numlines; k++, idx++)
|
||||
if (sub->numlines < 3) return -1;
|
||||
|
||||
int idx = ibo_data.Reserve((sub->numlines - 2) * 3);
|
||||
int idxc = idx;
|
||||
int firstndx = gen.GetIndex(sub->firstline[0].v1);
|
||||
int secondndx = gen.GetIndex(sub->firstline[1].v1);
|
||||
for (unsigned int k = 2; k<sub->numlines; k++)
|
||||
{
|
||||
vbo_shadowdata[idx].SetFlatVertex(sub->firstline[k].v1, plane);
|
||||
if (sub->sector->transdoor && floor) vbo_shadowdata[idx].z -= 1.f;
|
||||
auto ndx = gen.GetIndex(sub->firstline[k].v1);
|
||||
|
||||
ibo_data[idx++] = vi + firstndx;
|
||||
ibo_data[idx++] = vi + secondndx;
|
||||
ibo_data[idx++] = vi + ndx;
|
||||
secondndx = ndx;
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
@ -135,15 +144,28 @@ int FFlatVertexGenerator::CreateSubsectorVertices(subsector_t *sub, const secpla
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
int FFlatVertexGenerator::CreateSectorVertices(sector_t *sec, const secplane_t &plane, int floor)
|
||||
int FFlatVertexGenerator::CreateIndexedSectorVertices(sector_t *sec, const secplane_t &plane, int floor, FFlatVertexGenerator::FIndexGenerationInfo &gen)
|
||||
{
|
||||
int rt = vbo_shadowdata.Size();
|
||||
// First calculate the vertices for the sector itself
|
||||
for(int j=0; j<sec->subsectorcount; j++)
|
||||
int rt = ibo_data.Size();
|
||||
int vi = vbo_shadowdata.Reserve(gen.vertices.Size());
|
||||
float diff;
|
||||
|
||||
// Create the actual vertices.
|
||||
if (sec->transdoor && floor) diff = -1.f;
|
||||
else diff = 0.f;
|
||||
for (unsigned i = 0; i < gen.vertices.Size(); i++)
|
||||
{
|
||||
vbo_shadowdata[vi + i].SetFlatVertex(gen.vertices[i], plane);
|
||||
vbo_shadowdata[vi + i].z += diff;
|
||||
}
|
||||
|
||||
// Create the indices for the subsectors
|
||||
for (int j = 0; j<sec->subsectorcount; j++)
|
||||
{
|
||||
subsector_t *sub = sec->subsectors[j];
|
||||
CreateSubsectorVertices(sub, plane, floor);
|
||||
CreateIndexedSubsectorVertices(sub, plane, floor, vi, gen);
|
||||
}
|
||||
sec->ibocount = ibo_data.Size() - rt;
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
@ -153,23 +175,24 @@ int FFlatVertexGenerator::CreateSectorVertices(sector_t *sec, const secplane_t &
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
int FFlatVertexGenerator::CreateVertices(int h, sector_t *sec, const secplane_t &plane, int floor)
|
||||
int FFlatVertexGenerator::CreateIndexedVertices(int h, sector_t *sec, const secplane_t &plane, int floor, TArray<FFlatVertexGenerator::FIndexGenerationInfo> &gen)
|
||||
{
|
||||
sec->vboindex[h] = vbo_shadowdata.Size();
|
||||
// First calculate the vertices for the sector itself
|
||||
sec->vboheight[h] = sec->GetPlaneTexZ(h);
|
||||
sec->vboindex[h] = CreateSectorVertices(sec, plane, floor);
|
||||
sec->iboindex[h] = CreateIndexedSectorVertices(sec, plane, floor, gen[sec->Index()]);
|
||||
|
||||
// Next are all sectors using this one as heightsec
|
||||
TArray<sector_t *> &fakes = sec->e->FakeFloor.Sectors;
|
||||
for (unsigned g=0; g<fakes.Size(); g++)
|
||||
for (unsigned g = 0; g < fakes.Size(); g++)
|
||||
{
|
||||
sector_t *fsec = fakes[g];
|
||||
fsec->vboindex[2+h] = CreateSectorVertices(fsec, plane, false);
|
||||
fsec->iboindex[2 + h] = CreateIndexedSectorVertices(fsec, plane, false, gen[fsec->Index()]);
|
||||
}
|
||||
|
||||
// and finally all attached 3D floors
|
||||
TArray<sector_t *> &xf = sec->e->XFloor.attached;
|
||||
for (unsigned g=0; g<xf.Size(); g++)
|
||||
for (unsigned g = 0; g < xf.Size(); g++)
|
||||
{
|
||||
sector_t *fsec = xf[g];
|
||||
F3DFloor *ffloor = Find3DFloor(fsec, sec);
|
||||
|
@ -181,15 +204,14 @@ int FFlatVertexGenerator::CreateVertices(int h, sector_t *sec, const secplane_t
|
|||
|
||||
if (dotop || dobottom)
|
||||
{
|
||||
if (dotop) ffloor->top.vindex = vbo_shadowdata.Size();
|
||||
if (dobottom) ffloor->bottom.vindex = vbo_shadowdata.Size();
|
||||
|
||||
CreateSectorVertices(fsec, plane, false);
|
||||
auto ndx = CreateIndexedSectorVertices(fsec, plane, false, gen[fsec->Index()]);
|
||||
if (dotop) ffloor->top.vindex = ndx;
|
||||
if (dobottom) ffloor->bottom.vindex = ndx;
|
||||
}
|
||||
}
|
||||
}
|
||||
sec->vbocount[h] = vbo_shadowdata.Size() - sec->vboindex[h];
|
||||
return sec->vboindex[h];
|
||||
return sec->iboindex[h];
|
||||
}
|
||||
|
||||
|
||||
|
@ -199,13 +221,28 @@ int FFlatVertexGenerator::CreateVertices(int h, sector_t *sec, const secplane_t
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FFlatVertexGenerator::CreateFlatVertices()
|
||||
void FFlatVertexGenerator::CreateIndexedFlatVertices()
|
||||
{
|
||||
TArray<FIndexGenerationInfo> gen;
|
||||
gen.Resize(level.sectors.Size());
|
||||
// This must be generated up front so that the following code knows how many vertices a sector contains.
|
||||
for (unsigned i = 0; i < level.sectors.Size(); i++)
|
||||
{
|
||||
for (int j = 0; j < level.sectors[i].subsectorcount; j++)
|
||||
{
|
||||
auto sub = level.sectors[i].subsectors[j];
|
||||
for (unsigned k = 0; k < sub->numlines; k++)
|
||||
{
|
||||
auto vert = sub->firstline[k].v1;
|
||||
gen[i].AddVertex(vert);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int h = sector_t::floor; h <= sector_t::ceiling; h++)
|
||||
{
|
||||
for(auto &sec : level.sectors)
|
||||
for (auto &sec : level.sectors)
|
||||
{
|
||||
CreateVertices(h, &sec, sec.GetSecPlane(h), h == sector_t::floor);
|
||||
CreateIndexedVertices(h, &sec, sec.GetSecPlane(h), h == sector_t::floor, gen);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -213,15 +250,15 @@ void FFlatVertexGenerator::CreateFlatVertices()
|
|||
// No new vertices are needed here. The planes come from the actual sector
|
||||
for (auto &sec : level.sectors)
|
||||
{
|
||||
for(auto ff : sec.e->XFloor.ffloors)
|
||||
for (auto ff : sec.e->XFloor.ffloors)
|
||||
{
|
||||
if (ff->top.model == &sec)
|
||||
{
|
||||
ff->top.vindex = sec.vboindex[ff->top.isceiling];
|
||||
ff->top.vindex = sec.iboindex[ff->top.isceiling];
|
||||
}
|
||||
if (ff->bottom.model == &sec)
|
||||
{
|
||||
ff->bottom.vindex = sec.vboindex[ff->top.isceiling];
|
||||
ff->bottom.vindex = sec.iboindex[ff->top.isceiling];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -233,13 +270,13 @@ void FFlatVertexGenerator::CreateFlatVertices()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FFlatVertexGenerator::UpdatePlaneVertices(sector_t *sec, int plane, FFlatVertex *map)
|
||||
void FFlatVertexGenerator::UpdatePlaneVertices(sector_t *sec, int plane)
|
||||
{
|
||||
int startvt = sec->vboindex[plane];
|
||||
int countvt = sec->vbocount[plane];
|
||||
secplane_t &splane = sec->GetSecPlane(plane);
|
||||
FFlatVertex *vt = &vbo_shadowdata[startvt];
|
||||
FFlatVertex *mapvt = &map[startvt];
|
||||
FFlatVertex *mapvt = &mMap[startvt];
|
||||
for(int i=0; i<countvt; i++, vt++, mapvt++)
|
||||
{
|
||||
vt->z = (float)splane.ZatPoint(vt->x, vt->y);
|
||||
|
@ -257,7 +294,7 @@ void FFlatVertexGenerator::UpdatePlaneVertices(sector_t *sec, int plane, FFlatVe
|
|||
void FFlatVertexGenerator::CreateVertices()
|
||||
{
|
||||
vbo_shadowdata.Resize(NUM_RESERVED);
|
||||
CreateFlatVertices();
|
||||
CreateIndexedFlatVertices();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -266,16 +303,16 @@ void FFlatVertexGenerator::CreateVertices()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FFlatVertexGenerator::CheckPlanes(sector_t *sector, FFlatVertex *map)
|
||||
void FFlatVertexGenerator::CheckPlanes(sector_t *sector)
|
||||
{
|
||||
if (sector->GetPlaneTexZ(sector_t::ceiling) != sector->vboheight[sector_t::ceiling])
|
||||
{
|
||||
UpdatePlaneVertices(sector, sector_t::ceiling, map);
|
||||
UpdatePlaneVertices(sector, sector_t::ceiling);
|
||||
sector->vboheight[sector_t::ceiling] = sector->GetPlaneTexZ(sector_t::ceiling);
|
||||
}
|
||||
if (sector->GetPlaneTexZ(sector_t::floor) != sector->vboheight[sector_t::floor])
|
||||
{
|
||||
UpdatePlaneVertices(sector, sector_t::floor, map);
|
||||
UpdatePlaneVertices(sector, sector_t::floor);
|
||||
sector->vboheight[sector_t::floor] = sector->GetPlaneTexZ(sector_t::floor);
|
||||
}
|
||||
}
|
||||
|
@ -287,11 +324,11 @@ void FFlatVertexGenerator::CheckPlanes(sector_t *sector, FFlatVertex *map)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FFlatVertexGenerator::CheckUpdate(sector_t *sector, FFlatVertex *map)
|
||||
void FFlatVertexGenerator::CheckUpdate(sector_t *sector)
|
||||
{
|
||||
CheckPlanes(sector, map);
|
||||
CheckPlanes(sector);
|
||||
sector_t *hs = sector->GetHeightSec();
|
||||
if (hs != NULL) CheckPlanes(hs, map);
|
||||
if (hs != NULL) CheckPlanes(hs);
|
||||
for (unsigned i = 0; i < sector->e->XFloor.ffloors.Size(); i++)
|
||||
CheckPlanes(sector->e->XFloor.ffloors[i]->model, map);
|
||||
CheckPlanes(sector->e->XFloor.ffloors[i]->model);
|
||||
}
|
||||
|
|
|
@ -45,9 +45,32 @@ class FFlatVertexGenerator
|
|||
{
|
||||
protected:
|
||||
TArray<FFlatVertex> vbo_shadowdata;
|
||||
TArray<uint32_t> ibo_data;
|
||||
FFlatVertex *mMap;
|
||||
|
||||
// Temporary data for creating an indexed buffer
|
||||
struct FIndexGenerationInfo
|
||||
{
|
||||
TArray<vertex_t *> vertices;
|
||||
TMap<vertex_t*, uint32_t> vertexmap;
|
||||
|
||||
uint32_t AddVertex(vertex_t *vert)
|
||||
{
|
||||
auto check = vertexmap.CheckKey(vert);
|
||||
if (check != nullptr) return *check;
|
||||
auto index = vertices.Push(vert);
|
||||
vertexmap[vert] = index;
|
||||
return index;
|
||||
}
|
||||
|
||||
uint32_t GetIndex(vertex_t *vert)
|
||||
{
|
||||
auto check = vertexmap.CheckKey(vert);
|
||||
if (check != nullptr) return *check;
|
||||
return ~0;
|
||||
}
|
||||
};
|
||||
|
||||
void CheckPlanes(sector_t *sector);
|
||||
|
||||
public:
|
||||
enum
|
||||
|
@ -66,16 +89,17 @@ public:
|
|||
void OutputResized(int width, int height);
|
||||
|
||||
private:
|
||||
int CreateSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor);
|
||||
int CreateSectorVertices(sector_t *sec, const secplane_t &plane, int floor);
|
||||
int CreateVertices(int h, sector_t *sec, const secplane_t &plane, int floor);
|
||||
void CreateFlatVertices();
|
||||
void UpdatePlaneVertices(sector_t *sec, int plane, FFlatVertex *map);
|
||||
int CreateIndexedSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor, int vi, FIndexGenerationInfo &gen);
|
||||
int CreateIndexedSectorVertices(sector_t *sec, const secplane_t &plane, int floor, FIndexGenerationInfo &gen);
|
||||
int CreateIndexedVertices(int h, sector_t *sec, const secplane_t &plane, int floor, TArray<FIndexGenerationInfo> &gen);
|
||||
void CreateIndexedFlatVertices();
|
||||
|
||||
void UpdatePlaneVertices(sector_t *sec, int plane);
|
||||
protected:
|
||||
void CreateVertices();
|
||||
void CheckPlanes(sector_t *sector, FFlatVertex *map);
|
||||
void CheckUpdate(sector_t *sector, FFlatVertex *map);
|
||||
|
||||
void CheckPlanes(sector_t *sector);
|
||||
public:
|
||||
void CheckUpdate(sector_t *sector);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -31,10 +31,14 @@
|
|||
#include "g_levellocals.h"
|
||||
#include "p_effect.h"
|
||||
#include "po_man.h"
|
||||
#include "hwrenderer/scene/hw_fakeflat.h"
|
||||
#include "hwrenderer/scene/hw_clipper.h"
|
||||
#include "hwrenderer/scene/hw_drawstructs.h"
|
||||
#include "hwrenderer/scene/hw_drawinfo.h"
|
||||
#include "hwrenderer/scene/hw_portal.h"
|
||||
#include "hwrenderer/utility/hw_clock.h"
|
||||
#include "hwrenderer/data/flatvertices.h"
|
||||
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "gl/scene/gl_scenedrawer.h"
|
||||
|
||||
EXTERN_CVAR(Bool, gl_render_segs)
|
||||
|
||||
|
@ -42,10 +46,11 @@ CVAR(Bool, gl_render_things, true, 0)
|
|||
CVAR(Bool, gl_render_walls, true, 0)
|
||||
CVAR(Bool, gl_render_flats, true, 0)
|
||||
|
||||
void GLSceneDrawer::UnclipSubsector(subsector_t *sub)
|
||||
void HWDrawInfo::UnclipSubsector(subsector_t *sub)
|
||||
{
|
||||
int count = sub->numlines;
|
||||
seg_t * seg = sub->firstline;
|
||||
auto &clipper = *mClipper;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
|
@ -70,7 +75,7 @@ void GLSceneDrawer::UnclipSubsector(subsector_t *sub)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLSceneDrawer::AddLine (seg_t *seg, bool portalclip)
|
||||
void HWDrawInfo::AddLine (seg_t *seg, bool portalclip)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
if (seg->linedef->Index() == 38)
|
||||
|
@ -79,15 +84,16 @@ void GLSceneDrawer::AddLine (seg_t *seg, bool portalclip)
|
|||
}
|
||||
#endif
|
||||
|
||||
sector_t * backsector = NULL;
|
||||
sector_t * backsector = nullptr;
|
||||
sector_t bs;
|
||||
|
||||
if (portalclip)
|
||||
{
|
||||
int clipres = GLRenderer->mClipPortal->ClipSeg(seg);
|
||||
int clipres = mClipPortal->ClipSeg(seg);
|
||||
if (clipres == PClip_InFront) return;
|
||||
}
|
||||
|
||||
auto &clipper = *mClipper;
|
||||
angle_t startAngle = clipper.GetClipAngle(seg->v2);
|
||||
angle_t endAngle = clipper.GetClipAngle(seg->v1);
|
||||
|
||||
|
@ -97,7 +103,7 @@ void GLSceneDrawer::AddLine (seg_t *seg, bool portalclip)
|
|||
return;
|
||||
}
|
||||
|
||||
if (seg->sidedef == NULL)
|
||||
if (seg->sidedef == nullptr)
|
||||
{
|
||||
if (!(currentsubsector->flags & SSECMF_DRAWN))
|
||||
{
|
||||
|
@ -168,7 +174,7 @@ void GLSceneDrawer::AddLine (seg_t *seg, bool portalclip)
|
|||
|
||||
GLWall wall;
|
||||
wall.sub = currentsubsector;
|
||||
wall.Process(gl_drawinfo, seg, currentsector, backsector);
|
||||
wall.Process(this, seg, currentsector, backsector);
|
||||
rendered_lines++;
|
||||
|
||||
SetupWall.Unclock();
|
||||
|
@ -185,7 +191,7 @@ void GLSceneDrawer::AddLine (seg_t *seg, bool portalclip)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLSceneDrawer::PolySubsector(subsector_t * sub)
|
||||
void HWDrawInfo::PolySubsector(subsector_t * sub)
|
||||
{
|
||||
int count = sub->numlines;
|
||||
seg_t * line = sub->firstline;
|
||||
|
@ -194,7 +200,7 @@ void GLSceneDrawer::PolySubsector(subsector_t * sub)
|
|||
{
|
||||
if (line->linedef)
|
||||
{
|
||||
AddLine (line, GLRenderer->mClipPortal != NULL);
|
||||
AddLine (line, mClipPortal != nullptr);
|
||||
}
|
||||
line++;
|
||||
}
|
||||
|
@ -209,7 +215,7 @@ void GLSceneDrawer::PolySubsector(subsector_t * sub)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLSceneDrawer::RenderPolyBSPNode (void *node)
|
||||
void HWDrawInfo::RenderPolyBSPNode (void *node)
|
||||
{
|
||||
while (!((size_t)node & 1)) // Keep going until found a subsector
|
||||
{
|
||||
|
@ -225,7 +231,7 @@ void GLSceneDrawer::RenderPolyBSPNode (void *node)
|
|||
side ^= 1;
|
||||
|
||||
// It is not necessary to use the slower precise version here
|
||||
if (!clipper.CheckBox(bsp->bbox[side]))
|
||||
if (!mClipper->CheckBox(bsp->bbox[side]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -242,15 +248,15 @@ void GLSceneDrawer::RenderPolyBSPNode (void *node)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLSceneDrawer::AddPolyobjs(subsector_t *sub)
|
||||
void HWDrawInfo::AddPolyobjs(subsector_t *sub)
|
||||
{
|
||||
if (sub->BSP == NULL || sub->BSP->bDirty)
|
||||
if (sub->BSP == nullptr || sub->BSP->bDirty)
|
||||
{
|
||||
sub->BuildPolyBSP();
|
||||
for (unsigned i = 0; i < sub->BSP->Segs.Size(); i++)
|
||||
{
|
||||
sub->BSP->Segs[i].Subsector = sub;
|
||||
sub->BSP->Segs[i].PartnerSeg = NULL;
|
||||
sub->BSP->Segs[i].PartnerSeg = nullptr;
|
||||
}
|
||||
}
|
||||
if (sub->BSP->Nodes.Size() == 0)
|
||||
|
@ -270,13 +276,13 @@ void GLSceneDrawer::AddPolyobjs(subsector_t *sub)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLSceneDrawer::AddLines(subsector_t * sub, sector_t * sector)
|
||||
void HWDrawInfo::AddLines(subsector_t * sub, sector_t * sector)
|
||||
{
|
||||
currentsector = sector;
|
||||
currentsubsector = sub;
|
||||
|
||||
ClipWall.Clock();
|
||||
if (sub->polys != NULL)
|
||||
if (sub->polys != nullptr)
|
||||
{
|
||||
AddPolyobjs(sub);
|
||||
}
|
||||
|
@ -287,13 +293,13 @@ void GLSceneDrawer::AddLines(subsector_t * sub, sector_t * sector)
|
|||
|
||||
while (count--)
|
||||
{
|
||||
if (seg->linedef == NULL)
|
||||
if (seg->linedef == nullptr)
|
||||
{
|
||||
if (!(sub->flags & SSECMF_DRAWN)) AddLine (seg, GLRenderer->mClipPortal != NULL);
|
||||
if (!(sub->flags & SSECMF_DRAWN)) AddLine (seg, mClipPortal != nullptr);
|
||||
}
|
||||
else if (!(seg->sidedef->Flags & WALLF_POLYOBJ))
|
||||
{
|
||||
AddLine (seg, GLRenderer->mClipPortal != NULL);
|
||||
AddLine (seg, mClipPortal != nullptr);
|
||||
}
|
||||
seg++;
|
||||
}
|
||||
|
@ -314,7 +320,7 @@ inline bool PointOnLine(const DVector2 &pos, const line_t *line)
|
|||
return fabs(v) <= EQUAL_EPSILON;
|
||||
}
|
||||
|
||||
void GLSceneDrawer::AddSpecialPortalLines(subsector_t * sub, sector_t * sector, line_t *line)
|
||||
void HWDrawInfo::AddSpecialPortalLines(subsector_t * sub, sector_t * sector, line_t *line)
|
||||
{
|
||||
currentsector = sector;
|
||||
currentsubsector = sub;
|
||||
|
@ -325,7 +331,7 @@ void GLSceneDrawer::AddSpecialPortalLines(subsector_t * sub, sector_t * sector,
|
|||
|
||||
while (count--)
|
||||
{
|
||||
if (seg->linedef != NULL && seg->PartnerSeg != NULL)
|
||||
if (seg->linedef != nullptr && seg->PartnerSeg != nullptr)
|
||||
{
|
||||
if (PointOnLine(seg->v1->fPos(), line) && PointOnLine(seg->v2->fPos(), line))
|
||||
AddLine(seg, false);
|
||||
|
@ -342,7 +348,7 @@ void GLSceneDrawer::AddSpecialPortalLines(subsector_t * sub, sector_t * sector,
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLSceneDrawer::RenderThings(subsector_t * sub, sector_t * sector)
|
||||
void HWDrawInfo::RenderThings(subsector_t * sub, sector_t * sector)
|
||||
{
|
||||
SetupSprite.Clock();
|
||||
sector_t * sec=sub->sector;
|
||||
|
@ -354,7 +360,7 @@ void GLSceneDrawer::RenderThings(subsector_t * sub, sector_t * sector)
|
|||
thing->validcount = validcount;
|
||||
|
||||
FIntCVar *cvar = thing->GetInfo()->distancecheck;
|
||||
if (cvar != NULL && *cvar >= 0)
|
||||
if (cvar != nullptr && *cvar >= 0)
|
||||
{
|
||||
double dist = (thing->Pos() - r_viewpoint.Pos).LengthSquared();
|
||||
double check = (double)**cvar;
|
||||
|
@ -367,7 +373,7 @@ void GLSceneDrawer::RenderThings(subsector_t * sub, sector_t * sector)
|
|||
if (CurrentMapSections[thing->subsector->mapsection])
|
||||
{
|
||||
GLSprite sprite;
|
||||
sprite.Process(gl_drawinfo, thing, sector, in_area, false);
|
||||
sprite.Process(this, thing, sector, in_area, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -375,7 +381,7 @@ void GLSceneDrawer::RenderThings(subsector_t * sub, sector_t * sector)
|
|||
{
|
||||
AActor *thing = node->m_thing;
|
||||
FIntCVar *cvar = thing->GetInfo()->distancecheck;
|
||||
if (cvar != NULL && *cvar >= 0)
|
||||
if (cvar != nullptr && *cvar >= 0)
|
||||
{
|
||||
double dist = (thing->Pos() - r_viewpoint.Pos).LengthSquared();
|
||||
double check = (double)**cvar;
|
||||
|
@ -386,7 +392,7 @@ void GLSceneDrawer::RenderThings(subsector_t * sub, sector_t * sector)
|
|||
}
|
||||
|
||||
GLSprite sprite;
|
||||
sprite.Process(gl_drawinfo, thing, sector, gl_drawinfo->mDrawer->in_area, true);
|
||||
sprite.Process(this, thing, sector, in_area, true);
|
||||
}
|
||||
SetupSprite.Unclock();
|
||||
}
|
||||
|
@ -401,7 +407,7 @@ void GLSceneDrawer::RenderThings(subsector_t * sub, sector_t * sector)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLSceneDrawer::DoSubsector(subsector_t * sub)
|
||||
void HWDrawInfo::DoSubsector(subsector_t * sub)
|
||||
{
|
||||
unsigned int i;
|
||||
sector_t * sector;
|
||||
|
@ -422,23 +428,23 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub)
|
|||
if (!CurrentMapSections[sub->mapsection]) return;
|
||||
if (sub->flags & SSECF_POLYORG) return; // never render polyobject origin subsectors because their vertices no longer are where one may expect.
|
||||
|
||||
if (gl_drawinfo->ss_renderflags[sub->Index()] & SSRF_SEEN)
|
||||
if (ss_renderflags[sub->Index()] & SSRF_SEEN)
|
||||
{
|
||||
// This means that we have reached a subsector in a portal that has been marked 'seen'
|
||||
// from the other side of the portal. This means we must clear the clipper for the
|
||||
// range this subsector spans before going on.
|
||||
UnclipSubsector(sub);
|
||||
}
|
||||
if (clipper.IsBlocked()) return; // if we are inside a stacked sector portal which hasn't unclipped anything yet.
|
||||
if (mClipper->IsBlocked()) return; // if we are inside a stacked sector portal which hasn't unclipped anything yet.
|
||||
|
||||
fakesector=hw_FakeFlat(sector, &fake, in_area, false);
|
||||
|
||||
if (GLRenderer->mClipPortal)
|
||||
if (mClipPortal)
|
||||
{
|
||||
int clipres = GLRenderer->mClipPortal->ClipSubsector(sub);
|
||||
int clipres = mClipPortal->ClipSubsector(sub);
|
||||
if (clipres == PClip_InFront)
|
||||
{
|
||||
line_t *line = GLRenderer->mClipPortal->ClipLine();
|
||||
line_t *line = mClipPortal->ClipLine();
|
||||
// The subsector is out of range, but we still have to check lines that lie directly on the boundary and may expose their upper or lower parts.
|
||||
if (line) AddSpecialPortalLines(sub, fakesector, line);
|
||||
return;
|
||||
|
@ -447,7 +453,11 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub)
|
|||
|
||||
if (sector->validcount != validcount)
|
||||
{
|
||||
GLRenderer->mVBO->CheckUpdate(sector);
|
||||
if (sector->Index() == 62)
|
||||
{
|
||||
int a = 0;
|
||||
}
|
||||
mVBO->CheckUpdate(sector);
|
||||
}
|
||||
|
||||
// [RH] Add particles
|
||||
|
@ -458,14 +468,14 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub)
|
|||
|
||||
for (i = ParticlesInSubsec[sub->Index()]; i != NO_PARTICLE; i = Particles[i].snext)
|
||||
{
|
||||
if (GLRenderer->mClipPortal)
|
||||
if (mClipPortal)
|
||||
{
|
||||
int clipres = GLRenderer->mClipPortal->ClipPoint(Particles[i].Pos);
|
||||
int clipres = mClipPortal->ClipPoint(Particles[i].Pos);
|
||||
if (clipres == PClip_InFront) continue;
|
||||
}
|
||||
|
||||
GLSprite sprite;
|
||||
sprite.ProcessParticle(gl_drawinfo, &Particles[i], fakesector);
|
||||
sprite.ProcessParticle(this, &Particles[i], fakesector);
|
||||
}
|
||||
SetupSprite.Unclock();
|
||||
}
|
||||
|
@ -507,35 +517,33 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub)
|
|||
fakesector = hw_FakeFlat(sector, &fake, in_area, false);
|
||||
}
|
||||
|
||||
uint8_t &srf = gl_drawinfo->sectorrenderflags[sub->render_sector->sectornum];
|
||||
uint8_t &srf = sectorrenderflags[sub->render_sector->sectornum];
|
||||
if (!(srf & SSRF_PROCESSED))
|
||||
{
|
||||
srf |= SSRF_PROCESSED;
|
||||
|
||||
SetupFlat.Clock();
|
||||
GLFlat flat;
|
||||
flat.ProcessSector(gl_drawinfo, fakesector);
|
||||
flat.ProcessSector(this, fakesector);
|
||||
SetupFlat.Unclock();
|
||||
}
|
||||
// mark subsector as processed - but mark for rendering only if it has an actual area.
|
||||
gl_drawinfo->ss_renderflags[sub->Index()] =
|
||||
ss_renderflags[sub->Index()] =
|
||||
(sub->numlines > 2) ? SSRF_PROCESSED|SSRF_RENDERALL : SSRF_PROCESSED;
|
||||
if (sub->hacked & 1) gl_drawinfo->AddHackedSubsector(sub);
|
||||
if (sub->hacked & 1) AddHackedSubsector(sub);
|
||||
|
||||
FSectorPortalGroup *portal;
|
||||
|
||||
portal = fakesector->GetPortalGroup(sector_t::ceiling);
|
||||
if (portal != NULL)
|
||||
if (portal != nullptr)
|
||||
{
|
||||
GLSectorStackPortal *glportal = portal->GetRenderState();
|
||||
glportal->AddSubsector(sub);
|
||||
portal->AddSubsector(sub);
|
||||
}
|
||||
|
||||
portal = fakesector->GetPortalGroup(sector_t::floor);
|
||||
if (portal != NULL)
|
||||
if (portal != nullptr)
|
||||
{
|
||||
GLSectorStackPortal *glportal = portal->GetRenderState();
|
||||
glportal->AddSubsector(sub);
|
||||
portal->AddSubsector(sub);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -554,7 +562,7 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLSceneDrawer::RenderBSPNode (void *node)
|
||||
void HWDrawInfo::RenderBSPNode (void *node)
|
||||
{
|
||||
if (level.nodes.Size() == 0)
|
||||
{
|
||||
|
@ -575,9 +583,9 @@ void GLSceneDrawer::RenderBSPNode (void *node)
|
|||
side ^= 1;
|
||||
|
||||
// It is not necessary to use the slower precise version here
|
||||
if (!clipper.CheckBox(bsp->bbox[side]))
|
||||
if (!mClipper->CheckBox(bsp->bbox[side]))
|
||||
{
|
||||
if (!(gl_drawinfo->no_renderflags[bsp->Index()] & SSRF_SEEN))
|
||||
if (!(no_renderflags[bsp->Index()] & SSRF_SEEN))
|
||||
return;
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
#include <atomic>
|
||||
#include "r_defs.h"
|
||||
|
||||
|
||||
struct FSectorPortalGroup;
|
||||
struct FLinePortalSpan;
|
||||
struct FFlatVertex;
|
||||
|
@ -14,6 +15,9 @@ class IShadowMap;
|
|||
struct particle_t;
|
||||
struct FDynLightData;
|
||||
struct HUDSprite;
|
||||
class Clipper;
|
||||
class IPortal;
|
||||
class FFlatVertexGenerator;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -78,11 +82,12 @@ struct HWDrawInfo
|
|||
|
||||
int FixedColormap;
|
||||
std::atomic<int> spriteindex;
|
||||
bool clipPortal;
|
||||
IPortal *mClipPortal;
|
||||
FRotator mAngles;
|
||||
FVector2 mViewVector;
|
||||
AActor *mViewActor;
|
||||
IShadowMap *mShadowMap;
|
||||
Clipper *mClipper;
|
||||
|
||||
TArray<MissingTextureInfo> MissingUpperTextures;
|
||||
TArray<MissingTextureInfo> MissingLowerTextures;
|
||||
|
@ -104,16 +109,38 @@ struct HWDrawInfo
|
|||
TArray<uint8_t> ss_renderflags;
|
||||
TArray<uint8_t> no_renderflags;
|
||||
|
||||
// This is needed by the BSP traverser.
|
||||
BitArray CurrentMapSections; // this cannot be a single number, because a group of portals with the same displacement may link different sections.
|
||||
area_t in_area;
|
||||
fixed_t viewx, viewy; // since the nodes are still fixed point, keeping the view position also fixed point for node traversal is faster.
|
||||
FFlatVertexGenerator *mVBO; // this class needs access because the sector vertex updating is part of BSP traversal.
|
||||
|
||||
|
||||
private:
|
||||
// For ProcessLowerMiniseg
|
||||
bool inview;
|
||||
subsector_t * viewsubsector;
|
||||
TArray<seg_t *> lowersegs;
|
||||
|
||||
|
||||
subsector_t *currentsubsector; // used by the line processing code.
|
||||
sector_t *currentsector;
|
||||
|
||||
sector_t fakesec; // this is a struct member because it gets used in recursively called functions so it cannot be put on the stack.
|
||||
|
||||
void UnclipSubsector(subsector_t *sub);
|
||||
void AddLine(seg_t *seg, bool portalclip);
|
||||
void PolySubsector(subsector_t * sub);
|
||||
void RenderPolyBSPNode(void *node);
|
||||
void AddPolyobjs(subsector_t *sub);
|
||||
void AddLines(subsector_t * sub, sector_t * sector);
|
||||
void AddSpecialPortalLines(subsector_t * sub, sector_t * sector, line_t *line);
|
||||
void RenderThings(subsector_t * sub, sector_t * sector);
|
||||
void DoSubsector(subsector_t * sub);
|
||||
public:
|
||||
void RenderBSPNode(void *node);
|
||||
|
||||
void ClearBuffers();
|
||||
void SetViewArea();
|
||||
|
||||
bool DoOneSectorUpper(subsector_t * subsec, float planez, area_t in_area);
|
||||
bool DoOneSectorLower(subsector_t * subsec, float planez, area_t in_area);
|
||||
|
@ -169,8 +196,5 @@ public:
|
|||
virtual GLDecal *AddDecal(bool onmirror) = 0;
|
||||
virtual std::pair<FFlatVertex *, unsigned int> AllocVertices(unsigned int count) = 0;
|
||||
|
||||
virtual int ClipPoint(const DVector3 &pos) = 0;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -306,12 +306,14 @@ public:
|
|||
bool stack;
|
||||
bool ceiling;
|
||||
uint8_t renderflags;
|
||||
int vboindex;
|
||||
int iboindex;
|
||||
//int vboheight;
|
||||
|
||||
int dynlightindex;
|
||||
|
||||
bool SetupLights(int pass, FLightNode *head, FDynLightData &lightdata, int portalgroup);
|
||||
bool SetupSubsectorLights(int pass, subsector_t * sub, FDynLightData &lightdata);
|
||||
bool SetupSectorLights(int pass, sector_t * sec, FDynLightData &lightdata);
|
||||
|
||||
void PutFlat(HWDrawInfo *di, bool fog = false);
|
||||
void Process(HWDrawInfo *di, sector_t * model, int whichplane, bool notexture);
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#include "a_sharedglobal.h"
|
||||
#include "r_sky.h"
|
||||
#include "hw_fakeflat.h"
|
||||
#include "hw_drawinfo.h"
|
||||
#include "r_utility.h"
|
||||
|
||||
|
||||
//==========================================================================
|
||||
|
@ -232,7 +234,7 @@ sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac
|
|||
{
|
||||
dest->SetTexture(sector_t::floor, s->GetTexture(sector_t::floor), false);
|
||||
dest->SetPlaneTexZQuick(sector_t::floor, s->GetPlaneTexZ(sector_t::floor));
|
||||
dest->vboindex[sector_t::floor] = sec->vboindex[sector_t::vbo_fakefloor];
|
||||
dest->iboindex[sector_t::floor] = sec->iboindex[sector_t::vbo_fakefloor];
|
||||
dest->vboheight[sector_t::floor] = s->vboheight[sector_t::floor];
|
||||
}
|
||||
else if (s->MoreFlags & SECMF_FAKEFLOORONLY)
|
||||
|
@ -258,7 +260,7 @@ sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac
|
|||
dest->SetPlaneTexZQuick(sector_t::floor, s->GetPlaneTexZ(sector_t::floor));
|
||||
dest->floorplane = s->floorplane;
|
||||
|
||||
dest->vboindex[sector_t::floor] = sec->vboindex[sector_t::vbo_fakefloor];
|
||||
dest->iboindex[sector_t::floor] = sec->iboindex[sector_t::vbo_fakefloor];
|
||||
dest->vboheight[sector_t::floor] = s->vboheight[sector_t::floor];
|
||||
}
|
||||
|
||||
|
@ -270,7 +272,7 @@ sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac
|
|||
{
|
||||
dest->SetTexture(sector_t::ceiling, s->GetTexture(sector_t::ceiling), false);
|
||||
dest->SetPlaneTexZQuick(sector_t::ceiling, s->GetPlaneTexZ(sector_t::ceiling));
|
||||
dest->vboindex[sector_t::ceiling] = sec->vboindex[sector_t::vbo_fakeceiling];
|
||||
dest->iboindex[sector_t::ceiling] = sec->iboindex[sector_t::vbo_fakeceiling];
|
||||
dest->vboheight[sector_t::ceiling] = s->vboheight[sector_t::ceiling];
|
||||
}
|
||||
}
|
||||
|
@ -278,7 +280,7 @@ sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac
|
|||
{
|
||||
dest->ceilingplane = s->ceilingplane;
|
||||
dest->SetPlaneTexZQuick(sector_t::ceiling, s->GetPlaneTexZ(sector_t::ceiling));
|
||||
dest->vboindex[sector_t::ceiling] = sec->vboindex[sector_t::vbo_fakeceiling];
|
||||
dest->iboindex[sector_t::ceiling] = sec->iboindex[sector_t::vbo_fakeceiling];
|
||||
dest->vboheight[sector_t::ceiling] = s->vboheight[sector_t::ceiling];
|
||||
}
|
||||
}
|
||||
|
@ -292,10 +294,10 @@ sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac
|
|||
dest->ceilingplane=s->floorplane;
|
||||
dest->ceilingplane.FlipVert();
|
||||
|
||||
dest->vboindex[sector_t::floor] = sec->vboindex[sector_t::floor];
|
||||
dest->iboindex[sector_t::floor] = sec->iboindex[sector_t::floor];
|
||||
dest->vboheight[sector_t::floor] = sec->vboheight[sector_t::floor];
|
||||
|
||||
dest->vboindex[sector_t::ceiling] = sec->vboindex[sector_t::vbo_fakefloor];
|
||||
dest->iboindex[sector_t::ceiling] = sec->iboindex[sector_t::vbo_fakefloor];
|
||||
dest->vboheight[sector_t::ceiling] = s->vboheight[sector_t::floor];
|
||||
|
||||
dest->ClearPortal(sector_t::ceiling);
|
||||
|
@ -345,10 +347,10 @@ sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac
|
|||
dest->floorplane = s->ceilingplane;
|
||||
dest->floorplane.FlipVert();
|
||||
|
||||
dest->vboindex[sector_t::floor] = sec->vboindex[sector_t::vbo_fakeceiling];
|
||||
dest->iboindex[sector_t::floor] = sec->iboindex[sector_t::vbo_fakeceiling];
|
||||
dest->vboheight[sector_t::floor] = s->vboheight[sector_t::ceiling];
|
||||
|
||||
dest->vboindex[sector_t::ceiling] = sec->vboindex[sector_t::ceiling];
|
||||
dest->iboindex[sector_t::ceiling] = sec->iboindex[sector_t::ceiling];
|
||||
dest->vboheight[sector_t::ceiling] = sec->vboheight[sector_t::ceiling];
|
||||
|
||||
dest->ClearPortal(sector_t::floor);
|
||||
|
@ -383,4 +385,26 @@ sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool bac
|
|||
return dest;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Sets the area the camera is in
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void HWDrawInfo::SetViewArea()
|
||||
{
|
||||
// The render_sector is better suited to represent the current position in GL
|
||||
r_viewpoint.sector = R_PointInSubsector(r_viewpoint.Pos)->render_sector;
|
||||
|
||||
// Get the heightsec state from the render sector, not the current one!
|
||||
if (r_viewpoint.sector->GetHeightSec())
|
||||
{
|
||||
in_area = r_viewpoint.Pos.Z <= r_viewpoint.sector->heightsec->floorplane.ZatPoint(r_viewpoint.Pos) ? area_below :
|
||||
(r_viewpoint.Pos.Z > r_viewpoint.sector->heightsec->ceilingplane.ZatPoint(r_viewpoint.Pos) &&
|
||||
!(r_viewpoint.sector->heightsec->MoreFlags&SECMF_FAKEFLOORONLY)) ? area_above : area_normal;
|
||||
}
|
||||
else
|
||||
{
|
||||
in_area = level.HasHeightSecs ? area_default : area_normal; // depends on exposed lower sectors, if map contains heightsecs.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -92,14 +92,13 @@ bool hw_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * glte
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool GLFlat::SetupSubsectorLights(int pass, subsector_t * sub, FDynLightData &lightdata)
|
||||
bool GLFlat::SetupLights(int pass, FLightNode * node, FDynLightData &lightdata, int portalgroup)
|
||||
{
|
||||
Plane p;
|
||||
|
||||
if (renderstyle == STYLE_Add && !level.lightadditivesurfaces) return false; // no lights on additively blended surfaces.
|
||||
|
||||
lightdata.Clear();
|
||||
FLightNode * node = sub->lighthead;
|
||||
while (node)
|
||||
{
|
||||
ADynamicLight * light = node->lightsource;
|
||||
|
@ -121,13 +120,23 @@ bool GLFlat::SetupSubsectorLights(int pass, subsector_t * sub, FDynLightData &li
|
|||
}
|
||||
|
||||
p.Set(plane.plane.Normal(), plane.plane.fD());
|
||||
lightdata.GetLight(sub->sector->PortalGroup, p, light, false);
|
||||
lightdata.GetLight(portalgroup, p, light, false);
|
||||
node = node->nextLight;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GLFlat::SetupSubsectorLights(int pass, subsector_t * sub, FDynLightData &lightdata)
|
||||
{
|
||||
return SetupLights(pass, sub->lighthead, lightdata, sub->sector->PortalGroup);
|
||||
}
|
||||
|
||||
bool GLFlat::SetupSectorLights(int pass, sector_t * sec, FDynLightData &lightdata)
|
||||
{
|
||||
return SetupLights(pass, sec->lighthead, lightdata, sec->PortalGroup);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// GLFlat::PutFlat
|
||||
|
@ -220,11 +229,11 @@ void GLFlat::SetFrom3DFloor(F3DFloor *rover, bool top, bool underside)
|
|||
renderstyle = rover->flags&FF_ADDITIVETRANS? STYLE_Add : STYLE_Translucent;
|
||||
if (plane.model->VBOHeightcheck(plane.isceiling))
|
||||
{
|
||||
vboindex = plane.vindex;
|
||||
iboindex = plane.vindex;
|
||||
}
|
||||
else
|
||||
{
|
||||
vboindex = -1;
|
||||
iboindex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,11 +298,11 @@ void GLFlat::ProcessSector(HWDrawInfo *di, sector_t * frontsector)
|
|||
{
|
||||
if (frontsector->VBOHeightcheck(sector_t::floor))
|
||||
{
|
||||
vboindex = frontsector->vboindex[sector_t::floor];
|
||||
iboindex = frontsector->iboindex[sector_t::floor];
|
||||
}
|
||||
else
|
||||
{
|
||||
vboindex = -1;
|
||||
iboindex = -1;
|
||||
}
|
||||
|
||||
ceiling = false;
|
||||
|
@ -349,11 +358,11 @@ void GLFlat::ProcessSector(HWDrawInfo *di, sector_t * frontsector)
|
|||
{
|
||||
if (frontsector->VBOHeightcheck(sector_t::ceiling))
|
||||
{
|
||||
vboindex = frontsector->vboindex[sector_t::ceiling];
|
||||
iboindex = frontsector->iboindex[sector_t::ceiling];
|
||||
}
|
||||
else
|
||||
{
|
||||
vboindex = -1;
|
||||
iboindex = -1;
|
||||
}
|
||||
|
||||
ceiling = true;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "hw_drawinfo.h"
|
||||
#include "hwrenderer/textures/hw_material.h"
|
||||
|
||||
struct GLSkyInfo
|
||||
|
@ -32,3 +33,12 @@ struct GLHorizonInfo
|
|||
PalEntry specialcolor;
|
||||
};
|
||||
|
||||
class IPortal
|
||||
{
|
||||
public:
|
||||
virtual ~IPortal() {}
|
||||
virtual int ClipSeg(seg_t *seg) { return PClip_Inside; }
|
||||
virtual int ClipSubsector(subsector_t *sub) { return PClip_Inside; }
|
||||
virtual int ClipPoint(const DVector2 &pos) { return PClip_Inside; }
|
||||
virtual line_t *ClipLine() { return nullptr; }
|
||||
};
|
||||
|
|
|
@ -72,7 +72,20 @@ void HWDrawInfo::ClearBuffers()
|
|||
HandledSubsectors.Clear();
|
||||
spriteindex = 0;
|
||||
|
||||
CurrentMapSections.Resize(level.NumMapSections);
|
||||
CurrentMapSections.Zero();
|
||||
|
||||
sectorrenderflags.Resize(level.sectors.Size());
|
||||
ss_renderflags.Resize(level.subsectors.Size());
|
||||
no_renderflags.Resize(level.subsectors.Size());
|
||||
|
||||
memset(§orrenderflags[0], 0, level.sectors.Size() * sizeof(sectorrenderflags[0]));
|
||||
memset(&ss_renderflags[0], 0, level.subsectors.Size() * sizeof(ss_renderflags[0]));
|
||||
memset(&no_renderflags[0], 0, level.nodes.Size() * sizeof(no_renderflags[0]));
|
||||
|
||||
mClipPortal = nullptr;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Adds a subsector plane to a sector's render list
|
||||
|
@ -1077,6 +1090,7 @@ void HWDrawInfo::ProcessSectorStacks(area_t in_area)
|
|||
{
|
||||
subsector_t *sub = HandledSubsectors[j];
|
||||
ss_renderflags[sub->Index()] &= ~SSRF_RENDERCEILING;
|
||||
sub->sector->ibocount = -1; // cannot render this sector in one go.
|
||||
|
||||
if (sub->portalcoverage[sector_t::ceiling].subsectors == NULL)
|
||||
{
|
||||
|
@ -1122,6 +1136,7 @@ void HWDrawInfo::ProcessSectorStacks(area_t in_area)
|
|||
{
|
||||
subsector_t *sub = HandledSubsectors[j];
|
||||
ss_renderflags[sub->Index()] &= ~SSRF_RENDERFLOOR;
|
||||
sub->sector->ibocount = -1; // cannot render this sector in one go.
|
||||
|
||||
if (sub->portalcoverage[sector_t::floor].subsectors == NULL)
|
||||
{
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "hwrenderer/scene/hw_drawstructs.h"
|
||||
#include "hwrenderer/scene/hw_drawinfo.h"
|
||||
#include "hwrenderer/scene/hw_fakeflat.h"
|
||||
#include "hwrenderer/scene/hw_portal.h"
|
||||
#include "hwrenderer/utility/hw_cvars.h"
|
||||
#include "hwrenderer/utility/hw_clock.h"
|
||||
#include "hwrenderer/utility/hw_lighting.h"
|
||||
|
@ -448,7 +449,7 @@ void GLSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t
|
|||
// exclude vertically moving objects from this check.
|
||||
if (!thing->Vel.isZero())
|
||||
{
|
||||
if (!gl_FindModelFrame(thing->GetClass(), spritenum, thing->frame, false))
|
||||
if (!FindModelFrame(thing->GetClass(), spritenum, thing->frame, false))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -471,9 +472,9 @@ void GLSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t
|
|||
thing->flags7 |= MF7_FLYCHEAT; // do this only once for the very first frame, but not if it gets into range again.
|
||||
}
|
||||
|
||||
if (thruportal != 2 && di->clipPortal)
|
||||
if (thruportal != 2 && di->mClipPortal != nullptr)
|
||||
{
|
||||
int clipres = di->ClipPoint(thingpos);
|
||||
int clipres = di->mClipPortal->ClipPoint(thingpos);
|
||||
if (clipres == PClip_InFront) return;
|
||||
}
|
||||
// disabled because almost none of the actual game code is even remotely prepared for this. If desired, use the INTERPOLATE flag.
|
||||
|
@ -509,7 +510,7 @@ void GLSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t
|
|||
z += fz;
|
||||
}
|
||||
|
||||
modelframe = isPicnumOverride ? nullptr : gl_FindModelFrame(thing->GetClass(), spritenum, thing->frame, !!(thing->flags & MF_DROPPED));
|
||||
modelframe = isPicnumOverride ? nullptr : FindModelFrame(thing->GetClass(), spritenum, thing->frame, !!(thing->flags & MF_DROPPED));
|
||||
if (!modelframe)
|
||||
{
|
||||
bool mirror;
|
||||
|
|
|
@ -252,14 +252,13 @@ bool HUDSprite::GetWeaponRenderStyle(DPSprite *psp, AActor *playermo, sector_t *
|
|||
auto rs = psp->GetRenderStyle(playermo->RenderStyle, playermo->Alpha);
|
||||
|
||||
visstyle_t vis;
|
||||
float trans = 0.f;
|
||||
|
||||
vis.RenderStyle = STYLE_Count;
|
||||
vis.Alpha = rs.second;
|
||||
vis.Invert = false;
|
||||
playermo->AlterWeaponSprite(&vis);
|
||||
|
||||
if (!(psp->Flags & PSPF_FORCEALPHA)) trans = vis.Alpha;
|
||||
alpha = (psp->Flags & PSPF_FORCEALPHA) ? 0.f : vis.Alpha;
|
||||
|
||||
if (vis.RenderStyle != STYLE_Count && !(psp->Flags & PSPF_FORCESTYLE))
|
||||
{
|
||||
|
@ -303,14 +302,10 @@ bool HUDSprite::GetWeaponRenderStyle(DPSprite *psp, AActor *playermo, sector_t *
|
|||
{
|
||||
alpha = 1.f;
|
||||
}
|
||||
else if (trans == 0.f)
|
||||
else if (alpha == 0.f)
|
||||
{
|
||||
alpha = vis.Alpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
alpha = trans;
|
||||
}
|
||||
if (!RenderStyle.IsVisible(alpha)) return false; // if it isn't visible skip the rest.
|
||||
|
||||
PalEntry ThingColor = (playermo->RenderStyle.Flags & STYLEF_ColorIsFixed) ? playermo->fillcolor : 0xffffff;
|
||||
|
@ -430,7 +425,7 @@ void HWDrawInfo::PreparePlayerSprites(sector_t * viewsector, area_t in_area)
|
|||
bool brightflash = false;
|
||||
AActor * playermo = players[consoleplayer].camera;
|
||||
player_t * player = playermo->player;
|
||||
const bool hudModelStep = gl_IsHUDModelForPlayerAvailable(player);
|
||||
const bool hudModelStep = IsHUDModelForPlayerAvailable(player);
|
||||
|
||||
AActor *camera = r_viewpoint.camera;
|
||||
|
||||
|
@ -453,7 +448,7 @@ void HWDrawInfo::PreparePlayerSprites(sector_t * viewsector, area_t in_area)
|
|||
for (DPSprite *psp = player->psprites; psp != nullptr && psp->GetID() < PSP_TARGETCENTER; psp = psp->GetNext())
|
||||
{
|
||||
if (!psp->GetState()) continue;
|
||||
FSpriteModelFrame *smf = playermo->player->ReadyWeapon ? gl_FindModelFrame(playermo->player->ReadyWeapon->GetClass(), psp->GetState()->sprite, psp->GetState()->GetFrame(), false) : nullptr;
|
||||
FSpriteModelFrame *smf = playermo->player->ReadyWeapon ? FindModelFrame(playermo->player->ReadyWeapon->GetClass(), psp->GetState()->sprite, psp->GetState()->GetFrame(), false) : nullptr;
|
||||
// This is an 'either-or' proposition. This maybe needs some work to allow overlays with weapon models but as originally implemented this just won't work.
|
||||
if (smf && !hudModelStep) continue;
|
||||
if (!smf && hudModelStep) continue;
|
||||
|
|
|
@ -119,7 +119,7 @@ void hw_PrecacheTexture(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitl
|
|||
{
|
||||
auto &state = cls->GetStates()[i];
|
||||
spritelist[state.sprite].Insert(gltrans, true);
|
||||
FSpriteModelFrame * smf = gl_FindModelFrame(cls, state.sprite, state.Frame, false);
|
||||
FSpriteModelFrame * smf = FindModelFrame(cls, state.sprite, state.Frame, false);
|
||||
if (smf != NULL)
|
||||
{
|
||||
for (int i = 0; i < MAX_MODELS_PER_FRAME; i++)
|
||||
|
|
|
@ -537,6 +537,8 @@ xx(Repeatspecial)
|
|||
xx(Conversation)
|
||||
xx(Locknumber)
|
||||
xx(Midtex3dimpassible)
|
||||
xx(Revealed)
|
||||
xx(AutomapStyle)
|
||||
|
||||
xx(Playercross)
|
||||
xx(Playeruse)
|
||||
|
|
|
@ -120,6 +120,7 @@ static void P_Add3DFloor(sector_t* sec, sector_t* sec2, line_t* master, int flag
|
|||
ffloor->top.copied = ffloor->bottom.copied = false;
|
||||
ffloor->top.model = ffloor->bottom.model = ffloor->model = sec2;
|
||||
ffloor->target = sec;
|
||||
ffloor->top.vindex = ffloor->bottom.vindex = -1;
|
||||
|
||||
if (!(flags&FF_THINFLOOR))
|
||||
{
|
||||
|
|
|
@ -1510,6 +1510,7 @@ void P_LoadSectors (MapData *map, FMissingTextureTracker &missingtex)
|
|||
ss->friction = ORIG_FRICTION;
|
||||
ss->movefactor = ORIG_FRICTION_FACTOR;
|
||||
ss->sectornum = i;
|
||||
ss->ibocount = -1;
|
||||
}
|
||||
delete[] msp;
|
||||
}
|
||||
|
|
|
@ -1107,6 +1107,14 @@ public:
|
|||
Flag(ld->flags, ML_3DMIDTEX_IMPASS, key);
|
||||
continue;
|
||||
|
||||
case NAME_Revealed:
|
||||
Flag(ld->flags, ML_REVEALED, key);
|
||||
continue;
|
||||
|
||||
case NAME_AutomapStyle:
|
||||
ld->automapstyle = AutomapLineStyle(CheckInt(key));
|
||||
continue;
|
||||
|
||||
case NAME_MoreIds:
|
||||
// delay parsing of the tag string until parsing of the sector is complete
|
||||
// This ensures that the ID is always the first tag in the list.
|
||||
|
@ -1375,6 +1383,7 @@ public:
|
|||
sec->sectornum = index;
|
||||
sec->damageinterval = 32;
|
||||
sec->terrainnum[sector_t::ceiling] = sec->terrainnum[sector_t::floor] = -1;
|
||||
sec->ibocount = -1;
|
||||
memset(sec->SpecialColors, -1, sizeof(sec->SpecialColors));
|
||||
if (floordrop) sec->Flags = SECF_FLOORDROP;
|
||||
// killough 3/7/98: end changes
|
||||
|
|
|
@ -79,6 +79,11 @@ void PolyTriangleDrawer::SetCullCCW(const DrawerCommandQueuePtr &queue, bool ccw
|
|||
queue->Push<PolySetCullCCWCommand>(ccw);
|
||||
}
|
||||
|
||||
void PolyTriangleDrawer::SetTwoSided(const DrawerCommandQueuePtr &queue, bool twosided)
|
||||
{
|
||||
queue->Push<PolySetTwoSidedCommand>(twosided);
|
||||
}
|
||||
|
||||
void PolyTriangleDrawer::SetWeaponScene(const DrawerCommandQueuePtr &queue, bool enable)
|
||||
{
|
||||
queue->Push<PolySetWeaponSceneCommand>(enable);
|
||||
|
@ -348,6 +353,14 @@ void PolyTriangleThreadData::DrawShadedTriangle(const ShadedTriVertex *vert, boo
|
|||
}
|
||||
}
|
||||
|
||||
if (twosided && numclipvert > 2)
|
||||
{
|
||||
args->v1 = &clippedvert[0];
|
||||
args->v2 = &clippedvert[1];
|
||||
args->v3 = &clippedvert[2];
|
||||
ccw = !IsFrontfacing(args);
|
||||
}
|
||||
|
||||
// Draw screen triangles
|
||||
if (ccw)
|
||||
{
|
||||
|
@ -588,6 +601,17 @@ void PolySetCullCCWCommand::Execute(DrawerThread *thread)
|
|||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PolySetTwoSidedCommand::PolySetTwoSidedCommand(bool twosided) : twosided(twosided)
|
||||
{
|
||||
}
|
||||
|
||||
void PolySetTwoSidedCommand::Execute(DrawerThread *thread)
|
||||
{
|
||||
PolyTriangleThreadData::Get(thread)->SetTwoSided(twosided);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PolySetWeaponSceneCommand::PolySetWeaponSceneCommand(bool value) : value(value)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ public:
|
|||
static void ClearBuffers(DCanvas *canvas);
|
||||
static void SetViewport(const DrawerCommandQueuePtr &queue, int x, int y, int width, int height, DCanvas *canvas, bool span_drawers);
|
||||
static void SetCullCCW(const DrawerCommandQueuePtr &queue, bool ccw);
|
||||
static void SetTwoSided(const DrawerCommandQueuePtr &queue, bool twosided);
|
||||
static void SetWeaponScene(const DrawerCommandQueuePtr &queue, bool enable);
|
||||
static void SetTransform(const DrawerCommandQueuePtr &queue, const Mat4f *objectToClip);
|
||||
};
|
||||
|
@ -47,6 +48,7 @@ public:
|
|||
void SetViewport(int x, int y, int width, int height, uint8_t *dest, int dest_width, int dest_height, int dest_pitch, bool dest_bgra, bool span_drawers);
|
||||
void SetTransform(const Mat4f *objectToClip);
|
||||
void SetCullCCW(bool value) { ccw = value; }
|
||||
void SetTwoSided(bool value) { twosided = value; }
|
||||
void SetWeaponScene(bool value) { weaponScene = value; }
|
||||
|
||||
void DrawElements(const PolyDrawArgs &args);
|
||||
|
@ -81,6 +83,7 @@ private:
|
|||
bool dest_bgra = false;
|
||||
uint8_t *dest = nullptr;
|
||||
bool ccw = true;
|
||||
bool twosided = false;
|
||||
bool weaponScene = false;
|
||||
const Mat4f *objectToClip = nullptr;
|
||||
bool span_drawers = false;
|
||||
|
@ -112,6 +115,18 @@ private:
|
|||
bool ccw;
|
||||
};
|
||||
|
||||
class PolySetTwoSidedCommand : public DrawerCommand
|
||||
{
|
||||
public:
|
||||
PolySetTwoSidedCommand(bool twosided);
|
||||
|
||||
void Execute(DrawerThread *thread) override;
|
||||
FString DebugInfo() override { return "PolySetCullCCWCommand"; }
|
||||
|
||||
private:
|
||||
bool twosided;
|
||||
};
|
||||
|
||||
class PolySetWeaponSceneCommand : public DrawerCommand
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -33,9 +33,6 @@
|
|||
#include "actorinlines.h"
|
||||
#include "i_time.h"
|
||||
|
||||
void gl_FlushModels();
|
||||
bool polymodelsInUse;
|
||||
|
||||
void PolyRenderModel(PolyRenderThread *thread, const Mat4f &worldToClip, uint32_t stencilValue, float x, float y, float z, FSpriteModelFrame *smf, AActor *actor)
|
||||
{
|
||||
PolyModelRenderer renderer(thread, worldToClip, stencilValue);
|
||||
|
@ -52,11 +49,6 @@ void PolyRenderHUDModel(PolyRenderThread *thread, const Mat4f &worldToClip, uint
|
|||
|
||||
PolyModelRenderer::PolyModelRenderer(PolyRenderThread *thread, const Mat4f &worldToClip, uint32_t stencilValue) : Thread(thread), WorldToClip(worldToClip), StencilValue(stencilValue)
|
||||
{
|
||||
if (!polymodelsInUse)
|
||||
{
|
||||
gl_FlushModels();
|
||||
polymodelsInUse = true;
|
||||
}
|
||||
}
|
||||
|
||||
void PolyModelRenderer::BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix)
|
||||
|
@ -64,10 +56,12 @@ void PolyModelRenderer::BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, co
|
|||
ModelActor = actor;
|
||||
const_cast<VSMatrix &>(objectToWorldMatrix).copy(ObjectToWorld.Matrix);
|
||||
SetTransform();
|
||||
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true);
|
||||
}
|
||||
|
||||
void PolyModelRenderer::EndDrawModel(AActor *actor, FSpriteModelFrame *smf)
|
||||
{
|
||||
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false);
|
||||
ModelActor = nullptr;
|
||||
}
|
||||
|
||||
|
@ -106,12 +100,14 @@ void PolyModelRenderer::BeginDrawHUDModel(AActor *actor, const VSMatrix &objectT
|
|||
const_cast<VSMatrix &>(objectToWorldMatrix).copy(ObjectToWorld.Matrix);
|
||||
SetTransform();
|
||||
PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, true);
|
||||
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true);
|
||||
}
|
||||
|
||||
void PolyModelRenderer::EndDrawHUDModel(AActor *actor)
|
||||
{
|
||||
ModelActor = nullptr;
|
||||
PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, false);
|
||||
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false);
|
||||
}
|
||||
|
||||
void PolyModelRenderer::SetInterpolation(double interpolation)
|
||||
|
|
|
@ -34,6 +34,8 @@ class PolyModelRenderer : public FModelRenderer
|
|||
public:
|
||||
PolyModelRenderer(PolyRenderThread *thread, const Mat4f &worldToClip, uint32_t stencilValue);
|
||||
|
||||
ModelRendererType GetType() const override { return PolyModelRendererType; }
|
||||
|
||||
void BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix) override;
|
||||
void EndDrawModel(AActor *actor, FSpriteModelFrame *smf) override;
|
||||
IModelVertexBuffer *CreateVertexBuffer(bool needindex, bool singleframe) override;
|
||||
|
|
|
@ -60,7 +60,7 @@ void RenderPolyPlayerSprites::Render(PolyRenderThread *thread)
|
|||
(r_deathcamera && viewpoint.camera->health <= 0))
|
||||
return;
|
||||
|
||||
renderHUDModel = r_models && gl_IsHUDModelForPlayerAvailable(players[consoleplayer].camera->player);
|
||||
renderHUDModel = r_models && IsHUDModelForPlayerAvailable(players[consoleplayer].camera->player);
|
||||
|
||||
PolyTransferHeights fakeflat(viewpoint.camera->subsector);
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ void RenderPolySprite::Render(PolyRenderThread *thread, AActor *thing, subsector
|
|||
{
|
||||
int spritenum = thing->sprite;
|
||||
bool isPicnumOverride = thing->picnum.isValid();
|
||||
FSpriteModelFrame *modelframe = isPicnumOverride ? nullptr : gl_FindModelFrame(thing->GetClass(), spritenum, thing->frame, !!(thing->flags & MF_DROPPED));
|
||||
FSpriteModelFrame *modelframe = isPicnumOverride ? nullptr : FindModelFrame(thing->GetClass(), spritenum, thing->frame, !!(thing->flags & MF_DROPPED));
|
||||
if (modelframe)
|
||||
{
|
||||
const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
struct FPortalGroupArray;
|
||||
struct portnode_t;
|
||||
struct subsector_t;
|
||||
//============================================================================
|
||||
//
|
||||
// This table holds the offsets for the different parts of a map
|
||||
|
@ -256,6 +257,8 @@ struct FSectorPortalGroup
|
|||
GLSectorStackPortal *glportal; // for quick access to the render data. This is only valid during BSP traversal!
|
||||
|
||||
GLSectorStackPortal *GetRenderState();
|
||||
|
||||
void AddSubsector(subsector_t *sub);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -94,8 +94,8 @@ void FModelRenderer::RenderModel(float x, float y, float z, FSpriteModelFrame *s
|
|||
|
||||
if (smf->flags & MDL_ROTATING)
|
||||
{
|
||||
const double time = smf->rotationSpeed*GetTimeFloat() / 200.;
|
||||
rotateOffset = double((time - xs_FloorToInt(time)) *360.);
|
||||
double turns = (I_GetTime() % 200 + I_GetTimeFrac()) / 200.0;
|
||||
rotateOffset = turns * 360.0;
|
||||
}
|
||||
|
||||
// Added MDL_USEACTORPITCH and MDL_USEACTORROLL flags processing.
|
||||
|
@ -164,14 +164,14 @@ void FModelRenderer::RenderModel(float x, float y, float z, FSpriteModelFrame *s
|
|||
objectToWorldMatrix.scale(1, stretch, 1);
|
||||
|
||||
BeginDrawModel(actor, smf, objectToWorldMatrix);
|
||||
RenderFrameModels(smf, actor->state, actor->tics, actor->GetClass(), nullptr, translation);
|
||||
RenderFrameModels(smf, actor->state, actor->tics, actor->GetClass(), translation);
|
||||
EndDrawModel(actor, smf);
|
||||
}
|
||||
|
||||
void FModelRenderer::RenderHUDModel(DPSprite *psp, float ofsX, float ofsY)
|
||||
{
|
||||
AActor * playermo = players[consoleplayer].camera;
|
||||
FSpriteModelFrame *smf = gl_FindModelFrame(playermo->player->ReadyWeapon->GetClass(), psp->GetState()->sprite, psp->GetState()->GetFrame(), false);
|
||||
FSpriteModelFrame *smf = FindModelFrame(playermo->player->ReadyWeapon->GetClass(), psp->GetState()->sprite, psp->GetState()->GetFrame(), false);
|
||||
|
||||
// [BB] No model found for this sprite, so we can't render anything.
|
||||
if (smf == nullptr)
|
||||
|
@ -200,16 +200,11 @@ void FModelRenderer::RenderHUDModel(DPSprite *psp, float ofsX, float ofsY)
|
|||
objectToWorldMatrix.rotate(-smf->rolloffset, 1, 0, 0);
|
||||
|
||||
BeginDrawHUDModel(playermo, objectToWorldMatrix);
|
||||
RenderFrameModels(smf, psp->GetState(), psp->GetTics(), playermo->player->ReadyWeapon->GetClass(), nullptr, 0);
|
||||
RenderFrameModels(smf, psp->GetState(), psp->GetTics(), playermo->player->ReadyWeapon->GetClass(), 0);
|
||||
EndDrawHUDModel(playermo);
|
||||
}
|
||||
|
||||
void FModelRenderer::RenderFrameModels(const FSpriteModelFrame *smf,
|
||||
const FState *curState,
|
||||
const int curTics,
|
||||
const PClass *ti,
|
||||
Matrix3x4 *normaltransform,
|
||||
int translation)
|
||||
void FModelRenderer::RenderFrameModels(const FSpriteModelFrame *smf, const FState *curState, const int curTics, const PClass *ti, int translation)
|
||||
{
|
||||
// [BB] Frame interpolation: Find the FSpriteModelFrame smfNext which follows after smf in the animation
|
||||
// and the scalar value inter ( element of [0,1) ), both necessary to determine the interpolated frame.
|
||||
|
@ -225,14 +220,13 @@ void FModelRenderer::RenderFrameModels(const FSpriteModelFrame *smf,
|
|||
// [BB] In case the tic counter is frozen we have to leave ticFraction at zero.
|
||||
if (ConsoleState == c_up && menuactive != MENU_On && !(level.flags2 & LEVEL2_FROZEN))
|
||||
{
|
||||
double time = GetTimeFloat();
|
||||
ticFraction = (time - static_cast<int>(time));
|
||||
ticFraction = I_GetTimeFrac();
|
||||
}
|
||||
inter = static_cast<double>(curState->Tics - curTics - ticFraction) / static_cast<double>(curState->Tics);
|
||||
inter = static_cast<double>(curState->Tics - curTics + ticFraction) / static_cast<double>(curState->Tics);
|
||||
|
||||
// [BB] For some actors (e.g. ZPoisonShroom) spr->actor->tics can be bigger than curState->Tics.
|
||||
// In this case inter is negative and we need to set it to zero.
|
||||
if (inter < 0.)
|
||||
if (curState->Tics < curTics)
|
||||
inter = 0.;
|
||||
else
|
||||
{
|
||||
|
@ -253,7 +247,7 @@ void FModelRenderer::RenderFrameModels(const FSpriteModelFrame *smf,
|
|||
}
|
||||
}
|
||||
if (inter != 0.0)
|
||||
smfNext = gl_FindModelFrame(ti, nextState->sprite, nextState->Frame, false);
|
||||
smfNext = FindModelFrame(ti, nextState->sprite, nextState->Frame, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -265,7 +259,7 @@ void FModelRenderer::RenderFrameModels(const FSpriteModelFrame *smf,
|
|||
FModel * mdl = Models[smf->modelIDs[i]];
|
||||
FTexture *tex = smf->skinIDs[i].isValid() ? TexMan(smf->skinIDs[i]) : nullptr;
|
||||
mdl->BuildVertexBuffer(this);
|
||||
SetVertexBuffer(mdl->mVBuf);
|
||||
SetVertexBuffer(mdl->GetVertexBuffer(this));
|
||||
|
||||
mdl->PushSpriteMDLFrame(smf, i);
|
||||
|
||||
|
@ -279,24 +273,9 @@ void FModelRenderer::RenderFrameModels(const FSpriteModelFrame *smf,
|
|||
}
|
||||
}
|
||||
|
||||
double FModelRenderer::GetTimeFloat()
|
||||
{
|
||||
return (double)I_msTime() * (double)TICRATE / 1000.;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void gl_LoadModels()
|
||||
{
|
||||
/*
|
||||
for (int i = Models.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
Models[i]->BuildVertexBuffer();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void gl_FlushModels()
|
||||
void FlushModels()
|
||||
{
|
||||
for (int i = Models.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
|
@ -306,9 +285,24 @@ void gl_FlushModels()
|
|||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FModel::FModel()
|
||||
{
|
||||
for (int i = 0; i < NumModelRendererTypes; i++)
|
||||
mVBuf[i] = nullptr;
|
||||
}
|
||||
|
||||
FModel::~FModel()
|
||||
{
|
||||
if (mVBuf != nullptr) delete mVBuf;
|
||||
DestroyVertexBuffer();
|
||||
}
|
||||
|
||||
void FModel::DestroyVertexBuffer()
|
||||
{
|
||||
for (int i = 0; i < NumModelRendererTypes; i++)
|
||||
{
|
||||
delete mVBuf[i];
|
||||
mVBuf[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static TArray<FSpriteModelFrame> SpriteModelFrames;
|
||||
|
@ -415,7 +409,7 @@ static unsigned FindModel(const char * path, const char * modelfile)
|
|||
FMemLump lumpd = Wads.ReadLump(lump);
|
||||
char * buffer = (char*)lumpd.GetMem();
|
||||
|
||||
if ( fullname.IndexOf("_d.3d") == fullname.Len()-5 )
|
||||
if ( (size_t)fullname.IndexOf("_d.3d") == fullname.Len()-5 )
|
||||
{
|
||||
FString anivfile = fullname.GetChars();
|
||||
anivfile.Substitute("_d.3d","_a.3d");
|
||||
|
@ -424,7 +418,7 @@ static unsigned FindModel(const char * path, const char * modelfile)
|
|||
model = new FUE1Model;
|
||||
}
|
||||
}
|
||||
else if ( fullname.IndexOf("_a.3d") == fullname.Len()-5 )
|
||||
else if ( (size_t)fullname.IndexOf("_a.3d") == fullname.Len()-5 )
|
||||
{
|
||||
FString datafile = fullname.GetChars();
|
||||
datafile.Substitute("_a.3d","_d.3d");
|
||||
|
@ -475,22 +469,15 @@ static unsigned FindModel(const char * path, const char * modelfile)
|
|||
|
||||
//===========================================================================
|
||||
//
|
||||
// gl_InitModels
|
||||
// InitModels
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void gl_InitModels()
|
||||
static void ParseModelDefLump(int Lump);
|
||||
|
||||
void InitModels()
|
||||
{
|
||||
int Lump, lastLump;
|
||||
FString path;
|
||||
int index, surface;
|
||||
int i;
|
||||
|
||||
FSpriteModelFrame smf;
|
||||
|
||||
lastLump = 0;
|
||||
|
||||
for(unsigned i=0;i<Models.Size();i++)
|
||||
for (unsigned i = 0; i < Models.Size(); i++)
|
||||
{
|
||||
delete Models[i];
|
||||
}
|
||||
|
@ -508,6 +495,7 @@ void gl_InitModels()
|
|||
for (unsigned i = 0; i < VoxelDefs.Size(); i++)
|
||||
{
|
||||
FVoxelModel *md = (FVoxelModel*)Models[VoxelDefs[i]->Voxel->VoxelIndex];
|
||||
FSpriteModelFrame smf;
|
||||
memset(&smf, 0, sizeof(smf));
|
||||
smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1;
|
||||
smf.modelIDs[0] = VoxelDefs[i]->Voxel->VoxelIndex;
|
||||
|
@ -539,302 +527,11 @@ void gl_InitModels()
|
|||
}
|
||||
}
|
||||
|
||||
memset(&smf, 0, sizeof(smf));
|
||||
smf.modelIDs[0] = smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1;
|
||||
int Lump;
|
||||
int lastLump = 0;
|
||||
while ((Lump = Wads.FindLump("MODELDEF", &lastLump)) != -1)
|
||||
{
|
||||
FScanner sc(Lump);
|
||||
while (sc.GetString())
|
||||
{
|
||||
if (sc.Compare("model"))
|
||||
{
|
||||
path = "";
|
||||
sc.MustGetString();
|
||||
memset(&smf, 0, sizeof(smf));
|
||||
smf.modelIDs[0] = smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1;
|
||||
smf.xscale=smf.yscale=smf.zscale=1.f;
|
||||
|
||||
smf.type = PClass::FindClass(sc.String);
|
||||
if (!smf.type || smf.type->Defaults == nullptr)
|
||||
{
|
||||
sc.ScriptError("MODELDEF: Unknown actor type '%s'\n", sc.String);
|
||||
}
|
||||
sc.MustGetStringName("{");
|
||||
while (!sc.CheckString("}"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
if (sc.Compare("path"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
FixPathSeperator(sc.String);
|
||||
path = sc.String;
|
||||
if (path[(int)path.Len()-1]!='/') path+='/';
|
||||
}
|
||||
else if (sc.Compare("model"))
|
||||
{
|
||||
sc.MustGetNumber();
|
||||
index = sc.Number;
|
||||
if (index < 0 || index >= MAX_MODELS_PER_FRAME)
|
||||
{
|
||||
sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars());
|
||||
}
|
||||
sc.MustGetString();
|
||||
FixPathSeperator(sc.String);
|
||||
smf.modelIDs[index] = FindModel(path.GetChars(), sc.String);
|
||||
if (smf.modelIDs[index] == -1)
|
||||
{
|
||||
Printf("%s: model not found in %s\n", sc.String, path.GetChars());
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("scale"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
smf.xscale = sc.Float;
|
||||
sc.MustGetFloat();
|
||||
smf.yscale = sc.Float;
|
||||
sc.MustGetFloat();
|
||||
smf.zscale = sc.Float;
|
||||
}
|
||||
// [BB] Added zoffset reading.
|
||||
// Now it must be considered deprecated.
|
||||
else if (sc.Compare("zoffset"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
smf.zoffset=sc.Float;
|
||||
}
|
||||
// Offset reading.
|
||||
else if (sc.Compare("offset"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
smf.xoffset = sc.Float;
|
||||
sc.MustGetFloat();
|
||||
smf.yoffset = sc.Float;
|
||||
sc.MustGetFloat();
|
||||
smf.zoffset = sc.Float;
|
||||
}
|
||||
// angleoffset, pitchoffset and rolloffset reading.
|
||||
else if (sc.Compare("angleoffset"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
smf.angleoffset = sc.Float;
|
||||
}
|
||||
else if (sc.Compare("pitchoffset"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
smf.pitchoffset = sc.Float;
|
||||
}
|
||||
else if (sc.Compare("rolloffset"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
smf.rolloffset = sc.Float;
|
||||
}
|
||||
// [BB] Added model flags reading.
|
||||
else if (sc.Compare("ignoretranslation"))
|
||||
{
|
||||
smf.flags |= MDL_IGNORETRANSLATION;
|
||||
}
|
||||
else if (sc.Compare("pitchfrommomentum"))
|
||||
{
|
||||
smf.flags |= MDL_PITCHFROMMOMENTUM;
|
||||
}
|
||||
else if (sc.Compare("inheritactorpitch"))
|
||||
{
|
||||
smf.flags |= MDL_USEACTORPITCH | MDL_BADROTATION;
|
||||
}
|
||||
else if (sc.Compare("inheritactorroll"))
|
||||
{
|
||||
smf.flags |= MDL_USEACTORROLL;
|
||||
}
|
||||
else if (sc.Compare("useactorpitch"))
|
||||
{
|
||||
smf.flags |= MDL_USEACTORPITCH;
|
||||
}
|
||||
else if (sc.Compare("useactorroll"))
|
||||
{
|
||||
smf.flags |= MDL_USEACTORROLL;
|
||||
}
|
||||
else if (sc.Compare("rotating"))
|
||||
{
|
||||
smf.flags |= MDL_ROTATING;
|
||||
smf.xrotate = 0.;
|
||||
smf.yrotate = 1.;
|
||||
smf.zrotate = 0.;
|
||||
smf.rotationCenterX = 0.;
|
||||
smf.rotationCenterY = 0.;
|
||||
smf.rotationCenterZ = 0.;
|
||||
smf.rotationSpeed = 1.;
|
||||
}
|
||||
else if (sc.Compare("rotation-speed"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
smf.rotationSpeed = sc.Float;
|
||||
}
|
||||
else if (sc.Compare("rotation-vector"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
smf.xrotate = sc.Float;
|
||||
sc.MustGetFloat();
|
||||
smf.yrotate = sc.Float;
|
||||
sc.MustGetFloat();
|
||||
smf.zrotate = sc.Float;
|
||||
}
|
||||
else if (sc.Compare("rotation-center"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
smf.rotationCenterX = sc.Float;
|
||||
sc.MustGetFloat();
|
||||
smf.rotationCenterY = sc.Float;
|
||||
sc.MustGetFloat();
|
||||
smf.rotationCenterZ = sc.Float;
|
||||
}
|
||||
else if (sc.Compare("interpolatedoubledframes"))
|
||||
{
|
||||
smf.flags |= MDL_INTERPOLATEDOUBLEDFRAMES;
|
||||
}
|
||||
else if (sc.Compare("nointerpolation"))
|
||||
{
|
||||
smf.flags |= MDL_NOINTERPOLATION;
|
||||
}
|
||||
else if (sc.Compare("skin"))
|
||||
{
|
||||
sc.MustGetNumber();
|
||||
index=sc.Number;
|
||||
if (index<0 || index>=MAX_MODELS_PER_FRAME)
|
||||
{
|
||||
sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars());
|
||||
}
|
||||
sc.MustGetString();
|
||||
FixPathSeperator(sc.String);
|
||||
if (sc.Compare(""))
|
||||
{
|
||||
smf.skinIDs[index]=FNullTextureID();
|
||||
}
|
||||
else
|
||||
{
|
||||
smf.skinIDs[index] = LoadSkin(path.GetChars(), sc.String);
|
||||
if (!smf.skinIDs[index].isValid())
|
||||
{
|
||||
Printf("Skin '%s' not found in '%s'\n",
|
||||
sc.String, smf.type->TypeName.GetChars());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("surfaceskin"))
|
||||
{
|
||||
sc.MustGetNumber();
|
||||
index = sc.Number;
|
||||
sc.MustGetNumber();
|
||||
surface = sc.Number;
|
||||
|
||||
if (index<0 || index >= MAX_MODELS_PER_FRAME)
|
||||
{
|
||||
sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars());
|
||||
}
|
||||
|
||||
if (surface<0 || surface >= MD3_MAX_SURFACES)
|
||||
{
|
||||
sc.ScriptError("Invalid MD3 Surface %d in %s", MD3_MAX_SURFACES, smf.type->TypeName.GetChars());
|
||||
}
|
||||
|
||||
sc.MustGetString();
|
||||
FixPathSeperator(sc.String);
|
||||
if (sc.Compare(""))
|
||||
{
|
||||
smf.surfaceskinIDs[index][surface] = FNullTextureID();
|
||||
}
|
||||
else
|
||||
{
|
||||
smf.surfaceskinIDs[index][surface] = LoadSkin(path.GetChars(), sc.String);
|
||||
if (!smf.surfaceskinIDs[index][surface].isValid())
|
||||
{
|
||||
Printf("Surface Skin '%s' not found in '%s'\n",
|
||||
sc.String, smf.type->TypeName.GetChars());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("frameindex") || sc.Compare("frame"))
|
||||
{
|
||||
bool isframe=!!sc.Compare("frame");
|
||||
|
||||
sc.MustGetString();
|
||||
smf.sprite = -1;
|
||||
for (i = 0; i < (int)sprites.Size (); ++i)
|
||||
{
|
||||
if (strnicmp (sprites[i].name, sc.String, 4) == 0)
|
||||
{
|
||||
if (sprites[i].numframes==0)
|
||||
{
|
||||
//sc.ScriptError("Sprite %s has no frames", sc.String);
|
||||
}
|
||||
smf.sprite = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (smf.sprite==-1)
|
||||
{
|
||||
sc.ScriptError("Unknown sprite %s in model definition for %s", sc.String, smf.type->TypeName.GetChars());
|
||||
}
|
||||
|
||||
sc.MustGetString();
|
||||
FString framechars = sc.String;
|
||||
|
||||
sc.MustGetNumber();
|
||||
index=sc.Number;
|
||||
if (index<0 || index>=MAX_MODELS_PER_FRAME)
|
||||
{
|
||||
sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars());
|
||||
}
|
||||
if (isframe)
|
||||
{
|
||||
sc.MustGetString();
|
||||
if (smf.modelIDs[index] != -1)
|
||||
{
|
||||
FModel *model = Models[smf.modelIDs[index]];
|
||||
smf.modelframes[index] = model->FindFrame(sc.String);
|
||||
if (smf.modelframes[index]==-1) sc.ScriptError("Unknown frame '%s' in %s", sc.String, smf.type->TypeName.GetChars());
|
||||
}
|
||||
else smf.modelframes[index] = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.MustGetNumber();
|
||||
smf.modelframes[index] = sc.Number;
|
||||
}
|
||||
|
||||
for(i=0; framechars[i]>0; i++)
|
||||
{
|
||||
char map[29]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
int c = toupper(framechars[i])-'A';
|
||||
|
||||
if (c<0 || c>=29)
|
||||
{
|
||||
sc.ScriptError("Invalid frame character %c found", c+'A');
|
||||
}
|
||||
if (map[c]) continue;
|
||||
smf.frame=c;
|
||||
SpriteModelFrames.Push(smf);
|
||||
GetDefaultByType(smf.type)->hasmodel = true;
|
||||
map[c]=1;
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("dontcullbackfaces"))
|
||||
{
|
||||
smf.flags |= MDL_DONTCULLBACKFACES;
|
||||
}
|
||||
else if (sc.Compare("userotationcenter"))
|
||||
{
|
||||
smf.flags |= MDL_USEROTATIONCENTER;
|
||||
smf.rotationCenterX = 0.;
|
||||
smf.rotationCenterY = 0.;
|
||||
smf.rotationCenterZ = 0.;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.ScriptMessage("Unrecognized string \"%s\"", sc.String);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ParseModelDefLump(Lump);
|
||||
}
|
||||
|
||||
// create a hash table for quick access
|
||||
|
@ -842,7 +539,7 @@ void gl_InitModels()
|
|||
atterm(DeleteModelHash);
|
||||
memset(SpriteModelHash, 0xff, SpriteModelFrames.Size () * sizeof(int));
|
||||
|
||||
for (i = 0; i < (int)SpriteModelFrames.Size (); i++)
|
||||
for (unsigned int i = 0; i < SpriteModelFrames.Size (); i++)
|
||||
{
|
||||
int j = ModelFrameHash(&SpriteModelFrames[i]) % SpriteModelFrames.Size ();
|
||||
|
||||
|
@ -851,13 +548,327 @@ void gl_InitModels()
|
|||
}
|
||||
}
|
||||
|
||||
static void ParseModelDefLump(int Lump)
|
||||
{
|
||||
FScanner sc(Lump);
|
||||
while (sc.GetString())
|
||||
{
|
||||
if (sc.Compare("model"))
|
||||
{
|
||||
int index, surface;
|
||||
FString path = "";
|
||||
sc.MustGetString();
|
||||
|
||||
FSpriteModelFrame smf;
|
||||
memset(&smf, 0, sizeof(smf));
|
||||
smf.modelIDs[0] = smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1;
|
||||
smf.xscale=smf.yscale=smf.zscale=1.f;
|
||||
|
||||
smf.type = PClass::FindClass(sc.String);
|
||||
if (!smf.type || smf.type->Defaults == nullptr)
|
||||
{
|
||||
sc.ScriptError("MODELDEF: Unknown actor type '%s'\n", sc.String);
|
||||
}
|
||||
sc.MustGetStringName("{");
|
||||
while (!sc.CheckString("}"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
if (sc.Compare("path"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
FixPathSeperator(sc.String);
|
||||
path = sc.String;
|
||||
if (path[(int)path.Len()-1]!='/') path+='/';
|
||||
}
|
||||
else if (sc.Compare("model"))
|
||||
{
|
||||
sc.MustGetNumber();
|
||||
index = sc.Number;
|
||||
if (index < 0 || index >= MAX_MODELS_PER_FRAME)
|
||||
{
|
||||
sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars());
|
||||
}
|
||||
sc.MustGetString();
|
||||
FixPathSeperator(sc.String);
|
||||
smf.modelIDs[index] = FindModel(path.GetChars(), sc.String);
|
||||
if (smf.modelIDs[index] == -1)
|
||||
{
|
||||
Printf("%s: model not found in %s\n", sc.String, path.GetChars());
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("scale"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
smf.xscale = sc.Float;
|
||||
sc.MustGetFloat();
|
||||
smf.yscale = sc.Float;
|
||||
sc.MustGetFloat();
|
||||
smf.zscale = sc.Float;
|
||||
}
|
||||
// [BB] Added zoffset reading.
|
||||
// Now it must be considered deprecated.
|
||||
else if (sc.Compare("zoffset"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
smf.zoffset=sc.Float;
|
||||
}
|
||||
// Offset reading.
|
||||
else if (sc.Compare("offset"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
smf.xoffset = sc.Float;
|
||||
sc.MustGetFloat();
|
||||
smf.yoffset = sc.Float;
|
||||
sc.MustGetFloat();
|
||||
smf.zoffset = sc.Float;
|
||||
}
|
||||
// angleoffset, pitchoffset and rolloffset reading.
|
||||
else if (sc.Compare("angleoffset"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
smf.angleoffset = sc.Float;
|
||||
}
|
||||
else if (sc.Compare("pitchoffset"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
smf.pitchoffset = sc.Float;
|
||||
}
|
||||
else if (sc.Compare("rolloffset"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
smf.rolloffset = sc.Float;
|
||||
}
|
||||
// [BB] Added model flags reading.
|
||||
else if (sc.Compare("ignoretranslation"))
|
||||
{
|
||||
smf.flags |= MDL_IGNORETRANSLATION;
|
||||
}
|
||||
else if (sc.Compare("pitchfrommomentum"))
|
||||
{
|
||||
smf.flags |= MDL_PITCHFROMMOMENTUM;
|
||||
}
|
||||
else if (sc.Compare("inheritactorpitch"))
|
||||
{
|
||||
smf.flags |= MDL_USEACTORPITCH | MDL_BADROTATION;
|
||||
}
|
||||
else if (sc.Compare("inheritactorroll"))
|
||||
{
|
||||
smf.flags |= MDL_USEACTORROLL;
|
||||
}
|
||||
else if (sc.Compare("useactorpitch"))
|
||||
{
|
||||
smf.flags |= MDL_USEACTORPITCH;
|
||||
}
|
||||
else if (sc.Compare("useactorroll"))
|
||||
{
|
||||
smf.flags |= MDL_USEACTORROLL;
|
||||
}
|
||||
else if (sc.Compare("rotating"))
|
||||
{
|
||||
smf.flags |= MDL_ROTATING;
|
||||
smf.xrotate = 0.;
|
||||
smf.yrotate = 1.;
|
||||
smf.zrotate = 0.;
|
||||
smf.rotationCenterX = 0.;
|
||||
smf.rotationCenterY = 0.;
|
||||
smf.rotationCenterZ = 0.;
|
||||
smf.rotationSpeed = 1.;
|
||||
}
|
||||
else if (sc.Compare("rotation-speed"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
smf.rotationSpeed = sc.Float;
|
||||
}
|
||||
else if (sc.Compare("rotation-vector"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
smf.xrotate = sc.Float;
|
||||
sc.MustGetFloat();
|
||||
smf.yrotate = sc.Float;
|
||||
sc.MustGetFloat();
|
||||
smf.zrotate = sc.Float;
|
||||
}
|
||||
else if (sc.Compare("rotation-center"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
smf.rotationCenterX = sc.Float;
|
||||
sc.MustGetFloat();
|
||||
smf.rotationCenterY = sc.Float;
|
||||
sc.MustGetFloat();
|
||||
smf.rotationCenterZ = sc.Float;
|
||||
}
|
||||
else if (sc.Compare("interpolatedoubledframes"))
|
||||
{
|
||||
smf.flags |= MDL_INTERPOLATEDOUBLEDFRAMES;
|
||||
}
|
||||
else if (sc.Compare("nointerpolation"))
|
||||
{
|
||||
smf.flags |= MDL_NOINTERPOLATION;
|
||||
}
|
||||
else if (sc.Compare("skin"))
|
||||
{
|
||||
sc.MustGetNumber();
|
||||
index=sc.Number;
|
||||
if (index<0 || index>=MAX_MODELS_PER_FRAME)
|
||||
{
|
||||
sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars());
|
||||
}
|
||||
sc.MustGetString();
|
||||
FixPathSeperator(sc.String);
|
||||
if (sc.Compare(""))
|
||||
{
|
||||
smf.skinIDs[index]=FNullTextureID();
|
||||
}
|
||||
else
|
||||
{
|
||||
smf.skinIDs[index] = LoadSkin(path.GetChars(), sc.String);
|
||||
if (!smf.skinIDs[index].isValid())
|
||||
{
|
||||
Printf("Skin '%s' not found in '%s'\n",
|
||||
sc.String, smf.type->TypeName.GetChars());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("surfaceskin"))
|
||||
{
|
||||
sc.MustGetNumber();
|
||||
index = sc.Number;
|
||||
sc.MustGetNumber();
|
||||
surface = sc.Number;
|
||||
|
||||
if (index<0 || index >= MAX_MODELS_PER_FRAME)
|
||||
{
|
||||
sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars());
|
||||
}
|
||||
|
||||
if (surface<0 || surface >= MD3_MAX_SURFACES)
|
||||
{
|
||||
sc.ScriptError("Invalid MD3 Surface %d in %s", MD3_MAX_SURFACES, smf.type->TypeName.GetChars());
|
||||
}
|
||||
|
||||
sc.MustGetString();
|
||||
FixPathSeperator(sc.String);
|
||||
if (sc.Compare(""))
|
||||
{
|
||||
smf.surfaceskinIDs[index][surface] = FNullTextureID();
|
||||
}
|
||||
else
|
||||
{
|
||||
smf.surfaceskinIDs[index][surface] = LoadSkin(path.GetChars(), sc.String);
|
||||
if (!smf.surfaceskinIDs[index][surface].isValid())
|
||||
{
|
||||
Printf("Surface Skin '%s' not found in '%s'\n",
|
||||
sc.String, smf.type->TypeName.GetChars());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("frameindex") || sc.Compare("frame"))
|
||||
{
|
||||
bool isframe=!!sc.Compare("frame");
|
||||
|
||||
sc.MustGetString();
|
||||
smf.sprite = -1;
|
||||
for (int i = 0; i < (int)sprites.Size (); ++i)
|
||||
{
|
||||
if (strnicmp (sprites[i].name, sc.String, 4) == 0)
|
||||
{
|
||||
if (sprites[i].numframes==0)
|
||||
{
|
||||
//sc.ScriptError("Sprite %s has no frames", sc.String);
|
||||
}
|
||||
smf.sprite = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (smf.sprite==-1)
|
||||
{
|
||||
sc.ScriptError("Unknown sprite %s in model definition for %s", sc.String, smf.type->TypeName.GetChars());
|
||||
}
|
||||
|
||||
sc.MustGetString();
|
||||
FString framechars = sc.String;
|
||||
|
||||
sc.MustGetNumber();
|
||||
index=sc.Number;
|
||||
if (index<0 || index>=MAX_MODELS_PER_FRAME)
|
||||
{
|
||||
sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars());
|
||||
}
|
||||
if (isframe)
|
||||
{
|
||||
sc.MustGetString();
|
||||
if (smf.modelIDs[index] != -1)
|
||||
{
|
||||
FModel *model = Models[smf.modelIDs[index]];
|
||||
smf.modelframes[index] = model->FindFrame(sc.String);
|
||||
if (smf.modelframes[index]==-1) sc.ScriptError("Unknown frame '%s' in %s", sc.String, smf.type->TypeName.GetChars());
|
||||
}
|
||||
else smf.modelframes[index] = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.MustGetNumber();
|
||||
smf.modelframes[index] = sc.Number;
|
||||
}
|
||||
|
||||
for(int i=0; framechars[i]>0; i++)
|
||||
{
|
||||
char map[29]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
int c = toupper(framechars[i])-'A';
|
||||
|
||||
if (c<0 || c>=29)
|
||||
{
|
||||
sc.ScriptError("Invalid frame character %c found", c+'A');
|
||||
}
|
||||
if (map[c]) continue;
|
||||
smf.frame=c;
|
||||
SpriteModelFrames.Push(smf);
|
||||
GetDefaultByType(smf.type)->hasmodel = true;
|
||||
map[c]=1;
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("dontcullbackfaces"))
|
||||
{
|
||||
smf.flags |= MDL_DONTCULLBACKFACES;
|
||||
}
|
||||
else if (sc.Compare("userotationcenter"))
|
||||
{
|
||||
smf.flags |= MDL_USEROTATIONCENTER;
|
||||
smf.rotationCenterX = 0.;
|
||||
smf.rotationCenterY = 0.;
|
||||
smf.rotationCenterZ = 0.;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.ScriptMessage("Unrecognized string \"%s\"", sc.String);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("#include"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
// This is not using sc.Open because it can print a more useful error message when done here
|
||||
int includelump = Wads.CheckNumForFullName(sc.String, true);
|
||||
if (includelump == -1)
|
||||
{
|
||||
if (strcmp(sc.String, "sentinel.modl") != 0) // Gene Tech mod has a broken #include statement
|
||||
sc.ScriptError("Lump '%s' not found", sc.String);
|
||||
}
|
||||
else
|
||||
{
|
||||
ParseModelDefLump(includelump);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// gl_FindModelFrame
|
||||
// FindModelFrame
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
FSpriteModelFrame * gl_FindModelFrame(const PClass * ti, int sprite, int frame, bool dropped)
|
||||
FSpriteModelFrame * FindModelFrame(const PClass * ti, int sprite, int frame, bool dropped)
|
||||
{
|
||||
if (GetDefaultByType(ti)->hasmodel)
|
||||
{
|
||||
|
@ -898,11 +909,11 @@ FSpriteModelFrame * gl_FindModelFrame(const PClass * ti, int sprite, int frame,
|
|||
|
||||
//===========================================================================
|
||||
//
|
||||
// gl_IsHUDModelForPlayerAvailable
|
||||
// IsHUDModelForPlayerAvailable
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
bool gl_IsHUDModelForPlayerAvailable (player_t * player)
|
||||
bool IsHUDModelForPlayerAvailable (player_t * player)
|
||||
{
|
||||
if (player == nullptr || player->ReadyWeapon == nullptr)
|
||||
return false;
|
||||
|
@ -913,7 +924,7 @@ bool gl_IsHUDModelForPlayerAvailable (player_t * player)
|
|||
return false;
|
||||
|
||||
FState* state = psp->GetState();
|
||||
FSpriteModelFrame *smf = gl_FindModelFrame(player->ReadyWeapon->GetClass(), state->sprite, state->GetFrame(), false);
|
||||
FSpriteModelFrame *smf = FindModelFrame(player->ReadyWeapon->GetClass(), state->sprite, state->GetFrame(), false);
|
||||
return ( smf != nullptr );
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,14 @@ FTextureID LoadSkin(const char * path, const char * fn);
|
|||
struct FSpriteModelFrame;
|
||||
class IModelVertexBuffer;
|
||||
|
||||
enum ModelRendererType
|
||||
{
|
||||
GLModelRendererType,
|
||||
SWModelRendererType,
|
||||
PolyModelRendererType,
|
||||
NumModelRendererTypes
|
||||
};
|
||||
|
||||
class FModelRenderer
|
||||
{
|
||||
public:
|
||||
|
@ -54,6 +62,8 @@ public:
|
|||
void RenderModel(float x, float y, float z, FSpriteModelFrame *modelframe, AActor *actor);
|
||||
void RenderHUDModel(DPSprite *psp, float ofsx, float ofsy);
|
||||
|
||||
virtual ModelRendererType GetType() const = 0;
|
||||
|
||||
virtual void BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix) = 0;
|
||||
virtual void EndDrawModel(AActor *actor, FSpriteModelFrame *smf) = 0;
|
||||
|
||||
|
@ -73,8 +83,7 @@ public:
|
|||
virtual void DrawElements(int numIndices, size_t offset) = 0;
|
||||
|
||||
private:
|
||||
void RenderFrameModels(const FSpriteModelFrame *smf, const FState *curState, const int curTics, const PClass *ti, Matrix3x4 *normaltransform, int translation);
|
||||
static double GetTimeFloat();
|
||||
void RenderFrameModels(const FSpriteModelFrame *smf, const FState *curState, const int curTics, const PClass *ti, int translation);
|
||||
};
|
||||
|
||||
struct FModelVertex
|
||||
|
@ -123,11 +132,7 @@ public:
|
|||
class FModel
|
||||
{
|
||||
public:
|
||||
|
||||
FModel()
|
||||
{
|
||||
mVBuf = NULL;
|
||||
}
|
||||
FModel();
|
||||
virtual ~FModel();
|
||||
|
||||
virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length) = 0;
|
||||
|
@ -135,19 +140,20 @@ public:
|
|||
virtual void RenderFrame(FModelRenderer *renderer, FTexture * skin, int frame, int frame2, double inter, int translation=0) = 0;
|
||||
virtual void BuildVertexBuffer(FModelRenderer *renderer) = 0;
|
||||
virtual void AddSkins(uint8_t *hitlist) = 0;
|
||||
void DestroyVertexBuffer()
|
||||
{
|
||||
delete mVBuf;
|
||||
mVBuf = NULL;
|
||||
}
|
||||
virtual float getAspectFactor() { return 1.f; }
|
||||
|
||||
void SetVertexBuffer(FModelRenderer *renderer, IModelVertexBuffer *buffer) { mVBuf[renderer->GetType()] = buffer; }
|
||||
IModelVertexBuffer *GetVertexBuffer(FModelRenderer *renderer) const { return mVBuf[renderer->GetType()]; }
|
||||
void DestroyVertexBuffer();
|
||||
|
||||
const FSpriteModelFrame *curSpriteMDLFrame;
|
||||
int curMDLIndex;
|
||||
void PushSpriteMDLFrame(const FSpriteModelFrame *smf, int index) { curSpriteMDLFrame = smf; curMDLIndex = index; };
|
||||
|
||||
IModelVertexBuffer *mVBuf;
|
||||
FString mFileName;
|
||||
|
||||
private:
|
||||
IModelVertexBuffer *mVBuf[NumModelRendererTypes];
|
||||
};
|
||||
|
||||
class FDMDModel : public FModel
|
||||
|
@ -473,9 +479,9 @@ struct FSpriteModelFrame
|
|||
float pitchoffset, rolloffset; // I don't want to bother with type transformations, so I made this variables float.
|
||||
};
|
||||
|
||||
FSpriteModelFrame * gl_FindModelFrame(const PClass * ti, int sprite, int frame, bool dropped);
|
||||
|
||||
bool gl_IsHUDModelForPlayerAvailable (player_t * player);
|
||||
FSpriteModelFrame * FindModelFrame(const PClass * ti, int sprite, int frame, bool dropped);
|
||||
bool IsHUDModelForPlayerAvailable(player_t * player);
|
||||
void FlushModels();
|
||||
|
||||
class DeletingModelArray : public TArray<FModel *>
|
||||
{
|
||||
|
|
|
@ -279,15 +279,17 @@ FDMDModel::~FDMDModel()
|
|||
|
||||
void FDMDModel::BuildVertexBuffer(FModelRenderer *renderer)
|
||||
{
|
||||
if (mVBuf == NULL)
|
||||
if (!GetVertexBuffer(renderer))
|
||||
{
|
||||
LoadGeometry();
|
||||
|
||||
int VertexBufferSize = info.numFrames * lodInfo[0].numTriangles * 3;
|
||||
unsigned int vindex = 0;
|
||||
|
||||
mVBuf = renderer->CreateVertexBuffer(false, info.numFrames == 1);
|
||||
FModelVertex *vertptr = mVBuf->LockVertexBuffer(VertexBufferSize);
|
||||
auto vbuf = renderer->CreateVertexBuffer(false, info.numFrames == 1);
|
||||
SetVertexBuffer(renderer, vbuf);
|
||||
|
||||
FModelVertex *vertptr = vbuf->LockVertexBuffer(VertexBufferSize);
|
||||
|
||||
for (int i = 0; i < info.numFrames; i++)
|
||||
{
|
||||
|
@ -313,7 +315,7 @@ void FDMDModel::BuildVertexBuffer(FModelRenderer *renderer)
|
|||
tri++;
|
||||
}
|
||||
}
|
||||
mVBuf->UnlockVertexBuffer();
|
||||
vbuf->UnlockVertexBuffer();
|
||||
UnloadGeometry();
|
||||
}
|
||||
}
|
||||
|
@ -368,7 +370,7 @@ void FDMDModel::RenderFrame(FModelRenderer *renderer, FTexture * skin, int frame
|
|||
|
||||
renderer->SetInterpolation(inter);
|
||||
renderer->SetMaterial(skin, false, translation);
|
||||
mVBuf->SetupFrame(renderer, frames[frameno].vindex, frames[frameno2].vindex, lodInfo[0].numTriangles * 3);
|
||||
GetVertexBuffer(renderer)->SetupFrame(renderer, frames[frameno].vindex, frames[frameno2].vindex, lodInfo[0].numTriangles * 3);
|
||||
renderer->DrawArrays(0, lodInfo[0].numTriangles * 3);
|
||||
renderer->SetInterpolation(0.f);
|
||||
}
|
||||
|
|
|
@ -237,7 +237,7 @@ void FMD3Model::LoadGeometry()
|
|||
|
||||
void FMD3Model::BuildVertexBuffer(FModelRenderer *renderer)
|
||||
{
|
||||
if (mVBuf == nullptr)
|
||||
if (!GetVertexBuffer(renderer))
|
||||
{
|
||||
LoadGeometry();
|
||||
|
||||
|
@ -251,9 +251,11 @@ void FMD3Model::BuildVertexBuffer(FModelRenderer *renderer)
|
|||
ibufsize += 3 * surf->numTriangles;
|
||||
}
|
||||
|
||||
mVBuf = renderer->CreateVertexBuffer(true, numFrames == 1);
|
||||
FModelVertex *vertptr = mVBuf->LockVertexBuffer(vbufsize);
|
||||
unsigned int *indxptr = mVBuf->LockIndexBuffer(ibufsize);
|
||||
auto vbuf = renderer->CreateVertexBuffer(true, numFrames == 1);
|
||||
SetVertexBuffer(renderer, vbuf);
|
||||
|
||||
FModelVertex *vertptr = vbuf->LockVertexBuffer(vbufsize);
|
||||
unsigned int *indxptr = vbuf->LockIndexBuffer(ibufsize);
|
||||
|
||||
assert(vertptr != nullptr && indxptr != nullptr);
|
||||
|
||||
|
@ -285,8 +287,8 @@ void FMD3Model::BuildVertexBuffer(FModelRenderer *renderer)
|
|||
}
|
||||
surf->UnloadGeometry();
|
||||
}
|
||||
mVBuf->UnlockVertexBuffer();
|
||||
mVBuf->UnlockIndexBuffer();
|
||||
vbuf->UnlockVertexBuffer();
|
||||
vbuf->UnlockIndexBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -365,7 +367,7 @@ void FMD3Model::RenderFrame(FModelRenderer *renderer, FTexture * skin, int frame
|
|||
}
|
||||
|
||||
renderer->SetMaterial(surfaceSkin, false, translation);
|
||||
mVBuf->SetupFrame(renderer, surf->vindex + frameno * surf->numVertices, surf->vindex + frameno2 * surf->numVertices, surf->numVertices);
|
||||
GetVertexBuffer(renderer)->SetupFrame(renderer, surf->vindex + frameno * surf->numVertices, surf->vindex + frameno2 * surf->numVertices, surf->numVertices);
|
||||
renderer->DrawElements(surf->numTriangles * 3, surf->iindex * sizeof(unsigned int));
|
||||
}
|
||||
renderer->SetInterpolation(0.f);
|
||||
|
|
|
@ -46,7 +46,7 @@ bool FUE1Model::Load( const char *filename, int lumpnum, const char *buffer, int
|
|||
FMemLump lump2;
|
||||
const char *buffer2;
|
||||
FString realfilename = Wads.GetLumpFullName(lumpnum);
|
||||
if ( realfilename.IndexOf("_d.3d") == realfilename.Len()-5 )
|
||||
if ( (size_t)realfilename.IndexOf("_d.3d") == realfilename.Len()-5 )
|
||||
{
|
||||
realfilename.Substitute("_d.3d","_a.3d");
|
||||
lumpnum2 = Wads.CheckNumForFullName(realfilename);
|
||||
|
@ -98,9 +98,9 @@ void FUE1Model::LoadGeometry()
|
|||
{
|
||||
UE1Vertex Vert;
|
||||
// unpack position
|
||||
Vert.Pos.X = unpackuvert(averts[j+i*numVerts],0);
|
||||
Vert.Pos.Y = unpackuvert(averts[j+i*numVerts],1);
|
||||
Vert.Pos.Z = unpackuvert(averts[j+i*numVerts],2);
|
||||
Vert.Pos = FVector3(unpackuvert(averts[j+i*numVerts],0),
|
||||
unpackuvert(averts[j+i*numVerts],1),
|
||||
unpackuvert(averts[j+i*numVerts],2));
|
||||
// push vertex (without normals, will be calculated later)
|
||||
verts.Push(Vert);
|
||||
}
|
||||
|
@ -114,10 +114,7 @@ void FUE1Model::LoadGeometry()
|
|||
Poly.V[j] = dpolys[i].vertices[j];
|
||||
// unpack coords
|
||||
for ( int j=0; j<3; j++ )
|
||||
{
|
||||
Poly.C[j].S = dpolys[i].uv[j][0]/255.f;
|
||||
Poly.C[j].T = dpolys[i].uv[j][1]/255.f;
|
||||
}
|
||||
Poly.C[j] = FVector2(dpolys[i].uv[j][0]/255.f,dpolys[i].uv[j][1]/255.f);
|
||||
Poly.texNum = dpolys[i].texnum;
|
||||
// push
|
||||
polys.Push(Poly);
|
||||
|
@ -129,39 +126,22 @@ void FUE1Model::LoadGeometry()
|
|||
{
|
||||
for ( int j=0; j<numVerts; j++ )
|
||||
{
|
||||
UE1Vector nsum = {0,0,0};
|
||||
float total = 0.;
|
||||
FVector3 nsum = FVector3(0,0,0);
|
||||
for ( int k=0; k<numPolys; k++ )
|
||||
{
|
||||
if ( (polys[k].V[0] != j) && (polys[k].V[1] != j) && (polys[k].V[2] != j) ) continue;
|
||||
UE1Vector vert[3], dir[2], norm;
|
||||
FVector3 vert[3], dir[2], norm;
|
||||
// compute facet normal
|
||||
for ( int l=0; l<3; l++ )
|
||||
vert[l] = verts[polys[k].V[l]+numVerts*i].Pos;
|
||||
dir[0].X = vert[1].X-vert[0].X;
|
||||
dir[0].Y = vert[1].Y-vert[0].Y;
|
||||
dir[0].Z = vert[1].Z-vert[0].Z;
|
||||
dir[1].X = vert[2].X-vert[0].X;
|
||||
dir[1].Y = vert[2].Y-vert[0].Y;
|
||||
dir[1].Z = vert[2].Z-vert[0].Z;
|
||||
norm.X = dir[0].Y*dir[1].Z-dir[0].Z*dir[1].Y;
|
||||
norm.Y = dir[0].Z*dir[1].X-dir[0].X*dir[1].Z;
|
||||
norm.Z = dir[0].X*dir[1].Y-dir[0].Y*dir[1].X;
|
||||
float s = (float)sqrt(norm.X*norm.X+norm.Y*norm.Y+norm.Z*norm.Z);
|
||||
if ( s != 0.f )
|
||||
{
|
||||
norm.X /= s;
|
||||
norm.Y /= s;
|
||||
norm.Z /= s;
|
||||
}
|
||||
nsum.X += norm.X;
|
||||
nsum.Y += norm.Y;
|
||||
nsum.Z += norm.Z;
|
||||
total+=1.f;
|
||||
dir[0] = vert[1]-vert[0];
|
||||
dir[1] = vert[2]-vert[0];
|
||||
dir[0].MakeUnit();
|
||||
dir[1].MakeUnit();
|
||||
norm = dir[0]^dir[1];
|
||||
nsum += norm.Unit();
|
||||
}
|
||||
verts[j+numVerts*i].Normal.X = nsum.X/total;
|
||||
verts[j+numVerts*i].Normal.Y = nsum.Y/total;
|
||||
verts[j+numVerts*i].Normal.Z = nsum.Z/total;
|
||||
verts[j+numVerts*i].Normal = nsum.Unit();
|
||||
}
|
||||
}
|
||||
// populate skin groups
|
||||
|
@ -218,7 +198,7 @@ void FUE1Model::RenderFrame( FModelRenderer *renderer, FTexture *skin, int frame
|
|||
}
|
||||
}
|
||||
renderer->SetMaterial(sskin,false,translation);
|
||||
mVBuf->SetupFrame(renderer,vofs+frame*fsize,vofs+frame2*fsize,vsize);
|
||||
GetVertexBuffer(renderer)->SetupFrame(renderer,vofs+frame*fsize,vofs+frame2*fsize,vsize);
|
||||
renderer->DrawArrays(0,vsize);
|
||||
vofs += vsize;
|
||||
}
|
||||
|
@ -227,14 +207,15 @@ void FUE1Model::RenderFrame( FModelRenderer *renderer, FTexture *skin, int frame
|
|||
|
||||
void FUE1Model::BuildVertexBuffer( FModelRenderer *renderer )
|
||||
{
|
||||
if ( mVBuf != NULL )
|
||||
if (GetVertexBuffer(renderer))
|
||||
return;
|
||||
int vsize = 0;
|
||||
for ( int i=0; i<numGroups; i++ )
|
||||
vsize += groups[i].numPolys*3;
|
||||
vsize *= numFrames;
|
||||
mVBuf = renderer->CreateVertexBuffer(false,numFrames==1);
|
||||
FModelVertex *vptr = mVBuf->LockVertexBuffer(vsize);
|
||||
auto vbuf = renderer->CreateVertexBuffer(false,numFrames==1);
|
||||
SetVertexBuffer(renderer, vbuf);
|
||||
FModelVertex *vptr = vbuf->LockVertexBuffer(vsize);
|
||||
int vidx = 0;
|
||||
for ( int i=0; i<numFrames; i++ )
|
||||
{
|
||||
|
@ -242,18 +223,18 @@ void FUE1Model::BuildVertexBuffer( FModelRenderer *renderer )
|
|||
{
|
||||
for ( int k=0; k<groups[j].numPolys; k++ )
|
||||
{
|
||||
for ( int l=0; l<3; l++ )
|
||||
for ( int l=2; l>=0; l-- )
|
||||
{
|
||||
UE1Vertex V = verts[polys[groups[j].P[k]].V[l]+i*numVerts];
|
||||
UE1Coord C = polys[groups[j].P[k]].C[l];
|
||||
FVector2 C = polys[groups[j].P[k]].C[l];
|
||||
FModelVertex *vert = &vptr[vidx++];
|
||||
vert->Set(V.Pos.X,V.Pos.Y,V.Pos.Z,C.S,C.T);
|
||||
vert->Set(V.Pos.X,V.Pos.Y,V.Pos.Z,C.X,C.Y);
|
||||
vert->SetNormal(V.Normal.X,V.Normal.Y,V.Normal.Z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mVBuf->UnlockVertexBuffer();
|
||||
vbuf->UnlockVertexBuffer();
|
||||
}
|
||||
|
||||
void FUE1Model::AddSkins( uint8_t *hitlist )
|
||||
|
|
|
@ -56,22 +56,14 @@ private:
|
|||
uint32_t * averts;
|
||||
|
||||
// converted data structures
|
||||
struct UE1Coord
|
||||
{
|
||||
float S, T;
|
||||
};
|
||||
struct UE1Vector
|
||||
{
|
||||
float X, Y, Z;
|
||||
};
|
||||
struct UE1Vertex
|
||||
{
|
||||
UE1Vector Pos, Normal;
|
||||
FVector3 Pos, Normal;
|
||||
};
|
||||
struct UE1Poly
|
||||
{
|
||||
int V[3];
|
||||
UE1Coord C[3];
|
||||
FVector2 C[3];
|
||||
int texNum;
|
||||
};
|
||||
struct UE1Group
|
||||
|
|
|
@ -321,19 +321,21 @@ void FVoxelModel::Initialize()
|
|||
|
||||
void FVoxelModel::BuildVertexBuffer(FModelRenderer *renderer)
|
||||
{
|
||||
if (mVBuf == NULL)
|
||||
if (!GetVertexBuffer(renderer))
|
||||
{
|
||||
Initialize();
|
||||
|
||||
mVBuf = renderer->CreateVertexBuffer(true, true);
|
||||
FModelVertex *vertptr = mVBuf->LockVertexBuffer(mVertices.Size());
|
||||
unsigned int *indxptr = mVBuf->LockIndexBuffer(mIndices.Size());
|
||||
auto vbuf = renderer->CreateVertexBuffer(true, true);
|
||||
SetVertexBuffer(renderer, vbuf);
|
||||
|
||||
FModelVertex *vertptr = vbuf->LockVertexBuffer(mVertices.Size());
|
||||
unsigned int *indxptr = vbuf->LockIndexBuffer(mIndices.Size());
|
||||
|
||||
memcpy(vertptr, &mVertices[0], sizeof(FModelVertex)* mVertices.Size());
|
||||
memcpy(indxptr, &mIndices[0], sizeof(unsigned int)* mIndices.Size());
|
||||
|
||||
mVBuf->UnlockVertexBuffer();
|
||||
mVBuf->UnlockIndexBuffer();
|
||||
vbuf->UnlockVertexBuffer();
|
||||
vbuf->UnlockIndexBuffer();
|
||||
mNumIndices = mIndices.Size();
|
||||
|
||||
// delete our temporary buffers
|
||||
|
@ -398,7 +400,7 @@ float FVoxelModel::getAspectFactor()
|
|||
void FVoxelModel::RenderFrame(FModelRenderer *renderer, FTexture * skin, int frame, int frame2, double inter, int translation)
|
||||
{
|
||||
renderer->SetMaterial(skin, true, translation);
|
||||
mVBuf->SetupFrame(renderer, 0, 0, 0);
|
||||
GetVertexBuffer(renderer)->SetupFrame(renderer, 0, 0, 0);
|
||||
renderer->DrawElements(mNumIndices, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include "r_data/voxels.h"
|
||||
#include "vm.h"
|
||||
|
||||
void gl_InitModels();
|
||||
void InitModels();
|
||||
|
||||
// variables used to look up
|
||||
// and range check thing_t sprites patches
|
||||
|
@ -1048,7 +1048,7 @@ void R_InitSprites ()
|
|||
// [RH] Sort the skins, but leave base as skin 0
|
||||
//qsort (&skins[PlayerClasses.Size ()], numskins-PlayerClasses.Size (), sizeof(FPlayerSkin), skinsorter);
|
||||
|
||||
gl_InitModels();
|
||||
InitModels();
|
||||
}
|
||||
|
||||
|
||||
|
|
53
src/r_defs.h
53
src/r_defs.h
|
@ -979,6 +979,12 @@ public:
|
|||
double CenterFloor() const { return floorplane.ZatPoint(centerspot); }
|
||||
double CenterCeiling() const { return ceilingplane.ZatPoint(centerspot); }
|
||||
|
||||
void CopyColors(sector_t *other)
|
||||
{
|
||||
memcpy(SpecialColors, other->SpecialColors, sizeof(SpecialColors));
|
||||
Colormap = other->Colormap;
|
||||
}
|
||||
|
||||
// [RH] store floor and ceiling planes instead of heights
|
||||
secplane_t floorplane, ceilingplane;
|
||||
|
||||
|
@ -986,26 +992,6 @@ public:
|
|||
PalEntry SpecialColors[5];
|
||||
FColormap Colormap;
|
||||
|
||||
private:
|
||||
FDynamicColormap *_ColorMap; // [RH] Per-sector colormap
|
||||
|
||||
public:
|
||||
// just a helper for refactoring
|
||||
FDynamicColormap *GetColorMap()
|
||||
{
|
||||
return _ColorMap;
|
||||
}
|
||||
|
||||
void CopyColors(sector_t *other)
|
||||
{
|
||||
memcpy(SpecialColors, other->SpecialColors, sizeof(SpecialColors));
|
||||
Colormap = other->Colormap;
|
||||
|
||||
_ColorMap = other->_ColorMap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
TObjPtr<AActor*> SoundTarget;
|
||||
|
||||
short special;
|
||||
|
@ -1101,9 +1087,11 @@ public:
|
|||
vbo_fakeceiling = ceiling+2,
|
||||
};
|
||||
|
||||
int vboindex[4]; // VBO indices of the 4 planes this sector uses during rendering
|
||||
int vboindex[4]; // VBO indices of the 4 planes this sector uses during rendering. This is only needed for updating plane heights.
|
||||
int iboindex[4]; // IBO indices of the 4 planes this sector uses during rendering
|
||||
double vboheight[2]; // Last calculated height for the 2 planes of this actual sector
|
||||
int vbocount[2]; // Total count of vertices belonging to this sector's planes
|
||||
int vbocount[2]; // Total count of vertices belonging to this sector's planes. This is used when a sector height changes and also contains all attached planes.
|
||||
int ibocount; // number of indices per plane (identical for all planes.) If this is -1 the index buffer is not in use.
|
||||
|
||||
float GetReflect(int pos) { return gl_plane_reflection_i? reflect[pos] : 0; }
|
||||
bool VBOHeightcheck(int pos) const { return vboheight[pos] == GetPlaneTexZ(pos); }
|
||||
|
@ -1295,6 +1283,26 @@ struct side_t
|
|||
|
||||
};
|
||||
|
||||
enum AutomapLineStyle : int
|
||||
{
|
||||
AMLS_Default,
|
||||
AMLS_OneSided,
|
||||
AMLS_TwoSided,
|
||||
AMLS_FloorDiff,
|
||||
AMLS_CeilingDiff,
|
||||
AMLS_ExtraFloor,
|
||||
AMLS_Special,
|
||||
AMLS_Secret,
|
||||
AMLS_NotSeen,
|
||||
AMLS_Locked,
|
||||
AMLS_IntraTeleport,
|
||||
AMLS_InterTeleport,
|
||||
AMLS_UnexploredSecret,
|
||||
AMLS_Portal,
|
||||
|
||||
AMLS_COUNT
|
||||
};
|
||||
|
||||
struct line_t
|
||||
{
|
||||
vertex_t *v1, *v2; // vertices, from v1 to v2
|
||||
|
@ -1311,6 +1319,7 @@ struct line_t
|
|||
int locknumber; // [Dusk] lock number for special
|
||||
unsigned portalindex;
|
||||
unsigned portaltransferred;
|
||||
AutomapLineStyle automapstyle;
|
||||
|
||||
DVector2 Delta() const
|
||||
{
|
||||
|
|
|
@ -962,7 +962,7 @@ namespace swrenderer
|
|||
{
|
||||
int spritenum = thing->sprite;
|
||||
bool isPicnumOverride = thing->picnum.isValid();
|
||||
FSpriteModelFrame *modelframe = isPicnumOverride ? nullptr : gl_FindModelFrame(thing->GetClass(), spritenum, thing->frame, !!(thing->flags & MF_DROPPED));
|
||||
FSpriteModelFrame *modelframe = isPicnumOverride ? nullptr : FindModelFrame(thing->GetClass(), spritenum, thing->frame, !!(thing->flags & MF_DROPPED));
|
||||
if (modelframe && (thing->Pos() - Thread->Viewport->viewpoint.Pos).LengthSquared() < model_distance_cull)
|
||||
{
|
||||
DVector3 pos = thing->InterpolatedPosition(Thread->Viewport->viewpoint.TicFrac);
|
||||
|
|
|
@ -34,9 +34,6 @@
|
|||
#include "swrenderer/viewport/r_viewport.h"
|
||||
#include "swrenderer/scene/r_light.h"
|
||||
|
||||
void gl_FlushModels();
|
||||
extern bool polymodelsInUse;
|
||||
|
||||
namespace swrenderer
|
||||
{
|
||||
void RenderModel::Project(RenderThread *thread, float x, float y, float z, FSpriteModelFrame *smf, AActor *actor)
|
||||
|
@ -83,11 +80,6 @@ namespace swrenderer
|
|||
|
||||
SWModelRenderer::SWModelRenderer(RenderThread *thread, Fake3DTranslucent clip3DFloor) : Thread(thread), Clip3DFloor(clip3DFloor)
|
||||
{
|
||||
if (polymodelsInUse)
|
||||
{
|
||||
gl_FlushModels();
|
||||
polymodelsInUse = false;
|
||||
}
|
||||
}
|
||||
|
||||
void SWModelRenderer::BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix)
|
||||
|
@ -128,11 +120,13 @@ namespace swrenderer
|
|||
}
|
||||
|
||||
SetTransform();
|
||||
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true);
|
||||
}
|
||||
|
||||
void SWModelRenderer::EndDrawModel(AActor *actor, FSpriteModelFrame *smf)
|
||||
{
|
||||
ModelActor = nullptr;
|
||||
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false);
|
||||
}
|
||||
|
||||
IModelVertexBuffer *SWModelRenderer::CreateVertexBuffer(bool needindex, bool singleframe)
|
||||
|
@ -191,12 +185,14 @@ namespace swrenderer
|
|||
ClipBottom = {};
|
||||
SetTransform();
|
||||
PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, true);
|
||||
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, true);
|
||||
}
|
||||
|
||||
void SWModelRenderer::EndDrawHUDModel(AActor *actor)
|
||||
{
|
||||
ModelActor = nullptr;
|
||||
PolyTriangleDrawer::SetWeaponScene(Thread->DrawQueue, false);
|
||||
PolyTriangleDrawer::SetTwoSided(Thread->DrawQueue, false);
|
||||
}
|
||||
|
||||
void SWModelRenderer::SetInterpolation(double interpolation)
|
||||
|
|
|
@ -54,6 +54,8 @@ namespace swrenderer
|
|||
public:
|
||||
SWModelRenderer(RenderThread *thread, Fake3DTranslucent clip3DFloor);
|
||||
|
||||
ModelRendererType GetType() const override { return SWModelRendererType; }
|
||||
|
||||
void BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix) override;
|
||||
void EndDrawModel(AActor *actor, FSpriteModelFrame *smf) override;
|
||||
IModelVertexBuffer *CreateVertexBuffer(bool needindex, bool singleframe) override;
|
||||
|
|
|
@ -94,7 +94,7 @@ namespace swrenderer
|
|||
(r_deathcamera && Thread->Viewport->viewpoint.camera->health <= 0))
|
||||
return;
|
||||
|
||||
renderHUDModel = r_models && gl_IsHUDModelForPlayerAvailable(players[consoleplayer].camera->player);
|
||||
renderHUDModel = r_models && IsHUDModelForPlayerAvailable(players[consoleplayer].camera->player);
|
||||
|
||||
FDynamicColormap *basecolormap;
|
||||
CameraLight *cameraLight = CameraLight::Instance();
|
||||
|
|
|
@ -81,7 +81,6 @@ CUSTOM_CVAR(Bool, gl_debug, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINI
|
|||
CUSTOM_CVAR(Bool, vr_enable_quadbuffered, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
||||
{
|
||||
Printf("You must restart " GAMENAME " to switch quad stereo mode\n");
|
||||
screen->enable_quadbuffered = self;
|
||||
}
|
||||
|
||||
EXTERN_CVAR(Int, vid_refreshrate)
|
||||
|
@ -1082,6 +1081,7 @@ SystemFrameBuffer::SystemFrameBuffer(void *hMonitor, int width, int height, int
|
|||
|
||||
m_supportsGamma = !!GetDeviceGammaRamp(hDC, (void *)m_origGamma);
|
||||
ReleaseDC(Window, hDC);
|
||||
enable_quadbuffered = vr_enable_quadbuffered;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1159,10 +1159,15 @@ bool SystemFrameBuffer::IsFullscreen()
|
|||
//
|
||||
//
|
||||
//==========================================================================
|
||||
EXTERN_CVAR(Bool, vid_vsync);
|
||||
CUSTOM_CVAR(Bool, gl_control_tear, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
{
|
||||
vid_vsync.Callback();
|
||||
}
|
||||
|
||||
void SystemFrameBuffer::SetVSync (bool vsync)
|
||||
{
|
||||
if (myWglSwapIntervalExtProc != NULL) myWglSwapIntervalExtProc(vsync ? SwapInterval : 0);
|
||||
if (myWglSwapIntervalExtProc != NULL) myWglSwapIntervalExtProc(vsync ? (gl_control_tear? SwapInterval : 1) : 0);
|
||||
}
|
||||
|
||||
void SystemFrameBuffer::SwapBuffers()
|
||||
|
|
|
@ -9,6 +9,10 @@ vec3 lightContribution(int i, vec3 normal)
|
|||
float lightdistance = distance(lightpos.xyz, pixelpos.xyz);
|
||||
if (lightpos.w < lightdistance)
|
||||
return vec3(0.0); // Early out lights touching surface but not this fragment
|
||||
|
||||
vec3 lightdir = normalize(lightpos.xyz - pixelpos.xyz);
|
||||
float dotprod = dot(normal, lightdir);
|
||||
if (dotprod < 0.0) return vec3(0.0); // light hits from the backside. This can happen with full sector light lists and must be rejected for all cases.
|
||||
|
||||
float attenuation = clamp((lightpos.w - lightdistance) / lightpos.w, 0.0, 1.0);
|
||||
|
||||
|
@ -17,8 +21,7 @@ vec3 lightContribution(int i, vec3 normal)
|
|||
|
||||
if (lightcolor.a < 0.0) // Sign bit is the attenuated light flag
|
||||
{
|
||||
vec3 lightdir = normalize(lightpos.xyz - pixelpos.xyz);
|
||||
attenuation *= clamp(dot(normal, lightdir), 0.0, 1.0);
|
||||
attenuation *= clamp(dotprod, 0.0, 1.0);
|
||||
}
|
||||
|
||||
if (attenuation > 0.0) // Skip shadow map test if possible
|
||||
|
|
|
@ -12,7 +12,7 @@ struct SBarInfo native ui
|
|||
}
|
||||
|
||||
|
||||
// The sole purpose of this wrapper is to elimintate the native dependencies of the status bar object
|
||||
// The sole purpose of this wrapper is to eliminate the native dependencies of the status bar object
|
||||
// because those would seriously impede the script conversion of the base class.
|
||||
|
||||
class SBarInfoWrapper : BaseStatusBar
|
||||
|
|
Loading…
Reference in a new issue