Better parenthesis button behavior
This commit is contained in:
parent
b57ae900e5
commit
bd5260e0f3
@ -639,7 +639,7 @@ public class Keyboard {
|
||||
{ "", null, null } /* 1,7 */
|
||||
}, { /* ROW 2 */
|
||||
{ "", null, null }, /* 2,0 */
|
||||
{ "√", null, null }, /* 2,1 */
|
||||
{ "√▯", null, null }, /* 2,1 */
|
||||
{ "", null, null }, /* 2,2 */
|
||||
{ "⇩", null, null }, /* 2,3 */
|
||||
{ "↶", null, null }, /* 2,4 */
|
||||
@ -649,8 +649,8 @@ public class Keyboard {
|
||||
}, { /* ROW 3 */
|
||||
{ "", null, null }, /* 3,0 */
|
||||
{ "", null, null }, /* 3,1 */
|
||||
{ "^x", null, null }, /* 3,2 */
|
||||
{ "^2", null, null }, /* 3,3 */
|
||||
{ "▯^▯", null, null }, /* 3,2 */
|
||||
{ "▯^2", null, null }, /* 3,3 */
|
||||
{ "", null, null }, /* 3,4 */
|
||||
{ "", null, null }, /* 3,5 */
|
||||
{ "", null, null }, /* 3,6 */
|
||||
@ -658,7 +658,7 @@ public class Keyboard {
|
||||
}, { /* ROW 4 */
|
||||
{ "", null, null }, /* 4,0 */
|
||||
{ "", null, null }, /* 4,1 */
|
||||
{ "(", null, null }, /* 4,2 */
|
||||
{ "(▯)", null, null }, /* 4,2 */
|
||||
{ ")", null, null }, /* 4,3 */
|
||||
{ "", null, null }, /* 4,4 */
|
||||
{ "S⇔D", null, null }, /* 4,5 */
|
||||
|
@ -9,12 +9,13 @@ import it.cavallium.warppi.math.MathContext;
|
||||
import it.cavallium.warppi.math.parser.features.interfaces.Feature;
|
||||
import it.cavallium.warppi.util.Error;
|
||||
|
||||
public abstract class Block implements GraphicalElement {
|
||||
public abstract class Block implements TreeBlock, GraphicalElement {
|
||||
|
||||
protected boolean small;
|
||||
protected int width;
|
||||
protected int height;
|
||||
protected int line;
|
||||
protected TreeContainer parent;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -69,4 +70,18 @@ public abstract class Block implements GraphicalElement {
|
||||
}
|
||||
|
||||
public abstract Feature toFeature(MathContext context) throws Error;
|
||||
|
||||
@Override
|
||||
public TreeContainer getParentContainer() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasParent() {
|
||||
return parent != null;
|
||||
}
|
||||
|
||||
public void setParent(TreeContainer parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import it.cavallium.warppi.util.Error;
|
||||
import it.cavallium.warppi.util.Errors;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
|
||||
public class BlockContainer implements GraphicalElement {
|
||||
public class BlockContainer implements TreeContainer, GraphicalElement {
|
||||
|
||||
private static boolean initialized = false;
|
||||
|
||||
@ -28,33 +28,35 @@ public class BlockContainer implements GraphicalElement {
|
||||
private int line;
|
||||
public final boolean withBorder;
|
||||
private boolean autoMinimums;
|
||||
private TreeBlock parent;
|
||||
|
||||
public BlockContainer() {
|
||||
this(false, BlockContainer.getDefaultCharWidth(false), BlockContainer.getDefaultCharHeight(false), true);
|
||||
public BlockContainer(TreeBlock parent) {
|
||||
this(parent, false, BlockContainer.getDefaultCharWidth(false), BlockContainer.getDefaultCharHeight(false), true);
|
||||
autoMinimums = true;
|
||||
}
|
||||
|
||||
public BlockContainer(final boolean small) {
|
||||
this(small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), true);
|
||||
public BlockContainer(TreeBlock parent, final boolean small) {
|
||||
this(parent, small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), true);
|
||||
autoMinimums = true;
|
||||
}
|
||||
|
||||
public BlockContainer(final boolean small, final ObjectArrayList<Block> content) {
|
||||
this(small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), content, true);
|
||||
public BlockContainer(TreeBlock parent, final boolean small, final ObjectArrayList<Block> content) {
|
||||
this(parent, small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), content, true);
|
||||
autoMinimums = true;
|
||||
}
|
||||
|
||||
public BlockContainer(final boolean small, final boolean withBorder) {
|
||||
this(small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), withBorder);
|
||||
public BlockContainer(TreeBlock parent, final boolean small, final boolean withBorder) {
|
||||
this(parent, small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), withBorder);
|
||||
autoMinimums = true;
|
||||
}
|
||||
|
||||
public BlockContainer(final boolean small, final int minWidth, final int minHeight, final boolean withBorder) {
|
||||
this(small, minWidth, minHeight, new ObjectArrayList<>(), withBorder);
|
||||
public BlockContainer(TreeBlock parent, final boolean small, final int minWidth, final int minHeight, final boolean withBorder) {
|
||||
this(parent, small, minWidth, minHeight, new ObjectArrayList<>(), withBorder);
|
||||
autoMinimums = false;
|
||||
}
|
||||
|
||||
public BlockContainer(final boolean small, final int minWidth, final int minHeight, final ObjectArrayList<Block> content, final boolean withBorder) {
|
||||
public BlockContainer(TreeBlock parent, final boolean small, final int minWidth, final int minHeight, final ObjectArrayList<Block> content, final boolean withBorder) {
|
||||
this.parent = parent;
|
||||
this.small = small;
|
||||
this.minWidth = minWidth;
|
||||
this.minHeight = minHeight;
|
||||
@ -65,6 +67,16 @@ public class BlockContainer implements GraphicalElement {
|
||||
this.content = content;
|
||||
recomputeDimensions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TreeBlock getParentBlock() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasParent() {
|
||||
return parent != null;
|
||||
}
|
||||
|
||||
public void addBlock(final int position, final Block b) {
|
||||
addBlockUnsafe(position, b);
|
||||
@ -72,6 +84,7 @@ public class BlockContainer implements GraphicalElement {
|
||||
}
|
||||
|
||||
public void addBlockUnsafe(final int position, final Block b) {
|
||||
b.setParent(this);
|
||||
if (b.isSmall() != small)
|
||||
b.setSmall(small);
|
||||
if (position >= content.size())
|
||||
@ -86,6 +99,7 @@ public class BlockContainer implements GraphicalElement {
|
||||
}
|
||||
|
||||
public void appendBlockUnsafe(final Block b) {
|
||||
b.setParent(this);
|
||||
if (b.isSmall() != small)
|
||||
b.setSmall(small);
|
||||
content.add(b);
|
||||
@ -97,11 +111,12 @@ public class BlockContainer implements GraphicalElement {
|
||||
}
|
||||
|
||||
public void removeBlockUnsafe(final Block b) {
|
||||
b.setParent(null);
|
||||
content.remove(b);
|
||||
}
|
||||
|
||||
public void removeAt(final int i) {
|
||||
content.remove(i);
|
||||
content.remove(i).setParent(null);
|
||||
recomputeDimensions();
|
||||
}
|
||||
|
||||
|
@ -19,8 +19,8 @@ public class BlockDivision extends Block {
|
||||
private int h1;
|
||||
|
||||
public BlockDivision() {
|
||||
containerUp = new BlockContainer(false);
|
||||
containerDown = new BlockContainer(false);
|
||||
containerUp = new BlockContainer(this, false);
|
||||
containerDown = new BlockContainer(this, false);
|
||||
recomputeDimensions();
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ import it.cavallium.warppi.math.parser.features.interfaces.Feature;
|
||||
import it.cavallium.warppi.util.Error;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
|
||||
public class BlockLogarithm extends Block {
|
||||
public class BlockLogarithm extends Block implements IParenthesis {
|
||||
|
||||
private final BlockContainer containerBase;
|
||||
private final BlockContainer containerNumber;
|
||||
@ -28,14 +28,14 @@ public class BlockLogarithm extends Block {
|
||||
private int toph;
|
||||
|
||||
public BlockLogarithm() {
|
||||
containerBase = new BlockContainer(true);
|
||||
containerNumber = new BlockContainer(false);
|
||||
containerBase = new BlockContainer(this, true);
|
||||
containerNumber = new BlockContainer(this, false);
|
||||
recomputeDimensions();
|
||||
}
|
||||
|
||||
public BlockLogarithm(final ObjectArrayList<Block> blocks) {
|
||||
containerBase = new BlockContainer(true);
|
||||
containerNumber = new BlockContainer(false, blocks);
|
||||
containerBase = new BlockContainer(this, true);
|
||||
containerNumber = new BlockContainer(this, false, blocks);
|
||||
recomputeDimensions();
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,6 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
|
||||
public class BlockParenthesis extends BlockParenthesisAbstract {
|
||||
public BlockParenthesis() {
|
||||
super();
|
||||
}
|
||||
|
||||
public BlockParenthesis(final ObjectArrayList<Block> blocks) {
|
||||
|
@ -8,7 +8,7 @@ import it.cavallium.warppi.math.parser.features.interfaces.Feature;
|
||||
import it.cavallium.warppi.util.Error;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
|
||||
public abstract class BlockParenthesisAbstract extends Block {
|
||||
public abstract class BlockParenthesisAbstract extends Block implements IParenthesis {
|
||||
|
||||
private final BlockContainer containerNumber;
|
||||
|
||||
@ -18,20 +18,20 @@ public abstract class BlockParenthesisAbstract extends Block {
|
||||
private int chh;
|
||||
|
||||
protected BlockParenthesisAbstract(final String prefix) {
|
||||
containerNumber = new BlockContainer(false);
|
||||
containerNumber = new BlockContainer(this, false);
|
||||
this.prefix = prefix;
|
||||
|
||||
recomputeDimensions();
|
||||
}
|
||||
|
||||
public BlockParenthesisAbstract() {
|
||||
containerNumber = new BlockContainer(false);
|
||||
containerNumber = new BlockContainer(this, false);
|
||||
prefix = null;
|
||||
recomputeDimensions();
|
||||
}
|
||||
|
||||
public BlockParenthesisAbstract(final ObjectArrayList<Block> blocks) {
|
||||
containerNumber = new BlockContainer(false, blocks);
|
||||
containerNumber = new BlockContainer(this, false, blocks);
|
||||
prefix = null;
|
||||
recomputeDimensions();
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ public class BlockPower extends Block {
|
||||
private final BlockContainer containerExponent;
|
||||
|
||||
public BlockPower() {
|
||||
containerExponent = new BlockContainer(true);
|
||||
containerExponent = new BlockContainer(this, true);
|
||||
recomputeDimensions();
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ public class BlockPower2 extends Block {
|
||||
private final BlockContainer containerExponent;
|
||||
|
||||
public BlockPower2() {
|
||||
containerExponent = new BlockContainer(true);
|
||||
containerExponent = new BlockContainer(this, true);
|
||||
containerExponent.addBlock(0, new BlockNumericChar('2'));
|
||||
recomputeDimensions();
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public class BlockSquareRoot extends Block {
|
||||
private int h1;
|
||||
|
||||
public BlockSquareRoot() {
|
||||
containerNumber = new BlockContainer(false);
|
||||
containerNumber = new BlockContainer(this, false);
|
||||
recomputeDimensions();
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,5 @@
|
||||
package it.cavallium.warppi.gui.expression.blocks;
|
||||
|
||||
public interface IParenthesis {
|
||||
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package it.cavallium.warppi.gui.expression.blocks;
|
||||
|
||||
public interface TreeBlock {
|
||||
public TreeContainer getParentContainer();
|
||||
public boolean hasParent();
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package it.cavallium.warppi.gui.expression.blocks;
|
||||
|
||||
public interface TreeContainer {
|
||||
public TreeBlock getParentBlock();
|
||||
public boolean hasParent();
|
||||
}
|
@ -1,8 +1,15 @@
|
||||
package it.cavallium.warppi.gui.expression.containers;
|
||||
|
||||
import it.cavallium.warppi.gui.expression.Caret;
|
||||
import it.cavallium.warppi.gui.expression.InputContext;
|
||||
import it.cavallium.warppi.gui.expression.blocks.Block;
|
||||
import it.cavallium.warppi.gui.expression.blocks.BlockChar;
|
||||
import it.cavallium.warppi.gui.expression.blocks.BlockReference;
|
||||
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
|
||||
import it.cavallium.warppi.gui.graphicengine.Renderer;
|
||||
import it.cavallium.warppi.math.MathContext;
|
||||
import it.cavallium.warppi.math.parser.features.interfaces.Feature;
|
||||
import it.cavallium.warppi.util.Error;
|
||||
|
||||
public class InlineInputContainer extends InputContainer {
|
||||
|
||||
|
@ -11,6 +11,8 @@ import it.cavallium.warppi.gui.expression.InputContext;
|
||||
import it.cavallium.warppi.gui.expression.blocks.Block;
|
||||
import it.cavallium.warppi.gui.expression.blocks.BlockContainer;
|
||||
import it.cavallium.warppi.gui.expression.blocks.BlockReference;
|
||||
import it.cavallium.warppi.gui.expression.blocks.TreeContainer;
|
||||
import it.cavallium.warppi.gui.expression.blocks.TreeBlock;
|
||||
import it.cavallium.warppi.gui.expression.layouts.InputLayout;
|
||||
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
|
||||
import it.cavallium.warppi.gui.graphicengine.Renderer;
|
||||
@ -21,8 +23,8 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
|
||||
public abstract class InputContainer implements GraphicalElement, InputLayout, Serializable {
|
||||
private static final long serialVersionUID = 923589369317765667L;
|
||||
private final BlockContainer root;
|
||||
private Caret caret;
|
||||
protected final BlockContainer root;
|
||||
protected Caret caret;
|
||||
private static final float CARET_DURATION = 0.5f;
|
||||
private float caretTime;
|
||||
private int maxPosition = 0;
|
||||
@ -53,7 +55,7 @@ public abstract class InputContainer implements GraphicalElement, InputLayout, S
|
||||
public InputContainer(final InputContext ic, final boolean small, final int minWidth, final int minHeight) {
|
||||
inputContext = ic;
|
||||
caret = new Caret(CaretState.VISIBLE_ON, 0);
|
||||
root = new BlockContainer(small, false);
|
||||
root = new BlockContainer(null, small, false);
|
||||
}
|
||||
|
||||
public void typeChar(final char c) {
|
||||
@ -69,10 +71,10 @@ public abstract class InputContainer implements GraphicalElement, InputLayout, S
|
||||
maxPosition = root.computeCaretMaxBound();
|
||||
root.recomputeDimensions();
|
||||
}
|
||||
closeExtra();
|
||||
}
|
||||
caretTime = 0;
|
||||
caret.turnOn();
|
||||
closeExtra();
|
||||
}
|
||||
|
||||
public void typeChar(final String c) {
|
||||
@ -98,6 +100,11 @@ public abstract class InputContainer implements GraphicalElement, InputLayout, S
|
||||
return selectedBlock;
|
||||
}
|
||||
|
||||
public BlockReference<?> getBlockAtCaretPosition(int i) {
|
||||
final BlockReference<?> selectedBlock = root.getBlock(new Caret(CaretState.HIDDEN, i));
|
||||
return selectedBlock;
|
||||
}
|
||||
|
||||
public void moveLeft() {
|
||||
final int curPos = caret.getPosition();
|
||||
if (curPos > 0)
|
||||
@ -109,10 +116,10 @@ public abstract class InputContainer implements GraphicalElement, InputLayout, S
|
||||
closeExtra();
|
||||
}
|
||||
|
||||
public void moveRight() {
|
||||
public void moveRight(int delta) {
|
||||
final int curPos = caret.getPosition();
|
||||
if (curPos + 1 < maxPosition)
|
||||
caret.setPosition(curPos + 1);
|
||||
if (curPos + delta < maxPosition)
|
||||
caret.setPosition(curPos + delta);
|
||||
else
|
||||
caret.setPosition(0);
|
||||
caret.turnOn();
|
||||
@ -120,6 +127,20 @@ public abstract class InputContainer implements GraphicalElement, InputLayout, S
|
||||
closeExtra();
|
||||
}
|
||||
|
||||
public void moveTo(int position) {
|
||||
if (position < maxPosition)
|
||||
caret.setPosition(position);
|
||||
else
|
||||
caret.setPosition(0);
|
||||
caret.turnOn();
|
||||
caretTime = 0;
|
||||
closeExtra();
|
||||
}
|
||||
|
||||
public void moveRight() {
|
||||
moveRight(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recomputeDimensions() {
|
||||
root.recomputeDimensions();
|
||||
|
@ -1,5 +1,7 @@
|
||||
package it.cavallium.warppi.gui.expression.containers;
|
||||
|
||||
import it.cavallium.warppi.gui.expression.Caret;
|
||||
import it.cavallium.warppi.gui.expression.CaretState;
|
||||
import it.cavallium.warppi.gui.expression.InputContext;
|
||||
import it.cavallium.warppi.gui.expression.blocks.Block;
|
||||
import it.cavallium.warppi.gui.expression.blocks.BlockChar;
|
||||
@ -8,12 +10,16 @@ import it.cavallium.warppi.gui.expression.blocks.BlockDivision;
|
||||
import it.cavallium.warppi.gui.expression.blocks.BlockLogarithm;
|
||||
import it.cavallium.warppi.gui.expression.blocks.BlockNumericChar;
|
||||
import it.cavallium.warppi.gui.expression.blocks.BlockParenthesis;
|
||||
import it.cavallium.warppi.gui.expression.blocks.BlockParenthesisAbstract;
|
||||
import it.cavallium.warppi.gui.expression.blocks.BlockPower;
|
||||
import it.cavallium.warppi.gui.expression.blocks.BlockPower2;
|
||||
import it.cavallium.warppi.gui.expression.blocks.BlockReference;
|
||||
import it.cavallium.warppi.gui.expression.blocks.BlockSine;
|
||||
import it.cavallium.warppi.gui.expression.blocks.BlockSquareRoot;
|
||||
import it.cavallium.warppi.gui.expression.blocks.BlockVariable;
|
||||
import it.cavallium.warppi.gui.expression.blocks.IParenthesis;
|
||||
import it.cavallium.warppi.gui.expression.blocks.TreeBlock;
|
||||
import it.cavallium.warppi.gui.expression.blocks.TreeContainer;
|
||||
import it.cavallium.warppi.math.MathematicalSymbols;
|
||||
|
||||
public class NormalInputContainer extends InputContainer {
|
||||
@ -92,9 +98,33 @@ public class NormalInputContainer extends InputContainer {
|
||||
public void typeChar(final char c) {
|
||||
super.typeChar(c);
|
||||
switch (c) {
|
||||
case MathematicalSymbols.PARENTHESIS_CLOSE:
|
||||
moveRight();
|
||||
case MathematicalSymbols.DIVISION:
|
||||
case MathematicalSymbols.PARENTHESIS_CLOSE: {
|
||||
BlockReference<?> ref = getSelectedBlock();
|
||||
if (ref == null) {
|
||||
break;
|
||||
} else {
|
||||
Caret newCaret = new Caret(CaretState.HIDDEN, caret.getPosition());
|
||||
BlockContainer currentContainer;
|
||||
BlockReference<?> newRef = ref;
|
||||
int safeExit = 0;
|
||||
do {
|
||||
currentContainer = (BlockContainer) newRef.get().getParentContainer();
|
||||
int initialRelativeIndex = currentContainer.getContent().indexOf(newRef.get());
|
||||
int newIndex = newCaret.getPosition() + (currentContainer.getContent().size() - initialRelativeIndex);
|
||||
newRef = getBlockAtCaretPosition(newIndex);
|
||||
newCaret.setPosition(newIndex);
|
||||
safeExit++;
|
||||
} while (newRef != null && newRef.get() instanceof IParenthesis == false && currentContainer != null && safeExit < 100000);
|
||||
if (safeExit >= 100000) {
|
||||
System.err.println("Error 0x001030: Infinite loop");
|
||||
}
|
||||
if (newRef != null) {
|
||||
moveTo(newCaret.getPosition());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MathematicalSymbols.DIVISION: {
|
||||
@SuppressWarnings("unchecked")
|
||||
final BlockReference<BlockDivision> ref = (BlockReference<BlockDivision>) getSelectedBlock();
|
||||
@SuppressWarnings("unused")
|
||||
@ -128,7 +158,8 @@ public class NormalInputContainer extends InputContainer {
|
||||
moveRight();
|
||||
moveRight();// Move to the divisor
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,22 +19,22 @@ public abstract class OutputContainer implements GraphicalElement, OutputLayout,
|
||||
|
||||
public OutputContainer() {
|
||||
roots = new ObjectArrayList<>();
|
||||
roots.add(new BlockContainer());
|
||||
roots.add(new BlockContainer(null));
|
||||
}
|
||||
|
||||
public OutputContainer(final boolean small) {
|
||||
roots = new ObjectArrayList<>();
|
||||
roots.add(new BlockContainer(small));
|
||||
roots.add(new BlockContainer(null, small));
|
||||
}
|
||||
|
||||
public OutputContainer(final boolean small, final int minWidth, final int minHeight) {
|
||||
roots = new ObjectArrayList<>();
|
||||
roots.add(new BlockContainer(small));
|
||||
roots.add(new BlockContainer(null, small));
|
||||
}
|
||||
|
||||
public void setContentAsSingleGroup(final ObjectArrayList<Block> blocks) {
|
||||
roots.clear();
|
||||
final BlockContainer bcnt = new BlockContainer();
|
||||
final BlockContainer bcnt = new BlockContainer(null);
|
||||
for (final Block block : blocks)
|
||||
bcnt.appendBlockUnsafe(block);
|
||||
roots.add(bcnt);
|
||||
@ -44,7 +44,7 @@ public abstract class OutputContainer implements GraphicalElement, OutputLayout,
|
||||
public void setContentAsMultipleGroups(final ObjectArrayList<ObjectArrayList<Block>> roots) {
|
||||
this.roots.clear();
|
||||
for (final ObjectArrayList<Block> blocks : roots) {
|
||||
final BlockContainer bcnt = new BlockContainer();
|
||||
final BlockContainer bcnt = new BlockContainer(null);
|
||||
for (final Block block : blocks)
|
||||
bcnt.appendBlockUnsafe(block);
|
||||
this.roots.add(bcnt);
|
||||
@ -55,7 +55,7 @@ public abstract class OutputContainer implements GraphicalElement, OutputLayout,
|
||||
public void setContentAsMultipleElements(final ObjectArrayList<Block> elems) {
|
||||
roots.clear();
|
||||
for (final Block block : elems) {
|
||||
final BlockContainer bcnt = new BlockContainer();
|
||||
final BlockContainer bcnt = new BlockContainer(null);
|
||||
bcnt.appendBlockUnsafe(block);
|
||||
roots.add(bcnt);
|
||||
}
|
||||
@ -125,7 +125,7 @@ public abstract class OutputContainer implements GraphicalElement, OutputLayout,
|
||||
|
||||
public void clear() {
|
||||
roots.clear();
|
||||
roots.add(new BlockContainer());
|
||||
roots.add(new BlockContainer(null));
|
||||
recomputeDimensions();
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,7 @@ public class Utils {
|
||||
|
||||
public static final int scaleMode = BigDecimal.ROUND_HALF_UP;
|
||||
public static final RoundingMode scaleMode2 = RoundingMode.HALF_UP;
|
||||
public static final int maxAutoFractionDigits = 5;
|
||||
|
||||
public static boolean newtMode = true;
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -5,6 +5,7 @@
|
||||
package it.cavallium.warppi.gui.graphicengine.impl.swing;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
@ -26,6 +27,8 @@ public class SwingAdvancedButton extends JButton {
|
||||
public boolean drawColor = false;
|
||||
public boolean drawDefaultComponent = false;
|
||||
public int state;
|
||||
protected boolean hover;
|
||||
public Color basicForeground;
|
||||
|
||||
public SwingAdvancedButton() {
|
||||
setOpaque(false);
|
||||
@ -69,10 +72,14 @@ public class SwingAdvancedButton extends JButton {
|
||||
final AlphaComposite acomp = AlphaComposite.getInstance(3, 1.0f);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
|
||||
g2d.setComposite(acomp);
|
||||
g2d.drawImage(backgroundImage, 0, (int) backgroundSize.getHeight() * -state, (int) backgroundSize.getWidth(), (int) (backgroundSize.getHeight() * 3), null);
|
||||
g2d.drawImage(backgroundImage, 0, (int) backgroundSize.getHeight() * -(hover ? state+1 : state), (int) backgroundSize.getWidth(), (int) (backgroundSize.getHeight() * 4), null);
|
||||
g2d.setFont(g.getFont());
|
||||
g2d.setColor(super.getForeground());
|
||||
g2d.drawString(getText(), super.getWidth() / 2 - g.getFontMetrics().stringWidth(getText()) / 2, super.getHeight() / 2 + g.getFontMetrics().getHeight() / 4);
|
||||
int y = super.getHeight() / 2 + g.getFontMetrics().getHeight() / 4;
|
||||
if (state == 2) {
|
||||
y += 8;
|
||||
}
|
||||
g2d.drawString(getText(), super.getWidth() / 2 - g.getFontMetrics().stringWidth(getText()) / 2, y);
|
||||
g2d.dispose();
|
||||
}
|
||||
if (drawDefaultComponent)
|
||||
@ -102,4 +109,9 @@ public class SwingAdvancedButton extends JButton {
|
||||
public boolean getCanClick() {
|
||||
return canclick;
|
||||
}
|
||||
|
||||
public void setBasicForeground(Color color) {
|
||||
basicForeground = color;
|
||||
super.setForeground(basicForeground);
|
||||
}
|
||||
}
|
||||
|
@ -203,12 +203,16 @@ public class SwingWindow extends JFrame {
|
||||
buttonsPanel = new JPanel();
|
||||
buttonsPanelContainer.add(buttonsPanel, BorderLayout.CENTER);
|
||||
buttonsPanel.setLayout(new GridLayout(9, 7));
|
||||
buttonsPanel.setBackground(Color.GRAY);
|
||||
buttonsPanel.setBackground(Color.BLACK);
|
||||
buttonsPanel.setDoubleBuffered(false);
|
||||
buttonsPanel.setVisible(true);
|
||||
for (int row = 0; row < 5; row++)
|
||||
for (int col = 0; col < 7; col++)
|
||||
createBtn(row, col);
|
||||
if (row == 0 && col == 2 || row == 0 && col == 4 || row == 2 && col == 2) {
|
||||
createBlankBox();
|
||||
} else {
|
||||
createBtn(row, col);
|
||||
}
|
||||
for (int row = 5; row < 8; row++) {
|
||||
createBlankBox();
|
||||
for (int col = 0; col < 5; col++)
|
||||
@ -234,7 +238,7 @@ public class SwingWindow extends JFrame {
|
||||
final SwingAdvancedButton b = new SwingAdvancedButton(img, new Dimension((int) (BTN_SIZE * 1.5), BTN_SIZE));
|
||||
b.drawDefaultComponent = false;
|
||||
b.setText(Keyboard.getKeyName(row, col));
|
||||
b.setForeground(Color.BLACK);
|
||||
b.setBasicForeground(Color.BLACK);
|
||||
Font f = b.getFont();
|
||||
f = f.deriveFont(Font.BOLD, BTN_SIZE / 3);
|
||||
b.setFont(f);
|
||||
@ -245,6 +249,43 @@ public class SwingWindow extends JFrame {
|
||||
Keyboard.keyReleasedRaw(row, col);
|
||||
c.grabFocus();
|
||||
});
|
||||
b.addMouseListener(new MouseListener() {
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
if (b.state == 2) {
|
||||
b.setForeground(b.basicForeground.darker());
|
||||
} else {
|
||||
b.setForeground(b.basicForeground);
|
||||
}
|
||||
b.hover = false;
|
||||
b.repaint();
|
||||
}
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
if (b.state == 2) {
|
||||
b.setForeground(b.basicForeground);
|
||||
} else {
|
||||
b.setForeground(b.basicForeground.brighter());
|
||||
}
|
||||
b.hover = true;
|
||||
b.repaint();
|
||||
}
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
});
|
||||
buttons[row][col] = b;
|
||||
buttonsPanel.add(b);
|
||||
}
|
||||
@ -261,9 +302,9 @@ public class SwingWindow extends JFrame {
|
||||
else
|
||||
btn.state = 0;
|
||||
if (val && Keyboard.hasKeyName(row, col))
|
||||
btn.setForeground(Color.RED);
|
||||
btn.setBasicForeground(Color.RED);
|
||||
else
|
||||
btn.setForeground(Color.BLACK);
|
||||
btn.setBasicForeground(Color.BLACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -280,9 +321,9 @@ public class SwingWindow extends JFrame {
|
||||
else
|
||||
btn.state = 0;
|
||||
if (val && Keyboard.hasKeyName(row, col))
|
||||
btn.setForeground(new Color(255, 120, 0));
|
||||
btn.setBasicForeground(new Color(255, 120, 0));
|
||||
else
|
||||
btn.setForeground(Color.BLACK);
|
||||
btn.setBasicForeground(Color.BLACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 600 B After Width: | Height: | Size: 767 B |
Binary file not shown.
@ -1,27 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
@ -1,23 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>warppi-engine-jogl</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>warppi-engine-jogl</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
@ -1,3 +1,3 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding//src/main/java=UTF-8
|
||||
encoding/<project>=UTF-8
|
||||
eclipse.preferences.version=1
|
||||
encoding//src/main/java=UTF-8
|
||||
encoding/<project>=UTF-8
|
@ -1,6 +1,6 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.release=disabled
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.release=disabled
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
@ -1,4 +1,4 @@
|
||||
activeProfiles=
|
||||
eclipse.preferences.version=1
|
||||
resolveWorkspaceProjects=true
|
||||
version=1
|
||||
activeProfiles=
|
||||
eclipse.preferences.version=1
|
||||
resolveWorkspaceProjects=true
|
||||
version=1
|
@ -1,61 +1,61 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>it.cavallium</groupId>
|
||||
<artifactId>warppi</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</parent>
|
||||
<artifactId>warppi-engine-jogl</artifactId>
|
||||
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<name>WarpPI Calculator JOGL Engine</name>
|
||||
<description>WarpPI Calculator engine-jogl project</description>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>it.cavallium</groupId>
|
||||
<artifactId>warppi-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jogamp.jogl</groupId>
|
||||
<artifactId>jogl-all-main</artifactId>
|
||||
<version>2.3.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jogamp.gluegen</groupId>
|
||||
<artifactId>gluegen-rt-main</artifactId>
|
||||
<version>2.3.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ar.com.hjg</groupId>
|
||||
<artifactId>pngj</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Export-Package>it.cavallium.warppi.*</Export-Package>
|
||||
<Bundle-SymbolicName>warppi-engine-jogl</Bundle-SymbolicName>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>it.cavallium</groupId>
|
||||
<artifactId>warppi</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</parent>
|
||||
<artifactId>warppi-engine-jogl</artifactId>
|
||||
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<name>WarpPI Calculator JOGL Engine</name>
|
||||
<description>WarpPI Calculator engine-jogl project</description>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>it.cavallium</groupId>
|
||||
<artifactId>warppi-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jogamp.jogl</groupId>
|
||||
<artifactId>jogl-all-main</artifactId>
|
||||
<version>2.3.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jogamp.gluegen</groupId>
|
||||
<artifactId>gluegen-rt-main</artifactId>
|
||||
<version>2.3.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ar.com.hjg</groupId>
|
||||
<artifactId>pngj</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Export-Package>it.cavallium.warppi.*</Export-Package>
|
||||
<Bundle-SymbolicName>warppi-engine-jogl</Bundle-SymbolicName>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -1,203 +1,203 @@
|
||||
package it.cavallium.warppi.gui.graphicengine.impl.jogl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
import com.jogamp.opengl.GLProfile;
|
||||
import com.jogamp.opengl.util.texture.Texture;
|
||||
|
||||
import it.cavallium.warppi.Engine;
|
||||
import it.cavallium.warppi.StaticVars;
|
||||
import it.cavallium.warppi.flow.Observable;
|
||||
import it.cavallium.warppi.gui.graphicengine.BinaryFont;
|
||||
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
|
||||
import it.cavallium.warppi.gui.graphicengine.RenderingLoop;
|
||||
import it.cavallium.warppi.gui.graphicengine.Skin;
|
||||
|
||||
public class JOGLEngine implements GraphicEngine {
|
||||
|
||||
private volatile boolean initialized;
|
||||
private volatile boolean created;
|
||||
private NEWTWindow wnd;
|
||||
private RenderingLoop d;
|
||||
private JOGLRenderer r;
|
||||
private final Map<String, JOGLFont> fontCache = new HashMap<>();
|
||||
int[] size;
|
||||
private final CopyOnWriteArrayList<BinaryFont> registeredFonts = new CopyOnWriteArrayList<>();
|
||||
private final Semaphore exitSemaphore = new Semaphore(0);
|
||||
protected LinkedList<Texture> registeredTextures;
|
||||
protected LinkedList<Texture> unregisteredTextures;
|
||||
|
||||
@Override
|
||||
public int[] getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInitialized() {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTitle(final String title) {
|
||||
wnd.window.setTitle(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResizable(final boolean r) {
|
||||
if (!r)
|
||||
wnd.window.setPosition(0, 0);
|
||||
wnd.window.setResizable(r);
|
||||
wnd.window.setUndecorated(!r);
|
||||
wnd.window.setPointerVisible(r);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDisplayMode(final int ww, final int wh) {
|
||||
wnd.setSize(ww, wh);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
create(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create(final Runnable onInitialized) {
|
||||
initialized = false;
|
||||
created = false;
|
||||
size = new int[] { StaticVars.screenSize[0], StaticVars.screenSize[1] };
|
||||
created = true;
|
||||
registeredTextures = new LinkedList<>();
|
||||
unregisteredTextures = new LinkedList<>();
|
||||
r = new JOGLRenderer();
|
||||
wnd = new NEWTWindow(this);
|
||||
wnd.create();
|
||||
setDisplayMode(StaticVars.screenSize[0], StaticVars.screenSize[1]);
|
||||
setResizable(Engine.getPlatform().getSettings().isDebugEnabled());
|
||||
initialized = true;
|
||||
wnd.onInitialized = onInitialized;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Observable<Integer[]> onResize() {
|
||||
return wnd.onResizeEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return size[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return size[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
if (initialized && created) {
|
||||
initialized = false;
|
||||
created = false;
|
||||
exitSemaphore.release();
|
||||
wnd.window.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(final RenderingLoop d) {
|
||||
this.d = d;
|
||||
wnd.window.setVisible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void repaint() {
|
||||
if (d != null & r != null && JOGLRenderer.gl != null)
|
||||
d.refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JOGLRenderer getRenderer() {
|
||||
return r;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryFont loadFont(final String name) throws IOException {
|
||||
for (final Entry<String, JOGLFont> entry : fontCache.entrySet())
|
||||
if (entry.getKey().equals(name))
|
||||
return entry.getValue();
|
||||
final JOGLFont font = new JOGLFont(this, name);
|
||||
fontCache.put(name, font);
|
||||
return font;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryFont loadFont(final String path, final String name) throws IOException {
|
||||
for (final Entry<String, JOGLFont> entry : fontCache.entrySet())
|
||||
if (entry.getKey().equals(name))
|
||||
return entry.getValue();
|
||||
final JOGLFont font = new JOGLFont(this, path, name);
|
||||
fontCache.put(name, font);
|
||||
return font;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Skin loadSkin(final String file) throws IOException {
|
||||
return new JOGLSkin(this, file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waitForExit() {
|
||||
try {
|
||||
exitSemaphore.acquire();
|
||||
} catch (final InterruptedException e) {}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
if (StaticVars.startupArguments.isEngineForced() && StaticVars.startupArguments.isGPUEngineForced() == false)
|
||||
return false;
|
||||
if (StaticVars.startupArguments.isHeadlessEngineForced())
|
||||
return false;
|
||||
boolean available = false;
|
||||
boolean errored = false;
|
||||
try {
|
||||
available = GLProfile.isAvailable(GLProfile.GL2ES2);
|
||||
} catch (final Exception ex) {
|
||||
errored = true;
|
||||
System.err.println("OpenGL Error: " + ex.getMessage());
|
||||
}
|
||||
if (!available && !errored)
|
||||
System.err.println(GLProfile.glAvailabilityToString());
|
||||
return available;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesRefreshPauses() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void registerFont(final JOGLFont gpuFont) {
|
||||
registeredFonts.add(gpuFont);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsFontRegistering() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CopyOnWriteArrayList<BinaryFont> getRegisteredFonts() {
|
||||
return registeredFonts;
|
||||
}
|
||||
|
||||
public void registerTexture(final Texture t) {
|
||||
unregisteredTextures.addLast(t);
|
||||
}
|
||||
|
||||
package it.cavallium.warppi.gui.graphicengine.impl.jogl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
import com.jogamp.opengl.GLProfile;
|
||||
import com.jogamp.opengl.util.texture.Texture;
|
||||
|
||||
import it.cavallium.warppi.Engine;
|
||||
import it.cavallium.warppi.StaticVars;
|
||||
import it.cavallium.warppi.flow.Observable;
|
||||
import it.cavallium.warppi.gui.graphicengine.BinaryFont;
|
||||
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
|
||||
import it.cavallium.warppi.gui.graphicengine.RenderingLoop;
|
||||
import it.cavallium.warppi.gui.graphicengine.Skin;
|
||||
|
||||
public class JOGLEngine implements GraphicEngine {
|
||||
|
||||
private volatile boolean initialized;
|
||||
private volatile boolean created;
|
||||
private NEWTWindow wnd;
|
||||
private RenderingLoop d;
|
||||
private JOGLRenderer r;
|
||||
private final Map<String, JOGLFont> fontCache = new HashMap<>();
|
||||
int[] size;
|
||||
private final CopyOnWriteArrayList<BinaryFont> registeredFonts = new CopyOnWriteArrayList<>();
|
||||
private final Semaphore exitSemaphore = new Semaphore(0);
|
||||
protected LinkedList<Texture> registeredTextures;
|
||||
protected LinkedList<Texture> unregisteredTextures;
|
||||
|
||||
@Override
|
||||
public int[] getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInitialized() {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTitle(final String title) {
|
||||
wnd.window.setTitle(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResizable(final boolean r) {
|
||||
if (!r)
|
||||
wnd.window.setPosition(0, 0);
|
||||
wnd.window.setResizable(r);
|
||||
wnd.window.setUndecorated(!r);
|
||||
wnd.window.setPointerVisible(r);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDisplayMode(final int ww, final int wh) {
|
||||
wnd.setSize(ww, wh);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
create(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create(final Runnable onInitialized) {
|
||||
initialized = false;
|
||||
created = false;
|
||||
size = new int[] { StaticVars.screenSize[0], StaticVars.screenSize[1] };
|
||||
created = true;
|
||||
registeredTextures = new LinkedList<>();
|
||||
unregisteredTextures = new LinkedList<>();
|
||||
r = new JOGLRenderer();
|
||||
wnd = new NEWTWindow(this);
|
||||
wnd.create();
|
||||
setDisplayMode(StaticVars.screenSize[0], StaticVars.screenSize[1]);
|
||||
setResizable(Engine.getPlatform().getSettings().isDebugEnabled());
|
||||
initialized = true;
|
||||
wnd.onInitialized = onInitialized;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Observable<Integer[]> onResize() {
|
||||
return wnd.onResizeEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return size[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return size[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
if (initialized && created) {
|
||||
initialized = false;
|
||||
created = false;
|
||||
exitSemaphore.release();
|
||||
wnd.window.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(final RenderingLoop d) {
|
||||
this.d = d;
|
||||
wnd.window.setVisible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void repaint() {
|
||||
if (d != null & r != null && JOGLRenderer.gl != null)
|
||||
d.refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JOGLRenderer getRenderer() {
|
||||
return r;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryFont loadFont(final String name) throws IOException {
|
||||
for (final Entry<String, JOGLFont> entry : fontCache.entrySet())
|
||||
if (entry.getKey().equals(name))
|
||||
return entry.getValue();
|
||||
final JOGLFont font = new JOGLFont(this, name);
|
||||
fontCache.put(name, font);
|
||||
return font;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryFont loadFont(final String path, final String name) throws IOException {
|
||||
for (final Entry<String, JOGLFont> entry : fontCache.entrySet())
|
||||
if (entry.getKey().equals(name))
|
||||
return entry.getValue();
|
||||
final JOGLFont font = new JOGLFont(this, path, name);
|
||||
fontCache.put(name, font);
|
||||
return font;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Skin loadSkin(final String file) throws IOException {
|
||||
return new JOGLSkin(this, file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waitForExit() {
|
||||
try {
|
||||
exitSemaphore.acquire();
|
||||
} catch (final InterruptedException e) {}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
if (StaticVars.startupArguments.isEngineForced() && StaticVars.startupArguments.isGPUEngineForced() == false)
|
||||
return false;
|
||||
if (StaticVars.startupArguments.isHeadlessEngineForced())
|
||||
return false;
|
||||
boolean available = false;
|
||||
boolean errored = false;
|
||||
try {
|
||||
available = GLProfile.isAvailable(GLProfile.GL2ES2);
|
||||
} catch (final Exception ex) {
|
||||
errored = true;
|
||||
System.err.println("OpenGL Error: " + ex.getMessage());
|
||||
}
|
||||
if (!available && !errored)
|
||||
System.err.println(GLProfile.glAvailabilityToString());
|
||||
return available;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesRefreshPauses() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void registerFont(final JOGLFont gpuFont) {
|
||||
registeredFonts.add(gpuFont);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsFontRegistering() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CopyOnWriteArrayList<BinaryFont> getRegisteredFonts() {
|
||||
return registeredFonts;
|
||||
}
|
||||
|
||||
public void registerTexture(final Texture t) {
|
||||
unregisteredTextures.addLast(t);
|
||||
}
|
||||
|
||||
}
|
@ -1,236 +1,236 @@
|
||||
package it.cavallium.warppi.gui.graphicengine.impl.jogl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
||||
import com.jogamp.opengl.GLException;
|
||||
import com.jogamp.opengl.util.texture.Texture;
|
||||
|
||||
import ar.com.hjg.pngj.ImageInfo;
|
||||
import ar.com.hjg.pngj.ImageLineHelper;
|
||||
import ar.com.hjg.pngj.ImageLineInt;
|
||||
import ar.com.hjg.pngj.PngWriter;
|
||||
import it.cavallium.warppi.Engine;
|
||||
import it.cavallium.warppi.gui.graphicengine.BinaryFont;
|
||||
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
|
||||
import it.cavallium.warppi.gui.graphicengine.impl.common.RFTFont;
|
||||
|
||||
public class JOGLFont implements BinaryFont {
|
||||
|
||||
public Texture texture;
|
||||
public int textureW;
|
||||
public int textureH;
|
||||
public int charW;
|
||||
public int charH;
|
||||
public int minCharIndex;
|
||||
public int maxCharIndex;
|
||||
public int[] intervals;
|
||||
public int intervalsTotalSize = 0;
|
||||
public int memoryWidth;
|
||||
public int memoryHeight;
|
||||
public int memoryWidthOfEachColumn;
|
||||
|
||||
private boolean initialized = false;
|
||||
private File tmpFont;
|
||||
|
||||
JOGLFont(final GraphicEngine g, final String name) throws IOException {
|
||||
this(g, null, name);
|
||||
}
|
||||
|
||||
public JOGLFont(final GraphicEngine g, final String path, final String name) throws IOException {
|
||||
load(path, name);
|
||||
((JOGLEngine) g).registerFont(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(final String name) throws IOException {
|
||||
load(null, name);
|
||||
}
|
||||
|
||||
public void load(final String path, final String name) throws IOException {
|
||||
RFTFont font;
|
||||
if (path == null)
|
||||
font = RFTFont.loadTemporaryFont(name);
|
||||
else
|
||||
font = RFTFont.loadTemporaryFont(path, name);
|
||||
charW = font.charW;
|
||||
charH = font.charH;
|
||||
minCharIndex = font.minBound;
|
||||
maxCharIndex = font.maxBound;
|
||||
intervals = font.intervals;
|
||||
intervalsTotalSize = font.intervalsTotalSize;
|
||||
boolean[][] rawchars = font.rawchars;
|
||||
font = null;
|
||||
Engine.getPlatform().gc();
|
||||
pregenTexture(rawchars);
|
||||
rawchars = null;
|
||||
Engine.getPlatform().gc();
|
||||
}
|
||||
|
||||
public int[] getCharIndexes(final String txt) {
|
||||
final int[] indexes = new int[txt.length()];
|
||||
int i = 0;
|
||||
for (final char c : txt.toCharArray()) {
|
||||
indexes[i] = compressIndex((c & 0xFFFF) - minCharIndex);
|
||||
i++;
|
||||
}
|
||||
return indexes;
|
||||
}
|
||||
|
||||
public int getCharIndex(final char c) {
|
||||
final int originalIndex = c & 0xFFFF;
|
||||
return compressIndex(originalIndex);
|
||||
}
|
||||
|
||||
private int compressIndex(final int originalIndex) {
|
||||
int compressedIndex = 0;
|
||||
for (int i = 0; i < intervals.length; i += 3)
|
||||
if (intervals[i] > originalIndex)
|
||||
break;
|
||||
else if (originalIndex <= intervals[i + 1]) {
|
||||
compressedIndex += originalIndex - intervals[i];
|
||||
break;
|
||||
} else
|
||||
compressedIndex += intervals[i + 2];
|
||||
return compressedIndex;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private int decompressIndex(final int compressedIndex) {
|
||||
final int originalIndex = 0;
|
||||
int i = 0;
|
||||
for (final int intvl = 0; i < intervals.length; i += 3) {
|
||||
i += intervals[intvl + 2];
|
||||
if (i >= compressedIndex)
|
||||
return intervals[intvl + 1] - (i - compressedIndex);
|
||||
}
|
||||
return originalIndex;
|
||||
}
|
||||
|
||||
private void pregenTexture(boolean[][] chars) throws IOException {
|
||||
final int totalChars = intervalsTotalSize;
|
||||
int w = powerOf2((int) Math.ceil(Math.sqrt(totalChars) * charW));
|
||||
int h = powerOf2((int) Math.ceil(Math.sqrt(totalChars) * charH));
|
||||
int maxIndexW = (int) Math.floor((double) w / (double) charW) - 1;
|
||||
int maxIndexH = (int) Math.floor((double) h / (double) charH) - 1;
|
||||
if (w > h) {
|
||||
System.out.println("w > h");
|
||||
h = powerOf2((int) Math.ceil((double) totalChars / (double) maxIndexW * charH));
|
||||
maxIndexH = (int) Math.floor((double) h / (double) charH) - 1;
|
||||
} else {
|
||||
System.out.println("w <= h");
|
||||
w = powerOf2((int) Math.ceil((double) totalChars / (double) maxIndexH * charW));
|
||||
maxIndexW = (int) Math.floor((double) w / (double) charW) - 1;
|
||||
}
|
||||
// final int h = powerOf2((int) (Math.ceil(Math.sqrt(totalChars) * charH)));
|
||||
|
||||
System.out.println((int) Math.ceil(Math.sqrt(totalChars) * charW) + " * " + (int) Math.ceil(Math.sqrt(totalChars) * charH) + " --> " + w + " * " + h);
|
||||
|
||||
final File f = Files.createTempFile("texture-font-", ".png").toFile();
|
||||
f.deleteOnExit();
|
||||
final FileOutputStream outputStream = new FileOutputStream(f);
|
||||
final ImageInfo imi = new ImageInfo(w, h, 8, true); // 8 bits per channel, alpha
|
||||
// open image for writing to a output stream
|
||||
final PngWriter png = new PngWriter(outputStream, imi);
|
||||
for (int y = 0; y < png.imgInfo.rows; y++) {
|
||||
final ImageLineInt iline = new ImageLineInt(imi);
|
||||
final int[] xValues = new int[imi.cols];
|
||||
for (int indexX = 0; indexX <= maxIndexW; indexX++) {// this line will be written to all rows
|
||||
final int charY = y % charH;
|
||||
final int indexY = (y - charY) / charH;
|
||||
final int i = indexY * (maxIndexW + 1) + indexX - minCharIndex;
|
||||
boolean[] currentChar;
|
||||
if (i < totalChars && (currentChar = chars[i]) != null)
|
||||
for (int charX = 0; charX < charW; charX++)
|
||||
if (i >= 0 & i < totalChars && currentChar != null && currentChar[charX + charY * charW])
|
||||
xValues[indexX * charW + charX] = 0xFFFFFFFF;
|
||||
}
|
||||
ImageLineHelper.setPixelsRGBA8(iline, xValues);
|
||||
if (y % 10 == 0)
|
||||
System.out.println(y + "/" + png.imgInfo.rows);
|
||||
png.writeRow(iline);
|
||||
}
|
||||
chars = null;
|
||||
png.end();
|
||||
Engine.getPlatform().gc();
|
||||
|
||||
try {
|
||||
memoryWidth = w;
|
||||
memoryHeight = h;
|
||||
memoryWidthOfEachColumn = maxIndexW + 1;
|
||||
textureW = w;
|
||||
textureH = h;
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
Engine.getPlatform().gc();
|
||||
tmpFont = f;
|
||||
} catch (GLException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void genTexture() {
|
||||
try {
|
||||
texture = JOGLRenderer.importTexture(tmpFont, true);
|
||||
tmpFont = null;
|
||||
} catch (GLException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private int powerOf2(final int i) {
|
||||
return i > 1 ? Integer.highestOneBit(i - 1) << 1 : 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(final GraphicEngine d) {
|
||||
genTexture();
|
||||
tmpFont = null;
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void use(final GraphicEngine d) {
|
||||
if (!initialized)
|
||||
initialize(d);
|
||||
final JOGLRenderer r = (JOGLRenderer) d.getRenderer();
|
||||
r.currentFont = this;
|
||||
r.useTexture(texture, textureW, textureH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStringWidth(final String text) {
|
||||
final int w = charW * text.length();
|
||||
if (text.length() > 0)
|
||||
return w;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterWidth() {
|
||||
return charW;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterHeight() {
|
||||
return charH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInitialized() {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkinWidth() {
|
||||
return memoryWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkinHeight() {
|
||||
return memoryHeight;
|
||||
}
|
||||
package it.cavallium.warppi.gui.graphicengine.impl.jogl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
||||
import com.jogamp.opengl.GLException;
|
||||
import com.jogamp.opengl.util.texture.Texture;
|
||||
|
||||
import ar.com.hjg.pngj.ImageInfo;
|
||||
import ar.com.hjg.pngj.ImageLineHelper;
|
||||
import ar.com.hjg.pngj.ImageLineInt;
|
||||
import ar.com.hjg.pngj.PngWriter;
|
||||
import it.cavallium.warppi.Engine;
|
||||
import it.cavallium.warppi.gui.graphicengine.BinaryFont;
|
||||
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
|
||||
import it.cavallium.warppi.gui.graphicengine.impl.common.RFTFont;
|
||||
|
||||
public class JOGLFont implements BinaryFont {
|
||||
|
||||
public Texture texture;
|
||||
public int textureW;
|
||||
public int textureH;
|
||||
public int charW;
|
||||
public int charH;
|
||||
public int minCharIndex;
|
||||
public int maxCharIndex;
|
||||
public int[] intervals;
|
||||
public int intervalsTotalSize = 0;
|
||||
public int memoryWidth;
|
||||
public int memoryHeight;
|
||||
public int memoryWidthOfEachColumn;
|
||||
|
||||
private boolean initialized = false;
|
||||
private File tmpFont;
|
||||
|
||||
JOGLFont(final GraphicEngine g, final String name) throws IOException {
|
||||
this(g, null, name);
|
||||
}
|
||||
|
||||
public JOGLFont(final GraphicEngine g, final String path, final String name) throws IOException {
|
||||
load(path, name);
|
||||
((JOGLEngine) g).registerFont(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(final String name) throws IOException {
|
||||
load(null, name);
|
||||
}
|
||||
|
||||
public void load(final String path, final String name) throws IOException {
|
||||
RFTFont font;
|
||||
if (path == null)
|
||||
font = RFTFont.loadTemporaryFont(name);
|
||||
else
|
||||
font = RFTFont.loadTemporaryFont(path, name);
|
||||
charW = font.charW;
|
||||
charH = font.charH;
|
||||
minCharIndex = font.minBound;
|
||||
maxCharIndex = font.maxBound;
|
||||
intervals = font.intervals;
|
||||
intervalsTotalSize = font.intervalsTotalSize;
|
||||
boolean[][] rawchars = font.rawchars;
|
||||
font = null;
|
||||
Engine.getPlatform().gc();
|
||||
pregenTexture(rawchars);
|
||||
rawchars = null;
|
||||
Engine.getPlatform().gc();
|
||||
}
|
||||
|
||||
public int[] getCharIndexes(final String txt) {
|
||||
final int[] indexes = new int[txt.length()];
|
||||
int i = 0;
|
||||
for (final char c : txt.toCharArray()) {
|
||||
indexes[i] = compressIndex((c & 0xFFFF) - minCharIndex);
|
||||
i++;
|
||||
}
|
||||
return indexes;
|
||||
}
|
||||
|
||||
public int getCharIndex(final char c) {
|
||||
final int originalIndex = c & 0xFFFF;
|
||||
return compressIndex(originalIndex);
|
||||
}
|
||||
|
||||
private int compressIndex(final int originalIndex) {
|
||||
int compressedIndex = 0;
|
||||
for (int i = 0; i < intervals.length; i += 3)
|
||||
if (intervals[i] > originalIndex)
|
||||
break;
|
||||
else if (originalIndex <= intervals[i + 1]) {
|
||||
compressedIndex += originalIndex - intervals[i];
|
||||
break;
|
||||
} else
|
||||
compressedIndex += intervals[i + 2];
|
||||
return compressedIndex;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private int decompressIndex(final int compressedIndex) {
|
||||
final int originalIndex = 0;
|
||||
int i = 0;
|
||||
for (final int intvl = 0; i < intervals.length; i += 3) {
|
||||
i += intervals[intvl + 2];
|
||||
if (i >= compressedIndex)
|
||||
return intervals[intvl + 1] - (i - compressedIndex);
|
||||
}
|
||||
return originalIndex;
|
||||
}
|
||||
|
||||
private void pregenTexture(boolean[][] chars) throws IOException {
|
||||
final int totalChars = intervalsTotalSize;
|
||||
int w = powerOf2((int) Math.ceil(Math.sqrt(totalChars) * charW));
|
||||
int h = powerOf2((int) Math.ceil(Math.sqrt(totalChars) * charH));
|
||||
int maxIndexW = (int) Math.floor((double) w / (double) charW) - 1;
|
||||
int maxIndexH = (int) Math.floor((double) h / (double) charH) - 1;
|
||||
if (w > h) {
|
||||
System.out.println("w > h");
|
||||
h = powerOf2((int) Math.ceil((double) totalChars / (double) maxIndexW * charH));
|
||||
maxIndexH = (int) Math.floor((double) h / (double) charH) - 1;
|
||||
} else {
|
||||
System.out.println("w <= h");
|
||||
w = powerOf2((int) Math.ceil((double) totalChars / (double) maxIndexH * charW));
|
||||
maxIndexW = (int) Math.floor((double) w / (double) charW) - 1;
|
||||
}
|
||||
// final int h = powerOf2((int) (Math.ceil(Math.sqrt(totalChars) * charH)));
|
||||
|
||||
System.out.println((int) Math.ceil(Math.sqrt(totalChars) * charW) + " * " + (int) Math.ceil(Math.sqrt(totalChars) * charH) + " --> " + w + " * " + h);
|
||||
|
||||
final File f = Files.createTempFile("texture-font-", ".png").toFile();
|
||||
f.deleteOnExit();
|
||||
final FileOutputStream outputStream = new FileOutputStream(f);
|
||||
final ImageInfo imi = new ImageInfo(w, h, 8, true); // 8 bits per channel, alpha
|
||||
// open image for writing to a output stream
|
||||
final PngWriter png = new PngWriter(outputStream, imi);
|
||||
for (int y = 0; y < png.imgInfo.rows; y++) {
|
||||
final ImageLineInt iline = new ImageLineInt(imi);
|
||||
final int[] xValues = new int[imi.cols];
|
||||
for (int indexX = 0; indexX <= maxIndexW; indexX++) {// this line will be written to all rows
|
||||
final int charY = y % charH;
|
||||
final int indexY = (y - charY) / charH;
|
||||
final int i = indexY * (maxIndexW + 1) + indexX - minCharIndex;
|
||||
boolean[] currentChar;
|
||||
if (i < totalChars && (currentChar = chars[i]) != null)
|
||||
for (int charX = 0; charX < charW; charX++)
|
||||
if (i >= 0 & i < totalChars && currentChar != null && currentChar[charX + charY * charW])
|
||||
xValues[indexX * charW + charX] = 0xFFFFFFFF;
|
||||
}
|
||||
ImageLineHelper.setPixelsRGBA8(iline, xValues);
|
||||
if (y % 10 == 0)
|
||||
System.out.println(y + "/" + png.imgInfo.rows);
|
||||
png.writeRow(iline);
|
||||
}
|
||||
chars = null;
|
||||
png.end();
|
||||
Engine.getPlatform().gc();
|
||||
|
||||
try {
|
||||
memoryWidth = w;
|
||||
memoryHeight = h;
|
||||
memoryWidthOfEachColumn = maxIndexW + 1;
|
||||
textureW = w;
|
||||
textureH = h;
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
Engine.getPlatform().gc();
|
||||
tmpFont = f;
|
||||
} catch (GLException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void genTexture() {
|
||||
try {
|
||||
texture = JOGLRenderer.importTexture(tmpFont, true);
|
||||
tmpFont = null;
|
||||
} catch (GLException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private int powerOf2(final int i) {
|
||||
return i > 1 ? Integer.highestOneBit(i - 1) << 1 : 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(final GraphicEngine d) {
|
||||
genTexture();
|
||||
tmpFont = null;
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void use(final GraphicEngine d) {
|
||||
if (!initialized)
|
||||
initialize(d);
|
||||
final JOGLRenderer r = (JOGLRenderer) d.getRenderer();
|
||||
r.currentFont = this;
|
||||
r.useTexture(texture, textureW, textureH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStringWidth(final String text) {
|
||||
final int w = charW * text.length();
|
||||
if (text.length() > 0)
|
||||
return w;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterWidth() {
|
||||
return charW;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacterHeight() {
|
||||
return charH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInitialized() {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkinWidth() {
|
||||
return memoryWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkinHeight() {
|
||||
return memoryHeight;
|
||||
}
|
||||
}
|
@ -1,447 +1,447 @@
|
||||
package it.cavallium.warppi.gui.graphicengine.impl.jogl;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.file.Files;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import com.jogamp.common.nio.Buffers;
|
||||
import com.jogamp.opengl.GL;
|
||||
import com.jogamp.opengl.GL2ES1;
|
||||
import com.jogamp.opengl.GLException;
|
||||
import com.jogamp.opengl.util.texture.Texture;
|
||||
import com.jogamp.opengl.util.texture.TextureData;
|
||||
import com.jogamp.opengl.util.texture.TextureIO;
|
||||
|
||||
import it.cavallium.warppi.Engine;
|
||||
import it.cavallium.warppi.gui.graphicengine.BinaryFont;
|
||||
import it.cavallium.warppi.gui.graphicengine.Renderer;
|
||||
|
||||
public class JOGLRenderer implements Renderer {
|
||||
|
||||
public static GL2ES1 gl;
|
||||
|
||||
private static final int ELEMENTS_MAX_COUNT_PER_BUFFER = 128;
|
||||
private static final int ELEMENT_VERTICES_COUNT = 6;
|
||||
|
||||
private static final int vertSize = 3;
|
||||
|
||||
private static final int texSize = 2;
|
||||
|
||||
private static final int colSize = 4;
|
||||
|
||||
private static final int vertBuffer = 0;
|
||||
|
||||
private static final int texBuffer = 1;
|
||||
|
||||
private static final int colBuffer = 2;
|
||||
|
||||
private static final int vertMax = JOGLRenderer.vertSize * JOGLRenderer.ELEMENT_VERTICES_COUNT * JOGLRenderer.ELEMENTS_MAX_COUNT_PER_BUFFER;
|
||||
|
||||
private static final int texMax = JOGLRenderer.texSize * JOGLRenderer.ELEMENT_VERTICES_COUNT * JOGLRenderer.ELEMENTS_MAX_COUNT_PER_BUFFER;
|
||||
|
||||
private static final int colMax = JOGLRenderer.colSize * JOGLRenderer.ELEMENT_VERTICES_COUNT * JOGLRenderer.ELEMENTS_MAX_COUNT_PER_BUFFER;
|
||||
|
||||
private int[] handlers;
|
||||
FloatBuffer fbVertices;
|
||||
FloatBuffer fbTextures;
|
||||
FloatBuffer fbColors;
|
||||
int fbElements;
|
||||
|
||||
float[] currentColor = new float[24];
|
||||
float[] currentClearColorARGBf = new float[] { 1f, 197f / 255f, 194f / 255f, 175f / 255f };
|
||||
boolean currentTexEnabled;
|
||||
Texture currentTex;
|
||||
float currentTexWidth;
|
||||
float currentTexHeight;
|
||||
|
||||
JOGLFont currentFont;
|
||||
|
||||
@Override
|
||||
public void glColor3i(final int r, final int gg, final int b) {
|
||||
final float red = r / 255f;
|
||||
final float gre = gg / 255f;
|
||||
final float blu = b / 255f;
|
||||
//currentColor = new float[] { red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, };
|
||||
currentColor = new float[] { red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, }; //OK
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glColor3f(final float red, final float gre, final float blu) {
|
||||
// currentColor = new float[] { red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, };
|
||||
currentColor = new float[] { red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, };//OK
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glColor4f(final float red, final float gre, final float blu, final float alp) {
|
||||
// currentColor = new float[] { red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, };
|
||||
currentColor = new float[] { red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, };//ok
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glColor(final int rgb) {
|
||||
final int alpha = rgb >> 24 & 0xFF;
|
||||
final int red = rgb >> 16 & 0xFF;
|
||||
final int green = rgb >> 8 & 0xFF;
|
||||
final int blue = rgb & 0xFF;
|
||||
glColor4i(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int glGetClearColor() {
|
||||
return (int) (currentClearColorARGBf[0] * 255) << 24 | (int) (currentClearColorARGBf[1] * 255) << 16 | (int) (currentClearColorARGBf[2] * 255) << 8 | (int) (currentClearColorARGBf[3] * 255);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glClearColor(final int rgb) {
|
||||
final float alpha = (rgb >> 24 & 0xFF) / 255f;
|
||||
final float red = (rgb >> 16 & 0xFF) / 255f;
|
||||
final float green = (rgb >> 8 & 0xFF) / 255f;
|
||||
final float blue = (rgb & 0xFF) / 255f;
|
||||
glClearColor4f(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glColor4i(final int r, final int g, final int b, final int a) {
|
||||
final float red = r / 255f;
|
||||
final float gre = g / 255f;
|
||||
final float blu = b / 255f;
|
||||
final float alp = a / 255f;
|
||||
//currentColor = new float[] { red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, };
|
||||
currentColor = new float[] { red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, };//OK
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glClearColor4i(final int red, final int green, final int blue, final int alpha) {
|
||||
final float ros = red / 255f;
|
||||
final float gre = green / 255f;
|
||||
final float blu = blue / 255f;
|
||||
final float alp = alpha / 255f;
|
||||
currentClearColorARGBf = new float[] { alp, ros, gre, blu };
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glClearColor4f(final float red, final float green, final float blue, final float alpha) {
|
||||
currentClearColorARGBf = new float[] { alpha, red, green, blue };
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glClear(final int screenWidth, final int screenHeight) {
|
||||
glColor(glGetClearColor());
|
||||
glFillColor(0, 0, screenWidth, screenHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glDrawLine(final float x0, final float y0, final float x1, final float y1) {
|
||||
glFillColor(x0, y0, x1 - x0 + 1, y1 - y0 + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glFillRect(final float x, final float y, final float width, final float height, float uvX, float uvY,
|
||||
float uvWidth, float uvHeight) {
|
||||
enableTexture();
|
||||
if (uvWidth < 0)
|
||||
uvX -= uvWidth;
|
||||
if (uvHeight < 0)
|
||||
uvY -= uvHeight;
|
||||
uvWidth /= currentTexWidth;
|
||||
uvX /= currentTexWidth;
|
||||
uvHeight /= currentTexHeight;
|
||||
uvY = 1 - uvY / currentTexHeight - uvHeight;
|
||||
// final float[] vertices = { x, y, 0.0f, x, y + height, 0.0f, x + width, y, 0.0f, x + width, y + height, 0.0f, };
|
||||
// final float[] tex_vertices = { uvX, uvY + uvHeight, uvX, uvY, uvX + uvWidth, uvY + uvHeight, uvX + uvWidth, uvY, };
|
||||
//V0 x, y, 0.0f
|
||||
//V1 x, y + height, 0.0f
|
||||
//V2 x + width, y, 0.0f
|
||||
//V3 x + width, y + height, 0.0f
|
||||
|
||||
//NV0 = V1
|
||||
//NV1 = V3
|
||||
//NV2 = V0
|
||||
|
||||
//NV3 = V0
|
||||
//NV4 = V3
|
||||
//NV5 = V2
|
||||
|
||||
final float[] vertices = { x, y + height, 0.0f, x + width, y + height, 0.0f, x, y, 0.0f, x, y, 0.0f, x + width, y + height, 0.0f, x + width, y, 0.0f };
|
||||
final float[] tex_vertices = { uvX, uvY, uvX + uvWidth, uvY, uvX, uvY + uvHeight, uvX, uvY + uvHeight, uvX + uvWidth, uvY, uvX + uvWidth, uvY + uvHeight };
|
||||
fbElements++;
|
||||
fbVertices.put(vertices);
|
||||
fbTextures.put(tex_vertices);
|
||||
fbColors.put(currentColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glFillColor(final float x0, final float y0, final float w1, final float h1) {
|
||||
disableTexture();
|
||||
// final float[] vertices = { x0, y0, 0.0f, x0, y0 + h1, 0.0f, x0 + w1, y0, 0.0f, x0 + w1, y0 + h1, 0.0f, };
|
||||
// final float[] tex_vertices = { 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, };
|
||||
//V0 x0, y0, 0.0f
|
||||
//V1 x0, y0 + h1, 0.0f
|
||||
//V2 x0 + w1, y0, 0.0f
|
||||
//V3 x0 + w1, y0 + h1, 0.0f
|
||||
|
||||
//NV0 = V1
|
||||
//NV1 = V3
|
||||
//NV2 = V0
|
||||
|
||||
//NV3 = V0
|
||||
//NV4 = V3
|
||||
//NV5 = V2
|
||||
|
||||
final float[] vertices = { x0, y0 + h1, 0.0f, x0 + w1, y0 + h1, 0.0f, x0, y0, 0.0f, x0, y0, 0.0f, x0 + w1, y0 + h1, 0.0f, x0 + w1, y0, 0.0f, };
|
||||
final float[] tex_vertices = { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, };
|
||||
fbElements++;
|
||||
fbVertices.put(vertices);
|
||||
fbTextures.put(tex_vertices);
|
||||
fbColors.put(currentColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glDrawStringLeft(final float x, final float y, final String text) {
|
||||
final int txtLen = text.length();
|
||||
final int[] txtArray = currentFont.getCharIndexes(text);
|
||||
int tableIndexX;
|
||||
int tableIndexY;
|
||||
for (int currentCharIndex = 0; currentCharIndex < txtLen; currentCharIndex++) {
|
||||
tableIndexX = txtArray[currentCharIndex] % currentFont.memoryWidthOfEachColumn;
|
||||
tableIndexY = (txtArray[currentCharIndex] - tableIndexX) / currentFont.memoryWidthOfEachColumn;
|
||||
glFillRect(x + (float) currentCharIndex * (float) currentFont.charW, y, currentFont.charW, currentFont.charH, tableIndexX * currentFont.charW, tableIndexY * currentFont.charH, currentFont.charW, currentFont.charH);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glDrawStringCenter(final float x, final float y, final String text) {
|
||||
glDrawStringLeft(x - currentFont.getStringWidth(text) / 2, y, text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glDrawStringRight(final float x, final float y, final String text) {
|
||||
glDrawStringLeft(x - currentFont.getStringWidth(text), y, text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glDrawCharLeft(final int x, final int y, final char ch) {
|
||||
final int index = currentFont.getCharIndex(ch);
|
||||
final int tableIndexX = index % currentFont.memoryWidthOfEachColumn;
|
||||
final int tableIndexY = (index - tableIndexX) / currentFont.memoryWidthOfEachColumn;
|
||||
glFillRect(x, y, currentFont.charW, currentFont.charH, tableIndexX * currentFont.charW, tableIndexY * currentFont.charH, currentFont.charW, currentFont.charH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glDrawCharCenter(final int x, final int y, final char ch) {
|
||||
glDrawCharLeft(x - currentFont.charW / 2, y, ch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glDrawCharRight(final int x, final int y, final char ch) {
|
||||
glDrawCharLeft(x - currentFont.charW, y, ch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryFont getCurrentFont() {
|
||||
return currentFont;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
static Texture importTexture(final GL gl, final String string) throws IOException {
|
||||
final FileInputStream f = new FileInputStream("test.png");
|
||||
final TextureData tx_dat = TextureIO.newTextureData(gl.getGLProfile(), f, false, TextureIO.PNG);
|
||||
final Texture tex = new Texture(gl, tx_dat);
|
||||
tex.setTexParameteri(gl, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
|
||||
tex.setTexParameteri(gl, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
|
||||
// tex.setTexParameteri(gl, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
|
||||
// tex.setTexParameteri(gl, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
|
||||
return tex;
|
||||
}
|
||||
|
||||
static OpenedTextureData openTexture(final String file, final boolean isResource) throws GLException, IOException {
|
||||
BufferedImage img = ImageIO.read(isResource ? JOGLRenderer.class.getResource("/" + file) : new File(file).toURI().toURL());
|
||||
File f;
|
||||
if (isResource) {
|
||||
f = Files.createTempFile("texture-", ".png").toFile();
|
||||
f.deleteOnExit();
|
||||
ImageIO.write(img, "png", f);
|
||||
} else
|
||||
f = new File(file);
|
||||
final int imgW = img.getWidth();
|
||||
final int imgH = img.getHeight();
|
||||
img = null;
|
||||
Engine.getPlatform().gc();
|
||||
return new OpenedTextureData(imgW, imgH, f, isResource);
|
||||
}
|
||||
|
||||
public static class OpenedTextureData {
|
||||
public final int w;
|
||||
public final int h;
|
||||
public final File f;
|
||||
public final boolean deleteOnExit;
|
||||
|
||||
/**
|
||||
* @param w
|
||||
* @param h
|
||||
* @param f
|
||||
* @param deleteOnExit
|
||||
*/
|
||||
public OpenedTextureData(final int w, final int h, final File f, final boolean deleteOnExit) {
|
||||
this.w = w;
|
||||
this.h = h;
|
||||
this.f = f;
|
||||
this.deleteOnExit = deleteOnExit;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static Texture importTexture(File f, final boolean deleteOnExit) throws GLException, IOException {
|
||||
final Texture tex = TextureIO.newTexture(f, false);
|
||||
if (deleteOnExit && f.exists())
|
||||
try {
|
||||
if (Engine.getPlatform().getSettings().isDebugEnabled())
|
||||
throw new IOException("Delete on exit!");
|
||||
f.delete();
|
||||
} catch (final Exception ex) {
|
||||
f.deleteOnExit();
|
||||
}
|
||||
tex.setTexParameteri(JOGLRenderer.gl, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
|
||||
tex.setTexParameteri(JOGLRenderer.gl, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
|
||||
f = null;
|
||||
return tex;
|
||||
}
|
||||
|
||||
public void initDrawCycle() {
|
||||
final boolean textureChange = precTexEnabled != currentTexEnabled || precTex != currentTex;
|
||||
if (fbVertices == null) {
|
||||
fbVertices = Buffers.newDirectFloatBuffer(JOGLRenderer.vertMax);
|
||||
fbTextures = Buffers.newDirectFloatBuffer(JOGLRenderer.texMax);
|
||||
fbColors = Buffers.newDirectFloatBuffer(JOGLRenderer.colMax);
|
||||
handlers = new int[3];
|
||||
JOGLRenderer.gl.glGenBuffers(3, handlers, 0);
|
||||
}
|
||||
startDrawSegment(false);
|
||||
if (textureChange)
|
||||
changeTexture();
|
||||
}
|
||||
|
||||
public void endDrawCycle() {
|
||||
final boolean textureChange = precTexEnabled != currentTexEnabled || precTex != currentTex;
|
||||
if (textureChange) {
|
||||
if (fbElements > 0)
|
||||
endDrawSegment();
|
||||
changeTexture();
|
||||
} else if (fbElements > 0)
|
||||
endDrawSegment();
|
||||
}
|
||||
|
||||
private void changeTexture() {
|
||||
precTexEnabled = currentTexEnabled;
|
||||
precTex = currentTex;
|
||||
if (currentTexEnabled) {
|
||||
JOGLRenderer.gl.glEnable(GL.GL_TEXTURE_2D);
|
||||
currentTex.bind(JOGLRenderer.gl);
|
||||
} else
|
||||
JOGLRenderer.gl.glDisable(GL.GL_TEXTURE_2D);
|
||||
firstBufferTexDataCall = true;
|
||||
}
|
||||
|
||||
public void startDrawSegment(final boolean continuation) {
|
||||
if (!continuation || cycleEnded)
|
||||
fbElements = 0;
|
||||
cycleEnded = false;
|
||||
}
|
||||
|
||||
private boolean precTexEnabled;
|
||||
private Texture precTex;
|
||||
private boolean cycleEnded = true;
|
||||
|
||||
public void doDrawSegment() {
|
||||
final boolean textureChange = precTexEnabled != currentTexEnabled || precTex != currentTex;
|
||||
final boolean changeRequired = fbElements >= JOGLRenderer.ELEMENTS_MAX_COUNT_PER_BUFFER;
|
||||
if (textureChange) {
|
||||
if (fbElements > 0) {
|
||||
endDrawSegment();
|
||||
startDrawSegment(false);
|
||||
}
|
||||
changeTexture();
|
||||
} else if (fbElements > 0 && changeRequired) {
|
||||
endDrawSegment();
|
||||
startDrawSegment(true);
|
||||
}
|
||||
}
|
||||
|
||||
boolean firstBufferDataCall = true;
|
||||
boolean firstBufferTexDataCall = true;
|
||||
|
||||
public void endDrawSegment() {
|
||||
fbVertices.flip();
|
||||
fbTextures.flip();
|
||||
fbColors.flip();
|
||||
|
||||
// gl.glVertexPointer(vertSize, GL.GL_FLOAT, 0, fbVertices);
|
||||
JOGLRenderer.gl.glBindBuffer(GL.GL_ARRAY_BUFFER, handlers[JOGLRenderer.vertBuffer]);
|
||||
if (firstBufferTexDataCall)
|
||||
JOGLRenderer.gl.glBufferData(GL.GL_ARRAY_BUFFER, fbVertices.limit() * Buffers.SIZEOF_FLOAT, fbVertices, GL.GL_STATIC_DRAW);
|
||||
else
|
||||
JOGLRenderer.gl.glBufferSubData(GL.GL_ARRAY_BUFFER, 0, fbVertices.limit() * Buffers.SIZEOF_FLOAT, fbVertices);
|
||||
JOGLRenderer.gl.glVertexPointer(JOGLRenderer.vertSize, GL.GL_FLOAT, 0, 0l);
|
||||
// gl.glTexCoordPointer(texSize, GL.GL_FLOAT, 0, fbTextures);
|
||||
JOGLRenderer.gl.glBindBuffer(GL.GL_ARRAY_BUFFER, handlers[JOGLRenderer.texBuffer]);
|
||||
if (firstBufferTexDataCall)
|
||||
JOGLRenderer.gl.glBufferData(GL.GL_ARRAY_BUFFER, fbTextures.limit() * Buffers.SIZEOF_FLOAT, fbTextures, GL.GL_STATIC_DRAW);
|
||||
else
|
||||
JOGLRenderer.gl.glBufferSubData(GL.GL_ARRAY_BUFFER, 0, fbTextures.limit() * Buffers.SIZEOF_FLOAT, fbTextures);
|
||||
JOGLRenderer.gl.glTexCoordPointer(JOGLRenderer.texSize, GL.GL_FLOAT, 0, 0l);
|
||||
// gl.glColorPointer(colSize, GL.GL_FLOAT, 0, fbColors);
|
||||
JOGLRenderer.gl.glBindBuffer(GL.GL_ARRAY_BUFFER, handlers[JOGLRenderer.colBuffer]);
|
||||
if (firstBufferTexDataCall)
|
||||
JOGLRenderer.gl.glBufferData(GL.GL_ARRAY_BUFFER, fbColors.limit() * Buffers.SIZEOF_FLOAT, fbColors, GL.GL_STATIC_DRAW);
|
||||
else
|
||||
JOGLRenderer.gl.glBufferSubData(GL.GL_ARRAY_BUFFER, 0, fbColors.limit() * Buffers.SIZEOF_FLOAT, fbColors);
|
||||
JOGLRenderer.gl.glColorPointer(JOGLRenderer.colSize, GL.GL_FLOAT, 0, 0l);
|
||||
|
||||
fbVertices.limit(JOGLRenderer.vertMax);
|
||||
fbTextures.limit(JOGLRenderer.texMax);
|
||||
fbColors.limit(JOGLRenderer.colMax);
|
||||
JOGLRenderer.gl.glDrawArrays(GL.GL_TRIANGLES, 0, fbElements * JOGLRenderer.ELEMENT_VERTICES_COUNT);
|
||||
//gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, fbElements * ELEMENT_VERTICES_COUNT);
|
||||
firstBufferDataCall = false;
|
||||
firstBufferTexDataCall = false;
|
||||
cycleEnded = true;
|
||||
|
||||
// deleteBuffer(fbVertices);
|
||||
// deleteBuffer(txVertices);
|
||||
// deleteBuffer(colVertices);
|
||||
// fbVertices = null;
|
||||
// txVertices = null;
|
||||
// colVertices = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glClearSkin() {
|
||||
if (currentTex != null) {
|
||||
currentTex = null;
|
||||
doDrawSegment();
|
||||
}
|
||||
}
|
||||
|
||||
void disableTexture() {
|
||||
currentTexEnabled = false;
|
||||
doDrawSegment();
|
||||
}
|
||||
|
||||
void enableTexture() {
|
||||
currentTexEnabled = true;
|
||||
doDrawSegment();
|
||||
}
|
||||
|
||||
void useTexture(final Texture t, final float w, final float h) {
|
||||
currentTex = t;
|
||||
currentTexWidth = w;
|
||||
currentTexHeight = h;
|
||||
enableTexture();
|
||||
}
|
||||
package it.cavallium.warppi.gui.graphicengine.impl.jogl;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.file.Files;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import com.jogamp.common.nio.Buffers;
|
||||
import com.jogamp.opengl.GL;
|
||||
import com.jogamp.opengl.GL2ES1;
|
||||
import com.jogamp.opengl.GLException;
|
||||
import com.jogamp.opengl.util.texture.Texture;
|
||||
import com.jogamp.opengl.util.texture.TextureData;
|
||||
import com.jogamp.opengl.util.texture.TextureIO;
|
||||
|
||||
import it.cavallium.warppi.Engine;
|
||||
import it.cavallium.warppi.gui.graphicengine.BinaryFont;
|
||||
import it.cavallium.warppi.gui.graphicengine.Renderer;
|
||||
|
||||
public class JOGLRenderer implements Renderer {
|
||||
|
||||
public static GL2ES1 gl;
|
||||
|
||||
private static final int ELEMENTS_MAX_COUNT_PER_BUFFER = 128;
|
||||
private static final int ELEMENT_VERTICES_COUNT = 6;
|
||||
|
||||
private static final int vertSize = 3;
|
||||
|
||||
private static final int texSize = 2;
|
||||
|
||||
private static final int colSize = 4;
|
||||
|
||||
private static final int vertBuffer = 0;
|
||||
|
||||
private static final int texBuffer = 1;
|
||||
|
||||
private static final int colBuffer = 2;
|
||||
|
||||
private static final int vertMax = JOGLRenderer.vertSize * JOGLRenderer.ELEMENT_VERTICES_COUNT * JOGLRenderer.ELEMENTS_MAX_COUNT_PER_BUFFER;
|
||||
|
||||
private static final int texMax = JOGLRenderer.texSize * JOGLRenderer.ELEMENT_VERTICES_COUNT * JOGLRenderer.ELEMENTS_MAX_COUNT_PER_BUFFER;
|
||||
|
||||
private static final int colMax = JOGLRenderer.colSize * JOGLRenderer.ELEMENT_VERTICES_COUNT * JOGLRenderer.ELEMENTS_MAX_COUNT_PER_BUFFER;
|
||||
|
||||
private int[] handlers;
|
||||
FloatBuffer fbVertices;
|
||||
FloatBuffer fbTextures;
|
||||
FloatBuffer fbColors;
|
||||
int fbElements;
|
||||
|
||||
float[] currentColor = new float[24];
|
||||
float[] currentClearColorARGBf = new float[] { 1f, 197f / 255f, 194f / 255f, 175f / 255f };
|
||||
boolean currentTexEnabled;
|
||||
Texture currentTex;
|
||||
float currentTexWidth;
|
||||
float currentTexHeight;
|
||||
|
||||
JOGLFont currentFont;
|
||||
|
||||
@Override
|
||||
public void glColor3i(final int r, final int gg, final int b) {
|
||||
final float red = r / 255f;
|
||||
final float gre = gg / 255f;
|
||||
final float blu = b / 255f;
|
||||
//currentColor = new float[] { red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, };
|
||||
currentColor = new float[] { red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, }; //OK
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glColor3f(final float red, final float gre, final float blu) {
|
||||
// currentColor = new float[] { red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, };
|
||||
currentColor = new float[] { red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, red, gre, blu, 1.0f, };//OK
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glColor4f(final float red, final float gre, final float blu, final float alp) {
|
||||
// currentColor = new float[] { red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, };
|
||||
currentColor = new float[] { red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, };//ok
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glColor(final int rgb) {
|
||||
final int alpha = rgb >> 24 & 0xFF;
|
||||
final int red = rgb >> 16 & 0xFF;
|
||||
final int green = rgb >> 8 & 0xFF;
|
||||
final int blue = rgb & 0xFF;
|
||||
glColor4i(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int glGetClearColor() {
|
||||
return (int) (currentClearColorARGBf[0] * 255) << 24 | (int) (currentClearColorARGBf[1] * 255) << 16 | (int) (currentClearColorARGBf[2] * 255) << 8 | (int) (currentClearColorARGBf[3] * 255);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glClearColor(final int rgb) {
|
||||
final float alpha = (rgb >> 24 & 0xFF) / 255f;
|
||||
final float red = (rgb >> 16 & 0xFF) / 255f;
|
||||
final float green = (rgb >> 8 & 0xFF) / 255f;
|
||||
final float blue = (rgb & 0xFF) / 255f;
|
||||
glClearColor4f(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glColor4i(final int r, final int g, final int b, final int a) {
|
||||
final float red = r / 255f;
|
||||
final float gre = g / 255f;
|
||||
final float blu = b / 255f;
|
||||
final float alp = a / 255f;
|
||||
//currentColor = new float[] { red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, };
|
||||
currentColor = new float[] { red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, };//OK
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glClearColor4i(final int red, final int green, final int blue, final int alpha) {
|
||||
final float ros = red / 255f;
|
||||
final float gre = green / 255f;
|
||||
final float blu = blue / 255f;
|
||||
final float alp = alpha / 255f;
|
||||
currentClearColorARGBf = new float[] { alp, ros, gre, blu };
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glClearColor4f(final float red, final float green, final float blue, final float alpha) {
|
||||
currentClearColorARGBf = new float[] { alpha, red, green, blue };
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glClear(final int screenWidth, final int screenHeight) {
|
||||
glColor(glGetClearColor());
|
||||
glFillColor(0, 0, screenWidth, screenHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glDrawLine(final float x0, final float y0, final float x1, final float y1) {
|
||||
glFillColor(x0, y0, x1 - x0 + 1, y1 - y0 + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glFillRect(final float x, final float y, final float width, final float height, float uvX, float uvY,
|
||||
float uvWidth, float uvHeight) {
|
||||
enableTexture();
|
||||
if (uvWidth < 0)
|
||||
uvX -= uvWidth;
|
||||
if (uvHeight < 0)
|
||||
uvY -= uvHeight;
|
||||
uvWidth /= currentTexWidth;
|
||||
uvX /= currentTexWidth;
|
||||
uvHeight /= currentTexHeight;
|
||||
uvY = 1 - uvY / currentTexHeight - uvHeight;
|
||||
// final float[] vertices = { x, y, 0.0f, x, y + height, 0.0f, x + width, y, 0.0f, x + width, y + height, 0.0f, };
|
||||
// final float[] tex_vertices = { uvX, uvY + uvHeight, uvX, uvY, uvX + uvWidth, uvY + uvHeight, uvX + uvWidth, uvY, };
|
||||
//V0 x, y, 0.0f
|
||||
//V1 x, y + height, 0.0f
|
||||
//V2 x + width, y, 0.0f
|
||||
//V3 x + width, y + height, 0.0f
|
||||
|
||||
//NV0 = V1
|
||||
//NV1 = V3
|
||||
//NV2 = V0
|
||||
|
||||
//NV3 = V0
|
||||
//NV4 = V3
|
||||
//NV5 = V2
|
||||
|
||||
final float[] vertices = { x, y + height, 0.0f, x + width, y + height, 0.0f, x, y, 0.0f, x, y, 0.0f, x + width, y + height, 0.0f, x + width, y, 0.0f };
|
||||
final float[] tex_vertices = { uvX, uvY, uvX + uvWidth, uvY, uvX, uvY + uvHeight, uvX, uvY + uvHeight, uvX + uvWidth, uvY, uvX + uvWidth, uvY + uvHeight };
|
||||
fbElements++;
|
||||
fbVertices.put(vertices);
|
||||
fbTextures.put(tex_vertices);
|
||||
fbColors.put(currentColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glFillColor(final float x0, final float y0, final float w1, final float h1) {
|
||||
disableTexture();
|
||||
// final float[] vertices = { x0, y0, 0.0f, x0, y0 + h1, 0.0f, x0 + w1, y0, 0.0f, x0 + w1, y0 + h1, 0.0f, };
|
||||
// final float[] tex_vertices = { 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, };
|
||||
//V0 x0, y0, 0.0f
|
||||
//V1 x0, y0 + h1, 0.0f
|
||||
//V2 x0 + w1, y0, 0.0f
|
||||
//V3 x0 + w1, y0 + h1, 0.0f
|
||||
|
||||
//NV0 = V1
|
||||
//NV1 = V3
|
||||
//NV2 = V0
|
||||
|
||||
//NV3 = V0
|
||||
//NV4 = V3
|
||||
//NV5 = V2
|
||||
|
||||
final float[] vertices = { x0, y0 + h1, 0.0f, x0 + w1, y0 + h1, 0.0f, x0, y0, 0.0f, x0, y0, 0.0f, x0 + w1, y0 + h1, 0.0f, x0 + w1, y0, 0.0f, };
|
||||
final float[] tex_vertices = { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, };
|
||||
fbElements++;
|
||||
fbVertices.put(vertices);
|
||||
fbTextures.put(tex_vertices);
|
||||
fbColors.put(currentColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glDrawStringLeft(final float x, final float y, final String text) {
|
||||
final int txtLen = text.length();
|
||||
final int[] txtArray = currentFont.getCharIndexes(text);
|
||||
int tableIndexX;
|
||||
int tableIndexY;
|
||||
for (int currentCharIndex = 0; currentCharIndex < txtLen; currentCharIndex++) {
|
||||
tableIndexX = txtArray[currentCharIndex] % currentFont.memoryWidthOfEachColumn;
|
||||
tableIndexY = (txtArray[currentCharIndex] - tableIndexX) / currentFont.memoryWidthOfEachColumn;
|
||||
glFillRect(x + (float) currentCharIndex * (float) currentFont.charW, y, currentFont.charW, currentFont.charH, tableIndexX * currentFont.charW, tableIndexY * currentFont.charH, currentFont.charW, currentFont.charH);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glDrawStringCenter(final float x, final float y, final String text) {
|
||||
glDrawStringLeft(x - currentFont.getStringWidth(text) / 2, y, text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glDrawStringRight(final float x, final float y, final String text) {
|
||||
glDrawStringLeft(x - currentFont.getStringWidth(text), y, text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glDrawCharLeft(final int x, final int y, final char ch) {
|
||||
final int index = currentFont.getCharIndex(ch);
|
||||
final int tableIndexX = index % currentFont.memoryWidthOfEachColumn;
|
||||
final int tableIndexY = (index - tableIndexX) / currentFont.memoryWidthOfEachColumn;
|
||||
glFillRect(x, y, currentFont.charW, currentFont.charH, tableIndexX * currentFont.charW, tableIndexY * currentFont.charH, currentFont.charW, currentFont.charH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glDrawCharCenter(final int x, final int y, final char ch) {
|
||||
glDrawCharLeft(x - currentFont.charW / 2, y, ch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glDrawCharRight(final int x, final int y, final char ch) {
|
||||
glDrawCharLeft(x - currentFont.charW, y, ch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryFont getCurrentFont() {
|
||||
return currentFont;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
static Texture importTexture(final GL gl, final String string) throws IOException {
|
||||
final FileInputStream f = new FileInputStream("test.png");
|
||||
final TextureData tx_dat = TextureIO.newTextureData(gl.getGLProfile(), f, false, TextureIO.PNG);
|
||||
final Texture tex = new Texture(gl, tx_dat);
|
||||
tex.setTexParameteri(gl, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
|
||||
tex.setTexParameteri(gl, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
|
||||
// tex.setTexParameteri(gl, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
|
||||
// tex.setTexParameteri(gl, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
|
||||
return tex;
|
||||
}
|
||||
|
||||
static OpenedTextureData openTexture(final String file, final boolean isResource) throws GLException, IOException {
|
||||
BufferedImage img = ImageIO.read(isResource ? JOGLRenderer.class.getResource("/" + file) : new File(file).toURI().toURL());
|
||||
File f;
|
||||
if (isResource) {
|
||||
f = Files.createTempFile("texture-", ".png").toFile();
|
||||
f.deleteOnExit();
|
||||
ImageIO.write(img, "png", f);
|
||||
} else
|
||||
f = new File(file);
|
||||
final int imgW = img.getWidth();
|
||||
final int imgH = img.getHeight();
|
||||
img = null;
|
||||
Engine.getPlatform().gc();
|
||||
return new OpenedTextureData(imgW, imgH, f, isResource);
|
||||
}
|
||||
|
||||
public static class OpenedTextureData {
|
||||
public final int w;
|
||||
public final int h;
|
||||
public final File f;
|
||||
public final boolean deleteOnExit;
|
||||
|
||||
/**
|
||||
* @param w
|
||||
* @param h
|
||||
* @param f
|
||||
* @param deleteOnExit
|
||||
*/
|
||||
public OpenedTextureData(final int w, final int h, final File f, final boolean deleteOnExit) {
|
||||
this.w = w;
|
||||
this.h = h;
|
||||
this.f = f;
|
||||
this.deleteOnExit = deleteOnExit;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static Texture importTexture(File f, final boolean deleteOnExit) throws GLException, IOException {
|
||||
final Texture tex = TextureIO.newTexture(f, false);
|
||||
if (deleteOnExit && f.exists())
|
||||
try {
|
||||
if (Engine.getPlatform().getSettings().isDebugEnabled())
|
||||
throw new IOException("Delete on exit!");
|
||||
f.delete();
|
||||
} catch (final Exception ex) {
|
||||
f.deleteOnExit();
|
||||
}
|
||||
tex.setTexParameteri(JOGLRenderer.gl, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
|
||||
tex.setTexParameteri(JOGLRenderer.gl, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
|
||||
f = null;
|
||||
return tex;
|
||||
}
|
||||
|
||||
public void initDrawCycle() {
|
||||
final boolean textureChange = precTexEnabled != currentTexEnabled || precTex != currentTex;
|
||||
if (fbVertices == null) {
|
||||
fbVertices = Buffers.newDirectFloatBuffer(JOGLRenderer.vertMax);
|
||||
fbTextures = Buffers.newDirectFloatBuffer(JOGLRenderer.texMax);
|
||||
fbColors = Buffers.newDirectFloatBuffer(JOGLRenderer.colMax);
|
||||
handlers = new int[3];
|
||||
JOGLRenderer.gl.glGenBuffers(3, handlers, 0);
|
||||
}
|
||||
startDrawSegment(false);
|
||||
if (textureChange)
|
||||
changeTexture();
|
||||
}
|
||||
|
||||
public void endDrawCycle() {
|
||||
final boolean textureChange = precTexEnabled != currentTexEnabled || precTex != currentTex;
|
||||
if (textureChange) {
|
||||
if (fbElements > 0)
|
||||
endDrawSegment();
|
||||
changeTexture();
|
||||
} else if (fbElements > 0)
|
||||
endDrawSegment();
|
||||
}
|
||||
|
||||
private void changeTexture() {
|
||||
precTexEnabled = currentTexEnabled;
|
||||
precTex = currentTex;
|
||||
if (currentTexEnabled) {
|
||||
JOGLRenderer.gl.glEnable(GL.GL_TEXTURE_2D);
|
||||
currentTex.bind(JOGLRenderer.gl);
|
||||
} else
|
||||
JOGLRenderer.gl.glDisable(GL.GL_TEXTURE_2D);
|
||||
firstBufferTexDataCall = true;
|
||||
}
|
||||
|
||||
public void startDrawSegment(final boolean continuation) {
|
||||
if (!continuation || cycleEnded)
|
||||
fbElements = 0;
|
||||
cycleEnded = false;
|
||||
}
|
||||
|
||||
private boolean precTexEnabled;
|
||||
private Texture precTex;
|
||||
private boolean cycleEnded = true;
|
||||
|
||||
public void doDrawSegment() {
|
||||
final boolean textureChange = precTexEnabled != currentTexEnabled || precTex != currentTex;
|
||||
final boolean changeRequired = fbElements >= JOGLRenderer.ELEMENTS_MAX_COUNT_PER_BUFFER;
|
||||
if (textureChange) {
|
||||
if (fbElements > 0) {
|
||||
endDrawSegment();
|
||||
startDrawSegment(false);
|
||||
}
|
||||
changeTexture();
|
||||
} else if (fbElements > 0 && changeRequired) {
|
||||
endDrawSegment();
|
||||
startDrawSegment(true);
|
||||
}
|
||||
}
|
||||
|
||||
boolean firstBufferDataCall = true;
|
||||
boolean firstBufferTexDataCall = true;
|
||||
|
||||
public void endDrawSegment() {
|
||||
fbVertices.flip();
|
||||
fbTextures.flip();
|
||||
fbColors.flip();
|
||||
|
||||
// gl.glVertexPointer(vertSize, GL.GL_FLOAT, 0, fbVertices);
|
||||
JOGLRenderer.gl.glBindBuffer(GL.GL_ARRAY_BUFFER, handlers[JOGLRenderer.vertBuffer]);
|
||||
if (firstBufferTexDataCall)
|
||||
JOGLRenderer.gl.glBufferData(GL.GL_ARRAY_BUFFER, fbVertices.limit() * Buffers.SIZEOF_FLOAT, fbVertices, GL.GL_STATIC_DRAW);
|
||||
else
|
||||
JOGLRenderer.gl.glBufferSubData(GL.GL_ARRAY_BUFFER, 0, fbVertices.limit() * Buffers.SIZEOF_FLOAT, fbVertices);
|
||||
JOGLRenderer.gl.glVertexPointer(JOGLRenderer.vertSize, GL.GL_FLOAT, 0, 0l);
|
||||
// gl.glTexCoordPointer(texSize, GL.GL_FLOAT, 0, fbTextures);
|
||||
JOGLRenderer.gl.glBindBuffer(GL.GL_ARRAY_BUFFER, handlers[JOGLRenderer.texBuffer]);
|
||||
if (firstBufferTexDataCall)
|
||||
JOGLRenderer.gl.glBufferData(GL.GL_ARRAY_BUFFER, fbTextures.limit() * Buffers.SIZEOF_FLOAT, fbTextures, GL.GL_STATIC_DRAW);
|
||||
else
|
||||
JOGLRenderer.gl.glBufferSubData(GL.GL_ARRAY_BUFFER, 0, fbTextures.limit() * Buffers.SIZEOF_FLOAT, fbTextures);
|
||||
JOGLRenderer.gl.glTexCoordPointer(JOGLRenderer.texSize, GL.GL_FLOAT, 0, 0l);
|
||||
// gl.glColorPointer(colSize, GL.GL_FLOAT, 0, fbColors);
|
||||
JOGLRenderer.gl.glBindBuffer(GL.GL_ARRAY_BUFFER, handlers[JOGLRenderer.colBuffer]);
|
||||
if (firstBufferTexDataCall)
|
||||
JOGLRenderer.gl.glBufferData(GL.GL_ARRAY_BUFFER, fbColors.limit() * Buffers.SIZEOF_FLOAT, fbColors, GL.GL_STATIC_DRAW);
|
||||
else
|
||||
JOGLRenderer.gl.glBufferSubData(GL.GL_ARRAY_BUFFER, 0, fbColors.limit() * Buffers.SIZEOF_FLOAT, fbColors);
|
||||
JOGLRenderer.gl.glColorPointer(JOGLRenderer.colSize, GL.GL_FLOAT, 0, 0l);
|
||||
|
||||
fbVertices.limit(JOGLRenderer.vertMax);
|
||||
fbTextures.limit(JOGLRenderer.texMax);
|
||||
fbColors.limit(JOGLRenderer.colMax);
|
||||
JOGLRenderer.gl.glDrawArrays(GL.GL_TRIANGLES, 0, fbElements * JOGLRenderer.ELEMENT_VERTICES_COUNT);
|
||||
//gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, fbElements * ELEMENT_VERTICES_COUNT);
|
||||
firstBufferDataCall = false;
|
||||
firstBufferTexDataCall = false;
|
||||
cycleEnded = true;
|
||||
|
||||
// deleteBuffer(fbVertices);
|
||||
// deleteBuffer(txVertices);
|
||||
// deleteBuffer(colVertices);
|
||||
// fbVertices = null;
|
||||
// txVertices = null;
|
||||
// colVertices = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void glClearSkin() {
|
||||
if (currentTex != null) {
|
||||
currentTex = null;
|
||||
doDrawSegment();
|
||||
}
|
||||
}
|
||||
|
||||
void disableTexture() {
|
||||
currentTexEnabled = false;
|
||||
doDrawSegment();
|
||||
}
|
||||
|
||||
void enableTexture() {
|
||||
currentTexEnabled = true;
|
||||
doDrawSegment();
|
||||
}
|
||||
|
||||
void useTexture(final Texture t, final float w, final float h) {
|
||||
currentTex = t;
|
||||
currentTexWidth = w;
|
||||
currentTexHeight = h;
|
||||
enableTexture();
|
||||
}
|
||||
}
|
@ -1,75 +1,75 @@
|
||||
package it.cavallium.warppi.gui.graphicengine.impl.jogl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import com.jogamp.opengl.GLException;
|
||||
import com.jogamp.opengl.util.texture.Texture;
|
||||
|
||||
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
|
||||
import it.cavallium.warppi.gui.graphicengine.Skin;
|
||||
import it.cavallium.warppi.gui.graphicengine.impl.jogl.JOGLRenderer.OpenedTextureData;
|
||||
|
||||
public class JOGLSkin implements Skin {
|
||||
|
||||
public Texture t;
|
||||
public int w;
|
||||
public int h;
|
||||
|
||||
private String texturePath;
|
||||
private boolean initialized = false;
|
||||
private boolean isResource;
|
||||
|
||||
JOGLSkin(final GraphicEngine d, final String file) throws IOException {
|
||||
load(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(final String file) throws IOException {
|
||||
final boolean isResource = !Files.exists(Paths.get(file));
|
||||
if (isResource && this.getClass().getClassLoader().getResource(file) == null)
|
||||
throw new IOException("File '" + file + "' not found!");
|
||||
texturePath = file;
|
||||
this.isResource = isResource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(final GraphicEngine d) {
|
||||
try {
|
||||
final OpenedTextureData i = JOGLRenderer.openTexture(texturePath, isResource);
|
||||
t = JOGLRenderer.importTexture(i.f, i.deleteOnExit);
|
||||
w = i.w;
|
||||
h = i.h;
|
||||
((JOGLEngine) d).registerTexture(t);
|
||||
initialized = true;
|
||||
} catch (GLException | IOException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void use(final GraphicEngine d) {
|
||||
if (!initialized)
|
||||
initialize(d);
|
||||
final JOGLRenderer r = (JOGLRenderer) d.getRenderer();
|
||||
r.useTexture(t, w, h);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInitialized() {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkinWidth() {
|
||||
return w;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkinHeight() {
|
||||
return h;
|
||||
}
|
||||
|
||||
}
|
||||
package it.cavallium.warppi.gui.graphicengine.impl.jogl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import com.jogamp.opengl.GLException;
|
||||
import com.jogamp.opengl.util.texture.Texture;
|
||||
|
||||
import it.cavallium.warppi.gui.graphicengine.GraphicEngine;
|
||||
import it.cavallium.warppi.gui.graphicengine.Skin;
|
||||
import it.cavallium.warppi.gui.graphicengine.impl.jogl.JOGLRenderer.OpenedTextureData;
|
||||
|
||||
public class JOGLSkin implements Skin {
|
||||
|
||||
public Texture t;
|
||||
public int w;
|
||||
public int h;
|
||||
|
||||
private String texturePath;
|
||||
private boolean initialized = false;
|
||||
private boolean isResource;
|
||||
|
||||
JOGLSkin(final GraphicEngine d, final String file) throws IOException {
|
||||
load(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(final String file) throws IOException {
|
||||
final boolean isResource = !Files.exists(Paths.get(file));
|
||||
if (isResource && this.getClass().getClassLoader().getResource(file) == null)
|
||||
throw new IOException("File '" + file + "' not found!");
|
||||
texturePath = file;
|
||||
this.isResource = isResource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(final GraphicEngine d) {
|
||||
try {
|
||||
final OpenedTextureData i = JOGLRenderer.openTexture(texturePath, isResource);
|
||||
t = JOGLRenderer.importTexture(i.f, i.deleteOnExit);
|
||||
w = i.w;
|
||||
h = i.h;
|
||||
((JOGLEngine) d).registerTexture(t);
|
||||
initialized = true;
|
||||
} catch (GLException | IOException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void use(final GraphicEngine d) {
|
||||
if (!initialized)
|
||||
initialize(d);
|
||||
final JOGLRenderer r = (JOGLRenderer) d.getRenderer();
|
||||
r.useTexture(t, w, h);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInitialized() {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkinWidth() {
|
||||
return w;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkinHeight() {
|
||||
return h;
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -12,6 +12,7 @@ import it.cavallium.warppi.math.functions.Division;
|
||||
import it.cavallium.warppi.math.functions.Number;
|
||||
import it.cavallium.warppi.math.rules.Rule;
|
||||
import it.cavallium.warppi.math.rules.RuleType;
|
||||
import it.cavallium.warppi.util.Utils;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
|
||||
/**
|
||||
@ -46,11 +47,15 @@ public class NumberRule implements Rule {
|
||||
final MathContext mathContext = f.getMathContext();
|
||||
if (mathContext.exactMode)
|
||||
if (((Number) f).isInteger() == false) {
|
||||
final Number divisor = new Number(mathContext, BigInteger.TEN.pow(((Number) f).getNumberOfDecimalPlaces()));
|
||||
final Function number = new Number(mathContext, ((Number) f).getTerm().multiply(divisor.getTerm()));
|
||||
final Function div = new Division(mathContext, number, divisor);
|
||||
result.add(div);
|
||||
return result;
|
||||
final int decimalPlaces = ((Number) f).getNumberOfDecimalPlaces();
|
||||
final int decimalDigits = decimalPlaces + 1;
|
||||
if (decimalDigits < Utils.maxAutoFractionDigits) {
|
||||
final Number divisor = new Number(mathContext, BigInteger.TEN.pow(decimalPlaces));
|
||||
final Function number = new Number(mathContext, ((Number) f).getTerm().multiply(divisor.getTerm()));
|
||||
final Function div = new Division(mathContext, number, divisor);
|
||||
result.add(div);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
Loading…
Reference in New Issue
Block a user