1 /*******************************************************************************
\r
2 * Copyright 2011 See AUTHORS file.
\r
4 * Licensed under the Apache License, Version 2.0 (the "License");
\r
5 * you may not use this file except in compliance with the License.
\r
6 * You may obtain a copy of the License at
\r
8 * http://www.apache.org/licenses/LICENSE-2.0
\r
10 * Unless required by applicable law or agreed to in writing, software
\r
11 * distributed under the License is distributed on an "AS IS" BASIS,
\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
13 * See the License for the specific language governing permissions and
\r
14 * limitations under the License.
\r
15 ******************************************************************************/
\r
17 package com.badlogic.gdx.utils;
\r
19 import java.nio.ByteBuffer;
\r
21 import com.badlogic.gdx.Gdx;
\r
22 import com.badlogic.gdx.graphics.GL10;
\r
23 import com.badlogic.gdx.graphics.Pixmap;
\r
24 import com.badlogic.gdx.graphics.Pixmap.Format;
\r
25 import com.badlogic.gdx.graphics.Texture;
\r
26 import com.badlogic.gdx.graphics.g2d.TextureRegion;
\r
27 import com.badlogic.gdx.math.MathUtils;
\r
29 /** Class with static helper methods that provide access to the default OpenGL FrameBuffer. These methods can be used to get the
\r
30 * entire screen content or a portion thereof.
\r
33 public class ScreenUtils {
\r
35 /** Returns the default framebuffer contents as a {@link TextureRegion} with a width and height equal to the current screen
\r
36 * size. The base {@link Texture} always has {@link MathUtils#nextPowerOfTwo} dimensions and RGBA8888 {@link Format}. It can be
\r
37 * accessed via {@link TextureRegion#getTexture}. The texture is not managed and has to be reloaded manually on a context loss.
\r
38 * The returned TextureRegion is flipped along the Y axis by default. */
\r
39 public static TextureRegion getFrameBufferTexture () {
\r
40 final int w = Gdx.graphics.getWidth();
\r
41 final int h = Gdx.graphics.getHeight();
\r
42 return getFrameBufferTexture(0, 0, w, h);
\r
45 /** Returns a portion of the default framebuffer contents specified by x, y, width and height as a {@link TextureRegion} with
\r
46 * the same dimensions. The base {@link Texture} always has {@link MathUtils#nextPowerOfTwo} dimensions and RGBA8888
\r
47 * {@link Format}. It can be accessed via {@link TextureRegion#getTexture}. This texture is not managed and has to be reloaded
\r
48 * manually on a context loss. If the width and height specified are larger than the framebuffer dimensions, the Texture will
\r
49 * be padded accordingly. Pixels that fall outside of the current screen will have RGBA values of 0.
\r
51 * @param x the x position of the framebuffer contents to capture
\r
52 * @param y the y position of the framebuffer contents to capture
\r
53 * @param w the width of the framebuffer contents to capture
\r
54 * @param h the height of the framebuffer contents to capture */
\r
55 public static TextureRegion getFrameBufferTexture (int x, int y, int w, int h) {
\r
56 Gdx.gl.glPixelStorei(GL10.GL_PACK_ALIGNMENT, 1);
\r
57 final int potW = MathUtils.nextPowerOfTwo(w);
\r
58 final int potH = MathUtils.nextPowerOfTwo(h);
\r
60 final Pixmap pixmap = new Pixmap(potW, potH, Format.RGBA8888);
\r
61 ByteBuffer pixels = pixmap.getPixels();
\r
62 Gdx.gl.glReadPixels(x, y, potW, potH, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, pixels);
\r
64 Texture texture = new Texture(pixmap);
\r
65 TextureRegion textureRegion = new TextureRegion(texture, 0, h, w, -h);
\r
68 return textureRegion;
\r
71 public static Pixmap getFrameBufferPixmap(int x, int y, int w, int h) {
\r
72 Gdx.gl.glPixelStorei(GL10.GL_PACK_ALIGNMENT, 1);
\r
74 final Pixmap pixmap = new Pixmap(w, h, Format.RGBA8888);
\r
75 ByteBuffer pixels = pixmap.getPixels();
\r
76 Gdx.gl.glReadPixels(x, y, w, h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, pixels);
\r
81 /** Returns the default framebuffer contents as a byte[] array with a length equal to screen width * height * 4. The byte[] will
\r
82 * always contain RGBA8888 data. Because of differences in screen and image origins the framebuffer contents should be flipped
\r
83 * along the Y axis if you intend save them to disk as a bitmap. Flipping is not a cheap operation, so use this functionality
\r
86 * @param flipY whether to flip pixels along Y axis */
\r
87 public static byte[] getFrameBufferPixels (boolean flipY) {
\r
88 final int w = Gdx.graphics.getWidth();
\r
89 final int h = Gdx.graphics.getHeight();
\r
90 return getFrameBufferPixels(0, 0, w, h, flipY);
\r
93 /** Returns a portion of the default framebuffer contents specified by x, y, width and height, as a byte[] array with a length
\r
94 * equal to the specified width * height * 4. The byte[] will always contain RGBA8888 data. If the width and height specified
\r
95 * are larger than the framebuffer dimensions, the Texture will be padded accordingly. Pixels that fall outside of the current
\r
96 * screen will have RGBA values of 0. Because of differences in screen and image origins the framebuffer contents should be
\r
97 * flipped along the Y axis if you intend save them to disk as a bitmap. Flipping is not cheap operation, so use this
\r
98 * functionality wisely.
\r
100 * @param flipY whether to flip pixels along Y axis */
\r
101 public static byte[] getFrameBufferPixels (int x, int y, int w, int h, boolean flipY) {
\r
102 Gdx.gl.glPixelStorei(GL10.GL_PACK_ALIGNMENT, 1);
\r
103 final ByteBuffer pixels = BufferUtils.newByteBuffer(w * h * 4);
\r
104 Gdx.gl.glReadPixels(x, y, w, h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, pixels);
\r
105 final int numBytes = w * h * 4;
\r
106 byte[] lines = new byte[numBytes];
\r
108 final int numBytesPerLine = w * 4;
\r
109 for (int i = 0; i < h; i++) {
\r
110 pixels.position((h - i - 1) * numBytesPerLine);
\r
111 pixels.get(lines, i * numBytesPerLine, numBytesPerLine);
\r