1 /* $Id: vbfill.c,v 1.22 1998/01/27 03:30:18 brianp Exp $ */ 2 3 /* 4 * Mesa 3-D graphics library 5 * Version: 2.6 6 * Copyright (C) 1995-1997 Brian Paul 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Library General Public 10 * License as published by the Free Software Foundation; either 11 * version 2 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Library General Public License for more details. 17 * 18 * You should have received a copy of the GNU Library General Public 19 * License along with this library; if not, write to the Free 20 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 */ 22 23 24 /* 25 * $Log: vbfill.c,v $ 26 * Revision 1.22 1998/01/27 03:30:18 brianp 27 * minor tweak to FLOAT_COLOR_TO_UBYTE_COLOR macro: added an F suffix 28 * 29 * Revision 1.21 1998/01/25 16:59:13 brianp 30 * changed IEEE_ONE value to 0x3f7f0000 (Josh Vanderhoof) 31 * 32 * Revision 1.20 1998/01/16 01:29:29 brianp 33 * added DavidB's assembly language version of gl_Color3f() 34 * 35 * Revision 1.19 1998/01/09 02:40:43 brianp 36 * IEEE-optimized glColor[34]f[v]() commands (Josh Vanderhoof) 37 * 38 * Revision 1.18 1997/12/18 02:54:48 brianp 39 * now using FloatToInt() macro for better performance on x86 40 * 41 * Revision 1.17 1997/11/14 03:02:53 brianp 42 * clamp floating point color components to [0,1] before int conversion 43 * 44 * Revision 1.16 1997/08/13 01:31:11 brianp 45 * LightTwoSide is now a GLboolean 46 * 47 * Revision 1.15 1997/07/24 01:25:27 brianp 48 * changed precompiled header symbol from PCH to PC_HEADER 49 * 50 * Revision 1.14 1997/06/20 02:47:41 brianp 51 * added Color4ubv API pointer 52 * 53 * Revision 1.13 1997/06/20 02:46:49 brianp 54 * changed color components from GLfixed to GLubyte 55 * 56 * Revision 1.12 1997/05/28 03:26:49 brianp 57 * added precompiled header (PCH) support 58 * 59 * Revision 1.11 1997/05/27 03:13:41 brianp 60 * removed some debugging code 61 * 62 * Revision 1.10 1997/04/28 02:05:44 brianp 63 * renamed some vertex functions, also save color with texcoords 64 * 65 * Revision 1.9 1997/04/24 01:50:53 brianp 66 * optimized glColor3f, glColor3fv, glColor4fv 67 * 68 * Revision 1.8 1997/04/24 00:30:17 brianp 69 * optimized glTexCoord2() code 70 * 71 * Revision 1.7 1997/04/20 15:59:30 brianp 72 * removed VERTEX2_BIT stuff 73 * 74 * Revision 1.6 1997/04/16 23:55:33 brianp 75 * added optimized glTexCoord2f code 76 * 77 * Revision 1.5 1997/04/14 22:18:23 brianp 78 * added optimized glVertex3fv code 79 * 80 * Revision 1.4 1997/04/12 16:21:54 brianp 81 * added ctx->Exec.Vertex2f = vertex2_feedback; statement 82 * 83 * Revision 1.3 1997/04/12 12:23:26 brianp 84 * fixed 3 bugs in gl_eval_vertex 85 * 86 * Revision 1.2 1997/04/07 03:01:11 brianp 87 * optimized vertex[234] code 88 * 89 * Revision 1.1 1997/04/02 03:13:56 brianp 90 * Initial revision 91 * 92 */ 93 94 95 /* 96 * This file implements the functions for filling the vertex buffer: 97 * glVertex, glNormal, glColor, glIndex, glEdgeFlag, glTexCoord, 98 */ 99 100 101 #ifdef PC_HEADER 102 #include "all.h" 103 #else 104 #include <assert.h> 105 #include "context.h" 106 #include "light.h" 107 #include "clip.h" 108 #include "dlist.h" 109 #include "feedback.h" 110 #include "macros.h" 111 #include "matrix.h" 112 #include "mmath.h" 113 #include "pb.h" 114 #include "types.h" 115 #include "vb.h" 116 #include "vbfill.h" 117 #include "vbxform.h" 118 #include "xform.h" 119 #endif 120 121 122 123 /**********************************************************************/ 124 /****** glNormal functions *****/ 125 /**********************************************************************/ 126 127 /* 128 * Caller: context->API.Normal3f pointer. 129 */ 130 void gl_Normal3f( GLcontext *ctx, GLfloat nx, GLfloat ny, GLfloat nz ) 131 { 132 ctx->Current.Normal[0] = nx; 133 ctx->Current.Normal[1] = ny; 134 ctx->Current.Normal[2] = nz; 135 ctx->VB->MonoNormal = GL_FALSE; 136 } 137 138 139 /* 140 * Caller: context->API.Normal3fv pointer. 141 */ 142 void gl_Normal3fv( GLcontext *ctx, const GLfloat *n ) 143 { 144 ctx->Current.Normal[0] = n[0]; 145 ctx->Current.Normal[1] = n[1]; 146 ctx->Current.Normal[2] = n[2]; 147 ctx->VB->MonoNormal = GL_FALSE; 148 } 149 150 151 152 /**********************************************************************/ 153 /****** glIndex functions *****/ 154 /**********************************************************************/ 155 156 /* 157 * Caller: context->API.Indexf pointer. 158 */ 159 void gl_Indexf( GLcontext *ctx, GLfloat c ) 160 { 161 ctx->Current.Index = (GLuint) (GLint) c; 162 ctx->VB->MonoColor = GL_FALSE; 163 } 164 165 166 /* 167 * Caller: context->API.Indexi pointer. 168 */ 169 void gl_Indexi( GLcontext *ctx, GLint c ) 170 { 171 ctx->Current.Index = (GLuint) c; 172 ctx->VB->MonoColor = GL_FALSE; 173 } 174 175 176 177 /**********************************************************************/ 178 /****** glColor functions *****/ 179 /**********************************************************************/ 180 181 182 #if defined(__i386__) 183 #define USE_IEEE 184 #endif 185 186 #if defined(USE_IEEE) && !defined(DEBUG) && 0 187 188 #define IEEE_ONE 0x3f7f0000 189 190 /* 191 * Optimization for: 192 * GLfloat f; 193 * GLubyte b = FloatToInt(CLAMP(f, 0, 1) * 255) 194 */ 195 #define FLOAT_COLOR_TO_UBYTE_COLOR(b, f) \ 196 { \ 197 GLfloat tmp = f + 32768.0F; \ 198 b = ((*(GLuint *)&f >= IEEE_ONE) \ 199 ? (*(GLint *)&f < 0) ? (GLubyte)0 : (GLubyte)255 \ 200 : (GLubyte)*(GLuint *)&tmp); \ 201 } 202 203 #else 204 205 #define FLOAT_COLOR_TO_UBYTE_COLOR(b, f) \ 206 b = FloatToInt(CLAMP(f, 0.0F, 1.0F) * 255.0F) 207 208 #endif 209 210 211 212 /* 213 * Used when colors are not scaled to [0,255]. 214 * Caller: context->API.Color3f pointer. 215 */ 216 void gl_Color3f( GLcontext *ctx, GLfloat red, GLfloat green, GLfloat blue ) 217 { 218 ctx->Current.ByteColor[0] = FloatToInt(CLAMP(red , 0.0F, 1.0F) * ctx->Visual->RedScale); 219 ctx->Current.ByteColor[1] = FloatToInt(CLAMP(green, 0.0F, 1.0F) * ctx->Visual->GreenScale); 220 ctx->Current.ByteColor[2] = FloatToInt(CLAMP(blue , 0.0F, 1.0F) * ctx->Visual->BlueScale); 221 ctx->Current.ByteColor[3] = FloatToInt(ctx->Visual->AlphaScale); 222 ASSERT( !ctx->Light.ColorMaterialEnabled ); 223 ctx->VB->MonoColor = GL_FALSE; 224 } 225 226 227 /* 228 * Used when colors are scaled to [0,255]. 229 * Caller: context->API.Color3f pointer. 230 */ 231 void gl_Color3f8bit( GLcontext *ctx, GLfloat red, GLfloat green, GLfloat blue ) 232 { 233 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[0], red); 234 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[1], green); 235 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[2], blue); 236 ctx->Current.ByteColor[3] = 255; 237 ASSERT( !ctx->Light.ColorMaterialEnabled ); 238 ctx->VB->MonoColor = GL_FALSE; 239 } 240 241 242 /* 243 * Used when colors are not scaled to [0,255]. 244 * Caller: context->API.Color3fv pointer. 245 */ 246 void gl_Color3fv( GLcontext *ctx, const GLfloat *c ) 247 { 248 ctx->Current.ByteColor[0] = FloatToInt(CLAMP(c[0], 0.0F, 1.0F) * ctx->Visual->RedScale); 249 ctx->Current.ByteColor[1] = FloatToInt(CLAMP(c[1], 0.0F, 1.0F) * ctx->Visual->GreenScale); 250 ctx->Current.ByteColor[2] = FloatToInt(CLAMP(c[2], 0.0F, 1.0F) * ctx->Visual->BlueScale); 251 ctx->Current.ByteColor[3] = FloatToInt(ctx->Visual->AlphaScale); 252 ASSERT( !ctx->Light.ColorMaterialEnabled ); 253 ctx->VB->MonoColor = GL_FALSE; 254 } 255 256 257 /* 258 * Used when colors are scaled to [0,255]. 259 * Caller: context->API.Color3fv pointer. 260 */ 261 void gl_Color3fv8bit( GLcontext *ctx, const GLfloat *c ) 262 { 263 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[0], c[0]); 264 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[1], c[1]); 265 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[2], c[2]); 266 ctx->Current.ByteColor[3] = 255; 267 ASSERT( !ctx->Light.ColorMaterialEnabled ); 268 ctx->VB->MonoColor = GL_FALSE; 269 } 270 271 272 273 /* 274 * Used when colors are not scaled to [0,255]. 275 * Caller: context->API.Color4f pointer. 276 */ 277 void gl_Color4f( GLcontext *ctx, 278 GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ) 279 { 280 ctx->Current.ByteColor[0] = FloatToInt(CLAMP(red , 0.0F, 1.0F) * ctx->Visual->RedScale); 281 ctx->Current.ByteColor[1] = FloatToInt(CLAMP(green, 0.0F, 1.0F) * ctx->Visual->GreenScale); 282 ctx->Current.ByteColor[2] = FloatToInt(CLAMP(blue , 0.0F, 1.0F) * ctx->Visual->BlueScale); 283 ctx->Current.ByteColor[3] = FloatToInt(CLAMP(alpha, 0.0F, 1.0F) * ctx->Visual->AlphaScale); 284 ASSERT( !ctx->Light.ColorMaterialEnabled ); 285 ctx->VB->MonoColor = GL_FALSE; 286 } 287 288 289 /* 290 * Used when colors are scaled to [0,255]. 291 * Caller: context->API.Color4f pointer. 292 */ 293 void gl_Color4f8bit( GLcontext *ctx, 294 GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ) 295 { 296 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[0], red); 297 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[1], green); 298 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[2], blue); 299 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[3], alpha); 300 ASSERT( !ctx->Light.ColorMaterialEnabled ); 301 ctx->VB->MonoColor = GL_FALSE; 302 } 303 304 305 /* 306 * Used when colors are not scaled to [0,255]. 307 * Caller: context->API.Color4fv pointer. 308 */ 309 void gl_Color4fv( GLcontext *ctx, const GLfloat *c ) 310 { 311 ctx->Current.ByteColor[0] = FloatToInt(CLAMP(c[0], 0.0F, 1.0F) * ctx->Visual->RedScale); 312 ctx->Current.ByteColor[1] = FloatToInt(CLAMP(c[1], 0.0F, 1.0F) * ctx->Visual->GreenScale); 313 ctx->Current.ByteColor[2] = FloatToInt(CLAMP(c[2], 0.0F, 1.0F) * ctx->Visual->BlueScale); 314 ctx->Current.ByteColor[3] = FloatToInt(CLAMP(c[3], 0.0F, 1.0F) * ctx->Visual->AlphaScale); 315 ASSERT( !ctx->Light.ColorMaterialEnabled ); 316 ctx->VB->MonoColor = GL_FALSE; 317 } 318 319 320 /* 321 * Used when colors are scaled to [0,255]. 322 * Caller: context->API.Color4fv pointer. 323 */ 324 void gl_Color4fv8bit( GLcontext *ctx, const GLfloat *c ) 325 { 326 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[0], c[0]); 327 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[1], c[1]); 328 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[2], c[2]); 329 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Current.ByteColor[3], c[3]); 330 ASSERT( !ctx->Light.ColorMaterialEnabled ); 331 ctx->VB->MonoColor = GL_FALSE; 332 } 333 334 335 /* 336 * Used when colors are not scaled to [0,255] 337 * Caller: context->API.Color4ub pointer. 338 */ 339 void gl_Color4ub( GLcontext *ctx, 340 GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha ) 341 { 342 ctx->Current.ByteColor[0] = red * ctx->Visual->RedScale * (1.0F/255.0F); 343 ctx->Current.ByteColor[1] = green * ctx->Visual->GreenScale * (1.0F/255.0F); 344 ctx->Current.ByteColor[2] = blue * ctx->Visual->BlueScale * (1.0F/255.0F); 345 ctx->Current.ByteColor[3] = alpha * ctx->Visual->AlphaScale * (1.0F/255.0F); 346 ASSERT( !ctx->Light.ColorMaterialEnabled ); 347 ctx->VB->MonoColor = GL_FALSE; 348 } 349 350 351 /* 352 * Used when colors are scaled to [0,255]. 353 * Caller: context->API.Color4ub pointer. 354 */ 355 void gl_Color4ub8bit( GLcontext *ctx, 356 GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha ) 357 { 358 ASSIGN_4V( ctx->Current.ByteColor, red, green, blue, alpha ); 359 ASSERT( !ctx->Light.ColorMaterialEnabled ); 360 ctx->VB->MonoColor = GL_FALSE; 361 } 362 363 364 /* 365 * Used when colors are not scaled to [0,255] 366 * Caller: context->API.Color4ub pointer. 367 */ 368 void gl_Color4ubv( GLcontext *ctx, const GLubyte *c ) 369 { 370 ctx->Current.ByteColor[0] = c[0] * ctx->Visual->RedScale * (1.0F/255.0F); 371 ctx->Current.ByteColor[1] = c[1] * ctx->Visual->GreenScale * (1.0F/255.0F); 372 ctx->Current.ByteColor[2] = c[2] * ctx->Visual->BlueScale * (1.0F/255.0F); 373 ctx->Current.ByteColor[3] = c[3] * ctx->Visual->AlphaScale * (1.0F/255.0F); 374 ASSERT( !ctx->Light.ColorMaterialEnabled ); 375 ctx->VB->MonoColor = GL_FALSE; 376 } 377 378 379 /* 380 * This is the most efficient glColor*() command! 381 * Used when colors are scaled to [0,255]. 382 * Caller: context->API.Color4ub pointer. 383 */ 384 void gl_Color4ubv8bit( GLcontext *ctx, const GLubyte *c ) 385 { 386 COPY_4UBV( ctx->Current.ByteColor, c ); 387 ASSERT( !ctx->Light.ColorMaterialEnabled ); 388 ctx->VB->MonoColor = GL_FALSE; 389 } 390 391 392 /* 393 * glColor() which modifies material(s). 394 * Caller: context->API.Color3f pointer. 395 */ 396 void gl_ColorMat3f( GLcontext *ctx, GLfloat red, GLfloat green, GLfloat blue ) 397 { 398 GLfloat color[4]; 399 ctx->Current.ByteColor[0] = FloatToInt(CLAMP(red , 0.0F, 1.0F) * ctx->Visual->RedScale); 400 ctx->Current.ByteColor[1] = FloatToInt(CLAMP(green, 0.0F, 1.0F) * ctx->Visual->GreenScale); 401 ctx->Current.ByteColor[2] = FloatToInt(CLAMP(blue , 0.0F, 1.0F) * ctx->Visual->BlueScale); 402 ctx->Current.ByteColor[3] = FloatToInt(ctx->Visual->AlphaScale); 403 /* update material */ 404 ASSERT( ctx->Light.ColorMaterialEnabled ); 405 ASSIGN_4V( color, red, green, blue, 1.0F ); 406 gl_set_material( ctx, ctx->Light.ColorMaterialBitmask, color ); 407 ctx->VB->MonoColor = GL_FALSE; 408 } 409 410 411 /* 412 * glColor() which modifies material(s). 413 * Caller: context->API.Color3fv pointer. 414 */ 415 void gl_ColorMat3fv( GLcontext *ctx, const GLfloat *c ) 416 { 417 GLfloat color[4]; 418 ctx->Current.ByteColor[0] = FloatToInt(CLAMP(c[0], 0.0F, 1.0F) * ctx->Visual->RedScale); 419 ctx->Current.ByteColor[1] = FloatToInt(CLAMP(c[1], 0.0F, 1.0F) * ctx->Visual->GreenScale); 420 ctx->Current.ByteColor[2] = FloatToInt(CLAMP(c[2], 0.0F, 1.0F) * ctx->Visual->BlueScale); 421 ctx->Current.ByteColor[3] = FloatToInt(ctx->Visual->AlphaScale); 422 /* update material */ 423 ASSERT( ctx->Light.ColorMaterialEnabled ); 424 ASSIGN_4V( color, c[0], c[1], c[2], 1.0F ); 425 gl_set_material( ctx, ctx->Light.ColorMaterialBitmask, color ); 426 ctx->VB->MonoColor = GL_FALSE; 427 } 428 429 430 /* 431 * glColor() which modifies material(s). 432 * Caller: context->API.Color4f pointer. 433 */ 434 void gl_ColorMat4f( GLcontext *ctx, 435 GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ) 436 { 437 GLfloat color[4]; 438 ctx->Current.ByteColor[0] = FloatToInt(CLAMP(red , 0.0F, 1.0F) * ctx->Visual->RedScale); 439 ctx->Current.ByteColor[1] = FloatToInt(CLAMP(green, 0.0F, 1.0F) * ctx->Visual->GreenScale); 440 ctx->Current.ByteColor[2] = FloatToInt(CLAMP(blue , 0.0F, 1.0F) * ctx->Visual->BlueScale); 441 ctx->Current.ByteColor[3] = FloatToInt(CLAMP(alpha, 0.0F, 1.0F) * ctx->Visual->AlphaScale); 442 /* update material */ 443 ASSERT( ctx->Light.ColorMaterialEnabled ); 444 ASSIGN_4V( color, red, green, blue, alpha ); 445 gl_set_material( ctx, ctx->Light.ColorMaterialBitmask, color ); 446 ctx->VB->MonoColor = GL_FALSE; 447 } 448 449 450 /* 451 * glColor() which modifies material(s). 452 * Caller: context->API.Color4fv pointer. 453 */ 454 void gl_ColorMat4fv( GLcontext *ctx, const GLfloat *c ) 455 { 456 GLfloat color[4]; 457 ctx->Current.ByteColor[0] = FloatToInt(CLAMP(c[0], 0.0F, 1.0F) * ctx->Visual->RedScale); 458 ctx->Current.ByteColor[1] = FloatToInt(CLAMP(c[1], 0.0F, 1.0F) * ctx->Visual->GreenScale); 459 ctx->Current.ByteColor[2] = FloatToInt(CLAMP(c[2], 0.0F, 1.0F) * ctx->Visual->BlueScale); 460 ctx->Current.ByteColor[3] = FloatToInt(CLAMP(c[3], 0.0F, 1.0F) * ctx->Visual->AlphaScale); 461 /* update material */ 462 ASSERT( ctx->Light.ColorMaterialEnabled ); 463 ASSIGN_4V( color, c[0], c[1], c[2], c[3] ); 464 gl_set_material( ctx, ctx->Light.ColorMaterialBitmask, color ); 465 ctx->VB->MonoColor = GL_FALSE; 466 } 467 468 469 /* 470 * glColor which modifies material(s). 471 * Caller: context->API.Color4ub pointer. 472 */ 473 void gl_ColorMat4ub( GLcontext *ctx, 474 GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha ) 475 { 476 GLfloat color[4]; 477 if (ctx->Visual->EightBitColor) { 478 ASSIGN_4V( ctx->Current.ByteColor, red, green, blue, alpha ); 479 } 480 else { 481 ctx->Current.ByteColor[0] = red * ctx->Visual->RedScale * (1.0F/255.0F); 482 ctx->Current.ByteColor[1] = green * ctx->Visual->GreenScale * (1.0F/255.0F); 483 ctx->Current.ByteColor[2] = blue * ctx->Visual->BlueScale * (1.0F/255.0F); 484 ctx->Current.ByteColor[3] = alpha * ctx->Visual->AlphaScale * (1.0F/255.0F); 485 } 486 /* update material */ 487 ASSERT( ctx->Light.ColorMaterialEnabled ); 488 color[0] = red * (1.0F/255.0F); 489 color[1] = green * (1.0F/255.0F); 490 color[2] = blue * (1.0F/255.0F); 491 color[3] = alpha * (1.0F/255.0F); 492 gl_set_material( ctx, ctx->Light.ColorMaterialBitmask, color ); 493 ctx->VB->MonoColor = GL_FALSE; 494 } 495 496 497 /* 498 * glColor which modifies material(s). 499 * Caller: context->API.Color4ub pointer. 500 */ 501 void gl_ColorMat4ubv( GLcontext *ctx, const GLubyte *c ) 502 { 503 gl_ColorMat4ub( ctx, c[0], c[1], c[2], c[3] ); 504 } 505 506 507 508 /**********************************************************************/ 509 /****** glEdgeFlag functions *****/ 510 /**********************************************************************/ 511 512 /* 513 * Caller: context->API.EdgeFlag pointer. 514 */ 515 void gl_EdgeFlag( GLcontext *ctx, GLboolean flag ) 516 { 517 ctx->Current.EdgeFlag = flag; 518 } 519 520 521 522 /**********************************************************************/ 523 /***** glVertex functions *****/ 524 /**********************************************************************/ 525 526 /* 527 * Used when in feedback mode. 528 * Caller: context->API.Vertex4f pointer. 529 */ 530 static void vertex4f_feedback( GLcontext *ctx, 531 GLfloat x, GLfloat y, GLfloat z, GLfloat w ) 532 { 533 struct vertex_buffer *VB = ctx->VB; 534 GLuint count = VB->Count; 535 536 /* vertex */ 537 ASSIGN_4V( VB->Obj[count], x, y, z, w ); 538 539 /* color */ 540 COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor ); 541 542 /* index */ 543 VB->Findex[count] = ctx->Current.Index; 544 545 /* normal */ 546 COPY_3V( VB->Normal[count], ctx->Current.Normal ); 547 548 /* texcoord */ 549 COPY_4V( VB->TexCoord[count], ctx->Current.TexCoord ); 550 551 /* edgeflag */ 552 VB->Edgeflag[count] = ctx->Current.EdgeFlag; 553 554 count++; 555 VB->Count = count; 556 if (count==VB_MAX) { 557 gl_transform_vb_part1( ctx, GL_FALSE ); 558 } 559 } 560 561 562 static void vertex3f_feedback( GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z ) 563 { 564 vertex4f_feedback(ctx, x, y, z, 1.0F); 565 } 566 567 568 static void vertex2f_feedback( GLcontext *ctx, GLfloat x, GLfloat y ) 569 { 570 vertex4f_feedback(ctx, x, y, 0.0F, 1.0F); 571 } 572 573 574 static void vertex3fv_feedback( GLcontext *ctx, const GLfloat v[3] ) 575 { 576 vertex4f_feedback(ctx, v[0], v[1], v[2], 1.0F); 577 } 578 579 580 581 /* 582 * Only one glVertex4 function since it's not too popular. 583 * Caller: context->API.Vertex4f pointer. 584 */ 585 static void vertex4( GLcontext *ctx, 586 GLfloat x, GLfloat y, GLfloat z, GLfloat w ) 587 { 588 struct vertex_buffer *VB = ctx->VB; 589 GLuint count = VB->Count; 590 591 ASSIGN_4V( VB->Obj[count], x, y, z, w ); 592 COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor ); 593 COPY_3V( VB->Normal[count], ctx->Current.Normal ); 594 COPY_4V( VB->TexCoord[count], ctx->Current.TexCoord ); 595 VB->Edgeflag[count] = ctx->Current.EdgeFlag; 596 VB->VertexSizeMask = VERTEX4_BIT; 597 598 count++; 599 VB->Count = count; 600 if (count==VB_MAX) { 601 gl_transform_vb_part1( ctx, GL_FALSE ); 602 } 603 } 604 605 606 607 /* 608 * XYZ vertex, RGB color, normal, ST texture coords. 609 * Caller: context->API.Vertex3f pointer. 610 */ 611 static void vertex3f_normal_color_tex2( GLcontext *ctx, 612 GLfloat x, GLfloat y, GLfloat z ) 613 { 614 struct vertex_buffer *VB = ctx->VB; 615 GLuint count = VB->Count; 616 617 ASSIGN_3V( VB->Obj[count], x, y, z ); 618 COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor ); 619 COPY_3V( VB->Normal[count], ctx->Current.Normal ); 620 COPY_2V( VB->TexCoord[count], ctx->Current.TexCoord ); 621 VB->Edgeflag[count] = ctx->Current.EdgeFlag; 622 623 count++; 624 VB->Count = count; 625 if (count==VB_MAX) { 626 gl_transform_vb_part1( ctx, GL_FALSE ); 627 } 628 } 629 630 631 /* 632 * XYZ vertex, RGB color, normal, STRQ texture coords. 633 * Caller: context->API.Vertex3f pointer. 634 */ 635 static void vertex3f_normal_color_tex4( GLcontext *ctx, 636 GLfloat x, GLfloat y, GLfloat z ) 637 { 638 struct vertex_buffer *VB = ctx->VB; 639 GLuint count = VB->Count; 640 641 ASSIGN_3V( VB->Obj[count], x, y, z ); 642 COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor ); 643 COPY_3V( VB->Normal[count], ctx->Current.Normal ); 644 COPY_4V( VB->TexCoord[count], ctx->Current.TexCoord ); 645 VB->Edgeflag[count] = ctx->Current.EdgeFlag; 646 647 count++; 648 VB->Count = count; 649 if (count==VB_MAX) { 650 gl_transform_vb_part1( ctx, GL_FALSE ); 651 } 652 } 653 654 655 /* 656 * XYZ vertex, normal. 657 * Caller: context->API.Vertex3f pointer. 658 */ 659 static void vertex3f_normal( GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z ) 660 { 661 struct vertex_buffer *VB = ctx->VB; 662 GLuint count = VB->Count; 663 664 ASSIGN_3V( VB->Obj[count], x, y, z ); 665 COPY_3V( VB->Normal[count], ctx->Current.Normal ); 666 VB->Edgeflag[count] = ctx->Current.EdgeFlag; 667 668 count++; 669 VB->Count = count; 670 if (count==VB_MAX) { 671 gl_transform_vb_part1( ctx, GL_FALSE ); 672 } 673 } 674 675 676 /* 677 * XYZ vertex, ST texture coords. 678 * Caller: context->API.Vertex3f pointer. 679 */ 680 static void vertex3f_color_tex2( GLcontext *ctx, 681 GLfloat x, GLfloat y, GLfloat z ) 682 { 683 struct vertex_buffer *VB = ctx->VB; 684 GLuint count = VB->Count; 685 686 ASSIGN_3V( VB->Obj[count], x, y, z ); 687 COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor ); 688 COPY_2V( VB->TexCoord[count], ctx->Current.TexCoord ); 689 VB->Edgeflag[count] = ctx->Current.EdgeFlag; 690 691 count++; 692 VB->Count = count; 693 if (count==VB_MAX) { 694 gl_transform_vb_part1( ctx, GL_FALSE ); 695 } 696 } 697 698 699 /* 700 * XYZ vertex, STRQ texture coords. 701 * Caller: context->API.Vertex3f pointer. 702 */ 703 static void vertex3f_color_tex4( GLcontext *ctx, 704 GLfloat x, GLfloat y, GLfloat z ) 705 { 706 struct vertex_buffer *VB = ctx->VB; 707 GLuint count = VB->Count; 708 709 ASSIGN_3V( VB->Obj[count], x, y, z ); 710 COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor ); 711 COPY_4V( VB->TexCoord[count], ctx->Current.TexCoord ); 712 VB->Edgeflag[count] = ctx->Current.EdgeFlag; 713 714 count++; 715 VB->Count = count; 716 if (count==VB_MAX) { 717 gl_transform_vb_part1( ctx, GL_FALSE ); 718 } 719 } 720 721 722 /* 723 * XYZ vertex, RGB color. 724 * Caller: context->API.Vertex3f pointer. 725 */ 726 static void vertex3f_color( GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z ) 727 { 728 struct vertex_buffer *VB = ctx->VB; 729 GLuint count = VB->Count; 730 731 ASSIGN_3V( VB->Obj[count], x, y, z ); 732 COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor ); 733 VB->Edgeflag[count] = ctx->Current.EdgeFlag; 734 735 count++; 736 VB->Count = count; 737 if (count==VB_MAX) { 738 gl_transform_vb_part1( ctx, GL_FALSE ); 739 } 740 } 741 742 743 /* 744 * XYZ vertex, color index. 745 * Caller: context->API.Vertex3f pointer. 746 */ 747 static void vertex3f_index( GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z ) 748 { 749 struct vertex_buffer *VB = ctx->VB; 750 GLuint count = VB->Count; 751 752 ASSIGN_3V( VB->Obj[count], x, y, z ); 753 VB->Findex[count] = ctx->Current.Index; 754 VB->Edgeflag[count] = ctx->Current.EdgeFlag; 755 756 count++; 757 VB->Count = count; 758 if (count==VB_MAX) { 759 gl_transform_vb_part1( ctx, GL_FALSE ); 760 } 761 } 762 763 764 765 /* 766 * XY vertex, RGB color, normal, ST texture coords. 767 * Caller: context->API.Vertex2f pointer. 768 */ 769 static void vertex2f_normal_color_tex2( GLcontext *ctx, GLfloat x, GLfloat y ) 770 { 771 struct vertex_buffer *VB = ctx->VB; 772 GLuint count = VB->Count; 773 774 ASSIGN_3V( VB->Obj[count], x, y, 0.0F ); 775 COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor ); 776 COPY_3V( VB->Normal[count], ctx->Current.Normal ); 777 COPY_2V( VB->TexCoord[count], ctx->Current.TexCoord ); 778 VB->Edgeflag[count] = ctx->Current.EdgeFlag; 779 780 count++; 781 VB->Count = count; 782 if (count==VB_MAX) { 783 gl_transform_vb_part1( ctx, GL_FALSE ); 784 } 785 } 786 787 788 /* 789 * XY vertex, RGB color, normal, STRQ texture coords. 790 * Caller: context->API.Vertex2f pointer. 791 */ 792 static void vertex2f_normal_color_tex4( GLcontext *ctx, GLfloat x, GLfloat y ) 793 { 794 struct vertex_buffer *VB = ctx->VB; 795 GLuint count = VB->Count; 796 797 ASSIGN_3V( VB->Obj[count], x, y, 0.0F ); 798 COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor ); 799 COPY_3V( VB->Normal[count], ctx->Current.Normal ); 800 COPY_4V( VB->TexCoord[count], ctx->Current.TexCoord ); 801 VB->Edgeflag[count] = ctx->Current.EdgeFlag; 802 803 count++; 804 VB->Count = count; 805 if (count==VB_MAX) { 806 gl_transform_vb_part1( ctx, GL_FALSE ); 807 } 808 } 809 810 811 /* 812 * XY vertex, normal. 813 * Caller: context->API.Vertex2f pointer. 814 */ 815 static void vertex2f_normal( GLcontext *ctx, GLfloat x, GLfloat y ) 816 { 817 struct vertex_buffer *VB = ctx->VB; 818 GLuint count = VB->Count; 819 820 ASSIGN_3V( VB->Obj[count], x, y, 0.0F ); 821 COPY_3V( VB->Normal[count], ctx->Current.Normal ); 822 VB->Edgeflag[count] = ctx->Current.EdgeFlag; 823 824 count++; 825 VB->Count = count; 826 if (count==VB_MAX) { 827 gl_transform_vb_part1( ctx, GL_FALSE ); 828 } 829 } 830 831 832 /* 833 * XY vertex, ST texture coords. 834 * Caller: context->API.Vertex2f pointer. 835 */ 836 static void vertex2f_color_tex2( GLcontext *ctx, GLfloat x, GLfloat y ) 837 { 838 struct vertex_buffer *VB = ctx->VB; 839 GLuint count = VB->Count; 840 841 ASSIGN_3V( VB->Obj[count], x, y, 0.0F ); 842 COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor ); 843 COPY_2V( VB->TexCoord[count], ctx->Current.TexCoord ); 844 VB->Edgeflag[count] = ctx->Current.EdgeFlag; 845 846 count++; 847 VB->Count = count; 848 if (count==VB_MAX) { 849 gl_transform_vb_part1( ctx, GL_FALSE ); 850 } 851 } 852 853 854 /* 855 * XY vertex, STRQ texture coords. 856 * Caller: context->API.Vertex2f pointer. 857 */ 858 static void vertex2f_color_tex4( GLcontext *ctx, GLfloat x, GLfloat y ) 859 { 860 struct vertex_buffer *VB = ctx->VB; 861 GLuint count = VB->Count; 862 863 ASSIGN_3V( VB->Obj[count], x, y, 0.0F ); 864 COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor ); 865 COPY_4V( VB->TexCoord[count], ctx->Current.TexCoord ); 866 VB->Edgeflag[count] = ctx->Current.EdgeFlag; 867 868 count++; 869 VB->Count = count; 870 if (count==VB_MAX) { 871 gl_transform_vb_part1( ctx, GL_FALSE ); 872 } 873 } 874 875 876 /* 877 * XY vertex, RGB color. 878 * Caller: context->API.Vertex2f pointer. 879 */ 880 static void vertex2f_color( GLcontext *ctx, GLfloat x, GLfloat y ) 881 { 882 struct vertex_buffer *VB = ctx->VB; 883 GLuint count = VB->Count; 884 885 ASSIGN_3V( VB->Obj[count], x, y, 0.0F ); 886 COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor ); 887 VB->Edgeflag[count] = ctx->Current.EdgeFlag; 888 889 count++; 890 VB->Count = count; 891 if (count==VB_MAX) { 892 gl_transform_vb_part1( ctx, GL_FALSE ); 893 } 894 } 895 896 897 /* 898 * XY vertex, color index. 899 * Caller: context->API.Vertex3f pointer. 900 */ 901 static void vertex2f_index( GLcontext *ctx, GLfloat x, GLfloat y ) 902 { 903 struct vertex_buffer *VB = ctx->VB; 904 GLuint count = VB->Count; 905 906 ASSIGN_3V( VB->Obj[count], x, y, 0.0F ); 907 VB->Findex[count] = ctx->Current.Index; 908 VB->Edgeflag[count] = ctx->Current.EdgeFlag; 909 910 count++; 911 VB->Count = count; 912 if (count==VB_MAX) { 913 gl_transform_vb_part1( ctx, GL_FALSE ); 914 } 915 } 916 917 918 919 920 /* 921 * XYZ vertex, RGB color, normal, ST texture coords. 922 * Caller: context->API.Vertex3f pointer. 923 */ 924 static void vertex3fv_normal_color_tex2( GLcontext *ctx, const GLfloat v[3] ) 925 { 926 struct vertex_buffer *VB = ctx->VB; 927 GLuint count = VB->Count; 928 929 COPY_3V( VB->Obj[count], v ); 930 COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor ); 931 COPY_3V( VB->Normal[count], ctx->Current.Normal ); 932 COPY_2V( VB->TexCoord[count], ctx->Current.TexCoord ); 933 VB->Edgeflag[count] = ctx->Current.EdgeFlag; 934 935 count++; 936 VB->Count = count; 937 if (count==VB_MAX) { 938 gl_transform_vb_part1( ctx, GL_FALSE ); 939 } 940 } 941 942 943 /* 944 * XYZ vertex, RGB color, normal, STRQ texture coords. 945 * Caller: context->API.Vertex3f pointer. 946 */ 947 static void vertex3fv_normal_color_tex4( GLcontext *ctx, const GLfloat v[3] ) 948 { 949 struct vertex_buffer *VB = ctx->VB; 950 GLuint count = VB->Count; 951 952 COPY_3V( VB->Obj[count], v ); 953 COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor ); 954 COPY_3V( VB->Normal[count], ctx->Current.Normal ); 955 COPY_4V( VB->TexCoord[count], ctx->Current.TexCoord ); 956 VB->Edgeflag[count] = ctx->Current.EdgeFlag; 957 958 count++; 959 VB->Count = count; 960 if (count==VB_MAX) { 961 gl_transform_vb_part1( ctx, GL_FALSE ); 962 } 963 } 964 965 966 /* 967 * XYZ vertex, normal. 968 * Caller: context->API.Vertex3f pointer. 969 */ 970 static void vertex3fv_normal( GLcontext *ctx, const GLfloat v[3] ) 971 { 972 struct vertex_buffer *VB = ctx->VB; 973 GLuint count = VB->Count; 974 975 COPY_3V( VB->Obj[count], v ); 976 COPY_3V( VB->Normal[count], ctx->Current.Normal ); 977 VB->Edgeflag[count] = ctx->Current.EdgeFlag; 978 979 count++; 980 VB->Count = count; 981 if (count==VB_MAX) { 982 gl_transform_vb_part1( ctx, GL_FALSE ); 983 } 984 } 985 986 987 /* 988 * XYZ vertex, ST texture coords. 989 * Caller: context->API.Vertex3f pointer. 990 */ 991 static void vertex3fv_color_tex2( GLcontext *ctx, const GLfloat v[3] ) 992 { 993 struct vertex_buffer *VB = ctx->VB; 994 GLuint count = VB->Count; 995 996 COPY_3V( VB->Obj[count], v ); 997 COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor ); 998 COPY_2V( VB->TexCoord[count], ctx->Current.TexCoord ); 999 VB->Edgeflag[count] = ctx->Current.EdgeFlag; 1000 1001 count++; 1002 VB->Count = count; 1003 if (count==VB_MAX) { 1004 gl_transform_vb_part1( ctx, GL_FALSE ); 1005 } 1006 } 1007 1008 1009 /* 1010 * XYZ vertex, STRQ texture coords. 1011 * Caller: context->API.Vertex3f pointer. 1012 */ 1013 static void vertex3fv_color_tex4( GLcontext *ctx, const GLfloat v[3] ) 1014 { 1015 struct vertex_buffer *VB = ctx->VB; 1016 GLuint count = VB->Count; 1017 1018 COPY_3V( VB->Obj[count], v ); 1019 COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor ); 1020 COPY_4V( VB->TexCoord[count], ctx->Current.TexCoord ); 1021 VB->Edgeflag[count] = ctx->Current.EdgeFlag; 1022 1023 count++; 1024 VB->Count = count; 1025 if (count==VB_MAX) { 1026 gl_transform_vb_part1( ctx, GL_FALSE ); 1027 } 1028 } 1029 1030 1031 /* 1032 * XYZ vertex, RGB color. 1033 * Caller: context->API.Vertex3f pointer. 1034 */ 1035 static void vertex3fv_color( GLcontext *ctx, const GLfloat v[3] ) 1036 { 1037 struct vertex_buffer *VB = ctx->VB; 1038 GLuint count = VB->Count; 1039 1040 COPY_3V( VB->Obj[count], v ); 1041 COPY_4UBV( VB->Fcolor[count], ctx->Current.ByteColor ); 1042 VB->Edgeflag[count] = ctx->Current.EdgeFlag; 1043 1044 count++; 1045 VB->Count = count; 1046 if (count==VB_MAX) { 1047 gl_transform_vb_part1( ctx, GL_FALSE ); 1048 } 1049 } 1050 1051 1052 /* 1053 * XYZ vertex, Color index 1054 * Caller: context->API.Vertex3f pointer. 1055 */ 1056 static void vertex3fv_index( GLcontext *ctx, const GLfloat v[3] ) 1057 { 1058 struct vertex_buffer *VB = ctx->VB; 1059 GLuint count = VB->Count; 1060 1061 COPY_3V( VB->Obj[count], v ); 1062 VB->Findex[count] = ctx->Current.Index; 1063 VB->Edgeflag[count] = ctx->Current.EdgeFlag; 1064 1065 count++; 1066 VB->Count = count; 1067 if (count==VB_MAX) { 1068 gl_transform_vb_part1( ctx, GL_FALSE ); 1069 } 1070 } 1071 1072 1073 1074 /* 1075 * Called when outside glBegin/glEnd, raises an error. 1076 * Caller: context->API.Vertex4f pointer. 1077 */ 1078 void gl_vertex4f_nop( GLcontext *ctx, 1079 GLfloat x, GLfloat y, GLfloat z, GLfloat w ) 1080 { 1081 gl_error( ctx, GL_INVALID_OPERATION, "glVertex4" ); 1082 } 1083 1084 void gl_vertex3f_nop( GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z ) 1085 { 1086 gl_error( ctx, GL_INVALID_OPERATION, "glVertex3" ); 1087 } 1088 1089 void gl_vertex2f_nop( GLcontext *ctx, GLfloat x, GLfloat y ) 1090 { 1091 gl_error( ctx, GL_INVALID_OPERATION, "glVertex2" ); 1092 } 1093 1094 void gl_vertex3fv_nop( GLcontext *ctx, const GLfloat v[3] ) 1095 { 1096 gl_error( ctx, GL_INVALID_OPERATION, "glVertex3v" ); 1097 } 1098 1099 1100 1101 1102 /**********************************************************************/ 1103 /****** glTexCoord functions *****/ 1104 /**********************************************************************/ 1105 1106 /* 1107 * Caller: context->API.TexCoord2f pointer. 1108 */ 1109 void gl_TexCoord2f( GLcontext *ctx, GLfloat s, GLfloat t ) 1110 { 1111 ctx->Current.TexCoord[0] = s; 1112 ctx->Current.TexCoord[1] = t; 1113 } 1114 1115 1116 /* 1117 * Caller: context->API.TexCoord2f pointer. 1118 * This version of glTexCoord2 is called if glTexCoord[34] was a predecessor. 1119 */ 1120 void gl_TexCoord2f4( GLcontext *ctx, GLfloat s, GLfloat t ) 1121 { 1122 ctx->Current.TexCoord[0] = s; 1123 ctx->Current.TexCoord[1] = t; 1124 ctx->Current.TexCoord[2] = 0.0F; 1125 ctx->Current.TexCoord[3] = 1.0F; 1126 } 1127 1128 1129 /* 1130 * Caller: context->API.TexCoord4f pointer. 1131 */ 1132 void gl_TexCoord4f( GLcontext *ctx, GLfloat s, GLfloat t, GLfloat r, GLfloat q) 1133 { 1134 ctx->Current.TexCoord[0] = s; 1135 ctx->Current.TexCoord[1] = t; 1136 ctx->Current.TexCoord[2] = r; 1137 ctx->Current.TexCoord[3] = q; 1138 if (ctx->VB->TexCoordSize==2) { 1139 /* Have to switch to 4-component texture mode now */ 1140 ctx->VB->TexCoordSize = 4; 1141 gl_set_vertex_function( ctx ); 1142 ctx->Exec.TexCoord2f = ctx->API.TexCoord2f = gl_TexCoord2f4; 1143 } 1144 } 1145 1146 1147 1148 1149 /* 1150 * This function examines the current GL state and sets the 1151 * ctx->Exec.Vertex[34]f pointers to point at the appropriate vertex 1152 * processing functions. 1153 */ 1154 void gl_set_vertex_function( GLcontext *ctx ) 1155 { 1156 if (ctx->RenderMode==GL_FEEDBACK) { 1157 ctx->Exec.Vertex4f = vertex4f_feedback; 1158 ctx->Exec.Vertex3f = vertex3f_feedback; 1159 ctx->Exec.Vertex2f = vertex2f_feedback; 1160 ctx->Exec.Vertex3fv = vertex3fv_feedback; 1161 } 1162 else { 1163 ctx->Exec.Vertex4f = vertex4; 1164 if (ctx->Visual->RGBAflag) { 1165 if (ctx->NeedNormals) { 1166 /* lighting enabled, need normal vectors */ 1167 if (ctx->Texture.Enabled) { 1168 if (ctx->VB->TexCoordSize==2) { 1169 ctx->Exec.Vertex2f = vertex2f_normal_color_tex2; 1170 ctx->Exec.Vertex3f = vertex3f_normal_color_tex2; 1171 ctx->Exec.Vertex3fv = vertex3fv_normal_color_tex2; 1172 } 1173 else { 1174 ctx->Exec.Vertex2f = vertex2f_normal_color_tex4; 1175 ctx->Exec.Vertex3f = vertex3f_normal_color_tex4; 1176 ctx->Exec.Vertex3fv = vertex3fv_normal_color_tex4; 1177 } 1178 } 1179 else { 1180 ctx->Exec.Vertex2f = vertex2f_normal; 1181 ctx->Exec.Vertex3f = vertex3f_normal; 1182 ctx->Exec.Vertex3fv = vertex3fv_normal; 1183 } 1184 } 1185 else { 1186 /* not lighting, need vertex color */ 1187 if (ctx->Texture.Enabled) { 1188 if (ctx->VB->TexCoordSize==2) { 1189 ctx->Exec.Vertex2f = vertex2f_color_tex2; 1190 ctx->Exec.Vertex3f = vertex3f_color_tex2; 1191 ctx->Exec.Vertex3fv = vertex3fv_color_tex2; 1192 } 1193 else { 1194 ctx->Exec.Vertex2f = vertex2f_color_tex4; 1195 ctx->Exec.Vertex3f = vertex3f_color_tex4; 1196 ctx->Exec.Vertex3fv = vertex3fv_color_tex4; 1197 } 1198 } 1199 else { 1200 ctx->Exec.Vertex2f = vertex2f_color; 1201 ctx->Exec.Vertex3f = vertex3f_color; 1202 ctx->Exec.Vertex3fv = vertex3fv_color; 1203 } 1204 } 1205 } 1206 else { 1207 /* color index mode */ 1208 if (ctx->Light.Enabled) { 1209 ctx->Exec.Vertex2f = vertex2f_normal; 1210 ctx->Exec.Vertex3f = vertex3f_normal; 1211 ctx->Exec.Vertex3fv = vertex3fv_normal; 1212 } 1213 else { 1214 ctx->Exec.Vertex2f = vertex2f_index; 1215 ctx->Exec.Vertex3f = vertex3f_index; 1216 ctx->Exec.Vertex3fv = vertex3fv_index; 1217 } 1218 } 1219 } 1220 1221 if (!ctx->CompileFlag) { 1222 ctx->API.Vertex2f = ctx->Exec.Vertex2f; 1223 ctx->API.Vertex3f = ctx->Exec.Vertex3f; 1224 ctx->API.Vertex4f = ctx->Exec.Vertex4f; 1225 ctx->API.Vertex3fv = ctx->Exec.Vertex3fv; 1226 } 1227 } 1228 1229 1230 1231 /* 1232 * This function examines the current GL state and sets the 1233 * ctx->Exec.Color[34]* pointers to point at the appropriate vertex 1234 * processing functions. 1235 */ 1236 void gl_set_color_function( GLcontext *ctx ) 1237 { 1238 ASSERT( !INSIDE_BEGIN_END(ctx) ); 1239 1240 if (ctx->Light.ColorMaterialEnabled) { 1241 ctx->Exec.Color3f = gl_ColorMat3f; 1242 ctx->Exec.Color3fv = gl_ColorMat3fv; 1243 ctx->Exec.Color4f = gl_ColorMat4f; 1244 ctx->Exec.Color4fv = gl_ColorMat4fv; 1245 ctx->Exec.Color4ub = gl_ColorMat4ub; 1246 ctx->Exec.Color4ubv = gl_ColorMat4ubv; 1247 } 1248 else if (ctx->Visual->EightBitColor) { 1249 ctx->Exec.Color3f = gl_Color3f8bit; 1250 ctx->Exec.Color3fv = gl_Color3fv8bit; 1251 ctx->Exec.Color4f = gl_Color4f8bit; 1252 ctx->Exec.Color4fv = gl_Color4fv8bit; 1253 ctx->Exec.Color4ub = gl_Color4ub8bit; 1254 ctx->Exec.Color4ubv = gl_Color4ubv8bit; 1255 } 1256 else { 1257 ctx->Exec.Color3f = gl_Color3f; 1258 ctx->Exec.Color3fv = gl_Color3fv; 1259 ctx->Exec.Color4f = gl_Color4f; 1260 ctx->Exec.Color4fv = gl_Color4fv; 1261 ctx->Exec.Color4ub = gl_Color4ub; 1262 ctx->Exec.Color4ubv = gl_Color4ubv; 1263 } 1264 if (!ctx->CompileFlag) { 1265 ctx->API.Color3f = ctx->Exec.Color3f; 1266 ctx->API.Color3fv = ctx->Exec.Color3fv; 1267 ctx->API.Color4f = ctx->Exec.Color4f; 1268 ctx->API.Color4fv = ctx->Exec.Color4fv; 1269 ctx->API.Color4ub = ctx->Exec.Color4ub; 1270 ctx->API.Color4ubv = ctx->Exec.Color4ubv; 1271 } 1272 } 1273 1274 1275 1276 /**********************************************************************/ 1277 /***** Evaluator vertices *****/ 1278 /**********************************************************************/ 1279 1280 1281 /* 1282 * Process a vertex produced by an evaluator. 1283 * Caller: eval.c 1284 * Input: vertex - the X,Y,Z,W vertex 1285 * normal - normal vector 1286 * color - 4 integer color components 1287 * index - color index 1288 * texcoord - texture coordinate 1289 */ 1290 void gl_eval_vertex( GLcontext *ctx, 1291 const GLfloat vertex[4], const GLfloat normal[3], 1292 const GLubyte color[4], 1293 GLuint index, 1294 const GLfloat texcoord[4] ) 1295 { 1296 struct vertex_buffer *VB = ctx->VB; 1297 GLuint count = VB->Count; /* copy to local var to encourage optimization */ 1298 1299 VB->VertexSizeMask = VERTEX4_BIT; 1300 VB->MonoNormal = GL_FALSE; 1301 COPY_4V( VB->Obj[count], vertex ); 1302 COPY_3V( VB->Normal[count], normal ); 1303 COPY_4UBV( VB->Fcolor[count], color ); 1304 1305 #ifdef GL_VERSION_1_1 1306 if (ctx->Light.ColorMaterialEnabled 1307 && (ctx->Eval.Map1Color4 || ctx->Eval.Map2Color4)) { 1308 GLfloat fcolor[4]; 1309 fcolor[0] = color[0] * ctx->Visual->InvRedScale; 1310 fcolor[1] = color[1] * ctx->Visual->InvGreenScale; 1311 fcolor[2] = color[2] * ctx->Visual->InvBlueScale; 1312 fcolor[3] = color[3] * ctx->Visual->InvAlphaScale; 1313 gl_set_material( ctx, ctx->Light.ColorMaterialBitmask, fcolor ); 1314 } 1315 #endif 1316 VB->Findex[count] = index; 1317 COPY_4V( VB->TexCoord[count], texcoord ); 1318 VB->Edgeflag[count] = ctx->Current.EdgeFlag; 1319 1320 count++; 1321 VB->Count = count; 1322 if (count==VB_MAX) { 1323 gl_transform_vb_part1( ctx, GL_FALSE ); 1324 } 1325 } 1326 1327 1328 1329 1330 1331 /**********************************************************************/ 1332 /***** glBegin / glEnd *****/ 1333 /**********************************************************************/ 1334 1335 1336 #ifdef PROFILE 1337 static GLdouble begin_time; 1338 #endif 1339 1340 1341 void gl_Begin( GLcontext *ctx, GLenum p ) 1342 { 1343 struct vertex_buffer *VB = ctx->VB; 1344 struct pixel_buffer *PB = ctx->PB; 1345 #ifdef PROFILE 1346 begin_time = gl_time(); 1347 #endif 1348 1349 if (INSIDE_BEGIN_END(ctx)) { 1350 gl_error( ctx, GL_INVALID_OPERATION, "glBegin" ); 1351 return; 1352 } 1353 if (ctx->NewModelViewMatrix) { 1354 gl_analyze_modelview_matrix(ctx); 1355 } 1356 if (ctx->NewProjectionMatrix) { 1357 gl_analyze_projection_matrix(ctx); 1358 } 1359 if (ctx->NewState) { 1360 gl_update_state(ctx); 1361 } 1362 else if (ctx->Exec.Vertex3f==gl_vertex3f_nop) { 1363 gl_set_vertex_function(ctx); 1364 } 1365 1366 if (ctx->Driver.Begin) { 1367 (*ctx->Driver.Begin)( ctx, p ); 1368 } 1369 1370 ctx->Primitive = p; 1371 VB->Start = VB->Count = 0; 1372 1373 VB->MonoColor = ctx->MonoPixels; 1374 VB->MonoNormal = GL_TRUE; 1375 if (VB->MonoColor) { 1376 /* All pixels generated are likely to be the same color so have 1377 * the device driver set the "monocolor" now. 1378 */ 1379 if (ctx->Visual->RGBAflag) { 1380 GLubyte r = ctx->Current.ByteColor[0]; 1381 GLubyte g = ctx->Current.ByteColor[1]; 1382 GLubyte b = ctx->Current.ByteColor[2]; 1383 GLubyte a = ctx->Current.ByteColor[3]; 1384 (*ctx->Driver.Color)( ctx, r, g, b, a ); 1385 } 1386 else { 1387 (*ctx->Driver.Index)( ctx, ctx->Current.Index ); 1388 } 1389 } 1390 1391 /* By default use front color/index. Two-sided lighting may override. */ 1392 VB->Color = VB->Fcolor; 1393 VB->Index = VB->Findex; 1394 1395 switch (ctx->Primitive) { 1396 case GL_POINTS: 1397 ctx->LightTwoSide = GL_FALSE; 1398 PB_INIT( PB, GL_POINT ); 1399 break; 1400 case GL_LINES: 1401 case GL_LINE_STRIP: 1402 case GL_LINE_LOOP: 1403 ctx->LightTwoSide = GL_FALSE; 1404 ctx->StippleCounter = 0; 1405 PB_INIT( PB, GL_LINE ); 1406 break; 1407 case GL_TRIANGLES: 1408 case GL_TRIANGLE_STRIP: 1409 case GL_TRIANGLE_FAN: 1410 case GL_QUADS: 1411 case GL_QUAD_STRIP: 1412 case GL_POLYGON: 1413 ctx->LightTwoSide = ctx->Light.Enabled && ctx->Light.Model.TwoSide; 1414 PB_INIT( PB, GL_POLYGON ); 1415 break; 1416 default: 1417 gl_error( ctx, GL_INVALID_ENUM, "glBegin" ); 1418 ctx->Primitive = GL_BITMAP; 1419 } 1420 } 1421 1422 1423 1424 void gl_End( GLcontext *ctx ) 1425 { 1426 struct pixel_buffer *PB = ctx->PB; 1427 struct vertex_buffer *VB = ctx->VB; 1428 1429 if (ctx->Primitive==GL_BITMAP) { 1430 /* glEnd without glBegin */ 1431 gl_error( ctx, GL_INVALID_OPERATION, "glEnd" ); 1432 return; 1433 } 1434 1435 if (VB->Count > VB->Start) { 1436 gl_transform_vb_part1( ctx, GL_TRUE ); 1437 } 1438 if (PB->count>0) { 1439 gl_flush_pb(ctx); 1440 } 1441 1442 if (ctx->Driver.End) { 1443 (*ctx->Driver.End)(ctx); 1444 } 1445 1446 PB->primitive = ctx->Primitive = GL_BITMAP; /* Default mode */ 1447 1448 #ifdef PROFILE 1449 ctx->BeginEndTime += gl_time() - begin_time; 1450 ctx->BeginEndCount++; 1451 #endif 1452 } 1453 1454