Skip to main content
GameDev.net gamedev.net
🔒 Locked

Implementing horizontal scrolling

Started by edd1986 Mar 31, 2007 at 8:14 AM 12 replies 2.7k views
Original Post
edd1986
edd1986
Hiya, I'm playing about trying to make a horizontal scrolling game. The background texture I have is quite a bit smaller than the screen. What I would like to do is have it so it is stretched to fit the screen and will scroll and repeat horizontally. I think I understand the principles but am having a bit of trouble implementing (I have been using the excellent site http://www.toymaker.info/Games/html/2d_scrolling.html ) The example in the link above is a vertical scroller and the texture stretches to fit the size of the screen. In my application I have got so far as loading the background texture and have it scroll correctly, it does not however stretch to fit the screen. Here's a comparision between the example program and mine: Free Image Hosting at www.ImageShack.us Free Image Hosting at www.ImageShack.us The code I have for rendering the background is basically lifted off the website above, but I have been tinkering it so it scrolls horizontally rather than vertically so I'm a bit unsure why my program isn't working as per the example. Here is my background rendering code:

	//render background
	RECT rct;
	rct.top = 0;
	rct.bottom = screenHeight;

	D3DXVECTOR3 pos(0,0,0);

	g_pDXSpriteBackground->Begin(0);		

	// left sprite		
	rct.left=textureWidth-offset;
	rct.right=textureWidth;
		
	g_pDXSpriteBackground->Draw(g_pBackTexture, &rct, NULL,&pos,0xFFFFFFFF);

	//right sprite
	rct.left=0;
	rct.right=screenWidth - offset;
	rct.top = 0;
	rct.bottom = screenHeight;
	pos.x=(float)offset;

	g_pDXSpriteBackground->Draw(g_pBackTexture, &rct, NULL,&pos,0xFFFFFFFF);

	// Done
	g_pDXSpriteBackground->End();

	//update offset
	offset--;
	if (offset< 0)
		offset=textureWidth;


Does anyone have any ideas? Thanks in advance
Sc4Freak
Sc4Freak
Setting the pSrcRect parameter in the Draw function does not cause the texture to stretch. Instead, it causes the texture to be sampled outside of its bounds, causing the image you see in your program (by default the texture address mode is set to clamp IIRC).

To resize or rotate sprites, you need to generate a transformation matrix and send it to ID3DXSprite using the SetTransform() function.
edd1986
edd1986
Thanks for the quick reply. In the example code I have been learning from there are no matrix transformations though, rather when the app is resized the texture is stretched/shrunk appropriately. I can't see anything obvious in the code as to why this might be, any ideas?

Using the matrix transform idea, would it simply be a case of scaling the image as soon as it is loaded (my program is fullscreen) and then using that?

Thanks
edd1986
edd1986
Hi, again, scaling the sprite has indeed worked, just one more little problem though, when the end of texture has been reached and it is looping around the screen is blurring for a second before the texture becomes smooth again:

Free Image Hosting at www.ImageShack.us

Any ideas?

Thanks
Headkaze
Headkaze
Looks like your texture is set to D3DTADDRESS_BORDER so outside 0.0 and 1.0 becomes the border color. Try setting to D3DTADDRESS_WRAP or D3DTADDRESS_MIRROR.
edd1986
edd1986
Hi and thanks, I am fairly new to DX so am not sure if this is what you meant, I set the following line:

g_pd3dDevice->SetSamplerState(0,D3DSAMP_ADDRESSV,D3DTADDRESS_MIRROR)

However the black at the bottom remains (not so fussed about this, I'm more concerned about the blurring that appears in the screenshot for a couple of seconds )
redas
redas
try to set both: horizontal and vertical (uv) address modes

g_pd3dDevice->SetSamplerState(0,D3DSAMP_ADDRESSU,D3DTADDRESS_MIRROR)
g_pd3dDevice->SetSamplerState(0,D3DSAMP_ADDRESSV,D3DTADDRESS_MIRROR)
edd1986
edd1986
Same problems persist
edd1986
edd1986
Hi again - after some tinkering am still getting the same trouble. Here is the rendering and background loading code, if anyone could take a quick look:

Rendering:
g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);	g_pd3dDevice->SetSamplerState(0,D3DSAMP_ADDRESSU,D3DTADDRESS_MIRROR);	g_pd3dDevice->SetSamplerState(0,D3DSAMP_ADDRESSV,D3DTADDRESS_MIRROR);    // Render scene	g_pd3dDevice->BeginScene();	//render background	RECT rct;	//rct.left=0;	//rct.right=textureWidth;		rct.top = 0;	rct.bottom = textureHeight;	D3DXVECTOR3 pos(0,0,0);	// Draw sprite	g_pDXSpriteBackground->Begin(0);			// left sprite			rct.left=textureWidth-offset;	rct.right=textureWidth;			g_pDXSpriteBackground->Draw(g_pBackTexture, &rct, NULL,&pos,0xFFFFFFFF);	//right sprite	rct.left=0;	rct.right=screenWidth - offset;		pos.x=(float)offset;	g_pDXSpriteBackground->Draw(g_pBackTexture, &rct, NULL,&pos,0xFFFFFFFF);	// Done	g_pDXSpriteBackground->End();	//update offset	offset--;	if (offset< 0)		offset=textureWidth;


Loading:

bool CreateBackground(){	if (FAILED(D3DXCreateSprite(g_pd3dDevice,&g_pDXSpriteBackground)))		return false;	if (FAILED(D3DXCreateTextureFromFile(g_pd3dDevice,"suburbs.dds",&g_pBackTexture)))		return false;	// Get the dimensions of our txture	D3DSURFACE_DESC desc;	g_pBackTexture->GetLevelDesc(0,&desc);	textureWidth=desc.Width;	textureHeight=desc.Height;	return true;}


The view scrolls fine for what appears to be the time taken to scroll through the texture twice, then for a couple of seconds the right hand section becomes fuzzy (as per the screenshot above) before the texture is viewed normally again. Any ideas?

Thanks
redas
redas
Do you have lines in your render loop such these

d3dDevice->Clear(bla bla bla);d3dDevice->BeginScene()Sprite->Draw(bla bla bla);//something hereSprite->End();//I mean these two linesd3dDevice->EndScene();d3dDevice->Present(NULL, NULL, NULL, NULL);
edd1986
edd1986
Hiya, yeah I do, it's not in the code above because I also have code to render another sprite which I didn't include
redas
redas
I am not sure but maybe sprite doesn't reapet image and setting these

g_pd3dDevice->SetSamplerState(0,D3DSAMP_ADDRESSU,D3DTADDRESS_MIRROR)g_pd3dDevice->SetSamplerState(0,D3DSAMP_ADDRESSV,D3DTADDRESS_MIRROR)

makes no different


If I am right than you should try make your scrolling background with quads not sprites or try do it with sprites like this

Lets imagine that your background image width is the same as screen width (640 for examle) then first step whould be to craete double tiled image

Thats how your backgroun.bmp shoul look
Note: Whole immage size must be power off 2
(Nearest number power off 2 for double tiled 640x2 = 1280 image is 2048)
               2048px*----------------------------------*|X       X|X       X|              |1| X     X | X     X |   The black  |0|  X   X  |  X   X  |     area     |2| X     X | X     X |              |4|X       X|X       X|              |px*----------------------------------*  1 tile     2 tile


Now the rect area for sprite shoul be calculated like this (It looks correct on paper)

RECT rect;

rect.left = offset%screen_width;
rect.right = rect.left + screen_width;
MasterWorks
MasterWorks
Quote:
Original post by redas
Note: Whole immage size must be power off 2
(Nearest number power off 2 for double tiled 640x2 = 1280 image is 2048)

The cool thing about D3D is you dont have to worry about pixels in your rendering code. Whether your texture is 1024 pixels, 2048 pixels, or 32 pixels wide, the results should be the same; only the quality of the output is affected, since texture coordinates address percentages and not pixels.

I would much prefer to mildly stretch a 1024 pixel texture than use a texture that is way too large.

edd1986
edd1986
Thanks for the post redas, I have managed to solve it, a little trial and error did it :)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.