Merge pull request #36 from yquake2/shared_images

Reuse image load with other renders
This commit is contained in:
Denis Pauk 2022-12-15 23:04:56 +02:00 committed by GitHub
commit 879808af8c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 633 additions and 387 deletions

2
.gitignore vendored
View file

@ -1,2 +1,4 @@
/build/ /build/
/release/ /release/
*.orig
*.rej

View file

@ -199,6 +199,36 @@ typedef struct m8tex_s
int value; int value;
} m8tex_t; } m8tex_t;
/* .M32 texture file format */
#define M32_VERSION 0x4
#define M32_MIP_LEVELS 16
typedef struct m32tex_s
{
int version;
char name[128];
char altname[128]; // texture substitution
char animname[128]; // next frame in animation chain
char damagename[128]; // image that should be shown when damaged
unsigned width[M32_MIP_LEVELS], height[M32_MIP_LEVELS];
unsigned offsets[M32_MIP_LEVELS];
int flags;
int contents;
int value;
float scale_x, scale_y;
int mip_scale;
// detail texturing info
char dt_name[128]; // detailed texture name
float dt_scale_x, dt_scale_y;
float dt_u, dt_v;
float dt_alpha;
int dt_src_blend_mode, dt_dst_blend_mode;
int unused[20]; // future expansion to maintain compatibility with h2
} m32tex_t;
/* .BSP file format */ /* .BSP file format */
#define IDBSPHEADER (('P' << 24) + ('S' << 16) + ('B' << 8) + 'I') /* little-endian "IBSP" */ #define IDBSPHEADER (('P' << 24) + ('S' << 16) + ('B' << 8) + 'I') /* little-endian "IBSP" */

View file

@ -60,24 +60,68 @@ typedef enum
extern void R_Printf(int level, const char* msg, ...) __attribute__ ((format (printf, 2, 3))); extern void R_Printf(int level, const char* msg, ...) __attribute__ ((format (printf, 2, 3)));
extern void LoadPCX(char *origname, byte **pic, byte **palette, int *width, int *height); /* Shared images load */
extern void GetPCXInfo(char *filename, int *width, int *height); typedef struct image_s* (*loadimage_t)(const char *name, byte *pic, int width, int realwidth,
int height, int realheight, size_t data_size, imagetype_t type, int bits);
extern struct image_s* LoadWal(const char *origname, imagetype_t type, loadimage_t load_image);
extern struct image_s* LoadM8(const char *origname, imagetype_t type, loadimage_t load_image);
extern struct image_s* LoadM32(const char *origname, imagetype_t type, loadimage_t load_image);
extern void FixFileExt(const char *origname, const char *ext, char *filename, size_t size);
extern void GetPCXPalette(byte **colormap, unsigned *d_8to24table);
extern void LoadPCX(const char *origname, byte **pic, byte **palette, int *width, int *height);
extern void GetPCXInfo(const char *origname, int *width, int *height);
extern void GetWalInfo(const char *name, int *width, int *height);
extern void GetM8Info(const char *name, int *width, int *height);
extern void GetM32Info(const char *name, int *width, int *height);
extern qboolean LoadSTB(const char *origname, const char* type, byte **pic, int *width, int *height);
extern qboolean ResizeSTB(const byte *input_pixels, int input_width, int input_height, extern qboolean ResizeSTB(const byte *input_pixels, int input_width, int input_height,
byte *output_pixels, int output_width, int output_height); byte *output_pixels, int output_width, int output_height);
extern void SmoothColorImage(unsigned *dst, size_t size, size_t rstep); extern void SmoothColorImage(unsigned *dst, size_t size, size_t rstep);
extern void scale2x(const byte *src, byte *dst, int width, int height); extern void scale2x(const byte *src, byte *dst, int width, int height);
extern void scale3x(const byte *src, byte *dst, int width, int height); extern void scale3x(const byte *src, byte *dst, int width, int height);
extern void GetWalInfo(char *name, int *width, int *height);
extern void GetM8Info(char *name, int *width, int *height);
extern float Mod_RadiusFromBounds(const vec3_t mins, const vec3_t maxs); extern float Mod_RadiusFromBounds(const vec3_t mins, const vec3_t maxs);
extern const byte* Mod_DecompressVis(const byte *in, int row); extern const byte* Mod_DecompressVis(const byte *in, int row);
/* Shared models load */ /* Shared models struct */
typedef struct image_s* (*findimage_t)(char *name, imagetype_t type);
enum {
SIDE_FRONT = 0,
SIDE_BACK = 1,
SIDE_ON = 2
};
// FIXME: differentiate from texinfo SURF_ flags
enum {
SURF_PLANEBACK = 0x02,
SURF_DRAWSKY = 0x04, // sky brush face
SURF_DRAWTURB = 0x10,
SURF_DRAWBACKGROUND = 0x40,
SURF_UNDERWATER = 0x80
};
typedef struct mvertex_s
{
vec3_t position;
} mvertex_t;
typedef struct medge_s
{
unsigned short v[2];
unsigned int cachededgeoffset;
} medge_t;
typedef struct mtexinfo_s
{
float vecs[2][4];
int flags;
int numframes;
struct mtexinfo_s *next; /* animation chain */
struct image_s *image;
} mtexinfo_t;
/* Shared models func */
typedef struct image_s* (*findimage_t)(const char *name, imagetype_t type);
extern void *Mod_LoadMD2 (const char *mod_name, const void *buffer, int modfilelen, extern void *Mod_LoadMD2 (const char *mod_name, const void *buffer, int modfilelen,
vec3_t mins, vec3_t maxs, struct image_s **skins, vec3_t mins, vec3_t maxs, struct image_s **skins,
findimage_t find_image, modtype_t *type); findimage_t find_image, modtype_t *type);
@ -85,5 +129,11 @@ extern void *Mod_LoadSP2 (const char *mod_name, const void *buffer, int modfilel
struct image_s **skins, findimage_t find_image, modtype_t *type); struct image_s **skins, findimage_t find_image, modtype_t *type);
extern int Mod_ReLoadSkins(struct image_s **skins, findimage_t find_image, extern int Mod_ReLoadSkins(struct image_s **skins, findimage_t find_image,
void *extradata, modtype_t type); void *extradata, modtype_t type);
extern struct image_s *GetSkyImage(const char *skyname, const char* surfname,
qboolean palettedtexture, findimage_t find_image);
extern struct image_s *GetTexImage(const char *name, findimage_t find_image);
extern struct image_s *R_FindPic(const char *name, findimage_t find_image);
extern struct image_s* R_LoadImage(const char *name, const char* namewe, const char *ext, imagetype_t type,
qboolean r_retexturing, loadimage_t load_image);
#endif /* SRC_CLIENT_REFRESH_REF_SHARED_H_ */ #endif /* SRC_CLIENT_REFRESH_REF_SHARED_H_ */

View file

@ -117,7 +117,7 @@ fixQuitScreen(byte* px)
} }
void void
LoadPCX(char *origname, byte **pic, byte **palette, int *width, int *height) LoadPCX(const char *origname, byte **pic, byte **palette, int *width, int *height)
{ {
byte *raw; byte *raw;
pcx_t *pcx; pcx_t *pcx;
@ -129,13 +129,7 @@ LoadPCX(char *origname, byte **pic, byte **palette, int *width, int *height)
byte *out, *pix; byte *out, *pix;
char filename[256]; char filename[256];
Q_strlcpy(filename, origname, sizeof(filename)); FixFileExt(origname, "pcx", filename, sizeof(filename));
/* Add the extension */
if (strcmp(COM_FileExtension(filename), "pcx"))
{
Q_strlcat(filename, ".pcx", sizeof(filename));
}
*pic = NULL; *pic = NULL;
@ -276,7 +270,7 @@ LoadPCX(char *origname, byte **pic, byte **palette, int *width, int *height)
*pic = NULL; *pic = NULL;
} }
else if(pcx_width == 319 && pcx_height == 239 else if(pcx_width == 319 && pcx_height == 239
&& Q_strcasecmp(origname, "pics/quit.pcx") == 0 && Q_strcasecmp(filename, "pics/quit.pcx") == 0
&& Com_BlockChecksum(pcx, len) == 3329419434u) && Com_BlockChecksum(pcx, len) == 3329419434u)
{ {
// it's the quit screen, and the baseq2 one (identified by checksum) // it's the quit screen, and the baseq2 one (identified by checksum)
@ -293,10 +287,13 @@ LoadPCX(char *origname, byte **pic, byte **palette, int *width, int *height)
} }
void void
GetPCXInfo(char *filename, int *width, int *height) GetPCXInfo(const char *origname, int *width, int *height)
{ {
pcx_t *pcx; pcx_t *pcx;
byte *raw; byte *raw;
char filename[256];
FixFileExt(origname, "pcx", filename, sizeof(filename));
ri.FS_LoadFile(filename, (void **)&raw); ri.FS_LoadFile(filename, (void **)&raw);
@ -315,3 +312,39 @@ GetPCXInfo(char *filename, int *width, int *height)
return; return;
} }
/*
===============
GetPCXPalette
===============
*/
void
GetPCXPalette (byte **colormap, unsigned *d_8to24table)
{
byte *pal;
int i;
/* get the palette and colormap */
LoadPCX ("pics/colormap.pcx", colormap, &pal, NULL, NULL);
if (!*colormap || !pal)
{
ri.Sys_Error (ERR_FATAL, "%s: Couldn't load pics/colormap.pcx",
__func__);
}
for (i=0 ; i<256 ; i++)
{
unsigned v;
int r, g, b;
r = pal[i*3+0];
g = pal[i*3+1];
b = pal[i*3+2];
v = (255<<24) + (r<<0) + (g<<8) + (b<<16);
d_8to24table[i] = LittleLong(v);
}
d_8to24table[255] &= LittleLong(0xffffff); // 255 is transparent
free (pal);
}

View file

@ -47,24 +47,33 @@
#define STB_IMAGE_RESIZE_IMPLEMENTATION #define STB_IMAGE_RESIZE_IMPLEMENTATION
#include "stb_image_resize.h" #include "stb_image_resize.h"
/*
* Add extension to file name
*/
void
FixFileExt(const char *origname, const char *ext, char *filename, size_t size)
{
Q_strlcpy(filename, origname, size);
/* Add the extension */
if (strcmp(COM_FileExtension(filename), ext))
{
Q_strlcat(filename, ".", size);
Q_strlcat(filename, ext, size);
}
}
/* /*
* origname: the filename to be opened, might be without extension * origname: the filename to be opened, might be without extension
* type: extension of the type we wanna open ("jpg", "png" or "tga") * type: extension of the type we wanna open ("jpg", "png" or "tga")
* pic: pointer RGBA pixel data will be assigned to * pic: pointer RGBA pixel data will be assigned to
*/ */
qboolean static qboolean
LoadSTB(const char *origname, const char* type, byte **pic, int *width, int *height) LoadSTB(const char *origname, const char* type, byte **pic, int *width, int *height)
{ {
char filename[256]; char filename[256];
Q_strlcpy(filename, origname, sizeof(filename)); FixFileExt(origname, type, filename, sizeof(filename));
/* Add the extension */
if (strcmp(COM_FileExtension(filename), type) != 0)
{
Q_strlcat(filename, ".", sizeof(filename));
Q_strlcat(filename, type, sizeof(filename));
}
*pic = NULL; *pic = NULL;
@ -425,3 +434,229 @@ scale3x(const byte *src, byte *dst, int width, int height)
} }
} }
} }
static struct image_s *
LoadHiColorImage(const char *name, const char* namewe, const char *ext,
imagetype_t type, loadimage_t load_image)
{
int realwidth = 0, realheight = 0;
int width = 0, height = 0;
struct image_s *image = NULL;
byte *pic = NULL;
/* Get size of the original texture */
if (strcmp(ext, "pcx") == 0)
{
GetPCXInfo(name, &realwidth, &realheight);
}
else if (strcmp(ext, "wal") == 0)
{
GetWalInfo(name, &realwidth, &realheight);
}
else if (strcmp(ext, "m8") == 0)
{
GetM8Info(name, &realwidth, &realheight);
}
else if (strcmp(ext, "m32") == 0)
{
GetM32Info(name, &realwidth, &realheight);
}
/* try to load a tga, png or jpg (in that order/priority) */
if ( LoadSTB(namewe, "tga", &pic, &width, &height)
|| LoadSTB(namewe, "png", &pic, &width, &height)
|| LoadSTB(namewe, "jpg", &pic, &width, &height) )
{
if (width >= realwidth && height >= realheight)
{
if (realheight == 0 || realwidth == 0)
{
realheight = height;
realwidth = width;
}
image = load_image(name, pic,
width, realwidth,
height, realheight,
width * height,
type, 32);
}
}
if (pic)
{
free(pic);
}
return image;
}
struct image_s *
R_LoadImage(const char *name, const char* namewe, const char *ext, imagetype_t type,
qboolean r_retexturing, loadimage_t load_image)
{
struct image_s *image = NULL;
// with retexturing and not skin
if (r_retexturing)
{
image = LoadHiColorImage(name, namewe, ext, type, load_image);
}
if (!image)
{
if (!strcmp(ext, "pcx"))
{
byte *pic = NULL;
byte *palette = NULL;
int width = 0, height = 0;
LoadPCX (namewe, &pic, &palette, &width, &height);
if (!pic)
return NULL;
image = load_image(name, pic,
width, width,
height, height,
width * height, type, 8);
if (palette)
{
free(palette);
}
free(pic);
}
else if (!strcmp(ext, "wal"))
{
image = LoadWal(namewe, type, load_image);
}
else if (!strcmp(ext, "m8"))
{
image = LoadM8(namewe, type, load_image);
}
else if (!strcmp(ext, "m32"))
{
image = LoadM32(namewe, type, load_image);
}
else if (!strcmp(ext, "tga") ||
!strcmp(ext, "png") ||
!strcmp(ext, "jpg"))
{
byte *pic = NULL;
int width = 0, height = 0;
if (LoadSTB (namewe, ext, &pic, &width, &height) && pic)
{
image = load_image(name, pic,
width, width,
height, height,
width * height,
type, 32);
free(pic);
}
}
}
return image;
}
struct image_s*
GetSkyImage(const char *skyname, const char* surfname, qboolean palettedtexture,
findimage_t find_image)
{
struct image_s *image = NULL;
char pathname[MAX_QPATH];
/* Quake 2 */
if (palettedtexture)
{
Com_sprintf(pathname, sizeof(pathname), "env/%s%s.pcx",
skyname, surfname);
image = find_image(pathname, it_sky);
}
if (!image)
{
Com_sprintf(pathname, sizeof(pathname), "env/%s%s.tga",
skyname, surfname);
image = find_image(pathname, it_sky);
}
/* Heretic 2 */
if (!image)
{
Com_sprintf(pathname, sizeof(pathname), "pics/Skies/%s%s.m32",
skyname, surfname);
image = find_image(pathname, it_sky);
}
if (!image)
{
Com_sprintf(pathname, sizeof(pathname), "pics/Skies/%s%s.m8",
skyname, surfname);
image = find_image(pathname, it_sky);
}
return image;
}
struct image_s *
GetTexImage(const char *name, findimage_t find_image)
{
struct image_s *image = NULL;
char pathname[MAX_QPATH];
/* Quake 2 */
Com_sprintf(pathname, sizeof(pathname), "textures/%s.wal", name);
image = find_image(pathname, it_wall);
/* Heretic 2 */
if (!image)
{
Com_sprintf(pathname, sizeof(pathname), "textures/%s.m32", name);
image = find_image(pathname, it_wall);
}
if (!image)
{
Com_sprintf(pathname, sizeof(pathname), "textures/%s.m8", name);
image = find_image(pathname, it_wall);
}
return image;
}
struct image_s *
R_FindPic(const char *name, findimage_t find_image)
{
struct image_s *image = NULL;
if ((name[0] != '/') && (name[0] != '\\'))
{
char pathname[MAX_QPATH];
/* Quake 2 */
Com_sprintf(pathname, sizeof(pathname), "pics/%s.pcx", name);
image = find_image(pathname, it_pic);
/* Heretic 2 */
if (!image)
{
Com_sprintf(pathname, sizeof(pathname), "pics/misc/%s.m32", name);
image = find_image(pathname, it_pic);
}
if (!image)
{
Com_sprintf(pathname, sizeof(pathname), "pics/misc/%s.m8", name);
image = find_image(pathname, it_pic);
}
}
else
{
image = find_image(name + 1, it_pic);
}
return image;
}

View file

@ -26,17 +26,179 @@
#include "../common/header/ref_shared.h" #include "../common/header/ref_shared.h"
/* struct image_s *
* NOTE: LoadWal() is in *_image.c because it needs the renderer-specific image_t LoadWal(const char *origname, imagetype_t type, loadimage_t load_image)
*/ {
int width, height, ofs, size;
struct image_s *image;
char name[256];
miptex_t *mt;
FixFileExt(origname, "wal", name, sizeof(name));
size = ri.FS_LoadFile(name, (void **)&mt);
if (!mt)
{
return NULL;
}
if (size < sizeof(miptex_t))
{
R_Printf(PRINT_ALL, "%s: can't load %s, small header\n", __func__, name);
ri.FS_FreeFile((void *)mt);
return NULL;
}
width = LittleLong(mt->width);
height = LittleLong(mt->height);
ofs = LittleLong(mt->offsets[0]);
if ((ofs <= 0) || (width <= 0) || (height <= 0) ||
(((size - ofs) / height) < width))
{
R_Printf(PRINT_ALL, "%s: can't load %s, small body\n", __func__, name);
ri.FS_FreeFile((void *)mt);
return NULL;
}
image = load_image(name, (byte *)mt + ofs,
width, 0,
height, 0,
(size - ofs), type, 8);
ri.FS_FreeFile((void *)mt);
return image;
}
struct image_s *
LoadM8(const char *origname, imagetype_t type, loadimage_t load_image)
{
m8tex_t *mt;
int width, height, ofs, size, i;
struct image_s *image;
char name[256];
unsigned char *image_buffer = NULL;
FixFileExt(origname, "m8", name, sizeof(name));
size = ri.FS_LoadFile(name, (void **)&mt);
if (!mt)
{
return NULL;
}
if (size < sizeof(m8tex_t))
{
R_Printf(PRINT_ALL, "%s: can't load %s, small header\n", __func__, name);
ri.FS_FreeFile((void *)mt);
return NULL;
}
if (LittleLong (mt->version) != M8_VERSION)
{
R_Printf(PRINT_ALL, "%s: can't load %s, wrong magic value.\n", __func__, name);
ri.FS_FreeFile ((void *)mt);
return NULL;
}
width = LittleLong(mt->width[0]);
height = LittleLong(mt->height[0]);
ofs = LittleLong(mt->offsets[0]);
if ((ofs <= 0) || (width <= 0) || (height <= 0) ||
(((size - ofs) / height) < width))
{
R_Printf(PRINT_ALL, "%s: can't load %s, small body\n", __func__, name);
ri.FS_FreeFile((void *)mt);
return NULL;
}
image_buffer = malloc ((size - ofs) * 4);
for(i=0; i<(size - ofs); i++)
{
unsigned char value = *((byte *)mt + ofs + i);
image_buffer[i * 4 + 0] = mt->palette[value].r;
image_buffer[i * 4 + 1] = mt->palette[value].g;
image_buffer[i * 4 + 2] = mt->palette[value].b;
image_buffer[i * 4 + 3] = value == 255 ? 0 : 255;
}
image = load_image(name, image_buffer,
width, 0,
height, 0,
(size - ofs), type, 32);
free(image_buffer);
ri.FS_FreeFile((void *)mt);
return image;
}
struct image_s *
LoadM32(const char *origname, imagetype_t type, loadimage_t load_image)
{
m32tex_t *mt;
int width, height, ofs, size;
struct image_s *image;
char name[256];
FixFileExt(origname, "m32", name, sizeof(name));
size = ri.FS_LoadFile(name, (void **)&mt);
if (!mt)
{
return NULL;
}
if (size < sizeof(m8tex_t))
{
R_Printf(PRINT_ALL, "%s: can't load %s, small header\n", __func__, name);
ri.FS_FreeFile((void *)mt);
return NULL;
}
if (LittleLong (mt->version) != M32_VERSION)
{
R_Printf(PRINT_ALL, "%s: can't load %s, wrong magic value.\n", __func__, name);
ri.FS_FreeFile ((void *)mt);
return NULL;
}
width = LittleLong (mt->width[0]);
height = LittleLong (mt->height[0]);
ofs = LittleLong (mt->offsets[0]);
if ((ofs <= 0) || (width <= 0) || (height <= 0) ||
(((size - ofs) / height) < (width * 4)))
{
R_Printf(PRINT_ALL, "%s: can't load %s, small body\n", __func__, name);
ri.FS_FreeFile((void *)mt);
return NULL;
}
image = load_image(name, (byte *)mt + ofs,
width, 0,
height, 0,
(size - ofs) / 4, type, 32);
ri.FS_FreeFile ((void *)mt);
return image;
}
void void
GetWalInfo(char *name, int *width, int *height) GetWalInfo(const char *origname, int *width, int *height)
{ {
miptex_t *mt; miptex_t *mt;
int size; int size;
char filename[256];
size = ri.FS_LoadFile(name, (void **)&mt); FixFileExt(origname, "wal", filename, sizeof(filename));
size = ri.FS_LoadFile(filename, (void **)&mt);
if (!mt) if (!mt)
{ {
@ -58,19 +220,21 @@ GetWalInfo(char *name, int *width, int *height)
} }
void void
GetM8Info(char *name, int *width, int *height) GetM8Info(const char *origname, int *width, int *height)
{ {
m8tex_t *mt; m8tex_t *mt;
int size; int size;
char filename[256];
size = ri.FS_LoadFile(name, (void **)&mt); FixFileExt(origname, "m8", filename, sizeof(filename));
size = ri.FS_LoadFile(filename, (void **)&mt);
if (!mt) if (!mt)
{ {
return; return;
} }
if (size < sizeof(m8tex_t) || LittleLong (mt->version) != M8_VERSION) if (size < sizeof(m8tex_t) || LittleLong (mt->version) != M8_VERSION)
{ {
ri.FS_FreeFile((void *)mt); ri.FS_FreeFile((void *)mt);
@ -84,3 +248,33 @@ GetM8Info(char *name, int *width, int *height)
return; return;
} }
void
GetM32Info(const char *origname, int *width, int *height)
{
m32tex_t *mt;
int size;
char filename[256];
FixFileExt(origname, "m32", filename, sizeof(filename));
size = ri.FS_LoadFile(filename, (void **)&mt);
if (!mt)
{
return;
}
if (size < sizeof(m32tex_t) || LittleLong (mt->version) != M32_VERSION)
{
ri.FS_FreeFile((void *)mt);
return;
}
*width = LittleLong(mt->width[0]);
*height = LittleLong(mt->height[0]);
ri.FS_FreeFile((void *)mt);
return;
}

View file

@ -136,7 +136,7 @@ extern cvar_t *r_farsee;
extern cvar_t *vk_overbrightbits; extern cvar_t *vk_overbrightbits;
extern cvar_t *r_validation; extern cvar_t *r_validation;
extern cvar_t *vk_picmip; extern cvar_t *vk_picmip;
extern cvar_t *vk_skymip; extern cvar_t *r_palettedtexture;
extern cvar_t *vk_flashblend; extern cvar_t *vk_flashblend;
extern cvar_t *vk_finish; extern cvar_t *vk_finish;
extern cvar_t *vk_shadows; extern cvar_t *vk_shadows;
@ -240,7 +240,7 @@ struct image_s *RE_RegisterSkin (char *name);
image_t *Vk_LoadPic(const char *name, byte *pic, int width, int realwidth, image_t *Vk_LoadPic(const char *name, byte *pic, int width, int realwidth,
int height, int realheight, size_t data_size, imagetype_t type, int height, int realheight, size_t data_size, imagetype_t type,
int bits); int bits);
image_t *Vk_FindImage (char *name, imagetype_t type); image_t *Vk_FindImage (const char *name, imagetype_t type);
void Vk_TextureMode( char *string ); void Vk_TextureMode( char *string );
void Vk_LmapTextureMode( char *string ); void Vk_LmapTextureMode( char *string );
void Vk_ImageList_f (void); void Vk_ImageList_f (void);

View file

@ -41,10 +41,6 @@ BRUSH MODELS
// //
// in memory representation // in memory representation
// //
typedef struct
{
vec3_t position;
} mvertex_t;
#define SIDE_FRONT 0 #define SIDE_FRONT 0
@ -58,21 +54,6 @@ typedef struct
#define SURF_DRAWBACKGROUND 0x40 #define SURF_DRAWBACKGROUND 0x40
#define SURF_UNDERWATER 0x80 #define SURF_UNDERWATER 0x80
typedef struct
{
unsigned short v[2];
unsigned int cachededgeoffset;
} medge_t;
typedef struct mtexinfo_s
{
float vecs[2][4];
int flags;
int numframes;
struct mtexinfo_s *next; // animation chain
image_t *image;
} mtexinfo_t;
#define VERTEXSIZE 7 #define VERTEXSIZE 7
typedef struct vkpoly_s typedef struct vkpoly_s

View file

@ -31,10 +31,11 @@ Draw_InitLocal
*/ */
void Draw_InitLocal (void) void Draw_InitLocal (void)
{ {
draw_chars = Vk_FindImage("pics/conchars.pcx", it_pic); draw_chars = R_FindPic ("conchars", (findimage_t)Vk_FindImage);
if (!draw_chars) if (!draw_chars)
{ {
ri.Sys_Error(ERR_FATAL, "%s: Couldn't load pics/conchars.pcx", __func__); ri.Sys_Error(ERR_FATAL, "%s: Couldn't load pics/conchars.pcx",
__func__);
} }
} }
@ -85,19 +86,7 @@ RE_Draw_FindPic
*/ */
image_t *RE_Draw_FindPic (char *name) image_t *RE_Draw_FindPic (char *name)
{ {
image_t *vk; return R_FindPic(name, (findimage_t)Vk_FindImage);
if (name[0] != '/' && name[0] != '\\')
{
char fullname[MAX_QPATH];
Com_sprintf(fullname, sizeof(fullname), "pics/%s.pcx", name);
vk = Vk_FindImage(fullname, it_pic);
}
else
vk = Vk_FindImage(name + 1, it_pic);
return vk;
} }
/* /*
@ -107,17 +96,17 @@ RE_Draw_GetPicSize
*/ */
void RE_Draw_GetPicSize (int *w, int *h, char *name) void RE_Draw_GetPicSize (int *w, int *h, char *name)
{ {
image_t *vk; image_t *image;
vk = RE_Draw_FindPic(name); image = R_FindPic(name, (findimage_t)Vk_FindImage);
if (!vk) if (!image)
{ {
*w = *h = -1; *w = *h = -1;
return; return;
} }
*w = vk->width; *w = image->width;
*h = vk->height; *h = image->height;
} }
/* /*
@ -132,7 +121,7 @@ void RE_Draw_StretchPic (int x, int y, int w, int h, char *name)
if (!vk_frameStarted) if (!vk_frameStarted)
return; return;
vk = RE_Draw_FindPic(name); vk = R_FindPic(name, (findimage_t)Vk_FindImage);
if (!vk) if (!vk)
{ {
R_Printf(PRINT_ALL, "%s(): Can't find pic: %s\n", __func__, name); R_Printf(PRINT_ALL, "%s(): Can't find pic: %s\n", __func__, name);
@ -155,7 +144,7 @@ void RE_Draw_PicScaled (int x, int y, char *name, float scale)
{ {
image_t *vk; image_t *vk;
vk = RE_Draw_FindPic(name); vk = R_FindPic(name, (findimage_t)Vk_FindImage);
if (!vk) if (!vk)
{ {
R_Printf(PRINT_ALL, "%s(): Can't find pic: %s\n", __func__, name); R_Printf(PRINT_ALL, "%s(): Can't find pic: %s\n", __func__, name);
@ -180,7 +169,7 @@ void RE_Draw_TileClear (int x, int y, int w, int h, char *name)
if (!vk_frameStarted) if (!vk_frameStarted)
return; return;
image = RE_Draw_FindPic(name); image = R_FindPic(name, (findimage_t)Vk_FindImage);
if (!image) if (!image)
{ {
R_Printf(PRINT_ALL, "%s(): Can't find pic: %s\n", __func__, name); R_Printf(PRINT_ALL, "%s(): Can't find pic: %s\n", __func__, name);

View file

@ -1218,231 +1218,6 @@ Vk_LoadPic(const char *name, byte *pic, int width, int realwidth,
return image; return image;
} }
/*
================
Vk_LoadWal
================
*/
static image_t *Vk_LoadWal (char *name, imagetype_t type)
{
miptex_t *mt;
int width, height, ofs;
image_t *image;
ri.FS_LoadFile (name, (void **)&mt);
if (!mt)
{
R_Printf(PRINT_ALL, "%s: can't load %s\n", __func__, name);
return r_notexture;
}
width = LittleLong (mt->width);
height = LittleLong (mt->height);
ofs = LittleLong (mt->offsets[0]);
image = Vk_LoadPic(name, (byte *)mt + ofs,
width, width,
height, height,
height * width,
type, 8);
ri.FS_FreeFile ((void *)mt);
return image;
}
static image_t *
Vk_LoadM8(char *origname, imagetype_t type)
{
m8tex_t *mt;
int width, height, ofs, size;
image_t *image;
char name[256];
unsigned char *image_buffer = NULL;
Q_strlcpy(name, origname, sizeof(name));
/* Add the extension */
if (strcmp(COM_FileExtension(name), "m8"))
{
Q_strlcat(name, ".m8", sizeof(name));
}
size = ri.FS_LoadFile(name, (void **)&mt);
if (!mt)
{
R_Printf(PRINT_ALL, "%s: can't load %s\n", __func__, name);
return r_notexture;
}
if (size < sizeof(m8tex_t))
{
R_Printf(PRINT_ALL, "%s: can't load %s, small header\n", __func__, name);
ri.FS_FreeFile((void *)mt);
return r_notexture;
}
if (LittleLong (mt->version) != M8_VERSION)
{
R_Printf(PRINT_ALL, "LoadWal: can't load %s, wrong magic value.\n", name);
ri.FS_FreeFile ((void *)mt);
return r_notexture;
}
width = LittleLong(mt->width[0]);
height = LittleLong(mt->height[0]);
ofs = LittleLong(mt->offsets[0]);
if ((ofs <= 0) || (width <= 0) || (height <= 0) ||
(((size - ofs) / height) < width))
{
R_Printf(PRINT_ALL, "%s: can't load %s, small body\n", __func__, name);
ri.FS_FreeFile((void *)mt);
return r_notexture;
}
image_buffer = malloc (width * height * 4);
for(int i=0; i<width * height; i++)
{
unsigned char value = *((byte *)mt + ofs + i);
image_buffer[i * 4 + 0] = mt->palette[value].r;
image_buffer[i * 4 + 1] = mt->palette[value].g;
image_buffer[i * 4 + 2] = mt->palette[value].b;
image_buffer[i * 4 + 3] = value == 255 ? 0 : 255;
}
image = Vk_LoadPic(name, image_buffer,
width, width,
height, height,
width * height,
type, 32);
free(image_buffer);
ri.FS_FreeFile((void *)mt);
return image;
}
static image_t*
Vk_LoadHiColorImage(char *name, const char* namewe, const char *ext, imagetype_t type)
{
image_t *image = NULL;
byte *pic = NULL;
int realwidth = 0, realheight = 0;
int width = 0, height = 0;
if (strcmp(ext, "pcx") == 0)
{
/* Get size of the original texture */
GetPCXInfo(name, &realwidth, &realheight);
}
else if (strcmp(ext, "wal") == 0)
{
/* Get size of the original texture */
GetWalInfo(name, &realwidth, &realheight);
}
else if (strcmp(ext, "m8") == 0)
{
/* Get size of the original texture */
GetM8Info(name, &realwidth, &realheight);
}
/* try to load a tga, png or jpg (in that order/priority) */
if ( LoadSTB(namewe, "tga", &pic, &width, &height)
|| LoadSTB(namewe, "png", &pic, &width, &height)
|| LoadSTB(namewe, "jpg", &pic, &width, &height) )
{
if (width >= realwidth && height >= realheight)
{
if (realheight == 0 || realwidth == 0)
{
realheight = height;
realwidth = width;
}
image = Vk_LoadPic(name, pic,
width, realwidth,
height, realheight,
width * height,
type, 32);
}
}
if (pic)
{
free(pic);
}
return image;
}
static image_t*
Vk_LoadImage(char *name, const char* namewe, const char *ext, imagetype_t type)
{
image_t *image = NULL;
// with retexturing
if (r_retexturing->value)
{
image = Vk_LoadHiColorImage(name, namewe, ext, type);
}
if (!image)
{
byte *pic;
int width, height;
//
// load the pic from disk
//
pic = NULL;
if (!strcmp(ext, "pcx"))
{
byte *palette;
palette = NULL;
LoadPCX (name, &pic, &palette, &width, &height);
if (!pic)
return NULL;
image = Vk_LoadPic(name, pic,
width, width,
height, height,
width * height,
type, 8);
if (palette)
free(palette);
}
else if (!strcmp(ext, "wal"))
{
image = Vk_LoadWal (name, type);
}
else if (!strcmp(ext, "m8"))
{
image = Vk_LoadM8 (name, type);
}
else if (!strcmp(ext, "tga"))
{
if (!LoadSTB (namewe, "tga", &pic, &width, &height))
return NULL;
if (!pic)
return NULL;
image = Vk_LoadPic(name, pic,
width, width,
height, height,
width * height,
type, 32);
}
if (pic)
free(pic);
}
return image;
}
/* /*
=============== ===============
Vk_FindImage Vk_FindImage
@ -1450,7 +1225,8 @@ Vk_FindImage
Finds or loads the given image or NULL Finds or loads the given image or NULL
=============== ===============
*/ */
image_t *Vk_FindImage (char *name, imagetype_t type) image_t *
Vk_FindImage (const char *name, imagetype_t type)
{ {
image_t *image; image_t *image;
int i, len; int i, len;
@ -1499,7 +1275,8 @@ image_t *Vk_FindImage (char *name, imagetype_t type)
// //
// load the pic from disk // load the pic from disk
// //
image = Vk_LoadImage(name, namewe, ext, type); image = (image_t *)R_LoadImage(name, namewe, ext, type,
r_retexturing->value, (loadimage_t)Vk_LoadPic);
if (!image && r_validation->value > 0) if (!image && r_validation->value > 0)
{ {
@ -1598,46 +1375,6 @@ void Vk_FreeUnusedImages (void)
vulkan_memory_free_unused(); vulkan_memory_free_unused();
} }
/*
===============
Draw_GetPalette
===============
*/
static int Draw_GetPalette (void)
{
int i;
byte *pic, *pal;
int width, height;
// get the palette
LoadPCX ("pics/colormap.pcx", &pic, &pal, &width, &height);
if (!pal)
ri.Sys_Error (ERR_FATAL, "Couldn't load pics/colormap.pcx");
for (i=0 ; i<256 ; i++)
{
unsigned v;
int r, g, b;
r = pal[i*3+0];
g = pal[i*3+1];
b = pal[i*3+2];
v = (255u<<24) + (r<<0) + (g<<8) + (b<<16);
d_8to24table[i] = LittleLong(v);
}
d_8to24table[255] &= LittleLong(0xffffff); // 255 is transparent
free (pic);
free (pal);
return 0;
}
/* /*
=============== ===============
Vk_InitImages Vk_InitImages
@ -1647,6 +1384,7 @@ void Vk_InitImages (void)
{ {
int i; int i;
float overbright; float overbright;
byte *colormap;
numvktextures = 0; numvktextures = 0;
img_loaded = 0; img_loaded = 0;
@ -1671,7 +1409,8 @@ void Vk_InitImages (void)
intensitytable[i] = j; intensitytable[i] = j;
} }
Draw_GetPalette(); GetPCXPalette (&colormap, d_8to24table);
free(colormap);
overbright = vk_overbrightbits->value; overbright = vk_overbrightbits->value;

View file

@ -380,7 +380,6 @@ Mod_LoadTexinfo (model_t *loadmodel, const byte *mod_base, const lump_t *l)
texinfo_t *in; texinfo_t *in;
mtexinfo_t *out, *step; mtexinfo_t *out, *step;
int i, j, count; int i, j, count;
char name[MAX_QPATH];
in = (void *)(mod_base + l->fileofs); in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in)) if (l->filelen % sizeof(*in))
@ -397,6 +396,7 @@ Mod_LoadTexinfo (model_t *loadmodel, const byte *mod_base, const lump_t *l)
for ( i=0 ; i<count ; i++, in++, out++) for ( i=0 ; i<count ; i++, in++, out++)
{ {
image_t *image;
int next; int next;
for (j=0 ; j<4 ; j++) for (j=0 ; j<4 ; j++)
@ -410,21 +410,17 @@ Mod_LoadTexinfo (model_t *loadmodel, const byte *mod_base, const lump_t *l)
if (next > 0) if (next > 0)
out->next = loadmodel->texinfo + next; out->next = loadmodel->texinfo + next;
else else
out->next = NULL; out->next = NULL;
Com_sprintf (name, sizeof(name), "textures/%s.wal", in->texture);
out->image = Vk_FindImage (name, it_wall); image = GetTexImage(in->texture, (findimage_t)Vk_FindImage);
if (!out->image || out->image == r_notexture) if (!image)
{ {
Com_sprintf (name, sizeof(name), "textures/%s.m8", in->texture); R_Printf(PRINT_ALL, "%s: Couldn't load %s\n",
out->image = Vk_FindImage (name, it_wall); __func__, in->texture);
image = r_notexture;
} }
if (!out->image) out->image = image;
{
R_Printf(PRINT_ALL, "Couldn't load %s\n", name);
out->image = r_notexture;
}
} }
// count animation frames // count animation frames

View file

@ -94,7 +94,7 @@ cvar_t *r_lightlevel; // FIXME: This is a HACK to get the client's light level
cvar_t *vk_overbrightbits; cvar_t *vk_overbrightbits;
cvar_t *r_validation; cvar_t *r_validation;
cvar_t *vk_picmip; cvar_t *vk_picmip;
cvar_t *vk_skymip; cvar_t *r_palettedtexture;
cvar_t *vk_flashblend; cvar_t *vk_flashblend;
cvar_t *vk_finish; cvar_t *vk_finish;
#if defined(__APPLE__) #if defined(__APPLE__)
@ -195,6 +195,7 @@ void R_DrawSpriteModel (entity_t *currententity, model_t *currentmodel)
dsprframe_t *frame; dsprframe_t *frame;
float *up, *right; float *up, *right;
dsprite_t *psprite; dsprite_t *psprite;
image_t *skin;
// don't even bother culling, because it's just a single // don't even bother culling, because it's just a single
// polygon without a surface cache // polygon without a surface cache
@ -246,7 +247,15 @@ void R_DrawSpriteModel (entity_t *currententity, model_t *currentmodel)
vkCmdPushConstants(vk_activeCmdbuffer, vk_drawTexQuadPipeline[vk_state.current_renderpass].layout, vkCmdPushConstants(vk_activeCmdbuffer, vk_drawTexQuadPipeline[vk_state.current_renderpass].layout,
VK_SHADER_STAGE_FRAGMENT_BIT, 17 * sizeof(float), sizeof(gamma), &gamma); VK_SHADER_STAGE_FRAGMENT_BIT, 17 * sizeof(float), sizeof(gamma), &gamma);
vkCmdBindDescriptorSets(vk_activeCmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vk_drawSpritePipeline.layout, 0, 1, &currentmodel->skins[currententity->frame]->vk_texture.descriptorSet, 0, NULL); skin = currentmodel->skins[currententity->frame];
if (!skin)
{
skin = r_notexture;
}
vkCmdBindDescriptorSets(vk_activeCmdbuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
vk_drawSpritePipeline.layout, 0, 1,
&skin->vk_texture.descriptorSet, 0, NULL);
vkCmdDraw(vk_activeCmdbuffer, 6, 1, 0, 0); vkCmdDraw(vk_activeCmdbuffer, 6, 1, 0, 0);
} }
@ -1176,7 +1185,7 @@ R_Register( void )
vk_overbrightbits = ri.Cvar_Get("vk_overbrightbits", "1.0", CVAR_ARCHIVE); vk_overbrightbits = ri.Cvar_Get("vk_overbrightbits", "1.0", CVAR_ARCHIVE);
r_validation = ri.Cvar_Get("r_validation", "0", CVAR_ARCHIVE); r_validation = ri.Cvar_Get("r_validation", "0", CVAR_ARCHIVE);
vk_picmip = ri.Cvar_Get("vk_picmip", "0", 0); vk_picmip = ri.Cvar_Get("vk_picmip", "0", 0);
vk_skymip = ri.Cvar_Get("vk_skymip", "0", 0); r_palettedtexture = ri.Cvar_Get("r_palettedtexture", "0", 0);
vk_flashblend = ri.Cvar_Get("vk_flashblend", "0", 0); vk_flashblend = ri.Cvar_Get("vk_flashblend", "0", 0);
vk_finish = ri.Cvar_Get("vk_finish", "0", CVAR_ARCHIVE); vk_finish = ri.Cvar_Get("vk_finish", "0", CVAR_ARCHIVE);
r_clear = ri.Cvar_Get("r_clear", "0", CVAR_ARCHIVE); r_clear = ri.Cvar_Get("r_clear", "0", CVAR_ARCHIVE);

View file

@ -21,7 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// vk_warp.c -- sky and water polygons // vk_warp.c -- sky and water polygons
#include "header/local.h" #include "header/local.h"
static char skyname[MAX_QPATH];
static float skyrotate; static float skyrotate;
static vec3_t skyaxis; static vec3_t skyaxis;
static image_t *sky_images[6]; static image_t *sky_images[6];
@ -683,7 +682,6 @@ void R_DrawSkyBox (void)
} }
} }
/* /*
============ ============
RE_SetSky_s RE_SetSky_s
@ -693,8 +691,8 @@ RE_SetSky_s
static char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"}; static char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
void RE_SetSky_s (const char *name, float rotate, const vec3_t axis) void RE_SetSky_s (const char *name, float rotate, const vec3_t axis)
{ {
char skyname[MAX_QPATH];
int i; int i;
char pathname[MAX_QPATH];
strncpy(skyname, name, sizeof(skyname) - 1); strncpy(skyname, name, sizeof(skyname) - 1);
skyrotate = rotate; skyrotate = rotate;
@ -702,31 +700,21 @@ void RE_SetSky_s (const char *name, float rotate, const vec3_t axis)
for (i = 0; i<6; i++) for (i = 0; i<6; i++)
{ {
// chop down rotating skies for less memory image_t *image;
if (vk_skymip->value || skyrotate)
vk_picmip->value++;
Com_sprintf(pathname, sizeof(pathname), "env/%s%s.tga", skyname, suf[i]); image = (image_t *)GetSkyImage(skyname, suf[i],
r_palettedtexture->value, (findimage_t)Vk_FindImage);
sky_images[i] = Vk_FindImage(pathname, it_sky); if (!image)
if (!sky_images[i]) {
Com_sprintf(pathname, sizeof(pathname), "pics/Skies/%s%s.m8", skyname, suf[i]);
sky_images[i] = Vk_FindImage(pathname, it_sky);
}
if (!sky_images[i])
sky_images[i] = r_notexture;
if (vk_skymip->value || skyrotate)
{ // take less memory
vk_picmip->value--;
sky_min = 1.0 / 256;
sky_max = 255.0 / 256;
}
else
{ {
sky_min = 1.0 / 512; R_Printf(PRINT_ALL, "%s: can't load %s:%s sky\n",
sky_max = 511.0 / 512; __func__, skyname, suf[i]);
image = r_notexture;
} }
sky_images[i] = image;
} }
sky_min = 1.0 / 512;
sky_max = 511.0 / 512;
} }