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. * layer-correct custom rendering. RenderWorldLast is not refined enough for rendering world objects.
* This should probably be a forge event. * 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) { 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); 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.Create;
import com.simibubi.create.foundation.render.contraption.ContraptionProgram; import com.simibubi.create.foundation.render.contraption.ContraptionProgram;
import com.simibubi.create.foundation.render.gl.BasicProgram; import com.simibubi.create.foundation.render.gl.BasicProgram;
import com.simibubi.create.foundation.render.gl.backend.Backend; import com.simibubi.create.foundation.render.gl.attrib.impl.*;
import com.simibubi.create.foundation.render.gl.shader.GlProgram;
import com.simibubi.create.foundation.render.gl.shader.ProgramSpec; import com.simibubi.create.foundation.render.gl.shader.ProgramSpec;
import com.simibubi.create.foundation.render.gl.shader.ShaderConstants; import com.simibubi.create.foundation.render.gl.shader.ShaderConstants;
import net.minecraft.util.ResourceLocation; 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; import static com.simibubi.create.foundation.render.gl.backend.Backend.register;
public class AllProgramSpecs { public class AllProgramSpecs {
public static final ProgramSpec<BasicProgram> ROTATING = register(new ProgramSpec<>("rotating", Locations.ROTATING, Locations.INSTANCED, BasicProgram::new)); public static final ProgramSpec<BasicProgram> ROTATING = register(ProgramSpec.builder("rotating", BasicProgram::new)
public static final ProgramSpec<BasicProgram> BELT = register(new ProgramSpec<>("belt", Locations.BELT, Locations.INSTANCED, BasicProgram::new)); .addAttributes(ModelVertexAttributes.class)
public static final ProgramSpec<ContraptionProgram> CONTRAPTION_STRUCTURE = register(new ProgramSpec<>("contraption_structure", Locations.CONTRAPTION_STRUCTURE, Locations.CONTRAPTION, ContraptionProgram::new)); .addAttributes(KineticVertexAttributes.class)
public static final ProgramSpec<ContraptionProgram> CONTRAPTION_ROTATING = register(new ProgramSpec<>("contraption_rotating", Locations.ROTATING, Locations.CONTRAPTION, ContraptionProgram::new, ShaderConstants.define("CONTRAPTION"))); .addAttributes(RotatingVertexAttributes.class)
public static final ProgramSpec<ContraptionProgram> CONTRAPTION_BELT = register(new ProgramSpec<>("contraption_belt", Locations.BELT, Locations.CONTRAPTION, ContraptionProgram::new, ShaderConstants.define("CONTRAPTION"))); .setVert(Locations.ROTATING)
public static final ProgramSpec<ContraptionProgram> CONTRAPTION_ACTOR = register(new ProgramSpec<>("contraption_actor", Locations.CONTRAPTION_ACTOR, Locations.CONTRAPTION, ContraptionProgram::new)); .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 class Locations {
public static final ResourceLocation INSTANCED = loc("instanced.frag"); public static final ResourceLocation INSTANCED = loc("instanced.frag");

View file

@ -1,19 +1,18 @@
package com.simibubi.create.foundation.render; 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.backend.Backend;
import com.simibubi.create.foundation.render.gl.GlBuffer; import com.simibubi.create.foundation.render.gl.GlBuffer;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.BufferBuilder;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL20;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.HashSet;
public abstract class BufferedModel extends TemplateBuffer { public abstract class BufferedModel extends TemplateBuffer {
protected GlBuffer ebo;
protected GlBuffer modelVBO; protected GlBuffer modelVBO;
protected boolean removed; protected boolean removed;
@ -26,9 +25,9 @@ public abstract class BufferedModel extends TemplateBuffer {
modelVBO = new GlBuffer(GL20.GL_ARRAY_BUFFER); modelVBO = new GlBuffer(GL20.GL_ARRAY_BUFFER);
modelVBO.bind(); modelVBO.with(vbo -> initModel());
initModel();
modelVBO.unbind(); ebo = createEBO();
} }
protected void initModel() { 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 void copyVertex(ByteBuffer to, int index);
protected abstract VertexFormat getModelFormat(); protected abstract VertexFormat getModelFormat();
@ -64,35 +82,30 @@ public abstract class BufferedModel extends TemplateBuffer {
} }
/** /**
* Override this * Override this.
*/ */
protected void doRender() { protected void doRender() {
GL20.glDisableClientState(32884);
GL20.glDisableClientState(32885);
GL20.glDisableClientState(32886);
GL20.glDisableClientState(32888);
GL20.glEnable(GL20.GL_VERTEX_ARRAY);
modelVBO.bind(); modelVBO.bind();
ebo.bind();
setupAttributes(); setupAttributes();
GL20.glDrawArrays(GL11.GL_QUADS, 0, vertexCount); GL20.glDrawElements(GL20.GL_QUADS, vertexCount, GlPrimitiveType.USHORT.getGlConstant(), 0);
modelVBO.unbind();
int numAttributes = getTotalShaderAttributeCount(); int numAttributes = getTotalShaderAttributeCount();
for (int i = 0; i <= numAttributes; i++) { for (int i = 0; i <= numAttributes; i++) {
GL20.glDisableVertexAttribArray(i); GL20.glDisableVertexAttribArray(i);
} }
GL20.glDisable(GL20.GL_VERTEX_ARRAY); ebo.unbind();
modelVBO.unbind();
} }
protected void setupAttributes() { protected void setupAttributes() {
int numAttributes = getTotalShaderAttributeCount(); int numAttributes = getTotalShaderAttributeCount();
for (int i = 0; i <= numAttributes; i++) { for (int i = 0; i <= numAttributes; i++) {
GL20.glEnableVertexAttribArray(i); GL20.glEnableVertexAttribArray(i);
} }
getModelFormat().informAttributes(0); 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; if (!available()) return;
Matrix4f viewProjection = Matrix4f.translate(-cameraX, -cameraY, -cameraZ); Matrix4f viewProjection = Matrix4f.translate(-cameraX, -cameraY, -cameraZ);
viewProjection.multiplyBackward(stack.peek().getModel()); viewProjection.multiplyBackward(stack.peek().getModel());
viewProjection.multiplyBackward(getProjectionMatrix()); viewProjection.multiplyBackward(getProjectionMatrix());
type.startDrawing(); layer.startDrawing();
RenderSystem.enableDepthTest(); RenderSystem.enableDepthTest();
RenderSystem.enableCull(); RenderSystem.enableCull();
GL11.glCullFace(GL11.GL_BACK); GL11.glCullFace(GL11.GL_BACK);
CreateClient.kineticRenderer.render(type, viewProjection, cameraX, cameraY, cameraZ); CreateClient.kineticRenderer.render(layer, viewProjection, cameraX, cameraY, cameraZ);
RenderSystem.disableCull(); RenderSystem.disableCull();
//RenderSystem.disableDepthTest(); //RenderSystem.disableDepthTest();
ContraptionRenderDispatcher.renderLayer(type, viewProjection, cameraX, cameraY, cameraZ); ContraptionRenderDispatcher.renderLayer(layer, viewProjection, cameraX, cameraY, cameraZ);
if (!OptifineHandler.usingShaders()) if (!OptifineHandler.usingShaders())
GL20.glUseProgram(0); GL20.glUseProgram(0);
type.endDrawing(); layer.endDrawing();
} }
public static void notifyLightUpdate(ClientChunkProvider world, LightType type, SectionPos pos) { public static void notifyLightUpdate(ClientChunkProvider world, LightType type, SectionPos pos) {

View file

@ -1,13 +1,11 @@
package com.simibubi.create.foundation.render.contraption; package com.simibubi.create.foundation.render.contraption;
import com.simibubi.create.foundation.render.BufferedModel; 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.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.BufferBuilder;
import net.minecraft.client.renderer.LightTexture; 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; 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; import static com.simibubi.create.foundation.render.gl.attrib.CommonAttributes.RGBA;
public class ContraptionModel extends BufferedModel { 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) { public ContraptionModel(BufferBuilder buf) {
super(buf); super(buf);

View file

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

View file

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

View file

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

View file

@ -2,6 +2,8 @@ package com.simibubi.create.foundation.render.gl;
import org.lwjgl.opengl.GL30; import org.lwjgl.opengl.GL30;
import java.util.function.Consumer;
public class GlVertexArray extends GlObject { public class GlVertexArray extends GlObject {
public GlVertexArray() { public GlVertexArray() {
setHandle(GL30.glGenVertexArrays()); setHandle(GL30.glGenVertexArrays());
@ -15,6 +17,12 @@ public class GlVertexArray extends GlObject {
GL30.glBindVertexArray(0); GL30.glBindVertexArray(0);
} }
public void with(Consumer<GlVertexArray> action) {
bind();
action.accept(this);
unbind();
}
protected void deleteInternal(int handle) { protected void deleteInternal(int handle) {
GL30.glDeleteVertexArrays(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 VEC2 = new VertexAttribSpec(GlPrimitiveType.FLOAT, 2);
public static final VertexAttribSpec FLOAT = new VertexAttribSpec(GlPrimitiveType.FLOAT, 1); 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 NORMAL = new VertexAttribSpec(GlPrimitiveType.BYTE, 3, true);
public static final VertexAttribSpec UV = VertexAttribSpec.copy(VEC2); public static final VertexAttribSpec UV = new VertexAttribSpec(GlPrimitiveType.FLOAT, 2);
public static final VertexAttribSpec ROTATION = VertexAttribSpec.copy(VEC3);
public static final VertexAttribSpec INSTANCE_POSITION = VertexAttribSpec.copy(VEC3);
public static final VertexAttribSpec RGBA = new VertexAttribSpec(GlPrimitiveType.UBYTE, 4, true); 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 RGB = new VertexAttribSpec(GlPrimitiveType.UBYTE, 3, true);
public static final VertexAttribSpec LIGHT = new VertexAttribSpec(GlPrimitiveType.UBYTE, 2, 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 int attributeCount;
private final boolean normalized; 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) { public VertexAttribSpec(GlPrimitiveType type, int count) {
this(type, count, false); this(type, count, false);
} }

View file

@ -1,34 +1,23 @@
package com.simibubi.create.foundation.render.gl.attrib; package com.simibubi.create.foundation.render.gl.attrib;
import java.util.ArrayList;
import java.util.Arrays;
public class VertexFormat { public class VertexFormat {
private final VertexAttribSpec[] elements; private final ArrayList<IVertexAttrib> allAttributes;
private final int numAttributes; private final int numAttributes;
private final int stride; private final int stride;
public VertexFormat(VertexAttribSpec... elements) { public VertexFormat(ArrayList<IVertexAttrib> allAttributes) {
this.elements = elements; this.allAttributes = allAttributes;
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);
int numAttributes = 0, stride = 0; int numAttributes = 0, stride = 0;
for (VertexAttribSpec element : this.elements) { for (IVertexAttrib attrib : allAttributes) {
numAttributes += element.getAttributeCount(); VertexAttribSpec spec = attrib.attribSpec();
stride += element.getSize(); numAttributes += spec.getAttributeCount();
stride += spec.getSize();
} }
this.numAttributes = numAttributes; this.numAttributes = numAttributes;
this.stride = stride; this.stride = stride;
@ -44,10 +33,33 @@ public class VertexFormat {
public void informAttributes(int index) { public void informAttributes(int index) {
int offset = 0; int offset = 0;
for (VertexAttribSpec element : this.elements) { for (IVertexAttrib attrib : this.allAttributes) {
element.registerForBuffer(stride, index, offset); VertexAttribSpec spec = attrib.attribSpec();
index += element.getAttributeCount(); spec.registerForBuffer(stride, index, offset);
offset += element.getSize(); 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 { public enum ModelVertexAttributes implements IVertexAttrib {
VERTEX_POSITION("aPos", CommonAttributes.VEC3), 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 { 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), AXIS("aAxis", CommonAttributes.NORMAL),
; ;

View file

@ -1,6 +1,7 @@
package com.simibubi.create.foundation.render.gl.backend; package com.simibubi.create.foundation.render.gl.backend;
import com.simibubi.create.foundation.config.AllConfigs; 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.GlProgram;
import com.simibubi.create.foundation.render.gl.shader.GlShader; import com.simibubi.create.foundation.render.gl.shader.GlShader;
import com.simibubi.create.foundation.render.gl.shader.ProgramSpec; 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); vert = loadShader(manager, programSpec.getVert(), ShaderType.VERTEX, programSpec.defines);
frag = loadShader(manager, programSpec.getFrag(), ShaderType.FRAGMENT, programSpec.defines); frag = loadShader(manager, programSpec.getFrag(), ShaderType.FRAGMENT, programSpec.defines);
P program = GlProgram.builder(programSpec.name) GlProgram.Builder builder = GlProgram.builder(programSpec.name).attachShader(vert).attachShader(frag);
.attachShader(vert)
.attachShader(frag) programSpec.attributes.forEach(builder::addAttribute);
.build(programSpec.factory);
P program = builder.build(programSpec.factory);
programs.put(programSpec, program); programs.put(programSpec, program);

View file

@ -1,6 +1,7 @@
package com.simibubi.create.foundation.render.gl.shader; package com.simibubi.create.foundation.render.gl.shader;
import com.simibubi.create.foundation.render.gl.GlObject; 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 com.simibubi.create.foundation.render.gl.backend.Backend;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL20;
@ -67,6 +68,8 @@ public abstract class GlProgram extends GlObject {
private final ResourceLocation name; private final ResourceLocation name;
private final int program; private final int program;
private int attributeIndex;
public Builder(ResourceLocation name) { public Builder(ResourceLocation name) {
this.name = name; this.name = name;
this.program = GL20.glCreateProgram(); this.program = GL20.glCreateProgram();
@ -78,6 +81,12 @@ public abstract class GlProgram extends GlObject {
return this; 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 * 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 * 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); return factory.create(this.name, this.program);
} }
// public Builder bindAttribute(String name, GlVertexAttribute attribute) {
// GL20.glBindAttribLocation(this.program, attribute.getIndex(), name);
//
// return this;
// }
} }
@FunctionalInterface @FunctionalInterface

View file

@ -1,8 +1,12 @@
package com.simibubi.create.foundation.render.gl.shader; package com.simibubi.create.foundation.render.gl.shader;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.foundation.render.gl.attrib.IVertexAttrib;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import java.util.ArrayList;
import java.util.Arrays;
public class ProgramSpec<P extends GlProgram> { public class ProgramSpec<P extends GlProgram> {
public final ResourceLocation name; public final ResourceLocation name;
@ -13,17 +17,25 @@ public class ProgramSpec<P extends GlProgram> {
public final GlProgram.ProgramFactory<P> factory; public final GlProgram.ProgramFactory<P> factory;
public ProgramSpec(String name, ResourceLocation vert, ResourceLocation frag, GlProgram.ProgramFactory<P> factory) { public final ArrayList<IVertexAttrib> attributes;
this(name, vert, frag, factory, null);
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) { public static <P extends GlProgram> Builder<P> builder(ResourceLocation name, GlProgram.ProgramFactory<P> factory) {
this.name = new ResourceLocation(Create.ID, name); 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.vert = vert;
this.frag = frag; this.frag = frag;
this.defines = defines; this.defines = defines;
this.factory = factory; this.factory = factory;
this.attributes = attributes;
} }
public ResourceLocation getVert() { public ResourceLocation getVert() {
@ -34,4 +46,43 @@ public class ProgramSpec<P extends GlProgram> {
return frag; 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.CommonAttributes;
import com.simibubi.create.foundation.render.gl.attrib.VertexAttribSpec; 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.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 net.minecraft.client.renderer.texture.TextureAtlasSprite;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@ -12,10 +14,10 @@ import java.nio.ByteBuffer;
import static com.simibubi.create.foundation.render.gl.attrib.VertexAttribSpec.*; import static com.simibubi.create.foundation.render.gl.attrib.VertexAttribSpec.*;
public class BeltData extends KineticData<BeltData> { public class BeltData extends KineticData<BeltData> {
public static final VertexAttribSpec TARGET_UV = copy(CommonAttributes.VEC4); public static VertexFormat FORMAT = VertexFormat.builder()
public static final VertexAttribSpec SCROLL_MULT = new VertexAttribSpec(GlPrimitiveType.BYTE, 1, true); .addAttributes(KineticVertexAttributes.class)
.addAttributes(BeltVertexAttributes.class)
public static VertexFormat FORMAT = new VertexFormat(KineticData.FORMAT, CommonAttributes.ROTATION, CommonAttributes.UV, TARGET_UV, SCROLL_MULT); .build();
private float rotX; private float rotX;
private float rotY; 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.BufferedModel;
import com.simibubi.create.foundation.render.RenderMath; import com.simibubi.create.foundation.render.RenderMath;
import com.simibubi.create.foundation.render.gl.GlVertexArray; 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.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 net.minecraft.client.renderer.BufferBuilder;
import org.lwjgl.opengl.*; import org.lwjgl.opengl.*;
@ -16,7 +15,7 @@ import java.util.ArrayList;
import java.util.function.Consumer; import java.util.function.Consumer;
public abstract class InstancedModel<D extends InstanceData> extends BufferedModel { 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 GlVertexArray vao;
protected GlBuffer instanceVBO; protected GlBuffer instanceVBO;
@ -37,9 +36,7 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
vao = new GlVertexArray(); vao = new GlVertexArray();
instanceVBO = new GlBuffer(GL20.GL_ARRAY_BUFFER); instanceVBO = new GlBuffer(GL20.GL_ARRAY_BUFFER);
vao.bind(); vao.with(vao -> super.init());
super.init();
vao.unbind();
} }
@Override @Override
@ -108,10 +105,10 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
} }
protected void doRender() { protected void doRender() {
vao.bind(); vao.with(vao -> {
renderSetup(); renderSetup();
GL31.glDrawArraysInstanced(GL11.GL_QUADS, 0, vertexCount, glInstanceCount); GL31.glDrawArraysInstanced(GL11.GL_QUADS, 0, vertexCount, glInstanceCount);
vao.unbind(); });
} }
protected void renderSetup() { protected void renderSetup() {
@ -123,45 +120,43 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
int newInstanceCount = instanceCount(); int newInstanceCount = instanceCount();
int instanceSize = RenderMath.nextPowerOf2((newInstanceCount + 1) * stride); int instanceSize = RenderMath.nextPowerOf2((newInstanceCount + 1) * stride);
instanceVBO.bind(); instanceVBO.with(vbo -> {
// this probably changes enough that it's not worth reallocating the entire buffer every time.
// this probably changes enough that it's not worth reallocating the entire buffer every time. if (instanceSize > glBufferSize) {
if (instanceSize > glBufferSize) { GL15.glBufferData(vbo.getBufferType(), instanceSize, GL15.GL_STATIC_DRAW);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, instanceSize, GL15.GL_STATIC_DRAW); glBufferSize = instanceSize;
glBufferSize = instanceSize; minIndexChanged = 0;
minIndexChanged = 0; maxIndexChanged = newInstanceCount - 1;
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);
} }
});
if (newInstanceCount < glInstanceCount) { int offset = minIndexChanged * stride;
int clearFrom = (maxIndexChanged + 1) * stride; int length = (1 + maxIndexChanged - minIndexChanged) * stride;
int clearTo = (glInstanceCount) * stride;
Backend.mapBuffer(GL15.GL_ARRAY_BUFFER, clearFrom, clearTo - clearFrom, buffer -> { vbo.map(offset, length, buffer -> {
for (int i = clearFrom; i < clearTo; i++) { for (int i = minIndexChanged; i <= maxIndexChanged; i++) {
buffer.put((byte) 0); 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(); glInstanceCount = newInstanceCount;
instanceFormat.informAttributes(staticAttributes);
for (int i = 0; i < instanceFormat.getShaderAttributeCount(); i++) { int staticAttributes = getModelFormat().getShaderAttributeCount();
GL33.glVertexAttribDivisor(i + staticAttributes, 1); instanceFormat.informAttributes(staticAttributes);
}
instanceVBO.unbind(); for (int i = 0; i < instanceFormat.getShaderAttributeCount(); i++) {
GL33.glVertexAttribDivisor(i + staticAttributes, 1);
}
});
minIndexChanged = -1; minIndexChanged = -1;
maxIndexChanged = -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.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.foundation.render.gl.attrib.CommonAttributes; 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.VertexAttribSpec;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat;
import com.simibubi.create.foundation.utility.ColorHelper; import com.simibubi.create.foundation.utility.ColorHelper;
import net.minecraft.client.renderer.Vector3f; import net.minecraft.client.renderer.Vector3f;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@ -13,11 +12,6 @@ import java.nio.ByteBuffer;
import static com.simibubi.create.foundation.render.gl.attrib.VertexAttribSpec.*; import static com.simibubi.create.foundation.render.gl.attrib.VertexAttribSpec.*;
public class KineticData<D extends KineticData<D>> extends InstanceData { 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 x;
private float y; private float y;
private float z; private float z;

View file

@ -1,6 +1,8 @@
package com.simibubi.create.foundation.render.instancing; package com.simibubi.create.foundation.render.instancing;
import com.simibubi.create.foundation.render.gl.attrib.VertexFormat; 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.client.renderer.Vector3f;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
@ -9,7 +11,10 @@ import java.nio.ByteBuffer;
import static com.simibubi.create.foundation.render.gl.attrib.CommonAttributes.NORMAL; import static com.simibubi.create.foundation.render.gl.attrib.CommonAttributes.NORMAL;
public class RotatingData extends KineticData<RotatingData> { 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 rotationAxisX;
private byte rotationAxisY; 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; 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.gl.attrib.VertexFormat;
import com.simibubi.create.foundation.render.instancing.InstancedModel;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.BufferBuilder;
public class RotatingActorModel extends DynamicInstancedModel<StaticRotatingActorData, DynamicRotatingActorData> { public class RotatingActorModel extends InstancedModel<StaticRotatingActorData> {
public RotatingActorModel(BufferBuilder buf) { public RotatingActorModel(BufferBuilder buf) {
super(buf); super(buf);
} }
@Override
protected VertexFormat getDynamicFormat() {
return DynamicRotatingActorData.FORMAT;
}
@Override
protected DynamicRotatingActorData newDynamicPart() {
return new DynamicRotatingActorData();
}
@Override @Override
protected VertexFormat getInstanceFormat() { protected VertexFormat getInstanceFormat() {
return StaticRotatingActorData.FORMAT; return StaticRotatingActorData.FORMAT;

View file

@ -1,15 +1,18 @@
package com.simibubi.create.foundation.render.instancing.actors; package com.simibubi.create.foundation.render.instancing.actors;
import com.simibubi.create.foundation.render.gl.attrib.CommonAttributes; 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.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.client.renderer.Vector3f;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
public class StaticRotatingActorData extends InstanceData { 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 x;
private float y; private float y;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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