-
|
|
|
Hello everyone!
I've been working on this all day as an extracurricular endeavor, and haven't found a viable solution.
I have a sprite with a fish texture applied that swims across the screen, and as it reaches each edge of its window it will flip around and swim the other way. I'd like to have the sprite's graphic change direction, as well, so that the fish always appears to be swimming in a forward direction.
For my sprite I'm using an LPD3DXSPRITE, and for my texture, an LPDIRECT3DTEXTURE9. The texture bitmap has four frames in it.
Thus far I've tried using a reversed srcRect, and applying a D3DXMatrixScaling with -1,0, and 0 as scaling arguments, in addition to other fruitless modifications. In both of these cases my sprite disappears, even though I've disabled backface culling.
Here's a code snippet of my sprite rendering function (sorry, no C++ syntax highlighting?):
| 1 |
void dxManager::renderSprite(RECT *sourceRect, int * left, int * top, int direction) |
| 2 |
{ |
| 3 |
sprite->Begin(NULL); // begin sprite drawing |
| 4 |
|
| 5 |
pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); |
| 6 |
|
| 7 |
RECT finalSourceRect = *sourceRect; |
| 8 |
|
| 9 |
if (direction < 0) |
| 10 |
{ |
| 11 |
D3DXMATRIX flip, out, now; |
| 12 |
|
| 13 |
sprite->GetTransform(&now); |
| 14 |
D3DXMatrixScaling(&flip, -1, 1, 1); |
| 15 |
D3DXMatrixMultiply(&out, &flip, &now); |
| 16 |
|
| 17 |
sprite->SetTransform(&out); |
| 18 |
} |
| 19 |
|
| 20 |
D3DXVECTOR3 center(0.0f, 8.0f, 0.0f); // center at the upper-left corner |
| 21 |
D3DXVECTOR3 position((float)*left, (float)*top, 0.0f); |
| 22 |
|
| 23 |
sprite->Draw(spriteTexture, &finalSourceRect, ¢er, &position, D3DCOLOR_XRGB(255, 255, 255)); // draw it! |
| 24 |
|
| 25 |
sprite->End(); // end sprite drawing |
| 26 |
|
| 27 |
|
| 28 |
} |
and if needed, I can post a link to my project (VS2008 C++).
Right now I'm just kind of lost, as I'm new to DirectX, and all the potential leads I've seen thus far relate to MDX, XNA, or just don't work... As some may notice, I've still attempted to apply the indirectly-related solutions to my code, but to no avail (though most of it got deleted for being the cluttering mass of comments they were).
Anyway, this seems like something that should be natively implemented in Direct3D... If anyone has any advice, I thank you in advance for taking the time to help me :)
-ADAM
|
|
-
|
|
Re: How to flip a sprite?
|
Here are some other ways you could solve this:
1) Include 8 frames in your texture, 4 in the "forward" direction and 4 in the "reverse" direction and select the appropriate frame based on direction.
2) Use the texture matrix to flip the image by reversing the orientation of the texture coordinates instead of attempting to use the world matrix to reverse the orientation of the geometry.
|
|
-
|
|
Re: How to flip a sprite?
|
Thank you for your reply, legalize.
I refuse to succumb to option 1, hehheh...
So, option 2... I don't see any methods or properties of my texture that relate to transformations, matrices, or coordinates. Am I using the wrong texture class, perhaps? Also, I was unaware that I was trying to flip the world matrix... That would explain the disappearance of the sprites! hehe... At what point is this occurring? I thought that using sprite->SetTransform() only applied to the sprite. Would it be in my call to MatrixMultiplication()? I thought that just multiplied some matrices together, not multiplied matrices to the world matrix...
Thanks again, and in advance for any further help on this matter 8)
-ADAM
|
|
-
|
|
Re: How to flip a sprite?
|
Think about it this way - your transform says to scale by -1 in the x-direction (e.g. multiply all x-coordinates by -1). So, if you say "draw at 10,10", you're actually going to draw at -10,10.
|
|
-
|
|
Re: How to flip a sprite?
|
adamonline45:So, option 2... I don't see any methods or properties of my texture that relate to transformations, matrices, or coordinates.
If you take a look at Chapter 11. Basic Texturing and the pipeline poster from my book "The Direct3D Graphics Pipeline", you'll see that the fixed-function pipeline applies a transformation matrix to the texture coordinates independent of the matrix that is applied to the vertex position coordinates. I discuss this in the section on texture coordinate processing (11.5). You can do this yourself in a vertex shader if you are not using the fixed-function pipeline.
The texture coordinate transformation matrix allows you to control the orientation of the texture independently of the orientation of the geometry. For instance, you could keep the geometry static and make the texture translate across the surface of the geometry. Think of the situation when you wrap a birthday present in wrapping paper -- the wrapping paper itself is the texturing operation and how you cut the wrapping paper and position it around the present is the texture coordinate transformation. If you wanted to reverse the orientation of the pattern on the present, you could just turn the wrapping paper 180 degrees (or flip it over) to get the different orientation on the paper without moving the present.
|
|
-
|
|
Re: How to flip a sprite?
|
Well, then the only missing step is to add a translation part to the scale matrix so it brings the sprite back into view:
| D3DXMatrixScaling(&flip, -1, 1, 1); |
| flip[3][0] = left*2; |
| //flip[3][1] = top*2; // If you also flip on Y |
| |
You might want to disable culling too if you still can't see anything.
Wessam Bahnassi Microsoft DirectX MVP
|
|
-
|
|
Re: How to flip a sprite?
|
Goodness I hate to bump this... But thanks to everyone who gave me some input, I appreciate it! I solved my problem, and just kept going with other projects, neglecting you fine folks! :O
I ended up just using a 2-piece trianglestrip and uv texture coordinates. It just made it all a whole lot simpler, after I figured out how to render primitives! (In the example above, I was using surfaces).
Well, thanks again!
-ADAM
|
|
-
|
|
Re: How to flip a sprite?
|
In the big SpriteBatch.Draw method you have the option of setting a SpriteEffect value.
In my sprite class I made a method to flip sprites:
| public void SetFlip(bool _horizontal, bool _vertical) |
| { |
| |
| if (_horizontal && _vertical) |
| data.effects = SpriteEffects.FlipHorizontally | SpriteEffects.FlipVertically; |
| else if (_horizontal && !_vertical) |
| data.effects = SpriteEffects.FlipHorizontally; |
| else if (!_horizontal && _vertical) |
| data.effects = SpriteEffects.FlipVertically; |
| else |
| data.effects = SpriteEffects.None; |
| } |
Then when it comes to the sprite batch draw method I do this:
| spriteBatch.Draw(spriteData.texture, |
| spriteData.position, |
| spriteData.sourceRect, |
| spriteData.colour, |
| spriteData.rotation, |
| spriteData.hotSpot, |
| spriteData.scale, |
| spriteData.effects, |
| spriteData.z |
| ); |
|
|
|