Clone of mesa.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

matrix.c 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. * matrix.c
  3. *
  4. * Some useful matrix functions.
  5. *
  6. * Brian Paul
  7. * 10 Feb 2004
  8. */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <math.h>
  12. /**
  13. * Pretty-print the given matrix.
  14. */
  15. void
  16. PrintMatrix(const float p[16])
  17. {
  18. printf("[ %6.3f %6.3f %6.3f %6.3f ]\n", p[0], p[4], p[8], p[12]);
  19. printf("[ %6.3f %6.3f %6.3f %6.3f ]\n", p[1], p[5], p[9], p[13]);
  20. printf("[ %6.3f %6.3f %6.3f %6.3f ]\n", p[2], p[6], p[10], p[14]);
  21. printf("[ %6.3f %6.3f %6.3f %6.3f ]\n", p[3], p[7], p[11], p[15]);
  22. }
  23. /**
  24. * Build a glFrustum matrix.
  25. */
  26. void
  27. Frustum(float left, float right, float bottom, float top, float nearZ, float farZ, float *m)
  28. {
  29. float x = (2.0F*nearZ) / (right-left);
  30. float y = (2.0F*nearZ) / (top-bottom);
  31. float a = (right+left) / (right-left);
  32. float b = (top+bottom) / (top-bottom);
  33. float c = -(farZ+nearZ) / ( farZ-nearZ);
  34. float d = -(2.0F*farZ*nearZ) / (farZ-nearZ);
  35. #define M(row,col) m[col*4+row]
  36. M(0,0) = x; M(0,1) = 0.0F; M(0,2) = a; M(0,3) = 0.0F;
  37. M(1,0) = 0.0F; M(1,1) = y; M(1,2) = b; M(1,3) = 0.0F;
  38. M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = c; M(2,3) = d;
  39. M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = -1.0F; M(3,3) = 0.0F;
  40. #undef M
  41. }
  42. /**
  43. * Build a glOrtho marix.
  44. */
  45. void
  46. Ortho(float left, float right, float bottom, float top, float nearZ, float farZ, float *m)
  47. {
  48. #define M(row,col) m[col*4+row]
  49. M(0,0) = 2.0F / (right-left);
  50. M(0,1) = 0.0F;
  51. M(0,2) = 0.0F;
  52. M(0,3) = -(right+left) / (right-left);
  53. M(1,0) = 0.0F;
  54. M(1,1) = 2.0F / (top-bottom);
  55. M(1,2) = 0.0F;
  56. M(1,3) = -(top+bottom) / (top-bottom);
  57. M(2,0) = 0.0F;
  58. M(2,1) = 0.0F;
  59. M(2,2) = -2.0F / (farZ-nearZ);
  60. M(2,3) = -(farZ+nearZ) / (farZ-nearZ);
  61. M(3,0) = 0.0F;
  62. M(3,1) = 0.0F;
  63. M(3,2) = 0.0F;
  64. M(3,3) = 1.0F;
  65. #undef M
  66. }
  67. /**
  68. * Decompose a projection matrix to determine original glFrustum or
  69. * glOrtho parameters.
  70. */
  71. void
  72. DecomposeProjection( const float *m,
  73. int *isPerspective,
  74. float *leftOut, float *rightOut,
  75. float *botOut, float *topOut,
  76. float *nearOut, float *farOut)
  77. {
  78. if (m[15] == 0.0) {
  79. /* perspective */
  80. float p[16];
  81. const float x = m[0]; /* 2N / (R-L) */
  82. const float y = m[5]; /* 2N / (T-B) */
  83. const float a = m[8]; /* (R+L) / (R-L) */
  84. const float b = m[9]; /* (T+B) / (T-B) */
  85. const float c = m[10]; /* -(F+N) / (F-N) */
  86. const float d = m[14]; /* -2FN / (F-N) */
  87. /* These equations found with simple algebra, knowing the arithmetic
  88. * use to set up a typical perspective projection matrix in OpenGL.
  89. */
  90. const float nearZ = -d / (1.0 - c);
  91. const float farZ = (c - 1.0) * nearZ / (c + 1.0);
  92. const float left = nearZ * (a - 1.0) / x;
  93. const float right = 2.0 * nearZ / x + left;
  94. const float bottom = nearZ * (b - 1.0) / y;
  95. const float top = 2.0 * nearZ / y + bottom;
  96. *isPerspective = 1;
  97. *leftOut = left;
  98. *rightOut = right;
  99. *botOut = bottom;
  100. *topOut = top;
  101. *nearOut = nearZ;
  102. *farOut = farZ;
  103. }
  104. else {
  105. /* orthographic */
  106. const float x = m[0]; /* 2 / (R-L) */
  107. const float y = m[5]; /* 2 / (T-B) */
  108. const float z = m[10]; /* -2 / (F-N) */
  109. const float a = m[12]; /* -(R+L) / (R-L) */
  110. const float b = m[13]; /* -(T+B) / (T-B) */
  111. const float c = m[14]; /* -(F+N) / (F-N) */
  112. /* again, simple algebra */
  113. const float right = -(a - 1.0) / x;
  114. const float left = right - 2.0 / x;
  115. const float top = -(b - 1.0) / y;
  116. const float bottom = top - 2.0 / y;
  117. const float farZ = (c - 1.0) / z;
  118. const float nearZ = farZ + 2.0 / z;
  119. *isPerspective = 0;
  120. *leftOut = left;
  121. *rightOut = right;
  122. *botOut = bottom;
  123. *topOut = top;
  124. *nearOut = nearZ;
  125. *farOut = farZ;
  126. }
  127. }
  128. #if 0
  129. /* test harness */
  130. int
  131. main(int argc, char *argv[])
  132. {
  133. float m[16], p[16];
  134. float l, r, b, t, n, f;
  135. int persp;
  136. int i;
  137. #if 0
  138. l = -.9;
  139. r = 1.2;
  140. b = -0.5;
  141. t = 1.4;
  142. n = 30;
  143. f = 84;
  144. printf(" Frustum(%f, %f, %f, %f, %f, %f\n",l+1, r+1.2, b+.5, t+.3, n, f);
  145. Frustum(l+1, r+1.2, b+.5, t+.3, n, f, p);
  146. DecomposeProjection(p, &persp, &l, &r, &b, &t, &n, &f);
  147. printf("glFrustum(%f, %f, %f, %f, %f, %f)\n",
  148. l, r, b, t, n, f);
  149. PrintMatrix(p);
  150. #else
  151. printf("Ortho(-1, 1, -1, 1, 10, 84)\n");
  152. Ortho(-1, 1, -1, 1, 10, 84, m);
  153. PrintMatrix(m);
  154. DecomposeProjection(m, &persp, &l, &r, &b, &t, &n, &f);
  155. printf("Ortho(%f, %f, %f, %f, %f, %f) %d\n", l, r, b, t, n, f, persp);
  156. #endif
  157. return 0;
  158. }
  159. #endif