123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- .. _doc_viewports:
- Viewports
- =========
- Introduction
- ------------
- Godot has a small but useful feature called viewports. Viewports
- are, as the name implies, rectangles where the world is drawn. They
- have three main uses, but can flexibly adapted to a lot more. All this
- is done via the :ref:`Viewport <class_Viewport>` node.
- .. image:: img/viewportnode.png
- The main uses in question are:
- - **Scene Root**: The root of the active scene is always a Viewport.
- This is what displays the scenes created by the user. (You should
- know this by having read previous tutorials!)
- - **Sub-Viewports**: These can be created when a Viewport is a child of
- a :ref:`Control <class_Control>`.
- - **Render Targets**: Viewports can be set to "RenderTarget" mode. This
- means that the viewport is not directly visible, but its contents
- can be accessed via a :ref:`Texture <class_Texture>`.
- Input
- -----
- Viewports are also responsible of delivering properly adjusted and
- scaled input events to all its children nodes. Both the root viewport
- and sub-viewports do this automatically, but render targets do not.
- Because of this, the user must do it manually via the
- :ref:`Viewport.input() <class_Viewport_input>` function if needed.
- Listener
- --------
- Godot supports 3D sound (in both 2D and 3D nodes), more on this can be
- found in another tutorial (one day..). For this type of sound to be
- audible, the viewport needs to be enabled as a listener (for 2D or 3D).
- If you are using a custom viewport to display your world, don't forget
- to enable this!
- Cameras (2D & 3D)
- -----------------
- When using a 2D or 3D :ref:`Camera <class_Camera>` /
- :ref:`Camera2D <class_Camera2D>`, cameras will always display on the
- closest parent viewport (going towards the root). For example, in the
- following hierarchy:
- - Viewport
- - Camera
- Camera will display on the parent viewport, but in the following one:
- - Camera
- - Viewport
- It will not (or may display in the root viewport if this is a subscene).
- There can be only one active camera per viewport, so if there is more
- than one, make sure that the desired one has the "current" property set,
- or make it the current camera by calling:
- ::
- camera.make_current()
- Scale & stretching
- ------------------
- Viewports have a "rect" property. X and Y are often not used (only the
- root viewport uses them), while WIDTH AND HEIGHT represent the
- size of the viewport in pixels. For Sub-Viewports, these values are
- overridden by the ones from the parent control, but for render targets
- this sets their resolution.
- It is also possible to scale the 2D content and make it believe the
- viewport resolution is other than the one specified in the rect, by
- calling:
- ::
- viewport.set_size_override(w, h) # custom size for 2D
- viewport.set_size_override_stretch(true) # enable stretch for custom size
- The root viewport uses this for the stretch options in the project
- settings.
- Worlds
- ------
- For 3D, a Viewport will contain a :ref:`World <class_World>`. This
- is basically the universe that links physics and rendering together.
- Spatial-base nodes will register using the World of the closest
- viewport. By default, newly created viewports do not contain a World but
- use the same as a parent viewport (root viewport does contain one
- though, which is the one objects are rendered to by default). A world can
- be set in a viewport using the "world" property, and that will separate
- all children nodes of that viewport from interacting with the parent
- viewport world. This is especially useful in scenarios where, for
- example, you might want to show a separate character in 3D imposed over
- the game (like in Starcraft).
- As a helper for situations where you want to create viewports that
- display single objects and don't want to create a world, viewport has
- the option to use its own World. This is useful when you want to
- instance 3D characters or objects in the 2D world.
- For 2D, each Viewport always contains its own :ref:`World2D <class_World2D>`.
- This suffices in most cases, but in case sharing them may be desired, it
- is possible to do so by calling the viewport API manually.
- Capture
- -------
- It is possible to query a capture of the viewport contents. For the root
- viewport this is effectively a screen capture. This is done with the
- following API:
- ::
- # Retrieve the captured Image using get_data()
- var img = get_viewport().get_texture().get_data()
- # Also remember to flip the texture (because it's flipped)
- img.flip_y()
- # Convert Image to ImageTexture
- var tex = ImageTexture.new()
- tex.create_from_image(img)
- # Set Sprite Texture
- $sprite.texture = tex
- But if you use this in _ready() or from the first frame of the viewport's initialization
- you will get an empty texture cause there is nothing to get as texture. You can deal with
- it using (for example):
- ::
- # Let two frames pass to make sure the screen can be captured
- yield(get_tree(), "idle_frame")
- yield(get_tree(), "idle_frame")
- # You can get the image after this
- If the returned image is empty, capture still didn't happen, wait a
- little more, as this API is asynchronous.
- Sub-viewport
- ------------
- If the viewport is a child of a :ref:`ViewportContainer <class_viewportcontainer>`, it will become active and
- display anything it has inside. The layout is something like this:
- - ViewportContainer
-
- - Viewport
- The viewport will cover the area of its parent control completely, if stretch is set to true in Viewport Container.
- But you will have to setup the Viewport Size to get the the appropriate part of the Viewport.
- And Viewport Container can not be smaller than the size of the Viewport.
- .. image:: img/subviewport.png
- Render target
- -------------
- To set as a render target, toggle the "render target" property of
- the viewport to enabled. Note that whatever is inside will not be
- visible in the scene editor. To display the contents, the method remains the same.
- This can be requested via code using (for example):
- ::
- #This gets us the render_target texture
- var rtt = viewport.get_texture()
- sprite.texture = rtt
- By default, re-rendering of the render target happens when the render
- target texture has been drawn in a frame. If visible, it will be
- rendered, otherwise it will not. This behavior can be changed to manual
- rendering (once), or always render, no matter if visible or not.
- ``TODO: Review the doc, change outdated and add more images.``
- Make sure to check the viewport demos! Viewport folder in the demos
- archive available to download, or
- https://github.com/godotengine/godot-demo-projects/tree/master/viewport
|