mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-28 16:06:48 +01:00
fix vertex attribute data types
blockcolors and ao now work in contraptions be smarter about allocating buffers use gl buffer mapping, more to come
This commit is contained in:
parent
5ea0fa788f
commit
37e64e4c1d
14 changed files with 177 additions and 137 deletions
|
@ -126,7 +126,7 @@ dependencies {
|
||||||
//runtimeOnly fg.deobf("vazkii.arl:AutoRegLib:1.4-35.69")
|
//runtimeOnly fg.deobf("vazkii.arl:AutoRegLib:1.4-35.69")
|
||||||
//runtimeOnly fg.deobf("vazkii.quark:Quark:r2.0-212.984")
|
//runtimeOnly fg.deobf("vazkii.quark:Quark:r2.0-212.984")
|
||||||
|
|
||||||
annotationProcessor 'org.spongepowered:mixin:0.8:processor'
|
//annotationProcessor 'org.spongepowered:mixin:0.8:processor'
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
|
|
|
@ -6,7 +6,9 @@ import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
@ -16,6 +18,8 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||||
@Mixin(World.class)
|
@Mixin(World.class)
|
||||||
public class OnRemoveTileMixin {
|
public class OnRemoveTileMixin {
|
||||||
|
|
||||||
|
@Shadow @Final public boolean isRemote;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JUSTIFICATION: This method is called whenever a tile entity is removed due
|
* JUSTIFICATION: This method is called whenever a tile entity is removed due
|
||||||
* to a change in block state, even on the client. By hooking into this method,
|
* to a change in block state, even on the client. By hooking into this method,
|
||||||
|
@ -23,6 +27,6 @@ public class OnRemoveTileMixin {
|
||||||
*/
|
*/
|
||||||
@Inject(at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/World;getTileEntity(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/tileentity/TileEntity;"), method = "removeTileEntity", locals = LocalCapture.CAPTURE_FAILHARD)
|
@Inject(at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/World;getTileEntity(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/tileentity/TileEntity;"), method = "removeTileEntity", locals = LocalCapture.CAPTURE_FAILHARD)
|
||||||
private void onRemoveTile(BlockPos pos, CallbackInfo ci, TileEntity te) {
|
private void onRemoveTile(BlockPos pos, CallbackInfo ci, TileEntity te) {
|
||||||
FastRenderDispatcher.markForRebuild(te);
|
if (isRemote) FastRenderDispatcher.markForRebuild(te);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ import com.simibubi.create.foundation.render.instancing.VertexFormat;
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
import org.lwjgl.opengl.*;
|
import org.lwjgl.opengl.*;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import static com.simibubi.create.foundation.render.instancing.VertexAttribute.*;
|
import static com.simibubi.create.foundation.render.instancing.VertexAttribute.*;
|
||||||
|
|
||||||
public class ContraptionBuffer extends TemplateBuffer {
|
public class ContraptionBuffer extends TemplateBuffer {
|
||||||
|
@ -15,19 +17,21 @@ public class ContraptionBuffer extends TemplateBuffer {
|
||||||
|
|
||||||
public ContraptionBuffer(BufferBuilder buf) {
|
public ContraptionBuffer(BufferBuilder buf) {
|
||||||
super(buf);
|
super(buf);
|
||||||
setup();
|
if (vertexCount > 0) setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
RenderWork.enqueue(() -> {
|
if (vertexCount > 0) {
|
||||||
GL15.glDeleteBuffers(vbo);
|
RenderWork.enqueue(() -> {
|
||||||
GL15.glDeleteBuffers(ebo);
|
GL15.glDeleteBuffers(vbo);
|
||||||
GL30.glDeleteVertexArrays(vao);
|
GL15.glDeleteBuffers(ebo);
|
||||||
});
|
GL30.glDeleteVertexArrays(vao);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render() {
|
public void render() {
|
||||||
|
if (vertexCount == 0) return;
|
||||||
GL30.glBindVertexArray(vao);
|
GL30.glBindVertexArray(vao);
|
||||||
|
|
||||||
for (int i = 0; i <= 3; i++) {
|
for (int i = 0; i <= 3; i++) {
|
||||||
|
@ -54,39 +58,38 @@ public class ContraptionBuffer extends TemplateBuffer {
|
||||||
ebo = GlStateManager.genBuffers();
|
ebo = GlStateManager.genBuffers();
|
||||||
vbo = GlStateManager.genBuffers();
|
vbo = GlStateManager.genBuffers();
|
||||||
|
|
||||||
try (SafeDirectBuffer constant = new SafeDirectBuffer(invariantSize)) {
|
GL30.glBindVertexArray(vao);
|
||||||
constant.order(template.order());
|
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
|
||||||
constant.limit(invariantSize);
|
|
||||||
|
|
||||||
for (int i = 0; i < vertexCount; i++) {
|
// allocate the buffer on the gpu
|
||||||
constant.putFloat(getX(template, i));
|
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, invariantSize, GL15.GL_STATIC_DRAW);
|
||||||
constant.putFloat(getY(template, i));
|
|
||||||
constant.putFloat(getZ(template, i));
|
|
||||||
|
|
||||||
constant.put(getNX(template, i));
|
// mirror it in system memory so we can write to it
|
||||||
constant.put(getNY(template, i));
|
ByteBuffer constant = GL15.glMapBuffer(GL15.GL_ARRAY_BUFFER, GL15.GL_WRITE_ONLY);
|
||||||
constant.put(getNZ(template, i));
|
|
||||||
|
|
||||||
constant.putFloat(getU(template, i));
|
for (int i = 0; i < vertexCount; i++) {
|
||||||
constant.putFloat(getV(template, i));
|
constant.putFloat(getX(template, i));
|
||||||
|
constant.putFloat(getY(template, i));
|
||||||
|
constant.putFloat(getZ(template, i));
|
||||||
|
|
||||||
constant.put(getR(template, i));
|
constant.put(getNX(template, i));
|
||||||
constant.put(getG(template, i));
|
constant.put(getNY(template, i));
|
||||||
constant.put(getB(template, i));
|
constant.put(getNZ(template, i));
|
||||||
constant.put(getA(template, i));
|
|
||||||
}
|
|
||||||
constant.rewind();
|
|
||||||
|
|
||||||
GL30.glBindVertexArray(vao);
|
constant.putFloat(getU(template, i));
|
||||||
|
constant.putFloat(getV(template, i));
|
||||||
|
|
||||||
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, vbo);
|
constant.put(getR(template, i));
|
||||||
GlStateManager.bufferData(GL15.GL_ARRAY_BUFFER, constant.getBacking(), GL15.GL_STATIC_DRAW);
|
constant.put(getG(template, i));
|
||||||
buildEBO(ebo);
|
constant.put(getB(template, i));
|
||||||
|
constant.put(getA(template, i));
|
||||||
FORMAT.informAttributes(0);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
constant.rewind();
|
||||||
|
GL15.glUnmapBuffer(GL15.GL_ARRAY_BUFFER);
|
||||||
|
|
||||||
|
buildEBO(ebo);
|
||||||
|
|
||||||
|
FORMAT.informAttributes(0);
|
||||||
|
|
||||||
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, 0);
|
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, 0);
|
||||||
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
|
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
|
@ -8,6 +8,10 @@ import net.minecraft.world.LightType;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import org.lwjgl.opengl.*;
|
import org.lwjgl.opengl.*;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import static com.simibubi.create.foundation.render.RenderMath.nextPowerOf2;
|
||||||
|
|
||||||
public class ContraptionLighter {
|
public class ContraptionLighter {
|
||||||
|
|
||||||
private int minX;
|
private int minX;
|
||||||
|
@ -45,11 +49,6 @@ public class ContraptionLighter {
|
||||||
update(contraption);
|
update(contraption);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int nextPowerOf2(int a) {
|
|
||||||
int h = Integer.highestOneBit(a);
|
|
||||||
return (h == a) ? h : (h << 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSizeX() {
|
public int getSizeX() {
|
||||||
return sizeX;
|
return sizeX;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.simibubi.create.foundation.render;
|
||||||
|
|
||||||
|
public class RenderMath {
|
||||||
|
public static int nextPowerOf2(int a) {
|
||||||
|
int h = Integer.highestOneBit(a);
|
||||||
|
return (h == a) ? h : (h << 1);
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,20 +32,20 @@ public class TemplateBuffer {
|
||||||
((Buffer)template).rewind();
|
((Buffer)template).rewind();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void buildEBO(int ebo) throws Exception {
|
protected void buildEBO(int ebo){
|
||||||
int indicesSize = vertexCount * VertexFormatElement.Type.USHORT.getSize();
|
int indicesSize = vertexCount * VertexFormatElement.Type.USHORT.getSize();
|
||||||
try (SafeDirectBuffer indices = new SafeDirectBuffer(indicesSize)) {
|
|
||||||
indices.order(template.order());
|
|
||||||
indices.limit(indicesSize);
|
|
||||||
|
|
||||||
for (int i = 0; i < vertexCount; i++) {
|
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, ebo);
|
||||||
indices.putShort((short) i);
|
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesSize, GL15.GL_STATIC_DRAW);
|
||||||
}
|
|
||||||
indices.rewind();
|
|
||||||
|
|
||||||
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, ebo);
|
ByteBuffer indices = GL15.glMapBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, GL15.GL_WRITE_ONLY);
|
||||||
GlStateManager.bufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indices.getBacking(), GL15.GL_STATIC_DRAW);
|
|
||||||
|
for (int i = 0; i < vertexCount; i++) {
|
||||||
|
indices.putShort((short) i);
|
||||||
}
|
}
|
||||||
|
indices.rewind();
|
||||||
|
|
||||||
|
GL15.glUnmapBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
|
|
|
@ -2,10 +2,11 @@ package com.simibubi.create.foundation.render.instancing;
|
||||||
|
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||||
import com.simibubi.create.foundation.render.SafeDirectBuffer;
|
|
||||||
import net.minecraft.client.renderer.Vector3f;
|
import net.minecraft.client.renderer.Vector3f;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import static com.simibubi.create.foundation.render.instancing.VertexAttribute.*;
|
import static com.simibubi.create.foundation.render.instancing.VertexAttribute.*;
|
||||||
|
|
||||||
public class BasicData<D extends BasicData<D>> extends InstanceData {
|
public class BasicData<D extends BasicData<D>> extends InstanceData {
|
||||||
|
@ -17,16 +18,16 @@ public class BasicData<D extends BasicData<D>> extends InstanceData {
|
||||||
private float x;
|
private float x;
|
||||||
private float y;
|
private float y;
|
||||||
private float z;
|
private float z;
|
||||||
private float blockLight;
|
private byte blockLight;
|
||||||
private float skyLight;
|
private byte skyLight;
|
||||||
|
|
||||||
public D setBlockLight(int blockLight) {
|
public D setBlockLight(int blockLight) {
|
||||||
this.blockLight = blockLight / 15f;
|
this.blockLight = (byte) ((blockLight & 0xF) << 4);
|
||||||
return (D) this;
|
return (D) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public D setSkyLight(int skyLight) {
|
public D setSkyLight(int skyLight) {
|
||||||
this.skyLight = skyLight / 15f;
|
this.skyLight = (byte) ((skyLight & 0xF) << 4);
|
||||||
return (D) this;
|
return (D) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,10 +62,8 @@ public class BasicData<D extends BasicData<D>> extends InstanceData {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(SafeDirectBuffer buf) {
|
public void write(ByteBuffer buf) {
|
||||||
buf.put(r);
|
putVec3(buf, r, g, b);
|
||||||
buf.put(g);
|
|
||||||
buf.put(b);
|
|
||||||
|
|
||||||
putVec3(buf, x, y, z);
|
putVec3(buf, x, y, z);
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
package com.simibubi.create.foundation.render.instancing;
|
package com.simibubi.create.foundation.render.instancing;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
|
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
|
||||||
import com.simibubi.create.foundation.render.SafeDirectBuffer;
|
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import static com.simibubi.create.foundation.render.instancing.VertexAttribute.*;
|
import static com.simibubi.create.foundation.render.instancing.VertexAttribute.*;
|
||||||
|
|
||||||
public class BeltData extends BasicData<BeltData> {
|
public class BeltData extends BasicData<BeltData> {
|
||||||
|
@ -53,16 +54,16 @@ public class BeltData extends BasicData<BeltData> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(SafeDirectBuffer buf) {
|
public void write(ByteBuffer buf) {
|
||||||
super.write(buf);
|
super.write(buf);
|
||||||
|
|
||||||
putVec3(buf, rotX, rotY, rotZ);
|
putVec3(buf, rotX, rotY, rotZ);
|
||||||
|
|
||||||
putFloat(buf, rotationalSpeed);
|
put(buf, rotationalSpeed);
|
||||||
|
|
||||||
putVec2(buf, sourceU, sourceV);
|
putVec2(buf, sourceU, sourceV);
|
||||||
putVec4(buf, minU, minV, maxU, maxV);
|
putVec4(buf, minU, minV, maxU, maxV);
|
||||||
|
|
||||||
putFloat(buf, scrollMult);
|
put(buf, scrollMult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,14 @@ package com.simibubi.create.foundation.render.instancing;
|
||||||
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
import com.simibubi.create.foundation.render.RenderMath;
|
||||||
import com.simibubi.create.foundation.render.RenderWork;
|
import com.simibubi.create.foundation.render.RenderWork;
|
||||||
import com.simibubi.create.foundation.render.SafeDirectBuffer;
|
import com.simibubi.create.foundation.render.SafeDirectBuffer;
|
||||||
import com.simibubi.create.foundation.render.TemplateBuffer;
|
import com.simibubi.create.foundation.render.TemplateBuffer;
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
import org.lwjgl.opengl.*;
|
import org.lwjgl.opengl.*;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
@ -18,13 +20,15 @@ public abstract class InstanceBuffer<D extends InstanceData> extends TemplateBuf
|
||||||
|
|
||||||
protected int vao, ebo, invariantVBO, instanceVBO, instanceCount;
|
protected int vao, ebo, invariantVBO, instanceVBO, instanceCount;
|
||||||
|
|
||||||
|
protected int bufferSize = -1;
|
||||||
|
|
||||||
protected final ArrayList<D> data = new ArrayList<>();
|
protected final ArrayList<D> data = new ArrayList<>();
|
||||||
protected boolean rebuffer = false;
|
protected boolean rebuffer = false;
|
||||||
protected boolean shouldBuild = true;
|
protected boolean shouldBuild = true;
|
||||||
|
|
||||||
public InstanceBuffer(BufferBuilder buf) {
|
public InstanceBuffer(BufferBuilder buf) {
|
||||||
super(buf);
|
super(buf);
|
||||||
setup();
|
if (vertexCount > 0) setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setup() {
|
private void setup() {
|
||||||
|
@ -37,35 +41,33 @@ public abstract class InstanceBuffer<D extends InstanceData> extends TemplateBuf
|
||||||
invariantVBO = GlStateManager.genBuffers();
|
invariantVBO = GlStateManager.genBuffers();
|
||||||
instanceVBO = GlStateManager.genBuffers();
|
instanceVBO = GlStateManager.genBuffers();
|
||||||
|
|
||||||
try (SafeDirectBuffer constant = new SafeDirectBuffer(invariantSize)) {
|
GL30.glBindVertexArray(vao);
|
||||||
constant.order(template.order());
|
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, invariantVBO);
|
||||||
constant.limit(invariantSize);
|
|
||||||
|
|
||||||
for (int i = 0; i < vertexCount; i++) {
|
// allocate the buffer on the gpu
|
||||||
constant.putFloat(getX(template, i));
|
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, invariantSize, GL15.GL_STATIC_DRAW);
|
||||||
constant.putFloat(getY(template, i));
|
|
||||||
constant.putFloat(getZ(template, i));
|
|
||||||
|
|
||||||
constant.put(getNX(template, i));
|
// mirror it in system memory so we can write to it
|
||||||
constant.put(getNY(template, i));
|
ByteBuffer constant = GL15.glMapBuffer(GL15.GL_ARRAY_BUFFER, GL15.GL_WRITE_ONLY);
|
||||||
constant.put(getNZ(template, i));
|
|
||||||
|
|
||||||
constant.putFloat(getU(template, i));
|
for (int i = 0; i < vertexCount; i++) {
|
||||||
constant.putFloat(getV(template, i));
|
constant.putFloat(getX(template, i));
|
||||||
}
|
constant.putFloat(getY(template, i));
|
||||||
constant.rewind();
|
constant.putFloat(getZ(template, i));
|
||||||
|
|
||||||
GL30.glBindVertexArray(vao);
|
constant.put(getNX(template, i));
|
||||||
|
constant.put(getNY(template, i));
|
||||||
|
constant.put(getNZ(template, i));
|
||||||
|
|
||||||
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, invariantVBO);
|
constant.putFloat(getU(template, i));
|
||||||
GlStateManager.bufferData(GL15.GL_ARRAY_BUFFER, constant.getBacking(), GL15.GL_STATIC_DRAW);
|
constant.putFloat(getV(template, i));
|
||||||
|
|
||||||
buildEBO(ebo);
|
|
||||||
|
|
||||||
FORMAT.informAttributes(0);
|
|
||||||
} catch (Exception e) {
|
|
||||||
delete();
|
|
||||||
}
|
}
|
||||||
|
constant.rewind();
|
||||||
|
GL15.glUnmapBuffer(GL15.GL_ARRAY_BUFFER);
|
||||||
|
|
||||||
|
buildEBO(ebo);
|
||||||
|
|
||||||
|
FORMAT.informAttributes(0);
|
||||||
|
|
||||||
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, 0);
|
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, 0);
|
||||||
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
|
GlStateManager.bindBuffers(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
@ -93,16 +95,19 @@ public abstract class InstanceBuffer<D extends InstanceData> extends TemplateBuf
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
RenderWork.enqueue(() -> {
|
if (vertexCount > 0) {
|
||||||
GL15.glDeleteBuffers(invariantVBO);
|
RenderWork.enqueue(() -> {
|
||||||
GL15.glDeleteBuffers(instanceVBO);
|
GL15.glDeleteBuffers(invariantVBO);
|
||||||
GL15.glDeleteBuffers(ebo);
|
GL15.glDeleteBuffers(instanceVBO);
|
||||||
GL30.glDeleteVertexArrays(vao);
|
GL15.glDeleteBuffers(ebo);
|
||||||
vao = 0;
|
GL30.glDeleteVertexArrays(vao);
|
||||||
ebo = 0;
|
vao = 0;
|
||||||
invariantVBO = 0;
|
ebo = 0;
|
||||||
instanceVBO = 0;
|
invariantVBO = 0;
|
||||||
});
|
instanceVBO = 0;
|
||||||
|
bufferSize = -1;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract D newInstance();
|
protected abstract D newInstance();
|
||||||
|
@ -146,26 +151,27 @@ public abstract class InstanceBuffer<D extends InstanceData> extends TemplateBuf
|
||||||
|
|
||||||
VertexFormat instanceFormat = getInstanceFormat();
|
VertexFormat instanceFormat = getInstanceFormat();
|
||||||
|
|
||||||
int instanceSize = instanceCount * instanceFormat.getStride();
|
int instanceSize = RenderMath.nextPowerOf2(instanceCount * instanceFormat.getStride());
|
||||||
|
|
||||||
try (SafeDirectBuffer buffer = new SafeDirectBuffer(instanceSize)) {
|
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, instanceVBO);
|
||||||
buffer.order(template.order());
|
|
||||||
buffer.limit(instanceSize);
|
|
||||||
|
|
||||||
data.forEach(instanceData -> instanceData.write(buffer));
|
// this changes enough that it's not worth reallocating the entire buffer every time.
|
||||||
buffer.rewind();
|
if (instanceSize > bufferSize) {
|
||||||
|
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, instanceSize, GL15.GL_STATIC_DRAW);
|
||||||
|
bufferSize = instanceSize;
|
||||||
|
}
|
||||||
|
|
||||||
GlStateManager.bindBuffers(GL15.GL_ARRAY_BUFFER, instanceVBO);
|
ByteBuffer buffer = GL15.glMapBuffer(GL15.GL_ARRAY_BUFFER, GL15.GL_WRITE_ONLY);
|
||||||
GlStateManager.bufferData(GL15.GL_ARRAY_BUFFER, buffer.getBacking(), GL15.GL_STATIC_DRAW);
|
|
||||||
|
|
||||||
int staticAttributes = FORMAT.getNumAttributes();
|
data.forEach(instanceData -> instanceData.write(buffer));
|
||||||
instanceFormat.informAttributes(staticAttributes);
|
buffer.rewind();
|
||||||
|
GL15.glUnmapBuffer(GL15.GL_ARRAY_BUFFER);
|
||||||
|
|
||||||
for (int i = 0; i < instanceFormat.getNumAttributes(); i++) {
|
int staticAttributes = FORMAT.getNumAttributes();
|
||||||
GL33.glVertexAttribDivisor(i + staticAttributes, 1);
|
instanceFormat.informAttributes(staticAttributes);
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
for (int i = 0; i < instanceFormat.getNumAttributes(); i++) {
|
||||||
e.printStackTrace();
|
GL33.glVertexAttribDivisor(i + staticAttributes, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deselect (bind to 0) the VBO
|
// Deselect (bind to 0) the VBO
|
||||||
|
|
|
@ -1,30 +1,45 @@
|
||||||
package com.simibubi.create.foundation.render.instancing;
|
package com.simibubi.create.foundation.render.instancing;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.render.SafeDirectBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
public abstract class InstanceData {
|
public abstract class InstanceData {
|
||||||
|
|
||||||
public abstract void write(SafeDirectBuffer buf);
|
public abstract void write(ByteBuffer buf);
|
||||||
|
|
||||||
public void putVec4(SafeDirectBuffer buf, float x, float y, float z, float w) {
|
public void putVec4(ByteBuffer buf, float x, float y, float z, float w) {
|
||||||
putFloat(buf, x);
|
put(buf, x);
|
||||||
putFloat(buf, y);
|
put(buf, y);
|
||||||
putFloat(buf, z);
|
put(buf, z);
|
||||||
putFloat(buf, w);
|
put(buf, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putVec3(SafeDirectBuffer buf, float x, float y, float z) {
|
public void putVec3(ByteBuffer buf, float x, float y, float z) {
|
||||||
putFloat(buf, x);
|
put(buf, x);
|
||||||
putFloat(buf, y);
|
put(buf, y);
|
||||||
putFloat(buf, z);
|
put(buf, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putVec2(SafeDirectBuffer buf, float x, float y) {
|
public void putVec2(ByteBuffer buf, float x, float y) {
|
||||||
putFloat(buf, x);
|
put(buf, x);
|
||||||
putFloat(buf, y);
|
put(buf, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putFloat(SafeDirectBuffer buf, float f) {
|
public void putVec3(ByteBuffer buf, byte x, byte y, byte z) {
|
||||||
|
put(buf, x);
|
||||||
|
put(buf, y);
|
||||||
|
put(buf, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putVec2(ByteBuffer buf, byte x, byte y) {
|
||||||
|
put(buf, x);
|
||||||
|
put(buf, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put(ByteBuffer buf, byte b) {
|
||||||
|
buf.put(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put(ByteBuffer buf, float f) {
|
||||||
buf.putFloat(f);
|
buf.putFloat(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package com.simibubi.create.foundation.render.instancing;
|
package com.simibubi.create.foundation.render.instancing;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.render.SafeDirectBuffer;
|
|
||||||
import net.minecraft.client.renderer.Vector3f;
|
import net.minecraft.client.renderer.Vector3f;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import static com.simibubi.create.foundation.render.instancing.VertexAttribute.*;
|
import static com.simibubi.create.foundation.render.instancing.VertexAttribute.*;
|
||||||
|
|
||||||
public class RotatingData extends BasicData<RotatingData> {
|
public class RotatingData extends BasicData<RotatingData> {
|
||||||
|
@ -39,10 +40,10 @@ public class RotatingData extends BasicData<RotatingData> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(SafeDirectBuffer buf) {
|
public void write(ByteBuffer buf) {
|
||||||
super.write(buf);
|
super.write(buf);
|
||||||
putFloat(buf, rotationalSpeed);
|
put(buf, rotationalSpeed);
|
||||||
putFloat(buf, rotationOffset);
|
put(buf, rotationOffset);
|
||||||
|
|
||||||
putVec3(buf, rotationAxisX, rotationAxisY, rotationAxisZ);
|
putVec3(buf, rotationAxisX, rotationAxisY, rotationAxisZ);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,10 @@ public class VertexAttribute {
|
||||||
|
|
||||||
public static final VertexAttribute POSITION = VEC3;
|
public static final VertexAttribute POSITION = VEC3;
|
||||||
public static final VertexAttribute NORMAL = new VertexAttribute(VertexFormatElement.Type.BYTE, 3, true);
|
public static final VertexAttribute NORMAL = new VertexAttribute(VertexFormatElement.Type.BYTE, 3, true);
|
||||||
public static final VertexAttribute RGBA = new VertexAttribute(VertexFormatElement.Type.BYTE, 4, true);
|
public static final VertexAttribute RGBA = new VertexAttribute(VertexFormatElement.Type.UBYTE, 4, true);
|
||||||
public static final VertexAttribute RGB = new VertexAttribute(VertexFormatElement.Type.BYTE, 3, true);
|
public static final VertexAttribute RGB = new VertexAttribute(VertexFormatElement.Type.UBYTE, 3, true);
|
||||||
public static final VertexAttribute UV = VEC2;
|
public static final VertexAttribute UV = VEC2;
|
||||||
public static final VertexAttribute LIGHT = new VertexAttribute(VertexFormatElement.Type.FLOAT, 2);
|
public static final VertexAttribute LIGHT = new VertexAttribute(VertexFormatElement.Type.UBYTE, 2, true);
|
||||||
|
|
||||||
private final VertexFormatElement.Type type;
|
private final VertexFormatElement.Type type;
|
||||||
private final int count;
|
private final int count;
|
||||||
|
|
|
@ -43,8 +43,8 @@ void main() {
|
||||||
vec4 worldPos = model * vec4(aPos, 1);
|
vec4 worldPos = model * vec4(aPos, 1);
|
||||||
|
|
||||||
BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize;
|
BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize;
|
||||||
Diffuse = diffuse(normalize(model * vec4(aNormal, 0.)).xyz);
|
Diffuse = diffuse((model * vec4(aNormal, 0.)).xyz);
|
||||||
Color = vec4(1);//aColor;
|
Color = aColor / diffuse(aNormal);
|
||||||
TexCoords = aTexCoords;
|
TexCoords = aTexCoords;
|
||||||
gl_Position = projection * view * worldPos;
|
gl_Position = projection * view * worldPos;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,13 +49,17 @@ void main() {
|
||||||
|
|
||||||
renderPos += vec4(instancePos + vec3(0.5), 0);
|
renderPos += vec4(instancePos + vec3(0.5), 0);
|
||||||
|
|
||||||
Diffuse = diffuse(normalize((rotation * vec4(aNormal, 0.)).xyz));
|
vec3 norm = (rotation * vec4(aNormal, 0.)).xyz;
|
||||||
|
|
||||||
|
Diffuse = diffuse(norm);
|
||||||
TexCoords = aTexCoords;
|
TexCoords = aTexCoords;
|
||||||
gl_Position = projection * view * renderPos;
|
gl_Position = projection * view * renderPos;
|
||||||
Light = light;
|
Light = light;
|
||||||
|
|
||||||
if (debug == 1) {
|
if (debug == 1) {
|
||||||
Color = vec4(networkTint, 1);
|
Color = vec4(networkTint, 1);
|
||||||
|
} else if (debug == 2) {
|
||||||
|
Color = vec4(norm, 1);
|
||||||
} else {
|
} else {
|
||||||
Color = vec4(1);
|
Color = vec4(1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue