• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*******************************************************************************
2  * Copyright 2011 See AUTHORS file.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  ******************************************************************************/
16 
17 package com.badlogic.gdx.utils.viewport;
18 
19 import com.badlogic.gdx.ApplicationListener;
20 import com.badlogic.gdx.Gdx;
21 import com.badlogic.gdx.Screen;
22 import com.badlogic.gdx.graphics.Camera;
23 import com.badlogic.gdx.graphics.glutils.HdpiUtils;
24 import com.badlogic.gdx.math.Matrix4;
25 import com.badlogic.gdx.math.Rectangle;
26 import com.badlogic.gdx.math.Vector2;
27 import com.badlogic.gdx.math.Vector3;
28 import com.badlogic.gdx.math.collision.Ray;
29 import com.badlogic.gdx.scenes.scene2d.utils.ScissorStack;
30 
31 /** Manages a {@link Camera} and determines how world coordinates are mapped to and from the screen.
32  * @author Daniel Holderbaum
33  * @author Nathan Sweet */
34 public abstract class Viewport {
35 	private Camera camera;
36 	private float worldWidth, worldHeight;
37 	private int screenX, screenY, screenWidth, screenHeight;
38 
39 	private final Vector3 tmp = new Vector3();
40 
41 	/** Calls {@link #apply(boolean)} with false. */
apply()42 	public void apply () {
43 		apply(false);
44 	}
45 
46 	/** Applies the viewport to the camera and sets the glViewport.
47 	 * @param centerCamera If true, the camera position is set to the center of the world. */
apply(boolean centerCamera)48 	public void apply (boolean centerCamera) {
49 		HdpiUtils.glViewport(screenX, screenY, screenWidth, screenHeight);
50 		camera.viewportWidth = worldWidth;
51 		camera.viewportHeight = worldHeight;
52 		if (centerCamera) camera.position.set(worldWidth / 2, worldHeight / 2, 0);
53 		camera.update();
54 	}
55 
56 	/** Calls {@link #update(int, int, boolean)} with false. */
update(int screenWidth, int screenHeight)57 	public final void update (int screenWidth, int screenHeight) {
58 		update(screenWidth, screenHeight, false);
59 	}
60 
61 	/** Configures this viewport's screen bounds using the specified screen size and calls {@link #apply(boolean)}. Typically called
62 	 * from {@link ApplicationListener#resize(int, int)} or {@link Screen#resize(int, int)}.
63 	 * <p>
64 	 * The default implementation only calls {@link #apply(boolean)}. */
update(int screenWidth, int screenHeight, boolean centerCamera)65 	public void update (int screenWidth, int screenHeight, boolean centerCamera) {
66 		apply(centerCamera);
67 	}
68 
69 	/** Transforms the specified screen coordinate to world coordinates.
70 	 * @return The vector that was passed in, transformed to world coordinates.
71 	 * @see Camera#unproject(Vector3) */
unproject(Vector2 screenCoords)72 	public Vector2 unproject (Vector2 screenCoords) {
73 		tmp.set(screenCoords.x, screenCoords.y, 1);
74 		camera.unproject(tmp, screenX, screenY, screenWidth, screenHeight);
75 		screenCoords.set(tmp.x, tmp.y);
76 		return screenCoords;
77 	}
78 
79 	/** Transforms the specified world coordinate to screen coordinates.
80 	 * @return The vector that was passed in, transformed to screen coordinates.
81 	 * @see Camera#project(Vector3) */
project(Vector2 worldCoords)82 	public Vector2 project (Vector2 worldCoords) {
83 		tmp.set(worldCoords.x, worldCoords.y, 1);
84 		camera.project(tmp, screenX, screenY, screenWidth, screenHeight);
85 		worldCoords.set(tmp.x, tmp.y);
86 		return worldCoords;
87 	}
88 
89 	/** Transforms the specified screen coordinate to world coordinates.
90 	 * @return The vector that was passed in, transformed to world coordinates.
91 	 * @see Camera#unproject(Vector3) */
unproject(Vector3 screenCoords)92 	public Vector3 unproject (Vector3 screenCoords) {
93 		camera.unproject(screenCoords, screenX, screenY, screenWidth, screenHeight);
94 		return screenCoords;
95 	}
96 
97 	/** Transforms the specified world coordinate to screen coordinates.
98 	 * @return The vector that was passed in, transformed to screen coordinates.
99 	 * @see Camera#project(Vector3) */
project(Vector3 worldCoords)100 	public Vector3 project (Vector3 worldCoords) {
101 		camera.project(worldCoords, screenX, screenY, screenWidth, screenHeight);
102 		return worldCoords;
103 	}
104 
105 	/** @see Camera#getPickRay(float, float, float, float, float, float) */
getPickRay(float screenX, float screenY)106 	public Ray getPickRay (float screenX, float screenY) {
107 		return camera.getPickRay(screenX, screenY, this.screenX, this.screenY, screenWidth, screenHeight);
108 	}
109 
110 	/** @see ScissorStack#calculateScissors(Camera, float, float, float, float, Matrix4, Rectangle, Rectangle) */
calculateScissors(Matrix4 batchTransform, Rectangle area, Rectangle scissor)111 	public void calculateScissors (Matrix4 batchTransform, Rectangle area, Rectangle scissor) {
112 		ScissorStack.calculateScissors(camera, screenX, screenY, screenWidth, screenHeight, batchTransform, area, scissor);
113 	}
114 
115 	/** Transforms a point to real screen coordinates (as opposed to OpenGL ES window coordinates), where the origin is in the top
116 	 * left and the the y-axis is pointing downwards. */
toScreenCoordinates(Vector2 worldCoords, Matrix4 transformMatrix)117 	public Vector2 toScreenCoordinates (Vector2 worldCoords, Matrix4 transformMatrix) {
118 		tmp.set(worldCoords.x, worldCoords.y, 0);
119 		tmp.mul(transformMatrix);
120 		camera.project(tmp);
121 		tmp.y = Gdx.graphics.getHeight() - tmp.y;
122 		worldCoords.x = tmp.x;
123 		worldCoords.y = tmp.y;
124 		return worldCoords;
125 	}
126 
getCamera()127 	public Camera getCamera () {
128 		return camera;
129 	}
130 
setCamera(Camera camera)131 	public void setCamera (Camera camera) {
132 		this.camera = camera;
133 	}
134 
getWorldWidth()135 	public float getWorldWidth () {
136 		return worldWidth;
137 	}
138 
139 	/** The virtual width of this viewport in world coordinates. This width is scaled to the viewport's screen width. */
setWorldWidth(float worldWidth)140 	public void setWorldWidth (float worldWidth) {
141 		this.worldWidth = worldWidth;
142 	}
143 
getWorldHeight()144 	public float getWorldHeight () {
145 		return worldHeight;
146 	}
147 
148 	/** The virtual height of this viewport in world coordinates. This height is scaled to the viewport's screen height. */
setWorldHeight(float worldHeight)149 	public void setWorldHeight (float worldHeight) {
150 		this.worldHeight = worldHeight;
151 	}
152 
setWorldSize(float worldWidth, float worldHeight)153 	public void setWorldSize (float worldWidth, float worldHeight) {
154 		this.worldWidth = worldWidth;
155 		this.worldHeight = worldHeight;
156 	}
157 
getScreenX()158 	public int getScreenX () {
159 		return screenX;
160 	}
161 
162 	/** Sets the viewport's offset from the left edge of the screen. This is typically set by {@link #update(int, int, boolean)}. */
setScreenX(int screenX)163 	public void setScreenX (int screenX) {
164 		this.screenX = screenX;
165 	}
166 
getScreenY()167 	public int getScreenY () {
168 		return screenY;
169 	}
170 
171 	/** Sets the viewport's offset from the bottom edge of the screen. This is typically set by {@link #update(int, int, boolean)}. */
setScreenY(int screenY)172 	public void setScreenY (int screenY) {
173 		this.screenY = screenY;
174 	}
175 
getScreenWidth()176 	public int getScreenWidth () {
177 		return screenWidth;
178 	}
179 
180 	/** Sets the viewport's width in screen coordinates. This is typically set by {@link #update(int, int, boolean)}. */
setScreenWidth(int screenWidth)181 	public void setScreenWidth (int screenWidth) {
182 		this.screenWidth = screenWidth;
183 	}
184 
getScreenHeight()185 	public int getScreenHeight () {
186 		return screenHeight;
187 	}
188 
189 	/** Sets the viewport's height in screen coordinates. This is typically set by {@link #update(int, int, boolean)}. */
setScreenHeight(int screenHeight)190 	public void setScreenHeight (int screenHeight) {
191 		this.screenHeight = screenHeight;
192 	}
193 
194 	/** Sets the viewport's position in screen coordinates. This is typically set by {@link #update(int, int, boolean)}. */
setScreenPosition(int screenX, int screenY)195 	public void setScreenPosition (int screenX, int screenY) {
196 		this.screenX = screenX;
197 		this.screenY = screenY;
198 	}
199 
200 	/** Sets the viewport's size in screen coordinates. This is typically set by {@link #update(int, int, boolean)}. */
setScreenSize(int screenWidth, int screenHeight)201 	public void setScreenSize (int screenWidth, int screenHeight) {
202 		this.screenWidth = screenWidth;
203 		this.screenHeight = screenHeight;
204 	}
205 
206 	/** Sets the viewport's bounds in screen coordinates. This is typically set by {@link #update(int, int, boolean)}. */
setScreenBounds(int screenX, int screenY, int screenWidth, int screenHeight)207 	public void setScreenBounds (int screenX, int screenY, int screenWidth, int screenHeight) {
208 		this.screenX = screenX;
209 		this.screenY = screenY;
210 		this.screenWidth = screenWidth;
211 		this.screenHeight = screenHeight;
212 	}
213 
214 	/** Returns the left gutter (black bar) width in screen coordinates. */
getLeftGutterWidth()215 	public int getLeftGutterWidth () {
216 		return screenX;
217 	}
218 
219 	/** Returns the right gutter (black bar) x in screen coordinates. */
getRightGutterX()220 	public int getRightGutterX () {
221 		return screenX + screenWidth;
222 	}
223 
224 	/** Returns the right gutter (black bar) width in screen coordinates. */
getRightGutterWidth()225 	public int getRightGutterWidth () {
226 		return Gdx.graphics.getWidth() - (screenX + screenWidth);
227 	}
228 
229 	/** Returns the bottom gutter (black bar) height in screen coordinates. */
getBottomGutterHeight()230 	public int getBottomGutterHeight () {
231 		return screenY;
232 	}
233 
234 	/** Returns the top gutter (black bar) y in screen coordinates. */
getTopGutterY()235 	public int getTopGutterY () {
236 		return screenY + screenHeight;
237 	}
238 
239 	/** Returns the top gutter (black bar) height in screen coordinates. */
getTopGutterHeight()240 	public int getTopGutterHeight () {
241 		return Gdx.graphics.getHeight() - (screenY + screenHeight);
242 	}
243 }
244