/// <summary> /// Download Texture data to an Image instance. /// </summary> /// <param name="ctx"> /// A <see cref="GraphicsContext"/> used for downloading texture data. /// </param> /// <param name="pType"> /// A <see cref="OpenGL.PixelLayout"/> determining the pixel format of the downloaded data. /// </param> /// <param name="target"> /// A <see cref="TextureTarget"/> that specify the texture target. /// </param> /// <returns> /// /// </returns> protected Image[] Get(GraphicsContext ctx, PixelLayout pType, TextureTarget target) { // Bind this Texture ctx.Bind(this); // Get texture extents int width, height; Gl.GetTexLevelParameter(TextureTarget, 0, GetTextureParameter.TextureWidth, out width); Gl.GetTexLevelParameter(TextureTarget, 0, GetTextureParameter.TextureHeight, out height); if ((width <= 0) || (height <= 0)) { throw new InvalidOperationException(String.Format("invalid texture extents {0}x{1}", width, height)); } // Create image Image image = new Image(pType, (uint)width, (uint)height); // Set pixel transfer foreach (int alignment in new int[] { 8, 4, 2, 1 }) { if (image.Stride % alignment == 0) { Gl.PixelStore(PixelStoreParameter.PackAlignment, alignment); break; } } // Download texture contents Gl.GetTexImage(target, 0, Pixel.GetGlFormat(pType), Pixel.GetPixelType(pType), image.ImageBuffer); // Unbind this texture ctx.Unbind(this); return(new Image[] { image }); }
/// <summary> /// Actually create this BufferObject resources. /// </summary> /// <param name="ctx"> /// A <see cref="GraphicsContext"/> used for allocating resources. /// </param> /// <exception cref="ArgumentNullException"> /// Exception thrown if <paramref name="ctx"/> is null. /// </exception> /// <exception cref="ArgumentException"> /// Exception thrown if <paramref name="ctx"/> is not current on the calling thread. /// </exception> /// <exception cref="InvalidOperationException"> /// Exception thrown if this BufferObject has not client memory allocated and the hint is different from /// <see cref="BufferObjectHint.StaticCpuDraw"/> or <see cref="BufferObjectHint.DynamicCpuDraw"/>. /// </exception> /// <exception cref="InvalidOperationException"> /// Exception thrown if this BufferObject is currently mapped. /// </exception> protected override void CreateObject(GraphicsContext ctx) { CheckCurrentContext(ctx); if ((ClientBufferAddress == IntPtr.Zero) && ((Hint != BufferObjectHint.StaticCpuDraw) && (Hint != BufferObjectHint.DynamicCpuDraw))) { throw new InvalidOperationException("no client buffer"); } // Determine the client buffer size uint clientBufferSize = _ClientBufferSize; if (ClientBufferAddress != IntPtr.Zero) { clientBufferSize = ClientBufferSize; } Debug.Assert(clientBufferSize > 0); // Buffer must be bound ctx.Bind(this); if (ctx.Caps.GlExtensions.VertexBufferObject_ARB) { if (IsMapped) { throw new InvalidOperationException("mapped"); } // Define buffer object (type, size and hints) AllocateGpuBuffer(clientBufferSize, null); // Define buffer object contents if (ClientBufferAddress != IntPtr.Zero) { // Provide buffer contents Gl.BufferSubData(BufferType, IntPtr.Zero, _GpuBufferSize, ClientBufferAddress); // Release memory, if it is not required anymore if (_MemoryBufferAutoDispose) { ReleaseClientBuffer(); } } } else { // Discard previous GPU buffer, if any if (_GpuBuffer != null) { _GpuBuffer.Dispose(); } if (ClientBufferAddress == IntPtr.Zero) { // Note: GPU buffer size specified by _ClientBufferSize Debug.Assert(_ClientBufferSize > 0); // Allocate simulated GPU buffer _GpuBuffer = new AlignedMemoryBuffer(_ClientBufferSize, MinimumBufferAlignment); } else { // Let a virtual implementation decide how pass information from the client buffer and the "GPU" buffer UploadClientBuffer(); } // Store GPU buffer size _GpuBufferSize = _GpuBuffer.Size; } // Reset requested client buffer size _ClientBufferSize = 0; }