home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / System / Mesa-3.1 / src / lines.c < prev    next >
C/C++ Source or Header  |  2000-01-07  |  27KB  |  1,069 lines

  1. /* $Id: lines.c,v 1.5.2.1 1999/11/25 16:51:24 keithw Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.1
  6.  * 
  7.  * Copyright (C) 1999  Brian Paul   All Rights Reserved.
  8.  * 
  9.  * Permission is hereby granted, free of charge, to any person obtaining a
  10.  * copy of this software and associated documentation files (the "Software"),
  11.  * to deal in the Software without restriction, including without limitation
  12.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13.  * and/or sell copies of the Software, and to permit persons to whom the
  14.  * Software is furnished to do so, subject to the following conditions:
  15.  * 
  16.  * The above copyright notice and this permission notice shall be included
  17.  * in all copies or substantial portions of the Software.
  18.  * 
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  23.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  */
  26.  
  27.  
  28.  
  29.  
  30.  
  31. #ifdef PC_HEADER
  32. #include "all.h"
  33. #else
  34. #ifndef XFree86Server
  35. #include <assert.h>
  36. #else
  37. #include "GL/xf86glx.h"
  38. #endif
  39. #include "context.h"
  40. #include "depth.h"
  41. #include "feedback.h"
  42. #include "lines.h"
  43. #include "macros.h"
  44. #include "mmath.h"
  45. #include "pb.h"
  46. #include "texstate.h"
  47. #include "types.h"
  48. #include "vb.h"
  49. #endif
  50.  
  51.  
  52.  
  53. void gl_LineWidth( GLcontext *ctx, GLfloat width )
  54. {
  55.    if (width<=0.0) {
  56.       gl_error( ctx, GL_INVALID_VALUE, "glLineWidth" );
  57.       return;
  58.    }
  59.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLineWidth");
  60.    
  61.    if (ctx->Line.Width != width) {
  62.       ctx->Line.Width = width;
  63.       ctx->TriangleCaps &= ~DD_LINE_WIDTH;
  64.       if (width != 1.0) ctx->TriangleCaps |= DD_LINE_WIDTH;
  65.       ctx->NewState |= NEW_RASTER_OPS;
  66.    }
  67. }
  68.  
  69.  
  70.  
  71. void gl_LineStipple( GLcontext *ctx, GLint factor, GLushort pattern )
  72. {
  73.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLineStipple");
  74.    ctx->Line.StippleFactor = CLAMP( factor, 1, 256 );
  75.    ctx->Line.StipplePattern = pattern;
  76.    ctx->NewState |= NEW_RASTER_OPS;
  77. }
  78.  
  79.  
  80.  
  81. /**********************************************************************/
  82. /*****                    Rasterization                           *****/
  83. /**********************************************************************/
  84.  
  85.  
  86. /*
  87.  * There are 4 pairs (RGBA, CI) of line drawing functions:
  88.  *   1. simple:  width=1 and no special rasterization functions (fastest)
  89.  *   2. flat:  width=1, non-stippled, flat-shaded, any raster operations
  90.  *   3. smooth:  width=1, non-stippled, smooth-shaded, any raster operations
  91.  *   4. general:  any other kind of line (slowest)
  92.  */
  93.  
  94.  
  95. /*
  96.  * All line drawing functions have the same arguments:
  97.  * v1, v2 - indexes of first and second endpoints into vertex buffer arrays
  98.  * pv     - provoking vertex: which vertex color/index to use for flat shading.
  99.  */
  100.  
  101.  
  102.  
  103.  
  104.  
  105.  
  106. #if MAX_WIDTH > MAX_HEIGHT
  107. #  define MAXPOINTS MAX_WIDTH
  108. #else
  109. #  define MAXPOINTS MAX_HEIGHT
  110. #endif
  111.  
  112.  
  113. /* Flat, color index line */
  114. static void flat_ci_line( GLcontext *ctx,
  115.                           GLuint vert0, GLuint vert1, GLuint pvert )
  116. {
  117.    GLint count;
  118.    GLint *pbx = ctx->PB->x;
  119.    GLint *pby = ctx->PB->y;
  120.    PB_SET_INDEX( ctx, ctx->PB, ctx->VB->IndexPtr->data[pvert] );
  121.    count = ctx->PB->count;
  122.  
  123. #define INTERP_XY 1
  124.  
  125. #define PLOT(X,Y)        \
  126.     pbx[count] = X;        \
  127.     pby[count] = Y;        \
  128.     count++;
  129.  
  130. #include "linetemp.h"
  131.  
  132.    ctx->PB->count = count;
  133.    gl_flush_pb(ctx);
  134. }
  135.  
  136.  
  137.  
  138. /* Flat, color index line with Z interpolation/testing */
  139. static void flat_ci_z_line( GLcontext *ctx,
  140.                             GLuint vert0, GLuint vert1, GLuint pvert )
  141. {
  142.    GLint count;
  143.    GLint *pbx = ctx->PB->x;
  144.    GLint *pby = ctx->PB->y;
  145.    GLdepth *pbz = ctx->PB->z;
  146.    PB_SET_INDEX( ctx, ctx->PB, ctx->VB->IndexPtr->data[pvert] );
  147.    count = ctx->PB->count;
  148.  
  149. #define INTERP_XY 1
  150. #define INTERP_Z 1
  151.  
  152. #define PLOT(X,Y)        \
  153.     pbx[count] = X;        \
  154.     pby[count] = Y;        \
  155.     pbz[count] = Z;        \
  156.     count++;
  157.  
  158. #include "linetemp.h"
  159.  
  160.    ctx->PB->count = count;
  161.    gl_flush_pb(ctx);
  162. }
  163.  
  164.  
  165.  
  166. /* Flat-shaded, RGBA line */
  167. static void flat_rgba_line( GLcontext *ctx,
  168.                             GLuint vert0, GLuint vert1, GLuint pvert )
  169. {
  170.    GLint count;
  171.    GLint *pbx = ctx->PB->x;
  172.    GLint *pby = ctx->PB->y;
  173.    GLubyte *color = ctx->VB->ColorPtr->data[pvert];
  174.    PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] );
  175.    count = ctx->PB->count;
  176.  
  177. #define INTERP_XY 1
  178.  
  179. #define PLOT(X,Y)        \
  180.     pbx[count] = X;        \
  181.     pby[count] = Y;        \
  182.     count++;
  183.  
  184. #include "linetemp.h"
  185.  
  186.    ctx->PB->count = count;
  187.    gl_flush_pb(ctx);
  188. }
  189.  
  190.  
  191.  
  192. /* Flat-shaded, RGBA line with Z interpolation/testing */
  193. static void flat_rgba_z_line( GLcontext *ctx,
  194.                               GLuint vert0, GLuint vert1, GLuint pvert )
  195. {
  196.    GLint count;
  197.    GLint *pbx = ctx->PB->x;
  198.    GLint *pby = ctx->PB->y;
  199.    GLdepth *pbz = ctx->PB->z;
  200.    GLubyte *color = ctx->VB->ColorPtr->data[pvert];
  201.    PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] );
  202.    count = ctx->PB->count;
  203.  
  204. #define INTERP_XY 1
  205. #define INTERP_Z 1
  206.  
  207. #define PLOT(X,Y)    \
  208.     pbx[count] = X;    \
  209.     pby[count] = Y;    \
  210.     pbz[count] = Z;    \
  211.     count++;
  212.  
  213. #include "linetemp.h"
  214.  
  215.    ctx->PB->count = count;
  216.    gl_flush_pb(ctx);
  217. }
  218.  
  219.  
  220.  
  221. /* Smooth shaded, color index line */
  222. static void smooth_ci_line( GLcontext *ctx,
  223.                             GLuint vert0, GLuint vert1, GLuint pvert )
  224. {
  225.    GLint count = ctx->PB->count;
  226.    GLint *pbx = ctx->PB->x;
  227.    GLint *pby = ctx->PB->y;
  228.    GLuint *pbi = ctx->PB->i;
  229.    (void) pvert;
  230.  
  231. #define INTERP_XY 1
  232. #define INTERP_INDEX 1
  233.  
  234. #define PLOT(X,Y)        \
  235.     pbx[count] = X;        \
  236.     pby[count] = Y;        \
  237.     pbi[count] = I;        \
  238.     count++;
  239.  
  240. #include "linetemp.h"
  241.  
  242.    ctx->PB->count = count;
  243.    gl_flush_pb(ctx);
  244. }
  245.  
  246.  
  247.  
  248. /* Smooth shaded, color index line with Z interpolation/testing */
  249. static void smooth_ci_z_line( GLcontext *ctx,
  250.                               GLuint vert0, GLuint vert1, GLuint pvert )
  251. {
  252.    GLint count = ctx->PB->count;
  253.    GLint *pbx = ctx->PB->x;
  254.    GLint *pby = ctx->PB->y;
  255.    GLdepth *pbz = ctx->PB->z;
  256.    GLuint *pbi = ctx->PB->i;
  257.    (void) pvert;
  258.  
  259. #define INTERP_XY 1
  260. #define INTERP_Z 1
  261. #define INTERP_INDEX 1
  262.  
  263. #define PLOT(X,Y)        \
  264.     pbx[count] = X;        \
  265.     pby[count] = Y;        \
  266.     pbz[count] = Z;        \
  267.     pbi[count] = I;        \
  268.     count++;
  269.  
  270. #include "linetemp.h"
  271.  
  272.    ctx->PB->count = count;
  273.    gl_flush_pb(ctx);
  274. }
  275.  
  276.  
  277.  
  278. /* Smooth-shaded, RGBA line */
  279. static void smooth_rgba_line( GLcontext *ctx,
  280.                                  GLuint vert0, GLuint vert1, GLuint pvert )
  281. {
  282.    GLint count = ctx->PB->count;
  283.    GLint *pbx = ctx->PB->x;
  284.    GLint *pby = ctx->PB->y;
  285.    GLubyte (*pbrgba)[4] = ctx->PB->rgba;
  286.    (void) pvert;
  287.  
  288. #define INTERP_XY 1
  289. #define INTERP_RGB 1
  290. #define INTERP_ALPHA 1
  291.  
  292. #define PLOT(X,Y)            \
  293.     pbx[count] = X;            \
  294.     pby[count] = Y;            \
  295.     pbrgba[count][RCOMP] = FixedToInt(r0);    \
  296.     pbrgba[count][GCOMP] = FixedToInt(g0);    \
  297.     pbrgba[count][BCOMP] = FixedToInt(b0);    \
  298.     pbrgba[count][ACOMP] = FixedToInt(a0);    \
  299.     count++;
  300.  
  301. #include "linetemp.h"
  302.  
  303.    ctx->PB->count = count;
  304.    gl_flush_pb(ctx);
  305. }
  306.  
  307.  
  308.  
  309. /* Smooth-shaded, RGBA line with Z interpolation/testing */
  310. static void smooth_rgba_z_line( GLcontext *ctx,
  311.                                    GLuint vert0, GLuint vert1, GLuint pvert )
  312. {
  313.    GLint count = ctx->PB->count;
  314.    GLint *pbx = ctx->PB->x;
  315.    GLint *pby = ctx->PB->y;
  316.    GLdepth *pbz = ctx->PB->z;
  317.    GLubyte (*pbrgba)[4] = ctx->PB->rgba;
  318.    (void) pvert;
  319.  
  320. #define INTERP_XY 1
  321. #define INTERP_Z 1
  322. #define INTERP_RGB 1
  323. #define INTERP_ALPHA 1
  324.  
  325. #define PLOT(X,Y)            \
  326.     pbx[count] = X;            \
  327.     pby[count] = Y;            \
  328.     pbz[count] = Z;            \
  329.     pbrgba[count][RCOMP] = FixedToInt(r0);    \
  330.     pbrgba[count][GCOMP] = FixedToInt(g0);    \
  331.     pbrgba[count][BCOMP] = FixedToInt(b0);    \
  332.     pbrgba[count][ACOMP] = FixedToInt(a0);    \
  333.     count++;
  334.  
  335. #include "linetemp.h"
  336.  
  337.    ctx->PB->count = count;
  338.    gl_flush_pb(ctx);
  339. }
  340.  
  341.  
  342. #define CHECK_FULL(count)            \
  343.     if (count >= PB_SIZE-MAX_WIDTH) {    \
  344.        ctx->PB->count = count;        \
  345.        gl_flush_pb(ctx);            \
  346.        count = ctx->PB->count;        \
  347.     }
  348.  
  349.  
  350.  
  351. /* Smooth shaded, color index, any width, maybe stippled */
  352. static void general_smooth_ci_line( GLcontext *ctx,
  353.                                    GLuint vert0, GLuint vert1, GLuint pvert )
  354. {
  355.    GLint count = ctx->PB->count;
  356.    GLint *pbx = ctx->PB->x;
  357.    GLint *pby = ctx->PB->y;
  358.    GLdepth *pbz = ctx->PB->z;
  359.    GLuint *pbi = ctx->PB->i;
  360.    (void) pvert;
  361.  
  362.    if (ctx->Line.StippleFlag) {
  363.       /* stippled */
  364. #define INTERP_XY 1
  365. #define INTERP_Z 1
  366. #define INTERP_INDEX 1
  367. #define WIDE 1
  368. #define STIPPLE 1
  369. #define PLOT(X,Y)        \
  370.     pbx[count] = X;        \
  371.     pby[count] = Y;        \
  372.     pbz[count] = Z;        \
  373.     pbi[count] = I;        \
  374.     count++;        \
  375.     CHECK_FULL(count);
  376. #include "linetemp.h"
  377.    }
  378.    else {
  379.       /* unstippled */
  380.       if (ctx->Line.Width==2.0F) {
  381.          /* special case: unstippled and width=2 */
  382. #define INTERP_XY 1
  383. #define INTERP_Z 1
  384. #define INTERP_INDEX 1
  385. #define XMAJOR_PLOT(X,Y)            \
  386.     pbx[count] = X;  pbx[count+1] = X;    \
  387.     pby[count] = Y;  pby[count+1] = Y+1;    \
  388.     pbz[count] = Z;  pbz[count+1] = Z;    \
  389.     pbi[count] = I;  pbi[count+1] = I;    \
  390.     count += 2;                \
  391.     CHECK_FULL(count);
  392. #define YMAJOR_PLOT(X,Y)            \
  393.     pbx[count] = X;  pbx[count+1] = X+1;    \
  394.     pby[count] = Y;  pby[count+1] = Y;    \
  395.     pbz[count] = Z;  pbz[count+1] = Z;    \
  396.     pbi[count] = I;  pbi[count+1] = I;    \
  397.     count += 2;                \
  398.     CHECK_FULL(count);
  399. #include "linetemp.h"
  400.       }
  401.       else {
  402.          /* unstippled, any width */
  403. #define INTERP_XY 1
  404. #define INTERP_Z 1
  405. #define INTERP_INDEX 1
  406. #define WIDE 1
  407. #define PLOT(X,Y)        \
  408.     pbx[count] = X;        \
  409.     pby[count] = Y;        \
  410.     pbz[count] = Z;        \
  411.     pbi[count] = I;        \
  412.     count++;        \
  413.     CHECK_FULL(count);
  414. #include "linetemp.h"
  415.       }
  416.    }
  417.  
  418.    ctx->PB->count = count;
  419.    gl_flush_pb(ctx);
  420. }
  421.  
  422.  
  423. /* Flat shaded, color index, any width, maybe stippled */
  424. static void general_flat_ci_line( GLcontext *ctx,
  425.                                   GLuint vert0, GLuint vert1, GLuint pvert )
  426. {
  427.    GLint count;
  428.    GLint *pbx = ctx->PB->x;
  429.    GLint *pby = ctx->PB->y;
  430.    GLdepth *pbz = ctx->PB->z;
  431.    PB_SET_INDEX( ctx, ctx->PB, ctx->VB->IndexPtr->data[pvert] );
  432.    count = ctx->PB->count;
  433.  
  434.    if (ctx->Line.StippleFlag) {
  435.       /* stippled, any width */
  436. #define INTERP_XY 1
  437. #define INTERP_Z 1
  438. #define WIDE 1
  439. #define STIPPLE 1
  440. #define PLOT(X,Y)        \
  441.     pbx[count] = X;        \
  442.     pby[count] = Y;        \
  443.     pbz[count] = Z;        \
  444.     count++;        \
  445.     CHECK_FULL(count);
  446. #include "linetemp.h"
  447.    }
  448.    else {
  449.       /* unstippled */
  450.       if (ctx->Line.Width==2.0F) {
  451.          /* special case: unstippled and width=2 */
  452. #define INTERP_XY 1
  453. #define INTERP_Z 1
  454. #define XMAJOR_PLOT(X,Y)            \
  455.     pbx[count] = X;  pbx[count+1] = X;    \
  456.     pby[count] = Y;  pby[count+1] = Y+1;    \
  457.     pbz[count] = Z;  pbz[count+1] = Z;    \
  458.     count += 2;                \
  459.     CHECK_FULL(count);
  460. #define YMAJOR_PLOT(X,Y)            \
  461.     pbx[count] = X;  pbx[count+1] = X+1;    \
  462.     pby[count] = Y;  pby[count+1] = Y;    \
  463.     pbz[count] = Z;  pbz[count+1] = Z;    \
  464.     count += 2;                \
  465.     CHECK_FULL(count);
  466. #include "linetemp.h"
  467.       }
  468.       else {
  469.          /* unstippled, any width */
  470. #define INTERP_XY 1
  471. #define INTERP_Z 1
  472. #define WIDE 1
  473. #define PLOT(X,Y)        \
  474.     pbx[count] = X;        \
  475.     pby[count] = Y;        \
  476.     pbz[count] = Z;        \
  477.     count++;        \
  478.     CHECK_FULL(count);
  479. #include "linetemp.h"
  480.       }
  481.    }
  482.  
  483.    ctx->PB->count = count;
  484.    gl_flush_pb(ctx);
  485. }
  486.  
  487.  
  488.  
  489. static void general_smooth_rgba_line( GLcontext *ctx,
  490.                                       GLuint vert0, GLuint vert1, GLuint pvert)
  491. {
  492.    GLint count = ctx->PB->count;
  493.    GLint *pbx = ctx->PB->x;
  494.    GLint *pby = ctx->PB->y;
  495.    GLdepth *pbz = ctx->PB->z;
  496.    GLubyte (*pbrgba)[4] = ctx->PB->rgba;
  497.    (void) pvert;
  498.  
  499.    if (ctx->Line.StippleFlag) {
  500.       /* stippled */
  501. #define INTERP_XY 1
  502. #define INTERP_Z 1
  503. #define INTERP_RGB 1
  504. #define INTERP_ALPHA 1
  505. #define WIDE 1
  506. #define STIPPLE 1
  507. #define PLOT(X,Y)                \
  508.     pbx[count] = X;                \
  509.     pby[count] = Y;                \
  510.     pbz[count] = Z;                \
  511.     pbrgba[count][RCOMP] = FixedToInt(r0);    \
  512.     pbrgba[count][GCOMP] = FixedToInt(g0);    \
  513.     pbrgba[count][BCOMP] = FixedToInt(b0);    \
  514.     pbrgba[count][ACOMP] = FixedToInt(a0);    \
  515.     count++;                \
  516.     CHECK_FULL(count);
  517. #include "linetemp.h"
  518.    }
  519.    else {
  520.       /* unstippled */
  521.       if (ctx->Line.Width==2.0F) {
  522.          /* special case: unstippled and width=2 */
  523. #define INTERP_XY 1
  524. #define INTERP_Z 1
  525. #define INTERP_RGB 1
  526. #define INTERP_ALPHA 1
  527. #define XMAJOR_PLOT(X,Y)                \
  528.     pbx[count] = X;  pbx[count+1] = X;        \
  529.     pby[count] = Y;  pby[count+1] = Y+1;        \
  530.     pbz[count] = Z;  pbz[count+1] = Z;        \
  531.     pbrgba[count][RCOMP] = FixedToInt(r0);        \
  532.     pbrgba[count][GCOMP] = FixedToInt(g0);        \
  533.     pbrgba[count][BCOMP] = FixedToInt(b0);        \
  534.     pbrgba[count][ACOMP] = FixedToInt(a0);        \
  535.     pbrgba[count+1][RCOMP] = FixedToInt(r0);    \
  536.     pbrgba[count+1][GCOMP] = FixedToInt(g0);    \
  537.     pbrgba[count+1][BCOMP] = FixedToInt(b0);    \
  538.     pbrgba[count+1][ACOMP] = FixedToInt(a0);    \
  539.     count += 2;                    \
  540.     CHECK_FULL(count);
  541. #define YMAJOR_PLOT(X,Y)                \
  542.     pbx[count] = X;  pbx[count+1] = X+1;        \
  543.     pby[count] = Y;  pby[count+1] = Y;        \
  544.     pbz[count] = Z;  pbz[count+1] = Z;        \
  545.     pbrgba[count][RCOMP] = FixedToInt(r0);        \
  546.     pbrgba[count][GCOMP] = FixedToInt(g0);        \
  547.     pbrgba[count][BCOMP] = FixedToInt(b0);        \
  548.     pbrgba[count][ACOMP] = FixedToInt(a0);        \
  549.     pbrgba[count+1][RCOMP] = FixedToInt(r0);    \
  550.     pbrgba[count+1][GCOMP] = FixedToInt(g0);    \
  551.     pbrgba[count+1][BCOMP] = FixedToInt(b0);    \
  552.     pbrgba[count+1][ACOMP] = FixedToInt(a0);    \
  553.     count += 2;                    \
  554.     CHECK_FULL(count);
  555. #include "linetemp.h"
  556.       }
  557.       else {
  558.          /* unstippled, any width */
  559. #define INTERP_XY 1
  560. #define INTERP_Z 1
  561. #define INTERP_RGB 1
  562. #define INTERP_ALPHA 1
  563. #define WIDE 1
  564. #define PLOT(X,Y)                \
  565.     pbx[count] = X;                \
  566.     pby[count] = Y;                \
  567.     pbz[count] = Z;                \
  568.     pbrgba[count][RCOMP] = FixedToInt(r0);    \
  569.     pbrgba[count][GCOMP] = FixedToInt(g0);    \
  570.     pbrgba[count][BCOMP] = FixedToInt(b0);    \
  571.     pbrgba[count][ACOMP] = FixedToInt(a0);    \
  572.     count++;                \
  573.     CHECK_FULL(count);
  574. #include "linetemp.h"
  575.       }
  576.    }
  577.  
  578.    ctx->PB->count = count;
  579.    gl_flush_pb(ctx);
  580. }
  581.  
  582.  
  583. static void general_flat_rgba_line( GLcontext *ctx,
  584.                                     GLuint vert0, GLuint vert1, GLuint pvert )
  585. {
  586.    GLint count;
  587.    GLint *pbx = ctx->PB->x;
  588.    GLint *pby = ctx->PB->y;
  589.    GLdepth *pbz = ctx->PB->z;
  590.    GLubyte *color = ctx->VB->ColorPtr->data[pvert];
  591.    PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] );
  592.    count = ctx->PB->count;
  593.  
  594.    if (ctx->Line.StippleFlag) {
  595.       /* stippled */
  596. #define INTERP_XY 1
  597. #define INTERP_Z 1
  598. #define WIDE 1
  599. #define STIPPLE 1
  600. #define PLOT(X,Y)            \
  601.     pbx[count] = X;            \
  602.     pby[count] = Y;            \
  603.     pbz[count] = Z;            \
  604.     count++;            \
  605.     CHECK_FULL(count);
  606. #include "linetemp.h"
  607.    }
  608.    else {
  609.       /* unstippled */
  610.       if (ctx->Line.Width==2.0F) {
  611.          /* special case: unstippled and width=2 */
  612. #define INTERP_XY 1
  613. #define INTERP_Z 1
  614. #define XMAJOR_PLOT(X,Y)            \
  615.     pbx[count] = X;  pbx[count+1] = X;    \
  616.     pby[count] = Y;  pby[count+1] = Y+1;    \
  617.     pbz[count] = Z;  pbz[count+1] = Z;    \
  618.     count += 2;                \
  619.     CHECK_FULL(count);
  620. #define YMAJOR_PLOT(X,Y)            \
  621.     pbx[count] = X;  pbx[count+1] = X+1;    \
  622.     pby[count] = Y;  pby[count+1] = Y;    \
  623.     pbz[count] = Z;  pbz[count+1] = Z;    \
  624.     count += 2;                \
  625.     CHECK_FULL(count);
  626. #include "linetemp.h"
  627.       }
  628.       else {
  629.          /* unstippled, any width */
  630. #define INTERP_XY 1
  631. #define INTERP_Z 1
  632. #define WIDE 1
  633. #define PLOT(X,Y)            \
  634.     pbx[count] = X;            \
  635.     pby[count] = Y;            \
  636.     pbz[count] = Z;            \
  637.     count++;            \
  638.     CHECK_FULL(count);
  639. #include "linetemp.h"
  640.       }
  641.    }
  642.  
  643.    ctx->PB->count = count;
  644.    gl_flush_pb(ctx);
  645. }
  646.  
  647.  
  648. /* Flat-shaded, textured, any width, maybe stippled */
  649. static void flat_textured_line( GLcontext *ctx,
  650.                                 GLuint vert0, GLuint vert1, GLuint pv )
  651. {
  652.    GLint count;
  653.    GLint *pbx = ctx->PB->x;
  654.    GLint *pby = ctx->PB->y;
  655.    GLdepth *pbz = ctx->PB->z;
  656.    GLfloat *pbs = ctx->PB->s[0];
  657.    GLfloat *pbt = ctx->PB->t[0];
  658.    GLfloat *pbu = ctx->PB->u[0];
  659.    GLubyte *color = ctx->VB->ColorPtr->data[pv];
  660.    PB_SET_COLOR( ctx, ctx->PB, color[0], color[1], color[2], color[3] );
  661.    count = ctx->PB->count;
  662.  
  663.    if (ctx->Line.StippleFlag) {
  664.       /* stippled */
  665. #define INTERP_XY 1
  666. #define INTERP_Z 1
  667. #define INTERP_STUV0 1
  668. #define WIDE 1
  669. #define STIPPLE 1
  670. #define PLOT(X,Y)            \
  671.     {                \
  672.        pbx[count] = X;        \
  673.        pby[count] = Y;        \
  674.        pbz[count] = Z;        \
  675.        pbs[count] = s;        \
  676.        pbt[count] = t;        \
  677.        pbu[count] = u;        \
  678.        count++;            \
  679.        CHECK_FULL(count);        \
  680.     }
  681. #include "linetemp.h"
  682.    }
  683.    else {
  684.       /* unstippled */
  685. #define INTERP_XY 1
  686. #define INTERP_Z 1
  687. #define INTERP_STUV0 1
  688. #define WIDE 1
  689. #define PLOT(X,Y)            \
  690.     {                \
  691.        pbx[count] = X;        \
  692.        pby[count] = Y;        \
  693.        pbz[count] = Z;        \
  694.        pbs[count] = s;        \
  695.        pbt[count] = t;        \
  696.        pbu[count] = u;        \
  697.        count++;            \
  698.        CHECK_FULL(count);        \
  699.     }
  700. #include "linetemp.h"
  701.    }
  702.  
  703.    ctx->PB->count = count;
  704.    gl_flush_pb(ctx);
  705. }
  706.  
  707.  
  708.  
  709. /* Smooth-shaded, textured, any width, maybe stippled */
  710. static void smooth_textured_line( GLcontext *ctx,
  711.                                   GLuint vert0, GLuint vert1, GLuint pvert )
  712. {
  713.    GLint count = ctx->PB->count;
  714.    GLint *pbx = ctx->PB->x;
  715.    GLint *pby = ctx->PB->y;
  716.    GLdepth *pbz = ctx->PB->z;
  717.    GLfloat *pbs = ctx->PB->s[0];
  718.    GLfloat *pbt = ctx->PB->t[0];
  719.    GLfloat *pbu = ctx->PB->u[0];
  720.    GLubyte (*pbrgba)[4] = ctx->PB->rgba;
  721.    (void) pvert;
  722.  
  723.    if (ctx->Line.StippleFlag) {
  724.       /* stippled */
  725. #define INTERP_XY 1
  726. #define INTERP_Z 1
  727. #define INTERP_RGB 1
  728. #define INTERP_ALPHA 1
  729. #define INTERP_STUV0 1
  730. #define WIDE 1
  731. #define STIPPLE 1
  732. #define PLOT(X,Y)                    \
  733.     {                        \
  734.        pbx[count] = X;                \
  735.        pby[count] = Y;                \
  736.        pbz[count] = Z;                \
  737.        pbs[count] = s;                \
  738.        pbt[count] = t;                \
  739.        pbu[count] = u;                \
  740.        pbrgba[count][RCOMP] = FixedToInt(r0);    \
  741.        pbrgba[count][GCOMP] = FixedToInt(g0);    \
  742.        pbrgba[count][BCOMP] = FixedToInt(b0);    \
  743.        pbrgba[count][ACOMP] = FixedToInt(a0);    \
  744.        count++;                    \
  745.        CHECK_FULL(count);                \
  746.     }
  747. #include "linetemp.h"
  748.    }
  749.    else {
  750.       /* unstippled */
  751. #define INTERP_XY 1
  752. #define INTERP_Z 1
  753. #define INTERP_RGB 1
  754. #define INTERP_ALPHA 1
  755. #define INTERP_STUV0 1
  756. #define WIDE 1
  757. #define PLOT(X,Y)                    \
  758.     {                        \
  759.        pbx[count] = X;                \
  760.        pby[count] = Y;                \
  761.        pbz[count] = Z;                \
  762.        pbs[count] = s;                \
  763.        pbt[count] = t;                \
  764.        pbu[count] = u;                \
  765.        pbrgba[count][RCOMP] = FixedToInt(r0);    \
  766.        pbrgba[count][GCOMP] = FixedToInt(g0);    \
  767.        pbrgba[count][BCOMP] = FixedToInt(b0);    \
  768.        pbrgba[count][ACOMP] = FixedToInt(a0);    \
  769.        count++;                    \
  770.        CHECK_FULL(count);                \
  771.     }
  772. #include "linetemp.h"
  773.    }
  774.  
  775.    ctx->PB->count = count;
  776.    gl_flush_pb(ctx);
  777. }
  778.  
  779.  
  780. /* Smooth-shaded, multitextured, any width, maybe stippled, separate specular
  781.  * color interpolation.
  782.  */
  783. static void smooth_multitextured_line( GLcontext *ctx,
  784.                                    GLuint vert0, GLuint vert1, GLuint pvert )
  785. {
  786.    GLint count = ctx->PB->count;
  787.    GLint *pbx = ctx->PB->x;
  788.    GLint *pby = ctx->PB->y;
  789.    GLdepth *pbz = ctx->PB->z;
  790.    GLfloat *pbs = ctx->PB->s[0];
  791.    GLfloat *pbt = ctx->PB->t[0];
  792.    GLfloat *pbu = ctx->PB->u[0];
  793.    GLfloat *pbs1 = ctx->PB->s[1];
  794.    GLfloat *pbt1 = ctx->PB->t[1];
  795.    GLfloat *pbu1 = ctx->PB->u[1];
  796.    GLubyte (*pbrgba)[4] = ctx->PB->rgba;
  797.    GLubyte (*pbspec)[3] = ctx->PB->spec;
  798.    (void) pvert;
  799.  
  800.    if (ctx->Line.StippleFlag) {
  801.       /* stippled */
  802. #define INTERP_XY 1
  803. #define INTERP_Z 1
  804. #define INTERP_RGB 1
  805. #define INTERP_SPEC 1
  806. #define INTERP_ALPHA 1
  807. #define INTERP_STUV0 1
  808. #define INTERP_STUV1 1
  809. #define WIDE 1
  810. #define STIPPLE 1
  811. #define PLOT(X,Y)                    \
  812.     {                        \
  813.        pbx[count] = X;                \
  814.        pby[count] = Y;                \
  815.        pbz[count] = Z;                \
  816.        pbs[count] = s;                \
  817.        pbt[count] = t;                \
  818.        pbu[count] = u;                \
  819.        pbs1[count] = s1;                \
  820.        pbt1[count] = t1;                \
  821.        pbu1[count] = u1;                \
  822.        pbrgba[count][RCOMP] = FixedToInt(r0);    \
  823.        pbrgba[count][GCOMP] = FixedToInt(g0);    \
  824.        pbrgba[count][BCOMP] = FixedToInt(b0);    \
  825.        pbrgba[count][ACOMP] = FixedToInt(a0);    \
  826.        pbspec[count][RCOMP] = FixedToInt(sr0);    \
  827.        pbspec[count][GCOMP] = FixedToInt(sg0);    \
  828.        pbspec[count][BCOMP] = FixedToInt(sb0);    \
  829.        count++;                    \
  830.        CHECK_FULL(count);                \
  831.     }
  832. #include "linetemp.h"
  833.    }
  834.    else {
  835.       /* unstippled */
  836. #define INTERP_XY 1
  837. #define INTERP_Z 1
  838. #define INTERP_RGB 1
  839. #define INTERP_SPEC 1
  840. #define INTERP_ALPHA 1
  841. #define INTERP_STUV0 1
  842. #define INTERP_STUV1 1
  843. #define WIDE 1
  844. #define PLOT(X,Y)                    \
  845.     {                        \
  846.        pbx[count] = X;                \
  847.        pby[count] = Y;                \
  848.        pbz[count] = Z;                \
  849.        pbs[count] = s;                \
  850.        pbt[count] = t;                \
  851.        pbu[count] = u;                \
  852.        pbs1[count] = s1;                \
  853.        pbt1[count] = t1;                \
  854.        pbu1[count] = u1;                \
  855.        pbrgba[count][RCOMP] = FixedToInt(r0);    \
  856.        pbrgba[count][GCOMP] = FixedToInt(g0);    \
  857.        pbrgba[count][BCOMP] = FixedToInt(b0);    \
  858.        pbrgba[count][ACOMP] = FixedToInt(a0);    \
  859.        pbspec[count][RCOMP] = FixedToInt(sr0);    \
  860.        pbspec[count][GCOMP] = FixedToInt(sg0);    \
  861.        pbspec[count][BCOMP] = FixedToInt(sb0);    \
  862.        count++;                    \
  863.        CHECK_FULL(count);                \
  864.     }
  865. #include "linetemp.h"
  866.    }
  867.  
  868.    ctx->PB->count = count;
  869.    gl_flush_pb(ctx);
  870. }
  871.  
  872.  
  873. /*
  874.  * Antialiased RGBA line
  875.  *
  876.  * This AA line function isn't terribly efficient but it's pretty
  877.  * straight-forward to understand.  Also, it doesn't exactly conform
  878.  * to the specification.
  879.  */
  880. static void aa_rgba_line( GLcontext *ctx,
  881.                           GLuint vert0, GLuint vert1, GLuint pvert )
  882. {
  883. #define INTERP_RGBA 1
  884. #define PLOT(x, y)  { PB_WRITE_RGBA_PIXEL( pb, (x), (y), z, red, green, blue, coverage ); }
  885. #include "lnaatemp.h"
  886. }
  887.  
  888. /*
  889.  * Antialiased Textured RGBA line
  890.  *
  891.  * This AA line function isn't terribly efficient but it's pretty
  892.  * straight-forward to understand.  Also, it doesn't exactly conform
  893.  * to the specification.
  894.  */
  895. static void aa_tex_rgba_line( GLcontext *ctx,
  896.                               GLuint vert0, GLuint vert1, GLuint pvert )
  897. {
  898. #define INTERP_RGBA 1
  899. #define INTERP_STUV0 1
  900. #define PLOT(x, y)                            \
  901.    {                                    \
  902.       PB_WRITE_TEX_PIXEL( pb, (x), (y), z, red, green, blue, coverage,    \
  903.                           s, t, u );                    \
  904.    }
  905. #include "lnaatemp.h"
  906. }
  907.  
  908.  
  909. /*
  910.  * Antialiased Multitextured RGBA line
  911.  *
  912.  * This AA line function isn't terribly efficient but it's pretty
  913.  * straight-forward to understand.  Also, it doesn't exactly conform
  914.  * to the specification.
  915.  */
  916. static void aa_multitex_rgba_line( GLcontext *ctx,
  917.                                    GLuint vert0, GLuint vert1, GLuint pvert )
  918. {
  919. #define INTERP_RGBA 1
  920. #define INTERP_SPEC 1
  921. #define INTERP_STUV0 1
  922. #define INTERP_STUV1 1
  923. #define PLOT(x, y)                            \
  924.    {                                    \
  925.       PB_WRITE_MULTITEX_SPEC_PIXEL( pb, (x), (y), z,            \
  926.             red, green, blue, coverage, specRed, specGreen, specBlue,    \
  927.             s, t, u, s1, t1, u1 );                    \
  928.    }
  929. #include "lnaatemp.h"
  930. }
  931.  
  932.  
  933. /*
  934.  * Antialiased CI line.  Same comments for RGBA antialiased lines apply.
  935.  */
  936. static void aa_ci_line( GLcontext *ctx,
  937.                         GLuint vert0, GLuint vert1, GLuint pvert )
  938. {
  939. #define INTERP_INDEX 1
  940. #define PLOT(x, y)                        \
  941.    {                                \
  942.       PB_WRITE_CI_PIXEL( pb, (x), (y), z, index + coverage );    \
  943.    }
  944. #include "lnaatemp.h"
  945. }
  946.  
  947.  
  948. /*
  949.  * Null rasterizer for measuring transformation speed.
  950.  */
  951. static void null_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv )
  952. {
  953.    (void) ctx;
  954.    (void) v1;
  955.    (void) v2;
  956.    (void) pv;
  957. }
  958.  
  959.  
  960. /*
  961.  * Determine which line drawing function to use given the current
  962.  * rendering context.
  963.  */
  964. void gl_set_line_function( GLcontext *ctx )
  965. {
  966.    GLboolean rgbmode = ctx->Visual->RGBAflag;
  967.    /* TODO: antialiased lines */
  968.  
  969.    if (ctx->RenderMode==GL_RENDER) {
  970.       if (ctx->NoRaster) {
  971.          ctx->Driver.LineFunc = null_line;
  972.          return;
  973.       }
  974.       if (ctx->Driver.LineFunc) {
  975.          /* Device driver will draw lines. */
  976.      return;
  977.       }
  978.  
  979.       if (ctx->Line.SmoothFlag) {
  980.          /* antialiased lines */
  981.          if (rgbmode) {
  982.             if (ctx->Texture.ReallyEnabled) {
  983.                if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D
  984.                   || ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR)
  985.                   /* Multitextured! */
  986.                   ctx->Driver.LineFunc = aa_multitex_rgba_line;
  987.                else
  988.                   ctx->Driver.LineFunc = aa_tex_rgba_line;
  989.             } else {
  990.                ctx->Driver.LineFunc = aa_rgba_line;
  991.             }
  992.          }
  993.          else {
  994.             ctx->Driver.LineFunc = aa_ci_line;
  995.          }
  996.       }
  997.       else if (ctx->Texture.ReallyEnabled) {
  998.          if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D
  999.              || ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR) {
  1000.             /* multi-texture and/or separate specular color */
  1001.             ctx->Driver.LineFunc = smooth_multitextured_line;
  1002.          }
  1003.          else {
  1004.             if (ctx->Light.ShadeModel==GL_SMOOTH) {
  1005.                 ctx->Driver.LineFunc = smooth_textured_line;
  1006.             }
  1007.             else {
  1008.                 ctx->Driver.LineFunc = flat_textured_line;
  1009.             }
  1010.          }
  1011.       }
  1012.       else if (ctx->Line.Width!=1.0 || ctx->Line.StippleFlag
  1013.                || ctx->Line.SmoothFlag) {
  1014.          if (ctx->Light.ShadeModel==GL_SMOOTH) {
  1015.             if (rgbmode)
  1016.                ctx->Driver.LineFunc = general_smooth_rgba_line;
  1017.             else
  1018.                ctx->Driver.LineFunc = general_smooth_ci_line;
  1019.          }
  1020.          else {
  1021.             if (rgbmode)
  1022.                ctx->Driver.LineFunc = general_flat_rgba_line;
  1023.             else
  1024.                ctx->Driver.LineFunc = general_flat_ci_line;
  1025.          }
  1026.       }
  1027.       else {
  1028.      if (ctx->Light.ShadeModel==GL_SMOOTH) {
  1029.         /* Width==1, non-stippled, smooth-shaded */
  1030.             if (ctx->Depth.Test || ctx->FogMode == FOG_FRAGMENT) {
  1031.                if (rgbmode)
  1032.                   ctx->Driver.LineFunc = smooth_rgba_z_line;
  1033.                else
  1034.                   ctx->Driver.LineFunc = smooth_ci_z_line;
  1035.             }
  1036.             else {
  1037.                if (rgbmode)
  1038.                   ctx->Driver.LineFunc = smooth_rgba_line;
  1039.                else
  1040.                   ctx->Driver.LineFunc = smooth_ci_line;
  1041.             }
  1042.      }
  1043.          else {
  1044.         /* Width==1, non-stippled, flat-shaded */
  1045.             if (ctx->Depth.Test || ctx->FogMode == FOG_FRAGMENT) {
  1046.                if (rgbmode)
  1047.                   ctx->Driver.LineFunc = flat_rgba_z_line;
  1048.                else
  1049.                   ctx->Driver.LineFunc = flat_ci_z_line;
  1050.             }
  1051.             else {
  1052.                if (rgbmode)
  1053.                   ctx->Driver.LineFunc = flat_rgba_line;
  1054.                else
  1055.                   ctx->Driver.LineFunc = flat_ci_line;
  1056.             }
  1057.          }
  1058.       }
  1059.    }
  1060.    else if (ctx->RenderMode==GL_FEEDBACK) {
  1061.       ctx->Driver.LineFunc = gl_feedback_line;
  1062.    }
  1063.    else {
  1064.       /* GL_SELECT mode */
  1065.       ctx->Driver.LineFunc = gl_select_line;
  1066.    }
  1067. }
  1068.  
  1069.