Subversion Repositories Kolibri OS

Rev

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.    if (ctx->Driver.FrontFace)
  108.       ctx->Driver.FrontFace( ctx, mode );
  109. }
  110.  
  111.  
  112. /**
  113.  * Set the polygon rasterization mode.
  114.  *
  115.  * \param face the polygons which \p mode applies to.
  116.  * \param mode how polygons should be rasterized.
  117.  *
  118.  * \sa glPolygonMode().
  119.  *
  120.  * Verifies the parameters and updates gl_polygon_attrib::FrontMode and
  121.  * gl_polygon_attrib::BackMode. On change flushes the vertices and notifies the
  122.  * driver via the dd_function_table::PolygonMode callback.
  123.  */
  124. void GLAPIENTRY
  125. _mesa_PolygonMode( GLenum face, GLenum mode )
  126. {
  127.    GET_CURRENT_CONTEXT(ctx);
  128.  
  129.    if (MESA_VERBOSE&VERBOSE_API)
  130.       _mesa_debug(ctx, "glPolygonMode %s %s\n",
  131.                   _mesa_lookup_enum_by_nr(face),
  132.                   _mesa_lookup_enum_by_nr(mode));
  133.  
  134.    if (mode!=GL_POINT && mode!=GL_LINE && mode!=GL_FILL) {
  135.       _mesa_error( ctx, GL_INVALID_ENUM, "glPolygonMode(mode)" );
  136.       return;
  137.    }
  138.  
  139.    switch (face) {
  140.    case GL_FRONT:
  141.       if (ctx->API == API_OPENGL_CORE) {
  142.          _mesa_error( ctx, GL_INVALID_ENUM, "glPolygonMode(face)" );
  143.          return;
  144.       }
  145.       if (ctx->Polygon.FrontMode == mode)
  146.          return;
  147.       FLUSH_VERTICES(ctx, _NEW_POLYGON);
  148.       ctx->Polygon.FrontMode = mode;
  149.       break;
  150.    case GL_FRONT_AND_BACK:
  151.       if (ctx->Polygon.FrontMode == mode &&
  152.           ctx->Polygon.BackMode == mode)
  153.          return;
  154.       FLUSH_VERTICES(ctx, _NEW_POLYGON);
  155.       ctx->Polygon.FrontMode = mode;
  156.       ctx->Polygon.BackMode = mode;
  157.       break;
  158.    case GL_BACK:
  159.       if (ctx->API == API_OPENGL_CORE) {
  160.          _mesa_error( ctx, GL_INVALID_ENUM, "glPolygonMode(face)" );
  161.          return;
  162.       }
  163.       if (ctx->Polygon.BackMode == mode)
  164.          return;
  165.       FLUSH_VERTICES(ctx, _NEW_POLYGON);
  166.       ctx->Polygon.BackMode = mode;
  167.       break;
  168.    default:
  169.       _mesa_error( ctx, GL_INVALID_ENUM, "glPolygonMode(face)" );
  170.       return;
  171.    }
  172.  
  173.    if (ctx->Driver.PolygonMode)
  174.       ctx->Driver.PolygonMode(ctx, face, mode);
  175. }
  176.  
  177.  
  178. /**
  179.  * Called by glPolygonStipple.
  180.  */
  181. void GLAPIENTRY
  182. _mesa_PolygonStipple(const GLubyte *pattern)
  183. {
  184.    GET_CURRENT_CONTEXT(ctx);
  185.  
  186.    if (MESA_VERBOSE & VERBOSE_API)
  187.       _mesa_debug(ctx, "glPolygonStipple\n");
  188.  
  189.    FLUSH_VERTICES(ctx, _NEW_POLYGONSTIPPLE);
  190.  
  191.    pattern = _mesa_map_validate_pbo_source(ctx, 2,
  192.                                            &ctx->Unpack, 32, 32, 1,
  193.                                            GL_COLOR_INDEX, GL_BITMAP,
  194.                                            INT_MAX, pattern,
  195.                                            "glPolygonStipple");
  196.    if (!pattern)
  197.       return;
  198.  
  199.    _mesa_unpack_polygon_stipple(pattern, ctx->PolygonStipple, &ctx->Unpack);
  200.  
  201.    _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
  202.  
  203.    if (ctx->Driver.PolygonStipple)
  204.       ctx->Driver.PolygonStipple(ctx, pattern);
  205. }
  206.  
  207.  
  208. /**
  209.  * Called by glPolygonStipple.
  210.  */
  211. void GLAPIENTRY
  212. _mesa_GetnPolygonStippleARB( GLsizei bufSize, GLubyte *dest )
  213. {
  214.    GET_CURRENT_CONTEXT(ctx);
  215.  
  216.    if (MESA_VERBOSE&VERBOSE_API)
  217.       _mesa_debug(ctx, "glGetPolygonStipple\n");
  218.  
  219.    dest = _mesa_map_validate_pbo_dest(ctx, 2,
  220.                                       &ctx->Pack, 32, 32, 1,
  221.                                       GL_COLOR_INDEX, GL_BITMAP,
  222.                                       bufSize, dest, "glGetPolygonStipple");
  223.    if (!dest)
  224.       return;
  225.  
  226.    _mesa_pack_polygon_stipple(ctx->PolygonStipple, dest, &ctx->Pack);
  227.  
  228.    _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
  229. }
  230.  
  231.  
  232. void GLAPIENTRY
  233. _mesa_GetPolygonStipple( GLubyte *dest )
  234. {
  235.    _mesa_GetnPolygonStippleARB(INT_MAX, dest);
  236. }
  237.  
  238. void
  239. _mesa_polygon_offset_clamp(struct gl_context *ctx,
  240.                            GLfloat factor, GLfloat units, GLfloat clamp)
  241. {
  242.    if (ctx->Polygon.OffsetFactor == factor &&
  243.        ctx->Polygon.OffsetUnits == units &&
  244.        ctx->Polygon.OffsetClamp == clamp)
  245.       return;
  246.  
  247.    FLUSH_VERTICES(ctx, _NEW_POLYGON);
  248.    ctx->Polygon.OffsetFactor = factor;
  249.    ctx->Polygon.OffsetUnits = units;
  250.    ctx->Polygon.OffsetClamp = clamp;
  251.  
  252.    if (ctx->Driver.PolygonOffset)
  253.       ctx->Driver.PolygonOffset( ctx, factor, units, clamp );
  254. }
  255.  
  256. void GLAPIENTRY
  257. _mesa_PolygonOffset( GLfloat factor, GLfloat units )
  258. {
  259.    GET_CURRENT_CONTEXT(ctx);
  260.  
  261.    if (MESA_VERBOSE&VERBOSE_API)
  262.       _mesa_debug(ctx, "glPolygonOffset %f %f\n", factor, units);
  263.  
  264.    _mesa_polygon_offset_clamp(ctx, factor, units, 0.0);
  265. }
  266.  
  267.  
  268. void GLAPIENTRY
  269. _mesa_PolygonOffsetEXT( GLfloat factor, GLfloat bias )
  270. {
  271.    GET_CURRENT_CONTEXT(ctx);
  272.    /* XXX mult by DepthMaxF here??? */
  273.    _mesa_PolygonOffset(factor, bias * ctx->DrawBuffer->_DepthMaxF );
  274. }
  275.  
  276. void GLAPIENTRY
  277. _mesa_PolygonOffsetClampEXT( GLfloat factor, GLfloat units, GLfloat clamp )
  278. {
  279.    GET_CURRENT_CONTEXT(ctx);
  280.  
  281.    if (!ctx->Extensions.EXT_polygon_offset_clamp) {
  282.       _mesa_error(ctx, GL_INVALID_OPERATION,
  283.                   "unsupported function (glPolygonOffsetClampEXT) called");
  284.       return;
  285.    }
  286.  
  287.    if (MESA_VERBOSE&VERBOSE_API)
  288.       _mesa_debug(ctx, "glPolygonOffsetClampEXT %f %f %f\n", factor, units, clamp);
  289.  
  290.    _mesa_polygon_offset_clamp(ctx, factor, units, clamp);
  291. }
  292.  
  293.  
  294.  
  295. /**********************************************************************/
  296. /** \name Initialization */
  297. /*@{*/
  298.  
  299. /**
  300.  * Initialize the context polygon state.
  301.  *
  302.  * \param ctx GL context.
  303.  *
  304.  * Initializes __struct gl_contextRec::Polygon and __struct gl_contextRec::PolygonStipple
  305.  * attribute groups.
  306.  */
  307. void _mesa_init_polygon( struct gl_context * ctx )
  308. {
  309.    /* Polygon group */
  310.    ctx->Polygon.CullFlag = GL_FALSE;
  311.    ctx->Polygon.CullFaceMode = GL_BACK;
  312.    ctx->Polygon.FrontFace = GL_CCW;
  313.    ctx->Polygon._FrontBit = 0;
  314.    ctx->Polygon.FrontMode = GL_FILL;
  315.    ctx->Polygon.BackMode = GL_FILL;
  316.    ctx->Polygon.SmoothFlag = GL_FALSE;
  317.    ctx->Polygon.StippleFlag = GL_FALSE;
  318.    ctx->Polygon.OffsetFactor = 0.0F;
  319.    ctx->Polygon.OffsetUnits = 0.0F;
  320.    ctx->Polygon.OffsetClamp = 0.0F;
  321.    ctx->Polygon.OffsetPoint = GL_FALSE;
  322.    ctx->Polygon.OffsetLine = GL_FALSE;
  323.    ctx->Polygon.OffsetFill = GL_FALSE;
  324.  
  325.  
  326.    /* Polygon Stipple group */
  327.    memset( ctx->PolygonStipple, 0xff, 32*sizeof(GLuint) );
  328. }
  329.  
  330. /*@}*/
  331.