home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Programming / MiniGL / src / matrix.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-04-11  |  22.7 KB  |  918 lines

  1. /*
  2.  * $Id: matrix.c,v 1.1.1.1 2000/04/07 19:44:51 hfrieden Exp $
  3.  *
  4.  * $Date: 2000/04/07 19:44:51 $
  5.  * $Revision: 1.1.1.1 $
  6.  *
  7.  * (C) 1999 by Hyperion
  8.  * All rights reserved
  9.  *
  10.  * This file is part of the MiniGL library project
  11.  * See the file Licence.txt for more details
  12.  *
  13.  */
  14.  
  15. #include "sysinc.h"
  16. #include <math.h>
  17.  
  18. #ifndef PI
  19.     #ifdef M_PI
  20.     #define PI M_PI
  21.     #else
  22.     #define PI 3.1415927
  23.     #endif
  24. #endif
  25. static char rcsid[] = "$Id: matrix.c,v 1.1.1.1 2000/04/07 19:44:51 hfrieden Exp $";
  26.  
  27. INLINE void m_MatCopy(Matrix *pA, Matrix *pB);
  28. INLINE void m_MatMultGeneral(Matrix *pA, float *pB, Matrix *pC);
  29. INLINE void m_MatMultB0001(Matrix *pA, float *pB, Matrix *pC);
  30. INLINE void m_MatMultA0001(Matrix *pA, float *pB, Matrix *pC);
  31. INLINE void m_MatMultATrans(Matrix *pA, float *pB, Matrix *pC);
  32. INLINE void m_MatMultBTrans(Matrix *pA, float *pB, Matrix *pC);
  33. INLINE void m_LoadMatrixf(Matrix *pA, const float *v);
  34. INLINE void m_LoadMatrixd(Matrix *pA, const double *v);
  35. INLINE void m_LoadIdentity(Matrix *pA);
  36. INLINE void m_Mult(Matrix *pA, float *v, int vtype, Matrix *pC);
  37. void m_CombineMatrices(GLcontext context);
  38. void GLMatrixInit(GLcontext context);
  39.  
  40.  
  41. /* I am too lazy to convert our old code */
  42. #define CM_0 OF_11
  43. #define CM_1 OF_12
  44. #define CM_2 OF_13
  45. #define CM_3 OF_21
  46. #define CM_4 OF_22
  47. #define CM_5 OF_23
  48. #define CM_6 OF_31
  49. #define CM_7 OF_32
  50. #define CM_8 OF_33
  51.  
  52. /*
  53. ** Computes the determinant of the upper 3x3 submatrix block
  54. ** of the supplied matrix
  55. */
  56. INLINE GLfloat m_Determinant(Matrix *pA)
  57. {
  58.     #define a(x) (pA->v[CM_##x])
  59.      return ( a(0)*a(4)*a(8)  +  a(1)*a(5)*a(6)  + a(2)*a(3)*a(7)
  60.        -  a(0)*a(5)*a(7)  -  a(1)*a(3)*a(8)  - a(2)*a(4)*a(6));
  61.     #undef a
  62. }
  63.  
  64. /*
  65. ** Builds the inverse of the upper 3x3 submatrix block of the
  66. ** supplied matrix for the backtransformation of the normals
  67. */
  68. void m_DoInvert(Matrix *pA, GLfloat *out)
  69. {
  70.     GLfloat det = 1.f / m_Determinant(pA);
  71.  
  72.     #define a(x) (pA->v[CM_##x])
  73.  
  74.     *out++ = (GLfloat)(a(4)*a(8) - a(5)*a(7))*det;
  75.     *out++ = (GLfloat)(a(2)*a(7) - a(1)*a(8))*det;
  76.     *out++ = (GLfloat)(a(1)*a(5) - a(2)*a(4))*det;
  77.  
  78.     *out++ = (GLfloat)(a(5)*a(6) - a(3)*a(8))*det;
  79.     *out++ = (GLfloat)(a(0)*a(8) - a(2)*a(6))*det;
  80.     *out++ = (GLfloat)(a(2)*a(3) - a(0)*a(5))*det;
  81.     
  82.     *out++ = (GLfloat)(a(3)*a(7) - a(4)*a(6))*det;
  83.     *out++ = (GLfloat)(a(1)*a(6) - a(0)*a(7))*det;
  84.     *out++ = (GLfloat)(a(0)*a(4) - a(1)*a(3))*det;
  85.  
  86.     #undef a
  87. }
  88.  
  89. void m_BuildInverted(GLcontext context)
  90. {
  91.     context->InvRotValid = GL_TRUE;
  92.     m_DoInvert(CurrentMV, context->InvRot);
  93. }
  94.  
  95. /*
  96. ** Copy matrix B to matrix A
  97. ** A = B
  98. */
  99. INLINE void m_MatCopy(Matrix *pA, Matrix *pB)
  100. {
  101.     int i;
  102.  
  103.     for (i=0; i<16; i++) pA->v[i] = pB->v[i];
  104.     pA->flags = pB->flags;
  105.     pA->Inverse = pB->Inverse;
  106. }
  107.  
  108. /*
  109. ** General case: Matrix multiply
  110. ** Multiply matrix A by float field, storing the result in matrix C
  111. */
  112. INLINE void m_MatMultGeneral(Matrix *pA, float *pB, Matrix *pC)
  113. {
  114.     #define a(x) (pA->v[OF_##x])
  115.     #define b(x) (pB[OF_##x])
  116.     #define c(x) (pC->v[OF_##x])
  117.  
  118.     c(11) = a(11)*b(11) + a(12)*b(21) +
  119.             a(13)*b(31) + a(14)*b(41);
  120.  
  121.     c(12) = a(11)*b(12) + a(12)*b(22) +
  122.             a(13)*b(32) + a(14)*b(42);
  123.  
  124.     c(13) = a(11)*b(13) + a(12)*b(23) +
  125.             a(13)*b(33) + a(14)*b(43);
  126.  
  127.     c(14) = a(11)*b(14) + a(12)*b(24) +
  128.             a(13)*b(34) + a(14)*b(44);
  129.  
  130.     c(21) = a(21)*b(11) + a(22)*b(21) +
  131.             a(23)*b(31) + a(24)*b(41);
  132.  
  133.     c(22) = a(21)*b(12) + a(22)*b(22) +
  134.             a(23)*b(32) + a(24)*b(42);
  135.  
  136.     c(23) = a(21)*b(13) + a(22)*b(23) +
  137.             a(23)*b(33) + a(24)*b(43);
  138.  
  139.     c(24) = a(21)*b(14) + a(22)*b(24) +
  140.             a(23)*b(34) + a(24)*b(44);
  141.  
  142.     c(31) = a(31)*b(11) + a(32)*b(21) +
  143.             a(33)*b(31) + a(34)*b(41);
  144.  
  145.     c(32) = a(31)*b(12) + a(32)*b(22) +
  146.             a(33)*b(32) + a(34)*b(42);
  147.  
  148.     c(33) = a(31)*b(13) + a(32)*b(23) +
  149.             a(33)*b(33) + a(34)*b(43);
  150.  
  151.     c(34) = a(31)*b(14) + a(32)*b(24) +
  152.             a(33)*b(34) + a(34)*b(44);
  153.  
  154.     c(41) = a(41)*b(11) + a(42)*b(21) +
  155.             a(43)*b(31) + a(44)*b(41);
  156.  
  157.     c(42) = a(41)*b(12) + a(42)*b(22) +
  158.             a(43)*b(32) + a(44)*b(42);
  159.  
  160.     c(43) = a(41)*b(13) + a(42)*b(23) +
  161.             a(43)*b(33) + a(44)*b(43);
  162.  
  163.     c(44) = a(41)*b(14) + a(42)*b(24) +
  164.             a(43)*b(34) + a(44)*b(44);
  165.  
  166.     #undef a
  167.     #undef b
  168. }
  169.  
  170. /*
  171. ** Matrix B has three rows
  172. ** Multiply matrix A by float field, storing the result in matrix C
  173. */
  174. INLINE void m_MatMultB0001(Matrix *pA, float *pB, Matrix *pC)
  175. {
  176.     #define a(x) (pA->v[OF_##x])
  177.     #define b(x) (pB[OF_##x])
  178.     #define c(x) (pC->v[OF_##x])
  179.  
  180.     c(11) = a(11)*b(11) + a(12)*b(21) +
  181.             a(13)*b(31);
  182.  
  183.     c(12) = a(11)*b(12) + a(12)*b(22) +
  184.             a(13)*b(32);
  185.  
  186.     c(13) = a(11)*b(13) + a(12)*b(23) +
  187.             a(13)*b(33);
  188.  
  189.     c(14) = a(11)*b(14) + a(12)*b(24) +
  190.             a(13)*b(34) + a(14);
  191.  
  192.     c(21) = a(21)*b(11) + a(22)*b(21) +
  193.             a(23)*b(31);
  194.  
  195.     c(22) = a(21)*b(12) + a(22)*b(22) +
  196.             a(23)*b(32);
  197.  
  198.     c(23) = a(21)*b(13) + a(22)*b(23) +
  199.             a(23)*b(33);
  200.  
  201.     c(24) = a(21)*b(14) + a(22)*b(24) +
  202.             a(23)*b(34) + a(24);
  203.  
  204.     c(31) = a(31)*b(11) + a(32)*b(21) +
  205.             a(33)*b(31);
  206.  
  207.     c(32) = a(31)*b(12) + a(32)*b(22) +
  208.             a(33)*b(32);
  209.  
  210.     c(33) = a(31)*b(13) + a(32)*b(23) +
  211.             a(33)*b(33);
  212.  
  213.     c(34) = a(31)*b(14) + a(32)*b(24) +
  214.             a(33)*b(34) + a(34);
  215.  
  216.     c(41) = a(41)*b(11) + a(42)*b(21) +
  217.             a(43)*b(31);
  218.  
  219.     c(42) = a(41)*b(12) + a(42)*b(22) +
  220.             a(43)*b(32);
  221.  
  222.     c(43) = a(41)*b(13) + a(42)*b(23) +
  223.             a(43)*b(33);
  224.  
  225.     c(44) = a(41)*b(14) + a(42)*b(24) +
  226.             a(43)*b(34) + a(44);
  227.  
  228.     #undef a
  229.     #undef b
  230. }
  231.  
  232.  
  233. /*
  234. ** Matrix A has three rows
  235. ** Multiply matrix A by float field, storing the result in matrix C
  236. */
  237. INLINE void m_MatMultA0001(Matrix *pA, float *pB, Matrix *pC)
  238. {
  239.     #define a(x) (pA->v[OF_##x])
  240.     #define b(x) (pB[OF_##x])
  241.     #define c(x) (pC->v[OF_##x])
  242.  
  243.     c(11) = a(11)*b(11) + a(12)*b(21) +
  244.             a(13)*b(31) + a(14)*b(41);
  245.  
  246.     c(12) = a(11)*b(12) + a(12)*b(22) +
  247.             a(13)*b(32) + a(14)*b(42);
  248.  
  249.     c(13) = a(11)*b(13) + a(12)*b(23) +
  250.             a(13)*b(33) + a(14)*b(43);
  251.  
  252.     c(14) = a(11)*b(14) + a(12)*b(24) +
  253.             a(13)*b(34) + a(14)*b(44);
  254.  
  255.     c(21) = a(21)*b(11) + a(22)*b(21) +
  256.             a(23)*b(31) + a(24)*b(41);
  257.  
  258.     c(22) = a(21)*b(12) + a(22)*b(22) +
  259.             a(23)*b(32) + a(24)*b(42);
  260.  
  261.     c(23) = a(21)*b(13) + a(22)*b(23) +
  262.             a(23)*b(33) + a(24)*b(43);
  263.  
  264.     c(24) = a(21)*b(14) + a(22)*b(24) +
  265.             a(23)*b(34) + a(24)*b(44);
  266.  
  267.     c(31) = a(31)*b(11) + a(32)*b(21) +
  268.             a(33)*b(31) + a(34)*b(41);
  269.  
  270.     c(32) = a(31)*b(12) + a(32)*b(22) +
  271.             a(33)*b(32) + a(34)*b(42);
  272.  
  273.     c(33) = a(31)*b(13) + a(32)*b(23) +
  274.             a(33)*b(33) + a(34)*b(43);
  275.  
  276.     c(34) = a(31)*b(14) + a(32)*b(24) +
  277.             a(33)*b(34) + a(34)*b(44);
  278.  
  279.     c(41) = b(41);
  280.  
  281.     c(42) = b(42);
  282.  
  283.     c(43) = b(43);
  284.  
  285.     c(44) = b(44);
  286.  
  287.     #undef a
  288.     #undef b
  289. }
  290.  
  291. /*
  292. ** Matrix A is a translation matrix
  293. ** Multiply matrix A by float field, storing the result in matrix C
  294. */
  295. INLINE void m_MatMultATrans(Matrix *pA, float *pB, Matrix *pC)
  296. {
  297.     #define a(x) (pA->v[OF_##x])
  298.     #define b(x) (pB[OF_##x])
  299.     #define c(x) (pC->v[OF_##x])
  300.  
  301.     c(11) = b(11) + a(14)*b(41);
  302.  
  303.     c(12) = b(12) + a(14)*b(42);
  304.  
  305.     c(13) = b(13) + a(14)*b(43);
  306.  
  307.     c(14) = b(14) + a(14)*b(44);
  308.  
  309.     c(21) = b(21) + a(24)*b(41);
  310.  
  311.     c(22) = b(22) + a(24)*b(42);
  312.  
  313.     c(23) = b(23) + a(24)*b(43);
  314.  
  315.     c(24) = b(24) + a(24)*b(44);
  316.  
  317.     c(31) = b(31) + a(34)*b(41);
  318.  
  319.     c(32) = b(32) + a(34)*b(42);
  320.  
  321.     c(33) = b(33) + a(34)*b(43);
  322.  
  323.     c(34) = b(34) + a(34)*b(44);
  324.  
  325.     c(41) = b(41);
  326.  
  327.     c(42) = b(42);
  328.  
  329.     c(43) = b(43);
  330.  
  331.     c(44) = b(44);
  332.  
  333.     #undef a
  334.     #undef b
  335. }
  336.  
  337. /*
  338. ** Matrix B is a translation matrix
  339. ** Multiply matrix A by float field, storing the result in matrix C
  340. */
  341. INLINE void m_MatMultBTrans(Matrix *pA, float *pB, Matrix *pC)
  342. {
  343.     #define a(x) (pA->v[OF_##x])
  344.     #define b(x) (pB[OF_##x])
  345.     #define c(x) (pC->v[OF_##x])
  346.  
  347.     c(11) = a(11);
  348.  
  349.     c(12) = a(12);
  350.  
  351.     c(13) = a(13);
  352.  
  353.     c(14) = a(14)*b(14) + a(12)*b(24) +
  354.             a(13)*b(34) + a(14);
  355.  
  356.     c(21) = a(21)*b(11) + a(22)*b(21) +
  357.             a(23)*b(31) + a(24)*b(41);
  358.  
  359.     c(22) = a(22);
  360.  
  361.     c(23) = a(22);
  362.  
  363.     c(24) = a(21)*b(14) + a(22)*b(24) +
  364.             a(23)*b(34) + a(24);
  365.  
  366.     c(31) = a(31);
  367.  
  368.     c(32) = a(32);
  369.  
  370.     c(33) = a(33);
  371.  
  372.     c(34) = a(31)*b(14) + a(32)*b(24) +
  373.             a(33)*b(34) + a(34);
  374.  
  375.     c(41) = a(41);
  376.  
  377.     c(42) = a(42);
  378.  
  379.     c(43) = a(43);
  380.  
  381.     c(44) = a(41)*b(14) + a(42)*b(24) +
  382.             a(43)*b(34) + a(44);
  383.  
  384.     #undef a
  385.     #undef b
  386. }
  387.  
  388.  
  389. INLINE void m_LoadMatrixf(Matrix *pA, const float *v)
  390. {
  391.     #define a(x) pA->v[OF_##x] = *v++
  392.  
  393.     a(11); a(21); a(31); a(41);
  394.     a(12); a(22); a(32); a(42);
  395.     a(13); a(23); a(33); a(43);
  396.     a(14); a(24); a(34); a(44);
  397.  
  398.     if (*(v-4) == 0.f && *(v-3) == 0.f && *(v-2) == 0.f && *(v-1) == 1.f)
  399.         pA->flags = MGLMAT_0001;
  400.  
  401.     #undef a
  402. }
  403.  
  404. INLINE void m_LoadMatrixd(Matrix *pA, const double *v)
  405. {
  406.     #define a(x) pA->v[OF_##x] = (float)*v++
  407.  
  408.     a(11); a(21); a(31); a(41);
  409.     a(12); a(22); a(32); a(42);
  410.     a(13); a(23); a(33); a(43);
  411.     a(14); a(24); a(34); a(44);
  412.  
  413.     if (*(v-4) == 0.0 && *(v-3) == 0.0 && *(v-2) == 0.0 && *(v-1) == 1.0)
  414.         pA->flags = MGLMAT_0001;
  415.  
  416.     #undef a
  417. }
  418.  
  419.  
  420. INLINE void m_LoadIdentity(Matrix *pA)
  421. {
  422.     #define a(x) pA->v[OF_##x] = 0.f;
  423.     #define b(x) pA->v[OF_##x] = 1.f;
  424.  
  425.     b(11); a(21); a(31); a(41);
  426.     a(12); b(22); a(32); a(42);
  427.     a(13); a(23); b(33); a(43);
  428.     a(14); a(24); a(34); b(44);
  429.  
  430.     pA->flags = MGLMAT_IDENTITY;
  431.  
  432.     #undef a
  433.     #undef b
  434. }
  435.  
  436. /*
  437. ** Multiply matrix A by the matrix passed by v.
  438. ** The vtype specifies what kind of matrix v points to, so that
  439. ** this routine may select an optimized matrix multiplication routine.
  440. */
  441. INLINE void m_Mult(Matrix *pA, float *v, int vtype, Matrix *pC)
  442. {
  443. #if 0
  444.     if ((pA->flags & vtype) == 0)
  445.     {
  446.         m_MatMultGeneral(pA, v, pC);
  447.     }
  448.     else if (vtype == MGLMAT_TRANSLATION)
  449.     {
  450.         m_MatMultBTrans(pA, v, pC);
  451.     }
  452.     else if (vtype == MGLMAT_ROTATION || vtype == MGLMAT_0001)
  453.     {
  454.         m_MatMultB0001(pA, v, pC);
  455.     }
  456.     else if (pA->flags == MGLMAT_TRANSLATION)
  457.     {
  458.         m_MatMultATrans(pA, v, pC);
  459.     }
  460.     else if (pA->flags == MGLMAT_0001)
  461.     {
  462.         m_MatMultA0001(pA, v, pC);
  463.     }
  464.     else
  465.     {
  466.         m_MatMultGeneral(pA, v, pC);
  467.     }
  468.  
  469.     pC->flags = 0;
  470.  
  471.     if (vtype & MGLMASK_0001)
  472.     {
  473.         if (pA->flags & MGLMASK_0001)
  474.         {
  475.             pC->flags = MGLMAT_0001;
  476.         }
  477.     }
  478. #else
  479.     //FIXME: Put those special case mults back.
  480.     m_MatMultGeneral(pA, v, pC);
  481. #endif
  482. }
  483.  
  484. void m_CombineMatrices(GLcontext context)
  485. {
  486.     m_Mult(CurrentP,
  487.     CurrentMV->v,
  488.     CurrentMV->flags, &(context->CombinedMatrix));
  489.     context->CombinedValid = GL_TRUE;
  490. }
  491.  
  492. void m_PrintMatrix(Matrix *pA)
  493. {
  494.     #define a(x) (pA->v[OF_##x])
  495.     mykprintf("Matrix at 0x%lX\n", (ULONG)pA);
  496.     mykprintf("    | %6.3f %6.3f %6.3f %6.3f |\n",
  497.         a(11), a(12), a(13), a(14));
  498.     mykprintf("    | %6.3f %6.3f %6.3f %6.3f |\n",
  499.         a(21), a(22), a(23), a(24));
  500.     mykprintf("A = | %6.3f %6.3f %6.3f %6.3f |\n",
  501.         a(31), a(32), a(33), a(34));
  502.     mykprintf("    | %6.3f %6.3f %6.3f %6.3f |\n",
  503.         a(41), a(42), a(43), a(44));
  504.     #undef a
  505. }
  506.  
  507. // Interface functions
  508. void GLMatrixMode(GLcontext context, GLenum mode)
  509. {
  510.     //LOG(3, glMatrixMode, "%d", mode);
  511.     GLASSERT(mode == GL_PROJECTION || mode == GL_MODELVIEW);
  512.     GLASSERT(context != NULL);
  513.  
  514.     context->CurrentMatrixMode = mode;
  515. }
  516.  
  517. void GLLoadIdentity(GLcontext context)
  518. {
  519.     //LOG(3, glLoadIdentity, "");
  520.     GLASSERT(context != NULL);
  521.     GLFlagError(context, context->CurrentPrimitive != GL_BASE, GL_INVALID_OPERATION);
  522.     if (context->CurrentMatrixMode == GL_MODELVIEW)
  523.     {
  524.         m_LoadIdentity(CurrentMV);
  525.     }
  526.     else
  527.     {
  528.         m_LoadIdentity(CurrentP);
  529.     }
  530.     context->CombinedValid = GL_FALSE;
  531.     context->InvRotValid = GL_FALSE;
  532. }
  533.  
  534. void MGLPrintMatrix(GLcontext context, int mode)
  535. {
  536.     if (mode == GL_MODELVIEW)
  537.     {
  538.         m_PrintMatrix(CurrentMV);
  539.     }
  540.     else
  541.     {
  542.         m_PrintMatrix(CurrentP);
  543.     }
  544.     mykprintf("\n");
  545. }
  546.  
  547. void MGLPrintMatrixStack(GLcontext context, int mode)
  548. {
  549.     int i;
  550.  
  551.     mykprintf("Stack Top:\n");
  552.     MGLPrintMatrix(context, mode);
  553.     mykprintf("Rest of stack:\n");
  554.  
  555.     if (mode == GL_MODELVIEW) {
  556.         if (context->ModelViewStackPointer == 0) {
  557.             mykprintf("Empty\n\n\n");
  558.             return;
  559.         }
  560.         for (i=context->ModelViewStackPointer-1; i>=0; i--)
  561.         {
  562.             mykprintf("%d:\n", i);
  563.             m_PrintMatrix(&(context->ModelViewStack[i]));
  564.         }
  565.     }
  566.     else
  567.     {
  568.         if (context->ProjectionStackPointer == 0) {
  569.             mykprintf("Empty\n\n\n");
  570.             return;
  571.         }
  572.         for (i=context->ProjectionStackPointer-1; i>=0; i--)
  573.         {
  574.             mykprintf("%d:\n", i);
  575.             m_PrintMatrix(&(context->ProjectionStack[i]));
  576.         }
  577.     }
  578.     mykprintf("\n\n");
  579. }
  580.  
  581.  
  582. void GLLoadMatrixf(GLcontext context, const GLfloat *m)
  583. {
  584.     //LOG(3, glLoadMatrixf, "%f %f %f ...", *m, *(m+1), *(m+2));
  585.     GLASSERT(context != NULL);
  586.     GLFlagError(context, context->CurrentPrimitive != GL_BASE, GL_INVALID_OPERATION);
  587.     context->CombinedValid = GL_FALSE;
  588.     context->InvRotValid = GL_FALSE;
  589.     m_LoadMatrixf(CMATRIX(context), m);
  590. }
  591.  
  592. void GLLoadMatrixd(GLcontext context, const GLdouble *m)
  593. {
  594.     //LOG(3, glLoadMatrixf, "%lf %lf %lf ...", *m, *(m+1), *(m+2));
  595.     GLASSERT(context != NULL);
  596.     GLFlagError(context, context->CurrentPrimitive != GL_BASE, GL_INVALID_OPERATION);
  597.     context->CombinedValid = GL_FALSE;
  598.     context->InvRotValid = GL_FALSE;
  599.     m_LoadMatrixd(CMATRIX(context), m);
  600. }
  601.  
  602. void GLPushMatrix(GLcontext context)
  603. {
  604.     //LOG(3, glPushMatrix, "");
  605.     GLASSERT(context != NULL);
  606.     GLASSERT(context->ProjectionStackPointer <= PROJECTION_STACK_SIZE);
  607.     GLASSERT(context->ModelViewStackPointer  <= MODELVIEW_STACK_SIZE);
  608.     GLFlagError(context, context->CurrentPrimitive != GL_BASE, GL_INVALID_OPERATION);
  609.  
  610.     if (context->CurrentMatrixMode == GL_PROJECTION)
  611.     {
  612.         m_MatCopy(&(context->ProjectionStack[context->ProjectionStackPointer]),
  613.             CurrentP);
  614.         context->ProjectionStackPointer ++;
  615.     }
  616.     else
  617.     {
  618.         m_MatCopy(&(context->ModelViewStack[context->ModelViewStackPointer]),
  619.             CurrentMV);
  620.         context->ModelViewStackPointer ++;
  621.     }
  622. }
  623.  
  624. void GLPopMatrix(GLcontext context)
  625. {
  626.     //LOG(3, glPopMatrix, "");
  627.     GLASSERT(context != NULL);
  628.     GLASSERT(context->ProjectionStackPointer >= 0);
  629.     GLASSERT(context->ModelViewStackPointer  >= 0);
  630.     GLFlagError(context, context->CurrentPrimitive != GL_BASE, GL_INVALID_OPERATION);
  631.     context->InvRotValid = GL_FALSE;
  632.     context->CombinedValid = GL_FALSE;
  633.  
  634.     if (context->CurrentMatrixMode == GL_PROJECTION)
  635.     {
  636.         if (context->ProjectionStackPointer <= 0)
  637.         {
  638.             context->CurrentError = GL_INVALID_OPERATION;
  639.             return;
  640.         }
  641.         context->ProjectionStackPointer --;
  642.         m_MatCopy(CurrentP,
  643.             &(context->ProjectionStack[context->ProjectionStackPointer]));
  644.     }
  645.     else
  646.     {
  647.         if (context->ModelViewStackPointer <= 0)
  648.         {
  649.             context->CurrentError = GL_INVALID_OPERATION;
  650.             return;
  651.         }
  652.         context->ModelViewStackPointer --;
  653.         m_MatCopy(CurrentMV,
  654.             &(context->ModelViewStack[context->ModelViewStackPointer]));
  655.     }
  656.  
  657. }
  658.  
  659. void GLFrustum(GLcontext context, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
  660. {
  661.     float v[16];
  662.     float n2 = 2.0*zNear;
  663.     float rli = 1.f / (float)(right-left);
  664.     float tbi = 1.f / (float)(top-bottom);
  665.     float fni = 1.f / (float)(zFar-zNear);
  666.  
  667.     //LOG(3, glFrustum, "%lf &lf %lf %lf %lf %lf", left, right, bottom, top, zNear, zFar);
  668.  
  669.     GLASSERT(context != NULL);
  670.     GLFlagError(context, zFar<=0.0 || zNear <=0.0, GL_INVALID_VALUE);
  671.     GLFlagError(context, context->CurrentPrimitive != GL_BASE, GL_INVALID_OPERATION);
  672.     context->InvRotValid = GL_FALSE;
  673.     context->CombinedValid = GL_FALSE;
  674.  
  675.     v[OF_11] = n2*rli; v[OF_21] = 0.0; v[OF_31] = 0.0; v[OF_41] = 0.0;
  676.  
  677.     v[OF_22] = n2*tbi; v[OF_12] = 0.0; v[OF_32] = 0.0; v[OF_42] = 0.0;
  678.  
  679.     v[OF_13] = (right+left)*rli; v[OF_23] = (top+bottom)*tbi;
  680.     v[OF_33] = -(zFar+zNear)*fni; v[OF_43] = -1.0;
  681.  
  682.     v[OF_14] = 0.0; v[OF_24] = 0.0;
  683.     v[OF_34] = -(2.0*zFar*zNear)*fni; v[OF_44] = 0.0;
  684.     m_Mult(CMATRIX(context),
  685.         v,
  686.         MGLMAT_PERSPECTIVE,
  687.         OMATRIX(context)
  688.         );
  689.     SMATRIX(context);
  690.  
  691. }
  692.  
  693. void GLOrtho(GLcontext context, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
  694. {
  695.     float rli = 1.0  / (right-left);
  696.     float tbi = 1.0  / (top-bottom);
  697.     float fni = 1.0 / (zFar-zNear);
  698.     float v[16];
  699.  
  700.     //LOG(3, glOrtho, "%lf %lf %lf %lf %lf %lf", left, right, bottom, top, zNear, zFar);
  701.  
  702.     GLASSERT(context != NULL);
  703.     GLFlagError(context, context->CurrentPrimitive != GL_BASE, GL_INVALID_OPERATION);
  704.     context->InvRotValid = GL_FALSE;
  705.     context->CombinedValid = GL_FALSE;
  706.  
  707.     v[OF_11] = 2.0*rli; v[OF_12] = 0.0; v[OF_13] = 0.0;
  708.     v[OF_14] = -(right+left)*rli;
  709.  
  710.     v[OF_21] = 0.0; v[OF_22] = 2.0*tbi;
  711.     v[OF_23] = 0.0; v[OF_24] = -(top+bottom)*tbi;
  712.  
  713.     v[OF_31] = 0.0; v[OF_32] = 0.0;
  714.     v[OF_33] = -2.0*fni; v[OF_34] = -(zFar+zNear)*fni;
  715.  
  716.     v[OF_41] = v[OF_42] = v[OF_43] = 0.0;
  717.     v[OF_44] = 1.0;
  718.  
  719.     m_Mult(CMATRIX(context), v, MGLMAT_ORTHO, OMATRIX(context));
  720.     SMATRIX(context);
  721. }
  722.  
  723. void GLMultMatrixf(GLcontext context, const GLfloat *mat)
  724. {
  725.     //LOG(3, glMultMatrixf, "%f %f %f ...", *mat, *(mat+1), *(mat+2));
  726.     GLASSERT(context != NULL);
  727.     GLFlagError(context, context->CurrentPrimitive != GL_BASE, GL_INVALID_OPERATION);
  728.     context->InvRotValid = GL_FALSE;
  729.     context->CombinedValid = GL_FALSE;
  730.  
  731.     m_Mult(CMATRIX(context), (float *)mat, 0, OMATRIX(context));
  732.     SMATRIX(context);
  733. }
  734.  
  735. void GLMultMatrixd(GLcontext context, const GLdouble *mat)
  736. {
  737.     GLfloat v[16];
  738.     int i;
  739.     //LOG(3, glMultMatrixd, "%lf %lf %lf ...", *mat, *(mat+1), *(mat+2));
  740.  
  741.     GLASSERT(context != NULL);
  742.     GLFlagError(context, context->CurrentPrimitive != GL_BASE, GL_INVALID_OPERATION);
  743.     context->InvRotValid = GL_FALSE;
  744.     context->CombinedValid = GL_FALSE;
  745.  
  746.     for (i=0; i<16; i++)
  747.     {
  748.         v[i] = (GLfloat) *mat++;
  749.     }
  750.  
  751.     m_Mult(CMATRIX(context), v, 0, OMATRIX(context));
  752.     SMATRIX(context);
  753. }
  754.  
  755. /*
  756. ** The following routine was ripped from the Mesa source code.
  757. ** I did use this because it is much better than my original design. The code
  758. ** is just modified a bit to adapt to my code layout, but otherwise is unmodified.
  759. ** This code is included with the kind permission of Brian Paul, the author of Mesa.
  760. */
  761. void GLRotatef(GLcontext context, GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
  762. {
  763.     float v[16];
  764.     #define v(x) v[OF_##x]
  765.     float mag, s, c;
  766.     float xx,yy,zz,xy,yz,zx,xs,ys,zs,one_c;
  767.  
  768.     //LOG(3, glRotatef, "%f %f %f %f", angle, x,y,z);
  769.  
  770.     GLASSERT(context != NULL);
  771.     GLFlagError(context, context->CurrentPrimitive != GL_BASE, GL_INVALID_OPERATION);
  772.     context->InvRotValid = GL_FALSE;
  773.     context->CombinedValid = GL_FALSE;
  774.  
  775.  
  776.     s = (float)sin(angle * PI/180.0);
  777.     c = (float)cos(angle * PI/180.0);
  778.     mag = sqrt(x*x+y*y+z*z);
  779.  
  780.     if (mag == 0.0) return;
  781.  
  782.     if (mag != 1.0)
  783.     {
  784.         x /= mag;
  785.         y /= mag;
  786.         z /= mag;
  787.     }
  788.  
  789.     xx = x*x;
  790.     yy = y*y;
  791.     zz = z*z;
  792.     xy = x*y;
  793.     yz = y*z;
  794.     zx = z*x;
  795.     xs = x*s;
  796.     ys = y*s;
  797.     zs = z*s;
  798.     one_c = 1.f - c;
  799.  
  800.     v(11) = one_c*xx + c;
  801.     v(12) = one_c*xy - zs;
  802.     v(13) = one_c*zx + ys;
  803.     v(14) = 0.f;
  804.  
  805.     v(21) = one_c*xy + zs;
  806.     v(22) = one_c*yy + c;
  807.     v(23) = one_c*yz - xs;
  808.     v(24) = 0.f;
  809.  
  810.     v(31) = one_c*zx - ys;
  811.     v(32) = one_c*yz + xs;
  812.     v(33) = one_c*zz + c;
  813.     v(34) = 0.f;
  814.  
  815.     v(41) = 0.f;
  816.     v(42) = 0.f;
  817.     v(43) = 0.f;
  818.     v(44) = 1.f;
  819.  
  820.     m_Mult(CMATRIX(context), v, MGLMAT_ROTATION, OMATRIX(context));
  821.     SMATRIX(context);
  822.     #undef v
  823. }
  824.  
  825. void GLRotated(GLcontext context, GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
  826. {
  827.     GLRotatef(context, (GLfloat)angle, (GLfloat)x, (GLfloat)y, (GLfloat)z);
  828. }
  829.  
  830. void GLScaled(GLcontext context, GLdouble x, GLdouble y, GLdouble z)
  831. {
  832.     float v[16];
  833.     //LOG(3, glScaled, "%lf %lf %lf", x,y,z);
  834.     GLASSERT(context!=NULL);
  835.     context->InvRotValid = GL_FALSE;
  836.     context->CombinedValid = GL_FALSE;
  837.     #define v(x) v[OF_##x]
  838.     v(11) = (float)x;   v(12) = 0.0; v(13) = 0.0; v(14) = 0.0;
  839.     v(21) = 0.0; v(22) = (float)y;   v(23) = 0.0; v(24) = 0.0;
  840.     v(31) = 0.0; v(32) = 0.0; v(33) = (float)z;   v(34) = 0.0;
  841.     v(41) = 0.0; v(42) = 0.0; v(43) = 0.0; v(44) = 1.0;
  842.  
  843.     m_Mult(CMATRIX(context), v, MGLMAT_GENERAL_SCALE, OMATRIX(context));
  844.     SMATRIX(context);
  845.     #undef v
  846. }
  847.  
  848. void GLScalef(GLcontext context, GLfloat x, GLfloat y, GLfloat z)
  849. {
  850.     float v[16];
  851.     //LOG(3, glScalef, "%f %f %f", x,y,z);
  852.     GLASSERT(context!=NULL);
  853.     context->InvRotValid = GL_FALSE;
  854.     context->CombinedValid = GL_FALSE;
  855.     #define v(x) v[OF_##x]
  856.     v(11) = x;   v(12) = 0.0; v(13) = 0.0; v(14) = 0.0;
  857.     v(21) = 0.0; v(22) = y;   v(23) = 0.0; v(24) = 0.0;
  858.     v(31) = 0.0; v(32) = 0.0; v(33) = z;   v(34) = 0.0;
  859.     v(41) = 0.0; v(42) = 0.0; v(43) = 0.0; v(44) = 1.0;
  860.     m_Mult(CMATRIX(context), v, MGLMAT_GENERAL_SCALE, OMATRIX(context));
  861.     SMATRIX(context);
  862.     #undef v
  863. }
  864.  
  865. void GLTranslated(GLcontext context, GLdouble x, GLdouble y, GLdouble z)
  866. {
  867.     float v[16];
  868.  
  869.     //LOG(3, glTranslated, "%lf %lf %lf", x,y,z);
  870.  
  871.     GLASSERT(context != NULL);
  872.     context->InvRotValid = GL_FALSE;
  873.     context->CombinedValid = GL_FALSE;
  874.  
  875.     #define v(x) v[OF_##x]
  876.     v(11) = v(22) = v(33) = v(44) = 1.f;
  877.     v(21) = v(31) = v(41) = v(12) = v(32) = v(42) = v(13) = v(23) = v(43) = 0.f;
  878.     v(14) = (float)x; v(24) = (float)y; v(34) = (float)z;
  879.  
  880.     m_Mult(CMATRIX(context), v, MGLMAT_TRANSLATION, OMATRIX(context));
  881.     SMATRIX(context);
  882.     #undef v
  883. }
  884.  
  885. void GLTranslatef(GLcontext context, GLfloat x, GLfloat y, GLfloat z)
  886. {
  887.     float vv[16];
  888.     //LOG(3, glTranslatef, "%f %f %f", x,y,z);
  889.  
  890.     GLASSERT(context != NULL);
  891.     context->InvRotValid = GL_FALSE;
  892.     context->CombinedValid = GL_FALSE;
  893.  
  894.     #define v(x) vv[OF_##x]
  895.     v(11) = v(22) = v(33) = v(44) = 1.f;
  896.     v(21) = v(31) = v(41) = v(12) = v(32) = v(42) = v(13) = v(23) = v(43) = 0.f;
  897.     v(14) = (float)x; v(24) = (float)y; v(34) = (float)z;
  898.     #undef v
  899.     m_Mult(CMATRIX(context), vv, MGLMAT_TRANSLATION, OMATRIX(context));
  900.     SMATRIX(context);
  901. }
  902.  
  903. void GLMatrixInit(GLcontext context)
  904. {
  905.     context->ModelViewStackPointer = 0;
  906.     context->ProjectionStackPointer = 0;
  907.     context->ModelViewNr = 0;
  908.     context->ProjectionNr = 0;
  909.     context->CombinedValid = GL_FALSE;
  910.     context->InvRotValid = GL_FALSE;
  911.     GLMatrixMode(context, GL_PROJECTION);
  912.     GLLoadIdentity(context);
  913.     GLMatrixMode(context, GL_MODELVIEW);
  914.     GLLoadIdentity(context);
  915.  
  916. }
  917.  
  918.