actors render correctly

This commit is contained in:
JozsefA 2021-01-23 12:49:33 -08:00
parent cfd60fbc8d
commit 83cb735e62
14 changed files with 111 additions and 64 deletions

View file

@ -49,10 +49,9 @@ public class DrillRenderer extends KineticTileEntityRenderer {
model.setupInstance(data -> { model.setupInstance(data -> {
Direction facing = state.get(DrillBlock.FACING); Direction facing = state.get(DrillBlock.FACING);
Vector3f orientation = facing.getOpposite().getUnitVector();
data.setPosition(context.localPos) data.setPosition(context.localPos)
.setRotationOffset(0) .setRotationOffset(0)
.setRotationAxis(orientation) .setRotationAxis(0, 0, 1)
.setLocalRotation(AngleHelper.verticalAngle(facing), facing.getHorizontalAngle(), 0); .setLocalRotation(AngleHelper.verticalAngle(facing), facing.getHorizontalAngle(), 0);
}); });
} }

View file

@ -47,13 +47,12 @@ public class HarvesterRenderer extends SafeTileEntityRenderer<HarvesterTileEntit
model.setupInstance(data -> { model.setupInstance(data -> {
Direction facing = state.get(HORIZONTAL_FACING); Direction facing = state.get(HORIZONTAL_FACING);
Direction rotationAxis = facing.rotateY();
float originOffset = 1 / 16f; float originOffset = 1 / 16f;
Vector3f rotOffset = new Vector3f(0.5f, -2 * originOffset + 0.5f, originOffset + 0.5f); Vector3f rotOffset = new Vector3f(0.5f, -2 * originOffset + 0.5f, originOffset + 0.5f);
data.setPosition(context.localPos) data.setPosition(context.localPos)
.setRotationOffset(0) .setRotationOffset(0)
.setRotationCenter(rotOffset) .setRotationCenter(rotOffset)
.setRotationAxis(rotationAxis.getUnitVector()) .setRotationAxis(-1, 0, 0)
.setLocalRotation(0, facing.getHorizontalAngle(), 0); .setLocalRotation(0, facing.getHorizontalAngle(), 0);
}); });
} }

View file

@ -114,6 +114,12 @@ public class ClientEvents {
AnimationTickHolder.ticks = 0; AnimationTickHolder.ticks = 0;
} }
@SubscribeEvent
public static void onUnloadWorld(WorldEvent.Unload event) {
CreateClient.invalidateRenderers();
AnimationTickHolder.ticks = 0;
}
@SubscribeEvent @SubscribeEvent
public static void onRenderWorld(RenderWorldLastEvent event) { public static void onRenderWorld(RenderWorldLastEvent event) {
Vec3d cameraPos = Minecraft.getInstance().gameRenderer.getActiveRenderInfo().getProjectedView(); Vec3d cameraPos = Minecraft.getInstance().gameRenderer.getActiveRenderInfo().getProjectedView();

View file

@ -94,18 +94,11 @@ public class FastKineticRenderer {
public void render(RenderType layer, Matrix4f projection, Matrix4f view, ShaderCallback callback) { public void render(RenderType layer, Matrix4f projection, Matrix4f view, ShaderCallback callback) {
prepareFrame(); prepareFrame();
layer.startDrawing();
for (RenderMaterial<?> material : materials.values()) { for (RenderMaterial<?> material : materials.values()) {
material.render(projection, view, callback); if (material.canRenderInLayer(layer))
material.render(layer, projection, view, callback);
} }
ShaderHelper.releaseShader(); ShaderHelper.releaseShader();
layer.endDrawing();
}
public static RenderType getKineticRenderLayer() {
return RenderType.getCutoutMipped();
} }
} }

View file

@ -7,6 +7,7 @@ import com.simibubi.create.foundation.render.contraption.ContraptionRenderDispat
import com.simibubi.create.foundation.render.instancing.IInstanceRendered; import com.simibubi.create.foundation.render.instancing.IInstanceRendered;
import com.simibubi.create.foundation.render.instancing.IInstancedTileEntityRenderer; import com.simibubi.create.foundation.render.instancing.IInstancedTileEntityRenderer;
import com.simibubi.create.foundation.render.instancing.InstanceContext; import com.simibubi.create.foundation.render.instancing.InstanceContext;
import com.simibubi.create.foundation.render.shader.ShaderHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.player.ClientPlayerEntity; import net.minecraft.client.entity.player.ClientPlayerEntity;
@ -41,17 +42,18 @@ public class FastRenderDispatcher {
view.multiplyBackward(stack.peek().getModel()); view.multiplyBackward(stack.peek().getModel());
Matrix4f projection = getProjectionMatrix(); Matrix4f projection = getProjectionMatrix();
type.startDrawing();
if (type == FastKineticRenderer.getKineticRenderLayer()) {
RenderSystem.enableDepthTest(); RenderSystem.enableDepthTest();
RenderSystem.enableCull(); RenderSystem.enableCull();
GL11.glCullFace(GL11.GL_BACK); GL11.glCullFace(GL11.GL_BACK);
CreateClient.kineticRenderer.render(type, projection, view); CreateClient.kineticRenderer.render(type, projection, view);
RenderSystem.disableCull(); RenderSystem.disableCull();
//RenderSystem.disableDepthTest(); //RenderSystem.disableDepthTest();
}
ContraptionRenderDispatcher.renderLayer(type, projection, view); ContraptionRenderDispatcher.renderLayer(type, projection, view);
ShaderHelper.releaseShader();
type.endDrawing();
} }
public static void notifyLightUpdate(ClientChunkProvider world, LightType type, SectionPos pos) { public static void notifyLightUpdate(ClientChunkProvider world, LightType type, SectionPos pos) {

View file

@ -13,6 +13,7 @@ import java.nio.ByteBuffer;
public abstract class GPUBuffer extends TemplateBuffer { public abstract class GPUBuffer extends TemplateBuffer {
protected int vao, ebo, invariantVBO; protected int vao, ebo, invariantVBO;
protected boolean removed;
public GPUBuffer(BufferBuilder buf) { public GPUBuffer(BufferBuilder buf) {
super(buf); super(buf);
@ -68,7 +69,7 @@ public abstract class GPUBuffer extends TemplateBuffer {
} }
public void render() { public void render() {
if (vao == 0) return; if (vao == 0 || removed) return;
GL30.glBindVertexArray(vao); GL30.glBindVertexArray(vao);
preDrawTask(); preDrawTask();
@ -91,6 +92,7 @@ public abstract class GPUBuffer extends TemplateBuffer {
} }
public void delete() { public void delete() {
removed = true;
if (vertexCount > 0) { if (vertexCount > 0) {
RenderWork.enqueue(this::deleteInternal); RenderWork.enqueue(this::deleteInternal);
} }

View file

@ -43,12 +43,12 @@ public class ContraptionRenderDispatcher {
return renderer; return renderer;
} }
public static void renderLayer(RenderType renderType, Matrix4f projectionMat, Matrix4f viewMat) { public static void renderLayer(RenderType layer, Matrix4f projectionMat, Matrix4f viewMat) {
removeDeadContraptions(); removeDeadContraptions();
if (renderers.isEmpty()) return; if (renderers.isEmpty()) return;
renderType.startDrawing(); layer.startDrawing();
GL11.glEnable(GL13.GL_TEXTURE_3D); GL11.glEnable(GL13.GL_TEXTURE_3D);
GL13.glActiveTexture(GL40.GL_TEXTURE4); // the shaders expect light volumes to be in texture 4 GL13.glActiveTexture(GL40.GL_TEXTURE4); // the shaders expect light volumes to be in texture 4
@ -56,20 +56,15 @@ public class ContraptionRenderDispatcher {
int structureShader = ShaderHelper.useShader(Shader.CONTRAPTION_STRUCTURE, callback); int structureShader = ShaderHelper.useShader(Shader.CONTRAPTION_STRUCTURE, callback);
for (RenderedContraption renderer : renderers.values()) { for (RenderedContraption renderer : renderers.values()) {
renderer.doRenderLayer(renderType, structureShader); renderer.doRenderLayer(layer, structureShader);
} }
if (renderType == FastKineticRenderer.getKineticRenderLayer()) {
for (RenderedContraption renderer : renderers.values()) { for (RenderedContraption renderer : renderers.values()) {
renderer.kinetics.render(renderType, projectionMat, viewMat, renderer::setup); renderer.kinetics.render(layer, projectionMat, viewMat, renderer::setup);
renderer.teardown(); renderer.teardown();
} }
}
ShaderHelper.releaseShader(); layer.endDrawing();
renderType.endDrawing();
GL11.glDisable(GL13.GL_TEXTURE_3D); GL11.glDisable(GL13.GL_TEXTURE_3D);
GL13.glActiveTexture(GL40.GL_TEXTURE0); GL13.glActiveTexture(GL40.GL_TEXTURE0);
} }

View file

@ -25,6 +25,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier; import java.util.function.Supplier;
import static com.simibubi.create.foundation.render.Compartment.PARTIAL; import static com.simibubi.create.foundation.render.Compartment.PARTIAL;
@ -34,33 +35,43 @@ public class RenderMaterial<MODEL extends InstanceBuffer<?>> {
protected final Map<Compartment<?>, Cache<Object, MODEL>> models; protected final Map<Compartment<?>, Cache<Object, MODEL>> models;
protected final ModelFactory<MODEL> factory; protected final ModelFactory<MODEL> factory;
protected final Shader shader; protected final Shader shader;
protected final Predicate<RenderType> layerPredicate;
/**
* Creates a material that renders in the default layer (CUTOUT_MIPPED)
*/
public RenderMaterial(Shader shader, ModelFactory<MODEL> factory) { public RenderMaterial(Shader shader, ModelFactory<MODEL> factory) {
this(shader, factory, type -> type == RenderType.getCutoutMipped());
}
public RenderMaterial(Shader shader, ModelFactory<MODEL> factory, Predicate<RenderType> layerPredicate) {
this.models = new HashMap<>(); this.models = new HashMap<>();
this.factory = factory; this.factory = factory;
this.shader = shader; this.shader = shader;
this.layerPredicate = layerPredicate;
registerCompartment(Compartment.PARTIAL); registerCompartment(Compartment.PARTIAL);
registerCompartment(Compartment.DIRECTIONAL_PARTIAL); registerCompartment(Compartment.DIRECTIONAL_PARTIAL);
registerCompartment(KineticTileEntityRenderer.KINETIC_TILE); registerCompartment(KineticTileEntityRenderer.KINETIC_TILE);
} }
public void render(Matrix4f projection, Matrix4f view) { public boolean canRenderInLayer(RenderType layer) {
render(projection, view, null); return layerPredicate.test(layer);
} }
public void render(Matrix4f projection, Matrix4f view, ShaderCallback setup) { public void render(RenderType layer, Matrix4f projection, Matrix4f view) {
int handle = setupShader(projection, view); render(layer, projection, view, null);
if (setup != null) setup.call(handle); }
public void render(RenderType layer, Matrix4f projection, Matrix4f view, ShaderCallback setup) {
ShaderCallback cb = ShaderHelper.getViewProjectionCallback(projection, view);
if (setup != null) cb = cb.andThen(setup);
ShaderHelper.useShader(shader, cb);
makeRenderCalls(); makeRenderCalls();
teardown(); teardown();
} }
protected int setupShader(Matrix4f projection, Matrix4f view) {
ShaderCallback callback = ShaderHelper.getViewProjectionCallback(projection, view);
return ShaderHelper.useShader(shader, callback);
}
public void teardown() {} public void teardown() {}
public void delete() { public void delete() {

View file

@ -9,6 +9,7 @@ import org.lwjgl.opengl.*;
import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.MemoryUtil;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicBoolean;
// TODO: Don't immediately destroy light volumes. // TODO: Don't immediately destroy light volumes.
// There's a high chance that a contraption will stop and soon after start again. // There's a high chance that a contraption will stop and soon after start again.
@ -20,7 +21,8 @@ public class LightVolume {
private final GridAlignedBB textureVolume; private final GridAlignedBB textureVolume;
private ByteBuffer lightData; private ByteBuffer lightData;
private boolean bufferDirty; private final AtomicBoolean bufferDirty = new AtomicBoolean(false);
private boolean removed;
private int glTexture; private int glTexture;
@ -108,7 +110,7 @@ public class LightVolume {
writeLight(x - shiftX, y - shiftY, z - shiftZ, blockLight, skyLight); writeLight(x - shiftX, y - shiftY, z - shiftZ, blockLight, skyLight);
}); });
bufferDirty = true; bufferDirty.set(true);
} }
/** /**
@ -130,7 +132,7 @@ public class LightVolume {
writeBlock(x - xShift, y - yShift, z - zShift, light); writeBlock(x - xShift, y - yShift, z - zShift, light);
}); });
bufferDirty = true; bufferDirty.set(true);
} }
/** /**
@ -152,12 +154,12 @@ public class LightVolume {
writeSky(x - xShift, y - yShift, z - zShift, light); writeSky(x - xShift, y - yShift, z - zShift, light);
}); });
bufferDirty = true; bufferDirty.set(true);
} }
public void use() { public void use() {
// just in case something goes wrong or we accidentally call this before this volume is properly disposed of. // just in case something goes wrong or we accidentally call this before this volume is properly disposed of.
if (glTexture == 0 || lightData == null) return; if (glTexture == 0 || lightData == null || removed) return;
GL13.glActiveTexture(GL40.GL_TEXTURE4); GL13.glActiveTexture(GL40.GL_TEXTURE4);
GL12.glBindTexture(GL12.GL_TEXTURE_3D, glTexture); GL12.glBindTexture(GL12.GL_TEXTURE_3D, glTexture);
@ -166,9 +168,9 @@ public class LightVolume {
GL11.glTexParameteri(GL13.GL_TEXTURE_3D, GL13.GL_TEXTURE_WRAP_S, GL20.GL_MIRRORED_REPEAT); GL11.glTexParameteri(GL13.GL_TEXTURE_3D, GL13.GL_TEXTURE_WRAP_S, GL20.GL_MIRRORED_REPEAT);
GL11.glTexParameteri(GL13.GL_TEXTURE_3D, GL13.GL_TEXTURE_WRAP_R, GL20.GL_MIRRORED_REPEAT); GL11.glTexParameteri(GL13.GL_TEXTURE_3D, GL13.GL_TEXTURE_WRAP_R, GL20.GL_MIRRORED_REPEAT);
GL11.glTexParameteri(GL13.GL_TEXTURE_3D, GL13.GL_TEXTURE_WRAP_T, GL20.GL_MIRRORED_REPEAT); GL11.glTexParameteri(GL13.GL_TEXTURE_3D, GL13.GL_TEXTURE_WRAP_T, GL20.GL_MIRRORED_REPEAT);
if (bufferDirty) { if (bufferDirty.get()) {
GL12.glTexImage3D(GL12.GL_TEXTURE_3D, 0, GL40.GL_RG8, textureVolume.sizeX(), textureVolume.sizeY(), textureVolume.sizeZ(), 0, GL40.GL_RG, GL40.GL_UNSIGNED_BYTE, lightData); GL12.glTexImage3D(GL12.GL_TEXTURE_3D, 0, GL40.GL_RG8, textureVolume.sizeX(), textureVolume.sizeY(), textureVolume.sizeZ(), 0, GL40.GL_RG, GL40.GL_UNSIGNED_BYTE, lightData);
bufferDirty = false; bufferDirty.set(false);
} }
} }
@ -177,6 +179,7 @@ public class LightVolume {
} }
public void delete() { public void delete() {
removed = true;
RenderWork.enqueue(() -> { RenderWork.enqueue(() -> {
GL15.glDeleteTextures(glTexture); GL15.glDeleteTextures(glTexture);
glTexture = 0; glTexture = 0;

View file

@ -7,4 +7,11 @@ package com.simibubi.create.foundation.render.shader;
public interface ShaderCallback { public interface ShaderCallback {
void call(int shader); void call(int shader);
default ShaderCallback andThen(ShaderCallback other) {
return i -> {
call(i);
other.call(i);
};
}
} }

View file

@ -42,9 +42,17 @@ float diffuse(vec3 normal) {
void main() { void main() {
vec4 worldPos = model * vec4(aPos, 1); vec4 worldPos = model * vec4(aPos, 1);
vec3 norm = (model * vec4(aNormal, 0.)).xyz;
BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize; BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize;
Diffuse = diffuse((model * vec4(aNormal, 0.)).xyz); Diffuse = diffuse(norm);
Color = aColor / diffuse(aNormal); Color = aColor / diffuse(aNormal);
TexCoords = aTexCoords; TexCoords = aTexCoords;
gl_Position = projection * view * worldPos; gl_Position = projection * view * worldPos;
if (debug == 2) {
Color = vec4(norm, 1);
} else {
Color = aColor / diffuse(aNormal);
}
} }

View file

@ -46,7 +46,7 @@ mat4 rotation(vec3 rot) {
} }
mat4 kineticRotation() { mat4 kineticRotation() {
const float speed = 20; const float speed = -20;
float degrees = rotationOffset + time * speed * -3./10.; float degrees = rotationOffset + time * speed * -3./10.;
float angle = fract(degrees / 360.) * PI * 2.; float angle = fract(degrees / 360.) * PI * 2.;
@ -61,18 +61,26 @@ float diffuse(vec3 normal) {
} }
void main() { void main() {
mat4 kineticRotation = kineticRotation();
vec4 localPos = kineticRotation * vec4(aPos - rotationCenter, 1) + vec4(rotationCenter, 0);
//localPos = vec4(localPos.xyz + instancePos, 1);
vec3 rot = fract(localRotation / 360.) * PI * 2.; vec3 rot = fract(localRotation / 360.) * PI * 2.;
mat4 localRot = rotation(rot); mat4 localRot = rotation(rot);
vec4 localPos = localRot * vec4(aPos - 0.5, 1f) + vec4(0.5, 0.5, 0.5, 0); localPos = localRot * vec4(localPos.xyz - 0.5, 1f) + vec4(instancePos + 0.5, 0);
mat4 kineticRotation = kineticRotation();
localPos = kineticRotation * vec4(localPos.xyz - rotationCenter, 1) + vec4(instancePos + rotationCenter, 0);
vec4 worldPos = model * localPos; vec4 worldPos = model * localPos;
vec3 norm = normalize(model * localRot * kineticRotation * vec4(aNormal, 0.)).xyz;
BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize; BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize;
Diffuse = diffuse(normalize(model * localRot * kineticRotation * vec4(aNormal, 0.)).xyz); Diffuse = diffuse(norm);
Color = vec4(1.);
TexCoords = aTexCoords; TexCoords = aTexCoords;
gl_Position = projection * view * worldPos; gl_Position = projection * view * worldPos;
if (debug == 2) {
Color = vec4(norm, 1);
} else {
Color = vec4(1.);
}
} }

View file

@ -65,9 +65,16 @@ void main() {
float scrollSize = scrollTexture.w - scrollTexture.y; float scrollSize = scrollTexture.w - scrollTexture.y;
float scroll = fract(speed * time / (36 * 16.)) * scrollSize * scrollMult; float scroll = fract(speed * time / (36 * 16.)) * scrollSize * scrollMult;
vec3 norm = normalize(model * localRotation * vec4(aNormal, 0.)).xyz;
BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize; BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize;
Diffuse = diffuse(normalize(model * localRotation * vec4(aNormal, 0.)).xyz); Diffuse = diffuse(norm);
Color = vec4(1.);
TexCoords = aTexCoords - sourceUV + scrollTexture.xy + vec2(0., scroll); TexCoords = aTexCoords - sourceUV + scrollTexture.xy + vec2(0., scroll);
gl_Position = projection * view * worldPos; gl_Position = projection * view * worldPos;
if (debug == 2) {
Color = vec4(norm, 1);
} else {
Color = vec4(1.);
}
} }

View file

@ -57,9 +57,16 @@ void main() {
vec4 worldPos = model * localPos; vec4 worldPos = model * localPos;
vec3 norm = normalize(model * kineticRotation * vec4(aNormal, 0.)).xyz;
BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize; BoxCoord = (worldPos.xyz - lightBoxMin) / lightBoxSize;
Diffuse = diffuse(normalize(model * kineticRotation * vec4(aNormal, 0.)).xyz); Diffuse = diffuse(norm);
Color = vec4(1.);
TexCoords = aTexCoords; TexCoords = aTexCoords;
gl_Position = projection * view * worldPos; gl_Position = projection * view * worldPos;
if (debug == 2) {
Color = vec4(norm, 1);
} else {
Color = vec4(1.);
}
} }