mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 07:11:54 +00:00
- reinstated some texturing-based dynamic light code. Not active yet and not tested yet.
This commit is contained in:
parent
ee7a4daa8c
commit
d4806f82ca
6 changed files with 214 additions and 98 deletions
|
@ -45,10 +45,19 @@
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "v_text.h"
|
#include "v_text.h"
|
||||||
#include "r_utility.h"
|
#include "r_utility.h"
|
||||||
|
#include "gl/dynlights/gl_dynlight.h"
|
||||||
|
#include "gl/utility/gl_geometric.h"
|
||||||
|
#include "gl/renderer/gl_renderer.h"
|
||||||
#include "gl/system/gl_interface.h"
|
#include "gl/system/gl_interface.h"
|
||||||
#include "gl/system/gl_cvars.h"
|
#include "gl/system/gl_cvars.h"
|
||||||
#include "gl/renderer/gl_renderstate.h"
|
#include "gl/renderer/gl_renderstate.h"
|
||||||
|
#include "gl/scene/gl_drawinfo.h"
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
void gl_SetTextureMode(int type)
|
void gl_SetTextureMode(int type)
|
||||||
{
|
{
|
||||||
|
@ -190,6 +199,11 @@ BYTE *gl_WarpBuffer(BYTE *buffer, int Width, int Height, int warp, float Speed)
|
||||||
return (BYTE*)out;
|
return (BYTE*)out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
static int ffTextureMode;
|
static int ffTextureMode;
|
||||||
static bool ffTextureEnabled;
|
static bool ffTextureEnabled;
|
||||||
|
@ -322,6 +336,12 @@ void FRenderState::ApplyFixedFunction()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
void gl_FillScreen();
|
void gl_FillScreen();
|
||||||
|
|
||||||
void FRenderState::DrawColormapOverlay()
|
void FRenderState::DrawColormapOverlay()
|
||||||
|
@ -376,3 +396,183 @@ void FRenderState::DrawColormapOverlay()
|
||||||
gl_FillScreen();
|
gl_FillScreen();
|
||||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Sets up the parameters to render one dynamic light onto one plane
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, Vector & nearPt, Vector & up, Vector & right,
|
||||||
|
float & scale, int desaturation, bool checkside, bool forceadditive)
|
||||||
|
{
|
||||||
|
Vector fn, pos;
|
||||||
|
|
||||||
|
DVector3 lpos = light->PosRelative(group);
|
||||||
|
|
||||||
|
float dist = fabsf(p.DistToPoint(lpos.X, lpos.Z, lpos.Y));
|
||||||
|
float radius = (light->GetRadius() * gl_lights_size);
|
||||||
|
|
||||||
|
if (radius <= 0.f) return false;
|
||||||
|
if (dist > radius) return false;
|
||||||
|
if (checkside && gl_lights_checkside && p.PointOnSide(lpos.X, lpos.Z, lpos.Y))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (light->owned && light->target != NULL && !light->target->IsVisibleToPlayer())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
scale = 1.0f / ((2.f * radius) - dist);
|
||||||
|
|
||||||
|
// project light position onto plane (find closest point on plane)
|
||||||
|
|
||||||
|
|
||||||
|
pos.Set(lpos.X, lpos.Z, lpos.Y);
|
||||||
|
fn = p.Normal();
|
||||||
|
fn.GetRightUp(right, up);
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
nearPt = pos + fn * dist;
|
||||||
|
#else
|
||||||
|
Vector tmpVec = fn * dist;
|
||||||
|
nearPt = pos + tmpVec;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float cs = 1.0f - (dist / radius);
|
||||||
|
if (gl_lights_additive || light->flags4&MF4_ADDITIVE || forceadditive) cs *= 0.2f; // otherwise the light gets too strong.
|
||||||
|
float r = light->GetRed() / 255.0f * cs * gl_lights_intensity;
|
||||||
|
float g = light->GetGreen() / 255.0f * cs * gl_lights_intensity;
|
||||||
|
float b = light->GetBlue() / 255.0f * cs * gl_lights_intensity;
|
||||||
|
|
||||||
|
if (light->IsSubtractive())
|
||||||
|
{
|
||||||
|
Vector v;
|
||||||
|
|
||||||
|
gl_RenderState.BlendEquation(GL_FUNC_REVERSE_SUBTRACT);
|
||||||
|
v.Set(r, g, b);
|
||||||
|
r = v.Length() - r;
|
||||||
|
g = v.Length() - g;
|
||||||
|
b = v.Length() - b;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gl_RenderState.BlendEquation(GL_FUNC_ADD);
|
||||||
|
}
|
||||||
|
if (desaturation > 0 && gl.glslversion > 0) // no-shader excluded because no desaturated textures.
|
||||||
|
{
|
||||||
|
float gray = (r * 77 + g * 143 + b * 37) / 257;
|
||||||
|
|
||||||
|
r = (r*(32 - desaturation) + gray*desaturation) / 32;
|
||||||
|
g = (g*(32 - desaturation) + gray*desaturation) / 32;
|
||||||
|
b = (b*(32 - desaturation) + gray*desaturation) / 32;
|
||||||
|
}
|
||||||
|
glColor3f(r, g, b);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
bool gl_SetupLightTexture()
|
||||||
|
{
|
||||||
|
if (GLRenderer->gllight == NULL) return false;
|
||||||
|
FMaterial * pat = FMaterial::ValidateTexture(GLRenderer->gllight, false);
|
||||||
|
pat->Bind(CLAMP_XY, 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void FGLRenderer::RenderMultipassStuff()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
// First pass: empty background with sector light only
|
||||||
|
|
||||||
|
// Part 1: solid geometry. This is set up so that there are no transparent parts
|
||||||
|
|
||||||
|
// remove any remaining texture bindings and shaders whick may get in the way.
|
||||||
|
gl_RenderState.EnableTexture(false);
|
||||||
|
gl_RenderState.EnableBrightmap(false);
|
||||||
|
gl_RenderState.Apply();
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(GLPASS_BASE);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(GLPASS_BASE);
|
||||||
|
|
||||||
|
// Part 2: masked geometry. This is set up so that only pixels with alpha>0.5 will show
|
||||||
|
// This creates a blank surface that only fills the nontransparent parts of the texture
|
||||||
|
gl_RenderState.EnableTexture(true);
|
||||||
|
gl_RenderState.SetTextureMode(TM_MASK);
|
||||||
|
gl_RenderState.EnableBrightmap(true);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_WALLS_BRIGHT].DrawWalls(GLPASS_BASE_MASKED);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(GLPASS_BASE_MASKED);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_FLATS_BRIGHT].DrawFlats(GLPASS_BASE_MASKED);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(GLPASS_BASE_MASKED);
|
||||||
|
|
||||||
|
// Part 3: The base of fogged surfaces, including the texture
|
||||||
|
gl_RenderState.EnableBrightmap(false);
|
||||||
|
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_WALLS_FOG].DrawWalls(GLPASS_PLAIN);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_WALLS_FOGMASKED].DrawWalls(GLPASS_PLAIN);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_FLATS_FOG].DrawFlats(GLPASS_PLAIN);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_FLATS_FOGMASKED].DrawFlats(GLPASS_PLAIN);
|
||||||
|
|
||||||
|
// second pass: draw lights
|
||||||
|
glDepthMask(false);
|
||||||
|
if (mLightCount && !gl_fixedcolormap)
|
||||||
|
{
|
||||||
|
if (gl_SetupLightTexture())
|
||||||
|
{
|
||||||
|
gl_RenderState.BlendFunc(GL_ONE, GL_ONE);
|
||||||
|
glDepthFunc(GL_EQUAL);
|
||||||
|
if (glset.lightmode == 8) gl_RenderState.SetSoftLightLevel(255);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(GLPASS_LIGHTTEX);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_WALLS_BRIGHT].DrawWalls(GLPASS_LIGHTTEX);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(GLPASS_LIGHTTEX);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(GLPASS_LIGHTTEX);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_FLATS_BRIGHT].DrawFlats(GLPASS_LIGHTTEX);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(GLPASS_LIGHTTEX);
|
||||||
|
gl_RenderState.BlendEquation(GL_FUNC_ADD);
|
||||||
|
}
|
||||||
|
else gl_lights = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// third pass: modulated texture
|
||||||
|
gl_RenderState.SetColor(0xffffffff);
|
||||||
|
gl_RenderState.BlendFunc(GL_DST_COLOR, GL_ZERO);
|
||||||
|
gl_RenderState.EnableFog(false);
|
||||||
|
gl_RenderState.AlphaFunc(GL_GEQUAL, 0);
|
||||||
|
glDepthFunc(GL_LEQUAL);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(GLPASS_TEXONLY);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(GLPASS_TEXONLY);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_WALLS_BRIGHT].DrawWalls(GLPASS_TEXONLY);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_FLATS_BRIGHT].DrawFlats(GLPASS_TEXONLY);
|
||||||
|
gl_RenderState.AlphaFunc(GL_GREATER, gl_mask_threshold);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(GLPASS_TEXONLY);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(GLPASS_TEXONLY);
|
||||||
|
|
||||||
|
// fourth pass: additive lights
|
||||||
|
gl_RenderState.EnableFog(true);
|
||||||
|
gl_RenderState.BlendFunc(GL_ONE, GL_ONE);
|
||||||
|
glDepthFunc(GL_EQUAL);
|
||||||
|
if (gl_SetupLightTexture())
|
||||||
|
{
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(GLPASS_LIGHTTEX_ADDITIVE);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_WALLS_BRIGHT].DrawWalls(GLPASS_LIGHTTEX_ADDITIVE);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(GLPASS_LIGHTTEX_ADDITIVE);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(GLPASS_LIGHTTEX_ADDITIVE);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_FLATS_BRIGHT].DrawFlats(GLPASS_LIGHTTEX_ADDITIVE);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(GLPASS_LIGHTTEX_ADDITIVE);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_WALLS_FOG].DrawWalls(GLPASS_LIGHTTEX_ADDITIVE);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_WALLS_FOGMASKED].DrawWalls(GLPASS_LIGHTTEX_ADDITIVE);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_FLATS_FOG].DrawFlats(GLPASS_LIGHTTEX_ADDITIVE);
|
||||||
|
gl_drawinfo->dldrawlists[GLLDL_FLATS_FOGMASKED].DrawFlats(GLPASS_LIGHTTEX_ADDITIVE);
|
||||||
|
}
|
||||||
|
else gl_lights = false;
|
||||||
|
}
|
|
@ -140,95 +140,3 @@ bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, bo
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// Sets up the parameters to render one dynamic light onto one plane
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, Vector & nearPt, Vector & up, Vector & right,
|
|
||||||
float & scale, int desaturation, bool checkside, bool forceadditive)
|
|
||||||
{
|
|
||||||
Vector fn, pos;
|
|
||||||
|
|
||||||
DVector3 lpos = light->PosRelative(group);
|
|
||||||
|
|
||||||
float dist = fabsf(p.DistToPoint(lpos.X, lpos.Z, lpos.Y));
|
|
||||||
float radius = (light->GetRadius() * gl_lights_size);
|
|
||||||
|
|
||||||
if (radius <= 0.f) return false;
|
|
||||||
if (dist > radius) return false;
|
|
||||||
if (checkside && gl_lights_checkside && p.PointOnSide(lpos.X, lpos.Z, lpos.Y))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (light->owned && light->target != NULL && !light->target->IsVisibleToPlayer())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
scale = 1.0f / ((2.f * radius) - dist);
|
|
||||||
|
|
||||||
// project light position onto plane (find closest point on plane)
|
|
||||||
|
|
||||||
|
|
||||||
pos.Set(lpos.X, lpos.Z, lpos.Y);
|
|
||||||
fn = p.Normal();
|
|
||||||
fn.GetRightUp(right, up);
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
nearPt = pos + fn * dist;
|
|
||||||
#else
|
|
||||||
Vector tmpVec = fn * dist;
|
|
||||||
nearPt = pos + tmpVec;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
float cs = 1.0f - (dist / radius);
|
|
||||||
if (gl_lights_additive || light->flags4&MF4_ADDITIVE || forceadditive) cs *= 0.2f; // otherwise the light gets too strong.
|
|
||||||
float r = light->GetRed() / 255.0f * cs * gl_lights_intensity;
|
|
||||||
float g = light->GetGreen() / 255.0f * cs * gl_lights_intensity;
|
|
||||||
float b = light->GetBlue() / 255.0f * cs * gl_lights_intensity;
|
|
||||||
|
|
||||||
if (light->IsSubtractive())
|
|
||||||
{
|
|
||||||
Vector v;
|
|
||||||
|
|
||||||
gl_RenderState.BlendEquation(GL_FUNC_REVERSE_SUBTRACT);
|
|
||||||
v.Set(r, g, b);
|
|
||||||
r = v.Length() - r;
|
|
||||||
g = v.Length() - g;
|
|
||||||
b = v.Length() - b;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gl_RenderState.BlendEquation(GL_FUNC_ADD);
|
|
||||||
}
|
|
||||||
if (desaturation > 0 && gl.glslversion > 0) // no-shader excluded because no desaturated textures.
|
|
||||||
{
|
|
||||||
float gray = (r * 77 + g * 143 + b * 37) / 257;
|
|
||||||
|
|
||||||
r = (r*(32 - desaturation) + gray*desaturation) / 32;
|
|
||||||
g = (g*(32 - desaturation) + gray*desaturation) / 32;
|
|
||||||
b = (b*(32 - desaturation) + gray*desaturation) / 32;
|
|
||||||
}
|
|
||||||
glColor3f(r, g, b);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
bool gl_SetupLightTexture()
|
|
||||||
{
|
|
||||||
|
|
||||||
if (GLRenderer->gllight == NULL) return false;
|
|
||||||
FMaterial * pat = FMaterial::ValidateTexture(GLRenderer->gllight, true);
|
|
||||||
pat->Bind(CLAMP_XY, 0);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
|
@ -101,6 +101,7 @@ public:
|
||||||
void Initialize();
|
void Initialize();
|
||||||
|
|
||||||
void CreateScene();
|
void CreateScene();
|
||||||
|
void RenderMultipassStuff();
|
||||||
void RenderScene(int recursion);
|
void RenderScene(int recursion);
|
||||||
void RenderTranslucent();
|
void RenderTranslucent();
|
||||||
void DrawScene(bool toscreen = false);
|
void DrawScene(bool toscreen = false);
|
||||||
|
|
|
@ -57,8 +57,10 @@ enum Drawpasses
|
||||||
|
|
||||||
// these are only used with texture based dynamic lights
|
// these are only used with texture based dynamic lights
|
||||||
GLPASS_BASE, // untextured base for dynamic lights
|
GLPASS_BASE, // untextured base for dynamic lights
|
||||||
|
GLPASS_BASE_MASKED, // same but with active texture
|
||||||
GLPASS_LIGHTTEX, // lighttexture pass
|
GLPASS_LIGHTTEX, // lighttexture pass
|
||||||
GLPASS_TEXONLY // finishing texture pass
|
GLPASS_TEXONLY, // finishing texture pass
|
||||||
|
GLPASS_LIGHTTEX_ADDITIVE, // lighttexture pass (additive)
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -382,10 +382,10 @@ void FGLRenderer::RenderScene(int recursion)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Todo: Draw lights with multipass rendering.
|
// process everything that needs to handle textured dynamic lights.
|
||||||
// RenderMultpassStuff();
|
if (haslights) RenderMultipassStuff();
|
||||||
|
|
||||||
// The remaining stuff which is unaffected by dynamic lights is just processed as normal.
|
// The remaining lists which are unaffected by dynamic lights are just processed as normal.
|
||||||
pass = GLPASS_PLAIN;
|
pass = GLPASS_PLAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -813,8 +813,13 @@ bool Win32GLVideo::InitHardware (HWND Window, int multisample)
|
||||||
|
|
||||||
if (m_hRC == NULL && prof == WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB)
|
if (m_hRC == NULL && prof == WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB)
|
||||||
{
|
{
|
||||||
I_Error ("R_OPENGL: Unable to create an OpenGL render context.\n");
|
|
||||||
return false;
|
m_hRC = wglCreateContext(m_hDC);
|
||||||
|
if (m_hRC == NULL)
|
||||||
|
{
|
||||||
|
I_Error("R_OPENGL: Unable to create an OpenGL render context.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_hRC != NULL)
|
if (m_hRC != NULL)
|
||||||
|
|
Loading…
Reference in a new issue