• 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.tests;
18 
19 import com.badlogic.gdx.Gdx;
20 import com.badlogic.gdx.graphics.GL20;
21 import com.badlogic.gdx.graphics.OrthographicCamera;
22 import com.badlogic.gdx.graphics.Texture;
23 import com.badlogic.gdx.graphics.g2d.Batch;
24 import com.badlogic.gdx.graphics.g2d.BitmapFont;
25 import com.badlogic.gdx.graphics.g2d.SpriteBatch;
26 import com.badlogic.gdx.graphics.g2d.TextureRegion;
27 import com.badlogic.gdx.math.Rectangle;
28 import com.badlogic.gdx.scenes.scene2d.Actor;
29 import com.badlogic.gdx.scenes.scene2d.Stage;
30 import com.badlogic.gdx.scenes.scene2d.ui.Image;
31 import com.badlogic.gdx.scenes.scene2d.utils.Cullable;
32 import com.badlogic.gdx.tests.utils.GdxTest;
33 import com.badlogic.gdx.tests.utils.OrthoCamController;
34 import com.badlogic.gdx.utils.Align;
35 import com.badlogic.gdx.utils.Array;
36 import com.badlogic.gdx.utils.Scaling;
37 
38 /** This is a simple demonstration of how to perform VERY basic culling on hierarchies of stage actors that do not scale or rotate.
39  * It is not a general solution as it assumes that actors and groups are only translated (moved, change their x/y coordinates).
40  * NOTE: This has been obsoleted by {@link Cullable}.
41  *
42  * @author mzechner */
43 public class SimpleStageCullingTest extends GdxTest {
44 
45 	/** We need to extend a base actor class so we can add the culling in the render method. We also add a method to get the stage
46 	 * coordinates of the actor so we can cull it against the camera's view volume.
47 	 *
48 	 * @author mzechner */
49 	private class CullableActor extends Image {
50 		/** the camera to test against **/
51 		final OrthographicCamera camera;
52 		/** whether we are visible or not, used for counting visible actors **/
53 		boolean visible = false;
54 
CullableActor(String name, Texture texture, OrthographicCamera camera)55 		public CullableActor (String name, Texture texture, OrthographicCamera camera) {
56 			super(new TextureRegion(texture));
57 			setAlign(Align.center);
58 			setScaling(Scaling.none);
59 			this.camera = camera;
60 		}
61 
draw(Batch batch, float parentAlpha)62 		public void draw (Batch batch, float parentAlpha) {
63 			// if this actor is not within the view of the camera we don't draw it.
64 			if (isCulled()) return;
65 
66 			// otherwise we draw via the super class method
67 			super.draw(batch, parentAlpha);
68 		}
69 
70 		/** static helper Rectangles **/
71 		Rectangle actorRect = new Rectangle();
72 		Rectangle camRect = new Rectangle();
73 
isCulled()74 		private boolean isCulled () {
75 			// we start by setting the stage coordinates to this
76 			// actors coordinates which are relative to its parent
77 			// Group.
78 			float stageX = getX();
79 			float stageY = getY();
80 
81 			// now we go up the hierarchy and add all the parents'
82 			// coordinates to this actors coordinates. Note that
83 			// this assumes that neither this actor nor any of its
84 			// parents are rotated or scaled!
85 			Actor parent = this.getParent();
86 			while (parent != null) {
87 				stageX += parent.getX();
88 				stageY += parent.getY();
89 				parent = parent.getParent();
90 			}
91 
92 			// now we check if the rectangle of this actor in screen
93 			// coordinates is in the rectangle spanned by the camera's
94 			// view. This assumes that the camera has no zoom and is
95 			// not rotated!
96 			actorRect.set(stageX, stageY, getWidth(), getHeight());
97 			camRect.set(camera.position.x - camera.viewportWidth / 2.0f, camera.position.y - camera.viewportHeight / 2.0f,
98 				camera.viewportWidth, camera.viewportHeight);
99 			visible = camRect.overlaps(actorRect);
100 			return !visible;
101 		}
102 	}
103 
104 	OrthoCamController camController;
105 	Stage stage;
106 	Texture texture;
107 	SpriteBatch batch;
108 	BitmapFont font;
109 
110 	@Override
create()111 	public void create () {
112 		// create a stage and a camera controller so we can pan the view.
113 		stage = new Stage();;
114 		camController = new OrthoCamController((OrthographicCamera)stage.getCamera()); // we know it's an ortho cam at this point!
115 		Gdx.input.setInputProcessor(camController);
116 
117 		// load a dummy texture
118 		texture = new Texture(Gdx.files.internal("data/badlogicsmall.jpg"));
119 
120 		// populate the stage with some actors and groups.
121 		for (int i = 0; i < 5000; i++) {
122 			Actor img = new CullableActor("img" + i, texture, (OrthographicCamera)stage.getCamera());
123 			img.setX((float)Math.random() * 480 * 10);
124 			img.setY((float)Math.random() * 320 * 10);
125 			stage.addActor(img);
126 		}
127 
128 		// we also want to output the number of visible actors, so we need a SpriteBatch and a BitmapFont
129 		batch = new SpriteBatch();
130 		font = new BitmapFont(Gdx.files.internal("data/arial-15.fnt"), false);
131 	}
132 
render()133 	public void render () {
134 		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
135 		stage.draw();
136 
137 		// check how many actors are visible.
138 		Array<Actor> actors = stage.getActors();
139 		int numVisible = 0;
140 		for (int i = 0; i < actors.size; i++) {
141 			numVisible += ((CullableActor)actors.get(i)).visible ? 1 : 0;
142 		}
143 
144 		batch.begin();
145 		font.draw(batch, "Visible: " + numVisible + ", fps: " + Gdx.graphics.getFramesPerSecond(), 20, 30);
146 		batch.end();
147 	}
148 
149 	@Override
dispose()150 	public void dispose () {
151 		stage.dispose();
152 		texture.dispose();
153 		batch.dispose();
154 		font.dispose();
155 	}
156 }
157