mesa: replace _mesa_get_current_fixedfunc_tex_unit with _mesa_get_fixedfunc_tex_unit
[mesa.git] / src / mesa / main / texgen.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
5 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * 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_context *ctx, struct gl_fixedfunc_texture_unit *texUnit,
47 GLenum coord)
48 {
49 if (ctx->API == API_OPENGLES) {
50 return (coord == GL_TEXTURE_GEN_STR_OES)
51 ? &texUnit->GenS : NULL;
52 }
53
54 switch (coord) {
55 case GL_S:
56 return &texUnit->GenS;
57 case GL_T:
58 return &texUnit->GenT;
59 case GL_R:
60 return &texUnit->GenR;
61 case GL_Q:
62 return &texUnit->GenQ;
63 default:
64 return NULL;
65 }
66 }
67
68
69 void GLAPIENTRY
70 _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
71 {
72 struct gl_fixedfunc_texture_unit *texUnit;
73 struct gl_texgen *texgen;
74 GET_CURRENT_CONTEXT(ctx);
75
76 if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
77 _mesa_debug(ctx, "glTexGen %s %s %.1f(%s)...\n",
78 _mesa_enum_to_string(coord),
79 _mesa_enum_to_string(pname),
80 *params,
81 _mesa_enum_to_string((GLenum) (GLint) *params));
82
83 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
84 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexGen(current unit)");
85 return;
86 }
87
88 texUnit = _mesa_get_fixedfunc_tex_unit(ctx, ctx->Texture.CurrentUnit);
89
90 texgen = get_texgen(ctx, texUnit, coord);
91 if (!texgen) {
92 _mesa_error(ctx, GL_INVALID_ENUM, "glTexGen(coord)");
93 return;
94 }
95
96 switch (pname) {
97 case GL_TEXTURE_GEN_MODE:
98 {
99 GLenum mode = (GLenum) (GLint) params[0];
100 GLbitfield bit = 0x0;
101 if (texgen->Mode == mode)
102 return;
103 switch (mode) {
104 case GL_OBJECT_LINEAR:
105 bit = TEXGEN_OBJ_LINEAR;
106 break;
107 case GL_EYE_LINEAR:
108 bit = TEXGEN_EYE_LINEAR;
109 break;
110 case GL_SPHERE_MAP:
111 if (coord == GL_S || coord == GL_T)
112 bit = TEXGEN_SPHERE_MAP;
113 break;
114 case GL_REFLECTION_MAP_NV:
115 if (coord != GL_Q)
116 bit = TEXGEN_REFLECTION_MAP_NV;
117 break;
118 case GL_NORMAL_MAP_NV:
119 if (coord != GL_Q)
120 bit = TEXGEN_NORMAL_MAP_NV;
121 break;
122 default:
123 ; /* nop */
124 }
125 if (!bit) {
126 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
127 return;
128 }
129 if (ctx->API != API_OPENGL_COMPAT
130 && (bit & (TEXGEN_REFLECTION_MAP_NV | TEXGEN_NORMAL_MAP_NV)) == 0) {
131 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
132 return;
133 }
134
135 FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE);
136 texgen->Mode = mode;
137 texgen->_ModeBit = bit;
138 }
139 break;
140
141 case GL_OBJECT_PLANE:
142 {
143 if (ctx->API != API_OPENGL_COMPAT) {
144 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
145 return;
146 }
147 if (TEST_EQ_4V(texgen->ObjectPlane, params))
148 return;
149 FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE);
150 COPY_4FV(texgen->ObjectPlane, params);
151 }
152 break;
153
154 case GL_EYE_PLANE:
155 {
156 GLfloat tmp[4];
157
158 if (ctx->API != API_OPENGL_COMPAT) {
159 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
160 return;
161 }
162
163 /* Transform plane equation by the inverse modelview matrix */
164 if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
165 _math_matrix_analyse(ctx->ModelviewMatrixStack.Top);
166 }
167 _mesa_transform_vector(tmp, params,
168 ctx->ModelviewMatrixStack.Top->inv);
169 if (TEST_EQ_4V(texgen->EyePlane, tmp))
170 return;
171 FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE);
172 COPY_4FV(texgen->EyePlane, tmp);
173 }
174 break;
175
176 default:
177 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
178 return;
179 }
180
181 if (ctx->Driver.TexGen)
182 ctx->Driver.TexGen( ctx, coord, pname, params );
183 }
184
185
186 void GLAPIENTRY
187 _mesa_TexGeniv(GLenum coord, GLenum pname, const GLint *params )
188 {
189 GLfloat p[4];
190 p[0] = (GLfloat) params[0];
191 if (pname == GL_TEXTURE_GEN_MODE) {
192 p[1] = p[2] = p[3] = 0.0F;
193 }
194 else {
195 p[1] = (GLfloat) params[1];
196 p[2] = (GLfloat) params[2];
197 p[3] = (GLfloat) params[3];
198 }
199 _mesa_TexGenfv(coord, pname, p);
200 }
201
202
203 void GLAPIENTRY
204 _mesa_TexGend(GLenum coord, GLenum pname, GLdouble param )
205 {
206 GLfloat p[4];
207 p[0] = (GLfloat) param;
208 p[1] = p[2] = p[3] = 0.0F;
209 _mesa_TexGenfv( coord, pname, p );
210 }
211
212
213 void GLAPIENTRY
214 _es_GetTexGenfv(GLenum coord, GLenum pname, GLfloat *params)
215 {
216 _mesa_GetTexGenfv(GL_S, pname, params);
217 }
218
219
220 void GLAPIENTRY
221 _es_TexGenf(GLenum coord, GLenum pname, GLfloat param)
222 {
223 if (coord != GL_TEXTURE_GEN_STR_OES) {
224 GET_CURRENT_CONTEXT(ctx);
225 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGen[fx](pname)" );
226 return;
227 }
228 /* set S, T, and R at the same time */
229 _mesa_TexGenf(GL_S, pname, param);
230 _mesa_TexGenf(GL_T, pname, param);
231 _mesa_TexGenf(GL_R, pname, param);
232 }
233
234
235 void GLAPIENTRY
236 _es_TexGenfv(GLenum coord, GLenum pname, const GLfloat *params)
237 {
238 if (coord != GL_TEXTURE_GEN_STR_OES) {
239 GET_CURRENT_CONTEXT(ctx);
240 _mesa_error( ctx, GL_INVALID_ENUM, "glTexGen[fx]v(pname)" );
241 return;
242 }
243 /* set S, T, and R at the same time */
244 _mesa_TexGenfv(GL_S, pname, params);
245 _mesa_TexGenfv(GL_T, pname, params);
246 _mesa_TexGenfv(GL_R, pname, params);
247 }
248
249
250 void GLAPIENTRY
251 _mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params )
252 {
253 GLfloat p[4];
254 p[0] = (GLfloat) params[0];
255 if (pname == GL_TEXTURE_GEN_MODE) {
256 p[1] = p[2] = p[3] = 0.0F;
257 }
258 else {
259 p[1] = (GLfloat) params[1];
260 p[2] = (GLfloat) params[2];
261 p[3] = (GLfloat) params[3];
262 }
263 _mesa_TexGenfv( coord, pname, p );
264 }
265
266
267 void GLAPIENTRY
268 _mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param )
269 {
270 GLfloat p[4];
271 p[0] = param;
272 p[1] = p[2] = p[3] = 0.0F;
273 _mesa_TexGenfv(coord, pname, p);
274 }
275
276
277 void GLAPIENTRY
278 _mesa_TexGeni( GLenum coord, GLenum pname, GLint param )
279 {
280 GLint p[4];
281 p[0] = param;
282 p[1] = p[2] = p[3] = 0;
283 _mesa_TexGeniv( coord, pname, p );
284 }
285
286
287
288 void GLAPIENTRY
289 _mesa_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params )
290 {
291 struct gl_fixedfunc_texture_unit *texUnit;
292 struct gl_texgen *texgen;
293 GET_CURRENT_CONTEXT(ctx);
294
295 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
296 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGendv(current unit)");
297 return;
298 }
299
300 texUnit = _mesa_get_fixedfunc_tex_unit(ctx, ctx->Texture.CurrentUnit);
301
302 texgen = get_texgen(ctx, texUnit, coord);
303 if (!texgen) {
304 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexGendv(coord)");
305 return;
306 }
307
308 switch (pname) {
309 case GL_TEXTURE_GEN_MODE:
310 params[0] = ENUM_TO_DOUBLE(texgen->Mode);
311 break;
312 case GL_OBJECT_PLANE:
313 COPY_4V(params, texgen->ObjectPlane);
314 break;
315 case GL_EYE_PLANE:
316 COPY_4V(params, texgen->EyePlane);
317 break;
318 default:
319 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
320 }
321 }
322
323
324
325 void GLAPIENTRY
326 _mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params )
327 {
328 struct gl_fixedfunc_texture_unit *texUnit;
329 struct gl_texgen *texgen;
330 GET_CURRENT_CONTEXT(ctx);
331
332 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
333 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGenfv(current unit)");
334 return;
335 }
336
337 texUnit = _mesa_get_fixedfunc_tex_unit(ctx, ctx->Texture.CurrentUnit);
338
339 texgen = get_texgen(ctx, texUnit, coord);
340 if (!texgen) {
341 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexGenfv(coord)");
342 return;
343 }
344
345 switch (pname) {
346 case GL_TEXTURE_GEN_MODE:
347 params[0] = ENUM_TO_FLOAT(texgen->Mode);
348 break;
349 case GL_OBJECT_PLANE:
350 if (ctx->API != API_OPENGL_COMPAT) {
351 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(param)" );
352 return;
353 }
354 COPY_4V(params, texgen->ObjectPlane);
355 break;
356 case GL_EYE_PLANE:
357 if (ctx->API != API_OPENGL_COMPAT) {
358 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(param)" );
359 return;
360 }
361 COPY_4V(params, texgen->EyePlane);
362 break;
363 default:
364 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
365 }
366 }
367
368
369
370 void GLAPIENTRY
371 _mesa_GetTexGeniv( GLenum coord, GLenum pname, GLint *params )
372 {
373 struct gl_fixedfunc_texture_unit *texUnit;
374 struct gl_texgen *texgen;
375 GET_CURRENT_CONTEXT(ctx);
376
377 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
378 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGeniv(current unit)");
379 return;
380 }
381
382 texUnit = _mesa_get_fixedfunc_tex_unit(ctx, ctx->Texture.CurrentUnit);
383
384 texgen = get_texgen(ctx, texUnit, coord);
385 if (!texgen) {
386 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexGeniv(coord)");
387 return;
388 }
389
390 switch (pname) {
391 case GL_TEXTURE_GEN_MODE:
392 params[0] = texgen->Mode;
393 break;
394 case GL_OBJECT_PLANE:
395 if (ctx->API != API_OPENGL_COMPAT) {
396 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(param)" );
397 return;
398 }
399 params[0] = (GLint) texgen->ObjectPlane[0];
400 params[1] = (GLint) texgen->ObjectPlane[1];
401 params[2] = (GLint) texgen->ObjectPlane[2];
402 params[3] = (GLint) texgen->ObjectPlane[3];
403 break;
404 case GL_EYE_PLANE:
405 if (ctx->API != API_OPENGL_COMPAT) {
406 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(param)" );
407 return;
408 }
409 params[0] = (GLint) texgen->EyePlane[0];
410 params[1] = (GLint) texgen->EyePlane[1];
411 params[2] = (GLint) texgen->EyePlane[2];
412 params[3] = (GLint) texgen->EyePlane[3];
413 break;
414 default:
415 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
416 }
417 }