3
\$\begingroup\$

I'm very confused about the SDL2 viewport, I did some googling to find out how to implement it but people keep mentioning things like "world coordinates" which I don't have in my game.

Question : Do I even need world coordinates for the SDL2 viewport to work? If yes, how do I implement it?


I've currently got a problem where if my viewport goes too much to the right or down, the entire window will become green, kinda like if it stopped rendering all my sprites.

Here's a GIF to show you what I mean :

enter image description here

As you can see, whenever I go too much to the right or down the entire screen goes green.

I thought this maybe was beause of me not using world coordinates, but I have no idea I'm just guessing stuff at this point...


My current codes for moving the viewport, drawing it, and such looks like this :

Creating the viewport / camera :

Camera::Camera(Uint16 x, Uint16 y, Uint16 w, Uint16 h)
{

    // Sets up the viewport positions and sizes
    viewport.x = x;
    viewport.y = y;
    viewport.w = w;
    viewport.h = h;

    // Sets the viewport so that SDL uses it
    SDL_RenderSetViewport(Window::GetRenderer(), &viewport);

}

Drawing the viewport : (gets called every frame)

void Camera::DrawCameraViewport()
{
    SDL_RenderSetViewport(Window::GetRenderer(), &viewport);
}

I set the cameras position during runtime like this :

void Camera::SetCameraPosition(int _x, int _y)
{
    viewport.x = _x;
    viewport.y = _y;
}

And here's how I set the cameras position using the above function :

Note : Sorry, the line became giantic...

camera->SetCameraPosition(
    -SpriteManager::GetPlayerSprite()->GetPosition().x
    + Window::GetWindowMiddlePoint().x
    - SpriteManager::GetPlayerSprite()->GetMiddlePoint().x

    , -SpriteManager::GetPlayerSprite()->GetPosition().y
    + Window::GetWindowMiddlePoint().y
    - SpriteManager::GetPlayerSprite()->GetMiddlePoint().y);

Question : Am I implementing the viewport correctly?

\$\endgroup\$
  • \$\begingroup\$ Do you have a problem using SDL's viewport functionality or implementing a camera that follows a player around? Also you would have to show a littile bit of code, on the parts that aren't working. \$\endgroup\$ – Tyyppi_77 May 14 '16 at 10:55
  • \$\begingroup\$ @Tyyppi_77 I'm really confused... lol I'm not sure if I have the camera implemented correctly at all, because other threads keep mentioning things like world coordinates which I don't have and don't know how to implement. I will add some code and a GIF to my post now though. \$\endgroup\$ – BiiX May 14 '16 at 10:57
  • \$\begingroup\$ The viewport is for UI elements like minimaps and menus, and not for camera stuff. If you are rendering to the whole screen, don't use viewports. \$\endgroup\$ – amitp Jun 12 '16 at 22:05
  • \$\begingroup\$ @amitp Oh... Then how would I go about making a big map that the player can walk in? Any good links or something like that? \$\endgroup\$ – BiiX Jun 13 '16 at 16:28
7
+50
\$\begingroup\$

My guess is you're trying to implement a camera, and should not be using SDL Viewports. The viewports are for UI elements like menus, minimaps, etc. It's a way of dividing up the screen into multiple areas.

To implement a camera, you will want to think about coordinate systems. The world coordinates are the positions in the world, without thinking about the camera. If a tree is at 300,200 then it stays at 300,200 even if you move the camera around. The screen coordinates are where that tree is drawn on the screen. As you move around, the tree might be drawn in different places on screen.

If you try to use screen coordinates everywhere, things get really confusing. Every time you move the camera, you now need to go update everything. If you use world coordinates, you don't "move" the tree around. Instead, you draw it in a different place. The tree doesn't move. The camera moves.

Here's the basic formula:

screen + camera = world

You know the world coordinates of the tree, and the camera location, and you want to figure out the screen coordinates, so you rewrite the formula this way:

screen = world - camera

With the tree example, the tree is at x=300,y=200, and let's say the camera is at x=50,y=70, then you want to know where to draw the tree:

screen.x = tree.x - camera.x
screen.y = tree.y - camera.y
#
screen.x = 300 - 50 = 250
screen.y = 200 - 70 = 130
# draw tree at 250,130

When you move your camera, you redraw everything on the screen by calculating the new screen coordinates. If you moved the camera to x=100,y=20, you'd redraw the tree:

screen.x = tree.x - camera.x
screen.y = tree.y - camera.y
#
screen.x = 300 - 100 = 200
screen.y = 200 - 20 = 180
# draw tree at 200,180

Notice that tree.x,tree.y didn't change here. It's only the camera that changed. (You can later optimize this by not drawing the things that won't be on the screen, but first get the basics working before trying to optimize.)

(A bonus with the formula is that it works backwards too. If you got a mouse click and want to know where in the world you clicked, you use screen + camera = world. You know the screen location of the mouse click, and you know the camera location, so you add them together to figure out what you clicked on.)

One day I will finish my tutorial on this topic…

\$\endgroup\$
  • \$\begingroup\$ Ah, I see. Managed to get it work after a while of trying! :D Thanks a lot! \$\endgroup\$ – BiiX Jun 15 '16 at 14:03
-1
\$\begingroup\$

try using SDL_RenderSetClipRect() instead of SDL_RenderSetViewport . Had the same problem and changed into SDL_RenderSetClipRect(). Cheers!

\$\endgroup\$
  • \$\begingroup\$ This gives the same problem :( \$\endgroup\$ – BiiX Jun 11 '16 at 17:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.