Sign in to follow this  
the_moo

how to "stretch" textures in direct3d

Recommended Posts

hey all, unfortunately direct3d is not being kind to me now. i've got a system set up where i can render textures to the screen provided they are not scaled, or are scaled by a number (i.e. set scale to 2 and it doubles the size). however, i want to also be able to "stretch" a texture just by knowing how far it needs to be stretched (so scaling doesn't help). also, ive tried using the scaling method in a few ways that should act like stretching the right distance but they didnt work. so basically, i know the top left point of the texture, and i know how long and high it should be (so say the coordinates are: 0,0,50,10 and the texture is 30x10 pixels - the texture needs to be stretched 20 pixels), i ask, how can i make this sort of "stretching" work? here's the code i've got that i thought would work:
D3DTLVERTEX verts[4] =
{
	// x, y, z, rhw, colour, tu, tv
	{ left,  top,    z, rhw, colour, 0, 0 },
	{ right, top,    z, rhw, colour, 1, 0 },
	{ right, bottom, z, rhw, colour, 1, 1 },
	{ left,  bottom, z, rhw, colour, 0, 1 }
};
D3DDevice->SetTexture(0, texture);
D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(D3DTLVERTEX));


so i pretty much put the coordinates into those "left, right", etc. and i thought it should've aligned/stretched the texture to fit no matter what size. the deal is, it stretches it, but not to those sizes - the right and bottom coordinates are smaller than they should be... thats about all the information i can give. thanks in advance for any ideas

Share this post


Link to post
Share on other sites
the size of the texture in pixels is dependent upon the lengths between left/right and top/bottom, but if you want to allow those pixels to be "stretched" then you must use sampler states. Linear is nice...

dev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
dev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
dev->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);

You will leave the texture coordinates from 0 to 1 unless you want it to repeat. I hope that's what you were asking.

Share this post


Link to post
Share on other sites
hey again,
i tried altering/adding the code you showed me but it didnt do anything remarkably different (at least not to my problem).
here's a screen showing what i mean, it demonstrates the problem perfectly:

...and here's the code that draws the two images to the screen:

Blit(dest,tbg.top,dx,dy,100);
Blit(dest,tbg.top,dx+100,dy+17);

ok the important part here is: "100" in the first line and "dx+100" in the second line.
the first line draws the top shortened version.
the second line draws the bottom version.
notice how the second version starts 100 pixels away from the left of the first one, but the first one doesnt stretch the full 100 pixels to meet the second one, even though the "100" should mean it does ( that is the "right" value shown in the first post).
i hope that helps you to see the problem and maybe someone can give a solution.
thanks again for any info,

Share this post


Link to post
Share on other sites
Somethings wrong with the Blit examples you gave here.

On first glance, you seem to need to input the right and bottom end, not width and height. Therefor the first (left) blit should show dx + 100, not 100. (if dx means destination x that is).

Share this post


Link to post
Share on other sites
ok i guess i should clarify the function:
parameters:
dest: D3DDevice to draw with
tbg.top: the texture to draw
dx/dx+100: x location on the screen to draw at
dy/dy+17: y location on the screen to draw at
100/(blank): how far the texture should be drawn across x-axis (width); when left blank the original size of the texture is used.

i hope this is clear. i understand your idea endurion but unfortunately thats not the problem - for some reason, even though i specify width of 100, it stretches it less, but when i leave it blank (like in the eg. function) and it uses the texture size it works fine (152 pixels is the texture size just so you know).

anyway, i hope this helps to spark some ideas about solutions,
thanks again

Share this post


Link to post
Share on other sites
here is a snippet of my code that scales the squares in my game grid. sprite_handler is a LPD3DXSPRITE

if you know that it needs to be 20 pixels longer and the same height just scale the x direction. just calculate the scale factor to make it 20 pixels longer. as long as you know the dimensions of the origional image you should be ok.


go to msdn and look up

LPD3DXSPRITE
D3DXSPRITE
D3DXMatrixTransformation2D
SetTransform



double s = (double)theBoard->WIDTH / 1000;
D3DXVECTOR2 translate(theBoard->grid[i][n].Origin.X ,theBoard->grid[i][n].Origin.Y);
D3DXVECTOR2 scaleVector(s, s);
D3DXMATRIX mscale;
D3DXMatrixTransformation2D(&mscale, NULL, NULL, &scaleVector, NULL, NULL, &translate);
sprite_handler->SetTransform(&mscale);


if(!(sprite_handler->Draw(
Psquare,
NULL,
NULL,
NULL,
D3DCOLOR_XRGB(255,255,255))));

Share this post


Link to post
Share on other sites
finally i've got it! [grin]
i remembered (after reading your post donjonson) that d3d takes a texture of any size, but puts it on a surface the size of the next power of two up (eg. so if the texture was 100x50 pixels, the texture in d3d would be 128x64 pixels).
i worked out that using this i could calculate a ratio between the two when the texture is first created using the surface description and given width of the texture.
then i just use the ratio to scale the size of the image when drawn to the screen.

ah! its so good to have this problem off my back now! [smile]
thanks everyone for your suggestions,

Share this post


Link to post
Share on other sites

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