1
votes

I have a sprite, a square, just for orthogonal projection. Now I want to project it in a very basic, simple isometric way. (I know this might not be pretty, but I just want to figure this out)

Given my square, I rotate it 45 degrees. Now if I understand correctly, I should still divide my height by 2. This has been impossible for me in SFML. There is a scale function but if I scale with a factor 0.5 in the y-axis direction, my cube just gets stretched, instead of a diamond shape. It looks as though SFML transforms the sprite according to it's own relative axes (that were rotated before..).

Since you cannot access the height of a sprite, I was wondering if this was even possible?

Can I convert a square sprite to a diamond shape in SFML?

2

2 Answers

5
votes

Using a sf::RenderTexture is an option (see other answer). Another option is to fiddle with the sf::View. Double the view's height, and adjust coordinates. It would go something like this:

my_sprite.setRotation(45.f);
//adjust the position for new screen coordinates (once)
my_sprite.setPosition(my_sprite.getPosition().x, my_sprite.getPosition().y * 2);

//...

//when drawing:
sf::View v = my_render_window.getDefaultView();
v.setSize(v.getSize().x, v.getSize().y * 2);
v.setCenter(v.getSize() *.5f);

my_render_window.setView(v);
my_render_window.draw(my_sprite);
my_render_window.setView(my_render_window.getDefaultView());
1
votes

Rotate your sprite as you are doing now. Render it to an sf::RenderTexture. Use the member function getTexture, and make a new sprite from it, or reuse the old sprite. Scale the sprite along the y-axis. Draw it to the render window.

Some math on your part may be required in order to set the RenderTexture to the right size and to draw the original sprite in the correct location on it.

original_sprite.setRotation(45);
sf::RenderTexture rt;
rt.create(FigureOutWidth(),FigureOutHeight());
original_sprite.setPosition(MoreMathHere());
rt.draw(original_sprite);
sf::Sprite new_sprite(rt.getTexture());
new_sprite.setScale(1.0,0.5);

It should go without saying, but do this once in initialization, not every frame.