mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-23 04:22:34 +00:00
Merge branch 'dynlightmodels'
This commit is contained in:
commit
c3562fead2
11 changed files with 163 additions and 9 deletions
|
@ -59,6 +59,7 @@ struct FDynLightData
|
||||||
|
|
||||||
|
|
||||||
bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, FDynLightData &data);
|
bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, FDynLightData &data);
|
||||||
|
void gl_AddLightToList(int group, ADynamicLight * light, FDynLightData &ldata, bool hudmodel);
|
||||||
void gl_UploadLights(FDynLightData &data);
|
void gl_UploadLights(FDynLightData &data);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -65,12 +65,10 @@ CVAR(Int, gl_attenuate, -1, 0); // This is mainly a debug option.
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, FDynLightData &ldata)
|
bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, FDynLightData &ldata)
|
||||||
{
|
{
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
DVector3 pos = light->PosRelative(group);
|
DVector3 pos = light->PosRelative(group);
|
||||||
|
float radius = (light->GetRadius());
|
||||||
|
|
||||||
float dist = fabsf(p.DistToPoint(pos.X, pos.Z, pos.Y));
|
float dist = fabsf(p.DistToPoint(pos.X, pos.Z, pos.Y));
|
||||||
float radius = (light->GetRadius());
|
|
||||||
|
|
||||||
if (radius <= 0.f) return false;
|
if (radius <= 0.f) return false;
|
||||||
if (dist > radius) return false;
|
if (dist > radius) return false;
|
||||||
|
@ -79,6 +77,46 @@ bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, FD
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gl_AddLightToList(group, light, ldata, false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Add one dynamic light to the light data list
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
void gl_AddLightToList(int group, ADynamicLight * light, FDynLightData &ldata, bool hudmodel)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
DVector3 pos = light->PosRelative(group);
|
||||||
|
float radius = light->GetRadius();
|
||||||
|
|
||||||
|
if (hudmodel)
|
||||||
|
{
|
||||||
|
// HUD model is already translated and rotated. We must rotate the lights into that view space.
|
||||||
|
|
||||||
|
DVector3 rotation;
|
||||||
|
DVector3 localpos = pos - r_viewpoint.Pos;
|
||||||
|
|
||||||
|
rotation.X = localpos.X * r_viewpoint.Angles.Yaw.Sin() - localpos.Y * r_viewpoint.Angles.Yaw.Cos();
|
||||||
|
rotation.Y = localpos.X * r_viewpoint.Angles.Yaw.Cos() + localpos.Y * r_viewpoint.Angles.Yaw.Sin();
|
||||||
|
rotation.Z = localpos.Z;
|
||||||
|
localpos = rotation;
|
||||||
|
|
||||||
|
rotation.X = localpos.X;
|
||||||
|
rotation.Y = localpos.Y * r_viewpoint.Angles.Pitch.Sin() - localpos.Z * r_viewpoint.Angles.Pitch.Cos();
|
||||||
|
rotation.Z = localpos.Y * r_viewpoint.Angles.Pitch.Cos() + localpos.Z * r_viewpoint.Angles.Pitch.Sin();
|
||||||
|
localpos = rotation;
|
||||||
|
|
||||||
|
rotation.Y = localpos.Y;
|
||||||
|
rotation.Z = localpos.Z * r_viewpoint.Angles.Roll.Sin() - localpos.X * r_viewpoint.Angles.Roll.Cos();
|
||||||
|
rotation.X = localpos.Z * r_viewpoint.Angles.Roll.Cos() + localpos.X * r_viewpoint.Angles.Roll.Sin();
|
||||||
|
localpos = rotation;
|
||||||
|
|
||||||
|
pos = localpos;
|
||||||
|
}
|
||||||
|
|
||||||
float cs;
|
float cs;
|
||||||
if (light->IsAdditive())
|
if (light->IsAdditive())
|
||||||
|
@ -124,6 +162,5 @@ bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, FD
|
||||||
data[5] = g;
|
data[5] = g;
|
||||||
data[6] = b;
|
data[6] = b;
|
||||||
data[7] = shadowIndex;
|
data[7] = shadowIndex;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1099,6 +1099,9 @@ void gl_RenderHUDModel(DPSprite *psp, float ofsX, float ofsY)
|
||||||
// so we have to reset the view matrix.
|
// so we have to reset the view matrix.
|
||||||
gl_RenderState.mViewMatrix.loadIdentity();
|
gl_RenderState.mViewMatrix.loadIdentity();
|
||||||
|
|
||||||
|
// Need to reset the normal matrix too
|
||||||
|
gl_RenderState.mNormalViewMatrix.loadIdentity();
|
||||||
|
|
||||||
// Scaling model (y scale for a sprite means height, i.e. z in the world!).
|
// Scaling model (y scale for a sprite means height, i.e. z in the world!).
|
||||||
gl_RenderState.mViewMatrix.scale(smf->xscale, smf->zscale, smf->yscale);
|
gl_RenderState.mViewMatrix.scale(smf->xscale, smf->zscale, smf->yscale);
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,8 @@
|
||||||
#include "gl/shaders/gl_shader.h"
|
#include "gl/shaders/gl_shader.h"
|
||||||
#include "gl/data/gl_vertexbuffer.h"
|
#include "gl/data/gl_vertexbuffer.h"
|
||||||
|
|
||||||
|
extern int modellightindex;
|
||||||
|
|
||||||
static float avertexnormals[NUMVERTEXNORMALS][3] = {
|
static float avertexnormals[NUMVERTEXNORMALS][3] = {
|
||||||
#include "tab_anorms.h"
|
#include "tab_anorms.h"
|
||||||
};
|
};
|
||||||
|
@ -379,6 +381,7 @@ void FDMDModel::RenderFrame(FTexture * skin, int frameno, int frameno2, double i
|
||||||
gl_RenderState.SetInterpolationFactor((float)inter);
|
gl_RenderState.SetInterpolationFactor((float)inter);
|
||||||
|
|
||||||
gl_RenderState.Apply();
|
gl_RenderState.Apply();
|
||||||
|
if (modellightindex != -1) gl_RenderState.ApplyLightIndex(modellightindex);
|
||||||
mVBuf->SetupFrame(frames[frameno].vindex, frames[frameno2].vindex, lodInfo[0].numTriangles * 3);
|
mVBuf->SetupFrame(frames[frameno].vindex, frames[frameno2].vindex, lodInfo[0].numTriangles * 3);
|
||||||
glDrawArrays(GL_TRIANGLES, 0, lodInfo[0].numTriangles * 3);
|
glDrawArrays(GL_TRIANGLES, 0, lodInfo[0].numTriangles * 3);
|
||||||
gl_RenderState.SetInterpolationFactor(0.f);
|
gl_RenderState.SetInterpolationFactor(0.f);
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
|
|
||||||
#define MAX_QPATH 64
|
#define MAX_QPATH 64
|
||||||
|
|
||||||
|
extern int modellightindex;
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// decode the lat/lng normal to a 3 float normal
|
// decode the lat/lng normal to a 3 float normal
|
||||||
|
@ -372,6 +374,7 @@ void FMD3Model::RenderFrame(FTexture * skin, int frameno, int frameno2, double i
|
||||||
gl_RenderState.SetMaterial(tex, CLAMP_NONE, translation, -1, false);
|
gl_RenderState.SetMaterial(tex, CLAMP_NONE, translation, -1, false);
|
||||||
|
|
||||||
gl_RenderState.Apply();
|
gl_RenderState.Apply();
|
||||||
|
if (modellightindex != -1) gl_RenderState.ApplyLightIndex(modellightindex);
|
||||||
mVBuf->SetupFrame(surf->vindex + frameno * surf->numVertices, surf->vindex + frameno2 * surf->numVertices, surf->numVertices);
|
mVBuf->SetupFrame(surf->vindex + frameno * surf->numVertices, surf->vindex + frameno2 * surf->numVertices, surf->numVertices);
|
||||||
glDrawElements(GL_TRIANGLES, surf->numTriangles * 3, GL_UNSIGNED_INT, (void*)(intptr_t)(surf->iindex * sizeof(unsigned int)));
|
glDrawElements(GL_TRIANGLES, surf->numTriangles * 3, GL_UNSIGNED_INT, (void*)(intptr_t)(surf->iindex * sizeof(unsigned int)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
#include "gl/utility/gl_convert.h"
|
#include "gl/utility/gl_convert.h"
|
||||||
#include "gl/renderer/gl_renderstate.h"
|
#include "gl/renderer/gl_renderstate.h"
|
||||||
|
|
||||||
|
extern int modellightindex;
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
|
@ -445,6 +446,7 @@ void FVoxelModel::RenderFrame(FTexture * skin, int frame, int frame2, double int
|
||||||
gl_RenderState.SetMaterial(tex, CLAMP_NOFILTER, translation, -1, false);
|
gl_RenderState.SetMaterial(tex, CLAMP_NOFILTER, translation, -1, false);
|
||||||
|
|
||||||
gl_RenderState.Apply();
|
gl_RenderState.Apply();
|
||||||
|
if (modellightindex != -1) gl_RenderState.ApplyLightIndex(modellightindex);
|
||||||
mVBuf->SetupFrame(0, 0, 0);
|
mVBuf->SetupFrame(0, 0, 0);
|
||||||
glDrawElements(GL_TRIANGLES, mNumIndices, GL_UNSIGNED_INT, (void*)(intptr_t)0);
|
glDrawElements(GL_TRIANGLES, mNumIndices, GL_UNSIGNED_INT, (void*)(intptr_t)0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -328,6 +328,9 @@ void GLSprite::Draw(int pass)
|
||||||
{
|
{
|
||||||
if (gl_lights && GLRenderer->mLightCount && mDrawer->FixedColormap == CM_DEFAULT && !fullbright)
|
if (gl_lights && GLRenderer->mLightCount && mDrawer->FixedColormap == CM_DEFAULT && !fullbright)
|
||||||
{
|
{
|
||||||
|
if (modelframe && !particle)
|
||||||
|
gl_SetDynModelLight(gl_light_sprites ? actor : NULL, false);
|
||||||
|
else
|
||||||
gl_SetDynSpriteLight(gl_light_sprites ? actor : NULL, gl_light_particles ? particle : NULL);
|
gl_SetDynSpriteLight(gl_light_sprites ? actor : NULL, gl_light_particles ? particle : NULL);
|
||||||
}
|
}
|
||||||
sector_t *cursec = actor ? actor->Sector : particle ? particle->subsector->sector : nullptr;
|
sector_t *cursec = actor ? actor->Sector : particle ? particle->subsector->sector : nullptr;
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
#include "vectors.h"
|
#include "vectors.h"
|
||||||
#include "gl/gl_functions.h"
|
#include "gl/gl_functions.h"
|
||||||
#include "g_level.h"
|
#include "g_level.h"
|
||||||
|
#include "g_levellocals.h"
|
||||||
|
#include "actorinlines.h"
|
||||||
|
|
||||||
#include "gl/system/gl_cvars.h"
|
#include "gl/system/gl_cvars.h"
|
||||||
#include "gl/renderer/gl_renderer.h"
|
#include "gl/renderer/gl_renderer.h"
|
||||||
|
@ -42,7 +44,10 @@
|
||||||
#include "gl/scene/gl_portal.h"
|
#include "gl/scene/gl_portal.h"
|
||||||
#include "gl/shaders/gl_shader.h"
|
#include "gl/shaders/gl_shader.h"
|
||||||
#include "gl/textures/gl_material.h"
|
#include "gl/textures/gl_material.h"
|
||||||
|
#include "gl/dynlights/gl_lightbuffer.h"
|
||||||
|
|
||||||
|
FDynLightData modellightdata;
|
||||||
|
int modellightindex = -1;
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -114,6 +119,7 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *
|
||||||
node = node->nextLight;
|
node = node->nextLight;
|
||||||
}
|
}
|
||||||
gl_RenderState.SetDynLight(out[0], out[1], out[2]);
|
gl_RenderState.SetDynLight(out[0], out[1], out[2]);
|
||||||
|
modellightindex = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gl_SetDynSpriteLight(AActor *thing, particle_t *particle)
|
void gl_SetDynSpriteLight(AActor *thing, particle_t *particle)
|
||||||
|
@ -127,3 +133,94 @@ void gl_SetDynSpriteLight(AActor *thing, particle_t *particle)
|
||||||
gl_SetDynSpriteLight(NULL, particle->Pos.X, particle->Pos.Y, particle->Pos.Z, particle->subsector);
|
gl_SetDynSpriteLight(NULL, particle->Pos.X, particle->Pos.Y, particle->Pos.Z, particle->subsector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if circle potentially intersects with node AABB
|
||||||
|
static bool CheckBBoxCircle(float *bbox, float x, float y, float radiusSquared)
|
||||||
|
{
|
||||||
|
float centerX = (bbox[BOXRIGHT] + bbox[BOXLEFT]) * 0.5f;
|
||||||
|
float centerY = (bbox[BOXBOTTOM] + bbox[BOXTOP]) * 0.5f;
|
||||||
|
float extentX = (bbox[BOXRIGHT] - bbox[BOXLEFT]) * 0.5f;
|
||||||
|
float extentY = (bbox[BOXBOTTOM] - bbox[BOXTOP]) * 0.5f;
|
||||||
|
float aabbRadiusSquared = extentX * extentX + extentY * extentY;
|
||||||
|
x -= centerX;
|
||||||
|
y -= centerY;
|
||||||
|
float dist = x * x + y * y;
|
||||||
|
return dist <= radiusSquared + aabbRadiusSquared;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Callback>
|
||||||
|
void BSPNodeWalkCircle(void *node, float x, float y, float radiusSquared, const Callback &callback)
|
||||||
|
{
|
||||||
|
while (!((size_t)node & 1))
|
||||||
|
{
|
||||||
|
node_t *bsp = (node_t *)node;
|
||||||
|
|
||||||
|
if (CheckBBoxCircle(bsp->bbox[0], x, y, radiusSquared))
|
||||||
|
BSPNodeWalkCircle(bsp->children[0], x, y, radiusSquared, callback);
|
||||||
|
|
||||||
|
if (!CheckBBoxCircle(bsp->bbox[1], x, y, radiusSquared))
|
||||||
|
return;
|
||||||
|
|
||||||
|
node = bsp->children[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
subsector_t *sub = (subsector_t *)((uint8_t *)node - 1);
|
||||||
|
callback(sub);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Callback>
|
||||||
|
void BSPWalkCircle(float x, float y, float radiusSquared, const Callback &callback)
|
||||||
|
{
|
||||||
|
if (level.nodes.Size() == 0)
|
||||||
|
callback(&level.subsectors[0]);
|
||||||
|
else
|
||||||
|
BSPNodeWalkCircle(level.HeadNode(), x, y, radiusSquared, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gl_SetDynModelLight(AActor *self, bool hudmodel)
|
||||||
|
{
|
||||||
|
modellightdata.Clear();
|
||||||
|
|
||||||
|
if (self)
|
||||||
|
{
|
||||||
|
static std::vector<ADynamicLight*> addedLights; // static so that we build up a reserve (memory allocations stop)
|
||||||
|
|
||||||
|
addedLights.clear();
|
||||||
|
|
||||||
|
float x = self->X();
|
||||||
|
float y = self->Y();
|
||||||
|
float z = self->Center();
|
||||||
|
float radiusSquared = self->renderradius * self->renderradius;
|
||||||
|
|
||||||
|
BSPWalkCircle(x, y, radiusSquared, [&](subsector_t *subsector) // Iterate through all subsectors potentially touched by actor
|
||||||
|
{
|
||||||
|
FLightNode * node = subsector->lighthead;
|
||||||
|
while (node) // check all lights touching a subsector
|
||||||
|
{
|
||||||
|
ADynamicLight *light = node->lightsource;
|
||||||
|
if (light->visibletoplayer && !(light->flags2&MF2_DORMANT) && (!(light->lightflags&LF_DONTLIGHTSELF) || light->target != self) && !(light->lightflags&LF_DONTLIGHTACTORS))
|
||||||
|
{
|
||||||
|
int group = subsector->sector->PortalGroup;
|
||||||
|
DVector3 pos = light->PosRelative(group);
|
||||||
|
float radius = light->GetRadius();
|
||||||
|
double dx = pos.X - x;
|
||||||
|
double dy = pos.Y - y;
|
||||||
|
double dz = pos.Z - z;
|
||||||
|
double distSquared = dx * dx + dy * dy + dz * dz;
|
||||||
|
if (distSquared < radiusSquared + radius * radius) // Light and actor touches
|
||||||
|
{
|
||||||
|
if (std::find(addedLights.begin(), addedLights.end(), light) == addedLights.end()) // Check if we already added this light from a different subsector
|
||||||
|
{
|
||||||
|
gl_AddLightToList(group, light, modellightdata, hudmodel);
|
||||||
|
addedLights.push_back(light);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node = node->nextLight;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_RenderState.SetDynLight(0, 0, 0);
|
||||||
|
modellightindex = GLRenderer->mLights->UploadLights(modellightdata);
|
||||||
|
}
|
||||||
|
|
|
@ -422,5 +422,6 @@ inline float Dist2(float x1,float y1,float x2,float y2)
|
||||||
|
|
||||||
void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *subsec);
|
void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *subsec);
|
||||||
void gl_SetDynSpriteLight(AActor *actor, particle_t *particle);
|
void gl_SetDynSpriteLight(AActor *actor, particle_t *particle);
|
||||||
|
void gl_SetDynModelLight(AActor *self, bool hudmodel);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -420,6 +420,10 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
||||||
{
|
{
|
||||||
if (gl_lights && GLRenderer->mLightCount && FixedColormap == CM_DEFAULT && gl_light_sprites)
|
if (gl_lights && GLRenderer->mLightCount && FixedColormap == CM_DEFAULT && gl_light_sprites)
|
||||||
{
|
{
|
||||||
|
FSpriteModelFrame *smf = playermo->player->ReadyWeapon ? gl_FindModelFrame(playermo->player->ReadyWeapon->GetClass(), psp->GetState()->sprite, psp->GetState()->GetFrame(), false) : nullptr;
|
||||||
|
if (smf)
|
||||||
|
gl_SetDynModelLight(playermo, true);
|
||||||
|
else
|
||||||
gl_SetDynSpriteLight(playermo, NULL);
|
gl_SetDynSpriteLight(playermo, NULL);
|
||||||
}
|
}
|
||||||
SetColor(ll, 0, cmc, trans, true);
|
SetColor(ll, 0, cmc, trans, true);
|
||||||
|
|
|
@ -62,7 +62,7 @@ void main()
|
||||||
gl_ClipDistance[4] = worldcoord.y + ((uSplitBottomPlane.w + uSplitBottomPlane.x * worldcoord.x + uSplitBottomPlane.y * worldcoord.z) * uSplitBottomPlane.z);
|
gl_ClipDistance[4] = worldcoord.y + ((uSplitBottomPlane.w + uSplitBottomPlane.x * worldcoord.x + uSplitBottomPlane.y * worldcoord.z) * uSplitBottomPlane.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
vWorldNormal = NormalModelMatrix * normalize(aNormal);
|
vWorldNormal = NormalModelMatrix * vec4(normalize(aNormal.xyz), 1.0);
|
||||||
vEyeNormal = NormalViewMatrix * vWorldNormal;
|
vEyeNormal = NormalViewMatrix * vWorldNormal;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue