DirectX && C++: Problems with Copying Tiles [resolved]

Started by
5 comments, last by v0dKA 19 years, 7 months ago
Something weird happens when I try to paint my (at this point) mini-world. Firstly, tiles have space in between them, and secondly, the program doesn't copy the right pixels from the tileset. Here's (an attempt at) a picture to demonstrate what I mean: The left of the picture (minus the text) is the screen shot. The top right shows the tileset. Tough to see, but all tiles are surrounded by a yellow outline. That means a yellow outline should surround each tile drawn in the game. The yellow outline is only sometimes seen in the actual game. Also, the spaces between the tiles are a problem. They're supposed to be tightly next to each other without those spaces. To draw the tiles, I use DirectX in a simple sort of way. Instead of making verteces and triangles and world matrices, I use the CopyRects() method. The part that probably messes up is the source rectangle coords and perhaps the destination point, even though I can see nothing wrong with either when I run line by line. The tilesize is 32x32 (in here anyways - my code supports any even tilesizes within a specific range). I create a tile surface 256x256 (even though the image is smaller - that's not a bad thing, is it?). The tile surface holds the entire tileset. Then I CopyRects() from the tile surface to the back buffer. Here's the code responsible for the painting:

////////////////////////////////
// PlaceTile()
////////////////////////////////
HRESULT CEngine::PlaceTile( IDirect3DSurface8* pBackBuffer,
IDirect3DSurface8* pTileSurface, int TileNumber, int DstCol,
 int DstRow, int numTileCols, int numMapCols, int tileSize,
int xOffset, int yOffset )
{
	RECT SrcTileRect;
	POINT DstPoint;
	SrcTileRect.left = TileNumber2SourceX( TileNumber, numTileCols,
		tileSize );
	SrcTileRect.right = SrcTileRect.left + tileSize - 1;
	SrcTileRect.top = TileNumber2SourceY( TileNumber, numTileCols,
		tileSize );
	SrcTileRect.bottom = SrcTileRect.top + tileSize - 1;
	DstPoint.x = Column2X( DstCol, tileSize, numMapCols ) + xOffset;
	DstPoint.y = Row2Y( DstRow, tileSize ) + yOffset;




	HRESULT hResult( m_Direct3D.GetDevice()->CopyRects( pTileSurface,
		&SrcTileRect, 1, pBackBuffer, &DstPoint ) );


	return hResult;
}






Anyways, like I said, I see nothing wrong with the code. For the first tile to draw, here are some significant values: SrcTileRect.Top = 0 SrcTileRect.Bottom = 31 SrcTileRect.Left = 64 SrcTileRect.Right = 95 DstPoint.x = 16 DstPoint.y = 12 Here's for the second tile: SrcTileRect.Top = 0 SrcTileRect.Bottom = 31 SrcTileRect.Left = 0 SrcTileRect.Right = 31 DstPoint.x = 48 DstPoint.y = 12 Does anyone notice anything odd here? This has been [lame]bugging me[/lame] (heh... get it? "Bugging me"? eh? Eh? EH!?) for weeks. [Edited by - v0dKA on September 18, 2004 12:41:06 PM]
.:<<-v0d[KA]->>:.
Advertisement
I'm pretty sure you have to include one extra pixel in the right and bottom coordinates.

DirectX (and GDI) usually use inclusive-exclusive coord pairs.

In your case:

SrcTileRect.Top = 0SrcTileRect.Bottom = 32SrcTileRect.Left = 64SrcTileRect.Right = 96DstPoint.x = 16DstPoint.y = 12SrcTileRect.Top = 0SrcTileRect.Bottom = 32SrcTileRect.Left = 0SrcTileRect.Right = 32DstPoint.x = 48DstPoint.y = 12


This extra pixel will not be copied, but if you don't add it the rect will appear stretched (or too small).

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

OK, I updated it as Endurion said, but now it's even weirder. On the left is what I'm trying to draw, and on the right is what's actually drawn:



I have no idea where it gets those green extra pixels from! THe only green in the tileset is for that one tile I'm trying to draw, so it can't be from the neighbor tile. What's going wrong?
.:<<-v0d[KA]->>:.
Hmm, the docs for CopyRects say no stretching is being done.

When you say, you're using a 256x256 surface, is the original image 256x256 also or smaller? If you're using D3DXCreateTextureFromFile or similar you might get the image stretched. If that's the case try D3DXCreateTextureFromFileEx and use D3DX_FILTER_NONE for the filter flags so no stretching is done.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Quote:Original post by Endurion
Hmm, the docs for CopyRects say no stretching is being done.

When you say, you're using a 256x256 surface, is the original image 256x256 also or smaller? If you're using D3DXCreateTextureFromFile or similar you might get the image stretched. If that's the case try D3DXCreateTextureFromFileEx and use D3DX_FILTER_NONE for the filter flags so no stretching is done.


The tileset image is smaller.
I'm not using "create" texture, I'm using "load" texture. Here's the loading code:

hResult = m_pD3DDevice->CreateImageSurface( 256, 256,		D3DFMT_X8R8G8B8, &m_pCurrentTileSet );// Error check snippedhResult = D3DXLoadSurfaceFromFile( m_pCurrentTileSet,		NULL, NULL, filename, NULL, D3DX_DEFAULT, 0, NULL );//Error check snipped
.:<<-v0d[KA]->>:.
With D3DXLoadSurfaceFromFile the same applies. When both rects are set to NULL it will stretch the loaded image to the full surface. Try to either supply the right RECT for destination or use D3DX_FILTER_NONE for the filter.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

.:<<-v0d[KA]->>:.

This topic is closed to new replies.

Advertisement