How to rotate a rect in SDL2? - c++

I plan on making a game, and I want to create some background animations for said game. One of these animations is a rotating rectangle. I've looked all over, and I cannot find any form of math or logic that allows me to rotate a rectangle (SDL_Rect to be specific, but you might have already known that).
I can't figure out the math for myself, I really don't have any working code for this, so I can't show anything.
Essentially I'm looking for some type of logic that I can apply the rectangle's coordinates so that whenever the main game loop loops, it will rotate the rectangle some amount of degrees.

You can't rotate an SDL_Rect. If you look at its definition, it's made of coordinates for the top-left corner, the width and the height. There's no way to represent a rectangle with sides that aren't parallel to the coordinate system's axes.
SDL_RenderCopyEx supports drawing rotated textures, though.

Related

Is there a way to make a flat surface, that is perpendicular to the camera, visible in OpenGL?

As seen in the picture we have a rectangle which is 2 Dimensional in a 3D space.
When I rotate said rectangle (Slightly rotated) so that the normal of this plate is perpendicular to the camera, it vanishes (Heavily rotated Rectangle just before vanishing). The intuition would tell me, that the plate is supposed to show a single line of pixels, however this is not the case (but certainly what I'm trying to achieve). This Problem seems so trivial, but I can't find a solution to it.

Get screen position of the center of a mesh

My goal is to create an intuitive 3D manipulator to handle rotations of meshes displayed in my 3D editor, made with Qt / QML.
To do that, when the user clicks on an entity, 3 tori are spawned around the mesh, representing the euler angles the user can act on. If the user then clicks on one torus, I want him to be able to rotate the mesh by dragging the mouse. The natural way users seem to do that is by dragging the mouse around the torus in the direction they want the mesh to rotate.
I therefore need a way to know how the user is rotating his mouse. I thought of a way: when the user clicks on the torus, I retrieve the position of the center of the torus. Then, I translate this world position to its screen position. Then, I monitor the angle between the cursor of the mouse and the center of the torus. The evolution of this angle should tell me everything I need: if the angle increases clockwise, the mesh should rotate clockwise and vice versa. This solution should yield a result good enough for my application, since it won't depend on the angle of the camera, or only very minimally.
However, I can't find a way to translate a world position to its screen position with Qt. I found the function QVector3D::project(const QMatrix4x4 &modelView, const QMatrix4x4 &projection, const QRect &viewport), but its documentation is very scarce and I couldn't find anyone using it... I might have found what to feed in for the projection argument (the projectionMatrix property from QCamera, here https://doc.qt.io/qt-5/qml-qt3d-render-camera.html), but that's it. What is the modelView ? And viewport ? Is it simply QRect(0, 0, 1920, 1080) ?
If anyone have any kind of lead, it would be amazing, I can't find anything anywhere and I'm kind of losing hope now. Or maybe another, simpler, solution to my problem ? Please note that the user can also freely move the camera around the mesh, which adds in complexity.
Thanks a lot for your time, and have a nice day !
Yes, you should be able to translate from world position to screen position using the mentioned function. You are correct about the projection argument. As for the modelView argument, you should use viewMatrix property from QCamera, which is missing from the official documentation, but it works for me. The viewport parameter represents the dimensions of the part of the screen, you are projecting on. You could use QRect(0, 0, 1920, 1080) if you use full screen Full HD projection, otherwise use something like QRect(QPoint(0, 0), view->size()), where view is the wigdet or window with your 3D image. Be careful, that the resulting screen position will have y = 0 being down and positive values being above, which the opposite to usual screen coordinates.

Drawing a 3d object on a 2D screen plane without angle of view

I have a problem, I need to draw a 3D object in such a way that I can move it along the screen plane and rotate so that the angle of view is as if I always looked at it fixedly from one point.
I use the GLM library for working with matrices. I tried to use glm::ortho, but I can not operate with the z coordinate, respectively, the model does not rotate. if i use glm::perspective, then the model looks like i need only in the center of the screen. I mean, for example, the character model is depicted in the window of a game. How would you not move the window at any point on the screen, you look at the model directly, and not as if looking out of the corner.
I apologize, I do not know how to explain it in normal language, I hope it is understandable.

SFML Generate isometric tile

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?
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());
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.

Better modifying the render or moving the camera?

Since I gogled for it without finding anything interesting, I would like to ask you for some suggestions regarding if it is better to scale/translate the render itself keeping the camera position fixed or maybe moving closer/further or rotate the camera keeping the render position fixed?
I need a zooming out/in, rotation in all the 3 axes and also this kind of rotation
http://www.reknow.de/downloads/opengl/video.mp4
that is, if I first translate my render and then I apply a rotation, this rotation should consider the center always the windows center, and not the translated one
I need a zooming out/in, rotation in all the 3 axes and also this kind of rotation
What you mean is probably not "zooming" but "panning". And in OpenGL you place the "camera" by moving the scene around, because there is no camera.
Zooming is a change in the focal length, and would be implemented by changeing the FOV of the perspective.