141 lines
3.9 KiB
Java
141 lines
3.9 KiB
Java
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);
|
|
}
|
|
} |