Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2009 VMware, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * Permission is hereby granted, free of charge, to any person obtaining a
  6.  * copy of this software and associated documentation files (the "Software"),
  7.  * to deal in the Software without restriction, including without limitation
  8.  * on the rights to use, copy, modify, merge, publish, distribute, sub
  9.  * license, and/or sell copies of the Software, and to permit persons to whom
  10.  * the Software is furnished to do so, subject to the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice (including the next
  13.  * paragraph) shall be included in all copies or substantial portions of the
  14.  * Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
  19.  * VMWARE AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
  20.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  21.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  22.  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25. #include "u_indices.h"
  26. #include "u_indices_priv.h"
  27.  
  28.  
  29. static void translate_ubyte_ushort( const void *in,
  30.                                     unsigned start,
  31.                                     unsigned in_nr,
  32.                                     unsigned out_nr,
  33.                                     unsigned restart_index,
  34.                                     void *out )
  35. {
  36.    const ubyte *in_ub = (const ubyte *)in;
  37.    ushort *out_us = (ushort *)out;
  38.    unsigned i;
  39.    for (i = 0; i < out_nr; i++)
  40.       out_us[i] = (ushort) in_ub[i+start];
  41. }
  42.  
  43. static void translate_memcpy_ushort( const void *in,
  44.                                      unsigned start,
  45.                                      unsigned in_nr,
  46.                                      unsigned out_nr,
  47.                                      unsigned restart_index,
  48.                                      void *out )
  49. {
  50.    memcpy(out, &((short *)in)[start], out_nr*sizeof(short));
  51. }
  52.                              
  53. static void translate_memcpy_uint( const void *in,
  54.                                    unsigned start,
  55.                                    unsigned in_nr,
  56.                                    unsigned out_nr,
  57.                                    unsigned restart_index,
  58.                                    void *out )
  59. {
  60.    memcpy(out, &((int *)in)[start], out_nr*sizeof(int));
  61. }
  62.  
  63.  
  64. static void generate_linear_ushort( unsigned start,
  65.                                     unsigned nr,
  66.                                     void *out )
  67. {
  68.    ushort *out_us = (ushort *)out;
  69.    unsigned i;
  70.    for (i = 0; i < nr; i++)
  71.       out_us[i] = (ushort)(i + start);
  72. }
  73.                              
  74. static void generate_linear_uint( unsigned start,
  75.                                   unsigned nr,
  76.                                   void *out )
  77. {
  78.    unsigned *out_ui = (unsigned *)out;
  79.    unsigned i;
  80.    for (i = 0; i < nr; i++)
  81.       out_ui[i] = i + start;
  82. }
  83.  
  84.  
  85. /**
  86.  * Given a primitive type and number of vertices, return the number of vertices
  87.  * needed to draw the primitive with fill mode = PIPE_POLYGON_MODE_LINE using
  88.  * separate lines (PIPE_PRIM_LINES).
  89.  */
  90. static unsigned nr_lines( unsigned prim,
  91.                           unsigned nr )
  92. {
  93.    switch (prim) {
  94.    case PIPE_PRIM_TRIANGLES:
  95.       return (nr / 3) * 6;
  96.    case PIPE_PRIM_TRIANGLE_STRIP:
  97.       return (nr - 2) * 6;
  98.    case PIPE_PRIM_TRIANGLE_FAN:
  99.       return (nr - 2)  * 6;
  100.    case PIPE_PRIM_QUADS:
  101.       return (nr / 4) * 8;
  102.    case PIPE_PRIM_QUAD_STRIP:
  103.       return (nr - 2) / 2 * 8;
  104.    case PIPE_PRIM_POLYGON:
  105.       return 2 * nr; /* a line (two verts) for each polygon edge */
  106.    default:
  107.       assert(0);
  108.       return 0;
  109.    }
  110. }
  111.                              
  112.  
  113.  
  114. int u_unfilled_translator( unsigned prim,
  115.                         unsigned in_index_size,
  116.                         unsigned nr,
  117.                         unsigned unfilled_mode,
  118.                         unsigned *out_prim,
  119.                         unsigned *out_index_size,
  120.                         unsigned *out_nr,
  121.                         u_translate_func *out_translate )
  122. {
  123.    unsigned in_idx;
  124.    unsigned out_idx;
  125.  
  126.    u_unfilled_init();
  127.  
  128.    in_idx = in_size_idx(in_index_size);
  129.    *out_index_size = (in_index_size == 4) ? 4 : 2;
  130.    out_idx = out_size_idx(*out_index_size);
  131.  
  132.    if (unfilled_mode == PIPE_POLYGON_MODE_POINT)
  133.    {
  134.       *out_prim = PIPE_PRIM_POINTS;
  135.       *out_nr = nr;
  136.  
  137.       switch (in_index_size)
  138.       {
  139.       case 1:
  140.          *out_translate = translate_ubyte_ushort;
  141.          return U_TRANSLATE_NORMAL;
  142.       case 2:
  143.          *out_translate = translate_memcpy_uint;
  144.          return U_TRANSLATE_MEMCPY;
  145.       case 4:
  146.          *out_translate = translate_memcpy_ushort;
  147.          return U_TRANSLATE_MEMCPY;
  148.       default:
  149.          *out_translate = translate_memcpy_uint;
  150.          *out_nr = 0;
  151.          assert(0);
  152.          return U_TRANSLATE_ERROR;
  153.       }
  154.    }
  155.    else {
  156.       assert(unfilled_mode == PIPE_POLYGON_MODE_LINE);
  157.       *out_prim = PIPE_PRIM_LINES;
  158.       *out_translate = translate_line[in_idx][out_idx][prim];
  159.       *out_nr = nr_lines( prim, nr );
  160.       return U_TRANSLATE_NORMAL;
  161.    }
  162. }
  163.  
  164.  
  165. /**
  166.  * Utility for converting unfilled polygons into points, lines, triangles.
  167.  * Few drivers have direct support for OpenGL's glPolygonMode.
  168.  * This function helps with converting triangles into points or lines
  169.  * when the front and back fill modes are the same.  When there's
  170.  * different front/back fill modes, that can be handled with the
  171.  * 'draw' module.
  172.  */
  173. int u_unfilled_generator( unsigned prim,
  174.                           unsigned start,
  175.                           unsigned nr,
  176.                           unsigned unfilled_mode,
  177.                           unsigned *out_prim,
  178.                           unsigned *out_index_size,
  179.                           unsigned *out_nr,
  180.                           u_generate_func *out_generate )
  181. {
  182.    unsigned out_idx;
  183.  
  184.    u_unfilled_init();
  185.  
  186.    *out_index_size = ((start + nr) > 0xfffe) ? 4 : 2;
  187.    out_idx = out_size_idx(*out_index_size);
  188.  
  189.    if (unfilled_mode == PIPE_POLYGON_MODE_POINT) {
  190.  
  191.       if (*out_index_size == 4)
  192.          *out_generate = generate_linear_uint;
  193.       else
  194.          *out_generate = generate_linear_ushort;
  195.  
  196.       *out_prim = PIPE_PRIM_POINTS;
  197.       *out_nr = nr;
  198.       return U_GENERATE_LINEAR;
  199.    }
  200.    else {
  201.       assert(unfilled_mode == PIPE_POLYGON_MODE_LINE);
  202.       *out_prim = PIPE_PRIM_LINES;
  203.       *out_generate = generate_line[out_idx][prim];
  204.       *out_nr = nr_lines( prim, nr );
  205.  
  206.       return U_GENERATE_REUSABLE;
  207.    }
  208. }
  209.  
  210.