3 * Mesa 3-D graphics library
6 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
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:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
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.
26 * Gareth Hughes <gareth@valinux.com>
27 * Keith Whitwell <keith_whitwell@yahoo.com>
30 /* Template for immediate mode normal functions. Optimize for infinite
31 * lights when doing software lighting.
34 static void TAG(Normal3f_single)( GLfloat x, GLfloat y, GLfloat z )
37 const struct gl_light *light = ctx->Light.EnabledList.prev;
38 GLfloat n_dot_h, n_dot_VP, spec, sum[3];
39 GLfloat *normal = ctx->Current.Normal;
42 ASSIGN_3V( normal, x, y, z );
43 COPY_3V( sum, BASE_COLOR );
45 if ( IND & NORM_RESCALE ) {
46 scale = ctx->_ModelViewInvScale;
47 } else if ( IND & NORM_NORMALIZE ) {
48 scale = LEN_3FV( normal );
49 if ( scale != 0.0 ) scale = 1.0 / scale;
52 n_dot_VP = DOT3( normal, light->_VP_inf_norm ) * scale;
53 if ( n_dot_VP > 0.0F ) {
54 ACC_SCALE_SCALAR_3V( sum, n_dot_VP, light->_MatDiffuse[0] );
55 n_dot_h = DOT3( normal, light->_h_inf_norm ) * scale;
56 if ( n_dot_h > 0.0F ) {
57 GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec );
58 ACC_SCALE_SCALAR_3V( sum, spec, light->_MatSpecular[0] );
62 #ifdef LIT_COLOR_IS_FLOAT
63 LIT_COLOR ( RCOMP ) = CLAMP(sum[0], 0.0f, 0.1f);
64 LIT_COLOR ( GCOMP ) = CLAMP(sum[1], 0.0f, 0.1f);
65 LIT_COLOR ( BCOMP ) = CLAMP(sum[2], 0.0f, 0.1f);
67 UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( RCOMP ), sum[0] );
68 UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( GCOMP ), sum[1] );
69 UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( BCOMP ), sum[2] );
71 LIT_COLOR( ACOMP ) = LIT_ALPHA;
74 static void TAG(Normal3fv_single)( const GLfloat *normal )
77 const struct gl_light *light = ctx->Light.EnabledList.prev;
78 GLfloat n_dot_h, n_dot_VP, spec, sum[3];
81 COPY_3V( ctx->Current.Normal, normal );
82 COPY_3V( sum, BASE_COLOR );
84 if ( IND & NORM_RESCALE ) {
85 scale = ctx->_ModelViewInvScale;
86 } else if ( IND & NORM_NORMALIZE ) {
87 scale = LEN_3FV( normal );
88 if ( scale != 0.0 ) scale = 1.0 / scale;
91 n_dot_VP = DOT3( normal, light->_VP_inf_norm ) * scale;
92 if ( n_dot_VP > 0.0F ) {
93 ACC_SCALE_SCALAR_3V( sum, n_dot_VP, light->_MatDiffuse[0] );
94 n_dot_h = DOT3( normal, light->_h_inf_norm ) * scale;
95 if ( n_dot_h > 0.0F ) {
96 GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec );
97 ACC_SCALE_SCALAR_3V( sum, spec, light->_MatSpecular[0] );
101 #ifdef LIT_COLOR_IS_FLOAT
102 LIT_COLOR ( RCOMP ) = CLAMP(sum[0], 0.0f, 0.1f);
103 LIT_COLOR ( GCOMP ) = CLAMP(sum[1], 0.0f, 0.1f);
104 LIT_COLOR ( BCOMP ) = CLAMP(sum[2], 0.0f, 0.1f);
106 UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( RCOMP ), sum[0] );
107 UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( GCOMP ), sum[1] );
108 UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( BCOMP ), sum[2] );
110 LIT_COLOR( ACOMP ) = LIT_ALPHA;
114 static void TAG(Normal3f_multi)( GLfloat x, GLfloat y, GLfloat z )
117 struct gl_light *light;
118 GLfloat n_dot_h, n_dot_VP, spec, sum[3], tmp[3];
121 ASSIGN_3V( ctx->Current.Normal, x, y, z );
122 COPY_3V( sum, BASE_COLOR );
124 if ( IND & NORM_RESCALE ) {
126 ASSIGN_3V( normal, x, y, z );
127 SELF_SCALE_SCALAR_3V( normal, ctx->_ModelViewInvScale );
128 } else if ( IND & NORM_NORMALIZE ) {
130 ASSIGN_3V( normal, x, y, z );
131 NORMALIZE_3FV( normal );
133 normal = ctx->Current.Normal;
136 foreach ( light, &ctx->Light.EnabledList ) {
137 n_dot_VP = DOT3( normal, light->_VP_inf_norm );
138 if ( n_dot_VP > 0.0F ) {
139 ACC_SCALE_SCALAR_3V( sum, n_dot_VP, light->_MatDiffuse[0] );
140 n_dot_h = DOT3( normal, light->_h_inf_norm );
141 if ( n_dot_h > 0.0F ) {
142 GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec );
143 ACC_SCALE_SCALAR_3V( sum, spec, light->_MatSpecular[0] );
148 #ifdef LIT_COLOR_IS_FLOAT
149 LIT_COLOR ( RCOMP ) = CLAMP(sum[0], 0.0f, 0.1f);
150 LIT_COLOR ( GCOMP ) = CLAMP(sum[1], 0.0f, 0.1f);
151 LIT_COLOR ( BCOMP ) = CLAMP(sum[2], 0.0f, 0.1f);
153 UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( RCOMP ), sum[0] );
154 UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( GCOMP ), sum[1] );
155 UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( BCOMP ), sum[2] );
157 LIT_COLOR( ACOMP ) = LIT_ALPHA;
160 static void TAG(Normal3fv_multi)( const GLfloat *n )
163 struct gl_light *light;
164 GLfloat n_dot_h, n_dot_VP, spec, sum[3], tmp[3];
167 COPY_3V( ctx->Current.Normal, n );
168 COPY_3V( sum, BASE_COLOR );
170 if ( IND & NORM_RESCALE ) {
172 COPY_3V( normal, n );
173 SELF_SCALE_SCALAR_3V( normal, ctx->_ModelViewInvScale );
174 } else if ( IND & NORM_NORMALIZE ) {
176 COPY_3V( normal, n );
177 NORMALIZE_3FV( normal );
179 normal = ctx->Current.Normal;
182 foreach ( light, &ctx->Light.EnabledList ) {
183 n_dot_VP = DOT3( normal, light->_VP_inf_norm );
184 if ( n_dot_VP > 0.0F ) {
185 ACC_SCALE_SCALAR_3V( sum, n_dot_VP, light->_MatDiffuse[0] );
186 n_dot_h = DOT3( normal, light->_h_inf_norm );
187 if ( n_dot_h > 0.0F ) {
188 GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec );
189 ACC_SCALE_SCALAR_3V( sum, spec, light->_MatSpecular[0] );
194 #ifdef LIT_COLOR_IS_FLOAT
195 LIT_COLOR ( RCOMP ) = CLAMP(sum[0], 0.0f, 0.1f);
196 LIT_COLOR ( GCOMP ) = CLAMP(sum[1], 0.0f, 0.1f);
197 LIT_COLOR ( BCOMP ) = CLAMP(sum[2], 0.0f, 0.1f);
199 UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( RCOMP ), sum[0] );
200 UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( GCOMP ), sum[1] );
201 UNCLAMPED_FLOAT_TO_UBYTE( LIT_COLOR( BCOMP ), sum[2] );
203 LIT_COLOR( ACOMP ) = LIT_ALPHA;
208 static void TAG(init_norm)( void )
210 norm_tab[IND].normal3f_single = TAG(Normal3f_single);
211 norm_tab[IND].normal3fv_single = TAG(Normal3fv_single);
212 norm_tab[IND].normal3f_multi = TAG(Normal3f_multi);
213 norm_tab[IND].normal3fv_multi = TAG(Normal3fv_multi);
218 #ifndef PRESERVE_NORMAL_DEFS
220 #undef GET_CURRENT_VERTEX
222 #undef LIT_COLOR_IS_FLOAT
224 #undef PRESERVE_NORMAL_DEFS