From f2182bb2552c0f47fe33faeaa38c3e37b98ef699 Mon Sep 17 00:00:00 2001 From: Ivan 'provod' Avdeev Date: Sat, 25 Feb 2023 16:47:23 -0800 Subject: [PATCH 01/11] vk: fix beams per-vertex blending --- ref/vk/vk_beams.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/ref/vk/vk_beams.c b/ref/vk/vk_beams.c index e099c53f..ebd41b99 100644 --- a/ref/vk/vk_beams.c +++ b/ref/vk/vk_beams.c @@ -145,13 +145,17 @@ qboolean R_BeamCull( const vec3_t start, const vec3_t end, qboolean pvsOnly ) return true; } +static float clampf(float v, float min, float max) { + if (v < min) return min; + if (v > max) return max; + return v; +} -static void applyBrightness( float brightness, const vec4_t color, vec4_t out ) -{ - out[0] = color[0] * color[3] * brightness; - out[1] = color[1] * color[3] * brightness; - out[2] = color[2] * color[3] * brightness; - out[3] = 1.f; +static void applyBrightness( float brightness, const vec4_t color, rgba_t out ) { + out[0] = clampf(color[0] * color[3] * brightness, 0, 1) * 255.f; + out[1] = clampf(color[1] * color[3] * brightness, 0, 1) * 255.f; + out[2] = clampf(color[2] * color[3] * brightness, 0, 1) * 255.f; + out[3] = 255; } static void R_DrawSegs( vec3_t source, vec3_t delta, float width, float scale, float freq, float speed, int segments, int flags, const vec4_t color, int texture, int render_mode ) @@ -298,8 +302,8 @@ static void R_DrawSegs( vec3_t source, vec3_t delta, float width, float scale, f dst_vtx->lm_tc[0] = dst_vtx->lm_tc[1] = 0.f; dst_vtx->gl_tc[0] = 0.0f; dst_vtx->gl_tc[1] = curSeg.texcoord; - //FIXME VK applyBrightness( brightness, color, dst_vtx->color ); - // FIXME VK pglNormal3fv( vAveNormal ); + dst_vtx->flags = 1; + applyBrightness( brightness, color, dst_vtx->color ); VectorCopy( vPoint1, dst_vtx->pos ); VectorCopy( vAveNormal, dst_vtx->normal ); ++dst_vtx; @@ -307,9 +311,10 @@ static void R_DrawSegs( vec3_t source, vec3_t delta, float width, float scale, f dst_vtx->lm_tc[0] = dst_vtx->lm_tc[1] = 0.f; dst_vtx->gl_tc[0] = 1.0f; dst_vtx->gl_tc[1] = curSeg.texcoord; - //FIXME VK applyBrightness( brightness, color, dst_vtx->color ); - // FIXME VK pglNormal3fv( vAveNormal ); + dst_vtx->flags = 1; + applyBrightness( brightness, color, dst_vtx->color ); VectorCopy( vPoint2, dst_vtx->pos ); + VectorCopy( vAveNormal, dst_vtx->normal ); ++dst_vtx; } @@ -339,17 +344,19 @@ static void R_DrawSegs( vec3_t source, vec3_t delta, float width, float scale, f dst_vtx->lm_tc[0] = dst_vtx->lm_tc[1] = 0.f; dst_vtx->gl_tc[0] = 0.0f; dst_vtx->gl_tc[1] = curSeg.texcoord; - //FIXME VK applyBrightness( brightness, color, dst_vtx->color ); - // FIXME VK pglNormal3fv( vLastNormal ); + dst_vtx->flags = 1; + applyBrightness( brightness, color, dst_vtx->color ); VectorCopy( vPoint1, dst_vtx->pos ); + VectorCopy( vLastNormal, dst_vtx->normal ); ++dst_vtx; dst_vtx->lm_tc[0] = dst_vtx->lm_tc[1] = 0.f; dst_vtx->gl_tc[0] = 1.0f; dst_vtx->gl_tc[1] = curSeg.texcoord; - //FIXME VK applyBrightness( brightness, color, dst_vtx->color ); - // FIXME VK pglNormal3fv( vLastNormal ); + dst_vtx->flags = 1; + applyBrightness( brightness, color, dst_vtx->color ); VectorCopy( vPoint2, dst_vtx->pos ); + VectorCopy( vLastNormal, dst_vtx->normal ); ++dst_vtx; } From e4ad18f2204be0339dfe80184abd46f05a44d404 Mon Sep 17 00:00:00 2001 From: Ivan 'provod' Avdeev Date: Sat, 25 Feb 2023 16:58:59 -0800 Subject: [PATCH 02/11] vk: do not modulate beam color twice color is already applied at model/ubo level --- ref/vk/vk_beams.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/ref/vk/vk_beams.c b/ref/vk/vk_beams.c index ebd41b99..65c9aad9 100644 --- a/ref/vk/vk_beams.c +++ b/ref/vk/vk_beams.c @@ -151,10 +151,8 @@ static float clampf(float v, float min, float max) { return v; } -static void applyBrightness( float brightness, const vec4_t color, rgba_t out ) { - out[0] = clampf(color[0] * color[3] * brightness, 0, 1) * 255.f; - out[1] = clampf(color[1] * color[3] * brightness, 0, 1) * 255.f; - out[2] = clampf(color[2] * color[3] * brightness, 0, 1) * 255.f; +static void applyBrightness( float brightness, rgba_t out ) { + out[0] = out[1] = out[2] = clampf(brightness, 0, 1) * 255.f; out[3] = 255; } @@ -303,7 +301,7 @@ static void R_DrawSegs( vec3_t source, vec3_t delta, float width, float scale, f dst_vtx->gl_tc[0] = 0.0f; dst_vtx->gl_tc[1] = curSeg.texcoord; dst_vtx->flags = 1; - applyBrightness( brightness, color, dst_vtx->color ); + applyBrightness( brightness, dst_vtx->color ); VectorCopy( vPoint1, dst_vtx->pos ); VectorCopy( vAveNormal, dst_vtx->normal ); ++dst_vtx; @@ -312,7 +310,7 @@ static void R_DrawSegs( vec3_t source, vec3_t delta, float width, float scale, f dst_vtx->gl_tc[0] = 1.0f; dst_vtx->gl_tc[1] = curSeg.texcoord; dst_vtx->flags = 1; - applyBrightness( brightness, color, dst_vtx->color ); + applyBrightness( brightness, dst_vtx->color ); VectorCopy( vPoint2, dst_vtx->pos ); VectorCopy( vAveNormal, dst_vtx->normal ); ++dst_vtx; @@ -345,7 +343,7 @@ static void R_DrawSegs( vec3_t source, vec3_t delta, float width, float scale, f dst_vtx->gl_tc[0] = 0.0f; dst_vtx->gl_tc[1] = curSeg.texcoord; dst_vtx->flags = 1; - applyBrightness( brightness, color, dst_vtx->color ); + applyBrightness( brightness, dst_vtx->color ); VectorCopy( vPoint1, dst_vtx->pos ); VectorCopy( vLastNormal, dst_vtx->normal ); ++dst_vtx; @@ -354,7 +352,7 @@ static void R_DrawSegs( vec3_t source, vec3_t delta, float width, float scale, f dst_vtx->gl_tc[0] = 1.0f; dst_vtx->gl_tc[1] = curSeg.texcoord; dst_vtx->flags = 1; - applyBrightness( brightness, color, dst_vtx->color ); + applyBrightness( brightness, dst_vtx->color ); VectorCopy( vPoint2, dst_vtx->pos ); VectorCopy( vLastNormal, dst_vtx->normal ); ++dst_vtx; From 1fadbce860a23a575e14bdba9047bb9273aa02e4 Mon Sep 17 00:00:00 2001 From: Ivan 'provod' Avdeev Date: Sat, 25 Feb 2023 18:38:22 -0800 Subject: [PATCH 03/11] vk: remove flag attribute in vertex make color computation more uniform and not mode-specific --- ref/vk/shaders/brush.frag | 13 ++++--------- ref/vk/shaders/brush.vert | 11 +---------- ref/vk/vk_beams.c | 4 ---- ref/vk/vk_brush.c | 4 ++++ ref/vk/vk_geometry.h | 13 ++++++------- ref/vk/vk_render.c | 1 - ref/vk/vk_sprite.c | 4 ---- ref/vk/vk_studio.c | 1 - 8 files changed, 15 insertions(+), 36 deletions(-) diff --git a/ref/vk/shaders/brush.frag b/ref/vk/shaders/brush.frag index a9c87ef8..b87b7950 100644 --- a/ref/vk/shaders/brush.frag +++ b/ref/vk/shaders/brush.frag @@ -21,28 +21,23 @@ layout(location=1) in vec3 vNormal; layout(location=2) in vec2 vTexture0; layout(location=3) in vec2 vLightmapUV; layout(location=4) in vec4 vColor; -layout(location=5) flat in uint vFlags; layout(location=0) out vec4 outColor; // FIXME what should this be? const float dlight_attenuation_const = 5000.; -#define FLAG_VERTEX_LIGHTING 1 - void main() { outColor = vec4(0.); - const vec4 baseColor = vColor * texture(sTexture0, vTexture0); + const vec4 tex_color = texture(sTexture0, vTexture0); + // TODO make sure textures are premultiplied alpha + const vec4 baseColor = vColor * tex_color; if (baseColor.a < alpha_test_threshold) discard; outColor.a = baseColor.a; - - if ((vFlags & FLAG_VERTEX_LIGHTING) == 0) - outColor.rgb += baseColor.rgb * texture(sLightmap, vLightmapUV).rgb; - else - outColor.rgb += baseColor.rgb; + outColor.rgb += baseColor.rgb * texture(sLightmap, vLightmapUV).rgb; for (uint i = 0; i < ubo.num_lights; ++i) { const vec4 light_pos_r = ubo.lights[i].pos_r; diff --git a/ref/vk/shaders/brush.vert b/ref/vk/shaders/brush.vert index 573d8732..86d045fe 100644 --- a/ref/vk/shaders/brush.vert +++ b/ref/vk/shaders/brush.vert @@ -10,27 +10,18 @@ layout(location=1) in vec3 aNormal; layout(location=2) in vec2 aTexture0; layout(location=3) in vec2 aLightmapUV; layout(location=4) in vec4 aLightColor; -layout(location=5) in uint aFlags; layout(location=0) out vec3 vPos; layout(location=1) out vec3 vNormal; layout(location=2) out vec2 vTexture0; layout(location=3) out vec2 vLightmapUV; layout(location=4) out vec4 vColor; -layout(location=5) flat out uint vFlags; - -#define FLAG_VERTEX_LIGHTING 1 void main() { vPos = aPos.xyz; vNormal = aNormal; vTexture0 = aTexture0; vLightmapUV = aLightmapUV; - vColor = ubo.color; - - if ((aFlags & FLAG_VERTEX_LIGHTING) != 0) - vColor *= aLightColor; - - vFlags = aFlags; + vColor = ubo.color * aLightColor; gl_Position = ubo.mvp * vec4(aPos.xyz, 1.); } diff --git a/ref/vk/vk_beams.c b/ref/vk/vk_beams.c index 65c9aad9..66c9eec7 100644 --- a/ref/vk/vk_beams.c +++ b/ref/vk/vk_beams.c @@ -300,7 +300,6 @@ static void R_DrawSegs( vec3_t source, vec3_t delta, float width, float scale, f dst_vtx->lm_tc[0] = dst_vtx->lm_tc[1] = 0.f; dst_vtx->gl_tc[0] = 0.0f; dst_vtx->gl_tc[1] = curSeg.texcoord; - dst_vtx->flags = 1; applyBrightness( brightness, dst_vtx->color ); VectorCopy( vPoint1, dst_vtx->pos ); VectorCopy( vAveNormal, dst_vtx->normal ); @@ -309,7 +308,6 @@ static void R_DrawSegs( vec3_t source, vec3_t delta, float width, float scale, f dst_vtx->lm_tc[0] = dst_vtx->lm_tc[1] = 0.f; dst_vtx->gl_tc[0] = 1.0f; dst_vtx->gl_tc[1] = curSeg.texcoord; - dst_vtx->flags = 1; applyBrightness( brightness, dst_vtx->color ); VectorCopy( vPoint2, dst_vtx->pos ); VectorCopy( vAveNormal, dst_vtx->normal ); @@ -342,7 +340,6 @@ static void R_DrawSegs( vec3_t source, vec3_t delta, float width, float scale, f dst_vtx->lm_tc[0] = dst_vtx->lm_tc[1] = 0.f; dst_vtx->gl_tc[0] = 0.0f; dst_vtx->gl_tc[1] = curSeg.texcoord; - dst_vtx->flags = 1; applyBrightness( brightness, dst_vtx->color ); VectorCopy( vPoint1, dst_vtx->pos ); VectorCopy( vLastNormal, dst_vtx->normal ); @@ -351,7 +348,6 @@ static void R_DrawSegs( vec3_t source, vec3_t delta, float width, float scale, f dst_vtx->lm_tc[0] = dst_vtx->lm_tc[1] = 0.f; dst_vtx->gl_tc[0] = 1.0f; dst_vtx->gl_tc[1] = curSeg.texcoord; - dst_vtx->flags = 1; applyBrightness( brightness, dst_vtx->color ); VectorCopy( vPoint2, dst_vtx->pos ); VectorCopy( vLastNormal, dst_vtx->normal ); diff --git a/ref/vk/vk_brush.c b/ref/vk/vk_brush.c index 6d527394..8b45aaa7 100644 --- a/ref/vk/vk_brush.c +++ b/ref/vk/vk_brush.c @@ -169,6 +169,8 @@ static void EmitWaterPolys( const cl_entity_t *ent, const msurface_t *warp, qboo poly_vertices[i].lm_tc[0] = 0; poly_vertices[i].lm_tc[1] = 0; + Vector4Set(poly_vertices[i].color, 255, 255, 255, 255); + #define WATER_NORMALS poly_vertices[i].normal[0] = 0; poly_vertices[i].normal[1] = 0; @@ -654,6 +656,8 @@ static qboolean loadBrushSurfaces( model_sizes_t sizes, const model_t *mod ) { vertex.lm_tc[0] = s; vertex.lm_tc[1] = t; + Vector4Set(vertex.color, 255, 255, 255, 255); + *(bvert++) = vertex; // Ray tracing apparently expects triangle list only (although spec is not very clear about this kekw) diff --git a/ref/vk/vk_geometry.h b/ref/vk/vk_geometry.h index 24388443..90aa31d9 100644 --- a/ref/vk/vk_geometry.h +++ b/ref/vk/vk_geometry.h @@ -14,15 +14,14 @@ // TODO is this a good place? typedef struct vk_vertex_s { // TODO padding needed for storage buffer reading, figure out how to fix in GLSL/SPV side - vec3_t pos; float p0_; - vec3_t prev_pos; float p01_; - vec3_t normal; uint32_t flags; - vec3_t tangent; uint32_t p1_; + vec3_t pos; float pad0_; + vec3_t prev_pos; float pad1_; + vec3_t normal; uint32_t pad2_; + vec3_t tangent; uint32_t pad3_; vec2_t gl_tc; //float p2_[2]; vec2_t lm_tc; //float p3_[2]; - - rgba_t color; // per-vertex (non-rt lighting) color, color[3] == 1(255) => use color, discard lightmap; color[3] == 0 => use lightmap, discard color - float _padding[3]; + rgba_t color; + float pad4_[3]; } vk_vertex_t; typedef struct { diff --git a/ref/vk/vk_render.c b/ref/vk/vk_render.c index f15aa879..224db005 100644 --- a/ref/vk/vk_render.c +++ b/ref/vk/vk_render.c @@ -87,7 +87,6 @@ static qboolean createPipelines( void ) {.binding = 0, .location = 2, .format = VK_FORMAT_R32G32_SFLOAT, .offset = offsetof(vk_vertex_t, gl_tc)}, {.binding = 0, .location = 3, .format = VK_FORMAT_R32G32_SFLOAT, .offset = offsetof(vk_vertex_t, lm_tc)}, {.binding = 0, .location = 4, .format = VK_FORMAT_R8G8B8A8_UNORM, .offset = offsetof(vk_vertex_t, color)}, - {.binding = 0, .location = 5, .format = VK_FORMAT_R32_UINT, .offset = offsetof(vk_vertex_t, flags)}, {.binding = 0, .location = 6, .format = VK_FORMAT_R32G32B32_SFLOAT, .offset = offsetof(vk_vertex_t, prev_pos)}, }; diff --git a/ref/vk/vk_sprite.c b/ref/vk/vk_sprite.c index 35988d6c..56d8705e 100644 --- a/ref/vk/vk_sprite.c +++ b/ref/vk/vk_sprite.c @@ -679,7 +679,6 @@ static void R_DrawSpriteQuad( const char *debug_name, mspriteframe_t *frame, vec dst_vtx[0].gl_tc[0] = 0.f; dst_vtx[0].gl_tc[1] = 1.f; dst_vtx[0].lm_tc[0] = dst_vtx[0].lm_tc[1] = 0.f; - dst_vtx[0].flags = 1; // vertex lighting instead of lightmap lighting Vector4Set(dst_vtx[0].color, 255, 255, 255, 255); VectorCopy(v_normal, dst_vtx[0].normal); @@ -688,7 +687,6 @@ static void R_DrawSpriteQuad( const char *debug_name, mspriteframe_t *frame, vec dst_vtx[1].gl_tc[0] = 0.f; dst_vtx[1].gl_tc[1] = 0.f; dst_vtx[1].lm_tc[0] = dst_vtx[1].lm_tc[1] = 0.f; - dst_vtx[1].flags = 1; // vertex lighting instead of lightmap lighting Vector4Set(dst_vtx[1].color, 255, 255, 255, 255); VectorCopy(v_normal, dst_vtx[1].normal); @@ -697,7 +695,6 @@ static void R_DrawSpriteQuad( const char *debug_name, mspriteframe_t *frame, vec dst_vtx[2].gl_tc[0] = 1.f; dst_vtx[2].gl_tc[1] = 0.f; dst_vtx[2].lm_tc[0] = dst_vtx[2].lm_tc[1] = 0.f; - dst_vtx[2].flags = 1; // vertex lighting instead of lightmap lighting Vector4Set(dst_vtx[2].color, 255, 255, 255, 255); VectorCopy(v_normal, dst_vtx[2].normal); @@ -706,7 +703,6 @@ static void R_DrawSpriteQuad( const char *debug_name, mspriteframe_t *frame, vec dst_vtx[3].gl_tc[0] = 1.f; dst_vtx[3].gl_tc[1] = 1.f; dst_vtx[3].lm_tc[0] = dst_vtx[3].lm_tc[1] = 0.f; - dst_vtx[3].flags = 1; // vertex lighting instead of lightmap lighting Vector4Set(dst_vtx[3].color, 255, 255, 255, 255); VectorCopy(v_normal, dst_vtx[3].normal); diff --git a/ref/vk/vk_studio.c b/ref/vk/vk_studio.c index 64ffb833..0fb4f897 100644 --- a/ref/vk/vk_studio.c +++ b/ref/vk/vk_studio.c @@ -1932,7 +1932,6 @@ static void R_StudioDrawNormalMesh( short *ptricmds, vec3_t *pstudionorms, float dst_vtx->gl_tc[1] = ptricmds[3] * t; } - dst_vtx->flags = 1; // vertex lighting instead of lightmap lighting R_StudioSetColorBegin( ptricmds, pstudionorms, dst_vtx->color ); if (j > 1) { From ee4def11410273834b510f9a987f18e2e4839307 Mon Sep 17 00:00:00 2001 From: Ivan 'provod' Avdeev Date: Sat, 25 Feb 2023 18:41:01 -0800 Subject: [PATCH 04/11] rt: modulate additive kusochki by vertex color attribute --- ref/vk/shaders/additive.rahit | 2 +- ref/vk/shaders/alphamask.rahit | 2 +- ref/vk/shaders/light_common.glsl | 6 ++-- ref/vk/shaders/ray_kusochki.glsl | 8 ++---- ref/vk/shaders/rt_geometry.glsl | 44 ++++++++++++++++++------------ ref/vk/shaders/trace_additive.glsl | 6 ++-- ref/vk/shaders/utils.glsl | 11 +++++--- 7 files changed, 43 insertions(+), 36 deletions(-) diff --git a/ref/vk/shaders/additive.rahit b/ref/vk/shaders/additive.rahit index ab9a7eb2..973074c1 100644 --- a/ref/vk/shaders/additive.rahit +++ b/ref/vk/shaders/additive.rahit @@ -24,7 +24,7 @@ void main() { const uint vi2 = uint(getIndex(first_index_offset+1)) + getKusok(kusok_index).vertex_offset; const uint vi3 = uint(getIndex(first_index_offset+2)) + getKusok(kusok_index).vertex_offset; - const vec2 texture_uv = getVertex(vi1).gl_tc * (1. - bary.x - bary.y) + getVertex(vi2).gl_tc * bary.x + getVertex(vi3).gl_tc * bary.y + push_constants.time * getKusok(kusok_index).uv_speed; + const vec2 texture_uv = GET_VERTEX(vi1).gl_tc * (1. - bary.x - bary.y) + GET_VERTEX(vi2).gl_tc * bary.x + GET_VERTEX(vi3).gl_tc * bary.y + push_constants.time * getKusok(kusok_index).uv_speed; // TODO mips const uint tex_index = getKusok(kusok_index).tex_base_color; const vec4 texture_color = texture(textures[nonuniformEXT(tex_index)], texture_uv); diff --git a/ref/vk/shaders/alphamask.rahit b/ref/vk/shaders/alphamask.rahit index f2d07213..59ae5a46 100644 --- a/ref/vk/shaders/alphamask.rahit +++ b/ref/vk/shaders/alphamask.rahit @@ -18,7 +18,7 @@ void main() { const uint vi2 = uint(getIndex(first_index_offset+1)) + getKusok(kusok_index).vertex_offset; const uint vi3 = uint(getIndex(first_index_offset+2)) + getKusok(kusok_index).vertex_offset; - const vec2 texture_uv = getVertex(vi1).gl_tc * (1. - bary.x - bary.y) + getVertex(vi2).gl_tc * bary.x + getVertex(vi3).gl_tc * bary.y; + const vec2 texture_uv = GET_VERTEX(vi1).gl_tc * (1. - bary.x - bary.y) + GET_VERTEX(vi2).gl_tc * bary.x + GET_VERTEX(vi3).gl_tc * bary.y; const uint tex_index = getKusok(kusok_index).tex_base_color; const vec4 texture_color = texture(textures[nonuniformEXT(tex_index)], texture_uv); diff --git a/ref/vk/shaders/light_common.glsl b/ref/vk/shaders/light_common.glsl index ee2cba92..dbfb7b16 100644 --- a/ref/vk/shaders/light_common.glsl +++ b/ref/vk/shaders/light_common.glsl @@ -53,9 +53,9 @@ bool shadowTestAlphaMask(vec3 pos, vec3 dir, float dist) { const uint vi2 = uint(getIndex(first_index_offset+1)) + kusok.vertex_offset; const uint vi3 = uint(getIndex(first_index_offset+2)) + kusok.vertex_offset; const vec2 uvs[3] = { - getVertex(vi1).gl_tc, - getVertex(vi2).gl_tc, - getVertex(vi3).gl_tc, + GET_VERTEX(vi1).gl_tc, + GET_VERTEX(vi2).gl_tc, + GET_VERTEX(vi3).gl_tc, }; const vec2 bary = rayQueryGetIntersectionBarycentricsEXT(rq, false); const vec2 uv = baryMix(uvs[0], uvs[1], uvs[2], bary); diff --git a/ref/vk/shaders/ray_kusochki.glsl b/ref/vk/shaders/ray_kusochki.glsl index 9ae612b9..af0110fe 100644 --- a/ref/vk/shaders/ray_kusochki.glsl +++ b/ref/vk/shaders/ray_kusochki.glsl @@ -1,7 +1,6 @@ #ifndef RAY_KUSOCHKI_GLSL_INCLUDED #define RAY_KUSOCHKI_GLSL_INCLUDED #extension GL_EXT_shader_16bit_storage : require -//#extension GL_EXT_shader_8bit_storage : require #define GLSL #include "ray_interop.h" @@ -14,10 +13,7 @@ struct Vertex { vec3 tangent; vec2 gl_tc; vec2 _unused_lm_tc; - - //float padding; - //uint8_t color[4]; - uint _unused_color_u8_4; + uint color; }; layout(std430, binding = 3, set = 0) readonly buffer Kusochki { Kusok a[]; } kusochki; @@ -26,6 +22,6 @@ layout(std430, binding = 5, set = 0) readonly buffer Vertices { Vertex a[]; } ve Kusok getKusok(uint index) { return kusochki.a[index]; } uint16_t getIndex(uint index) { return indices.a[index]; } -Vertex getVertex(uint index) { return vertices.a[index]; } +#define GET_VERTEX(index) (vertices.a[index]) #endif //ifndef RAY_KUSOCHKI_GLSL_INCLUDED diff --git a/ref/vk/shaders/rt_geometry.glsl b/ref/vk/shaders/rt_geometry.glsl index 87b42e72..c2274f81 100644 --- a/ref/vk/shaders/rt_geometry.glsl +++ b/ref/vk/shaders/rt_geometry.glsl @@ -83,21 +83,21 @@ Geometry readHitGeometry(vec2 bary, float ray_cone_width) { const uint vi3 = uint(getIndex(first_index_offset+2)) + kusok.vertex_offset; const vec3 pos[3] = { - objectToWorld * vec4(getVertex(vi1).pos, 1.f), - objectToWorld * vec4(getVertex(vi2).pos, 1.f), - objectToWorld * vec4(getVertex(vi3).pos, 1.f), + objectToWorld * vec4(GET_VERTEX(vi1).pos, 1.f), + objectToWorld * vec4(GET_VERTEX(vi2).pos, 1.f), + objectToWorld * vec4(GET_VERTEX(vi3).pos, 1.f), }; const vec3 prev_pos[3] = { - (kusok.prev_transform * vec4(getVertex(vi1).prev_pos, 1.f)).xyz, - (kusok.prev_transform * vec4(getVertex(vi2).prev_pos, 1.f)).xyz, - (kusok.prev_transform * vec4(getVertex(vi3).prev_pos, 1.f)).xyz, + (kusok.prev_transform * vec4(GET_VERTEX(vi1).prev_pos, 1.f)).xyz, + (kusok.prev_transform * vec4(GET_VERTEX(vi2).prev_pos, 1.f)).xyz, + (kusok.prev_transform * vec4(GET_VERTEX(vi3).prev_pos, 1.f)).xyz, }; const vec2 uvs[3] = { - getVertex(vi1).gl_tc, - getVertex(vi2).gl_tc, - getVertex(vi3).gl_tc, + GET_VERTEX(vi1).gl_tc, + GET_VERTEX(vi2).gl_tc, + GET_VERTEX(vi3).gl_tc, }; geom.pos = baryMix(pos[0], pos[1], pos[2], bary); @@ -111,14 +111,14 @@ Geometry readHitGeometry(vec2 bary, float ray_cone_width) { // NOTE: only support rotations, for arbitrary transform would need to do transpose(inverse(mat3(gl_ObjectToWorldEXT))) const mat3 normalTransform = mat3(objectToWorld); // mat3(gl_ObjectToWorldEXT); geom.normal_shading = normalize(normalTransform * baryMix( - getVertex(vi1).normal, - getVertex(vi2).normal, - getVertex(vi3).normal, + GET_VERTEX(vi1).normal, + GET_VERTEX(vi2).normal, + GET_VERTEX(vi3).normal, bary)); geom.tangent = normalize(normalTransform * baryMix( - getVertex(vi1).tangent, - getVertex(vi2).tangent, - getVertex(vi3).tangent, + GET_VERTEX(vi1).tangent, + GET_VERTEX(vi2).tangent, + GET_VERTEX(vi3).tangent, bary)); geom.uv_lods = computeAnisotropicEllipseAxes(geom.pos, geom.normal_geometry, ray_direction, ray_cone_width * hit_t, pos, uvs, geom.uv); @@ -130,6 +130,7 @@ Geometry readHitGeometry(vec2 bary, float ray_cone_width) { struct MiniGeometry { vec2 uv; uint kusok_index; + vec4 color; }; MiniGeometry readCandidateMiniGeometry(rayQueryEXT rq) { @@ -144,16 +145,23 @@ MiniGeometry readCandidateMiniGeometry(rayQueryEXT rq) { const uint vi2 = uint(getIndex(first_index_offset+1)) + kusok.vertex_offset; const uint vi3 = uint(getIndex(first_index_offset+2)) + kusok.vertex_offset; const vec2 uvs[3] = { - getVertex(vi1).gl_tc, - getVertex(vi2).gl_tc, - getVertex(vi3).gl_tc, + GET_VERTEX(vi1).gl_tc, + GET_VERTEX(vi2).gl_tc, + GET_VERTEX(vi3).gl_tc, }; const vec2 bary = rayQueryGetIntersectionBarycentricsEXT(rq, false); const vec2 uv = baryMix(uvs[0], uvs[1], uvs[2], bary); + const vec4 colors[3] = { + unpackUnorm4x8(GET_VERTEX(vi1).color), + unpackUnorm4x8(GET_VERTEX(vi2).color), + unpackUnorm4x8(GET_VERTEX(vi3).color), + }; + MiniGeometry ret; ret.uv = uv; ret.kusok_index = kusok_index; + ret.color = baryMix(colors[0], colors[1], colors[2], bary); return ret; } #endif // #ifdef RAY_QUERY diff --git a/ref/vk/shaders/trace_additive.glsl b/ref/vk/shaders/trace_additive.glsl index 05c7a274..ddc22116 100644 --- a/ref/vk/shaders/trace_additive.glsl +++ b/ref/vk/shaders/trace_additive.glsl @@ -13,10 +13,10 @@ vec3 traceAdditive(vec3 pos, vec3 dir, float L) { rayQueryInitializeEXT(rq, tlas, flags, GEOMETRY_BIT_ADDITIVE, pos, 0., dir, L + additive_soft_overshoot); while (rayQueryProceedEXT(rq)) { const MiniGeometry geom = readCandidateMiniGeometry(rq); - const uint tex_base_color = getKusok(geom.kusok_index).tex_base_color; - const vec4 texture_color = texture(textures[nonuniformEXT(tex_base_color)], geom.uv); const Kusok kusok = getKusok(geom.kusok_index); - const vec3 color = texture_color.rgb * kusok.emissive * texture_color.a * kusok.color.a; + + const vec4 texture_color = texture(textures[nonuniformEXT(kusok.tex_base_color)], geom.uv); + const vec3 color = texture_color.rgb * kusok.emissive * texture_color.a * kusok.color.a * SRGBtoLINEAR(geom.color.rgb * geom.color.a); const float hit_t = rayQueryGetIntersectionTEXT(rq, false); const float overshoot = hit_t - L; diff --git a/ref/vk/shaders/utils.glsl b/ref/vk/shaders/utils.glsl index d06d55af..7c6a2a51 100644 --- a/ref/vk/shaders/utils.glsl +++ b/ref/vk/shaders/utils.glsl @@ -30,12 +30,15 @@ vec3 normalDecode( vec2 f ) return normalize( n ); } -vec3 baryMix(vec3 v1, vec3 v2, vec3 v3, vec2 bary) { - return v1 * (1. - bary.x - bary.y) + v2 * bary.x + v3 * bary.y; -} - vec2 baryMix(vec2 v1, vec2 v2, vec2 v3, vec2 bary) { return v1 * (1. - bary.x - bary.y) + v2 * bary.x + v3 * bary.y; } +vec3 baryMix(vec3 v1, vec3 v2, vec3 v3, vec2 bary) { + return v1 * (1. - bary.x - bary.y) + v2 * bary.x + v3 * bary.y; +} + +vec4 baryMix(vec4 v1, vec4 v2, vec4 v3, vec2 bary) { + return v1 * (1. - bary.x - bary.y) + v2 * bary.x + v3 * bary.y; +} #endif // UTILS_GLSL_INCLUDED From a118e12e014c968c3054896800cf250eec61f2d3 Mon Sep 17 00:00:00 2001 From: Ivan 'provod' Avdeev Date: Sun, 26 Feb 2023 20:45:29 -0800 Subject: [PATCH 05/11] vk: stub just enough triapi to render more beam types it is still drawn incorrectly, but at least something is visible, and we can iterate from here --- ref/vk/vk_beams.c | 27 +++++--- ref/vk/vk_triapi.c | 168 +++++++++++++++++++++++++++++++++++++++++++++ ref/vk/vk_triapi.h | 15 ++++ 3 files changed, 201 insertions(+), 9 deletions(-) create mode 100644 ref/vk/vk_triapi.c create mode 100644 ref/vk/vk_triapi.h diff --git a/ref/vk/vk_beams.c b/ref/vk/vk_beams.c index 66c9eec7..6d40b60d 100644 --- a/ref/vk/vk_beams.c +++ b/ref/vk/vk_beams.c @@ -7,6 +7,7 @@ #include "vk_sprite.h" #include "vk_scene.h" #include "vk_math.h" +#include "vk_triapi.h" #include "xash3d_types.h" #include "xash3d_mathlib.h" @@ -400,9 +401,6 @@ static void R_DrawSegs( vec3_t source, vec3_t delta, float width, float scale, f static void R_DrawTorus( vec3_t source, vec3_t delta, float width, float scale, float freq, float speed, int segments ) { - PRINT_NOT_IMPLEMENTED(); - -/* FIXME VK int i, noiseIndex, noiseStep; float div, length, fraction, factor, vLast, vStep; vec3_t last1, last2, point, screen, screenLast, tmp, normal; @@ -481,7 +479,6 @@ static void R_DrawTorus( vec3_t source, vec3_t delta, float width, float scale, VectorCopy( screen, screenLast ); noiseIndex += noiseStep; } -*/ } static void R_DrawDisk( vec3_t source, vec3_t delta, float width, float scale, float freq, float speed, int segments ) @@ -741,9 +738,6 @@ static void R_DrawBeamFollow( BEAM *pbeam, float frametime ) static void R_DrawRing( vec3_t source, vec3_t delta, float width, float amplitude, float freq, float speed, int segments ) { - PRINT_NOT_IMPLEMENTED(); - -/* FIXME VK int i, j, noiseIndex, noiseStep; float div, length, fraction, factor, vLast, vStep; vec3_t last1, last2, point, screen, screenLast; @@ -787,6 +781,7 @@ static void R_DrawRing( vec3_t source, vec3_t delta, float width, float amplitud VectorAdd( center, last1, tmp ); // maxs VectorSubtract( center, last1, screen ); // mins + /* FIXME VK if( !WORLDMODEL ) return; @@ -795,6 +790,7 @@ static void R_DrawRing( vec3_t source, vec3_t delta, float width, float amplitud { return; } + */ VectorSet( yaxis, xaxis[1], -xaxis[0], 0.0f ); VectorNormalize( yaxis ); @@ -855,7 +851,6 @@ static void R_DrawRing( vec3_t source, vec3_t delta, float width, float amplitud FracNoise( rgNoise, NOISE_DIVISIONS ); } } -*/ } /* @@ -1115,15 +1110,24 @@ void R_BeamDraw( BEAM *pbeam, float frametime ) { case TE_BEAMTORUS: // FIXME VK GL_Cull( GL_NONE ); + TriBegin( TRI_TRIANGLE_STRIP ); + TriColor4f( color[0], color[1], color[2], color[3] ); R_DrawTorus( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments ); + TriEnd(); break; case TE_BEAMDISK: // FIXME VK GL_Cull( GL_NONE ); + TriBegin( TRI_TRIANGLE_STRIP ); + TriColor4f( color[0], color[1], color[2], color[3] ); R_DrawDisk( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments ); + TriEnd(); break; case TE_BEAMCYLINDER: // FIXME VK GL_Cull( GL_NONE ); + TriBegin( TRI_TRIANGLE_STRIP ); + TriColor4f( color[0], color[1], color[2], color[3] ); R_DrawCylinder( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments ); + TriEnd(); break; case TE_BEAMPOINTS: case TE_BEAMHOSE: @@ -1131,11 +1135,16 @@ void R_BeamDraw( BEAM *pbeam, float frametime ) break; case TE_BEAMFOLLOW: // FIXME VK TriBegin( TRI_QUADS ); - R_DrawBeamFollow( pbeam, frametime ); + //TriColor4f( color[0], color[1], color[2], color[3] ); + //R_DrawBeamFollow( pbeam, frametime ); + //TriEnd(); break; case TE_BEAMRING: // FIXME VK GL_Cull( GL_NONE ); + TriBegin( TRI_TRIANGLE_STRIP ); + TriColor4f( color[0], color[1], color[2], color[3] ); R_DrawRing( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments ); + TriEnd(); break; } diff --git a/ref/vk/vk_triapi.c b/ref/vk/vk_triapi.c new file mode 100644 index 00000000..72e397f4 --- /dev/null +++ b/ref/vk/vk_triapi.c @@ -0,0 +1,168 @@ +#include "vk_triapi.h" +#include "vk_geometry.h" +#include "vk_render.h" + +#include "vk_textures.h" // FIXME temp + +#include "xash3d_mathlib.h" + +#define MAX_TRIAPI_VERTICES 1024 +#define MAX_TRIAPI_INDICES 1024 + +static struct { + vk_vertex_t vertices[MAX_TRIAPI_VERTICES]; + uint16_t indices[MAX_TRIAPI_INDICES]; + + int num_vertices; + int mode; +} g_triapi = {0}; + +void TriBegin( int mode ) { + ASSERT(!g_triapi.mode); + + switch(mode) { + case TRI_TRIANGLES: break; + case TRI_TRIANGLE_STRIP: break; + default: + gEngine.Con_Printf(S_ERROR "TriBegin: unsupported mode %d\n", mode); + return; + } + + g_triapi.mode = mode + 1; + g_triapi.num_vertices = 0; + + vk_vertex_t *const ve = g_triapi.vertices + 0; + memset(ve, 0, sizeof *ve); + Vector4Set(ve->color, 255, 255, 255, 255); +} + +/* static int genTrianglesIndices(void) { */ +/* return 0; */ +/* } */ + +static int genTriangleStripIndices(void) { + int num_indices = 0; + uint16_t *const dst_idx = g_triapi.indices; + for (int i = 2; i < g_triapi.num_vertices; ++i) { + if( i & 1 ) + { + // draw triangle [n-1 n-2 n] + dst_idx[num_indices++] = i - 1; + dst_idx[num_indices++] = i - 2; + dst_idx[num_indices++] = i; + } + else + { + // draw triangle [n-2 n-1 n] + dst_idx[num_indices++] = i - 2; + dst_idx[num_indices++] = i - 1; + dst_idx[num_indices++] = i; + } + } + return num_indices; +} + +static void emitDynamicGeometry(int num_indices) { + if (!num_indices) + return; + + r_geometry_buffer_lock_t buffer; + if (!R_GeometryBufferAllocAndLock( &buffer, g_triapi.num_vertices, num_indices, LifetimeSingleFrame )) { + gEngine.Con_Printf(S_ERROR "Cannot allocate geometry for tri api\n"); + return; + } + + memcpy(buffer.vertices.ptr, g_triapi.vertices, sizeof(vk_vertex_t) * g_triapi.num_vertices); + memcpy(buffer.indices.ptr, g_triapi.indices, sizeof(uint16_t) * num_indices); + + R_GeometryBufferUnlock( &buffer ); + + { + // FIXME pass these properly + const int texture = tglob.whiteTexture; + const vec4_t color = {1, 1, 1, 1}; + const vk_render_type_e render_type = kVkRenderType_A_1_R; + const char* name = "FIXME triapi"; + + const vk_render_geometry_t geometry = { + .texture = texture, + .material = kXVkMaterialEmissive, + + .max_vertex = g_triapi.num_vertices, + .vertex_offset = buffer.vertices.unit_offset, + + .element_count = num_indices, + .index_offset = buffer.indices.unit_offset, + + .emissive = { color[0], color[1], color[2] }, + }; + + VK_RenderModelDynamicBegin( render_type, color, name ); + VK_RenderModelDynamicAddGeometry( &geometry ); + VK_RenderModelDynamicCommit(); + } +} + +void TriEnd( void ) { + if (!g_triapi.mode) + return; + + if (!g_triapi.num_vertices) + return; + + int num_indices = 0; + switch(g_triapi.mode - 1) { + /* case TRI_TRIANGLES: */ + /* num_indices = genTrianglesIndices(); */ + /* break; */ + case TRI_TRIANGLE_STRIP: + num_indices = genTriangleStripIndices(); + break; + default: + gEngine.Con_Printf(S_ERROR "TriEnd: unsupported mode %d\n", g_triapi.mode - 1); + break; + } + + emitDynamicGeometry(num_indices); + + g_triapi.num_vertices = 0; + g_triapi.mode = 0; +} + +void TriTexCoord2f( float u, float v ) { + vk_vertex_t *const ve = g_triapi.vertices + g_triapi.num_vertices; + Vector2Set(ve->gl_tc, u, v); +} + +void TriVertex3fv( const float *v ) { + TriVertex3f(v[0], v[1], v[2]); +} + +void TriVertex3f( float x, float y, float z ) { + if (g_triapi.num_vertices == MAX_TRIAPI_VERTICES - 1) { + gEngine.Con_Printf(S_ERROR "vk TriApi: trying to emit more than %d vertices in one batch\n", MAX_TRIAPI_VERTICES); + return; + } + + vk_vertex_t *const ve = g_triapi.vertices + g_triapi.num_vertices; + VectorSet(ve->pos, x, y, z); + + // Emit vertex preserving previous vertex values + ++g_triapi.num_vertices; + g_triapi.vertices[g_triapi.num_vertices] = g_triapi.vertices[g_triapi.num_vertices-1]; +} + +static int clampi32(int v, int min, int max) { + if (v < min) return min; + if (v > max) return max; + return v; +} + +void TriColor4ub_( byte r, byte g, byte b, byte a ) { + Vector4Set(g_triapi.vertices[g_triapi.num_vertices].color, r, g, b, a); +} + +void TriColor4f( float r, float g, float b, float a ) { + TriColor4ub_(clampi32(r*255.f, 0, 255),clampi32(g*255.f, 0, 255),clampi32(b*255.f, 0, 255),clampi32(a*255.f, 0, 255)); +} + diff --git a/ref/vk/vk_triapi.h b/ref/vk/vk_triapi.h new file mode 100644 index 00000000..75b22097 --- /dev/null +++ b/ref/vk/vk_triapi.h @@ -0,0 +1,15 @@ +#pragma once + +#include "xash3d_types.h" + +void TriBegin( int mode ); + +void TriTexCoord2f( float u, float v ); +void TriColor4f( float r, float g, float b, float a ); +//void TriColor4ub( byte r, byte g, byte b, byte a ); + +// Emits next vertex +void TriVertex3fv( const float *v ); +void TriVertex3f( float x, float y, float z ); + +void TriEnd( void ); From cf5d3d9d47d200cb644158f133adb9d9b6e1ee7e Mon Sep 17 00:00:00 2001 From: Ivan 'provod' Avdeev Date: Mon, 27 Feb 2023 08:46:12 -0800 Subject: [PATCH 06/11] vk: increase limits for triapi c4a1 was using too many indices --- ref/vk/vk_triapi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ref/vk/vk_triapi.c b/ref/vk/vk_triapi.c index 72e397f4..f1c540ee 100644 --- a/ref/vk/vk_triapi.c +++ b/ref/vk/vk_triapi.c @@ -7,7 +7,7 @@ #include "xash3d_mathlib.h" #define MAX_TRIAPI_VERTICES 1024 -#define MAX_TRIAPI_INDICES 1024 +#define MAX_TRIAPI_INDICES 4096 static struct { vk_vertex_t vertices[MAX_TRIAPI_VERTICES]; @@ -44,6 +44,11 @@ static int genTriangleStripIndices(void) { int num_indices = 0; uint16_t *const dst_idx = g_triapi.indices; for (int i = 2; i < g_triapi.num_vertices; ++i) { + if (num_indices > MAX_TRIAPI_INDICES - 3) { + gEngine.Con_Printf(S_ERROR "Triapi ran out of indices space, max %d (vertices=%d)\n", MAX_TRIAPI_INDICES, g_triapi.num_vertices); + break; + } + if( i & 1 ) { // draw triangle [n-1 n-2 n] From 2daa130453fc178423855caabcd19599780f216b Mon Sep 17 00:00:00 2001 From: Ivan 'provod' Avdeev Date: Mon, 27 Feb 2023 09:20:13 -0800 Subject: [PATCH 07/11] vk: set beam/triapi texture and render mode explicitly --- ref/vk/vk_beams.c | 8 +++--- ref/vk/vk_triapi.c | 61 ++++++++++++++++++++++++++++++++-------------- ref/vk/vk_triapi.h | 4 ++- 3 files changed, 50 insertions(+), 23 deletions(-) diff --git a/ref/vk/vk_beams.c b/ref/vk/vk_beams.c index 6d40b60d..7e3aa73f 100644 --- a/ref/vk/vk_beams.c +++ b/ref/vk/vk_beams.c @@ -1106,26 +1106,27 @@ void R_BeamDraw( BEAM *pbeam, float frametime ) // TODO gl renderer has per-vertex color that is updated using brightness and whatever VK_RenderDebugLabelBegin( "beam" ); + TriSetTexture( texturenum ); + TriRenderMode( render_mode ); + TriColor4f( color[0], color[1], color[2], color[3] ); + switch( pbeam->type ) { case TE_BEAMTORUS: // FIXME VK GL_Cull( GL_NONE ); TriBegin( TRI_TRIANGLE_STRIP ); - TriColor4f( color[0], color[1], color[2], color[3] ); R_DrawTorus( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments ); TriEnd(); break; case TE_BEAMDISK: // FIXME VK GL_Cull( GL_NONE ); TriBegin( TRI_TRIANGLE_STRIP ); - TriColor4f( color[0], color[1], color[2], color[3] ); R_DrawDisk( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments ); TriEnd(); break; case TE_BEAMCYLINDER: // FIXME VK GL_Cull( GL_NONE ); TriBegin( TRI_TRIANGLE_STRIP ); - TriColor4f( color[0], color[1], color[2], color[3] ); R_DrawCylinder( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments ); TriEnd(); break; @@ -1142,7 +1143,6 @@ void R_BeamDraw( BEAM *pbeam, float frametime ) case TE_BEAMRING: // FIXME VK GL_Cull( GL_NONE ); TriBegin( TRI_TRIANGLE_STRIP ); - TriColor4f( color[0], color[1], color[2], color[3] ); R_DrawRing( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments ); TriEnd(); break; diff --git a/ref/vk/vk_triapi.c b/ref/vk/vk_triapi.c index f1c540ee..7631950b 100644 --- a/ref/vk/vk_triapi.c +++ b/ref/vk/vk_triapi.c @@ -14,26 +14,53 @@ static struct { uint16_t indices[MAX_TRIAPI_INDICES]; int num_vertices; - int mode; + int primitive_mode; + int texture_index; + + vk_render_type_e render_type; + + qboolean initialized; } g_triapi = {0}; -void TriBegin( int mode ) { - ASSERT(!g_triapi.mode); +void TriSetTexture( int texture_index ) { + g_triapi.texture_index = texture_index; +} - switch(mode) { +void TriRenderMode( int render_mode ) { + switch( render_mode ) + { + case kRenderTransAlpha: g_triapi.render_type = kVkRenderType_A_1mA_R; break; + case kRenderTransColor: + case kRenderTransTexture: g_triapi.render_type = kVkRenderType_A_1mA_RW; break; + case kRenderGlow: + case kRenderTransAdd: g_triapi.render_type = kVkRenderType_A_1_R; break; + case kRenderNormal: + default: g_triapi.render_type = kVkRenderTypeSolid; break; + } +} + +void TriBegin( int primitive_mode ) { + ASSERT(!g_triapi.primitive_mode); + + switch(primitive_mode) { case TRI_TRIANGLES: break; case TRI_TRIANGLE_STRIP: break; default: - gEngine.Con_Printf(S_ERROR "TriBegin: unsupported mode %d\n", mode); + gEngine.Con_Printf(S_ERROR "TriBegin: unsupported primitive_mode %d\n", primitive_mode); return; } - g_triapi.mode = mode + 1; - g_triapi.num_vertices = 0; - vk_vertex_t *const ve = g_triapi.vertices + 0; - memset(ve, 0, sizeof *ve); - Vector4Set(ve->color, 255, 255, 255, 255); + if (g_triapi.num_vertices > 1) + *ve = g_triapi.vertices[g_triapi.num_vertices-1]; + + if (!g_triapi.initialized) { + Vector4Set(ve->color, 255, 255, 255, 255); + g_triapi.initialized = true; + } + + g_triapi.primitive_mode = primitive_mode + 1; + g_triapi.num_vertices = 0; } /* static int genTrianglesIndices(void) { */ @@ -84,13 +111,11 @@ static void emitDynamicGeometry(int num_indices) { { // FIXME pass these properly - const int texture = tglob.whiteTexture; const vec4_t color = {1, 1, 1, 1}; - const vk_render_type_e render_type = kVkRenderType_A_1_R; const char* name = "FIXME triapi"; const vk_render_geometry_t geometry = { - .texture = texture, + .texture = g_triapi.texture_index, .material = kXVkMaterialEmissive, .max_vertex = g_triapi.num_vertices, @@ -102,21 +127,21 @@ static void emitDynamicGeometry(int num_indices) { .emissive = { color[0], color[1], color[2] }, }; - VK_RenderModelDynamicBegin( render_type, color, name ); + VK_RenderModelDynamicBegin( g_triapi.render_type, color, name ); VK_RenderModelDynamicAddGeometry( &geometry ); VK_RenderModelDynamicCommit(); } } void TriEnd( void ) { - if (!g_triapi.mode) + if (!g_triapi.primitive_mode) return; if (!g_triapi.num_vertices) return; int num_indices = 0; - switch(g_triapi.mode - 1) { + switch(g_triapi.primitive_mode - 1) { /* case TRI_TRIANGLES: */ /* num_indices = genTrianglesIndices(); */ /* break; */ @@ -124,14 +149,14 @@ void TriEnd( void ) { num_indices = genTriangleStripIndices(); break; default: - gEngine.Con_Printf(S_ERROR "TriEnd: unsupported mode %d\n", g_triapi.mode - 1); + gEngine.Con_Printf(S_ERROR "TriEnd: unsupported primitive_mode %d\n", g_triapi.primitive_mode - 1); break; } emitDynamicGeometry(num_indices); g_triapi.num_vertices = 0; - g_triapi.mode = 0; + g_triapi.primitive_mode = 0; } void TriTexCoord2f( float u, float v ) { diff --git a/ref/vk/vk_triapi.h b/ref/vk/vk_triapi.h index 75b22097..860d5e30 100644 --- a/ref/vk/vk_triapi.h +++ b/ref/vk/vk_triapi.h @@ -2,11 +2,13 @@ #include "xash3d_types.h" +void TriRenderMode( int mode ); +void TriSetTexture( int texture_index ); + void TriBegin( int mode ); void TriTexCoord2f( float u, float v ); void TriColor4f( float r, float g, float b, float a ); -//void TriColor4ub( byte r, byte g, byte b, byte a ); // Emits next vertex void TriVertex3fv( const float *v ); From 30334db15917d12241519f0760fc6eb62ac6036b Mon Sep 17 00:00:00 2001 From: Ivan 'provod' Avdeev Date: Mon, 27 Feb 2023 09:49:56 -0800 Subject: [PATCH 08/11] vk: draw the rest of the beams --- ref/vk/vk_beams.c | 63 ++++++++++++++++++++++------------------------ ref/vk/vk_triapi.c | 22 ++++++++++------ ref/vk/vk_triapi.h | 1 + 3 files changed, 46 insertions(+), 40 deletions(-) diff --git a/ref/vk/vk_beams.c b/ref/vk/vk_beams.c index 7e3aa73f..1de632d1 100644 --- a/ref/vk/vk_beams.c +++ b/ref/vk/vk_beams.c @@ -152,11 +152,16 @@ static float clampf(float v, float min, float max) { return v; } +// FIXME unclear how to organize this static void applyBrightness( float brightness, rgba_t out ) { out[0] = out[1] = out[2] = clampf(brightness, 0, 1) * 255.f; out[3] = 255; } +static void TriBrightness( float brightness ) { + TriColor4f( brightness, brightness, brightness, 1.f ); +} + static void R_DrawSegs( vec3_t source, vec3_t delta, float width, float scale, float freq, float speed, int segments, int flags, const vec4_t color, int texture, int render_mode ) { int noiseIndex, noiseStep; @@ -399,7 +404,7 @@ static void R_DrawSegs( vec3_t source, vec3_t delta, float width, float scale, f } } -static void R_DrawTorus( vec3_t source, vec3_t delta, float width, float scale, float freq, float speed, int segments ) +static void R_DrawTorus( vec3_t source, vec3_t delta, float width, float scale, float freq, float speed, int segments, const vec4_t color ) { int i, noiseIndex, noiseStep; float div, length, fraction, factor, vLast, vStep; @@ -426,6 +431,8 @@ static void R_DrawTorus( vec3_t source, vec3_t delta, float width, float scale, noiseStep = (int)((float)( NOISE_DIVISIONS - 1 ) * div * 65536.0f ); noiseIndex = 0; + TriBegin( TRI_TRIANGLE_STRIP ); + for( i = 0; i < segments; i++ ) { float s, c; @@ -479,13 +486,12 @@ static void R_DrawTorus( vec3_t source, vec3_t delta, float width, float scale, VectorCopy( screen, screenLast ); noiseIndex += noiseStep; } + + TriEndEx(color, "beam torus"); } -static void R_DrawDisk( vec3_t source, vec3_t delta, float width, float scale, float freq, float speed, int segments ) +static void R_DrawDisk( vec3_t source, vec3_t delta, float width, float scale, float freq, float speed, int segments, const vec4_t color ) { - PRINT_NOT_IMPLEMENTED(); - -/* FIXME VK float div, length, fraction; float w, vLast, vStep; vec3_t point; @@ -509,6 +515,8 @@ static void R_DrawDisk( vec3_t source, vec3_t delta, float width, float scale, f // clamp the beam width w = fmod( freq, width * 0.1f ) * delta[2]; + TriBegin( TRI_TRIANGLE_STRIP ); + // NOTE: we must force the degenerate triangles to be on the edge for( i = 0; i < segments; i++ ) { @@ -532,14 +540,12 @@ static void R_DrawDisk( vec3_t source, vec3_t delta, float width, float scale, f vLast += vStep; // advance texture scroll (v axis only) } - */ + + TriEndEx(color, "beam disk"); } -static void R_DrawCylinder( vec3_t source, vec3_t delta, float width, float scale, float freq, float speed, int segments ) +static void R_DrawCylinder( vec3_t source, vec3_t delta, float width, float scale, float freq, float speed, int segments, const vec4_t color ) { - PRINT_NOT_IMPLEMENTED(); - -/* FIXME VK float div, length, fraction; float vLast, vStep; vec3_t point; @@ -561,6 +567,7 @@ static void R_DrawCylinder( vec3_t source, vec3_t delta, float width, float scal vLast = fmod( freq * speed, 1 ); scale = scale * length; + TriBegin( TRI_TRIANGLE_STRIP ); for ( i = 0; i < segments; i++ ) { float s, c; @@ -586,14 +593,11 @@ static void R_DrawCylinder( vec3_t source, vec3_t delta, float width, float scal vLast += vStep; // Advance texture scroll (v axis only) } -*/ + TriEndEx(color, "beam cylinder"); } -static void R_DrawBeamFollow( BEAM *pbeam, float frametime ) +static void R_DrawBeamFollow( BEAM *pbeam, float frametime, const vec4_t color ) { - PRINT_NOT_IMPLEMENTED(); - -/* FIXME VK particle_t *pnew, *particles; float fraction, div, vLast, vStep; vec3_t last1, last2, tmp, screen; @@ -678,6 +682,7 @@ static void R_DrawBeamFollow( BEAM *pbeam, float frametime ) vLast = 0.0f; vStep = 1.0f; + TriBegin( TRI_QUADS ); while( particles ) { TriBrightness( fraction ); @@ -733,10 +738,11 @@ static void R_DrawBeamFollow( BEAM *pbeam, float frametime ) VectorMA( particles->org, frametime, particles->vel, particles->org ); particles = particles->next; } -*/ + + TriEndEx(color, "beam follow"); } -static void R_DrawRing( vec3_t source, vec3_t delta, float width, float amplitude, float freq, float speed, int segments ) +static void R_DrawRing( vec3_t source, vec3_t delta, float width, float amplitude, float freq, float speed, int segments, const vec4_t color ) { int i, j, noiseIndex, noiseStep; float div, length, fraction, factor, vLast, vStep; @@ -798,6 +804,7 @@ static void R_DrawRing( vec3_t source, vec3_t delta, float width, float amplitud j = segments / 8; + TriBegin( TRI_TRIANGLE_STRIP ); for( i = 0; i < segments + 1; i++ ) { fraction = i * div; @@ -851,6 +858,7 @@ static void R_DrawRing( vec3_t source, vec3_t delta, float width, float amplitud FracNoise( rgNoise, NOISE_DIVISIONS ); } } + TriEndEx( color, "beam ring" ); } /* @@ -1114,37 +1122,26 @@ void R_BeamDraw( BEAM *pbeam, float frametime ) { case TE_BEAMTORUS: // FIXME VK GL_Cull( GL_NONE ); - TriBegin( TRI_TRIANGLE_STRIP ); - R_DrawTorus( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments ); - TriEnd(); + R_DrawTorus( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments, color ); break; case TE_BEAMDISK: // FIXME VK GL_Cull( GL_NONE ); - TriBegin( TRI_TRIANGLE_STRIP ); - R_DrawDisk( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments ); - TriEnd(); + R_DrawDisk( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments, color ); break; case TE_BEAMCYLINDER: // FIXME VK GL_Cull( GL_NONE ); - TriBegin( TRI_TRIANGLE_STRIP ); - R_DrawCylinder( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments ); - TriEnd(); + R_DrawCylinder( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments, color ); break; case TE_BEAMPOINTS: case TE_BEAMHOSE: R_DrawSegs( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments, pbeam->flags, color, texturenum, render_mode ); break; case TE_BEAMFOLLOW: - // FIXME VK TriBegin( TRI_QUADS ); - //TriColor4f( color[0], color[1], color[2], color[3] ); - //R_DrawBeamFollow( pbeam, frametime ); - //TriEnd(); + R_DrawBeamFollow( pbeam, frametime, color ); break; case TE_BEAMRING: // FIXME VK GL_Cull( GL_NONE ); - TriBegin( TRI_TRIANGLE_STRIP ); - R_DrawRing( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments ); - TriEnd(); + R_DrawRing( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments, color ); break; } diff --git a/ref/vk/vk_triapi.c b/ref/vk/vk_triapi.c index 7631950b..c511375f 100644 --- a/ref/vk/vk_triapi.c +++ b/ref/vk/vk_triapi.c @@ -94,7 +94,7 @@ static int genTriangleStripIndices(void) { return num_indices; } -static void emitDynamicGeometry(int num_indices) { +static void emitDynamicGeometry(int num_indices, const vec4_t color, const char* name ) { if (!num_indices) return; @@ -110,13 +110,9 @@ static void emitDynamicGeometry(int num_indices) { R_GeometryBufferUnlock( &buffer ); { - // FIXME pass these properly - const vec4_t color = {1, 1, 1, 1}; - const char* name = "FIXME triapi"; - const vk_render_geometry_t geometry = { .texture = g_triapi.texture_index, - .material = kXVkMaterialEmissive, + .material = (g_triapi.render_type == kVkRenderTypeSolid) ? kXVkMaterialRegular : kXVkMaterialEmissive, .max_vertex = g_triapi.num_vertices, .vertex_offset = buffer.vertices.unit_offset, @@ -140,6 +136,18 @@ void TriEnd( void ) { if (!g_triapi.num_vertices) return; + const vk_vertex_t *const v = g_triapi.vertices + g_triapi.num_vertices - 1; + const vec4_t color = {v->color[0] / 255.f, v->color[1] / 255.f, v->color[2] / 255.f, 1.f}; + TriEndEx( color, "unnamed triapi" ); +} + +void TriEndEx( const vec4_t color, const char* name ) { + if (!g_triapi.primitive_mode) + return; + + if (!g_triapi.num_vertices) + return; + int num_indices = 0; switch(g_triapi.primitive_mode - 1) { /* case TRI_TRIANGLES: */ @@ -153,7 +161,7 @@ void TriEnd( void ) { break; } - emitDynamicGeometry(num_indices); + emitDynamicGeometry(num_indices, color, name); g_triapi.num_vertices = 0; g_triapi.primitive_mode = 0; diff --git a/ref/vk/vk_triapi.h b/ref/vk/vk_triapi.h index 860d5e30..953533b3 100644 --- a/ref/vk/vk_triapi.h +++ b/ref/vk/vk_triapi.h @@ -15,3 +15,4 @@ void TriVertex3fv( const float *v ); void TriVertex3f( float x, float y, float z ); void TriEnd( void ); +void TriEndEx( const vec4_t color, const char* name ); From 421c0ea733d4ab13ed443cc5e26aa362208c7354 Mon Sep 17 00:00:00 2001 From: Ivan Avdeev Date: Mon, 27 Feb 2023 10:37:03 -0800 Subject: [PATCH 09/11] vk: add tracers (not tested) --- ref/vk/vk_rmain.c | 49 ++----- ref/vk/vk_rpart.c | 311 +++++++++++++++++++++++++++++++++++++++++++++ ref/vk/vk_rpart.h | 6 + ref/vk/vk_triapi.c | 39 +++++- ref/vk/vk_triapi.h | 3 + 5 files changed, 364 insertions(+), 44 deletions(-) create mode 100644 ref/vk/vk_rpart.c create mode 100644 ref/vk/vk_rpart.h diff --git a/ref/vk/vk_rmain.c b/ref/vk/vk_rmain.c index 4dd7b177..bc746113 100644 --- a/ref/vk/vk_rmain.c +++ b/ref/vk/vk_rmain.c @@ -11,6 +11,8 @@ #include "vk_studio.h" #include "vk_beams.h" #include "vk_brush.h" +#include "vk_rpart.h" +#include "vk_triapi.h" #include "xash3d_types.h" #include "com_strings.h" @@ -174,16 +176,6 @@ static qboolean Mod_ProcessRenderData( model_t *mod, qboolean create, const byte return loaded; } -// efx implementation -static void CL_DrawParticles( double frametime, particle_t *particles, float partsize ) -{ - PRINT_NOT_IMPLEMENTED(); -} -static void CL_DrawTracers( double frametime, particle_t *tracers ) -{ - PRINT_NOT_IMPLEMENTED(); -} - // Xash3D Render Interface // Get renderer info (doesn't changes engine state at all) @@ -309,9 +301,13 @@ static void AVI_UploadRawFrame( int texture, int cols, int rows, int width, int } // glState related calls (must use this instead of normal gl-calls to prevent de-synchornize local states between engine and the client) -static void GL_Bind( int tmu, unsigned int texnum ) +static void GL_Bind( int tmu, unsigned int texnum ) { - PRINT_NOT_IMPLEMENTED(); + if (tmu != 0) { + PRINT_NOT_IMPLEMENTED_ARGS("non-zero tmu=%d", tmu); + } + + TriSetTexture(texnum); } static void GL_SelectTexture( int tmu ) { @@ -386,35 +382,6 @@ static void* R_GetProcAddress( const char *name ) } // TriAPI Interface -// NOTE: implementation isn't required to be compatible -static void TriRenderMode( int mode ) -{ - PRINT_NOT_IMPLEMENTED(); -} -static void TriBegin( int primitiveCode ) -{ - PRINT_NOT_IMPLEMENTED(); -} -static void TriEnd( void ) -{ - PRINT_NOT_IMPLEMENTED(); -} -static void TriColor4f( float r, float g, float b, float a ) -{ - PRINT_NOT_IMPLEMENTED(); -} -static void TriTexCoord2f( float u, float v ) -{ - PRINT_NOT_IMPLEMENTED(); -} -static void TriVertex3fv( const float *worldPnt ) -{ - PRINT_NOT_IMPLEMENTED(); -} -static void TriVertex3f( float x, float y, float z ) -{ - PRINT_NOT_IMPLEMENTED(); -} static void TriFog( float flFogColor[3], float flStart, float flEnd, int bOn ) { PRINT_NOT_IMPLEMENTED(); diff --git a/ref/vk/vk_rpart.c b/ref/vk/vk_rpart.c new file mode 100644 index 00000000..74cb8394 --- /dev/null +++ b/ref/vk/vk_rpart.c @@ -0,0 +1,311 @@ +/* +cl_part.c - particles and tracers +Copyright (C) 2010 Uncle Mike + +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 3 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. +*/ + +#include "vk_rpart.h" +#include "vk_triapi.h" +#include "camera.h" +#include "vk_textures.h" // tglob.particleTexture +#include "vk_common.h" +#include "vk_sprite.h" // R_GetSpriteTexture + +#include "xash3d_types.h" // vec3_t for r_efx.h +#include "const.h" // color24 for r_efx.h +#include "r_efx.h" +#include "event_flags.h" +#include "entity_types.h" +#include "triangleapi.h" +#include "pm_local.h" +#include "studio.h" +#include "client/cl_tent.h" // TriColor4ub +#include "pm_movevars.h" // movevars_t + +static float gTracerSize[11] = { 1.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; +static color24 gTracerColors[] = +{ +{ 255, 255, 255 }, // White +{ 255, 0, 0 }, // Red +{ 0, 255, 0 }, // Green +{ 0, 0, 255 }, // Blue +{ 0, 0, 0 }, // Tracer default, filled in from cvars, etc. +{ 255, 167, 17 }, // Yellow-orange sparks +{ 255, 130, 90 }, // Yellowish streaks (garg) +{ 55, 60, 144 }, // Blue egon streak +{ 255, 130, 90 }, // More Yellowish streaks (garg) +{ 255, 140, 90 }, // More Yellowish streaks (garg) +{ 200, 130, 90 }, // More red streaks (garg) +{ 255, 120, 70 }, // Darker red streaks (garg) +}; + +/* +================ +CL_DrawParticles + +update particle color, position, free expired and draw it +================ +*/ +void CL_DrawParticles( double frametime, particle_t *cl_active_particles, float partsize ) +{ + particle_t *p; + vec3_t right, up; + color24 *pColor; + int alpha; + float size; + + if( !cl_active_particles ) + return; // nothing to draw? + + TriRenderMode( kRenderTransAlpha ); + TriSetTexture( tglob.particleTexture ); + + TriBegin( TRI_QUADS ); + + for( p = cl_active_particles; p; p = p->next ) + { + if(( p->type != pt_blob ) || ( p->packedColor == 255 )) + { + size = partsize; // get initial size of particle + + // scale up to keep particles from disappearing + // FIXME are these really the same? + vec3_t cull_vforward, cull_vup, cull_vright; + VectorCopy(g_camera.vforward, cull_vforward); + VectorCopy(g_camera.vup, cull_vup); + VectorCopy(g_camera.vright, cull_vright); + size += (p->org[0] - g_camera.vieworg[0]) * cull_vforward[0]; + size += (p->org[1] - g_camera.vieworg[1]) * cull_vforward[1]; + size += (p->org[2] - g_camera.vieworg[2]) * cull_vforward[2]; + + if( size < 20.0f ) size = partsize; + else size = partsize + size * 0.002f; + + // scale the axes by radius + VectorScale( cull_vright, size, right ); + VectorScale( cull_vup, size, up ); + + p->color = bound( 0, p->color, 255 ); + pColor = gEngine.CL_GetPaletteColor( p->color ); + + alpha = 255 * (p->die - gpGlobals->time) * 16.0f; + if( alpha > 255 || p->type == pt_static ) + alpha = 255; + + TriColor4ub( gEngine.LightToTexGamma( pColor->r ), + gEngine.LightToTexGamma( pColor->g ), + gEngine.LightToTexGamma( pColor->b ), alpha ); + + TriTexCoord2f( 0.0f, 1.0f ); + TriVertex3f( p->org[0] - right[0] + up[0], p->org[1] - right[1] + up[1], p->org[2] - right[2] + up[2] ); + TriTexCoord2f( 0.0f, 0.0f ); + TriVertex3f( p->org[0] + right[0] + up[0], p->org[1] + right[1] + up[1], p->org[2] + right[2] + up[2] ); + TriTexCoord2f( 1.0f, 0.0f ); + TriVertex3f( p->org[0] + right[0] - up[0], p->org[1] + right[1] - up[1], p->org[2] + right[2] - up[2] ); + TriTexCoord2f( 1.0f, 1.0f ); + TriVertex3f( p->org[0] - right[0] - up[0], p->org[1] - right[1] - up[1], p->org[2] - right[2] - up[2] ); + } + + gEngine.CL_ThinkParticle( frametime, p ); + } + + const vec4_t color = { 1, 1, 1, 1 }; // pColor->r / 255.f, pColor->g / 255.f, pColor->b / 255.f, 1.f }; + TriEndEx( color, "particle"); +} + +/* +================ +CL_CullTracer + +check tracer bbox +================ +*/ +static qboolean CL_CullTracer( particle_t *p, const vec3_t start, const vec3_t end ) +{ + vec3_t mins, maxs; + int i; + + // compute the bounding box + for( i = 0; i < 3; i++ ) + { + if( start[i] < end[i] ) + { + mins[i] = start[i]; + maxs[i] = end[i]; + } + else + { + mins[i] = end[i]; + maxs[i] = start[i]; + } + + // don't let it be zero sized + if( mins[i] == maxs[i] ) + { + maxs[i] += gTracerSize[p->type] * 2.0f; + } + } + + // check bbox + return false; // FIXME VK R_CullBox( mins, maxs ); +} + +/* +================ +CL_DrawTracers + +update tracer color, position, free expired and draw it +================ +*/ +void CL_DrawTracers( double frametime, particle_t *cl_active_tracers ) +{ + float scale, atten, gravity; + vec3_t screenLast, screen; + vec3_t start, end, delta; + particle_t *p; + + /* FIXME VK + // update tracer color if this is changed + if( FBitSet( tracerred->flags|tracergreen->flags|tracerblue->flags|traceralpha->flags, FCVAR_CHANGED )) + { + color24 *customColors = &gTracerColors[4]; + customColors->r = (byte)(tracerred->value * traceralpha->value * 255); + customColors->g = (byte)(tracergreen->value * traceralpha->value * 255); + customColors->b = (byte)(tracerblue->value * traceralpha->value * 255); + ClearBits( tracerred->flags, FCVAR_CHANGED ); + ClearBits( tracergreen->flags, FCVAR_CHANGED ); + ClearBits( tracerblue->flags, FCVAR_CHANGED ); + ClearBits( traceralpha->flags, FCVAR_CHANGED ); + } + */ + + if( !cl_active_tracers ) + return; // nothing to draw? + + if( !TriSpriteTexture( gEngine.GetDefaultSprite( REF_DOT_SPRITE ), 0 )) + return; + + TriRenderMode( kRenderTransAdd ); + +#define MOVEVARS (gEngine.pfnGetMoveVars()) + gravity = frametime * MOVEVARS->gravity; + scale = 1.0 - (frametime * 0.9); + if( scale < 0.0f ) scale = 0.0f; + + for( p = cl_active_tracers; p; p = p->next ) + { + atten = (p->die - gpGlobals->time); + if( atten > 0.1f ) atten = 0.1f; + + VectorScale( p->vel, ( p->ramp * atten ), delta ); + VectorAdd( p->org, delta, end ); + VectorCopy( p->org, start ); + + if( !CL_CullTracer( p, start, end )) + { + vec3_t verts[4], tmp2; + vec3_t tmp, normal; + color24 *pColor; + + // Transform point into screen space + TriWorldToScreen( start, screen ); + TriWorldToScreen( end, screenLast ); + + // build world-space normal to screen-space direction vector + VectorSubtract( screen, screenLast, tmp ); + + // we don't need Z, we're in screen space + tmp[2] = 0; + VectorNormalize( tmp ); + + vec3_t cull_vforward, cull_vup, cull_vright; + VectorCopy(g_camera.vforward, cull_vforward); + VectorCopy(g_camera.vup, cull_vup); + VectorCopy(g_camera.vright, cull_vright); + + // build point along noraml line (normal is -y, x) + VectorScale( cull_vup, tmp[0] * gTracerSize[p->type], normal ); + VectorScale( cull_vright, -tmp[1] * gTracerSize[p->type], tmp2 ); + VectorSubtract( normal, tmp2, normal ); + + // compute four vertexes + VectorSubtract( start, normal, verts[0] ); + VectorAdd( start, normal, verts[1] ); + VectorAdd( verts[0], delta, verts[2] ); + VectorAdd( verts[1], delta, verts[3] ); + + if( p->color > sizeof( gTracerColors ) / sizeof( color24 ) ) + { + gEngine.Con_Printf( S_ERROR "UserTracer with color > %d\n", (int)(sizeof( gTracerColors ) / sizeof( color24 ))); + p->color = 0; + } + + pColor = &gTracerColors[p->color]; + TriColor4ub( pColor->r, pColor->g, pColor->b, p->packedColor ); + + TriBegin( TRI_QUADS ); + TriTexCoord2f( 0.0f, 0.8f ); + TriVertex3fv( verts[2] ); + TriTexCoord2f( 1.0f, 0.8f ); + TriVertex3fv( verts[3] ); + TriTexCoord2f( 1.0f, 0.0f ); + TriVertex3fv( verts[1] ); + TriTexCoord2f( 0.0f, 0.0f ); + TriVertex3fv( verts[0] ); + const vec4_t color = { 1, 1, 1, 1 }; //pColor->r / 255.f, pColor->g / 255.f, pColor->b / 255.f, p->packedColor / 255.f }; + TriEndEx( color, "tracer" ); + } + + // evaluate position + VectorMA( p->org, frametime, p->vel, p->org ); + + if( p->type == pt_grav ) + { + p->vel[0] *= scale; + p->vel[1] *= scale; + p->vel[2] -= gravity; + + p->packedColor = 255 * (p->die - gpGlobals->time) * 2; + if( p->packedColor > 255 ) p->packedColor = 255; + } + else if( p->type == pt_slowgrav ) + { + p->vel[2] = gravity * 0.05f; + } + } +} + +/* +=============== +CL_DrawParticlesExternal + +allow to draw effects from custom renderer +=============== +*/ + +/* FIXME VK +void CL_DrawParticlesExternal( const ref_viewpass_t *rvp, qboolean trans_pass, float frametime ) +{ + ref_instance_t oldRI = RI; + + memcpy( &oldRI, &RI, sizeof( ref_instance_t )); + R_SetupRefParams( rvp ); + R_SetupFrustum(); + R_SetuTri( false ); // don't touch GL-states + tr.frametime = frametime; + + gEngfuncs.CL_DrawEFX( frametime, trans_pass ); + + // restore internal state + memcpy( &RI, &oldRI, sizeof( ref_instance_t )); +} +*/ diff --git a/ref/vk/vk_rpart.h b/ref/vk/vk_rpart.h new file mode 100644 index 00000000..a325de3f --- /dev/null +++ b/ref/vk/vk_rpart.h @@ -0,0 +1,6 @@ +#pragma once + +typedef struct particle_s particle_t; + +void CL_DrawParticles( double frametime, particle_t *particles, float partsize ); +void CL_DrawTracers( double frametime, particle_t *tracers ); diff --git a/ref/vk/vk_triapi.c b/ref/vk/vk_triapi.c index c511375f..1d2cfc05 100644 --- a/ref/vk/vk_triapi.c +++ b/ref/vk/vk_triapi.c @@ -1,6 +1,7 @@ #include "vk_triapi.h" #include "vk_geometry.h" #include "vk_render.h" +#include "vk_sprite.h" // R_GetSpriteTexture #include "vk_textures.h" // FIXME temp @@ -26,6 +27,18 @@ void TriSetTexture( int texture_index ) { g_triapi.texture_index = texture_index; } +int TriSpriteTexture( model_t *pSpriteModel, int frame ) +{ + int gl_texturenum; + + if(( gl_texturenum = R_GetSpriteTexture( pSpriteModel, frame )) <= 0 ) + return 0; + + TriSetTexture( gl_texturenum ); + + return 1; +} + void TriRenderMode( int render_mode ) { switch( render_mode ) { @@ -45,6 +58,7 @@ void TriBegin( int primitive_mode ) { switch(primitive_mode) { case TRI_TRIANGLES: break; case TRI_TRIANGLE_STRIP: break; + case TRI_QUADS: break; default: gEngine.Con_Printf(S_ERROR "TriBegin: unsupported primitive_mode %d\n", primitive_mode); return; @@ -67,6 +81,26 @@ void TriBegin( int primitive_mode ) { /* return 0; */ /* } */ +static int genQuadsIndices(void) { + int num_indices = 0; + uint16_t *const dst_idx = g_triapi.indices; + for (int i = 3; i < g_triapi.num_vertices; i+=4) { + if (num_indices > MAX_TRIAPI_INDICES - 6) { + gEngine.Con_Printf(S_ERROR "Triapi ran out of indices space, max %d (vertices=%d)\n", MAX_TRIAPI_INDICES, g_triapi.num_vertices); + break; + } + + dst_idx[num_indices++] = 0 + i; + dst_idx[num_indices++] = 1 + i; + dst_idx[num_indices++] = 2 + i; + + dst_idx[num_indices++] = 0 + i; + dst_idx[num_indices++] = 2 + i; + dst_idx[num_indices++] = 3 + i; + } + return num_indices; +} + static int genTriangleStripIndices(void) { int num_indices = 0; uint16_t *const dst_idx = g_triapi.indices; @@ -153,9 +187,8 @@ void TriEndEx( const vec4_t color, const char* name ) { /* case TRI_TRIANGLES: */ /* num_indices = genTrianglesIndices(); */ /* break; */ - case TRI_TRIANGLE_STRIP: - num_indices = genTriangleStripIndices(); - break; + case TRI_TRIANGLE_STRIP: num_indices = genTriangleStripIndices(); break; + case TRI_QUADS: num_indices = genQuadsIndices(); break; default: gEngine.Con_Printf(S_ERROR "TriEnd: unsupported primitive_mode %d\n", g_triapi.primitive_mode - 1); break; diff --git a/ref/vk/vk_triapi.h b/ref/vk/vk_triapi.h index 953533b3..4825cb02 100644 --- a/ref/vk/vk_triapi.h +++ b/ref/vk/vk_triapi.h @@ -2,8 +2,11 @@ #include "xash3d_types.h" +typedef struct model_s model_t; + void TriRenderMode( int mode ); void TriSetTexture( int texture_index ); +int TriSpriteTexture( model_t *pSpriteModel, int frame ); void TriBegin( int mode ); From d87690876f7322b50b02213791fc86fa8df73e57 Mon Sep 17 00:00:00 2001 From: Ivan 'provod' Avdeev Date: Mon, 27 Feb 2023 10:51:11 -0800 Subject: [PATCH 10/11] vk: fix TRI_QUADS and primitive_mode tracking --- ref/vk/vk_triapi.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/ref/vk/vk_triapi.c b/ref/vk/vk_triapi.c index 1d2cfc05..79b44c2b 100644 --- a/ref/vk/vk_triapi.c +++ b/ref/vk/vk_triapi.c @@ -84,7 +84,7 @@ void TriBegin( int primitive_mode ) { static int genQuadsIndices(void) { int num_indices = 0; uint16_t *const dst_idx = g_triapi.indices; - for (int i = 3; i < g_triapi.num_vertices; i+=4) { + for (int i = 0; i < g_triapi.num_vertices - 3; i+=4) { if (num_indices > MAX_TRIAPI_INDICES - 6) { gEngine.Con_Printf(S_ERROR "Triapi ran out of indices space, max %d (vertices=%d)\n", MAX_TRIAPI_INDICES, g_triapi.num_vertices); break; @@ -167,9 +167,6 @@ void TriEnd( void ) { if (!g_triapi.primitive_mode) return; - if (!g_triapi.num_vertices) - return; - const vk_vertex_t *const v = g_triapi.vertices + g_triapi.num_vertices - 1; const vec4_t color = {v->color[0] / 255.f, v->color[1] / 255.f, v->color[2] / 255.f, 1.f}; TriEndEx( color, "unnamed triapi" ); @@ -179,9 +176,6 @@ void TriEndEx( const vec4_t color, const char* name ) { if (!g_triapi.primitive_mode) return; - if (!g_triapi.num_vertices) - return; - int num_indices = 0; switch(g_triapi.primitive_mode - 1) { /* case TRI_TRIANGLES: */ From c8e4ce0619d72aec26b7341a795bb9d5c57e62f3 Mon Sep 17 00:00:00 2001 From: Ivan 'provod' Avdeev Date: Mon, 27 Feb 2023 11:00:34 -0800 Subject: [PATCH 11/11] vk: fix tracers colors --- ref/vk/vk_rpart.c | 5 ++--- ref/vk/vk_triapi.h | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ref/vk/vk_rpart.c b/ref/vk/vk_rpart.c index 74cb8394..aa892fd5 100644 --- a/ref/vk/vk_rpart.c +++ b/ref/vk/vk_rpart.c @@ -28,7 +28,6 @@ GNU General Public License for more details. #include "triangleapi.h" #include "pm_local.h" #include "studio.h" -#include "client/cl_tent.h" // TriColor4ub #include "pm_movevars.h" // movevars_t static float gTracerSize[11] = { 1.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; @@ -101,7 +100,7 @@ void CL_DrawParticles( double frametime, particle_t *cl_active_particles, float if( alpha > 255 || p->type == pt_static ) alpha = 255; - TriColor4ub( gEngine.LightToTexGamma( pColor->r ), + TriColor4ub_( gEngine.LightToTexGamma( pColor->r ), gEngine.LightToTexGamma( pColor->g ), gEngine.LightToTexGamma( pColor->b ), alpha ); @@ -250,7 +249,7 @@ void CL_DrawTracers( double frametime, particle_t *cl_active_tracers ) } pColor = &gTracerColors[p->color]; - TriColor4ub( pColor->r, pColor->g, pColor->b, p->packedColor ); + TriColor4ub_( pColor->r, pColor->g, pColor->b, p->packedColor ); TriBegin( TRI_QUADS ); TriTexCoord2f( 0.0f, 0.8f ); diff --git a/ref/vk/vk_triapi.h b/ref/vk/vk_triapi.h index 4825cb02..a1a38a34 100644 --- a/ref/vk/vk_triapi.h +++ b/ref/vk/vk_triapi.h @@ -12,6 +12,7 @@ void TriBegin( int mode ); void TriTexCoord2f( float u, float v ); void TriColor4f( float r, float g, float b, float a ); +void TriColor4ub_( byte r, byte g, byte b, byte a ); // FIXME consolidate with vk_renderstate // Emits next vertex void TriVertex3fv( const float *v );