- removed the Vector class in the GL renderer and replaced all its uses with FVector3.

- optimized the math to get a plane equation from a linedef. The original code used a generic algorithm that knew nothing about the fact that Doom walls are always perfectly vertical. With this knowledge the plane calculation can be reduced to a lot less code because retrieving the normal is trivial in this special case.
- use the SSE2 rsqrtss instruction to calculate a wall's length, because this is by far the most frequent use of square roots in the GL renderer. So far this is only active on x64, it may be activated on 32 bit later as well, but only after it has been decided if 32 bit builds should be x87 or SSE2.

# Conflicts:
#	src/gl/dynlights/gl_dynlight.cpp

# Conflicts:
#	src/g_shared/a_dynlightdata.cpp
This commit is contained in:
Christoph Oelckers 2017-03-12 19:44:00 +01:00
commit 4cd0d3d454
8 changed files with 137 additions and 429 deletions

View file

@ -372,10 +372,10 @@ void FRenderState::DrawColormapOverlay()
//
//==========================================================================
bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, Vector & nearPt, Vector & up, Vector & right,
bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, FVector3 & nearPt, FVector3 & up, FVector3 & right,
float & scale, bool checkside, bool additive)
{
Vector fn, pos;
FVector3 fn, pos;
DVector3 lpos = light->PosRelative(group);
@ -398,16 +398,12 @@ bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, Vector & nearPt,
// project light position onto plane (find closest point on plane)
pos.Set(lpos.X, lpos.Z, lpos.Y);
pos = { (float)lpos.X, (float)lpos.Z, (float)lpos.Y };
fn = p.Normal();
fn.GetRightUp(right, up);
#ifdef _MSC_VER
nearPt = pos + fn * dist;
#else
Vector tmpVec = fn * dist;
FVector3 tmpVec = fn * dist;
nearPt = pos + tmpVec;
#endif
float cs = 1.0f - (dist / radius);
if (additive) cs *= 0.2f; // otherwise the light gets too strong.
@ -417,13 +413,11 @@ bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, Vector & nearPt,
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;
float length = float(FVector3(r, g, b).Length());
r = length - r;
g = length - g;
b = length - b;
}
else
{
@ -564,7 +558,7 @@ void GLWall::RenderFogBoundaryCompat()
void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass)
{
Plane p;
Vector nearPt, up, right, t1;
FVector3 nearPt, up, right, t1;
float scale;
FLightNode * node = sub->lighthead;
@ -604,11 +598,11 @@ void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass)
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;
t1 = { ptr->x, ptr->z, ptr->y };
FVector3 nearToVert = t1 - nearPt;
ptr->u = (nearToVert.Dot(right) * scale) + 0.5f;
ptr->v = (nearToVert.Dot(up) * scale) + 0.5f;
ptr->u = ((nearToVert | right) * scale) + 0.5f;
ptr->v = ((nearToVert | up) * scale) + 0.5f;
ptr++;
}
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
@ -660,10 +654,10 @@ 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;
FVector3 nearPt, up, right;
float scale;
p.Init(vtx, 4);
p.Set(&glseg);
if (!p.ValidNormal())
{
@ -675,15 +669,15 @@ bool GLWall::PrepareLight(ADynamicLight * light, int pass)
return false;
}
Vector t1;
FVector3 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;
t1 = &vtx[i * 3];
FVector3 nearToVert = t1 - nearPt;
tcs[i].u = ((nearToVert | right) * scale) + 0.5f;
tcs[i].v = ((nearToVert | up) * scale) + 0.5f;
// quick check whether the light touches this polygon
if (tcs[i].u<0) outcnt[0]++;