147 lines
4.1 KiB
C#
147 lines
4.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using SDL2;
|
|
|
|
namespace testdrid.SdlWrapper
|
|
{
|
|
internal class Texture : IDisposable
|
|
{
|
|
private Texture() {}
|
|
|
|
internal IntPtr Pointer { get; set; }
|
|
public static Texture FromSurface(Renderer renderer, Surface surface)
|
|
{
|
|
Texture result = new Texture();
|
|
result.Pointer = SDL.SDL_CreateTextureFromSurface(renderer.Pointer, surface.IntPointer);
|
|
if (result.Pointer == IntPtr.Zero)
|
|
{
|
|
throw SdlException.GenerateException();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public static Texture Create(Renderer renderer, SDL.SDL_TextureAccess access, int w, int h)
|
|
{
|
|
Texture result = new Texture();
|
|
result.Pointer = SDL.SDL_CreateTexture(renderer.Pointer, SDL.SDL_PIXELFORMAT_ARGB8888, (int)access, w, h);
|
|
if (result.Pointer == IntPtr.Zero)
|
|
{
|
|
throw SdlException.GenerateException();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
internal static Texture FromIntPointer(IntPtr intPtr)
|
|
{
|
|
Texture result = new Texture();
|
|
result.Pointer = intPtr;
|
|
return result;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
SDL.SDL_DestroyTexture(Pointer);
|
|
Pointer = IntPtr.Zero;
|
|
}
|
|
|
|
private bool queryCached;
|
|
private uint queryFormat;
|
|
private int queryAccess, queryW, queryH;
|
|
private void Query()
|
|
{
|
|
if (!queryCached)
|
|
{
|
|
SDL.SDL_QueryTexture(Pointer, out queryFormat, out queryAccess, out queryW, out queryH);
|
|
queryCached = true;
|
|
}
|
|
}
|
|
|
|
public int GetWidth()
|
|
{
|
|
Query();
|
|
return queryW;
|
|
}
|
|
|
|
public int GetHeight()
|
|
{
|
|
Query();
|
|
return queryH;
|
|
}
|
|
|
|
private IntPtr locked;
|
|
private int lockedPitch;
|
|
public void Lock()
|
|
{
|
|
if (locked != IntPtr.Zero)
|
|
throw new InvalidOperationException("Texture already locked");
|
|
|
|
int sdlLockTexture = SDL.SDL_LockTexture(Pointer, IntPtr.Zero, out locked, out lockedPitch);
|
|
if (sdlLockTexture != 0)
|
|
{
|
|
throw SdlException.GenerateException();
|
|
}
|
|
}
|
|
|
|
public void SetPixel(int x, int y, byte a, byte r, byte g, byte b)
|
|
{
|
|
if (y < 0)
|
|
return;
|
|
|
|
if (x < 0)
|
|
return;
|
|
|
|
if (x >= GetWidth())
|
|
return;
|
|
|
|
if (y >= GetHeight())
|
|
return;
|
|
|
|
if (locked == IntPtr.Zero)
|
|
throw new InvalidOperationException("Texture not locked");
|
|
|
|
int bytesPerPixel = lockedPitch / GetWidth();
|
|
|
|
int offset = lockedPitch * y;
|
|
offset += (x * bytesPerPixel);
|
|
|
|
Marshal.WriteByte(locked, offset + 0, b);
|
|
Marshal.WriteByte(locked, offset + 1, g);
|
|
Marshal.WriteByte(locked, offset + 2, r);
|
|
Marshal.WriteByte(locked, offset + 3, a);
|
|
}
|
|
|
|
public void Unlock()
|
|
{
|
|
if (locked == IntPtr.Zero)
|
|
throw new InvalidOperationException("Texture not locked");
|
|
SDL.SDL_UnlockTexture(Pointer);
|
|
locked = IntPtr.Zero;
|
|
lockedPitch = 0;
|
|
}
|
|
|
|
public void SetDrawBlendMode(SDL.SDL_BlendMode mode)
|
|
{
|
|
int i = SDL.SDL_SetTextureBlendMode(Pointer, mode);
|
|
if (i != 0)
|
|
throw SdlException.GenerateException();
|
|
}
|
|
|
|
public Surface LockAsSurface()
|
|
{
|
|
if (locked != IntPtr.Zero)
|
|
throw new InvalidOperationException("Texture already locked");
|
|
|
|
IntPtr surfacePtr;
|
|
if (SDL.SDL_LockTextureToSurface(Pointer, IntPtr.Zero, out surfacePtr) != 0)
|
|
throw SdlException.GenerateException();
|
|
locked = surfacePtr;
|
|
return new Surface(surfacePtr);
|
|
}
|
|
}
|
|
}
|