progress on rendering modes

This commit is contained in:
David Rose 2008-05-03 00:09:36 +00:00
parent bed83ef77f
commit d48ff75151
18 changed files with 1190 additions and 871 deletions

View File

@ -27,7 +27,7 @@
opinfo.h oscontext.c oscontext.h select.c specbuf.c \
specbuf.h texture.c tinygl.h tinyglu.h vertex.c \
zbuffer.c zbuffer.h zdither.c zfeatures.h zgl.h zline.c \
zline.h zmath.c zmath.h ztriangle.c ztriangle.h
zline.h zmath.c zmath.h ztriangle.c ztriangle.h ztriangle_two.h
#end lib_target

View File

@ -29,6 +29,8 @@ void gl_transform_to_viewport(GLContext *c,GLVertex *v)
+ ZB_POINT_GREEN_MIN);
v->zp.b=(int)(v->color.v[2] * (ZB_POINT_BLUE_MAX - ZB_POINT_BLUE_MIN)
+ ZB_POINT_BLUE_MIN);
v->zp.a=(int)(v->color.v[3] * (ZB_POINT_ALPHA_MAX - ZB_POINT_ALPHA_MIN)
+ ZB_POINT_ALPHA_MIN);
/* texture */
@ -78,6 +80,7 @@ static inline void interpolate(GLVertex *q,GLVertex *p0,GLVertex *p1,float t)
q->color.v[0]=p0->color.v[0] + (p1->color.v[0]-p0->color.v[0])*t;
q->color.v[1]=p0->color.v[1] + (p1->color.v[1]-p0->color.v[1])*t;
q->color.v[2]=p0->color.v[2] + (p1->color.v[2]-p0->color.v[2])*t;
q->color.v[3]=p0->color.v[3] + (p1->color.v[3]-p0->color.v[3])*t;
}
/*
@ -212,10 +215,12 @@ static inline void updateTmp(GLContext *c,
q->color.v[0]=p0->color.v[0] + (p1->color.v[0]-p0->color.v[0])*t;
q->color.v[1]=p0->color.v[1] + (p1->color.v[1]-p0->color.v[1])*t;
q->color.v[2]=p0->color.v[2] + (p1->color.v[2]-p0->color.v[2])*t;
q->color.v[3]=p0->color.v[3] + (p1->color.v[3]-p0->color.v[3])*t;
} else {
q->color.v[0]=p0->color.v[0];
q->color.v[1]=p0->color.v[1];
q->color.v[2]=p0->color.v[2];
q->color.v[3]=p0->color.v[3];
}
if (c->texture_2d_enabled) {
@ -393,18 +398,13 @@ void gl_draw_triangle_fill(GLContext *c,
}
#endif
if (c->texture_2d_enabled) {
#ifdef PROFILE
if (c->texture_2d_enabled) {
count_triangles_textured++;
#endif
ZB_setTexture(c->zb,c->current_texture->images[0].pixmap);
//ZB_fillTriangleMappingPerspective(c->zb,&p0->zp,&p1->zp,&p2->zp);
ZB_fillTriangleMappingSmooth(c->zb,&p0->zp,&p1->zp,&p2->zp);
} else if (c->current_shade_model == GL_SMOOTH) {
ZB_fillTriangleSmooth(c->zb,&p0->zp,&p1->zp,&p2->zp);
} else {
ZB_fillTriangleFlat(c->zb,&p0->zp,&p1->zp,&p2->zp);
}
#endif
(*c->zb_fill_tri)(c->zb,&p0->zp,&p1->zp,&p2->zp);
}
/* Render a clipped triangle in line mode */

View File

@ -92,24 +92,24 @@ void gl_resizeImage(unsigned char *dest,int xsize_dest,int ysize_dest,
yf=(int) ((y1 - floor(y1)) * INTERP_NORM);
if ((xf+yf) <= INTERP_NORM) {
for(j=0;j<3;j++) {
pix[j]=interpolate(pix_src[(yi*xsize_src+xi)*3+j],
pix_src[(yi*xsize_src+xi+1)*3+j],
pix_src[((yi+1)*xsize_src+xi)*3+j],
for(j=0;j<4;j++) {
pix[j]=interpolate(pix_src[(yi*xsize_src+xi)*4+j],
pix_src[(yi*xsize_src+xi+1)*4+j],
pix_src[((yi+1)*xsize_src+xi)*4+j],
xf,yf);
}
} else {
xf=INTERP_NORM - xf;
yf=INTERP_NORM - yf;
for(j=0;j<3;j++) {
pix[j]=interpolate(pix_src[((yi+1)*xsize_src+xi+1)*3+j],
pix_src[((yi+1)*xsize_src+xi)*3+j],
pix_src[(yi*xsize_src+xi+1)*3+j],
for(j=0;j<4;j++) {
pix[j]=interpolate(pix_src[((yi+1)*xsize_src+xi+1)*4+j],
pix_src[((yi+1)*xsize_src+xi)*4+j],
pix_src[(yi*xsize_src+xi+1)*4+j],
xf,yf);
}
}
pix+=3;
pix+=4;
x1+=x1inc;
}
y1+=y1inc;
@ -139,13 +139,14 @@ void gl_resizeImageNoInterpolate(unsigned char *dest,int xsize_dest,int ysize_de
for(x=0;x<xsize_dest;x++) {
xi=x1 >> FRAC_BITS;
yi=y1 >> FRAC_BITS;
pix1=pix_src+(yi*xsize_src+xi)*3;
pix1=pix_src+(yi*xsize_src+xi)*4;
pix[0]=pix1[0];
pix[1]=pix1[1];
pix[2]=pix1[2];
pix[3]=pix1[3];
pix+=3;
pix+=4;
x1+=x1inc;
}
y1+=y1inc;

View File

@ -151,12 +151,10 @@ void glopTexImage2D(GLContext *c,GLParam *p)
pixels1=pixels;
}
#if TGL_FEATURE_RENDER_BITS == 32
} else if ((target == GL_TEXTURE_2D && level == 0 && components == 4 &&
border == 0 && format == GL_RGBA &&
type == GL_UNSIGNED_BYTE && width == 256 && height == 256)) {
// RGBA format is acceptable if we have 32 render bits.
#endif
} else {
gl_fatal_error("glTexImage2D: combinaison of parameters not handled");
@ -166,12 +164,6 @@ void glopTexImage2D(GLContext *c,GLParam *p)
im->xsize=width;
im->ysize=height;
if (im->pixmap!=NULL) gl_free(im->pixmap);
#if TGL_FEATURE_RENDER_BITS == 24
im->pixmap=gl_malloc(width*height*3);
if(im->pixmap) {
memcpy(im->pixmap,pixels1,width*height*3);
}
#elif TGL_FEATURE_RENDER_BITS == 32
im->pixmap=gl_malloc(width*height*4);
if(im->pixmap) {
if (components == 4) {
@ -180,14 +172,6 @@ void glopTexImage2D(GLContext *c,GLParam *p)
gl_convertRGB_to_8A8R8G8B(im->pixmap,pixels1,width,height);
}
}
#elif TGL_FEATURE_RENDER_BITS == 16
im->pixmap=gl_malloc(width*height*2);
if(im->pixmap) {
gl_convertRGB_to_5R6G5B(im->pixmap,pixels1,width,height);
}
#else
#error TODO
#endif
if (do_free) gl_free(pixels1);
}

View File

@ -31,139 +31,61 @@ TypeHandle TinyGraphicsStateGuardian::_type_handle;
PStatCollector TinyGraphicsStateGuardian::_vertices_immediate_pcollector("Vertices:Immediate mode");
////////////////////////////////////////////////////////////////////
// Function: uchar_bgr_to_rgb
// Description: Recopies the given array of pixels, converting from
// BGR to RGB arrangement.
////////////////////////////////////////////////////////////////////
static void
uchar_bgr_to_rgb(unsigned char *dest, const unsigned char *source,
int num_pixels) {
for (int i = 0; i < num_pixels; i++) {
dest[0] = source[2];
dest[1] = source[1];
dest[2] = source[0];
dest += 3;
source += 3;
}
}
/*
////////////////////////////////////////////////////////////////////
// Function: uchar_bgra_to_rgba
// Description: Recopies the given array of pixels, converting from
// BGRA to RGBA arrangement.
////////////////////////////////////////////////////////////////////
static void
uchar_bgra_to_rgba(unsigned char *dest, const unsigned char *source,
int num_pixels) {
for (int i = 0; i < num_pixels; i++) {
dest[0] = source[2];
dest[1] = source[1];
dest[2] = source[0];
dest[3] = source[3];
dest += 4;
source += 4;
}
}
*/
////////////////////////////////////////////////////////////////////
// Function: uchar_bgra_to_rgb
// Description: Recopies the given array of pixels, converting from
// BGRA to RGB arrangement, dropping alpha.
////////////////////////////////////////////////////////////////////
static void
uchar_bgra_to_rgb(unsigned char *dest, const unsigned char *source,
int num_pixels) {
for (int i = 0; i < num_pixels; i++) {
dest[0] = source[2] * source[3] / 255;
dest[1] = source[1] * source[3] / 255;
dest[2] = source[0] * source[3] / 255;
dest += 3;
source += 4;
}
}
////////////////////////////////////////////////////////////////////
// Function: uchar_lum_to_rgb
// Description: Recopies the given array of pixels, converting from
// luminance to RGB arrangement.
////////////////////////////////////////////////////////////////////
static void
uchar_lum_to_rgb(unsigned char *dest, const unsigned char *source,
int num_pixels) {
for (int i = 0; i < num_pixels; i++) {
dest[0] = source[0];
dest[1] = source[0];
dest[2] = source[0];
dest += 3;
source += 1;
}
}
////////////////////////////////////////////////////////////////////
// Function: uchar_la_to_rgb
// Description: Recopies the given array of pixels, converting from
// luminance-alpha to RGB arrangement.
////////////////////////////////////////////////////////////////////
static void
uchar_la_to_rgb(unsigned char *dest, const unsigned char *source,
int num_pixels) {
for (int i = 0; i < num_pixels; i++) {
dest[2] = dest[1] = dest[0] = source[0] * source[1] / 255;
dest += 3;
source += 2;
}
}
////////////////////////////////////////////////////////////////////
// Function: restructure_image
// Description: Converts the pixels of the image to the appropriate
// format for TinyGL (i.e. GL_RGB).
////////////////////////////////////////////////////////////////////
static PTA_uchar
restructure_image(Texture *tex) {
int num_pixels = tex->get_x_size() * tex->get_y_size();
CPTA_uchar orig_image = tex->get_ram_image();
PTA_uchar new_image = PTA_uchar::empty_array(num_pixels * 3);
switch (tex->get_format()) {
case Texture::F_rgb:
case Texture::F_rgb5:
case Texture::F_rgb8:
case Texture::F_rgb12:
case Texture::F_rgb332:
uchar_bgr_to_rgb(new_image, orig_image, num_pixels);
break;
case Texture::F_rgba:
case Texture::F_rgbm:
case Texture::F_rgba4:
case Texture::F_rgba5:
case Texture::F_rgba8:
case Texture::F_rgba12:
case Texture::F_rgba16:
case Texture::F_rgba32:
uchar_bgra_to_rgb(new_image, orig_image, num_pixels);
break;
case Texture::F_luminance:
case Texture::F_alpha:
uchar_lum_to_rgb(new_image, orig_image, num_pixels);
break;
case Texture::F_luminance_alphamask:
case Texture::F_luminance_alpha:
uchar_la_to_rgb(new_image, orig_image, num_pixels);
break;
default:
break;
}
return new_image;
}
static const ZB_fillTriangleFunc fill_tri_funcs
[2 /* alpha test: anone, abin (binary) */]
[2 /* ztest: znone, zless */]
[3 /* white, flat, smooth */]
[3 /* untextured, textured, perspective textured */] = {
{ // alpha test anone
{
{ ZB_fillTriangleFlat_anone_znone,
ZB_fillTriangleMapping_anone_znone,
ZB_fillTriangleMappingPerspective_anone_znone },
{ ZB_fillTriangleFlat_anone_znone,
ZB_fillTriangleMappingFlat_anone_znone,
ZB_fillTriangleMappingPerspectiveFlat_anone_znone },
{ ZB_fillTriangleSmooth_anone_znone,
ZB_fillTriangleMappingSmooth_anone_znone,
ZB_fillTriangleMappingPerspectiveSmooth_anone_znone },
},
{
{ ZB_fillTriangleFlat_anone_zless,
ZB_fillTriangleMapping_anone_zless,
ZB_fillTriangleMappingPerspective_anone_zless },
{ ZB_fillTriangleFlat_anone_zless,
ZB_fillTriangleMappingFlat_anone_zless,
ZB_fillTriangleMappingPerspectiveFlat_anone_zless },
{ ZB_fillTriangleSmooth_anone_zless,
ZB_fillTriangleMappingSmooth_anone_zless,
ZB_fillTriangleMappingPerspectiveSmooth_anone_zless },
},
},
{ // alpha test abin
{
{ ZB_fillTriangleFlat_abin_znone,
ZB_fillTriangleMapping_abin_znone,
ZB_fillTriangleMappingPerspective_abin_znone },
{ ZB_fillTriangleFlat_abin_znone,
ZB_fillTriangleMappingFlat_abin_znone,
ZB_fillTriangleMappingPerspectiveFlat_abin_znone },
{ ZB_fillTriangleSmooth_abin_znone,
ZB_fillTriangleMappingSmooth_abin_znone,
ZB_fillTriangleMappingPerspectiveSmooth_abin_znone },
},
{
{ ZB_fillTriangleFlat_abin_zless,
ZB_fillTriangleMapping_abin_zless,
ZB_fillTriangleMappingPerspective_abin_zless },
{ ZB_fillTriangleFlat_abin_zless,
ZB_fillTriangleMappingFlat_abin_zless,
ZB_fillTriangleMappingPerspectiveFlat_abin_zless },
{ ZB_fillTriangleSmooth_abin_zless,
ZB_fillTriangleMappingSmooth_abin_zless,
ZB_fillTriangleMappingPerspectiveSmooth_abin_zless },
},
},
};
static inline void tgl_vertex_transform(GLContext * c, GLVertex * v)
{
@ -581,18 +503,17 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
gl_M4_Inv(&tmp, _c->matrix_stack_ptr[0]);
gl_M4_Transpose(&_c->matrix_model_view_inv, &tmp);
} else {
// If we're not using lighting, go ahead and compose the
// modelview and projection matrices.
load_matrix(&_c->matrix_model_projection,
_projection_mat->compose(_internal_transform));
}
/* test to accelerate computation */
_c->matrix_model_projection_no_w_transform = 0;
float *m = &_c->matrix_model_projection.m[0][0];
if (m[12] == 0.0 && m[13] == 0.0 && m[14] == 0.0) {
_c->matrix_model_projection_no_w_transform = 1;
}
// Compose the modelview and projection matrices.
load_matrix(&_c->matrix_model_projection,
_projection_mat->compose(_internal_transform));
/* test to accelerate computation */
_c->matrix_model_projection_no_w_transform = 0;
float *m = &_c->matrix_model_projection.m[0][0];
if (m[12] == 0.0 && m[13] == 0.0 && m[14] == 0.0) {
_c->matrix_model_projection_no_w_transform = 1;
}
_transform_stale = false;
}
@ -740,6 +661,47 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
v->edge_flag = 0;
}
// Set up the appropriate function callback for filling triangles,
// according to the current state.
int alpha_test_state = 0;
if (_target._transparency->get_mode() != TransparencyAttrib::M_none) {
alpha_test_state = 1;
}
int depth_test_state = 1;
if (_target._depth_test->get_mode() == DepthTestAttrib::M_none) {
depth_test_state = 0;
}
ShadeModelAttrib::Mode shade_model = _target._shade_model->get_mode();
if (!needs_normal && !needs_color) {
// With no per-vertex lighting, and no per-vertex colors, we might
// as well use the flat shading model.
shade_model = ShadeModelAttrib::M_flat;
}
int color_state = 2; // smooth
if (shade_model == ShadeModelAttrib::M_flat) {
color_state = 1; // flat
if (_c->current_color.X == 1.0f &&
_c->current_color.Y == 1.0f &&
_c->current_color.Z == 1.0f &&
_c->current_color.W == 1.0f) {
color_state = 0; // white
}
}
int texture_state = 0; // untextured
if (_c->texture_2d_enabled) {
texture_state = 2; // perspective-correct textures
if (_c->matrix_model_projection_no_w_transform) {
texture_state = 1; // non-perspective-correct textures
}
}
_c->zb_fill_tri = fill_tri_funcs[alpha_test_state][depth_test_state][color_state][texture_state];
//_c->zb_fill_tri = ZB_fillTriangleFlat_zless;
return true;
}
@ -962,12 +924,6 @@ set_state_and_transform(const RenderState *target,
_state._render_mode = _target._render_mode;
}
if (_target._shade_model != _state._shade_model) {
PStatTimer timer(_draw_set_state_shade_model_pcollector);
do_issue_shade_model();
_state._shade_model = _target._shade_model;
}
if ((_target._transparency != _state._transparency)||
(_target._color_write != _state._color_write)||
(_target._color_blend != _state._color_blend)) {
@ -1035,7 +991,7 @@ prepare_texture(Texture *tex) {
}
TinyTextureContext *gtc = new TinyTextureContext(_prepared_objects, tex);
glGenTextures(1, &gtc->_index);
gtc->_gltex = (GLTexture *)gl_zalloc(sizeof(GLTexture));
apply_texture(gtc);
return gtc;
@ -1053,9 +1009,22 @@ void TinyGraphicsStateGuardian::
release_texture(TextureContext *tc) {
TinyTextureContext *gtc = DCAST(TinyTextureContext, tc);
glDeleteTextures(1, &gtc->_index);
if (_c->current_texture == gtc->_gltex) {
_c->current_texture = NULL;
_c->zb->current_texture = NULL;
_c->texture_2d_enabled = false;
}
for (int i = 0; i < MAX_TEXTURE_LEVELS; i++) {
GLImage *im = &gtc->_gltex->images[i];
if (im->pixmap != NULL) {
gl_free(im->pixmap);
}
}
gl_free(gtc->_gltex);
gtc->_gltex = NULL;
gtc->_index = 0;
delete gtc;
}
@ -1183,25 +1152,6 @@ do_issue_transform() {
_transform_stale = true;
}
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsStateGuardian::do_issue_shade_model
// Access: Protected
// Description:
////////////////////////////////////////////////////////////////////
void TinyGraphicsStateGuardian::
do_issue_shade_model() {
const ShadeModelAttrib *attrib = _target._shade_model;
switch (attrib->get_mode()) {
case ShadeModelAttrib::M_smooth:
glShadeModel(GL_SMOOTH);
break;
case ShadeModelAttrib::M_flat:
glShadeModel(GL_FLAT);
break;
}
}
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsStateGuardian::do_issue_render_mode
// Access: Protected
@ -1339,7 +1289,7 @@ do_issue_material() {
////////////////////////////////////////////////////////////////////
void TinyGraphicsStateGuardian::
do_issue_texture() {
glDisable(GL_TEXTURE_2D);
_c->texture_2d_enabled = false;
int num_stages = _effective_texture->get_num_on_ff_stages();
if (num_stages == 0) {
@ -1359,7 +1309,6 @@ do_issue_texture() {
}
// Then, turn on the current texture mode.
glEnable(GL_TEXTURE_2D);
apply_texture(tc);
/*
@ -1508,12 +1457,13 @@ apply_texture(TextureContext *tc) {
TinyTextureContext *gtc = DCAST(TinyTextureContext, tc);
gtc->set_active(true);
glBindTexture(GL_TEXTURE_2D, gtc->_index);
_c->current_texture = gtc->_gltex;
_c->texture_2d_enabled = true;
if (gtc->was_image_modified()) {
// If the texture image was modified, reload the texture.
if (!upload_texture(gtc)) {
glDisable(GL_TEXTURE_2D);
_c->texture_2d_enabled = false;
}
gtc->mark_loaded();
@ -1522,6 +1472,8 @@ apply_texture(TextureContext *tc) {
// reload the texture.
gtc->mark_loaded();
}
_c->zb->current_texture = (PIXEL *)gtc->_gltex->images[0].pixmap;
}
////////////////////////////////////////////////////////////////////
@ -1541,24 +1493,70 @@ upload_texture(TinyTextureContext *gtc) {
tinydisplay_cat.debug()
<< "loading texture " << tex->get_name() << "\n";
}
CPTA_uchar image = tex->get_ram_image();
nassertr(!image.is_null(), false)
int width = tex->get_x_size();
int height = tex->get_y_size();
PTA_uchar new_image = restructure_image(tex);
const unsigned char *image_ptr = new_image.p();
#ifdef DO_PSTATS
_data_transferred_pcollector.add_level(new_image.size());
_data_transferred_pcollector.add_level(tex->get_ram_image_size());
#endif
glTexImage2D(GL_TEXTURE_2D, 0, 3,
width, height, 0,
GL_RGB, GL_UNSIGNED_BYTE, (void *)image_ptr);
// Internal texture size is always 256 x 256 x 4.
static const int iwidth = 256;
static const int iheight = 256;
static const int ibytecount = iwidth * iheight * 4;
GLImage *im = &gtc->_gltex->images[0];
im->xsize = iwidth;
im->ysize = iheight;
if (im->pixmap == NULL) {
im->pixmap = gl_malloc(ibytecount);
}
switch (tex->get_format()) {
case Texture::F_rgb:
case Texture::F_rgb5:
case Texture::F_rgb8:
case Texture::F_rgb12:
case Texture::F_rgb332:
copy_rgb_image(im, tex);
break;
case Texture::F_rgba:
case Texture::F_rgbm:
case Texture::F_rgba4:
case Texture::F_rgba5:
case Texture::F_rgba8:
case Texture::F_rgba12:
case Texture::F_rgba16:
case Texture::F_rgba32:
copy_rgba_image(im, tex);
break;
case Texture::F_luminance:
copy_lum_image(im, tex);
break;
case Texture::F_red:
copy_one_channel_image(im, tex, 0);
break;
case Texture::F_green:
copy_one_channel_image(im, tex, 1);
break;
case Texture::F_blue:
copy_one_channel_image(im, tex, 2);
break;
case Texture::F_alpha:
copy_alpha_image(im, tex);
break;
case Texture::F_luminance_alphamask:
case Texture::F_luminance_alpha:
copy_la_image(im, tex);
break;
}
#ifdef DO_PSTATS
gtc->update_data_size_bytes(256 * 256 * 3);
gtc->update_data_size_bytes(ibytecount);
#endif
tex->texture_uploaded();
@ -1566,6 +1564,339 @@ upload_texture(TinyTextureContext *gtc) {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsStateGuardian::copy_lum_image
// Access: Private, Static
// Description: Copies and scales the one-channel luminance image
// from the texture into the indicated GLImage pixmap.
////////////////////////////////////////////////////////////////////
void TinyGraphicsStateGuardian::
copy_lum_image(GLImage *im, Texture *tex) {
nassertv(tex->get_num_components() == 1);
int xsize_src = tex->get_x_size();
int ysize_src = tex->get_y_size();
CPTA_uchar src_image = tex->get_ram_image();
nassertv(!src_image.is_null());
const unsigned char *src = src_image.p();
// Component width, and offset to the high-order byte.
int cw = tex->get_component_width();
#ifdef WORDS_BIGENDIAN
// Big-endian: the high-order byte is always first.
static const int co = 0;
#else
// Little-endian: the high-order byte is last.
int co = cw - 1;
#endif
int xsize_dest = im->xsize;
int ysize_dest = im->xsize;
unsigned char *dest = (unsigned char *)im->pixmap;
nassertv(dest != NULL);
int sx_inc = (int)((float)(xsize_src) / (float)(xsize_dest));
int sy_inc = (int)((float)(ysize_src) / (float)(ysize_dest));
unsigned char *dpix = dest;
int syn = 0;
for (int dy = 0; dy < ysize_dest; dy++) {
int sy = syn / ysize_dest;
int sxn = 0;
for (int dx = 0; dx < xsize_dest; dx++) {
int sx = sxn / xsize_dest;
const unsigned char *spix = src + (sy * xsize_src + sx) * 1 * cw;
dpix[0] = spix[co];
dpix[1] = spix[co];
dpix[2] = spix[co];
dpix[3] = 0xff;
dpix += 4;
sxn += xsize_src;
}
syn += ysize_src;
}
}
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsStateGuardian::copy_alpha_image
// Access: Private, Static
// Description: Copies and scales the one-channel alpha image
// from the texture into the indicated GLImage pixmap.
////////////////////////////////////////////////////////////////////
void TinyGraphicsStateGuardian::
copy_alpha_image(GLImage *im, Texture *tex) {
nassertv(tex->get_num_components() == 1);
int xsize_src = tex->get_x_size();
int ysize_src = tex->get_y_size();
CPTA_uchar src_image = tex->get_ram_image();
nassertv(!src_image.is_null());
const unsigned char *src = src_image.p();
// Component width, and offset to the high-order byte.
int cw = tex->get_component_width();
#ifdef WORDS_BIGENDIAN
// Big-endian: the high-order byte is always first.
static const int co = 0;
#else
// Little-endian: the high-order byte is last.
int co = cw - 1;
#endif
int xsize_dest = im->xsize;
int ysize_dest = im->xsize;
unsigned char *dest = (unsigned char *)im->pixmap;
nassertv(dest != NULL);
int sx_inc = (int)((float)(xsize_src) / (float)(xsize_dest));
int sy_inc = (int)((float)(ysize_src) / (float)(ysize_dest));
unsigned char *dpix = dest;
int syn = 0;
for (int dy = 0; dy < ysize_dest; dy++) {
int sy = syn / ysize_dest;
int sxn = 0;
for (int dx = 0; dx < xsize_dest; dx++) {
int sx = sxn / xsize_dest;
const unsigned char *spix = src + (sy * xsize_src + sx) * 1 * cw;
dpix[0] = 0xff;
dpix[1] = 0xff;
dpix[2] = 0xff;
dpix[3] = spix[co];
dpix += 4;
sxn += xsize_src;
}
syn += ysize_src;
}
}
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsStateGuardian::copy_one_channel_image
// Access: Private, Static
// Description: Copies and scales the one-channel image (with a
// single channel, e.g. red, green, or blue) from
// the texture into the indicated GLImage pixmap.
////////////////////////////////////////////////////////////////////
void TinyGraphicsStateGuardian::
copy_one_channel_image(GLImage *im, Texture *tex, int channel) {
nassertv(tex->get_num_components() == 1);
int xsize_src = tex->get_x_size();
int ysize_src = tex->get_y_size();
CPTA_uchar src_image = tex->get_ram_image();
nassertv(!src_image.is_null());
const unsigned char *src = src_image.p();
// Component width, and offset to the high-order byte.
int cw = tex->get_component_width();
#ifdef WORDS_BIGENDIAN
// Big-endian: the high-order byte is always first.
static const int co = 0;
#else
// Little-endian: the high-order byte is last.
int co = cw - 1;
#endif
int xsize_dest = im->xsize;
int ysize_dest = im->xsize;
unsigned char *dest = (unsigned char *)im->pixmap;
nassertv(dest != NULL);
int sx_inc = (int)((float)(xsize_src) / (float)(xsize_dest));
int sy_inc = (int)((float)(ysize_src) / (float)(ysize_dest));
unsigned char *dpix = dest;
int syn = 0;
for (int dy = 0; dy < ysize_dest; dy++) {
int sy = syn / ysize_dest;
int sxn = 0;
for (int dx = 0; dx < xsize_dest; dx++) {
int sx = sxn / xsize_dest;
const unsigned char *spix = src + (sy * xsize_src + sx) * 1 * cw;
dpix[0] = 0;
dpix[1] = 0;
dpix[2] = 0;
dpix[3] = 0xff;
dpix[channel] = spix[co];
dpix += 4;
sxn += xsize_src;
}
syn += ysize_src;
}
}
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsStateGuardian::copy_la_image
// Access: Private, Static
// Description: Copies and scales the two-channel luminance-alpha
// image from the texture into the indicated GLImage
// pixmap.
////////////////////////////////////////////////////////////////////
void TinyGraphicsStateGuardian::
copy_la_image(GLImage *im, Texture *tex) {
nassertv(tex->get_num_components() == 2);
int xsize_src = tex->get_x_size();
int ysize_src = tex->get_y_size();
CPTA_uchar src_image = tex->get_ram_image();
nassertv(!src_image.is_null());
const unsigned char *src = src_image.p();
// Component width, and offset to the high-order byte.
int cw = tex->get_component_width();
#ifdef WORDS_BIGENDIAN
// Big-endian: the high-order byte is always first.
static const int co = 0;
#else
// Little-endian: the high-order byte is last.
int co = cw - 1;
#endif
int xsize_dest = im->xsize;
int ysize_dest = im->xsize;
unsigned char *dest = (unsigned char *)im->pixmap;
nassertv(dest != NULL);
int sx_inc = (int)((float)(xsize_src) / (float)(xsize_dest));
int sy_inc = (int)((float)(ysize_src) / (float)(ysize_dest));
unsigned char *dpix = dest;
int syn = 0;
for (int dy = 0; dy < ysize_dest; dy++) {
int sy = syn / ysize_dest;
int sxn = 0;
for (int dx = 0; dx < xsize_dest; dx++) {
int sx = sxn / xsize_dest;
const unsigned char *spix = src + (sy * xsize_src + sx) * 2 * cw;
dpix[0] = spix[co];
dpix[1] = spix[co];
dpix[2] = spix[co];
dpix[3] = spix[cw + co];
dpix += 4;
sxn += xsize_src;
}
syn += ysize_src;
}
}
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsStateGuardian::copy_rgb_image
// Access: Private, Static
// Description: Copies and scales the three-channel RGB image from
// the texture into the indicated GLImage pixmap.
////////////////////////////////////////////////////////////////////
void TinyGraphicsStateGuardian::
copy_rgb_image(GLImage *im, Texture *tex) {
nassertv(tex->get_num_components() == 3);
int xsize_src = tex->get_x_size();
int ysize_src = tex->get_y_size();
CPTA_uchar src_image = tex->get_ram_image();
nassertv(!src_image.is_null());
const unsigned char *src = src_image.p();
// Component width, and offset to the high-order byte.
int cw = tex->get_component_width();
#ifdef WORDS_BIGENDIAN
// Big-endian: the high-order byte is always first.
static const int co = 0;
#else
// Little-endian: the high-order byte is last.
int co = cw - 1;
#endif
int xsize_dest = im->xsize;
int ysize_dest = im->xsize;
unsigned char *dest = (unsigned char *)im->pixmap;
nassertv(dest != NULL);
int sx_inc = (int)((float)(xsize_src) / (float)(xsize_dest));
int sy_inc = (int)((float)(ysize_src) / (float)(ysize_dest));
unsigned char *dpix = dest;
int syn = 0;
for (int dy = 0; dy < ysize_dest; dy++) {
int sy = syn / ysize_dest;
int sxn = 0;
for (int dx = 0; dx < xsize_dest; dx++) {
int sx = sxn / xsize_dest;
const unsigned char *spix = src + (sy * xsize_src + sx) * 3 * cw;
dpix[0] = spix[co];
dpix[1] = spix[cw + co];
dpix[2] = spix[cw + cw + co];
dpix[3] = 0xff;
dpix += 4;
sxn += xsize_src;
}
syn += ysize_src;
}
}
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsStateGuardian::copy_rgba_image
// Access: Private, Static
// Description: Copies and scales the four-channel RGBA image from
// the texture into the indicated GLImage pixmap.
////////////////////////////////////////////////////////////////////
void TinyGraphicsStateGuardian::
copy_rgba_image(GLImage *im, Texture *tex) {
nassertv(tex->get_num_components() == 4);
int xsize_src = tex->get_x_size();
int ysize_src = tex->get_y_size();
CPTA_uchar src_image = tex->get_ram_image();
nassertv(!src_image.is_null());
const unsigned char *src = src_image.p();
// Component width, and offset to the high-order byte.
int cw = tex->get_component_width();
#ifdef WORDS_BIGENDIAN
// Big-endian: the high-order byte is always first.
static const int co = 0;
#else
// Little-endian: the high-order byte is last.
int co = cw - 1;
#endif
int xsize_dest = im->xsize;
int ysize_dest = im->xsize;
unsigned char *dest = (unsigned char *)im->pixmap;
nassertv(dest != NULL);
int sx_inc = (int)((float)(xsize_src) / (float)(xsize_dest));
int sy_inc = (int)((float)(ysize_src) / (float)(ysize_dest));
unsigned char *dpix = dest;
int syn = 0;
for (int dy = 0; dy < ysize_dest; dy++) {
int sy = syn / ysize_dest;
int sxn = 0;
for (int dx = 0; dx < xsize_dest; dx++) {
int sx = sxn / xsize_dest;
const unsigned char *spix = src + (sy * xsize_src + sx) * 4 * cw;
dpix[0] = spix[co];
dpix[1] = spix[cw + co];
dpix[2] = spix[cw + cw + co];
dpix[3] = spix[cw + cw + cw + co];
dpix += 4;
sxn += xsize_src;
}
syn += ysize_src;
}
}
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsStateGuardian::load_matrix
// Access: Private, Static

View File

@ -33,6 +33,7 @@ extern "C" {
class TinyTextureContext;
struct GLContext;
struct GLVertex;
struct GLImage;
////////////////////////////////////////////////////////////////////
@ -98,7 +99,6 @@ private:
void do_issue_transform();
void do_issue_render_mode();
void do_issue_cull_face();
void do_issue_shade_model();
void do_issue_material();
void do_issue_texture();
void do_issue_blending();
@ -106,6 +106,13 @@ private:
void apply_texture(TextureContext *tc);
bool upload_texture(TinyTextureContext *gtc);
static void copy_lum_image(GLImage *im, Texture *tex);
static void copy_alpha_image(GLImage *im, Texture *tex);
static void copy_one_channel_image(GLImage *im, Texture *tex, int channel);
static void copy_la_image(GLImage *im, Texture *tex);
static void copy_rgb_image(GLImage *im, Texture *tex);
static void copy_rgba_image(GLImage *im, Texture *tex);
static void load_matrix(M4 *matrix, const TransformState *transform);
INLINE static GLenum get_light_id(int index);

View File

@ -181,7 +181,7 @@ process_events() {
system_changed_properties(properties);
_screen = SDL_SetVideoMode(_properties.get_x_size(), _properties.get_y_size(), 32, _flags);
ZB_resize(_frame_buffer, NULL, _properties.get_x_size(), _properties.get_y_size());
_pitch = _screen->pitch * TGL_FEATURE_RENDER_BITS / _screen->format->BitsPerPixel;
_pitch = _screen->pitch * 32 / _screen->format->BitsPerPixel;
break;
case SDL_QUIT:
@ -325,7 +325,7 @@ create_frame_buffer() {
_frame_buffer = ZB_open(_properties.get_x_size(), _properties.get_y_size(), mode, 0, 0, 0, 0);
_pitch = _screen->pitch * TGL_FEATURE_RENDER_BITS / _screen->format->BitsPerPixel;
_pitch = _screen->pitch * 32 / _screen->format->BitsPerPixel;
}
////////////////////////////////////////////////////////////////////

View File

@ -26,5 +26,15 @@ INLINE TinyTextureContext::
TinyTextureContext(PreparedGraphicsObjects *pgo, Texture *tex) :
TextureContext(pgo, tex)
{
_index = 0;
_gltex = NULL;
}
////////////////////////////////////////////////////////////////////
// Function: TinyTextureContext::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE TinyTextureContext::
~TinyTextureContext() {
nassertv(_gltex == NULL);
}

View File

@ -24,6 +24,8 @@
#include "deletedChain.h"
#include "tinygl.h"
struct GLTexture;
////////////////////////////////////////////////////////////////////
// Class : TinyTextureContext
// Description :
@ -33,8 +35,9 @@ public:
INLINE TinyTextureContext(PreparedGraphicsObjects *pgo, Texture *tex);
ALLOC_DELETED_CHAIN(TinyTextureContext);
// This is the GL "name" of the texture object.
GLuint _index;
INLINE ~TinyTextureContext();
GLTexture *_gltex;
public:
static TypeHandle get_class_type() {

View File

@ -132,230 +132,6 @@ static void ZB_copyBuffer(ZBuffer * zb,
}
}
#if TGL_FEATURE_RENDER_BITS == 16
/* 32 bpp copy */
#ifdef TGL_FEATURE_32_BITS
#define RGB16_TO_RGB32(p0,p1,v)\
{\
unsigned int g,b,gb;\
g = (v & 0x07E007E0) << 5;\
b = (v & 0x001F001F) << 3;\
gb = g | b;\
p0 = (gb & 0x0000FFFF) | ((v & 0x0000F800) << 8);\
p1 = (gb >> 16) | ((v & 0xF8000000) >> 8);\
}
static void ZB_copyFrameBufferRGB32(ZBuffer * zb,
void *buf,
int linesize)
{
unsigned short *q;
unsigned int *p, *p1, v, w0, w1;
int y, n;
q = zb->pbuf;
p1 = (unsigned int *) buf;
for (y = 0; y < zb->ysize; y++) {
p = p1;
n = zb->xsize >> 2;
do {
v = *(unsigned int *) q;
#if BYTE_ORDER == BIG_ENDIAN
RGB16_TO_RGB32(w1, w0, v);
#else
RGB16_TO_RGB32(w0, w1, v);
#endif
p[0] = w0;
p[1] = w1;
v = *(unsigned int *) (q + 2);
#if BYTE_ORDER == BIG_ENDIAN
RGB16_TO_RGB32(w1, w0, v);
#else
RGB16_TO_RGB32(w0, w1, v);
#endif
p[2] = w0;
p[3] = w1;
q += 4;
p += 4;
} while (--n > 0);
p1 += linesize;
}
}
#endif
/* 24 bit packed pixel handling */
#ifdef TGL_FEATURE_24_BITS
/* order: RGBR GBRG BRGB */
/* XXX: packed pixel 24 bit support not tested */
/* XXX: big endian case not optimised */
#if BYTE_ORDER == BIG_ENDIAN
#define RGB16_TO_RGB24(p0,p1,p2,v1,v2)\
{\
unsigned int r1,g1,b1,gb1,g2,b2,gb2;\
v1 = (v1 << 16) | (v1 >> 16);\
v2 = (v2 << 16) | (v2 >> 16);\
r1 = (v1 & 0xF800F800);\
g1 = (v1 & 0x07E007E0) << 5;\
b1 = (v1 & 0x001F001F) << 3;\
gb1 = g1 | b1;\
p0 = ((gb1 & 0x0000FFFF) << 8) | (r1 << 16) | (r1 >> 24);\
g2 = (v2 & 0x07E007E0) << 5;\
b2 = (v2 & 0x001F001F) << 3;\
gb2 = g2 | b2;\
p1 = (gb1 & 0xFFFF0000) | (v2 & 0xF800) | ((gb2 >> 8) & 0xff);\
p2 = (gb2 << 24) | ((v2 & 0xF8000000) >> 8) | (gb2 >> 16);\
}
#else
#define RGB16_TO_RGB24(p0,p1,p2,v1,v2)\
{\
unsigned int r1,g1,b1,gb1,g2,b2,gb2;\
r1 = (v1 & 0xF800F800);\
g1 = (v1 & 0x07E007E0) << 5;\
b1 = (v1 & 0x001F001F) << 3;\
gb1 = g1 | b1;\
p0 = ((gb1 & 0x0000FFFF) << 8) | (r1 << 16) | (r1 >> 24);\
g2 = (v2 & 0x07E007E0) << 5;\
b2 = (v2 & 0x001F001F) << 3;\
gb2 = g2 | b2;\
p1 = (gb1 & 0xFFFF0000) | (v2 & 0xF800) | ((gb2 >> 8) & 0xff);\
p2 = (gb2 << 24) | ((v2 & 0xF8000000) >> 8) | (gb2 >> 16);\
}
#endif
static void ZB_copyFrameBufferRGB24(ZBuffer * zb,
void *buf,
int linesize)
{
unsigned short *q;
unsigned int *p, w0, w1, w2, v0, v1;
char *p1;
int y, n;
q = zb->pbuf;
p1 = buf;
linesize = linesize * 3;
for (y = 0; y < zb->ysize; y++) {
p = (unsigned int *)p1;
n = zb->xsize >> 2;
do {
v0 = *(unsigned int *) q;
v1 = *(unsigned int *) (q + 2);
RGB16_TO_RGB24(w0, w1, w2, v0, v1);
p[0] = w0;
p[1] = w1;
p[2] = w2;
q += 4;
p += 3;
} while (--n > 0);
p1 += linesize;
}
}
#endif
void ZB_copyFrameBuffer(ZBuffer * zb, void *buf,
int linesize)
{
switch (zb->mode) {
#ifdef TGL_FEATURE_8_BITS
case ZB_MODE_INDEX:
ZB_ditherFrameBuffer(zb, buf, linesize >> 1);
break;
#endif
#ifdef TGL_FEATURE_16_BITS
case ZB_MODE_5R6G5B:
ZB_copyBuffer(zb, buf, linesize);
break;
#endif
#ifdef TGL_FEATURE_32_BITS
case ZB_MODE_RGBA:
ZB_copyFrameBufferRGB32(zb, buf, linesize >> 1);
break;
#endif
#ifdef TGL_FEATURE_24_BITS
case ZB_MODE_RGB24:
ZB_copyFrameBufferRGB24(zb, buf, linesize >> 1);
break;
#endif
default:
assert(0);
}
}
#endif /* TGL_FEATURE_RENDER_BITS == 16 */
#if TGL_FEATURE_RENDER_BITS == 24
#define RGB24_TO_RGB16(r, g, b) \
((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3))
/* XXX: not optimized */
static void ZB_copyFrameBuffer5R6G5B(ZBuffer * zb,
void *buf, int linesize)
{
PIXEL *q;
unsigned short *p, *p1;
int y, n;
q = zb->pbuf;
p1 = (unsigned short *) buf;
for (y = 0; y < zb->ysize; y++) {
p = p1;
n = zb->xsize >> 2;
do {
p[0] = RGB24_TO_RGB16(q[0], q[1], q[2]);
p[1] = RGB24_TO_RGB16(q[3], q[4], q[5]);
p[2] = RGB24_TO_RGB16(q[6], q[7], q[8]);
p[3] = RGB24_TO_RGB16(q[9], q[10], q[11]);
q = (PIXEL *)((char *)q + 4 * PSZB);
p += 4;
} while (--n > 0);
p1 = (unsigned short *)((char *)p1 + linesize);
}
}
void ZB_copyFrameBuffer(ZBuffer * zb, void *buf,
int linesize)
{
switch (zb->mode) {
#ifdef TGL_FEATURE_16_BITS
case ZB_MODE_5R6G5B:
ZB_copyFrameBuffer5R6G5B(zb, buf, linesize);
break;
#endif
#ifdef TGL_FEATURE_24_BITS
case ZB_MODE_RGB24:
ZB_copyBuffer(zb, buf, linesize);
break;
#endif
default:
assert(0);
}
}
#endif /* TGL_FEATURE_RENDER_BITS == 24 */
#if TGL_FEATURE_RENDER_BITS == 32
#define RGB32_TO_RGB16(v) \
(((v >> 8) & 0xf800) | (((v) >> 5) & 0x07e0) | (((v) & 0xff) >> 3))
@ -404,8 +180,6 @@ void ZB_copyFrameBuffer(ZBuffer * zb, void *buf,
}
}
#endif /* TGL_FEATURE_RENDER_BITS == 32 */
/*
* adr must be aligned on an 'int'
@ -489,9 +263,7 @@ void memset_RGB24(void *adr,int r, int v, int b,long count)
void ZB_clear(ZBuffer * zb, int clear_z, int z,
int clear_color, int r, int g, int b)
{
#if TGL_FEATURE_RENDER_BITS != 24
int color;
#endif
int y;
PIXEL *pp;
@ -501,17 +273,8 @@ void ZB_clear(ZBuffer * zb, int clear_z, int z,
if (clear_color) {
pp = zb->pbuf;
for (y = 0; y < zb->ysize; y++) {
#if TGL_FEATURE_RENDER_BITS == 15 || TGL_FEATURE_RENDER_BITS == 16
color = RGB_TO_PIXEL(r, g, b);
memset_s(pp, color, zb->xsize);
#elif TGL_FEATURE_RENDER_BITS == 32
color = RGB_TO_PIXEL(r, g, b);
memset_l(pp, color, zb->xsize);
#elif TGL_FEATURE_RENDER_BITS == 24
memset_RGB24(pp,r>>8,g>>8,b>>8,zb->xsize);
#else
#error TODO
#endif
pp = (PIXEL *) ((char *) pp + zb->linesize);
}
}

View File

@ -16,12 +16,14 @@
#define ZB_POINT_T_MIN ( (1<<21) )
#define ZB_POINT_T_MAX ( (1<<30)-(1<<21) )
#define ZB_POINT_RED_MIN ( (1<<10) )
#define ZB_POINT_RED_MAX ( (1<<16)-(1<<10) )
#define ZB_POINT_GREEN_MIN ( (1<<9) )
#define ZB_POINT_GREEN_MAX ( (1<<16)-(1<<9) )
#define ZB_POINT_BLUE_MIN ( (1<<10) )
#define ZB_POINT_BLUE_MAX ( (1<<16)-(1<<10) )
#define ZB_POINT_RED_MIN 0x0000
#define ZB_POINT_RED_MAX 0xff00
#define ZB_POINT_GREEN_MIN 0x0000
#define ZB_POINT_GREEN_MAX 0xff00
#define ZB_POINT_BLUE_MIN 0x0000
#define ZB_POINT_BLUE_MAX 0xff00
#define ZB_POINT_ALPHA_MIN 0x0000
#define ZB_POINT_ALPHA_MAX 0xff00
/* display modes */
#define ZB_MODE_5R6G5B 1 /* true color 16 bits */
@ -30,56 +32,18 @@
#define ZB_MODE_RGB24 4 /* 24 bit rgb mode */
#define ZB_NB_COLORS 225 /* number of colors for 8 bit display */
#if TGL_FEATURE_RENDER_BITS == 15
#define RGB_TO_PIXEL(r,g,b) \
((((r) >> 1) & 0x7c00) | (((g) >> 6) & 0x03e0) | ((b) >> 11))
#define PIXEL_R(p) (((p) & 0x7c00) << 1)
#define PIXEL_G(p) (((p) & 0x03e0) << 6)
#define PIXEL_B(p) (((p) & 0x001f) << 11)
typedef unsigned short PIXEL;
/* bytes per pixel */
#define PSZB 2
/* bits per pixel = (1 << PSZH) */
#define PSZSH 4
#elif TGL_FEATURE_RENDER_BITS == 16
/* 16 bit mode */
#define RGB_TO_PIXEL(r,g,b) \
(((r) & 0xF800) | (((g) >> 5) & 0x07E0) | ((b) >> 11))
#define PIXEL_R(p) (((p) & 0xf800))
#define PIXEL_G(p) (((p) & 0x07e0) << 5)
#define PIXEL_B(p) (((p) & 0x001f) << 11)
typedef unsigned short PIXEL;
#define PSZB 2
#define PSZSH 4
#elif TGL_FEATURE_RENDER_BITS == 24
#define RGB_TO_PIXEL(r,g,b) \
((((r) << 8) & 0xff0000) | ((g) & 0xff00) | ((b) >> 8))
typedef unsigned char PIXEL;
#define PSZB 3
#define PSZSH 5
#elif TGL_FEATURE_RENDER_BITS == 32
#define RGB_TO_PIXEL(r,g,b) \
((((r) << 8) & 0xff0000) | ((g) & 0xff00) | ((b) >> 8))
#define RGBA_TO_PIXEL(r,g,b,a) \
((((a) << 16) & 0xff000000) | (((r) << 8) & 0xff0000) | ((g) & 0xff00) | ((b) >> 8))
#define PIXEL_R(p) (((p) & 0xff0000) >> 8)
#define PIXEL_G(p) ((p) & 0xff00)
#define PIXEL_B(p) (((p) & 0x00ff) << 8)
#define PIXEL_A(p) (((p) & 0xff000000) >> 16)
typedef unsigned int PIXEL;
#define PSZB 4
#define PSZSH 5
#else
#error Incorrect number of bits per pixel
#endif
#define PIXEL_MULT(p1, p2) \
RGB_TO_PIXEL((PIXEL_R(p1) * PIXEL_R(p2)) >> 16, \
(PIXEL_G(p1) * PIXEL_G(p2)) >> 16, \
@ -104,7 +68,7 @@ typedef struct {
typedef struct {
int x,y,z; /* integer coordinates in the zbuffer */
int s,t; /* coordinates for the mapping */
int r,g,b; /* color indexes */
int r,g,b,a; /* color indexes */
float sz,tz; /* temporary coordinates for mapping */
} ZBufferPoint;
@ -142,20 +106,80 @@ void ZB_line_z(ZBuffer * zb, ZBufferPoint * p1, ZBufferPoint * p2);
/* ztriangle.c */
void ZB_setTexture(ZBuffer *zb, PIXEL *texture);
void ZB_fillTriangleFlat(ZBuffer *zb,
void ZB_fillTriangleFlat_anone_znone(ZBuffer *zb,
ZBufferPoint *p1,ZBufferPoint *p2,ZBufferPoint *p3);
void ZB_fillTriangleSmooth(ZBuffer *zb,
void ZB_fillTriangleSmooth_anone_znone(ZBuffer *zb,
ZBufferPoint *p1,ZBufferPoint *p2,ZBufferPoint *p3);
void ZB_fillTriangleMapping(ZBuffer *zb,
void ZB_fillTriangleMapping_anone_znone(ZBuffer *zb,
ZBufferPoint *p1,ZBufferPoint *p2,ZBufferPoint *p3);
void ZB_fillTriangleMappingFlat_anone_znone(ZBuffer *zb,
ZBufferPoint *p1,ZBufferPoint *p2,ZBufferPoint *p3);
void ZB_fillTriangleMappingSmooth_anone_znone(ZBuffer *zb,
ZBufferPoint *p1,ZBufferPoint *p2,ZBufferPoint *p3);
void ZB_fillTriangleMappingPerspective(ZBuffer *zb,
void ZB_fillTriangleMappingPerspective_anone_znone(ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2);
void ZB_fillTriangleMappingSmooth(ZBuffer *zb,
void ZB_fillTriangleMappingPerspectiveFlat_anone_znone(ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2);
void ZB_fillTriangleMappingPerspectiveSmooth_anone_znone(ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2);
void ZB_fillTriangleFlat_anone_zless(ZBuffer *zb,
ZBufferPoint *p1,ZBufferPoint *p2,ZBufferPoint *p3);
void ZB_fillTriangleSmooth_anone_zless(ZBuffer *zb,
ZBufferPoint *p1,ZBufferPoint *p2,ZBufferPoint *p3);
void ZB_fillTriangleMapping_anone_zless(ZBuffer *zb,
ZBufferPoint *p1,ZBufferPoint *p2,ZBufferPoint *p3);
void ZB_fillTriangleMappingFlat_anone_zless(ZBuffer *zb,
ZBufferPoint *p1,ZBufferPoint *p2,ZBufferPoint *p3);
void ZB_fillTriangleMappingSmooth_anone_zless(ZBuffer *zb,
ZBufferPoint *p1,ZBufferPoint *p2,ZBufferPoint *p3);
void ZB_fillTriangleMappingPerspective_anone_zless(ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2);
void ZB_fillTriangleMappingPerspectiveFlat_anone_zless(ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2);
void ZB_fillTriangleMappingPerspectiveSmooth_anone_zless(ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2);
void ZB_fillTriangleFlat_abin_znone(ZBuffer *zb,
ZBufferPoint *p1,ZBufferPoint *p2,ZBufferPoint *p3);
void ZB_fillTriangleSmooth_abin_znone(ZBuffer *zb,
ZBufferPoint *p1,ZBufferPoint *p2,ZBufferPoint *p3);
void ZB_fillTriangleMapping_abin_znone(ZBuffer *zb,
ZBufferPoint *p1,ZBufferPoint *p2,ZBufferPoint *p3);
void ZB_fillTriangleMappingFlat_abin_znone(ZBuffer *zb,
ZBufferPoint *p1,ZBufferPoint *p2,ZBufferPoint *p3);
void ZB_fillTriangleMappingSmooth_abin_znone(ZBuffer *zb,
ZBufferPoint *p1,ZBufferPoint *p2,ZBufferPoint *p3);
void ZB_fillTriangleMappingPerspective_abin_znone(ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2);
void ZB_fillTriangleMappingPerspectiveFlat_abin_znone(ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2);
void ZB_fillTriangleMappingPerspectiveSmooth_abin_znone(ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2);
void ZB_fillTriangleFlat_abin_zless(ZBuffer *zb,
ZBufferPoint *p1,ZBufferPoint *p2,ZBufferPoint *p3);
void ZB_fillTriangleSmooth_abin_zless(ZBuffer *zb,
ZBufferPoint *p1,ZBufferPoint *p2,ZBufferPoint *p3);
void ZB_fillTriangleMapping_abin_zless(ZBuffer *zb,
ZBufferPoint *p1,ZBufferPoint *p2,ZBufferPoint *p3);
void ZB_fillTriangleMappingFlat_abin_zless(ZBuffer *zb,
ZBufferPoint *p1,ZBufferPoint *p2,ZBufferPoint *p3);
void ZB_fillTriangleMappingSmooth_abin_zless(ZBuffer *zb,
ZBufferPoint *p1,ZBufferPoint *p2,ZBufferPoint *p3);
void ZB_fillTriangleMappingPerspective_abin_zless(ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2);
void ZB_fillTriangleMappingPerspectiveFlat_abin_zless(ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2);
void ZB_fillTriangleMappingPerspectiveSmooth_abin_zless(ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2);

View File

@ -29,36 +29,11 @@
#define TGL_FEATURE_DISPLAYLISTS 1
#define TGL_FEATURE_POLYGON_OFFSET 1
/*
* Matrix of internal and external pixel formats supported. 'Y' means
* supported.
*
* External 8 16 24 32
* Internal
* 15 . . . .
* 16 Y Y Y Y
* 24 . Y Y .
* 32 . Y . Y
*
*
* 15 bpp does not work yet (although it is easy to add it - ask me if
* you need it).
*
* Internal pixel format: see TGL_FEATURE_RENDER_BITS
* External pixel format: see TGL_FEATURE_xxx_BITS
*/
/* enable various convertion code from internal pixel format (usually
16 bits per pixel) to any external format */
/* enable various conversion code from internal pixel format (32 bits
per pixel) to any external format */
#define TGL_FEATURE_16_BITS 1
//#define TGL_FEATURE_8_BITS 1
#define TGL_FEATURE_24_BITS 1
#define TGL_FEATURE_32_BITS 1
//#define TGL_FEATURE_RENDER_BITS 15
//#define TGL_FEATURE_RENDER_BITS 16
//#define TGL_FEATURE_RENDER_BITS 24
#define TGL_FEATURE_RENDER_BITS 32
#endif /* _tgl_features_h_ */

View File

@ -211,6 +211,7 @@ typedef struct GLContext {
int cull_face_enabled;
int normalize_enabled;
gl_draw_triangle_func draw_triangle_front,draw_triangle_back;
ZB_fillTriangleFunc zb_fill_tri;
/* selection */
int render_mode;

View File

@ -13,13 +13,7 @@ void ZB_plot(ZBuffer * zb, ZBufferPoint * p)
pp = (PIXEL *) ((char *) zb->pbuf + zb->linesize * p->y + p->x * PSZB);
zz = p->z >> ZB_POINT_Z_FRAC_BITS;
if (ZCMP(zz, *pz)) {
#if TGL_FEATURE_RENDER_BITS == 24
pp[0]=p->r>>8;
pp[1]=p->g>>8;
pp[2]=p->b>>8;
#else
*pp = RGB_TO_PIXEL(p->r, p->g, p->b);
#endif
*pz = zz;
}
}

View File

@ -2,7 +2,7 @@
int n, dx, dy, sx, pp_inc_1, pp_inc_2;
register int a;
register PIXEL *pp;
#if defined(INTERP_RGB) || TGL_FEATURE_RENDER_BITS == 24
#if defined(INTERP_RGB)
register unsigned int r, g, b;
#endif
#ifdef INTERP_RGB
@ -33,27 +33,14 @@
r = p2->r << 8;
g = p2->g << 8;
b = p2->b << 8;
#elif TGL_FEATURE_RENDER_BITS == 24
/* for 24 bits, we store the colors in different variables */
r = p2->r >> 8;
g = p2->g >> 8;
b = p2->b >> 8;
#endif
#ifdef INTERP_RGB
#define RGB(x) x
#if TGL_FEATURE_RENDER_BITS == 24
#define RGBPIXEL pp[0] = r >> 16, pp[1] = g >> 16, pp[2] = b >> 16
#else
#define RGBPIXEL *pp = RGB_TO_PIXEL(r >> 8,g >> 8,b >> 8)
#endif
#else /* INTERP_RGB */
#define RGB(x)
#if TGL_FEATURE_RENDER_BITS == 24
#define RGBPIXEL pp[0] = r, pp[1] = g, pp[2] = b
#else
#define RGBPIXEL *pp = color
#endif
#endif /* INTERP_RGB */
#ifdef INTERP_Z

View File

@ -1,304 +1,23 @@
#include <stdlib.h>
#include <stdio.h>
#include "zbuffer.h"
#define ZCMP(z,zpix) ((z) >= (zpix))
#define ACMP(a) 1
#define ZCMP(z,zpix) 1
#define FNAME(name) name ## _anone_znone
#include "ztriangle_two.h"
void ZB_fillTriangleFlat(ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2)
{
int color;
#define ACMP(a) 1
#define ZCMP(z,zpix) ((zpix) < (z))
#define FNAME(name) name ## _anone_zless
#include "ztriangle_two.h"
#define INTERP_Z
#define ACMP(a) ((a) > 0x8000)
#define ZCMP(z,zpix) 1
#define FNAME(name) name ## _abin_znone
#include "ztriangle_two.h"
#define DRAW_INIT() \
{ \
color=RGB_TO_PIXEL(p2->r,p2->g,p2->b); \
}
#define PUT_PIXEL(_a) \
{ \
zz=z >> ZB_POINT_Z_FRAC_BITS; \
if (ZCMP(zz,pz[_a])) { \
pp[_a]=color; \
pz[_a]=zz; \
} \
z+=dzdx; \
}
#include "ztriangle.h"
}
/*
* Smooth filled triangle.
* The code below is very tricky :)
*/
void ZB_fillTriangleSmooth(ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2)
{
#define INTERP_Z
#define INTERP_RGB
#define SAR_RND_TO_ZERO(v,n) (v / (1<<n))
#define DRAW_INIT() \
{ \
}
#define PUT_PIXEL(_a) \
{ \
zz=z >> ZB_POINT_Z_FRAC_BITS; \
if (ZCMP(zz,pz[_a])) { \
pp[_a] = RGB_TO_PIXEL(or1, og1, ob1);\
pz[_a]=zz; \
}\
z+=dzdx; \
og1+=dgdx; \
or1+=drdx; \
ob1+=dbdx; \
}
#include "ztriangle.h"
}
void ZB_setTexture(ZBuffer *zb,PIXEL *texture)
{
zb->current_texture=texture;
}
void ZB_fillTriangleMapping(ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2)
{
PIXEL *texture;
#define INTERP_Z
#define INTERP_ST
#define DRAW_INIT() \
{ \
texture=zb->current_texture; \
}
#define PUT_PIXEL(_a) \
{ \
zz=z >> ZB_POINT_Z_FRAC_BITS; \
if (ZCMP(zz,pz[_a])) { \
pp[_a]=texture[((t & 0x3FC00000) | s) >> 14]; \
pz[_a]=zz; \
} \
z+=dzdx; \
s+=dsdx; \
t+=dtdx; \
}
#include "ztriangle.h"
}
/*
* Texture mapping with perspective correction.
* We use the gradient method to make less divisions.
* TODO: pipeline the division
*/
void ZB_fillTriangleMappingPerspective(ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2)
{
PIXEL *texture;
float fdzdx,fndzdx,ndszdx,ndtzdx;
#define INTERP_Z
#define INTERP_STZ
#define NB_INTERP 8
#define DRAW_INIT() \
{ \
texture=zb->current_texture;\
fdzdx=(float)dzdx;\
fndzdx=NB_INTERP * fdzdx;\
ndszdx=NB_INTERP * dszdx;\
ndtzdx=NB_INTERP * dtzdx;\
}
#define PUT_PIXEL(_a) \
{ \
zz=z >> ZB_POINT_Z_FRAC_BITS; \
if (ZCMP(zz,pz[_a])) { \
pp[_a]=*(PIXEL *)((char *)texture+ \
(((t & 0x3FC00000) | (s & 0x003FC000)) >> (17 - PSZSH)));\
pz[_a]=zz; \
} \
z+=dzdx; \
s+=dsdx; \
t+=dtdx; \
}
#define DRAW_LINE() \
{ \
register unsigned short *pz; \
register PIXEL *pp; \
register unsigned int s,t,z,zz; \
register int n,dsdx,dtdx; \
float sz,tz,fz,zinv; \
n=(x2>>16)-x1; \
fz=(float)z1;\
zinv=1.0 / fz;\
pp=(PIXEL *)((char *)pp1 + x1 * PSZB); \
pz=pz1+x1; \
z=z1; \
sz=sz1;\
tz=tz1;\
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 );\
fz+=fndzdx;\
zinv=1.0 / 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;\
} \
{\
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 );\
}\
while (n>=0) { \
PUT_PIXEL(0); \
pz+=1; \
pp=(PIXEL *)((char *)pp + PSZB);\
n-=1; \
} \
}
#include "ztriangle.h"
}
/*
* Smooth filled triangle, with perspective-correct mapping.
*/
void ZB_fillTriangleMappingSmooth(ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2)
{
PIXEL *texture;
float fdzdx,fndzdx,ndszdx,ndtzdx;
#define INTERP_Z
#define INTERP_STZ
#define INTERP_RGB
#define SAR_RND_TO_ZERO(v,n) (v / (1<<n))
#define DRAW_INIT() \
{ \
texture=zb->current_texture;\
fdzdx=(float)dzdx;\
fndzdx=NB_INTERP * fdzdx;\
ndszdx=NB_INTERP * dszdx;\
ndtzdx=NB_INTERP * dtzdx;\
}
#define PUT_PIXEL(_a) \
{ \
zz=z >> ZB_POINT_Z_FRAC_BITS; \
if (ZCMP(zz,pz[_a])) { \
tmp=*(PIXEL *)((char *)texture+ \
(((t & 0x3FC00000) | (s & 0x003FC000)) >> (17 - PSZSH))); \
pp[_a] = RGB_TO_PIXEL(or1 * PIXEL_R(tmp) >> 16, \
og1 * PIXEL_G(tmp) >> 16, \
ob1 * PIXEL_B(tmp) >> 16); \
pz[_a]=zz; \
}\
z+=dzdx; \
og1+=dgdx; \
or1+=drdx; \
ob1+=dbdx; \
s+=dsdx; \
t+=dtdx; \
}
#define DRAW_LINE() \
{ \
register unsigned short *pz; \
register PIXEL *pp; \
register unsigned int s,t,z,zz; \
register int n,dsdx,dtdx; \
register unsigned int or1,og1,ob1; \
float sz,tz,fz,zinv; \
n=(x2>>16)-x1; \
fz=(float)z1;\
zinv=1.0 / fz;\
pp=(PIXEL *)((char *)pp1 + x1 * PSZB); \
pz=pz1+x1; \
z=z1; \
sz=sz1;\
tz=tz1;\
or1 = r1;\
og1 = g1;\
ob1 = b1;\
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 );\
fz+=fndzdx;\
zinv=1.0 / 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;\
} \
{\
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 );\
}\
while (n>=0) { \
PUT_PIXEL(0); \
pz+=1; \
pp=(PIXEL *)((char *)pp + PSZB);\
n-=1; \
} \
}
#include "ztriangle.h"
}
#define ACMP(a) ((a) > 0x8000)
#define ZCMP(z,zpix) ((zpix) < (z))
#define FNAME(name) name ## _abin_zless
#include "ztriangle_two.h"

View File

@ -23,6 +23,7 @@
int r1,drdx,drdy,drdl_min,drdl_max;
int g1,dgdx,dgdy,dgdl_min,dgdl_max;
int b1,dbdx,dbdy,dbdl_min,dbdl_max;
int a1,dadx,dady,dadl_min,dadl_max;
#endif
#ifdef INTERP_ST
int s1,dsdx,dsdy,dsdl_min,dsdl_max;
@ -91,6 +92,11 @@
dbdx = (int) (fdy2 * d1 - fdy1 * d2);
dbdy = (int) (fdx1 * d2 - fdx2 * d1);
d1 = p1->a - p0->a;
d2 = p2->a - p0->a;
dadx = (int) (fdy2 * d1 - fdy1 * d2);
dady = (int) (fdx1 * d2 - fdx2 * d1);
#endif
#ifdef INTERP_ST
@ -203,6 +209,10 @@
b1=l1->b;
dbdl_min=(dbdy + dbdx * dxdy_min);
dbdl_max=dbdl_min + dbdx;
a1=l1->a;
dadl_min=(dady + dadx * dxdy_min);
dadl_max=dadl_min + dadx;
#endif
#ifdef INTERP_ST
s1=l1->s;
@ -250,7 +260,7 @@
register unsigned int z,zz;
#endif
#ifdef INTERP_RGB
register unsigned int or1,og1,ob1;
register unsigned int or1,og1,ob1,oa1;
#endif
#ifdef INTERP_ST
register unsigned int s,t;
@ -269,6 +279,7 @@
or1 = r1;
og1 = g1;
ob1 = b1;
oa1 = a1;
#endif
#ifdef INTERP_ST
s=s1;
@ -314,6 +325,7 @@
r1+=drdl_max;
g1+=dgdl_max;
b1+=dbdl_max;
a1+=dadl_max;
#endif
#ifdef INTERP_ST
s1+=dsdl_max;

View File

@ -0,0 +1,508 @@
void FNAME(ZB_fillTriangleFlat) (ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2)
{
int color;
int oa;
#define INTERP_Z
#define DRAW_INIT() \
{ \
if (!ACMP(p2->a)) { \
return; \
} \
color=RGBA_TO_PIXEL(p2->r,p2->g,p2->b,p2->a); \
}
#define PUT_PIXEL(_a) \
{ \
zz=z >> ZB_POINT_Z_FRAC_BITS; \
if (ZCMP(zz,pz[_a])) { \
pp[_a]=color; \
pz[_a]=zz; \
} \
z+=dzdx; \
}
#include "ztriangle.h"
}
/*
* Smooth filled triangle.
* The code below is very tricky :)
*/
void FNAME(ZB_fillTriangleSmooth) (ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2)
{
#define INTERP_Z
#define INTERP_RGB
#define DRAW_INIT() \
{ \
}
#define PUT_PIXEL(_a) \
{ \
zz=z >> ZB_POINT_Z_FRAC_BITS; \
if (ZCMP(zz,pz[_a])) { \
if (ACMP(oa1)) { \
pp[_a] = RGBA_TO_PIXEL(or1, og1, ob1, oa1); \
pz[_a]=zz; \
} \
} \
z+=dzdx; \
og1+=dgdx; \
or1+=drdx; \
ob1+=dbdx; \
oa1+=dadx; \
}
#include "ztriangle.h"
}
void FNAME(ZB_fillTriangleMapping) (ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2)
{
PIXEL *texture;
#define INTERP_Z
#define INTERP_ST
#define DRAW_INIT() \
{ \
texture=zb->current_texture; \
}
#define PUT_PIXEL(_a) \
{ \
zz=z >> ZB_POINT_Z_FRAC_BITS; \
if (ZCMP(zz,pz[_a])) { \
tmp=texture[((t & 0x3FC00000) | s) >> 14]; \
if (ACMP(PIXEL_A(tmp))) { \
pp[_a]=tmp; \
pz[_a]=zz; \
} \
} \
z+=dzdx; \
s+=dsdx; \
t+=dtdx; \
}
#include "ztriangle.h"
}
void FNAME(ZB_fillTriangleMappingFlat) (ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2)
{
PIXEL *texture;
int or, og, ob, oa;
#define INTERP_Z
#define INTERP_ST
#define DRAW_INIT() \
{ \
texture=zb->current_texture; \
or = p2->r; \
og = p2->g; \
ob = p2->b; \
oa = p2->a; \
}
#define PUT_PIXEL(_a) \
{ \
zz=z >> ZB_POINT_Z_FRAC_BITS; \
if (ZCMP(zz,pz[_a])) { \
tmp=texture[((t & 0x3FC00000) | s) >> 14]; \
int a = oa * PIXEL_A(tmp) >> 16; \
if (ACMP(a)) { \
pp[_a] = RGBA_TO_PIXEL(or * PIXEL_R(tmp) >> 16, \
og * PIXEL_G(tmp) >> 16, \
ob * PIXEL_B(tmp) >> 16, \
a); \
pz[_a]=zz; \
} \
} \
z+=dzdx; \
s+=dsdx; \
t+=dtdx; \
}
#include "ztriangle.h"
}
void FNAME(ZB_fillTriangleMappingSmooth) (ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2)
{
PIXEL *texture;
#define INTERP_Z
#define INTERP_ST
#define INTERP_RGB
#define DRAW_INIT() \
{ \
texture=zb->current_texture; \
}
#define PUT_PIXEL(_a) \
{ \
zz=z >> ZB_POINT_Z_FRAC_BITS; \
if (ZCMP(zz,pz[_a])) { \
tmp=texture[((t & 0x3FC00000) | s) >> 14]; \
int a = oa1 * PIXEL_A(tmp) >> 16; \
if (ACMP(a)) { \
pp[_a] = RGBA_TO_PIXEL(or1 * PIXEL_R(tmp) >> 16, \
og1 * PIXEL_G(tmp) >> 16, \
ob1 * PIXEL_B(tmp) >> 16, \
a); \
pz[_a]=zz; \
} \
} \
z+=dzdx; \
og1+=dgdx; \
or1+=drdx; \
ob1+=dbdx; \
oa1+=dadx; \
s+=dsdx; \
t+=dtdx; \
}
#include "ztriangle.h"
}
/*
* Texture mapping with perspective correction.
* We use the gradient method to make less divisions.
* TODO: pipeline the division
*/
void FNAME(ZB_fillTriangleMappingPerspective) (ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2)
{
PIXEL *texture;
float fdzdx,fndzdx,ndszdx,ndtzdx;
#define INTERP_Z
#define INTERP_STZ
#define NB_INTERP 8
#define DRAW_INIT() \
{ \
texture=zb->current_texture; \
fdzdx=(float)dzdx; \
fndzdx=NB_INTERP * fdzdx; \
ndszdx=NB_INTERP * dszdx; \
ndtzdx=NB_INTERP * dtzdx; \
}
#define PUT_PIXEL(_a) \
{ \
zz=z >> ZB_POINT_Z_FRAC_BITS; \
if (ZCMP(zz,pz[_a])) { \
tmp = *(PIXEL *)((char *)texture+ \
(((t & 0x3FC00000) | (s & 0x003FC000)) >> (17 - PSZSH))); \
if (ACMP(PIXEL_A(tmp))) { \
pp[_a]=tmp; \
pz[_a]=zz; \
} \
} \
z+=dzdx; \
s+=dsdx; \
t+=dtdx; \
}
#define DRAW_LINE() \
{ \
register unsigned short *pz; \
register PIXEL *pp; \
register unsigned int s,t,z,zz; \
register int n,dsdx,dtdx; \
float sz,tz,fz,zinv; \
n=(x2>>16)-x1; \
fz=(float)z1; \
zinv=1.0 / fz; \
pp=(PIXEL *)((char *)pp1 + x1 * PSZB); \
pz=pz1+x1; \
z=z1; \
sz=sz1; \
tz=tz1; \
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 ); \
fz+=fndzdx; \
zinv=1.0 / 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; \
} \
{ \
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 ); \
} \
while (n>=0) { \
PUT_PIXEL(0); \
pz+=1; \
pp=(PIXEL *)((char *)pp + PSZB); \
n-=1; \
} \
}
#include "ztriangle.h"
}
/*
* Flat shaded triangle, with perspective-correct mapping.
*/
void FNAME(ZB_fillTriangleMappingPerspectiveFlat) (ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2)
{
PIXEL *texture;
float fdzdx,fndzdx,ndszdx,ndtzdx;
int or, og, ob, oa;
#define INTERP_Z
#define INTERP_STZ
#define INTERP_RGB
#define DRAW_INIT() \
{ \
texture=zb->current_texture; \
fdzdx=(float)dzdx; \
fndzdx=NB_INTERP * fdzdx; \
ndszdx=NB_INTERP * dszdx; \
ndtzdx=NB_INTERP * dtzdx; \
or = p2->r; \
og = p2->g; \
ob = p2->b; \
oa = p2->a; \
}
#define PUT_PIXEL(_a) \
{ \
zz=z >> ZB_POINT_Z_FRAC_BITS; \
if (ZCMP(zz,pz[_a])) { \
tmp=*(PIXEL *)((char *)texture+ \
(((t & 0x3FC00000) | (s & 0x003FC000)) >> (17 - PSZSH))); \
int a = oa * PIXEL_A(tmp) >> 16; \
if (ACMP(a)) { \
pp[_a] = RGBA_TO_PIXEL(or * PIXEL_R(tmp) >> 16, \
og * PIXEL_G(tmp) >> 16, \
ob * PIXEL_B(tmp) >> 16, \
a); \
pz[_a]=zz; \
} \
} \
z+=dzdx; \
s+=dsdx; \
t+=dtdx; \
}
#define DRAW_LINE() \
{ \
register unsigned short *pz; \
register PIXEL *pp; \
register unsigned int s,t,z,zz; \
register int n,dsdx,dtdx; \
register unsigned int or1,og1,ob1,oa1; \
float sz,tz,fz,zinv; \
n=(x2>>16)-x1; \
fz=(float)z1; \
zinv=1.0 / fz; \
pp=(PIXEL *)((char *)pp1 + x1 * PSZB); \
pz=pz1+x1; \
z=z1; \
sz=sz1; \
tz=tz1; \
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 ); \
fz+=fndzdx; \
zinv=1.0 / 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; \
} \
{ \
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 ); \
} \
while (n>=0) { \
PUT_PIXEL(0); \
pz+=1; \
pp=(PIXEL *)((char *)pp + PSZB); \
n-=1; \
} \
}
#include "ztriangle.h"
}
/*
* Smooth filled triangle, with perspective-correct mapping.
*/
void FNAME(ZB_fillTriangleMappingPerspectiveSmooth) (ZBuffer *zb,
ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2)
{
PIXEL *texture;
float fdzdx,fndzdx,ndszdx,ndtzdx;
#define INTERP_Z
#define INTERP_STZ
#define INTERP_RGB
#define DRAW_INIT() \
{ \
texture=zb->current_texture; \
fdzdx=(float)dzdx; \
fndzdx=NB_INTERP * fdzdx; \
ndszdx=NB_INTERP * dszdx; \
ndtzdx=NB_INTERP * dtzdx; \
}
#define PUT_PIXEL(_a) \
{ \
zz=z >> ZB_POINT_Z_FRAC_BITS; \
if (ZCMP(zz,pz[_a])) { \
tmp=*(PIXEL *)((char *)texture+ \
(((t & 0x3FC00000) | (s & 0x003FC000)) >> (17 - PSZSH))); \
int a = oa1 * PIXEL_A(tmp) >> 16; \
if (ACMP(a)) { \
pp[_a] = RGBA_TO_PIXEL(or1 * PIXEL_R(tmp) >> 16, \
og1 * PIXEL_G(tmp) >> 16, \
ob1 * PIXEL_B(tmp) >> 16, \
a); \
pz[_a]=zz; \
} \
} \
z+=dzdx; \
og1+=dgdx; \
or1+=drdx; \
ob1+=dbdx; \
oa1+=dadx; \
s+=dsdx; \
t+=dtdx; \
}
#define DRAW_LINE() \
{ \
register unsigned short *pz; \
register PIXEL *pp; \
register unsigned int s,t,z,zz; \
register int n,dsdx,dtdx; \
register unsigned int or1,og1,ob1,oa1; \
float sz,tz,fz,zinv; \
n=(x2>>16)-x1; \
fz=(float)z1; \
zinv=1.0 / fz; \
pp=(PIXEL *)((char *)pp1 + x1 * PSZB); \
pz=pz1+x1; \
z=z1; \
sz=sz1; \
tz=tz1; \
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 ); \
fz+=fndzdx; \
zinv=1.0 / 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; \
} \
{ \
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 ); \
} \
while (n>=0) { \
PUT_PIXEL(0); \
pz+=1; \
pp=(PIXEL *)((char *)pp + PSZB); \
n-=1; \
} \
}
#include "ztriangle.h"
}
#undef ACMP
#undef ZCMP
#undef FNAME