Skip to content

Commit

Permalink
Incomplete GPU accelerator
Browse files Browse the repository at this point in the history
  • Loading branch information
paulevsGitch committed Jan 30, 2023
1 parent 079940e commit ee7e19a
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/main/java/ru/paulevs/bismuthlib/BismuthLibClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public class BismuthLibClient implements ClientModInitializer {
private static final ResourceLocation LIGHTMAP_ID = new ResourceLocation(MOD_ID, "colored_light");
private static LevelShaderData data;

//private static GPULightPropagator gpuLight;
private static final Gson GSON = new GsonBuilder().create();
private static ResourceManager managerCache;
private static boolean fastLight = false;
Expand All @@ -86,6 +87,7 @@ public void onInitializeClient() {
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f);
RenderSystem.setShaderTexture(0, LIGHTMAP_ID);
//RenderSystem.setShaderTexture(0, gpuLight.getTexture());
BufferBuilder bufferBuilder = Tesselator.getInstance().getBuilder();
bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX);

Expand Down Expand Up @@ -342,11 +344,14 @@ public static void initData() {

if (data == null) {
data = new LevelShaderData(w, h, count);
//gpuLight = new GPULightPropagator(w, h);
Minecraft.getInstance().getTextureManager().register(LIGHTMAP_ID, data.getTexture());
}
else if (data.getDataWidth() != w || data.getDataHeight() != h || count != data.getThreadCount()) {
data.dispose();
data = new LevelShaderData(w, h, count);
//gpuLight.dispose();
//gpuLight = new GPULightPropagator(w, h);
Minecraft.getInstance().getTextureManager().register(LIGHTMAP_ID, data.getTexture());
}

Expand All @@ -365,6 +370,7 @@ else if (data.getDataWidth() != w || data.getDataHeight() != h || count != data.

public static void update(Level level, int cx, int cy, int cz) {
data.update(level, cx, cy, cz);
//gpuLight.render();
}

public static void updateSection(int cx, int cy, int cz) {
Expand Down
110 changes: 110 additions & 0 deletions src/main/java/ru/paulevs/bismuthlib/GPULightPropagator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package ru.paulevs.bismuthlib;

import com.mojang.blaze3d.pipeline.RenderTarget;
import com.mojang.blaze3d.pipeline.TextureTarget;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.platform.NativeImage;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.BufferUploader;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.Tesselator;
import com.mojang.blaze3d.vertex.VertexFormat;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ShaderInstance;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.util.Mth;
import org.lwjgl.opengl.GL30;

import java.io.IOException;
import java.util.Random;

public class GPULightPropagator {
private static ShaderInstance shader;
private final RenderTarget[] buffers = new RenderTarget[2];
private final int textureSide;
private final int dataSide;
private byte index;

public GPULightPropagator(int dataWidth, int dataHeight) {
if (shader == null) {
try {
shader = new ShaderInstance(
Minecraft.getInstance().getClientPackSource().getVanillaPack().asProvider(),
"bismuthlib_gpu_light",
DefaultVertexFormat.POSITION_TEX
);
}
catch (IOException e) {
e.printStackTrace();
}
}
dataSide = (int) Math.ceil(Mth.sqrt(dataWidth * dataWidth * dataHeight));
textureSide = getClosestPowerOfTwo(dataSide << 6);
buffers[0] = new TextureTarget(textureSide, textureSide, false, Minecraft.ON_OSX);
buffers[1] = new TextureTarget(textureSide, textureSide, false, Minecraft.ON_OSX);

Random random = new Random();
NativeImage image = new NativeImage(textureSide, textureSide, false);
for (int x = 0; x < textureSide; x++) {
for (int y = 0; y < textureSide; y++) {
image.setPixelRGBA(x, y, random.nextInt() | (255 << 24));
}
}

GlStateManager._bindTexture(buffers[0].getColorTextureId());
image.upload(0, 0, 0, false);
}

public void render() {
int buffer = GL30.glGetInteger(GL30.GL_DRAW_FRAMEBUFFER_BINDING);
//System.out.println(buffer);
for (byte i = 0; i < 16; i++) {
RenderTarget source = buffers[index];
index = (byte) ((index + 1) & 1);
RenderTarget target = buffers[index];
target.bindWrite(true);
target.clear(Minecraft.ON_OSX);

if (shader != null) RenderSystem.setShader(() -> shader);
RenderSystem.setShaderColor(1, 1, 1, 1);
RenderSystem.setShaderTexture(0, source.getColorTextureId());

BufferBuilder bufferBuilder = Tesselator.getInstance().getBuilder();
bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX);

bufferBuilder.vertex(0, textureSide, 0).uv(0.0F, 1.0F).endVertex();
bufferBuilder.vertex(textureSide, textureSide, 0).uv(1.0F, 1.0F).endVertex();
bufferBuilder.vertex(textureSide, 0, 0).uv(1.0F, 0.0F).endVertex();
bufferBuilder.vertex(0, 0, 0).uv(0.0F, 0.0F).endVertex();

BufferUploader.drawWithShader(bufferBuilder.end());
target.unbindWrite();
}
GL30.glBindRenderbuffer(GL30.GL_FRAMEBUFFER, buffer);
}

public void dispose() {
buffers[0].destroyBuffers();
buffers[1].destroyBuffers();
}

private int getClosestPowerOfTwo(int value) {
if (value <= 0) return 0;
byte index = 0;
byte count = 0;
for (byte i = 0; i < 32; i++) {
byte bit = (byte) (value & 1);
if (bit == 1) {
index = i;
count++;
}
value >>>= 1;
}
return count == 1 ? 1 << index : 1 << (index + 1);
}

public int getTexture() {
return buffers[index].getColorTextureId();
}
}

0 comments on commit ee7e19a

Please sign in to comment.