Sign in to follow this  

Direct3d using a texture for scrolling tile background

This topic is 3592 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am using Beginning Game Programming 2nd Edition by Jonathan Harbour. I would like to change his tile scrolling code to use a texture instead of a surface. The reason being that i would like to have tiles on top of a constant background. A texture is the only way I know of that lets you use transparency. Below I have copied some of the code: TileScrolling.cpp:
//This function updates the scrolling position and speed
void UpdateScrollPosition()
{
    //update horizontal scrolling position and speed
    ScrollX += SpeedX;

    if (ScrollX < 0) 
	{
        ScrollX = 0;
        SpeedX = 0;
	}
    else if (ScrollX > GAMEWORLDWIDTH - WINDOWWIDTH)
	{
        ScrollX = GAMEWORLDWIDTH - WINDOWWIDTH;
        SpeedX = 0;
	}
    
    //update vertical scrolling position and speed
    ScrollY += SpeedY;
    if (ScrollY < 0)
	{
        ScrollY = 0;
        SpeedY = 0;
	}
	else if (ScrollY > GAMEWORLDHEIGHT - WINDOWHEIGHT)
	{
        ScrollY = GAMEWORLDHEIGHT - WINDOWHEIGHT;
        SpeedY = 0;
    }
}

//This function does the real work of drawing a single tile from the 
//source image onto the tile scroll buffer. Parameters provide much 
//flexibility.
void DrawTile(LPDIRECT3DSURFACE9 source,	// source surface image//LPDIRECT3DSURFACE9
				int tilenum,				// tile #
				int width,					// tile width
				int height,					// tile height
				int columns,				// columns of tiles
				LPDIRECT3DSURFACE9 dest,	// destination surface
				int destx,					// destination x
				int desty)					// destination y
{
    
    //create a RECT to describe the source image
    RECT r1;
    r1.left = (tilenum % columns) * width;
    r1.top = (tilenum / columns) * height;
    r1.right = r1.left + width;
    r1.bottom = r1.top + height;
    
    //set destination rect
	RECT r2 = {destx,desty,destx+width,desty+height};
    
    //draw the tile 
    d3ddev->StretchRect(source, &r1, dest, &r2, D3DTEXF_NONE);
                        //draw the arrow

}



//This function fills the tilebuffer with tiles representing
//the current scroll display based on scrollx/scrolly.
void DrawTiles()
{
    int tilex, tiley;
    int columns, rows;
    int x, y;
    int tilenum;
    
    //calculate starting tile position
    tilex = ScrollX / TILEWIDTH;
    tiley = ScrollY / TILEHEIGHT;
    
    //calculate the number of columns and rows
    columns = WINDOWWIDTH / TILEWIDTH;
    rows = WINDOWHEIGHT / TILEHEIGHT;

    //draw tiles onto the scroll buffer surface
    for (y=0; y<=rows; y++)
	{
        for (x=0; x<=columns; x++)
		{
			//retrieve the tile number from this position
            tilenum = MAPDATA[((tiley + y) * MAPWIDTH + (tilex + x))];

			//draw the tile onto the scroll buffer
            DrawTile(tiles,tilenum,TILEWIDTH,TILEHEIGHT,20,scrollbuffer,
                x*TILEWIDTH,y*TILEHEIGHT);
		}
	}
}

//This function draws the portion of the scroll buffer onto the back buffer
//according to the current "partial tile" scroll position.
void DrawScrollWindow()
{
    //calculate the partial sub-tile lines to draw using modulus
    int partialx = ScrollX % TILEWIDTH;
    int partialy = ScrollY % TILEHEIGHT;
    
    //set dimensions of the source image as a rectangle
	RECT r1 = {partialx,partialy,partialx+WINDOWWIDTH,partialy+WINDOWHEIGHT};
        
    //set the destination rectangle
    //This line draws the virtual scroll buffer to the screen exactly as is,
    //without scaling the image to fit the screen. If your screen does not
    //divide evenly with the tiles, then you may want to scale the scroll
    //buffer to fill the entire screen. It's better to use a resolution that
    //divides evenly with your tile size.

    //use this line for scaled display
	//RECT r2 = {0, 0, WINDOWWIDTH-1, WINDOWHEIGHT-1};  
    
    //use this line for non-scaled display
    RECT r2 = {0, 0, SCREENWIDTH-1, SCREENHEIGHT-1};

    //draw the "partial tile" scroll window onto the back buffer
    d3ddev->StretchRect(scrollbuffer, &r1,backbuffer , &r2, D3DTEXF_NONE);
}




Below is the link to a forum thread where this issue was somewhat dealt with, but I had trouble understanding it: DirectX surface to texture colorkeying problem? *SOLVED* The end goal would be to convert the scrollbuffer area that is copied to the backbuffer to a texture. I would then draw this texture onto the screen using the sprite_handler. Thanks for your time and effort. [Edited by - billmason on February 13, 2008 8:47:38 PM]

Share this post


Link to post
Share on other sites
i would suggest loading the tiles into a texture then using the sprite stuff to draw everything. Is that an option for you? i was never able to get the copy from a surface to a texture to work right so i had to go texture / sprite all the way to get the transparecy working.

if so do you know how to load and use the sprites?

Share this post


Link to post
Share on other sites
Yes, it is definetly an option, but the main reason that I did not attempt it is:
1) because I am not completly confident with sprites and textures.
2) I do not know how to copy the tiles to the texture.

All that I know how to do is get a picture file and use it as a texture. I would like to know how to create a texture based on many different texture pieces like a tile engine is supposed to do.

Share this post


Link to post
Share on other sites
You can render to a surface with IDirect3DDevice9::SetRenderTarget() and you can get a surface for a texture with IDirect3DTexture9::GetSurfaceLevel().

Share this post


Link to post
Share on other sites
Thank you, but now I am switching gears and would like to draw tiles to a texture then render the texture.

Another alternative would be to render each tile individually to the screen.

Any suggestions?

Note:I changed the title name.

Share this post


Link to post
Share on other sites
OKay i was never able to get the GetSurfaceLeve(0) stuff to work and got no response to it either so here is what i did.


i have my tile file ( a bitmap or whatever image that is say 256 x 4096 ) my tiles are 64x64 so there are 255 tiles in that one image.

i load it as a testure with :

Tileset = TextureLoader.FromFile(device, @".\Data\Tileset1.bmp", 256, 4096, 0, 0, Microsoft.DirectX.Direct3D.Format.Unknown, Pool.Default, Filter.Point, Filter.Point, Color.Black.ToArgb());

where tileset is a Texture object;

then to draw one tile from it i use :

EKSprite.Draw(Tileset, new Rectangle(0, 0, 64, 64), new Vector3(0, 0, 0), new Vector3(ScreenX, ScreenY, Zlevel), Color.White.ToArgb());

Where EKSprite is my sprite object and ScreenX and ScreenY are the Destination Cords on screen.
now this one draws the first tile at the top left of the image so to draw the next one over

EKSprite.Draw(Tileset, new Rectangle(64, 0, 64, 64), new Vector3(0, 0, 0), new Vector3(ScreenX, ScreenY, Zlevel), Color.White.ToArgb());

This draws the second tile to the right the first 2 numbers in the rectangle are the x and y in the tilset texture (aka in the image)

Note: Zlevel is like -1.0 - +1.0 anything more or less wont show. it is used for sprite stacking eg: what goes on top of others.

does that help? and also i am using sprites alot and they are nice and pretty fast

Share this post


Link to post
Share on other sites
As a previous poster mentioned, use the Sprite interface, that's your best bet :) You just give it a texture and location (which you can change over a timer) and you have your scrolling background.

I hope this helps.
Take care.

Share this post


Link to post
Share on other sites

This topic is 3592 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this