DevLog #13 - Engine: Viewport & Camera

posted in StarDust DevLog
Published October 15, 2011
Advertisement
Before displaying a scene, the viewport and projection transformations are needed. The engine have to allow multiple viewports (for splitscreen or PIP). Each viewport may want to display same, or absolutely different scene. In a case multiple viewports display same scene, they may want to display it from different angles. Like this can be summed up the requirements for Scene, Camera, and Viewport interaction implementation.

Camera in scene

As first let take a look at a single scene that should support different view angles. The situation is offering to create a class for Camera, and have a Camera object in the scene for every predefined view. So you make something like a scene from a movie shooting, where are several cameras on the place and the cut then only selects which view will be used in the film at which moment. In my implementation the Camera::Render() function performs the transformation of camera and then calls the Scene::Draw(), so a single call of camera will draw whole scene from the desired angle and settings.
As you may see on the class diagram below, the Scene provides methods to create a Camera. The scene knows all its cameras and the created camera knows which scene it belongs to.

Viewport in window

Now when we have the ability to draw a scene from a camera, we have still to perform viewport transformation. As in case of cameras we create a class for viewports. Every viewport on the screen will correspond to one Viewport object. Split screen or PIP (picture in picture) is then made by creating at least two Viewport objects and calling Render() on each.

Display camera in viewport

Last thing remains - tell the viewport which scene to display and from vhich camera. By simply passing Camera as an argument of Render call we tell to viewport: "In this viewport display view from that camera".
The Viewport::Render() performs viewport transformation and calls Camera::Render().
The Camera::Render() performs camera transformations and calls Scene::Draw().

Here is an example of how can look the game code for split screen for two players:

[spoiler]// Create a 1280x1024 fullscreen window
Window* window = new Window();
window->Create( "Game title", 1280, 1024, 32, true ); // name, width, height, debth, fullscreen
window->Show();

// Create 2 viewports 1280x512 (horizontal splitscreen)
Viewport* viewportPlayer1 = new Viewport( 0, 0, window->Width(), window->Height()/2 ); // x, y, width, height
Viewport* viewportPlayer2 = new Viewport( 0, window->Height()/2, window->Width(), window->Height()/2 );

float aspect = window->Width() / ( window->Height()/2 );

//Create scene
Scene* gameScene = new Scene();
Camera* camPlayer1 = gameScene->CreatePerspectiveCamera( position1, 60.0, aspect, 0.1, 500.0 ); // position, FOV, aspect, near, far
Camera* camPlayer2 = gameScene->CreatePerspectiveCamera( position2, 60.0, aspect, 0.1, 500.0 );
// add other objects to Scene


// Draw
viewportPlayer1->Render( camPlayer1 );
viewportPlayer2->Render( camPlayer2 );

Renderer::SwapBuffers( window );
[/spoiler]

viewportcamera.png
0 likes 0 comments

Comments

Nobody has left a comment. You can be the first!
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement