
  'Example of matrix layout mapped to an array of 4x4 cells
  '
  '  0 4 8 C
  '  1 5 9 D
  '  2 6 A E
  '  3 7 B F
  '

  %MatrixType single

  sub MatrixMul(MatrixType *a,*b,*c, sys n)
  =========================================
  '
  '
  #if typecodeof a=0x64
    % OneStep 4
    % ColStep 16
    % mtype single
  #endif
  '
  #if typecodeof a=0x68
    % OneStep 8
    % ColStep 32
    % mtype double
  #endif

  sys pa=@a, pb=@b, pc=@c

  mov ecx,pa
  mov edx,pb
  mov eax,pc

  mov esi,n
  (
  call column : dec esi : jg repeat
  )
  exit sub

  column:
  -------

  mov edi,n
  (
  call cell : dec edi : jg repeat
  )
  add edx,ColStep
  sub ecx,ColStep
  ret

  cell: ' row A * column B
  ------------------------

  'matrix data is stored ascending vertically then horizontally
  'thus rows are minor, columns are major
  '
  push  ecx
  push  edx
  push  eax
  mov   eax,4
  fldz
  (
  fld   mtype [ecx]
  fmul  mtype [edx]
  faddp st1
  add   ecx,ColStep 'next column of matrix A
  add   edx,OneStep 'next row of matrix B
  dec eax
  jnz repeat
  )
  pop eax
  fstp mtype [eax] 'assign to next row of matrix C
  '
  pop edx
  pop ecx
  add   eax,OneStep 'next cell in column of matrix C (columns then rows)
  add   ecx,OneStep 'next row of matrix A
  ret
  '
  end sub

       

  sub getrow4S(MatrixType* matrix, MarixType *row)
  '===============================================
  '
  indexbase 0
  row<=matrix[0],matrix[4],matrix[8],matrix[12]
  end sub

  float BiasMatrix[16] 'converts -1..1 to 0..1
  BiasMatrix=>
  0.5, 0.0, 0.0, 0.0,
  0.0, 0.5, 0.0, 0.0,
  0.0, 0.0, 0.5, 0.0,
  0.5, 0.5, 0.5, 1.0;


' Shadow mapping
' September 2006
'
' derived from Paul Baker Tutorial
'
'
'//////////////////////////////////////////////////////////////////////////////////////////
'//     Shadow Mapping Tutorial
'//     Accompanies a tutorial found on my site
'//     Downloaded from: www.paulsprojects.net
'//     Created:    16th September 2003
'//
'//     Copyright (c) 2006, Paul Baker
'//     Distributed under the New BSD Licence. (See accompanying file License.txt or copy at
'//     http://www.paulsprojects.net/NewBSDLicense.txt)
'//////////////////////////////////////////////////////////////////////////////////////////


  float CameraProjectionMatrix[16],cameraViewMatrix[16]
  float LightProjectionMatrix[16],lightViewMatrix[16]
  float CameraPosition[4],lightPosition[4]
  long viewport[4]

  ---------------

  shadow_mapping:

  indexbase 0

  glPushMatrix
  glLoadIdentity
  gluPerspective 45.0, aspect, 1.0, 100.0
  glGetFloatv GL_MODELVIEW_MATRIX, cameraProjectionMatrix

  glLoadIdentity
  gluLookAt cameraPosition(0), cameraPosition(1), cameraPosition(2), 0.0, 0.0, -5.0, 0.0, 1.0, 0.0
  glGetFloatv GL_MODELVIEW_MATRIX, cameraViewMatrix

  glLoadIdentity
  gluPerspective 45.0, aspect, 4, 100.0 ' was 2 8
  glGetFloatv GL_MODELVIEW_MATRIX, lightProjectionMatrix(0)

  glLoadIdentity
  gluLookAt xp(9), yp(9), -zp(9),    0.0, 0.0, -5.0,     0.0, 1.0, 0.0
  'gluLookAt  lightPosition(0), lightPosition(1), lightPosition(2),    0.0, 0.0, -5.0,     0.0, 1.0, 0.0
  glGetFloatv GL_MODELVIEW_MATRIX, lightViewMatrix

  glPopMatrix

  sys ShadowMapSize=128

  ' FIRST PASS - from light's point of view
  -----------------------------------------
  '
  glDisable GL_LIGHTING
  glMatrixMode GL_PROJECTION
  glLoadMatrixf lightProjectionMatrix
  '
  glMatrixMode GL_MODELVIEW
  glLoadMatrixf lightViewMatrix

  ' Use viewport the same size as the shadow map
  glViewport 0, 0, shadowMapSize, shadowMapSize

  ' Draw back faces into the shadow map
  glCullFace GL_FRONT

  ' Disable color writes, and use flat shading for speed
  glShadeModel GL_FLAT
  glColorMask 0, 0, 0, 0

  render 'GOSUB next_frame ' SCENE FIRST PASS

  ' Read the depth buffer into the shadow map texture
  glBindTexture GL_TEXTURE_2D, ShadowTex(0) 'shadowMapTexture
  '
  'glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height) ' corrected inc
  glCopyTexSubImage2D GL_TEXTURE_2D, 0, 0, 0, 0, 0, shadowMapSize, shadowMapSize
  '
  ' restore states
  glCullFace GL_BACK
  glShadeModel GL_SMOOTH
  glColorMask 1, 1, 1, 1
  glEnable GL_LIGHTING
  '
 'SECOND PASS - Draw from camera's point of view
 -----------------------------------------------
  '
  glClear GL_DEPTH_BUFFER_BIT
  glMatrixMode GL_PROJECTION
  glLoadMatrixf cameraProjectionMatrix
  '
  glMatrixMode GL_MODELVIEW
  glLoadMatrixf cameraViewMatrix
  '
  glViewport 0, 0, viewport(2), viewport(3)

  ' Use dim light to represent shadowed areas
  'glLightfv GL_LIGHT2, GL_POSITION, lightPosition(0) ' byref lightposition.x y and z
  'glLightfv GL_LIGHT2, GL_AMBIENT, dimli(0)
  'glLightfv GL_LIGHT2, GL_DIFFUSE, dimli(0)
  'glLightfv GL_LIGHT2, GL_SPECULAR, drkli(0)
  'glEnable GL_LIGHT2
  'glEnable GL_LIGHTING
  '
  lighting 0.1, 0.20, 0.2, 0.0, 1

  render  'GOSUB next_frame ' SCENE SECOND PASS
  '
  ' THIRD PASS
  '------------
  '
  ' Draw with bright light
  'glLightfv(GL_LIGHT2, GL_DIFFUSE, maxli(0))
  'glLightfv(GL_LIGHT2, GL_SPECULAR,maxli(0))
  ' ambient, diffuse, specular, attenuation, positional
  lighting 0, 1, 1, .001, 1
  '
  'Calculate texture matrix for projection
  'This matrix takes us from eye space to the light's clip space
  'It is postmultiplied by the inverse of the current view matrix when specifying texgen
  '
  'MATRIX4X4 textureMatrix=biasMatrix*lightProjectionMatrix*lightViewMatrix
  'bias from [-1, 1] to [0, 1]
  'MAT tempMatrix()=biasMatrix() * lightProjectionMatrix()
  'MAT textureMatrix()=tempMatrix()  * lightViewMatrix()
  '  
  MatrixMul4x4 biasMatrix, lightProjectionMatrix, tempmatrix
  MatrixMul4x4 tempmatrix, lightViewMatrix, TextureMatrix
  '
  'Set up texture coordinate generation.
  '
  glTexGeni GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR
  ' glTexGenfv GL_S, GL_EYE_PLANE, textureMatrixGetRow(0)
  getrow4f textureMatrix(0)
  glTexGenfv GL_S, GL_EYE_PLANE, row4f(0)
  glEnable GL_TEXTURE_GEN_S
  '
  glTexGeni GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR
  'glTexGenfv(GL_T, GL_EYE_PLANE, textureMatrix.GetRow(1))
  getrow4f textureMatrix(1)
  glTexGenfv GL_T, GL_EYE_PLANE, row4f(0)
  glEnable GL_TEXTURE_GEN_T
  '
  glTexGeni GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR
  'glTexGenfv GL_R, GL_EYE_PLANE, textureMatrix.GetRow(2)
  getrow4f textureMatrix(2)
  glTexGenfv GL_R, GL_EYE_PLANE, row4f(0)
  glEnable GL_TEXTURE_GEN_R
  '
  glTexGeni GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR
  'glTexGenfv GL_Q, GL_EYE_PLANE, textureMatrix.GetRow(3)
  getrow4f textureMatrix(3)
  glTexGenfv GL_Q, GL_EYE_PLANE, row4f(0)
  glEnable GL_TEXTURE_GEN_Q
  '
  'Bind & enable shadow map texture
  glBindTexture GL_TEXTURE_2D, mapref(0) ' shadowMapTexture
  glEnable GL_TEXTURE_2D
  '
  ' Enable shadow comparison
  glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE
  '
  'Shadow comparison should be true (ie not in shadow) if r<=texture
  glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL
  'Shadow comparison should generate an INTENSITY result
  glTexParameteri GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY
  '
  ' Set alpha test to discard false comparisons
  glAlphaFunc GL_GEQUAL, 0.99
  glEnable GL_ALPHA_TEST
  '
  render 'GOSUB next_frame  ' SCENE THIRD PASS
  '
  ' Disable textures and texgen
  glDisable GL_TEXTURE_2D
  glDisable GL_TEXTURE_GEN_S
  glDisable GL_TEXTURE_GEN_T
  glDisable GL_TEXTURE_GEN_R
  glDisable GL_TEXTURE_GEN_Q
  '
  'Restore other states
  glDisable GL_LIGHTING
  glDisable GL_ALPHA_TEST

