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); + ZB_POINT_ALPHA_MIN);
/* texture */ /* texture */
if (c->texture_2d_enabled) { if (c->num_textures_enabled >= 1) {
v->zp.s = (int)(v->tex_coord.v[0] * c->current_texture->s_max); static const int si = 0;
v->zp.t = (int)(v->tex_coord.v[1] * c->current_texture->t_max); 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]; q->color.v[3]=p0->color.v[3];
} }
if (c->texture_2d_enabled) { for (int si = 0; si < c->num_textures_enabled; ++si) {
q->tex_coord.v[0]=p0->tex_coord.v[0] + (p1->tex_coord.v[0]-p0->tex_coord.v[0])*t; 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.v[1]=p0->tex_coord.v[1] + (p1->tex_coord.v[1]-p0->tex_coord.v[1])*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]); 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); gl_transform_to_viewport(c,q);
}
} }
static void gl_draw_triangle_clip(GLContext *c, static void gl_draw_triangle_clip(GLContext *c,
@ -368,7 +375,7 @@ void gl_draw_triangle_fill(GLContext *c,
#endif #endif
#ifdef PROFILE #ifdef PROFILE
if (c->texture_2d_enabled) { if (c->num_textures_enabled != 0) {
count_triangles_textured++; count_triangles_textured++;
} }
#endif #endif

View File

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

View File

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

View File

@ -43,11 +43,11 @@ typedef unsigned short ZPOINT;
already doing the right thing. Is msvc? */ already doing the right thing. Is msvc? */
//#define FAST_ABS(v) (((v) ^ ((v) >> (sizeof(v) * 8 - 1))) - ((v) >> (sizeof(v) * 8 - 1))) //#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_dx) = ((unsigned int)abs(dsdx) + (unsigned int)abs(dtdx)); \
mipmap_level = get_next_higher_bit(mipmap_dx >> ZB_POINT_ST_FRAC_BITS); \ (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) &= ((1 << (((mipmap_level) - 1) + ZB_POINT_ST_FRAC_BITS)) - 1); \
} }
#define ZB_POINT_RED_MIN 0x0000 #define ZB_POINT_RED_MIN 0x0000
@ -81,6 +81,8 @@ typedef unsigned int PIXEL;
// Returns an unsigned product of c1 * c2 // Returns an unsigned product of c1 * c2
#define PCOMPONENT_MULT(c1, c2) \ #define PCOMPONENT_MULT(c1, c2) \
((((unsigned int)(c1) * (unsigned int)(c2))) >> 16) ((((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. // 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 > // We leave 2 bits on the top to differentiate between c1 < 0 and c1 >
@ -126,7 +128,7 @@ struct ZBuffer {
int nb_colors; int nb_colors;
unsigned char *dctable; unsigned char *dctable;
int *ctable; 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 reference_alpha;
int blend_r, blend_g, blend_b, blend_a; int blend_r, blend_g, blend_b, blend_a;
ZB_storePixelFunc store_pix_func; ZB_storePixelFunc store_pix_func;
@ -140,6 +142,9 @@ struct ZBufferPoint {
int r,g,b,a; /* color indexes */ int r,g,b,a; /* color indexes */
float sz,tz; /* temporary coordinates for mapping */ float sz,tz; /* temporary coordinates for mapping */
int sa, ta; /* mapping coordinates for optional second texture stage */
float sza,tza;
}; };
/* zbuffer.c */ /* zbuffer.c */
@ -154,6 +159,9 @@ extern int pixel_count_smooth_textured;
extern int pixel_count_white_perspective; extern int pixel_count_white_perspective;
extern int pixel_count_flat_perspective; extern int pixel_count_flat_perspective;
extern int pixel_count_smooth_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) \ #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 (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_24_BITS 1
#define TGL_FEATURE_32_BITS 1 #define TGL_FEATURE_32_BITS 1
/* Number of simultaneous texture stages supported (multitexture). */
#define MAX_TEXTURE_STAGES 2
#endif /* _tgl_features_h_ */ #endif /* _tgl_features_h_ */

View File

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

View File

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

View File

@ -34,7 +34,7 @@ ExtraOptions = [
[ 'white', 'flat', 'smooth' ], [ 'white', 'flat', 'smooth' ],
# texturing # texturing
[ 'untextured', 'textured', 'perspective' ], [ 'untextured', 'textured', 'perspective', 'multitex' ],
] ]
FullOptions = Options + ExtraOptions FullOptions = Options + ExtraOptions
@ -60,9 +60,9 @@ CodeTable = {
'zless' : '#define ZCMP(zpix, z) ((ZPOINT)(zpix) < (ZPOINT)(z))', 'zless' : '#define ZCMP(zpix, z) ((ZPOINT)(zpix) < (ZPOINT)(z))',
# texture filters # 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)', '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 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)', '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 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))', '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) ops = [0] * len(Options)
@ -91,6 +91,10 @@ def getFname(ops):
keyword = FullOptions[i][ops[i]] keyword = FullOptions[i][ops[i]]
keywordList.append(keyword) 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)) fname = 'FB_triangle_%s' % ('_'.join(keywordList))
return fname 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. */ /* 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() \ #define DRAW_INIT() \
{ \ { \
texture_levels = zb->current_texture; \ texture_levels = zb->current_textures[0]; \
} }
#define PUT_PIXEL(_a) \ #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. */ \ /* This alpha is zero, and we'll never get other than 0. */ \
return; \ return; \
} \ } \
texture_levels = zb->current_texture; \ texture_levels = zb->current_textures[0]; \
or0 = p2->r; \ or0 = p2->r; \
og0 = p2->g; \ og0 = p2->g; \
ob0 = p2->b; \ ob0 = p2->b; \
@ -235,7 +235,7 @@ static void FNAME(smooth_textured) (ZBuffer *zb,
#define DRAW_INIT() \ #define DRAW_INIT() \
{ \ { \
texture_levels = zb->current_texture; \ texture_levels = zb->current_textures[0]; \
} }
#define PUT_PIXEL(_a) \ #define PUT_PIXEL(_a) \
@ -293,7 +293,7 @@ static void FNAME(white_perspective) (ZBuffer *zb,
#define DRAW_INIT() \ #define DRAW_INIT() \
{ \ { \
texture_levels = zb->current_texture; \ texture_levels = zb->current_textures[0]; \
fdzdx=(float)dzdx; \ fdzdx=(float)dzdx; \
fndzdx=NB_INTERP * fdzdx; \ fndzdx=NB_INTERP * fdzdx; \
ndszdx=NB_INTERP * dszdx; \ ndszdx=NB_INTERP * dszdx; \
@ -340,7 +340,7 @@ static void FNAME(white_perspective) (ZBuffer *zb,
t=(int) tt; \ t=(int) tt; \
dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \ dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \
dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \ dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \
CALC_MIPMAP_LEVEL; \ CALC_MIPMAP_LEVEL(mipmap_level, mipmap_dx, dsdx, dtdx); \
fz+=fndzdx; \ fz+=fndzdx; \
zinv=1.0f / fz; \ zinv=1.0f / fz; \
} \ } \
@ -366,7 +366,7 @@ static void FNAME(white_perspective) (ZBuffer *zb,
t=(int) tt; \ t=(int) tt; \
dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \ dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \
dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \ dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \
CALC_MIPMAP_LEVEL; \ CALC_MIPMAP_LEVEL(mipmap_level, mipmap_dx, dsdx, dtdx); \
} \ } \
while (n>=0) { \ while (n>=0) { \
PUT_PIXEL(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. */ \ /* This alpha is zero, and we'll never get other than 0. */ \
return; \ return; \
} \ } \
texture_levels = zb->current_texture; \ texture_levels = zb->current_textures[0]; \
fdzdx=(float)dzdx; \ fdzdx=(float)dzdx; \
fndzdx=NB_INTERP * fdzdx; \ fndzdx=NB_INTERP * fdzdx; \
ndszdx=NB_INTERP * dszdx; \ ndszdx=NB_INTERP * dszdx; \
@ -470,7 +470,7 @@ static void FNAME(flat_perspective) (ZBuffer *zb,
t=(int) tt; \ t=(int) tt; \
dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \ dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \
dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \ dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \
CALC_MIPMAP_LEVEL; \ CALC_MIPMAP_LEVEL(mipmap_level, mipmap_dx, dsdx, dtdx); \
fz+=fndzdx; \ fz+=fndzdx; \
zinv=1.0f / fz; \ zinv=1.0f / fz; \
} \ } \
@ -496,7 +496,7 @@ static void FNAME(flat_perspective) (ZBuffer *zb,
t=(int) tt; \ t=(int) tt; \
dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \ dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \
dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \ dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \
CALC_MIPMAP_LEVEL; \ CALC_MIPMAP_LEVEL(mipmap_level, mipmap_dx, dsdx, dtdx); \
} \ } \
while (n>=0) { \ while (n>=0) { \
PUT_PIXEL(0); \ PUT_PIXEL(0); \
@ -545,7 +545,7 @@ static void FNAME(smooth_perspective) (ZBuffer *zb,
#define DRAW_INIT() \ #define DRAW_INIT() \
{ \ { \
texture_levels = zb->current_texture; \ texture_levels = zb->current_textures[0]; \
fdzdx=(float)dzdx; \ fdzdx=(float)dzdx; \
fndzdx=NB_INTERP * fdzdx; \ fndzdx=NB_INTERP * fdzdx; \
ndszdx=NB_INTERP * dszdx; \ ndszdx=NB_INTERP * dszdx; \
@ -609,7 +609,7 @@ static void FNAME(smooth_perspective) (ZBuffer *zb,
t=(int) tt; \ t=(int) tt; \
dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \ dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \
dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \ dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \
CALC_MIPMAP_LEVEL; \ CALC_MIPMAP_LEVEL(mipmap_level, mipmap_dx, dsdx, dtdx); \
fz+=fndzdx; \ fz+=fndzdx; \
zinv=1.0f / fz; \ zinv=1.0f / fz; \
} \ } \
@ -635,7 +635,7 @@ static void FNAME(smooth_perspective) (ZBuffer *zb,
t=(int) tt; \ t=(int) tt; \
dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \ dsdx= (int)( (dszdx - ss*fdzdx)*zinv ); \
dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \ dtdx= (int)( (dtzdx - tt*fdzdx)*zinv ); \
CALC_MIPMAP_LEVEL; \ CALC_MIPMAP_LEVEL(mipmap_level, mipmap_dx, dsdx, dtdx); \
} \ } \
while (n>=0) { \ while (n>=0) { \
PUT_PIXEL(0); \ PUT_PIXEL(0); \
@ -650,6 +650,160 @@ static void FNAME(smooth_perspective) (ZBuffer *zb,
#include "ztriangle.h" #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 ACMP
#undef ZCMP #undef ZCMP
#undef STORE_PIX #undef STORE_PIX