OSDN Git Service

mesa: Change "BRIAN PAUL" to "THE AUTHORS" in license text.
[android-x86/external-mesa.git] / src / mesa / main / points.c
1 /**
2  * \file points.c
3  * Point operations.
4  */
5
6 /*
7  * Mesa 3-D graphics library
8  * Version:  7.1
9  *
10  * Copyright (C) 1999-2007  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  * THE AUTHORS 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 "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.0) {
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.0 ||
123                                    ctx->Point.Params[1] != 0.0 ||
124                                    ctx->Point.Params[2] != 0.0);
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    GLuint i;
229
230    ctx->Point.SmoothFlag = GL_FALSE;
231    ctx->Point.Size = 1.0;
232    ctx->Point.Params[0] = 1.0;
233    ctx->Point.Params[1] = 0.0;
234    ctx->Point.Params[2] = 0.0;
235    ctx->Point._Attenuated = GL_FALSE;
236    ctx->Point.MinSize = 0.0;
237    ctx->Point.MaxSize
238       = MAX2(ctx->Const.MaxPointSize, ctx->Const.MaxPointSizeAA);
239    ctx->Point.Threshold = 1.0;
240
241    /* Page 403 (page 423 of the PDF) of the OpenGL 3.0 spec says:
242     *
243     *     "Non-sprite points (section 3.4) - Enable/Disable targets
244     *     POINT_SMOOTH and POINT_SPRITE, and all associated state. Point
245     *     rasterization is always performed as though POINT_SPRITE were
246     *     enabled."
247     *
248     * In a core context, the state will default to true, and the setters and
249     * getters are disabled.
250     */
251    ctx->Point.PointSprite = (ctx->API == API_OPENGL_CORE ||
252                              ctx->API == API_OPENGLES2);
253
254    ctx->Point.SpriteRMode = GL_ZERO; /* GL_NV_point_sprite (only!) */
255    ctx->Point.SpriteOrigin = GL_UPPER_LEFT; /* GL_ARB_point_sprite */
256    for (i = 0; i < Elements(ctx->Point.CoordReplace); i++) {
257       ctx->Point.CoordReplace[i] = GL_FALSE; /* GL_ARB/NV_point_sprite */
258    }
259 }