2D Map Editor, Loading Tilesets.

Started by
7 comments, last by QuinnJohns 16 years, 1 month ago
I am working on a map editor currently, for future use of some 2d levels, for random purposes. The sprites will be displayed using D3DXSprite Tiles. I want to thank anyone helping me learn to improve my knowledge of Direct3D. Three Questions: 1) Would it be ideal to lay my sprites on my tileset, to be something like 4-rows, 4-colums, as an example - or does the number of tiles per row and column matter? I've got like a 2 row of 8, 1 row of 7 kind of thing going on right now? 2) Secondly, is there a way to predetermine the number of rows and columns and not hard coding it, when loading a tileset in my own editor for example? ie. Somehow detect if the cell is empty on my file format (.bmp, .jpg, etc), and therefore, stop creating additional sprites on my available tilesets. So I don't waste memory? How do I negate a blank placeholder for something such as a sky, if that is possible? 3) How do I load/save my maps, into my own particular file format/extension? Is there a standard Win32 function? or anything of that nature?
[size="2"][size="1"][size="2"]- Quinn
[size="2"][size="1"][size="2"]Software Developer, Mintrus
Advertisement
3) 'GetOpenFilename()' - Is that the option I'm liking for to open the files? I believe I'm looking in the right direction on that question, going to do some research while waiting for anyone to respond here in these early, early hours of the day. I wonder about the saving dialog... probably something similar in syntax... Yep, GetOpenFileName(), GetSaveFileName(), are what I am looking for, I believe. Has anyone run into any shortfalls, with these calls? better options?
[size="2"][size="1"][size="2"]- Quinn
[size="2"][size="1"][size="2"]Software Developer, Mintrus
1- I think it would be better to have the image square, in your case 4x4. Because some hardware don't support non power of 2 textures. But since you're loading them into individual tiles, I don't think it matters that much.

2- You could fill the blank tiles with a color you wouldn't use in your tileset (eg. magenta or cyan). When loading the tiles, read the first pixel of the corresponding tile to check whether it's blank. Another way would be to store the number of tiles in another file.

3- There are a couple of articles here describing how you could create your own format. Its up to you to decide how you arrange the information you wanna store.

Map File Format

Resource files explained

Not sure if these articles are relevant though, but it might give you an idea.

The functions GetOpenFileName() & GetSaveFileName() are used for getting input from the user and return a filepath. They won't write any files on their own.
Quote:Original post by vrihai
1- I think it would be better to have the image square, in your case 4x4. Because some hardware don't support non power of 2 textures. But since you're loading them into individual tiles, I don't think it matters that much.


The textures I am using are powers of 2, but I am referring to my actual grid. I am loading in a tileset, of 16x16 textures, resulting in 38 total textures, which currently, I have seperated by a 1-pixel division, between each, for the sake of D3DSprite, to keep from having my textures running together. Regardless, currently, my premade grid that I put all my tiles into, for use in my editor, runs about 30 textures on my top row of the grid and 6, on the next row, and I don't know if that matters, or if I should make it more uniform like a 6 x 6 instead?

Quote:Original post by vrihai
2- You could fill the blank tiles with a color you wouldn't use in your tileset (eg. magenta or cyan). When loading the tiles, read the first pixel of the corresponding tile to check whether it's blank. Another way would be to store the number of tiles in another file.


Well, in my original post, I presumed that as being an option. I guess I could use a filler color on my last tile, other than what is being utilized as my 'blank' tile, for the sake, of having a blank tile for random purposes. Is there a way to reference a D3DXSprite's color palette to see if it is exclusively one color? is there something similar to GetPixel(), for GDI?

Quote:Original post by vrihai
The functions GetOpenFileName() & GetSaveFileName() are used for getting input from the user and return a filepath. They won't write any files on their own.


GetOpenFileName(), would be presumably be good - when it comes to loading the tileset images, because I can locate the file, get the filepath, and then correlate that with where the image is located, to extract the tiles. Sounds ok, right?
[size="2"][size="1"][size="2"]- Quinn
[size="2"][size="1"][size="2"]Software Developer, Mintrus
I would highly recommend you use an image library like CxImage.

http://www.codeproject.com/KB/graphics/cximage.aspx

This makes handling images a lot easier, as you can loop through pixels and obtain the width and height of the image.

Your method of having separate images for each tile imo is the right method to use. You save memory because usually tiles are 32x32 or 64x64...which is a native size for direct X. Also, if you render with quads, you dont have to worry about the edges of the tiles 'bleeding' if you transform the screen (such as rotate or zoom)

Also, it means people can use more than 1 tileset for their levels..and if the entire tileset isnt used then you dont need to load those unused tiles into direct x.

Anyways... one tip if you decide to use CxImage..it takes the y co-ordinate from the bottom of the image. Thats caused me a few headaches in the past.

When your done with your CxImage...heres a way you can load it into directx:

CxImage& cx
BYTE *buffer = 0;
long size;
cx.Encode(buffer,size,CXIMAGE_FORMAT_PNG);

Call a function such as D3DXCreateTextureFromFileInMemory

cx.FreeMemory(buffer);

I use the format png as it will maintain the alpha channel in the tileset (if it has one)

Good luck :)



I don't think it matters how you lay it out on your grid, unless you're talking about wasted memory in blank space. If you're loading each tile into and individual texture, no memory will be wasted, but if they're all loaded into a single texture, I'm guessing performance would be better.

The only way to read the individual pixels appears to be Locking the surface, using the LockRect() function to gain access to the individual bytes of the texture.
Thanks Vrihai, I'll take a look into that function.

Quote:
Original post by David Clark
I would highly recommend you use an image library like CxImage.

http://www.codeproject.com/KB/graphics/cximage.aspx

This makes handling images a lot easier, as you can loop through pixels and obtain the width and height of the image.

Your method of having separate images for each tile imo is the right method to use. You save memory because usually tiles are 32x32 or 64x64...which is a native size for direct X. Also, if you render with quads, you dont have to worry about the edges of the tiles 'bleeding' if you transform the screen (such as rotate or zoom)

Also, it means people can use more than 1 tileset for their levels..and if the entire tileset isnt used then you dont need to load those unused tiles into direct x.

Anyways... one tip if you decide to use CxImage..it takes the y co-ordinate from the bottom of the image. Thats caused me a few headaches in the past.

When your done with your CxImage...heres a way you can load it into directx:

CxImage& cx
BYTE *buffer = 0;
long size;
cx.Encode(buffer,size,CXIMAGE_FORMAT_PNG);

Call a function such as D3DXCreateTextureFromFileInMemory

cx.FreeMemory(buffer);

I use the format png as it will maintain the alpha channel in the tileset (if it has one)

Good luck :)


I appreciate the advice, but the point of my tool, is to learn how to accomplish something, that way I wholely understand the concepts behind a lib such as that. So yeah, I may be reinventing the wheel, but I'm also broadening my knowledge. :) Thanks for the suggestion though.

[size="2"][size="1"][size="2"]- Quinn
[size="2"][size="1"][size="2"]Software Developer, Mintrus
Quote:Original post by QuinnJohns
3) 'GetOpenFilename()' - Is that the option I'm liking for to open the files? I believe I'm looking in the right direction on that question, going to do some research while waiting for anyone to respond here in these early, early hours of the day. I wonder about the saving dialog... probably something similar in syntax... Yep, GetOpenFileName(), GetSaveFileName(), are what I am looking for, I believe. Has anyone run into any shortfalls, with these calls? better options?


They are most definitely the standard way of doing what you want to do. They're nice because usually get you exactly the information you need (the path of a file the user wants to load or save to), and let you present a dialog that should be very familiar to the user. If you do need to customize the dialog a bit you can do so by hooking the dialog procedure.

As for looking at your texture to see if there are "blank tiles", if you want to use GDI functions (like GetPixel) to look at the texture you can get a DC from the texture's surface. It will probably be dog slow and the texture has to be one of the formats that GDI can work with (they're described in the SDK documentation for IDirect3DSurface9::GetDC), but if you're just doing this at load time in your map editor the speed shouldn't be a problem at all. Otherwise there's always the standard way of peeking at a texture, which is to use IDirect3DSurface9::LockRect and simply access the data directly.
Thanks MJP,

I'm familiar with GetPixel(), I used it for a project I did in an AI class for my old school, where I had a car, driving itself on a street, covered in large rocks, the car scanned the pixels ahead and on the sides to ensure it was capable of moving, without hitting something, and it worked perfectly. Until now, I didn't realize I could pull the DC from DirectX, until you showed me the IDirect3DSurface9::GetDC() call, just now. So thanks much, for that.

Would you recommend LockRect() over GetPixel(), when it comes to examining the entire 16x16 texture to see if it is entirely one color? versus just checking one pixel? in happenstance that one texture actually did have such a same pixel in the 1x1 location of that 16x16 texture.

Thanks.
[size="2"][size="1"][size="2"]- Quinn
[size="2"][size="1"][size="2"]Software Developer, Mintrus

This topic is closed to new replies.

Advertisement