renders: use three bytes for save model normal

This commit is contained in:
Denis Pauk 2024-06-04 23:44:59 +03:00
parent 88bb466f1e
commit ec8b792a4b
11 changed files with 85 additions and 95 deletions

View file

@ -119,7 +119,7 @@ Goals:
* [ ] Use separete texture hi-color buffer for ui in soft render,
* [ ] Cleanup function declarations in game save code,
* [ ] Fix broken base3 with sorted fields names,
* [ ] Use 3 bytes vertex normal,
* [x] Use 3 bytes vertex normal,
* [ ] Support scalled textures for models and walls in soft render and fix
lighting with remastered maps,
* [ ] Modified ReRelease game code support with removed KEX only related code.

View file

@ -77,33 +77,18 @@ R_VertBufferFree(void)
}
/* compressed vertex normals used by mdl and md2 model formats */
byte
R_CompressNormalMDL(const float *normal)
void
R_ConvertNormalMDL(byte in_normal, signed char *normal)
{
byte i, besti;
float bestdot;
const float *norm;
int n;
bestdot = normal[0] * r_avertexnormals[0][0] +
normal[1] * r_avertexnormals[0][1] +
normal[2] * r_avertexnormals[0][2];
besti = 0;
norm = r_avertexnormals[in_normal];
for (i = 1; i < NUMVERTEXNORMALS; i++)
for (n = 0; n < 3; n ++)
{
float dot;
dot = normal[0] * r_avertexnormals[i][0] +
normal[1] * r_avertexnormals[i][1] +
normal[2] * r_avertexnormals[i][2];
if (dot > bestdot)
{
bestdot = dot;
besti = i;
}
normal[n] = norm[n] * 127.f;
}
return besti;
}
void
@ -118,14 +103,17 @@ R_LerpVerts(qboolean powerUpEffect, int nverts,
{
for (i = 0; i < nverts; i++, v++, ov++, lerp += 4)
{
const float *normal = r_avertexnormals[v->lightnormalindex];
int n;
lerp[0] = move[0] + ov->v[0] * backv[0] + v->v[0] * frontv[0] +
normal[0] * POWERSUIT_SCALE;
lerp[1] = move[1] + ov->v[1] * backv[1] + v->v[1] * frontv[1] +
normal[1] * POWERSUIT_SCALE;
lerp[2] = move[2] + ov->v[2] * backv[2] + v->v[2] * frontv[2] +
normal[2] * POWERSUIT_SCALE;
for (n = 0; n < 3; n ++)
{
float normal;
normal = v->normal[n] / 127.f;
lerp[n] = move[n] + ov->v[n] * backv[n] + v->v[n] * frontv[n] +
normal * POWERSUIT_SCALE;
}
}
}
else

View file

@ -156,7 +156,8 @@ Mod_LoadFrames_MD2(dmdx_t *pheader, byte *src, size_t inframesize, vec3_t transl
for (j=0; j < pheader->num_xyz; j ++)
{
Mod_LoadFrames_VertMD2(poutframe->verts + j, pinframe->verts[j].v);
poutframe->verts[j].lightnormalindex = pinframe->verts[j].lightnormalindex;
R_ConvertNormalMDL(pinframe->verts[j].lightnormalindex,
poutframe->verts[j].normal);
}
}
}
@ -200,11 +201,13 @@ Mod_LoadFrames_SAM(dmdx_t *pheader, sin_sam_header_t **anims, int anim_num,
}
verts = (dtrivertx_t*)((char *)(pinframe + k) + pinframe[k].ofs_verts);
/* verts are all 8 bit, so no swapping needed */
for (j=0; j < pheader->num_xyz; j ++)
{
Mod_LoadFrames_VertMD2(poutframe->verts + j, verts[j].v);
poutframe->verts[j].lightnormalindex = verts[j].lightnormalindex;
R_ConvertNormalMDL(verts[j].lightnormalindex,
poutframe->verts[j].normal);
}
curr_frame ++;
@ -261,7 +264,8 @@ Mod_LoadFrames_MD2Anox(dmdx_t *pheader, byte *src, size_t inframesize,
/* 3 bytes vert + 2 bytes */
inverts += 5;
/* norm convert logic is unknown */
poutframe->verts[j].lightnormalindex = 0;
memset(poutframe->verts[j].normal, 0,
sizeof(poutframe->verts[j].normal));
}
break;
@ -287,7 +291,8 @@ Mod_LoadFrames_MD2Anox(dmdx_t *pheader, byte *src, size_t inframesize,
poutframe->verts[j].v[2] = tmp;
/* norm convert logic is unknown */
poutframe->verts[j].lightnormalindex = 0;
memset(poutframe->verts[j].normal, 0,
sizeof(poutframe->verts[j].normal));
}
break;
@ -299,7 +304,8 @@ Mod_LoadFrames_MD2Anox(dmdx_t *pheader, byte *src, size_t inframesize,
/* 6 bytes vert + 2 bytes */
inverts += 8;
/* norm convert logic is unknown */
poutframe->verts[j].lightnormalindex = 0;
memset(poutframe->verts[j].normal, 0,
sizeof(poutframe->verts[j].normal));
}
break;
@ -532,7 +538,7 @@ Mod_LoadFrames_DKM2(dmdx_t *pheader, const byte *src, size_t inframesize, vec3_t
Mod_LoadFrames_VertDKM2(outverts + j, *((int *)inverts));
inverts += sizeof(int);
/* norm convert logic is unknown */
outverts[j].lightnormalindex = 0;
memset(outverts[j].normal, 0, sizeof(outverts[j].normal));
inverts ++;
}
}
@ -606,12 +612,16 @@ Mod_LoadFixNormals(dmdx_t *pheader)
/* save normals */
for(t = 0; t < pheader->num_xyz; t++)
{
int j;
VectorNormalize(normals[t]);
/* FIXME: QSS does not have such invert */
VectorInverse(normals[t]);
poutframe->verts[t].lightnormalindex =
R_CompressNormalMDL(normals[t]);
for (j = 0; j < 3; j ++)
{
poutframe->verts[t].normal[j] = normals[t][j] * 127;
}
}
}
free(normals);
@ -1031,8 +1041,10 @@ Mod_LoadModel_MDL(const char *mod_name, const void *buffer, int modfilelen,
for (j=0; j < num_xyz; j ++)
{
Mod_LoadFrames_VertMD2(poutvertx + j, pinvertx[j].v);
poutvertx[j].lightnormalindex = pinvertx[j].lightnormalindex;
R_ConvertNormalMDL(pinvertx[j].lightnormalindex,
poutvertx[j].normal);
}
curr_pos += sizeof(dtrivertx_t) * num_xyz;
frame_count++;
}

View file

@ -1135,10 +1135,9 @@ PrepareFrameVertex(dmdx_vert_t *vertexArray, int num_verts, daliasxframe_t *fram
frame_out->verts[i].v[j] = (
vertexArray[i].xyz[j] - frame_out->translate[j]
) / frame_out->scale[j];
}
frame_out->verts[i].lightnormalindex =
R_CompressNormalMDL(vertexArray[i].norm);
frame_out->verts[i].normal[j] = vertexArray[i].norm[j] * 127.f;
}
}
}

View file

@ -26,12 +26,6 @@
#include "header/local.h"
#define NUMVERTEXNORMALS 162
static const float r_avertexnormals[NUMVERTEXNORMALS][3] = {
#include "../constants/anorms.h"
};
static void
R_DrawAliasDrawCommands(const entity_t *currententity, int *order, const int *order_end,
float alpha, dxtrivertx_t *verts, vec4_t *s_lerped, const float *shadelight,
@ -123,8 +117,8 @@ R_DrawAliasDrawCommands(const entity_t *currententity, int *order, const int *or
do
{
int index_xyz;
const float *norm;
int i, index_xyz;
vec3_t normal;
float l;
/* texture coordinates come from the draw list */
@ -134,10 +128,15 @@ R_DrawAliasDrawCommands(const entity_t *currententity, int *order, const int *or
index_xyz = order[2];
order += 3;
/* unpack normal */
for(i = 0; i < 3; i++)
{
normal[i] = verts[index_xyz].normal[i] / 127.f;
}
/* normals and vertexes come from the frame list */
/* shadevector is set above according to rotation (around Z axis I think) */
norm = r_avertexnormals[verts[index_xyz].lightnormalindex];
l = DotProduct(norm, shadevector) + 1;
l = DotProduct(normal, shadevector) + 1;
clr[index_clr++] = l * shadelight[0];
clr[index_clr++] = l * shadelight[1];

View file

@ -29,12 +29,6 @@
#include "../files/DG_dynarr.h"
#define NUMVERTEXNORMALS 162
static const float r_avertexnormals[NUMVERTEXNORMALS][3] = {
#include "../constants/anorms.h"
};
typedef struct gl3_shadowinfo_s {
vec3_t lightspot;
vec3_t shadevector;
@ -130,9 +124,8 @@ DrawAliasFrameLerpCommands(dmdx_t *paliashdr, entity_t* entity, vec3_t shadeligh
for(i=0; i<count; ++i)
{
gl3_alias_vtx_t* cur = &buf[i];
const float *norm;
int index_xyz;
int j = 0;
int index_xyz, i, j = 0;
vec3_t normal;
float l;
/* texture coordinates come from the draw list */
@ -143,10 +136,15 @@ DrawAliasFrameLerpCommands(dmdx_t *paliashdr, entity_t* entity, vec3_t shadeligh
order += 3;
/* unpack normal */
for(i = 0; i < 3; i++)
{
normal[i] = verts[index_xyz].normal[i] / 127.f;
}
/* normals and vertexes come from the frame list */
/* shadevector is set above according to rotation (around Z axis I think) */
norm = r_avertexnormals[verts[index_xyz].lightnormalindex];
l = DotProduct(norm, shadevector) + 1;
l = DotProduct(normal, shadevector) + 1;
for(j=0; j<3; ++j)
{

View file

@ -29,12 +29,6 @@
#include "../files/DG_dynarr.h"
#define NUMVERTEXNORMALS 162
static const float r_avertexnormals[NUMVERTEXNORMALS][3] = {
#include "../constants/anorms.h"
};
typedef struct gl4_shadowinfo_s {
vec3_t lightspot;
vec3_t shadevector;
@ -130,9 +124,8 @@ DrawAliasFrameLerpCommands(dmdx_t *paliashdr, entity_t* entity, vec3_t shadeligh
for(i=0; i<count; ++i)
{
gl4_alias_vtx_t* cur = &buf[i];
const float *norm;
int index_xyz;
int j = 0;
int index_xyz, i, j = 0;
vec3_t normal;
float l;
/* texture coordinates come from the draw list */
@ -143,10 +136,15 @@ DrawAliasFrameLerpCommands(dmdx_t *paliashdr, entity_t* entity, vec3_t shadeligh
order += 3;
/* unpack normal */
for(i = 0; i < 3; i++)
{
normal[i] = verts[index_xyz].normal[i] / 127.f;
}
/* normals and vertexes come from the frame list */
/* shadevector is set above according to rotation (around Z axis I think) */
norm = r_avertexnormals[verts[index_xyz].lightnormalindex];
l = DotProduct(norm, shadevector) + 1;
l = DotProduct(normal, shadevector) + 1;
for(j=0; j<3; ++j)
{

View file

@ -395,7 +395,7 @@ extern void R_LerpVerts(qboolean powerUpEffect, int nverts,
const dxtrivertx_t *v, const dxtrivertx_t *ov,
float *lerp, const float move[3],
const float frontv[3], const float backv[3]);
extern byte R_CompressNormalMDL(const float *normal);
extern void R_ConvertNormalMDL(byte in_normal, signed char *normal);
extern vec4_t *R_VertBufferRealloc(int num);
extern void R_VertBufferInit(void);
extern void R_VertBufferFree(void);

View file

@ -52,13 +52,6 @@ static float aliasoldworldtransform[3][4];
static float s_ziscale;
static vec3_t s_alias_forward, s_alias_right, s_alias_up;
#define NUMVERTEXNORMALS 162
static const float r_avertexnormals[NUMVERTEXNORMALS][3] = {
#include "../constants/anorms.h"
};
/*
================
R_AliasCheckBBox
@ -293,10 +286,14 @@ R_AliasTransformFinalVerts(int numpoints, finalvert_t *fv, dxtrivertx_t *newv, f
for (i = 0; i < numpoints; i++, fv++, newv++, lerp += 4)
{
vec3_t plightnormal;
float lightcos;
const float *plightnormal;
int n;
plightnormal = r_avertexnormals[newv->lightnormalindex];
for (n = 0; n < 3; n++)
{
plightnormal[n] = newv->normal[n] / 127.f;
}
fv->xyz[0] = DotProduct(lerp, aliastransform[0]) + aliastransform[0][3];
fv->xyz[1] = DotProduct(lerp, aliastransform[1]) + aliastransform[1][3];

View file

@ -27,8 +27,6 @@
#include "header/local.h"
#define NUMVERTEXNORMALS 162
enum {
TRIANGLE_STRIP = 0,
TRIANGLE_FAN = 1
@ -51,10 +49,6 @@ static modelvert *vertList[2] = {NULL, NULL};
static vec3_t *shadowverts = NULL;
static int verts_count = 0;
static const float r_avertexnormals[NUMVERTEXNORMALS][3] = {
#include "../constants/anorms.h"
};
// correction matrix with "hacked depth" for models with RF_DEPTHHACK flag set
static float r_vulkan_correction_dh[16] = {
1.f, 0.f, 0.f, 0.f,
@ -289,8 +283,8 @@ Vk_DrawAliasFrameLerpCommands(entity_t *currententity, int *order, int *order_en
do
{
int vertIdx = vertCounts[pipelineIdx];
int index_xyz = order[2];
const float *norm;
int i, index_xyz = order[2];
vec3_t normal;
float l;
if (Mesh_VertsRealloc(vertIdx))
@ -302,10 +296,15 @@ Vk_DrawAliasFrameLerpCommands(entity_t *currententity, int *order, int *order_en
vertList[pipelineIdx][vertIdx].texCoord[0] = ((float *)order)[0];
vertList[pipelineIdx][vertIdx].texCoord[1] = ((float *)order)[1];
/* unpack normal */
for(i = 0; i < 3; i++)
{
normal[i] = verts[index_xyz].normal[i] / 127.f;
}
/* normals and vertexes come from the frame list */
/* shadevector is set above according to rotation (around Z axis I think) */
norm = r_avertexnormals[verts[index_xyz].lightnormalindex];
l = DotProduct(norm, shadevector) + 1;
l = DotProduct(normal, shadevector) + 1;
vertList[pipelineIdx][vertIdx].color[0] = l * shadelight[0];
vertList[pipelineIdx][vertIdx].color[1] = l * shadelight[1];

View file

@ -436,7 +436,7 @@ typedef struct md3_header_s
typedef struct
{
unsigned short v[3]; /* scaled short to fit in frame mins/maxs */
byte lightnormalindex;
signed char normal[3];
} dxtrivertx_t;
typedef struct