Subversion Repositories Kolibri OS

Rev

Rev 5218 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5153 IgorA 1
;include 'msghandling.inc'
2
 
3
align 4
4
proc glopMaterial, context:dword, p:dword
5
;  int mode=p[1].i;
6
;  int type=p[2].i;
7
;  float *v=&p[3].f;
8
;  int i;
9
;  GLMaterial *m;
10
 
11
;  if (mode == GL_FRONT_AND_BACK) {
12
;    p[1].i=GL_FRONT;
13
;    glopMaterial(c,p);
14
;    mode=GL_BACK;
15
;  }
16
;  if (mode == GL_FRONT) m=&c->materials[0];
17
;  else m=&c->materials[1];
18
 
19
;  switch(type) {
20
;  case GL_EMISSION:
21
;    for(i=0;i<4;i++)
22
;      m->emission.v[i]=v[i];
23
;    break;
24
;  case GL_AMBIENT:
25
;    for(i=0;i<4;i++)
26
;      m->ambient.v[i]=v[i];
27
;    break;
28
;  case GL_DIFFUSE:
29
;    for(i=0;i<4;i++)
30
;      m->diffuse.v[i]=v[i];
31
;    break;
32
;  case GL_SPECULAR:
33
;    for(i=0;i<4;i++)
34
;      m->specular.v[i]=v[i];
35
;    break;
36
;  case GL_SHININESS:
37
;    m->shininess=v[0];
38
;    m->shininess_i = (v[0]/128.0f)*SPECULAR_BUFFER_RESOLUTION;
39
;    break;
40
;  case GL_AMBIENT_AND_DIFFUSE:
41
;    for(i=0;i<4;i++)
42
;      m->diffuse.v[i]=v[i];
43
;    for(i=0;i<4;i++)
44
;      m->ambient.v[i]=v[i];
45
;    break;
46
;  default:
47
;    assert(0);
48
;  }
49
	ret
50
endp
51
 
52
align 4
53
proc glopColorMaterial uses eax ebx ecx, context:dword, p:dword
54
	mov eax,[context]
55
	mov ebx,[p]
56
	mov ecx,[ebx+4] ;ecx = p[1]
57
	mov dword[eax+offs_cont_current_color_material_mode],ecx
58
	mov ecx,[ebx+8] ;ecx = p[2]
59
	mov dword[eax+offs_cont_current_color_material_type],ecx
60
	ret
61
endp
62
 
63
;void glopLight(GLContext *c,GLParam *p)
64
;{
65
;  int light=p[1].i;
66
;  int type=p[2].i;
67
;  V4 v;
68
;  GLLight *l;
69
;  int i;
70
;
71
;  assert(light >= GL_LIGHT0 && light < GL_LIGHT0+MAX_LIGHTS );
72
;
73
;  l=&c->lights[light-GL_LIGHT0];
74
;
75
;  for(i=0;i<4;i++) v.v[i]=p[3+i].f;
76
;
77
;  switch(type) {
78
;  case GL_AMBIENT:
79
;    l->ambient=v;
80
;    break;
81
;  case GL_DIFFUSE:
82
;    l->diffuse=v;
83
;    break;
84
;  case GL_SPECULAR:
85
;    l->specular=v;
86
;    break;
87
;  case GL_POSITION:
88
;    {
89
;      V4 pos;
90
;      gl_M4_MulV4(&pos,c->matrix_stack_ptr[0],&v);
91
;
92
;      l->position=pos;
93
;
94
;      if (l->position.v[3] == 0) {
95
;        l->norm_position.X=pos.X;
96
;        l->norm_position.Y=pos.Y;
97
;        l->norm_position.Z=pos.Z;
98
;
99
;        gl_V3_Norm(&l->norm_position);
100
;      }
101
;    }
102
;    break;
103
;  case GL_SPOT_DIRECTION:
104
;    for(i=0;i<3;i++) {
105
;      l->spot_direction.v[i]=v.v[i];
106
;      l->norm_spot_direction.v[i]=v.v[i];
107
;    }
108
;    gl_V3_Norm(&l->norm_spot_direction);
109
;    break;
110
;  case GL_SPOT_EXPONENT:
111
;    l->spot_exponent=v.v[0];
112
;    break;
113
;  case GL_SPOT_CUTOFF:
114
;    {
115
;      float a=v.v[0];
116
;      assert(a == 180 || (a>=0 && a<=90));
117
;      l->spot_cutoff=a;
118
;      if (a != 180) l->cos_spot_cutoff=cos(a * M_PI / 180.0);
119
;    }
120
;    break;
121
;  case GL_CONSTANT_ATTENUATION:
122
;    l->attenuation[0]=v.v[0];
123
;    break;
124
;  case GL_LINEAR_ATTENUATION:
125
;    l->attenuation[1]=v.v[0];
126
;    break;
127
;  case GL_QUADRATIC_ATTENUATION:
128
;    l->attenuation[2]=v.v[0];
129
;    break;
130
;  default:
131
;    assert(0);
132
;  }
133
;}
134
 
135
align 4
136
proc glopLightModel uses ebx ecx esi edi, context:dword, p:dword
137
	mov edi,[context]
138
	mov ebx,[p]
139
	mov esi,[ebx+8]
140
 
141
	cmp dword[ebx+4],GL_LIGHT_MODEL_AMBIENT
142
	jne @f
143
		mov ecx,4
144
		mov edi,dword[edi+offs_cont_ambient_light_model]
145
		rep movsd ;for(i=0;i<4;i++) context.ambient_light_model.v[i]=v[i]
146
		jmp .end_f
147
	@@:
148
	cmp dword[ebx+4],GL_LIGHT_MODEL_LOCAL_VIEWER
149
	jne @f
150
		fld dword[esi] ;st0 = p[2].v[0]
151
		fistp dword[edi+offs_cont_local_light_model]
152
		jmp .end_f
153
	@@:
154
	cmp dword[ebx+4],GL_LIGHT_MODEL_TWO_SIDE
155
	jne @f
156
		fld dword[esi] ;st0 = p[2].v[0]
157
		fistp dword[edi+offs_cont_light_model_two_side]
158
		jmp .end_f
159
	@@: ;default:
160
;    tgl_warning("glopLightModel: illegal pname: 0x%x\n", dword[ebx+4]);
161
;    //assert(0);
162
	.end_f:
163
	ret
164
endp
165
 
166
;static inline float clampf(float a,float min,float max)
167
;{
168
;  if (a
169
;  else if (a>max) return max;
170
;  else return a;
171
;}
172
 
173
align 4
174
proc gl_enable_disable_light uses eax ebx ecx, context:dword, light:dword, v:dword
175
	mov eax,[context]
176
	mov ebx,[light]
177
	imul ebx,sizeof.GLLight
178
	add ebx,[eax+offs_cont_lights]
179
 
180
	xor ecx,ecx
181
	cmp dword[ebx+offs_ligh_enabled],0
182
	jne @f
183
		not ecx
184
	@@:
185
	and ecx,[v]
186
	cmp ecx,0
187
	je @f
188
		;if (v && !l.enabled)
189
		mov dword[ebx+offs_ligh_enabled],1
190
		mov ecx,[eax+offs_cont_first_light]
191
		mov [ebx+offs_ligh_next],ecx
192
		mov [eax+offs_cont_first_light],ebx ;context.first_light = l
193
		mov dword[ebx+offs_ligh_prev],0 ;l.prev = NULL
194
		jmp .end_f
195
	@@:
196
	xor ecx,ecx
197
	cmp dword[v],0
198
	jne @f
199
		not ecx
200
	@@:
201
	and ecx,[ebx+offs_ligh_enabled]
202
	cmp ecx,0
203
	je .end_f
204
		;else if (!v && l.enabled)
205
		mov dword[ebx+offs_ligh_enabled],0 ;l.enabled = 0
206
		mov ecx,[ebx+offs_ligh_next]
207
		cmp dword[ebx+offs_ligh_prev],0 ;if (l.prev == NULL)
208
		jne .els_0
209
			mov [eax+offs_cont_first_light],ecx	;context.first_light = l.next
210
			jmp @f
211
		.els_0:
212
			mov eax,[ebx+offs_ligh_prev]
213
			mov [eax+offs_ligh_next],ecx ;l.prev.next = l.next
214
		@@:
215
		cmp dword[ebx+offs_ligh_next],0
216
		je .end_f
217
			mov ecx,[ebx+offs_ligh_prev]
218
			mov eax,[ebx+offs_ligh_next]
219
			mov [eax+offs_ligh_prev],ecx ;l.next.prev = l.prev
220
	.end_f:
221
	ret
222
endp
223
 
224
; non optimized lightening model
225
align 4
226
proc gl_shade_vertex, context:dword, v:dword
227
 
228
;  float R,G,B,A;
229
;  GLMaterial *m;
230
;  GLLight *l;
231
;  V3 n,s,d;
232
;  float dist,tmp,att,dot,dot_spot,dot_spec;
233
;  int twoside = c->light_model_two_side;
234
 
235
;  m=&c->materials[0];
236
 
237
;  n.X=v->normal.X;
238
;  n.Y=v->normal.Y;
239
;  n.Z=v->normal.Z;
240
 
241
;  R=m->emission.v[0]+m->ambient.v[0]*c->ambient_light_model.v[0];
242
;  G=m->emission.v[1]+m->ambient.v[1]*c->ambient_light_model.v[1];
243
;  B=m->emission.v[2]+m->ambient.v[2]*c->ambient_light_model.v[2];
244
;  A=clampf(m->diffuse.v[3],0,1);
245
 
246
;  for(l=c->first_light;l!=NULL;l=l->next) {
247
;    float lR,lB,lG;
248
 
249
;    /* ambient */
250
;    lR=l->ambient.v[0] * m->ambient.v[0];
251
;    lG=l->ambient.v[1] * m->ambient.v[1];
252
;    lB=l->ambient.v[2] * m->ambient.v[2];
253
 
254
;    if (l->position.v[3] == 0) {
255
;      /* light at infinity */
256
;      d.X=l->position.v[0];
257
;      d.Y=l->position.v[1];
258
;      d.Z=l->position.v[2];
259
;      att=1;
260
;    } else {
261
;      /* distance attenuation */
262
;      d.X=l->position.v[0]-v->ec.v[0];
263
;      d.Y=l->position.v[1]-v->ec.v[1];
264
;      d.Z=l->position.v[2]-v->ec.v[2];
265
;      dist=sqrt(d.X*d.X+d.Y*d.Y+d.Z*d.Z);
266
;      if (dist>1E-3) {
267
;        tmp=1/dist;
268
;        d.X*=tmp;
269
;        d.Y*=tmp;
270
;        d.Z*=tmp;
271
;      }
272
;      att=1.0f/(l->attenuation[0]+dist*(l->attenuation[1]+
273
;                                    dist*l->attenuation[2]));
274
;    }
275
;    dot=d.X*n.X+d.Y*n.Y+d.Z*n.Z;
276
;    if (twoside && dot < 0) dot = -dot;
277
;    if (dot>0) {
278
;      /* diffuse light */
279
;      lR+=dot * l->diffuse.v[0] * m->diffuse.v[0];
280
;      lG+=dot * l->diffuse.v[1] * m->diffuse.v[1];
281
;      lB+=dot * l->diffuse.v[2] * m->diffuse.v[2];
282
;
283
;      /* spot light */
284
;      if (l->spot_cutoff != 180) {
285
;        dot_spot=-(d.X*l->norm_spot_direction.v[0]+
286
;                   d.Y*l->norm_spot_direction.v[1]+
287
;                   d.Z*l->norm_spot_direction.v[2]);
288
;        if (twoside && dot_spot < 0) dot_spot = -dot_spot;
289
;        if (dot_spot < l->cos_spot_cutoff) {
290
;          /* no contribution */
291
;          continue;
292
;        } else {
293
;          /* TODO: optimize */
294
;          if (l->spot_exponent > 0) {
295
;            att=att*pow(dot_spot,l->spot_exponent);
296
;          }
297
;        }
298
;      }
299
 
300
;      /* specular light */
301
 
302
;      if (c->local_light_model) {
303
;        V3 vcoord;
304
;        vcoord.X=v->ec.X;
305
;        vcoord.Y=v->ec.Y;
306
;        vcoord.Z=v->ec.Z;
307
;        gl_V3_Norm(&vcoord);
308
;        s.X=d.X-vcoord.X;
309
;        s.Y=d.Y-vcoord.X;
310
;        s.Z=d.Z-vcoord.X;
311
;      } else {
312
;        s.X=d.X;
313
;        s.Y=d.Y;
314
;        s.Z=d.Z+1.0;
315
;      }
316
;      dot_spec=n.X*s.X+n.Y*s.Y+n.Z*s.Z;
317
;      if (twoside && dot_spec < 0) dot_spec = -dot_spec;
318
;      if (dot_spec>0) {
319
;        GLSpecBuf *specbuf;
320
;        int idx;
321
;        tmp=sqrt(s.X*s.X+s.Y*s.Y+s.Z*s.Z);
322
;        if (tmp > 1E-3) {
323
;          dot_spec=dot_spec / tmp;
324
;        }
325
 
326
;        /* TODO: optimize */
327
;        /* testing specular buffer code */
328
;        /* dot_spec= pow(dot_spec,m->shininess);*/
329
;        specbuf = specbuf_get_buffer(c, m->shininess_i, m->shininess);
330
;        idx = (int)(dot_spec*SPECULAR_BUFFER_SIZE);
331
;        if (idx > SPECULAR_BUFFER_SIZE) idx = SPECULAR_BUFFER_SIZE;
332
;        dot_spec = specbuf->buf[idx];
333
;        lR+=dot_spec * l->specular.v[0] * m->specular.v[0];
334
;        lG+=dot_spec * l->specular.v[1] * m->specular.v[1];
335
;        lB+=dot_spec * l->specular.v[2] * m->specular.v[2];
336
;      }
337
;    }
338
 
339
;    R+=att * lR;
340
;    G+=att * lG;
341
;    B+=att * lB;
342
;  }
343
 
344
;  v->color.v[0]=clampf(R,0,1);
345
;  v->color.v[1]=clampf(G,0,1);
346
;  v->color.v[2]=clampf(B,0,1);
347
;  v->color.v[3]=A;
348
	ret
349
endp
350