mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 14:51:51 +00:00
Merge remote-tracking branch 'gzdoom/master' into ssao
# Conflicts: # src/gl/renderer/gl_renderer.cpp # src/gl/scene/gl_scene.cpp # src/gl/shaders/gl_shader.cpp # wadsrc/static/language.enu # wadsrc/static/menudef.zz
This commit is contained in:
commit
ecb57d6cd9
80 changed files with 2198 additions and 172 deletions
|
@ -30,8 +30,27 @@ if(CMAKE_CROSSCOMPILING)
|
|||
include(${IMPORT_EXECUTABLES})
|
||||
endif()
|
||||
|
||||
# Recursive function to place PK3 archive source files into a hierarchy of source file in the IDE
|
||||
function( assort_pk3_source_folder FOLDER_NAME PK3_DIR )
|
||||
# Assort source files into folders in the IDE
|
||||
file(GLOB PK3_SRCS ${PK3_DIR}/*) # Create list of all files in this folder
|
||||
foreach(PK3_SRC ${PK3_SRCS})
|
||||
# If there are subfolders, recurse into them
|
||||
if(IS_DIRECTORY ${PK3_SRC})
|
||||
get_filename_component(DIRNAME ${PK3_SRC} NAME)
|
||||
# Exclude folder from list of source files
|
||||
list(REMOVE_ITEM PK3_SRCS ${PK3_SRC})
|
||||
# Recurse deeper into the filesystem folder tree
|
||||
assort_pk3_source_folder( ${FOLDER_NAME}\\${DIRNAME} ${PK3_SRC} )
|
||||
endif()
|
||||
# Assign IDE group for current top-level source files
|
||||
source_group(${FOLDER_NAME} FILES ${PK3_SRCS})
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# Simplify pk3 building, add_pk3(filename srcdirectory)
|
||||
function( add_pk3 PK3_NAME PK3_DIR )
|
||||
# message(STATUS "Creating build rule for PK3 ${PK3_NAME} ${PK3_DIR}")
|
||||
# Generate target name. Just use "pk3" for main pk3 target.
|
||||
string( REPLACE "." "_" PK3_TARGET ${PK3_NAME} )
|
||||
if( ${PK3_TARGET} STREQUAL "zdoom_pk3" )
|
||||
|
@ -48,14 +67,33 @@ function( add_pk3 PK3_NAME PK3_DIR )
|
|||
COMMAND zipdir -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR}
|
||||
DEPENDS zipdir )
|
||||
endif()
|
||||
# Grab a list of top-level PK3 folder files, so we can conveniently see them in the IDE
|
||||
file(GLOB PK3_SRCS ${PK3_DIR}/*)
|
||||
# Create a list of source files for this PK3, for use in the IDE
|
||||
# Phase 1: Create a list of all source files for this PK3 archive, except
|
||||
# for a couple of strife image file names that confuse CMake.
|
||||
file(GLOB_RECURSE PK3_SRCS ${PK3_DIR}/*)
|
||||
# Exclude from the source list some gzdoom .png files with brackets in the
|
||||
# file names here, because they confuse CMake.
|
||||
# This only affects the list of source files shown in the IDE.
|
||||
# It does not actually remove the files from the PK3 archive.
|
||||
# First replace that toxic bracket character with something we can handle
|
||||
string(REPLACE "[" confusing_bracket PK3_SRCS "${PK3_SRCS}")
|
||||
string(REPLACE "]" confusing_bracket PK3_SRCS "${PK3_SRCS}")
|
||||
foreach(PK3_SRC ${PK3_SRCS}) # All source files at all levels
|
||||
# Exclude those quarantined source file source file names that once had a bracket
|
||||
if(${PK3_SRC} MATCHES confusing_bracket)
|
||||
# message(STATUS "Ignoring PK3 file name containing brackets "${PK3_SRC})
|
||||
list(REMOVE_ITEM PK3_SRCS ${PK3_SRC})
|
||||
endif()
|
||||
endforeach()
|
||||
# Phase 2: Create the PK3 build rule, including the source file list for the IDE
|
||||
# Touch the zipdir executable here so that the pk3s are forced to
|
||||
# rebuild each time since their dependecy has "changed."
|
||||
# rebuild each time since their dependency has "changed."
|
||||
add_custom_target( ${PK3_TARGET} ALL
|
||||
COMMAND ${CMAKE_COMMAND} -E touch $<TARGET_FILE:zipdir>
|
||||
DEPENDS ${ZDOOM_OUTPUT_DIR}/${PK3_NAME}
|
||||
SOURCES "${PK3_SRCS}")
|
||||
SOURCES ${PK3_SRCS})
|
||||
# Phase 3: Assign source files to a nice folder structure in the IDE
|
||||
assort_pk3_source_folder("Source Files" ${PK3_DIR})
|
||||
endfunction()
|
||||
|
||||
# Macro for building libraries without debugging information
|
||||
|
|
33
docs/licenses/fxaa.txt
Normal file
33
docs/licenses/fxaa.txt
Normal file
|
@ -0,0 +1,33 @@
|
|||
//----------------------------------------------------------------------------------
|
||||
// File: es3-kepler\FXAA/FXAA3_11.h
|
||||
// SDK Version: v3.00
|
||||
// Email: gameworks@nvidia.com
|
||||
// Site: http://developer.nvidia.com/
|
||||
//
|
||||
// Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//----------------------------------------------------------------------------------
|
|
@ -214,6 +214,19 @@ Note: All <bool> fields default to false unless mentioned otherwise.
|
|||
damagehazard = <bool>; // Changes damage model to Strife's delayed damage for the given sector. Default = false.
|
||||
floorterrain = <string>; // Sets the terrain for the sector's floor. Default = 'use the flat texture's terrain definition.'
|
||||
ceilingterrain = <string>; // Sets the terrain for the sector's ceiling. Default = 'use the flat texture's terrain definition.'
|
||||
|
||||
portal_ceil_alpha = <float> // translucency of ceiling portal (default is 0 (not visible))
|
||||
portal_ceil_blocksound = <bool> // ceiling portal blocks sound.
|
||||
portal_ceil_disabled = <bool> // ceiling portal disabled.
|
||||
portal_ceil_nopass = <bool> // ceiling portal blocks movement if true.
|
||||
portal_ceil_norender = <bool> // ceiling portal not rendered.
|
||||
portal_ceil_overlaytype = <string> // defines translucency style, can either be "translucent" or "additive". Default is "translucent".
|
||||
portal_floor_alpha = <float> // translucency of floor portal (default is 0 (not visible))
|
||||
portal_floor_blocksound = <bool> // floor portal blocks sound.
|
||||
portal_floor_disabled = <bool> // floor portal disabled.
|
||||
portal_floor_nopass = <bool> // ceiling portal blocks movement if true.
|
||||
portal_floor_norender = <bool> // ceiling portal not rendered.
|
||||
portal_floor_overlaytype = <string> // defines translucency style, can either be "translucent" or "additive". Default is "translucent".
|
||||
|
||||
|
||||
* Note about dropactors
|
||||
|
|
|
@ -9,6 +9,8 @@ endif()
|
|||
include( CheckCXXSourceCompiles )
|
||||
include( CheckFunctionExists )
|
||||
include( CheckCXXCompilerFlag )
|
||||
include( CheckIncludeFile )
|
||||
include( CheckIncludeFiles )
|
||||
include( CheckLibraryExists )
|
||||
include( FindPkgConfig )
|
||||
include( FindOpenGL )
|
||||
|
@ -119,7 +121,13 @@ if( WIN32 )
|
|||
PATHS ENV DXSDK_DIR
|
||||
PATH_SUFFIXES Include )
|
||||
if( NOT D3D_INCLUDE_DIR )
|
||||
message( SEND_ERROR "Could not find DirectX 9 header files" )
|
||||
# Modern versions of the Windows SDK include d3d9.h. Unfortunately,
|
||||
# CMake cannot find this file via find_path, so we check for it using
|
||||
# CHECK_INCLUDE_FILE.
|
||||
CHECK_INCLUDE_FILE( d3d9.h D3D9_H_FOUND )
|
||||
if ( NOT D3D9_H_FOUND )
|
||||
message( SEND_ERROR "Could not find DirectX 9 header files" )
|
||||
endif()
|
||||
else()
|
||||
include_directories( ${D3D_INCLUDE_DIR} )
|
||||
endif()
|
||||
|
@ -128,35 +136,41 @@ if( WIN32 )
|
|||
PATHS ENV DXSDK_DIR
|
||||
PATH_SUFFIXES Include )
|
||||
if( NOT XINPUT_INCLUDE_DIR )
|
||||
message( WARNING "Could not find xinput.h. XInput will be disabled." )
|
||||
add_definitions( -DNO_XINPUT )
|
||||
# Modern versions of the Windows SDK include xinput.h. Unfortunately,
|
||||
# CMake cannot find this file via find_path, so we check for it using
|
||||
# CHECK_INCLUDE_FILES. windows.h must be included before xinput.h.
|
||||
CHECK_INCLUDE_FILES( "windows.h;xinput.h" XINPUT_H_FOUND )
|
||||
if( NOT XINPUT_H_FOUND )
|
||||
message( WARNING "Could not find xinput.h. XInput will be disabled." )
|
||||
add_definitions( -DNO_XINPUT )
|
||||
endif()
|
||||
else()
|
||||
include_directories( ${XINPUT_INCLUDE_DIR} )
|
||||
endif()
|
||||
|
||||
find_library( DX_dxguid_LIBRARY dxguid
|
||||
PATHS ENV DXSDK_DIR
|
||||
PATH_SUFFIXES Lib Lib/${XBITS} )
|
||||
find_library( DX_dinput8_LIBRARY dinput8
|
||||
PATHS ENV DXSDK_DIR
|
||||
PATH_SUFFIXES Lib Lib/${XBITS} )
|
||||
find_library( DX_dxguid_LIBRARY dxguid
|
||||
PATHS ENV DXSDK_DIR
|
||||
PATH_SUFFIXES Lib Lib/${XBITS} )
|
||||
|
||||
set( DX_LIBS_FOUND YES )
|
||||
if( NOT DX_dxguid_LIBRARY )
|
||||
set( DX_LIBS_FOUND NO )
|
||||
endif()
|
||||
# Modern versions of the Windows SDK include dinput8.lib. Unfortunately,
|
||||
# CMake cannot find these libraries via find_library.
|
||||
if( NOT DX_dinput8_LIBRARY )
|
||||
set( DX_LIBS_FOUND NO )
|
||||
# If we got this far, assume dinput8.lib is in the system library path.
|
||||
set( DX_dinput8_LIBRARY dinput8 )
|
||||
endif()
|
||||
|
||||
if( NOT DX_LIBS_FOUND )
|
||||
message( FATAL_ERROR "Could not find DirectX 9 libraries" )
|
||||
# Modern versions of the Windows SDK do NOT include dxguid.lib. Its contents
|
||||
# were moved to dinput8.lib.
|
||||
if( NOT DX_dxguid_LIBRARY )
|
||||
message( STATUS "Could not find dxguid.lib. Build may fail on old Windows SDKs.")
|
||||
endif()
|
||||
|
||||
set( ZDOOM_LIBS
|
||||
wsock32
|
||||
winmm
|
||||
"${DX_dxguid_LIBRARY}"
|
||||
"${DX_dinput8_LIBRARY}"
|
||||
ole32
|
||||
user32
|
||||
|
@ -167,6 +181,9 @@ if( WIN32 )
|
|||
setupapi
|
||||
oleaut32
|
||||
DelayImp )
|
||||
if( DX_dxguid_LIBRARY )
|
||||
list( APPEND ZDOOM_LIBS "${DX_dxguid_LIBRARY}" )
|
||||
endif()
|
||||
else()
|
||||
if( APPLE )
|
||||
set( FMOD_SEARCH_PATHS "/Developer/FMOD Programmers API Mac/api" )
|
||||
|
@ -1116,6 +1133,7 @@ set( FASTMATH_SOURCES
|
|||
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
|
||||
|
@ -1124,12 +1142,14 @@ set( FASTMATH_SOURCES
|
|||
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
|
||||
|
|
|
@ -755,6 +755,9 @@ public:
|
|||
// What species am I?
|
||||
virtual FName GetSpecies();
|
||||
|
||||
// set translation
|
||||
void SetTranslation(const char *trname);
|
||||
|
||||
double GetBobOffset(double ticfrac = 0) const
|
||||
{
|
||||
if (!(flags2 & MF2_FLOATBOB))
|
||||
|
|
|
@ -2439,6 +2439,7 @@ void D_DoomMain (void)
|
|||
if (!batchrun) Printf ("ParseTeamInfo: Load team definitions.\n");
|
||||
TeamLibrary.ParseTeamInfo ();
|
||||
|
||||
R_ParseTrnslate();
|
||||
PClassActor::StaticInit ();
|
||||
|
||||
// [GRB] Initialize player class list
|
||||
|
|
|
@ -330,7 +330,11 @@ DObject::~DObject ()
|
|||
}
|
||||
}
|
||||
}
|
||||
type->DestroySpecials(this);
|
||||
|
||||
if (nullptr != type)
|
||||
{
|
||||
type->DestroySpecials(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ void DSectorEffect::Destroy()
|
|||
}
|
||||
|
||||
DSectorEffect::DSectorEffect (sector_t *sector)
|
||||
: DThinker(STAT_SECTOREFFECT)
|
||||
{
|
||||
m_Sector = sector;
|
||||
}
|
||||
|
|
|
@ -1207,29 +1207,23 @@ void G_FinishTravel ()
|
|||
pnum = int(pawn->player - players);
|
||||
pawn->ChangeStatNum (STAT_PLAYER);
|
||||
pawndup = pawn->player->mo;
|
||||
start = NULL;
|
||||
assert (pawn != pawndup);
|
||||
if (pawndup == NULL)
|
||||
{ // Oh no! there was no start for this player!
|
||||
start = G_PickPlayerStart(pnum, PPS_FORCERANDOM);
|
||||
if (start != NULL) pawndup = P_SpawnPlayer(start, pnum, (level.flags2 & LEVEL2_PRERAISEWEAPON) ? SPF_WEAPONFULLYUP : 0);
|
||||
if (pawndup == NULL)
|
||||
{
|
||||
pawn->flags |= MF_NOSECTOR | MF_NOBLOCKMAP;
|
||||
pawn->Destroy();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
start = G_PickPlayerStart(pnum, 0);
|
||||
if (start == NULL)
|
||||
{
|
||||
start = G_PickPlayerStart(pnum, 0);
|
||||
if (start == NULL)
|
||||
if (pawndup != nullptr)
|
||||
{
|
||||
Printf(TEXTCOLOR_RED "No player %d start to travel to!\n", pnum + 1);
|
||||
// Move to the coordinates this player had when they left the level.
|
||||
pawn->SetXYZ(pawndup->Pos());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Could not find a start for this player at all. This really should never happen but if it does, let's better abort.
|
||||
DThinker::DestroyThinkersInList(STAT_TRAVELLING);
|
||||
I_Error ("No player %d start to travel to!\n", pnum + 1);
|
||||
}
|
||||
}
|
||||
oldpawn = pawndup;
|
||||
|
||||
|
@ -1266,8 +1260,11 @@ void G_FinishTravel ()
|
|||
pawn->player->camera = pawn;
|
||||
pawn->player->viewheight = pawn->ViewHeight;
|
||||
pawn->flags2 &= ~MF2_BLASTED;
|
||||
DObject::StaticPointerSubstitution (oldpawn, pawn);
|
||||
oldpawn->Destroy();
|
||||
if (oldpawn != nullptr)
|
||||
{
|
||||
DObject::StaticPointerSubstitution (oldpawn, pawn);
|
||||
oldpawn->Destroy();
|
||||
}
|
||||
if (pawndup != NULL)
|
||||
{
|
||||
pawndup->Destroy();
|
||||
|
|
|
@ -54,6 +54,12 @@ void AFastProjectile::Tick ()
|
|||
// Handle movement
|
||||
if (!Vel.isZero() || (Z() != floorz))
|
||||
{
|
||||
// force some lateral movement so that collision detection works as intended.
|
||||
if ((flags & MF_MISSILE) && Vel.X == 0 && Vel.Y == 0 && !IsZeroDamage())
|
||||
{
|
||||
Vel.X = MinVel;
|
||||
}
|
||||
|
||||
frac = Vel / count;
|
||||
changexy = frac.X != 0 || frac.Y != 0;
|
||||
int ripcount = count / 8;
|
||||
|
@ -124,7 +130,7 @@ void AFastProjectile::Tick ()
|
|||
P_ExplodeMissile (this, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
if (changexy && ripcount <= 0)
|
||||
if (!frac.isZero() && ripcount <= 0)
|
||||
{
|
||||
ripcount = count >> 3;
|
||||
Effect();
|
||||
|
|
|
@ -1021,7 +1021,7 @@ class CommandDrawNumber : public CommandDrawString
|
|||
usePrefix(false), interpolationSpeed(0), drawValue(0), length(3),
|
||||
lowValue(-1), lowTranslation(CR_UNTRANSLATED), highValue(-1),
|
||||
highTranslation(CR_UNTRANSLATED), value(CONSTANT),
|
||||
inventoryItem(NULL)
|
||||
inventoryItem(NULL), cvarName(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1166,6 +1166,37 @@ class CommandDrawNumber : public CommandDrawString
|
|||
|
||||
if(parenthesized) sc.MustGetToken(')');
|
||||
}
|
||||
else if (sc.Compare("intcvar"))
|
||||
{
|
||||
bool parenthesized = sc.CheckToken('(');
|
||||
|
||||
value = INTCVAR;
|
||||
|
||||
if (!parenthesized || !sc.CheckToken(TK_StringConst))
|
||||
sc.MustGetToken(TK_Identifier);
|
||||
|
||||
cvarName = sc.String;
|
||||
|
||||
// We have a name, but make sure it exists. If not, send notification so modders
|
||||
// are aware of the situation.
|
||||
FBaseCVar *CVar = FindCVar(cvarName, nullptr);
|
||||
|
||||
if (CVar != nullptr)
|
||||
{
|
||||
ECVarType cvartype = CVar->GetRealType();
|
||||
|
||||
if (!(cvartype == CVAR_Bool || cvartype == CVAR_Int))
|
||||
{
|
||||
sc.ScriptMessage("CVar '%s' is not an int or bool", cvarName.GetChars());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.ScriptMessage("CVar '%s' does not exist", cvarName.GetChars());
|
||||
}
|
||||
|
||||
if (parenthesized) sc.MustGetToken(')');
|
||||
}
|
||||
}
|
||||
if(value == INVENTORY)
|
||||
{
|
||||
|
@ -1444,6 +1475,24 @@ class CommandDrawNumber : public CommandDrawString
|
|||
num++;
|
||||
}
|
||||
break;
|
||||
case INTCVAR:
|
||||
{
|
||||
FBaseCVar *CVar = GetCVar(statusBar->CPlayer->mo, cvarName);
|
||||
if (CVar != nullptr)
|
||||
{
|
||||
ECVarType cvartype = CVar->GetRealType();
|
||||
|
||||
if (cvartype == CVAR_Bool || cvartype == CVAR_Int)
|
||||
{
|
||||
num = CVar->GetGenericRep(CVAR_Int).Int;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback in case of bad cvar/type. Unset can remove a cvar at will.
|
||||
num = 0;
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
if(interpolationSpeed != 0 && (!hudChanged || level.time == 1))
|
||||
|
@ -1522,6 +1571,7 @@ class CommandDrawNumber : public CommandDrawString
|
|||
ACCURACY,
|
||||
STAMINA,
|
||||
KEYS,
|
||||
INTCVAR,
|
||||
|
||||
CONSTANT
|
||||
};
|
||||
|
@ -1544,6 +1594,7 @@ class CommandDrawNumber : public CommandDrawString
|
|||
PClassActor *inventoryItem;
|
||||
|
||||
FString prefixPadding;
|
||||
FString cvarName;
|
||||
|
||||
friend class CommandDrawInventoryBar;
|
||||
};
|
||||
|
|
|
@ -442,7 +442,7 @@ VSMatrix::computeNormalMatrix(const FLOATTYPE *aMatrix)
|
|||
mMat3x3[1] * (mMat3x3[5] * mMat3x3[6] - mMat3x3[8] * mMat3x3[3]) +
|
||||
mMat3x3[2] * (mMat3x3[3] * mMat3x3[7] - mMat3x3[4] * mMat3x3[6]);
|
||||
|
||||
invDet = 1.0f/det;
|
||||
invDet = 1.0/det;
|
||||
|
||||
mMatrix[0] = (mMat3x3[4] * mMat3x3[8] - mMat3x3[5] * mMat3x3[7]) * invDet;
|
||||
mMatrix[1] = (mMat3x3[5] * mMat3x3[6] - mMat3x3[8] * mMat3x3[3]) * invDet;
|
||||
|
|
|
@ -71,6 +71,7 @@ void FSimpleVertexBuffer::BindVBO()
|
|||
glEnableVertexAttribArray(VATTR_TEXCOORD);
|
||||
glEnableVertexAttribArray(VATTR_COLOR);
|
||||
glDisableVertexAttribArray(VATTR_VERTEX2);
|
||||
glDisableVertexAttribArray(VATTR_NORMAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -221,7 +222,7 @@ void FFlatVertexBuffer::OutputResized(int width, int height)
|
|||
vbo_shadowdata[7].Set((float)width, (float)height, 0, 0, 0);
|
||||
|
||||
Map();
|
||||
memcpy(map, &vbo_shadowdata[4], 4 * sizeof(FFlatVertex));
|
||||
memcpy(&map[4], &vbo_shadowdata[4], 4 * sizeof(FFlatVertex));
|
||||
Unmap();
|
||||
}
|
||||
|
||||
|
@ -236,6 +237,7 @@ void FFlatVertexBuffer::BindVBO()
|
|||
glEnableVertexAttribArray(VATTR_TEXCOORD);
|
||||
glDisableVertexAttribArray(VATTR_COLOR);
|
||||
glDisableVertexAttribArray(VATTR_VERTEX2);
|
||||
glDisableVertexAttribArray(VATTR_NORMAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -271,6 +271,7 @@ struct FModelVertex
|
|||
{
|
||||
float x, y, z; // world position
|
||||
float u, v; // texture coordinates
|
||||
unsigned packedNormal; // normal vector as GL_INT_2_10_10_10_REV.
|
||||
|
||||
void Set(float xx, float yy, float zz, float uu, float vv)
|
||||
{
|
||||
|
@ -283,7 +284,13 @@ struct FModelVertex
|
|||
|
||||
void SetNormal(float nx, float ny, float nz)
|
||||
{
|
||||
// GZDoom currently doesn't use normals. This function is so that the high level code can pretend it does.
|
||||
/*
|
||||
int inx = int(nx * 512);
|
||||
int iny = int(ny * 512);
|
||||
int inz = int(nz * 512);
|
||||
packedNormal = 0x40000000 | ((inx & 1023) << 20) | ((iny & 1023) << 10) | (inz & 1023);
|
||||
*/
|
||||
packedNormal = 0; // Per-pixel lighting for models isn't implemented yet so leave this at 0 for now.
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -391,6 +391,16 @@ void ADynamicLight::UpdateLocation()
|
|||
Prev = target->Pos();
|
||||
subsector = R_PointInSubsector(Prev);
|
||||
Sector = subsector->sector;
|
||||
|
||||
// Some z-coordinate fudging to prevent the light from getting too close to the floor or ceiling planes. With proper attenuation this would render them invisible.
|
||||
// A distance of 5 is needed so that the light's effect doesn't become too small.
|
||||
if (Z() < target->floorz + 5.) SetZ(target->floorz + 5.);
|
||||
else if (Z() > target->ceilingz - 5.) SetZ(target->ceilingz - 5.);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Z() < floorz + 5.) SetZ(floorz + 5.);
|
||||
else if (Z() > ceilingz - 5.) SetZ(ceilingz - 5.);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -119,6 +119,7 @@ void FModelVertexBuffer::BindVBO()
|
|||
glEnableVertexAttribArray(VATTR_VERTEX);
|
||||
glEnableVertexAttribArray(VATTR_TEXCOORD);
|
||||
glEnableVertexAttribArray(VATTR_VERTEX2);
|
||||
glEnableVertexAttribArray(VATTR_NORMAL);
|
||||
glDisableVertexAttribArray(VATTR_COLOR);
|
||||
}
|
||||
else
|
||||
|
@ -245,6 +246,7 @@ unsigned int FModelVertexBuffer::SetupFrame(unsigned int frame1, unsigned int fr
|
|||
glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame1].x);
|
||||
glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame1].u);
|
||||
glVertexAttribPointer(VATTR_VERTEX2, 3, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame2].x);
|
||||
glVertexAttribPointer(VATTR_NORMAL, 4, GL_UNSIGNED_INT_2_10_10_10_REV, false, sizeof(FModelVertex), &VMO[frame2].packedNormal);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -248,6 +248,7 @@ void FVoxelModel::AddFace(int x1, int y1, int z1, int x2, int y2, int z2, int x3
|
|||
FModelVertex vert;
|
||||
unsigned int indx[4];
|
||||
|
||||
vert.packedNormal = 0; // currently this is not being used for voxels.
|
||||
vert.u = (((col & 15) * 255 / 16) + 7) / 255.f;
|
||||
vert.v = (((col / 16) * 255 / 16) + 7) / 255.f;
|
||||
|
||||
|
@ -271,6 +272,7 @@ void FVoxelModel::AddFace(int x1, int y1, int z1, int x2, int y2, int z2, int x3
|
|||
vert.y = -z3 + PivotZ;
|
||||
indx[3] = AddVertex(vert, check);
|
||||
|
||||
|
||||
mIndices.Push(indx[0]);
|
||||
mIndices.Push(indx[1]);
|
||||
mIndices.Push(indx[3]);
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
#include "gl/shaders/gl_tonemapshader.h"
|
||||
#include "gl/shaders/gl_colormapshader.h"
|
||||
#include "gl/shaders/gl_lensshader.h"
|
||||
#include "gl/shaders/gl_fxaashader.h"
|
||||
#include "gl/shaders/gl_presentshader.h"
|
||||
#include "gl/renderer/gl_2ddrawer.h"
|
||||
#include "gl/stereo3d/gl_stereo3d.h"
|
||||
|
@ -70,24 +71,24 @@
|
|||
// CVARs
|
||||
//
|
||||
//==========================================================================
|
||||
CVAR(Bool, gl_bloom, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
|
||||
CUSTOM_CVAR(Float, gl_bloom_amount, 1.4f, 0)
|
||||
CVAR(Bool, gl_bloom, false, CVAR_ARCHIVE);
|
||||
CUSTOM_CVAR(Float, gl_bloom_amount, 1.4f, CVAR_ARCHIVE)
|
||||
{
|
||||
if (self < 0.1f) self = 0.1f;
|
||||
}
|
||||
|
||||
CVAR(Float, gl_exposure_scale, 1.3f, 0)
|
||||
CVAR(Float, gl_exposure_min, 0.35f, 0)
|
||||
CVAR(Float, gl_exposure_base, 0.35f, 0)
|
||||
CVAR(Float, gl_exposure_speed, 0.05f, 0)
|
||||
CVAR(Float, gl_exposure_scale, 1.3f, CVAR_ARCHIVE)
|
||||
CVAR(Float, gl_exposure_min, 0.35f, CVAR_ARCHIVE)
|
||||
CVAR(Float, gl_exposure_base, 0.35f, CVAR_ARCHIVE)
|
||||
CVAR(Float, gl_exposure_speed, 0.05f, CVAR_ARCHIVE)
|
||||
|
||||
CUSTOM_CVAR(Int, gl_tonemap, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
CUSTOM_CVAR(Int, gl_tonemap, 0, CVAR_ARCHIVE)
|
||||
{
|
||||
if (self < 0 || self > 5)
|
||||
self = 0;
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, gl_bloom_kernel_size, 7, 0)
|
||||
CUSTOM_CVAR(Int, gl_bloom_kernel_size, 7, CVAR_ARCHIVE)
|
||||
{
|
||||
if (self < 3 || self > 15 || self % 2 == 0)
|
||||
self = 7;
|
||||
|
@ -95,9 +96,17 @@ CUSTOM_CVAR(Int, gl_bloom_kernel_size, 7, 0)
|
|||
|
||||
CVAR(Bool, gl_lens, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
|
||||
CVAR(Float, gl_lens_k, -0.12f, 0)
|
||||
CVAR(Float, gl_lens_kcube, 0.1f, 0)
|
||||
CVAR(Float, gl_lens_chromatic, 1.12f, 0)
|
||||
CVAR(Float, gl_lens_k, -0.12f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
CVAR(Float, gl_lens_kcube, 0.1f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
CVAR(Float, gl_lens_chromatic, 1.12f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
|
||||
CUSTOM_CVAR(Int, gl_fxaa, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
{
|
||||
if (self < 0 || self >= FFXAAShader::Count)
|
||||
{
|
||||
self = 0;
|
||||
}
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, gl_ssao, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
{
|
||||
|
@ -139,6 +148,7 @@ void FGLRenderer::PostProcessScene()
|
|||
TonemapScene();
|
||||
ColormapScene();
|
||||
LensDistortScene();
|
||||
ApplyFXAA();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -599,6 +609,51 @@ void FGLRenderer::LensDistortScene()
|
|||
FGLDebug::PopGroup();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Apply FXAA and place the result in the HUD/2D texture
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FGLRenderer::ApplyFXAA()
|
||||
{
|
||||
if (0 == gl_fxaa)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FGLDebug::PushGroup("ApplyFXAA");
|
||||
|
||||
const GLfloat rpcRes[2] =
|
||||
{
|
||||
1.0f / mBuffers->GetWidth(),
|
||||
1.0f / mBuffers->GetHeight()
|
||||
};
|
||||
|
||||
FGLPostProcessState savedState;
|
||||
|
||||
mBuffers->BindNextFB();
|
||||
mBuffers->BindCurrentTexture(0);
|
||||
mFXAALumaShader->Bind();
|
||||
mFXAALumaShader->InputTexture.Set(0);
|
||||
RenderScreenQuad();
|
||||
mBuffers->NextTexture();
|
||||
|
||||
mBuffers->BindNextFB();
|
||||
mBuffers->BindCurrentTexture(0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
mFXAAShader->Bind();
|
||||
mFXAAShader->InputTexture.Set(0);
|
||||
mFXAAShader->ReciprocalResolution.Set(rpcRes);
|
||||
RenderScreenQuad();
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
mBuffers->NextTexture();
|
||||
|
||||
FGLDebug::PopGroup();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copies the rendered screen to its final destination
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define __GL_RENDERBUFFERS_H
|
||||
|
||||
#include "gl/shaders/gl_shader.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
|
||||
class FGLBloomTextureLevel
|
||||
{
|
||||
|
|
|
@ -57,7 +57,9 @@
|
|||
#include "gl/shaders/gl_tonemapshader.h"
|
||||
#include "gl/shaders/gl_colormapshader.h"
|
||||
#include "gl/shaders/gl_lensshader.h"
|
||||
#include "gl/shaders/gl_fxaashader.h"
|
||||
#include "gl/shaders/gl_presentshader.h"
|
||||
#include "gl/shaders/gl_present3dRowshader.h"
|
||||
#include "gl/stereo3d/gl_stereo3d.h"
|
||||
#include "gl/textures/gl_texture.h"
|
||||
#include "gl/textures/gl_translate.h"
|
||||
|
@ -104,6 +106,7 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb)
|
|||
mTonemapPalette = nullptr;
|
||||
mBuffers = nullptr;
|
||||
mPresentShader = nullptr;
|
||||
mPresent3dRowShader = nullptr;
|
||||
mBloomExtractShader = nullptr;
|
||||
mBloomCombineShader = nullptr;
|
||||
mExposureExtractShader = nullptr;
|
||||
|
@ -118,6 +121,8 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb)
|
|||
mDepthBlurShader = nullptr;
|
||||
mSSAOShader = nullptr;
|
||||
mSSAOCombineShader = nullptr;
|
||||
mFXAAShader = nullptr;
|
||||
mFXAALumaShader = nullptr;
|
||||
}
|
||||
|
||||
void gl_LoadModels();
|
||||
|
@ -140,7 +145,10 @@ void FGLRenderer::Initialize(int width, int height)
|
|||
mColormapShader = new FColormapShader();
|
||||
mTonemapPalette = nullptr;
|
||||
mLensShader = new FLensShader();
|
||||
mFXAAShader = new FFXAAShader;
|
||||
mFXAALumaShader = new FFXAALumaShader;
|
||||
mPresentShader = new FPresentShader();
|
||||
mPresent3dRowShader = new FPresent3DRowShader();
|
||||
m2DDrawer = new F2DDrawer;
|
||||
|
||||
// needed for the core profile, because someone decided it was a good idea to remove the default VAO.
|
||||
|
@ -197,6 +205,7 @@ FGLRenderer::~FGLRenderer()
|
|||
if (mDepthBlurShader) delete mDepthBlurShader;
|
||||
if (mSSAOShader) delete mSSAOShader;
|
||||
if (mSSAOCombineShader) delete mSSAOCombineShader;
|
||||
if (mPresent3dRowShader) delete mPresent3dRowShader;
|
||||
if (mBloomExtractShader) delete mBloomExtractShader;
|
||||
if (mBloomCombineShader) delete mBloomCombineShader;
|
||||
if (mExposureExtractShader) delete mExposureExtractShader;
|
||||
|
@ -207,6 +216,8 @@ FGLRenderer::~FGLRenderer()
|
|||
if (mTonemapPalette) delete mTonemapPalette;
|
||||
if (mColormapShader) delete mColormapShader;
|
||||
if (mLensShader) delete mLensShader;
|
||||
delete mFXAAShader;
|
||||
delete mFXAALumaShader;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -32,7 +32,10 @@ class FBlurShader;
|
|||
class FTonemapShader;
|
||||
class FColormapShader;
|
||||
class FLensShader;
|
||||
class FFXAALumaShader;
|
||||
class FFXAAShader;
|
||||
class FPresentShader;
|
||||
class FPresent3DRowShader;
|
||||
class F2DDrawer;
|
||||
class FHardwareTexture;
|
||||
|
||||
|
@ -111,7 +114,10 @@ public:
|
|||
FColormapShader *mColormapShader;
|
||||
FHardwareTexture *mTonemapPalette;
|
||||
FLensShader *mLensShader;
|
||||
FFXAALumaShader *mFXAALumaShader;
|
||||
FFXAAShader *mFXAAShader;
|
||||
FPresentShader *mPresentShader;
|
||||
FPresent3DRowShader *mPresent3dRowShader;
|
||||
|
||||
FTexture *gllight;
|
||||
FTexture *glpart2;
|
||||
|
@ -188,6 +194,7 @@ public:
|
|||
void BindTonemapPalette(int texunit);
|
||||
void ClearTonemapPalette();
|
||||
void LensDistortScene();
|
||||
void ApplyFXAA();
|
||||
void CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma);
|
||||
void DrawPresentTexture(const GL_IRECT &box, bool applyGamma);
|
||||
void Flush();
|
||||
|
|
|
@ -142,6 +142,7 @@ bool FRenderState::ApplyShader()
|
|||
}
|
||||
|
||||
glVertexAttrib4fv(VATTR_COLOR, mColor.vec);
|
||||
glVertexAttrib4fv(VATTR_NORMAL, mNormal.vec);
|
||||
|
||||
activeShader->muDesaturation.Set(mDesaturation / 255.f);
|
||||
activeShader->muFogEnabled.Set(fogset);
|
||||
|
@ -270,12 +271,16 @@ bool FRenderState::ApplyShader()
|
|||
if (mModelMatrixEnabled)
|
||||
{
|
||||
mModelMatrix.matrixToGL(activeShader->modelmatrix_index);
|
||||
VSMatrix norm;
|
||||
norm.computeNormalMatrix(mModelMatrix);
|
||||
mNormalModelMatrix.matrixToGL(activeShader->normalmodelmatrix_index);
|
||||
activeShader->currentModelMatrixState = true;
|
||||
}
|
||||
else if (activeShader->currentModelMatrixState)
|
||||
{
|
||||
activeShader->currentModelMatrixState = false;
|
||||
identityMatrix.matrixToGL(activeShader->modelmatrix_index);
|
||||
identityMatrix.matrixToGL(activeShader->normalmodelmatrix_index);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -97,6 +97,7 @@ class FRenderState
|
|||
float mShaderTimer;
|
||||
|
||||
FVertexBuffer *mVertexBuffer, *mCurrentVertexBuffer;
|
||||
FStateVec4 mNormal;
|
||||
FStateVec4 mColor;
|
||||
FStateVec4 mCameraPos;
|
||||
FStateVec4 mGlowTop, mGlowBottom;
|
||||
|
@ -128,6 +129,8 @@ public:
|
|||
VSMatrix mViewMatrix;
|
||||
VSMatrix mModelMatrix;
|
||||
VSMatrix mTextureMatrix;
|
||||
VSMatrix mNormalViewMatrix;
|
||||
VSMatrix mNormalModelMatrix;
|
||||
|
||||
FRenderState()
|
||||
{
|
||||
|
@ -189,6 +192,16 @@ public:
|
|||
|
||||
void SetClipHeight(float height, float direction);
|
||||
|
||||
void SetNormal(FVector3 norm)
|
||||
{
|
||||
mNormal.Set(norm.X, norm.Y, norm.Z, 0.f);
|
||||
}
|
||||
|
||||
void SetNormal(float x, float y, float z)
|
||||
{
|
||||
mNormal.Set(x, y, z, 0.f);
|
||||
}
|
||||
|
||||
void SetColor(float r, float g, float b, float a = 1.f, int desat = 0)
|
||||
{
|
||||
mColor.Set(r, g, b, a);
|
||||
|
|
|
@ -374,6 +374,7 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG
|
|||
}
|
||||
#endif
|
||||
|
||||
gl_RenderState.SetNormal(plane.plane.Normal().X, plane.plane.Normal().Z, plane.plane.Normal().Y);
|
||||
|
||||
switch (pass)
|
||||
{
|
||||
|
@ -502,6 +503,11 @@ inline void GLFlat::PutFlat(bool fog)
|
|||
void GLFlat::Process(sector_t * model, int whichplane, bool fog)
|
||||
{
|
||||
plane.GetFromSector(model, whichplane);
|
||||
if (whichplane != int(ceiling))
|
||||
{
|
||||
// Flip the normal if the source plane has a different orientation than what we are about to render.
|
||||
plane.plane.FlipVert();
|
||||
}
|
||||
|
||||
if (!fog)
|
||||
{
|
||||
|
@ -641,7 +647,7 @@ void GLFlat::ProcessSector(sector_t * frontsector)
|
|||
Colormap.CopyFrom3DLight(light);
|
||||
}
|
||||
renderstyle = STYLE_Translucent;
|
||||
Process(frontsector, false, false);
|
||||
Process(frontsector, sector_t::floor, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -700,7 +706,7 @@ void GLFlat::ProcessSector(sector_t * frontsector)
|
|||
Colormap.CopyFrom3DLight(light);
|
||||
}
|
||||
renderstyle = STYLE_Translucent;
|
||||
Process(frontsector, true, false);
|
||||
Process(frontsector, sector_t::ceiling, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -176,12 +176,12 @@ void GLPortal::DrawPortalStencil()
|
|||
bool GLPortal::Start(bool usestencil, bool doquery)
|
||||
{
|
||||
rendered_portals++;
|
||||
PortalAll.Clock();
|
||||
// PortalAll.Clock();
|
||||
if (usestencil)
|
||||
{
|
||||
if (!gl_portals)
|
||||
{
|
||||
PortalAll.Unclock();
|
||||
// PortalAll.Unclock();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -297,7 +297,7 @@ bool GLPortal::Start(bool usestencil, bool doquery)
|
|||
GLRenderer->mCurrentPortal = this;
|
||||
|
||||
if (PrevPortal != NULL) PrevPortal->PushState();
|
||||
PortalAll.Unclock();
|
||||
// PortalAll.Unclock();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1219,7 +1219,7 @@ void GLEEHorizonPortal::DrawContents()
|
|||
if (sector->GetTexture(sector_t::ceiling) != skyflatnum)
|
||||
{
|
||||
GLHorizonInfo horz;
|
||||
horz.plane.GetFromSector(sector, true);
|
||||
horz.plane.GetFromSector(sector, sector_t::ceiling);
|
||||
horz.lightlevel = gl_ClampLight(sector->GetCeilingLight());
|
||||
horz.colormap = sector->ColorMap;
|
||||
if (portal->mType == PORTS_PLANE)
|
||||
|
@ -1232,7 +1232,7 @@ void GLEEHorizonPortal::DrawContents()
|
|||
if (sector->GetTexture(sector_t::floor) != skyflatnum)
|
||||
{
|
||||
GLHorizonInfo horz;
|
||||
horz.plane.GetFromSector(sector, false);
|
||||
horz.plane.GetFromSector(sector, sector_t::floor);
|
||||
horz.lightlevel = gl_ClampLight(sector->GetFloorLight());
|
||||
horz.colormap = sector->ColorMap;
|
||||
if (portal->mType == PORTS_PLANE)
|
||||
|
|
|
@ -114,6 +114,7 @@ void FSkyVertexBuffer::BindVBO()
|
|||
glEnableVertexAttribArray(VATTR_TEXCOORD);
|
||||
glEnableVertexAttribArray(VATTR_COLOR);
|
||||
glDisableVertexAttribArray(VATTR_VERTEX2);
|
||||
glDisableVertexAttribArray(VATTR_NORMAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -406,6 +406,7 @@ void GLSprite::Draw(int pass)
|
|||
gl_RenderState.Apply();
|
||||
|
||||
FVector3 v[4];
|
||||
gl_RenderState.SetNormal(0, 0, 0);
|
||||
CalculateVertices(v);
|
||||
|
||||
FQuadDrawer qd;
|
||||
|
|
|
@ -60,6 +60,15 @@ struct GLSeg
|
|||
float x1,x2;
|
||||
float y1,y2;
|
||||
float fracleft, fracright; // fractional offset of the 2 vertices on the linedef
|
||||
|
||||
FVector3 Normal() const
|
||||
{
|
||||
// we do not use the vector math inlines here because they are not optimized for speed but accuracy in the playsim
|
||||
float x = y2 - y1;
|
||||
float y = x1 - x2;
|
||||
float length = sqrt(x*x + y*y);
|
||||
return FVector3(x / length, 0, y / length);
|
||||
}
|
||||
};
|
||||
|
||||
struct texcoord
|
||||
|
|
|
@ -470,7 +470,7 @@ bool GLWall::DoHorizon(seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2)
|
|||
}
|
||||
else
|
||||
{
|
||||
hi.plane.GetFromSector(fs, true);
|
||||
hi.plane.GetFromSector(fs, sector_t::ceiling);
|
||||
hi.lightlevel = gl_ClampLight(fs->GetCeilingLight());
|
||||
hi.colormap = fs->ColorMap;
|
||||
|
||||
|
@ -498,7 +498,7 @@ bool GLWall::DoHorizon(seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2)
|
|||
}
|
||||
else
|
||||
{
|
||||
hi.plane.GetFromSector(fs, false);
|
||||
hi.plane.GetFromSector(fs, sector_t::floor);
|
||||
hi.lightlevel = gl_ClampLight(fs->GetFloorLight());
|
||||
hi.colormap = fs->ColorMap;
|
||||
|
||||
|
|
|
@ -254,14 +254,13 @@ void GLWall::RenderMirrorSurface()
|
|||
if (GLRenderer->mirrortexture == NULL) return;
|
||||
|
||||
// For the sphere map effect we need a normal of the mirror surface,
|
||||
Vector v(glseg.y2-glseg.y1, 0 ,-glseg.x2+glseg.x1);
|
||||
v.Normalize();
|
||||
FVector3 v = glseg.Normal();
|
||||
|
||||
if (!gl.legacyMode)
|
||||
{
|
||||
// we use texture coordinates and texture matrix to pass the normal stuff to the shader so that the default vertex buffer format can be used as is.
|
||||
tcs[LOLFT].u = tcs[LORGT].u = tcs[UPLFT].u = tcs[UPRGT].u = v.X();
|
||||
tcs[LOLFT].v = tcs[LORGT].v = tcs[UPLFT].v = tcs[UPRGT].v = v.Z();
|
||||
tcs[LOLFT].u = tcs[LORGT].u = tcs[UPLFT].u = tcs[UPRGT].u = v.X;
|
||||
tcs[LOLFT].v = tcs[LORGT].v = tcs[UPLFT].v = tcs[UPRGT].v = v.Z;
|
||||
|
||||
gl_RenderState.EnableTextureMatrix(true);
|
||||
gl_RenderState.mTextureMatrix.computeNormalMatrix(gl_RenderState.mViewMatrix);
|
||||
|
@ -414,6 +413,7 @@ void GLWall::RenderTranslucentWall()
|
|||
//==========================================================================
|
||||
void GLWall::Draw(int pass)
|
||||
{
|
||||
gl_RenderState.SetNormal(glseg.Normal());
|
||||
switch (pass)
|
||||
{
|
||||
case GLPASS_LIGHTSONLY:
|
||||
|
|
99
src/gl/shaders/gl_fxaashader.cpp
Normal file
99
src/gl/shaders/gl_fxaashader.cpp
Normal file
|
@ -0,0 +1,99 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright(C) 2016 Alexey Lysiuk
|
||||
// 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/
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
//
|
||||
// Fast approXimate Anti-Aliasing (FXAA) post-processing
|
||||
//
|
||||
|
||||
#include "gl/system/gl_system.h"
|
||||
#include "gl/shaders/gl_fxaashader.h"
|
||||
|
||||
EXTERN_CVAR(Int, gl_fxaa)
|
||||
|
||||
void FFXAALumaShader::Bind()
|
||||
{
|
||||
if (!mShader)
|
||||
{
|
||||
mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
|
||||
mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/fxaa.fp", "#define FXAA_LUMA_PASS\n", 330);
|
||||
mShader.SetFragDataLocation(0, "FragColor");
|
||||
mShader.Link("shaders/glsl/fxaa");
|
||||
mShader.SetAttribLocation(0, "PositionInProjection");
|
||||
InputTexture.Init(mShader, "InputTexture");
|
||||
}
|
||||
|
||||
mShader.Bind();
|
||||
}
|
||||
|
||||
static int GetMaxVersion()
|
||||
{
|
||||
return gl.glslversion >= 4.f ? 400 : 330;
|
||||
}
|
||||
|
||||
static FString GetDefines()
|
||||
{
|
||||
int quality;
|
||||
|
||||
switch (gl_fxaa)
|
||||
{
|
||||
default:
|
||||
case FFXAAShader::Low: quality = 10; break;
|
||||
case FFXAAShader::Medium: quality = 12; break;
|
||||
case FFXAAShader::High: quality = 29; break;
|
||||
case FFXAAShader::Extreme: quality = 39; break;
|
||||
}
|
||||
|
||||
const int gatherAlpha = GetMaxVersion() >= 400 ? 1 : 0;
|
||||
|
||||
// TODO: enable FXAA_GATHER4_ALPHA on OpenGL earlier than 4.0
|
||||
// when GL_ARB_gpu_shader5/GL_NV_gpu_shader5 extensions are supported
|
||||
|
||||
FString result;
|
||||
result.Format(
|
||||
"#define FXAA_QUALITY__PRESET %i\n"
|
||||
"#define FXAA_GATHER4_ALPHA %i\n",
|
||||
quality, gatherAlpha);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void FFXAAShader::Bind()
|
||||
{
|
||||
assert(gl_fxaa > 0 && gl_fxaa < Count);
|
||||
FShaderProgram &shader = mShaders[gl_fxaa];
|
||||
|
||||
if (!shader)
|
||||
{
|
||||
const FString defines = GetDefines();
|
||||
const int maxVersion = GetMaxVersion();
|
||||
|
||||
shader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
|
||||
shader.Compile(FShaderProgram::Fragment, "shaders/glsl/fxaa.fp", defines, maxVersion);
|
||||
shader.SetFragDataLocation(0, "FragColor");
|
||||
shader.Link("shaders/glsl/fxaa");
|
||||
shader.SetAttribLocation(0, "PositionInProjection");
|
||||
InputTexture.Init(shader, "InputTexture");
|
||||
ReciprocalResolution.Init(shader, "ReciprocalResolution");
|
||||
}
|
||||
|
||||
shader.Bind();
|
||||
}
|
66
src/gl/shaders/gl_fxaashader.h
Normal file
66
src/gl/shaders/gl_fxaashader.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright(C) 2016 Alexey Lysiuk
|
||||
// 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/
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
//
|
||||
// Fast approXimate Anti-Aliasing (FXAA) post-processing
|
||||
//
|
||||
|
||||
#ifndef __GL_FXAASHADER_H__
|
||||
#define __GL_FXAASHADER_H__
|
||||
|
||||
#include "gl_shaderprogram.h"
|
||||
|
||||
class FFXAALumaShader
|
||||
{
|
||||
public:
|
||||
void Bind();
|
||||
|
||||
FBufferedUniform1i InputTexture;
|
||||
|
||||
private:
|
||||
FShaderProgram mShader;
|
||||
};
|
||||
|
||||
|
||||
class FFXAAShader
|
||||
{
|
||||
public:
|
||||
enum Quality
|
||||
{
|
||||
None,
|
||||
Low,
|
||||
Medium,
|
||||
High,
|
||||
Extreme,
|
||||
Count
|
||||
};
|
||||
|
||||
void Bind();
|
||||
|
||||
FBufferedUniform1i InputTexture;
|
||||
FBufferedUniform2f ReciprocalResolution;
|
||||
|
||||
private:
|
||||
FShaderProgram mShaders[Count];
|
||||
};
|
||||
|
||||
#endif // __GL_FXAASHADER_H__
|
60
src/gl/shaders/gl_present3dRowshader.cpp
Normal file
60
src/gl/shaders/gl_present3dRowshader.cpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright(C) 2016 Christopher Bruns
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see http://www.gnu.org/licenses/
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
/*
|
||||
** gl_3dRowshader.cpp
|
||||
** Copy rendered texture to back buffer, possibly with gamma correction
|
||||
** while interleaving rows from two independent viewpoint textures,
|
||||
** representing the left-eye and right-eye views.
|
||||
**
|
||||
*/
|
||||
|
||||
#include "gl/system/gl_system.h"
|
||||
#include "files.h"
|
||||
#include "m_swap.h"
|
||||
#include "v_video.h"
|
||||
#include "gl/gl_functions.h"
|
||||
#include "vectors.h"
|
||||
#include "gl/system/gl_interface.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl/system/gl_cvars.h"
|
||||
#include "gl/shaders/gl_present3dRowshader.h"
|
||||
|
||||
void FPresent3DRowShader::Bind()
|
||||
{
|
||||
if (!mShader)
|
||||
{
|
||||
mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquadscale.vp", "", 330);
|
||||
mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/present_row3d.fp", "", 330);
|
||||
mShader.SetFragDataLocation(0, "FragColor");
|
||||
mShader.Link("shaders/glsl/presentRow3d");
|
||||
mShader.SetAttribLocation(0, "PositionInProjection");
|
||||
mShader.SetAttribLocation(1, "UV");
|
||||
LeftEyeTexture.Init(mShader, "LeftEyeTexture");
|
||||
RightEyeTexture.Init(mShader, "RightEyeTexture");
|
||||
InvGamma.Init(mShader, "InvGamma");
|
||||
Contrast.Init(mShader, "Contrast");
|
||||
Brightness.Init(mShader, "Brightness");
|
||||
Scale.Init(mShader, "UVScale");
|
||||
VerticalPixelOffset.Init(mShader, "VerticalPixelOffset");
|
||||
}
|
||||
mShader.Bind();
|
||||
}
|
51
src/gl/shaders/gl_present3dRowshader.h
Normal file
51
src/gl/shaders/gl_present3dRowshader.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright(C) 2015 Christopher Bruns
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see http://www.gnu.org/licenses/
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
/*
|
||||
** gl_present3dRowshader.h
|
||||
** Final composition and present shader for row-interleaved stereoscopic 3D mode
|
||||
**
|
||||
*/
|
||||
|
||||
#ifndef GL_PRESENT3DROWSHADER_H_
|
||||
#define GL_PRESENT3DROWSHADER_H_
|
||||
|
||||
#include "gl_shaderprogram.h"
|
||||
|
||||
class FPresent3DRowShader
|
||||
{
|
||||
public:
|
||||
void Bind();
|
||||
|
||||
FBufferedUniformSampler LeftEyeTexture;
|
||||
FBufferedUniformSampler RightEyeTexture;
|
||||
FBufferedUniform1f InvGamma;
|
||||
FBufferedUniform1f Contrast;
|
||||
FBufferedUniform1f Brightness;
|
||||
FBufferedUniform2f Scale;
|
||||
FBufferedUniform1i VerticalPixelOffset;
|
||||
|
||||
private:
|
||||
FShaderProgram mShader;
|
||||
};
|
||||
|
||||
// GL_PRESENT3DROWSHADER_H_
|
||||
#endif
|
|
@ -179,6 +179,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
|||
glBindAttribLocation(hShader, VATTR_TEXCOORD, "aTexCoord");
|
||||
glBindAttribLocation(hShader, VATTR_COLOR, "aColor");
|
||||
glBindAttribLocation(hShader, VATTR_VERTEX2, "aVertex2");
|
||||
glBindAttribLocation(hShader, VATTR_NORMAL, "aNormal");
|
||||
|
||||
glBindFragDataLocation(hShader, 0, "FragColor");
|
||||
glBindFragDataLocation(hShader, 1, "FragData");
|
||||
|
@ -244,6 +245,8 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
|||
texturematrix_index = glGetUniformLocation(hShader, "TextureMatrix");
|
||||
vertexmatrix_index = glGetUniformLocation(hShader, "uQuadVertices");
|
||||
texcoordmatrix_index = glGetUniformLocation(hShader, "uQuadTexCoords");
|
||||
normalviewmatrix_index = glGetUniformLocation(hShader, "NormalViewMatrix");
|
||||
normalmodelmatrix_index = glGetUniformLocation(hShader, "NormalModelMatrix");
|
||||
quadmode_index = glGetUniformLocation(hShader, "uQuadMode");
|
||||
|
||||
if (!gl.legacyMode && !(gl.flags & RFL_SHADER_STORAGE_BUFFER))
|
||||
|
@ -332,14 +335,14 @@ FShader *FShaderCollection::Compile (const char *ShaderName, const char *ShaderP
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FShader::ApplyMatrices(VSMatrix *proj, VSMatrix *view)
|
||||
void FShader::ApplyMatrices(VSMatrix *proj, VSMatrix *view, VSMatrix *norm)
|
||||
{
|
||||
Bind();
|
||||
glUniformMatrix4fv(projectionmatrix_index, 1, false, proj->get());
|
||||
glUniformMatrix4fv(viewmatrix_index, 1, false, view->get());
|
||||
glUniformMatrix4fv(normalviewmatrix_index, 1, false, norm->get());
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -601,23 +604,26 @@ EXTERN_CVAR(Int, gl_fuzztype)
|
|||
|
||||
void FShaderCollection::ApplyMatrices(VSMatrix *proj, VSMatrix *view)
|
||||
{
|
||||
VSMatrix norm;
|
||||
norm.computeNormalMatrix(*view);
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
mTextureEffects[i]->ApplyMatrices(proj, view);
|
||||
mTextureEffectsNAT[i]->ApplyMatrices(proj, view);
|
||||
mTextureEffects[i]->ApplyMatrices(proj, view, &norm);
|
||||
mTextureEffectsNAT[i]->ApplyMatrices(proj, view, &norm);
|
||||
}
|
||||
mTextureEffects[4]->ApplyMatrices(proj, view);
|
||||
mTextureEffects[4]->ApplyMatrices(proj, view, &norm);
|
||||
if (gl_fuzztype != 0)
|
||||
{
|
||||
mTextureEffects[4 + gl_fuzztype]->ApplyMatrices(proj, view);
|
||||
mTextureEffects[4 + gl_fuzztype]->ApplyMatrices(proj, view, &norm);
|
||||
}
|
||||
for (unsigned i = 12; i < mTextureEffects.Size(); i++)
|
||||
{
|
||||
mTextureEffects[i]->ApplyMatrices(proj, view);
|
||||
mTextureEffects[i]->ApplyMatrices(proj, view, &norm);
|
||||
}
|
||||
for (int i = 0; i < MAX_EFFECTS; i++)
|
||||
{
|
||||
mEffectShaders[i]->ApplyMatrices(proj, view);
|
||||
mEffectShaders[i]->ApplyMatrices(proj, view, &norm);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -286,7 +286,9 @@ class FShader
|
|||
int lights_index;
|
||||
int projectionmatrix_index;
|
||||
int viewmatrix_index;
|
||||
int normalviewmatrix_index;
|
||||
int modelmatrix_index;
|
||||
int normalmodelmatrix_index;
|
||||
int texturematrix_index;
|
||||
public:
|
||||
int vertexmatrix_index;
|
||||
|
@ -319,7 +321,7 @@ public:
|
|||
bool Bind();
|
||||
unsigned int GetHandle() const { return hShader; }
|
||||
|
||||
void ApplyMatrices(VSMatrix *proj, VSMatrix *view);
|
||||
void ApplyMatrices(VSMatrix *proj, VSMatrix *view, VSMatrix *norm);
|
||||
|
||||
};
|
||||
|
||||
|
|
124
src/gl/stereo3d/gl_interleaved3d.cpp
Normal file
124
src/gl/stereo3d/gl_interleaved3d.cpp
Normal file
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
** gl_interleaved3d.cpp
|
||||
** Interleaved image stereoscopic 3D modes for GZDoom
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2016 Christopher Bruns
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
**
|
||||
*/
|
||||
|
||||
#include "gl_interleaved3d.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/renderer/gl_renderbuffers.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl/shaders/gl_present3dRowshader.h"
|
||||
|
||||
EXTERN_CVAR(Float, vid_brightness)
|
||||
EXTERN_CVAR(Float, vid_contrast)
|
||||
EXTERN_CVAR(Bool, fullscreen)
|
||||
EXTERN_CVAR(Int, win_y) // pixel position of top of display window
|
||||
|
||||
namespace s3d {
|
||||
|
||||
/* static */
|
||||
const RowInterleaved3D& RowInterleaved3D::getInstance(float ipd)
|
||||
{
|
||||
static RowInterleaved3D instance(ipd);
|
||||
return instance;
|
||||
}
|
||||
|
||||
RowInterleaved3D::RowInterleaved3D(double ipdMeters)
|
||||
: TopBottom3D(ipdMeters)
|
||||
{}
|
||||
|
||||
void RowInterleaved3D::Present() const
|
||||
{
|
||||
GLRenderer->mBuffers->BindOutputFB();
|
||||
GLRenderer->ClearBorders();
|
||||
|
||||
|
||||
// Bind each eye texture, for composition in the shader
|
||||
GLRenderer->mBuffers->BindEyeTexture(0, 0);
|
||||
GLRenderer->mBuffers->BindEyeTexture(1, 1);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
const GL_IRECT& box = GLRenderer->mOutputLetterbox;
|
||||
glViewport(box.left, box.top, box.width, box.height);
|
||||
|
||||
bool applyGamma = true;
|
||||
|
||||
GLRenderer->mPresent3dRowShader->Bind();
|
||||
GLRenderer->mPresent3dRowShader->LeftEyeTexture.Set(0);
|
||||
GLRenderer->mPresent3dRowShader->RightEyeTexture.Set(1);
|
||||
|
||||
if (!applyGamma || GLRenderer->framebuffer->IsHWGammaActive())
|
||||
{
|
||||
GLRenderer->mPresent3dRowShader->InvGamma.Set(1.0f);
|
||||
GLRenderer->mPresent3dRowShader->Contrast.Set(1.0f);
|
||||
GLRenderer->mPresent3dRowShader->Brightness.Set(0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
GLRenderer->mPresent3dRowShader->InvGamma.Set(1.0f / clamp<float>(Gamma, 0.1f, 4.f));
|
||||
GLRenderer->mPresent3dRowShader->Contrast.Set(clamp<float>(vid_contrast, 0.1f, 3.f));
|
||||
GLRenderer->mPresent3dRowShader->Brightness.Set(clamp<float>(vid_brightness, -0.8f, 0.8f));
|
||||
}
|
||||
GLRenderer->mPresent3dRowShader->Scale.Set(
|
||||
GLRenderer->mScreenViewport.width / (float)GLRenderer->mBuffers->GetWidth(),
|
||||
GLRenderer->mScreenViewport.height / (float)GLRenderer->mBuffers->GetHeight());
|
||||
|
||||
// Compute absolute offset from top of screen to top of current display window
|
||||
// because we need screen-relative, not window-relative, scan line parity
|
||||
int windowVOffset = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (! fullscreen) {
|
||||
I_SaveWindowedPos(); // update win_y CVAR
|
||||
windowVOffset = win_y;
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
GLRenderer->mPresent3dRowShader->VerticalPixelOffset.Set(
|
||||
windowVOffset // fixme: vary with window location
|
||||
+ box.height % 2 // because we want the top pixel offset, but gl_FragCoord.y is the bottom pixel offset
|
||||
);
|
||||
|
||||
GLRenderer->RenderScreenQuad();
|
||||
}
|
||||
|
||||
|
||||
} /* namespace s3d */
|
60
src/gl/stereo3d/gl_interleaved3d.h
Normal file
60
src/gl/stereo3d/gl_interleaved3d.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
** gl_interleaved3d.h
|
||||
** Interleaved stereoscopic 3D modes for GZDoom
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2016 Christopher Bruns
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
**
|
||||
*/
|
||||
|
||||
#ifndef GL_INTERLEAVED3D_H_
|
||||
#define GL_INTERLEAVED3D_H_
|
||||
|
||||
#include "gl_stereo3d.h"
|
||||
#include "gl_stereo_leftright.h"
|
||||
#include "gl_sidebyside3d.h"
|
||||
#include "gl/system/gl_system.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
|
||||
class FPresent3DRowShader;
|
||||
|
||||
namespace s3d {
|
||||
|
||||
class RowInterleaved3D : public TopBottom3D
|
||||
{
|
||||
public:
|
||||
static const RowInterleaved3D& getInstance(float ipd);
|
||||
RowInterleaved3D(double ipdMeters);
|
||||
void Present() const override;
|
||||
};
|
||||
|
||||
} /* namespace s3d */
|
||||
|
||||
|
||||
#endif /* GL_INTERLEAVED3D_H_ */
|
|
@ -108,4 +108,43 @@ void SideBySideFull::AdjustPlayerSprites() const /* override */
|
|||
gl_RenderState.ApplyMatrices();
|
||||
}
|
||||
|
||||
/* static */
|
||||
const TopBottom3D& TopBottom3D::getInstance(float ipd)
|
||||
{
|
||||
static TopBottom3D instance(ipd);
|
||||
return instance;
|
||||
}
|
||||
|
||||
void TopBottom3D::Present() const
|
||||
{
|
||||
GLRenderer->mBuffers->BindOutputFB();
|
||||
GLRenderer->ClearBorders();
|
||||
|
||||
// Compute screen regions to use for left and right eye views
|
||||
int topHeight = GLRenderer->mOutputLetterbox.height / 2;
|
||||
int bottomHeight = GLRenderer->mOutputLetterbox.height - topHeight;
|
||||
GL_IRECT topHalfScreen = GLRenderer->mOutputLetterbox;
|
||||
topHalfScreen.height = topHeight;
|
||||
topHalfScreen.top = topHeight;
|
||||
GL_IRECT bottomHalfScreen = GLRenderer->mOutputLetterbox;
|
||||
bottomHalfScreen.height = bottomHeight;
|
||||
bottomHalfScreen.top = 0;
|
||||
|
||||
GLRenderer->mBuffers->BindEyeTexture(0, 0);
|
||||
GLRenderer->DrawPresentTexture(topHalfScreen, true);
|
||||
|
||||
GLRenderer->mBuffers->BindEyeTexture(1, 0);
|
||||
GLRenderer->DrawPresentTexture(bottomHalfScreen, true);
|
||||
}
|
||||
|
||||
// AdjustViewports() is called from within FLGRenderer::SetOutputViewport(...)
|
||||
void TopBottom3D::AdjustViewports() const
|
||||
{
|
||||
// Change size of renderbuffer, and align to screen
|
||||
GLRenderer->mSceneViewport.height /= 2;
|
||||
GLRenderer->mSceneViewport.top /= 2;
|
||||
GLRenderer->mScreenViewport.height /= 2;
|
||||
GLRenderer->mScreenViewport.top /= 2;
|
||||
}
|
||||
|
||||
} /* namespace s3d */
|
||||
|
|
|
@ -88,6 +88,14 @@ private:
|
|||
SBSFRightEyePose rightEye;
|
||||
};
|
||||
|
||||
class TopBottom3D : public SideBySideSquished
|
||||
{
|
||||
public:
|
||||
static const TopBottom3D& getInstance(float ipd);
|
||||
TopBottom3D(double ipdMeters) : SideBySideSquished(ipdMeters) {}
|
||||
void Present() const override;
|
||||
virtual void AdjustViewports() const override;
|
||||
};
|
||||
|
||||
} /* namespace s3d */
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "gl/stereo3d/gl_anaglyph.h"
|
||||
#include "gl/stereo3d/gl_quadstereo.h"
|
||||
#include "gl/stereo3d/gl_sidebyside3d.h"
|
||||
#include "gl/stereo3d/gl_interleaved3d.h"
|
||||
#include "gl/system/gl_cvars.h"
|
||||
|
||||
// Set up 3D-specific console variables:
|
||||
|
@ -100,6 +101,12 @@ const Stereo3DMode& Stereo3DMode::getCurrentMode()
|
|||
setCurrentMode(AmberBlue::getInstance(vr_ipd));
|
||||
break;
|
||||
// TODO: 10: HTC Vive/OpenVR
|
||||
case 11:
|
||||
setCurrentMode(TopBottom3D::getInstance(vr_ipd));
|
||||
break;
|
||||
case 12:
|
||||
setCurrentMode(RowInterleaved3D::getInstance(vr_ipd));
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
setCurrentMode(MonoView::getInstance());
|
||||
|
|
|
@ -189,7 +189,9 @@ void OpenGLFrameBuffer::Update()
|
|||
int clientHeight = GetClientHeight();
|
||||
if (clientWidth > 0 && clientHeight > 0 && (Width != clientWidth || Height != clientHeight))
|
||||
{
|
||||
Resize(clientWidth, clientHeight);
|
||||
// Do not call Resize here because it's only for software canvases
|
||||
Pitch = Width = clientWidth;
|
||||
Height = clientHeight;
|
||||
V_OutputResized(Width, Height);
|
||||
GLRenderer->mVBO->OutputResized(Width, Height);
|
||||
}
|
||||
|
@ -209,13 +211,13 @@ void OpenGLFrameBuffer::Swap()
|
|||
{
|
||||
Finish.Reset();
|
||||
Finish.Clock();
|
||||
glFinish();
|
||||
if (needsetgamma)
|
||||
{
|
||||
//DoSetGamma();
|
||||
needsetgamma = false;
|
||||
}
|
||||
SwapBuffers();
|
||||
glFinish();
|
||||
Finish.Unclock();
|
||||
swapped = true;
|
||||
FHardwareTexture::UnbindAll();
|
||||
|
|
15
src/m_swap.h
15
src/m_swap.h
|
@ -46,6 +46,11 @@ inline short LittleShort(int x)
|
|||
return OSSwapLittleToHostInt16((uint16_t)x);
|
||||
}
|
||||
|
||||
inline unsigned short LittleShort(unsigned int x)
|
||||
{
|
||||
return OSSwapLittleToHostInt16((uint16_t)x);
|
||||
}
|
||||
|
||||
inline int LittleLong(int x)
|
||||
{
|
||||
return OSSwapLittleToHostInt32((uint32_t)x);
|
||||
|
@ -56,6 +61,16 @@ inline unsigned int LittleLong(unsigned int x)
|
|||
return OSSwapLittleToHostInt32(x);
|
||||
}
|
||||
|
||||
inline int LittleLong(long x)
|
||||
{
|
||||
return OSSwapLittleToHostInt32((uint32_t)x);
|
||||
}
|
||||
|
||||
inline unsigned int LittleLong(unsigned long x)
|
||||
{
|
||||
return OSSwapLittleToHostInt32((uint32_t)x);
|
||||
}
|
||||
|
||||
inline short BigShort(short x)
|
||||
{
|
||||
return (short)OSSwapBigToHostInt16((uint16_t)x);
|
||||
|
|
|
@ -717,7 +717,11 @@ void M_Drawer (void)
|
|||
|
||||
if (DMenu::CurrentMenu != NULL && menuactive != MENU_Off)
|
||||
{
|
||||
if (DMenu::CurrentMenu->DimAllowed()) screen->Dim(fade);
|
||||
if (DMenu::CurrentMenu->DimAllowed())
|
||||
{
|
||||
screen->Dim(fade);
|
||||
V_SetBorderNeedRefresh();
|
||||
}
|
||||
DMenu::CurrentMenu->Drawer();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -507,6 +507,21 @@ xx(Alphaceiling)
|
|||
xx(Renderstylefloor)
|
||||
xx(Renderstyleceiling)
|
||||
xx(Waterzone)
|
||||
xx(portal_ceil_alpha)
|
||||
xx(portal_ceil_blocksound)
|
||||
xx(portal_ceil_disabled)
|
||||
xx(portal_ceil_nopass)
|
||||
xx(portal_ceil_norender)
|
||||
xx(portal_ceil_overlaytype)
|
||||
xx(portal_ceil_useglobaltex)
|
||||
xx(portal_floor_alpha)
|
||||
xx(portal_floor_blocksound)
|
||||
xx(portal_floor_disabled)
|
||||
xx(portal_floor_nopass)
|
||||
xx(portal_floor_norender)
|
||||
xx(portal_floor_overlaytype)
|
||||
xx(portal_floor_useglobaltex)
|
||||
|
||||
|
||||
xx(offsetx_top)
|
||||
xx(offsety_top)
|
||||
|
|
|
@ -754,7 +754,7 @@ void ACSStringPool::ReadStrings(FSerializer &file, const char *key)
|
|||
unsigned bucketnum = h % NUM_BUCKETS;
|
||||
Pool[ii].Hash = h;
|
||||
Pool[ii].Next = PoolBuckets[bucketnum];
|
||||
PoolBuckets[bucketnum] = i;
|
||||
PoolBuckets[bucketnum] = ii;
|
||||
}
|
||||
file.EndObject();
|
||||
}
|
||||
|
@ -4379,10 +4379,11 @@ enum EACSFunctions
|
|||
ACSF_CheckClass = 200,
|
||||
ACSF_DamageActor, // [arookas]
|
||||
ACSF_SetActorFlag,
|
||||
ACSF_SetTranslation,
|
||||
|
||||
// ZDaemon
|
||||
ACSF_GetTeamScore = 19620, // (int team)
|
||||
ACSF_SetTeamScore, // (int team, int value)
|
||||
ACSF_SetTeamScore, // (int team, int value
|
||||
};
|
||||
|
||||
int DLevelScript::SideFromID(int id, int side)
|
||||
|
@ -6002,6 +6003,26 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
return count;
|
||||
}
|
||||
|
||||
case ACSF_SetTranslation:
|
||||
{
|
||||
int tid = args[0];
|
||||
const char *trname = FBehavior::StaticLookupString(args[1]);
|
||||
if (tid == 0)
|
||||
{
|
||||
if (activator != nullptr)
|
||||
activator->SetTranslation(trname);
|
||||
}
|
||||
else
|
||||
{
|
||||
FActorIterator it(tid);
|
||||
while ((actor = it.Next()) != nullptr)
|
||||
{
|
||||
actor->SetTranslation(trname);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -342,7 +342,7 @@ bool P_CreateFloor(sector_t *sec, DFloor::EFloor floortype, line_t *line,
|
|||
ceilingheight = sec->FindLowestCeilingPoint(&spot2);
|
||||
floor->m_FloorDestDist = sec->floorplane.PointToDist(spot, newheight);
|
||||
if (sec->floorplane.ZatPointDist(spot2, floor->m_FloorDestDist) > ceilingheight)
|
||||
floor->m_FloorDestDist = sec->floorplane.PointToDist(spot2, floortype == ceilingheight - height);
|
||||
floor->m_FloorDestDist = sec->floorplane.PointToDist(spot2, ceilingheight - height);
|
||||
break;
|
||||
|
||||
case DFloor::floorRaiseToHighest:
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
#include "p_spec.h"
|
||||
#include "p_checkposition.h"
|
||||
#include "serializer.h"
|
||||
#include "r_utility.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
@ -1040,11 +1041,11 @@ bool AActor::IsInsideVisibleAngles() const
|
|||
if (players[consoleplayer].camera == nullptr)
|
||||
return true;
|
||||
|
||||
DAngle anglestart = VisibleStartAngle.Normalized180();
|
||||
DAngle angleend = VisibleEndAngle.Normalized180();
|
||||
DAngle pitchstart = VisibleStartPitch.Normalized180();
|
||||
DAngle pitchend = VisibleEndPitch.Normalized180();
|
||||
|
||||
DAngle anglestart = VisibleStartAngle;
|
||||
DAngle angleend = VisibleEndAngle;
|
||||
DAngle pitchstart = VisibleStartPitch;
|
||||
DAngle pitchend = VisibleEndPitch;
|
||||
|
||||
if (anglestart > angleend)
|
||||
{
|
||||
DAngle temp = anglestart;
|
||||
|
@ -1052,28 +1053,26 @@ bool AActor::IsInsideVisibleAngles() const
|
|||
angleend = temp;
|
||||
}
|
||||
|
||||
if (pitchstart > angleend)
|
||||
if (pitchstart > pitchend)
|
||||
{
|
||||
DAngle temp = pitchstart;
|
||||
pitchstart = pitchend;
|
||||
pitchend = temp;
|
||||
}
|
||||
|
||||
|
||||
player_t* pPlayer = players[consoleplayer].camera->player;
|
||||
AActor *mo = players[consoleplayer].camera;
|
||||
|
||||
if (pPlayer && pPlayer->mo)
|
||||
if (mo != nullptr)
|
||||
{
|
||||
AActor *mo = pPlayer->mo;
|
||||
DVector3 diffang = Vec3To(mo);
|
||||
|
||||
DVector3 diffang = ViewPos - Pos();
|
||||
DAngle to = diffang.Angle();
|
||||
|
||||
if (!(renderflags & RF_ABSMASKANGLE))
|
||||
to = deltaangle(Angles.Yaw, to);
|
||||
|
||||
// Note that this check is inversed due to only being able to vectorize
|
||||
// from one way (this actor to the player). It still means to pass
|
||||
// if the player is within the visible angles.
|
||||
if ((to <= anglestart || to >= angleend))
|
||||
if ((to >= anglestart && to <= angleend))
|
||||
{
|
||||
to = diffang.Pitch();
|
||||
if (!(renderflags & RF_ABSMASKPITCH))
|
||||
|
@ -1324,6 +1323,9 @@ bool AActor::Massacre ()
|
|||
|
||||
if (health > 0)
|
||||
{
|
||||
auto f = flags;
|
||||
auto f2 = flags2;
|
||||
|
||||
flags |= MF_SHOOTABLE;
|
||||
flags2 &= ~(MF2_DORMANT|MF2_INVULNERABLE);
|
||||
do
|
||||
|
@ -1332,6 +1334,12 @@ bool AActor::Massacre ()
|
|||
P_DamageMobj (this, NULL, NULL, TELEFRAG_DAMAGE, NAME_Massacre);
|
||||
}
|
||||
while (health != prevhealth && health > 0); //abort if the actor wasn't hurt.
|
||||
if (health > 0)
|
||||
{
|
||||
// restore flags if this did not kill the monster.
|
||||
flags = f;
|
||||
flags2 = f2;
|
||||
}
|
||||
return health <= 0;
|
||||
}
|
||||
return false;
|
||||
|
@ -3518,7 +3526,7 @@ void AActor::Tick ()
|
|||
sector_t *sec = node->m_sector;
|
||||
DVector2 scrollv;
|
||||
|
||||
if (level.Scrolls.Size() > (sec-sectors))
|
||||
if (level.Scrolls.Size() > unsigned(sec-sectors))
|
||||
{
|
||||
scrollv = level.Scrolls[sec - sectors];
|
||||
}
|
||||
|
@ -6517,6 +6525,23 @@ int AActor::ApplyDamageFactor(FName damagetype, int damage) const
|
|||
}
|
||||
|
||||
|
||||
void AActor::SetTranslation(const char *trname)
|
||||
{
|
||||
if (*trname == 0)
|
||||
{
|
||||
// an empty string resets to the default
|
||||
Translation = GetDefault()->Translation;
|
||||
return;
|
||||
}
|
||||
|
||||
int tnum = R_FindCustomTranslation(trname);
|
||||
if (tnum >= 0)
|
||||
{
|
||||
Translation = tnum;
|
||||
}
|
||||
// silently ignore if the name does not exist, this would create some insane message spam otherwise.
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// DropItem handling
|
||||
|
|
|
@ -1049,6 +1049,25 @@ DEFINE_ACTION_FUNCTION(AActor, A_OverlayFlags)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC OverlayID
|
||||
// Because non-action functions cannot acquire the ID of the overlay...
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, OverlayID)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (ACTION_CALL_FROM_PSPRITE())
|
||||
{
|
||||
ACTION_RETURN_INT(stateinfo->mPSPIndex);
|
||||
}
|
||||
ACTION_RETURN_INT(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC A_Lower
|
||||
|
|
|
@ -642,6 +642,11 @@ static void ReadOnePlayer(FSerializer &arc, bool skipload)
|
|||
{
|
||||
CopyPlayer(&players[i], &playerTemp, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we need the player actor, so that G_FinishTravel can destroy it later.
|
||||
players[i].mo = playerTemp.mo;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -755,6 +760,13 @@ static void ReadMultiplePlayers(FSerializer &arc, int numPlayers, int numPlayers
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
players[i].mo = playertemp[i].mo;
|
||||
}
|
||||
}
|
||||
|
||||
delete[] tempPlayerUsed;
|
||||
delete[] playertemp;
|
||||
|
|
|
@ -259,6 +259,7 @@ DScroller::DScroller (EScroll type, double dx, double dy,
|
|||
m_Accel = accel;
|
||||
m_Parts = scrollpos;
|
||||
m_vdx = m_vdy = 0;
|
||||
m_LastHeight = 0;
|
||||
if ((m_Control = control) != -1)
|
||||
m_LastHeight =
|
||||
sectors[control].CenterFloor () + sectors[control].CenterCeiling ();
|
||||
|
@ -342,6 +343,7 @@ DScroller::DScroller (double dx, double dy, const line_t *l,
|
|||
m_vdx = m_vdy = 0;
|
||||
m_Accel = accel;
|
||||
m_Parts = scrollpos;
|
||||
m_LastHeight = 0;
|
||||
if ((m_Control = control) != -1)
|
||||
m_LastHeight = sectors[control].CenterFloor() + sectors[control].CenterCeiling();
|
||||
m_Affectee = int(l->sidedef[0] - sides);
|
||||
|
|
|
@ -1568,6 +1568,60 @@ public:
|
|||
tagstring = CheckString(key);
|
||||
break;
|
||||
|
||||
case NAME_portal_ceil_alpha:
|
||||
sec->planes[sector_t::ceiling].alpha = CheckFloat(key);
|
||||
break;
|
||||
|
||||
case NAME_portal_ceil_blocksound:
|
||||
Flag(sec->planes[sector_t::ceiling].Flags, PLANEF_BLOCKSOUND, key);
|
||||
break;
|
||||
|
||||
case NAME_portal_ceil_disabled:
|
||||
Flag(sec->planes[sector_t::ceiling].Flags, PLANEF_DISABLED, key);
|
||||
break;
|
||||
|
||||
case NAME_portal_ceil_nopass:
|
||||
Flag(sec->planes[sector_t::ceiling].Flags, PLANEF_NOPASS, key);
|
||||
break;
|
||||
|
||||
case NAME_portal_ceil_norender:
|
||||
Flag(sec->planes[sector_t::ceiling].Flags, PLANEF_NORENDER, key);
|
||||
break;
|
||||
|
||||
case NAME_portal_ceil_overlaytype:
|
||||
if (!stricmp(CheckString(key), "translucent")) sec->planes[sector_t::ceiling].Flags &= ~PLANEF_ADDITIVE;
|
||||
else if (!stricmp(CheckString(key), "additive")) sec->planes[sector_t::ceiling].Flags |= PLANEF_ADDITIVE;
|
||||
break;
|
||||
|
||||
case NAME_portal_floor_alpha:
|
||||
sec->planes[sector_t::floor].alpha = CheckFloat(key);
|
||||
break;
|
||||
|
||||
case NAME_portal_floor_blocksound:
|
||||
Flag(sec->planes[sector_t::floor].Flags, PLANEF_BLOCKSOUND, key);
|
||||
break;
|
||||
|
||||
case NAME_portal_floor_disabled:
|
||||
Flag(sec->planes[sector_t::floor].Flags, PLANEF_DISABLED, key);
|
||||
break;
|
||||
|
||||
case NAME_portal_floor_nopass:
|
||||
Flag(sec->planes[sector_t::floor].Flags, PLANEF_NOPASS, key);
|
||||
break;
|
||||
|
||||
case NAME_portal_floor_norender:
|
||||
Flag(sec->planes[sector_t::floor].Flags, PLANEF_NORENDER, key);
|
||||
break;
|
||||
|
||||
case NAME_portal_floor_overlaytype:
|
||||
if (!stricmp(CheckString(key), "translucent")) sec->planes[sector_t::floor].Flags &= ~PLANEF_ADDITIVE;
|
||||
else if (!stricmp(CheckString(key), "additive")) sec->planes[sector_t::floor].Flags |= PLANEF_ADDITIVE;
|
||||
break;
|
||||
|
||||
// These two are used by Eternity for something I do not understand.
|
||||
//case NAME_portal_ceil_useglobaltex:
|
||||
//case NAME_portal_floor_useglobaltex:
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -609,26 +609,26 @@ void FRemapTable::AddToTranslation(const char *range)
|
|||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
int FRemapTable::StoreTranslation()
|
||||
int FRemapTable::StoreTranslation(int slot)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < translationtables[TRANSLATION_Decorate].Size(); i++)
|
||||
for (i = 0; i < translationtables[slot].Size(); i++)
|
||||
{
|
||||
if (*this == *translationtables[TRANSLATION_Decorate][i])
|
||||
if (*this == *translationtables[slot][i])
|
||||
{
|
||||
// A duplicate of this translation already exists
|
||||
return TRANSLATION(TRANSLATION_Decorate, i);
|
||||
return TRANSLATION(slot, i);
|
||||
}
|
||||
}
|
||||
if (translationtables[TRANSLATION_Decorate].Size() >= MAX_DECORATE_TRANSLATIONS)
|
||||
if (translationtables[slot].Size() >= MAX_DECORATE_TRANSLATIONS)
|
||||
{
|
||||
I_Error("Too many DECORATE translations");
|
||||
}
|
||||
FRemapTable *newtrans = new FRemapTable;
|
||||
*newtrans = *this;
|
||||
i = translationtables[TRANSLATION_Decorate].Push(newtrans);
|
||||
return TRANSLATION(TRANSLATION_Decorate, i);
|
||||
i = translationtables[slot].Push(newtrans);
|
||||
return TRANSLATION(slot, i);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1197,3 +1197,90 @@ void R_GetPlayerTranslation (int color, const FPlayerColorSet *colorset, FPlayer
|
|||
|
||||
R_CreatePlayerTranslation (h, s, v, colorset, skin, table, NULL, NULL);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
static TMap<FName, int> customTranslationMap;
|
||||
|
||||
int R_FindCustomTranslation(const char *name)
|
||||
{
|
||||
if (name == nullptr)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
// Ice is a special case which will remain in its original slot.
|
||||
if (!stricmp(name, "Ice"))
|
||||
{
|
||||
return TRANSLATION(TRANSLATION_Standard, 7);
|
||||
}
|
||||
int *t = customTranslationMap.CheckKey(FName(name, true));
|
||||
return (t != nullptr)? *t : -1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void R_ParseTrnslate()
|
||||
{
|
||||
customTranslationMap.Clear();
|
||||
translationtables[TRANSLATION_Custom].Clear();
|
||||
|
||||
int lump;
|
||||
int lastlump = 0;
|
||||
while (-1 != (lump = Wads.FindLump("TRNSLATE", &lastlump)))
|
||||
{
|
||||
FScanner sc(lump);
|
||||
while (sc.GetToken())
|
||||
{
|
||||
sc.TokenMustBe(TK_Identifier);
|
||||
|
||||
FName newtrans = sc.String;
|
||||
FRemapTable *base = nullptr;
|
||||
if (sc.CheckToken(':'))
|
||||
{
|
||||
sc.MustGetAnyToken();
|
||||
if (sc.TokenType == TK_IntConst)
|
||||
{
|
||||
int max = 6;
|
||||
if (sc.Number < 0 || sc.Number > max)
|
||||
{
|
||||
sc.ScriptError("Translation must be in the range [0,%d]", max);
|
||||
}
|
||||
base = translationtables[TRANSLATION_Standard][sc.Number];
|
||||
}
|
||||
else if (sc.TokenType == TK_Identifier)
|
||||
{
|
||||
int tnum = R_FindCustomTranslation(sc.String);
|
||||
if (tnum == -1)
|
||||
{
|
||||
sc.ScriptError("Base translation '%s' not found in '%s'", sc.String, newtrans.GetChars());
|
||||
}
|
||||
base = translationtables[GetTranslationType(tnum)][GetTranslationIndex(tnum)];
|
||||
}
|
||||
else
|
||||
{
|
||||
// error out.
|
||||
sc.TokenMustBe(TK_Identifier);
|
||||
}
|
||||
}
|
||||
sc.MustGetToken('=');
|
||||
FRemapTable NewTranslation;
|
||||
if (base != nullptr) NewTranslation = *base;
|
||||
else NewTranslation.MakeIdentity();
|
||||
do
|
||||
{
|
||||
sc.MustGetToken(TK_StringConst);
|
||||
NewTranslation.AddToTranslation(sc.String);
|
||||
} while (sc.CheckToken(','));
|
||||
|
||||
int trans = NewTranslation.StoreTranslation(TRANSLATION_Custom);
|
||||
customTranslationMap[newtrans] = trans;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ enum
|
|||
TRANSLATION_Decorate,
|
||||
TRANSLATION_Blood,
|
||||
TRANSLATION_RainPillar,
|
||||
TRANSLATION_Custom,
|
||||
|
||||
NUM_TRANSLATION_TABLES
|
||||
};
|
||||
|
@ -42,7 +43,7 @@ struct FRemapTable
|
|||
void AddColorRange(int start, int end, int r1,int g1, int b1, int r2, int g2, int b2);
|
||||
void AddDesaturation(int start, int end, double r1, double g1, double b1, double r2, double g2, double b2);
|
||||
void AddToTranslation(const char * range);
|
||||
int StoreTranslation();
|
||||
int StoreTranslation(int slot);
|
||||
|
||||
BYTE *Remap; // For the software renderer
|
||||
PalEntry *Palette; // The ideal palette this maps to
|
||||
|
@ -109,6 +110,9 @@ extern TArray<PalEntry> BloodTranslationColors;
|
|||
|
||||
int CreateBloodTranslation(PalEntry color);
|
||||
|
||||
int R_FindCustomTranslation(const char *name);
|
||||
void R_ParseTrnslate();
|
||||
|
||||
|
||||
|
||||
#endif // __R_TRANSLATE_H
|
||||
|
|
|
@ -321,23 +321,31 @@ protected:
|
|||
}
|
||||
|
||||
bool WriteDouble(double d) {
|
||||
if (internal::Double(d).IsNanOrInf()) {
|
||||
if (!(writeFlags & kWriteNanAndInfFlag))
|
||||
return false;
|
||||
if (internal::Double(d).IsNan()) {
|
||||
PutReserve(*os_, 3);
|
||||
PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');
|
||||
return true;
|
||||
}
|
||||
if (internal::Double(d).Sign()) {
|
||||
PutReserve(*os_, 9);
|
||||
PutUnsafe(*os_, '-');
|
||||
}
|
||||
else
|
||||
PutReserve(*os_, 8);
|
||||
PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f');
|
||||
PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y');
|
||||
return true;
|
||||
bool ret = true;
|
||||
if (internal::Double(d).IsNanOrInf()) {
|
||||
if (!(writeFlags & kWriteNanAndInfFlag))
|
||||
{
|
||||
// if we abort here, the writer is left in a broken state, unable to recover, so better write a 0 in addition to returning an error.
|
||||
ret = false;
|
||||
d = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (internal::Double(d).IsNan()) {
|
||||
PutReserve(*os_, 3);
|
||||
PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');
|
||||
return true;
|
||||
}
|
||||
if (internal::Double(d).Sign()) {
|
||||
PutReserve(*os_, 9);
|
||||
PutUnsafe(*os_, '-');
|
||||
}
|
||||
else
|
||||
PutReserve(*os_, 8);
|
||||
PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f');
|
||||
PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
char buffer[25];
|
||||
|
@ -345,7 +353,7 @@ protected:
|
|||
PutReserve(*os_, static_cast<size_t>(end - buffer));
|
||||
for (char* p = buffer; p != end; ++p)
|
||||
PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p));
|
||||
return true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool WriteString(const Ch* str, SizeType length) {
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "i_system.h"
|
||||
#include "d_player.h"
|
||||
#include "serializer.h"
|
||||
#include "v_text.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
@ -326,6 +327,99 @@ void S_HashSounds ()
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// S_CheckIntegrity
|
||||
//
|
||||
// Scans the entire sound list and looks for recursive definitions.
|
||||
//==========================================================================
|
||||
|
||||
static bool S_CheckSound(sfxinfo_t *startsfx, sfxinfo_t *sfx, TArray<sfxinfo_t *> &chain)
|
||||
{
|
||||
sfxinfo_t *me = sfx;
|
||||
bool success = true;
|
||||
unsigned siz = chain.Size();
|
||||
|
||||
if (sfx->bPlayerReserve)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// There is a bad link in here, but let's report it only for the sound that contains the broken definition.
|
||||
// Once that sound has been disabled this one will work again.
|
||||
if (chain.Find(sfx) < chain.Size())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
chain.Push(sfx);
|
||||
|
||||
if (me->bRandomHeader)
|
||||
{
|
||||
const FRandomSoundList *list = &S_rnd[me->link];
|
||||
for (int i = 0; i < list->NumSounds; ++i)
|
||||
{
|
||||
auto rsfx = &S_sfx[list->Sounds[i]];
|
||||
if (rsfx == startsfx)
|
||||
{
|
||||
Printf(TEXTCOLOR_RED "recursive sound $random found for %s:\n", startsfx->name.GetChars());
|
||||
success = false;
|
||||
for (unsigned i = 1; i<chain.Size(); i++)
|
||||
{
|
||||
Printf(TEXTCOLOR_ORANGE " -> %s\n", chain[i]->name.GetChars());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
success &= S_CheckSound(startsfx, rsfx, chain);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (me->link != sfxinfo_t::NO_LINK)
|
||||
{
|
||||
me = &S_sfx[me->link];
|
||||
if (me == startsfx)
|
||||
{
|
||||
Printf(TEXTCOLOR_RED "recursive sound $alias found for %s:\n", startsfx->name.GetChars());
|
||||
success = false;
|
||||
for (unsigned i = 1; i<chain.Size(); i++)
|
||||
{
|
||||
Printf(TEXTCOLOR_ORANGE " -> %s\n", chain[i]->name.GetChars());
|
||||
}
|
||||
chain.Resize(siz);
|
||||
}
|
||||
else
|
||||
{
|
||||
success &= S_CheckSound(startsfx, me, chain);
|
||||
}
|
||||
}
|
||||
chain.Pop();
|
||||
return success;
|
||||
}
|
||||
|
||||
void S_CheckIntegrity()
|
||||
{
|
||||
TArray<sfxinfo_t *> chain;
|
||||
TArray<bool> broken;
|
||||
|
||||
broken.Resize(S_sfx.Size());
|
||||
memset(&broken[0], 0, sizeof(bool)*S_sfx.Size());
|
||||
for (unsigned i = 0; i < S_sfx.Size(); i++)
|
||||
{
|
||||
auto &sfx = S_sfx[i];
|
||||
broken[i] = !S_CheckSound(&sfx, &sfx, chain);
|
||||
}
|
||||
for (unsigned i = 0; i < S_sfx.Size(); i++)
|
||||
{
|
||||
if (broken[i])
|
||||
{
|
||||
auto &sfx = S_sfx[i];
|
||||
Printf(TEXTCOLOR_RED "Sound %s has been disabled\n", sfx.name.GetChars());
|
||||
sfx.bRandomHeader = false;
|
||||
sfx.link = 0; // link to the empty sound.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// S_PickReplacement
|
||||
|
@ -334,13 +428,12 @@ void S_HashSounds ()
|
|||
// is not the head of a random list, then the sound passed is returned.
|
||||
//==========================================================================
|
||||
|
||||
int S_PickReplacement (int refid)
|
||||
int S_PickReplacement(int refid)
|
||||
{
|
||||
if (S_sfx[refid].bRandomHeader)
|
||||
while (S_sfx[refid].bRandomHeader)
|
||||
{
|
||||
const FRandomSoundList *list = &S_rnd[S_sfx[refid].link];
|
||||
|
||||
return list->Sounds[pr_randsound() % list->NumSounds];
|
||||
refid = list->Sounds[pr_randsound() % list->NumSounds];
|
||||
}
|
||||
return refid;
|
||||
}
|
||||
|
@ -941,6 +1034,7 @@ void S_ParseSndInfo (bool redefine)
|
|||
S_ShrinkPlayerSoundLists ();
|
||||
|
||||
sfx_empty = Wads.CheckNumForName ("dsempty", ns_sounds);
|
||||
S_CheckIntegrity();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -961,6 +1055,7 @@ void S_AddLocalSndInfo(int lump)
|
|||
}
|
||||
|
||||
S_ShrinkPlayerSoundLists ();
|
||||
S_CheckIntegrity();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -522,18 +522,19 @@ void S_CacheSound (sfxinfo_t *sfx)
|
|||
{
|
||||
return;
|
||||
}
|
||||
else if (sfx->bRandomHeader)
|
||||
sfxinfo_t *orig = sfx;
|
||||
while (!sfx->bRandomHeader && sfx->link != sfxinfo_t::NO_LINK)
|
||||
{
|
||||
S_CacheRandomSound (sfx);
|
||||
sfx = &S_sfx[sfx->link];
|
||||
}
|
||||
if (sfx->bRandomHeader)
|
||||
{
|
||||
S_CacheRandomSound(sfx);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (sfx->link != sfxinfo_t::NO_LINK)
|
||||
{
|
||||
sfx = &S_sfx[sfx->link];
|
||||
}
|
||||
S_LoadSound(sfx);
|
||||
sfx->bUsed = true;
|
||||
S_LoadSound (sfx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -753,8 +754,8 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector,
|
|||
if (type == SOURCE_Actor && actor != NULL)
|
||||
{
|
||||
vel->X = float(actor->Vel.X * TICRATE);
|
||||
vel->Y = float(actor->Vel.Y * TICRATE);
|
||||
vel->Z = float(actor->Vel.Z * TICRATE);
|
||||
vel->Y = float(actor->Vel.Z * TICRATE);
|
||||
vel->Z = float(actor->Vel.Y * TICRATE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -215,8 +215,14 @@ struct FWriter
|
|||
|
||||
void Double(double k)
|
||||
{
|
||||
if (mWriter1) mWriter1->Double(k);
|
||||
else if (mWriter2) mWriter2->Double(k);
|
||||
if (mWriter1)
|
||||
{
|
||||
mWriter1->Double(k);
|
||||
}
|
||||
else if (mWriter2)
|
||||
{
|
||||
mWriter2->Double(k);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -815,7 +821,6 @@ void FSerializer::WriteObjects()
|
|||
for (unsigned i = 0; i < w->mDObjects.Size(); i++)
|
||||
{
|
||||
auto obj = w->mDObjects[i];
|
||||
player_t *player;
|
||||
|
||||
BeginObject(nullptr);
|
||||
w->Key("classtype");
|
||||
|
@ -1294,7 +1299,7 @@ FSerializer &SerializePointer(FSerializer &arc, const char *key, T *&value, T **
|
|||
assert(base != nullptr);
|
||||
if (arc.isReading() || !arc.w->inObject() || defval == nullptr || value != *defval)
|
||||
{
|
||||
ptrdiff_t vv = value == nullptr ? -1 : value - base;
|
||||
int64_t vv = value == nullptr ? -1 : value - base;
|
||||
Serialize(arc, key, vv, nullptr);
|
||||
value = vv < 0 ? nullptr : base + vv;
|
||||
}
|
||||
|
|
|
@ -211,11 +211,11 @@ bool MUSSong2::CheckDone()
|
|||
|
||||
void MUSSong2::Precache()
|
||||
{
|
||||
TArray<WORD> work(MusHeader->NumInstruments);
|
||||
TArray<WORD> work(LittleShort(MusHeader->NumInstruments));
|
||||
const BYTE *used = (BYTE *)MusHeader + sizeof(MUSHeader) / sizeof(BYTE);
|
||||
int i, k;
|
||||
|
||||
for (i = k = 0; i < MusHeader->NumInstruments; ++i)
|
||||
for (i = k = 0; i < LittleShort(MusHeader->NumInstruments); ++i)
|
||||
{
|
||||
BYTE instr = used[k++];
|
||||
WORD val;
|
||||
|
|
|
@ -288,7 +288,7 @@ static void FinishThingdef()
|
|||
|
||||
if (func == nullptr)
|
||||
{
|
||||
VMFunctionBuilder buildit;
|
||||
VMFunctionBuilder buildit(true);
|
||||
|
||||
assert(tcall->Proto != nullptr);
|
||||
|
||||
|
|
|
@ -3322,6 +3322,22 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetTranslucent)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// A_SetRenderStyle
|
||||
//
|
||||
//===========================================================================
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetRenderStyle)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_FLOAT(alpha);
|
||||
PARAM_INT_OPT(mode) { mode = 0; }
|
||||
|
||||
self->Alpha = clamp(alpha, 0., 1.);
|
||||
self->RenderStyle = ERenderStyle(mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// A_FadeIn
|
||||
|
@ -7396,3 +7412,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetVisibleRotation)
|
|||
|
||||
ACTION_RETURN_BOOL(true);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetTranslation)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_STRING(trname);
|
||||
|
||||
self->SetTranslation(trname);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -3373,7 +3373,7 @@ FxExpression *FxClassMember::Resolve(FCompileContext &ctx)
|
|||
|
||||
ExpEmit FxClassMember::Emit(VMFunctionBuilder *build)
|
||||
{
|
||||
if (~membervar->Flags & VARF_Native)
|
||||
if (build->IsActionFunc && ~membervar->Flags & VARF_Native)
|
||||
{ // Check if this is a user-defined variable.
|
||||
// As of right now, FxClassMember is only ever used with FxSelf.
|
||||
// This very user variable was defined in stateowner so if
|
||||
|
@ -3948,15 +3948,16 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx)
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// Assumption: This call is being made to generate code inside an action
|
||||
// method, so the first three address registers are all set up for such a
|
||||
// function. (self, stateowner, callingstate)
|
||||
// Assumption: This call is being generated inside a function whose a0
|
||||
// register is a self pointer. For action functions, a1 maps to stateowner
|
||||
// and a2 maps to callingstate. (self, stateowner, callingstate)
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build)
|
||||
{
|
||||
assert(build->Registers[REGT_POINTER].GetMostUsed() >= 3);
|
||||
assert((build->IsActionFunc && build->Registers[REGT_POINTER].GetMostUsed() >= NAP) ||
|
||||
(!build->IsActionFunc && build->Registers[REGT_POINTER].GetMostUsed() >= 1));
|
||||
int count = (ArgList ? ArgList->Size() : 0);
|
||||
|
||||
if (count == 1)
|
||||
|
@ -3975,8 +3976,18 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build)
|
|||
}
|
||||
if (Function->Flags & VARF_Action)
|
||||
{
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER, 1);
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER, 2);
|
||||
static_assert(NAP == 3, "This code needs to be updated if NAP changes");
|
||||
if (build->IsActionFunc)
|
||||
{
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER, 1);
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
int null = build->GetConstantAddress(nullptr, ATAG_GENERIC);
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, null);
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, null);
|
||||
}
|
||||
count += 2;
|
||||
}
|
||||
// Emit code to pass explicit parameters
|
||||
|
@ -4967,7 +4978,8 @@ static int DecoHandleRuntimeState(VMFrameStack *stack, VMValue *param, int numpa
|
|||
|
||||
ExpEmit FxRuntimeStateIndex::Emit(VMFunctionBuilder *build)
|
||||
{
|
||||
assert(build->Registers[REGT_POINTER].GetMostUsed() >= 3);
|
||||
assert(build->IsActionFunc && build->Registers[REGT_POINTER].GetMostUsed() >= 3 &&
|
||||
"FxRuntimeStateIndex is only valid inside action functions");
|
||||
|
||||
ExpEmit out(build, REGT_POINTER);
|
||||
|
||||
|
@ -5139,7 +5151,14 @@ int DecoFindSingleNameState(VMFrameStack *stack, VMValue *param, int numparam, V
|
|||
ExpEmit FxMultiNameState::Emit(VMFunctionBuilder *build)
|
||||
{
|
||||
ExpEmit dest(build, REGT_POINTER);
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER, 1); // pass stateowner
|
||||
if (build->IsActionFunc)
|
||||
{
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER, 1); // pass stateowner
|
||||
}
|
||||
else
|
||||
{
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER, 0); // pass self
|
||||
}
|
||||
for (unsigned i = 0; i < names.Size(); ++i)
|
||||
{
|
||||
build->EmitParamInt(names[i]);
|
||||
|
|
|
@ -1100,9 +1100,10 @@ DEFINE_PROPERTY(translation, L, Actor)
|
|||
for(int i = 1; i < PROP_PARM_COUNT; i++)
|
||||
{
|
||||
PROP_STRING_PARM(str, i);
|
||||
if (i== 1 && PROP_PARM_COUNT == 2 && !stricmp(str, "Ice"))
|
||||
int tnum;
|
||||
if (i== 1 && PROP_PARM_COUNT == 2 && (tnum = R_FindCustomTranslation(str)) != -1)
|
||||
{
|
||||
defaults->Translation = TRANSLATION(TRANSLATION_Standard, 7);
|
||||
defaults->Translation = tnum;
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
@ -1110,7 +1111,7 @@ DEFINE_PROPERTY(translation, L, Actor)
|
|||
CurrentTranslation.AddToTranslation(str);
|
||||
}
|
||||
}
|
||||
defaults->Translation = CurrentTranslation.StoreTranslation ();
|
||||
defaults->Translation = CurrentTranslation.StoreTranslation (TRANSLATION_Decorate);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1437,7 +1438,7 @@ DEFINE_PROPERTY(spriterotation, F, Actor)
|
|||
DEFINE_PROPERTY(visibleangles, Ff, Actor)
|
||||
{
|
||||
PROP_DOUBLE_PARM(visstart, 0);
|
||||
PROP_DOUBLE_PARM(visend, 0);
|
||||
PROP_DOUBLE_PARM(visend, 1);
|
||||
defaults->VisibleStartAngle = visstart;
|
||||
defaults->VisibleEndAngle = visend;
|
||||
}
|
||||
|
@ -1448,7 +1449,7 @@ DEFINE_PROPERTY(visibleangles, Ff, Actor)
|
|||
DEFINE_PROPERTY(visiblepitch, Ff, Actor)
|
||||
{
|
||||
PROP_DOUBLE_PARM(visstart, 0);
|
||||
PROP_DOUBLE_PARM(visend, 0);
|
||||
PROP_DOUBLE_PARM(visend, 1);
|
||||
defaults->VisibleStartPitch = visstart;
|
||||
defaults->VisibleEndPitch = visend;
|
||||
}
|
||||
|
|
|
@ -556,17 +556,29 @@ struct TVector3
|
|||
// Resizes this vector to be the specified length (if it is not 0)
|
||||
TVector3 &MakeResize(double len)
|
||||
{
|
||||
double scale = len / Length();
|
||||
X = vec_t(X * scale);
|
||||
Y = vec_t(Y * scale);
|
||||
Z = vec_t(Z * scale);
|
||||
double vlen = Length();
|
||||
if (vlen != 0.)
|
||||
{
|
||||
double scale = len / vlen;
|
||||
X = vec_t(X * scale);
|
||||
Y = vec_t(Y * scale);
|
||||
Z = vec_t(Z * scale);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
TVector3 Resized(double len)
|
||||
{
|
||||
double scale = len / Length();
|
||||
return{ vec_t(X * scale), vec_t(Y * scale), vec_t(Z * scale) };
|
||||
double vlen = Length();
|
||||
if (vlen != 0.)
|
||||
{
|
||||
double scale = len / vlen;
|
||||
return{ vec_t(X * scale), vec_t(Y * scale), vec_t(Z * scale) };
|
||||
}
|
||||
else
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
// Dot product
|
||||
|
|
|
@ -27,6 +27,12 @@
|
|||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
// This macro is defined by newer versions of xinput.h. In case we are
|
||||
// compiling with an older version, define it here.
|
||||
#ifndef XUSER_MAX_COUNT
|
||||
#define XUSER_MAX_COUNT 4
|
||||
#endif
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
typedef DWORD (WINAPI *XInputGetStateType)(DWORD index, XINPUT_STATE *state);
|
||||
|
|
|
@ -37,7 +37,9 @@ extern int NewWidth, NewHeight, NewBits, DisplayBits;
|
|||
// these get used before GLEW is initialized so we have to use separate pointers with different names
|
||||
PFNWGLCHOOSEPIXELFORMATARBPROC myWglChoosePixelFormatARB; // = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
|
||||
PFNWGLCREATECONTEXTATTRIBSARBPROC myWglCreateContextAttribsARB;
|
||||
PFNWGLSWAPINTERVALEXTPROC vsyncfunc;
|
||||
PFNWGLSWAPINTERVALEXTPROC myWglSwapIntervalExtProc;
|
||||
|
||||
|
||||
|
||||
|
||||
CUSTOM_CVAR(Bool, gl_debug, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
||||
|
@ -933,10 +935,32 @@ Win32GLFrameBuffer::Win32GLFrameBuffer(void *hMonitor, int width, int height, in
|
|||
vid_renderer = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
vsyncfunc = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
|
||||
|
||||
HDC hDC = GetDC(Window);
|
||||
const char *wglext = nullptr;
|
||||
|
||||
myWglSwapIntervalExtProc = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
|
||||
auto myWglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
|
||||
if (myWglGetExtensionsStringARB)
|
||||
{
|
||||
wglext = myWglGetExtensionsStringARB(hDC);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto myWglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)wglGetProcAddress("wglGetExtensionsStringEXT");
|
||||
if (myWglGetExtensionsStringEXT)
|
||||
{
|
||||
wglext = myWglGetExtensionsStringEXT();
|
||||
}
|
||||
}
|
||||
SwapInterval = 1;
|
||||
if (wglext != nullptr)
|
||||
{
|
||||
if (strstr(wglext, "WGL_EXT_swap_control_tear"))
|
||||
{
|
||||
SwapInterval = -1;
|
||||
}
|
||||
}
|
||||
|
||||
m_supportsGamma = !!GetDeviceGammaRamp(hDC, (void *)m_origGamma);
|
||||
ReleaseDC(Window, hDC);
|
||||
}
|
||||
|
@ -1091,7 +1115,7 @@ void Win32GLFrameBuffer::ReleaseResources ()
|
|||
|
||||
void Win32GLFrameBuffer::SetVSync (bool vsync)
|
||||
{
|
||||
if (vsyncfunc != NULL) vsyncfunc(vsync ? 1 : 0);
|
||||
if (myWglSwapIntervalExtProc != NULL) myWglSwapIntervalExtProc(vsync ? SwapInterval : 0);
|
||||
}
|
||||
|
||||
void Win32GLFrameBuffer::SwapBuffers()
|
||||
|
|
|
@ -148,6 +148,7 @@ protected:
|
|||
int m_Lock;
|
||||
char m_displayDeviceNameBuffer[CCHDEVICENAME];
|
||||
char *m_displayDeviceName;
|
||||
int SwapInterval;
|
||||
|
||||
friend class Win32GLVideo;
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
VMFunctionBuilder::VMFunctionBuilder()
|
||||
VMFunctionBuilder::VMFunctionBuilder(bool selfcheck)
|
||||
{
|
||||
NumIntConstants = 0;
|
||||
NumFloatConstants = 0;
|
||||
|
@ -14,6 +14,7 @@ VMFunctionBuilder::VMFunctionBuilder()
|
|||
NumStringConstants = 0;
|
||||
MaxParam = 0;
|
||||
ActiveParam = 0;
|
||||
IsActionFunc = selfcheck;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -23,7 +23,7 @@ public:
|
|||
friend class VMFunctionBuilder;
|
||||
};
|
||||
|
||||
VMFunctionBuilder();
|
||||
VMFunctionBuilder(bool checkself = false);
|
||||
~VMFunctionBuilder();
|
||||
|
||||
VMScriptFunction *MakeFunction();
|
||||
|
@ -60,6 +60,9 @@ public:
|
|||
// Track available registers.
|
||||
RegAvailability Registers[4];
|
||||
|
||||
// For use by DECORATE's self/stateowner sanitizer.
|
||||
bool IsActionFunc;
|
||||
|
||||
private:
|
||||
struct AddrKonst
|
||||
{
|
||||
|
|
|
@ -57,6 +57,7 @@ ACTOR Actor native //: Thinker
|
|||
native float GetSpriteAngle(int ptr = AAPTR_DEFAULT);
|
||||
native float GetSpriteRotation(int ptr = AAPTR_DEFAULT);
|
||||
native int GetMissileDamage(int mask, int add, int ptr = AAPTR_DEFAULT);
|
||||
action native int OverlayID();
|
||||
|
||||
// Action functions
|
||||
// Meh, MBF redundant functions. Only for DeHackEd support.
|
||||
|
@ -218,6 +219,7 @@ ACTOR Actor native //: Thinker
|
|||
native void A_LogInt(int whattoprint);
|
||||
native void A_LogFloat(float whattoprint);
|
||||
native void A_SetTranslucent(float alpha, int style = 0);
|
||||
native void A_SetRenderStyle(float alpha, int style);
|
||||
action native A_FadeIn(float reduce = 0.1, int flags = 0);
|
||||
action native A_FadeOut(float reduce = 0.1, int flags = 1); //bool remove == true
|
||||
native void A_FadeTo(float target, float amount = 0.1, int flags = 0);
|
||||
|
@ -343,6 +345,7 @@ ACTOR Actor native //: Thinker
|
|||
action native bool A_SetSpriteAngle(float angle = 0, int ptr = AAPTR_DEFAULT);
|
||||
action native bool A_SetSpriteRotation(float angle = 0, int ptr = AAPTR_DEFAULT);
|
||||
action native bool A_SetVisibleRotation(float anglestart = 0, float angleend = 0, float pitchstart = 0, float pitchend = 0, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||
native void A_SetTranslation(string transname);
|
||||
|
||||
native void A_RearrangePointers(int newtarget, int newmaster = AAPTR_DEFAULT, int newtracer = AAPTR_DEFAULT, int flags=0);
|
||||
native void A_TransferPointer(int ptr_source, int ptr_recepient, int sourcefield, int recepientfield=AAPTR_DEFAULT, int flags=0);
|
||||
|
|
|
@ -689,4 +689,22 @@ enum
|
|||
|
||||
VRF_NOANGLE = VRF_NOANGLESTART|VRF_NOANGLEEND,
|
||||
VRF_NOPITCH = VRF_NOPITCHSTART|VRF_NOPITCHEND,
|
||||
};
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
STYLE_None,
|
||||
STYLE_Normal,
|
||||
STYLE_Fuzzy,
|
||||
STYLE_SoulTrans,
|
||||
STYLE_OptFuzzy,
|
||||
STYLE_Stencil,
|
||||
STYLE_Translucent,
|
||||
STYLE_Add,
|
||||
STYLE_Shaded,
|
||||
STYLE_TranslucentStencil,
|
||||
STYLE_Shadow,
|
||||
STYLE_Subtract,
|
||||
STYLE_AddStencil,
|
||||
STYLE_AddShaded,
|
||||
};
|
||||
|
|
|
@ -151,6 +151,7 @@ $alias switches/exitbutn switches/normbutn // Heretic has no special exit button
|
|||
plats/pt1_strt pstart
|
||||
plats/pt1_stop pstop
|
||||
plats/pt1_mid dormov
|
||||
plats/pt2_mid stnmov
|
||||
|
||||
//
|
||||
// Door Sounds
|
||||
|
|
5
wadsrc/static/filter/game-heretic/sndseq.txt
Normal file
5
wadsrc/static/filter/game-heretic/sndseq.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
:Platform
|
||||
playuntildone plats/pt1_strt
|
||||
playrepeat plats/pt2_mid
|
||||
stopsound plats/pt1_stop
|
||||
end
|
|
@ -2638,6 +2638,7 @@ GLPREFMNU_BLOOM = "Bloom effect";
|
|||
GLPREFMNU_LENS = "Lens distortion effect";
|
||||
GLPREFMNU_SSAO = "Ambient occlusion quality";
|
||||
GLPREFMNU_SSAO_PORTALS = "Portals with AO";
|
||||
GLPREFMNU_FXAA = "FXAA Quality";
|
||||
|
||||
// Option Values
|
||||
OPTVAL_SMART = "Smart";
|
||||
|
@ -2708,8 +2709,14 @@ OPTVAL_LEFTEYE = "Left Eye";
|
|||
OPTVAL_RIGHTEYE = "Right Eye";
|
||||
OPTVAL_SBSFULL = "Side-by-side Full";
|
||||
OPTVAL_SBSNARROW = "Side-by-side Narrow";
|
||||
OPTVAL_TOPBOTTOM = "Top/Bottom";
|
||||
OPTVAL_ROWINTERLEAVED = "Row Interleaved";
|
||||
OPTVAL_QUADBUFFERED = "Quad-buffered";
|
||||
OPTVAL_UNCHARTED2 = "Uncharted 2";
|
||||
OPTVAL_HEJLDAWSON = "Hejl Dawson";
|
||||
OPTVAL_REINHARD = "Reinhard";
|
||||
OPTVAL_PALETTE = "Palette";
|
||||
OPTVAL_PALETTE = "Palette";
|
||||
OPTVAL_LOW = "Low";
|
||||
OPTVAL_MEDIUM = "Medium";
|
||||
OPTVAL_HIGH = "High";
|
||||
OPTVAL_EXTREME = "Extreme";
|
||||
|
|
|
@ -50,6 +50,15 @@ OptionValue "SSAOModes"
|
|||
3, "$OPTVAL_HIGH"
|
||||
}
|
||||
|
||||
OptionValue "FXAAQuality"
|
||||
{
|
||||
0, "$OPTVAL_OFF"
|
||||
1, "$OPTVAL_LOW"
|
||||
2, "$OPTVAL_MEDIUM"
|
||||
3, "$OPTVAL_HIGH"
|
||||
4, "$OPTVAL_EXTREME"
|
||||
}
|
||||
|
||||
OptionValue "TextureFormats"
|
||||
{
|
||||
0, "$OPTVAL_RGBA8"
|
||||
|
@ -177,6 +186,8 @@ OptionValue VRMode
|
|||
9, "$OPTVAL_AMBERBLUE"
|
||||
3, "$OPTVAL_SBSFULL"
|
||||
4, "$OPTVAL_SBSNARROW"
|
||||
11, "$OPTVAL_TOPBOTTOM"
|
||||
12, "$OPTVAL_ROWINTERLEAVED"
|
||||
5, "$OPTVAL_LEFTEYE"
|
||||
6, "$OPTVAL_RIGHTEYE"
|
||||
7, "$OPTVAL_QUADBUFFERED"
|
||||
|
@ -236,4 +247,5 @@ OptionMenu "GLPrefOptions"
|
|||
Option "$GLPREFMNU_LENS", gl_lens, "OnOff"
|
||||
Option "$GLPREFMNU_SSAO", gl_ssao, "SSAOModes"
|
||||
Slider "$GLPREFMNU_SSAO_PORTALS", gl_ssao_portals, 0.0, 4.0, 1.0, 0
|
||||
Option "$GLPREFMNU_FXAA", gl_fxaa, "FXAAQuality"
|
||||
}
|
||||
|
|
615
wadsrc/static/shaders/glsl/fxaa.fp
Normal file
615
wadsrc/static/shaders/glsl/fxaa.fp
Normal file
|
@ -0,0 +1,615 @@
|
|||
//----------------------------------------------------------------------------------
|
||||
// File: es3-kepler\FXAA/FXAA3_11.h
|
||||
// SDK Version: v3.00
|
||||
// Email: gameworks@nvidia.com
|
||||
// Site: http://developer.nvidia.com/
|
||||
//
|
||||
// Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
in vec2 TexCoord;
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform sampler2D InputTexture;
|
||||
|
||||
#ifdef FXAA_LUMA_PASS
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 tex = texture(InputTexture, TexCoord).rgb;
|
||||
vec3 luma = vec3(0.299, 0.587, 0.114);
|
||||
FragColor = vec4(tex, dot(tex, luma));
|
||||
}
|
||||
|
||||
#else // FXAA itself
|
||||
|
||||
//============================================================================
|
||||
// NVIDIA FXAA 3.11 by TIMOTHY LOTTES
|
||||
//============================================================================
|
||||
|
||||
#define FXAA_DISCARD 1
|
||||
|
||||
#define FXAA_GREEN_AS_LUMA 0
|
||||
|
||||
#define FxaaBool bool
|
||||
#define FxaaDiscard discard
|
||||
#define FxaaFloat float
|
||||
#define FxaaFloat2 vec2
|
||||
#define FxaaFloat3 vec3
|
||||
#define FxaaFloat4 vec4
|
||||
#define FxaaHalf float
|
||||
#define FxaaHalf2 vec2
|
||||
#define FxaaHalf3 vec3
|
||||
#define FxaaHalf4 vec4
|
||||
#define FxaaInt2 ivec2
|
||||
#define FxaaSat(x) clamp(x, 0.0, 1.0)
|
||||
#define FxaaTex sampler2D
|
||||
|
||||
#define FxaaTexTop(t, p) textureLod(t, p, 0.0)
|
||||
#define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o)
|
||||
|
||||
#if (FXAA_GATHER4_ALPHA == 1)
|
||||
#define FxaaTexAlpha4(t, p) textureGather(t, p, 3)
|
||||
#define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)
|
||||
#define FxaaTexGreen4(t, p) textureGather(t, p, 1)
|
||||
#define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)
|
||||
#endif
|
||||
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.w; }
|
||||
#else
|
||||
FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; }
|
||||
#endif
|
||||
|
||||
#if (FXAA_QUALITY__PRESET == 10)
|
||||
#define FXAA_QUALITY__PS 3
|
||||
#define FXAA_QUALITY__P0 1.5
|
||||
#define FXAA_QUALITY__P1 3.0
|
||||
#define FXAA_QUALITY__P2 12.0
|
||||
#elif (FXAA_QUALITY__PRESET == 11)
|
||||
#define FXAA_QUALITY__PS 4
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 3.0
|
||||
#define FXAA_QUALITY__P3 12.0
|
||||
#elif (FXAA_QUALITY__PRESET == 12)
|
||||
#define FXAA_QUALITY__PS 5
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 4.0
|
||||
#define FXAA_QUALITY__P4 12.0
|
||||
#elif (FXAA_QUALITY__PRESET == 13)
|
||||
#define FXAA_QUALITY__PS 6
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 2.0
|
||||
#define FXAA_QUALITY__P4 4.0
|
||||
#define FXAA_QUALITY__P5 12.0
|
||||
#elif (FXAA_QUALITY__PRESET == 14)
|
||||
#define FXAA_QUALITY__PS 7
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 2.0
|
||||
#define FXAA_QUALITY__P4 2.0
|
||||
#define FXAA_QUALITY__P5 4.0
|
||||
#define FXAA_QUALITY__P6 12.0
|
||||
#elif (FXAA_QUALITY__PRESET == 15)
|
||||
#define FXAA_QUALITY__PS 8
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 2.0
|
||||
#define FXAA_QUALITY__P4 2.0
|
||||
#define FXAA_QUALITY__P5 2.0
|
||||
#define FXAA_QUALITY__P6 4.0
|
||||
#define FXAA_QUALITY__P7 12.0
|
||||
#elif (FXAA_QUALITY__PRESET == 20)
|
||||
#define FXAA_QUALITY__PS 3
|
||||
#define FXAA_QUALITY__P0 1.5
|
||||
#define FXAA_QUALITY__P1 2.0
|
||||
#define FXAA_QUALITY__P2 8.0
|
||||
#elif (FXAA_QUALITY__PRESET == 21)
|
||||
#define FXAA_QUALITY__PS 4
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 8.0
|
||||
#elif (FXAA_QUALITY__PRESET == 22)
|
||||
#define FXAA_QUALITY__PS 5
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 2.0
|
||||
#define FXAA_QUALITY__P4 8.0
|
||||
#elif (FXAA_QUALITY__PRESET == 23)
|
||||
#define FXAA_QUALITY__PS 6
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 2.0
|
||||
#define FXAA_QUALITY__P4 2.0
|
||||
#define FXAA_QUALITY__P5 8.0
|
||||
#elif (FXAA_QUALITY__PRESET == 24)
|
||||
#define FXAA_QUALITY__PS 7
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 2.0
|
||||
#define FXAA_QUALITY__P4 2.0
|
||||
#define FXAA_QUALITY__P5 3.0
|
||||
#define FXAA_QUALITY__P6 8.0
|
||||
#elif (FXAA_QUALITY__PRESET == 25)
|
||||
#define FXAA_QUALITY__PS 8
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 2.0
|
||||
#define FXAA_QUALITY__P4 2.0
|
||||
#define FXAA_QUALITY__P5 2.0
|
||||
#define FXAA_QUALITY__P6 4.0
|
||||
#define FXAA_QUALITY__P7 8.0
|
||||
#elif (FXAA_QUALITY__PRESET == 26)
|
||||
#define FXAA_QUALITY__PS 9
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 2.0
|
||||
#define FXAA_QUALITY__P4 2.0
|
||||
#define FXAA_QUALITY__P5 2.0
|
||||
#define FXAA_QUALITY__P6 2.0
|
||||
#define FXAA_QUALITY__P7 4.0
|
||||
#define FXAA_QUALITY__P8 8.0
|
||||
#elif (FXAA_QUALITY__PRESET == 27)
|
||||
#define FXAA_QUALITY__PS 10
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 2.0
|
||||
#define FXAA_QUALITY__P4 2.0
|
||||
#define FXAA_QUALITY__P5 2.0
|
||||
#define FXAA_QUALITY__P6 2.0
|
||||
#define FXAA_QUALITY__P7 2.0
|
||||
#define FXAA_QUALITY__P8 4.0
|
||||
#define FXAA_QUALITY__P9 8.0
|
||||
#elif (FXAA_QUALITY__PRESET == 28)
|
||||
#define FXAA_QUALITY__PS 11
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 2.0
|
||||
#define FXAA_QUALITY__P4 2.0
|
||||
#define FXAA_QUALITY__P5 2.0
|
||||
#define FXAA_QUALITY__P6 2.0
|
||||
#define FXAA_QUALITY__P7 2.0
|
||||
#define FXAA_QUALITY__P8 2.0
|
||||
#define FXAA_QUALITY__P9 4.0
|
||||
#define FXAA_QUALITY__P10 8.0
|
||||
#elif (FXAA_QUALITY__PRESET == 29)
|
||||
#define FXAA_QUALITY__PS 12
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.5
|
||||
#define FXAA_QUALITY__P2 2.0
|
||||
#define FXAA_QUALITY__P3 2.0
|
||||
#define FXAA_QUALITY__P4 2.0
|
||||
#define FXAA_QUALITY__P5 2.0
|
||||
#define FXAA_QUALITY__P6 2.0
|
||||
#define FXAA_QUALITY__P7 2.0
|
||||
#define FXAA_QUALITY__P8 2.0
|
||||
#define FXAA_QUALITY__P9 2.0
|
||||
#define FXAA_QUALITY__P10 4.0
|
||||
#define FXAA_QUALITY__P11 8.0
|
||||
#elif (FXAA_QUALITY__PRESET == 39)
|
||||
#define FXAA_QUALITY__PS 12
|
||||
#define FXAA_QUALITY__P0 1.0
|
||||
#define FXAA_QUALITY__P1 1.0
|
||||
#define FXAA_QUALITY__P2 1.0
|
||||
#define FXAA_QUALITY__P3 1.0
|
||||
#define FXAA_QUALITY__P4 1.0
|
||||
#define FXAA_QUALITY__P5 1.5
|
||||
#define FXAA_QUALITY__P6 2.0
|
||||
#define FXAA_QUALITY__P7 2.0
|
||||
#define FXAA_QUALITY__P8 2.0
|
||||
#define FXAA_QUALITY__P9 2.0
|
||||
#define FXAA_QUALITY__P10 4.0
|
||||
#define FXAA_QUALITY__P11 8.0
|
||||
#endif
|
||||
|
||||
FxaaFloat4 FxaaPixelShader(FxaaFloat2 pos, FxaaTex tex, FxaaFloat2 fxaaQualityRcpFrame,
|
||||
FxaaFloat fxaaQualitySubpix, FxaaFloat fxaaQualityEdgeThreshold, FxaaFloat fxaaQualityEdgeThresholdMin)
|
||||
{
|
||||
FxaaFloat2 posM;
|
||||
posM.x = pos.x;
|
||||
posM.y = pos.y;
|
||||
#if (FXAA_GATHER4_ALPHA == 1)
|
||||
#if (FXAA_DISCARD == 0)
|
||||
FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
#define lumaM rgbyM.w
|
||||
#else
|
||||
#define lumaM rgbyM.y
|
||||
#endif
|
||||
#endif
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
FxaaFloat4 luma4A = FxaaTexAlpha4(tex, posM);
|
||||
FxaaFloat4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1));
|
||||
#else
|
||||
FxaaFloat4 luma4A = FxaaTexGreen4(tex, posM);
|
||||
FxaaFloat4 luma4B = FxaaTexOffGreen4(tex, posM, FxaaInt2(-1, -1));
|
||||
#endif
|
||||
#if (FXAA_DISCARD == 1)
|
||||
#define lumaM luma4A.w
|
||||
#endif
|
||||
#define lumaE luma4A.z
|
||||
#define lumaS luma4A.x
|
||||
#define lumaSE luma4A.y
|
||||
#define lumaNW luma4B.w
|
||||
#define lumaN luma4B.z
|
||||
#define lumaW luma4B.x
|
||||
#else
|
||||
FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);
|
||||
#if (FXAA_GREEN_AS_LUMA == 0)
|
||||
#define lumaM rgbyM.w
|
||||
#else
|
||||
#define lumaM rgbyM.y
|
||||
#endif
|
||||
FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0, 1), fxaaQualityRcpFrame.xy));
|
||||
FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 0), fxaaQualityRcpFrame.xy));
|
||||
FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0,-1), fxaaQualityRcpFrame.xy));
|
||||
FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy));
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat maxSM = max(lumaS, lumaM);
|
||||
FxaaFloat minSM = min(lumaS, lumaM);
|
||||
FxaaFloat maxESM = max(lumaE, maxSM);
|
||||
FxaaFloat minESM = min(lumaE, minSM);
|
||||
FxaaFloat maxWN = max(lumaN, lumaW);
|
||||
FxaaFloat minWN = min(lumaN, lumaW);
|
||||
FxaaFloat rangeMax = max(maxWN, maxESM);
|
||||
FxaaFloat rangeMin = min(minWN, minESM);
|
||||
FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold;
|
||||
FxaaFloat range = rangeMax - rangeMin;
|
||||
FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled);
|
||||
FxaaBool earlyExit = range < rangeMaxClamped;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
if(earlyExit)
|
||||
#if (FXAA_DISCARD == 1)
|
||||
FxaaDiscard;
|
||||
#else
|
||||
return rgbyM;
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_GATHER4_ALPHA == 0)
|
||||
FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1,-1), fxaaQualityRcpFrame.xy));
|
||||
FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 1), fxaaQualityRcpFrame.xy));
|
||||
FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1,-1), fxaaQualityRcpFrame.xy));
|
||||
FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));
|
||||
#else
|
||||
FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy));
|
||||
FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat lumaNS = lumaN + lumaS;
|
||||
FxaaFloat lumaWE = lumaW + lumaE;
|
||||
FxaaFloat subpixRcpRange = 1.0/range;
|
||||
FxaaFloat subpixNSWE = lumaNS + lumaWE;
|
||||
FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS;
|
||||
FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat lumaNESE = lumaNE + lumaSE;
|
||||
FxaaFloat lumaNWNE = lumaNW + lumaNE;
|
||||
FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE;
|
||||
FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat lumaNWSW = lumaNW + lumaSW;
|
||||
FxaaFloat lumaSWSE = lumaSW + lumaSE;
|
||||
FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2);
|
||||
FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2);
|
||||
FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW;
|
||||
FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE;
|
||||
FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4;
|
||||
FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE;
|
||||
FxaaFloat lengthSign = fxaaQualityRcpFrame.x;
|
||||
FxaaBool horzSpan = edgeHorz >= edgeVert;
|
||||
FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
if(!horzSpan) lumaN = lumaW;
|
||||
if(!horzSpan) lumaS = lumaE;
|
||||
if(horzSpan) lengthSign = fxaaQualityRcpFrame.y;
|
||||
FxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat gradientN = lumaN - lumaM;
|
||||
FxaaFloat gradientS = lumaS - lumaM;
|
||||
FxaaFloat lumaNN = lumaN + lumaM;
|
||||
FxaaFloat lumaSS = lumaS + lumaM;
|
||||
FxaaBool pairN = abs(gradientN) >= abs(gradientS);
|
||||
FxaaFloat gradient = max(abs(gradientN), abs(gradientS));
|
||||
if(pairN) lengthSign = -lengthSign;
|
||||
FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat2 posB;
|
||||
posB.x = posM.x;
|
||||
posB.y = posM.y;
|
||||
FxaaFloat2 offNP;
|
||||
offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x;
|
||||
offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y;
|
||||
if(!horzSpan) posB.x += lengthSign * 0.5;
|
||||
if( horzSpan) posB.y += lengthSign * 0.5;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat2 posN;
|
||||
posN.x = posB.x - offNP.x * FXAA_QUALITY__P0;
|
||||
posN.y = posB.y - offNP.y * FXAA_QUALITY__P0;
|
||||
FxaaFloat2 posP;
|
||||
posP.x = posB.x + offNP.x * FXAA_QUALITY__P0;
|
||||
posP.y = posB.y + offNP.y * FXAA_QUALITY__P0;
|
||||
FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0;
|
||||
FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN));
|
||||
FxaaFloat subpixE = subpixC * subpixC;
|
||||
FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP));
|
||||
/*--------------------------------------------------------------------------*/
|
||||
if(!pairN) lumaNN = lumaSS;
|
||||
FxaaFloat gradientScaled = gradient * 1.0/4.0;
|
||||
FxaaFloat lumaMM = lumaM - lumaNN * 0.5;
|
||||
FxaaFloat subpixF = subpixD * subpixE;
|
||||
FxaaBool lumaMLTZero = lumaMM < 0.0;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
lumaEndN -= lumaNN * 0.5;
|
||||
lumaEndP -= lumaNN * 0.5;
|
||||
FxaaBool doneN = abs(lumaEndN) >= gradientScaled;
|
||||
FxaaBool doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P1;
|
||||
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P1;
|
||||
FxaaBool doneNP = (!doneN) || (!doneP);
|
||||
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P1;
|
||||
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P1;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
if(doneNP) {
|
||||
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P2;
|
||||
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P2;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P2;
|
||||
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P2;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PS > 3)
|
||||
if(doneNP) {
|
||||
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P3;
|
||||
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P3;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P3;
|
||||
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P3;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PS > 4)
|
||||
if(doneNP) {
|
||||
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P4;
|
||||
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P4;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P4;
|
||||
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P4;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PS > 5)
|
||||
if(doneNP) {
|
||||
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P5;
|
||||
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P5;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P5;
|
||||
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P5;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PS > 6)
|
||||
if(doneNP) {
|
||||
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P6;
|
||||
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P6;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P6;
|
||||
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P6;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PS > 7)
|
||||
if(doneNP) {
|
||||
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P7;
|
||||
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P7;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P7;
|
||||
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P7;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PS > 8)
|
||||
if(doneNP) {
|
||||
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P8;
|
||||
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P8;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P8;
|
||||
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P8;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PS > 9)
|
||||
if(doneNP) {
|
||||
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P9;
|
||||
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P9;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P9;
|
||||
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P9;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PS > 10)
|
||||
if(doneNP) {
|
||||
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P10;
|
||||
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P10;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P10;
|
||||
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P10;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PS > 11)
|
||||
if(doneNP) {
|
||||
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P11;
|
||||
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P11;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P11;
|
||||
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P11;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#if (FXAA_QUALITY__PS > 12)
|
||||
if(doneNP) {
|
||||
if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
|
||||
if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
|
||||
if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
|
||||
if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
|
||||
doneN = abs(lumaEndN) >= gradientScaled;
|
||||
doneP = abs(lumaEndP) >= gradientScaled;
|
||||
if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P12;
|
||||
if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P12;
|
||||
doneNP = (!doneN) || (!doneP);
|
||||
if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P12;
|
||||
if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P12;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
#endif
|
||||
/*--------------------------------------------------------------------------*/
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat dstN = posM.x - posN.x;
|
||||
FxaaFloat dstP = posP.x - posM.x;
|
||||
if(!horzSpan) dstN = posM.y - posN.y;
|
||||
if(!horzSpan) dstP = posP.y - posM.y;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero;
|
||||
FxaaFloat spanLength = (dstP + dstN);
|
||||
FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero;
|
||||
FxaaFloat spanLengthRcp = 1.0/spanLength;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaBool directionN = dstN < dstP;
|
||||
FxaaFloat dst = min(dstN, dstP);
|
||||
FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP;
|
||||
FxaaFloat subpixG = subpixF * subpixF;
|
||||
FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5;
|
||||
FxaaFloat subpixH = subpixG * fxaaQualitySubpix;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0;
|
||||
FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH);
|
||||
if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign;
|
||||
if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign;
|
||||
#if (FXAA_DISCARD == 1)
|
||||
return FxaaTexTop(tex, posM);
|
||||
#else
|
||||
return FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM);
|
||||
#endif
|
||||
}
|
||||
|
||||
uniform vec2 ReciprocalResolution;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = FxaaPixelShader(TexCoord, InputTexture, ReciprocalResolution, 0.75f, 0.166f, 0.0833f);
|
||||
}
|
||||
|
||||
#endif // FXAA_LUMA_PASS
|
|
@ -1,6 +1,8 @@
|
|||
in vec4 pixelpos;
|
||||
in vec2 glowdist;
|
||||
|
||||
in vec4 vWorldNormal;
|
||||
in vec4 vEyeNormal;
|
||||
in vec4 vTexCoord;
|
||||
in vec4 vColor;
|
||||
|
||||
|
@ -124,6 +126,37 @@ float R_DoomLightingEquation(float light)
|
|||
return lightscale;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Standard lambertian diffuse light calculation
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
float diffuseContribution(vec3 lightDirection, vec3 normal)
|
||||
{
|
||||
return max(dot(normal, lightDirection), 0.0f);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Calculates the brightness of a dynamic point light
|
||||
// Todo: Find a better way to define which lighting model to use.
|
||||
// (Specular mode has been removed for now.)
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
float pointLightAttenuation(vec4 lightpos)
|
||||
{
|
||||
float attenuation = max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w;
|
||||
#if 0
|
||||
return attenuation;
|
||||
#else
|
||||
vec3 lightDirection = normalize(lightpos.xyz - pixelpos.xyz);
|
||||
float diffuseAmount = diffuseContribution(lightDirection, normalize(vWorldNormal.xyz));
|
||||
return attenuation * diffuseAmount;
|
||||
#endif
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Calculate light
|
||||
|
@ -199,7 +232,7 @@ vec4 getLightColor(float fogdist, float fogfactor)
|
|||
vec4 lightpos = lights[i];
|
||||
vec4 lightcolor = lights[i+1];
|
||||
|
||||
lightcolor.rgb *= max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w;
|
||||
lightcolor.rgb *= pointLightAttenuation(lightpos);
|
||||
dynlight.rgb += lightcolor.rgb;
|
||||
}
|
||||
//
|
||||
|
@ -210,7 +243,7 @@ vec4 getLightColor(float fogdist, float fogfactor)
|
|||
vec4 lightpos = lights[i];
|
||||
vec4 lightcolor = lights[i+1];
|
||||
|
||||
lightcolor.rgb *= max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w;
|
||||
lightcolor.rgb *= pointLightAttenuation(lightpos);
|
||||
dynlight.rgb -= lightcolor.rgb;
|
||||
}
|
||||
}
|
||||
|
@ -318,7 +351,7 @@ void main()
|
|||
vec4 lightpos = lights[i];
|
||||
vec4 lightcolor = lights[i+1];
|
||||
|
||||
lightcolor.rgb *= max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w;
|
||||
lightcolor.rgb *= pointLightAttenuation(lightpos);
|
||||
addlight.rgb += lightcolor.rgb;
|
||||
}
|
||||
frag.rgb = clamp(frag.rgb + desaturate(addlight).rgb, 0.0, 1.0);
|
||||
|
|
|
@ -4,8 +4,12 @@ in vec2 aTexCoord;
|
|||
in vec4 aColor;
|
||||
#ifndef SIMPLE // we do not need these for simple shaders
|
||||
in vec4 aVertex2;
|
||||
in vec4 aNormal;
|
||||
out vec4 pixelpos;
|
||||
out vec2 glowdist;
|
||||
|
||||
out vec4 vWorldNormal;
|
||||
out vec4 vEyeNormal;
|
||||
#endif
|
||||
|
||||
out vec4 vTexCoord;
|
||||
|
@ -54,6 +58,9 @@ void main()
|
|||
gl_ClipDistance[3] = -((uSplitTopPlane.w + uSplitTopPlane.x * worldcoord.x + uSplitTopPlane.y * worldcoord.z) * uSplitTopPlane.z) - worldcoord.y;
|
||||
gl_ClipDistance[4] = worldcoord.y + ((uSplitBottomPlane.w + uSplitBottomPlane.x * worldcoord.x + uSplitBottomPlane.y * worldcoord.z) * uSplitBottomPlane.z);
|
||||
}
|
||||
|
||||
vWorldNormal = NormalModelMatrix * aNormal;
|
||||
vEyeNormal = NormalViewMatrix * vWorldNormal;
|
||||
#endif
|
||||
|
||||
#ifdef SPHEREMAP
|
||||
|
|
35
wadsrc/static/shaders/glsl/present_row3d.fp
Normal file
35
wadsrc/static/shaders/glsl/present_row3d.fp
Normal file
|
@ -0,0 +1,35 @@
|
|||
|
||||
in vec2 TexCoord;
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform sampler2D LeftEyeTexture;
|
||||
uniform sampler2D RightEyeTexture;
|
||||
uniform float InvGamma;
|
||||
uniform float Contrast;
|
||||
uniform float Brightness;
|
||||
uniform int VerticalPixelOffset; // top-of-window might not be top-of-screen
|
||||
|
||||
vec4 ApplyGamma(vec4 c)
|
||||
{
|
||||
vec3 val = c.rgb * Contrast - (Contrast - 1.0) * 0.5;
|
||||
val += Brightness * 0.5;
|
||||
val = pow(max(val, vec3(0.0)), vec3(InvGamma));
|
||||
return vec4(val, c.a);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
int thisVerticalPixel = int(gl_FragCoord.y + 1.0); // Bottom row is typically the right eye, when WindowHeight is even
|
||||
bool isLeftEye = (thisVerticalPixel // because we want to alternate eye view on each row
|
||||
+ VerticalPixelOffset // because the window might not be aligned to the screen
|
||||
) % 2 == 0;
|
||||
vec4 inputColor;
|
||||
if (isLeftEye) {
|
||||
inputColor = texture(LeftEyeTexture, TexCoord);
|
||||
}
|
||||
else {
|
||||
// inputColor = vec4(0, 1, 0, 1);
|
||||
inputColor = texture(RightEyeTexture, TexCoord);
|
||||
}
|
||||
FragColor = ApplyGamma(inputColor);
|
||||
}
|
|
@ -56,5 +56,7 @@ uniform int uQuadMode;
|
|||
uniform mat4 ProjectionMatrix;
|
||||
uniform mat4 ViewMatrix;
|
||||
uniform mat4 ModelMatrix;
|
||||
uniform mat4 NormalViewMatrix;
|
||||
uniform mat4 NormalModelMatrix;
|
||||
uniform mat4 TextureMatrix;
|
||||
|
||||
|
|
Loading…
Reference in a new issue