mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-29 08:26:37 +01:00
Model changes
- Buffered models directly consume IModels - Document IModel more - Move contraption world render spoofing to flywheel - Miscellaneous new RenderMaths - Added WorldModel, renders many blocks given a world instance - Fix broken transparency on contraptions when using Flywheel
This commit is contained in:
parent
17d5081345
commit
d69ff7054e
14 changed files with 311 additions and 78 deletions
|
@ -97,6 +97,14 @@ public class VecBuffer {
|
|||
return this;
|
||||
}
|
||||
|
||||
public VecBuffer putColor(byte r, byte g, byte b, byte a) {
|
||||
internal.put(r);
|
||||
internal.put(g);
|
||||
internal.put(b);
|
||||
internal.put(a);
|
||||
return this;
|
||||
}
|
||||
|
||||
public VecBuffer putVec3(float x, float y, float z) {
|
||||
internal.putFloat(x);
|
||||
internal.putFloat(y);
|
||||
|
|
|
@ -11,9 +11,9 @@ import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
|||
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
|
||||
import com.jozufozu.flywheel.backend.material.MaterialSpec;
|
||||
import com.jozufozu.flywheel.backend.model.BufferedModel;
|
||||
import com.jozufozu.flywheel.backend.model.IBufferedModel;
|
||||
import com.jozufozu.flywheel.backend.model.IndexedModel;
|
||||
import com.jozufozu.flywheel.core.model.IModel;
|
||||
import com.jozufozu.flywheel.core.model.ModelUtil;
|
||||
import com.jozufozu.flywheel.util.AttribUtil;
|
||||
|
||||
/**
|
||||
|
@ -37,7 +37,7 @@ import com.jozufozu.flywheel.util.AttribUtil;
|
|||
public class Instancer<D extends InstanceData> {
|
||||
|
||||
protected final Supplier<IModel> gen;
|
||||
protected BufferedModel model;
|
||||
protected IBufferedModel model;
|
||||
|
||||
protected final VertexFormat instanceFormat;
|
||||
protected final IInstanceFactory<D> factory;
|
||||
|
@ -92,7 +92,7 @@ public class Instancer<D extends InstanceData> {
|
|||
}
|
||||
|
||||
private void init() {
|
||||
model = ModelUtil.getIndexedModel(gen.get());
|
||||
model = new IndexedModel(gen.get());
|
||||
initialized = true;
|
||||
|
||||
if (model.getVertexCount() <= 0)
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
package com.jozufozu.flywheel.backend.model;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.jozufozu.flywheel.backend.gl.GlVertexArray;
|
||||
import com.jozufozu.flywheel.core.model.IModel;
|
||||
import com.jozufozu.flywheel.util.AttribUtil;
|
||||
|
||||
public class ArrayModelRenderer extends ModelRenderer {
|
||||
|
||||
protected GlVertexArray vao;
|
||||
|
||||
public ArrayModelRenderer(BufferedModel model) {
|
||||
public ArrayModelRenderer(Supplier<IModel> model) {
|
||||
super(model);
|
||||
vao = new GlVertexArray();
|
||||
|
||||
vao.bind();
|
||||
model.setupState();
|
||||
vao.unbind();
|
||||
model.clearState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
if (!model.valid()) return;
|
||||
if (!isInitialized()) init();
|
||||
if (!isValid()) return;
|
||||
|
||||
vao.bind();
|
||||
|
||||
|
@ -25,4 +25,31 @@ public class ArrayModelRenderer extends ModelRenderer {
|
|||
|
||||
vao.unbind();
|
||||
}
|
||||
|
||||
private boolean isValid() {
|
||||
return model != null && model.valid();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
initialized = true;
|
||||
IModel model = modelSupplier.get();
|
||||
|
||||
if (model.vertexCount() <= 0) return;
|
||||
|
||||
this.model = new IndexedModel(model);
|
||||
|
||||
vao = new GlVertexArray();
|
||||
|
||||
vao.bind();
|
||||
|
||||
// bind the model's vbo to our vao
|
||||
this.model.setupState();
|
||||
|
||||
AttribUtil.enableArrays(this.model.getAttributeCount());
|
||||
|
||||
vao.unbind();
|
||||
|
||||
this.model.clearState();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,46 +9,45 @@ import com.jozufozu.flywheel.backend.gl.GlPrimitive;
|
|||
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
|
||||
import com.jozufozu.flywheel.core.model.IModel;
|
||||
import com.jozufozu.flywheel.util.AttribUtil;
|
||||
|
||||
public class BufferedModel {
|
||||
public class BufferedModel implements IBufferedModel {
|
||||
|
||||
protected final IModel model;
|
||||
protected final GlPrimitive primitiveMode;
|
||||
protected final ByteBuffer data;
|
||||
protected final VertexFormat format;
|
||||
protected final int vertexCount;
|
||||
protected GlBuffer vbo;
|
||||
protected boolean deleted;
|
||||
|
||||
public BufferedModel(GlPrimitive primitiveMode, VertexFormat format, ByteBuffer data, int vertices) {
|
||||
public BufferedModel(GlPrimitive primitiveMode, IModel model) {
|
||||
this.model = model;
|
||||
this.primitiveMode = primitiveMode;
|
||||
this.data = data;
|
||||
this.format = format;
|
||||
this.vertexCount = vertices;
|
||||
|
||||
vbo = new GlBuffer(GlBufferType.ARRAY_BUFFER);
|
||||
|
||||
vbo.bind();
|
||||
// allocate the buffer on the gpu
|
||||
vbo.alloc(this.data.capacity());
|
||||
vbo.alloc(model.size());
|
||||
|
||||
// mirror it in system memory so we can write to it, and upload our model.
|
||||
vbo.getBuffer(0, this.data.capacity())
|
||||
.put(this.data)
|
||||
.flush();
|
||||
MappedBuffer buffer = vbo.getBuffer(0, model.size());
|
||||
model.buffer(buffer);
|
||||
buffer.flush();
|
||||
|
||||
vbo.unbind();
|
||||
}
|
||||
|
||||
public VertexFormat getFormat() {
|
||||
return format;
|
||||
return model.format();
|
||||
}
|
||||
|
||||
public int getVertexCount() {
|
||||
return vertexCount;
|
||||
return model.vertexCount();
|
||||
}
|
||||
|
||||
public boolean valid() {
|
||||
return vertexCount > 0 && !deleted;
|
||||
return getVertexCount() > 0 && !deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,7 +56,7 @@ public class BufferedModel {
|
|||
public void setupState() {
|
||||
vbo.bind();
|
||||
AttribUtil.enableArrays(getAttributeCount());
|
||||
format.vertexAttribPointers(0);
|
||||
getFormat().vertexAttribPointers(0);
|
||||
}
|
||||
|
||||
public void clearState() {
|
||||
|
@ -66,7 +65,7 @@ public class BufferedModel {
|
|||
}
|
||||
|
||||
public void drawCall() {
|
||||
glDrawArrays(primitiveMode.glEnum, 0, vertexCount);
|
||||
glDrawArrays(primitiveMode.glEnum, 0, getVertexCount());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -75,7 +74,7 @@ public class BufferedModel {
|
|||
public void drawInstances(int instanceCount) {
|
||||
if (!valid()) return;
|
||||
|
||||
Backend.getInstance().compat.drawInstanced.drawArraysInstanced(primitiveMode, 0, vertexCount, instanceCount);
|
||||
Backend.getInstance().compat.drawInstanced.drawArraysInstanced(primitiveMode, 0, getVertexCount(), instanceCount);
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
|
@ -84,10 +83,5 @@ public class BufferedModel {
|
|||
deleted = true;
|
||||
vbo.delete();
|
||||
}
|
||||
|
||||
public int getAttributeCount() {
|
||||
return format.getAttributeCount();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package com.jozufozu.flywheel.backend.model;
|
||||
|
||||
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
||||
|
||||
public interface IBufferedModel {
|
||||
|
||||
VertexFormat getFormat();
|
||||
|
||||
int getVertexCount();
|
||||
|
||||
boolean valid();
|
||||
|
||||
/**
|
||||
* The VBO/VAO should be bound externally.
|
||||
*/
|
||||
void setupState();
|
||||
|
||||
void clearState();
|
||||
|
||||
void drawCall();
|
||||
|
||||
/**
|
||||
* Draws many instances of this model, assuming the appropriate state is already bound.
|
||||
*/
|
||||
void drawInstances(int instanceCount);
|
||||
|
||||
void delete();
|
||||
|
||||
default int getAttributeCount() {
|
||||
return getFormat().getAttributeCount();
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ import com.jozufozu.flywheel.backend.Backend;
|
|||
import com.jozufozu.flywheel.backend.gl.GlPrimitive;
|
||||
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
||||
import com.jozufozu.flywheel.core.QuadConverter;
|
||||
import com.jozufozu.flywheel.core.model.IModel;
|
||||
|
||||
/**
|
||||
* An indexed triangle model. Just what the driver ordered.
|
||||
|
@ -18,15 +19,10 @@ public class IndexedModel extends BufferedModel {
|
|||
|
||||
protected ElementBuffer ebo;
|
||||
|
||||
public IndexedModel(VertexFormat modelFormat, ByteBuffer buf, int vertices, ElementBuffer ebo) {
|
||||
super(GlPrimitive.TRIANGLES, modelFormat, buf, vertices);
|
||||
public IndexedModel(IModel model) {
|
||||
super(GlPrimitive.TRIANGLES, model);
|
||||
|
||||
this.ebo = ebo;
|
||||
}
|
||||
|
||||
public static IndexedModel fromSequentialQuads(VertexFormat modelFormat, ByteBuffer quads, int vertices) {
|
||||
return new IndexedModel(modelFormat, quads, vertices, QuadConverter.getInstance()
|
||||
.quads2Tris(vertices / 4));
|
||||
this.ebo = model.createEBO();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -48,13 +44,8 @@ public class IndexedModel extends BufferedModel {
|
|||
|
||||
@Override
|
||||
public void drawInstances(int instanceCount) {
|
||||
if (vertexCount <= 0 || deleted) return;
|
||||
if (!valid()) return;
|
||||
|
||||
Backend.getInstance().compat.drawInstanced.drawElementsInstanced(primitiveMode, ebo.elementCount, ebo.eboIndexType, 0, instanceCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete() {
|
||||
super.delete();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,26 @@
|
|||
package com.jozufozu.flywheel.backend.model;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.jozufozu.flywheel.core.model.IModel;
|
||||
|
||||
public class ModelRenderer {
|
||||
|
||||
protected BufferedModel model;
|
||||
protected Supplier<IModel> modelSupplier;
|
||||
protected IBufferedModel model;
|
||||
|
||||
public ModelRenderer(BufferedModel model) {
|
||||
this.model = model;
|
||||
protected boolean initialized;
|
||||
|
||||
public ModelRenderer(Supplier<IModel> modelSupplier) {
|
||||
this.modelSupplier = modelSupplier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders this model, checking first if there is anything to render.
|
||||
*/
|
||||
public void draw() {
|
||||
|
||||
if (!isInitialized()) init();
|
||||
if (!model.valid()) return;
|
||||
|
||||
model.setupState();
|
||||
|
@ -19,7 +28,21 @@ public class ModelRenderer {
|
|||
model.clearState();
|
||||
}
|
||||
|
||||
protected void init() {
|
||||
initialized = true;
|
||||
IModel model = modelSupplier.get();
|
||||
|
||||
if (model.vertexCount() <= 0) return;
|
||||
|
||||
this.model = new IndexedModel(model);
|
||||
}
|
||||
|
||||
public boolean isInitialized() {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
model.delete();
|
||||
if (model != null)
|
||||
model.delete();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,12 +9,21 @@ public class Formats {
|
|||
.addAttributes(CommonAttributes.VEC3, CommonAttributes.NORMAL, CommonAttributes.UV)
|
||||
.build();
|
||||
|
||||
public static final VertexFormat COLORED_LIT_MODEL = VertexFormat.builder()
|
||||
.addAttributes(CommonAttributes.VEC3,
|
||||
CommonAttributes.NORMAL,
|
||||
CommonAttributes.UV,
|
||||
CommonAttributes.RGBA,
|
||||
CommonAttributes.LIGHT)
|
||||
.build();
|
||||
|
||||
public static final VertexFormat TRANSFORMED = litInstance().addAttributes(MatrixAttributes.MAT4, MatrixAttributes.MAT3)
|
||||
.build();
|
||||
|
||||
public static final VertexFormat ORIENTED = litInstance().addAttributes(CommonAttributes.VEC3, CommonAttributes.VEC3, CommonAttributes.QUATERNION)
|
||||
.build();
|
||||
|
||||
public static VertexFormat.Builder litInstance() {
|
||||
public static VertexFormat.Builder litInstance() {
|
||||
return VertexFormat.builder()
|
||||
.addAttributes(CommonAttributes.LIGHT, CommonAttributes.RGBA);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,9 @@ import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
|||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
/**
|
||||
* A model of a single block.
|
||||
*/
|
||||
public class BlockModel implements IModel {
|
||||
private static final MatrixStack IDENTITY = new MatrixStack();
|
||||
|
||||
|
@ -69,12 +72,6 @@ public class BlockModel implements IModel {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementBuffer createEBO() {
|
||||
return QuadConverter.getInstance()
|
||||
.quads2Tris(vertexCount() / 4);
|
||||
}
|
||||
|
||||
public static BufferBuilder getBufferBuilder(IBakedModel model, BlockState referenceState, MatrixStack ms) {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
BlockRendererDispatcher dispatcher = mc.getBlockRenderer();
|
||||
|
|
|
@ -3,9 +3,27 @@ package com.jozufozu.flywheel.core.model;
|
|||
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
||||
import com.jozufozu.flywheel.backend.model.ElementBuffer;
|
||||
import com.jozufozu.flywheel.core.QuadConverter;
|
||||
|
||||
/**
|
||||
* A model that can be rendered by flywheel.
|
||||
*
|
||||
* <p>
|
||||
* It is expected that the following assertion will not fail:
|
||||
* </p>
|
||||
*
|
||||
* <pre>{@code
|
||||
* IModel model = ...;
|
||||
* VecBuffer into = ...;
|
||||
*
|
||||
* int initial = VecBuffer.unwrap().position();
|
||||
*
|
||||
* model.buffer(into);
|
||||
*
|
||||
* int final = VecBuffer.unwrap().position();
|
||||
*
|
||||
* assert model.size() == final - initial;
|
||||
* }</pre>
|
||||
*/
|
||||
public interface IModel {
|
||||
|
||||
|
@ -14,12 +32,34 @@ public interface IModel {
|
|||
*/
|
||||
void buffer(VecBuffer buffer);
|
||||
|
||||
/**
|
||||
* @return The number of vertices the model has.
|
||||
*/
|
||||
int vertexCount();
|
||||
|
||||
/**
|
||||
* @return The format of this model's vertices
|
||||
*/
|
||||
VertexFormat format();
|
||||
|
||||
ElementBuffer createEBO();
|
||||
/**
|
||||
* Create an element buffer object that indexes the vertices of this model.
|
||||
*
|
||||
* <p>
|
||||
* Very often models in minecraft are made up of sequential quads, which is a very predictable pattern.
|
||||
* The default implementation accommodates this, however this can be overridden to change the behavior and
|
||||
* support more complex models.
|
||||
* </p>
|
||||
* @return an element buffer object indexing this model's vertices.
|
||||
*/
|
||||
default ElementBuffer createEBO() {
|
||||
return QuadConverter.getInstance()
|
||||
.quads2Tris(vertexCount() / 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* The size in bytes that this model's data takes up.
|
||||
*/
|
||||
default int size() {
|
||||
return vertexCount() * format().getStride();
|
||||
}
|
||||
|
|
|
@ -43,10 +43,4 @@ public class ModelPart implements IModel {
|
|||
public VertexFormat format() {
|
||||
return Formats.UNLIT_MODEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementBuffer createEBO() {
|
||||
return QuadConverter.getInstance()
|
||||
.quads2Tris(vertices / 4);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +1,62 @@
|
|||
package com.jozufozu.flywheel.core.model;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import static org.lwjgl.opengl.GL11.GL_QUADS;
|
||||
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
||||
import com.jozufozu.flywheel.backend.model.IndexedModel;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Random;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
|
||||
import net.minecraft.block.BlockRenderType;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.BlockModelRenderer;
|
||||
import net.minecraft.client.renderer.BlockModelShapes;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.RenderTypeLookup;
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockDisplayReader;
|
||||
import net.minecraft.world.gen.feature.template.Template;
|
||||
import net.minecraftforge.client.ForgeHooksClient;
|
||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||
import net.minecraftforge.common.util.Lazy;
|
||||
|
||||
public class ModelUtil {
|
||||
public static IndexedModel getIndexedModel(IModel blockModel) {
|
||||
ByteBuffer vertices = ByteBuffer.allocate(blockModel.size());
|
||||
vertices.order(ByteOrder.nativeOrder());
|
||||
private static final Lazy<BlockModelRenderer> MODEL_RENDERER = Lazy.of(() -> new BlockModelRenderer(Minecraft.getInstance().getBlockColors()));
|
||||
private static final Lazy<BlockModelShapes> BLOCK_MODELS = Lazy.of(() -> Minecraft.getInstance().getModelManager().getBlockModelShaper());
|
||||
|
||||
blockModel.buffer(new VecBuffer(vertices));
|
||||
public static BufferBuilder getBufferBuilderFromTemplate(IBlockDisplayReader renderWorld, RenderType layer, Collection<Template.BlockInfo> blocks) {
|
||||
MatrixStack ms = new MatrixStack();
|
||||
Random random = new Random();
|
||||
BufferBuilder builder = new BufferBuilder(DefaultVertexFormats.BLOCK.getIntegerSize());
|
||||
builder.begin(GL_QUADS, DefaultVertexFormats.BLOCK);
|
||||
|
||||
((Buffer) vertices).rewind();
|
||||
ForgeHooksClient.setRenderLayer(layer);
|
||||
BlockModelRenderer.enableCaching();
|
||||
for (Template.BlockInfo info : blocks) {
|
||||
BlockState state = info.state;
|
||||
|
||||
return new IndexedModel(blockModel.format(), vertices, blockModel.vertexCount(), blockModel.createEBO());
|
||||
if (state.getRenderShape() != BlockRenderType.MODEL)
|
||||
continue;
|
||||
if (!RenderTypeLookup.canRenderInLayer(state, layer))
|
||||
continue;
|
||||
|
||||
BlockPos pos = info.pos;
|
||||
|
||||
ms.pushPose();
|
||||
ms.translate(pos.getX(), pos.getY(), pos.getZ());
|
||||
MODEL_RENDERER.get().renderModel(renderWorld, BLOCK_MODELS.get().getBlockModel(state), state, pos, ms, builder, true,
|
||||
random, 42, OverlayTexture.NO_OVERLAY, EmptyModelData.INSTANCE);
|
||||
ms.popPose();
|
||||
}
|
||||
BlockModelRenderer.clearCache();
|
||||
ForgeHooksClient.setRenderLayer(null);
|
||||
|
||||
builder.end();
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
package com.jozufozu.flywheel.core.model;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
||||
import com.jozufozu.flywheel.core.Formats;
|
||||
import com.jozufozu.flywheel.util.BufferBuilderReader;
|
||||
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.world.IBlockDisplayReader;
|
||||
import net.minecraft.world.gen.feature.template.Template;
|
||||
|
||||
public class WorldModel implements IModel {
|
||||
|
||||
private final BufferBuilderReader reader;
|
||||
|
||||
public WorldModel(IBlockDisplayReader renderWorld, RenderType layer, Collection<Template.BlockInfo> blocks) {
|
||||
reader = new BufferBuilderReader(ModelUtil.getBufferBuilderFromTemplate(renderWorld, layer, blocks));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buffer(VecBuffer vertices) {
|
||||
for (int i = 0; i < vertexCount(); i++) {
|
||||
vertices.putVec3(reader.getX(i), reader.getY(i), reader.getZ(i));
|
||||
|
||||
vertices.putVec3(reader.getNX(i), reader.getNY(i), reader.getNZ(i));
|
||||
|
||||
vertices.putVec2(reader.getU(i), reader.getV(i));
|
||||
|
||||
vertices.putColor(reader.getR(i), reader.getG(i), reader.getB(i), reader.getA(i));
|
||||
|
||||
int light = reader.getLight(i);
|
||||
|
||||
byte block = (byte) (LightTexture.block(light) << 4);
|
||||
byte sky = (byte) (LightTexture.sky(light) << 4);
|
||||
|
||||
vertices.putVec2(block, sky);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int vertexCount() {
|
||||
return reader.getVertexCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexFormat format() {
|
||||
return Formats.COLORED_LIT_MODEL;
|
||||
}
|
||||
|
||||
}
|
|
@ -2,7 +2,31 @@ package com.jozufozu.flywheel.util;
|
|||
|
||||
public class RenderMath {
|
||||
|
||||
/**
|
||||
* Convert a signed, normalized floating point value into a normalized byte.
|
||||
*/
|
||||
public static byte nb(float f) {
|
||||
return (byte) (f * 127);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a signed byte into a normalized float.
|
||||
*/
|
||||
public static float f(byte b) {
|
||||
return b / 127f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an unsigned byte into a normalized float.
|
||||
*/
|
||||
public static float uf(byte b) {
|
||||
return (float) (Byte.toUnsignedInt(b)) / 255f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an unsigned, normalized float into an unsigned normalized byte.
|
||||
*/
|
||||
public static byte unb(float f) {
|
||||
return (byte) Math.floor(f * 255);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue