How to Mirror/Reflect/Flip a texture vertially?

Hi,

I've previously developed a small .Net 1.1 application that converts from TGA and DDS files to the native texture files of a game (Dawn of War). The problem is that not everyone wants to then get additional plugins (or can't get plugins) to read the DDS files or convert them to TGAs for editing. Instead, I'm trying to use the DirectX SDK to convert between TGA and DDS (DXT1) without the need for an additional app.

The general conversion is working fine, but because DirectX images don't use the same origin coordinates as TGA images, everything needs flipping vertically. I've tried numerous ways of attempting to flip it, all with no success.

My basic code for loading a TGA and saving as a DDS is:

Texture txtr = null;
PresentParameters pres = new PresentParameters();
pres.Windowed = true;
pres.SwapEffect = SwapEffect.Discard;

Device device = new Device(0,
DeviceType.Hardware, this,
CreateFlags.SoftwareVertexProcessing,
pres);
...
txtr = TextureLoader.FromFile(device, file, 0, 0, 1, Usage.None, Format.Dxt1, Pool.SystemMemory, Filter.Linear, Filter.Linear, 0);
device.SetTexture(0, txtr);
txtr.GenerateMipSubLevels();
TextureLoader.Save(file.Replace(".tga",".dds"), ImageFileFormat.Dds, txtr);



I've tried setting scale matricies with values of "-1" on the World and on Texture0 both before and after the loading and the SetTexture(), I've tried rotating around various axises, I've even tried:

device.Transform.Texture0 = Matrix.Identity * Matrix.Scaling(50,100,0);

And seen no effect at all. If anyone could help and tell me how to just flip a basic texture, I'd appreciate it. The MSDN docs have, so far, been of very little use. Compared to the standard .Net ones they're somewhat bare and all of the tutorials I can find revolve around games/3D worlds.

Thanks


Answer this question

How to Mirror/Reflect/Flip a texture vertially?

  • Help me please

    All of the transforms etc don't actually flip the image, they just flip it when its drawn.

    You h ave a couple of choices:

    1. Load the DDS - draw the DDS to an off screen texture of the same size using the transforms, then save the new texture.

    2. Don't use DirectX - there's probably libraries out there that load DDS and/or TGA into .NEt bitmaps. (You might even be able to convert a texture to a bitmap through streams but I will have to think about that). Then once its in bitmap you can use those interfaces

    3. Open up the texture with unsafe code and copy the pixels to anotehr texture one at a time. You can also do this with unsafe code - use texture.lockrectangle to get an array back. But its likley to be fairly slow depending on the size of your textures.



  • Mike Awai

    I should probably have mentioned unsafe code last. You can totally do it with arrays without any unsafe stuff. You should only drop into unsafe if you need the extra perf. LIke I said it will be noticable on big textures.

  • rak.chaubey

    I'm trying to avoid DevIL. The app currently runs at 170K without DevIL or 1.07MB if I include DevIL (which I currently do to display some TGAs in a PictureBox). As for unsafe code and performance, considering how the app currently composites about half a dozen images in a second on my 3500+ by doing byte array work, I don't think flipping a single image should require the performance boost. Also, even without the performance boost my tool is still much faster than the first tool that someone made for the job, which was written in VB.

    Now to try out the byte flipping and FromStream version :)

    [edit] Yep, all seems good now with the manual byte flipping. It only needs to loop over half of the rows of the texture (temp = bottom row pixel; bottom row pixel = top row pixel; top row pixel = temp; next pixel) and performance seems fine.  I do now have to fix some things with my TGA handling, though, because DirectX actually uses the ID where as Photoshop always left it blank.

    Thanks

  • filippg

    I had another thought, you could use the DevIL librarire to flip the top level mip map and then use DX to generate the others.

  • Krish Srinivasan

    Firstly - oooops, missed a "c" in the title! I'm sure everyone realised I meant vertically :)

    I've tried the DevIL.Net libraries that can load and save both TGA and DDS images, but the DDS images created by the DevIL.Net wrappers don't create the MipMaps that the game needs. Drawing the DDS to an off-screen texture seems sensible, but it seems like the long way round.

    I think I'll go for option three, which was something I was considering anyway. I wasn't planning on doing it in 'unsafe code', but instead loading the TGA in to a byte array and then looping through the rows to put the top rows at the bottom and vica versa, before using the alternate FromStream method. Hopefully that'll work :) I've already got some TGA byte manipulation to covert a set of TGAs in to a single composite image, so it shouldn't be too difficult (in theory).

    I should be able to test it tomorrow, and then I'll get back :)

    Thanks

  • How to Mirror/Reflect/Flip a texture vertially?