Subversion Repositories Kolibri OS

Rev

Rev 5218 | 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. ;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<min) return min;
  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.  
  351.