WarpPI/src/main/java/org/warp/picalculator/gui/graphicengine/gpu/GPURenderer.java

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;
}
}