Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

OpenGL Matrix

By: sufokmpc on Dec 20th, 2011  |  syntax: PureBasic  |  size: 13.80 KB  |  views: 193  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. ; *---------------------------------*
  2. ; *   OpenGL Matrix                 *
  3. ; *   xorc1zt                       *
  4. ; *   2011                          *
  5. ; *---------------------------------*
  6.  
  7.  
  8. ; ** IMPORTANT ** : OpenGL Matrix are column-major ordered
  9. ;
  10. ;   m[0] m[4] m[8]  m[12]     m[Xx] m[Yx] m[Zx] m[Tx]
  11. ;   m[1] m[5] m[9]  m[13]     m[Xy] m[Yy] m[Zy] m[Ty]
  12. ;   m[2] m[6] m[10] m[14] ==> m[Xz] m[Yz] m[Zz] m[Tz]
  13. ;   m[3] m[7] m[11] m[15]     m[Xw] m[Yw] m[Zw] m[Tw]
  14. ;
  15. ;
  16.  
  17. EnableExplicit
  18. #MATRIX_SIZEBYTE = 64 ; 16*float
  19. #TRACEFUNCTION = #False
  20.  
  21. Macro traceFunction(string)
  22.   CompilerIf #TRACEFUNCTION
  23.     Debug "[ TRACE ]: "+string
  24.   CompilerEndIf
  25. EndMacro
  26.  
  27. Interface MATRIX
  28.   debugValues()
  29.   getAddress()
  30.   identity()
  31.   multiply(MATRIX)
  32.   rotateX(angledegree.f)
  33.   rotateY(angledegree.f)
  34.   rotateZ(angledegree.f)
  35.   translate(x.f, y.f, z.f)
  36.   perspective(angle.f, near.f, far.f, aspect.f)
  37.   orthogonal(left.f, right.f, bottom.f, top.f, near.f, far.f)
  38.   lookAt(eyeX.f, eyeY.f, eyeZ.f, centerX.f, centerY.f, centerZ.f, upX.f, upY.f, upZ.f)
  39.   push()
  40.   pop()
  41.   destroy()
  42. EndInterface
  43.  
  44. Structure PARENTSTR
  45.   value.f[16]
  46.   *parent.PARENTSTR
  47. EndStructure
  48.  
  49. Structure MATRIXSTR
  50.   VTable.l
  51.   value.f[16]
  52.   label.s
  53.   *parent.PARENTSTR
  54. EndStructure
  55.  
  56. Enumeration
  57.   #Xx
  58.   #Xy
  59.   #Xz
  60.   #Xw
  61.   #Yx
  62.   #Yy
  63.   #Yz
  64.   #Yw
  65.   #Zx
  66.   #Zy
  67.   #Zz
  68.   #Zw
  69.   #Tx
  70.   #Ty
  71.   #Tz
  72.   #Tw
  73. EndEnumeration
  74.  
  75. Declare   crossProduct( Array *a.f(1), Array *b.f(1), Array *result.f(1))
  76. Declare   normalize(Array *a.f(1))
  77. Declare   debugValues(*Self.MATRIXSTR)
  78. Declare.i getAddress(*Self.MATRIXSTR)
  79. Declare   identity(*Self.MATRIXSTR)
  80. Declare   multiply(*self.MATRIXSTR, *matrix.MATRIXSTR)
  81. Declare   rotateX(*Self.MATRIXSTR, angledegree.f)
  82. Declare   rotateY(*Self.MATRIXSTR, angledegree.f)
  83. Declare   rotateZ(*Self.MATRIXSTR, angledegree.f)
  84. Declare   translate(*Self.MATRIXSTR, x.f, y.f, z.f)
  85. Declare   perspective(*Self.MATRIXSTR, angle.f, near.f, far.f, aspect.f)
  86. Declare   orthogonal(*Self.MATRIXSTR, left.f, right.f, bottom.f, top.f, near.f, far.f)
  87. Declare   lookAt(*Self.MATRIXSTR, eyeX.f, eyeY.f, eyeZ.f, centerX.f, centerY.f, centerZ.f, upX.f, upY.f, upZ.f)
  88. Declare   push(*Self.MATRIXSTR)
  89. Declare   pop(*Self.MATRIXSTR)
  90. Declare   destroy(*Self.MATRIXSTR)
  91. Declare.i createMatrix(label.s)  
  92.  
  93. Procedure crossProduct( Array *a.f(1), Array *b.f(1), Array *result.f(1))
  94.   traceFunction("crossProduct()")
  95.  
  96.   *result(0) = ( *a(1) * *b(2) ) - ( *b(1) * *a(2) )
  97.   *result(1) = ( *a(2) * *b(0) ) - ( *b(2) * *a(0) )
  98.   *result(2) = ( *a(0) * *b(1) ) - ( *b(0) * *a(1) )
  99. EndProcedure
  100.  
  101. Procedure normalize(Array *a.f(1))
  102.   traceFunction("normalize()")
  103.  
  104.   Define mag.f = Sqr( *a(0) * *a(0) + *a(1) * *a(1) + *a(2) * *a(2) )
  105.   *a(0) / mag
  106.   *a(1) / mag
  107.   *a(2) / mag
  108. EndProcedure
  109.  
  110. Procedure debugValues(*Self.MATRIXSTR)
  111.   traceFunction("debugValues()")
  112.  
  113.   Debug "---- MATRIX: "+*self\label+" ----"
  114.   Debug StrF( *self\value[#Xx] )+" "+StrF( *self\value[#Yx] )+" "+StrF( *self\value[#Zx] )+" "+StrF( *self\value[#Tx] )
  115.   Debug StrF( *self\value[#Xy] )+" "+StrF( *self\value[#Yy] )+" "+StrF( *self\value[#Zy] )+" "+StrF( *self\value[#Ty] )
  116.   Debug StrF( *self\value[#Xz] )+" "+StrF( *self\value[#Yz] )+" "+StrF( *self\value[#Zz] )+" "+StrF( *self\value[#Tz] )
  117.   Debug StrF( *self\value[#Xw] )+" "+StrF( *self\value[#Yw] )+" "+StrF( *self\value[#Zw] )+" "+StrF( *self\value[#Tw] )
  118. EndProcedure
  119.  
  120. Procedure.i getAddress(*Self.MATRIXSTR)
  121.   traceFunction("getAddress()")
  122.   ProcedureReturn @*self\value[0]
  123. EndProcedure
  124.  
  125. Procedure identity(*Self.MATRIXSTR)
  126.   traceFunction("indentity()")
  127.  
  128.   CompilerIf 1
  129.     With *Self
  130.       \value[#Xx] = 1
  131.       \value[#Xy] = 0
  132.       \value[#Xz] = 0
  133.       \value[#Xw] = 0
  134.      
  135.       \value[#Yx] = 0
  136.       \value[#Yy] = 1
  137.       \value[#Yz] = 0
  138.       \value[#Yw] = 0
  139.      
  140.       \value[#Zx] = 0
  141.       \value[#Zy] = 0
  142.       \value[#Zz] = 1
  143.       \value[#Zw] = 0
  144.      
  145.       \value[#Tx] = 0
  146.       \value[#Ty] = 0
  147.       \value[#Tz] = 0
  148.       \value[#Tw] = 1
  149.     EndWith
  150.   CompilerElse
  151.     CopyMemory(?MatrixIdentity, @*self\value[0], #MATRIX_SIZEBYTE)
  152.   CompilerEndIf
  153. EndProcedure
  154.  
  155. Procedure multiply(*self.MATRIXSTR, *matrix.MATRIXSTR)
  156.   Define tempmatrix.MATRIXSTR
  157.  
  158.   traceFunction("multiply()")
  159.  
  160.   tempmatrix\value[#Xx] = (*self\value[0]  * *matrix\value[0])
  161.   tempmatrix\value[#Xx] + (*self\value[4]  * *matrix\value[1])
  162.   tempmatrix\value[#Xx] + (*self\value[8]  * *matrix\value[2])
  163.   tempmatrix\value[#Xx] + (*self\value[12] * *matrix\value[3])
  164.  
  165.   tempmatrix\value[#Xy] = (*self\value[1]  * *matrix\value[0])
  166.   tempmatrix\value[#Xy] + (*self\value[5]  * *matrix\value[1])
  167.   tempmatrix\value[#Xy] + (*self\value[9]  * *matrix\value[2])
  168.   tempmatrix\value[#Xy] + (*self\value[13] * *matrix\value[3])
  169.  
  170.   tempmatrix\value[#Xz] = (*self\value[2]  * *matrix\value[0])
  171.   tempmatrix\value[#Xz] + (*self\value[6]  * *matrix\value[1])
  172.   tempmatrix\value[#Xz] + (*self\value[10] * *matrix\value[2])
  173.   tempmatrix\value[#Xz] + (*self\value[14] * *matrix\value[3])
  174.  
  175.   tempmatrix\value[#Xw] = (*self\value[3]  * *matrix\value[0])
  176.   tempmatrix\value[#Xw] + (*self\value[7]  * *matrix\value[1])
  177.   tempmatrix\value[#Xw] + (*self\value[11] * *matrix\value[2])
  178.   tempmatrix\value[#Xw] + (*self\value[15] * *matrix\value[3])  
  179.  
  180.   tempmatrix\value[#Yx] = (*self\value[0]  * *matrix\value[4])
  181.   tempmatrix\value[#Yx] + (*self\value[4]  * *matrix\value[5])
  182.   tempmatrix\value[#Yx] + (*self\value[8]  * *matrix\value[6])
  183.   tempmatrix\value[#Yx] + (*self\value[12] * *matrix\value[7])
  184.  
  185.   tempmatrix\value[#Yy] = (*self\value[1]  * *matrix\value[4])
  186.   tempmatrix\value[#Yy] + (*self\value[5]  * *matrix\value[5])
  187.   tempmatrix\value[#Yy] + (*self\value[9]  * *matrix\value[6])
  188.   tempmatrix\value[#Yy] + (*self\value[13] * *matrix\value[7])
  189.  
  190.   tempmatrix\value[#Yz] = (*self\value[2]  * *matrix\value[4])
  191.   tempmatrix\value[#Yz] + (*self\value[6]  * *matrix\value[5])
  192.   tempmatrix\value[#Yz] + (*self\value[10] * *matrix\value[6])
  193.   tempmatrix\value[#Yz] + (*self\value[14] * *matrix\value[7])
  194.  
  195.   tempmatrix\value[#Yw] = (*self\value[3]  * *matrix\value[4])
  196.   tempmatrix\value[#Yw] + (*self\value[7]  * *matrix\value[5])
  197.   tempmatrix\value[#Yw] + (*self\value[11] * *matrix\value[6])
  198.   tempmatrix\value[#Yw] + (*self\value[15] * *matrix\value[7])  
  199.  
  200.   tempmatrix\value[#Zx] = (*self\value[0]  * *matrix\value[8])
  201.   tempmatrix\value[#Zx] + (*self\value[4]  * *matrix\value[9])
  202.   tempmatrix\value[#Zx] + (*self\value[8]  * *matrix\value[10])
  203.   tempmatrix\value[#Zx] + (*self\value[12] * *matrix\value[11])
  204.  
  205.   tempmatrix\value[#Zy] = (*self\value[1]  * *matrix\value[8])
  206.   tempmatrix\value[#Zy] + (*self\value[5]  * *matrix\value[9])
  207.   tempmatrix\value[#Zy] + (*self\value[9]  * *matrix\value[10])
  208.   tempmatrix\value[#Zy] + (*self\value[13] * *matrix\value[11])
  209.  
  210.   tempmatrix\value[#Zz] = (*self\value[2]  * *matrix\value[8])
  211.   tempmatrix\value[#Zz] + (*self\value[6]  * *matrix\value[9])
  212.   tempmatrix\value[#Zz] + (*self\value[10] * *matrix\value[10])
  213.   tempmatrix\value[#Zz] + (*self\value[14] * *matrix\value[11])
  214.  
  215.   tempmatrix\value[#Zw] = (*self\value[3]  * *matrix\value[8])
  216.   tempmatrix\value[#Zw] + (*self\value[7]  * *matrix\value[9])
  217.   tempmatrix\value[#Zw] + (*self\value[11] * *matrix\value[10])
  218.   tempmatrix\value[#zw] + (*self\value[15] * *matrix\value[11])
  219.  
  220.   tempmatrix\value[#Tx] = (*self\value[0]  * *matrix\value[12])
  221.   tempmatrix\value[#Tx] + (*self\value[4]  * *matrix\value[13])
  222.   tempmatrix\value[#Tx] + (*self\value[8]  * *matrix\value[14])
  223.   tempmatrix\value[#Tx] + (*self\value[12] * *matrix\value[15])
  224.  
  225.   tempmatrix\value[#Ty] = (*self\value[1]  * *matrix\value[12])
  226.   tempmatrix\value[#Ty] + (*self\value[5]  * *matrix\value[13])
  227.   tempmatrix\value[#Ty] + (*self\value[9]  * *matrix\value[14])
  228.   tempmatrix\value[#Ty] + (*self\value[13] * *matrix\value[15])
  229.  
  230.   tempmatrix\value[#Tz] = (*self\value[2]  * *matrix\value[12])
  231.   tempmatrix\value[#Tz] + (*self\value[6]  * *matrix\value[13])
  232.   tempmatrix\value[#Tz] + (*self\value[10] * *matrix\value[14])
  233.   tempmatrix\value[#Tz] + (*self\value[14] * *matrix\value[15])
  234.  
  235.   tempmatrix\value[#Tw] = (*self\value[3]  * *matrix\value[12])
  236.   tempmatrix\value[#Tw] + (*self\value[7]  * *matrix\value[13])
  237.   tempmatrix\value[#Tw] + (*self\value[11] * *matrix\value[14])
  238.   tempmatrix\value[#Tw] + (*self\value[15] * *matrix\value[15])
  239.  
  240.   CopyMemory(@tempmatrix\value[0], @*self\value[0], #MATRIX_SIZEBYTE)
  241. EndProcedure
  242.  
  243. Procedure rotateX(*Self.MATRIXSTR, angledegree.f)
  244.   Define tempmatrix.MATRIXSTR
  245.   Define sine.f
  246.   Define cosine.f
  247.  
  248.   traceFunction("rotateX()")
  249.  
  250.   angledegree = Radian(angledegree)
  251.   sine = Sin(angledegree)
  252.   cosine = Cos(angledegree)
  253.  
  254.   identity(tempmatrix)
  255.  
  256.   With tempmatrix
  257.           \value[#Yy] = cosine
  258.           \value[#Yz] = -sine
  259.           \value[#Zy] = sine
  260.           \value[#Zz] = cosine
  261.         EndWith
  262.        
  263.         multiply(*self, tempmatrix)
  264. EndProcedure
  265.  
  266. Procedure rotateY(*Self.MATRIXSTR, angledegree.f)
  267.   Define tempmatrix.MATRIXSTR
  268.   Define sine.f
  269.   Define cosine.f
  270.  
  271.   traceFunction("rotateY()")
  272.  
  273.   angledegree = Radian(angledegree)
  274.   sine = Sin(angledegree)
  275.   cosine = Cos(angledegree)
  276.  
  277.   identity(tempmatrix)
  278.  
  279.   With tempmatrix
  280.           \value[#Xx] = cosine
  281.           \value[#Zx] = sine
  282.           \value[#Xz] = -sine
  283.           \value[#Zz] = cosine
  284.         EndWith
  285.        
  286.         multiply(*self, tempmatrix)
  287. EndProcedure
  288.  
  289. Procedure rotateZ(*Self.MATRIXSTR, angledegree.f)
  290.   Define tempmatrix.MATRIXSTR
  291.   Define sine.f
  292.   Define cosine.f
  293.  
  294.   traceFunction("rotateZ()")
  295.  
  296.   angledegree = Radian(angledegree)
  297.   sine = Sin(angledegree)
  298.   cosine = Cos(angledegree)
  299.  
  300.   identity(tempmatrix)
  301.  
  302.   With tempmatrix
  303.           \value[#Xx] = cosine
  304.           \value[#Xy] = -sine
  305.           \value[#Yx] = sine
  306.           \value[#Yy] = cosine
  307.         EndWith
  308.        
  309.         multiply(*self, tempmatrix)
  310. EndProcedure
  311.  
  312. Procedure translate(*Self.MATRIXSTR, x.f, y.f, z.f)
  313.   Define tempmatrix.MATRIXSTR
  314.  
  315.   traceFunction("translate()")
  316.  
  317.   identity(tempmatrix)
  318.  
  319.   With tempmatrix
  320.           \value[#Tx] = x
  321.           \value[#Ty] = y
  322.           \value[#Tz] = z
  323.         EndWith
  324.  
  325.         multiply(*self, tempmatrix)
  326. EndProcedure
  327.  
  328. Procedure perspective(*Self.MATRIXSTR, angle.f, near.f, far.f, aspect.f)
  329.   Define y_scale.f
  330.   Define x_scale.f
  331.   Define frustum_length.f
  332.  
  333.   traceFunction("perspective()")
  334.  
  335.   y_scale = 1.0/Tan(Radian(angle/2))
  336.   x_scale = y_scale/aspect
  337.   frustum_length = (far-near)
  338.  
  339.   With *self
  340.     \value[#Xx] = x_scale
  341.     \value[#Yy] = y_scale
  342.     \value[#Zz] = -( (near+far)/frustum_length )
  343.     \value[#Zw] = -1
  344.     \value[#Tz] = -( (2*near*far)/frustum_length )
  345.    
  346.     \value[#Xy] = 0
  347.     \value[#Xz] = 0
  348.     \value[#Xw] = 0
  349.     \value[#Yx] = 0
  350.     \value[#Yz] = 0
  351.     \value[#Yw] = 0
  352.     \value[#Zx] = 0
  353.     \value[#Zy] = 0
  354.     \value[#Tx] = 0
  355.     \value[#Ty] = 0
  356.     \value[#Tw] = 0
  357.   EndWith
  358. EndProcedure
  359.  
  360. Procedure orthogonal(*Self.MATRIXSTR, left.f, right.f, bottom.f, top.f, near.f, far.f)
  361.   traceFunction("orthogonal()")
  362.  
  363.   With *Self
  364.     \value[#Xx] = 2/(right-left)
  365.     \value[#Yy] = 2/(top-bottom)
  366.     \value[#Zz] = -2/(far-near)
  367.     \value[#Tx] = -( (right+left)/(right-left) )
  368.     \value[#Ty] = -( (top+bottom)/(top-bottom) )
  369.     \value[#Tz] = -( (far+near)/(far-near) )
  370.     \value[#Tw] = 1
  371.    
  372.     \value[#Xy] = 0
  373.     \value[#Xz] = 0
  374.     \value[#Xw] = 0
  375.     \value[#Yx] = 0
  376.     \value[#Yz] = 0
  377.     \value[#Yw] = 0
  378.     \value[#Zx] = 0
  379.     \value[#Zy] = 0
  380.   EndWith
  381. EndProcedure
  382.  
  383. Procedure lookAt(*Self.MATRIXSTR, eyeX.f, eyeY.f, eyeZ.f, centerX.f, centerY.f, centerZ.f, upX.f, upY.f, upZ.f)
  384.   Dim axe.f(2)
  385.   Dim regard.f(2)
  386.   Dim normal.f(2)
  387.   Dim newaxe.f(2)
  388.   Define tempmatrix.MATRIXSTR
  389.  
  390.   traceFunction("lookAt()")
  391.  
  392.   axe(0) = upX
  393.   axe(1) = upY
  394.   axe(2) = upZ
  395.   regard(0) = centerX-eyeX
  396.   regard(1) = centerY-eyeY
  397.   regard(2) = centerZ-eyeZ
  398.  
  399.   crossProduct( regard(), axe(), normal() )
  400.   crossProduct( normal(), regard(), newaxe() )
  401.  
  402.   normalize( normal() )
  403.   normalize( newaxe() )
  404.   normalize( regard() )
  405.  
  406.   With tempmatrix
  407.     \value[#Xx] = normal(0)
  408.     \value[#Xy] = newaxe(0)
  409.     \value[#Xz] = -regard(0)
  410.     \value[#Yx] = normal(1)
  411.     \value[#Yy] = newaxe(1)
  412.     \value[#Yz] = -regard(1)
  413.     \value[#Zx] = normal(2)
  414.     \value[#Zy] = newaxe(2)
  415.     \value[#Zz] = -regard(2)
  416.     \value[#Tw] = 1.0
  417.   EndWith
  418.  
  419.   multiply(*self, tempmatrix)
  420.   translate(*self, -eyeX, -eyeY, -eyeZ)
  421. EndProcedure
  422.  
  423. Procedure push(*Self.MATRIXSTR)
  424.   Define *tempstr.PARENTSTR = AllocateMemory( SizeOf(PARENTSTR) )
  425.  
  426.   traceFunction("push()")
  427.   CopyMemory(@*Self\value[0], @*tempstr\value[0], #MATRIX_SIZEBYTE)
  428.  
  429.   If *Self\parent
  430.     *tempstr\parent = *Self\parent
  431.   EndIf
  432.  
  433.   *Self\parent = *tempstr
  434. EndProcedure
  435.  
  436. Procedure pop(*Self.MATRIXSTR)
  437.   Define *tempstr.PARENTSTR = *Self\parent
  438.  
  439.   traceFunction("pop()")
  440.  
  441.   If Not *Self\parent
  442.     Debug "No matrix to restore"
  443.     ProcedureReturn
  444.   EndIf
  445.  
  446.   CopyMemory(@*tempstr\value[0], @*Self\value[0], #MATRIX_SIZEBYTE)
  447.  
  448.   If *tempstr\parent
  449.     *Self\parent = *tempstr\parent
  450.   Else
  451.     *self\parent = #Null
  452.   EndIf
  453.  
  454.   FreeMemory(*tempstr)
  455. EndProcedure
  456.  
  457. Procedure destroy(*Self.MATRIXSTR)
  458.   traceFunction("destroy()")
  459.   FreeMemory(*self)
  460. EndProcedure
  461.  
  462. Procedure.i createMatrix(label.s)
  463.   Define *temp.MATRIXSTR
  464.  
  465.   traceFunction("createMatrix()")
  466.    
  467.   *temp.MATRIXSTR = AllocateMemory( SizeOf( MATRIXSTR ) )
  468.   *temp\VTable = ?VTable
  469.   *temp\label = label
  470.   ProcedureReturn *temp
  471. EndProcedure
  472.  
  473. DataSection
  474.   VTable:
  475.   Data.l @debugValues()
  476.   Data.l @getAddress()
  477.   Data.l @identity()
  478.   Data.l @multiply()
  479.   Data.l @rotateX()
  480.   Data.l @rotateY()
  481.   Data.l @rotateZ()
  482.   Data.l @translate()
  483.   Data.l @perspective()
  484.   Data.l @orthogonal()
  485.   Data.l @lookAt()
  486.   Data.l @push()
  487.   Data.l @pop()
  488.   Data.l @destroy()
  489.  
  490.   MatrixIdentity:
  491.   Data.f 1, 0, 0, 0
  492.   Data.f 0, 1, 0, 0
  493.   Data.f 0, 0, 1, 0
  494.   Data.f 0, 0, 0, 1
  495. EndDataSection