Subversion Repositories Kolibri OS

Rev

Rev 5153 | Rev 5256 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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. align 4
  64. proc glopLight uses eax ebx ecx edx, context:dword, p:dword
  65.         mov eax,[context]
  66.         mov ebx,[p]
  67.         mov edx,[ebx+4] ;edx = p[1]
  68.  
  69. ;  V4 v;
  70.  
  71. ;  assert(edx >= GL_LIGHT0 && edx < GL_LIGHT0+MAX_LIGHTS );
  72.  
  73.         sub edx,GL_LIGHT0
  74.         imul edx,sizeof.GLLight
  75.         add edx,eax
  76.         add edx,offs_cont_lights
  77.  
  78.         mov ecx,[ebx+8] ;ecx = p[2]
  79.         cmp ecx,GL_AMBIENT
  80.         jne @f
  81.                 mov esi,ebx
  82.                 add esi,12
  83.                 mov edi,edx
  84.                 ;add edi,offs_ligh_ambient ;offs_ligh_ambient = 0
  85.                 mov ecx,4
  86.                 rep movsd ;l.ambient=v
  87.                 jmp .end_f
  88.         @@:
  89.         cmp ecx,GL_DIFFUSE
  90.         jne @f
  91.                 mov esi,ebx
  92.                 add esi,12
  93.                 mov edi,edx
  94.                 add edi,offs_ligh_diffuse
  95.                 mov ecx,4
  96.                 rep movsd ;l.diffuse=v
  97.                 jmp .end_f
  98.         @@:
  99.         cmp ecx,GL_SPECULAR
  100.         jne @f
  101.                 mov esi,ebx
  102.                 add esi,12
  103.                 mov edi,edx
  104.                 add edi,offs_ligh_specular
  105.                 mov ecx,4
  106.                 rep movsd ;l.specular=v
  107.                 jmp .end_f
  108.         @@:
  109.         cmp ecx,GL_POSITION
  110.         jne @f
  111. ;    {
  112. ;  for(i=0;i<4;i++) v.v[i]=p[3+i].f;
  113. ;      V4 pos;
  114. ;      gl_M4_MulV4(&pos,c->matrix_stack_ptr[0],&v);
  115. ;
  116. ;      l->position=pos;
  117. ;
  118. ;      if (l->position.v[3] == 0) {
  119. ;        l->norm_position.X=pos.X;
  120. ;        l->norm_position.Y=pos.Y;
  121. ;        l->norm_position.Z=pos.Z;
  122. ;        
  123. ;        gl_V3_Norm(&l->norm_position);
  124. ;      }
  125. ;    }
  126.                 jmp .end_f
  127.         @@:
  128.         cmp ecx,GL_SPOT_DIRECTION
  129.         jne @f
  130.                 mov esi,ebx
  131.                 add esi,12
  132.                 mov edi,edx
  133.                 add edi,offs_ligh_spot_direction
  134.                 mov ecx,3
  135.                 rep movsd ;l.spot_direction=v[0,1,2]
  136.                 mov esi,ebx
  137.                 add esi,12
  138.                 mov edi,edx
  139.                 add edi,offs_ligh_norm_spot_direction
  140.                 mov ecx,3
  141.                 rep movsd ;l.norm_spot_direction=v[0,1,2]
  142.                 add edx,offs_ligh_norm_spot_direction
  143.                 stdcall gl_V3_Norm,edx
  144.                 jmp .end_f
  145.         @@:
  146.         cmp ecx,GL_SPOT_EXPONENT
  147.         jne @f
  148.                 mov ecx,[ebx+12]
  149.                 mov [edi+offs_ligh_spot_exponent],ecx ;l.spot_exponent=p[3]
  150.                 jmp .end_f
  151.         @@:
  152.         cmp ecx,GL_SPOT_CUTOFF
  153.         jne @f
  154. ;    {
  155. ;      float a=v.v[0];
  156. ;      assert(a == 180 || (a>=0 && a<=90));
  157. ;      l->spot_cutoff=a;
  158. ;      if (a != 180) l->cos_spot_cutoff=cos(a * M_PI / 180.0);
  159. ;    }
  160.                 jmp .end_f
  161.         @@:
  162.         cmp ecx,GL_CONSTANT_ATTENUATION
  163.                 mov ecx,[ebx+12]
  164.                 mov [edi+offs_ligh_attenuation],ecx ;l->attenuation[0]=p[3]
  165.                 jmp .end_f
  166.         @@:
  167.         cmp ecx,GL_LINEAR_ATTENUATION
  168.                 mov ecx,[ebx+12]
  169.                 mov [edi+offs_ligh_attenuation+4],ecx ;l->attenuation[1]=p[3]
  170.                 jmp .end_f
  171.         @@:
  172.         cmp ecx,GL_QUADRATIC_ATTENUATION
  173.                 mov ecx,[ebx+12]
  174.                 mov [edi+offs_ligh_attenuation+8],ecx ;l->attenuation[2]=p[3]
  175.                 jmp .end_f
  176.         @@: ;default:
  177. ;    assert(0);
  178.         .end_f:
  179.         ret
  180. endp
  181.  
  182.  
  183. align 4
  184. proc glopLightModel uses ebx ecx esi edi, context:dword, p:dword
  185.         mov edi,[context]
  186.         mov ebx,[p]
  187.         mov esi,[ebx+8]
  188.  
  189.         cmp dword[ebx+4],GL_LIGHT_MODEL_AMBIENT
  190.         jne @f
  191.                 mov ecx,4
  192.                 mov edi,dword[edi+offs_cont_ambient_light_model]
  193.                 rep movsd ;for(i=0;i<4;i++) context.ambient_light_model.v[i]=v[i]
  194.                 jmp .end_f
  195.         @@:
  196.         cmp dword[ebx+4],GL_LIGHT_MODEL_LOCAL_VIEWER
  197.         jne @f
  198.                 fld dword[esi] ;st0 = p[2].v[0]
  199.                 fistp dword[edi+offs_cont_local_light_model]
  200.                 jmp .end_f
  201.         @@:
  202.         cmp dword[ebx+4],GL_LIGHT_MODEL_TWO_SIDE
  203.         jne @f
  204.                 fld dword[esi] ;st0 = p[2].v[0]
  205.                 fistp dword[edi+offs_cont_light_model_two_side]
  206.                 jmp .end_f
  207.         @@: ;default:
  208. ;    tgl_warning("glopLightModel: illegal pname: 0x%x\n", dword[ebx+4]);
  209. ;    //assert(0);
  210.         .end_f:
  211.         ret
  212. endp
  213.  
  214. ;static inline float clampf(float a,float min,float max)
  215. ;{
  216. ;  if (a<min) return min;
  217. ;  else if (a>max) return max;
  218. ;  else return a;
  219. ;}
  220.  
  221. align 4
  222. proc gl_enable_disable_light uses eax ebx ecx, context:dword, light:dword, v:dword
  223.         mov eax,[context]
  224.         mov ebx,[light]
  225.         imul ebx,sizeof.GLLight
  226.         add ebx,[eax+offs_cont_lights]
  227.  
  228.         xor ecx,ecx
  229.         cmp dword[ebx+offs_ligh_enabled],0
  230.         jne @f
  231.                 not ecx
  232.         @@:
  233.         and ecx,[v]
  234.         cmp ecx,0
  235.         je @f
  236.                 ;if (v && !l.enabled)
  237.                 mov dword[ebx+offs_ligh_enabled],1
  238.                 mov ecx,[eax+offs_cont_first_light]
  239.                 mov [ebx+offs_ligh_next],ecx
  240.                 mov [eax+offs_cont_first_light],ebx ;context.first_light = l
  241.                 mov dword[ebx+offs_ligh_prev],0 ;l.prev = NULL
  242.                 jmp .end_f
  243.         @@:
  244.         xor ecx,ecx
  245.         cmp dword[v],0
  246.         jne @f
  247.                 not ecx
  248.         @@:
  249.         and ecx,[ebx+offs_ligh_enabled]
  250.         cmp ecx,0
  251.         je .end_f
  252.                 ;else if (!v && l.enabled)
  253.                 mov dword[ebx+offs_ligh_enabled],0 ;l.enabled = 0
  254.                 mov ecx,[ebx+offs_ligh_next]
  255.                 cmp dword[ebx+offs_ligh_prev],0 ;if (l.prev == NULL)
  256.                 jne .els_0
  257.                         mov [eax+offs_cont_first_light],ecx     ;context.first_light = l.next
  258.                         jmp @f
  259.                 .els_0:
  260.                         mov eax,[ebx+offs_ligh_prev]
  261.                         mov [eax+offs_ligh_next],ecx ;l.prev.next = l.next
  262.                 @@:
  263.                 cmp dword[ebx+offs_ligh_next],0
  264.                 je .end_f
  265.                         mov ecx,[ebx+offs_ligh_prev]
  266.                         mov eax,[ebx+offs_ligh_next]
  267.                         mov [eax+offs_ligh_prev],ecx ;l.next.prev = l.prev
  268.         .end_f:
  269.         ret
  270. endp
  271.  
  272. ; non optimized lightening model
  273. align 4
  274. proc gl_shade_vertex, context:dword, v:dword
  275.  
  276. ;  float R,G,B,A;
  277. ;  GLMaterial *m;
  278. ;  GLLight *l;
  279. ;  V3 n,s,d;
  280. ;  float dist,tmp,att,dot,dot_spot,dot_spec;
  281. ;  int twoside = c->light_model_two_side;
  282.  
  283. ;  m=&c->materials[0];
  284.  
  285. ;  n.X=v->normal.X;
  286. ;  n.Y=v->normal.Y;
  287. ;  n.Z=v->normal.Z;
  288.  
  289. ;  R=m->emission.v[0]+m->ambient.v[0]*c->ambient_light_model.v[0];
  290. ;  G=m->emission.v[1]+m->ambient.v[1]*c->ambient_light_model.v[1];
  291. ;  B=m->emission.v[2]+m->ambient.v[2]*c->ambient_light_model.v[2];
  292. ;  A=clampf(m->diffuse.v[3],0,1);
  293.  
  294. ;  for(l=c->first_light;l!=NULL;l=l->next) {
  295. ;    float lR,lB,lG;
  296.  
  297. ;    /* ambient */
  298. ;    lR=l->ambient.v[0] * m->ambient.v[0];
  299. ;    lG=l->ambient.v[1] * m->ambient.v[1];
  300. ;    lB=l->ambient.v[2] * m->ambient.v[2];
  301.  
  302. ;    if (l->position.v[3] == 0) {
  303. ;      /* light at infinity */
  304. ;      d.X=l->position.v[0];
  305. ;      d.Y=l->position.v[1];
  306. ;      d.Z=l->position.v[2];
  307. ;      att=1;
  308. ;    } else {
  309. ;      /* distance attenuation */
  310. ;      d.X=l->position.v[0]-v->ec.v[0];
  311. ;      d.Y=l->position.v[1]-v->ec.v[1];
  312. ;      d.Z=l->position.v[2]-v->ec.v[2];
  313. ;      dist=sqrt(d.X*d.X+d.Y*d.Y+d.Z*d.Z);
  314. ;      if (dist>1E-3) {
  315. ;        tmp=1/dist;
  316. ;        d.X*=tmp;
  317. ;        d.Y*=tmp;
  318. ;        d.Z*=tmp;
  319. ;      }
  320. ;      att=1.0f/(l->attenuation[0]+dist*(l->attenuation[1]+
  321. ;                                    dist*l->attenuation[2]));
  322. ;    }
  323. ;    dot=d.X*n.X+d.Y*n.Y+d.Z*n.Z;
  324. ;    if (twoside && dot < 0) dot = -dot;
  325. ;    if (dot>0) {
  326. ;      /* diffuse light */
  327. ;      lR+=dot * l->diffuse.v[0] * m->diffuse.v[0];
  328. ;      lG+=dot * l->diffuse.v[1] * m->diffuse.v[1];
  329. ;      lB+=dot * l->diffuse.v[2] * m->diffuse.v[2];
  330. ;
  331. ;      /* spot light */
  332. ;      if (l->spot_cutoff != 180) {
  333. ;        dot_spot=-(d.X*l->norm_spot_direction.v[0]+
  334. ;                   d.Y*l->norm_spot_direction.v[1]+
  335. ;                   d.Z*l->norm_spot_direction.v[2]);
  336. ;        if (twoside && dot_spot < 0) dot_spot = -dot_spot;
  337. ;        if (dot_spot < l->cos_spot_cutoff) {
  338. ;          /* no contribution */
  339. ;          continue;
  340. ;        } else {
  341. ;          /* TODO: optimize */
  342. ;          if (l->spot_exponent > 0) {
  343. ;            att=att*pow(dot_spot,l->spot_exponent);
  344. ;          }
  345. ;        }
  346. ;      }
  347.  
  348. ;      /* specular light */
  349.  
  350. ;      if (c->local_light_model) {
  351. ;        V3 vcoord;
  352. ;        vcoord.X=v->ec.X;
  353. ;        vcoord.Y=v->ec.Y;
  354. ;        vcoord.Z=v->ec.Z;
  355. ;        gl_V3_Norm(&vcoord);
  356. ;        s.X=d.X-vcoord.X;
  357. ;        s.Y=d.Y-vcoord.X;
  358. ;        s.Z=d.Z-vcoord.X;
  359. ;      } else {
  360. ;        s.X=d.X;
  361. ;        s.Y=d.Y;
  362. ;        s.Z=d.Z+1.0;
  363. ;      }
  364. ;      dot_spec=n.X*s.X+n.Y*s.Y+n.Z*s.Z;
  365. ;      if (twoside && dot_spec < 0) dot_spec = -dot_spec;
  366. ;      if (dot_spec>0) {
  367. ;        GLSpecBuf *specbuf;
  368. ;        int idx;
  369. ;        tmp=sqrt(s.X*s.X+s.Y*s.Y+s.Z*s.Z);
  370. ;        if (tmp > 1E-3) {
  371. ;          dot_spec=dot_spec / tmp;
  372. ;        }
  373.  
  374. ;        /* TODO: optimize */
  375. ;        /* testing specular buffer code */
  376. ;        /* dot_spec= pow(dot_spec,m->shininess);*/
  377. ;        specbuf = specbuf_get_buffer(c, m->shininess_i, m->shininess);
  378. ;        idx = (int)(dot_spec*SPECULAR_BUFFER_SIZE);
  379. ;        if (idx > SPECULAR_BUFFER_SIZE) idx = SPECULAR_BUFFER_SIZE;
  380. ;        dot_spec = specbuf->buf[idx];
  381. ;        lR+=dot_spec * l->specular.v[0] * m->specular.v[0];
  382. ;        lG+=dot_spec * l->specular.v[1] * m->specular.v[1];
  383. ;        lB+=dot_spec * l->specular.v[2] * m->specular.v[2];
  384. ;      }
  385. ;    }
  386.  
  387. ;    R+=att * lR;
  388. ;    G+=att * lG;
  389. ;    B+=att * lB;
  390. ;  }
  391.  
  392. ;  v->color.v[0]=clampf(R,0,1);
  393. ;  v->color.v[1]=clampf(G,0,1);
  394. ;  v->color.v[2]=clampf(B,0,1);
  395. ;  v->color.v[3]=A;
  396.         ret
  397. endp
  398.  
  399.