From d6b678ac78785f8df92fabee0dbf3993e5c77769 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 2 Feb 2021 19:53:36 +0900 Subject: [PATCH] [vulkan] Implement team colors It's not quite as expected, but that may be due to one of msaa, the 0-15 range in the palette not being all the way to white, the color gradients being not quite linear (haven't checked yet) or some combination of the above. However, it's that what should be yellow is more green. At least the zombies are no longer white and the ogres don't look like they're wearing skeleton suits. --- include/QF/Vulkan/qf_alias.h | 8 +++++ libs/models/alias/vulkan_model_alias.c | 10 +++--- libs/video/renderer/vulkan/alias.frag | 11 ++++--- libs/video/renderer/vulkan/qfpipeline.plist | 4 +-- libs/video/renderer/vulkan/vulkan_alias.c | 34 +++++++++------------ 5 files changed, 36 insertions(+), 31 deletions(-) diff --git a/include/QF/Vulkan/qf_alias.h b/include/QF/Vulkan/qf_alias.h index 6f96e0fa0..714cb06b3 100644 --- a/include/QF/Vulkan/qf_alias.h +++ b/include/QF/Vulkan/qf_alias.h @@ -53,6 +53,14 @@ typedef struct qfv_alias_mesh_s { VkDeviceMemory memory; } qfv_alias_mesh_t; +typedef struct qfv_alias_skin_s { + VkDeviceMemory memory; + VkImage image; + VkImageView view; + byte colora[4]; + byte colorb[4]; +} qfv_alias_skin_t; + typedef struct qfv_light_s { vec3_t color; float dist; diff --git a/libs/models/alias/vulkan_model_alias.c b/libs/models/alias/vulkan_model_alias.c index 5b3ce995c..fd1f8c731 100644 --- a/libs/models/alias/vulkan_model_alias.c +++ b/libs/models/alias/vulkan_model_alias.c @@ -67,7 +67,7 @@ skin_clear (int skin_offset, aliashdr_t *hdr, vulkan_ctx_t *ctx) { qfv_device_t *device = ctx->device; qfv_devfuncs_t *dfunc = device->funcs; - qfv_tex_t *skin = (qfv_tex_t *) ((byte *) hdr + skin_offset); + qfv_alias_skin_t *skin = (qfv_alias_skin_t *) ((byte *) hdr + skin_offset); dfunc->vkDestroyImageView (device->dev, skin->view, 0); dfunc->vkDestroyImage (device->dev, skin->image, 0); @@ -115,11 +115,13 @@ Vulkan_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skinpix, int skinsize, qfv_device_t *device = ctx->device; qfv_devfuncs_t *dfunc = device->funcs; aliashdr_t *header = alias_ctx->header; - qfv_tex_t *skin; + qfv_alias_skin_t *skin; byte *tskin; int w, h; - skin = Hunk_Alloc (sizeof (qfv_tex_t)); + skin = Hunk_Alloc (sizeof (qfv_alias_skin_t)); + QuatCopy (vid.palette32 + (TOP_RANGE + 15) * 4, skin->colora); + QuatCopy (vid.palette32 + (BOTTOM_RANGE + 15) * 4, skin->colorb); skindesc->skin = (byte *) skin - (byte *) header; //FIXME move all skins into arrays(?) w = header->mdl.skinwidth; @@ -130,7 +132,6 @@ Vulkan_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skinpix, int skinsize, int mipLevels = QFV_MipLevels (w, h); VkExtent3D extent = { w, h, 1 }; - skin->offset = 0; skin->image = QFV_CreateImage (device, 0, VK_IMAGE_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM, extent, mipLevels, 4, VK_SAMPLE_COUNT_1_BIT, @@ -212,7 +213,6 @@ Vulkan_Mod_LoadSkin (mod_alias_ctx_t *alias_ctx, byte *skinpix, int skinsize, dfunc->vkCmdPipelineBarrier (packet->cmd, stages.src, stages.dst, 0, 0, 0, 0, 0, 1, &barrier); - } else { QFV_GenerateMipMaps (device, packet->cmd, skin->image, mipLevels, w, h, 4); diff --git a/libs/video/renderer/vulkan/alias.frag b/libs/video/renderer/vulkan/alias.frag index bff1b87dd..3b5c9fddd 100644 --- a/libs/video/renderer/vulkan/alias.frag +++ b/libs/video/renderer/vulkan/alias.frag @@ -23,7 +23,10 @@ layout (set = 0, binding = 1) uniform Lights { }; layout (push_constant) uniform PushConstants { - layout (offset = 80) + layout (offset = 68) + uint base_color; + uint colorA; + uint colorB; vec4 fog; vec4 color; }; @@ -56,9 +59,9 @@ main (void) vec4 c; int i; vec3 light = vec3 (0); - c = texture (Skin, vec3 (st, 0)); - c += texture (Skin, vec3 (st, 1)); - c += texture (Skin, vec3 (st, 2)); + c = texture (Skin, vec3 (st, 0)) * unpackUnorm4x8(base_color); + c += texture (Skin, vec3 (st, 1)) * unpackUnorm4x8(colorA); + c += texture (Skin, vec3 (st, 2)) * unpackUnorm4x8(colorB); if (MaxLights > 0) { for (i = 0; i < light_count; i++) { diff --git a/libs/video/renderer/vulkan/qfpipeline.plist b/libs/video/renderer/vulkan/qfpipeline.plist index 5d44ec6ff..33bc11b27 100644 --- a/libs/video/renderer/vulkan/qfpipeline.plist +++ b/libs/video/renderer/vulkan/qfpipeline.plist @@ -271,8 +271,8 @@ }, { stageFlags = fragment; - offset = 80; - size = "2 * 4 * 4"; + offset = 68; + size = "3 * 4 + 2 * 4 * 4"; }, ); }; diff --git a/libs/video/renderer/vulkan/vulkan_alias.c b/libs/video/renderer/vulkan/vulkan_alias.c index d7f933cb9..76f4ac7b5 100644 --- a/libs/video/renderer/vulkan/vulkan_alias.c +++ b/libs/video/renderer/vulkan/vulkan_alias.c @@ -65,18 +65,6 @@ #include "vid_vulkan.h" #include "vkparse.h" -static VkImageView -get_view (qfv_tex_t *tex, qfv_tex_t *default_tex) -{ - if (tex) { - return tex->view; - } - if (default_tex) { - return default_tex->view; - } - return 0; -} - void Vulkan_DrawAlias (entity_t *ent, struct vulkan_ctx_s *ctx) { @@ -87,23 +75,28 @@ Vulkan_DrawAlias (entity_t *ent, struct vulkan_ctx_s *ctx) model_t *model = ent->model; aliashdr_t *hdr; qfv_alias_mesh_t *mesh; - float blend; - qfv_tex_t *skin; + qfv_alias_skin_t *skin; + float vertex_constants[17]; + byte fragment_constants[3][4]; if (!(hdr = model->aliashdr)) { hdr = Cache_Get (&model->cache); } mesh = (qfv_alias_mesh_t *) ((byte *) hdr + hdr->commands); - blend = R_AliasGetLerpedFrames (ent, hdr); + memcpy (vertex_constants, ent->transform, sizeof (ent->transform)); + vertex_constants[16] = R_AliasGetLerpedFrames (ent, hdr); if (0/*XXX ent->skin && ent->skin->tex*/) { //skin = ent->skin->tex; } else { maliasskindesc_t *skindesc; skindesc = R_AliasGetSkindesc (ent->skinnum, hdr); - skin = (qfv_tex_t *) ((byte *) hdr + skindesc->skin); + skin = (qfv_alias_skin_t *) ((byte *) hdr + skindesc->skin); } + QuatScale (ent->colormod, 255, fragment_constants[0]); + QuatCopy (skin->colora, fragment_constants[1]); + QuatCopy (skin->colorb, fragment_constants[2]); VkDeviceSize offsets[] = { ent->pose1 * hdr->poseverts * sizeof (aliasvrt_t), @@ -120,11 +113,12 @@ Vulkan_DrawAlias (entity_t *ent, struct vulkan_ctx_s *ctx) VK_INDEX_TYPE_UINT32); dfunc->vkCmdPushConstants (aframe->cmd, actx->layout, VK_SHADER_STAGE_VERTEX_BIT, - 0, 16 * sizeof (float), ent->transform); + 0, sizeof (vertex_constants), vertex_constants); dfunc->vkCmdPushConstants (aframe->cmd, actx->layout, - VK_SHADER_STAGE_VERTEX_BIT, - 64, sizeof (float), &blend); - aframe->imageInfo[0].imageView = get_view (skin, 0); + VK_SHADER_STAGE_FRAGMENT_BIT, + 68, sizeof (fragment_constants), + fragment_constants); + aframe->imageInfo[0].imageView = skin->view; dfunc->vkCmdPushDescriptorSetKHR (aframe->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, actx->layout,