mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-26 05:41:39 +00:00
This commit is contained in:
commit
2a9e97688d
53 changed files with 752 additions and 102 deletions
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
@ -835,10 +822,11 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo
|
|||
clipper.SafeAddClipRangeRealAngles(ViewAngle.BAMs() + a1, ViewAngle.BAMs() - a1);
|
||||
|
||||
ProcessScene(toscreen);
|
||||
if (mainview && toscreen) EndDrawScene(lviewsector); // do not call this for camera textures.
|
||||
if (mainview && toscreen) EndDrawScene(lviewsector); // do not call this for camera textures.
|
||||
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;
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 ||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ public:
|
|||
void Bind();
|
||||
|
||||
FBufferedUniformSampler SceneTexture;
|
||||
FBufferedUniform1f Exposure;
|
||||
FBufferedUniformSampler ExposureTexture;
|
||||
FBufferedUniform2f Scale;
|
||||
FBufferedUniform2f Offset;
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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
|
111
src/gl/stereo3d/gl_sidebyside3d.cpp
Normal file
111
src/gl/stereo3d/gl_sidebyside3d.cpp
Normal 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 */
|
95
src/gl/stereo3d/gl_sidebyside3d.h
Normal file
95
src/gl/stereo3d/gl_sidebyside3d.h
Normal 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_ */
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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); }
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -644,6 +644,7 @@ xx(ColorSet)
|
|||
xx(NeverSwitchOnPickup)
|
||||
xx(MoveBob)
|
||||
xx(StillBob)
|
||||
xx(WBobSpeed)
|
||||
xx(PlayerClass)
|
||||
xx(Wi_NoAutostartMap)
|
||||
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -272,6 +272,7 @@ enum
|
|||
SCRIPT_Return = 15,
|
||||
SCRIPT_Event = 16, // [BB]
|
||||
SCRIPT_Kill = 17, // [JM]
|
||||
SCRIPT_Reopen = 18, // [Nash]
|
||||
};
|
||||
|
||||
// Script flags
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -44,6 +44,6 @@
|
|||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
||||
<string>YES</string>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -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,22 +695,54 @@ 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 " FLUIDSYNTHLIB1 " or " FLUIDSYNTHLIB2 "\n");
|
||||
return false;
|
||||
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)
|
||||
{
|
||||
Printf(TEXTCOLOR_RED"Could not load " FLUIDSYNTHLIB ": %s\n", dlerror());
|
||||
return false;
|
||||
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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -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"
|
|
@ -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));
|
||||
}
|
||||
|
|
23
wadsrc/static/shaders/glsl/exposureaverage.fp
Normal file
23
wadsrc/static/shaders/glsl/exposureaverage.fp
Normal 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);
|
||||
}
|
16
wadsrc/static/shaders/glsl/exposurecombine.fp
Normal file
16
wadsrc/static/shaders/glsl/exposurecombine.fp
Normal 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);
|
||||
}
|
13
wadsrc/static/shaders/glsl/exposureextract.fp
Normal file
13
wadsrc/static/shaders/glsl/exposureextract.fp
Normal 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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue