diff --git a/.gitignore b/.gitignore
index 8baaf9fc42..65ed2bc629 100644
--- a/.gitignore
+++ b/.gitignore
@@ -146,4 +146,116 @@
/sdk/nbi/stub/ext/components/products/jdk/build/
/sdk/nbi/stub/ext/components/products/jdk/dist/
/sdk/jme3-dark-laf/nbproject/private/
+
jme3-lwjgl3/build/
+
+### Intellij ###
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff:
+.idea/workspace.xml
+.idea/tasks.xml
+.idea/dictionaries
+.idea/vcs.xml
+.idea/jsLibraryMappings.xml
+
+# Sensitive or high-churn files:
+.idea/dataSources.ids
+.idea/dataSources.xml
+.idea/dataSources.local.xml
+.idea/sqlDataSources.xml
+.idea/dynamic.xml
+.idea/uiDesigner.xml
+
+# Gradle:
+.idea/gradle.xml
+.idea/libraries
+
+# Mongo Explorer plugin:
+.idea/mongoSettings.xml
+
+## File-based project format:
+*.iws
+
+## Plugin-specific files:
+
+# IntelliJ
+/out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+
+### Eclipse ###
+
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.settings/
+.loadpath
+.recommenders
+
+# Eclipse Core
+.project
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# PyDev specific (Python IDE for Eclipse)
+*.pydevproject
+
+# CDT-specific (C/C++ Development Tooling)
+.cproject
+
+# JDT-specific (Eclipse Java Development Tools)
+.classpath
+
+# Java annotation processor (APT)
+.factorypath
+
+# PDT-specific (PHP Development Tools)
+.buildpath
+
+# sbteclipse plugin
+.target
+
+# Tern plugin
+.tern-project
+
+# TeXlipse plugin
+.texlipse
+
+# STS (Spring Tool Suite)
+.springBeans
+
+# Code Recommenders
+.recommenders/
+
+
+### Sonar ###
+#Sonar generated dir
+*.sonar/
+
+*.jdproj
+
+sonar-project.properties
+
+*.properties
diff --git a/common.gradle b/common.gradle
old mode 100644
new mode 100755
index 2cad48bf22..57b2293cdb
--- a/common.gradle
+++ b/common.gradle
@@ -25,8 +25,9 @@ configurations {
dependencies {
// Adding dependencies here will add the dependencies to each subproject.
testCompile group: 'junit', name: 'junit', version: '4.12'
- testCompile group: 'org.mockito', name: 'mockito-core', version: '2.0.28-beta'
testCompile group: 'org.easytesting', name: 'fest-assert-core', version: '2.0M10'
+ testCompile group: 'org.mockito', name: 'mockito-core', version: '2.0.28-beta'
+ compile 'org.apache.commons:commons-lang3:3.0'
deployerJars "org.apache.maven.wagon:wagon-ssh:2.9"
}
diff --git a/jme3-android-examples/src/main/gen/com/jme3/android/BuildConfig.java b/jme3-android-examples/src/main/gen/com/jme3/android/BuildConfig.java
new file mode 100644
index 0000000000..b3c5e7a8c5
--- /dev/null
+++ b/jme3-android-examples/src/main/gen/com/jme3/android/BuildConfig.java
@@ -0,0 +1,8 @@
+/*___Generated_by_IDEA___*/
+
+package com.jme3.android;
+
+/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
+public final class BuildConfig {
+ public final static boolean DEBUG = Boolean.parseBoolean(null);
+}
\ No newline at end of file
diff --git a/jme3-android-examples/src/main/gen/com/jme3/android/Manifest.java b/jme3-android-examples/src/main/gen/com/jme3/android/Manifest.java
new file mode 100644
index 0000000000..c6b0496951
--- /dev/null
+++ b/jme3-android-examples/src/main/gen/com/jme3/android/Manifest.java
@@ -0,0 +1,7 @@
+/*___Generated_by_IDEA___*/
+
+package com.jme3.android;
+
+/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
+public final class Manifest {
+}
\ No newline at end of file
diff --git a/jme3-android-examples/src/main/gen/com/jme3/android/R.java b/jme3-android-examples/src/main/gen/com/jme3/android/R.java
new file mode 100644
index 0000000000..5e250b921e
--- /dev/null
+++ b/jme3-android-examples/src/main/gen/com/jme3/android/R.java
@@ -0,0 +1,7 @@
+/*___Generated_by_IDEA___*/
+
+package com.jme3.android;
+
+/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
+public final class R {
+}
\ No newline at end of file
diff --git a/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java b/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java
old mode 100644
new mode 100755
index 991ad25c0a..28122b9ca4
--- a/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java
+++ b/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java
@@ -57,6 +57,10 @@
import com.jme3.renderer.opengl.GLFbo;
import com.jme3.renderer.opengl.GLRenderer;
import com.jme3.system.*;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -278,6 +282,20 @@ public TouchInput getTouchInput() {
return androidInput.getTouchInput();
}
+ @Override
+ public java.util.List getInput() {
+ List inputs = new ArrayList<>();
+
+ inputs.add(getKeyInput());
+ inputs.add(getMouseInput());
+ if(!settings.getBoolean("DisableJoysticks")) {
+ inputs.add(getJoyInput());
+ }
+ inputs.add(getTouchInput());
+ inputs.removeAll(Collections.singleton(null));
+
+ return inputs;
+ }
@Override
public Timer getTimer() {
return timer;
diff --git a/jme3-android/src/main/java/jme3test/android/gen/com/jme3/androiddemo/BuildConfig.java b/jme3-android/src/main/java/jme3test/android/gen/com/jme3/androiddemo/BuildConfig.java
new file mode 100644
index 0000000000..4ec9fe873d
--- /dev/null
+++ b/jme3-android/src/main/java/jme3test/android/gen/com/jme3/androiddemo/BuildConfig.java
@@ -0,0 +1,8 @@
+/*___Generated_by_IDEA___*/
+
+package com.jme3.androiddemo;
+
+/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */
+public final class BuildConfig {
+ public final static boolean DEBUG = Boolean.parseBoolean(null);
+}
\ No newline at end of file
diff --git a/jme3-android/src/main/java/jme3test/android/gen/com/jme3/androiddemo/Manifest.java b/jme3-android/src/main/java/jme3test/android/gen/com/jme3/androiddemo/Manifest.java
new file mode 100644
index 0000000000..8f5cc81439
--- /dev/null
+++ b/jme3-android/src/main/java/jme3test/android/gen/com/jme3/androiddemo/Manifest.java
@@ -0,0 +1,7 @@
+/*___Generated_by_IDEA___*/
+
+package com.jme3.androiddemo;
+
+/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
+public final class Manifest {
+}
\ No newline at end of file
diff --git a/jme3-android/src/main/java/jme3test/android/gen/com/jme3/androiddemo/R.java b/jme3-android/src/main/java/jme3test/android/gen/com/jme3/androiddemo/R.java
new file mode 100644
index 0000000000..b5a0338c32
--- /dev/null
+++ b/jme3-android/src/main/java/jme3test/android/gen/com/jme3/androiddemo/R.java
@@ -0,0 +1,7 @@
+/*___Generated_by_IDEA___*/
+
+package com.jme3.androiddemo;
+
+/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
+public final class R {
+}
\ No newline at end of file
diff --git a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/textures/CombinedTexture.java b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/textures/CombinedTexture.java
old mode 100644
new mode 100755
index e406447eb4..e4bdcbe4c1
--- a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/textures/CombinedTexture.java
+++ b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/textures/CombinedTexture.java
@@ -10,6 +10,7 @@
import java.util.logging.Level;
import java.util.logging.Logger;
+import com.jme3.texture.TextureDefault2D;
import jme3tools.converters.ImageToAwt;
import com.jme3.math.ColorRGBA;
@@ -33,7 +34,6 @@
import com.jme3.texture.Texture.MagFilter;
import com.jme3.texture.Texture.MinFilter;
import com.jme3.texture.Texture.WrapMode;
-import com.jme3.texture.Texture2D;
import com.jme3.texture.TextureCubeMap;
import com.jme3.texture.image.ColorSpace;
import com.jme3.util.BufferUtils;
@@ -96,7 +96,7 @@ public CombinedTexture(int mappingType, boolean discardCoveredTextures) {
* the blender context
*/
public void add(Texture texture, TextureBlender textureBlender, int uvCoordinatesType, int projectionType, Structure textureStructure, String uvCoordinatesName, BlenderContext blenderContext) {
- if (!(texture instanceof GeneratedTexture) && !(texture instanceof Texture2D)) {
+ if (!(texture instanceof GeneratedTexture) && !(texture instanceof TextureDefault2D)) {
throw new IllegalArgumentException("Unsupported texture type: " + (texture == null ? "null" : texture.getClass()));
}
if (!(texture instanceof GeneratedTexture) || blenderContext.getBlenderKey().isLoadGeneratedTextures()) {
@@ -120,7 +120,7 @@ public void add(Texture texture, TextureBlender textureBlender, int uvCoordinate
}
/**
- * This method flattens the texture and creates a single result of Texture2D
+ * This method flattens the texture and creates a single result of TextureDefault2D
* type.
*
* @param geometry
@@ -149,7 +149,7 @@ public void flatten(Geometry geometry, Long geometriesOMA, Map 0) {
@@ -174,7 +174,7 @@ public void flatten(Geometry geometry, Long geometriesOMA, Map resultUVS;
@@ -62,12 +62,12 @@
* This method triangulates the given flat texture. The given texture is not
* changed.
*
- * @param texture2d
+ * @param textureDefault2D
* the texture to be triangulated
* @param uvs
* the UV coordinates for each face
*/
- public TriangulatedTexture(Texture2D texture2d, List uvs, BlenderContext blenderContext) {
+ public TriangulatedTexture(TextureDefault2D textureDefault2D, List uvs, BlenderContext blenderContext) {
maxTextureSize = blenderContext.getBlenderKey().getMaxTextureSize();
faceTextures = new TreeSet(new Comparator() {
public int compare(TriangleTextureElement o1, TriangleTextureElement o2) {
@@ -76,9 +76,9 @@ public int compare(TriangleTextureElement o1, TriangleTextureElement o2) {
});
int facesCount = uvs.size() / 3;
for (int i = 0; i < facesCount; ++i) {
- faceTextures.add(new TriangleTextureElement(i, texture2d.getImage(), uvs, true, blenderContext));
+ faceTextures.add(new TriangleTextureElement(i, textureDefault2D.getImage(), uvs, true, blenderContext));
}
- format = texture2d.getImage().getFormat();
+ format = textureDefault2D.getImage().getFormat();
}
/**
@@ -179,7 +179,7 @@ public void castToUVS(TriangulatedTexture targetTexture, BlenderContext blenderC
* computed vefore)
* @return flat result texture (all images merged into one)
*/
- public Texture2D getResultTexture(boolean rebuild) {
+ public TextureDefault2D getResultTexture(boolean rebuild) {
if (resultTexture == null || rebuild) {
// sorting the parts by their height (from highest to the lowest)
List list = new ArrayList(faceTextures);
@@ -244,7 +244,7 @@ public int compare(TriangleTextureElement o1, TriangleTextureElement o2) {
}
Image resultImage = new Image(format, resultImageWidth, resultImageHeight, BufferUtils.createByteBuffer(resultImageWidth * resultImageHeight * (format.getBitsPerPixel() >> 3)), ColorSpace.Linear);
- resultTexture = new Texture2D(resultImage);
+ resultTexture = new TextureDefault2D(resultImage);
for (Entry entry : imageLayoutData.entrySet()) {
if (!duplicatedFaceIndexes.contains(entry.getKey().faceIndex)) {
this.draw(resultImage, entry.getKey().image, entry.getValue()[0], entry.getValue()[1]);
@@ -263,7 +263,7 @@ public int compare(TriangleTextureElement o1, TriangleTextureElement o2) {
/**
* @return the result flat texture
*/
- public Texture2D getResultTexture() {
+ public TextureDefault2D getResultTexture() {
return this.getResultTexture(false);
}
diff --git a/jme3-core/src/main/java/com/jme3/app/Application.java b/jme3-core/src/main/java/com/jme3/app/Application.java
old mode 100644
new mode 100755
index 9688a5d1ed..b0802bd87a
--- a/jme3-core/src/main/java/com/jme3/app/Application.java
+++ b/jme3-core/src/main/java/com/jme3/app/Application.java
@@ -48,6 +48,7 @@
import com.jme3.system.JmeContext.Type;
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Future;
@@ -86,10 +87,8 @@ public class Application implements SystemListener {
protected LostFocusBehavior lostFocusBehavior = LostFocusBehavior.ThrottleOnLostFocus;
protected float speed = 1f;
protected boolean paused = false;
- protected MouseInput mouseInput;
- protected KeyInput keyInput;
- protected JoyInput joyInput;
- protected TouchInput touchInput;
+
+ protected List inputs;
protected InputManager inputManager;
protected AppStateManager stateManager;
@@ -173,6 +172,10 @@ public void setAssetManager(AssetManager assetManager){
this.assetManager = assetManager;
}
+ public void setInputManager(InputManager inputManager) {
+ this.inputManager = inputManager;
+ }
+
private void initAssetManager(){
URL assetCfgUrl = null;
@@ -305,26 +308,9 @@ private void initCamera(){
* initializes joystick input if joysticks are enabled in the
* AppSettings.
*/
- private void initInput(){
- mouseInput = context.getMouseInput();
- if (mouseInput != null)
- mouseInput.initialize();
-
- keyInput = context.getKeyInput();
- if (keyInput != null)
- keyInput.initialize();
-
- touchInput = context.getTouchInput();
- if (touchInput != null)
- touchInput.initialize();
-
- if (!settings.getBoolean("DisableJoysticks")){
- joyInput = context.getJoyInput();
- if (joyInput != null)
- joyInput.initialize();
- }
-
- inputManager = new InputManager(mouseInput, keyInput, joyInput, touchInput);
+ protected void initInput(){
+ inputs = context.getInput();
+ inputManager = new InputManager(inputs);
}
private void initStateManager(){
@@ -715,18 +701,7 @@ public void update(){
}
protected void destroyInput(){
- if (mouseInput != null)
- mouseInput.destroy();
-
- if (keyInput != null)
- keyInput.destroy();
-
- if (joyInput != null)
- joyInput.destroy();
-
- if (touchInput != null)
- touchInput.destroy();
-
+ inputManager.destroyInput();
inputManager = null;
}
diff --git a/jme3-core/src/main/java/com/jme3/font/BitmapTextPage.java b/jme3-core/src/main/java/com/jme3/font/BitmapTextPage.java
old mode 100644
new mode 100755
index 58dc875504..88745df39a
--- a/jme3-core/src/main/java/com/jme3/font/BitmapTextPage.java
+++ b/jme3-core/src/main/java/com/jme3/font/BitmapTextPage.java
@@ -36,7 +36,7 @@
import com.jme3.scene.Mesh;
import com.jme3.scene.VertexBuffer;
import com.jme3.scene.VertexBuffer.Type;
-import com.jme3.texture.Texture2D;
+import com.jme3.texture.TextureDefault2D;
import com.jme3.util.BufferUtils;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
@@ -54,7 +54,7 @@ class BitmapTextPage extends Geometry {
private final short[] idx;
private final byte[] color;
private final int page;
- private final Texture2D texture;
+ private final TextureDefault2D texture;
private final LinkedList pageQuads = new LinkedList();
BitmapTextPage(BitmapFont font, boolean arrayBased, int page) {
@@ -73,7 +73,7 @@ class BitmapTextPage extends Geometry {
}
setMaterial(mat);
- this.texture = (Texture2D) mat.getTextureParam("ColorMap").getTextureValue();
+ this.texture = (TextureDefault2D) mat.getTextureParam("ColorMap").getTextureValue();
// initialize buffers
Mesh m = getMesh();
@@ -112,7 +112,7 @@ class BitmapTextPage extends Geometry {
this(font, false, 0);
}
- Texture2D getTexture() {
+ TextureDefault2D getTexture() {
return texture;
}
diff --git a/jme3-core/src/main/java/com/jme3/input/InputManager.java b/jme3-core/src/main/java/com/jme3/input/InputManager.java
old mode 100644
new mode 100755
index b21d225bbc..302a8821c1
--- a/jme3-core/src/main/java/com/jme3/input/InputManager.java
+++ b/jme3-core/src/main/java/com/jme3/input/InputManager.java
@@ -42,6 +42,7 @@
import com.jme3.util.SafeArrayList;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -89,6 +90,7 @@ public class InputManager implements RawInputListener {
private final MouseInput mouse;
private final JoyInput joystick;
private final TouchInput touch;
+ private final List inputs;
private float frameTPF;
private long lastLastUpdateTime = 0;
private long lastUpdateTime = 0;
@@ -123,32 +125,40 @@ public Mapping(String name) {
*
*
This should only be called internally in {@link Application}.
*
- * @param mouse
- * @param keys
- * @param joystick
- * @param touch
+ * @param inputs
* @throws IllegalArgumentException If either mouseInput or keyInput are null.
*/
- public InputManager(MouseInput mouse, KeyInput keys, JoyInput joystick, TouchInput touch) {
+ public InputManager(List inputs) {
+ KeyInput keys = null;
+ MouseInput mouse = null;
+ JoyInput joystick = null;
+ TouchInput touch = null;
+
+ for (Input input : inputs) {
+ input.initialize();
+ input.setInputListener(this);
+ if(input instanceof MouseInput) {
+ mouse = (MouseInput) input;
+ } else if (input instanceof KeyInput) {
+ keys = (KeyInput) input;
+ } else if (input instanceof JoyInput) {
+ joystick = (JoyInput) input;
+ joysticks = joystick.loadJoysticks(this);
+ } else if (input instanceof TouchInput) {
+ touch = (TouchInput) input;
+ }
+ }
+
if (keys == null || mouse == null) {
throw new IllegalArgumentException("Mouse or keyboard cannot be null");
}
+ this.inputs = inputs;
this.keys = keys;
this.mouse = mouse;
this.joystick = joystick;
this.touch = touch;
- keys.setInputListener(this);
- mouse.setInputListener(this);
- if (joystick != null) {
- joystick.setInputListener(this);
- joysticks = joystick.loadJoysticks(this);
- }
- if (touch != null) {
- touch.setInputListener(this);
- }
-
firstTime = keys.getInputTimeNanos();
}
@@ -893,13 +903,8 @@ public void update(float tpf) {
eventsPermitted = true;
- keys.update();
- mouse.update();
- if (joystick != null) {
- joystick.update();
- }
- if (touch != null) {
- touch.update();
+ for(Input input : inputs){
+ input.update();
}
eventsPermitted = false;
@@ -946,4 +951,30 @@ public void onTouchEvent(TouchEvent evt) {
cursorPos.set(evt.getX(), evt.getY());
inputQueue.add(evt);
}
+
+ public void destroyInput() {
+ for(Input input : inputs){
+ input.destroy();
+ }
+ }
+
+ public List getInputs() {
+ return inputs;
+ }
+
+ public TouchInput getTouch() {
+ return touch;
+ }
+
+ public JoyInput getJoystick() {
+ return joystick;
+ }
+
+ public MouseInput getMouse() {
+ return mouse;
+ }
+
+ public KeyInput getKeys() {
+ return keys;
+ }
}
diff --git a/jme3-core/src/main/java/com/jme3/input/JoyInput.java b/jme3-core/src/main/java/com/jme3/input/JoyInput.java
old mode 100644
new mode 100755
diff --git a/jme3-core/src/main/java/com/jme3/input/TouchInput.java b/jme3-core/src/main/java/com/jme3/input/TouchInput.java
old mode 100644
new mode 100755
diff --git a/jme3-core/src/main/java/com/jme3/post/Filter.java b/jme3-core/src/main/java/com/jme3/post/Filter.java
old mode 100644
new mode 100755
index feaacbe5d9..939b8d0fe1
--- a/jme3-core/src/main/java/com/jme3/post/Filter.java
+++ b/jme3-core/src/main/java/com/jme3/post/Filter.java
@@ -42,7 +42,8 @@
import com.jme3.texture.FrameBuffer;
import com.jme3.texture.Image.Format;
import com.jme3.texture.Texture;
-import com.jme3.texture.Texture2D;
+import com.jme3.texture.TextureDefault2D;
+
import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
@@ -82,8 +83,8 @@ public Filter(String name) {
public class Pass {
protected FrameBuffer renderFrameBuffer;
- protected Texture2D renderedTexture;
- protected Texture2D depthTexture;
+ protected TextureDefault2D renderedTexture;
+ protected TextureDefault2D depthTexture;
protected Material passMaterial;
/**
@@ -99,18 +100,18 @@ public void init(Renderer renderer, int width, int height, Format textureFormat,
Collection caps = renderer.getCaps();
if (numSamples > 1 && caps.contains(Caps.FrameBufferMultisample) && caps.contains(Caps.OpenGL31)) {
renderFrameBuffer = new FrameBuffer(width, height, numSamples);
- renderedTexture = new Texture2D(width, height, numSamples, textureFormat);
+ renderedTexture = new TextureDefault2D(width, height, numSamples, textureFormat);
renderFrameBuffer.setDepthBuffer(depthBufferFormat);
if (renderDepth) {
- depthTexture = new Texture2D(width, height, numSamples, depthBufferFormat);
+ depthTexture = new TextureDefault2D(width, height, numSamples, depthBufferFormat);
renderFrameBuffer.setDepthTexture(depthTexture);
}
} else {
renderFrameBuffer = new FrameBuffer(width, height, 1);
- renderedTexture = new Texture2D(width, height, textureFormat);
+ renderedTexture = new TextureDefault2D(width, height, textureFormat);
renderFrameBuffer.setDepthBuffer(depthBufferFormat);
if (renderDepth) {
- depthTexture = new Texture2D(width, height, depthBufferFormat);
+ depthTexture = new TextureDefault2D(width, height, depthBufferFormat);
renderFrameBuffer.setDepthTexture(depthTexture);
}
}
@@ -170,15 +171,15 @@ public void setRenderFrameBuffer(FrameBuffer renderFrameBuffer) {
this.renderFrameBuffer = renderFrameBuffer;
}
- public Texture2D getDepthTexture() {
+ public TextureDefault2D getDepthTexture() {
return depthTexture;
}
- public Texture2D getRenderedTexture() {
+ public TextureDefault2D getRenderedTexture() {
return renderedTexture;
}
- public void setRenderedTexture(Texture2D renderedTexture) {
+ public void setRenderedTexture(TextureDefault2D renderedTexture) {
this.renderedTexture = renderedTexture;
}
@@ -379,7 +380,7 @@ protected void setRenderFrameBuffer(FrameBuffer renderFrameBuffer) {
* returns the rendered texture of this filter
* @return
*/
- protected Texture2D getRenderedTexture() {
+ protected TextureDefault2D getRenderedTexture() {
return defaultPass.renderedTexture;
}
@@ -387,7 +388,7 @@ protected Texture2D getRenderedTexture() {
* sets the rendered texture of this filter
* @param renderedTexture
*/
- protected void setRenderedTexture(Texture2D renderedTexture) {
+ protected void setRenderedTexture(TextureDefault2D renderedTexture) {
this.defaultPass.renderedTexture = renderedTexture;
}
diff --git a/jme3-core/src/main/java/com/jme3/post/FilterPostProcessor.java b/jme3-core/src/main/java/com/jme3/post/FilterPostProcessor.java
old mode 100644
new mode 100755
index cf51ad0c9e..82c16d65ac
--- a/jme3-core/src/main/java/com/jme3/post/FilterPostProcessor.java
+++ b/jme3-core/src/main/java/com/jme3/post/FilterPostProcessor.java
@@ -39,7 +39,7 @@
import com.jme3.texture.FrameBuffer;
import com.jme3.texture.Image.Format;
import com.jme3.texture.Texture;
-import com.jme3.texture.Texture2D;
+import com.jme3.texture.TextureDefault2D;
import com.jme3.ui.Picture;
import com.jme3.util.SafeArrayList;
import java.io.IOException;
@@ -62,8 +62,8 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
private FrameBuffer renderFrameBufferMS;
private int numSamples = 1;
private FrameBuffer renderFrameBuffer;
- private Texture2D filterTexture;
- private Texture2D depthTexture;
+ private TextureDefault2D filterTexture;
+ private TextureDefault2D depthTexture;
private SafeArrayList filters = new SafeArrayList(Filter.class);
private AssetManager assetManager;
private Picture fsQuad;
@@ -167,7 +167,7 @@ private void initFilter(Filter filter, ViewPort vp) {
filter.setProcessor(this);
if (filter.isRequiresDepthTexture()) {
if (!computeDepth && renderFrameBuffer != null) {
- depthTexture = new Texture2D(width, height, Format.Depth24);
+ depthTexture = new TextureDefault2D(width, height, Format.Depth24);
renderFrameBuffer.setDepthTexture(depthTexture);
}
computeDepth = true;
@@ -239,7 +239,7 @@ public void postQueue(RenderQueue rq) {
* @param sceneFb
*/
private void renderFilterChain(Renderer r, FrameBuffer sceneFb) {
- Texture2D tex = filterTexture;
+ TextureDefault2D tex = filterTexture;
FrameBuffer buff = sceneFb;
boolean msDepth = depthTexture != null && depthTexture.getImage().getMultiSamples() > 1;
for (int i = 0; i < filters.size(); i++) {
@@ -458,8 +458,8 @@ public void reshape(ViewPort vp, int w, int h) {
if (numSamples > 1 && caps.contains(Caps.FrameBufferMultisample)) {
renderFrameBufferMS = new FrameBuffer(width, height, numSamples);
if (caps.contains(Caps.OpenGL32)) {
- Texture2D msColor = new Texture2D(width, height, numSamples, fbFormat);
- Texture2D msDepth = new Texture2D(width, height, numSamples, Format.Depth);
+ TextureDefault2D msColor = new TextureDefault2D(width, height, numSamples, fbFormat);
+ TextureDefault2D msDepth = new TextureDefault2D(width, height, numSamples, Format.Depth);
renderFrameBufferMS.setDepthTexture(msDepth);
renderFrameBufferMS.setColorTexture(msColor);
filterTexture = msColor;
@@ -473,7 +473,7 @@ public void reshape(ViewPort vp, int w, int h) {
if (numSamples <= 1 || !caps.contains(Caps.OpenGL32)) {
renderFrameBuffer = new FrameBuffer(width, height, 1);
renderFrameBuffer.setDepthBuffer(Format.Depth);
- filterTexture = new Texture2D(width, height, fbFormat);
+ filterTexture = new TextureDefault2D(width, height, fbFormat);
renderFrameBuffer.setColorTexture(filterTexture);
}
@@ -542,7 +542,7 @@ public void read(JmeImporter im) throws IOException {
* returns the depth texture of the scene
* @return the depth texture
*/
- public Texture2D getDepthTexture() {
+ public TextureDefault2D getDepthTexture() {
return depthTexture;
}
@@ -551,7 +551,7 @@ public Texture2D getDepthTexture() {
* returns the rendered texture of the scene
* @return the filter texture
*/
- public Texture2D getFilterTexture() {
+ public TextureDefault2D getFilterTexture() {
return filterTexture;
}
diff --git a/jme3-core/src/main/java/com/jme3/post/HDRRenderer.java b/jme3-core/src/main/java/com/jme3/post/HDRRenderer.java
old mode 100644
new mode 100755
index 2c071ae03d..22fa83c3ea
--- a/jme3-core/src/main/java/com/jme3/post/HDRRenderer.java
+++ b/jme3-core/src/main/java/com/jme3/post/HDRRenderer.java
@@ -42,7 +42,7 @@
import com.jme3.texture.Texture;
import com.jme3.texture.Texture.MagFilter;
import com.jme3.texture.Texture.MinFilter;
-import com.jme3.texture.Texture2D;
+import com.jme3.texture.TextureDefault2D;
import com.jme3.ui.Picture;
import java.util.Collection;
import java.util.logging.Logger;
@@ -63,13 +63,13 @@ public class HDRRenderer implements SceneProcessor {
private FrameBuffer msFB;
private FrameBuffer mainSceneFB;
- private Texture2D mainScene;
+ private TextureDefault2D mainScene;
private FrameBuffer scene64FB;
- private Texture2D scene64;
+ private TextureDefault2D scene64;
private FrameBuffer scene8FB;
- private Texture2D scene8;
+ private TextureDefault2D scene8;
private FrameBuffer scene1FB[] = new FrameBuffer[2];
- private Texture2D scene1[] = new Texture2D[2];
+ private TextureDefault2D scene1[] = new TextureDefault2D[2];
private Material hdr64;
private Material hdr8;
@@ -256,7 +256,7 @@ public void reshape(ViewPort vp, int w, int h){
}
mainSceneFB = new FrameBuffer(w, h, 1);
- mainScene = new Texture2D(w, h, bufFormat);
+ mainScene = new TextureDefault2D(w, h, bufFormat);
mainSceneFB.setDepthBuffer(Format.Depth);
mainSceneFB.setColorTexture(mainScene);
mainScene.setMagFilter(fbMagFilter);
@@ -297,23 +297,23 @@ public void initialize(RenderManager rm, ViewPort vp){
Format lumFmt = Format.RGB8;
scene64FB = new FrameBuffer(64, 64, 1);
- scene64 = new Texture2D(64, 64, lumFmt);
+ scene64 = new TextureDefault2D(64, 64, lumFmt);
scene64FB.setColorTexture(scene64);
scene64.setMagFilter(fbMagFilter);
scene64.setMinFilter(fbMinFilter);
scene8FB = new FrameBuffer(8, 8, 1);
- scene8 = new Texture2D(8, 8, lumFmt);
+ scene8 = new TextureDefault2D(8, 8, lumFmt);
scene8FB.setColorTexture(scene8);
scene8.setMagFilter(fbMagFilter);
scene8.setMinFilter(fbMinFilter);
scene1FB[0] = new FrameBuffer(1, 1, 1);
- scene1[0] = new Texture2D(1, 1, lumFmt);
+ scene1[0] = new TextureDefault2D(1, 1, lumFmt);
scene1FB[0].setColorTexture(scene1[0]);
scene1FB[1] = new FrameBuffer(1, 1, 1);
- scene1[1] = new Texture2D(1, 1, lumFmt);
+ scene1[1] = new TextureDefault2D(1, 1, lumFmt);
scene1FB[1].setColorTexture(scene1[1]);
// prepare tonemap shader
diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLCapabilities.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLCapabilities.java
new file mode 100755
index 0000000000..4213089f66
--- /dev/null
+++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLCapabilities.java
@@ -0,0 +1,415 @@
+package com.jme3.renderer.opengl;
+
+import com.jme3.renderer.Caps;
+import com.jme3.renderer.Limits;
+import com.jme3.renderer.RenderContext;
+import com.jme3.util.BufferUtils;
+
+import java.nio.IntBuffer;
+import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static java.util.Arrays.asList;
+
+public class GLCapabilities {
+
+ private static final Logger logger = Logger.getLogger(GLCapabilities.class.getName());
+ protected final EnumSet caps = EnumSet.noneOf(Caps.class);
+ private static final Pattern GLVERSION_PATTERN = Pattern.compile(".*?(\\d+)\\.(\\d+).*");
+ protected final EnumMap limits = new EnumMap<>(Limits.class);
+
+ private final IntBuffer intBuf16 = BufferUtils.createIntBuffer(16);
+ private GL gl;
+ private GL2 gl2;
+ private GL3 gl3;
+ private HashSet extensions;
+
+ public void loadCapabilities(GL gl, GL2 gl2, GL3 gl3, RenderContext context) {
+ this.gl = gl;
+ this.gl2 = gl2;
+ this.gl3 = gl3;
+ if (gl2 != null) {
+ loadCapabilitiesGL2(gl.glGetString(GL.GL_VERSION), context);
+ loadCapabilitiesGLSL(gl.glGetString(GL.GL_SHADING_LANGUAGE_VERSION));
+ loadCapabilitiesGLSL1Support();
+ } else {
+ loadCapabilitiesES();
+ }
+ loadCapabilitiesCommon();
+ }
+
+ /**
+ * Load Embedded System Capabilities.
+ * Important: Do not add OpenGL20 - that's the desktop capability!
+ */
+ protected void loadCapabilitiesES() {
+ caps.add(Caps.GLSL100);
+ caps.add(Caps.OpenGLES20);
+ }
+
+ protected void loadCapabilitiesGL2(String glVersion, RenderContext context) {
+ int oglVer = extractVersion(glVersion);
+ Map> versionCapMap = getGLVersionCapabilityMapping();
+ addCapabilitiesBasedOnVersion(versionCapMap, oglVer);
+
+
+ // Fix issue in TestRenderToMemory when GL.GL_FRONT is the main
+ // buffer being used.
+ context.initialDrawBuf = getInteger(GL2.GL_DRAW_BUFFER);
+ context.initialReadBuf = getInteger(GL2.GL_READ_BUFFER);
+ }
+
+ /**
+ * Load GL Shading Language capabilities
+ */
+ protected void loadCapabilitiesGLSL(String glslVersion) {
+ int glslVer = extractVersion(glslVersion);
+ Map> versionCapMap = getGSLVersionCapabilityMapping();
+ addCapabilitiesBasedOnVersion(versionCapMap, glslVer);
+ }
+
+ /**
+ * Workaround, always assume we support GLSL100 & GLSL110
+ * Supporting OpenGL 2.0 means supporting GLSL 1.10.
+ */
+ protected void loadCapabilitiesGLSL1Support() {
+ caps.add(Caps.GLSL110);
+ caps.add(Caps.GLSL100);
+ }
+
+ protected void loadCapabilitiesCommon() {
+ extensions = loadExtensions();
+
+ limits.put(Limits.VertexTextureUnits, getInteger(GL.GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS));
+ if (limits.get(Limits.VertexTextureUnits) > 0) {
+ caps.add(Caps.VertexTextureFetch);
+ }
+
+ limits.put(Limits.FragmentTextureUnits, getInteger(GL.GL_MAX_TEXTURE_IMAGE_UNITS));
+
+ if (caps.contains(Caps.OpenGLES20)) {
+ limits.put(Limits.VertexUniformVectors, getInteger(GL.GL_MAX_VERTEX_UNIFORM_VECTORS));
+ } else {
+ limits.put(Limits.VertexUniformVectors, getInteger(GL.GL_MAX_VERTEX_UNIFORM_COMPONENTS) / 4);
+ }
+ limits.put(Limits.VertexAttributes, getInteger(GL.GL_MAX_VERTEX_ATTRIBS));
+ limits.put(Limits.TextureSize, getInteger(GL.GL_MAX_TEXTURE_SIZE));
+ limits.put(Limits.CubemapSize, getInteger(GL.GL_MAX_CUBE_MAP_TEXTURE_SIZE));
+
+ if (hasExtension("GL_ARB_draw_instanced") &&
+ hasExtension("GL_ARB_instanced_arrays")) {
+ caps.add(Caps.MeshInstancing);
+ }
+
+ if (hasExtension("GL_OES_element_index_uint") || gl2 != null) {
+ caps.add(Caps.IntegerIndexBuffer);
+ }
+
+ if (hasExtension("GL_ARB_texture_buffer_object")) {
+ caps.add(Caps.TextureBuffer);
+ }
+
+ loadTextureFormatExtensions();
+
+ if (hasExtension("GL_ARB_vertex_array_object") || caps.contains(Caps.OpenGL30)) {
+ caps.add(Caps.VertexBufferArray);
+ }
+
+ if (hasExtension("GL_ARB_texture_non_power_of_two") ||
+ hasExtension("GL_OES_texture_npot") ||
+ caps.contains(Caps.OpenGL30)) {
+ caps.add(Caps.NonPowerOfTwoTextures);
+ } else {
+ logger.log(Level.WARNING, "Your graphics card does not "
+ + "support non-power-of-2 textures. "
+ + "Some features might not work.");
+ }
+
+ if (caps.contains(Caps.OpenGLES20)) {
+ // OpenGL ES 2 has some limited support for NPOT textures
+ caps.add(Caps.PartialNonPowerOfTwoTextures);
+ }
+
+ if (hasExtension("GL_EXT_texture_array") || caps.contains(Caps.OpenGL30)) {
+ caps.add(Caps.TextureArray);
+ }
+
+ if (hasExtension("GL_EXT_texture_filter_anisotropic")) {
+ caps.add(Caps.TextureFilterAnisotropic);
+ limits.put(Limits.TextureAnisotropy, getInteger(GLExt.GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT));
+ }
+
+ if (hasExtension("GL_EXT_framebuffer_object")
+ || caps.contains(Caps.OpenGL30)
+ || caps.contains(Caps.OpenGLES20)) {
+ loadGLExtFrameBufferObjectCapabilities();
+ }
+
+ if (hasExtension("GL_ARB_multisample")) {
+ boolean available = getInteger(GLExt.GL_SAMPLE_BUFFERS_ARB) != 0;
+ int samples = getInteger(GLExt.GL_SAMPLES_ARB);
+ logger.log(Level.FINER, "Samples: {0}", samples);
+ boolean enabled = gl.glIsEnabled(GLExt.GL_MULTISAMPLE_ARB);
+ if (samples > 0 && available && !enabled) {
+ // Doesn't seem to be neccessary .. OGL spec says its always
+ // set by default?
+ gl.glEnable(GLExt.GL_MULTISAMPLE_ARB);
+ }
+ caps.add(Caps.Multisample);
+ }
+
+ // Supports sRGB pipeline.
+ if ( (hasExtension("GL_ARB_framebuffer_sRGB") && hasExtension("GL_EXT_texture_sRGB"))
+ || caps.contains(Caps.OpenGL30) ) {
+ caps.add(Caps.Srgb);
+ }
+
+ // Supports seamless cubemap
+ if (hasExtension("GL_ARB_seamless_cube_map") || caps.contains(Caps.OpenGL32)) {
+ caps.add(Caps.SeamlessCubemap);
+ }
+
+ if (caps.contains(Caps.OpenGL32) && !hasExtension("GL_ARB_compatibility")) {
+ caps.add(Caps.CoreProfile);
+ }
+
+ if (hasExtension("GL_ARB_get_program_binary")) {
+ int binaryFormats = getInteger(GLExt.GL_NUM_PROGRAM_BINARY_FORMATS);
+ if (binaryFormats > 0) {
+ caps.add(Caps.BinaryShader);
+ }
+ }
+
+ // Print context information
+ logger.log(Level.INFO, "OpenGL Renderer Information\n" +
+ " * Vendor: {0}\n" +
+ " * Renderer: {1}\n" +
+ " * OpenGL Version: {2}\n" +
+ " * GLSL Version: {3}\n" +
+ " * Profile: {4}",
+ new Object[]{
+ gl.glGetString(GL.GL_VENDOR),
+ gl.glGetString(GL.GL_RENDERER),
+ gl.glGetString(GL.GL_VERSION),
+ gl.glGetString(GL.GL_SHADING_LANGUAGE_VERSION),
+ caps.contains(Caps.CoreProfile) ? "Core" : "Compatibility"
+ });
+
+ // Print capabilities (if fine logging is enabled)
+ if (logger.isLoggable(Level.FINE)) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("Supported capabilities: \n");
+ for (Caps cap : caps)
+ {
+ sb.append("\t").append(cap.toString()).append("\n");
+ }
+ logger.log(Level.FINE, sb.toString());
+ }
+ }
+
+ private void loadGLExtFrameBufferObjectCapabilities() {
+ caps.add(Caps.FrameBuffer);
+
+ limits.put(Limits.RenderBufferSize, getInteger(GLFbo.GL_MAX_RENDERBUFFER_SIZE_EXT));
+ limits.put(Limits.FrameBufferAttachments, getInteger(GLFbo.GL_MAX_COLOR_ATTACHMENTS_EXT));
+
+ if (hasExtension("GL_EXT_framebuffer_blit") || caps.contains(Caps.OpenGL30)) {
+ caps.add(Caps.FrameBufferBlit);
+ }
+
+ if (hasExtension("GL_EXT_framebuffer_multisample")) {
+ caps.add(Caps.FrameBufferMultisample);
+ limits.put(Limits.FrameBufferSamples, getInteger(GLExt.GL_MAX_SAMPLES_EXT));
+ }
+
+ if (hasExtension("GL_ARB_texture_multisample")) {
+ caps.add(Caps.TextureMultisample);
+ limits.put(Limits.ColorTextureSamples, getInteger(GLExt.GL_MAX_COLOR_TEXTURE_SAMPLES));
+ limits.put(Limits.DepthTextureSamples, getInteger(GLExt.GL_MAX_DEPTH_TEXTURE_SAMPLES));
+ if (!limits.containsKey(Limits.FrameBufferSamples)) {
+ // In case they want to query samples on main FB ...
+ limits.put(Limits.FrameBufferSamples, limits.get(Limits.ColorTextureSamples));
+ }
+ }
+
+ if (hasExtension("GL_ARB_draw_buffers") || caps.contains(Caps.OpenGL30)) {
+ limits.put(Limits.FrameBufferMrtAttachments, getInteger(GLExt.GL_MAX_DRAW_BUFFERS_ARB));
+ if (limits.get(Limits.FrameBufferMrtAttachments) > 1) {
+ caps.add(Caps.FrameBufferMRT);
+ }
+ } else {
+ limits.put(Limits.FrameBufferMrtAttachments, 1);
+ }
+ }
+
+ private void loadTextureFormatExtensions() {
+ boolean hasFloatTexture;
+
+ hasFloatTexture = hasExtension("GL_OES_texture_half_float") &&
+ hasExtension("GL_OES_texture_float");
+
+ if (!hasFloatTexture) {
+ hasFloatTexture = hasExtension("GL_ARB_texture_float") &&
+ hasExtension("GL_ARB_half_float_pixel");
+
+ if (!hasFloatTexture) {
+ hasFloatTexture = caps.contains(Caps.OpenGL30);
+ }
+ }
+
+ if (hasFloatTexture) {
+ caps.add(Caps.FloatTexture);
+ }
+
+ if (hasExtension("GL_OES_depth_texture") || gl2 != null) {
+ caps.add(Caps.DepthTexture);
+
+ // TODO: GL_OES_depth24
+ }
+
+ if (hasExtension("GL_OES_rgb8_rgba8") ||
+ hasExtension("GL_ARM_rgba8") ||
+ hasExtension("GL_EXT_texture_format_BGRA8888")) {
+ caps.add(Caps.Rgba8);
+ }
+
+ if (caps.contains(Caps.OpenGL30) || hasExtension("GL_OES_packed_depth_stencil")) {
+ caps.add(Caps.PackedDepthStencilBuffer);
+ }
+
+ if (hasExtension("GL_ARB_color_buffer_float") &&
+ hasExtension("GL_ARB_half_float_pixel")) {
+ // XXX: Require both 16 and 32 bit float support for FloatColorBuffer.
+ caps.add(Caps.FloatColorBuffer);
+ }
+
+ if (hasExtension("GL_ARB_depth_buffer_float")) {
+ caps.add(Caps.FloatDepthBuffer);
+ }
+
+ if ((hasExtension("GL_EXT_packed_float") && hasFloatTexture) ||
+ caps.contains(Caps.OpenGL30)) {
+ // Either OpenGL3 is available or both packed_float & half_float_pixel.
+ caps.add(Caps.PackedFloatColorBuffer);
+ caps.add(Caps.PackedFloatTexture);
+ }
+
+ if (hasExtension("GL_EXT_texture_shared_exponent") || caps.contains(Caps.OpenGL30)) {
+ caps.add(Caps.SharedExponentTexture);
+ }
+
+ if (hasExtension("GL_EXT_texture_compression_s3tc")) {
+ caps.add(Caps.TextureCompressionS3TC);
+ }
+
+ if (hasExtension("GL_ARB_ES3_compatibility")) {
+ caps.add(Caps.TextureCompressionETC2);
+ caps.add(Caps.TextureCompressionETC1);
+ } else if (hasExtension("GL_OES_compressed_ETC1_RGB8_texture")) {
+ caps.add(Caps.TextureCompressionETC1);
+ }
+ }
+
+ public int extractVersion(String version) {
+ Matcher m = GLVERSION_PATTERN.matcher(version);
+ if (m.matches()) {
+ int major = Integer.parseInt(m.group(1));
+ int minor = Integer.parseInt(m.group(2));
+ if (minor >= 10 && minor % 10 == 0) {
+ // some versions can look like "1.30" instead of "1.3".
+ // make sure to correct for this
+ minor /= 10;
+ }
+ return major * 100 + minor * 10;
+ } else {
+ return -1;
+ }
+ }
+
+ protected HashSet loadExtensions() {
+ HashSet extensionSet = new HashSet(64);
+ if (getCaps().contains(Caps.OpenGL30)) {
+ // If OpenGL3+ is available, use the non-deprecated way
+ // of getting supported extensions.
+ gl3.glGetInteger(GL3.GL_NUM_EXTENSIONS, intBuf16);
+ int extensionCount = intBuf16.get(0);
+ for (int i = 0; i < extensionCount; i++) {
+ String extension = gl3.glGetString(GL.GL_EXTENSIONS, i);
+ extensionSet.add(extension);
+ }
+ } else {
+ extensionSet.addAll(asList(gl.glGetString(GL.GL_EXTENSIONS).split(" ")));
+ }
+ return extensionSet;
+ }
+
+ public Map> getGLVersionCapabilityMapping() {
+
+ Map> map = new TreeMap<>();
+
+ map.put(200, Collections.singletonList(Caps.OpenGL20));
+ map.put(210, Collections.singletonList(Caps.OpenGL21));
+ map.put(300, Collections.singletonList(Caps.OpenGL30));
+ map.put(310, Collections.singletonList(Caps.OpenGL31));
+ map.put(320, Collections.singletonList(Caps.OpenGL32));
+ map.put(330, asList(Caps.OpenGL33, Caps.GeometryShader));
+ map.put(400, asList(Caps.OpenGL40, Caps.TesselationShader));
+
+ return map;
+ }
+
+ public Map> getGSLVersionCapabilityMapping() {
+ Map> map = new TreeMap<>();
+
+ map.put(100, Collections.singletonList(Caps.GLSL100));
+ map.put(110, Collections.singletonList(Caps.GLSL110));
+ map.put(120, Collections.singletonList(Caps.GLSL120));
+ map.put(130, Collections.singletonList(Caps.GLSL130));
+ map.put(140, Collections.singletonList(Caps.GLSL140));
+ map.put(150, Collections.singletonList(Caps.GLSL150));
+ map.put(330, Collections.singletonList(Caps.GLSL330));
+ map.put(400, Collections.singletonList(Caps.GLSL400));
+
+ return map;
+ }
+
+ /**
+ * Add capabilities for all versions below the given version.
+ * @param versionCapMap mapping of existing versions and there capabilities
+ * @param version version to add capabilities for
+ */
+ private void addCapabilitiesBasedOnVersion(Map> versionCapMap, int version) {
+ for (Map.Entry> entry : versionCapMap.entrySet()) {
+ if (version >= entry.getKey()) {
+ for (Caps cap : entry.getValue()) {
+ caps.add(cap);
+ }
+ }
+ }
+ }
+
+ protected boolean has(Caps cap) {
+ return caps.contains(cap);
+ }
+
+ private boolean hasExtension(String extensionName) {
+ return extensions.contains(extensionName);
+ }
+
+ protected int getInteger(int en) {
+ intBuf16.clear();
+ gl.glGetInteger(en, intBuf16);
+ return intBuf16.get(0);
+ }
+
+ public EnumSet getCaps() {
+ return caps;
+ }
+
+ public EnumMap getLimits() {
+ return limits;
+ }
+}
diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java
old mode 100644
new mode 100755
index 50e603d2f1..1bde05d188
--- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java
+++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java
@@ -59,39 +59,30 @@
import com.jme3.util.MipMapGenerator;
import com.jme3.util.NativeObjectManager;
import java.nio.*;
-import java.util.Arrays;
-import java.util.EnumMap;
-import java.util.EnumSet;
-import java.util.HashSet;
-import java.util.List;
+import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+
import jme3tools.shader.ShaderDebug;
-public final class GLRenderer implements Renderer {
+public class GLRenderer implements Renderer {
private static final Logger logger = Logger.getLogger(GLRenderer.class.getName());
private static final boolean VALIDATE_SHADER = false;
- private static final Pattern GLVERSION_PATTERN = Pattern.compile(".*?(\\d+)\\.(\\d+).*");
private final ByteBuffer nameBuf = BufferUtils.createByteBuffer(250);
private final StringBuilder stringBuf = new StringBuilder(250);
private final IntBuffer intBuf1 = BufferUtils.createIntBuffer(1);
private final IntBuffer intBuf16 = BufferUtils.createIntBuffer(16);
- private final FloatBuffer floatBuf16 = BufferUtils.createFloatBuffer(16);
- private final RenderContext context = new RenderContext();
+ protected final RenderContext context = new RenderContext();
private final NativeObjectManager objManager = new NativeObjectManager();
- private final EnumSet caps = EnumSet.noneOf(Caps.class);
- private final EnumMap limits = new EnumMap(Limits.class);
+ protected final GLCapabilities glCaps = new GLCapabilities();
private FrameBuffer mainFbOverride = null;
private final Statistics statistics = new Statistics();
private int vpX, vpY, vpW, vpH;
private int clipX, clipY, clipW, clipH;
private boolean linearizeSrgbImages;
- private HashSet extensions;
private final GL gl;
private final GL2 gl2;
@@ -118,381 +109,12 @@ public Statistics getStatistics() {
@Override
public EnumSet getCaps() {
- return caps;
+ return glCaps.getCaps();
}
// Not making public yet ...
public EnumMap getLimits() {
- return limits;
- }
-
- private HashSet loadExtensions() {
- HashSet extensionSet = new HashSet(64);
- if (caps.contains(Caps.OpenGL30)) {
- // If OpenGL3+ is available, use the non-deprecated way
- // of getting supported extensions.
- gl3.glGetInteger(GL3.GL_NUM_EXTENSIONS, intBuf16);
- int extensionCount = intBuf16.get(0);
- for (int i = 0; i < extensionCount; i++) {
- String extension = gl3.glGetString(GL.GL_EXTENSIONS, i);
- extensionSet.add(extension);
- }
- } else {
- extensionSet.addAll(Arrays.asList(gl.glGetString(GL.GL_EXTENSIONS).split(" ")));
- }
- return extensionSet;
- }
-
- public static int extractVersion(String version) {
- Matcher m = GLVERSION_PATTERN.matcher(version);
- if (m.matches()) {
- int major = Integer.parseInt(m.group(1));
- int minor = Integer.parseInt(m.group(2));
- if (minor >= 10 && minor % 10 == 0) {
- // some versions can look like "1.30" instead of "1.3".
- // make sure to correct for this
- minor /= 10;
- }
- return major * 100 + minor * 10;
- } else {
- return -1;
- }
- }
-
- private boolean hasExtension(String extensionName) {
- return extensions.contains(extensionName);
- }
-
- private void loadCapabilitiesES() {
- caps.add(Caps.GLSL100);
- caps.add(Caps.OpenGLES20);
-
- // Important: Do not add OpenGL20 - that's the desktop capability!
- }
-
- private void loadCapabilitiesGL2() {
- int oglVer = extractVersion(gl.glGetString(GL.GL_VERSION));
-
- if (oglVer >= 200) {
- caps.add(Caps.OpenGL20);
- if (oglVer >= 210) {
- caps.add(Caps.OpenGL21);
- if (oglVer >= 300) {
- caps.add(Caps.OpenGL30);
- if (oglVer >= 310) {
- caps.add(Caps.OpenGL31);
- if (oglVer >= 320) {
- caps.add(Caps.OpenGL32);
- }
- if (oglVer >= 330) {
- caps.add(Caps.OpenGL33);
- caps.add(Caps.GeometryShader);
- }
- if (oglVer >= 400) {
- caps.add(Caps.OpenGL40);
- caps.add(Caps.TesselationShader);
- }
- }
- }
- }
- }
-
- int glslVer = extractVersion(gl.glGetString(GL.GL_SHADING_LANGUAGE_VERSION));
-
- switch (glslVer) {
- default:
- if (glslVer < 400) {
- break;
- }
- // so that future OpenGL revisions wont break jme3
- // fall through intentional
- case 400:
- caps.add(Caps.GLSL400);
- case 330:
- caps.add(Caps.GLSL330);
- case 150:
- caps.add(Caps.GLSL150);
- case 140:
- caps.add(Caps.GLSL140);
- case 130:
- caps.add(Caps.GLSL130);
- case 120:
- caps.add(Caps.GLSL120);
- case 110:
- caps.add(Caps.GLSL110);
- case 100:
- caps.add(Caps.GLSL100);
- break;
- }
-
- // Workaround, always assume we support GLSL100 & GLSL110
- // Supporting OpenGL 2.0 means supporting GLSL 1.10.
- caps.add(Caps.GLSL110);
- caps.add(Caps.GLSL100);
-
- // Fix issue in TestRenderToMemory when GL.GL_FRONT is the main
- // buffer being used.
- context.initialDrawBuf = getInteger(GL2.GL_DRAW_BUFFER);
- context.initialReadBuf = getInteger(GL2.GL_READ_BUFFER);
-
- // XXX: This has to be GL.GL_BACK for canvas on Mac
- // Since initialDrawBuf is GL.GL_FRONT for pbuffer, gotta
- // change this value later on ...
-// initialDrawBuf = GL.GL_BACK;
-// initialReadBuf = GL.GL_BACK;
- }
-
- private void loadCapabilitiesCommon() {
- extensions = loadExtensions();
-
- limits.put(Limits.VertexTextureUnits, getInteger(GL.GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS));
- if (limits.get(Limits.VertexTextureUnits) > 0) {
- caps.add(Caps.VertexTextureFetch);
- }
-
- limits.put(Limits.FragmentTextureUnits, getInteger(GL.GL_MAX_TEXTURE_IMAGE_UNITS));
-
-// gl.glGetInteger(GL.GL_MAX_VERTEX_UNIFORM_COMPONENTS, intBuf16);
-// vertexUniforms = intBuf16.get(0);
-// logger.log(Level.FINER, "Vertex Uniforms: {0}", vertexUniforms);
-//
-// gl.glGetInteger(GL.GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, intBuf16);
-// fragUniforms = intBuf16.get(0);
-// logger.log(Level.FINER, "Fragment Uniforms: {0}", fragUniforms);
- if (caps.contains(Caps.OpenGLES20)) {
- limits.put(Limits.VertexUniformVectors, getInteger(GL.GL_MAX_VERTEX_UNIFORM_VECTORS));
- } else {
- limits.put(Limits.VertexUniformVectors, getInteger(GL.GL_MAX_VERTEX_UNIFORM_COMPONENTS) / 4);
- }
- limits.put(Limits.VertexAttributes, getInteger(GL.GL_MAX_VERTEX_ATTRIBS));
- limits.put(Limits.TextureSize, getInteger(GL.GL_MAX_TEXTURE_SIZE));
- limits.put(Limits.CubemapSize, getInteger(GL.GL_MAX_CUBE_MAP_TEXTURE_SIZE));
-
- if (hasExtension("GL_ARB_draw_instanced") &&
- hasExtension("GL_ARB_instanced_arrays")) {
- caps.add(Caps.MeshInstancing);
- }
-
- if (hasExtension("GL_OES_element_index_uint") || gl2 != null) {
- caps.add(Caps.IntegerIndexBuffer);
- }
-
- if (hasExtension("GL_ARB_texture_buffer_object")) {
- caps.add(Caps.TextureBuffer);
- }
-
- // == texture format extensions ==
-
- boolean hasFloatTexture;
-
- hasFloatTexture = hasExtension("GL_OES_texture_half_float") &&
- hasExtension("GL_OES_texture_float");
-
- if (!hasFloatTexture) {
- hasFloatTexture = hasExtension("GL_ARB_texture_float") &&
- hasExtension("GL_ARB_half_float_pixel");
-
- if (!hasFloatTexture) {
- hasFloatTexture = caps.contains(Caps.OpenGL30);
- }
- }
-
- if (hasFloatTexture) {
- caps.add(Caps.FloatTexture);
- }
-
- if (hasExtension("GL_OES_depth_texture") || gl2 != null) {
- caps.add(Caps.DepthTexture);
-
- // TODO: GL_OES_depth24
- }
-
- if (hasExtension("GL_OES_rgb8_rgba8") ||
- hasExtension("GL_ARM_rgba8") ||
- hasExtension("GL_EXT_texture_format_BGRA8888")) {
- caps.add(Caps.Rgba8);
- }
-
- if (caps.contains(Caps.OpenGL30) || hasExtension("GL_OES_packed_depth_stencil")) {
- caps.add(Caps.PackedDepthStencilBuffer);
- }
-
- if (hasExtension("GL_ARB_color_buffer_float") &&
- hasExtension("GL_ARB_half_float_pixel")) {
- // XXX: Require both 16 and 32 bit float support for FloatColorBuffer.
- caps.add(Caps.FloatColorBuffer);
- }
-
- if (hasExtension("GL_ARB_depth_buffer_float")) {
- caps.add(Caps.FloatDepthBuffer);
- }
-
- if ((hasExtension("GL_EXT_packed_float") && hasFloatTexture) ||
- caps.contains(Caps.OpenGL30)) {
- // Either OpenGL3 is available or both packed_float & half_float_pixel.
- caps.add(Caps.PackedFloatColorBuffer);
- caps.add(Caps.PackedFloatTexture);
- }
-
- if (hasExtension("GL_EXT_texture_shared_exponent") || caps.contains(Caps.OpenGL30)) {
- caps.add(Caps.SharedExponentTexture);
- }
-
- if (hasExtension("GL_EXT_texture_compression_s3tc")) {
- caps.add(Caps.TextureCompressionS3TC);
- }
-
- if (hasExtension("GL_ARB_ES3_compatibility")) {
- caps.add(Caps.TextureCompressionETC2);
- caps.add(Caps.TextureCompressionETC1);
- } else if (hasExtension("GL_OES_compressed_ETC1_RGB8_texture")) {
- caps.add(Caps.TextureCompressionETC1);
- }
-
- // == end texture format extensions ==
-
- if (hasExtension("GL_ARB_vertex_array_object") || caps.contains(Caps.OpenGL30)) {
- caps.add(Caps.VertexBufferArray);
- }
-
- if (hasExtension("GL_ARB_texture_non_power_of_two") ||
- hasExtension("GL_OES_texture_npot") ||
- caps.contains(Caps.OpenGL30)) {
- caps.add(Caps.NonPowerOfTwoTextures);
- } else {
- logger.log(Level.WARNING, "Your graphics card does not "
- + "support non-power-of-2 textures. "
- + "Some features might not work.");
- }
-
- if (caps.contains(Caps.OpenGLES20)) {
- // OpenGL ES 2 has some limited support for NPOT textures
- caps.add(Caps.PartialNonPowerOfTwoTextures);
- }
-
- if (hasExtension("GL_EXT_texture_array") || caps.contains(Caps.OpenGL30)) {
- caps.add(Caps.TextureArray);
- }
-
- if (hasExtension("GL_EXT_texture_filter_anisotropic")) {
- caps.add(Caps.TextureFilterAnisotropic);
- limits.put(Limits.TextureAnisotropy, getInteger(GLExt.GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT));
- }
-
- if (hasExtension("GL_EXT_framebuffer_object")
- || caps.contains(Caps.OpenGL30)
- || caps.contains(Caps.OpenGLES20)) {
- caps.add(Caps.FrameBuffer);
-
- limits.put(Limits.RenderBufferSize, getInteger(GLFbo.GL_MAX_RENDERBUFFER_SIZE_EXT));
- limits.put(Limits.FrameBufferAttachments, getInteger(GLFbo.GL_MAX_COLOR_ATTACHMENTS_EXT));
-
- if (hasExtension("GL_EXT_framebuffer_blit") || caps.contains(Caps.OpenGL30)) {
- caps.add(Caps.FrameBufferBlit);
- }
-
- if (hasExtension("GL_EXT_framebuffer_multisample")) {
- caps.add(Caps.FrameBufferMultisample);
- limits.put(Limits.FrameBufferSamples, getInteger(GLExt.GL_MAX_SAMPLES_EXT));
- }
-
- if (hasExtension("GL_ARB_texture_multisample")) {
- caps.add(Caps.TextureMultisample);
- limits.put(Limits.ColorTextureSamples, getInteger(GLExt.GL_MAX_COLOR_TEXTURE_SAMPLES));
- limits.put(Limits.DepthTextureSamples, getInteger(GLExt.GL_MAX_DEPTH_TEXTURE_SAMPLES));
- if (!limits.containsKey(Limits.FrameBufferSamples)) {
- // In case they want to query samples on main FB ...
- limits.put(Limits.FrameBufferSamples, limits.get(Limits.ColorTextureSamples));
- }
- }
-
- if (hasExtension("GL_ARB_draw_buffers") || caps.contains(Caps.OpenGL30)) {
- limits.put(Limits.FrameBufferMrtAttachments, getInteger(GLExt.GL_MAX_DRAW_BUFFERS_ARB));
- if (limits.get(Limits.FrameBufferMrtAttachments) > 1) {
- caps.add(Caps.FrameBufferMRT);
- }
- } else {
- limits.put(Limits.FrameBufferMrtAttachments, 1);
- }
- }
-
- if (hasExtension("GL_ARB_multisample")) {
- boolean available = getInteger(GLExt.GL_SAMPLE_BUFFERS_ARB) != 0;
- int samples = getInteger(GLExt.GL_SAMPLES_ARB);
- logger.log(Level.FINER, "Samples: {0}", samples);
- boolean enabled = gl.glIsEnabled(GLExt.GL_MULTISAMPLE_ARB);
- if (samples > 0 && available && !enabled) {
- // Doesn't seem to be neccessary .. OGL spec says its always
- // set by default?
- gl.glEnable(GLExt.GL_MULTISAMPLE_ARB);
- }
- caps.add(Caps.Multisample);
- }
-
- // Supports sRGB pipeline.
- if ( (hasExtension("GL_ARB_framebuffer_sRGB") && hasExtension("GL_EXT_texture_sRGB"))
- || caps.contains(Caps.OpenGL30) ) {
- caps.add(Caps.Srgb);
- }
-
- // Supports seamless cubemap
- if (hasExtension("GL_ARB_seamless_cube_map") || caps.contains(Caps.OpenGL32)) {
- caps.add(Caps.SeamlessCubemap);
- }
-
- if (caps.contains(Caps.OpenGL32) && !hasExtension("GL_ARB_compatibility")) {
- caps.add(Caps.CoreProfile);
- }
-
- if (hasExtension("GL_ARB_get_program_binary")) {
- int binaryFormats = getInteger(GLExt.GL_NUM_PROGRAM_BINARY_FORMATS);
- if (binaryFormats > 0) {
- caps.add(Caps.BinaryShader);
- }
- }
-
- // Print context information
- logger.log(Level.INFO, "OpenGL Renderer Information\n" +
- " * Vendor: {0}\n" +
- " * Renderer: {1}\n" +
- " * OpenGL Version: {2}\n" +
- " * GLSL Version: {3}\n" +
- " * Profile: {4}",
- new Object[]{
- gl.glGetString(GL.GL_VENDOR),
- gl.glGetString(GL.GL_RENDERER),
- gl.glGetString(GL.GL_VERSION),
- gl.glGetString(GL.GL_SHADING_LANGUAGE_VERSION),
- caps.contains(Caps.CoreProfile) ? "Core" : "Compatibility"
- });
-
- // Print capabilities (if fine logging is enabled)
- if (logger.isLoggable(Level.FINE)) {
- StringBuilder sb = new StringBuilder();
- sb.append("Supported capabilities: \n");
- for (Caps cap : caps)
- {
- sb.append("\t").append(cap.toString()).append("\n");
- }
- logger.log(Level.FINE, sb.toString());
- }
-
- texUtil.initialize(caps);
- }
-
- private void loadCapabilities() {
- if (gl2 != null) {
- loadCapabilitiesGL2();
- } else {
- loadCapabilitiesES();
- }
- loadCapabilitiesCommon();
- }
-
- private int getInteger(int en) {
- intBuf16.clear();
- gl.glGetInteger(en, intBuf16);
- return intBuf16.get(0);
+ return glCaps.getLimits();
}
private boolean getBoolean(int en) {
@@ -504,15 +126,17 @@ private boolean getBoolean(int en) {
public void initialize() {
loadCapabilities();
+ texUtil.initialize(glCaps.getCaps());
+
// Initialize default state..
gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);
- if (caps.contains(Caps.SeamlessCubemap)) {
+ if (glCaps.has(Caps.SeamlessCubemap)) {
// Enable this globally. Should be OK.
gl.glEnable(GLExt.GL_TEXTURE_CUBE_MAP_SEAMLESS);
}
- if (caps.contains(Caps.CoreProfile)) {
+ if (glCaps.has(Caps.CoreProfile)) {
// Core Profile requires VAO to be bound.
gl3.glGenVertexArrays(intBuf16);
int vaoId = intBuf16.get(0);
@@ -520,13 +144,17 @@ public void initialize() {
}
if (gl2 != null) {
gl2.glEnable(GL2.GL_VERTEX_PROGRAM_POINT_SIZE);
- if (!caps.contains(Caps.CoreProfile)) {
+ if (!glCaps.has(Caps.CoreProfile)) {
gl2.glEnable(GL2.GL_POINT_SPRITE);
context.pointSprite = true;
}
}
}
+ protected void loadCapabilities() {
+ glCaps.loadCapabilities(gl, gl2, gl3, context);
+ }
+
public void invalidateState() {
context.reset();
if (gl2 != null) {
@@ -595,7 +223,7 @@ public void setBackgroundColor(ColorRGBA color) {
}
public void setAlphaToCoverage(boolean value) {
- if (caps.contains(Caps.Multisample)) {
+ if (glCaps.has(Caps.Multisample)) {
if (value) {
gl.glEnable(GLExt.GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
} else {
@@ -1051,7 +679,7 @@ public void updateShaderSourceData(ShaderSource source) {
throw new RendererException("Cannot recompile shader source");
}
- boolean gles2 = caps.contains(Caps.OpenGLES20);
+ boolean gles2 = glCaps.has(Caps.OpenGLES20);
String language = source.getLanguage();
if (gles2 && !language.equals("GLSL100")) {
@@ -1170,7 +798,7 @@ public void updateShaderData(Shader shader) {
// Check if GLSL version is 1.5 for shader
gl3.glBindFragDataLocation(id, 0, "outFragColor");
// For MRT
- for (int i = 0; i < limits.get(Limits.FrameBufferMrtAttachments); i++) {
+ for (int i = 0; i < glCaps.getLimits().get(Limits.FrameBufferMrtAttachments); i++) {
gl3.glBindFragDataLocation(id, i, "outFragData[" + i + "]");
}
}
@@ -1270,7 +898,7 @@ public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst) {
}
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst, boolean copyDepth) {
- if (caps.contains(Caps.FrameBufferBlit)) {
+ if (glCaps.has(Caps.FrameBufferBlit)) {
int srcX0 = 0;
int srcY0 = 0;
int srcX1;
@@ -1381,7 +1009,7 @@ private void updateRenderBuffer(FrameBuffer fb, RenderBuffer rb) {
context.boundRB = id;
}
- int rbSize = limits.get(Limits.RenderBufferSize);
+ int rbSize = glCaps.getLimits().get(Limits.RenderBufferSize);
if (fb.getWidth() > rbSize || fb.getHeight() > rbSize) {
throw new RendererException("Resolution " + fb.getWidth()
+ ":" + fb.getHeight() + " is not supported.");
@@ -1389,9 +1017,9 @@ private void updateRenderBuffer(FrameBuffer fb, RenderBuffer rb) {
GLImageFormat glFmt = texUtil.getImageFormatWithError(rb.getFormat(), fb.isSrgb());
- if (fb.getSamples() > 1 && caps.contains(Caps.FrameBufferMultisample)) {
+ if (fb.getSamples() > 1 && glCaps.has(Caps.FrameBufferMultisample)) {
int samples = fb.getSamples();
- int maxSamples = limits.get(Limits.FrameBufferSamples);
+ int maxSamples = glCaps.getLimits().get(Limits.FrameBufferSamples);
if (maxSamples < samples) {
samples = maxSamples;
}
@@ -1521,7 +1149,7 @@ public Vector2f[] getFrameBufferSamplePositions(FrameBuffer fb) {
if (fb.getSamples() <= 1) {
throw new IllegalArgumentException("Framebuffer must be multisampled");
}
- if (!caps.contains(Caps.TextureMultisample)) {
+ if (!glCaps.has(Caps.TextureMultisample)) {
throw new RendererException("Multisampled textures are not supported");
}
@@ -1570,28 +1198,26 @@ public void setReadDrawBuffers(FrameBuffer fb) {
if (fb.getNumColorBuffers() == 0) {
// make sure to select NONE as draw buf
// no color buffer attached.
- if (gl2 != null) {
- if (context.boundDrawBuf != NONE) {
- gl2.glDrawBuffer(GL.GL_NONE);
- context.boundDrawBuf = NONE;
- }
- if (context.boundReadBuf != NONE) {
- gl2.glReadBuffer(GL.GL_NONE);
- context.boundReadBuf = NONE;
- }
+ if (context.boundDrawBuf != NONE) {
+ gl2.glDrawBuffer(GL.GL_NONE);
+ context.boundDrawBuf = NONE;
+ }
+ if (context.boundReadBuf != NONE) {
+ gl2.glReadBuffer(GL.GL_NONE);
+ context.boundReadBuf = NONE;
}
} else {
- if (fb.getNumColorBuffers() > limits.get(Limits.FrameBufferAttachments)) {
+ if (fb.getNumColorBuffers() > glCaps.getLimits().get(Limits.FrameBufferAttachments)) {
throw new RendererException("Framebuffer has more color "
+ "attachments than are supported"
+ " by the video hardware!");
}
if (fb.isMultiTarget()) {
- if (!caps.contains(Caps.FrameBufferMRT)) {
+ if (!glCaps.has(Caps.FrameBufferMRT)) {
throw new RendererException("Multiple render targets "
+ " are not supported by the video hardware");
}
- if (fb.getNumColorBuffers() > limits.get(Limits.FrameBufferMrtAttachments)) {
+ if (fb.getNumColorBuffers() > glCaps.getLimits().get(Limits.FrameBufferMrtAttachments)) {
throw new RendererException("Framebuffer has more"
+ " multi targets than are supported"
+ " by the video hardware!");
@@ -1610,11 +1236,9 @@ public void setReadDrawBuffers(FrameBuffer fb) {
} else {
RenderBuffer rb = fb.getColorBuffer(fb.getTargetIndex());
// select this draw buffer
- if (gl2 != null) {
- if (context.boundDrawBuf != rb.getSlot()) {
- gl2.glDrawBuffer(GLFbo.GL_COLOR_ATTACHMENT0_EXT + rb.getSlot());
- context.boundDrawBuf = rb.getSlot();
- }
+ if (context.boundDrawBuf != rb.getSlot()) {
+ gl2.glDrawBuffer(GLFbo.GL_COLOR_ATTACHMENT0_EXT + rb.getSlot());
+ context.boundDrawBuf = rb.getSlot();
}
}
}
@@ -1633,7 +1257,7 @@ public void setFrameBuffer(FrameBuffer fb) {
}
}
- if (!caps.contains(Caps.FrameBuffer)) {
+ if (!glCaps.has(Caps.FrameBuffer)) {
throw new RendererException("Framebuffer objects are not supported"
+ " by the video hardware");
}
@@ -1736,7 +1360,7 @@ public void deleteFrameBuffer(FrameBuffer fb) {
|* Textures *|
\*********************************************************************/
private int convertTextureType(Texture.Type type, int samples, int face) {
- if (samples > 1 && !caps.contains(Caps.TextureMultisample)) {
+ if (samples > 1 && !glCaps.has(Caps.TextureMultisample)) {
throw new RendererException("Multisample textures are not supported" +
" by the video hardware.");
}
@@ -1749,7 +1373,7 @@ private int convertTextureType(Texture.Type type, int samples, int face) {
return GL.GL_TEXTURE_2D;
}
case TwoDimensionalArray:
- if (!caps.contains(Caps.TextureArray)) {
+ if (!glCaps.has(Caps.TextureArray)) {
throw new RendererException("Array textures are not supported"
+ " by the video hardware.");
}
@@ -1759,7 +1383,7 @@ private int convertTextureType(Texture.Type type, int samples, int face) {
return GLExt.GL_TEXTURE_2D_ARRAY_EXT;
}
case ThreeDimensional:
- if (!caps.contains(Caps.OpenGL20)) {
+ if (!glCaps.has(Caps.OpenGL20)) {
throw new RendererException("3D textures are not supported" +
" by the video hardware.");
}
@@ -1860,7 +1484,7 @@ private void setupTextureParams(int unit, Texture tex) {
gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER, convertMinFilter(tex.getMinFilter(), haveMips));
curState.minFilter = tex.getMinFilter();
}
- if (caps.contains(Caps.TextureFilterAnisotropic)
+ if (glCaps.has(Caps.TextureFilterAnisotropic)
&& curState.anisoFilter != tex.getAnisotropicFilter()) {
bindTextureAndUnit(target, image, unit);
gl.glTexParameterf(target,
@@ -1931,13 +1555,13 @@ private void checkNonPowerOfTwo(Texture tex) {
return;
}
- if (caps.contains(Caps.NonPowerOfTwoTextures)) {
+ if (glCaps.has(Caps.NonPowerOfTwoTextures)) {
// Texture is NPOT but it is supported by video hardware.
return;
}
// Maybe we have some / partial support for NPOT?
- if (!caps.contains(Caps.PartialNonPowerOfTwoTextures)) {
+ if (!glCaps.has(Caps.PartialNonPowerOfTwoTextures)) {
// Cannot use any type of NPOT texture (uncommon)
throw new RendererException("non-power-of-2 textures are not "
+ "supported by the video hardware");
@@ -2043,7 +1667,7 @@ public void updateTexImageData(Image img, Texture.Type type, int unit, boolean s
// Image does not have mipmaps, but they are required.
// Generate from base level.
- if (!caps.contains(Caps.FrameBuffer) && gl2 != null) {
+ if (!glCaps.has(Caps.FrameBuffer) && gl2 != null) {
gl2.glTexParameteri(target, GL2.GL_GENERATE_MIPMAP, GL.GL_TRUE);
img.setMipmapsGenerated(true);
} else {
@@ -2063,27 +1687,27 @@ public void updateTexImageData(Image img, Texture.Type type, int unit, boolean s
int imageSamples = img.getMultiSamples();
if (imageSamples > 1) {
if (img.getFormat().isDepthFormat()) {
- img.setMultiSamples(Math.min(limits.get(Limits.DepthTextureSamples), imageSamples));
+ img.setMultiSamples(Math.min(glCaps.getLimits().get(Limits.DepthTextureSamples), imageSamples));
} else {
- img.setMultiSamples(Math.min(limits.get(Limits.ColorTextureSamples), imageSamples));
+ img.setMultiSamples(Math.min(glCaps.getLimits().get(Limits.ColorTextureSamples), imageSamples));
}
}
// Check if graphics card doesn't support multisample textures
- if (!caps.contains(Caps.TextureMultisample)) {
+ if (!glCaps.has(Caps.TextureMultisample)) {
if (img.getMultiSamples() > 1) {
throw new RendererException("Multisample textures are not supported by the video hardware");
}
}
// Check if graphics card doesn't support depth textures
- if (img.getFormat().isDepthFormat() && !caps.contains(Caps.DepthTexture)) {
+ if (img.getFormat().isDepthFormat() && !glCaps.has(Caps.DepthTexture)) {
throw new RendererException("Depth textures are not supported by the video hardware");
}
if (target == GL.GL_TEXTURE_CUBE_MAP) {
// Check max texture size before upload
- int cubeSize = limits.get(Limits.CubemapSize);
+ int cubeSize = glCaps.getLimits().get(Limits.CubemapSize);
if (img.getWidth() > cubeSize || img.getHeight() > cubeSize) {
throw new RendererException("Cannot upload cubemap " + img + ". The maximum supported cubemap resolution is " + cubeSize);
}
@@ -2091,7 +1715,7 @@ public void updateTexImageData(Image img, Texture.Type type, int unit, boolean s
throw new RendererException("Cubemaps must have square dimensions");
}
} else {
- int texSize = limits.get(Limits.TextureSize);
+ int texSize = glCaps.getLimits().get(Limits.TextureSize);
if (img.getWidth() > texSize || img.getHeight() > texSize) {
throw new RendererException("Cannot upload texture " + img + ". The maximum supported texture resolution is " + texSize);
}
@@ -2114,7 +1738,7 @@ public void updateTexImageData(Image img, Texture.Type type, int unit, boolean s
texUtil.uploadTexture(imageForUpload, GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, i, linearizeSrgbImages);
}
} else if (target == GLExt.GL_TEXTURE_2D_ARRAY_EXT) {
- if (!caps.contains(Caps.TextureArray)) {
+ if (!glCaps.has(Caps.TextureArray)) {
throw new RendererException("Texture arrays not supported by graphics hardware");
}
@@ -2136,7 +1760,7 @@ public void updateTexImageData(Image img, Texture.Type type, int unit, boolean s
img.setMultiSamples(imageSamples);
}
- if (caps.contains(Caps.FrameBuffer) || gl2 == null) {
+ if (glCaps.has(Caps.FrameBuffer) || gl2 == null) {
if (!img.hasMipmaps() && img.isGeneratedMipmapsRequired() && img.getData(0) != null) {
glfbo.glGenerateMipmapEXT(target);
img.setMipmapsGenerated(true);
@@ -2351,7 +1975,7 @@ public void setVertexAttrib(VertexBuffer vb, VertexBuffer idb) {
}
if (vb.isInstanced()) {
- if (!caps.contains(Caps.MeshInstancing)) {
+ if (!glCaps.has(Caps.MeshInstancing)) {
throw new RendererException("Instancing is required, "
+ "but not supported by the "
+ "graphics hardware");
@@ -2433,7 +2057,7 @@ public void setVertexAttrib(VertexBuffer vb) {
}
public void drawTriangleArray(Mesh.Mode mode, int count, int vertCount) {
- boolean useInstancing = count > 1 && caps.contains(Caps.MeshInstancing);
+ boolean useInstancing = count > 1 && glCaps.has(Caps.MeshInstancing);
if (useInstancing) {
glext.glDrawArraysInstancedARB(convertElementMode(mode), 0,
vertCount, count);
@@ -2453,7 +2077,7 @@ public void drawTriangleList(VertexBuffer indexBuf, Mesh mesh, int count) {
break;
case UnsignedInt:
// Requres extension on OpenGL ES 2.
- if (!caps.contains(Caps.IntegerIndexBuffer)) {
+ if (!glCaps.has(Caps.IntegerIndexBuffer)) {
throw new RendererException("32-bit index buffers are not supported by the video hardware");
}
break;
@@ -2478,7 +2102,7 @@ public void drawTriangleList(VertexBuffer indexBuf, Mesh mesh, int count) {
}
int vertCount = mesh.getVertexCount();
- boolean useInstancing = count > 1 && caps.contains(Caps.MeshInstancing);
+ boolean useInstancing = count > 1 && glCaps.has(Caps.MeshInstancing);
if (mesh.getMode() == Mode.Hybrid) {
int[] modeStart = mesh.getModeStart();
@@ -2700,7 +2324,7 @@ public void renderMesh(Mesh mesh, int lod, int count, VertexBuffer[] instanceDat
public void setMainFrameBufferSrgb(boolean enableSrgb) {
// Gamma correction
- if (!caps.contains(Caps.Srgb) && enableSrgb) {
+ if (!glCaps.has(Caps.Srgb) && enableSrgb) {
// Not supported, sorry.
logger.warning("sRGB framebuffer is not supported " +
"by video hardware, but was requested.");
@@ -2725,8 +2349,14 @@ public void setMainFrameBufferSrgb(boolean enableSrgb) {
}
public void setLinearizeSrgbImages(boolean linearize) {
- if (caps.contains(Caps.Srgb)) {
+ if (glCaps.has(Caps.Srgb)) {
linearizeSrgbImages = linearize;
}
}
+
+ private int getInteger(int en) {
+ intBuf16.clear();
+ gl.glGetInteger(en, intBuf16);
+ return intBuf16.get(0);
+ }
}
diff --git a/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java
old mode 100644
new mode 100755
index bd70465cbc..461c0f5f43
--- a/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java
+++ b/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java
@@ -64,7 +64,7 @@
import com.jme3.texture.Texture.MagFilter;
import com.jme3.texture.Texture.MinFilter;
import com.jme3.texture.Texture.ShadowCompareMode;
-import com.jme3.texture.Texture2D;
+import com.jme3.texture.TextureDefault2D;
import com.jme3.ui.Picture;
/**
@@ -81,8 +81,8 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable
protected RenderManager renderManager;
protected ViewPort viewPort;
protected FrameBuffer[] shadowFB;
- protected Texture2D[] shadowMaps;
- protected Texture2D dummyTex;
+ protected TextureDefault2D[] shadowMaps;
+ protected TextureDefault2D dummyTex;
protected Material preshadowMat;
protected Material postshadowMat;
protected Matrix4f[] lightViewProjectionsMatrices;
@@ -147,14 +147,14 @@ protected AbstractShadowRenderer(AssetManager assetManager, int shadowMapSize, i
private void init(AssetManager assetManager, int nbShadowMaps, int shadowMapSize) {
this.postshadowMat = new Material(assetManager, "Common/MatDefs/Shadow/PostShadow.j3md");
shadowFB = new FrameBuffer[nbShadowMaps];
- shadowMaps = new Texture2D[nbShadowMaps];
+ shadowMaps = new TextureDefault2D[nbShadowMaps];
dispPic = new Picture[nbShadowMaps];
lightViewProjectionsMatrices = new Matrix4f[nbShadowMaps];
shadowMapStringCache = new String[nbShadowMaps];
lightViewStringCache = new String[nbShadowMaps];
//DO NOT COMMENT THIS (it prevent the OSX incomplete read buffer crash)
- dummyTex = new Texture2D(shadowMapSize, shadowMapSize, Format.RGBA8);
+ dummyTex = new TextureDefault2D(shadowMapSize, shadowMapSize, Format.RGBA8);
preshadowMat = new Material(assetManager, "Common/MatDefs/Shadow/PreShadow.j3md");
postshadowMat.setFloat("ShadowMapSize", shadowMapSize);
@@ -162,7 +162,7 @@ private void init(AssetManager assetManager, int nbShadowMaps, int shadowMapSize
for (int i = 0; i < nbShadowMaps; i++) {
lightViewProjectionsMatrices[i] = new Matrix4f();
shadowFB[i] = new FrameBuffer(shadowMapSize, shadowMapSize, 1);
- shadowMaps[i] = new Texture2D(shadowMapSize, shadowMapSize, Format.Depth);
+ shadowMaps[i] = new TextureDefault2D(shadowMapSize, shadowMapSize, Format.Depth);
shadowFB[i].setDepthTexture(shadowMaps[i]);
@@ -214,7 +214,7 @@ final public void setEdgeFilteringMode(EdgeFilteringMode filterMode) {
postshadowMat.setInt("FilterMode", filterMode.getMaterialParamValue());
postshadowMat.setFloat("PCFEdge", edgesThickness);
if (shadowCompareMode == CompareMode.Hardware) {
- for (Texture2D shadowMap : shadowMaps) {
+ for (TextureDefault2D shadowMap : shadowMaps) {
if (filterMode == EdgeFilteringMode.Bilinear) {
shadowMap.setMagFilter(MagFilter.Bilinear);
shadowMap.setMinFilter(MinFilter.BilinearNoMipMaps);
@@ -247,7 +247,7 @@ final public void setShadowCompareMode(CompareMode compareMode) {
}
this.shadowCompareMode = compareMode;
- for (Texture2D shadowMap : shadowMaps) {
+ for (TextureDefault2D shadowMap : shadowMaps) {
if (compareMode == CompareMode.Hardware) {
shadowMap.setShadowCompareMode(ShadowCompareMode.LessOrEqual);
if (edgeFilteringMode == EdgeFilteringMode.Bilinear) {
diff --git a/jme3-core/src/main/java/com/jme3/shadow/BasicShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/BasicShadowRenderer.java
old mode 100644
new mode 100755
index 1410574eaa..8348b2f38a
--- a/jme3-core/src/main/java/com/jme3/shadow/BasicShadowRenderer.java
+++ b/jme3-core/src/main/java/com/jme3/shadow/BasicShadowRenderer.java
@@ -46,7 +46,7 @@
import com.jme3.scene.Spatial;
import com.jme3.texture.FrameBuffer;
import com.jme3.texture.Image.Format;
-import com.jme3.texture.Texture2D;
+import com.jme3.texture.TextureDefault2D;
import com.jme3.ui.Picture;
/**
@@ -62,7 +62,7 @@ public class BasicShadowRenderer implements SceneProcessor {
private RenderManager renderManager;
private ViewPort viewPort;
private FrameBuffer shadowFB;
- private Texture2D shadowMap;
+ private TextureDefault2D shadowMap;
private Camera shadowCam;
private Material preshadowMat;
private Material postshadowMat;
@@ -70,7 +70,7 @@ public class BasicShadowRenderer implements SceneProcessor {
private boolean noOccluders = false;
private Vector3f[] points = new Vector3f[8];
private Vector3f direction = new Vector3f();
- protected Texture2D dummyTex;
+ protected TextureDefault2D dummyTex;
private float shadowMapSize;
protected GeometryList lightReceivers = new GeometryList(new OpaqueComparator());
@@ -83,12 +83,12 @@ public class BasicShadowRenderer implements SceneProcessor {
*/
public BasicShadowRenderer(AssetManager manager, int size) {
shadowFB = new FrameBuffer(size, size, 1);
- shadowMap = new Texture2D(size, size, Format.Depth);
+ shadowMap = new TextureDefault2D(size, size, Format.Depth);
shadowFB.setDepthTexture(shadowMap);
shadowCam = new Camera(size, size);
//DO NOT COMMENT THIS (it prevent the OSX incomplete read buffer crash)
- dummyTex = new Texture2D(size, size, Format.RGBA8);
+ dummyTex = new TextureDefault2D(size, size, Format.RGBA8);
shadowFB.setColorTexture(dummyTex);
shadowMapSize = (float)size;
preshadowMat = new Material(manager, "Common/MatDefs/Shadow/PreShadow.j3md");
diff --git a/jme3-core/src/main/java/com/jme3/shadow/PssmShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/PssmShadowRenderer.java
old mode 100644
new mode 100755
index e06b5c3375..ef6ed40c5a
--- a/jme3-core/src/main/java/com/jme3/shadow/PssmShadowRenderer.java
+++ b/jme3-core/src/main/java/com/jme3/shadow/PssmShadowRenderer.java
@@ -56,7 +56,7 @@
import com.jme3.texture.Texture.MagFilter;
import com.jme3.texture.Texture.MinFilter;
import com.jme3.texture.Texture.ShadowCompareMode;
-import com.jme3.texture.Texture2D;
+import com.jme3.texture.TextureDefault2D;
import com.jme3.ui.Picture;
import java.util.ArrayList;
import java.util.List;
@@ -140,8 +140,8 @@ public enum CompareMode {
protected RenderManager renderManager;
protected ViewPort viewPort;
protected FrameBuffer[] shadowFB;
- protected Texture2D[] shadowMaps;
- protected Texture2D dummyTex;
+ protected TextureDefault2D[] shadowMaps;
+ protected TextureDefault2D dummyTex;
protected Camera shadowCam;
protected Material preshadowMat;
protected Material postshadowMat;
@@ -212,14 +212,14 @@ protected PssmShadowRenderer(AssetManager manager, int size, int nbSplits, Mater
shadowMapSize = size;
shadowFB = new FrameBuffer[nbSplits];
- shadowMaps = new Texture2D[nbSplits];
+ shadowMaps = new TextureDefault2D[nbSplits];
dispPic = new Picture[nbSplits];
lightViewProjectionsMatrices = new Matrix4f[nbSplits];
splits = new ColorRGBA();
splitsArray = new float[nbSplits + 1];
//DO NOT COMMENT THIS (it prevent the OSX incomplete read buffer crash)
- dummyTex = new Texture2D(size, size, Format.RGBA8);
+ dummyTex = new TextureDefault2D(size, size, Format.RGBA8);
preshadowMat = new Material(manager, "Common/MatDefs/Shadow/PreShadow.j3md");
postshadowMat.setFloat("ShadowMapSize", size);
@@ -227,7 +227,7 @@ protected PssmShadowRenderer(AssetManager manager, int size, int nbSplits, Mater
for (int i = 0; i < nbSplits; i++) {
lightViewProjectionsMatrices[i] = new Matrix4f();
shadowFB[i] = new FrameBuffer(size, size, 1);
- shadowMaps[i] = new Texture2D(size, size, Format.Depth);
+ shadowMaps[i] = new TextureDefault2D(size, size, Format.Depth);
shadowFB[i].setDepthTexture(shadowMaps[i]);
@@ -273,7 +273,7 @@ final public void setFilterMode(FilterMode filterMode) {
postshadowMat.setInt("FilterMode", filterMode.ordinal());
postshadowMat.setFloat("PCFEdge", edgesThickness);
if (compareMode == CompareMode.Hardware) {
- for (Texture2D shadowMap : shadowMaps) {
+ for (TextureDefault2D shadowMap : shadowMaps) {
if (filterMode == FilterMode.Bilinear) {
shadowMap.setMagFilter(MagFilter.Bilinear);
shadowMap.setMinFilter(MinFilter.BilinearNoMipMaps);
@@ -301,7 +301,7 @@ final public void setCompareMode(CompareMode compareMode) {
}
this.compareMode = compareMode;
- for (Texture2D shadowMap : shadowMaps) {
+ for (TextureDefault2D shadowMap : shadowMaps) {
if (compareMode == CompareMode.Hardware) {
shadowMap.setShadowCompareMode(ShadowCompareMode.LessOrEqual);
if (filterMode == FilterMode.Bilinear) {
diff --git a/jme3-core/src/main/java/com/jme3/system/AppSettings.java b/jme3-core/src/main/java/com/jme3/system/AppSettings.java
old mode 100644
new mode 100755
diff --git a/jme3-core/src/main/java/com/jme3/system/JmeContext.java b/jme3-core/src/main/java/com/jme3/system/JmeContext.java
old mode 100644
new mode 100755
index f4f47ae679..cda9ac7211
--- a/jme3-core/src/main/java/com/jme3/system/JmeContext.java
+++ b/jme3-core/src/main/java/com/jme3/system/JmeContext.java
@@ -31,17 +31,15 @@
*/
package com.jme3.system;
-import com.jme3.input.JoyInput;
-import com.jme3.input.KeyInput;
-import com.jme3.input.MouseInput;
-import com.jme3.input.TouchInput;
+import com.jme3.input.*;
import com.jme3.renderer.Renderer;
+import java.util.List;
+
/**
* Represents a rendering context within the engine.
*/
public interface JmeContext {
-
/**
* The type of context.
*/
@@ -110,6 +108,11 @@ public enum Type {
*/
public Renderer getRenderer();
+ /**
+ * @return All input implementations. May be empty if not available.
+ */
+ public List getInput();
+
/**
* @return Mouse input implementation. May be null if not available.
*/
diff --git a/jme3-core/src/main/java/com/jme3/system/NullContext.java b/jme3-core/src/main/java/com/jme3/system/NullContext.java
old mode 100644
new mode 100755
index 41204e6c98..0b9c4ac177
--- a/jme3-core/src/main/java/com/jme3/system/NullContext.java
+++ b/jme3-core/src/main/java/com/jme3/system/NullContext.java
@@ -31,13 +31,14 @@
*/
package com.jme3.system;
-import com.jme3.input.JoyInput;
-import com.jme3.input.KeyInput;
-import com.jme3.input.MouseInput;
-import com.jme3.input.TouchInput;
+import com.jme3.input.*;
import com.jme3.input.dummy.DummyKeyInput;
import com.jme3.input.dummy.DummyMouseInput;
import com.jme3.renderer.Renderer;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -58,6 +59,8 @@ public class NullContext implements JmeContext, Runnable {
protected SystemListener listener;
protected NullRenderer renderer;
+ protected List inputs;
+
public Type getType() {
return Type.Headless;
}
@@ -175,6 +178,20 @@ public JoyInput getJoyInput() {
return null;
}
+ public java.util.List getInput() {
+ if(inputs == null) {
+ inputs = new ArrayList<>();
+ inputs.add(getKeyInput());
+ inputs.add(getMouseInput());
+ if(!settings.getBoolean("DisableJoysticks")) {
+ inputs.add(getJoyInput());
+ }
+ inputs.add(getTouchInput());
+ inputs.removeAll(Collections.singleton(null));
+ }
+ return inputs;
+ }
+
public TouchInput getTouchInput() {
return null;
}
diff --git a/jme3-core/src/main/java/com/jme3/texture/FrameBuffer.java b/jme3-core/src/main/java/com/jme3/texture/FrameBuffer.java
old mode 100644
new mode 100755
index bc21fd82bb..62555762f9
--- a/jme3-core/src/main/java/com/jme3/texture/FrameBuffer.java
+++ b/jme3-core/src/main/java/com/jme3/texture/FrameBuffer.java
@@ -319,7 +319,7 @@ public int getTargetIndex(){
*
* @param tex The color texture to set.
*/
- public void setColorTexture(Texture2D tex){
+ public void setColorTexture(TextureDefault2D tex){
clearColorTargets();
addColorTexture(tex);
}
@@ -354,7 +354,7 @@ public void clearColorTargets(){
*
* @param tex The texture to add.
*/
- public void addColorTexture(Texture2D tex) {
+ public void addColorTexture(TextureDefault2D tex) {
if (id != -1)
throw new UnsupportedOperationException("FrameBuffer already initialized.");
@@ -400,7 +400,7 @@ public void addColorTexture(TextureCubeMap tex, TextureCubeMap.Face face) {
*
* @param tex The color texture to set.
*/
- public void setDepthTexture(Texture2D tex){
+ public void setDepthTexture(TextureDefault2D tex){
if (id != -1)
throw new UnsupportedOperationException("FrameBuffer already initialized.");
diff --git a/jme3-core/src/main/java/com/jme3/texture/Texture.java b/jme3-core/src/main/java/com/jme3/texture/Texture.java
old mode 100644
new mode 100755
index 6be00700b7..5188c1da44
--- a/jme3-core/src/main/java/com/jme3/texture/Texture.java
+++ b/jme3-core/src/main/java/com/jme3/texture/Texture.java
@@ -318,6 +318,9 @@ public enum ShadowCompareMode {
private ShadowCompareMode shadowCompareMode = ShadowCompareMode.Off;
private int anisotropicFilter;
+ protected WrapMode wrapS = WrapMode.EdgeClamp;
+ protected WrapMode wrapT = WrapMode.EdgeClamp;
+
/**
* @return A cloned Texture object.
*/
@@ -450,7 +453,22 @@ public Image getImage() {
* @throws IllegalArgumentException
* if axis or mode are null or invalid for this type of texture
*/
- public abstract void setWrap(WrapAxis axis, WrapMode mode);
+ public void setWrap(WrapAxis axis, WrapMode mode){
+ if (mode == null) {
+ throw new IllegalArgumentException("mode can not be null.");
+ } else if (axis == null) {
+ throw new IllegalArgumentException("axis can not be null.");
+ }
+
+ switch (axis) {
+ case S:
+ this.wrapS = mode;
+ break;
+ case T:
+ this.wrapT = mode;
+ break;
+ }
+ }
/**
* setWrap sets the wrap mode of this texture for all axis.
@@ -460,7 +478,13 @@ public Image getImage() {
* @throws IllegalArgumentException
* if mode is null or invalid for this type of texture
*/
- public abstract void setWrap(WrapMode mode);
+ public void setWrap(WrapMode mode) {
+ if (mode == null) {
+ throw new IllegalArgumentException("mode can not be null.");
+ }
+ this.wrapS = mode;
+ this.wrapT = mode;
+ }
/**
* getWrap returns the wrap mode for a given coordinate axis
@@ -472,7 +496,11 @@ public Image getImage() {
* @throws IllegalArgumentException
* if axis is null or invalid for this type of texture
*/
- public abstract WrapMode getWrap(WrapAxis axis);
+ public WrapMode getWrap(WrapAxis axis) {
+ if (axis == WrapAxis.S) return wrapS;
+ else if (axis == WrapAxis.T) return wrapT;
+ throw new IllegalArgumentException("invalid WrapAxis: " + axis);
+ }
public abstract Type getType();
@@ -523,6 +551,11 @@ public boolean equals(Object obj) {
return false;
}
final Texture other = (Texture) obj;
+
+ if (this.getWrap(WrapAxis.S) != other.getWrap(WrapAxis.S))
+ return false;
+ if (this.getWrap(WrapAxis.T) != other.getWrap(WrapAxis.T))
+ return false;
// NOTE: Since images are generally considered unique assets in jME3,
// using the image's equals() implementation is not neccessary here
@@ -600,6 +633,8 @@ public void write(JmeExporter e) throws IOException {
MinFilter.BilinearNoMipMaps);
capsule.write(magnificationFilter, "magnificationFilter",
MagFilter.Bilinear);
+ capsule.write(wrapS, "wrapS", WrapMode.EdgeClamp);
+ capsule.write(wrapT, "wrapT", WrapMode.EdgeClamp);
}
public void read(JmeImporter e) throws IOException {
diff --git a/jme3-core/src/main/java/com/jme3/texture/Texture2D.java b/jme3-core/src/main/java/com/jme3/texture/Texture2D.java
old mode 100644
new mode 100755
index 441da13533..954e71a9c6
--- a/jme3-core/src/main/java/com/jme3/texture/Texture2D.java
+++ b/jme3-core/src/main/java/com/jme3/texture/Texture2D.java
@@ -1,112 +1,15 @@
-/*
- * Copyright (c) 2009-2012 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
package com.jme3.texture;
-import com.jme3.export.InputCapsule;
-import com.jme3.export.JmeExporter;
-import com.jme3.export.JmeImporter;
-import com.jme3.export.OutputCapsule;
-import com.jme3.texture.image.ColorSpace;
-import java.io.IOException;
+public abstract class Texture2D extends Texture{
-/**
- * @author Joshua Slack
- */
-public class Texture2D extends Texture {
-
- private WrapMode wrapS = WrapMode.EdgeClamp;
- private WrapMode wrapT = WrapMode.EdgeClamp;
-
- /**
- * Creates a new two-dimensional texture with default attributes.
- */
- public Texture2D(){
+ public Texture2D() {
super();
}
- /**
- * Creates a new two-dimensional texture using the given image.
- * @param img The image to use.
- */
- public Texture2D(Image img){
- super();
- setImage(img);
- if (img.getData(0) == null) {
- setMagFilter(MagFilter.Nearest);
- setMinFilter(MinFilter.NearestNoMipMaps);
- }
- }
-
- /**
- * Creates a new two-dimensional texture for the purpose of offscreen
- * rendering.
- *
- * @see com.jme3.texture.FrameBuffer
- *
- * @param width
- * @param height
- * @param format
- */
- public Texture2D(int width, int height, Image.Format format){
- this(new Image(format, width, height, null, ColorSpace.Linear));
- }
-
- /**
- * Creates a new two-dimensional texture for the purpose of offscreen
- * rendering.
- *
- * @see com.jme3.texture.FrameBuffer
- *
- * @param width
- * @param height
- * @param format
- * @param numSamples
- */
- public Texture2D(int width, int height, int numSamples, Image.Format format){
- this(new Image(format, width, height, null, ColorSpace.Linear));
- getImage().setMultiSamples(numSamples);
- }
-
- @Override
- public Texture createSimpleClone() {
- Texture2D clone = new Texture2D();
- createSimpleClone(clone);
- return clone;
- }
-
@Override
public Texture createSimpleClone(Texture rVal) {
- rVal.setWrap(WrapAxis.S, wrapS);
- rVal.setWrap(WrapAxis.T, wrapT);
+ rVal.setWrap(Texture.WrapAxis.S, wrapS);
+ rVal.setWrap(Texture.WrapAxis.T, wrapT);
return super.createSimpleClone(rVal);
}
@@ -122,20 +25,9 @@ public Texture createSimpleClone(Texture rVal) {
* if axis or mode are null
*/
public void setWrap(WrapAxis axis, WrapMode mode) {
- if (mode == null) {
- throw new IllegalArgumentException("mode can not be null.");
- } else if (axis == null) {
- throw new IllegalArgumentException("axis can not be null.");
- }
- switch (axis) {
- case S:
- this.wrapS = mode;
- break;
- case T:
- this.wrapT = mode;
- break;
- default:
- throw new IllegalArgumentException("Not applicable for 2D textures");
+ super.setWrap(axis, mode);
+ if (axis != WrapAxis.S && axis != WrapAxis.T) {
+ throw new IllegalArgumentException("Not applicable for 2D textures");
}
}
@@ -148,11 +40,7 @@ public void setWrap(WrapAxis axis, WrapMode mode) {
* if mode is null
*/
public void setWrap(WrapMode mode) {
- if (mode == null) {
- throw new IllegalArgumentException("mode can not be null.");
- }
- this.wrapS = mode;
- this.wrapT = mode;
+ super.setWrap(mode);
}
/**
@@ -163,59 +51,12 @@ public void setWrap(WrapMode mode) {
* the axis to return for
* @return the wrap mode of the texture.
* @throws IllegalArgumentException
- * if axis is null
+ * if axis is null or invalid for this type
*/
public WrapMode getWrap(WrapAxis axis) {
- switch (axis) {
- case S:
- return wrapS;
- case T:
- return wrapT;
- default:
- throw new IllegalArgumentException("invalid WrapAxis: " + axis);
- }
- }
-
- @Override
- public Type getType() {
- return Type.TwoDimensional;
- }
-
- @Override
- public boolean equals(Object other) {
- if (!(other instanceof Texture2D)) {
- return false;
+ if (axis == WrapAxis.R) {
+ throw new IllegalArgumentException("invalid WrapAxis: " + axis);
}
- Texture2D that = (Texture2D) other;
- if (this.getWrap(WrapAxis.S) != that.getWrap(WrapAxis.S))
- return false;
- if (this.getWrap(WrapAxis.T) != that.getWrap(WrapAxis.T))
- return false;
- return super.equals(other);
- }
-
- @Override
- public int hashCode() {
- int hash = super.hashCode();
- hash = 79 * hash + (this.wrapS != null ? this.wrapS.hashCode() : 0);
- hash = 79 * hash + (this.wrapT != null ? this.wrapT.hashCode() : 0);
- return hash;
+ return super.getWrap(axis);
}
-
- @Override
- public void write(JmeExporter e) throws IOException {
- super.write(e);
- OutputCapsule capsule = e.getCapsule(this);
- capsule.write(wrapS, "wrapS", WrapMode.EdgeClamp);
- capsule.write(wrapT, "wrapT", WrapMode.EdgeClamp);
- }
-
- @Override
- public void read(JmeImporter e) throws IOException {
- super.read(e);
- InputCapsule capsule = e.getCapsule(this);
- wrapS = capsule.readEnum("wrapS", WrapMode.class, WrapMode.EdgeClamp);
- wrapT = capsule.readEnum("wrapT", WrapMode.class, WrapMode.EdgeClamp);
- }
-
}
diff --git a/jme3-core/src/main/java/com/jme3/texture/Texture3D.java b/jme3-core/src/main/java/com/jme3/texture/Texture3D.java
old mode 100644
new mode 100755
index c94d7c3adb..a1d16dd127
--- a/jme3-core/src/main/java/com/jme3/texture/Texture3D.java
+++ b/jme3-core/src/main/java/com/jme3/texture/Texture3D.java
@@ -1,110 +1,20 @@
-/*
- * Copyright (c) 2009-2012 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
package com.jme3.texture;
import com.jme3.export.InputCapsule;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
-import com.jme3.texture.image.ColorSpace;
+
import java.io.IOException;
-/**
- * @author Maarten Steur
- */
-public class Texture3D extends Texture {
+public abstract class Texture3D extends Texture{
- private WrapMode wrapS = WrapMode.EdgeClamp;
- private WrapMode wrapT = WrapMode.EdgeClamp;
- private WrapMode wrapR = WrapMode.EdgeClamp;
+ protected WrapMode wrapR = WrapMode.EdgeClamp;
- /**
- * Creates a new two-dimensional texture with default attributes.
- */
public Texture3D() {
super();
}
- /**
- * Creates a new three-dimensional texture using the given image.
- * @param img The image to use.
- */
- public Texture3D(Image img) {
- super();
- setImage(img);
- if (img.getFormat().isDepthFormat()) {
- setMagFilter(MagFilter.Nearest);
- setMinFilter(MinFilter.NearestNoMipMaps);
- }
- }
-
- /**
- * Creates a new three-dimensional texture for the purpose of offscreen
- * rendering.
- *
- * @see com.jme3.texture.FrameBuffer
- *
- * @param width
- * @param height
- * @param depth
- * @param format
- */
- public Texture3D(int width, int height, int depth, Image.Format format) {
- this(new Image(format, width, height, depth, null, ColorSpace.Linear));
- }
-
- /**
- * Creates a new three-dimensional texture for the purpose of offscreen
- * rendering.
- *
- * @see com.jme3.texture.FrameBuffer
- *
- * @param width
- * @param height
- * @param format
- * @param numSamples
- */
- public Texture3D(int width, int height, int depth, int numSamples, Image.Format format) {
- this(new Image(format, width, height, depth, null, ColorSpace.Linear));
- getImage().setMultiSamples(numSamples);
- }
-
- @Override
- public Texture createSimpleClone() {
- Texture3D clone = new Texture3D();
- createSimpleClone(clone);
- return clone;
- }
-
@Override
public Texture createSimpleClone(Texture rVal) {
rVal.setWrap(WrapAxis.S, wrapS);
@@ -125,21 +35,9 @@ public Texture createSimpleClone(Texture rVal) {
* if axis or mode are null
*/
public void setWrap(WrapAxis axis, WrapMode mode) {
- if (mode == null) {
- throw new IllegalArgumentException("mode can not be null.");
- } else if (axis == null) {
- throw new IllegalArgumentException("axis can not be null.");
- }
- switch (axis) {
- case S:
- this.wrapS = mode;
- break;
- case T:
- this.wrapT = mode;
- break;
- case R:
- this.wrapR = mode;
- break;
+ super.setWrap(axis, mode);
+ if(axis == WrapAxis.R) {
+ this.wrapR = mode;
}
}
@@ -152,11 +50,7 @@ public void setWrap(WrapAxis axis, WrapMode mode) {
* if mode is null
*/
public void setWrap(WrapMode mode) {
- if (mode == null) {
- throw new IllegalArgumentException("mode can not be null.");
- }
- this.wrapS = mode;
- this.wrapT = mode;
+ super.setWrap(mode);
this.wrapR = mode;
}
@@ -171,46 +65,16 @@ public void setWrap(WrapMode mode) {
* if axis is null
*/
public WrapMode getWrap(WrapAxis axis) {
- switch (axis) {
- case S:
- return wrapS;
- case T:
- return wrapT;
- case R:
- return wrapR;
- }
- throw new IllegalArgumentException("invalid WrapAxis: " + axis);
- }
-
- @Override
- public Type getType() {
- return Type.ThreeDimensional;
- }
-
- @Override
- public boolean equals(Object other) {
- if (!(other instanceof Texture3D)) {
- return false;
- }
- Texture3D that = (Texture3D) other;
- if (this.getWrap(WrapAxis.S) != that.getWrap(WrapAxis.S)) {
- return false;
- }
- if (this.getWrap(WrapAxis.T) != that.getWrap(WrapAxis.T)) {
- return false;
- }
- if (this.getWrap(WrapAxis.R) != that.getWrap(WrapAxis.R)) {
- return false;
+ if (axis == WrapAxis.R) {
+ return wrapR;
}
- return super.equals(other);
+ return super.getWrap(axis);
}
@Override
public void write(JmeExporter e) throws IOException {
super.write(e);
OutputCapsule capsule = e.getCapsule(this);
- capsule.write(wrapS, "wrapS", WrapMode.EdgeClamp);
- capsule.write(wrapT, "wrapT", WrapMode.EdgeClamp);
capsule.write(wrapR, "wrapR", WrapMode.EdgeClamp);
}
@@ -222,4 +86,4 @@ public void read(JmeImporter e) throws IOException {
wrapT = capsule.readEnum("wrapT", WrapMode.class, WrapMode.EdgeClamp);
wrapR = capsule.readEnum("wrapR", WrapMode.class, WrapMode.EdgeClamp);
}
-}
\ No newline at end of file
+}
diff --git a/jme3-core/src/main/java/com/jme3/texture/TextureArray.java b/jme3-core/src/main/java/com/jme3/texture/TextureArray.java
old mode 100644
new mode 100755
index 50015cff82..e466ad7db1
--- a/jme3-core/src/main/java/com/jme3/texture/TextureArray.java
+++ b/jme3-core/src/main/java/com/jme3/texture/TextureArray.java
@@ -45,10 +45,8 @@
* renderManager.getRenderer().getCaps().contains(Caps.TextureArray)
* @author phate666
*/
-public class TextureArray extends Texture {
+public class TextureArray extends Texture2D {
- private WrapMode wrapS = WrapMode.EdgeClamp;
- private WrapMode wrapT = WrapMode.EdgeClamp;
/**
* Construct a TextureArray
@@ -101,55 +99,8 @@ public Texture createSimpleClone() {
return clone;
}
- @Override
- public Texture createSimpleClone(Texture rVal) {
- rVal.setWrap(WrapAxis.S, wrapS);
- rVal.setWrap(WrapAxis.T, wrapT);
- return super.createSimpleClone(rVal);
- }
-
@Override
public Type getType() {
return Type.TwoDimensionalArray;
}
-
- @Override
- public WrapMode getWrap(WrapAxis axis) {
- switch (axis) {
- case S:
- return wrapS;
- case T:
- return wrapT;
- default:
- throw new IllegalArgumentException("invalid WrapAxis: " + axis);
- }
- }
-
- @Override
- public void setWrap(WrapAxis axis, WrapMode mode) {
- if (mode == null) {
- throw new IllegalArgumentException("mode can not be null.");
- } else if (axis == null) {
- throw new IllegalArgumentException("axis can not be null.");
- }
- switch (axis) {
- case S:
- this.wrapS = mode;
- break;
- case T:
- this.wrapT = mode;
- break;
- default:
- throw new IllegalArgumentException("Not applicable for 2D textures");
- }
- }
-
- @Override
- public void setWrap(WrapMode mode) {
- if (mode == null) {
- throw new IllegalArgumentException("mode can not be null.");
- }
- this.wrapS = mode;
- this.wrapT = mode;
- }
}
\ No newline at end of file
diff --git a/jme3-core/src/main/java/com/jme3/texture/TextureCubeMap.java b/jme3-core/src/main/java/com/jme3/texture/TextureCubeMap.java
old mode 100644
new mode 100755
index e2447fac28..b897c67ec3
--- a/jme3-core/src/main/java/com/jme3/texture/TextureCubeMap.java
+++ b/jme3-core/src/main/java/com/jme3/texture/TextureCubeMap.java
@@ -55,11 +55,7 @@
*
* @author Joshua Slack
*/
-public class TextureCubeMap extends Texture {
-
- private WrapMode wrapS = WrapMode.EdgeClamp;
- private WrapMode wrapT = WrapMode.EdgeClamp;
- private WrapMode wrapR = WrapMode.EdgeClamp;
+public class TextureCubeMap extends Texture3D {
/**
* Face of the Cubemap as described by its directional offset from the
@@ -97,83 +93,6 @@ public Texture createSimpleClone() {
return createSimpleClone(new TextureCubeMap());
}
- @Override
- public Texture createSimpleClone(Texture rVal) {
- rVal.setWrap(WrapAxis.S, wrapS);
- rVal.setWrap(WrapAxis.T, wrapT);
- rVal.setWrap(WrapAxis.R, wrapR);
- return super.createSimpleClone(rVal);
- }
-
- /**
- * setWrap sets the wrap mode of this texture for a
- * particular axis.
- *
- * @param axis
- * the texture axis to define a wrapmode on.
- * @param mode
- * the wrap mode for the given axis of the texture.
- * @throws IllegalArgumentException
- * if axis or mode are null
- */
- public void setWrap(WrapAxis axis, WrapMode mode) {
- if (mode == null) {
- throw new IllegalArgumentException("mode can not be null.");
- } else if (axis == null) {
- throw new IllegalArgumentException("axis can not be null.");
- }
- switch (axis) {
- case S:
- this.wrapS = mode;
- break;
- case T:
- this.wrapT = mode;
- break;
- case R:
- this.wrapR = mode;
- break;
- }
- }
-
- /**
- * setWrap sets the wrap mode of this texture for all axis.
- *
- * @param mode
- * the wrap mode for the given axis of the texture.
- * @throws IllegalArgumentException
- * if mode is null
- */
- public void setWrap(WrapMode mode) {
- if (mode == null) {
- throw new IllegalArgumentException("mode can not be null.");
- }
- this.wrapS = mode;
- this.wrapT = mode;
- this.wrapR = mode;
- }
-
- /**
- * getWrap returns the wrap mode for a given coordinate axis
- * on this texture.
- *
- * @param axis
- * the axis to return for
- * @return the wrap mode of the texture.
- * @throws IllegalArgumentException
- * if axis is null
- */
- public WrapMode getWrap(WrapAxis axis) {
- switch (axis) {
- case S:
- return wrapS;
- case T:
- return wrapT;
- case R:
- return wrapR;
- }
- throw new IllegalArgumentException("invalid WrapAxis: " + axis);
- }
-
@Override
public Type getType() {
return Type.CubeMap;
@@ -185,10 +104,6 @@ public boolean equals(Object other) {
return false;
}
TextureCubeMap that = (TextureCubeMap) other;
- if (this.getWrap(WrapAxis.S) != that.getWrap(WrapAxis.S))
- return false;
- if (this.getWrap(WrapAxis.T) != that.getWrap(WrapAxis.T))
- return false;
if (this.getWrap(WrapAxis.R) != that.getWrap(WrapAxis.R))
return false;
return super.equals(other);
@@ -202,22 +117,4 @@ public int hashCode() {
hash = 53 * hash + (this.wrapR != null ? this.wrapR.hashCode() : 0);
return hash;
}
-
- @Override
- public void write(JmeExporter e) throws IOException {
- super.write(e);
- OutputCapsule capsule = e.getCapsule(this);
- capsule.write(wrapS, "wrapS", WrapMode.EdgeClamp);
- capsule.write(wrapT, "wrapT", WrapMode.EdgeClamp);
- capsule.write(wrapR, "wrapR", WrapMode.EdgeClamp);
- }
-
- @Override
- public void read(JmeImporter e) throws IOException {
- super.read(e);
- InputCapsule capsule = e.getCapsule(this);
- wrapS = capsule.readEnum("wrapS", WrapMode.class, WrapMode.EdgeClamp);
- wrapT = capsule.readEnum("wrapT", WrapMode.class, WrapMode.EdgeClamp);
- wrapR = capsule.readEnum("wrapR", WrapMode.class, WrapMode.EdgeClamp);
- }
}
diff --git a/jme3-core/src/main/java/com/jme3/texture/TextureDefault2D.java b/jme3-core/src/main/java/com/jme3/texture/TextureDefault2D.java
new file mode 100755
index 0000000000..a709f12aaf
--- /dev/null
+++ b/jme3-core/src/main/java/com/jme3/texture/TextureDefault2D.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2009-2012 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.texture;
+
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeImporter;
+import com.jme3.texture.image.ColorSpace;
+import java.io.IOException;
+
+/**
+ * @author Joshua Slack
+ */
+public class TextureDefault2D extends Texture2D {
+
+ /**
+ * Creates a new two-dimensional texture with default attributes.
+ */
+ public TextureDefault2D(){
+ super();
+ }
+
+ /**
+ * Creates a new two-dimensional texture using the given image.
+ * @param img The image to use.
+ */
+ public TextureDefault2D(Image img){
+ super();
+ setImage(img);
+ if (img.getData(0) == null) {
+ setMagFilter(MagFilter.Nearest);
+ setMinFilter(MinFilter.NearestNoMipMaps);
+ }
+ }
+
+ /**
+ * Creates a new two-dimensional texture for the purpose of offscreen
+ * rendering.
+ *
+ * @see com.jme3.texture.FrameBuffer
+ *
+ * @param width
+ * @param height
+ * @param format
+ */
+ public TextureDefault2D(int width, int height, Image.Format format){
+ this(new Image(format, width, height, null, ColorSpace.Linear));
+ }
+
+ /**
+ * Creates a new two-dimensional texture for the purpose of offscreen
+ * rendering.
+ *
+ * @see com.jme3.texture.FrameBuffer
+ *
+ * @param width
+ * @param height
+ * @param format
+ * @param numSamples
+ */
+ public TextureDefault2D(int width, int height, int numSamples, Image.Format format){
+ this(new Image(format, width, height, null, ColorSpace.Linear));
+ getImage().setMultiSamples(numSamples);
+ }
+
+ @Override
+ public Texture createSimpleClone() {
+ TextureDefault2D clone = new TextureDefault2D();
+ createSimpleClone(clone);
+ return clone;
+ }
+
+ @Override
+ public Type getType() {
+ return Type.TwoDimensional;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof TextureDefault2D)) {
+ return false;
+ }
+ return super.equals(other);
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = super.hashCode();
+ hash = 79 * hash + (this.wrapS != null ? this.wrapS.hashCode() : 0);
+ hash = 79 * hash + (this.wrapT != null ? this.wrapT.hashCode() : 0);
+ return hash;
+ }
+
+ @Override
+ public void read(JmeImporter e) throws IOException {
+ super.read(e);
+ InputCapsule capsule = e.getCapsule(this);
+ wrapS = capsule.readEnum("wrapS", WrapMode.class, WrapMode.EdgeClamp);
+ wrapT = capsule.readEnum("wrapT", WrapMode.class, WrapMode.EdgeClamp);
+ }
+
+}
diff --git a/jme3-core/src/main/java/com/jme3/texture/TextureDefault3D.java b/jme3-core/src/main/java/com/jme3/texture/TextureDefault3D.java
new file mode 100755
index 0000000000..29de06e091
--- /dev/null
+++ b/jme3-core/src/main/java/com/jme3/texture/TextureDefault3D.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2009-2012 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.texture;
+
+import com.jme3.export.InputCapsule;
+import com.jme3.export.JmeExporter;
+import com.jme3.export.JmeImporter;
+import com.jme3.export.OutputCapsule;
+import com.jme3.texture.image.ColorSpace;
+import java.io.IOException;
+
+/**
+ * @author Maarten Steur
+ */
+public class TextureDefault3D extends Texture3D {
+
+ /**
+ * Creates a new two-dimensional texture with default attributes.
+ */
+ public TextureDefault3D() {
+ super();
+ }
+
+ /**
+ * Creates a new three-dimensional texture using the given image.
+ * @param img The image to use.
+ */
+ public TextureDefault3D(Image img) {
+ super();
+ setImage(img);
+ if (img.getFormat().isDepthFormat()) {
+ setMagFilter(MagFilter.Nearest);
+ setMinFilter(MinFilter.NearestNoMipMaps);
+ }
+ }
+
+ /**
+ * Creates a new three-dimensional texture for the purpose of offscreen
+ * rendering.
+ *
+ * @see com.jme3.texture.FrameBuffer
+ *
+ * @param width
+ * @param height
+ * @param depth
+ * @param format
+ */
+ public TextureDefault3D(int width, int height, int depth, Image.Format format) {
+ this(new Image(format, width, height, depth, null, ColorSpace.Linear));
+ }
+
+ /**
+ * Creates a new three-dimensional texture for the purpose of offscreen
+ * rendering.
+ *
+ * @see com.jme3.texture.FrameBuffer
+ *
+ * @param width
+ * @param height
+ * @param format
+ * @param numSamples
+ */
+ public TextureDefault3D(int width, int height, int depth, int numSamples, Image.Format format) {
+ this(new Image(format, width, height, depth, null, ColorSpace.Linear));
+ getImage().setMultiSamples(numSamples);
+ }
+
+ @Override
+ public Texture createSimpleClone() {
+ return createSimpleClone(new TextureDefault3D());
+ }
+
+ @Override
+ public Type getType() {
+ return Type.ThreeDimensional;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof TextureDefault3D)) {
+ return false;
+ }
+ TextureDefault3D that = (TextureDefault3D) other;
+ if (this.getWrap(WrapAxis.R) != that.getWrap(WrapAxis.R)) {
+ return false;
+ }
+ return super.equals(other);
+ }
+
+
+}
\ No newline at end of file
diff --git a/jme3-core/src/main/java/com/jme3/texture/TextureProcessor.java b/jme3-core/src/main/java/com/jme3/texture/TextureProcessor.java
old mode 100644
new mode 100755
index 78107836ef..31804c93d3
--- a/jme3-core/src/main/java/com/jme3/texture/TextureProcessor.java
+++ b/jme3-core/src/main/java/com/jme3/texture/TextureProcessor.java
@@ -56,9 +56,9 @@ public Object postProcess(AssetKey key, Object obj) {
}
tex = new TextureCubeMap();
} else if (texKey.getTextureTypeHint() == Texture.Type.ThreeDimensional) {
- tex = new Texture3D();
+ tex = new TextureDefault3D();
} else {
- tex = new Texture2D();
+ tex = new TextureDefault2D();
}
// enable mipmaps if image has them
diff --git a/jme3-core/src/main/java/com/jme3/texture/image/DefaultImageRaster.java b/jme3-core/src/main/java/com/jme3/texture/image/DefaultImageRaster.java
old mode 100644
new mode 100755
index 2d70d53d72..0d5cb7bfcf
--- a/jme3-core/src/main/java/com/jme3/texture/image/DefaultImageRaster.java
+++ b/jme3-core/src/main/java/com/jme3/texture/image/DefaultImageRaster.java
@@ -34,14 +34,15 @@
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.texture.Image;
+
import java.nio.ByteBuffer;
public class DefaultImageRaster extends ImageRaster {
-
- private final int[] components = new int[4];
+
+ protected final int[] components = new int[4];
private ByteBuffer buffer;
- private final Image image;
- private final ImageCodec codec;
+ protected final Image image;
+ protected final ImageCodec codec;
private final int width;
private final int height;
private final int offset;
@@ -49,13 +50,47 @@ public class DefaultImageRaster extends ImageRaster {
private final boolean convertToLinear;
private int slice;
- private void rangeCheck(int x, int y) {
+
+
+ protected void rangeCheck(int x, int y) {
if (x < 0 || y < 0 || x >= width || y >= height) {
throw new IllegalArgumentException("x and y must be inside the image dimensions:"
+ x + ", " + y + " in:" + width + ", " + height);
}
}
-
+
+ /**
+ * Create new image reader / writer.
+ *
+ * @param image The image to read / write to.
+ * @param slice Which slice to use. Only applies to 3D images, 2D image
+ * arrays or cubemaps.
+ * @param mipMapLevel The mipmap level to read / write to. To access levels
+ * other than 0, the image must have
+ * {@link Image#setMipMapSizes(int[]) mipmap sizes} set.
+ * @param convertToLinear If true, the application expects read or written
+ * colors to be in linear color space (ImageRaster will
+ * automatically perform a conversion as needed). If false, the application expects
+ * colors to be in the image's native {@link Image#getColorSpace() color space}.
+ * @return An ImageRaster to read / write to the image.
+ */
+ public static DefaultImageRaster create(Image image, int slice, int mipMapLevel, boolean convertToLinear) {
+ return new DefaultImageRaster(image, slice, mipMapLevel, convertToLinear);
+ }
+
+ /**
+ * Create new image reader / writer for 2D images.
+ *
+ * @param image The image to read / write to.
+ * @return An ImageRaster to read / write to the image.
+ */
+ public static DefaultImageRaster create(Image image) {
+ if (image.getData().size() > 1) {
+ throw new IllegalStateException("Use constructor that takes slices argument to read from multislice image");
+ }
+ return new DefaultImageRaster(image, 0, 0, false);
+ }
+
public DefaultImageRaster(Image image, int slice, int mipMapLevel, boolean convertToLinear) {
int[] mipMapSizes = image.getMipMapSizes();
int availableMips = mipMapSizes != null ? mipMapSizes.length : 1;
@@ -115,42 +150,32 @@ public int getHeight() {
@Override
public void setPixel(int x, int y, ColorRGBA color) {
rangeCheck(x, y);
-
+ getSRGB(color);
+ grayscaleCheck(color, codec);
+ setComponents(color, codec, components);
+ writeComponents(x, y);
+ setImageUpdateNeeded(image);
+ }
+
+ /**
+ * Input is linear, needs to be converted to sRGB before writing into image.
+ * @param color
+ */
+
+ protected void getSRGB(ColorRGBA color) {
if (convertToLinear) {
- // Input is linear, needs to be converted to sRGB before writing
- // into image.
color = color.getAsSrgb();
}
-
- // Check flags for grayscale
- if (codec.isGray) {
- float gray = color.r * 0.27f + color.g * 0.67f + color.b * 0.06f;
- color = new ColorRGBA(gray, gray, gray, color.a);
- }
+ }
- switch (codec.type) {
- case ImageCodec.FLAG_F16:
- components[0] = (int) FastMath.convertFloatToHalf(color.a);
- components[1] = (int) FastMath.convertFloatToHalf(color.r);
- components[2] = (int) FastMath.convertFloatToHalf(color.g);
- components[3] = (int) FastMath.convertFloatToHalf(color.b);
- break;
- case ImageCodec.FLAG_F32:
- components[0] = (int) Float.floatToIntBits(color.a);
- components[1] = (int) Float.floatToIntBits(color.r);
- components[2] = (int) Float.floatToIntBits(color.g);
- components[3] = (int) Float.floatToIntBits(color.b);
- break;
- case 0:
- // Convert color to bits by multiplying by size
- components[0] = Math.min( (int) (color.a * codec.maxAlpha + 0.5f), codec.maxAlpha);
- components[1] = Math.min( (int) (color.r * codec.maxRed + 0.5f), codec.maxRed);
- components[2] = Math.min( (int) (color.g * codec.maxGreen + 0.5f), codec.maxGreen);
- components[3] = Math.min( (int) (color.b * codec.maxBlue + 0.5f), codec.maxBlue);
- break;
- }
+
+ protected void writeComponents(int x, int y) {
codec.writeComponents(getBuffer(), x, y, width, offset, components, temp);
- image.setUpdateNeeded();
+ }
+
+
+ protected void readComponents(int x, int y) {
+ codec.readComponents(getBuffer(), x, y, width, offset, components, temp);
}
private ByteBuffer getBuffer(){
@@ -163,54 +188,21 @@ private ByteBuffer getBuffer(){
@Override
public ColorRGBA getPixel(int x, int y, ColorRGBA store) {
rangeCheck(x, y);
-
- codec.readComponents(getBuffer(), x, y, width, offset, components, temp);
+ readComponents(x, y);
if (store == null) {
store = new ColorRGBA();
}
- switch (codec.type) {
- case ImageCodec.FLAG_F16:
- store.set(FastMath.convertHalfToFloat((short)components[1]),
- FastMath.convertHalfToFloat((short)components[2]),
- FastMath.convertHalfToFloat((short)components[3]),
- FastMath.convertHalfToFloat((short)components[0]));
- break;
- case ImageCodec.FLAG_F32:
- store.set(Float.intBitsToFloat((int)components[1]),
- Float.intBitsToFloat((int)components[2]),
- Float.intBitsToFloat((int)components[3]),
- Float.intBitsToFloat((int)components[0]));
- break;
- case 0:
- // Convert to float and divide by bitsize to get into range 0.0 - 1.0.
- store.set((float)components[1] / codec.maxRed,
- (float)components[2] / codec.maxGreen,
- (float)components[3] / codec.maxBlue,
- (float)components[0] / codec.maxAlpha);
- break;
- }
- if (codec.isGray) {
- store.g = store.b = store.r;
- } else {
- if (codec.maxRed == 0) {
- store.r = 1;
- }
- if (codec.maxGreen == 0) {
- store.g = 1;
- }
- if (codec.maxBlue == 0) {
- store.b = 1;
- }
- if (codec.maxAlpha == 0) {
- store.a = 1;
- }
- }
+ setStoreComponents(store, codec, components);
+ setStoreRGBA(store, codec);
+ setSRGB(store);
+ return store;
+ }
+
+ protected void setSRGB(ColorRGBA store) {
if (convertToLinear) {
// Input image is sRGB, need to convert to linear.
store.setAsSrgb(store.r, store.g, store.b, store.a);
}
-
- return store;
}
}
diff --git a/jme3-core/src/main/java/com/jme3/texture/image/ImageRaster.java b/jme3-core/src/main/java/com/jme3/texture/image/ImageRaster.java
old mode 100644
new mode 100755
index 92bbb33158..baba90ca72
--- a/jme3-core/src/main/java/com/jme3/texture/image/ImageRaster.java
+++ b/jme3-core/src/main/java/com/jme3/texture/image/ImageRaster.java
@@ -32,6 +32,7 @@
package com.jme3.texture.image;
import com.jme3.math.ColorRGBA;
+import com.jme3.math.FastMath;
import com.jme3.system.JmeSystem;
import com.jme3.texture.Image;
@@ -65,49 +66,6 @@
*/
public abstract class ImageRaster {
- /**
- * Create new image reader / writer.
- *
- * @param image The image to read / write to.
- * @param slice Which slice to use. Only applies to 3D images, 2D image
- * arrays or cubemaps.
- * @param mipMapLevel The mipmap level to read / write to. To access levels
- * other than 0, the image must have
- * {@link Image#setMipMapSizes(int[]) mipmap sizes} set.
- * @param convertToLinear If true, the application expects read or written
- * colors to be in linear color space (ImageRaster will
- * automatically perform a conversion as needed). If false, the application expects
- * colors to be in the image's native {@link Image#getColorSpace() color space}.
- * @return An ImageRaster to read / write to the image.
- */
- public static ImageRaster create(Image image, int slice, int mipMapLevel, boolean convertToLinear) {
- return new DefaultImageRaster(image, slice, mipMapLevel, convertToLinear);
- }
-
- /**
- * Create new image reader / writer.
- *
- * @param image The image to read / write to.
- * @param slice Which slice to use. Only applies to 3D images, 2D image
- * arrays or cubemaps.
- * @return An ImageRaster to read / write to the image.
- */
- public static ImageRaster create(Image image, int slice) {
- return create(image, slice, 0, false);
- }
-
- /**
- * Create new image reader / writer for 2D images.
- *
- * @param image The image to read / write to.
- * @return An ImageRaster to read / write to the image.
- */
- public static ImageRaster create(Image image) {
- if (image.getData().size() > 1) {
- throw new IllegalStateException("Use constructor that takes slices argument to read from multislice image");
- }
- return create(image, 0, 0, false);
- }
public ImageRaster() {
}
@@ -201,4 +159,87 @@ public ImageRaster() {
public ColorRGBA getPixel(int x, int y) {
return getPixel(x, y, null);
}
+
+ /**
+ * Check flags for grayscale
+ * @param color
+ */
+ protected void grayscaleCheck(ColorRGBA color, ImageCodec codec) {
+ if (codec.isGray) {
+ float gray = color.r * 0.27f + color.g * 0.67f + color.b * 0.06f;
+ color = new ColorRGBA(gray, gray, gray, color.a);
+ }
+ }
+
+ protected void setComponents(ColorRGBA color, ImageCodec codec, int[] components) {
+ switch (codec.type) {
+ case ImageCodec.FLAG_F16:
+ components[0] = (int) FastMath.convertFloatToHalf(color.a);
+ components[1] = (int) FastMath.convertFloatToHalf(color.r);
+ components[2] = (int) FastMath.convertFloatToHalf(color.g);
+ components[3] = (int) FastMath.convertFloatToHalf(color.b);
+ break;
+ case ImageCodec.FLAG_F32:
+ components[0] = (int) Float.floatToIntBits(color.a);
+ components[1] = (int) Float.floatToIntBits(color.r);
+ components[2] = (int) Float.floatToIntBits(color.g);
+ components[3] = (int) Float.floatToIntBits(color.b);
+ break;
+ case 0:
+ // Convert color to bits by multiplying by size
+ components[0] = Math.min((int) (color.a * codec.maxAlpha + 0.5f), codec.maxAlpha);
+ components[1] = Math.min((int) (color.r * codec.maxRed + 0.5f), codec.maxRed);
+ components[2] = Math.min((int) (color.g * codec.maxGreen + 0.5f), codec.maxGreen);
+ components[3] = Math.min((int) (color.b * codec.maxBlue + 0.5f), codec.maxBlue);
+ break;
+ }
+ }
+
+ protected void setImageUpdateNeeded(Image image) {
+ image.setUpdateNeeded();
+ }
+
+ protected void setStoreComponents(ColorRGBA store, ImageCodec codec, int[] components) {
+ switch (codec.type) {
+ case ImageCodec.FLAG_F16:
+ store.set(FastMath.convertHalfToFloat((short)components[1]),
+ FastMath.convertHalfToFloat((short)components[2]),
+ FastMath.convertHalfToFloat((short)components[3]),
+ FastMath.convertHalfToFloat((short)components[0]));
+ break;
+ case ImageCodec.FLAG_F32:
+ store.set(Float.intBitsToFloat((int)components[1]),
+ Float.intBitsToFloat((int)components[2]),
+ Float.intBitsToFloat((int)components[3]),
+ Float.intBitsToFloat((int)components[0]));
+ break;
+ case 0:
+ // Convert to float and divide by bitsize to get into range 0.0 - 1.0.
+ store.set((float)components[1] / codec.maxRed,
+ (float)components[2] / codec.maxGreen,
+ (float)components[3] / codec.maxBlue,
+ (float)components[0] / codec.maxAlpha);
+ break;
+ }
+ }
+
+ protected void setStoreRGBA(ColorRGBA store, ImageCodec codec) {
+ if (codec.isGray) {
+ store.g = store.b = store.r;
+ } else {
+ if (codec.maxRed == 0) {
+ store.r = 1;
+ }
+ if (codec.maxGreen == 0) {
+ store.g = 1;
+ }
+ if (codec.maxBlue == 0) {
+ store.b = 1;
+ }
+ if (codec.maxAlpha == 0) {
+ store.a = 1;
+ }
+ }
+ }
+
}
diff --git a/jme3-core/src/main/java/com/jme3/texture/image/MipMapImageRaster.java b/jme3-core/src/main/java/com/jme3/texture/image/MipMapImageRaster.java
old mode 100644
new mode 100755
index 84ea1ea242..897cdd7931
--- a/jme3-core/src/main/java/com/jme3/texture/image/MipMapImageRaster.java
+++ b/jme3-core/src/main/java/com/jme3/texture/image/MipMapImageRaster.java
@@ -34,14 +34,15 @@
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.texture.Image;
+
import java.nio.ByteBuffer;
public class MipMapImageRaster extends ImageRaster {
- private final int[] components = new int[4];
+ protected final int[] components = new int[4];
private ByteBuffer buffer;
- private final Image image;
- private final ImageCodec codec;
+ protected final Image image;
+ protected final ImageCodec codec;
private int width[];
private int height[];
private final byte[] temp;
@@ -49,7 +50,7 @@ public class MipMapImageRaster extends ImageRaster {
private int mipLevel;
private int[] offsets;
- private void rangeCheck(int x, int y) {
+ protected void rangeCheck(int x, int y) {
if (x < 0 || y < 0 || x >= width[mipLevel] || y >= height[mipLevel]) {
throw new IllegalArgumentException("x and y must be inside the image dimensions");
}
@@ -99,36 +100,18 @@ public void setMipLevel(int mipLevel) {
@Override
public void setPixel(int x, int y, ColorRGBA color) {
rangeCheck(x, y);
+ grayscaleCheck(color, codec);
+ setComponents(color, codec, components);
+ writeComponents(x, y);
+ setImageUpdateNeeded(image);
+ }
- // Check flags for grayscale
- if (codec.isGray) {
- float gray = color.r * 0.27f + color.g * 0.67f + color.b * 0.06f;
- color = new ColorRGBA(gray, gray, gray, color.a);
- }
-
- switch (codec.type) {
- case ImageCodec.FLAG_F16:
- components[0] = (int) FastMath.convertFloatToHalf(color.a);
- components[1] = (int) FastMath.convertFloatToHalf(color.r);
- components[2] = (int) FastMath.convertFloatToHalf(color.g);
- components[3] = (int) FastMath.convertFloatToHalf(color.b);
- break;
- case ImageCodec.FLAG_F32:
- components[0] = (int) Float.floatToIntBits(color.a);
- components[1] = (int) Float.floatToIntBits(color.r);
- components[2] = (int) Float.floatToIntBits(color.g);
- components[3] = (int) Float.floatToIntBits(color.b);
- break;
- case 0:
- // Convert color to bits by multiplying by size
- components[0] = Math.min((int) (color.a * codec.maxAlpha + 0.5f), codec.maxAlpha);
- components[1] = Math.min((int) (color.r * codec.maxRed + 0.5f), codec.maxRed);
- components[2] = Math.min((int) (color.g * codec.maxGreen + 0.5f), codec.maxGreen);
- components[3] = Math.min((int) (color.b * codec.maxBlue + 0.5f), codec.maxBlue);
- break;
- }
+ protected void writeComponents(int x, int y) {
codec.writeComponents(getBuffer(), x, y, width[mipLevel], offsets[mipLevel], components, temp);
- image.setUpdateNeeded();
+ }
+
+ protected void readComponents(int x, int y) {
+ codec.readComponents(getBuffer(), x, y, width[mipLevel], offsets[mipLevel], components, temp);
}
private ByteBuffer getBuffer() {
@@ -141,48 +124,12 @@ private ByteBuffer getBuffer() {
@Override
public ColorRGBA getPixel(int x, int y, ColorRGBA store) {
rangeCheck(x, y);
-
- codec.readComponents(getBuffer(), x, y, width[mipLevel], offsets[mipLevel], components, temp);
+ readComponents(x, y);
if (store == null) {
store = new ColorRGBA();
}
- switch (codec.type) {
- case ImageCodec.FLAG_F16:
- store.set(FastMath.convertHalfToFloat((short) components[1]),
- FastMath.convertHalfToFloat((short) components[2]),
- FastMath.convertHalfToFloat((short) components[3]),
- FastMath.convertHalfToFloat((short) components[0]));
- break;
- case ImageCodec.FLAG_F32:
- store.set(Float.intBitsToFloat((int) components[1]),
- Float.intBitsToFloat((int) components[2]),
- Float.intBitsToFloat((int) components[3]),
- Float.intBitsToFloat((int) components[0]));
- break;
- case 0:
- // Convert to float and divide by bitsize to get into range 0.0 - 1.0.
- store.set((float) components[1] / codec.maxRed,
- (float) components[2] / codec.maxGreen,
- (float) components[3] / codec.maxBlue,
- (float) components[0] / codec.maxAlpha);
- break;
- }
- if (codec.isGray) {
- store.g = store.b = store.r;
- } else {
- if (codec.maxRed == 0) {
- store.r = 1;
- }
- if (codec.maxGreen == 0) {
- store.g = 1;
- }
- if (codec.maxBlue == 0) {
- store.b = 1;
- }
- if (codec.maxAlpha == 0) {
- store.a = 1;
- }
- }
+ setStoreComponents(store, codec, components);
+ setStoreRGBA(store, codec);
return store;
}
diff --git a/jme3-core/src/main/java/com/jme3/ui/Picture.java b/jme3-core/src/main/java/com/jme3/ui/Picture.java
old mode 100644
new mode 100755
index ad7bc87999..73be08f73f
--- a/jme3-core/src/main/java/com/jme3/ui/Picture.java
+++ b/jme3-core/src/main/java/com/jme3/ui/Picture.java
@@ -40,7 +40,7 @@
import com.jme3.renderer.queue.RenderQueue.Bucket;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Quad;
-import com.jme3.texture.Texture2D;
+import com.jme3.texture.TextureDefault2D;
/**
* A Picture represents a 2D image drawn on the screen.
@@ -133,7 +133,7 @@ public void setPosition(float x, float y){
*/
public void setImage(AssetManager assetManager, String imgName, boolean useAlpha){
TextureKey key = new TextureKey(imgName, true);
- Texture2D tex = (Texture2D) assetManager.loadTexture(key);
+ TextureDefault2D tex = (TextureDefault2D) assetManager.loadTexture(key);
setTexture(assetManager, tex, useAlpha);
}
@@ -146,7 +146,7 @@ public void setImage(AssetManager assetManager, String imgName, boolean useAlpha
* objects behind it to appear through. If false, the transparent
* portions will be the image's color at that pixel.
*/
- public void setTexture(AssetManager assetManager, Texture2D tex, boolean useAlpha){
+ public void setTexture(AssetManager assetManager, TextureDefault2D tex, boolean useAlpha){
if (getMaterial() == null){
Material mat = new Material(assetManager, "Common/MatDefs/Gui/Gui.j3md");
mat.setColor("Color", ColorRGBA.White);
diff --git a/jme3-core/src/main/java/com/jme3/util/MipMapGenerator.java b/jme3-core/src/main/java/com/jme3/util/MipMapGenerator.java
index 3ac6a7ecdd..c10adeab5e 100644
--- a/jme3-core/src/main/java/com/jme3/util/MipMapGenerator.java
+++ b/jme3-core/src/main/java/com/jme3/util/MipMapGenerator.java
@@ -35,6 +35,7 @@
import com.jme3.math.FastMath;
import com.jme3.texture.Image;
import com.jme3.texture.Image.Format;
+import com.jme3.texture.image.DefaultImageRaster;
import com.jme3.texture.image.ImageRaster;
import java.nio.ByteBuffer;
import java.util.ArrayList;
@@ -52,9 +53,9 @@ public static Image scaleImage(Image inputImage, int outputWidth, int outputHeig
outputHeight,
buffer,
inputImage.getColorSpace());
-
- ImageRaster input = ImageRaster.create(inputImage, 0, 0, false);
- ImageRaster output = ImageRaster.create(outputImage, 0, 0, false);
+
+ ImageRaster input = DefaultImageRaster.create(inputImage, 0, 0, false);
+ ImageRaster output = DefaultImageRaster.create(outputImage, 0, 0, false);
float xRatio = ((float)(input.getWidth() - 1)) / output.getWidth();
float yRatio = ((float)(input.getHeight() - 1)) / output.getHeight();
diff --git a/jme3-core/src/main/java/com/jme3/util/SkyFactory.java b/jme3-core/src/main/java/com/jme3/util/SkyFactory.java
old mode 100644
new mode 100755
index 730ee3b11a..da96a4412c
--- a/jme3-core/src/main/java/com/jme3/util/SkyFactory.java
+++ b/jme3-core/src/main/java/com/jme3/util/SkyFactory.java
@@ -67,7 +67,7 @@ public enum EnvMapType{
*/
CubeMap,
/**
- * The env map is a Sphere map. The texture is a Texture2D with the pixels arranged for
+ * The env map is a Sphere map. The texture is a TextureDefault2D with the pixels arranged for
* sphere
* mapping.
*/
@@ -94,11 +94,11 @@ public enum EnvMapType{
* transformation to the normal.
* @param sphereMap determines how the texture is used:
*
- *
true: The texture is a Texture2D with the pixels arranged for
+ *
true: The texture is a TextureDefault2D with the pixels arranged for
* sphere
* mapping.
- *
false: The texture is either a TextureCubeMap or Texture2D. If it is
- * a Texture2D then the image is taken from it and is inserted into a
+ *
false: The texture is either a TextureCubeMap or TextureDefault2D. If it is
+ * a TextureDefault2D then the image is taken from it and is inserted into a
* TextureCubeMap
*
* @return a new spatial representing the sky, ready to be attached to the
@@ -140,11 +140,11 @@ public static Spatial createSky(AssetManager assetManager, Texture texture,
* transformation to the normal.
* @param sphereMap determines how the texture is used:
*
- *
true: The texture is a Texture2D with the pixels arranged for
+ *
true: The texture is a TextureDefault2D with the pixels arranged for
* sphere
* mapping.
- *
false: The texture is either a TextureCubeMap or Texture2D. If it is
- * a Texture2D then the image is taken from it and is inserted into a
+ *
false: The texture is either a TextureCubeMap or TextureDefault2D. If it is
+ * a TextureDefault2D then the image is taken from it and is inserted into a
* TextureCubeMap
*
* @param sphereRadius the sky sphere's radius: for the sky to be visible,
@@ -222,11 +222,11 @@ public static Spatial createSky(AssetManager assetManager, Texture texture,
* @param texture to use *
* @param sphereMap determines how the texture is used:
*
- *
true: The texture is a Texture2D with the pixels arranged for
+ *
true: The texture is a TextureDefault2D with the pixels arranged for
* sphere
* mapping.
- *
false: The texture is either a TextureCubeMap or Texture2D. If it is
- * a Texture2D then the image is taken from it and is inserted into a
+ *
false: The texture is either a TextureCubeMap or TextureDefault2D. If it is
+ * a TextureDefault2D then the image is taken from it and is inserted into a
* TextureCubeMap
*
* @return a new spatial representing the sky, ready to be attached to the
@@ -245,11 +245,11 @@ public static Spatial createSky(AssetManager assetManager, Texture texture, bool
* @param textureName the path to the texture asset to use
* @param sphereMap determines how the texture is used:
*
- *
true: The texture is a Texture2D with the pixels arranged for
+ *
true: The texture is a TextureDefault2D with the pixels arranged for
* sphere
* mapping.
- *
false: The texture is either a TextureCubeMap or Texture2D. If it is
- * a Texture2D then the image is taken from it and is inserted into a
+ *
false: The texture is either a TextureCubeMap or TextureDefault2D. If it is
+ * a TextureDefault2D then the image is taken from it and is inserted into a
* TextureCubeMap
+In the Material Definitions article you learned how to configure Materials programmatically in Java code. If you have certain commonly used Materials that never change, you can clean up the amount of Java code that clutters your init method, by moving material settings into .j3m files. Then later in your code, you only need to call one setter instead of several to apply the material.
+
+
+
+If you want to colorize simple shapes (one texture all around), then .j3m are the most easily customizable solution. J3m files can contain texture mapped materials, but as usual you have to create the textures in an external editor, especially if you use UV-mapped textures.
+
+
+
+
+
Writing the .j3m File
+
+
+
For every Material, create a file and give it a name that describes it: e.g. SimpleBump.j3m
+
+
Place the file in your project's assets/Materials/ directory, e.g. MyGame/src/assets/Materials/SimpleBump.j3m
+
+
Edit the file and add content using the following Syntax, e.g.:
shiny bumpy rock is a descriptive string that you can make up. Choose a name to help you remember for what you intend to use this material.
+
+
After the colon, specify on which Material definition you base this Material.
+
+
+
+
Now look up the choosen Material Definition's parameters and their parameter types from the Material table. Add one line for each parameter.
+
+
For example: The series of four numbers in the example above represent RGBA color values.
+
+
+
+
Check the detailed syntax reference below if you are unsure.
+
+
+
+
+
In the jMonkeyEngine SDK, use File→New File→Material→Empty Material File to create .j3m files. You can edit .j3m files directly in the SDK. On the other hand, they are plain text files, so you can also create them in any plain text editor.
+
+
+
+
+
+
How to Use .j3m Materials
+
+
+
+This is how you use the prepared .j3m Material on a Spatial. Since you have saved the .j3m file to your project's Assets directory, the .j3m path is relative to MyGame/src/assets/….
+
+Tip: In the jMonkeyEngine SDK, open Windows>Palette and drag the JME Material: Set J3M snippet into your code.
+
+
+
+
+
Syntax Reference for .j3m Files
+
+
+
+
+
Paths
+
+
+
+Make sure to get the paths to the textures (.png, .jpg) and material definitions (.j3md) right.
+
+
+
The paths to the built-in .j3md files are relative to jME3's Core Data directory. Just copy the path stated in the Material table.
+Common/MatDefs/Misc/Unshaded.j3md is resolved to jme3/src/src/core-data/Common/MatDefs/Misc/Unshaded.j3md.
+
+
The paths to your textures are relative to your project's assets directory.
+Textures/bump_rock_normal.png is resolved to MyGame/src/assets/Textures/bump_rock_normal.png
+
+
+
+
+
+
Data Types
+
+
+
+All data types (except Color) are specified in com.jme3.shader.VarType.
+“Color” is specified as Vector4 in J3MLoader.java.
+
+
+
+
+
Name
jME Java class
.j3m file syntax
+
+
+
+
Float
(basic Java type)
a float (e.g. 0.72) , no comma or parentheses
+
+
+
Vector2
com.jme3.math.Vector2f
Two floats, no comma or parentheses
+
+
+
Vector3
com.jme3.math.Vector3f
Three floats, no comma or parentheses
+
+
+
Vector4
com.jme3.math.Vector4f
Four floats, no comma or parentheses
+
+
+
Texture2D
com.jme3.texture.TextureDefault2D
Path to texture in assets directory, no quotation marks
+
+
+
Texture3D
com.jme3.texture.TextureDefault3D
Same as texture 2D except it is interpreted as a 3D texture
+
+
+
TextureCubeMap
com.jme3.texture.TextureCubeMap
Same as texture 2D except it is interpreted as a cubemap texture
+
+
+
Boolean
(basic Java type)
true or false
+
+
+
Int
(basic Java type)
Integer number, no comma or parentheses
+
+
+
Color
com.jme3.math.ColorRGBA
Four floats, no comma or parentheses
+
+
+
FloatArray
(Currently not supported in J3M)
+
+
+
Vector2Array
(Currently not supported in J3M)
+
+
+
Vector3Array
(Currently not supported in J3M)
+
+
+
Vector4Array
(Currently not supported in J3M)
+
+
+
Matrix3
(Currently not supported in J3M)
+
+
+
Matrix4
(Currently not supported in J3M)
+
+
+
Matrix3Array
(Currently not supported in J3M)
+
+
+
Matrix4Array
(Currently not supported in J3M)
+
+
+
TextureBuffer
(Currently not supported in J3M)
+
+
+
TextureArray
(Currently not supported in J3M)
+
+
+
+
+
+
Flip and Repeat Syntax
+
+
+
A texture can be flipped using the following syntax NormalMap: Flip Textures/bump_rock_normal.png
+
+
A texture can be set to repeat using the following syntax NormalMap: Repeat Textures/bump_rock_normal.png
+
+
If a texture is set to both being flipped and repeated, Flip must come before Repeat
+
+
+
+
+
+
Syntax for Additional Render States
+
+
+
A Boolean can be “On” or “Off”
+
+
Float is “123.0” etc
+
+
Enum - values depend on the enum
+
+
+
+
+See the javadoc for a detailed explanation of render states.
+
+
+
+
+
Name
Type
Purpose
+
+
+
+
(Boolean)
Enable wireframe rendering mode
+
+
+
(Enum: FaceCullMode)
Set face culling mode (Off, Front, Back, FrontAndBack)
+
+
+
(Boolean)
Enable writing depth to the depth buffer
+
+
+
(Boolean)
Enable depth testing
+
+
+
(Enum: BlendMode)
Set the blending mode
+
+
+
(Float)
Set the alpha testing alpha falloff value (if set, it will enable alpha testing)
+
+
+
(Float, Float)
Set the polygon offset factor and units
+
+
+
(Boolean)
Enable color writing
+
+
+
(Boolean)
Enable point sprite rendering for point meshes
+
+
+
+
+
+
Examples
+
+
+
+
+
Example 1: Shiny
+
+
Spatial signpost = (Spatial) assetManager.loadAsset(
+ new OgreMeshKey("Models/Sign Post/Sign Post.mesh.xml", null));
+signpost.setMaterial( assetManager.loadMaterial(
+ new AssetKey("Models/Sign Post/Sign Post.j3m")));
+TangentBinormalGenerator.generate(signpost);
+rootNode.attachChild(signpost);