protected unsafe void CreateFromSurface(IntPtr surfacep, uint glformat) { Sdl.Surface *surface = (Sdl.Surface *)surfacep; this.width = (uint)surface->w; this.height = (uint)surface->h; if (!IsPowerOf2(width) || !IsPowerOf2(height)) { throw new Exception("Texture size must be power of 2"); } GlUtil.Assert("before creating texture"); CreateTexture(); try { gl.BindTexture(gl.TEXTURE_2D, handle); uint surface_format = SetupPixelFormat(surfacep); gl.TexImage2D(gl.TEXTURE_2D, 0, (int)glformat, (int)width, (int)height, 0, surface_format, gl.UNSIGNED_BYTE, surface->pixels); GlUtil.Assert("creating texture (too big?)"); SetTextureParams(); } catch (Exception) { uint[] handles = { handle }; gl.DeleteTextures(1, handles); throw; } }
public unsafe void copy_to(IntPtr surfacep, uint surface_x, uint surface_y, uint texture_x, uint texture_y, uint width, uint height) { Sdl.Surface *surface = (Sdl.Surface *)surfacep; PixelFormat *format = (PixelFormat *)surface->format; GlUtil.Assert("Before update texture"); uint surface_format = SetupPixelFormat(surfacep); /* We're extracting sub rectangles from the SDL_Surface pixeldata, by * setting the pitch to the real width, but telling OpenGL just our * desired image dimensions. */ IntPtr pixeldata = (IntPtr) (((byte *)surface->pixels) + surface_y * surface->pitch + format->BytesPerPixel * surface_x); gl.TexSubImage2D(gl.TEXTURE_2D, 0, (int)texture_x, (int)texture_y, (int)width, (int)height, surface_format, gl.UNSIGNED_BYTE, pixeldata); GlUtil.Assert("Updating Texture Part"); }
private static unsafe uint SetupPixelFormat(IntPtr surfacep) { Sdl.Surface *surface = (Sdl.Surface *)surfacep; PixelFormat *format = (PixelFormat *)surface->format; uint glformat; if (format->BytesPerPixel == 3) { glformat = gl.RGB; } else if (format->BytesPerPixel == 4) { glformat = gl.RGBA; } else { throw new Exception("Surface format not supported (only 24 and 32BPP modes supported at the moment)"); } gl.PixelStorei(gl.UNPACK_ALIGNMENT, 1); gl.PixelStorei(gl.UNPACK_ROW_LENGTH, surface->pitch / format->BytesPerPixel); return(glformat); }
private unsafe void Create(IntPtr sdlsurface) { Sdl.Surface *surface = (Sdl.Surface *)sdlsurface; uint width = NextPowerOfTwo((uint)surface->w); uint height = NextPowerOfTwo((uint)surface->h); IntPtr pixelbufferp; if (BitConverter.IsLittleEndian) { pixelbufferp = SDL.CreateRGBSurface(SDL.SWSURFACE, (int)width, (int)height, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); } else { pixelbufferp = SDL.CreateRGBSurface(SDL.SWSURFACE, (int)width, (int)height, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff); } if (pixelbufferp == IntPtr.Zero) { throw new Exception("Couldn't create surface texture (out of memory?)"); } try { SDL.SetAlpha(sdlsurface, 0, 0); SDL.BlitSurface(sdlsurface, IntPtr.Zero, pixelbufferp, IntPtr.Zero); CreateFromSurface(pixelbufferp, gl.RGBA); } finally { SDL.FreeSurface(pixelbufferp); } ImageWidth = (float)surface->w; ImageHeight = (float)surface->h; }