Merge branch '965-glsl'
[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 * BRIAN PAUL 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 "texstate.h"
36 #include "mtypes.h"
37
38
39 /**
40 * Set current point size.
41 * \param size point diameter in pixels
42 * \sa glPointSize().
43 */
44 void GLAPIENTRY
45 _mesa_PointSize( GLfloat size )
46 {
47 GET_CURRENT_CONTEXT(ctx);
48 ASSERT_OUTSIDE_BEGIN_END(ctx);
49
50 if (size <= 0.0) {
51 _mesa_error( ctx, GL_INVALID_VALUE, "glPointSize" );
52 return;
53 }
54
55 if (ctx->Point.Size == size)
56 return;
57
58 FLUSH_VERTICES(ctx, _NEW_POINT);
59 ctx->Point.Size = size;
60
61 if (ctx->Driver.PointSize)
62 ctx->Driver.PointSize(ctx, size);
63 }
64
65
66 #if _HAVE_FULL_GL
67
68 /*
69 * Added by GL_NV_point_sprite
70 */
71 void GLAPIENTRY
72 _mesa_PointParameteriNV( GLenum pname, GLint param )
73 {
74 const GLfloat value = (GLfloat) param;
75 _mesa_PointParameterfvEXT(pname, &value);
76 }
77
78
79 /*
80 * Added by GL_NV_point_sprite
81 */
82 void GLAPIENTRY
83 _mesa_PointParameterivNV( GLenum pname, const GLint *params )
84 {
85 GLfloat p[3];
86 p[0] = (GLfloat) params[0];
87 if (pname == GL_DISTANCE_ATTENUATION_EXT) {
88 p[1] = (GLfloat) params[1];
89 p[2] = (GLfloat) params[2];
90 }
91 _mesa_PointParameterfvEXT(pname, p);
92 }
93
94
95
96 /*
97 * Same for both GL_EXT_point_parameters and GL_ARB_point_parameters.
98 */
99 void GLAPIENTRY
100 _mesa_PointParameterfEXT( GLenum pname, GLfloat param)
101 {
102 _mesa_PointParameterfvEXT(pname, &param);
103 }
104
105
106
107 /*
108 * Same for both GL_EXT_point_parameters and GL_ARB_point_parameters.
109 */
110 void GLAPIENTRY
111 _mesa_PointParameterfvEXT( GLenum pname, const GLfloat *params)
112 {
113 GET_CURRENT_CONTEXT(ctx);
114 ASSERT_OUTSIDE_BEGIN_END(ctx);
115
116 switch (pname) {
117 case GL_DISTANCE_ATTENUATION_EXT:
118 if (ctx->Extensions.EXT_point_parameters) {
119 if (TEST_EQ_3V(ctx->Point.Params, params))
120 return;
121 FLUSH_VERTICES(ctx, _NEW_POINT);
122 COPY_3V(ctx->Point.Params, params);
123 ctx->Point._Attenuated = (ctx->Point.Params[0] != 1.0 ||
124 ctx->Point.Params[1] != 0.0 ||
125 ctx->Point.Params[2] != 0.0);
126
127 if (ctx->Point._Attenuated)
128 ctx->_TriangleCaps |= DD_POINT_ATTEN;
129 else
130 ctx->_TriangleCaps &= ~DD_POINT_ATTEN;
131 }
132 else {
133 _mesa_error(ctx, GL_INVALID_ENUM,
134 "glPointParameterf[v]{EXT,ARB}(pname)");
135 return;
136 }
137 break;
138 case GL_POINT_SIZE_MIN_EXT:
139 if (ctx->Extensions.EXT_point_parameters) {
140 if (params[0] < 0.0F) {
141 _mesa_error( ctx, GL_INVALID_VALUE,
142 "glPointParameterf[v]{EXT,ARB}(param)" );
143 return;
144 }
145 if (ctx->Point.MinSize == params[0])
146 return;
147 FLUSH_VERTICES(ctx, _NEW_POINT);
148 ctx->Point.MinSize = params[0];
149 }
150 else {
151 _mesa_error(ctx, GL_INVALID_ENUM,
152 "glPointParameterf[v]{EXT,ARB}(pname)");
153 return;
154 }
155 break;
156 case GL_POINT_SIZE_MAX_EXT:
157 if (ctx->Extensions.EXT_point_parameters) {
158 if (params[0] < 0.0F) {
159 _mesa_error( ctx, GL_INVALID_VALUE,
160 "glPointParameterf[v]{EXT,ARB}(param)" );
161 return;
162 }
163 if (ctx->Point.MaxSize == params[0])
164 return;
165 FLUSH_VERTICES(ctx, _NEW_POINT);
166 ctx->Point.MaxSize = params[0];
167 }
168 else {
169 _mesa_error(ctx, GL_INVALID_ENUM,
170 "glPointParameterf[v]{EXT,ARB}(pname)");
171 return;
172 }
173 break;
174 case GL_POINT_FADE_THRESHOLD_SIZE_EXT:
175 if (ctx->Extensions.EXT_point_parameters) {
176 if (params[0] < 0.0F) {
177 _mesa_error( ctx, GL_INVALID_VALUE,
178 "glPointParameterf[v]{EXT,ARB}(param)" );
179 return;
180 }
181 if (ctx->Point.Threshold == params[0])
182 return;
183 FLUSH_VERTICES(ctx, _NEW_POINT);
184 ctx->Point.Threshold = params[0];
185 }
186 else {
187 _mesa_error(ctx, GL_INVALID_ENUM,
188 "glPointParameterf[v]{EXT,ARB}(pname)");
189 return;
190 }
191 break;
192 case GL_POINT_SPRITE_R_MODE_NV:
193 /* This is one area where ARB_point_sprite and NV_point_sprite
194 * differ. In ARB_point_sprite the POINT_SPRITE_R_MODE is
195 * always ZERO. NV_point_sprite adds the S and R modes.
196 */
197 if (ctx->Extensions.NV_point_sprite) {
198 GLenum value = (GLenum) params[0];
199 if (value != GL_ZERO && value != GL_S && value != GL_R) {
200 _mesa_error(ctx, GL_INVALID_VALUE,
201 "glPointParameterf[v]{EXT,ARB}(param)");
202 return;
203 }
204 if (ctx->Point.SpriteRMode == value)
205 return;
206 FLUSH_VERTICES(ctx, _NEW_POINT);
207 ctx->Point.SpriteRMode = value;
208 }
209 else {
210 _mesa_error(ctx, GL_INVALID_ENUM,
211 "glPointParameterf[v]{EXT,ARB}(pname)");
212 return;
213 }
214 break;
215 case GL_POINT_SPRITE_COORD_ORIGIN:
216 if (ctx->Extensions.ARB_point_sprite) {
217 GLenum value = (GLenum) params[0];
218 if (value != GL_LOWER_LEFT && value != GL_UPPER_LEFT) {
219 _mesa_error(ctx, GL_INVALID_VALUE,
220 "glPointParameterf[v]{EXT,ARB}(param)");
221 return;
222 }
223 if (ctx->Point.SpriteOrigin == value)
224 return;
225 FLUSH_VERTICES(ctx, _NEW_POINT);
226 ctx->Point.SpriteOrigin = value;
227 }
228 else {
229 _mesa_error(ctx, GL_INVALID_ENUM,
230 "glPointParameterf[v]{EXT,ARB}(pname)");
231 return;
232 }
233 break;
234 default:
235 _mesa_error( ctx, GL_INVALID_ENUM,
236 "glPointParameterf[v]{EXT,ARB}(pname)" );
237 return;
238 }
239
240 if (ctx->Driver.PointParameterfv)
241 (*ctx->Driver.PointParameterfv)(ctx, pname, params);
242 }
243 #endif
244
245
246
247 /**
248 * Initialize the context point state.
249 *
250 * \param ctx GL context.
251 *
252 * Initializes __GLcontextRec::Point and point related constants in
253 * __GLcontextRec::Const.
254 */
255 void
256 _mesa_init_point(GLcontext *ctx)
257 {
258 GLuint i;
259
260 ctx->Point.SmoothFlag = GL_FALSE;
261 ctx->Point.Size = 1.0;
262 ctx->Point.Params[0] = 1.0;
263 ctx->Point.Params[1] = 0.0;
264 ctx->Point.Params[2] = 0.0;
265 ctx->Point._Attenuated = GL_FALSE;
266 ctx->Point.MinSize = 0.0;
267 ctx->Point.MaxSize
268 = MAX2(ctx->Const.MaxPointSize, ctx->Const.MaxPointSizeAA);
269 ctx->Point.Threshold = 1.0;
270 ctx->Point.PointSprite = GL_FALSE; /* GL_ARB/NV_point_sprite */
271 ctx->Point.SpriteRMode = GL_ZERO; /* GL_NV_point_sprite (only!) */
272 ctx->Point.SpriteOrigin = GL_UPPER_LEFT; /* GL_ARB_point_sprite */
273 for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
274 ctx->Point.CoordReplace[i] = GL_FALSE; /* GL_ARB/NV_point_sprite */
275 }
276 }