OSDN Git Service

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