1 /* 2 * Copyright Andrej Mitrovic 2013. 3 * Distributed under the Boost Software License, Version 1.0. 4 * (See accompanying file LICENSE_1_0.txt or copy at 5 * http://www.boost.org/LICENSE_1_0.txt) 6 */ 7 module demo.glu; 8 9 import core.memory; 10 11 import core.stdc.stdio; 12 import core.stdc.stdlib; 13 14 import std.exception; 15 import std.math; 16 import std.random; 17 import std.stdio; 18 import std.string; 19 20 alias stderr = std.stdio.stderr; 21 22 import glad.gl.all; 23 import glad.gl.loader; 24 25 /* 26 ** Make m an identity matrix 27 */ 28 void __gluMakeIdentityd(ref GLdouble[16] m) 29 { 30 m[0 + 4 * 0] = 1; 31 m[0 + 4 * 1] = 0; 32 m[0 + 4 * 2] = 0; 33 m[0 + 4 * 3] = 0; 34 m[1 + 4 * 0] = 0; 35 m[1 + 4 * 1] = 1; 36 m[1 + 4 * 2] = 0; 37 m[1 + 4 * 3] = 0; 38 m[2 + 4 * 0] = 0; 39 m[2 + 4 * 1] = 0; 40 m[2 + 4 * 2] = 1; 41 m[2 + 4 * 3] = 0; 42 m[3 + 4 * 0] = 0; 43 m[3 + 4 * 1] = 0; 44 m[3 + 4 * 2] = 0; 45 m[3 + 4 * 3] = 1; 46 } 47 48 /* 49 ** inverse = invert(src) 50 */ 51 int __gluInvertMatrixd(ref GLdouble[16] src, ref GLdouble[16] inverse) 52 { 53 int i, j, k, swap; 54 double t = 0; 55 GLdouble[4][4] temp = 0; 56 57 for (i = 0; i < 4; i++) 58 { 59 for (j = 0; j < 4; j++) 60 { 61 temp[i][j] = src[i * 4 + j]; 62 } 63 } 64 65 __gluMakeIdentityd(inverse); 66 67 for (i = 0; i < 4; i++) 68 { 69 /* 70 ** Look for largest element in column 71 */ 72 swap = i; 73 74 for (j = i + 1; j < 4; j++) 75 { 76 if (fabs(temp[j][i]) > fabs(temp[i][i])) 77 { 78 swap = j; 79 } 80 } 81 82 if (swap != i) 83 { 84 /* 85 ** Swap rows. 86 */ 87 for (k = 0; k < 4; k++) 88 { 89 t = temp[i][k]; 90 temp[i][k] = temp[swap][k]; 91 temp[swap][k] = t; 92 93 t = inverse[i * 4 + k]; 94 inverse[i * 4 + k] = inverse[swap * 4 + k]; 95 inverse[swap * 4 + k] = t; 96 } 97 } 98 99 if (temp[i][i] == 0) 100 { 101 /* 102 ** No non-zero pivot. The matrix is singular, which shouldn't 103 ** happen. This means the user gave us a bad matrix. 104 */ 105 return GL_FALSE; 106 } 107 108 t = temp[i][i]; 109 110 for (k = 0; k < 4; k++) 111 { 112 temp[i][k] /= t; 113 inverse[i * 4 + k] /= t; 114 } 115 116 for (j = 0; j < 4; j++) 117 { 118 if (j != i) 119 { 120 t = temp[j][i]; 121 122 for (k = 0; k < 4; k++) 123 { 124 temp[j][k] -= temp[i][k] * t; 125 inverse[j * 4 + k] -= inverse[i * 4 + k] * t; 126 } 127 } 128 } 129 } 130 131 return GL_TRUE; 132 } 133 134 void __gluMultMatricesd(ref GLdouble[16] a, ref GLdouble[16] b, ref GLdouble[16] r) 135 { 136 int i, j; 137 138 for (i = 0; i < 4; i++) 139 { 140 for (j = 0; j < 4; j++) 141 { 142 r[i * 4 + j] = 143 a[i * 4 + 0] * b[0 * 4 + j] + 144 a[i * 4 + 1] * b[1 * 4 + j] + 145 a[i * 4 + 2] * b[2 * 4 + j] + 146 a[i * 4 + 3] * b[3 * 4 + j]; 147 } 148 } 149 } 150 151 void __gluMultMatrixVecd(ref GLdouble[16] matrix, ref GLdouble[4] in_, ref GLdouble[4] out_) 152 { 153 int i; 154 155 for (i = 0; i < 4; i++) 156 { 157 out_[i] = 158 in_[0] * matrix[0 * 4 + i] + 159 in_[1] * matrix[1 * 4 + i] + 160 in_[2] * matrix[2 * 4 + i] + 161 in_[3] * matrix[3 * 4 + i]; 162 } 163 } 164 165 GLint gluUnProject(ref GLdouble winx, GLdouble winy, GLdouble winz, 166 ref GLdouble[16] modelMatrix, 167 ref GLdouble[16] projMatrix, 168 ref GLint[4] viewport, 169 GLdouble* objx, GLdouble* objy, GLdouble* objz) 170 { 171 double[16] finalMatrix = 0; 172 double[4] in_ = 0; 173 double[4] out_ = 0; 174 175 __gluMultMatricesd(modelMatrix, projMatrix, finalMatrix); 176 177 if (!__gluInvertMatrixd(finalMatrix, finalMatrix)) 178 return GL_FALSE; 179 180 in_[0] = winx; 181 in_[1] = winy; 182 in_[2] = winz; 183 in_[3] = 1.0; 184 185 /* Map x and y from window coordinates */ 186 in_[0] = (in_[0] - viewport[0]) / viewport[2]; 187 in_[1] = (in_[1] - viewport[1]) / viewport[3]; 188 189 /* Map to range -1 to 1 */ 190 in_[0] = in_[0] * 2 - 1; 191 in_[1] = in_[1] * 2 - 1; 192 in_[2] = in_[2] * 2 - 1; 193 194 __gluMultMatrixVecd(finalMatrix, in_, out_); 195 196 if (out_[3] == 0.0) 197 return GL_FALSE; 198 199 out_[0] /= out_[3]; 200 out_[1] /= out_[3]; 201 out_[2] /= out_[3]; 202 *objx = out_[0]; 203 *objy = out_[1]; 204 *objz = out_[2]; 205 206 return GL_TRUE; 207 } 208 209 void gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top) 210 { 211 glOrtho(left, right, bottom, top, -1, 1); 212 }