Merge pull request #315 from 0x4E69676874466F78/fonarik

This commit is contained in:
Ivan Avdeev 2021-12-30 09:02:30 -08:00 committed by GitHub
commit 7f846eaddd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 129 additions and 4 deletions

View File

@ -63,6 +63,7 @@ GNU General Public License for more details.
#define PARM_TEX_MEMORY 38 // returns total memory of uploaded texture in bytes
#define PARM_DELUXEDATA 39 // nasty hack, convert int to pointer
#define PARM_SHADOWDATA 40 // nasty hack, convert int to pointer
#define PARM_MODERNFLASHLIGHT 41 // new dynamic flashlight, initially for Vulkan render
// skybox ordering
enum

View File

@ -2696,11 +2696,14 @@ void CL_AddEntityEffects( cl_entity_t *ent )
if( FBitSet( ent->curstate.effects, EF_BRIGHTFIELD ))
R_EntityParticles( ent );
if( FBitSet( ent->curstate.effects, EF_DIMLIGHT ))
if ( FBitSet( ent->curstate.effects, EF_DIMLIGHT ))
{
if( ent->player && !Host_IsQuakeCompatible( ))
if ( ent->player && !Host_IsQuakeCompatible( ))
{
CL_UpdateFlashlight( ent );
if ( !REF_GET_PARM( PARM_MODERNFLASHLIGHT, 1))
{
CL_UpdateFlashlight( ent );
}
}
else
{

View File

@ -15,6 +15,10 @@
#include <string.h>
#include <ctype.h> // isalnum...
#include "camera.h"
#include "pm_defs.h"
#include "pmtrace.h"
#define PROFILER_SCOPES(X) \
X(finalize , "VK_LightsFrameFinalize"); \
X(emissive_surface, "VK_LightsAddEmissiveSurface"); \
@ -836,6 +840,101 @@ static int addSpotLight( const vk_light_entity_t *le, float radius, int lightsty
return index;
}
void R_LightAddFlashlight(const struct cl_entity_s *ent, qboolean local_player ) {
// parameters
const float hack_attenuation = 0.1;
float radius = 1.0;
// TODO: better tune it
const float _cone = 10.0;
const float _cone2 = 30.0;
const vec3_t light_color = {255, 255, 192};
float light_intensity = 300;
vec3_t color;
vec3_t origin;
vec3_t angles;
vk_light_entity_t le;
float thirdperson_offset = 25;
vec3_t forward, view_ofs;
vec3_t vecSrc, vecEnd;
pmtrace_t *trace;
if( local_player )
{
// local player case
// position
if (gEngine.EngineGetParm(PARM_THIRDPERSON, 0)) { // thirdperson
AngleVectors( g_camera.viewangles, forward, NULL, NULL );
view_ofs[0] = view_ofs[1] = 0.0f;
if( ent->curstate.usehull == 1 ) {
view_ofs[2] = 12.0f; // VEC_DUCK_VIEW;
} else {
view_ofs[2] = 28.0f; // DEFAULT_VIEWHEIGHT
}
VectorAdd( ent->origin, view_ofs, vecSrc );
VectorMA( vecSrc, thirdperson_offset, forward, vecEnd );
trace = gEngine.EV_VisTraceLine( vecSrc, vecEnd, PM_STUDIO_BOX );
VectorCopy( trace->endpos, origin );
VectorCopy( forward, le.dir);
} else { // firstperson
// based on https://github.com/SNMetamorph/PrimeXT/blob/0869b1abbddd13c1229769d8cd71941610be0bf3/client/flashlight.cpp#L35
origin[0] = g_camera.vieworg[0] + (g_camera.vright[0] * (-4.0f)) + (g_camera.vforward[0] * 14.0); // forward-back
origin[1] = g_camera.vieworg[1] + (g_camera.vright[1] * (-4.0f)) + (g_camera.vforward[1] * 14.0); // left-right
origin[2] = g_camera.vieworg[2] + (g_camera.vright[2] * (-4.0f)) + (g_camera.vforward[2] * 14.0); // up-down
origin[2] += 2.0f;
VectorCopy(g_camera.vforward, le.dir);
}
}
else // non-local player case
{
thirdperson_offset = 10;
radius = 10;
light_intensity = 60;
VectorCopy( ent->angles, angles );
// NOTE: pitch divided by 3.0 twice. So we need apply 3^2 = 9
angles[PITCH] = ent->curstate.angles[PITCH] * 9.0f;
angles[YAW] = ent->angles[YAW];
angles[ROLL] = 0.0f; // roll not used
AngleVectors( angles, angles, NULL, NULL );
view_ofs[0] = view_ofs[1] = 0.0f;
if( ent->curstate.usehull == 1 ) {
view_ofs[2] = 12.0f; // VEC_DUCK_VIEW;
} else {
view_ofs[2] = 28.0f; // DEFAULT_VIEWHEIGHT
}
VectorAdd( ent->origin, view_ofs, vecSrc );
VectorMA( vecSrc, thirdperson_offset, angles, vecEnd );
trace = gEngine.EV_VisTraceLine( vecSrc, vecEnd, PM_STUDIO_BOX );
VectorCopy( trace->endpos, origin );
VectorCopy( angles, le.dir );
}
VectorCopy(origin, le.origin);
// prepare colors by parseEntPropRgbav
VectorScale(light_color, light_intensity / 255.0f, color);
// convert colors by weirdGoldsrcLightScaling
float l1 = Q_max(color[0], Q_max(color[1], color[2]));
l1 = l1 * l1 / 10;
VectorScale(color, l1, le.color);
// convert stopdots by parseStopDot
le.stopdot = cosf(_cone * M_PI / 180.f);
le.stopdot2 = cosf(_cone2 * M_PI / 180.f);
/*
gEngine.Con_Printf("flashlight: origin=(%f %f %f) color=(%f %f %f) dir=(%f %f %f)\n",
le.origin[0], le.origin[1], le.origin[2],
le.color[0], le.color[1], le.color[2],
le.dir[0], le.dir[1], le.dir[2]);
*/
addSpotLight(&le, radius, 0, hack_attenuation, false);
}
static float sphereSolidAngleFromDistDiv2Pi(float r, float d) {
return 1. - sqrt(d*d - r*r)/d;
}

View File

@ -92,3 +92,6 @@ void XVK_GetEmissiveForTexture( vec3_t out, int texture_id );
void VK_LightsFrameFinalize( void );
int R_LightCellIndex( const int light_cell[3] );
struct cl_entity_s;
void R_LightAddFlashlight( const struct cl_entity_s *ent, qboolean local_player );

View File

@ -1,4 +1,5 @@
#include "vk_core.h"
#include "vk_cvar.h"
#include "vk_common.h"
#include "vk_textures.h"
#include "vk_renderstate.h"
@ -228,6 +229,7 @@ static const char *getParmName(int parm)
case PARM_TEX_MEMORY: return "PARM_TEX_MEMORY";
case PARM_DELUXEDATA: return "PARM_DELUXEDATA";
case PARM_SHADOWDATA: return "PARM_SHADOWDATA";
case PARM_MODERNFLASHLIGHT: return "PARM_MODERNFLASHLIGHT";
default: return "UNKNOWN";
}
}
@ -248,6 +250,11 @@ static int VK_RefGetParm( int parm, int arg )
case PARM_TEX_FLAGS:
tex = findTexture(arg);
return tex->flags;
case PARM_MODERNFLASHLIGHT:
if (CVAR_TO_BOOL( vk_rtx )) {
return true;
}
return false;
}
PRINT_NOT_IMPLEMENTED_ARGS("(%s(%d), %d)", getParmName(parm), parm, arg);

View File

@ -596,7 +596,7 @@ static void drawEntity( cl_entity_t *ent, int render_mode )
static float g_frametime = 0;
void VK_SceneRender( const ref_viewpass_t *rvp ) {
int current_pipeline_index = kRenderNormal;
const cl_entity_t* const local_player = gEngine.GetLocalPlayer();
g_frametime = /*FIXME VK RP_NORMALPASS( )) ? */
gpGlobals->time - gpGlobals->oldtime
@ -629,11 +629,23 @@ void VK_SceneRender( const ref_viewpass_t *rvp ) {
}
}
{
// Draw flashlight for local player
if( FBitSet( local_player->curstate.effects, EF_DIMLIGHT )) {
R_LightAddFlashlight(local_player, true);
}
}
// Draw opaque entities
for (int i = 0; i < g_lists.draw_list->num_solid_entities; ++i)
{
cl_entity_t *ent = g_lists.draw_list->solid_entities[i];
drawEntity(ent, kRenderNormal);
// Draw flashlight for other players
if( FBitSet( ent->curstate.effects, EF_DIMLIGHT ) && ent != local_player) {
R_LightAddFlashlight(ent, false);
}
}
// Draw opaque beams