␊ |
␉␉#region glSetBufferData Methods␊ |
␊ |
␉␉public void SetVertexBufferData<T>(␊ |
␉␉public void SetVertexBufferData(␊ |
␉␉␉IGLBuffer buffer,␊ |
␉␉␉int elementSizeInBytes,␊ |
␉␉␉int offsetInBytes,␊ |
␉␉␉T[] data,␊ |
␉␉␉IntPtr data,␊ |
␉␉␉int startIndex,␊ |
␉␉␉int elementCount,␊ |
␉␉␉int elementSizeInBytes,␊ |
␉␉␉SetDataOptions options␊ |
␉␉) where T : struct {␊ |
␉␉) {␊ |
#if !DISABLE_THREADING␊ |
␉␉␉ForceToMainThread(() => {␊ |
#endif␊ |
|
␉␉␉␉);␊ |
␉␉␉}␊ |
␊ |
␉␉␉GCHandle dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);␊ |
␊ |
␉␉␉glBufferSubData(␊ |
␉␉␉␉GLenum.GL_ARRAY_BUFFER,␊ |
␉␉␉␉(IntPtr) offsetInBytes,␊ |
␉␉␉␉(IntPtr) (elementSizeInBytes * elementCount),␊ |
␉␉␉␉(IntPtr) (dataHandle.AddrOfPinnedObject().ToInt64() + startIndex * elementSizeInBytes)␊ |
␉␉␉␉data + (startIndex * elementSizeInBytes)␊ |
␉␉␉);␊ |
␊ |
␉␉␉dataHandle.Free();␊ |
␊ |
#if !DISABLE_THREADING␊ |
␉␉␉});␊ |
#endif␊ |
␉␉}␊ |
␊ |
␉␉public void SetIndexBufferData<T>(␊ |
␉␉public void SetIndexBufferData(␊ |
␉␉␉IGLBuffer buffer,␊ |
␉␉␉int offsetInBytes,␊ |
␉␉␉T[] data,␊ |
␉␉␉IntPtr data,␊ |
␉␉␉int startIndex,␊ |
␉␉␉int elementCount,␊ |
␉␉␉int elementSizeInBytes,␊ |
␉␉␉SetDataOptions options␊ |
␉␉) where T : struct {␊ |
␉␉) {␊ |
#if !DISABLE_THREADING␊ |
␉␉␉ForceToMainThread(() => {␊ |
#endif␊ |
|
␉␉␉␉);␊ |
␉␉␉}␊ |
␊ |
␉␉␉GCHandle dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);␊ |
␊ |
␉␉␉int elementSizeInBytes = Marshal.SizeOf(typeof(T));␊ |
␉␉␉glBufferSubData(␊ |
␉␉␉␉GLenum.GL_ELEMENT_ARRAY_BUFFER,␊ |
␉␉␉␉(IntPtr) offsetInBytes,␊ |
␉␉␉␉(IntPtr) (elementSizeInBytes * elementCount),␊ |
␉␉␉␉(IntPtr) (dataHandle.AddrOfPinnedObject().ToInt64() + startIndex * elementSizeInBytes)␊ |
␉␉␉␉data + (startIndex * elementSizeInBytes)␊ |
␉␉␉);␊ |
␊ |
␉␉␉dataHandle.Free();␊ |
␊ |
#if !DISABLE_THREADING␊ |
␉␉␉});␊ |
#endif␊ |
|
␊ |
␉␉#region glGetBufferData Methods␊ |
␊ |
␉␉public void GetVertexBufferData<T>(␊ |
␉␉public void GetVertexBufferData(␊ |
␉␉␉IGLBuffer buffer,␊ |
␉␉␉int offsetInBytes,␊ |
␉␉␉T[] data,␊ |
␉␉␉IntPtr data,␊ |
␉␉␉int startIndex,␊ |
␉␉␉int elementCount,␊ |
␉␉␉int elementSizeInBytes,␊ |
␉␉␉int vertexStride␊ |
␉␉) where T : struct {␊ |
␉␉) {␊ |
#if !DISABLE_THREADING␊ |
␉␉␉ForceToMainThread(() => {␊ |
#endif␊ |
␊ |
␉␉␉BindVertexBuffer(buffer);␊ |
␊ |
␉␉␉GCHandle dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);␊ |
␊ |
␉␉␉glGetBufferSubData(␊ |
␉␉␉␉GLenum.GL_ARRAY_BUFFER,␊ |
␉␉␉␉(IntPtr) offsetInBytes,␊ |
␉␉␉␉(IntPtr) (elementCount * vertexStride),␊ |
␉␉␉␉dataHandle.AddrOfPinnedObject() + (startIndex * Marshal.SizeOf(typeof(T)))␊ |
␉␉␉␉data + (startIndex * elementSizeInBytes)␊ |
␉␉␉);␊ |
␊ |
␉␉␉dataHandle.Free();␊ |
␊ |
#if !DISABLE_THREADING␊ |
␉␉␉});␊ |
#endif␊ |
␉␉}␊ |
␊ |
␉␉public void GetIndexBufferData<T>(␊ |
␉␉public void GetIndexBufferData(␊ |
␉␉␉IGLBuffer buffer,␊ |
␉␉␉int offsetInBytes,␊ |
␉␉␉T[] data,␊ |
␉␉␉IntPtr data,␊ |
␉␉␉int startIndex,␊ |
␉␉␉int elementCount␊ |
␉␉) where T : struct {␊ |
␉␉␉int elementCount,␊ |
␉␉␉int elementSizeInBytes␊ |
␉␉) {␊ |
#if !DISABLE_THREADING␊ |
␉␉␉ForceToMainThread(() => {␊ |
#endif␊ |
␊ |
␉␉␉BindIndexBuffer(buffer);␊ |
␊ |
␉␉␉GCHandle dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);␊ |
␊ |
␉␉␉int typeSize = Marshal.SizeOf(typeof(T));␊ |
␉␉␉glGetBufferSubData(␊ |
␉␉␉␉GLenum.GL_ELEMENT_ARRAY_BUFFER,␊ |
␉␉␉␉(IntPtr) offsetInBytes,␊ |
␉␉␉␉(IntPtr) (elementCount * typeSize),␊ |
␉␉␉␉dataHandle.AddrOfPinnedObject() + (startIndex * typeSize)␊ |
␉␉␉␉(IntPtr) (elementCount * elementSizeInBytes),␊ |
␉␉␉␉data + (startIndex * elementSizeInBytes)␊ |
␉␉␉);␊ |
␊ |
␉␉␉dataHandle.Free();␊ |
␊ |
#if !DISABLE_THREADING␊ |
␉␉␉});␊ |
#endif␊ |
|
␊ |
␉␉#region glReadPixels Methods␊ |
␊ |
␉␉public void ReadBackbuffer<T>(␊ |
␉␉␉T[] data,␊ |
␉␉public void ReadBackbuffer(␊ |
␉␉␉IntPtr data,␊ |
␉␉␉int dataLen,␊ |
␉␉␉int startIndex,␊ |
␉␉␉int elementCount,␊ |
␉␉␉int elementSizeInBytes,␊ |
␉␉␉Rectangle? rect␊ |
␉␉) where T : struct {␊ |
␉␉␉if (startIndex > 0 || elementCount != data.Length)␊ |
␉␉) {␊ |
␉␉␉/* FIXME: Right now we're expecting one of the following:␊ |
␉␉␉ * - byte[]␊ |
␉␉␉ * - int[]␊ |
␉␉␉ * - uint[]␊ |
␉␉␉ * - Color[]␊ |
␉␉␉ * Anything else will freak out because we're using␊ |
␉␉␉ * color backbuffers. Maybe check this out when adding␊ |
␉␉␉ * support for more backbuffer types!␊ |
␉␉␉ * -flibit␊ |
␉␉␉ */␊ |
␊ |
␉␉␉if (startIndex > 0 || elementCount != (dataLen / elementSizeInBytes))␊ |
␉␉␉{␊ |
␉␉␉␉throw new NotImplementedException(␊ |
␉␉␉␉␉"ReadBackbuffer startIndex/elementCount"␊ |
|
␉␉␉␉h = Backbuffer.Height;␊ |
␉␉␉}␊ |
␊ |
␉␉␉GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);␊ |
␉␉␉try␊ |
␉␉␉{␊ |
␉␉␉␉glReadPixels(␊ |
␉␉␉␉␉x,␊ |
␉␉␉␉␉y,␊ |
␉␉␉␉␉w,␊ |
␉␉␉␉␉h,␊ |
␉␉␉␉␉GLenum.GL_RGBA,␊ |
␉␉␉␉␉GLenum.GL_UNSIGNED_BYTE,␊ |
␉␉␉␉␉handle.AddrOfPinnedObject()␊ |
␉␉␉␉);␊ |
␉␉␉}␊ |
␉␉␉finally␊ |
␉␉␉{␊ |
␉␉␉␉handle.Free();␊ |
␉␉␉}␊ |
␉␉␉glReadPixels(␊ |
␉␉␉␉x,␊ |
␉␉␉␉y,␊ |
␉␉␉␉w,␊ |
␉␉␉␉h,␊ |
␉␉␉␉GLenum.GL_RGBA,␊ |
␉␉␉␉GLenum.GL_UNSIGNED_BYTE,␊ |
␉␉␉␉data␊ |
␉␉␉);␊ |
␊ |
␉␉␉BindReadFramebuffer(prevReadBuffer);␊ |
␊ |
␉␉␉// Now we get to do a software-based flip! Yes, really! -flibit␊ |
␉␉␉int pitch = w * 4 / Marshal.SizeOf(typeof(T));␊ |
␉␉␉T[] tempRow = new T[pitch];␊ |
␉␉␉int pitch = w * 4;␊ |
␉␉␉byte[] tempRow = new byte[pitch];␊ |
␉␉␉GCHandle handle = GCHandle.Alloc(tempRow, GCHandleType.Pinned);␊ |
␉␉␉IntPtr temp = handle.AddrOfPinnedObject();␊ |
␉␉␉for (int row = 0; row < h / 2; row += 1)␊ |
␉␉␉{␊ |
␉␉␉␉Array.Copy(data, row * pitch, tempRow, 0, pitch);␊ |
␉␉␉␉Array.Copy(data, (h - row - 1) * pitch, data, row * pitch, pitch);␊ |
␉␉␉␉Array.Copy(tempRow, 0, data, (h - row - 1) * pitch, pitch);␊ |
␉␉␉␉// Top to temp, bottom to top, temp to bottom␊ |
␉␉␉␉memcpy(temp, data + (row * pitch), (IntPtr) pitch);␊ |
␉␉␉␉memcpy(data + (row * pitch), data + ((h - row - 1) * pitch), (IntPtr) pitch);␊ |
␉␉␉␉memcpy(data + ((h - row - 1) * pitch), temp, (IntPtr) pitch);␊ |
␉␉␉}␊ |
␉␉␉handle.Free();␊ |
␉␉}␊ |
␉␉[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]␊ |
␉␉private static extern void memcpy(IntPtr dst, IntPtr src, IntPtr len);␊ |
␊ |
␉␉/// <summary>␊ |
␉␉/// Attempts to read the texture data directly from the FBO using glReadPixels␊ |