OSDN Git Service

pixmap screencap is now y-up
[mikumikustudio/libgdx-mikumikustudio.git] / gdx / src / com / badlogic / gdx / utils / ScreenUtils.java
1 /*******************************************************************************\r
2  * Copyright 2011 See AUTHORS file.\r
3  * \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
7  * \r
8  *   http://www.apache.org/licenses/LICENSE-2.0\r
9  * \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
16 \r
17 package com.badlogic.gdx.utils;\r
18 \r
19 import java.nio.ByteBuffer;\r
20 \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
28 \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
31  * \r
32  * @author espitz */\r
33 public class ScreenUtils {\r
34 \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
43         }\r
44 \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
50          * \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
59 \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
63 \r
64                 Texture texture = new Texture(pixmap);\r
65                 TextureRegion textureRegion = new TextureRegion(texture, 0, h, w, -h);\r
66                 pixmap.dispose();\r
67 \r
68                 return textureRegion;\r
69         }\r
70         \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
73 \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
77 \r
78                 return pixmap;\r
79         }\r
80 \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
84          * wisely.\r
85          * \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
91         }\r
92 \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
99          * \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
107                 if (flipY) {\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
112                         }\r
113                 } else {\r
114                         pixels.clear();\r
115                         pixels.get(lines);\r
116                 }\r
117                 return lines;\r
118 \r
119         }\r
120 }\r