{
// * 4 for the expansion from 0-255 to 0-1023 range,
// / 255 to scale down byte colors
- VectorMA(dlightcolor, ent->state_current.glowsize * (4.0f / 255.0f), (qbyte *)&d_8to24table[ent->state_current.glowcolor], dlightcolor);
+ VectorMA(dlightcolor, ent->state_current.glowsize * (4.0f / 255.0f), (qbyte *)&palette_complete[ent->state_current.glowcolor], dlightcolor);
}
// LordHavoc: customizable trail
if (ent->render.flags & RENDER_GLOWTRAIL)
colorStart = MSG_ReadByte ();
colorLength = MSG_ReadByte ();
CL_ParticleExplosion2 (pos, colorStart, colorLength);
- tempcolor = (qbyte *)&d_8to24table[(rand()%colorLength) + colorStart];
+ tempcolor = (qbyte *)&palette_complete[(rand()%colorLength) + colorStart];
CL_AllocDlight (NULL, pos, 350, tempcolor[0] * (1.0f / 255.0f), tempcolor[1] * (1.0f / 255.0f), tempcolor[2] * (1.0f / 255.0f), 700, 0.5);
S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
break;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
#else
- particlefonttexture = R_LoadTexture (particletexturepool, "particlefont", 256, 256, particletexturedata, TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE);
+ particlefonttexture = R_LoadTexture2D(particletexturepool, "particlefont", 256, 256, particletexturedata, TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE, NULL);
#endif
}
cl_videosoundresampledata = NULL;
cl_videotexturepool = R_AllocTexturePool();
- cl_videotexture = R_LoadTexture(cl_videotexturepool, "videotexture", cl_videoimagewidth, cl_videoimageheight, NULL, TEXTYPE_RGBA, TEXF_FRAGMENT);
+ cl_videotexture = R_LoadTexture2D(cl_videotexturepool, "videotexture", cl_videoimagewidth, cl_videoimageheight, NULL, TEXTYPE_RGBA, TEXF_FRAGMENT, NULL);
}
void CL_VideoStop(void)
#include "quakedef.h"
+#include "image.h"
cvar_t gl_mesh_maxverts = {0, "gl_mesh_maxverts", "1024"};
cvar_t gl_mesh_floatcolors = {0, "gl_mesh_floatcolors", "1"};
*/
#include "quakedef.h"
+#include "image.h"
cvar_t scr_conalpha = {CVAR_SAVE, "scr_conalpha", "1"};
buffer[i][3] = 255;
}
}
- return R_LoadTexture(drawtexturepool, "mousepointer", 16, 16, &buffer[0][0], TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE);
+ return R_LoadTexture2D(drawtexturepool, "mousepointer", 16, 16, &buffer[0][0], TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE, NULL);
}
// must match NUMCROSSHAIRS in r_crosshairs.c
data[i][3] = (qbyte) ((int) (in[i] - '0') * 255 / 7);
}
}
- return R_LoadTexture(drawtexturepool, va("crosshair%i", num), 16, 16, &data[0][0], TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE);
+ return R_LoadTexture2D(drawtexturepool, va("crosshair%i", num), 16, 16, &data[0][0], TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE, NULL);
}
/*
cachepichash[hashkey] = pic;
// load the pic from disk
- pic->tex = loadtextureimage(drawtexturepool, path, 0, 0, false, false, true);
+ pic->tex = loadtextureimage(drawtexturepool, path, 0, 0, false, TEXF_ALPHA | TEXF_PRECACHE);
if (pic->tex == NULL && !strncmp(path, "gfx/", 4))
{
// compatibility with older versions
- pic->tex = loadtextureimage(drawtexturepool, path + 4, 0, 0, false, false, true);
+ pic->tex = loadtextureimage(drawtexturepool, path + 4, 0, 0, false, TEXF_ALPHA | TEXF_PRECACHE);
// failed to find gfx/whatever.tga or similar, try the wad
if (pic->tex == NULL && (p = W_GetLumpName (path + 4)))
{
for (i = 0;i < 128 * 128;i++)
if (pix[i] == 0)
pix[i] = 255;
- pic->tex = R_LoadTexture (drawtexturepool, path, 128, 128, pix, TEXTYPE_QPALETTE, TEXF_ALPHA | TEXF_PRECACHE);
+ pic->tex = R_LoadTexture2D(drawtexturepool, path, 128, 128, pix, TEXTYPE_PALETTE, TEXF_ALPHA | TEXF_PRECACHE, palette_complete);
}
else
- pic->tex = R_LoadTexture (drawtexturepool, path, p->width, p->height, p->data, TEXTYPE_QPALETTE, TEXF_ALPHA | TEXF_PRECACHE);
+ pic->tex = R_LoadTexture2D(drawtexturepool, path, p->width, p->height, p->data, TEXTYPE_PALETTE, TEXF_ALPHA | TEXF_PRECACHE, palette_complete);
}
}
if (pic->tex == NULL && !strcmp(path, "ui/mousepointer.tga"))
pic->height = height;
if (pic->tex)
R_FreeTexture(pic->tex);
- pic->tex = R_LoadTexture (drawtexturepool, picname, width, height, pixels, TEXTYPE_RGBA, alpha ? TEXF_ALPHA : 0);
+ pic->tex = R_LoadTexture2D(drawtexturepool, picname, width, height, pixels, TEXTYPE_RGBA, alpha ? TEXF_ALPHA : 0, NULL);
return pic;
}
{
// 128-224 are backwards ranges
c = (ent->colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12;
- bcolor = (qbyte *) (&d_8to24table[c]);
+ bcolor = (qbyte *) (&palette_complete[c]);
pantsfullbright = c >= 224;
VectorScale(bcolor, (1.0f / 255.0f), pantscolor);
c = (ent->colormap & 0xF0);c += (c >= 128 && c < 224) ? 4 : 12;
- bcolor = (qbyte *) (&d_8to24table[c]);
+ bcolor = (qbyte *) (&palette_complete[c]);
shirtfullbright = c >= 224;
VectorScale(bcolor, (1.0f / 255.0f), shirtcolor);
}
R_Mesh_ResizeCheck(ent->model->numverts);
R_LerpMDLMD2Vertices(ent, varray_vertex, aliasvert_normals);
Mod_BuildTextureVectorsAndNormals(ent->model->numverts, ent->model->numtris, varray_vertex, ent->model->mdlmd2data_texcoords, ent->model->mdlmd2data_indices, aliasvert_svectors, aliasvert_tvectors, aliasvert_normals);
- R_Shadow_RenderLighting(ent->model->numverts, ent->model->numtris, ent->model->mdlmd2data_indices, aliasvert_svectors, aliasvert_tvectors, aliasvert_normals, ent->model->mdlmd2data_texcoords, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, skinframe->base, r_notexture, NULL, NULL);
+ R_Shadow_RenderLighting(ent->model->numverts, ent->model->numtris, ent->model->mdlmd2data_indices, aliasvert_svectors, aliasvert_tvectors, aliasvert_normals, ent->model->mdlmd2data_texcoords, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, skinframe->base, skinframe->gloss, skinframe->nmap, NULL);
}
int ZymoticLerpBones(int count, const zymbonematrix *bonebase, const frameblend_t *blend, const zymbone_t *bone)
float f, colorscale;
const surfmesh_t *mesh;
rmeshstate_t m;
- float alpha = ent->alpha * (surf->flags & SURF_DRAWNOALPHA ? 1 : r_wateralpha.value);
+ float alpha = ent->alpha * (surf->flags & SURF_WATERALPHA ? r_wateralpha.value : 1);
float modelorg[3];
+ texture_t *texture;
Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
R_Mesh_Matrix(&ent->matrix);
memset(&m, 0, sizeof(m));
- if (ent->effects & EF_ADDITIVE)
+ texture = surf->texinfo->texture->currentframe[ent->frame != 0];
+ if (texture->rendertype == SURFRENDER_ADD)
{
m.blendfunc1 = GL_SRC_ALPHA;
m.blendfunc2 = GL_ONE;
}
- else if (surf->currenttexture->fogtexture != NULL || alpha < 1)
+ else if (texture->rendertype == SURFRENDER_ALPHA)
{
m.blendfunc1 = GL_SRC_ALPHA;
m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
m.blendfunc1 = GL_ONE;
m.blendfunc2 = GL_ZERO;
}
- m.tex[0] = R_GetTexture(surf->currenttexture->texture);
+ m.tex[0] = R_GetTexture(texture->texture);
colorscale = r_colorscale;
if (gl_combine.integer)
{
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_SRC_ALPHA;
m.blendfunc2 = GL_ONE;
- m.tex[0] = R_GetTexture(surf->currenttexture->fogtexture);
+ m.tex[0] = R_GetTexture(texture->fogtexture);
R_Mesh_State(&m);
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
{
const msurface_t *surf;
vec3_t center;
- if ((r_wateralpha.value < 1 && !(texture->flags & SURF_DRAWNOALPHA)) || ent->effects & EF_ADDITIVE || texture->fogtexture)
+ if (texture->rendertype != SURFRENDER_OPAQUE)
{
for (surf = firstsurf;surf;surf = surf->texturechain)
{
const surfmesh_t *mesh;
rmeshstate_t m;
float modelorg[3];
+ texture_t *texture;
Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
memset(&m, 0, sizeof(m));
- if (ent->effects & EF_ADDITIVE)
+ texture = surf->texinfo->texture->currentframe[ent->frame != 0];
+ if (texture->rendertype == SURFRENDER_ADD)
{
m.blendfunc1 = GL_SRC_ALPHA;
m.blendfunc2 = GL_ONE;
}
- else if (surf->currenttexture->fogtexture != NULL || ent->alpha < 1)
+ else if (texture->rendertype == SURFRENDER_ALPHA)
{
m.blendfunc1 = GL_SRC_ALPHA;
m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
m.blendfunc1 = GL_ONE;
m.blendfunc2 = GL_ZERO;
}
- m.tex[0] = R_GetTexture(surf->currenttexture->texture);
+ m.tex[0] = R_GetTexture(texture->texture);
colorscale = r_colorscale;
if (gl_combine.integer)
{
const surfmesh_t *mesh;
rmeshstate_t m;
float modelorg[3];
+ texture_t *texture;
+ texture = surf->texinfo->texture->currentframe[ent->frame != 0];
Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_SRC_ALPHA;
m.blendfunc2 = GL_ONE;
- m.tex[0] = R_GetTexture(surf->currenttexture->glowtexture);
+ m.tex[0] = R_GetTexture(texture->glowtexture);
R_Mesh_State(&m);
GL_UseColorArray();
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
const surfmesh_t *mesh;
rmeshstate_t m;
float modelorg[3];
+ texture_t *texture;
+ texture = surf->texinfo->texture->currentframe[ent->frame != 0];
Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_SRC_ALPHA;
m.blendfunc2 = GL_ONE;
- m.tex[0] = R_GetTexture(surf->currenttexture->fogtexture);
+ m.tex[0] = R_GetTexture(texture->fogtexture);
R_Mesh_State(&m);
GL_UseColorArray();
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
const entity_render_t *ent = calldata1;
const msurface_t *surf = ent->model->surfaces + calldata2;
+ texture_t *texture;
+ texture = surf->texinfo->texture->currentframe[ent->frame != 0];
R_Mesh_Matrix(&ent->matrix);
RSurfShader_Wall_Pass_BaseVertex(ent, surf);
- if (surf->currenttexture->glowtexture)
+ if (texture->glowtexture)
RSurfShader_Wall_Pass_Glow(ent, surf);
if (fogenabled)
RSurfShader_Wall_Pass_Fog(ent, surf);
t = model->textures + i;
if (ent->effects & EF_ADDITIVE)
t->rendertype = SURFRENDER_ADD;
- else if (ent->alpha < 1 || t->flags & SURF_WATERALPHA || t->fogtexture != NULL)
+ else if (ent->alpha < 1 || (t->flags & SURF_WATERALPHA && r_wateralpha.value < 1) || t->fogtexture != NULL)
t->rendertype = SURFRENDER_ALPHA;
else
t->rendertype = SURFRENDER_OPAQUE;
{
R_Mesh_ResizeCheck(mesh->numverts);
memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
- R_Shadow_RenderLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, t->texture, r_notexture, NULL, NULL);
+ R_Shadow_RenderLighting(mesh->numverts, mesh->numtriangles, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals, mesh->str, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, t->texture, t->glosstexture, t->nmaptexture, NULL);
}
}
}
#include "quakedef.h"
+#include "image.h"
cvar_t r_max_size = {CVAR_SAVE, "r_max_size", "2048"};
cvar_t r_max_scrapsize = {CVAR_SAVE, "r_max_scrapsize", "256"};
}
textypeinfo_t;
-static textypeinfo_t textype_qpalette = {TEXTYPE_QPALETTE, 1, 4, GL_RGBA, 3};
-static textypeinfo_t textype_rgb = {TEXTYPE_RGB , 3, 3, GL_RGB , 3};
-static textypeinfo_t textype_rgba = {TEXTYPE_RGBA , 4, 4, GL_RGBA, 3};
-static textypeinfo_t textype_qpalette_alpha = {TEXTYPE_QPALETTE, 1, 4, GL_RGBA, 4};
-static textypeinfo_t textype_rgba_alpha = {TEXTYPE_RGBA , 4, 4, GL_RGBA, 4};
+static textypeinfo_t textype_palette = {TEXTYPE_PALETTE, 1, 4, GL_RGBA, 3};
+static textypeinfo_t textype_rgb = {TEXTYPE_RGB , 3, 3, GL_RGB , 3};
+static textypeinfo_t textype_rgba = {TEXTYPE_RGBA , 4, 4, GL_RGBA, 3};
+static textypeinfo_t textype_palette_alpha = {TEXTYPE_PALETTE, 1, 4, GL_RGBA, 4};
+static textypeinfo_t textype_rgba_alpha = {TEXTYPE_RGBA , 4, 4, GL_RGBA, 4};
// a tiling texture (most common type)
#define GLIMAGETYPE_TILE 0
textypeinfo_t *textype;
// one of the GLTEXTURETYPE_ values
int texturetype;
+ // palette if the texture is TEXTYPE_PALETTE
+ const unsigned int *palette;
}
gltexture_t;
{
switch(textype)
{
- case TEXTYPE_QPALETTE:
- return &textype_qpalette_alpha;
+ case TEXTYPE_PALETTE:
+ return &textype_palette_alpha;
case TEXTYPE_RGB:
Host_Error("R_GetTexTypeInfo: RGB format has no alpha, TEXF_ALPHA not allowed\n");
return NULL;
{
switch(textype)
{
- case TEXTYPE_QPALETTE:
- return &textype_qpalette;
+ case TEXTYPE_PALETTE:
+ return &textype_palette;
case TEXTYPE_RGB:
return &textype_rgb;
case TEXTYPE_RGBA:
memset(resizebuffer, 255, glt->width * glt->height * glt->image->depth * glt->image->bytesperpixel);
prevbuffer = resizebuffer;
}
- else if (glt->textype->textype == TEXTYPE_QPALETTE)
+ else if (glt->textype->textype == TEXTYPE_PALETTE)
{
// promote paletted to RGBA, so we only have to worry about RGB and
// RGBA in the rest of this code
R_MakeResizeBufferBigger(glt->image->width * glt->image->height * glt->image->depth * glt->image->bytesperpixel);
- Image_Copy8bitRGBA(prevbuffer, colorconvertbuffer, glt->width * glt->height * glt->depth, d_8to24table);
+ Image_Copy8bitRGBA(prevbuffer, colorconvertbuffer, glt->width * glt->height * glt->depth, glt->palette);
prevbuffer = colorconvertbuffer;
}
}
else
{
- if (glt->textype->textype == TEXTYPE_QPALETTE)
+ if (glt->textype->textype == TEXTYPE_PALETTE)
{
// promote paletted to RGBA, so we only have to worry about RGB and
// RGBA in the rest of this code
- Image_Copy8bitRGBA(prevbuffer, colorconvertbuffer, glt->width * glt->height * glt->depth, d_8to24table);
+ Image_Copy8bitRGBA(prevbuffer, colorconvertbuffer, glt->width * glt->height * glt->depth, glt->palette);
prevbuffer = colorconvertbuffer;
}
Con_Printf("R_UploadTexture: Texture %s already uploaded and destroyed. Can not upload original image again. Uploaded blank texture.\n", glt->identifier);
}
-static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, char *identifier, int width, int height, int depth, int sides, int flags, int textype, int texturetype, qbyte *data)
+static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int depth, int sides, int flags, int textype, int texturetype, const qbyte *data, const unsigned int *palette)
{
int i, size;
gltexture_t *glt;
// clear the alpha flag if the texture has no transparent pixels
switch(textype)
{
- case TEXTYPE_QPALETTE:
+ case TEXTYPE_PALETTE:
if (flags & TEXF_ALPHA)
{
flags &= ~TEXF_ALPHA;
{
for (i = 0;i < size;i++)
{
- if (data[i] == 255)
+ if (((qbyte *)&palette[data[i]])[3] == 255)
{
flags |= TEXF_ALPHA;
break;
glt->textype = texinfo;
glt->texturetype = texturetype;
glt->inputdatasize = size;
+ glt->palette = palette;
if (data)
{
return (rtexture_t *)glt;
}
-rtexture_t *R_LoadTexture(rtexturepool_t *rtexturepool, char *identifier, int width, int height, qbyte *data, int textype, int flags)
+rtexture_t *R_LoadTexture1D(rtexturepool_t *rtexturepool, const char *identifier, int width, const qbyte *data, int textype, int flags, const unsigned int *palette)
{
- return R_SetupTexture(rtexturepool, identifier, width, height, 1, 1, flags, textype, GLTEXTURETYPE_2D, data);
+ return R_SetupTexture(rtexturepool, identifier, width, 1, 1, 1, flags, textype, GLTEXTURETYPE_1D, data, palette);
}
-rtexture_t *R_LoadTexture1D(rtexturepool_t *rtexturepool, char *identifier, int width, qbyte *data, int textype, int flags)
+rtexture_t *R_LoadTexture2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, const qbyte *data, int textype, int flags, const unsigned int *palette)
{
- return R_SetupTexture(rtexturepool, identifier, width, 1, 1, 1, flags, textype, GLTEXTURETYPE_1D, data);
+ return R_SetupTexture(rtexturepool, identifier, width, height, 1, 1, flags, textype, GLTEXTURETYPE_2D, data, palette);
}
-rtexture_t *R_LoadTexture2D(rtexturepool_t *rtexturepool, char *identifier, int width, int height, qbyte *data, int textype, int flags)
+rtexture_t *R_LoadTexture3D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int depth, const qbyte *data, int textype, int flags, const unsigned int *palette)
{
- return R_SetupTexture(rtexturepool, identifier, width, height, 1, 1, flags, textype, GLTEXTURETYPE_2D, data);
+ return R_SetupTexture(rtexturepool, identifier, width, height, depth, 1, flags, textype, GLTEXTURETYPE_3D, data, palette);
}
-rtexture_t *R_LoadTexture3D(rtexturepool_t *rtexturepool, char *identifier, int width, int height, int depth, qbyte *data, int textype, int flags)
+rtexture_t *R_LoadTextureCubeMap(rtexturepool_t *rtexturepool, const char *identifier, int width, const qbyte *data, int textype, int flags, const unsigned int *palette)
{
- return R_SetupTexture(rtexturepool, identifier, width, height, depth, 1, flags, textype, GLTEXTURETYPE_3D, data);
-}
-
-rtexture_t *R_LoadTextureCubeMap(rtexturepool_t *rtexturepool, char *identifier, int width, qbyte *data, int textype, int flags)
-{
- return R_SetupTexture(rtexturepool, identifier, width, width, 1, 6, flags, textype, GLTEXTURETYPE_CUBEMAP, data);
+ return R_SetupTexture(rtexturepool, identifier, width, width, 1, 6, flags, textype, GLTEXTURETYPE_CUBEMAP, data, palette);
}
int R_TextureHasAlpha(rtexture_t *rt)
#define GL_TEXTURE_WRAP_S 0x2802
#define GL_TEXTURE_WRAP_T 0x2803
#define GL_TEXTURE_WRAP_R 0x8072
+#define GL_TEXTURE_BORDER_COLOR 0x1004
#define GL_TEXTURE_MAG_FILTER 0x2800
#define GL_TEXTURE_MIN_FILTER 0x2801
#define GL_UNPACK_ALIGNMENT 0x0CF5
extern void (GLAPIENTRY *qglStencilOp)(GLenum fail, GLenum zfail, GLenum zpass);
extern void (GLAPIENTRY *qglClearStencil)(GLint s);
-//extern void (GLAPIENTRY *qglTexEnvf)(GLenum target, GLenum pname, GLfloat param);
+extern void (GLAPIENTRY *qglTexEnvf)(GLenum target, GLenum pname, GLfloat param);
extern void (GLAPIENTRY *qglTexEnvi)(GLenum target, GLenum pname, GLint param);
-//extern void (GLAPIENTRY *qglTexParameterf)(GLenum target, GLenum pname, GLfloat param);
+extern void (GLAPIENTRY *qglTexParameterf)(GLenum target, GLenum pname, GLfloat param);
+extern void (GLAPIENTRY *qglTexParameterfv)(GLenum target, GLenum pname, GLfloat *params);
extern void (GLAPIENTRY *qglTexParameteri)(GLenum target, GLenum pname, GLint param);
extern void (GLAPIENTRY *qglGenTextures)(GLsizei n, GLuint *textures);
#include "quakedef.h"
+#include "image.h"
int image_width;
int image_height;
-void Image_GammaRemapRGB(qbyte *in, qbyte *out, int pixels, qbyte *gammar, qbyte *gammag, qbyte *gammab)
+void Image_GammaRemapRGB(const qbyte *in, qbyte *out, int pixels, const qbyte *gammar, const qbyte *gammag, const qbyte *gammab)
{
while (pixels--)
{
}
// note: pal must be 32bit color
-void Image_Copy8bitRGBA(qbyte *in, qbyte *out, int pixels, int *pal)
+void Image_Copy8bitRGBA(const qbyte *in, qbyte *out, int pixels, const unsigned int *pal)
{
int *iout = (void *)out;
while (pixels >= 8)
LoadPCX
============
*/
-qbyte* LoadPCX (qbyte *f, int matchwidth, int matchheight)
+qbyte* LoadPCX (const qbyte *f, int matchwidth, int matchheight)
{
pcx_t pcx;
- qbyte *palette, *a, *b, *image_rgba, *fin, *pbuf, *enddata;
+ qbyte *a, *b, *image_rgba, *pbuf;
+ const qbyte *palette, *fin, *enddata;
int x, y, x2, dataByte;
if (loadsize < sizeof(pcx) + 768)
LoadTGA
=============
*/
-qbyte *LoadTGA (qbyte *f, int matchwidth, int matchheight)
+qbyte *LoadTGA (const qbyte *f, int matchwidth, int matchheight)
{
int x, y, row_inc;
unsigned char red, green, blue, alpha, run, runlen;
- qbyte *pixbuf, *image_rgba, *fin, *enddata;
+ qbyte *pixbuf, *image_rgba;
+ const qbyte *fin, *enddata;
if (loadsize < 18+3)
return NULL;
LoadLMP
============
*/
-qbyte *LoadLMP (qbyte *f, int matchwidth, int matchheight)
+qbyte *LoadLMP (const qbyte *f, int matchwidth, int matchheight)
{
qbyte *image_rgba;
int width, height;
Con_Printf("LoadLMP: not enough memory for %i by %i image\n", image_width, image_height);
return NULL;
}
- Image_Copy8bitRGBA(f + 8, image_rgba, image_width * image_height, d_8to24table);
+ Image_Copy8bitRGBA(f + 8, image_rgba, image_width * image_height, palette_complete);
return image_rgba;
}
LoadLMP
============
*/
-qbyte *LoadLMPAs8Bit (qbyte *f, int matchwidth, int matchheight)
+qbyte *LoadLMPAs8Bit (const qbyte *f, int matchwidth, int matchheight)
{
qbyte *image_8bit;
int width, height;
return image_8bit;
}
-void Image_StripImageExtension (char *in, char *out)
+void Image_StripImageExtension (const char *in, char *out)
{
- char *end, *temp;
+ const char *end, *temp;
end = in + strlen(in);
if ((end - in) >= 4)
{
strcpy(out, in);
}
-qbyte *loadimagepixels (char *filename, qboolean complain, int matchwidth, int matchheight)
+qbyte *loadimagepixels (const char *filename, qboolean complain, int matchwidth, int matchheight)
{
qbyte *f, *data;
char basename[256], name[256], *c;
return NULL;
}
-int image_makemask (qbyte *in, qbyte *out, int size)
+int image_makemask (const qbyte *in, qbyte *out, int size)
{
- int i, count;
+ int i, count;
count = 0;
for (i = 0;i < size;i++)
{
return count;
}
-qbyte* loadimagepixelsmask (char* filename, qboolean complain, int matchwidth, int matchheight)
+qbyte* loadimagepixelsmask (const char *filename, qboolean complain, int matchwidth, int matchheight)
{
qbyte *in, *data;
in = data = loadimagepixels(filename, complain, matchwidth, matchheight);
}
}
-rtexture_t *loadtextureimage (rtexturepool_t *pool, char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap, qboolean precache)
+rtexture_t *loadtextureimage (rtexturepool_t *pool, const char *filename, int matchwidth, int matchheight, qboolean complain, int flags)
{
qbyte *data;
rtexture_t *rt;
if (!(data = loadimagepixels (filename, complain, matchwidth, matchheight)))
return 0;
- rt = R_LoadTexture (pool, filename, image_width, image_height, data, TEXTYPE_RGBA, TEXF_ALPHA | (mipmap ? TEXF_MIPMAP : 0) | (precache ? TEXF_PRECACHE : 0));
+ rt = R_LoadTexture2D(pool, filename, image_width, image_height, data, TEXTYPE_RGBA, flags, NULL);
Mem_Free(data);
return rt;
}
-rtexture_t *loadtextureimagemask (rtexturepool_t *pool, char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap, qboolean precache)
+rtexture_t *loadtextureimagemask (rtexturepool_t *pool, const char *filename, int matchwidth, int matchheight, qboolean complain, int flags)
{
qbyte *data;
rtexture_t *rt;
if (!(data = loadimagepixelsmask (filename, complain, matchwidth, matchheight)))
return 0;
- rt = R_LoadTexture (pool, filename, image_width, image_height, data, TEXTYPE_RGBA, TEXF_ALPHA | (mipmap ? TEXF_MIPMAP : 0) | (precache ? TEXF_PRECACHE : 0));
+ rt = R_LoadTexture2D(pool, filename, image_width, image_height, data, TEXTYPE_RGBA, flags, NULL);
Mem_Free(data);
return rt;
}
rtexture_t *image_masktex;
-rtexture_t *loadtextureimagewithmask (rtexturepool_t *pool, char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap, qboolean precache)
+rtexture_t *image_nmaptex;
+rtexture_t *loadtextureimagewithmask (rtexturepool_t *pool, const char *filename, int matchwidth, int matchheight, qboolean complain, int flags)
{
- int count;
qbyte *data;
- char *filename2;
rtexture_t *rt;
image_masktex = NULL;
+ image_nmaptex = NULL;
if (!(data = loadimagepixels (filename, complain, matchwidth, matchheight)))
return 0;
- rt = R_LoadTexture (pool, filename, image_width, image_height, data, TEXTYPE_RGBA, TEXF_ALPHA | (mipmap ? TEXF_MIPMAP : 0) | (precache ? TEXF_PRECACHE : 0));
- count = image_makemask(data, data, image_width * image_height);
- if (count)
- {
- filename2 = Mem_Alloc(tempmempool, strlen(filename) + 6);
- sprintf(filename2, "%s_mask", filename);
- image_masktex = R_LoadTexture (pool, filename2, image_width, image_height, data, TEXTYPE_RGBA, TEXF_ALPHA | (mipmap ? TEXF_MIPMAP : 0) | (precache ? TEXF_PRECACHE : 0));
- Mem_Free(filename2);
- }
+
+ rt = R_LoadTexture2D(pool, filename, image_width, image_height, data, TEXTYPE_RGBA, flags, NULL);
+
+ if (flags & TEXF_ALPHA && image_makemask(data, data, image_width * image_height))
+ image_masktex = R_LoadTexture2D(pool, va("%s_mask", filename), image_width, image_height, data, TEXTYPE_RGBA, flags, NULL);
+
Mem_Free(data);
return rt;
}
-qboolean Image_WriteTGARGB_preflipped (char *filename, int width, int height, qbyte *data)
+rtexture_t *loadtextureimagewithmaskandnmap (rtexturepool_t *pool, const char *filename, int matchwidth, int matchheight, qboolean complain, int flags, float bumpscale)
+{
+ qbyte *data, *data2;
+ rtexture_t *rt;
+ image_masktex = NULL;
+ image_nmaptex = NULL;
+ if (!(data = loadimagepixels (filename, complain, matchwidth, matchheight)))
+ return 0;
+
+ data2 = Mem_Alloc(tempmempool, image_width * image_height * 4);
+
+ rt = R_LoadTexture2D(pool, filename, image_width, image_height, data, TEXTYPE_RGBA, flags, NULL);
+
+ Image_HeightmapToNormalmap(data, data2, image_width, image_height, (flags & TEXF_CLAMP) != 0, bumpscale);
+ image_nmaptex = R_LoadTexture2D(pool, va("%s_nmap", filename), image_width, image_height, data2, TEXTYPE_RGBA, flags, NULL);
+
+ if (flags & TEXF_ALPHA && image_makemask(data, data2, image_width * image_height))
+ image_masktex = R_LoadTexture2D(pool, va("%s_mask", filename), image_width, image_height, data2, TEXTYPE_RGBA, flags, NULL);
+
+ Mem_Free(data2);
+
+ Mem_Free(data);
+ return rt;
+}
+
+qboolean Image_WriteTGARGB_preflipped (const char *filename, int width, int height, const qbyte *data)
{
qboolean ret;
- qbyte *buffer, *in, *out, *end;
+ qbyte *buffer, *out;
+ const qbyte *in, *end;
buffer = Mem_Alloc(tempmempool, width*height*3 + 18);
return ret;
}
-void Image_WriteTGARGB (char *filename, int width, int height, qbyte *data)
+void Image_WriteTGARGB (const char *filename, int width, int height, const qbyte *data)
{
int y;
- qbyte *buffer, *in, *out, *end;
+ qbyte *buffer, *out;
+ const qbyte *in, *end;
buffer = Mem_Alloc(tempmempool, width*height*3 + 18);
Mem_Free(buffer);
}
-void Image_WriteTGARGBA (char *filename, int width, int height, qbyte *data)
+void Image_WriteTGARGBA (const char *filename, int width, int height, const qbyte *data)
{
int y;
- qbyte *buffer, *in, *out, *end;
+ qbyte *buffer, *out;
+ const qbyte *in, *end;
buffer = Mem_Alloc(tempmempool, width*height*4 + 18);
Mem_Free(buffer);
}
-qboolean Image_CheckAlpha(qbyte *data, int size, qboolean rgba)
+qboolean Image_CheckAlpha(const qbyte *data, int size, qboolean rgba)
{
- qbyte *end;
+ const qbyte *end;
if (rgba)
{
// check alpha bytes
return 0;
}
-static void Image_Resample32LerpLine (qbyte *in, qbyte *out, int inwidth, int outwidth)
+static void Image_Resample32LerpLine (const qbyte *in, qbyte *out, int inwidth, int outwidth)
{
int j, xi, oldx = 0, f, fstep, endx, lerp;
fstep = (int) (inwidth*65536.0f/outwidth);
}
}
-static void Image_Resample24LerpLine (qbyte *in, qbyte *out, int inwidth, int outwidth)
+static void Image_Resample24LerpLine (const qbyte *in, qbyte *out, int inwidth, int outwidth)
{
int j, xi, oldx = 0, f, fstep, endx, lerp;
fstep = (int) (inwidth*65536.0f/outwidth);
mempool_t *resamplemempool = NULL;
#define LERPBYTE(i) r = resamplerow1[i];out[i] = (qbyte) ((((resamplerow2[i] - r) * lerp) >> 16) + r)
-void Image_Resample32Lerp(void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight)
+void Image_Resample32Lerp(const void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight)
{
int i, j, r, yi, oldy, f, fstep, lerp, endy = (inheight-1), inwidth4 = inwidth*4, outwidth4 = outwidth*4;
- qbyte *inrow, *out;
+ qbyte *out;
+ const qbyte *inrow;
out = outdata;
fstep = (int) (inheight*65536.0f/outheight);
}
}
-void Image_Resample32Nearest(void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight)
+void Image_Resample32Nearest(const void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight)
{
int i, j;
unsigned frac, fracstep;
}
}
-void Image_Resample24Lerp(void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight)
+void Image_Resample24Lerp(const void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight)
{
int i, j, r, yi, oldy, f, fstep, lerp, endy = (inheight-1), inwidth3 = inwidth * 3, outwidth3 = outwidth * 3;
- qbyte *inrow, *out;
+ qbyte *out;
+ const qbyte *inrow;
out = outdata;
fstep = (int) (inheight*65536.0f/outheight);
}
}
-void Image_Resample24Nolerp(void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight)
+void Image_Resample24Nolerp(const void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight)
{
int i, j, f, inwidth3 = inwidth * 3;
unsigned frac, fracstep;
Image_Resample
================
*/
-void Image_Resample (void *indata, int inwidth, int inheight, int indepth, void *outdata, int outwidth, int outheight, int outdepth, int bytesperpixel, int quality)
+void Image_Resample (const void *indata, int inwidth, int inheight, int indepth, void *outdata, int outwidth, int outheight, int outdepth, int bytesperpixel, int quality)
{
if (indepth != 1 || outdepth != 1)
Sys_Error("Image_Resample: 3D resampling not supported\n");
}
// in can be the same as out
-void Image_MipReduce(qbyte *in, qbyte *out, int *width, int *height, int *depth, int destwidth, int destheight, int destdepth, int bytesperpixel)
+void Image_MipReduce(const qbyte *in, qbyte *out, int *width, int *height, int *depth, int destwidth, int destheight, int destdepth, int bytesperpixel)
{
int x, y, nextrow;
if (*depth != 1 || destdepth != 1)
}
}
+void Image_HeightmapToNormalmap(const unsigned char *inpixels, unsigned char *outpixels, int width, int height, int clamp, float bumpscale)
+{
+ int x, y;
+ const unsigned char *p0, *p1, *p2;
+ unsigned char *out;
+ float iwidth, iheight, ibumpscale, n[3];
+ iwidth = 1.0f / width;
+ iheight = 1.0f / height;
+ ibumpscale = (255.0f * 3.0f) / (bumpscale * 16.0f);
+ out = outpixels;
+ for (y = 0;y < height;y++)
+ {
+ for (x = 0;x < width;x++)
+ {
+ p0 = inpixels + (y * width + x) * 4;
+ if (x == width - 1)
+ {
+ if (clamp)
+ p1 = inpixels + (y * width + x) * 4;
+ else
+ p1 = inpixels + (y * width) * 4;
+ }
+ else
+ p1 = inpixels + (y * width + x + 1) * 4;
+ if (y == height - 1)
+ {
+ if (clamp)
+ p2 = inpixels + (y * width + x) * 4;
+ else
+ p2 = inpixels + x * 4;
+ }
+ else
+ p2 = inpixels + ((y + 1) * width + x) * 4;
+ /*
+ dv[0][0] = iwidth;
+ dv[0][1] = 0;
+ dv[0][2] = ((p1[0] + p1[1] + p1[2]) * ibumpscale) - ((p0[0] + p0[1] + p0[2]) * ibumpscale);
+ dv[1][0] = 0;
+ dv[1][1] = iheight;
+ dv[1][2] = ((p2[0] + p2[1] + p2[2]) * ibumpscale) - ((p0[0] + p0[1] + p0[2]) * ibumpscale);
+ n[0] = dv[0][1]*dv[1][2]-dv[0][2]*dv[1][1];
+ n[1] = dv[0][2]*dv[1][0]-dv[0][0]*dv[1][2];
+ n[2] = dv[0][0]*dv[1][1]-dv[0][1]*dv[1][0];
+ */
+ n[0] = ((p0[0] + p0[1] + p0[2]) - (p1[0] + p1[1] + p1[2]));
+ n[1] = ((p0[0] + p0[1] + p0[2]) - (p2[0] + p2[1] + p2[2]));
+ n[2] = ibumpscale;
+ VectorNormalize(n);
+ out[0] = 128.0f + n[0] * 127.0f;
+ out[1] = 128.0f + n[1] * 127.0f;
+ out[2] = 128.0f + n[2] * 127.0f;
+ out[3] = 255;
+ out += 4;
+ }
+ }
+}
#define IMAGE_H
// applies gamma correction to RGB pixels, in can be the same as out
-void Image_GammaRemapRGB(qbyte *in, qbyte *out, int pixels, qbyte *gammar, qbyte *gammag, qbyte *gammab);
+void Image_GammaRemapRGB(const qbyte *in, qbyte *out, int pixels, const qbyte *gammar, const qbyte *gammag, const qbyte *gammab);
// converts 8bit image data to RGBA, in can not be the same as out
-void Image_Copy8bitRGBA(qbyte *in, qbyte *out, int pixels, int *pal);
+void Image_Copy8bitRGBA(const qbyte *in, qbyte *out, int pixels, const unsigned int *pal);
// makes a RGBA mask from RGBA input, in can be the same as out
-int image_makemask (qbyte *in, qbyte *out, int size);
+int image_makemask (const qbyte *in, qbyte *out, int size);
// loads a texture, as pixel data
-qbyte *loadimagepixels (char* filename, qboolean complain, int matchwidth, int matchheight);
+qbyte *loadimagepixels (const char *filename, qboolean complain, int matchwidth, int matchheight);
// loads a texture, as a texture
-rtexture_t *loadtextureimage (rtexturepool_t *pool, char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap, qboolean precache);
+rtexture_t *loadtextureimage (rtexturepool_t *pool, const char *filename, int matchwidth, int matchheight, qboolean complain, int flags);
// loads a texture's alpha mask, as pixel data
-qbyte *loadimagepixelsmask (char* filename, qboolean complain, int matchwidth, int matchheight);
+qbyte *loadimagepixelsmask (const char *filename, qboolean complain, int matchwidth, int matchheight);
// loads a texture's alpha mask, as a texture
-rtexture_t *loadtextureimagemask (rtexturepool_t *pool, char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap, qboolean precache);
+rtexture_t *loadtextureimagemask (rtexturepool_t *pool, const char *filename, int matchwidth, int matchheight, qboolean complain, int flags);
// loads a texture and it's alpha mask at once (NULL if it has no translucent pixels)
rtexture_t *image_masktex;
-rtexture_t *loadtextureimagewithmask (rtexturepool_t *pool, char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap, qboolean precache);
+rtexture_t *image_nmaptex;
+rtexture_t *loadtextureimagewithmask (rtexturepool_t *pool, const char *filename, int matchwidth, int matchheight, qboolean complain, int flags);
+rtexture_t *loadtextureimagewithmaskandnmap (rtexturepool_t *pool, const char *filename, int matchwidth, int matchheight, qboolean complain, int flags, float bumpscale);
// writes a RGB TGA that is already upside down (which TGA wants)
-qboolean Image_WriteTGARGB_preflipped (char *filename, int width, int height, qbyte *data);
+qboolean Image_WriteTGARGB_preflipped (const char *filename, int width, int height, const qbyte *data);
// writes a RGB TGA
-void Image_WriteTGARGB (char *filename, int width, int height, qbyte *data);
+void Image_WriteTGARGB (const char *filename, int width, int height, const qbyte *data);
// writes a RGBA TGA
-void Image_WriteTGARGBA (char *filename, int width, int height, qbyte *data);
+void Image_WriteTGARGBA (const char *filename, int width, int height, const qbyte *data);
// returns true if the image has some translucent pixels
-qboolean Image_CheckAlpha(qbyte *data, int size, qboolean rgba);
+qboolean Image_CheckAlpha(const qbyte *data, int size, qboolean rgba);
// resizes the image (in can not be the same as out)
-void Image_Resample (void *indata, int inwidth, int inheight, int indepth, void *outdata, int outwidth, int outheight, int outdepth, int bytesperpixel, int quality);
+void Image_Resample (const void *indata, int inwidth, int inheight, int indepth, void *outdata, int outwidth, int outheight, int outdepth, int bytesperpixel, int quality);
// scales the image down by a power of 2 (in can be the same as out)
-void Image_MipReduce(qbyte *in, qbyte *out, int *width, int *height, int *depth, int destwidth, int destheight, int destdepth, int bytesperpixel);
+void Image_MipReduce(const qbyte *in, qbyte *out, int *width, int *height, int *depth, int destwidth, int destheight, int destdepth, int bytesperpixel);
// only used by menuplyr coloring
-qbyte *LoadLMPAs8Bit (qbyte *f, int matchwidth, int matchheight);
+qbyte *LoadLMPAs8Bit (const qbyte *f, int matchwidth, int matchheight);
+
+void Image_HeightmapToNormalmap(const unsigned char *inpixels, unsigned char *outpixels, int width, int height, int clamp, float bumpscale);
#endif
*/
#include "quakedef.h"
+#include "image.h"
void (*vid_menudrawfn)(void);
void (*vid_menukeyfn)(int key);
M_BuildTranslationTable (menuplyr_top*16, menuplyr_bottom*16);
for (i = 0;i < menuplyr_width * menuplyr_height;i++)
- trans[i] = d_8to24table[translation[pixels[i]]];
+ trans[i] = palette_complete[translation[pixels[i]]];
Draw_NewPic("gfx/menuplyr.lmp", menuplyr_width, menuplyr_height, true, (qbyte *)trans);
}
*/
#include "quakedef.h"
+#include "image.h"
static cvar_t r_mipskins = {CVAR_SAVE, "r_mipskins", "0"};
}
}
-static rtexture_t *GL_SkinSplitShirt(qbyte *in, qbyte *out, int width, int height, int bits, char *name, int precache)
+static rtexture_t *GL_TextureForSkinLayer(const qbyte *in, int width, int height, const char *name, const unsigned int *palette, int precache)
{
- int i, pixels, passed;
- qbyte pixeltest[16];
- for (i = 0;i < 16;i++)
- pixeltest[i] = (bits & (1 << i)) != 0;
- pixels = width*height;
- passed = 0;
- while(pixels--)
- {
- if (pixeltest[*in >> 4] && *in != 0 && *in != 255)
- {
- passed++;
- // turn to white while copying
- if (*in >= 128 && *in < 224) // backwards ranges
- *out = (*in & 15) ^ 15;
- else
- *out = *in & 15;
- }
- else
- *out = 0;
- in++;
- out++;
- }
- if (passed)
- return R_LoadTexture (loadmodel->texturepool, name, width, height, out - width*height, TEXTYPE_QPALETTE, (r_mipskins.integer ? TEXF_MIPMAP : 0) | (precache ? TEXF_PRECACHE : 0));
- else
- return NULL;
-}
-
-static rtexture_t *GL_SkinSplit(qbyte *in, qbyte *out, int width, int height, int bits, char *name, int precache)
-{
- int i, pixels, passed;
- qbyte pixeltest[16];
- for (i = 0;i < 16;i++)
- pixeltest[i] = (bits & (1 << i)) != 0;
- pixels = width*height;
- passed = 0;
- while(pixels--)
- {
- if (pixeltest[*in >> 4] && *in != 0 && *in != 255)
- {
- passed++;
- *out = *in;
- }
- else
- *out = 0;
- in++;
- out++;
- }
- if (passed)
- return R_LoadTexture (loadmodel->texturepool, name, width, height, out - width*height, TEXTYPE_QPALETTE, (r_mipskins.integer ? TEXF_MIPMAP : 0) | (precache ? TEXF_PRECACHE : 0));
- else
- return NULL;
+ int i;
+ for (i = 0;i < width*height;i++)
+ if (((qbyte *)&palette[in[i]])[3] > 0)
+ return R_LoadTexture2D (loadmodel->texturepool, name, width, height, in, TEXTYPE_PALETTE, (r_mipskins.integer ? TEXF_MIPMAP : 0) | (precache ? TEXF_PRECACHE : 0), palette);
+ return NULL;
}
static int Mod_LoadExternalSkin (char *basename, skinframe_t *skinframe, int precache)
{
- skinframe->base = loadtextureimagewithmask(loadmodel->texturepool, va("%s_normal", basename), 0, 0, false, r_mipskins.integer, precache);
- skinframe->fog = image_masktex;
+ skinframe->base = loadtextureimagewithmaskandnmap(loadmodel->texturepool, va("%s_normal", basename), 0, 0, false, TEXF_ALPHA | (precache ? TEXF_PRECACHE : 0) | (r_mipskins.integer ? TEXF_MIPMAP : 0), 1);
if (!skinframe->base)
- {
- skinframe->base = loadtextureimagewithmask(loadmodel->texturepool, basename, 0, 0, false, r_mipskins.integer, precache);
- skinframe->fog = image_masktex;
- }
- skinframe->pants = loadtextureimage(loadmodel->texturepool, va("%s_pants" , basename), 0, 0, false, r_mipskins.integer, precache);
- skinframe->shirt = loadtextureimage(loadmodel->texturepool, va("%s_shirt" , basename), 0, 0, false, r_mipskins.integer, precache);
- skinframe->glow = loadtextureimage(loadmodel->texturepool, va("%s_glow" , basename), 0, 0, false, r_mipskins.integer, precache);
+ skinframe->base = loadtextureimagewithmaskandnmap(loadmodel->texturepool, basename, 0, 0, false, TEXF_ALPHA | (precache ? TEXF_PRECACHE : 0) | (r_mipskins.integer ? TEXF_MIPMAP : 0), 1);
+ skinframe->fog = image_masktex;
+ skinframe->nmap = image_nmaptex;
+ skinframe->gloss = loadtextureimage(loadmodel->texturepool, va("%s_gloss" , basename), 0, 0, false, TEXF_ALPHA | (precache ? TEXF_PRECACHE : 0) | (r_mipskins.integer ? TEXF_MIPMAP : 0));
+ skinframe->pants = loadtextureimage(loadmodel->texturepool, va("%s_pants" , basename), 0, 0, false, TEXF_ALPHA | (precache ? TEXF_PRECACHE : 0) | (r_mipskins.integer ? TEXF_MIPMAP : 0));
+ skinframe->shirt = loadtextureimage(loadmodel->texturepool, va("%s_shirt" , basename), 0, 0, false, TEXF_ALPHA | (precache ? TEXF_PRECACHE : 0) | (r_mipskins.integer ? TEXF_MIPMAP : 0));
+ skinframe->glow = loadtextureimage(loadmodel->texturepool, va("%s_glow" , basename), 0, 0, false, TEXF_ALPHA | (precache ? TEXF_PRECACHE : 0) | (r_mipskins.integer ? TEXF_MIPMAP : 0));
skinframe->merged = NULL;
return skinframe->base != NULL || skinframe->pants != NULL || skinframe->shirt != NULL || skinframe->glow != NULL;
}
-static int Mod_LoadInternalSkin (char *basename, qbyte *skindata, qbyte *skintemp, int width, int height, skinframe_t *skinframe, int precache)
+static int Mod_LoadInternalSkin (char *basename, qbyte *skindata, int width, int height, skinframe_t *skinframe, int precache)
{
- if (!skindata || !skintemp)
+ qbyte *temp1, *temp2;
+ if (!skindata)
return false;
- skinframe->pants = GL_SkinSplitShirt(skindata, skintemp, width, height, 0x0040, va("%s_pants", basename), false); // pants
- skinframe->shirt = GL_SkinSplitShirt(skindata, skintemp, width, height, 0x0002, va("%s_shirt", basename), false); // shirt
- skinframe->glow = GL_SkinSplit (skindata, skintemp, width, height, 0xC000, va("%s_glow", basename), precache); // glow
+ temp1 = Mem_Alloc(loadmodel->mempool, width * height * 8);
+ temp2 = temp1 + width * height * 4;
+ Image_Copy8bitRGBA(skindata, temp1, width * height, palette_nofullbrights);
+ Image_HeightmapToNormalmap(temp1, temp2, width, height, false, 1);
+ skinframe->nmap = R_LoadTexture2D(loadmodel->texturepool, va("%s_nmap", basename), width, height, temp2, TEXTYPE_RGBA, (r_mipskins.integer ? TEXF_MIPMAP : 0) | (precache ? TEXF_PRECACHE : 0), NULL);
+ Mem_Free(temp1);
+ skinframe->gloss = NULL;
+ skinframe->pants = GL_TextureForSkinLayer(skindata, width, height, va("%s_pants", basename), palette_pantsaswhite, false); // pants
+ skinframe->shirt = GL_TextureForSkinLayer(skindata, width, height, va("%s_shirt", basename), palette_shirtaswhite, false); // shirt
+ skinframe->glow = GL_TextureForSkinLayer(skindata, width, height, va("%s_glow", basename), palette_onlyfullbrights, precache); // glow
if (skinframe->pants || skinframe->shirt)
{
- skinframe->base = GL_SkinSplit (skindata, skintemp, width, height, 0x3FBD, va("%s_normal", basename), false); // normal (no special colors)
- skinframe->merged = GL_SkinSplit (skindata, skintemp, width, height, 0x3FFF, va("%s_body", basename), precache); // body (normal + pants + shirt, but not glow)
+ skinframe->base = GL_TextureForSkinLayer(skindata, width, height, va("%s_normal", basename), palette_nocolormapnofullbrights, false); // normal (no special colors)
+ skinframe->merged = GL_TextureForSkinLayer(skindata, width, height, va("%s_body", basename), palette_nofullbrights, precache); // body (normal + pants + shirt, but not glow)
}
else
- skinframe->base = GL_SkinSplit (skindata, skintemp, width, height, 0x3FFF, va("%s_base", basename), precache); // no special colors
+ skinframe->base = GL_TextureForSkinLayer(skindata, width, height, va("%s_base", basename), palette_nofullbrights, precache); // no special colors
// quake model skins don't have alpha
skinframe->fog = NULL;
return true;
float scales, scalet, scale[3], translate[3], interval;
qbyte *datapointer, *startframes, *startskins;
char name[MAX_QPATH];
- qbyte *skintemp = NULL;
skinframe_t tempskinframe;
animscene_t *tempskinscenes;
skinframe_t *tempskinframes;
}
// load the skins
- skintemp = Mem_Alloc(tempmempool, skinwidth * skinheight);
loadmodel->skinscenes = Mem_Alloc(loadmodel->mempool, loadmodel->numskins * sizeof(animscene_t));
loadmodel->skinframes = Mem_Alloc(loadmodel->mempool, totalskins * sizeof(skinframe_t));
totalskins = 0;
else
sprintf (name, "%s_%i", loadmodel->name, i);
if (!Mod_LoadExternalSkin(name, loadmodel->skinframes + totalskins, i == 0))
- Mod_LoadInternalSkin(name, (qbyte *)datapointer, skintemp, skinwidth, skinheight, loadmodel->skinframes + totalskins, i == 0);
+ Mod_LoadInternalSkin(name, (qbyte *)datapointer, skinwidth, skinheight, loadmodel->skinframes + totalskins, i == 0);
datapointer += skinwidth * skinheight;
totalskins++;
}
}
- Mem_Free(skintemp);
// check for skins that don't exist in the model, but do exist as external images
// (this was added because yummyluv kept pestering me about support for it)
for (;;)
inskin = (void*)(base + LittleLong(pinmodel->ofs_skins));
if (loadmodel->numskins)
{
- loadmodel->skinscenes = Mem_Alloc(loadmodel->mempool, sizeof(animscene_t) * loadmodel->numskins);
- loadmodel->skinframes = Mem_Alloc(loadmodel->mempool, sizeof(skinframe_t) * loadmodel->numskins);
+ loadmodel->skinscenes = Mem_Alloc(loadmodel->mempool, sizeof(animscene_t) * loadmodel->numskins + sizeof(skinframe_t) * loadmodel->numskins);
+ loadmodel->skinframes = (void *)(loadmodel->skinscenes + loadmodel->numskins);
for (i = 0;i < loadmodel->numskins;i++)
{
loadmodel->skinscenes[i].firstframe = i;
loadmodel->skinscenes[i].framecount = 1;
loadmodel->skinscenes[i].loop = true;
loadmodel->skinscenes[i].framerate = 10;
- loadmodel->skinframes[i].base = loadtextureimagewithmask (loadmodel->texturepool, inskin, 0, 0, true, r_mipskins.integer, true);
+ loadmodel->skinframes[i].base = loadtextureimagewithmaskandnmap (loadmodel->texturepool, inskin, 0, 0, true, TEXF_ALPHA | TEXF_PRECACHE | (r_mipskins.integer ? TEXF_MIPMAP : 0), 1);
loadmodel->skinframes[i].fog = image_masktex;
+ loadmodel->skinframes[i].nmap = image_nmaptex;
+ loadmodel->skinframes[i].gloss = NULL;
loadmodel->skinframes[i].pants = NULL;
loadmodel->skinframes[i].shirt = NULL;
loadmodel->skinframes[i].glow = NULL;
// zymlump_t lump_shaders; // char shadername[numshaders][32]; // shaders used on this model
shadername = (void *) (pheader->lump_shaders.start + pbase);
for (i = 0;i < pheader->numshaders;i++)
- loadmodel->zymdata_textures[i] = loadtextureimage(loadmodel->texturepool, shadername + i * 32, 0, 0, true, r_mipskins.integer, true);
+ loadmodel->zymdata_textures[i] = loadtextureimage(loadmodel->texturepool, shadername + i * 32, 0, 0, true, TEXF_ALPHA | TEXF_PRECACHE | (r_mipskins.integer ? TEXF_MIPMAP : 0));
}
{
*/
#include "quakedef.h"
+#include "image.h"
// note: model_shared.c sets up r_notexture, and r_surf_notexture
data[y][x][3] = 255;
}
}
- detailtextures[i] = R_LoadTexture(detailtexturepool, va("detailtexture%i", i), DETAILRESOLUTION, DETAILRESOLUTION, &data[0][0][0], TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_PRECACHE);
+ detailtextures[i] = R_LoadTexture2D(detailtexturepool, va("detailtexture%i", i), DETAILRESOLUTION, DETAILRESOLUTION, &data[0][0][0], TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_PRECACHE, NULL);
}
}
miptex_t *dmiptex;
texture_t *tx, *tx2, *anims[10], *altanims[10];
dmiptexlump_t *m;
- qbyte *data, *mtdata, *data2;
+ qbyte *data, *mtdata;
char name[256];
+ qbyte *basepixels, *bumppixels, *nmappixels, *glosspixels, *glowpixels, *maskpixels;
+ int basepixels_width, basepixels_height, bumppixels_width, bumppixels_height;
+ int nmappixels_width, nmappixels_height, glosspixels_width, glosspixels_height;
+ int glowpixels_width, glowpixels_height, maskpixels_width, maskpixels_height;
+ rtexture_t *detailtexture;
loadmodel->textures = NULL;
Con_Printf("warning: unnamed texture in %s, renaming to %s\n", loadmodel->name, tx->name);
}
+ basepixels = NULL;
+ bumppixels = NULL;
+ nmappixels = NULL;
+ glosspixels = NULL;
+ glowpixels = NULL;
+ maskpixels = NULL;
+ detailtexture = NULL;
+
// LordHavoc: HL sky textures are entirely different than quake
if (!loadmodel->ishlbsp && !strncmp(tx->name, "sky", 3) && mtwidth == 256 && mtheight == 128)
{
R_InitSky (mtdata, 1);
}
}
- else if ((tx->texture = loadtextureimagewithmask(loadmodel->texturepool, tx->name, 0, 0, false, true, true)))
- {
- tx->fogtexture = image_masktex;
- strcpy(name, tx->name);
- strcat(name, "_glow");
- tx->glowtexture = loadtextureimage(loadmodel->texturepool, name, 0, 0, false, true, true);
- }
else
{
- if (loadmodel->ishlbsp)
+ basepixels = loadimagepixels(tx->name, false, 0, 0);
+ if (basepixels)
+ {
+ strcpy(name, tx->name);
+ strcat(name, "_glow");
+ glowpixels = loadimagepixels(name, false, 0, 0);
+ }
+ else
{
- if (mtdata && (data = W_ConvertWAD3Texture(dmiptex)))
+ if (loadmodel->ishlbsp)
{
- // texture included
- tx->texture = R_LoadTexture (loadmodel->texturepool, tx->name, image_width, image_height, data, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE);
- if (R_TextureHasAlpha(tx->texture))
+ // internal texture overrides wad
+ if (mtdata && (basepixels = W_ConvertWAD3Texture(dmiptex)) != NULL)
{
- // make mask texture
- for (j = 0;j < image_width * image_height;j++)
- data[j*4+0] = data[j*4+1] = data[j*4+2] = 255;
- strcpy(name, tx->name);
- strcat(name, "_fog");
- tx->fogtexture = R_LoadTexture (loadmodel->texturepool, name, image_width, image_height, data, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE);
+ basepixels_width = image_width;
+ basepixels_height = image_height;
}
- Mem_Free(data);
- }
- else if ((data = W_GetTexture(tx->name)))
- {
- // get the size from the wad texture
- tx->width = image_width;
- tx->height = image_height;
- tx->texture = R_LoadTexture (loadmodel->texturepool, tx->name, image_width, image_height, data, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE);
- if (R_TextureHasAlpha(tx->texture))
+ else if ((basepixels = W_GetTexture(tx->name)) != NULL)
{
- // make mask texture
- for (j = 0;j < image_width * image_height;j++)
- data[j*4+0] = data[j*4+1] = data[j*4+2] = 255;
- strcpy(name, tx->name);
- strcat(name, "_fog");
- tx->fogtexture = R_LoadTexture (loadmodel->texturepool, name, image_width, image_height, data, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE);
+ // get the size from the wad texture
+ tx->width = basepixels_width = image_width;
+ tx->height = basepixels_height = image_height;
}
- Mem_Free(data);
}
else
{
- tx->width = 16;
- tx->height = 16;
- tx->texture = r_notexture;
- }
- }
- else
- {
- if (mtdata) // texture included
- {
- int fullbrights;
- data = mtdata;
- fullbrights = false;
- if (r_fullbrights.value && tx->name[0] != '*')
+ if (mtdata) // texture included
{
- for (j = 0;j < tx->width*tx->height;j++)
+ if (r_fullbrights.integer && tx->name[0] != '*')
{
- if (data[j] >= 224) // fullbright
+ basepixels_width = tx->width;
+ basepixels_height = tx->height;
+ basepixels = Mem_Alloc(loadmodel->mempool, basepixels_width * basepixels_height * 4);
+ Image_Copy8bitRGBA(mtdata, basepixels, basepixels_width * basepixels_height, palette_nofullbrights);
+ for (j = 0;j < tx->width*tx->height;j++)
+ if (((qbyte *)&palette_onlyfullbrights[mtdata[j]])[3] > 0) // fullbright
+ break;
+ if (j < tx->width * tx->height)
{
- fullbrights = true;
- break;
+ glowpixels_width = tx->width;
+ glowpixels_height = tx->height;
+ glowpixels = Mem_Alloc(loadmodel->mempool, glowpixels_width * glowpixels_height * 4);
+ Image_Copy8bitRGBA(mtdata, glowpixels, glowpixels_width * glowpixels_height, palette_onlyfullbrights);
}
}
+ else
+ {
+ basepixels_width = tx->width;
+ basepixels_height = tx->height;
+ basepixels = Mem_Alloc(loadmodel->mempool, basepixels_width * basepixels_height * 4);
+ Image_Copy8bitRGBA(mtdata, basepixels, tx->width * tx->height, palette_complete);
+ }
}
- if (fullbrights)
- {
- data2 = Mem_Alloc(loadmodel->mempool, tx->width*tx->height);
- for (j = 0;j < tx->width*tx->height;j++)
- data2[j] = data[j] >= 224 ? 0 : data[j]; // no fullbrights
- tx->texture = R_LoadTexture (loadmodel->texturepool, tx->name, tx->width, tx->height, data2, TEXTYPE_QPALETTE, TEXF_MIPMAP | TEXF_PRECACHE);
- strcpy(name, tx->name);
- strcat(name, "_glow");
- for (j = 0;j < tx->width*tx->height;j++)
- data2[j] = data[j] >= 224 ? data[j] : 0; // only fullbrights
- tx->glowtexture = R_LoadTexture (loadmodel->texturepool, name, tx->width, tx->height, data2, TEXTYPE_QPALETTE, TEXF_MIPMAP | TEXF_PRECACHE);
- Mem_Free(data2);
- }
- else
- tx->texture = R_LoadTexture (loadmodel->texturepool, tx->name, tx->width, tx->height, data, TEXTYPE_QPALETTE, TEXF_MIPMAP | TEXF_PRECACHE);
}
- else // no texture, and no external replacement texture was found
+ }
+ }
+
+ if (basepixels)
+ {
+ for (j = 3;j < basepixels_width * basepixels_height * 4;j += 4)
+ if (basepixels[j] < 255)
+ break;
+ if (j < basepixels_width * basepixels_height * 4)
+ {
+ maskpixels = Mem_Alloc(loadmodel->mempool, basepixels_width * basepixels_height * 4);
+ maskpixels_width = basepixels_width;
+ maskpixels_height = basepixels_height;
+ for (j = 0;j < basepixels_width * basepixels_height * 4;j += 4)
{
- tx->width = 16;
- tx->height = 16;
- tx->texture = r_notexture;
+ maskpixels[j+0] = 255;
+ maskpixels[j+1] = 255;
+ maskpixels[j+2] = 255;
+ maskpixels[j+3] = basepixels[j+3];
}
}
+
+ if (!bumppixels)
+ {
+ bumppixels = Mem_Alloc(loadmodel->mempool, basepixels_width * basepixels_height * 4);
+ bumppixels_width = basepixels_width;
+ bumppixels_height = basepixels_height;
+ memcpy(bumppixels, basepixels, bumppixels_width * bumppixels_height * 4);
+ }
+
+ if (!nmappixels && bumppixels)
+ {
+ nmappixels = Mem_Alloc(loadmodel->mempool, bumppixels_width * bumppixels_height * 4);
+ nmappixels_width = bumppixels_width;
+ nmappixels_height = bumppixels_height;
+ Image_HeightmapToNormalmap(bumppixels, nmappixels, nmappixels_width, nmappixels_height, false, 1);
+ }
+ }
+
+ if (!detailtexture)
+ detailtexture = detailtextures[i % NUM_DETAILTEXTURES];
+
+ if (basepixels)
+ {
+ tx->texture = R_LoadTexture2D (loadmodel->texturepool, tx->name, basepixels_width, basepixels_height, basepixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL);
+ if (nmappixels)
+ tx->nmaptexture = R_LoadTexture2D (loadmodel->texturepool, va("%s_nmap", tx->name), basepixels_width, basepixels_height, basepixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL);
+ if (glosspixels)
+ tx->glosstexture = R_LoadTexture2D (loadmodel->texturepool, va("%s_gloss", tx->name), glosspixels_width, glosspixels_height, glosspixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL);
+ if (glowpixels)
+ tx->glowtexture = R_LoadTexture2D (loadmodel->texturepool, va("%s_glow", tx->name), glowpixels_width, glowpixels_height, glowpixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL);
+ if (maskpixels)
+ tx->fogtexture = R_LoadTexture2D (loadmodel->texturepool, va("%s_mask", tx->name), maskpixels_width, maskpixels_height, maskpixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL);
+ tx->detailtexture = detailtexture;
}
+ else
+ {
+ // no texture found
+ tx->width = 16;
+ tx->height = 16;
+ tx->texture = r_notexture;
+ tx->nmaptexture = NULL;
+ tx->glosstexture = NULL;
+ tx->glowtexture = NULL;
+ tx->fogtexture = NULL;
+ tx->detailtexture = NULL;
+ }
+
+ if (basepixels)
+ Mem_Free(basepixels);
+ if (bumppixels)
+ Mem_Free(bumppixels);
+ if (nmappixels)
+ Mem_Free(nmappixels);
+ if (glosspixels)
+ Mem_Free(glosspixels);
+ if (glowpixels)
+ Mem_Free(glowpixels);
+ if (maskpixels)
+ Mem_Free(maskpixels);
if (tx->name[0] == '*')
{
tx->shader = &Cshader_wall_lightmap;
}
- tx->detailtexture = detailtextures[i % NUM_DETAILTEXTURES];
// start out with no animation
tx->currentframe[0] = tx;
tx->currentframe[1] = tx;
if (r_miplightmaps.integer)
{
surf->lightmaptexturestride = (surf->extents[0]>>4)+1;
- surf->lightmaptexture = R_LoadTexture(loadmodel->texturepool, NULL, surf->lightmaptexturestride, (surf->extents[1]>>4)+1, NULL, loadmodel->lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, TEXF_MIPMAP | TEXF_PRECACHE);
+ surf->lightmaptexture = R_LoadTexture2D(loadmodel->texturepool, NULL, surf->lightmaptexturestride, (surf->extents[1]>>4)+1, NULL, loadmodel->lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, TEXF_MIPMAP | TEXF_PRECACHE, NULL);
}
else
{
surf->lightmaptexturestride = R_CompatibleFragmentWidth((surf->extents[0]>>4)+1, loadmodel->lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, 0);
- surf->lightmaptexture = R_LoadTexture(loadmodel->texturepool, NULL, surf->lightmaptexturestride, (surf->extents[1]>>4)+1, NULL, loadmodel->lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, TEXF_FRAGMENT | TEXF_PRECACHE);
+ surf->lightmaptexture = R_LoadTexture2D(loadmodel->texturepool, NULL, surf->lightmaptexturestride, (surf->extents[1]>>4)+1, NULL, loadmodel->lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, TEXF_FRAGMENT | TEXF_PRECACHE, NULL);
}
R_FragmentLocation(surf->lightmaptexture, NULL, NULL, &ubase, &vbase, &uscale, &vscale);
uscale = (uscale - ubase) * 16.0 / ((surf->extents[0] & ~15) + 16);
rtexture_t *fogtexture;
// detail texture (usually not used if transparent)
rtexture_t *detailtexture;
+ // normalmap for bumpmap shading
+ rtexture_t *nmaptexture;
+ // color filtering for glossy surfaces
+ rtexture_t *glosstexture;
// shader to use for this texture
Cshader_t *shader;
short extents[2];
mtexinfo_t *texinfo;
- texture_t *currenttexture; // updated (animated) during early surface processing each frame
// index into d_lightstylevalue array, 255 means not used (black)
qbyte styles[MAXLIGHTMAPS];
}
r_notexturepool = R_AllocTexturePool();
- r_notexture = R_LoadTexture(r_notexturepool, "notexture", 16, 16, &pix[0][0][0], TEXTYPE_RGBA, TEXF_MIPMAP);
+ r_notexture = R_LoadTexture2D(r_notexturepool, "notexture", 16, 16, &pix[0][0][0], TEXTYPE_RGBA, TEXF_MIPMAP, NULL);
}
extern void Mod_BrushStartup (void);
rtexture_t *glow; // glow only
rtexture_t *merged; // original texture minus glow
rtexture_t *fog; // white texture with alpha of the base texture, NULL if not transparent
+ rtexture_t *nmap; // normalmap (bumpmap for dot3)
+ rtexture_t *gloss; // glossmap (for dot3)
}
skinframe_t;
// on the same machine.
#include "quakedef.h"
+#include "image.h"
cvar_t r_mipsprites = {CVAR_SAVE, "r_mipsprites", "1"};
sprintf (name, "%s_%i_%i", tempname, i, j);
else
sprintf (name, "%s_%i", tempname, i);
- loadmodel->sprdata_frames[realframes].texture = loadtextureimagewithmask(loadmodel->texturepool, name, 0, 0, false, r_mipsprites.integer, true);
+ loadmodel->sprdata_frames[realframes].texture = loadtextureimagewithmask(loadmodel->texturepool, name, 0, 0, false, (r_mipsprites.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_PRECACHE);
loadmodel->sprdata_frames[realframes].fogtexture = image_masktex;
if (!loadmodel->sprdata_frames[realframes].texture)
else //if (version == SPRITE_VERSION || version == SPRITEHL_VERSION)
Image_Copy8bitRGBA(datapointer, pixbuf, width*height, palette);
- loadmodel->sprdata_frames[realframes].texture = R_LoadTexture (loadmodel->texturepool, name, width, height, pixbuf, TEXTYPE_RGBA, TEXF_ALPHA | (r_mipsprites.integer ? TEXF_MIPMAP : 0) | TEXF_PRECACHE);
+ loadmodel->sprdata_frames[realframes].texture = R_LoadTexture2D (loadmodel->texturepool, name, width, height, pixbuf, TEXTYPE_RGBA, TEXF_ALPHA | (r_mipsprites.integer ? TEXF_MIPMAP : 0) | TEXF_PRECACHE, NULL);
// make fog version (just alpha)
for (k = 0;k < width*height;k++)
sprintf (name, "%s_%i_%ifog", tempname, i, j);
else
sprintf (name, "%s_%ifog", tempname, i);
- loadmodel->sprdata_frames[realframes].fogtexture = R_LoadTexture (loadmodel->texturepool, name, width, height, pixbuf, TEXTYPE_RGBA, TEXF_ALPHA | (r_mipsprites.integer ? TEXF_MIPMAP : 0) | TEXF_PRECACHE);
+ loadmodel->sprdata_frames[realframes].fogtexture = R_LoadTexture2D (loadmodel->texturepool, name, width, height, pixbuf, TEXTYPE_RGBA, TEXF_ALPHA | (r_mipsprites.integer ? TEXF_MIPMAP : 0) | TEXF_PRECACHE, NULL);
Mem_Free(pixbuf);
}
loadmodel->sprnum_type = LittleLong (pinqsprite->type);
loadmodel->synctype = LittleLong (pinqsprite->synctype);
- Mod_Sprite_SharedSetup(datapointer, LittleLong (pinqsprite->version), d_8to24table);
+ Mod_Sprite_SharedSetup(datapointer, LittleLong (pinqsprite->version), palette_complete);
}
else if (version == SPRITEHL_VERSION)
{
#include "quakedef.h"
-unsigned int d_8to24table[256];
+unsigned int palette_complete[256];
+unsigned int palette_nofullbrights[256];
+unsigned int palette_onlyfullbrights[256];
+unsigned int palette_nocolormapnofullbrights[256];
+unsigned int palette_pantsaswhite[256];
+unsigned int palette_shirtaswhite[256];
+unsigned int palette_alpha[256];
+unsigned int palette_font[256];
+
qbyte host_basepal[768];
cvar_t v_gamma = {CVAR_SAVE, "v_gamma", "1"};
void Palette_Setup8to24(void)
{
int i;
+ int fullbright_start, fullbright_end;
+ int pants_start, pants_end;
+ int shirt_start, shirt_end;
+ int reversed_start, reversed_end;
qbyte *in, *out;
+ qbyte *colormap;
in = host_basepal;
- out = (qbyte *) d_8to24table; // d_8to24table is accessed as 32bit for speed reasons, but is created as 8bit bytes
- for (i=0 ; i<255 ; i++)
+ out = (qbyte *) palette_complete; // palette is accessed as 32bit for speed reasons, but is created as 8bit bytes
+ for (i = 0;i < 255;i++)
{
*out++ = *in++;
*out++ = *in++;
*out++ = *in++;
*out++ = 255;
}
- d_8to24table[255] = 0; // completely transparent black
+ palette_complete[255] = 0; // completely transparent black
+
+ // FIXME: fullbright_start should be read from colormap.lmp
+ colormap = COM_LoadFile("gfx/colormap.lmp", true);
+ if (colormap && com_filesize >= 16385)
+ fullbright_start = 256 - colormap[16384];
+ else
+ fullbright_start = 256;
+ if (colormap)
+ Mem_Free(colormap);
+ fullbright_end = 256;
+ pants_start = 96;
+ pants_end = 112;
+ shirt_start = 16;
+ shirt_end = 32;
+ reversed_start = 128;
+ reversed_end = 224;
+
+ memset(palette_nofullbrights, 0, sizeof(palette_nofullbrights));
+ for (i = 0;i < fullbright_start;i++)
+ palette_nofullbrights[i] = palette_complete[i];
+
+ memset(palette_onlyfullbrights, 0, sizeof(palette_onlyfullbrights));
+ for (i = fullbright_start;i < fullbright_end;i++)
+ palette_onlyfullbrights[i] = palette_complete[i];
+
+ for (i = 0;i < 256;i++)
+ palette_nocolormapnofullbrights[i] = palette_complete[i];
+ for (i = pants_start;i < pants_end;i++)
+ palette_nocolormapnofullbrights[i] = 0;
+ for (i = shirt_start;i < shirt_end;i++)
+ palette_nocolormapnofullbrights[i] = 0;
+ for (i = fullbright_start;i < fullbright_end;i++)
+ palette_nocolormapnofullbrights[i] = 0;
+
+ memset(palette_pantsaswhite, 0, sizeof(palette_pantsaswhite));
+ for (i = pants_start;i < pants_end;i++)
+ {
+ if (i >= reversed_start && i < reversed_end)
+ palette_pantsaswhite[i] = 15 - (i - pants_start);
+ else
+ palette_pantsaswhite[i] = i - pants_start;
+ }
+
+ memset(palette_shirtaswhite, 0, sizeof(palette_shirtaswhite));
+ for (i = shirt_start;i < shirt_end;i++)
+ {
+ if (i >= reversed_start && i < reversed_end)
+ palette_shirtaswhite[i] = 15 - (i - shirt_start);
+ else
+ palette_shirtaswhite[i] = i - shirt_start;
+ }
+
+ memset(palette_alpha, 0, sizeof(palette_alpha));
+ for (i = 0;i < 255;i++)
+ palette_alpha[i] = 0xFFFFFFFF;
+
+ memset(palette_font, 0, sizeof(palette_font));
+ for (i = 1;i < 255;i++)
+ palette_font[i] = palette_complete[i];
}
extern cvar_t v_overbrightbits;
extern cvar_t v_hwgamma;
-extern unsigned int d_8to24table[256];
-//extern qbyte d_15to8table[32768];
+extern unsigned int palette_complete[256];
+extern unsigned int palette_nofullbrights[256];
+extern unsigned int palette_onlyfullbrights[256];
+extern unsigned int palette_nocolormapnofullbrights[256];
+extern unsigned int palette_pantsaswhite[256];
+extern unsigned int palette_shirtaswhite[256];
+extern unsigned int palette_alpha[256];
+extern unsigned int palette_font[256];
extern qboolean hardwaregammasupported;
void fractalnoisequick(unsigned char *noise, int size, int startgrid);
#include "palette.h"
-#include "image.h"
void Sys_Shared_Init(void);
}
else
i = 15;
- color = (qbyte *) &d_8to24table[i];
+ color = (qbyte *) &palette_complete[i];
if (crosshair_flashspeed.value >= 0.01f)
base = (sin(realtime * crosshair_flashspeed.value * (M_PI*2.0f)) * crosshair_flashrange.value);
else
data[y][x][3] = bound(0, a, 255);
}
}
- explosiontexture = R_LoadTexture (explosiontexturepool, "explosiontexture", 128, 128, &data[0][0][0], TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE);
+ explosiontexture = R_LoadTexture2D(explosiontexturepool, "explosiontexture", 128, 128, &data[0][0][0], TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL);
for (y = 0;y < 128;y++)
for (x = 0;x < 128;x++)
data[y][x][0] = data[y][x][1] = data[y][x][2] = 255;
- explosiontexturefog = R_LoadTexture (explosiontexturepool, "explosiontexturefog", 128, 128, &data[0][0][0], TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE);
+ explosiontexturefog = R_LoadTexture2D(explosiontexturepool, "explosiontexturefog", 128, 128, &data[0][0][0], TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL);
// note that explosions survive the restart
}
pixels[y][x][3] = 255;
}
}
- lightcorona = R_LoadTexture (lighttexturepool, "lightcorona", 32, 32, &pixels[0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE);
+ lightcorona = R_LoadTexture2D(lighttexturepool, "lightcorona", 32, 32, &pixels[0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
}
void r_light_shutdown(void)
static void R_Shadow_Make3DTextures(void)
{
int x, y, z, d;
- float v[3], intensity, ilen, length;
+ float v[3], intensity, ilen, length, bordercolor[4];
qbyte data[ATTEN3DSIZE][ATTEN3DSIZE][ATTEN3DSIZE][4];
if (r_light_quality.integer != 1 || !gl_texture3d)
return;
}
}
}
- r_shadow_normalsattenuationtexture = R_LoadTexture3D(r_shadow_texturepool, "normalsattenuation", ATTEN3DSIZE, ATTEN3DSIZE, ATTEN3DSIZE, &data[0][0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP);
+ r_shadow_normalsattenuationtexture = R_LoadTexture3D(r_shadow_texturepool, "normalsattenuation", ATTEN3DSIZE, ATTEN3DSIZE, ATTEN3DSIZE, &data[0][0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL);
+ bordercolor[0] = 0.5f;
+ bordercolor[1] = 0.5f;
+ bordercolor[2] = 0.5f;
+ bordercolor[3] = 1.0f;
+ qglTexParameterfv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, bordercolor);
}
static void R_Shadow_MakeTextures(void)
data[0][y][x][3] = 255;
}
}
- r_shadow_blankbumptexture = R_LoadTexture(r_shadow_texturepool, "blankbump", 128, 128, &data[0][0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE);
+ r_shadow_blankbumptexture = R_LoadTexture2D(r_shadow_texturepool, "blankbump", 128, 128, &data[0][0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
for (side = 0;side < 6;side++)
{
for (y = 0;y < 128;y++)
}
}
}
- r_shadow_normalscubetexture = R_LoadTextureCubeMap(r_shadow_texturepool, "normalscube", 128, &data[0][0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP);
+ r_shadow_normalscubetexture = R_LoadTextureCubeMap(r_shadow_texturepool, "normalscube", 128, &data[0][0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP, NULL);
for (y = 0;y < 128;y++)
{
for (x = 0;x < 128;x++)
data[0][y][x][3] = 255;
}
}
- r_shadow_attenuation2dtexture = R_LoadTexture2D(r_shadow_texturepool, "attenuation2d", 128, 128, &data[0][0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP);
+ r_shadow_attenuation2dtexture = R_LoadTexture2D(r_shadow_texturepool, "attenuation2d", 128, 128, &data[0][0][0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_CLAMP, NULL);
R_Shadow_Make3DTextures();
}
for (i = 0;i < numverts;i++, vertex += 4, svectors += 4, tvectors += 4, normals += 4, out += 4)
{
VectorSubtract(vertex, relativelightorigin, lightvec);
- out[0] = 0.5f + DotProduct(svectors, lightvec) * iradius;
- out[1] = 0.5f + DotProduct(tvectors, lightvec) * iradius;
- out[2] = 0.5f + DotProduct(normals, lightvec) * iradius;
+ if (r_shadow6.integer != 0)
+ {
+ VectorClear(lightvec);
+ if (r_shadow6.integer > 0)
+ lightvec[(r_shadow6.integer - 1) % 3] = 64;
+ else
+ lightvec[((-r_shadow6.integer) - 1) % 3] = -64;
+ }
+ if (r_shadow4.integer & 8)
+ lightvec[0] = -lightvec[0];
+ if (r_shadow4.integer & 16)
+ lightvec[1] = -lightvec[1];
+ if (r_shadow4.integer & 32)
+ lightvec[2] = -lightvec[2];
+ if (r_shadow4.integer & 1)
+ out[0] = 0.5f - DotProduct(svectors, lightvec) * iradius;
+ else
+ out[0] = 0.5f + DotProduct(svectors, lightvec) * iradius;
+ if (r_shadow4.integer & 2)
+ out[1] = 0.5f - DotProduct(tvectors, lightvec) * iradius;
+ else
+ out[2] = 0.5f + DotProduct(tvectors, lightvec) * iradius;
+ if (r_shadow4.integer & 4)
+ out[2] = 0.5f - DotProduct(normals, lightvec) * iradius;
+ else
+ out[2] = 0.5f + DotProduct(normals, lightvec) * iradius;
}
}
m.texcombinergb[1] = GL_DOT3_RGB_ARB;
m.texcombinergb[2] = GL_MODULATE;
m.texcombinergb[3] = GL_MODULATE;
+ m.texrgbscale[2] = 2;
R_Mesh_TextureState(&m);
R_Shadow_GenTexCoords_Diffuse_Attenuation3D(varray_texcoord[1], numverts, varray_vertex, svectors, tvectors, normals, relativelightorigin, lightradius);
if (m.texcubemap[3])
m.texcombinergb[1] = GL_DOT3_RGB_ARB;
m.texcombinergb[2] = GL_MODULATE;
m.texcombinergb[3] = GL_MODULATE;
+ m.texrgbscale[2] = 2;
R_Mesh_TextureState(&m);
R_Shadow_GenTexCoords_Specular_Attenuation3D(varray_texcoord[1], numverts, varray_vertex, svectors, tvectors, normals, relativelightorigin, relativeeyeorigin, lightradius);
R_Mesh_Draw(numverts, numtriangles, elements);
#include "quakedef.h"
+#include "image.h"
cvar_t r_sky = {CVAR_SAVE, "r_sky", "1"};
qboolean skyavailable_quake;
continue;
}
}
- skyboxside[i] = R_LoadTexture(skytexturepool, va("skyboxside%d", i), image_width, image_height, image_rgba, TEXTYPE_RGBA, TEXF_PRECACHE);
+ skyboxside[i] = R_LoadTexture2D(skytexturepool, va("skyboxside%d", i), image_width, image_height, image_rgba, TEXTYPE_RGBA, TEXF_CLAMP | TEXF_PRECACHE, NULL);
Mem_Free(image_rgba);
}
varray_vertex[i * 4 + 0] = (x) * 16.0f;\
varray_vertex[i * 4 + 1] = (y) * 16.0f;\
varray_vertex[i * 4 + 2] = (z) * 16.0f;\
- varray_texcoord[0][i * 4 + 0] = (s) * (254.0f/256.0f) + (1.0f/256.0f);\
- varray_texcoord[0][i * 4 + 1] = (t) * (254.0f/256.0f) + (1.0f/256.0f);
+ varray_texcoord[0][i * 4 + 0] = (s);\
+ varray_texcoord[0][i * 4 + 1] = (t);
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_ONE;
for (j=0 ; j<128 ; j++)
{
p = src[i*256 + j + 128];
- rgba = &d_8to24table[p];
+ rgba = &palette_complete[p];
trans[(i*128) + j] = *rgba;
r += ((qbyte *)rgba)[0];
g += ((qbyte *)rgba)[1];
memcpy(skyupperlayerpixels, trans, 128*128*4);
- solidskytexture = R_LoadTexture (skytexturepool, "sky_solidtexture", 128, 128, (qbyte *) trans, TEXTYPE_RGBA, TEXF_PRECACHE);
+ solidskytexture = R_LoadTexture2D(skytexturepool, "sky_solidtexture", 128, 128, (qbyte *) trans, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
if (bytesperpixel == 4)
{
if (p == 0)
trans[(i*128) + j] = transpix;
else
- trans[(i*128) + j] = d_8to24table[p];
+ trans[(i*128) + j] = palette_complete[p];
}
}
}
memcpy(skylowerlayerpixels, trans, 128*128*4);
- alphaskytexture = R_LoadTexture (skytexturepool, "sky_alphatexture", 128, 128, (qbyte *) trans, TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE);
+ alphaskytexture = R_LoadTexture2D(skytexturepool, "sky_alphatexture", 128, 128, (qbyte *) trans, TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE, NULL);
}
void R_ResetQuakeSky(void)
// used for checking if textures mismatch
#define TEXF_IMPORTANTBITS (TEXF_ALPHA | TEXF_MIPMAP | TEXF_FRAGMENT | TEXF_CLAMP)
-// 8bit quake paletted
-#define TEXTYPE_QPALETTE 1
+// 8bit paletted
+#define TEXTYPE_PALETTE 1
// 24bit RGB
#define TEXTYPE_RGB 2
// 32bit RGBA
// add a texture to a pool and optionally precache (upload) it
// (note: data == NULL is perfectly acceptable)
-rtexture_t *R_LoadTexture(rtexturepool_t *rtexturepool, char *identifier, int width, int height, qbyte *data, int textype, int flags);
-rtexture_t *R_LoadTexture1D(rtexturepool_t *rtexturepool, char *identifier, int width, qbyte *data, int textype, int flags);
-rtexture_t *R_LoadTexture2D(rtexturepool_t *rtexturepool, char *identifier, int width, int height, qbyte *data, int textype, int flags);
-rtexture_t *R_LoadTexture3D(rtexturepool_t *rtexturepool, char *identifier, int width, int height, int depth, qbyte *data, int textype, int flags);
-rtexture_t *R_LoadTextureCubeMap(rtexturepool_t *rtexturepool, char *identifier, int width, qbyte *data, int textype, int flags);
+// (note: palette must not be NULL if using TEXTYPE_PALETTE)
+rtexture_t *R_LoadTexture1D(rtexturepool_t *rtexturepool, const char *identifier, int width, const qbyte *data, int textype, int flags, const unsigned int *palette);
+rtexture_t *R_LoadTexture2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, const qbyte *data, int textype, int flags, const unsigned int *palette);
+rtexture_t *R_LoadTexture3D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int depth, const qbyte *data, int textype, int flags, const unsigned int *palette);
+rtexture_t *R_LoadTextureCubeMap(rtexturepool_t *rtexturepool, const char *identifier, int width, const qbyte *data, int textype, int flags, const unsigned int *palette);
// free a texture
void R_FreeTexture(rtexture_t *rt);
#include "r_lerpanim.h"
extern cvar_t r_render;
-#include "image.h"
extern cvar_t r_textureunits;
extern cvar_t gl_dither;
continue;
// draw background
- c = (qbyte *)&d_8to24table[(s->colors & 0xf0) + 8];
+ c = (qbyte *)&palette_complete[(s->colors & 0xf0) + 8];
DrawQ_Fill (sbar_x + x + 10, sbar_y - 23, 28, 4, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f), 0);
- c = (qbyte *)&d_8to24table[((s->colors & 15)<<4) + 8];
+ c = (qbyte *)&palette_complete[((s->colors & 15)<<4) + 8];
DrawQ_Fill (sbar_x + x + 10, sbar_y + 4 - 23, 28, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f), 0);
// draw number
s = &cl.scores[cl.viewentity - 1];
// draw background
Sbar_DrawPic (112, 0, rsb_teambord);
- c = (qbyte *)&d_8to24table[(s->colors & 0xf0) + 8];
+ c = (qbyte *)&palette_complete[(s->colors & 0xf0) + 8];
DrawQ_Fill (sbar_x + 113, vid.conheight-SBAR_HEIGHT+3, 22, 9, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f), 0);
- c = (qbyte *)&d_8to24table[((s->colors & 15)<<4) + 8];
+ c = (qbyte *)&palette_complete[((s->colors & 15)<<4) + 8];
DrawQ_Fill (sbar_x + 113, vid.conheight-SBAR_HEIGHT+12, 22, 9, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f), 0);
// draw number
continue;
// draw background
- c = (qbyte *)&d_8to24table[(s->colors & 0xf0) + 8];
+ c = (qbyte *)&palette_complete[(s->colors & 0xf0) + 8];
DrawQ_Fill ( x + 8, y+1, 88, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f), 0);
- c = (qbyte *)&d_8to24table[((s->colors & 15)<<4) + 8];
+ c = (qbyte *)&palette_complete[((s->colors & 15)<<4) + 8];
DrawQ_Fill ( x + 8, y+4, 88, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f), 0);
total = cl.time - s->entertime;
continue;
// draw background
- c = (qbyte *)&d_8to24table[(s->colors & 0xf0) + 8];
+ c = (qbyte *)&palette_complete[(s->colors & 0xf0) + 8];
DrawQ_Fill ( x, y+1, 72, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f), 0);
- c = (qbyte *)&d_8to24table[((s->colors & 15)<<4) + 8];
+ c = (qbyte *)&palette_complete[((s->colors & 15)<<4) + 8];
DrawQ_Fill ( x, y+4, 72, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f), 0);
fph = (cl.time - s->entertime) ? (int) ((float) s->frags * 3600.0 / (cl.time - s->entertime)) : 0;
void (GLAPIENTRY *qglStencilOp)(GLenum fail, GLenum zfail, GLenum zpass);
void (GLAPIENTRY *qglClearStencil)(GLint s);
-//void (GLAPIENTRY *qglTexEnvf)(GLenum target, GLenum pname, GLfloat param);
+void (GLAPIENTRY *qglTexEnvf)(GLenum target, GLenum pname, GLfloat param);
void (GLAPIENTRY *qglTexEnvi)(GLenum target, GLenum pname, GLint param);
-//void (GLAPIENTRY *qglTexParameterf)(GLenum target, GLenum pname, GLfloat param);
+void (GLAPIENTRY *qglTexParameterf)(GLenum target, GLenum pname, GLfloat param);
+void (GLAPIENTRY *qglTexParameterfv)(GLenum target, GLenum pname, GLfloat *params);
void (GLAPIENTRY *qglTexParameteri)(GLenum target, GLenum pname, GLint param);
void (GLAPIENTRY *qglGenTextures)(GLsizei n, GLuint *textures);
{"glStencilMask", (void **) &qglStencilMask},
{"glStencilOp", (void **) &qglStencilOp},
{"glClearStencil", (void **) &qglClearStencil},
-// {"glTexEnvf", (void **) &qglTexEnvf},
+ {"glTexEnvf", (void **) &qglTexEnvf},
{"glTexEnvi", (void **) &qglTexEnvi},
-// {"glTexParameterf", (void **) &qglTexParameterf},
+ {"glTexParameterf", (void **) &qglTexParameterf},
+ {"glTexParameterfv", (void **) &qglTexParameterfv},
{"glTexParameteri", (void **) &qglTexParameteri},
{"glPixelStoref", (void **) &qglPixelStoref},
{"glPixelStorei", (void **) &qglPixelStorei},