progress on rendering modes
This commit is contained in:
parent
bed83ef77f
commit
d48ff75151
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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, >c->_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, >c->_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 = >c->_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 = >c->_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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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_ */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
Loading…
Reference in New Issue