/// <summary> /// 把连续16个float值按照列优先的顺序转换为mat4 /// </summary> /// <param name="values"></param> /// <param name="startIndex"></param> /// <returns></returns> public static mat4 ToMat4(this float[] values, int startIndex = 0) { mat4 result; result = new mat4( values.ToVec4(startIndex + 0), values.ToVec4(startIndex + 4), values.ToVec4(startIndex + 8), values.ToVec4(startIndex + 12)); return result; }
void element_BeforeRendering(object sender, Objects.RenderEventArgs e) { rotation += 3.0f; modelMatrix = glm.rotate(rotation, new vec3(0, 1, 0)); viewMatrix = this.camera.GetViewMat4(); projectionMatrix = this.camera.GetProjectionMat4(); mat4 mvp = projectionMatrix * viewMatrix * modelMatrix; IMVP element = sender as IMVP; element.SetShaderProgram(mvp); }
void pyramidElement_BeforeRendering(object sender, Objects.RenderEventArgs e) { rotation += 3.0f; mat4 modelMatrix = glm.rotate(rotation, new vec3(0, 1, 0)); const float distance = 0.7f; viewMatrix = glm.lookAt(new vec3(-distance, distance, -distance), new vec3(0, 0, 0), new vec3(0, -1, 0)); int[] viewport = new int[4]; GL.GetInteger(GetTarget.Viewport, viewport); projectionMatrix = glm.perspective(60.0f, (float)viewport[2] / (float)viewport[3], 0.01f, 100.0f); mat4 mvp = projectionMatrix * viewMatrix * modelMatrix; IMVP element = sender as IMVP; element.SetShaderProgram(mvp); }
/// <summary> /// Define a picking region. /// </summary> /// <param name="center">The center.</param> /// <param name="delta">The delta.</param> /// <param name="viewport">The viewport.</param> /// <returns></returns> /// <exception cref="System.ArgumentOutOfRangeException"></exception> public static mat4 pickMatrix(vec2 center, vec2 delta, vec4 viewport) { if (delta.x <= 0 || delta.y <= 0) { throw new ArgumentOutOfRangeException(); } var Result = new mat4(1.0f); if (!(delta.x > (0f) && delta.y > (0f))) { return(Result); // Error } vec3 Temp = new vec3( ((viewport[2]) - (2f) * (center.x - (viewport[0]))) / delta.x, ((viewport[3]) - (2f) * (center.y - (viewport[1]))) / delta.y, (0f)); // Translate and scale the picked region to the entire window Result = translate(Result, Temp); return(scale(Result, new vec3((viewport[2]) / delta.x, (viewport[3]) / delta.y, (1)))); }
/// <summary> /// Builds a perspective projection matrix based on a field of view. /// </summary> /// <param name="fov">The fov (in radians).</param> /// <param name="width">The width.</param> /// <param name="height">The height.</param> /// <param name="zNear">The z near.</param> /// <param name="zFar">The z far.</param> /// <returns></returns> /// <exception cref="System.ArgumentOutOfRangeException"></exception> public static mat4 perspectiveFov(float fov, float width, float height, float zNear, float zFar) { if (width <= 0 || height <= 0 || fov <= 0) { throw new ArgumentOutOfRangeException(); } var rad = fov; var h = glm.cos((0.5f) * rad) / glm.sin((0.5f) * rad); var w = h * height / width; var result = new mat4(0); result[0, 0] = w; result[1, 1] = h; result[2, 2] = -(zFar + zNear) / (zFar - zNear); result[2, 3] = -(1f); result[3, 2] = -((2f) * zFar * zNear) / (zFar - zNear); return(result); }
/// <summary> /// Build a look at view matrix. /// </summary> /// <param name="eye">The eye.</param> /// <param name="center">The center.</param> /// <param name="up">Up.</param> /// <returns></returns> public static mat4 lookAt(vec3 eye, vec3 center, vec3 up) { vec3 f = normalize(center - eye); vec3 s = normalize(cross(f, up)); vec3 u = cross(s, f); mat4 Result = new mat4(1); Result[0, 0] = s.x; Result[1, 0] = s.y; Result[2, 0] = s.z; Result[0, 1] = u.x; Result[1, 1] = u.y; Result[2, 1] = u.z; Result[0, 2] = -f.x; Result[1, 2] = -f.y; Result[2, 2] = -f.z; Result[3, 0] = -dot(s, eye); Result[3, 1] = -dot(u, eye); Result[3, 2] = dot(f, eye); return(Result); }
void IMVP.SetShaderProgram(mat4 mvp) { IMVP element = this.axisElement as IMVP; element.SetShaderProgram(mvp); }
void IMVP.SetShaderProgram(mat4 mvp) { IMVPHelper.DoUpdateMVP(this, mvp); }
//void IRenderable.Render(RenderModes renderMode) //{ // base.Render(renderMode); //} void IMVP.SetShaderProgram(mat4 mvp) { ShaderProgram shaderProgram = this.currentShaderProgram; shaderProgram.Bind(); if (shaderProgram == this.pickingShaderProgram) { shaderProgram.SetUniform("pickingBaseID", ((IColorCodedPicking)this).PickingBaseID); shaderProgram.SetUniformMatrix4(strMVP, mvp.to_array()); } else { shaderProgram.SetUniformMatrix4(strMVP, mvp.to_array()); } }
void IMVP.SetShaderProgram(mat4 mvp) { GL.Enable(GL.GL_VERTEX_PROGRAM_POINT_SIZE); GL.Enable(GL.GL_POINT_SPRITE_ARB); //GL.TexEnv(GL.GL_POINT_SPRITE_ARB, GL.GL_COORD_REPLACE_ARB, GL.GL_TRUE);//TODO: test TexEnvi() GL.TexEnvf(GL.GL_POINT_SPRITE_ARB, GL.GL_COORD_REPLACE_ARB, GL.GL_TRUE); GL.Enable(GL.GL_POINT_SMOOTH); GL.Hint(GL.GL_POINT_SMOOTH_HINT, GL.GL_NICEST); GL.Enable(GL.GL_BLEND); GL.BlendEquation(GL.GL_FUNC_ADD_EXT); GL.BlendFuncSeparate(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA, GL.GL_ONE, GL.GL_ONE); GL.BindTexture(GL.GL_TEXTURE_2D, this.texture[0]); IMVPHelper.DoUpdateMVP(this, mvp); //int[] poinSizes = new int[2]; //GL.GetInteger(GetTarget.PointSizeRange, poinSizes); //if (this.textureWidth > poinSizes[1]) //{ // GL.PointParameter(GL.GL_POINT_SIZE_MAX_ARB, this.textureWidth); // GL.GetInteger(GetTarget.PointSizeRange, poinSizes); // Console.WriteLine("asf"); //} shaderProgram.SetUniform(PointSpriteStringElement.strpointSize, this.textureWidth + 0.0f); shaderProgram.SetUniform(PointSpriteStringElement.strtex, this.texture[0]); shaderProgram.SetUniform(PointSpriteStringElement.strtextColor, this.textColor.x, this.textColor.y, this.textColor.z); }
/// <summary> /// 如果此矩阵是glm.perspective()的结果,那么返回glm.perspective()的各个参数值。 /// </summary> /// <param name="matrix"></param> /// <param name="fovy"></param> /// <param name="aspectRatio"></param> /// <param name="zNear"></param> /// <param name="zFar"></param> /// <returns></returns> public static bool TryParse(this mat4 matrix, out float fovy, out float aspectRatio, out float zNear, out float zFar) { /* * var result = mat4.identity(); * float tangent = (float)Math.Tan(fovy / 2.0f); * float height = zNear * tangent; * float width = height * aspect; * float l = -width, r = width, b = -height, t = height, n = zNear, f = zFar; * result[0, 0] = 2 * n / (r - l);// = 2 * zNear / (2 * zNear * tangent * aspect) * result[1, 1] = 2 * n / (t - b);// = 2 * zNear / (2 * zNear * tangent) * result[2, 0] = (r + l) / (r - l);// = 0 * result[2, 1] = (t + b) / (t - b);// = 0 * result[2, 2] = -(f + n) / (f - n); * result[2, 3] = -1; * result[3, 2] = -(2 * f * n) / (f - n); * result[3, 3] = 0; */ float tanHalfFovy = 1.0f / matrix[1, 1]; fovy = 2 * (float)(Math.Atan(tanHalfFovy)); if (fovy < 0) { fovy = -fovy; } //aspectRatio = 1.0f / matrix[0, 0] / tanHalfFovy; aspectRatio = matrix[1, 1] / matrix[0, 0]; if (matrix[2, 2] == 1.0f) { zFar = 0.0f; zNear = 0.0f; } else if (matrix[2, 2] == -1.0f) { zNear = 0.0f; zFar = float.PositiveInfinity; } else { zNear = matrix[3, 2] / (matrix[2, 2] - 1); zFar = matrix[3, 2] / (matrix[2, 2] + 1); } if (matrix[0, 0] == 0.0f || matrix[1, 1] == 0.0f || matrix[2, 2] == 0.0f) { return(false); } if (matrix[1, 0] != 0.0f || matrix[3, 0] != 0.0f || matrix[0, 1] != 0.0f || matrix[3, 1] != 0.0f || matrix[0, 2] != 0.0f || matrix[1, 2] != 0.0f || matrix[0, 3] != 0.0f || matrix[1, 3] != 0.0f || matrix[3, 3] != 0.0f) { return(false); } if (matrix[2, 3] != -1.0f) { return(false); } return(true); }
public static void TypicalScene() { const int count = 1000000; long startTick = 0; long interval, interval2; // 测试float类型 { var floatArray = new UnmanagedArray<float>(count); startTick = DateTime.Now.Ticks; for (int i = 0; i < count; i++) { floatArray[i] = i; } for (int i = 0; i < count; i++) { var item = floatArray[i]; if (item != i) { throw new Exception(); } } interval = DateTime.Now.Ticks - startTick; unsafe { startTick = DateTime.Now.Ticks; float* header = (float*)floatArray.FirstElement(); float* last = (float*)floatArray.LastElement(); float* tailAddress = (float*)floatArray.TailAddress(); int value = 0; for (float* ptr = header; ptr <= last/*or: ptr < tailAddress*/; ptr++) { *ptr = value++; } int i = 0; for (float* ptr = header; ptr <= last/*or: ptr < tailAddress*/; ptr++, i++) { var item = *ptr; if (item != i) { throw new Exception(); } } interval2 = DateTime.Now.Ticks - startTick; } Console.WriteLine("Ticks: safe: {0} vs unsafe: {1}", interval, interval2); } // 测试decimal类型 { var decimalArray = new UnmanagedArray<decimal>(count); startTick = DateTime.Now.Ticks; for (int i = 0; i < count; i++) { decimalArray[i] = i; } for (int i = 0; i < count; i++) { var item = decimalArray[i]; if (item != i) { throw new Exception(); } } interval = DateTime.Now.Ticks - startTick; unsafe { startTick = DateTime.Now.Ticks; decimal* header = (decimal*)decimalArray.FirstElement(); decimal* last = (decimal*)decimalArray.LastElement(); decimal* tailAddress = (decimal*)decimalArray.TailAddress(); int value = 0; for (decimal* ptr = header; ptr <= last/*or: ptr < tailAddress*/; ptr++) { *ptr = value++; } int i = 0; for (decimal* ptr = header; ptr <= last/*or: ptr < tailAddress*/; ptr++, i++) { var item = *ptr; if (item != i) { throw new Exception(); } } interval2 = DateTime.Now.Ticks - startTick; } Console.WriteLine("Ticks: safe: {0} vs unsafe: {1}", interval, interval2); } // 测试int类型 { var intArray = new UnmanagedArray<int>(count); startTick = DateTime.Now.Ticks; for (int i = 0; i < count; i++) { intArray[i] = i; } for (int i = 0; i < count; i++) { var item = intArray[i]; if (item != i) { throw new Exception(); } } interval = DateTime.Now.Ticks - startTick; unsafe { startTick = DateTime.Now.Ticks; int* header = (int*)intArray.FirstElement(); int* last = (int*)intArray.LastElement(); int* tailAddress = (int*)intArray.TailAddress(); int value = 0; for (int* ptr = header; ptr <= last/*or: ptr < tailAddress*/; ptr++) { *ptr = value++; } int i = 0; for (int* ptr = header; ptr <= last/*or: ptr < tailAddress*/; ptr++, i++) { var item = *ptr; if (item != i) { throw new Exception(); } } interval2 = DateTime.Now.Ticks - startTick; } Console.WriteLine("Ticks: safe: {0} vs unsafe: {1}", interval, interval2); } // 测试bool类型 { var boolArray = new UnmanagedArray<bool>(count); startTick = DateTime.Now.Ticks; for (int i = 0; i < count; i++) { boolArray[i] = i % 2 == 0; } for (int i = 0; i < count; i++) { var item = boolArray[i]; if (item != (i % 2 == 0)) { throw new Exception(); } } interval = DateTime.Now.Ticks - startTick; unsafe { startTick = DateTime.Now.Ticks; bool* header = (bool*)boolArray.FirstElement(); bool* last = (bool*)boolArray.LastElement(); bool* tailAddress = (bool*)boolArray.TailAddress(); int value = 0; for (bool* ptr = header; ptr <= last/*or: ptr < tailAddress*/; ptr++) { *ptr = (value % 2 == 0); value++; } int i = 0; for (bool* ptr = header; ptr <= last/*or: ptr < tailAddress*/; ptr++, i++) { var item = *ptr; if (item != (i % 2 == 0)) { throw new Exception(); } } interval2 = DateTime.Now.Ticks - startTick; } Console.WriteLine("Ticks: safe: {0} vs unsafe: {1}", interval, interval2); } // 测试vec3类型 { var vec3Array = new UnmanagedArray<vec3>(count); startTick = DateTime.Now.Ticks; for (int i = 0; i < count; i++) { vec3Array[i] = new vec3(i * 3 + 0, i * 3 + 1, i * 3 + 2); } for (int i = 0; i < count; i++) { var item = vec3Array[i]; var old = new vec3(i * 3 + 0, i * 3 + 1, i * 3 + 2); if (item.x != old.x || item.y != old.y || item.z != old.z) { throw new Exception(); } } interval = DateTime.Now.Ticks - startTick; unsafe { startTick = DateTime.Now.Ticks; vec3* header = (vec3*)vec3Array.FirstElement(); vec3* last = (vec3*)vec3Array.LastElement(); vec3* tailAddress = (vec3*)vec3Array.TailAddress(); int i = 0; for (vec3* ptr = header; ptr <= last/*or: ptr < tailAddress*/; ptr++) { *ptr = new vec3(i * 3 + 0, i * 3 + 1, i * 3 + 2); i++; } i = 0; for (vec3* ptr = header; ptr <= last/*or: ptr < tailAddress*/; ptr++, i++) { var item = *ptr; var old = new vec3(i * 3 + 0, i * 3 + 1, i * 3 + 2); if (item.x != old.x || item.y != old.y || item.z != old.z) { throw new Exception(); } } interval2 = DateTime.Now.Ticks - startTick; } Console.WriteLine("Ticks: safe: {0} vs unsafe: {1}", interval, interval2); } // 测试mat4类型 { var vec3Array = new UnmanagedArray<mat4>(count); startTick = DateTime.Now.Ticks; for (int i = 0; i < count; i++) { vec3Array[i] = new mat4(new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3)); } for (int i = 0; i < count; i++) { var item = vec3Array[i]; var old = new mat4(new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3)); for (int col = 0; col < 4; col++) { for (int row = 0; row < 4; row++) { if (item[col][row] != old[col][row]) { throw new Exception(); } } } } interval = DateTime.Now.Ticks - startTick; unsafe { startTick = DateTime.Now.Ticks; mat4* header = (mat4*)vec3Array.FirstElement(); mat4* last = (mat4*)vec3Array.LastElement(); mat4* tailAddress = (mat4*)vec3Array.TailAddress(); int i = 0; for (mat4* ptr = header; ptr <= last/*or: ptr < tailAddress*/; ptr++) { *ptr = new mat4(new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3)); i++; } i = 0; for (mat4* ptr = header; ptr <= last/*or: ptr < tailAddress*/; ptr++, i++) { var item = *ptr; var old = new mat4(new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3)); for (int col = 0; col < 4; col++) { for (int row = 0; row < 4; row++) { if (item[col][row] != old[col][row]) { throw new Exception(); } } } } interval2 = DateTime.Now.Ticks - startTick; } Console.WriteLine("Ticks: safe: {0} vs unsafe: {1}", interval, interval2); } // 立即释放所有非托管数组占用的内存,任何之前创建的UnmanagedBase数组都不再可用了。 UnmanagedArray<int>.FreeAll(); }
/// <summary> /// Multiplies the <paramref name="lhs"/> matrix by the <paramref name="rhs"/> matrix. /// </summary> /// <param name="lhs">The LHS matrix.</param> /// <param name="rhs">The RHS matrix.</param> /// <returns>The product of <paramref name="lhs"/> and <paramref name="rhs"/>.</returns> public static mat4 operator *(mat4 lhs, mat4 rhs) { mat4 result = new mat4( new vec4( lhs[0][0] * rhs[0][0] + lhs[1][0] * rhs[0][1] + lhs[2][0] * rhs[0][2] + lhs[3][0] * rhs[0][3], lhs[0][1] * rhs[0][0] + lhs[1][1] * rhs[0][1] + lhs[2][1] * rhs[0][2] + lhs[3][1] * rhs[0][3], lhs[0][2] * rhs[0][0] + lhs[1][2] * rhs[0][1] + lhs[2][2] * rhs[0][2] + lhs[3][2] * rhs[0][3], lhs[0][3] * rhs[0][0] + lhs[1][3] * rhs[0][1] + lhs[2][3] * rhs[0][2] + lhs[3][3] * rhs[0][3] ), new vec4( lhs[0][0] * rhs[1][0] + lhs[1][0] * rhs[1][1] + lhs[2][0] * rhs[1][2] + lhs[3][0] * rhs[1][3], lhs[0][1] * rhs[1][0] + lhs[1][1] * rhs[1][1] + lhs[2][1] * rhs[1][2] + lhs[3][1] * rhs[1][3], lhs[0][2] * rhs[1][0] + lhs[1][2] * rhs[1][1] + lhs[2][2] * rhs[1][2] + lhs[3][2] * rhs[1][3], lhs[0][3] * rhs[1][0] + lhs[1][3] * rhs[1][1] + lhs[2][3] * rhs[1][2] + lhs[3][3] * rhs[1][3] ), new vec4( lhs[0][0] * rhs[2][0] + lhs[1][0] * rhs[2][1] + lhs[2][0] * rhs[2][2] + lhs[3][0] * rhs[2][3], lhs[0][1] * rhs[2][0] + lhs[1][1] * rhs[2][1] + lhs[2][1] * rhs[2][2] + lhs[3][1] * rhs[2][3], lhs[0][2] * rhs[2][0] + lhs[1][2] * rhs[2][1] + lhs[2][2] * rhs[2][2] + lhs[3][2] * rhs[2][3], lhs[0][3] * rhs[2][0] + lhs[1][3] * rhs[2][1] + lhs[2][3] * rhs[2][2] + lhs[3][3] * rhs[2][3] ), new vec4( lhs[0][0] * rhs[3][0] + lhs[1][0] * rhs[3][1] + lhs[2][0] * rhs[3][2] + lhs[3][0] * rhs[3][3], lhs[0][1] * rhs[3][0] + lhs[1][1] * rhs[3][1] + lhs[2][1] * rhs[3][2] + lhs[3][1] * rhs[3][3], lhs[0][2] * rhs[3][0] + lhs[1][2] * rhs[3][1] + lhs[2][2] * rhs[3][2] + lhs[3][2] * rhs[3][3], lhs[0][3] * rhs[3][0] + lhs[1][3] * rhs[3][1] + lhs[2][3] * rhs[3][2] + lhs[3][3] * rhs[3][3] ) ); return result; }
/// <summary> /// 获取此UI元素的投影矩阵、视图矩阵和模型矩阵 /// </summary> /// <param name="uiElement"></param> /// <param name="projectionMatrix"></param> /// <param name="viewMatrix"></param> /// <param name="modelMatrix"></param> /// <param name="camera">如果为null,会以glm.lookAt(new vec3(0, 0, 1), new vec3(0, 0, 0), new vec3(0, 1, 0))计算默认值。</param> /// <param name="maxDepth">UI元素的外接球半径的倍数。</param> public static void GetMatrix(this IUILayout uiElement, out mat4 projectionMatrix, out mat4 viewMatrix, out mat4 modelMatrix, IViewCamera camera = null, float maxDepth = 2.0f) { IUILayoutArgs args = uiElement.GetArgs(); float max = (float)Math.Max(args.UIWidth, args.UIHeight); { //projectionMatrix = glm.ortho((float)args.left, (float)args.right, (float)args.bottom, (float)args.top, // TODO: / 2后与legacy opengl的UI元素显示就完全一致了。为什么??? projectionMatrix = glm.ortho((float)args.left / 2, (float)args.right / 2, (float)args.bottom / 2, (float)args.top / 2, uiElement.Param.zNear, uiElement.Param.zFar); // 下面注释掉的代码是用来测试legacy OpenGL的matrix与GLM库计算的matrix是否相同用的。已经证明了两者完全相同,此处仅作留念+以防万一。 //{ // float[] matrix = new float[16]; // GL.MatrixMode(GL.GL_PROJECTION); // GL.PushMatrix(); // GL.GetFloat(GetTarget.ProjectionMatrix, matrix); // GL.LoadIdentity(); // GL.GetFloat(GetTarget.ProjectionMatrix, matrix); // GL.Ortho(args.left / 2, args.right / 2, args.bottom / 2, args.top / 2, uiElement.Param.zNear, uiElement.Param.zFar); // GL.GetFloat(GetTarget.ProjectionMatrix, matrix);// this equals projectionMatrix // GL.PopMatrix(); //} // 把UI元素移到ortho长方体的最靠近camera的地方,这样就可以把UI元素放到OpenGL最前方。 projectionMatrix = glm.translate(projectionMatrix, new vec3(0, 0, uiElement.Param.zFar - max / 2 * maxDepth)); } { // UI元素不在三维场景中,所以其Camera可以是null。 if (camera == null) { //viewMatrix = glm.lookAt(new vec3(0, 0, 1), new vec3(0, 0, 0), new vec3(0, 1, 0)); viewMatrix = glm.lookAt( ScientificCamera.defaultPosition, ScientificCamera.defaultTarget, ScientificCamera.defaultUpVector); } else { vec3 position = camera.Position - camera.Target; position.Normalize(); viewMatrix = glm.lookAt(position, new vec3(0, 0, 0), camera.UpVector); } // 下面注释掉的代码是用来测试legacy OpenGL的matrix与GLM库计算的matrix是否相同用的。已经证明了两者完全相同,此处仅作留念+以防万一。 //{ // float[] matrix = new float[16]; // GL.MatrixMode(GL.GL_MODELVIEW); // GL.PushMatrix(); // GL.GetFloat(GetTarget.ModelviewMatix, matrix); // GL.LoadIdentity(); // GL.GetFloat(GetTarget.ModelviewMatix, matrix); // if(camera==null) // { // GL.gluLookAt(0, 0, 1, 0, 0, 0, 0, 1, 0); // } // else // { // vec3 position = camera.Position - camera.Target; // position.Normalize(); // GL.gluLookAt(position.x, position.y, position.z, 0, 0, 0, camera.UpVector.x, camera.UpVector.y, camera.UpVector.z); // } // GL.GetFloat(GetTarget.ModelviewMatix, matrix);// this equals viewMatrix // GL.PopMatrix(); //} } { modelMatrix = glm.scale(mat4.identity(), new vec3(args.UIWidth / 2, args.UIHeight / 2, max / 2)); // 下面注释掉的代码是用来测试legacy OpenGL的matrix与GLM库计算的matrix是否相同用的。已经证明了两者完全相同,此处仅作留念+以防万一。 //{ // float[] matrix = new float[16]; // GL.MatrixMode(GL.GL_MODELVIEW); // GL.PushMatrix(); // GL.GetFloat(GetTarget.ModelviewMatix, matrix); // GL.LoadIdentity(); // GL.GetFloat(GetTarget.ModelviewMatix, matrix); // GL.Scale(args.UIWidth / 2, args.UIHeight / 2, max / 2); // GL.GetFloat(GetTarget.ModelviewMatix, matrix);// this equals modelMatrix // GL.PopMatrix(); //} } }