mirror of
https://github.com/w23/xash3d-fwgs
synced 2024-11-05 01:51:55 +01:00
move water warping to vk_brush
This commit is contained in:
parent
74e0fb2947
commit
531fcd9393
@ -55,6 +55,188 @@ void VK_BrushShutdown( void )
|
||||
{
|
||||
}
|
||||
|
||||
// speed up sin calculations
|
||||
static const float r_turbsin[] =
|
||||
{
|
||||
#include "warpsin.h"
|
||||
};
|
||||
|
||||
#define SUBDIVIDE_SIZE 64
|
||||
#define TURBSCALE ( 256.0f / ( M_PI2 ))
|
||||
|
||||
/*
|
||||
=============
|
||||
EmitWaterPolys
|
||||
|
||||
Does a water warp on the pre-fragmented glpoly_t chain
|
||||
=============
|
||||
*/
|
||||
static void EmitWaterPolys( const cl_entity_t *ent, const msurface_t *warp, qboolean reverse )
|
||||
{
|
||||
float *v, nv, waveHeight;
|
||||
float s, t, os, ot;
|
||||
glpoly_t *p;
|
||||
int i;
|
||||
int num_vertices = 0, num_indices = 0;
|
||||
vk_buffer_handle_t vertex_buffer, index_buffer = InvalidHandle;
|
||||
vk_buffer_lock_t vertex_lock, index_lock;
|
||||
int vertex_offset = 0;
|
||||
vk_vertex_t *vertices;
|
||||
uint16_t *indices;
|
||||
|
||||
const qboolean useQuads = FBitSet( warp->flags, SURF_DRAWTURB_QUADS );
|
||||
|
||||
if( !warp->polys ) return;
|
||||
|
||||
// set the current waveheight
|
||||
// FIXME VK if( warp->polys->verts[0][2] >= RI.vieworg[2] )
|
||||
// waveHeight = -ent->curstate.scale;
|
||||
// else
|
||||
waveHeight = ent->curstate.scale;
|
||||
|
||||
// reset fog color for nonlightmapped water
|
||||
// FIXME VK GL_ResetFogColor();
|
||||
|
||||
// Compute vertex count
|
||||
for( p = warp->polys; p; p = p->next ) {
|
||||
const int triangles = p->numverts - 2;
|
||||
num_vertices += p->numverts;
|
||||
num_indices += triangles * 3;
|
||||
}
|
||||
|
||||
vertex_buffer = VK_RenderBufferAlloc( sizeof(vk_vertex_t), num_vertices, LifetimeSingleFrame );
|
||||
index_buffer = VK_RenderBufferAlloc( sizeof(uint16_t), num_indices, LifetimeSingleFrame );
|
||||
if (vertex_buffer == InvalidHandle || index_buffer == InvalidHandle)
|
||||
{
|
||||
// TODO should we free one of the above if it still succeeded?
|
||||
gEngine.Con_Printf(S_ERROR "Ran out of buffer space\n");
|
||||
return;
|
||||
}
|
||||
|
||||
vertex_lock = VK_RenderBufferLock( vertex_buffer );
|
||||
index_lock = VK_RenderBufferLock( index_buffer );
|
||||
|
||||
vertices = vertex_lock.ptr;
|
||||
indices = index_lock.ptr;
|
||||
|
||||
for( p = warp->polys; p; p = p->next )
|
||||
{
|
||||
if( reverse )
|
||||
v = p->verts[0] + ( p->numverts - 1 ) * VERTEXSIZE;
|
||||
else v = p->verts[0];
|
||||
|
||||
for( i = 0; i < p->numverts; i++ )
|
||||
{
|
||||
if( waveHeight )
|
||||
{
|
||||
nv = r_turbsin[(int)(gpGlobals->time * 160.0f + v[1] + v[0]) & 255] + 8.0f;
|
||||
nv = (r_turbsin[(int)(v[0] * 5.0f + gpGlobals->time * 171.0f - v[1]) & 255] + 8.0f ) * 0.8f + nv;
|
||||
nv = nv * waveHeight + v[2];
|
||||
}
|
||||
else nv = v[2];
|
||||
|
||||
os = v[3];
|
||||
ot = v[4];
|
||||
|
||||
s = os + r_turbsin[(int)((ot * 0.125f + gpGlobals->time) * TURBSCALE) & 255];
|
||||
s *= ( 1.0f / SUBDIVIDE_SIZE );
|
||||
|
||||
t = ot + r_turbsin[(int)((os * 0.125f + gpGlobals->time) * TURBSCALE) & 255];
|
||||
t *= ( 1.0f / SUBDIVIDE_SIZE );
|
||||
|
||||
vertices[vertex_offset + i].pos[0] = v[0];
|
||||
vertices[vertex_offset + i].pos[1] = v[1];
|
||||
vertices[vertex_offset + i].pos[2] = nv;
|
||||
|
||||
vertices[vertex_offset + i].gl_tc[0] = s;
|
||||
vertices[vertex_offset + i].gl_tc[1] = t;
|
||||
|
||||
vertices[vertex_offset + i].lm_tc[0] = 0;
|
||||
vertices[vertex_offset + i].lm_tc[1] = 0;
|
||||
|
||||
// FIXME calc normal
|
||||
vertices[vertex_offset + i].normal[0] = 0;
|
||||
vertices[vertex_offset + i].normal[1] = 0;
|
||||
vertices[vertex_offset + i].normal[2] = 1;
|
||||
|
||||
// Ray tracing apparently expects triangle list only (although spec is not very clear about this kekw)
|
||||
if (i > 1) {
|
||||
// vec3_t e0, e1, normal;
|
||||
// VectorSubtract( vertices[vertex_offset + i - 1].pos, vertices[vertex_offset].pos, e0 );
|
||||
// VectorSubtract( vertices[vertex_offset + i].pos, vertices[vertex_offset].pos, e1 );
|
||||
// CrossProduct( e1, e0, normal );
|
||||
// //VectorNormalize(normal);
|
||||
|
||||
// VectorAdd(normal, vertices[vertex_offset].normal, vertices[vertex_offset].normal);
|
||||
// VectorAdd(normal, vertices[vertex_offset + i].normal, vertices[vertex_offset + i].normal);
|
||||
// VectorAdd(normal, vertices[vertex_offset + i - 1].normal, vertices[vertex_offset + i - 1].normal);
|
||||
|
||||
*(indices++) = (uint16_t)(vertex_offset);
|
||||
*(indices++) = (uint16_t)(vertex_offset + i - 1);
|
||||
*(indices++) = (uint16_t)(vertex_offset + i);
|
||||
}
|
||||
|
||||
if( reverse )
|
||||
v -= VERTEXSIZE;
|
||||
else v += VERTEXSIZE;
|
||||
}
|
||||
|
||||
// for( i = 0; i < p->numverts; i++ ) {
|
||||
// VectorNormalize(vertices[vertex_offset + i].normal);
|
||||
// }
|
||||
|
||||
vertex_offset += p->numverts;
|
||||
}
|
||||
|
||||
VK_RenderBufferUnlock( vertex_buffer );
|
||||
VK_RenderBufferUnlock( index_buffer );
|
||||
|
||||
// Render
|
||||
{
|
||||
const vk_render_geometry_t geometry = {
|
||||
.texture = warp->texinfo->texture->gl_texturenum, // FIXME assert >= 0
|
||||
|
||||
.vertex_count = num_vertices,
|
||||
.vertex_buffer = vertex_buffer,
|
||||
.vertex_offset = 0,
|
||||
|
||||
.element_count = num_indices,
|
||||
.index_offset = 0,
|
||||
.index_buffer = index_buffer,
|
||||
};
|
||||
|
||||
VK_RenderModelDynamicAddGeometry( &geometry );
|
||||
}
|
||||
|
||||
// FIXME VK GL_SetupFogColorForSurfaces();
|
||||
}
|
||||
|
||||
void XVK_DrawWaterSurfaces( const cl_entity_t *ent )
|
||||
{
|
||||
const model_t *model = ent->model;
|
||||
VK_RenderModelDynamicBegin( model->name, ent->curstate.rendermode );
|
||||
|
||||
// (done?) Subdivide surfaces to glpolys
|
||||
// Iterate through all surfaces, find *TURB*
|
||||
for( int i = 0; i < model->nummodelsurfaces; i++ )
|
||||
{
|
||||
const msurface_t *surf = model->surfaces + model->firstmodelsurface + i;
|
||||
|
||||
if( !FBitSet( surf->flags, SURF_DRAWTURB ) && !FBitSet( surf->flags, SURF_DRAWTURB_QUADS) )
|
||||
continue;
|
||||
|
||||
// Iterate through all glpolys
|
||||
// generate geometries
|
||||
EmitWaterPolys( ent, surf, false );
|
||||
}
|
||||
|
||||
// submit as dynamic model
|
||||
VK_RenderModelDynamicCommit();
|
||||
|
||||
// TODO:
|
||||
// - upload water geometry only once, animate in compute/vertex shader
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_TextureAnimation
|
||||
@ -119,6 +301,10 @@ void VK_BrushModelDraw( const cl_entity_t *ent, int render_mode )
|
||||
return;
|
||||
}
|
||||
|
||||
if (bmodel->num_water_surfaces) {
|
||||
XVK_DrawWaterSurfaces(ent);
|
||||
}
|
||||
|
||||
if (bmodel->render_model.num_geometries == 0)
|
||||
return;
|
||||
|
||||
@ -153,6 +339,8 @@ static qboolean renderableSurface( const msurface_t *surf, int i ) {
|
||||
typedef struct {
|
||||
int num_surfaces, num_vertices, num_indices;
|
||||
int max_texture_id;
|
||||
int water_surfaces;
|
||||
int sky_surfaces;
|
||||
} model_sizes_t;
|
||||
|
||||
static model_sizes_t computeSizes( const model_t *mod ) {
|
||||
@ -162,6 +350,9 @@ static model_sizes_t computeSizes( const model_t *mod ) {
|
||||
{
|
||||
const msurface_t *surf = mod->surfaces + mod->firstmodelsurface + i;
|
||||
|
||||
sizes.water_surfaces += !!(surf->flags & (SURF_DRAWTURB | SURF_DRAWTURB_QUADS));
|
||||
sizes.sky_surfaces += !!(surf->flags & SURF_DRAWSKY);
|
||||
|
||||
if (!renderableSurface(surf, i))
|
||||
continue;
|
||||
|
||||
@ -323,6 +514,8 @@ qboolean VK_BrushModelLoad( model_t *mod )
|
||||
bmodel->render_model.debug_name = mod->name;
|
||||
bmodel->render_model.render_mode = kRenderNormal;
|
||||
|
||||
bmodel->num_water_surfaces = sizes.water_surfaces != 0;
|
||||
|
||||
if (sizes.num_surfaces != 0) {
|
||||
bmodel->render_model.geometries = (vk_render_geometry_t*)((char*)(bmodel + 1));
|
||||
|
||||
|
@ -10,6 +10,7 @@ struct cl_entity_s;
|
||||
|
||||
typedef struct vk_brush_model_s {
|
||||
vk_render_model_t render_model;
|
||||
int num_water_surfaces;
|
||||
} vk_brush_model_t;
|
||||
|
||||
qboolean VK_BrushInit( void );
|
||||
|
@ -82,188 +82,6 @@ int R_FIXME_GetEntityRenderMode( cl_entity_t *ent )
|
||||
return ent->curstate.rendermode;
|
||||
}
|
||||
|
||||
// speed up sin calculations
|
||||
static const float r_turbsin[] =
|
||||
{
|
||||
#include "warpsin.h"
|
||||
};
|
||||
|
||||
#define SUBDIVIDE_SIZE 64
|
||||
#define TURBSCALE ( 256.0f / ( M_PI2 ))
|
||||
|
||||
/*
|
||||
=============
|
||||
EmitWaterPolys
|
||||
|
||||
Does a water warp on the pre-fragmented glpoly_t chain
|
||||
=============
|
||||
*/
|
||||
static void EmitWaterPolys( const cl_entity_t *ent, const msurface_t *warp, qboolean reverse )
|
||||
{
|
||||
float *v, nv, waveHeight;
|
||||
float s, t, os, ot;
|
||||
glpoly_t *p;
|
||||
int i;
|
||||
int num_vertices = 0, num_indices = 0;
|
||||
vk_buffer_handle_t vertex_buffer, index_buffer = InvalidHandle;
|
||||
vk_buffer_lock_t vertex_lock, index_lock;
|
||||
int vertex_offset = 0;
|
||||
vk_vertex_t *vertices;
|
||||
uint16_t *indices;
|
||||
|
||||
const qboolean useQuads = FBitSet( warp->flags, SURF_DRAWTURB_QUADS );
|
||||
|
||||
if( !warp->polys ) return;
|
||||
|
||||
// set the current waveheight
|
||||
// FIXME VK if( warp->polys->verts[0][2] >= RI.vieworg[2] )
|
||||
// waveHeight = -ent->curstate.scale;
|
||||
// else
|
||||
waveHeight = ent->curstate.scale;
|
||||
|
||||
// reset fog color for nonlightmapped water
|
||||
// FIXME VK GL_ResetFogColor();
|
||||
|
||||
// Compute vertex count
|
||||
for( p = warp->polys; p; p = p->next ) {
|
||||
const int triangles = p->numverts - 2;
|
||||
num_vertices += p->numverts;
|
||||
num_indices += triangles * 3;
|
||||
}
|
||||
|
||||
vertex_buffer = VK_RenderBufferAlloc( sizeof(vk_vertex_t), num_vertices, LifetimeSingleFrame );
|
||||
index_buffer = VK_RenderBufferAlloc( sizeof(uint16_t), num_indices, LifetimeSingleFrame );
|
||||
if (vertex_buffer == InvalidHandle || index_buffer == InvalidHandle)
|
||||
{
|
||||
// TODO should we free one of the above if it still succeeded?
|
||||
gEngine.Con_Printf(S_ERROR "Ran out of buffer space\n");
|
||||
return;
|
||||
}
|
||||
|
||||
vertex_lock = VK_RenderBufferLock( vertex_buffer );
|
||||
index_lock = VK_RenderBufferLock( index_buffer );
|
||||
|
||||
vertices = vertex_lock.ptr;
|
||||
indices = index_lock.ptr;
|
||||
|
||||
for( p = warp->polys; p; p = p->next )
|
||||
{
|
||||
if( reverse )
|
||||
v = p->verts[0] + ( p->numverts - 1 ) * VERTEXSIZE;
|
||||
else v = p->verts[0];
|
||||
|
||||
for( i = 0; i < p->numverts; i++ )
|
||||
{
|
||||
if( waveHeight )
|
||||
{
|
||||
nv = r_turbsin[(int)(gpGlobals->time * 160.0f + v[1] + v[0]) & 255] + 8.0f;
|
||||
nv = (r_turbsin[(int)(v[0] * 5.0f + gpGlobals->time * 171.0f - v[1]) & 255] + 8.0f ) * 0.8f + nv;
|
||||
nv = nv * waveHeight + v[2];
|
||||
}
|
||||
else nv = v[2];
|
||||
|
||||
os = v[3];
|
||||
ot = v[4];
|
||||
|
||||
s = os + r_turbsin[(int)((ot * 0.125f + gpGlobals->time) * TURBSCALE) & 255];
|
||||
s *= ( 1.0f / SUBDIVIDE_SIZE );
|
||||
|
||||
t = ot + r_turbsin[(int)((os * 0.125f + gpGlobals->time) * TURBSCALE) & 255];
|
||||
t *= ( 1.0f / SUBDIVIDE_SIZE );
|
||||
|
||||
vertices[vertex_offset + i].pos[0] = v[0];
|
||||
vertices[vertex_offset + i].pos[1] = v[1];
|
||||
vertices[vertex_offset + i].pos[2] = nv;
|
||||
|
||||
vertices[vertex_offset + i].gl_tc[0] = s;
|
||||
vertices[vertex_offset + i].gl_tc[1] = t;
|
||||
|
||||
vertices[vertex_offset + i].lm_tc[0] = 0;
|
||||
vertices[vertex_offset + i].lm_tc[1] = 0;
|
||||
|
||||
// FIXME calc normal
|
||||
vertices[vertex_offset + i].normal[0] = 0;
|
||||
vertices[vertex_offset + i].normal[1] = 0;
|
||||
vertices[vertex_offset + i].normal[2] = 1;
|
||||
|
||||
// Ray tracing apparently expects triangle list only (although spec is not very clear about this kekw)
|
||||
if (i > 1) {
|
||||
// vec3_t e0, e1, normal;
|
||||
// VectorSubtract( vertices[vertex_offset + i - 1].pos, vertices[vertex_offset].pos, e0 );
|
||||
// VectorSubtract( vertices[vertex_offset + i].pos, vertices[vertex_offset].pos, e1 );
|
||||
// CrossProduct( e1, e0, normal );
|
||||
// //VectorNormalize(normal);
|
||||
|
||||
// VectorAdd(normal, vertices[vertex_offset].normal, vertices[vertex_offset].normal);
|
||||
// VectorAdd(normal, vertices[vertex_offset + i].normal, vertices[vertex_offset + i].normal);
|
||||
// VectorAdd(normal, vertices[vertex_offset + i - 1].normal, vertices[vertex_offset + i - 1].normal);
|
||||
|
||||
*(indices++) = (uint16_t)(vertex_offset);
|
||||
*(indices++) = (uint16_t)(vertex_offset + i - 1);
|
||||
*(indices++) = (uint16_t)(vertex_offset + i);
|
||||
}
|
||||
|
||||
if( reverse )
|
||||
v -= VERTEXSIZE;
|
||||
else v += VERTEXSIZE;
|
||||
}
|
||||
|
||||
// for( i = 0; i < p->numverts; i++ ) {
|
||||
// VectorNormalize(vertices[vertex_offset + i].normal);
|
||||
// }
|
||||
|
||||
vertex_offset += p->numverts;
|
||||
}
|
||||
|
||||
VK_RenderBufferUnlock( vertex_buffer );
|
||||
VK_RenderBufferUnlock( index_buffer );
|
||||
|
||||
// Render
|
||||
{
|
||||
const vk_render_geometry_t geometry = {
|
||||
.texture = warp->texinfo->texture->gl_texturenum, // FIXME assert >= 0
|
||||
|
||||
.vertex_count = num_vertices,
|
||||
.vertex_buffer = vertex_buffer,
|
||||
.vertex_offset = 0,
|
||||
|
||||
.element_count = num_indices,
|
||||
.index_offset = 0,
|
||||
.index_buffer = index_buffer,
|
||||
};
|
||||
|
||||
VK_RenderModelDynamicAddGeometry( &geometry );
|
||||
}
|
||||
|
||||
// FIXME VK GL_SetupFogColorForSurfaces();
|
||||
}
|
||||
|
||||
void XVK_DrawWaterSurfaces( const cl_entity_t *ent )
|
||||
{
|
||||
const model_t *model = ent->model;
|
||||
VK_RenderModelDynamicBegin( model->name, ent->curstate.rendermode );
|
||||
|
||||
// (done?) Subdivide surfaces to glpolys
|
||||
// Iterate through all surfaces, find *TURB*
|
||||
for( int i = 0; i < model->nummodelsurfaces; i++ )
|
||||
{
|
||||
const msurface_t *surf = model->surfaces + model->firstmodelsurface + i;
|
||||
|
||||
if( !FBitSet( surf->flags, SURF_DRAWTURB ) && !FBitSet( surf->flags, SURF_DRAWTURB_QUADS) )
|
||||
continue;
|
||||
|
||||
// Iterate through all glpolys
|
||||
// generate geometries
|
||||
EmitWaterPolys( ent, surf, false );
|
||||
}
|
||||
|
||||
// submit as dynamic model
|
||||
VK_RenderModelDynamicCommit();
|
||||
|
||||
// TODO:
|
||||
// - upload water geometry only once, animate in compute/vertex shader
|
||||
}
|
||||
|
||||
// tell the renderer what new map is started
|
||||
void R_NewMap( void )
|
||||
{
|
||||
@ -809,9 +627,6 @@ static void drawEntity( cl_entity_t *ent, int render_mode )
|
||||
R_RotateForEntity( model, ent );
|
||||
VK_RenderStateSetMatrixModel( model );
|
||||
VK_BrushModelDraw( ent, render_mode );
|
||||
|
||||
// FIXME refactor water handling: move this inside BrushModelDraw
|
||||
XVK_DrawWaterSurfaces( ent );
|
||||
break;
|
||||
|
||||
case mod_studio:
|
||||
@ -865,9 +680,6 @@ void VK_SceneRender( const ref_viewpass_t *rvp )
|
||||
VK_RenderStateSetColor( 1.f, 1.f, 1.f, 1.f);
|
||||
VK_BrushModelDraw( world, kRenderNormal );
|
||||
}
|
||||
|
||||
// FIXME refactor water handling
|
||||
XVK_DrawWaterSurfaces( world );
|
||||
}
|
||||
|
||||
// Draw opaque entities
|
||||
|
Loading…
Reference in New Issue
Block a user