mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
multitexture tinydisplay
This commit is contained in:
parent
89d50d7ab3
commit
76f94669d0
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -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() {
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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_ */
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
@ -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];
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user