📄 fxtris.c
字号:
/* * Mesa 3-D graphics library * Version: 4.0 * * Copyright (C) 1999-2001 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. *//* Authors: * Keith Whitwell <keith@tungstengraphics.com> * Daniel Borca <dborca@users.sourceforge.net> */#include "glheader.h"#ifdef FX#include "imports.h"#include "mtypes.h"#include "macros.h"#include "colormac.h"#include "swrast/swrast.h"#include "swrast_setup/swrast_setup.h"#include "tnl/t_context.h"#include "tnl/t_pipeline.h"#include "fxdrv.h"static GLboolean fxMultipass_ColorSum (GLcontext *ctx, GLuint pass);/* * Subpixel offsets to adjust Mesa's (true) window coordinates to * Glide coordinates. We need these to ensure precise rasterization. * Otherwise, we'll fail a bunch of conformance tests. */#define TRI_X_OFFSET ( 0.0F)#define TRI_Y_OFFSET ( 0.0F)#define LINE_X_OFFSET ( 0.0F)#define LINE_Y_OFFSET ( 0.125F)#define PNT_X_OFFSET ( 0.375F)#define PNT_Y_OFFSET ( 0.375F)static void fxRasterPrimitive( GLcontext *ctx, GLenum prim );static void fxRenderPrimitive( GLcontext *ctx, GLenum prim );static GLenum reduced_prim[GL_POLYGON+1] = { GL_POINTS, GL_LINES, GL_LINES, GL_LINES, GL_TRIANGLES, GL_TRIANGLES, GL_TRIANGLES, GL_TRIANGLES, GL_TRIANGLES, GL_TRIANGLES};/*********************************************************************** * Macros for t_dd_tritmp.h to draw basic primitives * ***********************************************************************/#define TRI( a, b, c ) \do { \ if (DO_FALLBACK) \ fxMesa->draw_tri( fxMesa, a, b, c ); \ else \ grDrawTriangle( a, b, c ); \} while (0) \#define QUAD( a, b, c, d ) \do { \ if (DO_FALLBACK) { \ fxMesa->draw_tri( fxMesa, a, b, d ); \ fxMesa->draw_tri( fxMesa, b, c, d ); \ } else { \ GrVertex *_v_[4]; \ _v_[0] = d; \ _v_[1] = a; \ _v_[2] = b; \ _v_[3] = c; \ grDrawVertexArray(GR_TRIANGLE_FAN, 4, _v_);\ /*grDrawTriangle( a, b, d );*/ \ /*grDrawTriangle( b, c, d );*/ \ } \} while (0)#define LINE( v0, v1 ) \do { \ if (DO_FALLBACK) \ fxMesa->draw_line( fxMesa, v0, v1 ); \ else { \ v0->x += LINE_X_OFFSET - TRI_X_OFFSET; \ v0->y += LINE_Y_OFFSET - TRI_Y_OFFSET; \ v1->x += LINE_X_OFFSET - TRI_X_OFFSET; \ v1->y += LINE_Y_OFFSET - TRI_Y_OFFSET; \ grDrawLine( v0, v1 ); \ v0->x -= LINE_X_OFFSET - TRI_X_OFFSET; \ v0->y -= LINE_Y_OFFSET - TRI_Y_OFFSET; \ v1->x -= LINE_X_OFFSET - TRI_X_OFFSET; \ v1->y -= LINE_Y_OFFSET - TRI_Y_OFFSET; \ } \} while (0)#define POINT( v0 ) \do { \ if (DO_FALLBACK) \ fxMesa->draw_point( fxMesa, v0 ); \ else { \ v0->x += PNT_X_OFFSET - TRI_X_OFFSET; \ v0->y += PNT_Y_OFFSET - TRI_Y_OFFSET; \ grDrawPoint( v0 ); \ v0->x -= PNT_X_OFFSET - TRI_X_OFFSET; \ v0->y -= PNT_Y_OFFSET - TRI_Y_OFFSET; \ } \} while (0)/*********************************************************************** * Fallback to swrast for basic primitives * ***********************************************************************//* Build an SWvertex from a hardware vertex. * * This code is hit only when a mix of accelerated and unaccelerated * primitives are being drawn, and only for the unaccelerated * primitives. */static voidfx_translate_vertex( GLcontext *ctx, const GrVertex *src, SWvertex *dst){ fxMesaContext fxMesa = FX_CONTEXT(ctx); GLuint ts0 = fxMesa->tmu_source[0]; GLuint ts1 = fxMesa->tmu_source[1]; GLfloat w = 1.0F / src->oow; dst->win[0] = src->x; dst->win[1] = src->y; dst->win[2] = src->ooz; dst->win[3] = src->oow;#if FX_PACKEDCOLOR dst->color[0] = src->pargb[2]; dst->color[1] = src->pargb[1]; dst->color[2] = src->pargb[0]; dst->color[3] = src->pargb[3]; dst->specular[0] = src->pspec[2]; dst->specular[1] = src->pspec[1]; dst->specular[2] = src->pspec[0];#else /* !FX_PACKEDCOLOR */ dst->color[0] = src->r; dst->color[1] = src->g; dst->color[2] = src->b; dst->color[3] = src->a; dst->specular[0] = src->r1; dst->specular[1] = src->g1; dst->specular[2] = src->g1;#endif /* !FX_PACKEDCOLOR */ dst->texcoord[ts0][0] = fxMesa->inv_s0scale * src->tmuvtx[0].sow * w; dst->texcoord[ts0][1] = fxMesa->inv_t0scale * src->tmuvtx[0].tow * w; if (fxMesa->stw_hint_state & GR_STWHINT_W_DIFF_TMU0) dst->texcoord[ts0][3] = src->tmuvtx[0].oow * w; else dst->texcoord[ts0][3] = 1.0F; if (fxMesa->SetupIndex & SETUP_TMU1) { dst->texcoord[ts1][0] = fxMesa->inv_s1scale * src->tmuvtx[1].sow * w; dst->texcoord[ts1][1] = fxMesa->inv_t1scale * src->tmuvtx[1].tow * w; if (fxMesa->stw_hint_state & GR_STWHINT_W_DIFF_TMU1) dst->texcoord[ts1][3] = src->tmuvtx[1].oow * w; else dst->texcoord[ts1][3] = 1.0F; } dst->pointSize = src->psize;}static voidfx_fallback_tri( fxMesaContext fxMesa, GrVertex *v0, GrVertex *v1, GrVertex *v2 ){ GLcontext *ctx = fxMesa->glCtx; SWvertex v[3]; fx_translate_vertex( ctx, v0, &v[0] ); fx_translate_vertex( ctx, v1, &v[1] ); fx_translate_vertex( ctx, v2, &v[2] ); _swrast_Triangle( ctx, &v[0], &v[1], &v[2] );}static voidfx_fallback_line( fxMesaContext fxMesa, GrVertex *v0, GrVertex *v1 ){ GLcontext *ctx = fxMesa->glCtx; SWvertex v[2]; fx_translate_vertex( ctx, v0, &v[0] ); fx_translate_vertex( ctx, v1, &v[1] ); _swrast_Line( ctx, &v[0], &v[1] );}static voidfx_fallback_point( fxMesaContext fxMesa, GrVertex *v0 ){ GLcontext *ctx = fxMesa->glCtx; SWvertex v[1]; fx_translate_vertex( ctx, v0, &v[0] ); _swrast_Point( ctx, &v[0] );}/*********************************************************************** * Functions to draw basic primitives * ***********************************************************************/static void fx_print_vertex( GLcontext *ctx, const GrVertex *v ){ fprintf(stderr, "fx_print_vertex:\n"); fprintf(stderr, "\tvertex at %p\n", (void *) v); fprintf(stderr, "\tx %f y %f z %f oow %f\n", v->x, v->y, v->ooz, v->oow);#if FX_PACKEDCOLOR fprintf(stderr, "\tr %d g %d b %d a %d\n", v->pargb[2], v->pargb[1], v->pargb[0], v->pargb[3]);#else /* !FX_PACKEDCOLOR */ fprintf(stderr, "\tr %f g %f b %f a %f\n", v->r, v->g, v->b, v->a);#endif /* !FX_PACKEDCOLOR */ fprintf(stderr, "\n");}#define DO_FALLBACK 0/* Need to do clip loop at each triangle when mixing swrast and hw * rendering. These functions are only used when mixed-mode rendering * is occurring. */static void fx_draw_triangle( fxMesaContext fxMesa, GrVertex *v0, GrVertex *v1, GrVertex *v2 ){ BEGIN_CLIP_LOOP(); TRI( v0, v1, v2 ); END_CLIP_LOOP();}static void fx_draw_line( fxMesaContext fxMesa, GrVertex *v0, GrVertex *v1 ){ /* No support for wide lines (avoid wide/aa line fallback). */ BEGIN_CLIP_LOOP(); LINE(v0, v1); END_CLIP_LOOP();}static void fx_draw_point( fxMesaContext fxMesa, GrVertex *v0 ){ /* No support for wide points. */ BEGIN_CLIP_LOOP(); POINT( v0 ); END_CLIP_LOOP();}#ifndef M_2PI#define M_2PI 6.28318530717958647692528676655901#endif#define __GL_COSF cos#define __GL_SINF sinstatic void fx_draw_point_sprite ( fxMesaContext fxMesa, GrVertex *v0, GLfloat psize ){ const GLcontext *ctx = fxMesa->glCtx; GLfloat radius; GrVertex _v_[4]; GLuint ts0 = fxMesa->tmu_source[0]; GLuint ts1 = fxMesa->tmu_source[1]; GLfloat w = v0->oow; GLfloat u0scale = fxMesa->s0scale * w; GLfloat v0scale = fxMesa->t0scale * w; GLfloat u1scale = fxMesa->s1scale * w; GLfloat v1scale = fxMesa->t1scale * w; radius = psize / 2.0F; _v_[0] = *v0; _v_[1] = *v0; _v_[2] = *v0; _v_[3] = *v0; /* CLIP_LOOP ?!? */ /* point coverage? */ /* we don't care about culling here (see fxSetupCull) */ if (ctx->Point.SpriteOrigin == GL_UPPER_LEFT) { _v_[0].x -= radius; _v_[0].y += radius; _v_[1].x += radius; _v_[1].y += radius; _v_[2].x += radius; _v_[2].y -= radius; _v_[3].x -= radius; _v_[3].y -= radius; } else { _v_[0].x -= radius; _v_[0].y -= radius; _v_[1].x += radius; _v_[1].y -= radius; _v_[2].x += radius; _v_[2].y += radius; _v_[3].x -= radius; _v_[3].y += radius; } if (ctx->Point.CoordReplace[ts0]) { _v_[0].tmuvtx[0].sow = 0; _v_[0].tmuvtx[0].tow = 0; _v_[1].tmuvtx[0].sow = u0scale; _v_[1].tmuvtx[0].tow = 0; _v_[2].tmuvtx[0].sow = u0scale; _v_[2].tmuvtx[0].tow = v0scale; _v_[3].tmuvtx[0].sow = 0; _v_[3].tmuvtx[0].tow = v0scale; } if (ctx->Point.CoordReplace[ts1]) { _v_[0].tmuvtx[1].sow = 0; _v_[0].tmuvtx[1].tow = 0; _v_[1].tmuvtx[1].sow = u1scale; _v_[1].tmuvtx[1].tow = 0; _v_[2].tmuvtx[1].sow = u1scale; _v_[2].tmuvtx[1].tow = v1scale; _v_[3].tmuvtx[1].sow = 0; _v_[3].tmuvtx[1].tow = v1scale; } grDrawVertexArrayContiguous(GR_TRIANGLE_FAN, 4, _v_, sizeof(GrVertex));}static void fx_draw_point_wide ( fxMesaContext fxMesa, GrVertex *v0 ){ GLint i, n; GLfloat ang, radius, oon; GrVertex vtxB, vtxC; GrVertex *_v_[3]; const GLcontext *ctx = fxMesa->glCtx; const GLfloat psize = (ctx->_TriangleCaps & DD_POINT_ATTEN) ? CLAMP(v0->psize, ctx->Point.MinSize, ctx->Point.MaxSize) : ctx->Point._Size; /* clamped */ if (ctx->Point.PointSprite) { fx_draw_point_sprite(fxMesa, v0, psize); return; } _v_[0] = v0; _v_[1] = &vtxB; _v_[2] = &vtxC; radius = psize / 2.0F; n = IROUND(psize * 2); /* radius x 4 */ if (n < 4) n = 4; oon = 1.0F / (GLfloat)n; /* CLIP_LOOP ?!? */ /* point coverage? */ /* we don't care about culling here (see fxSetupCull) */ vtxB = *v0; vtxC = *v0; vtxB.x += radius; ang = M_2PI * oon; vtxC.x += radius * __GL_COSF(ang); vtxC.y += radius * __GL_SINF(ang); grDrawVertexArray(GR_TRIANGLE_FAN, 3, _v_); for (i = 2; i <= n; i++) { ang = M_2PI * i * oon; vtxC.x = v0->x + radius * __GL_COSF(ang); vtxC.y = v0->y + radius * __GL_SINF(ang); grDrawVertexArray(GR_TRIANGLE_FAN_CONTINUE, 1, &_v_[2]); }}static void fx_render_pw_verts( GLcontext *ctx, GLuint start, GLuint count, GLuint flags ){ fxMesaContext fxMesa = FX_CONTEXT(ctx); GrVertex *fxVB = fxMesa->verts; (void) flags; fxRenderPrimitive( ctx, GL_POINTS ); for ( ; start < count ; start++) fx_draw_point_wide(fxMesa, fxVB + start);}static void fx_render_pw_elts ( GLcontext *ctx, GLuint start, GLuint count, GLuint flags ){ fxMesaContext fxMesa = FX_CONTEXT(ctx); GrVertex *fxVB = fxMesa->verts; const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; (void) flags; fxRenderPrimitive( ctx, GL_POINTS ); for ( ; start < count ; start++) fx_draw_point_wide(fxMesa, fxVB + elt[start]);}static void fx_draw_point_wide_aa ( fxMesaContext fxMesa, GrVertex *v0 ){ GLint i, n; GLfloat ang, radius, oon; GrVertex vtxB, vtxC; const GLcontext *ctx = fxMesa->glCtx; const GLfloat psize = (ctx->_TriangleCaps & DD_POINT_ATTEN) ? CLAMP(v0->psize, ctx->Point.MinSize, ctx->Point.MaxSize) : ctx->Point._Size; /* clamped */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -