2 #include "msghandling.h"
4 void glopMaterial(GLContext
*c
,GLParam
*p
)
12 if (mode
== GL_FRONT_AND_BACK
) {
17 if (mode
== GL_FRONT
) m
=&c
->materials
[0];
18 else m
=&c
->materials
[1];
23 m
->emission
.v
[i
]=v
[i
];
35 m
->specular
.v
[i
]=v
[i
];
39 m
->shininess_i
= (v
[0]/128.0f
)*SPECULAR_BUFFER_RESOLUTION
;
41 case GL_AMBIENT_AND_DIFFUSE
:
52 void glopColorMaterial(GLContext
*c
,GLParam
*p
)
57 c
->current_color_material_mode
=mode
;
58 c
->current_color_material_type
=type
;
61 void glopLight(GLContext
*c
,GLParam
*p
)
69 assert(light
>= GL_LIGHT0
&& light
< GL_LIGHT0
+MAX_LIGHTS
);
71 l
=&c
->lights
[light
-GL_LIGHT0
];
73 for(i
=0;i
<4;i
++) v
.v
[i
]=p
[3+i
].f
;
88 gl_M4_MulV4(&pos
,c
->matrix_stack_ptr
[0],&v
);
92 if (l
->position
.v
[3] == 0) {
93 l
->norm_position
.X
=pos
.X
;
94 l
->norm_position
.Y
=pos
.Y
;
95 l
->norm_position
.Z
=pos
.Z
;
97 gl_V3_Norm(&l
->norm_position
);
101 case GL_SPOT_DIRECTION
:
103 l
->spot_direction
.v
[i
]=v
.v
[i
];
104 l
->norm_spot_direction
.v
[i
]=v
.v
[i
];
106 gl_V3_Norm(&l
->norm_spot_direction
);
108 case GL_SPOT_EXPONENT
:
109 l
->spot_exponent
=v
.v
[0];
114 assert(a
== 180 || (a
>=0 && a
<=90));
116 if (a
!= 180) l
->cos_spot_cutoff
=cos(a
* M_PI
/ 180.0);
119 case GL_CONSTANT_ATTENUATION
:
120 l
->attenuation
[0]=v
.v
[0];
122 case GL_LINEAR_ATTENUATION
:
123 l
->attenuation
[1]=v
.v
[0];
125 case GL_QUADRATIC_ATTENUATION
:
126 l
->attenuation
[2]=v
.v
[0];
134 void glopLightModel(GLContext
*c
,GLParam
*p
)
141 case GL_LIGHT_MODEL_AMBIENT
:
143 c
->ambient_light_model
.v
[i
]=v
[i
];
145 case GL_LIGHT_MODEL_LOCAL_VIEWER
:
146 c
->local_light_model
=(int)v
[0];
148 case GL_LIGHT_MODEL_TWO_SIDE
:
149 c
->light_model_two_side
= (int)v
[0];
152 tgl_warning("glopLightModel: illegal pname: 0x%x\n", pname
);
159 static inline float clampf(float a
,float min
,float max
)
161 if (a
<min
) return min
;
162 else if (a
>max
) return max
;
166 void gl_enable_disable_light(GLContext
*c
,int light
,int v
)
168 GLLight
*l
=&c
->lights
[light
];
169 if (v
&& !l
->enabled
) {
171 l
->next
=c
->first_light
;
174 } else if (!v
&& l
->enabled
) {
176 if (l
->prev
== NULL
) c
->first_light
=l
->next
;
177 else l
->prev
->next
=l
->next
;
178 if (l
->next
!= NULL
) l
->next
->prev
=l
->prev
;
182 /* non optimized lightening model */
183 void gl_shade_vertex(GLContext
*c
,GLVertex
*v
)
189 float dist
,tmp
,att
,dot
,dot_spot
,dot_spec
;
190 int twoside
= c
->light_model_two_side
;
198 R
=m
->emission
.v
[0]+m
->ambient
.v
[0]*c
->ambient_light_model
.v
[0];
199 G
=m
->emission
.v
[1]+m
->ambient
.v
[1]*c
->ambient_light_model
.v
[1];
200 B
=m
->emission
.v
[2]+m
->ambient
.v
[2]*c
->ambient_light_model
.v
[2];
201 A
=clampf(m
->diffuse
.v
[3],0,1);
203 for(l
=c
->first_light
;l
!=NULL
;l
=l
->next
) {
207 lR
=l
->ambient
.v
[0] * m
->ambient
.v
[0];
208 lG
=l
->ambient
.v
[1] * m
->ambient
.v
[1];
209 lB
=l
->ambient
.v
[2] * m
->ambient
.v
[2];
211 if (l
->position
.v
[3] == 0) {
212 /* light at infinity */
213 d
.X
=l
->position
.v
[0];
214 d
.Y
=l
->position
.v
[1];
215 d
.Z
=l
->position
.v
[2];
218 /* distance attenuation */
219 d
.X
=l
->position
.v
[0]-v
->ec
.v
[0];
220 d
.Y
=l
->position
.v
[1]-v
->ec
.v
[1];
221 d
.Z
=l
->position
.v
[2]-v
->ec
.v
[2];
222 dist
=sqrt(d
.X
*d
.X
+d
.Y
*d
.Y
+d
.Z
*d
.Z
);
229 att
=1.0f
/(l
->attenuation
[0]+dist
*(l
->attenuation
[1]+
230 dist
*l
->attenuation
[2]));
232 dot
=d
.X
*n
.X
+d
.Y
*n
.Y
+d
.Z
*n
.Z
;
233 if (twoside
&& dot
< 0) dot
= -dot
;
236 lR
+=dot
* l
->diffuse
.v
[0] * m
->diffuse
.v
[0];
237 lG
+=dot
* l
->diffuse
.v
[1] * m
->diffuse
.v
[1];
238 lB
+=dot
* l
->diffuse
.v
[2] * m
->diffuse
.v
[2];
241 if (l
->spot_cutoff
!= 180) {
242 dot_spot
=-(d
.X
*l
->norm_spot_direction
.v
[0]+
243 d
.Y
*l
->norm_spot_direction
.v
[1]+
244 d
.Z
*l
->norm_spot_direction
.v
[2]);
245 if (twoside
&& dot_spot
< 0) dot_spot
= -dot_spot
;
246 if (dot_spot
< l
->cos_spot_cutoff
) {
247 /* no contribution */
251 if (l
->spot_exponent
> 0) {
252 att
=att
*pow(dot_spot
,l
->spot_exponent
);
259 if (c
->local_light_model
) {
273 dot_spec
=n
.X
*s
.X
+n
.Y
*s
.Y
+n
.Z
*s
.Z
;
274 if (twoside
&& dot_spec
< 0) dot_spec
= -dot_spec
;
278 tmp
=sqrt(s
.X
*s
.X
+s
.Y
*s
.Y
+s
.Z
*s
.Z
);
280 dot_spec
=dot_spec
/ tmp
;
284 /* testing specular buffer code */
285 /* dot_spec= pow(dot_spec,m->shininess);*/
286 specbuf
= specbuf_get_buffer(c
, m
->shininess_i
, m
->shininess
);
287 idx
= (int)(dot_spec
*SPECULAR_BUFFER_SIZE
);
288 if (idx
> SPECULAR_BUFFER_SIZE
) idx
= SPECULAR_BUFFER_SIZE
;
289 dot_spec
= specbuf
->buf
[idx
];
290 lR
+=dot_spec
* l
->specular
.v
[0] * m
->specular
.v
[0];
291 lG
+=dot_spec
* l
->specular
.v
[1] * m
->specular
.v
[1];
292 lB
+=dot_spec
* l
->specular
.v
[2] * m
->specular
.v
[2];
301 v
->color
.v
[0]=clampf(R
,0,1);
302 v
->color
.v
[1]=clampf(G
,0,1);
303 v
->color
.v
[2]=clampf(B
,0,1);