Sign in to follow this  
riku743

DirectX: Unable to Flip Sprite Horizontally

Recommended Posts

Hi,

 

I've been working on a 2D game using DirectX, and it has been going pretty smoothly. I have a structure set up to contain data for a sprite, including its position and the actual sprite object (lpSprite) as well as some variables dealing with movement speed and etc. There is a function I've made to draw a given sprite with a given texture, and it works well. Until recently, I had two separate textures for one of the sprites, with each texture facing a different direction, and it would draw the sprite with one of the textures depending on which direction it was facing. This worked fine, but I didn't want to have two textures for each as I started adding more sprites to the game, so I started looking into how to flip a sprite horizontally using SetTransform. Below is a snippet of code taken from my function that draws the sprite.

	D3DXVECTOR3 vCenter( 0.0f, 0.0f, 0.0f );
	D3DXVECTOR3 vPosition( s_sprite.xPosit, s_sprite.yPosit, 0.0f );
																			
	s_sprite.lpSprite->Begin( D3DXSPRITE_ALPHABLEND );

	if(s_sprite.flipHoriz)
	{
		D3DXMATRIX transMatrix;
		D3DXMatrixScaling(&transMatrix, 1.0f, -1.0f, 1.0f );
		s_sprite.lpSprite->SetTransform(&transMatrix);
	}


    s_sprite.lpSprite->Draw( t_texture.lpTexture,
                          &srcRect,
                          &vCenter,
                          &vPosition,
                          D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f) );

 

The part that I added recently is the if(s_sprite.flipHoriz), which is a bool, and the three lines inside the if statement. Now, after adjusting the code so that when the sprite should be facing left flipHoriz is true, when I run the program and move the sprite to be facing left, it is no longer visible. Its position remains at what it should be, and the program doesn't stop running, but you can't see it anymore. When I move it back to be facing right, it still is not visible.

 

What did I do wrong? After looking around on the internet, it seems that my sprite's center being at 0,0 is an oddity and this may be part of the problem, but up until this point, it worked fine. Also, I tried setting the center to the actual center of the sprite, but the same problem persisted (and all of the sprites were drawn in the slightly wrong place).

Share this post


Link to post
Share on other sites

Are you back face culling? Because flipping the sprite like that will change the winding order. Try setting the cull mode to none instead, see if that works. If it does draw mirrored sprites with the oppsoite cull mode (or don't back face cull sprites at all). Or...

 

You can also flip sprites by flipping the UVs instead, that won't change the winding order.

Share this post


Link to post
Share on other sites

I'm not back face culling -- my game is completely 2D, so I assumed I didn't need to. I tried setting the cull mode to none, and it didn't change anything.

 

If you mean the UVs for the texture, I don't actually set those. I create the texture using D3DXCreateTextureFromFileEx and loadTexture(), and then Sprite->Draw() to associate it with the sprite. I don't ever draw textures directly or onto anything but sprites, so as far as I know it wasn't necessary to do anything else (and it worked fine up until this point). If you mean something else, could you elaborate?

 

I'm pretty new to this, apologies if I don't understand or am doing things in a non-standard way.

Edited by riku743

Share this post


Link to post
Share on other sites

What if you negate the y value in the vPosition vector as well (only in the if flipped case)? Because setting the transform may negate the position when it is applied to the whole sprite. All I can think of, I've not used the DirectX sprite stuff.

Share this post


Link to post
Share on other sites

just set the scale negative in the dimension you want?

i.e. setting the scale to 1, -1 flips the sprite upside down (vertically?), and -1, 1 flips it left-right (horizontally?).

 

edit: now that i've actually read your post... (dumb me)... maybe try using D3DXMatrixTransformation2D and passing in all the required values, and set the matrix before the call to sprite->Draw()? in that case, you dont need to pass the center nor position to the draw method, only the color tint.

Edited by Strewya

Share this post


Link to post
Share on other sites

Aha! I had tried using D3DXMatrixTransformation2D before, but I was using it only for the scaling, not for the position as well. It apparently works better if you do it all at once. Also, now that it's doing it this way, setting the center to the actual center doesn't mess things up.

 

....However, although the sprite is now visible, it has somehow done both a horizontal flip and a vertical flip, and has moved up . Or, more accurately, a 180 degree rotation. Here's what the adjusted code snippet looks like:

	D3DXVECTOR2 vCenter( s_sprite.width/2.0f, s_sprite.height/2.0f );
	D3DXVECTOR2 vPosition( s_sprite.xPosit, s_sprite.yPosit );
	D3DXVECTOR2 vScale(1.0f, 1.0f);
	D3DXMATRIX transMatrix;
																			
	s_sprite.lpSprite->Begin( D3DXSPRITE_ALPHABLEND );

	if(s_sprite.flipHoriz)
		vScale.x = -1.0f;
	
	D3DXMatrixTransformation2D(&transMatrix, &vCenter, 0.0f, &vScale, NULL, 0.0f, &vPosition);

	s_sprite.lpSprite->SetTransform(&transMatrix);

    s_sprite.lpSprite->Draw( t_texture.lpTexture,
                          &srcRect,
                          NULL,
                          NULL,
                          D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f) );

 

It's possible I'm just using D3DXMatrixTransformation2D incorrectly. Before I changed the center to the real center, it was as if it flipped horizontally, and then reflected vertically over the top line bounding the sprite rectangle. Now it stays in the same place, it's just upside-down.

 

Edit: Nevermind! I had it making the y value of the scaling vector negative, when it seems it should have been the x value in this case.

Thanks for the help, guys.

Edited by riku743

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