2009-02-13 19:21:00 +00:00

255 lines
9.8 KiB
C

#ifndef _tgl_zbuffer_h_
#define _tgl_zbuffer_h_
/*
* Z buffer
*/
#include "zfeatures.h"
#include "pbitops.h"
typedef unsigned int ZPOINT;
#define ZB_Z_BITS 20
#define ZB_POINT_Z_FRAC_BITS 10 // These must add to < 32.
/* The number of fractional bits below the S and T texture coords.
The more we have, the more precise the texel calculation will be
when we zoom into small details of a texture; but the greater
chance we might overflow our 32-bit integer when texcoords get
large. This also limits our greatest texture size (its T dimension
cannot exceed this number of bits).*/
#define ZB_POINT_ST_FRAC_BITS 12
/* This is the theoretical max number of bits we have available to
shift down to achieve each next mipmap level, based on the size of
a 32-bit int. We need to preallocate mipmap arrays of this size. */
#define MAX_MIPMAP_LEVELS (32 - ZB_POINT_ST_FRAC_BITS + 1)
/* Returns the index within a texture level for the given (s, t) texel. */
#define ZB_TEXEL(texture_level, s, t) \
((((t) & (texture_level).t_mask) >> (texture_level).t_shift) | \
(((s) & (texture_level).s_mask) >> (texture_level).s_shift))
#define ZB_LOOKUP_TEXTURE_NEAREST(texture_def, s, t) \
(texture_def)->levels[0].pixmap[ZB_TEXEL((texture_def)->levels[0], s, t)]
#define ZB_LOOKUP_TEXTURE_MIPMAP_NEAREST(texture_def, s, t, level) \
(texture_def)->levels[(level)].pixmap[ZB_TEXEL((texture_def)->levels[(level)], s, t)]
/* A special abs() function which doesn't require any branching
instructions. Might not work on some exotic hardware. */
/* Also doesn't appear to be any faster in practice. Guess gcc is
already doing the right thing. Is msvc? */
//#define FAST_ABS(v) (((v) ^ ((v) >> (sizeof(v) * 8 - 1))) - ((v) >> (sizeof(v) * 8 - 1)))
#define DO_CALC_MIPMAP_LEVEL(mipmap_level, mipmap_dx, dsdx, dtdx) \
{ \
(mipmap_dx) = ((unsigned int)abs(dsdx) + (unsigned int)abs(dtdx)); \
(mipmap_level) = get_next_higher_bit((mipmap_dx) >> ZB_POINT_ST_FRAC_BITS); \
(mipmap_dx) &= ((1 << (((mipmap_level) - 1) + ZB_POINT_ST_FRAC_BITS)) - 1); \
}
#define ZB_POINT_RED_MIN 0x0000
#define ZB_POINT_RED_MAX 0xffff
#define ZB_POINT_GREEN_MIN 0x0000
#define ZB_POINT_GREEN_MAX 0xffff
#define ZB_POINT_BLUE_MIN 0x0000
#define ZB_POINT_BLUE_MAX 0xffff
#define ZB_POINT_ALPHA_MIN 0x0000
#define ZB_POINT_ALPHA_MAX 0xffff
/* display modes */
#define ZB_MODE_5R6G5B 1 /* true color 16 bits */
#define ZB_MODE_INDEX 2 /* color index 8 bits */
#define ZB_MODE_RGBA 3 /* 32 bit rgba mode */
#define ZB_MODE_RGB24 4 /* 24 bit rgb mode */
#define ZB_NB_COLORS 225 /* number of colors for 8 bit display */
#define RGB_TO_PIXEL(r,g,b) \
((((unsigned int)(r) << 8) & 0xff0000) | ((unsigned int)(g) & 0xff00) | ((unsigned int)(b) >> 8))
#define RGBA_TO_PIXEL(r,g,b,a) \
((((unsigned int)(a) << 16) & 0xff000000) | (((unsigned int)(r) << 8) & 0xff0000) | ((unsigned int)(g) & 0xff00) | ((unsigned int)(b) >> 8))
#define RGBA8_TO_PIXEL(r,g,b,a) \
((((unsigned int)(a) << 24) & 0xff000000) | (((unsigned int)(r) << 16) & 0xff0000) | (((unsigned int)(g) << 8) & 0xff00) | (unsigned int)(b))
#define PIXEL_R(p) (((unsigned int)(p) & 0xff0000) >> 8)
#define PIXEL_G(p) ((unsigned int)(p) & 0xff00)
#define PIXEL_B(p) (((unsigned int)(p) & 0x00ff) << 8)
#define PIXEL_A(p) (((unsigned int)(p) & 0xff000000) >> 16)
typedef unsigned int PIXEL;
#define PSZB 4
#define PSZSH 5
// Returns an unsigned product of c1 * c2
#define PCOMPONENT_MULT(c1, c2) \
((((unsigned int)(c1) * (unsigned int)(c2))) >> 16)
#define PCOMPONENT_MULT3(c1, c2, c3) \
PCOMPONENT_MULT(c1, PCOMPONENT_MULT(c2, c3))
#define PCOMPONENT_MULT4(c1, c2, c3, c4) \
PCOMPONENT_MULT(PCOMPONENT_MULT(c1, c2), PCOMPONENT_MULT(c3, c4))
// Returns a signed product of c1 * c2, where c1 is initially signed.
// We leave 2 bits on the top to differentiate between c1 < 0 and c1 >
// 0xffff; the result has the same sign.
#define PALPHA_MULT(c1, c2) \
(((int)(((int)(c1) >> 2) * (unsigned int)(c2))) >> 14)
#define PCOMPONENT_BLEND(c1, c2, a2) \
((((unsigned int)(c1) * ((unsigned int)0xffff - (unsigned int)(a2)) + (unsigned int)(c2) * (unsigned int)(a2))) >> 16)
#define PIXEL_BLEND(r1, g1, b1, r2, g2, b2, a2) \
RGBA_TO_PIXEL(PCOMPONENT_BLEND(r1, r2, a2), \
PCOMPONENT_BLEND(g1, g2, a2), \
PCOMPONENT_BLEND(b1, b2, a2), \
a2)
#define PIXEL_BLEND_RGB(rgb, r, g, b, a) \
PIXEL_BLEND(PIXEL_R(rgb), PIXEL_G(rgb), PIXEL_B(rgb), r, g, b, a)
typedef struct {
PIXEL *pixmap;
unsigned int s_mask, s_shift, t_mask, t_shift;
} ZTextureLevel;
typedef struct ZBuffer ZBuffer;
typedef struct ZBufferPoint ZBufferPoint;
typedef struct ZTextureDef ZTextureDef;
typedef void (*ZB_fillTriangleFunc)(ZBuffer *,
ZBufferPoint *,ZBufferPoint *,ZBufferPoint *);
typedef void (*ZB_storePixelFunc)(ZBuffer *zb, PIXEL &result, int r, int g, int b, int a);
typedef PIXEL (*ZB_lookupTextureFunc)(ZTextureDef *texture_def, int s, int t, unsigned int level, unsigned int level_dx);
typedef int (*ZB_texWrapFunc)(int coord, int max_coord);
struct ZTextureDef {
ZTextureLevel *levels;
ZB_lookupTextureFunc tex_minfilter_func;
ZB_lookupTextureFunc tex_magfilter_func;
ZB_lookupTextureFunc tex_minfilter_func_impl;
ZB_lookupTextureFunc tex_magfilter_func_impl;
ZB_texWrapFunc tex_wrap_u_func;
ZB_texWrapFunc tex_wrap_v_func;
int s_max, t_max;
PIXEL border_color;
};
struct ZBuffer {
int xsize,ysize;
int linesize; /* line size, in bytes */
int mode;
ZPOINT *zbuf;
PIXEL *pbuf;
int frame_buffer_allocated;
int nb_colors;
unsigned char *dctable;
int *ctable;
ZTextureDef current_textures[MAX_TEXTURE_STAGES];
int reference_alpha;
int blend_r, blend_g, blend_b, blend_a;
ZB_storePixelFunc store_pix_func;
};
struct ZBufferPoint {
int x,y,z; /* integer coordinates in the zbuffer */
int s,t; /* coordinates for the mapping */
int r,g,b,a; /* color indexes */
float sz,tz; /* temporary coordinates for mapping */
int sa, ta; /* mapping coordinates for optional second texture stage */
float sza,tza;
int sb, tb; /* mapping coordinates for optional third texture stage */
float szb,tzb;
};
/* zbuffer.c */
#ifdef DO_PSTATS
extern int pixel_count_white_untextured;
extern int pixel_count_flat_untextured;
extern int pixel_count_smooth_untextured;
extern int pixel_count_white_textured;
extern int pixel_count_flat_textured;
extern int pixel_count_smooth_textured;
extern int pixel_count_white_perspective;
extern int pixel_count_flat_perspective;
extern int pixel_count_smooth_perspective;
extern int pixel_count_smooth_multitex2;
extern int pixel_count_smooth_multitex3;
#define COUNT_PIXELS(pixel_count, p0, p1, p2) \
(pixel_count) += abs((p0)->x * ((p1)->y - (p2)->y) + (p1)->x * ((p2)->y - (p0)->y) + (p2)->x * ((p0)->y - (p1)->y)) / 2
#else
#define COUNT_PIXELS(pixel_count, p0, p1, p2)
#endif // DO_PSTATS
ZBuffer *ZB_open(int xsize,int ysize,int mode,
int nb_colors,
unsigned char *color_indexes,
unsigned int *color_table,
void *frame_buffer);
void ZB_close(ZBuffer *zb);
void ZB_resize(ZBuffer *zb,void *frame_buffer,int xsize,int ysize);
void ZB_clear(ZBuffer *zb, int clear_z, ZPOINT z,
int clear_color, unsigned int r, unsigned int g, unsigned int b, unsigned int a);
void ZB_clear_viewport(ZBuffer * zb, int clear_z, ZPOINT z,
int clear_color, unsigned int r, unsigned int g, unsigned int b, unsigned int a,
int xmin, int ymin, int xsize, int ysize);
PIXEL lookup_texture_nearest(ZTextureDef *texture_def, int s, int t, unsigned int level, unsigned int level_dx);
PIXEL lookup_texture_bilinear(ZTextureDef *texture_def, int s, int t, unsigned int level, unsigned int level_dx);
PIXEL lookup_texture_mipmap_nearest(ZTextureDef *texture_def, int s, int t, unsigned int level, unsigned int level_dx);
PIXEL lookup_texture_mipmap_linear(ZTextureDef *texture_def, int s, int t, unsigned int level, unsigned int level_dx);
PIXEL lookup_texture_mipmap_bilinear(ZTextureDef *texture_def, int s, int t, unsigned int level, unsigned int level_dx);
PIXEL lookup_texture_mipmap_trilinear(ZTextureDef *texture_def, int s, int t, unsigned int level, unsigned int level_dx);
PIXEL apply_wrap_general_minfilter(ZTextureDef *texture_def, int s, int t, unsigned int level, unsigned int level_dx);
PIXEL apply_wrap_general_magfilter(ZTextureDef *texture_def, int s, int t, unsigned int level, unsigned int level_dx);
PIXEL apply_wrap_border_color_minfilter(ZTextureDef *texture_def, int s, int t, unsigned int level, unsigned int level_dx);
PIXEL apply_wrap_border_color_magfilter(ZTextureDef *texture_def, int s, int t, unsigned int level, unsigned int level_dx);
PIXEL apply_wrap_clamp_minfilter(ZTextureDef *texture_def, int s, int t, unsigned int level, unsigned int level_dx);
PIXEL apply_wrap_clamp_magfilter(ZTextureDef *texture_def, int s, int t, unsigned int level, unsigned int level_dx);
int texcoord_clamp(int coord, int max_coord);
int texcoord_repeat(int coord, int max_coord);
int texcoord_mirror(int coord, int max_coord);
int texcoord_mirror_once(int coord, int max_coord);
/* linesize is in BYTES */
void ZB_copyFrameBuffer(ZBuffer *zb,void *buf,int linesize);
/* zdither.c */
void ZB_initDither(ZBuffer *zb,int nb_colors,
unsigned char *color_indexes,int *color_table);
void ZB_closeDither(ZBuffer *zb);
void ZB_ditherFrameBuffer(ZBuffer *zb,unsigned char *dest,
int linesize);
/* zline.c */
void ZB_plot(ZBuffer *zb,ZBufferPoint *p);
void ZB_line(ZBuffer *zb,ZBufferPoint *p1,ZBufferPoint *p2);
void ZB_line_z(ZBuffer * zb, ZBufferPoint * p1, ZBufferPoint * p2);
/* memory.c */
void gl_free(void *p);
void *gl_malloc(int size);
void *gl_zalloc(int size);
#endif /* _tgl_zbuffer_h_ */