t_vb_rendertmp.h revision 7117f1b4
1/* 2 * Mesa 3-D graphics library 3 * Version: 6.5 4 * 5 * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: 25 * Keith Whitwell <keith@tungstengraphics.com> 26 */ 27 28 29#ifndef POSTFIX 30#define POSTFIX 31#endif 32 33#ifndef INIT 34#define INIT(x) 35#endif 36 37#ifndef NEED_EDGEFLAG_SETUP 38#define NEED_EDGEFLAG_SETUP 0 39#define EDGEFLAG_GET(a) 0 40#define EDGEFLAG_SET(a,b) (void)b 41#endif 42 43#ifndef RESET_STIPPLE 44#define RESET_STIPPLE 45#endif 46 47#ifndef TEST_PRIM_END 48#define TEST_PRIM_END(prim) (flags & PRIM_END) 49#define TEST_PRIM_BEGIN(prim) (flags & PRIM_BEGIN) 50#endif 51 52#ifndef ELT 53#define ELT(x) x 54#endif 55 56#ifndef RENDER_TAB_QUALIFIER 57#define RENDER_TAB_QUALIFIER static 58#endif 59 60static void TAG(render_points)( GLcontext *ctx, 61 GLuint start, 62 GLuint count, 63 GLuint flags ) 64{ 65 LOCAL_VARS; 66 (void) flags; 67 68 INIT(GL_POINTS); 69 RENDER_POINTS( start, count ); 70 POSTFIX; 71} 72 73static void TAG(render_lines)( GLcontext *ctx, 74 GLuint start, 75 GLuint count, 76 GLuint flags ) 77{ 78 GLuint j; 79 LOCAL_VARS; 80 (void) flags; 81 82 INIT(GL_LINES); 83 for (j=start+1; j<count; j+=2 ) { 84 RESET_STIPPLE; 85 RENDER_LINE( ELT(j-1), ELT(j) ); 86 } 87 POSTFIX; 88} 89 90 91static void TAG(render_line_strip)( GLcontext *ctx, 92 GLuint start, 93 GLuint count, 94 GLuint flags ) 95{ 96 GLuint j; 97 LOCAL_VARS; 98 (void) flags; 99 100 INIT(GL_LINE_STRIP); 101 102 if (TEST_PRIM_BEGIN(flags)) { 103 RESET_STIPPLE; 104 } 105 106 for (j=start+1; j<count; j++ ) 107 RENDER_LINE( ELT(j-1), ELT(j) ); 108 109 POSTFIX; 110} 111 112 113static void TAG(render_line_loop)( GLcontext *ctx, 114 GLuint start, 115 GLuint count, 116 GLuint flags ) 117{ 118 GLuint i; 119 LOCAL_VARS; 120 121 (void) flags; 122 123 INIT(GL_LINE_LOOP); 124 125 if (start+1 < count) { 126 if (TEST_PRIM_BEGIN(flags)) { 127 RESET_STIPPLE; 128 RENDER_LINE( ELT(start), ELT(start+1) ); 129 } 130 131 for ( i = start+2 ; i < count ; i++) { 132 RENDER_LINE( ELT(i-1), ELT(i) ); 133 } 134 135 if ( TEST_PRIM_END(flags)) { 136 RENDER_LINE( ELT(count-1), ELT(start) ); 137 } 138 } 139 140 POSTFIX; 141} 142 143 144static void TAG(render_triangles)( GLcontext *ctx, 145 GLuint start, 146 GLuint count, 147 GLuint flags ) 148{ 149 GLuint j; 150 LOCAL_VARS; 151 (void) flags; 152 153 INIT(GL_TRIANGLES); 154 if (NEED_EDGEFLAG_SETUP) { 155 for (j=start+2; j<count; j+=3) { 156 /* Leave the edgeflags as supplied by the user. 157 */ 158 RESET_STIPPLE; 159 RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) ); 160 } 161 } else { 162 for (j=start+2; j<count; j+=3) { 163 RENDER_TRI( ELT(j-2), ELT(j-1), ELT(j) ); 164 } 165 } 166 POSTFIX; 167} 168 169 170 171static void TAG(render_tri_strip)( GLcontext *ctx, 172 GLuint start, 173 GLuint count, 174 GLuint flags ) 175{ 176 GLuint j; 177 GLuint parity = 0; 178 LOCAL_VARS; 179 180 INIT(GL_TRIANGLE_STRIP); 181 if (NEED_EDGEFLAG_SETUP) { 182 for (j=start+2;j<count;j++,parity^=1) { 183 GLuint ej2 = ELT(j-2+parity); 184 GLuint ej1 = ELT(j-1-parity); 185 GLuint ej = ELT(j); 186 GLboolean ef2 = EDGEFLAG_GET( ej2 ); 187 GLboolean ef1 = EDGEFLAG_GET( ej1 ); 188 GLboolean ef = EDGEFLAG_GET( ej ); 189 if (TEST_PRIM_BEGIN(flags)) { 190 RESET_STIPPLE; 191 } 192 EDGEFLAG_SET( ej2, GL_TRUE ); 193 EDGEFLAG_SET( ej1, GL_TRUE ); 194 EDGEFLAG_SET( ej, GL_TRUE ); 195 RENDER_TRI( ej2, ej1, ej ); 196 EDGEFLAG_SET( ej2, ef2 ); 197 EDGEFLAG_SET( ej1, ef1 ); 198 EDGEFLAG_SET( ej, ef ); 199 } 200 } else { 201 for (j=start+2; j<count ; j++, parity^=1) { 202 RENDER_TRI( ELT(j-2+parity), ELT(j-1-parity), ELT(j) ); 203 } 204 } 205 POSTFIX; 206} 207 208 209static void TAG(render_tri_fan)( GLcontext *ctx, 210 GLuint start, 211 GLuint count, 212 GLuint flags ) 213{ 214 GLuint j; 215 LOCAL_VARS; 216 (void) flags; 217 218 INIT(GL_TRIANGLE_FAN); 219 if (NEED_EDGEFLAG_SETUP) { 220 for (j=start+2;j<count;j++) { 221 /* For trifans, all edges are boundary. 222 */ 223 GLuint ejs = ELT(start); 224 GLuint ej1 = ELT(j-1); 225 GLuint ej = ELT(j); 226 GLboolean efs = EDGEFLAG_GET( ejs ); 227 GLboolean ef1 = EDGEFLAG_GET( ej1 ); 228 GLboolean ef = EDGEFLAG_GET( ej ); 229 if (TEST_PRIM_BEGIN(flags)) { 230 RESET_STIPPLE; 231 } 232 EDGEFLAG_SET( ejs, GL_TRUE ); 233 EDGEFLAG_SET( ej1, GL_TRUE ); 234 EDGEFLAG_SET( ej, GL_TRUE ); 235 RENDER_TRI( ejs, ej1, ej); 236 EDGEFLAG_SET( ejs, efs ); 237 EDGEFLAG_SET( ej1, ef1 ); 238 EDGEFLAG_SET( ej, ef ); 239 } 240 } else { 241 for (j=start+2;j<count;j++) { 242 RENDER_TRI( ELT(start), ELT(j-1), ELT(j) ); 243 } 244 } 245 246 POSTFIX; 247} 248 249 250static void TAG(render_poly)( GLcontext *ctx, 251 GLuint start, 252 GLuint count, 253 GLuint flags ) 254{ 255 GLuint j = start+2; 256 LOCAL_VARS; 257 (void) flags; 258 259 INIT(GL_POLYGON); 260 if (NEED_EDGEFLAG_SETUP) { 261 GLboolean efstart = EDGEFLAG_GET( ELT(start) ); 262 GLboolean efcount = EDGEFLAG_GET( ELT(count-1) ); 263 264 /* If the primitive does not begin here, the first edge 265 * is non-boundary. 266 */ 267 if (!TEST_PRIM_BEGIN(flags)) 268 EDGEFLAG_SET( ELT(start), GL_FALSE ); 269 else { 270 RESET_STIPPLE; 271 } 272 273 /* If the primitive does not end here, the final edge is 274 * non-boundary. 275 */ 276 if (!TEST_PRIM_END(flags)) 277 EDGEFLAG_SET( ELT(count-1), GL_FALSE ); 278 279 /* Draw the first triangles (possibly zero) 280 */ 281 if (j+1<count) { 282 GLboolean ef = EDGEFLAG_GET( ELT(j) ); 283 EDGEFLAG_SET( ELT(j), GL_FALSE ); 284 RENDER_TRI( ELT(j-1), ELT(j), ELT(start) ); 285 EDGEFLAG_SET( ELT(j), ef ); 286 j++; 287 288 /* Don't render the first edge again: 289 */ 290 EDGEFLAG_SET( ELT(start), GL_FALSE ); 291 292 for (;j+1<count;j++) { 293 GLboolean efj = EDGEFLAG_GET( ELT(j) ); 294 EDGEFLAG_SET( ELT(j), GL_FALSE ); 295 RENDER_TRI( ELT(j-1), ELT(j), ELT(start) ); 296 EDGEFLAG_SET( ELT(j), efj ); 297 } 298 } 299 300 /* Draw the last or only triangle 301 */ 302 if (j < count) 303 RENDER_TRI( ELT(j-1), ELT(j), ELT(start) ); 304 305 /* Restore the first and last edgeflags: 306 */ 307 EDGEFLAG_SET( ELT(count-1), efcount ); 308 EDGEFLAG_SET( ELT(start), efstart ); 309 310 } 311 else { 312 for (j=start+2;j<count;j++) { 313 RENDER_TRI( ELT(j-1), ELT(j), ELT(start) ); 314 } 315 } 316 POSTFIX; 317} 318 319static void TAG(render_quads)( GLcontext *ctx, 320 GLuint start, 321 GLuint count, 322 GLuint flags ) 323{ 324 GLuint j; 325 LOCAL_VARS; 326 (void) flags; 327 328 INIT(GL_QUADS); 329 if (NEED_EDGEFLAG_SETUP) { 330 for (j=start+3; j<count; j+=4) { 331 /* Use user-specified edgeflags for quads. 332 */ 333 RESET_STIPPLE; 334 RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) ); 335 } 336 } else { 337 for (j=start+3; j<count; j+=4) { 338 RENDER_QUAD( ELT(j-3), ELT(j-2), ELT(j-1), ELT(j) ); 339 } 340 } 341 POSTFIX; 342} 343 344static void TAG(render_quad_strip)( GLcontext *ctx, 345 GLuint start, 346 GLuint count, 347 GLuint flags ) 348{ 349 GLuint j; 350 LOCAL_VARS; 351 (void) flags; 352 353 INIT(GL_QUAD_STRIP); 354 if (NEED_EDGEFLAG_SETUP) { 355 for (j=start+3;j<count;j+=2) { 356 /* All edges are boundary. Set edgeflags to 1, draw the 357 * quad, and restore them to the original values. 358 */ 359 GLboolean ef3 = EDGEFLAG_GET( ELT(j-3) ); 360 GLboolean ef2 = EDGEFLAG_GET( ELT(j-2) ); 361 GLboolean ef1 = EDGEFLAG_GET( ELT(j-1) ); 362 GLboolean ef = EDGEFLAG_GET( ELT(j) ); 363 if (TEST_PRIM_BEGIN(flags)) { 364 RESET_STIPPLE; 365 } 366 EDGEFLAG_SET( ELT(j-3), GL_TRUE ); 367 EDGEFLAG_SET( ELT(j-2), GL_TRUE ); 368 EDGEFLAG_SET( ELT(j-1), GL_TRUE ); 369 EDGEFLAG_SET( ELT(j), GL_TRUE ); 370 RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) ); 371 EDGEFLAG_SET( ELT(j-3), ef3 ); 372 EDGEFLAG_SET( ELT(j-2), ef2 ); 373 EDGEFLAG_SET( ELT(j-1), ef1 ); 374 EDGEFLAG_SET( ELT(j), ef ); 375 } 376 } else { 377 for (j=start+3;j<count;j+=2) { 378 RENDER_QUAD( ELT(j-1), ELT(j-3), ELT(j-2), ELT(j) ); 379 } 380 } 381 POSTFIX; 382} 383 384static void TAG(render_noop)( GLcontext *ctx, 385 GLuint start, 386 GLuint count, 387 GLuint flags ) 388{ 389 (void)(ctx && start && count && flags); 390} 391 392RENDER_TAB_QUALIFIER void (*TAG(render_tab)[GL_POLYGON+2])(GLcontext *, 393 GLuint, 394 GLuint, 395 GLuint) = 396{ 397 TAG(render_points), 398 TAG(render_lines), 399 TAG(render_line_loop), 400 TAG(render_line_strip), 401 TAG(render_triangles), 402 TAG(render_tri_strip), 403 TAG(render_tri_fan), 404 TAG(render_quads), 405 TAG(render_quad_strip), 406 TAG(render_poly), 407 TAG(render_noop), 408}; 409 410 411 412#ifndef PRESERVE_VB_DEFS 413#undef RENDER_TRI 414#undef RENDER_QUAD 415#undef RENDER_LINE 416#undef RENDER_POINTS 417#undef LOCAL_VARS 418#undef INIT 419#undef POSTFIX 420#undef RESET_STIPPLE 421#undef DBG 422#undef ELT 423#undef RENDER_TAB_QUALIFIER 424#endif 425 426#ifndef PRESERVE_TAG 427#undef TAG 428#endif 429 430#undef PRESERVE_VB_DEFS 431#undef PRESERVE_TAG 432