Merge branch '3.0_work'

# Conflicts:
#	src/gl/scene/gl_portal.cpp
#	src/r_plane.cpp
This commit is contained in:
Christoph Oelckers 2017-03-12 20:31:34 +01:00
commit 61c91f05fc
552 changed files with 58264 additions and 23541 deletions

3
.gitignore vendored
View file

@ -47,3 +47,6 @@
/build_vc2015-32
/build_vc2015-64
/build
/llvm
/src/r_drawersasm.obj
/src/r_drawersasm.o

View file

@ -174,20 +174,24 @@ if( MSVC )
# Disable run-time type information
set( ALL_C_FLAGS "/GF /Gy /GR-" )
if( CMAKE_SIZEOF_VOID_P MATCHES "4")
# SSE2 option (to allow x87 in 32 bit and disallow extended feature sets which have not yet been checked for precision)
option (ZDOOM_USE_SSE2 "Use SSE2 instruction set")
if (ZDOOM_USE_SSE2)
set( ALL_C_FLAGS "${ALL_C_FLAGS} /arch:SSE2")
else ()
if (MSVC_VERSION GREATER 1699)
# On Visual C++ 2012 and later SSE2 is the default, so we need to switch it off explicitly
set( ALL_C_FLAGS "${ALL_C_FLAGS} /arch:IA32")
endif ()
endif ()
else()
set( ALL_C_FLAGS "${ALL_C_FLAGS} /arch:SSE2")
endif()
# Use SSE 2 as minimum always as the true color drawers needs it for __vectorcall
#set( ALL_C_FLAGS "${ALL_C_FLAGS} /arch:SSE2") # This is already the default
# if( CMAKE_SIZEOF_VOID_P MATCHES "4")
# # SSE2 option (to allow x87 in 32 bit and disallow extended feature sets which have not yet been checked for precision)
# option (ZDOOM_USE_SSE2 "Use SSE2 instruction set")
# if (ZDOOM_USE_SSE2)
# set( ALL_C_FLAGS "${ALL_C_FLAGS} /arch:SSE2")
# else ()
# if (MSVC_VERSION GREATER 1699)
# # On Visual C++ 2012 and later SSE2 is the default, so we need to switch it off explicitly
# set( ALL_C_FLAGS "${ALL_C_FLAGS} /arch:IA32")
# endif ()
# endif ()
# else()
# set( ALL_C_FLAGS "${ALL_C_FLAGS} /arch:SSE2")
# endif()
# Avoid CRT DLL dependancies in release builds, optionally generate assembly output for checking crash locations.
option( ZDOOM_GENERATE_ASM "Generate assembly output." OFF )

View file

@ -601,7 +601,9 @@ endif()
# Start defining source files for ZDoom
set( PLAT_WIN32_SOURCES
sound/mididevices/music_win_mididevice.cpp
win32/eaxedit.cpp
win32/critsec.cpp
win32/fb_d3d9.cpp
win32/fb_d3d9_wipe.cpp
win32/fb_ddraw.cpp
@ -626,6 +628,7 @@ set( PLAT_POSIX_SOURCES
posix/i_steam.cpp )
set( PLAT_SDL_SOURCES
posix/sdl/crashcatcher.c
posix/sdl/critsec.cpp
posix/sdl/hardware.cpp
posix/sdl/i_gui.cpp
posix/sdl/i_input.cpp
@ -640,6 +643,7 @@ set( PLAT_UNIX_SOURCES
posix/unix/i_specialpaths.cpp
posix/unix/iwadpicker_gtk.cpp )
set( PLAT_OSX_SOURCES
sound/mididevices/music_audiotoolbox_mididevice.cpp
posix/osx/iwadpicker_cocoa.mm
posix/osx/i_specialpaths.mm
posix/osx/zdoom.icns )
@ -702,6 +706,7 @@ if( HAVE_MMX )
PROPERTIES COMPILE_FLAGS "-mmmx" )
endif( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
endif( HAVE_MMX )
add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c ${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.h
COMMAND lemon -C${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/xlat/xlat_parser.y
DEPENDS lemon ${CMAKE_CURRENT_SOURCE_DIR}/xlat/xlat_parser.y )
@ -749,8 +754,8 @@ file( GLOB HEADER_FILES
g_inventory/*.h
intermission/*.h
menu/*.h
oplsynth/*.h
oplsynth/dosbox/*.h
sound/oplsynth/*.h
sound/oplsynth/dosbox/*.h
posix/*.h
posix/cocoa/*.h
posix/sdl/*.h
@ -765,9 +770,22 @@ file( GLOB HEADER_FILES
scripting/decorate/*.h
scripting/zscript/*.h
scripting/vm/*.h
timidity/*.h
wildmidi/*.h
sound/timidity/*.h
sound/wildmidi/*.h
xlat/*.h
swrenderer/*.h
swrenderer/drawers/*.h
swrenderer/scene/*.h
swrenderer/segments/*.h
swrenderer/line/*.h
swrenderer/plane/*.h
swrenderer/things/*.h
swrenderer/viewport/*.h
polyrenderer/*.h
polyrenderer/math/*.h
polyrenderer/drawers/*.h
polyrenderer/drawers/*.php
polyrenderer/scene/*.h
gl/*.h
gl/api/*.h
gl/data/*.h
@ -786,10 +804,77 @@ file( GLOB HEADER_FILES
*.h
)
set ( SWRENDER_SOURCES
swrenderer/r_swcanvas.cpp
swrenderer/r_swrenderer.cpp
swrenderer/r_memory.cpp
swrenderer/r_renderthread.cpp
swrenderer/drawers/r_draw_pal.cpp
swrenderer/drawers/r_draw_rgba.cpp
swrenderer/drawers/r_thread.cpp
swrenderer/scene/r_3dfloors.cpp
swrenderer/scene/r_light.cpp
swrenderer/scene/r_opaque_pass.cpp
swrenderer/scene/r_portal.cpp
swrenderer/scene/r_scene.cpp
swrenderer/scene/r_translucent_pass.cpp
swrenderer/viewport/r_drawerargs.cpp
swrenderer/viewport/r_skydrawer.cpp
swrenderer/viewport/r_spandrawer.cpp
swrenderer/viewport/r_spritedrawer.cpp
swrenderer/viewport/r_viewport.cpp
swrenderer/viewport/r_walldrawer.cpp
swrenderer/line/r_line.cpp
swrenderer/line/r_walldraw.cpp
swrenderer/line/r_wallsetup.cpp
swrenderer/line/r_fogboundary.cpp
swrenderer/line/r_renderdrawsegment.cpp
swrenderer/segments/r_clipsegment.cpp
swrenderer/segments/r_drawsegment.cpp
swrenderer/segments/r_portalsegment.cpp
swrenderer/things/r_visiblesprite.cpp
swrenderer/things/r_visiblespritelist.cpp
swrenderer/things/r_voxel.cpp
swrenderer/things/r_particle.cpp
swrenderer/things/r_playersprite.cpp
swrenderer/things/r_sprite.cpp
swrenderer/things/r_wallsprite.cpp
swrenderer/things/r_decal.cpp
swrenderer/plane/r_visibleplane.cpp
swrenderer/plane/r_visibleplanelist.cpp
swrenderer/plane/r_skyplane.cpp
swrenderer/plane/r_planerenderer.cpp
swrenderer/plane/r_flatplane.cpp
swrenderer/plane/r_slopeplane.cpp
)
set( POLYRENDER_SOURCES
polyrenderer/poly_renderer.cpp
polyrenderer/scene/poly_scene.cpp
polyrenderer/scene/poly_portal.cpp
polyrenderer/scene/poly_cull.cpp
polyrenderer/scene/poly_decal.cpp
polyrenderer/scene/poly_particle.cpp
polyrenderer/scene/poly_plane.cpp
polyrenderer/scene/poly_playersprite.cpp
polyrenderer/scene/poly_wall.cpp
polyrenderer/scene/poly_wallsprite.cpp
polyrenderer/scene/poly_sprite.cpp
polyrenderer/scene/poly_sky.cpp
polyrenderer/drawers/poly_buffer.cpp
polyrenderer/drawers/poly_triangle.cpp
polyrenderer/drawers/poly_draw_args.cpp
polyrenderer/drawers/screen_triangle.cpp
polyrenderer/math/tri_matrix.cpp
polyrenderer/math/poly_intersection.cpp
)
# These files will be flagged as "headers" so that they appear in project files
# without being compiled.
set( NOT_COMPILED_SOURCE_FILES
${OTHER_SYSTEM_SOURCES}
${SWRENDER_SOURCES}
${POLYRENDER_SOURCES}
sc_man_scanner.h
sc_man_scanner.re
g_statusbar/sbarinfo_commands.cpp
@ -801,128 +886,30 @@ set( NOT_COMPILED_SOURCE_FILES
zcc-parse.h
)
set( FASTMATH_PCH_SOURCES
r_swrenderer.cpp
r_3dfloors.cpp
r_bsp.cpp
r_draw.cpp
r_draw_pal.cpp
r_drawt_pal.cpp
r_thread.cpp
r_main.cpp
r_plane.cpp
r_segs.cpp
r_sky.cpp
r_things.cpp
r_walldraw.cpp
s_advsound.cpp
s_environment.cpp
s_playlist.cpp
s_sndseq.cpp
s_sound.cpp
GuillotineBinPack.cpp
SkylineBinPack.cpp
intermission/intermission.cpp
intermission/intermission_parse.cpp
menu/joystickmenu.cpp
menu/loadsavemenu.cpp
menu/menu.cpp
menu/menudef.cpp
menu/messagebox.cpp
menu/optionmenu.cpp
menu/playermenu.cpp
menu/videomenu.cpp
oplsynth/fmopl.cpp
oplsynth/mlopl.cpp
oplsynth/mlopl_io.cpp
oplsynth/dosbox/opl.cpp
oplsynth/OPL3.cpp
oplsynth/nukedopl3.cpp
timidity/common.cpp
timidity/instrum.cpp
timidity/instrum_dls.cpp
timidity/instrum_font.cpp
timidity/instrum_sf2.cpp
timidity/mix.cpp
timidity/playmidi.cpp
timidity/resample.cpp
timidity/timidity.cpp
wildmidi/file_io.cpp
wildmidi/gus_pat.cpp
wildmidi/reverb.cpp
wildmidi/wm_error.cpp
r_data/colormaps.cpp
r_data/r_translate.cpp
)
# This is disabled for now because I cannot find a way to give the .pch file a different name.
# Visual C++ 2015 seems hell-bent of only allowing one .pch file with the same name as the executable.
#enable_precompiled_headers( g_pch2.h FASTMATH_PCH_SOURCES )
# Enable fast math for some sources
set( FASTMATH_SOURCES
${FASTMATH_PCH_SOURCES}
oplsynth/music_opldumper_mididevice.cpp
oplsynth/music_opl_mididevice.cpp
oplsynth/opl_mus_player.cpp
swrenderer/r_all.cpp
polyrenderer/poly_all.cpp
sound/oplsynth/opl_mus_player.cpp
sound/fmodsound.cpp
sound/i_music.cpp
sound/i_sound.cpp
sound/mpg123_decoder.cpp
sound/music_cd.cpp
sound/music_dumb.cpp
sound/music_gme.cpp
sound/music_mus_midiout.cpp
sound/music_smf_midiout.cpp
sound/music_hmi_midiout.cpp
sound/music_xmi_midiout.cpp
sound/music_midistream.cpp
sound/music_midi_base.cpp
sound/music_midi_timidity.cpp
sound/music_mus_opl.cpp
sound/music_stream.cpp
sound/music_fluidsynth_mididevice.cpp
sound/music_softsynth_mididevice.cpp
sound/music_timidity_mididevice.cpp
sound/music_wildmidi_mididevice.cpp
sound/music_win_mididevice.cpp
sound/music_audiotoolbox_mididevice.cpp
sound/oalsound.cpp
sound/sndfile_decoder.cpp
sound/music_pseudo_mididevice.cpp
wildmidi/wildmidi_lib.cpp
gl/compatibility/gl_20.cpp
gl/data/gl_data.cpp
gl/data/gl_portaldata.cpp
gl/data/gl_setup.cpp
sound/mididevices/music_timiditypp_mididevice.cpp
gl/data/gl_matrix.cpp
gl/data/gl_vertexbuffer.cpp
gl/dynlights/a_dynlight.cpp
gl/utility/gl_clock.cpp
gl/utility/gl_cycler.cpp
gl/utility/gl_geometric.cpp
gl/renderer/gl_2ddrawer.cpp
gl/renderer/gl_quaddrawer.cpp
gl/renderer/gl_renderer.cpp
gl/renderer/gl_renderstate.cpp
gl/renderer/gl_renderbuffers.cpp
gl/renderer/gl_lightdata.cpp
gl/renderer/gl_postprocess.cpp
gl/renderer/gl_postprocessstate.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
gl/textures/gl_hwtexture.cpp
gl/textures/gl_texture.cpp
gl/textures/gl_material.cpp
gl/textures/gl_hirestex.cpp
gl/textures/gl_bitmap.cpp
gl/textures/gl_samplers.cpp
gl/textures/gl_translate.cpp
gl/textures/gl_hqresize.cpp
gl/textures/gl_skyboxtexture.cpp
gl/scene/gl_bsp.cpp
gl/scene/gl_fakeflat.cpp
gl/scene/gl_clipper.cpp
@ -940,40 +927,9 @@ set( FASTMATH_SOURCES
gl/scene/gl_walls_draw.cpp
gl/scene/gl_vertex.cpp
gl/scene/gl_spritelight.cpp
gl/stereo3d/gl_stereo3d.cpp
gl/stereo3d/gl_stereo_cvars.cpp
gl/stereo3d/gl_stereo_leftright.cpp
gl/stereo3d/scoped_view_shifter.cpp
gl/stereo3d/gl_anaglyph.cpp
gl/stereo3d/gl_quadstereo.cpp
gl/stereo3d/gl_sidebyside3d.cpp
gl/stereo3d/gl_interleaved3d.cpp
gl/dynlights/gl_dynlight.cpp
gl/dynlights/gl_glow.cpp
gl/dynlights/gl_dynlight1.cpp
gl/dynlights/gl_lightbuffer.cpp
gl/shaders/gl_shader.cpp
gl/shaders/gl_texshader.cpp
gl/shaders/gl_shaderprogram.cpp
gl/shaders/gl_presentshader.cpp
gl/shaders/gl_present3dRowshader.cpp
gl/shaders/gl_bloomshader.cpp
gl/shaders/gl_ambientshader.cpp
gl/shaders/gl_blurshader.cpp
gl/shaders/gl_colormapshader.cpp
gl/shaders/gl_tonemapshader.cpp
gl/shaders/gl_lensshader.cpp
gl/shaders/gl_fxaashader.cpp
gl/system/gl_interface.cpp
gl/system/gl_framebuffer.cpp
gl/system/gl_debug.cpp
gl/system/gl_menu.cpp
gl/system/gl_wipe.cpp
gl/system/gl_load.c
gl/models/gl_models_md3.cpp
gl/models/gl_models_md2.cpp
gl/models/gl_models.cpp
gl/models/gl_voxels.cpp
)
set (PCH_SOURCES
@ -998,6 +954,7 @@ set (PCH_SOURCES
compatibility.cpp
configfile.cpp
ct_chat.cpp
cycler.cpp
d_dehacked.cpp
d_iwad.cpp
d_main.cpp
@ -1096,6 +1053,12 @@ set (PCH_SOURCES
po_man.cpp
portal.cpp
r_utility.cpp
r_sky.cpp
s_advsound.cpp
s_environment.cpp
s_playlist.cpp
s_sndseq.cpp
s_sound.cpp
serializer.cpp
sc_man.cpp
st_stuff.cpp
@ -1120,6 +1083,8 @@ set (PCH_SOURCES
g_inventory/a_weapons.cpp
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
@ -1131,6 +1096,70 @@ set (PCH_SOURCES
g_statusbar/sbar_mugshot.cpp
g_statusbar/shared_sbar.cpp
g_statusbar/strife_sbar.cpp
gl/compatibility/gl_20.cpp
gl/data/gl_data.cpp
gl/data/gl_portaldata.cpp
gl/data/gl_setup.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/models/gl_models_md3.cpp
gl/models/gl_models_md2.cpp
gl/models/gl_voxels.cpp
gl/renderer/gl_quaddrawer.cpp
gl/renderer/gl_renderer.cpp
gl/renderer/gl_renderstate.cpp
gl/renderer/gl_renderbuffers.cpp
gl/renderer/gl_lightdata.cpp
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_shadowmapshader.cpp
gl/shaders/gl_presentshader.cpp
gl/shaders/gl_present3dRowshader.cpp
gl/shaders/gl_bloomshader.cpp
gl/shaders/gl_ambientshader.cpp
gl/shaders/gl_blurshader.cpp
gl/shaders/gl_colormapshader.cpp
gl/shaders/gl_tonemapshader.cpp
gl/shaders/gl_lensshader.cpp
gl/shaders/gl_fxaashader.cpp
gl/stereo3d/gl_stereo3d.cpp
gl/stereo3d/gl_stereo_cvars.cpp
gl/stereo3d/gl_stereo_leftright.cpp
gl/stereo3d/scoped_view_shifter.cpp
gl/stereo3d/gl_anaglyph.cpp
gl/stereo3d/gl_quadstereo.cpp
gl/stereo3d/gl_sidebyside3d.cpp
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_bitmap.cpp
gl/textures/gl_samplers.cpp
gl/textures/gl_translate.cpp
gl/textures/gl_hqresize.cpp
gl/textures/gl_skyboxtexture.cpp
menu/joystickmenu.cpp
menu/loadsavemenu.cpp
menu/menu.cpp
menu/menudef.cpp
menu/messagebox.cpp
menu/optionmenu.cpp
menu/playermenu.cpp
menu/videomenu.cpp
resourcefiles/ancientzip.cpp
resourcefiles/file_7z.cpp
resourcefiles/file_grp.cpp
@ -1172,6 +1201,10 @@ set (PCH_SOURCES
fragglescript/t_spec.cpp
fragglescript/t_variable.cpp
fragglescript/t_cmd.cpp
intermission/intermission.cpp
intermission/intermission_parse.cpp
r_data/colormaps.cpp
r_data/r_translate.cpp
r_data/sprites.cpp
r_data/voxels.cpp
r_data/renderstyle.cpp
@ -1195,8 +1228,50 @@ set (PCH_SOURCES
scripting/zscript/zcc_compile.cpp
scripting/zscript/zcc_parser.cpp
sfmt/SFMT.cpp
sound/i_music.cpp
sound/i_sound.cpp
sound/mididevices/music_opldumper_mididevice.cpp
sound/mididevices/music_opl_mididevice.cpp
sound/mididevices/music_pseudo_mididevice.cpp
sound/mididevices/music_fluidsynth_mididevice.cpp
sound/mididevices/music_softsynth_mididevice.cpp
sound/mididevices/music_timidity_mididevice.cpp
sound/mididevices/music_wildmidi_mididevice.cpp
sound/musicformats/music_cd.cpp
sound/musicformats/music_dumb.cpp
sound/musicformats/music_gme.cpp
sound/musicformats/music_mus_midiout.cpp
sound/musicformats/music_smf_midiout.cpp
sound/musicformats/music_hmi_midiout.cpp
sound/musicformats/music_xmi_midiout.cpp
sound/musicformats/music_midistream.cpp
sound/musicformats/music_opl.cpp
sound/musicformats/music_stream.cpp
sound/oplsynth/fmopl.cpp
sound/oplsynth/mlopl.cpp
sound/oplsynth/mlopl_io.cpp
sound/oplsynth/dosbox/opl.cpp
sound/oplsynth/OPL3.cpp
sound/oplsynth/nukedopl3.cpp
sound/timidity/common.cpp
sound/timidity/instrum.cpp
sound/timidity/instrum_dls.cpp
sound/timidity/instrum_font.cpp
sound/timidity/instrum_sf2.cpp
sound/timidity/mix.cpp
sound/timidity/playmidi.cpp
sound/timidity/resample.cpp
sound/timidity/timidity.cpp
sound/wildmidi/file_io.cpp
sound/wildmidi/gus_pat.cpp
sound/wildmidi/reverb.cpp
sound/wildmidi/wildmidi_lib.cpp
sound/wildmidi/wm_error.cpp
events.cpp
GuillotineBinPack.cpp
SkylineBinPack.cpp
)
enable_precompiled_headers( g_pch.h PCH_SOURCES )
add_executable( zdoom WIN32 MACOSX_BUNDLE
@ -1246,15 +1321,16 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "SunOS")
endif()
target_link_libraries( zdoom ${ZDOOM_LIBS} gdtoa dumb lzma )
include_directories( .
g_statusbar
g_shared
g_inventory
oplsynth
sound
textures
timidity
wildmidi
sound/oplsynth
sound/timidity
sound/wildmidi
xlat
scripting
scripting/vm
@ -1366,12 +1442,12 @@ install(TARGETS zdoom
COMPONENT "Game executable")
source_group("Audio Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sound/.+")
source_group("Audio Files\\OPL Synth" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/oplsynth/.+")
source_group("Audio Files\\OPL Synth\\DOSBox" FILES oplsynth/dosbox/opl.cpp oplsynth/dosbox/opl.h)
source_group("Audio Files\\Timidity\\Headers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/timidity/.+\\.h$")
source_group("Audio Files\\Timidity\\Source" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/timidity/.+\\.cpp$")
source_group("Audio Files\\WildMidi\\Headers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/wildmidi/.+\\.h$")
source_group("Audio Files\\WildMidi\\Source" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/wildmidi/.+\\.cpp$")
source_group("Audio Files\\OPL Synth" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sound/oplsynth/.+")
source_group("Audio Files\\OPL Synth\\DOSBox" FILES sound/oplsynth/dosbox/opl.cpp sound/oplsynth/dosbox/opl.h)
source_group("Audio Files\\Timidity" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sound/timidity/.+")
source_group("Audio Files\\WildMidi" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sound/wildmidi/.+")
source_group("Audio Files\\MIDI Devices" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sound/mididevices/.+")
source_group("Audio Files\\Music formats" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sound/musicformats/.+")
source_group("External\\Math" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/math/.+")
source_group("External\\RapidJSON" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/rapidjson/.+")
source_group("External\\SFMT" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/sfmt/.+")
@ -1393,8 +1469,18 @@ source_group("OpenGL Renderer\\Shaders" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOU
source_group("OpenGL Renderer\\System" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/system/.+")
source_group("OpenGL Renderer\\Textures" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/textures/.+")
source_group("OpenGL Renderer\\Utilities" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/utility/.+")
source_group("Render Core\\Render Headers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_.+\\.h$")
source_group("Render Core\\Render Sources" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_.+\\.cpp$")
source_group("Software Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/swrenderer/.+")
source_group("Software Renderer\\Drawers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/swrenderer/drawers/.+")
source_group("Software Renderer\\Scene" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/swrenderer/scene/.+")
source_group("Software Renderer\\Segments" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/swrenderer/segments/.+")
source_group("Software Renderer\\Line" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/swrenderer/line/.+")
source_group("Software Renderer\\Plane" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/swrenderer/plane/.+")
source_group("Software Renderer\\Things" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/swrenderer/things/.+")
source_group("Software Renderer\\Viewport" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/swrenderer/viewport/.+")
source_group("Poly Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/polyrenderer/.+")
source_group("Poly Renderer\\Math" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/polyrenderer/math/.+")
source_group("Poly Renderer\\Drawers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/polyrenderer/drawers/.+")
source_group("Poly Renderer\\Scene" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/polyrenderer/scene/.+")
source_group("Render Data\\Resource Headers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_data/.+\\.h$")
source_group("Render Data\\Resource Sources" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_data/.+\\.cpp$")
source_group("Render Data\\Textures" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/textures/.+")

View file

@ -47,6 +47,7 @@ struct subsector_t;
struct FBlockNode;
struct FPortalGroupArray;
struct visstyle_t;
class FLightDefaults;
//
// NOTES: AActor
//
@ -974,6 +975,10 @@ public:
void ClearRenderSectorList();
void ClearRenderLineList();
void AttachLight(unsigned int count, const FLightDefaults *lightdef);
void SetDynamicLights();
// info for drawing
// NOTE: The first member variable *must* be snext.
AActor *snext, **sprev; // links in sector (if needed)
@ -1191,6 +1196,7 @@ public:
DVector3 Prev;
DRotator PrevAngles;
int PrevPortalGroup;
TArray<TObjPtr<AActor*> > AttachedLights;
// ThingIDs
static void ClearTIDHashes ();
@ -1432,12 +1438,10 @@ public:
int ApplyDamageFactor(FName damagetype, int damage) const;
int GetModifiedDamage(FName damagetype, int damage, bool passive);
static void DeleteAllAttachedLights();
static void RecreateAllAttachedLights();
// begin of GZDoom specific additions
TArray<TObjPtr<AActor*> > dynamiclights;
void * lightassociations;
bool hasmodel;
// end of GZDoom specific additions
size_t PropagateMark();
};
@ -1469,6 +1473,7 @@ public:
{
base = nullptr;
}
private:
AActor *base;
int id;

55
src/actorinlines.h Normal file
View file

@ -0,0 +1,55 @@
#pragma once
#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.
inline DVector3 AActor::PosRelative(int portalgroup) const
{
return Pos() + Displacements.getOffset(Sector->PortalGroup, portalgroup);
}
inline DVector3 AActor::PosRelative(const AActor *other) const
{
return Pos() + Displacements.getOffset(Sector->PortalGroup, other->Sector->PortalGroup);
}
inline DVector3 AActor::PosRelative(sector_t *sec) const
{
return Pos() + Displacements.getOffset(Sector->PortalGroup, sec->PortalGroup);
}
inline DVector3 AActor::PosRelative(line_t *line) const
{
return Pos() + 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);
}
inline void AActor::ClearInterpolation()
{
Prev = Pos();
PrevAngles = Angles;
if (Sector) PrevPortalGroup = Sector->PortalGroup;
else PrevPortalGroup = 0;
}
inline double secplane_t::ZatPoint(const AActor *ac) const
{
return (D + normal.X*ac->X() + normal.Y*ac->Y()) * negiC;
}
inline double sector_t::HighestCeilingAt(AActor *a, sector_t **resultsec)
{
return HighestCeilingAt(a->Pos(), resultsec);
}
inline double sector_t::LowestFloorAt(AActor *a, sector_t **resultsec)
{
return LowestFloorAt(a->Pos(), resultsec);
}

View file

@ -70,6 +70,7 @@
#include "a_keys.h"
#include "r_data/colormaps.h"
#include "g_levellocals.h"
#include "actorinlines.h"
//=============================================================================
@ -153,12 +154,12 @@ CVAR (Color, am_ovportalcolor, 0x004022, CVAR_ARCHIVE);
struct AMColor
{
int Index;
uint32 RGB;
uint32_t RGB;
void FromCVar(FColorCVar & cv)
{
Index = cv.GetIndex();
RGB = uint32(cv) | MAKEARGB(255, 0, 0, 0);
RGB = uint32_t(cv) | MAKEARGB(255, 0, 0, 0);
}
void FromRGB(int r,int g, int b)
@ -1932,7 +1933,7 @@ void AM_drawSubsectors()
points[j].Y = float(f_y + (f_h - (pt.y - m_y) * scale));
}
// For lighting and texture determination
sector_t *sec = Renderer->FakeFlat(subsectors[i].render_sector, &tempsec, &floorlight, &ceilinglight, false);
sector_t *sec = Renderer->FakeFlat(subsectors[i].render_sector, &tempsec, &floorlight, &ceilinglight);
// Find texture origin.
originpt.x = -sec->GetXOffset(sector_t::floor);
originpt.y = sec->GetYOffset(sector_t::floor);
@ -1958,13 +1959,13 @@ void AM_drawSubsectors()
double secx;
double secy;
double seczb, seczt;
double cmpz = ViewPos.Z;
double cmpz = r_viewpoint.Pos.Z;
if (players[consoleplayer].camera && sec == players[consoleplayer].camera->Sector)
{
// For the actual camera sector use the current viewpoint as reference.
secx = ViewPos.X;
secy = ViewPos.Y;
secx = r_viewpoint.Pos.X;
secy = r_viewpoint.Pos.Y;
}
else
{
@ -2142,7 +2143,6 @@ void AM_showSS()
{
AM_drawSeg(sub->firstline + i, yellow);
}
PO_LinkToSubsectors();
for (int i = 0; i <po_NumPolyobjs; i++)
{

View file

@ -10,7 +10,7 @@
#include "c_cvars.h"
#include "info.h"
#include "doomdef.h"
#include "d_ticcmd.h"
#include "d_protocol.h"
#include "r_defs.h"
#include "a_pickups.h"
#include "stats.h"

View file

@ -24,6 +24,7 @@
#include "d_player.h"
#include "p_spec.h"
#include "p_checkposition.h"
#include "actorinlines.h"
static FRandom pr_botdofire ("BotDoFire");

View file

@ -10,7 +10,7 @@
#include "p_local.h"
#include "b_bot.h"
#include "g_game.h"
#include "d_ticcmd.h"
#include "d_protocol.h"
#include "m_random.h"
#include "i_system.h"
#include "p_lnspec.h"
@ -21,6 +21,7 @@
#include "d_player.h"
#include "p_spec.h"
#include "p_checkposition.h"
#include "actorinlines.h"
#include "math/cmath.h"
static FRandom pr_botopendoor ("BotOpenDoor");

View file

@ -21,6 +21,7 @@
#include "d_event.h"
#include "d_player.h"
#include "vectors.h"
#include "actorinlines.h"
static FRandom pr_botmove ("BotMove");

View file

@ -3,30 +3,14 @@
#include <stdint.h>
typedef int8_t SBYTE;
typedef uint8_t BYTE;
typedef int16_t SWORD;
typedef uint16_t WORD;
typedef uint32_t uint32;
typedef uint64_t QWORD;
// windef.h, included by windows.h, has its own incompatible definition
// of DWORD as a long. In files that mix Doom and Windows code, you
// must define USE_WINDOWS_DWORD before including doomtype.h so that
// you are aware that those files have a different DWORD than the rest
// of the source.
#ifndef USE_WINDOWS_DWORD
typedef uint32 DWORD;
#endif
typedef uint32 BITFIELD;
typedef uint32_t BITFIELD;
typedef int INTBOOL;
#if !defined(GUID_DEFINED)
#define GUID_DEFINED
typedef struct _GUID
{
DWORD Data1;
uint32_t Data1;
uint16_t Data2;
uint16_t Data3;
uint8_t Data4[8];
@ -35,7 +19,7 @@ typedef struct _GUID
union QWORD_UNION
{
QWORD AsOne;
uint64_t AsOne;
struct
{
#ifdef __BIG_ENDIAN__
@ -53,13 +37,13 @@ union QWORD_UNION
#define FRACUNIT (1<<FRACBITS)
typedef int32_t fixed_t;
typedef DWORD dsfixed_t; // fixedpt used by span drawer
typedef uint32_t dsfixed_t; // fixedpt used by span drawer
#define FIXED_MAX (signed)(0x7fffffff)
#define FIXED_MIN (signed)(0x80000000)
#define DWORD_MIN ((uint32)0)
#define DWORD_MAX ((uint32)0xffffffff)
#define DWORD_MIN ((uint32_t)0)
#define DWORD_MAX ((uint32_t)0xffffffff)
// the last remnants of tables.h
#define ANGLE_90 (0x40000000)
@ -67,7 +51,7 @@ typedef DWORD dsfixed_t; // fixedpt used by span drawer
#define ANGLE_270 (0xc0000000)
#define ANGLE_MAX (0xffffffff)
typedef uint32 angle_t;
typedef uint32_t angle_t;
#ifdef __GNUC__

View file

@ -45,6 +45,7 @@
#include "d_event.h"
#include "w_wad.h"
#include "templates.h"
#include "dobject.h"
#include <math.h>
#include <stdlib.h>

View file

@ -48,7 +48,7 @@
#include "hu_stuff.h"
#include "i_system.h"
#include "i_video.h"
#include "i_input.h"
#include "g_input.h"
#include "m_swap.h"
#include "v_palette.h"
#include "v_video.h"
@ -162,10 +162,14 @@ int active_con_scale()
int scale = con_scale;
if (scale <= 0)
{
scale = CleanXfac - 1;
if (scale <= 0)
scale = uiscale;
if (scale == 0)
{
scale = 1;
scale = CleanXfac - 1;
if (scale <= 0)
{
scale = 1;
}
}
}
return scale;

View file

@ -1677,7 +1677,7 @@ void C_SetCVarsToDefaults (void)
}
}
void C_ArchiveCVars (FConfigFile *f, uint32 filter)
void C_ArchiveCVars (FConfigFile *f, uint32_t filter)
{
FBaseCVar *cvar = CVars;

View file

@ -96,13 +96,13 @@ class FxCVar;
class FBaseCVar
{
public:
FBaseCVar (const char *name, uint32 flags, void (*callback)(FBaseCVar &));
FBaseCVar (const char *name, uint32_t flags, void (*callback)(FBaseCVar &));
virtual ~FBaseCVar ();
inline void Callback () { if (m_Callback) m_Callback (*this); }
inline const char *GetName () const { return Name; }
inline uint32 GetFlags () const { return Flags; }
inline uint32_t GetFlags () const { return Flags; }
inline FBaseCVar *GetNext() const { return m_Next; }
void CmdSet (const char *newval);
@ -147,11 +147,11 @@ protected:
static UCVarValue FromGUID (const GUID &value, ECVarType type);
char *Name;
uint32 Flags;
uint32_t Flags;
private:
FBaseCVar (const FBaseCVar &var);
FBaseCVar (const char *name, uint32 flags);
FBaseCVar (const char *name, uint32_t flags);
void (*m_Callback)(FBaseCVar &);
FBaseCVar *m_Next;
@ -159,26 +159,26 @@ private:
static bool m_UseCallback;
static bool m_DoNoSet;
friend FString C_GetMassCVarString (uint32 filter, bool compact);
friend FString C_GetMassCVarString (uint32_t filter, bool compact);
friend void C_ReadCVars (uint8_t **demo_p);
friend void C_BackupCVars (void);
friend FBaseCVar *FindCVar (const char *var_name, FBaseCVar **prev);
friend FBaseCVar *FindCVarSub (const char *var_name, int namelen);
friend void UnlatchCVars (void);
friend void DestroyCVarsFlagged (uint32_t flags);
friend void C_ArchiveCVars (FConfigFile *f, uint32 filter);
friend void C_ArchiveCVars (FConfigFile *f, uint32_t filter);
friend void C_SetCVarsToDefaults (void);
friend void FilterCompactCVars (TArray<FBaseCVar *> &cvars, uint32 filter);
friend void FilterCompactCVars (TArray<FBaseCVar *> &cvars, uint32_t filter);
friend void C_DeinitConsole();
};
// Returns a string with all cvars whose flags match filter. In compact mode,
// the cvar names are omitted to save space.
FString C_GetMassCVarString (uint32 filter, bool compact=false);
FString C_GetMassCVarString (uint32_t filter, bool compact=false);
// Writes all cvars that could effect demo sync to *demo_p. These are
// cvars that have either CVAR_SERVERINFO or CVAR_DEMOSAVE set.
void C_WriteCVars (uint8_t **demo_p, uint32 filter, bool compact=false);
void C_WriteCVars (uint8_t **demo_p, uint32_t filter, bool compact=false);
// Read all cvars from *demo_p and set them appropriately.
void C_ReadCVars (uint8_t **demo_p);
@ -205,12 +205,12 @@ void UnlatchCVars (void);
void DestroyCVarsFlagged (uint32_t flags);
// archive cvars to FILE f
void C_ArchiveCVars (FConfigFile *f, uint32 filter);
void C_ArchiveCVars (FConfigFile *f, uint32_t filter);
// initialize cvars to default values after they are created
void C_SetCVarsToDefaults (void);
void FilterCompactCVars (TArray<FBaseCVar *> &cvars, uint32 filter);
void FilterCompactCVars (TArray<FBaseCVar *> &cvars, uint32_t filter);
void C_DeinitConsole();
@ -218,7 +218,7 @@ class FBoolCVar : public FBaseCVar
{
friend class FxCVar;
public:
FBoolCVar (const char *name, bool def, uint32 flags, void (*callback)(FBoolCVar &)=NULL);
FBoolCVar (const char *name, bool def, uint32_t flags, void (*callback)(FBoolCVar &)=NULL);
virtual ECVarType GetRealType () const;
@ -244,7 +244,7 @@ class FIntCVar : public FBaseCVar
{
friend class FxCVar;
public:
FIntCVar (const char *name, int def, uint32 flags, void (*callback)(FIntCVar &)=NULL);
FIntCVar (const char *name, int def, uint32_t flags, void (*callback)(FIntCVar &)=NULL);
virtual ECVarType GetRealType () const;
@ -272,7 +272,7 @@ class FFloatCVar : public FBaseCVar
{
friend class FxCVar;
public:
FFloatCVar (const char *name, float def, uint32 flags, void (*callback)(FFloatCVar &)=NULL);
FFloatCVar (const char *name, float def, uint32_t flags, void (*callback)(FFloatCVar &)=NULL);
virtual ECVarType GetRealType () const;
@ -299,7 +299,7 @@ class FStringCVar : public FBaseCVar
{
friend class FxCVar;
public:
FStringCVar (const char *name, const char *def, uint32 flags, void (*callback)(FStringCVar &)=NULL);
FStringCVar (const char *name, const char *def, uint32_t flags, void (*callback)(FStringCVar &)=NULL);
~FStringCVar ();
virtual ECVarType GetRealType () const;
@ -326,7 +326,7 @@ class FColorCVar : public FIntCVar
{
friend class FxCVar;
public:
FColorCVar (const char *name, int def, uint32 flags, void (*callback)(FColorCVar &)=NULL);
FColorCVar (const char *name, int def, uint32_t flags, void (*callback)(FColorCVar &)=NULL);
virtual ECVarType GetRealType () const;
@ -334,8 +334,8 @@ public:
virtual UCVarValue GetGenericRepDefault (ECVarType type) const;
virtual void SetGenericRepDefault (UCVarValue value, ECVarType type);
inline operator uint32 () const { return Value; }
inline uint32 operator *() const { return Value; }
inline operator uint32_t () const { return Value; }
inline uint32_t operator *() const { return Value; }
inline int GetIndex () const { return Index; }
protected:
@ -351,7 +351,7 @@ class FFlagCVar : public FBaseCVar
{
friend class FxCVar;
public:
FFlagCVar (const char *name, FIntCVar &realvar, uint32 bitval);
FFlagCVar (const char *name, FIntCVar &realvar, uint32_t bitval);
virtual ECVarType GetRealType () const;
@ -372,7 +372,7 @@ protected:
virtual void DoSet (UCVarValue value, ECVarType type);
FIntCVar &ValueVar;
uint32 BitVal;
uint32_t BitVal;
int BitNum;
};
@ -380,7 +380,7 @@ class FMaskCVar : public FBaseCVar
{
friend class FxCVar;
public:
FMaskCVar (const char *name, FIntCVar &realvar, uint32 bitval);
FMaskCVar (const char *name, FIntCVar &realvar, uint32_t bitval);
virtual ECVarType GetRealType () const;
@ -397,14 +397,14 @@ protected:
virtual void DoSet (UCVarValue value, ECVarType type);
FIntCVar &ValueVar;
uint32 BitVal;
uint32_t BitVal;
int BitNum;
};
class FGUIDCVar : public FBaseCVar
{
public:
FGUIDCVar (const char *name, const GUID *defguid, uint32 flags, void (*callback)(FGUIDCVar &)=NULL);
FGUIDCVar (const char *name, const GUID *defguid, uint32_t flags, void (*callback)(FGUIDCVar &)=NULL);
virtual ECVarType GetRealType () const;

View file

@ -153,10 +153,10 @@ struct FButtonStatus
enum { MAX_KEYS = 6 }; // Maximum number of keys that can press this button
uint16_t Keys[MAX_KEYS];
BYTE bDown; // Button is down right now
BYTE bWentDown; // Button went down this tic
BYTE bWentUp; // Button went up this tic
BYTE padTo16Bytes;
uint8_t bDown; // Button is down right now
uint8_t bWentDown; // Button went down this tic
uint8_t bWentUp; // Button went up this tic
uint8_t padTo16Bytes;
bool PressKey (int keynum); // Returns true if this key caused the button to be pressed.
bool ReleaseKey (int keynum); // Returns true if this key is no longer pressed.

View file

@ -412,7 +412,7 @@ bool CheckWildcards (const char *pattern, const char *text)
void FormatGUID (char *buffer, size_t buffsize, const GUID &guid)
{
mysnprintf (buffer, buffsize, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
(uint32)guid.Data1, guid.Data2, guid.Data3,
(uint32_t)guid.Data1, guid.Data2, guid.Data3,
guid.Data4[0], guid.Data4[1],
guid.Data4[2], guid.Data4[3],
guid.Data4[4], guid.Data4[5],

View file

@ -71,10 +71,10 @@ void FColorMatcher::SetPalette (const uint32_t *palette)
Pal = (const PalEntry *)palette;
}
BYTE FColorMatcher::Pick (int r, int g, int b)
uint8_t FColorMatcher::Pick (int r, int g, int b)
{
if (Pal == NULL)
return 1;
return (BYTE)BestColor ((uint32 *)Pal, r, g, b);
return (uint8_t)BestColor ((uint32_t *)Pal, r, g, b);
}

View file

@ -114,6 +114,7 @@ static FCompatOption Options[] =
{ "linkfrozenprops", BCOMPATF_LINKFROZENPROPS, SLOT_BCOMPAT },
{ "floatbob", BCOMPATF_FLOATBOB, SLOT_BCOMPAT },
{ "noslopeid", BCOMPATF_NOSLOPEID, SLOT_BCOMPAT },
{ "clipmidtex", BCOMPATF_CLIPMIDTEX, SLOT_BCOMPAT },
// list copied from g_mapinfo.cpp
{ "shorttex", COMPATF_SHORTTEX, SLOT_COMPAT },
@ -152,7 +153,6 @@ static FCompatOption Options[] =
{ "multiexit", COMPATF2_MULTIEXIT, SLOT_COMPAT2 },
{ "teleport", COMPATF2_TELEPORT, SLOT_COMPAT2 },
{ "disablepushwindowcheck", COMPATF2_PUSHWINDOW, SLOT_COMPAT2 },
{ NULL, 0, 0 }
};

View file

@ -7,7 +7,7 @@
union FMD5Holder
{
BYTE Bytes[16];
uint8_t Bytes[16];
uint32_t DWords[4];
hash_t Hash;
};

View file

@ -863,7 +863,7 @@ const char *FConfigFile::GenerateEndTag(const char *value)
// isn't in the value. We create the sequences by generating two
// 64-bit random numbers and Base64 encoding the first 15 bytes
// from them.
union { QWORD rand_num[2]; BYTE rand_bytes[16]; };
union { uint64_t rand_num[2]; uint8_t rand_bytes[16]; };
do
{
rand_num[0] = pr_endtag.GenRand64();

37
src/critsec.h Normal file
View file

@ -0,0 +1,37 @@
#pragma once
// System independent critical sections without polluting the namespace with the operating system headers.
class FInternalCriticalSection;
FInternalCriticalSection *CreateCriticalSection();
void DeleteCriticalSection(FInternalCriticalSection *c);
void EnterCriticalSection(FInternalCriticalSection *c);
void LeaveCriticalSection(FInternalCriticalSection *c);
// This is just a convenience wrapper around the function interface.
class FCriticalSection
{
public:
FCriticalSection()
{
c = CreateCriticalSection();
}
~FCriticalSection()
{
DeleteCriticalSection(c);
}
void Enter()
{
EnterCriticalSection(c);
}
void Leave()
{
LeaveCriticalSection(c);
}
private:
FInternalCriticalSection *c;
};

View file

@ -27,7 +27,7 @@
#include "v_video.h"
#include "gi.h"
#include "d_gui.h"
#include "i_input.h"
#include "g_input.h"
#include "templates.h"
#include "d_net.h"
#include "d_event.h"

View file

@ -35,7 +35,7 @@
#include <math.h>
#include "serializer.h"
#include "gl/utility/gl_cycler.h"
#include "cycler.h"
//==========================================================================
//
@ -68,11 +68,11 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FCycler &c, FCycler *d
FCycler::FCycler()
{
m_cycle = 0.f;
m_cycle = 0.;
m_cycleType = CYCLE_Linear;
m_shouldCycle = false;
m_start = m_current = 0.f;
m_end = 0.f;
m_start = m_current = 0.;
m_end = 0.;
m_increment = true;
}
@ -83,19 +83,19 @@ FCycler::FCycler()
//
//==========================================================================
void FCycler::SetParams(float start, float end, float cycle, bool update)
void FCycler::SetParams(double start, double end, double cycle, bool update)
{
if (!update || cycle != m_cycle)
{
m_cycle = cycle;
m_time = 0.f;
m_time = 0.;
m_increment = true;
m_current = start;
}
else
{
// When updating and keeping the same cycle, scale the current light size to the new dimensions.
float fact = (m_current - m_start) / (m_end - m_start);
double fact = (m_current - m_start) / (m_end - m_start);
m_current = start + fact *(end - start);
}
m_start = start;
@ -109,10 +109,10 @@ void FCycler::SetParams(float start, float end, float cycle, bool update)
//
//==========================================================================
void FCycler::Update(float diff)
void FCycler::Update(double diff)
{
float mult, angle;
float step = m_end - m_start;
double mult, angle;
double step = m_end - m_start;
if (!m_shouldCycle)
{
@ -140,15 +140,15 @@ void FCycler::Update(float diff)
}
break;
case CYCLE_Sin:
angle = float(M_PI * 2.f * mult);
mult = sinf(angle);
mult = (mult + 1.f) / 2.f;
angle = double(M_PI * 2. * mult);
mult = g_sin(angle);
mult = (mult + 1.) / 2.;
m_current = m_start + (step * mult);
break;
case CYCLE_Cos:
angle = float(M_PI * 2.f * mult);
mult = cosf(angle);
mult = (mult + 1.f) / 2.f;
angle = double(M_PI * 2. * mult);
mult = g_cos(angle);
mult = (mult + 1.) / 2.;
m_current = m_start + (step * mult);
break;
case CYCLE_SawTooth:
@ -168,7 +168,7 @@ void FCycler::Update(float diff)
if (m_time == m_cycle)
{
m_time = 0.f;
m_time = 0.;
m_increment = !m_increment;
}
}

View file

@ -21,17 +21,17 @@ class FCycler
public:
FCycler();
void Update(float diff);
void SetParams(float start, float end, float cycle, bool update = false);
void Update(double diff);
void SetParams(double start, double end, double cycle, bool update = false);
void ShouldCycle(bool sc) { m_shouldCycle = sc; }
void SetCycleType(CycleType ct) { m_cycleType = ct; }
float GetVal() { return m_current; }
double GetVal() { return m_current; }
inline operator float () const { return m_current; }
inline operator double () const { return m_current; }
protected:
float m_start, m_end, m_current;
float m_time, m_cycle;
double m_start, m_end, m_current;
double m_time, m_cycle;
bool m_increment, m_shouldCycle;
CycleType m_cycleType;

View file

@ -111,6 +111,7 @@
#include "fragglescript/t_fs.h"
#include "g_levellocals.h"
#include "events.h"
#include "r_utility.h"
EXTERN_CVAR(Bool, hud_althud)
void DrawHUD();
@ -124,7 +125,6 @@ void DrawHUD();
extern void ReadStatistics();
extern void M_RestoreMode ();
extern void M_SetDefaultMode ();
extern void R_ExecuteSetViewSize ();
extern void G_NewInit ();
extern void SetupPlayerClasses ();
extern void HUD_InitHud();
@ -138,6 +138,7 @@ void G_BuildTiccmd (ticcmd_t* cmd);
void D_DoAdvanceDemo ();
void D_AddWildFile (TArray<FString> &wadfiles, const char *pattern);
void D_LoadWadSettings ();
void ParseGLDefs();
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
@ -670,7 +671,7 @@ void D_Display ()
if (viewactive)
{
R_SetFOV (players[consoleplayer].camera && players[consoleplayer].camera->player ?
R_SetFOV (r_viewpoint, players[consoleplayer].camera && players[consoleplayer].camera->player ?
players[consoleplayer].camera->player->FOV : 90.f);
}
@ -697,12 +698,10 @@ void D_Display ()
}
}
RenderTarget = screen;
// change the view size if needed
if (setsizeneeded && StatusBar != NULL)
{
R_ExecuteSetViewSize ();
R_ExecuteSetViewSize (r_viewpoint, r_viewwindow);
}
setmodeneeded = false;
@ -973,7 +972,6 @@ void D_ErrorCleanup ()
menuactive = MENU_Off;
}
insave = false;
Renderer->ErrorCleanup();
}
//==========================================================================
@ -2503,6 +2501,8 @@ void D_DoomMain (void)
StartScreen->Progress ();
ParseGLDefs();
if (!batchrun) Printf ("R_Init: Init %s refresh subsystem.\n", gameinfo.ConfigName.GetChars());
StartScreen->LoadingStatus ("Loading graphics", 0x3f);
R_Init ();

View file

@ -25,7 +25,7 @@
#include "doomtype.h"
#include "doomdef.h"
#include "d_ticcmd.h"
#include "d_protocol.h"
//

View file

@ -36,8 +36,6 @@
#include "c_cvars.h"
EXTERN_CVAR (Float, autoaim)
int D_GenderToInt (const char *gender);
extern const char *GenderNames[3];
@ -49,10 +47,10 @@ void D_UserInfoChanged (FBaseCVar *info);
void D_SendServerInfoChange (const FBaseCVar *cvar, UCVarValue value, ECVarType type);
void D_SendServerFlagChange (const FBaseCVar *cvar, int bitnum, bool set);
void D_DoServerInfoChange (BYTE **stream, bool singlebit);
void D_DoServerInfoChange (uint8_t **stream, bool singlebit);
void D_WriteUserInfoStrings (int player, BYTE **stream, bool compact=false);
void D_ReadUserInfoStrings (int player, BYTE **stream, bool update);
void D_WriteUserInfoStrings (int player, uint8_t **stream, bool compact=false);
void D_ReadUserInfoStrings (int player, uint8_t **stream, bool update);
struct FPlayerColorSet;
void D_GetPlayerColor (int player, float *h, float *s, float *v, FPlayerColorSet **colorset);

View file

@ -175,7 +175,7 @@ void D_GetPlayerColor (int player, float *h, float *s, float *v, FPlayerColorSet
{
userinfo_t *info = &players[player].userinfo;
FPlayerColorSet *colorset = NULL;
uint32 color;
uint32_t color;
int team;
if (players[player].mo != NULL)
@ -485,7 +485,7 @@ int userinfo_t::ColorSetChanged(int setnum)
return setnum;
}
uint32 userinfo_t::ColorChanged(const char *colorname)
uint32_t userinfo_t::ColorChanged(const char *colorname)
{
FColorCVar *color = static_cast<FColorCVar *>((*this)[NAME_Color]);
assert(color != NULL);
@ -496,7 +496,7 @@ uint32 userinfo_t::ColorChanged(const char *colorname)
return *color;
}
uint32 userinfo_t::ColorChanged(uint32 colorval)
uint32_t userinfo_t::ColorChanged(uint32_t colorval)
{
FColorCVar *color = static_cast<FColorCVar *>((*this)[NAME_Color]);
assert(color != NULL);

View file

@ -26,7 +26,7 @@
// Finally, for odd reasons, the player input
// is buffered within the player data struct,
// as commands per game tick.
#include "d_ticcmd.h"
#include "d_protocol.h"
#include "doomstat.h"
#include "a_weapons.h"
@ -308,7 +308,7 @@ struct userinfo_t : TMap<FName,FBaseCVar *>
{
return *static_cast<FIntCVar *>(*CheckKey(NAME_ColorSet));
}
uint32 GetColor() const
uint32_t GetColor() const
{
return *static_cast<FColorCVar *>(*CheckKey(NAME_Color));
}
@ -356,8 +356,8 @@ struct userinfo_t : TMap<FName,FBaseCVar *>
int GenderChanged(const char *gendername);
int PlayerClassChanged(const char *classname);
int PlayerClassNumChanged(int classnum);
uint32 ColorChanged(const char *colorname);
uint32 ColorChanged(uint32 colorval);
uint32_t ColorChanged(const char *colorname);
uint32_t ColorChanged(uint32_t colorval);
int ColorSetChanged(int setnum);
};

View file

@ -33,7 +33,7 @@
*/
#include "i_system.h"
#include "d_ticcmd.h"
#include "d_protocol.h"
#include "d_net.h"
#include "doomdef.h"
#include "doomstat.h"

View file

@ -229,7 +229,15 @@ int UnpackUserCmd (usercmd_t *ucmd, const usercmd_t *basis, uint8_t **stream);
int PackUserCmd (const usercmd_t *ucmd, const usercmd_t *basis, uint8_t **stream);
int WriteUserCmdMessage (usercmd_t *ucmd, const usercmd_t *basis, uint8_t **stream);
struct ticcmd_t;
// The data sampled per tick (single player)
// and transmitted to other peers (multiplayer).
// Mainly movements/button commands per game tick,
// plus a checksum for internal state consistency.
struct ticcmd_t
{
usercmd_t ucmd;
int16_t consistancy; // checks for net game
};
int SkipTicCmd (uint8_t **stream, int count);
void ReadTicCmd (uint8_t **stream, int player, int tic);

View file

@ -1,38 +0,0 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// $Id:$
//
// Copyright (C) 1993-1996 by id Software, Inc.
//
// This source is available for distribution and/or modification
// only under the terms of the DOOM Source Code License as
// published by id Software. All rights reserved.
//
// The source is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
// for more details.
//
// DESCRIPTION:
// System specific interface stuff.
//
//-----------------------------------------------------------------------------
#ifndef __D_TICCMD_H__
#define __D_TICCMD_H__
#include "d_protocol.h"
// The data sampled per tick (single player)
// and transmitted to other peers (multiplayer).
// Mainly movements/button commands per game tick,
// plus a checksum for internal state consistency.
struct ticcmd_t
{
usercmd_t ucmd;
int16_t consistancy; // checks for net game
};
#endif // __D_TICCMD_H__

View file

@ -38,7 +38,6 @@
#include "doomtype.h"
#include "r_data/renderstyle.h"
#include "textures/textures.h"
class FScanner;
class FDecalTemplate;

View file

@ -185,236 +185,7 @@ protected: \
#define _X_VMEXPORT_true(cls) nullptr
#define _X_VMEXPORT_false(cls) nullptr
enum EObjectFlags
{
// GC flags
OF_White0 = 1 << 0, // Object is white (type 0)
OF_White1 = 1 << 1, // Object is white (type 1)
OF_Black = 1 << 2, // Object is black
OF_Fixed = 1 << 3, // Object is fixed (should not be collected)
OF_Rooted = 1 << 4, // Object is soft-rooted
OF_EuthanizeMe = 1 << 5, // Object wants to die
OF_Cleanup = 1 << 6, // Object is now being deleted by the collector
OF_YesReallyDelete = 1 << 7, // Object is being deleted outside the collector, and this is okay, so don't print a warning
OF_WhiteBits = OF_White0 | OF_White1,
OF_MarkBits = OF_WhiteBits | OF_Black,
// Other flags
OF_JustSpawned = 1 << 8, // Thinker was spawned this tic
OF_SerialSuccess = 1 << 9, // For debugging Serialize() calls
OF_Sentinel = 1 << 10, // Object is serving as the sentinel in a ring list
OF_Transient = 1 << 11, // Object should not be archived (references to it will be nulled on disk)
OF_Spawned = 1 << 12, // Thinker was spawned at all (some thinkers get deleted before spawning)
OF_Released = 1 << 13, // Object was released from the GC system and should not be processed by GC function
OF_Abstract = 1 << 14, // Marks a class that cannot be created with new() function at all
OF_UI = 1 << 15, // Marks a class that defaults to VARF_UI for it's fields/methods
OF_Play = 1 << 16, // Marks a class that defaults to VARF_Play for it's fields/methods
};
template<class T> class TObjPtr;
namespace GC
{
enum EGCState
{
GCS_Pause,
GCS_Propagate,
GCS_Sweep,
GCS_Finalize
};
// Number of bytes currently allocated through M_Malloc/M_Realloc.
extern size_t AllocBytes;
// Amount of memory to allocate before triggering a collection.
extern size_t Threshold;
// List of gray objects.
extern DObject *Gray;
// List of every object.
extern DObject *Root;
// Current white value for potentially-live objects.
extern uint32 CurrentWhite;
// Current collector state.
extern EGCState State;
// Position of GC sweep in the list of objects.
extern DObject **SweepPos;
// Size of GC pause.
extern int Pause;
// Size of GC steps.
extern int StepMul;
// Is this the final collection just before exit?
extern bool FinalGC;
// Current white value for known-dead objects.
static inline uint32 OtherWhite()
{
return CurrentWhite ^ OF_WhiteBits;
}
// Frees all objects, whether they're dead or not.
void FreeAll();
// Does one collection step.
void Step();
// Does a complete collection.
void FullGC();
// Handles the grunt work for a write barrier.
void Barrier(DObject *pointing, DObject *pointed);
// Handles a write barrier.
static inline void WriteBarrier(DObject *pointing, DObject *pointed);
// Handles a write barrier for a pointer that isn't inside an object.
static inline void WriteBarrier(DObject *pointed);
// Handles a read barrier.
template<class T> inline T *ReadBarrier(T *&obj)
{
if (obj == NULL || !(obj->ObjectFlags & OF_EuthanizeMe))
{
return obj;
}
return obj = NULL;
}
// Check if it's time to collect, and do a collection step if it is.
static inline void CheckGC()
{
if (AllocBytes >= Threshold)
Step();
}
// Forces a collection to start now.
static inline void StartCollection()
{
Threshold = AllocBytes;
}
// Marks a white object gray. If the object wants to die, the pointer
// is NULLed instead.
void Mark(DObject **obj);
// Marks an array of objects.
void MarkArray(DObject **objs, size_t count);
// For cleanup
void DelSoftRootHead();
// Soft-roots an object.
void AddSoftRoot(DObject *obj);
// Unroots an object.
void DelSoftRoot(DObject *obj);
template<class T> void Mark(T *&obj)
{
union
{
T *t;
DObject *o;
};
o = obj;
Mark(&o);
obj = t;
}
template<class T> void Mark(TObjPtr<T> &obj);
template<class T> void MarkArray(T **obj, size_t count)
{
MarkArray((DObject **)(obj), count);
}
template<class T> void MarkArray(TArray<T> &arr)
{
MarkArray(&arr[0], arr.Size());
}
}
// A template class to help with handling read barriers. It does not
// handle write barriers, because those can be handled more efficiently
// with knowledge of the object that holds the pointer.
template<class T>
class TObjPtr
{
union
{
T pp;
DObject *o;
};
public:
TObjPtr() throw()
{
}
TObjPtr(T q) throw()
: pp(q)
{
}
TObjPtr(const TObjPtr<T> &q) throw()
: pp(q.pp)
{
}
T operator=(T q) throw()
{
return pp = q;
// The caller must now perform a write barrier.
}
operator T() throw()
{
return GC::ReadBarrier(pp);
}
T &operator*()
{
T q = GC::ReadBarrier(pp);
assert(q != NULL);
return *q;
}
T *operator&() throw()
{
// Does not perform a read barrier. The only real use for this is with
// the DECLARE_POINTER macro, where a read barrier would be a very bad
// thing.
return &pp;
}
T operator->() throw()
{
return GC::ReadBarrier(pp);
}
bool operator!=(T u) throw()
{
return GC::ReadBarrier(o) != u;
}
bool operator==(T u) throw()
{
return GC::ReadBarrier(o) == u;
}
template<class U> friend inline void GC::Mark(TObjPtr<U> &obj);
template<class U> friend FSerializer &Serialize(FSerializer &arc, const char *key, TObjPtr<U> &value, TObjPtr<U> *);
friend class DObject;
};
// Use barrier_cast instead of static_cast when you need to cast
// the contents of a TObjPtr to a related type.
template<class T,class U> inline T barrier_cast(TObjPtr<U> &o)
{
return static_cast<T>(static_cast<U>(o));
}
template<class T> inline void GC::Mark(TObjPtr<T> &obj)
{
GC::Mark(&obj.o);
}
#include "dobjgc.h"
class DObject
{
@ -434,7 +205,7 @@ private:
public:
DObject *ObjNext; // Keep track of all allocated objects
DObject *GCNext; // Next object in this collection list
uint32 ObjectFlags; // Flags for this object
uint32_t ObjectFlags; // Flags for this object
void *ScriptVar(FName field, PType *type);

View file

@ -65,7 +65,6 @@
#include "sbar.h"
#include "stats.h"
#include "c_dispatch.h"
#include "p_acs.h"
#include "s_sndseq.h"
#include "r_data/r_interpolate.h"
#include "doomstat.h"
@ -80,6 +79,8 @@
#include "g_levellocals.h"
#include "events.h"
void MarkACSThinker();
// MACROS ------------------------------------------------------------------
/*
@ -331,7 +332,7 @@ static void MarkRoot()
Mark(DIntermissionController::CurrentIntermission);
DThinker::MarkRoots();
FCanvasTextureInfo::Mark();
Mark(DACSThinker::ActiveThinker);
MarkACSThinker();
Mark(E_FirstEventHandler);
Mark(E_LastEventHandler);
for (auto &s : level.sectorPortals)

235
src/dobjgc.h Normal file
View file

@ -0,0 +1,235 @@
#pragma once
#include <stdint.h>
class DObject;
class FSerializer;
enum EObjectFlags
{
// GC flags
OF_White0 = 1 << 0, // Object is white (type 0)
OF_White1 = 1 << 1, // Object is white (type 1)
OF_Black = 1 << 2, // Object is black
OF_Fixed = 1 << 3, // Object is fixed (should not be collected)
OF_Rooted = 1 << 4, // Object is soft-rooted
OF_EuthanizeMe = 1 << 5, // Object wants to die
OF_Cleanup = 1 << 6, // Object is now being deleted by the collector
OF_YesReallyDelete = 1 << 7, // Object is being deleted outside the collector, and this is okay, so don't print a warning
OF_WhiteBits = OF_White0 | OF_White1,
OF_MarkBits = OF_WhiteBits | OF_Black,
// Other flags
OF_JustSpawned = 1 << 8, // Thinker was spawned this tic
OF_SerialSuccess = 1 << 9, // For debugging Serialize() calls
OF_Sentinel = 1 << 10, // Object is serving as the sentinel in a ring list
OF_Transient = 1 << 11, // Object should not be archived (references to it will be nulled on disk)
OF_Spawned = 1 << 12, // Thinker was spawned at all (some thinkers get deleted before spawning)
OF_Released = 1 << 13, // Object was released from the GC system and should not be processed by GC function
OF_Abstract = 1 << 14, // Marks a class that cannot be created with new() function at all
OF_UI = 1 << 15, // Marks a class that defaults to VARF_UI for it's fields/methods
OF_Play = 1 << 16, // Marks a class that defaults to VARF_Play for it's fields/methods
};
template<class T> class TObjPtr;
namespace GC
{
enum EGCState
{
GCS_Pause,
GCS_Propagate,
GCS_Sweep,
GCS_Finalize
};
// Number of bytes currently allocated through M_Malloc/M_Realloc.
extern size_t AllocBytes;
// Amount of memory to allocate before triggering a collection.
extern size_t Threshold;
// List of gray objects.
extern DObject *Gray;
// List of every object.
extern DObject *Root;
// Current white value for potentially-live objects.
extern uint32_t CurrentWhite;
// Current collector state.
extern EGCState State;
// Position of GC sweep in the list of objects.
extern DObject **SweepPos;
// Size of GC pause.
extern int Pause;
// Size of GC steps.
extern int StepMul;
// Is this the final collection just before exit?
extern bool FinalGC;
// Current white value for known-dead objects.
static inline uint32_t OtherWhite()
{
return CurrentWhite ^ OF_WhiteBits;
}
// Frees all objects, whether they're dead or not.
void FreeAll();
// Does one collection step.
void Step();
// Does a complete collection.
void FullGC();
// Handles the grunt work for a write barrier.
void Barrier(DObject *pointing, DObject *pointed);
// Handles a write barrier.
static inline void WriteBarrier(DObject *pointing, DObject *pointed);
// Handles a write barrier for a pointer that isn't inside an object.
static inline void WriteBarrier(DObject *pointed);
// Handles a read barrier.
template<class T> inline T *ReadBarrier(T *&obj)
{
if (obj == NULL || !(obj->ObjectFlags & OF_EuthanizeMe))
{
return obj;
}
return obj = NULL;
}
// Check if it's time to collect, and do a collection step if it is.
static inline void CheckGC()
{
if (AllocBytes >= Threshold)
Step();
}
// Forces a collection to start now.
static inline void StartCollection()
{
Threshold = AllocBytes;
}
// Marks a white object gray. If the object wants to die, the pointer
// is NULLed instead.
void Mark(DObject **obj);
// Marks an array of objects.
void MarkArray(DObject **objs, size_t count);
// For cleanup
void DelSoftRootHead();
// Soft-roots an object.
void AddSoftRoot(DObject *obj);
// Unroots an object.
void DelSoftRoot(DObject *obj);
template<class T> void Mark(T *&obj)
{
union
{
T *t;
DObject *o;
};
o = obj;
Mark(&o);
obj = t;
}
template<class T> void Mark(TObjPtr<T> &obj);
template<class T> void MarkArray(T **obj, size_t count)
{
MarkArray((DObject **)(obj), count);
}
template<class T> void MarkArray(TArray<T> &arr)
{
MarkArray(&arr[0], arr.Size());
}
}
// A template class to help with handling read barriers. It does not
// handle write barriers, because those can be handled more efficiently
// with knowledge of the object that holds the pointer.
template<class T>
class TObjPtr
{
union
{
T pp;
DObject *o;
};
public:
TObjPtr() throw()
{
}
TObjPtr(T q) throw()
: pp(q)
{
}
TObjPtr(const TObjPtr<T> &q) throw()
: pp(q.pp)
{
}
T operator=(T q) throw()
{
return pp = q;
// The caller must now perform a write barrier.
}
operator T() throw()
{
return GC::ReadBarrier(pp);
}
T &operator*()
{
T q = GC::ReadBarrier(pp);
assert(q != NULL);
return *q;
}
T *operator&() throw()
{
// Does not perform a read barrier. The only real use for this is with
// the DECLARE_POINTER macro, where a read barrier would be a very bad
// thing.
return &pp;
}
T operator->() throw()
{
return GC::ReadBarrier(pp);
}
bool operator!=(T u) throw()
{
return GC::ReadBarrier(o) != u;
}
bool operator==(T u) throw()
{
return GC::ReadBarrier(o) == u;
}
template<class U> friend inline void GC::Mark(TObjPtr<U> &obj);
template<class U> friend FSerializer &Serialize(FSerializer &arc, const char *key, TObjPtr<U> &value, TObjPtr<U> *);
friend class DObject;
};
// Use barrier_cast instead of static_cast when you need to cast
// the contents of a TObjPtr to a related type.
template<class T,class U> inline T barrier_cast(TObjPtr<U> &o)
{
return static_cast<T>(static_cast<U>(o));
}
template<class T> inline void GC::Mark(TObjPtr<T> &obj)
{
GC::Mark(&obj.o);
}

View file

@ -645,7 +645,7 @@ void PInt::SetValue(void *addr, int val)
}
else if (Size == 8)
{
*(QWORD *)addr = val;
*(uint64_t *)addr = val;
}
else
{
@ -681,7 +681,7 @@ int PInt::GetValueInt(void *addr) const
}
else if (Size == 8)
{ // truncated output
return (int)*(QWORD *)addr;
return (int)*(uint64_t *)addr;
}
else
{

View file

@ -8,6 +8,13 @@
typedef std::pair<const class PType *, unsigned> FTypeAndOffset;
class PStruct;
// This is intentionally not in vm.h so that this file remains free of DObject pollution.
class VMException : public DObject
{
DECLARE_CLASS(VMException, DObject);
};
#include "vm.h"
// Variable/parameter/field flags -------------------------------------------

View file

@ -359,6 +359,7 @@ enum
BCOMPATF_LINKFROZENPROPS = 1 << 6, // Clearing PROP_TOTALLYFROZEN or PROP_FROZEN also clears the other
BCOMPATF_FLOATBOB = 1 << 8, // Use Hexen's original method of preventing floatbobbing items from falling down
BCOMPATF_NOSLOPEID = 1 << 9, // disable line IDs on slopes.
BCOMPATF_CLIPMIDTEX = 1 << 10, // Always Clip midtex's in the software renderer (required to run certain GZDoom maps)
};
// phares 3/20/98:

View file

@ -122,8 +122,8 @@ extern bool noblit;
extern int viewwindowx;
extern int viewwindowy;
extern "C" int viewheight;
extern "C" int viewwidth;
extern int viewheight;
extern int viewwidth;

View file

@ -118,9 +118,9 @@ enum
struct PalEntry
{
PalEntry () {}
PalEntry (uint32 argb) { d = argb; }
operator uint32 () const { return d; }
PalEntry &operator= (uint32 other) { d = other; return *this; }
PalEntry (uint32_t argb) { d = argb; }
operator uint32_t () const { return d; }
PalEntry &operator= (uint32_t other) { d = other; return *this; }
PalEntry InverseColor() const { PalEntry nc; nc.a = a; nc.r = 255 - r; nc.g = 255 - g; nc.b = 255 - b; return nc; }
#ifdef __BIG_ENDIAN__
PalEntry (uint8_t ir, uint8_t ig, uint8_t ib) : a(0), r(ir), g(ig), b(ib) {}
@ -131,7 +131,7 @@ struct PalEntry
{
uint8_t a,r,g,b;
};
uint32 d;
uint32_t d;
};
#else
PalEntry (uint8_t ir, uint8_t ig, uint8_t ib) : b(ib), g(ig), r(ir), a(0) {}
@ -142,7 +142,7 @@ struct PalEntry
{
uint8_t b,g,r,a;
};
uint32 d;
uint32_t d;
};
#endif
};

View file

@ -1,26 +0,0 @@
enum
{
EX_Return = 0x00,
EX_EndFuncParms = 0x01,
EX_ByteConst = 0x02,
EX_WordConst = 0x03,
EX_DWordConst = 0x04,
EX_FixedConst = 0x05, // To become FloatConst whenever I move to floats
EX_StringConst = 0x06,
EX_Extended1 = 0xF1,
EX_Extended2 = 0xF2,
EX_Extended3 = 0xF3,
EX_Extended4 = 0xF4,
EX_Extended5 = 0xF5,
EX_Extended6 = 0xF6,
EX_Extended7 = 0xF7,
EX_Extended8 = 0xF8,
EX_Extended9 = 0xF9,
EX_ExtendedA = 0xFA,
EX_ExtendedB = 0xFB,
EX_ExtendedC = 0xFC,
EX_ExtendedD = 0xFD,
EX_ExtendedE = 0xFE,
EX_ExtendedF = 0xFF
};

View file

@ -183,7 +183,7 @@ void DThinker::SerializeThinkers(FSerializer &arc, bool hubLoad)
int size = arc.ArraySize();
for (int j = 0; j < size; j++)
{
DThinker *thinker;
DThinker *thinker = nullptr;
arc(nullptr, thinker);
if (thinker != nullptr)
{

View file

@ -776,12 +776,12 @@ void DStaticEventHandler::WorldTick()
static FRenderEvent E_SetupRenderEvent()
{
FRenderEvent e;
e.ViewPos = ::ViewPos;
e.ViewAngle = ::ViewAngle;
e.ViewPitch = ::ViewPitch;
e.ViewRoll = ::ViewRoll;
e.FracTic = ::r_TicFracF;
e.Camera = ::camera;
e.ViewPos = r_viewpoint.Pos;
e.ViewAngle = r_viewpoint.Angles.Yaw;
e.ViewPitch = r_viewpoint.Angles.Pitch;
e.ViewRoll = r_viewpoint.Angles.Roll;
e.FracTic = r_viewpoint.TicFrac;
e.Camera = r_viewpoint.camera;
return e;
}

View file

@ -28,6 +28,9 @@
#include "f_wipe.h"
#include "c_cvars.h"
#include "templates.h"
#include "v_palette.h"
EXTERN_CVAR(Bool, r_blendmethod)
//
// SCREEN WIPE PACKAGE
@ -42,7 +45,7 @@ static int *y;
// [RH] Fire Wipe
#define FIREWIDTH 64
#define FIREHEIGHT 64
static BYTE *burnarray;
static uint8_t *burnarray;
static int density;
static int burntime;
@ -78,7 +81,7 @@ bool wipe_initMelt (int ticks)
int i, r;
// copy start screen to main screen
screen->DrawBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (BYTE *)wipe_scr_start);
screen->DrawBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (uint8_t *)wipe_scr_start);
// makes this wipe faster (in theory)
// to have stuff in column-major format
@ -162,21 +165,21 @@ bool wipe_exitMelt (int ticks)
bool wipe_initBurn (int ticks)
{
burnarray = new BYTE[FIREWIDTH * (FIREHEIGHT+5)];
burnarray = new uint8_t[FIREWIDTH * (FIREHEIGHT+5)];
memset (burnarray, 0, FIREWIDTH * (FIREHEIGHT+5));
density = 4;
burntime = 0;
return 0;
}
int wipe_CalcBurn (BYTE *burnarray, int width, int height, int density)
int wipe_CalcBurn (uint8_t *burnarray, int width, int height, int density)
{
// This is a modified version of the fire that was once used
// on the player setup menu.
static int voop;
int a, b;
BYTE *from;
uint8_t *from;
// generator
from = &burnarray[width * height];
@ -195,10 +198,10 @@ int wipe_CalcBurn (BYTE *burnarray, int width, int height, int density)
from = burnarray;
for (b = 0; b <= height; b += 2)
{
BYTE *pixel = from;
uint8_t *pixel = from;
// special case: first pixel on line
BYTE *p = pixel + (width << 1);
uint8_t *p = pixel + (width << 1);
unsigned int top = *p + *(p + width - 1) + *(p + 1);
unsigned int bottom = *(pixel + (width << 2));
unsigned int c1 = (top + bottom) >> 2;
@ -271,48 +274,89 @@ bool wipe_doBurn (int ticks)
// Draw the screen
int xstep, ystep, firex, firey;
int x, y;
BYTE *to, *fromold, *fromnew;
uint8_t *to, *fromold, *fromnew;
const int SHIFT = 16;
xstep = (FIREWIDTH << SHIFT) / SCREENWIDTH;
ystep = (FIREHEIGHT << SHIFT) / SCREENHEIGHT;
to = screen->GetBuffer();
fromold = (BYTE *)wipe_scr_start;
fromnew = (BYTE *)wipe_scr_end;
fromold = (uint8_t *)wipe_scr_start;
fromnew = (uint8_t *)wipe_scr_end;
for (y = 0, firey = 0; y < SCREENHEIGHT; y++, firey += ystep)
if (!r_blendmethod)
{
for (x = 0, firex = 0; x < SCREENWIDTH; x++, firex += xstep)
for (y = 0, firey = 0; y < SCREENHEIGHT; y++, firey += ystep)
{
int fglevel;
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;
DWORD *fg2rgb = Col2RGB8[fglevel];
DWORD *bg2rgb = Col2RGB8[bglevel];
DWORD fg = fg2rgb[fromnew[x]];
DWORD bg = bg2rgb[fromold[x]];
fg = (fg+bg) | 0x1f07c1f;
to[x] = RGB32k.All[fg & (fg>>15)];
done = false;
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;
}
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);
}
@ -335,31 +379,53 @@ bool wipe_doFade (int ticks)
fade += ticks * 2;
if (fade > 64)
{
screen->DrawBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (BYTE *)wipe_scr_end);
screen->DrawBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (uint8_t *)wipe_scr_end);
return true;
}
else
{
int x, y;
int bglevel = 64 - fade;
DWORD *fg2rgb = Col2RGB8[fade];
DWORD *bg2rgb = Col2RGB8[bglevel];
BYTE *fromnew = (BYTE *)wipe_scr_end;
BYTE *fromold = (BYTE *)wipe_scr_start;
BYTE *to = screen->GetBuffer();
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;
for (y = 0; y < SCREENHEIGHT; y++)
if (!r_blendmethod)
{
for (x = 0; x < SCREENWIDTH; x++)
for (y = 0; y < SCREENHEIGHT; y++)
{
DWORD fg = fg2rgb[fromnew[x]];
DWORD bg = bg2rgb[fromold[x]];
fg = (fg+bg) | 0x1f07c1f;
to[x] = RGB32k.All[fg & (fg>>15)];
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;
}
fromnew += SCREENWIDTH;
fromold += SCREENWIDTH;
to += SCREENPITCH;
}
}
return false;
@ -382,12 +448,15 @@ static bool (*wipes[])(int) =
// 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, (BYTE *)wipe_scr_start);
screen->GetBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (uint8_t *)wipe_scr_start);
return true;
}
return false;
@ -395,11 +464,15 @@ bool wipe_StartScreen (int type)
void wipe_EndScreen (void)
{
if (screen->IsBgra())
return;
if (CurrentWipeType)
{
wipe_scr_end = new short[SCREENWIDTH * SCREENHEIGHT / 2];
screen->GetBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (BYTE *)wipe_scr_end);
screen->DrawBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (BYTE *)wipe_scr_start); // restore start scr.
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);
}
@ -410,6 +483,9 @@ bool wipe_ScreenWipe (int ticks)
{
bool rc;
if (screen->IsBgra())
return true;
if (CurrentWipeType == wipe_None)
return true;
@ -423,6 +499,9 @@ bool wipe_ScreenWipe (int ticks)
// Final things for the wipe
void wipe_Cleanup()
{
if (screen->IsBgra())
return;
if (wipe_scr_start != NULL)
{
delete[] wipe_scr_start;

View file

@ -34,7 +34,7 @@ void wipe_Cleanup ();
// The buffer must have an additional 5 rows not included in height
// to use for a seeding area.
int wipe_CalcBurn (BYTE *buffer, int width, int height, int density);
int wipe_CalcBurn (uint8_t *buffer, int width, int height, int density);
enum
{

View file

@ -33,9 +33,7 @@
**
*/
#ifdef _WIN32
#define USE_WINDOWS_DWORD
#endif
// This also pulls in windows.h
#include "LzmaDec.h"
#include "files.h"
@ -392,7 +390,7 @@ ISzAlloc g_Alloc = { SzAlloc, SzFree };
FileReaderLZMA::FileReaderLZMA (FileReader &file, size_t uncompressed_size, bool zip)
: File(file), SawEOF(false)
{
BYTE header[4 + LZMA_PROPS_SIZE];
uint8_t header[4 + LZMA_PROPS_SIZE];
int err;
assert(zip == true);

View file

@ -71,6 +71,7 @@
#include "r_utility.h"
#include "math/cmath.h"
#include "g_levellocals.h"
#include "actorinlines.h"
static FRandom pr_script("FScript");

View file

@ -45,7 +45,6 @@
#include "m_random.h"
#include "m_crc32.h"
#include "i_system.h"
#include "i_input.h"
#include "p_saveg.h"
#include "p_tick.h"
#include "d_main.h"
@ -234,7 +233,7 @@ FString shotfile;
AActor* bodyque[BODYQUESIZE];
int bodyqueslot;
void R_ExecuteSetViewSize (void);
void R_ExecuteSetViewSize (FViewWindow &viewwindow);
FString savename;
FString BackupSaveName;

9
src/g_input.h Normal file
View file

@ -0,0 +1,9 @@
#pragma once
// These were in i_input.h, which differed between platforms and on Windows caused problems with its
// inclusion of system specific data, so it has been separated into this platform independent file.
void I_PutInClipboard (const char *str);
FString I_GetFromClipboard (bool use_primary_selection);
void I_SetMouseCapture();
void I_ReleaseMouseCapture();

View file

@ -9,7 +9,16 @@
class player_t;
class FConfigFile;
struct visstyle_t;
// This encapsulates the fields of vissprite_t that can be altered by AlterWeaponSprite
struct visstyle_t
{
bool Invert;
float Alpha;
ERenderStyle RenderStyle;
};
/************************************************************************/
/* Class definitions */

View file

@ -91,6 +91,7 @@
#include "g_hub.h"
#include "g_levellocals.h"
#include "actorinlines.h"
#include <string.h>
@ -1389,7 +1390,7 @@ void G_InitLevelLocals ()
level_info_t *info;
BaseBlendA = 0.0f; // Remove underwater blend effect, if any
NormalLight.Maps = realcolormaps;
NormalLight.Maps = realcolormaps.Maps;
// [BB] Instead of just setting the color, we also have to reset Desaturate and build the lights.
NormalLight.ChangeColor (PalEntry (255, 255, 255), 0);
@ -1417,6 +1418,7 @@ void G_InitLevelLocals ()
R_SetDefaultColormap (info->FadeTable);
if (strnicmp (info->FadeTable, "COLORMAP", 8) != 0)
{
level.fadeto = 0xff939393; //[SP] Hexen True-color compatibility, just use gray.
level.flags |= LEVEL_HASFADETABLE;
}
/*
@ -1484,7 +1486,7 @@ bool FLevelLocals::IsJumpingAllowed() const
return false;
if (dmflags & DF_YES_JUMP)
return true;
return !(level.flags & LEVEL_JUMP_NO);
return !(flags & LEVEL_JUMP_NO);
}
//==========================================================================
@ -1498,7 +1500,7 @@ bool FLevelLocals::IsCrouchingAllowed() const
return false;
if (dmflags & DF_YES_CROUCH)
return true;
return !(level.flags & LEVEL_CROUCH_NO);
return !(flags & LEVEL_CROUCH_NO);
}
//==========================================================================
@ -1512,7 +1514,7 @@ bool FLevelLocals::IsFreelookAllowed() const
return false;
if (dmflags & DF_YES_FREELOOK)
return true;
return !(level.flags & LEVEL_FREELOOK_NO);
return !(flags & LEVEL_FREELOOK_NO);
}
//==========================================================================

View file

@ -35,16 +35,12 @@
#define __G_LEVEL_H__
#include "doomtype.h"
#include "doomdef.h"
#include "sc_man.h"
#include "s_sound.h"
#include "p_acs.h"
#include "textures/textures.h"
#include "resourcefiles/file_zip.h"
struct level_info_t;
struct cluster_info_t;
class FScanner;
class FSerializer;
#if defined(_MSC_VER)
#pragma section(".yreg$u",read)
@ -55,6 +51,24 @@ class FScanner;
#define GCC_YSEG __attribute__((section(SECTION_YREG))) __attribute__((used))
#endif
// The structure used to control scripts between maps
struct acsdefered_t
{
enum EType
{
defexecute,
defexealways,
defsuspend,
defterminate
} type;
int script;
int args[3];
int playernum;
};
FSerializer &Serialize(FSerializer &arc, const char *key, acsdefered_t &defer, acsdefered_t *def);
struct FIntermissionDescriptor;
struct FIntermissionAction;
@ -175,7 +189,7 @@ enum ELevelFlags : unsigned int
LEVEL_CHANGEMAPCHEAT = 0x40000000, // Don't display cluster messages
LEVEL_VISITED = 0x80000000, // Used for intermission map
// The flags QWORD is now split into 2 DWORDs
// The flags uint64_t is now split into 2 DWORDs
LEVEL2_RANDOMPLAYERSTARTS = 0x00000001, // Select single player starts randomnly (no voodoo dolls)
LEVEL2_ALLMAP = 0x00000002, // The player picked up a map on this level
@ -223,7 +237,8 @@ enum ELevelFlags : unsigned int
// More flags!
LEVEL3_FORCEFAKECONTRAST = 0x00000001, // forces fake contrast even with fog enabled
LEVEL3_REMOVEITEMS = 0x00000002, // kills all INVBAR items on map change.
LEVEL3_REMOVEITEMS = 0x00000002, // kills all INVBAR items on map change.
LEVEL3_ATTENUATE = 0x00000004, // attenuate lights?
};
@ -339,7 +354,7 @@ struct level_info_t
TArray<FSpecialAction> specialactions;
TArray<FSoundID> PrecacheSounds;
TArray<int> PrecacheSounds;
TArray<FString> PrecacheTextures;
TArray<FName> PrecacheClasses;

View file

@ -2,6 +2,7 @@
#include "g_level.h"
#include "r_defs.h"
#include "portal.h"
struct FLevelLocals
{
@ -136,3 +137,56 @@ inline int sector_t::GetOppositePortalGroup(int plane)
{
return level.sectorPortals[Portals[plane]].mDestination->PortalGroup;
}
inline bool sector_t::PortalBlocksView(int plane)
{
if (GetPortalType(plane) != PORTS_LINKEDPORTAL) return false;
return !!(planes[plane].Flags & (PLANEF_NORENDER | PLANEF_DISABLED | PLANEF_OBSTRUCTED));
}
inline bool sector_t::PortalBlocksSight(int plane)
{
return PLANEF_LINKED != (planes[plane].Flags & (PLANEF_NORENDER | PLANEF_NOPASS | PLANEF_DISABLED | PLANEF_OBSTRUCTED | PLANEF_LINKED));
}
inline bool sector_t::PortalBlocksMovement(int plane)
{
return PLANEF_LINKED != (planes[plane].Flags & (PLANEF_NOPASS | PLANEF_DISABLED | PLANEF_OBSTRUCTED | PLANEF_LINKED));
}
inline bool sector_t::PortalBlocksSound(int plane)
{
return PLANEF_LINKED != (planes[plane].Flags & (PLANEF_BLOCKSOUND | PLANEF_DISABLED | PLANEF_OBSTRUCTED | PLANEF_LINKED));
}
inline bool sector_t::PortalIsLinked(int plane)
{
return (GetPortalType(plane) == PORTS_LINKEDPORTAL);
}
inline FLinePortal *line_t::getPortal() const
{
return portalindex >= linePortals.Size() ? (FLinePortal*)NULL : &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);
}
// 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);
}
inline line_t *line_t::getPortalDestination() const
{
return portalindex >= linePortals.Size() ? (line_t*)NULL : linePortals[portalindex].mDestination;
}
inline int line_t::getPortalAlignment() const
{
return portalindex >= linePortals.Size() ? 0 : linePortals[portalindex].mAlign;
}

View file

@ -1216,7 +1216,6 @@ DEFINE_MAP_OPTION(hazardflash, true)
info->hazardflash = V_GetColor(NULL, parse.sc);
}
//==========================================================================
//
// All flag based map options

View file

@ -21,3 +21,10 @@
#include <limits>
#include <memory>
#include <tuple>
#include <vector>
#include <utility>
// These two headers get included nearly everywhere so it doesn't matter if changing them forces a few more recompiles.
// The overall savings from PCHing them are more significant.
#include "tarray.h"
#include "zstring.h"

View file

@ -72,6 +72,7 @@
#include "doomstat.h"
#include "serializer.h"
#include "g_levellocals.h"
#include "actorinlines.h"
#include "gl/renderer/gl_renderer.h"
@ -81,8 +82,14 @@
#include "gl/utility/gl_templates.h"
#include "gl/system//gl_interface.h"
EXTERN_CVAR(Int, vid_renderer)
CUSTOM_CVAR (Bool, gl_lights, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
{
if (self) AActor::RecreateAllAttachedLights();
else AActor::DeleteAllAttachedLights();
}
CVAR (Bool, gl_attachedlights, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
//==========================================================================
//
@ -233,10 +240,6 @@ void ADynamicLight::Deactivate(AActor *activator)
//==========================================================================
void ADynamicLight::Tick()
{
if (vid_renderer == 0)
{
return;
}
if (IsOwned())
{
if (!target || !target->state)
@ -748,11 +751,11 @@ void ADynamicLight::UnlinkLight ()
if (owned && target != NULL)
{
// Delete reference in owning actor
for(int c=target->dynamiclights.Size()-1; c>=0; c--)
for(int c=target->AttachedLights.Size()-1; c>=0; c--)
{
if (target->dynamiclights[c] == this)
if (target->AttachedLights[c] == this)
{
target->dynamiclights.Delete(c);
target->AttachedLights.Delete(c);
break;
}
}
@ -769,23 +772,6 @@ void ADynamicLight::OnDestroy()
}
//==========================================================================
//
// Needed for garbage collection
//
//==========================================================================
size_t AActor::PropagateMark()
{
for (unsigned i=0; i<dynamiclights.Size(); i++)
{
GC::Mark(dynamiclights[i]);
}
return Super::PropagateMark();
}
CCMD(listlights)
{
int walls, sectors, subsecs;

123
src/g_shared/a_dynlight.h Normal file
View file

@ -0,0 +1,123 @@
#pragma once
#include "c_cvars.h"
#include "actor.h"
#include "cycler.h"
EXTERN_CVAR(Bool, gl_lights)
EXTERN_CVAR(Bool, gl_attachedlights)
class ADynamicLight;
class FSerializer;
class FLightDefaults;
enum
{
LIGHT_RED = 0,
LIGHT_GREEN = 1,
LIGHT_BLUE = 2,
LIGHT_INTENSITY = 3,
LIGHT_SECONDARY_INTENSITY = 4,
LIGHT_SCALE = 3,
};
// This is as good as something new - and it can be set directly in the ActorInfo!
#define MF4_SUBTRACTIVE MF4_MISSILEEVENMORE
#define MF4_ADDITIVE MF4_MISSILEMORE
#define MF4_DONTLIGHTSELF MF4_SEESDAGGERS
#define MF4_ATTENUATE MF4_INCOMBAT
enum ELightType
{
PointLight,
PulseLight,
FlickerLight,
RandomFlickerLight,
SectorLight,
SpotLight,
ColorPulseLight,
ColorFlickerLight,
RandomColorFlickerLight
};
struct FLightNode
{
FLightNode ** prevTarget;
FLightNode * nextTarget;
FLightNode ** prevLight;
FLightNode * nextLight;
ADynamicLight * lightsource;
union
{
side_t * targLine;
subsector_t * targSubsector;
void * targ;
};
};
//
// Base class
//
// [CO] I merged everything together in this one class so that I don't have
// to create and re-create an excessive amount of objects
//
class ADynamicLight : public AActor
{
friend class FLightDefaults;
DECLARE_CLASS (ADynamicLight, AActor)
public:
virtual void Tick();
void Serialize(FSerializer &arc);
void PostSerialize();
uint8_t GetRed() const { return args[LIGHT_RED]; }
uint8_t GetGreen() const { return args[LIGHT_GREEN]; }
uint8_t GetBlue() const { return args[LIGHT_BLUE]; }
float GetRadius() const { return (IsActive() ? m_currentRadius * 2.f : 0.f); }
void LinkLight();
void UnlinkLight();
size_t PointerSubstitution (DObject *old, DObject *notOld);
void BeginPlay();
void SetOrigin (double x, double y, double z, bool moving = false);
void PostBeginPlay();
void OnDestroy() override;
void Activate(AActor *activator);
void Deactivate(AActor *activator);
void SetOffset(const DVector3 &pos);
void UpdateLocation();
bool IsOwned() const { return owned; }
bool IsActive() const { return !(flags2&MF2_DORMANT); }
bool IsSubtractive() { return !!(flags4&MF4_SUBTRACTIVE); }
bool IsAdditive() { return !!(flags4&MF4_ADDITIVE); }
FState *targetState;
FLightNode * touching_sides;
FLightNode * touching_subsectors;
FLightNode * touching_sector;
private:
double DistToSeg(const DVector3 &pos, seg_t *seg);
void CollectWithinRadius(const DVector3 &pos, subsector_t *subSec, float radius);
protected:
DVector3 m_off;
float m_currentRadius;
unsigned int m_lastUpdate;
FCycler m_cycler;
subsector_t * subsector;
public:
int m_tickCount;
uint8_t lightflags;
uint8_t lighttype;
bool owned;
bool halo;
uint8_t color2[3];
bool visibletoplayer;
bool swapped;
int bufferindex;
};

View file

@ -1,5 +1,5 @@
/*
** gl_dynlight.cpp
** _gl_dynlight.cpp
** Light definitions for actors.
**
**---------------------------------------------------------------------------
@ -50,15 +50,9 @@
#include "d_dehacked.h"
#include "v_text.h"
#include "g_levellocals.h"
#include "a_dynlight.h"
#include "gl/dynlights/gl_dynlight.h"
#include "gl/textures/gl_skyboxtexture.h"
#include "gl/utility/gl_clock.h"
#include "gl/utility/gl_convert.h"
#include "gl/data/gl_data.h"
#include "gl/system//gl_interface.h"
int ScriptDepth;
void gl_InitGlow(FScanner &sc);
void gl_ParseBrightmap(FScanner &sc, int);
@ -156,7 +150,7 @@ protected:
bool m_swapped = false;
};
TArray<FLightDefaults *> LightDefaults;
TDeletingArray<FLightDefaults *> LightDefaults;
//-----------------------------------------------------------------------------
//
@ -205,7 +199,7 @@ void FLightDefaults::ApplyProperties(ADynamicLight * light) const
else light->m_cycler.SetParams(float(light->args[LIGHT_INTENSITY]), float(light->args[LIGHT_SECONDARY_INTENSITY]), pulseTime, oldtype == PulseLight);
light->m_cycler.ShouldCycle(true);
light->m_cycler.SetCycleType(CYCLE_Sin);
light->m_currentRadius = light->m_cycler.GetVal();
light->m_currentRadius = (float)light->m_cycler.GetVal();
if (light->m_currentRadius <= 0) light->m_currentRadius = 1;
light->swapped = m_swapped;
}
@ -214,7 +208,7 @@ void FLightDefaults::ApplyProperties(ADynamicLight * light) const
{
case 0: light->flags4 &= ~MF4_ATTENUATE; break;
case 1: light->flags4 |= MF4_ATTENUATE; break;
default: if (glset.attenuate) light->flags4 |= MF4_ATTENUATE; else light->flags4 &= ~MF4_ATTENUATE; break;
default: if (level.flags3 & LEVEL3_ATTENUATE) light->flags4 |= MF4_ATTENUATE; else light->flags4 &= ~MF4_ATTENUATE; break;
}
}
@ -277,7 +271,7 @@ extern int ScriptDepth;
//
//==========================================================================
inline float gl_ParseFloat(FScanner &sc)
inline float ParseFloat(FScanner &sc)
{
sc.GetFloat();
@ -285,7 +279,7 @@ inline float gl_ParseFloat(FScanner &sc)
}
inline int gl_ParseInt(FScanner &sc)
inline int ParseInt(FScanner &sc)
{
sc.GetNumber();
@ -293,7 +287,7 @@ inline int gl_ParseInt(FScanner &sc)
}
inline char *gl_ParseString(FScanner &sc)
inline char *ParseString(FScanner &sc)
{
sc.GetString();
@ -301,16 +295,16 @@ inline char *gl_ParseString(FScanner &sc)
}
void gl_ParseTriple(FScanner &sc, float floatVal[3])
static void ParseTriple(FScanner &sc, float floatVal[3])
{
for (int i = 0; i < 3; i++)
{
floatVal[i] = gl_ParseFloat(sc);
floatVal[i] = ParseFloat(sc);
}
}
void gl_AddLightDefaults(FLightDefaults *defaults)
static void AddLightDefaults(FLightDefaults *defaults)
{
FLightDefaults *temp;
unsigned int i;
@ -327,7 +321,8 @@ void gl_AddLightDefaults(FLightDefaults *defaults)
}
}
if (gl.legacyMode && (defaults->GetAttenuate()))
// If the current renderer cannot handle attenuated lights we need to reduce the radius here to account for the far more bright lights this would create.
if (/*!Renderer->CanAttenuate() &&*/ (defaults->GetAttenuate()))
{
defaults->SetArg(LIGHT_INTENSITY, defaults->GetArg(LIGHT_INTENSITY) * 2 / 3);
defaults->SetArg(LIGHT_SECONDARY_INTENSITY, defaults->GetArg(LIGHT_SECONDARY_INTENSITY) * 2 / 3);
@ -343,7 +338,7 @@ void gl_AddLightDefaults(FLightDefaults *defaults)
//
//-----------------------------------------------------------------------------
void gl_ParsePointLight(FScanner &sc)
static void ParsePointLight(FScanner &sc)
{
int type;
float floatTriple[3];
@ -373,39 +368,39 @@ void gl_ParsePointLight(FScanner &sc)
ScriptDepth--;
break;
case LIGHTTAG_COLOR:
gl_ParseTriple(sc, floatTriple);
ParseTriple(sc, floatTriple);
defaults->SetArg(LIGHT_RED, clamp<int>((int)(floatTriple[0] * 255), 0, 255));
defaults->SetArg(LIGHT_GREEN, clamp<int>((int)(floatTriple[1] * 255), 0, 255));
defaults->SetArg(LIGHT_BLUE, clamp<int>((int)(floatTriple[2] * 255), 0, 255));
break;
case LIGHTTAG_OFFSET:
gl_ParseTriple(sc, floatTriple);
ParseTriple(sc, floatTriple);
defaults->SetOffset(floatTriple);
break;
case LIGHTTAG_SIZE:
intVal = clamp<int>(gl_ParseInt(sc), 1, 1024);
intVal = clamp<int>(ParseInt(sc), 1, 1024);
defaults->SetArg(LIGHT_INTENSITY, intVal);
break;
case LIGHTTAG_SUBTRACTIVE:
defaults->SetSubtractive(gl_ParseInt(sc) != 0);
defaults->SetSubtractive(ParseInt(sc) != 0);
break;
case LIGHTTAG_ADDITIVE:
defaults->SetAdditive(gl_ParseInt(sc) != 0);
defaults->SetAdditive(ParseInt(sc) != 0);
break;
case LIGHTTAG_HALO:
defaults->SetHalo(gl_ParseInt(sc) != 0);
defaults->SetHalo(ParseInt(sc) != 0);
break;
case LIGHTTAG_DONTLIGHTSELF:
defaults->SetDontLightSelf(gl_ParseInt(sc) != 0);
defaults->SetDontLightSelf(ParseInt(sc) != 0);
break;
case LIGHTTAG_ATTENUATE:
defaults->SetAttenuate(gl_ParseInt(sc) != 0);
defaults->SetAttenuate(ParseInt(sc) != 0);
break;
default:
sc.ScriptError("Unknown tag: %s\n", sc.String);
}
}
gl_AddLightDefaults(defaults);
AddLightDefaults(defaults);
}
else
{
@ -420,7 +415,7 @@ void gl_ParsePointLight(FScanner &sc)
//
//-----------------------------------------------------------------------------
void gl_ParsePulseLight(FScanner &sc)
static void ParsePulseLight(FScanner &sc)
{
int type;
float floatVal, floatTriple[3];
@ -450,38 +445,38 @@ void gl_ParsePulseLight(FScanner &sc)
ScriptDepth--;
break;
case LIGHTTAG_COLOR:
gl_ParseTriple(sc, floatTriple);
ParseTriple(sc, floatTriple);
defaults->SetArg(LIGHT_RED, clamp<int>((int)(floatTriple[0] * 255), 0, 255));
defaults->SetArg(LIGHT_GREEN, clamp<int>((int)(floatTriple[1] * 255), 0, 255));
defaults->SetArg(LIGHT_BLUE, clamp<int>((int)(floatTriple[2] * 255), 0, 255));
break;
case LIGHTTAG_OFFSET:
gl_ParseTriple(sc, floatTriple);
ParseTriple(sc, floatTriple);
defaults->SetOffset(floatTriple);
break;
case LIGHTTAG_SIZE:
intVal = clamp<int>(gl_ParseInt(sc), 1, 1024);
intVal = clamp<int>(ParseInt(sc), 1, 1024);
defaults->SetArg(LIGHT_INTENSITY, intVal);
break;
case LIGHTTAG_SECSIZE:
intVal = clamp<int>(gl_ParseInt(sc), 1, 1024);
intVal = clamp<int>(ParseInt(sc), 1, 1024);
defaults->SetArg(LIGHT_SECONDARY_INTENSITY, intVal);
break;
case LIGHTTAG_INTERVAL:
floatVal = gl_ParseFloat(sc);
floatVal = ParseFloat(sc);
defaults->SetParameter(floatVal * TICRATE);
break;
case LIGHTTAG_SUBTRACTIVE:
defaults->SetSubtractive(gl_ParseInt(sc) != 0);
defaults->SetSubtractive(ParseInt(sc) != 0);
break;
case LIGHTTAG_HALO:
defaults->SetHalo(gl_ParseInt(sc) != 0);
defaults->SetHalo(ParseInt(sc) != 0);
break;
case LIGHTTAG_DONTLIGHTSELF:
defaults->SetDontLightSelf(gl_ParseInt(sc) != 0);
defaults->SetDontLightSelf(ParseInt(sc) != 0);
break;
case LIGHTTAG_ATTENUATE:
defaults->SetAttenuate(gl_ParseInt(sc) != 0);
defaults->SetAttenuate(ParseInt(sc) != 0);
break;
default:
sc.ScriptError("Unknown tag: %s\n", sc.String);
@ -489,7 +484,7 @@ void gl_ParsePulseLight(FScanner &sc)
}
defaults->OrderIntensities();
gl_AddLightDefaults(defaults);
AddLightDefaults(defaults);
}
else
{
@ -504,7 +499,7 @@ void gl_ParsePulseLight(FScanner &sc)
//
//-----------------------------------------------------------------------------
void gl_ParseFlickerLight(FScanner &sc)
void ParseFlickerLight(FScanner &sc)
{
int type;
float floatVal, floatTriple[3];
@ -534,45 +529,45 @@ void gl_ParseFlickerLight(FScanner &sc)
ScriptDepth--;
break;
case LIGHTTAG_COLOR:
gl_ParseTriple(sc, floatTriple);
ParseTriple(sc, floatTriple);
defaults->SetArg(LIGHT_RED, clamp<int>((int)(floatTriple[0] * 255), 0, 255));
defaults->SetArg(LIGHT_GREEN, clamp<int>((int)(floatTriple[1] * 255), 0, 255));
defaults->SetArg(LIGHT_BLUE, clamp<int>((int)(floatTriple[2] * 255), 0, 255));
break;
case LIGHTTAG_OFFSET:
gl_ParseTriple(sc, floatTriple);
ParseTriple(sc, floatTriple);
defaults->SetOffset(floatTriple);
break;
case LIGHTTAG_SIZE:
intVal = clamp<int>(gl_ParseInt(sc), 1, 1024);
intVal = clamp<int>(ParseInt(sc), 1, 1024);
defaults->SetArg(LIGHT_INTENSITY, intVal);
break;
case LIGHTTAG_SECSIZE:
intVal = clamp<int>(gl_ParseInt(sc), 1, 1024);
intVal = clamp<int>(ParseInt(sc), 1, 1024);
defaults->SetArg(LIGHT_SECONDARY_INTENSITY, intVal);
break;
case LIGHTTAG_CHANCE:
floatVal = gl_ParseFloat(sc);
floatVal = ParseFloat(sc);
defaults->SetParameter(floatVal*360.);
break;
case LIGHTTAG_SUBTRACTIVE:
defaults->SetSubtractive(gl_ParseInt(sc) != 0);
defaults->SetSubtractive(ParseInt(sc) != 0);
break;
case LIGHTTAG_HALO:
defaults->SetHalo(gl_ParseInt(sc) != 0);
defaults->SetHalo(ParseInt(sc) != 0);
break;
case LIGHTTAG_DONTLIGHTSELF:
defaults->SetDontLightSelf(gl_ParseInt(sc) != 0);
defaults->SetDontLightSelf(ParseInt(sc) != 0);
break;
case LIGHTTAG_ATTENUATE:
defaults->SetAttenuate(gl_ParseInt(sc) != 0);
defaults->SetAttenuate(ParseInt(sc) != 0);
break;
default:
sc.ScriptError("Unknown tag: %s\n", sc.String);
}
}
defaults->OrderIntensities();
gl_AddLightDefaults(defaults);
AddLightDefaults(defaults);
}
else
{
@ -587,7 +582,7 @@ void gl_ParseFlickerLight(FScanner &sc)
//
//-----------------------------------------------------------------------------
void gl_ParseFlickerLight2(FScanner &sc)
void ParseFlickerLight2(FScanner &sc)
{
int type;
float floatVal, floatTriple[3];
@ -617,38 +612,38 @@ void gl_ParseFlickerLight2(FScanner &sc)
ScriptDepth--;
break;
case LIGHTTAG_COLOR:
gl_ParseTriple(sc, floatTriple);
ParseTriple(sc, floatTriple);
defaults->SetArg(LIGHT_RED, clamp<int>((int)(floatTriple[0] * 255), 0, 255));
defaults->SetArg(LIGHT_GREEN, clamp<int>((int)(floatTriple[1] * 255), 0, 255));
defaults->SetArg(LIGHT_BLUE, clamp<int>((int)(floatTriple[2] * 255), 0, 255));
break;
case LIGHTTAG_OFFSET:
gl_ParseTriple(sc, floatTriple);
ParseTriple(sc, floatTriple);
defaults->SetOffset(floatTriple);
break;
case LIGHTTAG_SIZE:
intVal = clamp<int>(gl_ParseInt(sc), 1, 1024);
intVal = clamp<int>(ParseInt(sc), 1, 1024);
defaults->SetArg(LIGHT_INTENSITY, intVal);
break;
case LIGHTTAG_SECSIZE:
intVal = clamp<int>(gl_ParseInt(sc), 1, 1024);
intVal = clamp<int>(ParseInt(sc), 1, 1024);
defaults->SetArg(LIGHT_SECONDARY_INTENSITY, intVal);
break;
case LIGHTTAG_INTERVAL:
floatVal = gl_ParseFloat(sc);
floatVal = ParseFloat(sc);
defaults->SetParameter(floatVal * 360.);
break;
case LIGHTTAG_SUBTRACTIVE:
defaults->SetSubtractive(gl_ParseInt(sc) != 0);
defaults->SetSubtractive(ParseInt(sc) != 0);
break;
case LIGHTTAG_HALO:
defaults->SetHalo(gl_ParseInt(sc) != 0);
defaults->SetHalo(ParseInt(sc) != 0);
break;
case LIGHTTAG_DONTLIGHTSELF:
defaults->SetDontLightSelf(gl_ParseInt(sc) != 0);
defaults->SetDontLightSelf(ParseInt(sc) != 0);
break;
case LIGHTTAG_ATTENUATE:
defaults->SetAttenuate(gl_ParseInt(sc) != 0);
defaults->SetAttenuate(ParseInt(sc) != 0);
break;
default:
sc.ScriptError("Unknown tag: %s\n", sc.String);
@ -660,7 +655,7 @@ void gl_ParseFlickerLight2(FScanner &sc)
defaults->SetArg(LIGHT_SECONDARY_INTENSITY, defaults->GetArg(LIGHT_INTENSITY));
defaults->SetArg(LIGHT_INTENSITY, v);
}
gl_AddLightDefaults(defaults);
AddLightDefaults(defaults);
}
else
{
@ -675,7 +670,7 @@ void gl_ParseFlickerLight2(FScanner &sc)
//
//-----------------------------------------------------------------------------
void gl_ParseSectorLight(FScanner &sc)
static void ParseSectorLight(FScanner &sc)
{
int type;
float floatVal;
@ -705,36 +700,36 @@ void gl_ParseSectorLight(FScanner &sc)
ScriptDepth--;
break;
case LIGHTTAG_COLOR:
gl_ParseTriple(sc, floatTriple);
ParseTriple(sc, floatTriple);
defaults->SetArg(LIGHT_RED, clamp<int>((int)(floatTriple[0] * 255), 0, 255));
defaults->SetArg(LIGHT_GREEN, clamp<int>((int)(floatTriple[1] * 255), 0, 255));
defaults->SetArg(LIGHT_BLUE, clamp<int>((int)(floatTriple[2] * 255), 0, 255));
break;
case LIGHTTAG_OFFSET:
gl_ParseTriple(sc, floatTriple);
ParseTriple(sc, floatTriple);
defaults->SetOffset(floatTriple);
break;
case LIGHTTAG_SCALE:
floatVal = gl_ParseFloat(sc);
floatVal = ParseFloat(sc);
defaults->SetArg(LIGHT_SCALE, clamp((int)(floatVal * 255), 1, 1024));
break;
case LIGHTTAG_SUBTRACTIVE:
defaults->SetSubtractive(gl_ParseInt(sc) != 0);
defaults->SetSubtractive(ParseInt(sc) != 0);
break;
case LIGHTTAG_HALO:
defaults->SetHalo(gl_ParseInt(sc) != 0);
defaults->SetHalo(ParseInt(sc) != 0);
break;
case LIGHTTAG_DONTLIGHTSELF:
defaults->SetDontLightSelf(gl_ParseInt(sc) != 0);
defaults->SetDontLightSelf(ParseInt(sc) != 0);
break;
case LIGHTTAG_ATTENUATE:
defaults->SetAttenuate(gl_ParseInt(sc) != 0);
defaults->SetAttenuate(ParseInt(sc) != 0);
break;
default:
sc.ScriptError("Unknown tag: %s\n", sc.String);
}
}
gl_AddLightDefaults(defaults);
AddLightDefaults(defaults);
}
else
{
@ -749,7 +744,7 @@ void gl_ParseSectorLight(FScanner &sc)
//
//-----------------------------------------------------------------------------
void gl_AddLightAssociation(const char *actor, const char *frame, const char *light)
static void AddLightAssociation(const char *actor, const char *frame, const char *light)
{
FLightAssociation *temp;
unsigned int i;
@ -778,7 +773,7 @@ void gl_AddLightAssociation(const char *actor, const char *frame, const char *li
//
//-----------------------------------------------------------------------------
void gl_ParseFrame(FScanner &sc, FString name)
static void ParseFrame(FScanner &sc, FString name)
{
int type, startDepth;
FString frameName;
@ -811,8 +806,8 @@ void gl_ParseFrame(FScanner &sc, FString name)
ScriptDepth--;
break;
case LIGHTTAG_LIGHT:
gl_ParseString(sc);
gl_AddLightAssociation(name, frameName, sc.String);
ParseString(sc);
AddLightAssociation(name, frameName, sc.String);
break;
default:
sc.ScriptError("Unknown tag: %s\n", sc.String);
@ -832,7 +827,7 @@ void gl_ParseFrame(FScanner &sc, FString name)
//
//-----------------------------------------------------------------------------
void gl_ParseObject(FScanner &sc)
void ParseObject(FScanner &sc)
{
int type;
FString name;
@ -840,7 +835,7 @@ void gl_ParseObject(FScanner &sc)
// get name
sc.GetString();
name = sc.String;
if (!PClass::FindClass(name))
if (!PClass::FindActor(name))
sc.ScriptMessage("Warning: dynamic lights attached to non-existent actor %s\n", name.GetChars());
// check for opening brace
@ -861,7 +856,7 @@ void gl_ParseObject(FScanner &sc)
ScriptDepth--;
break;
case LIGHTTAG_FRAME:
gl_ParseFrame(sc, name);
ParseFrame(sc, name);
break;
default:
sc.ScriptError("Unknown tag: %s\n", sc.String);
@ -875,25 +870,6 @@ void gl_ParseObject(FScanner &sc)
}
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
void gl_ReleaseLights()
{
unsigned int i;
for (i = 0; i < LightDefaults.Size(); i++)
{
delete LightDefaults[i];
}
LightAssociations.Clear();
LightDefaults.Clear();
}
//==========================================================================
//
//
@ -950,7 +926,7 @@ enum
// There is no functionality for this stuff!
//
//==========================================================================
bool gl_ParseShader(FScanner &sc)
bool ParseShader(FScanner &sc)
{
int ShaderDepth = 0;
@ -983,8 +959,6 @@ bool gl_ParseShader(FScanner &sc)
//
// Light associations per actor class
//
// Turn this inefficient mess into something that can be used at run time.
//
//==========================================================================
class FInternalLightAssociation
@ -1039,20 +1013,6 @@ FInternalLightAssociation::FInternalLightAssociation(FLightAssociation * asso)
}
}
//==========================================================================
//
//
//
//==========================================================================
inline TDeletingArray<FInternalLightAssociation *> * gl_GetActorLights(AActor * actor)
{
return (TDeletingArray<FInternalLightAssociation *>*)actor->lightassociations;
}
TDeletingArray< TDeletingArray<FInternalLightAssociation *> * > AssoDeleter;
//==========================================================================
//
// State lights
@ -1069,7 +1029,7 @@ TArray<FLightDefaults *> StateLights;
//
//==========================================================================
void gl_InitializeActorLights()
void InitializeActorLights()
{
for(unsigned int i=0;i<LightAssociations.Size();i++)
{
@ -1077,28 +1037,11 @@ void gl_InitializeActorLights()
if (ti)
{
ti = GetRealType(ti);
AActor * defaults = GetDefaultByType(ti);
if (defaults)
{
FInternalLightAssociation * iasso = new FInternalLightAssociation(&LightAssociations[i]);
if (!defaults->lightassociations)
{
TDeletingArray<FInternalLightAssociation*> *p =new TDeletingArray<FInternalLightAssociation*>;
defaults->lightassociations = p;
AssoDeleter.Push(p);
}
TDeletingArray<FInternalLightAssociation *> * lights = gl_GetActorLights(defaults);
if (iasso->Light()==NULL)
{
// The definition was not valid.
delete iasso;
}
else
{
lights->Push(iasso);
}
}
// put this in the class data arena so that we do not have to worry about deleting it ourselves.
void *mem = ClassDataAllocator.Alloc(sizeof(FInternalLightAssociation));
FInternalLightAssociation * iasso = new(mem) FInternalLightAssociation(&LightAssociations[i]);
if (iasso->Light() != nullptr)
ti->LightAssociations.Push(iasso);
}
}
// we don't need the parser data for the light associations anymore
@ -1134,24 +1077,23 @@ void gl_InitializeActorLights()
//
//==========================================================================
void gl_AttachLight(AActor *actor, unsigned int count, const FLightDefaults *lightdef)
void AActor::AttachLight(unsigned int count, const FLightDefaults *lightdef)
{
ADynamicLight *light;
// I'm skipping the single rotations because that really doesn't make sense!
if (count < actor->dynamiclights.Size())
if (count < AttachedLights.Size())
{
light = barrier_cast<ADynamicLight*>(actor->dynamiclights[count]);
light = barrier_cast<ADynamicLight*>(AttachedLights[count]);
assert(light != NULL);
}
else
{
light = Spawn<ADynamicLight>(actor->Pos(), NO_REPLACE);
light->target = actor;
light = Spawn<ADynamicLight>(Pos(), NO_REPLACE);
light->target = this;
light->owned = true;
light->ObjectFlags |= OF_Transient;
//light->flags4 |= MF4_ATTENUATE;
actor->dynamiclights.Push(light);
AttachedLights.Push(light);
}
light->flags2&=~MF2_DORMANT;
lightdef->ApplyProperties(light);
@ -1163,51 +1105,59 @@ void gl_AttachLight(AActor *actor, unsigned int count, const FLightDefaults *lig
//
//==========================================================================
void gl_SetActorLights(AActor *actor)
void AActor::SetDynamicLights()
{
TArray<FInternalLightAssociation *> * l = gl_GetActorLights(actor);
TArray<FInternalLightAssociation *> & LightAssociations = GetClass()->LightAssociations;
unsigned int count = 0;
All.Clock();
if (actor->state == NULL) return;
if (l)
if (state == NULL) return;
if (LightAssociations.Size() > 0)
{
TArray<FInternalLightAssociation *> & LightAssociations=*l;
ADynamicLight *lights, *tmpLight;
unsigned int i;
int sprite = actor->sprite;
int frame = actor->frame;
lights = tmpLight = NULL;
for (i = 0; i < LightAssociations.Size(); i++)
{
if (LightAssociations[i]->Sprite() == sprite &&
(LightAssociations[i]->Frame()==frame || LightAssociations[i]->Frame()==-1))
{
gl_AttachLight(actor, count++, LightAssociations[i]->Light());
AttachLight(count++, LightAssociations[i]->Light());
}
}
}
if (count == 0 && actor->state->Light > 0)
if (count == 0 && state->Light > 0)
{
for(int i= actor->state->Light; StateLights[i] != NULL; i++)
for(int i= state->Light; StateLights[i] != NULL; i++)
{
if (StateLights[i] != (FLightDefaults*)-1)
{
gl_AttachLight(actor, count++, StateLights[i]);
AttachLight(count++, StateLights[i]);
}
}
}
for(;count<actor->dynamiclights.Size();count++)
for(;count<AttachedLights.Size();count++)
{
actor->dynamiclights[count]->flags2 |= MF2_DORMANT;
memset(actor->dynamiclights[count]->args, 0, 3*sizeof(actor->args[0]));
AttachedLights[count]->flags2 |= MF2_DORMANT;
memset(AttachedLights[count]->args, 0, 3*sizeof(args[0]));
}
All.Unclock();
}
//==========================================================================
//
// Needed for garbage collection
//
//==========================================================================
size_t AActor::PropagateMark()
{
for (unsigned i = 0; i<AttachedLights.Size(); i++)
{
GC::Mark(AttachedLights[i]);
}
return Super::PropagateMark();
}
//==========================================================================
@ -1216,7 +1166,7 @@ void gl_SetActorLights(AActor *actor)
//
//==========================================================================
void gl_DeleteAllAttachedLights()
void AActor::DeleteAllAttachedLights()
{
TThinkerIterator<AActor> it;
AActor * a;
@ -1224,7 +1174,7 @@ void gl_DeleteAllAttachedLights()
while ((a=it.Next()))
{
a->dynamiclights.Clear();
a->AttachedLights.Clear();
}
TThinkerIterator<ADynamicLight> it2;
@ -1236,8 +1186,6 @@ void gl_DeleteAllAttachedLights()
if (l->owned) l->Destroy();
l=ll;
}
}
//==========================================================================
@ -1246,14 +1194,14 @@ void gl_DeleteAllAttachedLights()
//
//==========================================================================
void gl_RecreateAllAttachedLights()
void AActor::RecreateAllAttachedLights()
{
TThinkerIterator<AActor> it;
AActor * a;
while ((a=it.Next()))
{
gl_SetActorLights(a);
a->SetDynamicLights();
}
}
@ -1264,7 +1212,7 @@ void gl_RecreateAllAttachedLights()
// by LoadDynLightDefs, which wasn't simply integrated into ParseDefs
// because of the way the code needs to load two out of five lumps.
//==========================================================================
void gl_DoParseDefs(FScanner &sc, int workingLump)
static void DoParseDefs(FScanner &sc, int workingLump)
{
int recursion=0;
int lump, type;
@ -1289,32 +1237,32 @@ void gl_DoParseDefs(FScanner &sc, int workingLump)
sc.ScriptError("Lump '%s' not found", sc.String);
FScanner newscanner(lump);
gl_DoParseDefs(newscanner, lump);
DoParseDefs(newscanner, lump);
break;
}
case LIGHT_POINT:
gl_ParsePointLight(sc);
ParsePointLight(sc);
break;
case LIGHT_PULSE:
gl_ParsePulseLight(sc);
ParsePulseLight(sc);
break;
case LIGHT_FLICKER:
gl_ParseFlickerLight(sc);
ParseFlickerLight(sc);
break;
case LIGHT_FLICKER2:
gl_ParseFlickerLight2(sc);
ParseFlickerLight2(sc);
break;
case LIGHT_SECTOR:
gl_ParseSectorLight(sc);
ParseSectorLight(sc);
break;
case LIGHT_OBJECT:
gl_ParseObject(sc);
ParseObject(sc);
break;
case LIGHT_CLEAR:
gl_ReleaseLights();
// This has been intentionally removed
break;
case TAG_SHADER:
gl_ParseShader(sc);
ParseShader(sc);
break;
case TAG_CLEARSHADERS:
break;
@ -1355,7 +1303,7 @@ void gl_DoParseDefs(FScanner &sc, int workingLump)
//
//==========================================================================
void gl_LoadGLDefs(const char *defsLump)
static void LoadGLDefs(const char *defsLump)
{
int workingLump, lastLump;
static const char *gldefsnames[] = { "GLDEFS", defsLump, nullptr };
@ -1364,7 +1312,7 @@ void gl_LoadGLDefs(const char *defsLump)
while ((workingLump = Wads.FindLumpMulti(gldefsnames, &lastLump)) != -1)
{
FScanner sc(workingLump);
gl_DoParseDefs(sc, workingLump);
DoParseDefs(sc, workingLump);
}
}
@ -1375,12 +1323,12 @@ void gl_LoadGLDefs(const char *defsLump)
//
//==========================================================================
void gl_ParseDefs()
void ParseGLDefs()
{
const char *defsLump = NULL;
atterm( gl_ReleaseLights );
gl_ReleaseLights();
LightAssociations.Clear();
LightDefaults.Clear();
gl_DestroyUserShaders();
switch (gameinfo.gametype)
{
@ -1403,11 +1351,10 @@ void gl_ParseDefs()
break;
}
gl_ParseVavoomSkybox();
gl_LoadGLDefs(defsLump);
gl_InitializeActorLights();
LoadGLDefs(defsLump);
InitializeActorLights();
}
//==========================================================================
//
//

View file

@ -159,7 +159,7 @@ void DEarthquake::Tick ()
double DEarthquake::GetModWave(double waveMultiplier) const
{
double time = m_Countdown - r_TicFracF;
double time = m_Countdown - r_viewpoint.TicFrac;
return g_sin(waveMultiplier * time * (M_PI * 2 / TICRATE));
}

View file

@ -1101,13 +1101,13 @@ void DrawHUD()
}
else
{
if (AspectTallerThanWide(WidescreenRatio))
if (AspectTallerThanWide(r_viewwindow.WidescreenRatio))
{
hudheight = hudwidth * 30 / AspectMultiplier(WidescreenRatio); // BaseRatioSizes is inverted for this mode
hudheight = hudwidth * 30 / AspectMultiplier(r_viewwindow.WidescreenRatio); // BaseRatioSizes is inverted for this mode
}
else
{
hudheight = hudwidth * 30 / (48*48/AspectMultiplier(WidescreenRatio));
hudheight = hudwidth * 30 / (48*48/AspectMultiplier(r_viewwindow.WidescreenRatio));
}
}
}

View file

@ -38,6 +38,7 @@
#include "dobject.h"
#include "v_collection.h"
#include "v_text.h"
#include "r_data/renderstyle.h"
class player_t;
struct FRemapTable;
@ -343,9 +344,9 @@ public:
DBaseStatusBar (int reltop, int hres=320, int vres=200);
void OnDestroy() override;
void AttachMessage (DHUDMessage *msg, uint32 id=0, int layer=HUDMSGLayer_Default);
void AttachMessage (DHUDMessage *msg, uint32_t id=0, int layer=HUDMSGLayer_Default);
DHUDMessage *DetachMessage (DHUDMessage *msg);
DHUDMessage *DetachMessage (uint32 id);
DHUDMessage *DetachMessage (uint32_t id);
void DetachAllMessages ();
void ShowPlayerName ();
double GetDisplacement() { return Displacement; }

View file

@ -41,6 +41,7 @@
#include "sbarinfo.h"
#include "templates.h"
#include "r_utility.h"
#include "actorinlines.h"
#define ST_RAMPAGEDELAY (2*TICRATE)
#define ST_MUCHPAIN 20

View file

@ -611,7 +611,7 @@ void DBaseStatusBar::DrawCrosshair ()
ST_LoadCrosshair();
// Don't draw the crosshair if there is none
if (CrosshairImage == NULL || gamestate == GS_TITLELEVEL || camera->health <= 0)
if (CrosshairImage == NULL || gamestate == GS_TITLELEVEL || r_viewpoint.camera->health <= 0)
{
return;
}

View file

@ -33,23 +33,22 @@ class FHealthBar : public FTexture
public:
FHealthBar ();
const BYTE *GetColumn (unsigned int column, const Span **spans_out);
const BYTE *GetPixels ();
const uint8_t *GetColumn (unsigned int column, const Span **spans_out);
const uint8_t *GetPixels ();
bool CheckModified ();
void Unload ();
void SetVial (int level);
protected:
BYTE Pixels[200*2];
BYTE Colors[8];
uint8_t Pixels[200*2];
uint8_t Colors[8];
static const Span DummySpan[2];
int VialLevel;
bool NeedRefresh;
void MakeTexture ();
void FillBar (int min, int max, BYTE light, BYTE dark);
void FillBar (int min, int max, uint8_t light, uint8_t dark);
};
const FTexture::Span FHealthBar::DummySpan[2] = { { 0, 2 }, { 0, 0 } };
@ -59,7 +58,7 @@ FHealthBar::FHealthBar ()
{
int i;
static const BYTE rgbs[8*3] =
static const uint8_t rgbs[8*3] =
{
180, 228, 128, // light green
128, 180, 80, // dark green
@ -91,11 +90,7 @@ bool FHealthBar::CheckModified ()
return NeedRefresh;
}
void FHealthBar::Unload ()
{
}
const BYTE *FHealthBar::GetColumn (unsigned int column, const Span **spans_out)
const uint8_t *FHealthBar::GetColumn (unsigned int column, const Span **spans_out)
{
if (NeedRefresh)
{
@ -112,7 +107,7 @@ const BYTE *FHealthBar::GetColumn (unsigned int column, const Span **spans_out)
return Pixels + column*2;
}
const BYTE *FHealthBar::GetPixels ()
const uint8_t *FHealthBar::GetPixels ()
{
if (NeedRefresh)
{
@ -171,7 +166,7 @@ void FHealthBar::MakeTexture ()
}
}
void FHealthBar::FillBar (int min, int max, BYTE light, BYTE dark)
void FHealthBar::FillBar (int min, int max, uint8_t light, uint8_t dark)
{
for (int i = min*2; i < max*2; i++)
{
@ -562,7 +557,7 @@ private:
int bars = (CurrentPop == POP_Status) ? imgINVPOP : imgINVPOP2;
int back = (CurrentPop == POP_Status) ? imgINVPBAK : imgINVPBAK2;
// Extrapolate the height of the popscreen for smoother movement
int height = clamp<int> (PopHeight + int(r_TicFracF * PopHeightChange), -POP_HEIGHT, 0);
int height = clamp<int> (PopHeight + int(r_viewpoint.TicFrac * PopHeightChange), -POP_HEIGHT, 0);
xscale = CleanXfac;
yscale = CleanYfac;
@ -613,7 +608,7 @@ private:
if (KeyPopScroll > 0)
{
// Extrapolate the scroll position for smoother scrolling
int scroll = MAX<int> (0,KeyPopScroll - int(r_TicFracF * (280./KEY_TIME)));
int scroll = MAX<int> (0,KeyPopScroll - int(r_viewpoint.TicFrac * (280./KEY_TIME)));
pos -= 10;
leftcol = leftcol - 280 + scroll;
}

View file

@ -125,6 +125,21 @@ const char* GameInfoBorders[] =
} \
while (sc.CheckToken(',')); \
}
#define GAMEINFOKEY_SOUNDARRAY(key, variable, length, clear) \
else if(nextKey.CompareNoCase(variable) == 0) \
{ \
if (clear) gameinfo.key.Clear(); \
do \
{ \
sc.MustGetToken(TK_StringConst); \
if(length > 0 && strlen(sc.String) > length) \
{ \
sc.ScriptError("Value for '%s' can not be longer than %d characters.", #key, length); \
} \
gameinfo.key[gameinfo.key.Reserve(1)] = FSoundID(sc.String); \
} \
while (sc.CheckToken(',')); \
}
#define GAMEINFOKEY_STRING(key, variable) \
else if(nextKey.CompareNoCase(variable) == 0) \
@ -323,7 +338,7 @@ void FMapInfoParser::ParseGameInfo()
GAMEINFOKEY_STRINGARRAY(infoPages, "infoPage", 8, true)
GAMEINFOKEY_STRINGARRAY(PrecachedClasses, "precacheclasses", 0, false)
GAMEINFOKEY_STRINGARRAY(PrecachedTextures, "precachetextures", 0, false)
GAMEINFOKEY_STRINGARRAY(PrecachedSounds, "precachesounds", 0, false)
GAMEINFOKEY_SOUNDARRAY(PrecachedSounds, "precachesounds", 0, false)
GAMEINFOKEY_STRINGARRAY(EventHandlers, "addeventhandlers", 0, true)
GAMEINFOKEY_STRINGARRAY(EventHandlers, "eventhandlers", 0, false)
GAMEINFOKEY_STRING(PauseSign, "pausesign")

View file

@ -36,7 +36,6 @@
#include "basictypes.h"
#include "zstring.h"
#include "s_sound.h"
// Flags are not user configurable and only depend on the standard IWADs
#define GI_MAPxx 0x00000001
@ -123,7 +122,7 @@ struct gameinfo_t
TArray<FName> PrecachedClasses;
TArray<FString> PrecachedTextures;
TArray<FSoundID> PrecachedSounds;
TArray<int> PrecachedSounds;
TArray<FString> EventHandlers;
FString titleMusic;

View file

@ -38,6 +38,7 @@
#include "v_text.h"
#include "r_utility.h"
#include "g_levellocals.h"
#include "actorinlines.h"
#include "gl/dynlights/gl_dynlight.h"
#include "gl/utility/gl_geometric.h"
#include "gl/renderer/gl_renderer.h"
@ -46,6 +47,7 @@
#include "gl/system/gl_cvars.h"
#include "gl/renderer/gl_renderstate.h"
#include "gl/scene/gl_drawinfo.h"
#include "gl/scene/gl_scenedrawer.h"
#include "gl/data/gl_vertexbuffer.h"
@ -370,10 +372,10 @@ void FRenderState::DrawColormapOverlay()
//
//==========================================================================
bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, Vector & nearPt, Vector & up, Vector & right,
bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, FVector3 & nearPt, FVector3 & up, FVector3 & right,
float & scale, bool checkside, bool additive)
{
Vector fn, pos;
FVector3 fn, pos;
DVector3 lpos = light->PosRelative(group);
@ -396,16 +398,12 @@ bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, Vector & nearPt,
// project light position onto plane (find closest point on plane)
pos.Set(lpos.X, lpos.Z, lpos.Y);
pos = { (float)lpos.X, (float)lpos.Z, (float)lpos.Y };
fn = p.Normal();
fn.GetRightUp(right, up);
#ifdef _MSC_VER
nearPt = pos + fn * dist;
#else
Vector tmpVec = fn * dist;
FVector3 tmpVec = fn * dist;
nearPt = pos + tmpVec;
#endif
float cs = 1.0f - (dist / radius);
if (additive) cs *= 0.2f; // otherwise the light gets too strong.
@ -415,13 +413,11 @@ bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, Vector & nearPt,
if (light->IsSubtractive())
{
Vector v;
gl_RenderState.BlendEquation(GL_FUNC_REVERSE_SUBTRACT);
v.Set(r, g, b);
r = v.Length() - r;
g = v.Length() - g;
b = v.Length() - b;
float length = float(FVector3(r, g, b).Length());
r = length - r;
g = length - g;
b = length - b;
}
else
{
@ -517,8 +513,8 @@ void GLWall::RenderFogBoundaryCompat()
// as the shader version but it's an acceptable compromise.
float fogdensity = gl_GetFogDensity(lightlevel, Colormap.FadeColor, Colormap.fogdensity);
float dist1 = Dist2(ViewPos.X, ViewPos.Y, glseg.x1, glseg.y1);
float dist2 = Dist2(ViewPos.X, ViewPos.Y, glseg.x2, glseg.y2);
float dist1 = Dist2(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, glseg.x1, glseg.y1);
float dist2 = Dist2(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, glseg.x2, glseg.y2);
// these values were determined by trial and error and are scale dependent!
float fogd1 = (0.95f - exp(-fogdensity*dist1 / 62500.f)) * 1.05f;
@ -562,7 +558,7 @@ void GLWall::RenderFogBoundaryCompat()
void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass)
{
Plane p;
Vector nearPt, up, right, t1;
FVector3 nearPt, up, right, t1;
float scale;
FLightNode * node = sub->lighthead;
@ -602,11 +598,11 @@ void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass)
ptr->x = vt->fX();
ptr->z = plane.plane.ZatPoint(vt) + dz;
ptr->y = vt->fY();
t1.Set(ptr->x, ptr->z, ptr->y);
Vector nearToVert = t1 - nearPt;
t1 = { ptr->x, ptr->z, ptr->y };
FVector3 nearToVert = t1 - nearPt;
ptr->u = (nearToVert.Dot(right) * scale) + 0.5f;
ptr->v = (nearToVert.Dot(up) * scale) + 0.5f;
ptr->u = ((nearToVert | right) * scale) + 0.5f;
ptr->v = ((nearToVert | up) * scale) + 0.5f;
ptr++;
}
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
@ -658,10 +654,10 @@ bool GLWall::PrepareLight(ADynamicLight * light, int pass)
{
float vtx[] = { glseg.x1,zbottom[0],glseg.y1, glseg.x1,ztop[0],glseg.y1, glseg.x2,ztop[1],glseg.y2, glseg.x2,zbottom[1],glseg.y2 };
Plane p;
Vector nearPt, up, right;
FVector3 nearPt, up, right;
float scale;
p.Init(vtx, 4);
p.Set(&glseg);
if (!p.ValidNormal())
{
@ -673,15 +669,15 @@ bool GLWall::PrepareLight(ADynamicLight * light, int pass)
return false;
}
Vector t1;
FVector3 t1;
int outcnt[4] = { 0,0,0,0 };
for (int i = 0; i<4; i++)
{
t1.Set(&vtx[i * 3]);
Vector nearToVert = t1 - nearPt;
tcs[i].u = (nearToVert.Dot(right) * scale) + 0.5f;
tcs[i].v = (nearToVert.Dot(up) * scale) + 0.5f;
t1 = &vtx[i * 3];
FVector3 nearToVert = t1 - nearPt;
tcs[i].u = ((nearToVert | right) * scale) + 0.5f;
tcs[i].v = ((nearToVert | up) * scale) + 0.5f;
// quick check whether the light touches this polygon
if (tcs[i].u<0) outcnt[0]++;
@ -755,7 +751,7 @@ void GLWall::RenderLightsCompat(int pass)
//
//==========================================================================
void FGLRenderer::RenderMultipassStuff()
void GLSceneDrawer::RenderMultipassStuff()
{
// First pass: empty background with sector light only
@ -789,7 +785,7 @@ void FGLRenderer::RenderMultipassStuff()
// second pass: draw lights
glDepthMask(false);
if (mLightCount && !gl_fixedcolormap)
if (GLRenderer->mLightCount && !gl_fixedcolormap)
{
if (gl_SetupLightTexture())
{

View file

@ -61,7 +61,6 @@ long gl_frameCount;
EXTERN_CVAR(Int, gl_lightmode)
EXTERN_CVAR(Bool, gl_brightfog)
EXTERN_CVAR(Bool, gl_lightadditivesurfaces)
EXTERN_CVAR(Bool, gl_attenuate)
CUSTOM_CVAR(Float, maxviewpitch, 90.f, CVAR_ARCHIVE|CVAR_SERVERINFO)
@ -240,7 +239,6 @@ struct FGLROptions : public FOptionalMapinfoData
skyfog = 0;
brightfog = false;
lightmode = -1;
attenuate = -1;
nocoloredspritelighting = -1;
nolightfade = false;
notexturefill = -1;
@ -257,7 +255,6 @@ struct FGLROptions : public FOptionalMapinfoData
newopt->outsidefogdensity = outsidefogdensity;
newopt->skyfog = skyfog;
newopt->lightmode = lightmode;
newopt->attenuate = attenuate;
newopt->nocoloredspritelighting = nocoloredspritelighting;
newopt->nolightfade = nolightfade;
newopt->notexturefill = notexturefill;
@ -272,7 +269,6 @@ struct FGLROptions : public FOptionalMapinfoData
int skyfog;
int lightmode;
int brightfog;
int8_t attenuate;
int8_t lightadditivesurfaces;
int8_t nocoloredspritelighting;
int8_t notexturefill;
@ -378,20 +374,6 @@ DEFINE_MAP_OPTION(lightadditivesurfaces, false)
}
}
DEFINE_MAP_OPTION(attenuate, false)
{
FGLROptions *opt = info->GetOptData<FGLROptions>("gl_renderer");
if (parse.CheckAssign())
{
parse.sc.MustGetNumber();
opt->attenuate = !!parse.sc.Number;
}
else
{
opt->attenuate = true;
}
}
DEFINE_MAP_OPTION(skyrotate, false)
{
FGLROptions *opt = info->GetOptData<FGLROptions>("gl_renderer");
@ -450,8 +432,6 @@ static void ResetOpts()
else glset.brightfog = !!glset.map_brightfog;
if (glset.map_lightadditivesurfaces == -1) glset.lightadditivesurfaces = gl_lightadditivesurfaces;
else glset.lightadditivesurfaces = !!glset.map_lightadditivesurfaces;
if (glset.map_attenuate == -1) glset.attenuate = gl_attenuate;
else glset.attenuate = !!glset.map_attenuate;
}
void InitGLRMapinfoData()
@ -463,7 +443,6 @@ void InitGLRMapinfoData()
gl_SetFogParams(clamp(opt->fogdensity, 0, 255), level.info->outsidefog, clamp(opt->outsidefogdensity, 0, 255), opt->skyfog);
glset.map_lightmode = opt->lightmode;
glset.map_lightadditivesurfaces = opt->lightadditivesurfaces;
glset.map_attenuate = opt->attenuate;
glset.map_brightfog = opt->brightfog;
glset.map_nocoloredspritelighting = opt->nocoloredspritelighting;
glset.map_notexturefill = opt->notexturefill;
@ -478,7 +457,6 @@ void InitGLRMapinfoData()
glset.map_lightmode = -1;
glset.map_lightadditivesurfaces = -1;
glset.map_brightfog = -1;
glset.map_attenuate = -1;
glset.map_nocoloredspritelighting = -1;
glset.map_notexturefill = -1;
glset.skyrotatevector = FVector3(0, 0, 1);
@ -590,7 +568,7 @@ CCMD(dumpgeometry)
subsector_t * sub = sector.subsectors[j];
Printf(PRINT_LOG, " Subsector %d - real sector = %d - %s\n", int(sub-subsectors), sub->sector->sectornum, sub->hacked&1? "hacked":"");
for(DWORD k=0;k<sub->numlines;k++)
for(uint32_t k=0;k<sub->numlines;k++)
{
seg_t * seg = sub->firstline + k;
if (seg->linedef)

View file

@ -4,24 +4,22 @@
#include "doomtype.h"
#include "vectors.h"
#include "r_utility.h"
struct GLRenderSettings
{
SBYTE lightmode;
int8_t lightmode;
bool nocoloredspritelighting;
bool nolightfade;
bool notexturefill;
bool brightfog;
bool lightadditivesurfaces;
bool attenuate;
int8_t map_lightmode;
int8_t map_nocoloredspritelighting;
int8_t map_notexturefill;
int8_t map_brightfog;
int8_t map_lightadditivesurfaces;
int8_t map_attenuate;
FVector3 skyrotatevector;
FVector3 skyrotatevector2;
@ -36,12 +34,11 @@ extern GLRenderSettings glset;
#include "a_sharedglobal.h"
#include "c_cvars.h"
extern int extralight;
EXTERN_CVAR(Int, gl_weaponlight);
inline int getExtraLight()
{
return extralight * gl_weaponlight;
return r_viewpoint.extralight * gl_weaponlight;
}
void gl_RecalcVertexHeights(vertex_t * v);
@ -69,7 +66,7 @@ struct FGLLinePortal
extern TArray<FPortal *> portals;
extern TArray<FGLLinePortal*> linePortalToGL;
extern TArray<BYTE> currentmapsection;
extern TArray<uint8_t> currentmapsection;
void gl_InitPortals();
void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, const DVector2 &displacement);

View file

@ -296,7 +296,7 @@ struct FCoverageBuilder
else
{
// we reached a subsector so we can link the node with this subsector
subsector_t *sub = (subsector_t *)((BYTE *)node - 1);
subsector_t *sub = (subsector_t *)((uint8_t *)node - 1);
collect.Push(int(sub-subsectors));
}
}
@ -325,9 +325,9 @@ void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, c
build.center.y = xs_CRoundToInt(centery / subsector->numlines);
build.CollectNode(nodes + numnodes - 1, shape);
coverage->subsectors = new DWORD[build.collect.Size()];
coverage->subsectors = new uint32_t[build.collect.Size()];
coverage->sscount = build.collect.Size();
memcpy(coverage->subsectors, &build.collect[0], build.collect.Size() * sizeof(DWORD));
memcpy(coverage->subsectors, &build.collect[0], build.collect.Size() * sizeof(uint32_t));
}
//==========================================================================

View file

@ -67,7 +67,7 @@ static void DoSetMapSection(subsector_t *sub, int num)
for (unsigned a = 0; a < MapSectionCollector.Size(); a++)
{
sub = MapSectionCollector[a];
for (DWORD i = 0; i < sub->numlines; i++)
for (uint32_t i = 0; i < sub->numlines; i++)
{
seg_t * seg = sub->firstline + i;
@ -126,7 +126,7 @@ static int MergeMapSections(int num)
cvertex_t vt;
// first step: Set mapsection for all vertex positions.
for(DWORD i=0;i<(DWORD)numsegs;i++)
for(uint32_t i=0;i<(uint32_t)numsegs;i++)
{
seg_t * seg = &segs[i];
int section = seg->Subsector->mapsection;
@ -138,7 +138,7 @@ static int MergeMapSections(int num)
}
// second step: Check if any seg references more than one mapsection, either by subsector or by vertex
for(DWORD i=0;i<(DWORD)numsegs;i++)
for(uint32_t i=0;i<(uint32_t)numsegs;i++)
{
seg_t * seg = &segs[i];
int section = seg->Subsector->mapsection;
@ -219,7 +219,7 @@ static void SetMapSections()
static void SpreadHackedFlag(subsector_t * sub)
{
// The subsector pointer hasn't been set yet!
for(DWORD i=0;i<sub->numlines;i++)
for(uint32_t i=0;i<sub->numlines;i++)
{
seg_t * seg = sub->firstline + i;
@ -276,7 +276,7 @@ static void PrepareSectorData()
if (subsectors[i].sector == subsectors[i].render_sector)
{
seg_t * seg = subsectors[i].firstline;
for(DWORD j=0;j<subsectors[i].numlines;j++)
for(uint32_t j=0;j<subsectors[i].numlines;j++)
{
if (!(subsectors[i].hacked&1) && seg[j].linedef==0 &&
seg[j].PartnerSeg!=NULL &&

View file

@ -31,6 +31,7 @@ struct vertex_t;
struct secplane_t;
struct subsector_t;
struct sector_t;
class FMaterial;
enum
{

View file

@ -0,0 +1,288 @@
//
//---------------------------------------------------------------------------
// AABB-tree used for ray testing
// Copyright(C) 2017 Magnus Norddahl
// 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/
//
//--------------------------------------------------------------------------
//
#include "gl/system/gl_system.h"
#include "gl/shaders/gl_shader.h"
#include "gl/dynlights/gl_aabbtree.h"
#include "gl/system/gl_interface.h"
#include "r_state.h"
#include "g_levellocals.h"
LevelAABBTree::LevelAABBTree()
{
// Calculate the center of all lines
TArray<FVector2> centroids;
for (unsigned int i = 0; i < level.lines.Size(); i++)
{
FVector2 v1 = { (float)level.lines[i].v1->fX(), (float)level.lines[i].v1->fY() };
FVector2 v2 = { (float)level.lines[i].v2->fX(), (float)level.lines[i].v2->fY() };
centroids.Push((v1 + v2) * 0.5f);
}
// Create a list of level lines we want to add:
TArray<int> line_elements;
for (unsigned int i = 0; i < level.lines.Size(); i++)
{
if (!level.lines[i].backsector)
{
line_elements.Push(i);
}
}
// GenerateTreeNode needs a buffer where it can store line indices temporarily when sorting lines into the left and right child AABB buckets
TArray<int> work_buffer;
work_buffer.Resize(line_elements.Size() * 2);
// Generate the AABB tree
GenerateTreeNode(&line_elements[0], (int)line_elements.Size(), &centroids[0], &work_buffer[0]);
// Add the lines referenced by the leaf nodes
lines.Resize(level.lines.Size());
for (unsigned int i = 0; i < level.lines.Size(); i++)
{
const auto &line = level.lines[i];
auto &treeline = lines[i];
treeline.x = (float)line.v1->fX();
treeline.y = (float)line.v1->fY();
treeline.dx = (float)line.v2->fX() - treeline.x;
treeline.dy = (float)line.v2->fY() - treeline.y;
}
}
double LevelAABBTree::RayTest(const DVector3 &ray_start, const DVector3 &ray_end)
{
// Precalculate some of the variables used by the ray/line intersection test
DVector2 raydelta = ray_end - ray_start;
double raydist2 = raydelta | raydelta;
DVector2 raynormal = DVector2(raydelta.Y, -raydelta.X);
double rayd = raynormal | ray_start;
if (raydist2 < 1.0)
return 1.0f;
double hit_fraction = 1.0;
// Walk the tree nodes
int stack[16];
int stack_pos = 1;
stack[0] = nodes.Size() - 1; // root node is the last node in the list
while (stack_pos > 0)
{
int node_index = stack[stack_pos - 1];
if (!OverlapRayAABB(ray_start, ray_end, nodes[node_index]))
{
// If the ray doesn't overlap this node's AABB we're done for this subtree
stack_pos--;
}
else if (nodes[node_index].line_index != -1) // isLeaf(node_index)
{
// We reached a leaf node. Do a ray/line intersection test to see if we hit the line.
hit_fraction = MIN(IntersectRayLine(ray_start, ray_end, nodes[node_index].line_index, raydelta, rayd, raydist2), hit_fraction);
stack_pos--;
}
else if (stack_pos == 16)
{
stack_pos--; // stack overflow - tree is too deep!
}
else
{
// The ray overlaps the node's AABB. Examine its child nodes.
stack[stack_pos - 1] = nodes[node_index].left_node;
stack[stack_pos] = nodes[node_index].right_node;
stack_pos++;
}
}
return hit_fraction;
}
bool LevelAABBTree::OverlapRayAABB(const DVector2 &ray_start2d, const DVector2 &ray_end2d, const AABBTreeNode &node)
{
// To do: simplify test to use a 2D test
DVector3 ray_start = DVector3(ray_start2d, 0.0);
DVector3 ray_end = DVector3(ray_end2d, 0.0);
DVector3 aabb_min = DVector3(node.aabb_left, node.aabb_top, -1.0);
DVector3 aabb_max = DVector3(node.aabb_right, node.aabb_bottom, 1.0);
// Standard 3D ray/AABB overlapping test.
// The details for the math here can be found in Real-Time Rendering, 3rd Edition.
// We could use a 2D test here instead, which would probably simplify the math.
DVector3 c = (ray_start + ray_end) * 0.5f;
DVector3 w = ray_end - c;
DVector3 h = (aabb_max - aabb_min) * 0.5f; // aabb.extents();
c -= (aabb_max + aabb_min) * 0.5f; // aabb.center();
DVector3 v = DVector3(abs(w.X), abs(w.Y), abs(w.Z));
if (abs(c.X) > v.X + h.X || abs(c.Y) > v.Y + h.Y || abs(c.Z) > v.Z + h.Z)
return false; // disjoint;
if (abs(c.Y * w.Z - c.Z * w.Y) > h.Y * v.Z + h.Z * v.Y ||
abs(c.X * w.Z - c.Z * w.X) > h.X * v.Z + h.Z * v.X ||
abs(c.X * w.Y - c.Y * w.X) > h.X * v.Y + h.Y * v.X)
return false; // disjoint;
return true; // overlap;
}
double LevelAABBTree::IntersectRayLine(const DVector2 &ray_start, const DVector2 &ray_end, int line_index, const DVector2 &raydelta, double rayd, double raydist2)
{
// Check if two line segments intersects (the ray and the line).
// The math below does this by first finding the fractional hit for an infinitely long ray line.
// If that hit is within the line segment (0 to 1 range) then it calculates the fractional hit for where the ray would hit.
//
// This algorithm is homemade - I would not be surprised if there's a much faster method out there.
const double epsilon = 0.0000001;
const AABBTreeLine &line = lines[line_index];
DVector2 raynormal = DVector2(raydelta.Y, -raydelta.X);
DVector2 line_pos(line.x, line.y);
DVector2 line_delta(line.dx, line.dy);
double den = raynormal | line_delta;
if (abs(den) > epsilon)
{
double t_line = (rayd - (raynormal | line_pos)) / den;
if (t_line >= 0.0 && t_line <= 1.0)
{
DVector2 linehitdelta = line_pos + line_delta * t_line - ray_start;
double t = (raydelta | linehitdelta) / raydist2;
return t > 0.0 ? t : 1.0;
}
}
return 1.0;
}
int LevelAABBTree::GenerateTreeNode(int *lines, int num_lines, const FVector2 *centroids, int *work_buffer)
{
if (num_lines == 0)
return -1;
// Find bounding box and median of the lines
FVector2 median = FVector2(0.0f, 0.0f);
FVector2 aabb_min, aabb_max;
aabb_min.X = (float)level.lines[lines[0]].v1->fX();
aabb_min.Y = (float)level.lines[lines[0]].v1->fY();
aabb_max = aabb_min;
for (int i = 0; i < num_lines; i++)
{
float x1 = (float)level.lines[lines[i]].v1->fX();
float y1 = (float)level.lines[lines[i]].v1->fY();
float x2 = (float)level.lines[lines[i]].v2->fX();
float y2 = (float)level.lines[lines[i]].v2->fY();
aabb_min.X = MIN(aabb_min.X, x1);
aabb_min.X = MIN(aabb_min.X, x2);
aabb_min.Y = MIN(aabb_min.Y, y1);
aabb_min.Y = MIN(aabb_min.Y, y2);
aabb_max.X = MAX(aabb_max.X, x1);
aabb_max.X = MAX(aabb_max.X, x2);
aabb_max.Y = MAX(aabb_max.Y, y1);
aabb_max.Y = MAX(aabb_max.Y, y2);
median += centroids[lines[i]];
}
median /= (float)num_lines;
if (num_lines == 1) // Leaf node
{
nodes.Push(AABBTreeNode(aabb_min, aabb_max, lines[0]));
return (int)nodes.Size() - 1;
}
// Find the longest axis
float axis_lengths[2] =
{
aabb_max.X - aabb_min.X,
aabb_max.Y - aabb_min.Y
};
int axis_order[2] = { 0, 1 };
FVector2 axis_plane[2] = { FVector2(1.0f, 0.0f), FVector2(0.0f, 1.0f) };
std::sort(axis_order, axis_order + 2, [&](int a, int b) { return axis_lengths[a] > axis_lengths[b]; });
// Try sort at longest axis, then if that fails then the other one.
// We place the sorted lines into work_buffer and then move the result back to the lines list when done.
int left_count, right_count;
FVector2 axis;
for (int attempt = 0; attempt < 2; attempt++)
{
// Find the sort plane for axis
FVector2 axis = axis_plane[axis_order[attempt]];
FVector3 plane(axis, -(median | axis));
// Sort lines into two based ib whether the line center is on the front or back side of a plane
left_count = 0;
right_count = 0;
for (int i = 0; i < num_lines; i++)
{
int line_index = lines[i];
float side = FVector3(centroids[lines[i]], 1.0f) | plane;
if (side >= 0.0f)
{
work_buffer[left_count] = line_index;
left_count++;
}
else
{
work_buffer[num_lines + right_count] = line_index;
right_count++;
}
}
if (left_count != 0 && right_count != 0)
break;
}
// Check if something went wrong when sorting and do a random sort instead
if (left_count == 0 || right_count == 0)
{
left_count = num_lines / 2;
right_count = num_lines - left_count;
}
else
{
// Move result back into lines list:
for (int i = 0; i < left_count; i++)
lines[i] = work_buffer[i];
for (int i = 0; i < right_count; i++)
lines[i + left_count] = work_buffer[num_lines + i];
}
// Create child nodes:
int left_index = -1;
int right_index = -1;
if (left_count > 0)
left_index = GenerateTreeNode(lines, left_count, centroids, work_buffer);
if (right_count > 0)
right_index = GenerateTreeNode(lines + left_count, right_count, centroids, work_buffer);
// Store resulting node and return its index
nodes.Push(AABBTreeNode(aabb_min, aabb_max, left_index, right_index));
return (int)nodes.Size() - 1;
}

View file

@ -0,0 +1,59 @@
#pragma once
#include "vectors.h"
// Node in a binary AABB tree
struct AABBTreeNode
{
AABBTreeNode(const FVector2 &aabb_min, const FVector2 &aabb_max, int line_index) : aabb_left(aabb_min.X), aabb_top(aabb_min.Y), aabb_right(aabb_max.X), aabb_bottom(aabb_max.Y), left_node(-1), right_node(-1), line_index(line_index) { }
AABBTreeNode(const FVector2 &aabb_min, const FVector2 &aabb_max, int left, int right) : aabb_left(aabb_min.X), aabb_top(aabb_min.Y), aabb_right(aabb_max.X), aabb_bottom(aabb_max.Y), left_node(left), right_node(right), line_index(-1) { }
// Axis aligned bounding box for the node
float aabb_left, aabb_top;
float aabb_right, aabb_bottom;
// Child node indices
int left_node;
int right_node;
// AABBTreeLine index if it is a leaf node. Index is -1 if it is not.
int line_index;
// Padding to keep 16-byte length (this structure is uploaded to the GPU)
int padding;
};
// Line segment for leaf nodes in an AABB tree
struct AABBTreeLine
{
float x, y;
float dx, dy;
};
// Axis aligned bounding box tree used for ray testing lines.
class LevelAABBTree
{
public:
// Constructs a tree for the current level
LevelAABBTree();
// Nodes in the AABB tree. Last node is the root node.
TArray<AABBTreeNode> nodes;
// Line segments for the leaf nodes in the tree.
TArray<AABBTreeLine> lines;
// Shoot a ray from ray_start to ray_end and return the closest hit as a fractional value between 0 and 1. Returns 1 if no line was hit.
double RayTest(const DVector3 &ray_start, const DVector3 &ray_end);
private:
// Test if a ray overlaps an AABB node or not
bool OverlapRayAABB(const DVector2 &ray_start2d, const DVector2 &ray_end2d, const AABBTreeNode &node);
// Intersection test between a ray and a line segment
double IntersectRayLine(const DVector2 &ray_start, const DVector2 &ray_end, int line_index, const DVector2 &raydelta, double rayd, double raydist2);
// Generate a tree node and its children recursively
int GenerateTreeNode(int *lines, int num_lines, const FVector2 *centroids, int *work_buffer);
};

View file

@ -24,134 +24,10 @@
#define __GLC_DYNLIGHT_H
#include "c_cvars.h"
#include "a_dynlight.h"
#include "gl/utility/gl_geometric.h"
#include "gl/utility/gl_cycler.h"
EXTERN_CVAR(Bool, gl_lights)
EXTERN_CVAR(Bool, gl_attachedlights)
class ADynamicLight;
class FSerializer;
class FLightDefaults;
enum
{
LIGHT_RED = 0,
LIGHT_GREEN = 1,
LIGHT_BLUE = 2,
LIGHT_INTENSITY = 3,
LIGHT_SECONDARY_INTENSITY = 4,
LIGHT_SCALE = 3,
};
// This is as good as something new - and it can be set directly in the ActorInfo!
#define MF4_SUBTRACTIVE MF4_MISSILEEVENMORE
#define MF4_ADDITIVE MF4_MISSILEMORE
#define MF4_DONTLIGHTSELF MF4_SEESDAGGERS
#define MF4_ATTENUATE MF4_INCOMBAT
enum ELightType
{
PointLight,
PulseLight,
FlickerLight,
RandomFlickerLight,
SectorLight,
SpotLight,
ColorPulseLight,
ColorFlickerLight,
RandomColorFlickerLight
};
struct FLightNode
{
FLightNode ** prevTarget;
FLightNode * nextTarget;
FLightNode ** prevLight;
FLightNode * nextLight;
ADynamicLight * lightsource;
union
{
side_t * targLine;
subsector_t * targSubsector;
void * targ;
};
};
//
// Base class
//
// [CO] I merged everything together in this one class so that I don't have
// to create and re-create an excessive amount of objects
//
class ADynamicLight : public AActor
{
friend class FLightDefaults;
DECLARE_CLASS (ADynamicLight, AActor)
public:
virtual void Tick();
void Serialize(FSerializer &arc);
void PostSerialize();
BYTE GetRed() const { return args[LIGHT_RED]; }
BYTE GetGreen() const { return args[LIGHT_GREEN]; }
BYTE GetBlue() const { return args[LIGHT_BLUE]; }
float GetRadius() const { return (IsActive() ? m_currentRadius * 2.f : 0.f); }
void LinkLight();
void UnlinkLight();
size_t PointerSubstitution (DObject *old, DObject *notOld);
void BeginPlay();
void SetOrigin (double x, double y, double z, bool moving = false);
void PostBeginPlay();
void OnDestroy() override;
void Activate(AActor *activator);
void Deactivate(AActor *activator);
void SetOffset(const DVector3 &pos);
void UpdateLocation();
bool IsOwned() const { return owned; }
bool IsActive() const { return !(flags2&MF2_DORMANT); }
bool IsSubtractive() { return !!(flags4&MF4_SUBTRACTIVE); }
bool IsAdditive() { return !!(flags4&MF4_ADDITIVE); }
FState *targetState;
FLightNode * touching_sides;
FLightNode * touching_subsectors;
FLightNode * touching_sector;
private:
double DistToSeg(const DVector3 &pos, seg_t *seg);
void CollectWithinRadius(const DVector3 &pos, subsector_t *subSec, float radius);
protected:
DVector3 m_off;
float m_currentRadius;
unsigned int m_lastUpdate;
FCycler m_cycler;
subsector_t * subsector;
public:
int m_tickCount;
BYTE lightflags;
BYTE lighttype;
bool owned;
bool halo;
BYTE color2[3];
bool visibletoplayer;
bool swapped;
int bufferindex;
};
enum
{
STAT_DLIGHT=64
};
struct FDynLightData
{
TArray<float> arrays[3];

View file

@ -31,6 +31,8 @@
#include "vectors.h"
#include "gl/gl_functions.h"
#include "g_level.h"
#include "actorinlines.h"
#include "a_dynlight.h"
#include "gl/system/gl_interface.h"
#include "gl/renderer/gl_renderer.h"
@ -49,16 +51,12 @@
//
//==========================================================================
CUSTOM_CVAR (Bool, gl_lights, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
{
if (self) gl_RecreateAllAttachedLights();
else gl_DeleteAllAttachedLights();
}
CVAR (Bool, gl_attachedlights, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
CVAR (Bool, gl_lights_checkside, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
CVAR (Bool, gl_light_sprites, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
CVAR (Bool, gl_light_particles, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
CVAR (Bool, gl_light_shadowmap, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
CVAR(Int, gl_attenuate, -1, 0); // This is mainly a debug option.
//==========================================================================
//
@ -99,15 +97,24 @@ bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, FD
if (light->IsSubtractive())
{
Vector v;
DVector3 v(r, g, b);
float length = (float)v.Length();
v.Set(r, g, b);
r = v.Length() - r;
g = v.Length() - g;
b = v.Length() - b;
r = length - r;
g = length - g;
b = length - b;
i = 1;
}
// Store attenuate flag in the sign bit of the float.
float shadowIndex = GLRenderer->mShadowMap.ShadowMapIndex(light) + 1.0f;
bool attenuate;
if (gl_attenuate == -1) attenuate = !!(light->flags4 & MF4_ATTENUATE);
else attenuate = !!gl_attenuate;
shadowIndex = -shadowIndex;
float *data = &ldata.arrays[i][ldata.arrays[i].Reserve(8)];
data[0] = pos.X;
data[1] = pos.Z;
@ -116,7 +123,7 @@ bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, FD
data[4] = r;
data[5] = g;
data[6] = b;
data[7] = !!(light->flags4 & MF4_ATTENUATE);
data[7] = shadowIndex;
return true;
}

View file

@ -0,0 +1,206 @@
//
//---------------------------------------------------------------------------
// 1D dynamic shadow maps
// Copyright(C) 2017 Magnus Norddahl
// 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/
//
//--------------------------------------------------------------------------
//
#include "gl/system/gl_system.h"
#include "gl/shaders/gl_shader.h"
#include "gl/dynlights/gl_shadowmap.h"
#include "gl/dynlights/gl_dynlight.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_debug.h"
#include "gl/system/gl_cvars.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/renderer/gl_postprocessstate.h"
#include "gl/renderer/gl_renderbuffers.h"
#include "gl/shaders/gl_shadowmapshader.h"
#include "r_state.h"
/*
The 1D shadow maps are stored in a 1024x1024 texture as float depth values (R32F).
Each line in the texture is assigned to a single light. For example, to grab depth values for light 20
the fragment shader (main.fp) needs to sample from row 20. That is, the V texture coordinate needs
to be 20.5/1024.
mLightToShadowmap is a hash map storing which line each ADynamicLight is assigned to. The public
ShadowMapIndex function allows the main rendering to find the index and upload that along with the
normal light data. From there, the main.fp shader can sample from the shadow map texture, which
is currently always bound to texture unit 16.
The texel row for each light is split into four parts. One for each direction, like a cube texture,
but then only in 2D where this reduces itself to a square. When main.fp samples from the shadow map
it first decides in which direction the fragment is (relative to the light), like cubemap sampling does
for 3D, but once again just for the 2D case.
Texels 0-255 is Y positive, 256-511 is X positive, 512-767 is Y negative and 768-1023 is X negative.
Generating the shadow map itself is done by FShadowMap::Update(). The shadow map texture's FBO is
bound and then a screen quad is drawn to make a fragment shader cover all texels. For each fragment
it shoots a ray and collects the distance to what it hit.
The shadowmap.fp shader knows which light and texel it is processing by mapping gl_FragCoord.y back
to the light index, and it knows which direction to ray trace by looking at gl_FragCoord.x. For
example, if gl_FragCoord.y is 20.5, then it knows its processing light 20, and if gl_FragCoord.x is
127.5, then it knows we are shooting straight ahead for the Y positive direction.
Ray testing is done by uploading two GPU storage buffers - one holding AABB tree nodes, and one with
the line segments at the leaf nodes of the tree. The fragment shader then performs a test same way
as on the CPU, except everything uses indexes as pointers are not allowed in GLSL.
*/
void FShadowMap::Update()
{
if (!IsEnabled())
return;
UploadAABBTree();
UploadLights();
FGLDebug::PushGroup("ShadowMap");
FGLPostProcessState savedState;
GLRenderer->mBuffers->BindShadowMapFB();
GLRenderer->mShadowMapShader->Bind();
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, mLightList);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, mNodesBuffer);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, mLinesBuffer);
glViewport(0, 0, 1024, 1024);
GLRenderer->RenderScreenQuad();
const auto &viewport = GLRenderer->mScreenViewport;
glViewport(viewport.left, viewport.top, viewport.width, viewport.height);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, 0);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, 0);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, 0);
GLRenderer->mBuffers->BindShadowMapTexture(16);
FGLDebug::PopGroup();
}
bool FShadowMap::ShadowTest(ADynamicLight *light, const DVector3 &pos)
{
if (IsEnabled() && mAABBTree)
return mAABBTree->RayTest(light->Pos(), pos) >= 1.0f;
else
return true;
}
bool FShadowMap::IsEnabled() const
{
return gl_light_shadowmap && !!(gl.flags & RFL_SHADER_STORAGE_BUFFER);
}
int FShadowMap::ShadowMapIndex(ADynamicLight *light)
{
if (IsEnabled())
return mLightToShadowmap[light];
else
return 1024;
}
void FShadowMap::UploadLights()
{
mLights.Clear();
mLightToShadowmap.Clear(mLightToShadowmap.CountUsed() * 2); // To do: allow clearing a TMap while building up a reserve
TThinkerIterator<ADynamicLight> it(STAT_DLIGHT);
while (true)
{
ADynamicLight *light = it.Next();
if (!light) break;
mLightToShadowmap[light] = mLights.Size() / 4;
mLights.Push(light->X());
mLights.Push(light->Y());
mLights.Push(light->Z());
mLights.Push(light->GetRadius());
if (mLights.Size() == 1024) // Only 1024 lights for now
break;
}
while (mLights.Size() < 1024 * 4)
mLights.Push(0.0f);
if (mLightList == 0)
glGenBuffers(1, (GLuint*)&mLightList);
int oldBinding = 0;
glGetIntegerv(GL_SHADER_STORAGE_BUFFER_BINDING, &oldBinding);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, mLightList);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(float) * mLights.Size(), &mLights[0], GL_STATIC_DRAW);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, oldBinding);
}
void FShadowMap::UploadAABBTree()
{
if (numnodes != mLastNumNodes || numsegs != mLastNumSegs) // To do: there is probably a better way to detect a map change than this..
Clear();
if (mAABBTree)
return;
mAABBTree.reset(new 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);
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);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, oldBinding);
}
void FShadowMap::Clear()
{
if (mLightList != 0)
{
glDeleteBuffers(1, (GLuint*)&mLightList);
mLightList = 0;
}
if (mNodesBuffer != 0)
{
glDeleteBuffers(1, (GLuint*)&mNodesBuffer);
mNodesBuffer = 0;
}
if (mLinesBuffer != 0)
{
glDeleteBuffers(1, (GLuint*)&mLinesBuffer);
mLinesBuffer = 0;
}
mAABBTree.reset();
mLastNumNodes = numnodes;
mLastNumSegs = numsegs;
}

View file

@ -0,0 +1,60 @@
#pragma once
#include "gl/dynlights/gl_aabbtree.h"
#include "tarray.h"
#include <memory>
class ADynamicLight;
class FShadowMap
{
public:
FShadowMap() { }
~FShadowMap() { Clear(); }
// Release resources
void Clear();
// Update shadow map texture
void Update();
// Return the assigned shadow map index for a given light
int ShadowMapIndex(ADynamicLight *light);
// Test if a world position is in shadow relative to the specified light and returns false if it is
bool ShadowTest(ADynamicLight *light, const DVector3 &pos);
// Returns true if gl_light_shadowmap is enabled and supported by the hardware
bool IsEnabled() const;
private:
// Upload the AABB-tree to the GPU
void UploadAABBTree();
// Upload light list to the GPU
void UploadLights();
// OpenGL storage buffer with the list of lights in the shadow map texture
int mLightList = 0;
// Working buffer for creating the list of lights. Stored here to avoid allocating memory each frame
TArray<float> mLights;
// The assigned shadow map index for each light
TMap<ADynamicLight*, int> mLightToShadowmap;
// OpenGL storage buffers for the AABB tree
int mNodesBuffer = 0;
int mLinesBuffer = 0;
// Used to detect when a level change requires the AABB tree to be regenerated
int mLastNumNodes = 0;
int mLastNumSegs = 0;
// AABB-tree of the level, used for ray tests
std::unique_ptr<LevelAABBTree> mAABBTree;
FShadowMap(const FShadowMap &) = delete;
FShadowMap &operator=(FShadowMap &) = delete;
};

View file

@ -8,6 +8,5 @@ class AActor;
void gl_PreprocessLevel();
void gl_CleanLevelData();
void gl_LinkLights();
void gl_SetActorLights(AActor *);
#endif

View file

@ -1023,7 +1023,7 @@ void gl_RenderModel(GLSprite * spr)
if (spr->actor->renderflags & RF_INTERPOLATEANGLES)
{
// [Nash] use interpolated angles
DRotator Angles = spr->actor->InterpolatedAngles(r_TicFracF);
DRotator Angles = spr->actor->InterpolatedAngles(r_viewpoint.TicFrac);
angle = Angles.Yaw.Degrees;
}

View file

@ -59,7 +59,7 @@ public:
virtual int FindFrame(const char * name) = 0;
virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0) = 0;
virtual void BuildVertexBuffer() = 0;
virtual void AddSkins(BYTE *hitlist) = 0;
virtual void AddSkins(uint8_t *hitlist) = 0;
void DestroyVertexBuffer()
{
delete mVBuf;
@ -185,7 +185,7 @@ public:
virtual int FindFrame(const char * name);
virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0);
virtual void LoadGeometry();
virtual void AddSkins(BYTE *hitlist);
virtual void AddSkins(uint8_t *hitlist);
void UnloadGeometry();
void BuildVertexBuffer();
@ -292,7 +292,7 @@ public:
virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0);
void LoadGeometry();
void BuildVertexBuffer();
virtual void AddSkins(BYTE *hitlist);
virtual void AddSkins(uint8_t *hitlist);
};
struct FVoxelVertexHash
@ -335,7 +335,7 @@ protected:
TArray<unsigned int> mIndices;
void MakeSlabPolys(int x, int y, kvxslab_t *voxptr, FVoxelMap &check);
void AddFace(int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3, int x4, int y4, int z4, BYTE color, FVoxelMap &check);
void AddFace(int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3, int x4, int y4, int z4, uint8_t color, FVoxelMap &check);
unsigned int AddVertex(FModelVertex &vert, FVoxelMap &check);
public:
@ -345,7 +345,7 @@ public:
void Initialize();
virtual int FindFrame(const char * name);
virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0);
virtual void AddSkins(BYTE *hitlist);
virtual void AddSkins(uint8_t *hitlist);
FTextureID GetPaletteTexture() const { return mPalette; }
void BuildVertexBuffer();
float getAspectFactor();

View file

@ -300,7 +300,7 @@ void FMD3Model::BuildVertexBuffer()
//
//===========================================================================
void FMD3Model::AddSkins(BYTE *hitlist)
void FMD3Model::AddSkins(uint8_t *hitlist)
{
for (int i = 0; i < numSurfaces; i++)
{

View file

@ -65,8 +65,8 @@ public:
FVoxelTexture(FVoxel *voxel);
~FVoxelTexture();
const BYTE *GetColumn (unsigned int column, const Span **spans_out);
const BYTE *GetPixels ();
const uint8_t *GetColumn (unsigned int column, const Span **spans_out);
const uint8_t *GetPixels ();
void Unload ();
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf);
@ -74,7 +74,7 @@ public:
protected:
FVoxel *SourceVox;
BYTE *Pixels;
uint8_t *Pixels;
};
@ -107,20 +107,20 @@ FVoxelTexture::~FVoxelTexture()
{
}
const BYTE *FVoxelTexture::GetColumn (unsigned int column, const Span **spans_out)
const uint8_t *FVoxelTexture::GetColumn (unsigned int column, const Span **spans_out)
{
// not needed
return NULL;
}
const BYTE *FVoxelTexture::GetPixels ()
const uint8_t *FVoxelTexture::GetPixels ()
{
// GetPixels gets called when a translated palette is used so we still need to implement it here.
if (Pixels == NULL)
{
Pixels = new BYTE[256];
Pixels = new uint8_t[256];
BYTE *pp = SourceVox->Palette;
uint8_t *pp = SourceVox->Palette;
if(pp != NULL)
{
@ -137,7 +137,7 @@ const BYTE *FVoxelTexture::GetPixels ()
{
for(int i=0;i<256;i++, pp+=3)
{
Pixels[i] = (BYTE)i;
Pixels[i] = (uint8_t)i;
}
}
}
@ -165,14 +165,14 @@ void FVoxelTexture::Unload ()
int FVoxelTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf)
{
PalEntry pe[256];
BYTE bitmap[256];
BYTE *pp = SourceVox->Palette;
uint8_t bitmap[256];
uint8_t *pp = SourceVox->Palette;
if(pp != NULL)
{
for(int i=0;i<256;i++, pp+=3)
{
bitmap[i] = (BYTE)i;
bitmap[i] = (uint8_t)i;
pe[i].r = (pp[0] << 2) | (pp[0] >> 4);
pe[i].g = (pp[1] << 2) | (pp[1] >> 4);
pe[i].b = (pp[2] << 2) | (pp[2] >> 4);
@ -183,7 +183,7 @@ int FVoxelTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, F
{
for(int i=0;i<256;i++, pp+=3)
{
bitmap[i] = (BYTE)i;
bitmap[i] = (uint8_t)i;
pe[i] = GPalette.BaseColors[i];
pe[i].a = 255;
}
@ -239,7 +239,7 @@ unsigned int FVoxelModel::AddVertex(FModelVertex &vert, FVoxelMap &check)
//
//===========================================================================
void FVoxelModel::AddFace(int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3, int x4, int y4, int z4, BYTE col, FVoxelMap &check)
void FVoxelModel::AddFace(int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3, int x4, int y4, int z4, uint8_t col, FVoxelMap &check)
{
float PivotX = mVoxel->Mips[0].Pivot.X;
float PivotY = mVoxel->Mips[0].Pivot.Y;
@ -289,7 +289,7 @@ void FVoxelModel::AddFace(int x1, int y1, int z1, int x2, int y2, int z2, int x3
void FVoxelModel::MakeSlabPolys(int x, int y, kvxslab_t *voxptr, FVoxelMap &check)
{
const BYTE *col = voxptr->col;
const uint8_t *col = voxptr->col;
int zleng = voxptr->zleng;
int ztop = voxptr->ztop;
int cull = voxptr->backfacecull;
@ -342,13 +342,13 @@ void FVoxelModel::Initialize()
FVoxelMipLevel *mip = &mVoxel->Mips[0];
for (int x = 0; x < mip->SizeX; x++)
{
BYTE *slabxoffs = &mip->SlabData[mip->OffsetX[x]];
uint8_t *slabxoffs = &mip->SlabData[mip->OffsetX[x]];
short *xyoffs = &mip->OffsetXY[x * (mip->SizeY + 1)];
for (int y = 0; y < mip->SizeY; y++)
{
kvxslab_t *voxptr = (kvxslab_t *)(slabxoffs + xyoffs[y]);
kvxslab_t *voxend = (kvxslab_t *)(slabxoffs + xyoffs[y+1]);
for (; voxptr < voxend; voxptr = (kvxslab_t *)((BYTE *)voxptr + voxptr->zleng + 3))
for (; voxptr < voxend; voxptr = (kvxslab_t *)((uint8_t *)voxptr + voxptr->zleng + 3))
{
MakeSlabPolys(x, y, voxptr, check);
}
@ -394,7 +394,7 @@ void FVoxelModel::BuildVertexBuffer()
//
//===========================================================================
void FVoxelModel::AddSkins(BYTE *hitlist)
void FVoxelModel::AddSkins(uint8_t *hitlist)
{
hitlist[mPalette.GetIndex()] |= FTexture::TEX_Flat;
}

View file

@ -3,487 +3,487 @@
#endif
{
-0.525731, 0.000000, 0.850651},
-0.525731f, 0.000000f, 0.850651f},
{
-0.442863, 0.238856, 0.864188},
-0.442863f, 0.238856f, 0.864188f},
{
-0.295242, 0.000000, 0.955423},
-0.295242f, 0.000000f, 0.955423f},
{
-0.309017, 0.500000, 0.809017},
-0.309017f, 0.500000f, 0.809017f},
{
-0.162460, 0.262866, 0.951056},
-0.162460f, 0.262866f, 0.951056f},
{
0.000000, 0.000000, 1.000000},
0.000000f, 0.000000f, 1.000000f},
{
0.000000, 0.850651, 0.525731},
0.000000f, 0.850651f, 0.525731f},
{
-0.147621, 0.716567, 0.681718},
-0.147621f, 0.716567f, 0.681718f},
{
0.147621, 0.716567, 0.681718},
0.147621f, 0.716567f, 0.681718f},
{
0.000000, 0.525731, 0.850651},
0.000000f, 0.525731f, 0.850651f},
{
0.309017, 0.500000, 0.809017},
0.309017f, 0.500000f, 0.809017f},
{
0.525731, 0.000000, 0.850651},
0.525731f, 0.000000f, 0.850651f},
{
0.295242, 0.000000, 0.955423},
0.295242f, 0.000000f, 0.955423f},
{
0.442863, 0.238856, 0.864188},
0.442863f, 0.238856f, 0.864188f},
{
0.162460, 0.262866, 0.951056},
0.162460f, 0.262866f, 0.951056f},
{
-0.681718, 0.147621, 0.716567},
-0.681718f, 0.147621f, 0.716567f},
{
-0.809017, 0.309017, 0.500000},
-0.809017f, 0.309017f, 0.500000f},
{
-0.587785, 0.425325, 0.688191},
-0.587785f, 0.425325f, 0.688191f},
{
-0.850651, 0.525731, 0.000000},
-0.850651f, 0.525731f, 0.000000f},
{
-0.864188, 0.442863, 0.238856},
-0.864188f, 0.442863f, 0.238856f},
{
-0.716567, 0.681718, 0.147621},
-0.716567f, 0.681718f, 0.147621f},
{
-0.688191, 0.587785, 0.425325},
-0.688191f, 0.587785f, 0.425325f},
{
-0.500000, 0.809017, 0.309017},
-0.500000f, 0.809017f, 0.309017f},
{
-0.238856, 0.864188, 0.442863},
-0.238856f, 0.864188f, 0.442863f},
{
-0.425325, 0.688191, 0.587785},
-0.425325f, 0.688191f, 0.587785f},
{
-0.716567, 0.681718, -0.147621},
-0.716567f, 0.681718f, -0.147621f},
{
-0.500000, 0.809017, -0.309017},
-0.500000f, 0.809017f, -0.309017f},
{
-0.525731, 0.850651, 0.000000},
-0.525731f, 0.850651f, 0.000000f},
{
0.000000, 0.850651, -0.525731},
0.000000f, 0.850651f, -0.525731f},
{
-0.238856, 0.864188, -0.442863},
-0.238856f, 0.864188f, -0.442863f},
{
0.000000, 0.955423, -0.295242},
0.000000f, 0.955423f, -0.295242f},
{
-0.262866, 0.951056, -0.162460},
-0.262866f, 0.951056f, -0.162460f},
{
0.000000, 1.000000, 0.000000},
0.000000f, 1.000000f, 0.000000f},
{
0.000000, 0.955423, 0.295242},
0.000000f, 0.955423f, 0.295242f},
{
-0.262866, 0.951056, 0.162460},
-0.262866f, 0.951056f, 0.162460f},
{
0.238856, 0.864188, 0.442863},
0.238856f, 0.864188f, 0.442863f},
{
0.262866, 0.951056, 0.162460},
0.262866f, 0.951056f, 0.162460f},
{
0.500000, 0.809017, 0.309017},
0.500000f, 0.809017f, 0.309017f},
{
0.238856, 0.864188, -0.442863},
0.238856f, 0.864188f, -0.442863f},
{
0.262866, 0.951056, -0.162460},
0.262866f, 0.951056f, -0.162460f},
{
0.500000, 0.809017, -0.309017},
0.500000f, 0.809017f, -0.309017f},
{
0.850651, 0.525731, 0.000000},
0.850651f, 0.525731f, 0.000000f},
{
0.716567, 0.681718, 0.147621},
0.716567f, 0.681718f, 0.147621f},
{
0.716567, 0.681718, -0.147621},
0.716567f, 0.681718f, -0.147621f},
{
0.525731, 0.850651, 0.000000},
0.525731f, 0.850651f, 0.000000f},
{
0.425325, 0.688191, 0.587785},
0.425325f, 0.688191f, 0.587785f},
{
0.864188, 0.442863, 0.238856},
0.864188f, 0.442863f, 0.238856f},
{
0.688191, 0.587785, 0.425325},
0.688191f, 0.587785f, 0.425325f},
{
0.809017, 0.309017, 0.500000},
0.809017f, 0.309017f, 0.500000f},
{
0.681718, 0.147621, 0.716567},
0.681718f, 0.147621f, 0.716567f},
{
0.587785, 0.425325, 0.688191},
0.587785f, 0.425325f, 0.688191f},
{
0.955423, 0.295242, 0.000000},
0.955423f, 0.295242f, 0.000000f},
{
1.000000, 0.000000, 0.000000},
1.000000f, 0.000000f, 0.000000f},
{
0.951056, 0.162460, 0.262866},
0.951056f, 0.162460f, 0.262866f},
{
0.850651, -0.525731, 0.000000},
0.850651f, -0.525731f, 0.000000f},
{
0.955423, -0.295242, 0.000000},
0.955423f, -0.295242f, 0.000000f},
{
0.864188, -0.442863, 0.238856},
0.864188f, -0.442863f, 0.238856f},
{
0.951056, -0.162460, 0.262866},
0.951056f, -0.162460f, 0.262866f},
{
0.809017, -0.309017, 0.500000},
0.809017f, -0.309017f, 0.500000f},
{
0.681718, -0.147621, 0.716567},
0.681718f, -0.147621f, 0.716567f},
{
0.850651, 0.000000, 0.525731},
0.850651f, 0.000000f, 0.525731f},
{
0.864188, 0.442863, -0.238856},
0.864188f, 0.442863f, -0.238856f},
{
0.809017, 0.309017, -0.500000},
0.809017f, 0.309017f, -0.500000f},
{
0.951056, 0.162460, -0.262866},
0.951056f, 0.162460f, -0.262866f},
{
0.525731, 0.000000, -0.850651},
0.525731f, 0.000000f, -0.850651f},
{
0.681718, 0.147621, -0.716567},
0.681718f, 0.147621f, -0.716567f},
{
0.681718, -0.147621, -0.716567},
0.681718f, -0.147621f, -0.716567f},
{
0.850651, 0.000000, -0.525731},
0.850651f, 0.000000f, -0.525731f},
{
0.809017, -0.309017, -0.500000},
0.809017f, -0.309017f, -0.500000f},
{
0.864188, -0.442863, -0.238856},
0.864188f, -0.442863f, -0.238856f},
{
0.951056, -0.162460, -0.262866},
0.951056f, -0.162460f, -0.262866f},
{
0.147621, 0.716567, -0.681718},
0.147621f, 0.716567f, -0.681718f},
{
0.309017, 0.500000, -0.809017},
0.309017f, 0.500000f, -0.809017f},
{
0.425325, 0.688191, -0.587785},
0.425325f, 0.688191f, -0.587785f},
{
0.442863, 0.238856, -0.864188},
0.442863f, 0.238856f, -0.864188f},
{
0.587785, 0.425325, -0.688191},
0.587785f, 0.425325f, -0.688191f},
{
0.688191, 0.587785, -0.425325},
0.688191f, 0.587785f, -0.425325f},
{
-0.147621, 0.716567, -0.681718},
-0.147621f, 0.716567f, -0.681718f},
{
-0.309017, 0.500000, -0.809017},
-0.309017f, 0.500000f, -0.809017f},
{
0.000000, 0.525731, -0.850651},
0.000000f, 0.525731f, -0.850651f},
{
-0.525731, 0.000000, -0.850651},
-0.525731f, 0.000000f, -0.850651f},
{
-0.442863, 0.238856, -0.864188},
-0.442863f, 0.238856f, -0.864188f},
{
-0.295242, 0.000000, -0.955423},
-0.295242f, 0.000000f, -0.955423f},
{
-0.162460, 0.262866, -0.951056},
-0.162460f, 0.262866f, -0.951056f},
{
0.000000, 0.000000, -1.000000},
0.000000f, 0.000000f, -1.000000f},
{
0.295242, 0.000000, -0.955423},
0.295242f, 0.000000f, -0.955423f},
{
0.162460, 0.262866, -0.951056},
0.162460f, 0.262866f, -0.951056f},
{
-0.442863, -0.238856, -0.864188},
-0.442863f, -0.238856f, -0.864188f},
{
-0.309017, -0.500000, -0.809017},
-0.309017f, -0.500000f, -0.809017f},
{
-0.162460, -0.262866, -0.951056},
-0.162460f, -0.262866f, -0.951056f},
{
0.000000, -0.850651, -0.525731},
0.000000f, -0.850651f, -0.525731f},
{
-0.147621, -0.716567, -0.681718},
-0.147621f, -0.716567f, -0.681718f},
{
0.147621, -0.716567, -0.681718},
0.147621f, -0.716567f, -0.681718f},
{
0.000000, -0.525731, -0.850651},
0.000000f, -0.525731f, -0.850651f},
{
0.309017, -0.500000, -0.809017},
0.309017f, -0.500000f, -0.809017f},
{
0.442863, -0.238856, -0.864188},
0.442863f, -0.238856f, -0.864188f},
{
0.162460, -0.262866, -0.951056},
0.162460f, -0.262866f, -0.951056f},
{
0.238856, -0.864188, -0.442863},
0.238856f, -0.864188f, -0.442863f},
{
0.500000, -0.809017, -0.309017},
0.500000f, -0.809017f, -0.309017f},
{
0.425325, -0.688191, -0.587785},
0.425325f, -0.688191f, -0.587785f},
{
0.716567, -0.681718, -0.147621},
0.716567f, -0.681718f, -0.147621f},
{
0.688191, -0.587785, -0.425325},
0.688191f, -0.587785f, -0.425325f},
{
0.587785, -0.425325, -0.688191},
0.587785f, -0.425325f, -0.688191f},
{
0.000000, -0.955423, -0.295242},
0.000000f, -0.955423f, -0.295242f},
{
0.000000, -1.000000, 0.000000},
0.000000f, -1.000000f, 0.000000f},
{
0.262866, -0.951056, -0.162460},
0.262866f, -0.951056f, -0.162460f},
{
0.000000, -0.850651, 0.525731},
0.000000f, -0.850651f, 0.525731f},
{
0.000000, -0.955423, 0.295242},
0.000000f, -0.955423f, 0.295242f},
{
0.238856, -0.864188, 0.442863},
0.238856f, -0.864188f, 0.442863f},
{
0.262866, -0.951056, 0.162460},
0.262866f, -0.951056f, 0.162460f},
{
0.500000, -0.809017, 0.309017},
0.500000f, -0.809017f, 0.309017f},
{
0.716567, -0.681718, 0.147621},
0.716567f, -0.681718f, 0.147621f},
{
0.525731, -0.850651, 0.000000},
0.525731f, -0.850651f, 0.000000f},
{
-0.238856, -0.864188, -0.442863},
-0.238856f, -0.864188f, -0.442863f},
{
-0.500000, -0.809017, -0.309017},
-0.500000f, -0.809017f, -0.309017f},
{
-0.262866, -0.951056, -0.162460},
-0.262866f, -0.951056f, -0.162460f},
{
-0.850651, -0.525731, 0.000000},
-0.850651f, -0.525731f, 0.000000f},
{
-0.716567, -0.681718, -0.147621},
-0.716567f, -0.681718f, -0.147621f},
{
-0.716567, -0.681718, 0.147621},
-0.716567f, -0.681718f, 0.147621f},
{
-0.525731, -0.850651, 0.000000},
-0.525731f, -0.850651f, 0.000000f},
{
-0.500000, -0.809017, 0.309017},
-0.500000f, -0.809017f, 0.309017f},
{
-0.238856, -0.864188, 0.442863},
-0.238856f, -0.864188f, 0.442863f},
{
-0.262866, -0.951056, 0.162460},
-0.262866f, -0.951056f, 0.162460f},
{
-0.864188, -0.442863, 0.238856},
-0.864188f, -0.442863f, 0.238856f},
{
-0.809017, -0.309017, 0.500000},
-0.809017f, -0.309017f, 0.500000f},
{
-0.688191, -0.587785, 0.425325},
-0.688191f, -0.587785f, 0.425325f},
{
-0.681718, -0.147621, 0.716567},
-0.681718f, -0.147621f, 0.716567f},
{
-0.442863, -0.238856, 0.864188},
-0.442863f, -0.238856f, 0.864188f},
{
-0.587785, -0.425325, 0.688191},
-0.587785f, -0.425325f, 0.688191f},
{
-0.309017, -0.500000, 0.809017},
-0.309017f, -0.500000f, 0.809017f},
{
-0.147621, -0.716567, 0.681718},
-0.147621f, -0.716567f, 0.681718f},
{
-0.425325, -0.688191, 0.587785},
-0.425325f, -0.688191f, 0.587785f},
{
-0.162460, -0.262866, 0.951056},
-0.162460f, -0.262866f, 0.951056f},
{
0.442863, -0.238856, 0.864188},
0.442863f, -0.238856f, 0.864188f},
{
0.162460, -0.262866, 0.951056},
0.162460f, -0.262866f, 0.951056f},
{
0.309017, -0.500000, 0.809017},
0.309017f, -0.500000f, 0.809017f},
{
0.147621, -0.716567, 0.681718},
0.147621f, -0.716567f, 0.681718f},
{
0.000000, -0.525731, 0.850651},
0.000000f, -0.525731f, 0.850651f},
{
0.425325, -0.688191, 0.587785},
0.425325f, -0.688191f, 0.587785f},
{
0.587785, -0.425325, 0.688191},
0.587785f, -0.425325f, 0.688191f},
{
0.688191, -0.587785, 0.425325},
0.688191f, -0.587785f, 0.425325f},
{
-0.955423, 0.295242, 0.000000},
-0.955423f, 0.295242f, 0.000000f},
{
-0.951056, 0.162460, 0.262866},
-0.951056f, 0.162460f, 0.262866f},
{
-1.000000, 0.000000, 0.000000},
-1.000000f, 0.000000f, 0.000000f},
{
-0.850651, 0.000000, 0.525731},
-0.850651f, 0.000000f, 0.525731f},
{
-0.955423, -0.295242, 0.000000},
-0.955423f, -0.295242f, 0.000000f},
{
-0.951056, -0.162460, 0.262866},
-0.951056f, -0.162460f, 0.262866f},
{
-0.864188, 0.442863, -0.238856},
-0.864188f, 0.442863f, -0.238856f},
{
-0.951056, 0.162460, -0.262866},
-0.951056f, 0.162460f, -0.262866f},
{
-0.809017, 0.309017, -0.500000},
-0.809017f, 0.309017f, -0.500000f},
{
-0.864188, -0.442863, -0.238856},
-0.864188f, -0.442863f, -0.238856f},
{
-0.951056, -0.162460, -0.262866},
-0.951056f, -0.162460f, -0.262866f},
{
-0.809017, -0.309017, -0.500000},
-0.809017f, -0.309017f, -0.500000f},
{
-0.681718, 0.147621, -0.716567},
-0.681718f, 0.147621f, -0.716567f},
{
-0.681718, -0.147621, -0.716567},
-0.681718f, -0.147621f, -0.716567f},
{
-0.850651, 0.000000, -0.525731},
-0.850651f, 0.000000f, -0.525731f},
{
-0.688191, 0.587785, -0.425325},
-0.688191f, 0.587785f, -0.425325f},
{
-0.587785, 0.425325, -0.688191},
-0.587785f, 0.425325f, -0.688191f},
{
-0.425325, 0.688191, -0.587785},
-0.425325f, 0.688191f, -0.587785f},
{
-0.425325, -0.688191, -0.587785},
-0.425325f, -0.688191f, -0.587785f},
{
-0.587785, -0.425325, -0.688191},
-0.587785f, -0.425325f, -0.688191f},
{
-0.688191, -0.587785, -0.425325},
-0.688191f, -0.587785f, -0.425325f},

View file

@ -139,7 +139,7 @@ void F2DDrawer::AddTexture(FTexture *img, DrawParms &parms)
{
color = PalEntry(light, light, light);
}
color.a = (BYTE)(parms.Alpha * 255);
color.a = (uint8_t)(parms.Alpha * 255);
// scissor test doesn't use the current viewport for the coordinates, so use real screen coordinates
dg.mScissor[0] = GLRenderer->ScreenToWindowX(parms.lclip);
@ -253,7 +253,7 @@ void F2DDrawer::AddDim(PalEntry color, float damount, int x1, int y1, int w, int
//
//==========================================================================
void F2DDrawer::AddClear(int left, int top, int right, int bottom, int palcolor, uint32 color)
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);
@ -311,7 +311,7 @@ void F2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FTexture *
//
//==========================================================================
void F2DDrawer::AddLine(int x1, int y1, int x2, int y2, int palcolor, uint32 color)
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;
@ -344,7 +344,7 @@ void F2DDrawer::AddLine(int x1, int y1, int x2, int y2, int palcolor, uint32 col
//
//==========================================================================
void F2DDrawer::AddPixel(int x1, int y1, int palcolor, uint32 color)
void F2DDrawer::AddPixel(int x1, int y1, int palcolor, uint32_t color)
{
PalEntry p = color ? (PalEntry)color : GPalette.BaseColors[palcolor];
p.a = 255;
@ -372,7 +372,7 @@ void F2DDrawer::Draw()
F2DDrawer::EDrawType lasttype = DrawTypeTexture;
if (mData.Size() == 0) return;
SBYTE savedlightmode = glset.lightmode;
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;

View file

@ -57,15 +57,15 @@ class F2DDrawer : public FSimpleVertexBuffer
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 color);
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, FDynamicColormap *colormap, PalEntry flatcolor, int lightlevel);
void AddLine(int x1, int y1, int x2, int y2, int palcolor, uint32 color);
void AddPixel(int x1, int y1, int palcolor, uint32 color);
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();

View file

@ -79,5 +79,4 @@ struct FColormap
};
#endif

View file

@ -59,7 +59,6 @@ CUSTOM_CVAR(Bool, gl_enhanced_nightvision, true, CVAR_ARCHIVE|CVAR_NOINITCALL)
}
CVAR(Bool, gl_brightfog, false, CVAR_ARCHIVE);
CVAR(Bool, gl_lightadditivesurfaces, false, CVAR_ARCHIVE);
CVAR(Bool, gl_attenuate, false, CVAR_ARCHIVE);
@ -253,7 +252,7 @@ static PalEntry gl_CalcLightColor(int light, PalEntry pe, int blendfactor)
g = (mixlight + pe.g * blendfactor) / 255;
b = (mixlight + pe.b * blendfactor) / 255;
}
return PalEntry(255, BYTE(r), BYTE(g), BYTE(b));
return PalEntry(255, uint8_t(r), uint8_t(g), uint8_t(b));
}
//==========================================================================

View file

@ -42,9 +42,6 @@ inline bool gl_isFullbright(PalEntry color, int lightlevel)
return gl_fixedcolormap || (gl_isWhite(color) && lightlevel==255);
}
void gl_DeleteAllAttachedLights();
void gl_RecreateAllAttachedLights();
extern int fogdensity;
extern int outsidefogdensity;
extern int skyfog;

View file

@ -529,7 +529,7 @@ void FGLRenderer::CreateTonemapPalette()
{
for (int b = 0; b < 64; b++)
{
PalEntry color = GPalette.BaseColors[(BYTE)PTM_BestColor((uint32 *)GPalette.BaseColors, (r << 2) | (r >> 4), (g << 2) | (g >> 4), (b << 2) | (b >> 4), 0, 256)];
PalEntry color = GPalette.BaseColors[(uint8_t)PTM_BestColor((uint32_t *)GPalette.BaseColors, (r << 2) | (r >> 4), (g << 2) | (g >> 4), (b << 2) | (b >> 4), 0, 256)];
int index = ((r * 64 + g) * 64 + b) * 4;
lut[index] = color.r;
lut[index + 1] = color.g;
@ -832,7 +832,7 @@ void FGLRenderer::ClearBorders()
// [SP] Re-implemented BestColor for more precision rather than speed. This function is only ever called once until the game palette is changed.
int FGLRenderer::PTM_BestColor (const uint32 *pal_in, int r, int g, int b, int first, int num)
int FGLRenderer::PTM_BestColor (const uint32_t *pal_in, int r, int g, int b, int first, int num)
{
const PalEntry *pal = (const PalEntry *)pal_in;
static double powtable[256];
@ -840,7 +840,7 @@ int FGLRenderer::PTM_BestColor (const uint32 *pal_in, int r, int g, int b, int f
static float trackpowtable = 0.;
double fbestdist, fdist;
int bestcolor;
int bestcolor = 0;
if (firstTime || trackpowtable != gl_paltonemap_powtable)
{

View file

@ -26,7 +26,6 @@
*/
#include "gl/system/gl_system.h"
#include "files.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
@ -741,6 +740,49 @@ void FGLRenderBuffers::BindEyeFB(int eye, bool readBuffer)
glBindFramebuffer(readBuffer ? GL_READ_FRAMEBUFFER : GL_FRAMEBUFFER, mEyeFBs[eye]);
}
//==========================================================================
//
// Shadow map texture and frame buffers
//
//==========================================================================
void FGLRenderBuffers::BindShadowMapFB()
{
CreateShadowMap();
glBindFramebuffer(GL_FRAMEBUFFER, mShadowMapFB);
}
void FGLRenderBuffers::BindShadowMapTexture(int texunit)
{
CreateShadowMap();
glActiveTexture(GL_TEXTURE0 + texunit);
glBindTexture(GL_TEXTURE_2D, mShadowMapTexture);
}
void FGLRenderBuffers::CreateShadowMap()
{
if (mShadowMapTexture != 0)
return;
GLint activeTex, textureBinding, frameBufferBinding;
glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex);
glActiveTexture(GL_TEXTURE0);
glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &frameBufferBinding);
mShadowMapTexture = Create2DTexture("ShadowMap", GL_R32F, 1024, 1024);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
mShadowMapFB = CreateFrameBuffer("ShadowMapFB", mShadowMapTexture);
glBindTexture(GL_TEXTURE_2D, textureBinding);
glActiveTexture(activeTex);
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferBinding);
}
//==========================================================================
//
// Makes the scene frame buffer active (multisample, depth, stecil, etc.)

View file

@ -49,6 +49,9 @@ public:
void BindEyeTexture(int eye, int texunit);
void BindEyeFB(int eye, bool readBuffer = false);
void BindShadowMapFB();
void BindShadowMapTexture(int index);
enum { NumBloomLevels = 4 };
FGLBloomTextureLevel BloomLevels[NumBloomLevels];
@ -89,6 +92,7 @@ private:
void CreateBloom(int width, int height);
void CreateExposureLevels(int width, int height);
void CreateEyeBuffers(int eye);
void CreateShadowMap();
void CreateAmbientOcclusion(int width, int height);
GLuint Create2DTexture(const FString &name, GLuint format, int width, int height, const void *data = nullptr);
GLuint Create2DMultisampleTexture(const FString &name, GLuint format, int width, int height, int samples, bool fixedSampleLocations);
@ -133,6 +137,10 @@ private:
TArray<GLuint> mEyeTextures;
TArray<GLuint> mEyeFBs;
// Shadow map texture
GLuint mShadowMapTexture = 0;
GLuint mShadowMapFB = 0;
static bool FailedCreate;
static bool BuffersActive;
};

View file

@ -60,6 +60,7 @@
#include "gl/shaders/gl_fxaashader.h"
#include "gl/shaders/gl_presentshader.h"
#include "gl/shaders/gl_present3dRowshader.h"
#include "gl/shaders/gl_shadowmapshader.h"
#include "gl/stereo3d/gl_stereo3d.h"
#include "gl/textures/gl_texture.h"
#include "gl/textures/gl_translate.h"
@ -125,6 +126,7 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb)
mSSAOCombineShader = nullptr;
mFXAAShader = nullptr;
mFXAALumaShader = nullptr;
mShadowMapShader = nullptr;
}
void gl_LoadModels();
@ -153,6 +155,7 @@ void FGLRenderer::Initialize(int width, int height)
mPresent3dCheckerShader = new FPresent3DCheckerShader();
mPresent3dColumnShader = new FPresent3DColumnShader();
mPresent3dRowShader = new FPresent3DRowShader();
mShadowMapShader = new FShadowMapShader();
m2DDrawer = new F2DDrawer;
// needed for the core profile, because someone decided it was a good idea to remove the default VAO.
@ -186,7 +189,7 @@ void FGLRenderer::Initialize(int width, int height)
FGLRenderer::~FGLRenderer()
{
gl_FlushModels();
gl_DeleteAllAttachedLights();
AActor::DeleteAllAttachedLights();
FMaterial::FlushAll();
if (m2DDrawer != nullptr) delete m2DDrawer;
if (mShaderManager != NULL) delete mShaderManager;
@ -223,6 +226,7 @@ FGLRenderer::~FGLRenderer()
if (mTonemapPalette) delete mTonemapPalette;
if (mColormapShader) delete mColormapShader;
if (mLensShader) delete mLensShader;
if (mShadowMapShader) delete mShadowMapShader;
delete mFXAAShader;
delete mFXAALumaShader;
}

View file

@ -6,6 +6,7 @@
#include "vectors.h"
#include "r_renderer.h"
#include "gl/data/gl_matrix.h"
#include "gl/dynlights/gl_shadowmap.h"
struct particle_t;
class FCanvasTexture;
@ -40,6 +41,7 @@ class FPresent3DColumnShader;
class FPresent3DRowShader;
class F2DDrawer;
class FHardwareTexture;
class FShadowMapShader;
inline float DEG2RAD(float deg)
{
@ -123,6 +125,9 @@ public:
FPresent3DCheckerShader *mPresent3dCheckerShader;
FPresent3DColumnShader *mPresent3dColumnShader;
FPresent3DRowShader *mPresent3dRowShader;
FShadowMapShader *mShadowMapShader;
FShadowMap mShadowMap;
FTexture *gllight;
FTexture *glpart2;
@ -153,23 +158,8 @@ public:
int ScreenToWindowX(int x);
int ScreenToWindowY(int y);
angle_t FrustumAngle();
void SetViewArea();
void Set3DViewport(bool mainview);
void Reset3DViewport();
sector_t *RenderViewpoint (AActor * camera, GL_IRECT * bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen);
void RenderView(player_t *player);
void SetViewAngle(DAngle viewangle);
void SetupView(float viewx, float viewy, float viewz, DAngle viewangle, bool mirror, bool planemirror);
void Initialize(int width, int height);
void CreateScene();
void RenderMultipassStuff();
void RenderScene(int recursion);
void RenderTranslucent();
void DrawScene(int drawmode);
void DrawBlend(sector_t * viewsector);
void DrawPSprite (player_t * player,DPSprite *psp,float sx, float sy, bool hudModelStep, int OverrideShader, bool alphatexture);
void DrawPlayerSprites(sector_t * viewsector, bool hudModelStep);
@ -187,12 +177,9 @@ public:
void SetupLevel();
void RenderScreenQuad();
void SetFixedColormap (player_t *player);
void WriteSavePic (player_t *player, FileWriter *file, int width, int height);
void EndDrawScene(sector_t * viewsector);
void UpdateCameraExposure();
void PostProcessScene();
void AmbientOccludeScene();
void UpdateCameraExposure();
void BloomScene();
void TonemapScene();
void ColormapScene();
@ -204,10 +191,6 @@ public:
void DrawPresentTexture(const GL_IRECT &box, bool applyGamma);
void Flush();
void SetProjection(float fov, float ratio, float fovratio);
void SetProjection(VSMatrix matrix); // raw matrix input from stereo 3d modes
void SetViewMatrix(float vx, float vy, float vz, bool mirror, bool planemirror);
void ProcessScene(bool toscreen = false);
bool StartOffscreen();
void EndOffscreen();
@ -216,7 +199,7 @@ public:
double originx, double originy, double scalex, double scaley,
DAngle rotation, FDynamicColormap *colormap, PalEntry flatcolor, int lightlevel, int bottomclip);
int PTM_BestColor (const uint32 *pal_in, int r, int g, int b, int first, int num);
int PTM_BestColor (const uint32_t *pal_in, int r, int g, int b, int first, int num);
static float GetZNear() { return 5.f; }
static float GetZFar() { return 65536.f; }

View file

@ -33,35 +33,31 @@
#include "p_effect.h"
#include "po_man.h"
#include "doomdata.h"
#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_clipper.h"
#include "gl/scene/gl_scenedrawer.h"
#include "gl/scene/gl_portal.h"
#include "gl/scene/gl_wall.h"
#include "gl/utility/gl_clock.h"
EXTERN_CVAR(Bool, gl_render_segs)
Clipper clipper;
CVAR(Bool, gl_render_things, true, 0)
CVAR(Bool, gl_render_walls, true, 0)
CVAR(Bool, gl_render_flats, true, 0)
extern fixed_t viewx, viewy;
static void UnclipSubsector(subsector_t *sub)
void GLSceneDrawer::UnclipSubsector(subsector_t *sub)
{
int count = sub->numlines;
seg_t * seg = sub->firstline;
while (count--)
{
angle_t startAngle = seg->v2->GetClipAngle();
angle_t endAngle = seg->v1->GetClipAngle();
angle_t startAngle = clipper.GetClipAngle(seg->v2);
angle_t endAngle = clipper.GetClipAngle(seg->v1);
// Back side, i.e. backface culling - read: endAngle >= startAngle!
if (startAngle-endAngle >= ANGLE_180)
@ -81,11 +77,7 @@ static void UnclipSubsector(subsector_t *sub)
//
//==========================================================================
// making these 2 variables global instead of passing them as function parameters is faster.
static subsector_t *currentsubsector;
static sector_t *currentsector;
static void AddLine (seg_t *seg, bool portalclip)
void GLSceneDrawer::AddLine (seg_t *seg, bool portalclip)
{
#ifdef _DEBUG
if (seg->linedef->Index() == 38)
@ -94,7 +86,6 @@ static void AddLine (seg_t *seg, bool portalclip)
}
#endif
angle_t startAngle, endAngle;
sector_t * backsector = NULL;
sector_t bs;
@ -104,8 +95,8 @@ static void AddLine (seg_t *seg, bool portalclip)
if (clipres == GLPortal::PClip_InFront) return;
}
startAngle = seg->v2->GetClipAngle();
endAngle = seg->v1->GetClipAngle();
angle_t startAngle = clipper.GetClipAngle(seg->v2);
angle_t endAngle = clipper.GetClipAngle(seg->v1);
// Back side, i.e. backface culling - read: endAngle >= startAngle!
if (startAngle-endAngle<ANGLE_180)
@ -131,7 +122,7 @@ static void AddLine (seg_t *seg, bool portalclip)
}
currentsubsector->flags |= SSECF_DRAWN;
BYTE ispoly = BYTE(seg->sidedef->Flags & WALLF_POLYOBJ);
uint8_t ispoly = uint8_t(seg->sidedef->Flags & WALLF_POLYOBJ);
if (!seg->backsector)
{
@ -201,7 +192,7 @@ static void AddLine (seg_t *seg, bool portalclip)
//
//==========================================================================
static void PolySubsector(subsector_t * sub)
void GLSceneDrawer::PolySubsector(subsector_t * sub)
{
int count = sub->numlines;
seg_t * line = sub->firstline;
@ -225,7 +216,7 @@ static void PolySubsector(subsector_t * sub)
//
//==========================================================================
static void RenderPolyBSPNode (void *node)
void GLSceneDrawer::RenderPolyBSPNode (void *node)
{
while (!((size_t)node & 1)) // Keep going until found a subsector
{
@ -248,7 +239,7 @@ static void RenderPolyBSPNode (void *node)
node = bsp->children[side];
}
PolySubsector ((subsector_t *)((BYTE *)node - 1));
PolySubsector ((subsector_t *)((uint8_t *)node - 1));
}
//==========================================================================
@ -258,7 +249,7 @@ static void RenderPolyBSPNode (void *node)
//
//==========================================================================
static void AddPolyobjs(subsector_t *sub)
void GLSceneDrawer::AddPolyobjs(subsector_t *sub)
{
if (sub->BSP == NULL || sub->BSP->bDirty)
{
@ -286,7 +277,7 @@ static void AddPolyobjs(subsector_t *sub)
//
//==========================================================================
static inline void AddLines(subsector_t * sub, sector_t * sector)
void GLSceneDrawer::AddLines(subsector_t * sub, sector_t * sector)
{
currentsector = sector;
currentsubsector = sub;
@ -330,7 +321,7 @@ inline bool PointOnLine(const DVector2 &pos, const line_t *line)
return fabs(v) <= EQUAL_EPSILON;
}
static inline void AddSpecialPortalLines(subsector_t * sub, sector_t * sector, line_t *line)
void GLSceneDrawer::AddSpecialPortalLines(subsector_t * sub, sector_t * sector, line_t *line)
{
currentsector = sector;
currentsubsector = sub;
@ -358,9 +349,8 @@ static inline void AddSpecialPortalLines(subsector_t * sub, sector_t * sector, l
//
//==========================================================================
static inline void RenderThings(subsector_t * sub, sector_t * sector)
void GLSceneDrawer::RenderThings(subsector_t * sub, sector_t * sector)
{
SetupSprite.Clock();
sector_t * sec=sub->sector;
// Handle all things in sector.
@ -373,7 +363,7 @@ static inline void RenderThings(subsector_t * sub, sector_t * sector)
FIntCVar *cvar = thing->GetClass()->distancecheck;
if (cvar != NULL && *cvar >= 0)
{
double dist = (thing->Pos() - ViewPos).LengthSquared();
double dist = (thing->Pos() - r_viewpoint.Pos).LengthSquared();
double check = (double)**cvar;
if (dist >= check * check)
{
@ -390,7 +380,7 @@ static inline void RenderThings(subsector_t * sub, sector_t * sector)
FIntCVar *cvar = thing->GetClass()->distancecheck;
if (cvar != NULL && *cvar >= 0)
{
double dist = (thing->Pos() - ViewPos).LengthSquared();
double dist = (thing->Pos() - r_viewpoint.Pos).LengthSquared();
double check = (double)**cvar;
if (dist >= check * check)
{
@ -413,7 +403,7 @@ static inline void RenderThings(subsector_t * sub, sector_t * sector)
//
//==========================================================================
static void DoSubsector(subsector_t * sub)
void GLSceneDrawer::DoSubsector(subsector_t * sub)
{
unsigned int i;
sector_t * sector;
@ -468,7 +458,7 @@ static void DoSubsector(subsector_t * sub)
{
SetupSprite.Clock();
for (i = ParticlesInSubsec[DWORD(sub-subsectors)]; i != NO_PARTICLE; i = Particles[i].snext)
for (i = ParticlesInSubsec[uint32_t(sub-subsectors)]; i != NO_PARTICLE; i = Particles[i].snext)
{
GLRenderer->ProcessParticle(&Particles[i], fakesector);
}
@ -512,7 +502,7 @@ static void DoSubsector(subsector_t * sub)
fakesector = gl_FakeFlat(sector, &fake, false);
}
BYTE &srf = gl_drawinfo->sectorrenderflags[sub->render_sector->sectornum];
uint8_t &srf = gl_drawinfo->sectorrenderflags[sub->render_sector->sectornum];
if (!(srf & SSRF_PROCESSED))
{
srf |= SSRF_PROCESSED;
@ -558,7 +548,7 @@ static void DoSubsector(subsector_t * sub)
//
//==========================================================================
void gl_RenderBSPNode (void *node)
void GLSceneDrawer::RenderBSPNode (void *node)
{
if (numnodes == 0)
{
@ -573,7 +563,7 @@ void gl_RenderBSPNode (void *node)
int side = R_PointOnSide(viewx, viewy, bsp);
// Recursively divide front space (toward the viewer).
gl_RenderBSPNode (bsp->children[side]);
RenderBSPNode (bsp->children[side]);
// Possibly divide back space (away from the viewer).
side ^= 1;
@ -587,7 +577,7 @@ void gl_RenderBSPNode (void *node)
node = bsp->children[side];
}
DoSubsector ((subsector_t *)((BYTE *)node - 1));
DoSubsector ((subsector_t *)((uint8_t *)node - 1));
}

View file

@ -36,28 +36,12 @@
*/
#include "gl/scene/gl_clipper.h"
#include "g_levellocals.h"
ClipNode * ClipNode::freelist;
int Clipper::anglecache;
//-----------------------------------------------------------------------------
//
// Destructor
//
//-----------------------------------------------------------------------------
Clipper::~Clipper()
Clipper::Clipper()
{
Clear();
while (ClipNode::freelist != NULL)
{
ClipNode * node = ClipNode::freelist;
ClipNode::freelist = node->next;
delete node;
}
starttime = I_MSTime();
}
//-----------------------------------------------------------------------------
@ -78,7 +62,7 @@ void Clipper::RemoveRange(ClipNode * range)
if (range->next) range->next->prev = range->prev;
}
range->Free();
Free(range);
}
//-----------------------------------------------------------------------------
@ -97,7 +81,7 @@ void Clipper::Clear()
{
temp = node;
node = node->next;
temp->Free();
Free(temp);
}
node = silhouette;
@ -105,12 +89,12 @@ void Clipper::Clear()
{
temp = node;
node = node->next;
temp->Free();
Free(temp);
}
cliphead = NULL;
silhouette = NULL;
anglecache++;
starttime = I_MSTime();
}
//-----------------------------------------------------------------------------
@ -126,7 +110,7 @@ void Clipper::SetSilhouette()
while (node != NULL)
{
ClipNode *snode = ClipNode::NewRange(node->start, node->end);
ClipNode *snode = NewRange(node->start, node->end);
if (silhouette == NULL) silhouette = snode;
snode->prev = last;
if (last != NULL) last->next = snode;
@ -135,7 +119,6 @@ void Clipper::SetSilhouette()
}
}
//-----------------------------------------------------------------------------
//
// IsRangeVisible
@ -227,7 +210,7 @@ void Clipper::AddClipRange(angle_t start, angle_t end)
//just add range
node = cliphead;
prevNode = NULL;
temp = ClipNode::NewRange(start, end);
temp = NewRange(start, end);
while (node != NULL && node->start < end)
{
@ -259,7 +242,7 @@ void Clipper::AddClipRange(angle_t start, angle_t end)
}
else
{
temp = ClipNode::NewRange(start, end);
temp = NewRange(start, end);
cliphead = temp;
return;
}
@ -343,7 +326,7 @@ void Clipper::DoRemoveClipRange(angle_t start, angle_t end)
}
else if (node->start < start && node->end > end)
{
temp=ClipNode::NewRange(end, node->end);
temp = NewRange(end, node->end);
node->end=start;
temp->next=node->next;
temp->prev=node;
@ -389,18 +372,10 @@ angle_t Clipper::AngleToPseudo(angle_t ang)
//
//-----------------------------------------------------------------------------
fixed_t viewx, viewy;
void R_SetView()
{
viewx = FLOAT2FIXED(ViewPos.X);
viewy = FLOAT2FIXED(ViewPos.Y);
}
angle_t R_PointToPseudoAngle(double x, double y)
{
double vecx = x - ViewPos.X;
double vecy = y - ViewPos.Y;
double vecx = x - r_viewpoint.Pos.X;
double vecy = y - r_viewpoint.Pos.Y;
if (vecx == 0 && vecy == 0)
{
@ -411,7 +386,7 @@ angle_t R_PointToPseudoAngle(double x, double y)
double result = vecy / (fabs(vecx) + fabs(vecy));
if (vecx < 0)
{
result = 2.f - result;
result = 2. - result;
}
return xs_Fix<30>::ToFix(result);
}
@ -427,7 +402,7 @@ angle_t R_PointToPseudoAngle(double x, double y)
// if some part of the bbox might be visible.
//
//-----------------------------------------------------------------------------
static const BYTE checkcoord[12][4] = // killough -- static const
static const uint8_t checkcoord[12][4] = // killough -- static const
{
{3,0,2,1},
{3,0,2,0},
@ -447,12 +422,12 @@ bool Clipper::CheckBox(const float *bspcoord)
angle_t angle1, angle2;
int boxpos;
const BYTE* check;
const uint8_t* check;
// Find the corners of the box
// that define the edges from current viewpoint.
boxpos = (ViewPos.X <= bspcoord[BOXLEFT] ? 0 : ViewPos.X < bspcoord[BOXRIGHT ] ? 1 : 2) +
(ViewPos.Y >= bspcoord[BOXTOP ] ? 0 : ViewPos.Y > bspcoord[BOXBOTTOM] ? 4 : 8);
boxpos = (r_viewpoint.Pos.X <= bspcoord[BOXLEFT] ? 0 : r_viewpoint.Pos.X < bspcoord[BOXRIGHT ] ? 1 : 2) +
(r_viewpoint.Pos.Y >= bspcoord[BOXTOP ] ? 0 : r_viewpoint.Pos.Y > bspcoord[BOXBOTTOM] ? 4 : 8);
if (boxpos == 5) return true;

View file

@ -4,57 +4,41 @@
#include "doomtype.h"
#include "xs_Float.h"
#include "r_utility.h"
#include "memarena.h"
angle_t R_PointToPseudoAngle(double x, double y);
// Used to speed up angle calculations during clipping
inline angle_t vertex_t::GetClipAngle()
{
return R_PointToPseudoAngle(p.X, p.Y);
}
class ClipNode
{
friend class Clipper;
friend class ClipNodesFreer;
ClipNode *prev, *next;
angle_t start, end;
static ClipNode * freelist;
bool operator== (const ClipNode &other)
{
return other.start == start && other.end == end;
}
void Free()
{
next=freelist;
freelist=this;
}
static ClipNode * GetNew()
{
if (freelist)
{
ClipNode * p=freelist;
freelist=p->next;
return p;
}
else return new ClipNode;
}
static ClipNode * NewRange(angle_t start, angle_t end)
{
ClipNode * c=GetNew();
c->start=start;
c->end=end;
c->next=c->prev=NULL;
return c;
}
};
class Clipper
{
ClipNode * clipnodes;
ClipNode * cliphead;
ClipNode * silhouette; // will be preserved even when RemoveClipRange is called
bool blocked;
unsigned starttime;
TStaticArray<angle_t> anglecache;
FMemArena nodearena;
ClipNode * freelist = nullptr;
ClipNode * clipnodes = nullptr;
ClipNode * cliphead = nullptr;
ClipNode * silhouette = nullptr; // will be preserved even when RemoveClipRange is called
bool blocked = false;
static angle_t AngleToPseudo(angle_t ang);
bool IsRangeVisible(angle_t startangle, angle_t endangle);
@ -65,18 +49,36 @@ class Clipper
public:
static int anglecache;
Clipper()
{
blocked = false;
clipnodes=cliphead=NULL;
}
~Clipper();
Clipper();
void Clear();
void Free(ClipNode *node)
{
node->next = freelist;
freelist = node;
}
ClipNode * GetNew()
{
if (freelist)
{
ClipNode * p = freelist;
freelist = p->next;
return p;
}
else return (ClipNode*)nodearena.Alloc(sizeof(ClipNode));
}
ClipNode * NewRange(angle_t start, angle_t end)
{
ClipNode * c = GetNew();
c->start = start;
c->end = end;
c->next = c->prev = NULL;
return c;
}
void SetSilhouette();
@ -142,18 +144,13 @@ public:
}
bool CheckBox(const float *bspcoord);
// Used to speed up angle calculations during clipping
inline angle_t GetClipAngle(vertex_t *v)
{
return v->angletime == starttime ? v->viewangle : (v->angletime = starttime, v->viewangle = R_PointToPseudoAngle(v->p.X, v->p.Y));
}
};
extern Clipper clipper;
angle_t R_PointToPseudoAngle(double x, double y);
void R_SetView();
// Used to speed up angle calculations during clipping
inline angle_t vertex_t::GetClipAngle()
{
return angletime == Clipper::anglecache? viewangle : (angletime = Clipper::anglecache, viewangle = R_PointToPseudoAngle(p.X, p.Y));
}
#endif

View file

@ -299,7 +299,7 @@ void GLDrawList::SortWallIntoPlane(SortNode * head,SortNode * sort)
GLFlat * fh=&flats[drawitems[head->itemindex].index];
GLWall * ws=&walls[drawitems[sort->itemindex].index];
bool ceiling = fh->z > ViewPos.Z;
bool ceiling = fh->z > r_viewpoint.Pos.Z;
if ((ws->ztop[0] > fh->z || ws->ztop[1] > fh->z) && (ws->zbottom[0] < fh->z || ws->zbottom[1] < fh->z))
{
@ -362,7 +362,7 @@ void GLDrawList::SortSpriteIntoPlane(SortNode * head,SortNode * sort)
GLFlat * fh=&flats[drawitems[head->itemindex].index];
GLSprite * ss=&sprites[drawitems[sort->itemindex].index];
bool ceiling = fh->z > ViewPos.Z;
bool ceiling = fh->z > r_viewpoint.Pos.Z;
if ((ss->z1>fh->z && ss->z2<fh->z) || ss->modelframe)
{
@ -770,7 +770,7 @@ void GLDrawList::DoDrawSorted(SortNode * head)
if (drawitems[head->itemindex].rendertype == GLDIT_FLAT)
{
z = flats[drawitems[head->itemindex].index].z;
relation = z > ViewPos.Z ? 1 : -1;
relation = z > r_viewpoint.Pos.Z ? 1 : -1;
}
@ -1186,9 +1186,9 @@ void FDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, boo
gl_SetFog(lightlevel, rel, &Colormap, false);
gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false);
float fviewx = ViewPos.X;
float fviewy = ViewPos.Y;
float fviewz = ViewPos.Z;
float fviewx = r_viewpoint.Pos.X;
float fviewy = r_viewpoint.Pos.Y;
float fviewz = r_viewpoint.Pos.Z;
gl_SetPlaneTextureRotation(&plane, gltexture);
gl_RenderState.Apply();
@ -1239,7 +1239,7 @@ void FDrawInfo::FloodUpperGap(seg_t * seg)
double frontz = fakefsector->ceilingplane.ZatPoint(seg->v1);
if (fakebsector->GetTexture(sector_t::ceiling)==skyflatnum) return;
if (backz < ViewPos.Z) return;
if (backz < r_viewpoint.Pos.Z) return;
if (seg->sidedef == seg->linedef->sidedef[0])
{
@ -1292,7 +1292,7 @@ void FDrawInfo::FloodLowerGap(seg_t * seg)
if (fakebsector->GetTexture(sector_t::floor) == skyflatnum) return;
if (fakebsector->GetPlaneTexZ(sector_t::floor) > ViewPos.Z) return;
if (fakebsector->GetPlaneTexZ(sector_t::floor) > r_viewpoint.Pos.Z) return;
if (seg->sidedef == seg->linedef->sidedef[0])
{

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