Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /**
  2.  * \file polygon.c
  3.  * Polygon operations.
  4.  */
  5.  
  6. /*
  7.  * Mesa 3-D graphics library
  8.  * Version:  6.5.1
  9.  *
  10.  * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
  11.  *
  12.  * Permission is hereby granted, free of charge, to any person obtaining a
  13.  * copy of this software and associated documentation files (the "Software"),
  14.  * to deal in the Software without restriction, including without limitation
  15.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  16.  * and/or sell copies of the Software, and to permit persons to whom the
  17.  * Software is furnished to do so, subject to the following conditions:
  18.  *
  19.  * The above copyright notice and this permission notice shall be included
  20.  * in all copies or substantial portions of the Software.
  21.  *
  22.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  23.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  24.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  25.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  26.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  27.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  28.  */
  29.  
  30.  
  31. #include "glheader.h"
  32. #include "imports.h"
  33. #include "bufferobj.h"
  34. #include "context.h"
  35. #include "image.h"
  36. #include "enums.h"
  37. #include "pack.h"
  38. #include "polygon.h"
  39. #include "mtypes.h"
  40.  
  41.  
  42. /**
  43.  * Specify whether to cull front- or back-facing facets.
  44.  *
  45.  * \param mode culling mode.
  46.  *
  47.  * \sa glCullFace().
  48.  *
  49.  * Verifies the parameter and updates gl_polygon_attrib::CullFaceMode. On
  50.  * change, flushes the vertices and notifies the driver via
  51.  * the dd_function_table::CullFace callback.
  52.  */
  53. void GLAPIENTRY
  54. _mesa_CullFace( GLenum mode )
  55. {
  56.    GET_CURRENT_CONTEXT(ctx);
  57.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  58.  
  59.    if (MESA_VERBOSE&VERBOSE_API)
  60.       _mesa_debug(ctx, "glCullFace %s\n", _mesa_lookup_enum_by_nr(mode));
  61.  
  62.    if (mode!=GL_FRONT && mode!=GL_BACK && mode!=GL_FRONT_AND_BACK) {
  63.       _mesa_error( ctx, GL_INVALID_ENUM, "glCullFace" );
  64.       return;
  65.    }
  66.  
  67.    if (ctx->Polygon.CullFaceMode == mode)
  68.       return;
  69.  
  70.    FLUSH_VERTICES(ctx, _NEW_POLYGON);
  71.    ctx->Polygon.CullFaceMode = mode;
  72.  
  73.    if (ctx->Driver.CullFace)
  74.       ctx->Driver.CullFace( ctx, mode );
  75. }
  76.  
  77.  
  78. /**
  79.  * Define front- and back-facing
  80.  *
  81.  * \param mode orientation of front-facing polygons.
  82.  *
  83.  * \sa glFrontFace().
  84.  *
  85.  * Verifies the parameter and updates gl_polygon_attrib::FrontFace. On change
  86.  * flushes the vertices and notifies the driver via
  87.  * the dd_function_table::FrontFace callback.
  88.  */
  89. void GLAPIENTRY
  90. _mesa_FrontFace( GLenum mode )
  91. {
  92.    GET_CURRENT_CONTEXT(ctx);
  93.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  94.  
  95.    if (MESA_VERBOSE&VERBOSE_API)
  96.       _mesa_debug(ctx, "glFrontFace %s\n", _mesa_lookup_enum_by_nr(mode));
  97.  
  98.    if (mode!=GL_CW && mode!=GL_CCW) {
  99.       _mesa_error( ctx, GL_INVALID_ENUM, "glFrontFace" );
  100.       return;
  101.    }
  102.  
  103.    if (ctx->Polygon.FrontFace == mode)
  104.       return;
  105.  
  106.    FLUSH_VERTICES(ctx, _NEW_POLYGON);
  107.    ctx->Polygon.FrontFace = mode;
  108.  
  109.    ctx->Polygon._FrontBit = (GLboolean) (mode == GL_CW);
  110.  
  111.    if (ctx->Driver.FrontFace)
  112.       ctx->Driver.FrontFace( ctx, mode );
  113. }
  114.  
  115.  
  116. /**
  117.  * Set the polygon rasterization mode.
  118.  *
  119.  * \param face the polygons which \p mode applies to.
  120.  * \param mode how polygons should be rasterized.
  121.  *
  122.  * \sa glPolygonMode().
  123.  *
  124.  * Verifies the parameters and updates gl_polygon_attrib::FrontMode and
  125.  * gl_polygon_attrib::BackMode. On change flushes the vertices and notifies the
  126.  * driver via the dd_function_table::PolygonMode callback.
  127.  */
  128. void GLAPIENTRY
  129. _mesa_PolygonMode( GLenum face, GLenum mode )
  130. {
  131.    GET_CURRENT_CONTEXT(ctx);
  132.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  133.  
  134.    if (MESA_VERBOSE&VERBOSE_API)
  135.       _mesa_debug(ctx, "glPolygonMode %s %s\n",
  136.                   _mesa_lookup_enum_by_nr(face),
  137.                   _mesa_lookup_enum_by_nr(mode));
  138.  
  139.    if (mode!=GL_POINT && mode!=GL_LINE && mode!=GL_FILL) {
  140.       _mesa_error( ctx, GL_INVALID_ENUM, "glPolygonMode(mode)" );
  141.       return;
  142.    }
  143.  
  144.    switch (face) {
  145.    case GL_FRONT:
  146.       if (ctx->Polygon.FrontMode == mode)
  147.          return;
  148.       FLUSH_VERTICES(ctx, _NEW_POLYGON);
  149.       ctx->Polygon.FrontMode = mode;
  150.       break;
  151.    case GL_FRONT_AND_BACK:
  152.       if (ctx->Polygon.FrontMode == mode &&
  153.           ctx->Polygon.BackMode == mode)
  154.          return;
  155.       FLUSH_VERTICES(ctx, _NEW_POLYGON);
  156.       ctx->Polygon.FrontMode = mode;
  157.       ctx->Polygon.BackMode = mode;
  158.       break;
  159.    case GL_BACK:
  160.       if (ctx->Polygon.BackMode == mode)
  161.          return;
  162.       FLUSH_VERTICES(ctx, _NEW_POLYGON);
  163.       ctx->Polygon.BackMode = mode;
  164.       break;
  165.    default:
  166.       _mesa_error( ctx, GL_INVALID_ENUM, "glPolygonMode(face)" );
  167.       return;
  168.    }
  169.  
  170.    if (ctx->Polygon.FrontMode == GL_FILL && ctx->Polygon.BackMode == GL_FILL)
  171.       ctx->_TriangleCaps &= ~DD_TRI_UNFILLED;
  172.    else
  173.       ctx->_TriangleCaps |= DD_TRI_UNFILLED;
  174.  
  175.    if (ctx->Driver.PolygonMode)
  176.       ctx->Driver.PolygonMode(ctx, face, mode);
  177. }
  178.  
  179. #if _HAVE_FULL_GL
  180.  
  181.  
  182. /**
  183.  * This routine updates the ctx->Polygon.Stipple state.
  184.  * If we're getting the stipple data from a PBO, we map the buffer
  185.  * in order to access the data.
  186.  * In any case, we obey the current pixel unpacking parameters when fetching
  187.  * the stipple data.
  188.  *
  189.  * In the future, this routine should be used as a fallback, called via
  190.  * ctx->Driver.PolygonStipple().  We'll have to update all the DRI drivers
  191.  * too.
  192.  */
  193. void
  194. _mesa_polygon_stipple(struct gl_context *ctx, const GLubyte *pattern)
  195. {
  196.    pattern = _mesa_map_validate_pbo_source(ctx, 2,
  197.                                            &ctx->Unpack, 32, 32, 1,
  198.                                            GL_COLOR_INDEX, GL_BITMAP, pattern,
  199.                                            "glPolygonStipple");
  200.    if (!pattern)
  201.       return;
  202.  
  203.    _mesa_unpack_polygon_stipple(pattern, ctx->PolygonStipple, &ctx->Unpack);
  204.  
  205.    _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
  206. }
  207.  
  208.  
  209. /**
  210.  * Called by glPolygonStipple.
  211.  */
  212. void GLAPIENTRY
  213. _mesa_PolygonStipple( const GLubyte *pattern )
  214. {
  215.    GET_CURRENT_CONTEXT(ctx);
  216.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  217.  
  218.    if (MESA_VERBOSE&VERBOSE_API)
  219.       _mesa_debug(ctx, "glPolygonStipple\n");
  220.  
  221.    FLUSH_VERTICES(ctx, _NEW_POLYGONSTIPPLE);
  222.  
  223.    _mesa_polygon_stipple(ctx, pattern);
  224.  
  225.    if (ctx->Driver.PolygonStipple)
  226.       ctx->Driver.PolygonStipple(ctx, pattern);
  227. }
  228.  
  229.  
  230. /**
  231.  * Called by glPolygonStipple.
  232.  */
  233. void GLAPIENTRY
  234. _mesa_GetPolygonStipple( GLubyte *dest )
  235. {
  236.    GET_CURRENT_CONTEXT(ctx);
  237.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  238.  
  239.    if (MESA_VERBOSE&VERBOSE_API)
  240.       _mesa_debug(ctx, "glGetPolygonStipple\n");
  241.  
  242.    dest = _mesa_map_validate_pbo_dest(ctx, 2,
  243.                                       &ctx->Pack, 32, 32, 1,
  244.                                       GL_COLOR_INDEX, GL_BITMAP, dest,
  245.                                       "glGetPolygonStipple");
  246.    if (!dest)
  247.       return;
  248.  
  249.    _mesa_pack_polygon_stipple(ctx->PolygonStipple, dest, &ctx->Pack);
  250.  
  251.    _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
  252. }
  253.  
  254.  
  255. void GLAPIENTRY
  256. _mesa_PolygonOffset( GLfloat factor, GLfloat units )
  257. {
  258.    GET_CURRENT_CONTEXT(ctx);
  259.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  260.  
  261.    if (MESA_VERBOSE&VERBOSE_API)
  262.       _mesa_debug(ctx, "glPolygonOffset %f %f\n", factor, units);
  263.  
  264.    if (ctx->Polygon.OffsetFactor == factor &&
  265.        ctx->Polygon.OffsetUnits == units)
  266.       return;
  267.  
  268.    FLUSH_VERTICES(ctx, _NEW_POLYGON);
  269.    ctx->Polygon.OffsetFactor = factor;
  270.    ctx->Polygon.OffsetUnits = units;
  271.  
  272.    if (ctx->Driver.PolygonOffset)
  273.       ctx->Driver.PolygonOffset( ctx, factor, units );
  274. }
  275.  
  276.  
  277. void GLAPIENTRY
  278. _mesa_PolygonOffsetEXT( GLfloat factor, GLfloat bias )
  279. {
  280.    GET_CURRENT_CONTEXT(ctx);
  281.    /* XXX mult by DepthMaxF here??? */
  282.    _mesa_PolygonOffset(factor, bias * ctx->DrawBuffer->_DepthMaxF );
  283. }
  284.  
  285. #endif
  286.  
  287.  
  288. /**********************************************************************/
  289. /** \name Initialization */
  290. /*@{*/
  291.  
  292. /**
  293.  * Initialize the context polygon state.
  294.  *
  295.  * \param ctx GL context.
  296.  *
  297.  * Initializes __struct gl_contextRec::Polygon and __struct gl_contextRec::PolygonStipple
  298.  * attribute groups.
  299.  */
  300. void _mesa_init_polygon( struct gl_context * ctx )
  301. {
  302.    /* Polygon group */
  303.    ctx->Polygon.CullFlag = GL_FALSE;
  304.    ctx->Polygon.CullFaceMode = GL_BACK;
  305.    ctx->Polygon.FrontFace = GL_CCW;
  306.    ctx->Polygon._FrontBit = 0;
  307.    ctx->Polygon.FrontMode = GL_FILL;
  308.    ctx->Polygon.BackMode = GL_FILL;
  309.    ctx->Polygon.SmoothFlag = GL_FALSE;
  310.    ctx->Polygon.StippleFlag = GL_FALSE;
  311.    ctx->Polygon.OffsetFactor = 0.0F;
  312.    ctx->Polygon.OffsetUnits = 0.0F;
  313.    ctx->Polygon.OffsetPoint = GL_FALSE;
  314.    ctx->Polygon.OffsetLine = GL_FALSE;
  315.    ctx->Polygon.OffsetFill = GL_FALSE;
  316.  
  317.  
  318.    /* Polygon Stipple group */
  319.    memset( ctx->PolygonStipple, 0xff, 32*sizeof(GLuint) );
  320. }
  321.  
  322. /*@}*/
  323.