|
|
|
@@ -1,11 +1,17 @@
|
|
|
|
|
package speiger.src.coreengine.rendering.textures.custom;
|
|
|
|
|
|
|
|
|
|
import org.lwjgl.opengl.GL46;
|
|
|
|
|
import org.lwjgl.stb.STBImage;
|
|
|
|
|
import org.lwjgl.stb.STBTTFontinfo;
|
|
|
|
|
import org.lwjgl.stb.STBTruetype;
|
|
|
|
|
import org.lwjgl.system.MemoryUtil;
|
|
|
|
|
|
|
|
|
|
import speiger.src.coreengine.math.misc.ColorSpaces;
|
|
|
|
|
import speiger.src.coreengine.rendering.utils.GLFunctions;
|
|
|
|
|
import speiger.src.coreengine.rendering.utils.GLStateTracker;
|
|
|
|
|
import speiger.src.coreengine.rendering.utils.values.GLDataType;
|
|
|
|
|
import speiger.src.coreengine.rendering.utils.values.IGLValue;
|
|
|
|
|
import speiger.src.coreengine.rendering.utils.values.IGLValue.ITextureComponentFormat;
|
|
|
|
|
import speiger.src.coreengine.rendering.utils.values.textures.GLTextureType;
|
|
|
|
|
|
|
|
|
|
public class Drawable implements IDrawable, AutoCloseable {
|
|
|
|
|
ITextureComponentFormat format;
|
|
|
|
@@ -20,6 +26,7 @@ public class Drawable implements IDrawable, AutoCloseable {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Drawable(ITextureComponentFormat format, int width, int height, long pixels, boolean isSTB) {
|
|
|
|
|
this.format = format;
|
|
|
|
|
this.width = width;
|
|
|
|
|
this.height = height;
|
|
|
|
|
this.pixels = pixels;
|
|
|
|
@@ -55,12 +62,34 @@ public class Drawable implements IDrawable, AutoCloseable {
|
|
|
|
|
|
|
|
|
|
protected void ensureValid(int x, int y) {
|
|
|
|
|
if(x < 0 || y < 0) throw new ArrayIndexOutOfBoundsException("Index out of bounds: X=["+x+"], Y=["+y+"]");
|
|
|
|
|
if(x >= width || y >= height) throw new ArrayIndexOutOfBoundsException("Index out of bounds: X=["+x+"], Y=["+y+"], width=["+width+"], height=["+height+"]");
|
|
|
|
|
if(x > width || y > height) throw new ArrayIndexOutOfBoundsException("Index out of bounds: X=["+x+"], Y=["+y+"], width=["+width+"], height=["+height+"]");
|
|
|
|
|
if(pixels == 0L) throw new IllegalStateException("Pixel Data doesn't exist");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void upload(int texture, int level, int x, int y, int texX, int texY, int width, int height) {
|
|
|
|
|
public void drawFont(STBTTFontinfo info, int glyth, int sourceX, int sourceY, int targetX, int targetY, int width, int height, float scaleX, float scaleY) {
|
|
|
|
|
ensureValid(targetX, targetY);
|
|
|
|
|
ensureValid(targetX + width, targetY + height);
|
|
|
|
|
if(components != 1) throw new IllegalStateException("Format has to be 1 component");
|
|
|
|
|
STBTruetype.nstbtt_MakeGlyphBitmapSubpixel(info.address(), pixels + offset(targetX, targetY), width, height, width(), scaleX, scaleY, sourceX, sourceY, glyth);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void upload(int targetX, int targetY, int sourceX, int sourceY, int width, int height) {
|
|
|
|
|
upload(GLTextureType.TEXTURE_2D, 0, targetX, targetY, sourceX, sourceY, width, height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void upload(IGLValue textureType, int level, int targetX, int targetY, int sourceX, int sourceY, int width, int height) {
|
|
|
|
|
ensureValid(sourceX, sourceY);
|
|
|
|
|
ensureValid(sourceX + width, sourceY + height);
|
|
|
|
|
GLStateTracker tracker = GLStateTracker.instance();
|
|
|
|
|
tracker.unpack_row_length.set(width());
|
|
|
|
|
tracker.unpack_alignment.set(format.components());
|
|
|
|
|
tracker.unpack_skip_pixel.set(sourceX);
|
|
|
|
|
tracker.unpack_skip_rows.set(sourceY);
|
|
|
|
|
GLFunctions.upload2DSubImage(textureType, level, targetX, targetY, width, height, format, GLDataType.UNSIGNED_BYTE, pixels);
|
|
|
|
|
tracker.unpack_row_length.setDefault();
|
|
|
|
|
tracker.unpack_skip_pixel.setDefault();
|
|
|
|
|
tracker.unpack_skip_rows.setDefault();
|
|
|
|
|
tracker.unpack_alignment.setDefault();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@@ -103,8 +132,10 @@ public class Drawable implements IDrawable, AutoCloseable {
|
|
|
|
|
if(components != 4) throw new IllegalStateException("Format has to be 4 components");
|
|
|
|
|
ensureValid(x, y);
|
|
|
|
|
ensureValid(x+width, y+height);
|
|
|
|
|
for(int yOff = 0;yOff<height;yOff++) {
|
|
|
|
|
MemoryUtil.memSet(offset(x, y+yOff), data, width * 4L);
|
|
|
|
|
for(int xOff = 0;xOff<width;xOff++) {
|
|
|
|
|
for(int yOff = 0;yOff<height;yOff++) {
|
|
|
|
|
MemoryUtil.memPutInt(this.pixels + offset(x+xOff, y+yOff), data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -119,27 +150,27 @@ public class Drawable implements IDrawable, AutoCloseable {
|
|
|
|
|
public int getR(int index) {
|
|
|
|
|
if(!format.hasRed()) throw new IllegalArgumentException("Format doesn't support Red/Luminance");
|
|
|
|
|
ensureValid(index);
|
|
|
|
|
return MemoryUtil.memGetByte(index * 4L);
|
|
|
|
|
return MemoryUtil.memGetByte(index * components + format.redOffset());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public int getG(int index) {
|
|
|
|
|
if(!format.hasGreen()) throw new IllegalArgumentException("Format doesn't support Green");
|
|
|
|
|
ensureValid(index);
|
|
|
|
|
return MemoryUtil.memGetByte(index * 4L + 1L);
|
|
|
|
|
return MemoryUtil.memGetByte(index * components + format.greenOffset());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public int getB(int index) {
|
|
|
|
|
if(!format.hasBlue()) throw new IllegalArgumentException("Format doesn't support Blue");
|
|
|
|
|
ensureValid(index);
|
|
|
|
|
return MemoryUtil.memGetByte(index * 4L + 2L);
|
|
|
|
|
return MemoryUtil.memGetByte(index * components + format.blueOffset());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public int getA(int index) {
|
|
|
|
|
if(!format.hasAlpha()) throw new IllegalArgumentException("Format doesn't support Alpha");
|
|
|
|
|
ensureValid(index);
|
|
|
|
|
return MemoryUtil.memGetByte(index * 4L + 3L);
|
|
|
|
|
return MemoryUtil.memGetByte(index * components + format.alphaOffset());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|