Richy19's picture

Possible Matrix4.CreateOrthographic bug?

Im on mono using a recent version of openTK from the repo.

I tried a simple program:

// Released to the public domain. Use, modify and relicense at will.
using System;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Audio;
using OpenTK.Audio.OpenAL;
using OpenTK.Input;
namespace StarterKit
	class Game : GameWindow
		float[] vertices = {	0.5f,	0.0f,	1.0f,	
								0.0f,	1.0f,	1.0f,
								1.0f,	1.0f,	1.0f };
		int vbo;
		string fragmentSource = "#version 120\n" +
						"void main(){gl_FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);}";
		string vertexSource = "#version 120\n" +
						"uniform mat4 MVP; attribute vec3 Position;" +
						"void main(){ gl_Position = MVP * vec4(Position, 1.0f);	}";
		int shaderProgram, vertexShader, fragmentShader;
		int MVPID, PositionID;
		Matrix4 MVP;
		/// <summary>Creates a 800x600 window with the specified title.</summary>
		public Game ()
            : base(800, 600, GraphicsMode.Default, "OpenTK Quick Start Sample")
			VSync = VSyncMode.On;
		protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
			GL.DetachShader( shaderProgram, vertexShader );
			GL.DetachShader( shaderProgram, fragmentShader );
			GL.DeleteBuffers(1, ref vbo);
		/// <summary>Load resources here.</summary>
		/// <param name="e">Not used.</param>
		protected override void OnLoad (EventArgs e)
			base.OnLoad (e);
			GL.ClearColor (0.1f, 0.2f, 0.5f, 0.0f);
			GL.Enable (EnableCap.DepthTest);
			GL.GenBuffers (1, out vbo);
			GL.BindBuffer (BufferTarget.ArrayBuffer, vbo);
			GL.BufferData (BufferTarget.ArrayBuffer, (IntPtr)(vertices.Length * sizeof(float)), vertices, BufferUsageHint.StaticDraw);
			vertexShader = GL.CreateShader(ShaderType.VertexShader);
			GL.ShaderSource( vertexShader, vertexSource );
			GL.CompileShader( vertexShader );
			fragmentShader = GL.CreateShader( ShaderType.FragmentShader );
			GL.ShaderSource( fragmentShader, fragmentSource );
			GL.CompileShader( fragmentShader );
			shaderProgram = GL.CreateProgram();
			GL.AttachShader( shaderProgram, vertexShader );
			GL.AttachShader( shaderProgram, fragmentShader );
			MVPID = GL.GetUniformLocation(shaderProgram, "MVP");
			PositionID = GL.GetAttribLocation(shaderProgram, "Position");
			MVP = Matrix4.CreateOrthographicOffCenter(0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 2.0f);
		/// <summary>
		/// Called when your window is resized. Set your viewport here. It is also
		/// a good place to set up your projection matrix (which probably changes
		/// along when the aspect ratio of your window).
		/// </summary>
		/// <param name="e">Not used.</param>
		protected override void OnResize (EventArgs e)
			base.OnResize (e);
			GL.Viewport (ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, ClientRectangle.Height);
		/// <summary>
		/// Called when it is time to setup the next frame. Add you game logic here.
		/// </summary>
		/// <param name="e">Contains timing information for framerate independent logic.</param>
		protected override void OnUpdateFrame (FrameEventArgs e)
			base.OnUpdateFrame (e);
			if (Keyboard [Key.Escape])
				Exit ();
		/// <summary>
		/// Called when it is time to render the next frame. Add your rendering code here.
		/// </summary>
		/// <param name="e">Contains timing information.</param>
		protected override void OnRenderFrame (FrameEventArgs e)
			base.OnRenderFrame (e);
			GL.Clear (ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
			GL.UseProgram (shaderProgram);
			GL.UniformMatrix4(MVPID, false, ref MVP);
    		GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
    		GL.VertexAttribPointer(PositionID, 3, VertexAttribPointerType.Float, false, 0, IntPtr.Zero);
			GL.DrawArrays(BeginMode.Triangles, 0, 3);
			GL.UseProgram (0);
			SwapBuffers ();
			ErrorCode ec = GL.GetError ();
			if (ec != 0) {
				System.Console.WriteLine( ec.ToString() );
		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		static void Main ()
			// The 'using' idiom guarantees proper resource cleanup.
			// We request 30 UpdateFrame events per second, and unlimited
			// RenderFrame events (as fast as the computer can handle).
			using (Game game = new Game()) {
				game.Run (30.0);

However nothing showed up.
After much debugging it turned out to be a depth problem.
and changing the positive values of the z value of the verticies fixed it however I was under the impression that setting the near and far values of the ortho to 0 and 2 would make it dislay anything within these values, however it is actually only accepting values between 0 and -2


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
mOfl's picture

If you only apply a projection (and no model-, world- or view-space transformation) to the geometry, then in a right-handed coordinate system like the one used in OpenGL you will look in the direction of the negative Z axis. In this case, you have to "turn around" the projection space, leading to inverted near and far clipping planes: MVP = Matrix4.CreateOrthographicOffCenter(0.0f, 1.0f, 0.0f, 1.0f, -2.0f, 0.0f);