Axiom.RenderSystems.OpenGL.ARBGpuProgram.LoadFromSource C# (CSharp) Method

LoadFromSource() protected method

Load Assembler gpu program source.
protected LoadFromSource ( ) : void
return void
		protected override void LoadFromSource()
		{
			Gl.glBindProgramARB( programType, programId );

			// MONO: Cannot compile programs when passing in the string as is for whatever reason.
			// would get "Invalid vertex program header", which I assume means the source got mangled along the way
			byte[] bytes = Encoding.ASCII.GetBytes( Source );
			// TODO: We pin the managed 'bytes' to get a pointer to data and get sure they won't move around in memory.
			//       In case glProgramStringARB() doesn't store the pointer internally, we better free the handle yet in this method,
			//       or rather utilize a fixed (byte* sourcePtr = bytes) statement, which cares for unpinning the data even in case
			//       of an exception, where GCHandle.Free() would be missed without try-finally.

			//       In case the above isn't possible, the theory also says that if we have a handle to managed data (except Weak, WeakTrackResurrection handle types)
			//       we should be implementing a finalizer to ensure freeing the handle as that can be treated as an unmanaged resource from this point of view.
			//       I decided not to extend this class with IDisposable for several reasons, including class's user contract,
			//       and the fact that this might be a temporary issue only. So for now only a finalizer will take care for avoiding memory leaks (although minor ones in this case).
			//       So recheck the MONO issue later, the above comment talks about passing the string directly, btw. the method seems to take byte[] as well (if that would work eventually...).
			if ( _handle.IsAllocated )
			{
				_handle.Free();
			}
			_handle = GCHandle.Alloc( bytes, GCHandleType.Pinned );
			IntPtr sourcePtr = _handle.AddrOfPinnedObject();

			Gl.glProgramStringARB( programType, Gl.GL_PROGRAM_FORMAT_ASCII_ARB, Source.Length, sourcePtr );

			// check for any errors
			if ( Gl.glGetError() == Gl.GL_INVALID_OPERATION )
			{
				int pos;
				string error;

				Gl.glGetIntegerv( Gl.GL_PROGRAM_ERROR_POSITION_ARB, out pos );
				error = Gl.glGetString( Gl.GL_PROGRAM_ERROR_STRING_ARB ); // TAO 2.0
				//error = Marshal.PtrToStringAnsi( Gl.glGetString( Gl.GL_PROGRAM_ERROR_STRING_ARB ) );

				throw new Exception( string.Format( "Error on line {0} in program '{1}'\nError: {2}", pos, Name, error ) );
			}
		}