294 lines
9.5 KiB
Java
Executable File
294 lines
9.5 KiB
Java
Executable File
package org.warp.picalculator.gui.graphicengine.gpu;
|
|
|
|
import java.awt.image.BufferedImage;
|
|
import java.io.ByteArrayInputStream;
|
|
import java.io.ByteArrayOutputStream;
|
|
import java.io.File;
|
|
import java.io.FileInputStream;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.nio.Buffer;
|
|
import java.nio.FloatBuffer;
|
|
|
|
import javax.imageio.ImageIO;
|
|
|
|
import org.warp.picalculator.gui.graphicengine.BinaryFont;
|
|
import org.warp.picalculator.gui.graphicengine.Renderer;
|
|
|
|
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;
|
|
|
|
public class GPURenderer implements Renderer {
|
|
|
|
public static GL2ES1 gl;
|
|
|
|
private final DeallocationHelper deallocationHelper = new DeallocationHelper();
|
|
FloatBuffer fbVertices;
|
|
FloatBuffer txVertices;
|
|
FloatBuffer colVertices;
|
|
int fbElements;
|
|
|
|
float[] currentColor = new float[16];
|
|
float[] currentClearColorARGBf = new float[] { 1f, 197f / 255f, 194f / 255f, 175f / 255f };
|
|
boolean currentTexEnabled;
|
|
Texture currentTex;
|
|
float currentTexWidth;
|
|
float currentTexHeight;
|
|
|
|
GPUFont currentFont;
|
|
|
|
@Override
|
|
public void glColor3i(int r, int gg, 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, };
|
|
}
|
|
|
|
@Override
|
|
public void glColor3f(float red, float gre, 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, };
|
|
}
|
|
|
|
@Override
|
|
public void glColor4f(float red, float gre, float blu, float alp) {
|
|
currentColor = new float[] { red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, red, gre, blu, alp, };
|
|
}
|
|
|
|
@Override
|
|
public void glColor(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(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(int r, int g, int b, 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, };
|
|
}
|
|
|
|
@Override
|
|
public void glClearColor4i(int red, int green, int blue, 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(float red, float green, float blue, float alpha) {
|
|
currentClearColorARGBf = new float[] { alpha, red, green, blue };
|
|
}
|
|
|
|
@Override
|
|
public void glClear(int screenWidth, int screenHeight) {
|
|
glColor(glGetClearColor());
|
|
glFillColor(0, 0, screenWidth, screenHeight);
|
|
}
|
|
|
|
@Override
|
|
public void glDrawLine(float x0, float y0, float x1, float y1) {
|
|
glFillColor(x0, y0, x1 - x0 + 1, y1 - y0 + 1);
|
|
}
|
|
|
|
@Override
|
|
public void glFillRect(float x, float y, float width, float height, float uvX, float uvY, float uvWidth,
|
|
float uvHeight) {
|
|
enableTexture();
|
|
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, };
|
|
fbElements++;
|
|
fbVertices.put(vertices);
|
|
txVertices.put(tex_vertices);
|
|
colVertices.put(currentColor);
|
|
}
|
|
|
|
@Override
|
|
public void glFillColor(float x0, float y0, float w1, 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, };
|
|
fbElements++;
|
|
fbVertices.put(vertices);
|
|
txVertices.put(tex_vertices);
|
|
colVertices.put(currentColor);
|
|
}
|
|
|
|
@Override
|
|
public void glDrawStringLeft(float x, float y, 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(float x, float y, String text) {
|
|
glDrawStringLeft(x - (currentFont.getStringWidth(text) / 2), y, text);
|
|
}
|
|
|
|
@Override
|
|
public void glDrawStringRight(float x, float y, String text) {
|
|
glDrawStringLeft(x - currentFont.getStringWidth(text), y, text);
|
|
}
|
|
|
|
@Override
|
|
public void glDrawCharLeft(int x, int y, 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(int x, int y, char ch) {
|
|
glDrawCharLeft(x - (currentFont.charW / 2), y, ch);
|
|
}
|
|
|
|
@Override
|
|
public void glDrawCharRight(int x, int y, char ch) {
|
|
glDrawCharLeft(x - currentFont.charW, y, ch);
|
|
}
|
|
|
|
@Override
|
|
public BinaryFont getCurrentFont() {
|
|
return currentFont;
|
|
}
|
|
|
|
static Texture importTexture(GL gl, 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 BufferedImage openTexture(String file) throws GLException, IOException {
|
|
return ImageIO.read(GPURenderer.class.getClassLoader().getResource(file));
|
|
}
|
|
|
|
static Texture importTexture(BufferedImage img) throws GLException, IOException {
|
|
final ByteArrayOutputStream os = new ByteArrayOutputStream();
|
|
ImageIO.write(img, "png", os);
|
|
final InputStream fis = new ByteArrayInputStream(os.toByteArray());
|
|
final Texture tex = TextureIO.newTexture(fis, false, TextureIO.PNG);
|
|
tex.setTexParameteri(gl, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
|
|
tex.setTexParameteri(gl, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
|
|
return tex;
|
|
}
|
|
|
|
@Override
|
|
public void glClearSkin() {
|
|
if (currentTex != null) {
|
|
currentTex = null;
|
|
endDrawCycle();
|
|
startDrawCycle();
|
|
}
|
|
}
|
|
|
|
public void startDrawCycle() {
|
|
if (fbVertices == null) {
|
|
fbVertices = Buffers.newDirectFloatBuffer(3 * 4);
|
|
txVertices = Buffers.newDirectFloatBuffer(2 * 4);
|
|
colVertices = Buffers.newDirectFloatBuffer(4 * 4);
|
|
}
|
|
fbElements = 0;
|
|
}
|
|
|
|
private boolean precTexEnabled;
|
|
private Texture precTex;
|
|
|
|
public void endDrawCycle() {
|
|
fbVertices.rewind();
|
|
txVertices.rewind();
|
|
colVertices.rewind();
|
|
|
|
gl.glColorPointer(4, GL.GL_FLOAT, 0, colVertices);
|
|
gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, txVertices);
|
|
gl.glVertexPointer(3, GL.GL_FLOAT, 0, fbVertices);
|
|
|
|
if (precTexEnabled != currentTexEnabled | precTex != currentTex) {
|
|
precTexEnabled = currentTexEnabled;
|
|
precTex = currentTex;
|
|
if (currentTexEnabled) {
|
|
gl.glEnable(GL.GL_TEXTURE_2D);
|
|
currentTex.bind(gl);
|
|
} else {
|
|
gl.glDisable(GL.GL_TEXTURE_2D);
|
|
}
|
|
}
|
|
|
|
gl.glDrawArrays(GL.GL_TRIANGLE_STRIP, 0, fbElements * 4);
|
|
|
|
// deleteBuffer(fbVertices);
|
|
// deleteBuffer(txVertices);
|
|
// deleteBuffer(colVertices);
|
|
// fbVertices = null;
|
|
// txVertices = null;
|
|
// colVertices = null;
|
|
}
|
|
|
|
public void deleteBuffer(final Buffer realNioBuffer) {
|
|
if (deallocationHelper != null) {
|
|
deallocationHelper.deallocate(realNioBuffer);
|
|
}
|
|
}
|
|
|
|
void disableTexture() {
|
|
endDrawCycle();
|
|
startDrawCycle();
|
|
currentTexEnabled = false;
|
|
}
|
|
|
|
void enableTexture() {
|
|
endDrawCycle();
|
|
startDrawCycle();
|
|
currentTexEnabled = true;
|
|
}
|
|
|
|
void useTexture(Texture t, float w, float h) {
|
|
enableTexture();
|
|
currentTex = t;
|
|
currentTexWidth = w;
|
|
currentTexHeight = h;
|
|
}
|
|
}
|