2021-09-09 00:48:49 +02:00
|
|
|
package com.jozufozu.flywheel.light;
|
|
|
|
|
2021-11-18 23:59:39 +01:00
|
|
|
import static org.lwjgl.opengl.GL11.GL_LINEAR;
|
|
|
|
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER;
|
|
|
|
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MIN_FILTER;
|
|
|
|
import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_S;
|
|
|
|
import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_T;
|
|
|
|
import static org.lwjgl.opengl.GL11.GL_UNPACK_ALIGNMENT;
|
|
|
|
import static org.lwjgl.opengl.GL11.GL_UNPACK_ROW_LENGTH;
|
|
|
|
import static org.lwjgl.opengl.GL11.GL_UNPACK_SKIP_PIXELS;
|
|
|
|
import static org.lwjgl.opengl.GL11.GL_UNPACK_SKIP_ROWS;
|
|
|
|
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE;
|
|
|
|
import static org.lwjgl.opengl.GL11.glPixelStorei;
|
|
|
|
import static org.lwjgl.opengl.GL12.GL_TEXTURE_3D;
|
|
|
|
import static org.lwjgl.opengl.GL12.GL_TEXTURE_WRAP_R;
|
|
|
|
import static org.lwjgl.opengl.GL12.GL_UNPACK_IMAGE_HEIGHT;
|
|
|
|
import static org.lwjgl.opengl.GL12.GL_UNPACK_SKIP_IMAGES;
|
|
|
|
import static org.lwjgl.opengl.GL12.glTexImage3D;
|
|
|
|
import static org.lwjgl.opengl.GL12.glTexSubImage3D;
|
|
|
|
import static org.lwjgl.opengl.GL14.GL_MIRRORED_REPEAT;
|
2021-09-09 00:48:49 +02:00
|
|
|
|
2021-12-08 07:47:05 +01:00
|
|
|
import org.lwjgl.opengl.GL30;
|
|
|
|
|
2021-09-09 00:48:49 +02:00
|
|
|
import com.jozufozu.flywheel.backend.gl.GlTexture;
|
|
|
|
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
|
2021-12-22 09:22:41 +01:00
|
|
|
import com.jozufozu.flywheel.util.box.GridAlignedBB;
|
|
|
|
import com.jozufozu.flywheel.util.box.ImmutableBox;
|
2021-09-09 00:48:49 +02:00
|
|
|
|
2022-07-09 19:23:40 +02:00
|
|
|
import net.minecraft.world.level.BlockAndTintGetter;
|
2021-09-09 00:48:49 +02:00
|
|
|
|
|
|
|
public class GPULightVolume extends LightVolume {
|
|
|
|
|
|
|
|
protected final GridAlignedBB sampleVolume = new GridAlignedBB();
|
|
|
|
private final GlTexture glTexture;
|
|
|
|
|
2021-11-09 23:59:31 +01:00
|
|
|
private final GlTextureUnit textureUnit = GlTextureUnit.T4;
|
2021-09-09 00:48:49 +02:00
|
|
|
protected boolean bufferDirty;
|
|
|
|
|
2022-07-09 19:23:40 +02:00
|
|
|
public GPULightVolume(BlockAndTintGetter level, ImmutableBox sampleVolume) {
|
|
|
|
super(level, sampleVolume);
|
2021-09-09 00:48:49 +02:00
|
|
|
this.sampleVolume.assign(sampleVolume);
|
|
|
|
|
|
|
|
glTexture = new GlTexture(GL_TEXTURE_3D);
|
|
|
|
|
2021-12-10 09:07:52 +01:00
|
|
|
GlTextureUnit oldState = GlTextureUnit.getActive();
|
|
|
|
|
2021-09-09 00:48:49 +02:00
|
|
|
// allocate space for the texture
|
2021-12-10 09:07:52 +01:00
|
|
|
textureUnit.makeActive();
|
2021-09-09 00:48:49 +02:00
|
|
|
glTexture.bind();
|
|
|
|
|
|
|
|
int sizeX = box.sizeX();
|
|
|
|
int sizeY = box.sizeY();
|
|
|
|
int sizeZ = box.sizeZ();
|
2021-12-08 07:47:05 +01:00
|
|
|
glTexImage3D(GL_TEXTURE_3D, 0, GL30.GL_RG8, sizeX, sizeY, sizeZ, 0, GL30.GL_RG, GL_UNSIGNED_BYTE, 0);
|
2021-09-09 00:48:49 +02:00
|
|
|
|
2021-12-12 02:31:09 +01:00
|
|
|
glTexture.setParameteri(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
|
glTexture.setParameteri(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
glTexture.setParameteri(GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
|
|
|
|
glTexture.setParameteri(GL_TEXTURE_WRAP_R, GL_MIRRORED_REPEAT);
|
|
|
|
glTexture.setParameteri(GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
|
|
|
|
|
2021-09-09 00:48:49 +02:00
|
|
|
glTexture.unbind();
|
2021-12-10 09:07:52 +01:00
|
|
|
oldState.makeActive();
|
2021-09-09 00:48:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void setBox(ImmutableBox box) {
|
|
|
|
this.box.assign(box);
|
|
|
|
this.box.nextPowerOf2Centered();
|
|
|
|
// called during super ctor
|
|
|
|
if (sampleVolume != null) this.sampleVolume.assign(box);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void bind() {
|
|
|
|
// just in case something goes wrong, or we accidentally call this before this volume is properly disposed of.
|
2021-12-10 09:07:52 +01:00
|
|
|
if (lightData == null || lightData.capacity() == 0) return;
|
2021-09-09 00:48:49 +02:00
|
|
|
|
2021-11-09 23:59:31 +01:00
|
|
|
textureUnit.makeActive();
|
2021-09-09 00:48:49 +02:00
|
|
|
glTexture.bind();
|
|
|
|
|
|
|
|
uploadTexture();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void uploadTexture() {
|
|
|
|
if (bufferDirty) {
|
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
|
|
|
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
|
|
|
|
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
|
|
|
|
glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
|
|
|
|
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
|
2021-12-10 09:07:52 +01:00
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 2); // we use 2 bytes per texel
|
2021-09-09 00:48:49 +02:00
|
|
|
int sizeX = box.sizeX();
|
|
|
|
int sizeY = box.sizeY();
|
|
|
|
int sizeZ = box.sizeZ();
|
|
|
|
|
2021-12-08 07:47:05 +01:00
|
|
|
glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, sizeX, sizeY, sizeZ, GL30.GL_RG, GL_UNSIGNED_BYTE, lightData);
|
2021-09-09 00:48:49 +02:00
|
|
|
|
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // 4 is the default
|
|
|
|
bufferDirty = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void unbind() {
|
|
|
|
glTexture.unbind();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void delete() {
|
|
|
|
super.delete();
|
|
|
|
glTexture.delete();
|
|
|
|
}
|
|
|
|
|
2022-07-10 21:22:02 +02:00
|
|
|
public void move(ImmutableBox newSampleVolume) {
|
2021-09-09 00:48:49 +02:00
|
|
|
if (lightData == null) return;
|
|
|
|
|
|
|
|
if (box.contains(newSampleVolume)) {
|
2022-04-09 02:23:02 +02:00
|
|
|
sampleVolume.assign(newSampleVolume);
|
2022-07-09 19:23:40 +02:00
|
|
|
initialize();
|
2021-09-09 00:48:49 +02:00
|
|
|
} else {
|
2022-07-10 21:22:02 +02:00
|
|
|
super.move(newSampleVolume);
|
2021-09-09 00:48:49 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public ImmutableBox getVolume() {
|
|
|
|
return sampleVolume;
|
|
|
|
}
|
2022-07-09 19:23:40 +02:00
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void markDirty() {
|
|
|
|
this.bufferDirty = true;
|
|
|
|
}
|
2021-09-09 00:48:49 +02:00
|
|
|
}
|