Commit 15fee58e authored by Luboš Horáček's avatar Luboš Horáček

#9 Taking screenshots of OpenGL surface

parent 4f107855
......@@ -2,6 +2,14 @@ android {
buildToolsVersion "21.1.2"
compileSdkVersion 21
defaultConfig {
targetSdkVersion 21
versionName tablexiaVersionName
versionCode tablexiaVersionCode
applicationId rootProject.applicationIdRelease
testApplicationId rootProject.applicationIdRelease + ".test"
}
buildTypes {
debug {
applicationIdSuffix rootProject.applicationIdDebugSuffix
......@@ -18,12 +26,17 @@ android {
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res/main']
assets.srcDirs = ['assets']
java.srcDir file('src/main/java')
}
androidTest {
java.srcDir file('src/androidTest/java')
}
test {
java.srcDir file('src/test/java')
}
release {
res.srcDirs = ['res/release']
}
......@@ -33,14 +46,6 @@ android {
devel {
res.srcDirs = ['res/devel']
}
instrumentTest.setRoot('tests')
}
defaultConfig {
versionName tablexiaVersionName
versionCode tablexiaVersionCode
applicationId rootProject.applicationIdRelease
}
assemble.dependsOn = ['assembleRelease', 'assembleDebug']
......@@ -104,6 +109,7 @@ task copyAndroidNatives() {
}
}
}
task run(type: Exec) {
def path
def localProperties = project.file("../local.properties")
......@@ -125,39 +131,7 @@ task run(type: Exec) {
def adb = path + "/platform-tools/adb"
commandLine "$adb", 'shell', 'am', 'start', '-n', 'cz.nic.tablexia.android/cz.nic.tablexia.android.AndroidLauncher'
}
// sets up the Android Eclipse project, using the old Ant based build.
eclipse {
// need to specify Java source sets explicitely, SpringSource Gradle Eclipse plugin
// ignores any nodes added in classpath.file.withXml
sourceSets {
main {
java.srcDirs "src/main/java", 'gen'
}
androidTest {
java.srcDirs "src/test/java"
}
}
jdt {
sourceCompatibility = 1.6
targetCompatibility = 1.6
}
classpath {
plusConfigurations += [project.configurations.compile]
containers 'com.android.ide.eclipse.adt.ANDROID_FRAMEWORK', 'com.android.ide.eclipse.adt.LIBRARIES'
}
project {
name = appName + "-android"
natures 'com.android.ide.eclipse.adt.AndroidNature'
buildCommands.clear();
buildCommand "com.android.ide.eclipse.adt.ResourceManagerBuilder"
buildCommand "com.android.ide.eclipse.adt.PreCompilerBuilder"
buildCommand "org.eclipse.jdt.core.javabuilder"
buildCommand "com.android.ide.eclipse.adt.ApkBuilder"
}
}
// sets up the Android Idea project, using the old Ant based build.
idea {
module {
......@@ -182,5 +156,9 @@ idea {
}
spoon {
debug = true // for debug output
}
debug = true
failOnFailure = false
//testSizes = ['small', 'medium']
adbTimeout = 10*60
failIfNoDeviceConnected = false
}
\ No newline at end of file
package cz.nic.tablexia.android.test;
package cz.nic.tablexia.android.test.instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.test.UiThreadTest;
import android.test.suitebuilder.annotation.SmallTest;
import com.squareup.spoon.Spoon;
......@@ -13,10 +13,22 @@ public class ScreenTest extends ActivityInstrumentationTestCase2<AndroidLauncher
super(AndroidLauncher.class);
}
@UiThreadTest
public void screenTest() throws Throwable {
@SmallTest
public void testScreenshot() throws Throwable {
final AndroidLauncher act = getActivity();
sleep(10);
Spoon.screenshot(act, "startup");
sleep(10);
Spoon.screenshot(act, "startup");
}
private void sleep(float seconds){
try {
Thread.sleep((int)(seconds * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package cz.nic.tablexia.android;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Environment;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
import java.io.File;
import java.io.FileOutputStream;
import cz.nic.tablexia.Tablexia;
import cz.nic.tablexia.debug.BuildConfig;
import cz.nic.tablexia.util.Log;
public class AndroidLauncher extends AndroidApplication {
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
initialize(new Tablexia(BuildConfig.BUILD_TYPE, getResources().getConfiguration().locale, BuildConfig.VERSION_NAME, savedInstanceState == null), config);
}
private Tablexia tablexia;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
initialize(tablexia = new Tablexia(BuildConfig.BUILD_TYPE, getResources().getConfiguration().locale, BuildConfig.VERSION_NAME, savedInstanceState == null), config);
}
@Override
public void onBackPressed() {
//super.onBackPressed();
tablexia.takeScreenShot(new Tablexia.ScreenshotListener() {
@Override
public void screenshotTaken(int[] screen) {
int width = Gdx.graphics.getWidth();
int height = Gdx.graphics.getHeight();
try {
Bitmap sb = Bitmap.createBitmap(screen, width, height, Bitmap.Config.ARGB_8888);
String file_path = Environment.getExternalStorageDirectory().getAbsolutePath();
File dir = new File(file_path);
dir.mkdirs();
File file = new File(dir, "screenshot_tablexia_" + System.currentTimeMillis() + ".png");
FileOutputStream fOut = new FileOutputStream(file);
sb.compress(Bitmap.CompressFormat.PNG, 85, fOut);
sb.recycle();
fOut.flush();
fOut.close();
} catch (Exception e) {
e.printStackTrace();
Log.err(this.getClass().getSimpleName(), e.getMessage());
}
}
});
}
}
......@@ -5,9 +5,9 @@ buildscript {
}
dependencies {
classpath 'de.richsource.gradle.plugins:gwt-gradle-plugin:0.6'
classpath 'com.android.tools.build:gradle:1.0.0'
classpath 'com.android.tools.build:gradle:1.1.0'
classpath 'org.robovm:robovm-gradle-plugin:1.0.0'
classpath('com.stanfy.spoon:spoon-gradle-plugin:1.0.2')
classpath 'de.felixschulze.gradle:gradle-spoon-plugin:2.1'
classpath 'commons-io:commons-io:2.4'
classpath 'com.google.guava:guava:17.0'
}
......@@ -103,7 +103,6 @@ project(":android") {
compile "com.badlogicgames.gdx:gdx-backend-android:$gdxVersion"
compile "com.badlogicgames.gdx:gdx-freetype:$gdxVersion"
compile "net.engio:mbassador:$mbassadorVersion"
androidTestCompile "com.squareup.spoon:spoon-client:1.1.2"
natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-armeabi"
natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-armeabi-v7a"
......@@ -111,6 +110,10 @@ project(":android") {
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi"
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi-v7a"
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86"
testCompile 'org.robolectric:robolectric:2.3'
androidTestCompile "com.squareup.spoon:spoon-client:1.1.7"
androidTestCompile 'com.jayway.android.robotium:robotium-solo:5.3.1'
}
}
......
......@@ -2,9 +2,11 @@ package cz.nic.tablexia;
import com.badlogic.gdx.Application;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL30;
import net.engio.mbassy.listener.Handler;
import java.nio.ByteBuffer;
import java.util.Locale;
import cz.nic.tablexia.bus.ApplicationBus;
......@@ -23,10 +25,10 @@ import cz.nic.tablexia.util.Utility;
public class Tablexia extends TablexiaApplication {
private boolean loadingComplete = false;
private MainMenuContainer mainMenuContainer;
private ZipAssetLoader zipAssetLoader;
private boolean resetState;
private boolean loadingComplete = false;
private MainMenuContainer mainMenuContainer;
private ZipAssetLoader zipAssetLoader;
private boolean resetState;
public Tablexia(boolean debug, Locale systemLocale, String versionName, boolean resetState) {
TablexiaSettings.init(debug, systemLocale, versionName);
......@@ -116,9 +118,9 @@ public class Tablexia extends TablexiaApplication {
TablexiaSettings.getInstance().loadPreferences(resetState);
Log.setLoglevel(TablexiaSettings.getInstance().getLogLevel());
// init event bus handlers
ApplicationBus.getInstance().subscribe(this);
// init event bus handlers
ApplicationBus.getInstance().subscribe(this);
// start loading application scope data
startLoading(TablexiaSettings.getInstance().getLocale());
......@@ -133,11 +135,17 @@ public class Tablexia extends TablexiaApplication {
super.pause();
}
@Override
public void render() {
// render other screens
super.render();
if (screenShot) {
screenShot = false;
obtainScreenshot();
}
// process loading
if (!loadingComplete) {
// load internal assets
......@@ -153,6 +161,48 @@ public class Tablexia extends TablexiaApplication {
}
}
boolean screenShot = false;
ScreenshotListener listener;
public void takeScreenShot(ScreenshotListener listener) {
screenShot = true;
this.listener = listener;
}
public static interface ScreenshotListener {
public void screenshotTaken(int[] screen);
}
private void obtainScreenshot() {
Gdx.gl.glFinish();
int width = Gdx.graphics.getWidth();
int height = Gdx.graphics.getHeight();
int bt[] = new int[width * height];
ByteBuffer pbuf = ByteBuffer.allocateDirect(width * height * 4);
//pbuf.order(ByteOrder.LITTLE_ENDIAN);
Gdx.gl.glReadPixels(0, 0, width, height, GL30.GL_RGBA, GL30.GL_UNSIGNED_BYTE, pbuf);
for (int i = 0; i < height; i++) {//remember, that OpenGL bitmap is incompatible with Android bitmap
//and so, some correction need.
for (int j = 0; j < width; j++) {
int pr = pbuf.get(4 * i * j + j);
int pg = pbuf.get(4 * i * j + j + 1);
int pb = pbuf.get(4 * i * j + j + 2);
//int pa = pbuf.get(4 * i * j + j + 3);
int pa = 1;
int color = (pa << 24) | (pr << 16) | (pg << 8) | pb;
bt[(i * j) + j] = color;
}
}
if (listener != null) {
listener.screenshotTaken(bt);
}
}
@Override
public void dispose() {
super.dispose();
......@@ -191,11 +241,11 @@ public class Tablexia extends TablexiaApplication {
public void handleChangeScreenEvent(final ChangeScreenEvent changeScreenEvent) {
final Class<? extends AbstractTablexiaScreen<?>> screenClass = changeScreenEvent.getScreen();
if (!loadingComplete) {
Log.err(((Object)this).getClass(), "Cannot change screen -> Application loading not complete!");
Log.err(((Object) this).getClass(), "Cannot change screen -> Application loading not complete!");
return;
}
if (screenClass == null) {
Log.err(((Object)this).getClass(), "Cannot change screen -> Received empty screen class!");
Log.err(((Object) this).getClass(), "Cannot change screen -> Received empty screen class!");
return;
}
// create new screen on GL thread
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment