/shark/trunk/ports/mesa/src/tnl_dd/t_dd_tritmp.h |
---|
0,0 → 1,740 |
/* $Id: t_dd_tritmp.h,v 1.1 2003-02-28 11:54:02 pj Exp $ */ |
/* |
* Mesa 3-D graphics library |
* Version: 3.5 |
* |
* 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> |
*/ |
/* Template for building functions to plug into the driver interface |
* of t_vb_render.c: |
* ctx->Driver.QuadFunc |
* ctx->Driver.TriangleFunc |
* ctx->Driver.LineFunc |
* ctx->Driver.PointsFunc |
* |
* DO_TWOSIDE: Plug back-color values from the VB into backfacing triangles, |
* and restore vertices afterwards. |
* DO_OFFSET: Calculate offset for triangles and adjust vertices. Restore |
* vertices after rendering. |
* DO_FLAT: For hardware without native flatshading, copy provoking colors |
* into the other vertices. Restore after rendering. |
* DO_UNFILLED: Decompose triangles to lines and points where appropriate. |
* |
* HAVE_RGBA: Vertices have rgba values (otherwise index values). |
* HAVE_SPEC: Vertices have secondary rgba values. |
* |
* VERT_X(v): Alias for vertex x value. |
* VERT_Y(v): Alias for vertex y value. |
* VERT_Z(v): Alias for vertex z value. |
* DEPTH_SCALE: Scale for offset. |
* |
* VERTEX: Hardware vertex type. |
* GET_VERTEX(n): Retreive vertex with index n. |
* AREA_IS_CCW(a): Return true if triangle with signed area a is ccw. |
* |
* VERT_SET_RGBA: Assign vertex rgba from VB color. |
* VERT_COPY_RGBA: Copy vertex rgba another vertex. |
* VERT_SAVE_RGBA: Save vertex rgba to a local variable. |
* VERT_RESTORE_RGBA: Restore vertex rgba from a local variable. |
* --> Similar for IND and SPEC. |
* |
* LOCAL_VARS(n): (At least) define local vars for save/restore rgba. |
* |
*/ |
#if HAVE_RGBA |
#define VERT_SET_IND( v, c ) (void) c |
#define VERT_COPY_IND( v0, v1 ) |
#define VERT_SAVE_IND( idx ) |
#define VERT_RESTORE_IND( idx ) |
#if HAVE_BACK_COLORS |
#define VERT_SET_RGBA( v, c ) |
#endif |
#else |
#define VERT_SET_RGBA( v, c ) (void) c |
#define VERT_COPY_RGBA( v0, v1 ) |
#define VERT_SAVE_RGBA( idx ) |
#define VERT_RESTORE_RGBA( idx ) |
#if HAVE_BACK_COLORS |
#define VERT_SET_IND( v, c ) |
#endif |
#endif |
#if !HAVE_SPEC |
#define VERT_SET_SPEC( v, c ) (void) c |
#define VERT_COPY_SPEC( v0, v1 ) |
#define VERT_SAVE_SPEC( idx ) |
#define VERT_RESTORE_SPEC( idx ) |
#if HAVE_BACK_COLORS |
#define VERT_COPY_SPEC1( v ) |
#endif |
#else |
#if HAVE_BACK_COLORS |
#define VERT_SET_SPEC( v, c ) |
#endif |
#endif |
#if !HAVE_BACK_COLORS |
#define VERT_COPY_SPEC1( v ) |
#define VERT_COPY_IND1( v ) |
#define VERT_COPY_RGBA1( v ) |
#endif |
#ifndef INSANE_VERTICES |
#define VERT_SET_Z(v,val) VERT_Z(v) = val |
#define VERT_Z_ADD(v,val) VERT_Z(v) += val |
#endif |
#if DO_TRI |
static void TAG(triangle)( GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 ) |
{ |
struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb; |
VERTEX *v[3]; |
GLfloat offset; |
GLfloat z[3]; |
GLenum mode = GL_FILL; |
GLuint facing; |
LOCAL_VARS(3); |
/* fprintf(stderr, "%s\n", __FUNCTION__); */ |
v[0] = (VERTEX *)GET_VERTEX(e0); |
v[1] = (VERTEX *)GET_VERTEX(e1); |
v[2] = (VERTEX *)GET_VERTEX(e2); |
if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED) |
{ |
GLfloat ex = VERT_X(v[0]) - VERT_X(v[2]); |
GLfloat ey = VERT_Y(v[0]) - VERT_Y(v[2]); |
GLfloat fx = VERT_X(v[1]) - VERT_X(v[2]); |
GLfloat fy = VERT_Y(v[1]) - VERT_Y(v[2]); |
GLfloat cc = ex*fy - ey*fx; |
if (DO_TWOSIDE || DO_UNFILLED) |
{ |
facing = AREA_IS_CCW( cc ) ^ ctx->Polygon._FrontBit; |
if (DO_UNFILLED) { |
if (facing) { |
mode = ctx->Polygon.BackMode; |
if (ctx->Polygon.CullFlag && |
ctx->Polygon.CullFaceMode != GL_FRONT) { |
return; |
} |
} else { |
mode = ctx->Polygon.FrontMode; |
if (ctx->Polygon.CullFlag && |
ctx->Polygon.CullFaceMode != GL_BACK) { |
return; |
} |
} |
} |
if (DO_TWOSIDE && facing == 1) |
{ |
if (HAVE_RGBA) { |
if (HAVE_BACK_COLORS) { |
if (!DO_FLAT) { |
VERT_SAVE_RGBA( 0 ); |
VERT_SAVE_RGBA( 1 ); |
VERT_COPY_RGBA1( v[0] ); |
VERT_COPY_RGBA1( v[1] ); |
} |
VERT_SAVE_RGBA( 2 ); |
VERT_COPY_RGBA1( v[2] ); |
if (HAVE_SPEC) { |
if (!DO_FLAT) { |
VERT_SAVE_SPEC( 0 ); |
VERT_SAVE_SPEC( 1 ); |
VERT_COPY_SPEC1( v[0] ); |
VERT_COPY_SPEC1( v[1] ); |
} |
VERT_SAVE_SPEC( 2 ); |
VERT_COPY_SPEC1( v[2] ); |
} |
} |
else { |
GLchan (*vbcolor)[4] = VB->ColorPtr[1]->Ptr; |
ASSERT(VB->ColorPtr[1]->Type == CHAN_TYPE); |
ASSERT(VB->ColorPtr[1]->StrideB == 4*sizeof(GLchan)); |
(void) vbcolor; |
if (!DO_FLAT) { |
VERT_SAVE_RGBA( 0 ); |
VERT_SAVE_RGBA( 1 ); |
VERT_SET_RGBA( v[0], vbcolor[e0] ); |
VERT_SET_RGBA( v[1], vbcolor[e1] ); |
} |
VERT_SAVE_RGBA( 2 ); |
VERT_SET_RGBA( v[2], vbcolor[e2] ); |
if (HAVE_SPEC && VB->SecondaryColorPtr[1]) { |
GLchan (*vbspec)[4] = VB->SecondaryColorPtr[1]->Ptr; |
if (!DO_FLAT) { |
VERT_SAVE_SPEC( 0 ); |
VERT_SAVE_SPEC( 1 ); |
VERT_SET_SPEC( v[0], vbspec[e0] ); |
VERT_SET_SPEC( v[1], vbspec[e1] ); |
} |
VERT_SAVE_SPEC( 2 ); |
VERT_SET_SPEC( v[2], vbspec[e2] ); |
} |
} |
} |
else { |
GLuint *vbindex = VB->IndexPtr[1]->data; |
if (!DO_FLAT) { |
VERT_SET_IND( v[0], vbindex[e0] ); |
VERT_SET_IND( v[1], vbindex[e1] ); |
} |
VERT_SET_IND( v[2], vbindex[e2] ); |
} |
} |
} |
if (DO_OFFSET) |
{ |
offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE; |
z[0] = VERT_Z(v[0]); |
z[1] = VERT_Z(v[1]); |
z[2] = VERT_Z(v[2]); |
if (cc * cc > 1e-16) { |
GLfloat ic = 1.0 / cc; |
GLfloat ez = z[0] - z[2]; |
GLfloat fz = z[1] - z[2]; |
GLfloat a = ey*fz - ez*fy; |
GLfloat b = ez*fx - ex*fz; |
GLfloat ac = a * ic; |
GLfloat bc = b * ic; |
if ( ac < 0.0f ) ac = -ac; |
if ( bc < 0.0f ) bc = -bc; |
offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor; |
} |
offset *= ctx->MRD; |
} |
} |
if (DO_FLAT) { |
if (HAVE_RGBA) { |
VERT_SAVE_RGBA( 0 ); |
VERT_SAVE_RGBA( 1 ); |
VERT_COPY_RGBA( v[0], v[2] ); |
VERT_COPY_RGBA( v[1], v[2] ); |
if (HAVE_SPEC && VB->SecondaryColorPtr[0]) { |
VERT_SAVE_SPEC( 0 ); |
VERT_SAVE_SPEC( 1 ); |
VERT_COPY_SPEC( v[0], v[2] ); |
VERT_COPY_SPEC( v[1], v[2] ); |
} |
} |
else { |
VERT_SAVE_IND( 0 ); |
VERT_SAVE_IND( 1 ); |
VERT_COPY_IND( v[0], v[2] ); |
VERT_COPY_IND( v[1], v[2] ); |
} |
} |
if (mode == GL_POINT) { |
if (DO_OFFSET && ctx->Polygon.OffsetPoint) { |
VERT_Z_ADD(v[0], offset); |
VERT_Z_ADD(v[1], offset); |
VERT_Z_ADD(v[2], offset); |
} |
UNFILLED_TRI( ctx, GL_POINT, e0, e1, e2 ); |
} else if (mode == GL_LINE) { |
if (DO_OFFSET && ctx->Polygon.OffsetLine) { |
VERT_Z_ADD(v[0], offset); |
VERT_Z_ADD(v[1], offset); |
VERT_Z_ADD(v[2], offset); |
} |
UNFILLED_TRI( ctx, GL_LINE, e0, e1, e2 ); |
} else { |
if (DO_OFFSET && ctx->Polygon.OffsetFill) { |
VERT_Z_ADD(v[0], offset); |
VERT_Z_ADD(v[1], offset); |
VERT_Z_ADD(v[2], offset); |
} |
if (DO_UNFILLED) |
RASTERIZE( GL_TRIANGLES ); |
TRI( v[0], v[1], v[2] ); |
} |
if (DO_OFFSET) |
{ |
VERT_SET_Z(v[0], z[0]); |
VERT_SET_Z(v[1], z[1]); |
VERT_SET_Z(v[2], z[2]); |
} |
if (DO_TWOSIDE && facing == 1) |
{ |
if (HAVE_RGBA) { |
if (!DO_FLAT) { |
VERT_RESTORE_RGBA( 0 ); |
VERT_RESTORE_RGBA( 1 ); |
} |
VERT_RESTORE_RGBA( 2 ); |
if (HAVE_SPEC) { |
if (!DO_FLAT) { |
VERT_RESTORE_SPEC( 0 ); |
VERT_RESTORE_SPEC( 1 ); |
} |
VERT_RESTORE_SPEC( 2 ); |
} |
} |
else { |
GLuint *vbindex = VB->IndexPtr[0]->data; |
if (!DO_FLAT) { |
VERT_SET_IND( v[0], vbindex[e0] ); |
VERT_SET_IND( v[1], vbindex[e1] ); |
} |
VERT_SET_IND( v[2], vbindex[e2] ); |
} |
} |
if (DO_FLAT) { |
if (HAVE_RGBA) { |
VERT_RESTORE_RGBA( 0 ); |
VERT_RESTORE_RGBA( 1 ); |
if (HAVE_SPEC && VB->SecondaryColorPtr[0]) { |
VERT_RESTORE_SPEC( 0 ); |
VERT_RESTORE_SPEC( 1 ); |
} |
} |
else { |
VERT_RESTORE_IND( 0 ); |
VERT_RESTORE_IND( 1 ); |
} |
} |
} |
#endif |
#if DO_QUAD |
#if DO_FULL_QUAD |
static void TAG(quad)( GLcontext *ctx, |
GLuint e0, GLuint e1, GLuint e2, GLuint e3 ) |
{ |
struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb; |
VERTEX *v[4]; |
GLfloat offset; |
GLfloat z[4]; |
GLenum mode = GL_FILL; |
GLuint facing; |
LOCAL_VARS(4); |
v[0] = (VERTEX *)GET_VERTEX(e0); |
v[1] = (VERTEX *)GET_VERTEX(e1); |
v[2] = (VERTEX *)GET_VERTEX(e2); |
v[3] = (VERTEX *)GET_VERTEX(e3); |
if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED) |
{ |
GLfloat ex = VERT_X(v[2]) - VERT_X(v[0]); |
GLfloat ey = VERT_Y(v[2]) - VERT_Y(v[0]); |
GLfloat fx = VERT_X(v[3]) - VERT_X(v[1]); |
GLfloat fy = VERT_Y(v[3]) - VERT_Y(v[1]); |
GLfloat cc = ex*fy - ey*fx; |
if (DO_TWOSIDE || DO_UNFILLED) |
{ |
facing = AREA_IS_CCW( cc ) ^ ctx->Polygon._FrontBit; |
if (DO_UNFILLED) { |
if (facing) { |
mode = ctx->Polygon.BackMode; |
if (ctx->Polygon.CullFlag && |
ctx->Polygon.CullFaceMode != GL_FRONT) { |
return; |
} |
} else { |
mode = ctx->Polygon.FrontMode; |
if (ctx->Polygon.CullFlag && |
ctx->Polygon.CullFaceMode != GL_BACK) { |
return; |
} |
} |
} |
if (DO_TWOSIDE && facing == 1) |
{ |
if (HAVE_RGBA) { |
GLchan (*vbcolor)[4] = VB->ColorPtr[1]->Ptr; |
(void)vbcolor; |
if (HAVE_BACK_COLORS) { |
if (!DO_FLAT) { |
VERT_SAVE_RGBA( 0 ); |
VERT_SAVE_RGBA( 1 ); |
VERT_SAVE_RGBA( 2 ); |
VERT_COPY_RGBA1( v[0] ); |
VERT_COPY_RGBA1( v[1] ); |
VERT_COPY_RGBA1( v[2] ); |
} |
VERT_SAVE_RGBA( 3 ); |
VERT_COPY_RGBA1( v[3] ); |
if (HAVE_SPEC) { |
if (!DO_FLAT) { |
VERT_SAVE_SPEC( 0 ); |
VERT_SAVE_SPEC( 1 ); |
VERT_SAVE_SPEC( 2 ); |
VERT_COPY_SPEC1( v[0] ); |
VERT_COPY_SPEC1( v[1] ); |
VERT_COPY_SPEC1( v[2] ); |
} |
VERT_SAVE_SPEC( 3 ); |
VERT_COPY_SPEC1( v[3] ); |
} |
} |
else { |
if (!DO_FLAT) { |
VERT_SAVE_RGBA( 0 ); |
VERT_SAVE_RGBA( 1 ); |
VERT_SAVE_RGBA( 2 ); |
VERT_SET_RGBA( v[0], vbcolor[e0] ); |
VERT_SET_RGBA( v[1], vbcolor[e1] ); |
VERT_SET_RGBA( v[2], vbcolor[e2] ); |
} |
VERT_SAVE_RGBA( 3 ); |
VERT_SET_RGBA( v[3], vbcolor[e3] ); |
if (HAVE_SPEC && VB->SecondaryColorPtr[1]) { |
GLchan (*vbspec)[4] = VB->SecondaryColorPtr[1]->Ptr; |
ASSERT(VB->SecondaryColorPtr[1]->StrideB==4*sizeof(GLchan)); |
if (!DO_FLAT) { |
VERT_SAVE_SPEC( 0 ); |
VERT_SAVE_SPEC( 1 ); |
VERT_SAVE_SPEC( 2 ); |
VERT_SET_SPEC( v[0], vbspec[e0] ); |
VERT_SET_SPEC( v[1], vbspec[e1] ); |
VERT_SET_SPEC( v[2], vbspec[e2] ); |
} |
VERT_SAVE_SPEC( 3 ); |
VERT_SET_SPEC( v[3], vbspec[e3] ); |
} |
} |
} |
else { |
GLuint *vbindex = VB->IndexPtr[1]->data; |
if (!DO_FLAT) { |
VERT_SET_IND( v[0], vbindex[e0] ); |
VERT_SET_IND( v[1], vbindex[e1] ); |
VERT_SET_IND( v[2], vbindex[e2] ); |
} |
VERT_SET_IND( v[3], vbindex[e3] ); |
} |
} |
} |
if (DO_OFFSET) |
{ |
offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE; |
z[0] = VERT_Z(v[0]); |
z[1] = VERT_Z(v[1]); |
z[2] = VERT_Z(v[2]); |
z[3] = VERT_Z(v[3]); |
if (cc * cc > 1e-16) { |
GLfloat ez = z[2] - z[0]; |
GLfloat fz = z[3] - z[1]; |
GLfloat a = ey*fz - ez*fy; |
GLfloat b = ez*fx - ex*fz; |
GLfloat ic = 1.0 / cc; |
GLfloat ac = a * ic; |
GLfloat bc = b * ic; |
if ( ac < 0.0f ) ac = -ac; |
if ( bc < 0.0f ) bc = -bc; |
offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor; |
} |
offset *= ctx->MRD; |
} |
} |
if (DO_FLAT) { |
if (HAVE_RGBA) { |
VERT_SAVE_RGBA( 0 ); |
VERT_SAVE_RGBA( 1 ); |
VERT_SAVE_RGBA( 2 ); |
VERT_COPY_RGBA( v[0], v[3] ); |
VERT_COPY_RGBA( v[1], v[3] ); |
VERT_COPY_RGBA( v[2], v[3] ); |
if (HAVE_SPEC && VB->SecondaryColorPtr[0]) { |
VERT_SAVE_SPEC( 0 ); |
VERT_SAVE_SPEC( 1 ); |
VERT_SAVE_SPEC( 2 ); |
VERT_COPY_SPEC( v[0], v[3] ); |
VERT_COPY_SPEC( v[1], v[3] ); |
VERT_COPY_SPEC( v[2], v[3] ); |
} |
} |
else { |
VERT_SAVE_IND( 0 ); |
VERT_SAVE_IND( 1 ); |
VERT_SAVE_IND( 2 ); |
VERT_COPY_IND( v[0], v[3] ); |
VERT_COPY_IND( v[1], v[3] ); |
VERT_COPY_IND( v[2], v[3] ); |
} |
} |
if (mode == GL_POINT) { |
if (( DO_OFFSET) && ctx->Polygon.OffsetPoint) { |
VERT_Z_ADD(v[0], offset); |
VERT_Z_ADD(v[1], offset); |
VERT_Z_ADD(v[2], offset); |
VERT_Z_ADD(v[3], offset); |
} |
UNFILLED_QUAD( ctx, GL_POINT, e0, e1, e2, e3 ); |
} else if (mode == GL_LINE) { |
if (DO_OFFSET && ctx->Polygon.OffsetLine) { |
VERT_Z_ADD(v[0], offset); |
VERT_Z_ADD(v[1], offset); |
VERT_Z_ADD(v[2], offset); |
VERT_Z_ADD(v[3], offset); |
} |
UNFILLED_QUAD( ctx, GL_LINE, e0, e1, e2, e3 ); |
} else { |
if (DO_OFFSET && ctx->Polygon.OffsetFill) { |
VERT_Z_ADD(v[0], offset); |
VERT_Z_ADD(v[1], offset); |
VERT_Z_ADD(v[2], offset); |
VERT_Z_ADD(v[3], offset); |
} |
RASTERIZE( GL_TRIANGLES ); |
QUAD( (v[0]), (v[1]), (v[2]), (v[3]) ); |
} |
if (DO_OFFSET) |
{ |
VERT_SET_Z(v[0], z[0]); |
VERT_SET_Z(v[1], z[1]); |
VERT_SET_Z(v[2], z[2]); |
VERT_SET_Z(v[3], z[3]); |
} |
if (DO_TWOSIDE && facing == 1) |
{ |
if (HAVE_RGBA) { |
if (!DO_FLAT) { |
VERT_RESTORE_RGBA( 0 ); |
VERT_RESTORE_RGBA( 1 ); |
VERT_RESTORE_RGBA( 2 ); |
} |
VERT_RESTORE_RGBA( 3 ); |
if (HAVE_SPEC) { |
if (!DO_FLAT) { |
VERT_RESTORE_SPEC( 0 ); |
VERT_RESTORE_SPEC( 1 ); |
VERT_RESTORE_SPEC( 2 ); |
} |
VERT_RESTORE_SPEC( 3 ); |
} |
} |
else { |
GLuint *vbindex = VB->IndexPtr[0]->data; |
if (!DO_FLAT) { |
VERT_SET_IND( v[0], vbindex[e0] ); |
VERT_SET_IND( v[1], vbindex[e1] ); |
VERT_SET_IND( v[2], vbindex[e2] ); |
} |
VERT_SET_IND( v[3], vbindex[e3] ); |
} |
} |
if (DO_FLAT) { |
if (HAVE_RGBA) { |
VERT_RESTORE_RGBA( 0 ); |
VERT_RESTORE_RGBA( 1 ); |
VERT_RESTORE_RGBA( 2 ); |
if (HAVE_SPEC && VB->SecondaryColorPtr[0]) { |
VERT_RESTORE_SPEC( 0 ); |
VERT_RESTORE_SPEC( 1 ); |
VERT_RESTORE_SPEC( 2 ); |
} |
} |
else { |
VERT_RESTORE_IND( 0 ); |
VERT_RESTORE_IND( 1 ); |
VERT_RESTORE_IND( 2 ); |
} |
} |
} |
#else |
static void TAG(quad)( GLcontext *ctx, GLuint e0, |
GLuint e1, GLuint e2, GLuint e3 ) |
{ |
if (DO_UNFILLED) { |
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; |
GLubyte ef1 = VB->EdgeFlag[e1]; |
GLubyte ef3 = VB->EdgeFlag[e3]; |
VB->EdgeFlag[e1] = 0; |
TAG(triangle)( ctx, e0, e1, e3 ); |
VB->EdgeFlag[e1] = ef1; |
VB->EdgeFlag[e3] = 0; |
TAG(triangle)( ctx, e1, e2, e3 ); |
VB->EdgeFlag[e3] = ef3; |
} else { |
TAG(triangle)( ctx, e0, e1, e3 ); |
TAG(triangle)( ctx, e1, e2, e3 ); |
} |
} |
#endif |
#endif |
#if DO_LINE |
static void TAG(line)( GLcontext *ctx, GLuint e0, GLuint e1 ) |
{ |
TNLvertexbuffer *VB = &TNL_CONTEXT(ctx)->vb; |
VERTEX *v[2]; |
LOCAL_VARS(2); |
v[0] = (VERTEX *)GET_VERTEX(e0); |
v[1] = (VERTEX *)GET_VERTEX(e1); |
if (DO_FLAT) { |
if (HAVE_RGBA) { |
VERT_SAVE_RGBA( 0 ); |
VERT_COPY_RGBA( v[0], v[1] ); |
if (HAVE_SPEC && VB->SecondaryColorPtr[0]) { |
VERT_SAVE_SPEC( 0 ); |
VERT_COPY_SPEC( v[0], v[1] ); |
} |
} |
else { |
VERT_SAVE_IND( 0 ); |
VERT_COPY_IND( v[0], v[1] ); |
} |
} |
LINE( v[0], v[1] ); |
if (DO_FLAT) { |
if (HAVE_RGBA) { |
VERT_RESTORE_RGBA( 0 ); |
if (HAVE_SPEC && VB->SecondaryColorPtr[0]) { |
VERT_RESTORE_SPEC( 0 ); |
} |
} |
else { |
VERT_RESTORE_IND( 0 ); |
} |
} |
} |
#endif |
#if DO_POINTS |
static void TAG(points)( GLcontext *ctx, GLuint first, GLuint last ) |
{ |
struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb; |
int i; |
LOCAL_VARS(1); |
if (VB->Elts == 0) { |
for ( i = first ; i < last ; i++ ) { |
if ( VB->ClipMask[i] == 0 ) { |
VERTEX *v = (VERTEX *)GET_VERTEX(i); |
POINT( v ); |
} |
} |
} else { |
for ( i = first ; i < last ; i++ ) { |
GLuint e = VB->Elts[i]; |
if ( VB->ClipMask[e] == 0 ) { |
VERTEX *v = (VERTEX *)GET_VERTEX(e); |
POINT( v ); |
} |
} |
} |
} |
#endif |
static void TAG(init)( void ) |
{ |
#if DO_QUAD |
TAB[IND].quad = TAG(quad); |
#endif |
#if DO_TRI |
TAB[IND].triangle = TAG(triangle); |
#endif |
#if DO_LINE |
TAB[IND].line = TAG(line); |
#endif |
#if DO_POINTS |
TAB[IND].points = TAG(points); |
#endif |
} |
#undef IND |
#undef TAG |
#if HAVE_RGBA |
#undef VERT_SET_IND |
#undef VERT_COPY_IND |
#undef VERT_SAVE_IND |
#undef VERT_RESTORE_IND |
#if HAVE_BACK_COLORS |
#undef VERT_SET_RGBA |
#endif |
#else |
#undef VERT_SET_RGBA |
#undef VERT_COPY_RGBA |
#undef VERT_SAVE_RGBA |
#undef VERT_RESTORE_RGBA |
#if HAVE_BACK_COLORS |
#undef VERT_SET_IND |
#endif |
#endif |
#if !HAVE_SPEC |
#undef VERT_SET_SPEC |
#undef VERT_COPY_SPEC |
#undef VERT_SAVE_SPEC |
#undef VERT_RESTORE_SPEC |
#if HAVE_BACK_COLORS |
#undef VERT_COPY_SPEC1 |
#endif |
#else |
#if HAVE_BACK_COLORS |
#undef VERT_SET_SPEC |
#endif |
#endif |
#if !HAVE_BACK_COLORS |
#undef VERT_COPY_SPEC1 |
#undef VERT_COPY_IND1 |
#undef VERT_COPY_RGBA1 |
#endif |
#ifndef INSANE_VERTICES |
#undef VERT_SET_Z |
#undef VERT_Z_ADD |
#endif |
/shark/trunk/ports/mesa/src/tnl_dd/t_dd_rendertmp.h |
---|
0,0 → 1,438 |
/* $Id: t_dd_rendertmp.h,v 1.1 2003-02-28 11:54:01 pj Exp $ */ |
/* |
* Mesa 3-D graphics library |
* Version: 3.5 |
* |
* 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> |
*/ |
#ifndef POSTFIX |
#define POSTFIX |
#endif |
#ifndef INIT |
#define INIT(x) |
#endif |
#ifndef NEED_EDGEFLAG_SETUP |
#define NEED_EDGEFLAG_SETUP 0 |
#define EDGEFLAG_GET(a) 0 |
#define EDGEFLAG_SET(a,b) (void)b |
#endif |
#ifndef RESET_STIPPLE |
#define RESET_STIPPLE |
#endif |
#ifndef RESET_OCCLUSION |
#define RESET_OCCLUSION |
#endif |
#ifndef TEST_PRIM_END |
#define TEST_PRIM_END(flags) (flags & PRIM_END) |
#define TEST_PRIM_BEGIN(flags) (flags & PRIM_BEGIN) |
#define TEST_PRIM_PARITY(flags) (flags & PRIM_PARITY) |
#endif |
#ifndef ELT |
#define ELT(x) x |
#endif |
#ifndef RENDER_TAB_QUALIFIER |
#define RENDER_TAB_QUALIFIER static |
#endif |
static void TAG(render_points)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
LOCAL_VARS; |
(void) flags; |
RESET_OCCLUSION; |
INIT(GL_POINTS); |
RENDER_POINTS( start, count ); |
POSTFIX; |
} |
static void TAG(render_lines)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
GLuint j; |
LOCAL_VARS; |
(void) flags; |
RESET_OCCLUSION; |
INIT(GL_LINES); |
for (j=start+1; j<count; j+=2 ) { |
RENDER_LINE( ELT(j-1), ELT(j) ); |
RESET_STIPPLE; |
} |
POSTFIX; |
} |
static void TAG(render_line_strip)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
GLuint j; |
LOCAL_VARS; |
(void) flags; |
RESET_OCCLUSION; |
INIT(GL_LINE_STRIP); |
for (j=start+1; j<count; j++ ) |
RENDER_LINE( ELT(j-1), ELT(j) ); |
if (TEST_PRIM_END(flags)) |
RESET_STIPPLE; |
POSTFIX; |
} |
static void TAG(render_line_loop)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
GLuint i; |
LOCAL_VARS; |
(void) flags; |
RESET_OCCLUSION; |
INIT(GL_LINE_LOOP); |
if (start+1 < count) { |
if (TEST_PRIM_BEGIN(flags)) { |
RENDER_LINE( ELT(start), ELT(start+1) ); |
} |
for ( i = start+2 ; i < count ; i++) { |
RENDER_LINE( ELT(i-1), ELT(i) ); |
} |
if ( TEST_PRIM_END(flags)) { |
RENDER_LINE( ELT(count-1), ELT(start) ); |
RESET_STIPPLE; |
} |
} |
POSTFIX; |
} |
static void TAG(render_triangles)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
GLuint j; |
LOCAL_VARS; |
(void) flags; |
INIT(GL_TRIANGLES); |
if (NEED_EDGEFLAG_SETUP) { |
for (j=start+2; j<count; j+=3) { |
/* Leave the edgeflags as supplied by the user. |
*/ |
RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) ); |
RESET_STIPPLE; |
} |
} else { |
for (j=start+2; j<count; j+=3) { |
RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) ); |
} |
} |
POSTFIX; |
} |
static void TAG(render_tri_strip)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
GLuint j; |
GLuint parity = 0; |
LOCAL_VARS; |
if (TEST_PRIM_PARITY(flags)) |
parity = 1; |
INIT(GL_TRIANGLE_STRIP); |
if (NEED_EDGEFLAG_SETUP) { |
for (j=start+2;j<count;j++,parity^=1) { |
GLuint ej2 = ELT(j-2+parity); |
GLuint ej1 = ELT(j-1-parity); |
GLuint ej = ELT(j); |
GLboolean ef2 = EDGEFLAG_GET( ej2 ); |
GLboolean ef1 = EDGEFLAG_GET( ej1 ); |
GLboolean ef = EDGEFLAG_GET( ej ); |
EDGEFLAG_SET( ej2, GL_TRUE ); |
EDGEFLAG_SET( ej1, GL_TRUE ); |
EDGEFLAG_SET( ej, GL_TRUE ); |
RENDER_TRI( ej2, ej1, ej ); |
EDGEFLAG_SET( ej2, ef2 ); |
EDGEFLAG_SET( ej1, ef1 ); |
EDGEFLAG_SET( ej, ef ); |
RESET_STIPPLE; |
} |
} else { |
for (j=start+2; j<count ; j++, parity^=1) { |
RENDER_TRI( ELT(j-2+parity), ELT(j-1-parity), ELT(j) ); |
} |
} |
POSTFIX; |
} |
static void TAG(render_tri_fan)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
GLuint j; |
LOCAL_VARS; |
(void) flags; |
INIT(GL_TRIANGLE_FAN); |
if (NEED_EDGEFLAG_SETUP) { |
for (j=start+2;j<count;j++) { |
/* For trifans, all edges are boundary. |
*/ |
GLuint ejs = ELT(start); |
GLuint ej1 = ELT(j-1); |
GLuint ej = ELT(j); |
GLboolean efs = EDGEFLAG_GET( ejs ); |
GLboolean ef1 = EDGEFLAG_GET( ej1 ); |
GLboolean ef = EDGEFLAG_GET( ej ); |
EDGEFLAG_SET( ejs, GL_TRUE ); |
EDGEFLAG_SET( ej1, GL_TRUE ); |
EDGEFLAG_SET( ej, GL_TRUE ); |
RENDER_TRI( ejs, ej1, ej); |
EDGEFLAG_SET( ejs, efs ); |
EDGEFLAG_SET( ej1, ef1 ); |
EDGEFLAG_SET( ej, ef ); |
RESET_STIPPLE; |
} |
} else { |
for (j=start+2;j<count;j++) { |
RENDER_TRI( ELT(start), ELT(j-1), ELT(j) ); |
} |
} |
POSTFIX; |
} |
static void TAG(render_poly)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
GLuint j = start+2; |
LOCAL_VARS; |
(void) flags; |
INIT(GL_POLYGON); |
if (NEED_EDGEFLAG_SETUP) { |
GLboolean efstart = EDGEFLAG_GET( ELT(start) ); |
GLboolean efcount = EDGEFLAG_GET( ELT(count-1) ); |
/* If the primitive does not begin here, the first edge |
* is non-boundary. |
*/ |
if (!TEST_PRIM_BEGIN(flags)) |
EDGEFLAG_SET( ELT(start), GL_FALSE ); |
/* If the primitive does not end here, the final edge is |
* non-boundary. |
*/ |
if (!TEST_PRIM_END(flags)) |
EDGEFLAG_SET( ELT(count-1), GL_FALSE ); |
/* Draw the first triangles (possibly zero) |
*/ |
if (j<count-1) { |
GLboolean ef = EDGEFLAG_GET( ELT(j) ); |
EDGEFLAG_SET( ELT(j), GL_FALSE ); |
RENDER_TRI( ELT(j-1), ELT(j), ELT(start) ); |
EDGEFLAG_SET( ELT(j), ef ); |
j++; |
/* Don't render the first edge again: |
*/ |
EDGEFLAG_SET( ELT(start), GL_FALSE ); |
for (;j<count-1;j++) { |
GLboolean efj = EDGEFLAG_GET( ELT(j) ); |
EDGEFLAG_SET( ELT(j), GL_FALSE ); |
RENDER_TRI( ELT(j-1), ELT(j), ELT(start) ); |
EDGEFLAG_SET( ELT(j), efj ); |
} |
} |
/* Draw the last or only triangle |
*/ |
if (j < count) |
RENDER_TRI( ELT(j-1), ELT(j), ELT(start) ); |
/* Restore the first and last edgeflags: |
*/ |
EDGEFLAG_SET( ELT(count-1), efcount ); |
EDGEFLAG_SET( ELT(start), efstart ); |
if (TEST_PRIM_END(flags)) { |
RESET_STIPPLE; |
} |
} |
else { |
for (j=start+2;j<count;j++) { |
RENDER_TRI( ELT(j-1), ELT(j), ELT(start) ); |
} |
} |
POSTFIX; |
} |
static void TAG(render_quads)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
GLuint j; |
LOCAL_VARS; |
(void) flags; |
INIT(GL_QUADS); |
if (NEED_EDGEFLAG_SETUP) { |
for (j=start+3; j<count; j+=4) { |
/* Use user-specified edgeflags for quads. |
*/ |
RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) ); |
RESET_STIPPLE; |
} |
} else { |
for (j=start+3; j<count; j+=4) { |
RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) ); |
} |
} |
POSTFIX; |
} |
static void TAG(render_quad_strip)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
GLuint j; |
LOCAL_VARS; |
(void) flags; |
INIT(GL_QUAD_STRIP); |
if (NEED_EDGEFLAG_SETUP) { |
for (j=start+3;j<count;j+=2) { |
/* All edges are boundary. Set edgeflags to 1, draw the |
* quad, and restore them to the original values. |
*/ |
GLboolean ef3 = EDGEFLAG_GET( ELT(j-3) ); |
GLboolean ef2 = EDGEFLAG_GET( ELT(j-2) ); |
GLboolean ef1 = EDGEFLAG_GET( ELT(j-1) ); |
GLboolean ef = EDGEFLAG_GET( ELT(j) ); |
EDGEFLAG_SET( ELT(j-3), GL_TRUE ); |
EDGEFLAG_SET( ELT(j-2), GL_TRUE ); |
EDGEFLAG_SET( ELT(j-1), GL_TRUE ); |
EDGEFLAG_SET( ELT(j), GL_TRUE ); |
RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) ); |
EDGEFLAG_SET( ELT(j-3), ef3 ); |
EDGEFLAG_SET( ELT(j-2), ef2 ); |
EDGEFLAG_SET( ELT(j-1), ef1 ); |
EDGEFLAG_SET( ELT(j), ef ); |
RESET_STIPPLE; |
} |
} else { |
for (j=start+3;j<count;j+=2) { |
RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) ); |
} |
} |
POSTFIX; |
} |
static void TAG(render_noop)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
(void)(ctx && start && count && flags); |
} |
RENDER_TAB_QUALIFIER void (*TAG(render_tab)[GL_POLYGON+2])(GLcontext *, |
GLuint, |
GLuint, |
GLuint) = |
{ |
TAG(render_points), |
TAG(render_lines), |
TAG(render_line_loop), |
TAG(render_line_strip), |
TAG(render_triangles), |
TAG(render_tri_strip), |
TAG(render_tri_fan), |
TAG(render_quads), |
TAG(render_quad_strip), |
TAG(render_poly), |
TAG(render_noop), |
}; |
#ifndef PRESERVE_VB_DEFS |
#undef RENDER_TRI |
#undef RENDER_QUAD |
#undef RENDER_LINE |
#undef RENDER_POINTS |
#undef LOCAL_VARS |
#undef INIT |
#undef POSTFIX |
#undef RESET_STIPPLE |
#undef DBG |
#undef ELT |
#undef RENDER_TAB_QUALIFIER |
#endif |
#ifndef PRESERVE_TAG |
#undef TAG |
#endif |
#undef PRESERVE_VB_DEFS |
#undef PRESERVE_TAG |
/shark/trunk/ports/mesa/src/tnl_dd/imm/t_dd_imm_tapi.h |
---|
0,0 → 1,76 |
/* $Id: t_dd_imm_tapi.h,v 1.1 2003-02-28 11:54:02 pj Exp $ */ |
/* |
* Mesa 3-D graphics library |
* Version: 3.5 |
* |
* 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: |
* Gareth Hughes <gareth@valinux.com> |
* Keith Whitwell <keith_whitwell@yahoo.com> |
*/ |
/* Template for immediate mode texture coordinate functions. |
*/ |
#ifndef DO_PROJ_TEX |
#error "Need to define DO_PROJ_TEX" |
#endif |
/* ============================================================= |
* Notify on calls to texture4f, to allow switch to projected texture |
* vertex format: |
*/ |
static void TAG(TexCoord4f)( GLfloat s, GLfloat t, GLfloat r, GLfloat q ) |
{ |
GET_CURRENT; |
DO_PROJ_TEX; |
TEXCOORD4( s, t, r, q ); |
} |
static void TAG(TexCoord4fv)( const GLfloat *v ) |
{ |
GET_CURRENT; |
DO_PROJ_TEX; |
TEXCOORD4( v[0], v[1], v[2], v[3] ); |
} |
static void TAG(MultiTexCoord4fARB)( GLenum target, GLfloat s, |
GLfloat t, GLfloat r, GLfloat q ) |
{ |
GET_CURRENT; |
DO_PROJ_TEX; |
MULTI_TEXCOORD4( unit, s, t, r, q ); |
} |
static void TAG(MultiTexCoord4fvARB)( GLenum target, const GLfloat *v ) |
{ |
GET_CURRENT; |
DO_PROJ_TEX; |
MULTI_TEXCOORD4( unit, v[0], v[1], v[2], v[3] ); |
} |
#undef DO_PROJ_TEX |
#undef TAG |
/shark/trunk/ports/mesa/src/tnl_dd/imm/t_dd_imm_vapi.h |
---|
0,0 → 1,160 |
/* $Id: t_dd_imm_vapi.h,v 1.1 2003-02-28 11:54:02 pj Exp $ */ |
/* |
* Mesa 3-D graphics library |
* Version: 3.5 |
* |
* 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: |
* Gareth Hughes <gareth@valinux.com> |
* Keith Whitwell <keithw@valinux.com> |
*/ |
/* Template for immediate mode vertex functions. |
*/ |
#define DBG 0 |
#define VERTEX( ox, oy, oz, ow ) |
do { |
GET_CURRENT_VERTEX; |
GLfloat w; |
GLuint mask; |
const GLfloat * const m = ctx->_ModelProjectMatrix.m; |
if (DO_FULL_MATRIX) { |
VERTEX_CLIP(0) = m[0] * ox + m[4] * oy + m[8] * oz + m[12] * ow; |
VERTEX_CLIP(1) = m[1] * ox + m[5] * oy + m[9] * oz + m[13] * ow; |
VERTEX_CLIP(2) = m[2] * ox + m[6] * oy + m[10] * oz + m[14] * ow; |
VERTEX_CLIP(3) = m[3] * ox + m[7] * oy + m[11] * oz + m[15] * ow; |
w = VERTEX_CLIP(3); |
} |
else if (DO_NOROT_MATRIX) { |
VERTEX_CLIP(0) = m[0] * ox + m[12] * ow; |
VERTEX_CLIP(1) = m[5] * oy + m[13] * ow; |
VERTEX_CLIP(2) = m[10] * oz + m[14] * ow; |
VERTEX_CLIP(3) = ow; |
w = ow; |
} |
else { |
ASSERT (DO_IDENTITY_MATRIX); |
VERTEX_CLIP(0) = ox; |
VERTEX_CLIP(1) = oy; |
VERTEX_CLIP(2) = oz; |
VERTEX_CLIP(3) = ow; |
w = ow; |
} |
mask = 0; |
if (DO_CLIP_TEST) { |
if ( VERTEX_CLIP(0) > w ) mask |= CLIP_RIGHT_BIT; |
if ( VERTEX_CLIP(0) < -w ) mask |= CLIP_LEFT_BIT; |
if ( VERTEX_CLIP(1) > w ) mask |= CLIP_TOP_BIT; |
if ( VERTEX_CLIP(1) < -w ) mask |= CLIP_BOTTOM_BIT; |
if ( VERTEX_CLIP(2) > w ) mask |= CLIP_FAR_BIT; |
if ( VERTEX_CLIP(2) < -w ) mask |= CLIP_NEAR_BIT; |
VERTEX_MASK(v) = mask; |
} |
if (!mask) { |
if (HAVE_VERTEX_WIN) { |
if (!HAVE_HW_VIEWPORT) { |
const GLfloat *s = GET_VIEWPORT_MATRIX(); |
if (HAVE_W && HAVE_HW_DIVIDE) { |
VERTEX_WIN( 0 ) = s[0] * VERTEX_CLIP( 0 ) + s[12]; |
VERTEX_WIN( 1 ) = s[5] * VERTEX_CLIP( 1 ) + s[13]; |
VERTEX_WIN( 2 ) = s[10] * VERTEX_CLIP( 2 ) + s[14]; |
VERTEX_WIN( 3 ) = w; |
} |
else { |
const GLfloat oow = 1.0/w; /* possibly opt away */ |
VERTEX_WIN( 0 ) = s[0] * VERTEX_CLIP( 0 ) * oow + s[12]; |
VERTEX_WIN( 1 ) = s[5] * VERTEX_CLIP( 1 ) * oow + s[13]; |
VERTEX_WIN( 2 ) = s[10] * VERTEX_CLIP( 2 ) * oow + s[14]; |
if (HAVE_W) |
VERTEX_WIN( 3 ) = oow; |
} |
} |
else if (HAVE_W && HAVE_HW_DIVIDE) { |
if (!VERTEX_WIN_IS_VERTEX_CLIP) { |
VERTEX_WIN( 0 ) = VERTEX_CLIP( 0 ); |
VERTEX_WIN( 1 ) = VERTEX_CLIP( 1 ); |
VERTEX_WIN( 2 ) = VERTEX_CLIP( 2 ); |
VERTEX_WIN( 3 ) = w; |
} |
} |
else { |
const GLfloat oow = 1.0/w; /* possibly opt away */ |
VERTEX_WIN( 0 ) = VERTEX_CLIP( 0 ) * oow; |
VERTEX_WIN( 1 ) = VERTEX_CLIP( 1 ) * oow; |
VERTEX_WIN( 2 ) = VERTEX_CLIP( 2 ) * oow; |
if (HAVE_W) |
VERTEX_WIN( 3 ) = oow; |
} |
} |
} else if (!FALLBACK_OR_CLIPPING) { |
SET_CLIPPING(); /* transition to clipping */ |
} |
COPY_VERTEX_FROM_CURRENT; |
BUILD_PRIM_FROM_VERTEX; |
} |
/* Let the compiler optimize away the constant operations: |
*/ |
static void VTAG(Vertex2f)( GLfloat ox, GLfloat oy ) |
{ |
/* Cliptest on clip[2] could also be eliminated... |
*/ |
VERTEX( ox, oy, 0, 1 ); |
} |
static void VTAG(Vertex2fv)( const GLfloat *obj ) |
{ |
/* Cliptest on clip[2] could also be eliminated... |
*/ |
VERTEX( obj[0], obj[1], 0, 1 ); |
} |
static void VTAG(Vertex3f)( GLfloat ox, GLfloat oy, GLfloat oz ) |
{ |
VERTEX( ox, oy, oz, 1 ); |
} |
static void VTAG(Vertex3fv)( const GLfloat *obj ) |
{ |
VERTEX( obj[0], obj[1], obj[2], 1 ); |
} |
static void VTAG(Vertex4f)( GLfloat ox, GLfloat oy, GLfloat oz, GLfloat ow ) |
{ |
VERTEX( ox, oy, oz, ow ); |
} |
static void VTAG(Vertex4fv)( const GLfloat *obj ) |
{ |
VERTEX( obj[0], obj[1], obj[2], obj[3] ); |
} |
#undef DO_FULL_MATRIX |
#undef VTAG |
#undef VERTEX |
/shark/trunk/ports/mesa/src/tnl_dd/imm/t_dd_imm_vb.c |
---|
0,0 → 1,205 |
/* $Id: t_dd_imm_vb.c,v 1.1 2003-02-28 11:54:02 pj Exp $ */ |
/* |
* Mesa 3-D graphics library |
* Version: 3.5 |
* |
* 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_whitwell@yahoo.com> |
*/ |
/* Template to build clipping routines to support t_dd_imm_primtmp.h. |
* |
* The TAG(draw_line) and TAG(draw_triangle) routines are called in |
* clipping and fallback scenarios, and when the native hardware |
* primitive (eg polygons) is unavailable. |
*/ |
#define CLIP_DOTPROD(K, A, B, C, D) \ |
(CLIP_X(K)*A + CLIP_Y(K)*B + \ |
CLIP_Z(K)*C + CLIP_W(K)*D) |
#define POLY_CLIP( PLANE, A, B, C, D ) \ |
do { \ |
if (mask & PLANE) { \ |
TNL_VERTEX **indata = inlist[in]; \ |
TNL_VERTEX **outdata = inlist[in ^= 1]; \ |
TNL_VERTEX *J = indata[0]; \ |
GLfloat dpJ = CLIP_DOTPROD(J, A, B, C, D ); \ |
GLuint outcount = 0; \ |
GLuint i; \ |
\ |
indata[n] = indata[0]; /* prevent rotation of vertices */ \ |
for (i = 1; i <= n; i++) { \ |
TNL_VERTEX *I = indata[i]; \ |
GLfloat dpI = CLIP_DOTPROD(idx, A, B, C, D ); \ |
\ |
if (!NEGATIVE(dpPrev)) { \ |
outdata[outcount++] = J; \ |
} \ |
\ |
if (DIFFERENT_SIGNS(dpI, dpJ)) { \ |
TNL_VERTEX *O = verts++; \ |
outdata[outcount++] = O; \ |
if (NEGATIVE(dpI)) { \ |
/* Going out of bounds. Avoid division by zero as we \ |
* know dp != dpPrev from DIFFERENT_SIGNS, above. \ |
*/ \ |
GLfloat t = dpI / (dpI - dpJ); \ |
INTERP( ctx, t, O, I, J ); \ |
} else { \ |
/* Coming back in. \ |
*/ \ |
GLfloat t = dpJ / (dpJ - dpI); \ |
INTERP( ctx, t, O, J, I ); \ |
} \ |
} \ |
\ |
J = I; \ |
dpJ = dpI; \ |
} \ |
\ |
if (outcount < 3) \ |
return; \ |
\ |
nr = outcount; \ |
} \ |
} while (0) |
#define LINE_CLIP(PLANE, A, B, C, D ) \ |
do { \ |
if (mask & PLANE) { \ |
GLfloat dpI = CLIP_DOTPROD( I, A, B, C, D ); \ |
GLfloat dpJ = CLIP_DOTPROD( J, A, B, C, D ); \ |
\ |
if (DIFFERENT_SIGNS(dpI, dpJ)) { \ |
TNL_VERTEX *O = verts++; \ |
if (NEGATIVE(dpJ)) { \ |
GLfloat t = dpI / (dpI - dpJ); \ |
INTERP( ctx, t, O, I, J ); \ |
J = O; \ |
} else { \ |
GLfloat t = dpJ / (dpJ - dpI); \ |
INTERP( ctx, t, O, J, I ); \ |
I = O; \ |
} \ |
} \ |
else if (NEGATIVE(dpI)) \ |
return; \ |
} \ |
} while (0) |
/* Clip a line against the viewport and user clip planes. |
*/ |
static void TAG(clip_draw_line)( GLcontext *ctx, |
TNL_VERTEX *I, |
TNL_VERTEX *J, |
GLuint mask ) |
{ |
LOCAL_VARS; |
GET_INTERP_FUNC; |
TNL_VERTEX tmp[MAX_CLIPPED_VERTICES]; |
TNL_VERTEX *verts = tmp; |
TNL_VERTEX *pv = J; |
LINE_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 ); |
LINE_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 ); |
LINE_CLIP( CLIP_TOP_BIT, 0, -1, 0, 1 ); |
LINE_CLIP( CLIP_BOTTOM_BIT, 0, 1, 0, 1 ); |
LINE_CLIP( CLIP_FAR_BIT, 0, 0, -1, 1 ); |
LINE_CLIP( CLIP_NEAR_BIT, 0, 0, 1, 1 ); |
if ((ctx->_TriangleCaps & DD_FLATSHADE) && J != pv) |
COPY_PV( ctx, J, pv ); |
DRAW_LINE( I, J ); |
} |
/* Clip a triangle against the viewport and user clip planes. |
*/ |
static void TAG(clip_draw_triangle)( GLcontext *ctx, |
TNL_VERTEX *v0, |
TNL_VERTEX *v1, |
TNL_VERTEX *v2, |
GLuint mask ) |
{ |
LOCAL_VARS; |
GET_INTERP_FUNC; |
TNL_VERTEX tmp[MAX_CLIPPED_VERTICES]; |
TNL_VERTEX *verts = tmp; |
TNL_VERTEX *(inlist[2][MAX_CLIPPED_VERTICES]); |
TNL_VERTEX **out; |
GLuint in = 0; |
GLuint n = 3; |
GLuint i; |
ASSIGN_3V(inlist, v2, v0, v1 ); /* pv rotated to slot zero */ |
POLY_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 ); |
POLY_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 ); |
POLY_CLIP( CLIP_TOP_BIT, 0, -1, 0, 1 ); |
POLY_CLIP( CLIP_BOTTOM_BIT, 0, 1, 0, 1 ); |
POLY_CLIP( CLIP_FAR_BIT, 0, 0, -1, 1 ); |
POLY_CLIP( CLIP_NEAR_BIT, 0, 0, 1, 1 ); |
if ((ctx->_TriangleCaps & DD_FLATSHADE) && v2 != inlist[0]) |
COPY_PV( ctx, inlist[0], v2 ); |
out = inlist[in]; |
DRAW_POLYGON( out, n ); |
} |
static __inline void TAG(draw_triangle)( GLcontext *ctx, |
TNL_VERTEX *v0, |
TNL_VERTEX *v1, |
TNL_VERTEX *v2 ) |
{ |
LOCAL_VARS; |
GLubyte ormask = (v0->mask | v1->mask | v2->mask); |
if ( !ormask ) { |
DRAW_TRI( v0, v1, v2 ); |
} else if ( !(v0->mask & v1->mask & v2->mask) ) { |
TAG(clip_draw_triangle)( ctx, v0, v1, v2, ormask ); |
} |
} |
static __inline void TAG(draw_line)( GLcontext *ctx, |
TNL_VERTEX *v0, |
TNL_VERTEX *v1 ) |
{ |
LOCAL_VARS; |
GLubyte ormask = (v0->mask | v1->mask); |
if ( !ormask ) { |
DRAW_LINE( v0, v1 ); |
} else if ( !(v0->mask & v1->mask) ) { |
TAG(clip_draw_line)( ctx, v0, v1, ormask ); |
} |
} |
/shark/trunk/ports/mesa/src/tnl_dd/imm/NOTES.imm |
---|
0,0 → 1,112 |
NOTE: |
These files are incomplete. They do not yet form a working |
implementation of hte concepts discused below. |
OVERVIEW |
The t_dd_imm_* files form a set of templates to produce driver - |
specific software tnl modules for a small subset of transformation and |
lighting states. |
The approach is quite different to the large vertex buffers of the |
src/tnl module, and is based around a cache of four recent vertices |
and a 'current' vertex which is updated directly from the Color, |
Normal, Texcoord, SecondaryColor and Fog entrypoints. |
The current vertex is actually a composite of the ctx->Current values |
and a partial hardware vertex maintained where the hardware values |
differ from those in ctx->Current. For example, clamped color values |
are kept in the hardware vertex, while texcoords remain in |
ctx->Current. |
A crude diagram: |
+--------------+ +-------------------+ |
| ctx->Current | | Current-HW-vertex | |
+--------------+ +-------------------+ |
\ / |
\ / |
\ / |
\ / |
--------- -------- |
| | |
v v |
+--------+ +--------+ +--------+ +--------+ |
| vert-0 | | vert-1 | | vert-2 | | vert-3 | |
+--------+ +--------+ +--------+ +--------+ |
| |
| |
v |
DMA |
Here values from ctx->Current and current-HW-vertex are merged to |
build vert-2, which is then dumped to hardware (DMA). A state machine |
determines which vertex is built in turn, and how the vertices are |
used to present primitives to hardware. These actions all occur |
during a call to Vertex{234}f{v}. |
Each vert-n includes clip coordinates and a clipmask in addition to |
the hardware (window) coordinates. This information allows clipping |
to take place directly on these vertices, if need be. |
t_dd_imm_capi.h |
Color{34}{fub}{v}() implementations. These update both |
ctx->Current (unclamped float colors) and current-HW-vertex |
with hardware-specific color values (typically unsigned |
bytes). |
When lighting is enabled, the functions from src/api_noop.c |
should be used, which just update ctx->Current. (The |
current-hw-vertex colors are produced from lighting, which is |
keyed to Normal3f). |
t_dd_imm_vb.c |
Support functions for clipping and fallback. See |
t_dd_imm_primtmp.h. |
t_dd_imm_napi.c |
t_dd_imm_napi.h |
Versions of Normal3f{v} to perform lighting with one or more |
infinite lights. Updates ctx->Current.Normal and the current |
HW colors. |
When lighting is disabled, use the functions from api_noop.c |
instead. |
t_dd_imm_primtmp.h |
State machine to control emission of vertices and primitives |
to hardware. Called indirectly from Vertex{234}f{v}. Capable |
of supporting hardware strip and fan primitives, and of |
decomposing to discreet primitives for clipping or fallback, |
or where the native primitive is unavailable. |
t_dd_imm_tapi.h |
Implementations of TexCoord{v} and MultiTexCoord4f{v}ARB to |
fire a callback when transitioning to projective texture. |
Most drivers will need to change vertex format at this point, |
some may need to enable a software rasterization fallback. |
t_dd_imm_vapi.h |
Implementations of Vertex{234}f{v}. These perform |
transformation and cliptesting on their arguments, then jump |
into the state machine implemented in primtmp.h. |
t_dd_imm_vertex.h |
Support functions for building and clip-interpolating hardware |
vertices. Called from primtmp.h. |
Keith Whitwell, June 2001. |
/shark/trunk/ports/mesa/src/tnl_dd/imm/t_dd_imm_napi.h |
---|
0,0 → 1,227 |
/* $Id: t_dd_imm_napi.h,v 1.1 2003-02-28 11:54:02 pj Exp $ */ |
/* |
* Mesa 3-D graphics library |
* Version: 3.5 |
* |
* 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: |
* Gareth Hughes <gareth@valinux.com> |
* Keith Whitwell <keith_whitwell@yahoo.com> |
*/ |
/* Template for immediate mode normal functions. Optimize for infinite |
* lights when doing software lighting. |
*/ |
static void TAG(Normal3f_single)( GLfloat x, GLfloat y, GLfloat z ) |
{ |
GET_CURRENT_VERTEX; |
const struct gl_light *light = ctx->Light.EnabledList.prev; |
GLfloat n_dot_h, n_dot_VP, spec, sum[3]; |
GLfloat *normal = ctx->Current.Normal; |
GLfloat scale = 1.0; |
ASSIGN_3V( normal, x, y, z ); |
COPY_3V( sum, BASE_COLOR ); |
if ( IND & NORM_RESCALE ) { |
scale = ctx->_ModelViewInvScale; |
} else if ( IND & NORM_NORMALIZE ) { |
scale = LEN_3FV( normal ); |
if ( scale != 0.0 ) scale = 1.0 / scale; |
} |
n_dot_VP = DOT3( normal, light->_VP_inf_norm ) * scale; |
if ( n_dot_VP > 0.0F ) { |
ACC_SCALE_SCALAR_3V( sum, n_dot_VP, light->_MatDiffuse[0] ); |
n_dot_h = DOT3( normal, light->_h_inf_norm ) * scale; |
if ( n_dot_h > 0.0F ) { |
GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec ); |
ACC_SCALE_SCALAR_3V( sum, spec, light->_MatSpecular[0] ); |
} |
} |
#ifdef LIT_COLOR_IS_FLOAT |
LIT_COLOR ( RCOMP ) = CLAMP(sum[0], 0.0f, 0.1f); |
LIT_COLOR ( GCOMP ) = CLAMP(sum[1], 0.0f, 0.1f); |
LIT_COLOR ( BCOMP ) = CLAMP(sum[2], 0.0f, 0.1f); |
#else |
UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( RCOMP ), sum[0] ); |
UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( GCOMP ), sum[1] ); |
UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( BCOMP ), sum[2] ); |
#endif |
LIT_COLOR( ACOMP ) = LIT_ALPHA; |
} |
static void TAG(Normal3fv_single)( const GLfloat *normal ) |
{ |
GET_CURRENT_VERTEX; |
const struct gl_light *light = ctx->Light.EnabledList.prev; |
GLfloat n_dot_h, n_dot_VP, spec, sum[3]; |
GLfloat scale = 1.0; |
COPY_3V( ctx->Current.Normal, normal ); |
COPY_3V( sum, BASE_COLOR ); |
if ( IND & NORM_RESCALE ) { |
scale = ctx->_ModelViewInvScale; |
} else if ( IND & NORM_NORMALIZE ) { |
scale = LEN_3FV( normal ); |
if ( scale != 0.0 ) scale = 1.0 / scale; |
} |
n_dot_VP = DOT3( normal, light->_VP_inf_norm ) * scale; |
if ( n_dot_VP > 0.0F ) { |
ACC_SCALE_SCALAR_3V( sum, n_dot_VP, light->_MatDiffuse[0] ); |
n_dot_h = DOT3( normal, light->_h_inf_norm ) * scale; |
if ( n_dot_h > 0.0F ) { |
GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec ); |
ACC_SCALE_SCALAR_3V( sum, spec, light->_MatSpecular[0] ); |
} |
} |
#ifdef LIT_COLOR_IS_FLOAT |
LIT_COLOR ( RCOMP ) = CLAMP(sum[0], 0.0f, 0.1f); |
LIT_COLOR ( GCOMP ) = CLAMP(sum[1], 0.0f, 0.1f); |
LIT_COLOR ( BCOMP ) = CLAMP(sum[2], 0.0f, 0.1f); |
#else |
UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( RCOMP ), sum[0] ); |
UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( GCOMP ), sum[1] ); |
UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( BCOMP ), sum[2] ); |
#endif |
LIT_COLOR( ACOMP ) = LIT_ALPHA; |
} |
static void TAG(Normal3f_multi)( GLfloat x, GLfloat y, GLfloat z ) |
{ |
GET_CURRENT_VERTEX; |
struct gl_light *light; |
GLfloat n_dot_h, n_dot_VP, spec, sum[3], tmp[3]; |
GLfloat *normal; |
ASSIGN_3V( ctx->Current.Normal, x, y, z ); |
COPY_3V( sum, BASE_COLOR ); |
if ( IND & NORM_RESCALE ) { |
normal = tmp; |
ASSIGN_3V( normal, x, y, z ); |
SELF_SCALE_SCALAR_3V( normal, ctx->_ModelViewInvScale ); |
} else if ( IND & NORM_NORMALIZE ) { |
normal = tmp; |
ASSIGN_3V( normal, x, y, z ); |
NORMALIZE_3FV( normal ); |
} else { |
normal = ctx->Current.Normal; |
} |
foreach ( light, &ctx->Light.EnabledList ) { |
n_dot_VP = DOT3( normal, light->_VP_inf_norm ); |
if ( n_dot_VP > 0.0F ) { |
ACC_SCALE_SCALAR_3V( sum, n_dot_VP, light->_MatDiffuse[0] ); |
n_dot_h = DOT3( normal, light->_h_inf_norm ); |
if ( n_dot_h > 0.0F ) { |
GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec ); |
ACC_SCALE_SCALAR_3V( sum, spec, light->_MatSpecular[0] ); |
} |
} |
} |
#ifdef LIT_COLOR_IS_FLOAT |
LIT_COLOR ( RCOMP ) = CLAMP(sum[0], 0.0f, 0.1f); |
LIT_COLOR ( GCOMP ) = CLAMP(sum[1], 0.0f, 0.1f); |
LIT_COLOR ( BCOMP ) = CLAMP(sum[2], 0.0f, 0.1f); |
#else |
UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( RCOMP ), sum[0] ); |
UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( GCOMP ), sum[1] ); |
UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( BCOMP ), sum[2] ); |
#endif |
LIT_COLOR( ACOMP ) = LIT_ALPHA; |
} |
static void TAG(Normal3fv_multi)( const GLfloat *n ) |
{ |
GET_CURRENT_VERTEX; |
struct gl_light *light; |
GLfloat n_dot_h, n_dot_VP, spec, sum[3], tmp[3]; |
GLfloat *normal; |
COPY_3V( ctx->Current.Normal, n ); |
COPY_3V( sum, BASE_COLOR ); |
if ( IND & NORM_RESCALE ) { |
normal = tmp; |
COPY_3V( normal, n ); |
SELF_SCALE_SCALAR_3V( normal, ctx->_ModelViewInvScale ); |
} else if ( IND & NORM_NORMALIZE ) { |
normal = tmp; |
COPY_3V( normal, n ); |
NORMALIZE_3FV( normal ); |
} else { |
normal = ctx->Current.Normal; |
} |
foreach ( light, &ctx->Light.EnabledList ) { |
n_dot_VP = DOT3( normal, light->_VP_inf_norm ); |
if ( n_dot_VP > 0.0F ) { |
ACC_SCALE_SCALAR_3V( sum, n_dot_VP, light->_MatDiffuse[0] ); |
n_dot_h = DOT3( normal, light->_h_inf_norm ); |
if ( n_dot_h > 0.0F ) { |
GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec ); |
ACC_SCALE_SCALAR_3V( sum, spec, light->_MatSpecular[0] ); |
} |
} |
} |
#ifdef LIT_COLOR_IS_FLOAT |
LIT_COLOR ( RCOMP ) = CLAMP(sum[0], 0.0f, 0.1f); |
LIT_COLOR ( GCOMP ) = CLAMP(sum[1], 0.0f, 0.1f); |
LIT_COLOR ( BCOMP ) = CLAMP(sum[2], 0.0f, 0.1f); |
#else |
UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( RCOMP ), sum[0] ); |
UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( GCOMP ), sum[1] ); |
UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( BCOMP ), sum[2] ); |
#endif |
LIT_COLOR( ACOMP ) = LIT_ALPHA; |
} |
static void TAG(init_norm)( void ) |
{ |
norm_tab[IND].normal3f_single = TAG(Normal3f_single); |
norm_tab[IND].normal3fv_single = TAG(Normal3fv_single); |
norm_tab[IND].normal3f_multi = TAG(Normal3f_multi); |
norm_tab[IND].normal3fv_multi = TAG(Normal3fv_multi); |
} |
#ifndef PRESERVE_NORMAL_DEFS |
#undef GET_CURRENT |
#undef GET_CURRENT_VERTEX |
#undef LIT_COLOR |
#undef LIT_COLOR_IS_FLOAT |
#endif |
#undef PRESERVE_NORMAL_DEFS |
#undef IND |
#undef TAG |
/shark/trunk/ports/mesa/src/tnl_dd/imm/t_dd_imm_vbtmp.h |
---|
0,0 → 1,269 |
/* $Id: t_dd_imm_vbtmp.h,v 1.1 2003-02-28 11:54:02 pj Exp $ */ |
/* |
* Mesa 3-D graphics library |
* Version: 3.5 |
* |
* 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_whitwell@yahoo.com> |
*/ |
/* Template to build support for t_dd_imm_* tnl module using vertices |
* as defined in t_dd_vertex.h. |
* |
* See t_dd_vbtmp.h for definitions of arguments to this file. |
* Unfortunately it seems necessary to duplicate a lot of that code. |
*/ |
#ifndef LOCALVARS |
#define LOCALVARS |
#endif |
/* COPY_VERTEX_FROM_CURRENT in t_dd_imm_vapi.c |
*/ |
static void TAG(emit_vfmt)( GLcontext *ctx, VERTEX *v ) |
{ |
LOCALVARS |
; |
/* This template assumes (like t_dd_vbtmp.h) that color is ubyte. |
*/ |
if (DO_TEX0 || DO_TEX1 || !HAVE_TINY_VERTICES) |
{ |
const GLubyte *col = GET_HARDWARE_COLOR(); |
if (HAVE_RGBA_COLOR) { |
v->v.ui[4] = *(GLuint *)&col; |
} else { |
v->v.color.blue = col[2]; |
v->v.color.green = col[1]; |
v->v.color.red = col[0]; |
v->v.color.alpha = col[3]; |
} |
} |
else { |
if (HAVE_RGBA_COLOR) { |
v->v.ui[3] = *(GLuint *)col; |
} |
else { |
v->tv.color.blue = col[2]; |
v->tv.color.green = col[1]; |
v->tv.color.red = col[0]; |
v->tv.color.alpha = col[3]; |
} |
} |
if (DO_TEX0) { |
GLfloat *tc = ctx->Current.Texture[0]; |
v->v.u0 = tc[0]; |
v->v.v0 = tc[1]; |
if (DO_PTEX) { |
if (HAVE_PTEX_VERTICES) { |
v->pv.q0 = tc[3]; |
} |
else { |
float rhw = 1.0 / tc[3]; |
v->v.w *= tc[3]; |
v->v.u0 *= rhw; |
v->v.v0 *= rhw; |
} |
} |
} |
if (DO_TEX1) { |
GLfloat *tc = ctx->Current.Texture[1]; |
if (DO_PTEX) { |
v->pv.u1 = tc[0]; |
v->pv.v1 = tc[1]; |
v->pv.q1 = tc[3]; |
} |
else { |
v->v.u1 = tc[0]; |
v->v.v1 = tc[1]; |
} |
} |
else if (DO_PTEX) { |
*(GLuint *)&v->pv.q1 = 0; /* avoid culling on radeon */ |
} |
if (DO_TEX2) { |
GLfloat *tc = ctx->Current.Texture[2]; |
if (DO_PTEX) { |
v->pv.u2 = tc[0]; |
v->pv.v2 = tc[1]; |
v->pv.q2 = tc[3]; |
} |
else { |
v->v.u2 = tc[0]; |
v->v.v2 = tc[1]; |
} |
} |
if (DO_TEX3) { |
GLfloat *tc = ctx->Current.Texture[3]; |
if (DO_PTEX) { |
v->pv.u3 = tc[0]; |
v->pv.v3 = tc[1]; |
v->pv.q3 = tc[3]; |
} |
else { |
v->v.u3 = tc[0]; |
v->v.v3 = tc[1]; |
} |
} |
} |
static void TAG(interp)( GLcontext *ctx, |
GLfloat t, |
TNL_VERTEX *dst, |
TNL_VERTEX *in, |
TNL_VERTEX *out ) |
{ |
LOCALVARS |
const GLfloat *s = GET_VIEWPORT_MAT(); |
GLfloat w; |
(void)s; |
if (HAVE_HW_DIVIDE) { |
VIEWPORT_X( dst->v.v.x, dst->clip[0] ); |
VIEWPORT_Y( dst->v.v.y, dst->clip[1] ); |
VIEWPORT_Z( dst->v.v.z, dst->clip[2] ); |
w = dstclip[3]; |
} |
else { |
w = 1.0 / dst->clip[3]; |
VIEWPORT_X( dst->v.v.x, dst->clip[0] * w ); |
VIEWPORT_Y( dst->v.v.y, dst->clip[1] * w ); |
VIEWPORT_Z( dst->v.v.z, dst->clip[2] * w ); |
} |
if (HAVE_HW_DIVIDE || DO_TEX0) { |
dst->v.v.w = w; |
INTERP_UB( t, dst->v.ub4[4][0], out->v.ub4[4][0], in->v.ub4[4][0] ); |
INTERP_UB( t, dst->v.ub4[4][1], out->v.ub4[4][1], in->v.ub4[4][1] ); |
INTERP_UB( t, dst->v.ub4[4][2], out->v.ub4[4][2], in->v.ub4[4][2] ); |
INTERP_UB( t, dst->v.ub4[4][3], out->v.ub4[4][3], in->v.ub4[4][3] ); |
if (DO_TEX0) { |
if (DO_PTEX) { |
if (HAVE_PTEX_VERTICES) { |
INTERP_F( t, dst->v.pv.u0, out->v.pv.u0, in->v.pv.u0 ); |
INTERP_F( t, dst->v.pv.v0, out->v.pv.v0, in->v.pv.v0 ); |
INTERP_F( t, dst->v.pv.q0, out->v.pv.q0, in->v.pv.q0 ); |
} else { |
GLfloat wout = out->clip[3]; /* projected clip */ |
GLfloat win = in->clip[3]; /* projected clip */ |
GLfloat qout = out->v.pv.w / wout; |
GLfloat qin = in->v.pv.w / win; |
GLfloat qdst, rqdst; |
ASSERT( !HAVE_HW_DIVIDE ); /* assert win, wout projected clip */ |
INTERP_F( t, dst->v.v.u0, out->v.v.u0 * qout, in->v.v.u0 * qin ); |
INTERP_F( t, dst->v.v.v0, out->v.v.v0 * qout, in->v.v.v0 * qin ); |
INTERP_F( t, qdst, qout, qin ); |
rqdst = 1.0 / qdst; |
dst->v.v.u0 *= rqdst; |
dst->v.v.v0 *= rqdst; |
dst->v.v.w *= rqdst; |
} |
} |
else { |
INTERP_F( t, dst->v.v.u0, out->v.v.u0, in->v.v.u0 ); |
INTERP_F( t, dst->v.v.v0, out->v.v.v0, in->v.v.v0 ); |
} |
} |
if (DO_TEX1) { |
if (DO_PTEX) { |
INTERP_F( t, dst->v.pv.u1, out->v.pv.u1, in->v.pv.u1 ); |
INTERP_F( t, dst->v.pv.v1, out->v.pv.v1, in->v.pv.v1 ); |
INTERP_F( t, dst->v.pv.q1, out->v.pv.q1, in->v.pv.q1 ); |
} else { |
INTERP_F( t, dst->v.v.u1, out->v.v.u1, in->v.v.u1 ); |
INTERP_F( t, dst->v.v.v1, out->v.v.v1, in->v.v.v1 ); |
} |
} |
else if (DO_PTEX) { |
dst->v.pv.q0 = 0.0; /* must be a valid float on radeon */ |
} |
if (DO_TEX2) { |
if (DO_PTEX) { |
INTERP_F( t, dst->v.pv.u2, out->v.pv.u2, in->v.pv.u2 ); |
INTERP_F( t, dst->v.pv.v2, out->v.pv.v2, in->v.pv.v2 ); |
INTERP_F( t, dst->v.pv.q2, out->v.pv.q2, in->v.pv.q2 ); |
} else { |
INTERP_F( t, dst->v.v.u2, out->v.v.u2, in->v.v.u2 ); |
INTERP_F( t, dst->v.v.v2, out->v.v.v2, in->v.v.v2 ); |
} |
} |
if (DO_TEX3) { |
if (DO_PTEX) { |
INTERP_F( t, dst->v.pv.u3, out->v.pv.u3, in->v.pv.u3 ); |
INTERP_F( t, dst->v.pv.v3, out->v.pv.v3, in->v.pv.v3 ); |
INTERP_F( t, dst->v.pv.q3, out->v.pv.q3, in->v.pv.q3 ); |
} else { |
INTERP_F( t, dst->v.v.u3, out->v.v.u3, in->v.v.u3 ); |
INTERP_F( t, dst->v.v.v3, out->v.v.v3, in->v.v.v3 ); |
} |
} |
} else { |
/* 4-dword vertex. Color is in v[3] and there is no oow coordinate. |
*/ |
INTERP_UB( t, dst->v.ub4[3][0], out->v.ub4[3][0], in->v.ub4[3][0] ); |
INTERP_UB( t, dst->v.ub4[3][1], out->v.ub4[3][1], in->v.ub4[3][1] ); |
INTERP_UB( t, dst->v.ub4[3][2], out->v.ub4[3][2], in->v.ub4[3][2] ); |
INTERP_UB( t, dst->v.ub4[3][3], out->v.ub4[3][3], in->v.ub4[3][3] ); |
} |
} |
static __inline void TAG(copy_pv)( GLcontext *ctx, |
TNL_VERTEX *dst, |
TNL_VERTEX *src ) |
{ |
if (DO_TEX0 || DO_TEX1 || !HAVE_TINY_VERTICES) { |
dst->v.v.ui[4] = src->v.v.ui[4]; |
} |
else { |
dst->v.v.ui[3] = src->v.v.ui[3]; |
} |
} |
static void TAG(init)( void ) |
{ |
setup_tab[IND].emit = TAG(emit_vfmt); |
setup_tab[IND].interp = TAG(interp_vfmt); |
} |
#undef IND |
#undef TAG |
/shark/trunk/ports/mesa/src/tnl_dd/imm/t_dd_imm_primtmp.h |
---|
0,0 → 1,571 |
/* $Id: t_dd_imm_primtmp.h,v 1.1 2003-02-28 11:54:02 pj Exp $ */ |
/* |
* Mesa 3-D graphics library |
* Version: 3.5 |
* |
* 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 <keithw@valinux.com> |
* Gareth Hughes <gareth@valinux.com> |
*/ |
/* Template for immediate mode vertices. |
* |
* Probably instantiate once for each vertex format used: |
* - TINY_VERTICES |
* - TEX0_VERTICES |
* - TEX1_VERTICES |
* - PTEX_VERTICES |
* |
* Have to handle TEX->PTEX transition somehow. |
*/ |
#define DBG 0 |
/* ============================================================= |
* GL_POINTS |
*/ |
static void TAG(flush_point_0)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
if ( !v0->mask ) { |
LOCAL_VARS; |
DRAW_POINT( v0 ); |
} |
} |
/* ============================================================= |
* GL_LINES |
*/ |
static void TAG(flush_line_1)( GLcontext *ctx, TNL_VERTEX *v0 ); |
static void TAG(flush_line_0)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
FLUSH_VERTEX = TAG(flush_line_1); |
ACTIVE_VERTEX = IMM_VERTICES( 1 ); |
} |
static void TAG(flush_line_1)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
TNL_VERTEX *v1 = v0 - 1; |
ACTIVE_VERTEX = IMM_VERTICES( 0 ); |
FLUSH_VERTEX = TAG(flush_line_0); |
if (FALLBACK_OR_CLIPPING) |
CLIP_OR_DRAW_LINE( ctx, v1, v0 ); |
else |
DRAW_LINE( ctx, v1, v0 ); |
} |
/* ============================================================= |
* GL_LINE_LOOP |
*/ |
static void TAG(flush_line_loop_2)( GLcontext *ctx, TNL_VERTEX *v0 ); |
static void TAG(flush_line_loop_1)( GLcontext *ctx, TNL_VERTEX *v0 ); |
static void TAG(flush_line_loop_0)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
ACTIVE_VERTEX = v0 + 1; |
FLUSH_VERTEX = TAG(flush_line_loop_1); |
} |
#define DRAW_LINELOOP_LINE( a, b ) \ |
if (!HAVE_LINE_STRIP || FALLBACK_OR_CLIPPING) { \ |
CLIP_OR_DRAW_LINE( ctx, a, b ); \ |
} else if (EXTEND_PRIM( 1 )) { \ |
EMIT_VERTEX( b ); \ |
} else { \ |
BEGIN_PRIM( GL_LINE_STRIP, 2 ); \ |
EMIT_VERTEX( a ); \ |
EMIT_VERTEX( b ); \ |
} |
static void TAG(flush_line_loop_1)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
TNL_VERTEX *v1 = v0 - 1; |
ACTIVE_VERTEX = v1; |
FLUSH_VERTEX = TAG(flush_line_loop_2); |
DRAW_LINELOOP_LINE( v1, v0 ); |
} |
static void TAG(flush_line_loop_2)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
TNL_VERTEX *v1 = v0 + 1; |
ACTIVE_VERTEX = v1; |
FLUSH_VERTEX = TAG(flush_line_loop_1); |
DRAW_LINELOOP_LINE( v1, v0 ); |
} |
static void TAG(end_line_loop)( GLcontext *ctx ) |
{ |
LOCAL_VARS; |
if ( FLUSH_VERTEX != TAG(flush_line_loop_0) ) { |
TNL_VERTEX *v1 = ACTIVE_VERTEX; |
TNL_VERTEX *v0 = IMM_VERTICES( 0 ); |
DRAW_LINELOOP_LINE( v1, v0 ); |
} |
} |
/* ============================================================= |
* GL_LINE_STRIP |
*/ |
static void TAG(flush_line_strip_2)( GLcontext *ctx, TNL_VERTEX *v0 ); |
static void TAG(flush_line_strip_1)( GLcontext *ctx, TNL_VERTEX *v0 ); |
static void TAG(flush_line_strip_0)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
ACTIVE_VERTEX = v0 + 1; |
FLUSH_VERTEX = TAG(flush_line_strip_0b); |
} |
static void TAG(flush_line_strip_1)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
TNL_VERTEX *v1 = v0 - 1; |
ACTIVE_VERTEX = v1; |
FLUSH_VERTEX = TAG(flush_line_strip_2); |
if (!HAVE_LINE_STRIP || FALLBACK_OR_CLIPPING) |
CLIP_OR_DRAW_LINE( ctx, v1, v0 ); |
else if (EXTEND_PRIM( 1 )) { |
EMIT_VERTEX( v0 ); |
} else { |
BEGIN_PRIM( GL_LINE_STRIP, 2 ); |
EMIT_VERTEX( v1 ); |
EMIT_VERTEX( v0 ); |
} |
} |
static void TAG(flush_line_strip_2)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
TNL_VERTEX *v1 = v0 + 1; |
ACTIVE_VERTEX = v1; |
FLUSH_VERTEX = TAG(flush_line_strip_1); |
if (!HAVE_LINE_STRIP || FALLBACK_OR_CLIPPING) |
CLIP_OR_DRAW_LINE( ctx, v1, v0 ); |
else if (EXTEND_PRIM( 1 )) { |
EMIT_VERTEX( v0 ); |
} else { |
BEGIN_PRIM( GL_LINE_STRIP, 2 ); |
EMIT_VERTEX( v1 ); |
EMIT_VERTEX( v0 ); |
} |
} |
/* ============================================================= |
* GL_TRIANGLES |
*/ |
static void TAG(flush_triangle_2)( GLcontext *ctx, TNL_VERTEX *v0 ); |
static void TAG(flush_triangle_1)( GLcontext *ctx, TNL_VERTEX *v0 ); |
static void TAG(flush_triangle_0)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
if ( DBG ) fprintf( stderr, __FUNCTION__ "\n" ); |
ACTIVE_VERTEX = v0 + 1; |
FLUSH_VERTEX = TAG(flush_triangle_1); |
BEGIN_PRIM( GL_TRIANGLES, 0 ); |
} |
static void TAG(flush_triangle_1)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
if ( DBG ) fprintf( stderr, __FUNCTION__ "\n" ); |
ACTIVE_VERTEX = v0 + 1; |
FLUSH_VERTEX = TAG(flush_triangle_2); |
} |
static void TAG(flush_triangle_2)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
TNL_VERTEX *v2 = v0 - 2; |
TNL_VERTEX *v1 = v0 - 1; |
if ( DBG ) fprintf( stderr, __FUNCTION__ "\n" ); |
ACTIVE_VERTEX = v2; |
FLUSH_VERTEX = TAG(flush_triangle_0); |
/* nothing gained by trying to emit as hw primitives -- that |
* happens normally in this case. |
*/ |
if (FALLBACK_OR_CLIPPING) |
CLIP_OR_DRAW_TRI( ctx, v2, v1, v0 ); |
else |
DRAW_TRI( ctx, v2, v1, v0 ); |
} |
/* ============================================================= |
* GL_TRIANGLE_STRIP |
*/ |
static void TAG(flush_tri_strip_3)( GLcontext *ctx, TNL_VERTEX *v0 ); |
static void TAG(flush_tri_strip_2)( GLcontext *ctx, TNL_VERTEX *v0 ); |
static void TAG(flush_tri_strip_1)( GLcontext *ctx, TNL_VERTEX *v0 ); |
static void TAG(flush_tri_strip_0)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
ACTIVE_VERTEX = IMM_VERTICES( 1 ); |
FLUSH_VERTEX = TAG(flush_tri_strip_1); |
} |
static void TAG(flush_tri_strip_1)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
ACTIVE_VERTEX = IMM_VERTICES( 2 ); |
FLUSH_VERTEX = TAG(flush_tri_strip_2); |
} |
#define DO_TRISTRIP_TRI( vert0, vert1 ) \ |
if (!HAVE_TRI_STRIP || FALLBACK_OR_CLIPPING) { \ |
TNL_VERTEX *v2 = IMM_VERTICES( vert0 ); \ |
TNL_VERTEX *v1 = IMM_VERTICES( vert1 ); \ |
TAG(draw_tri)( ctx, v2, v1, v0 ); \ |
} else if (EXTEND_PRIM( 1 )) { \ |
EMIT_VERTEX( v0 ); \ |
} else { \ |
TNL_VERTEX *v2 = IMM_VERTICES( vert0 ); \ |
TNL_VERTEX *v1 = IMM_VERTICES( vert1 ); \ |
BEGIN_PRIM( GL_TRIANGLE_STRIP, 3 ); \ |
EMIT_VERTEX( v2 ); \ |
EMIT_VERTEX( v1 ); \ |
EMIT_VERTEX( v0 ); \ |
} |
static void TAG(flush_tri_strip_2)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
FLUSH_VERTEX = TAG(flush_tri_strip_3); |
ACTIVE_VERTEX = IMM_VERTICES( 3 ); |
DO_TRISTRIP_TRI( 0, 1 ); |
} |
static void TAG(flush_tri_strip_3)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
FLUSH_VERTEX = TAG(flush_tri_strip_4); |
ACTIVE_VERTEX = IMM_VERTICES( 0 ); |
DO_TRISTRIP_TRI( 1, 2 ); |
} |
static void TAG(flush_tri_strip_4)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
FLUSH_VERTEX = TAG(flush_tri_strip_5); |
ACTIVE_VERTEX = IMM_VERTICES( 1 ); |
DO_TRISTRIP_TRI( 2, 3 ); |
} |
static void TAG(flush_tri_strip_5)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
FLUSH_VERTEX = TAG(flush_tri_strip_2); |
ACTIVE_VERTEX = IMM_VERTICES( 2 ); |
DO_TRISTRIP_TRI( 0, 3 ); |
} |
/* ============================================================= |
* GL_TRIANGLE_FAN |
*/ |
static void TAG(flush_tri_fan_2)( GLcontext *ctx, TNL_VERTEX *v0 ); |
static void TAG(flush_tri_fan_1)( GLcontext *ctx, TNL_VERTEX *v0 ); |
static void TAG(flush_tri_fan_0)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
ACTIVE_VERTEX = v0 + 1; |
FLUSH_VERTEX = TAG(flush_tri_fan_1); |
} |
static void TAG(flush_tri_fan_1)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
ACTIVE_VERTEX = v0 + 1; |
FLUSH_VERTEX = TAG(flush_tri_fan_2); |
} |
#define DO_TRIFAN_TRI( vert0, vert1 ) \ |
if (!HAVE_TRI_FAN || FALLBACK_OR_CLIPPING) { \ |
TNL_VERTEX *v2 = IMM_VERTICES( vert0 ); \ |
TNL_VERTEX *v1 = IMM_VERTICES( vert1 ); \ |
TAG(draw_tri)( ctx, v2, v1, v0 ); \ |
} else if (EXTEND_PRIM( 1 )) { \ |
EMIT_VERTEX( v0 ); \ |
} else { \ |
TNL_VERTEX *v2 = IMM_VERTICES( vert0 ); \ |
TNL_VERTEX *v1 = IMM_VERTICES( vert1 ); \ |
BEGIN_PRIM( GL_TRIANGLE_FAN, 3 ); \ |
EMIT_VERTEX( v2 ); \ |
EMIT_VERTEX( v1 ); \ |
EMIT_VERTEX( v0 ); \ |
} |
static void TAG(flush_tri_fan_2)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
ACTIVE_VERTEX = IMM_VERTICES( 1 ); |
FLUSH_VERTEX = TAG(flush_tri_fan_3 ); |
DO_TRIFAN_TRI( 0, 1 ); |
} |
static void TAG(flush_tri_fan_3)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
ACTIVE_VERTEX = IMM_VERTICES( 2 ); |
FLUSH_VERTEX = TAG(flush_tri_fan_2 ); |
DO_TRIFAN_TRI( 0, 2 ); |
} |
/* ============================================================= |
* GL_QUADS |
*/ |
static void TAG(flush_quad_3)( GLcontext *ctx, TNL_VERTEX *v0 ); |
static void TAG(flush_quad_2)( GLcontext *ctx, TNL_VERTEX *v0 ); |
static void TAG(flush_quad_1)( GLcontext *ctx, TNL_VERTEX *v0 ); |
static void TAG(flush_quad_0)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
IMM_VERTEX( v0 ) = v0 + 1; |
FLUSH_VERTEX = TAG(flush_quad_1); |
} |
static void TAG(flush_quad_1)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
IMM_VERTEX( v0 ) = v0 + 1; |
FLUSH_VERTEX = TAG(flush_quad_2); |
} |
static void TAG(flush_quad_2)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
IMM_VERTEX( v0 ) = v0 + 1; |
FLUSH_VERTEX = TAG(flush_quad_3); |
} |
static void TAG(flush_quad_3)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
TNL_VERTEX *v3 = v0 - 3; |
TNL_VERTEX *v2 = v0 - 2; |
TNL_VERTEX *v1 = v0 - 1; |
IMM_VERTEX( v0 ) = v3; |
FLUSH_VERTEX = TAG(flush_quad_0); |
if (!HAVE_HW_QUADS || FALLBACK_OR_CLIPPING) { |
CLIP_OR_DRAW_TRI( ctx, v3, v2, v0 ); |
CLIP_OR_DRAW_TRI( ctx, v2, v1, v0 ); |
} else { |
EXTEND_PRIM_NF( GL_QUADS, 4 ); |
EMIT_VERTEX( v3 ); |
EMIT_VERTEX( v2 ); |
EMIT_VERTEX( v1 ); |
EMIT_VERTEX( v0 ); |
} |
} |
/* ============================================================= |
* GL_QUAD_STRIP |
*/ |
static void TAG(flush_quad_strip_3)( GLcontext *ctx, TNL_VERTEX *v0 ); |
static void TAG(flush_quad_strip_2)( GLcontext *ctx, TNL_VERTEX *v0 ); |
static void TAG(flush_quad_strip_1)( GLcontext *ctx, TNL_VERTEX *v0 ); |
static void TAG(flush_quad_strip_0)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
IMM_VERTEX( v3 ) = v0; |
IMM_VERTEX( v0 ) = v0 + 1; |
FLUSH_VERTEX = TAG(flush_quad_strip_1); |
} |
static void TAG(flush_quad_strip_1)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
IMM_VERTEX( v2 ) = v0; |
IMM_VERTEX( v0 ) = v0 + 1; |
FLUSH_VERTEX = TAG(flush_quad_strip_2); |
} |
static void TAG(flush_quad_strip_2)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
IMM_VERTEX( v1 ) = v0; |
IMM_VERTEX( v0 ) = v0 + 1; |
FLUSH_VERTEX = TAG(flush_quad_strip_3); |
} |
static void TAG(flush_quad_strip_3)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
TNL_VERTEX *v3 = IMM_VERTEX( v3 ); |
TNL_VERTEX *v2 = IMM_VERTEX( v2 ); |
TNL_VERTEX *v1 = IMM_VERTEX( v1 ); |
IMM_VERTEX( v0 ) = v3; |
IMM_VERTEX( v2 ) = v0; |
IMM_VERTEX( v3 ) = v1; |
FLUSH_VERTEX = TAG(flush_quad_strip_2); |
if (FALLBACK_OR_CLIPPING) { |
CLIP_OR_DRAW_TRI( ctx, v3, v2, v0 ); |
CLIP_OR_DRAW_TRI( ctx, v2, v1, v0 ); |
} else { |
DRAW_TRI( ctx, v3, v2, v0 ); |
DRAW_TRI( ctx, v2, v1, v0 ); |
} |
} |
/* ============================================================= |
* GL_POLYGON |
*/ |
static void TAG(flush_poly_2)( GLcontext *ctx, TNL_VERTEX *v0 ); |
static void TAG(flush_poly_1)( GLcontext *ctx, TNL_VERTEX *v0 ); |
static void TAG(flush_poly_0)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
ACTIVE_VERTEX = IMM_VERTICES( 1 ); |
FLUSH_VERTEX = TAG(flush_poly_1); |
} |
static void TAG(flush_poly_1)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
ACTIVE_VERTEX = IMM_VERTICES( 2 ); |
FLUSH_VERTEX = TAG(flush_poly_2); |
} |
#define DO_POLY_TRI( vert0, vert1 ) \ |
if (!HAVE_POLYGONS || FALLBACK_OR_CLIPPING) { \ |
TNL_VERTEX *v2 = IMM_VERTICES( vert0 ); \ |
TNL_VERTEX *v1 = IMM_VERTICES( vert1 ); \ |
TAG(draw_tri)( ctx, v1, v0, v2 ); \ |
} else if (EXTEND_PRIM( 1 )) { \ |
EMIT_VERTEX( v0 ); \ |
} else { \ |
TNL_VERTEX *v2 = IMM_VERTICES( vert0 ); \ |
TNL_VERTEX *v1 = IMM_VERTICES( vert1 ); \ |
BEGIN_PRIM( GL_POLYGON, 3 ); \ |
EMIT_VERTEX( v2 ); \ |
EMIT_VERTEX( v1 ); \ |
EMIT_VERTEX( v0 ); \ |
} |
static void TAG(flush_poly_2)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
ACTIVE_VERTEX = IMM_VERTICES( 1 ); |
FLUSH_VERTEX = TAG(flush_poly_3); |
DO_POLY_TRI( 0, 1 ); |
} |
static void TAG(flush_poly_3)( GLcontext *ctx, TNL_VERTEX *v0 ) |
{ |
LOCAL_VARS; |
ACTIVE_VERTEX = IMM_VERTICES( 2 ); |
FLUSH_VERTEX = TAG(flush_poly_2); |
DO_POLY_TRI( 0, 2 ); |
} |
void (*TAG(flush_tab)[GL_POLYGON+1])( GLcontext *, TNL_VERTEX * ) = |
{ |
TAG(flush_point), |
TAG(flush_line_0), |
TAG(flush_line_loop_0), |
TAG(flush_line_strip_0), |
TAG(flush_triangle_0), |
TAG(flush_tri_strip_0), |
TAG(flush_tri_fan_0), |
TAG(flush_quad_0), |
TAG(flush_quad_strip_0), |
TAG(flush_poly_0), |
}; |
#ifndef PRESERVE_PRIM_DEFS |
#undef LOCAL_VARS |
#undef GET_INTERP_FUNC |
#undef IMM_VERTEX |
#undef IMM_VERTICES |
#undef FLUSH_VERTEX |
#endif |
#undef PRESERVE_PRIM_DEFS |
#undef EXTEND_PRIM |
#undef EMIT_VERTEX |
#undef EMIT_VERTEX_TRI |
#undef EMIT_VERTEX_LINE |
#undef EMIT_VERTEX_POINT |
#undef TAG |
/shark/trunk/ports/mesa/src/tnl_dd/imm/t_dd_imm_capi.h |
---|
0,0 → 1,420 |
/* $Id: t_dd_imm_capi.h,v 1.1 2003-02-28 11:54:02 pj Exp $ */ |
/* |
* Mesa 3-D graphics library |
* Version: 3.5 |
* |
* 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: |
* Gareth Hughes <gareth@valinux.com> |
*/ |
/* Template for immediate mode color functions. |
* |
* FIXME: Floating-point color versions of these... |
*/ |
static void TAG(Color3f)( GLfloat r, GLfloat g, GLfloat b ) |
{ |
GET_CURRENT; |
#ifdef COLOR_IS_FLOAT |
CURRENT_COLOR( RCOMP ) = CLAMP(r, 0.0f, 1.0f); |
CURRENT_COLOR( GCOMP ) = CLAMP(g, 0.0f, 1.0f); |
CURRENT_COLOR( BCOMP ) = CLAMP(b, 0.0f, 1.0f); |
CURRENT_COLOR( ACOMP ) = 1.0f; |
#else |
UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( RCOMP ), r ); |
UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( GCOMP ), g ); |
UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( BCOMP ), b ); |
CURRENT_COLOR( ACOMP ) = 255; |
#endif |
} |
static void TAG(Color3fv)( const GLfloat *v ) |
{ |
GET_CURRENT; |
#ifdef COLOR_IS_FLOAT |
CURRENT_COLOR( RCOMP ) = CLAMP(v[0], 0.0f, 1.0f); |
CURRENT_COLOR( GCOMP ) = CLAMP(v[1], 0.0f, 1.0f); |
CURRENT_COLOR( BCOMP ) = CLAMP(v[2], 0.0f, 1.0f); |
CURRENT_COLOR( ACOMP ) = 1.0f; |
#else |
UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( RCOMP ), v[0] ); |
UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( GCOMP ), v[1] ); |
UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( BCOMP ), v[2] ); |
CURRENT_COLOR( ACOMP ) = 255; |
#endif |
} |
static void TAG(Color3ub)( GLubyte r, GLubyte g, GLubyte b ) |
{ |
GET_CURRENT; |
#ifdef COLOR_IS_FLOAT |
CURRENT_COLOR( RCOMP ) = UBYTE_TO_FLOAT( r ); |
CURRENT_COLOR( GCOMP ) = UBYTE_TO_FLOAT( g ); |
CURRENT_COLOR( BCOMP ) = UBYTE_TO_FLOAT( b ); |
CURRENT_COLOR( ACOMP ) = 1.0f; |
#else |
CURRENT_COLOR( RCOMP ) = r; |
CURRENT_COLOR( GCOMP ) = g; |
CURRENT_COLOR( BCOMP ) = b; |
CURRENT_COLOR( ACOMP ) = 255; |
#endif |
} |
static void TAG(Color3ubv)( const GLubyte *v ) |
{ |
GET_CURRENT; |
#ifdef COLOR_IS_FLOAT |
CURRENT_COLOR( RCOMP ) = UBYTE_TO_FLOAT( v[0] ); |
CURRENT_COLOR( GCOMP ) = UBYTE_TO_FLOAT( v[1] ); |
CURRENT_COLOR( BCOMP ) = UBYTE_TO_FLOAT( v[2] ); |
CURRENT_COLOR( ACOMP ) = 1.0f; |
#else |
CURRENT_COLOR( RCOMP ) = v[0]; |
CURRENT_COLOR( GCOMP ) = v[1]; |
CURRENT_COLOR( BCOMP ) = v[2]; |
CURRENT_COLOR( ACOMP ) = 255; |
#endif |
} |
static void TAG(Color4f)( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) |
{ |
GET_CURRENT; |
#ifdef COLOR_IS_FLOAT |
CURRENT_COLOR( RCOMP ) = CLAMP(r, 0.0f, 1.0f); |
CURRENT_COLOR( GCOMP ) = CLAMP(g, 0.0f, 1.0f); |
CURRENT_COLOR( BCOMP ) = CLAMP(b, 0.0f, 1.0f); |
CURRENT_COLOR( ACOMP ) = CLAMP(a, 0.0f, 1.0f); |
#else |
UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( RCOMP ), r ); |
UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( GCOMP ), g ); |
UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( BCOMP ), b ); |
UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( ACOMP ), a ); |
#endif |
} |
static void TAG(Color4fv)( const GLfloat *v ) |
{ |
GET_CURRENT; |
#ifdef COLOR_IS_FLOAT |
CURRENT_COLOR( RCOMP ) = CLAMP(v[0], 0.0f, 1.0f); |
CURRENT_COLOR( GCOMP ) = CLAMP(v[1], 0.0f, 1.0f); |
CURRENT_COLOR( BCOMP ) = CLAMP(v[2], 0.0f, 1.0f); |
CURRENT_COLOR( ACOMP ) = CLAMP(v[3], 0.0f, 1.0f); |
#else |
UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( RCOMP ), v[0] ); |
UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( GCOMP ), v[1] ); |
UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( BCOMP ), v[2] ); |
UNCLAMPED_FLOAT_TO_UBYTE( CURRENT_COLOR( ACOMP ), v[3] ); |
#endif |
} |
static void TAG(Color4ub)( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) |
{ |
GET_CURRENT; |
#ifdef COLOR_IS_FLOAT |
CURRENT_COLOR( RCOMP ) = UBYTE_TO_FLOAT( r ); |
CURRENT_COLOR( GCOMP ) = UBYTE_TO_FLOAT( g ); |
CURRENT_COLOR( BCOMP ) = UBYTE_TO_FLOAT( b ); |
CURRENT_COLOR( ACOMP ) = UBYTE_TO_FLOAT( a ); |
#else |
CURRENT_COLOR( RCOMP ) = r; |
CURRENT_COLOR( GCOMP ) = g; |
CURRENT_COLOR( BCOMP ) = b; |
CURRENT_COLOR( ACOMP ) = a; |
#endif |
} |
static void TAG(Color4ubv)( const GLubyte *v ) |
{ |
GET_CURRENT; |
#ifdef COLOR_IS_FLOAT |
CURRENT_COLOR( RCOMP ) = UBYTE_TO_FLOAT( v[0] ); |
CURRENT_COLOR( GCOMP ) = UBYTE_TO_FLOAT( v[1] ); |
CURRENT_COLOR( BCOMP ) = UBYTE_TO_FLOAT( v[2] ); |
CURRENT_COLOR( ACOMP ) = UBYTE_TO_FLOAT( v[3] ); |
#else |
CURRENT_COLOR( RCOMP ) = v[0]; |
CURRENT_COLOR( GCOMP ) = v[1]; |
CURRENT_COLOR( BCOMP ) = v[2]; |
CURRENT_COLOR( ACOMP ) = v[3]; |
#endif |
} |
static void TAG(ColorMaterial3f)( GLfloat r, GLfloat g, GLfloat b ) |
{ |
GET_CURRENT_CONTEXT(ctx); |
GLfloat *color = ctx->Current.Color; |
color[0] = r; |
color[1] = g; |
color[2] = b; |
color[3] = 1.0; |
_mesa_update_color_material( ctx, color ); |
RECALC_BASE_COLOR( ctx ); |
} |
static void TAG(ColorMaterial3fv)( const GLfloat *v ) |
{ |
GET_CURRENT_CONTEXT(ctx); |
GLfloat *color = ctx->Current.Color; |
color[0] = v[0]; |
color[1] = v[1]; |
color[2] = v[2]; |
color[3] = 1.0; |
_mesa_update_color_material( ctx, color ); |
RECALC_BASE_COLOR( ctx ); |
} |
static void TAG(ColorMaterial3ub)( GLubyte r, GLubyte g, GLubyte b ) |
{ |
GET_CURRENT_CONTEXT(ctx); |
GLfloat *color = ctx->Current.Color; |
color[0] = UBYTE_TO_FLOAT( r ); |
color[1] = UBYTE_TO_FLOAT( g ); |
color[2] = UBYTE_TO_FLOAT( b ); |
color[3] = 1.0; |
_mesa_update_color_material( ctx, color ); |
RECALC_BASE_COLOR( ctx ); |
} |
static void TAG(ColorMaterial3ubv)( const GLubyte *v ) |
{ |
GET_CURRENT_CONTEXT(ctx); |
GLfloat *color = ctx->Current.Color; |
color[0] = UBYTE_TO_FLOAT( v[0] ); |
color[1] = UBYTE_TO_FLOAT( v[1] ); |
color[2] = UBYTE_TO_FLOAT( v[2] ); |
color[3] = 1.0; |
_mesa_update_color_material( ctx, color ); |
RECALC_BASE_COLOR( ctx ); |
} |
static void TAG(ColorMaterial4f)( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) |
{ |
GET_CURRENT_CONTEXT(ctx); |
GLfloat *color = ctx->Current.Color; |
color[0] = r; |
color[1] = g; |
color[2] = b; |
color[3] = a; |
_mesa_update_color_material( ctx, color ); |
RECALC_BASE_COLOR( ctx ); |
} |
static void TAG(ColorMaterial4fv)( const GLfloat *v ) |
{ |
GET_CURRENT_CONTEXT(ctx); |
GLfloat *color = ctx->Current.Color; |
color[0] = v[0]; |
color[1] = v[1]; |
color[2] = v[2]; |
color[3] = v[3]; |
_mesa_update_color_material( ctx, color ); |
RECALC_BASE_COLOR( ctx ); |
} |
static void TAG(ColorMaterial4ub)( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) |
{ |
GET_CURRENT_CONTEXT(ctx); |
GLfloat *color = ctx->Current.Color; |
color[0] = UBYTE_TO_FLOAT( r ); |
color[1] = UBYTE_TO_FLOAT( g ); |
color[2] = UBYTE_TO_FLOAT( b ); |
color[3] = UBYTE_TO_FLOAT( a ); |
_mesa_update_color_material( ctx, color ); |
RECALC_BASE_COLOR( ctx ); |
} |
static void TAG(ColorMaterial4ubv)( const GLubyte *v ) |
{ |
GET_CURRENT_CONTEXT(ctx); |
GLfloat *color = ctx->Current.Color; |
color[0] = UBYTE_TO_FLOAT( v[0] ); |
color[1] = UBYTE_TO_FLOAT( v[1] ); |
color[2] = UBYTE_TO_FLOAT( v[2] ); |
color[3] = UBYTE_TO_FLOAT( v[3] ); |
_mesa_update_color_material( ctx, color ); |
RECALC_BASE_COLOR( ctx ); |
} |
/* ============================================================= |
* Color chooser functions: |
*/ |
static void TAG(choose_Color3f)( GLfloat r, GLfloat g, GLfloat b ) |
{ |
GET_CURRENT_CONTEXT(ctx); |
if ( ctx->Light.Enabled ) { |
if ( ctx->Light.ColorMaterialEnabled ) { |
ctx->Exec->Color3f = TAG(ColorMaterial3f); |
} else { |
ctx->Exec->Color3f = _mesa_noop_Color3f; |
} |
} else { |
ctx->Exec->Color3f = TAG(Color3f); |
} |
glColor3f( r, g, b ); |
} |
static void TAG(choose_Color3fv)( const GLfloat *v ) |
{ |
GET_CURRENT_CONTEXT(ctx); |
if ( ctx->Light.Enabled ) { |
if ( ctx->Light.ColorMaterialEnabled ) { |
ctx->Exec->Color3fv = TAG(ColorMaterial3fv); |
} else { |
ctx->Exec->Color3fv = _mesa_noop_Color3fv; |
} |
} else { |
ctx->Exec->Color3fv = TAG(Color3fv); |
} |
glColor3fv( v ); |
} |
static void TAG(choose_Color3ub)( GLubyte r, GLubyte g, GLubyte b ) |
{ |
GET_CURRENT_CONTEXT(ctx); |
if ( ctx->Light.Enabled ) { |
if ( ctx->Light.ColorMaterialEnabled ) { |
ctx->Exec->Color3ub = TAG(ColorMaterial3ub); |
} else { |
ctx->Exec->Color3ub = _mesa_noop_Color3ub; |
} |
} else { |
ctx->Exec->Color3ub = TAG(Color3ub); |
} |
glColor3ub( r, g, b ); |
} |
static void TAG(choose_Color3ubv)( const GLubyte *v ) |
{ |
GET_CURRENT_CONTEXT(ctx); |
if ( ctx->Light.Enabled ) { |
if ( ctx->Light.ColorMaterialEnabled ) { |
ctx->Exec->Color3ubv = TAG(ColorMaterial3ubv); |
} else { |
ctx->Exec->Color3ubv = _mesa_noop_Color3ubv; |
} |
} else { |
ctx->Exec->Color3ubv = TAG(Color3ubv); |
} |
glColor3ubv( v ); |
} |
static void TAG(choose_Color4f)( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) |
{ |
GET_CURRENT_CONTEXT(ctx); |
if ( ctx->Light.Enabled ) { |
if ( ctx->Light.ColorMaterialEnabled ) { |
ctx->Exec->Color4f = TAG(ColorMaterial4f); |
} else { |
ctx->Exec->Color4f = _mesa_noop_Color4f; |
} |
} else { |
ctx->Exec->Color4f = TAG(Color4f); |
} |
glColor4f( r, g, b, a ); |
} |
static void TAG(choose_Color4fv)( const GLfloat *v ) |
{ |
GET_CURRENT_CONTEXT(ctx); |
if ( ctx->Light.Enabled ) { |
if ( ctx->Light.ColorMaterialEnabled ) { |
ctx->Exec->Color4fv = TAG(ColorMaterial4fv); |
} else { |
ctx->Exec->Color4fv = _mesa_noop_Color4fv; |
} |
} else { |
ctx->Exec->Color4fv = TAG(Color4fv); |
} |
glColor4fv( v ); |
} |
static void TAG(choose_Color4ub)( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) |
{ |
GET_CURRENT_CONTEXT(ctx); |
if ( ctx->Light.Enabled ) { |
if ( ctx->Light.ColorMaterialEnabled ) { |
ctx->Exec->Color4ub = TAG(ColorMaterial4ub); |
} else { |
ctx->Exec->Color4ub = _mesa_noop_Color4ub; |
} |
} else { |
ctx->Exec->Color4ub = TAG(Color4ub); |
} |
glColor4ub( r, g, b, a ); |
} |
static void TAG(choose_Color4ubv)( const GLubyte *v ) |
{ |
GET_CURRENT_CONTEXT(ctx); |
if ( ctx->Light.Enabled ) { |
if ( ctx->Light.ColorMaterialEnabled ) { |
ctx->Exec->Color4ubv = TAG(ColorMaterial4ubv); |
} else { |
ctx->Exec->Color4ubv = _mesa_noop_Color4ubv; |
} |
} else { |
ctx->Exec->Color4ubv = TAG(Color4ubv); |
} |
glColor4ubv( v ); |
} |
#undef GET_CURRENT |
#undef CURRENT_COLOR |
#undef CURRENT_SPECULAR |
#undef COLOR_IS_FLOAT |
#undef RECALC_BASE_COLOR |
#undef TAG |
/shark/trunk/ports/mesa/src/tnl_dd/t_dd_vb.c |
---|
0,0 → 1,392 |
/* |
* Mesa 3-D graphics library |
* Version: 3.5 |
* |
* 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> |
*/ |
#include "math/m_translate.h" |
#if (HAVE_HW_VIEWPORT) |
#define UNVIEWPORT_VARS |
#define UNVIEWPORT_X(x) x |
#define UNVIEWPORT_Y(x) x |
#define UNVIEWPORT_Z(x) x |
#endif |
#ifndef LOCALVARS |
#define LOCALVARS |
#endif |
#ifndef CHECK_HW_DIVIDE |
#define CHECK_HW_DIVIDE 1 |
#endif |
/* These don't need to be duplicated, but there's currently nowhere |
* really convenient to put them. Need to build some actual .o files in |
* this directory? |
*/ |
static void copy_pv_rgba4_spec5( GLcontext *ctx, GLuint edst, GLuint esrc ) |
{ |
LOCALVARS |
GLubyte *verts = GET_VERTEX_STORE(); |
GLuint shift = GET_VERTEX_STRIDE_SHIFT(); |
GLuint *dst = (GLuint *)(verts + (edst << shift)); |
GLuint *src = (GLuint *)(verts + (esrc << shift)); |
dst[4] = src[4]; |
dst[5] = src[5]; |
} |
static void copy_pv_rgba4( GLcontext *ctx, GLuint edst, GLuint esrc ) |
{ |
LOCALVARS |
GLubyte *verts = GET_VERTEX_STORE(); |
GLuint shift = GET_VERTEX_STRIDE_SHIFT(); |
GLuint *dst = (GLuint *)(verts + (edst << shift)); |
GLuint *src = (GLuint *)(verts + (esrc << shift)); |
dst[4] = src[4]; |
} |
static void copy_pv_rgba3( GLcontext *ctx, GLuint edst, GLuint esrc ) |
{ |
LOCALVARS |
GLubyte *verts = GET_VERTEX_STORE(); |
GLuint shift = GET_VERTEX_STRIDE_SHIFT(); |
GLuint *dst = (GLuint *)(verts + (edst << shift)); |
GLuint *src = (GLuint *)(verts + (esrc << shift)); |
dst[3] = src[3]; |
} |
void TAG(translate_vertex)(GLcontext *ctx, |
const VERTEX *src, |
SWvertex *dst) |
{ |
LOCALVARS |
GLuint format = GET_VERTEX_FORMAT(); |
GLfloat *s = ctx->Viewport._WindowMap.m; |
UNVIEWPORT_VARS; |
if (format == TINY_VERTEX_FORMAT) { |
if (HAVE_HW_VIEWPORT) { |
dst->win[0] = s[0] * src->v.x + s[12]; |
dst->win[1] = s[5] * src->v.y + s[13]; |
dst->win[2] = s[10] * src->v.z + s[14]; |
dst->win[3] = 1.0; |
} else { |
dst->win[0] = UNVIEWPORT_X( src->v.x ); |
dst->win[1] = UNVIEWPORT_Y( src->v.y ); |
dst->win[2] = UNVIEWPORT_Z( src->v.z ); |
dst->win[3] = 1.0; |
} |
dst->color[0] = src->tv.color.red; |
dst->color[1] = src->tv.color.green; |
dst->color[2] = src->tv.color.blue; |
dst->color[3] = src->tv.color.alpha; |
} |
else { |
if (HAVE_HW_VIEWPORT) { |
if (HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) { |
GLfloat oow = 1.0 / src->v.w; |
dst->win[0] = s[0] * src->v.x * oow + s[12]; |
dst->win[1] = s[5] * src->v.y * oow + s[13]; |
dst->win[2] = s[10] * src->v.z * oow + s[14]; |
dst->win[3] = oow; |
} else { |
dst->win[0] = s[0] * src->v.x + s[12]; |
dst->win[1] = s[5] * src->v.y + s[13]; |
dst->win[2] = s[10] * src->v.z + s[14]; |
dst->win[3] = src->v.w; |
} |
} else { |
dst->win[0] = UNVIEWPORT_X( src->v.x ); |
dst->win[1] = UNVIEWPORT_Y( src->v.y ); |
dst->win[2] = UNVIEWPORT_Z( src->v.z ); |
dst->win[3] = src->v.w; |
} |
dst->color[0] = src->v.color.red; |
dst->color[1] = src->v.color.green; |
dst->color[2] = src->v.color.blue; |
dst->color[3] = src->v.color.alpha; |
dst->specular[0] = src->v.specular.red; |
dst->specular[1] = src->v.specular.green; |
dst->specular[2] = src->v.specular.blue; |
dst->fog = src->v.specular.alpha/255.0; |
if (HAVE_PTEX_VERTICES && |
((HAVE_TEX2_VERTICES && format == PROJ_TEX3_VERTEX_FORMAT) || |
(format == PROJ_TEX1_VERTEX_FORMAT))) { |
dst->texcoord[0][0] = src->pv.u0; |
dst->texcoord[0][1] = src->pv.v0; |
dst->texcoord[0][3] = src->pv.q0; |
dst->texcoord[1][0] = src->pv.u1; |
dst->texcoord[1][1] = src->pv.v1; |
dst->texcoord[1][3] = src->pv.q1; |
if (HAVE_TEX2_VERTICES) { |
dst->texcoord[2][0] = src->pv.u2; |
dst->texcoord[2][1] = src->pv.v2; |
dst->texcoord[2][3] = src->pv.q2; |
} |
if (HAVE_TEX3_VERTICES) { |
dst->texcoord[3][0] = src->pv.u3; |
dst->texcoord[3][1] = src->pv.v3; |
dst->texcoord[3][3] = src->pv.q3; |
} |
} |
else { |
dst->texcoord[0][0] = src->v.u0; |
dst->texcoord[0][1] = src->v.v0; |
dst->texcoord[0][3] = 1.0; |
dst->texcoord[1][0] = src->v.u1; |
dst->texcoord[1][1] = src->v.v1; |
dst->texcoord[1][3] = 1.0; |
if (HAVE_TEX2_VERTICES) { |
dst->texcoord[2][0] = src->v.u2; |
dst->texcoord[2][1] = src->v.v2; |
dst->texcoord[2][3] = 1.0; |
} |
if (HAVE_TEX3_VERTICES) { |
dst->texcoord[3][0] = src->v.u3; |
dst->texcoord[3][1] = src->v.v3; |
dst->texcoord[3][3] = 1.0; |
} |
} |
} |
dst->pointSize = ctx->Point._Size; |
} |
void TAG(print_vertex)( GLcontext *ctx, const VERTEX *v ) |
{ |
LOCALVARS |
GLuint format = GET_VERTEX_FORMAT(); |
fprintf(stderr, "(%x) ", format); |
switch (format) { |
#if HAVE_TINY_VERTICES |
case TINY_VERTEX_FORMAT: |
fprintf(stderr, "xyz %.4f,%.4f,%.4f rgba %x:%x:%x:%x\n", |
v->v.x, v->v.y, v->v.z, |
v->tv.color.red, |
v->tv.color.green, |
v->tv.color.blue, |
v->tv.color.alpha); |
break; |
#endif |
#if HAVE_NOTEX_VERTICES |
case NOTEX_VERTEX_FORMAT: |
fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x spec %x:%x:%x:%x\n", |
v->v.x, v->v.y, v->v.z, v->v.w, |
v->v.color.red, |
v->v.color.green, |
v->v.color.blue, |
v->v.color.alpha, |
v->v.specular.red, |
v->v.specular.green, |
v->v.specular.blue, |
v->v.specular.alpha); |
break; |
#endif |
#if HAVE_TEX0_VERTICES |
case TEX0_VERTEX_FORMAT: |
fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x st %.4f,%.4f\n", |
v->v.x, v->v.y, v->v.z, v->v.w, |
v->v.color.red, |
v->v.color.green, |
v->v.color.blue, |
v->v.color.alpha, |
v->v.u0, |
v->v.v0); |
break; |
#endif |
#if HAVE_TEX1_VERTICES |
case TEX1_VERTEX_FORMAT: |
fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x st %.4f,%.4f st %.4f,%.4f\n", |
v->v.x, v->v.y, v->v.z, v->v.w, |
v->v.color.red, |
v->v.color.green, |
v->v.color.blue, |
v->v.color.alpha, |
v->v.u0, |
v->v.v0, |
v->v.u1, |
v->v.u2); |
break; |
#endif |
#if HAVE_PTEX_VERTICES |
case PROJ_TEX1_VERTEX_FORMAT: |
fprintf(stderr, "xyzw %.4f,%.4f,%.4f,%.4f rgba %x:%x:%x:%x stq %.4f,%.4f,%.4f stq %.4f,%.4f,%.4f\n", |
v->v.x, v->v.y, v->v.z, v->v.w, |
v->v.color.red, |
v->v.color.green, |
v->v.color.blue, |
v->v.color.alpha, |
v->pv.u0, |
v->pv.v0, |
v->pv.q0, |
v->pv.u1, |
v->pv.v1, |
v->pv.q1); |
break; |
#endif |
default: |
fprintf(stderr, "???\n"); |
break; |
} |
fprintf(stderr, "\n"); |
} |
static void do_import( struct vertex_buffer *VB, |
struct gl_client_array *to, |
struct gl_client_array *from ) |
{ |
GLuint count = VB->Count; |
if (!to->Ptr) { |
to->Ptr = ALIGN_MALLOC( VB->Size * 4 * sizeof(GLubyte), 32 ); |
to->Type = GL_UNSIGNED_BYTE; |
} |
/* No need to transform the same value 3000 times. |
*/ |
if (!from->StrideB) { |
to->StrideB = 0; |
count = 1; |
} |
else |
to->StrideB = 4 * sizeof(GLubyte); |
_math_trans_4ub( (GLubyte (*)[4]) to->Ptr, |
from->Ptr, |
from->StrideB, |
from->Type, |
from->Size, |
0, |
count); |
} |
#ifndef IMPORT_QUALIFIER |
#define IMPORT_QUALIFIER static |
#endif |
IMPORT_QUALIFIER void TAG(import_float_colors)( GLcontext *ctx ) |
{ |
LOCALVARS |
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; |
struct gl_client_array *to = GET_UBYTE_COLOR_STORE(); |
do_import( VB, to, VB->ColorPtr[0] ); |
VB->ColorPtr[0] = to; |
} |
IMPORT_QUALIFIER void TAG(import_float_spec_colors)( GLcontext *ctx ) |
{ |
LOCALVARS |
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; |
struct gl_client_array *to = GET_UBYTE_SPEC_COLOR_STORE(); |
do_import( VB, to, VB->SecondaryColorPtr[0] ); |
VB->SecondaryColorPtr[0] = to; |
} |
/* Interpolate the elements of the VB not included in typical hardware |
* vertices. |
* |
* NOTE: All these arrays are guarenteed by tnl to be writeable and |
* have good stride. |
*/ |
#ifndef INTERP_QUALIFIER |
#define INTERP_QUALIFIER static |
#endif |
#define GET_COLOR(ptr, idx) (((GLchan (*)[4])((ptr)->Ptr))[idx]) |
INTERP_QUALIFIER void TAG(interp_extras)( GLcontext *ctx, |
GLfloat t, |
GLuint dst, GLuint out, GLuint in, |
GLboolean force_boundary ) |
{ |
LOCALVARS |
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; |
if (VB->ColorPtr[1]) { |
INTERP_4CHAN( t, |
GET_COLOR(VB->ColorPtr[1], dst), |
GET_COLOR(VB->ColorPtr[1], out), |
GET_COLOR(VB->ColorPtr[1], in) ); |
if (VB->SecondaryColorPtr[1]) { |
INTERP_3CHAN( t, |
GET_COLOR(VB->SecondaryColorPtr[1], dst), |
GET_COLOR(VB->SecondaryColorPtr[1], out), |
GET_COLOR(VB->SecondaryColorPtr[1], in) ); |
} |
} |
if (VB->EdgeFlag) { |
VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary; |
} |
INTERP_VERTEX(ctx, t, dst, out, in, force_boundary); |
} |
INTERP_QUALIFIER void TAG(copy_pv_extras)( GLcontext *ctx, |
GLuint dst, GLuint src ) |
{ |
LOCALVARS |
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; |
if (VB->ColorPtr[1]) { |
COPY_CHAN4( GET_COLOR(VB->ColorPtr[1], dst), |
GET_COLOR(VB->ColorPtr[1], src) ); |
if (VB->SecondaryColorPtr[1]) { |
COPY_CHAN4( GET_COLOR(VB->SecondaryColorPtr[1], dst), |
GET_COLOR(VB->SecondaryColorPtr[1], src) ); |
} |
} |
COPY_PV_VERTEX(ctx, dst, src); |
} |
#undef INTERP_QUALIFIER |
#undef IMPORT_QUALIFIER |
#undef GET_COLOR |
#undef IND |
#undef TAG |
/shark/trunk/ports/mesa/src/tnl_dd/t_dd_unfilled.h |
---|
0,0 → 1,213 |
/* $Id: t_dd_unfilled.h,v 1.1 2003-02-28 11:54:02 pj Exp $ */ |
/* |
* Mesa 3-D graphics library |
* Version: 3.5 |
* |
* 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> |
*/ |
#if HAVE_RGBA |
#define VERT_SET_IND( v, c ) |
#define VERT_COPY_IND( v0, v1 ) |
#define VERT_SAVE_IND( idx ) |
#define VERT_RESTORE_IND( idx ) |
#endif |
#if !HAVE_SPEC |
#define VERT_SET_SPEC( v, c ) |
#define VERT_COPY_SPEC( v0, v1 ) |
#define VERT_SAVE_SPEC( idx ) |
#define VERT_RESTORE_SPEC( idx ) |
#endif |
static void TAG(unfilled_tri)( GLcontext *ctx, |
GLenum mode, |
GLuint e0, GLuint e1, GLuint e2 ) |
{ |
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; |
GLubyte *ef = VB->EdgeFlag; |
VERTEX *v[3]; |
LOCAL_VARS(3); |
v[0] = (VERTEX *)GET_VERTEX(e0); |
v[1] = (VERTEX *)GET_VERTEX(e1); |
v[2] = (VERTEX *)GET_VERTEX(e2); |
if ((ctx->_TriangleCaps & DD_FLATSHADE) && HAVE_HW_FLATSHADE) { |
if (HAVE_RGBA) { |
VERT_SAVE_RGBA(0); |
VERT_SAVE_RGBA(1); |
VERT_COPY_RGBA(v[0], v[2]); |
VERT_COPY_RGBA(v[1], v[2]); |
if (HAVE_SPEC) { |
VERT_SAVE_SPEC(0); |
VERT_SAVE_SPEC(1); |
VERT_COPY_SPEC(v[0], v[2]); |
VERT_COPY_SPEC(v[1], v[2]); |
} |
} else { |
VERT_SAVE_IND(0); |
VERT_SAVE_IND(1); |
VERT_COPY_IND(v[0], v[2]); |
VERT_COPY_IND(v[1], v[2]); |
} |
} |
/* fprintf(stderr, "%s %s %d %d %d\n", __FUNCTION__, */ |
/* _mesa_lookup_enum_by_nr( mode ), */ |
/* ef[e0], ef[e1], ef[e2]); */ |
if (mode == GL_POINT) { |
RASTERIZE(GL_POINTS); |
if (ef[e0]) POINT( v[0] ); |
if (ef[e1]) POINT( v[1] ); |
if (ef[e2]) POINT( v[2] ); |
} |
else { |
RASTERIZE(GL_LINES); |
if (RENDER_PRIMITIVE == GL_POLYGON) { |
if (ef[e2]) LINE( v[2], v[0] ); |
if (ef[e0]) LINE( v[0], v[1] ); |
if (ef[e1]) LINE( v[1], v[2] ); |
} |
else { |
if (ef[e0]) LINE( v[0], v[1] ); |
if (ef[e1]) LINE( v[1], v[2] ); |
if (ef[e2]) LINE( v[2], v[0] ); |
} |
} |
if ((ctx->_TriangleCaps & DD_FLATSHADE) && HAVE_HW_FLATSHADE) { |
if (HAVE_RGBA) { |
VERT_RESTORE_RGBA(0); |
VERT_RESTORE_RGBA(1); |
if (HAVE_SPEC) { |
VERT_RESTORE_SPEC(0); |
VERT_RESTORE_SPEC(1); |
} |
} else { |
VERT_RESTORE_IND(0); |
VERT_RESTORE_IND(1); |
} |
} |
} |
static void TAG(unfilled_quad)( GLcontext *ctx, |
GLenum mode, |
GLuint e0, GLuint e1, |
GLuint e2, GLuint e3 ) |
{ |
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; |
GLubyte *ef = VB->EdgeFlag; |
VERTEX *v[4]; |
LOCAL_VARS(4); |
v[0] = (VERTEX *)GET_VERTEX(e0); |
v[1] = (VERTEX *)GET_VERTEX(e1); |
v[2] = (VERTEX *)GET_VERTEX(e2); |
v[3] = (VERTEX *)GET_VERTEX(e3); |
/* Hardware flatshading breaks down here. If the hardware doesn't |
* support flatshading, this will already have been done: |
*/ |
if ((ctx->_TriangleCaps & DD_FLATSHADE) && HAVE_HW_FLATSHADE) { |
if (HAVE_RGBA) { |
VERT_SAVE_RGBA(0); |
VERT_SAVE_RGBA(1); |
VERT_SAVE_RGBA(2); |
VERT_COPY_RGBA(v[0], v[3]); |
VERT_COPY_RGBA(v[1], v[3]); |
VERT_COPY_RGBA(v[2], v[3]); |
if (HAVE_SPEC) { |
VERT_SAVE_SPEC(0); |
VERT_SAVE_SPEC(1); |
VERT_SAVE_SPEC(2); |
VERT_COPY_SPEC(v[0], v[3]); |
VERT_COPY_SPEC(v[1], v[3]); |
VERT_COPY_SPEC(v[2], v[3]); |
} |
} else { |
VERT_SAVE_IND(0); |
VERT_SAVE_IND(1); |
VERT_SAVE_IND(2); |
VERT_COPY_IND(v[0], v[3]); |
VERT_COPY_IND(v[1], v[3]); |
VERT_COPY_IND(v[2], v[3]); |
} |
} |
if (mode == GL_POINT) { |
RASTERIZE(GL_POINTS); |
if (ef[e0]) POINT( v[0] ); |
if (ef[e1]) POINT( v[1] ); |
if (ef[e2]) POINT( v[2] ); |
if (ef[e3]) POINT( v[3] ); |
} |
else { |
RASTERIZE(GL_LINES); |
if (ef[e0]) LINE( v[0], v[1] ); |
if (ef[e1]) LINE( v[1], v[2] ); |
if (ef[e2]) LINE( v[2], v[3] ); |
if (ef[e3]) LINE( v[3], v[0] ); |
} |
if ((ctx->_TriangleCaps & DD_FLATSHADE) && HAVE_HW_FLATSHADE) { |
if (HAVE_RGBA) { |
VERT_RESTORE_RGBA(0); |
VERT_RESTORE_RGBA(1); |
VERT_RESTORE_RGBA(2); |
if (HAVE_SPEC) { |
VERT_RESTORE_SPEC(0); |
VERT_RESTORE_SPEC(1); |
VERT_RESTORE_SPEC(2); |
} |
} else { |
VERT_RESTORE_IND(0); |
VERT_RESTORE_IND(1); |
VERT_RESTORE_IND(2); |
} |
} |
} |
#if HAVE_RGBA |
#undef VERT_SET_IND |
#undef VERT_COPY_IND |
#undef VERT_SAVE_IND |
#undef VERT_RESTORE_IND |
#endif |
#if !HAVE_SPEC |
#undef VERT_SET_SPEC |
#undef VERT_COPY_SPEC |
#undef VERT_SAVE_SPEC |
#undef VERT_RESTORE_SPEC |
#endif |
#undef TAG |
/shark/trunk/ports/mesa/src/tnl_dd/t_dd_dmatmp.h |
---|
0,0 → 1,1106 |
/* $Id: t_dd_dmatmp.h,v 1.1 2003-02-28 11:54:01 pj Exp $ */ |
/* |
* Mesa 3-D graphics library |
* Version: 3.5 |
* |
* 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> |
*/ |
/* Template for render stages which build and emit vertices directly |
* to fixed-size dma buffers. Useful for rendering strips and other |
* native primitives where clipping and per-vertex tweaks such as |
* those in t_dd_tritmp.h are not required. |
* |
* Produces code for both inline triangles and indexed triangles. |
* Where various primitive types are unaccelerated by hardware, the |
* code attempts to fallback to other primitive types (quadstrips to |
* tristrips, lineloops to linestrips), or to indexed vertices. |
* Ultimately, a FALLBACK() macro is invoked if there is no way to |
* render the primitive natively. |
*/ |
#if !defined(HAVE_TRIANGLES) |
#error "must have at least triangles to use render template" |
#endif |
#if !HAVE_ELTS |
#define ELTS_VARS |
#define ALLOC_ELTS( nr ) |
#define EMIT_ELT( offset, elt ) |
#define EMIT_TWO_ELTS( offset, elt0, elt1 ) |
#define INCR_ELTS( nr ) |
#define ELT_INIT(prim) |
#define GET_CURRENT_VB_MAX_ELTS() 0 |
#define GET_SUBSEQUENT_VB_MAX_ELTS() 0 |
#define ALLOC_ELTS_NEW_PRIMITIVE(nr) |
#define RELEASE_ELT_VERTS() |
#define EMIT_INDEXED_VERTS( ctx, start, count ) |
#endif |
#ifndef EMIT_TWO_ELTS |
#define EMIT_TWO_ELTS( offset, elt0, elt1 ) \ |
do { \ |
EMIT_ELT( offset, elt0 ); \ |
EMIT_ELT( offset+1, elt1 ); \ |
} while (0) |
#endif |
#ifndef FINISH |
#define FINISH |
#endif |
/**********************************************************************/ |
/* Render whole begin/end objects */ |
/**********************************************************************/ |
static GLboolean TAG(emit_elt_verts)( GLcontext *ctx, |
GLuint start, GLuint count ) |
{ |
if (HAVE_ELTS) { |
LOCAL_VARS; |
GLuint nr = count - start; |
if ( nr >= GET_SUBSEQUENT_VB_MAX_VERTS() ) /* assumes same packing for |
* indexed and regualar verts |
*/ |
return GL_FALSE; |
NEW_PRIMITIVE(); /* finish last prim */ |
EMIT_INDEXED_VERTS( ctx, start, count ); |
return GL_TRUE; |
} else { |
return GL_FALSE; |
} |
} |
#if (HAVE_ELTS) |
static void TAG(emit_elts)( GLcontext *ctx, GLuint *elts, GLuint nr ) |
{ |
GLint i; |
LOCAL_VARS; |
ELTS_VARS; |
ALLOC_ELTS( nr ); |
for ( i = 0 ; i < nr ; i+=2, elts += 2 ) { |
EMIT_TWO_ELTS( 0, elts[0], elts[1] ); |
INCR_ELTS( 2 ); |
} |
} |
#endif |
/*********************************************************************** |
* Render non-indexed primitives. |
***********************************************************************/ |
static void TAG(render_points_verts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
if (HAVE_POINTS) { |
LOCAL_VARS; |
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); |
int currentsz = GET_CURRENT_VB_MAX_VERTS(); |
GLuint j, nr; |
INIT( GL_POINTS ); |
if (currentsz < 8) |
currentsz = dmasz; |
for (j = start; j < count; j += nr ) { |
nr = MIN2( currentsz, count - j ); |
EMIT_VERTS( ctx, j, nr ); |
currentsz = dmasz; |
} |
FINISH; |
} else { |
VERT_FALLBACK( ctx, start, count, flags ); |
} |
} |
static void TAG(render_lines_verts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
if (HAVE_LINES) { |
LOCAL_VARS; |
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); |
int currentsz = GET_CURRENT_VB_MAX_VERTS(); |
GLuint j, nr; |
INIT( GL_LINES ); |
/* Emit whole number of lines in total and in each buffer: |
*/ |
count -= (count-start) & 1; |
currentsz -= currentsz & 1; |
dmasz -= dmasz & 1; |
if (currentsz < 8) |
currentsz = dmasz; |
for (j = start; j < count; j += nr ) { |
nr = MIN2( currentsz, count - j ); |
EMIT_VERTS( ctx, j, nr ); |
currentsz = dmasz; |
} |
FINISH; |
} else { |
VERT_FALLBACK( ctx, start, count, flags ); |
} |
} |
static void TAG(render_line_strip_verts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
if (HAVE_LINE_STRIPS) { |
LOCAL_VARS; |
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); |
int currentsz = GET_CURRENT_VB_MAX_VERTS(); |
GLuint j, nr; |
NEW_PRIMITIVE(); /* always a new primitive */ |
INIT( GL_LINE_STRIP ); |
if (currentsz < 8) |
currentsz = dmasz; |
for (j = start; j + 1 < count; j += nr - 1 ) { |
nr = MIN2( currentsz, count - j ); |
EMIT_VERTS( ctx, j, nr ); |
currentsz = dmasz; |
} |
FINISH; |
} else { |
VERT_FALLBACK( ctx, start, count, flags ); |
} |
} |
static void TAG(render_line_loop_verts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
if (HAVE_LINE_STRIPS) { |
LOCAL_VARS; |
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); |
int currentsz = GET_CURRENT_VB_MAX_VERTS(); |
GLuint j, nr; |
NEW_PRIMITIVE(); |
INIT( GL_LINE_STRIP ); |
if (flags & PRIM_BEGIN) |
j = start; |
else |
j = start + 1; |
/* Ensure last vertex won't wrap buffers: |
*/ |
currentsz--; |
dmasz--; |
if (currentsz < 8) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
if (j + 1 < count) { |
for ( ; j + 1 < count; j += nr - 1 ) { |
nr = MIN2( currentsz, count - j ); |
EMIT_VERTS( ctx, j, nr ); |
currentsz = dmasz; |
} |
if (start < count - 1 && (flags & PRIM_END)) |
EMIT_VERTS( ctx, start, 1 ); |
} |
else if (start + 1 < count && (flags & PRIM_END)) { |
EMIT_VERTS( ctx, start+1, 1 ); |
EMIT_VERTS( ctx, start, 1 ); |
} |
FINISH; |
} else { |
VERT_FALLBACK( ctx, start, count, flags ); |
} |
} |
static void TAG(render_triangles_verts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
LOCAL_VARS; |
int dmasz = (GET_SUBSEQUENT_VB_MAX_VERTS()/3) * 3; |
int currentsz = (GET_CURRENT_VB_MAX_VERTS()/3) * 3; |
GLuint j, nr; |
INIT(GL_TRIANGLES); |
/* Emit whole number of tris in total. dmasz is already a multiple |
* of 3. |
*/ |
count -= (count-start)%3; |
if (currentsz < 8) |
currentsz = dmasz; |
for (j = start; j < count; j += nr) { |
nr = MIN2( currentsz, count - j ); |
EMIT_VERTS( ctx, j, nr ); |
currentsz = dmasz; |
} |
FINISH; |
} |
static void TAG(render_tri_strip_verts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
if (HAVE_TRI_STRIPS) { |
LOCAL_VARS; |
GLuint j, nr; |
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); |
int currentsz; |
INIT(GL_TRIANGLE_STRIP); |
NEW_PRIMITIVE(); |
currentsz = GET_CURRENT_VB_MAX_VERTS(); |
if (currentsz < 8) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
if ((flags & PRIM_PARITY) && count - start > 2) { |
if (HAVE_TRI_STRIP_1 && 0) { |
} else { |
EMIT_VERTS( ctx, start, 1 ); |
currentsz--; |
} |
} |
/* From here on emit even numbers of tris when wrapping over buffers: |
*/ |
dmasz -= (dmasz & 1); |
currentsz -= (currentsz & 1); |
for (j = start ; j + 2 < count; j += nr - 2 ) { |
nr = MIN2( currentsz, count - j ); |
EMIT_VERTS( ctx, j, nr ); |
currentsz = dmasz; |
} |
FINISH; |
} else { |
VERT_FALLBACK( ctx, start, count, flags ); |
} |
} |
static void TAG(render_tri_fan_verts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
if (HAVE_TRI_FANS) { |
LOCAL_VARS; |
GLuint j, nr; |
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); |
int currentsz = GET_CURRENT_VB_MAX_VERTS(); |
NEW_PRIMITIVE(); |
INIT(GL_TRIANGLE_FAN); |
if (currentsz < 8) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
for (j = start + 1 ; j + 1 < count; j += nr - 1 ) { |
nr = MIN2( currentsz, count - j + 1 ); |
EMIT_VERTS( ctx, start, 1 ); |
EMIT_VERTS( ctx, j, nr - 1 ); |
currentsz = dmasz; |
} |
FINISH; |
} |
else { |
/* Could write code to emit these as indexed vertices (for the |
* g400, for instance). |
*/ |
VERT_FALLBACK( ctx, start, count, flags ); |
} |
} |
static void TAG(render_poly_verts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
if (HAVE_POLYGONS) { |
LOCAL_VARS; |
GLuint j, nr; |
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); |
int currentsz = GET_CURRENT_VB_MAX_VERTS(); |
NEW_PRIMITIVE(); |
INIT(GL_POLYGON); |
if (currentsz < 8) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
for (j = start + 1 ; j + 1 < count ; j += nr - 1 ) { |
nr = MIN2( currentsz, count - j + 1 ); |
EMIT_VERTS( ctx, start, 1 ); |
EMIT_VERTS( ctx, j, nr - 1 ); |
currentsz = dmasz; |
} |
FINISH; |
} |
else if (HAVE_TRI_FANS && !(ctx->_TriangleCaps & DD_FLATSHADE)) { |
TAG(render_tri_fan_verts)( ctx, start, count, flags ); |
} else { |
VERT_FALLBACK( ctx, start, count, flags ); |
} |
} |
static void TAG(render_quad_strip_verts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
GLuint j, nr; |
if (HAVE_QUAD_STRIPS) { |
LOCAL_VARS; |
GLuint j, nr; |
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); |
int currentsz; |
INIT(GL_QUAD_STRIP); |
NEW_PRIMITIVE(); |
currentsz = GET_CURRENT_VB_MAX_VERTS(); |
if (currentsz < 8) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
dmasz -= (dmasz & 2); |
currentsz -= (currentsz & 2); |
for (j = start ; j + 3 < count; j += nr - 2 ) { |
nr = MIN2( currentsz, count - j ); |
EMIT_VERTS( ctx, j, nr ); |
currentsz = dmasz; |
} |
FINISH; |
} else if (HAVE_TRI_STRIPS && (ctx->_TriangleCaps & DD_FLATSHADE)) { |
if (TAG(emit_elt_verts)( ctx, start, count )) { |
LOCAL_VARS; |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
GLuint j, nr; |
/* Simulate flat-shaded quadstrips using indexed vertices: |
*/ |
NEW_PRIMITIVE(); |
ELT_INIT( GL_TRIANGLES ); |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
/* Emit whole number of quads in total, and in each buffer. |
*/ |
dmasz -= dmasz & 1; |
count -= (count-start) & 1; |
currentsz -= currentsz & 1; |
if (currentsz < 12) |
currentsz = dmasz; |
currentsz = currentsz/6*2; |
dmasz = dmasz/6*2; |
for (j = start; j + 3 < count; j += nr - 2 ) { |
nr = MIN2( currentsz, count - j ); |
if (nr >= 4) { |
GLint quads = (nr/2)-1; |
GLint i; |
ELTS_VARS; |
NEW_PRIMITIVE(); |
ALLOC_ELTS_NEW_PRIMITIVE( quads*6 ); |
for ( i = j-start ; i < j-start+quads*2 ; i+=2 ) { |
EMIT_TWO_ELTS( 0, (i+0), (i+1) ); |
EMIT_TWO_ELTS( 2, (i+2), (i+1) ); |
EMIT_TWO_ELTS( 4, (i+3), (i+2) ); |
INCR_ELTS( 6 ); |
} |
NEW_PRIMITIVE(); |
} |
currentsz = dmasz; |
} |
RELEASE_ELT_VERTS(); |
} |
else { |
/* Vertices won't fit in a single buffer or elts not available, |
* VERT_FALLBACK. |
*/ |
VERT_FALLBACK( ctx, start, count, flags ); |
} |
} |
else if (HAVE_TRI_STRIPS) { |
LOCAL_VARS; |
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS(); |
int currentsz = GET_CURRENT_VB_MAX_VERTS(); |
/* Emit smooth-shaded quadstrips as tristrips: |
*/ |
NEW_PRIMITIVE(); |
INIT( GL_TRIANGLE_STRIP ); |
/* Emit whole number of quads in total, and in each buffer. |
*/ |
dmasz -= dmasz & 1; |
currentsz -= currentsz & 1; |
count -= (count-start) & 1; |
if (currentsz < 8) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
for (j = start; j + 3 < count; j += nr - 2 ) { |
nr = MIN2( currentsz, count - j ); |
EMIT_VERTS( ctx, j, nr ); |
currentsz = dmasz; |
} |
FINISH; |
} else { |
VERT_FALLBACK( ctx, start, count, flags ); |
} |
} |
static void TAG(render_quads_verts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
if (HAVE_QUADS) { |
LOCAL_VARS; |
int dmasz = (GET_SUBSEQUENT_VB_MAX_VERTS()/4) * 4; |
int currentsz = (GET_CURRENT_VB_MAX_VERTS()/4) * 4; |
GLuint j, nr; |
INIT(GL_QUADS); |
/* Emit whole number of quads in total. dmasz is already a multiple |
* of 4. |
*/ |
count -= (count-start)%4; |
if (currentsz < 8) |
currentsz = dmasz; |
for (j = start; j < count; j += nr) { |
nr = MIN2( currentsz, count - j ); |
EMIT_VERTS( ctx, j, nr ); |
currentsz = dmasz; |
} |
FINISH; |
} else if (TAG(emit_elt_verts)( ctx, start, count )) { |
/* Hardware doesn't have a quad primitive type -- try to |
* simulate it using indexed vertices and the triangle |
* primitive: |
*/ |
LOCAL_VARS; |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
GLuint j, nr; |
NEW_PRIMITIVE(); |
ELT_INIT( GL_TRIANGLES ); |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
/* Emit whole number of quads in total, and in each buffer. |
*/ |
dmasz -= dmasz & 3; |
count -= (count-start) & 3; |
currentsz -= currentsz & 3; |
/* Adjust for rendering as triangles: |
*/ |
currentsz = currentsz/6*4; |
dmasz = dmasz/6*4; |
if (currentsz < 8) |
currentsz = dmasz; |
for (j = start; j < count; j += nr ) { |
nr = MIN2( currentsz, count - j ); |
if (nr >= 4) { |
GLint quads = nr/4; |
GLint i; |
ELTS_VARS; |
NEW_PRIMITIVE(); |
ALLOC_ELTS_NEW_PRIMITIVE( quads*6 ); |
for ( i = j-start ; i < j-start+quads*4 ; i+=4 ) { |
EMIT_TWO_ELTS( 0, (i+0), (i+1) ); |
EMIT_TWO_ELTS( 2, (i+3), (i+1) ); |
EMIT_TWO_ELTS( 4, (i+2), (i+3) ); |
INCR_ELTS( 6 ); |
} |
NEW_PRIMITIVE(); |
} |
currentsz = dmasz; |
} |
RELEASE_ELT_VERTS(); |
} |
else { |
/* Vertices won't fit in a single buffer, fallback. |
*/ |
VERT_FALLBACK( ctx, start, count, flags ); |
} |
} |
static void TAG(render_noop)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
} |
static render_func TAG(render_tab_verts)[GL_POLYGON+2] = |
{ |
TAG(render_points_verts), |
TAG(render_lines_verts), |
TAG(render_line_loop_verts), |
TAG(render_line_strip_verts), |
TAG(render_triangles_verts), |
TAG(render_tri_strip_verts), |
TAG(render_tri_fan_verts), |
TAG(render_quads_verts), |
TAG(render_quad_strip_verts), |
TAG(render_poly_verts), |
TAG(render_noop), |
}; |
/**************************************************************************** |
* Render elts using hardware indexed verts * |
****************************************************************************/ |
#if (HAVE_ELTS) |
static void TAG(render_points_elts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
if (HAVE_POINTS) { |
LOCAL_VARS; |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; |
GLuint j, nr; |
ELT_INIT( GL_POINTS ); |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
if (currentsz < 8) |
currentsz = dmasz; |
for (j = start; j < count; j += nr ) { |
nr = MIN2( currentsz, count - j ); |
TAG(emit_elts)( ctx, elts+j, nr ); |
NEW_PRIMITIVE(); |
currentsz = dmasz; |
} |
} else { |
ELT_FALLBACK( ctx, start, count, flags ); |
} |
} |
static void TAG(render_lines_elts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
if (HAVE_LINES) { |
LOCAL_VARS; |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; |
GLuint j, nr; |
ELT_INIT( GL_LINES ); |
/* Emit whole number of lines in total and in each buffer: |
*/ |
count -= (count-start) & 1; |
currentsz -= currentsz & 1; |
dmasz -= dmasz & 1; |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
if (currentsz < 8) |
currentsz = dmasz; |
for (j = start; j < count; j += nr ) { |
nr = MIN2( currentsz, count - j ); |
TAG(emit_elts)( ctx, elts+j, nr ); |
NEW_PRIMITIVE(); |
currentsz = dmasz; |
} |
} else { |
ELT_FALLBACK( ctx, start, count, flags ); |
} |
} |
static void TAG(render_line_strip_elts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
if (HAVE_LINE_STRIPS) { |
LOCAL_VARS; |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; |
GLuint j, nr; |
NEW_PRIMITIVE(); /* always a new primitive */ |
ELT_INIT( GL_LINE_STRIP ); |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
if (currentsz < 8) |
currentsz = dmasz; |
for (j = start; j + 1 < count; j += nr - 1 ) { |
nr = MIN2( currentsz, count - j ); |
TAG(emit_elts)( ctx, elts+j, nr ); |
NEW_PRIMITIVE(); |
currentsz = dmasz; |
} |
} else { |
/* TODO: Try to emit as indexed lines. |
*/ |
ELT_FALLBACK( ctx, start, count, flags ); |
} |
} |
static void TAG(render_line_loop_elts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
if (HAVE_LINE_STRIPS) { |
LOCAL_VARS; |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; |
GLuint j, nr; |
NEW_PRIMITIVE(); |
ELT_INIT( GL_LINE_STRIP ); |
if (flags & PRIM_BEGIN) |
j = start; |
else |
j = start + 1; |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
if (currentsz < 8) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
/* Ensure last vertex doesn't wrap: |
*/ |
currentsz--; |
dmasz--; |
for ( ; j + 1 < count; j += nr - 1 ) { |
nr = MIN2( currentsz, count - j ); |
/* NEW_PRIMITIVE(); */ |
TAG(emit_elts)( ctx, elts+j, nr ); |
currentsz = dmasz; |
} |
if (flags & PRIM_END) |
TAG(emit_elts)( ctx, elts+start, 1 ); |
NEW_PRIMITIVE(); |
} else { |
/* TODO: Try to emit as indexed lines */ |
ELT_FALLBACK( ctx, start, count, flags ); |
} |
} |
/* For verts, we still eliminate the copy from main memory to dma |
* buffers. For elts, this is probably no better (worse?) than the |
* standard path. |
*/ |
static void TAG(render_triangles_elts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
LOCAL_VARS; |
GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS()/3*3; |
int currentsz; |
GLuint j, nr; |
NEW_PRIMITIVE(); |
ELT_INIT( GL_TRIANGLES ); |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
/* Emit whole number of tris in total. dmasz is already a multiple |
* of 3. |
*/ |
count -= (count-start)%3; |
currentsz -= currentsz%3; |
if (currentsz < 8) |
currentsz = dmasz; |
for (j = start; j < count; j += nr) { |
nr = MIN2( currentsz, count - j ); |
TAG(emit_elts)( ctx, elts+j, nr ); |
NEW_PRIMITIVE(); |
currentsz = dmasz; |
} |
} |
static void TAG(render_tri_strip_elts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
if (HAVE_TRI_STRIPS) { |
LOCAL_VARS; |
GLuint j, nr; |
GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
NEW_PRIMITIVE(); |
ELT_INIT( GL_TRIANGLE_STRIP ); |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
if (currentsz < 8) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
if ((flags & PRIM_PARITY) && count - start > 2) { |
TAG(emit_elts)( ctx, elts+start, 1 ); |
} |
/* Keep the same winding over multiple buffers: |
*/ |
dmasz -= (dmasz & 1); |
currentsz -= (currentsz & 1); |
for (j = start ; j + 2 < count; j += nr - 2 ) { |
nr = MIN2( currentsz, count - j ); |
TAG(emit_elts)( ctx, elts+j, nr ); |
NEW_PRIMITIVE(); |
currentsz = dmasz; |
} |
} else { |
/* TODO: try to emit as indexed triangles */ |
ELT_FALLBACK( ctx, start, count, flags ); |
} |
} |
static void TAG(render_tri_fan_elts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
if (HAVE_TRI_FANS) { |
LOCAL_VARS; |
GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; |
GLuint j, nr; |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
NEW_PRIMITIVE(); |
ELT_INIT( GL_TRIANGLE_FAN ); |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
if (currentsz < 8) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
for (j = start + 1 ; j + 1 < count; j += nr - 1 ) { |
nr = MIN2( currentsz, count - j + 1 ); |
TAG(emit_elts)( ctx, elts+start, 1 ); |
TAG(emit_elts)( ctx, elts+j, nr - 1 ); |
NEW_PRIMITIVE(); |
currentsz = dmasz; |
} |
} else { |
/* TODO: try to emit as indexed triangles */ |
ELT_FALLBACK( ctx, start, count, flags ); |
} |
} |
static void TAG(render_poly_elts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
if (HAVE_POLYGONS && 0) { |
} else if (HAVE_TRI_FANS && !(ctx->_TriangleCaps & DD_FLATSHADE)) { |
LOCAL_VARS; |
GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; |
GLuint j, nr; |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
NEW_PRIMITIVE(); |
ELT_INIT( GL_TRIANGLE_FAN ); |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
if (currentsz < 8) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
for (j = start + 1 ; j + 1 < count ; j += nr - 1 ) { |
nr = MIN2( currentsz, count - j + 1 ); |
TAG(emit_elts)( ctx, elts+start, 1 ); |
TAG(emit_elts)( ctx, elts+j, nr - 1 ); |
NEW_PRIMITIVE(); |
currentsz = dmasz; |
} |
} else { |
ELT_FALLBACK( ctx, start, count, flags ); |
} |
} |
static void TAG(render_quad_strip_elts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
if (HAVE_QUAD_STRIPS && 0) { |
} |
else if (HAVE_TRI_STRIPS) { |
LOCAL_VARS; |
GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
GLuint j, nr; |
NEW_PRIMITIVE(); |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
/* Emit whole number of quads in total, and in each buffer. |
*/ |
dmasz -= dmasz & 1; |
count -= (count-start) & 1; |
currentsz -= currentsz & 1; |
if (currentsz < 12) |
currentsz = dmasz; |
if (ctx->_TriangleCaps & DD_FLATSHADE) { |
ELT_INIT( GL_TRIANGLES ); |
currentsz = currentsz/6*2; |
dmasz = dmasz/6*2; |
for (j = start; j + 3 < count; j += nr - 2 ) { |
nr = MIN2( currentsz, count - j ); |
if (nr >= 4) |
{ |
GLint i; |
GLint quads = (nr/2)-1; |
ELTS_VARS; |
NEW_PRIMITIVE(); |
ALLOC_ELTS_NEW_PRIMITIVE( quads*6 ); |
for ( i = j-start ; i < j-start+quads ; i++, elts += 2 ) { |
EMIT_TWO_ELTS( 0, elts[0], elts[1] ); |
EMIT_TWO_ELTS( 2, elts[2], elts[1] ); |
EMIT_TWO_ELTS( 4, elts[3], elts[2] ); |
INCR_ELTS( 6 ); |
} |
NEW_PRIMITIVE(); |
} |
currentsz = dmasz; |
} |
} |
else { |
ELT_INIT( GL_TRIANGLE_STRIP ); |
for (j = start; j + 3 < count; j += nr - 2 ) { |
nr = MIN2( currentsz, count - j ); |
TAG(emit_elts)( ctx, elts+j, nr ); |
NEW_PRIMITIVE(); |
currentsz = dmasz; |
} |
} |
} |
} |
static void TAG(render_quads_elts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
if (HAVE_QUADS && 0) { |
} else { |
LOCAL_VARS; |
GLuint *elts = TNL_CONTEXT(ctx)->vb.Elts; |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
GLuint j, nr; |
ELT_INIT( GL_TRIANGLES ); |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
/* Emit whole number of quads in total, and in each buffer. |
*/ |
dmasz -= dmasz & 3; |
count -= (count-start) & 3; |
currentsz -= currentsz & 3; |
/* Adjust for rendering as triangles: |
*/ |
currentsz = currentsz/6*4; |
dmasz = dmasz/6*4; |
if (currentsz < 8) |
currentsz = dmasz; |
for (j = start; j + 3 < count; j += nr - 2 ) { |
nr = MIN2( currentsz, count - j ); |
if (nr >= 4) |
{ |
GLint quads = nr/4; |
GLint i; |
ELTS_VARS; |
NEW_PRIMITIVE(); |
ALLOC_ELTS_NEW_PRIMITIVE( quads * 6 ); |
for ( i = j-start ; i < j-start+quads ; i++, elts += 4 ) { |
EMIT_TWO_ELTS( 0, elts[0], elts[1] ); |
EMIT_TWO_ELTS( 2, elts[3], elts[1] ); |
EMIT_TWO_ELTS( 4, elts[2], elts[3] ); |
INCR_ELTS( 6 ); |
} |
} |
NEW_PRIMITIVE(); |
currentsz = dmasz; |
} |
} |
} |
static render_func TAG(render_tab_elts)[GL_POLYGON+2] = |
{ |
TAG(render_points_elts), |
TAG(render_lines_elts), |
TAG(render_line_loop_elts), |
TAG(render_line_strip_elts), |
TAG(render_triangles_elts), |
TAG(render_tri_strip_elts), |
TAG(render_tri_fan_elts), |
TAG(render_quads_elts), |
TAG(render_quad_strip_elts), |
TAG(render_poly_elts), |
TAG(render_noop), |
}; |
#endif |
/shark/trunk/ports/mesa/src/tnl_dd/t_dd_dmatmp2.h |
---|
0,0 → 1,1095 |
/* |
* Mesa 3-D graphics library |
* Version: 4.0.3 |
* |
* Copyright (C) 1999-2002 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> |
*/ |
/* Template for render stages which build and emit vertices directly |
* to fixed-size dma buffers. Useful for rendering strips and other |
* native primitives where clipping and per-vertex tweaks such as |
* those in t_dd_tritmp.h are not required. |
* |
*/ |
#if !HAVE_TRIANGLES || !HAVE_POINTS || !HAVE_LINES |
#error "must have points, lines & triangles to use render template" |
#endif |
#if !HAVE_TRI_STRIPS || !HAVE_TRI_FANS |
#error "must have tri strip and fans to use render template" |
#endif |
#if !HAVE_LINE_STRIPS |
#error "must have line strips to use render template" |
#endif |
#if !HAVE_POLYGONS |
#error "must have polygons to use render template" |
#endif |
#if !HAVE_ELTS |
#error "must have elts to use render template" |
#endif |
#ifndef EMIT_TWO_ELTS |
#define EMIT_TWO_ELTS( offset, elt0, elt1 ) \ |
do { \ |
EMIT_ELT( offset, elt0 ); \ |
EMIT_ELT( offset+1, elt1 ); \ |
} while (0) |
#endif |
/**********************************************************************/ |
/* Render whole begin/end objects */ |
/**********************************************************************/ |
static void TAG(emit_elts)( GLcontext *ctx, GLuint *elts, GLuint nr ) |
{ |
GLint i; |
LOCAL_VARS; |
ELTS_VARS; |
ALLOC_ELTS( nr ); |
for ( i = 0 ; i < nr ; i+=2, elts += 2 ) { |
EMIT_TWO_ELTS( 0, elts[0], elts[1] ); |
INCR_ELTS( 2 ); |
} |
} |
static void TAG(emit_consecutive_elts)( GLcontext *ctx, GLuint start, GLuint nr ) |
{ |
GLint i; |
LOCAL_VARS; |
ELTS_VARS; |
ALLOC_ELTS( nr ); |
for ( i = 0 ; i+1 < nr ; i+=2, start += 2 ) { |
EMIT_TWO_ELTS( 0, start, start+1 ); |
INCR_ELTS( 2 ); |
} |
if (i < nr) { |
EMIT_ELT( 0, start ); |
INCR_ELTS( 1 ); |
} |
} |
/*********************************************************************** |
* Render non-indexed primitives. |
***********************************************************************/ |
static void TAG(render_points_verts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
if (start < count) { |
LOCAL_VARS; |
if (0) fprintf(stderr, "%s\n", __FUNCTION__); |
EMIT_PRIM( ctx, GL_POINTS, HW_POINTS, start, count ); |
} |
} |
static void TAG(render_lines_verts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
LOCAL_VARS; |
if (0) fprintf(stderr, "%s\n", __FUNCTION__); |
count -= (count-start) & 1; |
if (start+1 >= count) |
return; |
if ((flags & PRIM_BEGIN) && ctx->Line.StippleFlag) { |
RESET_STIPPLE(); |
AUTO_STIPPLE( GL_TRUE ); |
} |
EMIT_PRIM( ctx, GL_LINES, HW_LINES, start, count ); |
if ((flags & PRIM_END) && ctx->Line.StippleFlag) |
AUTO_STIPPLE( GL_FALSE ); |
} |
static void TAG(render_line_strip_verts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
LOCAL_VARS; |
if (0) fprintf(stderr, "%s\n", __FUNCTION__); |
if (start+1 >= count) |
return; |
if ((flags & PRIM_BEGIN) && ctx->Line.StippleFlag) |
RESET_STIPPLE(); |
if (PREFER_DISCRETE_ELT_PRIM( count-start, HW_LINES )) |
{ |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
GLuint j, nr; |
ELT_INIT( GL_LINES, HW_LINES ); |
/* Emit whole number of lines in each full buffer. |
*/ |
dmasz = dmasz/2; |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
currentsz = currentsz/2; |
if (currentsz < 4) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
for (j = start; j + 1 < count; j += nr - 1 ) { |
GLint i; |
ELTS_VARS; |
nr = MIN2( currentsz, count - j ); |
ALLOC_ELTS( (nr-1)*2 ); |
for ( i = j ; i+1 < j+nr ; i+=1 ) { |
EMIT_TWO_ELTS( 0, (i+0), (i+1) ); |
INCR_ELTS( 2 ); |
} |
if (nr == currentsz) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
} |
} |
else |
EMIT_PRIM( ctx, GL_LINE_STRIP, HW_LINE_STRIP, start, count ); |
} |
static void TAG(render_line_loop_verts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
LOCAL_VARS; |
GLuint j, nr; |
if (0) fprintf(stderr, "%s\n", __FUNCTION__); |
if (flags & PRIM_BEGIN) { |
j = start; |
if (ctx->Line.StippleFlag) |
RESET_STIPPLE( ); |
} |
else |
j = start + 1; |
if (flags & PRIM_END) { |
if (start+1 >= count) |
return; |
if (PREFER_DISCRETE_ELT_PRIM( count-start, HW_LINES )) { |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
ELT_INIT( GL_LINES, HW_LINES ); |
/* Emit whole number of lines in each full buffer. |
*/ |
dmasz = dmasz/2; |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
currentsz = currentsz/2; |
if (currentsz < 4) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
/* Ensure last vertex doesn't wrap: |
*/ |
currentsz--; |
dmasz--; |
for (; j + 1 < count; ) { |
GLint i; |
ELTS_VARS; |
nr = MIN2( currentsz, count - j ); |
ALLOC_ELTS( (nr-1)*2 ); |
for ( i = j ; i+1 < j+nr ; i+=1 ) { |
EMIT_TWO_ELTS( 0, (i+0), (i+1) ); |
INCR_ELTS( 2 ); |
} |
j += nr - 1; |
if (j + 1 < count) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
else { |
ALLOC_ELTS( 2 ); |
EMIT_TWO_ELTS( 0, (j), (start) ); |
INCR_ELTS( 2 ); |
} |
} |
} |
else |
{ |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
ELT_INIT( GL_LINE_STRIP, HW_LINE_STRIP ); |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
if (currentsz < 8) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
/* Ensure last vertex doesn't wrap: |
*/ |
currentsz--; |
dmasz--; |
for ( ; j + 1 < count; ) { |
nr = MIN2( currentsz, count - j ); |
if (j + nr < count) { |
TAG(emit_consecutive_elts)( ctx, j, nr ); |
currentsz = dmasz; |
j += nr - 1; |
NEW_BUFFER(); |
} |
else if (nr) { |
ELTS_VARS; |
int i; |
ALLOC_ELTS( nr + 1 ); |
for ( i = 0 ; i+1 < nr ; i+=2, j += 2 ) { |
EMIT_TWO_ELTS( 0, j, j+1 ); |
INCR_ELTS( 2 ); |
} |
if (i < nr) { |
EMIT_ELT( 0, j ); j++; |
INCR_ELTS( 1 ); |
} |
EMIT_ELT( 0, start ); |
INCR_ELTS( 1 ); |
NEW_BUFFER(); |
} |
else { |
fprintf(stderr, "warining nr==0\n"); |
} |
} |
} |
} else { |
TAG(render_line_strip_verts)( ctx, j, count, flags ); |
} |
} |
static void TAG(render_triangles_verts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
LOCAL_VARS; |
if (0) fprintf(stderr, "%s\n", __FUNCTION__); |
count -= (count-start)%3; |
if (start+2 >= count) { |
return; |
} |
/* need a PREFER_DISCRETE_ELT_PRIM here too.. |
*/ |
EMIT_PRIM( ctx, GL_TRIANGLES, HW_TRIANGLES, start, count ); |
} |
static void TAG(render_tri_strip_verts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
LOCAL_VARS; |
if (0) fprintf(stderr, "%s\n", __FUNCTION__); |
if (start + 2 >= count) |
return; |
if (PREFER_DISCRETE_ELT_PRIM( count-start, HW_TRIANGLES )) |
{ |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
int parity = 0; |
GLuint j, nr; |
ELT_INIT( GL_TRIANGLES, HW_TRIANGLES ); |
if (flags & PRIM_PARITY) |
parity = 1; |
/* Emit even number of tris in each full buffer. |
*/ |
dmasz = dmasz/3; |
dmasz -= dmasz & 1; |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
currentsz = currentsz/3; |
currentsz -= currentsz & 1; |
if (currentsz < 4) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
for (j = start; j + 2 < count; j += nr - 2 ) { |
GLint i; |
ELTS_VARS; |
nr = MIN2( currentsz, count - j ); |
ALLOC_ELTS( (nr-2)*3 ); |
for ( i = j ; i+2 < j+nr ; i++, parity^=1 ) { |
EMIT_ELT( 0, (i+0+parity) ); |
EMIT_ELT( 1, (i+1-parity) ); |
EMIT_ELT( 2, (i+2) ); |
INCR_ELTS( 3 ); |
} |
if (nr == currentsz) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
} |
} |
else if ((flags & PRIM_PARITY) == 0) |
EMIT_PRIM( ctx, GL_TRIANGLE_STRIP, HW_TRIANGLE_STRIP_0, start, count ); |
else if (HAVE_TRI_STRIP_1) |
EMIT_PRIM( ctx, GL_TRIANGLE_STRIP, HW_TRIANGLE_STRIP_1, start, count ); |
else { |
/* Emit the first triangle with elts, then the rest as a regular strip. |
* TODO: Make this unlikely in t_imm_api.c |
*/ |
ELTS_VARS; |
ELT_INIT( GL_TRIANGLES, HW_TRIANGLES ); |
ALLOC_ELTS( 3 ); |
EMIT_ELT( 0, (start+1) ); |
EMIT_ELT( 1, (start+0) ); |
EMIT_ELT( 2, (start+2) ); |
INCR_ELTS( 3 ); |
NEW_PRIMITIVE(); |
start++; |
if (start + 2 >= count) |
return; |
EMIT_PRIM( ctx, GL_TRIANGLE_STRIP, HW_TRIANGLE_STRIP_0, start, |
count ); |
} |
} |
static void TAG(render_tri_fan_verts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
LOCAL_VARS; |
if (0) fprintf(stderr, "%s\n", __FUNCTION__); |
if (start+2 >= count) |
return; |
if (PREFER_DISCRETE_ELT_PRIM( count-start, HW_TRIANGLES )) |
{ |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
GLuint j, nr; |
ELT_INIT( GL_TRIANGLES, HW_TRIANGLES ); |
dmasz = dmasz/3; |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
currentsz = currentsz/3; |
if (currentsz < 4) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
for (j = start + 1; j + 1 < count; j += nr - 1 ) { |
GLint i; |
ELTS_VARS; |
nr = MIN2( currentsz, count - j ); |
ALLOC_ELTS( (nr-1)*3 ); |
for ( i = j ; i+1 < j+nr ; i++ ) { |
EMIT_ELT( 0, (start) ); |
EMIT_ELT( 1, (i) ); |
EMIT_ELT( 2, (i+1) ); |
INCR_ELTS( 3 ); |
} |
if (nr == currentsz) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
} |
} |
else { |
EMIT_PRIM( ctx, GL_TRIANGLE_FAN, HW_TRIANGLE_FAN, start, count ); |
} |
} |
static void TAG(render_poly_verts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
LOCAL_VARS; |
if (0) fprintf(stderr, "%s\n", __FUNCTION__); |
if (start+2 >= count) |
return; |
EMIT_PRIM( ctx, GL_POLYGON, HW_POLYGON, start, count ); |
} |
static void TAG(render_quad_strip_verts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
LOCAL_VARS; |
if (0) fprintf(stderr, "%s\n", __FUNCTION__); |
count -= (count-start) & 1; |
if (start+3 >= count) |
return; |
if (HAVE_QUAD_STRIPS) { |
EMIT_PRIM( ctx, GL_QUAD_STRIP, HW_QUAD_STRIP, start, count ); |
} |
else if (ctx->_TriangleCaps & DD_FLATSHADE) { |
LOCAL_VARS; |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
GLuint j, nr; |
ELT_INIT( GL_TRIANGLES, HW_TRIANGLES ); |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
/* Emit whole number of quads in total, and in each buffer. |
*/ |
currentsz = (currentsz/6)*2; |
dmasz = (dmasz/6)*2; |
if (currentsz < 4) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
for (j = start; j + 3 < count; j += nr - 2 ) { |
ELTS_VARS; |
GLint quads, i; |
nr = MIN2( currentsz, count - j ); |
quads = (nr/2)-1; |
ALLOC_ELTS( quads*6 ); |
for ( i = j ; i < j+quads*2 ; i+=2 ) { |
EMIT_TWO_ELTS( 0, (i+0), (i+1) ); |
EMIT_TWO_ELTS( 2, (i+2), (i+1) ); |
EMIT_TWO_ELTS( 4, (i+3), (i+2) ); |
INCR_ELTS( 6 ); |
} |
if (nr == currentsz) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
} |
} |
else { |
EMIT_PRIM( ctx, GL_TRIANGLE_STRIP, HW_TRIANGLE_STRIP_0, start, count ); |
} |
} |
static void TAG(render_quads_verts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
LOCAL_VARS; |
if (0) fprintf(stderr, "%s\n", __FUNCTION__); |
count -= (count-start)%4; |
if (start+3 >= count) |
return; |
if (HAVE_QUADS) { |
EMIT_PRIM( ctx, HW_QUADS, GL_QUADS, start, count ); |
} |
else { |
/* Hardware doesn't have a quad primitive type -- simulate it |
* using indexed vertices and the triangle primitive: |
*/ |
LOCAL_VARS; |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
GLuint j, nr; |
ELT_INIT( GL_TRIANGLES, HW_TRIANGLES ); |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
/* Adjust for rendering as triangles: |
*/ |
currentsz = (currentsz/6)*4; |
dmasz = (dmasz/6)*4; |
if (currentsz < 8) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
for (j = start; j < count; j += nr ) { |
ELTS_VARS; |
GLint quads, i; |
nr = MIN2( currentsz, count - j ); |
quads = nr/4; |
ALLOC_ELTS( quads*6 ); |
for ( i = j ; i < j+quads*4 ; i+=4 ) { |
EMIT_TWO_ELTS( 0, (i+0), (i+1) ); |
EMIT_TWO_ELTS( 2, (i+3), (i+1) ); |
EMIT_TWO_ELTS( 4, (i+2), (i+3) ); |
INCR_ELTS( 6 ); |
} |
if (nr == currentsz) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
} |
} |
} |
static void TAG(render_noop)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
} |
static render_func TAG(render_tab_verts)[GL_POLYGON+2] = |
{ |
TAG(render_points_verts), |
TAG(render_lines_verts), |
TAG(render_line_loop_verts), |
TAG(render_line_strip_verts), |
TAG(render_triangles_verts), |
TAG(render_tri_strip_verts), |
TAG(render_tri_fan_verts), |
TAG(render_quads_verts), |
TAG(render_quad_strip_verts), |
TAG(render_poly_verts), |
TAG(render_noop), |
}; |
/**************************************************************************** |
* Render elts using hardware indexed verts * |
****************************************************************************/ |
static void TAG(render_points_elts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
LOCAL_VARS; |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
GLuint *elts = GET_ELTS(); |
GLuint j, nr; |
ELT_INIT( GL_POINTS, HW_POINTS ); |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
if (currentsz < 8) |
currentsz = dmasz; |
for (j = start; j < count; j += nr ) { |
nr = MIN2( currentsz, count - j ); |
TAG(emit_elts)( ctx, elts+j, nr ); |
NEW_PRIMITIVE(); |
currentsz = dmasz; |
} |
} |
static void TAG(render_lines_elts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
LOCAL_VARS; |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
GLuint *elts = GET_ELTS(); |
GLuint j, nr; |
if (start+1 >= count) |
return; |
if ((flags & PRIM_BEGIN) && ctx->Line.StippleFlag) { |
RESET_STIPPLE(); |
AUTO_STIPPLE( GL_TRUE ); |
} |
ELT_INIT( GL_LINES, HW_LINES ); |
/* Emit whole number of lines in total and in each buffer: |
*/ |
count -= (count-start) & 1; |
currentsz -= currentsz & 1; |
dmasz -= dmasz & 1; |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
if (currentsz < 8) |
currentsz = dmasz; |
for (j = start; j < count; j += nr ) { |
nr = MIN2( currentsz, count - j ); |
TAG(emit_elts)( ctx, elts+j, nr ); |
NEW_PRIMITIVE(); |
currentsz = dmasz; |
} |
if ((flags & PRIM_END) && ctx->Line.StippleFlag) |
AUTO_STIPPLE( GL_FALSE ); |
} |
static void TAG(render_line_strip_elts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
LOCAL_VARS; |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
GLuint *elts = GET_ELTS(); |
GLuint j, nr; |
if (start+1 >= count) |
return; |
ELT_INIT( GL_LINE_STRIP, HW_LINE_STRIP ); |
if ((flags & PRIM_BEGIN) && ctx->Line.StippleFlag) |
RESET_STIPPLE(); |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
if (currentsz < 8) |
currentsz = dmasz; |
for (j = start; j + 1 < count; j += nr - 1 ) { |
nr = MIN2( currentsz, count - j ); |
TAG(emit_elts)( ctx, elts+j, nr ); |
NEW_PRIMITIVE(); |
currentsz = dmasz; |
} |
} |
static void TAG(render_line_loop_elts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
LOCAL_VARS; |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
GLuint *elts = GET_ELTS(); |
GLuint j, nr; |
if (0) fprintf(stderr, "%s\n", __FUNCTION__); |
if (flags & PRIM_BEGIN) |
j = start; |
else |
j = start + 1; |
if (flags & PRIM_END) { |
if (start+1 >= count) |
return; |
} |
else { |
if (j+1 >= count) |
return; |
} |
ELT_INIT( GL_LINE_STRIP, HW_LINE_STRIP ); |
if ((flags & PRIM_BEGIN) && ctx->Line.StippleFlag) |
RESET_STIPPLE(); |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
if (currentsz < 8) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
/* Ensure last vertex doesn't wrap: |
*/ |
currentsz--; |
dmasz--; |
for ( ; j + 1 < count; j += nr - 1 ) { |
nr = MIN2( currentsz, count - j ); |
TAG(emit_elts)( ctx, elts+j, nr ); |
currentsz = dmasz; |
} |
if (flags & PRIM_END) |
TAG(emit_elts)( ctx, elts+start, 1 ); |
NEW_PRIMITIVE(); |
} |
static void TAG(render_triangles_elts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
LOCAL_VARS; |
GLuint *elts = GET_ELTS(); |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS()/3*3; |
int currentsz; |
GLuint j, nr; |
if (start+2 >= count) |
return; |
/* NEW_PRIMITIVE(); */ |
ELT_INIT( GL_TRIANGLES, HW_TRIANGLES ); |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
/* Emit whole number of tris in total. dmasz is already a multiple |
* of 3. |
*/ |
count -= (count-start)%3; |
currentsz -= currentsz%3; |
if (currentsz < 8) |
currentsz = dmasz; |
for (j = start; j < count; j += nr) { |
nr = MIN2( currentsz, count - j ); |
TAG(emit_elts)( ctx, elts+j, nr ); |
NEW_PRIMITIVE(); |
currentsz = dmasz; |
} |
} |
static void TAG(render_tri_strip_elts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
LOCAL_VARS; |
GLuint j, nr; |
GLuint *elts = GET_ELTS(); |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
if (start+2 >= count) |
return; |
ELT_INIT( GL_TRIANGLE_STRIP, HW_TRIANGLE_STRIP_0 ); |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
if (currentsz < 8) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
if ((flags & PRIM_PARITY) && count - start > 2) { |
TAG(emit_elts)( ctx, elts+start, 1 ); |
currentsz--; |
} |
/* Keep the same winding over multiple buffers: |
*/ |
dmasz -= (dmasz & 1); |
currentsz -= (currentsz & 1); |
for (j = start ; j + 2 < count; j += nr - 2 ) { |
nr = MIN2( currentsz, count - j ); |
TAG(emit_elts)( ctx, elts+j, nr ); |
NEW_PRIMITIVE(); |
currentsz = dmasz; |
} |
} |
static void TAG(render_tri_fan_elts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
LOCAL_VARS; |
GLuint *elts = GET_ELTS(); |
GLuint j, nr; |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
if (start+2 >= count) |
return; |
ELT_INIT( GL_TRIANGLE_FAN, HW_TRIANGLE_FAN ); |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
if (currentsz < 8) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
for (j = start + 1 ; j + 1 < count; j += nr - 1 ) { |
nr = MIN2( currentsz, count - j + 1 ); |
TAG(emit_elts)( ctx, elts+start, 1 ); |
TAG(emit_elts)( ctx, elts+j, nr - 1 ); |
NEW_PRIMITIVE(); |
currentsz = dmasz; |
} |
} |
static void TAG(render_poly_elts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
LOCAL_VARS; |
GLuint *elts = GET_ELTS(); |
GLuint j, nr; |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
if (start+2 >= count) |
return; |
ELT_INIT( GL_POLYGON, HW_POLYGON ); |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
if (currentsz < 8) { |
NEW_BUFFER(); |
currentsz = dmasz; |
} |
for (j = start + 1 ; j + 1 < count ; j += nr - 1 ) { |
nr = MIN2( currentsz, count - j + 1 ); |
TAG(emit_elts)( ctx, elts+start, 1 ); |
TAG(emit_elts)( ctx, elts+j, nr - 1 ); |
NEW_PRIMITIVE(); |
currentsz = dmasz; |
} |
} |
static void TAG(render_quad_strip_elts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
if (start+3 >= count) |
return; |
if (HAVE_QUAD_STRIPS && 0) { |
} |
else { |
LOCAL_VARS; |
GLuint *elts = GET_ELTS(); |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
GLuint j, nr; |
NEW_PRIMITIVE(); |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
/* Emit whole number of quads in total, and in each buffer. |
*/ |
dmasz -= dmasz & 1; |
count -= (count-start) & 1; |
currentsz -= currentsz & 1; |
if (currentsz < 12) |
currentsz = dmasz; |
if (ctx->_TriangleCaps & DD_FLATSHADE) { |
ELT_INIT( GL_TRIANGLES, HW_TRIANGLES ); |
currentsz = currentsz/6*2; |
dmasz = dmasz/6*2; |
for (j = start; j + 3 < count; j += nr - 2 ) { |
nr = MIN2( currentsz, count - j ); |
if (nr >= 4) |
{ |
GLint i; |
GLint quads = (nr/2)-1; |
ELTS_VARS; |
ALLOC_ELTS( quads*6 ); |
for ( i = j-start ; i < j-start+quads ; i++, elts += 2 ) { |
EMIT_TWO_ELTS( 0, elts[0], elts[1] ); |
EMIT_TWO_ELTS( 2, elts[2], elts[1] ); |
EMIT_TWO_ELTS( 4, elts[3], elts[2] ); |
INCR_ELTS( 6 ); |
} |
NEW_PRIMITIVE(); |
} |
currentsz = dmasz; |
} |
} |
else { |
ELT_INIT( GL_TRIANGLE_STRIP, HW_TRIANGLE_STRIP_0 ); |
for (j = start; j + 3 < count; j += nr - 2 ) { |
nr = MIN2( currentsz, count - j ); |
TAG(emit_elts)( ctx, elts+j, nr ); |
NEW_PRIMITIVE(); |
currentsz = dmasz; |
} |
} |
} |
} |
static void TAG(render_quads_elts)( GLcontext *ctx, |
GLuint start, |
GLuint count, |
GLuint flags ) |
{ |
if (start+3 >= count) |
return; |
if (HAVE_QUADS && 0) { |
} else { |
LOCAL_VARS; |
GLuint *elts = GET_ELTS(); |
int dmasz = GET_SUBSEQUENT_VB_MAX_ELTS(); |
int currentsz; |
GLuint j, nr; |
ELT_INIT( GL_TRIANGLES, HW_TRIANGLES ); |
currentsz = GET_CURRENT_VB_MAX_ELTS(); |
/* Emit whole number of quads in total, and in each buffer. |
*/ |
dmasz -= dmasz & 3; |
count -= (count-start) & 3; |
currentsz -= currentsz & 3; |
/* Adjust for rendering as triangles: |
*/ |
currentsz = currentsz/6*4; |
dmasz = dmasz/6*4; |
if (currentsz < 8) |
currentsz = dmasz; |
for (j = start; j + 3 < count; j += nr - 2 ) { |
nr = MIN2( currentsz, count - j ); |
if (nr >= 4) |
{ |
GLint quads = nr/4; |
GLint i; |
ELTS_VARS; |
ALLOC_ELTS( quads * 6 ); |
for ( i = j-start ; i < j-start+quads ; i++, elts += 4 ) { |
EMIT_TWO_ELTS( 0, elts[0], elts[1] ); |
EMIT_TWO_ELTS( 2, elts[3], elts[1] ); |
EMIT_TWO_ELTS( 4, elts[2], elts[3] ); |
INCR_ELTS( 6 ); |
} |
} |
NEW_PRIMITIVE(); |
currentsz = dmasz; |
} |
} |
} |
static render_func TAG(render_tab_elts)[GL_POLYGON+2] = |
{ |
TAG(render_points_elts), |
TAG(render_lines_elts), |
TAG(render_line_loop_elts), |
TAG(render_line_strip_elts), |
TAG(render_triangles_elts), |
TAG(render_tri_strip_elts), |
TAG(render_tri_fan_elts), |
TAG(render_quads_elts), |
TAG(render_quad_strip_elts), |
TAG(render_poly_elts), |
TAG(render_noop), |
}; |
/shark/trunk/ports/mesa/src/tnl_dd/t_dd_vbtmp.h |
---|
0,0 → 1,835 |
/* $Id: t_dd_vbtmp.h,v 1.1 2003-02-28 11:54:02 pj Exp $ */ |
/* |
* Mesa 3-D graphics library |
* Version: 4.1 |
* |
* Copyright (C) 1999-2002 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> |
*/ |
/* Unlike the other templates here, this assumes quite a bit about the |
* underlying hardware. Specifically it assumes a d3d-like vertex |
* format, with a layout more or less constrained to look like the |
* following: |
* |
* union { |
* struct { |
* float x, y, z, w; |
* struct { char r, g, b, a; } color; |
* struct { char r, g, b, fog; } spec; |
* float u0, v0; |
* float u1, v1; |
* float u2, v2; |
* float u3, v3; |
* } v; |
* struct { |
* float x, y, z, w; |
* struct { char r, g, b, a; } color; |
* struct { char r, g, b, fog; } spec; |
* float u0, v0, q0; |
* float u1, v1, q1; |
* float u2, v2, q2; |
* float u3, v3, q3; |
* } pv; |
* struct { |
* float x, y, z; |
* struct { char r, g, b, a; } color; |
* } tv; |
* float f[16]; |
* unsigned int ui[16]; |
* unsigned char ub4[4][16]; |
* } |
* |
* VERTEX: hw vertex type as above |
* VERTEX_COLOR: hw color struct type in VERTEX |
* |
* DO_XYZW: Emit xyz and maybe w coordinates. |
* DO_RGBA: Emit color. |
* DO_SPEC: Emit specular color. |
* DO_FOG: Emit fog coordinate in specular alpha. |
* DO_TEX0: Emit tex0 u,v coordinates. |
* DO_TEX1: Emit tex1 u,v coordinates. |
* DO_TEX2: Emit tex2 u,v coordinates. |
* DO_TEX3: Emit tex3 u,v coordinates. |
* DO_PTEX: Emit tex0,1,2,3 q coordinates where possible. |
* |
* HAVE_RGBA_COLOR: Hardware takes color in rgba order (else bgra). |
* |
* HAVE_HW_VIEWPORT: Hardware performs viewport transform. |
* HAVE_HW_DIVIDE: Hardware performs perspective divide. |
* |
* HAVE_TINY_VERTICES: Hardware understands v.tv format. |
* HAVE_PTEX_VERTICES: Hardware understands v.pv format. |
* HAVE_NOTEX_VERTICES: Hardware understands v.v format with texcount 0. |
* |
* Additionally, this template assumes it is emitting *transformed* |
* vertices; the modifications to emit untransformed vertices (ie. to |
* t&l hardware) are probably too great to cooexist with the code |
* already in this file. |
* |
* NOTE: The PTEX vertex format always includes TEX0 and TEX1, even if |
* only TEX0 is enabled, in order to maintain a vertex size which is |
* an exact number of quadwords. |
*/ |
#if (HAVE_HW_VIEWPORT) |
#define VIEWPORT_X(dst,x) dst = x |
#define VIEWPORT_Y(dst,y) dst = y |
#define VIEWPORT_Z(dst,z) dst = z |
#else |
#define VIEWPORT_X(dst,x) dst = s[0] * x + s[12] |
#define VIEWPORT_Y(dst,y) dst = s[5] * y + s[13] |
#define VIEWPORT_Z(dst,z) dst = s[10] * z + s[14] |
#endif |
#if (HAVE_HW_DIVIDE && !HAVE_PTEX_VERTICES) |
#error "can't cope with this combination" |
#endif |
#ifndef LOCALVARS |
#define LOCALVARS |
#endif |
#ifndef CHECK_HW_DIVIDE |
#define CHECK_HW_DIVIDE 1 |
#endif |
#if (HAVE_HW_DIVIDE || DO_SPEC || DO_TEX0 || DO_FOG || !HAVE_TINY_VERTICES) |
static void TAG(emit)( GLcontext *ctx, |
GLuint start, GLuint end, |
void *dest, |
GLuint stride ) |
{ |
LOCALVARS |
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; |
GLfloat (*tc0)[4], (*tc1)[4], (*fog)[4]; |
GLfloat (*tc2)[4], (*tc3)[4]; |
GLubyte (*col)[4], (*spec)[4]; |
GLuint tc0_stride, tc1_stride, col_stride, spec_stride, fog_stride; |
GLuint tc2_stride, tc3_stride; |
GLuint tc0_size, tc1_size; |
GLuint tc2_size, tc3_size; |
GLfloat (*coord)[4]; |
GLuint coord_stride; |
VERTEX *v = (VERTEX *)dest; |
const GLfloat *s = GET_VIEWPORT_MAT(); |
const GLubyte *mask = VB->ClipMask; |
int i; |
/* fprintf(stderr, "%s(big) importable %d %d..%d\n", */ |
/* __FUNCTION__, VB->importable_data, start, end); */ |
if (HAVE_HW_VIEWPORT && HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) { |
(void) s; |
coord = VB->ClipPtr->data; |
coord_stride = VB->ClipPtr->stride; |
} |
else { |
coord = VB->NdcPtr->data; |
coord_stride = VB->NdcPtr->stride; |
} |
if (DO_TEX3) { |
const GLuint t3 = GET_TEXSOURCE(3); |
tc3 = VB->TexCoordPtr[t3]->data; |
tc3_stride = VB->TexCoordPtr[t3]->stride; |
if (DO_PTEX) |
tc3_size = VB->TexCoordPtr[t3]->size; |
} |
if (DO_TEX2) { |
const GLuint t2 = GET_TEXSOURCE(2); |
tc2 = VB->TexCoordPtr[t2]->data; |
tc2_stride = VB->TexCoordPtr[t2]->stride; |
if (DO_PTEX) |
tc2_size = VB->TexCoordPtr[t2]->size; |
} |
if (DO_TEX1) { |
const GLuint t1 = GET_TEXSOURCE(1); |
tc1 = VB->TexCoordPtr[t1]->data; |
tc1_stride = VB->TexCoordPtr[t1]->stride; |
if (DO_PTEX) |
tc1_size = VB->TexCoordPtr[t1]->size; |
} |
if (DO_TEX0) { |
const GLuint t0 = GET_TEXSOURCE(0); |
tc0_stride = VB->TexCoordPtr[t0]->stride; |
tc0 = VB->TexCoordPtr[t0]->data; |
if (DO_PTEX) |
tc0_size = VB->TexCoordPtr[t0]->size; |
} |
if (DO_RGBA) { |
if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE) |
IMPORT_FLOAT_COLORS( ctx ); |
col = (GLubyte (*)[4])VB->ColorPtr[0]->Ptr; |
col_stride = VB->ColorPtr[0]->StrideB; |
} |
if (DO_SPEC) { |
if (VB->SecondaryColorPtr[0]) { |
if (VB->SecondaryColorPtr[0]->Type != GL_UNSIGNED_BYTE) |
IMPORT_FLOAT_SPEC_COLORS( ctx ); |
spec = (GLubyte (*)[4])VB->SecondaryColorPtr[0]->Ptr; |
spec_stride = VB->SecondaryColorPtr[0]->StrideB; |
} else { |
GLubyte tmp[4]; |
spec = &tmp; |
spec_stride = 0; |
} |
} |
if (DO_FOG) { |
if (VB->FogCoordPtr) { |
fog = VB->FogCoordPtr->data; |
fog_stride = VB->FogCoordPtr->stride; |
} |
else { |
static GLfloat tmp[4] = {0, 0, 0, 0}; |
fog = &tmp; |
fog_stride = 0; |
} |
} |
if (VB->importable_data) { |
/* May have nonstandard strides: |
*/ |
if (start) { |
coord = (GLfloat (*)[4])((GLubyte *)coord + start * coord_stride); |
if (DO_TEX0) |
tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + start * tc0_stride); |
if (DO_TEX1) |
tc1 = (GLfloat (*)[4])((GLubyte *)tc1 + start * tc1_stride); |
if (DO_TEX2) |
tc2 = (GLfloat (*)[4])((GLubyte *)tc2 + start * tc2_stride); |
if (DO_TEX3) |
tc3 = (GLfloat (*)[4])((GLubyte *)tc3 + start * tc3_stride); |
if (DO_RGBA) |
STRIDE_4UB(col, start * col_stride); |
if (DO_SPEC) |
STRIDE_4UB(spec, start * spec_stride); |
if (DO_FOG) |
/*STRIDE_F(fog, start * fog_stride);*/ |
fog = (GLfloat (*)[4])((GLfloat *)fog + start * fog_stride); |
} |
for (i=start; i < end; i++, v = (VERTEX *)((GLubyte *)v + stride)) { |
if (DO_XYZW) { |
if (HAVE_HW_VIEWPORT || mask[i] == 0) { |
VIEWPORT_X(v->v.x, coord[0][0]); |
VIEWPORT_Y(v->v.y, coord[0][1]); |
VIEWPORT_Z(v->v.z, coord[0][2]); |
v->v.w = coord[0][3]; |
} |
/* fprintf(stderr, "vert %d: %.2f %.2f %.2f %.2f\n", */ |
/* i, v->v.x, v->v.y, v->v.z, v->v.w); */ |
coord = (GLfloat (*)[4])((GLubyte *)coord + coord_stride); |
} |
if (DO_RGBA) { |
if (HAVE_RGBA_COLOR) { |
*(GLuint *)&v->v.color = LE32_TO_CPU(*(GLuint *)&col[0]); |
STRIDE_4UB(col, col_stride); |
} else { |
v->v.color.blue = col[0][2]; |
v->v.color.green = col[0][1]; |
v->v.color.red = col[0][0]; |
v->v.color.alpha = col[0][3]; |
STRIDE_4UB(col, col_stride); |
} |
} |
if (DO_SPEC) { |
v->v.specular.red = spec[0][0]; |
v->v.specular.green = spec[0][1]; |
v->v.specular.blue = spec[0][2]; |
STRIDE_4UB(spec, spec_stride); |
} |
if (DO_FOG) { |
v->v.specular.alpha = fog[0][0] * 255.0; |
/*STRIDE_F(fog, fog_stride);*/ |
fog = (GLfloat (*)[4])((GLfloat *)fog + fog_stride); |
} |
if (DO_TEX0) { |
v->v.u0 = tc0[0][0]; |
v->v.v0 = tc0[0][1]; |
if (DO_PTEX) { |
if (HAVE_PTEX_VERTICES) { |
if (tc0_size == 4) |
v->pv.q0 = tc0[0][3]; |
else |
v->pv.q0 = 1.0; |
} |
else if (tc0_size == 4) { |
float rhw = 1.0 / tc0[0][3]; |
v->v.w *= tc0[0][3]; |
v->v.u0 *= rhw; |
v->v.v0 *= rhw; |
} |
} |
tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + tc0_stride); |
} |
if (DO_TEX1) { |
if (DO_PTEX) { |
v->pv.u1 = tc1[0][0]; |
v->pv.v1 = tc1[0][1]; |
if (tc1_size == 4) |
v->pv.q1 = tc1[0][3]; |
else |
v->pv.q1 = 1.0; |
} |
else { |
v->v.u1 = tc1[0][0]; |
v->v.v1 = tc1[0][1]; |
} |
tc1 = (GLfloat (*)[4])((GLubyte *)tc1 + tc1_stride); |
} |
else if (DO_PTEX) { |
*(GLuint *)&v->pv.q1 = 0; /* avoid culling on radeon */ |
} |
if (DO_TEX2) { |
if (DO_PTEX) { |
v->pv.u2 = tc2[0][0]; |
v->pv.v2 = tc2[0][1]; |
if (tc2_size == 4) |
v->pv.q2 = tc2[0][3]; |
else |
v->pv.q2 = 1.0; |
} |
else { |
v->v.u2 = tc2[0][0]; |
v->v.v2 = tc2[0][1]; |
} |
tc2 = (GLfloat (*)[4])((GLubyte *)tc2 + tc2_stride); |
} |
if (DO_TEX3) { |
if (DO_PTEX) { |
v->pv.u3 = tc3[0][0]; |
v->pv.v3 = tc3[0][1]; |
if (tc3_size == 4) |
v->pv.q3 = tc3[0][3]; |
else |
v->pv.q3 = 1.0; |
} |
else { |
v->v.u3 = tc3[0][0]; |
v->v.v3 = tc3[0][1]; |
} |
tc3 = (GLfloat (*)[4])((GLubyte *)tc3 + tc3_stride); |
} |
} |
} |
else { |
for (i=start; i < end; i++, v = (VERTEX *)((GLubyte *)v + stride)) { |
if (DO_XYZW) { |
if (HAVE_HW_VIEWPORT || mask[i] == 0) { |
VIEWPORT_X(v->v.x, coord[i][0]); |
VIEWPORT_Y(v->v.y, coord[i][1]); |
VIEWPORT_Z(v->v.z, coord[i][2]); |
v->v.w = coord[i][3]; |
} |
} |
if (DO_RGBA) { |
if (HAVE_RGBA_COLOR) { |
*(GLuint *)&v->v.color = LE32_TO_CPU(*(GLuint *)&col[i]); |
} |
else { |
v->v.color.blue = col[i][2]; |
v->v.color.green = col[i][1]; |
v->v.color.red = col[i][0]; |
v->v.color.alpha = col[i][3]; |
} |
} |
if (DO_SPEC) { |
v->v.specular.red = spec[i][0]; |
v->v.specular.green = spec[i][1]; |
v->v.specular.blue = spec[i][2]; |
} |
if (DO_FOG) { |
v->v.specular.alpha = fog[i][0] * 255.0; |
} |
if (DO_TEX0) { |
v->v.u0 = tc0[i][0]; |
v->v.v0 = tc0[i][1]; |
if (DO_PTEX) { |
if (HAVE_PTEX_VERTICES) { |
if (tc0_size == 4) |
v->pv.q0 = tc0[i][3]; |
else |
v->pv.q0 = 1.0; |
v->pv.q1 = 0; /* radeon */ |
} |
else if (tc0_size == 4) { |
float rhw = 1.0 / tc0[i][3]; |
v->v.w *= tc0[i][3]; |
v->v.u0 *= rhw; |
v->v.v0 *= rhw; |
} |
} |
} |
if (DO_TEX1) { |
if (DO_PTEX) { |
v->pv.u1 = tc1[i][0]; |
v->pv.v1 = tc1[i][1]; |
if (tc1_size == 4) |
v->pv.q1 = tc1[i][3]; |
else |
v->pv.q1 = 1.0; |
} |
else { |
v->v.u1 = tc1[i][0]; |
v->v.v1 = tc1[i][1]; |
} |
} |
} |
} |
} |
#else |
#if DO_XYZW |
#if HAVE_HW_DIVIDE |
#error "cannot use tiny vertices with hw perspective divide" |
#endif |
static void TAG(emit)( GLcontext *ctx, GLuint start, GLuint end, |
void *dest, GLuint stride ) |
{ |
LOCALVARS |
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; |
GLubyte (*col)[4]; |
GLuint col_stride; |
GLfloat (*coord)[4] = VB->NdcPtr->data; |
GLuint coord_stride = VB->NdcPtr->stride; |
GLfloat *v = (GLfloat *)dest; |
const GLubyte *mask = VB->ClipMask; |
const GLfloat *s = GET_VIEWPORT_MAT(); |
int i; |
(void) s; |
ASSERT(stride == 4); |
if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE) |
IMPORT_FLOAT_COLORS( ctx ); |
col = (GLubyte (*)[4])VB->ColorPtr[0]->Ptr; |
col_stride = VB->ColorPtr[0]->StrideB; |
ASSERT(VB->ColorPtr[0]->Type == GL_UNSIGNED_BYTE); |
/* fprintf(stderr, "%s(small) importable %x\n", */ |
/* __FUNCTION__, VB->importable_data); */ |
/* Pack what's left into a 4-dword vertex. Color is in a different |
* place, and there is no 'w' coordinate. |
*/ |
if (VB->importable_data) { |
if (start) { |
coord = (GLfloat (*)[4])((GLubyte *)coord + start * coord_stride); |
STRIDE_4UB(col, start * col_stride); |
} |
for (i=start; i < end; i++, v+=4) { |
if (HAVE_HW_VIEWPORT || mask[i] == 0) { |
VIEWPORT_X(v[0], coord[0][0]); |
VIEWPORT_Y(v[1], coord[0][1]); |
VIEWPORT_Z(v[2], coord[0][2]); |
} |
coord = (GLfloat (*)[4])((GLubyte *)coord + coord_stride); |
if (DO_RGBA) { |
if (HAVE_RGBA_COLOR) { |
*(GLuint *)&v[3] = LE32_TO_CPU(*(GLuint *)col); |
} |
else { |
VERTEX_COLOR *c = (VERTEX_COLOR *)&v[3]; |
c->blue = col[0][2]; |
c->green = col[0][1]; |
c->red = col[0][0]; |
c->alpha = col[0][3]; |
} |
STRIDE_4UB( col, col_stride ); |
} |
/* fprintf(stderr, "vert %d: %.2f %.2f %.2f %x\n", */ |
/* i, v[0], v[1], v[2], *(int *)&v[3]); */ |
} |
} |
else { |
for (i=start; i < end; i++, v+=4) { |
if (HAVE_HW_VIEWPORT || mask[i] == 0) { |
VIEWPORT_X(v[0], coord[i][0]); |
VIEWPORT_Y(v[1], coord[i][1]); |
VIEWPORT_Z(v[2], coord[i][2]); |
} |
if (DO_RGBA) { |
if (HAVE_RGBA_COLOR) { |
*(GLuint *)&v[3] = LE32_TO_CPU(*(GLuint *)&col[i]); |
} |
else { |
VERTEX_COLOR *c = (VERTEX_COLOR *)&v[3]; |
c->blue = col[i][2]; |
c->green = col[i][1]; |
c->red = col[i][0]; |
c->alpha = col[i][3]; |
} |
} |
/* fprintf(stderr, "vert %d: %.2f %.2f %.2f %x\n", */ |
/* i, v[0], v[1], v[2], *(int *)&v[3]); */ |
} |
} |
} |
#else |
static void TAG(emit)( GLcontext *ctx, GLuint start, GLuint end, |
void *dest, GLuint stride ) |
{ |
LOCALVARS |
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; |
GLubyte (*col)[4]; |
GLuint col_stride; |
GLfloat *v = (GLfloat *)dest; |
int i; |
if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE) |
IMPORT_FLOAT_COLORS( ctx ); |
col = VB->ColorPtr[0]->Ptr; |
col_stride = VB->ColorPtr[0]->StrideB; |
if (start) |
STRIDE_4UB(col, col_stride * start); |
/* Need to figure out where color is: |
*/ |
if (GET_VERTEX_FORMAT() == TINY_VERTEX_FORMAT) |
v += 3; |
else |
v += 4; |
for (i=start; i < end; i++, STRIDE_F(v, stride)) { |
if (HAVE_RGBA_COLOR) { |
*(GLuint *)v = LE32_TO_CPU(*(GLuint *)col[0]); |
} |
else { |
VERTEX_COLOR *c = (VERTEX_COLOR *)v; |
c->blue = col[0][2]; |
c->green = col[0][1]; |
c->red = col[0][0]; |
c->alpha = col[0][3]; |
} |
STRIDE_4UB( col, col_stride ); |
} |
} |
#endif /* emit */ |
#endif /* emit */ |
#if (DO_XYZW) && (DO_RGBA) |
#if (HAVE_PTEX_VERTICES) |
static GLboolean TAG(check_tex_sizes)( GLcontext *ctx ) |
{ |
LOCALVARS |
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; |
/* Force 'missing' texcoords to something valid. |
*/ |
if (DO_TEX3 && VB->TexCoordPtr[2] == 0) |
VB->TexCoordPtr[2] = VB->TexCoordPtr[3]; |
if (DO_TEX2 && VB->TexCoordPtr[1] == 0) |
VB->TexCoordPtr[1] = VB->TexCoordPtr[2]; |
if (DO_TEX1 && VB->TexCoordPtr[0] == 0) |
VB->TexCoordPtr[0] = VB->TexCoordPtr[1]; |
if (DO_PTEX) |
return GL_TRUE; |
if ((DO_TEX3 && VB->TexCoordPtr[GET_TEXSOURCE(3)]->size == 4) || |
(DO_TEX2 && VB->TexCoordPtr[GET_TEXSOURCE(2)]->size == 4) || |
(DO_TEX1 && VB->TexCoordPtr[GET_TEXSOURCE(1)]->size == 4) || |
(DO_TEX0 && VB->TexCoordPtr[GET_TEXSOURCE(0)]->size == 4)) |
return GL_FALSE; |
return GL_TRUE; |
} |
#else |
static GLboolean TAG(check_tex_sizes)( GLcontext *ctx ) |
{ |
LOCALVARS |
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; |
/* Force 'missing' texcoords to something valid. |
*/ |
if (DO_TEX3 && VB->TexCoordPtr[2] == 0) |
VB->TexCoordPtr[2] = VB->TexCoordPtr[3]; |
if (DO_TEX2 && VB->TexCoordPtr[1] == 0) |
VB->TexCoordPtr[1] = VB->TexCoordPtr[2]; |
if (DO_TEX1 && VB->TexCoordPtr[0] == 0) |
VB->TexCoordPtr[0] = VB->TexCoordPtr[1]; |
if (DO_PTEX) |
return GL_TRUE; |
/* No hardware support for projective texture. Can fake it for |
* TEX0 only. |
*/ |
if ((DO_TEX3 && VB->TexCoordPtr[GET_TEXSOURCE(3)]->size == 4) || |
(DO_TEX2 && VB->TexCoordPtr[GET_TEXSOURCE(2)]->size == 4) || |
(DO_TEX1 && VB->TexCoordPtr[GET_TEXSOURCE(1)]->size == 4)) { |
PTEX_FALLBACK(); |
return GL_FALSE; |
} |
if (DO_TEX0 && VB->TexCoordPtr[GET_TEXSOURCE(0)]->size == 4) { |
if (DO_TEX1 || DO_TEX2 || DO_TEX3) { |
PTEX_FALLBACK(); |
} |
return GL_FALSE; |
} |
return GL_TRUE; |
} |
#endif /* ptex */ |
static void TAG(interp)( GLcontext *ctx, |
GLfloat t, |
GLuint edst, GLuint eout, GLuint ein, |
GLboolean force_boundary ) |
{ |
LOCALVARS |
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; |
GLubyte *ddverts = GET_VERTEX_STORE(); |
GLuint shift = GET_VERTEX_STRIDE_SHIFT(); |
const GLfloat *dstclip = VB->ClipPtr->data[edst]; |
GLfloat w; |
const GLfloat *s = GET_VIEWPORT_MAT(); |
VERTEX *dst = (VERTEX *)(ddverts + (edst << shift)); |
VERTEX *in = (VERTEX *)(ddverts + (ein << shift)); |
VERTEX *out = (VERTEX *)(ddverts + (eout << shift)); |
(void)s; |
if (HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) { |
VIEWPORT_X( dst->v.x, dstclip[0] ); |
VIEWPORT_Y( dst->v.y, dstclip[1] ); |
VIEWPORT_Z( dst->v.z, dstclip[2] ); |
w = dstclip[3]; |
} |
else { |
w = 1.0 / dstclip[3]; |
VIEWPORT_X( dst->v.x, dstclip[0] * w ); |
VIEWPORT_Y( dst->v.y, dstclip[1] * w ); |
VIEWPORT_Z( dst->v.z, dstclip[2] * w ); |
} |
if ((HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) || |
DO_FOG || DO_SPEC || DO_TEX0 || DO_TEX1 || |
DO_TEX2 || DO_TEX3 || !HAVE_TINY_VERTICES) { |
dst->v.w = w; |
INTERP_UB( t, dst->ub4[4][0], out->ub4[4][0], in->ub4[4][0] ); |
INTERP_UB( t, dst->ub4[4][1], out->ub4[4][1], in->ub4[4][1] ); |
INTERP_UB( t, dst->ub4[4][2], out->ub4[4][2], in->ub4[4][2] ); |
INTERP_UB( t, dst->ub4[4][3], out->ub4[4][3], in->ub4[4][3] ); |
if (DO_SPEC) { |
INTERP_UB( t, dst->v.specular.red, out->v.specular.red, in->v.specular.red ); |
INTERP_UB( t, dst->v.specular.green, out->v.specular.green, in->v.specular.green ); |
INTERP_UB( t, dst->v.specular.blue, out->v.specular.blue, in->v.specular.blue ); |
} |
if (DO_FOG) { |
INTERP_UB( t, dst->v.specular.alpha, out->v.specular.alpha, in->v.specular.alpha ); |
} |
if (DO_TEX0) { |
if (DO_PTEX) { |
if (HAVE_PTEX_VERTICES) { |
INTERP_F( t, dst->pv.u0, out->pv.u0, in->pv.u0 ); |
INTERP_F( t, dst->pv.v0, out->pv.v0, in->pv.v0 ); |
INTERP_F( t, dst->pv.q0, out->pv.q0, in->pv.q0 ); |
} else { |
GLfloat wout = VB->NdcPtr->data[eout][3]; |
GLfloat win = VB->NdcPtr->data[ein][3]; |
GLfloat qout = out->pv.w / wout; |
GLfloat qin = in->pv.w / win; |
GLfloat qdst, rqdst; |
ASSERT( !HAVE_HW_DIVIDE ); |
INTERP_F( t, dst->v.u0, out->v.u0 * qout, in->v.u0 * qin ); |
INTERP_F( t, dst->v.v0, out->v.v0 * qout, in->v.v0 * qin ); |
INTERP_F( t, qdst, qout, qin ); |
rqdst = 1.0 / qdst; |
dst->v.u0 *= rqdst; |
dst->v.v0 *= rqdst; |
dst->v.w *= rqdst; |
} |
} |
else { |
INTERP_F( t, dst->v.u0, out->v.u0, in->v.u0 ); |
INTERP_F( t, dst->v.v0, out->v.v0, in->v.v0 ); |
} |
} |
if (DO_TEX1) { |
if (DO_PTEX) { |
INTERP_F( t, dst->pv.u1, out->pv.u1, in->pv.u1 ); |
INTERP_F( t, dst->pv.v1, out->pv.v1, in->pv.v1 ); |
INTERP_F( t, dst->pv.q1, out->pv.q1, in->pv.q1 ); |
} else { |
INTERP_F( t, dst->v.u1, out->v.u1, in->v.u1 ); |
INTERP_F( t, dst->v.v1, out->v.v1, in->v.v1 ); |
} |
} |
else if (DO_PTEX) { |
dst->pv.q1 = 0.0; /* must be a valid float on radeon */ |
} |
if (DO_TEX2) { |
if (DO_PTEX) { |
INTERP_F( t, dst->pv.u2, out->pv.u2, in->pv.u2 ); |
INTERP_F( t, dst->pv.v2, out->pv.v2, in->pv.v2 ); |
INTERP_F( t, dst->pv.q2, out->pv.q2, in->pv.q2 ); |
} else { |
INTERP_F( t, dst->v.u2, out->v.u2, in->v.u2 ); |
INTERP_F( t, dst->v.v2, out->v.v2, in->v.v2 ); |
} |
} |
if (DO_TEX3) { |
if (DO_PTEX) { |
INTERP_F( t, dst->pv.u3, out->pv.u3, in->pv.u3 ); |
INTERP_F( t, dst->pv.v3, out->pv.v3, in->pv.v3 ); |
INTERP_F( t, dst->pv.q3, out->pv.q3, in->pv.q3 ); |
} else { |
INTERP_F( t, dst->v.u3, out->v.u3, in->v.u3 ); |
INTERP_F( t, dst->v.v3, out->v.v3, in->v.v3 ); |
} |
} |
} else { |
/* 4-dword vertex. Color is in v[3] and there is no oow coordinate. |
*/ |
INTERP_UB( t, dst->ub4[3][0], out->ub4[3][0], in->ub4[3][0] ); |
INTERP_UB( t, dst->ub4[3][1], out->ub4[3][1], in->ub4[3][1] ); |
INTERP_UB( t, dst->ub4[3][2], out->ub4[3][2], in->ub4[3][2] ); |
INTERP_UB( t, dst->ub4[3][3], out->ub4[3][3], in->ub4[3][3] ); |
} |
} |
#endif /* rgba && xyzw */ |
static void TAG(init)( void ) |
{ |
setup_tab[IND].emit = TAG(emit); |
#if (DO_XYZW && DO_RGBA) |
setup_tab[IND].check_tex_sizes = TAG(check_tex_sizes); |
setup_tab[IND].interp = TAG(interp); |
#endif |
if (DO_SPEC) |
setup_tab[IND].copy_pv = copy_pv_rgba4_spec5; |
else if (HAVE_HW_DIVIDE || DO_SPEC || DO_FOG || DO_TEX0 || DO_TEX1 || |
DO_TEX2 || DO_TEX3 || !HAVE_TINY_VERTICES) |
setup_tab[IND].copy_pv = copy_pv_rgba4; |
else |
setup_tab[IND].copy_pv = copy_pv_rgba3; |
if (DO_TEX3) { |
if (DO_PTEX) { |
ASSERT(HAVE_PTEX_VERTICES); |
setup_tab[IND].vertex_format = PROJ_TEX3_VERTEX_FORMAT; |
setup_tab[IND].vertex_size = 18; |
setup_tab[IND].vertex_stride_shift = 7; |
} |
else { |
setup_tab[IND].vertex_format = TEX3_VERTEX_FORMAT; |
setup_tab[IND].vertex_size = 14; |
setup_tab[IND].vertex_stride_shift = 6; |
} |
} |
else if (DO_TEX2) { |
if (DO_PTEX) { |
ASSERT(HAVE_PTEX_VERTICES); |
setup_tab[IND].vertex_format = PROJ_TEX3_VERTEX_FORMAT; |
setup_tab[IND].vertex_size = 18; |
setup_tab[IND].vertex_stride_shift = 7; |
} |
else { |
setup_tab[IND].vertex_format = TEX2_VERTEX_FORMAT; |
setup_tab[IND].vertex_size = 12; |
setup_tab[IND].vertex_stride_shift = 6; |
} |
} |
else if (DO_TEX1) { |
if (DO_PTEX) { |
ASSERT(HAVE_PTEX_VERTICES); |
setup_tab[IND].vertex_format = PROJ_TEX1_VERTEX_FORMAT; |
setup_tab[IND].vertex_size = 12; |
setup_tab[IND].vertex_stride_shift = 6; |
} |
else { |
setup_tab[IND].vertex_format = TEX1_VERTEX_FORMAT; |
setup_tab[IND].vertex_size = 10; |
setup_tab[IND].vertex_stride_shift = 6; |
} |
} |
else if (DO_TEX0) { |
if (DO_PTEX && HAVE_PTEX_VERTICES) { |
setup_tab[IND].vertex_format = PROJ_TEX1_VERTEX_FORMAT; |
setup_tab[IND].vertex_size = 12; |
setup_tab[IND].vertex_stride_shift = 6; |
} else { |
setup_tab[IND].vertex_format = TEX0_VERTEX_FORMAT; |
setup_tab[IND].vertex_size = 8; |
setup_tab[IND].vertex_stride_shift = 5; |
} |
} |
else if (!HAVE_HW_DIVIDE && !DO_SPEC && !DO_FOG && HAVE_TINY_VERTICES) { |
setup_tab[IND].vertex_format = TINY_VERTEX_FORMAT; |
setup_tab[IND].vertex_size = 4; |
setup_tab[IND].vertex_stride_shift = 4; |
} else if (HAVE_NOTEX_VERTICES) { |
setup_tab[IND].vertex_format = NOTEX_VERTEX_FORMAT; |
setup_tab[IND].vertex_size = 6; |
setup_tab[IND].vertex_stride_shift = 5; |
} else { |
setup_tab[IND].vertex_format = TEX0_VERTEX_FORMAT; |
setup_tab[IND].vertex_size = 8; |
setup_tab[IND].vertex_stride_shift = 5; |
} |
assert(setup_tab[IND].vertex_size * 4 <= |
1 << setup_tab[IND].vertex_stride_shift); |
} |
#undef IND |
#undef TAG |
/shark/trunk/ports/mesa/src/tnl_dd/t_dd.c |
---|
0,0 → 1,59 |
/* $Id: t_dd.c,v 1.1 2003-02-28 11:54:01 pj Exp $ */ |
/* |
* Mesa 3-D graphics library |
* Version: 3.5 |
* |
* 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> |
*/ |
static void copy_pv_rgba4_spec5( GLcontext *ctx, GLuint edst, GLuint esrc ) |
{ |
i810ContextPtr imesa = I810_CONTEXT( ctx ); |
GLubyte *i810verts = (GLubyte *)imesa->verts; |
GLuint shift = imesa->vertex_stride_shift; |
i810Vertex *dst = (i810Vertex *)(i810verts + (edst << shift)); |
i810Vertex *src = (i810Vertex *)(i810verts + (esrc << shift)); |
dst->ui[4] = src->ui[4]; |
dst->ui[5] = src->ui[5]; |
} |
static void copy_pv_rgba4( GLcontext *ctx, GLuint edst, GLuint esrc ) |
{ |
i810ContextPtr imesa = I810_CONTEXT( ctx ); |
GLubyte *i810verts = (GLubyte *)imesa->verts; |
GLuint shift = imesa->vertex_stride_shift; |
i810Vertex *dst = (i810Vertex *)(i810verts + (edst << shift)); |
i810Vertex *src = (i810Vertex *)(i810verts + (esrc << shift)); |
dst->ui[4] = src->ui[4]; |
} |
static void copy_pv_rgba3( GLcontext *ctx, GLuint edst, GLuint esrc ) |
{ |
i810ContextPtr imesa = I810_CONTEXT( ctx ); |
GLubyte *i810verts = (GLubyte *)imesa->verts; |
GLuint shift = imesa->vertex_stride_shift; |
i810Vertex *dst = (i810Vertex *)(i810verts + (edst << shift)); |
i810Vertex *src = (i810Vertex *)(i810verts + (esrc << shift)); |
dst->ui[3] = src->ui[3]; |
} |
/shark/trunk/ports/mesa/src/tnl_dd/t_dd_vertex.h |
---|
0,0 → 1,79 |
/* $Id: t_dd_vertex.h,v 1.1 2003-02-28 11:54:02 pj Exp $ */ |
/* |
* Mesa 3-D graphics library |
* Version: 4.0.3 |
* |
* Copyright (C) 1999-2002 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> |
*/ |
typedef struct { |
GLfloat x, y, z, w; |
} TAG(_coord_t); |
#ifdef COLOR_IS_RGBA |
typedef struct { |
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN |
GLubyte alpha, blue, green, red; |
#else |
GLubyte red, green, blue, alpha; |
#endif |
} TAG(_color_t); |
#else |
typedef struct { |
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN |
GLubyte alpha, red, green, blue; |
#else |
GLubyte blue, green, red, alpha; |
#endif |
} TAG(_color_t); |
#endif |
typedef union { |
struct { |
GLfloat x, y, z, w; |
TAG(_color_t) color; |
TAG(_color_t) specular; |
GLfloat u0, v0; |
GLfloat u1, v1; |
GLfloat u2, v2; |
GLfloat u3, v3; |
} v; |
struct { |
GLfloat x, y, z, w; |
TAG(_color_t) color; |
TAG(_color_t) specular; |
GLfloat u0, v0, q0; |
GLfloat u1, v1, q1; |
GLfloat u2, v2, q2; |
GLfloat u3, v3, q3; |
} pv; |
struct { |
GLfloat x, y, z; |
TAG(_color_t) color; |
} tv; |
GLfloat f[24]; |
GLuint ui[24]; |
GLubyte ub4[24][4]; |
} TAG(Vertex), *TAG(VertexPtr); |
/shark/trunk/ports/mesa/src/tnl_dd/t_dd_triemit.h |
---|
0,0 → 1,157 |
#ifndef DO_DEBUG_VERTS |
#define DO_DEBUG_VERTS 0 |
#endif |
#ifndef PRINT_VERTEX |
#define PRINT_VERTEX(x) |
#endif |
#if defined(USE_X86_ASM) |
#define COPY_DWORDS( j, vb, vertsize, v ) \ |
do { \ |
int __tmp; \ |
__asm__ __volatile__( "rep ; movsl" \ |
: "=%c" (j), "=D" (vb), "=S" (__tmp) \ |
: "0" (vertsize), \ |
"D" ((long)vb), \ |
"S" ((long)v) ); \ |
} while (0) |
#else |
#define COPY_DWORDS( j, vb, vertsize, v ) \ |
do { \ |
for ( j = 0 ; j < vertsize ; j++ ) \ |
vb[j] = ((GLuint *)v)[j]; \ |
vb += vertsize; \ |
} while (0) |
#endif |
#if HAVE_QUADS |
static __inline void TAG(quad)( CTX_ARG, |
VERTEX *v0, |
VERTEX *v1, |
VERTEX *v2, |
VERTEX *v3 ) |
{ |
GLuint vertsize = GET_VERTEX_DWORDS(); |
GLuint *vb = (GLuint *)ALLOC_VERTS( 4, vertsize); |
GLuint j; |
if (DO_DEBUG_VERTS) { |
fprintf(stderr, "%s\n", __FUNCTION__); |
PRINT_VERTEX(v0); |
PRINT_VERTEX(v1); |
PRINT_VERTEX(v2); |
PRINT_VERTEX(v3); |
} |
COPY_DWORDS( j, vb, vertsize, v0 ); |
COPY_DWORDS( j, vb, vertsize, v1 ); |
COPY_DWORDS( j, vb, vertsize, v2 ); |
COPY_DWORDS( j, vb, vertsize, v3 ); |
} |
#else |
static __inline void TAG(quad)( CTX_ARG, |
VERTEX *v0, |
VERTEX *v1, |
VERTEX *v2, |
VERTEX *v3 ) |
{ |
GLuint vertsize = GET_VERTEX_DWORDS(); |
GLuint *vb = (GLuint *)ALLOC_VERTS( 6, vertsize); |
GLuint j; |
if (DO_DEBUG_VERTS) { |
fprintf(stderr, "%s\n", __FUNCTION__); |
PRINT_VERTEX(v0); |
PRINT_VERTEX(v1); |
PRINT_VERTEX(v2); |
PRINT_VERTEX(v3); |
} |
COPY_DWORDS( j, vb, vertsize, v0 ); |
COPY_DWORDS( j, vb, vertsize, v1 ); |
COPY_DWORDS( j, vb, vertsize, v3 ); |
COPY_DWORDS( j, vb, vertsize, v1 ); |
COPY_DWORDS( j, vb, vertsize, v2 ); |
COPY_DWORDS( j, vb, vertsize, v3 ); |
} |
#endif |
static __inline void TAG(triangle)( CTX_ARG, |
VERTEX *v0, |
VERTEX *v1, |
VERTEX *v2 ) |
{ |
GLuint vertsize = GET_VERTEX_DWORDS(); |
GLuint *vb = (GLuint *)ALLOC_VERTS( 3, vertsize); |
GLuint j; |
if (DO_DEBUG_VERTS) { |
fprintf(stderr, "%s\n", __FUNCTION__); |
PRINT_VERTEX(v0); |
PRINT_VERTEX(v1); |
PRINT_VERTEX(v2); |
} |
COPY_DWORDS( j, vb, vertsize, v0 ); |
COPY_DWORDS( j, vb, vertsize, v1 ); |
COPY_DWORDS( j, vb, vertsize, v2 ); |
} |
#if HAVE_LINES |
static __inline void TAG(line)( CTX_ARG, |
VERTEX *v0, |
VERTEX *v1 ) |
{ |
GLuint vertsize = GET_VERTEX_DWORDS(); |
GLuint *vb = (GLuint *)ALLOC_VERTS( 2, vertsize); |
GLuint j; |
COPY_DWORDS( j, vb, vertsize, v0 ); |
COPY_DWORDS( j, vb, vertsize, v1 ); |
} |
#endif |
#if HAVE_POINTS |
static __inline void TAG(point)( CTX_ARG, |
VERTEX *v0 ) |
{ |
GLuint vertsize = GET_VERTEX_DWORDS(); |
GLuint *vb = (GLuint *)ALLOC_VERTS( 1, vertsize); |
int j; |
COPY_DWORDS( j, vb, vertsize, v0 ); |
} |
#endif |
static void TAG(fast_clipped_poly)( GLcontext *ctx, const GLuint *elts, |
GLuint n ) |
{ |
LOCAL_VARS |
GLuint vertsize = GET_VERTEX_DWORDS(); |
GLuint *vb = (GLuint *)ALLOC_VERTS( (n-2) * 3, vertsize ); |
const GLuint *start = (const GLuint *)VERT(elts[0]); |
int i,j; |
if (DO_DEBUG_VERTS) { |
fprintf(stderr, "%s\n", __FUNCTION__); |
PRINT_VERTEX(VERT(elts[0])); |
PRINT_VERTEX(VERT(elts[1])); |
} |
for (i = 2 ; i < n ; i++) { |
if (DO_DEBUG_VERTS) { |
PRINT_VERTEX(VERT(elts[i])); |
} |
COPY_DWORDS( j, vb, vertsize, VERT(elts[i-1]) ); |
COPY_DWORDS( j, vb, vertsize, VERT(elts[i]) ); |
COPY_DWORDS( j, vb, vertsize, start ); |
} |
} |