mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2025-03-22 17:51:05 +00:00
Merge branch 'master' of https://github.com/coelckers/gzdoom
This commit is contained in:
commit
c4afa993f4
24 changed files with 616 additions and 251 deletions
|
@ -192,7 +192,7 @@ set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${DEB_C_FLAGS} -D_DEBUG" )
|
|||
option(FORCE_INTERNAL_ZLIB "Use internal zlib")
|
||||
option(FORCE_INTERNAL_JPEG "Use internal jpeg")
|
||||
option(FORCE_INTERNAL_BZIP2 "Use internal bzip2")
|
||||
option(FORCE_INTERNAL_GME "Use internal gme" ON)
|
||||
option(FORCE_INTERNAL_GME "Use internal gme")
|
||||
|
||||
# Fast math flags, required by some subprojects
|
||||
set( ZD_FASTMATH_FLAG "" )
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "gl/system/gl_cvars.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
|
||||
|
||||
//==========================================================================
|
||||
|
@ -67,8 +68,7 @@ void gl_PatchMenu()
|
|||
{
|
||||
if (gl.glslversion == 0)
|
||||
{
|
||||
// Radial fog and Doom lighting are not available in SM < 4 cards
|
||||
// The way they are implemented does not work well on older hardware.
|
||||
// Radial fog and Doom lighting are not available without full shader support.
|
||||
|
||||
FOptionValues **opt = OptionValues.CheckKey("LightingModes");
|
||||
if (opt != NULL)
|
||||
|
@ -376,8 +376,9 @@ void FRenderState::DrawColormapOverlay()
|
|||
// 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)
|
||||
float & scale, int desaturation, bool checkside, bool additive)
|
||||
{
|
||||
Vector fn, pos;
|
||||
|
||||
|
@ -392,7 +393,7 @@ bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, Vector & nearPt,
|
|||
{
|
||||
return false;
|
||||
}
|
||||
if (light->owned && light->target != NULL && !light->target->IsVisibleToPlayer())
|
||||
if (!light->visibletoplayer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -414,7 +415,7 @@ bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, Vector & nearPt,
|
|||
#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.
|
||||
if (additive) 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;
|
||||
|
@ -441,7 +442,7 @@ bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, Vector & nearPt,
|
|||
g = (g*(32 - desaturation) + gray*desaturation) / 32;
|
||||
b = (b*(32 - desaturation) + gray*desaturation) / 32;
|
||||
}
|
||||
glColor3f(r, g, b);
|
||||
gl_RenderState.SetColor(r, g, b);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -455,7 +456,7 @@ bool gl_SetupLightTexture()
|
|||
{
|
||||
if (GLRenderer->gllight == nullptr) return false;
|
||||
FMaterial * pat = FMaterial::ValidateTexture(GLRenderer->gllight, false);
|
||||
pat->Bind(CLAMP_XY, 0);
|
||||
pat->Bind(CLAMP_XY_NOMIP, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -486,7 +487,7 @@ bool GLWall::PutWallCompat(int passflag)
|
|||
if (sub->lighthead != nullptr) return false;
|
||||
}
|
||||
|
||||
bool foggy = (!gl_isBlack(Colormap.FadeColor) || level.flags&LEVEL_HASFADETABLE);
|
||||
bool foggy = !gl_isBlack(Colormap.FadeColor) || (level.flags&LEVEL_HASFADETABLE) || gl_lights_additive;
|
||||
bool masked = passflag == 2 && gltexture->isMasked();
|
||||
|
||||
int list = list_indices[masked][foggy];
|
||||
|
@ -500,6 +501,34 @@ bool GLWall::PutWallCompat(int passflag)
|
|||
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool GLFlat::PutFlatCompat(bool fog)
|
||||
{
|
||||
// are lights possible?
|
||||
if (gl_fixedcolormap != CM_DEFAULT || !gl_lights || !gltexture || renderstyle != STYLE_Translucent || alpha < 1.f - FLT_EPSILON || sector->lighthead == NULL) return false;
|
||||
|
||||
static int list_indices[2][2] =
|
||||
{ { GLLDL_FLATS_PLAIN, GLLDL_FLATS_FOG },{ GLLDL_FLATS_MASKED, GLLDL_FLATS_FOGMASKED } };
|
||||
|
||||
bool masked = gltexture->isMasked() && ((renderflags&SSRF_RENDER3DPLANES) || stack);
|
||||
bool foggy = gl_CheckFog(&Colormap, lightlevel) || (level.flags&LEVEL_HASFADETABLE) || gl_lights_additive;
|
||||
|
||||
|
||||
int list = list_indices[masked][foggy];
|
||||
if (list == GLLDL_FLATS_PLAIN)
|
||||
{
|
||||
if (gltexture->tex->gl_info.Brightmap && gl.glslversion >= 0.f) list = GLLDL_FLATS_BRIGHT;
|
||||
}
|
||||
gl_drawinfo->dldrawlists[list].AddFlat(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Fog boundary without any shader support
|
||||
|
@ -530,14 +559,14 @@ void GLWall::RenderFogBoundaryCompat()
|
|||
glDepthFunc(GL_LEQUAL);
|
||||
glColor4f(fc[0], fc[1], fc[2], fogd1);
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glTexCoord2f(lolft.u, lolft.v);
|
||||
glTexCoord2f(tcs[LOLFT].u, tcs[LOLFT].v);
|
||||
glVertex3f(glseg.x1, zbottom[0], glseg.y1);
|
||||
glTexCoord2f(uplft.u, uplft.v);
|
||||
glTexCoord2f(tcs[UPLFT].u, tcs[UPLFT].v);
|
||||
glVertex3f(glseg.x1, ztop[0], glseg.y1);
|
||||
glColor4f(fc[0], fc[1], fc[2], fogd2);
|
||||
glTexCoord2f(uprgt.u, uprgt.v);
|
||||
glTexCoord2f(tcs[UPRGT].u, tcs[UPRGT].v);
|
||||
glVertex3f(glseg.x2, ztop[1], glseg.y2);
|
||||
glTexCoord2f(lorgt.u, lorgt.v);
|
||||
glTexCoord2f(tcs[LORGT].u, tcs[LORGT].v);
|
||||
glVertex3f(glseg.x2, zbottom[1], glseg.y2);
|
||||
glEnd();
|
||||
glDepthFunc(GL_LESS);
|
||||
|
@ -548,6 +577,211 @@ void GLWall::RenderFogBoundaryCompat()
|
|||
gl_RenderState.EnableTexture(true);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Flats
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass)
|
||||
{
|
||||
Plane p;
|
||||
Vector nearPt, up, right, t1;
|
||||
float scale;
|
||||
|
||||
FLightNode * node = sub->lighthead;
|
||||
while (node)
|
||||
{
|
||||
ADynamicLight * light = node->lightsource;
|
||||
|
||||
if (light->flags2&MF2_DORMANT ||
|
||||
(pass == GLPASS_LIGHTTEX && light->IsAdditive()) ||
|
||||
(pass == GLPASS_LIGHTTEX_ADDITIVE && !light->IsAdditive()))
|
||||
{
|
||||
node = node->nextLight;
|
||||
continue;
|
||||
}
|
||||
|
||||
// we must do the side check here because gl_SetupLight needs the correct plane orientation
|
||||
// which we don't have for Legacy-style 3D-floors
|
||||
double planeh = plane.plane.ZatPoint(light);
|
||||
if (gl_lights_checkside && ((planeh<light->Z() && ceiling) || (planeh>light->Z() && !ceiling)))
|
||||
{
|
||||
node = node->nextLight;
|
||||
continue;
|
||||
}
|
||||
|
||||
p.Set(plane.plane);
|
||||
if (!gl_SetupLight(sub->sector->PortalGroup, p, light, nearPt, up, right, scale, CM_DEFAULT, false, pass != GLPASS_LIGHTTEX))
|
||||
{
|
||||
node = node->nextLight;
|
||||
continue;
|
||||
}
|
||||
gl_RenderState.Apply();
|
||||
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
for (unsigned int k = 0; k < sub->numlines; k++)
|
||||
{
|
||||
vertex_t *vt = sub->firstline[k].v1;
|
||||
ptr->x = vt->fX();
|
||||
ptr->z = plane.plane.ZatPoint(vt) + dz;
|
||||
ptr->y = vt->fY();
|
||||
t1.Set(ptr->x, ptr->z, ptr->y);
|
||||
Vector nearToVert = t1 - nearPt;
|
||||
|
||||
ptr->u = (nearToVert.Dot(right) * scale) + 0.5f;
|
||||
ptr->v = (nearToVert.Dot(up) * scale) + 0.5f;
|
||||
ptr++;
|
||||
}
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
|
||||
node = node->nextLight;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLFlat::DrawLightsCompat(int pass)
|
||||
{
|
||||
gl_RenderState.Apply();
|
||||
if (sub)
|
||||
{
|
||||
// This represents a single subsector
|
||||
DrawSubsectorLights(sub, pass);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw the subsectors belonging to this sector
|
||||
for (int i = 0; i<sector->subsectorcount; i++)
|
||||
{
|
||||
subsector_t * sub = sector->subsectors[i];
|
||||
if (gl_drawinfo->ss_renderflags[sub - subsectors] & renderflags)
|
||||
{
|
||||
DrawSubsectorLights(sub, pass);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the subsectors assigned to it due to missing textures
|
||||
if (!(renderflags&SSRF_RENDER3DPLANES))
|
||||
{
|
||||
gl_subsectorrendernode * node = (renderflags&SSRF_RENDERFLOOR) ?
|
||||
gl_drawinfo->GetOtherFloorPlanes(sector->sectornum) :
|
||||
gl_drawinfo->GetOtherCeilingPlanes(sector->sectornum);
|
||||
|
||||
while (node)
|
||||
{
|
||||
DrawSubsectorLights(sub, pass);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Sets up the texture coordinates for one light to be rendered
|
||||
//
|
||||
//==========================================================================
|
||||
bool GLWall::PrepareLight(ADynamicLight * light, int pass)
|
||||
{
|
||||
float vtx[] = { glseg.x1,zbottom[0],glseg.y1, glseg.x1,ztop[0],glseg.y1, glseg.x2,ztop[1],glseg.y2, glseg.x2,zbottom[1],glseg.y2 };
|
||||
Plane p;
|
||||
Vector nearPt, up, right;
|
||||
float scale;
|
||||
|
||||
p.Init(vtx, 4);
|
||||
|
||||
if (!p.ValidNormal())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!gl_SetupLight(seg->frontsector->PortalGroup, p, light, nearPt, up, right, scale, CM_DEFAULT, true, pass != GLPASS_LIGHTTEX))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tcs != NULL)
|
||||
{
|
||||
Vector t1;
|
||||
int outcnt[4] = { 0,0,0,0 };
|
||||
|
||||
for (int i = 0; i<4; i++)
|
||||
{
|
||||
t1.Set(&vtx[i * 3]);
|
||||
Vector nearToVert = t1 - nearPt;
|
||||
tcs[i].u = (nearToVert.Dot(right) * scale) + 0.5f;
|
||||
tcs[i].v = (nearToVert.Dot(up) * scale) + 0.5f;
|
||||
|
||||
// quick check whether the light touches this polygon
|
||||
if (tcs[i].u<0) outcnt[0]++;
|
||||
if (tcs[i].u>1) outcnt[1]++;
|
||||
if (tcs[i].v<0) outcnt[2]++;
|
||||
if (tcs[i].v>1) outcnt[3]++;
|
||||
|
||||
}
|
||||
// The light doesn't touch this polygon
|
||||
if (outcnt[0] == 4 || outcnt[1] == 4 || outcnt[2] == 4 || outcnt[3] == 4) return false;
|
||||
}
|
||||
|
||||
draw_dlight++;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void GLWall::RenderLightsCompat(int pass)
|
||||
{
|
||||
FLightNode * node;
|
||||
|
||||
// black fog is diminishing light and should affect lights less than the rest!
|
||||
if (pass == GLPASS_LIGHTTEX) gl_SetFog((255 + lightlevel) >> 1, 0, NULL, false);
|
||||
else gl_SetFog(lightlevel, 0, &Colormap, true);
|
||||
|
||||
if (seg->sidedef == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (!(seg->sidedef->Flags & WALLF_POLYOBJ))
|
||||
{
|
||||
// Iterate through all dynamic lights which touch this wall and render them
|
||||
node = seg->sidedef->lighthead;
|
||||
}
|
||||
else if (sub)
|
||||
{
|
||||
// To avoid constant rechecking for polyobjects use the subsector's lightlist instead
|
||||
node = sub->lighthead;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
texcoord save[4];
|
||||
memcpy(save, tcs, sizeof(tcs));
|
||||
while (node)
|
||||
{
|
||||
ADynamicLight * light = node->lightsource;
|
||||
|
||||
if (light->flags2&MF2_DORMANT ||
|
||||
(pass == GLPASS_LIGHTTEX && light->IsAdditive()) ||
|
||||
(pass == GLPASS_LIGHTTEX_ADDITIVE && !light->IsAdditive()))
|
||||
{
|
||||
node = node->nextLight;
|
||||
continue;
|
||||
}
|
||||
if (PrepareLight(light, pass))
|
||||
{
|
||||
RenderWall(RWF_TEXTURED, NULL);
|
||||
}
|
||||
node = node->nextLight;
|
||||
}
|
||||
memcpy(tcs, save, sizeof(tcs));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -556,7 +790,6 @@ void GLWall::RenderFogBoundaryCompat()
|
|||
|
||||
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
|
||||
|
@ -565,25 +798,28 @@ void FGLRenderer::RenderMultipassStuff()
|
|||
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);
|
||||
gl_drawinfo->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(GLPASS_PLAIN);
|
||||
gl_drawinfo->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(GLPASS_PLAIN);
|
||||
|
||||
// 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);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
|
||||
gl_drawinfo->dldrawlists[GLLDL_WALLS_BRIGHT].DrawWalls(GLPASS_PLAIN);
|
||||
gl_drawinfo->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(GLPASS_PLAIN);
|
||||
gl_drawinfo->dldrawlists[GLLDL_FLATS_BRIGHT].DrawFlats(GLPASS_PLAIN);
|
||||
gl_drawinfo->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(GLPASS_PLAIN);
|
||||
|
||||
// Part 3: The base of fogged surfaces, including the texture
|
||||
gl_RenderState.EnableBrightmap(false);
|
||||
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0);
|
||||
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_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
|
||||
gl_drawinfo->dldrawlists[GLLDL_WALLS_FOGMASKED].DrawWalls(GLPASS_PLAIN);
|
||||
gl_drawinfo->dldrawlists[GLLDL_FLATS_FOGMASKED].DrawFlats(GLPASS_PLAIN);
|
||||
|
||||
// second pass: draw lights
|
||||
|
@ -632,11 +868,18 @@ void FGLRenderer::RenderMultipassStuff()
|
|||
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);
|
||||
gl_drawinfo->dldrawlists[GLLDL_WALLS_FOG].DrawWalls(GLPASS_LIGHTTEX_FOGGY);
|
||||
gl_drawinfo->dldrawlists[GLLDL_WALLS_FOGMASKED].DrawWalls(GLPASS_LIGHTTEX_FOGGY);
|
||||
gl_drawinfo->dldrawlists[GLLDL_FLATS_FOG].DrawFlats(GLPASS_LIGHTTEX_FOGGY);
|
||||
gl_drawinfo->dldrawlists[GLLDL_FLATS_FOGMASKED].DrawFlats(GLPASS_LIGHTTEX_FOGGY);
|
||||
}
|
||||
else gl_lights = false;
|
||||
|
||||
glDepthFunc(GL_LESS);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
gl_RenderState.EnableFog(true);
|
||||
gl_RenderState.BlendFunc(GL_ONE, GL_ZERO);
|
||||
glDepthMask(true);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -160,6 +160,7 @@ void ADynamicLight::BeginPlay()
|
|||
|
||||
m_Radius[0] = args[LIGHT_INTENSITY];
|
||||
m_Radius[1] = args[LIGHT_SECONDARY_INTENSITY];
|
||||
visibletoplayer = true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -237,6 +238,7 @@ void ADynamicLight::Tick()
|
|||
return;
|
||||
}
|
||||
if (target->flags & MF_UNMORPHED) return;
|
||||
visibletoplayer = target->IsVisibleToPlayer(); // cache this value for the renderer to speed up calculations.
|
||||
}
|
||||
|
||||
// Don't bother if the light won't be shown
|
||||
|
|
|
@ -116,6 +116,7 @@ public:
|
|||
bool owned;
|
||||
bool halo;
|
||||
BYTE color2[3];
|
||||
bool visibletoplayer;
|
||||
int bufferindex;
|
||||
|
||||
// intermediate texture coordinate data
|
||||
|
|
|
@ -170,7 +170,10 @@ FModelVertex *FModelVertexBuffer::LockVertexBuffer(unsigned int size)
|
|||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
glBufferData(GL_ARRAY_BUFFER, size * sizeof(FModelVertex), nullptr, GL_STATIC_DRAW);
|
||||
return (FModelVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, size * sizeof(FModelVertex), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
if (gl.version >= 3.0)
|
||||
return (FModelVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, size * sizeof(FModelVertex), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
else
|
||||
return (FModelVertex*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -208,7 +211,10 @@ unsigned int *FModelVertexBuffer::LockIndexBuffer(unsigned int size)
|
|||
{
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size * sizeof(unsigned int), NULL, GL_STATIC_DRAW);
|
||||
return (unsigned int*)glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, size * sizeof(unsigned int), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
if (gl.version >= 3.0)
|
||||
return (unsigned int*)glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, size * sizeof(unsigned int), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
else
|
||||
return (unsigned int*)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -519,6 +525,7 @@ void gl_InitModels()
|
|||
{
|
||||
if (sc.Compare("model"))
|
||||
{
|
||||
path = "";
|
||||
sc.MustGetString();
|
||||
memset(&smf, 0, sizeof(smf));
|
||||
smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1;
|
||||
|
@ -529,7 +536,6 @@ void gl_InitModels()
|
|||
{
|
||||
sc.ScriptError("MODELDEF: Unknown actor type '%s'\n", sc.String);
|
||||
}
|
||||
GetDefaultByType(smf.type)->hasmodel=true;
|
||||
sc.MustGetStringName("{");
|
||||
while (!sc.CheckString("}"))
|
||||
{
|
||||
|
@ -743,6 +749,7 @@ void gl_InitModels()
|
|||
if (map[c]) continue;
|
||||
smf.frame=c;
|
||||
SpriteModelFrames.Push(smf);
|
||||
GetDefaultByType(smf.type)->hasmodel = true;
|
||||
map[c]=1;
|
||||
}
|
||||
}
|
||||
|
@ -933,16 +940,19 @@ void gl_RenderModel(GLSprite * spr)
|
|||
const double x = spr->actor->Vel.X;
|
||||
const double y = spr->actor->Vel.Y;
|
||||
const double z = spr->actor->Vel.Z;
|
||||
|
||||
// [BB] Calculate the pitch using spherical coordinates.
|
||||
if(z || x || y) pitch = float(atan( z/sqrt(x*x+y*y) ) / M_PI * 180);
|
||||
|
||||
// Correcting pitch if model is moving backwards
|
||||
if(x || y)
|
||||
|
||||
if (spr->actor->Vel.LengthSquared() > EQUAL_EPSILON)
|
||||
{
|
||||
if((x * cos(angle * M_PI / 180) + y * sin(angle * M_PI / 180)) / sqrt(x * x + y * y) < 0) pitch *= -1;
|
||||
// [BB] Calculate the pitch using spherical coordinates.
|
||||
if (z || x || y) pitch = float(atan(z / sqrt(x*x + y*y)) / M_PI * 180);
|
||||
|
||||
// Correcting pitch if model is moving backwards
|
||||
if (fabs(x) > EQUAL_EPSILON || fabs(y) > EQUAL_EPSILON)
|
||||
{
|
||||
if ((x * cos(angle * M_PI / 180) + y * sin(angle * M_PI / 180)) / sqrt(x * x + y * y) < 0) pitch *= -1;
|
||||
}
|
||||
else pitch = fabs(pitch);
|
||||
}
|
||||
else pitch = fabs(pitch);
|
||||
}
|
||||
|
||||
if( smf->flags & MDL_ROTATING )
|
||||
|
@ -964,7 +974,7 @@ void gl_RenderModel(GLSprite * spr)
|
|||
// Applying model transformations:
|
||||
// 1) Applying actor angle, pitch and roll to the model
|
||||
gl_RenderState.mModelMatrix.rotate(-angle, 0, 1, 0);
|
||||
gl_RenderState.mModelMatrix.rotate(pitch, 0, 0, 1);
|
||||
gl_RenderState.mModelMatrix.rotate(-pitch, 0, 0, 1);
|
||||
gl_RenderState.mModelMatrix.rotate(-roll, 1, 0, 0);
|
||||
|
||||
// 2) Applying Doomsday like rotation of the weapon pickup models
|
||||
|
|
|
@ -95,7 +95,7 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb)
|
|||
mSkyVBO = NULL;
|
||||
gl_spriteindex = 0;
|
||||
mShaderManager = NULL;
|
||||
glpart2 = glpart = mirrortexture = NULL;
|
||||
gllight = glpart2 = glpart = mirrortexture = NULL;
|
||||
mLights = NULL;
|
||||
}
|
||||
|
||||
|
@ -112,6 +112,7 @@ void FGLRenderer::Initialize()
|
|||
}
|
||||
else mVAOID = 0;
|
||||
|
||||
gllight = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/gllight.png"), FTexture::TEX_MiscPatch);
|
||||
glpart2 = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/glpart2.png"), FTexture::TEX_MiscPatch);
|
||||
glpart = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/glpart.png"), FTexture::TEX_MiscPatch);
|
||||
mirrortexture = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/mirror.png"), FTexture::TEX_MiscPatch);
|
||||
|
@ -350,7 +351,7 @@ void FGLRenderer::DrawTexture(FTexture *img, DrawParms &parms)
|
|||
if (pal) translation = -pal->GetIndex();
|
||||
}
|
||||
}
|
||||
gl_RenderState.SetMaterial(gltex, CLAMP_XY_NOMIP, translation, 0, !!(parms.style.Flags & STYLEF_RedIsAlpha));
|
||||
gl_RenderState.SetMaterial(gltex, CLAMP_XY_NOMIP, translation, -1, !!(parms.style.Flags & STYLEF_RedIsAlpha));
|
||||
|
||||
u1 = gltex->GetUL();
|
||||
v1 = gltex->GetVT();
|
||||
|
|
|
@ -326,7 +326,7 @@ void GLDrawList::SortWallIntoPlane(SortNode * head,SortNode * sort)
|
|||
GLWall * ws1;
|
||||
ws1=&walls[walls.Size()-1];
|
||||
ws=&walls[drawitems[sort->itemindex].index]; // may have been reallocated!
|
||||
float newtexv = ws->uplft.v + ((ws->lolft.v - ws->uplft.v) / (ws->zbottom[0] - ws->ztop[0])) * (fh->z - ws->ztop[0]);
|
||||
float newtexv = ws->tcs[GLWall::UPLFT].v + ((ws->tcs[GLWall::LOLFT].v - ws->tcs[GLWall::UPLFT].v) / (ws->zbottom[0] - ws->ztop[0])) * (fh->z - ws->ztop[0]);
|
||||
|
||||
// I make the very big assumption here that translucent walls in sloped sectors
|
||||
// and 3D-floors never coexist in the same level. If that were the case this
|
||||
|
@ -334,12 +334,12 @@ void GLDrawList::SortWallIntoPlane(SortNode * head,SortNode * sort)
|
|||
if (!ceiling)
|
||||
{
|
||||
ws->ztop[1] = ws1->zbottom[1] = ws->ztop[0] = ws1->zbottom[0] = fh->z;
|
||||
ws->uprgt.v = ws1->lorgt.v = ws->uplft.v = ws1->lolft.v = newtexv;
|
||||
ws->tcs[GLWall::UPRGT].v = ws1->tcs[GLWall::LORGT].v = ws->tcs[GLWall::UPLFT].v = ws1->tcs[GLWall::LOLFT].v = newtexv;
|
||||
}
|
||||
else
|
||||
{
|
||||
ws1->ztop[1] = ws->zbottom[1] = ws1->ztop[0] = ws->zbottom[0] = fh->z;
|
||||
ws1->uplft.v = ws->lolft.v = ws1->uprgt.v = ws->lorgt.v=newtexv;
|
||||
ws1->tcs[GLWall::UPLFT].v = ws->tcs[GLWall::LOLFT].v = ws1->tcs[GLWall::UPRGT].v = ws->tcs[GLWall::LORGT].v=newtexv;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -462,7 +462,7 @@ void GLDrawList::SortWallIntoWall(SortNode * head,SortNode * sort)
|
|||
|
||||
float ix=(float)(ws->glseg.x1+r*(ws->glseg.x2-ws->glseg.x1));
|
||||
float iy=(float)(ws->glseg.y1+r*(ws->glseg.y2-ws->glseg.y1));
|
||||
float iu=(float)(ws->uplft.u + r * (ws->uprgt.u - ws->uplft.u));
|
||||
float iu=(float)(ws->tcs[GLWall::UPLFT].u + r * (ws->tcs[GLWall::UPRGT].u - ws->tcs[GLWall::UPLFT].u));
|
||||
float izt=(float)(ws->ztop[0]+r*(ws->ztop[1]-ws->ztop[0]));
|
||||
float izb=(float)(ws->zbottom[0]+r*(ws->zbottom[1]-ws->zbottom[0]));
|
||||
|
||||
|
@ -475,7 +475,7 @@ void GLDrawList::SortWallIntoWall(SortNode * head,SortNode * sort)
|
|||
ws1->glseg.y1=ws->glseg.y2=iy;
|
||||
ws1->ztop[0]=ws->ztop[1]=izt;
|
||||
ws1->zbottom[0]=ws->zbottom[1]=izb;
|
||||
ws1->lolft.u = ws1->uplft.u = ws->lorgt.u = ws->uprgt.u = iu;
|
||||
ws1->tcs[GLWall::LOLFT].u = ws1->tcs[GLWall::UPLFT].u = ws->tcs[GLWall::LORGT].u = ws->tcs[GLWall::UPRGT].u = iu;
|
||||
|
||||
SortNode * sort2=SortNodes.GetNew();
|
||||
memset(sort2,0,sizeof(SortNode));
|
||||
|
|
|
@ -61,6 +61,7 @@ enum Drawpasses
|
|||
GLPASS_LIGHTTEX, // lighttexture pass
|
||||
GLPASS_TEXONLY, // finishing texture pass
|
||||
GLPASS_LIGHTTEX_ADDITIVE, // lighttexture pass (additive)
|
||||
GLPASS_LIGHTTEX_FOGGY, // lighttexture pass on foggy surfaces (forces all lights to be additive)
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -443,6 +443,11 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG
|
|||
}
|
||||
if (renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
break;
|
||||
|
||||
case GLPASS_LIGHTTEX:
|
||||
case GLPASS_LIGHTTEX_ADDITIVE:
|
||||
DrawLightsCompat(pass);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -463,6 +468,10 @@ inline void GLFlat::PutFlat(bool fog)
|
|||
{
|
||||
Colormap.Clear();
|
||||
}
|
||||
if (gl.lightmethod == LM_SOFTWARE)
|
||||
{
|
||||
if (PutFlatCompat(fog)) return;
|
||||
}
|
||||
if (renderstyle!=STYLE_Translucent || alpha < 1.f - FLT_EPSILON || fog || gltexture == NULL)
|
||||
{
|
||||
// translucent 3D floors go into the regular translucent list, translucent portals go into the translucent border list.
|
||||
|
|
|
@ -596,8 +596,12 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
|
|||
{
|
||||
if (!(thing->flags7 & MF7_FLYCHEAT) && thing->target == GLRenderer->mViewActor && GLRenderer->mViewActor != NULL)
|
||||
{
|
||||
double clipdist = clamp(thing->Speed, thing->target->radius, thing->target->radius * 2);
|
||||
if ((thingpos - ViewPos).LengthSquared() < clipdist * clipdist) return;
|
||||
double speed = thing->Vel.Length();
|
||||
if (speed >= thing->target->radius / 2)
|
||||
{
|
||||
double clipdist = clamp(thing->Speed, thing->target->radius, thing->target->radius * 2);
|
||||
if ((thingpos - ViewPos).LengthSquared() < clipdist * clipdist) return;
|
||||
}
|
||||
}
|
||||
thing->flags7 |= MF7_FLYCHEAT; // do this only once for the very first frame, but not if it gets into range again.
|
||||
}
|
||||
|
|
|
@ -75,57 +75,52 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *
|
|||
while (node)
|
||||
{
|
||||
light=node->lightsource;
|
||||
//if (!light->owned || light->target == NULL || light->target->IsVisibleToPlayer())
|
||||
if (light->visibletoplayer && !(light->flags2&MF2_DORMANT) && (!(light->flags4&MF4_DONTLIGHTSELF) || light->target != self))
|
||||
{
|
||||
if (!(light->flags2&MF2_DORMANT) &&
|
||||
(!(light->flags4&MF4_DONTLIGHTSELF) || light->target != self))
|
||||
float dist;
|
||||
|
||||
// This is a performance critical section of code where we cannot afford to let the compiler decide whether to inline the function or not.
|
||||
// This will do the calculations explicitly rather than calling one of AActor's utility functions.
|
||||
if (Displacements.size > 0)
|
||||
{
|
||||
float dist;
|
||||
int fromgroup = light->Sector->PortalGroup;
|
||||
int togroup = subsec->sector->PortalGroup;
|
||||
if (fromgroup == togroup || fromgroup == 0 || togroup == 0) goto direct;
|
||||
|
||||
// This is a performance critical section of code where we cannot afford to let the compiler decide whether to inline the function or not.
|
||||
// This will do the calculations explicitly rather than calling one of AActor's utility functions.
|
||||
if (Displacements.size > 0)
|
||||
DVector2 offset = Displacements.getOffset(fromgroup, togroup);
|
||||
dist = FVector3(x - light->X() - offset.X, y - light->Y() - offset.Y, z - light->Z()).LengthSquared();
|
||||
}
|
||||
else
|
||||
{
|
||||
direct:
|
||||
dist = FVector3(x - light->X(), y - light->Y(), z - light->Z()).LengthSquared();
|
||||
}
|
||||
|
||||
radius = light->GetRadius() * gl_lights_size;
|
||||
|
||||
if (dist < radius * radius)
|
||||
{
|
||||
dist = sqrtf(dist); // only calculate the square root if we really need it.
|
||||
|
||||
frac = 1.0f - (dist / radius);
|
||||
|
||||
if (frac > 0)
|
||||
{
|
||||
int fromgroup = light->Sector->PortalGroup;
|
||||
int togroup = subsec->sector->PortalGroup;
|
||||
if (fromgroup == togroup || fromgroup == 0 || togroup == 0) goto direct;
|
||||
|
||||
DVector2 offset = Displacements.getOffset(fromgroup, togroup);
|
||||
dist = FVector3(x - light->X() - offset.X, y - light->Y() - offset.Y, z - light->Z()).LengthSquared();
|
||||
}
|
||||
else
|
||||
{
|
||||
direct:
|
||||
dist = FVector3(x - light->X(), y - light->Y(), z - light->Z()).LengthSquared();
|
||||
}
|
||||
// This is to avoid calling the software-implemented sqrt function which gets used by FVector3::Length().
|
||||
// With fast math on in this module this call will be mapped to a machine instruction on most platforms.
|
||||
dist = sqrtf(dist);
|
||||
|
||||
radius = light->GetRadius() * gl_lights_size;
|
||||
|
||||
if (dist < radius)
|
||||
{
|
||||
frac = 1.0f - (dist / radius);
|
||||
|
||||
if (frac > 0)
|
||||
lr = light->GetRed() / 255.0f * gl_lights_intensity;
|
||||
lg = light->GetGreen() / 255.0f * gl_lights_intensity;
|
||||
lb = light->GetBlue() / 255.0f * gl_lights_intensity;
|
||||
if (light->IsSubtractive())
|
||||
{
|
||||
lr = light->GetRed() / 255.0f * gl_lights_intensity;
|
||||
lg = light->GetGreen() / 255.0f * gl_lights_intensity;
|
||||
lb = light->GetBlue() / 255.0f * gl_lights_intensity;
|
||||
if (light->IsSubtractive())
|
||||
{
|
||||
float bright = FVector3(lr, lg, lb).Length();
|
||||
FVector3 lightColor(lr, lg, lb);
|
||||
lr = (bright - lr) * -1;
|
||||
lg = (bright - lg) * -1;
|
||||
lb = (bright - lb) * -1;
|
||||
}
|
||||
|
||||
out[0] += lr * frac;
|
||||
out[1] += lg * frac;
|
||||
out[2] += lb * frac;
|
||||
float bright = FVector3(lr, lg, lb).Length();
|
||||
FVector3 lightColor(lr, lg, lb);
|
||||
lr = (bright - lr) * -1;
|
||||
lg = (bright - lg) * -1;
|
||||
lb = (bright - lb) * -1;
|
||||
}
|
||||
|
||||
out[0] += lr * frac;
|
||||
out[1] += lg * frac;
|
||||
out[2] += lb * frac;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,14 +61,14 @@ EXTERN_CVAR(Bool, gl_seamless)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLWall::SplitUpperEdge(texcoord * tcs, FFlatVertex *&ptr)
|
||||
void GLWall::SplitUpperEdge(FFlatVertex *&ptr)
|
||||
{
|
||||
if (seg == NULL || seg->sidedef == NULL || (seg->sidedef->Flags & WALLF_POLYOBJ) || seg->sidedef->numsegs == 1) return;
|
||||
|
||||
side_t *sidedef = seg->sidedef;
|
||||
float polyw = glseg.fracright - glseg.fracleft;
|
||||
float facu = (tcs[2].u - tcs[1].u) / polyw;
|
||||
float facv = (tcs[2].v - tcs[1].v) / polyw;
|
||||
float facu = (tcs[UPRGT].u - tcs[UPLFT].u) / polyw;
|
||||
float facv = (tcs[UPRGT].v - tcs[UPLFT].v) / polyw;
|
||||
float fact = (ztop[1] - ztop[0]) / polyw;
|
||||
float facc = (zceil[1] - zceil[0]) / polyw;
|
||||
float facf = (zfloor[1] - zfloor[0]) / polyw;
|
||||
|
@ -85,8 +85,8 @@ void GLWall::SplitUpperEdge(texcoord * tcs, FFlatVertex *&ptr)
|
|||
ptr->x = cseg->v2->fX();
|
||||
ptr->y = cseg->v2->fY();
|
||||
ptr->z = ztop[0] + fact * fracfac;
|
||||
ptr->u = tcs[1].u + facu * fracfac;
|
||||
ptr->v = tcs[1].v + facv * fracfac;
|
||||
ptr->u = tcs[UPLFT].u + facu * fracfac;
|
||||
ptr->v = tcs[UPLFT].v + facv * fracfac;
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
@ -97,14 +97,14 @@ void GLWall::SplitUpperEdge(texcoord * tcs, FFlatVertex *&ptr)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLWall::SplitLowerEdge(texcoord * tcs, FFlatVertex *&ptr)
|
||||
void GLWall::SplitLowerEdge(FFlatVertex *&ptr)
|
||||
{
|
||||
if (seg == NULL || seg->sidedef == NULL || (seg->sidedef->Flags & WALLF_POLYOBJ) || seg->sidedef->numsegs == 1) return;
|
||||
|
||||
side_t *sidedef = seg->sidedef;
|
||||
float polyw = glseg.fracright - glseg.fracleft;
|
||||
float facu = (tcs[3].u - tcs[0].u) / polyw;
|
||||
float facv = (tcs[3].v - tcs[0].v) / polyw;
|
||||
float facu = (tcs[LORGT].u - tcs[LOLFT].u) / polyw;
|
||||
float facv = (tcs[LORGT].v - tcs[LOLFT].v) / polyw;
|
||||
float facb = (zbottom[1] - zbottom[0]) / polyw;
|
||||
float facc = (zceil[1] - zceil[0]) / polyw;
|
||||
float facf = (zfloor[1] - zfloor[0]) / polyw;
|
||||
|
@ -121,8 +121,8 @@ void GLWall::SplitLowerEdge(texcoord * tcs, FFlatVertex *&ptr)
|
|||
ptr->x = cseg->v2->fX();
|
||||
ptr->y = cseg->v2->fY();
|
||||
ptr->z = zbottom[0] + facb * fracfac;
|
||||
ptr->u = tcs[0].u + facu * fracfac;
|
||||
ptr->v = tcs[0].v + facv * fracfac;
|
||||
ptr->u = tcs[LOLFT].u + facu * fracfac;
|
||||
ptr->v = tcs[LOLFT].v + facv * fracfac;
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ void GLWall::SplitLowerEdge(texcoord * tcs, FFlatVertex *&ptr)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLWall::SplitLeftEdge(texcoord * tcs, FFlatVertex *&ptr)
|
||||
void GLWall::SplitLeftEdge(FFlatVertex *&ptr)
|
||||
{
|
||||
if (vertexes[0] == NULL) return;
|
||||
|
||||
|
@ -144,8 +144,8 @@ void GLWall::SplitLeftEdge(texcoord * tcs, FFlatVertex *&ptr)
|
|||
int i = 0;
|
||||
|
||||
float polyh1 = ztop[0] - zbottom[0];
|
||||
float factv1 = polyh1 ? (tcs[1].v - tcs[0].v) / polyh1 : 0;
|
||||
float factu1 = polyh1 ? (tcs[1].u - tcs[0].u) / polyh1 : 0;
|
||||
float factv1 = polyh1 ? (tcs[UPLFT].v - tcs[LOLFT].v) / polyh1 : 0;
|
||||
float factu1 = polyh1 ? (tcs[UPLFT].u - tcs[LOLFT].u) / polyh1 : 0;
|
||||
|
||||
while (i<vi->numheights && vi->heightlist[i] <= zbottom[0]) i++;
|
||||
while (i<vi->numheights && vi->heightlist[i] < ztop[0])
|
||||
|
@ -153,8 +153,8 @@ void GLWall::SplitLeftEdge(texcoord * tcs, FFlatVertex *&ptr)
|
|||
ptr->x = glseg.x1;
|
||||
ptr->y = glseg.y1;
|
||||
ptr->z = vi->heightlist[i];
|
||||
ptr->u = factu1*(vi->heightlist[i] - ztop[0]) + tcs[1].u;
|
||||
ptr->v = factv1*(vi->heightlist[i] - ztop[0]) + tcs[1].v;
|
||||
ptr->u = factu1*(vi->heightlist[i] - ztop[0]) + tcs[UPLFT].u;
|
||||
ptr->v = factv1*(vi->heightlist[i] - ztop[0]) + tcs[UPLFT].v;
|
||||
ptr++;
|
||||
i++;
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ void GLWall::SplitLeftEdge(texcoord * tcs, FFlatVertex *&ptr)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLWall::SplitRightEdge(texcoord * tcs, FFlatVertex *&ptr)
|
||||
void GLWall::SplitRightEdge(FFlatVertex *&ptr)
|
||||
{
|
||||
if (vertexes[1] == NULL) return;
|
||||
|
||||
|
@ -178,8 +178,8 @@ void GLWall::SplitRightEdge(texcoord * tcs, FFlatVertex *&ptr)
|
|||
int i = vi->numheights - 1;
|
||||
|
||||
float polyh2 = ztop[1] - zbottom[1];
|
||||
float factv2 = polyh2 ? (tcs[2].v - tcs[3].v) / polyh2 : 0;
|
||||
float factu2 = polyh2 ? (tcs[2].u - tcs[3].u) / polyh2 : 0;
|
||||
float factv2 = polyh2 ? (tcs[UPRGT].v - tcs[LORGT].v) / polyh2 : 0;
|
||||
float factu2 = polyh2 ? (tcs[UPRGT].u - tcs[LORGT].u) / polyh2 : 0;
|
||||
|
||||
while (i>0 && vi->heightlist[i] >= ztop[1]) i--;
|
||||
while (i>0 && vi->heightlist[i] > zbottom[1])
|
||||
|
@ -187,8 +187,8 @@ void GLWall::SplitRightEdge(texcoord * tcs, FFlatVertex *&ptr)
|
|||
ptr->x = glseg.x2;
|
||||
ptr->y = glseg.y2;
|
||||
ptr->z = vi->heightlist[i];
|
||||
ptr->u = factu2*(vi->heightlist[i] - ztop[1]) + tcs[2].u;
|
||||
ptr->v = factv2*(vi->heightlist[i] - ztop[1]) + tcs[2].v;
|
||||
ptr->u = factu2*(vi->heightlist[i] - ztop[1]) + tcs[UPRGT].u;
|
||||
ptr->v = factv2*(vi->heightlist[i] - ztop[1]) + tcs[UPRGT].v;
|
||||
ptr++;
|
||||
i--;
|
||||
}
|
||||
|
|
|
@ -119,6 +119,13 @@ public:
|
|||
RWF_NORENDER = 8,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOLFT,
|
||||
UPLFT,
|
||||
UPRGT,
|
||||
LORGT,
|
||||
};
|
||||
|
||||
friend struct GLDrawList;
|
||||
friend class GLPortal;
|
||||
|
@ -126,7 +133,7 @@ public:
|
|||
GLSeg glseg;
|
||||
vertex_t * vertexes[2]; // required for polygon splitting
|
||||
float ztop[2],zbottom[2];
|
||||
texcoord uplft, uprgt, lolft, lorgt;
|
||||
texcoord tcs[4];
|
||||
float alpha;
|
||||
FMaterial *gltexture;
|
||||
|
||||
|
@ -177,13 +184,14 @@ private:
|
|||
void CheckTexturePosition();
|
||||
|
||||
void RenderFogBoundaryCompat();
|
||||
void RenderLightsCompat(int pass);
|
||||
|
||||
void Put3DWall(lightlist_t * lightlist, bool translucent);
|
||||
void SplitWallComplex(sector_t * frontsector, bool translucent, float maplightbottomleft, float maplightbottomright);
|
||||
void SplitWall(sector_t * frontsector, bool translucent);
|
||||
|
||||
void SetupLights();
|
||||
bool PrepareLight(texcoord * tcs, ADynamicLight * light);
|
||||
bool PrepareLight(ADynamicLight * light, int pass);
|
||||
void RenderWall(int textured, unsigned int *store = NULL);
|
||||
void RenderTextured(int rflags);
|
||||
|
||||
|
@ -236,10 +244,10 @@ private:
|
|||
void RenderMirrorSurface();
|
||||
void RenderTranslucentWall();
|
||||
|
||||
void SplitLeftEdge(texcoord * tcs, FFlatVertex *&ptr);
|
||||
void SplitRightEdge(texcoord * tcs, FFlatVertex *&ptr);
|
||||
void SplitUpperEdge(texcoord * tcs, FFlatVertex *&ptr);
|
||||
void SplitLowerEdge(texcoord * tcs, FFlatVertex *&ptr);
|
||||
void SplitLeftEdge (FFlatVertex *&ptr);
|
||||
void SplitRightEdge(FFlatVertex *&ptr);
|
||||
void SplitUpperEdge(FFlatVertex *&ptr);
|
||||
void SplitLowerEdge(FFlatVertex *&ptr);
|
||||
|
||||
public:
|
||||
|
||||
|
@ -288,7 +296,6 @@ public:
|
|||
GLSectorPlane plane;
|
||||
int lightlevel;
|
||||
bool stack;
|
||||
bool foggy;
|
||||
bool ceiling;
|
||||
BYTE renderflags;
|
||||
int vboindex;
|
||||
|
@ -296,9 +303,13 @@ public:
|
|||
|
||||
int dynlightindex;
|
||||
|
||||
// compatibility fallback stuff.
|
||||
void DrawSubsectorLights(subsector_t * sub, int pass);
|
||||
void DrawLightsCompat(int pass);
|
||||
bool PutFlatCompat(bool fog);
|
||||
|
||||
void SetupSubsectorLights(int pass, subsector_t * sub, int *dli = NULL);
|
||||
void DrawSubsector(subsector_t * sub);
|
||||
void DrawSubsectorLights(subsector_t * sub, int pass);
|
||||
void DrawSkyboxSector(int pass, bool processlights);
|
||||
void DrawSubsectors(int pass, bool processlights, bool istrans);
|
||||
void ProcessLights(bool istrans);
|
||||
|
|
|
@ -142,7 +142,7 @@ void GLWall::PutWall(bool translucent)
|
|||
if (gl.lightmethod == LM_SOFTWARE && !translucent)
|
||||
{
|
||||
// This is not yet ready.
|
||||
//if (PutWallCompat(passflag[type])) return;
|
||||
if (PutWallCompat(passflag[type])) return;
|
||||
}
|
||||
|
||||
bool masked;
|
||||
|
@ -297,10 +297,10 @@ void GLWall::SplitWallComplex(sector_t * frontsector, bool translucent, float ma
|
|||
copyWall1.ztop[1] = copyWall2.ztop[0] = ztop[0] + coeff * (ztop[1] - ztop[0]);
|
||||
copyWall1.zbottom[1] = copyWall2.zbottom[0] = zbottom[0] + coeff * (zbottom[1] - zbottom[0]);
|
||||
copyWall1.glseg.fracright = copyWall2.glseg.fracleft = glseg.fracleft + coeff * (glseg.fracright - glseg.fracleft);
|
||||
copyWall1.uprgt.u = copyWall2.uplft.u = uplft.u + coeff * (uprgt.u - uplft.u);
|
||||
copyWall1.uprgt.v = copyWall2.uplft.v = uplft.v + coeff * (uprgt.v - uplft.v);
|
||||
copyWall1.lorgt.u = copyWall2.lolft.u = lolft.u + coeff * (lorgt.u - lolft.u);
|
||||
copyWall1.lorgt.v = copyWall2.lolft.v = lolft.v + coeff * (lorgt.v - lolft.v);
|
||||
copyWall1.tcs[UPRGT].u = copyWall2.tcs[UPLFT].u = tcs[UPLFT].u + coeff * (tcs[UPRGT].u - tcs[UPLFT].u);
|
||||
copyWall1.tcs[UPRGT].v = copyWall2.tcs[UPLFT].v = tcs[UPLFT].v + coeff * (tcs[UPRGT].v - tcs[UPLFT].v);
|
||||
copyWall1.tcs[LORGT].u = copyWall2.tcs[LOLFT].u = tcs[LOLFT].u + coeff * (tcs[LORGT].u - tcs[LOLFT].u);
|
||||
copyWall1.tcs[LORGT].v = copyWall2.tcs[LOLFT].v = tcs[LOLFT].v + coeff * (tcs[LORGT].v - tcs[LOLFT].v);
|
||||
|
||||
copyWall1.SplitWall(frontsector, translucent);
|
||||
copyWall2.SplitWall(frontsector, translucent);
|
||||
|
@ -338,10 +338,10 @@ void GLWall::SplitWallComplex(sector_t * frontsector, bool translucent, float ma
|
|||
copyWall1.ztop[1] = copyWall2.ztop[0] = ztop[0] + coeff * (ztop[1] - ztop[0]);
|
||||
copyWall1.zbottom[1] = copyWall2.zbottom[0] = zbottom[0] + coeff * (zbottom[1] - zbottom[0]);
|
||||
copyWall1.glseg.fracright = copyWall2.glseg.fracleft = glseg.fracleft + coeff * (glseg.fracright - glseg.fracleft);
|
||||
copyWall1.uprgt.u = copyWall2.uplft.u = uplft.u + coeff * (uprgt.u - uplft.u);
|
||||
copyWall1.uprgt.v = copyWall2.uplft.v = uplft.v + coeff * (uprgt.v - uplft.v);
|
||||
copyWall1.lorgt.u = copyWall2.lolft.u = lolft.u + coeff * (lorgt.u - lolft.u);
|
||||
copyWall1.lorgt.v = copyWall2.lolft.v = lolft.v + coeff * (lorgt.v - lolft.v);
|
||||
copyWall1.tcs[UPRGT].u = copyWall2.tcs[UPLFT].u = tcs[UPLFT].u + coeff * (tcs[UPRGT].u - tcs[UPLFT].u);
|
||||
copyWall1.tcs[UPRGT].v = copyWall2.tcs[UPLFT].v = tcs[UPLFT].v + coeff * (tcs[UPRGT].v - tcs[UPLFT].v);
|
||||
copyWall1.tcs[LORGT].u = copyWall2.tcs[LOLFT].u = tcs[LOLFT].u + coeff * (tcs[LORGT].u - tcs[LOLFT].u);
|
||||
copyWall1.tcs[LORGT].v = copyWall2.tcs[LOLFT].v = tcs[LOLFT].v + coeff * (tcs[LORGT].v - tcs[LOLFT].v);
|
||||
|
||||
copyWall1.SplitWall(frontsector, translucent);
|
||||
copyWall2.SplitWall(frontsector, translucent);
|
||||
|
@ -432,10 +432,10 @@ void GLWall::SplitWall(sector_t * frontsector, bool translucent)
|
|||
flags |= GLWF_NOSPLITUPPER;
|
||||
ztop[0]=copyWall1.zbottom[0]=maplightbottomleft;
|
||||
ztop[1]=copyWall1.zbottom[1]=maplightbottomright;
|
||||
uplft.v=copyWall1.lolft.v=copyWall1.uplft.v+
|
||||
(maplightbottomleft-copyWall1.ztop[0])*(copyWall1.lolft.v-copyWall1.uplft.v)/(zbottom[0]-copyWall1.ztop[0]);
|
||||
uprgt.v=copyWall1.lorgt.v=copyWall1.uprgt.v+
|
||||
(maplightbottomright-copyWall1.ztop[1])*(copyWall1.lorgt.v-copyWall1.uprgt.v)/(zbottom[1]-copyWall1.ztop[1]);
|
||||
tcs[UPLFT].v=copyWall1.tcs[LOLFT].v=copyWall1.tcs[UPLFT].v+
|
||||
(maplightbottomleft-copyWall1.ztop[0])*(copyWall1.tcs[LOLFT].v-copyWall1.tcs[UPLFT].v)/(zbottom[0]-copyWall1.ztop[0]);
|
||||
tcs[UPRGT].v=copyWall1.tcs[LORGT].v=copyWall1.tcs[UPRGT].v+
|
||||
(maplightbottomright-copyWall1.ztop[1])*(copyWall1.tcs[LORGT].v-copyWall1.tcs[UPRGT].v)/(zbottom[1]-copyWall1.ztop[1]);
|
||||
copyWall1.Put3DWall(&lightlist[i], translucent);
|
||||
}
|
||||
if (ztop[0]==zbottom[0] && ztop[1]==zbottom[1])
|
||||
|
@ -574,8 +574,8 @@ bool GLWall::SetWallCoordinates(seg_t * seg, FTexCoordInfo *tci, float textureto
|
|||
|
||||
if (tci)
|
||||
{
|
||||
uplft.v = tci->FloatToTexV(-ztop[0] + texturetop);
|
||||
lolft.v = tci->FloatToTexV(-zbottom[0] + texturetop);
|
||||
tcs[UPLFT].v = tci->FloatToTexV(-ztop[0] + texturetop);
|
||||
tcs[LOLFT].v = tci->FloatToTexV(-zbottom[0] + texturetop);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -595,7 +595,7 @@ bool GLWall::SetWallCoordinates(seg_t * seg, FTexCoordInfo *tci, float textureto
|
|||
|
||||
if (tci)
|
||||
{
|
||||
lolft.v = uplft.v = tci->FloatToTexV(-ztop[0] + texturetop);
|
||||
tcs[LOLFT].v = tcs[UPLFT].v = tci->FloatToTexV(-ztop[0] + texturetop);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -612,8 +612,8 @@ bool GLWall::SetWallCoordinates(seg_t * seg, FTexCoordInfo *tci, float textureto
|
|||
|
||||
if (tci)
|
||||
{
|
||||
uprgt.v = tci->FloatToTexV(-ztop[1] + texturetop);
|
||||
lorgt.v = tci->FloatToTexV(-zbottom[1] + texturetop);
|
||||
tcs[UPRGT].v = tci->FloatToTexV(-ztop[1] + texturetop);
|
||||
tcs[LORGT].v = tci->FloatToTexV(-zbottom[1] + texturetop);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -632,12 +632,12 @@ bool GLWall::SetWallCoordinates(seg_t * seg, FTexCoordInfo *tci, float textureto
|
|||
zbottom[1] = ztop[1] = inter_y;
|
||||
if (tci)
|
||||
{
|
||||
lorgt.v = uprgt.v = tci->FloatToTexV(-ztop[1] + texturetop);
|
||||
tcs[LORGT].v = tcs[UPRGT].v = tci->FloatToTexV(-ztop[1] + texturetop);
|
||||
}
|
||||
}
|
||||
|
||||
uplft.u = lolft.u = l_ul + texlength * glseg.fracleft;
|
||||
uprgt.u = lorgt.u = l_ul + texlength * glseg.fracright;
|
||||
tcs[UPLFT].u = tcs[LOLFT].u = l_ul + texlength * glseg.fracleft;
|
||||
tcs[UPRGT].u = tcs[LORGT].u = l_ul + texlength * glseg.fracright;
|
||||
|
||||
if (gltexture != NULL)
|
||||
{
|
||||
|
@ -646,15 +646,15 @@ bool GLWall::SetWallCoordinates(seg_t * seg, FTexCoordInfo *tci, float textureto
|
|||
else if (flags & GLT_CLAMPY)
|
||||
{
|
||||
// for negative scales we can get negative coordinates here.
|
||||
normalize = (uplft.v > lolft.v || uprgt.v > lorgt.v);
|
||||
normalize = (tcs[UPLFT].v > tcs[LOLFT].v || tcs[UPRGT].v > tcs[LORGT].v);
|
||||
}
|
||||
if (normalize)
|
||||
{
|
||||
// we have to shift the y-coordinate from [-1..0] to [0..1] when using texture clamping with a negative scale
|
||||
uplft.v += 1.f;
|
||||
uprgt.v += 1.f;
|
||||
lolft.v += 1.f;
|
||||
lorgt.v += 1.f;
|
||||
tcs[UPLFT].v += 1.f;
|
||||
tcs[UPRGT].v += 1.f;
|
||||
tcs[LOLFT].v += 1.f;
|
||||
tcs[LORGT].v += 1.f;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -675,21 +675,21 @@ void GLWall::CheckTexturePosition()
|
|||
|
||||
// clamp texture coordinates to a reasonable range.
|
||||
// Extremely large values can cause visual problems
|
||||
if (uplft.v < uprgt.v)
|
||||
if (tcs[UPLFT].v < tcs[UPRGT].v)
|
||||
{
|
||||
sub = float(xs_FloorToInt(uplft.v));
|
||||
sub = float(xs_FloorToInt(tcs[UPLFT].v));
|
||||
}
|
||||
else
|
||||
{
|
||||
sub = float(xs_FloorToInt(uprgt.v));
|
||||
sub = float(xs_FloorToInt(tcs[UPRGT].v));
|
||||
}
|
||||
uplft.v -= sub;
|
||||
uprgt.v -= sub;
|
||||
lolft.v -= sub;
|
||||
lorgt.v -= sub;
|
||||
tcs[UPLFT].v -= sub;
|
||||
tcs[UPRGT].v -= sub;
|
||||
tcs[LOLFT].v -= sub;
|
||||
tcs[LORGT].v -= sub;
|
||||
|
||||
if ((uplft.v == 0.f && uprgt.v == 0.f && lolft.v <= 1.f && lorgt.v <= 1.f) ||
|
||||
(uplft.v >= 0.f && uprgt.v >= 0.f && lolft.v == 1.f && lorgt.v == 1.f))
|
||||
if ((tcs[UPLFT].v == 0.f && tcs[UPRGT].v == 0.f && tcs[LOLFT].v <= 1.f && tcs[LORGT].v <= 1.f) ||
|
||||
(tcs[UPLFT].v >= 0.f && tcs[UPRGT].v >= 0.f && tcs[LOLFT].v == 1.f && tcs[LORGT].v == 1.f))
|
||||
{
|
||||
flags |= GLT_CLAMPY;
|
||||
}
|
||||
|
@ -698,13 +698,13 @@ void GLWall::CheckTexturePosition()
|
|||
// This intentionally only tests the seg's frontsector.
|
||||
if (seg->frontsector->special == GLSector_Skybox)
|
||||
{
|
||||
sub = (float)xs_FloorToInt(uplft.u);
|
||||
uplft.u -= sub;
|
||||
uprgt.u -= sub;
|
||||
lolft.u -= sub;
|
||||
lorgt.u -= sub;
|
||||
if ((uplft.u == 0.f && lolft.u == 0.f && uprgt.u <= 1.f && lorgt.u <= 1.f) ||
|
||||
(uplft.u >= 0.f && lolft.u >= 0.f && uprgt.u == 1.f && lorgt.u == 1.f))
|
||||
sub = (float)xs_FloorToInt(tcs[UPLFT].u);
|
||||
tcs[UPLFT].u -= sub;
|
||||
tcs[UPRGT].u -= sub;
|
||||
tcs[LOLFT].u -= sub;
|
||||
tcs[LORGT].u -= sub;
|
||||
if ((tcs[UPLFT].u == 0.f && tcs[LOLFT].u == 0.f && tcs[UPRGT].u <= 1.f && tcs[LORGT].u <= 1.f) ||
|
||||
(tcs[UPLFT].u >= 0.f && tcs[LOLFT].u >= 0.f && tcs[UPRGT].u == 1.f && tcs[LORGT].u == 1.f))
|
||||
{
|
||||
flags |= GLT_CLAMPX;
|
||||
}
|
||||
|
@ -1039,10 +1039,10 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary,
|
|||
// split the poly!
|
||||
GLWall split;
|
||||
int i,t=0;
|
||||
float v_factor=(zbottom[0]-ztop[0])/(lolft.v-uplft.v);
|
||||
float v_factor=(zbottom[0]-ztop[0])/(tcs[LOLFT].v-tcs[UPLFT].v);
|
||||
// only split the vertical area of the polygon that does not contain slopes.
|
||||
float splittopv = MAX(uplft.v, uprgt.v);
|
||||
float splitbotv = MIN(lolft.v, lorgt.v);
|
||||
float splittopv = MAX(tcs[UPLFT].v, tcs[UPRGT].v);
|
||||
float splitbotv = MIN(tcs[LOLFT].v, tcs[LORGT].v);
|
||||
|
||||
// this is split vertically into sections.
|
||||
for(i=0;i<v;i++)
|
||||
|
@ -1063,16 +1063,16 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary,
|
|||
// if not use the top of the remaining polygon
|
||||
if (splitrect[i].top>splittopv)
|
||||
{
|
||||
split.ztop[0]=split.ztop[1]= ztop[0]+v_factor*(splitrect[i].top-uplft.v);
|
||||
split.uplft.v=split.uprgt.v=splitrect[i].top;
|
||||
split.ztop[0]=split.ztop[1]= ztop[0]+v_factor*(splitrect[i].top-tcs[UPLFT].v);
|
||||
split.tcs[UPLFT].v=split.tcs[UPRGT].v=splitrect[i].top;
|
||||
}
|
||||
// the bottom line of the current segment is inside the splittable area
|
||||
// use the splitrect's bottom as bottom of this segment
|
||||
// if not use the bottom of the remaining polygon
|
||||
if (splitbot<=splitbotv)
|
||||
{
|
||||
split.zbottom[0]=split.zbottom[1]=ztop[0]+v_factor*(splitbot-uplft.v);
|
||||
split.lolft.v=split.lorgt.v=splitbot;
|
||||
split.zbottom[0]=split.zbottom[1]=ztop[0]+v_factor*(splitbot-tcs[UPLFT].v);
|
||||
split.tcs[LOLFT].v=split.tcs[LORGT].v=splitbot;
|
||||
}
|
||||
//
|
||||
//
|
||||
|
@ -1166,8 +1166,8 @@ void GLWall::BuildFFBlock(seg_t * seg, F3DFloor * rover,
|
|||
|
||||
texlength = tci.FloatToTexU(seg->sidedef->TexelLength);
|
||||
|
||||
uplft.u = lolft.u = ul + texlength * glseg.fracleft;
|
||||
uprgt.u = lorgt.u = ul + texlength * glseg.fracright;
|
||||
tcs[UPLFT].u = tcs[LOLFT].u = ul + texlength * glseg.fracleft;
|
||||
tcs[UPRGT].u = tcs[LORGT].u = ul + texlength * glseg.fracright;
|
||||
|
||||
float rowoffset = tci.RowOffset(seg->sidedef->GetTextureYOffset(side_t::mid));
|
||||
to = (rover->flags&(FF_UPPERTEXTURE | FF_LOWERTEXTURE)) ?
|
||||
|
@ -1175,10 +1175,10 @@ void GLWall::BuildFFBlock(seg_t * seg, F3DFloor * rover,
|
|||
|
||||
to += rowoffset + rover->top.model->GetPlaneTexZ(rover->top.isceiling);
|
||||
|
||||
uplft.v = tci.FloatToTexV(to - ff_topleft);
|
||||
uprgt.v = tci.FloatToTexV(to - ff_topright);
|
||||
lolft.v = tci.FloatToTexV(to - ff_bottomleft);
|
||||
lorgt.v = tci.FloatToTexV(to - ff_bottomright);
|
||||
tcs[UPLFT].v = tci.FloatToTexV(to - ff_topleft);
|
||||
tcs[UPRGT].v = tci.FloatToTexV(to - ff_topright);
|
||||
tcs[LOLFT].v = tci.FloatToTexV(to - ff_bottomleft);
|
||||
tcs[LORGT].v = tci.FloatToTexV(to - ff_bottomright);
|
||||
type = RENDERWALL_FFBLOCK;
|
||||
CheckTexturePosition();
|
||||
}
|
||||
|
|
|
@ -175,14 +175,8 @@ void GLWall::SetupLights()
|
|||
|
||||
void GLWall::RenderWall(int textured, unsigned int *store)
|
||||
{
|
||||
static texcoord tcs[4]; // making this variable static saves us a relatively costly stack integrity check.
|
||||
bool split = (gl_seamless && !(textured&RWF_NOSPLIT) && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ) && !(flags & GLWF_NOSPLIT));
|
||||
|
||||
tcs[0]=lolft;
|
||||
tcs[1]=uplft;
|
||||
tcs[2]=uprgt;
|
||||
tcs[3]=lorgt;
|
||||
|
||||
if (!(textured & RWF_NORENDER))
|
||||
{
|
||||
gl_RenderState.Apply();
|
||||
|
@ -193,18 +187,18 @@ void GLWall::RenderWall(int textured, unsigned int *store)
|
|||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
unsigned int count, offset;
|
||||
|
||||
ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[0].u, tcs[0].v);
|
||||
ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[LOLFT].u, tcs[LOLFT].v);
|
||||
ptr++;
|
||||
if (split && glseg.fracleft == 0) SplitLeftEdge(tcs, ptr);
|
||||
ptr->Set(glseg.x1, ztop[0], glseg.y1, tcs[1].u, tcs[1].v);
|
||||
if (split && glseg.fracleft == 0) SplitLeftEdge(ptr);
|
||||
ptr->Set(glseg.x1, ztop[0], glseg.y1, tcs[UPLFT].u, tcs[UPLFT].v);
|
||||
ptr++;
|
||||
if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(tcs, ptr);
|
||||
ptr->Set(glseg.x2, ztop[1], glseg.y2, tcs[2].u, tcs[2].v);
|
||||
if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(ptr);
|
||||
ptr->Set(glseg.x2, ztop[1], glseg.y2, tcs[UPRGT].u, tcs[UPRGT].v);
|
||||
ptr++;
|
||||
if (split && glseg.fracright == 1) SplitRightEdge(tcs, ptr);
|
||||
ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[3].u, tcs[3].v);
|
||||
if (split && glseg.fracright == 1) SplitRightEdge(ptr);
|
||||
ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[LORGT].u, tcs[LORGT].v);
|
||||
ptr++;
|
||||
if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs, ptr);
|
||||
if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(ptr);
|
||||
count = GLRenderer->mVBO->GetCount(ptr, &offset);
|
||||
if (!(textured & RWF_NORENDER))
|
||||
{
|
||||
|
@ -265,8 +259,8 @@ void GLWall::RenderMirrorSurface()
|
|||
if (gl.glslversion >= 0.f)
|
||||
{
|
||||
// we use texture coordinates and texture matrix to pass the normal stuff to the shader so that the default vertex buffer format can be used as is.
|
||||
lolft.u = lorgt.u = uplft.u = uprgt.u = v.X();
|
||||
lolft.v = lorgt.v = uplft.v = uprgt.v = v.Z();
|
||||
tcs[LOLFT].u = tcs[LORGT].u = tcs[UPLFT].u = tcs[UPRGT].u = v.X();
|
||||
tcs[LOLFT].v = tcs[LORGT].v = tcs[UPLFT].v = tcs[UPRGT].v = v.Z();
|
||||
|
||||
gl_RenderState.EnableTextureMatrix(true);
|
||||
gl_RenderState.mTextureMatrix.computeNormalMatrix(gl_RenderState.mViewMatrix);
|
||||
|
@ -448,5 +442,10 @@ void GLWall::Draw(int pass)
|
|||
RenderTranslucentWall();
|
||||
break;
|
||||
}
|
||||
|
||||
case GLPASS_LIGHTTEX:
|
||||
case GLPASS_LIGHTTEX_ADDITIVE:
|
||||
RenderLightsCompat(pass);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -302,9 +302,9 @@ void DFlicker::Tick ()
|
|||
DFlicker::DFlicker (sector_t *sector, int upper, int lower)
|
||||
: DLighting (sector)
|
||||
{
|
||||
m_MaxLight = upper;
|
||||
m_MinLight = lower;
|
||||
sector->lightlevel = upper;
|
||||
m_MaxLight = sector_t::ClampLight(upper);
|
||||
m_MinLight = sector_t::ClampLight(lower);
|
||||
sector->lightlevel = m_MaxLight;
|
||||
m_Count = (pr_flicker()&64)+1;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ static oalloadentry oalfuncs[] = {
|
|||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
|
||||
#ifndef IN_IDE_PARSER
|
||||
#define alEnable p_alEnable
|
||||
#define alDisable p_alDisable
|
||||
#define alIsEnabled p_alIsEnabled
|
||||
|
@ -116,6 +116,7 @@ static oalloadentry oalfuncs[] = {
|
|||
#define alcCaptureStart p_alcCaptureStart
|
||||
#define alcCaptureStop p_alcCaptureStop
|
||||
#define alcCaptureSamples p_alcCaptureSamples
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -40,6 +40,9 @@
|
|||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#include <memory>
|
||||
#include <chrono>
|
||||
|
||||
#include "except.h"
|
||||
#include "doomstat.h"
|
||||
#include "templates.h"
|
||||
|
@ -69,7 +72,7 @@ static void* hmodOpenAL;
|
|||
#ifdef __APPLE__
|
||||
#define OPENALLIB "OpenAL.framework/OpenAL"
|
||||
#else
|
||||
#define OPENALLIB "libopenal.so"
|
||||
#define OPENALLIB "libopenal.so.1"
|
||||
#endif
|
||||
#define LoadLibrary(x) dlopen((x), RTLD_LAZY)
|
||||
#define GetProcAddress(a,b) dlsym((a),(b))
|
||||
|
@ -273,6 +276,8 @@ class OpenALSoundStream : public SoundStream
|
|||
alSourcei(Source, AL_DIRECT_FILTER, AL_FILTER_NULL);
|
||||
alSource3i(Source, AL_AUXILIARY_SEND_FILTER, 0, 0, AL_FILTER_NULL);
|
||||
}
|
||||
if(Renderer->AL.EXT_SOURCE_RADIUS)
|
||||
alSourcef(Source, AL_SOURCE_RADIUS, 0.f);
|
||||
|
||||
alGenBuffers(BufferCount, Buffers);
|
||||
return (getALError() == AL_NO_ERROR);
|
||||
|
@ -626,12 +631,21 @@ public:
|
|||
|
||||
extern ReverbContainer *ForcedEnvironment;
|
||||
|
||||
#define AREA_SOUND_RADIUS (128.f)
|
||||
#define AREA_SOUND_RADIUS (32.f)
|
||||
|
||||
#define PITCH_MULT (0.7937005f) /* Approx. 4 semitones lower; what Nash suggested */
|
||||
|
||||
#define PITCH(pitch) (snd_pitched ? (pitch)/128.f : 1.f)
|
||||
|
||||
static size_t GetChannelCount(ChannelConfig chans)
|
||||
{
|
||||
switch(chans)
|
||||
{
|
||||
case ChannelConfig_Mono: return 1;
|
||||
case ChannelConfig_Stereo: return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static float GetRolloff(const FRolloffInfo *rolloff, float distance)
|
||||
{
|
||||
|
@ -686,7 +700,12 @@ template<typename T>
|
|||
static void LoadALFunc(const char *name, T *x)
|
||||
{ *x = reinterpret_cast<T>(alGetProcAddress(name)); }
|
||||
|
||||
template<typename T>
|
||||
static void LoadALCFunc(ALCdevice *device, const char *name, T *x)
|
||||
{ *x = reinterpret_cast<T>(alcGetProcAddress(device, name)); }
|
||||
|
||||
#define LOAD_FUNC(x) (LoadALFunc(#x, &x))
|
||||
#define LOAD_DEV_FUNC(d, x) (LoadALCFunc(d, #x, &x))
|
||||
OpenALSoundRenderer::OpenALSoundRenderer()
|
||||
: Device(NULL), Context(NULL), SFXPaused(0), PrevEnvironment(NULL), EnvSlot(0)
|
||||
{
|
||||
|
@ -744,8 +763,10 @@ OpenALSoundRenderer::OpenALSoundRenderer()
|
|||
DPrintf(" Extensions: " TEXTCOLOR_ORANGE"%s\n", alGetString(AL_EXTENSIONS));
|
||||
|
||||
ALC.EXT_EFX = !!alcIsExtensionPresent(Device, "ALC_EXT_EFX");
|
||||
ALC.EXT_disconnect = !!alcIsExtensionPresent(Device, "ALC_EXT_disconnect");;
|
||||
ALC.EXT_disconnect = !!alcIsExtensionPresent(Device, "ALC_EXT_disconnect");
|
||||
ALC.SOFT_pause_device = !!alcIsExtensionPresent(Device, "ALC_SOFT_pause_device");
|
||||
AL.EXT_source_distance_model = !!alIsExtensionPresent("AL_EXT_source_distance_model");
|
||||
AL.EXT_SOURCE_RADIUS = !!alIsExtensionPresent("AL_EXT_SOURCE_RADIUS");
|
||||
AL.SOFT_deferred_updates = !!alIsExtensionPresent("AL_SOFT_deferred_updates");
|
||||
AL.SOFT_loop_points = !!alIsExtensionPresent("AL_SOFT_loop_points");
|
||||
|
||||
|
@ -766,6 +787,12 @@ OpenALSoundRenderer::OpenALSoundRenderer()
|
|||
alProcessUpdatesSOFT = _wrap_ProcessUpdatesSOFT;
|
||||
}
|
||||
|
||||
if(ALC.SOFT_pause_device)
|
||||
{
|
||||
LOAD_DEV_FUNC(Device, alcDevicePauseSOFT);
|
||||
LOAD_DEV_FUNC(Device, alcDeviceResumeSOFT);
|
||||
}
|
||||
|
||||
ALenum err = getALError();
|
||||
if(err != AL_NO_ERROR)
|
||||
{
|
||||
|
@ -905,6 +932,7 @@ OpenALSoundRenderer::OpenALSoundRenderer()
|
|||
if(EnvSlot)
|
||||
Printf(" EFX enabled\n");
|
||||
}
|
||||
#undef LOAD_DEV_FUNC
|
||||
#undef LOAD_FUNC
|
||||
|
||||
OpenALSoundRenderer::~OpenALSoundRenderer()
|
||||
|
@ -1042,7 +1070,7 @@ std::pair<SoundHandle,bool> OpenALSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int
|
|||
{
|
||||
int sum = 0;
|
||||
for(int c = 0;c < channels;c++)
|
||||
sum = ((short*)sfxdata)[i*channels + c];
|
||||
sum += ((short*)sfxdata)[i*channels + c];
|
||||
((short*)sfxdata)[i] = sum / channels;
|
||||
}
|
||||
}
|
||||
|
@ -1052,7 +1080,7 @@ std::pair<SoundHandle,bool> OpenALSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int
|
|||
{
|
||||
int sum = 0;
|
||||
for(int c = 0;c < channels;c++)
|
||||
sum = sfxdata[i*channels + c] - 128;
|
||||
sum += sfxdata[i*channels + c] - 128;
|
||||
sfxdata[i] = (sum / channels) + 128;
|
||||
}
|
||||
}
|
||||
|
@ -1124,7 +1152,7 @@ std::pair<SoundHandle,bool> OpenALSoundRenderer::LoadSound(BYTE *sfxdata, int le
|
|||
SampleType type;
|
||||
int srate;
|
||||
|
||||
SoundDecoder *decoder = CreateDecoder(&reader);
|
||||
std::unique_ptr<SoundDecoder> decoder(CreateDecoder(&reader));
|
||||
if(!decoder) return std::make_pair(retval, true);
|
||||
|
||||
decoder->getInfo(&srate, &chans, &type);
|
||||
|
@ -1143,46 +1171,53 @@ std::pair<SoundHandle,bool> OpenALSoundRenderer::LoadSound(BYTE *sfxdata, int le
|
|||
{
|
||||
Printf("Unsupported audio format: %s, %s\n", GetChannelConfigName(chans),
|
||||
GetSampleTypeName(type));
|
||||
delete decoder;
|
||||
return std::make_pair(retval, true);
|
||||
}
|
||||
|
||||
TArray<char> data = decoder->readAll();
|
||||
if(chans != ChannelConfig_Mono && monoize)
|
||||
{
|
||||
// TODO: Handle this better if ChannelConfig ever gets more channel configurations.
|
||||
size_t frames = data.Size() / 2 / (type == SampleType_Int16 ? 2 : 1);
|
||||
size_t chancount = GetChannelCount(chans);
|
||||
size_t frames = data.Size() / chancount /
|
||||
(type == SampleType_Int16 ? 2 : 1);
|
||||
if(type == SampleType_Int16)
|
||||
{
|
||||
short *sfxdata = (short*)&data[0];
|
||||
for(size_t i = 0;i < frames;i++)
|
||||
sfxdata[i] = (sfxdata[i*2 + 0]-0 + sfxdata[i*2 + 1]-0)/2;
|
||||
{
|
||||
int sum = 0;
|
||||
for(size_t c = 0;c < chancount;c++)
|
||||
sum += sfxdata[i*chancount + c];
|
||||
sfxdata[i] = sum / chancount;
|
||||
}
|
||||
}
|
||||
else if(type == SampleType_UInt8)
|
||||
{
|
||||
BYTE *sfxdata = (BYTE*)&data[0];
|
||||
for(size_t i = 0;i < frames;i++)
|
||||
sfxdata[i] = (sfxdata[i*2 + 0]-128 + sfxdata[i*2 + 1]-128)/2 + 128;
|
||||
{
|
||||
int sum = 0;
|
||||
for(size_t c = 0;c < chancount;c++)
|
||||
sum += sfxdata[i*chancount + c] - 128;
|
||||
sfxdata[i] = (sum / chancount) + 128;
|
||||
}
|
||||
}
|
||||
data.Resize(data.Size()/2);
|
||||
data.Resize(data.Size()/chancount);
|
||||
}
|
||||
|
||||
ALenum err;
|
||||
ALuint buffer = 0;
|
||||
alGenBuffers(1, &buffer);
|
||||
alBufferData(buffer, format, &data[0], data.Size(), srate);
|
||||
|
||||
ALenum err;
|
||||
if((err=getALError()) != AL_NO_ERROR)
|
||||
{
|
||||
Printf("Failed to buffer data: %s\n", alGetString(err));
|
||||
alDeleteBuffers(1, &buffer);
|
||||
getALError();
|
||||
delete decoder;
|
||||
return std::make_pair(retval, true);
|
||||
}
|
||||
|
||||
retval.data = MAKE_PTRID(buffer);
|
||||
delete decoder;
|
||||
return std::make_pair(retval, (chans == ChannelConfig_Mono || monoize));
|
||||
}
|
||||
|
||||
|
@ -1262,6 +1297,8 @@ FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int
|
|||
alSourcef(source, AL_ROLLOFF_FACTOR, 0.f);
|
||||
alSourcef(source, AL_MAX_GAIN, SfxVolume);
|
||||
alSourcef(source, AL_GAIN, SfxVolume*vol);
|
||||
if(AL.EXT_SOURCE_RADIUS)
|
||||
alSourcef(source, AL_SOURCE_RADIUS, 0.f);
|
||||
|
||||
if(EnvSlot)
|
||||
{
|
||||
|
@ -1282,7 +1319,7 @@ FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int
|
|||
else
|
||||
alSourcef(source, AL_PITCH, PITCH(pitch));
|
||||
|
||||
if(!reuse_chan)
|
||||
if(!reuse_chan || reuse_chan->StartTime.AsOne == 0)
|
||||
alSourcef(source, AL_SEC_OFFSET, 0.f);
|
||||
else
|
||||
{
|
||||
|
@ -1290,8 +1327,11 @@ FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int
|
|||
alSourcef(source, AL_SEC_OFFSET, reuse_chan->StartTime.Lo/1000.f);
|
||||
else
|
||||
{
|
||||
// FIXME: set offset based on the current time and the StartTime
|
||||
alSourcef(source, AL_SEC_OFFSET, 0.f);
|
||||
float offset = std::chrono::duration_cast<std::chrono::duration<float>>(
|
||||
std::chrono::steady_clock::now().time_since_epoch() -
|
||||
std::chrono::steady_clock::time_point::duration(reuse_chan->StartTime.AsOne)
|
||||
).count();
|
||||
if(offset > 0.f) alSourcef(source, AL_SEC_OFFSET, offset);
|
||||
}
|
||||
}
|
||||
if(getALError() != AL_NO_ERROR)
|
||||
|
@ -1321,7 +1361,6 @@ FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int
|
|||
chan->Rolloff.RolloffType = ROLLOFF_Log;
|
||||
chan->Rolloff.RolloffFactor = 0.f;
|
||||
chan->Rolloff.MinDistance = 1.f;
|
||||
chan->DistanceScale = 1.f;
|
||||
chan->DistanceSqr = 0.f;
|
||||
chan->ManualRolloff = false;
|
||||
|
||||
|
@ -1404,7 +1443,16 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener
|
|||
float gain = GetRolloff(rolloff, sqrtf(dist_sqr) * distscale);
|
||||
dir.MakeResize((gain > 0.00001f) ? 1.f/gain : 100000.f);
|
||||
}
|
||||
if((chanflags&SNDF_AREA) && dist_sqr < AREA_SOUND_RADIUS*AREA_SOUND_RADIUS)
|
||||
if(AL.EXT_SOURCE_RADIUS)
|
||||
{
|
||||
/* Since the OpenAL distance is decoupled from the sound's distance, get the OpenAL
|
||||
* distance that corresponds to the area radius. */
|
||||
alSourcef(source, AL_SOURCE_RADIUS, (chanflags&SNDF_AREA) ?
|
||||
// Clamp in case the max distance is <= the area radius
|
||||
1.f/MAX<float>(GetRolloff(rolloff, AREA_SOUND_RADIUS), 0.00001f) : 0.f
|
||||
);
|
||||
}
|
||||
else if((chanflags&SNDF_AREA) && dist_sqr < AREA_SOUND_RADIUS*AREA_SOUND_RADIUS)
|
||||
{
|
||||
FVector3 amb(0.f, !(dir.Y>=0.f) ? -1.f : 1.f, 0.f);
|
||||
float a = sqrtf(dist_sqr) / AREA_SOUND_RADIUS;
|
||||
|
@ -1414,20 +1462,24 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener
|
|||
|
||||
alSource3f(source, AL_POSITION, dir[0], dir[1], -dir[2]);
|
||||
}
|
||||
else if((chanflags&SNDF_AREA) && dist_sqr < AREA_SOUND_RADIUS*AREA_SOUND_RADIUS)
|
||||
else
|
||||
{
|
||||
FVector3 dir = pos - listener->position;
|
||||
FVector3 dir = pos;
|
||||
if(AL.EXT_SOURCE_RADIUS)
|
||||
alSourcef(source, AL_SOURCE_RADIUS, (chanflags&SNDF_AREA) ? AREA_SOUND_RADIUS : 0.f);
|
||||
else if((chanflags&SNDF_AREA) && dist_sqr < AREA_SOUND_RADIUS*AREA_SOUND_RADIUS)
|
||||
{
|
||||
dir -= listener->position;
|
||||
|
||||
float mindist = rolloff->MinDistance/distscale;
|
||||
FVector3 amb(0.f, !(dir.Y>=0.f) ? -mindist : mindist, 0.f);
|
||||
float a = sqrtf(dist_sqr) / AREA_SOUND_RADIUS;
|
||||
dir = amb + (dir-amb)*a;
|
||||
float mindist = rolloff->MinDistance/distscale;
|
||||
FVector3 amb(0.f, !(dir.Y>=0.f) ? -mindist : mindist, 0.f);
|
||||
float a = sqrtf(dist_sqr) / AREA_SOUND_RADIUS;
|
||||
dir = amb + (dir-amb)*a;
|
||||
|
||||
dir += listener->position;
|
||||
dir += listener->position;
|
||||
}
|
||||
alSource3f(source, AL_POSITION, dir[0], dir[1], -dir[2]);
|
||||
}
|
||||
else
|
||||
alSource3f(source, AL_POSITION, pos[0], pos[1], -pos[2]);
|
||||
alSource3f(source, AL_VELOCITY, vel[0], vel[1], -vel[2]);
|
||||
alSource3f(source, AL_DIRECTION, 0.f, 0.f, 0.f);
|
||||
|
||||
|
@ -1456,7 +1508,7 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener
|
|||
else
|
||||
alSourcef(source, AL_PITCH, PITCH(pitch));
|
||||
|
||||
if(!reuse_chan)
|
||||
if(!reuse_chan || reuse_chan->StartTime.AsOne == 0)
|
||||
alSourcef(source, AL_SEC_OFFSET, 0.f);
|
||||
else
|
||||
{
|
||||
|
@ -1464,8 +1516,11 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener
|
|||
alSourcef(source, AL_SEC_OFFSET, reuse_chan->StartTime.Lo/1000.f);
|
||||
else
|
||||
{
|
||||
// FIXME: set offset based on the current time and the StartTime
|
||||
alSourcef(source, AL_SAMPLE_OFFSET, 0.f);
|
||||
float offset = std::chrono::duration_cast<std::chrono::duration<float>>(
|
||||
std::chrono::steady_clock::now().time_since_epoch() -
|
||||
std::chrono::steady_clock::time_point::duration(reuse_chan->StartTime.AsOne)
|
||||
).count();
|
||||
if(offset > 0.f) alSourcef(source, AL_SEC_OFFSET, offset);
|
||||
}
|
||||
}
|
||||
if(getALError() != AL_NO_ERROR)
|
||||
|
@ -1493,7 +1548,6 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener
|
|||
else chan->SysChannel = MAKE_PTRID(source);
|
||||
|
||||
chan->Rolloff = *rolloff;
|
||||
chan->DistanceScale = distscale;
|
||||
chan->DistanceSqr = dist_sqr;
|
||||
chan->ManualRolloff = manualRolloff;
|
||||
|
||||
|
@ -1579,10 +1633,20 @@ void OpenALSoundRenderer::SetInactive(SoundRenderer::EInactiveState state)
|
|||
{
|
||||
case SoundRenderer::INACTIVE_Active:
|
||||
alListenerf(AL_GAIN, 1.0f);
|
||||
if(ALC.SOFT_pause_device)
|
||||
{
|
||||
alcDeviceResumeSOFT(Device);
|
||||
getALCError(Device);
|
||||
}
|
||||
break;
|
||||
|
||||
/* FIXME: This doesn't stop anything. */
|
||||
case SoundRenderer::INACTIVE_Complete:
|
||||
if(ALC.SOFT_pause_device)
|
||||
{
|
||||
alcDevicePauseSOFT(Device);
|
||||
getALCError(Device);
|
||||
}
|
||||
/* fall-through */
|
||||
case SoundRenderer::INACTIVE_Mute:
|
||||
alListenerf(AL_GAIN, 0.0f);
|
||||
break;
|
||||
|
@ -1631,26 +1695,26 @@ void OpenALSoundRenderer::UpdateSoundParams3D(SoundListener *listener, FISoundCh
|
|||
if(chan == NULL || chan->SysChannel == NULL)
|
||||
return;
|
||||
|
||||
alDeferUpdatesSOFT();
|
||||
|
||||
FVector3 dir = pos - listener->position;
|
||||
chan->DistanceSqr = (float)dir.LengthSquared();
|
||||
|
||||
if(chan->ManualRolloff)
|
||||
{
|
||||
if(dir.DoesNotApproximatelyEqual(FVector3(0.f, 0.f, 0.f)))
|
||||
{
|
||||
float gain = GetRolloff(&chan->Rolloff, sqrtf(chan->DistanceSqr) * chan->DistanceScale);
|
||||
dir.MakeResize((gain > 0.00001f) ? 1.f/gain : 100000.f);
|
||||
}
|
||||
if(areasound && chan->DistanceSqr < AREA_SOUND_RADIUS*AREA_SOUND_RADIUS)
|
||||
if(!AL.EXT_SOURCE_RADIUS && areasound &&
|
||||
chan->DistanceSqr < AREA_SOUND_RADIUS*AREA_SOUND_RADIUS)
|
||||
{
|
||||
FVector3 amb(0.f, !(dir.Y>=0.f) ? -1.f : 1.f, 0.f);
|
||||
float a = sqrtf(chan->DistanceSqr) / AREA_SOUND_RADIUS;
|
||||
dir = amb + (dir-amb)*a;
|
||||
}
|
||||
if(dir.DoesNotApproximatelyEqual(FVector3(0.f, 0.f, 0.f)))
|
||||
{
|
||||
float gain = GetRolloff(&chan->Rolloff, sqrtf(chan->DistanceSqr)*chan->DistanceScale);
|
||||
dir.MakeResize((gain > 0.00001f) ? 1.f/gain : 100000.f);
|
||||
}
|
||||
}
|
||||
else if(areasound && chan->DistanceSqr < AREA_SOUND_RADIUS*AREA_SOUND_RADIUS)
|
||||
else if(!AL.EXT_SOURCE_RADIUS && areasound &&
|
||||
chan->DistanceSqr < AREA_SOUND_RADIUS*AREA_SOUND_RADIUS)
|
||||
{
|
||||
float mindist = chan->Rolloff.MinDistance / chan->DistanceScale;
|
||||
FVector3 amb(0.f, !(dir.Y>=0.f) ? -mindist : mindist, 0.f);
|
||||
|
@ -1659,6 +1723,8 @@ void OpenALSoundRenderer::UpdateSoundParams3D(SoundListener *listener, FISoundCh
|
|||
}
|
||||
dir += listener->position;
|
||||
|
||||
alDeferUpdatesSOFT();
|
||||
|
||||
ALuint source = GET_PTRID(chan->SysChannel);
|
||||
alSource3f(source, AL_POSITION, dir[0], dir[1], -dir[2]);
|
||||
alSource3f(source, AL_VELOCITY, vel[0], vel[1], -vel[2]);
|
||||
|
@ -1802,7 +1868,7 @@ void OpenALSoundRenderer::MarkStartTime(FISoundChannel *chan)
|
|||
{
|
||||
// FIXME: Get current time (preferably from the audio clock, but the system
|
||||
// time will have to do)
|
||||
chan->StartTime.AsOne = 0;
|
||||
chan->StartTime.AsOne = std::chrono::steady_clock::now().time_since_epoch().count();
|
||||
}
|
||||
|
||||
float OpenALSoundRenderer::GetAudibility(FISoundChannel *chan)
|
||||
|
|
|
@ -58,6 +58,11 @@
|
|||
#define AL_FORMAT_71CHN32 0x1212
|
||||
#endif
|
||||
|
||||
#ifndef AL_EXT_SOURCE_RADIUS
|
||||
#define AL_EXT_SOURCE_RADIUS 1
|
||||
#define AL_SOURCE_RADIUS 0x1031
|
||||
#endif
|
||||
|
||||
#include "efx.h"
|
||||
|
||||
|
||||
|
@ -124,9 +129,11 @@ private:
|
|||
struct {
|
||||
bool EXT_EFX;
|
||||
bool EXT_disconnect;
|
||||
bool SOFT_pause_device;
|
||||
} ALC;
|
||||
struct {
|
||||
bool EXT_source_distance_model;
|
||||
bool EXT_SOURCE_RADIUS;
|
||||
bool SOFT_deferred_updates;
|
||||
bool SOFT_loop_points;
|
||||
} AL;
|
||||
|
@ -174,6 +181,9 @@ private:
|
|||
ALvoid (AL_APIENTRY*alDeferUpdatesSOFT)(void);
|
||||
ALvoid (AL_APIENTRY*alProcessUpdatesSOFT)(void);
|
||||
|
||||
void (ALC_APIENTRY*alcDevicePauseSOFT)(ALCdevice *device);
|
||||
void (ALC_APIENTRY*alcDeviceResumeSOFT)(ALCdevice *device);
|
||||
|
||||
void LoadReverb(const ReverbContainer *env);
|
||||
void PurgeStoppedSources();
|
||||
static FSoundChan *FindLowestChannel();
|
||||
|
|
|
@ -45,6 +45,7 @@ FWarpTexture::FWarpTexture (FTexture *source, int warptype)
|
|||
: GenTime (0), SourcePic (source), Pixels (0), Spans (0), Speed (1.f)
|
||||
{
|
||||
CopyInfo(source);
|
||||
if (warptype == 2) SetupMultipliers(256, 128);
|
||||
SetupMultipliers(128, 128); // [mxd]
|
||||
bWarped = warptype;
|
||||
}
|
||||
|
|
|
@ -2433,12 +2433,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItem)
|
|||
ACTION_RETURN_BOOL(true);
|
||||
}
|
||||
|
||||
if (distance == 0)
|
||||
{
|
||||
// use the minimum distance that does not result in an overlap
|
||||
distance = (self->radius + GetDefaultByType(missile)->radius);
|
||||
}
|
||||
|
||||
if (ACTION_CALL_FROM_WEAPON())
|
||||
{
|
||||
// Used from a weapon, so use some ammo
|
||||
|
|
|
@ -7,11 +7,10 @@ vec4 ProcessTexel()
|
|||
const float pi = 3.14159265358979323846;
|
||||
vec2 offset = vec2(0.0,0.0);
|
||||
|
||||
float siny = sin(pi * 2.0 * (texCoord.y * 2.2 + timer * 0.75)) * 0.03;
|
||||
offset.y = siny + sin(pi * 2.0 * (texCoord.x * 0.75 + timer * 0.75)) * 0.03;
|
||||
offset.x = siny + sin(pi * 2.0 * (texCoord.x * 1.1 + timer * 0.45)) * 0.02;
|
||||
offset.y = 0.5 + sin(pi * 2.0 * (texCoord.y + timer * 0.61 + 900.0/8192.0)) + sin(pi * 2.0 * (texCoord.x * 2.0 + timer * 0.36 + 300.0/8192.0));
|
||||
offset.x = 0.5 + sin(pi * 2.0 * (texCoord.y + timer * 0.49 + 700.0/8192.0)) + sin(pi * 2.0 * (texCoord.x * 2.0 + timer * 0.49 + 1200.0/8192.0));
|
||||
|
||||
texCoord += offset;
|
||||
texCoord += offset * 0.025;
|
||||
|
||||
return getTexel(texCoord);
|
||||
}
|
||||
|
|
18
wadsrc/static/shaders/glsl/func_warp3.fp
Normal file
18
wadsrc/static/shaders/glsl/func_warp3.fp
Normal file
|
@ -0,0 +1,18 @@
|
|||
uniform float timer;
|
||||
|
||||
vec4 ProcessTexel()
|
||||
{
|
||||
vec2 texCoord = vTexCoord.st;
|
||||
|
||||
const float pi = 3.14159265358979323846;
|
||||
vec2 offset = vec2(0.0,0.0);
|
||||
|
||||
float siny = sin(pi * 2.0 * (texCoord.y * 2.0 + timer * 0.75)) * 0.03;
|
||||
offset.y = siny + sin(pi * 2.0 * (texCoord.x + timer * 0.75)) * 0.03;
|
||||
offset.x = siny + sin(pi * 2.0 * (texCoord.x + timer * 0.45)) * 0.02;
|
||||
|
||||
texCoord += offset;
|
||||
|
||||
return getTexel(texCoord);
|
||||
}
|
||||
|
|
@ -134,7 +134,7 @@ float R_DoomLightingEquation(float light, float dist)
|
|||
/* L in the range 0 to 63 */
|
||||
float L = light * 63.0/31.0;
|
||||
|
||||
float min_L = clamp(36.0/31.0 - L, 0.0, 1.0);
|
||||
float min_L = clamp(36.0/31.0 - L, 0.03, 1.0);
|
||||
|
||||
// Fix objects getting totally black when close.
|
||||
if (dist < 0.0001)
|
||||
|
|
Loading…
Reference in a new issue