From 08dfacd4259b4c6f6d89e4d0c52ade17e811e314 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 3 Jan 2001 22:17:16 +0000 Subject: New point rasterization functions based on template code that handles CI/RGB, texture, antialiasing, attenuation, etc. --- src/mesa/swrast/s_points.c | 975 ++++-------------------------------------- src/mesa/swrast/s_pointtemp.h | 312 ++++++++++++++ 2 files changed, 393 insertions(+), 894 deletions(-) create mode 100644 src/mesa/swrast/s_pointtemp.h diff --git a/src/mesa/swrast/s_points.c b/src/mesa/swrast/s_points.c index 58cf8e9946..33b11e5d5c 100644 --- a/src/mesa/swrast/s_points.c +++ b/src/mesa/swrast/s_points.c @@ -1,4 +1,4 @@ -/* $Id: s_points.c,v 1.9 2000/12/08 00:20:15 brianp Exp $ */ +/* $Id: s_points.c,v 1.10 2001/01/03 22:17:16 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -30,7 +30,6 @@ #include "macros.h" #include "mmath.h" #include "texstate.h" - #include "s_context.h" #include "s_feedback.h" #include "s_pb.h" @@ -38,897 +37,136 @@ #include "s_span.h" -/**********************************************************************/ -/***** Rasterization *****/ -/**********************************************************************/ - - -/* - * There are 3 pairs (RGBA, CI) of point rendering functions: - * 1. simple: size=1 and no special rasterization functions (fastest) - * 2. size1: size=1 and any rasterization functions - * 3. general: any size and rasterization functions (slowest) - * - */ - - +#define INDEX 0x0 +#define RGBA 0x1 +#define SMOOTH 0x2 +#define TEXTURE 0x4 +#define SPECULAR 0x8 +#define LARGE 0x10 +#define ATTENUATE 0x20 +#define SPRITE 0x40 /* * CI points with size == 1.0 */ -static void -size1_ci_point( GLcontext *ctx, const SWvertex *vert ) -{ - struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; - GLint *pbx = PB->x, *pby = PB->y; - GLdepth *pbz = PB->z; - GLfixed *pbfog = PB->fog; - GLuint *pbi = PB->index; - GLuint pbcount = PB->count; - - pbx[pbcount] = (GLint) vert->win[0]; - pby[pbcount] = (GLint) vert->win[1]; - pbz[pbcount] = (GLint) vert->win[2]; - pbfog[pbcount] = FloatToFixed(vert->fog); - pbi[pbcount] = vert->index; - - PB->count++; - PB_CHECK_FLUSH(ctx, PB); -} - +#define FLAGS (INDEX) +#define NAME size1_ci_point +#include "s_pointtemp.h" /* * RGBA points with size == 1.0 */ -static void -size1_rgba_point( GLcontext *ctx, const SWvertex *vert ) -{ - struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; - - GLint x = (GLint) vert->win[0]; - GLint y = (GLint) vert->win[1]; - GLint z = (GLint) (vert->win[2]); - GLfixed fog = FloatToFixed( vert->fog ); - GLubyte red = vert->color[0]; - GLubyte green = vert->color[1]; - GLubyte blue = vert->color[2]; - GLubyte alpha = vert->color[3]; - - PB_WRITE_RGBA_PIXEL( PB, x, y, z, fog, red, green, blue, alpha ); - PB_CHECK_FLUSH(ctx, PB); -} - +#define FLAGS (RGBA) +#define NAME size1_rgba_point +#include "s_pointtemp.h" /* * General CI points. */ -static void -general_ci_point( GLcontext *ctx, const SWvertex *vert ) -{ - struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; - const GLint isize = (GLint) (ctx->Point._Size + 0.5F); - GLint radius = isize >> 1; - - GLint x0, x1, y0, y1; - GLint ix, iy; - - GLint x = (GLint) vert->win[0]; - GLint y = (GLint) vert->win[1]; - GLint z = (GLint) (vert->win[2]); - - GLfixed fog = FloatToFixed( vert->fog ); - - if (isize & 1) { - /* odd size */ - x0 = x - radius; - x1 = x + radius; - y0 = y - radius; - y1 = y + radius; - } - else { - /* even size */ - x0 = (GLint) (x + 1.5F) - radius; - x1 = x0 + isize - 1; - y0 = (GLint) (y + 1.5F) - radius; - y1 = y0 + isize - 1; - } - - PB_SET_INDEX( PB, vert->index ); - - for (iy = y0; iy <= y1; iy++) { - for (ix = x0; ix <= x1; ix++) { - PB_WRITE_PIXEL( PB, ix, iy, z, fog ); - } - } - PB_CHECK_FLUSH(ctx,PB); -} +#define FLAGS (INDEX | LARGE) +#define NAME general_ci_point +#include "s_pointtemp.h" /* * General RGBA points. */ -static void -general_rgba_point( GLcontext *ctx, const SWvertex *vert ) -{ - struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; - GLint isize = (GLint) (ctx->Point._Size + 0.5F); - GLint radius = isize >> 1; - - GLint x0, x1, y0, y1; - GLint ix, iy; - - GLint x = (GLint) vert->win[0]; - GLint y = (GLint) vert->win[1]; - GLint z = (GLint) (vert->win[2]); - - GLfixed fog = FloatToFixed( vert->fog ); - - if (isize & 1) { - /* odd size */ - x0 = x - radius; - x1 = x + radius; - y0 = y - radius; - y1 = y + radius; - } - else { - /* even size */ - x0 = (GLint) (x + 1.5F) - radius; - x1 = x0 + isize - 1; - y0 = (GLint) (y + 1.5F) - radius; - y1 = y0 + isize - 1; - } - - PB_SET_COLOR( PB, - vert->color[0], - vert->color[1], - vert->color[2], - vert->color[3] ); - - for (iy = y0; iy <= y1; iy++) { - for (ix = x0; ix <= x1; ix++) { - PB_WRITE_PIXEL( PB, ix, iy, z, fog ); - } - } - PB_CHECK_FLUSH(ctx,PB); -} - - +#define FLAGS (RGBA | LARGE) +#define NAME general_rgba_point +#include "s_pointtemp.h" /* * Textured RGBA points. */ -static void -textured_rgba_point( GLcontext *ctx, const SWvertex *vert ) -{ - struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; - - GLint x0, x1, y0, y1; - GLint ix, iy, radius; - GLint red, green, blue, alpha; - GLfloat s, t, u; - - GLint x = (GLint) vert->win[0]; - GLint y = (GLint) vert->win[1]; - GLint z = (GLint) (vert->win[2]); - GLint isize = (GLint) (ctx->Point._Size + 0.5F); - - GLfixed fog = FloatToFixed( vert->fog ); - - if (isize < 1) { - isize = 1; - } - radius = isize >> 1; - - if (isize & 1) { - /* odd size */ - x0 = x - radius; - x1 = x + radius; - y0 = y - radius; - y1 = y + radius; - } - else { - /* even size */ - x0 = (GLint) (x + 1.5F) - radius; - x1 = x0 + isize - 1; - y0 = (GLint) (y + 1.5F) - radius; - y1 = y0 + isize - 1; - } - - red = vert->color[0]; - green = vert->color[1]; - blue = vert->color[2]; - alpha = vert->color[3]; - - if (vert->texcoord[0][3] != 1.0) { - s = vert->texcoord[0][0]/vert->texcoord[0][3]; - t = vert->texcoord[0][1]/vert->texcoord[0][3]; - u = vert->texcoord[0][2]/vert->texcoord[0][3]; - } else { - s = vert->texcoord[0][0]; - t = vert->texcoord[0][1]; - u = vert->texcoord[0][2]; - } - - for (iy = y0; iy <= y1; iy++) { - for (ix = x0; ix <= x1; ix++) { - PB_WRITE_TEX_PIXEL( PB, ix, iy, z, fog, red, green, blue, alpha, - s, t, u ); - } - } - - PB_CHECK_FLUSH(ctx, PB); -} - +#define FLAGS (RGBA | LARGE | TEXTURE) +#define NAME textured_rgba_point +#include "s_pointtemp.h" /* * Multitextured RGBA points. */ -static void -multitextured_rgba_point( GLcontext *ctx, const SWvertex *vert ) -{ - struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; - - const GLint red = vert->color[0]; - const GLint green = vert->color[1]; - const GLint blue = vert->color[2]; - const GLint alpha = vert->color[3]; - const GLint sRed = vert->specular[0]; - const GLint sGreen = vert->specular[1]; - const GLint sBlue = vert->specular[2]; - const GLint x = (GLint) vert->win[0]; - const GLint y = (GLint) vert->win[1]; - const GLint z = (GLint) (vert->win[2]); - GLint x0, x1, y0, y1; - GLint ix, iy; - GLfloat texcoord[MAX_TEXTURE_UNITS][4]; - GLint radius, u; - GLint isize = (GLint) (ctx->Point._Size + 0.5F); - - GLfixed fog = FloatToFixed( vert->fog ); - - if (isize < 1) { - isize = 1; - } - radius = isize >> 1; - - if (isize & 1) { - /* odd size */ - x0 = x - radius; - x1 = x + radius; - y0 = y - radius; - y1 = y + radius; - } - else { - /* even size */ - x0 = (GLint) (x + 1.5F) - radius; - x1 = x0 + isize - 1; - y0 = (GLint) (y + 1.5F) - radius; - y1 = y0 + isize - 1; - } - - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture.Unit[u]._ReallyEnabled) { - if (vert->texcoord[u][3] != 1.0) { - texcoord[u][0] = vert->texcoord[u][0] / - vert->texcoord[u][3]; - texcoord[u][1] = vert->texcoord[u][1] / - vert->texcoord[u][3]; - texcoord[u][2] = vert->texcoord[u][2] / - vert->texcoord[u][3]; - } - else { - texcoord[u][0] = vert->texcoord[u][0]; - texcoord[u][1] = vert->texcoord[u][1]; - texcoord[u][2] = vert->texcoord[u][2]; - } - } - } - - for (iy = y0; iy <= y1; iy++) { - for (ix = x0; ix <= x1; ix++) { - PB_WRITE_MULTITEX_SPEC_PIXEL( PB, ix, iy, z, fog, - red, green, blue, alpha, - sRed, sGreen, sBlue, - texcoord ); - } - } - PB_CHECK_FLUSH(ctx, PB); -} - - -/* - * NOTES on aa point rasterization: - * - * Let d = distance of fragment center from vertex. - * if d < rmin2 then - * fragment has 100% coverage - * else if d > rmax2 then - * fragment has 0% coverage - * else - * fragement has % coverage = (d - rmin2) / (rmax2 - rmin2) - */ +#define FLAGS (RGBA | LARGE | TEXTURE | SPECULAR) +#define NAME multitextured_rgba_point +#include "s_pointtemp.h" /* * Antialiased points with or without texture mapping. */ -static void -antialiased_rgba_point( GLcontext *ctx, const SWvertex *vert ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - struct pixel_buffer *PB = swrast->PB; - const GLfloat radius = ctx->Point._Size * 0.5F; - const GLfloat rmin = radius - 0.7071F; /* 0.7071 = sqrt(2)/2 */ - const GLfloat rmax = radius + 0.7071F; - const GLfloat rmin2 = MAX2(0.0, rmin * rmin); - const GLfloat rmax2 = rmax * rmax; - const GLfloat cscale = 256.0F / (rmax2 - rmin2); - - if (ctx->Texture._ReallyEnabled) { - GLint x, y; - GLfloat vx = vert->win[0]; - GLfloat vy = vert->win[1]; - const GLint xmin = (GLint) (vx - radius); - const GLint xmax = (GLint) (vx + radius); - const GLint ymin = (GLint) (vy - radius); - const GLint ymax = (GLint) (vy + radius); - const GLint z = (GLint) (vert->win[2]); - const GLint red = vert->color[0]; - const GLint green = vert->color[1]; - const GLint blue = vert->color[2]; - GLfloat texcoord[MAX_TEXTURE_UNITS][4]; - GLint u, alpha; - - GLfixed fog = FloatToFixed( vert->fog ); - - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture.Unit[u]._ReallyEnabled) { - if (texcoord[u][3] != 1.0) { - texcoord[u][0] = (vert->texcoord[u][0] / - vert->texcoord[u][3]); - texcoord[u][1] = (vert->texcoord[u][1] / - vert->texcoord[u][3]); - texcoord[u][2] = (vert->texcoord[u][2] / - vert->texcoord[u][3]); - } - else { - texcoord[u][0] = vert->texcoord[u][0]; - texcoord[u][1] = vert->texcoord[u][1]; - texcoord[u][2] = vert->texcoord[u][2]; - } - } - } - - /* translate by a half pixel to simplify math below */ - vx -= 0.5F; - vx -= 0.5F; - - for (y = ymin; y <= ymax; y++) { - for (x = xmin; x <= xmax; x++) { - const GLfloat dx = x - vx; - const GLfloat dy = y - vy; - const GLfloat dist2 = dx*dx + dy*dy; - if (dist2 < rmax2) { - alpha = vert->color[3]; - if (dist2 >= rmin2) { - GLint coverage = (GLint) (256.0F - (dist2 - rmin2) * cscale); - /* coverage is in [0,256] */ - alpha = (alpha * coverage) >> 8; - } - if (swrast->_MultiTextureEnabled) { - PB_WRITE_MULTITEX_PIXEL( PB, x,y,z, fog, - red, green, blue, - alpha, texcoord ); - } - else { - PB_WRITE_TEX_PIXEL( PB, x,y,z, fog, - red, green, blue, alpha, - texcoord[0][0], - texcoord[0][1], - texcoord[0][2] ); - } - } - } - } - - PB_CHECK_FLUSH(ctx,PB); - } - else { - /* Not texture mapped */ - const GLint xmin = (GLint) (vert->win[0] - 0.0 - radius); - const GLint xmax = (GLint) (vert->win[0] - 0.0 + radius); - const GLint ymin = (GLint) (vert->win[1] - 0.0 - radius); - const GLint ymax = (GLint) (vert->win[1] - 0.0 + radius); - const GLint red = vert->color[0]; - const GLint green = vert->color[1]; - const GLint blue = vert->color[2]; - const GLint z = (GLint) (vert->win[2]); - GLint x, y; - - GLfixed fog = FloatToFixed( vert->fog ); - - /* - printf("point %g, %g\n", vert->win[0], vert->win[1]); - printf("%d..%d X %d..%d\n", xmin, xmax, ymin, ymax); - */ - for (y = ymin; y <= ymax; y++) { - for (x = xmin; x <= xmax; x++) { - const GLfloat dx = x + 0.5F - vert->win[0]; - const GLfloat dy = y + 0.5F - vert->win[1]; - const GLfloat dist2 = dx*dx + dy*dy; - if (dist2 < rmax2) { - GLint alpha = vert->color[3]; - if (dist2 >= rmin2) { - GLint coverage = (GLint) (256.0F - (dist2 - rmin2) * cscale); - /* coverage is in [0,256] */ - alpha = (alpha * coverage) >> 8; - } - PB_WRITE_RGBA_PIXEL(PB, x, y, z, fog, - red, green, blue, alpha); - } - } - } - PB_CHECK_FLUSH(ctx,PB); - } -} - - - -/* Definition of the functions for GL_EXT_point_parameters */ - -#if 000 -/* Calculates the distance attenuation formula of a vector of points in - * eye space coordinates - */ -static GLfloat attenuation_distance(const GLcontext *ctx, const GLfloat *pos) -{ - GLfloat dist = GL_SQRT(pos[0]*pos[0]+pos[1]*pos[1]+pos[2]*pos[2]); - return 1.0F / (ctx->Point.Params[0] + - dist * (ctx->Point.Params[1] + - dist * ctx->Point.Params[2])); -} -#endif +#define FLAGS (RGBA | SMOOTH | TEXTURE) +#define NAME antialiased_rgba_point +#include "s_pointtemp.h" /* - * Distance Attenuated General CI points. + * Distance attenuated, general CI points. */ -static void -dist_atten_general_ci_point( GLcontext *ctx, const SWvertex *vert ) -{ - struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; - GLint x0, x1, y0, y1; - GLint ix, iy; - GLint isize, radius; - GLint x = (GLint) vert->win[0]; - GLint y = (GLint) vert->win[1]; - GLint z = (GLint) (vert->win[2]); - - GLfixed fog = FloatToFixed( vert->fog ); - - if (vert->pointSize >= ctx->Point.Threshold) { - isize = (GLint) (MIN2(vert->pointSize, ctx->Point.MaxSize) + 0.5F); - } - else { - isize = (GLint) (MAX2(ctx->Point.Threshold, ctx->Point.MinSize) + 0.5F); - } - radius = isize >> 1; - - if (isize & 1) { - /* odd size */ - x0 = x - radius; - x1 = x + radius; - y0 = y - radius; - y1 = y + radius; - } - else { - /* even size */ - x0 = (GLint) (x + 1.5F) - radius; - x1 = x0 + isize - 1; - y0 = (GLint) (y + 1.5F) - radius; - y1 = y0 + isize - 1; - } - - PB_SET_INDEX( PB, vert->index ); +#define FLAGS (INDEX | ATTENUATE) +#define NAME atten_general_ci_point +#include "s_pointtemp.h" - for (iy=y0;iy<=y1;iy++) { - for (ix=x0;ix<=x1;ix++) { - PB_WRITE_PIXEL( PB, ix, iy, z, fog ); - } - } - PB_CHECK_FLUSH(ctx,PB); -} /* - * Distance Attenuated General RGBA points. + * Distance attenuated, general RGBA points. */ -static void -dist_atten_general_rgba_point( GLcontext *ctx, const SWvertex *vert ) -{ - struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; - GLint x0, x1, y0, y1; - GLint ix, iy; - GLint isize, radius; - GLint x = (GLint) vert->win[0]; - GLint y = (GLint) vert->win[1]; - GLint z = (GLint) (vert->win[2]); - GLchan alpha; - GLfixed fog = FloatToFixed( vert->fog ); - - if (vert->pointSize >= ctx->Point.Threshold) { - isize = (GLint) (MIN2(vert->pointSize, ctx->Point.MaxSize) + 0.5F); - alpha = vert->color[3]; - } - else { - GLfloat dsize = vert->pointSize / ctx->Point.Threshold; - isize = (GLint) (MAX2(ctx->Point.Threshold, ctx->Point.MinSize) + 0.5F); - alpha = (GLint) (vert->color[3] * (dsize * dsize)); - } - radius = isize >> 1; - - if (isize & 1) { - /* odd size */ - x0 = x - radius; - x1 = x + radius; - y0 = y - radius; - y1 = y + radius; - } - else { - /* even size */ - x0 = (GLint) (x + 1.5F) - radius; - x1 = x0 + isize - 1; - y0 = (GLint) (y + 1.5F) - radius; - y1 = y0 + isize - 1; - } +#define FLAGS (RGBA | ATTENUATE) +#define NAME atten_general_rgba_point +#include "s_pointtemp.h" - PB_SET_COLOR( PB, - vert->color[0], - vert->color[1], - vert->color[2], - alpha ); - - for (iy = y0; iy <= y1; iy++) { - for (ix = x0; ix <= x1; ix++) { - PB_WRITE_PIXEL( PB, ix, iy, z, fog ); - } - } - PB_CHECK_FLUSH(ctx,PB); -} /* - * Distance Attenuated Textured RGBA points. + * Distance attenuated, Textured RGBA points. */ -static void -dist_atten_textured_rgba_point( GLcontext *ctx, const SWvertex *vert ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - struct pixel_buffer *PB = swrast->PB; - const GLint x = (GLint) vert->win[0]; - const GLint y = (GLint) vert->win[1]; - const GLint z = (GLint) (vert->win[2]); - const GLint red = vert->color[0]; - const GLint green = vert->color[1]; - const GLint blue = vert->color[2]; - GLfloat texcoord[MAX_TEXTURE_UNITS][4]; - GLint x0, x1, y0, y1; - GLint ix, iy, alpha, u; - GLint isize, radius; - - GLfixed fog = FloatToFixed( vert->fog ); - - /* compute point size and alpha */ - if (vert->pointSize >= ctx->Point.Threshold) { - isize = (GLint) (MIN2(vert->pointSize, ctx->Point.MaxSize) + 0.5F); - alpha = vert->color[3]; - } - else { - GLfloat dsize = vert->pointSize / ctx->Point.Threshold; - isize = (GLint) (MAX2(ctx->Point.Threshold, ctx->Point.MinSize) + 0.5F); - alpha = (GLint) (vert->color[3] * (dsize * dsize)); - } - if (isize < 1) { - isize = 1; - } - radius = isize >> 1; - - if (isize & 1) { - /* odd size */ - x0 = x - radius; - x1 = x + radius; - y0 = y - radius; - y1 = y + radius; - } - else { - /* even size */ - x0 = (GLint) (x + 1.5F) - radius; - x1 = x0 + isize - 1; - y0 = (GLint) (y + 1.5F) - radius; - y1 = y0 + isize - 1; - } +#define FLAGS (RGBA | ATTENUATE | TEXTURE) +#define NAME atten_textured_rgba_point +#include "s_pointtemp.h" - /* get texture coordinates */ - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture.Unit[u]._ReallyEnabled) { - if (texcoord[u][3] != 1.0) { - texcoord[u][0] = vert->texcoord[u][0] / - vert->texcoord[u][3]; - texcoord[u][1] = vert->texcoord[u][1] / - vert->texcoord[u][3]; - texcoord[u][2] = vert->texcoord[u][2] / - vert->texcoord[u][3]; - } - else { - texcoord[u][0] = vert->texcoord[u][0]; - texcoord[u][1] = vert->texcoord[u][1]; - texcoord[u][2] = vert->texcoord[u][2]; - } - } - } - - for (iy = y0; iy <= y1; iy++) { - for (ix = x0; ix <= x1; ix++) { - if (swrast->_MultiTextureEnabled) { - PB_WRITE_MULTITEX_PIXEL( PB, ix, iy, z, fog, - red, green, blue, alpha, - texcoord ); - } - else { - PB_WRITE_TEX_PIXEL( PB, ix, iy, z, fog, - red, green, blue, alpha, - texcoord[0][0], - texcoord[0][1], - texcoord[0][2] ); - } - } - } - PB_CHECK_FLUSH(ctx,PB); -} /* - * Distance Attenuated Antialiased points with or without texture mapping. + * Distance attenuated, Antialiased points with or without texture mapping. */ -static void -dist_atten_antialiased_rgba_point( GLcontext *ctx, const SWvertex *vert ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - struct pixel_buffer *PB = swrast->PB; - - if (ctx->Texture._ReallyEnabled) { - GLfloat radius, rmin, rmax, rmin2, rmax2, cscale, alphaAtten; - GLint xmin, ymin, xmax, ymax; - GLint x, y, z; - GLint red, green, blue, alpha; - GLfloat texcoord[MAX_TEXTURE_UNITS][4]; - GLint u; - - GLfixed fog = FloatToFixed( vert->fog ); - - if (vert->pointSize >= ctx->Point.Threshold) { - radius = MIN2(vert->pointSize, ctx->Point.MaxSize) * 0.5F; - alphaAtten = 1.0F; - } - else { - GLfloat dsize = vert->pointSize / ctx->Point.Threshold; - radius = (MAX2(ctx->Point.Threshold, ctx->Point.MinSize) * 0.5F); - alphaAtten = dsize * dsize; - } - rmin = radius - 0.7071F; /* 0.7071 = sqrt(2)/2 */ - rmax = radius + 0.7071F; - rmin2 = MAX2(0.0, rmin * rmin); - rmax2 = rmax * rmax; - cscale = 256.0F / (rmax2 - rmin2); - - xmin = (GLint) (vert->win[0] - radius); - xmax = (GLint) (vert->win[0] + radius); - ymin = (GLint) (vert->win[1] - radius); - ymax = (GLint) (vert->win[1] + radius); - z = (GLint) (vert->win[2]); - - red = vert->color[0]; - green = vert->color[1]; - blue = vert->color[2]; - - /* get texture coordinates */ - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture.Unit[u]._ReallyEnabled) { - if (vert->texcoord[u][3] != 1.0 && vert->texcoord[u][3] != 0.0) { - texcoord[u][0] = vert->texcoord[u][0] / vert->texcoord[u][3]; - texcoord[u][1] = vert->texcoord[u][1] / vert->texcoord[u][3]; - texcoord[u][2] = vert->texcoord[u][2] / vert->texcoord[u][3]; - } - else { - texcoord[u][0] = vert->texcoord[u][0]; - texcoord[u][1] = vert->texcoord[u][1]; - texcoord[u][2] = vert->texcoord[u][2]; - } - } - } - - for (y = ymin; y <= ymax; y++) { - for (x = xmin; x <= xmax; x++) { - const GLfloat dx = x + 0.5F - vert->win[0]; - const GLfloat dy = y + 0.5F - vert->win[1]; - const GLfloat dist2 = dx*dx + dy*dy; - if (dist2 < rmax2) { - alpha = vert->color[3]; - if (dist2 >= rmin2) { - GLint coverage = (GLint) (256.0F - (dist2 - rmin2) * cscale); - /* coverage is in [0,256] */ - alpha = (alpha * coverage) >> 8; - } - alpha = (GLint) (alpha * alphaAtten); - if (swrast->_MultiTextureEnabled) { - PB_WRITE_MULTITEX_PIXEL( PB, x, y, z, fog, - red, green, blue, alpha, - texcoord ); - } - else { - PB_WRITE_TEX_PIXEL( PB, x,y,z, fog, - red, green, blue, alpha, - texcoord[0][0], - texcoord[0][1], - texcoord[0][2] ); - } - } - } - } - PB_CHECK_FLUSH(ctx,PB); - } - else { - /* Not texture mapped */ - GLfloat radius, rmin, rmax, rmin2, rmax2, cscale, alphaAtten; - GLint xmin, ymin, xmax, ymax; - GLint x, y, z; - GLfixed fog; - GLint red, green, blue, alpha; - - if (vert->pointSize >= ctx->Point.Threshold) { - radius = MIN2(vert->pointSize, ctx->Point.MaxSize) * 0.5F; - alphaAtten = 1.0F; - } - else { - GLfloat dsize = vert->pointSize / ctx->Point.Threshold; - radius = (MAX2(ctx->Point.Threshold, ctx->Point.MinSize) * 0.5F); - alphaAtten = dsize * dsize; - } - rmin = radius - 0.7071F; /* 0.7071 = sqrt(2)/2 */ - rmax = radius + 0.7071F; - rmin2 = MAX2(0.0, rmin * rmin); - rmax2 = rmax * rmax; - cscale = 256.0F / (rmax2 - rmin2); - - xmin = (GLint) (vert->win[0] - radius); - xmax = (GLint) (vert->win[0] + radius); - ymin = (GLint) (vert->win[1] - radius); - ymax = (GLint) (vert->win[1] + radius); - z = (GLint) (vert->win[2]); - - fog = FloatToFixed( vert->fog ); - - red = vert->color[0]; - green = vert->color[1]; - blue = vert->color[2]; - - for (y = ymin; y <= ymax; y++) { - for (x = xmin; x <= xmax; x++) { - const GLfloat dx = x + 0.5F - vert->win[0]; - const GLfloat dy = y + 0.5F - vert->win[1]; - const GLfloat dist2 = dx * dx + dy * dy; - if (dist2 < rmax2) { - alpha = vert->color[3]; - if (dist2 >= rmin2) { - GLint coverage = (GLint) (256.0F - (dist2 - rmin2) * cscale); - /* coverage is in [0,256] */ - alpha = (alpha * coverage) >> 8; - } - alpha = (GLint) (alpha * alphaAtten); - PB_WRITE_RGBA_PIXEL(PB, x, y, z, fog, - red, green, blue, alpha); - } - } - } - PB_CHECK_FLUSH(ctx,PB); - } -} +#define FLAGS (RGBA | ATTENUATE | TEXTURE | SMOOTH) +#define NAME atten_antialiased_rgba_point +#include "s_pointtemp.h" /* * Sprite (textured point) */ -static void -sprite_point( GLcontext *ctx, const SWvertex *vert ) -{ - SWcontext *swctx = SWRAST_CONTEXT(ctx); - const GLfloat radius = vert->pointSize; /* XXX threshold, alpha */ - SWvertex v0, v1, v2, v3; - GLuint unit; - - /* lower left corner */ - v0 = *vert; - v0.win[0] -= radius; - v0.win[1] -= radius; +#define FLAGS (RGBA | TEXTURE | SPRITE) +#define NAME sprite_point +#include "s_pointtemp.h" - /* lower right corner */ - v1 = *vert; - v1.win[0] += radius; - v1.win[1] -= radius; - /* upper right corner */ - v2 = *vert; - v2.win[0] += radius; - v2.win[1] += radius; +#define FLAGS (RGBA | ATTENUATE | TEXTURE | SPRITE) +#define NAME atten_sprite_point +#include "s_pointtemp.h" - /* upper left corner */ - v3 = *vert; - v3.win[0] -= radius; - v3.win[1] += radius; - for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { - if (ctx->Texture.Unit[unit]._ReallyEnabled) { - v0.texcoord[unit][0] = 0.0; - v0.texcoord[unit][1] = 0.0; - v1.texcoord[unit][0] = 1.0; - v1.texcoord[unit][1] = 0.0; - v2.texcoord[unit][0] = 1.0; - v2.texcoord[unit][1] = 1.0; - v3.texcoord[unit][0] = 0.0; - v3.texcoord[unit][1] = 1.0; - } - } - /* XXX if radius < threshold, attenuate alpha? */ - /* XXX what about clipping? */ - /* render */ - swctx->Triangle(ctx, &v0, &v1, &v2); - swctx->Triangle(ctx, &v0, &v2, &v3); -} +/* record the current point function name */ +#ifdef DEBUG +static const char *pntFuncName = NULL; +#define USE(pntFunc) \ +do { \ + pntFuncName = #pntFunc; \ + /*printf("%s\n", pntFuncName);*/ \ + swrast->Point = pntFunc; \ +} while (0) +#else -#ifdef DEBUG -extern void -_mesa_print_point_function(GLcontext *ctx); /* silence compiler warning */ -void -_mesa_print_point_function(GLcontext *ctx) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); +#define USE(pntFunc) swrast->Point = pntFunc - printf("Point Func == "); - if (swrast->Point == size1_ci_point) - printf("size1_ci_point\n"); - else if (swrast->Point == size1_rgba_point) - printf("size1_rgba_point\n"); - else if (swrast->Point == general_ci_point) - printf("general_ci_point\n"); - else if (swrast->Point == general_rgba_point) - printf("general_rgba_point\n"); - else if (swrast->Point == textured_rgba_point) - printf("textured_rgba_point\n"); - else if (swrast->Point == multitextured_rgba_point) - printf("multitextured_rgba_point\n"); - else if (swrast->Point == antialiased_rgba_point) - printf("antialiased_rgba_point\n"); - else if (swrast->Point == dist_atten_general_ci_point) - printf("dist_atten_general_ci_point\n"); - else if (swrast->Point == dist_atten_general_rgba_point) - printf("dist_atten_general_rgba_point\n"); - else if (swrast->Point == dist_atten_textured_rgba_point) - printf("dist_atten_textured_rgba_point\n"); - else if (swrast->Point == dist_atten_antialiased_rgba_point) - printf("dist_atten_antialiased_rgba_point\n"); - else if (!swrast->Point) - printf("NULL\n"); - else - printf("Driver func %p\n", swrast->Point); -} #endif @@ -944,111 +182,60 @@ _swrast_choose_point( GLcontext *ctx ) if (ctx->RenderMode==GL_RENDER) { if (ctx->Point.SpriteMode) { - /* XXX this is hacked in! */ - swrast->Point = sprite_point; + /* XXX this might not be good enough */ + if (ctx->Point._Attenuated) + USE(atten_sprite_point); + else + USE(sprite_point); } else if (!ctx->Point._Attenuated) { if (ctx->Point.SmoothFlag && rgbmode) { - swrast->Point = antialiased_rgba_point; + USE(antialiased_rgba_point); } else if (ctx->Texture._ReallyEnabled) { if (swrast->_MultiTextureEnabled || ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR || ctx->Fog.ColorSumEnabled) { - swrast->Point = multitextured_rgba_point; + USE(multitextured_rgba_point); } else { - swrast->Point = textured_rgba_point; + USE(textured_rgba_point); } } else if (ctx->Point._Size == 1.0) { /* size=1, any raster ops */ if (rgbmode) - swrast->Point = size1_rgba_point; + USE(size1_rgba_point); else - swrast->Point = size1_ci_point; + USE(size1_ci_point); } else { /* every other kind of point rendering */ if (rgbmode) - swrast->Point = general_rgba_point; + USE(general_rgba_point); else - swrast->Point = general_ci_point; + USE(general_ci_point); } } else if (ctx->Point.SmoothFlag && rgbmode) { - swrast->Point = dist_atten_antialiased_rgba_point; + USE(atten_antialiased_rgba_point); } else if (ctx->Texture._ReallyEnabled) { - swrast->Point = dist_atten_textured_rgba_point; + USE(atten_textured_rgba_point); } else { /* every other kind of point rendering */ if (rgbmode) - swrast->Point = dist_atten_general_rgba_point; + USE(atten_general_rgba_point); else - swrast->Point = dist_atten_general_ci_point; + USE(atten_general_ci_point); } } else if (ctx->RenderMode==GL_FEEDBACK) { - swrast->Point = gl_feedback_point; + USE(gl_feedback_point); } else { /* GL_SELECT mode */ - swrast->Point = gl_select_point; + USE(gl_select_point); } - - /*_mesa_print_points_function(ctx);*/ } - - - -#if 000 /* prototype of new point code */ - -#define RGBA 0x1 -#define SMOOTH 0x2 -#define LARGE 0x4 -#define TEXTURE 0x8 -#define ATTENUATE 0x10 -#define SPRITE 0x20 - -#define FLAGS (RGBA | SMOOTH | LARGE) -#define NAME rgba_smooth_large -#include "s_pointtemp.h" - -#define FLAGS (RGBA | TEXTURE | ATTENUATE) -#define NAME rgba_texture_smooth_attenuate -#include "s_pointtemp.h" - -#define FLAGS (INDEX | LARGE | ATTENUATE) -#define NAME index_large_attenuate -#include "s_pointtemp.h" - - -static void* point_tab[0x20]; - -void -_swrast_choose_point( GLcontext *ctx ) -{ - GLuint index = 0; - - if (ctx->RenderMode==GL_RENDER) { - if (ctx->Visual.RGBAflag) - index |= RGBA; - if (ctx->Point.SmoothFlag) - index |= SMOOTH; - if (ctx->Point._Attenuated || ctx->Point.Size > 1.0) - index |= SIZED; - if (ctx->Texture.ReallyEnabled) - index |= TEXTURE; - swrast->Point = point_tab[index]; - } - else if (ctx->RenderMode==GL_FEEDBACK) { - swrast->Point = gl_feedback_point; - } - else { - /* GL_SELECT mode */ - swrast->Point = gl_select_point; - } -} -#endif diff --git a/src/mesa/swrast/s_pointtemp.h b/src/mesa/swrast/s_pointtemp.h new file mode 100644 index 0000000000..ed2ab0ca5e --- /dev/null +++ b/src/mesa/swrast/s_pointtemp.h @@ -0,0 +1,312 @@ +/* $Id: s_pointtemp.h,v 1.1 2001/01/03 22:17:16 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/* + * Point rendering template code. + * + * Set FLAGS = bitwise-OR of the following tokens: + * + * RGBA = do rgba instead of color index + * SMOOTH = do antialiasing + * TEXTURE = do texture coords + * SPECULAR = do separate specular color + * LARGE = do points with diameter > 1 pixel + * ATTENUATE = compute point size attenuation + * SPRITE = GL_MESA_sprite_point + * + * Notes: LARGE and ATTENUATE are exclusive of each other. + * TEXTURE requires RGBA + * SPECULAR requires TEXTURE + */ + + +/* + * NOTES on antialiased point rasterization: + * + * Let d = distance of fragment center from vertex. + * if d < rmin2 then + * fragment has 100% coverage + * else if d > rmax2 then + * fragment has 0% coverage + * else + * fragement has % coverage = (d - rmin2) / (rmax2 - rmin2) + */ + + + +static void +NAME ( GLcontext *ctx, const SWvertex *vert ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + struct pixel_buffer *PB = swrast->PB; + + const GLint z = (GLint) (vert->win[2]); + const GLfixed fog = FloatToFixed( vert->fog ); + +#if FLAGS & RGBA + const GLint red = vert->color[0]; + const GLint green = vert->color[1]; + const GLint blue = vert->color[2]; + GLint alpha = vert->color[3]; +#if FLAGS & SPECULAR + const GLint sRed = vert->specular[0]; + const GLint sGreen = vert->specular[1]; + const GLint sBlue = vert->specular[2]; +#endif +#else + GLint index = vert->index; +#endif +#if FLAGS & (ATTENUATE | LARGE | SMOOTH) + GLfloat size; +#endif +#if FLAGS & ATTENUATE + GLfloat alphaAtten; +#endif + +#if FLAGS & TEXTURE + GLfloat texcoord[MAX_TEXTURE_UNITS][4]; + GLuint u; + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + if (ctx->Texture.Unit[u]._ReallyEnabled) { + if (vert->texcoord[u][3] != 1.0 && vert->texcoord[u][3] != 0.0) { + texcoord[u][0] = vert->texcoord[u][0] / vert->texcoord[u][3]; + texcoord[u][1] = vert->texcoord[u][1] / vert->texcoord[u][3]; + texcoord[u][2] = vert->texcoord[u][2] / vert->texcoord[u][3]; + } + else { + texcoord[u][0] = vert->texcoord[u][0]; + texcoord[u][1] = vert->texcoord[u][1]; + texcoord[u][2] = vert->texcoord[u][2]; + } + } + } +#endif + +#if FLAGS & ATTENUATE + if (vert->pointSize >= ctx->Point.Threshold) { + size = MIN2(vert->pointSize, ctx->Point.MaxSize); + alphaAtten = 1.0F; + } + else { + GLfloat dsize = vert->pointSize / ctx->Point.Threshold; + size = MAX2(ctx->Point.Threshold, ctx->Point.MinSize); + alphaAtten = dsize * dsize; + } +#elif FLAGS & (LARGE | SMOOTH) + size = ctx->Point._Size; +#endif + +#if FLAGS & SPRITE + { + SWcontext *swctx = SWRAST_CONTEXT(ctx); + const GLfloat radius = 0.5 * vert->pointSize; /* XXX threshold, alpha */ + SWvertex v0, v1, v2, v3; + GLuint unit; + + (void) red; + (void) green; + (void) blue; + (void) alpha; + (void) fog; + (void) z; + + /* lower left corner */ + v0 = *vert; + v0.win[0] -= radius; + v0.win[1] -= radius; + + /* lower right corner */ + v1 = *vert; + v1.win[0] += radius; + v1.win[1] -= radius; + + /* upper right corner */ + v2 = *vert; + v2.win[0] += radius; + v2.win[1] += radius; + + /* upper left corner */ + v3 = *vert; + v3.win[0] -= radius; + v3.win[1] += radius; + + for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { + if (ctx->Texture.Unit[unit]._ReallyEnabled) { + v0.texcoord[unit][0] = 0.0; + v0.texcoord[unit][1] = 0.0; + v1.texcoord[unit][0] = 1.0; + v1.texcoord[unit][1] = 0.0; + v2.texcoord[unit][0] = 1.0; + v2.texcoord[unit][1] = 1.0; + v3.texcoord[unit][0] = 0.0; + v3.texcoord[unit][1] = 1.0; + } + } + + /* XXX if radius < threshold, attenuate alpha? */ + + /* XXX need to implement clipping!!! */ + + /* render */ + swctx->Triangle(ctx, &v0, &v1, &v2); + swctx->Triangle(ctx, &v0, &v2, &v3); + } + +#elif FLAGS & (LARGE | ATTENUATE | SMOOTH) + + { + GLint x, y; + const GLfloat radius = 0.5F * size; +#if FLAGS & SMOOTH + const GLfloat rmin = radius - 0.7071F; /* 0.7071 = sqrt(2)/2 */ + const GLfloat rmax = radius + 0.7071F; + const GLfloat rmin2 = MAX2(0.0, rmin * rmin); + const GLfloat rmax2 = rmax * rmax; + const GLfloat cscale = 256.0F / (rmax2 - rmin2); + const GLint xmin = (GLint) (vert->win[0] - radius); + const GLint xmax = (GLint) (vert->win[0] + radius); + const GLint ymin = (GLint) (vert->win[1] - radius); + const GLint ymax = (GLint) (vert->win[1] + radius); +#else + /* non-smooth */ + GLint xmin, xmax, ymin, ymax; + GLint iSize = (GLint) (size + 0.5F); + GLint iRadius; + iSize = MAX2(1, iSize); + iRadius = iSize / 2; + if (iSize & 1) { + /* odd size */ + xmin = vert->win[0] - iRadius; + xmax = vert->win[0] + iRadius; + ymin = vert->win[1] - iRadius; + ymax = vert->win[1] + iRadius; + } + else { + /* even size */ + xmin = (GLint) vert->win[0] - iRadius + 1; + xmax = xmin + iSize - 1; + ymin = (GLint) vert->win[1] - iRadius + 1; + ymax = ymin + iSize - 1; + } +#endif + (void) radius; + + for (y = ymin; y <= ymax; y++) { + for (x = xmin; x <= xmax; x++) { +#if FLAGS & SMOOTH + /* compute coverage */ + const GLfloat dx = x - vert->win[0]; + const GLfloat dy = y - vert->win[1]; + const GLfloat dist2 = dx * dx + dy * dy; + if (dist2 < rmax2) { + alpha = vert->color[3]; + if (dist2 >= rmin2) { + GLint coverage = (GLint) (256.0F - (dist2 - rmin2) * cscale); +#if FLAGS & RGBA + /* coverage is in [0,256] */ + alpha = (alpha * coverage) >> 8; +#else + /* 4 fractional index bits */ + index = (index & ~f) | (coverage >> 4); /* XXX verify */ +#endif + } +#endif /* SMOOTH */ + +#if ((FLAGS & (ATTENUATE | RGBA)) == (ATTENUATE | RGBA)) + alpha = (GLint) (alpha * alphaAtten); +#endif + +#if FLAGS & SPECULAR + PB_WRITE_MULTITEX_SPEC_PIXEL(PB, x, y, z, fog, + red, green, blue, alpha, + sRed, sGreen, sBlue, + texcoord); + +#elif FLAGS & TEXTURE + if (swrast->_MultiTextureEnabled) { + PB_WRITE_MULTITEX_PIXEL(PB, x, y, z, fog, + red, green, blue, alpha, + texcoord); + } + else { + PB_WRITE_TEX_PIXEL(PB, x,y,z, fog, + red, green, blue, alpha, + texcoord[0][0], + texcoord[0][1], + texcoord[0][2]); + } +#elif FLAGS & RGBA + PB_WRITE_RGBA_PIXEL(PB, x, y, z, fog, red, green, blue, alpha); +#else /* color index */ + PB_WRITE_CI_PIXEL(PB, x, y, z, fog, index); +#endif +#if FLAGS & SMOOTH + } +#endif + } + } + PB_CHECK_FLUSH(ctx,PB); + } + +#else /* LARGE || ATTENUATE || SMOOTH*/ + + { + /* size == 1 */ + GLint x = vert->win[0]; + GLint y = vert->win[1]; +#if ((FLAGS & (SPECULAR | TEXTURE)) == (SPECULAR | TEXTURE)) + PB_WRITE_MULTITEX_SPEC_PIXEL(PB, x, y, z, fog, + red, green, blue, alpha, + sRed, sGreen, sBlue, + texcoord); +#elif FLAGS & TEXTURE + if (swrast->_MultiTextureEnabled) { + PB_WRITE_MULTITEX_PIXEL(PB, x, y, z, fog, + red, green, blue, alpha, texcoord ); + } + else { + PB_WRITE_TEX_PIXEL(PB, x, y, z, fog, + red, green, blue, alpha, + texcoord[0][0], texcoord[0][1], texcoord[0][2]); + } +#elif FLAGS & RGBA + /* rgba size 1 point */ + alpha = vert->color[3]; + PB_WRITE_RGBA_PIXEL(PB, x, y, z, fog, red, green, blue, alpha); +#else + /* color index size 1 point */ + PB_WRITE_CI_PIXEL(PB, x, y, z, fog, index); +#endif + } +#endif /* LARGE || ATTENUATE || SMOOTH */ + + PB_CHECK_FLUSH(ctx, PB); +} + + +#undef FLAGS +#undef NAME -- cgit v1.2.3