Skip to main content
gamedev.net
🔒 Locked

C# Image Library

Started by Ibasa 1 reply 4.9k views
Original Post
Ibasa
Ibasa
I'm currently in the process of writing a game in C#, im using slimDX and have a small project set up to try things out in dx10, one of things this project does (and later my game and tools will need to do) is load image files. Using .NET you can load bitmaps with the Bitmap class but that didnt like loading my RGBA bitmaps! And only loads a few image types! The common suggestion on the here and around the rest of the interwebs seems to be use a wrapper around a C or C++ image library like devIL. Problem with that is, firstly P/Invoke (slow!) and secondly a lot are designed around a C interface (and theres more differance between C# and C/C++ than just the syntax). So I've started programming my own image library in pure C#. The 4 Main classes are: ImageFile - Interface to load and save files (eg BMPFile) Image - Class to get and set pixels (RGBA float,uint or int) Resource - Collection of Subresources Subresource - Base class to store pixels in byte format (eg R8G8B8A8), can convert to and from Image The library can be extended by creating new ImageFile classes or Subresource class and just registering them in (Uses named factory pattern). An example of the library being used with slimDX, loading a bmp, generating mipmaps (point filter), and then creating a DirectX10 texture:


SlimDX.Direct3D10.ShaderResourceView CreateTexture(SharpIL.Resource resource)
{
    SlimDX.DataRectangle[] data = new SlimDX.DataRectangle[resource.SubresourceCount];

    for(int i=0; i<data.Length; ++i)
    {
        SlimDX.DataStream stream = new SlimDX.DataStream(resource.Volume, true, true);
        stream.WriteRange(resource.Data);
        stream.Position = 0;
        data = new SlimDX.DataRectangle(resource.Pitch, stream);
    }

    SlimDX.Direct3D10.Texture2DDescription desc = new SlimDX.Direct3D10.Texture2DDescription()
    {
        BindFlags = SlimDX.Direct3D10.BindFlags.ShaderResource,
        CpuAccessFlags = SlimDX.Direct3D10.CpuAccessFlags.None,
        Format = DXGIFormatFromILFormat(resource.Format),
        ArraySize = resource.ArraySize,
        Height = resource.Width,
        Width = resource.Height,
        MipLevels = resource.MipLevels,
        SampleDescription = new SlimDX.DXGI.SampleDescription(1, 0),
        OptionFlags = SlimDX.Direct3D10.ResourceOptionFlags.None,
        Usage = SlimDX.Direct3D10.ResourceUsage.Immutable
    };
    SlimDX.Direct3D10.Texture2D texture = new SlimDX.Direct3D10.Texture2D(
        device, desc, data);

    return new SlimDX.Direct3D10.ShaderResourceView(device, texture);
}


void UpdateDiffuse()
{
    SharpIL.Image image = SharpIL.Resource.Load("../../DiffuseMap.bmp").ToImage();

    SharpIL.Resource rgbaResource = new SharpIL.Resource(image.Width, image.Height, 1, 0, 1, "R8G8B8A8");
				
    for(int i=0; i<rgbaResource.MipLevels; ++i)
    {
        SharpIL.Image mip = new SharpIL.Image(rgbaResource.Width, rgbaResource.Height, 1, PixelType.UInt);
				
        int xscale = image.Width/mip.Width;
        int yscale = image.Height/mip.Height;
				
        for(int y=0; y<mip.Height; ++y)
        {
            for(int x=0; y<mip.Width; ++x)
            {
                UPixel pix = image.GetUPixel(x*xscale, y*scale, 0);
                mip.SetUPixel(x,y,pix);
            }
        }
				
        rgbaResource.FromImage(mip);
    }

    try
    {
        SlimDX.Direct3D10.ShaderResourceView newView = CreateTexture(rgbaResource);

        if (specMap != null)
            specMap.Dispose();
        specMap = newView;
        System.Diagnostics.Debug.WriteLine("Diffuse texture compiled");
        }
        catch
        {
            System.Diagnostics.Debug.WriteLine("Diffuse texture didnt compile.");
        }
}

Thoughts? Am I being silly and should just go back to devIL? What would make this a usefull library to you? Any questions? Thank you for you time :) edit - I suck at source tags :( [Edited by - Ibasa on February 27, 2009 9:11:52 AM]
bubu LV
bubu LV
I have no problems loading RGBA images from PNG and BMP formats with System.Drawing. Can you show your code that doesn't work?

And I wouldn't say that P/Invoke is slow - I'm using it for OpenGL, Newton, and various other native libraries. Of course it is slower than native code. But not slow.

I think that pure .NET library will be slower than P/Invoke to native image loading library or System.Drawing.
Mike.Popoloski
Mike.Popoloski
Maybe I'm missing something, but why can't you let DirectX do the image loading? D3DX (and SlimDX) support loading .bmp, .dds, .dib, .hdr, .jpg, .pfm, .png, .ppm, and .tga.
Mike Popoloski | Journal | SlimDX

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.