gdx-html backend stuff

This commit is contained in:
Hannes Janetzek 2013-06-26 12:05:42 +02:00
parent 57a3cb7763
commit 85389dce85
17 changed files with 3077 additions and 15 deletions

View File

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8"?>
<classpath> <classpath>
<classpathentry kind="src" path="src"/> <classpathentry excluding="org/oscim/gdx/emu/" kind="src" path="src"/>
<classpathentry combineaccessrules="false" kind="src" path="/vtm-gdx"/> <classpathentry kind="src" path="src/org/oscim/gdx/emu"/>
<classpathentry kind="con" path="com.google.gwt.eclipse.core.GWT_CONTAINER"/> <classpathentry combineaccessrules="false" kind="src" path="/vtm-gdx"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="con" path="com.google.gwt.eclipse.core.GWT_CONTAINER"/>
<classpathentry combineaccessrules="false" kind="src" path="/vtm"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="war/WEB-INF/classes"/> <classpathentry combineaccessrules="false" kind="src" path="/vtm"/>
<classpathentry kind="lib" path="war/WEB-INF/lib/gdx-backend-gwt-sources.jar"/> <classpathentry kind="lib" path="/vtm-gdx/libs/gdx-sources.jar"/>
<classpathentry kind="lib" path="war/WEB-INF/lib/gdx-backend-gwt.jar" sourcepath="war/WEB-INF/lib/gdx-backend-gwt-sources.jar"/> <classpathentry kind="lib" path="/vtm-gdx/libs/gdx.jar" sourcepath="/vtm-gdx/libs/gdx-sources.jar"/>
<classpathentry kind="lib" path="/vtm-gdx/libs/gdx-sources.jar"/> <classpathentry combineaccessrules="false" kind="src" path="/gdx-backends-gwt"/>
<classpathentry kind="lib" path="/vtm-gdx/libs/gdx.jar" sourcepath="/vtm-gdx/libs/gdx-sources.jar"/> <classpathentry kind="output" path="war/WEB-INF/classes"/>
</classpath> </classpath>

View File

@ -1,4 +1,4 @@
eclipse.preferences.version=1 eclipse.preferences.version=1
entryPointModules= entryPointModules=
filesCopiedToWebInfLib=gwt-servlet.jar filesCopiedToWebInfLib=gwt-servlet.jar
gwtCompileSettings=PGd3dC1jb21waWxlLXNldHRpbmdzPjxsb2ctbGV2ZWw+SU5GTzwvbG9nLWxldmVsPjxvdXRwdXQtc3R5bGU+UFJFVFRZPC9vdXRwdXQtc3R5bGU+PGV4dHJhLWFyZ3M+PCFbQ0RBVEFbXV0+PC9leHRyYS1hcmdzPjx2bS1hcmdzPjwhW0NEQVRBWy1YbXg1MTJtXV0+PC92bS1hcmdzPjxlbnRyeS1wb2ludC1tb2R1bGU+b3JnLm9zY2ltLmdkeC5Hd3REZWZpbml0aW9uPC9lbnRyeS1wb2ludC1tb2R1bGU+PC9nd3QtY29tcGlsZS1zZXR0aW5ncz4\= gwtCompileSettings=PGd3dC1jb21waWxlLXNldHRpbmdzPjxsb2ctbGV2ZWw+SU5GTzwvbG9nLWxldmVsPjxvdXRwdXQtc3R5bGU+UFJFVFRZPC9vdXRwdXQtc3R5bGU+PGV4dHJhLWFyZ3M+PCFbQ0RBVEFbXV0+PC9leHRyYS1hcmdzPjx2bS1hcmdzPjwhW0NEQVRBWy1YbXgxMDI0bV1dPjwvdm0tYXJncz48ZW50cnktcG9pbnQtbW9kdWxlPm9yZy5vc2NpbS5nZHguR3d0RGVmaW5pdGlvbjwvZW50cnktcG9pbnQtbW9kdWxlPjwvZ3d0LWNvbXBpbGUtc2V0dGluZ3M+

View File

@ -4,4 +4,5 @@
<set-configuration-property name="gdx.assetpath" value="../vtm/assets"/> <set-configuration-property name="gdx.assetpath" value="../vtm/assets"/>
<inherits name="GdxMap"/> <inherits name="GdxMap"/>
<inherits name="com.badlogic.gdx.backends.gdx_backends_gwt"/> <inherits name="com.badlogic.gdx.backends.gdx_backends_gwt"/>
<super-source path="emu" />
</module> </module>

View File

@ -0,0 +1,61 @@
package org.oscim.gdx.client;
import org.oscim.backend.canvas.Bitmap;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.Pixmap;
import com.google.gwt.dom.client.ImageElement;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.RootPanel;
public class GwtBitmap implements Bitmap {
Pixmap bitmap;
Image image;
public GwtBitmap(Image data) {
ImageElement imageElement = ImageElement.as(data.getElement());
bitmap = new Pixmap(imageElement);
image = data;
}
@Override
public int getWidth() {
return bitmap.getWidth();
}
@Override
public int getHeight() {
return bitmap.getHeight();
}
@Override
public void recycle() {
bitmap.dispose();
}
@Override
public int[] getPixels() {
return null;
}
@Override
public void eraseColor(int color) {
}
@Override
public int uploadToTexture(boolean replace) {
Gdx.gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, bitmap.getGLInternalFormat(), bitmap.getWidth(),
bitmap.getHeight(), 0,
bitmap.getGLFormat(), bitmap.getGLType(), bitmap.getPixels());
bitmap.dispose();
if (image != null)
RootPanel.get().remove(image);
return 1;
}
}

View File

@ -0,0 +1,48 @@
package org.oscim.gdx.client;
import java.io.InputStream;
import org.oscim.backend.CanvasAdapter;
import org.oscim.backend.canvas.Bitmap;
import org.oscim.backend.canvas.Canvas;
import org.oscim.backend.canvas.Paint;
public class GwtCanvasAdapter extends CanvasAdapter {
@Override
public Bitmap decodeBitmap(InputStream in) {
return null;
}
@Override
public int getColor(Color color) {
// TODO Auto-generated method stub
return 0;
}
@Override
public Paint getPaint() {
// TODO Auto-generated method stub
return null;
}
@Override
public int parseColor(String colorString) {
// TODO Auto-generated method stub
return 0;
}
@Override
public Bitmap getBitmap(int width, int height, int format) {
// TODO Auto-generated method stub
return null;
}
@Override
public Canvas getCanvas() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -0,0 +1,16 @@
package org.oscim.gdx.client;
import org.oscim.backend.GL20;
import org.oscim.backend.GLAdapter;
import org.oscim.gdx.GdxMap;
import com.badlogic.gdx.Gdx;
public class GwtGdxMap extends GdxMap {
@Override
public void create() {
GLAdapter.INSTANCE = (GL20)Gdx.graphics.getGL20(); //(GL20)Gdx.gl20;
super.create();
}
}

View File

@ -1,19 +1,24 @@
package org.oscim.gdx.client; package org.oscim.gdx.client;
import org.oscim.gdx.GdxMap;
import com.badlogic.gdx.ApplicationListener; import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.backends.gwt.GwtApplication; import com.badlogic.gdx.backends.gwt.GwtApplication;
import com.badlogic.gdx.backends.gwt.GwtApplicationConfiguration; import com.badlogic.gdx.backends.gwt.GwtApplicationConfiguration;
public class GwtLauncher extends GwtApplication { public class GwtLauncher extends GwtApplication {
@Override @Override
public GwtApplicationConfiguration getConfig () { public GwtApplicationConfiguration getConfig () {
GwtApplicationConfiguration cfg = new GwtApplicationConfiguration(480, 320); GwtApplicationConfiguration cfg = new GwtApplicationConfiguration(1400, 800);
cfg.stencil = true;
cfg.fps = 20;
return cfg; return cfg;
} }
@Override @Override
public ApplicationListener getApplicationListener () { public ApplicationListener getApplicationListener () {
return new GdxMap();
return new GwtGdxMap();
} }
} }

View File

@ -0,0 +1,491 @@
/*******************************************************************************
* Copyright 2011 See AUTHORS file.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.badlogic.gdx.backends.gwt;
import com.badlogic.gdx.Application;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Audio;
import com.badlogic.gdx.Files;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Graphics;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.LifecycleListener;
import com.badlogic.gdx.Net;
import com.badlogic.gdx.Preferences;
import com.badlogic.gdx.backends.gwt.preloader.Preloader;
import com.badlogic.gdx.backends.gwt.preloader.Preloader.PreloaderCallback;
import com.badlogic.gdx.backends.gwt.preloader.Preloader.PreloaderState;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Clipboard;
import com.badlogic.gdx.utils.ObjectMap;
import com.badlogic.gdx.utils.TimeUtils;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.InlineHTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.VerticalPanel;
/** Implementation of an {@link Application} based on GWT. Clients have to override {@link #getConfig()} and
* {@link #getApplicationListener()}. Clients can override the default loading screen via
* {@link #getPreloaderCallback()} and implement any loading screen drawing via GWT widgets.
* @author mzechner */
public abstract class GwtApplication implements EntryPoint, Application {
private ApplicationListener listener;
private GwtApplicationConfiguration config;
private GwtGraphics graphics;
private GwtInput input;
private GwtNet net;
private Panel root = null;
private TextArea log = null;
private int logLevel = LOG_ERROR;
private Array<Runnable> runnables = new Array<Runnable>();
private Array<Runnable> runnablesHelper = new Array<Runnable>();
private Array<LifecycleListener> lifecycleListeners = new Array<LifecycleListener>();
private int lastWidth, lastHeight;
private Preloader preloader;
private static AgentInfo agentInfo;
private ObjectMap<String, Preferences> prefs = new ObjectMap<String, Preferences>();
/** @return the configuration for the {@link GwtApplication}. */
public abstract GwtApplicationConfiguration getConfig ();
@Override
public void onModuleLoad () {
consoleLog("onModuleLoad");
this.agentInfo = computeAgentInfo();
this.listener = getApplicationListener();
this.config = getConfig();
this.log = config.log;
if (config.rootPanel != null) {
this.root = config.rootPanel;
} else {
Element element = Document.get().getElementById("embed-" + GWT.getModuleName());
if (element == null) {
VerticalPanel panel = new VerticalPanel();
panel.setWidth("" + config.width + "px");
panel.setHeight("" + config.height + "px");
panel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
panel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
RootPanel.get().add(panel);
RootPanel.get().setWidth("" + config.width + "px");
RootPanel.get().setHeight("" + config.height + "px");
this.root = panel;
} else {
VerticalPanel panel = new VerticalPanel();
panel.setWidth("" + config.width + "px");
panel.setHeight("" + config.height + "px");
panel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
panel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
element.appendChild(panel.getElement());
root = panel;
}
}
// initialize SoundManager2
//SoundManager.init(GWT.getModuleBaseURL(), 9);
// wait for soundmanager to load, this is fugly, but for
// some reason the ontimeout and onerror callbacks are never
// called (function instanceof Function fails, wtf JS?).
new Timer() {
@Override
public void run () {
//if (SoundManager.ok()) {
final PreloaderCallback callback = getPreloaderCallback();
preloader = new Preloader();
preloader.preload("assets.txt", new PreloaderCallback() {
@Override
public void error (String file) {
callback.error(file);
}
@Override
public void update (PreloaderState state) {
callback.update(state);
if (state.hasEnded()) {
root.clear();
setupLoop();
}
}
});
cancel();
//}
}
}.scheduleRepeating(100);
}
private void setupLoop () {
// setup modules
consoleLog("setupLoop");
try {
graphics = new GwtGraphics(root, config);
} catch (Throwable e) {
root.clear();
root.add(new Label("Sorry, your browser doesn't seem to support WebGL"));
return;
}
lastWidth = graphics.getWidth();
lastHeight = graphics.getHeight();
Gdx.app = this;
//Gdx.audio = new GwtAudio();
Gdx.graphics = graphics;
Gdx.gl20 = graphics.getGL20();
Gdx.gl = graphics.getGLCommon();
Gdx.files = new GwtFiles(preloader);
this.input = new GwtInput(graphics.canvas);
Gdx.input = this.input;
this.net = new GwtNet();
Gdx.net = this.net;
// tell listener about app creation
try {
listener.create();
listener.resize(graphics.getWidth(), graphics.getHeight());
} catch (Throwable t) {
error("GwtApplication", "exception: " + t.getMessage(), t);
t.printStackTrace();
throw new RuntimeException(t);
}
// setup rendering timer
new Timer() {
@Override
public void run () {
try {
graphics.update();
if (Gdx.graphics.getWidth() != lastWidth || Gdx.graphics.getHeight() != lastHeight) {
GwtApplication.this.listener.resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
lastWidth = graphics.getWidth();
lastHeight = graphics.getHeight();
Gdx.gl.glViewport(0, 0, lastWidth, lastHeight);
}
runnablesHelper.addAll(runnables);
runnables.clear();
for (int i = 0; i < runnablesHelper.size; i++) {
runnablesHelper.get(i).run();
}
runnablesHelper.clear();
listener.render();
input.justTouched = false;
} catch (Throwable t) {
error("GwtApplication", "exception: " + t.getMessage(), t);
throw new RuntimeException(t);
}
}
}.scheduleRepeating((int)((1f / config.fps) * 1000));
}
public Panel getRootPanel () {
return root;
}
long loadStart = TimeUtils.nanoTime();
public PreloaderCallback getPreloaderCallback () {
final Panel preloaderPanel = new VerticalPanel();
preloaderPanel.setStyleName("gdx-preloader");
final Image logo = new Image(GWT.getModuleBaseURL() + "logo.png");
logo.setStyleName("logo");
preloaderPanel.add(logo);
final Panel meterPanel = new SimplePanel();
meterPanel.setStyleName("gdx-meter");
meterPanel.addStyleName("red");
final InlineHTML meter = new InlineHTML();
final Style meterStyle = meter.getElement().getStyle();
meterStyle.setWidth(0, Unit.PCT);
meterPanel.add(meter);
preloaderPanel.add(meterPanel);
getRootPanel().add(preloaderPanel);
return new PreloaderCallback() {
@Override
public void error (String file) {
System.out.println("error: " + file);
}
@Override
public void update (PreloaderState state) {
meterStyle.setWidth(100f * state.getProgress(), Unit.PCT);
}
};
}
@Override
public Graphics getGraphics () {
return graphics;
}
@Override
public Audio getAudio () {
return Gdx.audio;
}
@Override
public Input getInput () {
return Gdx.input;
}
@Override
public Files getFiles () {
return Gdx.files;
}
@Override
public Net getNet() {
return Gdx.net;
}
private void checkLogLabel () {
if (log == null) {
log = new TextArea();
log.setSize(graphics.getWidth() + "px", "200px");
log.setReadOnly(true);
root.add(log);
}
}
@Override
public void log (String tag, String message) {
if (logLevel >= LOG_INFO) {
checkLogLabel();
log.setText(log.getText() + "\n" + tag + ": " + message);
log.setCursorPos(log.getText().length() - 1);
System.out.println(tag + ": " + message);
}
}
@Override
public void log (String tag, String message, Exception exception) {
if (logLevel >= LOG_INFO) {
checkLogLabel();
log.setText(log.getText() + "\n" + tag + ": " + message + "\n" + exception.getMessage() + "\n");
log.setCursorPos(log.getText().length() - 1);
System.out.println(tag + ": " + message + "\n" + exception.getMessage());
System.out.println(getStackTrace(exception));
}
}
@Override
public void error (String tag, String message) {
if (logLevel >= LOG_ERROR) {
checkLogLabel();
log.setText(log.getText() + "\n" + tag + ": " + message);
log.setCursorPos(log.getText().length() - 1);
System.err.println(tag + ": " + message);
}
}
@Override
public void error (String tag, String message, Throwable exception) {
if (logLevel >= LOG_ERROR) {
checkLogLabel();
log.setText(log.getText() + "\n" + tag + ": " + message + "\n" + exception.getMessage());
log.setCursorPos(log.getText().length() - 1);
System.err.println(tag + ": " + message + "\n" + exception.getMessage() + "\n");
System.out.println(getStackTrace(exception));
}
}
@Override
public void debug (String tag, String message) {
if (logLevel >= LOG_DEBUG) {
checkLogLabel();
log.setText(log.getText() + "\n" + tag + ": " + message + "\n");
log.setCursorPos(log.getText().length() - 1);
System.out.println(tag + ": " + message + "\n");
}
}
@Override
public void debug (String tag, String message, Throwable exception) {
if (logLevel >= LOG_DEBUG) {
checkLogLabel();
log.setText(log.getText() + "\n" + tag + ": " + message + "\n" + exception.getMessage() + "\n");
log.setCursorPos(log.getText().length() - 1);
System.out.println(tag + ": " + message + "\n" + exception.getMessage());
System.out.println(getStackTrace(exception));
}
}
private String getStackTrace (Throwable e) {
StringBuffer buffer = new StringBuffer();
for (StackTraceElement trace : e.getStackTrace()) {
buffer.append(trace.toString() + "\n");
}
return buffer.toString();
}
@Override
public void setLogLevel (int logLevel) {
this.logLevel = logLevel;
}
@Override
public ApplicationType getType () {
return ApplicationType.WebGL;
}
@Override
public int getVersion () {
return 0;
}
@Override
public long getJavaHeap () {
return 0;
}
@Override
public long getNativeHeap () {
return 0;
}
@Override
public Preferences getPreferences (String name) {
Preferences pref = prefs.get(name);
if (pref == null) {
pref = new GwtPreferences(name);
prefs.put(name, pref);
}
return pref;
}
@Override
public Clipboard getClipboard() {
return new Clipboard() {
@Override
public String getContents () {
return null;
}
@Override
public void setContents (String content) {
}
};
}
@Override
public void postRunnable (Runnable runnable) {
runnables.add(runnable);
}
@Override
public void exit () {
}
/** Contains precomputed information on the user-agent. Useful for dealing with browser and OS behavioral differences. Kindly
* borrowed from PlayN */
public static AgentInfo agentInfo () {
return agentInfo;
}
/** kindly borrowed from PlayN **/
private static native AgentInfo computeAgentInfo () /*-{
var userAgent = navigator.userAgent.toLowerCase();
return {
// browser type flags
isFirefox : userAgent.indexOf("firefox") != -1,
isChrome : userAgent.indexOf("chrome") != -1,
isSafari : userAgent.indexOf("safari") != -1,
isOpera : userAgent.indexOf("opera") != -1,
isIE : userAgent.indexOf("msie") != -1,
// OS type flags
isMacOS : userAgent.indexOf("mac") != -1,
isLinux : userAgent.indexOf("linux") != -1,
isWindows : userAgent.indexOf("win") != -1
};
}-*/;
/** Returned by {@link #agentInfo}. Kindly borrowed from PlayN. */
public static class AgentInfo extends JavaScriptObject {
public final native boolean isFirefox () /*-{
return this.isFirefox;
}-*/;
public final native boolean isChrome () /*-{
return this.isChrome;
}-*/;
public final native boolean isSafari () /*-{
return this.isSafari;
}-*/;
public final native boolean isOpera () /*-{
return this.isOpera;
}-*/;
public final native boolean isIE () /*-{
return this.isIE;
}-*/;
public final native boolean isMacOS () /*-{
return this.isMacOS;
}-*/;
public final native boolean isLinux () /*-{
return this.isLinux;
}-*/;
public final native boolean isWindows () /*-{
return this.isWindows;
}-*/;
protected AgentInfo () {
}
}
public String getBaseUrl () {
return preloader.baseUrl;
}
public Preloader getPreloader () {
return preloader;
}
@Override
public void addLifecycleListener (LifecycleListener listener) {
synchronized(lifecycleListeners) {
lifecycleListeners.add(listener);
}
}
@Override
public void removeLifecycleListener (LifecycleListener listener) {
synchronized(lifecycleListeners) {
lifecycleListeners.removeValue(listener, true);
}
}
native void consoleLog(String message) /*-{
console.log( "GWT:" + message );
}-*/;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,373 @@
/*******************************************************************************
* Copyright 2011 See AUTHORS file.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.badlogic.gdx.graphics;
import java.nio.Buffer;
import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.Map;
import com.badlogic.gdx.backends.gwt.GwtFileHandle;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.BufferUtils;
import com.badlogic.gdx.utils.Disposable;
import com.badlogic.gdx.utils.GdxRuntimeException;
import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.canvas.dom.client.CanvasPixelArray;
import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.canvas.dom.client.Context2d.Composite;
import com.google.gwt.dom.client.CanvasElement;
import com.google.gwt.dom.client.ImageElement;
public class Pixmap implements Disposable {
public static Map<Integer, Pixmap> pixmaps = new HashMap<Integer, Pixmap>();
static int nextId = 0;
/** Different pixel formats.
*
* @author mzechner */
public enum Format {
Alpha, Intensity, LuminanceAlpha, RGB565, RGBA4444, RGB888, RGBA8888;
}
/** Blending functions to be set with {@link Pixmap#setBlending}.
* @author mzechner */
public enum Blending {
None, SourceOver
}
/** Filters to be used with {@link Pixmap#drawPixmap(Pixmap, int, int, int, int, int, int, int, int)}.
*
* @author mzechner */
public enum Filter {
NearestNeighbour, BiLinear
}
int width;
int height;
Format format;
Canvas canvas;
Context2d context;
int id;
IntBuffer buffer;
int r = 255, g = 255, b = 255;
float a;
String color = make(r, g, b, a);
static Blending blending;
CanvasPixelArray pixels;
public Pixmap (FileHandle file) {
GwtFileHandle gwtFile = (GwtFileHandle)file;
ImageElement img = gwtFile.preloader.images.get(file.path());
if (img == null) throw new GdxRuntimeException("Couldn't load image '" + file.path() + "', file does not exist");
create(img.getWidth(), img.getHeight(), Format.RGBA8888);
context.setGlobalCompositeOperation(Composite.COPY);
context.drawImage(img, 0, 0);
context.setGlobalCompositeOperation(getComposite());
}
private static Composite getComposite () {
return blending == Blending.None ? Composite.COPY : Composite.SOURCE_OVER;
}
public Pixmap (ImageElement img) {
create(img.getWidth(), img.getHeight(), Format.RGBA8888);
context.drawImage(img, 0, 0);
}
public Pixmap (int width, int height, Format format) {
create(width, height, format);
}
private void create (int width, int height, Format format2) {
this.width = width;
this.height = height;
this.format = Format.RGBA8888;
canvas = Canvas.createIfSupported();
canvas.getCanvasElement().setWidth(width);
canvas.getCanvasElement().setHeight(height);
context = canvas.getContext2d();
context.setGlobalCompositeOperation(getComposite());
buffer = BufferUtils.newIntBuffer(1);
id = nextId++;
buffer.put(0, id);
pixmaps.put(id, this);
}
public static String make (int r2, int g2, int b2, float a2) {
return "rgba(" + r2 + "," + g2 + "," + b2 + "," + a2 + ")";
}
/** Sets the type of {@link Blending} to be used for all operations. Default is {@link Blending#SourceOver}.
* @param blending the blending type */
public static void setBlending (Blending blending) {
Pixmap.blending = blending;
Composite composite = getComposite();
for (Pixmap pixmap : pixmaps.values()) {
pixmap.context.setGlobalCompositeOperation(composite);
}
}
/** @return the currently set {@link Blending} */
public static Blending getBlending () {
return blending;
}
/** Sets the type of interpolation {@link Filter} to be used in conjunction with
* {@link Pixmap#drawPixmap(Pixmap, int, int, int, int, int, int, int, int)}.
* @param filter the filter. */
public static void setFilter (Filter filter) {
}
public Format getFormat () {
return format;
}
public int getGLInternalFormat () {
return GL20.GL_RGBA;
}
public int getGLFormat () {
return GL20.GL_RGBA;
}
public int getGLType () {
return GL20.GL_UNSIGNED_BYTE;
}
public int getWidth () {
return width;
}
public int getHeight () {
return height;
}
public Buffer getPixels () {
return buffer;
}
@Override
public void dispose () {
pixmaps.remove(id);
}
public CanvasElement getCanvasElement () {
return canvas.getCanvasElement();
}
/** Sets the color for the following drawing operations
* @param color the color, encoded as RGBA8888 */
public void setColor (int color) {
r = (color >>> 24) & 0xff;
g = (color >>> 16) & 0xff;
b = (color >>> 8) & 0xff;
a = (color & 0xff) / 255f;
this.color = make(r, g, b, a);
context.setFillStyle(this.color);
context.setStrokeStyle(this.color);
}
/** Sets the color for the following drawing operations.
*
* @param r The red component.
* @param g The green component.
* @param b The blue component.
* @param a The alpha component. */
public void setColor (float r, float g, float b, float a) {
this.r = (int)(r * 255);
this.g = (int)(g * 255);
this.b = (int)(b * 255);
this.a = a;
color = make(this.r, this.g, this.b, this.a);
context.setFillStyle(color);
context.setStrokeStyle(this.color);
}
/** Sets the color for the following drawing operations.
* @param color The color. */
public void setColor (Color color) {
setColor(color.r, color.g, color.b, color.a);
}
/** Fills the complete bitmap with the currently set color. */
public void fill () {
context.fillRect(0, 0, getWidth(), getHeight());
}
// /**
// * Sets the width in pixels of strokes.
// *
// * @param width The stroke width in pixels.
// */
// public void setStrokeWidth (int width);
/** Draws a line between the given coordinates using the currently set color.
*
* @param x The x-coodinate of the first point
* @param y The y-coordinate of the first point
* @param x2 The x-coordinate of the first point
* @param y2 The y-coordinate of the first point */
public void drawLine (int x, int y, int x2, int y2) {
context.beginPath();
context.moveTo(x, y);
context.lineTo(x2, y2);
context.stroke();
context.closePath();
}
/** Draws a rectangle outline starting at x, y extending by width to the right and by height downwards (y-axis points downwards)
* using the current color.
*
* @param x The x coordinate
* @param y The y coordinate
* @param width The width in pixels
* @param height The height in pixels */
public void drawRectangle (int x, int y, int width, int height) {
context.beginPath();
context.rect(x, y, width, height);
context.stroke();
context.closePath();
}
/** Draws an area form another Pixmap to this Pixmap.
*
* @param pixmap The other Pixmap
* @param x The target x-coordinate (top left corner)
* @param y The target y-coordinate (top left corner) */
public void drawPixmap (Pixmap pixmap, int x, int y) {
context.drawImage(pixmap.getCanvasElement(), x, y);
}
/** Draws an area form another Pixmap to this Pixmap.
*
* @param pixmap The other Pixmap
* @param x The target x-coordinate (top left corner)
* @param y The target y-coordinate (top left corner)
* @param srcx The source x-coordinate (top left corner)
* @param srcy The source y-coordinate (top left corner);
* @param srcWidth The width of the area form the other Pixmap in pixels
* @param srcHeight The height of the area form the other Pixmap in pixles */
public void drawPixmap (Pixmap pixmap, int x, int y, int srcx, int srcy, int srcWidth, int srcHeight) {
context.drawImage(pixmap.getCanvasElement(), srcx, srcy, srcWidth, srcHeight, x, y, srcWidth, srcHeight);
}
/** Draws an area form another Pixmap to this Pixmap. This will automatically scale and stretch the source image to the
* specified target rectangle. Use {@link Pixmap#setFilter(Filter)} to specify the type of filtering to be used (nearest
* neighbour or bilinear).
*
* @param pixmap The other Pixmap
* @param srcx The source x-coordinate (top left corner)
* @param srcy The source y-coordinate (top left corner);
* @param srcWidth The width of the area form the other Pixmap in pixels
* @param srcHeight The height of the area form the other Pixmap in pixles
* @param dstx The target x-coordinate (top left corner)
* @param dsty The target y-coordinate (top left corner)
* @param dstWidth The target width
* @param dstHeight the target height */
public void drawPixmap (Pixmap pixmap, int srcx, int srcy, int srcWidth, int srcHeight, int dstx, int dsty, int dstWidth,
int dstHeight) {
context.drawImage(pixmap.getCanvasElement(), srcx, srcy, srcWidth, srcHeight, dstx, dsty, dstWidth, dstHeight);
}
/** Fills a rectangle starting at x, y extending by width to the right and by height downwards (y-axis points downwards) using
* the current color.
*
* @param x The x coordinate
* @param y The y coordinate
* @param width The width in pixels
* @param height The height in pixels */
public void fillRectangle (int x, int y, int width, int height) {
context.fillRect(x, y, width, height);
}
/** Draws a circle outline with the center at x,y and a radius using the current color and stroke width.
*
* @param x The x-coordinate of the center
* @param y The y-coordinate of the center
* @param radius The radius in pixels */
public void drawCircle (int x, int y, int radius) {
context.beginPath();
context.arc(x, y, radius, 0, 2 * Math.PI, false);
context.stroke();
context.closePath();
}
/** Fills a circle with the center at x,y and a radius using the current color.
*
* @param x The x-coordinate of the center
* @param y The y-coordinate of the center
* @param radius The radius in pixels */
public void fillCircle (int x, int y, int radius) {
context.beginPath();
context.arc(x, y, radius, 0, 2 * Math.PI, false);
context.fill();
context.closePath();
}
/** Fills a triangle with vertices at x1,y1 and x2,y2 and x3,y3 using the current color.
*
* @param x1 The x-coordinate of vertex 1
* @param y1 The y-coordinate of vertex 1
* @param x2 The x-coordinate of vertex 2
* @param y2 The y-coordinate of vertex 2
* @param x3 The x-coordinate of vertex 3
* @param y3 The y-coordinate of vertex 3 */
public void fillTriangle (int x1, int y1, int x2, int y2, int x3, int y3) {
context.beginPath();
context.moveTo(x1,y1);
context.lineTo(x2,y2);
context.lineTo(x3,y3);
context.lineTo(x1,y1);
context.fill();
context.closePath();
}
/** Returns the 32-bit RGBA8888 value of the pixel at x, y. For Alpha formats the RGB components will be one.
*
* @param x The x-coordinate
* @param y The y-coordinate
* @return The pixel color in RGBA8888 format. */
public int getPixel (int x, int y) {
if (pixels == null) pixels = context.getImageData(0, 0, width, height).getData();
int i = x * 4 + y * width * 4;
int r = pixels.get(i + 0) & 0xff;
int g = pixels.get(i + 1) & 0xff;
int b = pixels.get(i + 2) & 0xff;
int a = pixels.get(i + 3) & 0xff;
return (r << 24) | (g << 16) | (b << 8) | (a);
}
/** Draws a pixel at the given location with the current color.
*
* @param x the x-coordinate
* @param y the y-coordinate */
public void drawPixel (int x, int y) {
context.fillRect(x, y, 1, 1);
}
/** Draws a pixel at the given location with the given color.
*
* @param x the x-coordinate
* @param y the y-coordinate
* @param color the color in RGBA8888 format. */
public void drawPixel (int x, int y, int color) {
setColor(color);
drawPixel(x, y);
}
}

View File

@ -0,0 +1,11 @@
package java.net;
public class MalformedURLException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,17 @@
package java.net;
public class URL {
@Override
public String toString() {
return mPath;
}
String mProtocol;
String mHostname;
int mPort;
String mPath;
public URL(String protocol, String hostName, int port, String path) {
mPath = "http://" +hostName +"/" + path;
}
}

View File

@ -0,0 +1,12 @@
package java.util.concurrent;
import java.util.ArrayList;
public class CopyOnWriteArrayList<E> extends ArrayList<E> {
/**
*
*/
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,104 @@
/*
* Copyright 2010, 2011, 2012 mapsforge.org
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.oscim.core;
import org.oscim.layers.tile.TileLoader;
/**
* A tile represents a rectangular part of the world map. All tiles can be
* identified by their X and Y number together with their zoom level. The actual
* area that a tile covers on a map depends on the underlying map projection.
*/
public class Tile {
public TileLoader loader;
/**
* Width and height of a map tile in pixel.
*/
public static int SIZE = 256;
/**
* The X number of this tile.
*/
public final int tileX;
/**
* The Y number of this tile.
*/
public final int tileY;
/**
* The Zoom level of this tile.
*/
public final byte zoomLevel;
/**
* @param tileX
* the X number of the tile.
* @param tileY
* the Y number of the tile.
* @param zoomLevel
* the zoom level of the tile.
*/
public Tile(int tileX, int tileY, byte zoomLevel) {
this.tileX = tileX;
this.tileY = tileY;
this.zoomLevel = zoomLevel;
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("[X:");
stringBuilder.append(this.tileX);
stringBuilder.append(", Y:");
stringBuilder.append(this.tileY);
stringBuilder.append(", Z:");
stringBuilder.append(this.zoomLevel);
stringBuilder.append("]");
return stringBuilder.toString();
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof Tile))
return false;
Tile o = (Tile) obj;
if (o.tileX == this.tileX && o.tileY == this.tileY
&& o.zoomLevel == this.zoomLevel)
return true;
return false;
}
private int mHash = 0;
@Override
public int hashCode() {
if (mHash == 0) {
int result = 7;
result = 31 * result + this.tileX;
result = 31 * result + this.tileY;
result = 31 * result + this.zoomLevel;
mHash = result;
}
return mHash;
}
}

View File

@ -0,0 +1,107 @@
/*
* Copyright 2013 Hannes Janetzek
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.oscim.layers.tile;
import com.badlogic.gdx.utils.Timer;
public abstract class TileLoader {
private final TileManager mTileManager;
private Timer mTimer;
public TileLoader(TileManager tileManager) {
if (mTimer == null)
mTimer = new Timer();
mTileManager = tileManager;
}
public abstract void cleanup();
protected abstract boolean executeJob(MapTile tile);
boolean isInterrupted;
void interrupt() {
isInterrupted = true;
// cancel loading
}
boolean mPausing;
public boolean isPausing() {
return mPausing;
}
public void pause() {
mPausing = true;
}
public void proceed() {
mPausing = false;
// FIXME
hasWork = false;
if (!mTileManager.jobQueue.isEmpty())
go();
}
public void awaitPausing() {
}
public void start() {
mPausing = false;
}
boolean hasWork;
public void go() {
if (hasWork)
return;
final TileLoader loader = this;
mTimer.scheduleTask(new Timer.Task() {
@Override
public void run() {
MapTile tile = mTileManager.jobQueue.poll();
if (tile == null)
return;
try {
tile.loader = loader;
executeJob(tile);
} catch (Exception e) {
e.printStackTrace();
return;
}
}
}, 0.01f);
hasWork = true;
}
public void jobCompleted(MapTile tile, boolean success) {
if (success) {
if (!isInterrupted) {
// pass tile to main thread
mTileManager.passTile(tile);
}
}
hasWork = false;
if (!mPausing && !mTileManager.jobQueue.isEmpty())
go();
}
}

View File

@ -0,0 +1,102 @@
/*
* Copyright 2013 Hannes Janetzek
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.oscim.layers.tile.bitmap;
import java.net.URL;
import org.oscim.backend.Log;
import org.oscim.backend.canvas.Bitmap;
import org.oscim.core.Tile;
import org.oscim.gdx.client.GwtBitmap;
import org.oscim.layers.tile.MapTile;
import org.oscim.layers.tile.TileLayer;
import org.oscim.layers.tile.TileLoader;
import org.oscim.layers.tile.TileManager;
import org.oscim.renderer.sublayers.BitmapLayer;
import org.oscim.renderer.sublayers.Layers;
import org.oscim.view.MapView;
import com.google.gwt.event.dom.client.ErrorEvent;
import com.google.gwt.event.dom.client.ErrorHandler;
import com.google.gwt.event.dom.client.LoadEvent;
import com.google.gwt.event.dom.client.LoadHandler;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.RootPanel;
public class BitmapTileLayer extends TileLayer<TileLoader> {
private static final int TIMEOUT_CONNECT = 5000;
private static final int TIMEOUT_READ = 10000;
final TileSource mTileSource;
public BitmapTileLayer(MapView mapView, TileSource tileSource) {
super(mapView, tileSource.getZoomLevelMax());
mTileSource = tileSource;
}
@Override
protected TileLoader createLoader(TileManager tm) {
return new TileLoader(tm) {
private void loadImage(final MapTile tile, final String url) {
final Image img = new Image(url);
RootPanel.get().add(img);
img.setVisible(false);
img.addLoadHandler(new LoadHandler() {
public void onLoad(LoadEvent event) {
Log.d("sup", "got image " + url);
Bitmap bitmap = new GwtBitmap(img);
tile.layers = new Layers();
BitmapLayer l = new BitmapLayer(false);
l.setBitmap(bitmap, Tile.SIZE, Tile.SIZE);
tile.layers.textureLayers = l;
tile.loader.jobCompleted(tile, true);
}
});
img.addErrorHandler(new ErrorHandler() {
@Override
public void onError(ErrorEvent event) {
tile.loader.jobCompleted(tile, false);
}
});
}
@Override
protected boolean executeJob(MapTile tile) {
URL url;
try {
url = mTileSource.getTileUrl(tile);
Log.d("sup", "load image " + url);
loadImage(tile, url.toString());
} catch (Exception e) {
e.printStackTrace();
return false;
}
return false;
}
@Override
public void cleanup() {
}
};
}
}

View File

@ -0,0 +1,622 @@
/*******************************************************************************
* Copyright 2011 See libgdx AUTHORS file.
* Copyright 2013 Hannes Janetzek
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package org.oscim.utils;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import org.oscim.backend.GL20;
import org.oscim.backend.GLAdapter;
public class Matrix4 {
private static GL20 GL = GLAdapter.get();
public static final int M00 = 0;// 0;
public static final int M01 = 4;// 1;
public static final int M02 = 8;// 2;
public static final int M03 = 12;// 3;
public static final int M10 = 1;// 4;
public static final int M11 = 5;// 5;
public static final int M12 = 9;// 6;
public static final int M13 = 13;// 7;
public static final int M20 = 2;// 8;
public static final int M21 = 6;// 9;
public static final int M22 = 10;// 10;
public static final int M23 = 14;// 11;
public static final int M30 = 3;// 12;
public static final int M31 = 7;// 13;
public static final int M32 = 11;// 14;
public static final int M33 = 15;// 15;
//private final static String TAG = Matrix4.class.getName();
private final FloatBuffer buffer = ByteBuffer.allocateDirect(16 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
private final static String INVALID_INPUT = "Bad Array!";
public final float tmp[] = new float[16];
public final float val[] = new float[16];
/** Sets the matrix to the given matrix as a float array. The float array must have at least 16 elements; the first 16 will be
* copied.
*
* @param values The matrix, in float form, that is to be copied. Remember that this matrix is in <a
* href="http://en.wikipedia.org/wiki/Row-major_order">column major</a> order.
* @return This matrix for the purpose of chaining methods together. */
public void set (float[] values) {
val[M00] = values[M00];
val[M10] = values[M10];
val[M20] = values[M20];
val[M30] = values[M30];
val[M01] = values[M01];
val[M11] = values[M11];
val[M21] = values[M21];
val[M31] = values[M31];
val[M02] = values[M02];
val[M12] = values[M12];
val[M22] = values[M22];
val[M32] = values[M32];
val[M03] = values[M03];
val[M13] = values[M13];
val[M23] = values[M23];
val[M33] = values[M33];
}
/**
* Get the Matrix as float array
*
* @param m float array to store Matrix
*/
public void get(float[] m) {
if (m == null || m.length != 16)
throw new IllegalArgumentException(INVALID_INPUT);
System.arraycopy(val, 0, m, 0, 16);
}
/**
* Copy values from mat
*
* @param mat Matrix to copy
*/
public void copy(Matrix4 m) {
if (m == null || m.val.length != 16)
throw new IllegalArgumentException(INVALID_INPUT);
System.arraycopy(m.val, 0, val, 0, 16);
//set(mat.val);
//copy(pointer, mat.pointer);
}
/**
* Project Vector with Matrix
*
* @param vec3 Vector to project
*/
public void prj(float[] vec3) {
if (vec3 == null || vec3.length < 3)
throw new IllegalArgumentException(INVALID_INPUT);
//prj(pointer, vec3);
matrix4_proj(val, vec3);
}
static void matrix4_proj (float[] mat, float[] vec) {
float inv_w = 1.0f / (vec[0] * mat[M30] + vec[1] * mat[M31] + vec[2] * mat[M32] + mat[M33]);
float x = (vec[0] * mat[M00] + vec[1] * mat[M01] + vec[2] * mat[M02] + mat[M03]) * inv_w;
float y = (vec[0] * mat[M10] + vec[1] * mat[M11] + vec[2] * mat[M12] + mat[M13]) * inv_w;
float z = (vec[0] * mat[M20] + vec[1] * mat[M21] + vec[2] * mat[M22] + mat[M23]) * inv_w;
vec[0] = x;
vec[1] = y;
vec[2] = z;
}
/**
* Multiply rhs onto Matrix.
*
* @param rhs right hand side
*/
public void multiplyRhs(Matrix4 rhs) {
//smulrhs(pointer, rhs.pointer);
matrix4_mul(val, rhs.val);
}
/**
* Use this matrix as rhs, multiply it on lhs and store result.
*
* @param lhs right hand side
*/
public void multiplyLhs(Matrix4 lhs) {
//smullhs(pointer, lhs.pointer);
System.arraycopy(lhs.val, 0, tmp, 0, 16);
matrix4_mul(tmp, val);
System.arraycopy(tmp, 0, val, 0, 16);
}
/**
* Multiply rhs onto lhs and store result in Matrix.
*
* This matrix MUST be different from lhs and rhs!
*
* As you know, when combining matrices for vector projection
* this has the same effect first as applying rhs then lhs.
*
* @param lhs left hand side
* @param rhs right hand side
*/
public void multiplyMM(Matrix4 lhs, Matrix4 rhs) {
//smul(pointer, lhs.pointer, rhs.pointer);
System.arraycopy(lhs.val, 0, tmp, 0, 16);
matrix4_mul(tmp, rhs.val);
System.arraycopy(tmp, 0, val, 0, 16);
}
/**
* Transpose mat and store result in Matrix
*
* @param mat to transpose
*/
public void transposeM(Matrix4 mat) {
//strans(pointer, mat.pointer);
val[M00] = mat.val[M00];
val[M01] = mat.val[M10];
val[M02] = mat.val[M20];
val[M03] = mat.val[M30];
val[M10] = mat.val[M01];
val[M11] = mat.val[M11];
val[M12] = mat.val[M21];
val[M13] = mat.val[M31];
val[M20] = mat.val[M02];
val[M21] = mat.val[M12];
val[M22] = mat.val[M22];
val[M23] = mat.val[M32];
val[M30] = mat.val[M03];
val[M31] = mat.val[M13];
val[M32] = mat.val[M23];
val[M33] = mat.val[M33];
}
/**
* Set rotation
*
* @param a angle in degree
* @param x around x-axis
* @param y around y-axis
* @param z around z-axis
*/
public void setRotation(float a, float x, float y, float z) {
//setRotation(pointer, a, x, y, z);
setRotateM(val, 0, a, x, y, z);
}
/**
* Set translation
*
* @param x along x-axis
* @param y along y-axis
* @param z along z-axis
*/
public void setTranslation(float x, float y, float z) {
//setTranslation(pointer, x, y, z);
setIdentity();
val[M03] = x;
val[M13] = y;
val[M23] = z;
}
/**
* Set scale factor
*
* @param x axis
* @param y axis
* @param z axis
*/
public void setScale(float x, float y, float z) {
//setScale(pointer, x, y, z);
setIdentity();
val[M00] = x;
val[M11] = y;
val[M22] = z;
}
/**
* Set translation and x,y scale
*
* @param tx translate x
* @param ty translate y
* @param scale factor x,y
*/
public void setTransScale(float tx, float ty, float scale) {
//setTransScale(pointer, tx, ty, scale);
setIdentity();
val[M03] = tx;
val[M13] = ty;
//val[M23] = z;
val[M00] = scale;
val[M11] = scale;
//val[M22] = scale;
}
/**
* Set Matrix with glUniformMatrix
*
* @param location GL location id
*/
public void setAsUniform(int location) {
buffer.clear();
buffer.put(val, 0, 16);
buffer.position(0);
GL = GLAdapter.get();
GL.glUniformMatrix4fv(location, 1, false, buffer);
//setAsUniform(pointer, location);
}
/**
* Set single value
*
* @param pos at position
* @param value value to set
*/
public void setValue(int pos, float value) {
//setValueAt(pointer, pos, value);
val[pos] = value;
}
/**
* add some offset (similar to glDepthOffset)
*
* @param delta offset
*/
public void addDepthOffset(int delta) {
//addDepthOffset(pointer, delta);
}
/**
* Set identity matrix
*/
public void setIdentity() {
//identity(pointer);
val[M00] = 1;
val[M01] = 0;
val[M02] = 0;
val[M03] = 0;
val[M10] = 0;
val[M11] = 1;
val[M12] = 0;
val[M13] = 0;
val[M20] = 0;
val[M21] = 0;
val[M22] = 1;
val[M23] = 0;
val[M30] = 0;
val[M31] = 0;
val[M32] = 0;
val[M33] = 1;
}
static void matrix4_mul (float[] mata, float[] matb) {
float tmp[] = new float[16];
tmp[M00] = mata[M00] * matb[M00] + mata[M01] * matb[M10] + mata[M02] * matb[M20] + mata[M03] * matb[M30];
tmp[M01] = mata[M00] * matb[M01] + mata[M01] * matb[M11] + mata[M02] * matb[M21] + mata[M03] * matb[M31];
tmp[M02] = mata[M00] * matb[M02] + mata[M01] * matb[M12] + mata[M02] * matb[M22] + mata[M03] * matb[M32];
tmp[M03] = mata[M00] * matb[M03] + mata[M01] * matb[M13] + mata[M02] * matb[M23] + mata[M03] * matb[M33];
tmp[M10] = mata[M10] * matb[M00] + mata[M11] * matb[M10] + mata[M12] * matb[M20] + mata[M13] * matb[M30];
tmp[M11] = mata[M10] * matb[M01] + mata[M11] * matb[M11] + mata[M12] * matb[M21] + mata[M13] * matb[M31];
tmp[M12] = mata[M10] * matb[M02] + mata[M11] * matb[M12] + mata[M12] * matb[M22] + mata[M13] * matb[M32];
tmp[M13] = mata[M10] * matb[M03] + mata[M11] * matb[M13] + mata[M12] * matb[M23] + mata[M13] * matb[M33];
tmp[M20] = mata[M20] * matb[M00] + mata[M21] * matb[M10] + mata[M22] * matb[M20] + mata[M23] * matb[M30];
tmp[M21] = mata[M20] * matb[M01] + mata[M21] * matb[M11] + mata[M22] * matb[M21] + mata[M23] * matb[M31];
tmp[M22] = mata[M20] * matb[M02] + mata[M21] * matb[M12] + mata[M22] * matb[M22] + mata[M23] * matb[M32];
tmp[M23] = mata[M20] * matb[M03] + mata[M21] * matb[M13] + mata[M22] * matb[M23] + mata[M23] * matb[M33];
tmp[M30] = mata[M30] * matb[M00] + mata[M31] * matb[M10] + mata[M32] * matb[M20] + mata[M33] * matb[M30];
tmp[M31] = mata[M30] * matb[M01] + mata[M31] * matb[M11] + mata[M32] * matb[M21] + mata[M33] * matb[M31];
tmp[M32] = mata[M30] * matb[M02] + mata[M31] * matb[M12] + mata[M32] * matb[M22] + mata[M33] * matb[M32];
tmp[M33] = mata[M30] * matb[M03] + mata[M31] * matb[M13] + mata[M32] * matb[M23] + mata[M33] * matb[M33];
System.arraycopy(tmp, 0, mata, 0, 16);
}
// @Override
// public void finalize() {
// if (pointer != 0)
// delete(pointer);
// }
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Define a projection matrix in terms of six clip planes
* @param m the float array that holds the perspective matrix
* @param offset the offset into float array m where the perspective
* matrix data is written
*/
public static void frustumM(float[] m, int offset,
float left, float right, float bottom, float top,
float near, float far) {
if (left == right) {
throw new IllegalArgumentException("left == right");
}
if (top == bottom) {
throw new IllegalArgumentException("top == bottom");
}
if (near == far) {
throw new IllegalArgumentException("near == far");
}
if (near <= 0.0f) {
throw new IllegalArgumentException("near <= 0.0f");
}
if (far <= 0.0f) {
throw new IllegalArgumentException("far <= 0.0f");
}
final float r_width = 1.0f / (right - left);
final float r_height = 1.0f / (top - bottom);
final float r_depth = 1.0f / (near - far);
final float x = 2.0f * (near * r_width);
final float y = 2.0f * (near * r_height);
final float A = (right + left) * r_width;
final float B = (top + bottom) * r_height;
final float C = (far + near) * r_depth;
final float D = 2.0f * (far * near * r_depth);
m[offset + 0] = x;
m[offset + 5] = y;
m[offset + 8] = A;
m[offset + 9] = B;
m[offset + 10] = C;
m[offset + 14] = D;
m[offset + 11] = -1.0f;
m[offset + 1] = 0.0f;
m[offset + 2] = 0.0f;
m[offset + 3] = 0.0f;
m[offset + 4] = 0.0f;
m[offset + 6] = 0.0f;
m[offset + 7] = 0.0f;
m[offset + 12] = 0.0f;
m[offset + 13] = 0.0f;
m[offset + 15] = 0.0f;
}
/**
* Inverts a 4 x 4 matrix.
*
* @param mInv the array that holds the output inverted matrix
* @param mInvOffset an offset into mInv where the inverted matrix is
* stored.
* @param m the input array
* @param mOffset an offset into m where the matrix is stored.
* @return true if the matrix could be inverted, false if it could not.
*/
public static boolean invertM(float[] mInv, int mInvOffset, float[] m,
int mOffset) {
// Invert a 4 x 4 matrix using Cramer's Rule
// transpose matrix
final float src0 = m[mOffset + 0];
final float src4 = m[mOffset + 1];
final float src8 = m[mOffset + 2];
final float src12 = m[mOffset + 3];
final float src1 = m[mOffset + 4];
final float src5 = m[mOffset + 5];
final float src9 = m[mOffset + 6];
final float src13 = m[mOffset + 7];
final float src2 = m[mOffset + 8];
final float src6 = m[mOffset + 9];
final float src10 = m[mOffset + 10];
final float src14 = m[mOffset + 11];
final float src3 = m[mOffset + 12];
final float src7 = m[mOffset + 13];
final float src11 = m[mOffset + 14];
final float src15 = m[mOffset + 15];
// calculate pairs for first 8 elements (cofactors)
final float atmp0 = src10 * src15;
final float atmp1 = src11 * src14;
final float atmp2 = src9 * src15;
final float atmp3 = src11 * src13;
final float atmp4 = src9 * src14;
final float atmp5 = src10 * src13;
final float atmp6 = src8 * src15;
final float atmp7 = src11 * src12;
final float atmp8 = src8 * src14;
final float atmp9 = src10 * src12;
final float atmp10 = src8 * src13;
final float atmp11 = src9 * src12;
// calculate first 8 elements (cofactors)
final float dst0 = (atmp0 * src5 + atmp3 * src6 + atmp4 * src7)
- (atmp1 * src5 + atmp2 * src6 + atmp5 * src7);
final float dst1 = (atmp1 * src4 + atmp6 * src6 + atmp9 * src7)
- (atmp0 * src4 + atmp7 * src6 + atmp8 * src7);
final float dst2 = (atmp2 * src4 + atmp7 * src5 + atmp10 * src7)
- (atmp3 * src4 + atmp6 * src5 + atmp11 * src7);
final float dst3 = (atmp5 * src4 + atmp8 * src5 + atmp11 * src6)
- (atmp4 * src4 + atmp9 * src5 + atmp10 * src6);
final float dst4 = (atmp1 * src1 + atmp2 * src2 + atmp5 * src3)
- (atmp0 * src1 + atmp3 * src2 + atmp4 * src3);
final float dst5 = (atmp0 * src0 + atmp7 * src2 + atmp8 * src3)
- (atmp1 * src0 + atmp6 * src2 + atmp9 * src3);
final float dst6 = (atmp3 * src0 + atmp6 * src1 + atmp11 * src3)
- (atmp2 * src0 + atmp7 * src1 + atmp10 * src3);
final float dst7 = (atmp4 * src0 + atmp9 * src1 + atmp10 * src2)
- (atmp5 * src0 + atmp8 * src1 + atmp11 * src2);
// calculate pairs for second 8 elements (cofactors)
final float btmp0 = src2 * src7;
final float btmp1 = src3 * src6;
final float btmp2 = src1 * src7;
final float btmp3 = src3 * src5;
final float btmp4 = src1 * src6;
final float btmp5 = src2 * src5;
final float btmp6 = src0 * src7;
final float btmp7 = src3 * src4;
final float btmp8 = src0 * src6;
final float btmp9 = src2 * src4;
final float btmp10 = src0 * src5;
final float btmp11 = src1 * src4;
// calculate second 8 elements (cofactors)
final float dst8 = (btmp0 * src13 + btmp3 * src14 + btmp4 * src15)
- (btmp1 * src13 + btmp2 * src14 + btmp5 * src15);
final float dst9 = (btmp1 * src12 + btmp6 * src14 + btmp9 * src15)
- (btmp0 * src12 + btmp7 * src14 + btmp8 * src15);
final float dst10 = (btmp2 * src12 + btmp7 * src13 + btmp10 * src15)
- (btmp3 * src12 + btmp6 * src13 + btmp11 * src15);
final float dst11 = (btmp5 * src12 + btmp8 * src13 + btmp11 * src14)
- (btmp4 * src12 + btmp9 * src13 + btmp10 * src14);
final float dst12 = (btmp2 * src10 + btmp5 * src11 + btmp1 * src9 )
- (btmp4 * src11 + btmp0 * src9 + btmp3 * src10);
final float dst13 = (btmp8 * src11 + btmp0 * src8 + btmp7 * src10)
- (btmp6 * src10 + btmp9 * src11 + btmp1 * src8 );
final float dst14 = (btmp6 * src9 + btmp11 * src11 + btmp3 * src8 )
- (btmp10 * src11 + btmp2 * src8 + btmp7 * src9 );
final float dst15 = (btmp10 * src10 + btmp4 * src8 + btmp9 * src9 )
- (btmp8 * src9 + btmp11 * src10 + btmp5 * src8 );
// calculate determinant
final float det =
src0 * dst0 + src1 * dst1 + src2 * dst2 + src3 * dst3;
if (det == 0.0f) {
return false;
}
// calculate matrix inverse
final float invdet = 1.0f / det;
mInv[ mInvOffset] = dst0 * invdet;
mInv[ 1 + mInvOffset] = dst1 * invdet;
mInv[ 2 + mInvOffset] = dst2 * invdet;
mInv[ 3 + mInvOffset] = dst3 * invdet;
mInv[ 4 + mInvOffset] = dst4 * invdet;
mInv[ 5 + mInvOffset] = dst5 * invdet;
mInv[ 6 + mInvOffset] = dst6 * invdet;
mInv[ 7 + mInvOffset] = dst7 * invdet;
mInv[ 8 + mInvOffset] = dst8 * invdet;
mInv[ 9 + mInvOffset] = dst9 * invdet;
mInv[10 + mInvOffset] = dst10 * invdet;
mInv[11 + mInvOffset] = dst11 * invdet;
mInv[12 + mInvOffset] = dst12 * invdet;
mInv[13 + mInvOffset] = dst13 * invdet;
mInv[14 + mInvOffset] = dst14 * invdet;
mInv[15 + mInvOffset] = dst15 * invdet;
return true;
}
void setRotateM(float[] rm, int rmOffset, float a, float x, float y, float z)
{
rm[rmOffset + 3] = 0;
rm[rmOffset + 7] = 0;
rm[rmOffset + 11] = 0;
rm[rmOffset + 12] = 0;
rm[rmOffset + 13] = 0;
rm[rmOffset + 14] = 0;
rm[rmOffset + 15] = 1;
a *= (float) (Math.PI / 180.0f);
float s = (float) Math.sin(a);
float c = (float) Math.cos(a);
if (1.0f == x && 0.0f == y && 0.0f == z)
{
rm[rmOffset + 5] = c;
rm[rmOffset + 10] = c;
rm[rmOffset + 6] = s;
rm[rmOffset + 9] = -s;
rm[rmOffset + 1] = 0;
rm[rmOffset + 2] = 0;
rm[rmOffset + 4] = 0;
rm[rmOffset + 8] = 0;
rm[rmOffset + 0] = 1;
}
else if (0.0f == x && 1.0f == y && 0.0f == z)
{
rm[rmOffset + 0] = c;
rm[rmOffset + 10] = c;
rm[rmOffset + 8] = s;
rm[rmOffset + 2] = -s;
rm[rmOffset + 1] = 0;
rm[rmOffset + 4] = 0;
rm[rmOffset + 6] = 0;
rm[rmOffset + 9] = 0;
rm[rmOffset + 5] = 1;
}
else if (0.0f == x && 0.0f == y && 1.0f == z)
{
rm[rmOffset + 0] = c;
rm[rmOffset + 5] = c;
rm[rmOffset + 1] = s;
rm[rmOffset + 4] = -s;
rm[rmOffset + 2] = 0;
rm[rmOffset + 6] = 0;
rm[rmOffset + 8] = 0;
rm[rmOffset + 9] = 0;
rm[rmOffset + 10] = 1;
}
else
{
float len = (float) Math.sqrt(x * x + y * y + z * z);
if (1.0f != len)
{
float recipLen = 1.0f / len;
x *= recipLen;
y *= recipLen;
z *= recipLen;
}
float nc = 1.0f - c;
float xy = x * y;
float yz = y * z;
float zx = z * x;
float xs = x * s;
float ys = y * s;
float zs = z * s;
rm[rmOffset + 0] = x * x * nc + c;
rm[rmOffset + 4] = xy * nc - zs;
rm[rmOffset + 8] = zx * nc + ys;
rm[rmOffset + 1] = xy * nc + zs;
rm[rmOffset + 5] = y * y * nc + c;
rm[rmOffset + 9] = yz * nc - xs;
rm[rmOffset + 2] = zx * nc - ys;
rm[rmOffset + 6] = yz * nc + xs;
rm[rmOffset + 10] = z * z * nc + c;
}
}
}