fix #1 finally

start work on shader abstraction
use backend for ebos
fix some issues with ghost instances, more work to be done
This commit is contained in:
JozsefA 2021-02-01 16:16:35 -08:00
parent f6b68acbd5
commit f319dd5e8d
21 changed files with 325 additions and 81 deletions

View File

@ -471,6 +471,19 @@ public abstract class KineticTileEntity extends SmartTileEntity
return 16384.0D; // TODO: make this a config option
}
@Override
public void onLoad() {
super.onLoad();
if (world != null && world.isRemote)
CreateClient.kineticRenderer.add(this);
}
@Override
public void onChunkUnloaded() {
if (world != null && world.isRemote)
CreateClient.kineticRenderer.remove(this);
}
@Override
public void requestModelDataUpdate() {
super.requestModelDataUpdate();

View File

@ -478,6 +478,11 @@ public class BeltTileEntity extends KineticTileEntity {
updateLight();
}
@Override
public boolean shouldRenderAsTE() {
return isController();
}
private void updateLight() {
skyLight = (byte) world.getLightLevel(LightType.SKY, pos);
blockLight = (byte) world.getLightLevel(LightType.BLOCK, pos);

View File

@ -1,5 +1,6 @@
package com.simibubi.create.foundation.mixin;
import com.simibubi.create.CreateClient;
import com.simibubi.create.foundation.render.FastRenderDispatcher;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
@ -27,6 +28,6 @@ public class OnRemoveTileMixin {
*/
@Inject(at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/World;getTileEntity(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/tileentity/TileEntity;"), method = "removeTileEntity", locals = LocalCapture.CAPTURE_FAILHARD)
private void onRemoveTile(BlockPos pos, CallbackInfo ci, TileEntity te) {
if (isRemote) FastRenderDispatcher.enqueueRemove(te);
if (isRemote) CreateClient.kineticRenderer.remove(te);
}
}

View File

@ -35,8 +35,7 @@ import java.util.function.Consumer;
public class FastRenderDispatcher {
public static WorldAttached<ConcurrentHashMap.KeySetView<TileEntity, Boolean>> queuedUpdates = new WorldAttached<>(ConcurrentHashMap::newKeySet);
public static WorldAttached<ConcurrentHashMap.KeySetView<TileEntity, Boolean>> queuedRemovals = new WorldAttached<>(ConcurrentHashMap::newKeySet);
public static WorldAttached<ConcurrentHashMap.KeySetView<TileEntityInstance<?>, Boolean>> addedLastTick = new WorldAttached<>(ConcurrentHashMap::newKeySet);
public static WorldAttached<ConcurrentHashMap.KeySetView<TileEntity, Boolean>> addedLastTick = new WorldAttached<>(ConcurrentHashMap::newKeySet);
private static Matrix4f projectionMatrixThisFrame = null;
@ -48,15 +47,10 @@ public class FastRenderDispatcher {
queuedUpdates.get(te.getWorld()).add(te);
}
public static void enqueueRemove(TileEntity te) {
queuedRemovals.get(te.getWorld()).add(te);
}
public static void tick() {
ClientWorld world = Minecraft.getInstance().world;
runQueue(addedLastTick.get(world), TileEntityInstance::updateLight);
runQueue(queuedRemovals.get(world), CreateClient.kineticRenderer::remove);
runQueue(addedLastTick.get(world), CreateClient.kineticRenderer::onLightUpdate);
CreateClient.kineticRenderer.clean();
runQueue(queuedUpdates.get(world), CreateClient.kineticRenderer::update);

View File

@ -1,6 +1,6 @@
package com.simibubi.create.foundation.render;
import com.simibubi.create.foundation.render.gl.shader.Shader;
import com.simibubi.create.foundation.render.gl.shader.AllShaderPrograms;
import com.simibubi.create.foundation.render.gl.shader.ShaderCallback;
import com.simibubi.create.foundation.render.gl.shader.ShaderHelper;
import com.simibubi.create.foundation.render.instancing.*;
@ -11,9 +11,7 @@ import net.minecraft.tileentity.TileEntity;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class InstancedTileRenderer {
protected Map<TileEntity, TileEntityInstance<?>> renderers = new HashMap<>();
@ -25,8 +23,8 @@ public class InstancedTileRenderer {
}
public void registerMaterials() {
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(Shader.BELT, BeltModel::new));
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(Shader.ROTATING, RotatingModel::new));
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(AllShaderPrograms.BELT, BeltModel::new));
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(AllShaderPrograms.ROTATING, RotatingModel::new));
}
@SuppressWarnings("unchecked")
@ -42,13 +40,15 @@ public class InstancedTileRenderer {
@SuppressWarnings("unchecked")
@Nullable
public <T extends TileEntity> TileEntityInstance<? super T> getInstance(T tile, boolean create) {
if (renderers.containsKey(tile)) {
return (TileEntityInstance<? super T>) renderers.get(tile);
TileEntityInstance<?> instance = renderers.get(tile);
if (instance != null) {
return (TileEntityInstance<? super T>) instance;
} else if (create) {
TileEntityInstance<? super T> renderer = InstancedTileRenderRegistry.instance.create(this, tile);
if (renderer != null) {
FastRenderDispatcher.addedLastTick.get(tile.getWorld()).add(renderer);
FastRenderDispatcher.addedLastTick.get(tile.getWorld()).add(tile);
renderers.put(tile, renderer);
}
@ -60,16 +60,22 @@ public class InstancedTileRenderer {
public <T extends TileEntity> void onLightUpdate(T tile) {
if (tile instanceof IInstanceRendered) {
TileEntityInstance<? super T> instance = getInstance(tile);
TileEntityInstance<? super T> instance = getInstance(tile, false);
if (instance != null)
instance.updateLight();
}
}
public <T extends TileEntity> void add(T tile) {
if (tile instanceof IInstanceRendered) {
getInstance(tile);
}
}
public <T extends TileEntity> void update(T tile) {
if (tile instanceof IInstanceRendered) {
TileEntityInstance<? super T> instance = getInstance(tile);
TileEntityInstance<? super T> instance = getInstance(tile, false);
if (instance != null)
instance.update();
@ -91,8 +97,7 @@ public class InstancedTileRenderer {
// Clean up twice a second. This doesn't have to happen every tick,
// but this does need to be run to ensure we don't miss anything.
if (AnimationTickHolder.ticks % 10 == 0) {
List<TileEntity> removed = renderers.keySet().stream().filter(TileEntity::isRemoved).collect(Collectors.toList());
removed.forEach(renderers::remove);
renderers.keySet().stream().filter(TileEntity::isRemoved).forEach(renderers::remove);
}
}

View File

@ -2,6 +2,7 @@ package com.simibubi.create.foundation.render;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.datafixers.util.Pair;
import com.simibubi.create.foundation.render.gl.Backend;
import com.simibubi.create.foundation.render.gl.GlBuffer;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
@ -41,15 +42,11 @@ public class TemplateBuffer {
ebo.bind(GL15.GL_ELEMENT_ARRAY_BUFFER);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesSize, GL15.GL_STATIC_DRAW);
ByteBuffer indices = GL15.glMapBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, GL15.GL_WRITE_ONLY);
Backend.MAP_BUFFER.mapBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesSize, indices -> {
for (int i = 0; i < vertexCount; i++) {
indices.putShort((short) i);
}
indices.rewind();
GL15.glUnmapBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER);
});
ebo.unbind(GL15.GL_ELEMENT_ARRAY_BUFFER);

View File

@ -1,7 +1,7 @@
package com.simibubi.create.foundation.render.contraption;
import com.simibubi.create.foundation.render.InstancedTileRenderer;
import com.simibubi.create.foundation.render.gl.shader.Shader;
import com.simibubi.create.foundation.render.gl.shader.AllShaderPrograms;
import com.simibubi.create.foundation.render.instancing.BeltModel;
import com.simibubi.create.foundation.render.instancing.KineticRenderMaterials;
import com.simibubi.create.foundation.render.instancing.RenderMaterial;
@ -12,8 +12,8 @@ public class ContraptionKineticRenderer extends InstancedTileRenderer {
@Override
public void registerMaterials() {
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(Shader.CONTRAPTION_BELT, BeltModel::new));
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(Shader.CONTRAPTION_ROTATING, RotatingModel::new));
materials.put(KineticRenderMaterials.ACTORS, new RenderMaterial<>(Shader.CONTRAPTION_ACTOR, RotatingActorModel::new));
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(AllShaderPrograms.CONTRAPTION_BELT, BeltModel::new));
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(AllShaderPrograms.CONTRAPTION_ROTATING, RotatingModel::new));
materials.put(KineticRenderMaterials.ACTORS, new RenderMaterial<>(AllShaderPrograms.CONTRAPTION_ACTOR, RotatingActorModel::new));
}
}

View File

@ -5,7 +5,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Abs
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntityRenderer;
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionHandler;
import com.simibubi.create.foundation.render.gl.shader.Shader;
import com.simibubi.create.foundation.render.gl.shader.AllShaderPrograms;
import com.simibubi.create.foundation.render.gl.shader.ShaderCallback;
import com.simibubi.create.foundation.render.gl.shader.ShaderHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
@ -97,7 +97,7 @@ public class ContraptionRenderDispatcher {
ShaderCallback callback = ShaderHelper.getViewProjectionCallback(projectionMat, viewMat);
int structureShader = ShaderHelper.useShader(Shader.CONTRAPTION_STRUCTURE, callback);
int structureShader = ShaderHelper.useShader(AllShaderPrograms.CONTRAPTION_STRUCTURE, callback);
for (RenderedContraption renderer : renderers.values()) {
renderer.doRenderLayer(layer, structureShader);
}

View File

@ -0,0 +1,37 @@
package com.simibubi.create.foundation.render.gl;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@OnlyIn(Dist.CLIENT)
public enum GlPrimitiveType {
FLOAT(4, "Float", 5126),
UBYTE(1, "Unsigned Byte", 5121),
BYTE(1, "Byte", 5120),
USHORT(2, "Unsigned Short", 5123),
SHORT(2, "Short", 5122),
UINT(4, "Unsigned Int", 5125),
INT(4, "Int", 5124);
private final int size;
private final String displayName;
private final int glConstant;
private GlPrimitiveType(int p_i46095_3_, String p_i46095_4_, int p_i46095_5_) {
this.size = p_i46095_3_;
this.displayName = p_i46095_4_;
this.glConstant = p_i46095_5_;
}
public int getSize() {
return this.size;
}
public String getDisplayName() {
return this.displayName;
}
public int getGlConstant() {
return this.glConstant;
}
}

View File

@ -0,0 +1,55 @@
package com.simibubi.create.foundation.render.gl.shader;
import com.simibubi.create.Create;
import net.minecraft.util.ResourceLocation;
public enum AllShaderPrograms {
ROTATING("shader/rotating.vert", "shader/instanced.frag"),
BELT("shader/belt.vert", "shader/instanced.frag"),
CONTRAPTION_STRUCTURE("shader/contraption_structure.vert", "shader/contraption_structure.frag"),
CONTRAPTION_ROTATING("shader/contraption_rotating.vert", "shader/contraption.frag"),
CONTRAPTION_BELT("shader/contraption_belt.vert", "shader/contraption.frag"),
CONTRAPTION_ACTOR("shader/contraption_actor.vert", "shader/contraption.frag"),
;
public final String vert;
public final String frag;
AllShaderPrograms(String vert, String frag) {
this.vert = vert;
this.frag = frag;
}
}
//public class AllShaderPrograms {
// public static final ProgramBuilder ROTATING = new ProgramBuilder(name("rotating"))
// .vert(vert("rotating"))
// .frag(frag("instanced"));
// public static final ProgramBuilder BELT = new ProgramBuilder(name("belt"))
// .vert(vert("belt"))
// .frag(frag("instanced"));
// public static final ProgramBuilder CONTRAPTION_STRUCTURE = new ProgramBuilder(name("contraption_structure"))
// .vert(vert("contraption_structure"))
// .frag(frag("contraption_structure"));
// public static final ProgramBuilder CONTRAPTION_ROTATING = new ProgramBuilder(name("contraption_rotating"))
// .vert(vert("contraption_rotating"))
// .frag(frag("contraption"));
// public static final ProgramBuilder CONTRAPTION_BELT = new ProgramBuilder(name("contraption_belt"))
// .vert(vert("contraption_belt"))
// .frag(frag("contraption"));
// public static final ProgramBuilder CONTRAPTION_ACTOR = new ProgramBuilder(name("contraption_actor"))
// .vert(vert("contraption_actor"))
// .frag(frag("contraption"));
//
// private static ResourceLocation vert(String file) {
// return new ResourceLocation(Create.ID, "shader/" + file + ".vert");
// }
//
// private static ResourceLocation frag(String file) {
// return new ResourceLocation(Create.ID, "shader/" + file + ".vert");
// }
//
// private static ResourceLocation name(String name) {
// return new ResourceLocation(Create.ID, name);
// }
//}

View File

@ -0,0 +1,45 @@
package com.simibubi.create.foundation.render.gl.shader;
import com.simibubi.create.foundation.render.gl.GlPrimitiveType;
public class GLSLType {
public static final GLSLType FLOAT = new GLSLType("mat4", GlPrimitiveType.FLOAT, 16);
public static final GLSLType VEC2 = new GLSLType("vec4", GlPrimitiveType.FLOAT, 4);
public static final GLSLType VEC3 = new GLSLType("vec3", GlPrimitiveType.FLOAT, 3);
public static final GLSLType VEC4 = new GLSLType("vec2", GlPrimitiveType.FLOAT, 2);
public static final GLSLType MAT4 = new GLSLType("float", GlPrimitiveType.FLOAT, 1);
private final String symbol;
private final GlPrimitiveType base;
private final int count;
private final int size;
private final int attributeCount;
public GLSLType(String symbol, GlPrimitiveType base, int count) {
this.symbol = symbol;
this.base = base;
this.count = count;
this.size = base.getSize() * count;
this.attributeCount = (this.size + 15) / 16; // ceiling division. GLSL vertex attributes can only be 16 bytes wide
}
public String getSymbol() {
return symbol;
}
public GlPrimitiveType getBase() {
return base;
}
public int getCount() {
return count;
}
public int getSize() {
return size;
}
public int getAttributeCount() {
return attributeCount;
}
}

View File

@ -0,0 +1,49 @@
package com.simibubi.create.foundation.render.gl.shader;
import net.minecraft.util.ResourceLocation;
import java.util.EnumMap;
import java.util.Map;
public class ProgramBuilder {
private final ResourceLocation name;
private final Map<ShaderType, ResourceLocation> shaders;
private ShaderConstants constants;
public ProgramBuilder(ResourceLocation name) {
this.name = name;
shaders = new EnumMap<>(ShaderType.class);
}
public ResourceLocation getName() {
return name;
}
public Map<ShaderType, ResourceLocation> getShaders() {
return shaders;
}
public ShaderConstants getConstants() {
return constants;
}
public ProgramBuilder setConstants(ShaderConstants constants) {
this.constants = constants;
return this;
}
public ProgramBuilder vert(ResourceLocation file) {
return shader(ShaderType.VERTEX, file);
}
public ProgramBuilder frag(ResourceLocation file) {
return shader(ShaderType.FRAGMENT, file);
}
public ProgramBuilder shader(ShaderType type, ResourceLocation file) {
shaders.put(type, file);
return this;
}
}

View File

@ -1,19 +0,0 @@
package com.simibubi.create.foundation.render.gl.shader;
public enum Shader {
ROTATING("shader/rotating.vert", "shader/instanced.frag"),
BELT("shader/belt.vert", "shader/instanced.frag"),
CONTRAPTION_STRUCTURE("shader/contraption_structure.vert", "shader/contraption_structure.frag"),
CONTRAPTION_ROTATING("shader/contraption_rotating.vert", "shader/contraption.frag"),
CONTRAPTION_BELT("shader/contraption_belt.vert", "shader/contraption.frag"),
CONTRAPTION_ACTOR("shader/contraption_actor.vert", "shader/contraption.frag"),
;
public final String vert;
public final String frag;
Shader(String vert, String frag) {
this.vert = vert;
this.frag = frag;
}
}

View File

@ -0,0 +1,21 @@
package com.simibubi.create.foundation.render.gl.shader;
import java.util.ArrayList;
public class ShaderConstants {
private final ArrayList<String> defines;
public ShaderConstants() {
defines = new ArrayList<>();
}
public ShaderConstants define(String def) {
defines.add(def);
return this;
}
public ArrayList<String> getDefines() {
return defines;
}
}

View File

@ -34,7 +34,7 @@ public class ShaderHelper {
public static final FloatBuffer VEC3_BUFFER = MemoryUtil.memAllocFloat(3);
public static final FloatBuffer MATRIX_BUFFER = MemoryUtil.memAllocFloat(16);
private static final Map<Shader, ShaderProgram> PROGRAMS = new EnumMap<>(Shader.class);
private static final Map<AllShaderPrograms, ShaderProgram> PROGRAMS = new EnumMap<>(AllShaderPrograms.class);
@SuppressWarnings("deprecation")
public static void initShaders() {
@ -46,7 +46,7 @@ public class ShaderHelper {
if (predicate.test(VanillaResourceType.SHADERS)) {
PROGRAMS.values().forEach(ShaderLinkHelper::deleteShader);
PROGRAMS.clear();
for (Shader shader : Shader.values()) {
for (AllShaderPrograms shader : AllShaderPrograms.values()) {
createProgram(manager, shader);
}
}
@ -54,7 +54,7 @@ public class ShaderHelper {
}
}
public static int getShaderHandle(Shader shader) {
public static int getShaderHandle(AllShaderPrograms shader) {
ShaderProgram shaderProgram = PROGRAMS.get(shader);
return shaderProgram.getProgram();
@ -74,11 +74,11 @@ public class ShaderHelper {
};
}
public static int useShader(Shader shader) {
public static int useShader(AllShaderPrograms shader) {
return useShader(shader, null);
}
public static int useShader(Shader shader, @Nullable ShaderCallback cb) {
public static int useShader(AllShaderPrograms shader, @Nullable ShaderCallback cb) {
ShaderProgram prog = PROGRAMS.get(shader);
if (prog == null) {
return -1;
@ -109,7 +109,7 @@ public class ShaderHelper {
ShaderLinkHelper.useProgram(0);
}
private static void createProgram(IResourceManager manager, Shader shader) {
private static void createProgram(IResourceManager manager, AllShaderPrograms shader) {
try {
ShaderLoader vert = createShader(manager, shader.vert, ShaderLoader.ShaderType.VERTEX);
ShaderLoader frag = createShader(manager, shader.frag, ShaderLoader.ShaderType.FRAGMENT);

View File

@ -0,0 +1,6 @@
package com.simibubi.create.foundation.render.gl.shader;
public enum ShaderType {
VERTEX,
FRAGMENT,
}

View File

@ -0,0 +1,13 @@
package com.simibubi.create.foundation.render.gl.shader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class ShaderUniforms {
private final Map<String, GLSLType> uniforms;
public ShaderUniforms() {
this.uniforms = new HashMap<>();
}
}

View File

@ -1,6 +1,7 @@
package com.simibubi.create.foundation.render.instancing;
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
import com.simibubi.create.foundation.render.gl.GlPrimitiveType;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
@ -10,7 +11,7 @@ import static com.simibubi.create.foundation.render.instancing.VertexAttribute.*
public class BeltData extends KineticData<BeltData> {
public static final VertexAttribute TARGET_UV = copy("scrollTexture", VEC4);
public static final VertexAttribute SCROLL_MULT = new VertexAttribute("scrollMult", VertexFormatElement.Type.BYTE, 1, true);
public static final VertexAttribute SCROLL_MULT = new VertexAttribute("scrollMult", GlPrimitiveType.BYTE, 1, true);
public static VertexFormat FORMAT = new VertexFormat(KineticData.FORMAT, ROTATION, UV, TARGET_UV, SCROLL_MULT);

View File

@ -7,7 +7,7 @@ import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.foundation.render.Compartment;
import com.simibubi.create.foundation.render.SuperByteBufferCache;
import com.simibubi.create.foundation.render.gl.shader.Shader;
import com.simibubi.create.foundation.render.gl.shader.AllShaderPrograms;
import com.simibubi.create.foundation.render.gl.shader.ShaderCallback;
import com.simibubi.create.foundation.render.gl.shader.ShaderHelper;
import net.minecraft.block.BlockState;
@ -33,17 +33,17 @@ public class RenderMaterial<MODEL extends InstancedModel<?>> {
protected final Map<Compartment<?>, Cache<Object, MODEL>> models;
protected final ModelFactory<MODEL> factory;
protected final Shader shader;
protected final AllShaderPrograms 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(AllShaderPrograms shader, ModelFactory<MODEL> factory) {
this(shader, factory, type -> type == RenderType.getCutoutMipped());
}
public RenderMaterial(Shader shader, ModelFactory<MODEL> factory, Predicate<RenderType> layerPredicate) {
public RenderMaterial(AllShaderPrograms shader, ModelFactory<MODEL> factory, Predicate<RenderType> layerPredicate) {
this.models = new HashMap<>();
this.factory = factory;
this.shader = shader;

View File

@ -1,26 +1,26 @@
package com.simibubi.create.foundation.render.instancing;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
import com.simibubi.create.foundation.render.gl.GlPrimitiveType;
import org.lwjgl.opengl.GL20;
public class VertexAttribute {
public static final VertexAttribute MAT4 = new VertexAttribute("mat4", VertexFormatElement.Type.FLOAT, 16);
public static final VertexAttribute VEC4 = new VertexAttribute("vec4", VertexFormatElement.Type.FLOAT, 4);
public static final VertexAttribute VEC3 = new VertexAttribute("vec3", VertexFormatElement.Type.FLOAT, 3);
public static final VertexAttribute VEC2 = new VertexAttribute("vec2", VertexFormatElement.Type.FLOAT, 2);
public static final VertexAttribute FLOAT = new VertexAttribute("float", VertexFormatElement.Type.FLOAT, 1);
public static final VertexAttribute MAT4 = new VertexAttribute("mat4", GlPrimitiveType.FLOAT, 16);
public static final VertexAttribute VEC4 = new VertexAttribute("vec4", GlPrimitiveType.FLOAT, 4);
public static final VertexAttribute VEC3 = new VertexAttribute("vec3", GlPrimitiveType.FLOAT, 3);
public static final VertexAttribute VEC2 = new VertexAttribute("vec2", GlPrimitiveType.FLOAT, 2);
public static final VertexAttribute FLOAT = new VertexAttribute("float", GlPrimitiveType.FLOAT, 1);
public static final VertexAttribute POSITION = copy("pos", VEC3);
public static final VertexAttribute INSTANCE_POSITION = copy("instancePos", VEC3);
public static final VertexAttribute ROTATION = copy("eulerAngles", VEC3);
public static final VertexAttribute NORMAL = new VertexAttribute("normal", VertexFormatElement.Type.BYTE, 3, true);
public static final VertexAttribute RGBA = new VertexAttribute("rgba", VertexFormatElement.Type.UBYTE, 4, true);
public static final VertexAttribute RGB = new VertexAttribute("rgb", VertexFormatElement.Type.UBYTE, 3, true);
public static final VertexAttribute NORMAL = new VertexAttribute("normal", GlPrimitiveType.BYTE, 3, true);
public static final VertexAttribute RGBA = new VertexAttribute("rgba", GlPrimitiveType.UBYTE, 4, true);
public static final VertexAttribute RGB = new VertexAttribute("rgb", GlPrimitiveType.UBYTE, 3, true);
public static final VertexAttribute UV = copy("uv", VEC2);
public static final VertexAttribute LIGHT = new VertexAttribute("light", VertexFormatElement.Type.UBYTE, 2, true);
public static final VertexAttribute LIGHT = new VertexAttribute("light", GlPrimitiveType.UBYTE, 2, true);
private final String name;
private final VertexFormatElement.Type type;
private final GlPrimitiveType type;
private final int count;
private final int size;
private final int attributeCount;
@ -39,11 +39,11 @@ public class VertexAttribute {
this.normalized = that.normalized;
}
public VertexAttribute(String name, VertexFormatElement.Type type, int count) {
public VertexAttribute(String name, GlPrimitiveType type, int count) {
this(name, type, count, false);
}
public VertexAttribute(String name, VertexFormatElement.Type type, int count, boolean normalized) {
public VertexAttribute(String name, GlPrimitiveType type, int count, boolean normalized) {
this.name = name;
this.type = type;
this.count = count;

View File

@ -2,6 +2,7 @@ package com.simibubi.create.foundation.render.light;
import com.simibubi.create.foundation.render.RenderWork;
import com.simibubi.create.foundation.render.gl.GlTexture;
import com.simibubi.create.foundation.render.gl.shader.ShaderHelper;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.SectionPos;
import net.minecraft.world.ILightReader;
@ -26,7 +27,19 @@ public class LightVolume {
setSampleVolume(sampleVolume);
this.glTexture = new GlTexture(GL20.GL_TEXTURE_3D);
this.lightData = MemoryUtil.memAlloc(this.textureVolume.volume() * 2);
this.lightData = MemoryUtil.memAlloc(this.textureVolume.volume() * 2); // TODO: reduce this to span only sampleVolume
// allocate space for the texture
GL20.glActiveTexture(GL20.GL_TEXTURE4);
glTexture.bind();
int sizeX = textureVolume.sizeX();
int sizeY = textureVolume.sizeY();
int sizeZ = textureVolume.sizeZ();
GL12.glTexImage3D(GL12.GL_TEXTURE_3D, 0, GL40.GL_RG8, sizeX, sizeY, sizeZ, 0, GL40.GL_RG, GL40.GL_UNSIGNED_BYTE, 0);
glTexture.unbind();
GL20.glActiveTexture(GL20.GL_TEXTURE0);
}
private void setSampleVolume(GridAlignedBB sampleVolume) {
@ -217,11 +230,19 @@ public class LightVolume {
private void uploadTexture() {
if (bufferDirty) {
GL20.glPixelStorei(GL20.GL_UNPACK_ROW_LENGTH, 0);
GL20.glPixelStorei(GL20.GL_UNPACK_SKIP_PIXELS, 0);
GL20.glPixelStorei(GL20.GL_UNPACK_SKIP_ROWS, 0);
GL20.glPixelStorei(GL20.GL_UNPACK_SKIP_IMAGES, 0);
GL20.glPixelStorei(GL20.GL_UNPACK_IMAGE_HEIGHT, 0);
GL20.glPixelStorei(GL20.GL_UNPACK_ALIGNMENT, 2);
int sizeX = textureVolume.sizeX();
int sizeY = textureVolume.sizeY();
int sizeZ = textureVolume.sizeZ();
GL12.glTexImage3D(GL12.GL_TEXTURE_3D, 0, GL40.GL_RG8, sizeX, sizeY, sizeZ, 0, GL40.GL_RG, GL40.GL_UNSIGNED_BYTE, lightData);
GL12.glTexSubImage3D(GL12.GL_TEXTURE_3D, 0, 0, 0, 0, sizeX, sizeY, sizeZ, GL40.GL_RG, GL40.GL_UNSIGNED_BYTE, lightData);
GL20.glPixelStorei(GL20.GL_UNPACK_ALIGNMENT, 4); // 4 is the default
bufferDirty = false;
}
}