Begin buffer rework

This commit is contained in:
JozsefA 2021-05-14 18:04:25 -07:00
parent 7abc860809
commit a9cdb1ab6b
31 changed files with 487 additions and 351 deletions

View file

@ -1,11 +1,11 @@
package com.jozufozu.flywheel.backend;
import java.nio.ByteBuffer;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import com.jozufozu.flywheel.backend.gl.GlBuffer;
import com.jozufozu.flywheel.backend.gl.GlBufferType;
import com.jozufozu.flywheel.backend.gl.MappedBufferRange;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
import com.simibubi.create.foundation.render.TemplateBuffer;
@ -23,9 +23,11 @@ public abstract class BufferedModel extends TemplateBuffer {
protected void init() {
modelVBO = new GlBuffer(GL20.GL_ARRAY_BUFFER);
modelVBO = new GlBuffer(GlBufferType.ARRAY_BUFFER);
modelVBO.with(vbo -> initModel());
modelVBO.bind();
initModel();
modelVBO.unbind();
}
protected void initModel() {
@ -36,14 +38,14 @@ public abstract class BufferedModel extends TemplateBuffer {
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, invariantSize, GL15.GL_STATIC_DRAW);
// mirror it in system memory so we can write to it
modelVBO.map(invariantSize, buffer -> {
MappedBufferRange buffer = modelVBO.getBuffer(0, invariantSize);
for (int i = 0; i < vertexCount; i++) {
copyVertex(buffer, i);
}
});
buffer.unmap();
}
protected abstract void copyVertex(ByteBuffer to, int index);
protected abstract void copyVertex(MappedBufferRange to, int index);
protected abstract VertexFormat getModelFormat();

View file

@ -1,7 +1,6 @@
package com.jozufozu.flywheel.backend.core;
import static org.lwjgl.opengl.GL20.glUniform1f;
import static org.lwjgl.opengl.GL20.glUniform1i;
import static org.lwjgl.opengl.GL20.glUniform3f;
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
@ -14,7 +13,6 @@ import net.minecraft.util.math.vector.Matrix4f;
public class BasicProgram extends GlProgram {
protected final int uTime;
protected final int uViewProjection;
protected final int uDebug;
protected final int uCameraPos;
protected final ProgramFogMode fogMode;
@ -30,7 +28,6 @@ public class BasicProgram extends GlProgram {
super(name, handle);
uTime = getUniformLocation("uTime");
uViewProjection = getUniformLocation("uViewProjection");
uDebug = getUniformLocation("uDebug");
uCameraPos = getUniformLocation("uCameraPos");
fogMode = fogFactory.create(this);
@ -45,14 +42,23 @@ public class BasicProgram extends GlProgram {
uLightMap = setSamplerBinding("uLightMap", 2);
}
public void bind(Matrix4f viewProjection, double camX, double camY, double camZ, int debugMode) {
public void uploadViewProjection(Matrix4f viewProjection) {
uploadMatrixUniform(uViewProjection, viewProjection);
}
public void uploadCameraPos(double camX, double camY, double camZ) {
glUniform3f(uCameraPos, (float) camX, (float) camY, (float) camZ);
}
public void uploadTime(float renderTime) {
glUniform1f(uTime, renderTime);
}
@Override
public void bind() {
super.bind();
glUniform1i(uDebug, debugMode);
glUniform1f(uTime, AnimationTickHolder.getRenderTime());
uploadMatrixUniform(uViewProjection, viewProjection);
glUniform3f(uCameraPos, (float) camX, (float) camY, (float) camZ);
uploadTime(AnimationTickHolder.getRenderTime());
fogMode.bind();
}

View file

@ -1,7 +1,6 @@
package com.jozufozu.flywheel.backend.core.materials;
import java.nio.ByteBuffer;
import com.jozufozu.flywheel.backend.gl.MappedBuffer;
import com.jozufozu.flywheel.backend.instancing.InstanceData;
import com.jozufozu.flywheel.backend.instancing.InstancedModel;
@ -72,7 +71,7 @@ public class BasicData extends InstanceData implements IFlatLight<BasicData> {
}
@Override
public void write(ByteBuffer buf) {
buf.put(new byte[]{blockLight, skyLight, r, g, b, a});
public void write(MappedBuffer buf) {
buf.putByteArray(new byte[]{blockLight, skyLight, r, g, b, a});
}
}

View file

@ -1,7 +1,6 @@
package com.jozufozu.flywheel.backend.core.materials;
import java.nio.ByteBuffer;
import com.jozufozu.flywheel.backend.gl.MappedBuffer;
import com.jozufozu.flywheel.backend.instancing.InstancedModel;
import com.jozufozu.flywheel.util.RenderUtil;
import com.mojang.blaze3d.matrix.MatrixStack;
@ -22,9 +21,8 @@ public class ModelData extends BasicData {
}
@Override
public void write(ByteBuffer buf) {
public void write(MappedBuffer buf) {
super.write(buf);
buf.asFloatBuffer().put(matrices);
buf.position(buf.position() + matrices.length * 4);
buf.putFloatArray(matrices);
}
}

View file

@ -1,7 +1,6 @@
package com.jozufozu.flywheel.backend.core.materials;
import java.nio.ByteBuffer;
import com.jozufozu.flywheel.backend.gl.MappedBuffer;
import com.jozufozu.flywheel.backend.instancing.InstancedModel;
import net.minecraft.util.math.BlockPos;
@ -82,10 +81,10 @@ public class OrientedData extends BasicData {
}
@Override
public void write(ByteBuffer buf) {
public void write(MappedBuffer buf) {
super.write(buf);
buf.asFloatBuffer().put(new float[]{
buf.putFloatArray(new float[]{
posX,
posY,
posZ,
@ -97,8 +96,6 @@ public class OrientedData extends BasicData {
qZ,
qW
});
buf.position(buf.position() + 10 * 4);
}
}

View file

@ -1,62 +1,50 @@
package com.jozufozu.flywheel.backend.gl;
import java.nio.ByteBuffer;
import java.util.function.Consumer;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import com.jozufozu.flywheel.backend.Backend;
import org.lwjgl.opengl.GL30;
public class GlBuffer extends GlObject {
protected final int bufferType;
protected final GlBufferType type;
protected final GlBufferUsage usage;
public GlBuffer(int bufferType) {
setHandle(GL20.glGenBuffers());
this.bufferType = bufferType;
public GlBuffer(GlBufferType type) {
this(type, GlBufferUsage.STATIC_DRAW);
}
public int getBufferType() {
return bufferType;
public GlBuffer(GlBufferType type, GlBufferUsage usage) {
setHandle(GL20.glGenBuffers());
this.type = type;
this.usage = usage;
}
public GlBufferType getBufferTarget() {
return type;
}
public void bind() {
bind(bufferType);
bind(type);
}
public void bind(int type) {
GL20.glBindBuffer(type, handle());
public void bind(GlBufferType type) {
GL20.glBindBuffer(type.glEnum, handle());
}
public void unbind() {
unbind(bufferType);
unbind(type);
}
public void unbind(int bufferType) {
GL20.glBindBuffer(bufferType, 0);
public void unbind(GlBufferType bufferType) {
GL20.glBindBuffer(bufferType.glEnum, 0);
}
public void alloc(int size, int usage) {
GL15.glBufferData(bufferType, size, usage);
public void alloc(int size) {
GL15.glBufferData(type.glEnum, size, usage.glEnum);
}
public void with(Consumer<GlBuffer> action) {
bind();
action.accept(this);
unbind();
}
public void map(int length, Consumer<ByteBuffer> upload) {
Backend.compat.mapBuffer.mapBuffer(bufferType, 0, length, upload);
}
public void map(int offset, int length, Consumer<ByteBuffer> upload) {
Backend.compat.mapBuffer.mapBuffer(bufferType, offset, length, upload);
}
public void map(int type, int offset, int length, Consumer<ByteBuffer> upload) {
Backend.compat.mapBuffer.mapBuffer(type, offset, length, upload);
public MappedBufferRange getBuffer(int offset, int length) {
return MappedBufferRange.create(this, offset, length, GL30.GL_MAP_WRITE_BIT);
}
protected void deleteInternal(int handle) {

View file

@ -0,0 +1,32 @@
package com.jozufozu.flywheel.backend.gl;
import org.lwjgl.opengl.GL15C;
import org.lwjgl.opengl.GL21;
import org.lwjgl.opengl.GL30;
import org.lwjgl.opengl.GL31;
import org.lwjgl.opengl.GL40;
import org.lwjgl.opengl.GL42;
import org.lwjgl.opengl.GL43;
public enum GlBufferType {
ARRAY_BUFFER(GL15C.GL_ARRAY_BUFFER),
ELEMENT_ARRAY_BUFFER(GL15C.GL_ELEMENT_ARRAY_BUFFER),
PIXEL_PACK_BUFFER(GL21.GL_PIXEL_PACK_BUFFER),
PIXEL_UNPACK_BUFFER(GL21.GL_PIXEL_UNPACK_BUFFER),
TRANSFORM_FEEDBACK_BUFFER(GL30.GL_TRANSFORM_FEEDBACK_BUFFER),
UNIFORM_BUFFER(GL31.GL_UNIFORM_BUFFER),
TEXTURE_BUFFER(GL31.GL_TEXTURE_BUFFER),
COPY_READ_BUFFER(GL31.GL_COPY_READ_BUFFER),
COPY_WRITE_BUFFER(GL31.GL_COPY_WRITE_BUFFER),
DRAW_INDIRECT_BUFFER(GL40.GL_DRAW_INDIRECT_BUFFER),
ATOMIC_COUNTER_BUFFER(GL42.GL_ATOMIC_COUNTER_BUFFER),
DISPATCH_INDIRECT_BUFFER(GL43.GL_DISPATCH_INDIRECT_BUFFER),
SHADER_STORAGE_BUFFER(GL43.GL_SHADER_STORAGE_BUFFER),
;
public final int glEnum;
GlBufferType(int glEnum) {
this.glEnum = glEnum;
}
}

View file

@ -0,0 +1,22 @@
package com.jozufozu.flywheel.backend.gl;
import org.lwjgl.opengl.GL15;
public enum GlBufferUsage {
STREAM_DRAW(GL15.GL_STREAM_DRAW),
STREAM_READ(GL15.GL_STREAM_READ),
STREAM_COPY(GL15.GL_STREAM_COPY),
STATIC_DRAW(GL15.GL_STATIC_DRAW),
STATIC_READ(GL15.GL_STATIC_READ),
STATIC_COPY(GL15.GL_STATIC_COPY),
DYNAMIC_DRAW(GL15.GL_DYNAMIC_DRAW),
DYNAMIC_READ(GL15.GL_DYNAMIC_READ),
DYNAMIC_COPY(GL15.GL_DYNAMIC_COPY),
;
public final int glEnum;
GlBufferUsage(int glEnum) {
this.glEnum = glEnum;
}
}

View file

@ -1,7 +1,5 @@
package com.jozufozu.flywheel.backend.gl;
import java.util.function.Consumer;
import com.jozufozu.flywheel.backend.Backend;
public class GlVertexArray extends GlObject {
@ -17,12 +15,6 @@ public class GlVertexArray extends GlObject {
Backend.compat.vao.bindVertexArray(0);
}
public void with(Consumer<GlVertexArray> action) {
bind();
action.accept(this);
unbind();
}
protected void deleteInternal(int handle) {
Backend.compat.vao.deleteVertexArrays(handle);
}

View file

@ -0,0 +1,84 @@
package com.jozufozu.flywheel.backend.gl;
import java.nio.ByteBuffer;
public abstract class MappedBuffer implements AutoCloseable {
private final ByteBuffer internal;
public MappedBuffer(ByteBuffer internal) {
this.internal = internal;
}
public MappedBuffer putFloatArray(float[] floats) {
internal.asFloatBuffer().put(floats);
internal.position(internal.position() + floats.length * 4);
return this;
}
public MappedBuffer putByteArray(byte[] bytes) {
internal.put(bytes);
return this;
}
public MappedBuffer position(int p) {
internal.position(p);
return this;
}
public MappedBuffer putFloat(float f) {
internal.putFloat(f);
return this;
}
public MappedBuffer putInt(int i) {
internal.putInt(i);
return this;
}
public MappedBuffer put(byte b) {
internal.put(b);
return this;
}
public MappedBuffer putVec4(float x, float y, float z, float w) {
internal.putFloat(x);
internal.putFloat(y);
internal.putFloat(z);
internal.putFloat(w);
return this;
}
public MappedBuffer putVec3(float x, float y, float z) {
internal.putFloat(x);
internal.putFloat(y);
internal.putFloat(z);
return this;
}
public MappedBuffer putVec2(float x, float y) {
internal.putFloat(x);
internal.putFloat(y);
return this;
}
public MappedBuffer putVec3(byte x, byte y, byte z) {
internal.put(x);
internal.put(y);
internal.put(z);
return this;
}
public MappedBuffer putVec2(byte x, byte y) {
internal.put(x);
internal.put(y);
return this;
}
}

View file

@ -0,0 +1,31 @@
package com.jozufozu.flywheel.backend.gl;
import java.nio.ByteBuffer;
import org.lwjgl.opengl.GL30;
public class MappedBufferRange extends MappedBuffer {
GlBuffer owner;
public MappedBufferRange(GlBuffer buffer, ByteBuffer internal) {
super(internal);
this.owner = buffer;
}
public static MappedBufferRange create(GlBuffer buffer, long offset, long length, int access) {
ByteBuffer byteBuffer = GL30.glMapBufferRange(buffer.type.glEnum, offset, length, access);
return new MappedBufferRange(buffer, byteBuffer);
}
public MappedBuffer unmap() {
GL30.glUnmapBuffer(owner.type.glEnum);
return this;
}
@Override
public void close() throws Exception {
unmap();
}
}

View file

@ -8,6 +8,8 @@ import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL30;
import org.lwjgl.opengl.GLCapabilities;
import com.jozufozu.flywheel.backend.gl.GlBufferType;
public enum MapBuffer implements GlVersioned {
GL30_RANGE {
@ -16,14 +18,18 @@ public enum MapBuffer implements GlVersioned {
return caps.OpenGL30;
}
public ByteBuffer mapBuffer(GlBufferType target, long offset, long length, int access) {
return GL30.glMapBufferRange(target.glEnum, offset, length, access);
}
@Override
public void mapBuffer(int target, int offset, int length, Consumer<ByteBuffer> upload) {
ByteBuffer buffer = GL30.glMapBufferRange(target, offset, length, GL30.GL_MAP_WRITE_BIT);
public void mapBuffer(GlBufferType target, int offset, int length, Consumer<ByteBuffer> upload) {
ByteBuffer buffer = mapBuffer(target, offset, length, GL30.GL_MAP_WRITE_BIT);
upload.accept(buffer);
buffer.rewind();
GL30.glUnmapBuffer(target);
GL30.glUnmapBuffer(target.glEnum);
}
},
ARB_RANGE {
@ -32,14 +38,18 @@ public enum MapBuffer implements GlVersioned {
return caps.GL_ARB_map_buffer_range;
}
public ByteBuffer mapBuffer(GlBufferType target, long offset, long length, int access) {
return ARBMapBufferRange.glMapBufferRange(target.glEnum, offset, length, access);
}
@Override
public void mapBuffer(int target, int offset, int length, Consumer<ByteBuffer> upload) {
ByteBuffer buffer = ARBMapBufferRange.glMapBufferRange(target, offset, length, GL30.GL_MAP_WRITE_BIT);
public void mapBuffer(GlBufferType target, int offset, int length, Consumer<ByteBuffer> upload) {
ByteBuffer buffer = ARBMapBufferRange.glMapBufferRange(target.glEnum, offset, length, GL30.GL_MAP_WRITE_BIT);
upload.accept(buffer);
buffer.rewind();
GL30.glUnmapBuffer(target);
GL30.glUnmapBuffer(target.glEnum);
}
},
GL15_MAP {
@ -49,13 +59,13 @@ public enum MapBuffer implements GlVersioned {
}
@Override
public void mapBuffer(int target, int offset, int length, Consumer<ByteBuffer> upload) {
ByteBuffer buffer = GL15.glMapBuffer(target, GL15.GL_WRITE_ONLY);
public void mapBuffer(GlBufferType target, int offset, int length, Consumer<ByteBuffer> upload) {
ByteBuffer buffer = GL15.glMapBuffer(target.glEnum, GL15.GL_WRITE_ONLY);
buffer.position(offset);
upload.accept(buffer);
buffer.rewind();
GL15.glUnmapBuffer(target);
GL15.glUnmapBuffer(target.glEnum);
}
},
UNSUPPORTED {
@ -65,11 +75,20 @@ public enum MapBuffer implements GlVersioned {
}
@Override
public void mapBuffer(int target, int offset, int length, Consumer<ByteBuffer> upload) {
public void mapBuffer(GlBufferType target, int offset, int length, Consumer<ByteBuffer> upload) {
throw new UnsupportedOperationException("glMapBuffer not supported");
}
@Override
public void unmapBuffer(int target) {
throw new UnsupportedOperationException("glMapBuffer not supported");
}
};
public abstract void mapBuffer(int target, int offset, int length, Consumer<ByteBuffer> upload);
public void unmapBuffer(int target) {
GL15.glUnmapBuffer(target);
}
public abstract void mapBuffer(GlBufferType target, int offset, int length, Consumer<ByteBuffer> upload);
}

View file

@ -1,6 +1,6 @@
package com.jozufozu.flywheel.backend.instancing;
import java.nio.ByteBuffer;
import com.jozufozu.flywheel.backend.gl.MappedBuffer;
public abstract class InstanceData {
@ -13,7 +13,7 @@ public abstract class InstanceData {
this.owner = owner;
}
public abstract void write(ByteBuffer buf);
public abstract void write(MappedBuffer buf);
public void markDirty() {
owner.anyToUpdate = true;
@ -25,40 +25,4 @@ public abstract class InstanceData {
removed = true;
}
public void putVec4(ByteBuffer buf, float x, float y, float z, float w) {
put(buf, x);
put(buf, y);
put(buf, z);
put(buf, w);
}
public void putVec3(ByteBuffer buf, float x, float y, float z) {
put(buf, x);
put(buf, y);
put(buf, z);
}
public void putVec2(ByteBuffer buf, float x, float y) {
put(buf, x);
put(buf, y);
}
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);
}
}

View file

@ -1,19 +1,18 @@
package com.jozufozu.flywheel.backend.instancing;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.BitSet;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.BufferedModel;
import com.jozufozu.flywheel.backend.core.materials.ModelAttributes;
import com.jozufozu.flywheel.backend.gl.GlBuffer;
import com.jozufozu.flywheel.backend.gl.GlBufferType;
import com.jozufozu.flywheel.backend.gl.GlVertexArray;
import com.jozufozu.flywheel.backend.gl.MappedBufferRange;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
import net.minecraft.client.renderer.BufferBuilder;
@ -41,9 +40,11 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
@Override
protected void init() {
vao = new GlVertexArray();
instanceVBO = new GlBuffer(GL20.GL_ARRAY_BUFFER);
instanceVBO = new GlBuffer(GlBufferType.ARRAY_BUFFER);
vao.with(vao -> super.init());
vao.bind();
super.init();
vao.unbind();
}
@Override
@ -79,12 +80,12 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
protected abstract D newInstance();
protected void doRender() {
vao.with(vao -> {
vao.bind();
renderSetup();
if (glInstanceCount > 0)
Backend.compat.drawInstanced.drawArraysInstanced(GL11.GL_QUADS, 0, vertexCount, glInstanceCount);
});
vao.unbind();
}
protected void renderSetup() {
@ -127,9 +128,9 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
final int offset = size * getInstanceFormat().getStride();
final int length = glBufferSize - offset;
if (length > 0) {
instanceVBO.map(offset, length, buffer -> {
buffer.put(new byte[length]);
});
MappedBufferRange buffer = instanceVBO.getBuffer(offset, length);
buffer.putByteArray(new byte[length]);
buffer.unmap();
}
}
@ -150,14 +151,14 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
final int length = (1 + lastDirty - firstDirty) * stride;
if (length > 0) {
instanceVBO.map(offset, length, buffer -> {
MappedBufferRange mapped = instanceVBO.getBuffer(offset, length);
dirtySet.stream().forEach(i -> {
final D d = data.get(i);
buffer.position(i * stride - offset);
d.write(buffer);
});
mapped.position(i * stride - offset);
d.write(mapped);
});
mapped.unmap();
}
}
@ -182,13 +183,13 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
int requiredSize = size * stride;
if (requiredSize > glBufferSize) {
glBufferSize = requiredSize + stride * 16;
instanceVBO.alloc(glBufferSize, GL15.GL_STATIC_DRAW);
instanceVBO.alloc(glBufferSize);
instanceVBO.map(glBufferSize, buffer -> {
MappedBufferRange buffer = instanceVBO.getBuffer(0, glBufferSize);
for (D datum : data) {
datum.write(buffer);
}
});
buffer.unmap();
glInstanceCount = size;
return true;
@ -231,7 +232,7 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
}
@Override
protected void copyVertex(ByteBuffer constant, int i) {
protected void copyVertex(MappedBufferRange constant, int i) {
constant.putFloat(getX(template, i));
constant.putFloat(getY(template, i));
constant.putFloat(getZ(template, i));

View file

@ -132,7 +132,6 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
*/
public void render(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ, ShaderCallback<P> callback) {
for (RenderMaterial<P, ?> material : materials.values()) {
if (material.canRenderInLayer(layer))
material.render(layer, viewProjection, camX, camY, camZ, callback);
}
}

View file

@ -1,24 +1,20 @@
package com.jozufozu.flywheel.backend.instancing;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import org.apache.commons.lang3.tuple.Pair;
import org.lwjgl.opengl.GL11;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.core.BasicProgram;
import com.jozufozu.flywheel.backend.core.PartialModel;
import com.jozufozu.flywheel.backend.gl.shader.ProgramSpec;
import com.jozufozu.flywheel.backend.gl.shader.ShaderCallback;
import com.jozufozu.flywheel.util.BakedQuadWrapper;
import com.jozufozu.flywheel.util.RenderUtil;
import com.jozufozu.flywheel.util.VirtualEmptyModelData;
import com.mojang.blaze3d.matrix.MatrixStack;
@ -29,14 +25,12 @@ import net.minecraft.client.renderer.BlockModelRenderer;
import net.minecraft.client.renderer.BlockRendererDispatcher;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Matrix4f;
import net.minecraftforge.client.model.data.IModelData;
public class RenderMaterial<P extends BasicProgram, MODEL extends InstancedModel<?>> {
@ -72,8 +66,12 @@ public class RenderMaterial<P extends BasicProgram, MODEL extends InstancedModel
}
public void render(RenderType layer, Matrix4f viewProjection, double camX, double camY, double camZ, ShaderCallback<P> setup) {
if (!canRenderInLayer(layer)) return;
P program = renderer.context.getProgram(programSpec);
program.bind(viewProjection, camX, camY, camZ, Backend.getDebugMode());
program.bind();
program.uploadViewProjection(viewProjection);
program.uploadCameraPos(camX, camY, camZ);
if (setup != null) setup.call(program);
@ -150,12 +148,12 @@ public class RenderMaterial<P extends BasicProgram, MODEL extends InstancedModel
BlockModelRenderer blockRenderer = dispatcher.getBlockModelRenderer();
BufferBuilder builder = new BufferBuilder(512);
BakedQuadWrapper quadReader = new BakedQuadWrapper();
IModelData modelData = model.getModelData(mc.world, BlockPos.ZERO.up(255), referenceState, VirtualEmptyModelData.INSTANCE);
List<BakedQuad> quads = Arrays.stream(dirs)
.flatMap(dir -> model.getQuads(referenceState, dir, mc.world.rand, modelData).stream())
.collect(Collectors.toList());
// BakedQuadWrapper quadReader = new BakedQuadWrapper();
//
// IModelData modelData = model.getModelData(mc.world, BlockPos.ZERO.up(255), referenceState, VirtualEmptyModelData.INSTANCE);
// List<BakedQuad> quads = Arrays.stream(dirs)
// .flatMap(dir -> model.getQuads(referenceState, dir, mc.world.rand, modelData).stream())
// .collect(Collectors.toList());
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
blockRenderer.renderModel(mc.world, model, referenceState, BlockPos.ZERO.up(255), ms, builder, true,

View file

@ -1,8 +1,7 @@
package com.simibubi.create.content.contraptions.base;
import java.nio.ByteBuffer;
import com.jozufozu.flywheel.backend.core.materials.BasicData;
import com.jozufozu.flywheel.backend.gl.MappedBuffer;
import com.jozufozu.flywheel.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.utility.ColorHelper;
@ -84,17 +83,15 @@ public class KineticData extends BasicData {
@Override
public void write(ByteBuffer buf) {
public void write(MappedBuffer buf) {
super.write(buf);
buf.asFloatBuffer().put(new float[] {
buf.putFloatArray(new float[]{
x,
y,
z,
rotationalSpeed,
rotationOffset
});
buf.position(buf.position() + 5 * 4);
}
}

View file

@ -1,7 +1,6 @@
package com.simibubi.create.content.contraptions.base;
import java.nio.ByteBuffer;
import com.jozufozu.flywheel.backend.gl.MappedBuffer;
import com.jozufozu.flywheel.backend.instancing.InstancedModel;
import net.minecraft.util.Direction;
@ -36,9 +35,9 @@ public class RotatingData extends KineticData {
}
@Override
public void write(ByteBuffer buf) {
public void write(MappedBuffer buf) {
super.write(buf);
putVec3(buf, rotationAxisX, rotationAxisY, rotationAxisZ);
buf.putVec3(rotationAxisX, rotationAxisY, rotationAxisZ);
}
}

View file

@ -1,7 +1,6 @@
package com.simibubi.create.content.contraptions.components.actors;
import java.nio.ByteBuffer;
import com.jozufozu.flywheel.backend.gl.MappedBuffer;
import com.jozufozu.flywheel.backend.instancing.InstanceData;
import com.jozufozu.flywheel.backend.instancing.InstancedModel;
@ -102,14 +101,14 @@ public class ActorData extends InstanceData {
}
@Override
public void write(ByteBuffer buf) {
putVec3(buf, x, y, z);
putVec2(buf, blockLight, skyLight);
put(buf, rotationOffset);
putVec3(buf, rotationAxisX, rotationAxisY, rotationAxisZ);
putVec4(buf, qX, qY, qZ, qW);
putVec3(buf, rotationCenterX, rotationCenterY, rotationCenterZ);
put(buf, speed);
public void write(MappedBuffer buf) {
buf.putVec3(x, y, z);
buf.putVec2(blockLight, skyLight);
buf.putFloat(rotationOffset);
buf.putVec3(rotationAxisX, rotationAxisY, rotationAxisZ);
buf.putVec4(qX, qY, qZ, qW);
buf.putVec3(rotationCenterX, rotationCenterY, rotationCenterZ);
buf.putFloat(speed);
}
}

View file

@ -1,13 +1,12 @@
package com.simibubi.create.content.contraptions.components.structureMovement.render;
import java.nio.ByteBuffer;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import com.jozufozu.flywheel.backend.BufferedModel;
import com.jozufozu.flywheel.backend.gl.GlBuffer;
import com.jozufozu.flywheel.backend.gl.GlBufferType;
import com.jozufozu.flywheel.backend.gl.GlPrimitiveType;
import com.jozufozu.flywheel.backend.gl.MappedBufferRange;
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
import net.minecraft.client.renderer.BufferBuilder;
@ -50,25 +49,25 @@ public class ContraptionModel extends BufferedModel {
}
protected final void createEBO() {
ebo = new GlBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER);
ebo = new GlBuffer(GlBufferType.ELEMENT_ARRAY_BUFFER);
eboIndexType = GlPrimitiveType.UINT; // TODO: choose this based on the number of vertices
int indicesSize = vertexCount * eboIndexType.getSize();
ebo.bind();
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesSize, GL15.GL_STATIC_DRAW);
ebo.map(indicesSize, indices -> {
ebo.alloc(indicesSize);
MappedBufferRange indices = ebo.getBuffer(0, indicesSize);
for (int i = 0; i < vertexCount; i++) {
indices.putInt(i);
}
});
indices.unmap();
ebo.unbind();
}
@Override
protected void copyVertex(ByteBuffer to, int vertex) {
protected void copyVertex(MappedBufferRange to, int vertex) {
to.putFloat(getX(template, vertex));
to.putFloat(getY(template, vertex));
to.putFloat(getZ(template, vertex));

View file

@ -1,12 +1,17 @@
package com.simibubi.create.content.contraptions.components.structureMovement.render;
import static org.lwjgl.opengl.GL13.GL_QUADS;
import static org.lwjgl.opengl.GL13.GL_TEXTURE0;
import static org.lwjgl.opengl.GL13.GL_TEXTURE4;
import static org.lwjgl.opengl.GL13.GL_TEXTURE_3D;
import static org.lwjgl.opengl.GL13.glActiveTexture;
import static org.lwjgl.opengl.GL13.glDisable;
import static org.lwjgl.opengl.GL13.glEnable;
import java.util.List;
import java.util.Random;
import org.apache.commons.lang3.tuple.Pair;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL40;
import com.jozufozu.flywheel.backend.Backend;
import com.mojang.blaze3d.matrix.MatrixStack;
@ -81,12 +86,16 @@ public class ContraptionRenderDispatcher {
if (renderers.isEmpty()) return;
layer.startDrawing();
GL11.glEnable(GL13.GL_TEXTURE_3D);
GL13.glActiveTexture(GL40.GL_TEXTURE4); // the shaders expect light volumes to be in texture 4
glEnable(GL_TEXTURE_3D);
glActiveTexture(GL_TEXTURE4); // the shaders expect light volumes to be in texture 4
if (Backend.canUseVBOs()) {
ContraptionProgram structureShader = ContraptionContext.INSTANCE.getProgram(AllProgramSpecs.STRUCTURE);
structureShader.bind(viewProjection, camX, camY, camZ, Backend.getDebugMode());
structureShader.bind();
structureShader.uploadViewProjection(viewProjection);
structureShader.uploadCameraPos(camX, camY, camZ);
for (RenderedContraption renderer : renderers.values()) {
renderer.doRenderLayer(layer, structureShader);
}
@ -100,8 +109,8 @@ public class ContraptionRenderDispatcher {
}
layer.endDrawing();
GL11.glDisable(GL13.GL_TEXTURE_3D);
GL13.glActiveTexture(GL40.GL_TEXTURE0);
glDisable(GL_TEXTURE_3D);
glActiveTexture(GL_TEXTURE0);
}
private static RenderedContraption getRenderer(World world, Contraption c) {
@ -206,7 +215,7 @@ public class ContraptionRenderDispatcher {
BlockModelRenderer blockRenderer = dispatcher.getBlockModelRenderer();
Random random = new Random();
BufferBuilder builder = new BufferBuilder(DefaultVertexFormats.BLOCK.getIntegerSize());
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
builder.begin(GL_QUADS, DefaultVertexFormats.BLOCK);
renderWorld.setTileEntities(c.presentTileEntities.values());
for (Template.BlockInfo info : c.getBlocks()

View file

@ -1,7 +1,6 @@
package com.simibubi.create.content.contraptions.relays.belt;
import java.nio.ByteBuffer;
import com.jozufozu.flywheel.backend.gl.MappedBuffer;
import com.jozufozu.flywheel.backend.instancing.InstancedModel;
import com.simibubi.create.content.contraptions.base.KineticData;
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
@ -57,14 +56,12 @@ public class BeltData extends KineticData {
}
@Override
public void write(ByteBuffer buf) {
public void write(MappedBuffer buf) {
super.write(buf);
putVec4(buf, qX, qY, qZ, qW);
putVec2(buf, sourceU, sourceV);
putVec4(buf, minU, minV, maxU, maxV);
put(buf, scrollMult);
buf.putVec4(qX, qY, qZ, qW);
buf.putVec2(sourceU, sourceV);
buf.putVec4(minU, minV, maxU, maxV);
buf.put(scrollMult);
}
}

View file

@ -1,8 +1,7 @@
package com.simibubi.create.content.logistics.block;
import java.nio.ByteBuffer;
import com.jozufozu.flywheel.backend.core.materials.IFlatLight;
import com.jozufozu.flywheel.backend.gl.MappedBuffer;
import com.jozufozu.flywheel.backend.instancing.InstanceData;
import com.jozufozu.flywheel.backend.instancing.InstancedModel;
@ -114,17 +113,17 @@ public class FlapData extends InstanceData implements IFlatLight<FlapData> {
}
@Override
public void write(ByteBuffer buf) {
putVec3(buf, x, y, z);
putVec2(buf, blockLight, skyLight);
public void write(MappedBuffer buf) {
buf.putVec3(x, y, z);
buf.putVec2(blockLight, skyLight);
putVec3(buf, segmentOffsetX, segmentOffsetY, segmentOffsetZ);
putVec3(buf, pivotX, pivotY, pivotZ);
buf.putVec3(segmentOffsetX, segmentOffsetY, segmentOffsetZ);
buf.putVec3(pivotX, pivotY, pivotZ);
put(buf, horizontalAngle);
put(buf, intensity);
put(buf, flapScale);
buf.putFloat(horizontalAngle);
buf.putFloat(intensity);
buf.putFloat(flapScale);
put(buf, flapness);
buf.putFloat(flapness);
}
}

View file

@ -5,14 +5,15 @@ import java.util.ArrayList;
import javax.annotation.Nullable;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.gl.GlBuffer;
import com.jozufozu.flywheel.backend.gl.GlBufferType;
import com.jozufozu.flywheel.backend.gl.GlPrimitiveType;
import com.jozufozu.flywheel.backend.gl.GlVertexArray;
import com.jozufozu.flywheel.backend.gl.MappedBufferRange;
import com.jozufozu.flywheel.util.RenderUtil;
import com.simibubi.create.foundation.render.AllProgramSpecs;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
@ -68,7 +69,7 @@ public class EffectsHandler {
private final Framebuffer framebuffer;
private final GlVertexArray vao = new GlVertexArray();
private final GlBuffer vbo = new GlBuffer(GL20.GL_ARRAY_BUFFER);
private final GlBuffer vbo = new GlBuffer(GlBufferType.ARRAY_BUFFER);
private final ArrayList<FilterSphere> spheres;
@ -79,8 +80,10 @@ public class EffectsHandler {
framebuffer = new Framebuffer(render.framebufferWidth, render.framebufferHeight, false, Minecraft.IS_RUNNING_ON_MAC);
vbo.bind();
vbo.alloc(bufferSize, GL15.GL_STATIC_DRAW);
vbo.map(bufferSize, buf -> buf.asFloatBuffer().put(vertices));
vbo.alloc(bufferSize);
MappedBufferRange buffer = vbo.getBuffer(0, bufferSize);
buffer.putFloatArray(vertices);
buffer.unmap();
vao.bind();

View file

@ -1,7 +1,6 @@
package com.simibubi.create.foundation.render.effects;
import java.nio.FloatBuffer;
import com.jozufozu.flywheel.backend.gl.MappedBuffer;
import com.jozufozu.flywheel.util.RenderUtil;
import net.minecraft.util.math.vector.Matrix4f;
@ -27,8 +26,8 @@ public class FilterSphere {
public Matrix4f filter;
public void write(FloatBuffer buf) {
buf.put(new float[]{
public void write(MappedBuffer buf) {
buf.putFloatArray(new float[]{
x,
y,
z,
@ -50,6 +49,6 @@ public class FilterSphere {
0, // padding
});
buf.put(RenderUtil.writeMatrix(filter));
buf.putFloatArray(RenderUtil.writeMatrix(filter));
}
}

View file

@ -1,12 +1,13 @@
package com.simibubi.create.foundation.render.effects;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL31;
import com.jozufozu.flywheel.backend.gl.GlBuffer;
import com.jozufozu.flywheel.backend.gl.GlBufferType;
import com.jozufozu.flywheel.backend.gl.MappedBufferRange;
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
import net.minecraft.util.ResourceLocation;
@ -43,15 +44,15 @@ public class SphereFilterProgram extends GlProgram {
public SphereFilterProgram(ResourceLocation name, int handle) {
super(name, handle);
effectsUBO = new GlBuffer(GL31.GL_UNIFORM_BUFFER);
effectsUBO = new GlBuffer(GlBufferType.UNIFORM_BUFFER);
uniformBlock = GL31.glGetUniformBlockIndex(handle, "Filters");
GL31.glUniformBlockBinding(handle, uniformBlock, UBO_BINDING);
effectsUBO.bind();
effectsUBO.alloc(BUFFER_SIZE, GL20.GL_STATIC_DRAW);
GL31.glBindBufferBase(effectsUBO.getBufferType(), UBO_BINDING, effectsUBO.handle());
effectsUBO.alloc(BUFFER_SIZE);
GL31.glBindBufferBase(effectsUBO.getBufferTarget().glEnum, UBO_BINDING, effectsUBO.handle());
effectsUBO.unbind();
uInverseProjection = getUniformLocation("uInverseProjection");
@ -79,15 +80,16 @@ public class SphereFilterProgram extends GlProgram {
}
public void uploadFilters(ArrayList<FilterSphere> filters) {
effectsUBO.bind(GL20.GL_ARRAY_BUFFER);
effectsUBO.map(GL20.GL_ARRAY_BUFFER, 0, BUFFER_SIZE, buf -> {
buf.putInt(filters.size());
buf.position(16);
FloatBuffer floatBuffer = buf.asFloatBuffer();
effectsUBO.bind(GlBufferType.ARRAY_BUFFER);
MappedBufferRange buffer = effectsUBO.getBuffer(0, BUFFER_SIZE);
buffer.putInt(filters.size())
.position(16);
filters.forEach(it -> it.write(floatBuffer));
});
effectsUBO.unbind(GL20.GL_ARRAY_BUFFER);
filters.forEach(it -> it.write(buffer));
buffer.unmap();
effectsUBO.unbind(GlBufferType.ARRAY_BUFFER);
}
public void bindInverseProjection(Matrix4f mat) {

View file

@ -1,6 +1,6 @@
#flwbuiltins
#[FLWFragment]
#[Fragment]
struct Raster {
vec2 texCoords;
vec4 color;

View file

@ -1,7 +1,6 @@
#version 110
#flwbuiltins
#flwinclude <"create:core/matutils.glsl">
#flwinclude <"create:core/diffuse.glsl">
attribute vec3 aPos;

View file

@ -1,23 +1,25 @@
#flwbuiltins
#flwinclude <"create:core/matutils.glsl">
#flwinclude <"create:core/diffuse.glsl">
#[FLWVertexData]
#[VertexData]
struct Vertex {
#[Layout(float)]
vec3 pos;
vec3 normal;
vec2 texCoords;
};
#[FLWInstanceData]
#[InstanceData]
struct Instance {
#[Normalized(ushort)]
vec2 light;
#[Normalized(ubyte)]
vec4 color;
mat4 transform;
mat3 normalMat;
};
#[FLWFragment]
#[Fragment]
struct Raster {
vec2 texCoords;
vec4 color;

View file

@ -2,11 +2,11 @@
#flwbeginbody
#FLWPrefixFields(FLWFragment, varying, v2f_)
#FLWPrefixFields(Fragment, varying, v2f_)
void main() {
FLWFragment f;
#FLWAssignFields(FLWFragment, f., v2f_)
Fragment f;
#FLWAssignFields(Fragment, f., v2f_)
FLWMain(f);
}

View file

@ -1,19 +1,19 @@
#version 110
#flwbeginbody
#FLWPrefixFields(FLWVertexData, attribute, a_v_)
#FLWPrefixFields(FLWInstanceData, attribute, a_i_)
#FLWPrefixFields(VertexData, attribute, a_v_)
#FLWPrefixFields(InstanceData, attribute, a_i_)
#FLWPrefixFields(FLWFragment, varying, v2f_)
#FLWPrefixFields(Fragment, varying, v2f_)
void main() {
FLWVertexData v;
#FLWAssignFields(FLWVertexData, v., a_v_)
VertexData v;
#FLWAssignFields(VertexData, v., a_v_)
FLWInstanceData i;
#FLWAssignFields(FLWInstanceData, i., a_i_)
InstanceData i;
#FLWAssignFields(InstanceData, i., a_i_)
FLWFragment o = FLWMain(v, i);
Fragment o = FLWMain(v, i);
#FLWAssignFields(FLWFragment, v2f_, o.)
#FLWAssignFields(Fragment, v2f_, o.)
}