WarpPI/desktop/src/main/java/it/cavallium/warppi/gui/graphicengine/impl/swing/SwingRenderer.java

354 lines
12 KiB
Java

package it.cavallium.warppi.gui.graphicengine.impl.swing;
import java.awt.FontMetrics;
import it.cavallium.warppi.StaticVars;
import it.cavallium.warppi.gui.graphicengine.BinaryFont;
import it.cavallium.warppi.gui.graphicengine.Renderer;
import it.cavallium.warppi.gui.graphicengine.impl.common.RFTFont;
public class SwingRenderer implements Renderer {
public int clearcolor = 0xFFc5c2af;
public SwingFont currentFont;
public SwingSkin currentSkin;
public int color = 0xFF000000;
public int[] size = new int[] { 1, 1 };
static int[] canvas2d = new int[1];
public SwingRenderer() {
}
@Override
public void glColor3i(final int r, final int gg, final int b) {
glColor4i(r, gg, b, 255);
}
@Override
public void glColor(final int c) {
color = c & 0xFFFFFFFF;
}
@Override
public void glClearColor(final int c) {
clearcolor = c & 0xFFFFFFFF;
}
@Override
public void glColor4i(final int red, final int green, final int blue, final int alpha) {
color = (alpha << 24) + (red << 16) + (green << 8) + blue;
}
@Override
public void glClearColor4i(final int red, final int green, final int blue, final int alpha) {
clearcolor = (alpha << 24) + (red << 16) + (green << 8) + blue;
}
@Override
public void glClearColor4f(final float red, final float green, final float blue, final float alpha) {
clearcolor = ((int) (alpha * 255) << 24) + ((int) (red * 255) << 16) + ((int) (green * 255) << 8) + (int) (blue * 255);
}
@Override
public void glClear(final int screenWidth, final int screenHeight) {
for (int x = 0; x < screenWidth; x++)
for (int y = 0; y < screenHeight; y++) {
final int index = x + y * size[0];
if (index >= 0 && index < SwingRenderer.canvas2d.length)
SwingRenderer.canvas2d[index] = clearcolor;
}
}
private void glDrawSkin(int x0, int y0, final int x1, final int y1, int s0, int t0, int s1, int t1,
final boolean transparent) {
final double incrementX = Math.abs((double) (x1 - x0) / (double) (s1 - s0));
final double incrementY = Math.abs((double) (y1 - y0) / (double) (t1 - t0));
final boolean flippedX = (x1 - x0) / (s1 - s0) < 0;
final boolean flippedY = (y1 - y0) / (t1 - t0) < 0;
int oldColor;
int newColor;
final int onex = s0 <= s1 ? 1 : -1;
final int oney = t0 <= t1 ? 1 : -1;
int width = 0;
int height = 0;
if (onex == -1) {
final int s00 = s0;
s0 = s1;
s1 = s00;
width = s1 - s0;
}
if (oney == -1) {
final int t00 = t0;
t0 = t1;
t1 = t00;
height = t1 - t0;
}
if (x0 >= size[0] || y0 >= size[0])
return;
if (x0 + width >= size[0])
s1 = size[0] - x0 + s0;
if (y0 + height >= size[1])
t1 = size[1] - y0 + t0;
if (x0 < 0) {
if (onex == -1) {
width += x0;
s1 += x0 + 1;
} else
s0 -= x0;
x0 = 0;
}
if (y0 < 0) {
if (oney == -1) {
height += y0;
t1 += y0 + 1;
} else
t0 -= y0;
y0 = 0;
}
for (double pixelX = 0; pixelX < x1 - x0; pixelX++)
for (double pixelY = 0; pixelY < y1 - y0; pixelY++) {
final int index = (int) (x0 + pixelX + (y0 + pixelY) * size[0]);
if (index >= 0 && index < SwingRenderer.canvas2d.length && pixelX < size[0]) {
final int texx = (int) (pixelX / incrementX);
final int texy = (int) (pixelY / incrementY);
int expX = 0;
int expY = 0;
if (incrementX < 1)
expX = (int) Math.round(1d / incrementX / 2d);
if (incrementY < 1)
expY = (int) Math.round(1d / incrementY / 2d);
final int[] newColors = new int[(1 + expX * 2) * (1 + expY * 2)];
for (int expXi = -expX; expXi <= expX; expXi++)
for (int expYi = -expY; expYi <= expY; expYi++) {
final int skinIndex = (int) (s0 + (texx * (flippedX ? -1d : 1d) + (flippedX ? -(s0 - s1) - 1 : 0) + expXi) + (t0 + (texy * (flippedY ? -1d : 1d) + (flippedY ? -(t0 - t1) - 1 : 0) + expYi)) * currentSkin.skinSize[0]);
final int idx = expXi + expX + (expYi + expY) * (1 + expY * 2);
if (idx >= 0 && idx < newColors.length)
newColors[idx] = getSkinColorAt(currentSkin.skinData, skinIndex);
}
newColor = joinColors(newColors);
if (index >= 0 && index < SwingRenderer.canvas2d.length) {
if (transparent) {
oldColor = SwingRenderer.canvas2d[index];
final float a2 = (newColor >> 24 & 0xFF) / 255f;
final float a1 = 1f - a2;
final int r = (int) ((oldColor >> 16 & 0xFF) * a1 + (newColor >> 16 & 0xFF) * a2);
final int g = (int) ((oldColor >> 8 & 0xFF) * a1 + (newColor >> 8 & 0xFF) * a2);
final int b = (int) ((oldColor & 0xFF) * a1 + (newColor & 0xFF) * a2);
newColor = 0xFF000000 | r << 16 | g << 8 | b;
}
SwingRenderer.canvas2d[index] = stackColors(SwingRenderer.canvas2d[index], newColor);
}
}
}
}
private int joinColors(final int[] newColors) {
int a = 0;
int r = 0;
int g = 0;
int b = 0;
for (final int newColor : newColors) {
a += newColor >> 24 & 0xFF;
r += newColor >> 16 & 0xFF;
g += newColor >> 8 & 0xFF;
b += newColor & 0xFF;
}
return a / newColors.length << 24 | r / newColors.length << 16 | g / newColors.length << 8 | b / newColors.length;
}
private int stackColors(final int... color) {
double a = 0;
double r = 0;
double g = 0;
double b = 0;
for (final int newColor : color) {
final double alpha = (newColor >> 24 & 0xFF) / 255d;
a = a * (1d - alpha) + (newColor >> 24 & 0xFF) * alpha;
r = r * (1d - alpha) + (newColor >> 16 & 0xFF) * alpha;
g = g * (1d - alpha) + (newColor >> 8 & 0xFF) * alpha;
b = b * (1d - alpha) + (newColor & 0xFF) * alpha;
}
return (int) a << 24 | (int) r << 16 | (int) g << 8 | (int) b;
}
private int getSkinColorAt(final int[] skinData, final int skinIndex) {
int newColor = 0;
if (skinIndex >= 0 && skinIndex < skinData.length) {
newColor = skinData[skinIndex];
final int a = (int) ((newColor >> 24 & 0xFF) * ((double) (color >> 24 & 0xFF) / (double) 0xFF));
final int r = (int) ((newColor >> 16 & 0xFF) * ((double) (color >> 16 & 0xFF) / (double) 0xFF));
final int g = (int) ((newColor >> 8 & 0xFF) * ((double) (color >> 8 & 0xFF) / (double) 0xFF));
final int b = (int) ((newColor & 0xFF) * ((double) (color & 0xFF) / (double) 0xFF));
newColor = a << 24 | r << 16 | g << 8 | b;
}
return newColor;
}
@Override
public void glDrawLine(float x0, float y0, float x1, float y1) {
final int ix0 = (int) x0;
final int ix1 = (int) x1;
final int iy0 = (int) y0;
final int iy1 = (int) y1;
if (ix0 >= size[0] || iy0 >= size[0])
return;
if (iy0 == iy1) {
for (int x = 0; x <= ix1 - ix0; x++)
if (ix0 + x < size[0] & iy0 < size[1])
SwingRenderer.canvas2d[ix0 + x + iy0 * size[0]] = stackColors(SwingRenderer.canvas2d[ix0 + x + iy0 * size[0]], color);
} else if (ix0 == ix1) {
for (int y = 0; y <= iy1 - iy0; y++)
if (ix0 < size[0] & iy0 + y < size[1])
SwingRenderer.canvas2d[ix0 + (iy0 + y) * size[0]] = stackColors(SwingRenderer.canvas2d[ix0 + (iy0 + y) * size[0]], color);
} else {
final int m = (iy1 - iy0) / (ix1 - ix0);
for (int texx = 0; texx <= ix1 - ix0; texx++)
if (ix0 + texx < size[0] && iy0 + m * texx < size[1])
if (ix0 + texx < size[0] & iy0 + m * texx < size[1])
SwingRenderer.canvas2d[ix0 + texx + (iy0 + m * texx) * size[0]] = stackColors(SwingRenderer.canvas2d[ix0 + texx + (iy0 + m * texx) * size[0]], color);
}
}
@Override
public void glFillRect(final float x, final float y, final float width, final float height, final float uvX,
final float uvY, final float uvWidth, final float uvHeight) {
if (currentSkin != null)
glDrawSkin((int) x, (int) y, (int) (x + width), (int) (y + height), (int) uvX, (int) uvY, (int) (uvWidth + uvX), (int) (uvHeight + uvY), true);
else
glFillColor(x, y, width, height);
}
@Override
public void glFillColor(float x, float y, final float width, final float height) {
final int ix = (int) x;
final int iy = (int) y;
final int iw = (int) width;
final int ih = (int) height;
int x0 = ix;
int y0 = iy;
int x1 = ix + iw;
int y1 = iy + ih;
if (ix >= size[0] || iy >= size[0])
return;
if (x0 < 0)
x0 = 0;
if (x1 >= size[0])
x1 = size[0];
if (y0 < 0)
y0 = 0;
if (y1 >= size[1])
y1 = size[1];
final int sizeW = size[0];
for (int px = x0; px < x1; px++)
for (int py = y0; py < y1; py++) {
final int idx = px + py * sizeW;
if (px < sizeW && idx >= 0 && idx < SwingRenderer.canvas2d.length)
SwingRenderer.canvas2d[idx] = stackColors(SwingRenderer.canvas2d[idx], color);
}
}
@Override
public void glDrawStringLeft(float x, float y, final String textString) {
final int ix = (int) x;
final int iy = (int) y;
final int[] text = currentFont.getCharIndexes(textString);
final int[] screen = SwingRenderer.canvas2d;
final int[] screenSize = size;
final int screenLength = screen.length;
int screenPos = 0;
int currentInt;
int currentIntBitPosition;
int bitData;
int cpos;
int j;
final int l = text.length;
for (int i = 0; i < l; i++) {
cpos = i * currentFont.charW;
final int charIndex = text[i];
for (int dy = 0; dy < currentFont.charH; dy++)
for (int dx = 0; dx < currentFont.charW; dx++) {
j = ix + cpos + dx;
if (j > 0 & j < screenSize[0]) {
final int bit = dx + dy * currentFont.charW;
currentInt = (int) (Math.floor(bit) / RFTFont.intBits);
currentIntBitPosition = bit - currentInt * RFTFont.intBits;
final int charIdx = charIndex * currentFont.charIntCount + currentInt;
if (charIdx >= 0 && charIdx < currentFont.chars32.length) {
bitData = currentFont.chars32[charIdx] >> currentIntBitPosition & 1;
screenPos = ix + cpos + dx + (iy + dy) * screenSize[0];
if (bitData == 1 & screenLength > screenPos & screenPos >= 0)
screen[screenPos] = stackColors(screen[screenPos], color);
}
}
}
}
}
@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);
}
@Deprecated
public int glGetFontWidth(final FontMetrics fm, final String text) {
return fm.stringWidth(text);
}
@Deprecated
public int glGetCurrentFontHeight() {
return currentFont.charH;
}
@Override
public int glGetClearColor() {
return clearcolor;
}
@Override
public BinaryFont getCurrentFont() {
return currentFont;
}
@Override
public void glColor3f(final float red, final float green, final float blue) {
glColor3i((int) (red * 255f), (int) (green * 255f), (int) (blue * 255f));
}
@Override
public void glColor4f(final float red, final float green, final float blue, final float alpha) {
glColor4i((int) (red * 255f), (int) (green * 255f), (int) (blue * 255f), (int) (alpha * 255f));
}
@Override
public void glClearSkin() {
currentSkin = null;
}
@Override
public void glDrawCharLeft(final int x, final int y, final char ch) {
glDrawStringLeft(x, y, ch + "");
}
@Override
public void glDrawCharCenter(final int x, final int y, final char ch) {
glDrawStringCenter(x, y, ch + "");
}
@Override
public void glDrawCharRight(final int x, final int y, final char ch) {
glDrawStringRight(x, y, ch + "");
}
}