mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-11-14 14:33:57 +01:00
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:
parent
f6b68acbd5
commit
f319dd5e8d
@ -471,6 +471,19 @@ public abstract class KineticTileEntity extends SmartTileEntity
|
|||||||
return 16384.0D; // TODO: make this a config option
|
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
|
@Override
|
||||||
public void requestModelDataUpdate() {
|
public void requestModelDataUpdate() {
|
||||||
super.requestModelDataUpdate();
|
super.requestModelDataUpdate();
|
||||||
|
@ -478,6 +478,11 @@ public class BeltTileEntity extends KineticTileEntity {
|
|||||||
updateLight();
|
updateLight();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldRenderAsTE() {
|
||||||
|
return isController();
|
||||||
|
}
|
||||||
|
|
||||||
private void updateLight() {
|
private void updateLight() {
|
||||||
skyLight = (byte) world.getLightLevel(LightType.SKY, pos);
|
skyLight = (byte) world.getLightLevel(LightType.SKY, pos);
|
||||||
blockLight = (byte) world.getLightLevel(LightType.BLOCK, pos);
|
blockLight = (byte) world.getLightLevel(LightType.BLOCK, pos);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.simibubi.create.foundation.mixin;
|
package com.simibubi.create.foundation.mixin;
|
||||||
|
|
||||||
|
import com.simibubi.create.CreateClient;
|
||||||
import com.simibubi.create.foundation.render.FastRenderDispatcher;
|
import com.simibubi.create.foundation.render.FastRenderDispatcher;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
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)
|
@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) {
|
private void onRemoveTile(BlockPos pos, CallbackInfo ci, TileEntity te) {
|
||||||
if (isRemote) FastRenderDispatcher.enqueueRemove(te);
|
if (isRemote) CreateClient.kineticRenderer.remove(te);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,8 +35,7 @@ import java.util.function.Consumer;
|
|||||||
public class FastRenderDispatcher {
|
public class FastRenderDispatcher {
|
||||||
|
|
||||||
public static WorldAttached<ConcurrentHashMap.KeySetView<TileEntity, Boolean>> queuedUpdates = new WorldAttached<>(ConcurrentHashMap::newKeySet);
|
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<TileEntity, Boolean>> addedLastTick = new WorldAttached<>(ConcurrentHashMap::newKeySet);
|
||||||
public static WorldAttached<ConcurrentHashMap.KeySetView<TileEntityInstance<?>, Boolean>> addedLastTick = new WorldAttached<>(ConcurrentHashMap::newKeySet);
|
|
||||||
|
|
||||||
private static Matrix4f projectionMatrixThisFrame = null;
|
private static Matrix4f projectionMatrixThisFrame = null;
|
||||||
|
|
||||||
@ -48,15 +47,10 @@ public class FastRenderDispatcher {
|
|||||||
queuedUpdates.get(te.getWorld()).add(te);
|
queuedUpdates.get(te.getWorld()).add(te);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void enqueueRemove(TileEntity te) {
|
|
||||||
queuedRemovals.get(te.getWorld()).add(te);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void tick() {
|
public static void tick() {
|
||||||
ClientWorld world = Minecraft.getInstance().world;
|
ClientWorld world = Minecraft.getInstance().world;
|
||||||
|
|
||||||
runQueue(addedLastTick.get(world), TileEntityInstance::updateLight);
|
runQueue(addedLastTick.get(world), CreateClient.kineticRenderer::onLightUpdate);
|
||||||
runQueue(queuedRemovals.get(world), CreateClient.kineticRenderer::remove);
|
|
||||||
CreateClient.kineticRenderer.clean();
|
CreateClient.kineticRenderer.clean();
|
||||||
|
|
||||||
runQueue(queuedUpdates.get(world), CreateClient.kineticRenderer::update);
|
runQueue(queuedUpdates.get(world), CreateClient.kineticRenderer::update);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package com.simibubi.create.foundation.render;
|
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.ShaderCallback;
|
||||||
import com.simibubi.create.foundation.render.gl.shader.ShaderHelper;
|
import com.simibubi.create.foundation.render.gl.shader.ShaderHelper;
|
||||||
import com.simibubi.create.foundation.render.instancing.*;
|
import com.simibubi.create.foundation.render.instancing.*;
|
||||||
@ -11,9 +11,7 @@ import net.minecraft.tileentity.TileEntity;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class InstancedTileRenderer {
|
public class InstancedTileRenderer {
|
||||||
protected Map<TileEntity, TileEntityInstance<?>> renderers = new HashMap<>();
|
protected Map<TileEntity, TileEntityInstance<?>> renderers = new HashMap<>();
|
||||||
@ -25,8 +23,8 @@ public class InstancedTileRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void registerMaterials() {
|
public void registerMaterials() {
|
||||||
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(Shader.BELT, BeltModel::new));
|
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(AllShaderPrograms.BELT, BeltModel::new));
|
||||||
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(Shader.ROTATING, RotatingModel::new));
|
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(AllShaderPrograms.ROTATING, RotatingModel::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@ -42,13 +40,15 @@ public class InstancedTileRenderer {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Nullable
|
@Nullable
|
||||||
public <T extends TileEntity> TileEntityInstance<? super T> getInstance(T tile, boolean create) {
|
public <T extends TileEntity> TileEntityInstance<? super T> getInstance(T tile, boolean create) {
|
||||||
if (renderers.containsKey(tile)) {
|
TileEntityInstance<?> instance = renderers.get(tile);
|
||||||
return (TileEntityInstance<? super T>) renderers.get(tile);
|
|
||||||
|
if (instance != null) {
|
||||||
|
return (TileEntityInstance<? super T>) instance;
|
||||||
} else if (create) {
|
} else if (create) {
|
||||||
TileEntityInstance<? super T> renderer = InstancedTileRenderRegistry.instance.create(this, tile);
|
TileEntityInstance<? super T> renderer = InstancedTileRenderRegistry.instance.create(this, tile);
|
||||||
|
|
||||||
if (renderer != null) {
|
if (renderer != null) {
|
||||||
FastRenderDispatcher.addedLastTick.get(tile.getWorld()).add(renderer);
|
FastRenderDispatcher.addedLastTick.get(tile.getWorld()).add(tile);
|
||||||
renderers.put(tile, renderer);
|
renderers.put(tile, renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,16 +60,22 @@ public class InstancedTileRenderer {
|
|||||||
|
|
||||||
public <T extends TileEntity> void onLightUpdate(T tile) {
|
public <T extends TileEntity> void onLightUpdate(T tile) {
|
||||||
if (tile instanceof IInstanceRendered) {
|
if (tile instanceof IInstanceRendered) {
|
||||||
TileEntityInstance<? super T> instance = getInstance(tile);
|
TileEntityInstance<? super T> instance = getInstance(tile, false);
|
||||||
|
|
||||||
if (instance != null)
|
if (instance != null)
|
||||||
instance.updateLight();
|
instance.updateLight();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <T extends TileEntity> void add(T tile) {
|
||||||
|
if (tile instanceof IInstanceRendered) {
|
||||||
|
getInstance(tile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public <T extends TileEntity> void update(T tile) {
|
public <T extends TileEntity> void update(T tile) {
|
||||||
if (tile instanceof IInstanceRendered) {
|
if (tile instanceof IInstanceRendered) {
|
||||||
TileEntityInstance<? super T> instance = getInstance(tile);
|
TileEntityInstance<? super T> instance = getInstance(tile, false);
|
||||||
|
|
||||||
if (instance != null)
|
if (instance != null)
|
||||||
instance.update();
|
instance.update();
|
||||||
@ -91,8 +97,7 @@ public class InstancedTileRenderer {
|
|||||||
// Clean up twice a second. This doesn't have to happen every tick,
|
// 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.
|
// but this does need to be run to ensure we don't miss anything.
|
||||||
if (AnimationTickHolder.ticks % 10 == 0) {
|
if (AnimationTickHolder.ticks % 10 == 0) {
|
||||||
List<TileEntity> removed = renderers.keySet().stream().filter(TileEntity::isRemoved).collect(Collectors.toList());
|
renderers.keySet().stream().filter(TileEntity::isRemoved).forEach(renderers::remove);
|
||||||
removed.forEach(renderers::remove);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package com.simibubi.create.foundation.render;
|
|||||||
|
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
|
import com.simibubi.create.foundation.render.gl.Backend;
|
||||||
import com.simibubi.create.foundation.render.gl.GlBuffer;
|
import com.simibubi.create.foundation.render.gl.GlBuffer;
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
import net.minecraft.client.renderer.vertex.VertexFormatElement;
|
import net.minecraft.client.renderer.vertex.VertexFormatElement;
|
||||||
@ -41,15 +42,11 @@ public class TemplateBuffer {
|
|||||||
ebo.bind(GL15.GL_ELEMENT_ARRAY_BUFFER);
|
ebo.bind(GL15.GL_ELEMENT_ARRAY_BUFFER);
|
||||||
|
|
||||||
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesSize, GL15.GL_STATIC_DRAW);
|
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesSize, GL15.GL_STATIC_DRAW);
|
||||||
|
Backend.MAP_BUFFER.mapBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesSize, indices -> {
|
||||||
ByteBuffer indices = GL15.glMapBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, GL15.GL_WRITE_ONLY);
|
|
||||||
|
|
||||||
for (int i = 0; i < vertexCount; i++) {
|
for (int i = 0; i < vertexCount; i++) {
|
||||||
indices.putShort((short) i);
|
indices.putShort((short) i);
|
||||||
}
|
}
|
||||||
indices.rewind();
|
});
|
||||||
|
|
||||||
GL15.glUnmapBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER);
|
|
||||||
|
|
||||||
ebo.unbind(GL15.GL_ELEMENT_ARRAY_BUFFER);
|
ebo.unbind(GL15.GL_ELEMENT_ARRAY_BUFFER);
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package com.simibubi.create.foundation.render.contraption;
|
package com.simibubi.create.foundation.render.contraption;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.render.InstancedTileRenderer;
|
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.BeltModel;
|
||||||
import com.simibubi.create.foundation.render.instancing.KineticRenderMaterials;
|
import com.simibubi.create.foundation.render.instancing.KineticRenderMaterials;
|
||||||
import com.simibubi.create.foundation.render.instancing.RenderMaterial;
|
import com.simibubi.create.foundation.render.instancing.RenderMaterial;
|
||||||
@ -12,8 +12,8 @@ public class ContraptionKineticRenderer extends InstancedTileRenderer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerMaterials() {
|
public void registerMaterials() {
|
||||||
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(Shader.CONTRAPTION_BELT, BeltModel::new));
|
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(AllShaderPrograms.CONTRAPTION_BELT, BeltModel::new));
|
||||||
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(Shader.CONTRAPTION_ROTATING, RotatingModel::new));
|
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(AllShaderPrograms.CONTRAPTION_ROTATING, RotatingModel::new));
|
||||||
materials.put(KineticRenderMaterials.ACTORS, new RenderMaterial<>(Shader.CONTRAPTION_ACTOR, RotatingActorModel::new));
|
materials.put(KineticRenderMaterials.ACTORS, new RenderMaterial<>(AllShaderPrograms.CONTRAPTION_ACTOR, RotatingActorModel::new));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.AbstractContraptionEntityRenderer;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
|
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionHandler;
|
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.ShaderCallback;
|
||||||
import com.simibubi.create.foundation.render.gl.shader.ShaderHelper;
|
import com.simibubi.create.foundation.render.gl.shader.ShaderHelper;
|
||||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||||
@ -97,7 +97,7 @@ public class ContraptionRenderDispatcher {
|
|||||||
|
|
||||||
ShaderCallback callback = ShaderHelper.getViewProjectionCallback(projectionMat, viewMat);
|
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()) {
|
for (RenderedContraption renderer : renderers.values()) {
|
||||||
renderer.doRenderLayer(layer, structureShader);
|
renderer.doRenderLayer(layer, structureShader);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
// }
|
||||||
|
//}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -34,7 +34,7 @@ public class ShaderHelper {
|
|||||||
public static final FloatBuffer VEC3_BUFFER = MemoryUtil.memAllocFloat(3);
|
public static final FloatBuffer VEC3_BUFFER = MemoryUtil.memAllocFloat(3);
|
||||||
public static final FloatBuffer MATRIX_BUFFER = MemoryUtil.memAllocFloat(16);
|
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")
|
@SuppressWarnings("deprecation")
|
||||||
public static void initShaders() {
|
public static void initShaders() {
|
||||||
@ -46,7 +46,7 @@ public class ShaderHelper {
|
|||||||
if (predicate.test(VanillaResourceType.SHADERS)) {
|
if (predicate.test(VanillaResourceType.SHADERS)) {
|
||||||
PROGRAMS.values().forEach(ShaderLinkHelper::deleteShader);
|
PROGRAMS.values().forEach(ShaderLinkHelper::deleteShader);
|
||||||
PROGRAMS.clear();
|
PROGRAMS.clear();
|
||||||
for (Shader shader : Shader.values()) {
|
for (AllShaderPrograms shader : AllShaderPrograms.values()) {
|
||||||
createProgram(manager, shader);
|
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);
|
ShaderProgram shaderProgram = PROGRAMS.get(shader);
|
||||||
|
|
||||||
return shaderProgram.getProgram();
|
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);
|
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);
|
ShaderProgram prog = PROGRAMS.get(shader);
|
||||||
if (prog == null) {
|
if (prog == null) {
|
||||||
return -1;
|
return -1;
|
||||||
@ -109,7 +109,7 @@ public class ShaderHelper {
|
|||||||
ShaderLinkHelper.useProgram(0);
|
ShaderLinkHelper.useProgram(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void createProgram(IResourceManager manager, Shader shader) {
|
private static void createProgram(IResourceManager manager, AllShaderPrograms shader) {
|
||||||
try {
|
try {
|
||||||
ShaderLoader vert = createShader(manager, shader.vert, ShaderLoader.ShaderType.VERTEX);
|
ShaderLoader vert = createShader(manager, shader.vert, ShaderLoader.ShaderType.VERTEX);
|
||||||
ShaderLoader frag = createShader(manager, shader.frag, ShaderLoader.ShaderType.FRAGMENT);
|
ShaderLoader frag = createShader(manager, shader.frag, ShaderLoader.ShaderType.FRAGMENT);
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
package com.simibubi.create.foundation.render.gl.shader;
|
||||||
|
|
||||||
|
public enum ShaderType {
|
||||||
|
VERTEX,
|
||||||
|
FRAGMENT,
|
||||||
|
}
|
@ -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<>();
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package com.simibubi.create.foundation.render.instancing;
|
package com.simibubi.create.foundation.render.instancing;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
|
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.texture.TextureAtlasSprite;
|
||||||
import net.minecraft.client.renderer.vertex.VertexFormatElement;
|
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 class BeltData extends KineticData<BeltData> {
|
||||||
public static final VertexAttribute TARGET_UV = copy("scrollTexture", VEC4);
|
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);
|
public static VertexFormat FORMAT = new VertexFormat(KineticData.FORMAT, ROTATION, UV, TARGET_UV, SCROLL_MULT);
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import com.simibubi.create.AllBlockPartials;
|
|||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
||||||
import com.simibubi.create.foundation.render.Compartment;
|
import com.simibubi.create.foundation.render.Compartment;
|
||||||
import com.simibubi.create.foundation.render.SuperByteBufferCache;
|
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.ShaderCallback;
|
||||||
import com.simibubi.create.foundation.render.gl.shader.ShaderHelper;
|
import com.simibubi.create.foundation.render.gl.shader.ShaderHelper;
|
||||||
import net.minecraft.block.BlockState;
|
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 Map<Compartment<?>, Cache<Object, MODEL>> models;
|
||||||
protected final ModelFactory<MODEL> factory;
|
protected final ModelFactory<MODEL> factory;
|
||||||
protected final Shader shader;
|
protected final AllShaderPrograms shader;
|
||||||
protected final Predicate<RenderType> layerPredicate;
|
protected final Predicate<RenderType> layerPredicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a material that renders in the default layer (CUTOUT_MIPPED)
|
* 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());
|
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.models = new HashMap<>();
|
||||||
this.factory = factory;
|
this.factory = factory;
|
||||||
this.shader = shader;
|
this.shader = shader;
|
||||||
|
@ -1,26 +1,26 @@
|
|||||||
package com.simibubi.create.foundation.render.instancing;
|
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;
|
import org.lwjgl.opengl.GL20;
|
||||||
|
|
||||||
public class VertexAttribute {
|
public class VertexAttribute {
|
||||||
public static final VertexAttribute MAT4 = new VertexAttribute("mat4", VertexFormatElement.Type.FLOAT, 16);
|
public static final VertexAttribute MAT4 = new VertexAttribute("mat4", GlPrimitiveType.FLOAT, 16);
|
||||||
public static final VertexAttribute VEC4 = new VertexAttribute("vec4", VertexFormatElement.Type.FLOAT, 4);
|
public static final VertexAttribute VEC4 = new VertexAttribute("vec4", GlPrimitiveType.FLOAT, 4);
|
||||||
public static final VertexAttribute VEC3 = new VertexAttribute("vec3", VertexFormatElement.Type.FLOAT, 3);
|
public static final VertexAttribute VEC3 = new VertexAttribute("vec3", GlPrimitiveType.FLOAT, 3);
|
||||||
public static final VertexAttribute VEC2 = new VertexAttribute("vec2", VertexFormatElement.Type.FLOAT, 2);
|
public static final VertexAttribute VEC2 = new VertexAttribute("vec2", GlPrimitiveType.FLOAT, 2);
|
||||||
public static final VertexAttribute FLOAT = new VertexAttribute("float", VertexFormatElement.Type.FLOAT, 1);
|
public static final VertexAttribute FLOAT = new VertexAttribute("float", GlPrimitiveType.FLOAT, 1);
|
||||||
|
|
||||||
public static final VertexAttribute POSITION = copy("pos", VEC3);
|
public static final VertexAttribute POSITION = copy("pos", VEC3);
|
||||||
public static final VertexAttribute INSTANCE_POSITION = copy("instancePos", VEC3);
|
public static final VertexAttribute INSTANCE_POSITION = copy("instancePos", VEC3);
|
||||||
public static final VertexAttribute ROTATION = copy("eulerAngles", 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 NORMAL = new VertexAttribute("normal", GlPrimitiveType.BYTE, 3, true);
|
||||||
public static final VertexAttribute RGBA = new VertexAttribute("rgba", VertexFormatElement.Type.UBYTE, 4, true);
|
public static final VertexAttribute RGBA = new VertexAttribute("rgba", GlPrimitiveType.UBYTE, 4, true);
|
||||||
public static final VertexAttribute RGB = new VertexAttribute("rgb", VertexFormatElement.Type.UBYTE, 3, 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 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 String name;
|
||||||
private final VertexFormatElement.Type type;
|
private final GlPrimitiveType type;
|
||||||
private final int count;
|
private final int count;
|
||||||
private final int size;
|
private final int size;
|
||||||
private final int attributeCount;
|
private final int attributeCount;
|
||||||
@ -39,11 +39,11 @@ public class VertexAttribute {
|
|||||||
this.normalized = that.normalized;
|
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);
|
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.name = name;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.count = count;
|
this.count = count;
|
||||||
|
@ -2,6 +2,7 @@ package com.simibubi.create.foundation.render.light;
|
|||||||
|
|
||||||
import com.simibubi.create.foundation.render.RenderWork;
|
import com.simibubi.create.foundation.render.RenderWork;
|
||||||
import com.simibubi.create.foundation.render.gl.GlTexture;
|
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.BlockPos;
|
||||||
import net.minecraft.util.math.SectionPos;
|
import net.minecraft.util.math.SectionPos;
|
||||||
import net.minecraft.world.ILightReader;
|
import net.minecraft.world.ILightReader;
|
||||||
@ -26,7 +27,19 @@ public class LightVolume {
|
|||||||
setSampleVolume(sampleVolume);
|
setSampleVolume(sampleVolume);
|
||||||
|
|
||||||
this.glTexture = new GlTexture(GL20.GL_TEXTURE_3D);
|
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) {
|
private void setSampleVolume(GridAlignedBB sampleVolume) {
|
||||||
@ -217,11 +230,19 @@ public class LightVolume {
|
|||||||
|
|
||||||
private void uploadTexture() {
|
private void uploadTexture() {
|
||||||
if (bufferDirty) {
|
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 sizeX = textureVolume.sizeX();
|
||||||
int sizeY = textureVolume.sizeY();
|
int sizeY = textureVolume.sizeY();
|
||||||
int sizeZ = textureVolume.sizeZ();
|
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;
|
bufferDirty = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user