More work on texture ports

This commit is contained in:
Speiger 2024-04-14 23:30:55 +02:00
parent 23859f9017
commit 84e84d6b26
35 changed files with 533 additions and 110 deletions

View File

@ -55,6 +55,7 @@ dependencies {
implementation "org.lwjgl:lwjgl-opengl"
implementation "org.lwjgl:lwjgl-stb"
implementation "org.lwjgl:lwjgl-nfd"
implementation "org.lwjgl:lwjgl-nanovg"
implementation "org.lwjgl:lwjgl::$lwjglNatives"
implementation "org.lwjgl:lwjgl-glfw::$lwjglNatives"
implementation "org.lwjgl:lwjgl-jemalloc::$lwjglNatives"
@ -62,6 +63,7 @@ dependencies {
implementation "org.lwjgl:lwjgl-opengl::$lwjglNatives"
implementation "org.lwjgl:lwjgl-stb::$lwjglNatives"
implementation "org.lwjgl:lwjgl-nfd::$lwjglNatives"
implementation "org.lwjgl:lwjgl-nanovg::$lwjglNatives"
//Gson
implementation 'com.google.code.gson:gson:2.8.6'

View File

@ -1,4 +1,4 @@
package speiger.src.coreengine.rendering.texturesOld.base;
package speiger.src.coreengine.assets.parsers;
import java.io.Closeable;
import java.io.IOException;
@ -13,6 +13,7 @@ import speiger.src.coreengine.assets.base.IAssetParser;
public class NativeMemoryParser implements IAssetParser<ByteBuffer> {
public static final IAssetParser<ByteBuffer> INSTANCE = new NativeMemoryParser();
@Override
public ByteBuffer parseAsset(Path path, Consumer<Closeable> autoCloser) throws IOException {
byte[] data = Files.readAllBytes(path);

View File

@ -36,8 +36,8 @@ import speiger.src.collections.objects.misc.pairs.ObjectObjectPair;
import speiger.src.coreengine.assets.AssetLocation;
import speiger.src.coreengine.math.vector.ints.Vec2i;
import speiger.src.coreengine.rendering.gui.renderer.IFontRenderer.CharInstance;
import speiger.src.coreengine.rendering.texturesOld.atlas.AtlasStitcher;
import speiger.src.coreengine.rendering.texturesOld.atlas.AtlasStitcher.Entry;
import speiger.src.coreengine.rendering.textures.custom.AtlasStitcher;
import speiger.src.coreengine.rendering.textures.custom.AtlasStitcher.Entry;
import speiger.src.coreengine.rendering.texturesOld.custom.TextureAtlas;
import speiger.src.coreengine.rendering.texturesOld.custom.TextureAtlas.AtlasEntry;
import speiger.src.coreengine.rendering.texturesOld.custom.TextureAtlas.Builder;

View File

@ -37,7 +37,7 @@ public record BufferAttribute(int index, int size, GLDataType type, boolean norm
public void unbind() { GL20.glDisableVertexAttribArray(index); }
public void applyAttribute(int stride, int offset) {
GL20.glVertexAttribPointer(index, size, type.glMode(), normal, stride, offset);
GL20.glVertexAttribPointer(index, size, type.glValue(), normal, stride, offset);
if(instancedAmount > 0) GL33.glVertexAttribDivisor(index, instancedAmount);
}
}

View File

@ -55,37 +55,37 @@ public class VertexBuffer {
}
public VertexBuffer bind() {
GL15.glBindBuffer(type.glMode(), id);
GL15.glBindBuffer(type.glValue(), id);
return this;
}
public VertexBuffer unbind() {
GL15.glBindBuffer(type.glMode(), 0);
GL15.glBindBuffer(type.glValue(), 0);
return this;
}
public VertexBuffer allocate(int totalBytes) {
this.size = totalBytes;
GL15.glBufferData(type.glMode(), totalBytes, state.glMode());
GL15.glBufferData(type.glValue(), totalBytes, state.glValue());
AllocationTracker.INSTANCE.addGPUBytes(totalBytes);
return this;
}
public VertexBuffer set(long pointer, int totalBytes) {
this.size = totalBytes;
GL15.nglBufferData(type.glMode(), totalBytes, pointer, state.glMode());
GL15.nglBufferData(type.glValue(), totalBytes, pointer, state.glValue());
AllocationTracker.INSTANCE.addGPUBytes(totalBytes);
return this;
}
public VertexBuffer fill(long pointer, int totalBytes, int offset) {
GL15.nglBufferSubData(type.glMode(), offset, totalBytes, pointer);
GL15.nglBufferSubData(type.glValue(), offset, totalBytes, pointer);
AllocationTracker.INSTANCE.addGPUBytes(totalBytes);
return this;
}
public VertexBuffer read(long pointer, int totalBytes, int offset) {
GL15.nglGetBufferSubData(type.glMode(), offset, totalBytes, pointer);
GL15.nglGetBufferSubData(type.glValue(), offset, totalBytes, pointer);
AllocationTracker.INSTANCE.addGPUBytes(totalBytes);
return this;
}
@ -139,29 +139,29 @@ public class VertexBuffer {
}
public VertexBuffer fill(int offset, byte[] data) {
GL15.glMapBuffer(type.glMode(), GL15.GL_WRITE_ONLY).position(offset).put(data);
GL15.glUnmapBuffer(type.glMode());
GL15.glMapBuffer(type.glValue(), GL15.GL_WRITE_ONLY).position(offset).put(data);
GL15.glUnmapBuffer(type.glValue());
AllocationTracker.INSTANCE.addGPUBytes(data.length);
return this;
}
public VertexBuffer fill(int offset, short[] data) {
GL15.glMapBuffer(type.glMode(), GL15.GL_WRITE_ONLY).position(offset).asShortBuffer().put(data);
GL15.glUnmapBuffer(type.glMode());
GL15.glMapBuffer(type.glValue(), GL15.GL_WRITE_ONLY).position(offset).asShortBuffer().put(data);
GL15.glUnmapBuffer(type.glValue());
AllocationTracker.INSTANCE.addGPUBytes(data.length * 2L);
return this;
}
public VertexBuffer fill(int offset, int[] data) {
GL15.glMapBuffer(type.glMode(), GL15.GL_WRITE_ONLY).position(offset).asIntBuffer().put(data);
GL15.glUnmapBuffer(type.glMode());
GL15.glMapBuffer(type.glValue(), GL15.GL_WRITE_ONLY).position(offset).asIntBuffer().put(data);
GL15.glUnmapBuffer(type.glValue());
AllocationTracker.INSTANCE.addGPUBytes(data.length * 4L);
return this;
}
public VertexBuffer fill(int offset, float[] data) {
GL15.glMapBuffer(type.glMode(), GL15.GL_WRITE_ONLY).position(offset).asFloatBuffer().put(data);
GL15.glUnmapBuffer(type.glMode());
GL15.glMapBuffer(type.glValue(), GL15.GL_WRITE_ONLY).position(offset).asFloatBuffer().put(data);
GL15.glUnmapBuffer(type.glValue());
AllocationTracker.INSTANCE.addGPUBytes(data.length * 4L);
return this;
}
@ -173,7 +173,7 @@ public class VertexBuffer {
public VertexBuffer fill(int offset, List<IntObjectPair<byte[]>> data) {
if(data.size() > 0) {
long totalInjected = 0;
ByteBuffer buffer = GL15.glMapBuffer(type.glMode(), GL15.GL_WRITE_ONLY);
ByteBuffer buffer = GL15.glMapBuffer(type.glValue(), GL15.GL_WRITE_ONLY);
for(int i = 0,m = data.size();i < m;i++) {
IntObjectPair<byte[]> entry = data.get(i);
buffer.position(entry.getIntKey() + offset);
@ -181,7 +181,7 @@ public class VertexBuffer {
totalInjected += entry.getValue().length;
}
buffer.flip();
if(!GL15.glUnmapBuffer(type.glMode())) GameLog.info("Memory Corruption?");
if(!GL15.glUnmapBuffer(type.glValue())) GameLog.info("Memory Corruption?");
AllocationTracker.INSTANCE.addGPUBytes(totalInjected);
}
return this;
@ -189,12 +189,12 @@ public class VertexBuffer {
public VertexBuffer grow(int newSize) {
if(size >= newSize) throw new IllegalArgumentException("New Size ["+newSize+"] is smaller then the buffer ["+size+"]");
ByteBuffer buffer = GL15.glMapBuffer(type.glMode(), GL15.GL_READ_ONLY);
ByteBuffer buffer = GL15.glMapBuffer(type.glValue(), GL15.GL_READ_ONLY);
if(size != buffer.remaining()) throw new IllegalStateException("Grow Function found inconsisten data: Found=["+buffer.remaining()+"], Expected=["+size+"]");
ByteBuffer newBuff = MemoryUtil.memAlloc(newSize);
MemoryUtil.memCopy(MemoryUtil.memAddress(buffer), MemoryUtil.memAddress(newBuff), size);
newBuff.position(newSize).flip();
GL15.glUnmapBuffer(type.glMode());
GL15.glUnmapBuffer(type.glValue());
AllocationTracker.INSTANCE.addGPUBytes(size);
set(MemoryUtil.memAddress(newBuff), newSize);
MemoryUtil.memFree(newBuff);
@ -203,12 +203,12 @@ public class VertexBuffer {
public VertexBuffer shrink(int newSize) {
if(size <= newSize) throw new IllegalArgumentException("New Size ["+newSize+"] is bigger then the buffer ["+size+"]");
ByteBuffer buffer = GL15.glMapBuffer(type.glMode(), GL15.GL_READ_WRITE);
ByteBuffer buffer = GL15.glMapBuffer(type.glValue(), GL15.GL_READ_WRITE);
if(size != buffer.remaining()) throw new IllegalStateException("Grow Function found inconsisten data: Found=["+buffer.remaining()+"], Expected=["+size+"]");
ByteBuffer newBuff = MemoryUtil.memAlloc(newSize);
MemoryUtil.memCopy(MemoryUtil.memAddress(buffer), MemoryUtil.memAddress(newBuff), newSize);
newBuff.position(newSize).flip();
GL15.glUnmapBuffer(type.glMode());
GL15.glUnmapBuffer(type.glValue());
AllocationTracker.INSTANCE.addGPUBytes(size);
set(MemoryUtil.memAddress(newBuff), newSize);
MemoryUtil.memFree(newBuff);

View File

@ -96,7 +96,7 @@ public abstract class ShaderProgram {
e.printStackTrace();
return -1;
}
int shaderID = GL20.glCreateShader(type.glMode());
int shaderID = GL20.glCreateShader(type.glValue());
GL20.glShaderSource(shaderID, builder);
GL20.glCompileShader(shaderID);
if(GL20.glGetShaderi(shaderID, GL20.GL_COMPILE_STATUS) == 0) {

View File

@ -1,15 +1,17 @@
package speiger.src.coreengine.rendering.textures.base;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL46;
import speiger.src.coreengine.rendering.utils.GLStateTracker;
import speiger.src.coreengine.rendering.utils.values.textures.GLTextureFormat;
import speiger.src.coreengine.rendering.utils.values.IGLValue;
import speiger.src.coreengine.rendering.utils.values.textures.GLTextureType;
public abstract class BaseTexture implements ITexture {
protected int id;
protected BaseTexture() {
this(GL11.glGenTextures());
track();
}
protected BaseTexture(int id) {
@ -17,8 +19,18 @@ public abstract class BaseTexture implements ITexture {
track();
}
protected int textureType() {
return -1;
protected void createTexture() {
this.id = GL46.glCreateTextures(textureType().glValue());
}
protected IGLValue textureType() {
return GLTextureType.TEXTURE_2D;
}
protected void removeTexture() {
if(id == 0) return;
GL11.glDeleteTextures(id);
id = 0;
}
protected void track() {
@ -36,8 +48,10 @@ public abstract class BaseTexture implements ITexture {
}
@Override
public void delete() {
GL11.glDeleteTextures(id);
public void delete(boolean untrack) {
removeTexture();
if(untrack) {
GLStateTracker.TEXTURE_TRACKER.deleteTexture(this);
}
}
}

View File

@ -1,11 +1,23 @@
package speiger.src.coreengine.rendering.textures.base;
import java.nio.ByteBuffer;
import org.lwjgl.system.MemoryUtil;
import speiger.src.coreengine.assets.AssetLocation;
import speiger.src.coreengine.assets.base.IAssetProvider;
import speiger.src.coreengine.rendering.textures.simple.DirectTexture;
import speiger.src.coreengine.rendering.textures.simple.SimpleTexture;
import speiger.src.coreengine.rendering.textures.simple.WrappedTexture;
public interface ITexture {
public int id();
public default void bind() { bind(0); }
public void bind(int unit);
public void reload();
public void delete();
public void load(IAssetProvider provider);
public default void reset() { delete(false); }
public default void delete() { delete(true); }
public void delete(boolean untrack);
public int width();
public int height();
@ -14,4 +26,24 @@ public interface ITexture {
public default float minV() { return 0F; }
public default float maxU() { return 1F; }
public default float maxV() { return 1F; }
public static ITexture direct(int width, int height, ByteBuffer buffer, TextureMetadata metadata) {
return direct(width, height, MemoryUtil.memAddress(buffer), metadata);
}
public static ITexture direct(int width, int height, long data, TextureMetadata metadata) {
return new DirectTexture(width, height, data, metadata);
}
public static ITexture simple(AssetLocation location, TextureMetadata metadata) {
return new SimpleTexture(location, metadata);
}
public static ITexture wrap(ITexture texture) {
return texture instanceof WrappedTexture ? texture : wrap(texture.id());
}
public static ITexture wrap(int id) {
return new WrappedTexture(id);
}
}

View File

@ -14,6 +14,8 @@ public class TextureMetadata {
int internalFormat;
int externalFormat;
int dataFormat;
boolean isSTBData = true;
boolean mipmapping = true;
LongList arguments = new LongArrayList();
private TextureMetadata() {}
@ -32,6 +34,8 @@ public class TextureMetadata {
public int getInternalFormat() { return internalFormat; }
public int getExternalFormat() { return externalFormat; }
public int getDataFormat() { return dataFormat; }
public boolean isSTBData() { return isSTBData; }
public boolean generateMipMappings() { return mipmapping; }
public Builder copy() { return new Builder(this); }
public static Builder builder() { return new Builder(); }
@ -44,12 +48,14 @@ public class TextureMetadata {
metadata.internalFormat = data.internalFormat;
metadata.externalFormat = data.externalFormat;
metadata.dataFormat = data.dataFormat;
metadata.isSTBData = data.isSTBData;
metadata.mipmapping = data.mipmapping;
metadata.arguments.addAll(data.arguments);
}
public Builder internalFormat(ITextureFormatType type) {
if(!type.internal()) throw new IllegalArgumentException("The GL_Type ["+type.glMode()+"] isn't supported in the internal format");
return internalFormat(type.glMode());
if(!type.internal()) throw new IllegalArgumentException("The GL_Type ["+type.glValue()+"] isn't supported in the internal format");
return internalFormat(type.glValue());
}
public Builder internalFormat(int glValue) {
@ -58,7 +64,7 @@ public class TextureMetadata {
}
public Builder externalFormat(ITextureFormatType type) {
return externalFormat(type.glMode());
return externalFormat(type.glValue());
}
public Builder externalFormat(int glValue) {
@ -67,7 +73,7 @@ public class TextureMetadata {
}
public Builder dataFormat(IGLDataType type) {
return dataFormat(type.glMode());
return dataFormat(type.glValue());
}
public Builder dataFormat(int glValue) {
@ -75,8 +81,18 @@ public class TextureMetadata {
return this;
}
public Builder stbData(boolean value) {
metadata.isSTBData = value;
return this;
}
public Builder mipmapping(boolean value) {
metadata.mipmapping = value;
return this;
}
public Builder removeArgument(ITextureParameter id) {
return removeArgument(id.glMode());
return removeArgument(id.glValue());
}
public Builder removeArgument(int id) {
@ -90,12 +106,12 @@ public class TextureMetadata {
}
public Builder arguement(ITextureParameter parameter, IGLValue value) {
return argument(parameter, value.glMode());
return argument(parameter, value.glValue());
}
public Builder argument(ITextureParameter parameter, int value) {
if(!parameter.isValid(value)) throw new IllegalArgumentException("Value ["+value+"] isn't supported for GL Function ["+parameter.glMode()+"], only int functions are supported with this");
return argument(parameter.glMode(), value);
if(!parameter.isValid(value)) throw new IllegalArgumentException("Value ["+value+"] isn't supported for GL Function ["+parameter.glValue()+"], only int functions are supported with this");
return argument(parameter.glValue(), value);
}
public Builder argument(int id, int value) {

View File

@ -1,7 +1,5 @@
package speiger.src.coreengine.rendering.textures.base;
import java.util.function.Predicate;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.lists.ObjectList;
import speiger.src.collections.objects.sets.ObjectLinkedOpenHashSet;
@ -26,6 +24,7 @@ public class TextureTracker implements ISimpleRealodableAsset, IManagedAsset {
public void register(ITexture texture, boolean reloadable) {
textures.add(texture);
if(reloadable) this.reloadable.add(texture);
texture.load(provider);
}
public void deleteTexture(ITexture texture) {
@ -35,18 +34,22 @@ public class TextureTracker implements ISimpleRealodableAsset, IManagedAsset {
@Override
public void onAssetsReloaded(IAssetProvider provider) {
textures.filter(Predicate.not(reloadable::contains)).forEach(ITexture::delete);
textures.forEach(ITexture::reset);
textures.clear();
reloadable.peek(ITexture::reload).forEach(textures::add);
reloadable.peek(this::load).forEach(textures::add);
}
@Override
public void destroy() {
textures.forEach(ITexture::delete);
textures.forEach(ITexture::reset);
textures.clear();
reloadable.clear();
}
private void load(ITexture texture) {
texture.load(provider);
}
@Override
public String getName() { return "Texture Tracker"; }

View File

@ -1,4 +1,4 @@
package speiger.src.coreengine.rendering.texturesOld.atlas;
package speiger.src.coreengine.rendering.textures.custom;
import java.util.List;
@ -6,9 +6,11 @@ import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.utils.ObjectIterables;
import speiger.src.collections.utils.HashUtil;
import speiger.src.coreengine.assets.AssetLocation;
import speiger.src.coreengine.rendering.texturesOld.atlas.AtlasStitcher.Entry;
import speiger.src.coreengine.rendering.textures.custom.AtlasStitcher.Entry;
/**
* Inspired by: <a href=https://github.com/lukaszdk/texture-atlas-generator/blob/master/AtlasGenerator.java>AtlasGenerator</a>
*/
public class AtlasStitcher<T extends Entry> {
final int maxWidth;
@ -27,17 +29,20 @@ public class AtlasStitcher<T extends Entry> {
public AtlasStitcher(int maxWidth, int maxHeight) {
this.maxWidth = maxWidth;
this.maxHeight = maxHeight;
if(maxWidth < 16 || maxHeight < 16) throw new IndexOutOfBoundsException("Minimum Size has to be 16x16 pixels");
if(maxWidth < 256 || maxHeight < 256) throw new IndexOutOfBoundsException("Minimum Size has to be 256x256 pixels");
}
public int width() { return width; }
public int height() { return height; }
public boolean isValid() { return valid; }
public void add(T entry) { add(new Record<T>(entry)); }
public void addAll(Iterable<? extends T> iterables) {
ObjectIterables.map(iterables, Record<T>::new).forEach(this::add);
public void add(T entry) { add(new Record<>(entry)); }
public void addAll(Iterable<? extends T> iterables) { ObjectIterables.map(iterables, Record<T>::new).forEach(this::add); }
@SuppressWarnings("unchecked")
public void addAll(T...entries) {
for(T entry : entries) {
add(new Record<>(entry));
}
}
private void add(Record<T> entry) {

View File

@ -0,0 +1,141 @@
package speiger.src.coreengine.rendering.textures.custom;
import org.lwjgl.opengl.GL45;
import org.lwjgl.system.MemoryUtil;
import speiger.src.collections.ints.collections.IntIterator;
import speiger.src.collections.ints.sets.IntLinkedOpenHashSet;
import speiger.src.collections.ints.sets.IntSet;
import speiger.src.coreengine.assets.base.IAssetProvider;
import speiger.src.coreengine.math.BitUtil;
import speiger.src.coreengine.rendering.textures.base.BaseTexture;
import speiger.src.coreengine.rendering.textures.base.TextureMetadata;
import speiger.src.coreengine.rendering.utils.values.GLDataType;
import speiger.src.coreengine.rendering.utils.values.textures.GLTextureFormat;
public class DynamicTexture extends BaseTexture implements IDynamicTexture {
IntSet dirtySections = new IntLinkedOpenHashSet();
TextureMetadata metadata;
int width;
int height;
long data;
public DynamicTexture(int width, int height, TextureMetadata metadata) {
this.metadata = metadata;
this.width = width;
this.height = height;
data = MemoryUtil.nmemAllocChecked(4L * width * height);
}
@Override
public void load(IAssetProvider provider) {
createTexture();
metadata.applyArguments(id);
GL45.glTextureStorage2D(id, 1, GLTextureFormat.RGBA.glValue(), width, height);
GL45.nglTextureSubImage2D(id, 0, 0, 0, width, height, GLTextureFormat.RGBA.glValue(), GLDataType.UNSIGNED_BYTE.glValue(), data);
dirtySections.clear();
}
@Override
public void delete(boolean untrack) {
super.delete(untrack);
if(untrack && data != 0L) {
MemoryUtil.nmemFree(data);
data = 0L;
}
}
@Override
public int width() { return width; }
@Override
public int height() { return height; }
@Override
public boolean isDirty() { return !dirtySections.isEmpty(); }
@Override
public void process(boolean full) {
if(full) {
GL45.nglTextureSubImage2D(id, 0, 0, 0, width, height, GLTextureFormat.RGBA.glValue(), GLDataType.UNSIGNED_BYTE.glValue(), data);
dirtySections.clear();
return;
}
Thread thread = Thread.currentThread();
long tempBuffer = MemoryUtil.nmemAllocChecked(1024);
for(IntIterator iter = dirtySections.iterator();iter.hasNext() && !thread.isInterrupted();iter.remove()) {
int key = iter.nextInt();
int x = BitUtil.toFirstShort(key) * 16;
int y = BitUtil.toSecondShort(key) * 16;
for(int i = 0;i<16;i++) {
MemoryUtil.memCopy(data + offset(x, y+i), tempBuffer+i*64, 64);//TODO implement a better solution here, i don't like it
}
GL45.nglTextureSubImage2D(id, 0, x, y, 16, 16, GLTextureFormat.RGBA.glValue(), GLDataType.UNSIGNED_BYTE.glValue(), tempBuffer);
}
MemoryUtil.nmemFree(tempBuffer);
}
protected long offset(int x, int y) {
return ((y * width()) + x) * 4L;
}
@Override
public void dirty(int x, int y) {
if(id() == 0) return;
dirtySections.add(BitUtil.toInt(x >> 4, y >> 4));
}
@Override
public void set(int index, int data) {
MemoryUtil.memPutInt(index * 4L, Integer.rotateLeft(data, 8));
dirty(index);
}
@Override
public void setR(int index, int red) {
MemoryUtil.memPutByte(index * 4L, (byte)(red & 0xFF));
dirty(index);
}
@Override
public void setG(int index, int green) {
MemoryUtil.memPutByte(index * 4L + 1L, (byte)(green & 0xFF));
dirty(index);
}
@Override
public void setB(int index, int blue) {
MemoryUtil.memPutByte(index * 4L + 2L, (byte)(blue & 0xFF));
dirty(index);
}
@Override
public void setA(int index, int alpha) {
MemoryUtil.memPutByte(index * 4L + 3L, (byte)(alpha & 0xFF));
dirty(index);
}
@Override
public int get(int index) {
return Integer.rotateRight(MemoryUtil.memGetInt(index * 4L), 8);
}
@Override
public int getR(int index) {
return MemoryUtil.memGetByte(index * 4L);
}
@Override
public int getG(int index) {
return MemoryUtil.memGetByte(index * 4L + 1L);
}
@Override
public int getB(int index) {
return MemoryUtil.memGetByte(index * 4L + 2L);
}
@Override
public int getA(int index) {
return MemoryUtil.memGetByte(index * 4L + 3L);
}
}

View File

@ -0,0 +1,43 @@
package speiger.src.coreengine.rendering.textures.custom;
import speiger.src.coreengine.rendering.textures.base.ITexture;
public interface IDynamicTexture extends ITexture {
public boolean isDirty();
public void process(boolean full);
public default void dirty(int index) { dirty(index % width(), index / width()); }
public void dirty(int x, int y);
public void set(int index, int data);
public default void set(int x, int y, int data) { set((y * width()) + x, data); }
public default void set(int index, int red, int green, int blue, int alpha) { set(index, ((alpha & 0xFF) << 24) | ((red & 0xFF) << 16) | ((green & 0xFF) << 8) | (blue & 0xFF)); }
public default void set(int x, int y, int red, int green, int blue, int alpha) { set((y * width()) + x, ((alpha & 0xFF) << 24) | ((red & 0xFF) << 16) | ((green & 0xFF) << 8) | (blue & 0xFF)); }
public void setR(int index, int red);
public default void setR(int x, int y, int red) { setR((y * width()) + x, red); }
public void setG(int index, int green);
public default void setG(int x, int y, int green) { setG((y * width()) + x, green); }
public void setB(int index, int blue);
public default void setB(int x, int y, int blue) { setB((y * width()) + x, blue); }
public void setA(int index, int alpha);
public default void setA(int x, int y, int alpha) { setA((y * width()) + x, alpha); }
public int get(int index);
public default int get(int x, int y) { return get((y * width()) + x); }
public int getR(int index);
public default int getR(int x, int y) { return getR((y * width()) + x); }
public int getG(int index);
public default int getG(int x, int y) { return getG((y * width()) + x); }
public int getB(int index);
public default int getB(int x, int y) { return getB((y * width()) + x); }
public int getA(int index);
public default int getA(int x, int y) { return getA((y * width()) + x); }
}

View File

@ -0,0 +1,55 @@
package speiger.src.coreengine.rendering.textures.simple;
import org.lwjgl.opengl.GL45;
import org.lwjgl.stb.STBImage;
import org.lwjgl.system.MemoryUtil;
import speiger.src.coreengine.assets.base.IAssetProvider;
import speiger.src.coreengine.rendering.textures.base.BaseTexture;
import speiger.src.coreengine.rendering.textures.base.TextureMetadata;
public class DirectTexture extends BaseTexture {
int width;
int height;
long imageData;
TextureMetadata metadata;
public DirectTexture(int width, int height, long imageData, TextureMetadata metadata) {
this.width = width;
this.height = height;
this.imageData = imageData;
this.metadata = metadata;
}
@Override
public void load(IAssetProvider provider) {
loadTexture();
}
@Override
public void delete(boolean untrack) {
super.delete(untrack);
if(imageData == 0L || !untrack) return;
if(metadata.isSTBData()) {
STBImage.nstbi_image_free(imageData);
imageData = 0L;
}
else {
MemoryUtil.nmemFree(imageData);
imageData = 0;
}
}
@Override
public int width() { return width; }
@Override
public int height() { return width; }
private void loadTexture() {
createTexture();
metadata.applyArguments(id);
GL45.glTextureStorage2D(id, 1, metadata.getInternalFormat(), width, height);
GL45.glTextureSubImage2D(id, 0, 0, 0, width, height, metadata.getExternalFormat(), metadata.getDataFormat(), imageData);
if(metadata.generateMipMappings()) GL45.glGenerateTextureMipmap(id);
}
}

View File

@ -1,43 +1,69 @@
package speiger.src.coreengine.rendering.textures.simple;
import org.lwjgl.stb.STBImage;
import java.io.IOException;
import java.nio.ByteBuffer;
import org.lwjgl.opengl.GL45;
import org.lwjgl.stb.STBImage;
import org.lwjgl.system.MemoryUtil;
import speiger.src.coreengine.assets.AssetLocation;
import speiger.src.coreengine.assets.base.IAsset;
import speiger.src.coreengine.assets.base.IAssetProvider;
import speiger.src.coreengine.assets.parsers.NativeMemoryParser;
import speiger.src.coreengine.rendering.textures.base.BaseTexture;
import speiger.src.coreengine.rendering.textures.base.TextureMetadata;
import speiger.src.coreengine.rendering.utils.values.GLDataType;
import speiger.src.coreengine.rendering.utils.values.textures.GLTextureFormat;
public class SimpleTexture extends BaseTexture {
AssetLocation location;
TextureMetadata metadata;
int width;
int height;
long imageData;
TextureMetadata metadata;
public SimpleTexture(int width, int height, long imageData, TextureMetadata metadata) {
this.width = width;
this.height = height;
this.imageData = imageData;
public SimpleTexture(AssetLocation location, TextureMetadata metadata) {
this.location = location;
this.metadata = metadata;
loadTexture();
}
@Override
public void reload() {
public void load(IAssetProvider provider) {
long address = 0L;
int channel = GLTextureFormat.toComponents(metadata.getExternalFormat());
try(IAsset asset = provider.getAsset(location)) {
ByteBuffer buffer = asset.custom(NativeMemoryParser.INSTANCE);
int[] width = new int[1];
int[] height = new int[1];
int[] fileChannels = new int[1];
address = STBImage.nstbi_load_from_memory(MemoryUtil.memAddress(buffer), buffer.remaining(), width, height, fileChannels, channel);
MemoryUtil.memFree(buffer);
if(address == 0) {
throw new IllegalArgumentException("Couldn't load texture ["+location+"]");
}
this.width = width[0];
this.height = height[0];
if(channel == 0) channel = fileChannels[0];
}
catch(IOException e) {
e.printStackTrace();
}
if(address == 0L) return;
createTexture();
metadata.applyArguments(id);
GL45.glTextureStorage2D(id, 1, metadata.getInternalFormat(), width, height);
GL45.nglTextureSubImage2D(id, 0, 0, 0, width, height, GLTextureFormat.bySTB(channel).glValue(), GLDataType.UNSIGNED_BYTE.glValue(), address);
if(metadata.generateMipMappings()) GL45.glGenerateTextureMipmap(id);
STBImage.nstbi_image_free(address);
}
@Override
public void delete() {
super.delete();
if(imageData == 0L) return;
STBImage.nstbi_image_free(imageData);
imageData = 0L;
public int width() {
return width;
}
@Override
public int width() { return width; }
@Override
public int height() { return width; }
private void loadTexture() {
public int height() {
return height;
}
}

View File

@ -0,0 +1,26 @@
package speiger.src.coreengine.rendering.textures.simple;
import speiger.src.coreengine.assets.base.IAssetProvider;
import speiger.src.coreengine.rendering.textures.base.BaseTexture;
import speiger.src.coreengine.rendering.textures.base.ITexture;
public class WrappedTexture extends BaseTexture {
public WrappedTexture(ITexture texture) {
this(texture.id());
}
public WrappedTexture(int id) {
super(id);
}
@Override
public void load(IAssetProvider provider) {}
@Override
protected void track() {}
@Override
public void delete(boolean untrack) {}
@Override
public int width() { return 0; }
@Override
public int height() { return 0; }
}

View File

@ -7,7 +7,6 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL46;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.MemoryUtil;

View File

@ -11,8 +11,8 @@ import org.lwjgl.system.MemoryUtil;
import speiger.src.coreengine.assets.AssetLocation;
import speiger.src.coreengine.assets.base.IAsset;
import speiger.src.coreengine.assets.parsers.NativeMemoryParser;
import speiger.src.coreengine.rendering.texturesOld.base.AbstractTexture;
import speiger.src.coreengine.rendering.texturesOld.base.NativeMemoryParser;
import speiger.src.coreengine.rendering.texturesOld.base.TextureManager;
public class STBTexture extends AbstractTexture

View File

@ -9,10 +9,10 @@ import speiger.src.coreengine.rendering.utils.values.IGLValue.ISourceFactor;
public class BlendState extends GLState
{
int srcRGB = GLBlendFactor.ONE.glMode();
int destRGB = GLBlendFactor.ZERO.glMode();
int srcAlpha = GLBlendFactor.ONE.glMode();
int destAlpha = GLBlendFactor.ZERO.glMode();
int srcRGB = GLBlendFactor.ONE.glValue();
int destRGB = GLBlendFactor.ZERO.glValue();
int srcAlpha = GLBlendFactor.ONE.glValue();
int destAlpha = GLBlendFactor.ZERO.glValue();
public BlendState() {
super(GL11.GL_BLEND);
@ -37,12 +37,12 @@ public class BlendState extends GLState
}
public BlendState setFunction(ISourceFactor srcRGB, ISourceFactor srcAlpha, IDestinationFactor destRGB, IDestinationFactor destAlpha) {
setFunction(srcRGB.glMode(), srcAlpha.glMode(), destRGB.glMode(), destAlpha.glMode());
setFunction(srcRGB.glValue(), srcAlpha.glValue(), destRGB.glValue(), destAlpha.glValue());
return this;
}
public BlendState setFunction(ISourceFactor src, IDestinationFactor dest) {
setFunction(src.glMode(), dest.glMode());
setFunction(src.glValue(), dest.glValue());
return this;
}

View File

@ -17,7 +17,7 @@ public class CullState extends GLState {
enable();
if(this.state != state) {
this.state = state;
GL11.glCullFace(state.glMode());
GL11.glCullFace(state.glValue());
}
return this;
}
@ -29,7 +29,7 @@ public class CullState extends GLState {
@Override
public void reapply() {
super.reapply();
GL11.glCullFace(state.glMode());
GL11.glCullFace(state.glValue());
}
@Override

View File

@ -18,7 +18,7 @@ public class GLWireFrame implements IGLState
public GLWireFrame set(GLPoligonMode state) {
if(this.state != state) {
this.state = state;
GL11.glPolygonMode(id.glMode(), state.glMode());
GL11.glPolygonMode(id.glValue(), state.glValue());
}
return this;
}
@ -30,6 +30,6 @@ public class GLWireFrame implements IGLState
@Override
public void reapply() {
GL11.glPolygonMode(id.glMode(), state.glMode());
GL11.glPolygonMode(id.glValue(), state.glValue());
}
}

View File

@ -20,7 +20,7 @@ public enum BufferState implements IGLValue {
}
@Override
public int glMode() {
public int glValue() {
return glValue;
}
}

View File

@ -19,7 +19,7 @@ public enum GLAlphaFunction implements IGLValue {
}
@Override
public int glMode() {
public int glValue() {
return glValue;
}
}

View File

@ -29,5 +29,5 @@ public enum GLBlendFactor implements ISourceFactor, IDestinationFactor {
this.glMode = glMode;
}
public int glMode() { return glMode; }
public int glValue() { return glMode; }
}

View File

@ -32,5 +32,5 @@ public enum GLBuffer implements IGLBuffer {
}
@Override
public int glMode() { return glMode; }
public int glValue() { return glMode; }
}

View File

@ -14,7 +14,7 @@ public enum GLCullType implements IGLValue {
}
@Override
public int glMode() {
public int glValue() {
return glValue;
}
}

View File

@ -11,7 +11,7 @@ import speiger.src.collections.ints.maps.interfaces.Int2ObjectMap;
import speiger.src.collections.objects.maps.impl.hash.Object2ObjectOpenHashMap;
import speiger.src.coreengine.rendering.utils.values.IGLValue.IGLDataType;
public record GLDataType(String name, int glMode, int byteSize, GLDataType.DataType type, boolean supportsIBO, boolean isCompound) implements IGLDataType {
public record GLDataType(String name, int glValue, int byteSize, GLDataType.DataType type, boolean supportsIBO, boolean isCompound) implements IGLDataType {
static final Int2ObjectMap<GLDataType> ID_TO_TYPE = new Int2ObjectOpenHashMap<>();
static final Map<String, GLDataType> NAME_TO_TYPE = new Object2ObjectOpenHashMap<>();
@ -42,16 +42,16 @@ public record GLDataType(String name, int glMode, int byteSize, GLDataType.DataT
public static final GLDataType UNSIGNED_INT_10F_11F_11F_REV = new GLDataType("u_int_10_11_11_rev", GL30.GL_UNSIGNED_INT_10F_11F_11F_REV, 4, DataType.INT);
public static final GLDataType UNSIGNED_INT_5_9_9_9_REV = new GLDataType("u_int_5_9_9_9_rev", GL30.GL_UNSIGNED_INT_5_9_9_9_REV, 4, DataType.INT);
public GLDataType(String name, int glMode, int byteSize, DataType type, boolean isCompound) {
this(name, glMode, byteSize, type, false, isCompound);
public GLDataType(String name, int glValue, int byteSize, DataType type, boolean isCompound) {
this(name, glValue, byteSize, type, false, isCompound);
}
public GLDataType(String name, int glMode, int byteSize, DataType type) {
this(name, glMode, byteSize, type, false, false);
public GLDataType(String name, int glValue, int byteSize, DataType type) {
this(name, glValue, byteSize, type, false, false);
}
public GLDataType {
ID_TO_TYPE.put(glMode, this);
ID_TO_TYPE.put(glValue, this);
NAME_TO_TYPE.put(name, this);
}

View File

@ -30,7 +30,7 @@ public enum GLMode implements IGLMode {
}
@Override
public int glMode() { return glMode; }
public int glValue() { return glMode; }
@Override
public int primitiveLength() { return length; }
@Override

View File

@ -14,7 +14,7 @@ public enum GLPoligonMode implements IGLValue {
}
@Override
public int glMode() {
public int glValue() {
return glValue;
}
}

View File

@ -1,7 +1,7 @@
package speiger.src.coreengine.rendering.utils.values;
public interface IGLValue {
public int glMode();
public int glValue();
public static interface IGLBuffer extends IGLValue {}
public static interface ISourceFactor extends IGLValue {}

View File

@ -20,5 +20,5 @@ public enum ShaderType implements IShaderType {
}
@Override
public int glMode() { return glMode; }
public int glValue() { return glMode; }
}

View File

@ -11,7 +11,9 @@ public enum GLTextureFormat implements ITextureFormatType {
RGB(GL11.GL_RGB, true),
RGBA(GL11.GL_RGBA, true),
DEPTH(GL11.GL_DEPTH_COMPONENT, true),
DEPTH_STENCIL(GL30.GL_DEPTH_STENCIL, true);
DEPTH_STENCIL(GL30.GL_DEPTH_STENCIL, true),
LUMINANCE(GL11.GL_LUMINANCE, false),
LUMINANCE_ALPHA(GL11.GL_LUMINANCE_ALPHA, false);
int glMode;
boolean internal;
@ -22,7 +24,27 @@ public enum GLTextureFormat implements ITextureFormatType {
}
@Override
public int glMode() { return glMode; }
public int glValue() { return glMode; }
@Override
public boolean internal() { return internal; }
public static int toComponents(int glValue) {
return switch(glValue) {
case GL11.GL_LUMINANCE -> 1;
case GL11.GL_LUMINANCE_ALPHA -> 2;
case GL11.GL_RGB -> 3;
case GL11.GL_RGBA -> 4;
default -> 0;
};
}
public static GLTextureFormat bySTB(int components) {
return switch(components) {
case 1 -> LUMINANCE;
case 2 -> LUMINANCE_ALPHA;
case 3 -> RGB;
case 4 -> RGBA;
default -> throw new IllegalArgumentException("Only 1-4 Components are supported");
};
}
}

View File

@ -40,7 +40,7 @@ public enum GLTextureParameter implements ITextureParameter {
private GLTextureParameter(int glValue, IGLValue... validValues) {
this.glValue = glValue;
this.validValues = new IntOpenHashSet(validValues.length);
for(int i = 0,m=validValues.length;i<m;this.validValues.add(validValues[i++].glMode()));
for(int i = 0,m=validValues.length;i<m;this.validValues.add(validValues[i++].glValue()));
}
private GLTextureParameter(int glValue, boolean any) {
@ -49,7 +49,7 @@ public enum GLTextureParameter implements ITextureParameter {
}
@Override
public int glMode() {
public int glValue() {
return glValue;
}

View File

@ -0,0 +1,38 @@
package speiger.src.coreengine.rendering.utils.values.textures;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import org.lwjgl.opengl.GL30;
import org.lwjgl.opengl.GL31;
import org.lwjgl.opengl.GL32;
import org.lwjgl.opengl.GL40;
import org.lwjgl.opengl.GL46;
import speiger.src.coreengine.rendering.utils.values.IGLValue;
public enum GLTextureType implements IGLValue {
TEXTURE_1D(GL11.GL_TEXTURE_1D),
TEXTURE_1D_ARRAY(GL30.GL_TEXTURE_1D_ARRAY),
TEXTURE_2D(GL11.GL_TEXTURE_2D),
TEXTURE_2D_ARRAY(GL30.GL_TEXTURE_2D_ARRAY),
TEXTURE_2D_MULTISAMPLE(GL32.GL_TEXTURE_2D_MULTISAMPLE),
TEXTURE_2D_MULTISAMPLE_ARRAY(GL32.GL_TEXTURE_2D_MULTISAMPLE_ARRAY),
TEXTURE_3D(GL12.GL_TEXTURE_3D),
TEXTURE_CUBE_MAP(GL32.GL_TEXTURE_CUBE_MAP),
TEXTURE_CUBE_MAP_ARRAY(GL40.GL_TEXTURE_CUBE_MAP_ARRAY),
TEXTURE_RECTANGLE(GL31.GL_TEXTURE_RECTANGLE),
TEXTURE_BUFFER(GL31.GL_TEXTURE_BUFFER);
int glValue;
private GLTextureType(int glValue) {
this.glValue = glValue;
}
@Override
public int glValue() {
GL46.glBindTexture(glValue, glValue);
return glValue;
}
}

View File

@ -39,7 +39,7 @@ public enum GLTextureValue implements IGLValue {
}
@Override
public int glMode() {
public int glValue() {
return glValue;
}
}