Finishing more work on textures/fonts
This commit is contained in:
parent
cc5267378d
commit
30e63d79a2
|
@ -14,6 +14,7 @@ import speiger.src.coreengine.rendering.input.devices.FileDrop;
|
|||
import speiger.src.coreengine.rendering.input.devices.Joystick;
|
||||
import speiger.src.coreengine.rendering.input.devices.Keyboard;
|
||||
import speiger.src.coreengine.rendering.input.devices.Mouse;
|
||||
import speiger.src.coreengine.rendering.input.events.KeyEvent;
|
||||
import speiger.src.coreengine.rendering.input.window.Window;
|
||||
import speiger.src.coreengine.rendering.input.window.WindowManager;
|
||||
import speiger.src.coreengine.rendering.models.buffers.BufferAttribute;
|
||||
|
@ -23,10 +24,12 @@ import speiger.src.coreengine.rendering.shader.SimpleShader;
|
|||
import speiger.src.coreengine.rendering.shader.uniform.base.TextureUniform;
|
||||
import speiger.src.coreengine.rendering.tesselation.buffer.VertexBuilder;
|
||||
import speiger.src.coreengine.rendering.tesselation.format.VertexTypes;
|
||||
import speiger.src.coreengine.rendering.textures.custom.Drawable;
|
||||
import speiger.src.coreengine.rendering.textures.custom.DynamicTexture;
|
||||
import speiger.src.coreengine.rendering.utils.GLStateTracker;
|
||||
import speiger.src.coreengine.rendering.utils.values.GLDataType;
|
||||
import speiger.src.coreengine.rendering.utils.values.GLMode;
|
||||
import speiger.src.coreengine.rendering.utils.values.textures.GLTextureFormat;
|
||||
import speiger.src.coreengine.utils.eventbus.EventBus;
|
||||
import speiger.src.coreengine.utils.helpers.IOUtils;
|
||||
|
||||
|
@ -67,6 +70,17 @@ public class NewInputTest {
|
|||
texture.process(true);
|
||||
window.visible(true);
|
||||
|
||||
bus.register(KeyEvent.Key.class, T -> {
|
||||
if(T.key() == GLFW.GLFW_KEY_T) {
|
||||
T.cancel();
|
||||
texture.bind();
|
||||
Drawable drawable = new Drawable(GLTextureFormat.RGBA, 8, 8);
|
||||
drawable.fill(0, 0, 8, 8, 255, 255, 0, 255);
|
||||
drawable.upload(6, 6, 2, 2, 4, 4);
|
||||
drawable.close();
|
||||
}
|
||||
});
|
||||
|
||||
VertexBuilder builder = new VertexBuilder(255);
|
||||
builder.start(GLMode.TRIANGLES, VertexTypes.TESTING);
|
||||
builder.pos(-0.5F, -0.5F, 0).tex(0F, 1F).rgba(-1).endVertex();
|
||||
|
|
|
@ -99,6 +99,7 @@ public class TextureMetadata {
|
|||
for(int i = 0,m=list.size();i<m;i++) {
|
||||
if(BitUtil.intKey(list.getLong(i)) == id) {
|
||||
list.removeLong(i--);
|
||||
m--;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
|
|
|
@ -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 xOff = 0;xOff<width;xOff++) {
|
||||
for(int yOff = 0;yOff<height;yOff++) {
|
||||
MemoryUtil.memSet(offset(x, y+yOff), data, width * 4L);
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,6 +99,7 @@ public class EventBus
|
|||
}
|
||||
|
||||
protected Listeners getListeners(Class<? extends Event> event) {
|
||||
//TODO this is abusing undefined behavior!
|
||||
return listeners.computeIfAbsent(event, T -> {
|
||||
if(T == Event.class) return new Listeners();
|
||||
else return new Listeners(getListeners(castClass(event.getSuperclass())));
|
||||
|
|
Loading…
Reference in New Issue