Merge branch 'asm-shader-rework-2'
[mesa.git] / src / mesa / main / texgen.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.5
4 *
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26 /**
27 * \file texgen.c
28 *
29 * glTexGen-related functions
30 */
31
32
33 #include "main/glheader.h"
34 #include "main/context.h"
35 #include "main/enums.h"
36 #include "main/macros.h"
37 #include "main/texgen.h"
38 #include "main/texstate.h"
39 #include "math/m_matrix.h"
40
41
42 /**
43 * Return texgen state for given coordinate
44 */
45 static struct gl_texgen *
46 get_texgen(struct gl_texture_unit *texUnit, GLenum coord)
47 {
48 switch (coord) {
49 case GL_S:
50 return &texUnit->GenS;
51 case GL_T:
52 return &texUnit->GenT;
53 case GL_R:
54 return &texUnit->GenR;
55 case GL_Q:
56 return &texUnit->GenQ;
57 default:
58 return NULL;
59 }
60 }
61
62
63 void GLAPIENTRY
64 _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
65 {
66 struct gl_texture_unit *texUnit;
67 struct gl_texgen *texgen;
68 GET_CURRENT_CONTEXT(ctx);
69 ASSERT_OUTSIDE_BEGIN_END(ctx);
70
71 if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
72 _mesa_debug(ctx, "glTexGen %s %s %.1f(%s)...\n",
73 _mesa_lookup_enum_by_nr(coord),
74 _mesa_lookup_enum_by_nr(pname),
75 *params,
76 _mesa_lookup_enum_by_nr((GLenum) (GLint) *params));
77
78 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
79 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexGen(current unit)");
80 return;
81 }
82
83 texUnit = _mesa_get_current_tex_unit(ctx);
84
85 texgen = get_texgen(texUnit, coord);
86 if (!texgen) {
87 _mesa_error(ctx, GL_INVALID_ENUM, "glTexGen(coord)");
88 return;
89 }
90
91 switch (pname) {
92 case GL_TEXTURE_GEN_MODE:
93 {
94 GLenum mode = (GLenum) (GLint) params[0];
95 GLbitfield bit = 0x0;
96 if (texgen->Mode == mode)
97 return;
98 switch (mode) {
99 case GL_OBJECT_LINEAR:
100 bit = TEXGEN_OBJ_LINEAR;
101 break;
102 case GL_EYE_LINEAR:
103 bit = TEXGEN_EYE_LINEAR;
104 break;
105 case GL_SPHERE_MAP:
106 if (coord == GL_S || coord == GL_T)
107 bit = TEXGEN_SPHERE_MAP;
108 break;
109 case GL_REFLECTION_MAP_NV:
110 if (coord != GL_Q)
111 bit = TEXGEN_REFLECTION_MAP_NV;
112 break;
113 case GL_NORMAL_MAP_NV:
114 if (coord != GL_Q)
115 bit = TEXGEN_NORMAL_MAP_NV;
116 break;
117 default:
118 ; /* nop */
119 }
120 if (!bit) {
121 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
122 return;
123 }
124 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
125 texgen->Mode = mode;
126 texgen->_ModeBit = bit;
127 }
128 break;
129
130 case GL_OBJECT_PLANE:
131 {
132 if (TEST_EQ_4V(texgen->ObjectPlane, params))
133 return;
134 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
135 COPY_4FV(texgen->ObjectPlane, params);
136 }
137 break;
138
139 case GL_EYE_PLANE:
140 {
141 GLfloat tmp[4];
142 /* Transform plane equation by the inverse modelview matrix */
143 if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
144 _math_matrix_analyse(ctx->ModelviewMatrixStack.Top);
145 }
146 _mesa_transform_vector(tmp, params,
147 ctx->ModelviewMatrixStack.Top->inv);
148 if (TEST_EQ_4V(texgen->EyePlane, tmp))
149 return;
150 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
151 COPY_4FV(texgen->EyePlane, tmp);
152 }
153 break;
154
155 default:
156 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
157 return;
158 }
159
160 if (ctx->Driver.TexGen)
161 ctx->Driver.TexGen( ctx, coord, pname, params );
162 }
163
164
165 void GLAPIENTRY
166 _mesa_TexGeniv(GLenum coord, GLenum pname, const GLint *params )
167 {
168 GLfloat p[4];
169 p[0] = (GLfloat) params[0];
170 if (pname == GL_TEXTURE_GEN_MODE) {
171 p[1] = p[2] = p[3] = 0.0F;
172 }
173 else {
174 p[1] = (GLfloat) params[1];
175 p[2] = (GLfloat) params[2];
176 p[3] = (GLfloat) params[3];
177 }
178 _mesa_TexGenfv(coord, pname, p);
179 }
180
181
182 void GLAPIENTRY
183 _mesa_TexGend(GLenum coord, GLenum pname, GLdouble param )
184 {
185 GLfloat p = (GLfloat) param;
186 _mesa_TexGenfv( coord, pname, &p );
187 }
188
189
190 void GLAPIENTRY
191 _mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params )
192 {
193 GLfloat p[4];
194 p[0] = (GLfloat) params[0];
195 if (pname == GL_TEXTURE_GEN_MODE) {
196 p[1] = p[2] = p[3] = 0.0F;
197 }
198 else {
199 p[1] = (GLfloat) params[1];
200 p[2] = (GLfloat) params[2];
201 p[3] = (GLfloat) params[3];
202 }
203 _mesa_TexGenfv( coord, pname, p );
204 }
205
206
207 void GLAPIENTRY
208 _mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param )
209 {
210 _mesa_TexGenfv(coord, pname, &param);
211 }
212
213
214 void GLAPIENTRY
215 _mesa_TexGeni( GLenum coord, GLenum pname, GLint param )
216 {
217 _mesa_TexGeniv( coord, pname, &param );
218 }
219
220
221
222 void GLAPIENTRY
223 _mesa_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params )
224 {
225 struct gl_texture_unit *texUnit;
226 struct gl_texgen *texgen;
227 GET_CURRENT_CONTEXT(ctx);
228 ASSERT_OUTSIDE_BEGIN_END(ctx);
229
230 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
231 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGendv(current unit)");
232 return;
233 }
234
235 texUnit = _mesa_get_current_tex_unit(ctx);
236
237 texgen = get_texgen(texUnit, coord);
238 if (!texgen) {
239 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexGendv(coord)");
240 return;
241 }
242
243 switch (pname) {
244 case GL_TEXTURE_GEN_MODE:
245 params[0] = ENUM_TO_DOUBLE(texgen->Mode);
246 break;
247 case GL_OBJECT_PLANE:
248 COPY_4V(params, texgen->ObjectPlane);
249 break;
250 case GL_EYE_PLANE:
251 COPY_4V(params, texgen->EyePlane);
252 break;
253 default:
254 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
255 }
256 }
257
258
259
260 void GLAPIENTRY
261 _mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params )
262 {
263 struct gl_texture_unit *texUnit;
264 struct gl_texgen *texgen;
265 GET_CURRENT_CONTEXT(ctx);
266 ASSERT_OUTSIDE_BEGIN_END(ctx);
267
268 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
269 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGenfv(current unit)");
270 return;
271 }
272
273 texUnit = _mesa_get_current_tex_unit(ctx);
274
275 texgen = get_texgen(texUnit, coord);
276 if (!texgen) {
277 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexGenfv(coord)");
278 return;
279 }
280
281 switch (pname) {
282 case GL_TEXTURE_GEN_MODE:
283 params[0] = ENUM_TO_FLOAT(texgen->Mode);
284 break;
285 case GL_OBJECT_PLANE:
286 COPY_4V(params, texgen->ObjectPlane);
287 break;
288 case GL_EYE_PLANE:
289 COPY_4V(params, texgen->EyePlane);
290 break;
291 default:
292 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
293 }
294 }
295
296
297
298 void GLAPIENTRY
299 _mesa_GetTexGeniv( GLenum coord, GLenum pname, GLint *params )
300 {
301 struct gl_texture_unit *texUnit;
302 struct gl_texgen *texgen;
303 GET_CURRENT_CONTEXT(ctx);
304 ASSERT_OUTSIDE_BEGIN_END(ctx);
305
306 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
307 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGeniv(current unit)");
308 return;
309 }
310
311 texUnit = _mesa_get_current_tex_unit(ctx);
312
313 texgen = get_texgen(texUnit, coord);
314 if (!texgen) {
315 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexGeniv(coord)");
316 return;
317 }
318
319 switch (pname) {
320 case GL_TEXTURE_GEN_MODE:
321 params[0] = texgen->Mode;
322 break;
323 case GL_OBJECT_PLANE:
324 params[0] = (GLint) texgen->ObjectPlane[0];
325 params[1] = (GLint) texgen->ObjectPlane[1];
326 params[2] = (GLint) texgen->ObjectPlane[2];
327 params[3] = (GLint) texgen->ObjectPlane[3];
328 break;
329 case GL_EYE_PLANE:
330 params[0] = (GLint) texgen->EyePlane[0];
331 params[1] = (GLint) texgen->EyePlane[1];
332 params[2] = (GLint) texgen->EyePlane[2];
333 params[3] = (GLint) texgen->EyePlane[3];
334 break;
335 default:
336 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
337 }
338 }
339
340