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,