• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "main/dispatch.h"
41 
42 
43 /**
44  * Return texgen state for given coordinate
45  */
46 static struct gl_texgen *
get_texgen(struct gl_context * ctx,struct gl_texture_unit * texUnit,GLenum coord)47 get_texgen(struct gl_context *ctx, struct gl_texture_unit *texUnit,
48            GLenum coord)
49 {
50    if (ctx->API == API_OPENGLES) {
51       return (coord == GL_TEXTURE_GEN_STR_OES)
52          ? &texUnit->GenS : NULL;
53    }
54 
55    switch (coord) {
56    case GL_S:
57       return &texUnit->GenS;
58    case GL_T:
59       return &texUnit->GenT;
60    case GL_R:
61       return &texUnit->GenR;
62    case GL_Q:
63       return &texUnit->GenQ;
64    default:
65       return NULL;
66    }
67 }
68 
69 
70 void GLAPIENTRY
_mesa_TexGenfv(GLenum coord,GLenum pname,const GLfloat * params)71 _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
72 {
73    struct gl_texture_unit *texUnit;
74    struct gl_texgen *texgen;
75    GET_CURRENT_CONTEXT(ctx);
76 
77    if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
78       _mesa_debug(ctx, "glTexGen %s %s %.1f(%s)...\n",
79                   _mesa_enum_to_string(coord),
80                   _mesa_enum_to_string(pname),
81                   *params,
82 		  _mesa_enum_to_string((GLenum) (GLint) *params));
83 
84    if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
85       _mesa_error(ctx, GL_INVALID_OPERATION, "glTexGen(current unit)");
86       return;
87    }
88 
89    texUnit = _mesa_get_current_tex_unit(ctx);
90 
91    texgen = get_texgen(ctx, texUnit, coord);
92    if (!texgen) {
93       _mesa_error(ctx, GL_INVALID_ENUM, "glTexGen(coord)");
94       return;
95    }
96 
97    switch (pname) {
98    case GL_TEXTURE_GEN_MODE:
99       {
100          GLenum mode = (GLenum) (GLint) params[0];
101          GLbitfield bit = 0x0;
102          if (texgen->Mode == mode)
103             return;
104          switch (mode) {
105          case GL_OBJECT_LINEAR:
106             bit = TEXGEN_OBJ_LINEAR;
107             break;
108          case GL_EYE_LINEAR:
109             bit = TEXGEN_EYE_LINEAR;
110             break;
111          case GL_SPHERE_MAP:
112             if (coord == GL_S || coord == GL_T)
113                bit = TEXGEN_SPHERE_MAP;
114             break;
115          case GL_REFLECTION_MAP_NV:
116             if (coord != GL_Q)
117                bit = TEXGEN_REFLECTION_MAP_NV;
118             break;
119          case GL_NORMAL_MAP_NV:
120             if (coord != GL_Q)
121                bit = TEXGEN_NORMAL_MAP_NV;
122             break;
123          default:
124             ; /* nop */
125          }
126          if (!bit) {
127             _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
128             return;
129          }
130          if (ctx->API != API_OPENGL_COMPAT
131              && (bit & (TEXGEN_REFLECTION_MAP_NV | TEXGEN_NORMAL_MAP_NV)) == 0) {
132             _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
133             return;
134          }
135 
136          FLUSH_VERTICES(ctx, _NEW_TEXTURE);
137          texgen->Mode = mode;
138          texgen->_ModeBit = bit;
139       }
140       break;
141 
142    case GL_OBJECT_PLANE:
143       {
144          if (ctx->API != API_OPENGL_COMPAT) {
145             _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
146             return;
147          }
148          if (TEST_EQ_4V(texgen->ObjectPlane, params))
149             return;
150          FLUSH_VERTICES(ctx, _NEW_TEXTURE);
151          COPY_4FV(texgen->ObjectPlane, params);
152       }
153       break;
154 
155    case GL_EYE_PLANE:
156       {
157          GLfloat tmp[4];
158 
159          if (ctx->API != API_OPENGL_COMPAT) {
160             _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
161             return;
162          }
163 
164          /* Transform plane equation by the inverse modelview matrix */
165          if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
166             _math_matrix_analyse(ctx->ModelviewMatrixStack.Top);
167          }
168          _mesa_transform_vector(tmp, params,
169                                 ctx->ModelviewMatrixStack.Top->inv);
170          if (TEST_EQ_4V(texgen->EyePlane, tmp))
171             return;
172          FLUSH_VERTICES(ctx, _NEW_TEXTURE);
173          COPY_4FV(texgen->EyePlane, tmp);
174       }
175       break;
176 
177    default:
178       _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
179       return;
180    }
181 
182    if (ctx->Driver.TexGen)
183       ctx->Driver.TexGen( ctx, coord, pname, params );
184 }
185 
186 
187 void GLAPIENTRY
_mesa_TexGeniv(GLenum coord,GLenum pname,const GLint * params)188 _mesa_TexGeniv(GLenum coord, GLenum pname, const GLint *params )
189 {
190    GLfloat p[4];
191    p[0] = (GLfloat) params[0];
192    if (pname == GL_TEXTURE_GEN_MODE) {
193       p[1] = p[2] = p[3] = 0.0F;
194    }
195    else {
196       p[1] = (GLfloat) params[1];
197       p[2] = (GLfloat) params[2];
198       p[3] = (GLfloat) params[3];
199    }
200    _mesa_TexGenfv(coord, pname, p);
201 }
202 
203 
204 void GLAPIENTRY
_mesa_TexGend(GLenum coord,GLenum pname,GLdouble param)205 _mesa_TexGend(GLenum coord, GLenum pname, GLdouble param )
206 {
207    GLfloat p[4];
208    p[0] = (GLfloat) param;
209    p[1] = p[2] = p[3] = 0.0F;
210    _mesa_TexGenfv( coord, pname, p );
211 }
212 
213 
214 void GLAPIENTRY
_es_GetTexGenfv(GLenum coord,GLenum pname,GLfloat * params)215 _es_GetTexGenfv(GLenum coord, GLenum pname, GLfloat *params)
216 {
217    _mesa_GetTexGenfv(GL_S, pname, params);
218 }
219 
220 
221 void GLAPIENTRY
_es_TexGenf(GLenum coord,GLenum pname,GLfloat param)222 _es_TexGenf(GLenum coord, GLenum pname, GLfloat param)
223 {
224    if (coord != GL_TEXTURE_GEN_STR_OES) {
225       GET_CURRENT_CONTEXT(ctx);
226       _mesa_error( ctx, GL_INVALID_ENUM, "glTexGen[fx](pname)" );
227       return;
228    }
229    /* set S, T, and R at the same time */
230    _mesa_TexGenf(GL_S, pname, param);
231    _mesa_TexGenf(GL_T, pname, param);
232    _mesa_TexGenf(GL_R, pname, param);
233 }
234 
235 
236 void GLAPIENTRY
_es_TexGenfv(GLenum coord,GLenum pname,const GLfloat * params)237 _es_TexGenfv(GLenum coord, GLenum pname, const GLfloat *params)
238 {
239    if (coord != GL_TEXTURE_GEN_STR_OES) {
240       GET_CURRENT_CONTEXT(ctx);
241       _mesa_error( ctx, GL_INVALID_ENUM, "glTexGen[fx]v(pname)" );
242       return;
243    }
244    /* set S, T, and R at the same time */
245    _mesa_TexGenfv(GL_S, pname, params);
246    _mesa_TexGenfv(GL_T, pname, params);
247    _mesa_TexGenfv(GL_R, pname, params);
248 }
249 
250 
251 void GLAPIENTRY
_mesa_TexGendv(GLenum coord,GLenum pname,const GLdouble * params)252 _mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params )
253 {
254    GLfloat p[4];
255    p[0] = (GLfloat) params[0];
256    if (pname == GL_TEXTURE_GEN_MODE) {
257       p[1] = p[2] = p[3] = 0.0F;
258    }
259    else {
260       p[1] = (GLfloat) params[1];
261       p[2] = (GLfloat) params[2];
262       p[3] = (GLfloat) params[3];
263    }
264    _mesa_TexGenfv( coord, pname, p );
265 }
266 
267 
268 void GLAPIENTRY
_mesa_TexGenf(GLenum coord,GLenum pname,GLfloat param)269 _mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param )
270 {
271    GLfloat p[4];
272    p[0] = param;
273    p[1] = p[2] = p[3] = 0.0F;
274    _mesa_TexGenfv(coord, pname, p);
275 }
276 
277 
278 void GLAPIENTRY
_mesa_TexGeni(GLenum coord,GLenum pname,GLint param)279 _mesa_TexGeni( GLenum coord, GLenum pname, GLint param )
280 {
281    GLint p[4];
282    p[0] = param;
283    p[1] = p[2] = p[3] = 0;
284    _mesa_TexGeniv( coord, pname, p );
285 }
286 
287 
288 
289 void GLAPIENTRY
_mesa_GetTexGendv(GLenum coord,GLenum pname,GLdouble * params)290 _mesa_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params )
291 {
292    struct gl_texture_unit *texUnit;
293    struct gl_texgen *texgen;
294    GET_CURRENT_CONTEXT(ctx);
295 
296    if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
297       _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGendv(current unit)");
298       return;
299    }
300 
301    texUnit = _mesa_get_current_tex_unit(ctx);
302 
303    texgen = get_texgen(ctx, texUnit, coord);
304    if (!texgen) {
305       _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexGendv(coord)");
306       return;
307    }
308 
309    switch (pname) {
310    case GL_TEXTURE_GEN_MODE:
311       params[0] = ENUM_TO_DOUBLE(texgen->Mode);
312       break;
313    case GL_OBJECT_PLANE:
314       COPY_4V(params, texgen->ObjectPlane);
315       break;
316    case GL_EYE_PLANE:
317       COPY_4V(params, texgen->EyePlane);
318       break;
319    default:
320       _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
321    }
322 }
323 
324 
325 
326 void GLAPIENTRY
_mesa_GetTexGenfv(GLenum coord,GLenum pname,GLfloat * params)327 _mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params )
328 {
329    struct gl_texture_unit *texUnit;
330    struct gl_texgen *texgen;
331    GET_CURRENT_CONTEXT(ctx);
332 
333    if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
334       _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGenfv(current unit)");
335       return;
336    }
337 
338    texUnit = _mesa_get_current_tex_unit(ctx);
339 
340    texgen = get_texgen(ctx, texUnit, coord);
341    if (!texgen) {
342       _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexGenfv(coord)");
343       return;
344    }
345 
346    switch (pname) {
347    case GL_TEXTURE_GEN_MODE:
348       params[0] = ENUM_TO_FLOAT(texgen->Mode);
349       break;
350    case GL_OBJECT_PLANE:
351       if (ctx->API != API_OPENGL_COMPAT) {
352          _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(param)" );
353          return;
354       }
355       COPY_4V(params, texgen->ObjectPlane);
356       break;
357    case GL_EYE_PLANE:
358       if (ctx->API != API_OPENGL_COMPAT) {
359          _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(param)" );
360          return;
361       }
362       COPY_4V(params, texgen->EyePlane);
363       break;
364    default:
365       _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
366    }
367 }
368 
369 
370 
371 void GLAPIENTRY
_mesa_GetTexGeniv(GLenum coord,GLenum pname,GLint * params)372 _mesa_GetTexGeniv( GLenum coord, GLenum pname, GLint *params )
373 {
374    struct gl_texture_unit *texUnit;
375    struct gl_texgen *texgen;
376    GET_CURRENT_CONTEXT(ctx);
377 
378    if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
379       _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGeniv(current unit)");
380       return;
381    }
382 
383    texUnit = _mesa_get_current_tex_unit(ctx);
384 
385    texgen = get_texgen(ctx, texUnit, coord);
386    if (!texgen) {
387       _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexGeniv(coord)");
388       return;
389    }
390 
391    switch (pname) {
392    case GL_TEXTURE_GEN_MODE:
393       params[0] = texgen->Mode;
394       break;
395    case GL_OBJECT_PLANE:
396       if (ctx->API != API_OPENGL_COMPAT) {
397          _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(param)" );
398          return;
399       }
400       params[0] = (GLint) texgen->ObjectPlane[0];
401       params[1] = (GLint) texgen->ObjectPlane[1];
402       params[2] = (GLint) texgen->ObjectPlane[2];
403       params[3] = (GLint) texgen->ObjectPlane[3];
404       break;
405    case GL_EYE_PLANE:
406       if (ctx->API != API_OPENGL_COMPAT) {
407          _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(param)" );
408          return;
409       }
410       params[0] = (GLint) texgen->EyePlane[0];
411       params[1] = (GLint) texgen->EyePlane[1];
412       params[2] = (GLint) texgen->EyePlane[2];
413       params[3] = (GLint) texgen->EyePlane[3];
414       break;
415    default:
416       _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
417    }
418 }
419