diff --git a/examples/opengl/src/openglexample.d b/examples/opengl/src/openglexample.d index db1ee0ed..650ed695 100644 --- a/examples/opengl/src/openglexample.d +++ b/examples/opengl/src/openglexample.d @@ -248,28 +248,32 @@ static if (ENABLE_OPENGL) { checkgl!glDisable(GL_CULL_FACE); checkgl!glDisable(GL_DEPTH_TEST); - import gl3n.linalg; - glSupport.setPerspectiveProjection(windowRect, rc, 90.0f, 0.5f, 100.0f); - mat4 projectionMatrix = mat4.perspective(rc.width, rc.height, 90.0f, 0.5f, 100.0f); - mat4 viewMatrix = mat4.look_at(vec3(10, 10, 0), vec3(0, 0, 0), vec3(1, -1, 0));//translation(0.0f, 0.0f, 4.0f).rotatez(angle); + //import gl3n.linalg; + glSupport.setPerspectiveProjection(windowRect, rc, 45.0f, 0.5f, 100.0f); + //mat4 projectionMatrix = glSupport.projectionMatrix; //mat4.perspective(rc.width, rc.height, 90.0f, 0.5f, 100.0f); + mat4 projectionMatrix; + float aspectRatio = cast(float)rc.width / cast(float)rc.height; + projectionMatrix.setPerspective(45.0f, aspectRatio, 0.5f, 100.0f); + mat4 viewMatrix = 1.0f; + viewMatrix.lookAt(vec3(10, 10, 0), vec3(0, 0, 0), vec3(1, -1, 0));//translation(0.0f, 0.0f, 4.0f).rotatez(angle); mat4 modelMatrix = mat4.identity; mat4 m = projectionMatrix * viewMatrix * modelMatrix; - float[16] matrix; - for (int y = 0; y < 4; y++) - for (int x = 0; x < 4; x++) - matrix[y * 4 + x] = m[x][y]; + //float[16] matrix; + //for (int y = 0; y < 4; y++) + // for (int x = 0; x < 4; x++) + // matrix[y * 4 + x] = m[x][y]; //matrix[x * 4 + y] = m[y][x]; Log.d("projectionViewModelMatrix qt: ", glSupport.projectionMatrix); - Log.d("projectionViewModelMatrix: ", matrix); - Log.d("(-1,-1,-1) * matrix: ", m * vec4(-1, -1, -1, 1)); - Log.d("(1,1,1) * matrix: ", m * vec4(1, 1, 1, 1)); - Log.d("(0,1,0) * matrix: ", m * vec4(0, 1, 0, 1)); - Log.d("(1,0,0) * matrix: ", m * vec4(1, 0, 0, 1)); - Log.d("(0,0,0) * matrix: ", m * vec4(0, 0, 0, 1)); + Log.d("projectionViewModelMatrix: ", cast(float[16])m.m); + //Log.d("(-1,-1,-1) * matrix: ", m * vec4(-1, -1, -1, 1)); + //Log.d("(1,1,1) * matrix: ", m * vec4(1, 1, 1, 1)); + //Log.d("(0,1,0) * matrix: ", m * vec4(0, 1, 0, 1)); + //Log.d("(1,0,0) * matrix: ", m * vec4(1, 0, 0, 1)); + //Log.d("(0,0,0) * matrix: ", m * vec4(0, 0, 0, 1)); - _program.execute(vertices, colors, texcoords, _tx.texture, true, matrix); + _program.execute(vertices, colors, texcoords, _tx.texture, true, m); } /// returns true is widget is being animated - need to call animate() and redraw @property override bool animating() { return true; } diff --git a/src/dlangui/core/math3d.d b/src/dlangui/core/math3d.d index bbc7415f..27262779 100644 --- a/src/dlangui/core/math3d.d +++ b/src/dlangui/core/math3d.d @@ -108,7 +108,7 @@ struct vec3 { /// add value to all components of vector vec3 opBinary(string op : "+")(float v) const { - vec3 res; + vec3 res = this; res.vec[0] += v; res.vec[1] += v; res.vec[2] += v; @@ -116,7 +116,7 @@ struct vec3 { } /// multiply all components of vector by value vec3 opBinary(string op : "*")(float v) const { - vec3 res; + vec3 res = this; res.vec[0] *= v; res.vec[1] *= v; res.vec[2] *= v; @@ -124,7 +124,7 @@ struct vec3 { } /// subtract value from all components of vector vec3 opBinary(string op : "-")(float v) const { - vec3 res; + vec3 res = this; res.vec[0] -= v; res.vec[1] -= v; res.vec[2] -= v; @@ -132,7 +132,7 @@ struct vec3 { } /// divide all components of vector by value vec3 opBinary(string op : "/")(float v) const { - vec3 res; + vec3 res = this; res.vec[0] /= v; res.vec[1] /= v; res.vec[2] /= v; @@ -201,7 +201,7 @@ struct vec3 { /// add value to all components of vector vec3 opBinary(string op : "+")(const vec3 v) const { - vec3 res; + vec3 res = this; res.vec[0] += v.vec[0]; res.vec[1] += v.vec[1]; res.vec[2] += v.vec[2]; @@ -209,7 +209,7 @@ struct vec3 { } /// subtract value from all components of vector vec3 opBinary(string op : "-")(const vec3 v) const { - vec3 res; + vec3 res = this; res.vec[0] -= v.vec[0]; res.vec[1] -= v.vec[1]; res.vec[2] -= v.vec[2]; @@ -228,6 +228,16 @@ struct vec3 { return res; } + /// returns vector with all components which are negative of components for this vector + vec3 opUnary(string op : "-")() const { + vec3 ret = this; + ret[0] = vec[0]; + ret[1] = vec[1]; + ret[2] = vec[2]; + return ret; + } + + /// sum of squares of all vector components @property float magnitudeSquared() { return vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]; @@ -252,6 +262,12 @@ struct vec3 { return res; } + /// cross product + static vec3 crossProduct(const vec3 v1, const vec3 v2) { + return vec3(v1.y * v2.z - v1.z * v2.y, + v1.z * v2.x - v1.x * v2.z, + v1.x * v2.y - v1.y * v2.x); + } } /// 4 component vector @@ -380,7 +396,7 @@ struct vec4 { /// add value to all components of vector vec4 opBinary(string op : "+")(float v) const { - vec4 res; + vec4 res = this; res.vec[0] += v; res.vec[1] += v; res.vec[2] += v; @@ -389,7 +405,7 @@ struct vec4 { } /// multiply all components of vector by value vec4 opBinary(string op : "*")(float v) const { - vec4 res; + vec4 res = this; res.vec[0] *= v; res.vec[1] *= v; res.vec[2] *= v; @@ -398,7 +414,7 @@ struct vec4 { } /// subtract value from all components of vector vec4 opBinary(string op : "-")(float v) const { - vec4 res; + vec4 res = this; res.vec[0] -= v; res.vec[1] -= v; res.vec[2] -= v; @@ -407,7 +423,7 @@ struct vec4 { } /// divide all components of vector by value vec4 opBinary(string op : "/")(float v) const { - vec4 res; + vec4 res = this; res.vec[0] /= v; res.vec[1] /= v; res.vec[2] /= v; @@ -485,7 +501,7 @@ struct vec4 { /// add value to all components of vector vec4 opBinary(string op : "+")(const vec4 v) const { - vec4 res; + vec4 res = this; res.vec[0] += v.vec[0]; res.vec[1] += v.vec[1]; res.vec[2] += v.vec[2]; @@ -494,7 +510,7 @@ struct vec4 { } /// subtract value from all components of vector vec4 opBinary(string op : "-")(const vec4 v) const { - vec4 res; + vec4 res = this; res.vec[0] -= v.vec[0]; res.vec[1] -= v.vec[1]; res.vec[2] -= v.vec[2]; @@ -515,6 +531,18 @@ struct vec4 { return res; } + /// returns vector with all components which are negative of components for this vector + vec4 opUnary(string op : "-")() const { + vec4 ret = this; + ret[0] = vec[0]; + ret[1] = vec[1]; + ret[2] = vec[2]; + ret[3] = vec[3]; + return ret; + } + + + /// sum of squares of all vector components @property float magnitudeSquared() { return vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2] + vec[3]*vec[3]; @@ -547,6 +575,10 @@ struct mat4 { alias m this; + this(float v) { + setDiagonal(v); + } + this(const ref mat4 v) { m[0..15] = v.m[0..15]; } @@ -558,6 +590,10 @@ struct mat4 { m[0..15] = v.m[0..15]; return this; } + ref mat4 opAssign(const mat4 v) { + m[0..15] = v.m[0..15]; + return this; + } ref mat4 opAssign(const float[16] v) { m[0..15] = v[0..15]; return this; @@ -622,6 +658,130 @@ struct mat4 { m[3*4 + 3] = 0.0f; } + ref mat4 lookAt(const vec3 eye, const vec3 center, const vec3 up) { + vec3 forward = (center - eye).normalized(); + vec3 side = vec3.crossProduct(forward, up).normalized(); + vec3 upVector = vec3.crossProduct(side, forward); + + mat4 m; + m.setIdentity(); + m[0*4 + 0] = side.x; + m[1*4 + 0] = side.y; + m[2*4 + 0] = side.z; + m[3*4 + 0] = 0.0f; + m[0*4 + 1] = upVector.x; + m[1*4 + 1] = upVector.y; + m[2*4 + 1] = upVector.z; + m[3*4 + 1] = 0.0f; + m[0*4 + 2] = -forward.x; + m[1*4 + 2] = -forward.y; + m[2*4 + 2] = -forward.z; + m[3*4 + 2] = 0.0f; + m[0*4 + 3] = 0.0f; + m[1*4 + 3] = 0.0f; + m[2*4 + 3] = 0.0f; + m[3*4 + 3] = 1.0f; + + this *= m; + translate(-eye); + return this; + } + + ref mat4 setLookAt(const vec3 eye, const vec3 center, const vec3 up) { + setIdentity(); + lookAt(eye, center, up); + return this; + } + + ref mat4 translate(const vec3 v) { + m[3*4 + 0] += m[0*4 + 0] * v.x + m[1*4 + 0] * v.y + m[2*4 + 0] * v.z; + m[3*4 + 1] += m[0*4 + 1] * v.x + m[1*4 + 1] * v.y + m[2*4 + 1] * v.z; + m[3*4 + 2] += m[0*4 + 2] * v.x + m[1*4 + 2] * v.y + m[2*4 + 2] * v.z; + m[3*4 + 3] += m[0*4 + 3] * v.x + m[1*4 + 3] * v.y + m[2*4 + 3] * v.z; + return this; + } + + /// multiply this matrix by another matrix + mat4 opBinary(string op : "*")(const ref mat4 m2) const { + return mul(this, m2); + } + + /// multiply this matrix by another matrix + mat4 opOpAssign(string op : "*")(const ref mat4 m2) { + this = mul(this, m2); + return this; + } + + /// multiply two matrices + static mat4 mul(const ref mat4 m1, const ref mat4 m2) { + mat4 m; + m.m[0*4 + 0] = m1.m[0*4 + 0] * m2.m[0*4 + 0] + + m1.m[1*4 + 0] * m2.m[0*4 + 1] + + m1.m[2*4 + 0] * m2.m[0*4 + 2] + + m1.m[3*4 + 0] * m2.m[0*4 + 3]; + m.m[0*4 + 1] = m1.m[0*4 + 1] * m2.m[0*4 + 0] + + m1.m[1*4 + 1] * m2.m[0*4 + 1] + + m1.m[2*4 + 1] * m2.m[0*4 + 2] + + m1.m[3*4 + 1] * m2.m[0*4 + 3]; + m.m[0*4 + 2] = m1.m[0*4 + 2] * m2.m[0*4 + 0] + + m1.m[1*4 + 2] * m2.m[0*4 + 1] + + m1.m[2*4 + 2] * m2.m[0*4 + 2] + + m1.m[3*4 + 2] * m2.m[0*4 + 3]; + m.m[0*4 + 3] = m1.m[0*4 + 3] * m2.m[0*4 + 0] + + m1.m[1*4 + 3] * m2.m[0*4 + 1] + + m1.m[2*4 + 3] * m2.m[0*4 + 2] + + m1.m[3*4 + 3] * m2.m[0*4 + 3]; + m.m[1*4 + 0] = m1.m[0*4 + 0] * m2.m[1*4 + 0] + + m1.m[1*4 + 0] * m2.m[1*4 + 1] + + m1.m[2*4 + 0] * m2.m[1*4 + 2] + + m1.m[3*4 + 0] * m2.m[1*4 + 3]; + m.m[1*4 + 1] = m1.m[0*4 + 1] * m2.m[1*4 + 0] + + m1.m[1*4 + 1] * m2.m[1*4 + 1] + + m1.m[2*4 + 1] * m2.m[1*4 + 2] + + m1.m[3*4 + 1] * m2.m[1*4 + 3]; + m.m[1*4 + 2] = m1.m[0*4 + 2] * m2.m[1*4 + 0] + + m1.m[1*4 + 2] * m2.m[1*4 + 1] + + m1.m[2*4 + 2] * m2.m[1*4 + 2] + + m1.m[3*4 + 2] * m2.m[1*4 + 3]; + m.m[1*4 + 3] = m1.m[0*4 + 3] * m2.m[1*4 + 0] + + m1.m[1*4 + 3] * m2.m[1*4 + 1] + + m1.m[2*4 + 3] * m2.m[1*4 + 2] + + m1.m[3*4 + 3] * m2.m[1*4 + 3]; + m.m[2*4 + 0] = m1.m[0*4 + 0] * m2.m[2*4 + 0] + + m1.m[1*4 + 0] * m2.m[2*4 + 1] + + m1.m[2*4 + 0] * m2.m[2*4 + 2] + + m1.m[3*4 + 0] * m2.m[2*4 + 3]; + m.m[2*4 + 1] = m1.m[0*4 + 1] * m2.m[2*4 + 0] + + m1.m[1*4 + 1] * m2.m[2*4 + 1] + + m1.m[2*4 + 1] * m2.m[2*4 + 2] + + m1.m[3*4 + 1] * m2.m[2*4 + 3]; + m.m[2*4 + 2] = m1.m[0*4 + 2] * m2.m[2*4 + 0] + + m1.m[1*4 + 2] * m2.m[2*4 + 1] + + m1.m[2*4 + 2] * m2.m[2*4 + 2] + + m1.m[3*4 + 2] * m2.m[2*4 + 3]; + m.m[2*4 + 3] = m1.m[0*4 + 3] * m2.m[2*4 + 0] + + m1.m[1*4 + 3] * m2.m[2*4 + 1] + + m1.m[2*4 + 3] * m2.m[2*4 + 2] + + m1.m[3*4 + 3] * m2.m[2*4 + 3]; + m.m[3*4 + 0] = m1.m[0*4 + 0] * m2.m[3*4 + 0] + + m1.m[1*4 + 0] * m2.m[3*4 + 1] + + m1.m[2*4 + 0] * m2.m[3*4 + 2] + + m1.m[3*4 + 0] * m2.m[3*4 + 3]; + m.m[3*4 + 1] = m1.m[0*4 + 1] * m2.m[3*4 + 0] + + m1.m[1*4 + 1] * m2.m[3*4 + 1] + + m1.m[2*4 + 1] * m2.m[3*4 + 2] + + m1.m[3*4 + 1] * m2.m[3*4 + 3]; + m.m[3*4 + 2] = m1.m[0*4 + 2] * m2.m[3*4 + 0] + + m1.m[1*4 + 2] * m2.m[3*4 + 1] + + m1.m[2*4 + 2] * m2.m[3*4 + 2] + + m1.m[3*4 + 2] * m2.m[3*4 + 3]; + m.m[3*4 + 3] = m1.m[0*4 + 3] * m2.m[3*4 + 0] + + m1.m[1*4 + 3] * m2.m[3*4 + 1] + + m1.m[2*4 + 3] * m2.m[3*4 + 2] + + m1.m[3*4 + 3] * m2.m[3*4 + 3]; + return m; + } + /// 2d index by row, col ref float opIndex(int y, int x) { return m[y*4 + x]; @@ -642,31 +802,72 @@ struct mat4 { return m[index]; } - /// set to identity + /// set to identity: fill all items of matrix with zero except main diagonal items which will be assigned to 1.0f ref mat4 setIdentity() { + return setDiagonal(1.0f); + } + /// set to diagonal: fill all items of matrix with zero except main diagonal items which will be assigned to v + ref mat4 setDiagonal(float v) { for (int x = 0; x < 4; x++) { for (int y = 0; y < 4; y++) { if (x == y) - m[y * 4 + x] = 1.0f; + m[y * 4 + x] = v; else m[y * 4 + x] = 0.0f; } } return this; } + /// fill all items of matrix with specified value + ref mat4 fill(float v) { + foreach(ref f; m) + f = v; + return this; + } + /// fill all items of matrix with zero ref mat4 setZero() { foreach(ref f; m) f = 0.0f; return this; } + /// creates identity matrix static mat4 identity() { mat4 res; return res.setIdentity(); } + /// creates zero matrix static mat4 zero() { mat4 res; return res.setZero(); } + + + /// add value to all components of matrix + ref mat4 opOpAssign(string op : "+")(float v) { + foreach(ref item; m) + item += v; + return this; + } + /// multiply all components of matrix by value + ref mat4 opOpAssign(string op : "*")(float v) { + foreach(ref item; m) + item *= v; + return this; + } + /// subtract value from all components of matrix + ref mat4 opOpAssign(string op : "-")(float v) { + foreach(ref item; m) + item -= v; + return this; + } + /// divide all components of vector by matrix + ref mat4 opOpAssign(string op : "/")(float v) { + foreach(ref item; m) + item /= v; + return this; + } + + } @@ -725,4 +926,10 @@ unittest { float r; r = m[1, 3]; m[2, 1] = 0.0f; + m += 1; + m -= 2; + m *= 3; + m /= 3; + m.translate(vec3(2, 3, 4)); + m.setLookAt(vec3(5, 5, 5), vec3(0, 0, 0), vec3(-1, 1, 1)); }