vk: half-fix water levels being too high

Pass current entity to compute wave height. Still doesn't switch to
negative height when underwater for some reason.
And still displays water sides.

Add some notes regarding water geometry generation and drawing.
This commit is contained in:
Ivan Avdeev 2023-11-07 13:45:25 -05:00
parent c575cb6cfd
commit 3e9f6bc7a4
3 changed files with 39 additions and 15 deletions

View File

@ -679,4 +679,15 @@ Hunch: need to split external/refapi refcount-unaware functionality and hash map
- old textures (but which should've been loaded for the new map too) with refcount=1 are deleted
- ;_;
# 2023-11-07 E326
Water :|
## Overview
- water is `msurface_t` with `SURF_DRAWTURB` (?)
- Engine calls `GL_SubdivideSurface()` to produce `glpoly_t` chain of subdivided polygons for a given `msurface_t`
- When? How? Is it correct?
- What does it do exactly?
- rendering uses `glpoly_t` to generate and submit heightmap-animated triangles
- animated height depends on current camera position. Height is inverted if camera is underwater.
- there are "water sides" with `PLANE_Z` flag. These are drawn only when `cl_entity_t.curstate.effects` has `EF_WATERSIDES` bit
- water sides can be found in test_brush2

View File

@ -10,7 +10,7 @@
- not even sure we need it?
- [ ] do not draw water sides when not requested.
- [ ] potentially collinear planes vs ray tracing #264
- [ ] update animated textures is now super slow
- [ ] update animated textures is now super slow: some static map surfaces have alternate anims (e.g. light post on c2a5)
# 2023-11-06 E325
- [x] fix material asserts and inherit

View File

@ -17,6 +17,7 @@
#include "vk_staging.h"
#include "vk_logs.h"
#include "profiler.h"
#include "camera.h"
#include "ref_params.h"
#include "eiface.h"
@ -27,6 +28,14 @@
#define MODULE_NAME "brush"
#define LOG_MODULE LogModule_Brush
typedef struct {
int surfaces_count;
const int *surfaces_indices;
r_geometry_range_t geometry;
vk_render_model_t render_model;
} r_brush_water_model_t;
typedef struct vk_brush_model_s {
model_t *engine_model;
@ -41,13 +50,8 @@ typedef struct vk_brush_model_s {
matrix4x4 prev_transform;
float prev_time;
struct {
int surfaces_count;
const int *surfaces_indices;
r_geometry_range_t geometry;
vk_render_model_t render_model;
} water;
r_brush_water_model_t water;
r_brush_water_model_t water_sides;
} vk_brush_model_t;
typedef struct {
@ -194,10 +198,11 @@ static void brushComputeWaterPolys( compute_water_polys_t args ) {
for( glpoly_t *p = args.warp->polys; p; p = p->next ) {
ASSERT(p->numverts <= MAX_WATER_VERTICES);
float *v;
const float *v;
if( args.reverse )
v = p->verts[0] + ( p->numverts - 1 ) * VERTEXSIZE;
else v = p->verts[0];
else
v = p->verts[0];
for( int i = 0; i < p->numverts; i++ )
{
@ -212,7 +217,8 @@ static void brushComputeWaterPolys( compute_water_polys_t args ) {
prev_nv = (r_turbsin[(int)(v[0] * 5.0f + args.prev_time * 171.0f - v[1]) & 255] + 8.0f ) * 0.8f + prev_nv;
prev_nv = prev_nv * scale + v[2];
}
else prev_nv = nv = v[2];
else
prev_nv = nv = v[2];
const float os = v[3];
const float ot = v[4];
@ -367,19 +373,26 @@ static void fillWaterSurfaces( const cl_entity_t *ent, vk_brush_model_t *bmodel,
const r_geometry_range_lock_t geom_lock = R_GeometryRangeLock(&bmodel->water.geometry);
const float scale = ent ? ent->curstate.scale : 1.f;
int vertices_offset = 0;
int indices_offset = 0;
for (int i = 0; i < bmodel->water.surfaces_count; ++i) {
const int surf_index = bmodel->water.surfaces_indices[i];
const msurface_t *warp = bmodel->engine_model->surfaces + surf_index;
/* if( warp->plane->type != PLANE_Z && !FBitSet( ent->curstate.effects, EF_WATERSIDES )) */
/* continue; */
const float scale = (!ent) ? 0.f :
( warp->polys->verts[0][2] >= g_camera.vieworg[2] )
? -ent->curstate.scale
: ent->curstate.scale;
int vertices = 0, indices = 0;
brushComputeWaterPolys((compute_water_polys_t){
.prev_time = bmodel->prev_time,
.scale = scale,
.reverse = false, // ??? is it ever true?
.warp = bmodel->engine_model->surfaces + surf_index,
.warp = warp,
.dst_vertices = geom_lock.vertices + vertices_offset,
.dst_indices = geom_lock.indices + indices_offset,
@ -568,7 +581,7 @@ static void brushDrawWater(vk_brush_model_t *bmodel, const cl_entity_t *ent, int
APROF_SCOPE_DECLARE_BEGIN(brush_draw_water, __FUNCTION__);
ASSERT(bmodel->water.surfaces_count > 0);
fillWaterSurfaces(NULL, bmodel, bmodel->water.render_model.geometries);
fillWaterSurfaces(ent, bmodel, bmodel->water.render_model.geometries);
if (!R_RenderModelUpdate(&bmodel->water.render_model)) {
ERR("Failed to update brush model \"%s\" water", bmodel->render_model.debug_name);
}