2 * Mesa 3-D graphics library
4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
5 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
29 * glTexGen-related functions
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"
43 * Return texgen state for given coordinate
45 static struct gl_texgen
*
46 get_texgen(struct gl_context
*ctx
, GLuint texunitIndex
, GLenum coord
, const char* caller
)
48 struct gl_fixedfunc_texture_unit
* texUnit
;
49 if (texunitIndex
>= ctx
->Const
.MaxTextureCoordUnits
) {
50 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s(unit=%d)", caller
, texunitIndex
);
54 texUnit
= _mesa_get_fixedfunc_tex_unit(ctx
, texunitIndex
);
56 if (ctx
->API
== API_OPENGLES
) {
57 return (coord
== GL_TEXTURE_GEN_STR_OES
)
58 ? &texUnit
->GenS
: NULL
;
63 return &texUnit
->GenS
;
65 return &texUnit
->GenT
;
67 return &texUnit
->GenR
;
69 return &texUnit
->GenQ
;
76 /* Helper for glTexGenfv and glMultiTexGenfvEXT functions */
78 texgenfv( GLuint texunitIndex
, GLenum coord
, GLenum pname
,
79 const GLfloat
*params
, const char* caller
)
81 struct gl_texgen
*texgen
;
82 GET_CURRENT_CONTEXT(ctx
);
84 texgen
= get_texgen(ctx
, texunitIndex
, coord
, caller
);
86 _mesa_error(ctx
, GL_INVALID_ENUM
, "%s(coord)", caller
);
91 case GL_TEXTURE_GEN_MODE
:
93 GLenum mode
= (GLenum
) (GLint
) params
[0];
95 if (texgen
->Mode
== mode
)
98 case GL_OBJECT_LINEAR
:
99 bit
= TEXGEN_OBJ_LINEAR
;
102 bit
= TEXGEN_EYE_LINEAR
;
105 if (coord
== GL_S
|| coord
== GL_T
)
106 bit
= TEXGEN_SPHERE_MAP
;
108 case GL_REFLECTION_MAP_NV
:
110 bit
= TEXGEN_REFLECTION_MAP_NV
;
112 case GL_NORMAL_MAP_NV
:
114 bit
= TEXGEN_NORMAL_MAP_NV
;
120 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexGenfv(param)" );
123 if (ctx
->API
!= API_OPENGL_COMPAT
124 && (bit
& (TEXGEN_REFLECTION_MAP_NV
| TEXGEN_NORMAL_MAP_NV
)) == 0) {
125 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexGenfv(param)" );
129 FLUSH_VERTICES(ctx
, _NEW_TEXTURE_STATE
);
131 texgen
->_ModeBit
= bit
;
135 case GL_OBJECT_PLANE
:
137 if (ctx
->API
!= API_OPENGL_COMPAT
) {
138 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexGenfv(param)" );
141 if (TEST_EQ_4V(texgen
->ObjectPlane
, params
))
143 FLUSH_VERTICES(ctx
, _NEW_TEXTURE_STATE
);
144 COPY_4FV(texgen
->ObjectPlane
, params
);
152 if (ctx
->API
!= API_OPENGL_COMPAT
) {
153 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexGenfv(param)" );
157 /* Transform plane equation by the inverse modelview matrix */
158 if (_math_matrix_is_dirty(ctx
->ModelviewMatrixStack
.Top
)) {
159 _math_matrix_analyse(ctx
->ModelviewMatrixStack
.Top
);
161 _mesa_transform_vector(tmp
, params
,
162 ctx
->ModelviewMatrixStack
.Top
->inv
);
163 if (TEST_EQ_4V(texgen
->EyePlane
, tmp
))
165 FLUSH_VERTICES(ctx
, _NEW_TEXTURE_STATE
);
166 COPY_4FV(texgen
->EyePlane
, tmp
);
171 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexGenfv(pname)" );
175 if (ctx
->Driver
.TexGen
)
176 ctx
->Driver
.TexGen( ctx
, coord
, pname
, params
);
180 /* Helper for glGetTexGendv / glGetMultiTexGendvEXT */
182 gettexgendv( GLuint texunitIndex
, GLenum coord
, GLenum pname
,
183 GLdouble
*params
, const char* caller
)
185 struct gl_texgen
*texgen
;
186 GET_CURRENT_CONTEXT(ctx
);
188 texgen
= get_texgen(ctx
, texunitIndex
, coord
, caller
);
190 _mesa_error(ctx
, GL_INVALID_ENUM
, "%s(coord)", caller
);
195 case GL_TEXTURE_GEN_MODE
:
196 params
[0] = ENUM_TO_DOUBLE(texgen
->Mode
);
198 case GL_OBJECT_PLANE
:
199 COPY_4V(params
, texgen
->ObjectPlane
);
202 COPY_4V(params
, texgen
->EyePlane
);
205 _mesa_error( ctx
, GL_INVALID_ENUM
, "%s(pname)", caller
);
210 /* Helper for glGetTexGenfv / glGetMultiTexGenfvEXT */
212 gettexgenfv( GLenum texunitIndex
, GLenum coord
, GLenum pname
,
213 GLfloat
*params
, const char* caller
)
215 struct gl_texgen
*texgen
;
216 GET_CURRENT_CONTEXT(ctx
);
218 texgen
= get_texgen(ctx
, texunitIndex
, coord
, caller
);
220 _mesa_error(ctx
, GL_INVALID_ENUM
, "%s(coord)", caller
);
225 case GL_TEXTURE_GEN_MODE
:
226 params
[0] = ENUM_TO_FLOAT(texgen
->Mode
);
228 case GL_OBJECT_PLANE
:
229 if (ctx
->API
!= API_OPENGL_COMPAT
) {
230 _mesa_error( ctx
, GL_INVALID_ENUM
, "%s(param)", caller
);
233 COPY_4V(params
, texgen
->ObjectPlane
);
236 if (ctx
->API
!= API_OPENGL_COMPAT
) {
237 _mesa_error( ctx
, GL_INVALID_ENUM
, "%s(param)", caller
);
240 COPY_4V(params
, texgen
->EyePlane
);
243 _mesa_error( ctx
, GL_INVALID_ENUM
, "%s(pname)", caller
);
248 /* Helper for glGetTexGeniv / glGetMultiTexGenivEXT */
250 gettexgeniv( GLenum texunitIndex
, GLenum coord
, GLenum pname
,
251 GLint
*params
, const char* caller
)
253 struct gl_texgen
*texgen
;
254 GET_CURRENT_CONTEXT(ctx
);
256 texgen
= get_texgen(ctx
, texunitIndex
, coord
, caller
);
258 _mesa_error(ctx
, GL_INVALID_ENUM
, "%s(coord)", caller
);
263 case GL_TEXTURE_GEN_MODE
:
264 params
[0] = texgen
->Mode
;
266 case GL_OBJECT_PLANE
:
267 if (ctx
->API
!= API_OPENGL_COMPAT
) {
268 _mesa_error( ctx
, GL_INVALID_ENUM
, "%s(param)" , caller
);
271 params
[0] = (GLint
) texgen
->ObjectPlane
[0];
272 params
[1] = (GLint
) texgen
->ObjectPlane
[1];
273 params
[2] = (GLint
) texgen
->ObjectPlane
[2];
274 params
[3] = (GLint
) texgen
->ObjectPlane
[3];
277 if (ctx
->API
!= API_OPENGL_COMPAT
) {
278 _mesa_error( ctx
, GL_INVALID_ENUM
, "%s(param)" , caller
);
281 params
[0] = (GLint
) texgen
->EyePlane
[0];
282 params
[1] = (GLint
) texgen
->EyePlane
[1];
283 params
[2] = (GLint
) texgen
->EyePlane
[2];
284 params
[3] = (GLint
) texgen
->EyePlane
[3];
287 _mesa_error( ctx
, GL_INVALID_ENUM
, "%s(pname)" , caller
);
293 _mesa_TexGenfv( GLenum coord
, GLenum pname
, const GLfloat
*params
)
295 GET_CURRENT_CONTEXT(ctx
);
296 texgenfv(ctx
->Texture
.CurrentUnit
, coord
, pname
, params
, "glTexGenfv");
301 _mesa_MultiTexGenfvEXT( GLenum texunit
, GLenum coord
, GLenum pname
, const GLfloat
*params
)
303 texgenfv(texunit
- GL_TEXTURE0
, coord
, pname
, params
, "glMultiTexGenfvEXT");
308 _mesa_TexGeniv(GLenum coord
, GLenum pname
, const GLint
*params
)
310 GET_CURRENT_CONTEXT(ctx
);
312 p
[0] = (GLfloat
) params
[0];
313 if (pname
== GL_TEXTURE_GEN_MODE
) {
314 p
[1] = p
[2] = p
[3] = 0.0F
;
317 p
[1] = (GLfloat
) params
[1];
318 p
[2] = (GLfloat
) params
[2];
319 p
[3] = (GLfloat
) params
[3];
321 texgenfv(ctx
->Texture
.CurrentUnit
, coord
, pname
, p
, "glTexGeniv");
325 _mesa_MultiTexGenivEXT(GLenum texunit
, GLenum coord
, GLenum pname
, const GLint
*params
)
328 p
[0] = (GLfloat
) params
[0];
329 if (pname
== GL_TEXTURE_GEN_MODE
) {
330 p
[1] = p
[2] = p
[3] = 0.0F
;
333 p
[1] = (GLfloat
) params
[1];
334 p
[2] = (GLfloat
) params
[2];
335 p
[3] = (GLfloat
) params
[3];
337 texgenfv(texunit
- GL_TEXTURE0
, coord
, pname
, p
, "glMultiTexGenivEXT");
342 _mesa_TexGend(GLenum coord
, GLenum pname
, GLdouble param
)
344 GET_CURRENT_CONTEXT(ctx
);
346 p
[0] = (GLfloat
) param
;
347 p
[1] = p
[2] = p
[3] = 0.0F
;
348 texgenfv(ctx
->Texture
.CurrentUnit
, coord
, pname
, p
, "glTexGend");
353 _mesa_MultiTexGendEXT(GLenum texunit
, GLenum coord
, GLenum pname
, GLdouble param
)
356 p
[0] = (GLfloat
) param
;
357 p
[1] = p
[2] = p
[3] = 0.0F
;
358 texgenfv(texunit
- GL_TEXTURE0
, coord
, pname
, p
, "glMultiTexGendEXT");
362 _es_GetTexGenfv(GLenum coord
, GLenum pname
, GLfloat
*params
)
364 _mesa_GetTexGenfv(GL_S
, pname
, params
);
369 _es_TexGenf(GLenum coord
, GLenum pname
, GLfloat param
)
371 if (coord
!= GL_TEXTURE_GEN_STR_OES
) {
372 GET_CURRENT_CONTEXT(ctx
);
373 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexGen[fx](pname)" );
376 /* set S, T, and R at the same time */
377 _mesa_TexGenf(GL_S
, pname
, param
);
378 _mesa_TexGenf(GL_T
, pname
, param
);
379 _mesa_TexGenf(GL_R
, pname
, param
);
384 _es_TexGenfv(GLenum coord
, GLenum pname
, const GLfloat
*params
)
386 if (coord
!= GL_TEXTURE_GEN_STR_OES
) {
387 GET_CURRENT_CONTEXT(ctx
);
388 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexGen[fx]v(pname)" );
391 /* set S, T, and R at the same time */
392 _mesa_TexGenfv(GL_S
, pname
, params
);
393 _mesa_TexGenfv(GL_T
, pname
, params
);
394 _mesa_TexGenfv(GL_R
, pname
, params
);
399 _mesa_TexGendv(GLenum coord
, GLenum pname
, const GLdouble
*params
)
401 GET_CURRENT_CONTEXT(ctx
);
403 p
[0] = (GLfloat
) params
[0];
404 if (pname
== GL_TEXTURE_GEN_MODE
) {
405 p
[1] = p
[2] = p
[3] = 0.0F
;
408 p
[1] = (GLfloat
) params
[1];
409 p
[2] = (GLfloat
) params
[2];
410 p
[3] = (GLfloat
) params
[3];
412 texgenfv(ctx
->Texture
.CurrentUnit
, coord
, pname
, p
, "glTexGendv");
417 _mesa_MultiTexGendvEXT(GLenum texunit
, GLenum coord
, GLenum pname
, const GLdouble
*params
)
420 p
[0] = (GLfloat
) params
[0];
421 if (pname
== GL_TEXTURE_GEN_MODE
) {
422 p
[1] = p
[2] = p
[3] = 0.0F
;
425 p
[1] = (GLfloat
) params
[1];
426 p
[2] = (GLfloat
) params
[2];
427 p
[3] = (GLfloat
) params
[3];
429 texgenfv(texunit
- GL_TEXTURE0
, coord
, pname
, p
, "glMultiTexGendvEXT");
434 _mesa_TexGenf( GLenum coord
, GLenum pname
, GLfloat param
)
436 GET_CURRENT_CONTEXT(ctx
);
439 p
[1] = p
[2] = p
[3] = 0.0F
;
440 texgenfv(ctx
->Texture
.CurrentUnit
, coord
, pname
, p
, "glTexGenf");
445 _mesa_MultiTexGenfEXT( GLenum texunit
, GLenum coord
, GLenum pname
, GLfloat param
)
449 p
[1] = p
[2] = p
[3] = 0.0F
;
450 texgenfv(texunit
- GL_TEXTURE0
, coord
, pname
, p
, "glMultiTexGenfEXT");
455 _mesa_TexGeni( GLenum coord
, GLenum pname
, GLint param
)
459 p
[1] = p
[2] = p
[3] = 0;
460 _mesa_TexGeniv( coord
, pname
, p
);
465 _mesa_MultiTexGeniEXT( GLenum texunit
, GLenum coord
, GLenum pname
, GLint param
)
469 p
[1] = p
[2] = p
[3] = 0;
470 _mesa_MultiTexGenivEXT( texunit
, coord
, pname
, p
);
475 _mesa_GetTexGendv( GLenum coord
, GLenum pname
, GLdouble
*params
)
477 GET_CURRENT_CONTEXT(ctx
);
478 gettexgendv(ctx
->Texture
.CurrentUnit
, coord
, pname
, params
, "glGetTexGendv");
483 _mesa_GetMultiTexGendvEXT( GLenum texunit
, GLenum coord
, GLenum pname
, GLdouble
*params
)
485 gettexgendv(texunit
- GL_TEXTURE0
, coord
, pname
, params
, "glGetMultiTexGendvEXT");
490 _mesa_GetTexGenfv( GLenum coord
, GLenum pname
, GLfloat
*params
)
492 GET_CURRENT_CONTEXT(ctx
);
493 gettexgenfv(ctx
->Texture
.CurrentUnit
, coord
, pname
, params
, "glGetTexGenfv");
498 _mesa_GetMultiTexGenfvEXT( GLenum texunit
, GLenum coord
, GLenum pname
, GLfloat
*params
)
500 gettexgenfv(texunit
- GL_TEXTURE0
, coord
, pname
, params
, "glGetMultiTexGenfvEXT");
505 _mesa_GetTexGeniv( GLenum coord
, GLenum pname
, GLint
*params
)
507 GET_CURRENT_CONTEXT(ctx
);
508 gettexgeniv(ctx
->Texture
.CurrentUnit
, coord
, pname
, params
, "glGetTexGeniv");
513 _mesa_GetMultiTexGenivEXT( GLenum texunit
, GLenum coord
, GLenum pname
, GLint
*params
)
515 gettexgeniv(texunit
- GL_TEXTURE0
, coord
, pname
, params
, "glGetTexGenivEXT");