better vertex attributes.

all shaders are now GL 2.0 compatible!!!
contraption structure rendering is technically 2.0 compatible now, need some better handling for that.
This commit is contained in:
JozsefA 2021-02-11 20:03:24 -08:00
parent 576165e3d6
commit 67408e0dff
37 changed files with 608 additions and 468 deletions

View file

@ -20,7 +20,7 @@ public class RenderInLayerMixin {
* layer-correct custom rendering. RenderWorldLast is not refined enough for rendering world objects.
* This should probably be a forge event.
*/
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/profiler/IProfiler;endSection()V", ordinal = 1), method = "renderLayer")
@Inject(at = @At(value = "TAIL"), method = "renderLayer")
private void renderLayer(RenderType type, MatrixStack stack, double cameraX, double cameraY, double cameraZ, CallbackInfo ci) {
FastRenderDispatcher.renderLayer(type, stack, (float) cameraX, (float) cameraY, (float) cameraZ);
}

View file

@ -3,8 +3,7 @@ package com.simibubi.create.foundation.render;
import com.simibubi.create.Create;
import com.simibubi.create.foundation.render.contraption.ContraptionProgram;
import com.simibubi.create.foundation.render.gl.BasicProgram;
import com.simibubi.create.foundation.render.gl.backend.Backend;
import com.simibubi.create.foundation.render.gl.shader.GlProgram;
import com.simibubi.create.foundation.render.gl.attrib.impl.*;
import com.simibubi.create.foundation.render.gl.shader.ProgramSpec;
import com.simibubi.create.foundation.render.gl.shader.ShaderConstants;
import net.minecraft.util.ResourceLocation;
@ -12,12 +11,52 @@ import net.minecraft.util.ResourceLocation;
import static com.simibubi.create.foundation.render.gl.backend.Backend.register;
public class AllProgramSpecs {
public static final ProgramSpec<BasicProgram> ROTATING = register(new ProgramSpec<>("rotating", Locations.ROTATING, Locations.INSTANCED, BasicProgram::new));
public static final ProgramSpec<BasicProgram> BELT = register(new ProgramSpec<>("belt", Locations.BELT, Locations.INSTANCED, BasicProgram::new));
public static final ProgramSpec<ContraptionProgram> CONTRAPTION_STRUCTURE = register(new ProgramSpec<>("contraption_structure", Locations.CONTRAPTION_STRUCTURE, Locations.CONTRAPTION, ContraptionProgram::new));
public static final ProgramSpec<ContraptionProgram> CONTRAPTION_ROTATING = register(new ProgramSpec<>("contraption_rotating", Locations.ROTATING, Locations.CONTRAPTION, ContraptionProgram::new, ShaderConstants.define("CONTRAPTION")));
public static final ProgramSpec<ContraptionProgram> CONTRAPTION_BELT = register(new ProgramSpec<>("contraption_belt", Locations.BELT, Locations.CONTRAPTION, ContraptionProgram::new, ShaderConstants.define("CONTRAPTION")));
public static final ProgramSpec<ContraptionProgram> CONTRAPTION_ACTOR = register(new ProgramSpec<>("contraption_actor", Locations.CONTRAPTION_ACTOR, Locations.CONTRAPTION, ContraptionProgram::new));
public static final ProgramSpec<BasicProgram> ROTATING = register(ProgramSpec.builder("rotating", BasicProgram::new)
.addAttributes(ModelVertexAttributes.class)
.addAttributes(KineticVertexAttributes.class)
.addAttributes(RotatingVertexAttributes.class)
.setVert(Locations.ROTATING)
.setFrag(Locations.INSTANCED)
.createProgramSpec());
public static final ProgramSpec<BasicProgram> BELT = register(ProgramSpec.builder("belt", BasicProgram::new)
.addAttributes(ModelVertexAttributes.class)
.addAttributes(KineticVertexAttributes.class)
.addAttributes(BeltVertexAttributes.class)
.setVert(Locations.BELT)
.setFrag(Locations.INSTANCED)
.createProgramSpec());
public static final ProgramSpec<ContraptionProgram> CONTRAPTION_STRUCTURE = register(ProgramSpec.builder("contraption_structure", ContraptionProgram::new)
.addAttributes(ContraptionVertexAttributes.class)
.setVert(Locations.CONTRAPTION_STRUCTURE)
.setFrag(Locations.CONTRAPTION)
.createProgramSpec());
public static final ProgramSpec<ContraptionProgram> CONTRAPTION_ROTATING = register(ProgramSpec.builder("contraption_rotating", ContraptionProgram::new)
.addAttributes(ModelVertexAttributes.class)
.addAttributes(KineticVertexAttributes.class)
.addAttributes(RotatingVertexAttributes.class)
.setVert(Locations.ROTATING)
.setFrag(Locations.CONTRAPTION)
.setDefines(ShaderConstants.define("CONTRAPTION"))
.createProgramSpec());
public static final ProgramSpec<ContraptionProgram> CONTRAPTION_BELT = register(ProgramSpec.builder("contraption_belt", ContraptionProgram::new)
.addAttributes(ModelVertexAttributes.class)
.addAttributes(KineticVertexAttributes.class)
.addAttributes(BeltVertexAttributes.class)
.setVert(Locations.BELT)
.setFrag(Locations.CONTRAPTION)
.setDefines(ShaderConstants.define("CONTRAPTION"))
.createProgramSpec());
public static final ProgramSpec<ContraptionProgram> CONTRAPTION_ACTOR = register(ProgramSpec.builder("contraption_actor", ContraptionProgram::new)
.addAttributes(ModelVertexAttributes.class)
.addAttributes(ActorVertexAttributes.class)
.setVert(Locations.CONTRAPTION_ACTOR)
.setFrag(Locations.CONTRAPTION)
.createProgramSpec());
public static class Locations {
public static final ResourceLocation INSTANCED = loc("instanced.frag");

View file

@ -1,19 +1,18 @@
package com.simibubi.create.foundation.render;
import com.mojang.blaze3d.platform.GlStateManager;
import com.simibubi.create.foundation.render.gl.GlPrimitiveType;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import com.simibubi.create.foundation.render.gl.backend.Backend;
import com.simibubi.create.foundation.render.gl.GlBuffer;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import net.minecraft.client.renderer.BufferBuilder;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import java.nio.ByteBuffer;
import java.util.HashSet;
public abstract class BufferedModel extends TemplateBuffer {
protected GlBuffer ebo;
protected GlBuffer modelVBO;
protected boolean removed;
@ -26,9 +25,9 @@ public abstract class BufferedModel extends TemplateBuffer {
modelVBO = new GlBuffer(GL20.GL_ARRAY_BUFFER);
modelVBO.bind();
initModel();
modelVBO.unbind();
modelVBO.with(vbo -> initModel());
ebo = createEBO();
}
protected void initModel() {
@ -46,6 +45,25 @@ public abstract class BufferedModel extends TemplateBuffer {
});
}
protected final GlBuffer createEBO() {
GlBuffer ebo = new GlBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER);
int indicesSize = vertexCount * GlPrimitiveType.USHORT.getSize();
ebo.bind();
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesSize, GL15.GL_STATIC_DRAW);
Backend.mapBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesSize, indices -> {
for (int i = 0; i < vertexCount; i++) {
indices.putShort((short) i);
}
});
ebo.unbind();
return ebo;
}
protected abstract void copyVertex(ByteBuffer to, int index);
protected abstract VertexFormat getModelFormat();
@ -64,35 +82,30 @@ public abstract class BufferedModel extends TemplateBuffer {
}
/**
* Override this
* Override this.
*/
protected void doRender() {
GL20.glDisableClientState(32884);
GL20.glDisableClientState(32885);
GL20.glDisableClientState(32886);
GL20.glDisableClientState(32888);
GL20.glEnable(GL20.GL_VERTEX_ARRAY);
modelVBO.bind();
ebo.bind();
setupAttributes();
GL20.glDrawArrays(GL11.GL_QUADS, 0, vertexCount);
modelVBO.unbind();
GL20.glDrawElements(GL20.GL_QUADS, vertexCount, GlPrimitiveType.USHORT.getGlConstant(), 0);
int numAttributes = getTotalShaderAttributeCount();
for (int i = 0; i <= numAttributes; i++) {
GL20.glDisableVertexAttribArray(i);
}
GL20.glDisable(GL20.GL_VERTEX_ARRAY);
ebo.unbind();
modelVBO.unbind();
}
protected void setupAttributes() {
int numAttributes = getTotalShaderAttributeCount();
for (int i = 0; i <= numAttributes; i++) {
GL20.glEnableVertexAttribArray(i);
}
getModelFormat().informAttributes(0);
}

View file

@ -96,26 +96,26 @@ public class FastRenderDispatcher {
}
}
public static void renderLayer(RenderType type, MatrixStack stack, float cameraX, float cameraY, float cameraZ) {
public static void renderLayer(RenderType layer, MatrixStack stack, float cameraX, float cameraY, float cameraZ) {
if (!available()) return;
Matrix4f viewProjection = Matrix4f.translate(-cameraX, -cameraY, -cameraZ);
viewProjection.multiplyBackward(stack.peek().getModel());
viewProjection.multiplyBackward(getProjectionMatrix());
type.startDrawing();
layer.startDrawing();
RenderSystem.enableDepthTest();
RenderSystem.enableCull();
GL11.glCullFace(GL11.GL_BACK);
CreateClient.kineticRenderer.render(type, viewProjection, cameraX, cameraY, cameraZ);
CreateClient.kineticRenderer.render(layer, viewProjection, cameraX, cameraY, cameraZ);
RenderSystem.disableCull();
//RenderSystem.disableDepthTest();
ContraptionRenderDispatcher.renderLayer(type, viewProjection, cameraX, cameraY, cameraZ);
ContraptionRenderDispatcher.renderLayer(layer, viewProjection, cameraX, cameraY, cameraZ);
if (!OptifineHandler.usingShaders())
GL20.glUseProgram(0);
type.endDrawing();
layer.endDrawing();
}
public static void notifyLightUpdate(ClientChunkProvider world, LightType type, SectionPos pos) {

View file

@ -1,13 +1,11 @@
package com.simibubi.create.foundation.render.contraption;
import com.simibubi.create.foundation.render.BufferedModel;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import com.simibubi.create.foundation.render.gl.attrib.impl.ContraptionVertexAttributes;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.LightTexture;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL40;
import java.nio.ByteBuffer;
@ -15,7 +13,9 @@ import static com.simibubi.create.foundation.render.gl.attrib.CommonAttributes.L
import static com.simibubi.create.foundation.render.gl.attrib.CommonAttributes.RGBA;
public class ContraptionModel extends BufferedModel {
public static final VertexFormat FORMAT = new VertexFormat(InstancedModel.FORMAT, RGBA, LIGHT);
public static final VertexFormat FORMAT = VertexFormat.builder()
.addAttributes(ContraptionVertexAttributes.class)
.build();
public ContraptionModel(BufferBuilder buf) {
super(buf);

View file

@ -27,7 +27,6 @@ public class ContraptionProgram extends BasicProgram {
}
public void bind(Matrix4f model, GridAlignedBB lightVolume) {
bind();
GL20.glUniform3f(uLightBoxSize, lightVolume.sizeX(), lightVolume.sizeY(), lightVolume.sizeZ());
GL20.glUniform3f(uLightBoxMin, lightVolume.minX, lightVolume.minY, lightVolume.minZ);
uploadMatrixUniform(uModel, model);

View file

@ -8,7 +8,6 @@ import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL20;
public class BasicProgram extends GlProgram {
protected final int uTicks;
protected final int uTime;
protected final int uViewProjection;
protected final int uDebug;
@ -21,7 +20,6 @@ public class BasicProgram extends GlProgram {
public BasicProgram(ResourceLocation name, int handle) {
super(name, handle);
uTicks = getUniformLocation("uTicks");
uTime = getUniformLocation("uTime");
uViewProjection = getUniformLocation("uViewProjection");
uDebug = getUniformLocation("uDebug");
@ -43,7 +41,6 @@ public class BasicProgram extends GlProgram {
super.bind();
GL20.glUniform1i(uDebug, debugMode);
GL20.glUniform1i(uTicks, AnimationTickHolder.getTicks());
GL20.glUniform1f(uTime, AnimationTickHolder.getRenderTick());
uploadMatrixUniform(uViewProjection, viewProjection);

View file

@ -1,7 +1,11 @@
package com.simibubi.create.foundation.render.gl;
import com.simibubi.create.foundation.render.gl.backend.Backend;
import org.lwjgl.opengl.GL20;
import java.nio.ByteBuffer;
import java.util.function.Consumer;
public class GlBuffer extends GlObject {
protected final int bufferType;
@ -11,6 +15,10 @@ public class GlBuffer extends GlObject {
this.bufferType = bufferType;
}
public int getBufferType() {
return bufferType;
}
public void bind() {
GL20.glBindBuffer(bufferType, handle());
}
@ -19,6 +27,16 @@ public class GlBuffer extends GlObject {
GL20.glBindBuffer(bufferType, 0);
}
public void with(Consumer<GlBuffer> action) {
bind();
action.accept(this);
unbind();
}
public void map(int offset, int length, Consumer<ByteBuffer> upload) {
Backend.mapBuffer(bufferType, offset, length, upload);
}
protected void deleteInternal(int handle) {
GL20.glDeleteBuffers(handle);
}

View file

@ -2,6 +2,8 @@ package com.simibubi.create.foundation.render.gl;
import org.lwjgl.opengl.GL30;
import java.util.function.Consumer;
public class GlVertexArray extends GlObject {
public GlVertexArray() {
setHandle(GL30.glGenVertexArrays());
@ -15,6 +17,12 @@ public class GlVertexArray extends GlObject {
GL30.glBindVertexArray(0);
}
public void with(Consumer<GlVertexArray> action) {
bind();
action.accept(this);
unbind();
}
protected void deleteInternal(int handle) {
GL30.glDeleteVertexArrays(handle);
}

View file

@ -1,27 +0,0 @@
package com.simibubi.create.foundation.render.gl.attrib;
import java.util.ArrayList;
public class AttributeGroup {
private final int divisor;
private final ArrayList<VertexAttribSpec> attributes;
public AttributeGroup(int divisor) {
this.divisor = divisor;
this.attributes = new ArrayList<>();
}
public AttributeGroup attrib(VertexAttribSpec attrib) {
attributes.add(attrib);
return this;
}
public int getDivisor() {
return divisor;
}
public ArrayList<VertexAttribSpec> getAttributes() {
return attributes;
}
}

View file

@ -10,14 +10,12 @@ public class CommonAttributes {
public static final VertexAttribSpec VEC2 = new VertexAttribSpec(GlPrimitiveType.FLOAT, 2);
public static final VertexAttribSpec FLOAT = new VertexAttribSpec(GlPrimitiveType.FLOAT, 1);
public static final VertexAttribSpec POSITION = VertexAttribSpec.copy(VEC3);
public static final VertexAttribSpec NORMAL = new VertexAttribSpec(GlPrimitiveType.BYTE, 3, true);
public static final VertexAttribSpec UV = VertexAttribSpec.copy(VEC2);
public static final VertexAttribSpec ROTATION = VertexAttribSpec.copy(VEC3);
public static final VertexAttribSpec INSTANCE_POSITION = VertexAttribSpec.copy(VEC3);
public static final VertexAttribSpec UV = new VertexAttribSpec(GlPrimitiveType.FLOAT, 2);
public static final VertexAttribSpec RGBA = new VertexAttribSpec(GlPrimitiveType.UBYTE, 4, true);
public static final VertexAttribSpec RGB = new VertexAttribSpec(GlPrimitiveType.UBYTE, 3, true);
public static final VertexAttribSpec LIGHT = new VertexAttribSpec(GlPrimitiveType.UBYTE, 2, true);
public static final VertexAttribSpec NORMALIZED_BYTE = new VertexAttribSpec(GlPrimitiveType.BYTE, 1, true);
}

View file

@ -11,18 +11,6 @@ public class VertexAttribSpec {
private final int attributeCount;
private final boolean normalized;
public static VertexAttribSpec copy(VertexAttribSpec other) {
return new VertexAttribSpec(other);
}
public VertexAttribSpec(VertexAttribSpec that) {
this.type = that.type;
this.count = that.count;
this.size = that.size;
this.attributeCount = that.attributeCount;
this.normalized = that.normalized;
}
public VertexAttribSpec(GlPrimitiveType type, int count) {
this(type, count, false);
}

View file

@ -1,34 +1,23 @@
package com.simibubi.create.foundation.render.gl.attrib;
import java.util.ArrayList;
import java.util.Arrays;
public class VertexFormat {
private final VertexAttribSpec[] elements;
private final ArrayList<IVertexAttrib> allAttributes;
private final int numAttributes;
private final int stride;
public VertexFormat(VertexAttribSpec... elements) {
this.elements = elements;
int numAttributes = 0, stride = 0;
for (VertexAttribSpec element : elements) {
numAttributes += element.getAttributeCount();
stride += element.getSize();
}
this.numAttributes = numAttributes;
this.stride = stride;
}
public VertexFormat(VertexFormat start, VertexAttribSpec... elements) {
int baseLength = start.elements.length;
int addedLength = elements.length;
this.elements = new VertexAttribSpec[baseLength + addedLength];
System.arraycopy(start.elements, 0, this.elements, 0, baseLength);
System.arraycopy(elements, 0, this.elements, baseLength, addedLength);
public VertexFormat(ArrayList<IVertexAttrib> allAttributes) {
this.allAttributes = allAttributes;
int numAttributes = 0, stride = 0;
for (VertexAttribSpec element : this.elements) {
numAttributes += element.getAttributeCount();
stride += element.getSize();
for (IVertexAttrib attrib : allAttributes) {
VertexAttribSpec spec = attrib.attribSpec();
numAttributes += spec.getAttributeCount();
stride += spec.getSize();
}
this.numAttributes = numAttributes;
this.stride = stride;
@ -44,10 +33,33 @@ public class VertexFormat {
public void informAttributes(int index) {
int offset = 0;
for (VertexAttribSpec element : this.elements) {
element.registerForBuffer(stride, index, offset);
index += element.getAttributeCount();
offset += element.getSize();
for (IVertexAttrib attrib : this.allAttributes) {
VertexAttribSpec spec = attrib.attribSpec();
spec.registerForBuffer(stride, index, offset);
index += spec.getAttributeCount();
offset += spec.getSize();
}
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private final ArrayList<IVertexAttrib> allAttributes;
public Builder() {
allAttributes = new ArrayList<>();
}
public <A extends Enum<A> & IVertexAttrib> Builder addAttributes(Class<A> attribEnum) {
allAttributes.addAll(Arrays.asList(attribEnum.getEnumConstants()));
return this;
}
public VertexFormat build() {
return new VertexFormat(allAttributes);
}
}
}

View file

@ -1,39 +0,0 @@
package com.simibubi.create.foundation.render.gl.attrib;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Stream;
public class VertexFormat2 {
private final ArrayList<Class<? extends Enum<? extends IVertexAttrib>>> allAttributes;
public VertexFormat2(ArrayList<Class<? extends Enum<? extends IVertexAttrib>>> allAttributes) {
this.allAttributes = allAttributes;
}
public static Builder builder() {
return new Builder();
}
public Stream<IVertexAttrib> getAttributeStream() {
return (Stream<IVertexAttrib>) allAttributes.stream().flatMap(it -> Arrays.stream(it.getEnumConstants()));
}
public static class Builder {
private final ArrayList<Class<? extends Enum<? extends IVertexAttrib>>> allAttributes;
public Builder() {
allAttributes = new ArrayList<>();
}
public <A extends Enum<A> & IVertexAttrib> Builder addAttributes(Class<A> attribEnum) {
allAttributes.add(attribEnum);
return this;
}
public VertexFormat2 build() {
return new VertexFormat2(allAttributes);
}
}
}

View file

@ -0,0 +1,43 @@
package com.simibubi.create.foundation.render.gl.attrib.impl;
import com.simibubi.create.foundation.render.gl.attrib.CommonAttributes;
import com.simibubi.create.foundation.render.gl.attrib.IVertexAttrib;
import com.simibubi.create.foundation.render.gl.attrib.VertexAttribSpec;
public enum ActorVertexAttributes implements IVertexAttrib {
INSTANCE_POSITION("aInstancePos", CommonAttributes.VEC3),
LIGHT("aModelLight", CommonAttributes.LIGHT),
OFFSET("aOffset", CommonAttributes.FLOAT),
AXIS("aAxis", CommonAttributes.NORMAL),
INSTANCE_ROTATION("aInstanceRot", CommonAttributes.VEC3),
ROTATION_CENTER("aRotationCenter", CommonAttributes.NORMAL),
;
private final String name;
private final VertexAttribSpec spec;
ActorVertexAttributes(String name, VertexAttribSpec spec) {
this.name = name;
this.spec = spec;
}
@Override
public String attribName() {
return name;
}
@Override
public VertexAttribSpec attribSpec() {
return spec;
}
@Override
public int getDivisor() {
return 1;
}
@Override
public int getBufferIndex() {
return 1;
}
}

View file

@ -0,0 +1,42 @@
package com.simibubi.create.foundation.render.gl.attrib.impl;
import com.simibubi.create.foundation.render.gl.attrib.CommonAttributes;
import com.simibubi.create.foundation.render.gl.attrib.IVertexAttrib;
import com.simibubi.create.foundation.render.gl.attrib.VertexAttribSpec;
import com.simibubi.create.foundation.render.instancing.BeltData;
public enum BeltVertexAttributes implements IVertexAttrib {
INSTANCE_ROTATION("aInstanceRot", CommonAttributes.VEC3),
SOURCE_TEX("aSourceTexture", CommonAttributes.UV),
SCROLL_TEX("aScrollTexture", CommonAttributes.VEC4),
SCROLL_MULT("aScrollMult", CommonAttributes.NORMALIZED_BYTE),
;
private final String name;
private final VertexAttribSpec spec;
BeltVertexAttributes(String name, VertexAttribSpec spec) {
this.name = name;
this.spec = spec;
}
@Override
public String attribName() {
return name;
}
@Override
public VertexAttribSpec attribSpec() {
return spec;
}
@Override
public int getDivisor() {
return 1;
}
@Override
public int getBufferIndex() {
return 1;
}
}

View file

@ -0,0 +1,42 @@
package com.simibubi.create.foundation.render.gl.attrib.impl;
import com.simibubi.create.foundation.render.gl.attrib.CommonAttributes;
import com.simibubi.create.foundation.render.gl.attrib.IVertexAttrib;
import com.simibubi.create.foundation.render.gl.attrib.VertexAttribSpec;
public enum ContraptionVertexAttributes implements IVertexAttrib {
VERTEX_POSITION("aPos", CommonAttributes.VEC3),
NORMAL("aNormal", CommonAttributes.NORMAL),
TEXTURE("aTexCoords", CommonAttributes.UV),
COLOR("aColor", CommonAttributes.RGBA),
MODEL_LIGHT("aModelLight", CommonAttributes.LIGHT),
;
private final String name;
private final VertexAttribSpec spec;
ContraptionVertexAttributes(String name, VertexAttribSpec spec) {
this.name = name;
this.spec = spec;
}
@Override
public String attribName() {
return name;
}
@Override
public VertexAttribSpec attribSpec() {
return spec;
}
@Override
public int getDivisor() {
return 0;
}
@Override
public int getBufferIndex() {
return 0;
}
}

View file

@ -0,0 +1,42 @@
package com.simibubi.create.foundation.render.gl.attrib.impl;
import com.simibubi.create.foundation.render.gl.attrib.CommonAttributes;
import com.simibubi.create.foundation.render.gl.attrib.IVertexAttrib;
import com.simibubi.create.foundation.render.gl.attrib.VertexAttribSpec;
public enum KineticVertexAttributes implements IVertexAttrib {
INSTANCE_POSITION("aInstancePos", CommonAttributes.VEC3),
LIGHT("aLight", CommonAttributes.LIGHT),
NETWORK_COLOR("aNetworkTint", CommonAttributes.RGB),
SPEED("aSpeed", CommonAttributes.FLOAT),
OFFSET("aOffset", CommonAttributes.FLOAT),
;
private final String name;
private final VertexAttribSpec spec;
KineticVertexAttributes(String name, VertexAttribSpec spec) {
this.name = name;
this.spec = spec;
}
@Override
public String attribName() {
return name;
}
@Override
public VertexAttribSpec attribSpec() {
return spec;
}
@Override
public int getDivisor() {
return 1;
}
@Override
public int getBufferIndex() {
return 1;
}
}

View file

@ -1,4 +1,8 @@
package com.simibubi.create.foundation.render.gl.attrib;
package com.simibubi.create.foundation.render.gl.attrib.impl;
import com.simibubi.create.foundation.render.gl.attrib.CommonAttributes;
import com.simibubi.create.foundation.render.gl.attrib.IVertexAttrib;
import com.simibubi.create.foundation.render.gl.attrib.VertexAttribSpec;
public enum ModelVertexAttributes implements IVertexAttrib {
VERTEX_POSITION("aPos", CommonAttributes.VEC3),

View file

@ -1,11 +1,10 @@
package com.simibubi.create.foundation.render.gl.attrib;
package com.simibubi.create.foundation.render.gl.attrib.impl;
import com.simibubi.create.foundation.render.gl.attrib.CommonAttributes;
import com.simibubi.create.foundation.render.gl.attrib.IVertexAttrib;
import com.simibubi.create.foundation.render.gl.attrib.VertexAttribSpec;
public enum RotatingVertexAttributes implements IVertexAttrib {
INSTANCE_POSITION("aInstancePos", CommonAttributes.VEC3),
LIGHT("aLight", CommonAttributes.LIGHT),
NETWORK_COLOR("aNetworkTint", CommonAttributes.RGB),
SPEED("aSpeed", CommonAttributes.FLOAT),
OFFSET("aOffset", CommonAttributes.FLOAT),
AXIS("aAxis", CommonAttributes.NORMAL),
;

View file

@ -1,6 +1,7 @@
package com.simibubi.create.foundation.render.gl.backend;
import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.render.gl.attrib.IVertexAttrib;
import com.simibubi.create.foundation.render.gl.shader.GlProgram;
import com.simibubi.create.foundation.render.gl.shader.GlShader;
import com.simibubi.create.foundation.render.gl.shader.ProgramSpec;
@ -163,10 +164,11 @@ public class Backend {
vert = loadShader(manager, programSpec.getVert(), ShaderType.VERTEX, programSpec.defines);
frag = loadShader(manager, programSpec.getFrag(), ShaderType.FRAGMENT, programSpec.defines);
P program = GlProgram.builder(programSpec.name)
.attachShader(vert)
.attachShader(frag)
.build(programSpec.factory);
GlProgram.Builder builder = GlProgram.builder(programSpec.name).attachShader(vert).attachShader(frag);
programSpec.attributes.forEach(builder::addAttribute);
P program = builder.build(programSpec.factory);
programs.put(programSpec, program);

View file

@ -1,6 +1,7 @@
package com.simibubi.create.foundation.render.gl.shader;
import com.simibubi.create.foundation.render.gl.GlObject;
import com.simibubi.create.foundation.render.gl.attrib.IVertexAttrib;
import com.simibubi.create.foundation.render.gl.backend.Backend;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL20;
@ -67,6 +68,8 @@ public abstract class GlProgram extends GlObject {
private final ResourceLocation name;
private final int program;
private int attributeIndex;
public Builder(ResourceLocation name) {
this.name = name;
this.program = GL20.glCreateProgram();
@ -78,6 +81,12 @@ public abstract class GlProgram extends GlObject {
return this;
}
public <A extends IVertexAttrib> Builder addAttribute(A attrib) {
GL20.glBindAttribLocation(this.program, attributeIndex, attrib.attribName());
attributeIndex += attrib.attribSpec().getAttributeCount();
return this;
}
/**
* Links the attached shaders to this program and returns a user-defined container which wraps the shader
* program. This container can, for example, provide methods for updating the specific uniforms of that shader
@ -104,12 +113,6 @@ public abstract class GlProgram extends GlObject {
return factory.create(this.name, this.program);
}
// public Builder bindAttribute(String name, GlVertexAttribute attribute) {
// GL20.glBindAttribLocation(this.program, attribute.getIndex(), name);
//
// return this;
// }
}
@FunctionalInterface

View file

@ -1,8 +1,12 @@
package com.simibubi.create.foundation.render.gl.shader;
import com.simibubi.create.Create;
import com.simibubi.create.foundation.render.gl.attrib.IVertexAttrib;
import net.minecraft.util.ResourceLocation;
import java.util.ArrayList;
import java.util.Arrays;
public class ProgramSpec<P extends GlProgram> {
public final ResourceLocation name;
@ -13,17 +17,25 @@ public class ProgramSpec<P extends GlProgram> {
public final GlProgram.ProgramFactory<P> factory;
public ProgramSpec(String name, ResourceLocation vert, ResourceLocation frag, GlProgram.ProgramFactory<P> factory) {
this(name, vert, frag, factory, null);
public final ArrayList<IVertexAttrib> attributes;
public static <P extends GlProgram> Builder<P> builder(String name, GlProgram.ProgramFactory<P> factory) {
return builder(new ResourceLocation(Create.ID, name), factory);
}
public ProgramSpec(String name, ResourceLocation vert, ResourceLocation frag, GlProgram.ProgramFactory<P> factory, ShaderConstants defines) {
this.name = new ResourceLocation(Create.ID, name);
public static <P extends GlProgram> Builder<P> builder(ResourceLocation name, GlProgram.ProgramFactory<P> factory) {
return new Builder<>(name, factory);
}
public ProgramSpec(ResourceLocation name, ResourceLocation vert, ResourceLocation frag, GlProgram.ProgramFactory<P> factory, ShaderConstants defines, ArrayList<IVertexAttrib> attributes) {
this.name = name;
this.vert = vert;
this.frag = frag;
this.defines = defines;
this.factory = factory;
this.attributes = attributes;
}
public ResourceLocation getVert() {
@ -34,4 +46,43 @@ public class ProgramSpec<P extends GlProgram> {
return frag;
}
public static class Builder<P extends GlProgram> {
private ResourceLocation vert;
private ResourceLocation frag;
private ShaderConstants defines = null;
private final ResourceLocation name;
private final GlProgram.ProgramFactory<P> factory;
private final ArrayList<IVertexAttrib> attributes;
public Builder(ResourceLocation name, GlProgram.ProgramFactory<P> factory) {
this.name = name;
this.factory = factory;
attributes = new ArrayList<>();
}
public Builder<P> setVert(ResourceLocation vert) {
this.vert = vert;
return this;
}
public Builder<P> setFrag(ResourceLocation frag) {
this.frag = frag;
return this;
}
public Builder<P> setDefines(ShaderConstants defines) {
this.defines = defines;
return this;
}
public <A extends Enum<A> & IVertexAttrib> Builder<P> addAttributes(Class<A> attributeEnum) {
attributes.addAll(Arrays.asList(attributeEnum.getEnumConstants()));
return this;
}
public ProgramSpec<P> createProgramSpec() {
return new ProgramSpec<>(name, vert, frag, factory, defines, attributes);
}
}
}

View file

@ -5,6 +5,8 @@ import com.simibubi.create.foundation.render.gl.GlPrimitiveType;
import com.simibubi.create.foundation.render.gl.attrib.CommonAttributes;
import com.simibubi.create.foundation.render.gl.attrib.VertexAttribSpec;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import com.simibubi.create.foundation.render.gl.attrib.impl.BeltVertexAttributes;
import com.simibubi.create.foundation.render.gl.attrib.impl.KineticVertexAttributes;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import java.nio.ByteBuffer;
@ -12,10 +14,10 @@ import java.nio.ByteBuffer;
import static com.simibubi.create.foundation.render.gl.attrib.VertexAttribSpec.*;
public class BeltData extends KineticData<BeltData> {
public static final VertexAttribSpec TARGET_UV = copy(CommonAttributes.VEC4);
public static final VertexAttribSpec SCROLL_MULT = new VertexAttribSpec(GlPrimitiveType.BYTE, 1, true);
public static VertexFormat FORMAT = new VertexFormat(KineticData.FORMAT, CommonAttributes.ROTATION, CommonAttributes.UV, TARGET_UV, SCROLL_MULT);
public static VertexFormat FORMAT = VertexFormat.builder()
.addAttributes(KineticVertexAttributes.class)
.addAttributes(BeltVertexAttributes.class)
.build();
private float rotX;
private float rotY;

View file

@ -1,38 +0,0 @@
package com.simibubi.create.foundation.render.instancing;
import com.simibubi.create.foundation.render.gl.GlBuffer;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import net.minecraft.client.renderer.BufferBuilder;
import org.lwjgl.opengl.GL20;
public abstract class DynamicInstancedModel<S extends InstanceData, D extends InstanceData> extends InstancedModel<S> {
protected GlBuffer dynamicVBO;
protected int dynamicBufferSize = -1;
public DynamicInstancedModel(BufferBuilder buf) {
super(buf);
}
@Override
protected void init() {
super.init();
dynamicVBO = new GlBuffer(GL20.GL_ARRAY_BUFFER);
}
protected abstract VertexFormat getDynamicFormat();
protected abstract D newDynamicPart();
@Override
protected int getTotalShaderAttributeCount() {
return super.getTotalShaderAttributeCount() + getDynamicFormat().getShaderAttributeCount();
}
@Override
protected void deleteInternal() {
super.deleteInternal();
dynamicVBO.delete();
}
}

View file

@ -4,10 +4,9 @@ package com.simibubi.create.foundation.render.instancing;
import com.simibubi.create.foundation.render.BufferedModel;
import com.simibubi.create.foundation.render.RenderMath;
import com.simibubi.create.foundation.render.gl.GlVertexArray;
import com.simibubi.create.foundation.render.gl.attrib.CommonAttributes;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import com.simibubi.create.foundation.render.gl.backend.Backend;
import com.simibubi.create.foundation.render.gl.GlBuffer;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import com.simibubi.create.foundation.render.gl.attrib.impl.ModelVertexAttributes;
import net.minecraft.client.renderer.BufferBuilder;
import org.lwjgl.opengl.*;
@ -16,7 +15,7 @@ import java.util.ArrayList;
import java.util.function.Consumer;
public abstract class InstancedModel<D extends InstanceData> extends BufferedModel {
public static final VertexFormat FORMAT = new VertexFormat(CommonAttributes.POSITION, CommonAttributes.NORMAL, CommonAttributes.UV);
public static final VertexFormat FORMAT = VertexFormat.builder().addAttributes(ModelVertexAttributes.class).build();
protected GlVertexArray vao;
protected GlBuffer instanceVBO;
@ -37,9 +36,7 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
vao = new GlVertexArray();
instanceVBO = new GlBuffer(GL20.GL_ARRAY_BUFFER);
vao.bind();
super.init();
vao.unbind();
vao.with(vao -> super.init());
}
@Override
@ -108,10 +105,10 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
}
protected void doRender() {
vao.bind();
renderSetup();
GL31.glDrawArraysInstanced(GL11.GL_QUADS, 0, vertexCount, glInstanceCount);
vao.unbind();
vao.with(vao -> {
renderSetup();
GL31.glDrawArraysInstanced(GL11.GL_QUADS, 0, vertexCount, glInstanceCount);
});
}
protected void renderSetup() {
@ -123,45 +120,43 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
int newInstanceCount = instanceCount();
int instanceSize = RenderMath.nextPowerOf2((newInstanceCount + 1) * stride);
instanceVBO.bind();
// this probably changes enough that it's not worth reallocating the entire buffer every time.
if (instanceSize > glBufferSize) {
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, instanceSize, GL15.GL_STATIC_DRAW);
glBufferSize = instanceSize;
minIndexChanged = 0;
maxIndexChanged = newInstanceCount - 1;
}
int offset = minIndexChanged * stride;
int length = (1 + maxIndexChanged - minIndexChanged) * stride;
Backend.mapBuffer(GL15.GL_ARRAY_BUFFER, offset, length, buffer -> {
for (int i = minIndexChanged; i <= maxIndexChanged; i++) {
data.get(i).write(buffer);
instanceVBO.with(vbo -> {
// this probably changes enough that it's not worth reallocating the entire buffer every time.
if (instanceSize > glBufferSize) {
GL15.glBufferData(vbo.getBufferType(), instanceSize, GL15.GL_STATIC_DRAW);
glBufferSize = instanceSize;
minIndexChanged = 0;
maxIndexChanged = newInstanceCount - 1;
}
});
if (newInstanceCount < glInstanceCount) {
int clearFrom = (maxIndexChanged + 1) * stride;
int clearTo = (glInstanceCount) * stride;
Backend.mapBuffer(GL15.GL_ARRAY_BUFFER, clearFrom, clearTo - clearFrom, buffer -> {
for (int i = clearFrom; i < clearTo; i++) {
buffer.put((byte) 0);
int offset = minIndexChanged * stride;
int length = (1 + maxIndexChanged - minIndexChanged) * stride;
vbo.map(offset, length, buffer -> {
for (int i = minIndexChanged; i <= maxIndexChanged; i++) {
data.get(i).write(buffer);
}
});
}
glInstanceCount = newInstanceCount;
if (newInstanceCount < glInstanceCount) {
int clearFrom = (maxIndexChanged + 1) * stride;
int clearTo = (glInstanceCount) * stride;
vbo.map(clearFrom, clearTo - clearFrom, buffer -> {
for (int i = clearFrom; i < clearTo; i++) {
buffer.put((byte) 0);
}
});
}
int staticAttributes = getModelFormat().getShaderAttributeCount();
instanceFormat.informAttributes(staticAttributes);
glInstanceCount = newInstanceCount;
for (int i = 0; i < instanceFormat.getShaderAttributeCount(); i++) {
GL33.glVertexAttribDivisor(i + staticAttributes, 1);
}
int staticAttributes = getModelFormat().getShaderAttributeCount();
instanceFormat.informAttributes(staticAttributes);
instanceVBO.unbind();
for (int i = 0; i < instanceFormat.getShaderAttributeCount(); i++) {
GL33.glVertexAttribDivisor(i + staticAttributes, 1);
}
});
minIndexChanged = -1;
maxIndexChanged = -1;

View file

@ -3,7 +3,6 @@ package com.simibubi.create.foundation.render.instancing;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.foundation.render.gl.attrib.CommonAttributes;
import com.simibubi.create.foundation.render.gl.attrib.VertexAttribSpec;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import com.simibubi.create.foundation.utility.ColorHelper;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.util.math.BlockPos;
@ -13,11 +12,6 @@ import java.nio.ByteBuffer;
import static com.simibubi.create.foundation.render.gl.attrib.VertexAttribSpec.*;
public class KineticData<D extends KineticData<D>> extends InstanceData {
public static final VertexAttribSpec ROTATION_CENTER = copy(CommonAttributes.VEC3);
public static final VertexAttribSpec SPEED = copy(CommonAttributes.FLOAT);
public static final VertexAttribSpec OFFSET = copy(CommonAttributes.FLOAT);
public static final VertexFormat FORMAT = new VertexFormat(CommonAttributes.INSTANCE_POSITION, CommonAttributes.LIGHT, CommonAttributes.RGB, SPEED, OFFSET);
private float x;
private float y;
private float z;

View file

@ -1,6 +1,8 @@
package com.simibubi.create.foundation.render.instancing;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import com.simibubi.create.foundation.render.gl.attrib.impl.KineticVertexAttributes;
import com.simibubi.create.foundation.render.gl.attrib.impl.RotatingVertexAttributes;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.util.Direction;
@ -9,7 +11,10 @@ import java.nio.ByteBuffer;
import static com.simibubi.create.foundation.render.gl.attrib.CommonAttributes.NORMAL;
public class RotatingData extends KineticData<RotatingData> {
public static VertexFormat FORMAT = new VertexFormat(KineticData.FORMAT, NORMAL);
public static VertexFormat FORMAT = VertexFormat.builder()
.addAttributes(KineticVertexAttributes.class)
.addAttributes(RotatingVertexAttributes.class)
.build();
private byte rotationAxisX;
private byte rotationAxisY;

View file

@ -1,34 +0,0 @@
package com.simibubi.create.foundation.render.instancing.actors;
import com.simibubi.create.foundation.render.instancing.InstanceData;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import net.minecraft.client.renderer.Vector3f;
import java.nio.ByteBuffer;
import static com.simibubi.create.foundation.render.gl.attrib.CommonAttributes.NORMAL;
public class DynamicRotatingActorData extends InstanceData {
public static VertexFormat FORMAT = new VertexFormat(NORMAL);
private byte relativeMotionX;
private byte relativeMotionY;
private byte relativeMotionZ;
public DynamicRotatingActorData setRelativeMotion(Vector3f axis) {
setRelativeMotion(axis.getX(), axis.getY(), axis.getZ());
return this;
}
public DynamicRotatingActorData setRelativeMotion(float relativeMotionX, float relativeMotionY, float relativeMotionZ) {
this.relativeMotionX = (byte) (relativeMotionX * 127);
this.relativeMotionY = (byte) (relativeMotionY * 127);
this.relativeMotionZ = (byte) (relativeMotionZ * 127);
return this;
}
@Override
public void write(ByteBuffer buf) {
putVec3(buf, relativeMotionX, relativeMotionY, relativeMotionZ);
}
}

View file

@ -1,24 +1,14 @@
package com.simibubi.create.foundation.render.instancing.actors;
import com.simibubi.create.foundation.render.instancing.DynamicInstancedModel;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import net.minecraft.client.renderer.BufferBuilder;
public class RotatingActorModel extends DynamicInstancedModel<StaticRotatingActorData, DynamicRotatingActorData> {
public class RotatingActorModel extends InstancedModel<StaticRotatingActorData> {
public RotatingActorModel(BufferBuilder buf) {
super(buf);
}
@Override
protected VertexFormat getDynamicFormat() {
return DynamicRotatingActorData.FORMAT;
}
@Override
protected DynamicRotatingActorData newDynamicPart() {
return new DynamicRotatingActorData();
}
@Override
protected VertexFormat getInstanceFormat() {
return StaticRotatingActorData.FORMAT;

View file

@ -1,15 +1,18 @@
package com.simibubi.create.foundation.render.instancing.actors;
import com.simibubi.create.foundation.render.gl.attrib.CommonAttributes;
import com.simibubi.create.foundation.render.instancing.InstanceData;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import com.simibubi.create.foundation.render.gl.attrib.impl.ActorVertexAttributes;
import com.simibubi.create.foundation.render.instancing.InstanceData;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.util.math.BlockPos;
import java.nio.ByteBuffer;
public class StaticRotatingActorData extends InstanceData {
public static VertexFormat FORMAT = new VertexFormat(CommonAttributes.POSITION, CommonAttributes.LIGHT, CommonAttributes.FLOAT, CommonAttributes.NORMAL, CommonAttributes.VEC3, CommonAttributes.NORMAL);
public static VertexFormat FORMAT = VertexFormat.builder()
.addAttributes(ActorVertexAttributes.class)
.build();
private float x;
private float y;

View file

@ -1,71 +1,70 @@
#version 330 core
#version 110
#define PI 3.1415926538
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;
attribute vec3 aPos;
attribute vec3 aNormal;
attribute vec2 aTexCoords;
layout (location = 3) in vec3 instancePos;
layout (location = 4) in vec2 light;
layout (location = 5) in vec3 networkTint;
layout (location = 6) in float speed;
layout (location = 7) in float offset;
layout (location = 8) in vec3 eulerAngles;
layout (location = 9) in vec2 sourceTexture;
layout (location = 10) in vec4 scrollTexture;
layout (location = 11) in float scrollMult;
attribute vec3 aInstancePos;
attribute vec2 aLight;
attribute vec3 aNetworkTint;
attribute float aSpeed;
attribute float aOffset;
attribute vec3 aInstanceRot;
attribute vec2 aSourceTexture;
attribute vec4 aScrollTexture;
attribute float aScrollMult;
out vec2 TexCoords;
out vec4 Color;
out float Diffuse;
out vec2 Light;
varying vec2 TexCoords;
varying vec4 Color;
varying float Diffuse;
varying vec2 Light;
#if defined(CONTRAPTION)
out vec3 BoxCoord;
varying vec3 BoxCoord;
uniform vec3 uLightBoxSize;
uniform vec3 uLightBoxMin;
uniform mat4 uModel;
#endif
uniform int uTicks;
uniform float uTime;
uniform mat4 uViewProjection;
uniform int uDebug;
uniform vec3 uCameraPos;
out float FragDistance;
varying float FragDistance;
mat4 rotate(vec3 axis, float angle) {
float s = sin(angle);
float c = cos(angle);
float oc = 1 - c;
float oc = 1. - c;
return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0,
oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0,
oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0,
0, 0, 0, 1);
return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.,
oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.,
oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.,
0., 0., 0., 1.);
}
float diffuse(vec3 normal) {
float x = normal.x;
float y = normal.y;
float z = normal.z;
return min(x * x * .6 + y * y * ((3 + y) / 4) + z * z * .8, 1);
return min(x * x * .6 + y * y * ((3. + y) / 4.) + z * z * .8, 1.);
}
mat4 rotation(vec3 rot) {
return rotate(vec3(0, 1, 0), rot.y) * rotate(vec3(0, 0, 1), rot.z) * rotate(vec3(1, 0, 0), rot.x);
return rotate(vec3(0., 1., 0.), rot.y) * rotate(vec3(0., 0., 1.), rot.z) * rotate(vec3(1., 0., 0.), rot.x);
}
mat4 localRotation() {
vec3 rot = fract(eulerAngles / 360) * PI * 2;
vec3 rot = fract(aInstanceRot / 360.) * PI * 2.;
return rotation(rot);
}
void main() {
mat4 localRotation = localRotation();
vec4 worldPos = localRotation * vec4(aPos - .5, 1) + vec4(instancePos + .5, 0);
vec4 worldPos = localRotation * vec4(aPos - .5, 1.) + vec4(aInstancePos + .5, 0.);
#ifdef CONTRAPTION
@ -77,30 +76,30 @@ void main() {
mat4 normalMat = localRotation;
#endif
vec3 norm = normalize(normalMat * vec4(aNormal, 0)).xyz;
vec3 norm = normalize(normalMat * vec4(aNormal, 0.)).xyz;
float scrollSize = scrollTexture.w - scrollTexture.y;
float scroll = fract(speed * uTime / (36 * 16) + offset) * scrollSize * scrollMult;
float scrollSize = aScrollTexture.w - aScrollTexture.y;
float scroll = fract(aSpeed * uTime / (36. * 16.) + aOffset) * scrollSize * aScrollMult;
Diffuse = diffuse(norm);
TexCoords = aTexCoords - sourceTexture + scrollTexture.xy + vec2(0, scroll);
Light = light;
TexCoords = aTexCoords - aSourceTexture + aScrollTexture.xy + vec2(0, scroll);
Light = aLight;
FragDistance = length(worldPos.xyz - uCameraPos);
gl_Position = uViewProjection * worldPos;
#ifdef CONTRAPTION
if (uDebug == 2) {
Color = vec4(norm, 1);
Color = vec4(norm, 1.);
} else {
Color = vec4(1);
Color = vec4(1.);
}
#else
if (uDebug == 1) {
Color = vec4(networkTint, 1);
Color = vec4(aNetworkTint, 1.);
} else if (uDebug == 2) {
Color = vec4(norm, 1);
Color = vec4(norm, 1.);
} else {
Color = vec4(1);
Color = vec4(1.);
}
#endif
}

View file

@ -1,14 +1,12 @@
#version 330 core
#version 110
in vec2 TexCoords;
in vec4 Color;
in float Diffuse;
in vec2 Light;
in float FragDistance;
varying vec2 TexCoords;
varying vec4 Color;
varying float Diffuse;
varying vec2 Light;
varying float FragDistance;
in vec3 BoxCoord;
out vec4 fragColor;
varying vec3 BoxCoord;
uniform vec2 uFogRange;
uniform vec4 uFogColor;
@ -18,7 +16,7 @@ uniform sampler2D uLightMap;
uniform sampler3D uLightVolume;
vec4 light() {
vec2 lm = texture(uLightVolume, BoxCoord).rg * 0.9375 + 0.03125;
vec2 lm = texture3D(uLightVolume, BoxCoord).rg * 0.9375 + 0.03125;
return texture2D(uLightMap, max(lm, Light));
}
@ -28,8 +26,8 @@ void main() {
vec4 color = vec4(tex.rgb * light().rgb * Diffuse * Color.rgb, tex.a);
float fog = (uFogRange.y - FragDistance) / (uFogRange.y - uFogRange.x);
fog = clamp(fog, 0, 1);
fog = clamp(fog, 0., 1.);
fragColor = mix(uFogColor, color, fog);
fragColor.a = color.a;
gl_FragColor = mix(uFogColor, color, fog);
gl_FragColor.a = color.a;
}

View file

@ -1,92 +1,88 @@
#version 330 core
#version 110
#define PI 3.1415926538
// model data
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;
attribute vec3 aPos;
attribute vec3 aNormal;
attribute vec2 aTexCoords;
// instance data
layout (location = 3) in vec3 instancePos;
layout (location = 4) in vec2 modelLight;
layout (location = 5) in float rotationOffset;
layout (location = 6) in vec3 localRotationAxis;
layout (location = 7) in vec3 localRotation;
layout (location = 8) in vec3 rotationCenter;
attribute vec3 aInstancePos;
attribute vec2 aModelLight;
attribute float aOffset;
attribute vec3 aAxis;
attribute vec3 aInstanceRot;
attribute vec3 aRotationCenter;
// dynamic data
//layout (location = 9) in vec3 relativeMotion;
out float Diffuse;
out vec2 TexCoords;
out vec4 Color;
out vec3 BoxCoord;
out vec2 Light;
varying float Diffuse;
varying vec2 TexCoords;
varying vec4 Color;
varying vec3 BoxCoord;
varying vec2 Light;
uniform vec3 uLightBoxSize;
uniform vec3 uLightBoxMin;
uniform mat4 uModel;
uniform int uTicks;
uniform float uTime;
uniform mat4 uViewProjection;
uniform int uDebug;
uniform vec3 uCameraPos;
out float FragDistance;
varying float FragDistance;
mat4 rotate(vec3 axis, float angle) {
float s = sin(angle);
float c = cos(angle);
float oc = 1 - c;
float oc = 1. - c;
return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0,
oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0,
oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0,
0, 0, 0, 1);
return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.,
oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.,
oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.,
0., 0., 0., 1.);
}
float diffuse(vec3 normal) {
float x = normal.x;
float y = normal.y;
float z = normal.z;
return min(x * x * .6 + y * y * ((3 + y) / 4) + z * z * .8, 1);
return min(x * x * .6 + y * y * ((3. + y) / 4.) + z * z * .8, 1.);
}
mat4 rotation(vec3 rot) {
return rotate(vec3(0, 1, 0), rot.y) * rotate(vec3(0, 0, 1), rot.z) * rotate(vec3(1, 0, 0), rot.x);
return rotate(vec3(0., 1., 0.), rot.y) * rotate(vec3(0., 0., 1.), rot.z) * rotate(vec3(1., 0., 0.), rot.x);
}
mat4 kineticRotation() {
const float speed = -20;
float degrees = rotationOffset + uTime * speed * -3/10;
float angle = fract(degrees / 360) * PI * 2;
const float speed = -20.;
float degrees = aOffset + uTime * speed * -3./10.;
float angle = fract(degrees / 360.) * PI * 2.;
return rotate(normalize(localRotationAxis), angle);
return rotate(normalize(aAxis), angle);
}
void main() {
mat4 kineticRotation = kineticRotation();
vec4 localPos = kineticRotation * vec4(aPos - rotationCenter, 1) + vec4(rotationCenter, 0);
//localPos = vec4(localPos.xyz + instancePos, 1);
vec4 localPos = kineticRotation * vec4(aPos - aRotationCenter, 1.) + vec4(aRotationCenter, 0.);
vec3 rot = fract(localRotation / 360) * PI * 2;
vec3 rot = fract(aInstanceRot / 360.) * PI * 2.;
mat4 localRot = rotation(rot);
localPos = localRot * vec4(localPos.xyz - .5, 1) + vec4(instancePos + .5, 0);
localPos = localRot * vec4(localPos.xyz - .5, 1.) + vec4(aInstancePos + .5, 0.);
vec4 worldPos = uModel * localPos;
vec3 norm = normalize(uModel * localRot * kineticRotation * vec4(aNormal, 0)).xyz;
vec3 norm = normalize(uModel * localRot * kineticRotation * vec4(aNormal, 0.)).xyz;
BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize;
Diffuse = diffuse(norm);
TexCoords = aTexCoords;
Light = modelLight;
Light = aModelLight;
FragDistance = length(worldPos.xyz - uCameraPos);
gl_Position = uViewProjection * worldPos;
if (uDebug == 2) {
Color = vec4(norm, 1);
Color = vec4(norm, 1.);
} else {
Color = vec4(1);
Color = vec4(1.);
}
}

View file

@ -1,63 +1,62 @@
#version 330 core
#version 110
#define PI 3.1415926538
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;
layout (location = 3) in vec4 aColor;
layout (location = 4) in vec2 modelLight;
attribute vec3 aPos;
attribute vec3 aNormal;
attribute vec2 aTexCoords;
attribute vec4 aColor;
attribute vec2 aModelLight;
out float Diffuse;
out vec2 TexCoords;
out vec4 Color;
out vec3 BoxCoord;
out vec2 Light;
varying float Diffuse;
varying vec2 TexCoords;
varying vec4 Color;
varying vec3 BoxCoord;
varying vec2 Light;
uniform vec3 uLightBoxSize;
uniform vec3 uLightBoxMin;
uniform mat4 uModel;
uniform int uTicks;
uniform float uTime;
uniform mat4 uViewProjection;
uniform int uDebug;
uniform vec3 uCameraPos;
out float FragDistance;
varying float FragDistance;
mat4 rotate(vec3 axis, float angle) {
float s = sin(angle);
float c = cos(angle);
float oc = 1 - c;
float oc = 1. - c;
return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0,
oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0,
oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0,
0, 0, 0, 1);
return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.,
oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.,
oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.,
0., 0., 0., 1.);
}
float diffuse(vec3 normal) {
float x = normal.x;
float y = normal.y;
float z = normal.z;
return min(x * x * .6 + y * y * ((3 + y) / 4) + z * z * .8, 1);
return min(x * x * .6 + y * y * ((3. + y) / 4.) + z * z * .8, 1.);
}
void main() {
vec4 worldPos = uModel * vec4(aPos, 1);
vec4 worldPos = uModel * vec4(aPos, 1.);
vec3 norm = (uModel * vec4(aNormal, 0)).xyz;
vec3 norm = (uModel * vec4(aNormal, 0.)).xyz;
BoxCoord = (worldPos.xyz - uLightBoxMin) / uLightBoxSize;
Diffuse = diffuse(norm);
Color = aColor / diffuse(aNormal);
TexCoords = aTexCoords;
Light = modelLight;
Light = aModelLight;
FragDistance = length(worldPos.xyz - uCameraPos);
gl_Position = uViewProjection * worldPos;
if (uDebug == 2) {
Color = vec4(norm, 1);
Color = vec4(norm, 1.);
} else {
Color = aColor / diffuse(aNormal);
}

View file

@ -1,12 +1,10 @@
#version 330 core
#version 110
in vec2 TexCoords;
in vec2 Light;
in float Diffuse;
in vec4 Color;
in float FragDistance;
out vec4 fragColor;
varying vec2 TexCoords;
varying vec2 Light;
varying float Diffuse;
varying vec4 Color;
varying float FragDistance;
uniform vec2 uFogRange;
uniform vec4 uFogColor;
@ -25,8 +23,8 @@ void main() {
vec4 color = vec4(tex.rgb * light().rgb * Diffuse, tex.a) * Color;
float fog = (uFogRange.y - FragDistance) / (uFogRange.y - uFogRange.x);
fog = clamp(fog, 0, 1);
fog = clamp(fog, 0., 1.);
fragColor = mix(uFogColor, color, fog);
fragColor.a = color.a;
gl_FragColor = mix(uFogColor, color, fog);
gl_FragColor.a = color.a;
}

View file

@ -1,69 +1,68 @@
#version 330 core
#version 110
#define PI 3.1415926538
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;
attribute vec3 aPos;
attribute vec3 aNormal;
attribute vec2 aTexCoords;
layout (location = 3) in vec3 instancePos;
layout (location = 4) in vec2 light;
layout (location = 5) in vec3 networkTint;
layout (location = 6) in float speed;
layout (location = 7) in float offset;
layout (location = 8) in vec3 rotationAxis;
attribute vec3 aInstancePos;
attribute vec2 aLight;
attribute vec3 aNetworkTint;
attribute float aSpeed;
attribute float aOffset;
attribute vec3 aAxis;
out vec2 TexCoords;
out vec4 Color;
out float Diffuse;
out vec2 Light;
varying vec2 TexCoords;
varying vec4 Color;
varying float Diffuse;
varying vec2 Light;
#if defined(CONTRAPTION)
out vec3 BoxCoord;
varying vec3 BoxCoord;
uniform vec3 uLightBoxSize;
uniform vec3 uLightBoxMin;
uniform mat4 uModel;
#endif
uniform int uTicks;
uniform float uTime;
uniform mat4 uViewProjection;
uniform int uDebug;
uniform vec3 uCameraPos;
out float FragDistance;
varying float FragDistance;
mat4 rotate(vec3 axis, float angle) {
float s = sin(angle);
float c = cos(angle);
float oc = 1 - c;
float oc = 1. - c;
return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0,
oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0,
oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0,
0, 0, 0, 1);
return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.,
oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.,
oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.,
0., 0., 0., 1.);
}
float diffuse(vec3 normal) {
float x = normal.x;
float y = normal.y;
float z = normal.z;
return min(x * x * .6 + y * y * ((3 + y) / 4) + z * z * .8, 1);
return min(x * x * .6 + y * y * ((3. + y) / 4.) + z * z * .8, 1.);
}
mat4 rotation(vec3 rot) {
return rotate(vec3(0, 1, 0), rot.y) * rotate(vec3(0, 0, 1), rot.z) * rotate(vec3(1, 0, 0), rot.x);
return rotate(vec3(0., 1., 0.), rot.y) * rotate(vec3(0., 0., 1.), rot.z) * rotate(vec3(1., 0., 0.), rot.x);
}
mat4 kineticRotation() {
float degrees = offset + uTime * speed * -3/10;
float angle = fract(degrees / 360) * PI * 2;
float degrees = aOffset + uTime * aSpeed * -3./10.;
float angle = fract(degrees / 360.) * PI * 2.;
return rotate(rotationAxis, angle);
return rotate(aAxis, angle);
}
void main() {
mat4 kineticRotation = kineticRotation();
vec4 worldPos = kineticRotation * vec4(aPos - 0.5, 1) + vec4(instancePos + .5, 0);
vec4 worldPos = kineticRotation * vec4(aPos - .5, 1.) + vec4(aInstancePos + .5, 0.);
#ifdef CONTRAPTION
@ -75,27 +74,27 @@ void main() {
mat4 normalMat = kineticRotation;
#endif
vec3 norm = normalize(normalMat * vec4(aNormal, 0)).xyz;
vec3 norm = normalize(normalMat * vec4(aNormal, 0.)).xyz;
Diffuse = diffuse(norm);
TexCoords = aTexCoords;
Light = light;
Light = aLight;
FragDistance = length(worldPos.xyz - uCameraPos);
gl_Position = uViewProjection * worldPos;
#ifdef CONTRAPTION
if (uDebug == 2) {
Color = vec4(norm, 1);
Color = vec4(norm, 1.);
} else {
Color = vec4(1);
Color = vec4(1.);
}
#else
if (uDebug == 1) {
Color = vec4(networkTint, 1);
Color = vec4(aNetworkTint, 1.);
} else if (uDebug == 2) {
Color = vec4(norm, 1);
Color = vec4(norm, 1.);
} else {
Color = vec4(1);
Color = vec4(1.);
}
#endif
}