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

  1. /* $Id: vbindirect.c,v 1.3 1999/10/11 04:24:05 joukj 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.  * New (3.1) transformation code written by Keith Whitwell.
  29.  */
  30.  
  31.  
  32. #include "vb.h"
  33. #include "vbcull.h"
  34. #include "vbrender.h"
  35. #include "pipeline.h"
  36. #include "pb.h"
  37. #include "types.h"
  38. #include "stages.h"
  39.  
  40. static struct gl_prim_state next_lines[3] = {
  41.    { 1, 2, 0, 0, &next_lines[1] },
  42.    { 1, 2, 1, 0, &next_lines[0] }
  43. };
  44.  
  45. static struct gl_prim_state next_line_loop[3] = {
  46.    { 1, 2, 0, 0, &next_line_loop[1] },
  47.    { 1, 2, 1, 1, &next_line_loop[1] }
  48. };
  49.  
  50. static struct gl_prim_state next_line_strip[3] = {
  51.    { 1, 2, 0, 0, &next_line_strip[1] },
  52.    { 1, 2, 1, 0, &next_line_strip[1] }
  53. };
  54.  
  55. static struct gl_prim_state next_poly[3] = {
  56.    { 1, 2, 0, 0, &next_poly[1] },
  57.    { 1, 2, 0, 0, &next_poly[2] },
  58.    { 0, 2, 1, 0, &next_poly[2] }
  59. };
  60.  
  61. static struct gl_prim_state next_tris[3] = {
  62.    { 1, 2, 0, 0, &next_tris[1] },
  63.    { 1, 2, 0, 0, &next_tris[2] },
  64.    { 1, 2, 1, 0, &next_tris[0] } 
  65. };
  66.  
  67. static struct gl_prim_state next_tri_strip0[4] = {
  68.    { 2, 1, 0, 0, &next_tri_strip0[1] },
  69.    { 0, 2, 0, 0, &next_tri_strip0[2] },
  70.    { 2, 1, 1, 0, &next_tri_strip0[3] },
  71.    { 0, 2, 1, 0, &next_tri_strip0[2] },
  72. };
  73.  
  74. static struct gl_prim_state next_tri_strip1[4] = {
  75.    { 0, 2, 0, 0, &next_tri_strip1[1] },
  76.    { 2, 1, 0, 0, &next_tri_strip1[2] },
  77.    { 0, 2, 1, 0, &next_tri_strip1[3] },
  78.    { 2, 1, 1, 0, &next_tri_strip1[2] },
  79. };
  80.  
  81. static struct gl_prim_state next_quads[4] = {
  82.    { 1, 2, 0, 0, &next_quads[1] },
  83.    { 2, 1, 0, 0, &next_quads[2] },
  84.    { 1, 2, 1, 0, &next_quads[3] }, 
  85.    { 1, 2, 1, 0, &next_quads[0] }
  86. };
  87.  
  88. static struct gl_prim_state next_quad_strip[4] = {
  89.    { 2, 1, 0, 0, &next_quad_strip[1] },
  90.    { 0, 2, 0, 0, &next_quad_strip[2] },
  91.    { 2, 1, 1, 0, &next_quad_strip[3] },
  92.    { 0, 2, 1, 0, &next_quad_strip[2] },
  93. };
  94.  
  95.  
  96.  
  97.  
  98.  
  99.  
  100.  
  101. #define INIT(ctx, prim)                \
  102. do {                        \
  103.    if (ctx->PB->count > 0) gl_flush_pb(ctx);    \
  104.    if (ctx->PB->primitive != prim) {            \
  105.       gl_reduced_prim_change( ctx, prim );        \
  106.    }                            \
  107. } while(0)
  108.  
  109.  
  110.  
  111. /* Need better driver support for this case.
  112.  */
  113. static void 
  114. indexed_render_points( struct vertex_buffer *VB,
  115.                const struct gl_prim_state *state,
  116.                const GLuint *elt,
  117.                GLuint start,
  118.                GLuint count )
  119. {
  120.    GLcontext *ctx = VB->ctx;
  121.    GLuint i;
  122.    (void) state;
  123.    INIT(ctx, GL_POINTS);
  124.  
  125.    if (VB->ClipOrMask) {
  126.       const GLubyte *clip = VB->ClipMask;
  127.       for (i = start ; i < count ; i++) 
  128.      if (!clip[elt[i]]) 
  129.         ctx->Driver.PointsFunc( ctx, elt[i], elt[i] );
  130.    } else {
  131.       for (i = start ; i < count ; i++) 
  132.      ctx->Driver.PointsFunc( ctx, elt[i], elt[i] );
  133.    }
  134. }
  135.  
  136. static void 
  137. indexed_render_lines( struct vertex_buffer *VB,
  138.               const struct gl_prim_state *state,
  139.               const GLuint *elt,
  140.               GLuint start,
  141.               GLuint count )
  142. {
  143.    GLcontext *ctx = VB->ctx;
  144.    GLuint i;
  145.  
  146.    INIT(ctx, GL_LINES);
  147.  
  148.    if (VB->ClipOrMask) {
  149.       const GLubyte *clip = VB->ClipMask;
  150.       GLuint prev = 0;
  151.    
  152.       for (i = start ; i < count ; i++) {
  153.      GLuint curr = elt[i];
  154.      if (state->draw) {
  155.         if (clip[curr] | clip[prev]) 
  156.            gl_render_clipped_line( ctx, prev, curr ); 
  157.         else
  158.            ctx->Driver.LineFunc( ctx, prev, curr, curr );     
  159.          }
  160.      prev = curr;     
  161.      state = state->next;
  162.       }
  163.       if (state->finish_loop) {
  164.      GLuint curr = elt[start];
  165.      if (clip[curr] | clip[prev]) 
  166.         gl_render_clipped_line( ctx, prev, curr ); 
  167.      else
  168.         ctx->Driver.LineFunc( ctx, prev, curr, curr );
  169.       }
  170.    } else {
  171.       GLuint prev = 0;
  172.       for (i = start ; i < count ; i++) {
  173.      GLuint curr = elt[i];
  174.      if (state->draw) ctx->Driver.LineFunc( ctx, prev, curr, curr ); 
  175.      prev = curr;
  176.      state = state->next;
  177.       }
  178.       if (state->finish_loop) {
  179.      GLuint curr = elt[start];
  180.      ctx->Driver.LineFunc( ctx, prev, curr, curr );
  181.       }
  182.    }      
  183. }
  184.  
  185.  
  186.  
  187. static void 
  188. indexed_render_tris( struct vertex_buffer *VB,
  189.              const struct gl_prim_state *state,
  190.              const GLuint *elt,
  191.              GLuint start,
  192.              GLuint count ) 
  193. {
  194.    GLcontext *ctx = VB->ctx;
  195.    GLuint i;
  196.  
  197.    INIT(ctx, GL_POLYGON);
  198.  
  199.    if (VB->ClipOrMask) {      
  200.       GLuint v[3];
  201.       GLuint vlist[VB_MAX_CLIPPED_VERTS];
  202.  
  203.       const GLubyte *clip = VB->ClipMask;
  204.       for (i = start ; i < count ; i++) {
  205.      v[2] = elt[i];
  206.      if (state->draw) { 
  207.         if (clip[v[0]] | clip[v[1]] | clip[v[2]]) {
  208.            if (!(clip[v[0]] & clip[v[1]] & clip[v[2]] & CLIP_ALL_BITS)) {
  209.           COPY_3V(vlist, v);
  210.           gl_render_clipped_triangle( ctx, 3, vlist, vlist[2] );
  211.            }
  212.         }
  213.         else
  214.            ctx->TriangleFunc( ctx, v[0], v[1], v[2], v[2] );
  215.      }
  216.      v[0] = v[state->v0];
  217.      v[1] = v[state->v1];
  218.      state = state->next;
  219.       }
  220.    } else {
  221.       GLuint v[3];
  222.       const triangle_func tf = ctx->TriangleFunc;
  223.  
  224.       for (i = start ; i < count ; i++) {
  225.      v[2] = elt[i];
  226.      if (state->draw)
  227.         tf( ctx, v[0], v[1], v[2], v[2] );
  228.      v[0] = v[state->v0];
  229.      v[1] = v[state->v1];
  230.      state = state->next;
  231.       }
  232.    }
  233. }
  234.  
  235.  
  236. static void 
  237. indexed_render_noop( struct vertex_buffer *VB,
  238.              const struct gl_prim_state *state,
  239.              const GLuint *elt,
  240.              GLuint start,
  241.              GLuint count ) 
  242. {
  243.     (void) VB;
  244.     (void) state;
  245.     (void) elt;
  246.     (void) start;
  247.     (void) count;
  248. }
  249.  
  250.  
  251. typedef void (*indexed_render_func)( struct vertex_buffer *VB,
  252.                      const struct gl_prim_state *state,
  253.                      const GLuint *elt,
  254.                      GLuint start,
  255.                      GLuint count );
  256.  
  257.  
  258. indexed_render_func prim_func[GL_POLYGON+2] = {
  259.    indexed_render_points,
  260.    indexed_render_lines,
  261.    indexed_render_lines,
  262.    indexed_render_lines,
  263.    indexed_render_tris,
  264.    indexed_render_tris,
  265.    indexed_render_tris,
  266.    indexed_render_tris,
  267.    indexed_render_tris,
  268.    indexed_render_tris,
  269.    indexed_render_noop
  270. };
  271.    
  272.  
  273. CONST struct gl_prim_state *gl_prim_state_machine[GL_POLYGON+2][2] = {
  274.    { 0, 0 },
  275.    { next_lines,      next_lines },
  276.    { next_line_loop,  next_line_loop },
  277.    { next_line_strip, next_line_strip },
  278.    { next_tris,       next_tris },
  279.    { next_tri_strip0, next_tri_strip1 },
  280.    { next_poly,       next_poly },
  281.    { next_quads,      next_quads },
  282.    { next_quad_strip, next_quad_strip },
  283.    { next_poly,       next_poly },
  284. };
  285.  
  286.  
  287.  
  288.  
  289. void gl_render_elts( struct vertex_buffer *VB )
  290. {
  291.    GLcontext *ctx = VB->ctx;
  292.    struct vertex_buffer *saved_vb = ctx->VB;
  293.    GLenum prim = ctx->CVA.elt_mode;
  294.    GLuint *elt = VB->EltPtr->start;
  295.    GLuint nr = VB->EltPtr->count;
  296.    GLuint p = 0;
  297.  
  298.    gl_import_client_data( VB, ctx->RenderFlags,
  299.               (VB->ClipOrMask 
  300.                ? VEC_WRITABLE|VEC_GOOD_STRIDE
  301.                : VEC_GOOD_STRIDE));
  302.  
  303.    ctx->VB = VB;
  304.  
  305.    if (ctx->Driver.RenderStart)
  306.       ctx->Driver.RenderStart( ctx );
  307.    
  308.    do {
  309.       const struct gl_prim_state *state = gl_prim_state_machine[prim][0];
  310.       indexed_render_func func = prim_func[prim];
  311.       
  312.       func( VB, state, elt, 0, nr );
  313.  
  314.       if (ctx->TriangleCaps & DD_TRI_LIGHT_TWOSIDE) {
  315.      VB->Specular = VB->Spec[0];
  316.      VB->ColorPtr = VB->Color[0];
  317.      VB->IndexPtr = VB->Index[0];
  318.       }
  319.       
  320.    } while (ctx->Driver.MultipassFunc &&
  321.         ctx->Driver.MultipassFunc( VB, ++p ));
  322.  
  323.    
  324.    if (ctx->PB->count > 0) 
  325.       gl_flush_pb(ctx);
  326.  
  327.    if (ctx->Driver.RenderFinish)
  328.       ctx->Driver.RenderFinish( ctx );
  329.  
  330.    ctx->VB = saved_vb;
  331. }
  332.  
  333.  
  334.  
  335. void gl_render_vb_indirect( struct vertex_buffer *VB )
  336. {
  337.    GLuint i, next, prim;
  338.    GLuint parity = VB->Parity;
  339.    GLuint count = VB->Count;
  340.    const struct gl_prim_state *state;
  341.    indexed_render_func func;
  342.    GLcontext *ctx = VB->ctx;
  343.    struct vertex_buffer *cvaVB = ctx->CVA.VB;
  344.    struct vertex_buffer *saved_vb = ctx->VB;
  345.    GLuint p = 0;
  346.  
  347.    gl_import_client_data( cvaVB, ctx->RenderFlags,
  348.               (VB->ClipOrMask 
  349.                ? VEC_WRITABLE|VEC_GOOD_STRIDE
  350.                : VEC_GOOD_STRIDE));
  351.  
  352.    ctx->VB = cvaVB;
  353.  
  354.    if (!VB->CullDone)
  355.       gl_fast_copy_vb( VB );
  356.  
  357.    if (/*  ctx->Current.Primitive == GL_POLYGON+1 &&  */ctx->Driver.RenderStart)
  358.       ctx->Driver.RenderStart( ctx );
  359.  
  360.    do {
  361.       for (i = VB->CopyStart ; i < count ; parity = 0, i = next ) {
  362.      prim = VB->Primitive[i];
  363.      next = VB->NextPrimitive[i];
  364.  
  365.      state = gl_prim_state_machine[prim][parity];
  366.      func = prim_func[prim];
  367.       
  368.      func( cvaVB, state, VB->EltPtr->data, i, next );
  369.       
  370.      if (ctx->TriangleCaps & DD_TRI_LIGHT_TWOSIDE) {
  371.         cvaVB->Specular = cvaVB->Spec[0];
  372.         cvaVB->ColorPtr = cvaVB->Color[0];
  373.         cvaVB->IndexPtr = cvaVB->Index[0];
  374.      }
  375.       }
  376.  
  377.    } while (ctx->Driver.MultipassFunc &&
  378.         ctx->Driver.MultipassFunc( VB, ++p ));
  379.  
  380.  
  381.    if (ctx->PB->count > 0) 
  382.       gl_flush_pb(ctx);
  383.  
  384.    if (/*  ctx->Current.Primitive == GL_POLYGON+1 &&  */ctx->Driver.RenderFinish)
  385.       ctx->Driver.RenderFinish( ctx );
  386.  
  387.    ctx->VB = saved_vb;
  388. }
  389.