Home | History | Annotate | Download | only in main
      1 /**
      2  * \file points.c
      3  * Point operations.
      4  */
      5 
      6 /*
      7  * Mesa 3-D graphics library
      8  *
      9  * Copyright (C) 1999-2007  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 "context.h"
     33 #include "macros.h"
     34 #include "points.h"
     35 #include "mtypes.h"
     36 
     37 
     38 /**
     39  * Set current point size.
     40  * \param size  point diameter in pixels
     41  * \sa glPointSize().
     42  */
     43 void GLAPIENTRY
     44 _mesa_PointSize( GLfloat size )
     45 {
     46    GET_CURRENT_CONTEXT(ctx);
     47 
     48    if (size <= 0.0F) {
     49       _mesa_error( ctx, GL_INVALID_VALUE, "glPointSize" );
     50       return;
     51    }
     52 
     53    if (ctx->Point.Size == size)
     54       return;
     55 
     56    FLUSH_VERTICES(ctx, _NEW_POINT);
     57    ctx->Point.Size = size;
     58 
     59    if (ctx->Driver.PointSize)
     60       ctx->Driver.PointSize(ctx, size);
     61 }
     62 
     63 
     64 void GLAPIENTRY
     65 _mesa_PointParameteri( GLenum pname, GLint param )
     66 {
     67    GLfloat p[3];
     68    p[0] = (GLfloat) param;
     69    p[1] = p[2] = 0.0F;
     70    _mesa_PointParameterfv(pname, p);
     71 }
     72 
     73 
     74 void GLAPIENTRY
     75 _mesa_PointParameteriv( GLenum pname, const GLint *params )
     76 {
     77    GLfloat p[3];
     78    p[0] = (GLfloat) params[0];
     79    if (pname == GL_DISTANCE_ATTENUATION_EXT) {
     80       p[1] = (GLfloat) params[1];
     81       p[2] = (GLfloat) params[2];
     82    }
     83    _mesa_PointParameterfv(pname, p);
     84 }
     85 
     86 
     87 void GLAPIENTRY
     88 _mesa_PointParameterf( GLenum pname, GLfloat param)
     89 {
     90    GLfloat p[3];
     91    p[0] = param;
     92    p[1] = p[2] = 0.0F;
     93    _mesa_PointParameterfv(pname, p);
     94 }
     95 
     96 
     97 void GLAPIENTRY
     98 _mesa_PointParameterfv( GLenum pname, const GLfloat *params)
     99 {
    100    GET_CURRENT_CONTEXT(ctx);
    101 
    102    /* Drivers that support point sprites must also support point parameters.
    103     * If point parameters aren't supported, then this function shouldn't even
    104     * exist.
    105     */
    106    assert(!(ctx->Extensions.ARB_point_sprite
    107             || ctx->Extensions.NV_point_sprite)
    108           || ctx->Extensions.EXT_point_parameters);
    109 
    110    if (!ctx->Extensions.EXT_point_parameters) {
    111       _mesa_error(ctx, GL_INVALID_OPERATION,
    112                   "unsupported function called (unsupported extension)");
    113       return;
    114    }
    115 
    116    switch (pname) {
    117       case GL_DISTANCE_ATTENUATION_EXT:
    118          if (TEST_EQ_3V(ctx->Point.Params, params))
    119             return;
    120          FLUSH_VERTICES(ctx, _NEW_POINT);
    121          COPY_3V(ctx->Point.Params, params);
    122          ctx->Point._Attenuated = (ctx->Point.Params[0] != 1.0F ||
    123                                    ctx->Point.Params[1] != 0.0F ||
    124                                    ctx->Point.Params[2] != 0.0F);
    125          break;
    126       case GL_POINT_SIZE_MIN_EXT:
    127          if (params[0] < 0.0F) {
    128             _mesa_error( ctx, GL_INVALID_VALUE,
    129                          "glPointParameterf[v]{EXT,ARB}(param)" );
    130             return;
    131          }
    132          if (ctx->Point.MinSize == params[0])
    133             return;
    134          FLUSH_VERTICES(ctx, _NEW_POINT);
    135          ctx->Point.MinSize = params[0];
    136          break;
    137       case GL_POINT_SIZE_MAX_EXT:
    138          if (params[0] < 0.0F) {
    139             _mesa_error( ctx, GL_INVALID_VALUE,
    140                          "glPointParameterf[v]{EXT,ARB}(param)" );
    141             return;
    142          }
    143          if (ctx->Point.MaxSize == params[0])
    144             return;
    145          FLUSH_VERTICES(ctx, _NEW_POINT);
    146          ctx->Point.MaxSize = params[0];
    147          break;
    148       case GL_POINT_FADE_THRESHOLD_SIZE_EXT:
    149          if (params[0] < 0.0F) {
    150             _mesa_error( ctx, GL_INVALID_VALUE,
    151                          "glPointParameterf[v]{EXT,ARB}(param)" );
    152             return;
    153          }
    154          if (ctx->Point.Threshold == params[0])
    155             return;
    156          FLUSH_VERTICES(ctx, _NEW_POINT);
    157          ctx->Point.Threshold = params[0];
    158          break;
    159       case GL_POINT_SPRITE_R_MODE_NV:
    160          /* This is one area where ARB_point_sprite and NV_point_sprite
    161 	  * differ.  In ARB_point_sprite the POINT_SPRITE_R_MODE is
    162 	  * always ZERO.  NV_point_sprite adds the S and R modes.
    163 	  */
    164          if (_mesa_is_desktop_gl(ctx) && ctx->Extensions.NV_point_sprite) {
    165             GLenum value = (GLenum) params[0];
    166             if (value != GL_ZERO && value != GL_S && value != GL_R) {
    167                _mesa_error(ctx, GL_INVALID_VALUE,
    168                            "glPointParameterf[v]{EXT,ARB}(param)");
    169                return;
    170             }
    171             if (ctx->Point.SpriteRMode == value)
    172                return;
    173             FLUSH_VERTICES(ctx, _NEW_POINT);
    174             ctx->Point.SpriteRMode = value;
    175          }
    176          else {
    177             _mesa_error(ctx, GL_INVALID_ENUM,
    178                         "glPointParameterf[v]{EXT,ARB}(pname)");
    179             return;
    180          }
    181          break;
    182       case GL_POINT_SPRITE_COORD_ORIGIN:
    183 	 /* GL_POINT_SPRITE_COORD_ORIGIN was added to point sprites when the
    184 	  * extension was merged into OpenGL 2.0.
    185 	  */
    186          if ((ctx->API == API_OPENGL_COMPAT && ctx->Version >= 20)
    187              || ctx->API == API_OPENGL_CORE) {
    188             GLenum value = (GLenum) params[0];
    189             if (value != GL_LOWER_LEFT && value != GL_UPPER_LEFT) {
    190                _mesa_error(ctx, GL_INVALID_VALUE,
    191                            "glPointParameterf[v]{EXT,ARB}(param)");
    192                return;
    193             }
    194             if (ctx->Point.SpriteOrigin == value)
    195                return;
    196             FLUSH_VERTICES(ctx, _NEW_POINT);
    197             ctx->Point.SpriteOrigin = value;
    198          }
    199          else {
    200             _mesa_error(ctx, GL_INVALID_ENUM,
    201                         "glPointParameterf[v]{EXT,ARB}(pname)");
    202             return;
    203          }
    204          break;
    205       default:
    206          _mesa_error( ctx, GL_INVALID_ENUM,
    207                       "glPointParameterf[v]{EXT,ARB}(pname)" );
    208          return;
    209    }
    210 
    211    if (ctx->Driver.PointParameterfv)
    212       ctx->Driver.PointParameterfv(ctx, pname, params);
    213 }
    214 
    215 
    216 
    217 /**
    218  * Initialize the context point state.
    219  *
    220  * \param ctx GL context.
    221  *
    222  * Initializes __struct gl_contextRec::Point and point related constants in
    223  * __struct gl_contextRec::Const.
    224  */
    225 void
    226 _mesa_init_point(struct gl_context *ctx)
    227 {
    228    ctx->Point.SmoothFlag = GL_FALSE;
    229    ctx->Point.Size = 1.0;
    230    ctx->Point.Params[0] = 1.0;
    231    ctx->Point.Params[1] = 0.0;
    232    ctx->Point.Params[2] = 0.0;
    233    ctx->Point._Attenuated = GL_FALSE;
    234    ctx->Point.MinSize = 0.0;
    235    ctx->Point.MaxSize
    236       = MAX2(ctx->Const.MaxPointSize, ctx->Const.MaxPointSizeAA);
    237    ctx->Point.Threshold = 1.0;
    238 
    239    /* Page 403 (page 423 of the PDF) of the OpenGL 3.0 spec says:
    240     *
    241     *     "Non-sprite points (section 3.4) - Enable/Disable targets
    242     *     POINT_SMOOTH and POINT_SPRITE, and all associated state. Point
    243     *     rasterization is always performed as though POINT_SPRITE were
    244     *     enabled."
    245     *
    246     * In a core context, the state will default to true, and the setters and
    247     * getters are disabled.
    248     */
    249    ctx->Point.PointSprite = (ctx->API == API_OPENGL_CORE ||
    250                              ctx->API == API_OPENGLES2);
    251 
    252    ctx->Point.SpriteRMode = GL_ZERO; /* GL_NV_point_sprite (only!) */
    253    ctx->Point.SpriteOrigin = GL_UPPER_LEFT; /* GL_ARB_point_sprite */
    254    ctx->Point.CoordReplace = 0; /* GL_ARB/NV_point_sprite */
    255 }
    256