multitexture tinydisplay

This commit is contained in:
David Rose 2008-12-10 02:28:13 +00:00
parent 89d50d7ab3
commit 76f94669d0
13 changed files with 1364 additions and 671 deletions

View File

@ -33,9 +33,15 @@ void gl_transform_to_viewport(GLContext *c,GLVertex *v)
+ ZB_POINT_ALPHA_MIN);
/* texture */
if (c->texture_2d_enabled) {
v->zp.s = (int)(v->tex_coord.v[0] * c->current_texture->s_max);
v->zp.t = (int)(v->tex_coord.v[1] * c->current_texture->t_max);
if (c->num_textures_enabled >= 1) {
static const int si = 0;
v->zp.s = (int)(v->tex_coord[si].v[0] * c->current_textures[si]->s_max);
v->zp.t = (int)(v->tex_coord[si].v[1] * c->current_textures[si]->t_max);
}
if (c->num_textures_enabled >= 2) {
static const int si = 1;
v->zp.sa = (int)(v->tex_coord[si].v[0] * c->current_textures[si]->s_max);
v->zp.ta = (int)(v->tex_coord[si].v[1] * c->current_textures[si]->t_max);
}
}
@ -201,14 +207,15 @@ static inline void updateTmp(GLContext *c,
q->color.v[3]=p0->color.v[3];
}
if (c->texture_2d_enabled) {
q->tex_coord.v[0]=p0->tex_coord.v[0] + (p1->tex_coord.v[0]-p0->tex_coord.v[0])*t;
q->tex_coord.v[1]=p0->tex_coord.v[1] + (p1->tex_coord.v[1]-p0->tex_coord.v[1])*t;
for (int si = 0; si < c->num_textures_enabled; ++si) {
q->tex_coord[si].v[0]=p0->tex_coord[si].v[0] + (p1->tex_coord[si].v[0]-p0->tex_coord[si].v[0])*t;
q->tex_coord[si].v[1]=p0->tex_coord[si].v[1] + (p1->tex_coord[si].v[1]-p0->tex_coord[si].v[1])*t;
}
q->clip_code=gl_clipcode(q->pc.v[0],q->pc.v[1],q->pc.v[2],q->pc.v[3]);
if (q->clip_code==0)
if (q->clip_code==0) {
gl_transform_to_viewport(c,q);
}
}
static void gl_draw_triangle_clip(GLContext *c,
@ -368,7 +375,7 @@ void gl_draw_triangle_fill(GLContext *c,
#endif
#ifdef PROFILE
if (c->texture_2d_enabled) {
if (c->num_textures_enabled != 0) {
count_triangles_textured++;
}
#endif

View File

@ -47,11 +47,6 @@ void glInit(GLContext *c, ZBuffer *zbuffer)
c->current_normal.v[2]=0.0f;
c->current_normal.v[3]=0.0f;
c->current_tex_coord.v[0]=0.0f;
c->current_tex_coord.v[1]=0.0f;
c->current_tex_coord.v[2]=0.0f;
c->current_tex_coord.v[3]=1.0f;
c->cull_face_enabled=0;
/* specular buffer */

View File

@ -51,6 +51,9 @@ PStatCollector TinyGraphicsStateGuardian::_pixel_count_smooth_textured_pcollecto
PStatCollector TinyGraphicsStateGuardian::_pixel_count_white_perspective_pcollector("Pixels:White perspective");
PStatCollector TinyGraphicsStateGuardian::_pixel_count_flat_perspective_pcollector("Pixels:Flat perspective");
PStatCollector TinyGraphicsStateGuardian::_pixel_count_smooth_perspective_pcollector("Pixels:Smooth perspective");
PStatCollector TinyGraphicsStateGuardian::_pixel_count_white_multitex_pcollector("Pixels:White multitex");
PStatCollector TinyGraphicsStateGuardian::_pixel_count_flat_multitex_pcollector("Pixels:Flat multitex");
PStatCollector TinyGraphicsStateGuardian::_pixel_count_smooth_multitex_pcollector("Pixels:Smooth multitex");
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsStateGuardian::Constructor
@ -120,6 +123,7 @@ reset() {
Geom::GR_flat_last_vertex;
_max_texture_dimension = (1 << ZB_POINT_ST_FRAC_BITS);
_max_texture_stages = MAX_TEXTURE_STAGES;
_max_lights = MAX_LIGHTS;
_color_scale_via_lighting = false;
@ -392,6 +396,9 @@ begin_frame(Thread *current_thread) {
_pixel_count_white_perspective_pcollector.clear_level();
_pixel_count_flat_perspective_pcollector.clear_level();
_pixel_count_smooth_perspective_pcollector.clear_level();
_pixel_count_white_multitex_pcollector.clear_level();
_pixel_count_flat_multitex_pcollector.clear_level();
_pixel_count_smooth_multitex_pcollector.clear_level();
#endif
return true;
@ -495,6 +502,9 @@ end_frame(Thread *current_thread) {
_pixel_count_white_perspective_pcollector.flush_level();
_pixel_count_flat_perspective_pcollector.flush_level();
_pixel_count_smooth_perspective_pcollector.flush_level();
_pixel_count_white_multitex_pcollector.flush_level();
_pixel_count_flat_multitex_pcollector.flush_level();
_pixel_count_smooth_multitex_pcollector.flush_level();
#endif // DO_PSTATS
}
@ -604,27 +614,29 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
_vertices = (GLVertex *)PANDA_MALLOC_ARRAY(_vertices_size * sizeof(GLVertex));
}
GeomVertexReader rtexcoord, rcolor, rnormal;
GeomVertexReader rcolor, rnormal;
// We only support single-texturing, so only bother with the first
// texture stage.
bool needs_texcoord = false;
bool needs_texmat = false;
LMatrix4f texmat;
const InternalName *texcoord_name = InternalName::get_texcoord();
// We now support up to 2-stage multitexturing.
GeomVertexReader rtexcoord[MAX_TEXTURE_STAGES];
bool needs_texcoord[MAX_TEXTURE_STAGES] = { false, false };
bool needs_texmat[MAX_TEXTURE_STAGES] = { false, false };
LMatrix4f texmat[MAX_TEXTURE_STAGES];
const InternalName *texcoord_name[MAX_TEXTURE_STAGES] = {
InternalName::get_texcoord(), InternalName::get_texcoord()
};
int max_stage_index = _target_texture->get_num_on_ff_stages();
if (max_stage_index > 0) {
TextureStage *stage = _target_texture->get_on_ff_stage(0);
rtexcoord = GeomVertexReader(data_reader, stage->get_texcoord_name(),
for (int si = 0; si < max_stage_index; ++si) {
TextureStage *stage = _target_texture->get_on_ff_stage(si);
rtexcoord[si] = GeomVertexReader(data_reader, stage->get_texcoord_name(),
force);
rtexcoord.set_row(_min_vertex);
needs_texcoord = rtexcoord.has_column();
rtexcoord[si].set_row(_min_vertex);
needs_texcoord[si] = rtexcoord[si].has_column();
if (needs_texcoord) {
if (needs_texcoord[si]) {
const TexMatrixAttrib *target_tex_matrix = DCAST(TexMatrixAttrib, _target_rs->get_attrib_def(TexMatrixAttrib::get_class_slot()));
if (target_tex_matrix->has_stage(stage)) {
needs_texmat = true;
texmat = target_tex_matrix->get_mat(stage);
needs_texmat[si] = true;
texmat[si] = target_tex_matrix->get_mat(stage);
}
}
}
@ -689,17 +701,20 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
v->coord.v[2] = d[2];
v->coord.v[3] = d[3];
if (needs_texmat) {
// Transform texcoords as a four-component vector for most generality.
LVecBase4f d = rtexcoord.get_data4f() * texmat;
v->tex_coord.v[0] = d[0];
v->tex_coord.v[1] = d[1];
} else if (needs_texcoord) {
// No need to transform, so just extract as two-component.
const LVecBase2f &d = rtexcoord.get_data2f();
v->tex_coord.v[0] = d[0];
v->tex_coord.v[1] = d[1];
// Texture coordinates.
for (int si = 0; si < max_stage_index; ++si) {
if (needs_texmat[si]) {
// Transform texcoords as a four-component vector for most generality.
LVecBase4f d = rtexcoord[si].get_data4f() * texmat[si];
v->tex_coord[si].v[0] = d[0];
v->tex_coord[si].v[1] = d[1];
} else if (needs_texcoord[si]) {
// No need to transform, so just extract as two-component.
const LVecBase2f &d = rtexcoord[si].get_data2f();
v->tex_coord[si].v[0] = d[0];
v->tex_coord[si].v[1] = d[1];
}
}
if (needs_color) {
@ -846,8 +861,9 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
int texfilter_state = 0; // tnearest
if (texturing_state > 0) {
texfilter_state = _texfilter_state;
if (_c->matrix_model_projection_no_w_transform ||
_filled_flat) {
if (texturing_state < 3 &&
(_c->matrix_model_projection_no_w_transform || _filled_flat)) {
// Don't bother with the perspective-correct algorithm if we're
// under an orthonormal lens, e.g. render2d; or if
// RenderMode::M_filled_flat is in effect.
@ -873,6 +889,9 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
pixel_count_white_perspective = 0;
pixel_count_flat_perspective = 0;
pixel_count_smooth_perspective = 0;
pixel_count_white_multitex = 0;
pixel_count_flat_multitex = 0;
pixel_count_smooth_multitex = 0;
#endif // DO_PSTATS
return true;
@ -1268,6 +1287,9 @@ end_draw_primitives() {
_pixel_count_white_perspective_pcollector.add_level(pixel_count_white_perspective);
_pixel_count_flat_perspective_pcollector.add_level(pixel_count_flat_perspective);
_pixel_count_smooth_perspective_pcollector.add_level(pixel_count_smooth_perspective);
_pixel_count_white_multitex_pcollector.add_level(pixel_count_white_multitex);
_pixel_count_flat_multitex_pcollector.add_level(pixel_count_flat_multitex);
_pixel_count_smooth_multitex_pcollector.add_level(pixel_count_smooth_multitex);
#endif // DO_PSTATS
GraphicsStateGuardian::end_draw_primitives();
@ -1537,7 +1559,7 @@ prepare_texture(Texture *tex) {
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsStateGuardian::update_texture
// Access: Public, Virtual
// Access: Public
// Description: Ensures that the current Texture data is refreshed
// onto the GSG. This means updating the texture
// properties and/or re-uploading the texture image, if
@ -1552,7 +1574,7 @@ prepare_texture(Texture *tex) {
// true).
////////////////////////////////////////////////////////////////////
bool TinyGraphicsStateGuardian::
update_texture(TextureContext *tc, bool force) {
update_texture(TextureContext *tc, bool force, int stage_index) {
apply_texture(tc);
TinyTextureContext *gtc = DCAST(TinyTextureContext, tc);
@ -1570,8 +1592,8 @@ update_texture(TextureContext *tc, bool force) {
}
gtc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
_c->current_texture = gltex;
_c->zb->current_texture = gltex->levels;
_c->current_textures[stage_index] = gltex;
_c->zb->current_textures[stage_index] = gltex->levels;
return true;
}
@ -2026,35 +2048,44 @@ do_issue_material() {
void TinyGraphicsStateGuardian::
do_issue_texture() {
_texturing_state = 0; // untextured
_c->texture_2d_enabled = false;
_c->num_textures_enabled = 0;
int num_stages = _target_texture->get_num_on_ff_stages();
if (num_stages == 0) {
// No texturing.
return;
}
nassertv(num_stages == 1);
nassertv(num_stages <= MAX_TEXTURE_STAGES);
TextureStage *stage = _target_texture->get_on_ff_stage(0);
Texture *texture = _target_texture->get_on_texture(stage);
nassertv(texture != (Texture *)NULL);
Texture *texture = NULL;
for (int si = 0; si < num_stages; ++si) {
TextureStage *stage = _target_texture->get_on_ff_stage(si);
texture = _target_texture->get_on_texture(stage);
nassertv(texture != (Texture *)NULL);
TextureContext *tc = texture->prepare_now(_prepared_objects, this);
if (tc == (TextureContext *)NULL) {
// Something wrong with this texture; skip it.
return;
}
TextureContext *tc = texture->prepare_now(_prepared_objects, this);
if (tc == (TextureContext *)NULL) {
// Something wrong with this texture; skip it.
return;
}
// Then, turn on the current texture mode.
if (!update_texture(tc, false)) {
return;
// Then, turn on the current texture mode.
if (!update_texture(tc, false, si)) {
return;
}
// M_replace means M_replace; anything else is treated the same as
// M_modulate.
_texture_replace = (stage->get_mode() == TextureStage::M_replace);
}
// Set a few state cache values.
_c->texture_2d_enabled = true;
_c->num_textures_enabled = num_stages;
_texturing_state = 2; // perspective (perspective-correct texturing)
if (!td_perspective_textures) {
if (num_stages >= 2) {
_texturing_state = 3; // multitexture
} else if (!td_perspective_textures) {
_texturing_state = 1; // textured (not perspective correct)
}
@ -2086,7 +2117,7 @@ do_issue_texture() {
// This is the cheapest texture filter. We disallow mipmaps and
// perspective correctness.
_texfilter_state = 0; // tnearest
_texturing_state = 1; // textured (not perspective correct)
_texturing_state = 1; // textured (not perspective correct, no multitexture)
} else {
// This is the default texture filter. We use nearest sampling if
@ -2097,10 +2128,6 @@ do_issue_texture() {
_texfilter_state = 1; // tmipmap
}
}
// M_replace means M_replace; anything else is treated the same as
// M_modulate.
_texture_replace = (stage->get_mode() == TextureStage::M_replace);
}
////////////////////////////////////////////////////////////////////

View File

@ -82,7 +82,7 @@ public:
const TransformState *transform);
virtual TextureContext *prepare_texture(Texture *tex);
virtual bool update_texture(TextureContext *tc, bool force);
bool update_texture(TextureContext *tc, bool force, int stage_index);
virtual void release_texture(TextureContext *tc);
virtual void do_issue_light();
@ -173,6 +173,9 @@ private:
static PStatCollector _pixel_count_white_perspective_pcollector;
static PStatCollector _pixel_count_flat_perspective_pcollector;
static PStatCollector _pixel_count_smooth_perspective_pcollector;
static PStatCollector _pixel_count_white_multitex_pcollector;
static PStatCollector _pixel_count_flat_multitex_pcollector;
static PStatCollector _pixel_count_smooth_multitex_pcollector;
public:
static TypeHandle get_class_type() {

View File

@ -20,6 +20,9 @@ int pixel_count_smooth_textured;
int pixel_count_white_perspective;
int pixel_count_flat_perspective;
int pixel_count_smooth_perspective;
int pixel_count_white_multitex;
int pixel_count_flat_multitex;
int pixel_count_smooth_multitex;
#endif // DO_PSTATS
ZBuffer *ZB_open(int xsize, int ysize, int mode,
@ -80,7 +83,8 @@ ZBuffer *ZB_open(int xsize, int ysize, int mode,
zb->pbuf = (PIXEL *)frame_buffer;
}
zb->current_texture = NULL;
zb->current_textures[0] = NULL;
zb->current_textures[1] = NULL;
return zb;
error:

View File

@ -43,11 +43,11 @@ typedef unsigned short ZPOINT;
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 \
#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); \
(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
@ -81,6 +81,8 @@ typedef unsigned int PIXEL;
// 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))
// 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 >
@ -126,7 +128,7 @@ struct ZBuffer {
int nb_colors;
unsigned char *dctable;
int *ctable;
ZTextureLevel *current_texture; // This is actually an array of texture levels.
ZTextureLevel *current_textures[MAX_TEXTURE_STAGES]; // This is actually an array of texture levels for each stage.
int reference_alpha;
int blend_r, blend_g, blend_b, blend_a;
ZB_storePixelFunc store_pix_func;
@ -140,6 +142,9 @@ struct ZBufferPoint {
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;
};
/* zbuffer.c */
@ -154,6 +159,9 @@ 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_white_multitex;
extern int pixel_count_flat_multitex;
extern int pixel_count_smooth_multitex;
#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

View File

@ -36,4 +36,7 @@
#define TGL_FEATURE_24_BITS 1
#define TGL_FEATURE_32_BITS 1
/* Number of simultaneous texture stages supported (multitexture). */
#define MAX_TEXTURE_STAGES 2
#endif /* _tgl_features_h_ */

View File

@ -105,7 +105,7 @@ typedef struct GLVertex {
int edge_flag;
V3 normal;
V4 coord;
V4 tex_coord;
V4 tex_coord[MAX_TEXTURE_STAGES];
V4 color;
/* computed values */
@ -151,8 +151,8 @@ typedef struct GLContext {
GLMaterial materials[2];
/* textures */
GLTexture *current_texture;
int texture_2d_enabled;
GLTexture *current_textures[MAX_TEXTURE_STAGES];
int num_textures_enabled;
/* matrix */
M4 matrix_projection;
@ -180,7 +180,6 @@ typedef struct GLContext {
/* current vertex state */
V4 current_color;
V4 current_normal;
V4 current_tex_coord;
/* depth test */
int depth_test;

View File

@ -33,9 +33,16 @@
float sz1,dszdx,dszdy,dszdl_min,dszdl_max;
float tz1,dtzdx,dtzdy,dtzdl_min,dtzdl_max;
#endif
#ifdef INTERP_STZA
float sza1,dszadx,dszady,dszadl_min,dszadl_max;
float tza1,dtzadx,dtzady,dtzadl_min,dtzadl_max;
#endif
#if defined(INTERP_MIPMAP) && (defined(INTERP_ST) || defined(INTERP_STZ))
unsigned int mipmap_dx, mipmap_level;
#endif
#ifdef INTERP_STZA
unsigned int mipmap_dxa, mipmap_levela;
#endif
EARLY_OUT();
@ -117,7 +124,7 @@
dtdx = (int) (fdy2 * d1 - fdy1 * d2);
dtdy = (int) (fdx1 * d2 - fdx2 * d1);
CALC_MIPMAP_LEVEL;
CALC_MIPMAP_LEVEL(mipmap_level, mipmap_dx, dsdx, dtdx);
#endif
#ifdef INTERP_STZ
@ -145,6 +152,31 @@
}
#endif
#ifdef INTERP_STZA
{
float zz;
zz=(float) p0->z;
p0->sza= (float) p0->sa * zz;
p0->tza= (float) p0->ta * zz;
zz=(float) p1->z;
p1->sza= (float) p1->sa * zz;
p1->tza= (float) p1->ta * zz;
zz=(float) p2->z;
p2->sza= (float) p2->sa * zz;
p2->tza= (float) p2->ta * zz;
d1 = p1->sza - p0->sza;
d2 = p2->sza - p0->sza;
dszadx = (fdy2 * d1 - fdy1 * d2);
dszady = (fdx1 * d2 - fdx2 * d1);
d1 = p1->tza - p0->tza;
d2 = p2->tza - p0->tza;
dtzadx = (fdy2 * d1 - fdy1 * d2);
dtzady = (fdx1 * d2 - fdx2 * d1);
}
#endif
/* screen coordinates */
pp1 = (PIXEL *) ((char *) zb->pbuf + zb->linesize * p0->y);
@ -240,6 +272,15 @@
tz1=l1->tz;
dtzdl_min=(dtzdy + dtzdx * dxdy_min);
dtzdl_max=dtzdl_min + dtzdx;
#endif
#ifdef INTERP_STZA
sza1=l1->sza;
dszadl_min=(dszady + dszadx * dxdy_min);
dszadl_max=dszadl_min + dszadx;
tza1=l1->tza;
dtzadl_min=(dtzady + dtzadx * dxdy_min);
dtzadl_max=dtzadl_min + dtzadx;
#endif
}
@ -277,6 +318,9 @@
#ifdef INTERP_STZ
float sz,tz;
#endif
#ifdef INTERP_STZA
float sza,tza;
#endif
n=(x2 >> 16) - x1;
pp=(PIXEL *)((char *)pp1 + x1 * PSZB);
@ -297,6 +341,10 @@
#ifdef INTERP_STZ
sz=sz1;
tz=tz1;
#endif
#ifdef INTERP_STZA
sza=sza1;
tza=tza1;
#endif
while (n>=3) {
PUT_PIXEL(0);
@ -343,6 +391,10 @@
#ifdef INTERP_STZ
sz1+=dszdl_max;
tz1+=dtzdl_max;
#endif
#ifdef INTERP_STZA
sza1+=dszadl_max;
tza1+=dtzadl_max;
#endif
} else {
x1+=dxdy_min;
@ -362,6 +414,10 @@
#ifdef INTERP_STZ
sz1+=dszdl_min;
tz1+=dtzdl_min;
#endif
#ifdef INTERP_STZA
sza1+=dszadl_min;
tza1+=dtzadl_min;
#endif
}
@ -379,6 +435,7 @@
#undef INTERP_RGB
#undef INTERP_ST
#undef INTERP_STZ
#undef INTERP_STZA
#undef EARLY_OUT
#undef EARLY_OUT_FZ

View File

@ -34,7 +34,7 @@ ExtraOptions = [
[ 'white', 'flat', 'smooth' ],
# texturing
[ 'untextured', 'textured', 'perspective' ],
[ 'untextured', 'textured', 'perspective', 'multitex' ],
]
FullOptions = Options + ExtraOptions
@ -60,9 +60,9 @@ CodeTable = {
'zless' : '#define ZCMP(zpix, z) ((ZPOINT)(zpix) < (ZPOINT)(z))',
# texture filters
'tnearest' : '#define CALC_MIPMAP_LEVEL\n#define ZB_LOOKUP_TEXTURE(texture_levels, s, t, level, level_dx) ZB_LOOKUP_TEXTURE_NEAREST(texture_levels, s, t)',
'tmipmap' : '#define CALC_MIPMAP_LEVEL DO_CALC_MIPMAP_LEVEL\n#define INTERP_MIPMAP\n#define ZB_LOOKUP_TEXTURE(texture_levels, s, t, level, level_dx) ZB_LOOKUP_TEXTURE_MIPMAP_NEAREST(texture_levels, s, t, level)',
'tgeneral' : '#define CALC_MIPMAP_LEVEL DO_CALC_MIPMAP_LEVEL\n#define INTERP_MIPMAP\n#define ZB_LOOKUP_TEXTURE(texture_levels, s, t, level, level_dx) ((level == 0) ? zb->tex_magfilter_func(texture_levels, s, t, level, level_dx) : zb->tex_minfilter_func(texture_levels, s, t, level, level_dx))',
'tnearest' : '#define CALC_MIPMAP_LEVEL(mipmap_level, mipmap_dx, dsdx, dtdx)\n#define ZB_LOOKUP_TEXTURE(texture_levels, s, t, level, level_dx) ZB_LOOKUP_TEXTURE_NEAREST(texture_levels, s, t)',
'tmipmap' : '#define CALC_MIPMAP_LEVEL(mipmap_level, mipmap_dx, dsdx, dtdx) DO_CALC_MIPMAP_LEVEL(mipmap_level, mipmap_dx, dsdx, dtdx)\n#define INTERP_MIPMAP\n#define ZB_LOOKUP_TEXTURE(texture_levels, s, t, level, level_dx) ZB_LOOKUP_TEXTURE_MIPMAP_NEAREST(texture_levels, s, t, level)',
'tgeneral' : '#define CALC_MIPMAP_LEVEL(mipmap_level, mipmap_dx, dsdx, dtdx) DO_CALC_MIPMAP_LEVEL(mipmap_level, mipmap_dx, dsdx, dtdx)\n#define INTERP_MIPMAP\n#define ZB_LOOKUP_TEXTURE(texture_levels, s, t, level, level_dx) ((level == 0) ? zb->tex_magfilter_func(texture_levels, s, t, level, level_dx) : zb->tex_minfilter_func(texture_levels, s, t, level, level_dx))',
}
ops = [0] * len(Options)
@ -91,6 +91,10 @@ def getFname(ops):
keyword = FullOptions[i][ops[i]]
keywordList.append(keyword)
if keywordList[-1] == 'multitex':
# We don't bother with white_multitex or flat_multitex.
keywordList[-2] = 'smooth'
fname = 'FB_triangle_%s' % ('_'.join(keywordList))
return fname

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,3 @@
/* This file is generated code--do not edit. See ztriangle.py. */
extern const ZB_fillTriangleFunc fill_tri_funcs[2][4][3][2][3][3][3];
extern const ZB_fillTriangleFunc fill_tri_funcs[2][4][3][2][3][3][4];

View File

@ -128,7 +128,7 @@ static void FNAME(white_textured) (ZBuffer *zb,
#define DRAW_INIT() \
{ \
texture_levels = zb->current_texture; \
texture_levels = zb->current_textures[0]; \
}
#define PUT_PIXEL(_a) \
@ -170,7 +170,7 @@ static void FNAME(flat_textured) (ZBuffer *zb,
/* This alpha is zero, and we'll never get other than 0. */ \
return; \
} \
texture_levels = zb->current_texture; \
texture_levels = zb->current_textures[0]; \
or0 = p2->r; \
og0 = p2->g; \
ob0 = p2->b; \
@ -235,7 +235,7 @@ static void FNAME(smooth_textured) (ZBuffer *zb,
#define DRAW_INIT() \
{ \
texture_levels = zb->current_texture; \
texture_levels = zb->current_textures[0]; \
}
#define PUT_PIXEL(_a) \
@ -293,7 +293,7 @@ static void FNAME(white_perspective) (ZBuffer *zb,
#define DRAW_INIT() \
{ \
texture_levels = zb->current_texture; \
texture_levels = zb->current_textures[0]; \
fdzdx=(float)dzdx; \
fndzdx=NB_INTERP * fdzdx; \
ndszdx=NB_INTERP * dszdx; \
@ -340,7 +340,7 @@ static void FNAME(white_perspective) (ZBuffer *zb,
t=(int) tt; \
dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \
dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \
CALC_MIPMAP_LEVEL; \
CALC_MIPMAP_LEVEL(mipmap_level, mipmap_dx, dsdx, dtdx); \
fz+=fndzdx; \
zinv=1.0f / fz; \
} \
@ -366,7 +366,7 @@ static void FNAME(white_perspective) (ZBuffer *zb,
t=(int) tt; \
dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \
dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \
CALC_MIPMAP_LEVEL; \
CALC_MIPMAP_LEVEL(mipmap_level, mipmap_dx, dsdx, dtdx); \
} \
while (n>=0) { \
PUT_PIXEL(0); \
@ -406,7 +406,7 @@ static void FNAME(flat_perspective) (ZBuffer *zb,
/* This alpha is zero, and we'll never get other than 0. */ \
return; \
} \
texture_levels = zb->current_texture; \
texture_levels = zb->current_textures[0]; \
fdzdx=(float)dzdx; \
fndzdx=NB_INTERP * fdzdx; \
ndszdx=NB_INTERP * dszdx; \
@ -470,7 +470,7 @@ static void FNAME(flat_perspective) (ZBuffer *zb,
t=(int) tt; \
dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \
dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \
CALC_MIPMAP_LEVEL; \
CALC_MIPMAP_LEVEL(mipmap_level, mipmap_dx, dsdx, dtdx); \
fz+=fndzdx; \
zinv=1.0f / fz; \
} \
@ -496,7 +496,7 @@ static void FNAME(flat_perspective) (ZBuffer *zb,
t=(int) tt; \
dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \
dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \
CALC_MIPMAP_LEVEL; \
CALC_MIPMAP_LEVEL(mipmap_level, mipmap_dx, dsdx, dtdx); \
} \
while (n>=0) { \
PUT_PIXEL(0); \
@ -545,7 +545,7 @@ static void FNAME(smooth_perspective) (ZBuffer *zb,
#define DRAW_INIT() \
{ \
texture_levels = zb->current_texture; \
texture_levels = zb->current_textures[0]; \
fdzdx=(float)dzdx; \
fndzdx=NB_INTERP * fdzdx; \
ndszdx=NB_INTERP * dszdx; \
@ -609,7 +609,7 @@ static void FNAME(smooth_perspective) (ZBuffer *zb,
t=(int) tt; \
dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \
dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \
CALC_MIPMAP_LEVEL; \
CALC_MIPMAP_LEVEL(mipmap_level, mipmap_dx, dsdx, dtdx); \
fz+=fndzdx; \
zinv=1.0f / fz; \
} \
@ -635,7 +635,7 @@ static void FNAME(smooth_perspective) (ZBuffer *zb,
t=(int) tt; \
dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \
dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \
CALC_MIPMAP_LEVEL; \
CALC_MIPMAP_LEVEL(mipmap_level, mipmap_dx, dsdx, dtdx); \
} \
while (n>=0) { \
PUT_PIXEL(0); \
@ -650,6 +650,160 @@ static void FNAME(smooth_perspective) (ZBuffer *zb,
#include "ztriangle.h"
}
/*
* Smooth filled triangle, with perspective-correct mapping, on two
* stages of multitexture.
*/
static void FNAME(smooth_multitex) (ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2)
{
float fdzdx,fndzdx,ndszdx,ndtzdx,ndszadx,ndtzadx;
#define INTERP_Z
#define INTERP_STZ
#define INTERP_STZA
#define INTERP_RGB
#define EARLY_OUT() \
{ \
}
#define DRAW_INIT() \
{ \
fdzdx=(float)dzdx; \
fndzdx=NB_INTERP * fdzdx; \
ndszdx=NB_INTERP * dszdx; \
ndtzdx=NB_INTERP * dtzdx; \
ndszadx=NB_INTERP * dszadx; \
ndtzadx=NB_INTERP * dtzadx; \
}
#define PUT_PIXEL(_a) \
{ \
zz=z >> ZB_POINT_Z_FRAC_BITS; \
if (ZCMP(pz[_a], zz)) { \
tmp = ZB_LOOKUP_TEXTURE(zb->current_textures[0], s, t, mipmap_level, mipmap_dx); \
int a = PALPHA_MULT(oa1, PIXEL_A(tmp)); \
if (ACMP(zb, a)) { \
int tmpa = ZB_LOOKUP_TEXTURE(zb->current_textures[1], sa, ta, mipmap_levela, mipmap_dxa); \
STORE_PIX(pp[_a], \
RGBA_TO_PIXEL(PCOMPONENT_MULT3(or1, PIXEL_R(tmp), PIXEL_R(tmpa)), \
PCOMPONENT_MULT3(og1, PIXEL_G(tmp), PIXEL_G(tmpa)), \
PCOMPONENT_MULT3(ob1, PIXEL_B(tmp), PIXEL_B(tmpa)), \
a), \
PCOMPONENT_MULT3(or1, PIXEL_R(tmp), PIXEL_R(tmpa)), \
PCOMPONENT_MULT3(og1, PIXEL_G(tmp), PIXEL_G(tmpa)), \
PCOMPONENT_MULT3(ob1, PIXEL_B(tmp), PIXEL_B(tmpa)), \
a); \
STORE_Z(pz[_a], zz); \
} \
} \
z+=dzdx; \
og1+=dgdx; \
or1+=drdx; \
ob1+=dbdx; \
oa1+=dadx; \
s+=dsdx; \
t+=dtdx; \
sa+=dsadx; \
ta+=dtadx; \
}
#define DRAW_LINE() \
{ \
register ZPOINT *pz; \
register PIXEL *pp; \
register int s,t,sa,ta,z,zz; \
register int n,dsdx,dtdx,dsadx,dtadx; \
register int or1,og1,ob1,oa1; \
float sz,tz,sza,tza,fz,zinv; \
n=(x2>>16)-x1; \
fz=(float)z1; \
zinv=1.0f / fz; \
pp=(PIXEL *)((char *)pp1 + x1 * PSZB); \
pz=pz1+x1; \
z=z1; \
sz=sz1; \
tz=tz1; \
sza=sza1; \
tza=tza1; \
or1 = r1; \
og1 = g1; \
ob1 = b1; \
oa1 = a1; \
while (n>=(NB_INTERP-1)) { \
{ \
float ss,tt; \
ss=(sz * zinv); \
tt=(tz * zinv); \
s=(int) ss; \
t=(int) tt; \
dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \
dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \
CALC_MIPMAP_LEVEL(mipmap_level, mipmap_dx, dsdx, dtdx); \
} \
{ \
float ssa,tta; \
ssa=(sza * zinv); \
tta=(tza * zinv); \
sa=(int) ssa; \
ta=(int) tta; \
dsadx= (int)( (dszadx - ssa*fdzdx)*zinv ); \
dtadx= (int)( (dtzadx - tta*fdzdx)*zinv ); \
CALC_MIPMAP_LEVEL(mipmap_levela, mipmap_dxa, dsadx, dtadx); \
} \
fz+=fndzdx; \
zinv=1.0f / fz; \
PUT_PIXEL(0); \
PUT_PIXEL(1); \
PUT_PIXEL(2); \
PUT_PIXEL(3); \
PUT_PIXEL(4); \
PUT_PIXEL(5); \
PUT_PIXEL(6); \
PUT_PIXEL(7); \
pz+=NB_INTERP; \
pp=(PIXEL *)((char *)pp + NB_INTERP * PSZB); \
n-=NB_INTERP; \
sz+=ndszdx; \
tz+=ndtzdx; \
sza+=ndszadx; \
tza+=ndtzadx; \
} \
{ \
float ss,tt; \
ss=(sz * zinv); \
tt=(tz * zinv); \
s=(int) ss; \
t=(int) tt; \
dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \
dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \
CALC_MIPMAP_LEVEL(mipmap_level, mipmap_dx, dsdx, dtdx); \
} \
{ \
float ssa,tta; \
ssa=(sza * zinv); \
tta=(tza * zinv); \
sa=(int) ssa; \
ta=(int) tta; \
dsadx= (int)( (dszadx - ssa*fdzdx)*zinv ); \
dtadx= (int)( (dtzadx - tta*fdzdx)*zinv ); \
CALC_MIPMAP_LEVEL(mipmap_levela, mipmap_dxa, dsadx, dtadx); \
} \
while (n>=0) { \
PUT_PIXEL(0); \
pz+=1; \
pp=(PIXEL *)((char *)pp + PSZB); \
n-=1; \
} \
}
#define PIXEL_COUNT pixel_count_smooth_multitex
#include "ztriangle.h"
}
#undef ACMP
#undef ZCMP
#undef STORE_PIX