diff --git a/.gitignore b/.gitignore index 09d505187..606f718e9 100644 --- a/.gitignore +++ b/.gitignore @@ -4,12 +4,14 @@ /dist/ /build/ /netbeans/ +/sdk/jdks/local/ /jme3-core/build/ -/jme3-core/src/main/java/com/jme3/system/JmeVersion.java +/jme3-core/src/main/resources/com/jme3/system/version.properties /jme3-plugins/build/ /jme3-desktop/build/ /jme3-android-native/build/ /jme3-android/build/ +/jme3-android-examples/build/ /jme3-blender/build/ /jme3-effects/build/ /jme3-bullet/build/ @@ -79,6 +81,7 @@ /sdk/jme3-vehicle-creator/build/ /sdk/jme3-welcome-screen/build/ /sdk/jme3-glsl-support/build/ +/sdk/jme3-dark-laf/build/ /sdk/nbproject/private/ /sdk/jme3-scenecomposer/nbproject/private/ /sdk/jme3-core/nbproject/private/ @@ -131,3 +134,13 @@ !/jme3-bullet-native/libs/native/osx/x86_64/libbulletjme.dylib !/jme3-bullet-native/libs/native/linux/x86/libbulletjme.so !/jme3-bullet-native/libs/native/linux/x86_64/libbulletjme.so +/.nb-gradle/ +/sdk/ant-jme/nbproject/private/ +/sdk/nbi/stub/ext/engine/nbproject/private/ +/sdk/nbi/stub/ext/components/products/jdk/nbproject/private/ +/sdk/nbi/stub/ext/components/products/blender/nbproject/private/ +/sdk/nbi/stub/ext/components/products/helloworld/nbproject/private/ +/sdk/BasicGameTemplate/nbproject/private/ +/sdk/nbi/stub/ext/components/products/jdk/build/ +/sdk/nbi/stub/ext/components/products/jdk/dist/ +/sdk/jme3-dark-laf/nbproject/private/ diff --git a/.travis.yml b/.travis.yml index 2e93aa23c..eb7e58253 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,15 +8,45 @@ cache: - gradle-cache - netbeans -branches: - only: - - master +# branches: +# only: +# - master notifications: slack: - secure: "PWEk4+VL986c3gAjWp12nqyifvxCjBqKoESG9d7zWh1uiTLadTHhZJRMdsye36FCpz/c/Jt7zCRO/5y7FaubQptnRrkrRfjp5f99MJRzQVXnUAM+y385qVkXKRKd/PLpM7XPm4AvjvxHCyvzX2wamRvul/TekaXKB9Ti5FCN87s=" + on_success: change + on_failure: always + rooms: + secure: "PWEk4+VL986c3gAjWp12nqyifvxCjBqKoESG9d7zWh1uiTLadTHhZJRMdsye36FCpz/c/Jt7zCRO/5y7FaubQptnRrkrRfjp5f99MJRzQVXnUAM+y385qVkXKRKd/PLpM7XPm4AvjvxHCyvzX2wamRvul/TekaXKB9Ti5FCN87s=" + +install: + - ./gradlew assemble + +script: + - ./gradlew check + - ./gradlew createZipDistribution + - "[ $TRAVIS_BRANCH == 'master' ] && [ $TRAVIS_PULL_REQUEST == 'false' ] && ./gradlew uploadArchives || :" + +before_deploy: + - export RELEASE_DIST=$(ls build/distributions/*.zip) + +deploy: + provider: releases + api_key: + secure: PuEsJd6juXBH29ByITW3ntSAyrwWs0IeFvXJ5Y2YlhojhSMtTwkoWeB6YmDJWP4fhzbajk4TQ1HlOX2IxJXSW/8ShOEIUlGXz9fHiST0dkSM+iRAUgC5enCLW5ITPTiem7eY9ZhS9miIam7ngce9jHNMh75PTzZrEJtezoALT9w= + file_glob: true + file: "${RELEASE_DIST}" + skip_cleanup: true + on: + repo: jMonkeyEngine/jmonkeyengine + tags: true before_install: + - git fetch --unshallow + - openssl aes-256-cbc -K $encrypted_a1949b55824a_key -iv $encrypted_a1949b55824a_iv + -in private/www-updater.key.enc -out private/www-updater.key -d + +# before_install: # required libs for android build tools # sudo apt-get update # sudo apt-get install -qq p7zip-full diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ebecab28b..82ffeb4e8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,13 +16,6 @@ When you're ready to submit your code, just make a [pull request](https://help.g - When committing, always be sure to run an update before you commit. If there is a conflict between the latest revision and your patch after the update, then it is your responsibility to track down the update that caused the conflict and determine the issue (and fix it). In the case where the breaking commit has no thread linked (and one cannot be found in the forum), then the contributor should contact an administrator and wait for feedback before committing. - If your code is committed and it introduces new functionality, please edit the wiki accordingly. We can easily roll back to previous revisions, so just do your best; point us to it and we’ll see if it sticks! -**Note to Eclipse users:** The Eclipse [git client does not support https](http://hub.jmonkeyengine.org/forum/topic/problem-cloning-the-new-git-repository/#post-265594). The current workaround is to use the command line to clone the repository. -To import the local repository as a project follow these steps: - -1. Add a line 'apply plugin: eclipse' to your common.gradle file in the main project directory. -2. Navigate to the project directory in command line and execute command 'gradle eclipse'. This will load all the dependancies for eclipse. -3. In Eclipse, add the repository as an existing Java Project. - p.s. We will try hold ourselves to a [certain standard](http://www.defmacro.org/2013/04/03/issue-etiquette.html) when it comes to GitHub etiquette. If at any point we fail to uphold this standard, let us know. #### Core Contributors diff --git a/README.md b/README.md index b3f993569..29161ffa4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ -jMonkeyEngine +jMonkeyEngine ============= +[![Build Status](https://travis-ci.org/jMonkeyEngine/jmonkeyengine.svg?branch=master)](https://travis-ci.org/jMonkeyEngine/jmonkeyengine) + jMonkeyEngine is a 3D game engine for adventurous Java developers. It’s open source, cross platform and cutting edge. And it is all beautifully documented. The 3.0 branch is the latest stable version of the jMonkeyEngine 3 SDK, a complete game development suite. We'll be frequently submitting stable 3.0.x updates until the major 3.1 version arrives. The engine is used by several commercial game studios and computer-science courses. Here's a taste: diff --git a/build.gradle b/build.gradle index adb31217b..192bc32d3 100644 --- a/build.gradle +++ b/build.gradle @@ -1,14 +1,25 @@ import org.gradle.api.artifacts.* -apply plugin: 'base' // To add "clean" task to the root project. -//apply plugin: 'java-library-distribution' +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath 'com.android.tools.build:gradle:1.1.0' + } +} + +apply plugin: 'base' +apply from: file('version.gradle') +apply from: file('upload.gradle') // This is applied to all sub projects subprojects { - // Don't add to native builds - // if(!project.name.endsWith('native')){ - apply from: rootProject.file('common.gradle') - // } + if(!project.name.equals('jme3-android-examples')) { + apply from: rootProject.file('common.gradle') + } else { + apply from: rootProject.file('common-android-app.gradle') + } } task run(dependsOn: ':jme3-examples:run') { @@ -49,15 +60,14 @@ task libDist(dependsOn: subprojects.build) << { } } -task createZipDistribution(type:Zip,dependsOn:["dist","libDist"], description:"Package the nightly zip distribution"){ - archiveName "jME"+jmeVersion+"_"+jmeVersionTag+"_"+new Date().format("yyyy-MM-dd")+".zip" - - into("/") { - from {"./dist"} - } - into("/sources") { - from {"$buildDir/libDist/sources"} - } +task createZipDistribution(type:Zip,dependsOn:["dist","libDist"], description:"Package the nightly zip distribution"){ + archiveName "jME" + jmeFullVersion + ".zip" + into("/") { + from {"./dist"} + } + into("/sources") { + from {"$buildDir/libDist/sources"} + } } task copyLibs(type: Copy){ @@ -105,7 +115,12 @@ task wrapper(type: Wrapper, description: 'Creates and deploys the Gradle wrapper gradleVersion = '2.2.1' } -String findNDK() { +ext { + ndkCommandPath = "" + ndkExists = false +} + +task configureAndroidNDK { def ndkBuildFile = "ndk-build" // if windows, use ndk-build.cmd instead if (System.properties['os.name'].toLowerCase().contains('windows')) { @@ -118,27 +133,13 @@ String findNDK() { if (System.env.ANDROID_NDK != null) { ndkBuildPath = System.env.ANDROID_NDK + File.separator + ndkBuildFile } + if (new File(ndkBuildPath).exists()) { - return ndkBuildPath - } else { - return null - } -} - -boolean checkNdkExists(String ndkCommandPath) { -// String ndkCommandPath = findNDK() - if (ndkCommandPath != null && new File(ndkCommandPath).exists()) { - return true - } else { - return false + ndkExists = true + ndkCommandPath = ndkBuildPath } } -ext { - ndkCommandPath = findNDK() - ndkExists = checkNdkExists(ndkCommandPath) -} - //class IncrementalReverseTask extends DefaultTask { // @InputDirectory // def File inputDir @@ -166,11 +167,11 @@ ext { // } //} -allprojects { - tasks.withType(JavaExec) { - enableAssertions = true // false by default - } - tasks.withType(Test) { - enableAssertions = true // true by default - } -} \ No newline at end of file +//allprojects { +// tasks.withType(JavaExec) { +// enableAssertions = true // false by default +// } +// tasks.withType(Test) { +// enableAssertions = true // true by default +// } +//} \ No newline at end of file diff --git a/common-android-app.gradle b/common-android-app.gradle new file mode 100644 index 000000000..0ec48fbd7 --- /dev/null +++ b/common-android-app.gradle @@ -0,0 +1,13 @@ +apply plugin: 'com.android.application' + +group = 'com.jme3' +version = jmeVersion + '-' + jmeVersionTag + +sourceCompatibility = '1.6' + +repositories { + mavenCentral() + maven { + url "http://nifty-gui.sourceforge.net/nifty-maven-repo" + } +} \ No newline at end of file diff --git a/common.gradle b/common.gradle index 6af4c664f..69b695ecd 100644 --- a/common.gradle +++ b/common.gradle @@ -4,10 +4,9 @@ apply plugin: 'java' apply plugin: 'maven' -apply plugin: 'maven-publish' -group = 'com.jme3' -version = jmeVersion + '-' + jmeVersionTag +group = 'com.jme3' +version = jmePomVersion sourceCompatibility = '1.6' [compileJava, compileTestJava]*.options*.encoding = 'UTF-8' @@ -19,9 +18,21 @@ repositories { } } +configurations { + deployerJars +} + dependencies { // Adding dependencies here will add the dependencies to each subproject. testCompile group: 'junit', name: 'junit', version: '4.10' + deployerJars "org.apache.maven.wagon:wagon-ssh:2.9" +} + +jar { + manifest { + attributes 'Implementation-Title': 'jMonkeyEngine', + 'Implementation-Version': jmeFullVersion + } } javadoc { @@ -56,41 +67,35 @@ artifacts { } } -publishing { - publications { - maven(MavenPublication) { - from components.java - artifact sourcesJar - artifact javadocJar - - pom.withXml { - asNode().children().last() + { - resolveStrategy = Closure.DELEGATE_FIRST - name POM_NAME - description POM_DESCRIPTION - url POM_URL - scm { - url POM_SCM_URL - connection POM_SCM_CONNECTION - developerConnection POM_SCM_DEVELOPER_CONNECTION - } - licenses { - license { - name POM_LICENSE_NAME - url POM_LICENSE_URL - distribution POM_LICENSE_DISTRIBUTION - } - } +uploadArchives { + repositories.mavenDeployer { + configuration = configurations.deployerJars + + // disable this otherwise it will fill up the server with stale jars + uniqueVersion = false + + repository(url: "scp://updates.jmonkeyengine.org/var/www/updates/maven") { + authentication(userName: "www-updater", privateKey: "private/www-updater.key") + } + + pom.project { + name POM_NAME + description POM_DESCRIPTION + url POM_URL + scm { + url POM_SCM_URL + connection POM_SCM_CONNECTION + developerConnection POM_SCM_DEVELOPER_CONNECTION + } + licenses { + license { + name POM_LICENSE_NAME + url POM_LICENSE_URL + distribution POM_LICENSE_DISTRIBUTION } } } } - - repositories { - maven { - url "${rootProject.buildDir}/repo" // change to point to your repo, e.g. http://my.org/repo - } - } } task createFolders(description: 'Creates the source folders if they do not exist.') doLast { diff --git a/gradle.properties b/gradle.properties index ccc3ed460..4380c31a0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,9 @@ jmeVersion = 3.1.0 # Version used for application and settings folder, no spaces! jmeMainVersion = 3.1 # Version addition pre-alpha-svn, Stable, Beta -jmeVersionTag = snapshot-github +jmeVersionTag = SNAPSHOT +# Increment this each time jmeVersionTag changes but jmeVersion stays the same +jmeVersionTagID = 0 # specify if JavaDoc should be built buildJavaDoc = true @@ -11,6 +13,7 @@ buildJavaDoc = true # specify if SDK and Native libraries get built buildSdkProject = true buildNativeProjects = false +buildAndroidExamples = false # Path to android NDK for building native libraries #ndkPath=/Users/normenhansen/Documents/Code-Import/android-ndk-r7 diff --git a/jme3-android-examples/build.gradle b/jme3-android-examples/build.gradle new file mode 100644 index 000000000..f1ee38739 --- /dev/null +++ b/jme3-android-examples/build.gradle @@ -0,0 +1,40 @@ +dependencies { + compile project(':jme3-core') + compile project(':jme3-android') + compile project(':jme3-effects') + compile project(':jme3-bullet') + compile project(':jme3-bullet-native-android') + compile project(':jme3-networking') + compile project(':jme3-niftygui') + compile project(':jme3-plugins') + compile project(':jme3-terrain') + compile project(':jme3-testdata') +} + +android { + compileSdkVersion 10 + buildToolsVersion "22.0.1" + + lintOptions { + // Fix nifty gui referencing "java.awt" package. + disable 'InvalidPackage' + } + + defaultConfig { + applicationId "com.jme3.android" + minSdkVersion 10 // Android 2.3 GINGERBREAD + targetSdkVersion 22 // Android 5.1 LOLLIPOP + versionCode 1 + versionName "1.0" // TODO: from settings.gradle + } + + buildTypes { + release { + minifyEnabled false + } + debug { + applicationIdSuffix ".debug" + debuggable true + } + } +} \ No newline at end of file diff --git a/jme3-android-examples/src/main/AndroidManifest.xml b/jme3-android-examples/src/main/AndroidManifest.xml new file mode 100644 index 000000000..ee80b6b28 --- /dev/null +++ b/jme3-android-examples/src/main/AndroidManifest.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jme3-android-examples/src/main/java/jme3test/android/TestChooserAndroid.java b/jme3-android-examples/src/main/java/jme3test/android/TestChooserAndroid.java new file mode 100644 index 000000000..e704bc85a --- /dev/null +++ b/jme3-android-examples/src/main/java/jme3test/android/TestChooserAndroid.java @@ -0,0 +1,12 @@ +package jme3test.android; + +import android.content.pm.ActivityInfo; +import android.app.*; +import android.os.Bundle; + +public class TestChooserAndroid extends Activity { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } +} \ No newline at end of file diff --git a/jme3-android-examples/src/main/res/values/strings.xml b/jme3-android-examples/src/main/res/values/strings.xml new file mode 100644 index 000000000..b184fa936 --- /dev/null +++ b/jme3-android-examples/src/main/res/values/strings.xml @@ -0,0 +1,6 @@ + + + JMEAndroidTest + About + Quit + \ No newline at end of file diff --git a/jme3-android/src/main/java/com/jme3/audio/android/AndroidMediaPlayerAudioRenderer.java b/jme3-android/src/main/java/com/jme3/audio/android/AndroidMediaPlayerAudioRenderer.java index 7ed04658e..394cc257b 100644 --- a/jme3-android/src/main/java/com/jme3/audio/android/AndroidMediaPlayerAudioRenderer.java +++ b/jme3-android/src/main/java/com/jme3/audio/android/AndroidMediaPlayerAudioRenderer.java @@ -525,4 +525,9 @@ public class AndroidMediaPlayerAudioRenderer implements AudioRenderer, @Override public void deleteFilter(Filter filter) { } + + @Override + public float getSourcePlaybackTime(AudioSource src) { + throw new UnsupportedOperationException("Not supported yet."); + } } diff --git a/jme3-android/src/main/java/com/jme3/renderer/android/OGLESShaderRenderer.java b/jme3-android/src/main/java/com/jme3/renderer/android/OGLESShaderRenderer.java deleted file mode 100644 index 462715f37..000000000 --- a/jme3-android/src/main/java/com/jme3/renderer/android/OGLESShaderRenderer.java +++ /dev/null @@ -1,2549 +0,0 @@ -/* - * 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.renderer.android; - -import android.opengl.GLES20; -import android.os.Build; -import com.jme3.asset.AndroidImageInfo; -import com.jme3.light.LightList; -import com.jme3.material.RenderState; -import com.jme3.math.ColorRGBA; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector2f; -import com.jme3.math.Vector3f; -import com.jme3.math.Vector4f; -import com.jme3.renderer.Caps; -import com.jme3.renderer.IDList; -import com.jme3.renderer.RenderContext; -import com.jme3.renderer.Renderer; -import com.jme3.renderer.RendererException; -import com.jme3.renderer.Statistics; -import com.jme3.renderer.android.TextureUtil.AndroidGLImageFormat; -import com.jme3.renderer.opengl.GLRenderer; -import com.jme3.scene.Mesh; -import com.jme3.scene.Mesh.Mode; -import com.jme3.scene.VertexBuffer; -import com.jme3.scene.VertexBuffer.Format; -import com.jme3.scene.VertexBuffer.Type; -import com.jme3.scene.VertexBuffer.Usage; -import com.jme3.shader.Attribute; -import com.jme3.shader.Shader; -import com.jme3.shader.Shader.ShaderSource; -import com.jme3.shader.Shader.ShaderType; -import com.jme3.shader.Uniform; -import com.jme3.texture.FrameBuffer; -import com.jme3.texture.FrameBuffer.RenderBuffer; -import com.jme3.texture.Image; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapAxis; -import com.jme3.util.BufferUtils; -import com.jme3.util.ListMap; -import com.jme3.util.NativeObjectManager; -import java.nio.Buffer; -import java.nio.ByteBuffer; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; -import java.nio.ShortBuffer; -import java.util.EnumSet; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import jme3tools.shader.ShaderDebug; - -/** - * @deprecated Should not be used anymore. Use {@link GLRenderer} instead. - */ -@Deprecated -public class OGLESShaderRenderer implements Renderer { - - private static final Logger logger = Logger.getLogger(OGLESShaderRenderer.class.getName()); - private static final boolean VALIDATE_SHADER = false; - 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 RenderContext context = new RenderContext(); - private final NativeObjectManager objManager = new NativeObjectManager(); - private final EnumSet caps = EnumSet.noneOf(Caps.class); - // current state - private Shader boundShader; - // initalDrawBuf and initialReadBuf are not used on ES, - // http://www.khronos.org/opengles/sdk/docs/man/xhtml/glBindFramebuffer.xml - //private int initialDrawBuf, initialReadBuf; - private int glslVer; - private int vertexTextureUnits; - private int fragTextureUnits; - private int vertexUniforms; - private int fragUniforms; - private int vertexAttribs; -// private int maxFBOSamples; - private final int maxFBOAttachs = 1; // Only 1 color attachment on ES - private final int maxMRTFBOAttachs = 1; // FIXME for now, not sure if > 1 is needed for ES - private int maxRBSize; - private int maxTexSize; - private int maxCubeTexSize; - private int maxVertCount; - private int maxTriCount; - private boolean tdc; - private FrameBuffer lastFb = null; - private FrameBuffer mainFbOverride = null; - private final Statistics statistics = new Statistics(); - private int vpX, vpY, vpW, vpH; - private int clipX, clipY, clipW, clipH; - //private final GL10 gl; - private boolean powerVr = false; - private boolean useVBO = false; - - public OGLESShaderRenderer() { - } - - protected void updateNameBuffer() { - int len = stringBuf.length(); - - nameBuf.position(0); - nameBuf.limit(len); - for (int i = 0; i < len; i++) { - nameBuf.put((byte) stringBuf.charAt(i)); - } - - nameBuf.rewind(); - } - - public Statistics getStatistics() { - return statistics; - } - - public EnumSet getCaps() { - return caps; - } - - private static final Pattern VERSION = Pattern.compile(".*?(\\d+)\\.(\\d+).*"); - - public static int extractVersion(String version) { - - Matcher m = VERSION.matcher(version); - if (m.matches()) { - int major = Integer.parseInt(m.group(1)); - int minor = Integer.parseInt(m.group(2)); - - return major * 100 + minor * 10; - } else { - return -1; - } - } - - public void initialize() { - logger.log(Level.FINE, "Vendor: {0}", GLES20.glGetString(GLES20.GL_VENDOR)); - logger.log(Level.FINE, "Renderer: {0}", GLES20.glGetString(GLES20.GL_RENDERER)); - logger.log(Level.FINE, "Version: {0}", GLES20.glGetString(GLES20.GL_VERSION)); - logger.log(Level.FINE, "Shading Language Version: {0}", GLES20.glGetString(GLES20.GL_SHADING_LANGUAGE_VERSION)); - - powerVr = GLES20.glGetString(GLES20.GL_RENDERER).contains("PowerVR"); - - - //workaround, always assume we support GLSL100 - //some cards just don't report this correctly - caps.add(Caps.GLSL100); - - /* - // Fix issue in TestRenderToMemory when GL_FRONT is the main - // buffer being used. - initialDrawBuf = glGetInteger(GL_DRAW_BUFFER); - initialReadBuf = glGetInteger(GL_READ_BUFFER); - - // XXX: This has to be GL_BACK for canvas on Mac - // Since initialDrawBuf is GL_FRONT for pbuffer, gotta - // change this value later on ... -// initialDrawBuf = GL_BACK; -// initialReadBuf = GL_BACK; - */ - - // Check OpenGL version - int openGlVer = extractVersion(GLES20.glGetString(GLES20.GL_VERSION)); - if (openGlVer == -1) { - glslVer = -1; - throw new UnsupportedOperationException("OpenGL ES 2.0+ is required for OGLESShaderRenderer!"); - } - - // Check shader language version - glslVer = extractVersion(GLES20.glGetString(GLES20.GL_SHADING_LANGUAGE_VERSION)); - switch (glslVer) { - // TODO: When new versions of OpenGL ES shader language come out, - // update this. - default: - caps.add(Caps.GLSL100); - break; - } - - GLES20.glGetIntegerv(GLES20.GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, intBuf16); - vertexTextureUnits = intBuf16.get(0); - logger.log(Level.FINE, "VTF Units: {0}", vertexTextureUnits); - if (vertexTextureUnits > 0) { - caps.add(Caps.VertexTextureFetch); - } - - GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_IMAGE_UNITS, intBuf16); - fragTextureUnits = intBuf16.get(0); - logger.log(Level.FINE, "Texture Units: {0}", fragTextureUnits); - - // Multiply vector count by 4 to get float count. - GLES20.glGetIntegerv(GLES20.GL_MAX_VERTEX_UNIFORM_VECTORS, intBuf16); - vertexUniforms = intBuf16.get(0) * 4; - logger.log(Level.FINER, "Vertex Uniforms: {0}", vertexUniforms); - - GLES20.glGetIntegerv(GLES20.GL_MAX_FRAGMENT_UNIFORM_VECTORS, intBuf16); - fragUniforms = intBuf16.get(0) * 4; - logger.log(Level.FINER, "Fragment Uniforms: {0}", fragUniforms); - - GLES20.glGetIntegerv(GLES20.GL_MAX_VARYING_VECTORS, intBuf16); - int varyingFloats = intBuf16.get(0) * 4; - logger.log(Level.FINER, "Varying Floats: {0}", varyingFloats); - - GLES20.glGetIntegerv(GLES20.GL_MAX_VERTEX_ATTRIBS, intBuf16); - vertexAttribs = intBuf16.get(0); - logger.log(Level.FINE, "Vertex Attributes: {0}", vertexAttribs); - - GLES20.glGetIntegerv(GLES20.GL_SUBPIXEL_BITS, intBuf16); - int subpixelBits = intBuf16.get(0); - logger.log(Level.FINE, "Subpixel Bits: {0}", subpixelBits); - -// GLES10.glGetIntegerv(GLES10.GL_MAX_ELEMENTS_VERTICES, intBuf16); -// maxVertCount = intBuf16.get(0); -// logger.log(Level.FINER, "Preferred Batch Vertex Count: {0}", maxVertCount); -// -// GLES10.glGetIntegerv(GLES10.GL_MAX_ELEMENTS_INDICES, intBuf16); -// maxTriCount = intBuf16.get(0); -// logger.log(Level.FINER, "Preferred Batch Index Count: {0}", maxTriCount); - - GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, intBuf16); - maxTexSize = intBuf16.get(0); - logger.log(Level.FINE, "Maximum Texture Resolution: {0}", maxTexSize); - - GLES20.glGetIntegerv(GLES20.GL_MAX_CUBE_MAP_TEXTURE_SIZE, intBuf16); - maxCubeTexSize = intBuf16.get(0); - logger.log(Level.FINE, "Maximum CubeMap Resolution: {0}", maxCubeTexSize); - - GLES20.glGetIntegerv(GLES20.GL_MAX_RENDERBUFFER_SIZE, intBuf16); - maxRBSize = intBuf16.get(0); - logger.log(Level.FINER, "FBO RB Max Size: {0}", maxRBSize); - - /* - if (ctxCaps.GL_ARB_color_buffer_float){ - // XXX: Require both 16 and 32 bit float support for FloatColorBuffer. - if (ctxCaps.GL_ARB_half_float_pixel){ - caps.add(Caps.FloatColorBuffer); - } - } - - if (ctxCaps.GL_ARB_depth_buffer_float){ - caps.add(Caps.FloatDepthBuffer); - } - - if (ctxCaps.GL_ARB_draw_instanced) - caps.add(Caps.MeshInstancing); - - if (ctxCaps.GL_ARB_texture_buffer_object) - caps.add(Caps.TextureBuffer); - - if (ctxCaps.GL_ARB_texture_float){ - if (ctxCaps.GL_ARB_half_float_pixel){ - caps.add(Caps.FloatTexture); - } - } - - if (ctxCaps.GL_EXT_packed_float){ - caps.add(Caps.PackedFloatColorBuffer); - if (ctxCaps.GL_ARB_half_float_pixel){ - // because textures are usually uploaded as RGB16F - // need half-float pixel - caps.add(Caps.PackedFloatTexture); - } - } - - if (ctxCaps.GL_EXT_texture_array) - caps.add(Caps.TextureArray); - - if (ctxCaps.GL_EXT_texture_shared_exponent) - caps.add(Caps.SharedExponentTexture); - - if (ctxCaps.GL_EXT_framebuffer_object){ - caps.add(Caps.FrameBuffer); - - glGetInteger(GL_MAX_RENDERBUFFER_SIZE_EXT, intBuf16); - maxRBSize = intBuf16.get(0); - logger.log(Level.FINER, "FBO RB Max Size: {0}", maxRBSize); - - glGetInteger(GL_MAX_COLOR_ATTACHMENTS_EXT, intBuf16); - maxFBOAttachs = intBuf16.get(0); - logger.log(Level.FINER, "FBO Max renderbuffers: {0}", maxFBOAttachs); - - if (ctxCaps.GL_EXT_framebuffer_multisample){ - caps.add(Caps.FrameBufferMultisample); - - glGetInteger(GL_MAX_SAMPLES_EXT, intBuf16); - maxFBOSamples = intBuf16.get(0); - logger.log(Level.FINER, "FBO Max Samples: {0}", maxFBOSamples); - } - - if (ctxCaps.GL_ARB_draw_buffers){ - caps.add(Caps.FrameBufferMRT); - glGetInteger(ARBDrawBuffers.GL_MAX_DRAW_BUFFERS_ARB, intBuf16); - maxMRTFBOAttachs = intBuf16.get(0); - logger.log(Level.FINER, "FBO Max MRT renderbuffers: {0}", maxMRTFBOAttachs); - } - } - - if (ctxCaps.GL_ARB_multisample){ - glGetInteger(ARBMultisample.GL_SAMPLE_BUFFERS_ARB, intBuf16); - boolean available = intBuf16.get(0) != 0; - glGetInteger(ARBMultisample.GL_SAMPLES_ARB, intBuf16); - int samples = intBuf16.get(0); - logger.log(Level.FINER, "Samples: {0}", samples); - boolean enabled = glIsEnabled(ARBMultisample.GL_MULTISAMPLE_ARB); - if (samples > 0 && available && !enabled){ - glEnable(ARBMultisample.GL_MULTISAMPLE_ARB); - } - } - */ - - String extensions = GLES20.glGetString(GLES20.GL_EXTENSIONS); - logger.log(Level.FINE, "GL_EXTENSIONS: {0}", extensions); - - // Get number of compressed formats available. - GLES20.glGetIntegerv(GLES20.GL_NUM_COMPRESSED_TEXTURE_FORMATS, intBuf16); - int numCompressedFormats = intBuf16.get(0); - - // Allocate buffer for compressed formats. - IntBuffer compressedFormats = BufferUtils.createIntBuffer(numCompressedFormats); - GLES20.glGetIntegerv(GLES20.GL_COMPRESSED_TEXTURE_FORMATS, compressedFormats); - - // Check for errors after all glGet calls. - RendererUtil.checkGLError(); - - // Print compressed formats. - for (int i = 0; i < numCompressedFormats; i++) { - logger.log(Level.FINE, "Compressed Texture Formats: {0}", compressedFormats.get(i)); - } - - TextureUtil.loadTextureFeatures(extensions); - - applyRenderState(RenderState.DEFAULT); - GLES20.glDisable(GLES20.GL_DITHER); - RendererUtil.checkGLError(); - - useVBO = false; - - // NOTE: SDK_INT is only available since 1.6, - // but for jME3 it doesn't matter since android versions 1.5 and below - // are not supported. - if (Build.VERSION.SDK_INT >= 9){ - logger.log(Level.FINE, "Force-enabling VBO (Android 2.3 or higher)"); - useVBO = true; - } else { - useVBO = false; - } - - logger.log(Level.FINE, "Caps: {0}", caps); - } - - /** - * resetGLObjects should be called when die GLView gets recreated to reset all GPU objects - */ - public void resetGLObjects() { - objManager.resetObjects(); - statistics.clearMemory(); - boundShader = null; - lastFb = null; - context.reset(); - } - - public void cleanup() { - objManager.deleteAllObjects(this); - statistics.clearMemory(); - } - - private void checkCap(Caps cap) { - if (!caps.contains(cap)) { - throw new UnsupportedOperationException("Required capability missing: " + cap.name()); - } - } - - /*********************************************************************\ - |* Render State *| - \*********************************************************************/ - public void setDepthRange(float start, float end) { - GLES20.glDepthRangef(start, end); - RendererUtil.checkGLError(); - } - - public void clearBuffers(boolean color, boolean depth, boolean stencil) { - int bits = 0; - if (color) { - //See explanations of the depth below, we must enable color write to be able to clear the color buffer - if (context.colorWriteEnabled == false) { - GLES20.glColorMask(true, true, true, true); - context.colorWriteEnabled = true; - } - bits = GLES20.GL_COLOR_BUFFER_BIT; - } - if (depth) { - //glClear(GL_DEPTH_BUFFER_BIT) seems to not work when glDepthMask is false - //here s some link on openl board - //http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=257223 - //if depth clear is requested, we enable the depthMask - if (context.depthWriteEnabled == false) { - GLES20.glDepthMask(true); - context.depthWriteEnabled = true; - } - bits |= GLES20.GL_DEPTH_BUFFER_BIT; - } - if (stencil) { - bits |= GLES20.GL_STENCIL_BUFFER_BIT; - } - if (bits != 0) { - GLES20.glClear(bits); - RendererUtil.checkGLError(); - } - } - - public void setBackgroundColor(ColorRGBA color) { - GLES20.glClearColor(color.r, color.g, color.b, color.a); - RendererUtil.checkGLError(); - } - - public void applyRenderState(RenderState state) { - /* - if (state.isWireframe() && !context.wireframe){ - GLES20.glPolygonMode(GLES20.GL_FRONT_AND_BACK, GLES20.GL_LINE); - context.wireframe = true; - }else if (!state.isWireframe() && context.wireframe){ - GLES20.glPolygonMode(GLES20.GL_FRONT_AND_BACK, GLES20.GL_FILL); - context.wireframe = false; - } - */ - if (state.isDepthTest() && !context.depthTestEnabled) { - GLES20.glEnable(GLES20.GL_DEPTH_TEST); - GLES20.glDepthFunc(convertTestFunction(context.depthFunc)); - RendererUtil.checkGLError(); - context.depthTestEnabled = true; - } else if (!state.isDepthTest() && context.depthTestEnabled) { - GLES20.glDisable(GLES20.GL_DEPTH_TEST); - RendererUtil.checkGLError(); - context.depthTestEnabled = false; - } - if (state.getDepthFunc() != context.depthFunc) { - GLES20.glDepthFunc(convertTestFunction(state.getDepthFunc())); - context.depthFunc = state.getDepthFunc(); - } - - if (state.isDepthWrite() && !context.depthWriteEnabled) { - GLES20.glDepthMask(true); - RendererUtil.checkGLError(); - context.depthWriteEnabled = true; - } else if (!state.isDepthWrite() && context.depthWriteEnabled) { - GLES20.glDepthMask(false); - RendererUtil.checkGLError(); - context.depthWriteEnabled = false; - } - if (state.isColorWrite() && !context.colorWriteEnabled) { - GLES20.glColorMask(true, true, true, true); - RendererUtil.checkGLError(); - context.colorWriteEnabled = true; - } else if (!state.isColorWrite() && context.colorWriteEnabled) { - GLES20.glColorMask(false, false, false, false); - RendererUtil.checkGLError(); - context.colorWriteEnabled = false; - } -// if (state.isPointSprite() && !context.pointSprite) { -//// GLES20.glEnable(GLES20.GL_POINT_SPRITE); -//// GLES20.glTexEnvi(GLES20.GL_POINT_SPRITE, GLES20.GL_COORD_REPLACE, GLES20.GL_TRUE); -//// GLES20.glEnable(GLES20.GL_VERTEX_PROGRAM_POINT_SIZE); -//// GLES20.glPointParameterf(GLES20.GL_POINT_SIZE_MIN, 1.0f); -// } else if (!state.isPointSprite() && context.pointSprite) { -//// GLES20.glDisable(GLES20.GL_POINT_SPRITE); -// } - - if (state.isPolyOffset()) { - if (!context.polyOffsetEnabled) { - GLES20.glEnable(GLES20.GL_POLYGON_OFFSET_FILL); - GLES20.glPolygonOffset(state.getPolyOffsetFactor(), - state.getPolyOffsetUnits()); - RendererUtil.checkGLError(); - - context.polyOffsetEnabled = true; - context.polyOffsetFactor = state.getPolyOffsetFactor(); - context.polyOffsetUnits = state.getPolyOffsetUnits(); - } else { - if (state.getPolyOffsetFactor() != context.polyOffsetFactor - || state.getPolyOffsetUnits() != context.polyOffsetUnits) { - GLES20.glPolygonOffset(state.getPolyOffsetFactor(), - state.getPolyOffsetUnits()); - RendererUtil.checkGLError(); - - context.polyOffsetFactor = state.getPolyOffsetFactor(); - context.polyOffsetUnits = state.getPolyOffsetUnits(); - } - } - } else { - if (context.polyOffsetEnabled) { - GLES20.glDisable(GLES20.GL_POLYGON_OFFSET_FILL); - RendererUtil.checkGLError(); - - context.polyOffsetEnabled = false; - context.polyOffsetFactor = 0; - context.polyOffsetUnits = 0; - } - } - if (state.getFaceCullMode() != context.cullMode) { - if (state.getFaceCullMode() == RenderState.FaceCullMode.Off) { - GLES20.glDisable(GLES20.GL_CULL_FACE); - RendererUtil.checkGLError(); - } else { - GLES20.glEnable(GLES20.GL_CULL_FACE); - RendererUtil.checkGLError(); - } - - switch (state.getFaceCullMode()) { - case Off: - break; - case Back: - GLES20.glCullFace(GLES20.GL_BACK); - RendererUtil.checkGLError(); - break; - case Front: - GLES20.glCullFace(GLES20.GL_FRONT); - RendererUtil.checkGLError(); - break; - case FrontAndBack: - GLES20.glCullFace(GLES20.GL_FRONT_AND_BACK); - RendererUtil.checkGLError(); - break; - default: - throw new UnsupportedOperationException("Unrecognized face cull mode: " - + state.getFaceCullMode()); - } - - context.cullMode = state.getFaceCullMode(); - } - - if (state.getBlendMode() != context.blendMode) { - if (state.getBlendMode() == RenderState.BlendMode.Off) { - GLES20.glDisable(GLES20.GL_BLEND); - RendererUtil.checkGLError(); - } else { - GLES20.glEnable(GLES20.GL_BLEND); - switch (state.getBlendMode()) { - case Off: - break; - case Additive: - GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE); - break; - case AlphaAdditive: - GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE); - break; - case Color: - GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_COLOR); - break; - case Alpha: - GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); - break; - case PremultAlpha: - GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA); - break; - case Modulate: - GLES20.glBlendFunc(GLES20.GL_DST_COLOR, GLES20.GL_ZERO); - break; - case ModulateX2: - GLES20.glBlendFunc(GLES20.GL_DST_COLOR, GLES20.GL_SRC_COLOR); - break; - case Screen: - GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_COLOR); - break; - case Exclusion: - GLES20.glBlendFunc(GLES20.GL_ONE_MINUS_DST_COLOR, GLES20.GL_ONE_MINUS_SRC_COLOR); - break; - default: - throw new UnsupportedOperationException("Unrecognized blend mode: " - + state.getBlendMode()); - } - RendererUtil.checkGLError(); - } - context.blendMode = state.getBlendMode(); - } - } - - /*********************************************************************\ - |* Camera and World transforms *| - \*********************************************************************/ - public void setViewPort(int x, int y, int w, int h) { - if (x != vpX || vpY != y || vpW != w || vpH != h) { - GLES20.glViewport(x, y, w, h); - RendererUtil.checkGLError(); - - vpX = x; - vpY = y; - vpW = w; - vpH = h; - } - } - - public void setClipRect(int x, int y, int width, int height) { - if (!context.clipRectEnabled) { - GLES20.glEnable(GLES20.GL_SCISSOR_TEST); - RendererUtil.checkGLError(); - context.clipRectEnabled = true; - } - if (clipX != x || clipY != y || clipW != width || clipH != height) { - GLES20.glScissor(x, y, width, height); - RendererUtil.checkGLError(); - clipX = x; - clipY = y; - clipW = width; - clipH = height; - } - } - - public void clearClipRect() { - if (context.clipRectEnabled) { - GLES20.glDisable(GLES20.GL_SCISSOR_TEST); - RendererUtil.checkGLError(); - context.clipRectEnabled = false; - - clipX = 0; - clipY = 0; - clipW = 0; - clipH = 0; - } - } - - public void postFrame() { - RendererUtil.checkGLErrorForced(); - - objManager.deleteUnused(this); - } - - /*********************************************************************\ - |* Shaders *| - \*********************************************************************/ - protected void updateUniformLocation(Shader shader, Uniform uniform) { - stringBuf.setLength(0); - stringBuf.append(uniform.getName()).append('\0'); - updateNameBuffer(); - int loc = GLES20.glGetUniformLocation(shader.getId(), uniform.getName()); - RendererUtil.checkGLError(); - - if (loc < 0) { - uniform.setLocation(-1); - // uniform is not declared in shader - } else { - uniform.setLocation(loc); - } - } - - protected void bindProgram(Shader shader) { - int shaderId = shader.getId(); - if (context.boundShaderProgram != shaderId) { - GLES20.glUseProgram(shaderId); - RendererUtil.checkGLError(); - - statistics.onShaderUse(shader, true); - boundShader = shader; - context.boundShaderProgram = shaderId; - } else { - statistics.onShaderUse(shader, false); - } - } - - protected void updateUniform(Shader shader, Uniform uniform) { - assert uniform.getName() != null; - assert shader.getId() > 0; - - bindProgram(shader); - - int loc = uniform.getLocation(); - if (loc == -1) { - return; - } - - if (loc == -2) { - // get uniform location - updateUniformLocation(shader, uniform); - if (uniform.getLocation() == -1) { - // not declared, ignore - uniform.clearUpdateNeeded(); - return; - } - loc = uniform.getLocation(); - } - - if (uniform.getVarType() == null) { - // removed logging the warning to avoid flooding the log - // (LWJGL also doesn't post a warning) - //logger.log(Level.FINEST, "Uniform value is not set yet. Shader: {0}, Uniform: {1}", - // new Object[]{shader.toString(), uniform.toString()}); - return; // value not set yet.. - } - - statistics.onUniformSet(); - - uniform.clearUpdateNeeded(); - FloatBuffer fb; - IntBuffer ib; - switch (uniform.getVarType()) { - case Float: - Float f = (Float) uniform.getValue(); - GLES20.glUniform1f(loc, f.floatValue()); - break; - case Vector2: - Vector2f v2 = (Vector2f) uniform.getValue(); - GLES20.glUniform2f(loc, v2.getX(), v2.getY()); - break; - case Vector3: - Vector3f v3 = (Vector3f) uniform.getValue(); - GLES20.glUniform3f(loc, v3.getX(), v3.getY(), v3.getZ()); - break; - case Vector4: - Object val = uniform.getValue(); - if (val instanceof ColorRGBA) { - ColorRGBA c = (ColorRGBA) val; - GLES20.glUniform4f(loc, c.r, c.g, c.b, c.a); - } else if (val instanceof Vector4f) { - Vector4f c = (Vector4f) val; - GLES20.glUniform4f(loc, c.x, c.y, c.z, c.w); - } else { - Quaternion c = (Quaternion) uniform.getValue(); - GLES20.glUniform4f(loc, c.getX(), c.getY(), c.getZ(), c.getW()); - } - break; - case Boolean: - Boolean b = (Boolean) uniform.getValue(); - GLES20.glUniform1i(loc, b.booleanValue() ? GLES20.GL_TRUE : GLES20.GL_FALSE); - break; - case Matrix3: - fb = (FloatBuffer) uniform.getValue(); - assert fb.remaining() == 9; - GLES20.glUniformMatrix3fv(loc, 1, false, fb); - break; - case Matrix4: - fb = (FloatBuffer) uniform.getValue(); - assert fb.remaining() == 16; - GLES20.glUniformMatrix4fv(loc, 1, false, fb); - break; - case IntArray: - ib = (IntBuffer) uniform.getValue(); - GLES20.glUniform1iv(loc, ib.limit(), ib); - break; - case FloatArray: - fb = (FloatBuffer) uniform.getValue(); - GLES20.glUniform1fv(loc, fb.limit(), fb); - break; - case Vector2Array: - fb = (FloatBuffer) uniform.getValue(); - GLES20.glUniform2fv(loc, fb.limit() / 2, fb); - break; - case Vector3Array: - fb = (FloatBuffer) uniform.getValue(); - GLES20.glUniform3fv(loc, fb.limit() / 3, fb); - break; - case Vector4Array: - fb = (FloatBuffer) uniform.getValue(); - GLES20.glUniform4fv(loc, fb.limit() / 4, fb); - break; - case Matrix4Array: - fb = (FloatBuffer) uniform.getValue(); - GLES20.glUniformMatrix4fv(loc, fb.limit() / 16, false, fb); - break; - case Int: - Integer i = (Integer) uniform.getValue(); - GLES20.glUniform1i(loc, i.intValue()); - break; - default: - throw new UnsupportedOperationException("Unsupported uniform type: " + uniform.getVarType()); - } - RendererUtil.checkGLError(); - } - - protected void updateShaderUniforms(Shader shader) { - ListMap uniforms = shader.getUniformMap(); - for (int i = 0; i < uniforms.size(); i++) { - Uniform uniform = uniforms.getValue(i); - if (uniform.isUpdateNeeded()) { - updateUniform(shader, uniform); - } - } - } - - protected void resetUniformLocations(Shader shader) { - ListMap uniforms = shader.getUniformMap(); - for (int i = 0; i < uniforms.size(); i++) { - Uniform uniform = uniforms.getValue(i); - uniform.reset(); // e.g check location again - } - } - - /* - * (Non-javadoc) - * Only used for fixed-function. Ignored. - */ - public void setLighting(LightList list) { - } - - public int convertShaderType(ShaderType type) { - switch (type) { - case Fragment: - return GLES20.GL_FRAGMENT_SHADER; - case Vertex: - return GLES20.GL_VERTEX_SHADER; -// case Geometry: -// return ARBGeometryShader4.GL_GEOMETRY_SHADER_ARB; - default: - throw new RuntimeException("Unrecognized shader type."); - } - } - - public void updateShaderSourceData(ShaderSource source) { - int id = source.getId(); - if (id == -1) { - // Create id - id = GLES20.glCreateShader(convertShaderType(source.getType())); - RendererUtil.checkGLError(); - - if (id <= 0) { - throw new RendererException("Invalid ID received when trying to create shader."); - } - source.setId(id); - } - - if (!source.getLanguage().equals("GLSL100")) { - throw new RendererException("This shader cannot run in OpenGL ES. " - + "Only GLSL 1.0 shaders are supported."); - } - - // upload shader source - // merge the defines and source code - byte[] definesCodeData = source.getDefines().getBytes(); - byte[] sourceCodeData = source.getSource().getBytes(); - ByteBuffer codeBuf = BufferUtils.createByteBuffer(definesCodeData.length - + sourceCodeData.length); - codeBuf.put(definesCodeData); - codeBuf.put(sourceCodeData); - codeBuf.flip(); - - if (powerVr && source.getType() == ShaderType.Vertex) { - // XXX: This is to fix a bug in old PowerVR, remove - // when no longer applicable. - GLES20.glShaderSource( - id, source.getDefines() - + source.getSource()); - } else { - String precision =""; - if (source.getType() == ShaderType.Fragment) { - precision = "precision mediump float;\n"; - } - GLES20.glShaderSource( - id, - precision - +source.getDefines() - + source.getSource()); - } -// int range[] = new int[2]; -// int precision[] = new int[1]; -// GLES20.glGetShaderPrecisionFormat(GLES20.GL_VERTEX_SHADER, GLES20.GL_HIGH_FLOAT, range, 0, precision, 0); -// System.out.println("PRECISION HIGH FLOAT VERTEX"); -// System.out.println("range "+range[0]+"," +range[1]); -// System.out.println("precision "+precision[0]); - - GLES20.glCompileShader(id); - RendererUtil.checkGLError(); - - GLES20.glGetShaderiv(id, GLES20.GL_COMPILE_STATUS, intBuf1); - RendererUtil.checkGLError(); - - boolean compiledOK = intBuf1.get(0) == GLES20.GL_TRUE; - String infoLog = null; - - if (VALIDATE_SHADER || !compiledOK) { - // even if compile succeeded, check - // log for warnings - GLES20.glGetShaderiv(id, GLES20.GL_INFO_LOG_LENGTH, intBuf1); - RendererUtil.checkGLError(); - infoLog = GLES20.glGetShaderInfoLog(id); - } - - if (compiledOK) { - if (infoLog != null) { - logger.log(Level.FINE, "compile success: {0}, {1}", new Object[]{source.getName(), infoLog}); - } else { - logger.log(Level.FINE, "compile success: {0}", source.getName()); - } - source.clearUpdateNeeded(); - } else { - logger.log(Level.WARNING, "Bad compile of:\n{0}", - new Object[]{ShaderDebug.formatShaderSource(stringBuf.toString() + source.getDefines() + source.getSource())}); - if (infoLog != null) { - throw new RendererException("compile error in: " + source + "\n" + infoLog); - } else { - throw new RendererException("compile error in: " + source + "\nerror: "); - } - } - } - - public void updateShaderData(Shader shader) { - int id = shader.getId(); - boolean needRegister = false; - if (id == -1) { - // create program - id = GLES20.glCreateProgram(); - RendererUtil.checkGLError(); - - if (id <= 0) { - throw new RendererException("Invalid ID received when trying to create shader program."); - } - - shader.setId(id); - needRegister = true; - } - - for (ShaderSource source : shader.getSources()) { - if (source.isUpdateNeeded()) { - updateShaderSourceData(source); - } - - GLES20.glAttachShader(id, source.getId()); - RendererUtil.checkGLError(); - } - - // link shaders to program - GLES20.glLinkProgram(id); - RendererUtil.checkGLError(); - - GLES20.glGetProgramiv(id, GLES20.GL_LINK_STATUS, intBuf1); - RendererUtil.checkGLError(); - - boolean linkOK = intBuf1.get(0) == GLES20.GL_TRUE; - String infoLog = null; - - if (VALIDATE_SHADER || !linkOK) { - GLES20.glGetProgramiv(id, GLES20.GL_INFO_LOG_LENGTH, intBuf1); - RendererUtil.checkGLError(); - - int length = intBuf1.get(0); - if (length > 3) { - // get infos - infoLog = GLES20.glGetProgramInfoLog(id); - RendererUtil.checkGLError(); - } - } - - if (linkOK) { - if (infoLog != null) { - logger.log(Level.FINE, "shader link success. \n{0}", infoLog); - } else { - logger.fine("shader link success"); - } - shader.clearUpdateNeeded(); - if (needRegister) { - // Register shader for clean up if it was created in this method. - objManager.registerObject(shader); - statistics.onNewShader(); - } else { - // OpenGL spec: uniform locations may change after re-link - resetUniformLocations(shader); - } - } else { - if (infoLog != null) { - throw new RendererException("Shader link failure, shader: " + shader + "\n" + infoLog); - } else { - throw new RendererException("Shader link failure, shader: " + shader + "\ninfo: "); - } - } - } - - public void setShader(Shader shader) { - if (shader == null) { - throw new IllegalArgumentException("Shader cannot be null"); - } else { - if (shader.isUpdateNeeded()) { - updateShaderData(shader); - } - - // NOTE: might want to check if any of the - // sources need an update? - - assert shader.getId() > 0; - - updateShaderUniforms(shader); - bindProgram(shader); - } - } - - public void deleteShaderSource(ShaderSource source) { - if (source.getId() < 0) { - logger.warning("Shader source is not uploaded to GPU, cannot delete."); - return; - } - - source.clearUpdateNeeded(); - - GLES20.glDeleteShader(source.getId()); - RendererUtil.checkGLError(); - - source.resetObject(); - } - - public void deleteShader(Shader shader) { - if (shader.getId() == -1) { - logger.warning("Shader is not uploaded to GPU, cannot delete."); - return; - } - - for (ShaderSource source : shader.getSources()) { - if (source.getId() != -1) { - GLES20.glDetachShader(shader.getId(), source.getId()); - RendererUtil.checkGLError(); - - deleteShaderSource(source); - } - } - - GLES20.glDeleteProgram(shader.getId()); - RendererUtil.checkGLError(); - - statistics.onDeleteShader(); - shader.resetObject(); - } - - private int convertTestFunction(RenderState.TestFunction testFunc) { - switch (testFunc) { - case Never: - return GLES20.GL_NEVER; - case Less: - return GLES20.GL_LESS; - case LessOrEqual: - return GLES20.GL_LEQUAL; - case Greater: - return GLES20.GL_GREATER; - case GreaterOrEqual: - return GLES20.GL_GEQUAL; - case Equal: - return GLES20.GL_EQUAL; - case NotEqual: - return GLES20.GL_NOTEQUAL; - case Always: - return GLES20.GL_ALWAYS; - default: - throw new UnsupportedOperationException("Unrecognized test function: " + testFunc); - } - } - - /*********************************************************************\ - |* Framebuffers *| - \*********************************************************************/ - - public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst, boolean copyDepth) { - throw new RendererException("Copy framebuffer not implemented yet."); - -// if (GLContext.getCapabilities().GL_EXT_framebuffer_blit) { -// int srcX0 = 0; -// int srcY0 = 0; -// int srcX1 = 0; -// int srcY1 = 0; -// -// int dstX0 = 0; -// int dstY0 = 0; -// int dstX1 = 0; -// int dstY1 = 0; -// -// int prevFBO = context.boundFBO; -// -// if (mainFbOverride != null) { -// if (src == null) { -// src = mainFbOverride; -// } -// if (dst == null) { -// dst = mainFbOverride; -// } -// } -// -// if (src != null && src.isUpdateNeeded()) { -// updateFrameBuffer(src); -// } -// -// if (dst != null && dst.isUpdateNeeded()) { -// updateFrameBuffer(dst); -// } -// -// if (src == null) { -// GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); -// srcX0 = vpX; -// srcY0 = vpY; -// srcX1 = vpX + vpW; -// srcY1 = vpY + vpH; -// } else { -// GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, src.getId()); -// srcX1 = src.getWidth(); -// srcY1 = src.getHeight(); -// } -// if (dst == null) { -// GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); -// dstX0 = vpX; -// dstY0 = vpY; -// dstX1 = vpX + vpW; -// dstY1 = vpY + vpH; -// } else { -// GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, dst.getId()); -// dstX1 = dst.getWidth(); -// dstY1 = dst.getHeight(); -// } -// -// -// int mask = GL_COLOR_BUFFER_BIT; -// if (copyDepth) { -// mask |= GL_DEPTH_BUFFER_BIT; -// } -// GLES20.glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, -// dstX0, dstY0, dstX1, dstY1, mask, -// GL_NEAREST); -// -// -// GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, prevFBO); -// try { -// checkFrameBufferError(); -// } catch (IllegalStateException ex) { -// logger.log(Level.SEVERE, "Source FBO:\n{0}", src); -// logger.log(Level.SEVERE, "Dest FBO:\n{0}", dst); -// throw ex; -// } -// } else { -// throw new RendererException("EXT_framebuffer_blit required."); -// // TODO: support non-blit copies? -// } - } - - private void checkFrameBufferStatus(FrameBuffer fb) { - try { - checkFrameBufferError(); - } catch (IllegalStateException ex) { - logger.log(Level.SEVERE, "=== jMonkeyEngine FBO State ===\n{0}", fb); - printRealFrameBufferInfo(fb); - throw ex; - } - } - - private void checkFrameBufferError() { - int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER); - switch (status) { - case GLES20.GL_FRAMEBUFFER_COMPLETE: - break; - case GLES20.GL_FRAMEBUFFER_UNSUPPORTED: - //Choose different formats - throw new IllegalStateException("Framebuffer object format is " - + "unsupported by the video hardware."); - case GLES20.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - throw new IllegalStateException("Framebuffer has erronous attachment."); - case GLES20.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: - throw new IllegalStateException("Framebuffer doesn't have any renderbuffers attached."); - case GLES20.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: - throw new IllegalStateException("Framebuffer attachments must have same dimensions."); -// case GLES20.GL_FRAMEBUFFER_INCOMPLETE_FORMATS: -// throw new IllegalStateException("Framebuffer attachments must have same formats."); -// case GLES20.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: -// throw new IllegalStateException("Incomplete draw buffer."); -// case GLES20.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: -// throw new IllegalStateException("Incomplete read buffer."); -// case GLES20.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT: -// throw new IllegalStateException("Incomplete multisample buffer."); - default: - //Programming error; will fail on all hardware - throw new IllegalStateException("Some video driver error " - + "or programming error occured. " - + "Framebuffer object status is invalid: " + status); - } - } - - private void printRealRenderBufferInfo(FrameBuffer fb, RenderBuffer rb, String name) { - System.out.println("== Renderbuffer " + name + " =="); - System.out.println("RB ID: " + rb.getId()); - System.out.println("Is proper? " + GLES20.glIsRenderbuffer(rb.getId())); - - int attachment = convertAttachmentSlot(rb.getSlot()); - - intBuf16.clear(); - GLES20.glGetFramebufferAttachmentParameteriv(GLES20.GL_FRAMEBUFFER, - attachment, GLES20.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, intBuf16); - int type = intBuf16.get(0); - - intBuf16.clear(); - GLES20.glGetFramebufferAttachmentParameteriv(GLES20.GL_FRAMEBUFFER, - attachment, GLES20.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, intBuf16); - int rbName = intBuf16.get(0); - - switch (type) { - case GLES20.GL_NONE: - System.out.println("Type: None"); - break; - case GLES20.GL_TEXTURE: - System.out.println("Type: Texture"); - break; - case GLES20.GL_RENDERBUFFER: - System.out.println("Type: Buffer"); - System.out.println("RB ID: " + rbName); - break; - } - - - - } - - private void printRealFrameBufferInfo(FrameBuffer fb) { -// boolean doubleBuffer = GLES20.glGetBooleanv(GLES20.GL_DOUBLEBUFFER); - boolean doubleBuffer = false; // FIXME -// String drawBuf = getTargetBufferName(glGetInteger(GL_DRAW_BUFFER)); -// String readBuf = getTargetBufferName(glGetInteger(GL_READ_BUFFER)); - - int fbId = fb.getId(); - intBuf16.clear(); -// int curDrawBinding = GLES20.glGetIntegerv(GLES20.GL_DRAW_FRAMEBUFFER_BINDING); -// int curReadBinding = glGetInteger(ARBFramebufferObject.GL_READ_FRAMEBUFFER_BINDING); - - System.out.println("=== OpenGL FBO State ==="); - System.out.println("Context doublebuffered? " + doubleBuffer); - System.out.println("FBO ID: " + fbId); - System.out.println("Is proper? " + GLES20.glIsFramebuffer(fbId)); -// System.out.println("Is bound to draw? " + (fbId == curDrawBinding)); -// System.out.println("Is bound to read? " + (fbId == curReadBinding)); -// System.out.println("Draw buffer: " + drawBuf); -// System.out.println("Read buffer: " + readBuf); - - if (context.boundFBO != fbId) { - GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fbId); - context.boundFBO = fbId; - } - - if (fb.getDepthBuffer() != null) { - printRealRenderBufferInfo(fb, fb.getDepthBuffer(), "Depth"); - } - for (int i = 0; i < fb.getNumColorBuffers(); i++) { - printRealRenderBufferInfo(fb, fb.getColorBuffer(i), "Color" + i); - } - } - - private void updateRenderBuffer(FrameBuffer fb, RenderBuffer rb) { - int id = rb.getId(); - if (id == -1) { - GLES20.glGenRenderbuffers(1, intBuf1); - RendererUtil.checkGLError(); - - id = intBuf1.get(0); - rb.setId(id); - } - - if (context.boundRB != id) { - GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, id); - RendererUtil.checkGLError(); - - context.boundRB = id; - } - - if (fb.getWidth() > maxRBSize || fb.getHeight() > maxRBSize) { - throw new RendererException("Resolution " + fb.getWidth() - + ":" + fb.getHeight() + " is not supported."); - } - - AndroidGLImageFormat imageFormat = TextureUtil.getImageFormat(rb.getFormat(), true); - if (imageFormat.renderBufferStorageFormat == 0) { - throw new RendererException("The format '" + rb.getFormat() + "' cannot be used for renderbuffers."); - } - -// if (fb.getSamples() > 1 && GLContext.getCapabilities().GL_EXT_framebuffer_multisample) { - if (fb.getSamples() > 1) { -// // FIXME - throw new RendererException("Multisample FrameBuffer is not supported yet."); -// int samples = fb.getSamples(); -// if (maxFBOSamples < samples) { -// samples = maxFBOSamples; -// } -// glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, -// samples, -// glFmt.internalFormat, -// fb.getWidth(), -// fb.getHeight()); - } else { - GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, - imageFormat.renderBufferStorageFormat, - fb.getWidth(), - fb.getHeight()); - - RendererUtil.checkGLError(); - } - } - - private int convertAttachmentSlot(int attachmentSlot) { - // can also add support for stencil here - if (attachmentSlot == FrameBuffer.SLOT_DEPTH) { - return GLES20.GL_DEPTH_ATTACHMENT; -// if (attachmentSlot == FrameBuffer.SLOT_DEPTH_STENCIL) { -// return GLES30.GL_DEPTH_STENCIL_ATTACHMENT; - } else if (attachmentSlot == 0) { - return GLES20.GL_COLOR_ATTACHMENT0; - } else { - throw new UnsupportedOperationException("Android does not support multiple color attachments to an FBO"); - } - } - - public void updateRenderTexture(FrameBuffer fb, RenderBuffer rb) { - Texture tex = rb.getTexture(); - Image image = tex.getImage(); - if (image.isUpdateNeeded()) { - updateTexImageData(image, tex.getType()); - - // NOTE: For depth textures, sets nearest/no-mips mode - // Required to fix "framebuffer unsupported" - // for old NVIDIA drivers! - setupTextureParams(tex); - } - - GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, - convertAttachmentSlot(rb.getSlot()), - convertTextureType(tex.getType()), - image.getId(), - 0); - - RendererUtil.checkGLError(); - } - - public void updateFrameBufferAttachment(FrameBuffer fb, RenderBuffer rb) { - boolean needAttach; - if (rb.getTexture() == null) { - // if it hasn't been created yet, then attach is required. - needAttach = rb.getId() == -1; - updateRenderBuffer(fb, rb); - } else { - needAttach = false; - updateRenderTexture(fb, rb); - } - if (needAttach) { - GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, - convertAttachmentSlot(rb.getSlot()), - GLES20.GL_RENDERBUFFER, - rb.getId()); - - RendererUtil.checkGLError(); - } - } - - public void updateFrameBuffer(FrameBuffer fb) { - int id = fb.getId(); - if (id == -1) { - intBuf1.clear(); - // create FBO - GLES20.glGenFramebuffers(1, intBuf1); - RendererUtil.checkGLError(); - - id = intBuf1.get(0); - fb.setId(id); - objManager.registerObject(fb); - - statistics.onNewFrameBuffer(); - } - - if (context.boundFBO != id) { - GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, id); - RendererUtil.checkGLError(); - - // binding an FBO automatically sets draw buf to GL_COLOR_ATTACHMENT0 - context.boundDrawBuf = 0; - context.boundFBO = id; - } - - FrameBuffer.RenderBuffer depthBuf = fb.getDepthBuffer(); - if (depthBuf != null) { - updateFrameBufferAttachment(fb, depthBuf); - } - - for (int i = 0; i < fb.getNumColorBuffers(); i++) { - FrameBuffer.RenderBuffer colorBuf = fb.getColorBuffer(i); - updateFrameBufferAttachment(fb, colorBuf); - } - - fb.clearUpdateNeeded(); - } - - public void setMainFrameBufferOverride(FrameBuffer fb){ - mainFbOverride = fb; - } - - public void setFrameBuffer(FrameBuffer fb) { - if (fb == null && mainFbOverride != null) { - fb = mainFbOverride; - } - - if (lastFb == fb) { - if (fb == null || !fb.isUpdateNeeded()) { - return; - } - } - - // generate mipmaps for last FB if needed - if (lastFb != null) { - for (int i = 0; i < lastFb.getNumColorBuffers(); i++) { - RenderBuffer rb = lastFb.getColorBuffer(i); - Texture tex = rb.getTexture(); - if (tex != null - && tex.getMinFilter().usesMipMapLevels()) { - setTexture(0, rb.getTexture()); - -// int textureType = convertTextureType(tex.getType(), tex.getImage().getMultiSamples(), rb.getFace()); - int textureType = convertTextureType(tex.getType()); - GLES20.glGenerateMipmap(textureType); - RendererUtil.checkGLError(); - } - } - } - - if (fb == null) { - // unbind any fbos - if (context.boundFBO != 0) { - GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); - RendererUtil.checkGLError(); - - statistics.onFrameBufferUse(null, true); - - context.boundFBO = 0; - } - - /* - // select back buffer - if (context.boundDrawBuf != -1) { - glDrawBuffer(initialDrawBuf); - context.boundDrawBuf = -1; - } - if (context.boundReadBuf != -1) { - glReadBuffer(initialReadBuf); - context.boundReadBuf = -1; - } - */ - - lastFb = null; - } else { - if (fb.getNumColorBuffers() == 0 && fb.getDepthBuffer() == null) { - throw new IllegalArgumentException("The framebuffer: " + fb - + "\nDoesn't have any color/depth buffers"); - } - - if (fb.isUpdateNeeded()) { - updateFrameBuffer(fb); - } - - if (context.boundFBO != fb.getId()) { - GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fb.getId()); - RendererUtil.checkGLError(); - - statistics.onFrameBufferUse(fb, true); - - // update viewport to reflect framebuffer's resolution - setViewPort(0, 0, fb.getWidth(), fb.getHeight()); - - context.boundFBO = fb.getId(); - } else { - statistics.onFrameBufferUse(fb, false); - } - if (fb.getNumColorBuffers() == 0) { -// // make sure to select NONE as draw buf -// // no color buffer attached. select NONE - if (context.boundDrawBuf != -2) { -// glDrawBuffer(GL_NONE); - context.boundDrawBuf = -2; - } - if (context.boundReadBuf != -2) { -// glReadBuffer(GL_NONE); - context.boundReadBuf = -2; - } - } else { - if (fb.getNumColorBuffers() > maxFBOAttachs) { - throw new RendererException("Framebuffer has more color " - + "attachments than are supported" - + " by the video hardware!"); - } - if (fb.isMultiTarget()) { - if (fb.getNumColorBuffers() > maxMRTFBOAttachs) { - throw new RendererException("Framebuffer has more" - + " multi targets than are supported" - + " by the video hardware!"); - } - - if (context.boundDrawBuf != 100 + fb.getNumColorBuffers()) { - intBuf16.clear(); - for (int i = 0; i < fb.getNumColorBuffers(); i++) { - intBuf16.put(GLES20.GL_COLOR_ATTACHMENT0 + i); - } - - intBuf16.flip(); -// glDrawBuffers(intBuf16); - context.boundDrawBuf = 100 + fb.getNumColorBuffers(); - } - } else { - RenderBuffer rb = fb.getColorBuffer(fb.getTargetIndex()); - // select this draw buffer - if (context.boundDrawBuf != rb.getSlot()) { - GLES20.glActiveTexture(convertAttachmentSlot(rb.getSlot())); - RendererUtil.checkGLError(); - - context.boundDrawBuf = rb.getSlot(); - } - } - } - - assert fb.getId() >= 0; - assert context.boundFBO == fb.getId(); - - lastFb = fb; - - checkFrameBufferStatus(fb); - } - } - - /** - * Reads the Color Buffer from OpenGL and stores into the ByteBuffer. - * Make sure to call setViewPort with the appropriate viewport size before - * calling readFrameBuffer. - * @param fb FrameBuffer - * @param byteBuf ByteBuffer to store the Color Buffer from OpenGL - */ - public void readFrameBuffer(FrameBuffer fb, ByteBuffer byteBuf) { - if (fb != null) { - RenderBuffer rb = fb.getColorBuffer(); - if (rb == null) { - throw new IllegalArgumentException("Specified framebuffer" - + " does not have a colorbuffer"); - } - - setFrameBuffer(fb); - } else { - setFrameBuffer(null); - } - - GLES20.glReadPixels(vpX, vpY, vpW, vpH, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, byteBuf); - RendererUtil.checkGLError(); - } - - private void deleteRenderBuffer(FrameBuffer fb, RenderBuffer rb) { - intBuf1.put(0, rb.getId()); - GLES20.glDeleteRenderbuffers(1, intBuf1); - RendererUtil.checkGLError(); - } - - public void deleteFrameBuffer(FrameBuffer fb) { - if (fb.getId() != -1) { - if (context.boundFBO == fb.getId()) { - GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); - RendererUtil.checkGLError(); - - context.boundFBO = 0; - } - - if (fb.getDepthBuffer() != null) { - deleteRenderBuffer(fb, fb.getDepthBuffer()); - } - if (fb.getColorBuffer() != null) { - deleteRenderBuffer(fb, fb.getColorBuffer()); - } - - intBuf1.put(0, fb.getId()); - GLES20.glDeleteFramebuffers(1, intBuf1); - RendererUtil.checkGLError(); - - fb.resetObject(); - - statistics.onDeleteFrameBuffer(); - } - } - - /*********************************************************************\ - |* Textures *| - \*********************************************************************/ - private int convertTextureType(Texture.Type type) { - switch (type) { - case TwoDimensional: - return GLES20.GL_TEXTURE_2D; - // case TwoDimensionalArray: - // return EXTTextureArray.GL_TEXTURE_2D_ARRAY_EXT; -// case ThreeDimensional: - // return GLES20.GL_TEXTURE_3D; - case CubeMap: - return GLES20.GL_TEXTURE_CUBE_MAP; - default: - throw new UnsupportedOperationException("Unknown texture type: " + type); - } - } - - private int convertMagFilter(Texture.MagFilter filter) { - switch (filter) { - case Bilinear: - return GLES20.GL_LINEAR; - case Nearest: - return GLES20.GL_NEAREST; - default: - throw new UnsupportedOperationException("Unknown mag filter: " + filter); - } - } - - private int convertMinFilter(Texture.MinFilter filter) { - switch (filter) { - case Trilinear: - return GLES20.GL_LINEAR_MIPMAP_LINEAR; - case BilinearNearestMipMap: - return GLES20.GL_LINEAR_MIPMAP_NEAREST; - case NearestLinearMipMap: - return GLES20.GL_NEAREST_MIPMAP_LINEAR; - case NearestNearestMipMap: - return GLES20.GL_NEAREST_MIPMAP_NEAREST; - case BilinearNoMipMaps: - return GLES20.GL_LINEAR; - case NearestNoMipMaps: - return GLES20.GL_NEAREST; - default: - throw new UnsupportedOperationException("Unknown min filter: " + filter); - } - } - - private int convertWrapMode(Texture.WrapMode mode) { - switch (mode) { - case BorderClamp: - case Clamp: - case EdgeClamp: - return GLES20.GL_CLAMP_TO_EDGE; - case Repeat: - return GLES20.GL_REPEAT; - case MirroredRepeat: - return GLES20.GL_MIRRORED_REPEAT; - default: - throw new UnsupportedOperationException("Unknown wrap mode: " + mode); - } - } - - /** - * setupTextureParams sets the OpenGL context texture parameters - * @param tex the Texture to set the texture parameters from - */ - private void setupTextureParams(Texture tex) { - int target = convertTextureType(tex.getType()); - - // filter things - int minFilter = convertMinFilter(tex.getMinFilter()); - int magFilter = convertMagFilter(tex.getMagFilter()); - - GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_MIN_FILTER, minFilter); - GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_MAG_FILTER, magFilter); - RendererUtil.checkGLError(); - - /* - if (tex.getAnisotropicFilter() > 1){ - - if (GLContext.getCapabilities().GL_EXT_texture_filter_anisotropic){ - glTexParameterf(target, - EXTTextureFilterAnisotropic.GL_TEXTURE_MAX_ANISOTROPY_EXT, - tex.getAnisotropicFilter()); - } - - } - */ - // repeat modes - - switch (tex.getType()) { - case ThreeDimensional: - case CubeMap: // cubemaps use 3D coords - // GL_TEXTURE_WRAP_R is not available in api 8 - //GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_WRAP_R, convertWrapMode(tex.getWrap(WrapAxis.R))); - case TwoDimensional: - case TwoDimensionalArray: - GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_WRAP_T, convertWrapMode(tex.getWrap(WrapAxis.T))); - - // fall down here is intentional.. -// case OneDimensional: - GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_WRAP_S, convertWrapMode(tex.getWrap(WrapAxis.S))); - - RendererUtil.checkGLError(); - break; - default: - throw new UnsupportedOperationException("Unknown texture type: " + tex.getType()); - } - - // R to Texture compare mode -/* - if (tex.getShadowCompareMode() != Texture.ShadowCompareMode.Off){ - GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_COMPARE_MODE, GLES20.GL_COMPARE_R_TO_TEXTURE); - GLES20.glTexParameteri(target, GLES20.GL_DEPTH_TEXTURE_MODE, GLES20.GL_INTENSITY); - if (tex.getShadowCompareMode() == Texture.ShadowCompareMode.GreaterOrEqual){ - GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_COMPARE_FUNC, GLES20.GL_GEQUAL); - }else{ - GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_COMPARE_FUNC, GLES20.GL_LEQUAL); - } - } - */ - } - - /** - * activates and binds the texture - * @param img - * @param type - */ - public void updateTexImageData(Image img, Texture.Type type) { - int texId = img.getId(); - if (texId == -1) { - // create texture - GLES20.glGenTextures(1, intBuf1); - RendererUtil.checkGLError(); - - texId = intBuf1.get(0); - img.setId(texId); - objManager.registerObject(img); - - statistics.onNewTexture(); - } - - // bind texture - int target = convertTextureType(type); - if (context.boundTextures[0] != img) { - if (context.boundTextureUnit != 0) { - GLES20.glActiveTexture(GLES20.GL_TEXTURE0); - RendererUtil.checkGLError(); - - context.boundTextureUnit = 0; - } - - GLES20.glBindTexture(target, texId); - RendererUtil.checkGLError(); - - context.boundTextures[0] = img; - } - - boolean needMips = false; - if (img.isGeneratedMipmapsRequired()) { - needMips = true; - img.setMipmapsGenerated(true); - } - - if (target == GLES20.GL_TEXTURE_CUBE_MAP) { - // Check max texture size before upload - if (img.getWidth() > maxCubeTexSize || img.getHeight() > maxCubeTexSize) { - throw new RendererException("Cannot upload cubemap " + img + ". The maximum supported cubemap resolution is " + maxCubeTexSize); - } - } else { - if (img.getWidth() > maxTexSize || img.getHeight() > maxTexSize) { - throw new RendererException("Cannot upload texture " + img + ". The maximum supported texture resolution is " + maxTexSize); - } - } - - if (target == GLES20.GL_TEXTURE_CUBE_MAP) { - // Upload a cube map / sky box - @SuppressWarnings("unchecked") - List bmps = (List) img.getEfficentData(); - if (bmps != null) { - // Native android bitmap - if (bmps.size() != 6) { - throw new UnsupportedOperationException("Invalid texture: " + img - + "Cubemap textures must contain 6 data units."); - } - for (int i = 0; i < 6; i++) { - TextureUtil.uploadTextureBitmap(GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, bmps.get(i).getBitmap(), needMips); - bmps.get(i).notifyBitmapUploaded(); - } - } else { - // Standard jme3 image data - List data = img.getData(); - if (data.size() != 6) { - throw new UnsupportedOperationException("Invalid texture: " + img - + "Cubemap textures must contain 6 data units."); - } - for (int i = 0; i < 6; i++) { - TextureUtil.uploadTextureAny(img, GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, i, needMips); - } - } - } else { - TextureUtil.uploadTextureAny(img, target, 0, needMips); - if (img.getEfficentData() instanceof AndroidImageInfo) { - AndroidImageInfo info = (AndroidImageInfo) img.getEfficentData(); - info.notifyBitmapUploaded(); - } - } - - img.clearUpdateNeeded(); - } - - public void setTexture(int unit, Texture tex) { - Image image = tex.getImage(); - if (image.isUpdateNeeded() || (image.isGeneratedMipmapsRequired() && !image.isMipmapsGenerated()) ) { - updateTexImageData(image, tex.getType()); - } - - int texId = image.getId(); - assert texId != -1; - - if (texId == -1) { - logger.warning("error: texture image has -1 id"); - } - - Image[] textures = context.boundTextures; - - int type = convertTextureType(tex.getType()); -// if (!context.textureIndexList.moveToNew(unit)) { -// if (context.boundTextureUnit != unit){ -// glActiveTexture(GL_TEXTURE0 + unit); -// context.boundTextureUnit = unit; -// } -// glEnable(type); -// } - - if (textures[unit] != image) { - if (context.boundTextureUnit != unit) { - GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + unit); - context.boundTextureUnit = unit; - } - - GLES20.glBindTexture(type, texId); - RendererUtil.checkGLError(); - - textures[unit] = image; - - statistics.onTextureUse(tex.getImage(), true); - } else { - statistics.onTextureUse(tex.getImage(), false); - } - - setupTextureParams(tex); - } - - public void modifyTexture(Texture tex, Image pixels, int x, int y) { - setTexture(0, tex); - TextureUtil.uploadSubTexture(pixels, convertTextureType(tex.getType()), 0, x, y); - } - - public void deleteImage(Image image) { - int texId = image.getId(); - if (texId != -1) { - intBuf1.put(0, texId); - intBuf1.position(0).limit(1); - - GLES20.glDeleteTextures(1, intBuf1); - RendererUtil.checkGLError(); - - image.resetObject(); - - statistics.onDeleteTexture(); - } - } - - /*********************************************************************\ - |* Vertex Buffers and Attributes *| - \*********************************************************************/ - private int convertUsage(Usage usage) { - switch (usage) { - case Static: - return GLES20.GL_STATIC_DRAW; - case Dynamic: - return GLES20.GL_DYNAMIC_DRAW; - case Stream: - return GLES20.GL_STREAM_DRAW; - default: - throw new RuntimeException("Unknown usage type."); - } - } - - private int convertVertexBufferFormat(Format format) { - switch (format) { - case Byte: - return GLES20.GL_BYTE; - case UnsignedByte: - return GLES20.GL_UNSIGNED_BYTE; - case Short: - return GLES20.GL_SHORT; - case UnsignedShort: - return GLES20.GL_UNSIGNED_SHORT; - case Int: - return GLES20.GL_INT; - case UnsignedInt: - return GLES20.GL_UNSIGNED_INT; - /* - case Half: - return NVHalfFloat.GL_HALF_FLOAT_NV; - // return ARBHalfFloatVertex.GL_HALF_FLOAT; - */ - case Float: - return GLES20.GL_FLOAT; -// case Double: -// return GLES20.GL_DOUBLE; - default: - throw new RuntimeException("Unknown buffer format."); - - } - } - - public void updateBufferData(VertexBuffer vb) { - int bufId = vb.getId(); - boolean created = false; - if (bufId == -1) { - // create buffer - GLES20.glGenBuffers(1, intBuf1); - RendererUtil.checkGLError(); - - bufId = intBuf1.get(0); - vb.setId(bufId); - objManager.registerObject(vb); - - created = true; - } - - // bind buffer - int target; - if (vb.getBufferType() == VertexBuffer.Type.Index) { - target = GLES20.GL_ELEMENT_ARRAY_BUFFER; - if (context.boundElementArrayVBO != bufId) { - GLES20.glBindBuffer(target, bufId); - RendererUtil.checkGLError(); - - context.boundElementArrayVBO = bufId; - } - } else { - target = GLES20.GL_ARRAY_BUFFER; - if (context.boundArrayVBO != bufId) { - GLES20.glBindBuffer(target, bufId); - RendererUtil.checkGLError(); - - context.boundArrayVBO = bufId; - } - } - - int usage = convertUsage(vb.getUsage()); - vb.getData().rewind(); - - // if (created || vb.hasDataSizeChanged()) { - // upload data based on format - int size = vb.getData().limit() * vb.getFormat().getComponentSize(); - - switch (vb.getFormat()) { - case Byte: - case UnsignedByte: - GLES20.glBufferData(target, size, (ByteBuffer) vb.getData(), usage); - RendererUtil.checkGLError(); - break; - case Short: - case UnsignedShort: - GLES20.glBufferData(target, size, (ShortBuffer) vb.getData(), usage); - RendererUtil.checkGLError(); - break; - case Int: - case UnsignedInt: - GLES20.glBufferData(target, size, (IntBuffer) vb.getData(), usage); - RendererUtil.checkGLError(); - break; - case Float: - GLES20.glBufferData(target, size, (FloatBuffer) vb.getData(), usage); - RendererUtil.checkGLError(); - break; - default: - throw new RuntimeException("Unknown buffer format."); - } -// } else { -// int size = vb.getData().limit() * vb.getFormat().getComponentSize(); -// -// switch (vb.getFormat()) { -// case Byte: -// case UnsignedByte: -// GLES20.glBufferSubData(target, 0, size, (ByteBuffer) vb.getData()); -// RendererUtil.checkGLError(); -// break; -// case Short: -// case UnsignedShort: -// GLES20.glBufferSubData(target, 0, size, (ShortBuffer) vb.getData()); -// RendererUtil.checkGLError(); -// break; -// case Int: -// case UnsignedInt: -// GLES20.glBufferSubData(target, 0, size, (IntBuffer) vb.getData()); -// RendererUtil.checkGLError(); -// break; -// case Float: -// GLES20.glBufferSubData(target, 0, size, (FloatBuffer) vb.getData()); -// RendererUtil.checkGLError(); -// break; -// default: -// throw new RuntimeException("Unknown buffer format."); -// } -// } - vb.clearUpdateNeeded(); - } - - public void deleteBuffer(VertexBuffer vb) { - int bufId = vb.getId(); - if (bufId != -1) { - // delete buffer - intBuf1.put(0, bufId); - intBuf1.position(0).limit(1); - - GLES20.glDeleteBuffers(1, intBuf1); - RendererUtil.checkGLError(); - - vb.resetObject(); - } - } - - public void clearVertexAttribs() { - IDList attribList = context.attribIndexList; - for (int i = 0; i < attribList.oldLen; i++) { - int idx = attribList.oldList[i]; - - GLES20.glDisableVertexAttribArray(idx); - RendererUtil.checkGLError(); - - context.boundAttribs[idx] = null; - } - context.attribIndexList.copyNewToOld(); - } - - public void setVertexAttrib(VertexBuffer vb, VertexBuffer idb) { - if (vb.getBufferType() == VertexBuffer.Type.Index) { - throw new IllegalArgumentException("Index buffers not allowed to be set to vertex attrib"); - } - - if (vb.isUpdateNeeded() && idb == null) { - updateBufferData(vb); - } - - int programId = context.boundShaderProgram; - if (programId > 0) { - Attribute attrib = boundShader.getAttribute(vb.getBufferType()); - int loc = attrib.getLocation(); - if (loc == -1) { - return; // not defined - } - - if (loc == -2) { -// stringBuf.setLength(0); -// stringBuf.append("in").append(vb.getBufferType().name()).append('\0'); -// updateNameBuffer(); - - String attributeName = "in" + vb.getBufferType().name(); - loc = GLES20.glGetAttribLocation(programId, attributeName); - RendererUtil.checkGLError(); - - // not really the name of it in the shader (inPosition\0) but - // the internal name of the enum (Position). - if (loc < 0) { - attrib.setLocation(-1); - return; // not available in shader. - } else { - attrib.setLocation(loc); - } - } - - VertexBuffer[] attribs = context.boundAttribs; - if (!context.attribIndexList.moveToNew(loc)) { - GLES20.glEnableVertexAttribArray(loc); - RendererUtil.checkGLError(); - //System.out.println("Enabled ATTRIB IDX: "+loc); - } - if (attribs[loc] != vb) { - // NOTE: Use id from interleaved buffer if specified - int bufId = idb != null ? idb.getId() : vb.getId(); - assert bufId != -1; - - if (bufId == -1) { - logger.warning("invalid buffer id"); - } - - if (context.boundArrayVBO != bufId) { - GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, bufId); - RendererUtil.checkGLError(); - - context.boundArrayVBO = bufId; - } - - vb.getData().rewind(); - - GLES20.glVertexAttribPointer(loc, - vb.getNumComponents(), - convertVertexBufferFormat(vb.getFormat()), - vb.isNormalized(), - vb.getStride(), - 0); - - RendererUtil.checkGLError(); - - attribs[loc] = vb; - } - } else { - throw new IllegalStateException("Cannot render mesh without shader bound"); - } - } - - public void setVertexAttrib(VertexBuffer vb) { - setVertexAttrib(vb, null); - } - - public void drawTriangleArray(Mesh.Mode mode, int count, int vertCount) { - /* if (count > 1){ - ARBDrawInstanced.glDrawArraysInstancedARB(convertElementMode(mode), 0, - vertCount, count); - }else{*/ - GLES20.glDrawArrays(convertElementMode(mode), 0, vertCount); - RendererUtil.checkGLError(); - /* - }*/ - } - - public void drawTriangleList(VertexBuffer indexBuf, Mesh mesh, int count) { - if (indexBuf.getBufferType() != VertexBuffer.Type.Index) { - throw new IllegalArgumentException("Only index buffers are allowed as triangle lists."); - } - - if (indexBuf.isUpdateNeeded()) { - updateBufferData(indexBuf); - } - - int bufId = indexBuf.getId(); - assert bufId != -1; - - if (bufId == -1) { - throw new RendererException("Invalid buffer ID"); - } - - if (context.boundElementArrayVBO != bufId) { - GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, bufId); - RendererUtil.checkGLError(); - - context.boundElementArrayVBO = bufId; - } - - int vertCount = mesh.getVertexCount(); - boolean useInstancing = count > 1 && caps.contains(Caps.MeshInstancing); - - Buffer indexData = indexBuf.getData(); - - if (indexBuf.getFormat() == Format.UnsignedInt) { - throw new RendererException("OpenGL ES does not support 32-bit index buffers." + - "Split your models to avoid going over 65536 vertices."); - } - - if (mesh.getMode() == Mode.Hybrid) { - int[] modeStart = mesh.getModeStart(); - int[] elementLengths = mesh.getElementLengths(); - - int elMode = convertElementMode(Mode.Triangles); - int fmt = convertVertexBufferFormat(indexBuf.getFormat()); - int elSize = indexBuf.getFormat().getComponentSize(); - int listStart = modeStart[0]; - int stripStart = modeStart[1]; - int fanStart = modeStart[2]; - int curOffset = 0; - for (int i = 0; i < elementLengths.length; i++) { - if (i == stripStart) { - elMode = convertElementMode(Mode.TriangleStrip); - } else if (i == fanStart) { - elMode = convertElementMode(Mode.TriangleStrip); - } - int elementLength = elementLengths[i]; - - if (useInstancing) { - //ARBDrawInstanced. - throw new IllegalArgumentException("instancing is not supported."); - /* - GLES20.glDrawElementsInstancedARB(elMode, - elementLength, - fmt, - curOffset, - count); - */ - } else { - indexBuf.getData().position(curOffset); - GLES20.glDrawElements(elMode, elementLength, fmt, indexBuf.getData()); - RendererUtil.checkGLError(); - /* - glDrawRangeElements(elMode, - 0, - vertCount, - elementLength, - fmt, - curOffset); - */ - } - - curOffset += elementLength * elSize; - } - } else { - if (useInstancing) { - throw new IllegalArgumentException("instancing is not supported."); - //ARBDrawInstanced. -/* - GLES20.glDrawElementsInstancedARB(convertElementMode(mesh.getMode()), - indexBuf.getData().limit(), - convertVertexBufferFormat(indexBuf.getFormat()), - 0, - count); - */ - } else { - indexData.rewind(); - GLES20.glDrawElements( - convertElementMode(mesh.getMode()), - indexBuf.getData().limit(), - convertVertexBufferFormat(indexBuf.getFormat()), - 0); - RendererUtil.checkGLError(); - } - } - } - - /*********************************************************************\ - |* Render Calls *| - \*********************************************************************/ - public int convertElementMode(Mesh.Mode mode) { - switch (mode) { - case Points: - return GLES20.GL_POINTS; - case Lines: - return GLES20.GL_LINES; - case LineLoop: - return GLES20.GL_LINE_LOOP; - case LineStrip: - return GLES20.GL_LINE_STRIP; - case Triangles: - return GLES20.GL_TRIANGLES; - case TriangleFan: - return GLES20.GL_TRIANGLE_FAN; - case TriangleStrip: - return GLES20.GL_TRIANGLE_STRIP; - default: - throw new UnsupportedOperationException("Unrecognized mesh mode: " + mode); - } - } - - public void updateVertexArray(Mesh mesh) { - logger.log(Level.FINE, "updateVertexArray({0})", mesh); - int id = mesh.getId(); - /* - if (id == -1){ - IntBuffer temp = intBuf1; - // ARBVertexArrayObject.glGenVertexArrays(temp); - GLES20.glGenVertexArrays(temp); - id = temp.get(0); - mesh.setId(id); - } - - if (context.boundVertexArray != id){ - // ARBVertexArrayObject.glBindVertexArray(id); - GLES20.glBindVertexArray(id); - context.boundVertexArray = id; - } - */ - VertexBuffer interleavedData = mesh.getBuffer(Type.InterleavedData); - if (interleavedData != null && interleavedData.isUpdateNeeded()) { - updateBufferData(interleavedData); - } - - - for (VertexBuffer vb : mesh.getBufferList().getArray()){ - - if (vb.getBufferType() == Type.InterleavedData - || vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers - || vb.getBufferType() == Type.Index) { - continue; - } - - if (vb.getStride() == 0) { - // not interleaved - setVertexAttrib(vb); - } else { - // interleaved - setVertexAttrib(vb, interleavedData); - } - } - } - - /** - * renderMeshVertexArray renders a mesh using vertex arrays - */ - private void renderMeshVertexArray(Mesh mesh, int lod, int count) { - for (VertexBuffer vb : mesh.getBufferList().getArray()) { - if (vb.getBufferType() == Type.InterleavedData - || vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers - || vb.getBufferType() == Type.Index) { - continue; - } - - if (vb.getStride() == 0) { - // not interleaved - setVertexAttrib_Array(vb); - } else { - // interleaved - VertexBuffer interleavedData = mesh.getBuffer(Type.InterleavedData); - setVertexAttrib_Array(vb, interleavedData); - } - } - - VertexBuffer indices; - if (mesh.getNumLodLevels() > 0) { - indices = mesh.getLodLevel(lod); - } else { - indices = mesh.getBuffer(Type.Index);//buffers.get(Type.Index.ordinal()); - } - if (indices != null) { - drawTriangleList_Array(indices, mesh, count); - } else { - GLES20.glDrawArrays(convertElementMode(mesh.getMode()), 0, mesh.getVertexCount()); - RendererUtil.checkGLError(); - } - clearVertexAttribs(); - } - - private void renderMeshDefault(Mesh mesh, int lod, int count) { - VertexBuffer indices; - VertexBuffer interleavedData = mesh.getBuffer(Type.InterleavedData); - if (interleavedData != null && interleavedData.isUpdateNeeded()) { - updateBufferData(interleavedData); - } - - //IntMap buffers = mesh.getBuffers(); ; - if (mesh.getNumLodLevels() > 0) { - indices = mesh.getLodLevel(lod); - } else { - indices = mesh.getBuffer(Type.Index);// buffers.get(Type.Index.ordinal()); - } - for (VertexBuffer vb : mesh.getBufferList().getArray()){ - if (vb.getBufferType() == Type.InterleavedData - || vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers - || vb.getBufferType() == Type.Index) { - continue; - } - - if (vb.getStride() == 0) { - // not interleaved - setVertexAttrib(vb); - } else { - // interleaved - setVertexAttrib(vb, interleavedData); - } - } - if (indices != null) { - drawTriangleList(indices, mesh, count); - } else { -// throw new UnsupportedOperationException("Cannot render without index buffer"); - GLES20.glDrawArrays(convertElementMode(mesh.getMode()), 0, mesh.getVertexCount()); - RendererUtil.checkGLError(); - } - clearVertexAttribs(); - } - - public void renderMesh(Mesh mesh, int lod, int count, VertexBuffer[] instanceData) { - if (mesh.getVertexCount() == 0) { - return; - } - - /* - * NOTE: not supported in OpenGL ES 2.0. - if (context.pointSize != mesh.getPointSize()) { - GLES10.glPointSize(mesh.getPointSize()); - context.pointSize = mesh.getPointSize(); - } - */ - if (context.lineWidth != mesh.getLineWidth()) { - GLES20.glLineWidth(mesh.getLineWidth()); - RendererUtil.checkGLError(); - context.lineWidth = mesh.getLineWidth(); - } - - statistics.onMeshDrawn(mesh, lod); -// if (GLContext.getCapabilities().GL_ARB_vertex_array_object){ -// renderMeshVertexArray(mesh, lod, count); -// }else{ - - if (useVBO) { - renderMeshDefault(mesh, lod, count); - } else { - renderMeshVertexArray(mesh, lod, count); - } - } - - /** - * drawTriangleList_Array uses Vertex Array - * @param indexBuf - * @param mesh - * @param count - */ - public void drawTriangleList_Array(VertexBuffer indexBuf, Mesh mesh, int count) { - if (indexBuf.getBufferType() != VertexBuffer.Type.Index) { - throw new IllegalArgumentException("Only index buffers are allowed as triangle lists."); - } - - boolean useInstancing = count > 1 && caps.contains(Caps.MeshInstancing); - if (useInstancing) { - throw new IllegalArgumentException("Caps.MeshInstancing is not supported."); - } - - int vertCount = mesh.getVertexCount(); - Buffer indexData = indexBuf.getData(); - indexData.rewind(); - - if (mesh.getMode() == Mode.Hybrid) { - int[] modeStart = mesh.getModeStart(); - int[] elementLengths = mesh.getElementLengths(); - - int elMode = convertElementMode(Mode.Triangles); - int fmt = convertVertexBufferFormat(indexBuf.getFormat()); - int elSize = indexBuf.getFormat().getComponentSize(); - int listStart = modeStart[0]; - int stripStart = modeStart[1]; - int fanStart = modeStart[2]; - int curOffset = 0; - for (int i = 0; i < elementLengths.length; i++) { - if (i == stripStart) { - elMode = convertElementMode(Mode.TriangleStrip); - } else if (i == fanStart) { - elMode = convertElementMode(Mode.TriangleFan); - } - int elementLength = elementLengths[i]; - - indexBuf.getData().position(curOffset); - GLES20.glDrawElements(elMode, elementLength, fmt, indexBuf.getData()); - RendererUtil.checkGLError(); - - curOffset += elementLength * elSize; - } - } else { - GLES20.glDrawElements( - convertElementMode(mesh.getMode()), - indexBuf.getData().limit(), - convertVertexBufferFormat(indexBuf.getFormat()), - indexBuf.getData()); - RendererUtil.checkGLError(); - } - } - - /** - * setVertexAttrib_Array uses Vertex Array - * @param vb - * @param idb - */ - public void setVertexAttrib_Array(VertexBuffer vb, VertexBuffer idb) { - if (vb.getBufferType() == VertexBuffer.Type.Index) { - throw new IllegalArgumentException("Index buffers not allowed to be set to vertex attrib"); - } - - // Get shader - int programId = context.boundShaderProgram; - if (programId > 0) { - VertexBuffer[] attribs = context.boundAttribs; - - Attribute attrib = boundShader.getAttribute(vb.getBufferType()); - int loc = attrib.getLocation(); - if (loc == -1) { - //throw new IllegalArgumentException("Location is invalid for attrib: [" + vb.getBufferType().name() + "]"); - return; - } else if (loc == -2) { - String attributeName = "in" + vb.getBufferType().name(); - - loc = GLES20.glGetAttribLocation(programId, attributeName); - RendererUtil.checkGLError(); - - if (loc < 0) { - attrib.setLocation(-1); - return; // not available in shader. - } else { - attrib.setLocation(loc); - } - - } // if (loc == -2) - - if ((attribs[loc] != vb) || vb.isUpdateNeeded()) { - // NOTE: Use data from interleaved buffer if specified - VertexBuffer avb = idb != null ? idb : vb; - avb.getData().rewind(); - avb.getData().position(vb.getOffset()); - - // Upload attribute data - GLES20.glVertexAttribPointer(loc, - vb.getNumComponents(), - convertVertexBufferFormat(vb.getFormat()), - vb.isNormalized(), - vb.getStride(), - avb.getData()); - - RendererUtil.checkGLError(); - - GLES20.glEnableVertexAttribArray(loc); - RendererUtil.checkGLError(); - - attribs[loc] = vb; - } // if (attribs[loc] != vb) - } else { - throw new IllegalStateException("Cannot render mesh without shader bound"); - } - } - - /** - * setVertexAttrib_Array uses Vertex Array - * @param vb - */ - public void setVertexAttrib_Array(VertexBuffer vb) { - setVertexAttrib_Array(vb, null); - } - - public void setAlphaToCoverage(boolean value) { - if (value) { - GLES20.glEnable(GLES20.GL_SAMPLE_ALPHA_TO_COVERAGE); - RendererUtil.checkGLError(); - } else { - GLES20.glDisable(GLES20.GL_SAMPLE_ALPHA_TO_COVERAGE); - RendererUtil.checkGLError(); - } - } - - @Override - public void invalidateState() { - context.reset(); - boundShader = null; - lastFb = null; - } - - public void setMainFrameBufferSrgb(boolean srgb) { - //TODO once opglES3.0 is supported maybe.... - } - - public void setLinearizeSrgbImages(boolean linearize) { - //TODO once opglES3.0 is supported maybe.... - } - - public void readFrameBufferWithFormat(FrameBuffer fb, ByteBuffer byteBuf, Image.Format format) { - throw new UnsupportedOperationException("Not supported yet. URA will make that work seamlessly"); - } -} diff --git a/jme3-blender/build.gradle b/jme3-blender/build.gradle index 1b42c7109..a556d7a65 100644 --- a/jme3-blender/build.gradle +++ b/jme3-blender/build.gradle @@ -6,4 +6,7 @@ dependencies { compile project(':jme3-core') compile project(':jme3-desktop') compile project(':jme3-effects') -} + compile ('org.ejml:core:0.27') + compile ('org.ejml:dense64:0.27') + compile ('org.ejml:simple:0.27') +} \ No newline at end of file diff --git a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/animations/Ipo.java b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/animations/Ipo.java index f5113129f..6665752b7 100644 --- a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/animations/Ipo.java +++ b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/animations/Ipo.java @@ -145,7 +145,7 @@ public class Ipo { float[] times = new float[framesAmount + 1]; Vector3f[] translations = new Vector3f[framesAmount + 1]; - float[] translation = new float[] { localTranslation.x, localTranslation.y, localTranslation.z }; + float[] translation = new float[3]; Quaternion[] rotations = new Quaternion[framesAmount + 1]; float[] quaternionRotation = new float[] { localRotation.getX(), localRotation.getY(), localRotation.getZ(), localRotation.getW(), }; float[] eulerRotation = localRotation.toAngles(null); @@ -165,6 +165,8 @@ public class Ipo { // calculating track data for (int frame = startFrame; frame <= stopFrame; ++frame) { + boolean translationSet = false; + translation[0] = translation[1] = translation[2] = 0; int index = frame - startFrame; times[index] = index * timeBetweenFrames;// start + (frame - 1) * timeBetweenFrames; for (int j = 0; j < bezierCurves.length; ++j) { @@ -173,15 +175,18 @@ public class Ipo { // LOCATION case AC_LOC_X: translation[0] = (float) value; + translationSet = true; break; case AC_LOC_Y: if (swapAxes && value != 0) { value = -value; } translation[yIndex] = (float) value; + translationSet = true; break; case AC_LOC_Z: translation[zIndex] = (float) value; + translationSet = true; break; // EULER ROTATION @@ -235,7 +240,11 @@ public class Ipo { LOGGER.log(Level.WARNING, "Unknown ipo curve type: {0}.", bezierCurves[j].getType()); } } - translations[index] = localRotation.multLocal(new Vector3f(translation[0], translation[1], translation[2])); + if(translationSet) { + translations[index] = localRotation.multLocal(new Vector3f(translation[0], translation[1], translation[2])); + } else { + translations[index] = new Vector3f(); + } if(boneContext != null) { if(boneContext.getBone().getParent() == null && boneContext.is(BoneContext.NO_LOCAL_LOCATION)) { diff --git a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/constraints/Constraint.java b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/constraints/Constraint.java index 91cfd2f3f..f2268199c 100644 --- a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/constraints/Constraint.java +++ b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/constraints/Constraint.java @@ -64,7 +64,7 @@ public abstract class Constraint { Pointer pData = (Pointer) constraintStructure.getFieldValue("data"); if (pData.isNotNull()) { Structure data = pData.fetchData().get(0); - constraintDefinition = ConstraintDefinitionFactory.createConstraintDefinition(data, ownerOMA, blenderContext); + constraintDefinition = ConstraintDefinitionFactory.createConstraintDefinition(data, name, ownerOMA, blenderContext); Pointer pTar = (Pointer) data.getFieldValue("tar"); if (pTar != null && pTar.isNotNull()) { targetOMA = pTar.getOldMemoryAddress(); @@ -77,7 +77,7 @@ public abstract class Constraint { } } else { // Null constraint has no data, so create it here - constraintDefinition = ConstraintDefinitionFactory.createConstraintDefinition(null, null, blenderContext); + constraintDefinition = ConstraintDefinitionFactory.createConstraintDefinition(null, name, null, blenderContext); } ownerSpace = Space.valueOf(((Number) constraintStructure.getFieldValue("ownspace")).byteValue()); ipo = influenceIpo; diff --git a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/constraints/SimulationNode.java b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/constraints/SimulationNode.java index 031676b94..711e0a338 100644 --- a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/constraints/SimulationNode.java +++ b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/constraints/SimulationNode.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.Stack; import java.util.logging.Logger; import com.jme3.animation.AnimChannel; @@ -38,9 +39,9 @@ import com.jme3.util.TempVars; * @author Marcin Roguski (Kaelthas) */ public class SimulationNode { - private static final Logger LOGGER = Logger.getLogger(SimulationNode.class.getName()); + private static final Logger LOGGER = Logger.getLogger(SimulationNode.class.getName()); - private Long featureOMA; + private Long featureOMA; /** The blender context. */ private BlenderContext blenderContext; /** The name of the node (for debugging purposes). */ @@ -51,11 +52,11 @@ public class SimulationNode { private List animations; /** The nodes spatial (if null then the boneContext should be set). */ - private Spatial spatial; + private Spatial spatial; /** The skeleton of the bone (not null if the node simulated the bone). */ - private Skeleton skeleton; + private Skeleton skeleton; /** Animation controller for the node's feature. */ - private AnimControl animControl; + private AnimControl animControl; /** * The star transform of a spatial. Needed to properly reset the spatial to @@ -64,7 +65,7 @@ public class SimulationNode { private Transform spatialStartTransform; /** Star transformations for bones. Needed to properly reset the bones. */ private Map boneStartTransforms; - + /** * Builds the nodes tree for the given feature. The feature (bone or * spatial) is found by its OMA. The feature must be a root bone or a root @@ -208,8 +209,7 @@ public class SimulationNode { if (animations != null) { TempVars vars = TempVars.get(); AnimChannel animChannel = animControl.createChannel(); - - // List bonesWithConstraints = this.collectBonesWithConstraints(skeleton); + for (Animation animation : animations) { float[] animationTimeBoundaries = this.computeAnimationTimeBoundaries(animation); int maxFrame = (int) animationTimeBoundaries[0]; @@ -233,7 +233,7 @@ public class SimulationNode { for (Bone rootBone : skeleton.getRoots()) { // ignore the 0-indexed bone if (skeleton.getBoneIndex(rootBone) > 0) { - this.applyConstraints(rootBone, alteredOmas, applied, frame); + this.applyConstraints(rootBone, alteredOmas, applied, frame, new Stack()); } } @@ -294,34 +294,39 @@ public class SimulationNode { * the set of OMAS of the altered bones (is populated if necessary) * @param frame * the current frame of the animation + * @param bonesStack + * the stack of bones used to avoid infinite loops while applying constraints */ - private void applyConstraints(Bone bone, Set alteredOmas, Set applied, int frame) { - BoneContext boneContext = blenderContext.getBoneContext(bone); - if(!applied.contains(boneContext.getBoneOma())) { - List constraints = this.findConstraints(boneContext.getBoneOma(), blenderContext); - if (constraints != null && constraints.size() > 0) { - // TODO: BEWARE OF INFINITE LOOPS !!!!!!!!!!!!!!!!!!!!!!!!!! - for (Constraint constraint : constraints) { - if (constraint.getTargetOMA() != null && constraint.getTargetOMA() > 0L) { - // first apply constraints of the target bone - BoneContext targetBone = blenderContext.getBoneContext(constraint.getTargetOMA()); - this.applyConstraints(targetBone.getBone(), alteredOmas, applied, frame); - } - constraint.apply(frame); - if (constraint.getAlteredOmas() != null) { - alteredOmas.addAll(constraint.getAlteredOmas()); + private void applyConstraints(Bone bone, Set alteredOmas, Set applied, int frame, Stack bonesStack) { + if (!bonesStack.contains(bone)) { + bonesStack.push(bone); + BoneContext boneContext = blenderContext.getBoneContext(bone); + if (!applied.contains(boneContext.getBoneOma())) { + List constraints = this.findConstraints(boneContext.getBoneOma(), blenderContext); + if (constraints != null && constraints.size() > 0) { + for (Constraint constraint : constraints) { + if (constraint.getTargetOMA() != null && constraint.getTargetOMA() > 0L) { + // first apply constraints of the target bone + BoneContext targetBone = blenderContext.getBoneContext(constraint.getTargetOMA()); + this.applyConstraints(targetBone.getBone(), alteredOmas, applied, frame, bonesStack); + } + constraint.apply(frame); + if (constraint.getAlteredOmas() != null) { + alteredOmas.addAll(constraint.getAlteredOmas()); + } + alteredOmas.add(boneContext.getBoneOma()); } - alteredOmas.add(boneContext.getBoneOma()); } + applied.add(boneContext.getBoneOma()); } - applied.add(boneContext.getBoneOma()); - } - - List children = bone.getChildren(); - if (children != null && children.size() > 0) { - for (Bone child : bone.getChildren()) { - this.applyConstraints(child, alteredOmas, applied, frame); + + List children = bone.getChildren(); + if (children != null && children.size() > 0) { + for (Bone child : bone.getChildren()) { + this.applyConstraints(child, alteredOmas, applied, frame, bonesStack); + } } + bonesStack.pop(); } } diff --git a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinition.java b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinition.java index 346554052..a1f3a7316 100644 --- a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinition.java +++ b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinition.java @@ -30,6 +30,8 @@ public abstract class ConstraintDefinition { protected Set alteredOmas; /** The variable that determines if the constraint will alter the track in any way. */ protected boolean trackToBeChanged = true; + /** The name of the constraint. */ + protected String constraintName; /** * Loads a constraint definition based on the constraint definition @@ -53,6 +55,10 @@ public abstract class ConstraintDefinition { constraintHelper = (ConstraintHelper) (blenderContext == null ? null : blenderContext.getHelper(ConstraintHelper.class)); this.ownerOMA = ownerOMA; } + + public void setConstraintName(String constraintName) { + this.constraintName = constraintName; + } /** * @return determines if the definition of the constraint will change the bone in any way; in most cases diff --git a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionFactory.java b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionFactory.java index cbf727290..c1d69fe06 100644 --- a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionFactory.java +++ b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionFactory.java @@ -92,7 +92,7 @@ public class ConstraintDefinitionFactory { * this exception is thrown when the blender file is somehow * corrupted */ - public static ConstraintDefinition createConstraintDefinition(Structure constraintStructure, Long ownerOMA, BlenderContext blenderContext) throws BlenderFileException { + public static ConstraintDefinition createConstraintDefinition(Structure constraintStructure, String constraintName, Long ownerOMA, BlenderContext blenderContext) throws BlenderFileException { if (constraintStructure == null) { return new ConstraintDefinitionNull(null, ownerOMA, blenderContext); } @@ -100,7 +100,9 @@ public class ConstraintDefinitionFactory { Class constraintDefinitionClass = CONSTRAINT_CLASSES.get(constraintClassName); if (constraintDefinitionClass != null) { try { - return (ConstraintDefinition) constraintDefinitionClass.getDeclaredConstructors()[0].newInstance(constraintStructure, ownerOMA, blenderContext); + ConstraintDefinition def = (ConstraintDefinition) constraintDefinitionClass.getDeclaredConstructors()[0].newInstance(constraintStructure, ownerOMA, blenderContext); + def.setConstraintName(constraintName); + return def; } catch (IllegalArgumentException e) { throw new BlenderFileException(e.getLocalizedMessage(), e); } catch (SecurityException e) { @@ -113,9 +115,9 @@ public class ConstraintDefinitionFactory { throw new BlenderFileException(e.getLocalizedMessage(), e); } } else { - String constraintName = UNSUPPORTED_CONSTRAINTS.get(constraintClassName); - if (constraintName != null) { - return new UnsupportedConstraintDefinition(constraintName); + String unsupportedConstraintClassName = UNSUPPORTED_CONSTRAINTS.get(constraintClassName); + if (unsupportedConstraintClassName != null) { + return new UnsupportedConstraintDefinition(unsupportedConstraintClassName); } else { throw new BlenderFileException("Unknown constraint type: " + constraintClassName); } diff --git a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionIK.java b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionIK.java index 35a4e5618..69e087a28 100644 --- a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionIK.java +++ b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionIK.java @@ -1,40 +1,44 @@ package com.jme3.scene.plugins.blender.constraints.definitions; import java.util.ArrayList; -import java.util.Collections; +import java.util.Collection; import java.util.HashSet; import java.util.List; +import org.ejml.simple.SimpleMatrix; + import com.jme3.animation.Bone; import com.jme3.math.Transform; -import com.jme3.math.Vector3f; import com.jme3.scene.plugins.blender.BlenderContext; import com.jme3.scene.plugins.blender.animations.BoneContext; +import com.jme3.scene.plugins.blender.constraints.ConstraintHelper; import com.jme3.scene.plugins.blender.constraints.ConstraintHelper.Space; import com.jme3.scene.plugins.blender.file.Structure; import com.jme3.scene.plugins.blender.math.DQuaternion; import com.jme3.scene.plugins.blender.math.DTransform; +import com.jme3.scene.plugins.blender.math.Matrix; import com.jme3.scene.plugins.blender.math.Vector3d; /** - * The Inverse Kinematics constraint. + * A definiotion of a Inverse Kinematics constraint. This implementation uses Jacobian pseudoinverse algorithm. * - * @author Wesley Shillingford (wezrule) * @author Marcin Roguski (Kaelthas) */ public class ConstraintDefinitionIK extends ConstraintDefinition { - private static final float MIN_DISTANCE = 0.0001f; - private static final int FLAG_USE_TAIL = 0x01; - private static final int FLAG_POSITION = 0x20; + private static final float MIN_DISTANCE = 0.001f; + private static final float MIN_ANGLE_CHANGE = 0.001f; + private static final int FLAG_USE_TAIL = 0x01; + private static final int FLAG_POSITION = 0x20; + private BonesChain bones; /** The number of affected bones. Zero means that all parent bones of the current bone should take part in baking. */ - private int bonesAffected; - /** The total length of the bone chain. Useful for optimisation of computations speed in some cases. */ - private double chainLength; + private int bonesAffected; /** Indicates if the tail of the bone should be used or not. */ - private boolean useTail; + private boolean useTail; /** The amount of iterations of the algorithm. */ - private int iterations; + private int iterations; + /** The count of bones' chain. */ + private int bonesCount = -1; public ConstraintDefinitionIK(Structure constraintData, Long ownerOMA, BlenderContext blenderContext) { super(constraintData, ownerOMA, blenderContext); @@ -51,122 +55,104 @@ public class ConstraintDefinitionIK extends ConstraintDefinition { } } + /** + * Below are the variables that only need to be allocated once for IK constraint instance. + */ + /** Temporal quaternion. */ + private DQuaternion tempDQuaternion = new DQuaternion(); + /** Temporal matrix column. */ + private Vector3d col = new Vector3d(); + /** Effector's position change. */ + private Matrix deltaP = new Matrix(3, 1); + /** The current target position. */ + private Vector3d target = new Vector3d(); + /** Rotation vectors for each joint (allocated when we know the size of a bones' chain. */ + private Vector3d[] rotationVectors; + /** The Jacobian matrix. Allocated when the bones' chain size is known. */ + private Matrix J; + @Override public void bake(Space ownerSpace, Space targetSpace, Transform targetTransform, float influence) { - if (influence == 0 || !trackToBeChanged || targetTransform == null) { + if (influence == 0 || !trackToBeChanged || targetTransform == null || bonesCount == 0) { return;// no need to do anything } - DQuaternion q = new DQuaternion(); - Vector3d t = new Vector3d(targetTransform.getTranslation()); - List bones = this.loadBones(); + + if (bones == null) { + bones = new BonesChain((Bone) this.getOwner(), useTail, bonesAffected, alteredOmas, blenderContext); + } if (bones.size() == 0) { + bonesCount = 0; return;// no need to do anything } double distanceFromTarget = Double.MAX_VALUE; + target.set(targetTransform.getTranslation().x, targetTransform.getTranslation().y, targetTransform.getTranslation().z); - int iterations = this.iterations; - if (bones.size() == 1) { - iterations = 1;// if only one bone is in the chain then only one iteration that will properly rotate it will be needed - } else { - // if the target cannot be rached by the bones' chain then the chain will become straight and point towards the target - // in this case only one iteration will be needed, computed from the root to top bone - BoneContext rootBone = bones.get(bones.size() - 1); - Transform rootBoneTransform = constraintHelper.getTransform(rootBone.getArmatureObjectOMA(), rootBone.getBone().getName(), Space.CONSTRAINT_SPACE_WORLD); - if (t.distance(new Vector3d(rootBoneTransform.getTranslation())) >= chainLength) { - Collections.reverse(bones); - - for (BoneContext boneContext : bones) { - Bone bone = boneContext.getBone(); - DTransform boneTransform = new DTransform(constraintHelper.getTransform(boneContext.getArmatureObjectOMA(), bone.getName(), Space.CONSTRAINT_SPACE_WORLD)); - - Vector3d e = boneTransform.getTranslation().add(boneTransform.getRotation().mult(Vector3d.UNIT_Y).multLocal(boneContext.getLength()));// effector - Vector3d j = boneTransform.getTranslation(); // current join position - - Vector3d currentDir = e.subtractLocal(j).normalizeLocal(); - Vector3d target = t.subtract(j).normalizeLocal(); - double angle = currentDir.angleBetween(target); - if (angle != 0) { - Vector3d cross = currentDir.crossLocal(target).normalizeLocal(); - q.fromAngleAxis(angle, cross); - - if(bone.equals(this.getOwner())) { - if (boneContext.isLockX()) { - q.set(0, q.getY(), q.getZ(), q.getW()); - } - if (boneContext.isLockY()) { - q.set(q.getX(), 0, q.getZ(), q.getW()); - } - if (boneContext.isLockZ()) { - q.set(q.getX(), q.getY(), 0, q.getW()); - } - } - - boneTransform.getRotation().set(q.multLocal(boneTransform.getRotation())); - constraintHelper.applyTransform(boneContext.getArmatureObjectOMA(), bone.getName(), Space.CONSTRAINT_SPACE_WORLD, boneTransform.toTransform()); - } - } - - iterations = 0; + if (bonesCount < 0) { + bonesCount = bones.size(); + rotationVectors = new Vector3d[bonesCount]; + for (int i = 0; i < bonesCount; ++i) { + rotationVectors[i] = new Vector3d(); } + J = new Matrix(3, bonesCount); } - List bestSolution = new ArrayList(bones.size()); - double bestSolutionDistance = Double.MAX_VALUE; BoneContext topBone = bones.get(0); - for (int i = 0; i < iterations && distanceFromTarget > MIN_DISTANCE; ++i) { - for (BoneContext boneContext : bones) { - Bone bone = boneContext.getBone(); - DTransform topBoneTransform = new DTransform(constraintHelper.getTransform(topBone.getArmatureObjectOMA(), topBone.getBone().getName(), Space.CONSTRAINT_SPACE_WORLD)); - DTransform boneWorldTransform = new DTransform(constraintHelper.getTransform(boneContext.getArmatureObjectOMA(), bone.getName(), Space.CONSTRAINT_SPACE_WORLD)); + for (int i = 0; i < iterations; ++i) { + DTransform topBoneTransform = bones.getWorldTransform(topBone); + Vector3d e = topBoneTransform.getTranslation().add(topBoneTransform.getRotation().mult(Vector3d.UNIT_Y).multLocal(topBone.getLength()));// effector + distanceFromTarget = e.distance(target); + if (distanceFromTarget <= MIN_DISTANCE) { + break; + } - Vector3d e = topBoneTransform.getTranslation().addLocal(topBoneTransform.getRotation().mult(Vector3d.UNIT_Y).multLocal(topBone.getLength()));// effector + deltaP.setColumn(0, 0, target.x - e.x, target.y - e.y, target.z - e.z); + int column = 0; + for (BoneContext boneContext : bones) { + DTransform boneWorldTransform = bones.getWorldTransform(boneContext); Vector3d j = boneWorldTransform.getTranslation(); // current join position + Vector3d vectorFromJointToEffector = e.subtract(j); + vectorFromJointToEffector.cross(target.subtract(j), rotationVectors[column]).normalizeLocal(); + rotationVectors[column].cross(vectorFromJointToEffector, col); + J.setColumn(col, column++); + } + Matrix J_1 = J.pseudoinverse(); - Vector3d currentDir = e.subtractLocal(j).normalizeLocal(); - Vector3d target = t.subtract(j).normalizeLocal(); - double angle = currentDir.angleBetween(target); - if (angle != 0) { - Vector3d cross = currentDir.crossLocal(target).normalizeLocal(); - q.fromAngleAxis(angle, cross); - - if(bone.equals(this.getOwner())) { - if (boneContext.isLockX()) { - q.set(0, q.getY(), q.getZ(), q.getW()); - } - if (boneContext.isLockY()) { - q.set(q.getX(), 0, q.getZ(), q.getW()); - } - if (boneContext.isLockZ()) { - q.set(q.getX(), q.getY(), 0, q.getW()); - } - } - - boneWorldTransform.getRotation().set(q.multLocal(boneWorldTransform.getRotation())); - constraintHelper.applyTransform(boneContext.getArmatureObjectOMA(), bone.getName(), Space.CONSTRAINT_SPACE_WORLD, boneWorldTransform.toTransform()); - } else { - iterations = 0; - break; - } + SimpleMatrix deltaThetas = J_1.mult(deltaP); + if (deltaThetas.elementMaxAbs() < MIN_ANGLE_CHANGE) { + break; } + for (int j = 0; j < deltaThetas.numRows(); ++j) { + double angle = deltaThetas.get(j, 0); + Vector3d rotationVector = rotationVectors[j]; - DTransform topBoneTransform = new DTransform(constraintHelper.getTransform(topBone.getArmatureObjectOMA(), topBone.getBone().getName(), Space.CONSTRAINT_SPACE_WORLD)); - Vector3d e = topBoneTransform.getTranslation().addLocal(topBoneTransform.getRotation().mult(Vector3d.UNIT_Y).multLocal(topBone.getLength()));// effector - distanceFromTarget = e.distance(t); - - if(distanceFromTarget < bestSolutionDistance) { - bestSolutionDistance = distanceFromTarget; - bestSolution.clear(); - for(BoneContext boneContext : bones) { - bestSolution.add(constraintHelper.getTransform(boneContext.getArmatureObjectOMA(), boneContext.getBone().getName(), Space.CONSTRAINT_SPACE_WORLD)); + tempDQuaternion.fromAngleAxis(angle, rotationVector); + BoneContext boneContext = bones.get(j); + Bone bone = boneContext.getBone(); + if (bone.equals(this.getOwner())) { + if (boneContext.isLockX()) { + tempDQuaternion.set(0, tempDQuaternion.getY(), tempDQuaternion.getZ(), tempDQuaternion.getW()); + } + if (boneContext.isLockY()) { + tempDQuaternion.set(tempDQuaternion.getX(), 0, tempDQuaternion.getZ(), tempDQuaternion.getW()); + } + if (boneContext.isLockZ()) { + tempDQuaternion.set(tempDQuaternion.getX(), tempDQuaternion.getY(), 0, tempDQuaternion.getW()); + } } + + DTransform boneTransform = bones.getWorldTransform(boneContext); + boneTransform.getRotation().set(tempDQuaternion.mult(boneTransform.getRotation())); + bones.setWorldTransform(boneContext, boneTransform); } } - - // applying best solution - for(int i=0;i= 0; --i) { BoneContext boneContext = bones.get(i); - constraintHelper.applyTransform(boneContext.getArmatureObjectOMA(), boneContext.getBone().getName(), Space.CONSTRAINT_SPACE_WORLD, bestSolution.get(i)); + DTransform transform = bones.getWorldTransform(boneContext); + constraintHelper.applyTransform(boneContext.getArmatureObjectOMA(), boneContext.getBone().getName(), Space.CONSTRAINT_SPACE_WORLD, transform.toTransform()); } + bones = null;// need to reload them again } @Override @@ -174,56 +160,68 @@ public class ConstraintDefinitionIK extends ConstraintDefinition { return "Inverse kinematics"; } + @Override + public boolean isTargetRequired() { + return true; + } + /** - * @return the bone contexts of all bones that will be used in this constraint computations + * Loaded bones' chain. This class allows to operate on transform matrices that use double precision in computations. + * Only the final result is being transformed to single precision numbers. + * + * @author Marcin Roguski (Kaelthas) */ - private List loadBones() { - List bones = new ArrayList(); - Bone bone = (Bone) this.getOwner(); - if (bone == null) { - return bones; - } - if (!useTail) { - bone = bone.getParent(); - } - chainLength = 0; - while (bone != null) { - BoneContext boneContext = blenderContext.getBoneContext(bone); - chainLength += boneContext.getLength(); - bones.add(boneContext); - alteredOmas.add(boneContext.getBoneOma()); - if (bonesAffected != 0 && bones.size() >= bonesAffected) { - break; - } - // need to add spaces between bones to the chain length - Transform boneWorldTransform = constraintHelper.getTransform(boneContext.getArmatureObjectOMA(), boneContext.getBone().getName(), Space.CONSTRAINT_SPACE_WORLD); - Vector3f boneWorldTranslation = boneWorldTransform.getTranslation(); + private static class BonesChain extends ArrayList { + private static final long serialVersionUID = -1850524345643600718L; - bone = bone.getParent(); + private List bonesMatrices = new ArrayList(); + public BonesChain(Bone bone, boolean useTail, int bonesAffected, Collection alteredOmas, BlenderContext blenderContext) { if (bone != null) { - boneContext = blenderContext.getBoneContext(bone); - Transform parentWorldTransform = constraintHelper.getTransform(boneContext.getArmatureObjectOMA(), boneContext.getBone().getName(), Space.CONSTRAINT_SPACE_WORLD); - Vector3f parentWorldTranslation = parentWorldTransform.getTranslation(); - chainLength += boneWorldTranslation.distance(parentWorldTranslation); + ConstraintHelper constraintHelper = blenderContext.getHelper(ConstraintHelper.class); + if (!useTail) { + bone = bone.getParent(); + } + while (bone != null && (bonesAffected <= 0 || this.size() < bonesAffected)) { + BoneContext boneContext = blenderContext.getBoneContext(bone); + this.add(boneContext); + alteredOmas.add(boneContext.getBoneOma()); + + Space space = this.size() < bonesAffected ? Space.CONSTRAINT_SPACE_LOCAL : Space.CONSTRAINT_SPACE_WORLD; + Transform transform = constraintHelper.getTransform(boneContext.getArmatureObjectOMA(), boneContext.getBone().getName(), space); + bonesMatrices.add(new DTransform(transform).toMatrix()); + + bone = bone.getParent(); + } } } - return bones; - } - @Override - public boolean isTrackToBeChanged() { - if (trackToBeChanged) { - // need to check the bone structure too (when constructor was called not all of the bones might have been loaded yet) - // that is why it is also checked here - List bones = this.loadBones(); - trackToBeChanged = bones.size() > 0; + public DTransform getWorldTransform(BoneContext bone) { + int index = this.indexOf(bone); + return this.getWorldMatrix(index).toTransform(); } - return trackToBeChanged; - } - @Override - public boolean isTargetRequired() { - return true; + public void setWorldTransform(BoneContext bone, DTransform transform) { + int index = this.indexOf(bone); + Matrix boneMatrix = transform.toMatrix(); + + if (index < this.size() - 1) { + // computing the current bone local transform + Matrix parentWorldMatrix = this.getWorldMatrix(index + 1); + SimpleMatrix m = parentWorldMatrix.invert().mult(boneMatrix); + boneMatrix = new Matrix(m); + } + bonesMatrices.set(index, boneMatrix); + } + + public Matrix getWorldMatrix(int index) { + if (index == this.size() - 1) { + return new Matrix(bonesMatrices.get(this.size() - 1)); + } + + SimpleMatrix result = this.getWorldMatrix(index + 1); + result = result.mult(bonesMatrices.get(index)); + return new Matrix(result); + } } } diff --git a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/file/FileBlockHeader.java b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/file/FileBlockHeader.java index 666da7896..6a5222a9c 100644 --- a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/file/FileBlockHeader.java +++ b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/file/FileBlockHeader.java @@ -31,6 +31,7 @@ */ package com.jme3.scene.plugins.blender.file; +import java.util.logging.Level; import java.util.logging.Logger; import com.jme3.scene.plugins.blender.BlenderContext; @@ -171,8 +172,21 @@ public class FileBlockHeader { BLOCK_IP00('I' << 24 | 'P' << 16), // ipo BLOCK_AC00('A' << 24 | 'C' << 16), // action BLOCK_IM00('I' << 24 | 'M' << 16), // image - BLOCK_TE00('T' << 24 | 'E' << 16), BLOCK_WM00('W' << 24 | 'M' << 16), BLOCK_SR00('S' << 24 | 'R' << 16), BLOCK_SN00('S' << 24 | 'N' << 16), BLOCK_BR00('B' << 24 | 'R' << 16), BLOCK_LS00('L' << 24 | 'S' << 16), BLOCK_GLOB('G' << 24 | 'L' << 16 | 'O' << 8 | 'B'), BLOCK_REND('R' << 24 | 'E' << 16 | 'N' << 8 | 'D'), BLOCK_DATA('D' << 24 | 'A' << 16 | 'T' << 8 | 'A'), BLOCK_DNA1('D' << 24 | 'N' << 16 | 'A' << 8 | '1'), BLOCK_ENDB('E' << 24 | 'N' << 16 | 'D' << 8 | 'B'), BLOCK_TEST('T' << 24 | 'E' << 16 - | 'S' << 8 | 'T'), BLOCK_UNKN(0); + BLOCK_TE00('T' << 24 | 'E' << 16), + BLOCK_WM00('W' << 24 | 'M' << 16), + BLOCK_SR00('S' << 24 | 'R' << 16), + BLOCK_SN00('S' << 24 | 'N' << 16), + BLOCK_BR00('B' << 24 | 'R' << 16), + BLOCK_LS00('L' << 24 | 'S' << 16), + BLOCK_GR00('G' << 24 | 'R' << 16), + BLOCK_AR00('A' << 24 | 'R' << 16), + BLOCK_GLOB('G' << 24 | 'L' << 16 | 'O' << 8 | 'B'), + BLOCK_REND('R' << 24 | 'E' << 16 | 'N' << 8 | 'D'), + BLOCK_DATA('D' << 24 | 'A' << 16 | 'T' << 8 | 'A'), + BLOCK_DNA1('D' << 24 | 'N' << 16 | 'A' << 8 | '1'), + BLOCK_ENDB('E' << 24 | 'N' << 16 | 'D' << 8 | 'B'), + BLOCK_TEST('T' << 24 | 'E' << 16 | 'S' << 8 | 'T'), + BLOCK_UNKN(0); private int code; @@ -187,7 +201,12 @@ public class FileBlockHeader { } } byte[] codeBytes = new byte[] { (byte) (code >> 24 & 0xFF), (byte) (code >> 16 & 0xFF), (byte) (code >> 8 & 0xFF), (byte) (code & 0xFF) }; - LOGGER.warning("Unknown block header: " + new String(codeBytes)); + for (int i = 0; i < codeBytes.length; ++i) { + if (codeBytes[i] == 0) { + codeBytes[i] = '0'; + } + } + LOGGER.log(Level.WARNING, "Unknown block header: {0}", new String(codeBytes)); return BLOCK_UNKN; } } diff --git a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/math/DQuaternion.java b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/math/DQuaternion.java index 359abf057..9739ccd4b 100644 --- a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/math/DQuaternion.java +++ b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/math/DQuaternion.java @@ -164,6 +164,134 @@ public final class DQuaternion implements Savable, Cloneable, java.io.Serializab w = 1; } + /** + * norm returns the norm of this quaternion. This is the dot + * product of this quaternion with itself. + * + * @return the norm of the quaternion. + */ + public double norm() { + return w * w + x * x + y * y + z * z; + } + + public DQuaternion fromRotationMatrix(double m00, double m01, double m02, + double m10, double m11, double m12, double m20, double m21, double m22) { + // first normalize the forward (F), up (U) and side (S) vectors of the rotation matrix + // so that the scale does not affect the rotation + double lengthSquared = m00 * m00 + m10 * m10 + m20 * m20; + if (lengthSquared != 1f && lengthSquared != 0f) { + lengthSquared = 1.0 / Math.sqrt(lengthSquared); + m00 *= lengthSquared; + m10 *= lengthSquared; + m20 *= lengthSquared; + } + lengthSquared = m01 * m01 + m11 * m11 + m21 * m21; + if (lengthSquared != 1 && lengthSquared != 0f) { + lengthSquared = 1.0 / Math.sqrt(lengthSquared); + m01 *= lengthSquared; + m11 *= lengthSquared; + m21 *= lengthSquared; + } + lengthSquared = m02 * m02 + m12 * m12 + m22 * m22; + if (lengthSquared != 1f && lengthSquared != 0f) { + lengthSquared = 1.0 / Math.sqrt(lengthSquared); + m02 *= lengthSquared; + m12 *= lengthSquared; + m22 *= lengthSquared; + } + + // Use the Graphics Gems code, from + // ftp://ftp.cis.upenn.edu/pub/graphics/shoemake/quatut.ps.Z + // *NOT* the "Matrix and Quaternions FAQ", which has errors! + + // the trace is the sum of the diagonal elements; see + // http://mathworld.wolfram.com/MatrixTrace.html + double t = m00 + m11 + m22; + + // we protect the division by s by ensuring that s>=1 + if (t >= 0) { // |w| >= .5 + double s = Math.sqrt(t + 1); // |s|>=1 ... + w = 0.5f * s; + s = 0.5f / s; // so this division isn't bad + x = (m21 - m12) * s; + y = (m02 - m20) * s; + z = (m10 - m01) * s; + } else if (m00 > m11 && m00 > m22) { + double s = Math.sqrt(1.0 + m00 - m11 - m22); // |s|>=1 + x = s * 0.5f; // |x| >= .5 + s = 0.5f / s; + y = (m10 + m01) * s; + z = (m02 + m20) * s; + w = (m21 - m12) * s; + } else if (m11 > m22) { + double s = Math.sqrt(1.0 + m11 - m00 - m22); // |s|>=1 + y = s * 0.5f; // |y| >= .5 + s = 0.5f / s; + x = (m10 + m01) * s; + z = (m21 + m12) * s; + w = (m02 - m20) * s; + } else { + double s = Math.sqrt(1.0 + m22 - m00 - m11); // |s|>=1 + z = s * 0.5f; // |z| >= .5 + s = 0.5f / s; + x = (m02 + m20) * s; + y = (m21 + m12) * s; + w = (m10 - m01) * s; + } + + return this; + } + + /** + * toRotationMatrix converts this quaternion to a rotational + * matrix. The result is stored in result. 4th row and 4th column values are + * untouched. Note: the result is created from a normalized version of this quat. + * + * @param result + * The Matrix4f to store the result in. + * @return the rotation matrix representation of this quaternion. + */ + public Matrix toRotationMatrix(Matrix result) { + Vector3d originalScale = new Vector3d(); + + result.toScaleVector(originalScale); + result.setScale(1, 1, 1); + double norm = this.norm(); + // we explicitly test norm against one here, saving a division + // at the cost of a test and branch. Is it worth it? + double s = norm == 1f ? 2f : norm > 0f ? 2f / norm : 0; + + // compute xs/ys/zs first to save 6 multiplications, since xs/ys/zs + // will be used 2-4 times each. + double xs = x * s; + double ys = y * s; + double zs = z * s; + double xx = x * xs; + double xy = x * ys; + double xz = x * zs; + double xw = w * xs; + double yy = y * ys; + double yz = y * zs; + double yw = w * ys; + double zz = z * zs; + double zw = w * zs; + + // using s=2/norm (instead of 1/norm) saves 9 multiplications by 2 here + result.set(0, 0, 1 - (yy + zz)); + result.set(0, 1, xy - zw); + result.set(0, 2, xz + yw); + result.set(1, 0, xy + zw); + result.set(1, 1, 1 - (xx + zz)); + result.set(1, 2, yz - xw); + result.set(2, 0, xz - yw); + result.set(2, 1, yz + xw); + result.set(2, 2, 1 - (xx + yy)); + + result.setScale(originalScale); + + return result; + } + /** * fromAngleAxis sets this quaternion to the values specified * by an angle and an axis of rotation. This method creates an object, so diff --git a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/math/DTransform.java b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/math/DTransform.java index ed31a4c98..28fcda0c7 100644 --- a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/math/DTransform.java +++ b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/math/DTransform.java @@ -31,11 +31,15 @@ */ package com.jme3.scene.plugins.blender.math; -import com.jme3.export.*; -import com.jme3.math.Transform; - import java.io.IOException; +import com.jme3.export.InputCapsule; +import com.jme3.export.JmeExporter; +import com.jme3.export.JmeImporter; +import com.jme3.export.OutputCapsule; +import com.jme3.export.Savable; +import com.jme3.math.Transform; + /** * Started Date: Jul 16, 2004
*
@@ -57,6 +61,12 @@ public final class DTransform implements Savable, Cloneable, java.io.Serializabl private Vector3d translation; private Vector3d scale; + public DTransform() { + translation = new Vector3d(); + rotation = new DQuaternion(); + scale = new Vector3d(); + } + public DTransform(Transform transform) { translation = new Vector3d(transform.getTranslation()); rotation = new DQuaternion(transform.getRotation()); @@ -66,7 +76,15 @@ public final class DTransform implements Savable, Cloneable, java.io.Serializabl public Transform toTransform() { return new Transform(translation.toVector3f(), rotation.toQuaternion(), scale.toVector3f()); } - + + public Matrix toMatrix() { + Matrix m = Matrix.identity(4); + m.setTranslation(translation); + m.setRotationQuaternion(rotation); + m.setScale(scale); + return m; + } + /** * Sets this translation to the given value. * @param trans diff --git a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/math/Matrix.java b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/math/Matrix.java new file mode 100644 index 000000000..29550f23b --- /dev/null +++ b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/math/Matrix.java @@ -0,0 +1,214 @@ +package com.jme3.scene.plugins.blender.math; + +import java.text.DecimalFormat; + +import org.ejml.ops.CommonOps; +import org.ejml.simple.SimpleMatrix; +import org.ejml.simple.SimpleSVD; + +import com.jme3.math.FastMath; + +/** + * Encapsulates a 4x4 matrix + * + * + */ +public class Matrix extends SimpleMatrix { + private static final long serialVersionUID = 2396600537315902559L; + + public Matrix(int rows, int cols) { + super(rows, cols); + } + + /** + * Copy constructor + */ + public Matrix(SimpleMatrix m) { + super(m); + } + + public Matrix(double[][] data) { + super(data); + } + + public static Matrix identity(int size) { + Matrix result = new Matrix(size, size); + CommonOps.setIdentity(result.mat); + return result; + } + + public Matrix pseudoinverse() { + return this.pseudoinverse(1); + } + + @SuppressWarnings("unchecked") + public Matrix pseudoinverse(double lambda) { + SimpleSVD simpleSVD = this.svd(); + + SimpleMatrix U = simpleSVD.getU(); + SimpleMatrix S = simpleSVD.getW(); + SimpleMatrix V = simpleSVD.getV(); + + int N = Math.min(this.numRows(),this.numCols()); + double maxSingular = 0; + for( int i = 0; i < N; ++i ) { + if( S.get(i, i) > maxSingular ) { + maxSingular = S.get(i, i); + } + } + + double tolerance = FastMath.DBL_EPSILON * Math.max(this.numRows(),this.numCols()) * maxSingular; + for(int i=0;isetRotationQuaternion builds a rotation from a + * Quaternion. + * + * @param quat + * the quaternion to build the rotation from. + * @throws NullPointerException + * if quat is null. + */ + public void setRotationQuaternion(DQuaternion quat) { + quat.toRotationMatrix(this); + } + + public DTransform toTransform() { + DTransform result = new DTransform(); + result.setTranslation(this.toTranslationVector()); + result.setRotation(this.toRotationQuat()); + result.setScale(this.toScaleVector()); + return result; + } + + public Vector3d toTranslationVector() { + return new Vector3d(this.get(0, 3), this.get(1, 3), this.get(2, 3)); + } + + public DQuaternion toRotationQuat() { + DQuaternion quat = new DQuaternion(); + quat.fromRotationMatrix(this.get(0, 0), this.get(0, 1), this.get(0, 2), this.get(1, 0), this.get(1, 1), this.get(1, 2), this.get(2, 0), this.get(2, 1), this.get(2, 2)); + return quat; + } + + /** + * Retreives the scale vector from the matrix and stores it into a given + * vector. + * + * @param the + * vector where the scale will be stored + */ + public Vector3d toScaleVector() { + Vector3d result = new Vector3d(); + this.toScaleVector(result); + return result; + } + + /** + * Retreives the scale vector from the matrix and stores it into a given + * vector. + * + * @param the + * vector where the scale will be stored + */ + public void toScaleVector(Vector3d vector) { + double scaleX = Math.sqrt(this.get(0, 0) * this.get(0, 0) + this.get(1, 0) * this.get(1, 0) + this.get(2, 0) * this.get(2, 0)); + double scaleY = Math.sqrt(this.get(0, 1) * this.get(0, 1) + this.get(1, 1) * this.get(1, 1) + this.get(2, 1) * this.get(2, 1)); + double scaleZ = Math.sqrt(this.get(0, 2) * this.get(0, 2) + this.get(1, 2) * this.get(1, 2) + this.get(2, 2) * this.get(2, 2)); + vector.set(scaleX, scaleY, scaleZ); + } +} diff --git a/jme3-bullet-native/libs/native/windows/x86/bulletjme.dll b/jme3-bullet-native/libs/native/windows/x86/bulletjme.dll index 6839705bf..6874ad53d 100644 Binary files a/jme3-bullet-native/libs/native/windows/x86/bulletjme.dll and b/jme3-bullet-native/libs/native/windows/x86/bulletjme.dll differ diff --git a/jme3-bullet-native/libs/native/windows/x86_64/bulletjme.dll b/jme3-bullet-native/libs/native/windows/x86_64/bulletjme.dll index 3a2aa3449..24ae0eb52 100644 Binary files a/jme3-bullet-native/libs/native/windows/x86_64/bulletjme.dll and b/jme3-bullet-native/libs/native/windows/x86_64/bulletjme.dll differ diff --git a/jme3-bullet-native/src/native/cpp/com_jme3_bullet_objects_PhysicsRigidBody.cpp b/jme3-bullet-native/src/native/cpp/com_jme3_bullet_objects_PhysicsRigidBody.cpp index 0d9621bb8..c9fef97cb 100644 --- a/jme3-bullet-native/src/native/cpp/com_jme3_bullet_objects_PhysicsRigidBody.cpp +++ b/jme3-bullet-native/src/native/cpp/com_jme3_bullet_objects_PhysicsRigidBody.cpp @@ -811,39 +811,72 @@ extern "C" { /* * Class: com_jme3_bullet_objects_PhysicsRigidBody * Method: getAngularFactor - * Signature: (J)F + * Signature: (JLcom/jme3/math/Vector3f;)V */ - JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getAngularFactor - (JNIEnv *env, jobject object, jlong bodyId) { + JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getAngularFactor + (JNIEnv *env, jobject object, jlong bodyId, jobject factor) { btRigidBody* body = reinterpret_cast(bodyId); if (body == NULL) { jclass newExc = env->FindClass("java/lang/NullPointerException"); env->ThrowNew(newExc, "The native object does not exist."); - return 0; + return; } - return body->getAngularFactor().getX(); + jmeBulletUtil::convert(env, &body->getAngularFactor(), factor); } + /* * Class: com_jme3_bullet_objects_PhysicsRigidBody * Method: setAngularFactor - * Signature: (JF)V + * Signature: (JLcom/jme3/math/Vector3f;)V */ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setAngularFactor - (JNIEnv *env, jobject object, jlong bodyId, jfloat value) { + (JNIEnv *env, jobject object, jlong bodyId, jobject factor) { btRigidBody* body = reinterpret_cast(bodyId); if (body == NULL) { jclass newExc = env->FindClass("java/lang/NullPointerException"); env->ThrowNew(newExc, "The native object does not exist."); return; } - btVector3 vec1 = btVector3(); - vec1.setX(value); - vec1.setY(value); - vec1.setZ(value); - body->setAngularFactor(vec1); + btVector3 vec = btVector3(); + jmeBulletUtil::convert(env, factor, &vec); + body->setAngularFactor(vec); } + /* + * Class: com_jme3_bullet_objects_PhysicsRigidBody + * Method: getLinearFactor + * Signature: (JLcom/jme3/math/Vector3f;)V + */ + JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getLinearFactor + (JNIEnv *env, jobject object, jlong bodyId, jobject factor) { + btRigidBody* body = reinterpret_cast(bodyId); + if (body == NULL) { + jclass newExc = env->FindClass("java/lang/NullPointerException"); + env->ThrowNew(newExc, "The native object does not exist."); + return; + } + jmeBulletUtil::convert(env, &body->getLinearFactor(), factor); + } + + /* + * Class: com_jme3_bullet_objects_PhysicsRigidBody + * Method: setLinearFactor + * Signature: (JLcom/jme3/math/Vector3f;)V + */ + JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setLinearFactor + (JNIEnv *env, jobject object, jlong bodyId, jobject factor) { + btRigidBody* body = reinterpret_cast(bodyId); + if (body == NULL) { + jclass newExc = env->FindClass("java/lang/NullPointerException"); + env->ThrowNew(newExc, "The native object does not exist."); + return; + } + btVector3 vec = btVector3(); + jmeBulletUtil::convert(env, factor, &vec); + body->setLinearFactor(vec); + } + #ifdef __cplusplus } #endif diff --git a/jme3-bullet-native/src/native/cpp/com_jme3_bullet_objects_PhysicsRigidBody.h b/jme3-bullet-native/src/native/cpp/com_jme3_bullet_objects_PhysicsRigidBody.h index aa09a620a..67ba9e609 100644 --- a/jme3-bullet-native/src/native/cpp/com_jme3_bullet_objects_PhysicsRigidBody.h +++ b/jme3-bullet-native/src/native/cpp/com_jme3_bullet_objects_PhysicsRigidBody.h @@ -396,18 +396,35 @@ JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getAngula /* * Class: com_jme3_bullet_objects_PhysicsRigidBody * Method: getAngularFactor - * Signature: (J)F + * Signature: (JLcom/jme3/math/Vector3f;)V */ -JNIEXPORT jfloat JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getAngularFactor - (JNIEnv *, jobject, jlong); +JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getAngularFactor + (JNIEnv *, jobject, jlong, jobject); + /* * Class: com_jme3_bullet_objects_PhysicsRigidBody * Method: setAngularFactor - * Signature: (JF)V + * Signature: (JLcom/jme3/math/Vector3f;)V */ JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setAngularFactor - (JNIEnv *, jobject, jlong, jfloat); + (JNIEnv *, jobject, jlong, jobject); + +/* + * Class: com_jme3_bullet_objects_PhysicsRigidBody + * Method: getLinearFactor + * Signature: (JLcom/jme3/math/Vector3f;)V + */ +JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_getLinearFactor + (JNIEnv *, jobject, jlong, jobject); + +/* + * Class: com_jme3_bullet_objects_PhysicsRigidBody + * Method: setLinearFactor + * Signature: (JLcom/jme3/math/Vector3f;)V + */ +JNIEXPORT void JNICALL Java_com_jme3_bullet_objects_PhysicsRigidBody_setLinearFactor + (JNIEnv *, jobject, jlong, jobject); #ifdef __cplusplus } diff --git a/jme3-bullet/src/main/java/com/jme3/bullet/collision/shapes/CapsuleCollisionShape.java b/jme3-bullet/src/main/java/com/jme3/bullet/collision/shapes/CapsuleCollisionShape.java index 525e2e281..00ccdf74e 100644 --- a/jme3-bullet/src/main/java/com/jme3/bullet/collision/shapes/CapsuleCollisionShape.java +++ b/jme3-bullet/src/main/java/com/jme3/bullet/collision/shapes/CapsuleCollisionShape.java @@ -93,7 +93,9 @@ public class CapsuleCollisionShape extends CollisionShape{ */ @Override public void setScale(Vector3f scale) { - Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "CapsuleCollisionShape cannot be scaled"); + if (!scale.equals(Vector3f.UNIT_XYZ)) { + Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "CapsuleCollisionShape cannot be scaled"); + } } public void write(JmeExporter ex) throws IOException { diff --git a/jme3-bullet/src/main/java/com/jme3/bullet/objects/PhysicsRigidBody.java b/jme3-bullet/src/main/java/com/jme3/bullet/objects/PhysicsRigidBody.java index 40417c775..6f6eb4d76 100644 --- a/jme3-bullet/src/main/java/com/jme3/bullet/objects/PhysicsRigidBody.java +++ b/jme3-bullet/src/main/java/com/jme3/bullet/objects/PhysicsRigidBody.java @@ -627,16 +627,44 @@ public class PhysicsRigidBody extends PhysicsCollisionObject { private native float getAngularSleepingThreshold(long objectId); public float getAngularFactor() { - return getAngularFactor(objectId); + return getAngularFactor(null).getX(); } - private native float getAngularFactor(long objectId); + public Vector3f getAngularFactor(Vector3f store) { + // doing like this prevent from breaking the API + if (store == null) { + store = new Vector3f(); + } + getAngularFactor(objectId, store); + return store; + } + + private native void getAngularFactor(long objectId, Vector3f vec); public void setAngularFactor(float factor) { - setAngularFactor(objectId, factor); + setAngularFactor(objectId, new Vector3f(factor, factor, factor)); + } + + public void setAngularFactor(Vector3f factor) { + setAngularFactor(objectId, factor); + } + + private native void setAngularFactor(long objectId, Vector3f factor); + + public Vector3f getLinearFactor() { + Vector3f vec = new Vector3f(); + getLinearFactor(objectId, vec); + return vec; } - private native void setAngularFactor(long objectId, float factor); + private native void getLinearFactor(long objectId, Vector3f vec); + + public void setLinearFactor(Vector3f factor) { + setLinearFactor(objectId, factor); + } + + private native void setLinearFactor(long objectId, Vector3f factor); + /** * do not use manually, joints are added automatically @@ -673,7 +701,13 @@ public class PhysicsRigidBody extends PhysicsCollisionObject { capsule.write(getGravity(), "gravity", Vector3f.ZERO); capsule.write(getFriction(), "friction", 0.5f); capsule.write(getRestitution(), "restitution", 0); - capsule.write(getAngularFactor(), "angularFactor", 1); + Vector3f angularFactor = getAngularFactor(null); + if (angularFactor.x == angularFactor.y && angularFactor.y == angularFactor.z) { + capsule.write(getAngularFactor(), "angularFactor", 1); + } else { + capsule.write(getAngularFactor(null), "angularFactor", Vector3f.UNIT_XYZ); + capsule.write(getLinearFactor(), "linearFactor", Vector3f.UNIT_XYZ); + } capsule.write(kinematic, "kinematic", false); capsule.write(getLinearDamping(), "linearDamping", 0); @@ -703,7 +737,13 @@ public class PhysicsRigidBody extends PhysicsCollisionObject { setKinematic(capsule.readBoolean("kinematic", false)); setRestitution(capsule.readFloat("restitution", 0)); - setAngularFactor(capsule.readFloat("angularFactor", 1)); + Vector3f angularFactor = (Vector3f) capsule.readSavable("angularFactor", Vector3f.NAN.clone()); + if(angularFactor == Vector3f.NAN) { + setAngularFactor(capsule.readFloat("angularFactor", 1)); + } else { + setAngularFactor(angularFactor); + setLinearFactor((Vector3f) capsule.readSavable("linearFactor", Vector3f.UNIT_XYZ.clone())); + } setDamping(capsule.readFloat("linearDamping", 0), capsule.readFloat("angularDamping", 0)); setSleepingThresholds(capsule.readFloat("linearSleepingThreshold", 0.8f), capsule.readFloat("angularSleepingThreshold", 1.0f)); setCcdMotionThreshold(capsule.readFloat("ccdMotionThreshold", 0)); diff --git a/jme3-core/build.gradle b/jme3-core/build.gradle index bd699f52a..2a45d440b 100644 --- a/jme3-core/build.gradle +++ b/jme3-core/build.gradle @@ -12,55 +12,23 @@ sourceSets { } } -buildscript { - repositories { - mavenCentral() - } - dependencies { - classpath 'org.ajoberstar:gradle-git:1.0.0-rc.1' - } -} - -import java.text.SimpleDateFormat -import org.ajoberstar.grgit.* - -task updateVersion << { - - def verfile = file('src/main/java/com/jme3/system/JmeVersion.java') - def jmeGitHash - def jmeShortGitHash - def jmeBuildDate - def jmeBranchName - - try { - def grgit = Grgit.open(project.file('.').parent) - jmeGitHash = grgit.head().id - jmeShortGitHash = grgit.head().abbreviatedId - jmeBuildDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date()) - jmeBranchName = grgit.branch.current.name - } catch (ex) { - // Failed to get repo info - logger.warn("Failed to get repository info: " + ex.message + ". " + \ - "Only partial build info will be generated.") - - jmeGitHash = "" - jmeShortGitHash = "" - jmeBuildDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date()) - jmeBranchName = "unknown" - } - - verfile.text = "\npackage com.jme3.system;\n\n" + - "/**\n * THIS IS AN AUTO-GENERATED FILE..\n * DO NOT MODIFY!\n */\n" + - "public class JmeVersion {\n" + - " public static final String BUILD_DATE = \"${jmeBuildDate}\";\n" + - " public static final String BRANCH_NAME = \"${jmeBranchName}\";\n" + - " public static final String GIT_HASH = \"${jmeGitHash}\";\n" + - " public static final String GIT_SHORT_HASH = \"${jmeShortGitHash}\";\n" + - " public static final String FULL_NAME = \"jMonkeyEngine ${jmeVersion} (${jmeVersionTag})\";\n" + - "}\n" +task updateVersionPropertiesFile << { + def verfile = file('src/main/resources/com/jme3/system/version.properties') + verfile.text = "# THIS IS AN AUTO-GENERATED FILE..\n" + + "# DO NOT MODIFY!\n" + + "build.date=${jmeBuildDate}\n" + + "git.revision=${jmeRevision}\n" + + "git.branch=${jmeBranchName}\n" + + "git.hash=${jmeGitHash}\n" + + "git.hash.short=${jmeShortGitHash}\n" + + "git.tag=${jmeGitTag}\n" + + "name.full=jMonkeyEngine ${jmeFullVersion}\n" + + "version.full=${jmeFullVersion}\n" + + "version.number=${jmeVersion}\n" + + "version.tag=${jmeVersionTag}" } -compileJava.dependsOn(updateVersion) +compileJava.dependsOn(updateVersionPropertiesFile) dependencies { } diff --git a/jme3-core/src/main/java/com/jme3/animation/Bone.java b/jme3-core/src/main/java/com/jme3/animation/Bone.java index a78b4b931..29c0f38e9 100644 --- a/jme3-core/src/main/java/com/jme3/animation/Bone.java +++ b/jme3-core/src/main/java/com/jme3/animation/Bone.java @@ -553,7 +553,6 @@ public final class Bone implements Savable { Vector3f translate = modelPos.add(rotate.mult(scale.mult(modelBindInversePos, tmp2), tmp2), tmp2); // Populating the matrix - outTransform.loadIdentity(); outTransform.setTransform(translate, scale, rotate.toRotationMatrix(tmp4)); } diff --git a/jme3-core/src/main/java/com/jme3/animation/SkeletonControl.java b/jme3-core/src/main/java/com/jme3/animation/SkeletonControl.java index d5ef31939..b1f3d02df 100644 --- a/jme3-core/src/main/java/com/jme3/animation/SkeletonControl.java +++ b/jme3-core/src/main/java/com/jme3/animation/SkeletonControl.java @@ -82,7 +82,7 @@ public class SkeletonControl extends AbstractControl implements Cloneable { /** * User wishes to use hardware skinning if available. */ - private transient boolean hwSkinningDesired = false; + private transient boolean hwSkinningDesired = true; /** * Hardware skinning is currently being used. @@ -347,11 +347,22 @@ public class SkeletonControl extends AbstractControl implements Cloneable { public Control cloneForSpatial(Spatial spatial) { Node clonedNode = (Node) spatial; - AnimControl ctrl = spatial.getControl(AnimControl.class); SkeletonControl clone = new SkeletonControl(); - clone.skeleton = ctrl.getSkeleton(); - + AnimControl ctrl = spatial.getControl(AnimControl.class); + if (ctrl != null) { + // AnimControl is responsible for cloning the skeleton, not + // SkeletonControl. + clone.skeleton = ctrl.getSkeleton(); + } else { + // If there's no AnimControl, create the clone ourselves. + clone.skeleton = new Skeleton(skeleton); + } + clone.hwSkinningDesired = this.hwSkinningDesired; + clone.hwSkinningEnabled = this.hwSkinningEnabled; + clone.hwSkinningSupported = this.hwSkinningSupported; + clone.hwSkinningTested = this.hwSkinningTested; + clone.setSpatial(clonedNode); // Fix attachments for the cloned node diff --git a/jme3-core/src/main/java/com/jme3/app/StatsView.java b/jme3-core/src/main/java/com/jme3/app/StatsView.java index 9f748fdf4..a0446e85e 100644 --- a/jme3-core/src/main/java/com/jme3/app/StatsView.java +++ b/jme3-core/src/main/java/com/jme3/app/StatsView.java @@ -60,7 +60,7 @@ import com.jme3.scene.control.Control; */ public class StatsView extends Node implements Control { - private BitmapText[] labels; + private BitmapText statText; private Statistics statistics; private String[] statLabels; @@ -81,20 +81,17 @@ public class StatsView extends Node implements Control { statLabels = statistics.getLabels(); statData = new int[statLabels.length]; - labels = new BitmapText[statLabels.length]; BitmapFont font = manager.loadFont("Interface/Fonts/Console.fnt"); - for (int i = 0; i < labels.length; i++){ - labels[i] = new BitmapText(font); - labels[i].setLocalTranslation(0, labels[i].getLineHeight() * (i+1), 0); - attachChild(labels[i]); - } + statText = new BitmapText(font); + statText.setLocalTranslation(0, statText.getLineHeight() * statLabels.length, 0); + attachChild(statText); addControl(this); } public float getHeight() { - return labels[0].getLineHeight() * statLabels.length; + return statText.getLineHeight() * statLabels.length; } public void update(float tpf) { @@ -103,11 +100,14 @@ public class StatsView extends Node implements Control { return; statistics.getData(statData); - for (int i = 0; i < labels.length; i++) { - stringBuilder.setLength(0); - stringBuilder.append(statLabels[i]).append(" = ").append(statData[i]); - labels[i].setText(stringBuilder); + stringBuilder.setLength(0); + + // Need to walk through it backwards, as the first label + // should appear at the bottom, not the top. + for (int i = statLabels.length - 1; i >= 0; i--) { + stringBuilder.append(statLabels[i]).append(" = ").append(statData[i]).append('\n'); } + statText.setText(stringBuilder); // Moved to ResetStatsState to make sure it is // done even if there is no StatsView or the StatsView diff --git a/jme3-core/src/main/java/com/jme3/audio/AudioNode.java b/jme3-core/src/main/java/com/jme3/audio/AudioNode.java index 0e75db9fe..8664af6c7 100644 --- a/jme3-core/src/main/java/com/jme3/audio/AudioNode.java +++ b/jme3-core/src/main/java/com/jme3/audio/AudioNode.java @@ -77,7 +77,7 @@ public class AudioNode extends Node implements AudioSource { protected transient volatile AudioSource.Status status = AudioSource.Status.Stopped; protected transient volatile int channel = -1; protected Vector3f velocity = new Vector3f(); - protected boolean reverbEnabled = true; + protected boolean reverbEnabled = false; protected float maxDistance = 200; // 200 meters protected float refDistance = 10; // 10 meters protected Filter reverbFilter; @@ -409,6 +409,14 @@ public class AudioNode extends Node implements AudioSource { play(); } } + + @Override + public float getPlaybackTime() { + if (channel >= 0) + return getRenderer().getSourcePlaybackTime(this); + else + return 0; + } public Vector3f getPosition() { return getWorldTranslation(); diff --git a/jme3-core/src/main/java/com/jme3/audio/AudioRenderer.java b/jme3-core/src/main/java/com/jme3/audio/AudioRenderer.java index 78ea88e91..695999e48 100644 --- a/jme3-core/src/main/java/com/jme3/audio/AudioRenderer.java +++ b/jme3-core/src/main/java/com/jme3/audio/AudioRenderer.java @@ -59,6 +59,7 @@ public interface AudioRenderer { public void updateSourceParam(AudioSource src, AudioParam param); public void updateListenerParam(Listener listener, ListenerParam param); + public float getSourcePlaybackTime(AudioSource src); public void deleteFilter(Filter filter); public void deleteAudioData(AudioData ad); diff --git a/jme3-core/src/main/java/com/jme3/audio/AudioSource.java b/jme3-core/src/main/java/com/jme3/audio/AudioSource.java index 3aa23b78d..75a4e70f9 100644 --- a/jme3-core/src/main/java/com/jme3/audio/AudioSource.java +++ b/jme3-core/src/main/java/com/jme3/audio/AudioSource.java @@ -95,6 +95,11 @@ public interface AudioSource { * @return the time offset in the sound sample when to start playing. */ public float getTimeOffset(); + + /** + * @return the current playback position of the source in seconds. + */ + public float getPlaybackTime(); /** * @return The velocity of the audio source. diff --git a/jme3-core/src/main/java/com/jme3/audio/AudioStream.java b/jme3-core/src/main/java/com/jme3/audio/AudioStream.java index f7ff4c04b..598ae189c 100644 --- a/jme3-core/src/main/java/com/jme3/audio/AudioStream.java +++ b/jme3-core/src/main/java/com/jme3/audio/AudioStream.java @@ -54,6 +54,8 @@ public class AudioStream extends AudioData implements Closeable { protected boolean eof = false; protected int[] ids; + protected int unqueuedBuffersBytes = 0; + public AudioStream() { super(); } @@ -196,10 +198,21 @@ public class AudioStream extends AudioData implements Closeable { return in instanceof SeekableStream; } + public int getUnqueuedBufferBytes() { + return unqueuedBuffersBytes; + } + + public void setUnqueuedBufferBytes(int unqueuedBuffers) { + this.unqueuedBuffersBytes = unqueuedBuffers; + } + public void setTime(float time) { if (in instanceof SeekableStream) { ((SeekableStream) in).setTime(time); eof = false; + + // TODO: when we actually support seeking, this will need to be properly set. + unqueuedBuffersBytes = 0; } else { throw new IllegalStateException( "Cannot use setTime on a stream that " diff --git a/jme3-core/src/main/java/com/jme3/audio/openal/ALAudioRenderer.java b/jme3-core/src/main/java/com/jme3/audio/openal/ALAudioRenderer.java index c3ccea741..62f04018a 100644 --- a/jme3-core/src/main/java/com/jme3/audio/openal/ALAudioRenderer.java +++ b/jme3-core/src/main/java/com/jme3/audio/openal/ALAudioRenderer.java @@ -301,6 +301,58 @@ public class ALAudioRenderer implements AudioRenderer, Runnable { f.clearUpdateNeeded(); } + @Override + public float getSourcePlaybackTime(AudioSource src) { + checkDead(); + synchronized (threadLock) { + if (audioDisabled) { + return 0; + } + + // See comment in updateSourceParam(). + if (src.getChannel() < 0) { + return 0; + } + + int id = channels[src.getChannel()]; + AudioData data = src.getAudioData(); + int playbackOffsetBytes = 0; + + if (data instanceof AudioStream) { + // Because audio streams are processed in buffer chunks, + // we have to compute the amount of time the stream was already + // been playing based on the number of buffers that were processed. + AudioStream stream = (AudioStream) data; + + // NOTE: the assumption is that all enqueued buffers are the same size. + // this is currently enforced by fillBuffer(). + + // The number of unenqueued bytes that the decoder thread + // keeps track of. + int unqueuedBytes = stream.getUnqueuedBufferBytes(); + + // Additional processed buffers that the decoder thread + // did not unenqueue yet (it only updates 20 times per second). + int unqueuedBytesExtra = al.alGetSourcei(id, AL_BUFFERS_PROCESSED) * BUFFER_SIZE; + + // Total additional bytes that need to be considered. + playbackOffsetBytes = unqueuedBytes; // + unqueuedBytesExtra; + } + + // Add byte offset from source (for both streams and buffers) + playbackOffsetBytes += al.alGetSourcei(id, AL_BYTE_OFFSET); + + // Compute time value from bytes + // E.g. for 44100 source with 2 channels and 16 bits per sample: + // (44100 * 2 * 16 / 8) = 176400 + int bytesPerSecond = (data.getSampleRate() * + data.getChannels() * + data.getBitsPerSample() / 8); + + return (float)playbackOffsetBytes / bytesPerSecond; + } + } + public void updateSourceParam(AudioSource src, AudioParam param) { checkDead(); synchronized (threadLock) { @@ -648,6 +700,7 @@ public class ALAudioRenderer implements AudioRenderer, Runnable { private boolean fillStreamingSource(int sourceId, AudioStream stream, boolean looping) { boolean success = false; int processed = al.alGetSourcei(sourceId, AL_BUFFERS_PROCESSED); + int unqueuedBufferBytes = 0; for (int i = 0; i < processed; i++) { int buffer; @@ -656,6 +709,11 @@ public class ALAudioRenderer implements AudioRenderer, Runnable { al.alSourceUnqueueBuffers(sourceId, 1, ib); buffer = ib.get(0); + // XXX: assume that reading from AudioStream always + // gives BUFFER_SIZE amount of bytes! This might not always + // be the case... + unqueuedBufferBytes += BUFFER_SIZE; + boolean active = fillBuffer(stream, buffer); if (!active && !stream.isEOF()) { @@ -682,6 +740,8 @@ public class ALAudioRenderer implements AudioRenderer, Runnable { break; } } + + stream.setUnqueuedBufferBytes(stream.getUnqueuedBufferBytes() + unqueuedBufferBytes); return success; } diff --git a/jme3-core/src/main/java/com/jme3/cinematic/Cinematic.java b/jme3-core/src/main/java/com/jme3/cinematic/Cinematic.java index 373f6fac0..e610ef40b 100644 --- a/jme3-core/src/main/java/com/jme3/cinematic/Cinematic.java +++ b/jme3-core/src/main/java/com/jme3/cinematic/Cinematic.java @@ -702,7 +702,9 @@ public class Cinematic extends AbstractCinematicEvent implements AppState { dispose(); cinematicEvents.clear(); timeLine.clear(); - eventsData.clear(); + if (eventsData != null) { + eventsData.clear(); + } } /** diff --git a/jme3-core/src/main/java/com/jme3/cinematic/events/AnimationEvent.java b/jme3-core/src/main/java/com/jme3/cinematic/events/AnimationEvent.java index e8bfc5392..738b445b1 100644 --- a/jme3-core/src/main/java/com/jme3/cinematic/events/AnimationEvent.java +++ b/jme3-core/src/main/java/com/jme3/cinematic/events/AnimationEvent.java @@ -43,7 +43,7 @@ import com.jme3.export.JmeImporter; import com.jme3.export.OutputCapsule; import com.jme3.scene.Spatial; import java.io.IOException; -import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.logging.Logger; @@ -431,15 +431,17 @@ public class AnimationEvent extends AbstractCinematicEvent { @Override public void dispose() { super.dispose(); - Object o = cinematic.getEventData(MODEL_CHANNELS, model); - if (o != null) { - ArrayList list = (ArrayList) o; - list.remove(channel); - if (list.isEmpty()) { - cinematic.removeEventData(MODEL_CHANNELS, model); + if (cinematic != null) { + Object o = cinematic.getEventData(MODEL_CHANNELS, model); + if (o != null) { + Collection values = ((HashMap) o).values(); + while (values.remove(channel)); + if (values.isEmpty()) { + cinematic.removeEventData(MODEL_CHANNELS, model); + } } + cinematic = null; + channel = null; } - cinematic = null; - channel = null; } } diff --git a/jme3-core/src/main/java/com/jme3/collision/bih/BIHTree.java b/jme3-core/src/main/java/com/jme3/collision/bih/BIHTree.java index 38a633e96..5db94b409 100644 --- a/jme3-core/src/main/java/com/jme3/collision/bih/BIHTree.java +++ b/jme3-core/src/main/java/com/jme3/collision/bih/BIHTree.java @@ -48,6 +48,7 @@ import com.jme3.math.Vector3f; import com.jme3.scene.CollisionData; import com.jme3.scene.Mesh; import com.jme3.scene.Mesh.Mode; +import com.jme3.scene.VertexBuffer; import com.jme3.scene.VertexBuffer.Type; import com.jme3.scene.mesh.IndexBuffer; import com.jme3.scene.mesh.VirtualIndexBuffer; @@ -114,8 +115,13 @@ public class BIHTree implements CollisionData { bihSwapTmp = new float[9]; - FloatBuffer vb = (FloatBuffer) mesh.getBuffer(Type.Position).getData(); + VertexBuffer vBuffer = mesh.getBuffer(Type.Position); + if(vBuffer == null){ + throw new IllegalArgumentException("A mesh should at least contain a Position buffer"); + } IndexBuffer ib = mesh.getIndexBuffer(); + FloatBuffer vb = (FloatBuffer) vBuffer.getData(); + if (ib == null) { ib = new VirtualIndexBuffer(mesh.getVertexCount(), mesh.getMode()); } else if (mesh.getMode() != Mode.Triangles) { diff --git a/jme3-core/src/main/java/com/jme3/export/JmeExporter.java b/jme3-core/src/main/java/com/jme3/export/JmeExporter.java index 0afd170ea..b8c3abc60 100644 --- a/jme3-core/src/main/java/com/jme3/export/JmeExporter.java +++ b/jme3-core/src/main/java/com/jme3/export/JmeExporter.java @@ -46,22 +46,18 @@ public interface JmeExporter { * * @param object The savable to export * @param f The output stream - * @return Always returns true. If an error occurs during export, - * an exception is thrown * @throws IOException If an io exception occurs during export */ - public boolean save(Savable object, OutputStream f) throws IOException; + public void save(Savable object, OutputStream f) throws IOException; /** * Export the {@link Savable} to a file. * * @param object The savable to export * @param f The file to export to - * @return Always returns true. If an error occurs during export, - * an exception is thrown * @throws IOException If an io exception occurs during export */ - public boolean save(Savable object, File f) throws IOException; + public void save(Savable object, File f) throws IOException; /** * Returns the {@link OutputCapsule} for the given savable object. diff --git a/jme3-core/src/main/java/com/jme3/input/DefaultJoystickAxis.java b/jme3-core/src/main/java/com/jme3/input/DefaultJoystickAxis.java index 954451145..8f32c2d6b 100644 --- a/jme3-core/src/main/java/com/jme3/input/DefaultJoystickAxis.java +++ b/jme3-core/src/main/java/com/jme3/input/DefaultJoystickAxis.java @@ -72,8 +72,10 @@ public class DefaultJoystickAxis implements JoystickAxis { * @param negativeMapping The mapping to receive events when the axis is positive */ public void assignAxis(String positiveMapping, String negativeMapping){ - inputManager.addMapping(positiveMapping, new JoyAxisTrigger(parent.getJoyId(), axisIndex, false)); - inputManager.addMapping(negativeMapping, new JoyAxisTrigger(parent.getJoyId(), axisIndex, true)); + if (axisIndex != -1) { + inputManager.addMapping(positiveMapping, new JoyAxisTrigger(parent.getJoyId(), axisIndex, false)); + inputManager.addMapping(negativeMapping, new JoyAxisTrigger(parent.getJoyId(), axisIndex, true)); + } } /** diff --git a/jme3-core/src/main/java/com/jme3/light/AmbientLight.java b/jme3-core/src/main/java/com/jme3/light/AmbientLight.java index e147c6590..8dd5f9266 100644 --- a/jme3-core/src/main/java/com/jme3/light/AmbientLight.java +++ b/jme3-core/src/main/java/com/jme3/light/AmbientLight.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2012 jMonkeyEngine + * Copyright (c) 2009-2012, 2015 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,6 +32,7 @@ package com.jme3.light; import com.jme3.bounding.BoundingBox; +import com.jme3.math.ColorRGBA; import com.jme3.math.Vector3f; import com.jme3.renderer.Camera; import com.jme3.scene.Spatial; @@ -49,6 +50,13 @@ import com.jme3.util.TempVars; */ public class AmbientLight extends Light { + public AmbientLight() { + } + + public AmbientLight(ColorRGBA color) { + super(color); + } + @Override public boolean intersectsBox(BoundingBox box, TempVars vars) { return true; diff --git a/jme3-core/src/main/java/com/jme3/light/DirectionalLight.java b/jme3-core/src/main/java/com/jme3/light/DirectionalLight.java index c4258a67f..87fbf695a 100644 --- a/jme3-core/src/main/java/com/jme3/light/DirectionalLight.java +++ b/jme3-core/src/main/java/com/jme3/light/DirectionalLight.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2012 jMonkeyEngine + * Copyright (c) 2009-2012, 2015 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,6 +36,7 @@ import com.jme3.export.InputCapsule; import com.jme3.export.JmeExporter; import com.jme3.export.JmeImporter; import com.jme3.export.OutputCapsule; +import com.jme3.math.ColorRGBA; import com.jme3.math.Vector3f; import com.jme3.renderer.Camera; import com.jme3.scene.Spatial; @@ -53,6 +54,30 @@ public class DirectionalLight extends Light { protected Vector3f direction = new Vector3f(0f, -1f, 0f); + /** + * Creates a DirectionalLight + */ + public DirectionalLight() { + } + + /** + * Creates a DirectionalLight with the given direction + * @param direction the light's direction + */ + public DirectionalLight(Vector3f direction) { + setDirection(direction); + } + + /** + * Creates a DirectionalLight with the given direction and the given color + * @param direction the light's direction + * @param color the light's color + */ + public DirectionalLight(Vector3f direction, ColorRGBA color) { + super(color); + setDirection(direction); + } + @Override public void computeLastDistance(Spatial owner) { lastDistance = 0; // directional lights are always closest to their owner @@ -77,7 +102,7 @@ public class DirectionalLight extends Light { * * @param dir the direction of the light. */ - public void setDirection(Vector3f dir){ + public final void setDirection(Vector3f dir){ direction.set(dir); if (!direction.isUnitVector()) { direction.normalizeLocal(); diff --git a/jme3-core/src/main/java/com/jme3/light/Light.java b/jme3-core/src/main/java/com/jme3/light/Light.java index 4217e1b62..b1c48be7a 100644 --- a/jme3-core/src/main/java/com/jme3/light/Light.java +++ b/jme3-core/src/main/java/com/jme3/light/Light.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2012 jMonkeyEngine + * Copyright (c) 2009-2012, 2015 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -94,7 +94,7 @@ public abstract class Light implements Savable, Cloneable { } } - protected ColorRGBA color = new ColorRGBA(1f,1f,1f,1f); + protected ColorRGBA color = new ColorRGBA(ColorRGBA.White); /** * Used in LightList for caching the distance @@ -115,6 +115,13 @@ public abstract class Light implements Savable, Cloneable { boolean frustumCheckNeeded = true; boolean intersectsFrustum = false; + protected Light() { + } + + protected Light(ColorRGBA color) { + setColor(color); + } + /** * Returns the color of the light. * diff --git a/jme3-core/src/main/java/com/jme3/light/PointLight.java b/jme3-core/src/main/java/com/jme3/light/PointLight.java index 55a129275..ff3b3295f 100644 --- a/jme3-core/src/main/java/com/jme3/light/PointLight.java +++ b/jme3-core/src/main/java/com/jme3/light/PointLight.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2012 jMonkeyEngine + * Copyright (c) 2009-2012, 2015 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,14 +32,13 @@ package com.jme3.light; import com.jme3.bounding.BoundingBox; -import com.jme3.bounding.BoundingSphere; import com.jme3.bounding.BoundingVolume; import com.jme3.export.InputCapsule; import com.jme3.export.JmeExporter; import com.jme3.export.JmeImporter; import com.jme3.export.OutputCapsule; +import com.jme3.math.ColorRGBA; import com.jme3.math.FastMath; -import com.jme3.math.Plane; import com.jme3.math.Vector3f; import com.jme3.renderer.Camera; import com.jme3.scene.Spatial; @@ -62,6 +61,52 @@ public class PointLight extends Light { protected float radius = 0; protected float invRadius = 0; + /** + * Creates a PointLight + */ + public PointLight() { + } + + /** + * Creates a PointLight at the given position + * @param position the position in world space + */ + public PointLight(Vector3f position) { + setPosition(position); + } + + /** + * Creates a PointLight at the given position and with the given color + * @param position the position in world space + * @param color the light color + */ + public PointLight(Vector3f position, ColorRGBA color) { + super(color); + setPosition(position); + } + + /** + * Creates a PointLight at the given position, with the given color and the + * given radius + * @param position the position in world space + * @param color the light color + * @param radius the light radius + */ + public PointLight(Vector3f position, ColorRGBA color, float radius) { + this(position, color); + setRadius(radius); + } + + /** + * Creates a PointLight at the given position, with the given radius + * @param position the position in world space + * @param radius the light radius + */ + public PointLight(Vector3f position, float radius) { + this(position); + setRadius(radius); + } + @Override public void computeLastDistance(Spatial owner) { if (owner.getWorldBound() != null) { @@ -88,7 +133,7 @@ public class PointLight extends Light { * * @param position the world space position of the light. */ - public void setPosition(Vector3f position) { + public final void setPosition(Vector3f position) { this.position.set(position); } @@ -115,13 +160,13 @@ public class PointLight extends Light { * * @throws IllegalArgumentException If radius is negative */ - public void setRadius(float radius) { + public final void setRadius(float radius) { if (radius < 0) { throw new IllegalArgumentException("Light radius cannot be negative"); } this.radius = radius; - if (radius != 0) { - this.invRadius = 1 / radius; + if (radius != 0f) { + this.invRadius = 1f / radius; } else { this.invRadius = 0; } diff --git a/jme3-core/src/main/java/com/jme3/light/SpotLight.java b/jme3-core/src/main/java/com/jme3/light/SpotLight.java index f02f76fa4..9b551d3d8 100644 --- a/jme3-core/src/main/java/com/jme3/light/SpotLight.java +++ b/jme3-core/src/main/java/com/jme3/light/SpotLight.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2012 jMonkeyEngine + * Copyright (c) 2009-2012, 2015 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,6 +34,7 @@ package com.jme3.light; import com.jme3.bounding.BoundingBox; import com.jme3.bounding.BoundingVolume; import com.jme3.export.*; +import com.jme3.math.ColorRGBA; import com.jme3.math.FastMath; import com.jme3.math.Plane; import com.jme3.math.Vector3f; @@ -44,36 +45,121 @@ import java.io.IOException; /** * Represents a spot light. - * A spot light emmit a cone of light from a position and in a direction. - * It can be used to fake torch lights or car's lights. + * A spot light emits a cone of light from a position and in a direction. + * It can be used to fake torch lights or cars' lights. *

* In addition to a position and a direction, spot lights also have a range which * can be used to attenuate the influence of the light depending on the - * distance between the light and the effected object. + * distance between the light and the affected object. * Also the angle of the cone can be tweaked by changing the spot inner angle and the spot outer angle. - * the spot inner angle determin the cone of light where light has full influence. - * the spot outer angle determin the cone global cone of light of the spot light. - * the light intensity slowly decrease between the inner cone and the outer cone. + * the spot inner angle determines the cone of light where light has full influence. + * the spot outer angle determines the cone global cone of light of the spot light. + * the light intensity slowly decreases between the inner cone and the outer cone. * @author Nehon */ public class SpotLight extends Light { protected Vector3f position = new Vector3f(); - protected Vector3f direction = new Vector3f(0,-1,0); + protected Vector3f direction = new Vector3f(0, -1, 0); protected float spotInnerAngle = FastMath.QUARTER_PI / 8; protected float spotOuterAngle = FastMath.QUARTER_PI / 6; protected float spotRange = 100; - protected float invSpotRange = 1 / 100; - protected float packedAngleCos=0; + protected float invSpotRange = 1f / 100; + protected float packedAngleCos = 0; protected float outerAngleCosSqr, outerAngleSinSqr; protected float outerAngleSinRcp, outerAngleSin, outerAngleCos; + /** + * Creates a SpotLight. + */ public SpotLight() { super(); computeAngleParameters(); } + /** + * Creates a SpotLight at the given position and with the given direction. + * @param position the position in world space. + * @param direction the direction of the light. + */ + public SpotLight(Vector3f position, Vector3f direction) { + this(); + setPosition(position); + setDirection(direction); + } + + /** + * Creates a SpotLight at the given position, with the given direction, and the + * given range. + * @param position the position in world space. + * @param direction the direction of the light. + * @param range the spot light range + */ + public SpotLight(Vector3f position, Vector3f direction, float range) { + this(); + setPosition(position); + setDirection(direction); + this.spotRange = range; + } + + /** + * Creates a SpotLight at the given position, with the given direction and + * the given color. + * @param position the position in world space. + * @param direction the direction of the light. + * @param color the light's color. + */ + public SpotLight(Vector3f position, Vector3f direction, ColorRGBA color) { + super(color); + computeAngleParameters(); + setPosition(position); + setDirection(direction); + } + + + /** + * Creates a SpotLight at the given position, with the given direction, + * the given range and the given color. + * @param position the position in world space. + * @param direction the direction of the light. + * @param range the spot light range + * @param color the light's color. + */ + public SpotLight(Vector3f position, Vector3f direction, float range, ColorRGBA color) { + super(color); + computeAngleParameters(); + setPosition(position); + setDirection(direction); + this.spotRange = range; + } + + /** + * Creates a SpotLight at the given position, with the given direction, + * the given color and the given inner and outer angles + * (controls the falloff of the light) + * + * @param position the position in world space. + * @param direction the direction of the light. + * @param range the spot light range + * @param color the light's color. + * @param innerAngle the inner angle of the spot light. + * @param outerAngle the outer angle of the spot light. + * + * @see SpotLight#setSpotInnerAngle(float) + * @see SpotLight#setSpotOuterAngle(float) + */ + public SpotLight(Vector3f position, Vector3f direction, float range, ColorRGBA color, float innerAngle, float outerAngle) { + super(color); + this.spotInnerAngle = innerAngle; + this.spotOuterAngle = outerAngle; + computeAngleParameters(); + setPosition(position); + setDirection(direction); + this.spotRange = range; + } + + private void computeAngleParameters() { float innerCos = FastMath.cos(spotInnerAngle); outerAngleCos = FastMath.cos(spotOuterAngle); @@ -189,7 +275,7 @@ public class SpotLight extends Light { return direction; } - public void setDirection(Vector3f direction) { + public final void setDirection(Vector3f direction) { this.direction.set(direction); } @@ -197,7 +283,7 @@ public class SpotLight extends Light { return position; } - public void setPosition(Vector3f position) { + public final void setPosition(Vector3f position) { this.position.set(position); } diff --git a/jme3-core/src/main/java/com/jme3/material/Material.java b/jme3-core/src/main/java/com/jme3/material/Material.java index 5f0ab8f91..44bfb73f5 100644 --- a/jme3-core/src/main/java/com/jme3/material/Material.java +++ b/jme3-core/src/main/java/com/jme3/material/Material.java @@ -69,7 +69,7 @@ import java.util.logging.Logger; * Setting the parameters can modify the behavior of a * shader. *

- * + * * @author Kirill Vainer */ public class Material implements CloneableSmartAsset, Cloneable, Savable { @@ -146,7 +146,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { public String getName() { return name; } - + /** * This method sets the name of the material. * The name is not the same as the asset name. @@ -222,11 +222,11 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { } /** - * Compares two materials and returns true if they are equal. + * Compares two materials and returns true if they are equal. * This methods compare definition, parameters, additional render states. - * Since materials are mutable objects, implementing equals() properly is not possible, + * Since materials are mutable objects, implementing equals() properly is not possible, * hence the name contentEquals(). - * + * * @param otherObj the material to compare to this material * @return true if the materials are equal. */ @@ -234,15 +234,15 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { if (!(otherObj instanceof Material)) { return false; } - + Material other = (Material) otherObj; - + // Early exit if the material are the same object if (this == other) { return true; } - // Check material definition + // Check material definition if (this.getMaterialDef() != other.getMaterialDef()) { return false; } @@ -251,12 +251,12 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { if (this.paramValues.size() != other.paramValues.size()) { return false; } - + // Checking technique if (this.technique != null || other.technique != null) { // Techniques are considered equal if their names are the same - // E.g. if user chose custom technique for one material but - // uses default technique for other material, the materials + // E.g. if user chose custom technique for one material but + // uses default technique for other material, the materials // are not equal. String thisDefName = this.technique != null ? this.technique.getDef().getName() : "Default"; String otherDefName = other.technique != null ? other.technique.getDef().getName() : "Default"; @@ -290,7 +290,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { return false; } } - + return true; } @@ -305,7 +305,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { hash = 29 * hash + (this.additionalState != null ? this.additionalState.contentHashCode() : 0); return hash; } - + /** * Returns the currently active technique. *

@@ -436,7 +436,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { public Collection getParams() { return paramValues.values(); } - + /** * Returns the ListMap of all parameters set on this material. * @@ -473,7 +473,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { */ public void setParam(String name, VarType type, Object value) { checkSetParam(type, name); - + if (type.isTextureType()) { setTextureParam(name, type, (Texture)value); } else { @@ -501,7 +501,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { if (matParam == null) { return; } - + paramValues.remove(name); if (matParam instanceof MatParamTexture) { int texUnit = ((MatParamTexture) matParam).getUnit(); @@ -728,7 +728,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { renderer.renderMesh(mesh, lodLevel, 1, null); } } - + /** * Uploads the lights in the light list as two uniform arrays.

* *

@@ -747,30 +747,30 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { return 0; } - Uniform lightData = shader.getUniform("g_LightData"); - lightData.setVector4Length(numLights * 3);//8 lights * max 3 + Uniform lightData = shader.getUniform("g_LightData"); + lightData.setVector4Length(numLights * 3);//8 lights * max 3 Uniform ambientColor = shader.getUniform("g_AmbientLightColor"); - - if (startIndex != 0) { + + if (startIndex != 0) { // apply additive blending for 2nd and future passes rm.getRenderer().applyRenderState(additiveLight); - ambientColor.setValue(VarType.Vector4, ColorRGBA.Black); + ambientColor.setValue(VarType.Vector4, ColorRGBA.Black); }else{ ambientColor.setValue(VarType.Vector4, getAmbientColor(lightList,true)); } - + int lightDataIndex = 0; TempVars vars = TempVars.get(); Vector4f tmpVec = vars.vect4f1; int curIndex; int endIndex = numLights + startIndex; for (curIndex = startIndex; curIndex < endIndex && curIndex < lightList.size(); curIndex++) { - - - Light l = lightList.get(curIndex); + + + Light l = lightList.get(curIndex); if(l.getType() == Light.Type.Ambient){ - endIndex++; + endIndex++; continue; } ColorRGBA color = l.getColor(); @@ -781,14 +781,14 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { l.getType().getId(), lightDataIndex); lightDataIndex++; - + switch (l.getType()) { case Directional: DirectionalLight dl = (DirectionalLight) l; - Vector3f dir = dl.getDirection(); + Vector3f dir = dl.getDirection(); //Data directly sent in view space to avoid a matrix mult for each pixel tmpVec.set(dir.getX(), dir.getY(), dir.getZ(), 0.0f); - rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec); + rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec); // tmpVec.divideLocal(tmpVec.w); // tmpVec.normalizeLocal(); lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), -1, lightDataIndex); @@ -802,7 +802,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { Vector3f pos = pl.getPosition(); float invRadius = pl.getInvRadius(); tmpVec.set(pos.getX(), pos.getY(), pos.getZ(), 1.0f); - rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec); + rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec); //tmpVec.divideLocal(tmpVec.w); lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), invRadius, lightDataIndex); lightDataIndex++; @@ -810,37 +810,37 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { lightData.setVector4InArray(0,0,0,0, lightDataIndex); lightDataIndex++; break; - case Spot: + case Spot: SpotLight sl = (SpotLight) l; Vector3f pos2 = sl.getPosition(); Vector3f dir2 = sl.getDirection(); float invRange = sl.getInvSpotRange(); float spotAngleCos = sl.getPackedAngleCos(); tmpVec.set(pos2.getX(), pos2.getY(), pos2.getZ(), 1.0f); - rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec); + rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec); // tmpVec.divideLocal(tmpVec.w); lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), invRange, lightDataIndex); lightDataIndex++; - + //We transform the spot direction in view space here to save 5 varying later in the lighting shader //one vec4 less and a vec4 that becomes a vec3 //the downside is that spotAngleCos decoding happens now in the frag shader. tmpVec.set(dir2.getX(), dir2.getY(), dir2.getZ(), 0.0f); - rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec); + rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec); tmpVec.normalizeLocal(); lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), spotAngleCos, lightDataIndex); lightDataIndex++; - break; + break; default: throw new UnsupportedOperationException("Unknown type of light: " + l.getType()); } } - vars.release(); + vars.release(); //Padding of unsued buffer space while(lightDataIndex < numLights * 3) { lightData.setVector4InArray(0f, 0f, 0f, 0f, lightDataIndex); - lightDataIndex++; - } + lightDataIndex++; + } return curIndex; } @@ -887,10 +887,10 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { case Directional: DirectionalLight dl = (DirectionalLight) l; Vector3f dir = dl.getDirection(); - //FIXME : there is an inconstency here due to backward + //FIXME : there is an inconstency here due to backward //compatibility of the lighting shader. - //The directional light direction is passed in the - //LightPosition uniform. The lighting shader needs to be + //The directional light direction is passed in the + //LightPosition uniform. The lighting shader needs to be //reworked though in order to fix this. tmpLightPosition.set(dir.getX(), dir.getY(), dir.getZ(), -1); lightPos.setValue(VarType.Vector4, tmpLightPosition); @@ -987,11 +987,11 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { for (TechniqueDef techDef : techDefs) { if (rendererCaps.containsAll(techDef.getRequiredCaps())) { // use the first one that supports all the caps - tech = new Technique(this, techDef); + tech = new Technique(this, techDef); techniques.put(name, tech); if(tech.getDef().getLightMode() == renderManager.getPreferredLightMode() || tech.getDef().getLightMode() == LightMode.Disable){ - break; + break; } } lastTech = techDef; @@ -1078,7 +1078,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { Uniform u = uniforms.getValue(i); if (!u.isSetByCurrentMaterial()) { if (u.getName().charAt(0) != 'g') { - // Don't reset world globals! + // Don't reset world globals! // The benefits gained from this are very minimal // and cause lots of matrix -> FloatBuffer conversions. u.clearValue(); @@ -1093,21 +1093,21 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { *

* The material is rendered as follows: *

    - *
  • Determine which technique to use to render the material - - * either what the user selected via - * {@link #selectTechnique(java.lang.String, com.jme3.renderer.RenderManager) - * Material.selectTechnique()}, - * or the first default technique that the renderer supports + *
  • Determine which technique to use to render the material - + * either what the user selected via + * {@link #selectTechnique(java.lang.String, com.jme3.renderer.RenderManager) + * Material.selectTechnique()}, + * or the first default technique that the renderer supports * (based on the technique's {@link TechniqueDef#getRequiredCaps() requested rendering capabilities})
      - *
    • If the technique has been changed since the last frame, then it is notified via - * {@link Technique#makeCurrent(com.jme3.asset.AssetManager, boolean, java.util.EnumSet) - * Technique.makeCurrent()}. - * If the technique wants to use a shader to render the model, it should load it at this part - - * the shader should have all the proper defines as declared in the technique definition, - * including those that are bound to material parameters. - * The technique can re-use the shader from the last frame if + *
    • If the technique has been changed since the last frame, then it is notified via + * {@link Technique#makeCurrent(com.jme3.asset.AssetManager, boolean, java.util.EnumSet) + * Technique.makeCurrent()}. + * If the technique wants to use a shader to render the model, it should load it at this part - + * the shader should have all the proper defines as declared in the technique definition, + * including those that are bound to material parameters. + * The technique can re-use the shader from the last frame if * no changes to the defines occurred.
    - *
  • Set the {@link RenderState} to use for rendering. The render states are + *
  • Set the {@link RenderState} to use for rendering. The render states are * applied in this order (later RenderStates override earlier RenderStates):
      *
    1. {@link TechniqueDef#getRenderState() Technique Definition's RenderState} * - i.e. specific renderstate that is required for the shader.
    2. @@ -1120,22 +1120,22 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { *
    3. Uniforms bound to material parameters are updated based on the current material parameter values.
    4. *
    5. Uniforms bound to world parameters are updated from the RenderManager. * Internally {@link UniformBindingManager} is used for this task.
    6. - *
    7. Uniforms bound to textures will cause the texture to be uploaded as necessary. + *
    8. Uniforms bound to textures will cause the texture to be uploaded as necessary. * The uniform is set to the texture unit where the texture is bound.
- *
  • If the technique uses a shader, the model is then rendered according + *
  • If the technique uses a shader, the model is then rendered according * to the lighting mode specified on the technique definition.
      - *
    • {@link LightMode#SinglePass single pass light mode} fills the shader's light uniform arrays + *
    • {@link LightMode#SinglePass single pass light mode} fills the shader's light uniform arrays * with the first 4 lights and renders the model once.
    • - *
    • {@link LightMode#MultiPass multi pass light mode} light mode renders the model multiple times, - * for the first light it is rendered opaque, on subsequent lights it is + *
    • {@link LightMode#MultiPass multi pass light mode} light mode renders the model multiple times, + * for the first light it is rendered opaque, on subsequent lights it is * rendered with {@link BlendMode#AlphaAdditive alpha-additive} blending and depth writing disabled.
    • *
    - *
  • For techniques that do not use shaders, + *
  • For techniques that do not use shaders, * fixed function OpenGL is used to render the model (see {@link GL1Renderer} interface):
      *
    • OpenGL state ({@link FixedFuncBinding}) that is bound to material parameters is updated.
    • - *
    • The texture set on the material is uploaded and bound. + *
    • The texture set on the material is uploaded and bound. * Currently only 1 texture is supported for fixed function techniques.
    • - *
    • If the technique uses lighting, then OpenGL lighting state is updated + *
    • If the technique uses lighting, then OpenGL lighting state is updated * based on the light list on the geometry, otherwise OpenGL lighting is disabled.
    • *
    • The mesh is uploaded and rendered.
    • *
    @@ -1147,10 +1147,11 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { */ public void render(Geometry geom, LightList lights, RenderManager rm) { autoSelectTechnique(rm); + TechniqueDef techDef = technique.getDef(); - Renderer r = rm.getRenderer(); + if (techDef.isNoRender()) return; - TechniqueDef techDef = technique.getDef(); + Renderer r = rm.getRenderer(); if (rm.getForcedRenderState() != null) { r.applyRenderState(rm.getForcedRenderState()); @@ -1169,7 +1170,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { // reset unchanged uniform flag clearUniformsSetByCurrent(technique.getShader()); rm.updateUniformBindings(technique.getWorldBindUniforms()); - + // setup textures and uniforms for (int i = 0; i < paramValues.size(); i++) { @@ -1212,24 +1213,24 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { // any unset uniforms will be set to 0 resetUniformsNotSetByCurrent(shader); r.setShader(shader); - + renderMeshFromGeometry(r, geom); } /** * Called by {@link RenderManager} to render the geometry by * using this material. - * + * * Note that this version of the render method * does not perform light filtering. - * + * * @param geom The geometry to render * @param rm The render manager requesting the rendering */ public void render(Geometry geom, RenderManager rm) { render(geom, geom.getWorldLightList(), rm); } - + public void write(JmeExporter ex) throws IOException { OutputCapsule oc = ex.getCapsule(this); oc.write(def.getAssetName(), "material_def", null); @@ -1304,14 +1305,14 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable { continue; } } - + if (im.getFormatVersion() == 0 && param.getName().startsWith("m_")) { // Ancient version of jME3 ... param.setName(param.getName().substring(2)); } - + if (def.getMaterialParam(param.getName()) == null) { - logger.log(Level.WARNING, "The material parameter is not defined: {0}. Ignoring..", + logger.log(Level.WARNING, "The material parameter is not defined: {0}. Ignoring..", param.getName()); } else { checkSetParam(param.getVarType(), param.getName()); diff --git a/jme3-core/src/main/java/com/jme3/material/TechniqueDef.java b/jme3-core/src/main/java/com/jme3/material/TechniqueDef.java index f8152e563..d7523956c 100644 --- a/jme3-core/src/main/java/com/jme3/material/TechniqueDef.java +++ b/jme3-core/src/main/java/com/jme3/material/TechniqueDef.java @@ -40,7 +40,7 @@ import java.util.*; /** * Describes a technique definition. - * + * * @author Kirill Vainer */ public class TechniqueDef implements Savable { @@ -49,7 +49,7 @@ public class TechniqueDef implements Savable { * Version #1: Separate shader language for each shader source. */ public static final int SAVABLE_VERSION = 1; - + /** * Describes light rendering mode. */ @@ -58,15 +58,15 @@ public class TechniqueDef implements Savable { * Disable light-based rendering */ Disable, - + /** - * Enable light rendering by using a single pass. + * Enable light rendering by using a single pass. *

    * An array of light positions and light colors is passed to the shader * containing the world light list for the geometry being rendered. */ SinglePass, - + /** * Enable light rendering by using multi-pass rendering. *

    @@ -77,7 +77,7 @@ public class TechniqueDef implements Savable { * passes have it set to black. */ MultiPass, - + /** * @deprecated OpenGL1 is not supported anymore */ @@ -96,15 +96,16 @@ public class TechniqueDef implements Savable { private EnumMap shaderLanguages; private EnumMap shaderNames; - + private DefineList presetDefines; private boolean usesNodes = false; private List shaderNodes; private ShaderGenerationInfo shaderGenerationInfo; + private boolean noRender = false; private RenderState renderState; private RenderState forcedRenderState; - + private LightMode lightMode = LightMode.Disable; private ShadowMode shadowMode = ShadowMode.Disable; @@ -115,7 +116,7 @@ public class TechniqueDef implements Savable { * Creates a new technique definition. *

    * Used internally by the J3M/J3MD loader. - * + * * @param name The name of the technique, should be set to null * for default techniques. */ @@ -135,7 +136,7 @@ public class TechniqueDef implements Savable { /** * Returns the name of this technique as specified in the J3MD file. * Default techniques have the name "Default". - * + * * @return the name of this technique */ public String getName(){ @@ -153,9 +154,9 @@ public class TechniqueDef implements Savable { /** * Set the light mode - * + * * @param lightMode the light mode - * + * * @see LightMode */ public void setLightMode(LightMode lightMode) { @@ -172,9 +173,9 @@ public class TechniqueDef implements Savable { /** * Set the shadow mode. - * + * * @param shadowMode the shadow mode. - * + * * @see ShadowMode */ public void setShadowMode(ShadowMode shadowMode) { @@ -184,7 +185,7 @@ public class TechniqueDef implements Savable { /** * Returns the render state that this technique is using * @return the render state that this technique is using - * @see #setRenderState(com.jme3.material.RenderState) + * @see #setRenderState(com.jme3.material.RenderState) */ public RenderState getRenderState() { return renderState; @@ -192,15 +193,37 @@ public class TechniqueDef implements Savable { /** * Sets the render state that this technique is using. - * + * * @param renderState the render state that this technique is using. - * + * * @see RenderState */ public void setRenderState(RenderState renderState) { this.renderState = renderState; } + /** + * Sets if this technique should not be used to render. + * + * @param noRender not render or render ? + * + * @see NoRender + */ + public void setNoRender(boolean noRender) { + this.noRender = noRender; + } + + /** + * Returns true if this technique should not be used to render. + * (eg. to not render a material with default technique) + * + * @return true if this technique should not be rendered, false otherwise. + * + */ + public boolean isNoRender(){ + return noRender; + } + /** * @deprecated jME3 always requires shaders now */ @@ -208,12 +231,12 @@ public class TechniqueDef implements Savable { public boolean isUsingShaders(){ return true; } - + /** * Returns true if this technique uses Shader Nodes, false otherwise. - * + * * @return true if this technique uses Shader Nodes, false otherwise. - * + * */ public boolean isUsingShaderNodes(){ return usesNodes; @@ -222,7 +245,7 @@ public class TechniqueDef implements Savable { /** * Gets the {@link Caps renderer capabilities} that are required * by this technique. - * + * * @return the required renderer capabilities */ public EnumSet getRequiredCaps() { @@ -231,7 +254,7 @@ public class TechniqueDef implements Savable { /** * Sets the shaders that this technique definition will use. - * + * * @param vertexShader The name of the vertex shader * @param fragmentShader The name of the fragment shader * @param vertLanguage The vertex shader language @@ -242,7 +265,7 @@ public class TechniqueDef implements Savable { this.shaderNames.put(Shader.ShaderType.Vertex, vertexShader); this.shaderLanguages.put(Shader.ShaderType.Fragment, fragLanguage); this.shaderNames.put(Shader.ShaderType.Fragment, fragmentShader); - + requiredCaps.clear(); Caps vertCap = Caps.valueOf(vertLanguage); requiredCaps.add(vertCap); @@ -259,17 +282,17 @@ public class TechniqueDef implements Savable { */ public void setShaderFile(EnumMap shaderNames, EnumMap shaderLanguages) { requiredCaps.clear(); - + for (Shader.ShaderType shaderType : shaderNames.keySet()) { String language = shaderLanguages.get(shaderType); String shaderFile = shaderNames.get(shaderType); - + this.shaderLanguages.put(shaderType, language); this.shaderNames.put(shaderType, shaderFile); - + Caps vertCap = Caps.valueOf(language); requiredCaps.add(vertCap); - + if (shaderType.equals(Shader.ShaderType.Geometry)) { requiredCaps.add(Caps.GeometryShader); } else if (shaderType.equals(Shader.ShaderType.TessellationControl)) { @@ -280,11 +303,11 @@ public class TechniqueDef implements Savable { /** * Returns the define name which the given material parameter influences. - * + * * @param paramName The parameter name to look up * @return The define name - * - * @see #addShaderParamDefine(java.lang.String, java.lang.String) + * + * @see #addShaderParamDefine(java.lang.String, java.lang.String) */ public String getShaderParamDefine(String paramName){ if (defineParams == null) { @@ -297,11 +320,11 @@ public class TechniqueDef implements Savable { * Adds a define linked to a material parameter. *

    * Any time the material parameter on the parent material is altered, - * the appropriate define on the technique will be modified as well. - * See the method + * the appropriate define on the technique will be modified as well. + * See the method * {@link DefineList#set(java.lang.String, com.jme3.shader.VarType, java.lang.Object) } * on the exact details of how the material parameter changes the define. - * + * * @param paramName The name of the material parameter to link to. * @param defineName The name of the define parameter, e.g. USE_LIGHTING */ @@ -314,26 +337,26 @@ public class TechniqueDef implements Savable { /** * Returns the {@link DefineList} for the preset defines. - * + * * @return the {@link DefineList} for the preset defines. - * - * @see #addShaderPresetDefine(java.lang.String, com.jme3.shader.VarType, java.lang.Object) + * + * @see #addShaderPresetDefine(java.lang.String, com.jme3.shader.VarType, java.lang.Object) */ public DefineList getShaderPresetDefines() { return presetDefines; } - + /** - * Adds a preset define. + * Adds a preset define. *

    * Preset defines do not depend upon any parameters to be activated, * they are always passed to the shader as long as this technique is used. - * + * * @param defineName The name of the define parameter, e.g. USE_LIGHTING - * @param type The type of the define. See + * @param type The type of the define. See * {@link DefineList#set(java.lang.String, com.jme3.shader.VarType, java.lang.Object) } * to see why it matters. - * + * * @param value The value of the define */ public void addShaderPresetDefine(String defineName, VarType type, Object value){ @@ -346,18 +369,18 @@ public class TechniqueDef implements Savable { /** * Returns the name of the fragment shader used by the technique, or null * if no fragment shader is specified. - * + * * @return the name of the fragment shader to be used. */ public String getFragmentShaderName() { return shaderNames.get(Shader.ShaderType.Fragment); } - + /** * Returns the name of the vertex shader used by the technique, or null * if no vertex shader is specified. - * + * * @return the name of the vertex shader to be used. */ public String getVertexShaderName() { @@ -370,7 +393,7 @@ public class TechniqueDef implements Savable { public String getFragmentShaderLanguage() { return shaderLanguages.get(Shader.ShaderType.Fragment); } - + /** * Returns the language of the vertex shader used in this technique. */ @@ -390,10 +413,10 @@ public class TechniqueDef implements Savable { public String getShaderProgramName(Shader.ShaderType shaderType){ return shaderNames.get(shaderType); } - + /** * Adds a new world parameter by the given name. - * + * * @param name The world parameter to add. * @return True if the world parameter name was found and added * to the list of world parameters, false otherwise. @@ -402,7 +425,7 @@ public class TechniqueDef implements Savable { if (worldBinds == null){ worldBinds = new ArrayList(); } - + try { worldBinds.add( UniformBinding.valueOf(name) ); return true; @@ -418,11 +441,11 @@ public class TechniqueDef implements Savable { public void setForcedRenderState(RenderState forcedRenderState) { this.forcedRenderState = forcedRenderState; } - + /** * Returns a list of world parameters that are used by this * technique definition. - * + * * @return The list of world parameters */ public List getWorldBindings() { @@ -448,10 +471,11 @@ public class TechniqueDef implements Savable { oc.write(lightMode, "lightMode", LightMode.Disable); oc.write(shadowMode, "shadowMode", ShadowMode.Disable); oc.write(renderState, "renderState", null); + oc.write(noRender, "noRender", false); oc.write(usesNodes, "usesNodes", false); oc.writeSavableArrayList((ArrayList)shaderNodes,"shaderNodes", null); oc.write(shaderGenerationInfo, "shaderGenerationInfo", null); - + // TODO: Finish this when Map export is available // oc.write(defineParams, "defineParams", null); // TODO: Finish this when List export is available @@ -470,7 +494,8 @@ public class TechniqueDef implements Savable { lightMode = ic.readEnum("lightMode", LightMode.class, LightMode.Disable); shadowMode = ic.readEnum("shadowMode", ShadowMode.class, ShadowMode.Disable); renderState = (RenderState) ic.readSavable("renderState", null); - + noRender = ic.readBoolean("noRender", false); + if (ic.getSavableVersion(TechniqueDef.class) == 0) { // Old version shaderLanguages.put(Shader.ShaderType.Vertex,ic.readString("shaderLang", null)); @@ -483,7 +508,7 @@ public class TechniqueDef implements Savable { shaderLanguages.put(Shader.ShaderType.TessellationControl,ic.readString("tsctrlLanguage", null)); shaderLanguages.put(Shader.ShaderType.TessellationEvaluation,ic.readString("tsevalLanguage", null)); } - + usesNodes = ic.readBoolean("usesNodes", false); shaderNodes = ic.readSavableArrayList("shaderNodes", null); shaderGenerationInfo = (ShaderGenerationInfo) ic.readSavable("shaderGenerationInfo", null); @@ -525,6 +550,6 @@ public class TechniqueDef implements Savable { //todo: make toString return something usefull @Override public String toString() { - return "TechniqueDef{" + "requiredCaps=" + requiredCaps + ", name=" + name /*+ ", vertName=" + vertName + ", fragName=" + fragName + ", vertLanguage=" + vertLanguage + ", fragLanguage=" + fragLanguage */+ ", presetDefines=" + presetDefines + ", usesNodes=" + usesNodes + ", shaderNodes=" + shaderNodes + ", shaderGenerationInfo=" + shaderGenerationInfo + ", renderState=" + renderState + ", forcedRenderState=" + forcedRenderState + ", lightMode=" + lightMode + ", shadowMode=" + shadowMode + ", defineParams=" + defineParams + ", worldBinds=" + worldBinds + '}'; - } + return "TechniqueDef{" + "requiredCaps=" + requiredCaps + ", name=" + name /*+ ", vertName=" + vertName + ", fragName=" + fragName + ", vertLanguage=" + vertLanguage + ", fragLanguage=" + fragLanguage */+ ", presetDefines=" + presetDefines + ", usesNodes=" + usesNodes + ", shaderNodes=" + shaderNodes + ", shaderGenerationInfo=" + shaderGenerationInfo + ", renderState=" + renderState + ", forcedRenderState=" + forcedRenderState + ", lightMode=" + lightMode + ", shadowMode=" + shadowMode + ", defineParams=" + defineParams + ", worldBinds=" + worldBinds + ", noRender=" + noRender + '}'; + } } diff --git a/jme3-core/src/main/java/com/jme3/math/ColorRGBA.java b/jme3-core/src/main/java/com/jme3/math/ColorRGBA.java index 89f82ebbd..89df1bb2b 100644 --- a/jme3-core/src/main/java/com/jme3/math/ColorRGBA.java +++ b/jme3-core/src/main/java/com/jme3/math/ColorRGBA.java @@ -607,28 +607,28 @@ public final class ColorRGBA implements Savable, Cloneable, java.io.Serializable } /** - * Get the color in sRGB color space as a Vector4f + * Get the color in sRGB color space as a ColorRGBA. * * Note that linear values stored in the ColorRGBA will be gamma corrected - * and returned as a Vector4f - * the x atribute will be fed with the r channel in sRGB space - * the y atribute will be fed with the g channel in sRGB space - * the z atribute will be fed with the b channel in sRGB space - * the w atribute will be fed with the a channel + * and returned as a ColorRGBA. * - * Note that no correction will be performed on the alpha channel as it's - * conventionnally doesn't represent a color itself + * The x attribute will be fed with the r channel in sRGB space. + * The y attribute will be fed with the g channel in sRGB space. + * The z attribute will be fed with the b channel in sRGB space. + * The w attribute will be fed with the a channel. * - * @return the color in sRGB color space as a Vector4f - */ - public Vector4f getAsSrgb(){ - Vector4f srgb = new Vector4f(); - float invGama = 1f/GAMMA; - srgb.x = (float)Math.pow(r, invGama); - srgb.y = (float)Math.pow(g, invGama); - srgb.z = (float)Math.pow(b, invGama); - srgb.w = a; - + * Note that no correction will be performed on the alpha channel as it + * conventionally doesn't represent a color itself. + * + * @return the color in sRGB color space as a ColorRGBA. + */ + public ColorRGBA getAsSrgb() { + ColorRGBA srgb = new ColorRGBA(); + float invGama = 1f / GAMMA; + srgb.r = (float) Math.pow(r, invGama); + srgb.g = (float) Math.pow(g, invGama); + srgb.b = (float) Math.pow(b, invGama); + srgb.a = a; return srgb; } diff --git a/jme3-core/src/main/java/com/jme3/math/Matrix4f.java b/jme3-core/src/main/java/com/jme3/math/Matrix4f.java index c8dd3ef4a..159e39932 100644 --- a/jme3-core/src/main/java/com/jme3/math/Matrix4f.java +++ b/jme3-core/src/main/java/com/jme3/math/Matrix4f.java @@ -154,53 +154,34 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable } public void fromFrame(Vector3f location, Vector3f direction, Vector3f up, Vector3f left) { - loadIdentity(); - TempVars vars = TempVars.get(); - - Vector3f f = vars.vect1.set(direction); - Vector3f s = vars.vect2.set(f).crossLocal(up); - Vector3f u = vars.vect3.set(s).crossLocal(f); -// s.normalizeLocal(); -// u.normalizeLocal(); - - m00 = s.x; - m01 = s.y; - m02 = s.z; - - m10 = u.x; - m11 = u.y; - m12 = u.z; - - m20 = -f.x; - m21 = -f.y; - m22 = -f.z; - -// m00 = -left.x; -// m10 = -left.y; -// m20 = -left.z; -// -// m01 = up.x; -// m11 = up.y; -// m21 = up.z; -// -// m02 = -direction.x; -// m12 = -direction.y; -// m22 = -direction.z; -// - - Matrix4f transMatrix = vars.tempMat4; - transMatrix.loadIdentity(); - transMatrix.m03 = -location.x; - transMatrix.m13 = -location.y; - transMatrix.m23 = -location.z; - this.multLocal(transMatrix); - - vars.release(); - -// transMatrix.multLocal(this); - -// set(transMatrix); + try { + Vector3f fwdVector = vars.vect1.set(direction); + Vector3f leftVector = vars.vect2.set(fwdVector).crossLocal(up); + Vector3f upVector = vars.vect3.set(leftVector).crossLocal(fwdVector); + + m00 = leftVector.x; + m01 = leftVector.y; + m02 = leftVector.z; + m03 = -leftVector.dot(location); + + m10 = upVector.x; + m11 = upVector.y; + m12 = upVector.z; + m13 = -upVector.dot(location); + + m20 = -fwdVector.x; + m21 = -fwdVector.y; + m22 = -fwdVector.z; + m23 = fwdVector.dot(location); + + m30 = 0f; + m31 = 0f; + m32 = 0f; + m33 = 1f; + } finally { + vars.release(); + } } /** diff --git a/jme3-core/src/main/java/com/jme3/math/Transform.java b/jme3-core/src/main/java/com/jme3/math/Transform.java index ac7a324d0..9d8a72a1e 100644 --- a/jme3-core/src/main/java/com/jme3/math/Transform.java +++ b/jme3-core/src/main/java/com/jme3/math/Transform.java @@ -49,7 +49,7 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable private Quaternion rot = new Quaternion(); private Vector3f translation = new Vector3f(); - private Vector3f scale = new Vector3f(1,1,1); + private Vector3f scale = new Vector3f(1, 1, 1); public Transform(Vector3f translation, Quaternion rot){ this.translation.set(translation); @@ -283,9 +283,32 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable * Loads the identity. Equal to translation=0,0,0 scale=1,1,1 rot=0,0,0,1. */ public void loadIdentity() { - translation.set(0,0,0); - scale.set(1,1,1); - rot.set(0,0,0,1); + translation.set(0, 0, 0); + scale.set(1, 1, 1); + rot.set(0, 0, 0, 1); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 89 * hash + rot.hashCode(); + hash = 89 * hash + translation.hashCode(); + hash = 89 * hash + scale.hashCode(); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Transform other = (Transform) obj; + return this.translation.equals(other.translation) + && this.scale.equals(other.scale) + && this.rot.equals(other.rot); } @Override @@ -307,22 +330,21 @@ public final class Transform implements Savable, Cloneable, java.io.Serializable return this; } + @Override public void write(JmeExporter e) throws IOException { OutputCapsule capsule = e.getCapsule(this); - capsule.write(rot, "rot", new Quaternion()); + capsule.write(rot, "rot", Quaternion.IDENTITY); capsule.write(translation, "translation", Vector3f.ZERO); capsule.write(scale, "scale", Vector3f.UNIT_XYZ); } + @Override public void read(JmeImporter e) throws IOException { InputCapsule capsule = e.getCapsule(this); - rot = (Quaternion)capsule.readSavable("rot", new Quaternion()); - translation = (Vector3f)capsule.readSavable("translation", null); - if( translation == null ) { - translation = new Vector3f(); - } - scale = (Vector3f)capsule.readSavable("scale", Vector3f.UNIT_XYZ); + rot.set((Quaternion)capsule.readSavable("rot", Quaternion.IDENTITY)); + translation.set((Vector3f)capsule.readSavable("translation", Vector3f.ZERO)); + scale.set((Vector3f)capsule.readSavable("scale", Vector3f.UNIT_XYZ)); } @Override diff --git a/jme3-core/src/main/java/com/jme3/post/FilterPostProcessor.java b/jme3-core/src/main/java/com/jme3/post/FilterPostProcessor.java index 2cd8b83f8..b28aecece 100644 --- a/jme3-core/src/main/java/com/jme3/post/FilterPostProcessor.java +++ b/jme3-core/src/main/java/com/jme3/post/FilterPostProcessor.java @@ -300,7 +300,7 @@ public class FilterPostProcessor implements SceneProcessor, Savable { public void postFrame(FrameBuffer out) { FrameBuffer sceneBuffer = renderFrameBuffer; - if (renderFrameBufferMS != null && !renderer.getCaps().contains(Caps.OpenGL31)) { + if (renderFrameBufferMS != null && !renderer.getCaps().contains(Caps.OpenGL32)) { renderer.copyFrameBuffer(renderFrameBufferMS, renderFrameBuffer, true); } else if (renderFrameBufferMS != null) { sceneBuffer = renderFrameBufferMS; @@ -443,7 +443,7 @@ public class FilterPostProcessor implements SceneProcessor, Savable { //antialiasing on filters only supported in opengl 3 due to depth read problem if (numSamples > 1 && caps.contains(Caps.FrameBufferMultisample)) { renderFrameBufferMS = new FrameBuffer(width, height, numSamples); - if (caps.contains(Caps.OpenGL31)) { + if (caps.contains(Caps.OpenGL32)) { Texture2D msColor = new Texture2D(width, height, numSamples, fbFormat); Texture2D msDepth = new Texture2D(width, height, numSamples, Format.Depth); renderFrameBufferMS.setDepthTexture(msDepth); @@ -456,7 +456,7 @@ public class FilterPostProcessor implements SceneProcessor, Savable { } } - if (numSamples <= 1 || !caps.contains(Caps.OpenGL31)) { + if (numSamples <= 1 || !caps.contains(Caps.OpenGL32)) { renderFrameBuffer = new FrameBuffer(width, height, 1); renderFrameBuffer.setDepthBuffer(Format.Depth); filterTexture = new Texture2D(width, height, fbFormat); diff --git a/jme3-core/src/main/java/com/jme3/renderer/Limits.java b/jme3-core/src/main/java/com/jme3/renderer/Limits.java index b10c539b8..86cddb178 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/Limits.java +++ b/jme3-core/src/main/java/com/jme3/renderer/Limits.java @@ -75,4 +75,6 @@ public enum Limits { ColorTextureSamples, DepthTextureSamples, + + VertexUniformVectors, } diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GL.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL.java index 76eedb521..1b9c3f94d 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GL.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL.java @@ -74,6 +74,7 @@ public interface GL { public static final int GL_FRONT_AND_BACK = 0x408; public static final int GL_GEQUAL = 0x206; public static final int GL_GREATER = 0x204; + public static final int GL_GREEN = 0x1904; public static final int GL_INCR = 0x1E02; public static final int GL_INCR_WRAP = 0x8507; public static final int GL_INFO_LOG_LENGTH = 0x8B84; @@ -99,6 +100,8 @@ public interface GL { public static final int GL_MAX_TEXTURE_SIZE = 0xD33; public static final int GL_MAX_VERTEX_ATTRIBS = 0x8869; public static final int GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C; + public static final int GL_MAX_VERTEX_UNIFORM_COMPONENTS = 0x8B4A; + public static final int GL_MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB; public static final int GL_MIRRORED_REPEAT = 0x8370; public static final int GL_NEAREST = 0x2600; public static final int GL_NEAREST_MIPMAP_LINEAR = 0x2702; @@ -114,6 +117,7 @@ public interface GL { public static final int GL_OUT_OF_MEMORY = 0x505; public static final int GL_POINTS = 0x0; public static final int GL_POLYGON_OFFSET_FILL = 0x8037; + public static final int GL_RED = 0x1903; public static final int GL_RENDERER = 0x1F01; public static final int GL_REPEAT = 0x2901; public static final int GL_REPLACE = 0x1E01; @@ -157,6 +161,7 @@ public interface GL { public static final int GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518; public static final int GL_TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519; public static final int GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A; + public static final int GL_TEXTURE_BASE_LEVEL = 0x813C; public static final int GL_TEXTURE_MAG_FILTER = 0x2800; public static final int GL_TEXTURE_MAX_LEVEL = 0x813D; public static final int GL_TEXTURE_MIN_FILTER = 0x2801; diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GL3.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL3.java index 190ed4547..2a7c38bb9 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GL3.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL3.java @@ -34,7 +34,7 @@ package com.jme3.renderer.opengl; import java.nio.IntBuffer; /** - * GL functions only available on vanilla desktop OpenGL 3.0. + * GL functions only available on vanilla desktop OpenGL 3.0+. * * @author Kirill Vainer */ @@ -43,6 +43,17 @@ public interface GL3 extends GL2 { public static final int GL_DEPTH_STENCIL_ATTACHMENT = 0x821A; public static final int GL_GEOMETRY_SHADER = 0x8DD9; public static final int GL_NUM_EXTENSIONS = 0x821D; + public static final int GL_R8 = 0x8229; + public static final int GL_R16F = 0x822D; + public static final int GL_R32F = 0x822E; + public static final int GL_RG16F = 0x822F; + public static final int GL_RG32F = 0x8230; + public static final int GL_RG = 0x8227; + public static final int GL_RG8 = 0x822B; + public static final int GL_TEXTURE_SWIZZLE_A = 0x8E45; + public static final int GL_TEXTURE_SWIZZLE_B = 0x8E44; + public static final int GL_TEXTURE_SWIZZLE_G = 0x8E43; + public static final int GL_TEXTURE_SWIZZLE_R = 0x8E42; public void glBindFragDataLocation(int param1, int param2, String param3); /// GL3+ public void glBindVertexArray(int param1); /// GL3+ diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GL4.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL4.java index ce982eebf..058bc00ec 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GL4.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL4.java @@ -34,7 +34,7 @@ package com.jme3.renderer.opengl; import java.nio.IntBuffer; /** - * GL functions only available on vanilla desktop OpenGL 3.0. + * GL functions only available on vanilla desktop OpenGL 4.0. * * @author Kirill Vainer */ diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLImageFormat.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLImageFormat.java index 71d95f59b..8e65fbdef 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLImageFormat.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLImageFormat.java @@ -42,6 +42,7 @@ public final class GLImageFormat { public final int format; public final int dataType; public final boolean compressed; + public final boolean swizzleRequired; /** * Constructor for formats. @@ -55,6 +56,7 @@ public final class GLImageFormat { this.format = format; this.dataType = dataType; this.compressed = false; + this.swizzleRequired = false; } /** @@ -63,11 +65,30 @@ public final class GLImageFormat { * @param internalFormat OpenGL internal format * @param format OpenGL format * @param dataType OpenGL datatype + * @param compressed Format is compressed */ public GLImageFormat(int internalFormat, int format, int dataType, boolean compressed) { this.internalFormat = internalFormat; this.format = format; this.dataType = dataType; this.compressed = compressed; + this.swizzleRequired = false; + } + + /** + * Constructor for formats. + * + * @param internalFormat OpenGL internal format + * @param format OpenGL format + * @param dataType OpenGL datatype + * @param compressed Format is compressed + * @param swizzleRequired Need to use texture swizzle to upload texture + */ + public GLImageFormat(int internalFormat, int format, int dataType, boolean compressed, boolean swizzleRequired) { + this.internalFormat = internalFormat; + this.format = format; + this.dataType = dataType; + this.compressed = compressed; + this.swizzleRequired = swizzleRequired; } } diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLImageFormats.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLImageFormats.java index a7ef9f52d..ab80b9e2a 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLImageFormats.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLImageFormats.java @@ -52,6 +52,13 @@ public final class GLImageFormats { formatToGL[0][format.ordinal()] = new GLImageFormat(glInternalFormat, glFormat, glDataType); } + private static void formatSwiz(GLImageFormat[][] formatToGL, Image.Format format, + int glInternalFormat, + int glFormat, + int glDataType){ + formatToGL[0][format.ordinal()] = new GLImageFormat(glInternalFormat, glFormat, glDataType, false, true); + } + private static void formatSrgb(GLImageFormat[][] formatToGL, Image.Format format, int glInternalFormat, int glFormat, @@ -60,6 +67,14 @@ public final class GLImageFormats { formatToGL[1][format.ordinal()] = new GLImageFormat(glInternalFormat, glFormat, glDataType); } + private static void formatSrgbSwiz(GLImageFormat[][] formatToGL, Image.Format format, + int glInternalFormat, + int glFormat, + int glDataType) + { + formatToGL[1][format.ordinal()] = new GLImageFormat(glInternalFormat, glFormat, glDataType, false, true); + } + private static void formatComp(GLImageFormat[][] formatToGL, Image.Format format, int glCompressedFormat, int glFormat, @@ -88,6 +103,19 @@ public final class GLImageFormats { public static GLImageFormat[][] getFormatsForCaps(EnumSet caps) { GLImageFormat[][] formatToGL = new GLImageFormat[2][Image.Format.values().length]; + // Core Profile Formats (supported by both OpenGL Core 3.3 and OpenGL ES 3.0+) + if (caps.contains(Caps.CoreProfile)) { + formatSwiz(formatToGL, Format.Alpha8, GL3.GL_R8, GL.GL_RED, GL.GL_UNSIGNED_BYTE); + formatSwiz(formatToGL, Format.Luminance8, GL3.GL_R8, GL.GL_RED, GL.GL_UNSIGNED_BYTE); + formatSwiz(formatToGL, Format.Luminance8Alpha8, GL3.GL_RG8, GL3.GL_RG, GL.GL_UNSIGNED_BYTE); + formatSwiz(formatToGL, Format.Luminance16F, GL3.GL_R16F, GL.GL_RED, GLExt.GL_HALF_FLOAT_ARB); + formatSwiz(formatToGL, Format.Luminance32F, GL3.GL_R32F, GL.GL_RED, GL.GL_FLOAT); + formatSwiz(formatToGL, Format.Luminance16FAlpha16F, GL3.GL_RG16F, GL3.GL_RG, GLExt.GL_HALF_FLOAT_ARB); + + formatSrgbSwiz(formatToGL, Format.Luminance8, GLExt.GL_SRGB8_EXT, GL.GL_RED, GL.GL_UNSIGNED_BYTE); + formatSrgbSwiz(formatToGL, Format.Luminance8Alpha8, GLExt.GL_SRGB8_ALPHA8_EXT, GL3.GL_RG, GL.GL_UNSIGNED_BYTE); + } + if (caps.contains(Caps.OpenGL20)) { if (!caps.contains(Caps.CoreProfile)) { format(formatToGL, Format.Alpha8, GL2.GL_ALPHA8, GL.GL_ALPHA, GL.GL_UNSIGNED_BYTE); 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 index 37b7c753f..dd30da089 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java @@ -54,6 +54,7 @@ import com.jme3.texture.Texture; import com.jme3.texture.Texture.WrapAxis; import com.jme3.util.BufferUtils; import com.jme3.util.ListMap; +import com.jme3.util.MipMapGenerator; import com.jme3.util.NativeObjectManager; import java.nio.*; import java.util.Arrays; @@ -72,7 +73,7 @@ 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); @@ -82,22 +83,7 @@ public class GLRenderer implements Renderer { private final NativeObjectManager objManager = new NativeObjectManager(); private final EnumSet caps = EnumSet.noneOf(Caps.class); private final EnumMap limits = new EnumMap(Limits.class); - -// private int vertexTextureUnits; -// private int fragTextureUnits; -// private int vertexUniforms; -// private int fragUniforms; -// private int vertexAttribs; -// private int maxFBOSamples; -// private int maxFBOAttachs; -// private int maxMRTFBOAttachs; -// private int maxRBSize; -// private int maxTexSize; -// private int maxCubeTexSize; -// private int maxVertCount; -// private int maxTriCount; -// private int maxColorTexSamples; -// private int maxDepthTexSamples; + private FrameBuffer mainFbOverride = null; private final Statistics statistics = new Statistics(); private int vpX, vpY, vpW, vpH; @@ -112,7 +98,7 @@ public class GLRenderer implements Renderer { private final GLExt glext; private final GLFbo glfbo; private final TextureUtil texUtil; - + public GLRenderer(GL gl, GLExt glext, GLFbo glfbo) { this.gl = gl; this.gl2 = gl instanceof GL2 ? (GL2)gl : null; @@ -120,7 +106,7 @@ public class GLRenderer implements Renderer { this.gl4 = gl instanceof GL4 ? (GL4)gl : null; this.glfbo = glfbo; this.glext = glext; - this.texUtil = new TextureUtil(gl, gl2, glext, context); + this.texUtil = new TextureUtil(gl, gl2, glext); } @Override @@ -132,7 +118,7 @@ public class GLRenderer implements Renderer { public EnumSet getCaps() { return caps; } - + // Not making public yet ... public EnumMap getLimits() { return limits; @@ -154,7 +140,7 @@ public class GLRenderer implements Renderer { } return extensionSet; } - + public static int extractVersion(String version) { Matcher m = GLVERSION_PATTERN.matcher(version); if (m.matches()) { @@ -174,17 +160,17 @@ public class GLRenderer implements Renderer { 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) { @@ -208,9 +194,9 @@ public class GLRenderer implements Renderer { } } } - + int glslVer = extractVersion(gl.glGetString(GL.GL_SHADING_LANGUAGE_VERSION)); - + switch (glslVer) { default: if (glslVer < 400) { @@ -236,34 +222,34 @@ public class GLRenderer implements Renderer { 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); @@ -271,62 +257,66 @@ public class GLRenderer implements Renderer { // 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")) { + 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"); - + hasExtension("GL_OES_texture_float"); + if (!hasFloatTexture) { hasFloatTexture = hasExtension("GL_ARB_texture_float") && - hasExtension("GL_ARB_half_float_pixel"); - + 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")) { + + 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")) { + hasExtension("GL_ARB_half_float_pixel")) { // XXX: Require both 16 and 32 bit float support for FloatColorBuffer. caps.add(Caps.FloatColorBuffer); } @@ -335,45 +325,44 @@ public class GLRenderer implements Renderer { caps.add(Caps.FloatDepthBuffer); } - if ((hasExtension("GL_EXT_packed_float") && hasFloatTexture) || - caps.contains(Caps.OpenGL30)) { + 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") || - hasExtension("GL_APPLE_texture_2D_limited_npot") || - caps.contains(Caps.OpenGL30)) { + 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."); + + "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); @@ -387,16 +376,18 @@ public class GLRenderer implements Renderer { caps.add(Caps.TextureFilterAnisotropic); } - if (hasExtension("GL_EXT_framebuffer_object") || gl3 != null) { + if (hasExtension("GL_EXT_framebuffer_object") + || gl3 != null + || 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.add(Caps.FrameBufferBlit); } - + if (hasExtension("GL_EXT_framebuffer_multisample")) { caps.add(Caps.FrameBufferMultisample); limits.put(Limits.FrameBufferSamples, getInteger(GLExt.GL_MAX_SAMPLES_EXT)); @@ -412,7 +403,7 @@ public class GLRenderer implements Renderer { } } - if (hasExtension("GL_ARB_draw_buffers")) { + if (hasExtension("GL_ARB_draw_buffers") || gl3 != null) { limits.put(Limits.FrameBufferMrtAttachments, getInteger(GLExt.GL_MAX_DRAW_BUFFERS_ARB)); if (limits.get(Limits.FrameBufferMrtAttachments) > 1) { caps.add(Caps.FrameBufferMRT); @@ -434,10 +425,10 @@ public class GLRenderer implements Renderer { } caps.add(Caps.Multisample); } - + // Supports sRGB pipeline. - if ( (hasExtension("GL_ARB_framebuffer_sRGB") && hasExtension("GL_EXT_texture_sRGB")) - || caps.contains(Caps.OpenGL30) ) { + if ( (hasExtension("GL_ARB_framebuffer_sRGB") && hasExtension("GL_EXT_texture_sRGB")) + || caps.contains(Caps.OpenGL30) ) { caps.add(Caps.Srgb); } @@ -445,33 +436,33 @@ public class GLRenderer implements Renderer { 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" - }); - + " * 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(); @@ -482,10 +473,10 @@ public class GLRenderer implements Renderer { } logger.log(Level.FINE, sb.toString()); } - + texUtil.initialize(caps); } - + private void loadCapabilities() { if (gl2 != null) { loadCapabilitiesGL2(); @@ -494,31 +485,31 @@ public class GLRenderer implements Renderer { } loadCapabilitiesCommon(); } - + private int getInteger(int en) { intBuf16.clear(); gl.glGetInteger(en, intBuf16); return intBuf16.get(0); } - + private boolean getBoolean(int en) { gl.glGetBoolean(en, nameBuf); return nameBuf.get(0) != (byte)0; } - + @SuppressWarnings("fallthrough") public void initialize() { loadCapabilities(); - + // Initialize default state.. gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1); - + if (caps.contains(Caps.CoreProfile)) { // Core Profile requires VAO to be bound. gl3.glGenVertexArrays(intBuf16); int vaoId = intBuf16.get(0); gl3.glBindVertexArray(vaoId); - } + } if (gl2 != null) { gl2.glEnable(GL2.GL_VERTEX_PROGRAM_POINT_SIZE); if (!caps.contains(Caps.CoreProfile)) { @@ -551,8 +542,8 @@ public class GLRenderer implements Renderer { } /*********************************************************************\ - |* Render State *| - \*********************************************************************/ + |* Render State *| + \*********************************************************************/ public void setDepthRange(float start, float end) { gl.glDepthRange(start, end); } @@ -617,7 +608,7 @@ public class GLRenderer implements Renderer { } if (state.isDepthTest() && !context.depthTestEnabled) { - gl.glEnable(GL.GL_DEPTH_TEST); + gl.glEnable(GL.GL_DEPTH_TEST); gl.glDepthFunc(convertTestFunction(context.depthFunc)); context.depthTestEnabled = true; } else if (!state.isDepthTest() && context.depthTestEnabled) { @@ -729,7 +720,7 @@ public class GLRenderer implements Renderer { case Color: case Screen: gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE_MINUS_SRC_COLOR); - break; + break; case Exclusion: gl.glBlendFunc(GL.GL_ONE_MINUS_DST_COLOR, GL.GL_ONE_MINUS_SRC_COLOR); break; @@ -830,8 +821,8 @@ public class GLRenderer implements Renderer { } /*********************************************************************\ - |* Camera and World transforms *| - \*********************************************************************/ + |* Camera and World transforms *| + \*********************************************************************/ public void setViewPort(int x, int y, int w, int h) { if (x != vpX || vpY != y || vpW != w || vpH != h) { gl.glViewport(x, y, w, h); @@ -874,8 +865,8 @@ public class GLRenderer implements Renderer { } /*********************************************************************\ - |* Shaders *| - \*********************************************************************/ + |* Shaders *| + \*********************************************************************/ protected void updateUniformLocation(Shader shader, Uniform uniform) { int loc = gl.glGetUniformLocation(shader.getId(), uniform.getName()); if (loc < 0) { @@ -1055,12 +1046,12 @@ public class GLRenderer implements Renderer { boolean gles2 = caps.contains(Caps.OpenGLES20); String language = source.getLanguage(); - + if (gles2 && !language.equals("GLSL100")) { throw new RendererException("This shader cannot run in OpenGL ES 2. " - + "Only GLSL 1.00 shaders are supported."); + + "Only GLSL 1.00 shaders are supported."); } - + // Upload shader source. // Merge the defines and source code. stringBuf.setLength(0); @@ -1075,6 +1066,9 @@ public class GLRenderer implements Renderer { stringBuf.append("\n"); } else { if (gles2) { + // request GLSL ES (1.00) when compiling under GLES2. + stringBuf.append("#version 100\n"); + if (source.getType() == ShaderType.Fragment) { // GLES2 requires precision qualifier. stringBuf.append("precision mediump float;\n"); @@ -1087,14 +1081,15 @@ public class GLRenderer implements Renderer { } } } - + if (linearizeSrgbImages) { stringBuf.append("#define SRGB 1\n"); } - + stringBuf.append("#define ").append(source.getType().name().toUpperCase()).append("_SHADER 1\n"); + stringBuf.append(source.getDefines()); stringBuf.append(source.getSource()); - + intBuf1.clear(); intBuf1.put(0, stringBuf.length()); gl.glShaderSource(id, new String[]{ stringBuf.toString() }, intBuf1); @@ -1152,7 +1147,7 @@ public class GLRenderer implements Renderer { // If using GLSL 1.5, we bind the outputs for the user // For versions 3.3 and up, user should use layout qualifiers instead. boolean bindFragDataRequired = false; - + for (ShaderSource source : shader.getSources()) { if (source.isUpdateNeeded()) { updateShaderSourceData(source); @@ -1261,8 +1256,8 @@ public class GLRenderer implements Renderer { } /*********************************************************************\ - |* Framebuffers *| - \*********************************************************************/ + |* Framebuffers *| + \*********************************************************************/ public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst) { copyFrameBuffer(src, dst, true); } @@ -1417,7 +1412,7 @@ public class GLRenderer implements Renderer { } else if (attachmentSlot < 0 || attachmentSlot >= 16) { throw new UnsupportedOperationException("Invalid FBO attachment slot: " + attachmentSlot); } - + return GLFbo.GL_COLOR_ATTACHMENT0_EXT + attachmentSlot; } @@ -1427,8 +1422,8 @@ public class GLRenderer implements Renderer { if (image.isUpdateNeeded()) { // Check NPOT requirements checkNonPowerOfTwo(tex); - - updateTexImageData(image, tex.getType(), 0); + + updateTexImageData(image, tex.getType(), 0, false); // NOTE: For depth textures, sets nearest/no-mips mode // Required to fix "framebuffer unsupported" @@ -1491,7 +1486,7 @@ public class GLRenderer implements Renderer { } checkFrameBufferError(); - + fb.clearUpdateNeeded(); } @@ -1584,7 +1579,7 @@ public class GLRenderer implements Renderer { // update viewport to reflect framebuffer's resolution setViewPort(0, 0, fb.getWidth(), fb.getHeight()); - + if (context.boundFBO != fb.getId()) { glfbo.glBindFramebufferEXT(GLFbo.GL_FRAMEBUFFER_EXT, fb.getId()); statistics.onFrameBufferUse(fb, true); @@ -1655,7 +1650,7 @@ public class GLRenderer implements Renderer { public void readFrameBuffer(FrameBuffer fb, ByteBuffer byteBuf) { readFrameBufferWithGLFormat(fb, byteBuf, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE); } - + private void readFrameBufferWithGLFormat(FrameBuffer fb, ByteBuffer byteBuf, int glFormat, int dataType) { if (fb != null) { RenderBuffer rb = fb.getColorBuffer(); @@ -1677,8 +1672,8 @@ public class GLRenderer implements Renderer { gl.glReadPixels(vpX, vpY, vpW, vpH, glFormat, dataType, byteBuf); } - - public void readFrameBufferWithFormat(FrameBuffer fb, ByteBuffer byteBuf, Image.Format format) { + + public void readFrameBufferWithFormat(FrameBuffer fb, ByteBuffer byteBuf, Image.Format format) { GLImageFormat glFormat = texUtil.getImageFormatWithError(format, false); readFrameBufferWithGLFormat(fb, byteBuf, glFormat.format, glFormat.dataType); } @@ -1711,14 +1706,14 @@ public class GLRenderer implements Renderer { } /*********************************************************************\ - |* Textures *| - \*********************************************************************/ + |* Textures *| + \*********************************************************************/ private int convertTextureType(Texture.Type type, int samples, int face) { if (samples > 1 && !caps.contains(Caps.TextureMultisample)) { - throw new RendererException("Multisample textures are not supported" + - " by the video hardware."); + throw new RendererException("Multisample textures are not supported" + + " by the video hardware."); } - + switch (type) { case TwoDimensional: if (samples > 1) { @@ -1738,8 +1733,8 @@ public class GLRenderer implements Renderer { } case ThreeDimensional: if (!caps.contains(Caps.OpenGL20)) { - throw new RendererException("3D textures are not supported" + - " by the video hardware."); + throw new RendererException("3D textures are not supported" + + " by the video hardware."); } return GL2.GL_TEXTURE_3D; case CubeMap: @@ -1822,11 +1817,11 @@ public class GLRenderer implements Renderer { int target = convertTextureType(tex.getType(), image != null ? image.getMultiSamples() : 1, -1); boolean haveMips = true; - + if (image != null) { haveMips = image.isGeneratedMipmapsRequired() || image.hasMipmaps(); } - + // filter things if (image.getLastTextureState().magFilter != tex.getMagFilter()) { int magFilter = convertMagFilter(tex.getMagFilter()); @@ -1849,7 +1844,7 @@ public class GLRenderer implements Renderer { context.seamlessCubemap = false; } } - + if (tex.getAnisotropicFilter() > 1) { if (caps.contains(Caps.TextureFilterAnisotropic)) { gl.glTexParameterf(target, @@ -1858,10 +1853,6 @@ public class GLRenderer implements Renderer { } } - if (context.pointSprite) { - return; // Attempt to fix glTexParameter crash for some ATI GPUs - } - // repeat modes switch (tex.getType()) { case ThreeDimensional: @@ -1890,15 +1881,15 @@ public class GLRenderer implements Renderer { // R to Texture compare mode if (tex.getShadowCompareMode() != Texture.ShadowCompareMode.Off) { gl2.glTexParameteri(target, GL2.GL_TEXTURE_COMPARE_MODE, GL2.GL_COMPARE_R_TO_TEXTURE); - gl2.glTexParameteri(target, GL2.GL_DEPTH_TEXTURE_MODE, GL2.GL_INTENSITY); + gl2.glTexParameteri(target, GL2.GL_DEPTH_TEXTURE_MODE, GL2.GL_INTENSITY); if (tex.getShadowCompareMode() == Texture.ShadowCompareMode.GreaterOrEqual) { gl2.glTexParameteri(target, GL2.GL_TEXTURE_COMPARE_FUNC, GL.GL_GEQUAL); } else { gl2.glTexParameteri(target, GL2.GL_TEXTURE_COMPARE_FUNC, GL.GL_LEQUAL); } }else{ - //restoring default value - gl2.glTexParameteri(target, GL2.GL_TEXTURE_COMPARE_MODE, GL.GL_NONE); + //restoring default value + gl2.glTexParameteri(target, GL2.GL_TEXTURE_COMPARE_MODE, GL.GL_NONE); } tex.compareModeUpdated(); } @@ -1910,7 +1901,7 @@ public class GLRenderer implements Renderer { * Textures with power-of-2 dimensions are supported on all hardware, however * non-power-of-2 textures may or may not be supported depending on which * texturing features are used. - * + * * @param tex The texture to validate. * @throws RendererException If the texture is not supported by the hardware */ @@ -1919,23 +1910,23 @@ public class GLRenderer implements Renderer { // Texture is power-of-2, safe to use. return; } - + if (caps.contains(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)) { // Cannot use any type of NPOT texture (uncommon) throw new RendererException("non-power-of-2 textures are not " - + "supported by the video hardware"); + + "supported by the video hardware"); } - + // Partial NPOT supported.. if (tex.getMinFilter().usesMipMapLevels()) { throw new RendererException("non-power-of-2 textures with mip-maps " - + "are not supported by the video hardware"); + + "are not supported by the video hardware"); } switch (tex.getType()) { @@ -1943,7 +1934,7 @@ public class GLRenderer implements Renderer { case ThreeDimensional: if (tex.getWrap(WrapAxis.R) != Texture.WrapMode.EdgeClamp) { throw new RendererException("repeating non-power-of-2 textures " - + "are not supported by the video hardware"); + + "are not supported by the video hardware"); } // fallthrough intentional!!! case TwoDimensionalArray: @@ -1951,22 +1942,24 @@ public class GLRenderer implements Renderer { if (tex.getWrap(WrapAxis.S) != Texture.WrapMode.EdgeClamp || tex.getWrap(WrapAxis.T) != Texture.WrapMode.EdgeClamp) { throw new RendererException("repeating non-power-of-2 textures " - + "are not supported by the video hardware"); + + "are not supported by the video hardware"); } break; default: throw new UnsupportedOperationException("unrecongized texture type"); } } - + /** * Uploads the given image to the GL driver. - * + * * @param img The image to upload * @param type How the data in the image argument should be interpreted. * @param unit The texture slot to be used to upload the image, not important + * @param scaleToPot If true, the image will be scaled to power-of-2 dimensions + * before being uploaded. */ - public void updateTexImageData(Image img, Texture.Type type, int unit) { + public void updateTexImageData(Image img, Texture.Type type, int unit, boolean scaleToPot) { int texId = img.getId(); if (texId == -1) { // create texture @@ -1985,7 +1978,7 @@ public class GLRenderer implements Renderer { gl.glActiveTexture(GL.GL_TEXTURE0 + unit); context.boundTextureUnit = unit; } - + gl.glBindTexture(target, texId); context.boundTextures[unit] = img; @@ -2028,12 +2021,12 @@ public class GLRenderer implements Renderer { 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)) { 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); @@ -2050,33 +2043,39 @@ public class GLRenderer implements Renderer { } } + Image imageForUpload; + if (scaleToPot) { + imageForUpload = MipMapGenerator.resizeToPowerOf2(img); + } else { + imageForUpload = img; + } if (target == GL.GL_TEXTURE_CUBE_MAP) { - List data = img.getData(); + List data = imageForUpload.getData(); if (data.size() != 6) { logger.log(Level.WARNING, "Invalid texture: {0}\n" + "Cubemap textures must contain 6 data units.", img); return; } for (int i = 0; i < 6; i++) { - texUtil.uploadTexture(img, GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, i, linearizeSrgbImages); + 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)) { throw new RendererException("Texture arrays not supported by graphics hardware"); } - - List data = img.getData(); - + + List data = imageForUpload.getData(); + // -1 index specifies prepare data for 2D Array - texUtil.uploadTexture(img, target, -1, linearizeSrgbImages); - + texUtil.uploadTexture(imageForUpload, target, -1, linearizeSrgbImages); + for (int i = 0; i < data.size(); i++) { // upload each slice of 2D array in turn // this time with the appropriate index - texUtil.uploadTexture(img, target, i, linearizeSrgbImages); + texUtil.uploadTexture(imageForUpload, target, i, linearizeSrgbImages); } } else { - texUtil.uploadTexture(img, target, 0, linearizeSrgbImages); + texUtil.uploadTexture(imageForUpload, target, 0, linearizeSrgbImages); } if (img.getMultiSamples() != imageSamples) { @@ -2097,9 +2096,23 @@ public class GLRenderer implements Renderer { Image image = tex.getImage(); if (image.isUpdateNeeded() || (image.isGeneratedMipmapsRequired() && !image.isMipmapsGenerated())) { // Check NPOT requirements - checkNonPowerOfTwo(tex); - - updateTexImageData(image, tex.getType(), unit); + boolean scaleToPot = false; + + try { + checkNonPowerOfTwo(tex); + } catch (RendererException ex) { + if (logger.isLoggable(Level.WARNING)) { + int nextWidth = FastMath.nearestPowerOfTwo(tex.getImage().getWidth()); + int nextHeight = FastMath.nearestPowerOfTwo(tex.getImage().getHeight()); + logger.log(Level.WARNING, + "Non-power-of-2 textures are not supported! Scaling texture '" + tex.getName() + + "' of size " + tex.getImage().getWidth() + "x" + tex.getImage().getHeight() + + " to " + nextWidth + "x" + nextHeight); + } + scaleToPot = true; + } + + updateTexImageData(image, tex.getType(), unit, scaleToPot); } int texId = image.getId(); @@ -2144,8 +2157,8 @@ public class GLRenderer implements Renderer { } /*********************************************************************\ - |* Vertex Buffers and Attributes *| - \*********************************************************************/ + |* Vertex Buffers and Attributes *| + \*********************************************************************/ private int convertUsage(Usage usage) { switch (usage) { case Static: @@ -2219,7 +2232,7 @@ public class GLRenderer implements Renderer { //statistics.onVertexBufferUse(vb, false); } } - + int usage = convertUsage(vb.getUsage()); vb.getData().rewind(); @@ -2280,7 +2293,7 @@ public class GLRenderer implements Renderer { if (context.boundShaderProgram <= 0) { throw new IllegalStateException("Cannot render mesh without shader bound"); } - + Attribute attrib = context.boundShader.getAttribute(vb.getBufferType()); int loc = attrib.getLocation(); if (loc == -1) { @@ -2410,7 +2423,7 @@ public class GLRenderer implements Renderer { // What is this? throw new RendererException("Unexpected format for index buffer: " + indexBuf.getFormat()); } - + if (indexBuf.isUpdateNeeded()) { updateBufferData(indexBuf); } @@ -2484,8 +2497,8 @@ public class GLRenderer implements Renderer { } /*********************************************************************\ - |* Render Calls *| - \*********************************************************************/ + |* Render Calls *| + \*********************************************************************/ public int convertElementMode(Mesh.Mode mode) { switch (mode) { case Points: @@ -2527,7 +2540,7 @@ public class GLRenderer implements Renderer { if (interleavedData != null && interleavedData.isUpdateNeeded()) { updateBufferData(interleavedData); } - + if (instanceData != null) { setVertexAttrib(instanceData, null); } @@ -2577,11 +2590,11 @@ public class GLRenderer implements Renderer { } private void renderMeshDefault(Mesh mesh, int lod, int count, VertexBuffer[] instanceData) { - + // Here while count is still passed in. Can be removed when/if // the method is collapsed again. -pspeed count = Math.max(mesh.getInstanceCount(), count); - + VertexBuffer interleavedData = mesh.getBuffer(Type.InterleavedData); if (interleavedData != null && interleavedData.isUpdateNeeded()) { updateBufferData(interleavedData); @@ -2599,7 +2612,7 @@ public class GLRenderer implements Renderer { setVertexAttrib(vb, null); } } - + for (VertexBuffer vb : mesh.getBufferList().getArray()) { if (vb.getBufferType() == Type.InterleavedData || vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers @@ -2634,7 +2647,7 @@ public class GLRenderer implements Renderer { gl.glLineWidth(mesh.getLineWidth()); context.lineWidth = mesh.getLineWidth(); } - + if (gl4 != null && mesh.getMode().equals(Mode.Patch)) { gl4.glPatchParameter(mesh.getPatchVertexCount()); } @@ -2648,14 +2661,14 @@ public class GLRenderer implements Renderer { public void setMainFrameBufferSrgb(boolean enableSrgb) { // Gamma correction - if (!caps.contains(Caps.Srgb)) { + if (!caps.contains(Caps.Srgb) && enableSrgb) { // Not supported, sorry. - logger.warning("sRGB framebuffer is not supported " + - "by video hardware, but was requested."); - + logger.warning("sRGB framebuffer is not supported " + + "by video hardware, but was requested."); + return; } - + setFrameBuffer(null); if (enableSrgb) { diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/TextureUtil.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/TextureUtil.java index 37ffe5ed3..fb6032393 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/TextureUtil.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/TextureUtil.java @@ -54,14 +54,12 @@ final class TextureUtil { private final GL gl; private final GL2 gl2; private final GLExt glext; - private final RenderContext context; private GLImageFormat[][] formats; - - public TextureUtil(GL gl, GL2 gl2, GLExt glext, RenderContext context) { + + public TextureUtil(GL gl, GL2 gl2, GLExt glext) { this.gl = gl; this.gl2 = gl2; this.glext = glext; - this.context = context; } public void initialize(EnumSet caps) { @@ -92,9 +90,11 @@ final class TextureUtil { } public GLImageFormat getImageFormatWithError(Format fmt, boolean isSrgb) { + //if the passed format is one kind of depth there isno point in getting the srgb format; + isSrgb = isSrgb && fmt != Format.Depth && fmt != Format.Depth16 && fmt != Format.Depth24 && fmt != Format.Depth24Stencil8 && fmt != Format.Depth32 && fmt != Format.Depth32F; GLImageFormat glFmt = getImageFormat(fmt, isSrgb); if (glFmt == null && isSrgb) { - glFmt = getImageFormat(fmt, false); + glFmt = getImageFormat(fmt, false); logger.log(Level.WARNING, "No sRGB format available for ''{0}''. Failling back to linear.", fmt); } if (glFmt == null) { @@ -103,6 +103,33 @@ final class TextureUtil { return glFmt; } + private void setupTextureSwizzle(int target, Format format) { + // Needed for OpenGL 3.3 to support luminance / alpha formats + switch (format) { + case Alpha8: + gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_R, GL.GL_ZERO); + gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_G, GL.GL_ZERO); + gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_B, GL.GL_ZERO); + gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_A, GL.GL_RED); + break; + case Luminance8: + case Luminance16F: + case Luminance32F: + gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_R, GL.GL_RED); + gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_G, GL.GL_RED); + gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_B, GL.GL_RED); + gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_A, GL.GL_ONE); + break; + case Luminance8Alpha8: + case Luminance16FAlpha16F: + gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_R, GL.GL_RED); + gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_G, GL.GL_RED); + gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_B, GL.GL_RED); + gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_A, GL.GL_GREEN); + break; + } + } + private void uploadTextureLevel(GLImageFormat format, int target, int level, int slice, int sliceCount, int width, int height, int depth, int samples, ByteBuffer data) { if (format.compressed && data != null) { if (target == GL2.GL_TEXTURE_3D) { @@ -242,6 +269,11 @@ final class TextureUtil { } int samples = image.getMultiSamples(); + + // For OGL3 core: setup texture swizzle. + if (oglFormat.swizzleRequired) { + setupTextureSwizzle(target, jmeFormat); + } for (int i = 0; i < mipSizes.length; i++) { int mipWidth = Math.max(1, width >> i); diff --git a/jme3-core/src/main/java/com/jme3/scene/BatchNode.java b/jme3-core/src/main/java/com/jme3/scene/BatchNode.java index 475cfdf71..c3a0ab4bb 100644 --- a/jme3-core/src/main/java/com/jme3/scene/BatchNode.java +++ b/jme3-core/src/main/java/com/jme3/scene/BatchNode.java @@ -119,19 +119,6 @@ public class BatchNode extends GeometryGroupNode { setNeedsFullRebatch(true); } - @Override - public void updateGeometricState() { - if (!children.isEmpty()) { - for (Batch batch : batches.getArray()) { - if (batch.needMeshUpdate) { - batch.geometry.updateModelBound(); - batch.geometry.updateWorldBound(); - batch.needMeshUpdate = false; - } - } - } - super.updateGeometricState(); - } protected Matrix4f getTransformMatrix(Geometry g){ return g.cachedWorldMat; @@ -169,7 +156,7 @@ public class BatchNode extends GeometryGroupNode { nvb.updateData(normBuf); - batch.needMeshUpdate = true; + batch.geometry.updateModelBound(); } } @@ -234,7 +221,7 @@ public class BatchNode extends GeometryGroupNode { batch.geometry.setMesh(m); batch.geometry.getMesh().updateCounts(); - batch.geometry.getMesh().updateBound(); + batch.geometry.updateModelBound(); batches.add(batch); } if (batches.size() > 0) { @@ -457,6 +444,7 @@ public class BatchNode extends GeometryGroupNode { int maxWeights = -1; Mesh.Mode mode = null; + float lineWidth = 1f; for (Geometry geom : geometries) { totalVerts += geom.getVertexCount(); totalTris += geom.getTriangleCount(); @@ -465,6 +453,7 @@ public class BatchNode extends GeometryGroupNode { maxVertCount = geom.getVertexCount(); } Mesh.Mode listMode; + float listLineWidth = 1f; int components; switch (geom.getMesh().getMode()) { case Points: @@ -475,6 +464,7 @@ public class BatchNode extends GeometryGroupNode { case LineStrip: case Lines: listMode = Mesh.Mode.Lines; + listLineWidth = geom.getMesh().getLineWidth(); components = 2; break; case TriangleFan: @@ -504,13 +494,21 @@ public class BatchNode extends GeometryGroupNode { if (mode != null && mode != listMode) { throw new UnsupportedOperationException("Cannot combine different" + " primitive types: " + mode + " != " + listMode); - } + } mode = listMode; + if (mode == Mesh.Mode.Lines) { + if (lineWidth != 1f && listLineWidth != lineWidth) { + throw new UnsupportedOperationException("When using Mesh Line mode, cannot combine meshes with different line width " + + lineWidth + " != " + listLineWidth); + } + lineWidth = listLineWidth; + } compsForBuf[VertexBuffer.Type.Index.ordinal()] = components; } outMesh.setMaxNumWeights(maxWeights); outMesh.setMode(mode); + outMesh.setLineWidth(lineWidth); if (totalVerts >= 65536) { // make sure we create an UnsignedInt buffer so // we can fit all of the meshes @@ -583,11 +581,13 @@ public class BatchNode extends GeometryGroupNode { useTangents = true; } } else { - inBuf.copyElements(0, outBuf, globalVertIndex, geomVertCount); -// for (int vert = 0; vert < geomVertCount; vert++) { -// int curGlobalVertIndex = globalVertIndex + vert; -// inBuf.copyElement(vert, outBuf, curGlobalVertIndex); -// } + if (inBuf == null) { + throw new IllegalArgumentException("Geometry " + geom.getName() + " has no " + outBuf.getBufferType() + " buffer whereas other geoms have. all geometries should have the same types of buffers.\n Try to use GeometryBatchFactory.alignBuffer() on the BatchNode before batching"); + } else if (outBuf == null) { + throw new IllegalArgumentException("Geometry " + geom.getName() + " has a " + outBuf.getBufferType() + " buffer whereas other geoms don't. all geometries should have the same types of buffers.\n Try to use GeometryBatchFactory.alignBuffer() on the BatchNode before batching"); + } else { + inBuf.copyElements(0, outBuf, globalVertIndex, geomVertCount); + } } } @@ -745,8 +745,7 @@ public class BatchNode extends GeometryGroupNode { } } } - Geometry geometry; - boolean needMeshUpdate = false; + Geometry geometry; } protected void setNeedsFullRebatch(boolean needsFullRebatch) { diff --git a/jme3-core/src/main/java/com/jme3/scene/shape/AbstractBox.java b/jme3-core/src/main/java/com/jme3/scene/shape/AbstractBox.java index 35f078eeb..ab5db2462 100644 --- a/jme3-core/src/main/java/com/jme3/scene/shape/AbstractBox.java +++ b/jme3-core/src/main/java/com/jme3/scene/shape/AbstractBox.java @@ -149,6 +149,7 @@ public abstract class AbstractBox extends Mesh { duUpdateGeometryNormals(); duUpdateGeometryTextures(); duUpdateGeometryIndices(); + setStatic(); } /** diff --git a/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java index 5fac9c834..bd70465cb 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java +++ b/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java @@ -424,7 +424,7 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable renderManager.setCamera(shadowCam, false); renderManager.getRenderer().setFrameBuffer(shadowFB[shadowMapIndex]); - renderManager.getRenderer().clearBuffers(false, true, false); + renderManager.getRenderer().clearBuffers(true, true, true); // render shadow casters to shadow map viewPort.getQueue().renderShadowQueue(shadowMapOccluders, renderManager, shadowCam, true); @@ -459,7 +459,7 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable debug = true; } - abstract void getReceivers(GeometryList lightReceivers); + protected abstract void getReceivers(GeometryList lightReceivers); public void postFrame(FrameBuffer out) { if (skipPostPass) { diff --git a/jme3-core/src/main/java/com/jme3/shadow/BasicShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/BasicShadowRenderer.java index bc4273db7..1410574ea 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/BasicShadowRenderer.java +++ b/jme3-core/src/main/java/com/jme3/shadow/BasicShadowRenderer.java @@ -190,7 +190,7 @@ public class BasicShadowRenderer implements SceneProcessor { renderManager.setForcedMaterial(preshadowMat); r.setFrameBuffer(shadowFB); - r.clearBuffers(false, true, false); + r.clearBuffers(true, true, true); viewPort.getQueue().renderShadowQueue(shadowOccluders, renderManager, shadowCam, true); r.setFrameBuffer(viewPort.getOutputFrameBuffer()); diff --git a/jme3-core/src/main/java/com/jme3/shadow/DirectionalLightShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/DirectionalLightShadowRenderer.java index d0189e854..acf8a9677 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/DirectionalLightShadowRenderer.java +++ b/jme3-core/src/main/java/com/jme3/shadow/DirectionalLightShadowRenderer.java @@ -192,7 +192,7 @@ public class DirectionalLightShadowRenderer extends AbstractShadowRenderer { } @Override - void getReceivers(GeometryList lightReceivers) { + protected void getReceivers(GeometryList lightReceivers) { if (lightReceivers.size()==0) { for (Spatial scene : viewPort.getScenes()) { ShadowUtil.getGeometriesInCamFrustum(scene, viewPort.getCamera(), RenderQueue.ShadowMode.Receive, lightReceivers); diff --git a/jme3-core/src/main/java/com/jme3/shadow/PointLightShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/PointLightShadowRenderer.java index 2976a2460..f4a6455f1 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/PointLightShadowRenderer.java +++ b/jme3-core/src/main/java/com/jme3/shadow/PointLightShadowRenderer.java @@ -139,7 +139,7 @@ public class PointLightShadowRenderer extends AbstractShadowRenderer { } @Override - void getReceivers(GeometryList lightReceivers) { + protected void getReceivers(GeometryList lightReceivers) { lightReceivers.clear(); for (Spatial scene : viewPort.getScenes()) { ShadowUtil.getLitGeometriesInViewPort(scene, viewPort.getCamera(), shadowCams, RenderQueue.ShadowMode.Receive, lightReceivers); diff --git a/jme3-core/src/main/java/com/jme3/shadow/PssmShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/PssmShadowRenderer.java index 182052e13..e06b5c337 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/PssmShadowRenderer.java +++ b/jme3-core/src/main/java/com/jme3/shadow/PssmShadowRenderer.java @@ -450,7 +450,7 @@ public class PssmShadowRenderer implements SceneProcessor { } r.setFrameBuffer(shadowFB[i]); - r.clearBuffers(false, true, false); + r.clearBuffers(true, true, true); // render shadow casters to shadow map viewPort.getQueue().renderShadowQueue(splitOccluders, renderManager, shadowCam, true); diff --git a/jme3-core/src/main/java/com/jme3/shadow/SpotLightShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/SpotLightShadowRenderer.java index dafd25ac4..b291e722e 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/SpotLightShadowRenderer.java +++ b/jme3-core/src/main/java/com/jme3/shadow/SpotLightShadowRenderer.java @@ -151,7 +151,7 @@ public class SpotLightShadowRenderer extends AbstractShadowRenderer { } @Override - void getReceivers(GeometryList lightReceivers) { + protected void getReceivers(GeometryList lightReceivers) { lightReceivers.clear(); Camera[] cameras = new Camera[1]; cameras[0] = shadowCam; diff --git a/jme3-core/src/main/java/com/jme3/system/AppSettings.java b/jme3-core/src/main/java/com/jme3/system/AppSettings.java index 73b036f2f..484458929 100644 --- a/jme3-core/src/main/java/com/jme3/system/AppSettings.java +++ b/jme3-core/src/main/java/com/jme3/system/AppSettings.java @@ -54,6 +54,8 @@ import java.util.prefs.Preferences; */ public final class AppSettings extends HashMap { + private static final long serialVersionUID = 1L; + private static final AppSettings defaults = new AppSettings(false); /** diff --git a/jme3-core/src/main/java/com/jme3/system/JmeSystem.java b/jme3-core/src/main/java/com/jme3/system/JmeSystem.java index 1ec695388..51c2173fd 100644 --- a/jme3-core/src/main/java/com/jme3/system/JmeSystem.java +++ b/jme3-core/src/main/java/com/jme3/system/JmeSystem.java @@ -172,15 +172,6 @@ public class JmeSystem { return systemDelegate.getPlatformAssetConfigURL(); } - /** - * @deprecated Directly create an image raster via {@link DefaultImageRaster}. - */ - @Deprecated - public static ImageRaster createImageRaster(Image image, int slice) { - checkDelegate(); - return systemDelegate.createImageRaster(image, slice); - } - /** * Displays an error message to the user in whichever way the context * feels is appropriate. If this is a headless or an offscreen surface diff --git a/jme3-core/src/main/java/com/jme3/system/JmeSystemDelegate.java b/jme3-core/src/main/java/com/jme3/system/JmeSystemDelegate.java index a3f75bd9a..150275d46 100644 --- a/jme3-core/src/main/java/com/jme3/system/JmeSystemDelegate.java +++ b/jme3-core/src/main/java/com/jme3/system/JmeSystemDelegate.java @@ -132,11 +132,6 @@ public abstract class JmeSystemDelegate { return new DesktopAssetManager(null); } - @Deprecated - public final ImageRaster createImageRaster(Image image, int slice) { - return new DefaultImageRaster(image, slice); - } - public abstract void writeImageFile(OutputStream outStream, String format, ByteBuffer imageData, int width, int height) throws IOException; public abstract void showErrorDialog(String message); diff --git a/jme3-core/src/main/java/com/jme3/system/JmeVersion.java b/jme3-core/src/main/java/com/jme3/system/JmeVersion.java new file mode 100644 index 000000000..0492df950 --- /dev/null +++ b/jme3-core/src/main/java/com/jme3/system/JmeVersion.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2009-2015 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.system; + +import java.io.IOException; +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Pulls in version info from the version.properties file. + * + * @author Kirill Vainer + */ +public class JmeVersion { + + private static final Logger logger = Logger.getLogger(JmeVersion.class.getName()); + private static final Properties props = new Properties(); + + static { + try { + props.load(JmeVersion.class.getResourceAsStream("version.properties")); + } catch (IOException ex) { + logger.log(Level.WARNING, "Unable to read version info!", ex); + } + } + + public static final String BUILD_DATE = props.getProperty("build.date", "1900-01-01"); + public static final String BRANCH_NAME = props.getProperty("git.branch", "unknown"); + public static final String GIT_HASH = props.getProperty("git.hash", ""); + public static final String GIT_SHORT_HASH = props.getProperty("git.hash.short", ""); + public static final String GIT_TAG = props.getProperty("git.tag", ""); + public static final String VERSION_NUMBER = props.getProperty("version.number", ""); + public static final String VERSION_TAG = props.getProperty("version.tag", ""); + public static final String VERSION_FULL = props.getProperty("version.full", ""); + public static final String FULL_NAME = props.getProperty("name.full", "jMonkeyEngine (unknown version)"); +} diff --git a/jme3-core/src/main/java/com/jme3/texture/Image.java b/jme3-core/src/main/java/com/jme3/texture/Image.java index 96ab62819..ca9404720 100644 --- a/jme3-core/src/main/java/com/jme3/texture/Image.java +++ b/jme3-core/src/main/java/com/jme3/texture/Image.java @@ -367,7 +367,6 @@ public class Image extends NativeObject implements Savable /*, Cloneable*/ { protected int width, height, depth; protected int[] mipMapSizes; protected ArrayList data; - protected transient Object efficientData; protected int multiSamples = 1; protected ColorSpace colorSpace = null; // protected int mipOffset = 0; @@ -375,7 +374,7 @@ public class Image extends NativeObject implements Savable /*, Cloneable*/ { // attributes relating to GL object protected boolean mipsWereGenerated = false; protected boolean needGeneratedMips = false; - protected final LastTextureState lastTextureState = new LastTextureState(); + protected LastTextureState lastTextureState = new LastTextureState(); /** * Internal use only. @@ -490,6 +489,7 @@ public class Image extends NativeObject implements Savable /*, Cloneable*/ { Image clone = (Image) super.clone(); clone.mipMapSizes = mipMapSizes != null ? mipMapSizes.clone() : null; clone.data = data != null ? new ArrayList(data) : null; + clone.lastTextureState = new LastTextureState(); clone.setUpdateNeeded(); return clone; } @@ -760,8 +760,6 @@ public class Image extends NativeObject implements Savable /*, Cloneable*/ { */ @Deprecated public void setEfficentData(Object efficientData){ - this.efficientData = efficientData; - setUpdateNeeded(); } /** @@ -769,7 +767,7 @@ public class Image extends NativeObject implements Savable /*, Cloneable*/ { */ @Deprecated public Object getEfficentData(){ - return efficientData; + return null; } /** 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 index 4cbfc3b57..c79a4675d 100644 --- a/jme3-core/src/main/java/com/jme3/texture/image/DefaultImageRaster.java +++ b/jme3-core/src/main/java/com/jme3/texture/image/DefaultImageRaster.java @@ -44,7 +44,9 @@ public class DefaultImageRaster extends ImageRaster { private final ImageCodec codec; private final int width; private final int height; + private final int offset; private final byte[] temp; + private final boolean convertToLinear; private int slice; private void rangeCheck(int x, int y) { @@ -53,13 +55,40 @@ public class DefaultImageRaster extends ImageRaster { } } - public DefaultImageRaster(Image image, int slice) { + public DefaultImageRaster(Image image, int slice, int mipMapLevel, boolean convertToLinear) { + int[] mipMapSizes = image.getMipMapSizes(); + int availableMips = mipMapSizes != null ? mipMapSizes.length : 1; + + if (mipMapLevel >= availableMips) { + throw new IllegalStateException("Cannot create image raster for mipmap level #" + mipMapLevel + ". " + + "Image only has " + availableMips + " mipmap levels."); + } + + if (image.hasMipmaps()) { + this.width = Math.max(1, image.getWidth() >> mipMapLevel); + this.height = Math.max(1, image.getHeight() >> mipMapLevel); + + int mipOffset = 0; + for (int i = 0; i < mipMapLevel; i++) { + mipOffset += mipMapSizes[i]; + } + + this.offset = mipOffset; + } else { + this.width = image.getWidth(); + this.height = image.getHeight(); + this.offset = 0; + } + this.image = image; this.slice = slice; + + // Conversion to linear only needed if image's color space is sRGB. + this.convertToLinear = convertToLinear && image.getColorSpace() == ColorSpace.sRGB; + this.buffer = image.getData(slice); this.codec = ImageCodec.lookup(image.getFormat()); - this.width = image.getWidth(); - this.height = image.getHeight(); + if (codec instanceof ByteAlignedImageCodec || codec instanceof ByteOffsetImageCodec) { this.temp = new byte[codec.bpp]; } else { @@ -86,6 +115,12 @@ public class DefaultImageRaster extends ImageRaster { public void setPixel(int x, int y, ColorRGBA color) { rangeCheck(x, y); + 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; @@ -113,7 +148,7 @@ public class DefaultImageRaster extends ImageRaster { components[3] = Math.min( (int) (color.b * codec.maxBlue + 0.5f), codec.maxBlue); break; } - codec.writeComponents(getBuffer(), x, y, width, 0, components, temp); + codec.writeComponents(getBuffer(), x, y, width, offset, components, temp); image.setUpdateNeeded(); } @@ -128,7 +163,7 @@ public class DefaultImageRaster extends ImageRaster { public ColorRGBA getPixel(int x, int y, ColorRGBA store) { rangeCheck(x, y); - codec.readComponents(getBuffer(), x, y, width, 0, components, temp); + codec.readComponents(getBuffer(), x, y, width, offset, components, temp); if (store == null) { store = new ColorRGBA(); } @@ -169,6 +204,12 @@ public class DefaultImageRaster extends ImageRaster { store.a = 1; } } + + 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 index b4e583c35..92bbb3315 100644 --- a/jme3-core/src/main/java/com/jme3/texture/image/ImageRaster.java +++ b/jme3-core/src/main/java/com/jme3/texture/image/ImageRaster.java @@ -71,21 +71,42 @@ public abstract class ImageRaster { * @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 JmeSystem.createImageRaster(image, 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 JmeSystem.createImageRaster(image, 0); + return create(image, 0, 0, false); } public ImageRaster() { diff --git a/jme3-core/src/main/java/com/jme3/util/BufferUtils.java b/jme3-core/src/main/java/com/jme3/util/BufferUtils.java index 84c6f6743..6fc0c50f0 100644 --- a/jme3-core/src/main/java/com/jme3/util/BufferUtils.java +++ b/jme3-core/src/main/java/com/jme3/util/BufferUtils.java @@ -36,6 +36,7 @@ import com.jme3.math.Quaternion; import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; import com.jme3.math.Vector4f; +import java.io.UnsupportedEncodingException; import java.lang.ref.PhantomReference; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; @@ -1010,11 +1011,15 @@ public final class BufferUtils { } public static ByteBuffer createByteBuffer(String data) { - byte[] bytes = data.getBytes(); - ByteBuffer bb = createByteBuffer(bytes.length); - bb.put(bytes); - bb.flip(); - return bb; + try { + byte[] bytes = data.getBytes("UTF-8"); + ByteBuffer bb = createByteBuffer(bytes.length); + bb.put(bytes); + bb.flip(); + return bb; + } catch (UnsupportedEncodingException ex) { + throw new UnsupportedOperationException(ex); + } } /** diff --git a/jme3-core/src/main/java/com/jme3/util/LittleEndien.java b/jme3-core/src/main/java/com/jme3/util/LittleEndien.java index 092f77018..6b15a7d45 100644 --- a/jme3-core/src/main/java/com/jme3/util/LittleEndien.java +++ b/jme3-core/src/main/java/com/jme3/util/LittleEndien.java @@ -42,7 +42,6 @@ import java.io.*; public class LittleEndien extends InputStream implements DataInput { protected BufferedInputStream in; - protected BufferedReader inRead; /** * Creates a new LittleEndien reader from the given input stream. The @@ -51,7 +50,6 @@ public class LittleEndien extends InputStream implements DataInput { */ public LittleEndien(InputStream in) { this.in = new BufferedInputStream(in); - inRead = new BufferedReader(new InputStreamReader(in)); } public int read() throws IOException { @@ -141,7 +139,7 @@ public class LittleEndien extends InputStream implements DataInput { } public String readLine() throws IOException { - return inRead.readLine(); + throw new IOException("Unsupported operation"); } public String readUTF() throws IOException { diff --git a/jme3-core/src/main/java/com/jme3/util/MipMapGenerator.java b/jme3-core/src/main/java/com/jme3/util/MipMapGenerator.java new file mode 100644 index 000000000..3ac6a7ecd --- /dev/null +++ b/jme3-core/src/main/java/com/jme3/util/MipMapGenerator.java @@ -0,0 +1,140 @@ +/* + * 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.util; + +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.texture.Image; +import com.jme3.texture.Image.Format; +import com.jme3.texture.image.ImageRaster; +import java.nio.ByteBuffer; +import java.util.ArrayList; + +public class MipMapGenerator { + + private MipMapGenerator() { + } + + public static Image scaleImage(Image inputImage, int outputWidth, int outputHeight) { + int size = outputWidth * outputHeight * inputImage.getFormat().getBitsPerPixel() / 8; + ByteBuffer buffer = BufferUtils.createByteBuffer(size); + Image outputImage = new Image(inputImage.getFormat(), + outputWidth, + outputHeight, + buffer, + inputImage.getColorSpace()); + + ImageRaster input = ImageRaster.create(inputImage, 0, 0, false); + ImageRaster output = ImageRaster.create(outputImage, 0, 0, false); + + float xRatio = ((float)(input.getWidth() - 1)) / output.getWidth(); + float yRatio = ((float)(input.getHeight() - 1)) / output.getHeight(); + + ColorRGBA outputColor = new ColorRGBA(); + ColorRGBA bottomLeft = new ColorRGBA(); + ColorRGBA bottomRight = new ColorRGBA(); + ColorRGBA topLeft = new ColorRGBA(); + ColorRGBA topRight = new ColorRGBA(); + + for (int y = 0; y < outputHeight; y++) { + for (int x = 0; x < outputWidth; x++) { + float x2f = x * xRatio; + float y2f = y * yRatio; + + int x2 = (int)x2f; + int y2 = (int)y2f; + + float xDiff = x2f - x2; + float yDiff = y2f - y2; + + input.getPixel(x2, y2, bottomLeft); + input.getPixel(x2 + 1, y2, bottomRight); + input.getPixel(x2, y2 + 1, topLeft); + input.getPixel(x2 + 1, y2 + 1, topRight); + + bottomLeft.multLocal( (1f - xDiff) * (1f - yDiff) ); + bottomRight.multLocal( (xDiff) * (1f - yDiff) ); + topLeft.multLocal( (1f - xDiff) * (yDiff) ); + topRight.multLocal( (xDiff) * (yDiff) ); + + outputColor.set(bottomLeft).addLocal(bottomRight) + .addLocal(topLeft).addLocal(topRight); + + output.setPixel(x, y, outputColor); + } + } + return outputImage; + } + + public static Image resizeToPowerOf2(Image original){ + int potWidth = FastMath.nearestPowerOfTwo(original.getWidth()); + int potHeight = FastMath.nearestPowerOfTwo(original.getHeight()); + return scaleImage(original, potWidth, potHeight); + } + + public static void generateMipMaps(Image image){ + int width = image.getWidth(); + int height = image.getHeight(); + + Image current = image; + ArrayList output = new ArrayList(); + int totalSize = 0; + + while (height >= 1 || width >= 1){ + output.add(current.getData(0)); + totalSize += current.getData(0).capacity(); + + if (height == 1 || width == 1) { + break; + } + + height /= 2; + width /= 2; + + current = scaleImage(current, width, height); + } + + ByteBuffer combinedData = BufferUtils.createByteBuffer(totalSize); + int[] mipSizes = new int[output.size()]; + for (int i = 0; i < output.size(); i++){ + ByteBuffer data = output.get(i); + data.clear(); + combinedData.put(data); + mipSizes[i] = data.capacity(); + } + combinedData.flip(); + + // insert mip data into image + image.setData(0, combinedData); + image.setMipMapSizes(mipSizes); + } +} diff --git a/jme3-core/src/main/java/com/jme3/util/TangentBinormalGenerator.java b/jme3-core/src/main/java/com/jme3/util/TangentBinormalGenerator.java index 0f9aac1fc..5e85378ff 100644 --- a/jme3-core/src/main/java/com/jme3/util/TangentBinormalGenerator.java +++ b/jme3-core/src/main/java/com/jme3/util/TangentBinormalGenerator.java @@ -612,9 +612,9 @@ public class TangentBinormalGenerator { normal.normalizeLocal(); return new TriangleData( - tangent, - binormal, - normal); + tangent.clone(), + binormal.clone(), + normal.clone()); } finally { tmp.release(); } diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.frag b/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.frag index 107597047..d2ade5199 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.frag +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.frag @@ -37,6 +37,7 @@ varying vec3 SpecularSum; #endif #if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) && !defined(VERTEX_LIGHTING) uniform float m_ParallaxHeight; + varying vec3 vViewDirPrlx; #endif #ifdef LIGHTMAP @@ -78,18 +79,18 @@ void main(){ #ifdef STEEP_PARALLAX #ifdef NORMALMAP_PARALLAX //parallax map is stored in the alpha channel of the normal map - newTexCoord = steepParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight); + newTexCoord = steepParallaxOffset(m_NormalMap, vViewDirPrlx, texCoord, m_ParallaxHeight); #else //parallax map is a texture - newTexCoord = steepParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight); + newTexCoord = steepParallaxOffset(m_ParallaxMap, vViewDirPrlx, texCoord, m_ParallaxHeight); #endif #else #ifdef NORMALMAP_PARALLAX //parallax map is stored in the alpha channel of the normal map - newTexCoord = classicParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight); + newTexCoord = classicParallaxOffset(m_NormalMap, vViewDirPrlx, texCoord, m_ParallaxHeight); #else //parallax map is a texture - newTexCoord = classicParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight); + newTexCoord = classicParallaxOffset(m_ParallaxMap, vViewDirPrlx, texCoord, m_ParallaxHeight); #endif #endif #else diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.vert b/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.vert index f92b91fff..df441ed59 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.vert +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.vert @@ -48,6 +48,10 @@ varying vec3 lightVec; uniform vec4 g_LightDirection; #endif +#if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) && !defined(VERTEX_LIGHTING) + varying vec3 vViewDirPrlx; +#endif + #ifdef USE_REFLECTION uniform vec3 g_CameraPosition; @@ -107,17 +111,25 @@ void main(){ wvLightPos.w = g_LightPosition.w; vec4 lightColor = g_LightColor; - #if defined(NORMALMAP) && !defined(VERTEX_LIGHTING) + #if (defined(NORMALMAP) || defined(PARALLAXMAP)) && !defined(VERTEX_LIGHTING) vec3 wvTangent = normalize(TransformNormal(modelSpaceTan)); vec3 wvBinormal = cross(wvNormal, wvTangent); mat3 tbnMat = mat3(wvTangent, wvBinormal * inTangent.w,wvNormal); + #endif - vViewDir = -wvPosition * tbnMat; + #if defined(NORMALMAP) && !defined(VERTEX_LIGHTING) + vViewDir = -wvPosition * tbnMat; + #if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) + vViewDirPrlx = vViewDir; + #endif lightComputeDir(wvPosition, lightColor.w, wvLightPos, vLightDir, lightVec); vLightDir.xyz = (vLightDir.xyz * tbnMat).xyz; #elif !defined(VERTEX_LIGHTING) vNormal = wvNormal; vViewDir = viewDir; + #if defined(PARALLAXMAP) + vViewDirPrlx = -wvPosition * tbnMat; + #endif lightComputeDir(wvPosition, lightColor.w, wvLightPos, vLightDir, lightVec); #endif diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/SPLighting.frag b/jme3-core/src/main/resources/Common/MatDefs/Light/SPLighting.frag index 26b68a533..254806d87 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Light/SPLighting.frag +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/SPLighting.frag @@ -17,10 +17,7 @@ varying vec3 SpecularSum; #ifndef VERTEX_LIGHTING uniform mat4 g_ViewMatrix; uniform vec4 g_LightData[NB_LIGHTS]; - varying vec3 vPos; -#else - varying vec3 specularAccum; - varying vec4 diffuseAccum; + varying vec3 vPos; #endif #ifdef DIFFUSEMAP @@ -167,10 +164,9 @@ void main(){ #endif #ifdef VERTEX_LIGHTING - gl_FragColor.rgb = AmbientSum * diffuseColor.rgb - +diffuseAccum.rgb *diffuseColor.rgb - +specularAccum.rgb * specularColor.rgb; - gl_FragColor.a=1.0; + gl_FragColor.rgb = AmbientSum.rgb * diffuseColor.rgb + + DiffuseSum.rgb * diffuseColor.rgb + + SpecularSum.rgb * specularColor.rgb; #else int i = 0; diff --git a/jme3-core/src/main/resources/Common/MatDefs/Light/SPLighting.vert b/jme3-core/src/main/resources/Common/MatDefs/Light/SPLighting.vert index 6ad224d9b..1fde8e13d 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Light/SPLighting.vert +++ b/jme3-core/src/main/resources/Common/MatDefs/Light/SPLighting.vert @@ -43,8 +43,6 @@ attribute vec3 inNormal; varying vec3 vBinormal; #endif #else - varying vec3 specularAccum; - varying vec4 diffuseAccum; #ifdef COLORRAMP uniform sampler2D m_ColorRamp; #endif @@ -131,14 +129,13 @@ void main(){ #endif #ifdef VERTEX_LIGHTING int i = 0; - diffuseAccum = vec4(0.0); - specularAccum = vec3(0.0); + vec3 diffuseAccum = vec3(0.0); + vec3 specularAccum = vec3(0.0); vec4 diffuseColor; vec3 specularColor; for (int i =0;i < NB_LIGHTS; i+=3){ vec4 lightColor = g_LightData[i]; vec4 lightData1 = g_LightData[i+1]; - DiffuseSum = vec4(1.0); #ifdef MATERIAL_COLORS diffuseColor = m_Diffuse * vec4(lightColor.rgb, 1.0); specularColor = m_Specular.rgb * lightColor.rgb; @@ -166,13 +163,16 @@ void main(){ vec2 light = computeLighting(wvNormal, viewDir, lightDir.xyz, lightDir.w * spotFallOff, m_Shininess); #ifdef COLORRAMP - diffuseAccum.rgb += texture2D(m_ColorRamp, vec2(light.x, 0.0)).rgb * diffuseColor.rgb; - specularAccum.rgb += texture2D(m_ColorRamp, vec2(light.y, 0.0)).rgb * specularColor; + diffuseAccum += texture2D(m_ColorRamp, vec2(light.x, 0.0)).rgb * diffuseColor.rgb; + specularAccum += texture2D(m_ColorRamp, vec2(light.y, 0.0)).rgb * specularColor; #else - diffuseAccum.rgb += light.x * diffuseColor.rgb; - specularAccum.rgb += light.y * specularColor; + diffuseAccum += light.x * diffuseColor.rgb; + specularAccum += light.y * specularColor; #endif } + + DiffuseSum.rgb *= diffuseAccum.rgb; + SpecularSum.rgb *= specularAccum.rgb; #endif diff --git a/jme3-core/src/main/resources/Common/MatDefs/Misc/ColoredTextured.j3md b/jme3-core/src/main/resources/Common/MatDefs/Misc/ColoredTextured.j3md index 6b74c3074..497b7d0a7 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Misc/ColoredTextured.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Misc/ColoredTextured.j3md @@ -1,3 +1,4 @@ +Exception This material definition is deprecated. Please use Unshaded.j3md instead. MaterialDef Colored Textured { MaterialParameters { @@ -17,4 +18,4 @@ MaterialDef Colored Textured { Technique { } -} \ No newline at end of file +} diff --git a/jme3-core/src/main/resources/Common/MatDefs/Misc/Unshaded.frag b/jme3-core/src/main/resources/Common/MatDefs/Misc/Unshaded.frag index ce8219b6e..e615d8f1e 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Misc/Unshaded.frag +++ b/jme3-core/src/main/resources/Common/MatDefs/Misc/Unshaded.frag @@ -1,3 +1,5 @@ +#import "Common/ShaderLib/GLSLCompat.glsllib" + #if defined(HAS_GLOWMAP) || defined(HAS_COLORMAP) || (defined(HAS_LIGHTMAP) && !defined(SEPARATE_TEXCOORD)) #define NEED_TEXCOORD1 #endif diff --git a/jme3-core/src/main/resources/Common/MatDefs/Misc/Unshaded.j3md b/jme3-core/src/main/resources/Common/MatDefs/Misc/Unshaded.j3md index aee284705..8dd6fc5ca 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Misc/Unshaded.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Misc/Unshaded.j3md @@ -13,7 +13,7 @@ MaterialDef Unshaded { Color GlowColor // For instancing - Boolean UseInstancing + Boolean UseInstancing // For hardware skinning Int NumberOfBones @@ -54,8 +54,8 @@ MaterialDef Unshaded { } Technique { - VertexShader GLSL100: Common/MatDefs/Misc/Unshaded.vert - FragmentShader GLSL100: Common/MatDefs/Misc/Unshaded.frag + VertexShader GLSL150: Common/MatDefs/Misc/Unshaded.vert + FragmentShader GLSL150: Common/MatDefs/Misc/Unshaded.frag WorldParameters { WorldViewProjectionMatrix @@ -76,6 +76,25 @@ MaterialDef Unshaded { } Technique { + VertexShader GLSL100: Common/MatDefs/Misc/Unshaded.vert + FragmentShader GLSL100: Common/MatDefs/Misc/Unshaded.frag + + WorldParameters { + WorldViewProjectionMatrix + ViewProjectionMatrix + ViewMatrix + } + + Defines { + INSTANCING : UseInstancing + SEPARATE_TEXCOORD : SeparateTexCoord + HAS_COLORMAP : ColorMap + HAS_LIGHTMAP : LightMap + HAS_VERTEXCOLOR : VertexColor + HAS_COLOR : Color + NUM_BONES : NumberOfBones + DISCARD_ALPHA : AlphaDiscardThreshold + } } Technique PreNormalPass { diff --git a/jme3-core/src/main/resources/Common/MatDefs/Misc/Unshaded.vert b/jme3-core/src/main/resources/Common/MatDefs/Misc/Unshaded.vert index 63b05ef88..ba7899ca5 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Misc/Unshaded.vert +++ b/jme3-core/src/main/resources/Common/MatDefs/Misc/Unshaded.vert @@ -1,3 +1,4 @@ +#import "Common/ShaderLib/GLSLCompat.glsllib" #import "Common/ShaderLib/Skinning.glsllib" #import "Common/ShaderLib/Instancing.glsllib" diff --git a/jme3-core/src/main/resources/Common/MatDefs/Misc/UnshadedNodes.j3md b/jme3-core/src/main/resources/Common/MatDefs/Misc/UnshadedNodes.j3md index f9fb05288..b35c17a9d 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/Misc/UnshadedNodes.j3md +++ b/jme3-core/src/main/resources/Common/MatDefs/Misc/UnshadedNodes.j3md @@ -1,97 +1,121 @@ -MaterialDef UnshadedNodes { - - MaterialParameters { - Texture2D ColorMap - Texture2D LightMap - Color Color (Color) - Boolean VertexColor (UseVertexColor) - Boolean SeparateTexCoord - - // Alpha threshold for fragment discarding - Float AlphaDiscardThreshold (AlphaTestFallOff) - - // For hardware skinning - Int NumberOfBones - Matrix4Array BoneMatrices - - } - - Technique { - - WorldParameters { - WorldViewProjectionMatrix - //used for fog - WorldViewMatrix - } - - VertexShaderNodes{ - ShaderNode GpuSkinning{ - Definition: BasicGPUSkinning : Common/MatDefs/ShaderNodes/HardwareSkinning/HardwareSkinning.j3sn - Condition : NumberOfBones - InputMapping{ - modelPosition = Global.position; - boneMatrices = MatParam.BoneMatrices - boneWeight = Attr.inHWBoneWeight - boneIndex = Attr.inHWBoneIndex - } - OutputMapping{ - Global.position = modModelPosition - } - } - ShaderNode UnshadedVert{ - Definition: CommonVert : Common/MatDefs/ShaderNodes/Common/CommonVert.j3sn - InputMapping{ - worldViewProjectionMatrix = WorldParam.WorldViewProjectionMatrix - modelPosition = Global.position.xyz - texCoord1 = Attr.inTexCoord: ColorMap || (LightMap && !SeparateTexCoord) - texCoord2 = Attr.inTexCoord2: SeparateTexCoord - vertColor = Attr.inColor: VertexColor - } - OutputMapping{ - Global.position = projPosition - } - } - } - FragmentShaderNodes{ - ShaderNode UnshadedFrag{ - Definition: Unshaded : Common/MatDefs/ShaderNodes/Common/Unshaded.j3sn - InputMapping{ - texCoord = UnshadedVert.texCoord1: ColorMap - vertColor = UnshadedVert.vertColor: VertexColor - matColor = MatParam.Color: Color - colorMap = MatParam.ColorMap: ColorMap - color = Global.outColor - } - OutputMapping{ - Global.outColor = color - } - } - - ShaderNode AlphaDiscardThreshold{ - Definition: AlphaDiscard : Common/MatDefs/ShaderNodes/Basic/AlphaDiscard.j3sn - Condition : AlphaDiscardThreshold - InputMapping{ - alpha = Global.outColor.a - threshold = MatParam.AlphaDiscardThreshold - } - } - ShaderNode LightMap{ - Definition: LightMapping : Common/MatDefs/ShaderNodes/LightMapping/LightMapping.j3sn - Condition: LightMap - InputMapping{ - texCoord = UnshadedVert.texCoord1: !SeparateTexCoord - texCoord = UnshadedVert.texCoord2: SeparateTexCoord - lightMap = MatParam.LightMap - color = Global.outColor - } - OutputMapping{ - Global.outColor = color - } - } - - } - - } - - +MaterialDef UnshadedNodes { + MaterialParameters { + Texture2D ColorMap + Texture2D LightMap + Color Color (Color) + Boolean VertexColor (UseVertexColor) + Boolean SeparateTexCoord + Float AlphaDiscardThreshold (AlphaTestFallOff) + Int NumberOfBones + Matrix4Array BoneMatrices + } + Technique { + WorldParameters { + WorldViewProjectionMatrix + WorldViewMatrix + } + VertexShaderNodes { + ShaderNode GpuSkinning { + Definition : BasicGPUSkinning : Common/MatDefs/ShaderNodes/HardwareSkinning/HardwareSkinning.j3sn + Condition : NumberOfBones + InputMapping { + modelPosition = Global.position + boneMatrices = MatParam.BoneMatrices + boneWeight = Attr.inHWBoneWeight + boneIndex = Attr.inHWBoneIndex + } + OutputMapping { + Global.position = modModelPosition + } + } + ShaderNode UnshadedVert { + Definition : CommonVert : Common/MatDefs/ShaderNodes/Common/CommonVert.j3sn + InputMapping { + worldViewProjectionMatrix = WorldParam.WorldViewProjectionMatrix + modelPosition = Global.position.xyz + texCoord1 = Attr.inTexCoord : ColorMap || (LightMap && !SeparateTexCoord) + texCoord2 = Attr.inTexCoord2 : SeparateTexCoord + vertColor = Attr.inColor : VertexColor + } + OutputMapping { + Global.position = projPosition + } + } + } + FragmentShaderNodes { + ShaderNode MatColorMult { + Definition : ColorMult : Common/MatDefs/ShaderNodes/Basic/ColorMult.j3sn + InputMappings { + color1 = MatParam.Color + color2 = Global.outColor + } + OutputMappings { + Global.outColor = outColor + } + Condition : Color + } + ShaderNode VertColorMult { + Definition : ColorMult : Common/MatDefs/ShaderNodes/Basic/ColorMult.j3sn + InputMappings { + color1 = UnshadedVert.vertColor + color2 = Global.outColor + } + OutputMappings { + Global.outColor = outColor + } + Condition : VertexColor + } + ShaderNode ColorMapTF { + Definition : TextureFetch : Common/MatDefs/ShaderNodes/Basic/TextureFetch.j3sn + InputMappings { + texCoord = UnshadedVert.texCoord1 + textureMap = MatParam.ColorMap + } + OutputMappings { + } + Condition : ColorMap + } + ShaderNode ColorMapMult { + Definition : ColorMult : Common/MatDefs/ShaderNodes/Basic/ColorMult.j3sn + InputMappings { + color1 = ColorMapTF.outColor + color2 = Global.outColor + } + OutputMappings { + Global.outColor = outColor + } + Condition : ColorMap + } + ShaderNode AlphaDiscardThreshold { + Definition : AlphaDiscard : Common/MatDefs/ShaderNodes/Basic/AlphaDiscard.j3sn + Condition : AlphaDiscardThreshold + InputMapping { + alpha = Global.outColor.a + threshold = MatParam.AlphaDiscardThreshold + } + } + ShaderNode LightMapTF { + Definition : TextureFetch : Common/MatDefs/ShaderNodes/Basic/TextureFetch.j3sn + InputMappings { + textureMap = MatParam.LightMap + texCoord = UnshadedVert.texCoord2 : SeparateTexCoord + texCoord = UnshadedVert.texCoord1 : !SeparateTexCoord + } + OutputMappings { + } + Condition : LightMap + } + ShaderNode LightMapMult { + Definition : ColorMult : Common/MatDefs/ShaderNodes/Basic/ColorMult.j3sn + OutputMappings { + Global.outColor = outColor + } + InputMappings { + color1 = LightMapTF.outColor + color2 = Global.outColor + } + Condition : LightMap + } + } + } } \ No newline at end of file diff --git a/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Basic/TextureFetch.j3sn b/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Basic/TextureFetch.j3sn index b4ccd3640..034fcd116 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Basic/TextureFetch.j3sn +++ b/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Basic/TextureFetch.j3sn @@ -2,14 +2,15 @@ ShaderNodeDefinitions{ ShaderNodeDefinition TextureFetch { Type: Fragment Shader GLSL100: Common/MatDefs/ShaderNodes/Basic/texture.frag + Shader GLSL150: Common/MatDefs/ShaderNodes/Basic/texture15.frag Documentation{ Fetches a color value in the given texture acording to given texture coordinates - @input texture the texture to read + @input textureMap the texture to read @input texCoord the texture coordinates @output outColor the fetched color } Input { - sampler2D texture + sampler2D textureMap vec2 texCoord } Output { diff --git a/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Basic/texture.frag b/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Basic/texture.frag index eb83a7b1f..163fbc123 100644 --- a/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Basic/texture.frag +++ b/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Basic/texture.frag @@ -1,3 +1,3 @@ void main(){ - outColor = texture2D(texture,texCoord); + outColor = texture2D(textureMap,texCoord); } \ No newline at end of file diff --git a/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Basic/texture15.frag b/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Basic/texture15.frag new file mode 100644 index 000000000..2ece0a646 --- /dev/null +++ b/jme3-core/src/main/resources/Common/MatDefs/ShaderNodes/Basic/texture15.frag @@ -0,0 +1,3 @@ +void main(){ + outColor = texture(textureMap,texCoord); +} \ No newline at end of file diff --git a/jme3-core/src/main/resources/Common/ShaderLib/GLSLCompat.glsllib b/jme3-core/src/main/resources/Common/ShaderLib/GLSLCompat.glsllib new file mode 100644 index 000000000..3a3173997 --- /dev/null +++ b/jme3-core/src/main/resources/Common/ShaderLib/GLSLCompat.glsllib @@ -0,0 +1,34 @@ +#if defined _GL_ES_ +# define hfloat highp float +# define hvec2 highp vec2 +# define hvec3 highp vec3 +# define hvec4 highp vec4 +# define lfloat lowp float +# define lvec2 lowp vec2 +# define lvec3 lowp vec3 +# define lvec4 lowp vec4 +#else +# define hfloat float +# define hvec2 vec2 +# define hvec3 vec3 +# define hvec4 vec4 +# define lfloat float +# define lvec2 vec2 +# define lvec3 vec3 +# define lvec4 vec4 +#endif + +#if __VERSION__ >= 130 +out vec4 outFragColor; +# define texture1D texture +# define texture2D texture +# define texture3D texture +# define texture2DLod texture +# if defined VERTEX_SHADER +# define varying out +# define attribute in +# elif defined FRAGMENT_SHADER +# define varying in +# define gl_FragColor outFragColor +# endif +#endif \ No newline at end of file diff --git a/jme3-core/src/main/resources/Common/ShaderLib/MultiSample.glsllib b/jme3-core/src/main/resources/Common/ShaderLib/MultiSample.glsllib index bea736f9d..3b06e6441 100644 --- a/jme3-core/src/main/resources/Common/ShaderLib/MultiSample.glsllib +++ b/jme3-core/src/main/resources/Common/ShaderLib/MultiSample.glsllib @@ -15,8 +15,14 @@ uniform int m_NumSamplesDepth; #define DEPTHTEXTURE sampler2D #endif -// NOTE: Only define multisample functions if multisample is available and is being used! -#if defined(GL_ARB_texture_multisample) && (defined(RESOLVE_MS) || defined(RESOLVE_DEPTH_MS)) +#if __VERSION__ >= 150 + #define TEXTURE texture +#else + #define TEXTURE texture2D +#endif + +// NOTE: Only define multisample functions if multisample is available +#if defined(GL_ARB_texture_multisample) vec4 textureFetch(in sampler2DMS tex,in vec2 texC, in int numSamples){ ivec2 iTexC = ivec2(texC * vec2(textureSize(tex))); vec4 color = vec4(0.0); @@ -44,40 +50,21 @@ vec4 getDepth(in sampler2DMS tex,in vec2 texC){ return textureFetch(tex,texC,m_NumSamplesDepth); } -#elif __VERSION__ >= 150 - -vec4 fetchTextureSample(in sampler2D tex,in vec2 texC,in int sample){ - return texture(tex,texC); -} - -vec4 getColor(in sampler2D tex, in vec2 texC){ - return texture(tex,texC); -} - -vec4 getColorSingle(in sampler2D tex, in vec2 texC){ - return texture(tex, texC); -} - -vec4 getDepth(in sampler2D tex,in vec2 texC){ - return texture(tex,texC); -} - -#else +#endif vec4 fetchTextureSample(in sampler2D tex,in vec2 texC,in int sample){ - return texture2D(tex,texC); + return TEXTURE(tex,texC); } vec4 getColor(in sampler2D tex, in vec2 texC){ - return texture2D(tex,texC); + return TEXTURE(tex,texC); } vec4 getColorSingle(in sampler2D tex, in vec2 texC){ - return texture2D(tex, texC); + return TEXTURE(tex, texC); } vec4 getDepth(in sampler2D tex,in vec2 texC){ - return texture2D(tex,texC); + return TEXTURE(tex,texC); } -#endif \ No newline at end of file diff --git a/jme3-core/src/main/resources/com/jme3/asset/Desktop.cfg b/jme3-core/src/main/resources/com/jme3/asset/Desktop.cfg index df72654a1..28727d070 100644 --- a/jme3-core/src/main/resources/com/jme3/asset/Desktop.cfg +++ b/jme3-core/src/main/resources/com/jme3/asset/Desktop.cfg @@ -2,26 +2,4 @@ INCLUDE com/jme3/asset/General.cfg # Desktop-specific loaders LOADER com.jme3.texture.plugins.AWTLoader : jpg, bmp, gif, png, jpeg -LOADER com.jme3.audio.plugins.OGGLoader : oggLOADER com.jme3.audio.plugins.WAVLoader : wav LOADER com.jme3.audio.plugins.OGGLoader : ogg -LOADER com.jme3.cursors.plugins.CursorLoader : ani, cur, ico -LOADER com.jme3.material.plugins.J3MLoader : j3m -LOADER com.jme3.material.plugins.J3MLoader : j3md -LOADER com.jme3.material.plugins.ShaderNodeDefinitionLoader : j3sn -LOADER com.jme3.font.plugins.BitmapFontLoader : fnt -LOADER com.jme3.texture.plugins.DDSLoader : dds -LOADER com.jme3.texture.plugins.PFMLoader : pfm -LOADER com.jme3.texture.plugins.HDRLoader : hdr -LOADER com.jme3.texture.plugins.TGALoader : tga -LOADER com.jme3.export.binary.BinaryImporter : j3o -LOADER com.jme3.export.binary.BinaryImporter : j3f -LOADER com.jme3.scene.plugins.OBJLoader : obj -LOADER com.jme3.scene.plugins.MTLLoader : mtl -LOADER com.jme3.scene.plugins.ogre.MeshLoader : meshxml, mesh.xml -LOADER com.jme3.scene.plugins.ogre.SkeletonLoader : skeletonxml, skeleton.xml -LOADER com.jme3.scene.plugins.ogre.MaterialLoader : material -LOADER com.jme3.scene.plugins.ogre.SceneLoader : scene -LOADER com.jme3.scene.plugins.blender.BlenderModelLoader : blend -LOADER com.jme3.shader.plugins.GLSLLoader : vert, frag,geom,tsctrl,tseval, glsl, glsllib -LOADER com.jme3.scene.plugins.fbx.SceneLoader : fbx -LOADER com.jme3.scene.plugins.fbx.SceneWithAnimationLoader : fba diff --git a/jme3-core/src/main/resources/com/jme3/asset/General.cfg b/jme3-core/src/main/resources/com/jme3/asset/General.cfg index c0098ffe5..c56b62146 100644 --- a/jme3-core/src/main/resources/com/jme3/asset/General.cfg +++ b/jme3-core/src/main/resources/com/jme3/asset/General.cfg @@ -21,6 +21,6 @@ LOADER com.jme3.scene.plugins.ogre.SkeletonLoader : skeletonxml, skeleton.xml LOADER com.jme3.scene.plugins.ogre.MaterialLoader : material LOADER com.jme3.scene.plugins.ogre.SceneLoader : scene LOADER com.jme3.scene.plugins.blender.BlenderModelLoader : blend -LOADER com.jme3.shader.plugins.GLSLLoader : vert, frag, glsl, glsllib +LOADER com.jme3.shader.plugins.GLSLLoader : vert, frag, geom, tsctrl, tseval, glsl, glsllib LOADER com.jme3.scene.plugins.fbx.SceneLoader : fbx LOADER com.jme3.scene.plugins.fbx.SceneWithAnimationLoader : fba diff --git a/jme3-core/src/main/resources/com/jme3/system/version.properties b/jme3-core/src/main/resources/com/jme3/system/version.properties new file mode 100644 index 000000000..98168a14e --- /dev/null +++ b/jme3-core/src/main/resources/com/jme3/system/version.properties @@ -0,0 +1,11 @@ +# THIS IS AN AUTO-GENERATED FILE.. +# DO NOT MODIFY! +build.date=1900-01-01 +git.revision=0 +git.branch=unknown +git.hash= +git.hash.short= +git.tag= +name.full=jMonkeyEngine 3.1.0-UNKNOWN +version.number=3.1.0 +version.tag=SNAPSHOT \ No newline at end of file diff --git a/jme3-core/src/plugins/java/com/jme3/asset/plugins/ZipLocator.java b/jme3-core/src/plugins/java/com/jme3/asset/plugins/ZipLocator.java index d20816f34..22e7cc244 100644 --- a/jme3-core/src/plugins/java/com/jme3/asset/plugins/ZipLocator.java +++ b/jme3-core/src/plugins/java/com/jme3/asset/plugins/ZipLocator.java @@ -82,6 +82,7 @@ public class ZipLocator implements AssetLocator { public AssetInfo locate(AssetManager manager, AssetKey key) { String name = key.getName(); + if(name.startsWith("/"))name=name.substring(1); ZipEntry entry = zipfile.getEntry(name); if (entry == null) return null; diff --git a/jme3-core/src/plugins/java/com/jme3/export/binary/BinaryExporter.java b/jme3-core/src/plugins/java/com/jme3/export/binary/BinaryExporter.java index c02f7088a..eb12bf908 100644 --- a/jme3-core/src/plugins/java/com/jme3/export/binary/BinaryExporter.java +++ b/jme3-core/src/plugins/java/com/jme3/export/binary/BinaryExporter.java @@ -31,6 +31,7 @@ */ package com.jme3.export.binary; +import com.jme3.asset.AssetManager; import com.jme3.export.FormatVersion; import com.jme3.export.JmeExporter; import com.jme3.export.Savable; @@ -167,8 +168,33 @@ public class BinaryExporter implements JmeExporter { public static BinaryExporter getInstance() { return new BinaryExporter(); } + + /** + * Saves the object into memory then loads it from memory. + * + * Used by tests to check if the persistence system is working. + * + * @param The type of savable. + * @param assetManager AssetManager to load assets from. + * @param object The object to save and then load. + * @return A new instance that has been saved and loaded from the + * original object. + */ + public static T saveAndLoad(AssetManager assetManager, T object) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + BinaryExporter exporter = new BinaryExporter(); + exporter.save(object, baos); + BinaryImporter importer = new BinaryImporter(); + importer.setAssetManager(assetManager); + return (T) importer.load(baos.toByteArray()); + } catch (IOException ex) { + // Should never happen. + throw new AssertionError(ex); + } + } - public boolean save(Savable object, OutputStream os) throws IOException { + public void save(Savable object, OutputStream os) throws IOException { // reset some vars aliasCount = 1; idCount = 1; @@ -286,7 +312,7 @@ public class BinaryExporter implements JmeExporter { out = null; os = null; - if (debug ) { + if (debug) { logger.fine("Stats:"); logger.log(Level.FINE, "classes: {0}", classNum); logger.log(Level.FINE, "class table: {0} bytes", classTableSize); @@ -294,8 +320,6 @@ public class BinaryExporter implements JmeExporter { logger.log(Level.FINE, "location table: {0} bytes", locationTableSize); logger.log(Level.FINE, "data: {0} bytes", location); } - - return true; } protected String getChunk(BinaryIdContentPair pair) { @@ -325,7 +349,7 @@ public class BinaryExporter implements JmeExporter { return bytes; } - public boolean save(Savable object, File f) throws IOException { + public void save(Savable object, File f) throws IOException { File parentDirectory = f.getParentFile(); if (parentDirectory != null && !parentDirectory.exists()) { parentDirectory.mkdirs(); @@ -333,11 +357,9 @@ public class BinaryExporter implements JmeExporter { FileOutputStream fos = new FileOutputStream(f); try { - return save(object, fos); + save(object, fos); } finally { - if (fos != null) { - fos.close(); - } + fos.close(); } } diff --git a/jme3-core/src/plugins/java/com/jme3/material/plugins/J3MLoader.java b/jme3-core/src/plugins/java/com/jme3/material/plugins/J3MLoader.java index 0c81c3e14..d0620ca59 100644 --- a/jme3-core/src/plugins/java/com/jme3/material/plugins/J3MLoader.java +++ b/jme3-core/src/plugins/java/com/jme3/material/plugins/J3MLoader.java @@ -63,7 +63,7 @@ public class J3MLoader implements AssetLoader { // private ErrorLogger errors; private ShaderNodeLoaderDelegate nodesLoaderDelegate; boolean isUseNodes = false; - + private AssetManager assetManager; private AssetKey key; @@ -168,7 +168,7 @@ public class J3MLoader implements AssetLoader { if (tex != null){ if (repeat){ tex.setWrap(WrapMode.Repeat); - } + } }else{ tex = new Texture2D(PlaceholderAssets.getPlaceholderImage(assetManager)); if (repeat){ @@ -176,7 +176,7 @@ public class J3MLoader implements AssetLoader { } tex.setKey(texKey); tex.setName(texKey.getName()); - } + } return tex; }else{ String[] split = value.trim().split(whitespacePattern); @@ -222,15 +222,15 @@ public class J3MLoader implements AssetLoader { } } } - - // [ "(" ")" ] [-LINEAR] [ ":" ] + + // [ "(" ")" ] [-LINEAR] [ ":" ] private void readParam(String statement) throws IOException{ String name; String defaultVal = null; ColorSpace colorSpace = null; - + String[] split = statement.split(":"); - + // Parse default val if (split.length == 1){ // Doesn't contain default value @@ -239,14 +239,14 @@ public class J3MLoader implements AssetLoader { throw new IOException("Parameter statement syntax incorrect"); } statement = split[0].trim(); - defaultVal = split[1].trim(); + defaultVal = split[1].trim(); } - + if (statement.endsWith("-LINEAR")) { colorSpace = ColorSpace.Linear; statement = statement.substring(0, statement.length() - "-LINEAR".length()); } - + // Parse ffbinding int startParen = statement.indexOf("("); if (startParen != -1){ @@ -256,32 +256,32 @@ public class J3MLoader implements AssetLoader { // don't care about bindingStr statement = statement.substring(0, startParen); } - + // Parse type + name split = statement.split(whitespacePattern); if (split.length != 2){ throw new IOException("Parameter statement syntax incorrect"); } - + VarType type; if (split[0].equals("Color")){ type = VarType.Vector4; }else{ type = VarType.valueOf(split[0]); } - + name = split[1]; - + Object defaultValObj = null; - if (defaultVal != null){ + if (defaultVal != null){ defaultValObj = readValue(type, defaultVal); } if(type.isTextureType()){ - materialDef.addMaterialParamTexture(type, name, colorSpace); + materialDef.addMaterialParamTexture(type, name, colorSpace); }else{ materialDef.addMaterialParam(type, name, defaultValObj); } - + } private void readValueParam(String statement) throws IOException{ @@ -376,7 +376,7 @@ public class J3MLoader implements AssetLoader { technique.setRenderState(renderState); renderState = null; } - + private void readForcedRenderState(List renderStates) throws IOException{ renderState = new RenderState(); for (Statement statement : renderStates){ @@ -385,7 +385,7 @@ public class J3MLoader implements AssetLoader { technique.setForcedRenderState(renderState); renderState = null; } - + // [ ":" ] private void readDefine(String statement) throws IOException{ String[] split = statement.split(":"); @@ -405,9 +405,9 @@ public class J3MLoader implements AssetLoader { } } - + private void readTechniqueStatement(Statement statement) throws IOException{ - String[] split = statement.getLine().split("[ \\{]"); + String[] split = statement.getLine().split("[ \\{]"); if (split[0].equals("VertexShader") || split[0].equals("FragmentShader") || split[0].equals("GeometryShader") || @@ -420,12 +420,12 @@ public class J3MLoader implements AssetLoader { readShadowMode(statement.getLine()); }else if (split[0].equals("WorldParameters")){ readWorldParams(statement.getContents()); - }else if (split[0].equals("RenderState")){ + }else if (split[0].equals("RenderState")){ readRenderState(statement.getContents()); - }else if (split[0].equals("ForcedRenderState")){ + }else if (split[0].equals("ForcedRenderState")){ readForcedRenderState(statement.getContents()); - }else if (split[0].equals("Defines")){ - readDefines(statement.getContents()); + }else if (split[0].equals("Defines")){ + readDefines(statement.getContents()); } else if (split[0].equals("ShaderNodesDefinitions")) { initNodesLoader(); if (isUseNodes) { @@ -438,14 +438,16 @@ public class J3MLoader implements AssetLoader { } } else if (split[0].equals("FragmentShaderNodes")) { initNodesLoader(); - if (isUseNodes) { + if (isUseNodes) { nodesLoaderDelegate.readFragmentShaderNodes(statement.getContents()); } + } else if (split[0].equals("NoRender")) { + technique.setNoRender(true); } else { throw new MatParseException(null, split[0], statement); } } - + private void readTransparentStatement(String statement) throws IOException{ String[] split = statement.split(whitespacePattern); if (split.length != 2){ @@ -465,11 +467,11 @@ public class J3MLoader implements AssetLoader { } else { throw new IOException("Technique statement syntax incorrect"); } - + for (Statement statement : techStat.getContents()){ readTechniqueStatement(statement); } - + if(isUseNodes){ nodesLoaderDelegate.computeConditions(); //used for caching later, the shader here is not a file. @@ -479,14 +481,14 @@ public class J3MLoader implements AssetLoader { if (shaderName.containsKey(Shader.ShaderType.Vertex) && shaderName.containsKey(Shader.ShaderType.Fragment)) { technique.setShaderFile(shaderName, shaderLanguage); } - + materialDef.addTechniqueDef(technique); technique = null; shaderLanguage.clear(); shaderName.clear(); } - private void loadFromRoot(List roots) throws IOException{ + private void loadFromRoot(List roots) throws IOException{ if (roots.size() == 2){ Statement exception = roots.get(0); String line = exception.getLine(); @@ -498,7 +500,7 @@ public class J3MLoader implements AssetLoader { }else if (roots.size() != 1){ throw new IOException("Too many roots in J3M/J3MD file"); } - + boolean extending = false; Statement materialStat = roots.get(0); String materialName = materialStat.getLine(); @@ -511,16 +513,16 @@ public class J3MLoader implements AssetLoader { }else{ throw new IOException("Specified file is not a Material file"); } - + String[] split = materialName.split(":", 2); - + if (materialName.equals("")){ - throw new MatParseException("Material name cannot be empty", materialStat); + throw new MatParseException("Material name cannot be empty", materialStat); } if (split.length == 2){ if (!extending){ - throw new MatParseException("Must use 'Material' when extending.", materialStat); + throw new MatParseException("Must use 'Material' when extending.", materialStat); } String extendedMat = split[1].trim(); @@ -535,15 +537,15 @@ public class J3MLoader implements AssetLoader { // material.setAssetName(fileName); }else if (split.length == 1){ if (extending){ - throw new MatParseException("Expected ':', got '{'", materialStat); + throw new MatParseException("Expected ':', got '{'", materialStat); } materialDef = new MaterialDef(assetManager, materialName); // NOTE: pass file name for defs so they can be loaded later materialDef.setAssetName(key.getName()); }else{ - throw new MatParseException("Cannot use colon in material name/path", materialStat); + throw new MatParseException("Cannot use colon in material name/path", materialStat); } - + for (Statement statement : materialStat.getContents()){ split = statement.getLine().split("[ \\{]"); String statType = split[0]; @@ -561,16 +563,16 @@ public class J3MLoader implements AssetLoader { }else if (statType.equals("MaterialParameters")){ readMaterialParams(statement.getContents()); }else{ - throw new MatParseException("Expected material statement, got '"+statType+"'", statement); + throw new MatParseException("Expected material statement, got '"+statType+"'", statement); } } } } - public Object load(AssetInfo info) throws IOException { + public Object load(AssetInfo info) throws IOException { this.assetManager = info.getManager(); - - InputStream in = info.openStream(); + + InputStream in = info.openStream(); try { key = info.getKey(); if (key.getExtension().equals("j3m") && !(key instanceof MaterialKey)) { @@ -584,7 +586,7 @@ public class J3MLoader implements AssetLoader { in.close(); } } - + if (material != null){ // material implementation return material; @@ -593,7 +595,7 @@ public class J3MLoader implements AssetLoader { return materialDef; } } - + public MaterialDef loadMaterialDef(List roots, AssetManager manager, AssetKey key) throws IOException { this.key = key; this.assetManager = manager; @@ -615,6 +617,6 @@ public class J3MLoader implements AssetLoader { nodesLoaderDelegate.setAssetManager(assetManager); } } - } + } } diff --git a/jme3-core/src/test/java/com/jme3/cinematic/CinematicTest.java b/jme3-core/src/test/java/com/jme3/cinematic/CinematicTest.java new file mode 100644 index 000000000..400dbaa9f --- /dev/null +++ b/jme3-core/src/test/java/com/jme3/cinematic/CinematicTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2009-2015 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.cinematic; + +import com.jme3.animation.AnimControl; +import com.jme3.animation.Animation; +import com.jme3.cinematic.events.AnimationEvent; +import com.jme3.scene.Node; +import org.junit.Test; + +/** + * + * @author davidB + */ +public class CinematicTest { + + /** + * No NPE or any exception when clear() a new Cinematic + */ + @Test + public void clearEmpty() { + Cinematic sut = new Cinematic(); + sut.clear(); + } + + /** + * No ClassCastException when clear() a Cinematic with AnimationEvent + */ + @Test + public void clearAnimationEvent() { + Cinematic sut = new Cinematic(); + Node model = new Node("model"); + AnimControl ac = new AnimControl(); + ac.addAnim(new Animation("animName", 1.0f)); + model.addControl(ac); + sut.enqueueCinematicEvent(new AnimationEvent(model, "animName")); + sut.initialize(null, null); + sut.clear(); + } +} diff --git a/jme3-core/src/tools/java/jme3tools/optimize/GeometryBatchFactory.java b/jme3-core/src/tools/java/jme3tools/optimize/GeometryBatchFactory.java index a7668dc56..9904b3283 100644 --- a/jme3-core/src/tools/java/jme3tools/optimize/GeometryBatchFactory.java +++ b/jme3-core/src/tools/java/jme3tools/optimize/GeometryBatchFactory.java @@ -16,6 +16,7 @@ import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.nio.ShortBuffer; import java.util.*; +import java.util.logging.Level; import java.util.logging.Logger; public class GeometryBatchFactory { @@ -453,4 +454,93 @@ public class GeometryBatchFactory { mergeGeometries(geoms, outMesh); printMesh(outMesh); } + + /** + * Options to align the buffers of geometries' meshes of a sub graph + * + */ + public static enum AlignOption { + + /** + * Will remove the buffers of a type that is not on all the geometries + */ + RemoveUnalignedBuffers, + /** + * Will create missing buffers and pad with dummy data + */ + CreateMissingBuffers + } + + /** + * Will ensure that all the geometries' meshes of the n sub graph have the + * same types of buffers + * @param n the node to gather geometries from + * @param option the align options + * @see AlignOption + * + * Very experimental for now. + */ + public static void alignBuffers(Node n, AlignOption option) { + List geoms = new ArrayList(); + gatherGeoms(n, geoms); + + //gather buffer types + Map types = new EnumMap(VertexBuffer.Type.class); + Map typesCount = new EnumMap(VertexBuffer.Type.class); + for (Geometry geom : geoms) { + for (VertexBuffer buffer : geom.getMesh().getBufferList()) { + if (types.get(buffer.getBufferType()) == null) { + types.put(buffer.getBufferType(), buffer); + logger.log(Level.FINE, buffer.getBufferType().toString()); + } + Integer count = typesCount.get(buffer.getBufferType()); + if (count == null) { + count = 0; + } + count++; + typesCount.put(buffer.getBufferType(), count); + } + } + + switch (option) { + case RemoveUnalignedBuffers: + for (Geometry geom : geoms) { + + for (VertexBuffer buffer : geom.getMesh().getBufferList()) { + Integer count = typesCount.get(buffer.getBufferType()); + if (count != null && count < geoms.size()) { + geom.getMesh().clearBuffer(buffer.getBufferType()); + logger.log(Level.FINE, "removing {0} from {1}", new Object[]{buffer.getBufferType(), geom.getName()}); + + } + } + } + break; + case CreateMissingBuffers: + for (Geometry geom : geoms) { + for (VertexBuffer.Type type : types.keySet()) { + if (geom.getMesh().getBuffer(type) == null) { + VertexBuffer vb = new VertexBuffer(type); + Buffer b; + switch (type) { + case Index: + case BoneIndex: + case HWBoneIndex: + b = BufferUtils.createIntBuffer(geom.getMesh().getVertexCount() * types.get(type).getNumComponents()); + break; + case InterleavedData: + b = BufferUtils.createByteBuffer(geom.getMesh().getVertexCount() * types.get(type).getNumComponents()); + break; + default: + b = BufferUtils.createFloatBuffer(geom.getMesh().getVertexCount() * types.get(type).getNumComponents()); + } + vb.setupData(types.get(type).getUsage(), types.get(type).getNumComponents(), types.get(type).getFormat(), b); + geom.getMesh().setBuffer(vb); + logger.log(Level.FINE, "geom {0} misses buffer {1}. Creating", new Object[]{geom.getName(), type}); + } + } + } + break; + } + } } diff --git a/jme3-examples/build.gradle b/jme3-examples/build.gradle index 186a6bc2d..09e71997e 100644 --- a/jme3-examples/build.gradle +++ b/jme3-examples/build.gradle @@ -6,7 +6,10 @@ if (!hasProperty('mainClass')) { task run(dependsOn: 'build', type:JavaExec) { main = mainClass - classpath = sourceSets.main.runtimeClasspath + classpath = sourceSets.main.runtimeClasspath + if( assertions == "true" ){ + enableAssertions = true; + } } dependencies { @@ -18,7 +21,7 @@ dependencies { // compile project(':jme3-bullet-native') compile project(':jme3-jbullet') compile project(':jme3-jogg') -// compile project(':jme3-jogl') + compile project(':jme3-jogl') compile project(':jme3-lwjgl') compile project(':jme3-networking') compile project(':jme3-niftygui') @@ -48,7 +51,9 @@ jar.doFirst{ } } -task dist (dependsOn: ['build', ':jme3-jogl:jar', ':jme3-bullet:jar', ':jme3-android:jar']) << { +task dist (dependsOn: ['build', ':jme3-jogl:jar', ':jme3-bullet:jar', ':jme3-android:jar', \ + ':jme3-android-native:jar', ':jme3-bullet-native-android:jar', \ + ':jme3-bullet-native:jar']) << { // Copy all dependencies to ../dist/lib, remove versions from jar files configurations.compile.resolvedConfiguration.resolvedArtifacts.each { artifact -> copy { @@ -94,23 +99,23 @@ task dist (dependsOn: ['build', ':jme3-jogl:jar', ':jme3-bullet:jar', ':jme3-and copy { from project(':jme3-bullet-native').jar.archivePath into '../dist/opt/native-bullet' - rename {"jme3-bullet-natives.jar"} + rename {project(':jme3-bullet-native').name+".jar"} } // Copy android packages, remove version copy { from project(':jme3-android').jar.archivePath into '../dist/opt/android' - rename { project(':jme3-android').name + ".jar" } + rename {project(':jme3-android').name+".jar"} } copy { from project(':jme3-android-native').jar.archivePath into '../dist/opt/android' - rename { project(':jme3-android-native').name + ".jar" } + rename {project(':jme3-android-native').name+".jar"} } copy { from project(':jme3-bullet-native-android').jar.archivePath into '../dist/opt/native-bullet' - rename {"jme3-bullet-native-android.jar"} + rename {project(':jme3-bullet-native-android').name+".jar"} } } diff --git a/jme3-examples/gradle.properties b/jme3-examples/gradle.properties new file mode 100644 index 000000000..6f0993120 --- /dev/null +++ b/jme3-examples/gradle.properties @@ -0,0 +1,5 @@ +# When running this project we don't need javadoc to be built. +buildJavaDoc = false + +# We want assertions, because this is the test project. +assertions = true diff --git a/jme3-examples/src/main/java/jme3test/effect/TestParticleExportingCloning.java b/jme3-examples/src/main/java/jme3test/effect/TestParticleExportingCloning.java index 552287f75..d245de23f 100644 --- a/jme3-examples/src/main/java/jme3test/effect/TestParticleExportingCloning.java +++ b/jme3-examples/src/main/java/jme3test/effect/TestParticleExportingCloning.java @@ -69,26 +69,9 @@ public class TestParticleExportingCloning extends SimpleApplication { rootNode.attachChild(emit); rootNode.attachChild(emit2); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - try { - BinaryExporter.getInstance().save(emit, out); - - BinaryImporter imp = new BinaryImporter(); - imp.setAssetManager(assetManager); - ParticleEmitter emit3 = (ParticleEmitter) imp.load(out.toByteArray()); - - emit3.move(-3, 0, 0); - rootNode.attachChild(emit3); - } catch (IOException ex) { - ex.printStackTrace(); - } - - // Camera cam2 = cam.clone(); - // cam.setViewPortTop(0.5f); - // cam2.setViewPortBottom(0.5f); - // ViewPort vp = renderManager.createMainView("SecondView", cam2); - // viewPort.setClearEnabled(false); - // vp.attachScene(rootNode); + ParticleEmitter emit3 = BinaryExporter.saveAndLoad(assetManager, emit); + emit3.move(-3, 0, 0); + rootNode.attachChild(emit3); } } diff --git a/jme3-examples/src/main/java/jme3test/material/TestParallax.java b/jme3-examples/src/main/java/jme3test/material/TestParallax.java index 37b5e09b0..f5af57f1f 100644 --- a/jme3-examples/src/main/java/jme3test/material/TestParallax.java +++ b/jme3-examples/src/main/java/jme3test/material/TestParallax.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2012 jMonkeyEngine + * Copyright (c) 2009-2015 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -39,20 +39,17 @@ import com.jme3.input.controls.KeyTrigger; import com.jme3.light.DirectionalLight; import com.jme3.material.Material; import com.jme3.math.*; -import com.jme3.post.FilterPostProcessor; -import com.jme3.post.filters.FXAAFilter; import com.jme3.renderer.queue.RenderQueue.ShadowMode; import com.jme3.scene.Geometry; import com.jme3.scene.Node; import com.jme3.scene.Spatial; import com.jme3.scene.shape.Quad; -import com.jme3.texture.Texture.WrapMode; import com.jme3.util.SkyFactory; import com.jme3.util.TangentBinormalGenerator; public class TestParallax extends SimpleApplication { - private Vector3f lightDir = new Vector3f(-1, -1, .5f).normalizeLocal(); + private final Vector3f lightDir = new Vector3f(-1, -1, .5f).normalizeLocal(); public static void main(String[] args) { TestParallax app = new TestParallax(); @@ -60,7 +57,7 @@ public class TestParallax extends SimpleApplication { } public void setupSkyBox() { - rootNode.attachChild(SkyFactory.createSky(assetManager, "Scenes/Beach/FullskiesSunset0068.dds", false)); + rootNode.attachChild(SkyFactory.createSky(assetManager, "Scenes/Beach/FullskiesSunset0068.dds", SkyFactory.EnvMapType.CubeMap)); } DirectionalLight dl; @@ -75,12 +72,7 @@ public class TestParallax extends SimpleApplication { public void setupFloor() { mat = assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall2.j3m"); - mat.getTextureParam("DiffuseMap").getTextureValue().setWrap(WrapMode.Repeat); - mat.getTextureParam("NormalMap").getTextureValue().setWrap(WrapMode.Repeat); - - // Node floorGeom = (Node) assetManager.loadAsset("Models/WaterTest/WaterTest.mesh.xml"); - //Geometry g = ((Geometry) floorGeom.getChild(0)); - //g.getMesh().scaleTextureCoordinates(new Vector2f(10, 10)); + //mat = assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m"); Node floorGeom = new Node("floorGeom"); Quad q = new Quad(100, 100); @@ -100,9 +92,9 @@ public class TestParallax extends SimpleApplication { public void setupSignpost() { Spatial signpost = assetManager.loadModel("Models/Sign Post/Sign Post.mesh.xml"); - Material mat = assetManager.loadMaterial("Models/Sign Post/Sign Post.j3m"); + Material matSp = assetManager.loadMaterial("Models/Sign Post/Sign Post.j3m"); TangentBinormalGenerator.generate(signpost); - signpost.setMaterial(mat); + signpost.setMaterial(matSp); signpost.rotate(0, FastMath.HALF_PI, 0); signpost.setLocalTranslation(12, 23.5f, 30); signpost.setLocalScale(4); @@ -116,7 +108,6 @@ public class TestParallax extends SimpleApplication { cam.setRotation(new Quaternion(0.05173137f, 0.92363626f, -0.13454558f, 0.35513034f)); flyCam.setMoveSpeed(30); - setupLighting(); setupSkyBox(); setupFloor(); @@ -124,13 +115,14 @@ public class TestParallax extends SimpleApplication { inputManager.addListener(new AnalogListener() { + @Override public void onAnalog(String name, float value, float tpf) { if ("heightUP".equals(name)) { - parallaxHeigh += 0.0001; + parallaxHeigh += 0.01; mat.setFloat("ParallaxHeight", parallaxHeigh); } if ("heightDown".equals(name)) { - parallaxHeigh -= 0.0001; + parallaxHeigh -= 0.01; parallaxHeigh = Math.max(parallaxHeigh, 0); mat.setFloat("ParallaxHeight", parallaxHeigh); } @@ -142,6 +134,7 @@ public class TestParallax extends SimpleApplication { inputManager.addListener(new ActionListener() { + @Override public void onAction(String name, boolean isPressed, float tpf) { if (isPressed && "toggleSteep".equals(name)) { steep = !steep; diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestModelExportingCloning.java b/jme3-examples/src/main/java/jme3test/model/anim/TestModelExportingCloning.java new file mode 100644 index 000000000..de162907d --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/model/anim/TestModelExportingCloning.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2009-2015 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 jme3test.model.anim; + +import com.jme3.animation.AnimChannel; +import com.jme3.animation.AnimControl; +import com.jme3.app.SimpleApplication; +import com.jme3.export.binary.BinaryExporter; +import com.jme3.light.DirectionalLight; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; +import com.jme3.scene.Spatial; + +public class TestModelExportingCloning extends SimpleApplication { + + public static void main(String[] args) { + TestModelExportingCloning app = new TestModelExportingCloning(); + app.start(); + } + + @Override + public void simpleInitApp() { + cam.setLocation(new Vector3f(10f, 3f, 40f)); + cam.lookAtDirection(Vector3f.UNIT_Z.negate(), Vector3f.UNIT_Y); + + DirectionalLight dl = new DirectionalLight(); + dl.setDirection(new Vector3f(-0.1f, -0.7f, -1).normalizeLocal()); + dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f)); + rootNode.addLight(dl); + + AnimControl control; + AnimChannel channel; + + Spatial originalModel = assetManager.loadModel("Models/Oto/Oto.mesh.xml"); + control = originalModel.getControl(AnimControl.class); + channel = control.createChannel(); + channel.setAnim("Walk"); + rootNode.attachChild(originalModel); + + Spatial clonedModel = originalModel.clone(); + clonedModel.move(10, 0, 0); + control = clonedModel.getControl(AnimControl.class); + channel = control.createChannel(); + channel.setAnim("push"); + rootNode.attachChild(clonedModel); + + Spatial exportedModel = BinaryExporter.saveAndLoad(assetManager, originalModel); + exportedModel.move(20, 0, 0); + control = exportedModel.getControl(AnimControl.class); + channel = control.createChannel(); + channel.setAnim("pull"); + rootNode.attachChild(exportedModel); + } +} diff --git a/jme3-examples/src/main/java/jme3test/stress/TestShaderNodesStress.java b/jme3-examples/src/main/java/jme3test/stress/TestShaderNodesStress.java new file mode 100644 index 000000000..3364f5feb --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/stress/TestShaderNodesStress.java @@ -0,0 +1,102 @@ +package jme3test.stress; + +import com.jme3.app.BasicProfilerState; +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.profile.AppProfiler; +import com.jme3.profile.AppStep; +import com.jme3.profile.VpStep; +import com.jme3.renderer.ViewPort; +import com.jme3.renderer.queue.RenderQueue; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Quad; +import com.jme3.texture.Texture; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class TestShaderNodesStress extends SimpleApplication { + + public static void main(String[] args) { + TestShaderNodesStress app = new TestShaderNodesStress(); + app.start(); + } + + @Override + public void simpleInitApp() { + + Quad q = new Quad(1, 1); + Geometry g = new Geometry("quad", q); + g.setLocalTranslation(-500, -500, 0); + g.setLocalScale(1000); + + rootNode.attachChild(g); + cam.setLocation(new Vector3f(0.0f, 0.0f, 0.40647888f)); + cam.setRotation(new Quaternion(0.0f, 1.0f, 0.0f, 0.0f)); + + Texture tex = assetManager.loadTexture("Interface/Logo/Monkey.jpg"); + + Material mat = new Material(assetManager, "Common/MatDefs/Misc/UnshadedNodes.j3md"); + //Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + + mat.setColor("Color", ColorRGBA.Yellow); + mat.setTexture("ColorMap", tex); + g.setMaterial(mat); + //place the geoms in the transparent bucket so that they are rendered back to front for maximum overdraw + g.setQueueBucket(RenderQueue.Bucket.Transparent); + + for (int i = 0; i < 1000; i++) { + Geometry cl = g.clone(false); + cl.move(0, 0, -(i + 1)); + rootNode.attachChild(cl); + } + + flyCam.setMoveSpeed(20); + Logger.getLogger("com.jme3").setLevel(Level.WARNING); + + this.setAppProfiler(new Profiler()); + + } + + private class Profiler implements AppProfiler { + + private long startTime; + private long updateTime; + private long renderTime; + private long sum; + private int nbFrames; + + @Override + public void appStep(AppStep step) { + + switch (step) { + case BeginFrame: + startTime = System.nanoTime(); + break; + case RenderFrame: + updateTime = System.nanoTime(); + // System.err.println("Update time : " + (updateTime - startTime)); + break; + case EndFrame: + nbFrames++; + if (nbFrames >= 150) { + renderTime = System.nanoTime(); + sum += renderTime - updateTime; + System.err.println("render time : " + (renderTime - updateTime)); + System.err.println("Average render time : " + ((float)sum / (float)(nbFrames-150))); + } + break; + + } + + } + + @Override + public void vpStep(VpStep step, ViewPort vp, RenderQueue.Bucket bucket) { + + } + + } +} diff --git a/jme3-examples/src/main/resources/jme3test/texture/UnshadedArray.frag b/jme3-examples/src/main/resources/jme3test/texture/UnshadedArray.frag index 4cd92cff9..355cf6092 100644 --- a/jme3-examples/src/main/resources/jme3test/texture/UnshadedArray.frag +++ b/jme3-examples/src/main/resources/jme3test/texture/UnshadedArray.frag @@ -1,5 +1,5 @@ #extension GL_EXT_texture_array : enable -#extension GL_EXT_gpu_shader4 : enable +// #extension GL_EXT_gpu_shader4 : enable uniform vec4 m_Color; @@ -8,7 +8,7 @@ uniform vec4 m_Color; #endif #ifdef HAS_COLORMAP - #if !defined(GL_EXT_texture_array) && !defined(GL_EXT_gpu_shader4) + #if !defined(GL_EXT_texture_array) #error Texture arrays are not supported, but required for this shader. #endif diff --git a/jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGL.java b/jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGL.java new file mode 100644 index 000000000..6f335e960 --- /dev/null +++ b/jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGL.java @@ -0,0 +1,594 @@ +package com.jme3.renderer.jogl; + +import com.jme3.renderer.RendererException; +import com.jme3.renderer.opengl.GL; +import com.jme3.renderer.opengl.GL2; +import com.jme3.renderer.opengl.GL3; + +import java.nio.Buffer; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.ShortBuffer; + +import com.jme3.renderer.opengl.GL4; +import com.jogamp.opengl.GLContext; + +public class JoglGL implements GL, GL2, GL3, GL4 { + + private static int getLimitBytes(ByteBuffer buffer) { + checkLimit(buffer); + return buffer.limit(); + } + + private static int getLimitBytes(ShortBuffer buffer) { + checkLimit(buffer); + return buffer.limit() * 2; + } + + private static int getLimitBytes(FloatBuffer buffer) { + checkLimit(buffer); + return buffer.limit() * 4; + } + + private static int getLimitCount(Buffer buffer, int elementSize) { + checkLimit(buffer); + return buffer.limit() / elementSize; + } + + private static void checkLimit(Buffer buffer) { + if (buffer == null) { + return; + } + if (buffer.limit() == 0) { + throw new RendererException("Attempting to upload empty buffer (limit = 0), that's an error"); + } + if (buffer.remaining() == 0) { + throw new RendererException("Attempting to upload empty buffer (remaining = 0), that's an error"); + } + } + + @Override + public void resetStats() { + } + + @Override + public void glActiveTexture(int param1) { + GLContext.getCurrentGL().glActiveTexture(param1); + } + + @Override + public void glAlphaFunc(int param1, float param2) { + GLContext.getCurrentGL().getGL2ES1().glAlphaFunc(param1, param2); + } + + @Override + public void glAttachShader(int param1, int param2) { + GLContext.getCurrentGL().getGL2ES2().glAttachShader(param1, param2); + } + + @Override + public void glBindBuffer(int param1, int param2) { + GLContext.getCurrentGL().glBindBuffer(param1, param2); + } + + @Override + public void glBindTexture(int param1, int param2) { + GLContext.getCurrentGL().glBindTexture(param1, param2); + } + + @Override + public void glBlendFunc(int param1, int param2) { + GLContext.getCurrentGL().glBlendFunc(param1, param2); + } + + @Override + public void glBufferData(int param1, long param2, int param3) { + GLContext.getCurrentGL().glBufferData(param1, param2, null, param3); + } + + @Override + public void glBufferData(int param1, FloatBuffer param2, int param3) { + checkLimit(param2); + GLContext.getCurrentGL().glBufferData(param1, getLimitBytes(param2), param2, param3); + } + + @Override + public void glBufferData(int param1, ShortBuffer param2, int param3) { + checkLimit(param2); + GLContext.getCurrentGL().glBufferData(param1, getLimitBytes(param2), param2, param3); + } + + @Override + public void glBufferData(int param1, ByteBuffer param2, int param3) { + checkLimit(param2); + GLContext.getCurrentGL().glBufferData(param1, getLimitBytes(param2), param2, param3); + } + + @Override + public void glBufferSubData(int param1, long param2, FloatBuffer param3) { + checkLimit(param3); + GLContext.getCurrentGL().glBufferSubData(param1, param2, getLimitBytes(param3), param3); + } + + @Override + public void glBufferSubData(int param1, long param2, ShortBuffer param3) { + checkLimit(param3); + GLContext.getCurrentGL().glBufferSubData(param1, param2, getLimitBytes(param3), param3); + } + + @Override + public void glBufferSubData(int param1, long param2, ByteBuffer param3) { + checkLimit(param3); + GLContext.getCurrentGL().glBufferSubData(param1, param2, getLimitBytes(param3), param3); + } + + @Override + public void glClear(int param1) { + GLContext.getCurrentGL().glClear(param1); + } + + @Override + public void glClearColor(float param1, float param2, float param3, float param4) { + GLContext.getCurrentGL().glClearColor(param1, param2, param3, param4); + } + + @Override + public void glColorMask(boolean param1, boolean param2, boolean param3, boolean param4) { + GLContext.getCurrentGL().glColorMask(param1, param2, param3, param4); + } + + @Override + public void glCompileShader(int param1) { + GLContext.getCurrentGL().getGL2ES2().glCompileShader(param1); + } + + @Override + public void glCompressedTexImage2D(int param1, int param2, int param3, int param4, int param5, int param6, ByteBuffer param7) { + checkLimit(param7); + GLContext.getCurrentGL().glCompressedTexImage2D(param1, param2, param3, param4, param5, param6, getLimitBytes(param7), param7); + } + + @Override + public void glCompressedTexImage3D(int param1, int param2, int param3, int param4, int param5, int param6, int param7, ByteBuffer param8) { + checkLimit(param8); + GLContext.getCurrentGL().getGL2ES2().glCompressedTexImage3D(param1, param2, param3, param4, param5, param6, param7, getLimitBytes(param8), param8); + } + + @Override + public void glCompressedTexSubImage2D(int param1, int param2, int param3, int param4, int param5, int param6, int param7, ByteBuffer param8) { + checkLimit(param8); + GLContext.getCurrentGL().glCompressedTexSubImage2D(param1, param2, param3, param4, param5, param6, param7, getLimitBytes(param8), param8); + } + + @Override + public void glCompressedTexSubImage3D(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, ByteBuffer param10) { + checkLimit(param10); + GLContext.getCurrentGL().getGL2ES2().glCompressedTexSubImage3D(param1, param2, param3, param4, param5, param6, param7, param8, param9, getLimitBytes(param10), param10); + } + + @Override + public int glCreateProgram() { + return GLContext.getCurrentGL().getGL2ES2().glCreateProgram(); + } + + @Override + public int glCreateShader(int param1) { + return GLContext.getCurrentGL().getGL2ES2().glCreateShader(param1); + } + + @Override + public void glCullFace(int param1) { + GLContext.getCurrentGL().glCullFace(param1); + } + + @Override + public void glDeleteBuffers(IntBuffer param1) { + checkLimit(param1); + GLContext.getCurrentGL().glDeleteBuffers(param1.limit(), param1); + } + + @Override + public void glDeleteProgram(int param1) { + GLContext.getCurrentGL().getGL2ES2().glDeleteProgram(param1); + } + + @Override + public void glDeleteShader(int param1) { + GLContext.getCurrentGL().getGL2ES2().glDeleteShader(param1); + } + + @Override + public void glDeleteTextures(IntBuffer param1) { + checkLimit(param1); + GLContext.getCurrentGL().glDeleteTextures(param1.limit() ,param1); + } + + @Override + public void glDepthFunc(int param1) { + GLContext.getCurrentGL().glDepthFunc(param1); + } + + @Override + public void glDepthMask(boolean param1) { + GLContext.getCurrentGL().glDepthMask(param1); + } + + @Override + public void glDepthRange(double param1, double param2) { + GLContext.getCurrentGL().glDepthRange(param1, param2); + } + + @Override + public void glDetachShader(int param1, int param2) { + GLContext.getCurrentGL().getGL2ES2().glDetachShader(param1, param2); + } + + @Override + public void glDisable(int param1) { + GLContext.getCurrentGL().glDisable(param1); + } + + @Override + public void glDisableVertexAttribArray(int param1) { + GLContext.getCurrentGL().getGL2ES2().glDisableVertexAttribArray(param1); + } + + @Override + public void glDrawArrays(int param1, int param2, int param3) { + GLContext.getCurrentGL().glDrawArrays(param1, param2, param3); + } + + @Override + public void glDrawBuffer(int param1) { + GLContext.getCurrentGL().getGL2GL3().glDrawBuffer(param1); + } + + @Override + public void glDrawRangeElements(int param1, int param2, int param3, int param4, int param5, long param6) { + GLContext.getCurrentGL().getGL2ES3().glDrawRangeElements(param1, param2, param3, param4, param5, param6); + } + + @Override + public void glEnable(int param1) { + GLContext.getCurrentGL().glEnable(param1); + } + + @Override + public void glEnableVertexAttribArray(int param1) { + GLContext.getCurrentGL().getGL2ES2().glEnableVertexAttribArray(param1); + } + + @Override + public void glGenBuffers(IntBuffer param1) { + checkLimit(param1); + GLContext.getCurrentGL().glGenBuffers(param1.limit(), param1); + } + + @Override + public void glGenTextures(IntBuffer param1) { + checkLimit(param1); + GLContext.getCurrentGL().glGenTextures(param1.limit(), param1); + } + + @Override + public void glGetBoolean(int param1, ByteBuffer param2) { + checkLimit(param2); + GLContext.getCurrentGL().glGetBooleanv(param1, param2); + } + + @Override + public void glGetBufferSubData(int target, long offset, ByteBuffer data) { + checkLimit(data); + GLContext.getCurrentGL().getGL2GL3().glGetBufferSubData(target, offset, getLimitBytes(data), data); + } + + @Override + public int glGetError() { + return GLContext.getCurrentGL().glGetError(); + } + + @Override + public void glGetInteger(int param1, IntBuffer param2) { + checkLimit(param2); + GLContext.getCurrentGL().glGetIntegerv(param1, param2); + } + + @Override + public void glGetProgram(int param1, int param2, IntBuffer param3) { + checkLimit(param3); + GLContext.getCurrentGL().getGL2ES2().glGetProgramiv(param1, param2, param3); + } + + @Override + public void glGetShader(int param1, int param2, IntBuffer param3) { + checkLimit(param3); + GLContext.getCurrentGL().getGL2ES2().glGetShaderiv(param1, param2, param3); + } + + @Override + public String glGetString(int param1) { + return GLContext.getCurrentGL().glGetString(param1); + } + + @Override + public String glGetString(int param1, int param2) { + return GLContext.getCurrentGL().getGL2ES3().glGetStringi(param1, param2); + } + + @Override + public boolean glIsEnabled(int param1) { + return GLContext.getCurrentGL().glIsEnabled(param1); + } + + @Override + public void glLineWidth(float param1) { + GLContext.getCurrentGL().glLineWidth(param1); + } + + @Override + public void glLinkProgram(int param1) { + GLContext.getCurrentGL().getGL2ES2().glLinkProgram(param1); + } + + @Override + public void glPixelStorei(int param1, int param2) { + GLContext.getCurrentGL().glPixelStorei(param1, param2); + } + + @Override + public void glPointSize(float param1) { + GLContext.getCurrentGL().getGL2ES1().glPointSize(param1); + } + + @Override + public void glPolygonMode(int param1, int param2) { + GLContext.getCurrentGL().getGL2().glPolygonMode(param1, param2); + } + + @Override + public void glPolygonOffset(float param1, float param2) { + GLContext.getCurrentGL().glPolygonOffset(param1, param2); + } + + @Override + public void glReadBuffer(int param1) { + GLContext.getCurrentGL().getGL2ES3().glReadBuffer(param1); + } + + @Override + public void glReadPixels(int param1, int param2, int param3, int param4, int param5, int param6, ByteBuffer param7) { + checkLimit(param7); + GLContext.getCurrentGL().glReadPixels(param1, param2, param3, param4, param5, param6, param7); + } + + @Override + public void glReadPixels(int param1, int param2, int param3, int param4, int param5, int param6, long param7) { + GLContext.getCurrentGL().glReadPixels(param1, param2, param3, param4, param5, param6, param7); + } + + @Override + public void glScissor(int param1, int param2, int param3, int param4) { + GLContext.getCurrentGL().glScissor(param1, param2, param3, param4); + } + + @Override + public void glStencilFuncSeparate(int param1, int param2, int param3, int param4) { + GLContext.getCurrentGL().getGL2ES2().glStencilFuncSeparate(param1, param2, param3, param4); + } + + @Override + public void glStencilOpSeparate(int param1, int param2, int param3, int param4) { + GLContext.getCurrentGL().getGL2ES2().glStencilOpSeparate(param1, param2, param3, param4); + } + + @Override + public void glTexImage2D(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, ByteBuffer param9) { + checkLimit(param9); + GLContext.getCurrentGL().glTexImage2D(param1, param2, param3, param4, param5, param6, param7, param8, param9); + } + + @Override + public void glTexImage3D(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, ByteBuffer param10) { + checkLimit(param10); + GLContext.getCurrentGL().getGL2ES2().glTexImage3D(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10); + } + + @Override + public void glTexParameterf(int param1, int param2, float param3) { + GLContext.getCurrentGL().glTexParameterf(param1, param2, param3); + } + + @Override + public void glTexParameteri(int param1, int param2, int param3) { + GLContext.getCurrentGL().glTexParameteri(param1, param2, param3); + } + + @Override + public void glTexSubImage2D(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, ByteBuffer param9) { + checkLimit(param9); + GLContext.getCurrentGL().glTexSubImage2D(param1, param2, param3, param4, param5, param6, param7, param8, param9); + } + + @Override + public void glTexSubImage3D(int param1, int param2, int param3, int param4, int param5, int param6, int param7, int param8, int param9, int param10, ByteBuffer param11) { + checkLimit(param11); + GLContext.getCurrentGL().getGL2ES2().glTexSubImage3D(param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11); + } + + @Override + public void glUniform1(int param1, FloatBuffer param2) { + checkLimit(param2); + GLContext.getCurrentGL().getGL2ES2().glUniform1fv(param1, getLimitCount(param2, 1), param2); + } + + @Override + public void glUniform1(int param1, IntBuffer param2) { + checkLimit(param2); + GLContext.getCurrentGL().getGL2ES2().glUniform1iv(param1, getLimitCount(param2, 1), param2); + } + + @Override + public void glUniform1f(int param1, float param2) { + GLContext.getCurrentGL().getGL2ES2().glUniform1f(param1, param2); + } + + @Override + public void glUniform1i(int param1, int param2) { + GLContext.getCurrentGL().getGL2ES2().glUniform1i(param1, param2); + } + + @Override + public void glUniform2(int param1, IntBuffer param2) { + checkLimit(param2); + GLContext.getCurrentGL().getGL2ES2().glUniform2iv(param1, getLimitCount(param2, 2), param2); + } + + @Override + public void glUniform2(int param1, FloatBuffer param2) { + checkLimit(param2); + GLContext.getCurrentGL().getGL2ES2().glUniform2fv(param1, getLimitCount(param2, 2), param2); + } + + @Override + public void glUniform2f(int param1, float param2, float param3) { + GLContext.getCurrentGL().getGL2ES2().glUniform2f(param1, param2, param3); + } + + @Override + public void glUniform3(int param1, IntBuffer param2) { + checkLimit(param2); + GLContext.getCurrentGL().getGL2ES2().glUniform3iv(param1, getLimitCount(param2, 3), param2); + } + + @Override + public void glUniform3(int param1, FloatBuffer param2) { + checkLimit(param2); + GLContext.getCurrentGL().getGL2ES2().glUniform3fv(param1, getLimitCount(param2, 3), param2); + } + + @Override + public void glUniform3f(int param1, float param2, float param3, float param4) { + GLContext.getCurrentGL().getGL2ES2().glUniform3f(param1, param2, param3, param4); + } + + @Override + public void glUniform4(int param1, FloatBuffer param2) { + checkLimit(param2); + GLContext.getCurrentGL().getGL2ES2().glUniform4fv(param1, getLimitCount(param2, 4), param2); + } + + @Override + public void glUniform4(int param1, IntBuffer param2) { + checkLimit(param2); + GLContext.getCurrentGL().getGL2ES2().glUniform4iv(param1, getLimitCount(param2, 4), param2); + } + + @Override + public void glUniform4f(int param1, float param2, float param3, float param4, float param5) { + GLContext.getCurrentGL().getGL2ES2().glUniform4f(param1, param2, param3, param4, param5); + } + + @Override + public void glUniformMatrix3(int param1, boolean param2, FloatBuffer param3) { + checkLimit(param3); + GLContext.getCurrentGL().getGL2ES2().glUniformMatrix3fv(param1, getLimitCount(param3, 3 * 3), param2, param3); + } + + @Override + public void glUniformMatrix4(int param1, boolean param2, FloatBuffer param3) { + checkLimit(param3); + GLContext.getCurrentGL().getGL2ES2().glUniformMatrix4fv(param1, getLimitCount(param3, 4 * 4), param2, param3); + } + + @Override + public void glUseProgram(int param1) { + GLContext.getCurrentGL().getGL2ES2().glUseProgram(param1); + } + + @Override + public void glVertexAttribPointer(int param1, int param2, int param3, boolean param4, int param5, long param6) { + GLContext.getCurrentGL().getGL2ES2().glVertexAttribPointer(param1, param2, param3, param4, param5, param6); + } + + @Override + public void glViewport(int param1, int param2, int param3, int param4) { + GLContext.getCurrentGL().glViewport(param1, param2, param3, param4); + } + + @Override + public int glGetAttribLocation(int param1, String param2) { + // FIXME: Does JOGL require null-terminated strings????? + return GLContext.getCurrentGL().getGL2ES2().glGetAttribLocation(param1, param2 + "\0"); + } + + @Override + public int glGetUniformLocation(int param1, String param2) { + // FIXME: Does JOGL require null-terminated strings???????? + return GLContext.getCurrentGL().getGL2ES2().glGetUniformLocation(param1, param2 + "\0"); + } + + @Override + public void glShaderSource(int param1, String[] param2, IntBuffer param3) { + checkLimit(param3); + GLContext.getCurrentGL().getGL2ES2().glShaderSource(param1, param2.length, param2, param3); + } + + @Override + public String glGetProgramInfoLog(int program, int maxSize) { + ByteBuffer buffer = ByteBuffer.allocateDirect(maxSize); + buffer.order(ByteOrder.nativeOrder()); + ByteBuffer tmp = ByteBuffer.allocateDirect(4); + tmp.order(ByteOrder.nativeOrder()); + IntBuffer intBuffer = tmp.asIntBuffer(); + + GLContext.getCurrentGL().getGL2ES2().glGetProgramInfoLog(program, maxSize, intBuffer, buffer); + int numBytes = intBuffer.get(0); + byte[] bytes = new byte[numBytes]; + buffer.get(bytes); + return new String(bytes); + } + + @Override + public String glGetShaderInfoLog(int shader, int maxSize) { + ByteBuffer buffer = ByteBuffer.allocateDirect(maxSize); + buffer.order(ByteOrder.nativeOrder()); + ByteBuffer tmp = ByteBuffer.allocateDirect(4); + tmp.order(ByteOrder.nativeOrder()); + IntBuffer intBuffer = tmp.asIntBuffer(); + + GLContext.getCurrentGL().getGL2ES2().glGetShaderInfoLog(shader, maxSize, intBuffer, buffer); + int numBytes = intBuffer.get(0); + byte[] bytes = new byte[numBytes]; + buffer.get(bytes); + return new String(bytes); + } + + @Override + public void glBindFragDataLocation(int param1, int param2, String param3) { + GLContext.getCurrentGL().getGL2GL3().glBindFragDataLocation(param1, param2, param3); + } + + @Override + public void glBindVertexArray(int param1) { + GLContext.getCurrentGL().getGL2ES3().glBindVertexArray(param1); + } + + @Override + public void glGenVertexArrays(IntBuffer param1) { + checkLimit(param1); + GLContext.getCurrentGL().getGL2ES3().glGenVertexArrays(param1.limit(), param1); + } + + @Override + public void glPatchParameter(int count) { + GLContext.getCurrentGL().getGL3().glPatchParameteri(com.jogamp.opengl.GL3.GL_PATCH_VERTICES, count); + } + + @Override + public void glDeleteVertexArrays(IntBuffer arrays) { + checkLimit(arrays); + GLContext.getCurrentGL().getGL2ES3().glDeleteVertexArrays(arrays.limit(), arrays); + } +} diff --git a/jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGLExt.java b/jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGLExt.java new file mode 100644 index 000000000..a87e8a035 --- /dev/null +++ b/jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGLExt.java @@ -0,0 +1,88 @@ +package com.jme3.renderer.jogl; + +import com.jme3.renderer.RendererException; +import com.jme3.renderer.opengl.GLExt; +import com.jogamp.opengl.GLContext; + +import java.nio.Buffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; + +public class JoglGLExt implements GLExt { + + private static int getLimitBytes(IntBuffer buffer) { + checkLimit(buffer); + return buffer.limit() * 4; + } + + private static void checkLimit(Buffer buffer) { + if (buffer == null) { + return; + } + if (buffer.limit() == 0) { + throw new RendererException("Attempting to upload empty buffer (limit = 0), that's an error"); + } + if (buffer.remaining() == 0) { + throw new RendererException("Attempting to upload empty buffer (remaining = 0), that's an error"); + } + } + + @Override + public void glBufferData(int target, IntBuffer data, int usage) { + checkLimit(data); + GLContext.getCurrentGL().glBufferData(target, getLimitBytes(data), data, usage); + } + + @Override + public void glBufferSubData(int target, long offset, IntBuffer data) { + checkLimit(data); + GLContext.getCurrentGL().glBufferSubData(target, getLimitBytes(data), offset, data); + } + + @Override + public void glDrawArraysInstancedARB(int mode, int first, int count, int primcount) { + GLContext.getCurrentGL().getGL2ES3().glDrawArraysInstanced(mode, first, count, primcount); + } + + @Override + public void glDrawBuffers(IntBuffer bufs) { + checkLimit(bufs); + GLContext.getCurrentGL().getGL2ES2().glDrawBuffers(bufs.limit(), bufs); + } + + @Override + public void glDrawElementsInstancedARB(int mode, int indices_count, int type, long indices_buffer_offset, int primcount) { + GLContext.getCurrentGL().getGL2ES3().glDrawElementsInstanced(mode, indices_count, type, indices_buffer_offset, primcount); + } + + @Override + public void glGetMultisample(int pname, int index, FloatBuffer val) { + checkLimit(val); + GLContext.getCurrentGL().getGL2ES2().glGetMultisamplefv(pname, index, val); + } + + @Override + public void glTexImage2DMultisample(int target, int samples, int internalformat, int width, int height, boolean fixedsamplelocations) { + GLContext.getCurrentGL().getGL2ES2().glTexImage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations); + } + + @Override + public void glVertexAttribDivisorARB(int index, int divisor) { + GLContext.getCurrentGL().getGL2ES3().glVertexAttribDivisor(index, divisor); + } + + @Override + public Object glFenceSync(int condition, int flags) { + return GLContext.getCurrentGL().getGL3ES3().glFenceSync(condition, flags); + } + + @Override + public int glClientWaitSync(Object sync, int flags, long timeout) { + return GLContext.getCurrentGL().getGL3ES3().glClientWaitSync(((Long) sync).longValue(), flags, timeout); + } + + @Override + public void glDeleteSync(Object sync) { + GLContext.getCurrentGL().getGL3ES3().glDeleteSync(((Long) sync).longValue()); + } +} diff --git a/jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGLFbo.java b/jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGLFbo.java new file mode 100644 index 000000000..2691d2e24 --- /dev/null +++ b/jme3-jogl/src/main/java/com/jme3/renderer/jogl/JoglGLFbo.java @@ -0,0 +1,97 @@ +package com.jme3.renderer.jogl; + +import com.jme3.renderer.RendererException; +import com.jme3.renderer.opengl.GLFbo; +import com.jogamp.opengl.GLContext; + +import java.nio.Buffer; +import java.nio.IntBuffer; + +/** + * Implements GLFbo + * + * @author Kirill Vainer + */ +public class JoglGLFbo implements GLFbo { + + private static void checkLimit(Buffer buffer) { + if (buffer == null) { + return; + } + if (buffer.limit() == 0) { + throw new RendererException("Attempting to upload empty buffer (limit = 0), that's an error"); + } + if (buffer.remaining() == 0) { + throw new RendererException("Attempting to upload empty buffer (remaining = 0), that's an error"); + } + } + + @Override + public void glBlitFramebufferEXT(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, int filter) { + GLContext.getCurrentGL().getGL2ES3().glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + } + + @Override + public void glRenderbufferStorageMultisampleEXT(int target, int samples, int internalformat, int width, int height) { + GLContext.getCurrentGL().glRenderbufferStorageMultisample(target, samples, internalformat, width, height); + } + + @Override + public void glBindFramebufferEXT(int param1, int param2) { + GLContext.getCurrentGL().glBindFramebuffer(param1, param2); + } + + @Override + public void glBindRenderbufferEXT(int param1, int param2) { + GLContext.getCurrentGL().glBindRenderbuffer(param1, param2); + } + + @Override + public int glCheckFramebufferStatusEXT(int param1) { + return GLContext.getCurrentGL().glCheckFramebufferStatus(param1); + } + + @Override + public void glDeleteFramebuffersEXT(IntBuffer param1) { + checkLimit(param1); + GLContext.getCurrentGL().glDeleteFramebuffers(param1.limit(), param1); + } + + @Override + public void glDeleteRenderbuffersEXT(IntBuffer param1) { + checkLimit(param1); + GLContext.getCurrentGL().glDeleteRenderbuffers(param1.limit(), param1); + } + + @Override + public void glFramebufferRenderbufferEXT(int param1, int param2, int param3, int param4) { + GLContext.getCurrentGL().glFramebufferRenderbuffer(param1, param2, param3, param4); + } + + @Override + public void glFramebufferTexture2DEXT(int param1, int param2, int param3, int param4, int param5) { + GLContext.getCurrentGL().glFramebufferTexture2D(param1, param2, param3, param4, param5); + } + + @Override + public void glGenFramebuffersEXT(IntBuffer param1) { + checkLimit(param1); + GLContext.getCurrentGL().glGenFramebuffers(param1.limit(), param1); + } + + @Override + public void glGenRenderbuffersEXT(IntBuffer param1) { + checkLimit(param1); + GLContext.getCurrentGL().glGenRenderbuffers(param1.limit(), param1); + } + + @Override + public void glGenerateMipmapEXT(int param1) { + GLContext.getCurrentGL().glGenerateMipmap(param1); + } + + @Override + public void glRenderbufferStorageEXT(int param1, int param2, int param3, int param4) { + GLContext.getCurrentGL().glRenderbufferStorage(param1, param2, param3, param4); + } +} diff --git a/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglAbstractDisplay.java b/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglAbstractDisplay.java index a7f7fbfd7..7b3f2e655 100644 --- a/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglAbstractDisplay.java +++ b/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglAbstractDisplay.java @@ -37,22 +37,15 @@ import com.jme3.input.MouseInput; import com.jme3.input.TouchInput; import com.jme3.input.awt.AwtKeyInput; import com.jme3.input.awt.AwtMouseInput; -import com.jme3.renderer.jogl.JoglRenderer; import com.jogamp.opengl.util.Animator; import com.jogamp.opengl.util.AnimatorBase; import com.jogamp.opengl.util.FPSAnimator; + import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Logger; -import com.jogamp.opengl.DebugGL2; -import com.jogamp.opengl.DebugGL3; -import com.jogamp.opengl.DebugGL3bc; -import com.jogamp.opengl.DebugGL4; -import com.jogamp.opengl.DebugGL4bc; -import com.jogamp.opengl.DebugGLES1; -import com.jogamp.opengl.DebugGLES2; -import com.jogamp.opengl.GL; + import com.jogamp.opengl.GLAutoDrawable; import com.jogamp.opengl.GLCapabilities; import com.jogamp.opengl.GLEventListener; @@ -124,50 +117,9 @@ public abstract class JoglAbstractDisplay extends JoglContext implements GLEvent canvas.setSize(settings.getWidth(), settings.getHeight()); canvas.setIgnoreRepaint(true); canvas.addGLEventListener(this); - - if (settings.getBoolean("GraphicsDebug")) { - canvas.invoke(false, new GLRunnable() { - public boolean run(GLAutoDrawable glad) { - GL gl = glad.getGL(); - if (gl.isGLES()) { - if (gl.isGLES1()) { - glad.setGL(new DebugGLES1(gl.getGLES1())); - } else { - if (gl.isGLES2()) { - glad.setGL(new DebugGLES2(gl.getGLES2())); - } else { - // TODO ES3 - } - } - } else { - if (gl.isGL4bc()) { - glad.setGL(new DebugGL4bc(gl.getGL4bc())); - } else { - if (gl.isGL4()) { - glad.setGL(new DebugGL4(gl.getGL4())); - } else { - if (gl.isGL3bc()) { - glad.setGL(new DebugGL3bc(gl.getGL3bc())); - } else { - if (gl.isGL3()) { - glad.setGL(new DebugGL3(gl.getGL3())); - } else { - if (gl.isGL2()) { - glad.setGL(new DebugGL2(gl.getGL2())); - } - } - } - } - } - } - return true; - } - }); - } - - renderer = new JoglRenderer(); - renderer.setMainFrameBufferSrgb(settings.getGammaCorrection()); + //FIXME not sure it is the best place to do that + renderable.set(true); } protected void startGLCanvas() { @@ -182,9 +134,6 @@ public abstract class JoglAbstractDisplay extends JoglContext implements GLEvent animator.start(); wasAnimating = true; - - //FIXME not sure it is the best place to do that - renderable.set(true); } protected void onCanvasAdded() { diff --git a/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglCanvas.java b/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglCanvas.java index 9a409b85e..b56eb43c1 100644 --- a/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglCanvas.java +++ b/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglCanvas.java @@ -41,28 +41,34 @@ public class JoglCanvas extends JoglAbstractDisplay implements JmeCanvasContext private static final Logger logger = Logger.getLogger(JoglCanvas.class.getName()); private int width, height; + private boolean runningFirstTime = true; public JoglCanvas(){ super(); initGLCanvas(); } - public Type getType() { + @Override + public Type getType() { return Type.Canvas; } - public void setTitle(String title) { + @Override + public void setTitle(String title) { } - public void restart() { + @Override + public void restart() { } - public void create(boolean waitFor){ + @Override + public void create(boolean waitFor){ if (waitFor) waitFor(true); } - public void destroy(boolean waitFor){ + @Override + public void destroy(boolean waitFor){ if (waitFor) waitFor(false); if (animator.isAnimating()) @@ -81,13 +87,20 @@ public class JoglCanvas extends JoglAbstractDisplay implements JmeCanvasContext startGLCanvas(); } - public void init(GLAutoDrawable drawable) { + @Override + public void init(GLAutoDrawable drawable) { canvas.requestFocus(); super.internalCreate(); logger.fine("Display created."); - renderer.initialize(); + // At this point, the OpenGL context is active. + if (runningFirstTime){ + // THIS is the part that creates the renderer. + // It must always be called, now that we have the pbuffer workaround. + initContextFirstTime(); + runningFirstTime = false; + } listener.initialize(); } @@ -97,7 +110,8 @@ public class JoglCanvas extends JoglAbstractDisplay implements JmeCanvasContext super.startGLCanvas(); } - public void display(GLAutoDrawable glad) { + @Override + public void display(GLAutoDrawable glad) { if (!created.get() && renderer != null){ listener.destroy(); logger.fine("Canvas destroyed."); @@ -129,7 +143,8 @@ public class JoglCanvas extends JoglAbstractDisplay implements JmeCanvasContext } - public Canvas getCanvas() { + @Override + public Canvas getCanvas() { return canvas; } diff --git a/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglContext.java b/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglContext.java index 5d687af8d..3b90877df 100644 --- a/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglContext.java +++ b/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglContext.java @@ -36,17 +36,33 @@ import com.jme3.input.JoyInput; import com.jme3.input.KeyInput; import com.jme3.input.MouseInput; import com.jme3.renderer.Renderer; +import com.jme3.renderer.RendererException; +import com.jme3.renderer.jogl.JoglGL; +import com.jme3.renderer.jogl.JoglGLExt; +import com.jme3.renderer.jogl.JoglGLFbo; import com.jme3.renderer.jogl.JoglRenderer; +import com.jme3.renderer.opengl.GL2; +import com.jme3.renderer.opengl.GL3; +import com.jme3.renderer.opengl.GL4; +import com.jme3.renderer.opengl.GLDebugDesktop; +import com.jme3.renderer.opengl.GLExt; +import com.jme3.renderer.opengl.GLFbo; +import com.jme3.renderer.opengl.GLRenderer; +import com.jme3.renderer.opengl.GLTiming; +import com.jme3.renderer.opengl.GLTimingState; +import com.jme3.renderer.opengl.GLTracer; import com.jme3.system.AppSettings; import com.jme3.system.JmeContext; import com.jme3.system.NanoTimer; import com.jme3.system.NativeLibraryLoader; import com.jme3.system.SystemListener; import com.jme3.system.Timer; + import java.nio.IntBuffer; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.logging.Logger; + import com.jogamp.opengl.GL; import com.jogamp.opengl.GL2GL3; import com.jogamp.opengl.GLContext; @@ -62,7 +78,7 @@ public abstract class JoglContext implements JmeContext { protected final Object createdLock = new Object(); protected AppSettings settings = new AppSettings(true); - protected JoglRenderer renderer; + protected Renderer renderer; protected Timer timer; protected SystemListener listener; @@ -77,43 +93,53 @@ public abstract class JoglContext implements JmeContext { } } - public void setSystemListener(SystemListener listener){ + @Override + public void setSystemListener(SystemListener listener){ this.listener = listener; } - public void setSettings(AppSettings settings) { + @Override + public void setSettings(AppSettings settings) { this.settings.copyFrom(settings); } - public boolean isRenderable(){ + @Override + public boolean isRenderable(){ return renderable.get(); } - public AppSettings getSettings() { + @Override + public AppSettings getSettings() { return settings; } - public Renderer getRenderer() { + @Override + public Renderer getRenderer() { return renderer; } - public MouseInput getMouseInput() { + @Override + public MouseInput getMouseInput() { return mouseInput; } - public KeyInput getKeyInput() { + @Override + public KeyInput getKeyInput() { return keyInput; } - public JoyInput getJoyInput() { + @Override + public JoyInput getJoyInput() { return joyInput; } - public Timer getTimer() { + @Override + public Timer getTimer() { return timer; } - public boolean isCreated() { + @Override + public boolean isCreated() { return created.get(); } @@ -135,13 +161,78 @@ public abstract class JoglContext implements JmeContext { } } } + + protected void initContextFirstTime(){ + if (GLContext.getCurrent().getGLVersionNumber().getMajor() < 2) { + throw new RendererException("OpenGL 2.0 or higher is " + + "required for jMonkeyEngine"); + } + + if (settings.getRenderer().equals("JOGL")) { + com.jme3.renderer.opengl.GL gl = new JoglGL(); + GLExt glext = new JoglGLExt(); + GLFbo glfbo = new JoglGLFbo(); + + if (settings.getBoolean("GraphicsDebug")) { + gl = new GLDebugDesktop(gl, glext, glfbo); + glext = (GLExt) gl; + glfbo = (GLFbo) gl; + } + + if (settings.getBoolean("GraphicsTiming")) { + GLTimingState timingState = new GLTimingState(); + gl = (com.jme3.renderer.opengl.GL) GLTiming.createGLTiming(gl, timingState, GL.class, GL2.class, GL3.class, GL4.class); + glext = (GLExt) GLTiming.createGLTiming(glext, timingState, GLExt.class); + glfbo = (GLFbo) GLTiming.createGLTiming(glfbo, timingState, GLFbo.class); + } + + if (settings.getBoolean("GraphicsTrace")) { + gl = (com.jme3.renderer.opengl.GL) GLTracer.createDesktopGlTracer(gl, GL.class, GL2.class, GL3.class, GL4.class); + glext = (GLExt) GLTracer.createDesktopGlTracer(glext, GLExt.class); + glfbo = (GLFbo) GLTracer.createDesktopGlTracer(glfbo, GLFbo.class); + } + + //FIXME uncomment the line below when the unified renderer is ready for the prime time :) + //renderer = new GLRenderer(gl, glext, glfbo); + renderer = new JoglRenderer(); + renderer.initialize(); + } else { + throw new UnsupportedOperationException("Unsupported renderer: " + settings.getRenderer()); + } + + if (GLContext.getCurrentGL().isExtensionAvailable("GL_ARB_debug_output") && settings.getBoolean("GraphicsDebug")) { + GLContext.getCurrent().enableGLDebugMessage(true); + GLContext.getCurrent().addGLDebugListener(new JoglGLDebugOutputHandler()); + } + + renderer.setMainFrameBufferSrgb(settings.getGammaCorrection()); + renderer.setLinearizeSrgbImages(settings.getGammaCorrection()); - public void internalCreate() { + // Init input + if (keyInput != null) { + keyInput.initialize(); + } + + if (mouseInput != null) { + mouseInput.initialize(); + } + + if (joyInput != null) { + joyInput.initialize(); + } + } + + public void internalCreate() { timer = new NanoTimer(); synchronized (createdLock){ created.set(true); createdLock.notifyAll(); } + if (renderable.get()){ + initContextFirstTime(); + } else { + assert getType() == Type.Canvas; + } } protected void internalDestroy() { diff --git a/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglGLDebugOutputHandler.java b/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglGLDebugOutputHandler.java new file mode 100644 index 000000000..5a8b58715 --- /dev/null +++ b/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglGLDebugOutputHandler.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2009-2015 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.system.jogl; + +import java.util.HashMap; + +import com.jogamp.opengl.GL2ES2; +import com.jogamp.opengl.GLDebugListener; +import com.jogamp.opengl.GLDebugMessage; + +class JoglGLDebugOutputHandler implements GLDebugListener { + + private static final HashMap constMap = new HashMap(); + private static final String MESSAGE_FORMAT = + "[JME3] OpenGL debug message\r\n" + + " ID: %d\r\n" + + " Source: %s\r\n" + + " Type: %s\r\n" + + " Severity: %s\r\n" + + " Message: %s"; + + static { + constMap.put(GL2ES2.GL_DEBUG_SOURCE_API, "API"); + constMap.put(GL2ES2.GL_DEBUG_SOURCE_APPLICATION, "APPLICATION"); + constMap.put(GL2ES2.GL_DEBUG_SOURCE_OTHER, "OTHER"); + constMap.put(GL2ES2.GL_DEBUG_SOURCE_SHADER_COMPILER, "SHADER_COMPILER"); + constMap.put(GL2ES2.GL_DEBUG_SOURCE_THIRD_PARTY, "THIRD_PARTY"); + constMap.put(GL2ES2.GL_DEBUG_SOURCE_WINDOW_SYSTEM, "WINDOW_SYSTEM"); + + constMap.put(GL2ES2.GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR, "DEPRECATED_BEHAVIOR"); + constMap.put(GL2ES2.GL_DEBUG_TYPE_ERROR, "ERROR"); + constMap.put(GL2ES2.GL_DEBUG_TYPE_OTHER, "OTHER"); + constMap.put(GL2ES2.GL_DEBUG_TYPE_PERFORMANCE, "PERFORMANCE"); + constMap.put(GL2ES2.GL_DEBUG_TYPE_PORTABILITY, "PORTABILITY"); + constMap.put(GL2ES2.GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR, "UNDEFINED_BEHAVIOR"); + + constMap.put(GL2ES2.GL_DEBUG_SEVERITY_HIGH, "HIGH"); + constMap.put(GL2ES2.GL_DEBUG_SEVERITY_MEDIUM, "MEDIUM"); + constMap.put(GL2ES2.GL_DEBUG_SEVERITY_LOW, "LOW"); + } + + @Override + public void messageSent(GLDebugMessage event) { + String sourceStr = constMap.get(event.getDbgSource()); + String typeStr = constMap.get(event.getDbgType()); + String severityStr = constMap.get(event.getDbgSeverity()); + + System.err.println(String.format(MESSAGE_FORMAT, event.getDbgId(), sourceStr, typeStr, severityStr, event.getDbgMsg())); + } + +} diff --git a/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglNewtAbstractDisplay.java b/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglNewtAbstractDisplay.java index cb75d5d37..4ac6f5c49 100644 --- a/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglNewtAbstractDisplay.java +++ b/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglNewtAbstractDisplay.java @@ -37,21 +37,14 @@ import com.jme3.input.MouseInput; import com.jme3.input.TouchInput; import com.jme3.input.jogl.NewtKeyInput; import com.jme3.input.jogl.NewtMouseInput; -import com.jme3.renderer.jogl.JoglRenderer; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.util.Animator; import com.jogamp.opengl.util.AnimatorBase; import com.jogamp.opengl.util.FPSAnimator; + import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Logger; -import com.jogamp.opengl.DebugGL2; -import com.jogamp.opengl.DebugGL3; -import com.jogamp.opengl.DebugGL3bc; -import com.jogamp.opengl.DebugGL4; -import com.jogamp.opengl.DebugGL4bc; -import com.jogamp.opengl.DebugGLES1; -import com.jogamp.opengl.DebugGLES2; -import com.jogamp.opengl.GL; + import com.jogamp.opengl.GLAutoDrawable; import com.jogamp.opengl.GLCapabilities; import com.jogamp.opengl.GLEventListener; @@ -103,50 +96,9 @@ public abstract class JoglNewtAbstractDisplay extends JoglContext implements GLE canvas.requestFocus(); canvas.setSize(settings.getWidth(), settings.getHeight()); canvas.addGLEventListener(this); - - if (settings.getBoolean("GraphicsDebug")) { - canvas.invoke(false, new GLRunnable() { - public boolean run(GLAutoDrawable glad) { - GL gl = glad.getGL(); - if (gl.isGLES()) { - if (gl.isGLES1()) { - glad.setGL(new DebugGLES1(gl.getGLES1())); - } else { - if (gl.isGLES2()) { - glad.setGL(new DebugGLES2(gl.getGLES2())); - } else { - // TODO ES3 - } - } - } else { - if (gl.isGL4bc()) { - glad.setGL(new DebugGL4bc(gl.getGL4bc())); - } else { - if (gl.isGL4()) { - glad.setGL(new DebugGL4(gl.getGL4())); - } else { - if (gl.isGL3bc()) { - glad.setGL(new DebugGL3bc(gl.getGL3bc())); - } else { - if (gl.isGL3()) { - glad.setGL(new DebugGL3(gl.getGL3())); - } else { - if (gl.isGL2()) { - glad.setGL(new DebugGL2(gl.getGL2())); - } - } - } - } - } - } - return true; - } - }); - } - - renderer = new JoglRenderer(); - renderer.setMainFrameBufferSrgb(settings.getGammaCorrection()); + //FIXME not sure it is the best place to do that + renderable.set(true); } protected void startGLCanvas() { @@ -161,9 +113,6 @@ public abstract class JoglNewtAbstractDisplay extends JoglContext implements GLE animator.start(); wasAnimating = true; - - //FIXME not sure it is the best place to do that - renderable.set(true); } protected void onCanvasAdded() { diff --git a/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglNewtCanvas.java b/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglNewtCanvas.java index 3ed501580..e4e81a5df 100644 --- a/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglNewtCanvas.java +++ b/jme3-jogl/src/main/java/com/jme3/system/jogl/JoglNewtCanvas.java @@ -41,6 +41,7 @@ public class JoglNewtCanvas extends JoglNewtAbstractDisplay implements JmeCanvas private static final Logger logger = Logger.getLogger(JoglNewtCanvas.class.getName()); private int width, height; + private boolean runningFirstTime = true; private NewtCanvasAWT newtAwtCanvas; @@ -53,7 +54,9 @@ public class JoglNewtCanvas extends JoglNewtAbstractDisplay implements JmeCanvas protected final void initGLCanvas() { super.initGLCanvas(); newtAwtCanvas = new NewtCanvasAWT(canvas) { - @Override + private static final long serialVersionUID = 1L; + + @Override public void addNotify() { super.addNotify(); onCanvasAdded(); @@ -67,22 +70,27 @@ public class JoglNewtCanvas extends JoglNewtAbstractDisplay implements JmeCanvas }; } - public Type getType() { + @Override + public Type getType() { return Type.Canvas; } - public void setTitle(String title) { + @Override + public void setTitle(String title) { } - public void restart() { + @Override + public void restart() { } - public void create(boolean waitFor){ + @Override + public void create(boolean waitFor){ if (waitFor) waitFor(true); } - public void destroy(boolean waitFor){ + @Override + public void destroy(boolean waitFor){ if (waitFor) waitFor(false); if (animator.isAnimating()) @@ -101,13 +109,20 @@ public class JoglNewtCanvas extends JoglNewtAbstractDisplay implements JmeCanvas startGLCanvas(); } - public void init(GLAutoDrawable drawable) { + @Override + public void init(GLAutoDrawable drawable) { canvas.requestFocus(); super.internalCreate(); logger.fine("Display created."); - renderer.initialize(); + // At this point, the OpenGL context is active. + if (runningFirstTime){ + // THIS is the part that creates the renderer. + // It must always be called, now that we have the pbuffer workaround. + initContextFirstTime(); + runningFirstTime = false; + } listener.initialize(); } @@ -117,7 +132,8 @@ public class JoglNewtCanvas extends JoglNewtAbstractDisplay implements JmeCanvas super.startGLCanvas(); } - public void display(GLAutoDrawable glad) { + @Override + public void display(GLAutoDrawable glad) { if (!created.get() && renderer != null){ listener.destroy(); logger.fine("Canvas destroyed."); diff --git a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java index bf99c84eb..2b7df131a 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java +++ b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java @@ -13,7 +13,7 @@ import java.nio.ShortBuffer; import com.jme3.renderer.opengl.GL4; import org.lwjgl.opengl.*; -public class LwjglGL implements GL, GL2, GL3, GL4 { +public final class LwjglGL implements GL, GL2, GL3, GL4 { private static void checkLimit(Buffer buffer) { if (buffer == null) { diff --git a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLExt.java b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLExt.java index 2c6a63fd7..e3b9e6c77 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLExt.java +++ b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLExt.java @@ -13,7 +13,7 @@ import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GLSync; -public class LwjglGLExt implements GLExt { +public final class LwjglGLExt implements GLExt { private static void checkLimit(Buffer buffer) { if (buffer == null) { diff --git a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLFboEXT.java b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLFboEXT.java index 159000a6c..40571f5ed 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLFboEXT.java +++ b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLFboEXT.java @@ -13,7 +13,7 @@ import org.lwjgl.opengl.EXTFramebufferObject; * * @author Kirill Vainer */ -public class LwjglGLFboEXT implements GLFbo { +public final class LwjglGLFboEXT implements GLFbo { private static void checkLimit(Buffer buffer) { if (buffer == null) { diff --git a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLFboGL3.java b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLFboGL3.java index acc540273..14e0cc9e6 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLFboGL3.java +++ b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLFboGL3.java @@ -11,7 +11,7 @@ import org.lwjgl.opengl.GL30; * * @author Kirill Vainer */ -public class LwjglGLFboGL3 implements GLFbo { +public final class LwjglGLFboGL3 implements GLFbo { private static void checkLimit(Buffer buffer) { if (buffer == null) { diff --git a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglRenderer.java b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglRenderer.java deleted file mode 100644 index e614d1dfd..000000000 --- a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglRenderer.java +++ /dev/null @@ -1,2695 +0,0 @@ -/* - * 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.renderer.lwjgl; - -import com.jme3.light.LightList; -import com.jme3.material.RenderState; -import com.jme3.material.RenderState.StencilOperation; -import com.jme3.material.RenderState.TestFunction; -import com.jme3.math.*; -import com.jme3.renderer.*; -import com.jme3.scene.Mesh; -import com.jme3.scene.Mesh.Mode; -import com.jme3.scene.VertexBuffer; -import com.jme3.scene.VertexBuffer.Format; -import com.jme3.scene.VertexBuffer.Type; -import com.jme3.scene.VertexBuffer.Usage; -import com.jme3.shader.Attribute; -import com.jme3.shader.Shader; -import com.jme3.shader.Shader.ShaderSource; -import com.jme3.shader.Shader.ShaderType; -import com.jme3.shader.Uniform; -import com.jme3.texture.FrameBuffer; -import com.jme3.texture.FrameBuffer.RenderBuffer; -import com.jme3.texture.Image; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture.WrapAxis; -import com.jme3.util.BufferUtils; -import com.jme3.util.ListMap; -import com.jme3.util.NativeObjectManager; -import java.nio.*; -import java.util.EnumSet; -import java.util.HashSet; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; -import jme3tools.converters.MipMapGenerator; -import jme3tools.shader.ShaderDebug; - -import static org.lwjgl.opengl.ARBDrawInstanced.*; -import static org.lwjgl.opengl.ARBInstancedArrays.*; -import static org.lwjgl.opengl.ARBMultisample.*; -import static org.lwjgl.opengl.ARBTextureMultisample.*; -import static org.lwjgl.opengl.ARBVertexArrayObject.*; -import static org.lwjgl.opengl.EXTFramebufferBlit.*; -import static org.lwjgl.opengl.EXTFramebufferMultisample.*; -import static org.lwjgl.opengl.EXTFramebufferObject.*; -import static org.lwjgl.opengl.EXTFramebufferSRGB.*; -import static org.lwjgl.opengl.EXTTextureArray.*; -import static org.lwjgl.opengl.EXTTextureFilterAnisotropic.*; -import static org.lwjgl.opengl.GL11.*; -import static org.lwjgl.opengl.GL12.*; -import static org.lwjgl.opengl.GL13.*; -import static org.lwjgl.opengl.GL14.*; -import static org.lwjgl.opengl.GL15.*; -import static org.lwjgl.opengl.GL20.*; -import org.lwjgl.opengl.GL30; - -/** - * - * Should not be used, has been replaced by Unified Rendering Architechture. - * @deprecated - */ -@Deprecated -public class LwjglRenderer { - - private static final Logger logger = Logger.getLogger(LwjglRenderer.class.getName()); - private static final boolean VALIDATE_SHADER = false; - 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(); - private final NativeObjectManager objManager = new NativeObjectManager(); - private final EnumSet caps = EnumSet.noneOf(Caps.class); - - private int vertexTextureUnits; - private int fragTextureUnits; - private int vertexUniforms; - private int fragUniforms; - private int vertexAttribs; - private int maxFBOSamples; - private int maxFBOAttachs; - private int maxMRTFBOAttachs; - private int maxRBSize; - private int maxTexSize; - private int maxCubeTexSize; - private int maxVertCount; - private int maxTriCount; - private int maxColorTexSamples; - private int maxDepthTexSamples; - 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; - - public LwjglRenderer() { - } - - protected void updateNameBuffer() { - int len = stringBuf.length(); - - nameBuf.position(0); - nameBuf.limit(len); - for (int i = 0; i < len; i++) { - nameBuf.put((byte) stringBuf.charAt(i)); - } - - nameBuf.rewind(); - } - -// @Override - public Statistics getStatistics() { - return statistics; - } - - // @Override - public EnumSet getCaps() { - return caps; - } - - private static HashSet loadExtensions(String extensions) { - HashSet extensionSet = new HashSet(64); - for (String extension : extensions.split(" ")) { - extensionSet.add(extension); - } - return extensionSet; - } - - private static int extractVersion(String prefixStr, String versionStr) { - if (versionStr != null) { - int spaceIdx = versionStr.indexOf(" ", prefixStr.length()); - if (spaceIdx >= 1) { - versionStr = versionStr.substring(prefixStr.length(), spaceIdx).trim(); - } else { - versionStr = versionStr.substring(prefixStr.length()).trim(); - } - - // Find a character which is not a period or digit. - for (int i = 0; i < versionStr.length(); i++) { - char c = versionStr.charAt(i); - if (c != '.' && (c < '0' || c > '9')) { - versionStr = versionStr.substring(0, i); - break; - } - } - - // Pivot on first point. - int firstPoint = versionStr.indexOf("."); - - // Remove everything after second point. - int secondPoint = versionStr.indexOf(".", firstPoint + 1); - - if (secondPoint != -1) { - versionStr = versionStr.substring(0, secondPoint); - } - - String majorVerStr = versionStr.substring(0, firstPoint); - String minorVerStr = versionStr.substring(firstPoint + 1); - - if (minorVerStr.endsWith("0") && minorVerStr.length() > 1) { - minorVerStr = minorVerStr.substring(0, minorVerStr.length() - 1); - } - - int majorVer = Integer.parseInt(majorVerStr); - int minorVer = Integer.parseInt(minorVerStr); - - return majorVer * 100 + minorVer * 10; - } else { - return -1; - } - } - - private boolean hasExtension(String extensionName) { - return extensions.contains(extensionName); - } - - private void loadCapabilities() { - int oglVer = extractVersion("", glGetString(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); - } - } - } - } - } - - int glslVer = extractVersion("", glGetString(GL_SHADING_LANGUAGE_VERSION)); - - switch (glslVer) { - default: - if (glslVer < 400) { - break; - } - // so that future OpenGL revisions wont break jme3 - // fall through intentional - case 400: - case 330: - 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. - // Some cards just don't report this correctly. - caps.add(Caps.GLSL100); - - extensions = loadExtensions(glGetString(GL_EXTENSIONS)); - } - - @SuppressWarnings("fallthrough") - public void initialize() { - loadCapabilities(); - - // Fix issue in TestRenderToMemory when GL_FRONT is the main - // buffer being used. - context.initialDrawBuf = glGetInteger(GL_DRAW_BUFFER); - context.initialReadBuf = glGetInteger(GL_READ_BUFFER); - - // XXX: This has to be GL_BACK for canvas on Mac - // Since initialDrawBuf is GL_FRONT for pbuffer, gotta - // change this value later on ... -// initialDrawBuf = GL_BACK; -// initialReadBuf = GL_BACK; - - glGetInteger(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, intBuf16); - vertexTextureUnits = intBuf16.get(0); - logger.log(Level.FINER, "VTF Units: {0}", vertexTextureUnits); - if (vertexTextureUnits > 0) { - caps.add(Caps.VertexTextureFetch); - } - - glGetInteger(GL_MAX_TEXTURE_IMAGE_UNITS, intBuf16); - fragTextureUnits = intBuf16.get(0); - logger.log(Level.FINER, "Texture Units: {0}", fragTextureUnits); - - glGetInteger(GL_MAX_VERTEX_UNIFORM_COMPONENTS, intBuf16); - vertexUniforms = intBuf16.get(0); - logger.log(Level.FINER, "Vertex Uniforms: {0}", vertexUniforms); - - glGetInteger(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, intBuf16); - fragUniforms = intBuf16.get(0); - logger.log(Level.FINER, "Fragment Uniforms: {0}", fragUniforms); - - glGetInteger(GL_MAX_VERTEX_ATTRIBS, intBuf16); - vertexAttribs = intBuf16.get(0); - logger.log(Level.FINER, "Vertex Attributes: {0}", vertexAttribs); - - glGetInteger(GL_SUBPIXEL_BITS, intBuf16); - int subpixelBits = intBuf16.get(0); - logger.log(Level.FINER, "Subpixel Bits: {0}", subpixelBits); - - glGetInteger(GL_MAX_ELEMENTS_VERTICES, intBuf16); - maxVertCount = intBuf16.get(0); - logger.log(Level.FINER, "Preferred Batch Vertex Count: {0}", maxVertCount); - - glGetInteger(GL_MAX_ELEMENTS_INDICES, intBuf16); - maxTriCount = intBuf16.get(0); - logger.log(Level.FINER, "Preferred Batch Index Count: {0}", maxTriCount); - - glGetInteger(GL_MAX_TEXTURE_SIZE, intBuf16); - maxTexSize = intBuf16.get(0); - logger.log(Level.FINER, "Maximum Texture Resolution: {0}", maxTexSize); - - glGetInteger(GL_MAX_CUBE_MAP_TEXTURE_SIZE, intBuf16); - maxCubeTexSize = intBuf16.get(0); - logger.log(Level.FINER, "Maximum CubeMap Resolution: {0}", maxCubeTexSize); - - // ctxCaps = GLContext.getCapabilities(); - - 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 (caps.contains(Caps.OpenGL30)) { - caps.add(Caps.PackedDepthStencilBuffer); - } - - if (hasExtension("GL_ARB_draw_instanced") && - hasExtension("GL_ARB_instanced_arrays")) { - caps.add(Caps.MeshInstancing); - } - - if (hasExtension("GL_ARB_texture_buffer_object")) { - caps.add(Caps.TextureBuffer); - } - - if (hasExtension("GL_ARB_texture_float") && - hasExtension("GL_ARB_half_float_pixel")) { - caps.add(Caps.FloatTexture); - } - - if (hasExtension("GL_ARB_vertex_array_object") || caps.contains(Caps.OpenGL30)) { - caps.add(Caps.VertexBufferArray); - } - - if (hasExtension("GL_ARB_texture_non_power_of_two") || 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 (hasExtension("GL_EXT_texture_compression_s3tc")) { - caps.add(Caps.TextureCompressionS3TC); - } - - if (hasExtension("GL_ARB_ES3_compatibility")) { - caps.add(Caps.TextureCompressionETC1); - } - - if (hasExtension("GL_EXT_packed_float") || caps.contains(Caps.OpenGL30)) { - // This format is part of the OGL3 specification - caps.add(Caps.PackedFloatColorBuffer); - - if (hasExtension("GL_ARB_half_float_pixel")) { - // because textures are usually uploaded as RGB16F - // need half-float pixel - caps.add(Caps.PackedFloatTexture); - } - } - - if (hasExtension("GL_EXT_texture_array") || caps.contains(Caps.OpenGL30)) { - caps.add(Caps.TextureArray); - } - - if (hasExtension("GL_EXT_texture_shared_exponent") || caps.contains(Caps.OpenGL30)) { - caps.add(Caps.SharedExponentTexture); - } - - if (hasExtension("GL_EXT_texture_filter_anisotropic")) { - caps.add(Caps.TextureFilterAnisotropic); - } - - if (hasExtension("GL_EXT_framebuffer_object")) { - caps.add(Caps.FrameBuffer); - - glGetInteger(GL_MAX_RENDERBUFFER_SIZE_EXT, intBuf16); - maxRBSize = intBuf16.get(0); - logger.log(Level.FINER, "FBO RB Max Size: {0}", maxRBSize); - - glGetInteger(GL_MAX_COLOR_ATTACHMENTS_EXT, intBuf16); - maxFBOAttachs = intBuf16.get(0); - logger.log(Level.FINER, "FBO Max renderbuffers: {0}", maxFBOAttachs); - - if (hasExtension("GL_EXT_framebuffer_blit")) { - caps.add(Caps.FrameBufferBlit); - } - - if (hasExtension("GL_EXT_framebuffer_multisample")) { - caps.add(Caps.FrameBufferMultisample); - - glGetInteger(GL_MAX_SAMPLES_EXT, intBuf16); - maxFBOSamples = intBuf16.get(0); - logger.log(Level.FINER, "FBO Max Samples: {0}", maxFBOSamples); - } - - if (hasExtension("GL_ARB_texture_multisample")) { - caps.add(Caps.TextureMultisample); - - glGetInteger(GL_MAX_COLOR_TEXTURE_SAMPLES, intBuf16); - maxColorTexSamples = intBuf16.get(0); - logger.log(Level.FINER, "Texture Multisample Color Samples: {0}", maxColorTexSamples); - - glGetInteger(GL_MAX_DEPTH_TEXTURE_SAMPLES, intBuf16); - maxDepthTexSamples = intBuf16.get(0); - logger.log(Level.FINER, "Texture Multisample Depth Samples: {0}", maxDepthTexSamples); - } - - if (hasExtension("GL_ARB_draw_buffers")) { - glGetInteger(GL_MAX_DRAW_BUFFERS, intBuf16); - maxMRTFBOAttachs = intBuf16.get(0); - if (maxMRTFBOAttachs > 1) { - caps.add(Caps.FrameBufferMRT); - logger.log(Level.FINER, "FBO Max MRT renderbuffers: {0}", maxMRTFBOAttachs); - } - } - } - - if (hasExtension("GL_ARB_multisample")) { - glGetInteger(GL_SAMPLE_BUFFERS_ARB, intBuf16); - boolean available = intBuf16.get(0) != 0; - glGetInteger(GL_SAMPLES_ARB, intBuf16); - int samples = intBuf16.get(0); - logger.log(Level.FINER, "Samples: {0}", samples); - boolean enabled = glIsEnabled(GL_MULTISAMPLE_ARB); - if (samples > 0 && available && !enabled) { - glEnable(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); - } - - logger.log(Level.FINE, "Caps: {0}", caps); - } - - public void invalidateState() { - context.reset(); - context.initialDrawBuf = glGetInteger(GL_DRAW_BUFFER); - context.initialReadBuf = glGetInteger(GL_READ_BUFFER); - } - - public void resetGLObjects() { - logger.log(Level.FINE, "Reseting objects and invalidating state"); - objManager.resetObjects(); - statistics.clearMemory(); - invalidateState(); - } - - public void cleanup() { - logger.log(Level.FINE, "Deleting objects and invalidating state"); - objManager.deleteAllObjects(this); - statistics.clearMemory(); - invalidateState(); - } - - private void checkCap(Caps cap) { - if (!caps.contains(cap)) { - throw new UnsupportedOperationException("Required capability missing: " + cap.name()); - } - } - - /*********************************************************************\ - |* Render State *| - \*********************************************************************/ - public void setDepthRange(float start, float end) { - glDepthRange(start, end); - } - - public void clearBuffers(boolean color, boolean depth, boolean stencil) { - int bits = 0; - if (color) { - //See explanations of the depth below, we must enable color write to be able to clear the color buffer - if (context.colorWriteEnabled == false) { - glColorMask(true, true, true, true); - context.colorWriteEnabled = true; - } - bits = GL_COLOR_BUFFER_BIT; - } - if (depth) { - - //glClear(GL_DEPTH_BUFFER_BIT) seems to not work when glDepthMask is false - //here s some link on openl board - //http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=257223 - //if depth clear is requested, we enable the depthMask - if (context.depthWriteEnabled == false) { - glDepthMask(true); - context.depthWriteEnabled = true; - } - bits |= GL_DEPTH_BUFFER_BIT; - } - if (stencil) { - bits |= GL_STENCIL_BUFFER_BIT; - } - if (bits != 0) { - glClear(bits); - } - } - - public void setBackgroundColor(ColorRGBA color) { - glClearColor(color.r, color.g, color.b, color.a); - } - - public void setAlphaToCoverage(boolean value) { - if (caps.contains(Caps.Multisample)) { - if (value) { - glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB); - } else { - glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB); - } - } - } - - public void applyRenderState(RenderState state) { - if (state.isWireframe() && !context.wireframe) { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - context.wireframe = true; - } else if (!state.isWireframe() && context.wireframe) { - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - context.wireframe = false; - } - - if (state.isDepthTest() && !context.depthTestEnabled) { - glEnable(GL_DEPTH_TEST); - glDepthFunc(convertTestFunction(context.depthFunc)); - context.depthTestEnabled = true; - } else if (!state.isDepthTest() && context.depthTestEnabled) { - glDisable(GL_DEPTH_TEST); - context.depthTestEnabled = false; - } - if (state.getDepthFunc() != context.depthFunc) { - glDepthFunc(convertTestFunction(state.getDepthFunc())); - context.depthFunc = state.getDepthFunc(); - } - - if (state.isAlphaTest() && !context.alphaTestEnabled) { - glEnable(GL_ALPHA_TEST); - glAlphaFunc(convertTestFunction(context.alphaFunc), context.alphaTestFallOff); - context.alphaTestEnabled = true; - } else if (!state.isAlphaTest() && context.alphaTestEnabled) { - glDisable(GL_ALPHA_TEST); - context.alphaTestEnabled = false; - } - if (state.getAlphaFallOff() != context.alphaTestFallOff) { - glAlphaFunc(convertTestFunction(context.alphaFunc), context.alphaTestFallOff); - context.alphaTestFallOff = state.getAlphaFallOff(); - } - if (state.getAlphaFunc() != context.alphaFunc) { - glAlphaFunc(convertTestFunction(state.getAlphaFunc()), context.alphaTestFallOff); - context.alphaFunc = state.getAlphaFunc(); - } - - if (state.isDepthWrite() && !context.depthWriteEnabled) { - glDepthMask(true); - context.depthWriteEnabled = true; - } else if (!state.isDepthWrite() && context.depthWriteEnabled) { - glDepthMask(false); - context.depthWriteEnabled = false; - } - - if (state.isColorWrite() && !context.colorWriteEnabled) { - glColorMask(true, true, true, true); - context.colorWriteEnabled = true; - } else if (!state.isColorWrite() && context.colorWriteEnabled) { - glColorMask(false, false, false, false); - context.colorWriteEnabled = false; - } - - if (state.isPointSprite() && !context.pointSprite) { - // Only enable/disable sprite - if (context.boundTextures[0] != null) { - if (context.boundTextureUnit != 0) { - glActiveTexture(GL_TEXTURE0); - context.boundTextureUnit = 0; - } - glEnable(GL_POINT_SPRITE); - glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); - } - context.pointSprite = true; - } else if (!state.isPointSprite() && context.pointSprite) { - if (context.boundTextures[0] != null) { - if (context.boundTextureUnit != 0) { - glActiveTexture(GL_TEXTURE0); - context.boundTextureUnit = 0; - } - glDisable(GL_POINT_SPRITE); - glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); - context.pointSprite = false; - } - } - - if (state.isPolyOffset()) { - if (!context.polyOffsetEnabled) { - glEnable(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(state.getPolyOffsetFactor(), - state.getPolyOffsetUnits()); - context.polyOffsetEnabled = true; - context.polyOffsetFactor = state.getPolyOffsetFactor(); - context.polyOffsetUnits = state.getPolyOffsetUnits(); - } else { - if (state.getPolyOffsetFactor() != context.polyOffsetFactor - || state.getPolyOffsetUnits() != context.polyOffsetUnits) { - glPolygonOffset(state.getPolyOffsetFactor(), - state.getPolyOffsetUnits()); - context.polyOffsetFactor = state.getPolyOffsetFactor(); - context.polyOffsetUnits = state.getPolyOffsetUnits(); - } - } - } else { - if (context.polyOffsetEnabled) { - glDisable(GL_POLYGON_OFFSET_FILL); - context.polyOffsetEnabled = false; - context.polyOffsetFactor = 0; - context.polyOffsetUnits = 0; - } - } - - if (state.getFaceCullMode() != context.cullMode) { - if (state.getFaceCullMode() == RenderState.FaceCullMode.Off) { - glDisable(GL_CULL_FACE); - } else { - glEnable(GL_CULL_FACE); - } - - switch (state.getFaceCullMode()) { - case Off: - break; - case Back: - glCullFace(GL_BACK); - break; - case Front: - glCullFace(GL_FRONT); - break; - case FrontAndBack: - glCullFace(GL_FRONT_AND_BACK); - break; - default: - throw new UnsupportedOperationException("Unrecognized face cull mode: " - + state.getFaceCullMode()); - } - - context.cullMode = state.getFaceCullMode(); - } - - if (state.getBlendMode() != context.blendMode) { - if (state.getBlendMode() == RenderState.BlendMode.Off) { - glDisable(GL_BLEND); - } else { - glEnable(GL_BLEND); - switch (state.getBlendMode()) { - case Off: - break; - case Additive: - glBlendFunc(GL_ONE, GL_ONE); - break; - case AlphaAdditive: - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - break; - case Color: - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR); - break; - case Alpha: - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - break; - case PremultAlpha: - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - break; - case Modulate: - glBlendFunc(GL_DST_COLOR, GL_ZERO); - break; - case ModulateX2: - glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR); - break; - case Screen: - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR); - break; - case Exclusion: - glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_COLOR); - break; - default: - throw new UnsupportedOperationException("Unrecognized blend mode: " - + state.getBlendMode()); - } - } - - context.blendMode = state.getBlendMode(); - } - - if (context.stencilTest != state.isStencilTest() - || context.frontStencilStencilFailOperation != state.getFrontStencilStencilFailOperation() - || context.frontStencilDepthFailOperation != state.getFrontStencilDepthFailOperation() - || context.frontStencilDepthPassOperation != state.getFrontStencilDepthPassOperation() - || context.backStencilStencilFailOperation != state.getBackStencilStencilFailOperation() - || context.backStencilDepthFailOperation != state.getBackStencilDepthFailOperation() - || context.backStencilDepthPassOperation != state.getBackStencilDepthPassOperation() - || context.frontStencilFunction != state.getFrontStencilFunction() - || context.backStencilFunction != state.getBackStencilFunction()) { - - context.frontStencilStencilFailOperation = state.getFrontStencilStencilFailOperation(); //terrible looking, I know - context.frontStencilDepthFailOperation = state.getFrontStencilDepthFailOperation(); - context.frontStencilDepthPassOperation = state.getFrontStencilDepthPassOperation(); - context.backStencilStencilFailOperation = state.getBackStencilStencilFailOperation(); - context.backStencilDepthFailOperation = state.getBackStencilDepthFailOperation(); - context.backStencilDepthPassOperation = state.getBackStencilDepthPassOperation(); - context.frontStencilFunction = state.getFrontStencilFunction(); - context.backStencilFunction = state.getBackStencilFunction(); - - if (state.isStencilTest()) { - glEnable(GL_STENCIL_TEST); - glStencilOpSeparate(GL_FRONT, - convertStencilOperation(state.getFrontStencilStencilFailOperation()), - convertStencilOperation(state.getFrontStencilDepthFailOperation()), - convertStencilOperation(state.getFrontStencilDepthPassOperation())); - glStencilOpSeparate(GL_BACK, - convertStencilOperation(state.getBackStencilStencilFailOperation()), - convertStencilOperation(state.getBackStencilDepthFailOperation()), - convertStencilOperation(state.getBackStencilDepthPassOperation())); - glStencilFuncSeparate(GL_FRONT, - convertTestFunction(state.getFrontStencilFunction()), - 0, Integer.MAX_VALUE); - glStencilFuncSeparate(GL_BACK, - convertTestFunction(state.getBackStencilFunction()), - 0, Integer.MAX_VALUE); - } else { - glDisable(GL_STENCIL_TEST); - } - } - } - - private int convertStencilOperation(StencilOperation stencilOp) { - switch (stencilOp) { - case Keep: - return GL_KEEP; - case Zero: - return GL_ZERO; - case Replace: - return GL_REPLACE; - case Increment: - return GL_INCR; - case IncrementWrap: - return GL_INCR_WRAP; - case Decrement: - return GL_DECR; - case DecrementWrap: - return GL_DECR_WRAP; - case Invert: - return GL_INVERT; - default: - throw new UnsupportedOperationException("Unrecognized stencil operation: " + stencilOp); - } - } - - private int convertTestFunction(TestFunction testFunc) { - switch (testFunc) { - case Never: - return GL_NEVER; - case Less: - return GL_LESS; - case LessOrEqual: - return GL_LEQUAL; - case Greater: - return GL_GREATER; - case GreaterOrEqual: - return GL_GEQUAL; - case Equal: - return GL_EQUAL; - case NotEqual: - return GL_NOTEQUAL; - case Always: - return GL_ALWAYS; - default: - throw new UnsupportedOperationException("Unrecognized test function: " + testFunc); - } - } - - /*********************************************************************\ - |* Camera and World transforms *| - \*********************************************************************/ - public void setViewPort(int x, int y, int w, int h) { - if (x != vpX || vpY != y || vpW != w || vpH != h) { - glViewport(x, y, w, h); - vpX = x; - vpY = y; - vpW = w; - vpH = h; - } - } - - public void setClipRect(int x, int y, int width, int height) { - if (!context.clipRectEnabled) { - glEnable(GL_SCISSOR_TEST); - context.clipRectEnabled = true; - } - if (clipX != x || clipY != y || clipW != width || clipH != height) { - glScissor(x, y, width, height); - clipX = x; - clipY = y; - clipW = width; - clipH = height; - } - } - - public void clearClipRect() { - if (context.clipRectEnabled) { - glDisable(GL_SCISSOR_TEST); - context.clipRectEnabled = false; - - clipX = 0; - clipY = 0; - clipW = 0; - clipH = 0; - } - } - - public void postFrame() { - objManager.deleteUnused(this); -// statistics.clearFrame(); - } - - public void setWorldMatrix(Matrix4f worldMatrix) { - } - - public void setViewProjectionMatrices(Matrix4f viewMatrix, Matrix4f projMatrix) { - } - - /*********************************************************************\ - |* Shaders *| - \*********************************************************************/ - protected void updateUniformLocation(Shader shader, Uniform uniform) { - stringBuf.setLength(0); - stringBuf.append(uniform.getName()).append('\0'); - updateNameBuffer(); - int loc = glGetUniformLocation(shader.getId(), nameBuf); - if (loc < 0) { - uniform.setLocation(-1); - // uniform is not declared in shader - logger.log(Level.FINE, "Uniform {0} is not declared in shader {1}.", new Object[]{uniform.getName(), shader.getSources()}); - } else { - uniform.setLocation(loc); - } - } - - protected void bindProgram(Shader shader) { - int shaderId = shader.getId(); - if (context.boundShaderProgram != shaderId) { - glUseProgram(shaderId); - statistics.onShaderUse(shader, true); - context.boundShader = shader; - context.boundShaderProgram = shaderId; - } else { - statistics.onShaderUse(shader, false); - } - } - - protected void updateUniform(Shader shader, Uniform uniform) { - int shaderId = shader.getId(); - - assert uniform.getName() != null; - assert shader.getId() > 0; - - bindProgram(shader); - - int loc = uniform.getLocation(); - if (loc == -1) { - return; - } - - if (loc == -2) { - // get uniform location - updateUniformLocation(shader, uniform); - if (uniform.getLocation() == -1) { - // not declared, ignore - uniform.clearUpdateNeeded(); - return; - } - loc = uniform.getLocation(); - } - - if (uniform.getVarType() == null) { - return; // value not set yet.. - } - statistics.onUniformSet(); - - uniform.clearUpdateNeeded(); - FloatBuffer fb; - IntBuffer ib; - switch (uniform.getVarType()) { - case Float: - Float f = (Float) uniform.getValue(); - glUniform1f(loc, f.floatValue()); - break; - case Vector2: - Vector2f v2 = (Vector2f) uniform.getValue(); - glUniform2f(loc, v2.getX(), v2.getY()); - break; - case Vector3: - Vector3f v3 = (Vector3f) uniform.getValue(); - glUniform3f(loc, v3.getX(), v3.getY(), v3.getZ()); - break; - case Vector4: - Object val = uniform.getValue(); - if (val instanceof ColorRGBA) { - ColorRGBA c = (ColorRGBA) val; - glUniform4f(loc, c.r, c.g, c.b, c.a); - } else if (val instanceof Vector4f) { - Vector4f c = (Vector4f) val; - glUniform4f(loc, c.x, c.y, c.z, c.w); - } else { - Quaternion c = (Quaternion) uniform.getValue(); - glUniform4f(loc, c.getX(), c.getY(), c.getZ(), c.getW()); - } - break; - case Boolean: - Boolean b = (Boolean) uniform.getValue(); - glUniform1i(loc, b.booleanValue() ? GL_TRUE : GL_FALSE); - break; - case Matrix3: - fb = (FloatBuffer) uniform.getValue(); - assert fb.remaining() == 9; - glUniformMatrix3(loc, false, fb); - break; - case Matrix4: - fb = (FloatBuffer) uniform.getValue(); - assert fb.remaining() == 16; - glUniformMatrix4(loc, false, fb); - break; - case IntArray: - ib = (IntBuffer) uniform.getValue(); - glUniform1(loc, ib); - break; - case FloatArray: - fb = (FloatBuffer) uniform.getValue(); - glUniform1(loc, fb); - break; - case Vector2Array: - fb = (FloatBuffer) uniform.getValue(); - glUniform2(loc, fb); - break; - case Vector3Array: - fb = (FloatBuffer) uniform.getValue(); - glUniform3(loc, fb); - break; - case Vector4Array: - fb = (FloatBuffer) uniform.getValue(); - glUniform4(loc, fb); - break; - case Matrix4Array: - fb = (FloatBuffer) uniform.getValue(); - glUniformMatrix4(loc, false, fb); - break; - case Int: - Integer i = (Integer) uniform.getValue(); - glUniform1i(loc, i.intValue()); - break; - default: - throw new UnsupportedOperationException("Unsupported uniform type: " + uniform.getVarType()); - } - } - - protected void updateShaderUniforms(Shader shader) { - ListMap uniforms = shader.getUniformMap(); - for (int i = 0; i < uniforms.size(); i++) { - Uniform uniform = uniforms.getValue(i); - if (uniform.isUpdateNeeded()) { - updateUniform(shader, uniform); - } - } - } - - protected void resetUniformLocations(Shader shader) { - ListMap uniforms = shader.getUniformMap(); - for (int i = 0; i < uniforms.size(); i++) { - Uniform uniform = uniforms.getValue(i); - uniform.reset(); // e.g check location again - } - } - - /* - * (Non-javadoc) - * Only used for fixed-function. Ignored. - */ - public void setLighting(LightList list) { - } - - public int convertShaderType(ShaderType type) { - switch (type) { - case Fragment: - return GL_FRAGMENT_SHADER; - case Vertex: - return GL_VERTEX_SHADER; - default: - throw new UnsupportedOperationException("Unrecognized shader type."); - } - } - - public void updateShaderSourceData(ShaderSource source) { - int id = source.getId(); - if (id == -1) { - // Create id - id = glCreateShader(convertShaderType(source.getType())); - if (id <= 0) { - throw new RendererException("Invalid ID received when trying to create shader."); - } - - source.setId(id); - } else { - throw new RendererException("Cannot recompile shader source"); - } - - // Upload shader source. - // Merge the defines and source code. - String language = source.getLanguage(); - stringBuf.setLength(0); - if (language.startsWith("GLSL")) { - int version = Integer.parseInt(language.substring(4)); - if (version > 100) { - stringBuf.append("#version "); - stringBuf.append(language.substring(4)); - if (version >= 150) { - stringBuf.append(" core"); - } - stringBuf.append("\n"); - } else { - // version 100 does not exist in desktop GLSL. - // put version 110 in that case to enable strict checking - stringBuf.append("#version 110\n"); - } - } - updateNameBuffer(); - - byte[] definesCodeData = source.getDefines().getBytes(); - byte[] sourceCodeData = source.getSource().getBytes(); - ByteBuffer codeBuf = BufferUtils.createByteBuffer(nameBuf.limit() - + definesCodeData.length - + sourceCodeData.length); - codeBuf.put(nameBuf); - codeBuf.put(definesCodeData); - codeBuf.put(sourceCodeData); - codeBuf.flip(); - - glShaderSource(id, codeBuf); - glCompileShader(id); - - glGetShader(id, GL_COMPILE_STATUS, intBuf1); - - boolean compiledOK = intBuf1.get(0) == GL_TRUE; - String infoLog = null; - - if (VALIDATE_SHADER || !compiledOK) { - // even if compile succeeded, check - // log for warnings - glGetShader(id, GL_INFO_LOG_LENGTH, intBuf1); - int length = intBuf1.get(0); - if (length > 3) { - // get infos - ByteBuffer logBuf = BufferUtils.createByteBuffer(length); - glGetShaderInfoLog(id, null, logBuf); - byte[] logBytes = new byte[length]; - logBuf.get(logBytes, 0, length); - // convert to string, etc - infoLog = new String(logBytes); - } - } - - if (compiledOK) { - if (infoLog != null) { - logger.log(Level.WARNING, "{0} compiled successfully, compiler warnings: \n{1}", - new Object[]{source.getName(), infoLog}); - } else { - logger.log(Level.FINE, "{0} compiled successfully.", source.getName()); - } - source.clearUpdateNeeded(); - } else { - logger.log(Level.WARNING, "Bad compile of:\n{0}", - new Object[]{ShaderDebug.formatShaderSource(stringBuf.toString() + source.getDefines() + source.getSource())}); - if (infoLog != null) { - throw new RendererException("compile error in: " + source + "\n" + infoLog); - } else { - throw new RendererException("compile error in: " + source + "\nerror: "); - } - } - } - - public void updateShaderData(Shader shader) { - int id = shader.getId(); - boolean needRegister = false; - if (id == -1) { - // create program - id = glCreateProgram(); - if (id == 0) { - throw new RendererException("Invalid ID (" + id + ") received when trying to create shader program."); - } - - shader.setId(id); - needRegister = true; - } - - for (ShaderSource source : shader.getSources()) { - if (source.isUpdateNeeded()) { - updateShaderSourceData(source); - } - glAttachShader(id, source.getId()); - } - - if (caps.contains(Caps.OpenGL30)) { - // Check if GLSL version is 1.5 for shader - GL30.glBindFragDataLocation(id, 0, "outFragColor"); - // For MRT - for (int i = 0; i < maxMRTFBOAttachs; i++) { - GL30.glBindFragDataLocation(id, i, "outFragData[" + i + "]"); - } - } - - // Link shaders to program - glLinkProgram(id); - - // Check link status - glGetProgram(id, GL_LINK_STATUS, intBuf1); - boolean linkOK = intBuf1.get(0) == GL_TRUE; - String infoLog = null; - - if (VALIDATE_SHADER || !linkOK) { - glGetProgram(id, GL_INFO_LOG_LENGTH, intBuf1); - int length = intBuf1.get(0); - if (length > 3) { - // get infos - ByteBuffer logBuf = BufferUtils.createByteBuffer(length); - glGetProgramInfoLog(id, null, logBuf); - - // convert to string, etc - byte[] logBytes = new byte[length]; - logBuf.get(logBytes, 0, length); - infoLog = new String(logBytes); - } - } - - if (linkOK) { - if (infoLog != null) { - logger.log(Level.WARNING, "Shader linked successfully. Linker warnings: \n{0}", infoLog); - } else { - logger.fine("Shader linked successfully."); - } - shader.clearUpdateNeeded(); - if (needRegister) { - // Register shader for clean up if it was created in this method. - objManager.registerObject(shader); - statistics.onNewShader(); - } else { - // OpenGL spec: uniform locations may change after re-link - resetUniformLocations(shader); - } - } else { - if (infoLog != null) { - throw new RendererException("Shader failed to link, shader:" + shader + "\n" + infoLog); - } else { - throw new RendererException("Shader failed to link, shader:" + shader + "\ninfo: "); - } - } - } - - public void setShader(Shader shader) { - if (shader == null) { - throw new IllegalArgumentException("Shader cannot be null"); - } else { - if (shader.isUpdateNeeded()) { - updateShaderData(shader); - } - - // NOTE: might want to check if any of the - // sources need an update? - - assert shader.getId() > 0; - - updateShaderUniforms(shader); - bindProgram(shader); - } - } - - public void deleteShaderSource(ShaderSource source) { - if (source.getId() < 0) { - logger.warning("Shader source is not uploaded to GPU, cannot delete."); - return; - } - source.clearUpdateNeeded(); - glDeleteShader(source.getId()); - source.resetObject(); - } - - public void deleteShader(Shader shader) { - if (shader.getId() == -1) { - logger.warning("Shader is not uploaded to GPU, cannot delete."); - return; - } - - for (ShaderSource source : shader.getSources()) { - if (source.getId() != -1) { - glDetachShader(shader.getId(), source.getId()); - deleteShaderSource(source); - } - } - - glDeleteProgram(shader.getId()); - statistics.onDeleteShader(); - shader.resetObject(); - } - - /*********************************************************************\ - |* Framebuffers *| - \*********************************************************************/ - public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst) { - copyFrameBuffer(src, dst, true); - } - - public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst, boolean copyDepth) { - if (caps.contains(Caps.FrameBufferBlit)) { - int srcX0 = 0; - int srcY0 = 0; - int srcX1; - int srcY1; - - int dstX0 = 0; - int dstY0 = 0; - int dstX1; - int dstY1; - - int prevFBO = context.boundFBO; - - if (mainFbOverride != null) { - if (src == null) { - src = mainFbOverride; - } - if (dst == null) { - dst = mainFbOverride; - } - } - - if (src != null && src.isUpdateNeeded()) { - updateFrameBuffer(src); - } - - if (dst != null && dst.isUpdateNeeded()) { - updateFrameBuffer(dst); - } - - if (src == null) { - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); - srcX0 = vpX; - srcY0 = vpY; - srcX1 = vpX + vpW; - srcY1 = vpY + vpH; - } else { - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, src.getId()); - srcX1 = src.getWidth(); - srcY1 = src.getHeight(); - } - if (dst == null) { - glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); - dstX0 = vpX; - dstY0 = vpY; - dstX1 = vpX + vpW; - dstY1 = vpY + vpH; - } else { - glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, dst.getId()); - dstX1 = dst.getWidth(); - dstY1 = dst.getHeight(); - } - int mask = GL_COLOR_BUFFER_BIT; - if (copyDepth) { - mask |= GL_DEPTH_BUFFER_BIT; - } - glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1, mask, - GL_NEAREST); - - - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, prevFBO); - try { - checkFrameBufferError(); - } catch (IllegalStateException ex) { - logger.log(Level.SEVERE, "Source FBO:\n{0}", src); - logger.log(Level.SEVERE, "Dest FBO:\n{0}", dst); - throw ex; - } - } else { - throw new RendererException("EXT_framebuffer_blit required."); - // TODO: support non-blit copies? - } - } - - private String getTargetBufferName(int buffer) { - switch (buffer) { - case GL_NONE: - return "NONE"; - case GL_FRONT: - return "GL_FRONT"; - case GL_BACK: - return "GL_BACK"; - default: - if (buffer >= GL_COLOR_ATTACHMENT0_EXT - && buffer <= GL_COLOR_ATTACHMENT15_EXT) { - return "GL_COLOR_ATTACHMENT" - + (buffer - GL_COLOR_ATTACHMENT0_EXT); - } else { - return "UNKNOWN? " + buffer; - } - } - } - - private void printRealRenderBufferInfo(FrameBuffer fb, RenderBuffer rb, String name) { - System.out.println("== Renderbuffer " + name + " =="); - System.out.println("RB ID: " + rb.getId()); - System.out.println("Is proper? " + glIsRenderbufferEXT(rb.getId())); - - int attachment = convertAttachmentSlot(rb.getSlot()); - - int type = glGetFramebufferAttachmentParameteriEXT(GL_DRAW_FRAMEBUFFER_EXT, - attachment, - GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT); - - int rbName = glGetFramebufferAttachmentParameteriEXT(GL_DRAW_FRAMEBUFFER_EXT, - attachment, - GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT); - - switch (type) { - case GL_NONE: - System.out.println("Type: None"); - break; - case GL_TEXTURE: - System.out.println("Type: Texture"); - break; - case GL_RENDERBUFFER_EXT: - System.out.println("Type: Buffer"); - System.out.println("RB ID: " + rbName); - break; - } - - - - } - - private void printRealFrameBufferInfo(FrameBuffer fb) { - boolean doubleBuffer = glGetBoolean(GL_DOUBLEBUFFER); - String drawBuf = getTargetBufferName(glGetInteger(GL_DRAW_BUFFER)); - String readBuf = getTargetBufferName(glGetInteger(GL_READ_BUFFER)); - - int fbId = fb.getId(); - int curDrawBinding = glGetInteger(GL_DRAW_FRAMEBUFFER_BINDING_EXT); - int curReadBinding = glGetInteger(GL_READ_FRAMEBUFFER_BINDING_EXT); - - System.out.println("=== OpenGL FBO State ==="); - System.out.println("Context doublebuffered? " + doubleBuffer); - System.out.println("FBO ID: " + fbId); - System.out.println("Is proper? " + glIsFramebufferEXT(fbId)); - System.out.println("Is bound to draw? " + (fbId == curDrawBinding)); - System.out.println("Is bound to read? " + (fbId == curReadBinding)); - System.out.println("Draw buffer: " + drawBuf); - System.out.println("Read buffer: " + readBuf); - - if (context.boundFBO != fbId) { - glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fbId); - context.boundFBO = fbId; - } - - if (fb.getDepthBuffer() != null) { - printRealRenderBufferInfo(fb, fb.getDepthBuffer(), "Depth"); - } - for (int i = 0; i < fb.getNumColorBuffers(); i++) { - printRealRenderBufferInfo(fb, fb.getColorBuffer(i), "Color" + i); - } - } - - private void checkFrameBufferError() { - int status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - switch (status) { - case GL_FRAMEBUFFER_COMPLETE_EXT: - break; - case GL_FRAMEBUFFER_UNSUPPORTED_EXT: - //Choose different formats - throw new IllegalStateException("Framebuffer object format is " - + "unsupported by the video hardware."); - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: - throw new IllegalStateException("Framebuffer has erronous attachment."); - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: - throw new IllegalStateException("Framebuffer doesn't have any renderbuffers attached."); - case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: - throw new IllegalStateException("Framebuffer attachments must have same dimensions."); - case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: - throw new IllegalStateException("Framebuffer attachments must have same formats."); - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: - throw new IllegalStateException("Incomplete draw buffer."); - case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: - throw new IllegalStateException("Incomplete read buffer."); - case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT: - throw new IllegalStateException("Incomplete multisample buffer."); - default: - //Programming error; will fail on all hardware - throw new IllegalStateException("Some video driver error " - + "or programming error occured. " - + "Framebuffer object status is invalid. "); - } - } - - private void updateRenderBuffer(FrameBuffer fb, RenderBuffer rb) { - int id = rb.getId(); - if (id == -1) { - glGenRenderbuffersEXT(intBuf1); - id = intBuf1.get(0); - rb.setId(id); - } - - if (context.boundRB != id) { - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, id); - context.boundRB = id; - } - - if (fb.getWidth() > maxRBSize || fb.getHeight() > maxRBSize) { - throw new RendererException("Resolution " + fb.getWidth() - + ":" + fb.getHeight() + " is not supported."); - } - - TextureUtil.GLImageFormat glFmt = TextureUtil.getImageFormatWithError(caps, rb.getFormat(), fb.isSrgb()); - - if (fb.getSamples() > 1 && caps.contains(Caps.FrameBufferMultisample)) { - int samples = fb.getSamples(); - if (maxFBOSamples < samples) { - samples = maxFBOSamples; - } - glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, - samples, - glFmt.internalFormat, - fb.getWidth(), - fb.getHeight()); - } else { - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, - glFmt.internalFormat, - fb.getWidth(), - fb.getHeight()); - } - } - - private int convertAttachmentSlot(int attachmentSlot) { - // can also add support for stencil here - if (attachmentSlot == FrameBuffer.SLOT_DEPTH) { - return GL_DEPTH_ATTACHMENT_EXT; - } else if (attachmentSlot == FrameBuffer.SLOT_DEPTH_STENCIL) { - // NOTE: Using depth stencil format requires GL3, this is already - // checked via render caps. - return GL30.GL_DEPTH_STENCIL_ATTACHMENT; - } else if (attachmentSlot < 0 || attachmentSlot >= 16) { - throw new UnsupportedOperationException("Invalid FBO attachment slot: " + attachmentSlot); - } - - return GL_COLOR_ATTACHMENT0_EXT + attachmentSlot; - } - - public void updateRenderTexture(FrameBuffer fb, RenderBuffer rb) { - Texture tex = rb.getTexture(); - Image image = tex.getImage(); - if (image.isUpdateNeeded()) { - updateTexImageData(image, tex.getType(), 0); - - // NOTE: For depth textures, sets nearest/no-mips mode - // Required to fix "framebuffer unsupported" - // for old NVIDIA drivers! - setupTextureParams(tex); - } - - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, - convertAttachmentSlot(rb.getSlot()), - convertTextureType(tex.getType(), image.getMultiSamples(), rb.getFace()), - image.getId(), - 0); - } - - public void updateFrameBufferAttachment(FrameBuffer fb, RenderBuffer rb) { - boolean needAttach; - if (rb.getTexture() == null) { - // if it hasn't been created yet, then attach is required. - needAttach = rb.getId() == -1; - updateRenderBuffer(fb, rb); - } else { - needAttach = false; - updateRenderTexture(fb, rb); - } - if (needAttach) { - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, - convertAttachmentSlot(rb.getSlot()), - GL_RENDERBUFFER_EXT, - rb.getId()); - } - } - - public void updateFrameBuffer(FrameBuffer fb) { - int id = fb.getId(); - if (id == -1) { - // create FBO - glGenFramebuffersEXT(intBuf1); - id = intBuf1.get(0); - fb.setId(id); - objManager.registerObject(fb); - - statistics.onNewFrameBuffer(); - } - - if (context.boundFBO != id) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id); - // binding an FBO automatically sets draw buf to GL_COLOR_ATTACHMENT0 - context.boundDrawBuf = 0; - context.boundFBO = id; - } - - FrameBuffer.RenderBuffer depthBuf = fb.getDepthBuffer(); - if (depthBuf != null) { - updateFrameBufferAttachment(fb, depthBuf); - } - - for (int i = 0; i < fb.getNumColorBuffers(); i++) { - FrameBuffer.RenderBuffer colorBuf = fb.getColorBuffer(i); - updateFrameBufferAttachment(fb, colorBuf); - } - - fb.clearUpdateNeeded(); - } - - public Vector2f[] getFrameBufferSamplePositions(FrameBuffer fb) { - if (fb.getSamples() <= 1) { - throw new IllegalArgumentException("Framebuffer must be multisampled"); - } - if (!caps.contains(Caps.TextureMultisample)) { - throw new RendererException("Multisampled textures are not supported"); - } - - setFrameBuffer(fb); - - Vector2f[] samplePositions = new Vector2f[fb.getSamples()]; - FloatBuffer samplePos = BufferUtils.createFloatBuffer(2); - for (int i = 0; i < samplePositions.length; i++) { - glGetMultisample(GL_SAMPLE_POSITION, i, samplePos); - samplePos.clear(); - samplePositions[i] = new Vector2f(samplePos.get(0) - 0.5f, - samplePos.get(1) - 0.5f); - } - return samplePositions; - } - - public void setMainFrameBufferOverride(FrameBuffer fb) { - mainFbOverride = fb; - } - - public void setFrameBuffer(FrameBuffer fb) { - if (!caps.contains(Caps.FrameBuffer)) { - throw new RendererException("Framebuffer objects are not supported" + - " by the video hardware"); - } - - if (fb == null && mainFbOverride != null) { - fb = mainFbOverride; - } - - if (context.boundFB == fb) { - if (fb == null || !fb.isUpdateNeeded()) { - return; - } - } - - // generate mipmaps for last FB if needed - if (context.boundFB != null) { - for (int i = 0; i < context.boundFB.getNumColorBuffers(); i++) { - RenderBuffer rb = context.boundFB.getColorBuffer(i); - Texture tex = rb.getTexture(); - if (tex != null - && tex.getMinFilter().usesMipMapLevels()) { - setTexture(0, rb.getTexture()); - - int textureType = convertTextureType(tex.getType(), tex.getImage().getMultiSamples(), rb.getFace()); - glEnable(textureType); - glGenerateMipmapEXT(textureType); - glDisable(textureType); - } - } - } - - if (fb == null) { - // unbind any fbos - if (context.boundFBO != 0) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - statistics.onFrameBufferUse(null, true); - - context.boundFBO = 0; - } - // select back buffer - if (context.boundDrawBuf != -1) { - glDrawBuffer(context.initialDrawBuf); - context.boundDrawBuf = -1; - } - if (context.boundReadBuf != -1) { - glReadBuffer(context.initialReadBuf); - context.boundReadBuf = -1; - } - - context.boundFB = null; - } else { - if (fb.getNumColorBuffers() == 0 && fb.getDepthBuffer() == null) { - throw new IllegalArgumentException("The framebuffer: " + fb - + "\nDoesn't have any color/depth buffers"); - } - - if (fb.isUpdateNeeded()) { - updateFrameBuffer(fb); - } - - if (context.boundFBO != fb.getId()) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb.getId()); - statistics.onFrameBufferUse(fb, true); - - // update viewport to reflect framebuffer's resolution - setViewPort(0, 0, fb.getWidth(), fb.getHeight()); - - context.boundFBO = fb.getId(); - } else { - statistics.onFrameBufferUse(fb, false); - } - if (fb.getNumColorBuffers() == 0) { - // make sure to select NONE as draw buf - // no color buffer attached. select NONE - if (context.boundDrawBuf != -2) { - glDrawBuffer(GL_NONE); - context.boundDrawBuf = -2; - } - if (context.boundReadBuf != -2) { - glReadBuffer(GL_NONE); - context.boundReadBuf = -2; - } - } else { - if (fb.getNumColorBuffers() > maxFBOAttachs) { - throw new RendererException("Framebuffer has more color " - + "attachments than are supported" - + " by the video hardware!"); - } - if (fb.isMultiTarget()) { - if (fb.getNumColorBuffers() > maxMRTFBOAttachs) { - throw new RendererException("Framebuffer has more" - + " multi targets than are supported" - + " by the video hardware!"); - } - - if (context.boundDrawBuf != 100 + fb.getNumColorBuffers()) { - intBuf16.clear(); - for (int i = 0; i < fb.getNumColorBuffers(); i++) { - intBuf16.put(GL_COLOR_ATTACHMENT0_EXT + i); - } - - intBuf16.flip(); - glDrawBuffers(intBuf16); - context.boundDrawBuf = 100 + fb.getNumColorBuffers(); - } - } else { - RenderBuffer rb = fb.getColorBuffer(fb.getTargetIndex()); - // select this draw buffer - if (context.boundDrawBuf != rb.getSlot()) { - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + rb.getSlot()); - context.boundDrawBuf = rb.getSlot(); - } - } - } - - assert fb.getId() >= 0; - assert context.boundFBO == fb.getId(); - - context.boundFB = fb; - - try { - checkFrameBufferError(); - } catch (IllegalStateException ex) { - logger.log(Level.SEVERE, "=== jMonkeyEngine FBO State ===\n{0}", fb); - printRealFrameBufferInfo(fb); - throw ex; - } - } - } - - public void readFrameBuffer(FrameBuffer fb, ByteBuffer byteBuf) { - if (fb != null) { - RenderBuffer rb = fb.getColorBuffer(); - if (rb == null) { - throw new IllegalArgumentException("Specified framebuffer" - + " does not have a colorbuffer"); - } - - setFrameBuffer(fb); - if (context.boundReadBuf != rb.getSlot()) { - glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + rb.getSlot()); - context.boundReadBuf = rb.getSlot(); - } - } else { - setFrameBuffer(null); - } - - glReadPixels(vpX, vpY, vpW, vpH, /*GL_RGBA*/ GL_BGRA, GL_UNSIGNED_BYTE, byteBuf); - } - - private void deleteRenderBuffer(FrameBuffer fb, RenderBuffer rb) { - intBuf1.put(0, rb.getId()); - glDeleteRenderbuffersEXT(intBuf1); - } - - public void deleteFrameBuffer(FrameBuffer fb) { - if (fb.getId() != -1) { - if (context.boundFBO == fb.getId()) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - context.boundFBO = 0; - } - - if (fb.getDepthBuffer() != null) { - deleteRenderBuffer(fb, fb.getDepthBuffer()); - } - if (fb.getColorBuffer() != null) { - deleteRenderBuffer(fb, fb.getColorBuffer()); - } - - intBuf1.put(0, fb.getId()); - glDeleteFramebuffersEXT(intBuf1); - fb.resetObject(); - - statistics.onDeleteFrameBuffer(); - } - } - - /*********************************************************************\ - |* Textures *| - \*********************************************************************/ - private int convertTextureType(Texture.Type type, int samples, int face) { - if (samples > 1 && !caps.contains(Caps.TextureMultisample)) { - throw new RendererException("Multisample textures are not supported" + - " by the video hardware."); - } - - switch (type) { - case TwoDimensional: - if (samples > 1) { - return GL_TEXTURE_2D_MULTISAMPLE; - } else { - return GL_TEXTURE_2D; - } - case TwoDimensionalArray: - if (samples > 1) { - return GL_TEXTURE_2D_MULTISAMPLE_ARRAY; - } else { - return GL_TEXTURE_2D_ARRAY_EXT; - } - case ThreeDimensional: - return GL_TEXTURE_3D; - case CubeMap: - if (face < 0) { - return GL_TEXTURE_CUBE_MAP; - } else if (face < 6) { - return GL_TEXTURE_CUBE_MAP_POSITIVE_X + face; - } else { - throw new UnsupportedOperationException("Invalid cube map face index: " + face); - } - default: - throw new UnsupportedOperationException("Unknown texture type: " + type); - } - } - - private int convertMagFilter(Texture.MagFilter filter) { - switch (filter) { - case Bilinear: - return GL_LINEAR; - case Nearest: - return GL_NEAREST; - default: - throw new UnsupportedOperationException("Unknown mag filter: " + filter); - } - } - - private int convertMinFilter(Texture.MinFilter filter, boolean haveMips) { - if (haveMips){ - switch (filter) { - case Trilinear: - return GL_LINEAR_MIPMAP_LINEAR; - case BilinearNearestMipMap: - return GL_LINEAR_MIPMAP_NEAREST; - case NearestLinearMipMap: - return GL_NEAREST_MIPMAP_LINEAR; - case NearestNearestMipMap: - return GL_NEAREST_MIPMAP_NEAREST; - case BilinearNoMipMaps: - return GL_LINEAR; - case NearestNoMipMaps: - return GL_NEAREST; - default: - throw new UnsupportedOperationException("Unknown min filter: " + filter); - } - } else { - switch (filter) { - case Trilinear: - case BilinearNearestMipMap: - case BilinearNoMipMaps: - return GL_LINEAR; - case NearestLinearMipMap: - case NearestNearestMipMap: - case NearestNoMipMaps: - return GL_NEAREST; - default: - throw new UnsupportedOperationException("Unknown min filter: " + filter); - } - } - } - - private int convertWrapMode(Texture.WrapMode mode) { - switch (mode) { - case BorderClamp: - return GL_CLAMP_TO_BORDER; - case Clamp: - // Falldown intentional. - case EdgeClamp: - return GL_CLAMP_TO_EDGE; - case Repeat: - return GL_REPEAT; - case MirroredRepeat: - return GL_MIRRORED_REPEAT; - default: - throw new UnsupportedOperationException("Unknown wrap mode: " + mode); - } - } - - @SuppressWarnings("fallthrough") - private void setupTextureParams(Texture tex) { - Image image = tex.getImage(); - int target = convertTextureType(tex.getType(), image != null ? image.getMultiSamples() : 1, -1); - - boolean haveMips = true; - - if (image != null) { - haveMips = image.isGeneratedMipmapsRequired() || image.hasMipmaps(); - } - - // filter things - int minFilter = convertMinFilter(tex.getMinFilter(), haveMips); - int magFilter = convertMagFilter(tex.getMagFilter()); - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilter); - glTexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilter); - - if (tex.getAnisotropicFilter() > 1) { - if (caps.contains(Caps.TextureFilterAnisotropic)) { - glTexParameterf(target, - GL_TEXTURE_MAX_ANISOTROPY_EXT, - tex.getAnisotropicFilter()); - } - } - - if (context.pointSprite) { - return; // Attempt to fix glTexParameter crash for some ATI GPUs - } - - // repeat modes - switch (tex.getType()) { - case ThreeDimensional: - case CubeMap: // cubemaps use 3D coords - glTexParameteri(target, GL_TEXTURE_WRAP_R, convertWrapMode(tex.getWrap(WrapAxis.R))); - //There is no break statement on purpose here - case TwoDimensional: - case TwoDimensionalArray: - glTexParameteri(target, GL_TEXTURE_WRAP_T, convertWrapMode(tex.getWrap(WrapAxis.T))); - // fall down here is intentional.. -// case OneDimensional: - glTexParameteri(target, GL_TEXTURE_WRAP_S, convertWrapMode(tex.getWrap(WrapAxis.S))); - break; - default: - throw new UnsupportedOperationException("Unknown texture type: " + tex.getType()); - } - - if(tex.isNeedCompareModeUpdate()){ - // R to Texture compare mode - if (tex.getShadowCompareMode() != Texture.ShadowCompareMode.Off) { - glTexParameteri(target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); - glTexParameteri(target, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY); - if (tex.getShadowCompareMode() == Texture.ShadowCompareMode.GreaterOrEqual) { - glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC, GL_GEQUAL); - } else { - glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); - } - }else{ - //restoring default value - glTexParameteri(target, GL_TEXTURE_COMPARE_MODE, GL_NONE); - } - tex.compareModeUpdated(); - } - } - - /** - * Uploads the given image to the GL driver. - * - * @param img The image to upload - * @param type How the data in the image argument should be interpreted. - * @param unit The texture slot to be used to upload the image, not important - */ - public void updateTexImageData(Image img, Texture.Type type, int unit) { - int texId = img.getId(); - if (texId == -1) { - // create texture - glGenTextures(intBuf1); - texId = intBuf1.get(0); - img.setId(texId); - objManager.registerObject(img); - - statistics.onNewTexture(); - } - - // bind texture - int target = convertTextureType(type, img.getMultiSamples(), -1); - if (context.boundTextureUnit != unit) { - glActiveTexture(GL_TEXTURE0 + unit); - context.boundTextureUnit = unit; - } - if (context.boundTextures[unit] != img) { - glBindTexture(target, texId); - context.boundTextures[unit] = img; - - statistics.onTextureUse(img, true); - } - - if (!img.hasMipmaps() && img.isGeneratedMipmapsRequired()) { - // Image does not have mipmaps, but they are required. - // Generate from base level. - - if (!caps.contains(Caps.OpenGL30) && !caps.contains(Caps.OpenGLES20)) { - glTexParameteri(target, GL_GENERATE_MIPMAP, GL_TRUE); - img.setMipmapsGenerated(true); - } else { - // For OpenGL3 and up. - // We'll generate mipmaps via glGenerateMipmapEXT (see below) - } - } else if (img.hasMipmaps()) { - // Image already has mipmaps, set the max level based on the - // number of mipmaps we have. - glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, img.getMipMapSizes().length - 1); - } else { - // Image does not have mipmaps and they are not required. - // Specify that that the texture has no mipmaps. - glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, 0); - } - - int imageSamples = img.getMultiSamples(); - if (imageSamples > 1) { - if (img.getFormat().isDepthFormat()) { - img.setMultiSamples(Math.min(maxDepthTexSamples, imageSamples)); - } else { - img.setMultiSamples(Math.min(maxColorTexSamples, imageSamples)); - } - } - - // Yes, some OpenGL2 cards (GeForce 5) still dont support NPOT. - if (!caps.contains(Caps.NonPowerOfTwoTextures) && img.isNPOT()) { - if (img.getData(0) == null) { - throw new RendererException("non-power-of-2 framebuffer textures are not supported by the video hardware"); - } else { - MipMapGenerator.resizeToPowerOf2(img); - } - } - - // Check if graphics card doesn't support multisample textures - if (!caps.contains(Caps.TextureMultisample)) { - if (img.getMultiSamples() > 1) { - throw new RendererException("Multisample textures not supported by graphics hardware"); - } - } - - if (target == GL_TEXTURE_CUBE_MAP) { - // Check max texture size before upload - if (img.getWidth() > maxCubeTexSize || img.getHeight() > maxCubeTexSize) { - throw new RendererException("Cannot upload cubemap " + img + ". The maximum supported cubemap resolution is " + maxCubeTexSize); - } - if (img.getWidth() != img.getHeight()) { - throw new RendererException("Cubemaps must have square dimensions"); - } - } else { - if (img.getWidth() > maxTexSize || img.getHeight() > maxTexSize) { - throw new RendererException("Cannot upload texture " + img + ". The maximum supported texture resolution is " + maxTexSize); - } - } - - if (target == GL_TEXTURE_CUBE_MAP) { - List data = img.getData(); - if (data.size() != 6) { - logger.log(Level.WARNING, "Invalid texture: {0}\n" - + "Cubemap textures must contain 6 data units.", img); - return; - } - for (int i = 0; i < 6; i++) { - TextureUtil.uploadTexture(caps, img, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, i, 0, linearizeSrgbImages); - } - } else if (target == GL_TEXTURE_2D_ARRAY_EXT) { - if (!caps.contains(Caps.TextureArray)) { - throw new RendererException("Texture arrays not supported by graphics hardware"); - } - - List data = img.getData(); - - // -1 index specifies prepare data for 2D Array - TextureUtil.uploadTexture(caps, img, target, -1, 0, linearizeSrgbImages); - - for (int i = 0; i < data.size(); i++) { - // upload each slice of 2D array in turn - // this time with the appropriate index - TextureUtil.uploadTexture(caps, img, target, i, 0, linearizeSrgbImages); - } - } else { - TextureUtil.uploadTexture(caps, img, target, 0, 0, linearizeSrgbImages); - } - - if (img.getMultiSamples() != imageSamples) { - img.setMultiSamples(imageSamples); - } - - if (caps.contains(Caps.OpenGL30)) { - if (!img.hasMipmaps() && img.isGeneratedMipmapsRequired() && img.getData() != null) { - // XXX: Required for ATI - glEnable(target); - glGenerateMipmapEXT(target); - glDisable(target); - img.setMipmapsGenerated(true); - } - } - - img.clearUpdateNeeded(); - } - - public void setTexture(int unit, Texture tex) { - Image image = tex.getImage(); - if (image.isUpdateNeeded() || (image.isGeneratedMipmapsRequired() && !image.isMipmapsGenerated())) { - updateTexImageData(image, tex.getType(), unit); - } - - int texId = image.getId(); - assert texId != -1; - - Image[] textures = context.boundTextures; - - int type = convertTextureType(tex.getType(), image.getMultiSamples(), -1); -// if (!context.textureIndexList.moveToNew(unit)) { -// if (context.boundTextureUnit != unit){ -// glActiveTexture(GL_TEXTURE0 + unit); -// context.boundTextureUnit = unit; -// } -// glEnable(type); -// } - - if (context.boundTextureUnit != unit) { - glActiveTexture(GL_TEXTURE0 + unit); - context.boundTextureUnit = unit; - } - if (textures[unit] != image) { - glBindTexture(type, texId); - textures[unit] = image; - - statistics.onTextureUse(image, true); - } else { - statistics.onTextureUse(image, false); - } - - setupTextureParams(tex); - } - - public void modifyTexture(Texture tex, Image pixels, int x, int y) { - setTexture(0, tex); - TextureUtil.uploadSubTexture(caps, pixels, convertTextureType(tex.getType(), pixels.getMultiSamples(), -1), 0, x, y, linearizeSrgbImages); - } - - public void clearTextureUnits() { -// IDList textureList = context.textureIndexList; -// Image[] textures = context.boundTextures; -// for (int i = 0; i < textureList.oldLen; i++) { -// int idx = textureList.oldList[i]; -// if (context.boundTextureUnit != idx){ -// glActiveTexture(GL_TEXTURE0 + idx); -// context.boundTextureUnit = idx; -// } -// glDisable(convertTextureType(textures[idx].getType())); -// textures[idx] = null; -// } -// context.textureIndexList.copyNewToOld(); - } - - public void deleteImage(Image image) { - int texId = image.getId(); - if (texId != -1) { - intBuf1.put(0, texId); - intBuf1.position(0).limit(1); - glDeleteTextures(intBuf1); - image.resetObject(); - - statistics.onDeleteTexture(); - } - } - - /*********************************************************************\ - |* Vertex Buffers and Attributes *| - \*********************************************************************/ - private int convertUsage(Usage usage) { - switch (usage) { - case Static: - return GL_STATIC_DRAW; - case Dynamic: - return GL_DYNAMIC_DRAW; - case Stream: - return GL_STREAM_DRAW; - default: - throw new UnsupportedOperationException("Unknown usage type."); - } - } - - private int convertFormat(Format format) { - switch (format) { - case Byte: - return GL_BYTE; - case UnsignedByte: - return GL_UNSIGNED_BYTE; - case Short: - return GL_SHORT; - case UnsignedShort: - return GL_UNSIGNED_SHORT; - case Int: - return GL_INT; - case UnsignedInt: - return GL_UNSIGNED_INT; - case Float: - return GL_FLOAT; - case Double: - return GL_DOUBLE; - default: - throw new UnsupportedOperationException("Unknown buffer format."); - - } - } - - public void updateBufferData(VertexBuffer vb) { - int bufId = vb.getId(); - boolean created = false; - if (bufId == -1) { - // create buffer - glGenBuffers(intBuf1); - bufId = intBuf1.get(0); - vb.setId(bufId); - objManager.registerObject(vb); - - //statistics.onNewVertexBuffer(); - - created = true; - } - - // bind buffer - int target; - if (vb.getBufferType() == VertexBuffer.Type.Index) { - target = GL_ELEMENT_ARRAY_BUFFER; - if (context.boundElementArrayVBO != bufId) { - glBindBuffer(target, bufId); - context.boundElementArrayVBO = bufId; - //statistics.onVertexBufferUse(vb, true); - } else { - //statistics.onVertexBufferUse(vb, false); - } - } else { - target = GL_ARRAY_BUFFER; - if (context.boundArrayVBO != bufId) { - glBindBuffer(target, bufId); - context.boundArrayVBO = bufId; - //statistics.onVertexBufferUse(vb, true); - } else { - //statistics.onVertexBufferUse(vb, false); - } - } - - int usage = convertUsage(vb.getUsage()); - vb.getData().rewind(); - - if (created || vb.hasDataSizeChanged()) { - // upload data based on format - switch (vb.getFormat()) { - case Byte: - case UnsignedByte: - glBufferData(target, (ByteBuffer) vb.getData(), usage); - break; - // case Half: - case Short: - case UnsignedShort: - glBufferData(target, (ShortBuffer) vb.getData(), usage); - break; - case Int: - case UnsignedInt: - glBufferData(target, (IntBuffer) vb.getData(), usage); - break; - case Float: - glBufferData(target, (FloatBuffer) vb.getData(), usage); - break; - case Double: - glBufferData(target, (DoubleBuffer) vb.getData(), usage); - break; - default: - throw new UnsupportedOperationException("Unknown buffer format."); - } - } else { - // Invalidate buffer data (orphan) before uploading new data. - - - switch (vb.getFormat()) { - case Byte: - case UnsignedByte: - glBufferSubData(target, 0, (ByteBuffer) vb.getData()); - break; - case Short: - case UnsignedShort: - glBufferSubData(target, 0, (ShortBuffer) vb.getData()); - break; - case Int: - case UnsignedInt: - glBufferSubData(target, 0, (IntBuffer) vb.getData()); - break; - case Float: - glBufferSubData(target, 0, (FloatBuffer) vb.getData()); - break; - case Double: - glBufferSubData(target, 0, (DoubleBuffer) vb.getData()); - break; - default: - throw new UnsupportedOperationException("Unknown buffer format."); - } - } - - vb.clearUpdateNeeded(); - } - - public void deleteBuffer(VertexBuffer vb) { - int bufId = vb.getId(); - if (bufId != -1) { - // delete buffer - intBuf1.put(0, bufId); - intBuf1.position(0).limit(1); - glDeleteBuffers(intBuf1); - vb.resetObject(); - - //statistics.onDeleteVertexBuffer(); - } - } - - public void clearVertexAttribs() { - IDList attribList = context.attribIndexList; - for (int i = 0; i < attribList.oldLen; i++) { - int idx = attribList.oldList[i]; - glDisableVertexAttribArray(idx); - if (context.boundAttribs[idx].isInstanced()) { - glVertexAttribDivisorARB(idx, 0); - } - context.boundAttribs[idx] = null; - } - context.attribIndexList.copyNewToOld(); - } - - public void setVertexAttrib(VertexBuffer vb, VertexBuffer idb) { - if (vb.getBufferType() == VertexBuffer.Type.Index) { - throw new IllegalArgumentException("Index buffers not allowed to be set to vertex attrib"); - } - - int programId = context.boundShaderProgram; - - if (programId > 0) { - Attribute attrib = context.boundShader.getAttribute(vb.getBufferType()); - int loc = attrib.getLocation(); - if (loc == -1) { - return; // not defined - } - if (loc == -2) { - stringBuf.setLength(0); - stringBuf.append("in").append(vb.getBufferType().name()).append('\0'); - updateNameBuffer(); - loc = glGetAttribLocation(programId, nameBuf); - - // not really the name of it in the shader (inPosition\0) but - // the internal name of the enum (Position). - if (loc < 0) { - attrib.setLocation(-1); - return; // not available in shader. - } else { - attrib.setLocation(loc); - } - } - - if (vb.isInstanced()) { - if (!caps.contains(Caps.MeshInstancing)) { - throw new RendererException("Instancing is required, " - + "but not supported by the " - + "graphics hardware"); - } - } - int slotsRequired = 1; - if (vb.getNumComponents() > 4) { - if (vb.getNumComponents() % 4 != 0) { - throw new RendererException("Number of components in multi-slot " - + "buffers must be divisible by 4"); - } - slotsRequired = vb.getNumComponents() / 4; - } - - if (vb.isUpdateNeeded() && idb == null) { - updateBufferData(vb); - } - - VertexBuffer[] attribs = context.boundAttribs; - for (int i = 0; i < slotsRequired; i++) { - if (!context.attribIndexList.moveToNew(loc + i)) { - glEnableVertexAttribArray(loc + i); - //System.out.println("Enabled ATTRIB IDX: "+loc); - } - } - if (attribs[loc] != vb) { - // NOTE: Use id from interleaved buffer if specified - int bufId = idb != null ? idb.getId() : vb.getId(); - assert bufId != -1; - if (context.boundArrayVBO != bufId) { - glBindBuffer(GL_ARRAY_BUFFER, bufId); - context.boundArrayVBO = bufId; - //statistics.onVertexBufferUse(vb, true); - } else { - //statistics.onVertexBufferUse(vb, false); - } - - if (slotsRequired == 1) { - glVertexAttribPointer(loc, - vb.getNumComponents(), - convertFormat(vb.getFormat()), - vb.isNormalized(), - vb.getStride(), - vb.getOffset()); - } else { - for (int i = 0; i < slotsRequired; i++) { - // The pointer maps the next 4 floats in the slot. - // E.g. - // P1: XXXX____________XXXX____________ - // P2: ____XXXX____________XXXX________ - // P3: ________XXXX____________XXXX____ - // P4: ____________XXXX____________XXXX - // stride = 4 bytes in float * 4 floats in slot * num slots - // offset = 4 bytes in float * 4 floats in slot * slot index - glVertexAttribPointer(loc + i, - 4, - convertFormat(vb.getFormat()), - vb.isNormalized(), - 4 * 4 * slotsRequired, - 4 * 4 * i); - } - } - - for (int i = 0; i < slotsRequired; i++) { - int slot = loc + i; - if (vb.isInstanced() && (attribs[slot] == null || !attribs[slot].isInstanced())) { - // non-instanced -> instanced - glVertexAttribDivisorARB(slot, vb.getInstanceSpan()); - } else if (!vb.isInstanced() && attribs[slot] != null && attribs[slot].isInstanced()) { - // instanced -> non-instanced - glVertexAttribDivisorARB(slot, 0); - } - attribs[slot] = vb; - } - } - } else { - throw new IllegalStateException("Cannot render mesh without shader bound"); - } - } - - public void setVertexAttrib(VertexBuffer vb) { - setVertexAttrib(vb, null); - } - - public void drawTriangleArray(Mesh.Mode mode, int count, int vertCount) { - boolean useInstancing = count > 1 && caps.contains(Caps.MeshInstancing); - if (useInstancing) { - glDrawArraysInstancedARB(convertElementMode(mode), 0, - vertCount, count); - } else { - glDrawArrays(convertElementMode(mode), 0, vertCount); - } - } - - public void drawTriangleList(VertexBuffer indexBuf, Mesh mesh, int count) { - if (indexBuf.getBufferType() != VertexBuffer.Type.Index) { - throw new IllegalArgumentException("Only index buffers are allowed as triangle lists."); - } - - if (indexBuf.isUpdateNeeded()) { - updateBufferData(indexBuf); - } - - int bufId = indexBuf.getId(); - assert bufId != -1; - - if (context.boundElementArrayVBO != bufId) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufId); - context.boundElementArrayVBO = bufId; - //statistics.onVertexBufferUse(indexBuf, true); - } else { - //statistics.onVertexBufferUse(indexBuf, true); - } - - int vertCount = mesh.getVertexCount(); - boolean useInstancing = count > 1 && caps.contains(Caps.MeshInstancing); - - if (mesh.getMode() == Mode.Hybrid) { - int[] modeStart = mesh.getModeStart(); - int[] elementLengths = mesh.getElementLengths(); - - int elMode = convertElementMode(Mode.Triangles); - int fmt = convertFormat(indexBuf.getFormat()); - int elSize = indexBuf.getFormat().getComponentSize(); - int listStart = modeStart[0]; - int stripStart = modeStart[1]; - int fanStart = modeStart[2]; - int curOffset = 0; - for (int i = 0; i < elementLengths.length; i++) { - if (i == stripStart) { - elMode = convertElementMode(Mode.TriangleStrip); - } else if (i == fanStart) { - elMode = convertElementMode(Mode.TriangleFan); - } - int elementLength = elementLengths[i]; - - if (useInstancing) { - glDrawElementsInstancedARB(elMode, - elementLength, - fmt, - curOffset, - count); - } else { - glDrawRangeElements(elMode, - 0, - vertCount, - elementLength, - fmt, - curOffset); - } - - curOffset += elementLength * elSize; - } - } else { - if (useInstancing) { - glDrawElementsInstancedARB(convertElementMode(mesh.getMode()), - indexBuf.getData().limit(), - convertFormat(indexBuf.getFormat()), - 0, - count); - } else { - glDrawRangeElements(convertElementMode(mesh.getMode()), - 0, - vertCount, - indexBuf.getData().limit(), - convertFormat(indexBuf.getFormat()), - 0); - } - } - } - - /*********************************************************************\ - |* Render Calls *| - \*********************************************************************/ - public int convertElementMode(Mesh.Mode mode) { - switch (mode) { - case Points: - return GL_POINTS; - case Lines: - return GL_LINES; - case LineLoop: - return GL_LINE_LOOP; - case LineStrip: - return GL_LINE_STRIP; - case Triangles: - return GL_TRIANGLES; - case TriangleFan: - return GL_TRIANGLE_FAN; - case TriangleStrip: - return GL_TRIANGLE_STRIP; - default: - throw new UnsupportedOperationException("Unrecognized mesh mode: " + mode); - } - } - - public void updateVertexArray(Mesh mesh, VertexBuffer instanceData) { - int id = mesh.getId(); - if (id == -1) { - IntBuffer temp = intBuf1; - glGenVertexArrays(temp); - id = temp.get(0); - mesh.setId(id); - } - - if (context.boundVertexArray != id) { - glBindVertexArray(id); - context.boundVertexArray = id; - } - - VertexBuffer interleavedData = mesh.getBuffer(Type.InterleavedData); - if (interleavedData != null && interleavedData.isUpdateNeeded()) { - updateBufferData(interleavedData); - } - - if (instanceData != null) { - setVertexAttrib(instanceData, null); - } - - for (VertexBuffer vb : mesh.getBufferList().getArray()) { - if (vb.getBufferType() == Type.InterleavedData - || vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers - || vb.getBufferType() == Type.Index) { - continue; - } - - if (vb.getStride() == 0) { - // not interleaved - setVertexAttrib(vb); - } else { - // interleaved - setVertexAttrib(vb, interleavedData); - } - } - } - - private void renderMeshVertexArray(Mesh mesh, int lod, int count, VertexBuffer instanceData) { - if (mesh.getId() == -1) { - updateVertexArray(mesh, instanceData); - } else { - // TODO: Check if it was updated - } - - if (context.boundVertexArray != mesh.getId()) { - glBindVertexArray(mesh.getId()); - context.boundVertexArray = mesh.getId(); - } - -// IntMap buffers = mesh.getBuffers(); - VertexBuffer indices; - if (mesh.getNumLodLevels() > 0) { - indices = mesh.getLodLevel(lod); - } else { - indices = mesh.getBuffer(Type.Index); - } - if (indices != null) { - drawTriangleList(indices, mesh, count); - } else { - drawTriangleArray(mesh.getMode(), count, mesh.getVertexCount()); - } - clearVertexAttribs(); - clearTextureUnits(); - } - - private void renderMeshDefault(Mesh mesh, int lod, int count, VertexBuffer[] instanceData) { - - // Here while count is still passed in. Can be removed when/if - // the method is collapsed again. -pspeed - count = Math.max(mesh.getInstanceCount(), count); - - VertexBuffer interleavedData = mesh.getBuffer(Type.InterleavedData); - if (interleavedData != null && interleavedData.isUpdateNeeded()) { - updateBufferData(interleavedData); - } - - VertexBuffer indices; - if (mesh.getNumLodLevels() > 0) { - indices = mesh.getLodLevel(lod); - } else { - indices = mesh.getBuffer(Type.Index); - } - - if (instanceData != null) { - for (VertexBuffer vb : instanceData) { - setVertexAttrib(vb, null); - } - } - - for (VertexBuffer vb : mesh.getBufferList().getArray()) { - if (vb.getBufferType() == Type.InterleavedData - || vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers - || vb.getBufferType() == Type.Index) { - continue; - } - - if (vb.getStride() == 0) { - // not interleaved - setVertexAttrib(vb); - } else { - // interleaved - setVertexAttrib(vb, interleavedData); - } - } - - if (indices != null) { - drawTriangleList(indices, mesh, count); - } else { - drawTriangleArray(mesh.getMode(), count, mesh.getVertexCount()); - } - clearVertexAttribs(); - clearTextureUnits(); - } - - public void renderMesh(Mesh mesh, int lod, int count, VertexBuffer[] instanceData) { - if (mesh.getVertexCount() == 0) { - return; - } - - if (context.pointSprite && mesh.getMode() != Mode.Points) { - // XXX: Hack, disable point sprite mode if mesh not in point mode - if (context.boundTextures[0] != null) { - if (context.boundTextureUnit != 0) { - glActiveTexture(GL_TEXTURE0); - context.boundTextureUnit = 0; - } - glDisable(GL_POINT_SPRITE); - glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); - context.pointSprite = false; - } - } - - if (context.pointSize != mesh.getPointSize()) { - glPointSize(mesh.getPointSize()); - context.pointSize = mesh.getPointSize(); - } - if (context.lineWidth != mesh.getLineWidth()) { - glLineWidth(mesh.getLineWidth()); - context.lineWidth = mesh.getLineWidth(); - } - - statistics.onMeshDrawn(mesh, lod, count); -// if (ctxCaps.GL_ARB_vertex_array_object){ -// renderMeshVertexArray(mesh, lod, count); -// }else{ - renderMeshDefault(mesh, lod, count, instanceData); -// } - } - - public void setMainFrameBufferSrgb(boolean enableSrgb) { - // Gamma correction - - if (!caps.contains(Caps.Srgb)) { - // Not supported, sorry. - - logger.warning("sRGB framebuffer is not supported " + - "by video hardware, but was requested."); - - return; - } - - setFrameBuffer(null); - - if (enableSrgb) { - if (!glGetBoolean(GL_FRAMEBUFFER_SRGB_CAPABLE_EXT)) { - logger.warning("Driver claims that default framebuffer " - + "is not sRGB capable. Enabling anyway."); - } - - - - glEnable(GL_FRAMEBUFFER_SRGB_EXT); - - logger.log(Level.FINER, "SRGB FrameBuffer enabled (Gamma Correction)"); - } else { - glDisable(GL_FRAMEBUFFER_SRGB_EXT); - } - } - - public void setLinearizeSrgbImages(boolean linearize) { - if (caps.contains(Caps.Srgb)) { - linearizeSrgbImages = linearize; - } - } -} diff --git a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/TextureUtil.java b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/TextureUtil.java deleted file mode 100644 index 41dddd6ae..000000000 --- a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/TextureUtil.java +++ /dev/null @@ -1,514 +0,0 @@ -/* - * 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.renderer.lwjgl; - -import com.jme3.renderer.Caps; -import com.jme3.renderer.RendererException; -import com.jme3.texture.Image; -import com.jme3.texture.Image.Format; -import com.jme3.texture.image.ColorSpace; -import java.nio.ByteBuffer; -import java.util.EnumSet; -import java.util.logging.Level; -import java.util.logging.Logger; -import static org.lwjgl.opengl.ARBDepthBufferFloat.*; -import static org.lwjgl.opengl.ARBES3Compatibility.*; -import static org.lwjgl.opengl.ARBHalfFloatPixel.*; -import static org.lwjgl.opengl.ARBTextureFloat.*; -import static org.lwjgl.opengl.ARBTextureMultisample.*; -import static org.lwjgl.opengl.EXTPackedDepthStencil.*; -import static org.lwjgl.opengl.EXTPackedFloat.*; -import static org.lwjgl.opengl.EXTTextureArray.*; -import static org.lwjgl.opengl.EXTTextureCompressionS3TC.*; -import static org.lwjgl.opengl.EXTTextureSRGB.*; -import static org.lwjgl.opengl.EXTTextureSharedExponent.*; -import static org.lwjgl.opengl.GL11.*; -import static org.lwjgl.opengl.GL12.*; -import static org.lwjgl.opengl.GL13.*; -import static org.lwjgl.opengl.GL14.*; - -/** - * - * Should not be used, has been replaced by Unified Rendering Architechture. - * @deprecated - */ -@Deprecated -class TextureUtil { - - static class GLImageFormat { - - int internalFormat; - int format; - int dataType; - boolean compressed; - - public GLImageFormat(int internalFormat, int format, int dataType, boolean compressed) { - this.internalFormat = internalFormat; - this.format = format; - this.dataType = dataType; - this.compressed = compressed; - } - } - - private static final GLImageFormat[] formatToGL = new GLImageFormat[Format.values().length]; - - private static void setFormat(Format format, int glInternalFormat, int glFormat, int glDataType, boolean glCompressed){ - formatToGL[format.ordinal()] = new GLImageFormat(glInternalFormat, glFormat, glDataType, glCompressed); - } - - static { - // Alpha formats - setFormat(Format.Alpha8, GL_ALPHA8, GL_ALPHA, GL_UNSIGNED_BYTE, false); - - // Luminance formats - setFormat(Format.Luminance8, GL_LUMINANCE8, GL_LUMINANCE, GL_UNSIGNED_BYTE, false); - setFormat(Format.Luminance16F, GL_LUMINANCE16F_ARB, GL_LUMINANCE, GL_HALF_FLOAT_ARB, false); - setFormat(Format.Luminance32F, GL_LUMINANCE32F_ARB, GL_LUMINANCE, GL_FLOAT, false); - - // Luminance alpha formats - setFormat(Format.Luminance8Alpha8, GL_LUMINANCE8_ALPHA8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, false); - setFormat(Format.Luminance16FAlpha16F, GL_LUMINANCE_ALPHA16F_ARB, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_ARB, false); - - // Depth formats - setFormat(Format.Depth, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, false); - setFormat(Format.Depth16, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, false); - setFormat(Format.Depth24, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, false); - setFormat(Format.Depth32, GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, false); - setFormat(Format.Depth32F, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, false); - - // Depth stencil formats - setFormat(Format.Depth24Stencil8, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, false); - - // RGB formats - setFormat(Format.BGR8, GL_RGB8, GL_BGR, GL_UNSIGNED_BYTE, false); - setFormat(Format.ARGB8, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, false); - setFormat(Format.BGRA8, GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, false); - setFormat(Format.RGB8, GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, false); - setFormat(Format.RGB16F, GL_RGB16F_ARB, GL_RGB, GL_HALF_FLOAT_ARB, false); - setFormat(Format.RGB32F, GL_RGB32F_ARB, GL_RGB, GL_FLOAT, false); - - // Special RGB formats - setFormat(Format.RGB111110F, GL_R11F_G11F_B10F_EXT, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV_EXT, false); - setFormat(Format.RGB9E5, GL_RGB9_E5_EXT, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV_EXT, false); - setFormat(Format.RGB16F_to_RGB111110F, GL_R11F_G11F_B10F_EXT, GL_RGB, GL_HALF_FLOAT_ARB, false); - setFormat(Format.RGB16F_to_RGB9E5, GL_RGB9_E5_EXT, GL_RGB, GL_HALF_FLOAT_ARB, false); - - // RGBA formats - setFormat(Format.ABGR8, GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, false); - setFormat(Format.RGB5A1, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, false); - setFormat(Format.RGBA8, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false); - setFormat(Format.RGBA16F, GL_RGBA16F_ARB, GL_RGBA, GL_HALF_FLOAT_ARB, false); - setFormat(Format.RGBA32F, GL_RGBA32F_ARB, GL_RGBA, GL_FLOAT, false); - - // DXT formats - setFormat(Format.DXT1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_BYTE, true); - setFormat(Format.DXT1A, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_RGBA, GL_UNSIGNED_BYTE, true); - setFormat(Format.DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_BYTE, true); - setFormat(Format.DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_BYTE, true); - - // ETC1 support on regular OpenGL requires ES3 compatibility extension. - // NOTE: ETC2 is backwards compatible with ETC1, so we can - // upload ETC1 textures as ETC2. - setFormat(Format.ETC1, GL_COMPRESSED_RGB8_ETC2, GL_RGB, GL_UNSIGNED_BYTE, true); - } - - //sRGB formats - private static final GLImageFormat sRGB_RGB8 = new GLImageFormat(GL_SRGB8_EXT, GL_RGB, GL_UNSIGNED_BYTE, false); - private static final GLImageFormat sRGB_RGBA8 = new GLImageFormat(GL_SRGB8_ALPHA8_EXT, GL_RGBA, GL_UNSIGNED_BYTE, false); - private static final GLImageFormat sRGB_Luminance8 = new GLImageFormat(GL_SLUMINANCE8_EXT, GL_LUMINANCE, GL_UNSIGNED_BYTE, false); - private static final GLImageFormat sRGB_LuminanceAlpha8 = new GLImageFormat(GL_SLUMINANCE8_ALPHA8_EXT, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, false); - private static final GLImageFormat sRGB_BGR8 = new GLImageFormat(GL_SRGB8_EXT, GL_BGR, GL_UNSIGNED_BYTE, false); - private static final GLImageFormat sRGB_ABGR8 = new GLImageFormat(GL_SRGB8_ALPHA8_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, false); - private static final GLImageFormat sRGB_ARGB8 = new GLImageFormat(GL_SRGB8_ALPHA8_EXT, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, false); - private static final GLImageFormat sRGB_BGRA8 = new GLImageFormat(GL_SRGB8_ALPHA8_EXT, GL_BGRA, GL_UNSIGNED_BYTE, false); - private static final GLImageFormat sRGB_DXT1 = new GLImageFormat(GL_COMPRESSED_SRGB_S3TC_DXT1_EXT,GL_RGB, GL_UNSIGNED_BYTE, true); - private static final GLImageFormat sRGB_DXT1A = new GLImageFormat(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL_RGBA, GL_UNSIGNED_BYTE, true); - private static final GLImageFormat sRGB_DXT3 = new GLImageFormat(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_BYTE, true); - private static final GLImageFormat sRGB_DXT5 = new GLImageFormat(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_BYTE, true); - - public static GLImageFormat getImageFormat(EnumSet caps, Format fmt, boolean isSrgb){ - switch (fmt){ - case ETC1: - if (!caps.contains(Caps.TextureCompressionETC1)) { - return null; - } - break; - case DXT1: - case DXT1A: - case DXT3: - case DXT5: - if (!caps.contains(Caps.TextureCompressionS3TC)) { - return null; - } - break; - case Depth24Stencil8: - if (!caps.contains(Caps.PackedDepthStencilBuffer)){ - return null; - } - break; - case Luminance16F: - case Luminance16FAlpha16F: - case Luminance32F: - case RGB16F: - case RGB32F: - case RGBA16F: - case RGBA32F: - if (!caps.contains(Caps.FloatTexture)){ - return null; - } - break; - case Depth32F: - if (!caps.contains(Caps.FloatDepthBuffer)){ - return null; - } - break; - case RGB9E5: - case RGB16F_to_RGB9E5: - if (!caps.contains(Caps.SharedExponentTexture)){ - return null; - } - break; - case RGB111110F: - case RGB16F_to_RGB111110F: - if (!caps.contains(Caps.PackedFloatTexture)){ - return null; - } - break; - } - if (isSrgb) { - return getSrgbFormat(fmt); - } else { - return formatToGL[fmt.ordinal()]; - } - } - - public static GLImageFormat getImageFormatWithError(EnumSet caps, Format fmt, boolean isSrgb) { - GLImageFormat glFmt = getImageFormat(caps, fmt, isSrgb); - if (glFmt == null) { - throw new RendererException("Image format '" + fmt + "' is unsupported by the video hardware."); - } - return glFmt; - } - - private static GLImageFormat getSrgbFormat(Format fmt){ - switch (fmt) { - case RGB8: - return sRGB_RGB8; - case RGBA8: - return sRGB_RGBA8; - case BGR8: - return sRGB_BGR8; - case ABGR8: - return sRGB_ABGR8; - case ARGB8: - return sRGB_ARGB8; - case BGRA8: - return sRGB_BGRA8; - case Luminance8: - return sRGB_Luminance8; - case Luminance8Alpha8: - return sRGB_LuminanceAlpha8; - case DXT1: - return sRGB_DXT1; - case DXT1A: - return sRGB_DXT1A; - case DXT3: - return sRGB_DXT3; - case DXT5: - return sRGB_DXT5; - default: - Logger.getLogger(TextureUtil.class.getName()).log(Level.WARNING, "Format {0} has no sRGB equivalent, using linear format.", fmt.toString()); - return formatToGL[fmt.ordinal()]; - } - } - - public static void uploadTexture(EnumSet caps, - Image image, - int target, - int index, - int border, - boolean linearizeSrgb){ - - Image.Format fmt = image.getFormat(); - GLImageFormat glFmt = getImageFormatWithError(caps, fmt, image.getColorSpace() == ColorSpace.sRGB && linearizeSrgb); - - ByteBuffer data; - if (index >= 0 && image.getData() != null && image.getData().size() > 0){ - data = image.getData(index); - }else{ - data = null; - } - - int width = image.getWidth(); - int height = image.getHeight(); - int depth = image.getDepth(); - - if (data != null) { - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - } - - int[] mipSizes = image.getMipMapSizes(); - int pos = 0; - // TODO: Remove unneccessary allocation - if (mipSizes == null){ - if (data != null) - mipSizes = new int[]{ data.capacity() }; - else - mipSizes = new int[]{ width * height * fmt.getBitsPerPixel() / 8 }; - } - - boolean subtex = false; - int samples = image.getMultiSamples(); - - for (int i = 0; i < mipSizes.length; i++){ - int mipWidth = Math.max(1, width >> i); - int mipHeight = Math.max(1, height >> i); - int mipDepth = Math.max(1, depth >> i); - - if (data != null){ - data.position(pos); - data.limit(pos + mipSizes[i]); - } - - if (glFmt.compressed && data != null){ - if (target == GL_TEXTURE_3D){ - glCompressedTexImage3D(target, - i, - glFmt.internalFormat, - mipWidth, - mipHeight, - mipDepth, - border, - data); - } else if (target == GL_TEXTURE_2D_ARRAY_EXT) { - // Upload compressed texture array slice - glCompressedTexSubImage3D(target, - i, - 0, - 0, - index, - mipWidth, - mipHeight, - 1, - glFmt.internalFormat, - data); - }else{ - //all other targets use 2D: array, cubemap, 2d - glCompressedTexImage2D(target, - i, - glFmt.internalFormat, - mipWidth, - mipHeight, - border, - data); - } - }else{ - if (target == GL_TEXTURE_3D){ - glTexImage3D(target, - i, - glFmt.internalFormat, - mipWidth, - mipHeight, - mipDepth, - border, - glFmt.format, - glFmt.dataType, - data); - }else if (target == GL_TEXTURE_2D_ARRAY_EXT){ - // prepare data for 2D array - // or upload slice - if (index == -1){ - glTexImage3D(target, - i, - glFmt.internalFormat, - mipWidth, - mipHeight, - image.getData().size(), //# of slices - border, - glFmt.format, - glFmt.dataType, - data); - }else{ - glTexSubImage3D(target, - i, // level - 0, // xoffset - 0, // yoffset - index, // zoffset - mipWidth, // width - mipHeight, // height - 1, // depth - glFmt.format, - glFmt.dataType, - data); - } - }else{ - if (subtex){ - if (samples > 1){ - throw new IllegalStateException("Cannot update multisample textures"); - } - - glTexSubImage2D(target, - i, - 0, 0, - mipWidth, mipHeight, - glFmt.format, - glFmt.dataType, - data); - }else{ - if (samples > 1){ - glTexImage2DMultisample(target, - samples, - glFmt.internalFormat, - mipWidth, - mipHeight, - true); - }else{ - glTexImage2D(target, - i, - glFmt.internalFormat, - mipWidth, - mipHeight, - border, - glFmt.format, - glFmt.dataType, - data); - } - } - } - } - - pos += mipSizes[i]; - } - } - - /** - * Update the texture currently bound to target at with data from the given Image at position x and y. The parameter - * index is used as the zoffset in case a 3d texture or texture 2d array is being updated. - * - * @param image Image with the source data (this data will be put into the texture) - * @param target the target texture - * @param index the mipmap level to update - * @param x the x position where to put the image in the texture - * @param y the y position where to put the image in the texture - */ - public static void uploadSubTexture( - EnumSet caps, - Image image, - int target, - int index, - int x, - int y, - boolean linearizeSrgb) { - Image.Format fmt = image.getFormat(); - GLImageFormat glFmt = getImageFormatWithError(caps, fmt, image.getColorSpace() == ColorSpace.sRGB && linearizeSrgb); - - ByteBuffer data = null; - if (index >= 0 && image.getData() != null && image.getData().size() > 0) { - data = image.getData(index); - } - - int width = image.getWidth(); - int height = image.getHeight(); - int depth = image.getDepth(); - - if (data != null) { - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - } - - int[] mipSizes = image.getMipMapSizes(); - int pos = 0; - - // TODO: Remove unneccessary allocation - if (mipSizes == null){ - if (data != null) { - mipSizes = new int[]{ data.capacity() }; - } else { - mipSizes = new int[]{ width * height * fmt.getBitsPerPixel() / 8 }; - } - } - - int samples = image.getMultiSamples(); - - for (int i = 0; i < mipSizes.length; i++){ - int mipWidth = Math.max(1, width >> i); - int mipHeight = Math.max(1, height >> i); - int mipDepth = Math.max(1, depth >> i); - - if (data != null){ - data.position(pos); - data.limit(pos + mipSizes[i]); - } - - // to remove the cumbersome if/then/else stuff below we'll update the pos right here and use continue after each - // gl*Image call in an attempt to unclutter things a bit - pos += mipSizes[i]; - - int glFmtInternal = glFmt.internalFormat; - int glFmtFormat = glFmt.format; - int glFmtDataType = glFmt.dataType; - - if (glFmt.compressed && data != null){ - if (target == GL_TEXTURE_3D){ - glCompressedTexSubImage3D(target, i, x, y, index, mipWidth, mipHeight, mipDepth, glFmtInternal, data); - continue; - } - - // all other targets use 2D: array, cubemap, 2d - glCompressedTexSubImage2D(target, i, x, y, mipWidth, mipHeight, glFmtInternal, data); - continue; - } - - if (target == GL_TEXTURE_3D){ - glTexSubImage3D(target, i, x, y, index, mipWidth, mipHeight, mipDepth, glFmtFormat, glFmtDataType, data); - continue; - } - - if (target == GL_TEXTURE_2D_ARRAY_EXT){ - // prepare data for 2D array or upload slice - if (index == -1){ - glTexSubImage3D(target, i, x, y, index, mipWidth, mipHeight, mipDepth, glFmtFormat, glFmtDataType, data); - continue; - } - - glTexSubImage3D(target, i, x, y, index, width, height, 1, glFmtFormat, glFmtDataType, data); - continue; - } - - if (samples > 1){ - throw new IllegalStateException("Cannot update multisample textures"); - } - - glTexSubImage2D(target, i, x, y, mipWidth, mipHeight, glFmtFormat, glFmtDataType, data); - } - } -} diff --git a/jme3-networking/src/main/java/com/jme3/network/Client.java b/jme3-networking/src/main/java/com/jme3/network/Client.java index dd9873238..3ef9134df 100644 --- a/jme3-networking/src/main/java/com/jme3/network/Client.java +++ b/jme3-networking/src/main/java/com/jme3/network/Client.java @@ -55,6 +55,12 @@ public interface Client extends MessageConnection */ public boolean isConnected(); + /** + * Returns true if this client has been started and is still + * running. + */ + public boolean isStarted(); + /** * Returns a unique ID for this client within the remote * server or -1 if this client isn't fully connected to the diff --git a/jme3-networking/src/main/java/com/jme3/network/base/DefaultClient.java b/jme3-networking/src/main/java/com/jme3/network/base/DefaultClient.java index c0cc2e616..b297a933b 100644 --- a/jme3-networking/src/main/java/com/jme3/network/base/DefaultClient.java +++ b/jme3-networking/src/main/java/com/jme3/network/base/DefaultClient.java @@ -177,6 +177,10 @@ public class DefaultClient implements Client continue; send(ch, reg, false); } + } + + public boolean isStarted() { + return isRunning; } protected void waitForConnected() @@ -351,13 +355,16 @@ public class DefaultClient implements Client protected void fireConnected() { - // Let the services know we are finally started - services.start(); - for( ClientStateListener l : stateListeners ) { l.clientConnected( this ); } } + + protected void startServices() + { + // Let the services know we are finally started + services.start(); + } protected void fireDisconnected( DisconnectInfo info ) { @@ -416,11 +423,19 @@ public class DefaultClient implements Client // Pull off the connection management messages we're // interested in and then pass on the rest. if( m instanceof ClientRegistrationMessage ) { - // Then we've gotten our real id - this.id = (int)((ClientRegistrationMessage)m).getId(); - log.log( Level.FINE, "Connection established, id:{0}.", this.id ); - connecting.countDown(); - fireConnected(); + ClientRegistrationMessage crm = (ClientRegistrationMessage)m; + // See if it has a real ID + if( crm.getId() >= 0 ) { + // Then we've gotten our real id + this.id = (int)crm.getId(); + log.log( Level.FINE, "Connection established, id:{0}.", this.id ); + connecting.countDown(); + fireConnected(); + } else { + // Else it's a message letting us know that the + // hosted services have been started + startServices(); + } return; } else if( m instanceof ChannelInfoMessage ) { // This is an interum step in the connection process and diff --git a/jme3-networking/src/main/java/com/jme3/network/base/DefaultServer.java b/jme3-networking/src/main/java/com/jme3/network/base/DefaultServer.java index 0a9ac0ef1..2b9add2ef 100644 --- a/jme3-networking/src/main/java/com/jme3/network/base/DefaultServer.java +++ b/jme3-networking/src/main/java/com/jme3/network/base/DefaultServer.java @@ -223,7 +223,7 @@ public class DefaultServer implements Server { if( connections.isEmpty() ) return; - + ByteBuffer buffer = MessageProtocol.messageToBuffer(message, null); FilterAdapter adapter = filter == null ? null : new FilterAdapter(filter); @@ -412,7 +412,14 @@ public class DefaultServer implements Server // Now we can notify the listeners about the // new connection. - fireConnectionAdded( addedConnection ); + fireConnectionAdded( addedConnection ); + + // Send a second registration message with an invalid ID + // to let the connection know that it can start its services + m = new ClientRegistrationMessage(); + m.setId(-1); + m.setReliable(true); + addedConnection.send(m); } } diff --git a/jme3-networking/src/main/java/com/jme3/network/base/MessageProtocol.java b/jme3-networking/src/main/java/com/jme3/network/base/MessageProtocol.java index a8d0d39fd..6751ecc3f 100644 --- a/jme3-networking/src/main/java/com/jme3/network/base/MessageProtocol.java +++ b/jme3-networking/src/main/java/com/jme3/network/base/MessageProtocol.java @@ -181,7 +181,7 @@ public class MessageProtocol Message m = (Message)obj; messages.add(m); } catch( IOException e ) { - throw new RuntimeException( "Error deserializing object", e ); + throw new RuntimeException( "Error deserializing object, clas ID:" + buffer.getShort(0), e ); } } } diff --git a/jme3-networking/src/main/java/com/jme3/network/kernel/udp/UdpConnector.java b/jme3-networking/src/main/java/com/jme3/network/kernel/udp/UdpConnector.java index 20682ecee..bf0f7ddb1 100644 --- a/jme3-networking/src/main/java/com/jme3/network/kernel/udp/UdpConnector.java +++ b/jme3-networking/src/main/java/com/jme3/network/kernel/udp/UdpConnector.java @@ -113,7 +113,6 @@ public class UdpConnector implements Connector public ByteBuffer read() { checkClosed(); - try { DatagramPacket packet = new DatagramPacket( buffer, buffer.length ); sock.receive(packet); @@ -132,7 +131,6 @@ public class UdpConnector implements Connector public void write( ByteBuffer data ) { checkClosed(); - try { DatagramPacket p = new DatagramPacket( data.array(), data.position(), data.remaining(), remoteAddress ); diff --git a/jme3-networking/src/main/java/com/jme3/network/message/SerializerRegistrationsMessage.java b/jme3-networking/src/main/java/com/jme3/network/message/SerializerRegistrationsMessage.java index da7f2a7cf..9c3896475 100644 --- a/jme3-networking/src/main/java/com/jme3/network/message/SerializerRegistrationsMessage.java +++ b/jme3-networking/src/main/java/com/jme3/network/message/SerializerRegistrationsMessage.java @@ -127,7 +127,9 @@ public class SerializerRegistrationsMessage extends AbstractMessage { } compiled = list.toArray(new Registration[list.size()]); - INSTANCE = new SerializerRegistrationsMessage(compiled); + INSTANCE = new SerializerRegistrationsMessage(compiled); + + Serializer.setReadOnly(true); } public void registerAll() { diff --git a/jme3-networking/src/main/java/com/jme3/network/serializing/Serializer.java b/jme3-networking/src/main/java/com/jme3/network/serializing/Serializer.java index a7d20da54..d4c054403 100644 --- a/jme3-networking/src/main/java/com/jme3/network/serializing/Serializer.java +++ b/jme3-networking/src/main/java/com/jme3/network/serializing/Serializer.java @@ -71,6 +71,8 @@ public abstract class Serializer { private static boolean strictRegistration = true; + private static volatile boolean locked = false; + // Registers the classes we already have serializers for. static { @@ -168,6 +170,20 @@ public abstract class Serializer { return nextAvailableId--; } + /** + * Can put the registry in a read-only state such that additional attempts + * to register classes will fail. This can be used by servers to lock the + * registry to avoid accidentally registering classes after a full registry + * set has been compiled. + */ + public static void setReadOnly( boolean b ) { + locked = b; + } + + public static boolean isReadOnly() { + return locked; + } + /** * Directly registers a class for a specific ID. Generally, use the regular * registerClass() method. This method is intended for framework code that might @@ -175,7 +191,11 @@ public abstract class Serializer { */ public static SerializerRegistration registerClassForId( short id, Class cls, Serializer serializer ) { - SerializerRegistration reg = new SerializerRegistration(serializer, cls, id); + if( locked ) { + throw new RuntimeException("Serializer registry locked trying to register class:" + cls); + } + + SerializerRegistration reg = new SerializerRegistration(serializer, cls, id); idRegistrations.put(id, reg); classRegistrations.put(cls, reg); diff --git a/jme3-networking/src/main/java/com/jme3/network/serializing/serializers/GZIPSerializer.java b/jme3-networking/src/main/java/com/jme3/network/serializing/serializers/GZIPSerializer.java index 01dbd1d41..7579e84c5 100644 --- a/jme3-networking/src/main/java/com/jme3/network/serializing/serializers/GZIPSerializer.java +++ b/jme3-networking/src/main/java/com/jme3/network/serializing/serializers/GZIPSerializer.java @@ -87,7 +87,8 @@ public class GZIPSerializer extends Serializer { ByteArrayOutputStream byteArrayOutput = new ByteArrayOutputStream(); GZIPOutputStream gzipOutput = new GZIPOutputStream(byteArrayOutput); - gzipOutput.write(tempBuffer.array()); + tempBuffer.flip(); + gzipOutput.write(tempBuffer.array(), 0, tempBuffer.limit()); gzipOutput.flush(); gzipOutput.finish(); gzipOutput.close(); diff --git a/jme3-networking/src/main/java/com/jme3/network/serializing/serializers/ZIPSerializer.java b/jme3-networking/src/main/java/com/jme3/network/serializing/serializers/ZIPSerializer.java index 1241c1341..ad7d7162d 100644 --- a/jme3-networking/src/main/java/com/jme3/network/serializing/serializers/ZIPSerializer.java +++ b/jme3-networking/src/main/java/com/jme3/network/serializing/serializers/ZIPSerializer.java @@ -98,7 +98,8 @@ public class ZIPSerializer extends Serializer { ZipEntry zipEntry = new ZipEntry("zip"); zipOutput.putNextEntry(zipEntry); - zipOutput.write(tempBuffer.array()); + tempBuffer.flip(); + zipOutput.write(tempBuffer.array(), 0, tempBuffer.limit()); zipOutput.flush(); zipOutput.closeEntry(); zipOutput.close(); diff --git a/jme3-networking/src/main/java/com/jme3/network/service/AbstractClientService.java b/jme3-networking/src/main/java/com/jme3/network/service/AbstractClientService.java index bd1836451..d1a848dac 100644 --- a/jme3-networking/src/main/java/com/jme3/network/service/AbstractClientService.java +++ b/jme3-networking/src/main/java/com/jme3/network/service/AbstractClientService.java @@ -32,6 +32,7 @@ package com.jme3.network.service; +import com.jme3.network.Client; /** * Convenient base class for ClientServices providing some default ClientService @@ -48,4 +49,13 @@ public abstract class AbstractClientService extends AbstractServiceSubclasses must at least override the onInitialize(), startHostingOnConnection(), and + * stopHostingOnConnection() methods to handle service and connection initialization.

    + * + *

    An autoHost flag controls whether startHostingOnConnection() is called + * automatically when new connections are detected. If autoHohst is false then it + * is up to the implementation or appliction to specifically start hosting at + * some point.

    + * + * @author Paul Speed + */ +public abstract class AbstractHostedConnectionService extends AbstractHostedService { + + static final Logger log = Logger.getLogger(AbstractHostedConnectionService.class.getName()); + + private boolean autoHost; + + /** + * Creates a new HostedService that will autohost connections + * when detected. + */ + protected AbstractHostedConnectionService() { + this(true); + } + + /** + * Creates a new HostedService that will automatically host + * connections only if autoHost is true. + */ + protected AbstractHostedConnectionService( boolean autoHost ) { + this.autoHost = autoHost; + } + + /** + * When set to true, all new connections will automatically have + * hosting services attached to them by calling startHostingOnConnection(). + * If this is set to false then it is up to the application or other services + * to eventually call startHostingOnConnection(). + * + *

    Reasons for doing this vary but usually would be because + * the client shouldn't be allowed to perform any service-related calls until + * it has provided more information... for example, logging in.

    + */ + public void setAutoHost( boolean b ) { + this.autoHost = b; + } + + /** + * Returns true if this service automatically attaches + * hosting capabilities to new connections. + */ + public boolean getAutoHost() { + return autoHost; + } + + + /** + * Performs implementation specific connection hosting setup. + * Generally this involves setting up some handlers or session + * attributes on the connection. If autoHost is true then this + * method is called automatically during connectionAdded() + * processing. + */ + public abstract void startHostingOnConnection( HostedConnection hc ); + + /** + * Performs implementation specific connection tear-down. + * This will be called automatically when the connectionRemoved() + * event occurs... whether the application has already called it + * or not. + */ + public abstract void stopHostingOnConnection( HostedConnection hc ); + + /** + * Called internally when a new connection is detected for + * the server. If the current autoHost property is true then + * startHostingOnConnection(hc) is called. + */ + @Override + public void connectionAdded(Server server, HostedConnection hc) { + if( log.isLoggable(Level.FINEST) ) { + log.log(Level.FINEST, "connectionAdded({0}, {1})", new Object[]{server, hc}); + } + if( autoHost ) { + startHostingOnConnection(hc); + } + } + + /** + * Called internally when an existing connection is leaving + * the server. This method always calls stopHostingOnConnection(hc). + * Implementations should be aware that if they stopHostingOnConnection() + * early that they will get a second call when the connection goes away. + */ + @Override + public void connectionRemoved(Server server, HostedConnection hc) { + if( log.isLoggable(Level.FINEST) ) { + log.log(Level.FINEST, "connectionRemoved({0}, {1})", new Object[]{server, hc}); + } + stopHostingOnConnection(hc); + } +} diff --git a/jme3-networking/src/main/java/com/jme3/network/service/AbstractHostedService.java b/jme3-networking/src/main/java/com/jme3/network/service/AbstractHostedService.java index 789767b73..051c0d259 100644 --- a/jme3-networking/src/main/java/com/jme3/network/service/AbstractHostedService.java +++ b/jme3-networking/src/main/java/com/jme3/network/service/AbstractHostedService.java @@ -50,6 +50,15 @@ public abstract class AbstractHostedService extends AbstractService implements Servi @Override public String toString() { - return getClass().getName() + "[serviceManager=" + serviceManager + "]"; + return getClass().getName() + "[serviceManager.class=" + serviceManager.getClass() + "]"; } } diff --git a/jme3-networking/src/main/java/com/jme3/network/service/rpc/RpcClientService.java b/jme3-networking/src/main/java/com/jme3/network/service/rpc/RpcClientService.java index d9ea134e1..a74a7c7d1 100644 --- a/jme3-networking/src/main/java/com/jme3/network/service/rpc/RpcClientService.java +++ b/jme3-networking/src/main/java/com/jme3/network/service/rpc/RpcClientService.java @@ -60,6 +60,15 @@ public class RpcClientService extends AbstractClientService { public RpcClientService() { } + /** + * Returns the underlying RPC connection for use by other + * services that may require a more generic non-client/server + * specific RPC object with which to interact. + */ + public RpcConnection getRpcConnection() { + return rpc; + } + /** * Used internally to setup the RpcConnection and MessageDelegator. */ diff --git a/jme3-networking/src/main/java/com/jme3/network/service/rpc/RpcConnection.java b/jme3-networking/src/main/java/com/jme3/network/service/rpc/RpcConnection.java index b78316bf3..f457e426b 100644 --- a/jme3-networking/src/main/java/com/jme3/network/service/rpc/RpcConnection.java +++ b/jme3-networking/src/main/java/com/jme3/network/service/rpc/RpcConnection.java @@ -115,8 +115,13 @@ public class RpcConnection { if( log.isLoggable(Level.FINEST) ) { log.log(Level.FINEST, "Sending:{0} on channel:{1}", new Object[]{msg, channel}); - } - if( channel >= 0 ) { + } + + // Prevent non-async messages from being send as UDP + // because there is a high probabilty that this would block + // forever waiting for a response. For async calls it's ok + // so it doesn't do the check. + if( channel >= 0 ) { connection.send(channel, msg); } else { connection.send(msg); diff --git a/jme3-networking/src/main/java/com/jme3/network/service/rpc/RpcHostedService.java b/jme3-networking/src/main/java/com/jme3/network/service/rpc/RpcHostedService.java index 4a347b5a3..2d6f28593 100644 --- a/jme3-networking/src/main/java/com/jme3/network/service/rpc/RpcHostedService.java +++ b/jme3-networking/src/main/java/com/jme3/network/service/rpc/RpcHostedService.java @@ -35,8 +35,8 @@ package com.jme3.network.service.rpc; import com.jme3.network.HostedConnection; import com.jme3.network.Server; import com.jme3.network.serializing.Serializer; +import com.jme3.network.service.AbstractHostedConnectionService; import com.jme3.network.util.SessionDataDelegator; -import com.jme3.network.service.AbstractHostedService; import com.jme3.network.service.HostedServiceManager; import com.jme3.network.service.rpc.msg.RpcCallMessage; import com.jme3.network.service.rpc.msg.RpcResponseMessage; @@ -62,13 +62,12 @@ import java.util.logging.Logger; * * @author Paul Speed */ -public class RpcHostedService extends AbstractHostedService { +public class RpcHostedService extends AbstractHostedConnectionService { private static final String ATTRIBUTE_NAME = "rpcSession"; static final Logger log = Logger.getLogger(RpcHostedService.class.getName()); - private boolean autoHost; private SessionDataDelegator delegator; /** @@ -87,7 +86,7 @@ public class RpcHostedService extends AbstractHostedService { * on the specified 'autoHost' flag. */ public RpcHostedService( boolean autoHost ) { - this.autoHost = autoHost; + super(autoHost); // This works for me... has to be different in // the general case @@ -115,31 +114,6 @@ public class RpcHostedService extends AbstractHostedService { } } - /** - * When set to true, all new connections will automatically have - * RPC hosting services attached to them, meaning they can send - * and receive RPC calls. If this is set to false then it is up - * to other services to eventually call startHostingOnConnection(). - * - *

    Reasons for doing this vary but usually would be because - * the client shouldn't be allowed to perform any RPC calls until - * it has provided more information. In general, this is unnecessary - * because the RpcHandler registries are not shared. Each client - * gets their own and RPC calls will fail until the appropriate - * objects have been registtered.

    - */ - public void setAutoHost( boolean b ) { - this.autoHost = b; - } - - /** - * Returns true if this service automatically attaches RPC - * hosting capabilities to new connections. - */ - public boolean getAutoHost() { - return autoHost; - } - /** * Retrieves the RpcConnection for the specified HostedConnection * if that HostedConnection has had RPC services started using @@ -157,6 +131,7 @@ public class RpcHostedService extends AbstractHostedService { * This method is called automatically for all new connections if * autohost is set to true. */ + @Override public void startHostingOnConnection( HostedConnection hc ) { if( log.isLoggable(Level.FINEST) ) { log.log(Level.FINEST, "startHostingOnConnection:{0}", hc); @@ -173,6 +148,7 @@ public class RpcHostedService extends AbstractHostedService { * This method is called automatically for all leaving connections if * autohost is set to true. */ + @Override public void stopHostingOnConnection( HostedConnection hc ) { RpcConnection rpc = hc.getAttribute(ATTRIBUTE_NAME); if( rpc == null ) { @@ -195,33 +171,5 @@ public class RpcHostedService extends AbstractHostedService { server.removeMessageListener(delegator, delegator.getMessageTypes()); } - /** - * Called internally when a new connection is detected for - * the server. If the current autoHost property is true then - * startHostingOnConnection(hc) is called. - */ - @Override - public void connectionAdded(Server server, HostedConnection hc) { - if( log.isLoggable(Level.FINEST) ) { - log.log(Level.FINEST, "connectionAdded({0}, {1})", new Object[]{server, hc}); - } - if( autoHost ) { - startHostingOnConnection(hc); - } - } - - /** - * Called internally when an existing connection is leaving - * the server. If the current autoHost property is true then - * stopHostingOnConnection(hc) is called. - */ - @Override - public void connectionRemoved(Server server, HostedConnection hc) { - if( log.isLoggable(Level.FINEST) ) { - log.log(Level.FINEST, "connectionRemoved({0}, {1})", new Object[]{server, hc}); - } - stopHostingOnConnection(hc); - } - } diff --git a/jme3-networking/src/main/java/com/jme3/network/service/rpc/msg/RpcCallMessage.java b/jme3-networking/src/main/java/com/jme3/network/service/rpc/msg/RpcCallMessage.java index 70f12f1e0..11c5db591 100644 --- a/jme3-networking/src/main/java/com/jme3/network/service/rpc/msg/RpcCallMessage.java +++ b/jme3-networking/src/main/java/com/jme3/network/service/rpc/msg/RpcCallMessage.java @@ -92,7 +92,7 @@ public class RpcCallMessage extends AbstractMessage { + (isAsync() ? ", async" : ", sync") + ", objId=" + objId + ", procId=" + procId - + ", args.length=" + args.length + + ", args.length=" + (args == null ? 0 : args.length) + "]"; } } diff --git a/jme3-niftygui/src/main/java/com/jme3/cinematic/events/GuiEvent.java b/jme3-niftygui/src/main/java/com/jme3/cinematic/events/GuiEvent.java index 2f5d788b4..f832b4266 100644 --- a/jme3-niftygui/src/main/java/com/jme3/cinematic/events/GuiEvent.java +++ b/jme3-niftygui/src/main/java/com/jme3/cinematic/events/GuiEvent.java @@ -38,6 +38,8 @@ import com.jme3.export.JmeImporter; import com.jme3.export.OutputCapsule; import de.lessvoid.nifty.Nifty; import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; /** * @@ -45,6 +47,8 @@ import java.io.IOException; */ public class GuiEvent extends AbstractCinematicEvent { + static final Logger log = Logger.getLogger(GuiEvent.class.getName()); + protected String screen; protected Nifty nifty; @@ -76,7 +80,7 @@ public class GuiEvent extends AbstractCinematicEvent { @Override public void onPlay() { - System.out.println("screen should be " + screen); + log.log(Level.FINEST, "screen should be {0}", screen); nifty.gotoScreen(screen); } diff --git a/jme3-plugins/src/xml/java/com/jme3/export/xml/XMLExporter.java b/jme3-plugins/src/xml/java/com/jme3/export/xml/XMLExporter.java index 32138270d..0ede52884 100644 --- a/jme3-plugins/src/xml/java/com/jme3/export/xml/XMLExporter.java +++ b/jme3-plugins/src/xml/java/com/jme3/export/xml/XMLExporter.java @@ -40,6 +40,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; /** * Part of the jME XML IO system as introduced in the google code jmexml project. @@ -61,7 +62,8 @@ public class XMLExporter implements JmeExporter { } - public boolean save(Savable object, OutputStream f) throws IOException { + @Override + public void save(Savable object, OutputStream f) throws IOException { try { //Initialize Document when saving so we don't retain state of previous exports this.domOut = new DOMOutputCapsule(DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(), this); @@ -69,18 +71,22 @@ public class XMLExporter implements JmeExporter { DOMSerializer serializer = new DOMSerializer(); serializer.serialize(domOut.getDoc(), f); f.flush(); - return true; - } catch (Exception ex) { - IOException e = new IOException(); - e.initCause(ex); - throw e; + } catch (ParserConfigurationException ex) { + throw new IOException(ex); } } - public boolean save(Savable object, File f) throws IOException { - return save(object, new FileOutputStream(f)); + @Override + public void save(Savable object, File f) throws IOException { + FileOutputStream fos = new FileOutputStream(f); + try { + save(object, fos); + } finally { + fos.close(); + } } + @Override public OutputCapsule getCapsule(Savable object) { return domOut; } diff --git a/jme3-testdata/src/main/resources/Textures/Terrain/BrickWall/BrickWall.j3m b/jme3-testdata/src/main/resources/Textures/Terrain/BrickWall/BrickWall.j3m index 8b54f9e39..41af10431 100644 --- a/jme3-testdata/src/main/resources/Textures/Terrain/BrickWall/BrickWall.j3m +++ b/jme3-testdata/src/main/resources/Textures/Terrain/BrickWall/BrickWall.j3m @@ -1,8 +1,7 @@ Material Pong Rock : Common/MatDefs/Light/Lighting.j3md { MaterialParameters { Shininess: 2.0 - DiffuseMap : Textures/Terrain/BrickWall/BrickWall.jpg - NormalMap : Textures/Terrain/BrickWall/BrickWall_normal.jpg - ParallaxMap : Textures/Terrain/BrickWall/BrickWall_height.jpg + DiffuseMap : Repeat Textures/Terrain/BrickWall/BrickWall.jpg + ParallaxMap : Repeat Textures/Terrain/BrickWall/BrickWall_height.jpg } } \ No newline at end of file diff --git a/jme3-testdata/src/main/resources/Textures/Terrain/BrickWall/BrickWall2.j3m b/jme3-testdata/src/main/resources/Textures/Terrain/BrickWall/BrickWall2.j3m index 7db3ab893..8f90a9454 100644 --- a/jme3-testdata/src/main/resources/Textures/Terrain/BrickWall/BrickWall2.j3m +++ b/jme3-testdata/src/main/resources/Textures/Terrain/BrickWall/BrickWall2.j3m @@ -1,8 +1,8 @@ Material Pong Rock : Common/MatDefs/Light/Lighting.j3md { MaterialParameters { Shininess: 2.0 - DiffuseMap : Textures/Terrain/BrickWall/BrickWall.jpg - NormalMap : Textures/Terrain/BrickWall/BrickWall_normal_parallax.dds + DiffuseMap : Repeat Textures/Terrain/BrickWall/BrickWall.jpg + NormalMap : Repeat Textures/Terrain/BrickWall/BrickWall_normal_parallax.dds PackedNormalParallax: true } } \ No newline at end of file diff --git a/local.properties b/local.properties new file mode 100644 index 000000000..27e823fff --- /dev/null +++ b/local.properties @@ -0,0 +1 @@ +sdk.dir=C:\\AndroidSDK \ No newline at end of file diff --git a/private/known_hosts b/private/known_hosts new file mode 100644 index 000000000..fdc45836f --- /dev/null +++ b/private/known_hosts @@ -0,0 +1 @@ +updates.jmonkeyengine.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC5bNOiZwU5dF62nBllxkjiSIfn0k6RVfprvO1aUypRmARD3/MKJKg7cGLezlLKaHZtVs84VpEqpmg5IzPAXWEmxUw1oke70uYMli7JV+4oPAeQRFwUdldP98I5h9VHwSjBqMycRLkxYaHF8edIPt1Zsa2dM3qrufy71ndQoFF6g7QxmT7gsTxwcNufDxymIgiAna/Qp2fr0YCLCiB8RQ7JTHfqA3dOWw0wz7AwfBTwwDCHkVxB5B4nz5iZxFr0scvqcae8vMncq8xKS7OMrLbn6asVaF6dDu+5Jc0mqxma5Qg7VC1xQXZsvlRISfrTFhQMhEx+j9w5snzihrlFnZ35 diff --git a/private/www-updater.key.enc b/private/www-updater.key.enc new file mode 100644 index 000000000..63dcb3723 Binary files /dev/null and b/private/www-updater.key.enc differ diff --git a/sdk/BasicGameTemplate/nbproject/project.properties b/sdk/BasicGameTemplate/nbproject/project.properties index ac4b3d2a6..8f2414b51 100644 --- a/sdk/BasicGameTemplate/nbproject/project.properties +++ b/sdk/BasicGameTemplate/nbproject/project.properties @@ -50,8 +50,8 @@ javac.compilerargs= javac.deprecation=false javac.processorpath=\ ${javac.classpath} -javac.source=1.5 -javac.target=1.5 +javac.source=1.6 +javac.target=1.6 javac.test.classpath=\ ${javac.classpath}:\ ${build.classes.dir} diff --git a/sdk/JME3TestsTemplate/build.xml b/sdk/JME3TestsTemplate/build.xml index c1f098b99..d39b505e6 100644 --- a/sdk/JME3TestsTemplate/build.xml +++ b/sdk/JME3TestsTemplate/build.xml @@ -51,8 +51,7 @@ -init-macrodef-junit: defines macro for junit execution -init-macrodef-debug: defines macro for class debugging -init-macrodef-java: defines macro for class execution - -do-jar-with-manifest: JAR building (if you are using a manifest) - -do-jar-without-manifest: JAR building (if you are not using a manifest) + -do-jar: JAR building run: execution of project -javadoc-build: Javadoc generation test-report: JUnit report generation diff --git a/sdk/JME3TestsTemplate/nbproject/genfiles.properties b/sdk/JME3TestsTemplate/nbproject/genfiles.properties index 6fb0f140e..eca6dafb7 100644 --- a/sdk/JME3TestsTemplate/nbproject/genfiles.properties +++ b/sdk/JME3TestsTemplate/nbproject/genfiles.properties @@ -1,8 +1,8 @@ -build.xml.data.CRC32=0f706f4a -build.xml.script.CRC32=0b0b23c4 -build.xml.stylesheet.CRC32=28e38971@1.38.1.45 -# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. -# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. -nbproject/build-impl.xml.data.CRC32=0f706f4a -nbproject/build-impl.xml.script.CRC32=46d1a69a -nbproject/build-impl.xml.stylesheet.CRC32=0ae3a408@1.44.1.45 +build.xml.data.CRC32=0f706f4a +build.xml.script.CRC32=82b8b23d +build.xml.stylesheet.CRC32=8064a381@1.75.2.48 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=0f706f4a +nbproject/build-impl.xml.script.CRC32=46d1a69a +nbproject/build-impl.xml.stylesheet.CRC32=0ae3a408@1.44.1.45 diff --git a/sdk/JME3TestsTemplate/nbproject/project.properties b/sdk/JME3TestsTemplate/nbproject/project.properties index 2a8d46f22..489a9c7d9 100644 --- a/sdk/JME3TestsTemplate/nbproject/project.properties +++ b/sdk/JME3TestsTemplate/nbproject/project.properties @@ -25,20 +25,26 @@ excludes= includes=** jar.compress=false javac.classpath=\ - ${libs.jme3.classpath}:\ - ${libs.jme3-libraries.classpath}:\ - ${libs.jme3-libraries-blender.classpath}:\ + ${libs.jme3-jogg.classpath}:\ + ${libs.jme3-blender.classpath}:\ + ${libs.jme3-networking.classpath}:\ + ${libs.jme3-plugins.classpath}:\ + ${libs.jme3-core.classpath}:\ + ${libs.jme3-desktop.classpath}:\ + ${libs.jme3-lwjgl.classpath}:\ + ${libs.jme3-niftygui.classpath}:\ + ${libs.jme3-effects.classpath}:\ + ${libs.jme3-terrain.classpath}:\ + ${libs.jme3-jbullet.classpath}:\ ${libs.jme3-test-data.classpath} # Space-separated list of extra javac options javac.compilerargs= javac.deprecation=false -javac.source=1.5 -javac.target=1.5 +javac.source=1.6 +javac.target=1.6 javac.test.classpath=\ ${javac.classpath}:\ - ${build.classes.dir}:\ - ${libs.junit.classpath}:\ - ${libs.junit_4.classpath} + ${build.classes.dir} javadoc.additionalparam= javadoc.author=false javadoc.encoding=${source.encoding} diff --git a/sdk/JME3TestsTemplateAndroid/nbproject/project.properties b/sdk/JME3TestsTemplateAndroid/nbproject/project.properties index e3a940489..f020f7d80 100644 --- a/sdk/JME3TestsTemplateAndroid/nbproject/project.properties +++ b/sdk/JME3TestsTemplateAndroid/nbproject/project.properties @@ -47,8 +47,8 @@ javac.compilerargs= javac.deprecation=false javac.processorpath=\ ${javac.classpath} -javac.source=1.5 -javac.target=1.5 +javac.source=1.6 +javac.target=1.6 javac.test.classpath=\ ${javac.classpath}:\ ${build.classes.dir} diff --git a/sdk/ant-jme/nbproject/project.properties b/sdk/ant-jme/nbproject/project.properties index 80281cc3b..3a1490871 100644 --- a/sdk/ant-jme/nbproject/project.properties +++ b/sdk/ant-jme/nbproject/project.properties @@ -36,8 +36,8 @@ javac.compilerargs= javac.deprecation=false javac.processorpath=\ ${javac.classpath} -javac.source=1.5 -javac.target=1.5 +javac.source=1.6 +javac.target=1.6 javac.test.classpath=\ ${javac.classpath}:\ ${build.classes.dir} diff --git a/sdk/build.gradle b/sdk/build.gradle index b70e80b13..99c850987 100644 --- a/sdk/build.gradle +++ b/sdk/build.gradle @@ -165,7 +165,7 @@ task createBaseXml(dependsOn: configurations.corelibs) <<{ "compile-dependency"{} "run-dependency"{ "release-version" "1" - "specification-version" "3.0.0" + "specification-version" jmeVersion } } } @@ -388,12 +388,14 @@ copyTestSources.outputs.dir "JME3TestsTemplate/src/" copyTestSources.outputs.dir "JME3TestsTemplateAndroid/src/" ant.properties['plugins.version'] = jmeVersion -ant.properties['app.version']= jmeMainVersion + "-" + jmeVersionTag +ant.properties['app.version']= jmeFullVersion +ant.properties['nbm.revision']= jmeNbmRevision task buildSdk(dependsOn: [copyBaseLibs, copyProjectLibs, createProjectXml, createBaseXml, copyTestSources]) <<{ ant.propertyfile(file: "nbproject/project.properties") { entry( key: "plugins.version", value: "${jmeVersion}") - entry( key: "app.version", value: "${jmeMainVersion + "-" + jmeVersionTag}") + entry( key: "app.version", value: "${jmeFullVersion}") + entry( key: "nbm.revision", value: "${jmeNbmRevision}") } ant.ant(dir: ".", antfile: "build.xml", target: "build") } @@ -416,7 +418,7 @@ task cleanSdk() <<{ file("JME3TestsTemplateAndroid/src/jmetest/").deleteDir() } -jar.dependsOn(buildSdk) -clean.dependsOn(cleanSdk); - +tasks.remove(uploadArchives) +jar.dependsOn(buildSdk) +clean.dependsOn(cleanSdk) diff --git a/sdk/build.xml b/sdk/build.xml index acc5c1d04..ffa0b8fe8 100644 --- a/sdk/build.xml +++ b/sdk/build.xml @@ -12,7 +12,6 @@ - @@ -157,7 +156,7 @@ replace="OpenIDE-Module-Specification-Version: ${plugins.version}" byline="true"/> @@ -167,7 +166,7 @@ replace="OpenIDE-Module-Implementation-Version: 0" byline="true"/> @@ -176,9 +175,6 @@ - - - @@ -191,105 +187,19 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Setting implementation version for ${module_dir} to revision: ${svn.LastChangedRev} - + Setting implementation version for ${module_dir} to revision: ${nbm.revision} + - Removing implementation version for ${module_dir} from revision: ${svn.LastChangedRev} - + Removing implementation version for ${module_dir} from revision: ${nbm.revision} + - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -298,7 +208,7 @@ - + @@ -311,6 +221,8 @@ + + @@ -339,7 +251,7 @@ section="devel" depends="sun-java6-jdk" maintainer="jMonkeyEngine" - homepage="http://www.jmonkeyengine.com" + homepage="http://www.jmonkeyengine.org" postrm="debscripts/postrm" > @@ -360,57 +272,4 @@ - - - - Upload windows installers to googlecode.. - - - Upload linux installers to googlecode.. - - - Upload mac installer to googlecode.. - - - - - - - - diff --git a/sdk/jdks/build-osx-zip.sh b/sdk/jdks/build-osx-zip.sh index cf1051901..db3c44e99 100755 --- a/sdk/jdks/build-osx-zip.sh +++ b/sdk/jdks/build-osx-zip.sh @@ -1,5 +1,5 @@ #!/bin/sh -#(c) jMonkeyEngine.com +#(c) jmonkeyengine.org #Author Normen Hansen set -e rm -rf jdk-macosx.zip diff --git a/sdk/jdks/build-package.sh b/sdk/jdks/build-package.sh index c11a8ff2f..6f9c53503 100755 --- a/sdk/jdks/build-package.sh +++ b/sdk/jdks/build-package.sh @@ -1,6 +1,6 @@ #!/bin/bash set -e -#(c) jMonkeyEngine.com +#(c) jmonkeyengine.org #This script creates SFX binaries of the JDK for the specified platform #Author Normen Hansen diff --git a/sdk/jme3-android/nbproject/project.properties b/sdk/jme3-android/nbproject/project.properties index e2ab10b96..9b1b7cb61 100644 --- a/sdk/jme3-android/nbproject/project.properties +++ b/sdk/jme3-android/nbproject/project.properties @@ -3,7 +3,7 @@ javac.source=1.6 javac.compilerargs=-Xlint -Xlint:-serial license.file=../license-jme.txt -nbm.homepage=http://www.jmonkeyengine.com +nbm.homepage=http://www.jmonkeyengine.org nbm.module.author=Normen Hansen nbm.needs.restart=true spec.version.base=3.1.0 diff --git a/sdk/jme3-angelfont/nbproject/project.properties b/sdk/jme3-angelfont/nbproject/project.properties index 44c34ecb9..2cf7a410b 100644 --- a/sdk/jme3-angelfont/nbproject/project.properties +++ b/sdk/jme3-angelfont/nbproject/project.properties @@ -1,4 +1,6 @@ #Thu, 25 Aug 2011 20:26:50 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial +nbm.homepage=http\://www.jmonkeyengine.org +nbm.module.author=Normen Hansen spec.version.base=3.1.0 diff --git a/sdk/jme3-assetpack-support/nbproject/project.properties b/sdk/jme3-assetpack-support/nbproject/project.properties index e0b462857..eec6af9cd 100644 --- a/sdk/jme3-assetpack-support/nbproject/project.properties +++ b/sdk/jme3-assetpack-support/nbproject/project.properties @@ -1,8 +1,8 @@ #Thu, 25 Aug 2011 20:26:49 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial license.file=../license-jme.txt -nbm.homepage=http\://www.jmonkeyengine.com +nbm.homepage=http\://www.jmonkeyengine.org nbm.module.author=Normen Hansen nbm.needs.restart=true spec.version.base=3.1.0 diff --git a/sdk/jme3-blender/nbproject/project.properties b/sdk/jme3-blender/nbproject/project.properties index 33a6b9205..b47098087 100644 --- a/sdk/jme3-blender/nbproject/project.properties +++ b/sdk/jme3-blender/nbproject/project.properties @@ -1,7 +1,8 @@ #Thu, 25 Aug 2011 20:26:50 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial -nbm.homepage=http\://www.jmonkeyengine.com +license.file=../license-jme.txt +nbm.homepage=http\://www.jmonkeyengine.org nbm.module.author=Kaelthas nbm.needs.restart=true spec.version.base=3.1.0 diff --git a/sdk/jme3-blender/src/com/jme3/gde/blender/BlenderTool.java b/sdk/jme3-blender/src/com/jme3/gde/blender/BlenderTool.java index 0211cae7a..1d55a6b35 100644 --- a/sdk/jme3-blender/src/com/jme3/gde/blender/BlenderTool.java +++ b/sdk/jme3-blender/src/com/jme3/gde/blender/BlenderTool.java @@ -164,6 +164,14 @@ public class BlenderTool { return "../blender"; } } + + private static String getBlenderOsSettingsPath() { + if (Utilities.isMac()) { + return "../blender/blender.app/Contents/Resources"; + } else { + return "../blender"; + } + } private static boolean checkBlenderFolders() { String jmpDir = Places.getUserDirectory().getAbsolutePath(); @@ -251,9 +259,9 @@ public class BlenderTool { } private static File getBlenderSettingsFolder() { - File blender = InstalledFileLocator.getDefault().locate(getBlenderOsPath() + "/2.69", null, false); + File blender = InstalledFileLocator.getDefault().locate(getBlenderOsSettingsPath() + "/2.75", null, false); if (blender == null) { - blender = InstalledFileLocator.getDefault().locate(getBlenderOsPath() + "/2.67", null, false); + blender = InstalledFileLocator.getDefault().locate(getBlenderOsSettingsPath() + "/2.69", null, false); } if (blender == null) { DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message("Error finding Blender settings")); diff --git a/sdk/jme3-cinematics/nbproject/project.properties b/sdk/jme3-cinematics/nbproject/project.properties index 437a62d3a..4b4ae0191 100644 --- a/sdk/jme3-cinematics/nbproject/project.properties +++ b/sdk/jme3-cinematics/nbproject/project.properties @@ -1,8 +1,8 @@ #Thu, 25 Aug 2011 20:26:50 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial license.file=../license-jme.txt -nbm.homepage=http\://www.jmonkeyengine.com +nbm.homepage=http\://www.jmonkeyengine.org nbm.module.author=R\u00e9my Bouquet nbm.needs.restart=true spec.version.base=3.1.0 diff --git a/sdk/jme3-code-check/nbproject/project.properties b/sdk/jme3-code-check/nbproject/project.properties index 0411b6ff9..6700898e0 100644 --- a/sdk/jme3-code-check/nbproject/project.properties +++ b/sdk/jme3-code-check/nbproject/project.properties @@ -1,4 +1,7 @@ #Thu, 25 Aug 2011 20:26:50 +0200 javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial +license.file=../license-jme.txt +nbm.homepage=http\://www.jmonkeyengine.org +nbm.module.author=Normen Hansen spec.version.base=3.1.0 diff --git a/sdk/jme3-codepalette/nbproject/project.properties b/sdk/jme3-codepalette/nbproject/project.properties index e0b462857..eec6af9cd 100644 --- a/sdk/jme3-codepalette/nbproject/project.properties +++ b/sdk/jme3-codepalette/nbproject/project.properties @@ -1,8 +1,8 @@ #Thu, 25 Aug 2011 20:26:49 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial license.file=../license-jme.txt -nbm.homepage=http\://www.jmonkeyengine.com +nbm.homepage=http\://www.jmonkeyengine.org nbm.module.author=Normen Hansen nbm.needs.restart=true spec.version.base=3.1.0 diff --git a/sdk/jme3-core-baselibs/nbproject/genfiles.properties b/sdk/jme3-core-baselibs/nbproject/genfiles.properties index 1b1c32b3b..c9714ad4e 100644 --- a/sdk/jme3-core-baselibs/nbproject/genfiles.properties +++ b/sdk/jme3-core-baselibs/nbproject/genfiles.properties @@ -1,8 +1,8 @@ -build.xml.data.CRC32=278ea45d +build.xml.data.CRC32=d43b0890 build.xml.script.CRC32=cdae6a36 build.xml.stylesheet.CRC32=a56c6a5b@2.67.1 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. -nbproject/build-impl.xml.data.CRC32=278ea45d +nbproject/build-impl.xml.data.CRC32=d43b0890 nbproject/build-impl.xml.script.CRC32=246f9b81 nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.67.1 diff --git a/sdk/jme3-core-baselibs/nbproject/project.properties b/sdk/jme3-core-baselibs/nbproject/project.properties index 8bcd2222a..d4692bc80 100644 --- a/sdk/jme3-core-baselibs/nbproject/project.properties +++ b/sdk/jme3-core-baselibs/nbproject/project.properties @@ -1,7 +1,7 @@ -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial license.file=../license-jme.txt -nbm.homepage=http\://www.jmonkeyengine.com +nbm.homepage=http\://www.jmonkeyengine.org nbm.module.author=jMonkeyEngine nbm.needs.restart=true spec.version.base=3.1.0 diff --git a/sdk/jme3-core-baselibs/nbproject/project.xml b/sdk/jme3-core-baselibs/nbproject/project.xml index df81e68ff..be7a3e038 100644 --- a/sdk/jme3-core-baselibs/nbproject/project.xml +++ b/sdk/jme3-core-baselibs/nbproject/project.xml @@ -1,15 +1,15 @@ - - + + org.netbeans.modules.apisupport.project - + com.jme3.gde.core.baselibs - + com.jme3.gde.core.libraries - - + + 1 3.1.0 @@ -19,133 +19,142 @@ com.jme3.asset com.jme3.scene.plugins.blender - com.jme3.scene.plugins.blender.animations - com.jme3.scene.plugins.blender.cameras + com.jme3.scene.plugins.blender.math com.jme3.scene.plugins.blender.constraints com.jme3.scene.plugins.blender.constraints.definitions com.jme3.scene.plugins.blender.curves - com.jme3.scene.plugins.blender.file - com.jme3.scene.plugins.blender.landscape - com.jme3.scene.plugins.blender.lights - com.jme3.scene.plugins.blender.materials - com.jme3.scene.plugins.blender.math com.jme3.scene.plugins.blender.meshes - com.jme3.scene.plugins.blender.modifiers - com.jme3.scene.plugins.blender.objects com.jme3.scene.plugins.blender.particles + com.jme3.scene.plugins.blender.cameras + com.jme3.scene.plugins.blender.objects + com.jme3.scene.plugins.blender.landscape + com.jme3.scene.plugins.blender.modifiers com.jme3.scene.plugins.blender.textures + com.jme3.scene.plugins.blender.textures.io com.jme3.scene.plugins.blender.textures.blending com.jme3.scene.plugins.blender.textures.generating - com.jme3.scene.plugins.blender.textures.io - checkers.quals - com.jme3.animation - com.jme3.app - com.jme3.app.state - com.jme3.asset.cache - com.jme3.asset.plugins - com.jme3.audio - com.jme3.audio.openal - com.jme3.audio.plugins - com.jme3.bounding - com.jme3.cinematic - com.jme3.cinematic.events - com.jme3.collision - com.jme3.collision.bih - com.jme3.cursors.plugins - com.jme3.effect - com.jme3.effect.influencers - com.jme3.effect.shapes + com.jme3.scene.plugins.blender.animations + com.jme3.scene.plugins.blender.materials + com.jme3.scene.plugins.blender.file + com.jme3.scene.plugins.blender.lights + jme3tools.shader + jme3tools.savegame + jme3tools.shadercheck + jme3tools.optimize + jme3tools.converters + com.jme3.shader + com.jme3.shader.plugins com.jme3.export com.jme3.export.binary - com.jme3.font - com.jme3.font.plugins + com.jme3.cinematic + com.jme3.cinematic.events + com.jme3.math + com.jme3.util + com.jme3.util.blockparser + com.jme3.util.xml + com.jme3.post com.jme3.input - com.jme3.input.controls com.jme3.input.dummy + com.jme3.input.controls com.jme3.input.event - com.jme3.light + com.jme3.profile + com.jme3.ui + com.jme3.audio + com.jme3.audio.openal + com.jme3.audio.plugins + com.jme3.cursors.plugins + com.jme3.bounding + com.jme3.shadow + com.jme3.texture + com.jme3.texture.image + com.jme3.texture.plugins + com.jme3.system com.jme3.material com.jme3.material.plugins - com.jme3.math - com.jme3.post - com.jme3.profile com.jme3.renderer - com.jme3.renderer.opengl com.jme3.renderer.queue + com.jme3.renderer.opengl + com.jme3.effect + com.jme3.effect.shapes + com.jme3.effect.influencers + com.jme3.app + com.jme3.app.state + com.jme3.asset.plugins + com.jme3.asset.cache + com.jme3.light + com.jme3.animation + com.jme3.collision + com.jme3.collision.bih com.jme3.scene - com.jme3.scene.control + com.jme3.scene.shape + com.jme3.scene.plugins com.jme3.scene.debug com.jme3.scene.instancing + com.jme3.scene.control com.jme3.scene.mesh - com.jme3.scene.plugins - com.jme3.scene.shape - com.jme3.shader - com.jme3.shader.plugins - com.jme3.shadow - com.jme3.system - com.jme3.texture - com.jme3.texture.image - com.jme3.texture.plugins - com.jme3.ui - com.jme3.util - com.jme3.util.blockparser - com.jme3.util.xml - jme3tools.converters - jme3tools.converters.model - jme3tools.converters.model.strip - jme3tools.optimize - jme3tools.savegame - jme3tools.shader - jme3tools.shadercheck + com.jme3.font + com.jme3.font.plugins + checkers.quals + jme3tools.navigation com.jme3.input.awt com.jme3.system.awt - jme3tools.navigation - com.jme3.post.filters com.jme3.post.ssao + com.jme3.post.filters com.jme3.water com.jme3.bullet - com.jme3.bullet.collision - com.jme3.bullet.collision.shapes - com.jme3.bullet.collision.shapes.infos - com.jme3.bullet.control - com.jme3.bullet.control.ragdoll - com.jme3.bullet.debug + com.jme3.bullet.util com.jme3.bullet.joints com.jme3.bullet.joints.motors com.jme3.bullet.objects com.jme3.bullet.objects.infos - com.jme3.bullet.util - com.jme3.audio.lwjgl + com.jme3.bullet.debug + com.jme3.bullet.control + com.jme3.bullet.control.ragdoll + com.jme3.bullet.collision + com.jme3.bullet.collision.shapes + com.jme3.bullet.collision.shapes.infos com.jme3.input.lwjgl - com.jme3.renderer.lwjgl + com.jme3.audio.lwjgl com.jme3.system.lwjgl + com.jme3.renderer.lwjgl com.jme3.network - com.jme3.network.base com.jme3.network.kernel - com.jme3.network.kernel.tcp com.jme3.network.kernel.udp + com.jme3.network.kernel.tcp + com.jme3.network.util com.jme3.network.message com.jme3.network.rmi + com.jme3.network.base com.jme3.network.serializing com.jme3.network.serializing.serializers + com.jme3.network.service + com.jme3.network.service.rpc + com.jme3.network.service.rpc.msg + com.jme3.network.service.serializer com.jme3.niftygui com.jme3.export.xml com.jme3.scene.plugins.fbx + com.jme3.scene.plugins.fbx.obj + com.jme3.scene.plugins.fbx.anim + com.jme3.scene.plugins.fbx.node + com.jme3.scene.plugins.fbx.misc + com.jme3.scene.plugins.fbx.material com.jme3.scene.plugins.fbx.file + com.jme3.scene.plugins.fbx.mesh com.jme3.scene.plugins.ogre com.jme3.scene.plugins.ogre.matext com.jme3.terrain + com.jme3.terrain.heightmap com.jme3.terrain.geomipmap + com.jme3.terrain.geomipmap.picking com.jme3.terrain.geomipmap.grid com.jme3.terrain.geomipmap.lodcalc com.jme3.terrain.geomipmap.lodcalc.util - com.jme3.terrain.geomipmap.picking - com.jme3.terrain.heightmap com.jme3.terrain.noise - com.jme3.terrain.noise.basis com.jme3.terrain.noise.filter - com.jme3.terrain.noise.fractal com.jme3.terrain.noise.modulator + com.jme3.terrain.noise.fractal + com.jme3.terrain.noise.basis ext/jme3-blender-3.1.0-snapshot-github.jar @@ -193,4 +202,4 @@ - + \ No newline at end of file diff --git a/sdk/jme3-core-libraries/nbproject/project.properties b/sdk/jme3-core-libraries/nbproject/project.properties index 2e01f5d86..513fb20e4 100644 --- a/sdk/jme3-core-libraries/nbproject/project.properties +++ b/sdk/jme3-core-libraries/nbproject/project.properties @@ -1,8 +1,8 @@ #Thu, 25 Aug 2011 20:26:48 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial license.file=../license-jme.txt -nbm.homepage=http\://www.jmonkeyengine.com +nbm.homepage=http\://www.jmonkeyengine.org nbm.module.author=jMonkeyEngine nbm.needs.restart=true spec.version.base=3.1.0 diff --git a/sdk/jme3-core-libraries/nbproject/project.xml b/sdk/jme3-core-libraries/nbproject/project.xml index 19469cf8a..c7b1f70f9 100644 --- a/sdk/jme3-core-libraries/nbproject/project.xml +++ b/sdk/jme3-core-libraries/nbproject/project.xml @@ -6,6 +6,44 @@ + org.ejml + org.ejml.interfaces.decomposition + org.ejml.interfaces.linsol + org.ejml.data + org.ejml.alg.dense.linsol + org.ejml.ops + org.ejml.factory + org.ejml.alg.fixed + org.ejml.alg.generic + org.ejml.alg.block + org.ejml.alg.block.decomposition.chol + org.ejml.alg.block.decomposition.qr + org.ejml.alg.block.decomposition.hessenberg + org.ejml.alg.block.decomposition.bidiagonal + org.ejml.alg.block.linsol.chol + org.ejml.alg.block.linsol.qr + org.ejml.alg.dense.decomposition + org.ejml.alg.dense.decomposition.chol + org.ejml.alg.dense.decomposition.lu + org.ejml.alg.dense.decomposition.qr + org.ejml.alg.dense.decomposition.hessenberg + org.ejml.alg.dense.decomposition.svd + org.ejml.alg.dense.decomposition.svd.implicitqr + org.ejml.alg.dense.decomposition.eig + org.ejml.alg.dense.decomposition.eig.watched + org.ejml.alg.dense.decomposition.eig.symm + org.ejml.alg.dense.decomposition.bidiagonal + org.ejml.alg.dense.mult + org.ejml.alg.dense.misc + org.ejml.alg.dense.linsol.chol + org.ejml.alg.dense.linsol.lu + org.ejml.alg.dense.linsol.qr + org.ejml.alg.dense.linsol.svd + org.ejml.simple + org.ejml.alg.dense.decompose + org.ejml.alg.dense.decompose.chol + org.ejml.alg.dense.decompose.lu + org.ejml.alg.dense.decompose.qr com.bulletphysics com.bulletphysics.collision.broadphase com.bulletphysics.collision.dispatch @@ -161,6 +199,22 @@ org.jglfont.impl.format.awt org.jglfont.impl + + ext/core-0.27.jar + release/modules/ext/core-0.27.jar + + + ext/dense64-0.27.jar + release/modules/ext/dense64-0.27.jar + + + ext/simple-0.27.jar + release/modules/ext/simple-0.27.jar + + + ext/denseC64-0.27.jar + release/modules/ext/denseC64-0.27.jar + ext/jbullet.jar release/modules/ext/jbullet.jar diff --git a/sdk/jme3-core-updatecenters/nbproject/genfiles.properties b/sdk/jme3-core-updatecenters/nbproject/genfiles.properties index 0dd897993..6b53da996 100644 --- a/sdk/jme3-core-updatecenters/nbproject/genfiles.properties +++ b/sdk/jme3-core-updatecenters/nbproject/genfiles.properties @@ -1,8 +1,8 @@ -build.xml.data.CRC32=08468784 +build.xml.data.CRC32=e145fa2a build.xml.script.CRC32=cfa8d5c5 build.xml.stylesheet.CRC32=a56c6a5b@2.67.1 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. -nbproject/build-impl.xml.data.CRC32=08468784 +nbproject/build-impl.xml.data.CRC32=e145fa2a nbproject/build-impl.xml.script.CRC32=270846fb nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.67.1 diff --git a/sdk/jme3-core-updatecenters/nbproject/project.properties b/sdk/jme3-core-updatecenters/nbproject/project.properties index 9d2616783..98f519f77 100644 --- a/sdk/jme3-core-updatecenters/nbproject/project.properties +++ b/sdk/jme3-core-updatecenters/nbproject/project.properties @@ -1,4 +1,4 @@ #Thu, 25 Aug 2011 20:26:49 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial spec.version.base=3.1.0 diff --git a/sdk/jme3-core-updatecenters/nbproject/project.xml b/sdk/jme3-core-updatecenters/nbproject/project.xml index 3979d8b02..abc894aed 100644 --- a/sdk/jme3-core-updatecenters/nbproject/project.xml +++ b/sdk/jme3-core-updatecenters/nbproject/project.xml @@ -8,6 +8,8 @@ org.netbeans.modules.autoupdate.services + + 1.47.2 diff --git a/sdk/jme3-core-updatecenters/src/META-INF/services/org.netbeans.spi.autoupdate.KeyStoreProvider b/sdk/jme3-core-updatecenters/src/META-INF/services/org.netbeans.spi.autoupdate.KeyStoreProvider new file mode 100644 index 000000000..1af1a906c --- /dev/null +++ b/sdk/jme3-core-updatecenters/src/META-INF/services/org.netbeans.spi.autoupdate.KeyStoreProvider @@ -0,0 +1 @@ +com.jme3.gde.core.updatecenters.keystore.JmeKeyStoreProvider diff --git a/sdk/jme3-core-updatecenters/src/com/jme3/gde/core/updatecenters/Bundle.properties b/sdk/jme3-core-updatecenters/src/com/jme3/gde/core/updatecenters/Bundle.properties index 5a898643f..eb84743c9 100644 --- a/sdk/jme3-core-updatecenters/src/com/jme3/gde/core/updatecenters/Bundle.properties +++ b/sdk/jme3-core-updatecenters/src/com/jme3/gde/core/updatecenters/Bundle.properties @@ -1,7 +1,7 @@ #jMP update centers -com_jme3_gde_core_update_center_nightly=http://updates.jmonkeyengine.org/nightly/3.0/plugins/updates.xml -com_jme3_gde_core_update_center_stable=http://updates.jmonkeyengine.org/stable/3.0/plugins/updates.xml -com_jme3_jmp_contributions_update_center=http://updates.jmonkeyengine.org/contributions/updates.xml +com_jme3_gde_core_update_center_nightly=http://updates.jmonkeyengine.org/nightly/3.1/plugins/updates.xml +com_jme3_gde_core_update_center_stable=http://updates.jmonkeyengine.org/stable/3.1/plugins/updates.xml +com_jme3_jmp_contributions_update_center=http://updates.jmonkeyengine.org/contrib/3.1/updates.xml #jMP update centers Services/AutoupdateType/com_jme3_gde_core_update_center_nightly.instance=jMonkeyEngine SDK Nightly (Breaks!) diff --git a/sdk/jme3-core-updatecenters/src/com/jme3/gde/core/updatecenters/keystore/JmeKeyStoreProvider.java b/sdk/jme3-core-updatecenters/src/com/jme3/gde/core/updatecenters/keystore/JmeKeyStoreProvider.java new file mode 100644 index 000000000..d94e548bd --- /dev/null +++ b/sdk/jme3-core-updatecenters/src/com/jme3/gde/core/updatecenters/keystore/JmeKeyStoreProvider.java @@ -0,0 +1,47 @@ +package com.jme3.gde.core.updatecenters.keystore; + +import java.io.IOException; +import java.io.InputStream; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import org.netbeans.spi.autoupdate.KeyStoreProvider; +import org.openide.util.Exceptions; + +/** + * Loads the jMonkeyEngine SDK Plugins certificates into the AutoUpdate system. + * + * @author Kirill Vainer + */ +public class JmeKeyStoreProvider implements KeyStoreProvider { + + @Override + public KeyStore getKeyStore() { + InputStream in = null; + try { + in = JmeKeyStoreProvider.class.getResourceAsStream("trustedcerts.jks"); + KeyStore store = KeyStore.getInstance("JKS"); + store.load(in, "trustedcerts".toCharArray()); + return store; + } catch (KeyStoreException ex) { + Exceptions.printStackTrace(ex); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } catch (NoSuchAlgorithmException ex) { + Exceptions.printStackTrace(ex); + } catch (CertificateException ex) { + Exceptions.printStackTrace(ex); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + } + return null; + } + +} diff --git a/sdk/jme3-core-updatecenters/src/com/jme3/gde/core/updatecenters/keystore/trustedcerts.jks b/sdk/jme3-core-updatecenters/src/com/jme3/gde/core/updatecenters/keystore/trustedcerts.jks new file mode 100644 index 000000000..fef5a315c Binary files /dev/null and b/sdk/jme3-core-updatecenters/src/com/jme3/gde/core/updatecenters/keystore/trustedcerts.jks differ diff --git a/sdk/jme3-core/nbproject/project.properties b/sdk/jme3-core/nbproject/project.properties index 4206d1dff..88500da6c 100644 --- a/sdk/jme3-core/nbproject/project.properties +++ b/sdk/jme3-core/nbproject/project.properties @@ -1,10 +1,10 @@ #Thu, 25 Aug 2011 20:26:48 +0200 file.reference.DDSUtils.jar=release/modules/ext/DDSUtils.jar #Thu, 25 Aug 2011 19:32:54 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial license.file=../license-jme.txt -nbm.homepage=http\://www.jmonkeyengine.com +nbm.homepage=http\://www.jmonkeyengine.org nbm.module.author=Normen Hansen nbm.needs.restart=true project.license=jme diff --git a/sdk/jme3-dark-laf/README.md b/sdk/jme3-dark-laf/README.md new file mode 100644 index 000000000..0dbb8d231 --- /dev/null +++ b/sdk/jme3-dark-laf/README.md @@ -0,0 +1,10 @@ +# DarkMonkey +Netbeans LAF and FAC combo - uses NimROD and Obsidian + +This is a plug-in for for Netbeans 8+ (well, the version it was developed for is 8.0.2). We wanted a dark theme variant for the jMonkeyEngine 3.1 sdk, so we made one. Enjoy! + +![DarkMonkey Screenshot](http://jme-hub-cdn.jmonkeyengineor.netdna-cdn.com/uploads/default/_optimized/fdd/136/87eb8a1efd_690x387.png) + +## Features +- Adds the DarkMonkey LaF to the Netbeans 8 environment under appearance - It's NimROD with a couple of tweaks. We've just adapted Nilo's wonderful project for the look we were going for. +- Adds the DarkMonkey FaC to the editor profile listing - It's Obsidian with some tweaks. DejaVu Sans Mono brings some sophistication to an otherwise courier world. diff --git a/sdk/jme3-dark-laf/build.xml b/sdk/jme3-dark-laf/build.xml new file mode 100644 index 000000000..6a5f08ba7 --- /dev/null +++ b/sdk/jme3-dark-laf/build.xml @@ -0,0 +1,8 @@ + + + + + + Builds, tests, and runs the project org.jme3.netbeans.plaf.darkmonkey. + + diff --git a/sdk/jme3-dark-laf/manifest.mf b/sdk/jme3-dark-laf/manifest.mf new file mode 100644 index 000000000..b1505dfad --- /dev/null +++ b/sdk/jme3-dark-laf/manifest.mf @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +OpenIDE-Module: org.jme3.netbeans.plaf.darkmonkey/1 +OpenIDE-Module-Implementation-Version: 0 +OpenIDE-Module-Install: org/jme3/netbeans/plaf/darkmonkey/Installer.class +OpenIDE-Module-Layer: org/jme3/netbeans/plaf/darkmonkey/layer.xml +OpenIDE-Module-Localizing-Bundle: org/jme3/netbeans/plaf/darkmonkey/Bundle.properties + diff --git a/sdk/jme3-dark-laf/nbproject/build-impl.xml b/sdk/jme3-dark-laf/nbproject/build-impl.xml new file mode 100644 index 000000000..2057e4b42 --- /dev/null +++ b/sdk/jme3-dark-laf/nbproject/build-impl.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + You must set 'suite.dir' to point to your containing module suite + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/nbproject/genfiles.properties b/sdk/jme3-dark-laf/nbproject/genfiles.properties new file mode 100644 index 000000000..9adf50476 --- /dev/null +++ b/sdk/jme3-dark-laf/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=8f3042a8 +build.xml.script.CRC32=c15f5ee0 +build.xml.stylesheet.CRC32=a56c6a5b@2.67.1 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=8f3042a8 +nbproject/build-impl.xml.script.CRC32=4524e469 +nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.67.1 diff --git a/sdk/jme3-dark-laf/nbproject/project.properties b/sdk/jme3-dark-laf/nbproject/project.properties new file mode 100644 index 000000000..c023595b6 --- /dev/null +++ b/sdk/jme3-dark-laf/nbproject/project.properties @@ -0,0 +1,8 @@ +file.reference.nimrodlf.jar=release/modules/ext/nimrodlf.jar +javac.source=1.7 +javac.compilerargs=-Xlint -Xlint:-serial +license.file=../license-jme.txt +nbm.homepage=http://www.jmonkeyengine.org +nbm.module.author=Charles Anderson, R\u00e9my Bouquet +nbm.needs.restart=true +spec.version.base=3.1.0 diff --git a/sdk/jme3-dark-laf/nbproject/project.xml b/sdk/jme3-dark-laf/nbproject/project.xml new file mode 100644 index 000000000..9d6be0056 --- /dev/null +++ b/sdk/jme3-dark-laf/nbproject/project.xml @@ -0,0 +1,49 @@ + + + org.netbeans.modules.apisupport.project + + + org.jme3.netbeans.plaf.darkmonkey + + + + org.openide.awt + + + + 7.62.1 + + + + org.openide.modules + + + + 7.43.1 + + + + org.openide.util + + + + 8.39.1 + + + + org.openide.windows + + + + 6.71.1 + + + + + + ext/nimrodlf.jar + release/modules/ext/nimrodlf.jar + + + + diff --git a/sdk/jme3-dark-laf/nbproject/suite.properties b/sdk/jme3-dark-laf/nbproject/suite.properties new file mode 100644 index 000000000..29d7cc9bd --- /dev/null +++ b/sdk/jme3-dark-laf/nbproject/suite.properties @@ -0,0 +1 @@ +suite.dir=${basedir}/.. diff --git a/sdk/jme3-dark-laf/release/modules/ext/nimrodlf.jar b/sdk/jme3-dark-laf/release/modules/ext/nimrodlf.jar new file mode 100644 index 000000000..676f9b592 Binary files /dev/null and b/sdk/jme3-dark-laf/release/modules/ext/nimrodlf.jar differ diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/Bundle.properties b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/Bundle.properties new file mode 100644 index 000000000..1cc1695f7 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/Bundle.properties @@ -0,0 +1,10 @@ +OpenIDE-Module-Name=DarkMonkey +OpenIDE-Module-Display-Category=Appearance +OpenIDE-Module-Short-Description=Contains DarkMonkey theme for the JME3.1 stable release +OpenIDE-Module-Long-Description=\ +

    DarkMonkey Theme

    This is a Fonts/Colors and LookAndFeel combo that utilizes James McFadden's Obsidian Fonts/Colorsand Nilo Gonzalez's Nimrod LookAndFeel which isbased on the Metal LookAndFeel. \ + This module just checks and sees if the user already has the components, and if not, installs the theme and activates a few options:\n

    • under Tools - Options - Appearance - LookAndFeel it will have "DarkMonkey" , available.\ +
    • It also adds a Fonts/Colors Profile called "Dark Monkey".\ +

    We hope you like it!\ +

    For More Information visit: DarkMonkey Development Thread
    + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/DMUtils.java b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/DMUtils.java new file mode 100644 index 000000000..40470a535 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/DMUtils.java @@ -0,0 +1,288 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.jme3.netbeans.plaf.darkmonkey; + +import java.awt.Color; +import java.awt.Font; +import java.awt.FontFormatException; +import java.awt.GraphicsEnvironment; +import java.awt.image.BandedSampleModel; +import java.awt.image.BufferedImage; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferFloat; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import javax.imageio.ImageIO; + +/** + * I figured it would be best to have a Utilities type class to store the + * Methods I commonly use. Resources, registering stuff, resolving, transforming + * and so on... + * + * @author charles + */ +public class DMUtils { + + /** + *

    + * This method loads a picture from a relative path string. The relative + * path's root directory is understood to be inside of a jar... and in + * relation to the package of the referring Object instance. + *

    + *

    + * For example: if the object is an instance of + * org.jme3.netbeans.plaf.darkmonkey.DarkMonkeyIconFactory.class, and the + * string is "icons/MyCloseIcon.png", it will attempt to load + * org/jme3/netbeans/plaf/darkmonkey/icons/MyCloseIcon.png from + * DarkMonkeyIconFactory's jar file. + *

    + * It will print a stack trace if you get the relative path wrong. + * + * @param refObj - Reference Object(Object) - meant for a standard 'this' + * call, though any Instantiated class can be used. This is part of a + * workaround for Netbean's multiple class loader system. + * @param fileName - File Name(String) - the path to an image relative to + * the Reference Object's location in a jar file. + * @return BufferedImage - Freshly converted from the image file found at + * the location. + */ + public static BufferedImage loadImagefromJar(Object refObj, String fileName) { + BufferedImage bi = null; + try { + bi = ImageIO.read(refObj.getClass().getResourceAsStream(fileName)); + } catch (IOException e) { + // File is probably referenced wrong or "mispleled"... lol. + e.printStackTrace(); + } + return bi; + } + + /**

    + * This utility method is designed to Load OpenType/TrueType fonts into the + * current Runtime Environment without installing them to the OS. It takes + * the base path of the refObj and loads font files located relative to it. + * It checks to make sure that the fonts are not already installed in the system + * OS, first. If they are already installed, it does nothing more. + *

    + * Typical Usage - DMUtils.loadFontsFromJar(this, someFontFiles);
    + * and then someFontFiles[0] would contain something like "myfonts/DisFontPlain.ttf" + *

    + * @param refObj - Object - Usually just a *this*, but useful for a multiClassLoader + * type situation. + * @param fileNames - String[] - an array of {relative path + filename} strings for loading + * TrueType or OpenType fonts + */ + public static void loadFontsFromJar(Object refObj, String[] fileNames) { + //first, we grab ahold of what all fonts are in the JRE's system + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + Font[] fontsListing = ge.getAllFonts(); + + /* // this can be uncommented if you want to see all the fonts in the JRE + for (Font fontInListing : fontsListing) { + System.out.println(fontInListing.getFontName() + " : " + fontInListing.getFamily()); + } + */ + + // Then we go and process the incoming streams + InputStream inStream; + Font checkFont; + try { + toNextFileName: + for (String fileName : fileNames) {// load up the fileName to process... + checkFont = Font.createFont(Font.TRUETYPE_FONT, refObj.getClass().getResourceAsStream(fileName)); + for (Font fontInListing : fontsListing) {// check if it's already on the list + if (fontInListing.getFontName().equals(checkFont.getFontName())) { + continue toNextFileName; //head to the next file if we find it... + } + } + ge.registerFont(checkFont);// and register it if we don't.... + } + } catch (FontFormatException | IOException e) { + // a File is probably referenced wrong or "mispleled"... lol. + // you can alternativly send a single String for debugging purposes + e.printStackTrace(); + } + + } + + /** + * This method transforms the inputed BufferedImage by the supplied Color[]. + * The behavior treats the Color[] as Ordered Passes A, R, G, B for .length + * 4 or more. It treats it as Ordered Passes R, G, B only for .length 3 or + * less. + * + * @param colorSet Color[] - that processes [1..4] up to four palette + * colors. 3 or less uses R,G,B passes only. 4 uses A,R,G,B and ignores + * anything more. + * @param clearToColorRequested - Color - A color to Blend with the First + * Translucent Pass - Optional + * @param argbMappedBufferedImage - BufferedImage - The image containing + * Channels as Alpha for the Palette + * @return BufferedImage - a new BufferedImage() transformed by the palette. + */ + public static BufferedImage paletteSwapARGB8(Color[] colorSet, Color clearToColorRequested, BufferedImage argbMappedBufferedImage) { + if (argbMappedBufferedImage == null) { + return null; //S.E.P. + } + final Color BLACK_NO_ALPHA = new Color(0x00000000); + final Color WHITE_NO_ALPHA = new Color(0x00FFFFFF); + final int ALPHA = 3; // this is some static mapping for... + final int RED = 0; // readability in the following... + final int GREEN = 1; // Magic code section of band processing. + final int BLUE = 2; + final int[] orderedBands = {ALPHA, RED, GREEN, BLUE}; + //first we prep a cmap with blank passes and + Color[] cMap = {BLACK_NO_ALPHA, BLACK_NO_ALPHA, BLACK_NO_ALPHA, BLACK_NO_ALPHA}; + boolean clearColorFound = false; + Color clearToColor = BLACK_NO_ALPHA; + if (colorSet != null) { //if we get a null colorSet... it's all mapped to clear. + if (colorSet.length > cMap.length) { // if colorSet is more than 4, we only proces up to 4 + for (int i = 0; i < cMap.length; i++) { + if (colorSet[i] != null) { + if (!clearColorFound) { + clearColorFound = true; + clearToColor = colorSet[i]; + } + cMap[orderedBands[i]] = colorSet[i]; // and finally, if any of the Colors are null... invisible pass... + } + } + } else { + int startOffset = 0; + if (colorSet.length < 4) // if less than standard size, assume RGB model + { + startOffset++; // and "blank" the alpha color pass. + } + for (int i = 0; i < colorSet.length; i++) { + if (colorSet[i] != null) { + if (!clearColorFound) { + clearColorFound = true; + clearToColor = colorSet[i]; + } + cMap[orderedBands[i + startOffset]] = colorSet[i]; + } + } + } + } + + // finally adjust the clearToColor if one was requested + if (clearToColorRequested != null) { + clearToColor = clearToColorRequested; + } + //Next we'll switch to Rasters to easily handle floating point precision + // operations upon the individual channels. + + WritableRaster outRaster, inRaster; + int w = argbMappedBufferedImage.getWidth(); + int h = argbMappedBufferedImage.getHeight(); + BandedSampleModel inSM = new BandedSampleModel(DataBuffer.TYPE_FLOAT, w, h, 4); + DataBufferFloat inDBF = new DataBufferFloat((w * h), 4);//4 banks, and total size + inRaster = Raster.createWritableRaster(inSM, inDBF, null); // that null just means point 0, 0 (top/left) + outRaster = inRaster.createCompatibleWritableRaster(w, h); + float[] cMaptoFlArray, outColortoFlArray, clearColortoFlArray; + float inBandAsAlpha; + Color paletteColor; + // now we convert from W/E the argbMappedBufferedImage's format to + // our normalized [0f..1f] RGBA raster + outColortoFlArray = new float[]{0f, 0f, 0f, 0f}; // or new float[4]... w/e + clearColortoFlArray = clearToColor.getRGBComponents(new float[4]); + clearColortoFlArray[ALPHA] = 0f; + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + int packedPixel = argbMappedBufferedImage.getRGB(x, y); + int testing; + float ftesting; + //outColortoFlArray[ALPHA] = (((packedPixel >> 24) & 0xFF) / 255); + testing = packedPixel; + testing = testing >> 24; + testing = testing & 0xFF; + ftesting = testing; + ftesting = ftesting / 255; + outColortoFlArray[ALPHA] = ftesting; + + //outColortoFlArray[RED] = (((packedPixel >> 16) & 0xFF) / 255); + testing = packedPixel; + testing = testing >> 16; + testing = testing & 0xFF; + ftesting = testing; + ftesting = ftesting / 255; + outColortoFlArray[RED] = ftesting; + + //outColortoFlArray[GREEN] = (((packedPixel >> 8) & 0xFF) / 255); + testing = packedPixel; + testing = testing >> 8; + testing = testing & 0xFF; + ftesting = testing; + ftesting = ftesting / 255; + outColortoFlArray[GREEN] = ftesting; + + //outColortoFlArray[BLUE] = ( (packedPixel & 0xFF) / 255); + testing = packedPixel; + testing = testing & 0xFF; + ftesting = testing; + ftesting = ftesting / 255; + outColortoFlArray[BLUE] = ftesting; + + inRaster.setPixel(x, y, outColortoFlArray); + outRaster.setPixel(x, y, clearColortoFlArray); + } + } + // next, we process all bands in order - a "band" being one channel of A,R,G,B. + // as each band is processed the outRaster keeps getting "resampled" to apply + // the next band properly. all values are considered normalized [0f..1f] + for (int band : orderedBands) { + paletteColor = cMap[band]; + cMaptoFlArray = paletteColor.getRGBComponents(new float[4]);// this nullifies translucency + if (paletteColor != BLACK_NO_ALPHA) { + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + //inBandAsAlpha = inRaster.getSample(x, y, band); + inBandAsAlpha = inRaster.getSampleFloat(x, y, band); + outColortoFlArray = outRaster.getPixel(x, y, new float[4]); + outColortoFlArray[RED] = (outColortoFlArray[RED] + * (1f - (inBandAsAlpha * cMaptoFlArray[ALPHA]))) + + (cMaptoFlArray[RED] * (inBandAsAlpha * cMaptoFlArray[ALPHA])); + outColortoFlArray[GREEN] = (outColortoFlArray[GREEN] + * (1f - (inBandAsAlpha * cMaptoFlArray[ALPHA]))) + + (cMaptoFlArray[GREEN] * (inBandAsAlpha * cMaptoFlArray[ALPHA])); + outColortoFlArray[BLUE] = (outColortoFlArray[BLUE] + * (1f - (inBandAsAlpha * cMaptoFlArray[ALPHA]))) + + (cMaptoFlArray[BLUE] * (inBandAsAlpha * cMaptoFlArray[ALPHA])); + + outColortoFlArray[ALPHA] = (outColortoFlArray[ALPHA] + * (1f - (inBandAsAlpha * cMaptoFlArray[ALPHA]))) + + (cMaptoFlArray[ALPHA] * (inBandAsAlpha * cMaptoFlArray[ALPHA])); + + outRaster.setPixel(x, y, outColortoFlArray); + } + } + } + } + + //then we convert n' ship + BufferedImage returnBI = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + outColortoFlArray = outRaster.getPixel(x, y, new float[4]); + int packedColor = ((int) (outColortoFlArray[ALPHA] * 255f) << 24) + | ((int) (outColortoFlArray[RED] * 255f) << 16) + | ((int) (outColortoFlArray[GREEN] * 255f) << 8) + | ((int) (outColortoFlArray[BLUE] * 255f)); + returnBI.setRGB(x, y, packedColor); + } + } + + return returnBI; + } + + public static BufferedImage paletteSwapARGB8(Color[] colorSet, BufferedImage argbMappedBufferedImage) { + + return paletteSwapARGB8(colorSet, null, argbMappedBufferedImage); + } + +} diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/DarkMonkey.theme b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/DarkMonkey.theme new file mode 100644 index 000000000..c16f368da --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/DarkMonkey.theme @@ -0,0 +1,11 @@ +nimrodlf.p1=#77411D +nimrodlf.p2=#9E5F28 +nimrodlf.p3=#948519 +nimrodlf.s1=#303030 +nimrodlf.s2=#3A3A3A +nimrodlf.s3=#515151 +nimrodlf.w=#262626 +nimrodlf.b=#E8EAE0 +nimrodlf.menuOpacity=219 +nimrodlf.frameOpacity=180 +nimrodlf.font=DejaVu Sans Condensed-BOLD-12 diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/DarkMonkeyIconFactory.java b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/DarkMonkeyIconFactory.java new file mode 100644 index 000000000..4c640851b --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/DarkMonkeyIconFactory.java @@ -0,0 +1,153 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.jme3.netbeans.plaf.darkmonkey; + +import com.nilo.plaf.nimrod.NimRODIconFactory; +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.image.BandedSampleModel; +import java.awt.image.BufferedImage; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferFloat; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; +import java.io.Serializable; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.plaf.UIResource; + +/** + * This class provides for overrides on the system Icons from the + * NimROD look and feel + * @author charles + */ +public class DarkMonkeyIconFactory extends NimRODIconFactory{ + private static Icon treeCollapsedIcon; + private static Icon treeExpandedIcon; + + public static Icon getTreeCollapsedIcon(){ + if(treeCollapsedIcon == null){ + treeCollapsedIcon = new TreeCollapsedIcon(); + } + + return treeCollapsedIcon; + } + public static Icon getTreeExpandedIcon(){ + if(treeExpandedIcon == null){ + treeExpandedIcon = new TreeExpandedIcon(); + } + + return treeExpandedIcon; + } + + + private static class TreeCollapsedIcon implements Icon, UIResource, Serializable{ + private int w, h; + ImageIcon preProcessed; + { + w = 18; + h = 18; + preProcessed = null; + } + + public TreeCollapsedIcon(){ //maybe THIS is all I need, eh? + w = 18; + h = 18; + preProcessed = null; + } + + @Override + public void paintIcon(Component c, Graphics g, int x, int y) { + if(preProcessed != null){ + preProcessed.paintIcon(c, g, x, y); + return; + } + + //process for first time, unless this gets "uninitialized" by + // UIResource calls; + BufferedImage bi = DMUtils.loadImagefromJar(this, "icons/nehonC2.png"); + // start the experiments! + + Color[] normColorSet = {null, DarkMonkeyLookAndFeel.getWhite(), + null, DarkMonkeyLookAndFeel.getPrimaryControl()}; + bi = DMUtils.paletteSwapARGB8(normColorSet, bi); + // end experiment, back to old code + ImageIcon ii = new ImageIcon(bi); + Image scaled = ii.getImage(); + ImageIcon preProcess = new ImageIcon(scaled.getScaledInstance(w, h, Image.SCALE_SMOOTH)); + preProcess.paintIcon(c, g, x, y); + preProcessed = preProcess; + } + + @Override + public int getIconWidth() { + return w; + } + + @Override + public int getIconHeight() { + return h; + } + + } + + private static class TreeExpandedIcon implements Icon, UIResource, Serializable{ + private int w, h; + ImageIcon preProcessed; + { + w = 18; + h = 18; + preProcessed = null; + } + + + public TreeExpandedIcon(){ //maybe THIS is all I need, eh? + w = 18; + h = 18; + preProcessed = null; + } + + @Override + public void paintIcon(Component c, Graphics g, int x, int y) { + if(preProcessed != null){ + preProcessed.paintIcon(c, g, x, y); + return; + } + + //process for first time, unless this gets "uninitialized" by + // UIResource calls; + + BufferedImage bi = DMUtils.loadImagefromJar(this, "icons/nehonE2.png"); + Color[] normColorSet = { DarkMonkeyLookAndFeel.getWhite(), + null, DarkMonkeyLookAndFeel.getPrimaryControl()}; + bi = DMUtils.paletteSwapARGB8(normColorSet, bi); + + ImageIcon ii = new ImageIcon(bi); + Image scaled = ii.getImage(); + + ImageIcon preProcess = new ImageIcon(scaled.getScaledInstance(w, h, Image.SCALE_DEFAULT)); + + preProcess.paintIcon(c, g, x, y); + preProcessed = preProcess; + } + + @Override + public int getIconWidth() { + return w; + } + + @Override + public int getIconHeight() { + return h; + } + + } + + + +} diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/DarkMonkeyLookAndFeel.java b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/DarkMonkeyLookAndFeel.java new file mode 100644 index 000000000..a923a911e --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/DarkMonkeyLookAndFeel.java @@ -0,0 +1,111 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.jme3.netbeans.plaf.darkmonkey; + +import com.nilo.plaf.nimrod.NimRODTheme; +import java.awt.Color; +import java.awt.Font; +import java.util.Enumeration; +import javax.swing.ImageIcon; +import javax.swing.UIDefaults; + +/** + * The DarkMonkey look and feel class Extends the Nimrod LAF, which in turn, + * extends Metal. The version of Nimrod used is 1.2b obtained from:
    + * + * http://nilogonzalez.es/nimrodlf/download-en.html + *

    A copy of the jar and source used for this project is in the ext/ folder. + *

    + * + * @author Charles Anderson + */ +public class DarkMonkeyLookAndFeel extends com.nilo.plaf.nimrod.NimRODLookAndFeel{ + + public static final String dmLAFDefault = "DarkMonkey.theme"; + protected static NimRODTheme nrTheme = new NimRODTheme(); + + public DarkMonkeyLookAndFeel(){ + super(); + // Todo: replace following code with proper loading + // From DarkMonkey.theme + NimRODTheme nt = new NimRODTheme(); + + nt.setBlack(Color.decode("#E8EAE0")); + nt.setWhite(Color.decode("#262626")); + nt.setPrimary1(Color.decode("#77411D")); + nt.setPrimary2(Color.decode("#9E5F28")); + nt.setPrimary3(Color.decode("#948519")); + nt.setSecondary1(Color.decode("#303030")); + nt.setSecondary2(Color.decode("#3A3A3A")); + nt.setSecondary3(Color.decode("#515151")); + nt.setFrameOpacity(180); + nt.setMenuOpacity(219); + nt.setFont(Font.decode("DejaVu Sans Condensed-PLAIN-12")); + + setCurrentTheme(nt); + + } + + /** + * This method override, getID() returns the String "DarkMonkey" for + * registering this Look And Feel with the UImanager. + * @return String "DarkMonkey" + */ + @Override + public String getID() { + return "DarkMonkey"; + } + + /** + * This method override, getName() returns the String "DarkMonkey" for + * its Look and Feel Name. I don't know that this is important, but is + * overridden anyway, for completion. + * @return String "DarkMonkey" + */ + @Override + public String getName() { + return "DarkMonkey"; + } + + /** + * This method override, getDescription() returns the String + * "Look and Feel DarkMonkey - 2015, based on NimROD 2007" for + * instances of future programming that might use it as a tool tip or + * small descriptor in their Look and Feel modules. + * @return String "Look and Feel DarkMonkey - 2015, based on NimROD 2007" + */ + @Override + public String getDescription() { + return "Look and Feel DarkMonkey - 2015, based on NimROD 2007"; + } + + + @Override + protected void initClassDefaults( UIDefaults table) { + super.initClassDefaults( table); + /* + for( Enumeration en = table.keys(); en.hasMoreElements(); ) { + System.out.println( "[" + en.nextElement() + "]"); + } + */ + } + + @Override + protected void initComponentDefaults( UIDefaults table) { + super.initComponentDefaults( table); + + table.put("Tree.collapsedIcon", DarkMonkeyIconFactory.getTreeCollapsedIcon()); + table.put("Tree.expandedIcon", DarkMonkeyIconFactory.getTreeExpandedIcon()); + // + /* + for( Enumeration en = table.keys(); en.hasMoreElements(); ) { + System.out.println( "[" + en.nextElement() + "]"); + } + */ + + } + +} diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/DarkMonkeyValidator.java b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/DarkMonkeyValidator.java new file mode 100644 index 000000000..cc5ef7c70 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/DarkMonkeyValidator.java @@ -0,0 +1,29 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.jme3.netbeans.plaf.darkmonkey; + +import java.awt.EventQueue; +import javax.swing.JOptionPane; +import javax.swing.UIManager; +import org.openide.modules.OnStart; +import org.openide.windows.OnShowing; + +/** + * This is something that would be used once the nbm format is no longer + * needed and is absorbed by SDK downloadable. + * @author charles + */ +@OnStart +public class DarkMonkeyValidator implements Runnable{ + + @Override + public void run() { + + //assert EventQueue.isDispatchThread(); // this is for @OnShowing + //JOptionPane.showMessageDialog(null,"Hello from the Validator"); + } + +} diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/Installer.java b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/Installer.java new file mode 100644 index 000000000..8ceda6a48 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/Installer.java @@ -0,0 +1,40 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.jme3.netbeans.plaf.darkmonkey; + +import java.awt.Font; +import java.awt.GraphicsEnvironment; +import java.io.File; +import javax.swing.UIManager; +import org.openide.modules.ModuleInstall; + +public class Installer extends ModuleInstall { + + @Override + public void restored() { + UIManager.installLookAndFeel(new UIManager.LookAndFeelInfo( + new DarkMonkeyLookAndFeel().getName(), + DarkMonkeyLookAndFeel.class.getName())); + // TODO + + String[] fontsToLoad = { + "fonts/DejaVuSans.ttf", + "fonts/DejaVuSans-Bold.ttf", + "fonts/DejaVuSans-Oblique.ttf", + "fonts/DejaVuSans-BoldOblique.ttf", + "fonts/DejaVuSansCondensed.ttf", + "fonts/DejaVuSansCondensed-Bold.ttf", + "fonts/DejaVuSansCondensed-Oblique.ttf", + "fonts/DejaVuSansCondensed-BoldOblique.ttf", + "fonts/DejaVuSansMono.ttf", + "fonts/DejaVuSansMono-Bold.ttf", + "fonts/DejaVuSansMono-Oblique.ttf", + "fonts/DejaVuSansMono-BoldOblique.ttf" + }; + DMUtils.loadFontsFromJar(this, fontsToLoad); + } + +} diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/JunkSnippet.txt b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/JunkSnippet.txt new file mode 100644 index 000000000..7bbdbc2a7 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/JunkSnippet.txt @@ -0,0 +1,144 @@ + public static void loadFontsFromJar(Object refObj, String relPath) { + //first, we grab ahold of what all fonts are in the JRE's system + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + String[] fontFamilies = ge.getAvailableFontFamilyNames(); + //Next we get a listing of all of the fonts in the refObj's jar at relPath + ZipFile zipFile = new ZipFile("C:/test.zip"); + InputStream stream; + Enumeration entries = zipFile.entries(); + try { + bi = ImageIO.read(refObj.getClass().getResourceAsStream(fileName)); + } catch (IOException e) { + // File is probably referenced wrong or "mispleled"... lol. + e.printStackTrace(); + } + + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + stream = zipFile.getInputStream(entry); + stream.close(); + } + + ge.registerFont(Font.createFont(Font.TRUETYPE_FONT, new File("A.ttf"))); + + } + + /** + * Note from Charles: DO NOT USE - Retain it though :) this method correctly + * does get the path... of Netbeans.. lol... ... Todo: adjust this to work + * with concepts from the LoadImagefromJar... ... and we can make it work + * for custom defined themes dynamically in conjunction with the + * functionality available from Nilo's NimROD base. END NOTE... + * + * @param relativePath + * @return + * @throws NoSuchFileException + */ + public static String relpath(String relativePath) { + //TODO fix the following statement and we can start having dynamic LaF adjustment - Charles + final File f = new File(DMUtils.class.getProtectionDomain().getCodeSource().getLocation().getPath()); + //END TODO - Charles + String returnString; + int i; + returnString = f.getPath(); + i = returnString.indexOf("org-jme3-netbeans"); // This would have to be adjusted as well - Charles + returnString = returnString.substring(0, i); + returnString = returnString.replace(File.separatorChar, '/') + relativePath; + File check = new File(returnString); + + return returnString; + + } + +This next bit is from the AnnotationType overrides in the layer.xml..... + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/README.txt b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/README.txt new file mode 100644 index 000000000..109c25481 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/README.txt @@ -0,0 +1,42 @@ +- Note from Charles - +Ok, I think I have everything covered for community involvement: +If you contribute make sure to toss your name into the AUTHORS.txt file +for the proper directory. Make sure to toss in commenting and supply JavaDoc +for Methods / Classes. Otherwise, have fun with it! + +Structure: +-layer.xml contains the FAC side of this project. +-DarkMonkeyLookAndFeel contains the LAF side of this project. +-Installer is responsible for making sure LAF side and unregistered fonts are + available for each instance of netbeans. +-DMUtils contains resource/file methods for base IO or resource transformations +-DarkMonkeyValidator is a placeholder launchpoint snippet for conversion from + nbm format to a form that would integrate with an SDK downloadable build + (it is unnecessary as-is. Would replace Installer, functionally) +-DarkMonkey.theme is the desired way to use nimrodlf (unimplemented at current time) +-DarkMonkeyIconFactory produces images/icons for the small/fixed size level + -Tree.expandedIcon is overridden + -Tree.collapsedIcon is overridden + - more can be added +-Bundle.properties contains one of the cooler module description pages, ever*. + -* COOLEST. DESCRIPTION. EVER. (I'm cereal! / lol! /omg!) + +Directory Structure: +org.jme3.netbeans.plaf.darkmonkey is considered root for the relative path calls +that you will see in code. *Especially* if DMUtils is involved. + -ext/ or external, currently contains nimrodlf.jar and nimrodlf_src.zip + -fac/ or FontsColors, contains the FontsColors.xml files for layer.xml to + place into netbean's xmlfilesytem. + -fac/AnnotationTypes/ contains the Annotation.xml files for layer.xml to + place into netbean's xmlfilesytem. *Unimplemented* Only if the sidebar + icons for breakpoints and such should be replaced. + -fac/AnnotationTypes/icons *Unimplemented* *Does not exist yet* see above. + -fonts/ *unimplented* contains the physical .ttf fonts used by the LAF and FAC sides. + -icons/ contains image resources for LAF side. + + +Current Todo List: +-fix bug in src for nimrodlf.jar rebuild in ext/ + - Bug has to do with GridBagLayout and other such stuff where preferredSize + is derived. +-add font check/load code for fonts/. see JunkSnippet.txt for some proto work. \ No newline at end of file diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/.nbattrs b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/.nbattrs new file mode 100644 index 000000000..7ecdd8f3d --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/.nbattrs @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/Breakpoint.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/Breakpoint.xml new file mode 100644 index 000000000..ab5cdb3a5 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/Breakpoint.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/Breakpoint_broken.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/Breakpoint_broken.xml new file mode 100644 index 000000000..0c910da14 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/Breakpoint_broken.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/Breakpoint_stroke.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/Breakpoint_stroke.xml new file mode 100644 index 000000000..b7f6e535f --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/Breakpoint_stroke.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CallSite.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CallSite.xml new file mode 100644 index 000000000..97f28c4ed --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CallSite.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/ClassBreakpoint.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/ClassBreakpoint.xml new file mode 100644 index 000000000..9f237ae65 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/ClassBreakpoint.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/ClassBreakpoint_stroke.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/ClassBreakpoint_stroke.xml new file mode 100644 index 000000000..d6d6f8e91 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/ClassBreakpoint_stroke.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CondBreakpoint.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CondBreakpoint.xml new file mode 100644 index 000000000..8642294c0 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CondBreakpoint.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CondBreakpoint_broken.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CondBreakpoint_broken.xml new file mode 100644 index 000000000..19a2e232e --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CondBreakpoint_broken.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CondBreakpoint_stroke.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CondBreakpoint_stroke.xml new file mode 100644 index 000000000..eb206c4d3 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CondBreakpoint_stroke.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentExpression.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentExpression.xml new file mode 100644 index 000000000..fdec15548 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentExpression.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentExpressionLine.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentExpressionLine.xml new file mode 100644 index 000000000..686a5e530 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentExpressionLine.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentExpressionLine_BP.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentExpressionLine_BP.xml new file mode 100644 index 000000000..30d316146 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentExpressionLine_BP.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentExpressionLine_CBP.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentExpressionLine_CBP.xml new file mode 100644 index 000000000..f0595e41a --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentExpressionLine_CBP.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentExpressionLine_DBP.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentExpressionLine_DBP.xml new file mode 100644 index 000000000..8b1342b71 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentExpressionLine_DBP.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentExpressionLine_DCBP.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentExpressionLine_DCBP.xml new file mode 100644 index 000000000..5a11a7c76 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentExpressionLine_DCBP.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentPC.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentPC.xml new file mode 100644 index 000000000..93e5ef58f --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentPC.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentPC2.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentPC2.xml new file mode 100644 index 000000000..ece9b3616 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentPC2.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentPC2LinePart.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentPC2LinePart.xml new file mode 100644 index 000000000..99dd6d4aa --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentPC2LinePart.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentPC2_BP.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentPC2_BP.xml new file mode 100644 index 000000000..b3ed82ba3 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentPC2_BP.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentPC2_DBP.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentPC2_DBP.xml new file mode 100644 index 000000000..30c6f72d6 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentPC2_DBP.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentPCLinePart.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentPCLinePart.xml new file mode 100644 index 000000000..9b8feebab --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/CurrentPCLinePart.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledBreakpoint.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledBreakpoint.xml new file mode 100644 index 000000000..75294be39 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledBreakpoint.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledBreakpoint_stroke.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledBreakpoint_stroke.xml new file mode 100644 index 000000000..9ba03221a --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledBreakpoint_stroke.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledClassBreakpoint.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledClassBreakpoint.xml new file mode 100644 index 000000000..8d71638fa --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledClassBreakpoint.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledClassBreakpoint_stroke.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledClassBreakpoint_stroke.xml new file mode 100644 index 000000000..d858e4c28 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledClassBreakpoint_stroke.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledCondBreakpoint.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledCondBreakpoint.xml new file mode 100644 index 000000000..ce7ae7b9a --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledCondBreakpoint.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledCondBreakpoint_stroke.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledCondBreakpoint_stroke.xml new file mode 100644 index 000000000..d87175748 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledCondBreakpoint_stroke.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledFieldBreakpoint.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledFieldBreakpoint.xml new file mode 100644 index 000000000..730360695 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledFieldBreakpoint.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledFieldBreakpoint_stroke.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledFieldBreakpoint_stroke.xml new file mode 100644 index 000000000..9df689cdf --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledFieldBreakpoint_stroke.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledMethodBreakpoint.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledMethodBreakpoint.xml new file mode 100644 index 000000000..993af856e --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledMethodBreakpoint.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledMethodBreakpoint_stroke.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledMethodBreakpoint_stroke.xml new file mode 100644 index 000000000..1d6b5f09b --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/DisabledMethodBreakpoint_stroke.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/FieldBreakpoint.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/FieldBreakpoint.xml new file mode 100644 index 000000000..1c816c6c6 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/FieldBreakpoint.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/FieldBreakpoint_stroke.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/FieldBreakpoint_stroke.xml new file mode 100644 index 000000000..a30520f2d --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/FieldBreakpoint_stroke.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/MethodBreakpoint.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/MethodBreakpoint.xml new file mode 100644 index 000000000..6bc43a6e4 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/MethodBreakpoint.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/MethodBreakpoint_stroke.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/MethodBreakpoint_stroke.xml new file mode 100644 index 000000000..f235a9a32 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/MethodBreakpoint_stroke.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThread.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThread.xml new file mode 100644 index 000000000..8b476a25d --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThread.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThread_BP.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThread_BP.xml new file mode 100644 index 000000000..b37c17ca2 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThread_BP.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThread_BP_broken.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThread_BP_broken.xml new file mode 100644 index 000000000..8477ea95e --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThread_BP_broken.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThread_DBP.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThread_DBP.xml new file mode 100644 index 000000000..b3633a32a --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThread_DBP.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThread_PC.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThread_PC.xml new file mode 100644 index 000000000..b4ecab2ae --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThread_PC.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThread_PC_BP.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThread_PC_BP.xml new file mode 100644 index 000000000..ea4733484 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThread_PC_BP.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThreads.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThreads.xml new file mode 100644 index 000000000..fbc91baee --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThreads.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThreads_BP.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThreads_BP.xml new file mode 100644 index 000000000..939a55a8c --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThreads_BP.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThreads_BP_broken.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThreads_BP_broken.xml new file mode 100644 index 000000000..417d2f742 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThreads_BP_broken.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThreads_DBP.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThreads_DBP.xml new file mode 100644 index 000000000..5fce8a876 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThreads_DBP.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThreads_PC_BP.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThreads_PC_BP.xml new file mode 100644 index 000000000..cedc279dd --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/OtherThreads_PC_BP.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_BP.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_BP.xml new file mode 100644 index 000000000..ce0a84fcf --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_BP.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_BP_broken.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_BP_broken.xml new file mode 100644 index 000000000..bc39dc5f4 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_BP_broken.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_BP_stroke.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_BP_stroke.xml new file mode 100644 index 000000000..97b4a7f80 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_BP_stroke.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_CBP.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_CBP.xml new file mode 100644 index 000000000..2e03f914c --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_CBP.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_CBP_broken.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_CBP_broken.xml new file mode 100644 index 000000000..9578d867a --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_CBP_broken.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_CBP_stroke.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_CBP_stroke.xml new file mode 100644 index 000000000..6141bc1bd --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_CBP_stroke.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_DBP.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_DBP.xml new file mode 100644 index 000000000..76951fef4 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_DBP.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_DBP_stroke.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_DBP_stroke.xml new file mode 100644 index 000000000..8b32f784c --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_DBP_stroke.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_DCBP.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_DCBP.xml new file mode 100644 index 000000000..a768c78e9 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_DCBP.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_DCBP_stroke.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_DCBP_stroke.xml new file mode 100644 index 000000000..1cc067b05 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_DCBP_stroke.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_mixedBP.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_mixedBP.xml new file mode 100644 index 000000000..118f47060 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_mixedBP.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_mixedBP_broken.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_mixedBP_broken.xml new file mode 100644 index 000000000..8d9de2b91 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_mixedBP_broken.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_multi_BPCBP.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_multi_BPCBP.xml new file mode 100644 index 000000000..7554b1a7f --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_multi_BPCBP.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_multi_BPCBP_broken.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_multi_BPCBP_broken.xml new file mode 100644 index 000000000..7e728b15c --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_multi_BPCBP_broken.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_multi_DBPCBP.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_multi_DBPCBP.xml new file mode 100644 index 000000000..92eaded02 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/PC_multi_DBPCBP.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/README.txt b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/README.txt new file mode 100644 index 000000000..8834bd0b0 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/README.txt @@ -0,0 +1,11 @@ +- Note from Charles - +Yeah, these are the full xml definitions for the +annotations types. I've retained them from Nehon's +conf.zip file, but these aren't added to the layer.xml. + +Yet... + +-Only if we want to override the various icons, n stuff. +or +-if these actually override the colors specified in +the annotations fonts/colors. \ No newline at end of file diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/bookmark.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/bookmark.xml new file mode 100644 index 000000000..1f03f9839 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/bookmark.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/implements-has-implementations-combined.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/implements-has-implementations-combined.xml new file mode 100644 index 000000000..83e049c8f --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/implements-has-implementations-combined.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/implements-is-overridden-combined.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/implements-is-overridden-combined.xml new file mode 100644 index 000000000..0c254dd51 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/implements-is-overridden-combined.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/mixed_BP.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/mixed_BP.xml new file mode 100644 index 000000000..45914e713 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/mixed_BP.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/mixed_BP_broken.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/mixed_BP_broken.xml new file mode 100644 index 000000000..d99e90ee8 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/mixed_BP_broken.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/multi_BPCBP.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/multi_BPCBP.xml new file mode 100644 index 000000000..1c284b712 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/multi_BPCBP.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/multi_BPCBP_broken.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/multi_BPCBP_broken.xml new file mode 100644 index 000000000..b759921be --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/multi_BPCBP_broken.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/multi_DBPCBP.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/multi_DBPCBP.xml new file mode 100644 index 000000000..2e3beb577 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/multi_DBPCBP.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-modules-editor-annotations-has_implementations.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-modules-editor-annotations-has_implementations.xml new file mode 100644 index 000000000..468c18fc3 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-modules-editor-annotations-has_implementations.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-modules-editor-annotations-implements.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-modules-editor-annotations-implements.xml new file mode 100644 index 000000000..7fcb1b188 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-modules-editor-annotations-implements.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-modules-editor-annotations-is_overridden.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-modules-editor-annotations-is_overridden.xml new file mode 100644 index 000000000..655bcfb13 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-modules-editor-annotations-is_overridden.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-modules-editor-annotations-overrides.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-modules-editor-annotations-overrides.xml new file mode 100644 index 000000000..d028fde30 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-modules-editor-annotations-overrides.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-modules-git-Annotation.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-modules-git-Annotation.xml new file mode 100644 index 000000000..0e34aca67 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-modules-git-Annotation.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-modules-subversion-Annotation.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-modules-subversion-Annotation.xml new file mode 100644 index 000000000..5d71f4dc5 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-modules-subversion-Annotation.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-modules-versioning-annotate-Annotation.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-modules-versioning-annotate-Annotation.xml new file mode 100644 index 000000000..e76379ae7 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-modules-versioning-annotate-Annotation.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-modules-xml-error.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-modules-xml-error.xml new file mode 100644 index 000000000..3021fd1d3 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-modules-xml-error.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_err.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_err.xml new file mode 100644 index 000000000..55ac88c48 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_err.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_err_fixable.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_err_fixable.xml new file mode 100644 index 000000000..862814346 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_err_fixable.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_hint.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_hint.xml new file mode 100644 index 000000000..0220cfd4b --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_hint.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_hint_fixable.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_hint_fixable.xml new file mode 100644 index 000000000..c76fec170 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_hint_fixable.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_todo.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_todo.xml new file mode 100644 index 000000000..b37f74d96 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_todo.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_todo_fixable.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_todo_fixable.xml new file mode 100644 index 000000000..58ba23cd7 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_todo_fixable.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_verifier.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_verifier.xml new file mode 100644 index 000000000..4a8f56103 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_verifier.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_verifier_fixable.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_verifier_fixable.xml new file mode 100644 index 000000000..8601c8da9 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_verifier_fixable.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_warn.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_warn.xml new file mode 100644 index 000000000..16719bbd2 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_warn.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_warn_fixable.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_warn_fixable.xml new file mode 100644 index 000000000..3ff4011bc --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/org-netbeans-spi-java-parser_annotation_warn_fixable.xml @@ -0,0 +1,3 @@ + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/override-is-overridden-combined.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/override-is-overridden-combined.xml new file mode 100644 index 000000000..9d50207d5 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/AnnotationTypes/override-is-overridden-combined.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-Editor-annotation.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-Editor-annotation.xml new file mode 100644 index 000000000..5024f9e69 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-Editor-annotation.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-Editor-highlight.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-Editor-highlight.xml new file mode 100644 index 000000000..5800fe464 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-Editor-highlight.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-Editor-token.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-Editor-token.xml new file mode 100644 index 000000000..01a7f0cac --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-Editor-token.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-application-xml-dtd-token.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-application-xml-dtd-token.xml new file mode 100644 index 000000000..1b8368e1a --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-application-xml-dtd-token.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-css-token.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-css-token.xml new file mode 100644 index 000000000..651489eb2 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-css-token.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-html-token.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-html-token.xml new file mode 100644 index 000000000..e1b09178a --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-html-token.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-javascript-token.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-javascript-token.xml new file mode 100644 index 000000000..f318f02cd --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-javascript-token.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-plain-token.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-plain-token.xml new file mode 100644 index 000000000..2151022de --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-plain-token.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-x-diff-token.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-x-diff-token.xml new file mode 100644 index 000000000..3078cef90 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-x-diff-token.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-x-glsl-token.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-x-glsl-token.xml new file mode 100644 index 000000000..2b69657b7 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-x-glsl-token.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-x-groovy-token.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-x-groovy-token.xml new file mode 100644 index 000000000..f90545ccb --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-x-groovy-token.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-x-gsp-token.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-x-gsp-token.xml new file mode 100644 index 000000000..d0866faab --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-x-gsp-token.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-x-java-token.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-x-java-token.xml new file mode 100644 index 000000000..3ee9d08c9 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-x-java-token.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-x-json-token.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-x-json-token.xml new file mode 100644 index 000000000..a37fd1237 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-x-json-token.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-x-properties-token.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-x-properties-token.xml new file mode 100644 index 000000000..20704ac25 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-x-properties-token.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-x-yaml-token.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-x-yaml-token.xml new file mode 100644 index 000000000..7064a1f0e --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-x-yaml-token.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-xhtml-token.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-xhtml-token.xml new file mode 100644 index 000000000..55db420cc --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-xhtml-token.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-xml-external-parsed-entity-token.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-xml-external-parsed-entity-token.xml new file mode 100644 index 000000000..5d81a5eaa --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-xml-external-parsed-entity-token.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-xml-token.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-xml-token.xml new file mode 100644 index 000000000..5d81a5eaa --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/DarkMonkeyFAC-text-xml-token.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/EditorFontsColors-1_1dtd.txt b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/EditorFontsColors-1_1dtd.txt new file mode 100644 index 000000000..f456f9eff --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/EditorFontsColors-1_1dtd.txt @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/README.txt b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/README.txt new file mode 100644 index 000000000..6601e78fa --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fac/README.txt @@ -0,0 +1,36 @@ +- Note From Charles - +This "Directory" org.jme3.netbeans.plaf.darkmonkay.fac is similarly structured +to the way netbeans handles its Fonts and Colors internally. + +It is not really how Netbeans stores it. I have removed "/FontsColors/ThemeName" +from all directories... and the fac can be considered rooted at /Editor + +For the actual registration of all these colors... see the layer.xml +file at org.jme3.netbeans.plaf.darkmonkey + +That said: +-changing the values in the .xml files *will* affect the color values of the +"Dark Monkey" FAC default profile. + +and remember, the Fonts and Colors profile "Dark Monkey" side +of this module is only for the Editor module of Netbeans. Don't confuse this +with the Look and Feel "DarkMonkey" side. :) + +Together, they make the theme for DarkMonkey in Netbeans. + +Onwards! +Tips for learners: +- The syntax for these FAC .xml files is in EditorFontsColor-1_1dtd.txt + I've included the dtd as a txt so folks have a handy reference for knowing + what all options they have for including into the tags. +- Notice that the file names kind of look like the file folder structure of + one of those exported profile .zip files. Roll with that naming convention + if you notice the pattern. The last word is the same as the attr assigned + to the file in the layer.xml file... or the .nbattr file... +- It's all layered like css, so the more specific you get... the more values + that have to be overwritten when the user customizes. +- If in doubt, you can always refer to the Netbeans/Default code to see what + all "names" need to be covered for completion. (You can look at the + from layer.xml and see how the various FAC .xml files + work their way through to support the system.) +- There is a video on the DarkMonkey Dev Blog over at the jMonkeyEngine Forums \ No newline at end of file diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/AUTHORS b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/AUTHORS new file mode 100644 index 000000000..94df1e390 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/AUTHORS @@ -0,0 +1,54 @@ +abysta at yandex.ru +Adrian Schroeter +Aleksey Chalabyan +Andrey Valentinovich Panov +Ben Laenen +Besarion Gugushvili +Bhikkhu Pesala +Clayborne Arevalo +Dafydd Harries +Danilo Segan +Davide Viti +David Jez +David Lawrence Ramsey +Denis Jacquerye +Dwayne Bailey +Eugeniy Meshcheryakov +Gee Fung Sit +Heikki Lindroos +James Cloos +James Crippen +John Karp +Keenan Pepper +Lars Naesbye Christensen +Lior Halphon +MaEr +Mashrab Kuvatov +Max Berger +Mederic Boquien +Michael Everson +MihailJP +Misu Moldovan +Nguyen Thai Ngoc Duy +Nicolas Mailhot +Norayr Chilingarian +Ognyan Kulev +Ondrej Koala Vacha +Peter Cernak +Remy Oudompheng +Roozbeh Pournader +Rouben Hakobian +Sahak Petrosyan +Sander Vesik +Stepan Roh +Stephen Hartke +Steve Tinney +Tavmjong Bah +Thomas Henlich +Tim May +Valentin Stoykov +Vasek Stodulka +Wesley Transue +Yoshiki Ohshima + +$Id: AUTHORS 2495 2011-11-14 22:56:26Z noct_dreamer $ diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSans-Bold.ttf b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSans-Bold.ttf new file mode 100644 index 000000000..08695f23a Binary files /dev/null and b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSans-Bold.ttf differ diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSans-BoldOblique.ttf b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSans-BoldOblique.ttf new file mode 100644 index 000000000..7e3bcc105 Binary files /dev/null and b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSans-BoldOblique.ttf differ diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSans-Oblique.ttf b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSans-Oblique.ttf new file mode 100644 index 000000000..e33ab144d Binary files /dev/null and b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSans-Oblique.ttf differ diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSans.ttf b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSans.ttf new file mode 100644 index 000000000..9d40c3256 Binary files /dev/null and b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSans.ttf differ diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSansCondensed-Bold.ttf b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSansCondensed-Bold.ttf new file mode 100644 index 000000000..4c40003d4 Binary files /dev/null and b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSansCondensed-Bold.ttf differ diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSansCondensed-BoldOblique.ttf b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSansCondensed-BoldOblique.ttf new file mode 100644 index 000000000..24b611b18 Binary files /dev/null and b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSansCondensed-BoldOblique.ttf differ diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSansCondensed-Oblique.ttf b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSansCondensed-Oblique.ttf new file mode 100644 index 000000000..1e0526f9a Binary files /dev/null and b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSansCondensed-Oblique.ttf differ diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSansCondensed.ttf b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSansCondensed.ttf new file mode 100644 index 000000000..7f168d13c Binary files /dev/null and b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSansCondensed.ttf differ diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSansMono-Bold.ttf b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSansMono-Bold.ttf new file mode 100644 index 000000000..9c716794f Binary files /dev/null and b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSansMono-Bold.ttf differ diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSansMono-BoldOblique.ttf b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSansMono-BoldOblique.ttf new file mode 100644 index 000000000..d6536a5cc Binary files /dev/null and b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSansMono-BoldOblique.ttf differ diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSansMono-Oblique.ttf b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSansMono-Oblique.ttf new file mode 100644 index 000000000..e1af34130 Binary files /dev/null and b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSansMono-Oblique.ttf differ diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSansMono.ttf b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSansMono.ttf new file mode 100644 index 000000000..8b7bb2a4e Binary files /dev/null and b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/DejaVuSansMono.ttf differ diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/LICENSE b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/LICENSE new file mode 100644 index 000000000..254e2cc42 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/LICENSE @@ -0,0 +1,99 @@ +Fonts are (c) Bitstream (see below). DejaVu changes are in public domain. +Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below) + +Bitstream Vera Fonts Copyright +------------------------------ + +Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is +a trademark of Bitstream, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of the fonts accompanying this license ("Fonts") and associated +documentation files (the "Font Software"), to reproduce and distribute the +Font Software, including without limitation the rights to use, copy, merge, +publish, distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to the +following conditions: + +The above copyright and trademark notices and this permission notice shall +be included in all copies of one or more of the Font Software typefaces. + +The Font Software may be modified, altered, or added to, and in particular +the designs of glyphs or characters in the Fonts may be modified and +additional glyphs or characters may be added to the Fonts, only if the fonts +are renamed to names not containing either the words "Bitstream" or the word +"Vera". + +This License becomes null and void to the extent applicable to Fonts or Font +Software that has been modified and is distributed under the "Bitstream +Vera" names. + +The Font Software may be sold as part of a larger software package but no +copy of one or more of the Font Software typefaces may be sold by itself. + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, +TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME +FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING +ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE +FONT SOFTWARE. + +Except as contained in this notice, the names of Gnome, the Gnome +Foundation, and Bitstream Inc., shall not be used in advertising or +otherwise to promote the sale, use or other dealings in this Font Software +without prior written authorization from the Gnome Foundation or Bitstream +Inc., respectively. For further information, contact: fonts at gnome dot +org. + +Arev Fonts Copyright +------------------------------ + +Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of the fonts accompanying this license ("Fonts") and +associated documentation files (the "Font Software"), to reproduce +and distribute the modifications to the Bitstream Vera Font Software, +including without limitation the rights to use, copy, merge, publish, +distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to +the following conditions: + +The above copyright and trademark notices and this permission notice +shall be included in all copies of one or more of the Font Software +typefaces. + +The Font Software may be modified, altered, or added to, and in +particular the designs of glyphs or characters in the Fonts may be +modified and additional glyphs or characters may be added to the +Fonts, only if the fonts are renamed to names not containing either +the words "Tavmjong Bah" or the word "Arev". + +This License becomes null and void to the extent applicable to Fonts +or Font Software that has been modified and is distributed under the +"Tavmjong Bah Arev" names. + +The Font Software may be sold as part of a larger software package but +no copy of one or more of the Font Software typefaces may be sold by +itself. + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL +TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +Except as contained in this notice, the name of Tavmjong Bah shall not +be used in advertising or otherwise to promote the sale, use or other +dealings in this Font Software without prior written authorization +from Tavmjong Bah. For further information, contact: tavmjong @ free +. fr. + +$Id: LICENSE 2133 2007-11-28 02:46:28Z lechimp $ diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/README b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/README new file mode 100644 index 000000000..12e9e977c --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/fonts/README @@ -0,0 +1,77 @@ +-Note from Charles- +Though we are not extending anything and only using a part of their original +work, I am passing along their readme, authors, and License for proper +accreditation as that we are using: +DejaVu Sans Mono +DejaVu Sans Mono Bold +DejaVu Sans Mono Bold Oblique +DejaVu Sans Mono Oblique +DejaVu Sans +DejaVu Sans Bold +DejaVu Sans Bold Oblique +DejaVu Sans Oblique +from their wonderful font family + +Acquire their full Latest Version at: +http://dejavu-fonts.org +-End Note- + +DejaVu fonts 2.34 (c)2004-2013 DejaVu fonts team +------------------------------------------------ + +The DejaVu fonts are a font family based on the Bitstream Vera Fonts +(http://gnome.org/fonts/). Its purpose is to provide a wider range of +characters (see status.txt for more information) while maintaining the +original look and feel. + +DejaVu fonts are based on Bitstream Vera fonts version 1.10. + +Available fonts (Sans = sans serif, Mono = monospaced): + +DejaVu Sans Mono +DejaVu Sans Mono Bold +DejaVu Sans Mono Bold Oblique +DejaVu Sans Mono Oblique +DejaVu Sans +DejaVu Sans Bold +DejaVu Sans Bold Oblique +DejaVu Sans Oblique +DejaVu Sans ExtraLight (experimental) +DejaVu Serif +DejaVu Serif Bold +DejaVu Serif Bold Italic (experimental) +DejaVu Serif Italic (experimental) +DejaVu Sans Condensed (experimental) +DejaVu Sans Condensed Bold (experimental) +DejaVu Sans Condensed Bold Oblique (experimental) +DejaVu Sans Condensed Oblique (experimental) +DejaVu Serif Condensed (experimental) +DejaVu Serif Condensed Bold (experimental) +DejaVu Serif Condensed Bold Italic (experimental) +DejaVu Serif Condensed Italic (experimental) + +All fonts are also available as derivative called DejaVu LGC with support +only for Latin, Greek and Cyrillic scripts. + +For license information see LICENSE. What's new is described in NEWS. Known +bugs are in BUGS. All authors are mentioned in AUTHORS. + +Fonts are published in source form as SFD files (Spline Font Database from +FontForge - http://fontforge.sf.net/) and in compiled form as TTF files +(TrueType fonts). + +For more information go to http://dejavu.sourceforge.net/. + +Characters from Arev fonts, Copyright (c) 2006 by Tavmjong Bah: +--------------------------- +U+01BA, U+01BF, U+01F7, U+021C-U+021D, U+0220, U+0222-U+0223, +U+02B9, U+02BA, U+02BD, U+02C2-U+02C5, U+02d4-U+02D5, +U+02D7, U+02EC-U+02EE, U+0346-U+034E, U+0360, U+0362, +U+03E2-03EF, U+0460-0463, U+0466-U+0486, U+0488-U+0489, U+04A8-U+04A9, +U+0500-U+050F, U+2055-205E, U+20B0, U+20B2-U+20B3, U+2102, U+210D, U+210F, +U+2111, U+2113, U+2115, U+2118-U+211A, U+211C-U+211D, U+2124, U+2135, +U+213C-U+2140, U+2295-U+2298, U+2308-U+230B, U+26A2-U+26B1, U+2701-U+2704, +U+2706-U+2709, U+270C-U+274B, U+2758-U+275A, U+2761-U+2775, U+2780-U+2794, +U+2798-U+27AF, U+27B1-U+27BE, U+FB05-U+FB06 + +$Id: README 2535 2013-08-25 15:21:17Z moyogo $ diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/icons/nehonC2.png b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/icons/nehonC2.png new file mode 100644 index 000000000..4c96a2bfe Binary files /dev/null and b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/icons/nehonC2.png differ diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/icons/nehonE2.png b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/icons/nehonE2.png new file mode 100644 index 000000000..3160f134c Binary files /dev/null and b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/icons/nehonE2.png differ diff --git a/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/layer.xml b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/layer.xml new file mode 100644 index 000000000..3c84a4094 --- /dev/null +++ b/sdk/jme3-dark-laf/src/org/jme3/netbeans/plaf/darkmonkey/layer.xml @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sdk/jme3-desktop-executables/nbproject/project.properties b/sdk/jme3-desktop-executables/nbproject/project.properties index e0b462857..eec6af9cd 100644 --- a/sdk/jme3-desktop-executables/nbproject/project.properties +++ b/sdk/jme3-desktop-executables/nbproject/project.properties @@ -1,8 +1,8 @@ #Thu, 25 Aug 2011 20:26:49 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial license.file=../license-jme.txt -nbm.homepage=http\://www.jmonkeyengine.com +nbm.homepage=http\://www.jmonkeyengine.org nbm.module.author=Normen Hansen nbm.needs.restart=true spec.version.base=3.1.0 diff --git a/sdk/jme3-documentation/nbproject/project.properties b/sdk/jme3-documentation/nbproject/project.properties index 232d11645..39ff046d1 100644 --- a/sdk/jme3-documentation/nbproject/project.properties +++ b/sdk/jme3-documentation/nbproject/project.properties @@ -1,6 +1,6 @@ javac.source=1.6 javac.compilerargs=-Xlint -Xlint:-serial license.file=../license-jme.txt -nbm.homepage=http://www.jmonkeyengine.com +nbm.homepage=http://www.jmonkeyengine.org nbm.module.author=Normen Hansen, Ruth Kusterer, many others spec.version.base=3.1.0 diff --git a/sdk/jme3-gui/nbproject/project.properties b/sdk/jme3-gui/nbproject/project.properties index 291042fd5..9a27f3767 100644 --- a/sdk/jme3-gui/nbproject/project.properties +++ b/sdk/jme3-gui/nbproject/project.properties @@ -10,10 +10,10 @@ file.reference.slf4j-simple-1.7.7.jar=release/modules/ext/slf4j-simple-1.7.7.jar file.reference.swingtonifty.jar=release/modules/ext/swingtonifty.jar file.reference.xsom-20110101-SNAPSHOT.jar=release/modules/ext/xsom-20110101-SNAPSHOT.jar #Thu, 25 Aug 2011 20:26:49 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint:-serial license.file=../license-jme.txt -nbm.homepage=http://www.jmonkeyengine.com +nbm.homepage=http://www.jmonkeyengine.org nbm.module.author=Relucri nbm.needs.restart=true spec.version.base=3.1.0 diff --git a/sdk/jme3-lwjgl-applet/nbproject/project.properties b/sdk/jme3-lwjgl-applet/nbproject/project.properties index e0b462857..eec6af9cd 100644 --- a/sdk/jme3-lwjgl-applet/nbproject/project.properties +++ b/sdk/jme3-lwjgl-applet/nbproject/project.properties @@ -1,8 +1,8 @@ #Thu, 25 Aug 2011 20:26:49 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial license.file=../license-jme.txt -nbm.homepage=http\://www.jmonkeyengine.com +nbm.homepage=http\://www.jmonkeyengine.org nbm.module.author=Normen Hansen nbm.needs.restart=true spec.version.base=3.1.0 diff --git a/sdk/jme3-materialeditor/nbproject/project.properties b/sdk/jme3-materialeditor/nbproject/project.properties index e0b462857..eec6af9cd 100644 --- a/sdk/jme3-materialeditor/nbproject/project.properties +++ b/sdk/jme3-materialeditor/nbproject/project.properties @@ -1,8 +1,8 @@ #Thu, 25 Aug 2011 20:26:49 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial license.file=../license-jme.txt -nbm.homepage=http\://www.jmonkeyengine.com +nbm.homepage=http\://www.jmonkeyengine.org nbm.module.author=Normen Hansen nbm.needs.restart=true spec.version.base=3.1.0 diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ConnectionCurve.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ConnectionCurve.java index ec2f4aa98..7c225f745 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ConnectionCurve.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ConnectionCurve.java @@ -123,7 +123,7 @@ public class ConnectionCurve extends JPanel implements ComponentListener, MouseI g2.setStroke(new BasicStroke(4)); Path2D.Double path1 = new Path2D.Double(); - if (getDiagram().selectedItem == this) { + if (getDiagram().getSelectedItems().contains(this)) { g.setColor(SELECTED_COLOR); } else { g.setColor(VERY_DARK_GREY); @@ -162,7 +162,7 @@ public class ConnectionCurve extends JPanel implements ComponentListener, MouseI ((Graphics2D) g).draw(path1); g2.setStroke(new BasicStroke(2)); - if (getDiagram().selectedItem == this) { + if (getDiagram().getSelectedItems().contains(this)) { g.setColor(Color.WHITE); } else { g.setColor(LIGHT_GREY); @@ -385,7 +385,7 @@ public class ConnectionCurve extends JPanel implements ComponentListener, MouseI } if (selected) { - getDiagram().select(this); + getDiagram().select(this, e.isShiftDown() || e.isControlDown()); e.consume(); } } @@ -407,9 +407,7 @@ public class ConnectionCurve extends JPanel implements ComponentListener, MouseI if (e.getKeyCode() == KeyEvent.VK_DELETE) { Diagram diag = getDiagram(); - if (diag.selectedItem == this) { - diag.removeSelectedConnection(); - } + diag.removeSelected(); } } diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ConnectionStraight.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ConnectionStraight.java index 3eba66a23..fc4873bd8 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ConnectionStraight.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ConnectionStraight.java @@ -209,7 +209,7 @@ public class ConnectionStraight extends JPanel implements ComponentListener, Mou g.drawLine(p1.x, p1.y, p2.x, p2.y); - if (getDiagram().selectedItem == this) { + if (getDiagram().getSelectedItems().contains(this)) { g.setColor(Color.CYAN); } else { g.setColor(Color.GRAY); @@ -489,7 +489,7 @@ public class ConnectionStraight extends JPanel implements ComponentListener, Mou } if (selected) { - getDiagram().select(this); + getDiagram().select(this, e.isShiftDown() || e.isControlDown()); e.consume(); } } @@ -511,9 +511,7 @@ public class ConnectionStraight extends JPanel implements ComponentListener, Mou if (e.getKeyCode() == KeyEvent.VK_DELETE) { Diagram diag = getDiagram(); - if (diag.selectedItem == this) { - diag.removeSelectedConnection(); - } + diag.removeSelected(); } } diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Diagram.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Diagram.java index 9d344355e..88876f3e5 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Diagram.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Diagram.java @@ -55,7 +55,7 @@ public class Diagram extends JPanel implements MouseListener, MouseMotionListene protected Dot draggedFrom; protected Dot draggedTo; - protected Selectable selectedItem; + protected List selectedItems = new ArrayList(); protected List connections = new ArrayList(); protected List nodes = new ArrayList(); protected List outBuses = new ArrayList(); @@ -63,6 +63,9 @@ public class Diagram extends JPanel implements MouseListener, MouseMotionListene private MatDefEditorlElement parent; private String currentTechniqueName; private final BackdropPanel backDrop = new BackdropPanel(); + private final Cursor defCursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR); + private final Cursor hndCursor = Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR); + private final Point pp = new Point(); @SuppressWarnings("LeakingThisInConstructor") public Diagram() { @@ -99,7 +102,7 @@ public class Diagram extends JPanel implements MouseListener, MouseMotionListene } } - selectedItem = null; + selectedItems.clear(); repaint(); } else if (e.getButton() == MouseEvent.BUTTON2) { setCursor(hndCursor); @@ -204,13 +207,10 @@ public class Diagram extends JPanel implements MouseListener, MouseMotionListene public void mouseExited(MouseEvent e) { } - protected void removeSelectedConnection() { - if (selectedItem instanceof Connection) { - Connection selectedConnection = (Connection) selectedItem; - removeConnection(selectedConnection); - selectedItem = null; - parent.notifyRemoveConnection(selectedConnection); - } + protected void removeSelectedConnection(Selectable selectedItem) { + Connection selectedConnection = (Connection) selectedItem; + removeConnection(selectedConnection); + parent.notifyRemoveConnection(selectedConnection); } private String fixNodeName(String name) { @@ -276,44 +276,58 @@ public class Diagram extends JPanel implements MouseListener, MouseMotionListene np.revalidate(); repaint(); } - - protected void removeSelectedNode() { - if (selectedItem instanceof NodePanel) { - int result = JOptionPane.showConfirmDialog(null, "Delete this node and all its mappings?", "Delete Shader Node", JOptionPane.OK_CANCEL_OPTION); - if (result == JOptionPane.OK_OPTION) { - NodePanel selectedNode = (NodePanel) selectedItem; - nodes.remove(selectedNode); - for (Iterator it = connections.iterator(); it.hasNext();) { - Connection conn = it.next(); - if (conn.start.getNode() == selectedNode || conn.end.getNode() == selectedNode) { - it.remove(); - conn.end.disconnect(); - conn.start.disconnect(); - remove(conn); - } + + protected void removeSelected(){ + + int result = JOptionPane.showConfirmDialog(null, "Delete all selected items, nodes and mappings?", "Delete Selected", JOptionPane.OK_CANCEL_OPTION); + + if (result == JOptionPane.OK_OPTION) { + for (Selectable selectedItem : selectedItems) { + if (selectedItem instanceof NodePanel) { + removeSelectedNode(selectedItem); } + if (selectedItem instanceof Connection) { + removeSelectedConnection(selectedItem); + } + } + selectedItems.clear(); + } + } - selectedNode.cleanup(); - remove(selectedNode); - selectedItem = null; - repaint(); - parent.notifyRemoveNode(selectedNode); + private void removeSelectedNode(Selectable selectedItem) { + + NodePanel selectedNode = (NodePanel) selectedItem; + nodes.remove(selectedNode); + for (Iterator it = connections.iterator(); it.hasNext();) { + Connection conn = it.next(); + if (conn.start.getNode() == selectedNode || conn.end.getNode() == selectedNode) { + it.remove(); + conn.end.disconnect(); + conn.start.disconnect(); + remove(conn); } } + + selectedNode.cleanup(); + remove(selectedNode); + repaint(); + parent.notifyRemoveNode(selectedNode); } - private final Cursor defCursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR); - private final Cursor hndCursor = Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR); - private final Point pp = new Point(); + public List getSelectedItems() { + return selectedItems; + } @Override public void mouseDragged(MouseEvent e) { if (SwingUtilities.isLeftMouseButton(e)) { if (draggedFrom == null) { - if (selectedItem instanceof OutBusPanel) { - OutBusPanel bus = (OutBusPanel) selectedItem; - MouseEvent me = SwingUtilities.convertMouseEvent(this, e, bus); - bus.dispatchEvent(me); + for (Selectable selectedItem : selectedItems) { + if (selectedItem instanceof OutBusPanel) { + OutBusPanel bus = (OutBusPanel) selectedItem; + MouseEvent me = SwingUtilities.convertMouseEvent(this, e, bus); + bus.dispatchEvent(me); + } } } } else if (SwingUtilities.isMiddleMouseButton(e)) { @@ -373,22 +387,53 @@ public class Diagram extends JPanel implements MouseListener, MouseMotionListene * * @param selectable */ - public void select(Selectable selectable) { - parent.selectionChanged(doSelect(selectable)); + public void select(Selectable selectable, boolean multi) { + parent.selectionChanged(doSelect(selectable, multi)); + } + + public void multiMove(DraggablePanel movedPanel ,int xOffset, int yOffset){ + + for (Selectable selectedItem : selectedItems) { + if(selectedItem != movedPanel){ + if(selectedItem instanceof DraggablePanel){ + ((DraggablePanel)selectedItem).movePanel(xOffset, yOffset); + } + } + } } + public void multiStartDrag(DraggablePanel movedPanel){ + for (Selectable selectedItem : selectedItems) { + if(selectedItem != movedPanel){ + if(selectedItem instanceof DraggablePanel){ + ((DraggablePanel)selectedItem).saveLocation(); + } + } + } + } + /** * do select the item and repaint the diagram * * @param selectable * @return */ - private Selectable doSelect(Selectable selectable) { - this.selectedItem = selectable; + private Selectable doSelect(Selectable selectable, boolean multi) { + + + if (!multi && !selectedItems.contains(selectable)) { + selectedItems.clear(); + } + + if (selectable != null) { + selectedItems.add(selectable); + } + if (selectable instanceof Component) { ((Component) selectable).requestFocusInWindow(); } repaint(); + return selectable; } @@ -403,23 +448,23 @@ public class Diagram extends JPanel implements MouseListener, MouseMotionListene for (NodePanel nodePanel : nodes) { if (nodePanel.getKey().equals(key)) { - return doSelect(nodePanel); + return doSelect(nodePanel, false); } } for (Connection connection : connections) { if (connection.getKey().equals(key)) { - return doSelect(connection); + return doSelect(connection, false); } } for (OutBusPanel outBusPanel : outBuses) { if (outBusPanel.getKey().equals(key)) { - return doSelect(outBusPanel); + return doSelect(outBusPanel, false); } } - return doSelect(null); + return null; } @Override diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/DraggablePanel.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/DraggablePanel.java index e81d1d5b6..7941cb8d5 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/DraggablePanel.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/DraggablePanel.java @@ -37,16 +37,22 @@ public class DraggablePanel extends JPanel implements MouseListener, MouseMotion @Override public void mousePressed(MouseEvent e) { if (e.getButton() != MouseEvent.BUTTON2) { - svdx = getLocation().x; + if (!vertical) { svdex = e.getXOnScreen(); } - svdy = getLocation().y; svdey = e.getYOnScreen(); + saveLocation(); + diagram.multiStartDrag(this); e.consume(); } } + protected void saveLocation() { + svdy = getLocation().y; + svdx = getLocation().x; + } + @Override public void mouseReleased(MouseEvent e) { } @@ -71,11 +77,19 @@ public class DraggablePanel extends JPanel implements MouseListener, MouseMotion xoffset = e.getLocationOnScreen().x - svdex; } int yoffset = e.getLocationOnScreen().y - svdey; - setLocation(Math.max(0, svdx + xoffset), Math.max(0, svdy + yoffset)); + movePanel(xoffset, yoffset); + diagram.multiMove(this, xoffset, yoffset); e.consume(); } } + protected void movePanel(int xoffset, int yoffset) { + if (vertical) { + xoffset = 0; + } + setLocation(Math.max(0, svdx + xoffset), Math.max(0, svdy + yoffset)); + } + public Diagram getDiagram() { return diagram; } diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/NodePanel.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/NodePanel.java index 49e04170d..adfd9223d 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/NodePanel.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/NodePanel.java @@ -56,23 +56,6 @@ public class NodePanel extends DraggablePanel implements Selectable, PropertyCha protected List filePaths = new ArrayList(); protected Shader.ShaderType shaderType; -// private List listeners = Collections.synchronizedList(new LinkedList()); -// -// public void addPropertyChangeListener(PropertyChangeListener pcl) { -// listeners.add(pcl); -// } -// -// public void removePropertyChangeListener(PropertyChangeListener pcl) { -// listeners.remove(pcl); -// } -// -// protected void fire(String propertyName, Object old, Object nue) { -// //Passing 0 below on purpose, so you only synchronize for one atomic call: -// PropertyChangeListener[] pcls = (PropertyChangeListener[]) listeners.toArray(new PropertyChangeListener[0]); -// for (int i = 0; i < pcls.length; i++) { -// pcls[i].propertyChange(new PropertyChangeEvent(this, propertyName, old, nue)); -// } -// } public enum NodeType { Vertex(new Color(220, 220, 70)),//yellow @@ -186,9 +169,12 @@ public class NodePanel extends DraggablePanel implements Selectable, PropertyCha } private Dot getConnectPoint(List list, String varName, List listDot) { - if (varName.startsWith("m_") || varName.startsWith("g_")) { - varName = varName.substring(2); - } + //This has been commented out because it was causing issues when a variable name was explicitely starting with m_ or g_ in the j3md. + //I can't remember why it was done in the first place, but I can't see any case where the m_ should be stripped out. + //I'm letting this commented in case this comes to light some day, and something more clever will have to be done. +// if (varName.startsWith("m_") || varName.startsWith("g_")) { +// varName = varName.substring(2); +// } for (int i = 0; i < list.size(); i++) { if (list.get(i).getText().equals(varName)) { return listDot.get(i); @@ -201,13 +187,13 @@ public class NodePanel extends DraggablePanel implements Selectable, PropertyCha protected void paintComponent(Graphics g1) { Graphics2D g = (Graphics2D) g1; Color boderColor = Color.BLACK; - if (diagram.selectedItem == this) { + if (getDiagram().getSelectedItems().contains(this)) { boderColor = Color.WHITE; } g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, // Anti-alias! RenderingHints.VALUE_ANTIALIAS_ON); // Color[] colors = {new Color(0, 0, 0, 0.7f), new Color(0, 0, 0, 0.15f)}; - if (diagram.selectedItem == this) { + if (getDiagram().getSelectedItems().contains(this)) { Color[] colors = new Color[]{new Color(0.6f, 0.6f, 1.0f, 0.8f), new Color(0.6f, 0.6f, 1.0f, 0.5f)}; float[] factors = {0f, 1f}; g.setPaint(new RadialGradientPaint(getWidth() / 2, getHeight() / 2, getWidth() / 2, factors, colors)); @@ -260,8 +246,8 @@ public class NodePanel extends DraggablePanel implements Selectable, PropertyCha @Override public void mousePressed(MouseEvent e) { - super.mousePressed(e); - diagram.select(this); + super.mousePressed(e); + diagram.select(this, e.isShiftDown() || e.isControlDown()); showToolBar(); } @@ -442,9 +428,7 @@ public class NodePanel extends DraggablePanel implements Selectable, PropertyCha public void delete() { Diagram diag = getDiagram(); - if (diag.selectedItem == this) { - diag.removeSelectedNode(); - } + diag.removeSelected(); } public void keyReleased(KeyEvent e) { diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/OutBusPanel.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/OutBusPanel.java index 521776dce..6a489dea6 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/OutBusPanel.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/OutBusPanel.java @@ -110,7 +110,7 @@ public class OutBusPanel extends DraggablePanel implements ComponentListener, Se Polygon p = new Polygon(xs, ys, 8); - if (diagram.selectedItem == this) { + if (getDiagram().getSelectedItems().contains(this)) { int[] xs2 = {0, width - 30, width - 30, width, width - 32, width - 32, 0, 0}; int[] ys2 = {10, 10, 0, getHeight() / 2 + 2, getHeight(), getHeight() - 8, getHeight() - 8, 10}; @@ -154,7 +154,7 @@ public class OutBusPanel extends DraggablePanel implements ComponentListener, Se return; } super.mousePressed(e); - diagram.select(this); + diagram.select(this, e.isShiftDown() || e.isControlDown()); } @Override diff --git a/sdk/jme3-model-importer/nbproject/project.properties b/sdk/jme3-model-importer/nbproject/project.properties index e0b462857..eec6af9cd 100644 --- a/sdk/jme3-model-importer/nbproject/project.properties +++ b/sdk/jme3-model-importer/nbproject/project.properties @@ -1,8 +1,8 @@ #Thu, 25 Aug 2011 20:26:49 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial license.file=../license-jme.txt -nbm.homepage=http\://www.jmonkeyengine.com +nbm.homepage=http\://www.jmonkeyengine.org nbm.module.author=Normen Hansen nbm.needs.restart=true spec.version.base=3.1.0 diff --git a/sdk/jme3-model-importer/src/com/jme3/gde/modelimporter/ImportModel.java b/sdk/jme3-model-importer/src/com/jme3/gde/modelimporter/ImportModel.java index 1f3f57bf8..07b129628 100644 --- a/sdk/jme3-model-importer/src/com/jme3/gde/modelimporter/ImportModel.java +++ b/sdk/jme3-model-importer/src/com/jme3/gde/modelimporter/ImportModel.java @@ -212,6 +212,7 @@ public final class ImportModel implements ActionListener { } replaceLocatedTextures(spat, manager); targetData.saveAsset(); + targetData.closeAsset(); ((SpatialAssetDataObject) targetModel).getLookupContents().remove(tempProjectManager); } } catch (Exception ex) { diff --git a/sdk/jme3-model-importer/src/com/jme3/gde/modelimporter/ModelImporterVisualPanel3.java b/sdk/jme3-model-importer/src/com/jme3/gde/modelimporter/ModelImporterVisualPanel3.java index f7eeb57fa..51c0578e3 100644 --- a/sdk/jme3-model-importer/src/com/jme3/gde/modelimporter/ModelImporterVisualPanel3.java +++ b/sdk/jme3-model-importer/src/com/jme3/gde/modelimporter/ModelImporterVisualPanel3.java @@ -126,6 +126,7 @@ public final class ModelImporterVisualPanel3 extends JPanel { DialogDisplayer.getDefault().notifyLater(msg); Exceptions.printStackTrace(e); } + data.closeAsset(); manager.unregisterLocator(manager.getAssetFolderName(), UberAssetLocator.class); panel.fireChangeEvent(); } diff --git a/sdk/jme3-navmesh-gen/nbproject/project.properties b/sdk/jme3-navmesh-gen/nbproject/project.properties index 65d1fb700..78227c671 100644 --- a/sdk/jme3-navmesh-gen/nbproject/project.properties +++ b/sdk/jme3-navmesh-gen/nbproject/project.properties @@ -1,6 +1,6 @@ javac.source=1.6 javac.compilerargs=-Xlint -Xlint:-serial license.file=../license-jme.txt -nbm.homepage=http://www.jmonkeyengine.com +nbm.homepage=http://www.jmonkeyengine.org nbm.module.author=Brent Owens spec.version.base=3.1.0 diff --git a/sdk/jme3-obfuscate/nbproject/project.properties b/sdk/jme3-obfuscate/nbproject/project.properties index 61598fa7b..d16349a4f 100644 --- a/sdk/jme3-obfuscate/nbproject/project.properties +++ b/sdk/jme3-obfuscate/nbproject/project.properties @@ -1,6 +1,7 @@ #Thu, 25 Aug 2011 20:26:50 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial +license.file=../license-jme.txt nbm.homepage=http\://proguard.sourceforge.net/ nbm.module.author=Normen Hansen nbm.needs.restart=true diff --git a/sdk/jme3-ogretools/nbproject/project.properties b/sdk/jme3-ogretools/nbproject/project.properties index e0b462857..eec6af9cd 100644 --- a/sdk/jme3-ogretools/nbproject/project.properties +++ b/sdk/jme3-ogretools/nbproject/project.properties @@ -1,8 +1,8 @@ #Thu, 25 Aug 2011 20:26:49 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial license.file=../license-jme.txt -nbm.homepage=http\://www.jmonkeyengine.com +nbm.homepage=http\://www.jmonkeyengine.org nbm.module.author=Normen Hansen nbm.needs.restart=true spec.version.base=3.1.0 diff --git a/sdk/jme3-ogrexml/nbproject/project.properties b/sdk/jme3-ogrexml/nbproject/project.properties index 9b996acdd..4ad5ba7ab 100644 --- a/sdk/jme3-ogrexml/nbproject/project.properties +++ b/sdk/jme3-ogrexml/nbproject/project.properties @@ -1,8 +1,8 @@ #Thu, 25 Aug 2011 20:26:48 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial license.file=../license-jme.txt -nbm.homepage=http\://www.jmonkeyengine.com +nbm.homepage=http\://www.jmonkeyengine.org nbm.module.author=Normen Hansen nbm.needs.restart=true spec.version.base=3.1.0 diff --git a/sdk/jme3-project-baselibs/nbproject/project.properties b/sdk/jme3-project-baselibs/nbproject/project.properties index 2e01f5d86..513fb20e4 100644 --- a/sdk/jme3-project-baselibs/nbproject/project.properties +++ b/sdk/jme3-project-baselibs/nbproject/project.properties @@ -1,8 +1,8 @@ #Thu, 25 Aug 2011 20:26:48 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial license.file=../license-jme.txt -nbm.homepage=http\://www.jmonkeyengine.com +nbm.homepage=http\://www.jmonkeyengine.org nbm.module.author=jMonkeyEngine nbm.needs.restart=true spec.version.base=3.1.0 diff --git a/sdk/jme3-project-libraries/nbproject/project.properties b/sdk/jme3-project-libraries/nbproject/project.properties index 2e01f5d86..513fb20e4 100644 --- a/sdk/jme3-project-libraries/nbproject/project.properties +++ b/sdk/jme3-project-libraries/nbproject/project.properties @@ -1,8 +1,8 @@ #Thu, 25 Aug 2011 20:26:48 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial license.file=../license-jme.txt -nbm.homepage=http\://www.jmonkeyengine.com +nbm.homepage=http\://www.jmonkeyengine.org nbm.module.author=jMonkeyEngine nbm.needs.restart=true spec.version.base=3.1.0 diff --git a/sdk/jme3-project-testdata/nbproject/project.properties b/sdk/jme3-project-testdata/nbproject/project.properties index 2e01f5d86..513fb20e4 100644 --- a/sdk/jme3-project-testdata/nbproject/project.properties +++ b/sdk/jme3-project-testdata/nbproject/project.properties @@ -1,8 +1,8 @@ #Thu, 25 Aug 2011 20:26:48 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial license.file=../license-jme.txt -nbm.homepage=http\://www.jmonkeyengine.com +nbm.homepage=http\://www.jmonkeyengine.org nbm.module.author=jMonkeyEngine nbm.needs.restart=true spec.version.base=3.1.0 diff --git a/sdk/jme3-scenecomposer/nbproject/project.properties b/sdk/jme3-scenecomposer/nbproject/project.properties index e0b462857..eec6af9cd 100644 --- a/sdk/jme3-scenecomposer/nbproject/project.properties +++ b/sdk/jme3-scenecomposer/nbproject/project.properties @@ -1,8 +1,8 @@ #Thu, 25 Aug 2011 20:26:49 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial license.file=../license-jme.txt -nbm.homepage=http\://www.jmonkeyengine.com +nbm.homepage=http\://www.jmonkeyengine.org nbm.module.author=Normen Hansen nbm.needs.restart=true spec.version.base=3.1.0 diff --git a/sdk/jme3-templates/nbproject/project.properties b/sdk/jme3-templates/nbproject/project.properties index 2e01f5d86..513fb20e4 100644 --- a/sdk/jme3-templates/nbproject/project.properties +++ b/sdk/jme3-templates/nbproject/project.properties @@ -1,8 +1,8 @@ #Thu, 25 Aug 2011 20:26:48 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial license.file=../license-jme.txt -nbm.homepage=http\://www.jmonkeyengine.com +nbm.homepage=http\://www.jmonkeyengine.org nbm.module.author=jMonkeyEngine nbm.needs.restart=true spec.version.base=3.1.0 diff --git a/sdk/jme3-terrain-editor/nbproject/project.properties b/sdk/jme3-terrain-editor/nbproject/project.properties index a0916a395..0ed16b7c1 100644 --- a/sdk/jme3-terrain-editor/nbproject/project.properties +++ b/sdk/jme3-terrain-editor/nbproject/project.properties @@ -1,7 +1,7 @@ #Thu, 25 Aug 2011 20:26:49 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial license.file=../license-jme.txt -nbm.homepage=http\://www.jmonkeyengine.com +nbm.homepage=http\://www.jmonkeyengine.org nbm.module.author=Brent Owens, Normen Hansen spec.version.base=3.1.0 diff --git a/sdk/jme3-tests-template/nbproject/project.properties b/sdk/jme3-tests-template/nbproject/project.properties index 2e01f5d86..513fb20e4 100644 --- a/sdk/jme3-tests-template/nbproject/project.properties +++ b/sdk/jme3-tests-template/nbproject/project.properties @@ -1,8 +1,8 @@ #Thu, 25 Aug 2011 20:26:48 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial license.file=../license-jme.txt -nbm.homepage=http\://www.jmonkeyengine.com +nbm.homepage=http\://www.jmonkeyengine.org nbm.module.author=jMonkeyEngine nbm.needs.restart=true spec.version.base=3.1.0 diff --git a/sdk/jme3-tests-template/src/com/jme3/gde/templates/tests/testsdesktop/Bundle.properties b/sdk/jme3-tests-template/src/com/jme3/gde/templates/tests/testsdesktop/Bundle.properties index 189077573..c5264da33 100644 --- a/sdk/jme3-tests-template/src/com/jme3/gde/templates/tests/testsdesktop/Bundle.properties +++ b/sdk/jme3-tests-template/src/com/jme3/gde/templates/tests/testsdesktop/Bundle.properties @@ -1,7 +1,7 @@ # To change this license header, choose License Headers in Project Properties. # To change this template file, choose Tools | Templates # and open the template in the editor. - +LBL_CreateProjectStep=Name and Location JmeTestsPanelVisual.projectNameLabel.text=Project &Name: JmeTestsPanelVisual.projectLocationLabel.text=Project &Location: JmeTestsPanelVisual.browseButton.actionCommand=BROWSE diff --git a/sdk/jme3-texture-editor/nbproject/project.properties b/sdk/jme3-texture-editor/nbproject/project.properties index c4186f216..c3e2aa46a 100644 --- a/sdk/jme3-texture-editor/nbproject/project.properties +++ b/sdk/jme3-texture-editor/nbproject/project.properties @@ -1,8 +1,8 @@ #Thu, 25 Aug 2011 20:26:49 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial license.file=../license-jme.txt -nbm.homepage=http\://www.jmonkeyengine.com +nbm.homepage=http\://www.jmonkeyengine.org nbm.module.author=pgi nbm.needs.restart=true spec.version.base=3.1.0 diff --git a/sdk/jme3-vehicle-creator/nbproject/project.properties b/sdk/jme3-vehicle-creator/nbproject/project.properties index 44c34ecb9..0411b6ff9 100644 --- a/sdk/jme3-vehicle-creator/nbproject/project.properties +++ b/sdk/jme3-vehicle-creator/nbproject/project.properties @@ -1,4 +1,4 @@ #Thu, 25 Aug 2011 20:26:50 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial spec.version.base=3.1.0 diff --git a/sdk/jme3-wavefront/nbproject/project.properties b/sdk/jme3-wavefront/nbproject/project.properties index 9d2616783..98f519f77 100644 --- a/sdk/jme3-wavefront/nbproject/project.properties +++ b/sdk/jme3-wavefront/nbproject/project.properties @@ -1,4 +1,4 @@ #Thu, 25 Aug 2011 20:26:49 +0200 -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial spec.version.base=3.1.0 diff --git a/sdk/jme3-welcome-screen/nbproject/project.properties b/sdk/jme3-welcome-screen/nbproject/project.properties index 99dbdf441..ae558b0e0 100644 --- a/sdk/jme3-welcome-screen/nbproject/project.properties +++ b/sdk/jme3-welcome-screen/nbproject/project.properties @@ -1,7 +1,7 @@ -javac.source=1.5 +javac.source=1.6 javac.compilerargs=-Xlint -Xlint\:-serial license.file=../license-jme.txt -nbm.homepage=http\://www.jmonkeyengine.com +nbm.homepage=http\://www.jmonkeyengine.org nbm.module.author=Normen Hansen, jiyarza nbm.needs.restart=true spec.version.base=3.1.0 diff --git a/sdk/jmonkeyplatform.png b/sdk/jmonkeyplatform.png index eee01902f..36675de77 100644 Binary files a/sdk/jmonkeyplatform.png and b/sdk/jmonkeyplatform.png differ diff --git a/sdk/license-jme.txt b/sdk/license-jme.txt index 9f1503915..9c2661e5b 100644 --- a/sdk/license-jme.txt +++ b/sdk/license-jme.txt @@ -1,4 +1,4 @@ -Copyright (c) 2003-2012 jMonkeyEngine +Copyright (c) 2003-2015 jMonkeyEngine All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/sdk/nbi/stub/ext/components/products/blender/nbproject/build-impl.xml b/sdk/nbi/stub/ext/components/products/blender/nbproject/build-impl.xml index 6b25635be..f15304e39 100644 --- a/sdk/nbi/stub/ext/components/products/blender/nbproject/build-impl.xml +++ b/sdk/nbi/stub/ext/components/products/blender/nbproject/build-impl.xml @@ -54,6 +54,7 @@ is divided into following sections: + @@ -71,16 +72,20 @@ is divided into following sections: - + - - + + + - - - + + + + + + @@ -91,12 +96,6 @@ is divided into following sections: - - - - - - @@ -115,24 +114,12 @@ is divided into following sections: - + - + - - - - - - - - - - - - @@ -186,7 +173,15 @@ is divided into following sections: - + + + + + + + + + @@ -275,6 +270,7 @@ is divided into following sections: + @@ -314,6 +310,7 @@ is divided into following sections: + @@ -370,6 +367,11 @@ is divided into following sections: + + + + + @@ -393,7 +395,7 @@ is divided into following sections: - + @@ -407,6 +409,9 @@ is divided into following sections: + + + @@ -438,7 +443,7 @@ is divided into following sections: - + @@ -534,7 +539,7 @@ is divided into following sections: - + @@ -548,6 +553,9 @@ is divided into following sections: + + + @@ -826,8 +834,8 @@ is divided into following sections: - - + + @@ -839,7 +847,7 @@ is divided into following sections: - + @@ -894,6 +902,7 @@ is divided into following sections: + @@ -927,7 +936,7 @@ is divided into following sections: - + @@ -962,41 +971,25 @@ is divided into following sections: - - - - - - - - - - - - - To run this application from the command line without Ant, try: - - - - - - - java -cp "${run.classpath.with.dist.jar}" ${main.class} - - + - + - + - + + + + + + @@ -1004,23 +997,41 @@ is divided into following sections: - + To run this application from the command line without Ant, try: java -jar "${dist.jar.resolved}" - + + + + + + + + + + + + + + + + + - + + - + + - - - - - - - - - - - - - To run this application from the command line without Ant, try: - - - - - - - java -cp "${run.classpath.with.dist.jar}" ${main.class} - - + - + - + - + + + + + + @@ -1004,23 +997,41 @@ is divided into following sections: - + To run this application from the command line without Ant, try: java -jar "${dist.jar.resolved}" - + + + + + + + + + + + + + + + + + - + + - + + - - - - - - - - - - - - - To run this application from the command line without Ant, try: - - - - - - - java -cp "${run.classpath.with.dist.jar}" ${main.class} - - + - + - + - + + + + + + @@ -1004,23 +997,41 @@ is divided into following sections: - + To run this application from the command line without Ant, try: java -jar "${dist.jar.resolved}" - + + + + + + + + + + + + + + + + + - + + - + + - - - - - - - - - - - - - To run this application from the command line without Ant, try: - - - - - - - java -cp "${run.classpath.with.dist.jar}" ${main.class} - - + - + - + - + + + + + + @@ -1004,23 +997,41 @@ is divided into following sections: - + To run this application from the command line without Ant, try: java -jar "${dist.jar.resolved}" - + + + + + + + + + + + + + + + + + - + + - + + + + diff --git a/sdk/nbproject/platform.properties b/sdk/nbproject/platform.properties index 73f8590d7..65b38a709 100644 --- a/sdk/nbproject/platform.properties +++ b/sdk/nbproject/platform.properties @@ -1,4 +1,6 @@ branding.token=jmonkeyplatform +keystore=../nbproject/private/keystore.jks +nbm_alias=jmeupdates cluster.path=\ ${nbplatform.active.dir}/extide:\ ${nbplatform.active.dir}/harness:\ diff --git a/sdk/nbproject/project.properties b/sdk/nbproject/project.properties index dbcdb7343..64104ff3a 100644 --- a/sdk/nbproject/project.properties +++ b/sdk/nbproject/project.properties @@ -3,13 +3,16 @@ app.icon=branding/core/core.jar/org/netbeans/core/startup/frame48.gif #same as ${branding.token} app.name=jmonkeyplatform app.title=jMonkeyEngine SDK +app.description=A complete 3D game development suite written purely in Java. +app.categories=Development,Graphics,IDE,3DGraphics,Java app.icon.icns=jmonkeyplatform.icns #version name used for application and settings folder, no spaces! app.version=3.1-snapshot-github #version number used for plugins, only 3 numbers (e.g. 3.1.3) plugins.version=3.1.0 +nbm.revision=0 #command line args -run.args.extra=-J-Xmx512m -J-XX\:PermSize\=128m -J-XX\:MaxDirectMemorySize\=2048m -J-Dsun.zip.disableMemoryMapping\=true -J-Dapple.awt.graphics.UseQuartz\=true -J-Dsun.java2d.noddraw\=true +run.args.extra=-J-Dsun.java2d.dpiaware\=true -J-Dapple.laf.useScreenMenuBar\=true -J-Dawt.useSystemAAFontSettings\=lcd -J-Dswing.aatext\=true -J-Xmx512m -J-XX\:MaxDirectMemorySize\=2048m -J-Dsun.zip.disableMemoryMapping\=true -J-Dapple.awt.graphics.UseQuartz\=true -J-Dsun.java2d.noddraw\=true auxiliary.org-netbeans-modules-apisupport-installer.license-file=license-jme.txt auxiliary.org-netbeans-modules-apisupport-installer.os-linux=true auxiliary.org-netbeans-modules-apisupport-installer.os-macosx=true @@ -48,7 +51,8 @@ modules=\ ${project.com.jme3.gde.angelfont}:\ ${project.com.jme3.gde.android}:\ ${project.com.jme3.gde.nmgen}:\ - ${project.com.jme3.gde.docs} + ${project.com.jme3.gde.docs}:\ + ${project.org.jme3.netbeans.plaf.darkmonkey} project.com.jme3.gde.android=jme3-android project.com.jme3.gde.angelfont=jme3-angelfont project.com.jme3.gde.blender=jme3-blender @@ -82,3 +86,4 @@ project.com.jme3.gde.textureeditor=jme3-texture-editor project.com.jme3.gde.vehiclecreator=jme3-vehicle-creator project.com.jme3.gde.wavefront=jme3-wavefront project.com.jme3.gde.welcome=jme3-welcome-screen +project.org.jme3.netbeans.plaf.darkmonkey=jme3-dark-laf diff --git a/settings.gradle b/settings.gradle index 346532460..6aad1b374 100644 --- a/settings.gradle +++ b/settings.gradle @@ -35,6 +35,10 @@ include 'jme3-testdata' // Example projects include 'jme3-examples' +if(buildAndroidExamples == "true"){ + include 'jme3-android-examples' +} + if(buildSdkProject == "true"){ include 'sdk' } diff --git a/upload.gradle b/upload.gradle new file mode 100644 index 000000000..e28f5f41b --- /dev/null +++ b/upload.gradle @@ -0,0 +1,6 @@ +task copySshKnownHosts(type: Copy) { + from 'private/known_hosts' + into System.properties['user.home'] + '/.ssh' +} + +uploadArchives.dependsOn copySshKnownHosts \ No newline at end of file diff --git a/version.gradle b/version.gradle new file mode 100644 index 000000000..40e934278 --- /dev/null +++ b/version.gradle @@ -0,0 +1,117 @@ +/* + Version Info Examples + ===================== + + Nightly Build Snapshot + * Full Version: 3.1-5124 + * POM Version: 3.1.0-SNAPSHOT + * NBM Revision: 5124 + * NBM UC Suffix: nightly/3.1/plugins + + Nightly Build Snapshot (PBRIsComing branch) + * Full Version: 3.1-PBRIsComing-5124 + * POM Version: 3.1.0-PBRIsComing-SNAPSHOT + * NBM Revision: 5124 + * NBM UC Suffix: PBRIsComing-nightly/3.1/plugins + + Alpha1 Release + * Full Version: 3.1-alpha1 + * POM Version: 3.1.0-alpha1 + * NBM Revision: 1 + * NBM UC Suffix: stable/3.1/plugins + + Final Release + * Full Version: 3.1 + * POM Version: 3.1.0 + * NBM Revision: 5 + * NBM UC Suffix: stable/3.1/plugins + */ + +import java.text.SimpleDateFormat +import org.ajoberstar.grgit.* + +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath 'org.ajoberstar:gradle-git:1.2.0' + } +} + +ext { + jmeRevision = 0 + jmeNbmRevision = 0 + jmeGitHash = "" + jmeGitTag = "" + jmeShortGitHash = "" + jmeBuildDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + jmeBranchName = "unknown" + jmeFullVersion = "${jmeVersion}-UNKNOWN" + jmePomVersion = "unknown" + jmeNbmUcSuffix = "unknown" +} + +task configureVersionInfo { + try { + def grgit = Grgit.open(project.file('.')) + jmeRevision = grgit.log(includes:['HEAD']).size() + jmeGitHash = grgit.head().id + jmeShortGitHash = grgit.head().abbreviatedId + jmeBranchName = grgit.branch.current.name + jmeGitTag = grgit.describe() + if (jmeGitTag == null) jmeGitTag = "" + + if (System.env.TRAVIS_BRANCH != null) { + jmeBranchName = System.env.TRAVIS_BRANCH + } + if (System.env.TRAVIS_TAG != null) { + jmeGitTag = System.env.TRAVIS_TAG + } + if (System.env.TRAVIS_PULL_REQUEST != null && + System.env.TRAVIS_PULL_REQUEST != "false") { + jmeBranchName += "-pr-" + System.env.TRAVIS_PULL_REQUEST + } + + jmeFullVersion = jmeMainVersion + jmePomVersion = jmeVersion + + if (jmeBranchName != "master") { + jmeFullVersion += "-${jmeBranchName}" + jmePomVersion += "-${jmeBranchName}" + + jmeNbmUcSuffix = "${jmeBranchName}-" + } else { + jmeNbmUcSuffix = "" + } + + if (jmeVersionTag == "SNAPSHOT") { + jmeNbmUcSuffix += "nightly" + } else { + jmeNbmUcSuffix += "stable" + } + + jmeNbmUcSuffix += "/" + jmeMainVersion + "/plugins" + + if (jmeVersionTag == "SNAPSHOT") { + jmeFullVersion += "-${jmeRevision}" + jmePomVersion += "-SNAPSHOT" + jmeNbmRevision = jmeRevision + } else if (jmeVersionTag == "") { + jmeNbmRevision = jmeVersionTagID + } else { + jmeFullVersion += "-${jmeVersionTag}" + jmePomVersion += "-${jmeVersionTag}" + jmeNbmRevision = jmeVersionTagID + } + + logger.warn("Full Version: ${jmeFullVersion}") + logger.warn("POM Version: ${jmePomVersion}") + logger.warn("NBM Revision: ${jmeNbmRevision}") + logger.warn("NBM UC Suffix: ${jmeNbmUcSuffix}") + } catch (ex) { + // Failed to get repo info + logger.warn("Failed to get repository info: " + ex.message + ". " + \ + "Only partial build info will be generated.") + } +}