Merge branch '2D_Refactor'

This commit is contained in:
Christoph Oelckers 2018-04-13 17:52:58 +02:00
commit 71a6cc4625
348 changed files with 10095 additions and 23294 deletions

View file

@ -490,9 +490,6 @@ endif()
set( PLAT_WIN32_SOURCES
sound/mididevices/music_win_mididevice.cpp
win32/critsec.cpp
win32/fb_d3d9.cpp
win32/fb_d3d9_wipe.cpp
win32/fb_ddraw.cpp
win32/hardware.cpp
win32/helperthread.cpp
win32/i_cd.cpp
@ -521,7 +518,6 @@ set( PLAT_SDL_SOURCES
posix/sdl/i_joystick.cpp
posix/sdl/i_main.cpp
posix/sdl/i_system.cpp
posix/sdl/sdlvideo.cpp
posix/sdl/sdlglvideo.cpp
posix/sdl/st_start.cpp )
set( PLAT_UNIX_SOURCES
@ -574,17 +570,17 @@ if( HAVE_MMX )
add_definitions( -DHAVE_MMX=1 )
set( SYSTEM_SOURCES ${SYSTEM_SOURCES}
gl/hqnx_asm/hq2x_asm.cpp
gl/hqnx_asm/hq3x_asm.cpp
gl/hqnx_asm/hq4x_asm.cpp
gl/hqnx_asm/hqnx_asm_Image.cpp)
textures/hires/hqnx_asm/hq2x_asm.cpp
textures/hires/hqnx_asm/hq3x_asm.cpp
textures/hires/hqnx_asm/hq4x_asm.cpp
textures/hires/hqnx_asm/hqnx_asm_Image.cpp)
if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
set_source_files_properties(
gl/hqnx_asm/hq2x_asm.cpp
gl/hqnx_asm/hq3x_asm.cpp
gl/hqnx_asm/hq4x_asm.cpp
gl/textures/gl_hqresize.cpp
textures/hires/hqnx_asm/hq2x_asm.cpp
textures/hires/hqnx_asm/hq3x_asm.cpp
textures/hires/hqnx_asm/hq4x_asm.cpp
textures/hires/gl_hqresize.cpp
PROPERTIES COMPILE_FLAGS "-mmmx" )
endif( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
endif( HAVE_MMX )
@ -689,6 +685,9 @@ file( GLOB HEADER_FILES
sfmt/*.h
sound/*.h
textures/*.h
textures/hires/hqnx/*.h
textures/hires/hqnx_asm/*.h
textures/hires/xbr/*.h
scripting/*.h
scripting/backend/*.h
scripting/decorate/*.h
@ -718,9 +717,6 @@ file( GLOB HEADER_FILES
gl/api/*.h
gl/data/*.h
gl/dynlights/*.h
gl/hqnx/*.h
gl/hqnx_asm/*.h
gl/xbr/*.h
gl/models/*.h
gl/renderer/*.h
gl/scene/*.h
@ -729,11 +725,11 @@ file( GLOB HEADER_FILES
gl/system/*.h
gl/textures/*.h
gl/utility/*.h
gl_load/*.h
*.h
)
set ( SWRENDER_SOURCES
swrenderer/r_swcanvas.cpp
swrenderer/r_swcolormaps.cpp
swrenderer/r_swrenderer.cpp
swrenderer/r_memory.cpp
@ -836,13 +832,12 @@ set( FASTMATH_SOURCES
sound/timiditypp/fft4g.cpp
sound/timiditypp/reverb.cpp
gl/utility/gl_clock.cpp
gl/renderer/gl_2ddrawer.cpp
gl/hqnx/init.cpp
gl/hqnx/hq2x.cpp
gl/hqnx/hq3x.cpp
gl/hqnx/hq4x.cpp
gl/xbr/xbrz.cpp
gl/xbr/xbrz_old.cpp
textures/hires/hqnx/init.cpp
textures/hires/hqnx/hq2x.cpp
textures/hires/hqnx/hq3x.cpp
textures/hires/hqnx/hq4x.cpp
textures/hires/xbr/xbrz.cpp
textures/hires/xbr/xbrz_old.cpp
gl/scene/gl_bsp.cpp
gl/scene/gl_fakeflat.cpp
gl/scene/gl_clipper.cpp
@ -855,13 +850,14 @@ set( FASTMATH_SOURCES
gl/scene/gl_renderhacks.cpp
gl/scene/gl_weapon.cpp
gl/scene/gl_scene.cpp
gl/scene/gl_swscene.cpp
gl/scene/gl_sky.cpp
gl/scene/gl_portal.cpp
gl/scene/gl_walls_draw.cpp
gl/scene/gl_vertex.cpp
gl/scene/gl_spritelight.cpp
gl/dynlights/gl_dynlight1.cpp
gl/system/gl_load.c
gl_load/gl_load.c
gl/models/gl_models.cpp
r_data/models/models.cpp
r_data/matrix.cpp
@ -1016,6 +1012,7 @@ set (PCH_SOURCES
stringtable.cpp
teaminfo.cpp
umapinfo.cpp
v_2ddrawer.cpp
v_blend.cpp
v_collection.cpp
v_draw.cpp
@ -1033,7 +1030,6 @@ set (PCH_SOURCES
g_shared/a_action.cpp
g_shared/a_decals.cpp
g_shared/a_dynlight.cpp
g_shared/a_dynlightdata.cpp
g_shared/a_flashfader.cpp
g_shared/a_lightning.cpp
g_shared/a_morph.cpp
@ -1045,13 +1041,9 @@ set (PCH_SOURCES
g_statusbar/sbar_mugshot.cpp
g_statusbar/shared_sbar.cpp
gl/compatibility/gl_20.cpp
gl/data/gl_data.cpp
gl/data/gl_portaldata.cpp
gl/data/gl_setup.cpp
gl/compatibility/gl_swshader20.cpp
gl/data/gl_vertexbuffer.cpp
gl/dynlights/gl_glow.cpp
gl/dynlights/gl_lightbuffer.cpp
gl/dynlights/gl_aabbtree.cpp
gl/dynlights/gl_shadowmap.cpp
gl/renderer/gl_quaddrawer.cpp
gl/renderer/gl_renderer.cpp
@ -1061,7 +1053,6 @@ set (PCH_SOURCES
gl/renderer/gl_postprocess.cpp
gl/renderer/gl_postprocessstate.cpp
gl/shaders/gl_shader.cpp
gl/shaders/gl_texshader.cpp
gl/shaders/gl_shaderprogram.cpp
gl/shaders/gl_postprocessshader.cpp
gl/shaders/gl_shadowmapshader.cpp
@ -1084,18 +1075,15 @@ set (PCH_SOURCES
gl/stereo3d/gl_interleaved3d.cpp
gl/system/gl_interface.cpp
gl/system/gl_framebuffer.cpp
gl/system/gl_swframebuffer.cpp
gl/system/gl_swwipe.cpp
gl/system/gl_debug.cpp
gl/system/gl_menu.cpp
gl/system/gl_wipe.cpp
gl/textures/gl_hwtexture.cpp
gl/textures/gl_texture.cpp
gl/textures/gl_material.cpp
gl/textures/gl_hirestex.cpp
gl/textures/gl_samplers.cpp
gl/textures/gl_translate.cpp
gl/textures/gl_hqresize.cpp
hwrenderer/dynlights/hw_aabbtree.cpp
menu/joystickmenu.cpp
menu/loadsavemenu.cpp
menu/menu.cpp
@ -1116,29 +1104,32 @@ set (PCH_SOURCES
resourcefiles/resourcefile.cpp
textures/animations.cpp
textures/anim_switches.cpp
textures/automaptexture.cpp
textures/bitmap.cpp
textures/buildtexture.cpp
textures/canvastexture.cpp
textures/ddstexture.cpp
textures/flattexture.cpp
textures/imgztexture.cpp
textures/jpegtexture.cpp
textures/md5check.cpp
textures/multipatchtexture.cpp
textures/patchtexture.cpp
textures/pcxtexture.cpp
textures/pngtexture.cpp
textures/rawpagetexture.cpp
textures/emptytexture.cpp
textures/backdroptexture.cpp
textures/shadertexture.cpp
textures/texture.cpp
textures/texturemanager.cpp
textures/tgatexture.cpp
textures/warptexture.cpp
textures/skyboxtexture.cpp
textures/worldtexture.cpp
textures/formats/automaptexture.cpp
textures/formats/brightmaptexture.cpp
textures/formats/buildtexture.cpp
textures/formats/canvastexture.cpp
textures/formats/ddstexture.cpp
textures/formats/flattexture.cpp
textures/formats/imgztexture.cpp
textures/formats/jpegtexture.cpp
textures/formats/md5check.cpp
textures/formats/multipatchtexture.cpp
textures/formats/patchtexture.cpp
textures/formats/pcxtexture.cpp
textures/formats/pngtexture.cpp
textures/formats/rawpagetexture.cpp
textures/formats/emptytexture.cpp
textures/formats/backdroptexture.cpp
textures/formats/shadertexture.cpp
textures/formats/tgatexture.cpp
textures/formats/worldtexture.cpp
textures/formats/warptexture.cpp
textures/hires/hqresize.cpp
textures/hires/hirestex.cpp
xlat/parse_xlat.cpp
fragglescript/t_func.cpp
fragglescript/t_load.cpp
@ -1152,9 +1143,13 @@ set (PCH_SOURCES
intermission/intermission.cpp
intermission/intermission_parse.cpp
r_data/colormaps.cpp
r_data/gldefs.cpp
r_data/a_dynlightdata.cpp
r_data/r_translate.cpp
r_data/sprites.cpp
r_data/portalgroups.cpp
r_data/voxels.cpp
r_data/renderinfo.cpp
r_data/renderstyle.cpp
r_data/r_interpolate.cpp
r_data/r_vanillatrans.cpp
@ -1416,12 +1411,21 @@ source_group("FraggleScript" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/fr
source_group("Intermission" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/intermission/.+")
source_group("Inventory" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_inventory/.+")
source_group("Menu" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/menu/.+")
source_group("Hardware Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/.+")
source_group("Hardware Renderer\\Data" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/hwrenderer/data/.+")
source_group("Hardware Renderer\\Dynamic Lights" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/hwrenderer/dynlights/.+")
source_group("Hardware Renderer\\Models" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/hwrenderer/models/.+")
source_group("Hardware Renderer\\Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/hwrenderer/renderer/.+")
source_group("Hardware Renderer\\Scene" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/hwrenderer/scene/.+")
source_group("Hardware Renderer\\Stereo3D" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/hwrenderer/stereo3d/.+")
source_group("Hardware Renderer\\Shaders" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/hwrenderer/shaders/.+")
source_group("Hardware Renderer\\System" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/hwrenderer/system/.+")
source_group("Hardware Renderer\\Textures" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/hwrenderer/textures/.+")
source_group("Hardware Renderer\\Utilities" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/hwrenderer/utility/.+")
source_group("OpenGL Loader" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl_load/.+")
source_group("OpenGL Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/.+")
source_group("OpenGL Renderer\\Data" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/data/.+")
source_group("OpenGL Renderer\\Dynamic Lights" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/dynlights/.+")
source_group("OpenGL Renderer\\HQ Resize" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/hqnx/.+")
source_group("OpenGL Renderer\\HQ Resize MMX version" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/hqnx_asm/.+")
source_group("OpenGL Renderer\\XBRZ" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/hqnx_asm/.+")
source_group("OpenGL Renderer\\Models" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/models/.+")
source_group("OpenGL Renderer\\Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/renderer/.+")
source_group("OpenGL Renderer\\Scene" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/scene/.+")
@ -1444,6 +1448,11 @@ source_group("Poly Renderer\\Drawers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURC
source_group("Poly Renderer\\Scene" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/polyrenderer/scene/.+")
source_group("Render Data" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_data/.+")
source_group("Render Data\\Textures" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/textures/.+")
source_group("Render Data\\Textures\\Hires" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/textures/hires/.+")
source_group("Render Data\\Textures\\Hires\\HQ Resize" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/textures/hires/hqnx/.+")
source_group("Render Data\\Textures\\Hires\\HQ Resize MMX version" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/textures/hires/hqnx_asm/.+")
source_group("Render Data\\Textures\\Hires\\XBRZ" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/textures/hires/xbr/.+")
source_group("Render Data\\Textures\\Formats" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/textures/formats/.+")
source_group("Render Data\\Models" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_data/models/.+")
source_group("Render Interface" FILES r_defs.h r_renderer.h r_sky.cpp r_sky.h r_state.h r_utility.cpp r_utility.h)
source_group("Resource Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/resourcefiles/.+")

View file

@ -2,31 +2,32 @@
#include "actor.h"
#include "r_defs.h"
// These depend on both actor.h and r_defs.h so they cannot be in either file without creating a cross dependency.
#include "g_levellocals.h"
// These depend on both actor.h and r_defs.h so they cannot be in either file without creating a circular dependency.
inline DVector3 AActor::PosRelative(int portalgroup) const
{
return Pos() + Displacements.getOffset(Sector->PortalGroup, portalgroup);
return Pos() + level.Displacements.getOffset(Sector->PortalGroup, portalgroup);
}
inline DVector3 AActor::PosRelative(const AActor *other) const
{
return Pos() + Displacements.getOffset(Sector->PortalGroup, other->Sector->PortalGroup);
return Pos() + level.Displacements.getOffset(Sector->PortalGroup, other->Sector->PortalGroup);
}
inline DVector3 AActor::PosRelative(sector_t *sec) const
{
return Pos() + Displacements.getOffset(Sector->PortalGroup, sec->PortalGroup);
return Pos() + level.Displacements.getOffset(Sector->PortalGroup, sec->PortalGroup);
}
inline DVector3 AActor::PosRelative(line_t *line) const
{
return Pos() + Displacements.getOffset(Sector->PortalGroup, line->frontsector->PortalGroup);
return Pos() + level.Displacements.getOffset(Sector->PortalGroup, line->frontsector->PortalGroup);
}
inline DVector3 PosRelative(const DVector3 &pos, line_t *line, sector_t *refsec = NULL)
{
return pos + Displacements.getOffset(refsec->PortalGroup, line->frontsector->PortalGroup);
return pos + level.Displacements.getOffset(refsec->PortalGroup, line->frontsector->PortalGroup);
}

View file

@ -771,7 +771,6 @@ static int f_y;
// size of window on screen
static int f_w;
static int f_h;
static int f_p; // [RH] # of bytes from start of a line to start of next
static int amclock;
@ -1384,7 +1383,6 @@ void AM_Stop ()
{
automapactive = false;
stopped = true;
V_SetBorderNeedRefresh();
viewactive = true;
}
@ -2134,7 +2132,7 @@ void AM_drawSubsectors()
{
F3DFloor *rover = sec->e->XFloor.ffloors[i];
if (!(rover->flags & FF_EXISTS)) continue;
if (rover->flags & FF_FOG) continue;
if (rover->flags & (FF_FOG|FF_THISINSIDE)) continue;
if (!(rover->flags & FF_RENDERPLANES)) continue;
if (rover->alpha == 0) continue;
double roverz = rover->top.plane->ZatPoint(secx, secy);
@ -2192,6 +2190,11 @@ void AM_drawSubsectors()
(colormap.LightColor.b + 160) / 2);
colormap.Desaturation = 255 - (255 - colormap.Desaturation) / 4;
}
// make table based fog visible on the automap as well.
if (level.flags & LEVEL_HASFADETABLE)
{
colormap.FadeColor = PalEntry(0, 128, 128, 128);
}
// Draw the polygon.
FTexture *pic = TexMan(maptex);
@ -2336,6 +2339,7 @@ bool AM_Check3DFloors(line_t *line)
for(unsigned i=0;i<ff_front.Size();i++)
{
F3DFloor *rover = ff_front[i];
if (rover->flags & FF_THISINSIDE) continue;
if (!(rover->flags & FF_EXISTS)) continue;
if (rover->alpha == 0) continue;
realfrontcount++;
@ -2344,6 +2348,7 @@ bool AM_Check3DFloors(line_t *line)
for(unsigned i=0;i<ff_back.Size();i++)
{
F3DFloor *rover = ff_back[i];
if (rover->flags & FF_THISINSIDE) continue;
if (!(rover->flags & FF_EXISTS)) continue;
if (rover->alpha == 0) continue;
realbackcount++;
@ -2354,6 +2359,7 @@ bool AM_Check3DFloors(line_t *line)
for(unsigned i=0;i<ff_front.Size();i++)
{
F3DFloor *rover = ff_front[i];
if (rover->flags & FF_THISINSIDE) continue; // only relevant for software rendering.
if (!(rover->flags & FF_EXISTS)) continue;
if (rover->alpha == 0) continue;
@ -2361,6 +2367,7 @@ bool AM_Check3DFloors(line_t *line)
for(unsigned j=0;j<ff_back.Size();j++)
{
F3DFloor *rover2 = ff_back[j];
if (rover2->flags & FF_THISINSIDE) continue; // only relevant for software rendering.
if (!(rover2->flags & FF_EXISTS)) continue;
if (rover2->alpha == 0) continue;
if (rover->model == rover2->model && rover->flags == rover2->flags)
@ -2536,7 +2543,7 @@ void AM_drawWalls (bool allmap)
static mline_t l;
int lock, color;
int numportalgroups = am_portaloverlay ? Displacements.size : 0;
int numportalgroups = am_portaloverlay ? level.Displacements.size : 0;
for (int p = numportalgroups - 1; p >= -1; p--)
{
@ -2560,7 +2567,7 @@ void AM_drawWalls (bool allmap)
bool portalmode = numportalgroups > 0 && pg != MapPortalGroup;
if (pg == p)
{
offset = Displacements.getOffset(pg, MapPortalGroup);
offset = level.Displacements.getOffset(pg, MapPortalGroup);
}
else if (p == -1 && (pg == MapPortalGroup || !am_portaloverlay))
{
@ -3222,7 +3229,6 @@ void AM_Drawer (int bottom)
f_x = f_y = 0;
f_w = screen->GetWidth ();
f_h = bottom;
f_p = screen->GetPitch ();
AM_clearFB(AMColors[AMColors.Background]);
}
@ -3232,7 +3238,6 @@ void AM_Drawer (int bottom)
f_y = viewwindowy;
f_w = viewwidth;
f_h = viewheight;
f_p = screen->GetPitch ();
}
AM_activateNewScale();

View file

@ -516,31 +516,6 @@ CUSTOM_CVAR (Int, msgmidcolor2, 4, CVAR_ARCHIVE)
setmsgcolor (PRINTLEVELS+1, self);
}
static void maybedrawnow (bool tick, bool force)
{
// FIXME: Does not work right with hw2d
if (ConsoleDrawing || screen == NULL || screen->IsLocked () || screen->Accel2D || ConFont == NULL)
{
return;
}
if (vidactive &&
(((tick || gameaction != ga_nothing) && ConsoleState == c_down)
|| gamestate == GS_STARTUP))
{
static size_t lastprinttime = 0;
size_t nowtime = I_GetTime();
if (nowtime - lastprinttime > 1 || force)
{
screen->Lock (false);
C_DrawConsole (false);
screen->Update ();
lastprinttime = nowtime;
}
}
}
struct TextQueue
{
TextQueue (bool notify, int printlevel, const char *text)
@ -857,7 +832,6 @@ int PrintString (int printlevel, const char *outline)
if (vidactive && screen && SmallFont)
{
NotifyStrings.AddString(printlevel, outline);
maybedrawnow (false, false);
}
}
else if (Logfile != NULL)
@ -1026,8 +1000,6 @@ void FNotifyBuffer::Draw()
lineadv = SmallFont->GetHeight ();
BorderTopRefresh = screen->GetPageCount ();
for (unsigned i = 0; i < Text.Size(); ++ i)
{
FNotifyText &notify = Text[i];
@ -1088,16 +1060,14 @@ void C_InitTicker (const char *label, unsigned int max, bool showpercent)
TickerMax = max;
TickerLabel = label;
TickerAt = 0;
maybedrawnow (true, false);
}
void C_SetTicker (unsigned int at, bool forceUpdate)
{
TickerAt = at > TickerMax ? TickerMax : at;
maybedrawnow (true, TickerVisible ? forceUpdate : false);
}
void C_DrawConsole (bool hw2d)
void C_DrawConsole ()
{
static int oldbottom = 0;
int lines, left, offset;
@ -1116,14 +1086,6 @@ void C_DrawConsole (bool hw2d)
offset = -ConFont->GetHeight();
}
if ((ConBottom < oldbottom) &&
(gamestate == GS_LEVEL || gamestate == GS_TITLELEVEL) &&
(viewwindowx || viewwindowy) &&
viewactive)
{
V_SetBorderNeedRefresh();
}
oldbottom = ConBottom;
if (ConsoleState == c_up)
@ -1142,7 +1104,7 @@ void C_DrawConsole (bool hw2d)
DTA_DestWidth, screen->GetWidth(),
DTA_DestHeight, screen->GetHeight(),
DTA_ColorOverlay, conshade,
DTA_Alpha, (hw2d && gamestate != GS_FULLCONSOLE) ? (double)con_alpha : 1.,
DTA_Alpha, (gamestate != GS_FULLCONSOLE) ? (double)con_alpha : 1.,
DTA_Masked, false,
TAG_DONE);
if (conline && visheight < screen->GetHeight())
@ -1220,21 +1182,6 @@ void C_DrawConsole (bool hw2d)
}
}
// Apply palette blend effects
if (StatusBar != NULL && !hw2d)
{
player_t *player = StatusBar->CPlayer;
if (player->camera != NULL && player->camera->player != NULL)
{
player = player->camera->player;
}
if (player->BlendA != 0 && (gamestate == GS_LEVEL || gamestate == GS_TITLELEVEL))
{
screen->Dim (PalEntry ((unsigned char)(player->BlendR*255), (unsigned char)(player->BlendG*255), (unsigned char)(player->BlendB*255)),
player->BlendA, 0, ConBottom, screen->GetWidth(), screen->GetHeight() - ConBottom);
V_SetBorderNeedRefresh();
}
}
}
if (menuactive != MENU_Off)

View file

@ -67,7 +67,7 @@ void AddToConsole (int printlevel, const char *string);
int PrintString (int printlevel, const char *string);
int VPrintf (int printlevel, const char *format, va_list parms) GCCFORMAT(2);
void C_DrawConsole (bool hw2d);
void C_DrawConsole ();
void C_ToggleConsole (void);
void C_FullConsole (void);
void C_HideConsole (void);

View file

@ -274,8 +274,6 @@ void CT_Drawer (void)
screen->DrawText (SmallFont, CR_GREY, promptwidth, y, (char *)(ChatQueue + i),
DTA_VirtualWidth, screen_width, DTA_VirtualHeight, screen_height, DTA_KeepRatio, true, TAG_DONE);
ChatQueue[len] = '\0';
BorderTopRefresh = screen->GetPageCount ();
}
if (players[consoleplayer].camera != NULL &&

View file

@ -176,6 +176,7 @@ extern bool gameisdead;
extern bool demorecording;
extern bool M_DemoNoPlay; // [RH] if true, then skip any demos in the loop
extern bool insave;
extern TDeletingArray<FLightDefaults *> LightDefaults;
// PUBLIC DATA DEFINITIONS -------------------------------------------------
@ -669,7 +670,6 @@ CVAR (Flag, compat_pushwindow, compatflags2, COMPATF2_PUSHWINDOW);
void D_Display ()
{
bool wipe;
bool hw2d;
if (nodrawers || screen == NULL)
return; // for comparative timing / profiling
@ -680,7 +680,7 @@ void D_Display ()
cycles.Clock();
r_UseVanillaTransparency = UseVanillaTransparency(); // [SP] Cache UseVanillaTransparency() call
r_renderercaps = Renderer->GetCaps(); // [SP] Get the current capabilities of the renderer
r_renderercaps = screen->GetCaps(); // [SP] Get the current capabilities of the renderer
if (players[consoleplayer].camera == NULL)
{
@ -703,13 +703,6 @@ void D_Display ()
// [RH] change the screen mode if needed
if (setmodeneeded)
{
int oldrenderer;
extern int currentrenderer;
EXTERN_CVAR(Int, vid_renderer)
oldrenderer = vid_renderer; // [SP] Save pending vid_renderer setting (hack)
if (currentrenderer != vid_renderer)
vid_renderer = currentrenderer;
// Change screen mode.
if (Video->SetResolution (NewWidth, NewHeight, NewBits))
{
@ -728,7 +721,6 @@ void D_Display ()
// Reset the mouse cursor in case the bit depth changed
vid_cursor.Callback();
}
vid_renderer = oldrenderer; // [SP] Restore pending vid_renderer setting
}
// change the view size if needed
@ -738,22 +730,15 @@ void D_Display ()
}
setmodeneeded = false;
if (screen->Lock (false))
{
V_SetBorderNeedRefresh();
}
// [RH] Allow temporarily disabling wipes
if (NoWipe)
{
V_SetBorderNeedRefresh();
NoWipe--;
wipe = false;
wipegamestate = gamestate;
}
else if (gamestate != wipegamestate && gamestate != GS_FULLCONSOLE && gamestate != GS_TITLELEVEL)
{ // save the current screen if about to wipe
V_SetBorderNeedRefresh();
switch (wipegamestate)
{
default:
@ -779,9 +764,6 @@ void D_Display ()
wipe = false;
}
hw2d = false;
{
screen->FrameTime = I_msTimeFS();
TexMan.UpdateAnimations(screen->FrameTime);
@ -790,8 +772,8 @@ void D_Display ()
{
case GS_FULLCONSOLE:
screen->SetBlendingRect(0,0,0,0);
hw2d = screen->Begin2D(false);
C_DrawConsole (false);
screen->Begin2D(false);
C_DrawConsole ();
M_Drawer ();
screen->Update ();
return;
@ -800,40 +782,22 @@ void D_Display ()
case GS_TITLELEVEL:
if (!gametic)
{
if (!screen->HasBegun2D())
{
screen->Begin2D(false);
}
screen->Begin2D(false);
break;
}
if (StatusBar != NULL)
{
float blend[4] = { 0, 0, 0, 0 };
StatusBar->BlendView (blend);
}
screen->SetBlendingRect(viewwindowx, viewwindowy,
viewwindowx + viewwidth, viewwindowy + viewheight);
// [ZZ] execute event hook that we just started the frame
//E_RenderFrame();
//
Renderer->RenderView(&players[consoleplayer]);
if ((hw2d = screen->Begin2D(viewactive)))
{
// Redraw everything every frame when using 2D accel
V_SetBorderNeedRefresh();
}
Renderer->DrawRemainingPlayerSprites();
screen->DrawBlendingRect();
screen->RenderView(&players[consoleplayer]);
// returns with 2S mode set.
if (automapactive)
{
AM_Drawer (hud_althud? viewheight : StatusBar->GetTopOfStatusbar());
}
if (!automapactive || viewactive)
{
V_RefreshViewBorder ();
screen->RefreshViewBorder ();
}
// for timing the statusbar code.
@ -872,21 +836,21 @@ void D_Display ()
case GS_INTERMISSION:
screen->SetBlendingRect(0,0,0,0);
hw2d = screen->Begin2D(false);
screen->Begin2D(false);
WI_Drawer ();
CT_Drawer ();
break;
case GS_FINALE:
screen->SetBlendingRect(0,0,0,0);
hw2d = screen->Begin2D(false);
screen->Begin2D(false);
F_Drawer ();
CT_Drawer ();
break;
case GS_DEMOSCREEN:
screen->SetBlendingRect(0,0,0,0);
hw2d = screen->Begin2D(false);
screen->Begin2D(false);
D_PageDrawer ();
CT_Drawer ();
break;
@ -904,7 +868,7 @@ void D_Display ()
tex = TexMan(gameinfo.PauseSign);
x = (SCREENWIDTH - tex->GetScaledWidth() * CleanXfac)/2 +
tex->GetScaledLeftOffset() * CleanXfac;
tex->GetScaledLeftOffset(0) * CleanXfac;
screen->DrawTexture (tex, x, 4, DTA_CleanNoMove, true, TAG_DONE);
if (paused && multiplayer)
{
@ -940,7 +904,7 @@ void D_Display ()
NetUpdate (); // send out any new accumulation
// normal update
// draw ZScript UI stuff
C_DrawConsole (hw2d); // draw console
C_DrawConsole (); // draw console
M_Drawer (); // menu is drawn even on top of everything
FStat::PrintStat ();
screen->Update (); // page flip or blit buffer
@ -968,7 +932,7 @@ void D_Display ()
} while (diff < 1);
wipestart = nowtime;
done = screen->WipeDo (1);
C_DrawConsole (hw2d); // console and
C_DrawConsole (); // console and
M_Drawer (); // menu are drawn even on top of wipes
screen->Update (); // page flip or blit buffer
NetUpdate (); // [RH] not sure this is needed anymore
@ -992,7 +956,6 @@ void D_Display ()
void D_ErrorCleanup ()
{
savegamerestore = false;
screen->Unlock ();
bglobal.RemoveAllBots (true);
D_QuitNetGame ();
if (demorecording || demoplayback)
@ -1326,7 +1289,6 @@ void D_DoAdvanceDemo (void)
Advisory = NULL;
if (!M_DemoNoPlay)
{
V_SetBorderNeedRefresh();
democount++;
mysnprintf (demoname + 4, countof(demoname) - 4, "%d", democount);
if (Wads.CheckNumForName (demoname) < 0)
@ -2293,6 +2255,7 @@ static void CheckCmdLine()
}
}
//==========================================================================
//
// D_DoomMain
@ -2477,7 +2440,6 @@ void D_DoomMain (void)
{
if (!batchrun) Printf ("I_Init: Setting up machine state.\n");
I_Init ();
I_CreateRenderer();
}
if (!batchrun) Printf ("V_Init: allocate screen.\n");
@ -2675,7 +2637,7 @@ void D_DoomMain (void)
}
V_Init2();
gl_PatchMenu();
gl_PatchMenu(); // removes unapplicable entries for old hardware. This cannot be done in MENUDEF because at the point it gets parsed it doesn't have the needed info.
UpdateJoystickMenu(NULL);
v = Args->CheckValue ("-loadgame");
@ -2744,7 +2706,6 @@ void D_DoomMain (void)
// These calls from inside V_Init2 are still necessary
C_NewModeAdjust();
M_InitVideoModesMenu();
Renderer->RemapVoxels();
D_StartTitle (); // start up intro loop
setmodeneeded = false; // This may be set to true here, but isn't needed for a restart
}
@ -2777,6 +2738,7 @@ void D_DoomMain (void)
M_SaveDefaults(NULL); // save config before the restart
// delete all data that cannot be left until reinitialization
screen->CleanForRestart();
V_ClearFonts(); // must clear global font pointers
ColorSets.Clear();
PainFlashes.Clear();
@ -2788,6 +2750,7 @@ void D_DoomMain (void)
DestroyCVarsFlagged(CVAR_MOD); // Delete any cvar left by mods
FS_Close(); // destroy the global FraggleScript.
DeinitMenus();
LightDefaults.Clear(); // this can leak heap memory if it isn't cleared.
// delete DoomStartupInfo data
DoomStartupInfo.Name = (const char*)0;

View file

@ -2412,7 +2412,6 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
paused = player + 1;
S_PauseSound (false, false);
}
V_SetBorderNeedRefresh();
}
break;

View file

@ -36,8 +36,6 @@ extern int sys_ostype;
#include "version.h"
#include "v_video.h"
EXTERN_CVAR(Bool, vid_glswfb)
extern int currentrenderer;
CVAR(Int, sys_statsenabled, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOSET)
CVAR(String, sys_statshost, "gzstats.drdteam.org", CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOSET)
CVAR(Int, sys_statsport, 80, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOSET)
@ -252,34 +250,17 @@ static int GetCoreInfo()
static int GetRenderInfo()
{
if (currentrenderer == 0)
{
if (!screen->Accel2D) return 0;
if (vid_glswfb) return 2;
if (screen->LegacyHardware()) return 6;
return 1;
}
else
{
auto info = gl_getInfo();
if (info.first < 3.3) return 3; // Legacy OpenGL. Don't care about Intel HD 3000 on Windows being run in 'risky' mode.
if (!info.second) return 4;
return 5;
}
auto info = gl_getInfo();
if (info.first < 3.3) return 3; // Legacy OpenGL. Don't care about Intel HD 3000 on Windows being run in 'risky' mode.
if (!info.second) return 4;
return 5;
}
static void D_DoHTTPRequest(const char *request)
{
if (I_HTTPRequest(request))
{
if (currentrenderer == 0)
{
cvar_forceset("sentstats_swr_done", CHECKVERSIONSTR);
}
else
{
cvar_forceset("sentstats_hwr_done", CHECKVERSIONSTR);
}
cvar_forceset("sentstats_hwr_done", CHECKVERSIONSTR);
}
}
@ -295,12 +276,11 @@ void D_DoAnonStats()
done = true;
// Do not repeat if already sent.
if (currentrenderer == 0 && sentstats_swr_done >= CHECKVERSION) return;
if (currentrenderer == 1 && sentstats_hwr_done >= CHECKVERSION) return;
if (sentstats_hwr_done >= CHECKVERSION) return;
static char requeststring[1024];
mysnprintf(requeststring, sizeof requeststring, "GET /stats.py?render=%i&cores=%i&os=%i&renderconfig=%i HTTP/1.1\nHost: %s\nConnection: close\nUser-Agent: %s %s\n\n",
GetRenderInfo(), GetCoreInfo(), GetOSVersion(), currentrenderer, sys_statshost.GetHumanString(), GAMENAME, VERSIONSTR);
GetRenderInfo(), GetCoreInfo(), GetOSVersion(), V_IsHardwareRenderer(), sys_statshost.GetHumanString(), GAMENAME, VERSIONSTR);
DPrintf(DMSG_NOTIFY, "Sending %s", requeststring);
std::thread t1(D_DoHTTPRequest, requeststring);
t1.detach();

View file

@ -70,6 +70,5 @@ int NextSkill = -1;
int SinglePlayerClass[MAXPLAYERS];
bool ToggleFullscreen;
int BorderTopRefresh;
FString LumpFilterIWAD;

View file

@ -192,9 +192,6 @@ extern bool precache;
extern bool setsizeneeded;
extern bool setmodeneeded;
extern int BorderNeedRefresh;
extern int BorderTopRefresh;
EXTERN_CVAR (Float, mouse_sensitivity)
//?

View file

@ -196,6 +196,7 @@ enum class ETextureType : uint8_t
SkinGraphic,
Null,
FirstDefined,
SWCanvas,
};
class FTextureID

View file

@ -32,148 +32,6 @@
#include "templates.h"
#include "v_palette.h"
EXTERN_CVAR(Bool, r_blendmethod)
//
// SCREEN WIPE PACKAGE
//
static int CurrentWipeType;
static short *wipe_scr_start;
static short *wipe_scr_end;
static int *y;
// [RH] Fire Wipe
#define FIREWIDTH 64
#define FIREHEIGHT 64
static uint8_t *burnarray;
static int density;
static int burntime;
// [RH] Crossfade
static int fade;
// Melt -------------------------------------------------------------
// Match the strip sizes that oldschool Doom used on a 320x200 screen.
#define MELT_WIDTH 160
#define MELT_HEIGHT 200
void wipe_shittyColMajorXform (short *array)
{
int x, y;
short *dest;
int width = SCREENWIDTH / 2;
dest = new short[width*SCREENHEIGHT*2];
for(y = 0; y < SCREENHEIGHT; y++)
for(x = 0; x < width; x++)
dest[x*SCREENHEIGHT+y] = array[y*width+x];
memcpy(array, dest, SCREENWIDTH*SCREENHEIGHT);
delete[] dest;
}
bool wipe_initMelt (int ticks)
{
int i, r;
// copy start screen to main screen
screen->DrawBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (uint8_t *)wipe_scr_start);
// makes this wipe faster (in theory)
// to have stuff in column-major format
wipe_shittyColMajorXform (wipe_scr_start);
wipe_shittyColMajorXform (wipe_scr_end);
// setup initial column positions
// (y<0 => not ready to scroll yet)
y = new int[MELT_WIDTH];
y[0] = -(M_Random() & 15);
for (i = 1; i < MELT_WIDTH; i++)
{
r = (M_Random()%3) - 1;
y[i] = clamp(y[i-1] + r, -15, 0);
}
return 0;
}
bool wipe_doMelt (int ticks)
{
int i, j, dy, x;
const short *s;
short *d;
bool done = true;
while (ticks--)
{
done = true;
for (i = 0; i < MELT_WIDTH; i++)
{
if (y[i] < 0)
{
y[i]++;
done = false;
}
else if (y[i] < MELT_HEIGHT)
{
dy = (y[i] < 16) ? y[i]+1 : 8;
y[i] = MIN(y[i] + dy, MELT_HEIGHT);
done = false;
}
if (ticks == 0 && y[i] >= 0)
{ // Only draw for the final tick.
const int pitch = screen->GetPitch() / 2;
int sy = y[i] * SCREENHEIGHT / MELT_HEIGHT;
for (x = i * (SCREENWIDTH/2) / MELT_WIDTH; x < (i + 1) * (SCREENWIDTH/2) / MELT_WIDTH; ++x)
{
s = &wipe_scr_end[x*SCREENHEIGHT];
d = &((short *)screen->GetBuffer())[x];
for (j = sy; j != 0; --j)
{
*d = *(s++);
d += pitch;
}
s = &wipe_scr_start[x*SCREENHEIGHT];
for (j = SCREENHEIGHT - sy; j != 0; --j)
{
*d = *(s++);
d += pitch;
}
}
}
}
}
return done;
}
bool wipe_exitMelt (int ticks)
{
delete[] y;
return 0;
}
// Burn -------------------------------------------------------------
bool wipe_initBurn (int ticks)
{
burnarray = new uint8_t[FIREWIDTH * (FIREHEIGHT+5)];
memset (burnarray, 0, FIREWIDTH * (FIREHEIGHT+5));
density = 4;
burntime = 0;
return 0;
}
int wipe_CalcBurn (uint8_t *burnarray, int width, int height, int density)
{
// This is a modified version of the fire that was once used
@ -258,263 +116,3 @@ int wipe_CalcBurn (uint8_t *burnarray, int width, int height, int density)
return -1;
}
bool wipe_doBurn (int ticks)
{
bool done;
burntime += ticks;
ticks *= 2;
// Make the fire burn
done = false;
while (!done && ticks--)
{
density = wipe_CalcBurn(burnarray, FIREWIDTH, FIREHEIGHT, density);
done = (density < 0);
}
// Draw the screen
int xstep, ystep, firex, firey;
int x, y;
uint8_t *to, *fromold, *fromnew;
const int SHIFT = 16;
xstep = (FIREWIDTH << SHIFT) / SCREENWIDTH;
ystep = (FIREHEIGHT << SHIFT) / SCREENHEIGHT;
to = screen->GetBuffer();
fromold = (uint8_t *)wipe_scr_start;
fromnew = (uint8_t *)wipe_scr_end;
if (!r_blendmethod)
{
for (y = 0, firey = 0; y < SCREENHEIGHT; y++, firey += ystep)
{
for (x = 0, firex = 0; x < SCREENWIDTH; x++, firex += xstep)
{
int fglevel;
fglevel = burnarray[(firex>>SHIFT)+(firey>>SHIFT)*FIREWIDTH] / 2;
if (fglevel >= 63)
{
to[x] = fromnew[x];
}
else if (fglevel == 0)
{
to[x] = fromold[x];
done = false;
}
else
{
int bglevel = 64-fglevel;
uint32_t *fg2rgb = Col2RGB8[fglevel];
uint32_t *bg2rgb = Col2RGB8[bglevel];
uint32_t fg = fg2rgb[fromnew[x]];
uint32_t bg = bg2rgb[fromold[x]];
fg = (fg+bg) | 0x1f07c1f;
to[x] = RGB32k.All[fg & (fg>>15)];
done = false;
}
}
fromold += SCREENWIDTH;
fromnew += SCREENWIDTH;
to += SCREENPITCH;
}
}
else
{
for (y = 0, firey = 0; y < SCREENHEIGHT; y++, firey += ystep)
{
for (x = 0, firex = 0; x < SCREENWIDTH; x++, firex += xstep)
{
int fglevel;
fglevel = burnarray[(firex>>SHIFT)+(firey>>SHIFT)*FIREWIDTH] / 2;
if (fglevel >= 63)
{
to[x] = fromnew[x];
}
else if (fglevel == 0)
{
to[x] = fromold[x];
done = false;
}
else
{
int bglevel = 64-fglevel;
const PalEntry* pal = GPalette.BaseColors;
uint32_t fg = fromnew[x];
uint32_t bg = fromold[x];
int r = MIN((pal[fg].r * fglevel + pal[bg].r * bglevel) >> 8, 63);
int g = MIN((pal[fg].g * fglevel + pal[bg].g * bglevel) >> 8, 63);
int b = MIN((pal[fg].b * fglevel + pal[bg].b * bglevel) >> 8, 63);
to[x] = RGB256k.RGB[r][g][b];
done = false;
}
}
fromold += SCREENWIDTH;
fromnew += SCREENWIDTH;
to += SCREENPITCH;
}
}
return done || (burntime > 40);
}
bool wipe_exitBurn (int ticks)
{
delete[] burnarray;
return 0;
}
// Crossfade --------------------------------------------------------
bool wipe_initFade (int ticks)
{
fade = 0;
return 0;
}
bool wipe_doFade (int ticks)
{
fade += ticks * 2;
if (fade > 64)
{
screen->DrawBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (uint8_t *)wipe_scr_end);
return true;
}
else
{
int x, y;
int bglevel = 64 - fade;
uint32_t *fg2rgb = Col2RGB8[fade];
uint32_t *bg2rgb = Col2RGB8[bglevel];
uint8_t *fromnew = (uint8_t *)wipe_scr_end;
uint8_t *fromold = (uint8_t *)wipe_scr_start;
uint8_t *to = screen->GetBuffer();
const PalEntry *pal = GPalette.BaseColors;
if (!r_blendmethod)
{
for (y = 0; y < SCREENHEIGHT; y++)
{
for (x = 0; x < SCREENWIDTH; x++)
{
uint32_t fg = fg2rgb[fromnew[x]];
uint32_t bg = bg2rgb[fromold[x]];
fg = (fg+bg) | 0x1f07c1f;
to[x] = RGB32k.All[fg & (fg>>15)];
}
fromnew += SCREENWIDTH;
fromold += SCREENWIDTH;
to += SCREENPITCH;
}
}
else
{
for (y = 0; y < SCREENHEIGHT; y++)
{
for (x = 0; x < SCREENWIDTH; x++)
{
uint32_t fg = fromnew[x];
uint32_t bg = fromold[x];
int r = MIN((pal[fg].r * (64-bglevel) + pal[bg].r * bglevel) >> 8, 63);
int g = MIN((pal[fg].g * (64-bglevel) + pal[bg].g * bglevel) >> 8, 63);
int b = MIN((pal[fg].b * (64-bglevel) + pal[bg].b * bglevel) >> 8, 63);
to[x] = RGB256k.RGB[r][g][b];
}
fromnew += SCREENWIDTH;
fromold += SCREENWIDTH;
to += SCREENPITCH;
}
}
}
return false;
}
bool wipe_exitFade (int ticks)
{
return 0;
}
// General Wipe Functions -------------------------------------------
static bool (*wipes[])(int) =
{
wipe_initMelt, wipe_doMelt, wipe_exitMelt,
wipe_initBurn, wipe_doBurn, wipe_exitBurn,
wipe_initFade, wipe_doFade, wipe_exitFade
};
// Returns true if the wipe should be performed.
bool wipe_StartScreen (int type)
{
if (screen->IsBgra())
return false;
CurrentWipeType = clamp(type, 0, wipe_NUMWIPES - 1);
if (CurrentWipeType)
{
wipe_scr_start = new short[SCREENWIDTH * SCREENHEIGHT / 2];
screen->GetBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (uint8_t *)wipe_scr_start);
return true;
}
return false;
}
void wipe_EndScreen (void)
{
if (screen->IsBgra())
return;
if (CurrentWipeType)
{
wipe_scr_end = new short[SCREENWIDTH * SCREENHEIGHT / 2];
screen->GetBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (uint8_t *)wipe_scr_end);
screen->DrawBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (uint8_t *)wipe_scr_start); // restore start scr.
// Initialize the wipe
(*wipes[(CurrentWipeType-1)*3])(0);
}
}
// Returns true if the wipe is done.
bool wipe_ScreenWipe (int ticks)
{
bool rc;
if (screen->IsBgra())
return true;
if (CurrentWipeType == wipe_None)
return true;
// do a piece of wipe-in
rc = (*wipes[(CurrentWipeType-1)*3+1])(ticks);
return rc;
}
// Final things for the wipe
void wipe_Cleanup()
{
if (screen->IsBgra())
return;
if (wipe_scr_start != NULL)
{
delete[] wipe_scr_start;
wipe_scr_start = NULL;
}
if (wipe_scr_end != NULL)
{
delete[] wipe_scr_end;
wipe_scr_end = NULL;
}
if (CurrentWipeType > 0)
{
(*wipes[(CurrentWipeType-1)*3+2])(0);
}
}

View file

@ -30,6 +30,7 @@
// SCREEN WIPE PACKAGE
//
#if 0
bool wipe_StartScreen (int type);
void wipe_EndScreen (void);
bool wipe_ScreenWipe (int ticks);
@ -37,7 +38,8 @@ void wipe_Cleanup ();
// The buffer must have an additional 5 rows not included in height
// to use for a seeding area.
int wipe_CalcBurn (uint8_t *buffer, int width, int height, int density);
#endif
int wipe_CalcBurn(uint8_t *buffer, int width, int height, int density);
enum
{

View file

@ -2247,7 +2247,7 @@ static void PutSavePic (FileWriter *file, int width, int height)
}
else
{
Renderer->WriteSavePic(&players[consoleplayer], file, width, height);
screen->WriteSavePic(&players[consoleplayer], file, width, height);
}
}

View file

@ -117,6 +117,31 @@ EXTERN_CVAR (String, playerclass)
void G_VerifySkill();
CUSTOM_CVAR(Bool, gl_brightfog, false, CVAR_ARCHIVE | CVAR_NOINITCALL)
{
if (level.info->brightfog == -1) level.brightfog = self;
}
CUSTOM_CVAR(Bool, gl_lightadditivesurfaces, false, CVAR_ARCHIVE | CVAR_NOINITCALL)
{
if (level.info->lightadditivesurfaces == -1) level.lightadditivesurfaces = self;
}
CUSTOM_CVAR(Bool, gl_notexturefill, false, CVAR_NOINITCALL)
{
if (level.info->notexturefill == -1) level.notexturefill = self;
}
CUSTOM_CVAR(Int, gl_lightmode, 3, CVAR_ARCHIVE | CVAR_NOINITCALL)
{
int newself = self;
if (newself > 4) newself = 8; // use 8 for software lighting to avoid conflicts with the bit mask
if (newself < 0) newself = 0;
if (self != newself) self = newself;
else if ((level.info == nullptr || level.info->lightmode == -1)) level.lightmode = self;
}
static FRandom pr_classchoice ("RandomPlayerClassChoice");
@ -498,7 +523,6 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
demoplayback = false;
automapactive = false;
viewactive = true;
V_SetBorderNeedRefresh();
//Added by MC: Initialize bots.
if (!deathmatch)
@ -1491,6 +1515,12 @@ void G_InitLevelLocals ()
compatflags2.Callback();
level.DefaultEnvironment = info->DefaultEnvironment;
level.lightmode = info->lightmode < 0? gl_lightmode : info->lightmode;
level.brightfog = info->brightfog < 0? gl_brightfog : !!info->brightfog;
level.lightadditivesurfaces = info->lightadditivesurfaces < 0 ? gl_lightadditivesurfaces : !!info->lightadditivesurfaces;
level.notexturefill = info->notexturefill < 0 ? gl_notexturefill : !!info->notexturefill;
}
//==========================================================================
@ -1986,7 +2016,7 @@ inline T VecDiff(const T& v1, const T& v2)
if (nullptr != sec1 && nullptr != sec2)
{
result += Displacements.getOffset(sec2->PortalGroup, sec1->PortalGroup);
result += level.Displacements.getOffset(sec2->PortalGroup, sec1->PortalGroup);
}
}

View file

@ -35,6 +35,7 @@
#define __G_LEVEL_H__
#include "doomtype.h"
#include "vectors.h"
#include "sc_man.h"
#include "resourcefiles/file_zip.h"
@ -395,6 +396,14 @@ struct level_info_t
TArray<FString> EventHandlers;
int8_t lightmode;
int8_t brightfog;
int8_t lightadditivesurfaces;
int8_t notexturefill;
FVector3 skyrotatevector;
FVector3 skyrotatevector2;
level_info_t()
{
Reset();

View file

@ -84,6 +84,16 @@ struct FLevelLocals
TArray<uint8_t> rejectmatrix;
TArray<FSectorPortal> sectorPortals;
TArray<FLinePortal> linePortals;
// Portal information.
FDisplacementTable Displacements;
FPortalBlockmap PortalBlockmap;
TArray<FLinePortal*> linkedPortals; // only the linked portals, this is used to speed up looking for them in P_CollectConnectedGroups.
TArray<FSectorPortalGroup *> portalGroups;
TArray<FLinePortalSpan> linePortalSpans;
int NumMapSections;
TArray<zone_t> Zones;
FBlockmap blockmap;
@ -152,6 +162,12 @@ struct FLevelLocals
float pixelstretch;
float MusicVolume;
// Hardware render stuff that can either be set via CVAR or MAPINFO
int lightmode;
bool brightfog;
bool lightadditivesurfaces;
bool notexturefill;
bool IsJumpingAllowed() const;
bool IsCrouchingAllowed() const;
bool IsFreelookAllowed() const;
@ -262,27 +278,27 @@ inline bool sector_t::PortalIsLinked(int plane)
inline FLinePortal *line_t::getPortal() const
{
return portalindex >= linePortals.Size() ? (FLinePortal*)NULL : &linePortals[portalindex];
return portalindex >= level.linePortals.Size() ? (FLinePortal*)NULL : &level.linePortals[portalindex];
}
// returns true if the portal is crossable by actors
inline bool line_t::isLinePortal() const
{
return portalindex >= linePortals.Size() ? false : !!(linePortals[portalindex].mFlags & PORTF_PASSABLE);
return portalindex >= level.linePortals.Size() ? false : !!(level.linePortals[portalindex].mFlags & PORTF_PASSABLE);
}
// returns true if the portal needs to be handled by the renderer
inline bool line_t::isVisualPortal() const
{
return portalindex >= linePortals.Size() ? false : !!(linePortals[portalindex].mFlags & PORTF_VISIBLE);
return portalindex >= level.linePortals.Size() ? false : !!(level.linePortals[portalindex].mFlags & PORTF_VISIBLE);
}
inline line_t *line_t::getPortalDestination() const
{
return portalindex >= linePortals.Size() ? (line_t*)NULL : linePortals[portalindex].mDestination;
return portalindex >= level.linePortals.Size() ? (line_t*)NULL : level.linePortals[portalindex].mDestination;
}
inline int line_t::getPortalAlignment() const
{
return portalindex >= linePortals.Size() ? 0 : linePortals[portalindex].mAlign;
return portalindex >= level.linePortals.Size() ? 0 : level.linePortals[portalindex].mAlign;
}

View file

@ -283,6 +283,14 @@ void level_info_t::Reset()
specialactions.Clear();
DefaultEnvironment = 0;
PrecacheSounds.Clear();
brightfog = -1;
lightmode = -1;
notexturefill = -1;
lightadditivesurfaces = -1;
skyrotatevector = FVector3(0, 0, 1);
skyrotatevector2 = FVector3(0, 0, 1);
}
@ -1362,6 +1370,82 @@ DEFINE_MAP_OPTION(pixelratio, false)
}
DEFINE_MAP_OPTION(brightfog, false)
{
parse.ParseAssign();
parse.sc.MustGetNumber();
info->brightfog = parse.sc.Number;
}
DEFINE_MAP_OPTION(lightmode, false)
{
parse.ParseAssign();
parse.sc.MustGetNumber();
if ((parse.sc.Number >= 0 && parse.sc.Number <= 4) || parse.sc.Number == 8)
{
info->lightmode = uint8_t(parse.sc.Number);
}
else
{
parse.sc.ScriptMessage("Invalid light mode %d", parse.sc.Number);
}
}
DEFINE_MAP_OPTION(notexturefill, false)
{
if (parse.CheckAssign())
{
parse.sc.MustGetNumber();
info->notexturefill = !!parse.sc.Number;
}
else
{
info->notexturefill = true;
}
}
DEFINE_MAP_OPTION(lightadditivesurfaces, false)
{
if (parse.CheckAssign())
{
parse.sc.MustGetNumber();
info->lightadditivesurfaces = !!parse.sc.Number;
}
else
{
info->lightadditivesurfaces = true;
}
}
DEFINE_MAP_OPTION(skyrotate, false)
{
parse.ParseAssign();
parse.sc.MustGetFloat();
info->skyrotatevector.X = (float)parse.sc.Float;
if (parse.format_type == FMapInfoParser::FMT_New) parse.sc.MustGetStringName(",");
parse.sc.MustGetFloat();
info->skyrotatevector.Y = (float)parse.sc.Float;
if (parse.format_type == FMapInfoParser::FMT_New) parse.sc.MustGetStringName(",");
parse.sc.MustGetFloat();
info->skyrotatevector.Z = (float)parse.sc.Float;
info->skyrotatevector.MakeUnit();
}
DEFINE_MAP_OPTION(skyrotate2, false)
{
parse.ParseAssign();
parse.sc.MustGetFloat();
info->skyrotatevector2.X = (float)parse.sc.Float;
if (parse.format_type == FMapInfoParser::FMT_New) parse.sc.MustGetStringName(",");
parse.sc.MustGetFloat();
info->skyrotatevector2.Y = (float)parse.sc.Float;
if (parse.format_type == FMapInfoParser::FMT_New) parse.sc.MustGetStringName(",");
parse.sc.MustGetFloat();
info->skyrotatevector2.Z = (float)parse.sc.Float;
info->skyrotatevector2.MakeUnit();
}
//==========================================================================
//
// All flag based map options

View file

@ -504,7 +504,7 @@ void DBaseDecal::Spread (const FDecalTemplate *tpl, side_t *wall, double x, doub
int dwidth = tex->GetWidth ();
DecalWidth = dwidth * ScaleX;
DecalLeft = tex->LeftOffset * ScaleX;
DecalLeft = tex->GetLeftOffset(0) * ScaleX;
DecalRight = DecalWidth - DecalLeft;
SpreadSource = this;
SpreadTemplate = tpl;

View file

@ -76,8 +76,6 @@
#include "gl/system//gl_interface.h"
#include "vm.h"
extern int currentrenderer;
CUSTOM_CVAR (Bool, gl_lights, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
{
@ -181,12 +179,6 @@ void ADynamicLight::BeginPlay()
specialf1 = DAngle(double(SpawnAngle)).Normalized360().Degrees;
visibletoplayer = true;
if (currentrenderer == 1 && gl.legacyMode && (lightflags & LF_ATTENUATE))
{
args[LIGHT_INTENSITY] = args[LIGHT_INTENSITY] * 2 / 3;
args[LIGHT_SECONDARY_INTENSITY] = args[LIGHT_SECONDARY_INTENSITY] * 2 / 3;
}
}
//==========================================================================
@ -793,6 +785,147 @@ void ADynamicLight::OnDestroy()
}
//==========================================================================
//
//
//
//==========================================================================
void AActor::AttachLight(unsigned int count, const FLightDefaults *lightdef)
{
ADynamicLight *light;
if (count < AttachedLights.Size())
{
light = barrier_cast<ADynamicLight*>(AttachedLights[count]);
assert(light != NULL);
}
else
{
light = Spawn<ADynamicLight>(Pos(), NO_REPLACE);
light->target = this;
light->owned = true;
light->ObjectFlags |= OF_Transient;
//light->lightflags |= LF_ATTENUATE;
AttachedLights.Push(light);
}
light->flags2&=~MF2_DORMANT;
lightdef->ApplyProperties(light);
}
//==========================================================================
//
// per-state light adjustment
//
//==========================================================================
extern TArray<FLightDefaults *> StateLights;
void AActor::SetDynamicLights()
{
TArray<FInternalLightAssociation *> & LightAssociations = GetInfo()->LightAssociations;
unsigned int count = 0;
if (state == NULL) return;
if (LightAssociations.Size() > 0)
{
ADynamicLight *lights, *tmpLight;
unsigned int i;
lights = tmpLight = NULL;
for (i = 0; i < LightAssociations.Size(); i++)
{
if (LightAssociations[i]->Sprite() == sprite &&
(LightAssociations[i]->Frame()==frame || LightAssociations[i]->Frame()==-1))
{
AttachLight(count++, LightAssociations[i]->Light());
}
}
}
if (count == 0 && state->Light > 0)
{
for(int i= state->Light; StateLights[i] != NULL; i++)
{
if (StateLights[i] != (FLightDefaults*)-1)
{
AttachLight(count++, StateLights[i]);
}
}
}
for(;count<AttachedLights.Size();count++)
{
AttachedLights[count]->flags2 |= MF2_DORMANT;
memset(AttachedLights[count]->args, 0, 3*sizeof(args[0]));
}
}
//==========================================================================
//
// Needed for garbage collection
//
//==========================================================================
size_t AActor::PropagateMark()
{
for (unsigned i = 0; i<AttachedLights.Size(); i++)
{
GC::Mark(AttachedLights[i]);
}
return Super::PropagateMark();
}
//==========================================================================
//
// This is called before saving the game
//
//==========================================================================
void AActor::DeleteAllAttachedLights()
{
TThinkerIterator<AActor> it;
AActor * a;
ADynamicLight * l;
while ((a=it.Next()))
{
a->AttachedLights.Clear();
}
TThinkerIterator<ADynamicLight> it2;
l=it2.Next();
while (l)
{
ADynamicLight * ll = it2.Next();
if (l->owned) l->Destroy();
l=ll;
}
}
//==========================================================================
//
//
//
//==========================================================================
void AActor::RecreateAllAttachedLights()
{
TThinkerIterator<AActor> it;
AActor * a;
while ((a=it.Next()))
{
a->SetDynamicLights();
}
}
//==========================================================================
//
// CCMDs
//
//==========================================================================
CCMD(listlights)
{
int walls, sectors, subsecs;

View file

@ -8,17 +8,28 @@ EXTERN_CVAR(Bool, gl_attachedlights)
class ADynamicLight;
class FSerializer;
class FLightDefaults;
enum ELightType
{
PointLight,
PulseLight,
FlickerLight,
RandomFlickerLight,
SectorLight,
DummyLight,
ColorPulseLight,
ColorFlickerLight,
RandomColorFlickerLight
};
enum
{
LIGHT_RED = 0,
LIGHT_GREEN = 1,
LIGHT_BLUE = 2,
LIGHT_INTENSITY = 3,
LIGHT_SECONDARY_INTENSITY = 4,
LIGHT_SCALE = 3,
LIGHT_RED = 0,
LIGHT_GREEN = 1,
LIGHT_BLUE = 2,
LIGHT_INTENSITY = 3,
LIGHT_SECONDARY_INTENSITY = 4,
LIGHT_SCALE = 3,
};
enum LightFlag
@ -32,24 +43,111 @@ enum LightFlag
LF_SPOT = 64
};
//==========================================================================
//
// Light definitions
//
//==========================================================================
class FLightDefaults
{
public:
FLightDefaults(FName name, ELightType type);
void ApplyProperties(ADynamicLight * light) const;
FName GetName() const { return m_Name; }
void SetParameter(double p) { m_Param = p; }
void SetArg(int arg, int val) { m_Args[arg] = val; }
int GetArg(int arg) { return m_Args[arg]; }
uint8_t GetAttenuate() const { return m_attenuate; }
void SetOffset(float* ft) { m_Pos.X = ft[0]; m_Pos.Z = ft[1]; m_Pos.Y = ft[2]; }
void SetSubtractive(bool subtract) { m_subtractive = subtract; }
void SetAdditive(bool add) { m_additive = add; }
void SetDontLightSelf(bool add) { m_dontlightself = add; }
void SetAttenuate(bool on) { m_attenuate = on; }
void SetHalo(bool halo) { m_halo = halo; }
void SetDontLightActors(bool on) { m_dontlightactors = on; }
void SetSpot(bool spot) { m_spot = spot; }
void SetSpotInnerAngle(double angle) { m_spotInnerAngle = angle; }
void SetSpotOuterAngle(double angle) { m_spotOuterAngle = angle; }
void OrderIntensities()
{
if (m_Args[LIGHT_INTENSITY] > m_Args[LIGHT_SECONDARY_INTENSITY])
{
std::swap(m_Args[LIGHT_INTENSITY], m_Args[LIGHT_SECONDARY_INTENSITY]);
m_swapped = true;
}
}
protected:
FName m_Name;
int m_Args[5] = { 0,0,0,0,0 };
double m_Param = 0;
DVector3 m_Pos = { 0,0,0 };
ELightType m_type;
int8_t m_attenuate = -1;
bool m_subtractive = false;
bool m_additive = false;
bool m_halo = false;
bool m_dontlightself = false;
bool m_dontlightactors = false;
bool m_swapped = false;
bool m_spot = false;
double m_spotInnerAngle = 10.0;
double m_spotOuterAngle = 25.0;
};
//==========================================================================
//
// Light associations (intermediate parser data)
//
//==========================================================================
class FLightAssociation
{
public:
//FLightAssociation();
FLightAssociation(FName actorName, const char *frameName, FName lightName)
: m_ActorName(actorName), m_AssocLight(lightName)
{
strncpy(m_FrameName, frameName, 8);
}
FName ActorName() { return m_ActorName; }
const char *FrameName() { return m_FrameName; }
FName Light() { return m_AssocLight; }
void ReplaceLightName(FName newName) { m_AssocLight = newName; }
protected:
char m_FrameName[8];
FName m_ActorName, m_AssocLight;
};
//==========================================================================
//
// Light associations per actor class
//
//==========================================================================
class FInternalLightAssociation
{
public:
FInternalLightAssociation(FLightAssociation * asso);
int Sprite() const { return m_sprite; }
int Frame() const { return m_frame; }
const FLightDefaults *Light() const { return m_AssocLight; }
protected:
int m_sprite;
int m_frame;
FLightDefaults * m_AssocLight;
};
typedef TFlags<LightFlag> LightFlags;
DEFINE_TFLAGS_OPERATORS(LightFlags)
enum ELightType
{
PointLight,
PulseLight,
FlickerLight,
RandomFlickerLight,
SectorLight,
DummyLight,
ColorPulseLight,
ColorFlickerLight,
RandomColorFlickerLight
};
struct FLightNode
{
FLightNode ** prevTarget;

File diff suppressed because it is too large Load diff

View file

@ -220,10 +220,6 @@ void DHUDMessage::OnDestroy()
{
V_FreeBrokenLines (Lines);
Lines = NULL;
if (screen != NULL)
{
V_SetBorderNeedRefresh();
}
}
if (SourceText != NULL)
{
@ -618,7 +614,6 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh
DTA_RenderStyle, Style,
TAG_DONE);
}
V_SetBorderNeedRefresh();
}
}
@ -708,7 +703,6 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu
DTA_RenderStyle, Style,
TAG_DONE);
}
V_SetBorderNeedRefresh();
}
else
{

View file

@ -178,8 +178,8 @@ static void DrawHudText(FFont *font, int color, char * text, int x, int y, doubl
FTexture *texc = font->GetChar(text[i], &width);
if (texc != NULL)
{
double offset = texc->GetScaledTopOffsetDouble()
- tex_zero->GetScaledTopOffsetDouble()
double offset = texc->GetScaledTopOffsetDouble(0)
- tex_zero->GetScaledTopOffsetDouble(0)
+ tex_zero->GetScaledHeightDouble();
screen->DrawChar(font, color, x, y, text[i],

View file

@ -405,7 +405,6 @@ public:
void AttachToPlayer(player_t *player);
DVector2 GetHUDScale() const;
virtual void FlashCrosshair ();
virtual void BlendView (float blend[4]);
void NewGame ();
virtual void ScreenSizeChanged ();
void CallScreenSizeChanged();

View file

@ -1199,12 +1199,12 @@ public:
if((offsetflags & SBarInfoCommand::CENTER) == SBarInfoCommand::CENTER)
{
if (forceWidth < 0) dx -= (texture->GetScaledWidthDouble()/2.0)-texture->GetScaledLeftOffsetDouble();
else dx -= forceWidth*(0.5-(texture->GetScaledLeftOffsetDouble()/texture->GetScaledWidthDouble()));
if (forceWidth < 0) dx -= (texture->GetScaledWidthDouble()/2.0)-texture->GetScaledLeftOffsetDouble(0);
else dx -= forceWidth*(0.5-(texture->GetScaledLeftOffsetDouble(0)/texture->GetScaledWidthDouble()));
//Unoptimalized ^^formula is dx -= forceWidth/2.0-(texture->GetScaledLeftOffsetDouble()*forceWidth/texture->GetScaledWidthDouble());
if (forceHeight < 0) dy -= (texture->GetScaledHeightDouble()/2.0)-texture->GetScaledTopOffsetDouble();
else dy -= forceHeight*(0.5-(texture->GetScaledTopOffsetDouble()/texture->GetScaledHeightDouble()));
if (forceHeight < 0) dy -= (texture->GetScaledHeightDouble()/2.0)-texture->GetScaledTopOffsetDouble(0);
else dy -= forceHeight*(0.5-(texture->GetScaledTopOffsetDouble(0)/texture->GetScaledHeightDouble()));
}
dx += xOffset;
@ -1215,10 +1215,10 @@ public:
double tmp = 0;
w = forceWidth < 0 ? texture->GetScaledWidthDouble() : forceWidth;
h = forceHeight < 0 ? texture->GetScaledHeightDouble() : forceHeight;
double dcx = clip[0] == 0 ? 0 : dx + clip[0] - texture->GetScaledLeftOffsetDouble();
double dcy = clip[1] == 0 ? 0 : dy + clip[1] - texture->GetScaledTopOffsetDouble();
double dcr = clip[2] == 0 ? INT_MAX : dx + w - clip[2] - texture->GetScaledLeftOffsetDouble();
double dcb = clip[3] == 0 ? INT_MAX : dy + h - clip[3] - texture->GetScaledTopOffsetDouble();
double dcx = clip[0] == 0 ? 0 : dx + clip[0] - texture->GetScaledLeftOffsetDouble(0);
double dcy = clip[1] == 0 ? 0 : dy + clip[1] - texture->GetScaledTopOffsetDouble(0);
double dcr = clip[2] == 0 ? INT_MAX : dx + w - clip[2] - texture->GetScaledLeftOffsetDouble(0);
double dcb = clip[3] == 0 ? INT_MAX : dy + h - clip[3] - texture->GetScaledTopOffsetDouble(0);
if(clip[0] != 0 || clip[1] != 0)
{
@ -1300,10 +1300,10 @@ public:
// Check for clipping
if(clip[0] != 0 || clip[1] != 0 || clip[2] != 0 || clip[3] != 0)
{
rcx = clip[0] == 0 ? 0 : rx+((clip[0] - texture->GetScaledLeftOffsetDouble())*Scale.X);
rcy = clip[1] == 0 ? 0 : ry+((clip[1] - texture->GetScaledTopOffsetDouble())*Scale.Y);
rcr = clip[2] == 0 ? INT_MAX : rx+w-((clip[2] + texture->GetScaledLeftOffsetDouble())*Scale.X);
rcb = clip[3] == 0 ? INT_MAX : ry+h-((clip[3] + texture->GetScaledTopOffsetDouble())*Scale.Y);
rcx = clip[0] == 0 ? 0 : rx+((clip[0] - texture->GetScaledLeftOffsetDouble(0))*Scale.X);
rcy = clip[1] == 0 ? 0 : ry+((clip[1] - texture->GetScaledTopOffsetDouble(0))*Scale.Y);
rcr = clip[2] == 0 ? INT_MAX : rx+w-((clip[2] + texture->GetScaledLeftOffsetDouble(0))*Scale.X);
rcb = clip[3] == 0 ? INT_MAX : ry+h-((clip[3] + texture->GetScaledTopOffsetDouble(0))*Scale.Y);
}
if(clearDontDraw)
@ -1399,8 +1399,8 @@ public:
}
int character = (unsigned char)*str;
if(script->spacingCharacter == '\0') //If we are monospaced lets use the offset
ax += (c->LeftOffset+1); //ignore x offsets since we adapt to character size
if (script->spacingCharacter == '\0') //If we are monospaced lets use the offset
ax += (c->GetLeftOffset(0) + 1); //ignore x offsets since we adapt to character size
double rx, ry, rw, rh;
rx = ax + xOffset;
@ -1463,8 +1463,8 @@ public:
DTA_DestHeightF, rh,
DTA_Alpha, Alpha,
TAG_DONE);
if(script->spacingCharacter == '\0')
ax += width + spacing - (c->LeftOffset+1);
if (script->spacingCharacter == '\0')
ax += width + spacing - (c->GetLeftOffset(0) + 1);
else //width gets changed at the call to GetChar()
ax += font->GetCharWidth((unsigned char) script->spacingCharacter) + spacing;
str++;

View file

@ -95,10 +95,6 @@ extern int setblocks;
FTexture *CrosshairImage;
static int CrosshairNum;
// [RH] Base blending values (for e.g. underwater)
int BaseBlendR, BaseBlendG, BaseBlendB;
float BaseBlendA;
CVAR (Int, paletteflash, 0, CVAR_ARCHIVE)
CVAR (Flag, pf_hexenweaps, paletteflash, PF_HEXENWEAPONS)
CVAR (Flag, pf_poison, paletteflash, PF_POISON)
@ -197,10 +193,6 @@ void ST_LoadCrosshair(bool alwaysload)
return;
}
if (CrosshairImage != NULL)
{
CrosshairImage->Unload ();
}
if (num == 0)
{
CrosshairNum = 0;
@ -835,8 +827,8 @@ void DBaseStatusBar::RefreshBackground () const
{
if(y < SCREENHEIGHT)
{
V_DrawBorder (x+1, y, SCREENWIDTH, y+1);
V_DrawBorder (x+1, SCREENHEIGHT-1, SCREENWIDTH, SCREENHEIGHT);
screen->DrawBorder (x+1, y, SCREENWIDTH, y+1);
screen->DrawBorder (x+1, SCREENHEIGHT-1, SCREENWIDTH, SCREENHEIGHT);
}
}
else
@ -855,8 +847,8 @@ void DBaseStatusBar::RefreshBackground () const
x2 = SCREENWIDTH;
}
V_DrawBorder (0, y, x+1, SCREENHEIGHT);
V_DrawBorder (x2-1, y, SCREENWIDTH, SCREENHEIGHT);
screen->DrawBorder (0, y, x+1, SCREENHEIGHT);
screen->DrawBorder (x2-1, y, SCREENWIDTH, SCREENHEIGHT);
if (setblocks >= 10)
{
@ -1017,7 +1009,6 @@ void DBaseStatusBar::Draw (EHudState state)
VMValue params[] = { (DObject*)this };
VMCall(func, params, countof(params), nullptr, 0);
}
V_SetBorderNeedRefresh();
}
if (viewactive)
@ -1197,29 +1188,6 @@ void DBaseStatusBar::DrawTopStuff (EHudState state)
}
}
//---------------------------------------------------------------------------
//
// BlendView
//
//---------------------------------------------------------------------------
void DBaseStatusBar::BlendView (float blend[4])
{
// [Nash] Allow user to set blend intensity
float cnt = (BaseBlendA * underwater_fade_scalar);
V_AddBlend (BaseBlendR / 255.f, BaseBlendG / 255.f, BaseBlendB / 255.f, cnt, blend);
V_AddPlayerBlend(CPlayer, blend, 1.0f, 228);
if (screen->Accel2D || (CPlayer->camera != NULL && menuactive == MENU_Off && ConsoleState == c_up))
{
player_t *player = (CPlayer->camera != NULL && CPlayer->camera->player != NULL) ? CPlayer->camera->player : CPlayer;
V_AddBlend (player->BlendR, player->BlendG, player->BlendB, player->BlendA, blend);
}
V_SetBlend ((int)(blend[0] * 255.0f), (int)(blend[1] * 255.0f),
(int)(blend[2] * 255.0f), (int)(blend[3] * 256.0f));
}
void DBaseStatusBar::DrawConsistancy () const
{
@ -1261,7 +1229,6 @@ void DBaseStatusBar::DrawConsistancy () const
screen->DrawText (SmallFont, CR_GREEN,
(screen->GetWidth() - SmallFont->StringWidth (conbuff)*CleanXfac) / 2,
0, conbuff, DTA_CleanNoMove, true, TAG_DONE);
BorderTopRefresh = screen->GetPageCount ();
}
}
@ -1294,7 +1261,6 @@ void DBaseStatusBar::DrawWaiting () const
screen->DrawText (SmallFont, CR_ORANGE,
(screen->GetWidth() - SmallFont->StringWidth (conbuff)*CleanXfac) / 2,
SmallFont->GetHeight()*CleanYfac, conbuff, DTA_CleanNoMove, true, TAG_DONE);
BorderTopRefresh = screen->GetPageCount ();
}
}
@ -1581,14 +1547,14 @@ void DBaseStatusBar::DrawGraphic(FTextureID texture, double x, double y, int fla
{
case DI_ITEM_HCENTER: x -= boxwidth / 2; break;
case DI_ITEM_RIGHT: x -= boxwidth; break;
case DI_ITEM_HOFFSET: x -= tex->GetScaledLeftOffsetDouble() * boxwidth / texwidth; break;
case DI_ITEM_HOFFSET: x -= tex->GetScaledLeftOffsetDouble(0) * boxwidth / texwidth; break;
}
switch (flags & DI_ITEM_VMASK)
{
case DI_ITEM_VCENTER: y -= boxheight / 2; break;
case DI_ITEM_BOTTOM: y -= boxheight; break;
case DI_ITEM_VOFFSET: y -= tex->GetScaledTopOffsetDouble() * boxheight / texheight; break;
case DI_ITEM_VOFFSET: y -= tex->GetScaledTopOffsetDouble(0) * boxheight / texheight; break;
}
if (!fullscreenOffsets)
@ -1795,7 +1761,7 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d
}
if (!monospaced) //If we are monospaced lets use the offset
x += (c->LeftOffset + 1); //ignore x offsets since we adapt to character size
x += (c->GetLeftOffset(0) + 1); //ignore x offsets since we adapt to character size
double rx, ry, rw, rh;
rx = x + drawOffset.X;
@ -1835,7 +1801,7 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d
TAG_DONE);
if (!monospaced)
x += width + spacing - (c->LeftOffset + 1);
x += width + spacing - (c->GetLeftOffset(0) + 1);
else
x += spacing;
}

View file

@ -41,7 +41,6 @@
#include "actorinlines.h"
#include "g_levellocals.h"
#include "gl/dynlights/gl_dynlight.h"
#include "gl/utility/gl_geometric.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/renderer/gl_lightdata.h"
#include "gl/system/gl_interface.h"
@ -53,7 +52,6 @@
CVAR(Bool, gl_lights_additive, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CVAR(Bool, gl_legacy_mode, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOSET)
//==========================================================================
//
@ -65,7 +63,7 @@ CVAR(Bool, gl_legacy_mode, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOSET)
void gl_PatchMenu()
{
// Radial fog and Doom lighting are not available without full shader support.
if (!gl_legacy_mode) return;
if (!gl.legacyMode) return;
FOptionValues **opt = OptionValues.CheckKey("LightingModes");
if (opt != NULL)
@ -132,6 +130,31 @@ void gl_PatchMenu()
void gl_SetTextureMode(int type)
{
if (type == TM_SWCANVAS)
{
int shader = V_IsTrueColor() ? 2 : 0;
float c1[4], c2[4];
if (gl_RenderState.mColormapState > CM_DEFAULT && gl_RenderState.mColormapState < CM_MAXCOLORMAP)
{
FSpecialColormap *scm = &SpecialColormaps[gl_RenderState.mColormapState - CM_FIRSTSPECIALCOLORMAP];
for (int i = 0; i < 3; i++)
{
c1[i] = scm->ColorizeStart[i];
c2[i] = scm->ColorizeEnd[i] - scm->ColorizeStart[i];
}
c1[3] = 0;
c2[3] = 0;
shader++;
}
// Type 2 (unaltered true color) can be done without activating the shader.
if (shader != 2)
{
GLRenderer->legacyShaders->BindShader(shader, c1, c2);
return;
}
else type = TM_MODULATE;
}
glUseProgram(0);
if (type == TM_MASK)
{
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
@ -209,7 +232,7 @@ static bool currentModelMatrixState;
void FRenderState::ApplyFixedFunction()
{
int thistm = mTextureMode == TM_MODULATE && mTempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode;
int thistm = mTextureMode == TM_MODULATE && (mTempTM == TM_OPAQUE || mSpecialEffect == EFF_SWQUAD) ? TM_OPAQUE : mTextureMode;
if (thistm != ffTextureMode)
{
ffTextureMode = thistm;
@ -407,6 +430,12 @@ bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, FVector3 & nearP
float dist = fabsf(p.DistToPoint(lpos.X, lpos.Z, lpos.Y));
float radius = light->GetRadius();
if (V_IsHardwareRenderer() && gl.legacyMode && (light->lightflags & LF_ATTENUATE))
{
radius *= 0.66f;
}
if (radius <= 0.f) return false;
if (dist > radius) return false;
if (checkside && gl_lights_checkside && p.PointOnSide(lpos.X, lpos.Z, lpos.Y))
@ -486,7 +515,7 @@ static bool gl_CheckFog(FColormap *cm, int lightlevel)
{
frontfog = true;
}
else if (level.fogdensity != 0 || (glset.lightmode & 4) || cm->FogDensity > 0)
else if (level.fogdensity != 0 || (level.lightmode & 4) || cm->FogDensity > 0)
{
// case 3: level has fog density set
frontfog = true;
@ -641,7 +670,7 @@ void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass)
continue;
}
p.Set(plane.plane);
p.Set(plane.plane.Normal(), plane.plane.fD());
if (!gl_SetupLight(sub->sector->PortalGroup, p, light, nearPt, up, right, scale, false, pass != GLPASS_LIGHTTEX))
{
node = node->nextLight;
@ -715,7 +744,8 @@ bool GLWall::PrepareLight(ADynamicLight * light, int pass)
FVector3 nearPt, up, right;
float scale;
p.Set(&glseg);
auto normal = glseg.Normal();
p.Set(normal, -normal.X * glseg.x1 - normal.Y * glseg.y1);
if (!p.ValidNormal())
{
@ -849,7 +879,7 @@ void GLSceneDrawer::RenderMultipassStuff()
{
gl_RenderState.BlendFunc(GL_ONE, GL_ONE);
glDepthFunc(GL_EQUAL);
if (glset.lightmode == 8) gl_RenderState.SetSoftLightLevel(255);
if (level.lightmode == 8) gl_RenderState.SetSoftLightLevel(255);
gl_drawinfo->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(GLPASS_LIGHTTEX);
gl_drawinfo->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(GLPASS_LIGHTTEX);
gl_drawinfo->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(GLPASS_LIGHTTEX);
@ -896,3 +926,79 @@ void GLSceneDrawer::RenderMultipassStuff()
}
//==========================================================================
//
// Draws a color overlay for Legacy OpenGL
//
//==========================================================================
void LegacyColorOverlay(F2DDrawer *drawer, F2DDrawer::RenderCommand & cmd)
{
if (cmd.mDrawMode == F2DDrawer::DTM_Opaque || cmd.mDrawMode == F2DDrawer::DTM_InvertOpaque)
{
gl_RenderState.EnableTexture(false);
}
else
{
gl_RenderState.SetTextureMode(TM_MASK);
}
// Draw this the old fashioned way, there really is no point setting up a buffer for it.
glBegin(GL_TRIANGLES);
for (int i = 0; i < cmd.mIndexCount; i++)
{
auto &vertex = drawer->mVertices[drawer->mIndices[i + cmd.mIndexIndex]];
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glBlendEquation(GL_FUNC_ADD);
glColor4ub(cmd.mColor1.r, cmd.mColor1.g, cmd.mColor1.b, vertex.color0.a);
glTexCoord2f(vertex.u, vertex.v);
glVertex3f(vertex.x, vertex.y, vertex.z);
}
glEnd();
}
//==========================================================================
//
// Desaturation with translations.
// Let's keep this fallback crap strictly out of the main code,
// including the data it creates!
//
//==========================================================================
struct DesaturatedTranslations
{
FRemapTable *tables[32] = { nullptr };
};
static TMap<FRemapTable *, DesaturatedTranslations> DesaturatedTranslationTable;
static TDeletingArray<FRemapTable *> DesaturatedRemaps; // This is only here to delete the remap tables without infesting other code.
int LegacyDesaturation(F2DDrawer::RenderCommand &cmd)
{
int desat = cmd.mDesaturate / 8;
if (desat <= 0 || desat >= 32) return -1;
if(cmd.mTranslation == nullptr) return desat - 1 + STRange_Desaturate;
// Now it gets nasty. We got a combination of translation and desaturation.
// The easy case: It was already done.
auto find = DesaturatedTranslationTable.CheckKey(cmd.mTranslation);
if (find != nullptr && find->tables[desat] != nullptr) return find->tables[desat]->GetUniqueIndex();
// To handle this case for the legacy renderer a desaturated variant of the translation needs to be built.
auto newremap = new FRemapTable(*cmd.mTranslation);
DesaturatedRemaps.Push(newremap);
for (int i = 0; i < newremap->NumEntries; i++)
{
// This is used for true color texture creation, so the remap table can be left alone.
auto &p = newremap->Palette[i];
auto gray = p.Luminance();
p.r = (p.r * (31 - desat) + gray * (1 + desat)) / 32;
p.g = (p.g * (31 - desat) + gray * (1 + desat)) / 32;
p.b = (p.b * (31 - desat) + gray * (1 + desat)) / 32;
}
auto &tbl = DesaturatedTranslationTable[cmd.mTranslation];
tbl.tables[desat] = newremap;
return newremap->GetUniqueIndex();
}

View file

@ -0,0 +1,220 @@
//
//---------------------------------------------------------------------------
//
// Copyright(C) 2018 Christoph Oelckers
// All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see http://www.gnu.org/licenses/
//
//--------------------------------------------------------------------------
//
/*
** gl_swshader20.cpp
**
** Implements the shaders used to render the software renderer's
** 3D output to the screen,
**
*/
#include "gl/system/gl_system.h"
#include "tarray.h"
#include "doomtype.h"
#include "zstring.h"
#include "i_system.h"
#include "r_utility.h"
#include "w_wad.h"
#include "gl/dynlights/gl_dynlight.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/system/gl_interface.h"
#include "gl/renderer/gl_renderstate.h"
class LegacyShader
{
public:
~LegacyShader()
{
if (Program != 0) glDeleteProgram(Program);
if (VertexShader != 0) glDeleteShader(VertexShader);
if (FragmentShader != 0) glDeleteShader(FragmentShader);
}
int Program = 0;
int VertexShader = 0;
int FragmentShader = 0;
int ConstantLocations[2];
int ImageLocation = -1;
int PaletteLocation = -1;
};
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
LegacyShaderContainer::LegacyShaderContainer()
{
if (!LoadShaders())
{
Printf("Unable to compile shaders for software rendering\n");
}
}
LegacyShaderContainer::~LegacyShaderContainer()
{
for (auto p : Shaders) if (p) delete p;
}
LegacyShader* LegacyShaderContainer::CreatePixelShader(const FString& vertex, const FString& fragment, const FString &defines)
{
auto shader = new LegacyShader();
char buffer[10000];
shader->Program = glCreateProgram();
if (shader->Program == 0) { Printf("glCreateProgram failed. Disabling OpenGL hardware acceleration.\n"); return nullptr; }
shader->VertexShader = glCreateShader(GL_VERTEX_SHADER);
if (shader->VertexShader == 0) { Printf("glCreateShader(GL_VERTEX_SHADER) failed. Disabling OpenGL hardware acceleration.\n"); return nullptr; }
shader->FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
if (shader->FragmentShader == 0) { Printf("glCreateShader(GL_FRAGMENT_SHADER) failed. Disabling OpenGL hardware acceleration.\n"); return nullptr; }
{
FString vertexsrc = defines + vertex;
int lengths[1] = { (int)vertexsrc.Len() };
const char *sources[1] = { vertexsrc.GetChars() };
glShaderSource(shader->VertexShader, 1, sources, lengths);
glCompileShader(shader->VertexShader);
}
{
FString fragmentsrc = defines + fragment;
int lengths[1] = { (int)fragmentsrc.Len() };
const char *sources[1] = { fragmentsrc.GetChars() };
glShaderSource(shader->FragmentShader, 1, sources, lengths);
glCompileShader(shader->FragmentShader);
}
GLint status = 0;
int errorShader = shader->VertexShader;
glGetShaderiv(shader->VertexShader, GL_COMPILE_STATUS, &status);
if (status != GL_FALSE)
{
errorShader = shader->FragmentShader;
glGetShaderiv(shader->FragmentShader, GL_COMPILE_STATUS, &status);
}
if (status == GL_FALSE)
{
GLsizei length = 0;
buffer[0] = 0;
glGetShaderInfoLog(errorShader, 10000, &length, buffer);
Printf("Shader compile failed: %s", buffer);
delete shader;
return nullptr;
}
glAttachShader(shader->Program, shader->VertexShader);
glAttachShader(shader->Program, shader->FragmentShader);
glLinkProgram(shader->Program);
glGetProgramiv(shader->Program, GL_LINK_STATUS, &status);
if (status == GL_FALSE)
{
GLsizei length = 0;
buffer[0] = 0;
glGetProgramInfoLog(shader->Program, 10000, &length, buffer);
Printf("Shader link failed: %s", buffer);
delete shader;
return nullptr;
}
shader->ConstantLocations[0] = glGetUniformLocation(shader->Program, "uColor1");
shader->ConstantLocations[1] = glGetUniformLocation(shader->Program, "uColor2");
shader->ImageLocation = glGetUniformLocation(shader->Program, "tex");
shader->PaletteLocation = glGetUniformLocation(shader->Program, "palette");
return shader;
}
//==========================================================================
//
// SWSceneDrawer :: LoadShaders
//
// Returns true if all required shaders were loaded. (Gamma and burn wipe
// are the only ones not considered "required".)
//
//==========================================================================
static const char * const ShaderDefines[] = {
"#define PAL_TEX\n",
"#define PAL_TEX\n#define SPECIALCM\n",
"",
"#define SPECIALCM\n",
};
bool LegacyShaderContainer::LoadShaders()
{
int lumpvert = Wads.CheckNumForFullName("shaders/swgl/swshadergl2.vp");
int lumpfrag = Wads.CheckNumForFullName("shaders/swgl/swshadergl2.fp");
if (lumpvert < 0 || lumpfrag < 0)
return false;
FString vertsource = Wads.ReadLump(lumpvert).GetString();
FString fragsource = Wads.ReadLump(lumpfrag).GetString();
FString shaderdir, shaderpath;
unsigned int i;
for (i = 0; i < NUM_SHADERS; ++i)
{
shaderpath = shaderdir;
Shaders[i] = CreatePixelShader(vertsource, fragsource, ShaderDefines[i]);
if (!Shaders[i])
{
break;
}
glUseProgram(Shaders[i]->Program);
if (Shaders[i]->ImageLocation != -1) glUniform1i(Shaders[i]->ImageLocation, 0);
if (Shaders[i]->PaletteLocation != -1) glUniform1i(Shaders[i]->PaletteLocation, 1);
glUseProgram(0);
}
if (i == NUM_SHADERS)
{ // Success!
return true;
}
// Failure. Release whatever managed to load (which is probably nothing.)
for (i = 0; i < NUM_SHADERS; ++i)
{
if (Shaders[i]) delete Shaders[i];
}
return false;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void LegacyShaderContainer::BindShader(int num, const float *p1, const float *p2)
{
if (num >= 0 && num < 4)
{
auto shader = Shaders[num];
glUseProgram(shader->Program);
glUniform4fv(shader->ConstantLocations[0], 1, p1);
glUniform4fv(shader->ConstantLocations[1], 1, p2);
}
}

View file

@ -1,414 +0,0 @@
//
//---------------------------------------------------------------------------
//
// Copyright(C) 2005-2016 Christoph Oelckers
// All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see http://www.gnu.org/licenses/
//
//--------------------------------------------------------------------------
//
/*
** gl_data.cpp
** Maintenance data for GL renderer (mostly to handle rendering hacks)
**
**/
#include "gl/system/gl_system.h"
#include "doomtype.h"
#include "colormatcher.h"
#include "i_system.h"
#include "p_local.h"
#include "p_tags.h"
#include "p_lnspec.h"
#include "c_dispatch.h"
#include "r_sky.h"
#include "sc_man.h"
#include "w_wad.h"
#include "gi.h"
#include "g_level.h"
#include "doomstat.h"
#include "d_player.h"
#include "g_levellocals.h"
#include "gl/system/gl_interface.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/renderer/gl_lightdata.h"
#include "gl/data/gl_data.h"
#include "gl/dynlights/gl_dynlight.h"
#include "gl/dynlights/gl_glow.h"
#include "gl/models/gl_models.h"
#include "gl/utility/gl_clock.h"
#include "gl/shaders/gl_shader.h"
#include "gl/gl_functions.h"
GLRenderSettings glset;
EXTERN_CVAR(Int, gl_lightmode)
EXTERN_CVAR(Bool, gl_brightfog)
EXTERN_CVAR(Bool, gl_lightadditivesurfaces)
CUSTOM_CVAR(Bool, gl_notexturefill, false, 0)
{
glset.notexturefill = self;
}
void gl_CreateSections();
void AddAutoMaterials();
//-----------------------------------------------------------------------------
//
// Adjust sprite offsets for GL rendering (IWAD resources only)
//
//-----------------------------------------------------------------------------
void AdjustSpriteOffsets()
{
int lump, lastlump = 0;
int sprid;
TMap<int, bool> donotprocess;
int numtex = Wads.GetNumLumps();
for (int i = 0; i < numtex; i++)
{
if (Wads.GetLumpFile(i) > Wads.GetIwadNum()) break; // we are past the IWAD
if (Wads.GetLumpNamespace(i) == ns_sprites && Wads.GetLumpFile(i) == Wads.GetIwadNum())
{
char str[9];
Wads.GetLumpName(str, i);
str[8] = 0;
FTextureID texid = TexMan.CheckForTexture(str, ETextureType::Sprite, 0);
if (texid.isValid() && Wads.GetLumpFile(TexMan[texid]->SourceLump) > Wads.GetIwadNum())
{
// This texture has been replaced by some PWAD.
memcpy(&sprid, str, 4);
donotprocess[sprid] = true;
}
}
}
while ((lump = Wads.FindLump("SPROFS", &lastlump, false)) != -1)
{
FScanner sc;
sc.OpenLumpNum(lump);
sc.SetCMode(true);
GLRenderer->FlushTextures();
int ofslumpno = Wads.GetLumpFile(lump);
while (sc.GetString())
{
int x,y;
bool iwadonly = false;
bool forced = false;
FTextureID texno = TexMan.CheckForTexture(sc.String, ETextureType::Sprite);
sc.MustGetStringName(",");
sc.MustGetNumber();
x=sc.Number;
sc.MustGetStringName(",");
sc.MustGetNumber();
y=sc.Number;
if (sc.CheckString(","))
{
sc.MustGetString();
if (sc.Compare("iwad")) iwadonly = true;
if (sc.Compare("iwadforced")) forced = iwadonly = true;
}
if (texno.isValid())
{
FTexture * tex = TexMan[texno];
int lumpnum = tex->GetSourceLump();
// We only want to change texture offsets for sprites in the IWAD or the file this lump originated from.
if (lumpnum >= 0 && lumpnum < Wads.GetNumLumps())
{
int wadno = Wads.GetLumpFile(lumpnum);
if ((iwadonly && wadno==Wads.GetIwadNum()) || (!iwadonly && wadno == ofslumpno))
{
if (wadno == Wads.GetIwadNum() && !forced && iwadonly)
{
memcpy(&sprid, &tex->Name[0], 4);
if (donotprocess.CheckKey(sprid)) continue; // do not alter sprites that only get partially replaced.
}
tex->LeftOffset=x;
tex->TopOffset=y;
tex->KillNative();
}
}
}
}
}
}
//==========================================================================
//
// Portal identifier lists
//
//==========================================================================
//==========================================================================
//
// MAPINFO stuff
//
//==========================================================================
struct FGLROptions : public FOptionalMapinfoData
{
FGLROptions()
{
identifier = "gl_renderer";
brightfog = false;
lightmode = -1;
notexturefill = -1;
skyrotatevector = FVector3(0,0,1);
skyrotatevector2 = FVector3(0,0,1);
lightadditivesurfaces = false;
}
virtual FOptionalMapinfoData *Clone() const
{
FGLROptions *newopt = new FGLROptions;
newopt->identifier = identifier;
newopt->lightmode = lightmode;
newopt->notexturefill = notexturefill;
newopt->skyrotatevector = skyrotatevector;
newopt->skyrotatevector2 = skyrotatevector2;
newopt->lightadditivesurfaces = lightadditivesurfaces;
return newopt;
}
int lightmode;
int brightfog;
int8_t lightadditivesurfaces;
int8_t notexturefill;
FVector3 skyrotatevector;
FVector3 skyrotatevector2;
};
DEFINE_MAP_OPTION(brightfog, false)
{
FGLROptions *opt = info->GetOptData<FGLROptions>("gl_renderer");
parse.ParseAssign();
parse.sc.MustGetNumber();
opt->brightfog = parse.sc.Number;
}
DEFINE_MAP_OPTION(lightmode, false)
{
FGLROptions *opt = info->GetOptData<FGLROptions>("gl_renderer");
parse.ParseAssign();
parse.sc.MustGetNumber();
opt->lightmode = uint8_t(parse.sc.Number);
}
DEFINE_MAP_OPTION(notexturefill, false)
{
FGLROptions *opt = info->GetOptData<FGLROptions>("gl_renderer");
if (parse.CheckAssign())
{
parse.sc.MustGetNumber();
opt->notexturefill = !!parse.sc.Number;
}
else
{
opt->notexturefill = true;
}
}
DEFINE_MAP_OPTION(lightadditivesurfaces, false)
{
FGLROptions *opt = info->GetOptData<FGLROptions>("gl_renderer");
if (parse.CheckAssign())
{
parse.sc.MustGetNumber();
opt->lightadditivesurfaces = !!parse.sc.Number;
}
else
{
opt->lightadditivesurfaces = true;
}
}
DEFINE_MAP_OPTION(skyrotate, false)
{
FGLROptions *opt = info->GetOptData<FGLROptions>("gl_renderer");
parse.ParseAssign();
parse.sc.MustGetFloat();
opt->skyrotatevector.X = (float)parse.sc.Float;
if (parse.format_type == FMapInfoParser::FMT_New) parse.sc.MustGetStringName(",");
parse.sc.MustGetFloat();
opt->skyrotatevector.Y = (float)parse.sc.Float;
if (parse.format_type == FMapInfoParser::FMT_New) parse.sc.MustGetStringName(",");
parse.sc.MustGetFloat();
opt->skyrotatevector.Z = (float)parse.sc.Float;
opt->skyrotatevector.MakeUnit();
}
DEFINE_MAP_OPTION(skyrotate2, false)
{
FGLROptions *opt = info->GetOptData<FGLROptions>("gl_renderer");
parse.ParseAssign();
parse.sc.MustGetFloat();
opt->skyrotatevector2.X = (float)parse.sc.Float;
if (parse.format_type == FMapInfoParser::FMT_New) parse.sc.MustGetStringName(",");
parse.sc.MustGetFloat();
opt->skyrotatevector2.Y = (float)parse.sc.Float;
if (parse.format_type == FMapInfoParser::FMT_New) parse.sc.MustGetStringName(",");
parse.sc.MustGetFloat();
opt->skyrotatevector2.Z = (float)parse.sc.Float;
opt->skyrotatevector2.MakeUnit();
}
bool IsLightmodeValid()
{
return (glset.map_lightmode >= 0 && glset.map_lightmode <= 4) || glset.map_lightmode == 8;
}
static void ResetOpts()
{
if (!IsLightmodeValid()) glset.lightmode = gl_lightmode;
else glset.lightmode = glset.map_lightmode;
if (glset.map_notexturefill == -1) glset.notexturefill = gl_notexturefill;
else glset.notexturefill = !!glset.map_notexturefill;
if (glset.map_brightfog == -1) glset.brightfog = gl_brightfog;
else glset.brightfog = !!glset.map_brightfog;
if (glset.map_lightadditivesurfaces == -1) glset.lightadditivesurfaces = gl_lightadditivesurfaces;
else glset.lightadditivesurfaces = !!glset.map_lightadditivesurfaces;
}
void InitGLRMapinfoData()
{
FGLROptions *opt = level.info->GetOptData<FGLROptions>("gl_renderer", false);
if (opt != NULL)
{
glset.map_lightmode = opt->lightmode;
glset.map_lightadditivesurfaces = opt->lightadditivesurfaces;
glset.map_brightfog = opt->brightfog;
glset.map_notexturefill = opt->notexturefill;
glset.skyrotatevector = opt->skyrotatevector;
glset.skyrotatevector2 = opt->skyrotatevector2;
}
else
{
glset.map_lightmode = -1;
glset.map_lightadditivesurfaces = -1;
glset.map_brightfog = -1;
glset.map_notexturefill = -1;
glset.skyrotatevector = FVector3(0, 0, 1);
glset.skyrotatevector2 = FVector3(0, 0, 1);
}
ResetOpts();
}
CCMD(gl_resetmap)
{
ResetOpts();
}
//==========================================================================
//
// Recalculate all heights affecting this vertex.
//
//==========================================================================
void gl_RecalcVertexHeights(vertex_t * v)
{
int i,j,k;
float height;
v->numheights=0;
for(i=0;i<v->numsectors;i++)
{
for(j=0;j<2;j++)
{
if (j==0) height=v->sectors[i]->ceilingplane.ZatPoint(v);
else height=v->sectors[i]->floorplane.ZatPoint(v);
for(k=0;k<v->numheights;k++)
{
if (height == v->heightlist[k]) break;
if (height < v->heightlist[k])
{
memmove(&v->heightlist[k+1], &v->heightlist[k], sizeof(float) * (v->numheights-k));
v->heightlist[k]=height;
v->numheights++;
break;
}
}
if (k==v->numheights) v->heightlist[v->numheights++]=height;
}
}
if (v->numheights<=2) v->numheights=0; // is not in need of any special attention
v->dirty = false;
}
void gl_InitData()
{
AdjustSpriteOffsets();
AddAutoMaterials();
}
//==========================================================================
//
// dumpgeometry
//
//==========================================================================
CCMD(dumpgeometry)
{
for(auto &sector : level.sectors)
{
Printf(PRINT_LOG, "Sector %d\n", sector.sectornum);
for(int j=0;j<sector.subsectorcount;j++)
{
subsector_t * sub = sector.subsectors[j];
Printf(PRINT_LOG, " Subsector %d - real sector = %d - %s\n", int(sub->Index()), sub->sector->sectornum, sub->hacked&1? "hacked":"");
for(uint32_t k=0;k<sub->numlines;k++)
{
seg_t * seg = sub->firstline + k;
if (seg->linedef)
{
Printf(PRINT_LOG, " (%4.4f, %4.4f), (%4.4f, %4.4f) - seg %d, linedef %d, side %d",
seg->v1->fX(), seg->v1->fY(), seg->v2->fX(), seg->v2->fY(),
seg->Index(), seg->linedef->Index(), seg->sidedef != seg->linedef->sidedef[0]);
}
else
{
Printf(PRINT_LOG, " (%4.4f, %4.4f), (%4.4f, %4.4f) - seg %d, miniseg",
seg->v1->fX(), seg->v1->fY(), seg->v2->fX(), seg->v2->fY(), seg->Index());
}
if (seg->PartnerSeg)
{
subsector_t * sub2 = seg->PartnerSeg->Subsector;
Printf(PRINT_LOG, ", back sector = %d, real back sector = %d", sub2->render_sector->sectornum, seg->PartnerSeg->frontsector->sectornum);
}
else if (seg->backsector)
{
Printf(PRINT_LOG, ", back sector = %d (no partnerseg)", seg->backsector->sectornum);
}
Printf(PRINT_LOG, "\n");
}
}
}
}

View file

@ -1,68 +0,0 @@
#ifndef __GLC_DATA_H
#define __GLC_DATA_H
#include "doomtype.h"
#include "vectors.h"
#include "r_utility.h"
struct GLRenderSettings
{
int8_t lightmode;
bool notexturefill;
bool brightfog;
bool lightadditivesurfaces;
int8_t map_lightmode;
int8_t map_notexturefill;
int8_t map_brightfog;
int8_t map_lightadditivesurfaces;
FVector3 skyrotatevector;
FVector3 skyrotatevector2;
};
extern GLRenderSettings glset;
#include "r_defs.h"
#include "a_sharedglobal.h"
#include "c_cvars.h"
EXTERN_CVAR(Int, gl_weaponlight);
inline int getExtraLight()
{
return r_viewpoint.extralight * gl_weaponlight;
}
void gl_RecalcVertexHeights(vertex_t * v);
struct GLSectorStackPortal;
struct FPortal
{
DVector2 mDisplacement;
int plane;
GLSectorStackPortal *glportal; // for quick access to the render data. This is only valid during BSP traversal!
GLSectorStackPortal *GetRenderState();
};
struct FGLLinePortal
{
// defines the complete span of this portal, if this is of type PORTT_LINKED.
vertex_t *v1 = nullptr, *v2 = nullptr; // vertices, from v1 to v2
TArray<FLinePortal *> lines;
int validcount = 0;
};
extern TArray<FPortal *> glSectorPortals;
extern TArray<FGLLinePortal*> linePortalToGL;
extern TArray<uint8_t> currentmapsection;
void gl_InitPortals();
void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, const DVector2 &displacement);
void gl_InitData();
#endif

View file

@ -35,7 +35,6 @@
#include "gl/system/gl_interface.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/shaders/gl_shader.h"
#include "gl/data/gl_data.h"
#include "gl/data/gl_vertexbuffer.h"
@ -170,9 +169,9 @@ FFlatVertexBuffer::FFlatVertexBuffer(int width, int height)
// and the second one for the fullscreen quad used for blend overlays.
vbo_shadowdata[4].Set(0, 0, 0, 0, 0);
vbo_shadowdata[5].Set(0, (float)height, 0, 0, 0);
vbo_shadowdata[6].Set((float)width, 0, 0, 0, 0);
vbo_shadowdata[7].Set((float)width, (float)height, 0, 0, 0);
vbo_shadowdata[5].Set(0, (float)height, 0, 0, 1);
vbo_shadowdata[6].Set((float)width, 0, 0, 1, 0);
vbo_shadowdata[7].Set((float)width, (float)height, 0, 1, 1);
// and this is for the postprocessing copy operation
vbo_shadowdata[8].Set(-1.0f, -1.0f, 0, 0.0f, 0.0f);
@ -218,10 +217,10 @@ FFlatVertexBuffer::~FFlatVertexBuffer()
void FFlatVertexBuffer::OutputResized(int width, int height)
{
vbo_shadowdata[4].Set(0, 0, 0, 0, 0);
vbo_shadowdata[5].Set(0, (float)height, 0, 0, 0);
vbo_shadowdata[6].Set((float)width, 0, 0, 0, 0);
vbo_shadowdata[7].Set((float)width, (float)height, 0, 0, 0);
vbo_shadowdata[5].Set(0, (float)height, 0, 0, 1);
vbo_shadowdata[6].Set((float)width, 0, 0, 1, 0);
vbo_shadowdata[7].Set((float)width, (float)height, 0, 1, 1);
Map();
memcpy(&map[4], &vbo_shadowdata[4], 4 * sizeof(FFlatVertex));
Unmap();
@ -299,7 +298,7 @@ static F3DFloor *Find3DFloor(sector_t *target, sector_t *model)
for(unsigned i=0; i<target->e->XFloor.ffloors.Size(); i++)
{
F3DFloor *ffloor = target->e->XFloor.ffloors[i];
if (ffloor->model == model) return ffloor;
if (ffloor->model == model && !(ffloor->flags & FF_THISINSIDE)) return ffloor;
}
return NULL;
}

View file

@ -25,7 +25,6 @@
#include "c_cvars.h"
#include "a_dynlight.h"
#include "gl/utility/gl_geometric.h"
struct FDynLightData

View file

@ -29,7 +29,6 @@
#include "c_dispatch.h"
#include "p_local.h"
#include "vectors.h"
#include "gl/gl_functions.h"
#include "g_level.h"
#include "actorinlines.h"
#include "a_dynlight.h"
@ -37,7 +36,6 @@
#include "gl/system/gl_interface.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/renderer/gl_lightdata.h"
#include "gl/data/gl_data.h"
#include "gl/dynlights/gl_dynlight.h"
#include "gl/scene/gl_drawinfo.h"
#include "gl/scene/gl_portal.h"

View file

@ -1,208 +0,0 @@
//
//---------------------------------------------------------------------------
//
// Copyright(C) 2005-2016 Christoph Oelckers
// All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see http://www.gnu.org/licenses/
//
//--------------------------------------------------------------------------
//
/*
** gl_glow.cpp
** Glowing flats like Doomsday
**
**/
#include "w_wad.h"
#include "sc_man.h"
#include "v_video.h"
#include "r_defs.h"
#include "textures/textures.h"
#include "gl/dynlights/gl_glow.h"
//===========================================================================
//
// Reads glow definitions from GLDEFS
//
//===========================================================================
void gl_InitGlow(FScanner &sc)
{
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{
sc.MustGetString();
if (sc.Compare("FLATS"))
{
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{
sc.MustGetString();
FTextureID flump=TexMan.CheckForTexture(sc.String, ETextureType::Flat,FTextureManager::TEXMAN_TryAny);
FTexture *tex = TexMan[flump];
if (tex) tex->gl_info.bAutoGlowing = tex->gl_info.bGlowing = tex->gl_info.bFullbright = true;
}
}
else if (sc.Compare("WALLS"))
{
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{
sc.MustGetString();
FTextureID flump=TexMan.CheckForTexture(sc.String, ETextureType::Wall,FTextureManager::TEXMAN_TryAny);
FTexture *tex = TexMan[flump];
if (tex) tex->gl_info.bAutoGlowing = tex->gl_info.bGlowing = tex->gl_info.bFullbright = true;
}
}
else if (sc.Compare("TEXTURE"))
{
sc.SetCMode(true);
sc.MustGetString();
FTextureID flump=TexMan.CheckForTexture(sc.String, ETextureType::Flat,FTextureManager::TEXMAN_TryAny);
FTexture *tex = TexMan[flump];
sc.MustGetStringName(",");
sc.MustGetString();
PalEntry color = V_GetColor(NULL, sc.String);
//sc.MustGetStringName(",");
//sc.MustGetNumber();
if (sc.CheckString(","))
{
if (sc.CheckNumber())
{
if (tex) tex->gl_info.GlowHeight = sc.Number;
if (!sc.CheckString(",")) goto skip_fb;
}
sc.MustGetStringName("fullbright");
if (tex) tex->gl_info.bFullbright = true;
}
skip_fb:
sc.SetCMode(false);
if (tex && color != 0)
{
tex->gl_info.bAutoGlowing = false;
tex->gl_info.bGlowing = true;
tex->gl_info.GlowColor = color;
}
}
}
}
//==========================================================================
//
// Checks whether a sprite should be affected by a glow
//
//==========================================================================
int gl_CheckSpriteGlow(sector_t *sector, int lightlevel, const DVector3 &pos)
{
float bottomglowcolor[4];
bottomglowcolor[3] = 0;
auto c = sector->planes[sector_t::floor].GlowColor;
if (c == 0)
{
FTexture *tex = TexMan[sector->GetTexture(sector_t::floor)];
if (tex != NULL && tex->isGlowing())
{
if (!tex->gl_info.bAutoGlowing) tex = TexMan(sector->GetTexture(sector_t::floor));
if (tex->isGlowing()) // recheck the current animation frame.
{
tex->GetGlowColor(bottomglowcolor);
bottomglowcolor[3] = (float)tex->gl_info.GlowHeight;
}
}
}
else if (c != ~0u)
{
bottomglowcolor[0] = c.r / 255.f;
bottomglowcolor[1] = c.g / 255.f;
bottomglowcolor[2] = c.b / 255.f;
bottomglowcolor[3] = sector->planes[sector_t::floor].GlowHeight;
}
if (bottomglowcolor[3]> 0)
{
double floordiff = pos.Z - sector->floorplane.ZatPoint(pos);
if (floordiff < bottomglowcolor[3])
{
int maxlight = (255 + lightlevel) >> 1;
double lightfrac = floordiff / bottomglowcolor[3];
if (lightfrac < 0) lightfrac = 0;
lightlevel = int(lightfrac*lightlevel + maxlight*(1 - lightfrac));
}
}
return lightlevel;
}
//==========================================================================
//
// Checks whether a wall should glow
//
//==========================================================================
bool gl_GetWallGlow(sector_t *sector, float *topglowcolor, float *bottomglowcolor)
{
bool ret = false;
bottomglowcolor[3] = topglowcolor[3] = 0;
auto c = sector->planes[sector_t::ceiling].GlowColor;
if (c == 0)
{
FTexture *tex = TexMan[sector->GetTexture(sector_t::ceiling)];
if (tex != NULL && tex->isGlowing())
{
if (!tex->gl_info.bAutoGlowing) tex = TexMan(sector->GetTexture(sector_t::ceiling));
if (tex->isGlowing()) // recheck the current animation frame.
{
ret = true;
tex->GetGlowColor(topglowcolor);
topglowcolor[3] = (float)tex->gl_info.GlowHeight;
}
}
}
else if (c != ~0u)
{
topglowcolor[0] = c.r / 255.f;
topglowcolor[1] = c.g / 255.f;
topglowcolor[2] = c.b / 255.f;
topglowcolor[3] = sector->planes[sector_t::ceiling].GlowHeight;
ret = topglowcolor[3] > 0;
}
c = sector->planes[sector_t::floor].GlowColor;
if (c == 0)
{
FTexture *tex = TexMan[sector->GetTexture(sector_t::floor)];
if (tex != NULL && tex->isGlowing())
{
if (!tex->gl_info.bAutoGlowing) tex = TexMan(sector->GetTexture(sector_t::floor));
if (tex->isGlowing()) // recheck the current animation frame.
{
ret = true;
tex->GetGlowColor(bottomglowcolor);
bottomglowcolor[3] = (float)tex->gl_info.GlowHeight;
}
}
}
else if (c != ~0u)
{
bottomglowcolor[0] = c.r / 255.f;
bottomglowcolor[1] = c.g / 255.f;
bottomglowcolor[2] = c.b / 255.f;
bottomglowcolor[3] = sector->planes[sector_t::floor].GlowHeight;
ret = bottomglowcolor[3] > 0;
}
return ret;
}

View file

@ -1,11 +0,0 @@
#ifndef __GL_GLOW
#define __GL_GLOW
struct sector_t;
void gl_InitGlow(const char * lumpnm);
int gl_CheckSpriteGlow(sector_t *sec, int lightlevel, const DVector3 &pos);
bool gl_GetWallGlow(sector_t *sector, float *topglowcolor, float *bottomglowcolor);
#endif

View file

@ -216,18 +216,18 @@ void FShadowMap::UploadAABBTree()
if (mAABBTree)
return;
mAABBTree.reset(new LevelAABBTree());
mAABBTree.reset(new hwrenderer::LevelAABBTree());
int oldBinding = 0;
glGetIntegerv(GL_SHADER_STORAGE_BUFFER_BINDING, &oldBinding);
glGenBuffers(1, (GLuint*)&mNodesBuffer);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, mNodesBuffer);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(AABBTreeNode) * mAABBTree->nodes.Size(), &mAABBTree->nodes[0], GL_STATIC_DRAW);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(hwrenderer::AABBTreeNode) * mAABBTree->nodes.Size(), &mAABBTree->nodes[0], GL_STATIC_DRAW);
glGenBuffers(1, (GLuint*)&mLinesBuffer);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, mLinesBuffer);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(AABBTreeLine) * mAABBTree->lines.Size(), &mAABBTree->lines[0], GL_STATIC_DRAW);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(hwrenderer::AABBTreeLine) * mAABBTree->lines.Size(), &mAABBTree->lines[0], GL_STATIC_DRAW);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, oldBinding);
}

View file

@ -1,7 +1,7 @@
#pragma once
#include "gl/dynlights/gl_aabbtree.h"
#include "hwrenderer/dynlights/hw_aabbtree.h"
#include "tarray.h"
#include <memory>
@ -55,7 +55,7 @@ private:
unsigned mLastNumSegs = 0;
// AABB-tree of the level, used for ray tests
std::unique_ptr<LevelAABBTree> mAABBTree;
std::unique_ptr<hwrenderer::LevelAABBTree> mAABBTree;
FShadowMap(const FShadowMap &) = delete;
FShadowMap &operator=(FShadowMap &) = delete;

View file

@ -1,12 +0,0 @@
#ifndef __GL_FUNCT
#define __GL_FUNCT
#include "v_palette.h"
class AActor;
void gl_PreprocessLevel();
void gl_CleanLevelData();
void gl_LinkLights();
#endif

View file

@ -49,14 +49,11 @@
#include "gl/scene/gl_portal.h"
#include "gl/models/gl_models.h"
#include "gl/textures/gl_material.h"
#include "gl/utility/gl_convert.h"
#include "gl/renderer/gl_renderstate.h"
#include "gl/shaders/gl_shader.h"
CVAR(Bool, gl_light_models, true, CVAR_ARCHIVE)
extern int modellightindex;
VSMatrix FGLModelRenderer::GetViewToWorldMatrix()
{
VSMatrix objectToWorldMatrix;
@ -360,9 +357,9 @@ void FModelVertexBuffer::SetupFrame(FModelRenderer *renderer, unsigned int frame
//
//===========================================================================
void gl_RenderModel(GLSprite * spr)
void gl_RenderModel(GLSprite * spr, int mli)
{
FGLModelRenderer renderer;
FGLModelRenderer renderer(mli);
renderer.RenderModel(spr->x, spr->y, spr->z, spr->modelframe, spr->actor);
}
@ -372,8 +369,8 @@ void gl_RenderModel(GLSprite * spr)
//
//===========================================================================
void gl_RenderHUDModel(DPSprite *psp, float ofsX, float ofsY)
void gl_RenderHUDModel(DPSprite *psp, float ofsX, float ofsY, int mli)
{
FGLModelRenderer renderer;
FGLModelRenderer renderer(mli);
renderer.RenderHUDModel(psp, ofsX, ofsY);
}

View file

@ -32,7 +32,10 @@ class GLSprite;
class FGLModelRenderer : public FModelRenderer
{
int modellightindex = -1;
public:
FGLModelRenderer(int mli) : modellightindex(mli)
{}
void BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix) override;
void EndDrawModel(AActor *actor, FSpriteModelFrame *smf) override;
IModelVertexBuffer *CreateVertexBuffer(bool needindex, bool singleframe) override;
@ -48,5 +51,5 @@ public:
double GetTimeFloat() override;
};
void gl_RenderModel(GLSprite * spr);
void gl_RenderHUDModel(DPSprite *psp, float ofsx, float ofsy);
void gl_RenderModel(GLSprite * spr, int mli);
void gl_RenderHUDModel(DPSprite *psp, float ofsx, float ofsy, int mli);

View file

@ -1,492 +0,0 @@
//
//---------------------------------------------------------------------------
//
// Copyright(C) 2016 Christoph Oelckers
// All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see http://www.gnu.org/licenses/
//
//--------------------------------------------------------------------------
//
/*
** gl_2ddrawer.h
** Container class for drawing 2d graphics with a vertex buffer
**
**/
#include "gl/system/gl_system.h"
#include "gl/system/gl_framebuffer.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/renderer/gl_2ddrawer.h"
#include "gl/textures/gl_material.h"
#include "gl/renderer/gl_renderstate.h"
#include "gl/renderer/gl_lightdata.h"
#include "gl/scene/gl_drawinfo.h"
#include "gl/textures/gl_translate.h"
#include "vectors.h"
//==========================================================================
//
//
//
//==========================================================================
int F2DDrawer::AddData(const F2DDrawer::DataGeneric *data)
{
int addr = mData.Reserve(data->mLen);
memcpy(&mData[addr], data, data->mLen);
mLastLineCmd = -1;
return addr;
}
//==========================================================================
//
// Draws a texture
//
//==========================================================================
void F2DDrawer::AddTexture(FTexture *img, DrawParms &parms)
{
double xscale = parms.destwidth / parms.texwidth;
double yscale = parms.destheight / parms.texheight;
double x = parms.x - parms.left * xscale;
double y = parms.y - parms.top * yscale;
double w = parms.destwidth;
double h = parms.destheight;
float u1, v1, u2, v2;
int light = 255;
FMaterial * gltex = FMaterial::ValidateTexture(img, false);
if (gltex == nullptr) return;
DataTexture dg;
dg.mType = DrawTypeTexture;
dg.mLen = (sizeof(dg) + 7) & ~7;
dg.mVertCount = 4;
dg.mRenderStyle = parms.style;
dg.mMasked = !!parms.masked;
dg.mTexture = gltex;
if (parms.colorOverlay && (parms.colorOverlay & 0xffffff) == 0)
{
// handle black overlays as reduced light.
light = 255 - APART(parms.colorOverlay);
parms.colorOverlay = 0;
}
dg.mVertIndex = (int)mVertices.Reserve(parms.colorOverlay == 0? 4 : 8);
dg.mColorOverlay = parms.colorOverlay;
dg.mTranslation = 0;
if (!img->bHasCanvas)
{
dg.mAlphaTexture = !!(parms.style.Flags & STYLEF_RedIsAlpha);
if (!dg.mAlphaTexture)
{
if (parms.remap != NULL && !parms.remap->Inactive)
{
GLTranslationPalette * pal = static_cast<GLTranslationPalette*>(parms.remap->GetNative());
if (pal) dg.mTranslation = -pal->GetIndex();
}
}
u1 = gltex->GetUL();
v1 = gltex->GetVT();
u2 = gltex->GetUR();
v2 = gltex->GetVB();
}
else
{
dg.mAlphaTexture = false;
u1 = 0.f;
v1 = 1.f;
u2 = 1.f;
v2 = 0.f;
}
if (parms.flipX)
std::swap(u1, u2);
if (parms.windowleft > 0 || parms.windowright < parms.texwidth)
{
double wi = MIN(parms.windowright, parms.texwidth);
x += parms.windowleft * xscale;
w -= (parms.texwidth - wi + parms.windowleft) * xscale;
u1 = float(u1 + parms.windowleft / parms.texwidth);
u2 = float(u2 - (parms.texwidth - wi) / parms.texwidth);
}
PalEntry color;
if (parms.style.Flags & STYLEF_ColorIsFixed)
{
color = parms.fillcolor;
}
else
{
color = PalEntry(light, light, light);
}
color.a = (uint8_t)(parms.Alpha * 255);
// red and blue channels are swapped to use value as vertex color
color = PalEntry((color.a * parms.color.a) / 255, (color.b * parms.color.b) / 255, (color.g * parms.color.g) / 255, (color.r * parms.color.r) / 255);
// scissor test doesn't use the current viewport for the coordinates, so use real screen coordinates
dg.mScissor[0] = GLRenderer->ScreenToWindowX(parms.lclip);
dg.mScissor[1] = GLRenderer->ScreenToWindowY(parms.dclip);
dg.mScissor[2] = GLRenderer->ScreenToWindowX(parms.rclip) - dg.mScissor[0];
dg.mScissor[3] = GLRenderer->ScreenToWindowY(parms.uclip) - dg.mScissor[1];
FSimpleVertex *ptr = &mVertices[dg.mVertIndex];
ptr->Set(x, y, 0, u1, v1, color); ptr++;
ptr->Set(x, y + h, 0, u1, v2, color); ptr++;
ptr->Set(x + w, y, 0, u2, v1, color); ptr++;
ptr->Set(x + w, y + h, 0, u2, v2, color); ptr++;
if (parms.colorOverlay != 0)
{
color = parms.colorOverlay;
std::swap(color.r, color.b);
ptr->Set(x, y, 0, u1, v1, color); ptr++;
ptr->Set(x, y + h, 0, u1, v2, color); ptr++;
ptr->Set(x + w, y, 0, u2, v1, color); ptr++;
ptr->Set(x + w, y + h, 0, u2, v2, color); ptr++;
dg.mVertCount = 8;
}
AddData(&dg);
}
//==========================================================================
//
//
//
//==========================================================================
void F2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints,
double originx, double originy, double scalex, double scaley,
DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel)
{
FMaterial *gltexture = FMaterial::ValidateTexture(texture, false);
if (gltexture == nullptr)
{
return;
}
DataSimplePoly poly;
poly.mType = DrawTypePoly;
poly.mLen = (sizeof(poly) + 7) & ~7;
poly.mTexture = gltexture;
poly.mColormap = colormap;
poly.mLightLevel = lightlevel;
poly.mVertCount = npoints;
poly.mVertIndex = (int)mVertices.Reserve(npoints);
poly.mFlatColor = flatcolor;
bool dorotate = rotation != 0;
float cosrot = cos(rotation.Radians());
float sinrot = sin(rotation.Radians());
float uscale = float(1.f / (texture->GetScaledWidth() * scalex));
float vscale = float(1.f / (texture->GetScaledHeight() * scaley));
if (texture->bHasCanvas)
{
vscale = 0 - vscale;
}
float ox = float(originx);
float oy = float(originy);
for (int i = 0; i < npoints; ++i)
{
float u = points[i].X - 0.5f - ox;
float v = points[i].Y - 0.5f - oy;
if (dorotate)
{
float t = u;
u = t * cosrot - v * sinrot;
v = v * cosrot + t * sinrot;
}
mVertices[poly.mVertIndex+i].Set(points[i].X, points[i].Y, 0, u*uscale, v*vscale);
}
AddData(&poly);
}
//===========================================================================
//
//
//
//===========================================================================
void F2DDrawer::AddDim(PalEntry color, float damount, int x1, int y1, int w, int h)
{
color.a = uint8_t(damount * 255);
std::swap(color.r, color.b);
DataGeneric dg;
dg.mType = DrawTypeDim;
dg.mLen = (sizeof(dg) + 7) & ~7;
dg.mVertCount = 4;
dg.mVertIndex = (int)mVertices.Reserve(4);
FSimpleVertex *ptr = &mVertices[dg.mVertIndex];
ptr->Set(x1, y1, 0, 0, 0, color); ptr++;
ptr->Set(x1, y1 + h, 0, 0, 0, color); ptr++;
ptr->Set(x1 + w, y1 + h, 0, 0, 0, color); ptr++;
ptr->Set(x1 + w, y1, 0, 0, 0, color); ptr++;
AddData(&dg);
}
//==========================================================================
//
//
//
//==========================================================================
void F2DDrawer::AddClear(int left, int top, int right, int bottom, int palcolor, uint32_t color)
{
PalEntry p = palcolor == -1 || color != 0 ? (PalEntry)color : GPalette.BaseColors[palcolor];
AddDim(p, 1.f, left, top, right - left, bottom - top);
}
//==========================================================================
//
//
//
//==========================================================================
void F2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin)
{
float fU1, fU2, fV1, fV2;
FMaterial *gltexture = FMaterial::ValidateTexture(src, false);
if (!gltexture) return;
DataFlatFill dg;
dg.mType = DrawTypeFlatFill;
dg.mLen = (sizeof(dg) + 7) & ~7;
dg.mVertCount = 4;
dg.mVertIndex = (int)mVertices.Reserve(4);
dg.mTexture = gltexture;
// scaling is not used here.
if (!local_origin)
{
fU1 = float(left) / src->GetWidth();
fV1 = float(top) / src->GetHeight();
fU2 = float(right) / src->GetWidth();
fV2 = float(bottom) / src->GetHeight();
}
else
{
fU1 = 0;
fV1 = 0;
fU2 = float(right - left) / src->GetWidth();
fV2 = float(bottom - top) / src->GetHeight();
}
FSimpleVertex *ptr = &mVertices[dg.mVertIndex];
ptr->Set(left, top, 0, fU1, fV1); ptr++;
ptr->Set(left, bottom, 0, fU1, fV2); ptr++;
ptr->Set(right, top, 0, fU2, fV1); ptr++;
ptr->Set(right, bottom, 0, fU2, fV2); ptr++;
AddData(&dg);
}
//==========================================================================
//
//
//
//==========================================================================
void F2DDrawer::AddLine(int x1, int y1, int x2, int y2, int palcolor, uint32_t color)
{
PalEntry p = color ? (PalEntry)color : GPalette.BaseColors[palcolor];
p.a = 255;
std::swap(p.r, p.b);
DataGeneric dg;
dg.mType = DrawTypeLine;
dg.mLen = (sizeof(dg) + 7) & ~7;
dg.mVertCount = 2;
dg.mVertIndex = (int)mVertices.Reserve(2);
mVertices[dg.mVertIndex].Set(x1, y1, 0, 0, 0, p);
mVertices[dg.mVertIndex+1].Set(x2, y2, 0, 0, 0, p);
// Test if we can batch multiple line commands
if (mLastLineCmd == -1)
{
mLastLineCmd = AddData(&dg);
}
else
{
DataGeneric *dg = (DataGeneric *)&mData[mLastLineCmd];
dg->mVertCount += 2;
}
}
//==========================================================================
//
//
//
//==========================================================================
void F2DDrawer::AddPixel(int x1, int y1, int palcolor, uint32_t color)
{
PalEntry p = color ? (PalEntry)color : GPalette.BaseColors[palcolor];
p.a = 255;
std::swap(p.r, p.b);
DataGeneric dg;
dg.mType = DrawTypePixel;
dg.mLen = (sizeof(dg) + 7) & ~7;
dg.mVertCount = 2;
dg.mVertIndex = (int)mVertices.Reserve(1);
mVertices[dg.mVertIndex].Set(x1, y1, 0, 0, 0, p);
AddData(&dg);
}
//==========================================================================
//
//
//
//==========================================================================
void F2DDrawer::Draw()
{
F2DDrawer::EDrawType lasttype = DrawTypeTexture;
if (mData.Size() == 0) return;
int8_t savedlightmode = glset.lightmode;
// lightmode is only relevant for automap subsectors,
// but We cannot use the software light mode here because it doesn't properly calculate the light for 2D rendering.
if (glset.lightmode == 8) glset.lightmode = 0;
set(&mVertices[0], mVertices.Size());
for (unsigned i = 0; i < mData.Size();)
{
DataGeneric *dg = (DataGeneric *)&mData[i];
// DrawTypePoly may not use the color part of the vertex buffer because it needs to use gl_SetColor to produce proper output.
if (lasttype == DrawTypePoly && dg->mType != DrawTypePoly)
{
gl_RenderState.ResetColor(); // this is needed to reset the desaturation.
EnableColorArray(true);
}
else if (lasttype != DrawTypePoly && dg->mType == DrawTypePoly)
{
EnableColorArray(false);
}
lasttype = dg->mType;
switch (dg->mType)
{
default:
break;
case DrawTypeTexture:
{
DataTexture *dt = static_cast<DataTexture*>(dg);
gl_SetRenderStyle(dt->mRenderStyle, !dt->mMasked, false);
gl_RenderState.SetMaterial(dt->mTexture, CLAMP_XY_NOMIP, dt->mTranslation, -1, dt->mAlphaTexture);
glEnable(GL_SCISSOR_TEST);
glScissor(dt->mScissor[0], dt->mScissor[1], dt->mScissor[2], dt->mScissor[3]);
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
gl_RenderState.Apply();
glDrawArrays(GL_TRIANGLE_STRIP, dt->mVertIndex, 4);
gl_RenderState.BlendEquation(GL_FUNC_ADD);
if (dt->mVertCount > 4)
{
gl_RenderState.SetTextureMode(TM_MASK);
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
gl_RenderState.Apply();
glDrawArrays(GL_TRIANGLE_STRIP, dt->mVertIndex + 4, 4);
}
const auto &viewport = GLRenderer->mScreenViewport;
glScissor(viewport.left, viewport.top, viewport.width, viewport.height);
glDisable(GL_SCISSOR_TEST);
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
gl_RenderState.SetTextureMode(TM_MODULATE);
break;
}
case DrawTypePoly:
{
DataSimplePoly *dsp = static_cast<DataSimplePoly*>(dg);
gl_SetColor(dsp->mLightLevel, 0, false, dsp->mColormap, 1.f);
gl_RenderState.SetMaterial(dsp->mTexture, CLAMP_NONE, 0, -1, false);
gl_RenderState.SetObjectColor(dsp->mFlatColor|0xff000000);
gl_RenderState.Apply();
glDrawArrays(GL_TRIANGLE_FAN, dsp->mVertIndex, dsp->mVertCount);
gl_RenderState.SetObjectColor(0xffffffff);
break;
}
case DrawTypeFlatFill:
{
DataFlatFill *dff = static_cast<DataFlatFill*>(dg);
gl_RenderState.SetMaterial(dff->mTexture, CLAMP_NONE, 0, -1, false);
gl_RenderState.Apply();
glDrawArrays(GL_TRIANGLE_STRIP, dg->mVertIndex, dg->mVertCount);
break;
}
case DrawTypeDim:
gl_RenderState.EnableTexture(false);
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
gl_RenderState.AlphaFunc(GL_GREATER, 0);
gl_RenderState.Apply();
glDrawArrays(GL_TRIANGLE_FAN, dg->mVertIndex, dg->mVertCount);
gl_RenderState.EnableTexture(true);
break;
case DrawTypeLine:
gl_RenderState.EnableTexture(false);
gl_RenderState.Apply();
glDrawArrays(GL_LINES, dg->mVertIndex, dg->mVertCount);
gl_RenderState.EnableTexture(true);
break;
case DrawTypePixel:
gl_RenderState.EnableTexture(false);
gl_RenderState.Apply();
glDrawArrays(GL_POINTS, dg->mVertIndex, dg->mVertCount);
gl_RenderState.EnableTexture(true);
break;
}
i += dg->mLen;
}
gl_RenderState.SetVertexBuffer(GLRenderer->mVBO);
glset.lightmode = savedlightmode;
}
void F2DDrawer::Clear()
{
mVertices.Clear();
mData.Clear();
mLastLineCmd = -1;
}

View file

@ -1,75 +0,0 @@
#ifndef __2DDRAWER_H
#define __2DDRAWER_H
#include "tarray.h"
#include "gl/data/gl_vertexbuffer.h"
class F2DDrawer : public FSimpleVertexBuffer
{
enum EDrawType
{
DrawTypeTexture,
DrawTypeDim,
DrawTypeFlatFill,
DrawTypePoly,
DrawTypeLine,
DrawTypePixel
};
struct DataGeneric
{
EDrawType mType;
uint32_t mLen;
int mVertIndex;
int mVertCount;
};
struct DataTexture : public DataGeneric
{
FMaterial *mTexture;
int mScissor[4];
uint32_t mColorOverlay;
int mTranslation;
FRenderStyle mRenderStyle;
bool mMasked;
bool mAlphaTexture;
};
struct DataFlatFill : public DataGeneric
{
FMaterial *mTexture;
};
struct DataSimplePoly : public DataGeneric
{
FMaterial *mTexture;
int mLightLevel;
FColormap mColormap;
PalEntry mFlatColor;
};
TArray<FSimpleVertex> mVertices;
TArray<uint8_t> mData;
int mLastLineCmd = -1; // consecutive lines can be batched into a single draw call so keep this info around.
int AddData(const DataGeneric *data);
public:
void AddTexture(FTexture *img, DrawParms &parms);
void AddDim(PalEntry color, float damount, int x1, int y1, int w, int h);
void AddClear(int left, int top, int right, int bottom, int palcolor, uint32_t color);
void AddFlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin);
void AddPoly(FTexture *texture, FVector2 *points, int npoints,
double originx, double originy, double scalex, double scaley,
DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel);
void AddLine(int x1, int y1, int x2, int y2, int palcolor, uint32_t color);
void AddPixel(int x1, int y1, int palcolor, uint32_t color);
void Draw();
void Clear();
};
#endif

View file

@ -9,10 +9,12 @@ struct lightlist_t;
enum EColorManipulation
{
CM_SPECIAL2D = -3, // the special colormaps get passed as color pair from the 2D drawer so they need a different value here.
CM_PLAIN2D = -2, // regular 2D drawing.
CM_INVALID=-1,
CM_DEFAULT=0, // untranslated
CM_FIRSTSPECIALCOLORMAP, // first special fixed colormap
CM_FIRSTSPECIALCOLORMAPFORCED= 0x08000000, // first special fixed colormap, application forced (for 2D overlays)
CM_FOGLAYER = 0x10000000, // Sprite shaped fog layer
@ -22,6 +24,7 @@ enum EColorManipulation
};
#define CM_MAXCOLORMAP int(CM_FIRSTSPECIALCOLORMAP + SpecialColormaps.Size())
#define CM_MAXCOLORMAPFORCED int(CM_FIRSTSPECIALCOLORMAPFORCED + SpecialColormaps.Size())
#endif

View file

@ -28,7 +28,6 @@
#include "gl/system/gl_system.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_cvars.h"
#include "gl/data/gl_data.h"
#include "gl/renderer/gl_colormap.h"
#include "gl/renderer/gl_lightdata.h"
#include "gl/renderer/gl_renderstate.h"
@ -53,8 +52,6 @@ CUSTOM_CVAR(Bool, gl_enhanced_nightvision, true, CVAR_ARCHIVE|CVAR_NOINITCALL)
GLRenderer->mShaderManager->ResetFixedColormap();
}
}
CVAR(Bool, gl_brightfog, false, CVAR_ARCHIVE);
CVAR(Bool, gl_lightadditivesurfaces, false, CVAR_ARCHIVE);
@ -97,14 +94,6 @@ CUSTOM_CVAR(Int,gl_fogmode,1,CVAR_ARCHIVE|CVAR_NOINITCALL)
if (self<0) self=0;
}
CUSTOM_CVAR(Int, gl_lightmode, 3 ,CVAR_ARCHIVE|CVAR_NOINITCALL)
{
int newself = self;
if (newself > 4) newself=8; // use 8 for software lighting to avoid conflicts with the bit mask
if (newself < 0) newself=0;
if (self != newself) self = newself;
glset.lightmode = newself;
}
@ -119,12 +108,12 @@ CUSTOM_CVAR(Int, gl_lightmode, 3 ,CVAR_ARCHIVE|CVAR_NOINITCALL)
void gl_GetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblending,
int *tm, int *sb, int *db, int *be)
{
static int blendstyles[] = { GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA };
static int blendstyles[] = { GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR, };
static int renderops[] = { 0, GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1 };
int srcblend = blendstyles[style.SrcAlpha&3];
int dstblend = blendstyles[style.DestAlpha&3];
int srcblend = blendstyles[style.SrcAlpha%STYLEALPHA_MAX];
int dstblend = blendstyles[style.DestAlpha%STYLEALPHA_MAX];
int blendequation = renderops[style.BlendOp&15];
int texturemode = drawopaque? TM_OPAQUE : TM_MODULATE;
@ -138,7 +127,6 @@ void gl_GetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblend
}
else if (style.Flags & STYLEF_InvertSource)
{
// The only place where InvertSource is used is for inverted sprites with the infrared powerup.
texturemode = TM_INVERSE;
}
@ -173,7 +161,7 @@ int gl_CalcLightLevel(int lightlevel, int rellight, bool weapon)
if (lightlevel == 0) return 0;
if ((glset.lightmode & 2) && lightlevel < 192 && !weapon)
if ((level.lightmode & 2) && lightlevel < 192 && !weapon)
{
if (lightlevel > 100)
{
@ -211,7 +199,7 @@ static PalEntry gl_CalcLightColor(int light, PalEntry pe, int blendfactor)
{
int r,g,b;
if (glset.lightmode == 8)
if (level.lightmode == 8)
{
return pe;
}
@ -277,7 +265,7 @@ float gl_GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity)
{
float density;
if (glset.lightmode & 4)
if (level.lightmode & 4)
{
// uses approximations of Legacy's default settings.
density = level.fogdensity ? level.fogdensity : 18;
@ -290,9 +278,9 @@ float gl_GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity)
else if ((fogcolor.d & 0xffffff) == 0)
{
// case 2: black fog
if (glset.lightmode != 8 && !(level.flags3 & LEVEL3_NOLIGHTFADE))
if (level.lightmode != 8 && !(level.flags3 & LEVEL3_NOLIGHTFADE))
{
density = distfogtable[glset.lightmode != 0][gl_ClampLight(lightlevel)];
density = distfogtable[level.lightmode != 0][gl_ClampLight(lightlevel)];
}
else
{
@ -351,7 +339,7 @@ bool gl_CheckFog(sector_t *frontsector, sector_t *backsector)
else if (level.outsidefogdensity != 0 && APART(level.info->outsidefog) != 0xff && (fogcolor.d & 0xffffff) == (level.info->outsidefog & 0xffffff))
{
}
else if (level.fogdensity!=0 || (glset.lightmode & 4))
else if (level.fogdensity!=0 || (level.lightmode & 4))
{
// case 3: level has fog density set
}
@ -370,7 +358,7 @@ bool gl_CheckFog(sector_t *frontsector, sector_t *backsector)
{
return false;
}
else if (level.fogdensity!=0 || (glset.lightmode & 4))
else if (level.fogdensity!=0 || (level.lightmode & 4))
{
// case 3: level has fog density set
return false;
@ -460,7 +448,7 @@ void gl_SetFog(int lightlevel, int rellight, bool fullbright, const FColormap *c
}
else
{
if (glset.lightmode == 2 && fogcolor == 0)
if (level.lightmode == 2 && fogcolor == 0)
{
float light = gl_CalcLightLevel(lightlevel, rellight, false);
gl_SetShaderLight(light, lightlevel);
@ -481,7 +469,7 @@ void gl_SetFog(int lightlevel, int rellight, bool fullbright, const FColormap *c
gl_RenderState.SetFog(fogcolor, fogdensity);
// Korshun: fullbright fog like in software renderer.
if (glset.lightmode == 8 && glset.brightfog && fogdensity != 0 && fogcolor != 0)
if (level.lightmode == 8 && level.brightfog && fogdensity != 0 && fogcolor != 0)
{
gl_RenderState.SetSoftLightLevel(255);
}

View file

@ -42,7 +42,6 @@
#include "r_utility.h"
#include "p_local.h"
#include "colormatcher.h"
#include "gl/gl_functions.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"
#include "gl/system/gl_cvars.h"
@ -52,7 +51,6 @@
#include "gl/renderer/gl_renderbuffers.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/renderer/gl_postprocessstate.h"
#include "gl/data/gl_data.h"
#include "gl/data/gl_vertexbuffer.h"
#include "gl/shaders/gl_ambientshader.h"
#include "gl/shaders/gl_bloomshader.h"
@ -63,7 +61,7 @@
#include "gl/shaders/gl_fxaashader.h"
#include "gl/shaders/gl_presentshader.h"
#include "gl/shaders/gl_postprocessshader.h"
#include "gl/renderer/gl_2ddrawer.h"
#include "gl/shaders/gl_postprocessshaderinstance.h"
#include "gl/stereo3d/gl_stereo3d.h"
#include "r_videoscale.h"
@ -626,7 +624,7 @@ void FGLRenderer::CreateTonemapPalette()
}
}
mTonemapPalette = new FHardwareTexture(512, 512, true);
mTonemapPalette = new FHardwareTexture(true);
mTonemapPalette->CreateTexture(&lut[0], 512, 512, 0, false, 0, "mTonemapPalette");
}
}
@ -798,10 +796,10 @@ void FGLRenderer::Flush()
mBuffers->BindEyeFB(eye_ix);
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
glScissor(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
m2DDrawer->Draw();
screen->Draw2D();
FGLDebug::PopGroup();
}
m2DDrawer->Clear();
screen->Clear2D();
FGLPostProcessState savedState;
FGLDebug::PushGroup("PresentEyes");
@ -818,8 +816,8 @@ void FGLRenderer::Flush()
void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma)
{
m2DDrawer->Draw(); // draw all pending 2D stuff before copying the buffer
m2DDrawer->Clear();
screen->Draw2D(); // draw all pending 2D stuff before copying the buffer
screen->Clear2D();
mCustomPostProcessShaders->Run("screen");

View file

@ -28,7 +28,6 @@
#include "templates.h"
#include "gl/system/gl_system.h"
#include "gl/system/gl_interface.h"
#include "gl/data/gl_data.h"
#include "gl/data/gl_vertexbuffer.h"
#include "gl/system/gl_cvars.h"
#include "gl/shaders/gl_shader.h"

View file

@ -3,7 +3,6 @@
#include <string.h>
#include "gl/system/gl_interface.h"
#include "gl/data/gl_data.h"
#include "r_data/matrix.h"
#include "c_cvars.h"
#include "r_defs.h"

View file

@ -28,7 +28,6 @@
#include "gl/system/gl_system.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"

View file

@ -33,10 +33,12 @@
#include "m_png.h"
#include "m_crc32.h"
#include "w_wad.h"
//#include "gl/gl_intern.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "doomstat.h"
#include "i_time.h"
#include "p_effect.h"
#include "d_player.h"
#include "a_dynlight.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"
@ -46,10 +48,10 @@
#include "gl/renderer/gl_lightdata.h"
#include "gl/renderer/gl_renderstate.h"
#include "gl/renderer/gl_renderbuffers.h"
#include "gl/renderer/gl_2ddrawer.h"
#include "gl/data/gl_data.h"
#include "gl/data/gl_vertexbuffer.h"
#include "gl/scene/gl_drawinfo.h"
#include "gl/scene/gl_scenedrawer.h"
#include "gl/scene/gl_swscene.h"
#include "gl/scene/gl_portal.h"
#include "gl/shaders/gl_shader.h"
#include "gl/shaders/gl_ambientshader.h"
@ -63,20 +65,21 @@
#include "gl/shaders/gl_present3dRowshader.h"
#include "gl/shaders/gl_shadowmapshader.h"
#include "gl/shaders/gl_postprocessshader.h"
#include "gl/shaders/gl_postprocessshaderinstance.h"
#include "gl/stereo3d/gl_stereo3d.h"
#include "gl/textures/gl_texture.h"
#include "gl/textures/gl_translate.h"
#include "gl/textures/gl_material.h"
#include "gl/textures/gl_samplers.h"
#include "gl/utility/gl_clock.h"
#include "gl/utility/gl_templates.h"
#include "gl/models/gl_models.h"
#include "gl/dynlights/gl_lightbuffer.h"
#include "r_videoscale.h"
EXTERN_CVAR(Int, screenblocks)
EXTERN_CVAR(Bool, cl_capfps)
EXTERN_CVAR(Float, underwater_fade_scalar)
CVAR(Bool, gl_scale_viewport, true, CVAR_ARCHIVE);
extern bool NoInterpolateView;
//===========================================================================
//
@ -105,7 +108,6 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb)
gl_spriteindex = 0;
mShaderManager = nullptr;
mLights = nullptr;
m2DDrawer = nullptr;
mTonemapPalette = nullptr;
mBuffers = nullptr;
mPresentShader = nullptr;
@ -160,7 +162,11 @@ void FGLRenderer::Initialize(int width, int height)
mPresent3dRowShader = new FPresent3DRowShader();
mShadowMapShader = new FShadowMapShader();
mCustomPostProcessShaders = new FCustomPostProcessShaders();
m2DDrawer = new F2DDrawer;
if (gl.legacyMode)
{
legacyShaders = new LegacyShaderContainer;
}
GetSpecialTextures();
@ -196,7 +202,7 @@ FGLRenderer::~FGLRenderer()
gl_FlushModels();
AActor::DeleteAllAttachedLights();
FMaterial::FlushAll();
if (m2DDrawer != nullptr) delete m2DDrawer;
if (legacyShaders) delete legacyShaders;
if (mShaderManager != NULL) delete mShaderManager;
if (mSamplerManager != NULL) delete mSamplerManager;
if (mVBO != NULL) delete mVBO;
@ -208,6 +214,7 @@ FGLRenderer::~FGLRenderer()
glBindVertexArray(0);
glDeleteVertexArrays(1, &mVAOID);
}
if (swdrawer) delete swdrawer;
if (mBuffers) delete mBuffers;
if (mPresentShader) delete mPresentShader;
if (mLinearDepthShader) delete mLinearDepthShader;
@ -360,6 +367,13 @@ int FGLRenderer::ScreenToWindowY(int y)
//
//===========================================================================
void FGLRenderer::ResetSWScene()
{
// force recreation of the SW scene drawer to ensure it gets a new set of resources.
if (swdrawer != nullptr) delete swdrawer;
swdrawer = nullptr;
}
void FGLRenderer::SetupLevel()
{
mVBO->CreateVBO();
@ -420,18 +434,462 @@ void FGLRenderer::EndOffscreen()
glBindFramebuffer(GL_FRAMEBUFFER, mOldFBID);
}
//===========================================================================
//
//-----------------------------------------------------------------------------
//
// renders the view
//
//-----------------------------------------------------------------------------
void FGLRenderer::RenderView(player_t* player)
{
gl_RenderState.SetVertexBuffer(mVBO);
mVBO->Reset();
if (!V_IsHardwareRenderer())
{
if (swdrawer == nullptr) swdrawer = new SWSceneDrawer;
swdrawer->RenderView(player);
}
else
{
checkBenchActive();
// reset statistics counters
ResetProfilingData();
// Get this before everything else
if (cl_capfps || r_NoInterpolate) r_viewpoint.TicFrac = 1.;
else r_viewpoint.TicFrac = I_GetTimeFrac();
P_FindParticleSubsectors();
if (!gl.legacyMode) mLights->Clear();
// NoInterpolateView should have no bearing on camera textures, but needs to be preserved for the main view below.
bool saved_niv = NoInterpolateView;
NoInterpolateView = false;
// prepare all camera textures that have been used in the last frame
FCanvasTextureInfo::UpdateAll();
NoInterpolateView = saved_niv;
// now render the main view
float fovratio;
float ratio = r_viewwindow.WidescreenRatio;
if (r_viewwindow.WidescreenRatio >= 1.3f)
{
fovratio = 1.333333f;
}
else
{
fovratio = ratio;
}
// Check if there's some lights. If not some code can be skipped.
TThinkerIterator<ADynamicLight> it(STAT_DLIGHT);
mLightCount = ((it.Next()) != NULL);
GLSceneDrawer drawer;
drawer.SetFixedColormap(player);
mShadowMap.Update();
sector_t * viewsector = drawer.RenderViewpoint(player->camera, NULL, r_viewpoint.FieldOfView.Degrees, ratio, fovratio, true, true);
}
All.Unclock();
}
//===========================================================================
//
// Camera texture rendering
//
//===========================================================================
unsigned char *FGLRenderer::GetTextureBuffer(FTexture *tex, int &w, int &h)
void FGLRenderer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV)
{
FMaterial * gltex = FMaterial::ValidateTexture(tex, false);
if (gltex)
int width = gltex->TextureWidth();
int height = gltex->TextureHeight();
if (gl.legacyMode)
{
return gltex->CreateTexBuffer(0, w, h);
// In legacy mode, fail if the requested texture is too large.
if (gltex->GetWidth() > screen->GetWidth() || gltex->GetHeight() > screen->GetHeight()) return;
glFlush();
}
return NULL;
else
{
StartOffscreen();
gltex->BindToFrameBuffer();
}
GL_IRECT bounds;
bounds.left = bounds.top = 0;
bounds.width = FHardwareTexture::GetTexDimension(gltex->GetWidth());
bounds.height = FHardwareTexture::GetTexDimension(gltex->GetHeight());
GLSceneDrawer drawer;
drawer.FixedColormap = CM_DEFAULT;
gl_RenderState.SetFixedColormap(CM_DEFAULT);
drawer.RenderViewpoint(Viewpoint, &bounds, FOV, (float)width / height, (float)width / height, false, false);
if (gl.legacyMode)
{
glFlush();
gl_RenderState.SetMaterial(gltex, 0, 0, -1, false);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, bounds.width, bounds.height);
}
else
{
EndOffscreen();
}
tex->SetUpdated();
}
void FGLRenderer::WriteSavePic(player_t *player, FileWriter *file, int width, int height)
{
// Todo: This needs to call the software renderer and process the returned image, if so desired.
// This also needs to take out parts of the scene drawer so they can be shared between renderers.
GLSceneDrawer drawer;
drawer.WriteSavePic(player, file, width, height);
}
void gl_FillScreen()
{
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
gl_RenderState.EnableTexture(false);
gl_RenderState.Apply();
// The fullscreen quad is stored at index 4 in the main vertex buffer.
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, FFlatVertexBuffer::FULLSCREEN_INDEX, 4);
}
//==========================================================================
//
// Draws a blend over the entire view
//
//==========================================================================
void FGLRenderer::DrawBlend(sector_t * viewsector, bool FixedColormap, bool docolormap, bool in2d)
{
float blend[4] = { 0,0,0,0 };
PalEntry blendv = 0;
float extra_red;
float extra_green;
float extra_blue;
player_t *player = NULL;
if (players[consoleplayer].camera != NULL)
{
player = players[consoleplayer].camera->player;
}
// don't draw sector based blends when an invulnerability colormap is active
if (!FixedColormap)
{
if (!viewsector->e->XFloor.ffloors.Size())
{
if (viewsector->heightsec && !(viewsector->MoreFlags&SECF_IGNOREHEIGHTSEC))
{
auto s = viewsector->heightsec;
blendv = s->floorplane.PointOnSide(r_viewpoint.Pos) < 0? s->bottommap : s->ceilingplane.PointOnSide(r_viewpoint.Pos) < 0 ? s->topmap : s->midmap;
}
}
else
{
TArray<lightlist_t> & lightlist = viewsector->e->XFloor.lightlist;
for (unsigned int i = 0; i < lightlist.Size(); i++)
{
double lightbottom;
if (i < lightlist.Size() - 1)
lightbottom = lightlist[i + 1].plane.ZatPoint(r_viewpoint.Pos);
else
lightbottom = viewsector->floorplane.ZatPoint(r_viewpoint.Pos);
if (lightbottom < r_viewpoint.Pos.Z && (!lightlist[i].caster || !(lightlist[i].caster->flags&FF_FADEWALLS)))
{
// 3d floor 'fog' is rendered as a blending value
blendv = lightlist[i].blend;
// If this is the same as the sector's it doesn't apply!
if (blendv == viewsector->Colormap.FadeColor) blendv = 0;
// a little hack to make this work for Legacy maps.
if (blendv.a == 0 && blendv != 0) blendv.a = 128;
break;
}
}
}
if (blendv.a == 0 && docolormap)
{
blendv = R_BlendForColormap(blendv);
}
if (blendv.a == 255)
{
extra_red = blendv.r / 255.0f;
extra_green = blendv.g / 255.0f;
extra_blue = blendv.b / 255.0f;
// If this is a multiplicative blend do it separately and add the additive ones on top of it.
// black multiplicative blends are ignored
if (extra_red || extra_green || extra_blue)
{
if (!in2d)
{
gl_RenderState.BlendFunc(GL_DST_COLOR, GL_ZERO);
gl_RenderState.SetColor(extra_red, extra_green, extra_blue, 1.0f);
gl_FillScreen();
}
else
{
screen->Dim(blendv, 1, 0, 0, screen->GetWidth(), screen->GetHeight(), &LegacyRenderStyles[STYLE_Multiply]);
}
}
blendv = 0;
}
else if (blendv.a)
{
// [Nash] allow user to set blend intensity
int cnt = blendv.a;
cnt = (int)(cnt * underwater_fade_scalar);
V_AddBlend(blendv.r / 255.f, blendv.g / 255.f, blendv.b / 255.f, cnt / 255.0f, blend);
}
}
if (player)
{
V_AddPlayerBlend(player, blend, 0.5, 175);
}
if (players[consoleplayer].camera != NULL)
{
// except for fadeto effects
player_t *player = (players[consoleplayer].camera->player != NULL) ? players[consoleplayer].camera->player : &players[consoleplayer];
V_AddBlend(player->BlendR, player->BlendG, player->BlendB, player->BlendA, blend);
}
if (!in2d)
{
gl_RenderState.SetTextureMode(TM_MODULATE);
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if (blend[3] > 0.0f)
{
gl_RenderState.SetColor(blend[0], blend[1], blend[2], blend[3]);
gl_FillScreen();
}
gl_RenderState.ResetColor();
gl_RenderState.EnableTexture(true);
}
else
{
screen->Dim(PalEntry(255, blend[0] * 255, blend[1] * 255, blend[2] * 255), blend[3], 0, 0, screen->GetWidth(), screen->GetHeight());
}
}
//===========================================================================
//
// Vertex buffer for 2D drawer
//
//===========================================================================
class F2DVertexBuffer : public FSimpleVertexBuffer
{
uint32_t ibo_id;
// Make sure we can build upon FSimpleVertexBuffer.
static_assert(offsetof(FSimpleVertex, x) == offsetof(F2DDrawer::TwoDVertex, x), "x not aligned");
static_assert(offsetof(FSimpleVertex, u) == offsetof(F2DDrawer::TwoDVertex, u), "u not aligned");
static_assert(offsetof(FSimpleVertex, color) == offsetof(F2DDrawer::TwoDVertex, color0), "color not aligned");
public:
F2DVertexBuffer()
{
glGenBuffers(1, &ibo_id);
}
~F2DVertexBuffer()
{
if (ibo_id != 0)
{
glDeleteBuffers(1, &ibo_id);
}
}
void UploadData(F2DDrawer::TwoDVertex *vertices, int vertcount, int *indices, int indexcount)
{
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
glBufferData(GL_ARRAY_BUFFER, vertcount * sizeof(vertices[0]), vertices, GL_STREAM_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexcount * sizeof(indices[0]), indices, GL_STREAM_DRAW);
}
void BindVBO() override
{
FSimpleVertexBuffer::BindVBO();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id);
}
};
//===========================================================================
//
// Draws the 2D stuff. This is the version for OpenGL 3 and later.
//
//===========================================================================
void LegacyColorOverlay(F2DDrawer *drawer, F2DDrawer::RenderCommand & cmd);
int LegacyDesaturation(F2DDrawer::RenderCommand &cmd);
void FGLRenderer::Draw2D(F2DDrawer *drawer)
{
auto &vertices = drawer->mVertices;
auto &indices = drawer->mIndices;
auto &commands = drawer->mData;
if (commands.Size() == 0) return;
for (auto &v : vertices)
{
// Change from BGRA to RGBA
std::swap(v.color0.r, v.color0.b);
}
auto vb = new F2DVertexBuffer;
vb->UploadData(&vertices[0], vertices.Size(), &indices[0], indices.Size());
gl_RenderState.SetVertexBuffer(vb);
gl_RenderState.SetFixedColormap(CM_DEFAULT);
for(auto &cmd : commands)
{
int gltrans = -1;
int tm, sb, db, be;
// The texture mode being returned here cannot be used, because the higher level code
// already manipulated the data so that some cases will not be handled correctly.
// Since we already get a proper mode from the calling code this doesn't really matter.
gl_GetRenderStyle(cmd.mRenderStyle, false, false, &tm, &sb, &db, &be);
gl_RenderState.BlendEquation(be);
gl_RenderState.BlendFunc(sb, db);
// Rather than adding remapping code, let's enforce that the constants here are equal.
static_assert(int(F2DDrawer::DTM_Normal) == int(TM_MODULATE), "DTM_Normal != TM_MODULATE");
static_assert(int(F2DDrawer::DTM_Opaque) == int(TM_OPAQUE), "DTM_Opaque != TM_OPAQUE");
static_assert(int(F2DDrawer::DTM_Invert) == int(TM_INVERSE), "DTM_Invert != TM_INVERSE");
static_assert(int(F2DDrawer::DTM_InvertOpaque) == int(TM_INVERTOPAQUE), "DTM_InvertOpaque != TM_INVERTOPAQUE");
static_assert(int(F2DDrawer::DTM_Stencil) == int(TM_MASK), "DTM_Stencil != TM_MASK");
static_assert(int(F2DDrawer::DTM_AlphaTexture) == int(TM_REDTOALPHA), "DTM_AlphaTexture != TM_REDTOALPHA");
gl_RenderState.SetTextureMode(cmd.mDrawMode);
if (cmd.mFlags & F2DDrawer::DTF_Scissor)
{
glEnable(GL_SCISSOR_TEST);
// scissor test doesn't use the current viewport for the coordinates, so use real screen coordinates
// Note that the origin here is the lower left corner!
auto sciX = ScreenToWindowX(cmd.mScissor[0]);
auto sciY = ScreenToWindowY(cmd.mScissor[3]);
auto sciW = ScreenToWindowX(cmd.mScissor[2]) - sciX;
auto sciH = ScreenToWindowY(cmd.mScissor[1]) - sciY;
glScissor(sciX, sciY, sciW, sciH);
}
else glDisable(GL_SCISSOR_TEST);
if (cmd.mSpecialColormap != nullptr)
{
auto index = cmd.mSpecialColormap - &SpecialColormaps[0];
if (index < 0 || (unsigned)index >= SpecialColormaps.Size()) index = 0; // if it isn't in the table FBitmap cannot use it. Shouldn't happen anyway.
if (!gl.legacyMode || cmd.mTexture->UseType == ETextureType::SWCanvas)
{
gl_RenderState.SetFixedColormap(CM_FIRSTSPECIALCOLORMAPFORCED + int(index));
}
else
{
// map the special colormap to a translation for the legacy renderer.
// This only gets used on the software renderer's weapon sprite.
gltrans = STRange_Specialcolormap + index;
}
}
else
{
if (!gl.legacyMode)
{
gl_RenderState.Set2DOverlayColor(cmd.mColor1);
gl_RenderState.SetFixedColormap(CM_PLAIN2D);
}
else if (cmd.mDesaturate > 0)
{
gltrans = LegacyDesaturation(cmd);
}
}
gl_RenderState.SetColor(1, 1, 1, 1, cmd.mDesaturate);
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
if (cmd.mTexture != nullptr)
{
auto mat = FMaterial::ValidateTexture(cmd.mTexture, false);
if (mat == nullptr) continue;
// This requires very special handling
if (gl.legacyMode && cmd.mTexture->UseType == ETextureType::SWCanvas)
{
gl_RenderState.SetTextureMode(TM_SWCANVAS);
}
if (gltrans == -1 && cmd.mTranslation != nullptr) gltrans = cmd.mTranslation->GetUniqueIndex();
gl_RenderState.SetMaterial(mat, cmd.mFlags & F2DDrawer::DTF_Wrap ? CLAMP_NONE : CLAMP_XY_NOMIP, -gltrans, -1, cmd.mDrawMode == F2DDrawer::DTM_AlphaTexture);
gl_RenderState.EnableTexture(true);
// Canvas textures are stored upside down
if (cmd.mTexture->bHasCanvas)
{
gl_RenderState.mTextureMatrix.loadIdentity();
gl_RenderState.mTextureMatrix.scale(1.f, -1.f, 1.f);
gl_RenderState.mTextureMatrix.translate(0.f, 1.f, 0.0f);
gl_RenderState.EnableTextureMatrix(true);
}
}
else
{
gl_RenderState.EnableTexture(false);
}
gl_RenderState.Apply();
switch (cmd.mType)
{
case F2DDrawer::DrawTypeTriangles:
glDrawElements(GL_TRIANGLES, cmd.mIndexCount, GL_UNSIGNED_INT, (const void *)(cmd.mIndexIndex * sizeof(unsigned int)));
if (gl.legacyMode && cmd.mColor1 != 0)
{
// Draw the overlay as a separate operation.
LegacyColorOverlay(drawer, cmd);
}
break;
case F2DDrawer::DrawTypeLines:
glDrawArrays(GL_LINES, cmd.mVertIndex, cmd.mVertCount);
break;
case F2DDrawer::DrawTypePoints:
glDrawArrays(GL_POINTS, cmd.mVertIndex, cmd.mVertCount);
break;
}
gl_RenderState.SetEffect(EFF_NONE);
gl_RenderState.EnableTextureMatrix(false);
}
glDisable(GL_SCISSOR_TEST);
gl_RenderState.SetVertexBuffer(GLRenderer->mVBO);
gl_RenderState.EnableTexture(true);
gl_RenderState.SetTextureMode(TM_MODULATE);
gl_RenderState.SetFixedColormap(CM_DEFAULT);
gl_RenderState.ResetColor();
gl_RenderState.Apply();
delete vb;
}

View file

@ -40,11 +40,12 @@ class FPresentShader;
class FPresent3DCheckerShader;
class FPresent3DColumnShader;
class FPresent3DRowShader;
class F2DDrawer;
class FGL2DDrawer;
class FHardwareTexture;
class FShadowMapShader;
class FCustomPostProcessShaders;
class GLSceneDrawer;
class SWSceneDrawer;
inline float DEG2RAD(float deg)
{
@ -88,6 +89,29 @@ enum
DM_SKYPORTAL
};
// Helper baggage to draw the paletted software renderer output on old hardware.
// This must be here because the 2D drawer needs to access it, not the scene drawer.
class LegacyShader;
struct LegacyShaderContainer
{
enum
{
NUM_SHADERS = 4
};
LegacyShader *Shaders[NUM_SHADERS];
LegacyShader* CreatePixelShader(const FString& vertexsrc, const FString& fragmentsrc, const FString &defines);
LegacyShaderContainer();
~LegacyShaderContainer();
bool LoadShaders();
void BindShader(int num, const float *p1, const float *p2);
};
class FGLRenderer
{
public:
@ -146,7 +170,8 @@ public:
FFlatVertexBuffer *mVBO;
FSkyVertexBuffer *mSkyVBO;
FLightBuffer *mLights;
F2DDrawer *m2DDrawer;
SWSceneDrawer *swdrawer = nullptr;
LegacyShaderContainer *legacyShaders = nullptr;
GL_IRECT mScreenViewport;
GL_IRECT mSceneViewport;
@ -170,10 +195,8 @@ public:
void ClearBorders();
void FlushTextures();
unsigned char *GetTextureBuffer(FTexture *tex, int &w, int &h);
void SetupLevel();
void RenderView(player_t* player);
void ResetSWScene();
void RenderScreenQuad();
void PostProcessScene(int fixedcm, const std::function<void()> &afterBloomDrawEndScene2D);
@ -191,6 +214,11 @@ public:
void DrawPresentTexture(const GL_IRECT &box, bool applyGamma);
void Flush();
void GetSpecialTextures();
void Draw2D(F2DDrawer *data);
void RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV);
void WriteSavePic(player_t *player, FileWriter *file, int width, int height);
void RenderView(player_t *player);
void DrawBlend(sector_t * viewsector, bool FixedColormap, bool docolormap, bool in2d = false);
bool StartOffscreen();

View file

@ -26,9 +26,9 @@
*/
#include "templates.h"
#include "doomstat.h"
#include "gl/system/gl_system.h"
#include "gl/system/gl_interface.h"
#include "gl/data/gl_data.h"
#include "gl/data/gl_vertexbuffer.h"
#include "gl/system/gl_cvars.h"
#include "gl/shaders/gl_shader.h"
@ -159,8 +159,6 @@ bool FRenderState::ApplyShader()
glVertexAttrib4fv(VATTR_COLOR, mColor.vec);
glVertexAttrib4fv(VATTR_NORMAL, mNormal.vec);
//activeShader->muObjectColor2.Set(mObjectColor2);
activeShader->muObjectColor2.Set(mObjectColor2);
activeShader->muDesaturation.Set(mDesaturation / 255.f);
activeShader->muFogEnabled.Set(fogset);
@ -171,6 +169,7 @@ bool FRenderState::ApplyShader()
activeShader->muLightParms.Set(mLightParms);
activeShader->muFogColor.Set(mFogColor);
activeShader->muObjectColor.Set(mObjectColor);
activeShader->muObjectColor2.Set(mObjectColor2);
activeShader->muDynLightColor.Set(mDynColor.vec);
activeShader->muInterpolationFactor.Set(mInterpolationFactor);
activeShader->muClipHeight.Set(mClipHeight);
@ -225,7 +224,28 @@ bool FRenderState::ApplyShader()
activeShader->currentcliplinestate = 0;
}
if (mColormapState != activeShader->currentfixedcolormap)
if (mColormapState < -1) // 2D operations
{
if (mColormapState != CM_SPECIAL2D)
{
activeShader->muColormapStart.Set(m2DColors[0]);
activeShader->muFixedColormap.Set(4);
}
else
{
float startr = m2DColors[0].r / 255.f;
float startg = m2DColors[0].g / 255.f;
float startb = m2DColors[0].b / 255.f;
float ranger = m2DColors[1].r / 255.f - startr;
float rangeg = m2DColors[1].g / 255.f - startg;
float rangeb = m2DColors[1].b / 255.f - startb;
activeShader->muColormapStart.Set(startr, startg, startb, 0.f);
activeShader->muColormapRange.Set(ranger, rangeg, rangeb, 0.f);
activeShader->muFixedColormap.Set(1);
}
activeShader->currentfixedcolormap = mColormapState;
}
else if (mColormapState != activeShader->currentfixedcolormap)
{
float r, g, b;
activeShader->currentfixedcolormap = mColormapState;
@ -233,9 +253,9 @@ bool FRenderState::ApplyShader()
{
activeShader->muFixedColormap.Set(0);
}
else if (mColormapState > CM_DEFAULT && mColormapState < CM_MAXCOLORMAP)
else if ((mColormapState >= CM_FIRSTSPECIALCOLORMAP && mColormapState < CM_MAXCOLORMAPFORCED))
{
if (FGLRenderBuffers::IsEnabled())
if (FGLRenderBuffers::IsEnabled() && mColormapState < CM_FIRSTSPECIALCOLORMAPFORCED)
{
// When using postprocessing to apply the colormap, we must render the image fullbright here.
activeShader->muFixedColormap.Set(2);
@ -243,13 +263,20 @@ bool FRenderState::ApplyShader()
}
else
{
FSpecialColormap *scm = &SpecialColormaps[mColormapState - CM_FIRSTSPECIALCOLORMAP];
float m[] = { scm->ColorizeEnd[0] - scm->ColorizeStart[0],
scm->ColorizeEnd[1] - scm->ColorizeStart[1], scm->ColorizeEnd[2] - scm->ColorizeStart[2], 0.f };
if (mColormapState >= CM_FIRSTSPECIALCOLORMAPFORCED)
{
auto colormapState = mColormapState + CM_FIRSTSPECIALCOLORMAP - CM_FIRSTSPECIALCOLORMAPFORCED;
if (colormapState < CM_MAXCOLORMAP)
{
FSpecialColormap *scm = &SpecialColormaps[colormapState - CM_FIRSTSPECIALCOLORMAP];
float m[] = { scm->ColorizeEnd[0] - scm->ColorizeStart[0],
scm->ColorizeEnd[1] - scm->ColorizeStart[1], scm->ColorizeEnd[2] - scm->ColorizeStart[2], 0.f };
activeShader->muFixedColormap.Set(1);
activeShader->muColormapStart.Set(scm->ColorizeStart[0], scm->ColorizeStart[1], scm->ColorizeStart[2], 0.f);
activeShader->muColormapRange.Set(m);
activeShader->muFixedColormap.Set(1);
activeShader->muColormapStart.Set(scm->ColorizeStart[0], scm->ColorizeStart[1], scm->ColorizeStart[2], 0.f);
activeShader->muColormapRange.Set(m);
}
}
}
}
else if (mColormapState == CM_FOGLAYER)

View file

@ -25,12 +25,12 @@
#include <string.h>
#include "gl/system/gl_interface.h"
#include "gl/data/gl_data.h"
#include "r_data/matrix.h"
#include "gl/textures/gl_material.h"
#include "c_cvars.h"
#include "r_defs.h"
#include "r_data/r_translate.h"
#include "g_levellocals.h"
class FVertexBuffer;
class FShader;
@ -59,6 +59,7 @@ enum EEffect
EFF_SPHEREMAP,
EFF_BURN,
EFF_STENCIL,
EFF_SWQUAD,
MAX_EFFECTS
};
@ -72,6 +73,7 @@ enum EPassType
class FRenderState
{
friend void gl_SetTextureMode(int type);
bool mTextureEnabled;
bool mFogEnabled;
bool mGlowEnabled;
@ -108,6 +110,7 @@ class FRenderState
PalEntry mFogColor;
PalEntry mObjectColor;
PalEntry mObjectColor2;
PalEntry m2DColors[2]; // in the shader these will reuse the colormap ramp uniforms.
FStateVec4 mDynColor;
float mClipSplit[2];
@ -144,8 +147,8 @@ public:
void SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader, bool alphatexture)
{
// alpha textures need special treatment in the legacy renderer because withouz shaders they need a different texture.
if (alphatexture && gl.legacyMode) translation = INT_MAX;
// alpha textures need special treatment in the legacy renderer because without shaders they need a different texture. This will also override all other translations.
if (alphatexture && gl.legacyMode) translation = -STRange_AlphaTexture;
if (mat->tex->bHasCanvas)
{
@ -156,8 +159,8 @@ public:
mTempTM = TM_MODULATE;
}
mEffectState = overrideshader >= 0? overrideshader : mat->mShaderIndex;
mShaderTimer = mat->tex->gl_info.shaderspeed;
SetSpecular(mat->tex->gl_info.Glossiness, mat->tex->gl_info.SpecularLevel);
mShaderTimer = mat->tex->shaderspeed;
SetSpecular(mat->tex->Glossiness, mat->tex->SpecularLevel);
mat->Bind(clampmode, translation);
}
@ -355,9 +358,9 @@ public:
mGlowBottom.Set(b[0], b[1], b[2], b[3]);
}
void SetSoftLightLevel(int level)
void SetSoftLightLevel(int llevel)
{
if (glset.lightmode == 8) mLightParms[3] = level / 255.f;
if (level.lightmode == 8) mLightParms[3] = llevel / 255.f;
else mLightParms[3] = -1.f;
}
@ -392,6 +395,11 @@ public:
mObjectColor2 = pe;
}
void Set2DOverlayColor(PalEntry pe)
{
m2DColors[0] = pe;
}
void SetSpecular(float glossiness, float specularLevel)
{
mGlossiness = glossiness;

View file

@ -36,7 +36,6 @@
#include "g_levellocals.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/data/gl_data.h"
#include "gl/data/gl_vertexbuffer.h"
#include "gl/scene/gl_scenedrawer.h"
#include "gl/scene/gl_portal.h"
@ -423,7 +422,7 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub)
if (!sector) return;
// If the mapsections differ this subsector can't possibly be visible from the current view point
if (!(currentmapsection[sub->mapsection>>3] & (1 << (sub->mapsection & 7)))) return;
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)
@ -520,16 +519,16 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub)
(sub->numlines > 2) ? SSRF_PROCESSED|SSRF_RENDERALL : SSRF_PROCESSED;
if (sub->hacked & 1) gl_drawinfo->AddHackedSubsector(sub);
FPortal *portal;
FSectorPortalGroup *portal;
portal = fakesector->GetGLPortal(sector_t::ceiling);
portal = fakesector->GetPortalGroup(sector_t::ceiling);
if (portal != NULL)
{
GLSectorStackPortal *glportal = portal->GetRenderState();
glportal->AddSubsector(sub);
}
portal = fakesector->GetGLPortal(sector_t::floor);
portal = fakesector->GetPortalGroup(sector_t::floor);
if (portal != NULL)
{
GLSectorStackPortal *glportal = portal->GetRenderState();

View file

@ -32,7 +32,6 @@
#include "g_levellocals.h"
#include "gl/system/gl_cvars.h"
#include "gl/data/gl_data.h"
#include "gl/data/gl_vertexbuffer.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/renderer/gl_lightdata.h"
@ -40,7 +39,6 @@
#include "gl/scene/gl_drawinfo.h"
#include "gl/scene/gl_scenedrawer.h"
#include "gl/shaders/gl_shader.h"
#include "gl/textures/gl_texture.h"
#include "gl/textures/gl_material.h"
#include "gl/utility/gl_clock.h"
#include "gl/renderer/gl_quaddrawer.h"

View file

@ -35,7 +35,6 @@
#include "g_levellocals.h"
#include "gl/system/gl_cvars.h"
#include "gl/data/gl_data.h"
#include "gl/data/gl_vertexbuffer.h"
#include "gl/scene/gl_drawinfo.h"
#include "gl/scene/gl_portal.h"
@ -44,12 +43,12 @@
#include "gl/renderer/gl_renderstate.h"
#include "gl/textures/gl_material.h"
#include "gl/utility/gl_clock.h"
#include "gl/utility/gl_templates.h"
#include "gl/shaders/gl_shader.h"
#include "gl/stereo3d/scoped_color_mask.h"
#include "gl/renderer/gl_quaddrawer.h"
FDrawInfo * gl_drawinfo;
FDrawInfoList di_list;
//==========================================================================
//
@ -607,17 +606,6 @@ inline int GLDrawList::CompareSprites(SortNode * a,SortNode * b)
else return (i_compatflags & COMPATF_SPRITESORT)? s1->index-s2->index : s2->index-s1->index;
}
//==========================================================================
//
//
//
//==========================================================================
static GLDrawList * gd;
int CompareSprite(const void * a,const void * b)
{
return gd->CompareSprites(*(SortNode**)a,*(SortNode**)b);
}
//==========================================================================
//
//
@ -635,8 +623,11 @@ SortNode * GLDrawList::SortSpriteList(SortNode * head)
sortspritelist.Clear();
for(count=0,n=head;n;n=n->next) sortspritelist.Push(n);
gd=this;
qsort(&sortspritelist[0],sortspritelist.Size(),sizeof(SortNode *),CompareSprite);
std::sort(sortspritelist.begin(), sortspritelist.end(), [=](SortNode *a, SortNode *b)
{
return CompareSprites(a, b) < 0;
});
for(i=0;i<sortspritelist.Size();i++)
{
sortspritelist[i]->next=NULL;
@ -910,38 +901,20 @@ void GLDrawList::DrawDecals()
// Sorting the drawitems first by texture and then by light level.
//
//==========================================================================
static GLDrawList * sortinfo;
static int diwcmp (const void *a, const void *b)
{
const GLDrawItem * di1 = (const GLDrawItem *)a;
GLWall * w1=&sortinfo->walls[di1->index];
const GLDrawItem * di2 = (const GLDrawItem *)b;
GLWall * w2=&sortinfo->walls[di2->index];
if (w1->gltexture != w2->gltexture) return w1->gltexture - w2->gltexture;
return ((w1->flags & 3) - (w2->flags & 3));
}
static int difcmp (const void *a, const void *b)
{
const GLDrawItem * di1 = (const GLDrawItem *)a;
GLFlat * w1=&sortinfo->flats[di1->index];
const GLDrawItem * di2 = (const GLDrawItem *)b;
GLFlat* w2=&sortinfo->flats[di2->index];
return w1->gltexture - w2->gltexture;
}
void GLDrawList::SortWalls()
{
if (drawitems.Size() > 1)
{
sortinfo=this;
qsort(&drawitems[0], drawitems.Size(), sizeof(drawitems[0]), diwcmp);
std::sort(drawitems.begin(), drawitems.end(), [=](const GLDrawItem &a, const GLDrawItem &b) -> bool
{
GLWall * w1 = &walls[a.index];
GLWall * w2 = &walls[b.index];
if (w1->gltexture != w2->gltexture) return w1->gltexture < w2->gltexture;
return (w1->flags & 3) < (w2->flags & 3);
});
}
}
@ -949,8 +922,12 @@ void GLDrawList::SortFlats()
{
if (drawitems.Size() > 1)
{
sortinfo=this;
qsort(&drawitems[0], drawitems.Size(), sizeof(drawitems[0]), difcmp);
std::sort(drawitems.begin(), drawitems.end(), [=](const GLDrawItem &a, const GLDrawItem &b)
{
GLFlat * w1 = &flats[a.index];
GLFlat* w2 = &flats[b.index];
return w1->gltexture < w2->gltexture;
});
}
}
@ -990,6 +967,8 @@ void GLDrawList::AddSprite(GLSprite * sprite)
// Try to reuse the lists as often as possible as they contain resources that
// are expensive to create and delete.
//
// Note: If multithreading gets used, this class needs synchronization.
//
//==========================================================================
FDrawInfo *FDrawInfoList::GetNew()
@ -1009,8 +988,6 @@ void FDrawInfoList::Release(FDrawInfo * di)
mList.Push(di);
}
static FDrawInfoList di_list;
//==========================================================================
//
//

View file

@ -32,7 +32,6 @@
#include "r_sky.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/scene/gl_scenedrawer.h"
#include "gl/data/gl_data.h"
//==========================================================================

View file

@ -43,18 +43,14 @@
#include "gl/renderer/gl_renderer.h"
#include "gl/renderer/gl_lightdata.h"
#include "gl/renderer/gl_renderstate.h"
#include "gl/data/gl_data.h"
#include "gl/data/gl_vertexbuffer.h"
#include "gl/dynlights/gl_dynlight.h"
#include "gl/dynlights/gl_glow.h"
#include "gl/dynlights/gl_lightbuffer.h"
#include "gl/scene/gl_drawinfo.h"
#include "gl/shaders/gl_shader.h"
#include "gl/scene/gl_scenedrawer.h"
#include "gl/textures/gl_material.h"
#include "gl/utility/gl_clock.h"
#include "gl/utility/gl_convert.h"
#include "gl/utility/gl_templates.h"
#include "gl/renderer/gl_quaddrawer.h"
#ifdef _DEBUG
@ -112,7 +108,7 @@ void GLFlat::SetupSubsectorLights(int pass, subsector_t * sub, int *dli)
{
Plane p;
if (renderstyle == STYLE_Add && !glset.lightadditivesurfaces) return; // no lights on additively blended surfaces.
if (renderstyle == STYLE_Add && !level.lightadditivesurfaces) return; // no lights on additively blended surfaces.
if (dli != NULL && *dli != -1)
{
@ -143,7 +139,7 @@ void GLFlat::SetupSubsectorLights(int pass, subsector_t * sub, int *dli)
continue;
}
p.Set(plane.plane);
p.Set(plane.plane.Normal(), plane.plane.fD());
gl_GetLight(sub->sector->PortalGroup, p, light, false, lightdata);
node = node->nextLight;
}
@ -420,7 +416,7 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG
}
else
{
if (!gltexture->GetTransparent()) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
if (!gltexture->tex->GetTranslucency()) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
else gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false);
gl_SetPlaneTextureRotation(&plane, gltexture);
@ -472,7 +468,7 @@ inline void GLFlat::PutFlat(bool fog)
// translucent 3D floors go into the regular translucent list, translucent portals go into the translucent border list.
list = (renderflags&SSRF_RENDER3DPLANES) ? GLDL_TRANSLUCENT : GLDL_TRANSLUCENTBORDER;
}
else if (gltexture->GetTransparent())
else if (gltexture->tex->GetTranslucency())
{
if (stack)
{

View file

@ -45,8 +45,6 @@
#include "gl/renderer/gl_renderer.h"
#include "gl/renderer/gl_renderstate.h"
#include "gl/renderer/gl_quaddrawer.h"
#include "gl/dynlights/gl_glow.h"
#include "gl/data/gl_data.h"
#include "gl/data/gl_vertexbuffer.h"
#include "gl/scene/gl_clipper.h"
#include "gl/scene/gl_drawinfo.h"
@ -56,7 +54,6 @@
#include "gl/stereo3d/scoped_color_mask.h"
#include "gl/textures/gl_material.h"
#include "gl/utility/gl_clock.h"
#include "gl/utility/gl_templates.h"
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
@ -88,7 +85,9 @@ bool GLPortal::inskybox;
UniqueList<GLSkyInfo> UniqueSkies;
UniqueList<GLHorizonInfo> UniqueHorizons;
UniqueList<secplane_t> UniquePlaneMirrors;
UniqueList<FGLLinePortal> UniqueLineToLines;
UniqueList<FLinePortalSpan> UniqueLineToLines;
int skyboxrecursion = 0;
//==========================================================================
//
@ -463,7 +462,7 @@ void GLPortal::StartFrame()
//-----------------------------------------------------------------------------
//
// Portal info
// printing portal info
//
//-----------------------------------------------------------------------------
@ -474,7 +473,7 @@ CCMD(gl_portalinfo)
gl_portalinfo = true;
}
FString indent;
static FString indent;
//-----------------------------------------------------------------------------
//
@ -580,20 +579,22 @@ GLPortal * GLPortal::FindPortal(const void * src)
//-----------------------------------------------------------------------------
//
//
// Save/RestoreMapSection
//
// saves CurrentMapSection for a recursive call of SceneDrawer::DrawScene
//
//-----------------------------------------------------------------------------
void GLPortal::SaveMapSection()
{
savedmapsection.Resize(currentmapsection.Size());
memcpy(&savedmapsection[0], &currentmapsection[0], currentmapsection.Size());
memset(&currentmapsection[0], 0, currentmapsection.Size());
SavedMapSection = std::move(drawer->CurrentMapSections);
drawer->CurrentMapSections.Resize(SavedMapSection.Size());
drawer->CurrentMapSections.Zero();
}
void GLPortal::RestoreMapSection()
{
memcpy(&currentmapsection[0], &savedmapsection[0], currentmapsection.Size());
drawer->CurrentMapSections = std::move(SavedMapSection);
}
//-----------------------------------------------------------------------------
@ -611,7 +612,7 @@ void GLPortal::RestoreMapSection()
// GLSkyboxPortal::DrawContents
//
//-----------------------------------------------------------------------------
static int skyboxrecursion=0;
void GLSkyboxPortal::DrawContents()
{
int old_pm = PlaneMirrorMode;
@ -651,7 +652,7 @@ void GLSkyboxPortal::DrawContents()
int mapsection = R_PointInSubsector(r_viewpoint.Pos)->mapsection;
SaveMapSection();
currentmapsection[mapsection >> 3] |= 1 << (mapsection & 7);
drawer->CurrentMapSections.Set(mapsection);
drawer->DrawScene(DM_SKYPORTAL);
portal->mFlags &= ~PORTSF_INSKYBOX;
@ -674,6 +675,22 @@ void GLSkyboxPortal::DrawContents()
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//==========================================================================
//
// Fixme: This needs abstraction.
//
//==========================================================================
GLSectorStackPortal *FSectorPortalGroup::GetRenderState()
{
if (glportal == NULL) glportal = new GLSectorStackPortal(this);
return glportal;
}
GLSectorStackPortal::~GLSectorStackPortal()
{
if (origin != NULL && origin->glportal == this)
@ -717,7 +734,7 @@ void GLSectorStackPortal::SetupCoverage()
for(int j=0;j<sub->portalcoverage[plane].sscount; j++)
{
subsector_t *dsub = &::level.subsectors[sub->portalcoverage[plane].subsectors[j]];
currentmapsection[dsub->mapsection>>3] |= 1 << (dsub->mapsection&7);
drawer->CurrentMapSections.Set(dsub->mapsection);
gl_drawinfo->ss_renderflags[dsub->Index()] |= SSRF_SEEN;
}
}
@ -731,7 +748,7 @@ void GLSectorStackPortal::SetupCoverage()
//-----------------------------------------------------------------------------
void GLSectorStackPortal::DrawContents()
{
FPortal *portal = origin;
FSectorPortalGroup *portal = origin;
r_viewpoint.Pos += origin->mDisplacement;
r_viewpoint.ActorPos += origin->mDisplacement;
@ -1040,8 +1057,7 @@ 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];
int mapsection = sub->mapsection;
currentmapsection[mapsection >> 3] |= 1 << (mapsection & 7);
drawer->CurrentMapSections.Set(sub->mapsection);
}
GLRenderer->mViewActor = nullptr;

View file

@ -37,11 +37,9 @@
#define __GL_PORTAL_H
#include "tarray.h"
//#include "gl/gl_intern.h"
#include "actor.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/scene/gl_drawinfo.h"
#include "gl/utility/gl_templates.h"
#include "gl/data/gl_data.h"
struct GLHorizonInfo
{
@ -76,7 +74,7 @@ struct GLSkyInfo
extern UniqueList<GLSkyInfo> UniqueSkies;
extern UniqueList<GLHorizonInfo> UniqueHorizons;
extern UniqueList<secplane_t> UniquePlaneMirrors;
extern UniqueList<FGLLinePortal> UniqueLineToLines;
extern UniqueList<FLinePortalSpan> UniqueLineToLines;
struct GLEEHorizonPortal;
class GLSceneDrawer;
@ -111,7 +109,7 @@ private:
ActorRenderFlags savedvisibility;
GLPortal *PrevPortal;
GLPortal *PrevClipPortal;
TArray<uint8_t> savedmapsection;
BitArray SavedMapSection;
TArray<unsigned int> mPrimIndices;
protected:
@ -200,7 +198,7 @@ struct GLLinePortal : public GLPortal
CalcDelta();
}
GLLinePortal(FGLLinePortal *line)
GLLinePortal(FLinePortalSpan *line)
{
if (line->lines[0]->mType != PORTT_LINKED || line->v1 == nullptr)
{
@ -260,7 +258,7 @@ public:
struct GLLineToLinePortal : public GLLinePortal
{
FGLLinePortal *glport;
FLinePortalSpan *glport;
protected:
virtual void DrawContents();
virtual void * GetSource() const { return glport; }
@ -270,7 +268,7 @@ protected:
public:
GLLineToLinePortal(FGLLinePortal *ll)
GLLineToLinePortal(FLinePortalSpan *ll)
: GLLinePortal(ll)
{
glport = ll;
@ -333,11 +331,11 @@ protected:
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();
FPortal *origin;
FSectorPortalGroup *origin;
public:
GLSectorStackPortal(FPortal *pt)
GLSectorStackPortal(FSectorPortalGroup *pt)
{
origin=pt;
}

View file

@ -33,25 +33,27 @@
#include "g_levellocals.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/data/gl_data.h"
#include "gl/dynlights/gl_glow.h"
#include "gl/scene/gl_drawinfo.h"
#include "gl/scene/gl_portal.h"
#include "gl/scene/gl_scenedrawer.h"
#include "gl/utility/gl_clock.h"
#include "gl/utility/gl_templates.h"
// This is for debugging maps.
FreeList<gl_subsectorrendernode> SSR_List;
// profiling data
static int totalupper, totallower;
static int lowershcount, uppershcount;
static glcycle_t totalms, showtotalms;
static glcycle_t totalssms;
static sector_t fakesec;
static glcycle_t totalms, showtotalms, totalssms;
static sector_t fakesec; // this is static because it gets used in recursively called functions.
// Having this static doesn't really matter here because the hack code is not multithreading-capable anyway.
static bool inview;
static subsector_t * viewsubsector;
static TArray<seg_t *> lowersegs;
void FDrawInfo::ClearBuffers()
{
@ -62,7 +64,7 @@ void FDrawInfo::ClearBuffers()
{
gl_subsectorrendernode * n = node;
node = node->next;
SSR_List.Release(n);
delete n;
}
}
otherfloorplanes.Clear();
@ -74,7 +76,7 @@ void FDrawInfo::ClearBuffers()
{
gl_subsectorrendernode * n = node;
node = node->next;
SSR_List.Release(n);
delete n;
}
}
otherceilingplanes.Clear();
@ -507,7 +509,7 @@ void FDrawInfo::HandleMissingTextures()
for (unsigned int j = 0; j < HandledSubsectors.Size(); j++)
{
gl_subsectorrendernode * node = SSR_List.GetNew();
gl_subsectorrendernode * node = new gl_subsectorrendernode;
node->sub = HandledSubsectors[j];
AddOtherCeilingPlane(sec->sectornum, node);
@ -551,7 +553,7 @@ void FDrawInfo::HandleMissingTextures()
for (unsigned int j = 0; j < HandledSubsectors.Size(); j++)
{
gl_subsectorrendernode * node = SSR_List.GetNew();
gl_subsectorrendernode * node = new gl_subsectorrendernode;
node->sub = HandledSubsectors[j];
AddOtherCeilingPlane(fakesector->sectornum, node);
}
@ -579,7 +581,7 @@ void FDrawInfo::HandleMissingTextures()
for (unsigned int j = 0; j < HandledSubsectors.Size(); j++)
{
gl_subsectorrendernode * node = SSR_List.GetNew();
gl_subsectorrendernode * node = new gl_subsectorrendernode;
node->sub = HandledSubsectors[j];
AddOtherFloorPlane(sec->sectornum, node);
}
@ -622,7 +624,7 @@ void FDrawInfo::HandleMissingTextures()
for (unsigned int j = 0; j < HandledSubsectors.Size(); j++)
{
gl_subsectorrendernode * node = SSR_List.GetNew();
gl_subsectorrendernode * node = new gl_subsectorrendernode;
node->sub = HandledSubsectors[j];
AddOtherFloorPlane(fakesector->sectornum, node);
}
@ -664,7 +666,7 @@ void FDrawInfo::DrawUnhandledMissingTextures()
if (seg->backsector->GetTexture(sector_t::ceiling) == skyflatnum) continue;
if (seg->backsector->ValidatePortal(sector_t::ceiling) != NULL) continue;
if (!glset.notexturefill) FloodUpperGap(seg);
if (!level.notexturefill) FloodUpperGap(seg);
}
validcount++;
@ -683,7 +685,7 @@ void FDrawInfo::DrawUnhandledMissingTextures()
if (seg->backsector->GetTexture(sector_t::floor) == skyflatnum) continue;
if (seg->backsector->ValidatePortal(sector_t::floor) != NULL) continue;
if (!glset.notexturefill) FloodLowerGap(seg);
if (!level.notexturefill) FloodLowerGap(seg);
}
MissingUpperTextures.Clear();
MissingLowerTextures.Clear();
@ -765,9 +767,6 @@ bool FDrawInfo::CheckAnchorFloor(subsector_t * sub)
// Collect connected subsectors that have to be rendered with the same plane
//
//==========================================================================
static bool inview;
static subsector_t * viewsubsector;
static TArray<seg_t *> lowersegs;
bool FDrawInfo::CollectSubsectorsFloor(subsector_t * sub, sector_t * anchor)
{
@ -955,7 +954,7 @@ void FDrawInfo::HandleHackedSubsectors()
{
for(unsigned int j=0;j<HandledSubsectors.Size();j++)
{
gl_subsectorrendernode * node = SSR_List.GetNew();
gl_subsectorrendernode * node = new gl_subsectorrendernode;
node->sub = HandledSubsectors[j];
AddOtherFloorPlane(sub->render_sector->sectornum, node);
@ -985,7 +984,7 @@ void FDrawInfo::HandleHackedSubsectors()
{
for(unsigned int j=0;j<HandledSubsectors.Size();j++)
{
gl_subsectorrendernode * node = SSR_List.GetNew();
gl_subsectorrendernode * node = new gl_subsectorrendernode;
node->sub = HandledSubsectors[j];
AddOtherCeilingPlane(sub->render_sector->sectornum, node);
@ -1037,7 +1036,7 @@ void FDrawInfo::CollectSectorStacksCeiling(subsector_t * sub, sector_t * anchor)
sub->validcount=validcount;
// Has a sector stack or skybox itself!
if (sub->render_sector->GetGLPortal(sector_t::ceiling) != nullptr) return;
if (sub->render_sector->GetPortalGroup(sector_t::ceiling) != nullptr) return;
// Don't bother processing unrendered subsectors
if (sub->numlines>2 && !(ss_renderflags[sub->Index()]&SSRF_PROCESSED)) return;
@ -1081,7 +1080,7 @@ void FDrawInfo::CollectSectorStacksFloor(subsector_t * sub, sector_t * anchor)
sub->validcount=validcount;
// Has a sector stack or skybox itself!
if (sub->render_sector->GetGLPortal(sector_t::floor) != nullptr) return;
if (sub->render_sector->GetPortalGroup(sector_t::floor) != nullptr) return;
// Don't bother processing unrendered subsectors
if (sub->numlines>2 && !(ss_renderflags[sub->Index()]&SSRF_PROCESSED)) return;
@ -1122,13 +1121,12 @@ void FDrawInfo::CollectSectorStacksFloor(subsector_t * sub, sector_t * anchor)
void FDrawInfo::ProcessSectorStacks()
{
unsigned int i;
sector_t fake;
validcount++;
for (i=0;i<CeilingStacks.Size (); i++)
{
sector_t *sec = gl_FakeFlat(CeilingStacks[i], &fake, mDrawer->in_area, false);
FPortal *portal = sec->GetGLPortal(sector_t::ceiling);
sector_t *sec = gl_FakeFlat(CeilingStacks[i], &fakesec, mDrawer->in_area, false);
auto portal = sec->GetPortalGroup(sector_t::ceiling);
if (portal != NULL) for(int k=0;k<sec->subsectorcount;k++)
{
subsector_t * sub = sec->subsectors[k];
@ -1152,14 +1150,14 @@ void FDrawInfo::ProcessSectorStacks()
if (sub->portalcoverage[sector_t::ceiling].subsectors == NULL)
{
gl_BuildPortalCoverage(&sub->portalcoverage[sector_t::ceiling], sub, portal->mDisplacement);
BuildPortalCoverage(&sub->portalcoverage[sector_t::ceiling], sub, portal->mDisplacement);
}
portal->GetRenderState()->AddSubsector(sub);
if (sec->GetAlpha(sector_t::ceiling) != 0 && sec->GetTexture(sector_t::ceiling) != skyflatnum)
{
gl_subsectorrendernode * node = SSR_List.GetNew();
gl_subsectorrendernode * node = new gl_subsectorrendernode;
node->sub = sub;
AddOtherCeilingPlane(sec->sectornum, node);
}
@ -1171,8 +1169,8 @@ void FDrawInfo::ProcessSectorStacks()
validcount++;
for (i=0;i<FloorStacks.Size (); i++)
{
sector_t *sec = gl_FakeFlat(FloorStacks[i], &fake, mDrawer->in_area, false);
FPortal *portal = sec->GetGLPortal(sector_t::floor);
sector_t *sec = gl_FakeFlat(FloorStacks[i], &fakesec, mDrawer->in_area, false);
auto portal = sec->GetPortalGroup(sector_t::floor);
if (portal != NULL) for(int k=0;k<sec->subsectorcount;k++)
{
subsector_t * sub = sec->subsectors[k];
@ -1197,7 +1195,7 @@ void FDrawInfo::ProcessSectorStacks()
if (sub->portalcoverage[sector_t::floor].subsectors == NULL)
{
gl_BuildPortalCoverage(&sub->portalcoverage[sector_t::floor], sub, portal->mDisplacement);
BuildPortalCoverage(&sub->portalcoverage[sector_t::floor], sub, portal->mDisplacement);
}
GLSectorStackPortal *glportal = portal->GetRenderState();
@ -1205,7 +1203,7 @@ void FDrawInfo::ProcessSectorStacks()
if (sec->GetAlpha(sector_t::floor) != 0 && sec->GetTexture(sector_t::floor) != skyflatnum)
{
gl_subsectorrendernode * node = SSR_List.GetNew();
gl_subsectorrendernode * node = new gl_subsectorrendernode;
node->sub = sub;
AddOtherFloorPlane(sec->sectornum, node);
}

View file

@ -42,7 +42,6 @@
#include "po_man.h"
#include "r_utility.h"
#include "p_local.h"
#include "gl/gl_functions.h"
#include "serializer.h"
#include "g_levellocals.h"
#include "events.h"
@ -54,7 +53,6 @@
#include "gl/renderer/gl_lightdata.h"
#include "gl/renderer/gl_renderstate.h"
#include "gl/renderer/gl_renderbuffers.h"
#include "gl/data/gl_data.h"
#include "gl/data/gl_vertexbuffer.h"
#include "gl/dynlights/gl_dynlight.h"
#include "gl/models/gl_models.h"
@ -67,8 +65,6 @@
#include "gl/stereo3d/scoped_view_shifter.h"
#include "gl/textures/gl_material.h"
#include "gl/utility/gl_clock.h"
#include "gl/utility/gl_convert.h"
#include "gl/utility/gl_templates.h"
//==========================================================================
//
@ -83,17 +79,9 @@ CVAR(Bool, gl_sort_textures, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
EXTERN_CVAR (Bool, cl_capfps)
EXTERN_CVAR (Bool, r_deathcamera)
EXTERN_CVAR (Float, underwater_fade_scalar)
EXTERN_CVAR (Float, r_visibility)
EXTERN_CVAR (Bool, gl_legacy_mode)
EXTERN_CVAR (Bool, r_drawvoxels)
extern bool NoInterpolateView;
area_t in_area;
TArray<uint8_t> currentmapsection;
int camtexcount;
//-----------------------------------------------------------------------------
//
// R_FrustumAngle
@ -268,7 +256,7 @@ void GLSceneDrawer::CreateScene()
ProcessAll.Clock();
// clip the scene and fill the drawlists
for(unsigned i=0;i<glSectorPortals.Size(); i++) glSectorPortals[i]->glportal = NULL;
for(auto p : level.portalGroups) p->glportal = nullptr;
GLRenderer->gl_spriteindex=0;
Bsp.Clock();
GLRenderer->mVBO->Map();
@ -278,7 +266,9 @@ void GLSceneDrawer::CreateScene()
if (GLRenderer->mCurrentPortal != NULL) GLRenderer->mCurrentPortal->RenderAttached();
Bsp.Unclock();
// And now the crappy hacks that have to be done to avoid rendering anomalies:
// 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(); // Missing upper/lower textures
gl_drawinfo->HandleHackedSubsectors(); // open sector hacks for deep water
@ -464,7 +454,7 @@ void GLSceneDrawer::RenderTranslucent()
//-----------------------------------------------------------------------------
//
// gl_drawscene - this function renders the scene from the current
// viewpoint, including mirrors and skyboxes and other glSectorPortals
// viewpoint, including mirrors and skyboxes and other portals
// It is assumed that the GLPortal::EndFrame returns with the
// stencil, z-buffer and the projection matrix intact!
//
@ -515,7 +505,7 @@ void GLSceneDrawer::DrawScene(int drawmode)
gl_RenderState.ApplyMatrices();
}
// Handle all glSectorPortals after rendering the opaque objects but before
// Handle all portals after rendering the opaque objects but before
// doing all translucent stuff
recursion++;
GLPortal::EndFrame();
@ -523,138 +513,6 @@ void GLSceneDrawer::DrawScene(int drawmode)
RenderTranslucent();
}
void gl_FillScreen()
{
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
gl_RenderState.EnableTexture(false);
gl_RenderState.Apply();
// The fullscreen quad is stored at index 4 in the main vertex buffer.
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, FFlatVertexBuffer::FULLSCREEN_INDEX, 4);
}
//==========================================================================
//
// Draws a blend over the entire view
//
//==========================================================================
void GLSceneDrawer::DrawBlend(sector_t * viewsector)
{
float blend[4]={0,0,0,0};
PalEntry blendv=0;
float extra_red;
float extra_green;
float extra_blue;
player_t *player = NULL;
if (players[consoleplayer].camera != NULL)
{
player=players[consoleplayer].camera->player;
}
// don't draw sector based blends when an invulnerability colormap is active
if (!FixedColormap)
{
if (!viewsector->e->XFloor.ffloors.Size())
{
if (viewsector->heightsec && !(viewsector->MoreFlags&SECF_IGNOREHEIGHTSEC))
{
switch (in_area)
{
default:
case area_normal: blendv = viewsector->heightsec->midmap; break;
case area_above: blendv = viewsector->heightsec->topmap; break;
case area_below: blendv = viewsector->heightsec->bottommap; break;
}
}
}
else
{
TArray<lightlist_t> & lightlist = viewsector->e->XFloor.lightlist;
for (unsigned int i = 0; i < lightlist.Size(); i++)
{
double lightbottom;
if (i < lightlist.Size() - 1)
lightbottom = lightlist[i + 1].plane.ZatPoint(r_viewpoint.Pos);
else
lightbottom = viewsector->floorplane.ZatPoint(r_viewpoint.Pos);
if (lightbottom < r_viewpoint.Pos.Z && (!lightlist[i].caster || !(lightlist[i].caster->flags&FF_FADEWALLS)))
{
// 3d floor 'fog' is rendered as a blending value
blendv = lightlist[i].blend;
// If this is the same as the sector's it doesn't apply!
if (blendv == viewsector->Colormap.FadeColor) blendv = 0;
// a little hack to make this work for Legacy maps.
if (blendv.a == 0 && blendv != 0) blendv.a = 128;
break;
}
}
}
if (blendv.a == 0)
{
blendv = R_BlendForColormap(blendv);
}
if (blendv.a == 255)
{
extra_red = blendv.r / 255.0f;
extra_green = blendv.g / 255.0f;
extra_blue = blendv.b / 255.0f;
// If this is a multiplicative blend do it separately and add the additive ones on top of it.
blendv = 0;
// black multiplicative blends are ignored
if (extra_red || extra_green || extra_blue)
{
gl_RenderState.BlendFunc(GL_DST_COLOR, GL_ZERO);
gl_RenderState.SetColor(extra_red, extra_green, extra_blue, 1.0f);
gl_FillScreen();
}
}
else if (blendv.a)
{
// [Nash] allow user to set blend intensity
int cnt = blendv.a;
cnt = (int)(cnt * underwater_fade_scalar);
V_AddBlend(blendv.r / 255.f, blendv.g / 255.f, blendv.b / 255.f, cnt / 255.0f, blend);
}
}
// This mostly duplicates the code in shared_sbar.cpp
// When I was writing this the original was called too late so that I
// couldn't get the blend in time. However, since then I made some changes
// here that would get lost if I switched back so I won't do it.
if (player)
{
V_AddPlayerBlend(player, blend, 0.5, 175);
}
if (players[consoleplayer].camera != NULL)
{
// except for fadeto effects
player_t *player = (players[consoleplayer].camera->player != NULL) ? players[consoleplayer].camera->player : &players[consoleplayer];
V_AddBlend (player->BlendR, player->BlendG, player->BlendB, player->BlendA, blend);
}
gl_RenderState.SetTextureMode(TM_MODULATE);
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if (blend[3]>0.0f)
{
gl_RenderState.SetColor(blend[0], blend[1], blend[2], blend[3]);
gl_FillScreen();
}
gl_RenderState.ResetColor();
gl_RenderState.EnableTexture(true);
}
//-----------------------------------------------------------------------------
//
// Draws player sprites and color blend
@ -740,8 +598,9 @@ void GLSceneDrawer::ProcessScene(bool toscreen)
GLPortal::BeginScene();
int mapsection = R_PointInSubsector(r_viewpoint.Pos)->mapsection;
memset(&currentmapsection[0], 0, currentmapsection.Size());
currentmapsection[mapsection>>3] |= 1 << (mapsection & 7);
CurrentMapSections.Resize(level.NumMapSections);
CurrentMapSections.Zero();
CurrentMapSections.Set(mapsection);
DrawScene(toscreen ? DM_MAINVIEW : DM_OFFSCREEN);
FDrawInfo::EndDrawInfo();
@ -793,6 +652,17 @@ void GLSceneDrawer::SetFixedColormap (player_t *player)
gl_RenderState.SetFixedColormap(FixedColormap);
}
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
void GLSceneDrawer::DrawBlend(sector_t *viewsector)
{
GLRenderer->DrawBlend(viewsector, !!FixedColormap, true);
}
//-----------------------------------------------------------------------------
//
// Renders one viewpoint in a scene
@ -892,63 +762,6 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, f
return lviewsector;
}
//-----------------------------------------------------------------------------
//
// renders the view
//
//-----------------------------------------------------------------------------
void FGLRenderer::RenderView (player_t* player)
{
checkBenchActive();
gl_RenderState.SetVertexBuffer(mVBO);
mVBO->Reset();
// reset statistics counters
ResetProfilingData();
// Get this before everything else
if (cl_capfps || r_NoInterpolate) r_viewpoint.TicFrac = 1.;
else r_viewpoint.TicFrac = I_GetTimeFrac ();
P_FindParticleSubsectors ();
if (!gl.legacyMode) mLights->Clear();
// NoInterpolateView should have no bearing on camera textures, but needs to be preserved for the main view below.
bool saved_niv = NoInterpolateView;
NoInterpolateView = false;
// prepare all camera textures that have been used in the last frame
FCanvasTextureInfo::UpdateAll();
NoInterpolateView = saved_niv;
// now render the main view
float fovratio;
float ratio = r_viewwindow.WidescreenRatio;
if (r_viewwindow.WidescreenRatio >= 1.3f)
{
fovratio = 1.333333f;
}
else
{
fovratio = ratio;
}
GLSceneDrawer drawer;
drawer.SetFixedColormap (player);
// Check if there's some lights. If not some code can be skipped.
TThinkerIterator<ADynamicLight> it(STAT_DLIGHT);
mLightCount = ((it.Next()) != NULL);
mShadowMap.Update();
sector_t * viewsector = drawer.RenderViewpoint(player->camera, NULL, r_viewpoint.FieldOfView.Degrees, ratio, fovratio, true, true);
All.Unclock();
}
//===========================================================================
//
// Render the view to a savegame picture
@ -992,231 +805,3 @@ void GLSceneDrawer::WriteSavePic (player_t *player, FileWriter *file, int width,
M_CreatePNG (file, scr + ((height-1) * width * 3), NULL, SS_RGB, width, height, -width * 3, Gamma);
M_Free(scr);
}
//===========================================================================
//
//
//
//===========================================================================
struct FGLInterface : public FRenderer
{
void Precache(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitlist) override;
void RenderView(player_t *player) override;
void WriteSavePic (player_t *player, FileWriter *file, int width, int height) override;
void StartSerialize(FSerializer &arc) override;
void EndSerialize(FSerializer &arc) override;
void RenderTextureView (FCanvasTexture *self, AActor *viewpoint, double fov) override;
void PreprocessLevel() override;
void CleanLevelData() override;
bool RequireGLNodes() override;
int GetMaxViewPitch(bool down) override;
void SetClearColor(int color) override;
void Init() override;
uint32_t GetCaps() override;
};
//==========================================================================
//
// DFrameBuffer :: Precache
//
//==========================================================================
void gl_PrecacheTexture(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitlist);
void FGLInterface::Precache(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitlist)
{
gl_PrecacheTexture(texhitlist, actorhitlist);
}
//===========================================================================
//
// notify the renderer that serialization of the curent level is about to start/end
//
//===========================================================================
void FGLInterface::StartSerialize(FSerializer &arc)
{
}
void FGLInterface::EndSerialize(FSerializer &arc)
{
if (arc.isReading())
{
// The portal data needs to be recreated after reading a savegame.
gl_InitPortals();
}
}
//===========================================================================
//
// Get max. view angle (renderer specific information so it goes here now)
//
//===========================================================================
EXTERN_CVAR(Float, maxviewpitch)
int FGLInterface::GetMaxViewPitch(bool down)
{
return int(maxviewpitch);
}
//===========================================================================
//
//
//
//===========================================================================
void FGLInterface::SetClearColor(int color)
{
PalEntry pe = GPalette.BaseColors[color];
GLRenderer->mSceneClearColor[0] = pe.r / 255.f;
GLRenderer->mSceneClearColor[1] = pe.g / 255.f;
GLRenderer->mSceneClearColor[2] = pe.b / 255.f;
}
//===========================================================================
//
// Render the view to a savegame picture
//
//===========================================================================
void FGLInterface::WriteSavePic (player_t *player, FileWriter *file, int width, int height)
{
GLSceneDrawer drawer;
drawer.WriteSavePic(player, file, width, height);
}
//===========================================================================
//
//
//
//===========================================================================
void FGLInterface::RenderView(player_t *player)
{
GLRenderer->RenderView(player);
}
//===========================================================================
//
//
//
//===========================================================================
void FGLInterface::Init()
{
gl_InitData();
}
//===========================================================================
//
// Camera texture rendering
//
//===========================================================================
CVAR(Bool, gl_usefb, false , CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
extern TexFilter_s TexFilter[];
void FGLInterface::RenderTextureView (FCanvasTexture *tex, AActor *Viewpoint, double FOV)
{
FMaterial * gltex = FMaterial::ValidateTexture(tex, false);
int width = gltex->TextureWidth();
int height = gltex->TextureHeight();
if (gl.legacyMode)
{
// In legacy mode, fail if the requested texture is too large.
if (gltex->GetWidth() > screen->GetWidth() || gltex->GetHeight() > screen->GetHeight()) return;
glFlush();
}
else
{
GLRenderer->StartOffscreen();
gltex->BindToFrameBuffer();
}
GL_IRECT bounds;
bounds.left=bounds.top=0;
bounds.width=FHardwareTexture::GetTexDimension(gltex->GetWidth());
bounds.height=FHardwareTexture::GetTexDimension(gltex->GetHeight());
GLSceneDrawer drawer;
drawer.FixedColormap = CM_DEFAULT;
gl_RenderState.SetFixedColormap(CM_DEFAULT);
drawer.RenderViewpoint(Viewpoint, &bounds, FOV, (float)width/height, (float)width/height, false, false);
if (gl.legacyMode)
{
glFlush();
gl_RenderState.SetMaterial(gltex, 0, 0, -1, false);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, bounds.width, bounds.height);
}
else
{
GLRenderer->EndOffscreen();
}
tex->SetUpdated();
camtexcount++;
}
//===========================================================================
//
//
//
//===========================================================================
void FGLInterface::PreprocessLevel()
{
gl_PreprocessLevel();
}
void FGLInterface::CleanLevelData()
{
gl_CleanLevelData();
}
bool FGLInterface::RequireGLNodes()
{
return true;
}
uint32_t FGLInterface::GetCaps()
{
// describe our basic feature set
ActorRenderFeatureFlags FlagSet = RFF_FLATSPRITES | RFF_MODELS | RFF_SLOPE3DFLOORS |
RFF_TILTPITCH | RFF_ROLLSPRITES | RFF_POLYGONAL;
if (r_drawvoxels)
FlagSet |= RFF_VOXELS;
if (gl_legacy_mode)
{
// legacy mode always has truecolor because palette tonemap is not available
FlagSet |= RFF_TRUECOLOR;
}
else if (!(FGLRenderBuffers::IsEnabled()))
{
// truecolor is always available when renderbuffers are unavailable because palette tonemap is not possible
FlagSet |= RFF_TRUECOLOR | RFF_MATSHADER | RFF_BRIGHTMAP;
}
else
{
if (gl_tonemap != 5) // not running palette tonemap shader
FlagSet |= RFF_TRUECOLOR;
FlagSet |= RFF_MATSHADER | RFF_POSTSHADER | RFF_BRIGHTMAP;
}
return (uint32_t)FlagSet;
}
//===========================================================================
//
//
//
//===========================================================================
FRenderer *gl_CreateInterface()
{
return new FGLInterface;
}

View file

@ -6,6 +6,16 @@
#include "gl_portal.h"
#include "gl/renderer/gl_lightdata.h"
#include "gl/renderer/gl_renderer.h"
#include "r_utility.h"
#include "c_cvars.h"
EXTERN_CVAR(Int, gl_weaponlight);
inline int getExtraLight()
{
return r_viewpoint.extralight * gl_weaponlight;
}
class GLSceneDrawer
{
@ -45,6 +55,7 @@ public:
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);
@ -60,7 +71,7 @@ public:
void DrawBlend(sector_t * viewsector);
void EndDrawScene(sector_t * viewsector);
void DrawEndScene2D(sector_t * viewsector);
void RenderActorsInPortal(FGLLinePortal *glport);
void RenderActorsInPortal(FLinePortalSpan *glport);
void CheckViewArea(vertex_t *v1, vertex_t *v2, sector_t *frontsector, sector_t *backsector);
@ -71,7 +82,7 @@ public:
void DrawPSprite(player_t * player, DPSprite *psp, float sx, float sy, bool hudModelStep, int OverrideShader, bool alphatexture);
void DrawPlayerSprites(sector_t * viewsector, bool hudModelStep);
void DrawTargeterSprites();
void InitClipper(angle_t a1, angle_t a2)
{
clipper.Clear();

View file

@ -29,14 +29,11 @@
#include "doomdata.h"
#include "portal.h"
#include "g_levellocals.h"
#include "gl/gl_functions.h"
#include "gl/data/gl_data.h"
#include "gl/renderer/gl_lightdata.h"
#include "gl/scene/gl_drawinfo.h"
#include "gl/scene/gl_portal.h"
#include "gl/textures/gl_material.h"
#include "gl/utility/gl_convert.h"
CVAR(Bool,gl_noskyboxes, false, 0)
@ -136,7 +133,7 @@ void GLWall::SkyPlane(sector_t *sector, int plane, bool allowreflect)
case PORTS_PORTAL:
case PORTS_LINKEDPORTAL:
{
FPortal *glport = sector->GetGLPortal(plane);
auto glport = sector->GetPortalGroup(plane);
if (glport != NULL)
{
if (sector->PortalBlocksView(plane)) return;
@ -299,8 +296,8 @@ void GLWall::SkyTop(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex
int type = fs->GetPortalType(sector_t::ceiling);
if (type == PORTS_STACKEDSECTORTHING || type == PORTS_PORTAL || type == PORTS_LINKEDPORTAL)
{
FPortal *pfront = fs->GetGLPortal(sector_t::ceiling);
FPortal *pback = bs->GetGLPortal(sector_t::ceiling);
auto pfront = fs->GetPortalGroup(sector_t::ceiling);
auto pback = bs->GetPortalGroup(sector_t::ceiling);
if (pfront == NULL || fs->PortalBlocksView(sector_t::ceiling)) return;
if (pfront == pback && !bs->PortalBlocksView(sector_t::ceiling)) return;
}
@ -378,8 +375,8 @@ void GLWall::SkyBottom(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,ver
int type = fs->GetPortalType(sector_t::floor);
if (type == PORTS_STACKEDSECTORTHING || type == PORTS_PORTAL || type == PORTS_LINKEDPORTAL)
{
FPortal *pfront = fs->GetGLPortal(sector_t::floor);
FPortal *pback = bs->GetGLPortal(sector_t::floor);
auto pfront = fs->GetPortalGroup(sector_t::floor);
auto pback = bs->GetPortalGroup(sector_t::floor);
if (pfront == NULL || fs->PortalBlocksView(sector_t::floor)) return;
if (pfront == pback && !bs->PortalBlocksView(sector_t::floor)) return;
}

View file

@ -64,7 +64,6 @@
#include "textures/skyboxtexture.h"
#include "gl/system/gl_interface.h"
#include "gl/data/gl_data.h"
#include "gl/data/gl_vertexbuffer.h"
#include "gl/renderer/gl_lightdata.h"
#include "gl/renderer/gl_renderstate.h"
@ -72,7 +71,6 @@
#include "gl/scene/gl_scenedrawer.h"
#include "gl/scene/gl_portal.h"
#include "gl/shaders/gl_shader.h"
#include "gl/textures/gl_texture.h"
#include "gl/textures/gl_material.h"
@ -436,9 +434,9 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool
gl_RenderState.mModelMatrix.loadIdentity();
if (!sky2)
gl_RenderState.mModelMatrix.rotate(-180.0f+x_offset, glset.skyrotatevector.X, glset.skyrotatevector.Z, glset.skyrotatevector.Y);
gl_RenderState.mModelMatrix.rotate(-180.0f+x_offset, level.info->skyrotatevector.X, level.info->skyrotatevector.Z, level.info->skyrotatevector.Y);
else
gl_RenderState.mModelMatrix.rotate(-180.0f+x_offset, glset.skyrotatevector2.X, glset.skyrotatevector2.Z, glset.skyrotatevector2.Y);
gl_RenderState.mModelMatrix.rotate(-180.0f+x_offset, level.info->skyrotatevector2.X, level.info->skyrotatevector2.Z, level.info->skyrotatevector2.Y);
if (sb->faces[5])
{
@ -502,10 +500,10 @@ void GLSkyPortal::DrawContents()
bool drawBoth = false;
// We have no use for Doom lighting special handling here, so disable it for this function.
int oldlightmode = glset.lightmode;
if (glset.lightmode == 8)
int oldlightmode = ::level.lightmode;
if (::level.lightmode == 8)
{
glset.lightmode = 2;
::level.lightmode = 2;
gl_RenderState.SetSoftLightLevel(-1);
}
@ -520,7 +518,7 @@ void GLSkyPortal::DrawContents()
drawer->SetupView(0, 0, 0, r_viewpoint.Angles.Yaw, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
gl_RenderState.SetVertexBuffer(GLRenderer->mSkyVBO);
if (origin->texture[0] && origin->texture[0]->tex->gl_info.bSkybox)
if (origin->texture[0] && origin->texture[0]->tex->bSkybox)
{
RenderBox(origin->skytexno1, origin->texture[0], origin->x_offset[0], origin->sky2);
}
@ -558,7 +556,7 @@ void GLSkyPortal::DrawContents()
gl_RenderState.SetVertexBuffer(GLRenderer->mVBO);
gl_MatrixStack.Pop(gl_RenderState.mViewMatrix);
gl_RenderState.ApplyMatrices();
glset.lightmode = oldlightmode;
::level.lightmode = oldlightmode;
gl_RenderState.SetDepthClamp(oldClamp);
}

View file

@ -30,7 +30,6 @@
#include "p_effect.h"
#include "g_level.h"
#include "doomstat.h"
#include "gl/gl_functions.h"
#include "r_defs.h"
#include "r_sky.h"
#include "r_utility.h"
@ -48,8 +47,6 @@
#include "gl/renderer/gl_lightdata.h"
#include "gl/renderer/gl_renderstate.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/data/gl_data.h"
#include "gl/dynlights/gl_glow.h"
#include "gl/scene/gl_drawinfo.h"
#include "gl/scene/gl_scenedrawer.h"
#include "gl/scene/gl_portal.h"
@ -82,7 +79,6 @@ EXTERN_CVAR (Bool, r_debug_disable_vis_filter)
extern TArray<spritedef_t> sprites;
extern TArray<spriteframe_t> SpriteFrames;
extern uint32_t r_renderercaps;
extern int modellightindex;
enum HWRenderStyle
{
@ -301,7 +297,7 @@ void GLSprite::Draw(int pass)
gl_SetRenderStyle(RenderStyle, false,
// The rest of the needed checks are done inside gl_SetRenderStyle
trans > 1.f - FLT_EPSILON && gl_usecolorblending && mDrawer->FixedColormap == CM_DEFAULT && actor &&
fullbright && gltexture && !gltexture->GetTransparent());
fullbright && gltexture && !gltexture->tex->GetTranslucency());
if (hw_styleflags == STYLEHW_NoAlphaTest)
{
@ -426,7 +422,7 @@ void GLSprite::Draw(int pass)
secplane_t *lowplane = i == (*lightlist).Size() - 1 ? &bottomp : &(*lightlist)[i + 1].plane;
int thislight = (*lightlist)[i].caster != NULL ? gl_ClampLight(*(*lightlist)[i].p_lightlevel) : lightlevel;
int thisll = actor == nullptr? thislight : (uint8_t)gl_CheckSpriteGlow(actor->Sector, thislight, actor->InterpolatedPosition(r_viewpoint.TicFrac));
int thisll = actor == nullptr? thislight : (uint8_t)actor->Sector->CheckSpriteGlow(thislight, actor->InterpolatedPosition(r_viewpoint.TicFrac));
FColormap thiscm;
thiscm.CopyFog(Colormap);
@ -477,7 +473,7 @@ void GLSprite::Draw(int pass)
}
else
{
gl_RenderModel(this);
gl_RenderModel(this, dynlightindex);
}
}
@ -601,6 +597,7 @@ void GLSprite::PerformSpriteClipAdjustment(AActor *thing, const DVector2 &thingp
for (unsigned int i = 0; i < x.ffloors.Size(); i++)
{
F3DFloor * ff = x.ffloors[i];
if (ff->flags & FF_THISINSIDE) continue; // only relevant for software rendering.
float floorh = ff->top.plane->ZatPoint(thingpos);
float ceilingh = ff->bottom.plane->ZatPoint(thingpos);
if (floorh == thing->floorz)
@ -722,17 +719,17 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
}
// If this thing is in a map section that's not in view it can't possibly be visible
if (!thruportal && !(currentmapsection[thing->subsector->mapsection >> 3] & (1 << (thing->subsector->mapsection & 7)))) return;
if (!thruportal && !mDrawer->CurrentMapSections[thing->subsector->mapsection]) return;
// [RH] Interpolate the sprite's position to make it look smooth
DVector3 thingpos = thing->InterpolatedPosition(r_viewpoint.TicFrac);
if (thruportal == 1) thingpos += Displacements.getOffset(thing->Sector->PortalGroup, sector->PortalGroup);
if (thruportal == 1) thingpos += level.Displacements.getOffset(thing->Sector->PortalGroup, sector->PortalGroup);
// Some added checks if the camera actor is not supposed to be seen. It can happen that some portal setup has this actor in view in which case it may not be skipped here
if (thing == camera && !r_viewpoint.showviewer)
{
DVector3 thingorigin = thing->Pos();
if (thruportal == 1) thingorigin += Displacements.getOffset(thing->Sector->PortalGroup, sector->PortalGroup);
if (thruportal == 1) thingorigin += level.Displacements.getOffset(thing->Sector->PortalGroup, sector->PortalGroup);
if (fabs(thingorigin.X - r_viewpoint.ActorPos.X) < 2 && fabs(thingorigin.Y - r_viewpoint.ActorPos.Y) < 2) return;
}
// Thing is invisible if close to the camera.
@ -941,14 +938,14 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
// allow disabling of the fullbright flag by a brightmap definition
// (e.g. to do the gun flashes of Doom's zombies correctly.
fullbright = (thing->flags5 & MF5_BRIGHT) ||
((thing->renderflags & RF_FULLBRIGHT) && (!gltexture || !gltexture->tex->gl_info.bDisableFullbright));
((thing->renderflags & RF_FULLBRIGHT) && (!gltexture || !gltexture->tex->bDisableFullbright));
lightlevel = fullbright ? 255 :
gl_ClampLight(rendersector->GetTexture(sector_t::ceiling) == skyflatnum ?
rendersector->GetCeilingLight() : rendersector->GetFloorLight());
foglevel = (uint8_t)clamp<short>(rendersector->lightlevel, 0, 255);
lightlevel = gl_CheckSpriteGlow(rendersector, lightlevel, thingpos);
lightlevel = rendersector->CheckSpriteGlow(lightlevel, thingpos);
ThingColor = (thing->RenderStyle.Flags & STYLEF_ColorIsFixed) ? thing->fillcolor : 0xffffff;
ThingColor.a = 255;
@ -1063,7 +1060,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
RenderStyle.DestAlpha = STYLEALPHA_InvSrc;
}
}
if ((gltexture && gltexture->GetTransparent()) || (RenderStyle.Flags & STYLEF_RedIsAlpha))
if ((gltexture && gltexture->tex->GetTranslucency()) || (RenderStyle.Flags & STYLEF_RedIsAlpha))
{
if (hw_styleflags == STYLEHW_Solid)
{
@ -1284,7 +1281,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s
//
//==========================================================================
void GLSceneDrawer::RenderActorsInPortal(FGLLinePortal *glport)
void GLSceneDrawer::RenderActorsInPortal(FLinePortalSpan *glport)
{
TMap<AActor*, bool> processcheck;
if (glport->validcount == validcount) return; // only process once per frame

View file

@ -30,7 +30,6 @@
#include "p_local.h"
#include "p_effect.h"
#include "vectors.h"
#include "gl/gl_functions.h"
#include "g_level.h"
#include "g_levellocals.h"
#include "actorinlines.h"
@ -38,7 +37,6 @@
#include "gl/system/gl_cvars.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/renderer/gl_lightdata.h"
#include "gl/data/gl_data.h"
#include "gl/dynlights/gl_dynlight.h"
#include "gl/scene/gl_drawinfo.h"
#include "gl/scene/gl_portal.h"
@ -46,8 +44,6 @@
#include "gl/textures/gl_material.h"
#include "gl/dynlights/gl_lightbuffer.h"
FDynLightData modellightdata;
int modellightindex = -1;
template<class T>
T smoothstep(const T edge0, const T edge1, const T x)
@ -81,13 +77,13 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *
// This is a performance critical section of code where we cannot afford to let the compiler decide whether to inline the function or not.
// This will do the calculations explicitly rather than calling one of AActor's utility functions.
if (Displacements.size > 0)
if (level.Displacements.size > 0)
{
int fromgroup = light->Sector->PortalGroup;
int togroup = subsec->sector->PortalGroup;
if (fromgroup == togroup || fromgroup == 0 || togroup == 0) goto direct;
DVector2 offset = Displacements.getOffset(fromgroup, togroup);
DVector2 offset = level.Displacements.getOffset(fromgroup, togroup);
L = FVector3(x - light->X() - offset.X, y - light->Y() - offset.Y, z - light->Z());
}
else
@ -140,7 +136,6 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *
node = node->nextLight;
}
gl_RenderState.SetDynLight(out[0], out[1], out[2]);
modellightindex = -1;
}
void gl_SetDynSpriteLight(AActor *thing, particle_t *particle)
@ -200,11 +195,12 @@ void BSPWalkCircle(float x, float y, float radiusSquared, const Callback &callba
int gl_SetDynModelLight(AActor *self, int dynlightindex)
{
static FDynLightData modellightdata; // If this ever gets multithreaded, this variable must either be made non-static or thread_local.
// For deferred light mode this function gets called twice. First time for list upload, and second for draw.
if (gl.lightmethod == LM_DEFERRED && dynlightindex != -1)
{
gl_RenderState.SetDynLight(0, 0, 0);
modellightindex = dynlightindex;
return dynlightindex;
}
@ -262,7 +258,6 @@ int gl_SetDynModelLight(AActor *self, int dynlightindex)
if (gl.lightmethod != LM_DEFERRED)
{
gl_RenderState.SetDynLight(0, 0, 0);
modellightindex = dynlightindex;
}
return dynlightindex;
}

128
src/gl/scene/gl_swscene.cpp Normal file
View file

@ -0,0 +1,128 @@
//
//---------------------------------------------------------------------------
//
// Copyright(C) 2004-2018 Christoph Oelckers
// All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see http://www.gnu.org/licenses/
//
//--------------------------------------------------------------------------
//
/*
** gl_swscene.cpp
** common overlay code for software and hardware renderer
**
*/
#include "gl/system/gl_system.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_debug.h"
#include "gl/data/gl_vertexbuffer.h"
#include "gl/shaders/gl_shader.h"
#include "gl/renderer/gl_renderstate.h"
#include "v_palette.h"
#include "v_video.h"
#include "gl_swscene.h"
#include "w_wad.h"
#include "d_player.h"
#include "textures/bitmap.h"
#include "swrenderer/scene/r_light.h"
// [RH] Base blending values (for e.g. underwater)
int BaseBlendR, BaseBlendG, BaseBlendB;
float BaseBlendA;
class FSWPaletteTexture : public FTexture
{
public:
FSWPaletteTexture()
{
Width = 256;
Height = 1;
UseType = ETextureType::MiscPatch;
}
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf)
{
PalEntry *pe = (PalEntry*)bmp->GetPixels();
for (int i = 0; i < 256; i++)
{
pe[i] = GPalette.BaseColors[i].d | 0xff000000;
}
return 0;
}
};
class FSWSceneTexture : public FTexture
{
public:
FHardwareTexture *hwtex;
FSWSceneTexture(int w, int h, int bits)
{
Width = w;
Height = h;
WidthBits = bits;
UseType = ETextureType::SWCanvas;
hwtex = new FHardwareTexture(true);
new FGLTexture(this, hwtex);
}
// This is just a wrapper around the hardware texture and should never call the bitmap getters - if it does, something is wrong.
};
//==========================================================================
//
// SWSceneDrawer :: CreateResources
//
//==========================================================================
SWSceneDrawer::SWSceneDrawer()
{
PaletteTexture = new FSWPaletteTexture;
}
SWSceneDrawer::~SWSceneDrawer()
{
if (PaletteTexture != nullptr) delete PaletteTexture;
if (FBTexture != nullptr) delete FBTexture;
}
void SWSceneDrawer::RenderView(player_t *player)
{
DCanvas buffer(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor());
if (FBTexture == nullptr || FBTexture->hwtex == nullptr || FBTexture->GetWidth() != screen->GetWidth() || FBTexture->GetHeight() != screen->GetHeight() || (V_IsTrueColor() ? 1:0) != FBTexture->WidthBits)
{
// This manually constructs its own material here.
if (FBTexture != nullptr) delete FBTexture;
FBTexture = new FSWSceneTexture(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor());
FBTexture->hwtex->AllocateBuffer(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor() ? 4 : 1);
auto mat = FMaterial::ValidateTexture(FBTexture, false);
mat->AddTextureLayer(PaletteTexture);
}
auto buf = FBTexture->hwtex->MapBuffer();
if (!buf) I_FatalError("Unable to map buffer for software rendering");
buffer.SetBuffer(screen->GetWidth(), screen->GetHeight(), screen->GetWidth(), buf);
SWRenderer->RenderView(player, &buffer);
FBTexture->hwtex->CreateTexture(nullptr, screen->GetWidth(), screen->GetHeight(), 0, false, 0, "swbuffer");
auto map = swrenderer::CameraLight::Instance()->ShaderColormap();
screen->Begin2D(false);
screen->DrawTexture(FBTexture, 0, 0, DTA_SpecialColormap, map, TAG_DONE);
SWRenderer->DrawRemainingPlayerSprites();
GLRenderer->DrawBlend(r_viewpoint.sector, !!map, V_IsTrueColor(), true);
}

33
src/gl/scene/gl_swscene.h Normal file
View file

@ -0,0 +1,33 @@
#pragma once
#pragma once
#include "r_defs.h"
#include "m_fixed.h"
#include "gl_clipper.h"
#include "gl_portal.h"
#include "gl/renderer/gl_lightdata.h"
#include "gl/renderer/gl_renderer.h"
#include "r_utility.h"
#include "c_cvars.h"
class FSWSceneTexture;
class SWSceneDrawer
{
FTexture *PaletteTexture = nullptr;
FSWSceneTexture *FBTexture = nullptr;
bool FBIsTruecolor = false;
void BlendView (player_t *CPlayer, float blend[4]);
bool CreateResources();
void BindFBBuffer();
public:
SWSceneDrawer();
~SWSceneDrawer();
void RenderView(player_t *player);
};

View file

@ -23,18 +23,14 @@
#include "gl/system/gl_system.h"
#include "gl/gl_functions.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/renderer/gl_lightdata.h"
#include "gl/data/gl_data.h"
#include "gl/data/gl_vertexbuffer.h"
#include "gl/dynlights/gl_glow.h"
#include "gl/scene/gl_drawinfo.h"
#include "gl/scene/gl_portal.h"
#include "gl/shaders/gl_shader.h"
#include "gl/textures/gl_material.h"
#include "gl/utility/gl_templates.h"
EXTERN_CVAR(Bool, gl_seamless)

View file

@ -20,9 +20,9 @@ class FMaterial;
struct GLDrawList;
struct GLSkyInfo;
struct FTexCoordInfo;
struct FPortal;
struct FSectorPortalGroup;
struct FFlatVertex;
struct FGLLinePortal;
struct FLinePortalSpan;
class GLSceneDrawer;
enum
@ -171,9 +171,9 @@ public:
FSectorPortal *secportal; // sector portal (formerly skybox)
GLSkyInfo * sky; // for normal sky
GLHorizonInfo * horizon; // for horizon information
FPortal * portal; // stacked sector portals
FSectorPortalGroup * portal; // stacked sector portals
secplane_t * planemirror; // for plane mirrors
FGLLinePortal *lineportal; // line-to-line portals
FLinePortalSpan *lineportal; // line-to-line portals
};

View file

@ -37,15 +37,12 @@
#include "gl/system/gl_cvars.h"
#include "gl/renderer/gl_lightdata.h"
#include "gl/data/gl_data.h"
#include "gl/dynlights/gl_dynlight.h"
#include "gl/dynlights/gl_glow.h"
#include "gl/scene/gl_drawinfo.h"
#include "gl/scene/gl_portal.h"
#include "gl/scene/gl_scenedrawer.h"
#include "gl/textures/gl_material.h"
#include "gl/utility/gl_clock.h"
#include "gl/utility/gl_templates.h"
#include "gl/shaders/gl_shader.h"
@ -72,7 +69,7 @@ void GLWall::PutWall(bool translucent)
};
if (gltexture && gltexture->GetTransparent() && passflag[type] == 2)
if (gltexture && gltexture->tex->GetTranslucency() && passflag[type] == 2)
{
translucent = true;
}
@ -178,9 +175,9 @@ void GLWall::PutPortal(int ptype)
if (!portal)
{
line_t *otherside = lineportal->lines[0]->mDestination;
if (otherside != NULL && otherside->portalindex < linePortals.Size())
if (otherside != NULL && otherside->portalindex < level.linePortals.Size())
{
mDrawer->RenderActorsInPortal(linePortalToGL[otherside->portalindex]);
mDrawer->RenderActorsInPortal(otherside->getPortal()->mGroup);
}
portal = new GLLineToLinePortal(lineportal);
}
@ -995,7 +992,7 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary,
case 0:
RenderStyle=STYLE_Translucent;
alpha = seg->linedef->alpha;
translucent =alpha < 1. || (gltexture && gltexture->GetTransparent());
translucent =alpha < 1. || (gltexture && gltexture->tex->GetTranslucency());
break;
case ML_ADDTRANS:
@ -1221,6 +1218,7 @@ void GLWall::InverseFloors(seg_t * seg, sector_t * frontsector,
for (unsigned int i = 0; i < frontffloors.Size(); i++)
{
F3DFloor * rover = frontffloors[i];
if (rover->flags & FF_THISINSIDE) continue; // only relevant for software rendering.
if (!(rover->flags&FF_EXISTS)) continue;
if (!(rover->flags&FF_RENDERSIDES)) continue;
if (!(rover->flags&(FF_INVERTSIDES | FF_ALLSIDES))) continue;
@ -1273,6 +1271,7 @@ void GLWall::ClipFFloors(seg_t * seg, F3DFloor * ffloor, sector_t * frontsector,
for (unsigned int i = 0; i < frontffloors.Size(); i++)
{
F3DFloor * rover = frontffloors[i];
if (rover->flags & FF_THISINSIDE) continue; // only relevant for software rendering.
if (!(rover->flags&FF_EXISTS)) continue;
if (!(rover->flags&FF_RENDERSIDES)) continue;
if ((rover->flags&(FF_SWIMMABLE | FF_TRANSLUCENT)) != flags) continue;
@ -1372,6 +1371,7 @@ void GLWall::DoFFloorBlocks(seg_t * seg, sector_t * frontsector, sector_t * back
for (unsigned int i = 0; i < backffloors.Size(); i++)
{
F3DFloor * rover = backffloors[i];
if (rover->flags & FF_THISINSIDE) continue; // only relevant for software rendering.
if (!(rover->flags&FF_EXISTS)) continue;
if (!(rover->flags&FF_RENDERSIDES) || (rover->flags&FF_INVERTSIDES)) continue;
@ -1483,8 +1483,8 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
glseg.fracright = 1;
if (gl_seamless)
{
if (v1->dirty) gl_RecalcVertexHeights(v1);
if (v2->dirty) gl_RecalcVertexHeights(v2);
if (v1->dirty) v1->RecalcVertexHeights();
if (v2->dirty) v2->RecalcVertexHeights();
}
}
else // polyobjects must be rendered per seg.
@ -1538,7 +1538,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
gltexture = NULL;
if (gl_GetWallGlow(frontsector, topglowcolor, bottomglowcolor)) flags |= GLWF_GLOW;
if (frontsector->GetWallGlow(topglowcolor, bottomglowcolor)) flags |= GLWF_GLOW;
topplane = frontsector->ceilingplane;
bottomplane = frontsector->floorplane;
@ -1563,7 +1563,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
if (seg->linedef->isVisualPortal())
{
lineportal = linePortalToGL[seg->linedef->portalindex];
lineportal = seg->linedef->getPortal()->mGroup;
ztop[0] = zceil[0];
ztop[1] = zceil[1];
zbottom[0] = zfloor[0];
@ -1670,7 +1670,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
if (isportal)
{
lineportal = linePortalToGL[seg->linedef->portalindex];
lineportal = seg->linedef->getPortal()->mGroup;
ztop[0] = bch1;
ztop[1] = bch2;
zbottom[0] = bfh1;
@ -1774,7 +1774,7 @@ void GLWall::ProcessLowerMiniseg(seg_t *seg, sector_t * frontsector, sector_t *
RenderStyle = STYLE_Normal;
Colormap = frontsector->Colormap;
if (gl_GetWallGlow(frontsector, topglowcolor, bottomglowcolor)) flags |= GLWF_GLOW;
if (frontsector->GetWallGlow(topglowcolor, bottomglowcolor)) flags |= GLWF_GLOW;
topplane = frontsector->ceilingplane;
bottomplane = frontsector->floorplane;
dynlightindex = -1;

View file

@ -27,17 +27,14 @@
#include "g_levellocals.h"
#include "actor.h"
#include "actorinlines.h"
#include "gl/gl_functions.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_cvars.h"
#include "gl/renderer/gl_lightdata.h"
#include "gl/renderer/gl_renderstate.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/data/gl_data.h"
#include "gl/data/gl_vertexbuffer.h"
#include "gl/dynlights/gl_dynlight.h"
#include "gl/dynlights/gl_glow.h"
#include "gl/dynlights/gl_lightbuffer.h"
#include "gl/scene/gl_drawinfo.h"
#include "gl/scene/gl_portal.h"
@ -45,7 +42,6 @@
#include "gl/shaders/gl_shader.h"
#include "gl/textures/gl_material.h"
#include "gl/utility/gl_clock.h"
#include "gl/utility/gl_templates.h"
#include "gl/renderer/gl_quaddrawer.h"
EXTERN_CVAR(Bool, gl_seamless)
@ -60,7 +56,7 @@ FDynLightData lightdata;
void GLWall::SetupLights()
{
if (RenderStyle == STYLE_Add && !glset.lightadditivesurfaces) return; // no lights on additively blended surfaces.
if (RenderStyle == STYLE_Add && !level.lightadditivesurfaces) return; // no lights on additively blended surfaces.
// check for wall types which cannot have dynamic lights on them (portal types never get here so they don't need to be checked.)
switch (type)
@ -75,14 +71,10 @@ void GLWall::SetupLights()
Plane p;
lightdata.Clear();
p.Set(&glseg);
/*
if (!p.ValidNormal())
{
return;
}
*/
auto normal = glseg.Normal();
p.Set(normal, -normal.X * glseg.x1 - normal.Y * glseg.y1);
FLightNode *node;
if (seg->sidedef == NULL)
{
@ -403,7 +395,7 @@ void GLWall::RenderTranslucentWall()
{
SetupLights();
}
if (!gltexture->GetTransparent()) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
if (!gltexture->tex->GetTranslucency()) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
else gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
if (RenderStyle == STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA,GL_ONE);
RenderTextured(RWF_TEXTURED | RWF_NOSPLIT);

View file

@ -39,9 +39,7 @@
#include "gl/renderer/gl_renderer.h"
#include "gl/renderer/gl_lightdata.h"
#include "gl/renderer/gl_renderstate.h"
#include "gl/data/gl_data.h"
#include "gl/data/gl_vertexbuffer.h"
#include "gl/dynlights/gl_glow.h"
#include "gl/scene/gl_drawinfo.h"
#include "gl/scene/gl_scenedrawer.h"
#include "gl/models/gl_models.h"
@ -75,7 +73,7 @@ void GLSceneDrawer::DrawPSprite (player_t * player,DPSprite *psp, float sx, floa
// [BB] In the HUD model step we just render the model and break out.
if ( hudModelStep )
{
gl_RenderHUDModel(psp, sx, sy);
gl_RenderHUDModel(psp, sx, sy, weapondynlightindex[psp]);
return;
}
@ -146,7 +144,7 @@ void GLSceneDrawer::DrawPSprite (player_t * player,DPSprite *psp, float sx, floa
}
if (tex->GetTransparent() || OverrideShader != -1)
if (tex->tex->GetTranslucency() || OverrideShader != -1)
{
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
}
@ -176,7 +174,7 @@ static bool isBright(DPSprite *psp)
{
FMaterial * tex = FMaterial::ValidateTexture(lump, false, false);
if (tex)
disablefullbright = tex->tex->gl_info.bDisableFullbright;
disablefullbright = tex->tex->bDisableFullbright;
}
return psp->GetState()->GetFullbright() && !disablefullbright;
}
@ -315,7 +313,7 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
lightlevel = gl_CalcLightLevel(lightlevel, getExtraLight(), true);
if (glset.lightmode == 8 || lightlevel < 92)
if (level.lightmode == 8 || lightlevel < 92)
{
// Korshun: the way based on max possible light level for sector like in software renderer.
float min_L = 36.0 / 31.0 - ((lightlevel / 255.0) * (63.0 / 31.0)); // Lightlevel in range 0-63
@ -330,12 +328,12 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
{
lightlevel = (2 * lightlevel + 255) / 3;
}
lightlevel = gl_CheckSpriteGlow(viewsector, lightlevel, playermo->Pos());
lightlevel = viewsector->CheckSpriteGlow(lightlevel, playermo->Pos());
}
// Korshun: fullbright fog in opengl, render weapon sprites fullbright (but don't cancel out the light color!)
if (glset.brightfog && ((level.flags&LEVEL_HASFADETABLE) || cm.FadeColor != 0))
if (level.brightfog && ((level.flags&LEVEL_HASFADETABLE) || cm.FadeColor != 0))
{
lightlevel = 255;
}
@ -344,8 +342,8 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
// hack alert! Rather than changing everything in the underlying lighting code let's just temporarily change
// light mode here to draw the weapon sprite.
int oldlightmode = glset.lightmode;
if (glset.lightmode == 8) glset.lightmode = 2;
int oldlightmode = level.lightmode;
if (level.lightmode == 8) level.lightmode = 2;
for(DPSprite *psp = player->psprites; psp != nullptr && psp->GetID() < PSP_TARGETCENTER; psp = psp->GetNext())
{
@ -491,7 +489,7 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
gl_RenderState.SetObjectColor(0xffffffff);
gl_RenderState.SetDynLight(0, 0, 0);
gl_RenderState.EnableBrightmap(false);
glset.lightmode = oldlightmode;
level.lightmode = oldlightmode;
}
//==========================================================================

View file

@ -23,7 +23,6 @@
#include "gl/system/gl_system.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"

View file

@ -28,7 +28,6 @@
#include "gl/system/gl_system.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"

View file

@ -28,7 +28,6 @@
#include "gl/system/gl_system.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"

View file

@ -28,7 +28,6 @@
#include "gl/system/gl_system.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"

View file

@ -28,7 +28,6 @@
#include "gl/system/gl_system.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"

View file

@ -23,7 +23,6 @@
#include "gl/system/gl_system.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "w_wad.h"
#include "gl/system/gl_interface.h"
@ -34,6 +33,7 @@
#include "gl/renderer/gl_postprocessstate.h"
#include "gl/renderer/gl_renderbuffers.h"
#include "gl/shaders/gl_postprocessshader.h"
#include "gl/shaders/gl_postprocessshaderinstance.h"
#include "textures/textures.h"
#include "textures/bitmap.h"

View file

@ -1,10 +1,5 @@
#pragma once
#include "gl_shaderprogram.h"
#include <map>
class PostProcessShaderInstance;
enum class PostProcessUniformType
{
Undefined,
@ -35,38 +30,3 @@ struct PostProcessShader
extern TArray<PostProcessShader> PostProcessShaders;
class PostProcessShaderInstance
{
public:
PostProcessShaderInstance(PostProcessShader *desc) : Desc(desc) { }
~PostProcessShaderInstance();
void Run();
PostProcessShader *Desc;
private:
bool IsShaderSupported();
void CompileShader();
void UpdateUniforms();
void BindTextures();
FShaderProgram mProgram;
FBufferedUniformSampler mInputTexture;
std::map<FTexture*, int> mTextureHandles;
};
class FCustomPostProcessShaders
{
public:
FCustomPostProcessShaders();
~FCustomPostProcessShaders();
void Run(FString target);
private:
std::vector<std::unique_ptr<PostProcessShaderInstance>> mShaders;
FCustomPostProcessShaders(const FCustomPostProcessShaders &) = delete;
FCustomPostProcessShaders &operator=(const FCustomPostProcessShaders &) = delete;
};

View file

@ -0,0 +1,42 @@
#pragma once
#include "gl_shaderprogram.h"
#include <map>
struct PostProcessShader;
class PostProcessShaderInstance
{
public:
PostProcessShaderInstance(PostProcessShader *desc) : Desc(desc) { }
~PostProcessShaderInstance();
void Run();
PostProcessShader *Desc;
private:
bool IsShaderSupported();
void CompileShader();
void UpdateUniforms();
void BindTextures();
FShaderProgram mProgram;
FBufferedUniformSampler mInputTexture;
std::map<FTexture*, int> mTextureHandles;
};
class FCustomPostProcessShaders
{
public:
FCustomPostProcessShaders();
~FCustomPostProcessShaders();
void Run(FString target);
private:
std::vector<std::unique_ptr<PostProcessShaderInstance>> mShaders;
FCustomPostProcessShaders(const FCustomPostProcessShaders &) = delete;
FCustomPostProcessShaders &operator=(const FCustomPostProcessShaders &) = delete;
};

View file

@ -30,7 +30,6 @@
#include "gl/system/gl_system.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"

View file

@ -28,7 +28,6 @@
#include "gl/system/gl_system.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"

View file

@ -41,7 +41,6 @@
#include "gl/system/gl_interface.h"
#include "gl/system/gl_debug.h"
#include "gl/data/gl_data.h"
#include "r_data/matrix.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/renderer/gl_renderstate.h"
@ -587,6 +586,7 @@ static const FDefaultShader defaultshaders[]=
{"SpecularBrightmap", "shaders/glsl/func_brightmap.fp", "shaders/glsl/material_specular.fp", "#define SPECULAR\n#define NORMALMAP\n"},
{"PBR","shaders/glsl/func_normal.fp", "shaders/glsl/material_pbr.fp", "#define PBR\n#define NORMALMAP\n"},
{"PBRBrightmap","shaders/glsl/func_brightmap.fp", "shaders/glsl/material_pbr.fp", "#define PBR\n#define NORMALMAP\n"},
{"Paletted", "shaders/glsl/func_paletted.fp", "shaders/glsl/material_nolight.fp", ""},
{"No Texture", "shaders/glsl/func_notexture.fp", "shaders/glsl/material_normal.fp", ""},
{"Basic Fuzz", "shaders/glsl/fuzz_standard.fp", "shaders/glsl/material_normal.fp", ""},
{"Smooth Fuzz", "shaders/glsl/fuzz_smooth.fp", "shaders/glsl/material_normal.fp", ""},
@ -599,7 +599,7 @@ static const FDefaultShader defaultshaders[]=
{nullptr,nullptr,nullptr,nullptr}
};
static TArray<FString> usershaders;
TArray<FString> usershaders;
struct FEffectShader
{
@ -617,6 +617,7 @@ static const FEffectShader effectshaders[]=
{ "spheremap", "shaders/glsl/main.vp", "shaders/glsl/main.fp", "shaders/glsl/func_normal.fp", "shaders/glsl/material_normal.fp", "#define SPHEREMAP\n#define NO_ALPHATEST\n" },
{ "burn", "shaders/glsl/main.vp", "shaders/glsl/burn.fp", nullptr, nullptr, "#define SIMPLE\n#define NO_ALPHATEST\n" },
{ "stencil", "shaders/glsl/main.vp", "shaders/glsl/stencil.fp", nullptr, nullptr, "#define SIMPLE\n#define NO_ALPHATEST\n" },
{ "swrquad", "shaders/glsl/main.vp", "shaders/glsl/swshader.fp", nullptr, nullptr, "#define SIMPLE\n" },
};
FShaderManager::FShaderManager()
@ -872,157 +873,6 @@ void gl_DestroyUserShaders()
// todo
}
//==========================================================================
//
// Parses a shader definition
//
//==========================================================================
void gl_ParseHardwareShader(FScanner &sc, int deflump)
{
sc.MustGetString();
if (sc.Compare("postprocess"))
{
sc.MustGetString();
PostProcessShader shaderdesc;
shaderdesc.Target = sc.String;
shaderdesc.Target.ToLower();
bool validTarget = false;
if (sc.Compare("beforebloom")) validTarget = true;
if (sc.Compare("scene")) validTarget = true;
if (sc.Compare("screen")) validTarget = true;
if (!validTarget)
sc.ScriptError("Invalid target '%s' for postprocess shader",sc.String);
sc.MustGetToken('{');
while (!sc.CheckToken('}'))
{
sc.MustGetString();
if (sc.Compare("shader"))
{
sc.MustGetString();
shaderdesc.ShaderLumpName = sc.String;
sc.MustGetNumber();
shaderdesc.ShaderVersion = sc.Number;
if (sc.Number > 450 || sc.Number < 330)
sc.ScriptError("Shader version must be in range 330 to 450!");
}
else if (sc.Compare("name"))
{
sc.MustGetString();
shaderdesc.Name = sc.String;
}
else if (sc.Compare("uniform"))
{
sc.MustGetString();
FString uniformType = sc.String;
uniformType.ToLower();
sc.MustGetString();
FString uniformName = sc.String;
PostProcessUniformType parsedType = PostProcessUniformType::Undefined;
if (uniformType.Compare("int") == 0)
parsedType = PostProcessUniformType::Int;
else if (uniformType.Compare("float") == 0)
parsedType = PostProcessUniformType::Float;
else if (uniformType.Compare("vec2") == 0)
parsedType = PostProcessUniformType::Vec2;
else if (uniformType.Compare("vec3") == 0)
parsedType = PostProcessUniformType::Vec3;
else
sc.ScriptError("Unrecognized uniform type '%s'", sc.String);
if (parsedType != PostProcessUniformType::Undefined)
shaderdesc.Uniforms[uniformName].Type = parsedType;
}
else if (sc.Compare("texture"))
{
sc.MustGetString();
FString textureName = sc.String;
sc.MustGetString();
FString textureSource = sc.String;
shaderdesc.Textures[textureName] = textureSource;
}
else if (sc.Compare("enabled"))
{
shaderdesc.Enabled = true;
}
else
{
sc.ScriptError("Unknown keyword '%s'", sc.String);
}
}
PostProcessShaders.Push(shaderdesc);
}
else
{
ETextureType type = ETextureType::Any;
if (sc.Compare("texture")) type = ETextureType::Wall;
else if (sc.Compare("flat")) type = ETextureType::Flat;
else if (sc.Compare("sprite")) type = ETextureType::Sprite;
else sc.UnGet();
bool disable_fullbright = false;
bool thiswad = false;
bool iwad = false;
int maplump = -1;
FString maplumpname;
float speed = 1.f;
sc.MustGetString();
FTextureID no = TexMan.CheckForTexture(sc.String, type);
FTexture *tex = TexMan[no];
sc.MustGetToken('{');
while (!sc.CheckToken('}'))
{
sc.MustGetString();
if (sc.Compare("shader"))
{
sc.MustGetString();
maplumpname = sc.String;
}
else if (sc.Compare("speed"))
{
sc.MustGetFloat();
speed = float(sc.Float);
}
}
if (!tex)
{
return;
}
if (maplumpname.IsNotEmpty())
{
if (tex->bWarped != 0)
{
Printf("Cannot combine warping with hardware shader on texture '%s'\n", tex->Name.GetChars());
return;
}
tex->gl_info.shaderspeed = speed;
for (unsigned i = 0; i < usershaders.Size(); i++)
{
if (!usershaders[i].CompareNoCase(maplumpname))
{
tex->gl_info.shaderindex = i + FIRST_USER_SHADER;
return;
}
}
tex->gl_info.shaderindex = usershaders.Push(maplumpname) + FIRST_USER_SHADER;
}
}
}
static bool IsConsolePlayer(player_t *player)
{
AActor *activator = player ? player->mo : nullptr;

View file

@ -200,6 +200,12 @@ public:
{
glUniform4f(mIndex, a, b, c, d);
}
void Set(PalEntry newvalue)
{
glUniform4f(mIndex, newvalue.r / 255.f, newvalue.g / 255.f, newvalue.b / 255.f, newvalue.a / 255.f);
}
};
class FBufferedUniformPE
@ -399,28 +405,6 @@ public:
}
};
enum MaterialShaderIndex
{
SHADER_Default,
SHADER_Warp1,
SHADER_Warp2,
SHADER_Brightmap,
SHADER_Specular,
SHADER_SpecularBrightmap,
SHADER_PBR,
SHADER_PBRBrightmap,
SHADER_NoTexture,
SHADER_BasicFuzz,
SHADER_SmoothFuzz,
SHADER_SwirlyFuzz,
SHADER_TranslucentFuzz,
SHADER_JaggedFuzz,
SHADER_NoiseFuzz,
SHADER_SmoothNoiseFuzz,
SHADER_SoftwareFuzz,
FIRST_USER_SHADER
};
enum
{
LIGHTBUF_BINDINGPOINT = 1

View file

@ -28,7 +28,6 @@
#include "gl/system/gl_system.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_cvars.h"

View file

@ -24,7 +24,6 @@
#include "files.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"

View file

@ -28,7 +28,6 @@
#include "gl/system/gl_system.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"

View file

@ -41,6 +41,10 @@
#include "gl/system/gl_framebuffer.h"
#include "gl/shaders/gl_present3dRowshader.h"
#ifdef _WIN32
#include "hardware.h"
#endif // _WIN32
EXTERN_CVAR(Float, vid_saturation)
EXTERN_CVAR(Float, vid_brightness)
EXTERN_CVAR(Float, vid_contrast)

View file

@ -40,16 +40,13 @@
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/renderer/gl_renderbuffers.h"
#include "gl/renderer/gl_renderstate.h"
#include "gl/renderer/gl_lightdata.h"
#include "gl/data/gl_data.h"
#include "gl/textures/gl_hwtexture.h"
#include "gl/textures/gl_texture.h"
#include "gl/textures/gl_translate.h"
#include "gl/textures/gl_samplers.h"
#include "gl/utility/gl_clock.h"
#include "gl/utility/gl_templates.h"
#include "gl/gl_functions.h"
#include "gl/renderer/gl_2ddrawer.h"
#include "gl/data/gl_vertexbuffer.h"
#include "gl_debug.h"
#include "r_videoscale.h"
@ -98,9 +95,7 @@ OpenGLFrameBuffer::OpenGLFrameBuffer(void *hMonitor, int width, int height, int
mDebug = std::make_shared<FGLDebug>();
mDebug->Update();
gl_SetupMenu();
gl_GenerateGlobalBrightmapFromColormap();
DoSetGamma();
Accel2D = true;
}
OpenGLFrameBuffer::~OpenGLFrameBuffer()
@ -178,7 +173,6 @@ void OpenGLFrameBuffer::Update()
GLRenderer->Flush();
Swap();
Unlock();
CheckBench();
int initialWidth = IsFullscreen() ? VideoWidth : GetClientWidth();
@ -188,7 +182,7 @@ void OpenGLFrameBuffer::Update()
if (clientWidth > 0 && clientHeight > 0 && (Width != clientWidth || Height != clientHeight))
{
// Do not call Resize here because it's only for software canvases
Pitch = Width = clientWidth;
Width = clientWidth;
Height = clientHeight;
V_OutputResized(Width, Height);
GLRenderer->mVBO->OutputResized(Width, Height);
@ -197,6 +191,91 @@ void OpenGLFrameBuffer::Update()
GLRenderer->SetOutputViewport(nullptr);
}
//===========================================================================
//
//
//
//===========================================================================
void OpenGLFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV)
{
if (!V_IsHardwareRenderer())
{
Super::RenderTextureView(tex, Viewpoint, FOV);
}
else if (GLRenderer != nullptr)
{
GLRenderer->RenderTextureView(tex, Viewpoint, FOV);
camtexcount++;
}
}
//===========================================================================
//
// Render the view to a savegame picture
//
//===========================================================================
void OpenGLFrameBuffer::WriteSavePic(player_t *player, FileWriter *file, int width, int height)
{
if (!V_IsHardwareRenderer())
Super::WriteSavePic(player, file, width, height);
if (GLRenderer != nullptr)
GLRenderer->WriteSavePic(player, file, width, height);
}
//===========================================================================
//
//
//
//===========================================================================
void OpenGLFrameBuffer::RenderView(player_t *player)
{
if (GLRenderer != nullptr)
GLRenderer->RenderView(player);
}
//===========================================================================
//
//
//
//===========================================================================
EXTERN_CVAR(Bool, r_drawvoxels)
EXTERN_CVAR(Int, gl_tonemap)
uint32_t OpenGLFrameBuffer::GetCaps()
{
if (!V_IsHardwareRenderer())
return Super::GetCaps();
// describe our basic feature set
ActorRenderFeatureFlags FlagSet = RFF_FLATSPRITES | RFF_MODELS | RFF_SLOPE3DFLOORS |
RFF_TILTPITCH | RFF_ROLLSPRITES | RFF_POLYGONAL;
if (r_drawvoxels)
FlagSet |= RFF_VOXELS;
if (gl.legacyMode)
{
// legacy mode always has truecolor because palette tonemap is not available
FlagSet |= RFF_TRUECOLOR;
}
else if (!(FGLRenderBuffers::IsEnabled()))
{
// truecolor is always available when renderbuffers are unavailable because palette tonemap is not possible
FlagSet |= RFF_TRUECOLOR | RFF_MATSHADER | RFF_BRIGHTMAP;
}
else
{
if (gl_tonemap != 5) // not running palette tonemap shader
FlagSet |= RFF_TRUECOLOR;
FlagSet |= RFF_MATSHADER | RFF_POSTSHADER | RFF_BRIGHTMAP;
}
return (uint32_t)FlagSet;
}
//==========================================================================
//
@ -205,7 +284,6 @@ void OpenGLFrameBuffer::Update()
//==========================================================================
CVAR(Bool, gl_finishbeforeswap, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
extern int camtexcount;
void OpenGLFrameBuffer::Swap()
{
@ -308,6 +386,17 @@ bool OpenGLFrameBuffer::SetContrast(float contrast)
//
//===========================================================================
void OpenGLFrameBuffer::CleanForRestart()
{
if (GLRenderer)
GLRenderer->ResetSWScene();
}
void OpenGLFrameBuffer::SetTextureFilterMode()
{
if (GLRenderer != nullptr && GLRenderer->mSamplerManager != nullptr) GLRenderer->mSamplerManager->SetTextureFilterMode();
}
void OpenGLFrameBuffer::UpdatePalette()
{
if (GLRenderer)
@ -337,25 +426,29 @@ void OpenGLFrameBuffer::GetFlash(PalEntry &rgb, int &amount)
amount = Flash.a;
}
int OpenGLFrameBuffer::GetPageCount()
void OpenGLFrameBuffer::InitForLevel()
{
return 1;
if (GLRenderer != NULL)
{
GLRenderer->SetupLevel();
}
}
//===========================================================================
//
//
//
//===========================================================================
//==========================================================================
//
// DFrameBuffer :: CreatePalette
//
// Creates a native palette from a remap table, if supported.
//
//==========================================================================
FNativePalette *OpenGLFrameBuffer::CreatePalette(FRemapTable *remap)
void OpenGLFrameBuffer::SetClearColor(int color)
{
return GLTranslationPalette::CreatePalette(remap);
PalEntry pe = GPalette.BaseColors[color];
GLRenderer->mSceneClearColor[0] = pe.r / 255.f;
GLRenderer->mSceneClearColor[1] = pe.g / 255.f;
GLRenderer->mSceneClearColor[2] = pe.b / 255.f;
}
//==========================================================================
//
//
@ -386,100 +479,6 @@ bool OpenGLFrameBuffer::Begin2D(bool copy3d)
return true;
}
//==========================================================================
//
// Draws a texture
//
//==========================================================================
void OpenGLFrameBuffer::DrawTextureParms(FTexture *img, DrawParms &parms)
{
if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr)
GLRenderer->m2DDrawer->AddTexture(img, parms);
}
//==========================================================================
//
//
//
//==========================================================================
void OpenGLFrameBuffer::DrawLine(int x1, int y1, int x2, int y2, int palcolor, uint32_t color)
{
if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr)
GLRenderer->m2DDrawer->AddLine(x1, y1, x2, y2, palcolor, color);
}
//==========================================================================
//
//
//
//==========================================================================
void OpenGLFrameBuffer::DrawPixel(int x1, int y1, int palcolor, uint32_t color)
{
if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr)
GLRenderer->m2DDrawer->AddPixel(x1, y1, palcolor, color);
}
//==========================================================================
//
//
//
//==========================================================================
void OpenGLFrameBuffer::Dim(PalEntry)
{
// Unlike in the software renderer the color is being ignored here because
// view blending only affects the actual view with the GL renderer.
Super::Dim(0);
}
void OpenGLFrameBuffer::DoDim(PalEntry color, float damount, int x1, int y1, int w, int h)
{
if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr)
GLRenderer->m2DDrawer->AddDim(color, damount, x1, y1, w, h);
}
//==========================================================================
//
//
//
//==========================================================================
void OpenGLFrameBuffer::FlatFill (int left, int top, int right, int bottom, FTexture *src, bool local_origin)
{
if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr)
GLRenderer->m2DDrawer->AddFlatFill(left, top, right, bottom, src, local_origin);
}
//==========================================================================
//
//
//
//==========================================================================
void OpenGLFrameBuffer::DoClear(int left, int top, int right, int bottom, int palcolor, uint32_t color)
{
if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr)
GLRenderer->m2DDrawer->AddClear(left, top, right, bottom, palcolor, color);
}
//==========================================================================
//
// D3DFB :: FillSimplePoly
//
// Here, "simple" means that a simple triangle fan can draw it.
//
//==========================================================================
void OpenGLFrameBuffer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoints,
double originx, double originy, double scalex, double scaley,
DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip)
{
if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr && npoints >= 3)
{
GLRenderer->m2DDrawer->AddPoly(texture, points, npoints, originx, originy, scalex, scaley, rotation, colormap, flatcolor, lightlevel);
}
}
//===========================================================================
//
// Takes a screenshot
@ -550,7 +549,6 @@ void OpenGLFrameBuffer::GameRestart()
memcpy (SourcePalette, GPalette.BaseColors, sizeof(PalEntry)*256);
UpdatePalette ();
ScreenshotBuffer = NULL;
gl_GenerateGlobalBrightmapFromColormap();
GLRenderer->GetSpecialTextures();
}
@ -569,3 +567,14 @@ void OpenGLFrameBuffer::ScaleCoordsFromWindow(int16_t &x, int16_t &y)
x = int16_t((x - letterboxX) * Width / letterboxWidth);
y = int16_t((y - letterboxY) * Height / letterboxHeight);
}
//===========================================================================
//
// 2D drawing
//
//===========================================================================
void OpenGLFrameBuffer::Draw2D()
{
if (GLRenderer != nullptr) GLRenderer->Draw2D(&m2DDrawer);
}

View file

@ -1,10 +1,7 @@
#ifndef __GL_FRAMEBUFFER
#define __GL_FRAMEBUFFER
#ifdef _WIN32
#include "win32iface.h"
#include "win32gliface.h"
#endif
#include "gl_sysfb.h"
#include <memory>
@ -12,17 +9,9 @@ class FHardwareTexture;
class FSimpleVertexBuffer;
class FGLDebug;
#ifdef _WIN32
class OpenGLFrameBuffer : public Win32GLFrameBuffer
class OpenGLFrameBuffer : public SystemFrameBuffer
{
typedef Win32GLFrameBuffer Super;
#else
#include "sdlglvideo.h"
class OpenGLFrameBuffer : public SDLGLFB
{
typedef SDLGLFB Super; //[C]commented, DECLARE_CLASS defines this in linux
#endif
typedef SystemFrameBuffer Super;
public:
@ -39,14 +28,21 @@ public:
bool SetContrast(float contrast);
void DoSetGamma();
void UpdatePalette();
void GetFlashedPalette (PalEntry pal[256]);
PalEntry *GetPalette ();
bool SetFlash(PalEntry rgb, int amount);
void GetFlash(PalEntry &rgb, int &amount);
int GetPageCount();
bool Begin2D(bool copy3d);
void GameRestart();
void CleanForRestart() override;
void UpdatePalette() override;
void GetFlashedPalette (PalEntry pal[256]) override;
PalEntry *GetPalette () override;
bool SetFlash(PalEntry rgb, int amount) override;
void GetFlash(PalEntry &rgb, int &amount) override;
bool Begin2D(bool copy3d) override;
void GameRestart() override;
void InitForLevel() override;
void SetClearColor(int color) override;
uint32_t GetCaps() override;
void RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV) override;
void WriteSavePic(player_t *player, FileWriter *file, int width, int height) override;
void RenderView(player_t *player) override;
void SetTextureFilterMode() override;
// Retrieves a buffer containing image data for a screenshot.
// Hint: Pitch can be negative for upside-down images, in which case buffer
@ -56,32 +52,17 @@ public:
// Releases the screenshot buffer.
virtual void ReleaseScreenshotBuffer();
// 2D drawing
void DrawTextureParms(FTexture *img, DrawParms &parms);
void DrawLine(int x1, int y1, int x2, int y2, int palcolor, uint32_t color);
void DrawPixel(int x1, int y1, int palcolor, uint32_t color);
void DoClear(int left, int top, int right, int bottom, int palcolor, uint32_t color);
void Dim(PalEntry color=0);
void DoDim (PalEntry color, float damount, int x1, int y1, int w, int h);
void FlatFill (int left, int top, int right, int bottom, FTexture *src, bool local_origin=false);
void FillSimplePoly(FTexture *tex, FVector2 *points, int npoints,
double originx, double originy, double scalex, double scaley,
DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip);
FNativePalette *CreatePalette(FRemapTable *remap);
bool WipeStartScreen(int type);
void WipeEndScreen();
bool WipeDo(int ticks);
void WipeCleanup();
void Swap();
bool Is8BitMode() { return false; }
bool IsHWGammaActive() const { return HWGammaActive; }
void SetVSync(bool vsync);
void ScaleCoordsFromWindow(int16_t &x, int16_t &y) override;
void Draw2D() override;
bool HWGammaActive = false; // Are we using hardware or software gamma?
std::shared_ptr<FGLDebug> mDebug; // Debug API
@ -89,6 +70,7 @@ private:
PalEntry Flash; // Only needed to support some cruft in the interface that only makes sense for the software renderer
PalEntry SourcePalette[256]; // This is where unpaletted textures get their palette from
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
{

View file

@ -43,10 +43,6 @@ static TArray<FString> m_Extensions;
RenderContext gl;
static double realglversion; // this is public so the statistics code can access it.
EXTERN_CVAR(Bool, gl_legacy_mode)
extern int currentrenderer;
CVAR(Bool, gl_riskymodernpath, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
//==========================================================================
//
//
@ -211,11 +207,7 @@ void gl_LoadExtensions()
// The minimum requirement for the modern render path is GL 3.3.
// Although some GL 3.1 or 3.2 solutions may theoretically work they are usually too broken or too slow.
// unless, of course, we're simply using this as a software backend...
float minmodernpath = 3.3f;
if (gl_riskymodernpath)
minmodernpath = 3.1f;
if ((gl_version < minmodernpath && (currentrenderer==1)) || gl_version < 3.0f)
if (gl_version < 3.3f)
{
gl.legacyMode = true;
gl.lightmethod = LM_LEGACY;
@ -327,7 +319,6 @@ void gl_LoadExtensions()
UCVarValue value;
value.Bool = gl.legacyMode;
gl_legacy_mode.ForceSet (value, CVAR_Bool);
}
//==========================================================================
@ -373,18 +364,6 @@ void gl_PrintStartupLog()
glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &v);
Printf("Max. vertex shader storage blocks: %d\n", v);
}
// For shader-less, the special alphatexture translation must be changed to actually set the alpha, because it won't get translated by a shader.
if (gl.legacyMode)
{
FRemapTable *remap = translationtables[TRANSLATION_Standard][8];
for (int i = 0; i < 256; i++)
{
remap->Remap[i] = i;
remap->Palette[i] = PalEntry(i, 255, 255, 255);
}
}
}
std::pair<double, bool> gl_getInfo()

View file

@ -29,14 +29,14 @@ enum RenderFlags
enum TexMode
{
TM_SWCANVAS = -1, // special case for the legacy renderer, do not use for anything but the SW renderer's canvas.
TM_MODULATE = 0, // (r, g, b, a)
TM_MASK, // (1, 1, 1, a)
TM_OPAQUE, // (r, g, b, 1)
TM_INVERSE, // (1-r, 1-g, 1-b, a)
TM_REDTOALPHA, // (1, 1, 1, r)
TM_CLAMPY, // (r, g, b, (t >= 0.0 && t <= 1.0)? a:0)
TM_INVERTOPAQUE, // used by GL 2.x fallback code.
TM_INVERTOPAQUE, // (1-r, 1-g, 1-b, 1)
};
enum ELightMethod

File diff suppressed because it is too large Load diff

View file

@ -1,507 +0,0 @@
#ifndef __GL_SWFRAMEBUFFER
#define __GL_SWFRAMEBUFFER
#ifdef _WIN32
#include "win32iface.h"
#include "win32gliface.h"
#endif
#include "SkylineBinPack.h"
#include "textures.h"
#include <memory>
class FGLDebug;
#ifdef _WIN32
class OpenGLSWFrameBuffer : public Win32GLFrameBuffer
{
typedef Win32GLFrameBuffer Super;
#else
#include "sdlglvideo.h"
class OpenGLSWFrameBuffer : public SDLGLFB
{
typedef SDLGLFB Super; //[C]commented, DECLARE_CLASS defines this in linux
#endif
public:
explicit OpenGLSWFrameBuffer() {}
OpenGLSWFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen, bool bgra);
~OpenGLSWFrameBuffer();
bool IsValid() override;
bool Lock(bool buffered) override;
void Unlock() override;
void Update() override;
PalEntry *GetPalette() override;
void GetFlashedPalette(PalEntry palette[256]) override;
void UpdatePalette() override;
bool SetGamma(float gamma) override;
bool SetFlash(PalEntry rgb, int amount) override;
void GetFlash(PalEntry &rgb, int &amount) override;
int GetPageCount() override;
void SetVSync(bool vsync) override;
void NewRefreshRate() override;
void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma) override;
void ReleaseScreenshotBuffer() override;
void SetBlendingRect(int x1, int y1, int x2, int y2) override;
bool Begin2D(bool copy3d) override;
void DrawBlendingRect() override;
FNativeTexture *CreateTexture(FTexture *gametex, FTextureFormat fmt, bool wrapping) override;
FNativePalette *CreatePalette(FRemapTable *remap) override;
void DrawTextureParms(FTexture *img, DrawParms &parms) override;
void DoClear(int left, int top, int right, int bottom, int palcolor, uint32_t color) override;
void DoDim(PalEntry color, float amount, int x1, int y1, int w, int h) override;
void FlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin) override;
void DrawLine(int x0, int y0, int x1, int y1, int palColor, uint32_t realcolor) override;
void DrawPixel(int x, int y, int palcolor, uint32_t rgbcolor) override;
void FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip) override;
bool WipeStartScreen(int type) override;
void WipeEndScreen() override;
bool WipeDo(int ticks) override;
void WipeCleanup() override;
#ifdef WIN32
void PaletteChanged() override { }
int QueryNewPalette() override { return 0; }
void Blank() override { }
bool PaintToWindow() override;
bool Is8BitMode() override { return false; }
int GetTrueHeight() override { return TrueHeight; }
#endif
void ScaleCoordsFromWindow(int16_t &x, int16_t &y) override;
private:
struct FBVERTEX
{
float x, y, z, rhw;
uint32_t color0, color1;
float tu, tv;
};
struct BURNVERTEX
{
float x, y, z, rhw;
float tu0, tv0;
float tu1, tv1;
};
enum
{
PSCONST_Desaturation,
PSCONST_PaletteMod,
PSCONST_Weights,
PSCONST_Gamma,
PSCONST_ScreenSize,
NumPSCONST
};
struct GammaRamp
{
uint16_t red[256], green[256], blue[256];
};
struct LTRBRect
{
int left, top, right, bottom;
};
class HWTexture
{
public:
HWTexture() { Buffers[0] = 0; Buffers[1] = 0; }
~HWTexture();
int Texture = 0;
int Buffers[2];
int CurrentBuffer = 0;
int WrapS = 0;
int WrapT = 0;
int Format = 0;
std::vector<uint8_t> MapBuffer;
};
class HWFrameBuffer
{
public:
~HWFrameBuffer();
int Framebuffer = 0;
std::unique_ptr<HWTexture> Texture;
};
class HWVertexBuffer
{
public:
~HWVertexBuffer();
FBVERTEX *Lock();
void Unlock();
int VertexArray = 0;
int Buffer = 0;
int Size = 0;
};
class HWIndexBuffer
{
public:
~HWIndexBuffer();
uint16_t *Lock();
void Unlock();
int Buffer = 0;
int Size = 0;
private:
int LockedOldBinding = 0;
};
class HWPixelShader
{
public:
~HWPixelShader();
int Program = 0;
int VertexShader = 0;
int FragmentShader = 0;
int ConstantLocations[NumPSCONST];
int ImageLocation = -1;
int PaletteLocation = -1;
int NewScreenLocation = -1;
int BurnLocation = -1;
};
std::unique_ptr<HWFrameBuffer> CreateFrameBuffer(const FString &name, int width, int height);
std::unique_ptr<HWPixelShader> CreatePixelShader(FString vertexsrc, FString fragmentsrc, const FString &defines);
std::unique_ptr<HWVertexBuffer> CreateVertexBuffer(int size);
std::unique_ptr<HWIndexBuffer> CreateIndexBuffer(int size);
std::unique_ptr<HWTexture> CreateTexture(const FString &name, int width, int height, int levels, int format);
void SetGammaRamp(const GammaRamp *ramp);
void SetPixelShaderConstantF(int uniformIndex, const float *data, int vec4fcount);
void SetHWPixelShader(HWPixelShader *shader);
void SetStreamSource(HWVertexBuffer *vertexBuffer);
void SetIndices(HWIndexBuffer *indexBuffer);
void DrawTriangleFans(int count, const FBVERTEX *vertices);
void DrawTriangleFans(int count, const BURNVERTEX *vertices);
void DrawPoints(int count, const FBVERTEX *vertices);
void DrawLineList(int count);
void DrawTriangleList(int minIndex, int numVertices, int startIndex, int primitiveCount);
void Present();
void GetLetterboxFrame(int &x, int &y, int &width, int &height);
static void BgraToRgba(uint32_t *dest, const uint32_t *src, int width, int height, int srcpitch);
void BindFBBuffer();
void *MappedMemBuffer = nullptr;
bool UseMappedMemBuffer = true;
static uint32_t ColorARGB(uint32_t a, uint32_t r, uint32_t g, uint32_t b) { return ((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | ((b) & 0xff); }
static uint32_t ColorRGBA(uint32_t r, uint32_t g, uint32_t b, uint32_t a) { return ColorARGB(a, r, g, b); }
static uint32_t ColorXRGB(uint32_t r, uint32_t g, uint32_t b) { return ColorARGB(0xff, r, g, b); }
static uint32_t ColorValue(float r, float g, float b, float a) { return ColorRGBA((uint32_t)(r * 255.0f), (uint32_t)(g * 255.0f), (uint32_t)(b * 255.0f), (uint32_t)(a * 255.0f)); }
static void *MapBuffer(int target, int size);
// The number of points for the vertex buffer.
enum { NUM_VERTS = 10240 };
// The number of indices for the index buffer.
enum { NUM_INDEXES = ((NUM_VERTS * 6) / 4) };
// The number of quads we can batch together.
enum { MAX_QUAD_BATCH = (NUM_INDEXES / 6) };
// The default size for a texture atlas.
enum { DEF_ATLAS_WIDTH = 512 };
enum { DEF_ATLAS_HEIGHT = 512 };
// TYPES -------------------------------------------------------------------
struct Atlas;
struct PackedTexture
{
Atlas *Owner;
PackedTexture **Prev, *Next;
// Pixels this image covers
LTRBRect Area;
// Texture coordinates for this image
float Left, Top, Right, Bottom;
// Texture has extra space on the border?
bool Padded;
};
struct Atlas
{
Atlas(OpenGLSWFrameBuffer *fb, int width, int height, int format);
~Atlas();
PackedTexture *AllocateImage(const Rect &rect, bool padded);
void FreeBox(PackedTexture *box);
SkylineBinPack Packer;
Atlas *Next;
std::unique_ptr<HWTexture> Tex;
int Format;
PackedTexture *UsedList; // Boxes that contain images
int Width, Height;
bool OneUse;
};
class OpenGLTex : public FNativeTexture
{
public:
OpenGLTex(FTexture *tex, FTextureFormat fmt, OpenGLSWFrameBuffer *fb, bool wrapping);
~OpenGLTex();
FTexture *GameTex;
PackedTexture *Box;
OpenGLTex **Prev;
OpenGLTex *Next;
bool IsGray;
bool Create(OpenGLSWFrameBuffer *fb, bool wrapping);
bool Update();
bool CheckWrapping(bool wrapping);
int GetTexFormat();
};
class OpenGLPal : public FNativePalette
{
public:
OpenGLPal(FRemapTable *remap, OpenGLSWFrameBuffer *fb);
~OpenGLPal();
OpenGLPal **Prev;
OpenGLPal *Next;
std::unique_ptr<HWTexture> Tex;
uint32_t BorderColor;
bool DoColorSkip;
bool Update();
FRemapTable *Remap;
int RoundedPaletteSize;
};
// Flags for a buffered quad
enum
{
BQF_GamePalette = 1,
BQF_CustomPalette = 7,
BQF_Paletted = 7,
BQF_Bilinear = 8,
BQF_WrapUV = 16,
BQF_InvertSource = 32,
BQF_DisableAlphaTest = 64,
BQF_Desaturated = 128,
};
// Shaders for a buffered quad
enum
{
BQS_PalTex,
BQS_Plain,
BQS_RedToAlpha,
BQS_ColorOnly,
BQS_SpecialColormap,
BQS_InGameColormap,
};
struct BufferedTris
{
uint8_t Flags;
uint8_t ShaderNum;
int BlendOp;
int SrcBlend;
int DestBlend;
uint8_t Desat;
OpenGLPal *Palette;
HWTexture *Texture;
uint16_t NumVerts; // Number of _unique_ vertices used by this set.
uint16_t NumTris; // Number of triangles used by this set.
void ClearSetup()
{
Flags = 0;
ShaderNum = 0;
BlendOp = 0;
SrcBlend = 0;
DestBlend = 0;
}
bool IsSameSetup(const BufferedTris &other) const
{
return Flags == other.Flags && ShaderNum == other.ShaderNum && BlendOp == other.BlendOp && SrcBlend == other.SrcBlend && DestBlend == other.DestBlend;
}
};
enum
{
SHADER_NormalColor,
SHADER_NormalColorPal,
SHADER_NormalColorInv,
SHADER_NormalColorPalInv,
SHADER_RedToAlpha,
SHADER_RedToAlphaInv,
SHADER_VertexColor,
SHADER_SpecialColormap,
SHADER_SpecialColormapPal,
SHADER_InGameColormap,
SHADER_InGameColormapDesat,
SHADER_InGameColormapInv,
SHADER_InGameColormapInvDesat,
SHADER_InGameColormapPal,
SHADER_InGameColormapPalDesat,
SHADER_InGameColormapPalInv,
SHADER_InGameColormapPalInvDesat,
SHADER_BurnWipe,
SHADER_GammaCorrection,
NUM_SHADERS
};
static const char *const ShaderDefines[NUM_SHADERS];
void Flip();
void SetInitialState();
bool CreateResources();
void ReleaseResources();
bool LoadShaders();
bool CreateFBTexture();
bool CreatePaletteTexture();
bool CreateVertexes();
void UploadPalette();
void CalcFullscreenCoords(FBVERTEX verts[4], bool viewarea_only, uint32_t color0, uint32_t color1) const;
bool Reset();
std::unique_ptr<HWTexture> CopyCurrentScreen();
void ReleaseDefaultPoolItems();
void KillNativePals();
void KillNativeTexs();
PackedTexture *AllocPackedTexture(int width, int height, bool wrapping, int format);
void DrawPackedTextures(int packnum);
void DrawLetterbox(int x, int y, int width, int height);
void Draw3DPart(bool copy3d);
bool SetStyle(OpenGLTex *tex, DrawParms &parms, uint32_t &color0, uint32_t &color1, BufferedTris &quad);
static int GetStyleAlpha(int type);
static void SetColorOverlay(uint32_t color, float alpha, uint32_t &color0, uint32_t &color1);
void AddColorOnlyQuad(int left, int top, int width, int height, uint32_t color);
void AddColorOnlyRect(int left, int top, int width, int height, uint32_t color);
void CheckQuadBatch(int numtris = 2, int numverts = 4);
void BeginQuadBatch();
void EndQuadBatch();
void BeginLineBatch();
void EndLineBatch();
void EndBatch();
// State
void EnableAlphaTest(bool enabled);
void SetAlphaBlend(int op, int srcblend = 0, int destblend = 0);
void SetConstant(int cnum, float r, float g, float b, float a);
void SetPixelShader(HWPixelShader *shader);
void SetTexture(int tnum, HWTexture *texture);
void SetSamplerWrapS(int tnum, int mode);
void SetSamplerWrapT(int tnum, int mode);
void SetPaletteTexture(HWTexture *texture, int count, uint32_t border_color);
bool Valid = false;
std::shared_ptr<FGLDebug> Debug;
std::unique_ptr<HWVertexBuffer> StreamVertexBuffer, StreamVertexBufferBurn;
float ShaderConstants[NumPSCONST * 4];
HWPixelShader *CurrentShader = nullptr;
std::unique_ptr<HWFrameBuffer> OutputFB;
bool AlphaTestEnabled = false;
bool AlphaBlendEnabled = false;
int AlphaBlendOp = 0;
int AlphaSrcBlend = 0;
int AlphaDestBlend = 0;
float Constant[3][4];
uint32_t CurBorderColor;
HWPixelShader *CurPixelShader;
HWTexture *Texture[5];
int SamplerWrapS[5], SamplerWrapT[5];
PalEntry SourcePalette[256];
uint32_t BorderColor;
uint32_t FlashColor0, FlashColor1;
PalEntry FlashColor;
int FlashAmount;
int TrueHeight;
int PixelDoubling;
float Gamma;
#ifdef _WIN32
bool UpdatePending;
#endif // _WIN32
bool NeedPalUpdate;
bool NeedGammaUpdate;
LTRBRect BlendingRect;
int In2D;
bool InScene;
bool GatheringWipeScreen;
bool AALines;
uint8_t BlockNum;
OpenGLPal *Palettes = nullptr;
OpenGLTex *Textures = nullptr;
Atlas *Atlases = nullptr;
std::unique_ptr<HWTexture> FBTexture;
std::unique_ptr<HWTexture> PaletteTexture;
std::unique_ptr<HWTexture> ScreenshotTexture;
std::unique_ptr<HWVertexBuffer> VertexBuffer;
FBVERTEX *VertexData = nullptr;
std::unique_ptr<HWIndexBuffer> IndexBuffer;
uint16_t *IndexData = nullptr;
BufferedTris *QuadExtra = nullptr;
int VertexPos;
int IndexPos;
int QuadBatchPos;
enum { BATCH_None, BATCH_Quads, BATCH_Lines } BatchType;
std::unique_ptr<HWPixelShader> Shaders[NUM_SHADERS];
std::unique_ptr<HWTexture> InitialWipeScreen, FinalWipeScreen;
class Wiper
{
public:
virtual ~Wiper();
virtual bool Run(int ticks, OpenGLSWFrameBuffer *fb) = 0;
void DrawScreen(OpenGLSWFrameBuffer *fb, HWTexture *tex, int blendop = 0, uint32_t color0 = 0, uint32_t color1 = 0xFFFFFFF);
};
class Wiper_Melt; friend class Wiper_Melt;
class Wiper_Burn; friend class Wiper_Burn;
class Wiper_Crossfade; friend class Wiper_Crossfade;
Wiper *ScreenWipe;
};
#endif //__GL_SWFRAMEBUFFER

View file

@ -1,587 +0,0 @@
/*
** gl_swwipe.cpp
** Implements the different screen wipes using OpenGL calls.
**
**---------------------------------------------------------------------------
** Copyright 1998-2008 Randy Heit
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/
// HEADER FILES ------------------------------------------------------------
#include "gl/system/gl_system.h"
#include "m_swap.h"
#include "v_video.h"
#include "doomstat.h"
#include "m_png.h"
#include "m_crc32.h"
#include "vectors.h"
#include "v_palette.h"
#include "templates.h"
#include "c_dispatch.h"
#include "templates.h"
#include "i_system.h"
#include "i_video.h"
#include "v_pfx.h"
#include "stats.h"
#include "doomerrors.h"
#include "r_data/r_translate.h"
#include "f_wipe.h"
#include "sbar.h"
#include "w_wad.h"
#include "r_data/colormaps.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_swframebuffer.h"
#include "gl/data/gl_data.h"
#include "gl/utility/gl_clock.h"
#include "gl/utility/gl_templates.h"
#include "gl/gl_functions.h"
#include "gl_debug.h"
#include "m_random.h"
class OpenGLSWFrameBuffer::Wiper_Crossfade : public OpenGLSWFrameBuffer::Wiper
{
public:
Wiper_Crossfade();
bool Run(int ticks, OpenGLSWFrameBuffer *fb);
private:
int Clock;
};
class OpenGLSWFrameBuffer::Wiper_Melt : public OpenGLSWFrameBuffer::Wiper
{
public:
Wiper_Melt();
bool Run(int ticks, OpenGLSWFrameBuffer *fb);
private:
// Match the strip sizes that oldschool Doom used.
static const int WIDTH = 160, HEIGHT = 200;
int y[WIDTH];
};
class OpenGLSWFrameBuffer::Wiper_Burn : public OpenGLSWFrameBuffer::Wiper
{
public:
Wiper_Burn(OpenGLSWFrameBuffer *fb);
~Wiper_Burn();
bool Run(int ticks, OpenGLSWFrameBuffer *fb);
private:
static const int WIDTH = 64, HEIGHT = 64;
uint8_t BurnArray[WIDTH * (HEIGHT + 5)];
std::unique_ptr<HWTexture> BurnTexture;
int Density;
int BurnTime;
};
//==========================================================================
//
// OpenGLSWFrameBuffer :: WipeStartScreen
//
// Called before the current screen has started rendering. This needs to
// save what was drawn the previous frame so that it can be animated into
// what gets drawn this frame.
//
// In fullscreen mode, we use GetFrontBufferData() to grab the data that
// is visible on screen right now.
//
// In windowed mode, we can't do that because we'll get the whole desktop.
// Instead, we can conveniently use the TempRenderTexture, which is normally
// used for gamma-correcting copying the image to the back buffer.
//
//==========================================================================
bool OpenGLSWFrameBuffer::WipeStartScreen(int type)
{
if (!Accel2D)
{
return Super::WipeStartScreen(type);
}
switch (type)
{
case wipe_Melt:
ScreenWipe = new Wiper_Melt;
break;
case wipe_Burn:
ScreenWipe = new Wiper_Burn(this);
break;
case wipe_Fade:
ScreenWipe = new Wiper_Crossfade;
break;
default:
return false;
}
InitialWipeScreen = CopyCurrentScreen();
// Make even fullscreen model render to the TempRenderTexture, so
// we can have a copy of the new screen readily available.
GatheringWipeScreen = true;
return true;
}
//==========================================================================
//
// OpenGLSWFrameBuffer :: WipeEndScreen
//
// The screen we want to animate to has just been drawn. This function is
// called in place of Update(), so it has not been Presented yet.
//
//==========================================================================
void OpenGLSWFrameBuffer::WipeEndScreen()
{
if (!Accel2D)
{
Super::WipeEndScreen();
return;
}
// Don't do anything if there is no starting point.
if (InitialWipeScreen == NULL)
{
return;
}
// If the whole screen was drawn without 2D accel, get it in to
// video memory now.
if (!In2D)
{
Begin2D(true);
}
EndBatch(); // Make sure all batched primitives have been drawn.
FinalWipeScreen = CopyCurrentScreen();
// At this point, InitialWipeScreen holds the screen we are wiping from.
// FinalWipeScreen holds the screen we are wiping to, which may be the
// same texture as TempRenderTexture.
}
//==========================================================================
//
// OpenGLSWFrameBuffer :: WipeDo
//
// Perform the actual wipe animation. The number of tics since the last
// time this function was called is passed in. Returns true when the wipe
// is over. The first time this function has been called, the screen is
// still locked from before and EndScene() still has not been called.
// Successive times need to call BeginScene().
//
//==========================================================================
bool OpenGLSWFrameBuffer::WipeDo(int ticks)
{
if (!Accel2D)
{
return Super::WipeDo(ticks);
}
// Sanity checks.
if (InitialWipeScreen == NULL || FinalWipeScreen == NULL)
{
return true;
}
if (GatheringWipeScreen)
{ // This is the first time we've been called for this wipe.
GatheringWipeScreen = false;
}
else
{ // This is the second or later time we've been called for this wipe.
InScene = true;
}
In2D = 3;
EnableAlphaTest(false);
bool done = ScreenWipe->Run(ticks, this);
return done;
}
//==========================================================================
//
// OpenGLSWFrameBuffer :: WipeCleanup
//
// Release any resources that were specifically created for the wipe.
//
//==========================================================================
void OpenGLSWFrameBuffer::WipeCleanup()
{
if (ScreenWipe != NULL)
{
delete ScreenWipe;
ScreenWipe = NULL;
}
InitialWipeScreen.reset();
FinalWipeScreen.reset();
GatheringWipeScreen = false;
if (!Accel2D)
{
Super::WipeCleanup();
return;
}
}
//==========================================================================
//
// OpenGLSWFrameBuffer :: Wiper Constructor
//
//==========================================================================
OpenGLSWFrameBuffer::Wiper::~Wiper()
{
}
//==========================================================================
//
// OpenGLSWFrameBuffer :: Wiper :: DrawScreen
//
// Draw either the initial or target screen completely to the screen.
//
//==========================================================================
void OpenGLSWFrameBuffer::Wiper::DrawScreen(OpenGLSWFrameBuffer *fb, HWTexture *tex,
int blendop, uint32_t color0, uint32_t color1)
{
FBVERTEX verts[4];
fb->CalcFullscreenCoords(verts, false, color0, color1);
fb->SetTexture(0, tex);
fb->SetAlphaBlend(blendop, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
fb->SetPixelShader(fb->Shaders[SHADER_NormalColor].get());
fb->DrawTriangleFans(2, verts);
}
// WIPE: CROSSFADE ---------------------------------------------------------
//==========================================================================
//
// OpenGLSWFrameBuffer :: Wiper_Crossfade Constructor
//
//==========================================================================
OpenGLSWFrameBuffer::Wiper_Crossfade::Wiper_Crossfade()
: Clock(0)
{
}
//==========================================================================
//
// OpenGLSWFrameBuffer :: Wiper_Crossfade :: Run
//
// Fades the old screen into the new one over 32 ticks.
//
//==========================================================================
bool OpenGLSWFrameBuffer::Wiper_Crossfade::Run(int ticks, OpenGLSWFrameBuffer *fb)
{
Clock += ticks;
// Put the initial screen back to the buffer.
DrawScreen(fb, fb->InitialWipeScreen.get());
// Draw the new screen on top of it.
DrawScreen(fb, fb->FinalWipeScreen.get(), GL_FUNC_ADD, ColorValue(0,0,0,Clock / 32.f), ColorRGBA(255,255,255,0));
return Clock >= 32;
}
// WIPE: MELT --------------------------------------------------------------
//==========================================================================
//
// OpenGLSWFrameBuffer :: Wiper_Melt Constructor
//
//==========================================================================
OpenGLSWFrameBuffer::Wiper_Melt::Wiper_Melt()
{
int i, r;
// setup initial column positions
// (y<0 => not ready to scroll yet)
y[0] = -(M_Random() & 15);
for (i = 1; i < WIDTH; ++i)
{
r = (M_Random()%3) - 1;
y[i] = clamp(y[i-1] + r, -15, 0);
}
}
//==========================================================================
//
// OpenGLSWFrameBuffer :: Wiper_Melt :: Run
//
// Fades the old screen into the new one over 32 ticks.
//
//==========================================================================
bool OpenGLSWFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLSWFrameBuffer *fb)
{
// Draw the new screen on the bottom.
DrawScreen(fb, fb->FinalWipeScreen.get());
int i, dy;
int fbwidth = fb->Width;
int fbheight = fb->Height;
bool done = true;
// Copy the old screen in vertical strips on top of the new one.
while (ticks--)
{
done = true;
for (i = 0; i < WIDTH; i++)
{
if (y[i] < 0)
{
y[i]++;
done = false;
}
else if (y[i] < HEIGHT)
{
dy = (y[i] < 16) ? y[i]+1 : 8;
y[i] = MIN(y[i] + dy, HEIGHT);
done = false;
}
if (ticks == 0)
{ // Only draw for the final tick.
LTRBRect rect;
struct Point { int x, y; } dpt;
dpt.x = i * fbwidth / WIDTH;
dpt.y = MAX(0, y[i] * fbheight / HEIGHT);
rect.left = dpt.x;
rect.top = 0;
rect.right = (i + 1) * fbwidth / WIDTH;
rect.bottom = fbheight - dpt.y;
if (rect.bottom > rect.top)
{
fb->CheckQuadBatch();
BufferedTris *quad = &fb->QuadExtra[fb->QuadBatchPos];
FBVERTEX *vert = &fb->VertexData[fb->VertexPos];
uint16_t *index = &fb->IndexData[fb->IndexPos];
quad->ClearSetup();
quad->Flags = BQF_DisableAlphaTest;
quad->ShaderNum = BQS_Plain;
quad->Palette = NULL;
quad->Texture = fb->InitialWipeScreen.get();
quad->NumVerts = 4;
quad->NumTris = 2;
// Fill the vertex buffer.
float u0 = rect.left / float(fb->Width);
float v0 = 0;
float u1 = rect.right / float(fb->Width);
float v1 = (rect.bottom - rect.top) / float(fb->Height);
float x0 = float(rect.left);
float x1 = float(rect.right);
float y0 = float(dpt.y);
float y1 = float(fbheight);
vert[0].x = x0;
vert[0].y = y0;
vert[0].z = 0;
vert[0].rhw = 1;
vert[0].color0 = 0;
vert[0].color1 = 0xFFFFFFF;
vert[0].tu = u0;
vert[0].tv = v0;
vert[1].x = x1;
vert[1].y = y0;
vert[1].z = 0;
vert[1].rhw = 1;
vert[1].color0 = 0;
vert[1].color1 = 0xFFFFFFF;
vert[1].tu = u1;
vert[1].tv = v0;
vert[2].x = x1;
vert[2].y = y1;
vert[2].z = 0;
vert[2].rhw = 1;
vert[2].color0 = 0;
vert[2].color1 = 0xFFFFFFF;
vert[2].tu = u1;
vert[2].tv = v1;
vert[3].x = x0;
vert[3].y = y1;
vert[3].z = 0;
vert[3].rhw = 1;
vert[3].color0 = 0;
vert[3].color1 = 0xFFFFFFF;
vert[3].tu = u0;
vert[3].tv = v1;
// Fill the vertex index buffer.
index[0] = fb->VertexPos;
index[1] = fb->VertexPos + 1;
index[2] = fb->VertexPos + 2;
index[3] = fb->VertexPos;
index[4] = fb->VertexPos + 2;
index[5] = fb->VertexPos + 3;
// Batch the quad.
fb->QuadBatchPos++;
fb->VertexPos += 4;
fb->IndexPos += 6;
}
}
}
}
fb->EndQuadBatch();
return done;
}
// WIPE: BURN --------------------------------------------------------------
//==========================================================================
//
// OpenGLSWFrameBuffer :: Wiper_Burn Constructor
//
//==========================================================================
OpenGLSWFrameBuffer::Wiper_Burn::Wiper_Burn(OpenGLSWFrameBuffer *fb)
{
Density = 4;
BurnTime = 0;
memset(BurnArray, 0, sizeof(BurnArray));
if (fb->Shaders[SHADER_BurnWipe] == nullptr)
{
BurnTexture = nullptr;
}
BurnTexture = fb->CreateTexture("BurnWipe", WIDTH, HEIGHT, 1, GL_R8);
}
//==========================================================================
//
// OpenGLSWFrameBuffer :: Wiper_Burn Destructor
//
//==========================================================================
OpenGLSWFrameBuffer::Wiper_Burn::~Wiper_Burn()
{
BurnTexture.reset();
}
//==========================================================================
//
// OpenGLSWFrameBuffer :: Wiper_Burn :: Run
//
//==========================================================================
bool OpenGLSWFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLSWFrameBuffer *fb)
{
bool done;
BurnTime += ticks;
ticks *= 2;
// Make the fire burn
done = false;
while (!done && ticks--)
{
Density = wipe_CalcBurn(BurnArray, WIDTH, HEIGHT, Density);
done = (Density < 0);
}
// Update the burn texture with the new burn data
if (BurnTexture->Buffers[0] == 0)
{
glGenBuffers(2, (GLuint*)BurnTexture->Buffers);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, BurnTexture->Buffers[0]);
glBufferData(GL_PIXEL_UNPACK_BUFFER, WIDTH * HEIGHT, nullptr, GL_STREAM_DRAW);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, BurnTexture->Buffers[1]);
glBufferData(GL_PIXEL_UNPACK_BUFFER, WIDTH * HEIGHT, nullptr, GL_STREAM_DRAW);
}
else
{
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, BurnTexture->Buffers[BurnTexture->CurrentBuffer]);
BurnTexture->CurrentBuffer = (BurnTexture->CurrentBuffer + 1) & 1;
}
uint8_t *dest = (uint8_t*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, WIDTH * HEIGHT, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
if (dest)
{
memcpy(dest, BurnArray, WIDTH * HEIGHT);
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
GLint oldBinding = 0;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding);
glBindTexture(GL_TEXTURE_2D, BurnTexture->Texture);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, WIDTH, HEIGHT, GL_RED, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, oldBinding);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
}
// Put the initial screen back to the buffer.
DrawScreen(fb, fb->InitialWipeScreen.get());
// Burn the new screen on top of it.
float right = float(fb->Width);
float bot = float(fb->Height);
BURNVERTEX verts[4] =
{
{ 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0, 0 },
{ right, 0.f, 0.f, 1.f, 1.f, 0.f, 1, 0 },
{ right, bot, 0.f, 1.f, 1.f, 1.f, 1, 1 },
{ 0.f, bot, 0.f, 1.f, 0.f, 1.f, 0, 1 }
};
fb->SetTexture(0, fb->FinalWipeScreen.get());
fb->SetTexture(1, BurnTexture.get());
fb->SetAlphaBlend(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
fb->SetPixelShader(fb->Shaders[SHADER_BurnWipe].get());
glActiveTexture(GL_TEXTURE1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
fb->DrawTriangleFans(2, verts);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glActiveTexture(GL_TEXTURE0);
// The fire may not always stabilize, so the wipe is forced to end
// after an arbitrary maximum time.
return done || (BurnTime > 40);
}

View file

@ -6,7 +6,6 @@
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
//#include <direct.h>
#include <stddef.h>
#include <string.h>
#include <ctype.h>
@ -20,20 +19,12 @@
#endif
#include <time.h>
#ifdef _MSC_VER
#define F_OK 0 /* Check for file existence */
#define W_OK 2 /* Check for write permission */
#define R_OK 4 /* Check for read permission */
#include <io.h>
#else
#include <unistd.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//GL headers
#include "gl_load.h"
#include "gl_load/gl_load.h"
#if defined(__APPLE__)
#include <OpenGL/OpenGL.h>

Some files were not shown because too many files have changed in this diff Show more