This commit is contained in:
raa-eruanna 2016-09-22 05:23:02 -04:00
commit 2a9e97688d
53 changed files with 752 additions and 102 deletions

View File

@ -1117,6 +1117,7 @@ set( FASTMATH_SOURCES
gl/stereo3d/scoped_view_shifter.cpp
gl/stereo3d/gl_anaglyph.cpp
gl/stereo3d/gl_quadstereo.cpp
gl/stereo3d/gl_sidebyside3d.cpp
gl/dynlights/gl_dynlight.cpp
gl/dynlights/gl_glow.cpp
gl/dynlights/gl_dynlight1.cpp

View File

@ -70,6 +70,7 @@ CVAR (String, gender, "male", CVAR_USERINFO | CVAR_ARCHIVE);
CVAR (Bool, neverswitchonpickup, false, CVAR_USERINFO | CVAR_ARCHIVE);
CVAR (Float, movebob, 0.25f, CVAR_USERINFO | CVAR_ARCHIVE);
CVAR (Float, stillbob, 0.f, CVAR_USERINFO | CVAR_ARCHIVE);
CVAR (Float, wbobspeed, 1.f, CVAR_USERINFO | CVAR_ARCHIVE);
CVAR (String, playerclass, "Fighter", CVAR_USERINFO | CVAR_ARCHIVE);
enum
@ -83,6 +84,7 @@ enum
INFO_NeverSwitchOnPickup,
INFO_MoveBob,
INFO_StillBob,
INFO_WBobSpeed,
INFO_PlayerClass,
INFO_ColorSet,
};

View File

@ -337,6 +337,10 @@ struct userinfo_t : TMap<FName,FBaseCVar *>
{
return *static_cast<FFloatCVar *>(*CheckKey(NAME_StillBob));
}
float GetWBobSpeed() const
{
return *static_cast<FFloatCVar *>(*CheckKey(NAME_WBobSpeed));
}
int GetPlayerClassNum() const
{
return *static_cast<FIntCVar *>(*CheckKey(NAME_PlayerClass));

View File

@ -1291,6 +1291,9 @@ void G_FinishTravel ()
if (level.FromSnapshot)
{
FBehavior::StaticStartTypedScripts (SCRIPT_Return, pawn, true);
// [Nash] run REOPEN scripts upon map re-entry
FBehavior::StaticStartTypedScripts(SCRIPT_Reopen, NULL, false);
}
}

View File

@ -1669,7 +1669,7 @@ void APowerDamage::ModifyDamage(int damage, FName damageType, int &newdamage, bo
newdam = damage * 4;
}
if (Owner != NULL && newdam > damage) S_Sound(Owner, 5, ActiveSound, 1.0f, ATTN_NONE);
newdamage = newdam;
newdamage = damage = newdam;
}
if (Inventory != NULL) Inventory->ModifyDamage(damage, damageType, newdamage, passive);
}
@ -1744,7 +1744,7 @@ void APowerProtection::ModifyDamage(int damage, FName damageType, int &newdamage
newdam = damage / 4;
}
if (Owner != NULL && newdam < damage) S_Sound(Owner, CHAN_AUTO, ActiveSound, 1.0f, ATTN_NONE);
newdamage = newdam;
newdamage = damage = newdam;
}
if (Inventory != NULL)
{

View File

@ -222,6 +222,10 @@ bool AWeapon::HandlePickup (AInventory *item)
{
item->ItemFlags |= IF_PICKUPGOOD;
}
if (MaxAmount > 1) //[SP] If amount<maxamount do another pickup test of the weapon itself!
{
return Super::HandlePickup (item);
}
return true;
}
if (Inventory != NULL)

View File

@ -275,8 +275,8 @@ void FVoxelModel::AddFace(int x1, int y1, int z1, int x2, int y2, int z2, int x3
mIndices.Push(indx[1]);
mIndices.Push(indx[3]);
mIndices.Push(indx[1]);
mIndices.Push(indx[3]);
mIndices.Push(indx[2]);
mIndices.Push(indx[3]);
}
//===========================================================================

View File

@ -160,6 +160,7 @@ void F2DDrawer::AddTexture(FTexture *img, DrawParms &parms)
ptr->Set(x, y + h, 0, u1, v2, color); ptr++;
ptr->Set(x + w, y, 0, u2, v1, color); ptr++;
ptr->Set(x + w, y + h, 0, u2, v2, color); ptr++;
dg.mVertCount = 8;
}
AddData(&dg);
}

View File

@ -75,7 +75,10 @@ CUSTOM_CVAR(Float, gl_bloom_amount, 1.4f, 0)
if (self < 0.1f) self = 0.1f;
}
CVAR(Float, gl_exposure, 0.0f, 0)
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)
CUSTOM_CVAR(Int, gl_tonemap, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{
@ -106,6 +109,78 @@ void FGLRenderer::RenderScreenQuad()
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 4);
}
//-----------------------------------------------------------------------------
//
// Extracts light average from the scene and updates the camera exposure texture
//
//-----------------------------------------------------------------------------
void FGLRenderer::UpdateCameraExposure()
{
if (!gl_bloom && gl_tonemap == 0)
return;
FGLDebug::PushGroup("UpdateCameraExposure");
FGLPostProcessState savedState;
savedState.SaveTextureBinding1();
// Extract light level from scene texture:
const auto &level0 = mBuffers->ExposureLevels[0];
glBindFramebuffer(GL_FRAMEBUFFER, level0.Framebuffer);
glViewport(0, 0, level0.Width, level0.Height);
mBuffers->BindCurrentTexture(0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
mExposureExtractShader->Bind();
mExposureExtractShader->SceneTexture.Set(0);
mExposureExtractShader->Scale.Set(mSceneViewport.width / (float)mScreenViewport.width, mSceneViewport.height / (float)mScreenViewport.height);
mExposureExtractShader->Offset.Set(mSceneViewport.left / (float)mScreenViewport.width, mSceneViewport.top / (float)mScreenViewport.height);
RenderScreenQuad();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// Find the average value:
for (int i = 0; i + 1 < mBuffers->ExposureLevels.Size(); i++)
{
const auto &level = mBuffers->ExposureLevels[i];
const auto &next = mBuffers->ExposureLevels[i + 1];
glBindFramebuffer(GL_FRAMEBUFFER, next.Framebuffer);
glViewport(0, 0, next.Width, next.Height);
glBindTexture(GL_TEXTURE_2D, level.Texture);
mExposureAverageShader->Bind();
mExposureAverageShader->ExposureTexture.Set(0);
RenderScreenQuad();
}
// Combine average value with current camera exposure:
glBindFramebuffer(GL_FRAMEBUFFER, mBuffers->ExposureFB);
glViewport(0, 0, 1, 1);
if (!mBuffers->FirstExposureFrame)
{
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else
{
mBuffers->FirstExposureFrame = false;
}
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mBuffers->ExposureLevels.Last().Texture);
mExposureCombineShader->Bind();
mExposureCombineShader->ExposureTexture.Set(0);
mExposureCombineShader->ExposureBase.Set(gl_exposure_base);
mExposureCombineShader->ExposureMin.Set(gl_exposure_min);
mExposureCombineShader->ExposureScale.Set(gl_exposure_scale);
mExposureCombineShader->ExposureSpeed.Set(gl_exposure_speed);
RenderScreenQuad();
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
FGLDebug::PopGroup();
}
//-----------------------------------------------------------------------------
//
// Adds bloom contribution to scene texture
@ -121,6 +196,7 @@ void FGLRenderer::BloomScene()
FGLDebug::PushGroup("BloomScene");
FGLPostProcessState savedState;
savedState.SaveTextureBinding1();
const float blurAmount = gl_bloom_amount;
int sampleCount = gl_bloom_kernel_size;
@ -133,9 +209,12 @@ void FGLRenderer::BloomScene()
mBuffers->BindCurrentTexture(0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, mBuffers->ExposureTexture);
glActiveTexture(GL_TEXTURE0);
mBloomExtractShader->Bind();
mBloomExtractShader->SceneTexture.Set(0);
mBloomExtractShader->Exposure.Set(mCameraExposure);
mBloomExtractShader->ExposureTexture.Set(1);
mBloomExtractShader->Scale.Set(mSceneViewport.width / (float)mScreenViewport.width, mSceneViewport.height / (float)mScreenViewport.height);
mBloomExtractShader->Offset.Set(mSceneViewport.left / (float)mScreenViewport.width, mSceneViewport.top / (float)mScreenViewport.height);
RenderScreenQuad();
@ -220,7 +299,12 @@ void FGLRenderer::TonemapScene()
}
else
{
mTonemapShader->Exposure.Set(mCameraExposure);
savedState.SaveTextureBinding1();
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, mBuffers->ExposureTexture);
glActiveTexture(GL_TEXTURE0);
mTonemapShader->ExposureTexture.Set(1);
}
RenderScreenQuad();

View File

@ -45,7 +45,7 @@ FGLPostProcessState::FGLPostProcessState()
{
glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex);
glActiveTexture(GL_TEXTURE0);
glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding[0]);
glBindTexture(GL_TEXTURE_2D, 0);
if (gl.flags & RFL_SAMPLER_OBJECTS)
{
@ -75,6 +75,15 @@ FGLPostProcessState::FGLPostProcessState()
glDisable(GL_BLEND);
}
void FGLPostProcessState::SaveTextureBinding1()
{
glActiveTexture(GL_TEXTURE1);
glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding[1]);
glBindTexture(GL_TEXTURE_2D, 0);
textureBinding1Saved = true;
glActiveTexture(GL_TEXTURE0);
}
//-----------------------------------------------------------------------------
//
// Restores state at the end of post processing
@ -108,6 +117,12 @@ FGLPostProcessState::~FGLPostProcessState()
glUseProgram(currentProgram);
if (textureBinding1Saved)
{
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
}
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);
if (gl.flags & RFL_SAMPLER_OBJECTS)
@ -115,6 +130,13 @@ FGLPostProcessState::~FGLPostProcessState()
glBindSampler(0, samplerBinding[0]);
glBindSampler(1, samplerBinding[1]);
}
glBindTexture(GL_TEXTURE_2D, textureBinding);
glBindTexture(GL_TEXTURE_2D, textureBinding[0]);
if (textureBinding1Saved)
{
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textureBinding[1]);
}
glActiveTexture(activeTex);
}

View File

@ -14,12 +14,14 @@ public:
FGLPostProcessState();
~FGLPostProcessState();
void SaveTextureBinding1();
private:
FGLPostProcessState(const FGLPostProcessState &) = delete;
FGLPostProcessState &operator=(const FGLPostProcessState &) = delete;
GLint activeTex;
GLint textureBinding;
GLint textureBinding[2];
GLint samplerBinding[2];
GLboolean blendEnabled;
GLboolean scissorEnabled;
@ -32,6 +34,7 @@ private:
GLint blendSrcAlpha;
GLint blendDestRgb;
GLint blendDestAlpha;
bool textureBinding1Saved = false;
};
#endif

View File

@ -74,6 +74,7 @@ FGLRenderBuffers::~FGLRenderBuffers()
ClearPipeline();
ClearEyeBuffers();
ClearBloom();
ClearExposureLevels();
}
void FGLRenderBuffers::ClearScene()
@ -107,6 +108,18 @@ void FGLRenderBuffers::ClearBloom()
}
}
void FGLRenderBuffers::ClearExposureLevels()
{
for (auto &level : ExposureLevels)
{
DeleteTexture(level.Texture);
DeleteFrameBuffer(level.Framebuffer);
}
ExposureLevels.Clear();
DeleteTexture(ExposureTexture);
DeleteFrameBuffer(ExposureFB);
}
void FGLRenderBuffers::ClearEyeBuffers()
{
for (auto handle : mEyeFBs)
@ -186,11 +199,12 @@ bool FGLRenderBuffers::Setup(int width, int height, int sceneWidth, int sceneHei
}
// Bloom bluring buffers need to match the scene to avoid bloom bleeding artifacts
if (mBloomWidth != sceneWidth || mBloomHeight != sceneHeight)
if (mSceneWidth != sceneWidth || mSceneHeight != sceneHeight)
{
CreateBloom(sceneWidth, sceneHeight);
mBloomWidth = sceneWidth;
mBloomHeight = sceneHeight;
CreateExposureLevels(sceneWidth, sceneHeight);
mSceneWidth = sceneWidth;
mSceneHeight = sceneHeight;
}
glBindTexture(GL_TEXTURE_2D, textureBinding);
@ -204,11 +218,12 @@ bool FGLRenderBuffers::Setup(int width, int height, int sceneWidth, int sceneHei
ClearPipeline();
ClearEyeBuffers();
ClearBloom();
ClearExposureLevels();
mWidth = 0;
mHeight = 0;
mSamples = 0;
mBloomWidth = 0;
mBloomHeight = 0;
mSceneWidth = 0;
mSceneHeight = 0;
}
return !FailedCreate;
@ -281,6 +296,41 @@ void FGLRenderBuffers::CreateBloom(int width, int height)
}
}
//==========================================================================
//
// Creates camera exposure level buffers
//
//==========================================================================
void FGLRenderBuffers::CreateExposureLevels(int width, int height)
{
ClearExposureLevels();
int i = 0;
do
{
width = MAX(width / 2, 1);
height = MAX(height / 2, 1);
FString textureName, fbName;
textureName.Format("Exposure.Texture%d", i);
fbName.Format("Exposure.Framebuffer%d", i);
i++;
FGLExposureTextureLevel level;
level.Width = width;
level.Height = height;
level.Texture = Create2DTexture(textureName, GL_R32F, level.Width, level.Height);
level.Framebuffer = CreateFrameBuffer(fbName, level.Texture);
ExposureLevels.Push(level);
} while (width > 1 || height > 1);
ExposureTexture = Create2DTexture("Exposure.CameraTexture", GL_R32F, 1, 1);
ExposureFB = CreateFrameBuffer("Exposure.CameraFB", ExposureTexture);
FirstExposureFrame = true;
}
//==========================================================================
//
// Creates eye buffers if needed
@ -316,14 +366,14 @@ void FGLRenderBuffers::CreateEyeBuffers(int eye)
//
//==========================================================================
GLuint FGLRenderBuffers::Create2DTexture(const FString &name, GLuint format, int width, int height)
GLuint FGLRenderBuffers::Create2DTexture(const FString &name, GLuint format, int width, int height, const void *data)
{
GLuint type = (format == GL_RGBA16F) ? GL_FLOAT : GL_UNSIGNED_BYTE;
GLuint type = (format == GL_RGBA16F || format == GL_R32F) ? GL_FLOAT : GL_UNSIGNED_BYTE;
GLuint handle = 0;
glGenTextures(1, &handle);
glBindTexture(GL_TEXTURE_2D, handle);
FGLDebug::LabelObject(GL_TEXTURE, handle, name);
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, GL_RGBA, type, nullptr);
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format != GL_R32F ? GL_RGBA : GL_RED, type, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);

View File

@ -14,6 +14,15 @@ public:
GLuint Height = 0;
};
class FGLExposureTextureLevel
{
public:
GLuint Texture = 0;
GLuint Framebuffer = 0;
GLuint Width = 0;
GLuint Height = 0;
};
class FGLRenderBuffers
{
public:
@ -39,6 +48,11 @@ public:
enum { NumBloomLevels = 4 };
FGLBloomTextureLevel BloomLevels[NumBloomLevels];
TArray<FGLExposureTextureLevel> ExposureLevels;
GLuint ExposureTexture = 0;
GLuint ExposureFB = 0;
bool FirstExposureFrame = true;
static bool IsEnabled();
int GetWidth() const { return mWidth; }
@ -49,11 +63,13 @@ private:
void ClearPipeline();
void ClearEyeBuffers();
void ClearBloom();
void ClearExposureLevels();
void CreateScene(int width, int height, int samples);
void CreatePipeline(int width, int height);
void CreateBloom(int width, int height);
void CreateExposureLevels(int width, int height);
void CreateEyeBuffers(int eye);
GLuint Create2DTexture(const FString &name, GLuint format, int width, int height);
GLuint Create2DTexture(const FString &name, GLuint format, int width, int height, const void *data = nullptr);
GLuint CreateRenderBuffer(const FString &name, GLuint format, int width, int height);
GLuint CreateRenderBuffer(const FString &name, GLuint format, int samples, int width, int height);
GLuint CreateFrameBuffer(const FString &name, GLuint colorbuffer);
@ -69,8 +85,8 @@ private:
int mHeight = 0;
int mSamples = 0;
int mMaxSamples = 0;
int mBloomWidth = 0;
int mBloomHeight = 0;
int mSceneWidth = 0;
int mSceneHeight = 0;
static const int NumPipelineTextures = 2;
int mCurrentPipelineTexture = 0;

View File

@ -57,6 +57,7 @@
#include "gl/shaders/gl_colormapshader.h"
#include "gl/shaders/gl_lensshader.h"
#include "gl/shaders/gl_presentshader.h"
#include "gl/stereo3d/gl_stereo3d.h"
#include "gl/textures/gl_texture.h"
#include "gl/textures/gl_translate.h"
#include "gl/textures/gl_material.h"
@ -104,6 +105,9 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb)
mPresentShader = nullptr;
mBloomExtractShader = nullptr;
mBloomCombineShader = nullptr;
mExposureExtractShader = nullptr;
mExposureAverageShader = nullptr;
mExposureCombineShader = nullptr;
mBlurShader = nullptr;
mTonemapShader = nullptr;
mTonemapPalette = nullptr;
@ -119,6 +123,9 @@ void FGLRenderer::Initialize(int width, int height)
mBuffers = new FGLRenderBuffers();
mBloomExtractShader = new FBloomExtractShader();
mBloomCombineShader = new FBloomCombineShader();
mExposureExtractShader = new FExposureExtractShader();
mExposureAverageShader = new FExposureAverageShader();
mExposureCombineShader = new FExposureCombineShader();
mBlurShader = new FBlurShader();
mTonemapShader = new FTonemapShader();
mColormapShader = new FColormapShader();
@ -179,6 +186,9 @@ FGLRenderer::~FGLRenderer()
if (mPresentShader) delete mPresentShader;
if (mBloomExtractShader) delete mBloomExtractShader;
if (mBloomCombineShader) delete mBloomCombineShader;
if (mExposureExtractShader) delete mExposureExtractShader;
if (mExposureAverageShader) delete mExposureAverageShader;
if (mExposureCombineShader) delete mExposureCombineShader;
if (mBlurShader) delete mBlurShader;
if (mTonemapShader) delete mTonemapShader;
if (mTonemapPalette) delete mTonemapPalette;
@ -264,6 +274,8 @@ void FGLRenderer::SetOutputViewport(GL_IRECT *bounds)
mSceneViewport.top += mOutputLetterbox.top;
}
}
s3d::Stereo3DMode::getCurrentMode().AdjustViewports();
}
//===========================================================================

View File

@ -21,6 +21,9 @@ class DPSprite;
class FGLRenderBuffers;
class FBloomExtractShader;
class FBloomCombineShader;
class FExposureExtractShader;
class FExposureAverageShader;
class FExposureCombineShader;
class FBlurShader;
class FTonemapShader;
class FColormapShader;
@ -92,6 +95,9 @@ public:
FGLRenderBuffers *mBuffers;
FBloomExtractShader *mBloomExtractShader;
FBloomCombineShader *mBloomCombineShader;
FExposureExtractShader *mExposureExtractShader;
FExposureAverageShader *mExposureAverageShader;
FExposureCombineShader *mExposureCombineShader;
FBlurShader *mBlurShader;
FTonemapShader *mTonemapShader;
FColormapShader *mColormapShader;
@ -118,7 +124,6 @@ public:
GL_IRECT mSceneViewport;
GL_IRECT mOutputLetterbox;
bool mDrawingScene2D = false;
float mCameraExposure = 1.0f;
float mSceneClearColor[3];
@ -166,6 +171,7 @@ public:
void SetFixedColormap (player_t *player);
void WriteSavePic (player_t *player, FILE *file, int width, int height);
void EndDrawScene(sector_t * viewsector);
void UpdateCameraExposure();
void BloomScene();
void TonemapScene();
void ColormapScene();

View File

@ -622,6 +622,7 @@ void FGLRenderer::DrawBlend(sector_t * viewsector)
V_AddBlend (player->BlendR, player->BlendG, player->BlendB, player->BlendA, blend);
}
gl_RenderState.SetTextureMode(TM_MODULATE);
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if (blend[3]>0.0f)
{
@ -660,6 +661,7 @@ void FGLRenderer::EndDrawScene(sector_t * viewsector)
framebuffer->Begin2D(false);
Reset3DViewport();
// [BB] Only draw the sprites if we didn't render a HUD model before.
if ( renderHUDModel == false )
{
@ -790,20 +792,6 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo
mViewActor=camera;
}
if (toscreen)
{
if (gl_exposure == 0.0f)
{
float light = viewsector->lightlevel / 255.0f;
float exposure = MAX(1.0f + (1.0f - light * light) * 0.9f, 0.5f);
mCameraExposure = mCameraExposure * 0.995f + exposure * 0.005f;
}
else
{
mCameraExposure = gl_exposure;
}
}
// 'viewsector' will not survive the rendering so it cannot be used anymore below.
lviewsector = viewsector;
@ -815,7 +803,6 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo
{
const s3d::EyePose * eye = stereo3dMode.getEyePose(eye_ix);
eye->SetUp();
// TODO: stereo specific viewport - needed when implementing side-by-side modes etc.
SetOutputViewport(bounds);
Set3DViewport(mainview);
mDrawingScene2D = true;
@ -839,6 +826,7 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo
if (mainview && FGLRenderBuffers::IsEnabled())
{
mBuffers->BlitSceneToTexture();
UpdateCameraExposure();
BloomScene();
TonemapScene();
ColormapScene();
@ -979,25 +967,25 @@ void FGLRenderer::WriteSavePic (player_t *player, FILE *file, int width, int hei
struct FGLInterface : public FRenderer
{
bool UsesColormap() const;
bool UsesColormap() const override;
void PrecacheTexture(FTexture *tex, int cache);
void PrecacheSprite(FTexture *tex, SpriteHits &hits);
void Precache(BYTE *texhitlist, TMap<PClassActor*, bool> &actorhitlist);
void RenderView(player_t *player);
void WriteSavePic (player_t *player, FILE *file, int width, int height);
void StateChanged(AActor *actor);
void StartSerialize(FArchive &arc);
void EndSerialize(FArchive &arc);
void RenderTextureView (FCanvasTexture *self, AActor *viewpoint, int fov);
sector_t *FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel, bool back);
void SetFogParams(int _fogdensity, PalEntry _outsidefogcolor, int _outsidefogdensity, int _skyfog);
void PreprocessLevel();
void CleanLevelData();
bool RequireGLNodes();
void Precache(BYTE *texhitlist, TMap<PClassActor*, bool> &actorhitlist) override;
void RenderView(player_t *player) override;
void WriteSavePic (player_t *player, FILE *file, int width, int height) override;
void StateChanged(AActor *actor) override;
void StartSerialize(FArchive &arc) override;
void EndSerialize(FArchive &arc) override;
void RenderTextureView (FCanvasTexture *self, AActor *viewpoint, int fov) override;
sector_t *FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel, bool back) override;
void SetFogParams(int _fogdensity, PalEntry _outsidefogcolor, int _outsidefogdensity, int _skyfog) override;
void PreprocessLevel() override;
void CleanLevelData() override;
bool RequireGLNodes() override;
int GetMaxViewPitch(bool down);
void ClearBuffer(int color);
void Init();
int GetMaxViewPitch(bool down) override;
void ClearBuffer(int color) override;
void Init() override;
};
//===========================================================================

View File

@ -310,6 +310,11 @@ void GLSprite::Draw(int pass)
additivefog = true;
}
}
else if (modelframe == nullptr)
{
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(-1.0f, -128.0f);
}
if (RenderStyle.BlendOp!=STYLEOP_Shadow)
{
if (gl_lights && GLRenderer->mLightCount && !gl_fixedcolormap && !fullbright)
@ -440,6 +445,11 @@ void GLSprite::Draw(int pass)
gl_RenderState.BlendEquation(GL_FUNC_ADD);
gl_RenderState.SetTextureMode(TM_MODULATE);
}
else if (modelframe == nullptr)
{
glPolygonOffset(0.0f, 0.0f);
glDisable(GL_POLYGON_OFFSET_FILL);
}
gl_RenderState.SetObjectColor(0xffffffff);
gl_RenderState.EnableTexture(true);

View File

@ -46,6 +46,7 @@
#include "gl/shaders/gl_shader.h"
#include "gl/textures/gl_material.h"
#include "gl/renderer/gl_quaddrawer.h"
#include "gl/stereo3d/gl_stereo3d.h"
EXTERN_CVAR (Bool, r_drawplayersprites)
EXTERN_CVAR(Float, transsouls)
@ -198,6 +199,8 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
AActor * playermo=players[consoleplayer].camera;
player_t * player=playermo->player;
s3d::Stereo3DMode::getCurrentMode().AdjustPlayerSprites();
// this is the same as the software renderer
if (!player ||
!r_drawplayersprites ||

View File

@ -46,7 +46,7 @@ void FBloomExtractShader::Bind()
mShader.Link("shaders/glsl/bloomextract");
mShader.SetAttribLocation(0, "PositionInProjection");
SceneTexture.Init(mShader, "SceneTexture");
Exposure.Init(mShader, "ExposureAdjustment");
ExposureTexture.Init(mShader, "ExposureTexture");
Scale.Init(mShader, "Scale");
Offset.Init(mShader, "Offset");
}

View File

@ -9,7 +9,7 @@ public:
void Bind();
FBufferedUniformSampler SceneTexture;
FBufferedUniform1f Exposure;
FBufferedUniformSampler ExposureTexture;
FBufferedUniform2f Scale;
FBufferedUniform2f Offset;

View File

@ -47,7 +47,7 @@ void FTonemapShader::Bind()
shader.Link("shaders/glsl/tonemap");
shader.SetAttribLocation(0, "PositionInProjection");
SceneTexture.Init(shader, "InputTexture");
Exposure.Init(shader, "ExposureAdjustment");
ExposureTexture.Init(shader, "ExposureTexture");
PaletteLUT.Init(shader, "PaletteLUT");
}
shader.Bind();
@ -70,3 +70,51 @@ const char *FTonemapShader::GetDefines(int mode)
case Palette: return "#define PALETTE\n";
}
}
void FExposureExtractShader::Bind()
{
if (!mShader)
{
mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/exposureextract.fp", "", 330);
mShader.SetFragDataLocation(0, "FragColor");
mShader.Link("shaders/glsl/exposureextract");
mShader.SetAttribLocation(0, "PositionInProjection");
SceneTexture.Init(mShader, "SceneTexture");
Scale.Init(mShader, "Scale");
Offset.Init(mShader, "Offset");
}
mShader.Bind();
}
void FExposureAverageShader::Bind()
{
if (!mShader)
{
mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 400);
mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/exposureaverage.fp", "", 400);
mShader.SetFragDataLocation(0, "FragColor");
mShader.Link("shaders/glsl/exposureaverage");
mShader.SetAttribLocation(0, "PositionInProjection");
ExposureTexture.Init(mShader, "ExposureTexture");
}
mShader.Bind();
}
void FExposureCombineShader::Bind()
{
if (!mShader)
{
mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/exposurecombine.fp", "", 330);
mShader.SetFragDataLocation(0, "FragColor");
mShader.Link("shaders/glsl/exposurecombine");
mShader.SetAttribLocation(0, "PositionInProjection");
ExposureTexture.Init(mShader, "ExposureTexture");
ExposureBase.Init(mShader, "ExposureBase");
ExposureMin.Init(mShader, "ExposureMin");
ExposureScale.Init(mShader, "ExposureScale");
ExposureSpeed.Init(mShader, "ExposureSpeed");
}
mShader.Bind();
}

View File

@ -9,7 +9,7 @@ public:
void Bind();
FBufferedUniformSampler SceneTexture;
FBufferedUniform1f Exposure;
FBufferedUniformSampler ExposureTexture;
FBufferedUniformSampler PaletteLUT;
static bool IsPaletteMode();
@ -31,4 +31,43 @@ private:
FShaderProgram mShader[NumTonemapModes];
};
class FExposureExtractShader
{
public:
void Bind();
FBufferedUniformSampler SceneTexture;
FBufferedUniform2f Scale;
FBufferedUniform2f Offset;
private:
FShaderProgram mShader;
};
class FExposureAverageShader
{
public:
void Bind();
FBufferedUniformSampler ExposureTexture;
private:
FShaderProgram mShader;
};
class FExposureCombineShader
{
public:
void Bind();
FBufferedUniformSampler ExposureTexture;
FBufferedUniform1f ExposureBase;
FBufferedUniform1f ExposureMin;
FBufferedUniform1f ExposureScale;
FBufferedUniform1f ExposureSpeed;
private:
FShaderProgram mShader;
};
#endif

View File

@ -0,0 +1,111 @@
/*
** gl_sidebyside3d.cpp
** Mosaic 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_sidebyside3d.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/renderer/gl_renderbuffers.h"
namespace s3d {
void SideBySideBase::Present() const
{
GLRenderer->mBuffers->BindOutputFB();
GLRenderer->ClearBorders();
// Compute screen regions to use for left and right eye views
int leftWidth = GLRenderer->mOutputLetterbox.width / 2;
int rightWidth = GLRenderer->mOutputLetterbox.width - leftWidth;
GL_IRECT leftHalfScreen = GLRenderer->mOutputLetterbox;
leftHalfScreen.width = leftWidth;
GL_IRECT rightHalfScreen = GLRenderer->mOutputLetterbox;
rightHalfScreen.width = rightWidth;
rightHalfScreen.left += leftWidth;
GLRenderer->mBuffers->BindEyeTexture(0, 0);
GLRenderer->DrawPresentTexture(leftHalfScreen, true);
GLRenderer->mBuffers->BindEyeTexture(1, 0);
GLRenderer->DrawPresentTexture(rightHalfScreen, true);
}
// AdjustViewports() is called from within FLGRenderer::SetOutputViewport(...)
void SideBySideBase::AdjustViewports() const
{
// Change size of renderbuffer, and align to screen
GLRenderer->mSceneViewport.width /= 2;
GLRenderer->mSceneViewport.left /= 2;
GLRenderer->mScreenViewport.width /= 2;
GLRenderer->mScreenViewport.left /= 2;
}
/* static */
const SideBySideSquished& SideBySideSquished::getInstance(float ipd)
{
static SideBySideSquished instance(ipd);
return instance;
}
SideBySideSquished::SideBySideSquished(double ipdMeters)
: leftEye(ipdMeters), rightEye(ipdMeters)
{
eye_ptrs.Push(&leftEye);
eye_ptrs.Push(&rightEye);
}
/* static */
const SideBySideFull& SideBySideFull::getInstance(float ipd)
{
static SideBySideFull instance(ipd);
return instance;
}
SideBySideFull::SideBySideFull(double ipdMeters)
: leftEye(ipdMeters), rightEye(ipdMeters)
{
eye_ptrs.Push(&leftEye);
eye_ptrs.Push(&rightEye);
}
/* virtual */
void SideBySideFull::AdjustPlayerSprites() const /* override */
{
// Show weapon at double width, so it would appear normal width after rescaling
int w = GLRenderer->mScreenViewport.width;
int h = GLRenderer->mScreenViewport.height;
gl_RenderState.mProjectionMatrix.ortho(w/2, w + w/2, h, 0, -1.0f, 1.0f);
gl_RenderState.ApplyMatrices();
}
} /* namespace s3d */

View File

@ -0,0 +1,95 @@
/*
** gl_sidebyside3d.h
** Mosaic 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.
**---------------------------------------------------------------------------
**
**
*/
#ifndef GL_SIDEBYSIDE3D_H_
#define GL_SIDEBYSIDE3D_H_
#include "gl_stereo3d.h"
#include "gl_stereo_leftright.h"
#include "gl/system/gl_system.h"
#include "gl/renderer/gl_renderstate.h"
namespace s3d {
class SideBySideBase : public Stereo3DMode
{
public:
void Present() const override;
virtual void AdjustViewports() const override;
};
class SideBySideSquished : public SideBySideBase
{
public:
static const SideBySideSquished& getInstance(float ipd);
SideBySideSquished(double ipdMeters);
private:
LeftEyePose leftEye;
RightEyePose rightEye;
};
class SBSFLeftEyePose : public LeftEyePose {
public:
SBSFLeftEyePose(double ipdMeters) : LeftEyePose(ipdMeters) {}
virtual VSMatrix GetProjection(float fov, float aspectRatio, float fovRatio) const override {
return LeftEyePose::GetProjection(fov, 0.5f * aspectRatio, fovRatio);
}
};
class SBSFRightEyePose : public RightEyePose {
public:
SBSFRightEyePose(double ipdMeters) : RightEyePose(ipdMeters) {}
virtual VSMatrix GetProjection(float fov, float aspectRatio, float fovRatio) const override {
return RightEyePose::GetProjection(fov, 0.5f * aspectRatio, fovRatio);
}
};
class SideBySideFull : public SideBySideBase
{
public:
static const SideBySideFull& getInstance(float ipd);
SideBySideFull(double ipdMeters);
virtual void AdjustPlayerSprites() const override;
private:
SBSFLeftEyePose leftEye;
SBSFRightEyePose rightEye;
};
} /* namespace s3d */
#endif /* GL_SIDEBYSIDE3D_H_ */

View File

@ -31,6 +31,7 @@
#include <cstring> // needed for memcpy on linux, which is needed by VSMatrix copy ctor
#include "tarray.h"
#include "gl/data/gl_matrix.h"
#include "gl/renderer/gl_renderer.h"
/* stereoscopic 3D API */
@ -78,6 +79,8 @@ public:
virtual void TearDown() const {};
virtual bool IsMono() const { return false; }
virtual void AdjustViewports() const {};
virtual void AdjustPlayerSprites() const {};
virtual void Present() const = 0;
protected:

View File

@ -29,11 +29,15 @@
#include "gl/stereo3d/gl_stereo_leftright.h"
#include "gl/stereo3d/gl_anaglyph.h"
#include "gl/stereo3d/gl_quadstereo.h"
#include "gl/stereo3d/gl_sidebyside3d.h"
#include "gl/system/gl_cvars.h"
// Set up 3D-specific console variables:
CVAR(Int, vr_mode, 0, CVAR_GLOBALCONFIG)
// switch left and right eye views
CVAR(Bool, vr_swap_eyes, false, CVAR_GLOBALCONFIG)
// For broadest GL compatibility, require user to explicitly enable quad-buffered stereo mode.
// Setting vr_enable_quadbuffered_stereo does not automatically invoke quad-buffered stereo,
// but makes it possible for subsequent "vr_mode 7" to invoke quad-buffered stereo
@ -71,7 +75,12 @@ const Stereo3DMode& Stereo3DMode::getCurrentMode()
case 2:
setCurrentMode(RedCyan::getInstance(vr_ipd));
break;
// TODO: missing indices 3, 4 for not-yet-implemented side-by-side modes, to match values from GZ3Doom
case 3:
setCurrentMode(SideBySideFull::getInstance(vr_ipd));
break;
case 4:
setCurrentMode(SideBySideSquished::getInstance(vr_ipd));
break;
case 5:
setCurrentMode(LeftEyeView::getInstance(vr_ipd));
break;
@ -89,7 +98,9 @@ const Stereo3DMode& Stereo3DMode::getCurrentMode()
// TODO: 8: Oculus Rift
case 9:
setCurrentMode(AmberBlue::getInstance(vr_ipd));
break; case 0:
break;
// TODO: 10: HTC Vive/OpenVR
case 0:
default:
setCurrentMode(MonoView::getInstance());
break;

View File

@ -37,6 +37,7 @@
EXTERN_CVAR(Float, vr_screendist)
EXTERN_CVAR(Float, vr_hunits_per_meter)
EXTERN_CVAR(Bool, vr_swap_eyes)
namespace s3d {
@ -50,7 +51,7 @@ VSMatrix ShiftedEyePose::GetProjection(float fov, float aspectRatio, float fovRa
// For stereo 3D, use asymmetric frustum shift in projection matrix
// Q: shouldn't shift vary with roll angle, at least for desktop display?
// A: No. (lab) roll is not measured on desktop display (yet)
double frustumShift = zNear * shift / vr_screendist; // meters cancel, leaving doom units
double frustumShift = zNear * getShift() / vr_screendist; // meters cancel, leaving doom units
// double frustumShift = 0; // Turning off shift for debugging
double fH = zNear * tan(DEG2RAD(fov) / 2) / fovRatio;
double fW = fH * aspectRatio;
@ -68,13 +69,17 @@ VSMatrix ShiftedEyePose::GetProjection(float fov, float aspectRatio, float fovRa
/* virtual */
void ShiftedEyePose::GetViewShift(float yaw, float outViewShift[3]) const
{
float dx = -cos(DEG2RAD(yaw)) * vr_hunits_per_meter * shift;
float dy = sin(DEG2RAD(yaw)) * vr_hunits_per_meter * shift;
float dx = -cos(DEG2RAD(yaw)) * vr_hunits_per_meter * getShift();
float dy = sin(DEG2RAD(yaw)) * vr_hunits_per_meter * getShift();
outViewShift[0] = dx;
outViewShift[1] = dy;
outViewShift[2] = 0;
}
float ShiftedEyePose::getShift() const
{
return vr_swap_eyes ? -shift : shift;
}
/* static */
const LeftEyeView& LeftEyeView::getInstance(float ipd)

View File

@ -37,11 +37,14 @@ class ShiftedEyePose : public EyePose
{
public:
ShiftedEyePose(float shift) : shift(shift) {};
float getShift() const { return shift; }
void setShift(float shift) { this->shift = shift; }
float getShift() const;
virtual VSMatrix GetProjection(float fov, float aspectRatio, float fovRatio) const;
virtual void GetViewShift(float yaw, float outViewShift[3]) const;
protected:
void setShift(float shift) { this->shift = shift; }
private:
float shift;
};
@ -50,7 +53,7 @@ class LeftEyePose : public ShiftedEyePose
{
public:
LeftEyePose(float ipd) : ShiftedEyePose( float(-0.5) * ipd) {}
float getIpd() const { return float(-2.0)*getShift(); }
float getIpd() const { return float(fabs(2.0f*getShift())); }
void setIpd(float ipd) { setShift(float(-0.5)*ipd); }
};
@ -59,7 +62,7 @@ class RightEyePose : public ShiftedEyePose
{
public:
RightEyePose(float ipd) : ShiftedEyePose(float(+0.5)*ipd) {}
float getIpd() const { return float(+2.0)*shift; }
float getIpd() const { return float(fabs(2.0f*getShift())); }
void setIpd(float ipd) { setShift(float(+0.5)*ipd); }
};

View File

@ -250,8 +250,8 @@ void OpenGLFrameBuffer::DoSetGamma()
for (int i = 0; i < 256; i++)
{
double val = i * contrast - (contrast - 1) * 127;
if(gamma != 1) val = pow(val, invgamma) / norm;
val += bright * 128;
if(gamma != 1) val = pow(val, invgamma) / norm;
gammaTable[i] = gammaTable[i + 256] = gammaTable[i + 512] = (WORD)clamp<double>(val*256, 0, 0xffff);
}

View File

@ -644,6 +644,7 @@ xx(ColorSet)
xx(NeverSwitchOnPickup)
xx(MoveBob)
xx(StillBob)
xx(WBobSpeed)
xx(PlayerClass)
xx(Wi_NoAutostartMap)

View File

@ -2822,7 +2822,8 @@ void FBehavior::StaticStartTypedScripts (WORD type, AActor *activator, bool alwa
"Lightning",
"Unloading",
"Disconnect",
"Return"
"Return",
"Reopen"
};
DPrintf(DMSG_NOTIFY, "Starting all scripts of type %d (%s)\n", type,
type < countof(TypeNames) ? TypeNames[type] : TypeNames[SCRIPT_Lightning - 1]);

View File

@ -272,6 +272,7 @@ enum
SCRIPT_Return = 15,
SCRIPT_Event = 16, // [BB]
SCRIPT_Kill = 17, // [JM]
SCRIPT_Reopen = 18, // [Nash]
};
// Script flags

View File

@ -524,6 +524,7 @@ void P_DropWeapon (player_t *player)
// A_WeaponReady every tic, and it looks bad if they don't bob smoothly.
//
// [XA] Added new bob styles and exposed bob properties. Thanks, Ryan Cordell!
// [SP] Added new user option for bob speed
//
//============================================================================
@ -551,8 +552,9 @@ void P_BobWeapon (player_t *player, float *x, float *y, double ticfrac)
for (int i = 0; i < 2; i++)
{
// Bob the weapon based on movement speed.
FAngle angle = (BobSpeed * 35 / TICRATE*(level.time - 1 + i)) * (360.f / 8192.f);
// Bob the weapon based on movement speed. ([SP] And user's bob speed setting)
FAngle angle = (BobSpeed * player->userinfo.GetWBobSpeed() * 35 /
TICRATE*(level.time - 1 + i)) * (360.f / 8192.f);
// [RH] Smooth transitions between bobbing and not-bobbing frames.
// This also fixes the bug where you can "stick" a weapon off-center by

View File

@ -44,6 +44,6 @@
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<string>YES</string>
<true/>
</dict>
</plist>

View File

@ -59,7 +59,11 @@
#else
#include <dlfcn.h>
#ifdef __APPLE__
#define FLUIDSYNTHLIB "libfluidsynth.1.dylib"
#else // !__APPLE__
#define FLUIDSYNTHLIB "libfluidsynth.so.1"
#endif // __APPLE__
#endif
#define FLUID_REVERB_DEFAULT_ROOMSIZE 0.2f
@ -92,6 +96,8 @@
// PUBLIC DATA DEFINITIONS -------------------------------------------------
CVAR(String, fluid_lib, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR(String, fluid_patchset, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CUSTOM_CVAR(Float, fluid_gain, 0.5, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
@ -689,23 +695,55 @@ bool FluidSynthMIDIDevice::LoadFluidSynth()
const char *libname;
#ifdef _WIN32
FluidSynthDLL = LoadLibrary((libname = FLUIDSYNTHLIB1));
if (FluidSynthDLL == NULL)
if (strlen(fluid_lib) > 0)
{
FluidSynthDLL = LoadLibrary((libname = FLUIDSYNTHLIB2));
if (FluidSynthDLL == NULL)
FluidSynthDLL = LoadLibrary(libname = fluid_lib);
if (nullptr == FluidSynthDLL)
{
Printf(TEXTCOLOR_RED "Could not load %s\n", libname);
}
}
else
{
FluidSynthDLL = nullptr;
}
if (nullptr == FluidSynthDLL)
{
FluidSynthDLL = LoadLibrary(libname = FLUIDSYNTHLIB1);
if (nullptr == FluidSynthDLL)
{
FluidSynthDLL = LoadLibrary(libname = FLUIDSYNTHLIB2);
if (nullptr == FluidSynthDLL)
{
Printf(TEXTCOLOR_RED "Could not load " FLUIDSYNTHLIB1 " or " FLUIDSYNTHLIB2 "\n");
return false;
}
}
}
#else
FluidSynthSO = dlopen((libname = FLUIDSYNTHLIB), RTLD_LAZY);
if (FluidSynthSO == NULL)
if (strlen(fluid_lib) > 0)
{
FluidSynthSO = dlopen(libname = fluid_lib, RTLD_LAZY);
if (nullptr == FluidSynthSO)
{
Printf(TEXTCOLOR_RED "Could not load %s: %s\n", libname, dlerror());
}
}
else
{
FluidSynthSO = nullptr;
}
if (nullptr == FluidSynthSO)
{
FluidSynthSO = dlopen(libname = FLUIDSYNTHLIB, RTLD_LAZY);
if (nullptr == FluidSynthSO)
{
Printf(TEXTCOLOR_RED "Could not load " FLUIDSYNTHLIB ": %s\n", dlerror());
return false;
}
}
#endif
for (size_t i = 0; i < countof(imports); ++i)

View File

@ -3373,6 +3373,19 @@ FxExpression *FxClassMember::Resolve(FCompileContext &ctx)
ExpEmit FxClassMember::Emit(VMFunctionBuilder *build)
{
if (~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
// self (a0) != stateowner (a1) then the offset is most likely
// going to end up being totally wrong even if the variable was
// redefined in self which means we have to abort to avoid reading
// or writing to a random address and possibly crash.
build->Emit(OP_EQA_R, 1, 0, 1);
build->Emit(OP_JMP, 1);
build->Emit(OP_THROW, 2, X_BAD_SELF);
}
ExpEmit obj = classx->Emit(build);
assert(obj.RegType == REGT_POINTER);

View File

@ -1576,10 +1576,6 @@ DEFINE_PROPERTY(telefogdesttype, S, Actor)
DEFINE_PROPERTY(ripperlevel, I, Actor)
{
PROP_INT_PARM(id, 0);
if (id < 0)
{
I_Error ("RipperLevel must not be negative");
}
defaults->RipperLevel = id;
}
@ -1589,10 +1585,6 @@ DEFINE_PROPERTY(ripperlevel, I, Actor)
DEFINE_PROPERTY(riplevelmin, I, Actor)
{
PROP_INT_PARM(id, 0);
if (id < 0)
{
I_Error ("RipLevelMin must not be negative");
}
defaults->RipLevelMin = id;
}
@ -1602,10 +1594,6 @@ DEFINE_PROPERTY(riplevelmin, I, Actor)
DEFINE_PROPERTY(riplevelmax, I, Actor)
{
PROP_INT_PARM(id, 0);
if (id < 0)
{
I_Error ("RipLevelMax must not be negative");
}
defaults->RipLevelMax = id;
}

View File

@ -163,6 +163,7 @@ enum EVMAbortException
X_TOO_MANY_TRIES,
X_ARRAY_OUT_OF_BOUNDS,
X_DIVISION_BY_ZERO,
X_BAD_SELF,
};
class VMFunction : public DObject

View File

@ -371,7 +371,18 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction
col = print_reg(out, 0, a, (mode & MODE_ATYPE) >> MODE_ASHIFT, 24, func);
if ((mode & MODE_BCTYPE) == MODE_BCTHROW)
{
mode = (code[i].a == 0) ? (MODE_BP | MODE_CUNUSED) : (MODE_BKP | MODE_CUNUSED);
if (code[i].a == 0)
{
mode = (MODE_BP | MODE_CUNUSED);
}
else if (code[i].a == 1)
{
mode = (MODE_BKP | MODE_CUNUSED);
}
else
{
mode = (MODE_BCJOINT | MODE_BCIMMS);
}
}
else if ((mode & MODE_BCTYPE) == MODE_BCCATCH)
{

View File

@ -616,12 +616,16 @@ begin:
ASSERTA(B);
throw((VMException *)reg.a[B]);
}
else
else if (a == 1)
{
ASSERTKA(B);
assert(konstatag[B] == ATAG_OBJECT);
throw((VMException *)konsta[B].o);
}
else
{
THROW(BC);
}
NEXTOP;
OP(CATCH):
// This instruction is handled by our own catch handler and should

View File

@ -440,6 +440,10 @@ int VMFrameStack::Call(VMFunction *func, VMValue *params, int numparams, VMRetur
case X_DIVISION_BY_ZERO:
Printf("division by zero.");
break;
case X_BAD_SELF:
Printf("invalid self pointer.");
break;
}
Printf("\n");

View File

@ -83,7 +83,8 @@ xx(RETI, reti, I8I16), // Copy immediate from BC to return value A, possibly re
xx(TRY, try, I24), // When an exception is thrown, start searching for a handler at pc + ABC
xx(UNTRY, untry, I8), // Pop A entries off the exception stack
xx(THROW, throw, THROW), // A == 0: Throw exception object pB
// A != 0: Throw exception object pkB
// A == 1: Throw exception object pkB
// A >= 2: Throw VM exception of type BC
xx(CATCH, catch, CATCH), // A == 0: continue search on next try
// A == 1: continue execution at instruction immediately following CATCH (catches any exception)
// A == 2: (pB == <type of exception thrown>) then pc++ ; next instruction must JMP to another CATCH

View File

@ -30,6 +30,7 @@
#include "actors/shared/action.txt"
#include "actors/shared/dog.txt"
#include "actors/shared/damagetypes.txt"
#include "actors/shared/dynlights.txt"
#include "actors/doom/doomplayer.txt"
#include "actors/doom/possessed.txt"

View File

@ -1806,6 +1806,7 @@ DSPLYMNU_MENUDIM = "Menu dim";
DSPLYMNU_DIMCOLOR = "Dim color";
DSPLYMNU_MOVEBOB = "View bob amount while moving";
DSPLYMNU_STILLBOB = "View bob amount while not moving";
DSPLYMNU_BOBSPEED = "Weapon bob speed";
// HUD Options
HUDMNU_TITLE = "HUD Options";
@ -2704,6 +2705,8 @@ OPTVAL_REDCYAN = "Red/Cyan";
OPTVAL_AMBERBLUE = "Amber/Blue";
OPTVAL_LEFTEYE = "Left Eye";
OPTVAL_RIGHTEYE = "Right Eye";
OPTVAL_SBSFULL = "Side-by-side Full";
OPTVAL_SBSNARROW = "Side-by-side Narrow";
OPTVAL_QUADBUFFERED = "Quad-buffered";
OPTVAL_UNCHARTED2 = "Uncharted 2";
OPTVAL_HEJLDAWSON = "Hejl Dawson";

View File

@ -707,6 +707,7 @@ OptionMenu "VideoOptions"
ColorPicker "$DSPLYMNU_DIMCOLOR", "dimcolor"
Slider "$DSPLYMNU_MOVEBOB", "movebob", 0, 1.0, 0.05, 2
Slider "$DSPLYMNU_STILLBOB", "stillbob", 0, 1.0, 0.05, 2
Slider "$DSPLYMNU_BOBSPEED", "wbobspeed", 0, 2.0, 0.1, 2
}
//-------------------------------------------------------------------------------------------

View File

@ -167,6 +167,8 @@ OptionValue VRMode
1, "$OPTVAL_GREENMAGENTA"
2, "$OPTVAL_REDCYAN"
9, "$OPTVAL_AMBERBLUE"
3, "$OPTVAL_SBSFULL"
4, "$OPTVAL_SBSNARROW"
5, "$OPTVAL_LEFTEYE"
6, "$OPTVAL_RIGHTEYE"
7, "$OPTVAL_QUADBUFFERED"

View File

@ -3,12 +3,13 @@ in vec2 TexCoord;
out vec4 FragColor;
uniform sampler2D SceneTexture;
uniform float ExposureAdjustment;
uniform sampler2D ExposureTexture;
uniform vec2 Scale;
uniform vec2 Offset;
void main()
{
float exposureAdjustment = texture(ExposureTexture, vec2(0.5)).x;
vec4 color = texture(SceneTexture, Offset + TexCoord * Scale);
FragColor = max(vec4(color.rgb * ExposureAdjustment - 1, 1), vec4(0));
FragColor = max(vec4((color.rgb + vec3(0.001)) * exposureAdjustment - 1, 1), vec4(0));
}

View File

@ -0,0 +1,23 @@
in vec2 TexCoord;
out vec4 FragColor;
uniform sampler2D ExposureTexture;
void main()
{
#if __VERSION__ < 400
ivec2 size = textureSize(ExposureTexture, 0);
ivec2 tl = max(ivec2(TexCoord * vec2(size) - 0.5), ivec2(0));
ivec2 br = min(tl + ivec2(1), size - ivec2(1));
vec4 values = vec4(
texelFetch(ExposureTexture, tl, 0).x,
texelFetch(ExposureTexture, ivec2(tl.x, br.y), 0).x,
texelFetch(ExposureTexture, ivec2(br.x, tl.y), 0).x,
texelFetch(ExposureTexture, br, 0).x);
#else
vec4 values = textureGather(ExposureTexture, TexCoord);
#endif
FragColor = vec4((values.x + values.y + values.z + values.w) * 0.25, 0.0, 0.0, 1.0);
}

View File

@ -0,0 +1,16 @@
in vec2 TexCoord;
out vec4 FragColor;
uniform sampler2D ExposureTexture;
uniform float ExposureBase;
uniform float ExposureMin;
uniform float ExposureScale;
uniform float ExposureSpeed;
void main()
{
float light = texture(ExposureTexture, TexCoord).x;
float exposureAdjustment = 1.0 / max(ExposureBase + light * ExposureScale, ExposureMin);
FragColor = vec4(exposureAdjustment, 0.0, 0.0, ExposureSpeed);
}

View File

@ -0,0 +1,13 @@
in vec2 TexCoord;
out vec4 FragColor;
uniform sampler2D SceneTexture;
uniform vec2 Scale;
uniform vec2 Offset;
void main()
{
vec4 color = texture(SceneTexture, Offset + TexCoord * Scale);
FragColor = vec4(max(max(color.r, color.g), color.b), 0.0, 0.0, 1.0);
}

View File

@ -9,9 +9,9 @@ uniform float Brightness;
vec4 ApplyGamma(vec4 c)
{
vec3 val = max(c.rgb * Contrast - (Contrast - 1.0) * 0.5, vec3(0.0));
val = pow(val, vec3(InvGamma));
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);
}

View File

@ -3,7 +3,7 @@ in vec2 TexCoord;
out vec4 FragColor;
uniform sampler2D InputTexture;
uniform float ExposureAdjustment;
uniform sampler2D ExposureTexture;
vec3 Linear(vec3 c)
{
@ -84,7 +84,8 @@ void main()
{
vec3 color = texture(InputTexture, TexCoord).rgb;
#ifndef PALETTE
color = color * ExposureAdjustment;
float exposureAdjustment = texture(ExposureTexture, vec2(0.5)).x;
color = color * exposureAdjustment;
color = Linear(color); // needed because gzdoom's scene texture is not linear at the moment
#endif
FragColor = vec4(Tonemap(color), 1.0);