<?xml version="1.0" encoding="utf-8" ?> 
<shader compiler="xmlshader" name="lighting_vproc_fixed">
  <shadervars>
    <shadervar type="vector3" name="mat specular">1,1,1</shadervar>
  </shadervars>

  <?Template ifGLSupportsLight N?>
    <?! GL fixed pipeline can only do: 
	- unattenuated directional lights
	- other lights if they are not attenuated LINEAR
	Further, CS spotlights dont exactly map to GL ones...
	So for now, GL fixed function spots look slightly off. ?>
    <?if ((vars."light $N$ type".int == consts.CS_LIGHT_DIRECTIONAL)
	&& (vars."light $N$ attenuation mode".int == consts.CS_ATTN_NONE)) 
      || (vars."light $N$ attenuation mode".int != consts.CS_ATTN_LINEAR) ?>
  <?Endtemplate?>

  <?Template ifNotGLSupportsLight N?>
    <?ifGLSupportsLight $N$?>
    <?else?>
  <?Endtemplate?>
  
  <?Template HandleLightFVP LightCount N?>
    <?if $LightCount$ &gt; $N$ ?>
      <?ifGLSupportsLight $N$ ?>
	<light num="$N$">
	  <?if (vars."light $N$ type".int == consts.CS_LIGHT_DIRECTIONAL)?>
	    <?! Generate position for directional light ?>
	    <position type="expression">
	      <!-- small subtlety: GL spec says light coordinates are in
		   object space, yet here they are world space - at the 
		   time lighting parameters will be set, the GL object 
		   space is CS world space actually. This is due the way
		   CS sets up transforms. -->
	      <sexp>
		(* (make-vector 
		     (elt1 "light $N$ direction world")
		     (elt2 "light $N$ direction world")
		     (elt3 "light $N$ direction world")
		     0)
		   -1)
	      </sexp>
	    </position>
	    <!--attenuation type="vector3">1,0,0</attenuation-->
	  <?elsif (vars."light $N$ type".int == consts.CS_LIGHT_SPOTLIGHT)?>
	    <spotcutoff type="expression">
	      <!-- CS falloff is cosine of angle, GL wants angle -->
	      <sexp>(* (arccos (min 1 "light $N$ outer falloff") ) 57.295779513082320876798154814105)</sexp>
	      <!-- 57.295... = 180/PI -->
	    </spotcutoff>
	  <?endif?>
	  <?if (vars."light $N$ type".int != consts.CS_LIGHT_SPOTLIGHT)?>
	    <!-- Override any falloff of the light -->
	    <spotcutoff type="float">180</spotcutoff>
	  <?endif?>
	</light>
      <?endif?>
    <?endif?>
  <?Endtemplate?>
  
  <?Template HandleLightVProc LightCount N?>
    <?if $LightCount$ &gt; $N$ ?>
      <?!ifGLSupportsLight $N$ ?>
	<enablelight num="$N$">no</enablelight>
      <?!endif?>
    <?endif?>
  <?Endtemplate?>
  
  <?Template FVPcommon N ?>
    <?if !vars."tex diffuse".texture ?>
      <constantcolor layer="diffuse" type="shadervar">mat flatcolor</constantcolor>
    <?endif?>
    <!-- have GL light added on top of SW-computed light -->
    <colormaterial>emission</colormaterial>
    <!-- scale down colors, since FP will scale them up again -->
    <matambient type="vector3">0.5,0.5,0.5</matambient>
    <matdiffuse type="vector3">0.5,0.5,0.5</matdiffuse>
    <matspecularexp type="shadervar">mat shininess</matspecularexp>
    <separatespecular/>
    <?Generate L 0 7 ?>
      <?HandleLightFVP $N$ $$L$$ ?>
    <?Endgenerate?>
  <?Endtemplate?>
  <?Template VPROCcommon N ?>
    <lightmixmode>add</lightmixmode>
    <!--
    <?if buffers."color lit"?>
      <colormixmode>add</colormixmode>
      <colorbuffer>color lit</colorbuffer>
    <?else?>
      <colormixmode>mul</colormixmode>
      <colorbuffer>color unlit</colorbuffer>
    <?endif?>
    -->
    <!-- @@@ FIXME: Support software specular
         Unfortunately, the only way I see is to uglily use a 2nd pass
         for the specular part... [res] -->
    <colormixmode>none</colormixmode>
    <finalfactor type="float">0.5</finalfactor>
    <lights>$N$</lights>
    <?Generate L 0 7 ?>
      <?HandleLightVProc $N$ $$L$$ ?>
    <?Endgenerate?>
  <?Endtemplate?>
  <?Template FFPcommon?>
    <layer name="diffuse">
      <?if vars."tex diffuse".texture ?>
        <colorsource num="0" source="texture" modifier="color"/>
        <alphasource num="0" source="texture" modifier="alpha"/>
      <?else?>
        <colorsource num="0" source="constant color" modifier="color"/>
        <alphasource num="0" source="constant color" modifier="alpha"/>
      <?endif?>
      <colorsource num="1" source="primary color" modifier="color"/>
      <coloroperation operation="modulate" scale="2" />
      <alphasource num="1" source="primary color" modifier="alpha"/>
      <alphaoperation operation="modulate" />
    </layer>
  <?Endtemplate?>

  <?! "Dumbed down" to 4 for now to keep loading/processing time down ?>
  <?Generate N 4 1 ?>
    <?if vars."light count".int &gt;= $N$ ?>
      <!-- Tech with separate specular -->
      <technique priority="$N$50" lights="$N$">
	<pass>
	  <?if vars."tex diffuse".texture ?>
	    <texture name="tex diffuse" destination="diffuse" />
	    <buffer source="texture coordinate 0" destination="texture coordinate 0" />
	  <?else?>
	    <!-- need to bind at least some texture -->
	    <texture name="standardtex white" destination="diffuse" />
	  <?endif?>
	  <buffer source="normal" destination="normal" />
	  <buffer source="color" destination="color" />
	  <vp plugin="glfixed">
	    <fixedvp>
	      <?FVPcommon $N$ ?>
	      <!-- specular is separate, so no downscaling -->
	      <matspecular type="shadervar">mat specular</matspecular>
	      <!--matspecular type="float">1</matspecular-->
	    </fixedvp>
	  </vp>
	  <vproc plugin="vproc_std">
	    <vproc_std>
	      <?VPROCcommon $N$ ?>
	    </vproc_std>
	  </vproc>
	  <fp plugin="glfixed">
	    <fixedfp>
	      <?FFPcommon?>
	    </fixedfp>
	  </fp>
	</pass>
      </technique>
      <!-- Tech without separate specular -->
      <technique priority="$N$00" lights="$N$">
	<pass>
	  <?if vars."tex diffuse".texture ?>
	    <texture name="tex diffuse" destination="diffuse" />
	    <buffer source="texture coordinate 0" destination="texture coordinate 0" />
	  <?else?>
	    <!-- need to bind at least some texture -->
	    <texture name="standardtex white" destination="diffuse" />
	  <?endif?>
	  <buffer source="normal" destination="normal" />
	  <buffer source="color" destination="color" />
	  <vp plugin="glfixed">
	    <fixedvp>
	      <?FVPcommon $N$ ?>
	      <!-- specular is not separate, downscale as well -->
	      <matspecular type="expr">
		<sexp>(* "mat specular" 0.5)</sexp>
	      </matspecular>
	    </fixedvp>
	  </vp>
	  <vproc plugin="vproc_std">
	    <vproc_std>
	      <?VPROCcommon $N$ ?>
	    </vproc_std>
	  </vproc>
	  <fp plugin="glfixed">
	    <fixedfp>
	      <?FFPcommon?>
	    </fixedfp>
	  </fp>
	</pass>
      </technique>
    <?endif?>
  <?Endgenerate?>
  
  <fallbackshader name="lighting_vproc" file="/shader/lighting/vproc.xml" />
</shader>
