2001-02-19 21:15:25 +00:00
|
|
|
/*
|
|
|
|
r_main.c
|
|
|
|
|
2001-05-15 04:50:53 +00:00
|
|
|
(description)
|
2001-02-19 21:15:25 +00:00
|
|
|
|
|
|
|
Copyright (C) 1996-1997 Id Software, Inc.
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
|
|
|
as published by the Free Software Foundation; either version 2
|
|
|
|
of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to:
|
|
|
|
|
|
|
|
Free Software Foundation, Inc.
|
|
|
|
59 Temple Place - Suite 330
|
|
|
|
Boston, MA 02111-1307, USA
|
|
|
|
|
|
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
2003-01-15 15:31:36 +00:00
|
|
|
|
2001-05-15 04:50:53 +00:00
|
|
|
#ifdef HAVE_STRING_H
|
|
|
|
# include <string.h>
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_STRINGS_H
|
|
|
|
# include <strings.h>
|
|
|
|
#endif
|
2003-01-15 16:53:34 +00:00
|
|
|
#ifdef HAVE_STDLIB_H
|
|
|
|
# include <stdlib.h>
|
|
|
|
#endif
|
2001-05-15 04:50:53 +00:00
|
|
|
|
|
|
|
#include <math.h>
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-03-27 20:33:07 +00:00
|
|
|
#include "QF/cmd.h"
|
2001-05-10 06:01:11 +00:00
|
|
|
|
2021-07-24 05:19:52 +00:00
|
|
|
#include "QF/scene/entity.h"
|
|
|
|
|
2004-07-11 00:37:48 +00:00
|
|
|
#include "compat.h"
|
2012-04-10 04:27:53 +00:00
|
|
|
#include "mod_internal.h"
|
2012-02-14 08:28:09 +00:00
|
|
|
#include "r_internal.h"
|
2012-02-17 07:13:56 +00:00
|
|
|
#include "vid_internal.h"
|
2022-03-24 03:22:27 +00:00
|
|
|
#include "vid_sw.h"
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2002-06-10 22:52:13 +00:00
|
|
|
#ifdef PIC
|
|
|
|
# undef USE_INTEL_ASM //XXX asm pic hack
|
|
|
|
#endif
|
|
|
|
|
2022-03-29 04:08:58 +00:00
|
|
|
const byte *r_colormap;
|
2001-02-26 06:48:02 +00:00
|
|
|
int r_numallocatededges;
|
2023-06-13 09:06:11 +00:00
|
|
|
bool r_drawpolys;
|
|
|
|
bool r_drawculledpolys;
|
|
|
|
bool r_worldpolysbacktofront;
|
|
|
|
bool r_recursiveaffinetriangles = true;
|
2001-02-26 06:48:02 +00:00
|
|
|
int r_pixbytes = 1;
|
|
|
|
int r_outofsurfaces;
|
|
|
|
int r_outofedges;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2023-06-13 09:06:11 +00:00
|
|
|
bool r_viewchanged;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
int c_surf;
|
2012-02-18 05:34:14 +00:00
|
|
|
int r_maxsurfsseen, r_maxedgesseen;
|
|
|
|
static int r_cnumsurfs;
|
2023-06-13 09:06:11 +00:00
|
|
|
static bool r_surfsonstack;
|
2001-02-26 06:48:02 +00:00
|
|
|
int r_clipflags;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2012-02-18 05:34:14 +00:00
|
|
|
static byte *r_stack_start;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
|
|
|
// screen size info
|
2001-02-26 06:48:02 +00:00
|
|
|
float xcenter, ycenter;
|
|
|
|
float xscale, yscale;
|
|
|
|
float xscaleinv, yscaleinv;
|
|
|
|
float xscaleshrink, yscaleshrink;
|
|
|
|
float aliasxscale, aliasyscale, aliasxcenter, aliasycenter;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
int screenwidth;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
float pixelAspect;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2011-11-14 02:18:22 +00:00
|
|
|
plane_t screenedge[4];
|
2001-02-19 21:15:25 +00:00
|
|
|
|
|
|
|
// refresh flags
|
2001-02-26 06:48:02 +00:00
|
|
|
int r_polycount;
|
|
|
|
int r_drawnpolycount;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
int *pfrustum_indexes[4];
|
|
|
|
int r_frustum_indexes[4 * 6];
|
|
|
|
|
[renderer] Clean up use of vup/vright/vpn
This moves the common camera setup code out of the individual drivers,
and completely removes vup/vright/vpn from the non-software renderers.
This has highlighted the craziness around AngleVectors with it putting
+X forward, -Y right and +Z up. The main issue with this is it requires
a 90 degree pre-rotation about the Z axis to get the camera pointing in
the right direction, and that's for the native sw renderer (vulkan needs
a 90 degree pre-rotation about X, and gl and glsl need to invert an
axis, too), though at least it's just a matrix swizzle and vector
negation. However, it does mean the camera matrices can't be used
directly.
Also rename vpn to vfwd (still abbreviated, but fwd is much clearer in
meaning (to me, at least) than pn (plane normal, I guess, but which
way?)).
2022-03-14 00:34:24 +00:00
|
|
|
vec3_t vup, base_vup;
|
|
|
|
vec3_t vfwd, base_vfwd;
|
|
|
|
vec3_t vright, base_vright;
|
2022-03-14 02:56:10 +00:00
|
|
|
float r_viewmatrix[3][4];
|
[renderer] Clean up use of vup/vright/vpn
This moves the common camera setup code out of the individual drivers,
and completely removes vup/vright/vpn from the non-software renderers.
This has highlighted the craziness around AngleVectors with it putting
+X forward, -Y right and +Z up. The main issue with this is it requires
a 90 degree pre-rotation about the Z axis to get the camera pointing in
the right direction, and that's for the native sw renderer (vulkan needs
a 90 degree pre-rotation about X, and gl and glsl need to invert an
axis, too), though at least it's just a matrix swizzle and vector
negation. However, it does mean the camera matrices can't be used
directly.
Also rename vpn to vfwd (still abbreviated, but fwd is much clearer in
meaning (to me, at least) than pn (plane normal, I guess, but which
way?)).
2022-03-14 00:34:24 +00:00
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
float r_aliastransition, r_resfudge;
|
|
|
|
|
|
|
|
void
|
2012-02-22 13:12:29 +00:00
|
|
|
sw_R_Init (void)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2001-02-26 06:48:02 +00:00
|
|
|
int dummy;
|
|
|
|
|
2001-05-15 04:50:53 +00:00
|
|
|
// get stack position so we can guess if we are going to overflow
|
2001-02-26 06:48:02 +00:00
|
|
|
r_stack_start = (byte *) & dummy;
|
|
|
|
|
2012-04-10 04:27:53 +00:00
|
|
|
R_Init_Cvars ();
|
|
|
|
|
2012-02-14 08:28:09 +00:00
|
|
|
Draw_Init ();
|
2012-02-01 12:52:47 +00:00
|
|
|
SCR_Init ();
|
2002-06-07 15:09:20 +00:00
|
|
|
R_SetFPCW ();
|
2002-06-10 22:52:13 +00:00
|
|
|
#ifdef USE_INTEL_ASM
|
2002-06-03 07:23:41 +00:00
|
|
|
R_InitVars ();
|
2002-06-10 22:52:13 +00:00
|
|
|
#endif
|
2002-06-03 07:23:41 +00:00
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
R_InitTurb ();
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2001-05-15 21:13:07 +00:00
|
|
|
Cmd_AddCommand ("timerefresh", R_TimeRefresh_f, "Tests the current "
|
|
|
|
"refresh rate for the current location");
|
2001-05-15 04:50:53 +00:00
|
|
|
Cmd_AddCommand ("loadsky", R_LoadSky_f, "Load a skybox");
|
2001-02-26 06:48:02 +00:00
|
|
|
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
r_maxedges = NUMSTACKEDGES;
|
|
|
|
r_maxsurfs = NUMSTACKSURFACES;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
|
|
|
view_clipplanes[0].leftedge = true;
|
|
|
|
view_clipplanes[1].rightedge = true;
|
|
|
|
view_clipplanes[1].leftedge = view_clipplanes[2].leftedge =
|
2001-02-26 06:48:02 +00:00
|
|
|
view_clipplanes[3].leftedge = false;
|
2001-02-19 21:15:25 +00:00
|
|
|
view_clipplanes[0].rightedge = view_clipplanes[2].rightedge =
|
2001-02-26 06:48:02 +00:00
|
|
|
view_clipplanes[3].rightedge = false;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
|
|
|
// TODO: collect 386-specific code in one place
|
2001-05-15 04:50:53 +00:00
|
|
|
#ifdef USE_INTEL_ASM
|
2001-02-26 06:48:02 +00:00
|
|
|
Sys_MakeCodeWriteable ((long) R_EdgeCodeStart,
|
|
|
|
(long) R_EdgeCodeEnd - (long) R_EdgeCodeStart);
|
|
|
|
#endif // USE_INTEL_ASM
|
2001-02-19 21:15:25 +00:00
|
|
|
D_Init ();
|
2012-04-10 04:27:53 +00:00
|
|
|
|
|
|
|
Skin_Init ();
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
2022-10-25 10:36:09 +00:00
|
|
|
uint32_t
|
|
|
|
SW_AddEntity (entity_t ent)
|
|
|
|
{
|
|
|
|
// This takes advantage of the implicit (FIXME, make explicit) grouping of
|
|
|
|
// the sw components: as all entities that get added here will always have
|
|
|
|
// all three components, the three component pools are always in sync, thus
|
|
|
|
// the pool count can be used as a render id which can in turn be used to
|
|
|
|
// index the components within the pools.
|
|
|
|
ecs_registry_t *reg = ent.reg;
|
|
|
|
ecs_pool_t *pool = ®->comp_pools[scene_sw_matrix];
|
|
|
|
uint32_t render_id = pool->count;
|
|
|
|
|
|
|
|
transform_t transform = Entity_Transform (ent);
|
|
|
|
Ent_SetComponent (ent.id, scene_sw_matrix, reg,
|
|
|
|
Transform_GetWorldMatrixPtr (transform));
|
|
|
|
animation_t *animation = Ent_GetComponent (ent.id, scene_animation, reg);
|
|
|
|
Ent_SetComponent (ent.id, scene_sw_frame, reg, &animation->frame);
|
|
|
|
renderer_t *renderer = Ent_GetComponent (ent.id, scene_renderer, reg);
|
|
|
|
mod_brush_t *brush = &renderer->model->brush;
|
|
|
|
Ent_SetComponent (ent.id, scene_sw_brush, reg, &brush);
|
|
|
|
|
|
|
|
return render_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
reset_sw_components (ecs_registry_t *reg)
|
|
|
|
{
|
|
|
|
static uint32_t sw_comps[] = {
|
|
|
|
scene_sw_matrix,
|
|
|
|
scene_sw_frame,
|
|
|
|
scene_sw_brush,
|
|
|
|
};
|
|
|
|
|
|
|
|
for (int i = 0; i < 3; i++) {
|
|
|
|
ecs_pool_t *pool = ®->comp_pools[sw_comps[i]];
|
|
|
|
pool->count = 0; // remove component from every entity
|
|
|
|
// reserve first component object (render id 0) for the world
|
|
|
|
// pseudo-entity.
|
2022-10-26 03:32:09 +00:00
|
|
|
//FIXME takes advantage of the lack of checks for the validity of the
|
|
|
|
//entity id.
|
2022-10-25 10:36:09 +00:00
|
|
|
Ent_SetComponent (0, sw_comps[i], reg, 0);
|
|
|
|
// make sure entity 0 gets allocated a new component object as the
|
|
|
|
// world pseudo-entity currently has no actual entity (FIXME)
|
|
|
|
pool->dense[0] = nullent;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
void
|
2022-05-05 05:41:46 +00:00
|
|
|
R_NewScene (scene_t *scene)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2022-05-05 05:41:46 +00:00
|
|
|
model_t *worldmodel = scene->worldmodel;
|
2021-02-01 10:31:11 +00:00
|
|
|
mod_brush_t *brush = &worldmodel->brush;
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2022-10-25 10:36:09 +00:00
|
|
|
r_refdef.registry = scene->reg;
|
2022-03-14 06:27:43 +00:00
|
|
|
r_refdef.worldmodel = worldmodel;
|
2001-05-18 17:50:19 +00:00
|
|
|
|
2021-02-01 10:31:11 +00:00
|
|
|
if (brush->skytexture)
|
|
|
|
R_InitSky (brush->skytexture);
|
2004-11-06 02:21:00 +00:00
|
|
|
|
2012-01-29 07:09:35 +00:00
|
|
|
// Force a vis update
|
2022-05-22 07:31:24 +00:00
|
|
|
R_MarkLeaves (0, 0, 0, 0);
|
2012-01-29 07:09:35 +00:00
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
R_ClearParticles ();
|
|
|
|
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
r_cnumsurfs = r_maxsurfs;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
|
|
|
if (r_cnumsurfs <= MINSURFACES)
|
|
|
|
r_cnumsurfs = MINSURFACES;
|
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
if (r_cnumsurfs > NUMSTACKSURFACES) {
|
2021-07-28 06:01:45 +00:00
|
|
|
surfaces = Hunk_AllocName (0, r_cnumsurfs * sizeof (surf_t),
|
|
|
|
"surfaces");
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
surface_p = surfaces;
|
|
|
|
surf_max = &surfaces[r_cnumsurfs];
|
|
|
|
r_surfsonstack = false;
|
2001-02-26 06:48:02 +00:00
|
|
|
// surface 0 doesn't really exist; it's just a dummy because index 0
|
|
|
|
// is used to indicate no edge attached to surface
|
2001-02-19 21:15:25 +00:00
|
|
|
surfaces--;
|
|
|
|
R_SurfacePatch ();
|
2001-02-26 06:48:02 +00:00
|
|
|
} else {
|
2001-02-19 21:15:25 +00:00
|
|
|
r_surfsonstack = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
r_maxedgesseen = 0;
|
|
|
|
r_maxsurfsseen = 0;
|
|
|
|
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
r_numallocatededges = r_maxedges;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
|
|
|
if (r_numallocatededges < MINEDGES)
|
|
|
|
r_numallocatededges = MINEDGES;
|
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
if (r_numallocatededges <= NUMSTACKEDGES) {
|
2001-02-19 21:15:25 +00:00
|
|
|
auxedges = NULL;
|
2001-02-26 06:48:02 +00:00
|
|
|
} else {
|
2021-07-28 06:01:45 +00:00
|
|
|
auxedges = Hunk_AllocName (0, r_numallocatededges * sizeof (edge_t),
|
2001-02-19 21:15:25 +00:00
|
|
|
"edges");
|
|
|
|
}
|
|
|
|
|
|
|
|
r_dowarpold = false;
|
|
|
|
r_viewchanged = false;
|
|
|
|
}
|
|
|
|
|
2022-03-29 04:08:58 +00:00
|
|
|
void
|
|
|
|
R_SetColormap (const byte *cmap)
|
|
|
|
{
|
|
|
|
r_colormap = cmap;
|
2001-02-19 21:15:25 +00:00
|
|
|
// TODO: collect 386-specific code in one place
|
2001-05-15 04:50:53 +00:00
|
|
|
#ifdef USE_INTEL_ASM
|
2001-11-21 19:13:53 +00:00
|
|
|
Sys_MakeCodeWriteable ((long) R_Surf8Start,
|
|
|
|
(long) R_Surf8End - (long) R_Surf8Start);
|
|
|
|
R_SurfPatch ();
|
2001-02-26 06:48:02 +00:00
|
|
|
#endif // USE_INTEL_ASM
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
2022-03-02 06:00:32 +00:00
|
|
|
static inline void
|
[scene] Make entity_t just an entity id for ECS
This puts the hierarchy (transform) reference, animation, visibility,
renderer, active, and old_origin data in separate components. There are
a few bugs (crashes on grenade explosions in gl/glsl/vulkan, immediately
in sw, reasons known, missing brush models in vulkan).
While quake doesn't really need an ECS, the direction I want to take QF
does, and it does seem to have improved memory bandwidth a little
(uncertain). However, there's a lot more work to go (especially fixing
the above bugs), but this seems to be a good start.
2022-10-23 01:32:09 +00:00
|
|
|
draw_sprite_entity (entity_t ent)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2022-03-11 06:07:38 +00:00
|
|
|
R_DrawSprite (ent);
|
2022-03-02 06:00:32 +00:00
|
|
|
}
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2022-03-02 06:00:32 +00:00
|
|
|
static inline void
|
[scene] Make entity_t just an entity id for ECS
This puts the hierarchy (transform) reference, animation, visibility,
renderer, active, and old_origin data in separate components. There are
a few bugs (crashes on grenade explosions in gl/glsl/vulkan, immediately
in sw, reasons known, missing brush models in vulkan).
While quake doesn't really need an ECS, the direction I want to take QF
does, and it does seem to have improved memory bandwidth a little
(uncertain). However, there's a lot more work to go (especially fixing
the above bugs), but this seems to be a good start.
2022-10-23 01:32:09 +00:00
|
|
|
setup_lighting (entity_t ent, alight_t *lighting)
|
2022-03-02 06:00:32 +00:00
|
|
|
{
|
|
|
|
float minlight = 0;
|
|
|
|
int j;
|
2001-08-28 20:51:51 +00:00
|
|
|
// FIXME: remove and do real lighting
|
2001-02-26 06:48:02 +00:00
|
|
|
vec3_t dist;
|
|
|
|
float add;
|
2022-03-02 06:00:32 +00:00
|
|
|
float lightvec[3] = { -1, 0, 0 };
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2022-10-25 03:53:30 +00:00
|
|
|
renderer_t *renderer = Ent_GetComponent (ent.id, scene_renderer, ent.reg);
|
[scene] Make entity_t just an entity id for ECS
This puts the hierarchy (transform) reference, animation, visibility,
renderer, active, and old_origin data in separate components. There are
a few bugs (crashes on grenade explosions in gl/glsl/vulkan, immediately
in sw, reasons known, missing brush models in vulkan).
While quake doesn't really need an ECS, the direction I want to take QF
does, and it does seem to have improved memory bandwidth a little
(uncertain). However, there's a lot more work to go (especially fixing
the above bugs), but this seems to be a good start.
2022-10-23 01:32:09 +00:00
|
|
|
minlight = max (renderer->model->min_light, renderer->min_light);
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2022-03-02 06:00:32 +00:00
|
|
|
// 128 instead of 255 due to clamping below
|
2022-03-14 06:27:43 +00:00
|
|
|
j = max (R_LightPoint (&r_refdef.worldmodel->brush, r_entorigin),
|
2022-03-02 06:00:32 +00:00
|
|
|
minlight * 128);
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2022-03-02 06:00:32 +00:00
|
|
|
lighting->ambientlight = j;
|
|
|
|
lighting->shadelight = j;
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2022-03-17 06:04:30 +00:00
|
|
|
VectorCopy (lightvec, lighting->lightvec);
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2022-03-02 06:00:32 +00:00
|
|
|
for (unsigned lnum = 0; lnum < r_maxdlights; lnum++) {
|
|
|
|
if (r_dlights[lnum].die >= vr_data.realtime) {
|
|
|
|
VectorSubtract (r_entorigin, r_dlights[lnum].origin, dist);
|
|
|
|
add = r_dlights[lnum].radius - VectorLength (dist);
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2022-03-02 06:00:32 +00:00
|
|
|
if (add > 0)
|
|
|
|
lighting->ambientlight += add;
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
}
|
2022-03-02 06:00:32 +00:00
|
|
|
|
|
|
|
// clamp lighting so it doesn't overbright as much
|
|
|
|
if (lighting->ambientlight > 128)
|
|
|
|
lighting->ambientlight = 128;
|
|
|
|
if (lighting->ambientlight + lighting->shadelight > 192)
|
|
|
|
lighting->shadelight = 192 - lighting->ambientlight;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
[scene] Make entity_t just an entity id for ECS
This puts the hierarchy (transform) reference, animation, visibility,
renderer, active, and old_origin data in separate components. There are
a few bugs (crashes on grenade explosions in gl/glsl/vulkan, immediately
in sw, reasons known, missing brush models in vulkan).
While quake doesn't really need an ECS, the direction I want to take QF
does, and it does seem to have improved memory bandwidth a little
(uncertain). However, there's a lot more work to go (especially fixing
the above bugs), but this seems to be a good start.
2022-10-23 01:32:09 +00:00
|
|
|
draw_alias_entity (entity_t ent)
|
2022-03-02 06:00:32 +00:00
|
|
|
{
|
|
|
|
// see if the bounding box lets us trivially reject, also
|
|
|
|
// sets trivial accept status
|
[scene] Make entity_t just an entity id for ECS
This puts the hierarchy (transform) reference, animation, visibility,
renderer, active, and old_origin data in separate components. There are
a few bugs (crashes on grenade explosions in gl/glsl/vulkan, immediately
in sw, reasons known, missing brush models in vulkan).
While quake doesn't really need an ECS, the direction I want to take QF
does, and it does seem to have improved memory bandwidth a little
(uncertain). However, there's a lot more work to go (especially fixing
the above bugs), but this seems to be a good start.
2022-10-23 01:32:09 +00:00
|
|
|
visibility_t *visibility = Ent_GetComponent (ent.id, scene_visibility,
|
2022-10-25 03:53:30 +00:00
|
|
|
ent.reg);
|
[scene] Make entity_t just an entity id for ECS
This puts the hierarchy (transform) reference, animation, visibility,
renderer, active, and old_origin data in separate components. There are
a few bugs (crashes on grenade explosions in gl/glsl/vulkan, immediately
in sw, reasons known, missing brush models in vulkan).
While quake doesn't really need an ECS, the direction I want to take QF
does, and it does seem to have improved memory bandwidth a little
(uncertain). However, there's a lot more work to go (especially fixing
the above bugs), but this seems to be a good start.
2022-10-23 01:32:09 +00:00
|
|
|
visibility->trivial_accept = 0; //FIXME
|
2022-03-11 06:07:38 +00:00
|
|
|
if (R_AliasCheckBBox (ent)) {
|
2022-03-02 06:00:32 +00:00
|
|
|
alight_t lighting;
|
2022-03-11 06:07:38 +00:00
|
|
|
setup_lighting (ent, &lighting);
|
|
|
|
R_AliasDrawModel (ent, &lighting);
|
2022-03-02 06:00:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
[scene] Make entity_t just an entity id for ECS
This puts the hierarchy (transform) reference, animation, visibility,
renderer, active, and old_origin data in separate components. There are
a few bugs (crashes on grenade explosions in gl/glsl/vulkan, immediately
in sw, reasons known, missing brush models in vulkan).
While quake doesn't really need an ECS, the direction I want to take QF
does, and it does seem to have improved memory bandwidth a little
(uncertain). However, there's a lot more work to go (especially fixing
the above bugs), but this seems to be a good start.
2022-10-23 01:32:09 +00:00
|
|
|
draw_iqm_entity (entity_t ent)
|
2022-03-02 06:00:32 +00:00
|
|
|
{
|
|
|
|
// see if the bounding box lets us trivially reject, also
|
|
|
|
// sets trivial accept status
|
[scene] Make entity_t just an entity id for ECS
This puts the hierarchy (transform) reference, animation, visibility,
renderer, active, and old_origin data in separate components. There are
a few bugs (crashes on grenade explosions in gl/glsl/vulkan, immediately
in sw, reasons known, missing brush models in vulkan).
While quake doesn't really need an ECS, the direction I want to take QF
does, and it does seem to have improved memory bandwidth a little
(uncertain). However, there's a lot more work to go (especially fixing
the above bugs), but this seems to be a good start.
2022-10-23 01:32:09 +00:00
|
|
|
visibility_t *visibility = Ent_GetComponent (ent.id, scene_visibility,
|
2022-10-25 03:53:30 +00:00
|
|
|
ent.reg);
|
[scene] Make entity_t just an entity id for ECS
This puts the hierarchy (transform) reference, animation, visibility,
renderer, active, and old_origin data in separate components. There are
a few bugs (crashes on grenade explosions in gl/glsl/vulkan, immediately
in sw, reasons known, missing brush models in vulkan).
While quake doesn't really need an ECS, the direction I want to take QF
does, and it does seem to have improved memory bandwidth a little
(uncertain). However, there's a lot more work to go (especially fixing
the above bugs), but this seems to be a good start.
2022-10-23 01:32:09 +00:00
|
|
|
visibility->trivial_accept = 0; //FIXME
|
2022-03-02 06:00:32 +00:00
|
|
|
|
|
|
|
alight_t lighting;
|
2022-03-11 06:07:38 +00:00
|
|
|
setup_lighting (ent, &lighting);
|
|
|
|
R_IQMDrawModel (ent, &lighting);
|
2022-03-02 06:00:32 +00:00
|
|
|
}
|
|
|
|
|
2022-03-17 08:50:38 +00:00
|
|
|
void
|
|
|
|
R_DrawEntitiesOnList (entqueue_t *queue)
|
2022-03-02 06:00:32 +00:00
|
|
|
{
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
if (!r_drawentities)
|
2022-03-02 06:00:32 +00:00
|
|
|
return;
|
|
|
|
|
2022-03-21 12:59:07 +00:00
|
|
|
R_LowFPPrecision ();
|
2022-03-02 06:00:32 +00:00
|
|
|
#define RE_LOOP(type_name) \
|
|
|
|
do { \
|
2022-03-17 08:50:38 +00:00
|
|
|
for (size_t i = 0; i < queue->ent_queues[mod_##type_name].size; \
|
2022-03-04 16:48:10 +00:00
|
|
|
i++) { \
|
[scene] Make entity_t just an entity id for ECS
This puts the hierarchy (transform) reference, animation, visibility,
renderer, active, and old_origin data in separate components. There are
a few bugs (crashes on grenade explosions in gl/glsl/vulkan, immediately
in sw, reasons known, missing brush models in vulkan).
While quake doesn't really need an ECS, the direction I want to take QF
does, and it does seem to have improved memory bandwidth a little
(uncertain). However, there's a lot more work to go (especially fixing
the above bugs), but this seems to be a good start.
2022-10-23 01:32:09 +00:00
|
|
|
entity_t ent = queue->ent_queues[mod_##type_name].a[i]; \
|
|
|
|
transform_t transform = Entity_Transform (ent); \
|
|
|
|
r_entorigin = Transform_GetWorldPosition (transform); \
|
2022-03-02 06:00:32 +00:00
|
|
|
draw_##type_name##_entity (ent); \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
RE_LOOP (alias);
|
|
|
|
RE_LOOP (iqm);
|
|
|
|
RE_LOOP (sprite);
|
2022-03-21 12:59:07 +00:00
|
|
|
|
|
|
|
R_HighFPPrecision ();
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
2003-01-06 18:28:13 +00:00
|
|
|
static void
|
2001-02-26 06:48:02 +00:00
|
|
|
R_DrawViewModel (void)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2001-08-28 20:51:51 +00:00
|
|
|
// FIXME: remove and do real lighting
|
2001-02-26 06:48:02 +00:00
|
|
|
int j;
|
2003-04-17 00:01:48 +00:00
|
|
|
unsigned int lnum;
|
2001-02-26 06:48:02 +00:00
|
|
|
vec3_t dist;
|
|
|
|
float add;
|
2004-07-11 00:37:48 +00:00
|
|
|
float minlight;
|
2001-02-26 06:48:02 +00:00
|
|
|
dlight_t *dl;
|
[scene] Make entity_t just an entity id for ECS
This puts the hierarchy (transform) reference, animation, visibility,
renderer, active, and old_origin data in separate components. There are
a few bugs (crashes on grenade explosions in gl/glsl/vulkan, immediately
in sw, reasons known, missing brush models in vulkan).
While quake doesn't really need an ECS, the direction I want to take QF
does, and it does seem to have improved memory bandwidth a little
(uncertain). However, there's a lot more work to go (especially fixing
the above bugs), but this seems to be a good start.
2022-10-23 01:32:09 +00:00
|
|
|
entity_t viewent;
|
2022-03-17 06:04:30 +00:00
|
|
|
alight_t lighting;
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2012-02-14 08:28:09 +00:00
|
|
|
if (vr_data.inhibit_viewmodel
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
|| !r_drawviewmodel
|
|
|
|
|| !r_drawentities)
|
2001-02-19 21:15:25 +00:00
|
|
|
return;
|
|
|
|
|
2022-03-11 06:07:38 +00:00
|
|
|
viewent = vr_data.view_model;
|
2022-10-27 03:53:01 +00:00
|
|
|
if (!Entity_Valid (viewent)) {
|
|
|
|
return;
|
|
|
|
}
|
[scene] Make entity_t just an entity id for ECS
This puts the hierarchy (transform) reference, animation, visibility,
renderer, active, and old_origin data in separate components. There are
a few bugs (crashes on grenade explosions in gl/glsl/vulkan, immediately
in sw, reasons known, missing brush models in vulkan).
While quake doesn't really need an ECS, the direction I want to take QF
does, and it does seem to have improved memory bandwidth a little
(uncertain). However, there's a lot more work to go (especially fixing
the above bugs), but this seems to be a good start.
2022-10-23 01:32:09 +00:00
|
|
|
|
|
|
|
renderer_t *renderer = Ent_GetComponent (viewent.id, scene_renderer,
|
2022-10-25 03:53:30 +00:00
|
|
|
viewent.reg);
|
[scene] Make entity_t just an entity id for ECS
This puts the hierarchy (transform) reference, animation, visibility,
renderer, active, and old_origin data in separate components. There are
a few bugs (crashes on grenade explosions in gl/glsl/vulkan, immediately
in sw, reasons known, missing brush models in vulkan).
While quake doesn't really need an ECS, the direction I want to take QF
does, and it does seem to have improved memory bandwidth a little
(uncertain). However, there's a lot more work to go (especially fixing
the above bugs), but this seems to be a good start.
2022-10-23 01:32:09 +00:00
|
|
|
if (!renderer->model)
|
2001-02-19 21:15:25 +00:00
|
|
|
return;
|
|
|
|
|
2022-11-19 05:06:24 +00:00
|
|
|
if (!Ent_HasComponent (viewent.id, scene_visibility, viewent.reg)) {
|
|
|
|
// ensure the view model has a visibility component because one won't
|
|
|
|
// be added automatically, and the model rendering code expects there
|
|
|
|
// to be one
|
|
|
|
Ent_SetComponent (viewent.id, scene_visibility, viewent.reg, 0);
|
|
|
|
}
|
|
|
|
|
2022-10-25 03:53:30 +00:00
|
|
|
transform_t transform = Entity_Transform (viewent);
|
[scene] Make entity_t just an entity id for ECS
This puts the hierarchy (transform) reference, animation, visibility,
renderer, active, and old_origin data in separate components. There are
a few bugs (crashes on grenade explosions in gl/glsl/vulkan, immediately
in sw, reasons known, missing brush models in vulkan).
While quake doesn't really need an ECS, the direction I want to take QF
does, and it does seem to have improved memory bandwidth a little
(uncertain). However, there's a lot more work to go (especially fixing
the above bugs), but this seems to be a good start.
2022-10-23 01:32:09 +00:00
|
|
|
VectorCopy (Transform_GetWorldPosition (transform), r_entorigin);
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2022-03-17 06:04:30 +00:00
|
|
|
VectorNegate (vup, lighting.lightvec);
|
2001-02-19 21:15:25 +00:00
|
|
|
|
[scene] Make entity_t just an entity id for ECS
This puts the hierarchy (transform) reference, animation, visibility,
renderer, active, and old_origin data in separate components. There are
a few bugs (crashes on grenade explosions in gl/glsl/vulkan, immediately
in sw, reasons known, missing brush models in vulkan).
While quake doesn't really need an ECS, the direction I want to take QF
does, and it does seem to have improved memory bandwidth a little
(uncertain). However, there's a lot more work to go (especially fixing
the above bugs), but this seems to be a good start.
2022-10-23 01:32:09 +00:00
|
|
|
minlight = max (renderer->min_light, renderer->model->min_light);
|
2004-07-11 00:37:48 +00:00
|
|
|
|
2022-03-14 06:27:43 +00:00
|
|
|
j = max (R_LightPoint (&r_refdef.worldmodel->brush,
|
2021-03-19 11:18:45 +00:00
|
|
|
r_entorigin), minlight * 128);
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2022-03-17 06:04:30 +00:00
|
|
|
lighting.ambientlight = j;
|
|
|
|
lighting.shadelight = j;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2012-05-21 23:23:22 +00:00
|
|
|
// add dynamic lights
|
2001-10-09 20:35:17 +00:00
|
|
|
for (lnum = 0; lnum < r_maxdlights; lnum++) {
|
2001-05-20 05:42:52 +00:00
|
|
|
dl = &r_dlights[lnum];
|
2001-02-19 21:15:25 +00:00
|
|
|
if (!dl->radius)
|
|
|
|
continue;
|
|
|
|
if (!dl->radius)
|
|
|
|
continue;
|
2012-02-14 08:28:09 +00:00
|
|
|
if (dl->die < vr_data.realtime)
|
2001-02-19 21:15:25 +00:00
|
|
|
continue;
|
|
|
|
|
2021-03-19 11:18:45 +00:00
|
|
|
VectorSubtract (r_entorigin, dl->origin, dist);
|
2002-08-20 02:22:40 +00:00
|
|
|
add = dl->radius - VectorLength (dist);
|
2001-02-19 21:15:25 +00:00
|
|
|
if (add > 0)
|
2022-03-17 06:04:30 +00:00
|
|
|
lighting.ambientlight += add;
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
2001-05-15 21:13:07 +00:00
|
|
|
// clamp lighting so it doesn't overbright as much
|
2022-03-17 06:04:30 +00:00
|
|
|
if (lighting.ambientlight > 128)
|
|
|
|
lighting.ambientlight = 128;
|
|
|
|
if (lighting.ambientlight + lighting.shadelight > 192)
|
|
|
|
lighting.shadelight = 192 - lighting.ambientlight;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2022-03-17 06:04:30 +00:00
|
|
|
R_AliasDrawModel (viewent, &lighting);
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
2003-01-06 18:28:13 +00:00
|
|
|
static int
|
2022-10-25 10:36:09 +00:00
|
|
|
R_BmodelCheckBBox (const vec4f_t *transform, float radius, float *minmaxs)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2001-02-26 06:48:02 +00:00
|
|
|
int i, *pindex, clipflags;
|
|
|
|
vec3_t acceptpt, rejectpt;
|
|
|
|
double d;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
|
|
|
clipflags = 0;
|
|
|
|
|
2022-10-25 10:36:09 +00:00
|
|
|
if (transform[0][0] != 1 || transform[1][1] != 1 || transform[2][2] != 1) {
|
2001-02-26 06:48:02 +00:00
|
|
|
for (i = 0; i < 4; i++) {
|
2022-10-25 10:36:09 +00:00
|
|
|
d = DotProduct (transform[3], view_clipplanes[i].normal);
|
2001-02-19 21:15:25 +00:00
|
|
|
d -= view_clipplanes[i].dist;
|
|
|
|
|
2022-10-25 10:36:09 +00:00
|
|
|
if (d <= -radius)
|
2001-02-19 21:15:25 +00:00
|
|
|
return BMODEL_FULLY_CLIPPED;
|
|
|
|
|
2022-10-25 10:36:09 +00:00
|
|
|
if (d <= radius)
|
2001-02-26 06:48:02 +00:00
|
|
|
clipflags |= (1 << i);
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
2001-02-26 06:48:02 +00:00
|
|
|
} else {
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
|
|
// generate accept and reject points
|
2001-08-28 20:51:51 +00:00
|
|
|
// FIXME: do with fast look-ups or integer tests based on the
|
|
|
|
// sign bit of the floating point values
|
2001-02-19 21:15:25 +00:00
|
|
|
|
|
|
|
pindex = pfrustum_indexes[i];
|
|
|
|
|
|
|
|
rejectpt[0] = minmaxs[pindex[0]];
|
|
|
|
rejectpt[1] = minmaxs[pindex[1]];
|
|
|
|
rejectpt[2] = minmaxs[pindex[2]];
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
d = DotProduct (rejectpt, view_clipplanes[i].normal);
|
|
|
|
d -= view_clipplanes[i].dist;
|
|
|
|
|
|
|
|
if (d <= 0)
|
|
|
|
return BMODEL_FULLY_CLIPPED;
|
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
acceptpt[0] = minmaxs[pindex[3 + 0]];
|
|
|
|
acceptpt[1] = minmaxs[pindex[3 + 1]];
|
|
|
|
acceptpt[2] = minmaxs[pindex[3 + 2]];
|
2001-02-19 21:15:25 +00:00
|
|
|
|
|
|
|
d = DotProduct (acceptpt, view_clipplanes[i].normal);
|
|
|
|
d -= view_clipplanes[i].dist;
|
|
|
|
|
|
|
|
if (d <= 0)
|
2001-02-26 06:48:02 +00:00
|
|
|
clipflags |= (1 << i);
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return clipflags;
|
|
|
|
}
|
|
|
|
|
2003-01-06 18:28:13 +00:00
|
|
|
static void
|
2022-03-17 08:50:38 +00:00
|
|
|
R_DrawBrushEntitiesOnList (entqueue_t *queue)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2010-12-03 05:54:39 +00:00
|
|
|
int j, clipflags;
|
2003-04-17 00:01:48 +00:00
|
|
|
unsigned int k;
|
2021-03-19 11:18:45 +00:00
|
|
|
vec3_t origin;
|
2001-02-26 06:48:02 +00:00
|
|
|
float minmaxs[6];
|
2001-02-19 21:15:25 +00:00
|
|
|
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
if (!r_drawentities)
|
2001-02-19 21:15:25 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
insubmodel = true;
|
|
|
|
|
2022-03-17 08:50:38 +00:00
|
|
|
for (size_t i = 0; i < queue->ent_queues[mod_brush].size; i++) {
|
[scene] Make entity_t just an entity id for ECS
This puts the hierarchy (transform) reference, animation, visibility,
renderer, active, and old_origin data in separate components. There are
a few bugs (crashes on grenade explosions in gl/glsl/vulkan, immediately
in sw, reasons known, missing brush models in vulkan).
While quake doesn't really need an ECS, the direction I want to take QF
does, and it does seem to have improved memory bandwidth a little
(uncertain). However, there's a lot more work to go (especially fixing
the above bugs), but this seems to be a good start.
2022-10-23 01:32:09 +00:00
|
|
|
entity_t ent = queue->ent_queues[mod_brush].a[i];
|
2022-10-25 10:36:09 +00:00
|
|
|
uint32_t render_id = SW_AddEntity (ent);
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2022-10-25 10:36:09 +00:00
|
|
|
vec4f_t *transform = Ent_GetComponent (ent.id, scene_sw_matrix,
|
|
|
|
ent.reg);
|
|
|
|
VectorCopy (transform[3], origin);
|
2022-10-25 03:53:30 +00:00
|
|
|
renderer_t *renderer = Ent_GetComponent (ent.id, scene_renderer,
|
|
|
|
ent.reg);
|
|
|
|
model_t *model = renderer->model;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2022-03-02 06:00:32 +00:00
|
|
|
// see if the bounding box lets us trivially reject, also
|
|
|
|
// sets trivial accept status
|
|
|
|
for (j = 0; j < 3; j++) {
|
2022-10-25 03:53:30 +00:00
|
|
|
minmaxs[j] = origin[j] + model->mins[j];
|
|
|
|
minmaxs[3 + j] = origin[j] + model->maxs[j];
|
2022-03-02 06:00:32 +00:00
|
|
|
}
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2022-10-25 10:36:09 +00:00
|
|
|
clipflags = R_BmodelCheckBBox (transform, model->radius, minmaxs);
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2022-03-02 06:00:32 +00:00
|
|
|
if (clipflags != BMODEL_FULLY_CLIPPED) {
|
2022-10-25 03:53:30 +00:00
|
|
|
mod_brush_t *brush = &model->brush;
|
2022-03-02 06:00:32 +00:00
|
|
|
VectorCopy (origin, r_entorigin);
|
[renderer] Clean up use of vup/vright/vpn
This moves the common camera setup code out of the individual drivers,
and completely removes vup/vright/vpn from the non-software renderers.
This has highlighted the craziness around AngleVectors with it putting
+X forward, -Y right and +Z up. The main issue with this is it requires
a 90 degree pre-rotation about the Z axis to get the camera pointing in
the right direction, and that's for the native sw renderer (vulkan needs
a 90 degree pre-rotation about X, and gl and glsl need to invert an
axis, too), though at least it's just a matrix swizzle and vector
negation. However, it does mean the camera matrices can't be used
directly.
Also rename vpn to vfwd (still abbreviated, but fwd is much clearer in
meaning (to me, at least) than pn (plane normal, I guess, but which
way?)).
2022-03-14 00:34:24 +00:00
|
|
|
VectorSubtract (r_refdef.frame.position, r_entorigin, modelorg);
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2022-03-02 06:00:32 +00:00
|
|
|
r_pcurrentvertbase = brush->vertexes;
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2022-03-02 06:00:32 +00:00
|
|
|
// FIXME: stop transforming twice
|
[scene] Make entity_t just an entity id for ECS
This puts the hierarchy (transform) reference, animation, visibility,
renderer, active, and old_origin data in separate components. There are
a few bugs (crashes on grenade explosions in gl/glsl/vulkan, immediately
in sw, reasons known, missing brush models in vulkan).
While quake doesn't really need an ECS, the direction I want to take QF
does, and it does seem to have improved memory bandwidth a little
(uncertain). However, there's a lot more work to go (especially fixing
the above bugs), but this seems to be a good start.
2022-10-23 01:32:09 +00:00
|
|
|
R_RotateBmodel (transform);
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2022-03-02 06:00:32 +00:00
|
|
|
// calculate dynamic lighting for bmodel if it's not an
|
|
|
|
// instanced model
|
|
|
|
if (brush->firstmodelsurface != 0) {
|
|
|
|
for (k = 0; k < r_maxdlights; k++) {
|
|
|
|
if ((r_dlights[k].die < vr_data.realtime) ||
|
|
|
|
(!r_dlights[k].radius)) {
|
|
|
|
continue;
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
2022-03-02 06:00:32 +00:00
|
|
|
|
2022-05-22 02:18:32 +00:00
|
|
|
vec4f_t lightorigin;
|
2022-03-02 06:00:32 +00:00
|
|
|
VectorSubtract (r_dlights[k].origin, origin, lightorigin);
|
2022-05-22 02:18:32 +00:00
|
|
|
lightorigin[3] = 1;
|
2022-03-02 06:00:32 +00:00
|
|
|
R_RecursiveMarkLights (brush, lightorigin,
|
|
|
|
&r_dlights[k], k,
|
2022-05-22 02:18:32 +00:00
|
|
|
brush->hulls[0].firstclipnode);
|
2022-03-02 06:00:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// if the driver wants polygons, deliver those.
|
|
|
|
// Z-buffering is on at this point, so no clipping to the
|
|
|
|
// world tree is needed, just frustum clipping
|
|
|
|
if (r_drawpolys | r_drawculledpolys) {
|
2022-10-25 10:36:09 +00:00
|
|
|
R_ZDrawSubmodelPolys (render_id, brush);
|
2022-03-02 06:00:32 +00:00
|
|
|
} else {
|
2022-10-25 03:53:30 +00:00
|
|
|
visibility_t *visibility = Ent_GetComponent (ent.id,
|
|
|
|
scene_visibility,
|
|
|
|
ent.reg);
|
[scene] Make entity_t just an entity id for ECS
This puts the hierarchy (transform) reference, animation, visibility,
renderer, active, and old_origin data in separate components. There are
a few bugs (crashes on grenade explosions in gl/glsl/vulkan, immediately
in sw, reasons known, missing brush models in vulkan).
While quake doesn't really need an ECS, the direction I want to take QF
does, and it does seem to have improved memory bandwidth a little
(uncertain). However, there's a lot more work to go (especially fixing
the above bugs), but this seems to be a good start.
2022-10-23 01:32:09 +00:00
|
|
|
int topnode_id = visibility->topnode_id;
|
2022-10-25 10:36:09 +00:00
|
|
|
mod_brush_t *world_brush = &r_refdef.worldmodel->brush;
|
2022-05-22 02:18:32 +00:00
|
|
|
|
|
|
|
if (topnode_id >= 0) {
|
|
|
|
// not a leaf; has to be clipped to the world
|
|
|
|
// BSP
|
2022-10-25 10:36:09 +00:00
|
|
|
mnode_t *node = world_brush->nodes + topnode_id;
|
2022-05-22 02:18:32 +00:00
|
|
|
r_clipflags = clipflags;
|
2022-10-25 10:36:09 +00:00
|
|
|
R_DrawSolidClippedSubmodelPolygons (render_id, brush, node);
|
2022-05-22 02:18:32 +00:00
|
|
|
} else {
|
|
|
|
// falls entirely in one leaf, so we just put
|
|
|
|
// all the edges in the edge list and let 1/z
|
|
|
|
// sorting handle drawing order
|
2022-10-25 10:36:09 +00:00
|
|
|
mleaf_t *leaf = world_brush->leafs + ~topnode_id;
|
|
|
|
R_DrawSubmodelPolygons (render_id, brush, clipflags, leaf);
|
2001-05-15 04:50:53 +00:00
|
|
|
}
|
2022-03-02 06:00:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// put back world rotation and frustum clipping
|
|
|
|
// FIXME: R_RotateBmodel should just work off base_vxx
|
[renderer] Clean up use of vup/vright/vpn
This moves the common camera setup code out of the individual drivers,
and completely removes vup/vright/vpn from the non-software renderers.
This has highlighted the craziness around AngleVectors with it putting
+X forward, -Y right and +Z up. The main issue with this is it requires
a 90 degree pre-rotation about the Z axis to get the camera pointing in
the right direction, and that's for the native sw renderer (vulkan needs
a 90 degree pre-rotation about X, and gl and glsl need to invert an
axis, too), though at least it's just a matrix swizzle and vector
negation. However, it does mean the camera matrices can't be used
directly.
Also rename vpn to vfwd (still abbreviated, but fwd is much clearer in
meaning (to me, at least) than pn (plane normal, I guess, but which
way?)).
2022-03-14 00:34:24 +00:00
|
|
|
VectorCopy (base_vfwd, vfwd);
|
2022-03-02 06:00:32 +00:00
|
|
|
VectorCopy (base_vup, vup);
|
|
|
|
VectorCopy (base_vright, vright);
|
|
|
|
VectorCopy (base_modelorg, modelorg);
|
|
|
|
R_TransformFrustum ();
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
insubmodel = false;
|
|
|
|
}
|
|
|
|
|
2012-02-21 05:10:20 +00:00
|
|
|
static void
|
2022-03-17 08:50:38 +00:00
|
|
|
R_EdgeDrawing (entqueue_t *queue)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2001-02-26 06:48:02 +00:00
|
|
|
edge_t ledges[NUMSTACKEDGES +
|
|
|
|
((CACHE_SIZE - 1) / sizeof (edge_t)) + 1];
|
|
|
|
surf_t lsurfs[NUMSTACKSURFACES +
|
|
|
|
((CACHE_SIZE - 1) / sizeof (surf_t)) + 1];
|
|
|
|
|
|
|
|
if (auxedges) {
|
2001-02-19 21:15:25 +00:00
|
|
|
r_edges = auxedges;
|
2001-02-26 06:48:02 +00:00
|
|
|
} else {
|
|
|
|
r_edges = (edge_t *)
|
2007-04-11 22:03:36 +00:00
|
|
|
(((intptr_t) &ledges[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
if (r_surfsonstack) {
|
|
|
|
surfaces = (surf_t *)
|
2007-04-11 22:03:36 +00:00
|
|
|
(((intptr_t) &lsurfs[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
|
2001-02-19 21:15:25 +00:00
|
|
|
surf_max = &surfaces[r_cnumsurfs];
|
2001-02-26 06:48:02 +00:00
|
|
|
// surface 0 doesn't really exist; it's just a dummy because index 0
|
|
|
|
// is used to indicate no edge attached to surface
|
2001-02-19 21:15:25 +00:00
|
|
|
surfaces--;
|
|
|
|
R_SurfacePatch ();
|
|
|
|
}
|
|
|
|
|
|
|
|
R_BeginEdgeFrame ();
|
|
|
|
|
|
|
|
R_RenderWorld ();
|
|
|
|
|
|
|
|
if (r_drawculledpolys)
|
|
|
|
R_ScanEdges ();
|
|
|
|
|
2001-05-15 21:13:07 +00:00
|
|
|
// only the world can be drawn back to front with no z reads or compares,
|
|
|
|
// just z writes, so have the driver turn z compares on now
|
2001-02-19 21:15:25 +00:00
|
|
|
D_TurnZOn ();
|
|
|
|
|
2022-03-17 08:50:38 +00:00
|
|
|
R_DrawBrushEntitiesOnList (queue);
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2001-02-19 21:15:25 +00:00
|
|
|
if (!(r_drawpolys | r_drawculledpolys))
|
|
|
|
R_ScanEdges ();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2001-05-15 04:50:53 +00:00
|
|
|
R_RenderView
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2001-05-15 04:50:53 +00:00
|
|
|
r_refdef must be set before the first call
|
2001-02-19 21:15:25 +00:00
|
|
|
*/
|
2003-01-06 18:28:13 +00:00
|
|
|
static void
|
2001-02-26 06:48:02 +00:00
|
|
|
R_RenderView_ (void)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
if (r_norefresh)
|
2004-04-16 03:24:10 +00:00
|
|
|
return;
|
2022-03-14 06:27:43 +00:00
|
|
|
if (!r_refdef.worldmodel) {
|
2021-12-02 09:30:57 +00:00
|
|
|
return;
|
|
|
|
}
|
2004-04-16 03:24:10 +00:00
|
|
|
|
2022-10-25 10:36:09 +00:00
|
|
|
reset_sw_components (r_refdef.registry);
|
|
|
|
*(mod_brush_t **) SW_COMP (scene_sw_brush, 0) = &r_refdef.worldmodel->brush;
|
2001-02-19 21:15:25 +00:00
|
|
|
R_SetupFrame ();
|
|
|
|
|
|
|
|
// make FDIV fast. This reduces timing precision after we've been running for a
|
|
|
|
// while, so we don't do it globally. This also sets chop mode, and we do it
|
|
|
|
// here so that setup stuff like the refresh area calculations match what's
|
|
|
|
// done in screen.c
|
2002-06-07 15:09:20 +00:00
|
|
|
R_LowFPPrecision ();
|
2001-02-19 21:15:25 +00:00
|
|
|
|
2022-03-17 08:50:38 +00:00
|
|
|
R_EdgeDrawing (r_ent_queue);
|
2001-02-19 21:15:25 +00:00
|
|
|
|
[scene] Make entity_t just an entity id for ECS
This puts the hierarchy (transform) reference, animation, visibility,
renderer, active, and old_origin data in separate components. There are
a few bugs (crashes on grenade explosions in gl/glsl/vulkan, immediately
in sw, reasons known, missing brush models in vulkan).
While quake doesn't really need an ECS, the direction I want to take QF
does, and it does seem to have improved memory bandwidth a little
(uncertain). However, there's a lot more work to go (especially fixing
the above bugs), but this seems to be a good start.
2022-10-23 01:32:09 +00:00
|
|
|
if (Entity_Valid (vr_data.view_model)) {
|
2022-04-25 22:22:45 +00:00
|
|
|
R_DrawViewModel ();
|
|
|
|
}
|
2001-02-19 21:15:25 +00:00
|
|
|
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
if (r_aliasstats)
|
2001-02-19 21:15:25 +00:00
|
|
|
R_PrintAliasStats ();
|
2001-02-26 06:48:02 +00:00
|
|
|
|
2001-05-15 21:13:07 +00:00
|
|
|
// back to high floating-point precision
|
2002-06-07 15:09:20 +00:00
|
|
|
R_HighFPPrecision ();
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
void
|
|
|
|
R_RenderView (void)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2001-02-26 06:48:02 +00:00
|
|
|
int dummy;
|
|
|
|
int delta;
|
|
|
|
|
|
|
|
delta = (byte *) & dummy - r_stack_start;
|
2001-02-19 21:15:25 +00:00
|
|
|
if (delta < -10000 || delta > 10000)
|
|
|
|
Sys_Error ("R_RenderView: called without enough stack");
|
|
|
|
|
2021-07-28 06:01:45 +00:00
|
|
|
if (Hunk_LowMark (0) & 3)
|
2001-02-19 21:15:25 +00:00
|
|
|
Sys_Error ("Hunk is missaligned");
|
|
|
|
|
2007-04-11 22:03:36 +00:00
|
|
|
if ((intptr_t) (&dummy) & 3)
|
2001-02-19 21:15:25 +00:00
|
|
|
Sys_Error ("Stack is missaligned");
|
|
|
|
|
2022-03-29 04:08:58 +00:00
|
|
|
if ((intptr_t) (&r_colormap) & 3)
|
2001-02-19 21:15:25 +00:00
|
|
|
Sys_Error ("Globals are missaligned");
|
2022-03-24 06:45:01 +00:00
|
|
|
|
|
|
|
R_RenderView_ ();
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
|
2001-02-26 06:48:02 +00:00
|
|
|
void
|
|
|
|
R_InitTurb (void)
|
2001-02-19 21:15:25 +00:00
|
|
|
{
|
2001-02-26 06:48:02 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < (SIN_BUFFER_SIZE); i++) {
|
|
|
|
sintable[i] = AMP + sin (i * 3.14159 * 2 / CYCLE) * AMP;
|
2001-05-15 04:50:53 +00:00
|
|
|
intsintable[i] = AMP2 + sin (i * 3.14159 * 2 / CYCLE) * AMP2;
|
|
|
|
// AMP2 not 20
|
2001-02-19 21:15:25 +00:00
|
|
|
}
|
|
|
|
}
|
2022-03-14 14:51:30 +00:00
|
|
|
|
2012-02-18 13:28:42 +00:00
|
|
|
void
|
2011-12-23 03:51:47 +00:00
|
|
|
R_ClearState (void)
|
|
|
|
{
|
2022-03-14 06:27:43 +00:00
|
|
|
r_refdef.worldmodel = 0;
|
2011-12-23 03:51:47 +00:00
|
|
|
R_ClearDlights ();
|
|
|
|
R_ClearParticles ();
|
|
|
|
}
|