mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-01-18 23:52:02 +00:00
Merge remote-tracking branch 'remotes/origin/qzdoom-merge'
This commit is contained in:
commit
714ada01aa
40 changed files with 1032 additions and 77 deletions
|
@ -718,6 +718,7 @@ set ( SWRENDER_SOURCES
|
|||
swrenderer/viewport/r_viewport.cpp
|
||||
swrenderer/viewport/r_walldrawer.cpp
|
||||
swrenderer/line/r_line.cpp
|
||||
swrenderer/line/r_farclip_line.cpp
|
||||
swrenderer/line/r_walldraw.cpp
|
||||
swrenderer/line/r_wallsetup.cpp
|
||||
swrenderer/line/r_fogboundary.cpp
|
||||
|
@ -1006,6 +1007,7 @@ set (PCH_SOURCES
|
|||
gl/shaders/gl_shader.cpp
|
||||
gl/shaders/gl_texshader.cpp
|
||||
gl/shaders/gl_shaderprogram.cpp
|
||||
gl/shaders/gl_postprocessshader.cpp
|
||||
gl/shaders/gl_shadowmapshader.cpp
|
||||
gl/shaders/gl_presentshader.cpp
|
||||
gl/shaders/gl_present3dRowshader.cpp
|
||||
|
|
|
@ -1765,6 +1765,8 @@ void G_DoReborn (int playernum, bool freshbot)
|
|||
}
|
||||
else
|
||||
{
|
||||
bool isUnfriendly = players[playernum].mo && !(players[playernum].mo->flags & MF_FRIENDLY);
|
||||
|
||||
// respawn at the start
|
||||
// first disassociate the corpse
|
||||
if (players[playernum].mo)
|
||||
|
@ -1774,7 +1776,7 @@ void G_DoReborn (int playernum, bool freshbot)
|
|||
}
|
||||
|
||||
// spawn at random spot if in deathmatch
|
||||
if (deathmatch)
|
||||
if (deathmatch || isUnfriendly)
|
||||
{
|
||||
G_DeathMatchSpawnPlayer (playernum);
|
||||
return;
|
||||
|
|
|
@ -380,6 +380,7 @@ void FMapInfoParser::ParseGameInfo()
|
|||
GAMEINFOKEY_BOOL(nightmarefast, "nightmarefast")
|
||||
GAMEINFOKEY_COLOR(dimcolor, "dimcolor")
|
||||
GAMEINFOKEY_FLOAT(dimamount, "dimamount")
|
||||
GAMEINFOKEY_FLOAT(bluramount, "bluramount")
|
||||
GAMEINFOKEY_INT(definventorymaxamount, "definventorymaxamount")
|
||||
GAMEINFOKEY_INT(defaultrespawntime, "defaultrespawntime")
|
||||
GAMEINFOKEY_INT(defaultrespawntime, "defaultrespawntime")
|
||||
|
|
1
src/gi.h
1
src/gi.h
|
@ -159,6 +159,7 @@ struct gameinfo_t
|
|||
FString CursorPic;
|
||||
uint32_t dimcolor;
|
||||
float dimamount;
|
||||
float bluramount;
|
||||
int definventorymaxamount;
|
||||
int defaultrespawntime;
|
||||
int defaultdropstyle;
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
#include "gl/shaders/gl_lensshader.h"
|
||||
#include "gl/shaders/gl_fxaashader.h"
|
||||
#include "gl/shaders/gl_presentshader.h"
|
||||
#include "gl/shaders/gl_postprocessshader.h"
|
||||
#include "gl/renderer/gl_2ddrawer.h"
|
||||
#include "gl/stereo3d/gl_stereo3d.h"
|
||||
|
||||
|
@ -145,10 +146,12 @@ CUSTOM_CVAR(Bool, gl_paltonemap_reverselookup, true, CVAR_ARCHIVE | CVAR_NOINITC
|
|||
GLRenderer->ClearTonemapPalette();
|
||||
}
|
||||
|
||||
CVAR(Float, gl_menu_blur, -1.0f, CVAR_ARCHIVE)
|
||||
|
||||
EXTERN_CVAR(Float, vid_brightness)
|
||||
EXTERN_CVAR(Float, vid_contrast)
|
||||
|
||||
EXTERN_CVAR(Float, vid_saturation)
|
||||
EXTERN_CVAR(Int, gl_satformula)
|
||||
|
||||
void FGLRenderer::RenderScreenQuad()
|
||||
{
|
||||
|
@ -161,11 +164,13 @@ void FGLRenderer::PostProcessScene(int fixedcm)
|
|||
{
|
||||
mBuffers->BlitSceneToTexture();
|
||||
UpdateCameraExposure();
|
||||
mCustomPostProcessShaders->Run("beforebloom");
|
||||
BloomScene(fixedcm);
|
||||
TonemapScene();
|
||||
ColormapScene(fixedcm);
|
||||
LensDistortScene();
|
||||
ApplyFXAA();
|
||||
mCustomPostProcessShaders->Run("scene");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -467,6 +472,86 @@ void FGLRenderer::BloomScene(int fixedcm)
|
|||
FGLDebug::PopGroup();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Blur the scene
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FGLRenderer::BlurScene(float gameinfobluramount)
|
||||
{
|
||||
// first, respect the CVar
|
||||
float blurAmount = gl_menu_blur;
|
||||
|
||||
// if CVar is negative, use the gameinfo entry
|
||||
if (gl_menu_blur < 0)
|
||||
blurAmount = gameinfobluramount;
|
||||
|
||||
// if blurAmount == 0 or somehow still returns negative, exit to prevent a crash, clearly we don't want this
|
||||
if ((blurAmount <= 0.0) || !FGLRenderBuffers::IsEnabled())
|
||||
return;
|
||||
|
||||
FGLDebug::PushGroup("BlurScene");
|
||||
|
||||
FGLPostProcessState savedState;
|
||||
savedState.SaveTextureBindings(2);
|
||||
|
||||
int sampleCount = 9;
|
||||
int numLevels = 3; // Must be 4 or less (since FGLRenderBuffers::NumBloomLevels is 4 and we are using its buffers).
|
||||
assert(numLevels <= FGLRenderBuffers::NumBloomLevels);
|
||||
|
||||
const auto &viewport = mScreenViewport; // The area we want to blur. Could also be mSceneViewport if only the scene area is to be blured
|
||||
|
||||
const auto &level0 = mBuffers->BloomLevels[0];
|
||||
|
||||
// Grab the area we want to bloom:
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, mBuffers->GetCurrentFB());
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, level0.VFramebuffer);
|
||||
glBlitFramebuffer(viewport.left, viewport.top, viewport.width, viewport.height, 0, 0, level0.Width, level0.Height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
|
||||
// Blur and downscale:
|
||||
for (int i = 0; i < numLevels - 1; i++)
|
||||
{
|
||||
const auto &level = mBuffers->BloomLevels[i];
|
||||
const auto &next = mBuffers->BloomLevels[i + 1];
|
||||
mBlurShader->BlurHorizontal(this, blurAmount, sampleCount, level.VTexture, level.HFramebuffer, level.Width, level.Height);
|
||||
mBlurShader->BlurVertical(this, blurAmount, sampleCount, level.HTexture, next.VFramebuffer, next.Width, next.Height);
|
||||
}
|
||||
|
||||
// Blur and upscale:
|
||||
for (int i = numLevels - 1; i > 0; i--)
|
||||
{
|
||||
const auto &level = mBuffers->BloomLevels[i];
|
||||
const auto &next = mBuffers->BloomLevels[i - 1];
|
||||
|
||||
mBlurShader->BlurHorizontal(this, blurAmount, sampleCount, level.VTexture, level.HFramebuffer, level.Width, level.Height);
|
||||
mBlurShader->BlurVertical(this, blurAmount, sampleCount, level.HTexture, level.VFramebuffer, level.Width, level.Height);
|
||||
|
||||
// Linear upscale:
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, next.VFramebuffer);
|
||||
glViewport(0, 0, next.Width, next.Height);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, level.VTexture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
mBloomCombineShader->Bind();
|
||||
mBloomCombineShader->BloomTexture.Set(0);
|
||||
RenderScreenQuad();
|
||||
}
|
||||
|
||||
mBlurShader->BlurHorizontal(this, blurAmount, sampleCount, level0.VTexture, level0.HFramebuffer, level0.Width, level0.Height);
|
||||
mBlurShader->BlurVertical(this, blurAmount, sampleCount, level0.HTexture, level0.VFramebuffer, level0.Width, level0.Height);
|
||||
|
||||
// Copy blur back to scene texture:
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, level0.VFramebuffer);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mBuffers->GetCurrentFB());
|
||||
glBlitFramebuffer(0, 0, level0.Width, level0.Height, viewport.left, viewport.top, viewport.width, viewport.height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
|
||||
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
|
||||
|
||||
FGLDebug::PopGroup();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Tonemap scene texture and place the result in the HUD/2D texture
|
||||
|
@ -734,6 +819,8 @@ void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma)
|
|||
m2DDrawer->Draw(); // draw all pending 2D stuff before copying the buffer
|
||||
m2DDrawer->Clear();
|
||||
|
||||
mCustomPostProcessShaders->Run("screen");
|
||||
|
||||
FGLDebug::PushGroup("CopyToBackbuffer");
|
||||
if (FGLRenderBuffers::IsEnabled())
|
||||
{
|
||||
|
@ -777,12 +864,15 @@ void FGLRenderer::DrawPresentTexture(const GL_IRECT &box, bool applyGamma)
|
|||
mPresentShader->InvGamma.Set(1.0f);
|
||||
mPresentShader->Contrast.Set(1.0f);
|
||||
mPresentShader->Brightness.Set(0.0f);
|
||||
mPresentShader->Saturation.Set(1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
mPresentShader->InvGamma.Set(1.0f / clamp<float>(Gamma, 0.1f, 4.f));
|
||||
mPresentShader->Contrast.Set(clamp<float>(vid_contrast, 0.1f, 3.f));
|
||||
mPresentShader->Brightness.Set(clamp<float>(vid_brightness, -0.8f, 0.8f));
|
||||
mPresentShader->Saturation.Set(clamp<float>(vid_saturation, -15.0f, 15.f));
|
||||
mPresentShader->GrayFormula.Set(static_cast<int>(gl_satformula));
|
||||
}
|
||||
mPresentShader->Scale.Set(mScreenViewport.width / (float)mBuffers->GetWidth(), mScreenViewport.height / (float)mBuffers->GetHeight());
|
||||
RenderScreenQuad();
|
||||
|
|
|
@ -43,6 +43,8 @@ public:
|
|||
void BindNextFB();
|
||||
void NextTexture();
|
||||
|
||||
int GetCurrentFB() const { return mPipelineFB[mCurrentPipelineTexture]; }
|
||||
|
||||
void BindOutputFB();
|
||||
|
||||
void BlitToEyeTexture(int eye);
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
#include "gl/shaders/gl_presentshader.h"
|
||||
#include "gl/shaders/gl_present3dRowshader.h"
|
||||
#include "gl/shaders/gl_shadowmapshader.h"
|
||||
#include "gl/shaders/gl_postprocessshader.h"
|
||||
#include "gl/stereo3d/gl_stereo3d.h"
|
||||
#include "gl/textures/gl_texture.h"
|
||||
#include "gl/textures/gl_translate.h"
|
||||
|
@ -128,6 +129,7 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb)
|
|||
mFXAAShader = nullptr;
|
||||
mFXAALumaShader = nullptr;
|
||||
mShadowMapShader = nullptr;
|
||||
mCustomPostProcessShaders = nullptr;
|
||||
}
|
||||
|
||||
void gl_LoadModels();
|
||||
|
@ -157,6 +159,7 @@ void FGLRenderer::Initialize(int width, int height)
|
|||
mPresent3dColumnShader = new FPresent3DColumnShader();
|
||||
mPresent3dRowShader = new FPresent3DRowShader();
|
||||
mShadowMapShader = new FShadowMapShader();
|
||||
mCustomPostProcessShaders = new FCustomPostProcessShaders();
|
||||
m2DDrawer = new F2DDrawer;
|
||||
|
||||
// needed for the core profile, because someone decided it was a good idea to remove the default VAO.
|
||||
|
@ -232,6 +235,7 @@ FGLRenderer::~FGLRenderer()
|
|||
if (mColormapShader) delete mColormapShader;
|
||||
if (mLensShader) delete mLensShader;
|
||||
if (mShadowMapShader) delete mShadowMapShader;
|
||||
delete mCustomPostProcessShaders;
|
||||
delete mFXAAShader;
|
||||
delete mFXAALumaShader;
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ class FPresent3DRowShader;
|
|||
class F2DDrawer;
|
||||
class FHardwareTexture;
|
||||
class FShadowMapShader;
|
||||
class FCustomPostProcessShaders;
|
||||
|
||||
inline float DEG2RAD(float deg)
|
||||
{
|
||||
|
@ -126,6 +127,7 @@ public:
|
|||
FPresent3DColumnShader *mPresent3dColumnShader;
|
||||
FPresent3DRowShader *mPresent3dRowShader;
|
||||
FShadowMapShader *mShadowMapShader;
|
||||
FCustomPostProcessShaders *mCustomPostProcessShaders;
|
||||
|
||||
FShadowMap mShadowMap;
|
||||
|
||||
|
@ -182,6 +184,7 @@ public:
|
|||
void ClearTonemapPalette();
|
||||
void LensDistortScene();
|
||||
void ApplyFXAA();
|
||||
void BlurScene(float gameinfobluramount);
|
||||
void CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma);
|
||||
void DrawPresentTexture(const GL_IRECT &box, bool applyGamma);
|
||||
void Flush();
|
||||
|
|
|
@ -98,7 +98,7 @@ void GLSceneDrawer::DrawPSprite (player_t * player,DPSprite *psp, float sx, floa
|
|||
// calculate edges of the shape
|
||||
scalex = (320.0f / (240.0f * r_viewwindow.WidescreenRatio)) * vw / 320;
|
||||
|
||||
tx = sx - (160 - r.left);
|
||||
tx = (psp->Flags & PSPF_MIRROR) ? ((160 - r.width) - (sx + r.left)) : (sx - (160 - r.left));
|
||||
x1 = tx * scalex + vw/2;
|
||||
if (x1 > vw) return; // off the right side
|
||||
x1 += viewwindowx;
|
||||
|
@ -108,7 +108,6 @@ void GLSceneDrawer::DrawPSprite (player_t * player,DPSprite *psp, float sx, floa
|
|||
if (x2 < 0) return; // off the left side
|
||||
x2 += viewwindowx;
|
||||
|
||||
|
||||
// killough 12/98: fix psprite positioning problem
|
||||
ftexturemid = 100.f - sy - r.top;
|
||||
|
||||
|
@ -130,7 +129,8 @@ void GLSceneDrawer::DrawPSprite (player_t * player,DPSprite *psp, float sx, floa
|
|||
y1 = viewwindowy + vh / 2 - (ftexturemid * scale);
|
||||
y2 = y1 + (r.height * scale) + 1;
|
||||
|
||||
if (!(mirror) != !(psp->Flags & PSPF_FLIP))
|
||||
|
||||
if (!(mirror) != !(psp->Flags & (PSPF_FLIP)))
|
||||
{
|
||||
fU2 = tex->GetSpriteUL();
|
||||
fV1 = tex->GetSpriteVT();
|
||||
|
@ -437,7 +437,7 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
|||
|
||||
if (psp->Flags & PSPF_ADDBOB)
|
||||
{
|
||||
sx += bobx;
|
||||
sx += (psp->Flags & PSPF_MIRROR) ? -bobx : bobx;
|
||||
sy += boby;
|
||||
}
|
||||
|
||||
|
|
194
src/gl/shaders/gl_postprocessshader.cpp
Normal file
194
src/gl/shaders/gl_postprocessshader.cpp
Normal file
|
@ -0,0 +1,194 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright(C) 2017 Magnus Norddahl
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see http://www.gnu.org/licenses/
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#include "gl/system/gl_system.h"
|
||||
#include "m_swap.h"
|
||||
#include "v_video.h"
|
||||
#include "gl/gl_functions.h"
|
||||
#include "vectors.h"
|
||||
#include "w_wad.h"
|
||||
#include "gl/system/gl_interface.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl/system/gl_debug.h"
|
||||
#include "gl/system/gl_cvars.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/renderer/gl_postprocessstate.h"
|
||||
#include "gl/renderer/gl_renderbuffers.h"
|
||||
#include "gl/shaders/gl_postprocessshader.h"
|
||||
|
||||
CVAR(Bool, gl_custompost, true, 0)
|
||||
|
||||
TArray<PostProcessShader> PostProcessShaders;
|
||||
|
||||
FCustomPostProcessShaders::FCustomPostProcessShaders()
|
||||
{
|
||||
for (unsigned int i = 0; i < PostProcessShaders.Size(); i++)
|
||||
{
|
||||
mShaders.push_back(std::unique_ptr<PostProcessShaderInstance>(new PostProcessShaderInstance(&PostProcessShaders[i])));
|
||||
}
|
||||
}
|
||||
|
||||
FCustomPostProcessShaders::~FCustomPostProcessShaders()
|
||||
{
|
||||
}
|
||||
|
||||
void FCustomPostProcessShaders::Run(FString target)
|
||||
{
|
||||
if (!gl_custompost)
|
||||
return;
|
||||
|
||||
for (auto &shader : mShaders)
|
||||
{
|
||||
if (shader->Desc->Target == target)
|
||||
{
|
||||
shader->Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PostProcessShaderInstance::Run()
|
||||
{
|
||||
if (!IsShaderSupported())
|
||||
return;
|
||||
|
||||
CompileShader();
|
||||
|
||||
if (!Desc->Enabled)
|
||||
return;
|
||||
|
||||
FGLDebug::PushGroup(Desc->ShaderLumpName.GetChars());
|
||||
|
||||
FGLPostProcessState savedState;
|
||||
|
||||
GLRenderer->mBuffers->BindNextFB();
|
||||
GLRenderer->mBuffers->BindCurrentTexture(0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
mProgram.Bind();
|
||||
|
||||
UpdateUniforms();
|
||||
|
||||
mInputTexture.Set(0);
|
||||
|
||||
GLRenderer->RenderScreenQuad();
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
GLRenderer->mBuffers->NextTexture();
|
||||
|
||||
FGLDebug::PopGroup();
|
||||
}
|
||||
|
||||
bool PostProcessShaderInstance::IsShaderSupported()
|
||||
{
|
||||
int activeShaderVersion = (int)round(gl.glslversion * 10) * 10;
|
||||
return activeShaderVersion >= Desc->ShaderVersion;
|
||||
}
|
||||
|
||||
void PostProcessShaderInstance::CompileShader()
|
||||
{
|
||||
if (mProgram)
|
||||
return;
|
||||
|
||||
// Get the custom shader
|
||||
const char *lumpName = Desc->ShaderLumpName.GetChars();
|
||||
int lump = Wads.CheckNumForFullName(lumpName);
|
||||
if (lump == -1) I_FatalError("Unable to load '%s'", lumpName);
|
||||
FString code = Wads.ReadLump(lump).GetString().GetChars();
|
||||
|
||||
// Build an uniform block to use be used as input
|
||||
// (this is technically not an uniform block, but it could be changed into that for Vulkan GLSL support)
|
||||
FString uniformBlock;
|
||||
TMap<FString, PostProcessUniformValue>::Iterator it(Desc->Uniforms);
|
||||
TMap<FString, PostProcessUniformValue>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
FString type;
|
||||
FString name = pair->Key;
|
||||
|
||||
switch (pair->Value.Type)
|
||||
{
|
||||
case PostProcessUniformType::Float: type = "float"; break;
|
||||
case PostProcessUniformType::Int: type = "int"; break;
|
||||
case PostProcessUniformType::Vec2: type = "vec2"; break;
|
||||
case PostProcessUniformType::Vec3: type = "vec3"; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (!type.IsEmpty())
|
||||
uniformBlock.AppendFormat("uniform %s %s;\n", type.GetChars(), name.GetChars());
|
||||
}
|
||||
|
||||
// Build the input textures
|
||||
FString uniformTextures;
|
||||
uniformTextures += "uniform sampler2D InputTexture;\n";
|
||||
|
||||
// Setup pipeline
|
||||
FString pipelineInOut;
|
||||
pipelineInOut += "in vec2 TexCoord;\n";
|
||||
pipelineInOut += "out vec4 FragColor;\n";
|
||||
|
||||
FString prolog;
|
||||
prolog += uniformBlock;
|
||||
prolog += uniformTextures;
|
||||
prolog += pipelineInOut;
|
||||
|
||||
mProgram.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", Desc->ShaderVersion);
|
||||
mProgram.Compile(FShaderProgram::Fragment, lumpName, code, prolog.GetChars(), Desc->ShaderVersion);
|
||||
mProgram.SetFragDataLocation(0, "FragColor");
|
||||
mProgram.Link(Desc->ShaderLumpName.GetChars());
|
||||
mProgram.SetAttribLocation(0, "PositionInProjection");
|
||||
mInputTexture.Init(mProgram, "InputTexture");
|
||||
}
|
||||
|
||||
void PostProcessShaderInstance::UpdateUniforms()
|
||||
{
|
||||
TMap<FString, PostProcessUniformValue>::Iterator it(Desc->Uniforms);
|
||||
TMap<FString, PostProcessUniformValue>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
int location = glGetUniformLocation(mProgram, pair->Key.GetChars());
|
||||
if (location != -1)
|
||||
{
|
||||
switch (pair->Value.Type)
|
||||
{
|
||||
case PostProcessUniformType::Float:
|
||||
glUniform1f(location, (float)pair->Value.Values[0]);
|
||||
break;
|
||||
case PostProcessUniformType::Int:
|
||||
glUniform1i(location, (int)pair->Value.Values[0]);
|
||||
break;
|
||||
case PostProcessUniformType::Vec2:
|
||||
glUniform2f(location, (float)pair->Value.Values[0], (float)pair->Value.Values[1]);
|
||||
break;
|
||||
case PostProcessUniformType::Vec3:
|
||||
glUniform3f(location, (float)pair->Value.Values[0], (float)pair->Value.Values[1], (float)pair->Value.Values[2]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
67
src/gl/shaders/gl_postprocessshader.h
Normal file
67
src/gl/shaders/gl_postprocessshader.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
#pragma once
|
||||
|
||||
#include "gl_shaderprogram.h"
|
||||
|
||||
class PostProcessShaderInstance;
|
||||
|
||||
enum class PostProcessUniformType
|
||||
{
|
||||
Undefined,
|
||||
Int,
|
||||
Float,
|
||||
Vec2,
|
||||
Vec3
|
||||
};
|
||||
|
||||
struct PostProcessUniformValue
|
||||
{
|
||||
PostProcessUniformType Type = PostProcessUniformType::Undefined;
|
||||
double Values[4] = { 0.0, 0.0, 0.0, 0.0 };
|
||||
};
|
||||
|
||||
struct PostProcessShader
|
||||
{
|
||||
FString Target;
|
||||
FString ShaderLumpName;
|
||||
int ShaderVersion = 0;
|
||||
|
||||
FString Name;
|
||||
bool Enabled = false;
|
||||
|
||||
TMap<FString, PostProcessUniformValue> Uniforms;
|
||||
};
|
||||
|
||||
extern TArray<PostProcessShader> PostProcessShaders;
|
||||
|
||||
class PostProcessShaderInstance
|
||||
{
|
||||
public:
|
||||
PostProcessShaderInstance(PostProcessShader *desc) : Desc(desc) { }
|
||||
|
||||
void Run();
|
||||
|
||||
PostProcessShader *Desc;
|
||||
|
||||
private:
|
||||
bool IsShaderSupported();
|
||||
void CompileShader();
|
||||
void UpdateUniforms();
|
||||
|
||||
FShaderProgram mProgram;
|
||||
FBufferedUniformSampler mInputTexture;
|
||||
};
|
||||
|
||||
class FCustomPostProcessShaders
|
||||
{
|
||||
public:
|
||||
FCustomPostProcessShaders();
|
||||
~FCustomPostProcessShaders();
|
||||
|
||||
void Run(FString target);
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<PostProcessShaderInstance>> mShaders;
|
||||
|
||||
FCustomPostProcessShaders(const FCustomPostProcessShaders &) = delete;
|
||||
FCustomPostProcessShaders &operator=(const FCustomPostProcessShaders &) = delete;
|
||||
};
|
|
@ -46,6 +46,8 @@ void FPresentShaderBase::Init(const char * vtx_shader_name, const char * program
|
|||
InvGamma.Init(mShader, "InvGamma");
|
||||
Contrast.Init(mShader, "Contrast");
|
||||
Brightness.Init(mShader, "Brightness");
|
||||
Saturation.Init(mShader, "Saturation");
|
||||
GrayFormula.Init(mShader, "GrayFormula");
|
||||
Scale.Init(mShader, "UVScale");
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@ public:
|
|||
FBufferedUniform1f InvGamma;
|
||||
FBufferedUniform1f Contrast;
|
||||
FBufferedUniform1f Brightness;
|
||||
FBufferedUniform1f Saturation;
|
||||
FBufferedUniform1i GrayFormula;
|
||||
FBufferedUniform2f Scale;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#include "v_palette.h"
|
||||
#include "sc_man.h"
|
||||
#include "cmdlib.h"
|
||||
#include "vm.h"
|
||||
#include "d_player.h"
|
||||
|
||||
#include "gl/system/gl_interface.h"
|
||||
#include "gl/system/gl_debug.h"
|
||||
|
@ -46,6 +48,7 @@
|
|||
#include "gl/system/gl_cvars.h"
|
||||
#include "gl/shaders/gl_shader.h"
|
||||
#include "gl/shaders/gl_shaderprogram.h"
|
||||
#include "gl/shaders/gl_postprocessshader.h"
|
||||
#include "gl/textures/gl_material.h"
|
||||
#include "gl/dynlights/gl_lightbuffer.h"
|
||||
|
||||
|
@ -672,61 +675,253 @@ void gl_DestroyUserShaders()
|
|||
|
||||
void gl_ParseHardwareShader(FScanner &sc, int deflump)
|
||||
{
|
||||
int type = FTexture::TEX_Any;
|
||||
bool disable_fullbright=false;
|
||||
bool thiswad = false;
|
||||
bool iwad = false;
|
||||
int maplump = -1;
|
||||
FString maplumpname;
|
||||
float speed = 1.f;
|
||||
|
||||
sc.MustGetString();
|
||||
if (sc.Compare("texture")) type = FTexture::TEX_Wall;
|
||||
else if (sc.Compare("flat")) type = FTexture::TEX_Flat;
|
||||
else if (sc.Compare("sprite")) type = FTexture::TEX_Sprite;
|
||||
else sc.UnGet();
|
||||
|
||||
sc.MustGetString();
|
||||
FTextureID no = TexMan.CheckForTexture(sc.String, type);
|
||||
FTexture *tex = TexMan[no];
|
||||
|
||||
sc.MustGetToken('{');
|
||||
while (!sc.CheckToken('}'))
|
||||
if (sc.Compare("postprocess"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
if (sc.Compare("shader"))
|
||||
|
||||
PostProcessShader shaderdesc;
|
||||
shaderdesc.Target = sc.String;
|
||||
|
||||
sc.MustGetToken('{');
|
||||
while (!sc.CheckToken('}'))
|
||||
{
|
||||
sc.MustGetString();
|
||||
maplumpname = sc.String;
|
||||
}
|
||||
else if (sc.Compare("speed"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
speed = float(sc.Float);
|
||||
}
|
||||
}
|
||||
if (!tex)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (maplumpname.IsNotEmpty())
|
||||
{
|
||||
if (tex->bWarped != 0)
|
||||
{
|
||||
Printf("Cannot combine warping with hardware shader on texture '%s'\n", tex->Name.GetChars());
|
||||
return;
|
||||
}
|
||||
tex->gl_info.shaderspeed = speed;
|
||||
for(unsigned i=0;i<usershaders.Size();i++)
|
||||
{
|
||||
if (!usershaders[i].CompareNoCase(maplumpname))
|
||||
if (sc.Compare("shader"))
|
||||
{
|
||||
tex->gl_info.shaderindex = i + FIRST_USER_SHADER;
|
||||
return;
|
||||
sc.MustGetString();
|
||||
shaderdesc.ShaderLumpName = sc.String;
|
||||
|
||||
sc.MustGetNumber();
|
||||
shaderdesc.ShaderVersion = sc.Number;
|
||||
}
|
||||
else if (sc.Compare("name"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
shaderdesc.Name = sc.String;
|
||||
}
|
||||
else if (sc.Compare("uniform"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
FString uniformType = sc.String;
|
||||
uniformType.ToLower();
|
||||
|
||||
sc.MustGetString();
|
||||
FString uniformName = sc.String;
|
||||
|
||||
PostProcessUniformType parsedType = PostProcessUniformType::Undefined;
|
||||
|
||||
if (uniformType.Compare("int") == 0)
|
||||
parsedType = PostProcessUniformType::Int;
|
||||
else if (uniformType.Compare("float") == 0)
|
||||
parsedType = PostProcessUniformType::Float;
|
||||
else if (uniformType.Compare("vec2") == 0)
|
||||
parsedType = PostProcessUniformType::Vec2;
|
||||
else if (uniformType.Compare("vec3") == 0)
|
||||
parsedType = PostProcessUniformType::Vec3;
|
||||
|
||||
if (parsedType != PostProcessUniformType::Undefined)
|
||||
shaderdesc.Uniforms[uniformName].Type = parsedType;
|
||||
}
|
||||
else if (sc.Compare("enabled"))
|
||||
{
|
||||
shaderdesc.Enabled = true;
|
||||
}
|
||||
}
|
||||
tex->gl_info.shaderindex = usershaders.Push(maplumpname) + FIRST_USER_SHADER;
|
||||
}
|
||||
|
||||
PostProcessShaders.Push(shaderdesc);
|
||||
}
|
||||
else
|
||||
{
|
||||
int type = FTexture::TEX_Any;
|
||||
|
||||
if (sc.Compare("texture")) type = FTexture::TEX_Wall;
|
||||
else if (sc.Compare("flat")) type = FTexture::TEX_Flat;
|
||||
else if (sc.Compare("sprite")) type = FTexture::TEX_Sprite;
|
||||
else sc.UnGet();
|
||||
|
||||
bool disable_fullbright = false;
|
||||
bool thiswad = false;
|
||||
bool iwad = false;
|
||||
int maplump = -1;
|
||||
FString maplumpname;
|
||||
float speed = 1.f;
|
||||
|
||||
sc.MustGetString();
|
||||
FTextureID no = TexMan.CheckForTexture(sc.String, type);
|
||||
FTexture *tex = TexMan[no];
|
||||
|
||||
sc.MustGetToken('{');
|
||||
while (!sc.CheckToken('}'))
|
||||
{
|
||||
sc.MustGetString();
|
||||
if (sc.Compare("shader"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
maplumpname = sc.String;
|
||||
}
|
||||
else if (sc.Compare("speed"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
speed = float(sc.Float);
|
||||
}
|
||||
}
|
||||
if (!tex)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (maplumpname.IsNotEmpty())
|
||||
{
|
||||
if (tex->bWarped != 0)
|
||||
{
|
||||
Printf("Cannot combine warping with hardware shader on texture '%s'\n", tex->Name.GetChars());
|
||||
return;
|
||||
}
|
||||
tex->gl_info.shaderspeed = speed;
|
||||
for (unsigned i = 0; i < usershaders.Size(); i++)
|
||||
{
|
||||
if (!usershaders[i].CompareNoCase(maplumpname))
|
||||
{
|
||||
tex->gl_info.shaderindex = i + FIRST_USER_SHADER;
|
||||
return;
|
||||
}
|
||||
}
|
||||
tex->gl_info.shaderindex = usershaders.Push(maplumpname) + FIRST_USER_SHADER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsConsolePlayer(player_t *player)
|
||||
{
|
||||
AActor *activator = player ? player->mo : nullptr;
|
||||
if (activator == nullptr || activator->player == nullptr)
|
||||
return false;
|
||||
return int(activator->player - players) == consoleplayer;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Shader, SetEnabled)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_POINTER_DEF(player, player_t);
|
||||
PARAM_STRING(shaderName);
|
||||
PARAM_BOOL_DEF(value);
|
||||
|
||||
if (IsConsolePlayer(player))
|
||||
{
|
||||
for (unsigned int i = 0; i < PostProcessShaders.Size(); i++)
|
||||
{
|
||||
PostProcessShader &shader = PostProcessShaders[i];
|
||||
if (shader.Name == shaderName)
|
||||
shader.Enabled = value;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Shader, SetUniform1f)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_POINTER_DEF(player, player_t);
|
||||
PARAM_STRING(shaderName);
|
||||
PARAM_STRING(uniformName);
|
||||
PARAM_FLOAT_DEF(value);
|
||||
|
||||
if (IsConsolePlayer(player))
|
||||
{
|
||||
for (unsigned int i = 0; i < PostProcessShaders.Size(); i++)
|
||||
{
|
||||
PostProcessShader &shader = PostProcessShaders[i];
|
||||
if (shader.Name == shaderName)
|
||||
{
|
||||
double *vec4 = shader.Uniforms[uniformName].Values;
|
||||
vec4[0] = value;
|
||||
vec4[1] = 0.0;
|
||||
vec4[2] = 0.0;
|
||||
vec4[3] = 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Shader, SetUniform2f)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_POINTER_DEF(player, player_t);
|
||||
PARAM_STRING(shaderName);
|
||||
PARAM_STRING(uniformName);
|
||||
PARAM_FLOAT_DEF(x);
|
||||
PARAM_FLOAT_DEF(y);
|
||||
|
||||
if (IsConsolePlayer(player))
|
||||
{
|
||||
for (unsigned int i = 0; i < PostProcessShaders.Size(); i++)
|
||||
{
|
||||
PostProcessShader &shader = PostProcessShaders[i];
|
||||
if (shader.Name == shaderName)
|
||||
{
|
||||
double *vec4 = shader.Uniforms[uniformName].Values;
|
||||
vec4[0] = x;
|
||||
vec4[1] = y;
|
||||
vec4[2] = 0.0;
|
||||
vec4[3] = 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Shader, SetUniform3f)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_POINTER_DEF(player, player_t);
|
||||
PARAM_STRING(shaderName);
|
||||
PARAM_STRING(uniformName);
|
||||
PARAM_FLOAT_DEF(x);
|
||||
PARAM_FLOAT_DEF(y);
|
||||
PARAM_FLOAT_DEF(z);
|
||||
|
||||
if (IsConsolePlayer(player))
|
||||
{
|
||||
for (unsigned int i = 0; i < PostProcessShaders.Size(); i++)
|
||||
{
|
||||
PostProcessShader &shader = PostProcessShaders[i];
|
||||
if (shader.Name == shaderName)
|
||||
{
|
||||
double *vec4 = shader.Uniforms[uniformName].Values;
|
||||
vec4[0] = x;
|
||||
vec4[1] = y;
|
||||
vec4[2] = z;
|
||||
vec4[3] = 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Shader, SetUniform1i)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_POINTER_DEF(player, player_t);
|
||||
PARAM_STRING(shaderName);
|
||||
PARAM_STRING(uniformName);
|
||||
PARAM_INT_DEF(value);
|
||||
|
||||
if (IsConsolePlayer(player))
|
||||
{
|
||||
for (unsigned int i = 0; i < PostProcessShaders.Size(); i++)
|
||||
{
|
||||
PostProcessShader &shader = PostProcessShaders[i];
|
||||
if (shader.Name == shaderName)
|
||||
{
|
||||
double *vec4 = shader.Uniforms[uniformName].Values;
|
||||
vec4[0] = (double)value;
|
||||
vec4[1] = 0.0;
|
||||
vec4[2] = 0.0;
|
||||
vec4[3] = 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -41,8 +41,10 @@
|
|||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl/shaders/gl_present3dRowshader.h"
|
||||
|
||||
EXTERN_CVAR(Float, vid_saturation)
|
||||
EXTERN_CVAR(Float, vid_brightness)
|
||||
EXTERN_CVAR(Float, vid_contrast)
|
||||
EXTERN_CVAR(Int, gl_satformula)
|
||||
EXTERN_CVAR(Bool, fullscreen)
|
||||
EXTERN_CVAR(Int, win_x) // screen pixel position of left of display window
|
||||
EXTERN_CVAR(Int, win_y) // screen pixel position of top of display window
|
||||
|
@ -100,12 +102,15 @@ static void prepareInterleavedPresent(FPresentStereoShaderBase& shader)
|
|||
shader.InvGamma.Set(1.0f);
|
||||
shader.Contrast.Set(1.0f);
|
||||
shader.Brightness.Set(0.0f);
|
||||
shader.Saturation.Set(1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
shader.InvGamma.Set(1.0f / clamp<float>(Gamma, 0.1f, 4.f));
|
||||
shader.Contrast.Set(clamp<float>(vid_contrast, 0.1f, 3.f));
|
||||
shader.Brightness.Set(clamp<float>(vid_brightness, -0.8f, 0.8f));
|
||||
shader.Saturation.Set(clamp<float>(vid_saturation, -15.0f, 15.0f));
|
||||
shader.GrayFormula.Set(static_cast<int>(gl_satformula));
|
||||
}
|
||||
shader.Scale.Set(
|
||||
GLRenderer->mScreenViewport.width / (float)GLRenderer->mBuffers->GetWidth(),
|
||||
|
|
|
@ -73,6 +73,22 @@ CUSTOM_CVAR (Float, vid_contrast, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
|||
}
|
||||
}
|
||||
|
||||
CUSTOM_CVAR (Float, vid_saturation, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
{
|
||||
if (screen != NULL)
|
||||
{
|
||||
screen->SetGamma(Gamma);
|
||||
}
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, gl_satformula, 1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
{
|
||||
if (screen != NULL)
|
||||
{
|
||||
screen->SetGamma(Gamma);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Do some tinkering with the menus so that certain options only appear
|
||||
// when they are actually valid.
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#include "textures/textures.h"
|
||||
#include "vm.h"
|
||||
#include "events.h"
|
||||
#include "gl/renderer/gl_renderer.h" // for menu blur
|
||||
|
||||
//
|
||||
// Todo: Move these elsewhere
|
||||
|
@ -784,6 +785,8 @@ void M_Drawer (void)
|
|||
|
||||
if (CurrentMenu != nullptr && menuactive != MENU_Off)
|
||||
{
|
||||
if (GLRenderer)
|
||||
GLRenderer->BlurScene(gameinfo.bluramount);
|
||||
if (!CurrentMenu->DontDim)
|
||||
{
|
||||
screen->Dim(fade);
|
||||
|
|
|
@ -1889,6 +1889,9 @@ bool P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params)
|
|||
if (!(player->mo->flags & MF_SHOOTABLE))
|
||||
continue; // not shootable (observer or dead)
|
||||
|
||||
if (!((actor->flags ^ player->mo->flags) & MF_FRIENDLY))
|
||||
continue; // same +MF_FRIENDLY, ignore
|
||||
|
||||
if (player->cheats & CF_NOTARGET)
|
||||
continue; // no target
|
||||
|
||||
|
@ -1988,7 +1991,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Look)
|
|||
targ = NULL;
|
||||
}
|
||||
|
||||
if (targ && targ->player && (targ->player->cheats & CF_NOTARGET))
|
||||
if (targ && targ->player && ((targ->player->cheats & CF_NOTARGET) || !(targ->flags & MF_FRIENDLY)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -79,6 +79,9 @@ CVAR (Bool, cl_showsprees, true, CVAR_ARCHIVE)
|
|||
CVAR (Bool, cl_showmultikills, true, CVAR_ARCHIVE)
|
||||
EXTERN_CVAR (Bool, show_obituaries)
|
||||
|
||||
CVAR (Float, sv_damagefactormobj, 1.0, CVAR_SERVERINFO|CVAR_NOSAVE)
|
||||
CVAR (Float, sv_damagefactorfriendly, 1.0, CVAR_SERVERINFO|CVAR_NOSAVE)
|
||||
CVAR (Float, sv_damagefactorplayer, 1.0, CVAR_SERVERINFO|CVAR_NOSAVE)
|
||||
|
||||
FName MeansOfDeath;
|
||||
|
||||
|
@ -1036,7 +1039,17 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da
|
|||
if (player && damage > 1)
|
||||
{
|
||||
// Take half damage in trainer mode
|
||||
damage = int(damage * G_SkillProperty(SKILLP_DamageFactor));
|
||||
damage = int(damage * G_SkillProperty(SKILLP_DamageFactor) * sv_damagefactorplayer);
|
||||
}
|
||||
else if (!player && damage > 1 && !(target->flags & MF_FRIENDLY))
|
||||
{
|
||||
// inflict scaled damage to non-players
|
||||
damage = int(damage * sv_damagefactormobj);
|
||||
}
|
||||
else if (!player && damage > 1 && (target->flags & MF_FRIENDLY))
|
||||
{
|
||||
// inflict scaled damage to non-player friends
|
||||
damage = int(damage * sv_damagefactorfriendly);
|
||||
}
|
||||
// Special damage types
|
||||
if (inflictor)
|
||||
|
@ -1865,7 +1878,7 @@ void P_PoisonDamage (player_t *player, AActor *source, int damage, bool playPain
|
|||
return;
|
||||
}
|
||||
// Take half damage in trainer mode
|
||||
damage = int(damage * G_SkillProperty(SKILLP_DamageFactor));
|
||||
damage = int(damage * G_SkillProperty(SKILLP_DamageFactor) * sv_damagefactorplayer);
|
||||
// Handle passive damage modifiers (e.g. PowerProtection)
|
||||
damage = target->GetModifiedDamage(player->poisontype, damage, true);
|
||||
// Modify with damage factors
|
||||
|
|
|
@ -6718,7 +6718,7 @@ bool P_CheckMissileSpawn (AActor* th, double maxdist)
|
|||
th->tics = 1;
|
||||
}
|
||||
|
||||
DVector3 newpos = th->Pos();
|
||||
DVector3 newpos = { 0,0,0 };
|
||||
|
||||
if (maxdist > 0)
|
||||
{
|
||||
|
@ -6736,6 +6736,9 @@ bool P_CheckMissileSpawn (AActor* th, double maxdist)
|
|||
newpos += advance;
|
||||
}
|
||||
|
||||
newpos = th->Vec3Offset(newpos);
|
||||
th->SetXYZ(newpos);
|
||||
|
||||
FCheckPosition tm(!!(th->flags2 & MF2_RIP));
|
||||
|
||||
// killough 8/12/98: for non-missile objects (e.g. grenades)
|
||||
|
@ -7351,7 +7354,7 @@ bool AActor::IsTeammate (AActor *other)
|
|||
}
|
||||
else if (!deathmatch && player && other->player)
|
||||
{
|
||||
return true;
|
||||
return (!((flags ^ other->flags) & MF_FRIENDLY));
|
||||
}
|
||||
else if (teamplay)
|
||||
{
|
||||
|
@ -7432,6 +7435,9 @@ bool AActor::IsFriend (AActor *other)
|
|||
other->FriendPlayer == 0 ||
|
||||
players[FriendPlayer-1].mo->IsTeammate(players[other->FriendPlayer-1].mo);
|
||||
}
|
||||
// [SP] If friendly flags match, then they are on the same team.
|
||||
/*if (!((flags ^ other->flags) & MF_FRIENDLY))
|
||||
return true;*/
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -141,6 +141,7 @@ DEFINE_FIELD_BIT(DPSprite, Flags, bAddBob, PSPF_ADDBOB)
|
|||
DEFINE_FIELD_BIT(DPSprite, Flags, bPowDouble, PSPF_POWDOUBLE)
|
||||
DEFINE_FIELD_BIT(DPSprite, Flags, bCVarFast, PSPF_CVARFAST)
|
||||
DEFINE_FIELD_BIT(DPSprite, Flags, bFlip, PSPF_FLIP)
|
||||
DEFINE_FIELD_BIT(DPSprite, Flags, bMirror, PSPF_MIRROR)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
|
|
|
@ -68,6 +68,7 @@ enum PSPFlags
|
|||
PSPF_FLIP = 1 << 6,
|
||||
PSPF_FORCEALPHA = 1 << 7,
|
||||
PSPF_FORCESTYLE = 1 << 8,
|
||||
PSPF_MIRROR = 1 << 9,
|
||||
};
|
||||
|
||||
class DPSprite : public DObject
|
||||
|
|
|
@ -4119,6 +4119,22 @@ void P_SetupLevel (const char *lumpname, int position)
|
|||
}
|
||||
}
|
||||
|
||||
// [SP] move unfriendly players around
|
||||
// horribly hacky - yes, this needs rewritten.
|
||||
for (i = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
if (playeringame[i] && players[i].mo != NULL)
|
||||
{
|
||||
if (!(players[i].mo->flags & MF_FRIENDLY))
|
||||
{
|
||||
AActor * oldSpawn = players[i].mo;
|
||||
G_DeathMatchSpawnPlayer (i);
|
||||
oldSpawn->Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Don't count monsters in end-of-level sectors if option is on
|
||||
if (dmflags2 & DF2_NOCOUNTENDMONST)
|
||||
{
|
||||
|
|
|
@ -232,7 +232,7 @@ void RenderPolyPlayerSprites::RenderSprite(DPSprite *pspr, AActor *owner, float
|
|||
|
||||
if (pspr->Flags & PSPF_ADDBOB)
|
||||
{
|
||||
sx += bobx;
|
||||
sx += (pspr->Flags & PSPF_MIRROR) ? -bobx : bobx;
|
||||
sy += boby;
|
||||
}
|
||||
|
||||
|
@ -248,17 +248,20 @@ void RenderPolyPlayerSprites::RenderSprite(DPSprite *pspr, AActor *owner, float
|
|||
double pspriteyscale = pspritexscale * yaspectMul;
|
||||
double pspritexiscale = 1 / pspritexscale;
|
||||
|
||||
// calculate edges of the shape
|
||||
tx = sx - BASEXCENTER;
|
||||
int tleft = tex->GetScaledLeftOffset();
|
||||
int twidth = tex->GetScaledWidth();
|
||||
|
||||
// calculate edges of the shape
|
||||
//tx = sx - BASEXCENTER;
|
||||
tx = (pspr->Flags & PSPF_MIRROR) ? ((BASEXCENTER - twidth) - (sx - tleft)) : ((sx - BASEXCENTER) - tleft);
|
||||
|
||||
tx -= tex->GetScaledLeftOffset();
|
||||
x1 = xs_RoundToInt(viewwindow.centerx + tx * pspritexscale);
|
||||
|
||||
// off the right side
|
||||
if (x1 > viewwidth)
|
||||
return;
|
||||
|
||||
tx += tex->GetScaledWidth();
|
||||
tx += twidth;
|
||||
x2 = xs_RoundToInt(viewwindow.centerx + tx * pspritexscale);
|
||||
|
||||
// off the left side
|
||||
|
|
190
src/swrenderer/line/r_farclip_line.cpp
Normal file
190
src/swrenderer/line/r_farclip_line.cpp
Normal file
|
@ -0,0 +1,190 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright 2016 Magnus Norddahl
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see http://www.gnu.org/licenses/
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include "templates.h"
|
||||
#include "i_system.h"
|
||||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "doomdata.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "p_setup.h"
|
||||
#include "r_sky.h"
|
||||
#include "v_video.h"
|
||||
#include "m_swap.h"
|
||||
#include "w_wad.h"
|
||||
#include "stats.h"
|
||||
#include "a_sharedglobal.h"
|
||||
#include "d_net.h"
|
||||
#include "g_level.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "r_wallsetup.h"
|
||||
#include "v_palette.h"
|
||||
#include "r_utility.h"
|
||||
#include "r_data/colormaps.h"
|
||||
#include "swrenderer/r_memory.h"
|
||||
#include "swrenderer/scene/r_opaque_pass.h"
|
||||
#include "swrenderer/scene/r_3dfloors.h"
|
||||
#include "swrenderer/scene/r_portal.h"
|
||||
#include "swrenderer/scene/r_light.h"
|
||||
#include "swrenderer/scene/r_scene.h"
|
||||
#include "swrenderer/viewport/r_viewport.h"
|
||||
#include "swrenderer/line/r_farclip_line.h"
|
||||
#include "swrenderer/line/r_walldraw.h"
|
||||
#include "swrenderer/line/r_wallsetup.h"
|
||||
#include "swrenderer/drawers/r_draw.h"
|
||||
#include "swrenderer/segments/r_clipsegment.h"
|
||||
#include "swrenderer/segments/r_drawsegment.h"
|
||||
#include "swrenderer/plane/r_visibleplane.h"
|
||||
#include "swrenderer/plane/r_visibleplanelist.h"
|
||||
#include "swrenderer/viewport/r_skydrawer.h"
|
||||
#include "swrenderer/r_renderthread.h"
|
||||
|
||||
namespace swrenderer
|
||||
{
|
||||
FarClipLine::FarClipLine(RenderThread *thread)
|
||||
{
|
||||
Thread = thread;
|
||||
}
|
||||
|
||||
void FarClipLine::Render(seg_t *line, subsector_t *subsector, VisiblePlane *linefloorplane, VisiblePlane *lineceilingplane)
|
||||
{
|
||||
mSubsector = subsector;
|
||||
mFrontSector = mSubsector->sector;
|
||||
mLineSegment = line;
|
||||
mFloorPlane = linefloorplane;
|
||||
mCeilingPlane = lineceilingplane;
|
||||
|
||||
DVector2 pt1 = line->v1->fPos() - Thread->Viewport->viewpoint.Pos;
|
||||
DVector2 pt2 = line->v2->fPos() - Thread->Viewport->viewpoint.Pos;
|
||||
|
||||
// Reject lines not facing viewer
|
||||
if (pt1.Y * (pt1.X - pt2.X) + pt1.X * (pt2.Y - pt1.Y) >= 0)
|
||||
return;
|
||||
|
||||
if (WallC.Init(Thread, pt1, pt2, 32.0 / (1 << 12)))
|
||||
return;
|
||||
|
||||
RenderPortal *renderportal = Thread->Portal.get();
|
||||
if (WallC.sx1 >= renderportal->WindowRight || WallC.sx2 <= renderportal->WindowLeft)
|
||||
return;
|
||||
|
||||
if (line->linedef == nullptr)
|
||||
return;
|
||||
|
||||
// reject lines that aren't seen from the portal (if any)
|
||||
// [ZZ] 10.01.2016: lines inside a skybox shouldn't be clipped, although this imposes some limitations on portals in skyboxes.
|
||||
if (!renderportal->CurrentPortalInSkybox && renderportal->CurrentPortal && P_ClipLineToPortal(line->linedef, renderportal->CurrentPortal->dst, Thread->Viewport->viewpoint.Pos))
|
||||
return;
|
||||
|
||||
mFrontCeilingZ1 = mFrontSector->ceilingplane.ZatPoint(line->v1);
|
||||
mFrontFloorZ1 = mFrontSector->floorplane.ZatPoint(line->v1);
|
||||
mFrontCeilingZ2 = mFrontSector->ceilingplane.ZatPoint(line->v2);
|
||||
mFrontFloorZ2 = mFrontSector->floorplane.ZatPoint(line->v2);
|
||||
|
||||
mPrepped = false;
|
||||
|
||||
Thread->ClipSegments->Clip(WallC.sx1, WallC.sx2, true, this);
|
||||
}
|
||||
|
||||
bool FarClipLine::RenderWallSegment(int x1, int x2)
|
||||
{
|
||||
if (!mPrepped)
|
||||
{
|
||||
mPrepped = true;
|
||||
|
||||
//walltop.Project(Thread->Viewport.get(), mFrontSector->ceilingplane, &WallC, mLineSegment, Thread->Portal->MirrorFlags & RF_XFLIP);
|
||||
wallbottom.Project(Thread->Viewport.get(), mFrontSector->floorplane, &WallC, mLineSegment, Thread->Portal->MirrorFlags & RF_XFLIP);
|
||||
memcpy(walltop.ScreenY, wallbottom.ScreenY, sizeof(short) * MAXWIDTH);
|
||||
}
|
||||
|
||||
ClipSegmentTopBottom(x1, x2);
|
||||
MarkCeilingPlane(x1, x2);
|
||||
MarkFloorPlane(x1, x2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FarClipLine::ClipSegmentTopBottom(int x1, int x2)
|
||||
{
|
||||
// clip wall to the floor and ceiling
|
||||
auto ceilingclip = Thread->OpaquePass->ceilingclip;
|
||||
auto floorclip = Thread->OpaquePass->floorclip;
|
||||
for (int x = x1; x < x2; ++x)
|
||||
{
|
||||
if (walltop.ScreenY[x] < ceilingclip[x])
|
||||
{
|
||||
walltop.ScreenY[x] = ceilingclip[x];
|
||||
}
|
||||
if (wallbottom.ScreenY[x] > floorclip[x])
|
||||
{
|
||||
wallbottom.ScreenY[x] = floorclip[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FarClipLine::MarkCeilingPlane(int x1, int x2)
|
||||
{
|
||||
if (mCeilingPlane)
|
||||
{
|
||||
mCeilingPlane = Thread->PlaneList->GetRange(mCeilingPlane, x1, x2);
|
||||
|
||||
auto ceilingclip = Thread->OpaquePass->ceilingclip;
|
||||
auto floorclip = Thread->OpaquePass->floorclip;
|
||||
Clip3DFloors *clip3d = Thread->Clip3D.get();
|
||||
|
||||
for (int x = x1; x < x2; ++x)
|
||||
{
|
||||
short top = (clip3d->fakeFloor && clip3d->fake3D & FAKE3D_FAKECEILING) ? clip3d->fakeFloor->ceilingclip[x] : ceilingclip[x];
|
||||
short bottom = MIN(walltop.ScreenY[x], floorclip[x]);
|
||||
if (top < bottom)
|
||||
{
|
||||
mCeilingPlane->top[x] = top;
|
||||
mCeilingPlane->bottom[x] = bottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FarClipLine::MarkFloorPlane(int x1, int x2)
|
||||
{
|
||||
if (mFloorPlane)
|
||||
{
|
||||
mFloorPlane = Thread->PlaneList->GetRange(mFloorPlane, x1, x2);
|
||||
|
||||
auto ceilingclip = Thread->OpaquePass->ceilingclip;
|
||||
auto floorclip = Thread->OpaquePass->floorclip;
|
||||
Clip3DFloors *clip3d = Thread->Clip3D.get();
|
||||
|
||||
for (int x = x1; x < x2; ++x)
|
||||
{
|
||||
short top = MAX(wallbottom.ScreenY[x], ceilingclip[x]);
|
||||
short bottom = (clip3d->fakeFloor && clip3d->fake3D & FAKE3D_FAKEFLOOR) ? clip3d->fakeFloor->floorclip[x] : floorclip[x];
|
||||
if (top < bottom)
|
||||
{
|
||||
assert(bottom <= viewheight);
|
||||
mFloorPlane->top[x] = top;
|
||||
mFloorPlane->bottom[x] = bottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
60
src/swrenderer/line/r_farclip_line.h
Normal file
60
src/swrenderer/line/r_farclip_line.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright 2016 Magnus Norddahl
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU 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 General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see http://www.gnu.org/licenses/
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "r_line.h"
|
||||
|
||||
namespace swrenderer
|
||||
{
|
||||
class FarClipLine : VisibleSegmentRenderer
|
||||
{
|
||||
public:
|
||||
FarClipLine(RenderThread *thread);
|
||||
void Render(seg_t *line, subsector_t *subsector, VisiblePlane *linefloorplane, VisiblePlane *lineceilingplane);
|
||||
|
||||
RenderThread *Thread = nullptr;
|
||||
|
||||
private:
|
||||
bool RenderWallSegment(int x1, int x2) override;
|
||||
|
||||
void ClipSegmentTopBottom(int x1, int x2);
|
||||
void MarkCeilingPlane(int x1, int x2);
|
||||
void MarkFloorPlane(int x1, int x2);
|
||||
|
||||
subsector_t *mSubsector;
|
||||
sector_t *mFrontSector;
|
||||
seg_t *mLineSegment;
|
||||
VisiblePlane *mFloorPlane;
|
||||
VisiblePlane *mCeilingPlane;
|
||||
|
||||
double mFrontCeilingZ1;
|
||||
double mFrontCeilingZ2;
|
||||
double mFrontFloorZ1;
|
||||
double mFrontFloorZ2;
|
||||
|
||||
FWallCoords WallC;
|
||||
|
||||
bool mPrepped;
|
||||
|
||||
ProjectedWallLine walltop;
|
||||
ProjectedWallLine wallbottom;
|
||||
};
|
||||
}
|
|
@ -9,6 +9,7 @@
|
|||
#include "drawers/r_thread.cpp"
|
||||
#include "line/r_fogboundary.cpp"
|
||||
#include "line/r_line.cpp"
|
||||
#include "line/r_farclip_line.cpp"
|
||||
#include "line/r_renderdrawsegment.cpp"
|
||||
#include "line/r_walldraw.cpp"
|
||||
#include "line/r_wallsetup.cpp"
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "swrenderer/things/r_particle.h"
|
||||
#include "swrenderer/segments/r_clipsegment.h"
|
||||
#include "swrenderer/line/r_wallsetup.h"
|
||||
#include "swrenderer/line/r_farclip_line.h"
|
||||
#include "swrenderer/scene/r_scene.h"
|
||||
#include "swrenderer/scene/r_light.h"
|
||||
#include "swrenderer/viewport/r_viewport.h"
|
||||
|
@ -72,6 +73,36 @@
|
|||
EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor);
|
||||
EXTERN_CVAR(Bool, r_drawvoxels);
|
||||
|
||||
namespace
|
||||
{
|
||||
double sprite_distance_cull = 1e16;
|
||||
double line_distance_cull = 1e16;
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Float, r_sprite_distance_cull, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
{
|
||||
if (r_sprite_distance_cull > 0.0)
|
||||
{
|
||||
sprite_distance_cull = r_sprite_distance_cull * r_sprite_distance_cull;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite_distance_cull = 1e16;
|
||||
}
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Float, r_line_distance_cull, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
{
|
||||
if (r_line_distance_cull > 0.0)
|
||||
{
|
||||
line_distance_cull = r_line_distance_cull * r_line_distance_cull;
|
||||
}
|
||||
else
|
||||
{
|
||||
line_distance_cull = 1e16;
|
||||
}
|
||||
}
|
||||
|
||||
namespace swrenderer
|
||||
{
|
||||
RenderOpaquePass::RenderOpaquePass(RenderThread *thread) : renderline(thread)
|
||||
|
@ -730,10 +761,19 @@ namespace swrenderer
|
|||
count = sub->numlines;
|
||||
line = sub->firstline;
|
||||
|
||||
DVector2 viewpointPos = Thread->Viewport->viewpoint.Pos.XY();
|
||||
|
||||
basecolormap = GetColorTable(frontsector->Colormap, frontsector->SpecialColors[sector_t::walltop]);
|
||||
while (count--)
|
||||
{
|
||||
if (!outersubsector || line->sidedef == nullptr || !(line->sidedef->Flags & WALLF_POLYOBJ))
|
||||
double dist1 = (line->v1->fPos() - viewpointPos).LengthSquared();
|
||||
double dist2 = (line->v2->fPos() - viewpointPos).LengthSquared();
|
||||
if (dist1 > line_distance_cull && dist2 > line_distance_cull)
|
||||
{
|
||||
FarClipLine farclip(Thread);
|
||||
farclip.Render(line, InSubsector, floorplane, ceilingplane);
|
||||
}
|
||||
else if (!outersubsector || line->sidedef == nullptr || !(line->sidedef->Flags & WALLF_POLYOBJ))
|
||||
{
|
||||
// kg3D - fake planes bounding calculation
|
||||
if (r_3dfloors && line->backsector && frontsector->e && line->backsector->e->XFloor.ffloors.Size())
|
||||
|
@ -934,6 +974,10 @@ namespace swrenderer
|
|||
if (!renderportal->CurrentPortalInSkybox && renderportal->CurrentPortal && !!P_PointOnLineSidePrecise(thing->Pos(), renderportal->CurrentPortal->dst))
|
||||
return false;
|
||||
|
||||
double distanceSquared = (thing->Pos() - Thread->Viewport->viewpoint.Pos).LengthSquared();
|
||||
if (distanceSquared > sprite_distance_cull)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -240,7 +240,7 @@ namespace swrenderer
|
|||
|
||||
if (pspr->Flags & PSPF_ADDBOB)
|
||||
{
|
||||
sx += bobx;
|
||||
sx += (pspr->Flags & PSPF_MIRROR) ? -bobx : bobx;
|
||||
sy += boby;
|
||||
}
|
||||
|
||||
|
@ -256,17 +256,18 @@ namespace swrenderer
|
|||
double pspriteyscale = pspritexscale * viewport->YaspectMul;
|
||||
double pspritexiscale = 1 / pspritexscale;
|
||||
|
||||
// calculate edges of the shape
|
||||
tx = sx - BASEXCENTER;
|
||||
int tleft = tex->GetScaledLeftOffset();
|
||||
int twidth = tex->GetScaledWidth();
|
||||
|
||||
tx -= tex->GetScaledLeftOffset();
|
||||
// calculate edges of the shape
|
||||
tx = (pspr->Flags & PSPF_MIRROR) ? ((BASEXCENTER - twidth) - (sx - tleft)) : ((sx - BASEXCENTER) - tleft);
|
||||
x1 = xs_RoundToInt(viewport->CenterX + tx * pspritexscale);
|
||||
|
||||
// off the right side
|
||||
if (x1 > viewwidth)
|
||||
return;
|
||||
|
||||
tx += tex->GetScaledWidth();
|
||||
tx += twidth;
|
||||
x2 = xs_RoundToInt(viewport->CenterX + tx * pspritexscale);
|
||||
|
||||
// off the left side
|
||||
|
|
|
@ -2657,7 +2657,8 @@ MUSIC_DM2INT = "dm2int";
|
|||
DSPLYMNU_GLOPT = "OpenGL Renderer";
|
||||
DSPLYMNU_SWOPT = "Software Renderer";
|
||||
DSPLYMNU_GAMMA = "Gamma correction";
|
||||
DSPLYMNU_CONTRAST ="Contrast";
|
||||
DSPLYMNU_CONTRAST = "Contrast";
|
||||
DSPLYMNU_SATURATION = "Saturation";
|
||||
DSPLYMNU_HWGAMMA = "Hardware Gamma";
|
||||
|
||||
// OpenGL Options
|
||||
|
@ -2708,6 +2709,7 @@ GLPREFMNU_SPRBILLFACECAMERA = "Sprites face camera";
|
|||
GLPREFMNU_PARTICLESTYLE = "Particle style";
|
||||
GLPREFMNU_AMBLIGHT = "Ambient light level";
|
||||
GLPREFMNU_RENDERQUALITY = "Rendering quality";
|
||||
GLPREFMNU_MENUBLUR = "Menu Blur";
|
||||
GLPREFMNU_VRMODE = "Stereo 3D VR";
|
||||
GLPREFMNU_VRQUADSTEREO = "Enable Quad Stereo";
|
||||
GLPREFMNU_MULTISAMPLE = "Multisample";
|
||||
|
|
|
@ -38,6 +38,7 @@ gameinfo
|
|||
weaponslot = 7, "LAZDevice"
|
||||
dimcolor = "ff d7 00"
|
||||
dimamount = 0.2
|
||||
bluramount = 0.0
|
||||
definventorymaxamount = 25
|
||||
defaultrespawntime = 12
|
||||
defaultdropstyle = 1
|
||||
|
|
|
@ -39,6 +39,7 @@ gameinfo
|
|||
weaponslot = 7, "BFG9000"
|
||||
dimcolor = "ff d7 00"
|
||||
dimamount = 0.2
|
||||
bluramount = 0.0
|
||||
definventorymaxamount = 25
|
||||
defaultrespawntime = 12
|
||||
defaultdropstyle = 1
|
||||
|
|
|
@ -38,6 +38,7 @@ gameinfo
|
|||
weaponslot = 7, "Mace"
|
||||
dimcolor = "00 00 ff"
|
||||
dimamount = 0.2
|
||||
bluramount = 0
|
||||
definventorymaxamount = 16
|
||||
defaultrespawntime = 12
|
||||
defaultdropstyle = 1
|
||||
|
|
|
@ -37,6 +37,7 @@ gameinfo
|
|||
weaponslot = 4, "FWeapQuietus", "CWeapWraithverge", "MWeapBloodscourge"
|
||||
dimcolor = "00 00 ff"
|
||||
dimamount = 0.2
|
||||
bluramount = 0.0
|
||||
definventorymaxamount = 25
|
||||
defaultrespawntime = 12
|
||||
defaultdropstyle = 1
|
||||
|
|
|
@ -27,6 +27,7 @@ gameinfo
|
|||
intermissioncounter = true
|
||||
dimcolor = "6f 00 6b"
|
||||
dimamount = 0.8
|
||||
bluramount = 0.0
|
||||
definventorymaxamount = 25
|
||||
defaultrespawntime = 12
|
||||
defaultdropstyle = 1
|
||||
|
|
|
@ -38,6 +38,7 @@ gameinfo
|
|||
weaponslot = 8, "Sigil"
|
||||
dimcolor = "ff d7 00"
|
||||
dimamount = 0.2
|
||||
bluramount = 0
|
||||
definventorymaxamount = 25
|
||||
defaultrespawntime = 16
|
||||
defaultdropstyle = 2
|
||||
|
|
|
@ -734,16 +734,17 @@ OptionMenu "VideoOptions" protected
|
|||
|
||||
Submenu "$DSPLYMNU_GLOPT", "OpenGLOptions"
|
||||
Submenu "$DSPLYMNU_SWOPT", "SWROptions"
|
||||
Submenu "$GLMNU_DYNLIGHT", "GLLightOptions"
|
||||
Submenu "$GLMNU_DYNLIGHT", "GLLightOptions"
|
||||
Submenu "$DSPLYMNU_SCOREBOARD", "ScoreboardOptions"
|
||||
StaticText " "
|
||||
Slider "$DSPLYMNU_SCREENSIZE", "screenblocks", 3.0, 12.0, 1.0, 0
|
||||
Slider "$DSPLYMNU_SCREENSIZE", "screenblocks", 3.0, 12.0, 1.0, 0
|
||||
|
||||
Slider "$DSPLYMNU_GAMMA", "Gamma", 0.75, 3.0, 0.05, 2
|
||||
Slider "$DSPLYMNU_GAMMA", "Gamma", 0.75, 3.0, 0.05, 2
|
||||
Slider "$DSPLYMNU_BRIGHTNESS", "vid_brightness", -0.8,0.8, 0.05,2
|
||||
Slider "$DSPLYMNU_CONTRAST", "vid_contrast", 0.1, 3.0, 0.1
|
||||
Slider "$DSPLYMNU_CONTRAST", "vid_contrast", 0.1, 3.0, 0.1
|
||||
Slider "$DSPLYMNU_SATURATION", "vid_saturation", -3.0, 3.0, 0.25, 2
|
||||
Option "$DSPLYMNU_HWGAMMA", "vid_hwgamma", "HWGammaModes"
|
||||
|
||||
StaticText " "
|
||||
Option "$DSPLYMNU_VSYNC", "vid_vsync", "OnOff"
|
||||
Option "$DSPLYMNU_CAPFPS", "cl_capfps", "OffOn"
|
||||
Slider "$DSPLYMNU_BLOODFADE", "blood_fade_scalar", 0.0, 1.0, 0.05, 2
|
||||
|
@ -2160,6 +2161,8 @@ OptionMenu "OpenGLOptions" protected
|
|||
Option "$GLPREFMNU_PARTICLESTYLE", gl_particles_style, "Particles"
|
||||
Option "$GLPREFMNU_RENDERQUALITY", gl_render_precise, "Precision"
|
||||
StaticText " "
|
||||
Slider "$GLPREFMNU_MENUBLUR", gl_menu_blur, 0, 5.0, 0.5, 2
|
||||
StaticText " "
|
||||
Option "$GLPREFMNU_VRMODE", vr_mode, "VRMode"
|
||||
Option "$GLPREFMNU_VRQUADSTEREO", vr_enable_quadbuffered, "OnOff"
|
||||
StaticText " "
|
||||
|
|
|
@ -6,10 +6,17 @@ uniform sampler2D InputTexture;
|
|||
uniform float InvGamma;
|
||||
uniform float Contrast;
|
||||
uniform float Brightness;
|
||||
uniform float Saturation;
|
||||
uniform int GrayFormula;
|
||||
|
||||
vec4 ApplyGamma(vec4 c)
|
||||
{
|
||||
vec3 val = c.rgb * Contrast - (Contrast - 1.0) * 0.5;
|
||||
vec3 valgray;
|
||||
if (GrayFormula == 0)
|
||||
valgray = vec3(c.r + c.g + c.b) * (1 - Saturation) / 3 + c.rgb * Saturation;
|
||||
else
|
||||
valgray = mix(vec3(dot(c.rgb, vec3(0.3,0.56,0.14))), c.rgb, Saturation);
|
||||
vec3 val = valgray * Contrast - (Contrast - 1.0) * 0.5;
|
||||
val += Brightness * 0.5;
|
||||
val = pow(max(val, vec3(0.0)), vec3(InvGamma));
|
||||
return vec4(val, c.a);
|
||||
|
|
|
@ -775,3 +775,11 @@ class Lighting : SectorEffect native
|
|||
{
|
||||
}
|
||||
|
||||
struct Shader native
|
||||
{
|
||||
native clearscope static void SetEnabled(PlayerInfo player, string shaderName, bool enable);
|
||||
native clearscope static void SetUniform1f(PlayerInfo player, string shaderName, string uniformName, float value);
|
||||
native clearscope static void SetUniform2f(PlayerInfo player, string shaderName, string uniformName, vector2 value);
|
||||
native clearscope static void SetUniform3f(PlayerInfo player, string shaderName, string uniformName, vector3 value);
|
||||
native clearscope static void SetUniform1i(PlayerInfo player, string shaderName, string uniformName, int value);
|
||||
}
|
||||
|
|
|
@ -726,6 +726,7 @@ enum EPSpriteFlags
|
|||
PSPF_FLIP = 1 << 6,
|
||||
PSPF_FORCEALPHA = 1 << 7,
|
||||
PSPF_FORCESTYLE = 1 << 8,
|
||||
PSPF_MIRROR = 1 << 9,
|
||||
};
|
||||
|
||||
// Default psprite layers
|
||||
|
|
Loading…
Reference in a new issue