• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "api_exec_decl.h"
37 
38 
39 static void
update_point_size_set(struct gl_context * ctx)40 update_point_size_set(struct gl_context *ctx)
41 {
42    float size = CLAMP(ctx->Point.Size, ctx->Point.MinSize, ctx->Point.MaxSize);
43    ctx->PointSizeIsSet = (size == 1.0 && ctx->Point.Size == 1.0) || ctx->Point._Attenuated;
44 }
45 
46 /**
47  * Set current point size.
48  * \param size  point diameter in pixels
49  * \sa glPointSize().
50  */
51 static ALWAYS_INLINE void
point_size(struct gl_context * ctx,GLfloat size,bool no_error)52 point_size(struct gl_context *ctx, GLfloat size, bool no_error)
53 {
54    if (ctx->Point.Size == size)
55       return;
56 
57    if (!no_error && size <= 0.0F) {
58       _mesa_error(ctx, GL_INVALID_VALUE, "glPointSize");
59       return;
60    }
61 
62    FLUSH_VERTICES(ctx, _NEW_POINT, GL_POINT_BIT);
63    ctx->Point.Size = size;
64    update_point_size_set(ctx);
65 }
66 
67 
68 void GLAPIENTRY
_mesa_PointSize_no_error(GLfloat size)69 _mesa_PointSize_no_error(GLfloat size)
70 {
71    GET_CURRENT_CONTEXT(ctx);
72    point_size(ctx, size, true);
73 }
74 
75 
76 void GLAPIENTRY
_mesa_PointSize(GLfloat size)77 _mesa_PointSize( GLfloat size )
78 {
79    GET_CURRENT_CONTEXT(ctx);
80    point_size(ctx, size, false);
81 }
82 
83 
84 void GLAPIENTRY
_mesa_PointParameteri(GLenum pname,GLint param)85 _mesa_PointParameteri( GLenum pname, GLint param )
86 {
87    GLfloat p[3];
88    p[0] = (GLfloat) param;
89    p[1] = p[2] = 0.0F;
90    _mesa_PointParameterfv(pname, p);
91 }
92 
93 
94 void GLAPIENTRY
_mesa_PointParameteriv(GLenum pname,const GLint * params)95 _mesa_PointParameteriv( GLenum pname, const GLint *params )
96 {
97    GLfloat p[3];
98    p[0] = (GLfloat) params[0];
99    if (pname == GL_DISTANCE_ATTENUATION_EXT) {
100       p[1] = (GLfloat) params[1];
101       p[2] = (GLfloat) params[2];
102    }
103    _mesa_PointParameterfv(pname, p);
104 }
105 
106 
107 void GLAPIENTRY
_mesa_PointParameterf(GLenum pname,GLfloat param)108 _mesa_PointParameterf( GLenum pname, GLfloat param)
109 {
110    GLfloat p[3];
111    p[0] = param;
112    p[1] = p[2] = 0.0F;
113    _mesa_PointParameterfv(pname, p);
114 }
115 
116 
117 void GLAPIENTRY
_mesa_PointParameterfv(GLenum pname,const GLfloat * params)118 _mesa_PointParameterfv( GLenum pname, const GLfloat *params)
119 {
120    GET_CURRENT_CONTEXT(ctx);
121 
122    switch (pname) {
123       case GL_DISTANCE_ATTENUATION_EXT:
124          if (TEST_EQ_3V(ctx->Point.Params, params))
125             return;
126          FLUSH_VERTICES(ctx, _NEW_POINT | _NEW_FF_VERT_PROGRAM |
127                         _NEW_TNL_SPACES, GL_POINT_BIT);
128          COPY_3V(ctx->Point.Params, params);
129          ctx->Point._Attenuated = (ctx->Point.Params[0] != 1.0F ||
130                                    ctx->Point.Params[1] != 0.0F ||
131                                    ctx->Point.Params[2] != 0.0F);
132          update_point_size_set(ctx);
133          break;
134       case GL_POINT_SIZE_MIN_EXT:
135          if (params[0] < 0.0F) {
136             _mesa_error( ctx, GL_INVALID_VALUE,
137                          "glPointParameterf[v]{EXT,ARB}(param)" );
138             return;
139          }
140          if (ctx->Point.MinSize == params[0])
141             return;
142          FLUSH_VERTICES(ctx, _NEW_POINT, GL_POINT_BIT);
143          ctx->Point.MinSize = params[0];
144          break;
145       case GL_POINT_SIZE_MAX_EXT:
146          if (params[0] < 0.0F) {
147             _mesa_error( ctx, GL_INVALID_VALUE,
148                          "glPointParameterf[v]{EXT,ARB}(param)" );
149             return;
150          }
151          if (ctx->Point.MaxSize == params[0])
152             return;
153          FLUSH_VERTICES(ctx, _NEW_POINT, GL_POINT_BIT);
154          ctx->Point.MaxSize = params[0];
155          break;
156       case GL_POINT_FADE_THRESHOLD_SIZE_EXT:
157          if (params[0] < 0.0F) {
158             _mesa_error( ctx, GL_INVALID_VALUE,
159                          "glPointParameterf[v]{EXT,ARB}(param)" );
160             return;
161          }
162          if (ctx->Point.Threshold == params[0])
163             return;
164          FLUSH_VERTICES(ctx, _NEW_POINT, GL_POINT_BIT);
165          ctx->Point.Threshold = params[0];
166          break;
167       case GL_POINT_SPRITE_COORD_ORIGIN:
168 	 /* GL_POINT_SPRITE_COORD_ORIGIN was added to point sprites when the
169 	  * extension was merged into OpenGL 2.0.
170 	  */
171          if ((ctx->API == API_OPENGL_COMPAT && ctx->Version >= 20)
172              || ctx->API == API_OPENGL_CORE) {
173             GLenum value = (GLenum) params[0];
174             if (value != GL_LOWER_LEFT && value != GL_UPPER_LEFT) {
175                _mesa_error(ctx, GL_INVALID_VALUE,
176                            "glPointParameterf[v]{EXT,ARB}(param)");
177                return;
178             }
179             if (ctx->Point.SpriteOrigin == value)
180                return;
181             FLUSH_VERTICES(ctx, _NEW_POINT, GL_POINT_BIT);
182             ctx->Point.SpriteOrigin = value;
183          }
184          else {
185             _mesa_error(ctx, GL_INVALID_ENUM,
186                         "glPointParameterf[v]{EXT,ARB}(pname)");
187             return;
188          }
189          break;
190       default:
191          _mesa_error( ctx, GL_INVALID_ENUM,
192                       "glPointParameterf[v]{EXT,ARB}(pname)" );
193          return;
194    }
195 }
196 
197 
198 
199 /**
200  * Initialize the context point state.
201  *
202  * \param ctx GL context.
203  *
204  * Initializes __struct gl_contextRec::Point and point related constants in
205  * __struct gl_contextRec::Const.
206  */
207 void
_mesa_init_point(struct gl_context * ctx)208 _mesa_init_point(struct gl_context *ctx)
209 {
210    ctx->Point.SmoothFlag = GL_FALSE;
211    ctx->Point.Size = 1.0;
212    ctx->Point.Params[0] = 1.0;
213    ctx->Point.Params[1] = 0.0;
214    ctx->Point.Params[2] = 0.0;
215    ctx->Point._Attenuated = GL_FALSE;
216    ctx->Point.MinSize = 0.0;
217    ctx->Point.MaxSize
218       = MAX2(ctx->Const.MaxPointSize, ctx->Const.MaxPointSizeAA);
219    ctx->Point.Threshold = 1.0;
220 
221    /* Page 403 (page 423 of the PDF) of the OpenGL 3.0 spec says:
222     *
223     *     "Non-sprite points (section 3.4) - Enable/Disable targets
224     *     POINT_SMOOTH and POINT_SPRITE, and all associated state. Point
225     *     rasterization is always performed as though POINT_SPRITE were
226     *     enabled."
227     *
228     * In a core context, the state will default to true, and the setters and
229     * getters are disabled.
230     */
231    ctx->Point.PointSprite = (ctx->API == API_OPENGL_CORE ||
232                              ctx->API == API_OPENGLES2);
233 
234    ctx->Point.SpriteOrigin = GL_UPPER_LEFT; /* GL_ARB_point_sprite */
235    ctx->Point.CoordReplace = 0; /* GL_ARB_point_sprite */
236 }
237