📄 tdfx_tris.c
字号:
/* -*- mode: c; c-basic-offset: 3 -*- * * Copyright 2000 VA Linux Systems Inc., Fremont, California. * * 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 (including the next * paragraph) 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 * VA LINUX SYSTEMS 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. *//* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.c,v 1.4 2002/10/30 12:52:01 alanh Exp $ *//* New fixes: * Daniel Borca <dborca@users.sourceforge.net>, 19 Jul 2004 * * Authors: * Keith Whitwell <keith@tungstengraphics.com> */#include "glheader.h"#include "mtypes.h"#include "macros.h"#include "colormac.h"#include "swrast/swrast.h"#include "swrast_setup/swrast_setup.h"#include "swrast_setup/ss_context.h"#include "tnl/t_context.h"#include "tnl/t_pipeline.h"#include "tdfx_tris.h"#include "tdfx_state.h"#include "tdfx_vb.h"#include "tdfx_lock.h"#include "tdfx_render.h"static void tdfxRasterPrimitive( GLcontext *ctx, GLenum prim );static void tdfxRenderPrimitive( 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_triangle( fxMesa, a, b, c ); \ else \ fxMesa->Glide.grDrawTriangle( a, b, c ); \} while (0) \#define QUAD( a, b, c, d ) \do { \ if (DO_FALLBACK) { \ fxMesa->draw_triangle( fxMesa, a, b, d ); \ fxMesa->draw_triangle( fxMesa, b, c, d ); \ } else { \ tdfxVertex *_v_[4]; \ _v_[0] = d; \ _v_[1] = a; \ _v_[2] = b; \ _v_[3] = c; \ fxMesa->Glide.grDrawVertexArray(GR_TRIANGLE_FAN, 4, _v_);\ /*fxMesa->Glide.grDrawTriangle( a, b, d );*/\ /*fxMesa->Glide.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; \ fxMesa->Glide.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; \ fxMesa->Glide.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 void tdfx_translate_vertex( GLcontext *ctx, const tdfxVertex *src, SWvertex *dst){ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); if (fxMesa->vertexFormat == TDFX_LAYOUT_TINY) { dst->attrib[FRAG_ATTRIB_WPOS][0] = src->x - fxMesa->x_offset; dst->attrib[FRAG_ATTRIB_WPOS][1] = src->y - (fxMesa->screen_height - fxMesa->height - fxMesa->y_offset); dst->attrib[FRAG_ATTRIB_WPOS][2] = src->z; dst->attrib[FRAG_ATTRIB_WPOS][3] = 1.0; dst->color[0] = src->color[2]; dst->color[1] = src->color[1]; dst->color[2] = src->color[0]; dst->color[3] = src->color[3]; } else { GLfloat w = 1.0 / src->rhw; dst->attrib[FRAG_ATTRIB_WPOS][0] = src->x - fxMesa->x_offset; dst->attrib[FRAG_ATTRIB_WPOS][1] = src->y - (fxMesa->screen_height - fxMesa->height - fxMesa->y_offset); dst->attrib[FRAG_ATTRIB_WPOS][2] = src->z; dst->attrib[FRAG_ATTRIB_WPOS][3] = src->rhw; dst->color[0] = src->color[2]; dst->color[1] = src->color[1]; dst->color[2] = src->color[0]; dst->color[3] = src->color[3]; dst->attrib[FRAG_ATTRIB_TEX0][0] = 1.0 / fxMesa->sScale0 * w * src->tu0; dst->attrib[FRAG_ATTRIB_TEX0][1] = 1.0 / fxMesa->tScale0 * w * src->tv0; if (fxMesa->vertexFormat == TDFX_LAYOUT_PROJ1 || fxMesa->vertexFormat == TDFX_LAYOUT_PROJ2) { dst->attrib[FRAG_ATTRIB_TEX0][3] = w * src->tq0; } else { dst->attrib[FRAG_ATTRIB_TEX0][3] = 1.0; } if (fxMesa->SetupIndex & TDFX_TEX1_BIT) { dst->attrib[FRAG_ATTRIB_TEX1][0] = 1.0 / fxMesa->sScale1 * w * src->tu1; dst->attrib[FRAG_ATTRIB_TEX1][1] = 1.0 / fxMesa->tScale1 * w * src->tv1; if (fxMesa->vertexFormat == TDFX_LAYOUT_PROJ2) { dst->attrib[FRAG_ATTRIB_TEX1][3] = w * src->tq1; } else { dst->attrib[FRAG_ATTRIB_TEX1][3] = 1.0; } } } dst->pointSize = ctx->Point.Size;}static void tdfx_fallback_tri( tdfxContextPtr fxMesa, tdfxVertex *v0, tdfxVertex *v1, tdfxVertex *v2 ){ GLcontext *ctx = fxMesa->glCtx; SWvertex v[3]; tdfx_translate_vertex( ctx, v0, &v[0] ); tdfx_translate_vertex( ctx, v1, &v[1] ); tdfx_translate_vertex( ctx, v2, &v[2] ); _swrast_Triangle( ctx, &v[0], &v[1], &v[2] );}static void tdfx_fallback_line( tdfxContextPtr fxMesa, tdfxVertex *v0, tdfxVertex *v1 ){ GLcontext *ctx = fxMesa->glCtx; SWvertex v[2]; tdfx_translate_vertex( ctx, v0, &v[0] ); tdfx_translate_vertex( ctx, v1, &v[1] ); _swrast_Line( ctx, &v[0], &v[1] );}static void tdfx_fallback_point( tdfxContextPtr fxMesa, tdfxVertex *v0 ){ GLcontext *ctx = fxMesa->glCtx; SWvertex v[1]; tdfx_translate_vertex( ctx, v0, &v[0] ); _swrast_Point( ctx, &v[0] );}/*********************************************************************** * Functions to draw basic primitives * ***********************************************************************/static void tdfx_print_vertex( GLcontext *ctx, const tdfxVertex *v ){ tdfxContextPtr tmesa = TDFX_CONTEXT( ctx ); fprintf(stderr, "vertex at %p\n", (void *)v); if (tmesa->vertexFormat == TDFX_LAYOUT_TINY) { fprintf(stderr, "x %f y %f z %f\n", v->x, v->y, v->z); } else { fprintf(stderr, "x %f y %f z %f oow %f\n", v->x, v->y, v->z, v->rhw); } fprintf(stderr, "r %d g %d b %d a %d\n", v->color[0], v->color[1], v->color[2], v->color[3]); 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 tdfx_draw_triangle( tdfxContextPtr fxMesa, tdfxVertexPtr v0, tdfxVertexPtr v1, tdfxVertexPtr v2 ){/* fprintf(stderr, "%s\n", __FUNCTION__); *//* tdfx_print_vertex( fxMesa->glCtx, v0 ); *//* tdfx_print_vertex( fxMesa->glCtx, v1 ); *//* tdfx_print_vertex( fxMesa->glCtx, v2 ); */ BEGIN_CLIP_LOOP_LOCKED(fxMesa) { TRI( v0, v1, v2 ); } END_CLIP_LOOP_LOCKED(fxMesa);}static void tdfx_draw_line( tdfxContextPtr fxMesa, tdfxVertexPtr v0, tdfxVertexPtr v1 ){ /* No support for wide lines (avoid wide/aa line fallback). */ BEGIN_CLIP_LOOP_LOCKED(fxMesa) { LINE(v0, v1); } END_CLIP_LOOP_LOCKED(fxMesa);}static void tdfx_draw_point( tdfxContextPtr fxMesa, tdfxVertexPtr v0 ){ /* No support for wide points. */ BEGIN_CLIP_LOOP_LOCKED(fxMesa) { POINT( v0 ); } END_CLIP_LOOP_LOCKED(fxMesa);}#undef DO_FALLBACK#define TDFX_UNFILLED_BIT 0x1#define TDFX_OFFSET_BIT 0x2#define TDFX_TWOSIDE_BIT 0x4#define TDFX_FLAT_BIT 0x8#define TDFX_FALLBACK_BIT 0x10#define TDFX_MAX_TRIFUNC 0x20static struct { tnl_points_func points; tnl_line_func line; tnl_triangle_func triangle; tnl_quad_func quad;} rast_tab[TDFX_MAX_TRIFUNC];#define DO_FALLBACK (IND & TDFX_FALLBACK_BIT)#define DO_OFFSET (IND & TDFX_OFFSET_BIT)#define DO_UNFILLED (IND & TDFX_UNFILLED_BIT)#define DO_TWOSIDE (IND & TDFX_TWOSIDE_BIT)#define DO_FLAT (IND & TDFX_FLAT_BIT)#define DO_TRI 1#define DO_QUAD 1#define DO_LINE 1#define DO_POINTS 1#define DO_FULL_QUAD 1#define HAVE_RGBA 1#define HAVE_SPEC 0#define HAVE_HW_FLATSHADE 0#define HAVE_BACK_COLORS 0#define VERTEX tdfxVertex#define TAB rast_tab#define DEPTH_SCALE 1.0#define UNFILLED_TRI unfilled_tri#define UNFILLED_QUAD unfilled_quad#define VERT_X(_v) _v->x#define VERT_Y(_v) _v->y#define VERT_Z(_v) _v->z#define AREA_IS_CCW( a ) (a < 0)#define GET_VERTEX(e) (fxMesa->verts + (e))#define VERT_SET_RGBA( dst, f ) \do { \ UNCLAMPED_FLOAT_TO_UBYTE(dst->color[2], f[0]);\ UNCLAMPED_FLOAT_TO_UBYTE(dst->color[1], f[1]);\ UNCLAMPED_FLOAT_TO_UBYTE(dst->color[0], f[2]);\ UNCLAMPED_FLOAT_TO_UBYTE(dst->color[3], f[3]);\} while (0)#define VERT_COPY_RGBA( v0, v1 ) \ *(GLuint *)&v0->color = *(GLuint *)&v1->color#define VERT_SAVE_RGBA( idx ) \ *(GLuint *)&color[idx] = *(GLuint *)&v[idx]->color#define VERT_RESTORE_RGBA( idx ) \ *(GLuint *)&v[idx]->color = *(GLuint *)&color[idx]#define LOCAL_VARS(n) \ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); \ GLubyte color[n][4]; \ (void) color;/*********************************************************************** * Functions to draw basic unfilled primitives * ***********************************************************************/#define RASTERIZE(x) if (fxMesa->raster_primitive != reduced_prim[x]) \ tdfxRasterPrimitive( ctx, reduced_prim[x] )#define RENDER_PRIMITIVE fxMesa->render_primitive#define IND TDFX_FALLBACK_BIT#define TAG(x) x#include "tnl_dd/t_dd_unfilled.h"#undef IND/*********************************************************************** * Functions to draw GL primitives * ***********************************************************************/#define IND (0)#define TAG(x) x#include "tnl_dd/t_dd_tritmp.h"#define IND (TDFX_OFFSET_BIT)#define TAG(x) x##_offset#include "tnl_dd/t_dd_tritmp.h"#define IND (TDFX_TWOSIDE_BIT)#define TAG(x) x##_twoside#include "tnl_dd/t_dd_tritmp.h"#define IND (TDFX_TWOSIDE_BIT|TDFX_OFFSET_BIT)#define TAG(x) x##_twoside_offset#include "tnl_dd/t_dd_tritmp.h"#define IND (TDFX_UNFILLED_BIT)#define TAG(x) x##_unfilled#include "tnl_dd/t_dd_tritmp.h"#define IND (TDFX_OFFSET_BIT|TDFX_UNFILLED_BIT)#define TAG(x) x##_offset_unfilled#include "tnl_dd/t_dd_tritmp.h"#define IND (TDFX_TWOSIDE_BIT|TDFX_UNFILLED_BIT)#define TAG(x) x##_twoside_unfilled#include "tnl_dd/t_dd_tritmp.h"#define IND (TDFX_TWOSIDE_BIT|TDFX_OFFSET_BIT|TDFX_UNFILLED_BIT)#define TAG(x) x##_twoside_offset_unfilled#include "tnl_dd/t_dd_tritmp.h"#define IND (TDFX_FALLBACK_BIT)#define TAG(x) x##_fallback#include "tnl_dd/t_dd_tritmp.h"#define IND (TDFX_OFFSET_BIT|TDFX_FALLBACK_BIT)#define TAG(x) x##_offset_fallback#include "tnl_dd/t_dd_tritmp.h"#define IND (TDFX_TWOSIDE_BIT|TDFX_FALLBACK_BIT)#define TAG(x) x##_twoside_fallback#include "tnl_dd/t_dd_tritmp.h"#define IND (TDFX_TWOSIDE_BIT|TDFX_OFFSET_BIT|TDFX_FALLBACK_BIT)#define TAG(x) x##_twoside_offset_fallback#include "tnl_dd/t_dd_tritmp.h"#define IND (TDFX_UNFILLED_BIT|TDFX_FALLBACK_BIT)#define TAG(x) x##_unfilled_fallback#include "tnl_dd/t_dd_tritmp.h"#define IND (TDFX_OFFSET_BIT|TDFX_UNFILLED_BIT|TDFX_FALLBACK_BIT)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -