vk: add more beam types, tracers, triapi

- [x] fixes #293 
- [x] fixes #162 
- [x] add tracers, fix #263 
- [x] add basic triapi
This commit is contained in:
Ivan Avdeev 2023-02-27 11:17:28 -08:00 committed by GitHub
commit 19603722ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 689 additions and 154 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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.);
}

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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"
@ -145,13 +146,20 @@ 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;
// 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 )
@ -298,8 +306,7 @@ 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 );
applyBrightness( brightness, dst_vtx->color );
VectorCopy( vPoint1, dst_vtx->pos );
VectorCopy( vAveNormal, dst_vtx->normal );
++dst_vtx;
@ -307,9 +314,9 @@ 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 );
applyBrightness( brightness, dst_vtx->color );
VectorCopy( vPoint2, dst_vtx->pos );
VectorCopy( vAveNormal, dst_vtx->normal );
++dst_vtx;
}
@ -339,17 +346,17 @@ 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 );
applyBrightness( brightness, 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 );
applyBrightness( brightness, dst_vtx->color );
VectorCopy( vPoint2, dst_vtx->pos );
VectorCopy( vLastNormal, dst_vtx->normal );
++dst_vtx;
}
@ -397,11 +404,8 @@ 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 )
{
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;
@ -427,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;
@ -480,14 +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;
@ -511,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++ )
{
@ -534,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;
@ -563,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;
@ -588,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;
@ -680,6 +682,7 @@ static void R_DrawBeamFollow( BEAM *pbeam, float frametime )
vLast = 0.0f;
vStep = 1.0f;
TriBegin( TRI_QUADS );
while( particles )
{
TriBrightness( fraction );
@ -735,14 +738,12 @@ 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 )
{
PRINT_NOT_IMPLEMENTED();
/* FIXME VK
int i, j, noiseIndex, noiseStep;
float div, length, fraction, factor, vLast, vStep;
vec3_t last1, last2, point, screen, screenLast;
@ -786,6 +787,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;
@ -794,6 +796,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 );
@ -801,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;
@ -854,7 +858,7 @@ static void R_DrawRing( vec3_t source, vec3_t delta, float width, float amplitud
FracNoise( rgNoise, NOISE_DIVISIONS );
}
}
*/
TriEndEx( color, "beam ring" );
}
/*
@ -1110,31 +1114,34 @@ 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 );
R_DrawTorus( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments );
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 );
R_DrawDisk( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments );
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 );
R_DrawCylinder( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments );
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 );
R_DrawBeamFollow( pbeam, frametime );
R_DrawBeamFollow( pbeam, frametime, color );
break;
case TE_BEAMRING:
// FIXME VK GL_Cull( GL_NONE );
R_DrawRing( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments );
R_DrawRing( pbeam->source, pbeam->delta, pbeam->width, pbeam->amplitude, pbeam->freq, pbeam->speed, pbeam->segments, color );
break;
}

View File

@ -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)

View File

@ -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 {

View File

@ -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)},
};

View File

@ -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();

310
ref/vk/vk_rpart.c Normal file
View File

@ -0,0 +1,310 @@
/*
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 "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 ));
}
*/

6
ref/vk/vk_rpart.h Normal file
View File

@ -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 );

View File

@ -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);

View File

@ -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) {

233
ref/vk/vk_triapi.c Normal file
View File

@ -0,0 +1,233 @@
#include "vk_triapi.h"
#include "vk_geometry.h"
#include "vk_render.h"
#include "vk_sprite.h" // R_GetSpriteTexture
#include "vk_textures.h" // FIXME temp
#include "xash3d_mathlib.h"
#define MAX_TRIAPI_VERTICES 1024
#define MAX_TRIAPI_INDICES 4096
static struct {
vk_vertex_t vertices[MAX_TRIAPI_VERTICES];
uint16_t indices[MAX_TRIAPI_INDICES];
int num_vertices;
int primitive_mode;
int texture_index;
vk_render_type_e render_type;
qboolean initialized;
} g_triapi = {0};
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 )
{
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;
case TRI_QUADS: break;
default:
gEngine.Con_Printf(S_ERROR "TriBegin: unsupported primitive_mode %d\n", primitive_mode);
return;
}
vk_vertex_t *const ve = g_triapi.vertices + 0;
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) { */
/* return 0; */
/* } */
static int genQuadsIndices(void) {
int num_indices = 0;
uint16_t *const dst_idx = g_triapi.indices;
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;
}
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;
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]
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, const vec4_t color, const char* name ) {
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 );
{
const vk_render_geometry_t geometry = {
.texture = g_triapi.texture_index,
.material = (g_triapi.render_type == kVkRenderTypeSolid) ? kXVkMaterialRegular : 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( g_triapi.render_type, color, name );
VK_RenderModelDynamicAddGeometry( &geometry );
VK_RenderModelDynamicCommit();
}
}
void TriEnd( void ) {
if (!g_triapi.primitive_mode)
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;
int num_indices = 0;
switch(g_triapi.primitive_mode - 1) {
/* case TRI_TRIANGLES: */
/* num_indices = genTrianglesIndices(); */
/* 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;
}
emitDynamicGeometry(num_indices, color, name);
g_triapi.num_vertices = 0;
g_triapi.primitive_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));
}

22
ref/vk/vk_triapi.h Normal file
View File

@ -0,0 +1,22 @@
#pragma once
#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 );
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 );
void TriVertex3f( float x, float y, float z );
void TriEnd( void );
void TriEndEx( const vec4_t color, const char* name );