Closed feliwir closed 6 years ago
Sure I see no reason why this feature wouldn't be possible. I myself might be interested in this feature too, I just lack the know how. Since I don't have sufficient knowledge, I have a couple questions:
How do you envision the resulting API? Right now it is a single call to Load
, but it sounds like to support the GPU this will probably change.
Is it possible that to support a generic interface, so that opencl, cuda, etc, can use it? Maybe some image formats this is possible, while others it is not?
Let me know what you're thinking
I suppose it is also possible to create specialized subprojects like Pfim.OpenCL
or Pfim.Cuda
I was attempting to use OpenTK, since gpu's these days have fixed functions to decode dds compressed data. The call for this is glCompressedImage2D (see here: http://users.telenet.be/tfautre/softdev/ddsload/explanation.htm). So what does need to be exposed to the user:
A project which does this really well (in C++) is gli: https://github.com/g-truc/gli/blob/master/gli/core/load_dds.inl
I think opentk has an example for this aswell somewhere. A general note: writing a decoder in Cuda/OpenCL is slower than using the OpenGL function. All it needs as parameters is the compressed data and format
So, would the optimal solution be a C# interface on GLI? :smile:
Nah, it would be optimal if I could just access the compressed data :)
@nickbabcock Curious, was this issue solved?
@Krakean, no this issue is still outstanding. If you have an example or resources on how to decode dds or tga images on the gpu (from compressed texture data) in C#, I may take a look so I can properly test an implementation.
@nickbabcock Take a look here please - https://github.com/OpenSAGE/OpenSAGE/blob/master/src/OpenSage.Game/Data/Dds/DdsFile.cs This is how it used - https://github.com/OpenSAGE/OpenSAGE/blob/master/src/OpenSage.Game/Content/TextureLoader.cs
Not sure, but may be it can help you a bit
Thanks for the links! It looks like OpenSAGE is using veldrid. So I'll have to check that project out.
hey @nickbabcock I am a member of OpenSage. There is no need for you to implement the gpu decoding of in Pfim. Since there are multiple graphics backends that can dds decoding it’s the best approach if you make the compressed dds data available (so the user of Pfim can upload that to the gpu in whichever manner he likes). Since you already have the software dds decoder in place it shouldn’t be too much effort to turn off the decoding (if specified) and access the compressed data.
Right, right -- yeah my wording came off a bit wrong. Pfim wouldn't touch the body, but I needed to see how OpenSAGE used veldrid so that I can take make sure the interop is good (eg. so I can add an example to docs, etc)
I think if the compressed data is exposed as a simple byte[], then we can use “fixed” to copy it to a Veldrid (or whatever) texture in a reasonably performant manner.
So I was playing around with veldrid and veldrid.ImageSharp to get a feel for the APIs. I wanted to display a jpg in a window and I'm ashamed to say that I haven't been able to figure it out 😊
I set everything up
Sdl2Window window = VeldridStartup.CreateWindow(ref windowCI);
GraphicsDevice gd = VeldridStartup.CreateGraphicsDevice(window);
ImageSharpTexture sharpTexture = new ImageSharpTexture(@"my.jpg", false);
Texture texture = sharpTexture.CreateDeviceTexture(gd, gd.ResourceFactory);
CommandList commandList = gd.ResourceFactory.CreateCommandList();
and have a draw function
private static void Draw(GraphicsDevice gd, CommandList cl, Texture texture)
{
// But where to use texture?
cl.Begin();
cl.SetFramebuffer(gd.SwapchainFramebuffer);
cl.SetFullViewports();
cl.End();
gd.SubmitCommands(cl);
gd.SwapBuffers();
gd.WaitForIdle();
}
But since I can't figure out to send the texture to the screen, it's blank!
I tried following OpenSage's DrawingContext2D
down to SpriteBatch
but I couldn't tell how it's rendered onscreen. If anyone knows what I'm missing, it'd be greatly appreciated 😄
@nickbabcock Veldrid is a very low-level API, so you have to set up quite a few things in order to draw a textured object. There is a sample project that shows how to draw a textured cube. Drawing a 2D textured square is a little simpler. Feel free to reach out if you try it and get stuck.
Yeah maybe I'm trying to bite off more than I can chew, as I have very limited prior experience with 3D graphics. My end goal is to demonstrate loading a dds image and give the user a choice of decoding on the gpu / cpu. Technically nothing needs to be displayed, but I would like to verify the sample code's correct! I don't have to use veldrid -- and I wouldn't want veldrid to hand hold me from 0 to 60. However I show a sample of gpu image decoding would be a win in my book.
I really should look up the difference between vertex and index buffers 😝
It's been a long time waiting, but below is an example of loading DDS without decompressing the block compressed images:
var data = File.ReadAllBytes(path);
var image = Dds.Create(data, new PfimConfig());
var image2 = Dds.Create(data, new PfimConfig(decompress: false));
Assert.False(image.Compressed);
Assert.True(image2.Compressed);
Assert.NotEqual(image.Data, image2.Data);
Assert.Equal(image.Format, image2.Format);
image2.Decompress();
Assert.Equal(image.Data, image2.Data);
If you don't want the cpu decompression, you can figure out the BC algo with
if (image2.Header.PixelFormat.FourCC == CompressionAlgorithm.D3DFMT_DXT3)
{
}
This functionality will be in the next release (TBD), and I'm assuming that sooner rather than later is preferred.
This feature has been included as part of 0.5.1, feel free to try it and suggest improvements.
Hello, first of all this is a very nice library (exactly what i was looking for). But would it be possible to add loading of dds images without uncompressing them, so i can do that on the gpu? Would be a really neat feature for developing with opentk and stuff