Example #1
0
 /// <summary>
 /// Create a texture from a supplie bitmap.
 /// </summary>
 /// <param name="BitmapImage">The already decoded bitmap image.</param>
 /// <param name="FlipY">True if the bitmap should be flipped.</param>
 public Texture(Bitmap BitmapImage, bool FlipY = true)
 {
     Filename = BitmapImage.GetHashCode().ToString();
     LoadBitmap(BitmapImage, FlipY);
     Gl.BindTexture(TextureTarget, 0);
 }
Example #2
0
 /// <summary>
 /// Performs the draw routine with a custom shader program.
 /// </summary>
 /// <param name="program"></param>
 public void DrawProgram(ShaderProgram program)
 {
     BindAttributes(program);
     Gl.DrawElements(DrawMode, VertexCount, DrawElementsType.UnsignedInt, IntPtr.Zero);
 }
Example #3
0
 /// <summary>
 /// Binds a VBO based on the buffer target.
 /// </summary>
 /// <param name="buffer">The VBO to bind.</param>
 public static void BindBuffer <T>(VBO <T> buffer)
     where T : struct
 {
     Gl.BindBuffer(buffer.BufferTarget, buffer.vboID);
 }
Example #4
0
        /// <summary>
        /// Loads a compressed DDS file into an OpenGL texture.
        /// </summary>
        /// <param name="ResourceFile">The path to the DDS file.</param>
        private void LoadDDS(string ResourceFile)
        {
            using (BinaryReader stream = new BinaryReader(new FileStream(ResourceFile, FileMode.Open)))
            {
                string filecode = new string(stream.ReadChars(4));
                if (filecode != "DDS ")                                 // first 4 chars should be "DDS "
                {
                    throw new Exception("File was not a DDS file format.");
                }

                DDS.DDSURFACEDESC2 imageData = DDS.DDSURFACEDESC2.FromBinaryReader(stream);//new DDS.DDSURFACEDESC2(stream);  // read the DirectDraw surface descriptor
                this.Size = new Size((int)imageData.Width, (int)imageData.Height);

                if (imageData.LinearSize == 0)
                {
                    throw new Exception("The linear scan line size was zero.");
                }

                bool compressed = true;
                int  factor = 0, buffersize = 0, blocksize = 0;
                PixelInternalFormat format;
                switch (imageData.PixelFormat.FourCC) // check the compression type
                {
                case "DXT1":                          // DXT1 compression ratio is 8:1
                    format    = PixelInternalFormat.CompressedRgbaS3tcDxt1Ext;
                    factor    = 2;
                    blocksize = 8;
                    break;

                case "DXT3":        // DXT3 compression ratio is 4:1
                    format    = PixelInternalFormat.CompressedRgbaS3tcDxt3Ext;
                    factor    = 4;
                    blocksize = 16;
                    break;

                case "DXT5":        // DXT5 compression ratio is 4:1
                    format    = PixelInternalFormat.CompressedRgbaS3tcDxt5Ext;
                    factor    = 4;
                    blocksize = 16;
                    break;

                default:
                    compressed = false;
                    if (imageData.PixelFormat.ABitMask == 0xf000 && imageData.PixelFormat.RBitMask == 0x0f00 &&
                        imageData.PixelFormat.GBitMask == 0x00f0 && imageData.PixelFormat.BBitMask == 0x000f &&
                        imageData.PixelFormat.RGBBitCount == 16)
                    {
                        format = PixelInternalFormat.Rgba;
                    }
                    else if (imageData.PixelFormat.ABitMask == unchecked ((int)0xff000000) && imageData.PixelFormat.RBitMask == 0x00ff0000 &&
                             imageData.PixelFormat.GBitMask == 0x0000ff00 && imageData.PixelFormat.BBitMask == 0x000000ff &&
                             imageData.PixelFormat.RGBBitCount == 32)
                    {
                        format = PixelInternalFormat.Rgba;
                    }
                    else
                    {
                        throw new Exception(string.Format("File compression \"{0}\" is not supported.", imageData.PixelFormat.FourCC));
                    }
                    break;
                }

                if (imageData.LinearSize != 0)
                {
                    buffersize = (int)((imageData.MipmapCount > 1) ? imageData.LinearSize * factor : imageData.LinearSize);
                }
                else
                {
                    buffersize = (int)(stream.BaseStream.Length - stream.BaseStream.Position);
                }

                // read the pixel data and then pin it to memory so that the garbage collector
                // doesn't shuffle the data around while OpenGL is decompressing it
                byte[]   pixels = stream.ReadBytes(buffersize);
                GCHandle pinned = GCHandle.Alloc(pixels, GCHandleType.Pinned);

                try
                {
                    TextureTarget = (imageData.Height == 1 || imageData.Width == 1) ? TextureTarget.Texture1D : TextureTarget.Texture2D;
                    TextureID     = Gl.GenTexture();

                    Gl.BindTexture(TextureTarget, TextureID);
                    Gl.TexParameteri(TextureTarget, TextureParameterName.TextureMinFilter, TextureParameter.Linear);
                    Gl.TexParameteri(TextureTarget, TextureParameterName.TextureMagFilter, TextureParameter.Linear);

                    int nOffset = 0, nWidth = (int)imageData.Width, nHeight = (int)imageData.Height;

                    for (int i = 0; i < (imageData.MipmapCount == 0 ? 1 : imageData.MipmapCount); ++i)
                    {
                        if (nWidth == 0)
                        {
                            nWidth = 1;                     // smallest mipmap is 1x1 pixels
                        }
                        if (nHeight == 0)
                        {
                            nHeight = 1;
                        }
                        int nSize = 0;

                        if (compressed)
                        {
                            nSize = ((nWidth + 3) / 4) * ((nHeight + 3) / 4) * blocksize;
                            Gl.CompressedTexImage2D(TextureTarget, i, format, nWidth, nHeight, 0, nSize, (IntPtr)(pinned.AddrOfPinnedObject().ToInt64() + nOffset));
                        }
                        else
                        {
                            PixelType pixelType = imageData.PixelFormat.RGBBitCount == 16 ? PixelType.UnsignedShort4444Reversed : PixelType.UnsignedInt8888Reversed;

                            nSize = nWidth * nHeight * imageData.PixelFormat.RGBBitCount / 8;
                            Gl.TexImage2D(TextureTarget, i, format, nWidth, nHeight, 0, PixelFormat.Bgra, pixelType, (IntPtr)(pinned.AddrOfPinnedObject().ToInt64() + nOffset));
                        }

                        nOffset += nSize;
                        nWidth  /= 2;
                        nHeight /= 2;
                    }

#if MEMORY_LOGGER
                    MemoryLogger.AllocateTexture(TextureID, Size);
#endif
                }
                catch (Exception)
                {   // There was some sort of Dll related error, or the target GPU does not support glCompressedTexImage2DARB
                    throw;
                }
                finally
                {
                    pinned.Free();
                }
            }
        }
Example #5
0
 /// <summary>
 /// Installs a program object as part of current rendering state.
 /// </summary>
 /// <param name="Program">Specifies the handle of the program object whose executables are to be used as part of current rendering state.</param>
 public static void UseProgram(ShaderProgram Program)
 {
     Gl.UseProgram(Program.ProgramID);
 }
Example #6
0
 /// <summary>
 /// Bind a named texture to a texturing target
 /// </summary>
 /// <param name="Texture">Specifies the texture.</param>
 public static void BindTexture(Texture Texture)
 {
     Gl.BindTexture(Texture.TextureTarget, Texture.TextureID);
 }
Example #7
0
 /// <summary>
 /// Shortcut for quickly generating a single renderbuffer object without creating an array
 /// to pass to the gl function.  Calls Gl.GenRenderbuffers(1, id).
 /// </summary>
 /// <returns>The ID of the generated framebuffer.  0 on failure.</returns>
 public static uint GenRenderbuffer()
 {
     uint1[0] = 0;
     Gl.GenRenderbuffers(1, uint1);
     return(uint1[0]);
 }
Example #8
0
 /// <summary>
 /// Shortcut for quickly generating a single framebuffer object without creating an array
 /// to pass to the gl function.  Calls Gl.GenFramebuffers(1, id).
 /// </summary>
 /// <returns>The ID of the generated framebuffer.  0 on failure.</returns>
 public static uint GenFramebuffer()
 {
     Gl.GenFramebuffers(1, uint1);
     return(uint1[0]);
 }
Example #9
0
 /// <summary>
 /// Shortcut for quickly generating a single vertex array id without creating an array to
 /// pass to the gl function.  Calls Gl.GenVertexArrays(1, id).
 /// </summary>
 /// <returns>The ID of the generated vertex array.  0 on failure.</returns>
 public static uint GenVertexArray()
 {
     uint1[0] = 0;
     Gl.GenVertexArrays(1, uint1);
     return(uint1[0]);
 }
Example #10
0
 /// <summary>
 /// Shortcut for quickly generating a single texture id without creating an array to
 /// pass to the gl function.  Calls Gl.GenTexture(1, id).
 /// </summary>
 /// <returns>The ID of the generated texture.  0 on failure.</returns>
 public static uint GenTexture()
 {
     uint1[0] = 0;
     Gl.GenTextures(1, uint1);
     return(uint1[0]);
 }
Example #11
0
		/// <summary>
		/// Query the OpenGL implementation limits.
		/// </summary>
		/// <param name="glExtensions">
		/// A <see cref="Gl.Extensions"/> that specify the supported OpenGL extension by the current
		/// implementation.
		/// </param>
		/// <returns>
		/// It returns a <see cref="GraphicsLimits"/> that specify the current OpenGL implementation limits.
		/// </returns>
		/// <remarks>
		/// It is assumed to have a valid OpenGL context current on the calling thread.
		/// </remarks>
		public static GraphicsLimits Query(Gl.Extensions glExtensions)
		{
			if (glExtensions == null)
				throw new ArgumentNullException("glExtensions");

			KhronosApi.LogComment("Query OpenGL implementation imits.");

			GraphicsLimits graphicsLimits = new GraphicsLimits();
			FieldInfo[] graphicsLimitsFields = typeof(GraphicsLimits).GetFields(BindingFlags.Public | BindingFlags.Instance);

			foreach (FieldInfo field in graphicsLimitsFields) {
				GraphicsLimitAttribute graphicsLimitAttribute = (GraphicsLimitAttribute)Attribute.GetCustomAttribute(field, typeof(GraphicsLimitAttribute));
				Attribute[] graphicsExtensionAttributes = Attribute.GetCustomAttributes(field, typeof(KhronosApi.ExtensionAttribute));
				MethodInfo getMethod;

				if (graphicsLimitAttribute == null)
					continue;

				// Check extension support
				if ((graphicsExtensionAttributes != null) && (graphicsExtensionAttributes.Length > 0)) {
					bool supported = Array.Exists(graphicsExtensionAttributes, delegate(Attribute item) {
						return glExtensions.HasExtensions(((KhronosApi.ExtensionAttribute)item).ExtensionName);
					});

					if (supported == false)
						continue;
				}

				// Determine which method is used to get the OpenGL limit
				if (field.FieldType != typeof(String)) {
					if (field.FieldType.IsArray == true)
						getMethod = typeof(Gl).GetMethod("Get", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(Int32), field.FieldType }, null);
					else
						getMethod = typeof(Gl).GetMethod("Get", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(Int32), field.FieldType.MakeByRefType() }, null);
				} else
					getMethod = typeof(Gl).GetMethod("GetString", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(Int32) }, null);

				if (getMethod != null) {
					if (field.FieldType != typeof(String)) {
						object obj;

						if (field.FieldType.IsArray == false)
							obj = Activator.CreateInstance(field.FieldType);
						else
							obj = Array.CreateInstance(field.FieldType.GetElementType(), graphicsLimitAttribute.ArrayLenght);
						object[] @params = new object[] { graphicsLimitAttribute.EnumValue, obj };

						try {
							getMethod.Invoke(null, @params);

							field.SetValue(graphicsLimits, @params[1]);
						} catch (Exception) {

						}
						
					} else {
						try {
							string s = (string)getMethod.Invoke(null, new object[] { graphicsLimitAttribute.EnumValue });

							field.SetValue(graphicsLimits, s);
						} catch (Exception) {
							
						}
					}
				} else
					throw new InvalidOperationException("GraphicsLimits field " + field.Name + " doesn't have a OpenGL compatible type");

				string fieldValueString;
				object fieldValue = field.GetValue(graphicsLimits);

				if (fieldValue is Array) {
					StringBuilder sb = new StringBuilder();

					sb.Append("{ ");
					if (((Array)fieldValue).Length > 0) {
						foreach (object arrayItem in (Array)fieldValue)
							sb.AppendFormat("{0}, ", arrayItem);
						sb.Remove(sb.Length - 2, 2);
					}
					sb.Append(" }");

					fieldValueString = sb.ToString();
				} else
					fieldValueString = fieldValue.ToString();
			}

			return (graphicsLimits);
		}