diff --git a/SquidSquad/DawnSquad/build.gradle b/SquidSquad/DawnSquad/build.gradle index 8e4b3756..266f4420 100644 --- a/SquidSquad/DawnSquad/build.gradle +++ b/SquidSquad/DawnSquad/build.gradle @@ -8,7 +8,7 @@ buildscript { dependencies { classpath "com.android.tools.build:gradle:8.1.4" classpath "org.docstr:gwt-gradle-plugin:$gwtPluginVersion" - classpath 'com.guardsquare:proguard-gradle:7.3.2' + classpath 'com.guardsquare:proguard-gradle:7.4.2' } } diff --git a/SquidSquad/DaybreakDemo/core/src/main/java/com/github/tommyettinger/AnimatedGlidingSprite.java b/SquidSquad/DaybreakDemo/core/src/main/java/com/github/tommyettinger/AnimatedGlidingSprite.java deleted file mode 100644 index 286b6f43..00000000 --- a/SquidSquad/DaybreakDemo/core/src/main/java/com/github/tommyettinger/AnimatedGlidingSprite.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2022-2023 See AUTHORS file. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.tommyettinger; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.g2d.Animation; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.utils.NumberUtils; -import com.github.yellowstonegames.grid.Coord; -import com.github.yellowstonegames.smooth.CoordGlider; -import com.github.yellowstonegames.smooth.ParentSprite; -import com.github.yellowstonegames.smooth.VectorSequenceGlider; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; - -import static com.badlogic.gdx.graphics.g2d.SpriteBatch.*; - -/** - * Extends {@link ParentSprite}, but uses an {@link Animation} of {@link TextureRegion} for its visuals and a - * {@link CoordGlider} to store its position. The {@link CoordGlider} is publicly available as {@link #location} or with - * {@link #getLocation()}, which should be used to determine or change where this started its move, where it is going, - * and how far it has gone between the two. You Must Call {@link #animate(float)} with an increasing float parameter - * when you want the animation to be playing; otherwise it will stay on the first frame (or a later frame if you stop - * calling animate() at some other point). You can use the {@link VectorSequenceGlider} {@link #smallMotion} to move - * this AnimatedGlidingSprite at a finer resolution than between Coords for start and end points. - *
- * You probably want to use Textures with a width and height of 1 world unit in - * your Animation, and {@link #setSize(float, float)} on this to {@code 1, 1}; this avoids the need to convert between - * Coord units in the CoordGlider and some other unit in the world. - */ -public class AnimatedGlidingSprite extends ParentSprite { - public Animation animation; - @NonNull - public CoordGlider location; - @NonNull - public VectorSequenceGlider smallMotion; - /** - * A VectorSequenceGlider that is empty (has no motions) and belongs to this AnimatedGlidingSprite. - * This is public so external code can use it, but should never be modified. - * It is here so {@link #smallMotion} can be easily set to an empty sequence. - * You can also use {@code setSmallMotion(null)} to stop any small motion. - */ - @NonNull - public final VectorSequenceGlider ownEmptyMotion = VectorSequenceGlider.EMPTY.copy(); - - private AnimatedGlidingSprite() - { - this(null, Coord.get(0, 0)); - } - public AnimatedGlidingSprite(Animation animation) { - this(animation, Coord.get(0, 0)); - } - - public AnimatedGlidingSprite(Animation animation, Coord coord) { - this(animation, coord, coord); - } - - public AnimatedGlidingSprite(Animation animation, Coord start, Coord end) { - super(); - this.animation = animation; - setRegion(animation.getKeyFrame(0f)); - location = new CoordGlider(start, end); - smallMotion = ownEmptyMotion; - setPackedColor(SunBatch.NEUTRAL); - } - - /** - * Required to use to have the animation play; give this a steadily increasing stateTime (measured in seconds, as a - * float) and it will steadily play the animation; if stateTime stops increasing or this stops being called, then - * the animation is effectively paused. - * @param stateTime time playing the animation, in seconds; usually not an exact integer - * @return this for chaining - */ - public AnimatedGlidingSprite animate(final float stateTime) - { - setRegion(animation.getKeyFrame(stateTime)); - return this; - } - - public float getX() - { - return location.getX() + smallMotion.getX(); - } - - public float getY() - { - return location.getY() + smallMotion.getY(); - } - - @Override - public float[] getVertices() { - super.setPosition(getX(), getY()); - return super.getVertices(); - } - - public Animation getAnimation() { - return animation; - } - - public void setAnimation(Animation animation) { - this.animation = animation; - } - - @NonNull - public CoordGlider getLocation() { - return location; - } - - public void setLocation(@NonNull CoordGlider location) { - this.location = location; - } - - @NonNull - public VectorSequenceGlider getSmallMotion() { - return smallMotion; - } - - public void setSmallMotion(@Nullable VectorSequenceGlider smallMotion) { - if(smallMotion == null) this.smallMotion = ownEmptyMotion; - else this.smallMotion = smallMotion; - } - - - /** Sets the color used to tint this sprite. Default is {@link Color#WHITE}. */ - public void setColor (Color tint) { - float color = tint.toFloatBits(); - float[] vertices = this.vertices; - vertices[C1] = color; - vertices[C2] = color; - vertices[C3] = color; - vertices[C4] = color; - } - - /** Sets the alpha portion of the color used to tint this sprite. */ - public void setAlpha (float a) { - int bits = NumberUtils.floatToIntBits(vertices[C1]); - float color = NumberUtils.intBitsToFloat((bits & 0xFFFFFF) | (int)(a * 127.5f) << 25); - vertices[C1] = color; - vertices[C2] = color; - vertices[C3] = color; - vertices[C4] = color; - } - - /** @see #setColor(Color) */ - public void setColor (float r, float g, float b, float a) { - float color = Color.toFloatBits(r, g, b, a); - float[] vertices = this.vertices; - vertices[C1] = color; - vertices[C2] = color; - vertices[C3] = color; - vertices[C4] = color; - } - - /** Sets the color of this sprite, expanding the alpha from 0-254 to 0-255. - * @see #setColor(Color) - * @see Color#toFloatBits() */ - public void setPackedColor (float packedColor) { - float[] vertices = this.vertices; - vertices[C1] = packedColor; - vertices[C2] = packedColor; - vertices[C3] = packedColor; - vertices[C4] = packedColor; - } -} diff --git a/SquidSquad/DaybreakDemo/core/src/main/java/com/github/tommyettinger/DaybreakDemo.java b/SquidSquad/DaybreakDemo/core/src/main/java/com/github/tommyettinger/DaybreakDemo.java index b8c58481..5643d748 100644 --- a/SquidSquad/DaybreakDemo/core/src/main/java/com/github/tommyettinger/DaybreakDemo.java +++ b/SquidSquad/DaybreakDemo/core/src/main/java/com/github/tommyettinger/DaybreakDemo.java @@ -22,7 +22,9 @@ import com.badlogic.gdx.graphics.Colors; import com.badlogic.gdx.graphics.g2d.Animation; import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.graphics.glutils.ShaderProgram; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Align; @@ -31,6 +33,7 @@ import com.badlogic.gdx.utils.TimeUtils; import com.badlogic.gdx.utils.viewport.ScalingViewport; import com.badlogic.gdx.utils.viewport.Viewport; +import com.github.tommyettinger.digital.BitConversion; import com.github.tommyettinger.digital.TrigTools; import com.github.tommyettinger.ds.IntObjectMap; import com.github.tommyettinger.ds.ObjectDeque; @@ -41,6 +44,7 @@ import com.github.yellowstonegames.grid.*; import com.github.yellowstonegames.path.DijkstraMap; import com.github.yellowstonegames.place.DungeonProcessor; +import com.github.yellowstonegames.smooth.AnimatedGlidingSprite; import com.github.yellowstonegames.smooth.CoordGlider; import com.github.yellowstonegames.smooth.Director; import com.github.yellowstonegames.smooth.VectorSequenceGlider; @@ -57,7 +61,7 @@ public class DaybreakDemo extends ApplicationAdapter { private enum Phase {WAIT, PLAYER_ANIM, MONSTER_ANIM} - private SunBatch batch; + private SpriteBatch batch; private Phase phase = Phase.WAIT; // random number generator; this one is more efficient on GWT, but less-so on desktop. @@ -151,6 +155,8 @@ private boolean onGrid(int screenX, int screenY) { */ private static final int OKLAB_MEMORY = 0xFF808060; + public static final float NEUTRAL_PACKED = BitConversion.intBitsToFloat(0xFEFFFFFF & DescriptiveColor.WHITE); + public DaybreakDemo() { this(1L); } @@ -278,6 +284,7 @@ public void restart(long seed) { playerSprite = new AnimatedGlidingSprite(new Animation<>(DURATION, atlas.findRegions(rng.randomElement(Data.possibleCharacters)), Animation.PlayMode.LOOP), player); playerSprite.setSize(1f, 1f); + playerSprite.setPackedColor(NEUTRAL_PACKED); playerDirector = new Director<>(AnimatedGlidingSprite::getLocation, ObjectList.with(playerSprite), 150); vision.restart(linePlaceMap, player, 8); // vision.lighting.addLight(player, new Radiance(8, FullPalette.COSMIC_LATTE, 0f, 0f)); @@ -322,13 +329,63 @@ public void restart(long seed) { new String[]{",", ",", ",", " -"}, new String[]{"...\"", ", heh...\"", ", nyehehe...\"", "!\"", "!\"", "!\"", "!\" *PTOOEY!*",}, 0.2); } + /** + * Returns a new instance of an Oklab shader for GL2 when no shader is specified. + */ + public static ShaderProgram createDefaultShader () { + String vertexShader = "attribute vec4 a_position;\n" + + "attribute vec4 a_color;\n" + + "attribute vec2 a_texCoord0;\n" + + "uniform mat4 u_projTrans;\n" + + "uniform vec3 u_globalAdd;\n" + + "uniform vec3 u_globalMul;\n" + + "varying vec4 v_color;\n" + + "varying vec2 v_texCoords;\n" + + "\n" + + "void main(){\n" + + " v_color = a_color;\n" + + " v_color.r = (v_color.r - 0.5) * 0.5 * u_globalMul.r + u_globalAdd.r - 0.25;\n" + + " v_color.gb = (v_color.gb - 0.5) * u_globalMul.gb + u_globalAdd.gb;\n" + + " v_color.a = v_color.a * (255.0/254.0);\n" + + " v_texCoords = a_texCoord0;\n" + + " gl_Position = u_projTrans * a_position;\n" + + "}\n"; + String fragmentShaderOklab = + "#ifdef GL_ES\n" + + "#define LOWP lowp\n" + + "precision mediump float;\n" + + "#else\n" + + "#define LOWP \n" + + "#endif\n" + + "varying vec2 v_texCoords;\n" + + "varying LOWP vec4 v_color;\n" + + "uniform sampler2D u_texture;\n" + + "const vec3 forward = vec3(1.0 / 3.0);\n" + + "void main(){\n" + + " vec4 tgt = texture2D( u_texture, v_texCoords );\n" + + " vec3 lab = mat3(+0.2104542553, +1.9779984951, +0.0259040371, +0.7936177850, -2.4285922050, +0.7827717662, -0.0040720468, +0.4505937099, -0.8086757660) *" + + " pow(mat3(0.4121656120, 0.2118591070, 0.0883097947, 0.5362752080, 0.6807189584, 0.2818474174, 0.0514575653, 0.1074065790, 0.6302613616) \n" + + " * (tgt.rgb * tgt.rgb), forward);\n" + + " lab.x = pow(clamp(pow(lab.x, 1.5) + v_color.r, 0.0, 1.0), 0.666666);\n" + + " lab.yz = clamp(lab.yz + v_color.gb * 2.0, -1.0, 1.0);\n" + + " lab = mat3(1.0, 1.0, 1.0, +0.3963377774, -0.1055613458, -0.0894841775, +0.2158037573, -0.0638541728, -1.2914855480) * lab;\n" + + " gl_FragColor = vec4(sqrt(clamp(" + + " mat3(+4.0767245293, -1.2681437731, -0.0041119885, -3.3072168827, +2.6093323231, -0.7034763098, +0.2307590544, -0.3411344290, +1.7068625689) *\n" + + " (lab * lab * lab)," + + " 0.0, 1.0)), v_color.a * tgt.a);\n" + + "}"; + + ShaderProgram shader = new ShaderProgram(vertexShader, fragmentShaderOklab); + if (!shader.isCompiled()) throw new IllegalArgumentException("Error compiling shader: " + shader.getLog()); + return shader; + } @Override public void create() { Gdx.app.setLogLevel(Application.LOG_INFO); // We need access to a batch to render most things. - batch = new SunBatch(); + batch = new SpriteBatch(8000, createDefaultShader()); rng = new ChopRandom(seed); @@ -497,7 +554,7 @@ private void move(Coord next) { if (cg.getChange() != 0f && cg.getChange() != 1f) return; int newX = next.x, newY = next.y; - playerSprite.setPackedColor(SunBatch.NEUTRAL); + playerSprite.setPackedColor(NEUTRAL_PACKED); if (newX >= 0 && newY >= 0 && newX < placeWidth && newY < placeHeight && barePlaceMap[newX][newY] != '#') { // '+' is a door. @@ -643,7 +700,7 @@ public void putMap() { } // batch.setPackedColor(intBitsToFloat(0xFEFFFFFF)); // playerSprite.setPackedColor(intBitsToFloat(0xFEFFFFFF & vision.getForegroundColor(player.x, player.y, change))); -// batch.setPackedColor(SunBatch.NEUTRAL); +// batch.setPackedColor(NEUTRAL_PACKED); playerSprite.animate(time).draw(batch); // Gdx.graphics.setTitle(Gdx.graphics.getFramesPerSecond() + " FPS"); } diff --git a/SquidSquad/DaybreakDemo/core/src/main/java/com/github/tommyettinger/SunBatch.java b/SquidSquad/DaybreakDemo/core/src/main/java/com/github/tommyettinger/SunBatch.java deleted file mode 100644 index 9c463ad4..00000000 --- a/SquidSquad/DaybreakDemo/core/src/main/java/com/github/tommyettinger/SunBatch.java +++ /dev/null @@ -1,1140 +0,0 @@ -/******************************************************************************* - * Copyright 2011 See AUTHORS file. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package com.github.tommyettinger; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.Mesh; -import com.badlogic.gdx.graphics.Mesh.VertexDataType; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.VertexAttribute; -import com.badlogic.gdx.graphics.VertexAttributes.Usage; -import com.badlogic.gdx.graphics.g2d.Batch; -import com.badlogic.gdx.graphics.g2d.Sprite; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.graphics.glutils.ShaderProgram; -import com.badlogic.gdx.math.Affine2; -import com.badlogic.gdx.math.MathUtils; -import com.badlogic.gdx.math.Matrix4; -import com.github.tommyettinger.digital.BitConversion; -import com.github.yellowstonegames.core.DescriptiveColor; - -import java.nio.Buffer; - -import static com.github.tommyettinger.digital.BitConversion.reversedIntBitsToFloat; - -/** A variant on {@link com.badlogic.gdx.graphics.g2d.SpriteBatch} that doesn't use Color objects as much, instead - * working with packed float colors (the kind produced by {@link Color#toFloatBits()}). This also defaults to using a - * different shader; it uses Oklab for tint colors by default, and allows global color changes to be entered via two - * vec3 uniforms. - * @see Batch - * @author mzechner - * @author Nathan Sweet */ -public class SunBatch implements Batch { - /** @deprecated Do not use, this field is for testing only and is likely to be removed. Sets the {@link VertexDataType} to be - * used when gles 3 is not available, defaults to {@link VertexDataType#VertexArray}. */ - @Deprecated public static VertexDataType defaultVertexDataType = VertexDataType.VertexArray; - - private Mesh mesh; - - final float[] vertices; - int idx = 0; - Texture lastTexture = null; - float invTexWidth = 0, invTexHeight = 0; - - boolean drawing = false; - - private final Matrix4 transformMatrix = new Matrix4(); - private final Matrix4 projectionMatrix = new Matrix4(); - private final Matrix4 combinedMatrix = new Matrix4(); - - private boolean blendingDisabled = false; - private int blendSrcFunc = GL20.GL_SRC_ALPHA; - private int blendDstFunc = GL20.GL_ONE_MINUS_SRC_ALPHA; - private int blendSrcFuncAlpha = GL20.GL_SRC_ALPHA; - private int blendDstFuncAlpha = GL20.GL_ONE_MINUS_SRC_ALPHA; - - private final ShaderProgram shader; - private ShaderProgram customShader = null; - private boolean ownsShader; - - private final Color color = new Color(1f, 0.5f, 0.5f, 1); - public static final float NEUTRAL = BitConversion.intBitsToFloat(0xFEFFFFFF & DescriptiveColor.WHITE); - public float colorPacked = NEUTRAL; - - /** Number of render calls since the last {@link #begin()}. **/ - public int renderCalls = 0; - - /** Number of rendering calls, ever. Will not be reset unless set manually. **/ - public int totalRenderCalls = 0; - - /** The maximum number of sprites rendered in one batch so far. **/ - public int maxSpritesInBatch = 0; - - /** Constructs a new SunBatch with a size of 1000, one buffer, and the default shader. - * @see SunBatch#SunBatch(int, ShaderProgram) */ - public SunBatch() { - this(1000, null); - } - - /** Constructs a SunBatch with one buffer and the default shader. - * @see SunBatch#SunBatch(int, ShaderProgram) */ - public SunBatch(int size) { - this(size, null); - } - - /** Constructs a new SunBatch. Sets the projection matrix to an orthographic projection with y-axis point upwards, x-axis - * point to the right and the origin being in the bottom left corner of the screen. The projection will be pixel perfect with - * respect to the current screen resolution. - *

- * The defaultShader specifies the shader to use. Note that the names for uniforms for this default shader are different than - * the ones expect for shaders set with {@link #setShader(ShaderProgram)}. See {@link #createDefaultShader()}. - * @param size The max number of sprites in a single batch. Max of 8191. - * @param defaultShader The default shader to use. This is not owned by the SunBatch and must be disposed separately. */ - public SunBatch(int size, ShaderProgram defaultShader) { - // 32767 is max vertex index, so 32767 / 4 vertices per sprite = 8191 sprites max. - if (size > 8191) throw new IllegalArgumentException("Can't have more than 8191 sprites per batch: " + size); - - VertexDataType vertexDataType = (Gdx.gl30 != null) ? VertexDataType.VertexBufferObjectWithVAO : defaultVertexDataType; - - mesh = new Mesh(vertexDataType, false, size * 4, size * 6, - new VertexAttribute(Usage.Position, 2, ShaderProgram.POSITION_ATTRIBUTE), - new VertexAttribute(Usage.ColorPacked, 4, ShaderProgram.COLOR_ATTRIBUTE), - new VertexAttribute(Usage.TextureCoordinates, 2, ShaderProgram.TEXCOORD_ATTRIBUTE + "0")); - - projectionMatrix.setToOrtho2D(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); - - vertices = new float[size * 20]; - - int len = size * 6; - short[] indices = new short[len]; - short j = 0; - for (int i = 0; i < len; i += 6, j += 4) { - indices[i] = j; - indices[i + 1] = (short)(j + 1); - indices[i + 2] = (short)(j + 2); - indices[i + 3] = (short)(j + 2); - indices[i + 4] = (short)(j + 3); - indices[i + 5] = j; - } - mesh.setIndices(indices); - - if (defaultShader == null) { - shader = createDefaultShader(); - ownsShader = true; - } else - shader = defaultShader; - } - - /** Returns a new instance of the default shader used by SunBatch for GL2 when no shader is specified. */ - static public ShaderProgram createDefaultShader () { - String vertexShader = "attribute vec4 " + ShaderProgram.POSITION_ATTRIBUTE + ";\n" - + "attribute vec4 " + ShaderProgram.COLOR_ATTRIBUTE + ";\n" - + "attribute vec2 " + ShaderProgram.TEXCOORD_ATTRIBUTE + "0;\n" - + "uniform mat4 u_projTrans;\n" - + "uniform vec3 u_globalAdd;\n" - + "uniform vec3 u_globalMul;\n" - + "varying vec4 v_color;\n" - + "varying vec2 v_texCoords;\n" - + "\n" - + "void main()\n" - + "{\n" - + " v_color = " + ShaderProgram.COLOR_ATTRIBUTE + ";\n" - + " v_color.r = (v_color.r - 0.5) * 0.5 * u_globalMul.r + u_globalAdd.r - 0.25;\n" - + " v_color.gb = (v_color.gb - 0.5) * u_globalMul.gb + u_globalAdd.gb;\n" - + " v_color.a = v_color.a * (255.0/254.0);\n" - + " v_texCoords = " + ShaderProgram.TEXCOORD_ATTRIBUTE + "0;\n" - + " gl_Position = u_projTrans * " + ShaderProgram.POSITION_ATTRIBUTE + ";\n" - + "}\n"; - String fragmentShaderOklab = - "#ifdef GL_ES\n" + - "#define LOWP lowp\n" + - "precision mediump float;\n" + - "#else\n" + - "#define LOWP \n" + - "#endif\n" + - "varying vec2 v_texCoords;\n" + - "varying LOWP vec4 v_color;\n" + - "uniform sampler2D u_texture;\n" + - "const vec3 forward = vec3(1.0 / 3.0);\n" + - "void main()\n" + - "{\n" + - " vec4 tgt = texture2D( u_texture, v_texCoords );\n" + - " vec3 lab = mat3(+0.2104542553, +1.9779984951, +0.0259040371, +0.7936177850, -2.4285922050, +0.7827717662, -0.0040720468, +0.4505937099, -0.8086757660) *" + - " pow(mat3(0.4121656120, 0.2118591070, 0.0883097947, 0.5362752080, 0.6807189584, 0.2818474174, 0.0514575653, 0.1074065790, 0.6302613616) \n" + - " * (tgt.rgb * tgt.rgb), forward);\n" + - " lab.x = pow(clamp(pow(lab.x, 1.5) + v_color.r, 0.0, 1.0), 0.666666);\n" + - " lab.yz = clamp(lab.yz + v_color.gb * 2.0, -1.0, 1.0);\n" + - " lab = mat3(1.0, 1.0, 1.0, +0.3963377774, -0.1055613458, -0.0894841775, +0.2158037573, -0.0638541728, -1.2914855480) * lab;\n" + - " gl_FragColor = vec4(sqrt(clamp(" + - " mat3(+4.0767245293, -1.2681437731, -0.0041119885, -3.3072168827, +2.6093323231, -0.7034763098, +0.2307590544, -0.3411344290, +1.7068625689) *\n" + - " (lab * lab * lab)," + - " 0.0, 1.0)), v_color.a * tgt.a);\n" + - "}"; - - ShaderProgram shader = new ShaderProgram(vertexShader, fragmentShaderOklab); - if (!shader.isCompiled()) throw new IllegalArgumentException("Error compiling shader: " + shader.getLog()); - return shader; - } - - @Override - public void begin () { - if (drawing) throw new IllegalStateException("SunBatch.end must be called before begin."); - renderCalls = 0; - - Gdx.gl.glDepthMask(false); - if (customShader != null) - customShader.bind(); - else - shader.bind(); - setupMatrices(); - - drawing = true; - } - - @Override - public void end () { - if (!drawing) throw new IllegalStateException("SunBatch.begin must be called before end."); - if (idx > 0) flush(); - lastTexture = null; - drawing = false; - - GL20 gl = Gdx.gl; - gl.glDepthMask(true); - if (isBlendingEnabled()) gl.glDisable(GL20.GL_BLEND); - } - - @Override - public void setColor (Color tint) { - colorPacked = tint.toFloatBits(); - } - - @Override - public void setColor (float r, float g, float b, float a) { - colorPacked = Color.toFloatBits(r, g, b, a); - } - - @Override - public Color getColor () { - Color.abgr8888ToColor(color, colorPacked); - return color; - } - - @Override - public void setPackedColor (float packedColor) { - this.colorPacked = packedColor; - } - - /** - * Alpha goes in the most significant byte, and only the upper 7 bits are used. - * The others are also in reverse order compared to an ABGR7888 float. - * @param intColor Oklab or ABGR or something else with alpha as most significant - */ - public void setIntColor (int intColor) { - this.colorPacked = BitConversion.intBitsToFloat(0xFEFFFFFF & intColor); - } - - @Override - public float getPackedColor () { - return colorPacked; - } - - @Override - public void draw (Texture texture, float x, float y, float originX, float originY, float width, float height, float scaleX, - float scaleY, float rotation, int srcX, int srcY, int srcWidth, int srcHeight, boolean flipX, boolean flipY) { - if (!drawing) throw new IllegalStateException("SunBatch.begin must be called before draw."); - - float[] vertices = this.vertices; - - if (texture != lastTexture) - switchTexture(texture); - else if (idx == vertices.length) // - flush(); - - // bottom left and top right corner points relative to origin - final float worldOriginX = x + originX; - final float worldOriginY = y + originY; - float fx = -originX; - float fy = -originY; - float fx2 = width - originX; - float fy2 = height - originY; - - // scale - if (scaleX != 1 || scaleY != 1) { - fx *= scaleX; - fy *= scaleY; - fx2 *= scaleX; - fy2 *= scaleY; - } - - // construct corner points, start from top left and go counter clockwise - final float p1x = fx; - final float p1y = fy; - final float p2x = fx; - final float p2y = fy2; - final float p3x = fx2; - final float p3y = fy2; - final float p4x = fx2; - final float p4y = fy; - - float x1; - float y1; - float x2; - float y2; - float x3; - float y3; - float x4; - float y4; - - // rotate - if (rotation != 0) { - final float cos = MathUtils.cosDeg(rotation); - final float sin = MathUtils.sinDeg(rotation); - - x1 = cos * p1x - sin * p1y; - y1 = sin * p1x + cos * p1y; - - x2 = cos * p2x - sin * p2y; - y2 = sin * p2x + cos * p2y; - - x3 = cos * p3x - sin * p3y; - y3 = sin * p3x + cos * p3y; - - x4 = x1 + (x3 - x2); - y4 = y3 - (y2 - y1); - } else { - x1 = p1x; - y1 = p1y; - - x2 = p2x; - y2 = p2y; - - x3 = p3x; - y3 = p3y; - - x4 = p4x; - y4 = p4y; - } - - x1 += worldOriginX; - y1 += worldOriginY; - x2 += worldOriginX; - y2 += worldOriginY; - x3 += worldOriginX; - y3 += worldOriginY; - x4 += worldOriginX; - y4 += worldOriginY; - - float u = srcX * invTexWidth; - float v = (srcY + srcHeight) * invTexHeight; - float u2 = (srcX + srcWidth) * invTexWidth; - float v2 = srcY * invTexHeight; - - if (flipX) { - float tmp = u; - u = u2; - u2 = tmp; - } - - if (flipY) { - float tmp = v; - v = v2; - v2 = tmp; - } - - float color = this.colorPacked; - int idx = this.idx; - vertices[idx] = x1; - vertices[idx + 1] = y1; - vertices[idx + 2] = color; - vertices[idx + 3] = u; - vertices[idx + 4] = v; - - vertices[idx + 5] = x2; - vertices[idx + 6] = y2; - vertices[idx + 7] = color; - vertices[idx + 8] = u; - vertices[idx + 9] = v2; - - vertices[idx + 10] = x3; - vertices[idx + 11] = y3; - vertices[idx + 12] = color; - vertices[idx + 13] = u2; - vertices[idx + 14] = v2; - - vertices[idx + 15] = x4; - vertices[idx + 16] = y4; - vertices[idx + 17] = color; - vertices[idx + 18] = u2; - vertices[idx + 19] = v; - this.idx = idx + 20; - } - - @Override - public void draw (Texture texture, float x, float y, float width, float height, int srcX, int srcY, int srcWidth, - int srcHeight, boolean flipX, boolean flipY) { - if (!drawing) throw new IllegalStateException("SunBatch.begin must be called before draw."); - - float[] vertices = this.vertices; - - if (texture != lastTexture) - switchTexture(texture); - else if (idx == vertices.length) // - flush(); - - float u = srcX * invTexWidth; - float v = (srcY + srcHeight) * invTexHeight; - float u2 = (srcX + srcWidth) * invTexWidth; - float v2 = srcY * invTexHeight; - final float fx2 = x + width; - final float fy2 = y + height; - - if (flipX) { - float tmp = u; - u = u2; - u2 = tmp; - } - - if (flipY) { - float tmp = v; - v = v2; - v2 = tmp; - } - - float color = this.colorPacked; - int idx = this.idx; - vertices[idx] = x; - vertices[idx + 1] = y; - vertices[idx + 2] = color; - vertices[idx + 3] = u; - vertices[idx + 4] = v; - - vertices[idx + 5] = x; - vertices[idx + 6] = fy2; - vertices[idx + 7] = color; - vertices[idx + 8] = u; - vertices[idx + 9] = v2; - - vertices[idx + 10] = fx2; - vertices[idx + 11] = fy2; - vertices[idx + 12] = color; - vertices[idx + 13] = u2; - vertices[idx + 14] = v2; - - vertices[idx + 15] = fx2; - vertices[idx + 16] = y; - vertices[idx + 17] = color; - vertices[idx + 18] = u2; - vertices[idx + 19] = v; - this.idx = idx + 20; - } - - @Override - public void draw (Texture texture, float x, float y, int srcX, int srcY, int srcWidth, int srcHeight) { - if (!drawing) throw new IllegalStateException("SunBatch.begin must be called before draw."); - - float[] vertices = this.vertices; - - if (texture != lastTexture) - switchTexture(texture); - else if (idx == vertices.length) // - flush(); - - final float u = srcX * invTexWidth; - final float v = (srcY + srcHeight) * invTexHeight; - final float u2 = (srcX + srcWidth) * invTexWidth; - final float v2 = srcY * invTexHeight; - final float fx2 = x + srcWidth; - final float fy2 = y + srcHeight; - - float color = this.colorPacked; - int idx = this.idx; - vertices[idx] = x; - vertices[idx + 1] = y; - vertices[idx + 2] = color; - vertices[idx + 3] = u; - vertices[idx + 4] = v; - - vertices[idx + 5] = x; - vertices[idx + 6] = fy2; - vertices[idx + 7] = color; - vertices[idx + 8] = u; - vertices[idx + 9] = v2; - - vertices[idx + 10] = fx2; - vertices[idx + 11] = fy2; - vertices[idx + 12] = color; - vertices[idx + 13] = u2; - vertices[idx + 14] = v2; - - vertices[idx + 15] = fx2; - vertices[idx + 16] = y; - vertices[idx + 17] = color; - vertices[idx + 18] = u2; - vertices[idx + 19] = v; - this.idx = idx + 20; - } - - @Override - public void draw (Texture texture, float x, float y, float width, float height, float u, float v, float u2, float v2) { - if (!drawing) throw new IllegalStateException("SunBatch.begin must be called before draw."); - - float[] vertices = this.vertices; - - if (texture != lastTexture) - switchTexture(texture); - else if (idx == vertices.length) // - flush(); - - final float fx2 = x + width; - final float fy2 = y + height; - - float color = this.colorPacked; - int idx = this.idx; - vertices[idx] = x; - vertices[idx + 1] = y; - vertices[idx + 2] = color; - vertices[idx + 3] = u; - vertices[idx + 4] = v; - - vertices[idx + 5] = x; - vertices[idx + 6] = fy2; - vertices[idx + 7] = color; - vertices[idx + 8] = u; - vertices[idx + 9] = v2; - - vertices[idx + 10] = fx2; - vertices[idx + 11] = fy2; - vertices[idx + 12] = color; - vertices[idx + 13] = u2; - vertices[idx + 14] = v2; - - vertices[idx + 15] = fx2; - vertices[idx + 16] = y; - vertices[idx + 17] = color; - vertices[idx + 18] = u2; - vertices[idx + 19] = v; - this.idx = idx + 20; - } - - @Override - public void draw (Texture texture, float x, float y) { - draw(texture, x, y, texture.getWidth(), texture.getHeight()); - } - - @Override - public void draw (Texture texture, float x, float y, float width, float height) { - if (!drawing) throw new IllegalStateException("SunBatch.begin must be called before draw."); - - float[] vertices = this.vertices; - - if (texture != lastTexture) - switchTexture(texture); - else if (idx == vertices.length) // - flush(); - - final float fx2 = x + width; - final float fy2 = y + height; - final float u = 0; - final float v = 1; - final float u2 = 1; - final float v2 = 0; - - float color = this.colorPacked; - int idx = this.idx; - vertices[idx] = x; - vertices[idx + 1] = y; - vertices[idx + 2] = color; - vertices[idx + 3] = u; - vertices[idx + 4] = v; - - vertices[idx + 5] = x; - vertices[idx + 6] = fy2; - vertices[idx + 7] = color; - vertices[idx + 8] = u; - vertices[idx + 9] = v2; - - vertices[idx + 10] = fx2; - vertices[idx + 11] = fy2; - vertices[idx + 12] = color; - vertices[idx + 13] = u2; - vertices[idx + 14] = v2; - - vertices[idx + 15] = fx2; - vertices[idx + 16] = y; - vertices[idx + 17] = color; - vertices[idx + 18] = u2; - vertices[idx + 19] = v; - this.idx = idx + 20; - } - - @Override - public void draw (Texture texture, float[] spriteVertices, int offset, int count) { - if (!drawing) throw new IllegalStateException("SunBatch.begin must be called before draw."); - - int verticesLength = vertices.length; - int remainingVertices = verticesLength; - if (texture != lastTexture) - switchTexture(texture); - else { - remainingVertices -= idx; - if (remainingVertices == 0) { - flush(); - remainingVertices = verticesLength; - } - } - int copyCount = Math.min(remainingVertices, count); - - System.arraycopy(spriteVertices, offset, vertices, idx, copyCount); - idx += copyCount; - count -= copyCount; - while (count > 0) { - offset += copyCount; - flush(); - copyCount = Math.min(verticesLength, count); - System.arraycopy(spriteVertices, offset, vertices, 0, copyCount); - idx += copyCount; - count -= copyCount; - } - } - - @Override - public void draw (TextureRegion region, float x, float y) { - draw(region, x, y, region.getRegionWidth(), region.getRegionHeight()); - } - - @Override - public void draw (TextureRegion region, float x, float y, float width, float height) { - if (!drawing) throw new IllegalStateException("SunBatch.begin must be called before draw."); - - float[] vertices = this.vertices; - - Texture texture = region.getTexture(); - if (texture != lastTexture) { - switchTexture(texture); - } else if (idx == vertices.length) // - flush(); - - final float fx2 = x + width; - final float fy2 = y + height; - final float u = region.getU(); - final float v = region.getV2(); - final float u2 = region.getU2(); - final float v2 = region.getV(); - - float color = this.colorPacked; - int idx = this.idx; - vertices[idx] = x; - vertices[idx + 1] = y; - vertices[idx + 2] = color; - vertices[idx + 3] = u; - vertices[idx + 4] = v; - - vertices[idx + 5] = x; - vertices[idx + 6] = fy2; - vertices[idx + 7] = color; - vertices[idx + 8] = u; - vertices[idx + 9] = v2; - - vertices[idx + 10] = fx2; - vertices[idx + 11] = fy2; - vertices[idx + 12] = color; - vertices[idx + 13] = u2; - vertices[idx + 14] = v2; - - vertices[idx + 15] = fx2; - vertices[idx + 16] = y; - vertices[idx + 17] = color; - vertices[idx + 18] = u2; - vertices[idx + 19] = v; - this.idx = idx + 20; - } - - @Override - public void draw (TextureRegion region, float x, float y, float originX, float originY, float width, float height, - float scaleX, float scaleY, float rotation) { - if (!drawing) throw new IllegalStateException("SunBatch.begin must be called before draw."); - - float[] vertices = this.vertices; - - Texture texture = region.getTexture(); - if (texture != lastTexture) { - switchTexture(texture); - } else if (idx == vertices.length) // - flush(); - - // bottom left and top right corner points relative to origin - final float worldOriginX = x + originX; - final float worldOriginY = y + originY; - float fx = -originX; - float fy = -originY; - float fx2 = width - originX; - float fy2 = height - originY; - - // scale - if (scaleX != 1 || scaleY != 1) { - fx *= scaleX; - fy *= scaleY; - fx2 *= scaleX; - fy2 *= scaleY; - } - - // construct corner points, start from top left and go counter clockwise - final float p1x = fx; - final float p1y = fy; - final float p2x = fx; - final float p2y = fy2; - final float p3x = fx2; - final float p3y = fy2; - final float p4x = fx2; - final float p4y = fy; - - float x1; - float y1; - float x2; - float y2; - float x3; - float y3; - float x4; - float y4; - - // rotate - if (rotation != 0) { - final float cos = MathUtils.cosDeg(rotation); - final float sin = MathUtils.sinDeg(rotation); - - x1 = cos * p1x - sin * p1y; - y1 = sin * p1x + cos * p1y; - - x2 = cos * p2x - sin * p2y; - y2 = sin * p2x + cos * p2y; - - x3 = cos * p3x - sin * p3y; - y3 = sin * p3x + cos * p3y; - - x4 = x1 + (x3 - x2); - y4 = y3 - (y2 - y1); - } else { - x1 = p1x; - y1 = p1y; - - x2 = p2x; - y2 = p2y; - - x3 = p3x; - y3 = p3y; - - x4 = p4x; - y4 = p4y; - } - - x1 += worldOriginX; - y1 += worldOriginY; - x2 += worldOriginX; - y2 += worldOriginY; - x3 += worldOriginX; - y3 += worldOriginY; - x4 += worldOriginX; - y4 += worldOriginY; - - final float u = region.getU(); - final float v = region.getV2(); - final float u2 = region.getU2(); - final float v2 = region.getV(); - - float color = this.colorPacked; - int idx = this.idx; - vertices[idx] = x1; - vertices[idx + 1] = y1; - vertices[idx + 2] = color; - vertices[idx + 3] = u; - vertices[idx + 4] = v; - - vertices[idx + 5] = x2; - vertices[idx + 6] = y2; - vertices[idx + 7] = color; - vertices[idx + 8] = u; - vertices[idx + 9] = v2; - - vertices[idx + 10] = x3; - vertices[idx + 11] = y3; - vertices[idx + 12] = color; - vertices[idx + 13] = u2; - vertices[idx + 14] = v2; - - vertices[idx + 15] = x4; - vertices[idx + 16] = y4; - vertices[idx + 17] = color; - vertices[idx + 18] = u2; - vertices[idx + 19] = v; - this.idx = idx + 20; - } - - @Override - public void draw (TextureRegion region, float x, float y, float originX, float originY, float width, float height, - float scaleX, float scaleY, float rotation, boolean clockwise) { - if (!drawing) throw new IllegalStateException("SunBatch.begin must be called before draw."); - - float[] vertices = this.vertices; - - Texture texture = region.getTexture(); - if (texture != lastTexture) { - switchTexture(texture); - } else if (idx == vertices.length) // - flush(); - - // bottom left and top right corner points relative to origin - final float worldOriginX = x + originX; - final float worldOriginY = y + originY; - float fx = -originX; - float fy = -originY; - float fx2 = width - originX; - float fy2 = height - originY; - - // scale - if (scaleX != 1 || scaleY != 1) { - fx *= scaleX; - fy *= scaleY; - fx2 *= scaleX; - fy2 *= scaleY; - } - - // construct corner points, start from top left and go counter clockwise - final float p1x = fx; - final float p1y = fy; - final float p2x = fx; - final float p2y = fy2; - final float p3x = fx2; - final float p3y = fy2; - final float p4x = fx2; - final float p4y = fy; - - float x1; - float y1; - float x2; - float y2; - float x3; - float y3; - float x4; - float y4; - - // rotate - if (rotation != 0) { - final float cos = MathUtils.cosDeg(rotation); - final float sin = MathUtils.sinDeg(rotation); - - x1 = cos * p1x - sin * p1y; - y1 = sin * p1x + cos * p1y; - - x2 = cos * p2x - sin * p2y; - y2 = sin * p2x + cos * p2y; - - x3 = cos * p3x - sin * p3y; - y3 = sin * p3x + cos * p3y; - - x4 = x1 + (x3 - x2); - y4 = y3 - (y2 - y1); - } else { - x1 = p1x; - y1 = p1y; - - x2 = p2x; - y2 = p2y; - - x3 = p3x; - y3 = p3y; - - x4 = p4x; - y4 = p4y; - } - - x1 += worldOriginX; - y1 += worldOriginY; - x2 += worldOriginX; - y2 += worldOriginY; - x3 += worldOriginX; - y3 += worldOriginY; - x4 += worldOriginX; - y4 += worldOriginY; - - float u1, v1, u2, v2, u3, v3, u4, v4; - if (clockwise) { - u1 = region.getU2(); - v1 = region.getV2(); - u2 = region.getU(); - v2 = region.getV2(); - u3 = region.getU(); - v3 = region.getV(); - u4 = region.getU2(); - v4 = region.getV(); - } else { - u1 = region.getU(); - v1 = region.getV(); - u2 = region.getU2(); - v2 = region.getV(); - u3 = region.getU2(); - v3 = region.getV2(); - u4 = region.getU(); - v4 = region.getV2(); - } - - float color = this.colorPacked; - int idx = this.idx; - vertices[idx] = x1; - vertices[idx + 1] = y1; - vertices[idx + 2] = color; - vertices[idx + 3] = u1; - vertices[idx + 4] = v1; - - vertices[idx + 5] = x2; - vertices[idx + 6] = y2; - vertices[idx + 7] = color; - vertices[idx + 8] = u2; - vertices[idx + 9] = v2; - - vertices[idx + 10] = x3; - vertices[idx + 11] = y3; - vertices[idx + 12] = color; - vertices[idx + 13] = u3; - vertices[idx + 14] = v3; - - vertices[idx + 15] = x4; - vertices[idx + 16] = y4; - vertices[idx + 17] = color; - vertices[idx + 18] = u4; - vertices[idx + 19] = v4; - this.idx = idx + 20; - } - - @Override - public void draw (TextureRegion region, float width, float height, Affine2 transform) { - if (!drawing) throw new IllegalStateException("SunBatch.begin must be called before draw."); - - float[] vertices = this.vertices; - - Texture texture = region.getTexture(); - if (texture != lastTexture) { - switchTexture(texture); - } else if (idx == vertices.length) { - flush(); - } - - // construct corner points - float x1 = transform.m02; - float y1 = transform.m12; - float x2 = transform.m01 * height + transform.m02; - float y2 = transform.m11 * height + transform.m12; - float x3 = transform.m00 * width + transform.m01 * height + transform.m02; - float y3 = transform.m10 * width + transform.m11 * height + transform.m12; - float x4 = transform.m00 * width + transform.m02; - float y4 = transform.m10 * width + transform.m12; - - float u = region.getU(); - float v = region.getV2(); - float u2 = region.getU2(); - float v2 = region.getV(); - - float color = this.colorPacked; - int idx = this.idx; - vertices[idx] = x1; - vertices[idx + 1] = y1; - vertices[idx + 2] = color; - vertices[idx + 3] = u; - vertices[idx + 4] = v; - - vertices[idx + 5] = x2; - vertices[idx + 6] = y2; - vertices[idx + 7] = color; - vertices[idx + 8] = u; - vertices[idx + 9] = v2; - - vertices[idx + 10] = x3; - vertices[idx + 11] = y3; - vertices[idx + 12] = color; - vertices[idx + 13] = u2; - vertices[idx + 14] = v2; - - vertices[idx + 15] = x4; - vertices[idx + 16] = y4; - vertices[idx + 17] = color; - vertices[idx + 18] = u2; - vertices[idx + 19] = v; - this.idx = idx + 20; - } - - @Override - public void flush () { - if (idx == 0) return; - - renderCalls++; - totalRenderCalls++; - int spritesInBatch = idx / 20; - if (spritesInBatch > maxSpritesInBatch) maxSpritesInBatch = spritesInBatch; - int count = spritesInBatch * 6; - - lastTexture.bind(); - Mesh mesh = this.mesh; - mesh.setVertices(vertices, 0, idx); - Buffer indicesBuffer = (Buffer)mesh.getIndicesBuffer(true); - indicesBuffer.position(0); - indicesBuffer.limit(count); - - if (blendingDisabled) { - Gdx.gl.glDisable(GL20.GL_BLEND); - } else { - Gdx.gl.glEnable(GL20.GL_BLEND); - if (blendSrcFunc != -1) Gdx.gl.glBlendFuncSeparate(blendSrcFunc, blendDstFunc, blendSrcFuncAlpha, blendDstFuncAlpha); - } - - mesh.render(customShader != null ? customShader : shader, GL20.GL_TRIANGLES, 0, count); - - idx = 0; - } - - @Override - public void disableBlending () { - if (blendingDisabled) return; - flush(); - blendingDisabled = true; - } - - @Override - public void enableBlending () { - if (!blendingDisabled) return; - flush(); - blendingDisabled = false; - } - - @Override - public void setBlendFunction (int srcFunc, int dstFunc) { - setBlendFunctionSeparate(srcFunc, dstFunc, srcFunc, dstFunc); - } - - @Override - public void setBlendFunctionSeparate (int srcFuncColor, int dstFuncColor, int srcFuncAlpha, int dstFuncAlpha) { - if (blendSrcFunc == srcFuncColor && blendDstFunc == dstFuncColor && blendSrcFuncAlpha == srcFuncAlpha - && blendDstFuncAlpha == dstFuncAlpha) return; - flush(); - blendSrcFunc = srcFuncColor; - blendDstFunc = dstFuncColor; - blendSrcFuncAlpha = srcFuncAlpha; - blendDstFuncAlpha = dstFuncAlpha; - } - - @Override - public int getBlendSrcFunc () { - return blendSrcFunc; - } - - @Override - public int getBlendDstFunc () { - return blendDstFunc; - } - - @Override - public int getBlendSrcFuncAlpha () { - return blendSrcFuncAlpha; - } - - @Override - public int getBlendDstFuncAlpha () { - return blendDstFuncAlpha; - } - - @Override - public void dispose () { - mesh.dispose(); - if (ownsShader && shader != null) shader.dispose(); - } - - @Override - public Matrix4 getProjectionMatrix () { - return projectionMatrix; - } - - @Override - public Matrix4 getTransformMatrix () { - return transformMatrix; - } - - @Override - public void setProjectionMatrix (Matrix4 projection) { - if (drawing) flush(); - projectionMatrix.set(projection); - if (drawing) setupMatrices(); - } - - @Override - public void setTransformMatrix (Matrix4 transform) { - if (drawing) flush(); - transformMatrix.set(transform); - if (drawing) setupMatrices(); - } - - protected void setupMatrices () { - combinedMatrix.set(projectionMatrix).mul(transformMatrix); - if (customShader != null) { - customShader.setUniformMatrix("u_projTrans", combinedMatrix); - customShader.setUniformi("u_texture", 0); - } else { - shader.setUniformMatrix("u_projTrans", combinedMatrix); - shader.setUniformi("u_texture", 0); - } - } - - protected void switchTexture (Texture texture) { - flush(); - lastTexture = texture; - invTexWidth = 1.0f / texture.getWidth(); - invTexHeight = 1.0f / texture.getHeight(); - } - - @Override - public void setShader (ShaderProgram shader) { - if (shader == customShader) // avoid unnecessary flushing in case we are drawing - return; - if (drawing) { - flush(); - } - customShader = shader; - if (drawing) { - if (customShader != null) - customShader.bind(); - else - this.shader.bind(); - setupMatrices(); - } - } - - @Override - public ShaderProgram getShader () { - if (customShader == null) { - return shader; - } - return customShader; - } - - @Override - public boolean isBlendingEnabled () { - return !blendingDisabled; - } - - public boolean isDrawing () { - return drawing; - } -}