diff --git a/.travis.yml b/.travis.yml index bcd7c1a..c4343b1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,11 +2,11 @@ language: java jdk: oraclejdk8 -# Pre-install Maven dependencies -install: mvn dependency:go-offline +# Do something so that Gradle isn't run +install: echo "Gradle run suppressed, using Maven instead" # Compile and test source -script: mvn clean -DbuildNumber=$TRAVIS_BUILD_NUMBER -DciSystem=travis -Dcommit=${TRAVIS_COMMIT:0:7} +script: mvn clean install -DbuildNumber=$TRAVIS_BUILD_NUMBER -DciSystem=travis -Dcommit=${TRAVIS_COMMIT:0:7} # Fetch resources, run deployment goal/task, and generate Javadocs and reports after_success: @@ -45,4 +45,4 @@ env: - secure: "VFecbQ+pXBMbLfEDZDmT4Hsh7BP5vxQPzL3uyjKpB6ZnUw1rAkjwyTLfXT/ONdu8683gDUgbf6DawQ2TkAQBGRQjEDZL2fKp2oXw8mX0t0WKpLjL6uqC8QuRwKLOk9rWuOTiuk8IU6gNTHeD+wFatnMxKrwIc54IY+deK/Wo0PE=" - secure: "RtHTH8NllkaVBFHpX8+54Vlao8FEuRCDuTkCyYq5EN+hOXTQ64lQhhQneE+L7XwFj8hP7VYEckLLZ/whkj6hXJVZw5EtYJ+WnB9OvoRa+hI48PTzCXeNd8dafNQhu32A2iIKyVdc0UmjsM/rchrLBDovdVpVzfzfnACoCNVYOlM=" - secure: "bKD7Z1RbmfTRQHZ05c75a/X05QFnS51ejhCp+mpk7t9NIlWgV3xE9xhlKWS3x+A6xv8xYIrsQctex0zYxuKwZNjtb9rfeF5Yuf3PADAlDjaUykupo27jAp4Vi2SrTouMSlOmlnkDZ8b+RHI4v8Cb/Q01p1manZMAeouBtcms0tg=" - - secure: "Z43e9QaVLJN2v+of2K3p5NwYvn9TSG6bV4R7aLwJvMBIbDJ07LIdPGwWOJ1D2MxjhGOT/GVoyWO1ri/fO7uxAziIqes6xjoQALZOl3jlhU7VG1qEsoCtlEUZcX/CUgeKX9CK1Xg143AmrcOPLdYx7d2kXJOt/gMRToXsiUaY/x8=" + - secure: "YpuIE54CJ0s3lcGn0eBUxiMy2OJWBBCk+s+q9cMGixVZEt262+Ek2y1aZ02cx7moedYwnFlmr8oZt6X4l1LKKPO7O+woL10OWtS2iZTZk49V1MO4getIn8NRjQ/NGqgr2FOobIU6ygrp5RND662slO+07CN+hxTExVHuedfvJ9E=" diff --git a/README.md b/README.md index f8be0ca..730efde 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Caustic [![License](http://img.shields.io/badge/license-MIT-lightgrey.svg?style=flat)][License] [![Flattr this](http://img.shields.io/badge/flattr-donate-lightgrey.svg?style=flat)][Donate] [![Build Status](http://img.shields.io/travis/flow/caustic/develop.svg?style=flat)](https://travis-ci.org/flow/caustic) [![Coverage Status](http://img.shields.io/coveralls/flow/caustic/develop.svg?style=flat)](https://coveralls.io/r/flow/caustic) - +OpenGL rendering API and library, with support for LWJGL. ## Getting Started * [Examples and code snippets](https://github.com/flow/examples/tree/master/caustic) @@ -15,6 +15,13 @@ The latest and greatest source can be found here on [GitHub](https://github.com/ Or download the latest [development archive](https://github.com/flow/caustic/archive/develop.zip) or the latest [stable archive](https://github.com/flow/caustic/archive/master.zip). +## Dependencies +We love open-source libraries! This project uses are few of them to make things easier. If you aren't using Maven or Gradle, you'll need these! +* [com.flowpowered:flow-math](https://oss.sonatype.org/#nexus-search;gav~com.flowpowered~flow-math~~~) +* [net.sf.trove4j:trove4j](https://oss.sonatype.org/#nexus-search;gav~net.sf.trove4j~trove4j~~~) +* [org.lwjgl.lwjgl:lwjgl](https://oss.sonatype.org/#nexus-search;gav~org.lwjgl.lwjgl~lwjgl~~~) +* [org.lwjgl.lwjgl:lwjgl_util](https://oss.sonatype.org/#nexus-search;gav~org.lwjgl.lwjgl~lwjgl_util~~~) + ## Test Dependencies The following dependencies are only needed if you compiling the tests included with this project. Gotta test 'em all! * [junit:junit](https://oss.sonatype.org/#nexus-search;gav~junit~junit~~~) @@ -43,7 +50,7 @@ If you're using [Maven](https://maven.apache.org/download.html) to manage projec com.flowpowered caustic - 1.0.0-SNAPSHOT + 1.0.0 If you're using [Gradle](https://www.gradle.org/) to manage project dependencies, simply include the following in your `build.gradle` file: @@ -52,7 +59,7 @@ If you're using [Gradle](https://www.gradle.org/) to manage project dependencies mavenCentral() } dependencies { - compile 'com.flowpowered:caustic:1.0.0-SNAPSHOT' + compile 'com.flowpowered:caustic:1.0.0' } If you plan on using snapshots and do not already have the snapshot repo in your repository list, you will need to add this as well: diff --git a/android/pom.xml b/android/pom.xml deleted file mode 100644 index 878adf9..0000000 --- a/android/pom.xml +++ /dev/null @@ -1,38 +0,0 @@ - - 4.0.0 - - - Caustic Android - caustic-android - jar - Android implementation of the Caustic rendering library API. - - - - com.flowpowered - caustic - 1.0.0-SNAPSHOT - - - - - .. - 4.1.1.4 - - - - - - - ${project.groupId} - caustic-api - ${project.version} - - - com.google.android - android - ${android.version} - - - diff --git a/android/src/main/java/com/flowpowered/caustic/android/AndroidUtil.java b/android/src/main/java/com/flowpowered/caustic/android/AndroidUtil.java deleted file mode 100644 index d7033ea..0000000 --- a/android/src/main/java/com/flowpowered/caustic/android/AndroidUtil.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is part of Caustic Android, licensed under the MIT License (MIT). - * - * Copyright (c) 2013 Flow Powered - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.flowpowered.caustic.android; - -import android.opengl.GLES20; -import android.opengl.GLU; - -public final class AndroidUtil { - //public static final GLImplementation GLES20_IMPL = new GLImplementation(GLVersion.GLES20, GLES20GLFactory.class.getName()); - private static boolean debug = true; - - private AndroidUtil() { - } - - /** - * Sets the caustic renderer in debug mode. - * - * @param enabled If debug should be enabled - */ - public static void setDebugEnabled(boolean enabled) { - debug = enabled; - } - - /** - * Throws an exception if OpenGL reports an error. - * - * @throws com.flowpowered.caustic.android.AndroidUtil.GLESException If OpenGL reports an error - */ - public static void checkForGLESError() { - if (debug) { - final int errorValue = GLES20.glGetError(); - if (errorValue != GLES20.GL_NO_ERROR) { - throw new GLESException("OPEN GL ERROR: " + GLU.gluErrorString(errorValue)); - } - } - } - - /** - * An exception throw when a GLES exception occurs on Android. - */ - public static class GLESException extends RuntimeException { - /** - * Constructs a new Android GLES exception from the message. - * - * @param message The error message - */ - public GLESException(String message) { - super(message); - } - } -} diff --git a/api/build.gradle b/api/build.gradle new file mode 100644 index 0000000..b9d0a33 --- /dev/null +++ b/api/build.gradle @@ -0,0 +1,11 @@ +// Project information +ext.projectName = 'Caustic API' +archivesBaseName = 'caustic-api' +ext.packaging = 'jar' +ext.description = 'API for the Caustic OpenGL rendering library.' + +// Project dependencies +dependencies { + compile 'net.sf.trove4j:trove4j:3.0.3' + compile 'com.flowpowered:flow-math:1.0.0' +} diff --git a/api/pom.xml b/api/pom.xml index 4254f75..b699f2d 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -1,5 +1,4 @@ - + 4.0.0 @@ -12,7 +11,7 @@ com.flowpowered caustic - 1.0.0-SNAPSHOT + 1.0.0 diff --git a/api/src/main/java/com/flowpowered/caustic/api/gl/Context.java b/api/src/main/java/com/flowpowered/caustic/api/gl/Context.java index e3c73cc..19ca1a1 100644 --- a/api/src/main/java/com/flowpowered/caustic/api/gl/Context.java +++ b/api/src/main/java/com/flowpowered/caustic/api/gl/Context.java @@ -109,6 +109,12 @@ public void destroy() { */ public abstract void setWindowTitle(String title); + /** + * Sets if the window can be re-sized. + * @param resizable Whether or not the window can be re-sized + */ + public abstract void setResizable(boolean resizable); + /** * Sets the window size. * diff --git a/api/src/main/java/com/flowpowered/caustic/api/model/StringModel.java b/api/src/main/java/com/flowpowered/caustic/api/model/StringModel.java index 757490e..1b1b77e 100644 --- a/api/src/main/java/com/flowpowered/caustic/api/model/StringModel.java +++ b/api/src/main/java/com/flowpowered/caustic/api/model/StringModel.java @@ -34,10 +34,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import com.flowpowered.math.GenericMath; -import com.flowpowered.math.vector.Vector2f; -import com.flowpowered.math.vector.Vector4f; - import gnu.trove.impl.Constants; import gnu.trove.list.TFloatList; import gnu.trove.list.TIntList; @@ -49,6 +45,10 @@ import gnu.trove.map.hash.TCharIntHashMap; import gnu.trove.map.hash.TIntObjectHashMap; +import com.flowpowered.math.GenericMath; +import com.flowpowered.math.vector.Vector2f; +import com.flowpowered.math.vector.Vector4f; + import com.flowpowered.caustic.api.Material; import com.flowpowered.caustic.api.data.VertexAttribute; import com.flowpowered.caustic.api.data.VertexAttribute.DataType; diff --git a/api/src/main/java/com/flowpowered/caustic/api/util/ColladaFileLoader.java b/api/src/main/java/com/flowpowered/caustic/api/util/ColladaFileLoader.java index d6e04aa..b896841 100644 --- a/api/src/main/java/com/flowpowered/caustic/api/util/ColladaFileLoader.java +++ b/api/src/main/java/com/flowpowered/caustic/api/util/ColladaFileLoader.java @@ -23,6 +23,12 @@ */ package com.flowpowered.caustic.api.util; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; @@ -31,14 +37,6 @@ import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.flowpowered.math.vector.Vector3i; import gnu.trove.list.TFloatList; import gnu.trove.list.TIntList; @@ -52,6 +50,8 @@ import org.w3c.dom.NodeList; import org.xml.sax.SAXException; +import com.flowpowered.math.vector.Vector3i; + /** * A static loading class for the COLLADA file format (.dae). This class has the capability to load mesh data such as positions, texture coordinates, and normals. All models should be triangulated. * Apart from geometry, the COLLADA file format also allows for joint descriptions as well as animation descriptions. COLLADA also allows for physical properties to be assigned to a model which can be diff --git a/api/src/main/java/com/flowpowered/caustic/api/util/MeshGenerator.java b/api/src/main/java/com/flowpowered/caustic/api/util/MeshGenerator.java index db1ce58..ff2790e 100644 --- a/api/src/main/java/com/flowpowered/caustic/api/util/MeshGenerator.java +++ b/api/src/main/java/com/flowpowered/caustic/api/util/MeshGenerator.java @@ -29,6 +29,12 @@ import java.util.List; import java.util.Set; +import gnu.trove.list.TFloatList; +import gnu.trove.list.TIntList; +import gnu.trove.list.array.TFloatArrayList; +import gnu.trove.map.TObjectIntMap; +import gnu.trove.map.hash.TObjectIntHashMap; + import com.flowpowered.math.GenericMath; import com.flowpowered.math.TrigMath; import com.flowpowered.math.matrix.Matrix3f; @@ -37,12 +43,6 @@ import com.flowpowered.math.vector.Vector3f; import com.flowpowered.math.vector.Vector4i; -import gnu.trove.list.TFloatList; -import gnu.trove.list.TIntList; -import gnu.trove.list.array.TFloatArrayList; -import gnu.trove.map.TObjectIntMap; -import gnu.trove.map.hash.TObjectIntHashMap; - import com.flowpowered.caustic.api.data.VertexAttribute; import com.flowpowered.caustic.api.data.VertexAttribute.DataType; import com.flowpowered.caustic.api.data.VertexData; diff --git a/api/src/main/java/com/flowpowered/caustic/api/util/ObjFileLoader.java b/api/src/main/java/com/flowpowered/caustic/api/util/ObjFileLoader.java index cb39b22..16165d0 100644 --- a/api/src/main/java/com/flowpowered/caustic/api/util/ObjFileLoader.java +++ b/api/src/main/java/com/flowpowered/caustic/api/util/ObjFileLoader.java @@ -26,13 +26,13 @@ import java.io.InputStream; import java.util.Scanner; -import com.flowpowered.math.vector.Vector3i; - import gnu.trove.list.TFloatList; import gnu.trove.list.TIntList; import gnu.trove.list.array.TFloatArrayList; import gnu.trove.list.array.TIntArrayList; +import com.flowpowered.math.vector.Vector3i; + /** * A static loading class for standard .obj model files. This class will load positions, normals can texture coordinates. Missing normals are not calculated. Normals are expected to be of unit length. * Models should be triangulated. diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..ed6a72e --- /dev/null +++ b/build.gradle @@ -0,0 +1,223 @@ +// Default tasks +defaultTasks 'clean', 'licenseFormat', 'build', 'install' + +// Apply plugins +apply plugin: 'cobertura' // Coveralls dependency +apply plugin: 'com.github.kt3k.coveralls' +apply plugin: 'license' + +// Project information +ext.projectName = 'Caustic' +group = 'com.flowpowered' +version = '1.0.0' +ext.packaging = 'pom' +ext.inceptionYear = '2013' +ext.url = 'https://flowpowered.com/caustic' +ext.description = 'Parent Gradle project for the Caustic OpenGL rendering library.' + +// Organization information +ext.organization = 'Flow Powered' +ext.organizationUrl = 'https://flowpowered.com' + +// Build properties +ext.buildNumber = project.hasProperty('buildNumber') ? buildNumber : '0' +ext.ciSystem = project.hasProperty('ciSystem') ? ciSystem : 'unknown' +ext.commit = project.hasProperty('commit') ? commit : 'unknown' + +// Apply to all projects +allprojects { + // Apply plugins + apply plugin: 'java' + apply plugin: 'maven' + apply plugin: 'signing' + + // Project information + ext.projectName = 'Caustic' + group = 'com.flowpowered' + version = '1.0.0' + ext.packaging = 'pom' + ext.inceptionYear = '2013' + ext.url = 'https://flowpowered.com/caustic' + ext.description = 'Parent Gradle project for the Caustic OpenGL rendering library.' + + // Project repositories + repositories { + mavenLocal() + mavenCentral() + maven { + name = 'sonatype-nexus' + url = 'https://oss.sonatype.org/content/groups/public/' + } + } + + // Project dependencies + dependencies { + testCompile 'junit:junit:4.12' + } + + // Filter, process, and include resources + processResources { + // Include in final JAR + from(rootProject.rootDir) { + include 'LICENSE.txt' + } + } + + // License header formatting + license { + ext.project = projectName + ext.year = inceptionYear + ext.name = organization + ext.url = organizationUrl + header rootProject.file('HEADER.txt') + ignoreFailures true + strictCheck true + useDefaultMappings false + mapping { java = 'SLASHSTAR_STYLE' } + } + + // JAR manifest configuration + jar.manifest.mainAttributes( + 'Built-By': System.properties['user.name'], + 'Created-By': System.properties['java.vm.version'] + ' (' + System.properties['java.vm.vendor'] + ')', + 'Specification-Title': projectName, + 'Specification-Version': version + '+' + ciSystem + '-b' + buildNumber + '.git-' + commit, + 'Specification-Vendor': organization + ' - ' + organizationUrl) + + // Artifact deployment + uploadArchives { + repositories.mavenDeployer { + // Javadoc JAR generation + task javadocJar(type: Jar, dependsOn: javadoc) { + classifier = 'javadoc' + from 'build/docs/javadoc' + } + + // Source JAR generation + task sourcesJar(type: Jar) { + classifier = 'sources' + from sourceSets.main.java.srcDirs + } + + // Set all artifacts + artifacts { + archives jar, javadocJar, sourcesJar + } + + // Tasks and variables based on if release or snapshot + if (version.endsWith('-SNAPSHOT')) { + // Set variable to snapshots repository URL + ext.sonatypeUrl = 'https://oss.sonatype.org/content/repositories/snapshots/' + } else { + // Set variable to releases repository URL + ext.sonatypeUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2/' + + // Artifact signing + signing { + // Sign JAR artifacts + sign configurations.archives + + // Sign Maven POM + beforeDeployment { + org.gradle.api.artifacts.maven.MavenDeployment deployment -> signing.signPom(deployment) + } + } + } + + // Set login credentials for repository + repository(url: sonatypeUrl) { + authentication(userName: System.getenv("sonatypeUsername"), password: System.getenv("sonatypePassword")) + } + + // Maven POM generation + pom.project { + name projectName + artifactId archivesBaseName + packaging packaging + inceptionYear inceptionYear + url url + description project.ext.description + + scm { + connection 'scm:git:git://github.com/flow/caustic.git' + developerConnection 'scm:git:ssh://git@github.com:flow/caustic.git' + url 'https://github.com/flow/caustic' + } + + licenses { + license { + name 'MIT License' + url 'https://tldrlegal.com/l/mit' + distribution 'repo' + } + } + + organization { + name organization + url organizationUrl + } + + developers { + developer { + id 'DDoS' + name 'Aleksi Sapon' + email 'qctechs@gmail.com' + } + developer { + id 'kitskub' + name 'Jack Huey' + email 'kitskub@gmail.com' + } + developer { + id 'Wolf480pl' + name 'Wolf480pl' + email 'wolf480@interia.pl' + } + developer { + id 'Wulfspider' + name 'Luke Spragg' + email 'the@wulf.im' + } + } + } + } + } +} + +// Build plugin repositories and dependencies +buildscript { + repositories { + mavenLocal() + mavenCentral() + maven { + name = 'sonatype-nexus' + url = 'https://oss.sonatype.org/content/groups/public/' + } + } + dependencies { + classpath 'net.saliman:gradle-cobertura-plugin:2.2.5' // Coveralls dependency + classpath 'nl.javadude.gradle.plugins:license-gradle-plugin:0.10.0' + classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.0.1' + } +} + +// Source compiler configuration +configure([compileJava, compileTestJava]) { + sourceCompatibility = '1.7' + targetCompatibility = '1.7' + options.compilerArgs += ['-Xlint:all', '-Xlint:-path'] + options.deprecation = true + options.encoding = 'UTF-8' +} + +// Javadoc doclint configuration +if (JavaVersion.current().isJava8Compatible()) { + allprojects { + tasks.withType(Javadoc) { + options.addStringOption('Xdoclint:none', '-quiet') + } + } +} + +// Coveralls report configuration +cobertura.coverageFormats = ['html', 'xml'] // Coveralls requires xml format diff --git a/bump.sh b/bump.sh index e78375f..08800bc 100755 --- a/bump.sh +++ b/bump.sh @@ -10,5 +10,5 @@ read -p "New version: " NEW_VERSION || die_with "Prompt for new version failed" if ! echo $NEW_VERSION | grep -i -- '-SNAPSHOT' >/dev/null; then echo "WARNING: changing to a release version!"; fi echo "Updating the project version in build.gradle, pom.xml and README.md to $NEW_VERSION" -sed -ri "s/"`echo $CURRENT_VERSION | sed 's/\./\\\\./g'`"/$NEW_VERSION/g" build.gradle pom.xml README.md || die_with "Failed to update the project version!" -chmod 644 build.gradle pom.xml README.md +find . \( -name "pom.xml" -o -name "README.md" \) -exec sed -i "s/$CURRENT_VERSION/$NEW_VERSION/g" {} \; die_with "Failed to update the project version!" +chmod -R 644 pom.xml README.md diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..667288a Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..e32f178 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=http\://services.gradle.org/distributions/gradle-2.0-all.zip diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..91a7e26 --- /dev/null +++ b/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..8a0b282 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/lwjgl/build.gradle b/lwjgl/build.gradle new file mode 100644 index 0000000..4a28c46 --- /dev/null +++ b/lwjgl/build.gradle @@ -0,0 +1,12 @@ +// Project information +ext.projectName = 'Caustic LWJGL' +archivesBaseName = 'caustic-lwjgl' +ext.packaging = 'jar' +ext.description = 'LWJGL implementation of the Caustic rendering library API.' + +// Project dependencies +dependencies { + compile 'com.flowpowered:caustic-api:1.0.0-SNAPSHOT' + compile 'org.lwjgl.lwjgl:lwjgl:2.9.1' + compile 'org.lwjgl.lwjgl:lwjgl_util:2.9.1' +} diff --git a/lwjgl/pom.xml b/lwjgl/pom.xml index 8b8e889..497fe42 100644 --- a/lwjgl/pom.xml +++ b/lwjgl/pom.xml @@ -1,5 +1,4 @@ - + 4.0.0 @@ -12,7 +11,7 @@ com.flowpowered caustic - 1.0.0-SNAPSHOT + 1.0.0 diff --git a/lwjgl/src/main/java/com/flowpowered/caustic/lwjgl/gl20/GL20Context.java b/lwjgl/src/main/java/com/flowpowered/caustic/lwjgl/gl20/GL20Context.java index 8343fc1..d98308e 100644 --- a/lwjgl/src/main/java/com/flowpowered/caustic/lwjgl/gl20/GL20Context.java +++ b/lwjgl/src/main/java/com/flowpowered/caustic/lwjgl/gl20/GL20Context.java @@ -25,9 +25,6 @@ import java.nio.ByteBuffer; -import com.flowpowered.math.vector.Vector2i; -import com.flowpowered.math.vector.Vector4f; - import org.lwjgl.LWJGLException; import org.lwjgl.opengl.ContextAttribs; import org.lwjgl.opengl.Display; @@ -46,6 +43,8 @@ import com.flowpowered.caustic.api.util.CausticUtil; import com.flowpowered.caustic.api.util.Rectangle; import com.flowpowered.caustic.lwjgl.LWJGLUtil; +import com.flowpowered.math.vector.Vector2i; +import com.flowpowered.math.vector.Vector4f; /** * An OpenGL 2.0 implementation of {@link com.flowpowered.caustic.api.gl.Context}. @@ -130,6 +129,11 @@ public void setWindowTitle(String title) { Display.setTitle(title); } + @Override + public void setResizable(boolean resizable) { + Display.setResizable(resizable); + } + @Override public void setWindowSize(Vector2i windowSize) { try { diff --git a/lwjgl/src/main/java/com/flowpowered/caustic/lwjgl/gl20/GL20Program.java b/lwjgl/src/main/java/com/flowpowered/caustic/lwjgl/gl20/GL20Program.java index 98a1e3b..2e819b3 100644 --- a/lwjgl/src/main/java/com/flowpowered/caustic/lwjgl/gl20/GL20Program.java +++ b/lwjgl/src/main/java/com/flowpowered/caustic/lwjgl/gl20/GL20Program.java @@ -34,13 +34,6 @@ import java.util.logging.Level; import java.util.logging.Logger; -import com.flowpowered.math.matrix.Matrix2f; -import com.flowpowered.math.matrix.Matrix3f; -import com.flowpowered.math.matrix.Matrix4f; -import com.flowpowered.math.vector.Vector2f; -import com.flowpowered.math.vector.Vector3f; -import com.flowpowered.math.vector.Vector4f; - import gnu.trove.impl.Constants; import gnu.trove.iterator.TObjectIntIterator; import gnu.trove.map.TIntObjectMap; @@ -51,6 +44,13 @@ import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL20; +import com.flowpowered.math.matrix.Matrix2f; +import com.flowpowered.math.matrix.Matrix3f; +import com.flowpowered.math.matrix.Matrix4f; +import com.flowpowered.math.vector.Vector2f; +import com.flowpowered.math.vector.Vector3f; +import com.flowpowered.math.vector.Vector4f; + import com.flowpowered.caustic.api.gl.Program; import com.flowpowered.caustic.api.gl.Shader; import com.flowpowered.caustic.api.util.CausticUtil; diff --git a/lwjgl/src/main/java/com/flowpowered/caustic/lwjgl/gl20/GL20Texture.java b/lwjgl/src/main/java/com/flowpowered/caustic/lwjgl/gl20/GL20Texture.java index 4560419..950c0c3 100644 --- a/lwjgl/src/main/java/com/flowpowered/caustic/lwjgl/gl20/GL20Texture.java +++ b/lwjgl/src/main/java/com/flowpowered/caustic/lwjgl/gl20/GL20Texture.java @@ -26,8 +26,6 @@ import java.nio.ByteBuffer; import java.nio.FloatBuffer; -import com.flowpowered.math.vector.Vector4f; - import org.lwjgl.opengl.EXTTextureFilterAnisotropic; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; @@ -38,6 +36,7 @@ import com.flowpowered.caustic.api.gl.Texture; import com.flowpowered.caustic.api.util.CausticUtil; import com.flowpowered.caustic.lwjgl.LWJGLUtil; +import com.flowpowered.math.vector.Vector4f; /** * An OpenGL 2.0 implementation of {@link Texture}. @@ -199,6 +198,10 @@ public void setImageData(ByteBuffer imageData, int width, int height) { if (height <= 0) { throw new IllegalArgumentException("Height must be greater than zero"); } + // Back up the old values + int oldWidth = this.width; + int oldHeight = this.height; + // Update the texture width and height this.width = width; this.height = height; // Bind the texture @@ -210,12 +213,17 @@ public void setImageData(ByteBuffer imageData, int width, int height) { GLU.gluBuild2DMipmaps(GL11.GL_TEXTURE_2D, hasInternalFormat ? internalFormat.getGLConstant() : format.getGLConstant(), width, height, format.getGLConstant(), hasInternalFormat ? internalFormat.getComponentType().getGLConstant() : DataType.UNSIGNED_BYTE.getGLConstant(), imageData); } else { - // Else just make it a normal texture - // Use byte alignment + // Else just make it a normal texture, use byte alignment GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1); - // Upload the image - GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, hasInternalFormat ? internalFormat.getGLConstant() : format.getGLConstant(), width, height, 0, format.getGLConstant(), - hasInternalFormat ? internalFormat.getComponentType().getGLConstant() : DataType.UNSIGNED_BYTE.getGLConstant(), imageData); + // Check if we can only upload without reallocating + if (imageData != null && width == oldWidth && height == oldHeight) { + GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D, 0, 0, 0, width, height, format.getGLConstant(), + hasInternalFormat ? internalFormat.getComponentType().getGLConstant() : DataType.UNSIGNED_BYTE.getGLConstant(), imageData); + } else { + // Reallocate and upload the image + GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, hasInternalFormat ? internalFormat.getGLConstant() : format.getGLConstant(), width, height, 0, format.getGLConstant(), + hasInternalFormat ? internalFormat.getComponentType().getGLConstant() : DataType.UNSIGNED_BYTE.getGLConstant(), imageData); + } } // Unbind the texture GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); diff --git a/lwjgl/src/main/java/com/flowpowered/caustic/lwjgl/gl20/GL20VertexArray.java b/lwjgl/src/main/java/com/flowpowered/caustic/lwjgl/gl20/GL20VertexArray.java index 603b34e..919db39 100644 --- a/lwjgl/src/main/java/com/flowpowered/caustic/lwjgl/gl20/GL20VertexArray.java +++ b/lwjgl/src/main/java/com/flowpowered/caustic/lwjgl/gl20/GL20VertexArray.java @@ -143,12 +143,13 @@ public void setData(VertexData vertexData) { } // Unbind the indices buffer GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0); - // Update the count to the new one + // Update the total indices count indicesCount = newIndicesCount; - indicesDrawCount = indicesCount; + // Ensure the count fits under the total one + indicesDrawCount = indicesDrawCount <= 0 ? indicesCount : Math.min(indicesDrawCount, indicesCount); // Ensure that the indices offset and count fits inside the valid part of the buffer - indicesOffset = Math.min(indicesOffset, indicesCount - 1); - indicesDrawCount = indicesDrawCount - indicesOffset; + indicesOffset = Math.min(indicesOffset, indicesDrawCount - 1); + indicesDrawCount -= indicesOffset; // Bind the vao if (extension.has()) { extension.glBindVertexArray(id); @@ -245,12 +246,8 @@ public void setIndicesOffset(int offset) { @Override public void setIndicesCount(int count) { - if (count < 0) { - indicesDrawCount = indicesCount; - } else { - indicesDrawCount = count; - } - indicesDrawCount = Math.min(indicesDrawCount, indicesCount - indicesOffset); + indicesDrawCount = count <= 0 ? indicesCount : count; + indicesDrawCount = Math.min(count, indicesCount - indicesOffset); } @Override diff --git a/lwjgl/src/main/java/com/flowpowered/caustic/lwjgl/gl30/GL30Texture.java b/lwjgl/src/main/java/com/flowpowered/caustic/lwjgl/gl30/GL30Texture.java index eca37be..87f9e12 100644 --- a/lwjgl/src/main/java/com/flowpowered/caustic/lwjgl/gl30/GL30Texture.java +++ b/lwjgl/src/main/java/com/flowpowered/caustic/lwjgl/gl30/GL30Texture.java @@ -47,6 +47,10 @@ public void setImageData(ByteBuffer imageData, int width, int height) { if (height <= 0) { throw new IllegalArgumentException("Height must be greater than zero"); } + // Back up the old values + int oldWidth = this.width; + int oldHeight = this.height; + // Update the texture width and height this.width = width; this.height = height; // Bind the texture @@ -55,8 +59,15 @@ public void setImageData(ByteBuffer imageData, int width, int height) { GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1); // Upload the texture final boolean hasInternalFormat = internalFormat != null; - GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, hasInternalFormat ? internalFormat.getGLConstant() : format.getGLConstant(), width, height, 0, format.getGLConstant(), - hasInternalFormat ? internalFormat.getComponentType().getGLConstant() : DataType.UNSIGNED_BYTE.getGLConstant(), imageData); + // Check if we can only upload without reallocating + if (imageData != null && width == oldWidth && height == oldHeight) { + GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D, 0, 0, 0, width, height, format.getGLConstant(), + hasInternalFormat ? internalFormat.getComponentType().getGLConstant() : DataType.UNSIGNED_BYTE.getGLConstant(), imageData); + } else { + // Reallocate and upload the image + GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, hasInternalFormat ? internalFormat.getGLConstant() : format.getGLConstant(), width, height, 0, format.getGLConstant(), + hasInternalFormat ? internalFormat.getComponentType().getGLConstant() : DataType.UNSIGNED_BYTE.getGLConstant(), imageData); + } // Generate mipmaps if necessary if (minFilter.needsMipMaps() && imageData != null) { GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D); diff --git a/lwjgl/src/main/java/com/flowpowered/caustic/lwjgl/gl30/GL30VertexArray.java b/lwjgl/src/main/java/com/flowpowered/caustic/lwjgl/gl30/GL30VertexArray.java index 5c6d1a4..d868346 100644 --- a/lwjgl/src/main/java/com/flowpowered/caustic/lwjgl/gl30/GL30VertexArray.java +++ b/lwjgl/src/main/java/com/flowpowered/caustic/lwjgl/gl30/GL30VertexArray.java @@ -112,12 +112,13 @@ public void setData(VertexData vertexData) { } // Unbind the indices buffer GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0); - // Update the count to the new one + // Update the total indices count indicesCount = newIndicesCount; - indicesDrawCount = indicesCount; + // Ensure the count fits under the total one + indicesDrawCount = indicesDrawCount <= 0 ? indicesCount : Math.min(indicesDrawCount, indicesCount); // Ensure that the indices offset and count fits inside the valid part of the buffer - indicesOffset = Math.min(indicesOffset, indicesCount - 1); - indicesDrawCount = indicesDrawCount - indicesOffset; + indicesOffset = Math.min(indicesOffset, indicesDrawCount - 1); + indicesDrawCount -= indicesOffset; // Bind the vao GL30.glBindVertexArray(id); // Create a new array of attribute buffers ID of the correct size @@ -203,12 +204,8 @@ public void setIndicesOffset(int offset) { @Override public void setIndicesCount(int count) { - if (count < 0) { - indicesDrawCount = indicesCount; - } else { - indicesDrawCount = count; - } - indicesDrawCount = Math.min(indicesDrawCount, indicesCount - indicesOffset); + indicesDrawCount = count <= 0 ? indicesCount : count; + indicesDrawCount = Math.min(count, indicesCount - indicesOffset); } @Override diff --git a/pom.xml b/pom.xml index 80c6c79..5a91eb5 100644 --- a/pom.xml +++ b/pom.xml @@ -1,15 +1,14 @@ - + 4.0.0 Caustic com.flowpowered caustic - 1.0.0-SNAPSHOT + 1.0.0 pom 2013 - https://flowpowered.com + https://flowpowered.com/caustic Parent Maven project for the Caustic OpenGL rendering library. @@ -23,8 +22,7 @@ api lwjgl - android - software + @@ -118,7 +116,7 @@ . . - LICENSE.txt + ${project.root}/LICENSE.txt diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..ded588a --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +include 'api', 'lwjgl' diff --git a/software/build.gradle b/software/build.gradle new file mode 100644 index 0000000..ad23b3a --- /dev/null +++ b/software/build.gradle @@ -0,0 +1,10 @@ +// Project information +ext.projectName = 'Caustic Software' +archivesBaseName = 'caustic-software' +ext.packaging = 'jar' +ext.description = 'Software implementation of the Caustic rendering library API.' + +// Project dependencies +dependencies { + compile 'com.flowpowered:caustic-api:1.0.0-SNAPSHOT' +} diff --git a/software/src/main/java/com/flowpowered/caustic/software/SoftwareContext.java b/software/src/main/java/com/flowpowered/caustic/software/SoftwareContext.java index 4bb1522..e68d470 100644 --- a/software/src/main/java/com/flowpowered/caustic/software/SoftwareContext.java +++ b/software/src/main/java/com/flowpowered/caustic/software/SoftwareContext.java @@ -96,6 +96,11 @@ public void setWindowTitle(String title) { renderer.setWindowTitle(title); } + @Override + public void setResizable(boolean resizable) { + renderer.setWindowResizable(resizable); + } + @Override public void setWindowSize(Vector2i windowSize) { renderer.setWindowSize(windowSize.getX(), windowSize.getY()); diff --git a/software/src/main/java/com/flowpowered/caustic/software/SoftwareRenderer.java b/software/src/main/java/com/flowpowered/caustic/software/SoftwareRenderer.java index 3d96949..51c4990 100644 --- a/software/src/main/java/com/flowpowered/caustic/software/SoftwareRenderer.java +++ b/software/src/main/java/com/flowpowered/caustic/software/SoftwareRenderer.java @@ -37,13 +37,13 @@ import java.awt.image.DataBufferInt; import java.util.Arrays; -import gnu.trove.map.TIntObjectMap; -import gnu.trove.map.hash.TIntObjectHashMap; - import com.flowpowered.caustic.api.gl.Context.Capability; import com.flowpowered.caustic.api.util.CausticUtil; import com.flowpowered.caustic.api.util.Rectangle; +import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.TIntObjectHashMap; + /** * */ @@ -81,6 +81,10 @@ int getWindowWidth() { return width; } + void setWindowResizable(boolean resizable) { + frame.setResizable(resizable); + } + void setWindowSize(int width, int height) { if (this.width != width || this.height != height) { this.width = width; @@ -171,7 +175,9 @@ private void updateImage() { pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); depths = new short[width * height]; frame.pack(); - frame.setLocationRelativeTo(null); + if (!frame.isResizable()) { + frame.setLocationRelativeTo(null); + } } void dispose() { @@ -189,6 +195,11 @@ void render() { graphics.drawImage(image, 0, 0, width * scale, height * scale, null); graphics.dispose(); bufferStrategy.show(); + if (frame.isResizable() && getWidth() != width && getHeight() != height) { + width = getWidth(); + height = getHeight(); + updateImage(); + } } void clearPixels() {