Subversion Repositories Kolibri OS

Rev

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

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