Skip to content

Commit 0171c0d

Browse files
committed
feat: vbo world scene renderer
1 parent abb98d7 commit 0171c0d

File tree

3 files changed

+175
-35
lines changed

3 files changed

+175
-35
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package gregtech.client.renderer.scene;
2+
3+
import net.minecraft.client.Minecraft;
4+
import net.minecraft.client.renderer.*;
5+
import net.minecraft.client.renderer.texture.TextureMap;
6+
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
7+
import net.minecraft.client.renderer.vertex.VertexBuffer;
8+
import net.minecraft.util.BlockRenderLayer;
9+
import net.minecraft.util.math.BlockPos;
10+
import net.minecraft.world.World;
11+
import net.minecraftforge.client.ForgeHooksClient;
12+
import net.minecraftforge.client.MinecraftForgeClient;
13+
import net.minecraftforge.fml.relauncher.Side;
14+
import net.minecraftforge.fml.relauncher.SideOnly;
15+
import org.lwjgl.opengl.GL11;
16+
17+
import java.nio.ByteBuffer;
18+
import java.util.Collection;
19+
20+
@SideOnly(Side.CLIENT)
21+
public class VBOWorldSceneRenderer extends ImmediateWorldSceneRenderer {
22+
23+
protected final VertexBuffer[] vbos = new VertexBuffer[BlockRenderLayer.values().length];
24+
protected boolean isDirty = true;
25+
26+
public VBOWorldSceneRenderer(World world) {
27+
super(world);
28+
}
29+
30+
private void uploadVBO() {
31+
BlockRenderLayer oldRenderLayer = MinecraftForgeClient.getRenderLayer();
32+
33+
try { // render block in each layer
34+
for (BlockRenderLayer layer : BlockRenderLayer.values()) {
35+
36+
var vbo = this.vbos[layer.ordinal()] = new VertexBuffer(DefaultVertexFormats.BLOCK);
37+
38+
renderBlockLayer(layer);
39+
40+
// Get the buffer again
41+
BufferBuilder buffer = Tessellator.getInstance().getBuffer();
42+
buffer.finishDrawing();
43+
buffer.reset();
44+
45+
ByteBuffer data = buffer.getByteBuffer();
46+
vbo.bufferData(data);
47+
}
48+
} finally {
49+
ForgeHooksClient.setRenderLayer(oldRenderLayer);
50+
}
51+
this.isDirty = false;
52+
}
53+
54+
@Override
55+
protected void drawWorld() {
56+
if (this.isDirty) {
57+
uploadVBO();
58+
}
59+
60+
Minecraft mc = Minecraft.getMinecraft();
61+
GlStateManager.enableCull();
62+
GlStateManager.enableRescaleNormal();
63+
RenderHelper.disableStandardItemLighting();
64+
mc.entityRenderer.disableLightmap();
65+
mc.renderEngine.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE);
66+
GlStateManager.disableLighting();
67+
GlStateManager.enableTexture2D();
68+
GlStateManager.enableAlpha();
69+
70+
var oldRenderLayer = MinecraftForgeClient.getRenderLayer();
71+
for (var layer : BlockRenderLayer.values()) {
72+
73+
ForgeHooksClient.setRenderLayer(layer);
74+
75+
int pass = layer == BlockRenderLayer.TRANSLUCENT ? 1 : 0;
76+
setDefaultPassRenderState(pass);
77+
78+
GlStateManager.pushMatrix();
79+
{
80+
var vbo = this.vbos[layer.ordinal()];
81+
vbo.bindBuffer();
82+
setupClientStates();
83+
setupArrayPointers();
84+
vbo.drawArrays(GL11.GL_QUADS);
85+
resetClientStates();
86+
vbo.unbindBuffer();
87+
}
88+
GlStateManager.popMatrix();
89+
}
90+
ForgeHooksClient.setRenderLayer(oldRenderLayer);
91+
92+
renderTESR(); // Handles TileEntities
93+
94+
GlStateManager.shadeModel(GL11.GL_SMOOTH);
95+
RenderHelper.enableStandardItemLighting();
96+
GlStateManager.enableDepth();
97+
GlStateManager.disableBlend();
98+
GlStateManager.depthMask(true);
99+
}
100+
101+
@Override
102+
public WorldSceneRenderer addRenderedBlocks(Collection<BlockPos> blocks) {
103+
this.isDirty = true;
104+
return super.addRenderedBlocks(blocks);
105+
}
106+
107+
protected void setupClientStates() {
108+
GlStateManager.glEnableClientState(GL11.GL_VERTEX_ARRAY);
109+
OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit);
110+
GlStateManager.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
111+
OpenGlHelper.setClientActiveTexture(OpenGlHelper.lightmapTexUnit);
112+
GlStateManager.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
113+
OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit);
114+
GlStateManager.glEnableClientState(GL11.GL_COLOR_ARRAY);
115+
}
116+
117+
protected void resetClientStates() {
118+
GlStateManager.glDisableClientState(GL11.GL_VERTEX_ARRAY);
119+
GlStateManager.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
120+
GlStateManager.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
121+
GlStateManager.glDisableClientState(GL11.GL_COLOR_ARRAY);
122+
}
123+
124+
protected void setupArrayPointers() {
125+
// 28 == DefaultVertexFormats.BLOCK.getSize();
126+
GlStateManager.glVertexPointer(3, GL11.GL_FLOAT, 28, 0);
127+
GlStateManager.glColorPointer(4, GL11.GL_UNSIGNED_BYTE, 28, 12);
128+
GlStateManager.glTexCoordPointer(2, GL11.GL_FLOAT, 28, 16);
129+
OpenGlHelper.setClientActiveTexture(OpenGlHelper.lightmapTexUnit);
130+
GlStateManager.glTexCoordPointer(2, GL11.GL_SHORT, 28, 24);
131+
OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit);
132+
}
133+
}

src/main/java/gregtech/client/renderer/scene/WorldSceneRenderer.java

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package gregtech.client.renderer.scene;
22

3+
import codechicken.lib.vec.Vector3;
34
import gregtech.api.util.Position;
45
import gregtech.api.util.PositionedRect;
56
import gregtech.api.util.Size;
67
import gregtech.client.utils.RenderUtil;
7-
8+
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
89
import net.minecraft.block.Block;
910
import net.minecraft.block.state.IBlockState;
1011
import net.minecraft.client.Minecraft;
@@ -23,22 +24,18 @@
2324
import net.minecraftforge.client.MinecraftForgeClient;
2425
import net.minecraftforge.fml.relauncher.Side;
2526
import net.minecraftforge.fml.relauncher.SideOnly;
26-
27-
import codechicken.lib.vec.Vector3;
28-
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
2927
import org.jetbrains.annotations.Nullable;
3028
import org.lwjgl.opengl.GL11;
3129
import org.lwjgl.util.glu.GLU;
3230

31+
import javax.vecmath.Vector3f;
3332
import java.nio.ByteBuffer;
3433
import java.nio.ByteOrder;
3534
import java.nio.FloatBuffer;
3635
import java.nio.IntBuffer;
3736
import java.util.Collection;
3837
import java.util.function.Consumer;
3938

40-
import javax.vecmath.Vector3f;
41-
4239
/**
4340
* Created with IntelliJ IDEA.
4441
*
@@ -237,23 +234,8 @@ protected void drawWorld() {
237234

238235
try { // render block in each layer
239236
for (BlockRenderLayer layer : BlockRenderLayer.values()) {
240-
ForgeHooksClient.setRenderLayer(layer);
241-
int pass = layer == BlockRenderLayer.TRANSLUCENT ? 1 : 0;
242-
setDefaultPassRenderState(pass);
243-
244-
BufferBuilder buffer = Tessellator.getInstance().getBuffer();
245-
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
246-
BlockRendererDispatcher blockrendererdispatcher = mc.getBlockRendererDispatcher();
247-
248-
for (BlockPos pos : renderedBlocks) {
249-
IBlockState state = world.getBlockState(pos);
250-
Block block = state.getBlock();
251-
if (block == Blocks.AIR) continue;
252-
state = state.getActualState(world, pos);
253-
if (block.canRenderInLayer(state, layer)) {
254-
blockrendererdispatcher.renderBlock(state, pos, world, buffer);
255-
}
256-
}
237+
238+
renderBlockLayer(layer);
257239

258240
Tessellator.getInstance().draw();
259241
Tessellator.getInstance().getBuffer().setTranslation(0, 0, 0);
@@ -262,14 +244,44 @@ protected void drawWorld() {
262244
ForgeHooksClient.setRenderLayer(oldRenderLayer);
263245
}
264246

265-
RenderHelper.enableStandardItemLighting();
266-
GlStateManager.enableLighting();
247+
renderTESR(); // Handles TileEntities
248+
249+
GlStateManager.enableDepth();
250+
GlStateManager.disableBlend();
251+
GlStateManager.depthMask(true);
252+
253+
if (afterRender != null) {
254+
afterRender.accept(this);
255+
}
256+
}
267257

268-
// render TESR
258+
protected void renderBlockLayer(BlockRenderLayer layer) {
259+
ForgeHooksClient.setRenderLayer(layer);
260+
int pass = layer == BlockRenderLayer.TRANSLUCENT ? 1 : 0;
261+
setDefaultPassRenderState(pass);
262+
263+
BufferBuilder buffer = Tessellator.getInstance().getBuffer();
264+
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
265+
BlockRendererDispatcher blockrendererdispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher();
266+
267+
for (BlockPos pos : renderedBlocks) {
268+
IBlockState state = world.getBlockState(pos);
269+
Block block = state.getBlock();
270+
state = state.getActualState(world, pos);
271+
if (block == Blocks.AIR) continue;
272+
if (block.canRenderInLayer(state, layer)) {
273+
blockrendererdispatcher.renderBlock(state, pos, world, buffer);
274+
}
275+
}
276+
}
277+
278+
protected void renderTESR() {
279+
RenderHelper.enableStandardItemLighting();
269280
for (int pass = 0; pass < 2; pass++) {
270281
ForgeHooksClient.setRenderPass(pass);
271282
setDefaultPassRenderState(pass);
272-
for (BlockPos pos : renderedBlocks) {
283+
284+
for (BlockPos pos : renderedBlocks) { // This
273285
TileEntity tile = world.getTileEntity(pos);
274286
if (tile != null) {
275287
if (tile.shouldRenderInPass(pass)) {
@@ -279,13 +291,7 @@ protected void drawWorld() {
279291
}
280292
}
281293
ForgeHooksClient.setRenderPass(-1);
282-
GlStateManager.enableDepth();
283-
GlStateManager.disableBlend();
284-
GlStateManager.depthMask(true);
285-
286-
if (afterRender != null) {
287-
afterRender.accept(this);
288-
}
294+
RenderHelper.disableStandardItemLighting();
289295
}
290296

291297
public static void setDefaultPassRenderState(int pass) {

src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoRecipeWrapper.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import gregtech.api.util.GregFakePlayer;
1414
import gregtech.api.util.ItemStackHashStrategy;
1515
import gregtech.client.renderer.scene.ImmediateWorldSceneRenderer;
16+
import gregtech.client.renderer.scene.VBOWorldSceneRenderer;
1617
import gregtech.client.renderer.scene.WorldSceneRenderer;
1718
import gregtech.client.utils.RenderUtil;
1819
import gregtech.client.utils.TrackedDummyWorld;
@@ -585,7 +586,7 @@ private MBPattern initializePattern(@NotNull MultiblockShapeInfo shapeInfo, @Not
585586
}
586587

587588
TrackedDummyWorld world = new TrackedDummyWorld();
588-
ImmediateWorldSceneRenderer worldSceneRenderer = new ImmediateWorldSceneRenderer(world);
589+
ImmediateWorldSceneRenderer worldSceneRenderer = new VBOWorldSceneRenderer(world);
589590
worldSceneRenderer.setClearColor(ConfigHolder.client.multiblockPreviewColor);
590591
world.addBlocks(blockMap);
591592

0 commit comments

Comments
 (0)