mirror of
https://github.com/FabricMC/fabric.git
synced 2024-11-14 19:25:23 -05:00
Remove texture indices and make material AO a TriState
(#3044)
* Reorganize method order * Remove texture indices - Add allow passing shade boolean to QuadView#toBakedQuad - Add MutableQuadView#fromVanilla(int[], int) - Add NonExtendable annotation to SpriteFinder and RendererAccess - Add note to RenderContext#bakedModelConsumer * Make Material AO a TriState Co-authored-by: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> * Rename spriteUnitSquare -> uvUnitSquare * Remove toBakedQuad with shade boolean parameter * Add custom apiNote, implSpec, and implNote javadoc tags * Reject null BlendMode and AO; clarify fromVanilla(int[], int) javadoc * cullFace nullability, fromBakedQuad shade clarification, toBakedQuad color index * Add QuadView#copyUv and minor improvements * Nullability tweaks --------- Co-authored-by: PepperCode1 <44146161+PepperCode1@users.noreply.github.com>
This commit is contained in:
parent
f7923f6d3d
commit
7bf08b2e0c
23 changed files with 1017 additions and 668 deletions
|
@ -331,6 +331,12 @@ javadoc {
|
|||
)
|
||||
// Disable the crazy super-strict doclint tool in Java 8
|
||||
addStringOption("Xdoclint:none", "-quiet")
|
||||
|
||||
tags(
|
||||
'apiNote:a:API Note:',
|
||||
'implSpec:a:Implementation Requirements:',
|
||||
'implNote:a:Implementation Note:'
|
||||
)
|
||||
}
|
||||
|
||||
allprojects.each {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package net.fabricmc.fabric.api.renderer.v1;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.fabric.impl.renderer.RendererAccessImpl;
|
||||
|
@ -23,6 +24,7 @@ import net.fabricmc.fabric.impl.renderer.RendererAccessImpl;
|
|||
/**
|
||||
* Registration and access for rendering extensions.
|
||||
*/
|
||||
@ApiStatus.NonExtendable
|
||||
public interface RendererAccess {
|
||||
RendererAccess INSTANCE = RendererAccessImpl.INSTANCE;
|
||||
|
||||
|
|
|
@ -16,11 +16,14 @@
|
|||
|
||||
package net.fabricmc.fabric.api.renderer.v1.material;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
|
||||
import net.fabricmc.fabric.api.renderer.v1.Renderer;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
|
||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
||||
import net.fabricmc.fabric.api.util.TriState;
|
||||
|
||||
/**
|
||||
* Finds standard {@link RenderMaterial} instances used to communicate
|
||||
|
@ -29,6 +32,72 @@ import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
|||
* <p>Must be obtained via {@link Renderer#materialFinder()}.
|
||||
*/
|
||||
public interface MaterialFinder {
|
||||
/**
|
||||
* Defines how sprite pixels will be blended with the scene.
|
||||
*
|
||||
* <p>See {@link BlendMode} for more information.
|
||||
*
|
||||
* @apiNote The default implementation will be removed in the next breaking release.
|
||||
*/
|
||||
default MaterialFinder blendMode(BlendMode blendMode) {
|
||||
return blendMode(0, blendMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vertex color(s) will be modified for quad color index unless disabled.
|
||||
*
|
||||
* @apiNote The default implementation will be removed in the next breaking release.
|
||||
*/
|
||||
default MaterialFinder disableColorIndex(boolean disable) {
|
||||
return disableColorIndex(0, disable);
|
||||
}
|
||||
|
||||
/**
|
||||
* When true, sprite texture and color will be rendered at full brightness.
|
||||
* Lightmap values provided via {@link QuadEmitter#lightmap(int)} will be ignored.
|
||||
* False by default
|
||||
*
|
||||
* <p>This is the preferred method for emissive lighting effects. Some renderers
|
||||
* with advanced lighting models may not use block lightmaps and this method will
|
||||
* allow per-sprite emissive lighting in future extensions that support overlay sprites.
|
||||
*
|
||||
* <p>Note that color will still be modified by diffuse shading and ambient occlusion,
|
||||
* unless disabled via {@link #disableDiffuse(boolean)} and {@link #ambientOcclusion(TriState)}.
|
||||
*
|
||||
* @apiNote The default implementation will be removed in the next breaking release.
|
||||
*/
|
||||
default MaterialFinder emissive(boolean isEmissive) {
|
||||
return emissive(0, isEmissive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vertex color(s) will be modified for diffuse shading unless disabled.
|
||||
*
|
||||
* @apiNote The default implementation will be removed in the next breaking release.
|
||||
*/
|
||||
default MaterialFinder disableDiffuse(boolean disable) {
|
||||
return disableDiffuse(0, disable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls whether vertex color(s) will be modified for ambient occlusion.
|
||||
*
|
||||
* <p>By default, ambient occlusion will be used if {@link BakedModel#useAmbientOcclusion() the model uses ambient occlusion}
|
||||
* and the block state has {@link BlockState#getLuminance() a luminance} of 0.
|
||||
* Set to {@link TriState#TRUE} or {@link TriState#FALSE} to override this behavior.
|
||||
*
|
||||
* @apiNote The default implementation will be removed in the next breaking release.
|
||||
*/
|
||||
default MaterialFinder ambientOcclusion(TriState mode) {
|
||||
return disableAo(0, mode == TriState.FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets this instance to default values. Values will match those
|
||||
* in effect when an instance is newly obtained via {@link Renderer#materialFinder()}.
|
||||
*/
|
||||
MaterialFinder clear();
|
||||
|
||||
/**
|
||||
* Returns the standard material encoding all
|
||||
* of the current settings in this finder. The settings in
|
||||
|
@ -41,67 +110,63 @@ public interface MaterialFinder {
|
|||
RenderMaterial find();
|
||||
|
||||
/**
|
||||
* Resets this instance to default values. Values will match those
|
||||
* in effect when an instance is newly obtained via {@link Renderer#materialFinder()}.
|
||||
*/
|
||||
MaterialFinder clear();
|
||||
|
||||
/**
|
||||
* Reserved for future use. Behavior for values > 1 is currently undefined.
|
||||
*/
|
||||
MaterialFinder spriteDepth(int depth);
|
||||
|
||||
/**
|
||||
* Defines how sprite pixels will be blended with the scene.
|
||||
* Accepts {link @BlockRenderLayer} values and blending behavior
|
||||
* will emulate the way that Minecraft renders those instances. This does
|
||||
* NOT mean the sprite will be rendered in a specific render pass - some
|
||||
* implementations may not use the standard vanilla render passes.
|
||||
*
|
||||
* <p>CAN be null and is null by default. A null value means the renderer
|
||||
* will use the value normally associated with the block being rendered, or
|
||||
* {@code TRANSLUCENT} for item renders. (Normal Minecraft rendering)
|
||||
*
|
||||
* @deprecated Use {@code BlendMode} version instead.
|
||||
* @deprecated Use {@link #blendMode(BlendMode)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default MaterialFinder blendMode(int spriteIndex, RenderLayer renderLayer) {
|
||||
return blendMode(spriteIndex, BlendMode.fromRenderLayer(renderLayer));
|
||||
return blendMode(BlendMode.fromRenderLayer(renderLayer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines how sprite pixels will be blended with the scene.
|
||||
*
|
||||
* <p>See {@link BlendMode} for more information.
|
||||
* @deprecated Use {@link #blendMode(BlendMode)} instead.
|
||||
*/
|
||||
MaterialFinder blendMode(int spriteIndex, BlendMode blendMode);
|
||||
@Deprecated
|
||||
default MaterialFinder blendMode(int spriteIndex, BlendMode blendMode) {
|
||||
// Null check is kept for legacy reasons, but the new blendMode method will NPE if passed null!
|
||||
if (blendMode == null) {
|
||||
blendMode = BlendMode.DEFAULT;
|
||||
}
|
||||
|
||||
return blendMode(blendMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vertex color(s) will be modified for quad color index unless disabled.
|
||||
* @deprecated Use {@link #disableColorIndex(boolean)} instead.
|
||||
*/
|
||||
MaterialFinder disableColorIndex(int spriteIndex, boolean disable);
|
||||
@Deprecated
|
||||
default MaterialFinder disableColorIndex(int spriteIndex, boolean disable) {
|
||||
return disableColorIndex(disable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vertex color(s) will be modified for diffuse shading unless disabled.
|
||||
* @deprecated Use {@link #emissive(boolean)} instead.
|
||||
*/
|
||||
MaterialFinder disableDiffuse(int spriteIndex, boolean disable);
|
||||
@Deprecated
|
||||
default MaterialFinder emissive(int spriteIndex, boolean isEmissive) {
|
||||
return emissive(isEmissive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vertex color(s) will be modified for ambient occlusion unless disabled.
|
||||
* @deprecated Use {@link #disableDiffuse(boolean)} instead.
|
||||
*/
|
||||
MaterialFinder disableAo(int spriteIndex, boolean disable);
|
||||
@Deprecated
|
||||
default MaterialFinder disableDiffuse(int spriteIndex, boolean disable) {
|
||||
return disableDiffuse(disable);
|
||||
}
|
||||
|
||||
/**
|
||||
* When true, sprite texture and color will be rendered at full brightness.
|
||||
* Lightmap values provided via {@link QuadEmitter#lightmap(int)} will be ignored.
|
||||
* False by default
|
||||
*
|
||||
* <p>This is the preferred method for emissive lighting effects. Some renderers
|
||||
* with advanced lighting models may not use block lightmaps and this method will
|
||||
* allow per-sprite emissive lighting in future extensions that support overlay sprites.
|
||||
*
|
||||
* <p>Note that color will still be modified by diffuse shading and ambient occlusion,
|
||||
* unless disabled via {@link #disableAo(int, boolean)} and {@link #disableDiffuse(int, boolean)}.
|
||||
* @deprecated Use {@link #ambientOcclusion(TriState)} instead.
|
||||
*/
|
||||
MaterialFinder emissive(int spriteIndex, boolean isEmissive);
|
||||
@Deprecated
|
||||
default MaterialFinder disableAo(int spriteIndex, boolean disable) {
|
||||
return ambientOcclusion(disable ? TriState.FALSE : TriState.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not use. Does nothing.
|
||||
*/
|
||||
@Deprecated
|
||||
default MaterialFinder spriteDepth(int depth) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,9 +76,10 @@ public interface RenderMaterial {
|
|||
Identifier MATERIAL_STANDARD = new Identifier("fabric", "standard");
|
||||
|
||||
/**
|
||||
* How many sprite color/uv coordinates are in the material.
|
||||
* Behavior for values > 1 is currently undefined.
|
||||
* See {@link MaterialFinder#spriteDepth(int)}
|
||||
* Do not use. Always returns 1.
|
||||
*/
|
||||
int spriteDepth();
|
||||
@Deprecated
|
||||
default int spriteDepth() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package net.fabricmc.fabric.api.renderer.v1.mesh;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Vector2f;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import net.minecraft.client.render.model.BakedQuad;
|
||||
|
@ -33,39 +34,39 @@ import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
|
|||
* {@link QuadEmitter} and for dynamic renders/mesh transforms.
|
||||
*
|
||||
* <p>Instances of {@link MutableQuadView} will practically always be
|
||||
* threadlocal and/or reused - do not retain references.
|
||||
* thread local and/or reused - do not retain references.
|
||||
*
|
||||
* <p>Only the renderer should implement or extend this interface.
|
||||
*/
|
||||
public interface MutableQuadView extends QuadView {
|
||||
/**
|
||||
* Causes texture to appear with no rotation.
|
||||
* Pass in bakeFlags parameter to {@link #spriteBake(int, Sprite, int)}.
|
||||
* Pass in bakeFlags parameter to {@link #spriteBake(Sprite, int)}.
|
||||
*/
|
||||
int BAKE_ROTATE_NONE = 0;
|
||||
|
||||
/**
|
||||
* Causes texture to appear rotated 90 deg. clockwise relative to nominal face.
|
||||
* Pass in bakeFlags parameter to {@link #spriteBake(int, Sprite, int)}.
|
||||
* Pass in bakeFlags parameter to {@link #spriteBake(Sprite, int)}.
|
||||
*/
|
||||
int BAKE_ROTATE_90 = 1;
|
||||
|
||||
/**
|
||||
* Causes texture to appear rotated 180 deg. relative to nominal face.
|
||||
* Pass in bakeFlags parameter to {@link #spriteBake(int, Sprite, int)}.
|
||||
* Pass in bakeFlags parameter to {@link #spriteBake(Sprite, int)}.
|
||||
*/
|
||||
int BAKE_ROTATE_180 = 2;
|
||||
|
||||
/**
|
||||
* Causes texture to appear rotated 270 deg. clockwise relative to nominal face.
|
||||
* Pass in bakeFlags parameter to {@link #spriteBake(int, Sprite, int)}.
|
||||
* Pass in bakeFlags parameter to {@link #spriteBake(Sprite, int)}.
|
||||
*/
|
||||
int BAKE_ROTATE_270 = 3;
|
||||
|
||||
/**
|
||||
* When enabled, texture coordinate are assigned based on vertex position.
|
||||
* Any existing uv coordinates will be replaced.
|
||||
* Pass in bakeFlags parameter to {@link #spriteBake(int, Sprite, int)}.
|
||||
* Any existing UV coordinates will be replaced.
|
||||
* Pass in bakeFlags parameter to {@link #spriteBake(Sprite, int)}.
|
||||
*
|
||||
* <p>UV lock always derives texture coordinates based on nominal face, even
|
||||
* when the quad is not co-planar with that face, and the result is
|
||||
|
@ -79,12 +80,12 @@ public interface MutableQuadView extends QuadView {
|
|||
* flipped as part of baking. Can be useful for some randomization
|
||||
* and texture mapping scenarios. Results are different from what
|
||||
* can be obtained via rotation and both can be applied.
|
||||
* Pass in bakeFlags parameter to {@link #spriteBake(int, Sprite, int)}.
|
||||
* Pass in bakeFlags parameter to {@link #spriteBake(Sprite, int)}.
|
||||
*/
|
||||
int BAKE_FLIP_U = 8;
|
||||
|
||||
/**
|
||||
* Same as {@link MutableQuadView#BAKE_FLIP_U} but for V coordinate.
|
||||
* Same as {@link #BAKE_FLIP_U} but for V coordinate.
|
||||
*/
|
||||
int BAKE_FLIP_V = 16;
|
||||
|
||||
|
@ -93,86 +94,13 @@ public interface MutableQuadView extends QuadView {
|
|||
* with conventional Minecraft model format. This is scaled to 0-1 during
|
||||
* baking before interpolation. Model loaders that already have 0-1 coordinates
|
||||
* can avoid wasteful multiplication/division by passing 0-1 coordinates directly.
|
||||
* Pass in bakeFlags parameter to {@link #spriteBake(int, Sprite, int)}.
|
||||
* Pass in bakeFlags parameter to {@link #spriteBake(Sprite, int)}.
|
||||
*/
|
||||
int BAKE_NORMALIZED = 32;
|
||||
|
||||
/**
|
||||
* Assigns a different material to this quad. Useful for transformation of
|
||||
* existing meshes because lighting and texture blending are controlled by material.
|
||||
*/
|
||||
MutableQuadView material(RenderMaterial material);
|
||||
|
||||
/**
|
||||
* If non-null, quad is coplanar with a block face which, if known, simplifies
|
||||
* or shortcuts geometric analysis that might otherwise be needed.
|
||||
* Set to null if quad is not coplanar or if this is not known.
|
||||
* Also controls face culling during block rendering.
|
||||
*
|
||||
* <p>Null by default.
|
||||
*
|
||||
* <p>When called with a non-null value, also sets {@link #nominalFace(Direction)}
|
||||
* to the same value.
|
||||
*
|
||||
* <p>This is different from the value reported by {@link BakedQuad#getFace()}. That value
|
||||
* is computed based on face geometry and must be non-null in vanilla quads.
|
||||
* That computed value is returned by {@link #lightFace()}.
|
||||
*/
|
||||
@Nullable
|
||||
MutableQuadView cullFace(@Nullable Direction face);
|
||||
|
||||
/**
|
||||
* Provides a hint to renderer about the facing of this quad. Not required,
|
||||
* but if provided can shortcut some geometric analysis if the quad is parallel to a block face.
|
||||
* Should be the expected value of {@link #lightFace()}. Value will be confirmed
|
||||
* and if invalid the correct light face will be calculated.
|
||||
*
|
||||
* <p>Null by default, and set automatically by {@link #cullFace()}.
|
||||
*
|
||||
* <p>Models may also find this useful as the face for texture UV locking and rotation semantics.
|
||||
*
|
||||
* <p>Note: This value is not persisted independently when the quad is encoded.
|
||||
* When reading encoded quads, this value will always be the same as {@link #lightFace()}.
|
||||
*/
|
||||
@Nullable
|
||||
MutableQuadView nominalFace(Direction face);
|
||||
|
||||
/**
|
||||
* Value functions identically to {@link BakedQuad#getColorIndex()} and is
|
||||
* used by renderer / model builder in same way. Default value is -1.
|
||||
*/
|
||||
MutableQuadView colorIndex(int colorIndex);
|
||||
|
||||
/**
|
||||
* Enables bulk vertex data transfer using the standard Minecraft vertex formats.
|
||||
* This method should be performant whenever caller's vertex representation makes it feasible.
|
||||
*
|
||||
* <p>Calling this method does not emit the quad.
|
||||
*
|
||||
* @deprecated Use {@link #fromVanilla(BakedQuad, RenderMaterial, Direction)}
|
||||
* which has better encapsulation and removed outdated item flag
|
||||
*/
|
||||
@Deprecated
|
||||
MutableQuadView fromVanilla(int[] quadData, int startIndex, boolean isItem);
|
||||
|
||||
/**
|
||||
* Enables bulk vertex data transfer using the standard Minecraft vertex formats.
|
||||
* This method should be performant whenever caller's vertex representation makes it feasible.
|
||||
*
|
||||
* <p>Calling this method does not emit the quad.
|
||||
*/
|
||||
MutableQuadView fromVanilla(BakedQuad quad, RenderMaterial material, Direction cullFace);
|
||||
|
||||
/**
|
||||
* Encodes an integer tag with this quad that can later be retrieved via
|
||||
* {@link QuadView#tag()}. Useful for models that want to perform conditional
|
||||
* transformation or filtering on static meshes.
|
||||
*/
|
||||
MutableQuadView tag(int tag);
|
||||
|
||||
/**
|
||||
* Sets the geometric vertex position for the given vertex,
|
||||
* relative to block origin. (0,0,0). Minecraft rendering is designed
|
||||
* relative to block origin, (0,0,0). Minecraft rendering is designed
|
||||
* for models that fit within a single block space and is recommended
|
||||
* that coordinates remain in the 0-1 range, with multi-block meshes
|
||||
* split into multiple per-block models.
|
||||
|
@ -182,8 +110,81 @@ public interface MutableQuadView extends QuadView {
|
|||
/**
|
||||
* Same as {@link #pos(int, float, float, float)} but accepts vector type.
|
||||
*/
|
||||
default MutableQuadView pos(int vertexIndex, Vector3f vec) {
|
||||
return pos(vertexIndex, vec.x(), vec.y(), vec.z());
|
||||
default MutableQuadView pos(int vertexIndex, Vector3f pos) {
|
||||
return pos(vertexIndex, pos.x(), pos.y(), pos.z());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set vertex color.
|
||||
*
|
||||
* @apiNote The default implementation will be removed in the next breaking release.
|
||||
*/
|
||||
default MutableQuadView color(int vertexIndex, int color) {
|
||||
return spriteColor(vertexIndex, 0, color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience: set vertex color for all vertices at once.
|
||||
*/
|
||||
default MutableQuadView color(int c0, int c1, int c2, int c3) {
|
||||
color(0, c0);
|
||||
color(1, c1);
|
||||
color(2, c2);
|
||||
color(3, c3);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set texture coordinates.
|
||||
*
|
||||
* @apiNote The default implementation will be removed in the next breaking release.
|
||||
*/
|
||||
default MutableQuadView uv(int vertexIndex, float u, float v) {
|
||||
return sprite(vertexIndex, 0, u, v);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set texture coordinates.
|
||||
*
|
||||
* <p>Only use this function if you already have a {@link Vector2f}.
|
||||
* Otherwise, see {@link MutableQuadView#uv(int, float, float)}.
|
||||
*/
|
||||
default MutableQuadView uv(int vertexIndex, Vector2f uv) {
|
||||
return uv(vertexIndex, uv.x, uv.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns sprite atlas u,v coordinates to this quad for the given sprite.
|
||||
* Can handle UV locking, rotation, interpolation, etc. Control this behavior
|
||||
* by passing additive combinations of the BAKE_ flags defined in this interface.
|
||||
*
|
||||
* @apiNote The default implementation will be removed in the next breaking release.
|
||||
*/
|
||||
default MutableQuadView spriteBake(Sprite sprite, int bakeFlags) {
|
||||
return spriteBake(0, sprite, bakeFlags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept vanilla lightmap values. Input values will override lightmap values
|
||||
* computed from world state if input values are higher. Exposed for completeness
|
||||
* but some rendering implementations with non-standard lighting model may not honor it.
|
||||
*
|
||||
* <p>For emissive rendering, it is better to use {@link MaterialFinder#emissive(boolean)}.
|
||||
*/
|
||||
MutableQuadView lightmap(int vertexIndex, int lightmap);
|
||||
|
||||
/**
|
||||
* Convenience: set lightmap for all vertices at once.
|
||||
*
|
||||
* <p>For emissive rendering, it is better to use {@link MaterialFinder#emissive(boolean)}.
|
||||
* See {@link #lightmap(int, int)}.
|
||||
*/
|
||||
default MutableQuadView lightmap(int b0, int b1, int b2, int b3) {
|
||||
lightmap(0, b0);
|
||||
lightmap(1, b1);
|
||||
lightmap(2, b2);
|
||||
lightmap(3, b3);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -200,69 +201,135 @@ public interface MutableQuadView extends QuadView {
|
|||
/**
|
||||
* Same as {@link #normal(int, float, float, float)} but accepts vector type.
|
||||
*/
|
||||
default MutableQuadView normal(int vertexIndex, Vector3f vec) {
|
||||
return normal(vertexIndex, vec.x(), vec.y(), vec.z());
|
||||
default MutableQuadView normal(int vertexIndex, Vector3f normal) {
|
||||
return normal(vertexIndex, normal.x(), normal.y(), normal.z());
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept vanilla lightmap values. Input values will override lightmap values
|
||||
* computed from world state if input values are higher. Exposed for completeness
|
||||
* but some rendering implementations with non-standard lighting model may not honor it.
|
||||
* If non-null, quad is coplanar with a block face which, if known, simplifies
|
||||
* or shortcuts geometric analysis that might otherwise be needed.
|
||||
* Set to null if quad is not coplanar or if this is not known.
|
||||
* Also controls face culling during block rendering.
|
||||
*
|
||||
* <p>For emissive rendering, it is better to use {@link MaterialFinder#emissive(int, boolean)}.
|
||||
* <p>Null by default.
|
||||
*
|
||||
* <p>When called with a non-null value, also sets {@link #nominalFace(Direction)}
|
||||
* to the same value.
|
||||
*
|
||||
* <p>This is different from the value reported by {@link BakedQuad#getFace()}. That value
|
||||
* is computed based on face geometry and must be non-null in vanilla quads.
|
||||
* That computed value is returned by {@link #lightFace()}.
|
||||
*/
|
||||
MutableQuadView lightmap(int vertexIndex, int lightmap);
|
||||
MutableQuadView cullFace(@Nullable Direction face);
|
||||
|
||||
/**
|
||||
* Convenience: set lightmap for all vertices at once.
|
||||
* Provides a hint to renderer about the facing of this quad. Not required,
|
||||
* but if provided can shortcut some geometric analysis if the quad is parallel to a block face.
|
||||
* Should be the expected value of {@link #lightFace()}. Value will be confirmed
|
||||
* and if invalid the correct light face will be calculated.
|
||||
*
|
||||
* <p>For emissive rendering, it is better to use {@link MaterialFinder#emissive(int, boolean)}.
|
||||
* See {@link #lightmap(int, int)}.
|
||||
* <p>Null by default, and set automatically by {@link #cullFace()}.
|
||||
*
|
||||
* <p>Models may also find this useful as the face for texture UV locking and rotation semantics.
|
||||
*
|
||||
* <p>Note: This value is not persisted independently when the quad is encoded.
|
||||
* When reading encoded quads, this value will always be the same as {@link #lightFace()}.
|
||||
*/
|
||||
default MutableQuadView lightmap(int b0, int b1, int b2, int b3) {
|
||||
lightmap(0, b0);
|
||||
lightmap(1, b1);
|
||||
lightmap(2, b2);
|
||||
lightmap(3, b3);
|
||||
return this;
|
||||
MutableQuadView nominalFace(@Nullable Direction face);
|
||||
|
||||
/**
|
||||
* Assigns a different material to this quad. Useful for transformation of
|
||||
* existing meshes because lighting and texture blending are controlled by material.
|
||||
*/
|
||||
MutableQuadView material(RenderMaterial material);
|
||||
|
||||
/**
|
||||
* Value functions identically to {@link BakedQuad#getColorIndex()} and is
|
||||
* used by renderer / model builder in same way. Default value is -1.
|
||||
*/
|
||||
MutableQuadView colorIndex(int colorIndex);
|
||||
|
||||
/**
|
||||
* Encodes an integer tag with this quad that can later be retrieved via
|
||||
* {@link QuadView#tag()}. Useful for models that want to perform conditional
|
||||
* transformation or filtering on static meshes.
|
||||
*/
|
||||
MutableQuadView tag(int tag);
|
||||
|
||||
/**
|
||||
* Enables bulk vertex data transfer using the standard Minecraft vertex formats.
|
||||
* Only the {@link BakedQuad#getVertexData() quad vertex data} is copied.
|
||||
* This method should be performant whenever caller's vertex representation makes it feasible.
|
||||
*
|
||||
* <p>Use {@link #fromVanilla(BakedQuad, RenderMaterial, Direction) the other overload} which has better encapsulation
|
||||
* unless you have a specific reason to use this one.
|
||||
*
|
||||
* <p>Calling this method does not emit the quad.
|
||||
*
|
||||
* @apiNote The default implementation will be removed in the next breaking release.
|
||||
*/
|
||||
default MutableQuadView fromVanilla(int[] quadData, int startIndex) {
|
||||
return fromVanilla(quadData, startIndex, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set sprite color. Behavior for {@code spriteIndex > 0} is currently undefined.
|
||||
* Enables bulk vertex data transfer using the standard Minecraft quad format.
|
||||
*
|
||||
* <p>Calling this method does not emit the quad.
|
||||
*
|
||||
* <p>The material applied to this quad view might be slightly different from the {@code material} parameter regarding diffuse shading.
|
||||
* If either the baked quad {@link BakedQuad#hasShade() does not have shade} or the material {@link MaterialFinder#disableDiffuse(boolean) does not have shade},
|
||||
* diffuse shading will be disabled for this quad view.
|
||||
* This is reflected in the quad view's {@link #material()}, but the {@code material} parameter is unchanged (it is immutable anyway).
|
||||
*/
|
||||
MutableQuadView spriteColor(int vertexIndex, int spriteIndex, int color);
|
||||
MutableQuadView fromVanilla(BakedQuad quad, RenderMaterial material, @Nullable Direction cullFace);
|
||||
|
||||
/**
|
||||
* Convenience: set sprite color for all vertices at once. Behavior for {@code spriteIndex > 0} is currently undefined.
|
||||
* @deprecated Use {@link #color(int, int)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default MutableQuadView spriteColor(int vertexIndex, int spriteIndex, int color) {
|
||||
return color(vertexIndex, color);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #color(int, int, int, int)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default MutableQuadView spriteColor(int spriteIndex, int c0, int c1, int c2, int c3) {
|
||||
spriteColor(0, spriteIndex, c0);
|
||||
spriteColor(1, spriteIndex, c1);
|
||||
spriteColor(2, spriteIndex, c2);
|
||||
spriteColor(3, spriteIndex, c3);
|
||||
color(c0, c1, c2, c3);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set sprite atlas coordinates. Behavior for {@code spriteIndex > 0} is currently undefined.
|
||||
* @deprecated Use {@link #uv(int, float, float)} instead.
|
||||
*/
|
||||
MutableQuadView sprite(int vertexIndex, int spriteIndex, float u, float v);
|
||||
|
||||
/**
|
||||
* Set sprite atlas coordinates. Behavior for {@code spriteIndex > 0} is currently undefined.
|
||||
*
|
||||
* <p>Only use this function if you already have a {@link Vec2f}.
|
||||
* Otherwise, see {@link MutableQuadView#sprite(int, int, float, float)}.
|
||||
*/
|
||||
default MutableQuadView sprite(int vertexIndex, int spriteIndex, Vec2f uv) {
|
||||
return sprite(vertexIndex, spriteIndex, uv.x, uv.y);
|
||||
@Deprecated
|
||||
default MutableQuadView sprite(int vertexIndex, int spriteIndex, float u, float v) {
|
||||
return uv(vertexIndex, u, v);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns sprite atlas u,v coordinates to this quad for the given sprite.
|
||||
* Can handle UV locking, rotation, interpolation, etc. Control this behavior
|
||||
* by passing additive combinations of the BAKE_ flags defined in this interface.
|
||||
* Behavior for {@code spriteIndex > 0} is currently undefined.
|
||||
* @deprecated Use {@link #uv(int, Vector2f)} instead.
|
||||
*/
|
||||
MutableQuadView spriteBake(int spriteIndex, Sprite sprite, int bakeFlags);
|
||||
@Deprecated
|
||||
default MutableQuadView sprite(int vertexIndex, int spriteIndex, Vec2f uv) {
|
||||
return uv(vertexIndex, uv.x, uv.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #spriteBake(Sprite, int)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default MutableQuadView spriteBake(int spriteIndex, Sprite sprite, int bakeFlags) {
|
||||
return spriteBake(sprite, bakeFlags);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #fromVanilla(int[], int)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default MutableQuadView fromVanilla(int[] quadData, int startIndex, boolean isItem) {
|
||||
return fromVanilla(quadData, startIndex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package net.fabricmc.fabric.api.renderer.v1.mesh;
|
||||
|
||||
import org.joml.Vector2f;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
|
@ -38,36 +39,59 @@ import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
|||
* <p>Only the renderer should implement or extend this interface.
|
||||
*/
|
||||
public interface QuadEmitter extends MutableQuadView {
|
||||
@Override
|
||||
QuadEmitter material(RenderMaterial material);
|
||||
|
||||
@Override
|
||||
QuadEmitter cullFace(Direction face);
|
||||
|
||||
@Override
|
||||
QuadEmitter nominalFace(Direction face);
|
||||
|
||||
@Override
|
||||
QuadEmitter colorIndex(int colorIndex);
|
||||
|
||||
@Override
|
||||
QuadEmitter fromVanilla(int[] quadData, int startIndex, boolean isItem);
|
||||
|
||||
@Override
|
||||
QuadEmitter tag(int tag);
|
||||
|
||||
@Override
|
||||
QuadEmitter pos(int vertexIndex, float x, float y, float z);
|
||||
|
||||
@Override
|
||||
default QuadEmitter pos(int vertexIndex, Vector3f vec) {
|
||||
MutableQuadView.super.pos(vertexIndex, vec);
|
||||
default QuadEmitter pos(int vertexIndex, Vector3f pos) {
|
||||
MutableQuadView.super.pos(vertexIndex, pos);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @apiNote The default implementation will be removed in the next breaking release.
|
||||
*/
|
||||
@Override
|
||||
default QuadEmitter color(int vertexIndex, int color) {
|
||||
MutableQuadView.super.color(vertexIndex, color);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
default QuadEmitter normal(int vertexIndex, Vector3f vec) {
|
||||
MutableQuadView.super.normal(vertexIndex, vec);
|
||||
default QuadEmitter color(int c0, int c1, int c2, int c3) {
|
||||
MutableQuadView.super.color(c0, c1, c2, c3);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @apiNote The default implementation will be removed in the next breaking release.
|
||||
*/
|
||||
@Override
|
||||
default QuadEmitter uv(int vertexIndex, float u, float v) {
|
||||
MutableQuadView.super.uv(vertexIndex, u, v);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
default QuadEmitter uv(int vertexIndex, Vector2f uv) {
|
||||
MutableQuadView.super.uv(vertexIndex, uv);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @apiNote The default implementation will be removed in the next breaking release.
|
||||
*/
|
||||
@Override
|
||||
default QuadEmitter spriteBake(Sprite sprite, int bakeFlags) {
|
||||
MutableQuadView.super.spriteBake(sprite, bakeFlags);
|
||||
return this;
|
||||
}
|
||||
|
||||
default QuadEmitter uvUnitSquare() {
|
||||
uv(0, 0, 0);
|
||||
uv(1, 0, 1);
|
||||
uv(2, 1, 1);
|
||||
uv(3, 1, 0);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -80,38 +104,43 @@ public interface QuadEmitter extends MutableQuadView {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
QuadEmitter spriteColor(int vertexIndex, int spriteIndex, int color);
|
||||
// TODO: uncomment right before next breaking release
|
||||
// @Override
|
||||
// QuadEmitter normal(int vertexIndex, float x, float y, float z);
|
||||
|
||||
@Override
|
||||
default QuadEmitter spriteColor(int spriteIndex, int c0, int c1, int c2, int c3) {
|
||||
MutableQuadView.super.spriteColor(spriteIndex, c0, c1, c2, c3);
|
||||
default QuadEmitter normal(int vertexIndex, Vector3f normal) {
|
||||
MutableQuadView.super.normal(vertexIndex, normal);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
QuadEmitter sprite(int vertexIndex, int spriteIndex, float u, float v);
|
||||
QuadEmitter cullFace(Direction face);
|
||||
|
||||
@Override
|
||||
QuadEmitter nominalFace(Direction face);
|
||||
|
||||
@Override
|
||||
QuadEmitter material(RenderMaterial material);
|
||||
|
||||
@Override
|
||||
QuadEmitter colorIndex(int colorIndex);
|
||||
|
||||
@Override
|
||||
QuadEmitter tag(int tag);
|
||||
|
||||
/**
|
||||
* Set sprite atlas coordinates. Behavior for {@code spriteIndex > 0} is currently undefined.
|
||||
*
|
||||
* <p>Only use this function if you already have a {@link Vec2f}.
|
||||
* Otherwise, see {@link QuadEmitter#sprite(int, int, float, float)}.
|
||||
* @apiNote The default implementation will be removed in the next breaking release.
|
||||
*/
|
||||
default QuadEmitter sprite(int vertexIndex, int spriteIndex, Vec2f uv) {
|
||||
return sprite(vertexIndex, spriteIndex, uv.x, uv.y);
|
||||
}
|
||||
|
||||
default QuadEmitter spriteUnitSquare(int spriteIndex) {
|
||||
sprite(0, spriteIndex, 0, 0);
|
||||
sprite(1, spriteIndex, 0, 1);
|
||||
sprite(2, spriteIndex, 1, 1);
|
||||
sprite(3, spriteIndex, 1, 0);
|
||||
@Override
|
||||
default QuadEmitter fromVanilla(int[] quadData, int startIndex) {
|
||||
MutableQuadView.super.fromVanilla(quadData, startIndex);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
QuadEmitter spriteBake(int spriteIndex, Sprite sprite, int bakeFlags);
|
||||
// TODO: uncomment right before next breaking release
|
||||
// @Override
|
||||
// QuadEmitter fromVanilla(BakedQuad quad, RenderMaterial material, @Nullable Direction cullFace);
|
||||
|
||||
/**
|
||||
* Tolerance for determining if the depth parameter to {@link #square(Direction, float, float, float, float, float)}
|
||||
|
@ -185,4 +214,55 @@ public interface QuadEmitter extends MutableQuadView {
|
|||
* In both cases, current instance is reset to default values.
|
||||
*/
|
||||
QuadEmitter emit();
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
default QuadEmitter spriteColor(int vertexIndex, int spriteIndex, int color) {
|
||||
MutableQuadView.super.spriteColor(vertexIndex, spriteIndex, color);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
default QuadEmitter spriteColor(int spriteIndex, int c0, int c1, int c2, int c3) {
|
||||
MutableQuadView.super.spriteColor(spriteIndex, c0, c1, c2, c3);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
default QuadEmitter sprite(int vertexIndex, int spriteIndex, float u, float v) {
|
||||
MutableQuadView.super.sprite(vertexIndex, spriteIndex, u, v);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
default QuadEmitter sprite(int vertexIndex, int spriteIndex, Vec2f uv) {
|
||||
MutableQuadView.super.sprite(vertexIndex, spriteIndex, uv);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
default QuadEmitter spriteBake(int spriteIndex, Sprite sprite, int bakeFlags) {
|
||||
MutableQuadView.super.spriteBake(spriteIndex, sprite, bakeFlags);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #uvUnitSquare()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default QuadEmitter spriteUnitSquare(int spriteIndex) {
|
||||
uvUnitSquare();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
default QuadEmitter fromVanilla(int[] quadData, int startIndex, boolean isItem) {
|
||||
MutableQuadView.super.fromVanilla(quadData, startIndex, isItem);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package net.fabricmc.fabric.api.renderer.v1.mesh;
|
|||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Vector2f;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import net.minecraft.client.render.VertexFormats;
|
||||
|
@ -42,98 +43,24 @@ public interface QuadView {
|
|||
int VANILLA_QUAD_STRIDE = VANILLA_VERTEX_STRIDE * 4;
|
||||
|
||||
/**
|
||||
* Reads baked vertex data and outputs standard baked quad
|
||||
* vertex data in the given array and location.
|
||||
*
|
||||
* @param spriteIndex The sprite to be used for the quad.
|
||||
* Behavior for values > 0 is currently undefined.
|
||||
*
|
||||
* @param target Target array for the baked quad data.
|
||||
*
|
||||
* @param targetIndex Starting position in target array - array must have
|
||||
* at least 28 elements available at this index.
|
||||
*
|
||||
* @param isItem If true, will output vertex normals. Otherwise will output
|
||||
* lightmaps, per Minecraft vertex formats for baked models.
|
||||
* Retrieve geometric position, x coordinate.
|
||||
*/
|
||||
void toVanilla(int spriteIndex, int[] target, int targetIndex, boolean isItem);
|
||||
float x(int vertexIndex);
|
||||
|
||||
/**
|
||||
* Extracts all quad properties except material to the given {@link MutableQuadView} instance.
|
||||
* Must be used before calling {link QuadEmitter#emit()} on the target instance.
|
||||
* Meant for re-texturing, analysis and static transformation use cases.
|
||||
* Retrieve geometric position, y coordinate.
|
||||
*/
|
||||
void copyTo(MutableQuadView target);
|
||||
float y(int vertexIndex);
|
||||
|
||||
/**
|
||||
* Retrieves the material serialized with the quad.
|
||||
* Retrieve geometric position, z coordinate.
|
||||
*/
|
||||
RenderMaterial material();
|
||||
float z(int vertexIndex);
|
||||
|
||||
/**
|
||||
* Retrieves the quad color index serialized with the quad.
|
||||
* Convenience: access x, y, z by index 0-2.
|
||||
*/
|
||||
int colorIndex();
|
||||
|
||||
/**
|
||||
* Equivalent to {@link BakedQuad#getFace()}. This is the face used for vanilla lighting
|
||||
* calculations and will be the block face to which the quad is most closely aligned. Always
|
||||
* the same as cull face for quads that are on a block face, but never null.
|
||||
*/
|
||||
@NotNull
|
||||
Direction lightFace();
|
||||
|
||||
/**
|
||||
* If non-null, quad should not be rendered in-world if the
|
||||
* opposite face of a neighbor block occludes it.
|
||||
*
|
||||
* @see MutableQuadView#cullFace(Direction)
|
||||
*/
|
||||
@Nullable Direction cullFace();
|
||||
|
||||
/**
|
||||
* See {@link MutableQuadView#nominalFace(Direction)}.
|
||||
*/
|
||||
Direction nominalFace();
|
||||
|
||||
/**
|
||||
* Normal of the quad as implied by geometry. Will be invalid
|
||||
* if quad vertices are not co-planar. Typically computed lazily
|
||||
* on demand and not encoded.
|
||||
*
|
||||
* <p>Not typically needed by models. Exposed to enable standard lighting
|
||||
* utility functions for use by renderers.
|
||||
*/
|
||||
Vector3f faceNormal();
|
||||
|
||||
/**
|
||||
* Generates a new BakedQuad instance with texture
|
||||
* coordinates and colors from the given sprite.
|
||||
*
|
||||
* @param spriteIndex The sprite to be used for the quad.
|
||||
* Behavior for {@code spriteIndex > 0} is currently undefined.
|
||||
*
|
||||
* @param sprite {@link MutableQuadView} does not serialize sprites
|
||||
* so the sprite must be provided by the caller.
|
||||
*
|
||||
* @param isItem If true, will output vertex normals. Otherwise will output
|
||||
* lightmaps, per Minecraft vertex formats for baked models.
|
||||
*
|
||||
* @return A new baked quad instance with the closest-available appearance
|
||||
* supported by vanilla features. Will retain emissive light maps, for example,
|
||||
* but the standard Minecraft renderer will not use them.
|
||||
*/
|
||||
default BakedQuad toBakedQuad(int spriteIndex, Sprite sprite, boolean isItem) {
|
||||
int[] vertexData = new int[VANILLA_QUAD_STRIDE];
|
||||
toVanilla(spriteIndex, vertexData, 0, isItem);
|
||||
return new BakedQuad(vertexData, colorIndex(), lightFace(), sprite, true /* TODO:20w09a check me */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the integer tag encoded with this quad via {@link MutableQuadView#tag(int)}.
|
||||
* Will return zero if no tag was set. For use by models.
|
||||
*/
|
||||
int tag();
|
||||
float posByIndex(int vertexIndex, int coordinateIndex);
|
||||
|
||||
/**
|
||||
* Pass a non-null target to avoid allocation - will be returned with values.
|
||||
|
@ -142,24 +69,51 @@ public interface QuadView {
|
|||
Vector3f copyPos(int vertexIndex, @Nullable Vector3f target);
|
||||
|
||||
/**
|
||||
* Convenience: access x, y, z by index 0-2.
|
||||
* Retrieve vertex color.
|
||||
*
|
||||
* @apiNote The default implementation will be removed in the next breaking release.
|
||||
*/
|
||||
float posByIndex(int vertexIndex, int coordinateIndex);
|
||||
default int color(int vertexIndex) {
|
||||
return spriteColor(vertexIndex, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Geometric position, x coordinate.
|
||||
* Retrieve horizontal texture coordinates.
|
||||
*
|
||||
* @apiNote The default implementation will be removed in the next breaking release.
|
||||
*/
|
||||
float x(int vertexIndex);
|
||||
default float u(int vertexIndex) {
|
||||
return spriteU(vertexIndex, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Geometric position, y coordinate.
|
||||
* Retrieve vertical texture coordinates.
|
||||
*
|
||||
* @apiNote The default implementation will be removed in the next breaking release.
|
||||
*/
|
||||
float y(int vertexIndex);
|
||||
default float v(int vertexIndex) {
|
||||
return spriteV(vertexIndex, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Geometric position, z coordinate.
|
||||
* Pass a non-null target to avoid allocation - will be returned with values.
|
||||
* Otherwise returns a new instance.
|
||||
*
|
||||
* @apiNote The default implementation will be removed in the next breaking release.
|
||||
*/
|
||||
float z(int vertexIndex);
|
||||
default Vector2f copyUv(int vertexIndex, @Nullable Vector2f target) {
|
||||
if (target == null) {
|
||||
target = new Vector2f();
|
||||
}
|
||||
|
||||
target.set(u(vertexIndex), v(vertexIndex));
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimum block brightness. Zero if not set.
|
||||
*/
|
||||
int lightmap(int vertexIndex);
|
||||
|
||||
/**
|
||||
* If false, no vertex normal was provided.
|
||||
|
@ -167,13 +121,6 @@ public interface QuadView {
|
|||
*/
|
||||
boolean hasNormal(int vertexIndex);
|
||||
|
||||
/**
|
||||
* Pass a non-null target to avoid allocation - will be returned with values.
|
||||
* Otherwise returns a new instance. Returns null if normal not present.
|
||||
*/
|
||||
@Nullable
|
||||
Vector3f copyNormal(int vertexIndex, @Nullable Vector3f target);
|
||||
|
||||
/**
|
||||
* Will return {@link Float#NaN} if normal not present.
|
||||
*/
|
||||
|
@ -190,22 +137,138 @@ public interface QuadView {
|
|||
float normalZ(int vertexIndex);
|
||||
|
||||
/**
|
||||
* Minimum block brightness. Zero if not set.
|
||||
* Pass a non-null target to avoid allocation - will be returned with values.
|
||||
* Otherwise returns a new instance. Returns null if normal not present.
|
||||
*/
|
||||
int lightmap(int vertexIndex);
|
||||
@Nullable
|
||||
Vector3f copyNormal(int vertexIndex, @Nullable Vector3f target);
|
||||
|
||||
/**
|
||||
* Retrieve vertex color.
|
||||
* If non-null, quad should not be rendered in-world if the
|
||||
* opposite face of a neighbor block occludes it.
|
||||
*
|
||||
* @see MutableQuadView#cullFace(Direction)
|
||||
*/
|
||||
int spriteColor(int vertexIndex, int spriteIndex);
|
||||
@Nullable
|
||||
Direction cullFace();
|
||||
|
||||
/**
|
||||
* Retrieve horizontal sprite atlas coordinates.
|
||||
* Equivalent to {@link BakedQuad#getFace()}. This is the face used for vanilla lighting
|
||||
* calculations and will be the block face to which the quad is most closely aligned. Always
|
||||
* the same as cull face for quads that are on a block face, but never null.
|
||||
*/
|
||||
float spriteU(int vertexIndex, int spriteIndex);
|
||||
@NotNull
|
||||
Direction lightFace();
|
||||
|
||||
/**
|
||||
* Retrieve vertical sprite atlas coordinates.
|
||||
* See {@link MutableQuadView#nominalFace(Direction)}.
|
||||
*/
|
||||
float spriteV(int vertexIndex, int spriteIndex);
|
||||
Direction nominalFace();
|
||||
|
||||
/**
|
||||
* Normal of the quad as implied by geometry. Will be invalid
|
||||
* if quad vertices are not co-planar. Typically computed lazily
|
||||
* on demand and not encoded.
|
||||
*
|
||||
* <p>Not typically needed by models. Exposed to enable standard lighting
|
||||
* utility functions for use by renderers.
|
||||
*/
|
||||
Vector3f faceNormal();
|
||||
|
||||
/**
|
||||
* Retrieves the material serialized with the quad.
|
||||
*/
|
||||
RenderMaterial material();
|
||||
|
||||
/**
|
||||
* Retrieves the quad color index serialized with the quad.
|
||||
*/
|
||||
int colorIndex();
|
||||
|
||||
/**
|
||||
* Retrieves the integer tag encoded with this quad via {@link MutableQuadView#tag(int)}.
|
||||
* Will return zero if no tag was set. For use by models.
|
||||
*/
|
||||
int tag();
|
||||
|
||||
/**
|
||||
* Extracts all quad properties except material to the given {@link MutableQuadView} instance.
|
||||
* Must be used before calling {link QuadEmitter#emit()} on the target instance.
|
||||
* Meant for re-texturing, analysis and static transformation use cases.
|
||||
*/
|
||||
void copyTo(MutableQuadView target);
|
||||
|
||||
/**
|
||||
* Reads baked vertex data and outputs standard {@link BakedQuad#getVertexData() baked quad vertex data}
|
||||
* in the given array and location.
|
||||
*
|
||||
* @apiNote The default implementation will be removed in the next breaking release.
|
||||
*
|
||||
* @param target Target array for the baked quad data.
|
||||
*
|
||||
* @param targetIndex Starting position in target array - array must have
|
||||
* at least 28 elements available at this index.
|
||||
*/
|
||||
default void toVanilla(int[] target, int targetIndex) {
|
||||
toVanilla(0, target, targetIndex, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a new BakedQuad instance with texture
|
||||
* coordinates and colors from the given sprite.
|
||||
*
|
||||
* @param sprite {@link MutableQuadView} does not serialize sprites
|
||||
* so the sprite must be provided by the caller.
|
||||
*
|
||||
* @return A new baked quad instance with the closest-available appearance
|
||||
* supported by vanilla features. Will retain emissive light maps, for example,
|
||||
* but the standard Minecraft renderer will not use them.
|
||||
*/
|
||||
default BakedQuad toBakedQuad(Sprite sprite) {
|
||||
int[] vertexData = new int[VANILLA_QUAD_STRIDE];
|
||||
toVanilla(vertexData, 0);
|
||||
// TODO material inspection: set shade as !disableDiffuse
|
||||
// TODO material inspection: set color index to -1 if the material disables it
|
||||
return new BakedQuad(vertexData, colorIndex(), lightFace(), sprite, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #color(int)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default int spriteColor(int vertexIndex, int spriteIndex) {
|
||||
return color(vertexIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #u(int)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default float spriteU(int vertexIndex, int spriteIndex) {
|
||||
return u(vertexIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #v(int)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default float spriteV(int vertexIndex, int spriteIndex) {
|
||||
return v(vertexIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #toVanilla(int[], int)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default void toVanilla(int spriteIndex, int[] target, int targetIndex, boolean isItem) {
|
||||
toVanilla(target, targetIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #toBakedQuad(Sprite)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default BakedQuad toBakedQuad(int spriteIndex, Sprite sprite, boolean isItem) {
|
||||
return toBakedQuad(sprite);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,12 +84,8 @@ public final class ModelHelper {
|
|||
|
||||
if (mesh != null) {
|
||||
mesh.forEach(q -> {
|
||||
final int limit = q.material().spriteDepth();
|
||||
|
||||
for (int l = 0; l < limit; l++) {
|
||||
Direction face = q.cullFace();
|
||||
builders[face == null ? 6 : face.getId()].add(q.toBakedQuad(l, finder.find(q, l), false));
|
||||
}
|
||||
Direction cullFace = q.cullFace();
|
||||
builders[cullFace == null ? NULL_FACE_ID : cullFace.getId()].add(q.toBakedQuad(finder.find(q)));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package net.fabricmc.fabric.api.renderer.v1.model;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.client.texture.SpriteAtlasTexture;
|
||||
|
||||
|
@ -29,8 +31,9 @@ import net.fabricmc.fabric.impl.renderer.SpriteFinderImpl;
|
|||
* baked vertex coordinates. Main use is for {@link Mesh}-based models
|
||||
* to generate vanilla quads on demand without tracking and retaining
|
||||
* the sprites that were baked into the mesh. In other words, this class
|
||||
* supplies the sprite parameter for {@link QuadView#toBakedQuad(int, Sprite, boolean)}.
|
||||
* supplies the sprite parameter for {@link QuadView#toBakedQuad(Sprite)}.
|
||||
*/
|
||||
@ApiStatus.NonExtendable
|
||||
public interface SpriteFinder {
|
||||
/**
|
||||
* Retrieves or creates the finder for the given atlas.
|
||||
|
@ -51,13 +54,13 @@ public interface SpriteFinder {
|
|||
* Note that all the above refers to u,v coordinates. Geometric vertex does not matter,
|
||||
* except to the extent it was used to determine u,v.
|
||||
*/
|
||||
Sprite find(QuadView quad, int textureIndex);
|
||||
Sprite find(QuadView quad);
|
||||
|
||||
/**
|
||||
* Alternative to {@link #find(QuadView, int)} when vertex centroid is already
|
||||
* known or unsuitable. Expects normalized (0-1) coordinates on the atlas texture,
|
||||
* which should already be the case for u,v values in vanilla baked quads and in
|
||||
* {@link QuadView} after calling {@link MutableQuadView#spriteBake(int, Sprite, int)}.
|
||||
* {@link QuadView} after calling {@link MutableQuadView#spriteBake(Sprite, int)}.
|
||||
*
|
||||
* <p>Coordinates must be in the sprite interior for reliable results. Generally will
|
||||
* be easier to use {@link #find(QuadView, int)} unless you know the vertex
|
||||
|
@ -65,4 +68,12 @@ public interface SpriteFinder {
|
|||
* faster if you already have the centroid or another appropriate value.
|
||||
*/
|
||||
Sprite find(float u, float v);
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #find(QuadView)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default Sprite find(QuadView quad, int textureIndex) {
|
||||
return find(quad);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,8 @@ public interface RenderContext {
|
|||
* Fabric causes vanilla baked models to send themselves
|
||||
* via this interface. Can also be used by compound models that contain a mix
|
||||
* of vanilla baked models, packaged quads and/or dynamic elements.
|
||||
*
|
||||
* @apiNote The default implementation will be removed in the next breaking release.
|
||||
*/
|
||||
default BakedModelConsumer bakedModelConsumer() {
|
||||
// Default implementation is provided for compat with older renderer implementations,
|
||||
|
@ -64,43 +66,6 @@ public interface RenderContext {
|
|||
};
|
||||
}
|
||||
|
||||
interface BakedModelConsumer extends Consumer<BakedModel> {
|
||||
/**
|
||||
* Render a baked model by processing its {@linkplain BakedModel#getQuads} using the rendered block state.
|
||||
*
|
||||
* <p>For block contexts, this will pass the block state being rendered to {@link BakedModel#getQuads}.
|
||||
* For item contexts, this will pass a {@code null} block state to {@link BakedModel#getQuads}.
|
||||
* {@link #accept(BakedModel, BlockState)} can be used instead to pass the block state explicitly.
|
||||
*/
|
||||
@Override
|
||||
void accept(BakedModel model);
|
||||
|
||||
/**
|
||||
* Render a baked model by processing its {@linkplain BakedModel#getQuads} with an explicit block state.
|
||||
*
|
||||
* <p>This overload allows passing the block state (or {@code null} to query the item quads).
|
||||
* This is useful when a model is being wrapped, and expects a different
|
||||
* block state than the one of the block being rendered.
|
||||
*
|
||||
* <p>For item render contexts, you can use this function if you want to render the model with a specific block state.
|
||||
* Otherwise, use {@linkplain #accept(BakedModel)} the other overload} to render the usual item quads.
|
||||
*/
|
||||
void accept(BakedModel model, @Nullable BlockState state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fabric causes vanilla baked models to send themselves
|
||||
* via this interface. Can also be used by compound models that contain a mix
|
||||
* of vanilla baked models, packaged quads and/or dynamic elements.
|
||||
*
|
||||
* @deprecated Prefer using the more flexible {@link #bakedModelConsumer}.
|
||||
*/
|
||||
@Deprecated
|
||||
default Consumer<BakedModel> fallbackConsumer() {
|
||||
// This default implementation relies on implementors overriding bakedModelConsumer().
|
||||
return bakedModelConsumer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link QuadEmitter} instance that emits directly to the render buffer.
|
||||
* It remains necessary to call {@link QuadEmitter#emit()} to output the quad.
|
||||
|
@ -137,6 +102,43 @@ public interface RenderContext {
|
|||
*/
|
||||
void popTransform();
|
||||
|
||||
/**
|
||||
* Fabric causes vanilla baked models to send themselves
|
||||
* via this interface. Can also be used by compound models that contain a mix
|
||||
* of vanilla baked models, packaged quads and/or dynamic elements.
|
||||
*
|
||||
* @deprecated Prefer using the more flexible {@link #bakedModelConsumer}.
|
||||
*/
|
||||
@Deprecated
|
||||
default Consumer<BakedModel> fallbackConsumer() {
|
||||
// This default implementation relies on implementors overriding bakedModelConsumer().
|
||||
return bakedModelConsumer();
|
||||
}
|
||||
|
||||
interface BakedModelConsumer extends Consumer<BakedModel> {
|
||||
/**
|
||||
* Render a baked model by processing its {@linkplain BakedModel#getQuads} using the rendered block state.
|
||||
*
|
||||
* <p>For block contexts, this will pass the block state being rendered to {@link BakedModel#getQuads}.
|
||||
* For item contexts, this will pass a {@code null} block state to {@link BakedModel#getQuads}.
|
||||
* {@link #accept(BakedModel, BlockState)} can be used instead to pass the block state explicitly.
|
||||
*/
|
||||
@Override
|
||||
void accept(BakedModel model);
|
||||
|
||||
/**
|
||||
* Render a baked model by processing its {@linkplain BakedModel#getQuads} with an explicit block state.
|
||||
*
|
||||
* <p>This overload allows passing the block state (or {@code null} to query the item quads).
|
||||
* This is useful when a model is being wrapped, and expects a different
|
||||
* block state than the one of the block being rendered.
|
||||
*
|
||||
* <p>For item render contexts, you can use this function if you want to render the model with a specific block state.
|
||||
* Otherwise, use {@linkplain #accept(BakedModel)} the other overload} to render the usual item quads.
|
||||
*/
|
||||
void accept(BakedModel model, @Nullable BlockState state);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface QuadTransform {
|
||||
/**
|
||||
|
|
|
@ -53,13 +53,13 @@ public class SpriteFinderImpl implements SpriteFinder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Sprite find(QuadView quad, int textureIndex) {
|
||||
public Sprite find(QuadView quad) {
|
||||
float u = 0;
|
||||
float v = 0;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
u += quad.spriteU(i, textureIndex);
|
||||
v += quad.spriteV(i, textureIndex);
|
||||
u += quad.u(i);
|
||||
v += quad.v(i);
|
||||
}
|
||||
|
||||
return find(u * 0.25f, v * 0.25f);
|
||||
|
|
|
@ -58,9 +58,9 @@ final class FrameBakedModel implements BakedModel, FabricBakedModel {
|
|||
this.frameSprite = frameSprite;
|
||||
|
||||
MaterialFinder finder = RendererAccess.INSTANCE.getRenderer().materialFinder();
|
||||
this.translucentMaterial = finder.blendMode(0, BlendMode.TRANSLUCENT).find();
|
||||
this.translucentMaterial = finder.blendMode(BlendMode.TRANSLUCENT).find();
|
||||
finder.clear();
|
||||
this.translucentEmissiveMaterial = finder.blendMode(0, BlendMode.TRANSLUCENT).emissive(0, true).find();
|
||||
this.translucentEmissiveMaterial = finder.blendMode(BlendMode.TRANSLUCENT).emissive(true).find();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -173,11 +173,11 @@ final class FrameBakedModel implements BakedModel, FabricBakedModel {
|
|||
|
||||
// Change vertex colors to be partially transparent
|
||||
for (int vertex = 0; vertex < 4; ++vertex) {
|
||||
int color = quad.spriteColor(vertex, 0);
|
||||
int color = quad.color(vertex);
|
||||
int alpha = (color >> 24) & 0xFF;
|
||||
alpha = alpha * 3 / 4;
|
||||
color = (color & 0xFFFFFF) | (alpha << 24);
|
||||
quad.spriteColor(vertex, 0, color);
|
||||
quad.color(vertex, color);
|
||||
}
|
||||
|
||||
// Return true because we want the quad to be rendered
|
||||
|
|
|
@ -70,44 +70,44 @@ final class FrameUnbakedModel implements UnbakedModel {
|
|||
for (Direction direction : Direction.values()) {
|
||||
// Draw outer frame
|
||||
emitter.square(direction, 0.0F, 0.9F, 0.9F, 1.0F, 0.0F)
|
||||
.spriteBake(0, frameSprite, MutableQuadView.BAKE_LOCK_UV)
|
||||
.spriteColor(0, -1, -1, -1, -1)
|
||||
.spriteBake(frameSprite, MutableQuadView.BAKE_LOCK_UV)
|
||||
.color(-1, -1, -1, -1)
|
||||
.emit();
|
||||
|
||||
emitter.square(direction, 0.0F, 0.0F, 0.1F, 0.9F, 0.0F)
|
||||
.spriteBake(0, frameSprite, MutableQuadView.BAKE_LOCK_UV)
|
||||
.spriteColor(0, -1, -1, -1, -1)
|
||||
.spriteBake(frameSprite, MutableQuadView.BAKE_LOCK_UV)
|
||||
.color(-1, -1, -1, -1)
|
||||
.emit();
|
||||
|
||||
emitter.square(direction, 0.9F, 0.1F, 1.0F, 1.0F, 0.0F)
|
||||
.spriteBake(0, frameSprite, MutableQuadView.BAKE_LOCK_UV)
|
||||
.spriteColor(0, -1, -1, -1, -1)
|
||||
.spriteBake(frameSprite, MutableQuadView.BAKE_LOCK_UV)
|
||||
.color(-1, -1, -1, -1)
|
||||
.emit();
|
||||
|
||||
emitter.square(direction, 0.1F, 0.0F, 1.0F, 0.1F, 0.0F)
|
||||
.spriteBake(0, frameSprite, MutableQuadView.BAKE_LOCK_UV)
|
||||
.spriteColor(0, -1, -1, -1, -1)
|
||||
.spriteBake(frameSprite, MutableQuadView.BAKE_LOCK_UV)
|
||||
.color(-1, -1, -1, -1)
|
||||
.emit();
|
||||
|
||||
// Draw inner frame - inset by 0.9 so the frame looks like an actual mesh
|
||||
emitter.square(direction, 0.0F, 0.9F, 0.9F, 1.0F, 0.9F)
|
||||
.spriteBake(0, frameSprite, MutableQuadView.BAKE_LOCK_UV)
|
||||
.spriteColor(0, -1, -1, -1, -1)
|
||||
.spriteBake(frameSprite, MutableQuadView.BAKE_LOCK_UV)
|
||||
.color(-1, -1, -1, -1)
|
||||
.emit();
|
||||
|
||||
emitter.square(direction, 0.0F, 0.0F, 0.1F, 0.9F, 0.9F)
|
||||
.spriteBake(0, frameSprite, MutableQuadView.BAKE_LOCK_UV)
|
||||
.spriteColor(0, -1, -1, -1, -1)
|
||||
.spriteBake(frameSprite, MutableQuadView.BAKE_LOCK_UV)
|
||||
.color(-1, -1, -1, -1)
|
||||
.emit();
|
||||
|
||||
emitter.square(direction, 0.9F, 0.1F, 1.0F, 1.0F, 0.9F)
|
||||
.spriteBake(0, frameSprite, MutableQuadView.BAKE_LOCK_UV)
|
||||
.spriteColor(0, -1, -1, -1, -1)
|
||||
.spriteBake(frameSprite, MutableQuadView.BAKE_LOCK_UV)
|
||||
.color(-1, -1, -1, -1)
|
||||
.emit();
|
||||
|
||||
emitter.square(direction, 0.1F, 0.0F, 1.0F, 0.1F, 0.9F)
|
||||
.spriteBake(0, frameSprite, MutableQuadView.BAKE_LOCK_UV)
|
||||
.spriteColor(0, -1, -1, -1, -1)
|
||||
.spriteBake(frameSprite, MutableQuadView.BAKE_LOCK_UV)
|
||||
.color(-1, -1, -1, -1)
|
||||
.emit();
|
||||
}
|
||||
|
||||
|
|
|
@ -89,8 +89,8 @@ public class PillarBakedModel implements BakedModel, FabricBakedModel {
|
|||
}
|
||||
|
||||
emitter.square(side, 0, 0, 1, 1, 0);
|
||||
emitter.spriteBake(0, sprites[texture.ordinal()], MutableQuadView.BAKE_LOCK_UV);
|
||||
emitter.spriteColor(0, -1, -1, -1, -1);
|
||||
emitter.spriteBake(sprites[texture.ordinal()], MutableQuadView.BAKE_LOCK_UV);
|
||||
emitter.color(-1, -1, -1, -1);
|
||||
emitter.emit();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,13 +16,14 @@
|
|||
|
||||
package net.fabricmc.fabric.impl.client.indigo.renderer;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.util.Objects;
|
||||
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
import net.fabricmc.fabric.api.renderer.v1.material.BlendMode;
|
||||
import net.fabricmc.fabric.api.renderer.v1.material.MaterialFinder;
|
||||
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
|
||||
import net.fabricmc.fabric.api.util.TriState;
|
||||
|
||||
/**
|
||||
* Default implementation of the standard render materials.
|
||||
|
@ -32,13 +33,34 @@ import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
|
|||
*/
|
||||
public abstract class RenderMaterialImpl {
|
||||
private static final BlendMode[] BLEND_MODES = BlendMode.values();
|
||||
private static final int BLEND_MODE_COUNT = BLEND_MODES.length;
|
||||
private static final TriState[] TRI_STATES = TriState.values();
|
||||
private static final int TRI_STATE_COUNT = TRI_STATES.length;
|
||||
|
||||
private static final int BLEND_MODE_MASK = MathHelper.smallestEncompassingPowerOfTwo(BlendMode.values().length) - 1;
|
||||
private static final int COLOR_DISABLE_FLAG = BLEND_MODE_MASK + 1;
|
||||
private static final int EMISSIVE_FLAG = COLOR_DISABLE_FLAG << 1;
|
||||
private static final int DIFFUSE_FLAG = EMISSIVE_FLAG << 1;
|
||||
private static final int AO_FLAG = DIFFUSE_FLAG << 1;
|
||||
public static final int VALUE_COUNT = (AO_FLAG << 1);
|
||||
protected static final int BLEND_MODE_BIT_LENGTH = MathHelper.ceilLog2(BLEND_MODE_COUNT);
|
||||
protected static final int COLOR_DISABLE_BIT_LENGTH = 1;
|
||||
protected static final int EMISSIVE_BIT_LENGTH = 1;
|
||||
protected static final int DIFFUSE_BIT_LENGTH = 1;
|
||||
protected static final int AO_BIT_LENGTH = MathHelper.ceilLog2(TRI_STATE_COUNT);
|
||||
|
||||
protected static final int BLEND_MODE_BIT_OFFSET = 0;
|
||||
protected static final int COLOR_DISABLE_BIT_OFFSET = BLEND_MODE_BIT_OFFSET + BLEND_MODE_BIT_LENGTH;
|
||||
protected static final int EMISSIVE_BIT_OFFSET = COLOR_DISABLE_BIT_OFFSET + COLOR_DISABLE_BIT_LENGTH;
|
||||
protected static final int DIFFUSE_BIT_OFFSET = EMISSIVE_BIT_OFFSET + EMISSIVE_BIT_LENGTH;
|
||||
protected static final int AO_BIT_OFFSET = DIFFUSE_BIT_OFFSET + DIFFUSE_BIT_LENGTH;
|
||||
protected static final int TOTAL_BIT_LENGTH = AO_BIT_OFFSET + AO_BIT_LENGTH;
|
||||
|
||||
protected static final int BLEND_MODE_MASK = bitMask(BLEND_MODE_BIT_LENGTH, BLEND_MODE_BIT_OFFSET);
|
||||
protected static final int COLOR_DISABLE_FLAG = bitMask(COLOR_DISABLE_BIT_LENGTH, COLOR_DISABLE_BIT_OFFSET);
|
||||
protected static final int EMISSIVE_FLAG = bitMask(EMISSIVE_BIT_LENGTH, EMISSIVE_BIT_OFFSET);
|
||||
protected static final int DIFFUSE_FLAG = bitMask(DIFFUSE_BIT_LENGTH, DIFFUSE_BIT_OFFSET);
|
||||
protected static final int AO_MASK = bitMask(AO_BIT_LENGTH, AO_BIT_OFFSET);
|
||||
|
||||
public static final int VALUE_COUNT = 1 << TOTAL_BIT_LENGTH;
|
||||
|
||||
protected static int bitMask(int bitLength, int bitOffset) {
|
||||
return ((1 << bitLength) - 1) << bitOffset;
|
||||
}
|
||||
|
||||
private static final Value[] VALUES = new Value[VALUE_COUNT];
|
||||
|
||||
|
@ -52,8 +74,8 @@ public abstract class RenderMaterialImpl {
|
|||
return VALUES[index];
|
||||
}
|
||||
|
||||
public static Value setDisableDiffuse(Value material, int textureIndex, boolean disable) {
|
||||
if (material.disableDiffuse(textureIndex) != disable) {
|
||||
public static Value setDisableDiffuse(Value material, boolean disable) {
|
||||
if (material.disableDiffuse() != disable) {
|
||||
return byIndex(disable ? (material.bits | DIFFUSE_FLAG) : (material.bits & ~DIFFUSE_FLAG));
|
||||
}
|
||||
|
||||
|
@ -62,33 +84,45 @@ public abstract class RenderMaterialImpl {
|
|||
|
||||
protected int bits;
|
||||
|
||||
public BlendMode blendMode(int textureIndex) {
|
||||
return BLEND_MODES[bits & BLEND_MODE_MASK];
|
||||
protected RenderMaterialImpl(int bits) {
|
||||
this.bits = bits;
|
||||
}
|
||||
|
||||
public boolean disableColorIndex(int textureIndex) {
|
||||
public BlendMode blendMode() {
|
||||
int ordinal = (bits & BLEND_MODE_MASK) >> BLEND_MODE_BIT_OFFSET;
|
||||
|
||||
if (ordinal >= BLEND_MODE_COUNT) {
|
||||
return BlendMode.DEFAULT;
|
||||
}
|
||||
|
||||
return BLEND_MODES[ordinal];
|
||||
}
|
||||
|
||||
public boolean disableColorIndex() {
|
||||
return (bits & COLOR_DISABLE_FLAG) != 0;
|
||||
}
|
||||
|
||||
public int spriteDepth() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public boolean emissive(int textureIndex) {
|
||||
public boolean emissive() {
|
||||
return (bits & EMISSIVE_FLAG) != 0;
|
||||
}
|
||||
|
||||
public boolean disableDiffuse(int textureIndex) {
|
||||
public boolean disableDiffuse() {
|
||||
return (bits & DIFFUSE_FLAG) != 0;
|
||||
}
|
||||
|
||||
public boolean disableAo(int textureIndex) {
|
||||
return (bits & AO_FLAG) != 0;
|
||||
public TriState ambientOcclusion() {
|
||||
int ordinal = (bits & AO_MASK) >> AO_BIT_OFFSET;
|
||||
|
||||
if (ordinal >= TRI_STATE_COUNT) {
|
||||
return TriState.DEFAULT;
|
||||
}
|
||||
|
||||
return TRI_STATES[ordinal];
|
||||
}
|
||||
|
||||
public static class Value extends RenderMaterialImpl implements RenderMaterial {
|
||||
private Value(int bits) {
|
||||
this.bits = bits;
|
||||
super(bits);
|
||||
}
|
||||
|
||||
public int index() {
|
||||
|
@ -97,56 +131,61 @@ public abstract class RenderMaterialImpl {
|
|||
}
|
||||
|
||||
public static class Finder extends RenderMaterialImpl implements MaterialFinder {
|
||||
@Override
|
||||
public RenderMaterial find() {
|
||||
return VALUES[bits];
|
||||
private static int defaultBits = 0;
|
||||
|
||||
static {
|
||||
Finder finder = new Finder();
|
||||
finder.ambientOcclusion(TriState.DEFAULT);
|
||||
defaultBits = finder.bits;
|
||||
}
|
||||
|
||||
public Finder() {
|
||||
super(defaultBits);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaterialFinder clear() {
|
||||
bits = 0;
|
||||
public MaterialFinder blendMode(BlendMode blendMode) {
|
||||
Objects.requireNonNull(blendMode, "BlendMode may not be null");
|
||||
|
||||
bits = (bits & ~BLEND_MODE_MASK) | (blendMode.ordinal() << BLEND_MODE_BIT_OFFSET);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaterialFinder blendMode(int textureIndex, BlendMode blendMode) {
|
||||
if (blendMode == null) {
|
||||
blendMode = BlendMode.DEFAULT;
|
||||
}
|
||||
|
||||
bits = (bits & ~BLEND_MODE_MASK) | blendMode.ordinal();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaterialFinder disableColorIndex(int textureIndex, boolean disable) {
|
||||
public MaterialFinder disableColorIndex(boolean disable) {
|
||||
bits = disable ? (bits | COLOR_DISABLE_FLAG) : (bits & ~COLOR_DISABLE_FLAG);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaterialFinder spriteDepth(int depth) {
|
||||
Preconditions.checkArgument(depth == 1, "Unsupported sprite depth: %s", depth);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaterialFinder emissive(int textureIndex, boolean isEmissive) {
|
||||
public MaterialFinder emissive(boolean isEmissive) {
|
||||
bits = isEmissive ? (bits | EMISSIVE_FLAG) : (bits & ~EMISSIVE_FLAG);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaterialFinder disableDiffuse(int textureIndex, boolean disable) {
|
||||
public MaterialFinder disableDiffuse(boolean disable) {
|
||||
bits = disable ? (bits | DIFFUSE_FLAG) : (bits & ~DIFFUSE_FLAG);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaterialFinder disableAo(int textureIndex, boolean disable) {
|
||||
bits = disable ? (bits | AO_FLAG) : (bits & ~AO_FLAG);
|
||||
public MaterialFinder ambientOcclusion(TriState mode) {
|
||||
Objects.requireNonNull(mode, "ambient occlusion TriState may not be null");
|
||||
|
||||
bits = (bits & ~AO_MASK) | (mode.ordinal() << AO_BIT_OFFSET);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MaterialFinder clear() {
|
||||
bits = defaultBits;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderMaterial find() {
|
||||
return VALUES[bits];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -170,7 +170,7 @@ public abstract class AoCalculator {
|
|||
private void calcVanilla(MutableQuadViewImpl quad, float[] aoDest, int[] lightDest) {
|
||||
vanillaAoControlBits.clear();
|
||||
final Direction lightFace = quad.lightFace();
|
||||
quad.toVanilla(0, vertexData, 0, false);
|
||||
quad.toVanilla(vertexData, 0);
|
||||
|
||||
VanillaAoHelper.updateShape(blockInfo.blockView, blockInfo.blockState, blockInfo.blockPos, vertexData, lightFace, vanillaAoData, vanillaAoControlBits);
|
||||
vanillaCalc.apply(blockInfo.blockView, blockInfo.blockState, blockInfo.blockPos, lightFace, vanillaAoData, vanillaAoControlBits, quad.hasShade());
|
||||
|
|
|
@ -23,7 +23,7 @@ import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
|
|||
|
||||
/**
|
||||
* Handles most texture-baking use cases for model loaders and model libraries
|
||||
* via {@link #bakeSprite(MutableQuadView, int, Sprite, int)}. Also used by the API
|
||||
* via {@link #bakeSprite(MutableQuadView, Sprite, int)}. Also used by the API
|
||||
* itself to implement automatic block-breaking models for enhanced models.
|
||||
*/
|
||||
public class TextureHelper {
|
||||
|
@ -35,13 +35,13 @@ public class TextureHelper {
|
|||
* Bakes textures in the provided vertex data, handling UV locking,
|
||||
* rotation, interpolation, etc. Textures must not be already baked.
|
||||
*/
|
||||
public static void bakeSprite(MutableQuadView quad, int spriteIndex, Sprite sprite, int bakeFlags) {
|
||||
public static void bakeSprite(MutableQuadView quad, Sprite sprite, int bakeFlags) {
|
||||
if (quad.nominalFace() != null && (MutableQuadView.BAKE_LOCK_UV & bakeFlags) != 0) {
|
||||
// Assigns normalized UV coordinates based on vertex positions
|
||||
applyModifier(quad, spriteIndex, UVLOCKERS[quad.nominalFace().getId()]);
|
||||
applyModifier(quad, UVLOCKERS[quad.nominalFace().getId()]);
|
||||
} else if ((MutableQuadView.BAKE_NORMALIZED & bakeFlags) == 0) { // flag is NOT set, UVs are assumed to not be normalized yet as is the default, normalize through dividing by 16
|
||||
// Scales from 0-16 to 0-1
|
||||
applyModifier(quad, spriteIndex, (q, i, t) -> q.sprite(i, t, q.spriteU(i, t) * NORMALIZER, q.spriteV(i, t) * NORMALIZER));
|
||||
applyModifier(quad, (q, i) -> q.uv(i, q.u(i) * NORMALIZER, q.v(i) * NORMALIZER));
|
||||
}
|
||||
|
||||
final int rotation = bakeFlags & 3;
|
||||
|
@ -49,63 +49,63 @@ public class TextureHelper {
|
|||
if (rotation != 0) {
|
||||
// Rotates texture around the center of sprite.
|
||||
// Assumes normalized coordinates.
|
||||
applyModifier(quad, spriteIndex, ROTATIONS[rotation]);
|
||||
applyModifier(quad, ROTATIONS[rotation]);
|
||||
}
|
||||
|
||||
if ((MutableQuadView.BAKE_FLIP_U & bakeFlags) != 0) {
|
||||
// Inverts U coordinates. Assumes normalized (0-1) values.
|
||||
applyModifier(quad, spriteIndex, (q, i, t) -> q.sprite(i, t, 1 - q.spriteU(i, t), q.spriteV(i, t)));
|
||||
applyModifier(quad, (q, i) -> q.uv(i, 1 - q.u(i), q.v(i)));
|
||||
}
|
||||
|
||||
if ((MutableQuadView.BAKE_FLIP_V & bakeFlags) != 0) {
|
||||
// Inverts V coordinates. Assumes normalized (0-1) values.
|
||||
applyModifier(quad, spriteIndex, (q, i, t) -> q.sprite(i, t, q.spriteU(i, t), 1 - q.spriteV(i, t)));
|
||||
applyModifier(quad, (q, i) -> q.uv(i, q.u(i), 1 - q.v(i)));
|
||||
}
|
||||
|
||||
interpolate(quad, spriteIndex, sprite);
|
||||
interpolate(quad, sprite);
|
||||
}
|
||||
|
||||
/**
|
||||
* Faster than sprite method. Sprite computes span and normalizes inputs each call,
|
||||
* so we'd have to denormalize before we called, only to have the sprite renormalize immediately.
|
||||
*/
|
||||
private static void interpolate(MutableQuadView q, int spriteIndex, Sprite sprite) {
|
||||
private static void interpolate(MutableQuadView q, Sprite sprite) {
|
||||
final float uMin = sprite.getMinU();
|
||||
final float uSpan = sprite.getMaxU() - uMin;
|
||||
final float vMin = sprite.getMinV();
|
||||
final float vSpan = sprite.getMaxV() - vMin;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
q.sprite(i, spriteIndex, uMin + q.spriteU(i, spriteIndex) * uSpan, vMin + q.spriteV(i, spriteIndex) * vSpan);
|
||||
q.uv(i, uMin + q.u(i) * uSpan, vMin + q.v(i) * vSpan);
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
private interface VertexModifier {
|
||||
void apply(MutableQuadView quad, int vertexIndex, int spriteIndex);
|
||||
void apply(MutableQuadView quad, int vertexIndex);
|
||||
}
|
||||
|
||||
private static void applyModifier(MutableQuadView quad, int spriteIndex, VertexModifier modifier) {
|
||||
private static void applyModifier(MutableQuadView quad, VertexModifier modifier) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
modifier.apply(quad, i, spriteIndex);
|
||||
modifier.apply(quad, i);
|
||||
}
|
||||
}
|
||||
|
||||
private static final VertexModifier[] ROTATIONS = new VertexModifier[] {
|
||||
null,
|
||||
(q, i, t) -> q.sprite(i, t, q.spriteV(i, t), 1 - q.spriteU(i, t)), //90
|
||||
(q, i, t) -> q.sprite(i, t, 1 - q.spriteU(i, t), 1 - q.spriteV(i, t)), //180
|
||||
(q, i, t) -> q.sprite(i, t, 1 - q.spriteV(i, t), q.spriteU(i, t)) // 270
|
||||
(q, i) -> q.uv(i, q.v(i), 1 - q.u(i)), //90
|
||||
(q, i) -> q.uv(i, 1 - q.u(i), 1 - q.v(i)), //180
|
||||
(q, i) -> q.uv(i, 1 - q.v(i), q.u(i)) // 270
|
||||
};
|
||||
|
||||
private static final VertexModifier[] UVLOCKERS = new VertexModifier[6];
|
||||
|
||||
static {
|
||||
UVLOCKERS[Direction.EAST.getId()] = (q, i, t) -> q.sprite(i, t, 1 - q.z(i), 1 - q.y(i));
|
||||
UVLOCKERS[Direction.WEST.getId()] = (q, i, t) -> q.sprite(i, t, q.z(i), 1 - q.y(i));
|
||||
UVLOCKERS[Direction.NORTH.getId()] = (q, i, t) -> q.sprite(i, t, 1 - q.x(i), 1 - q.y(i));
|
||||
UVLOCKERS[Direction.SOUTH.getId()] = (q, i, t) -> q.sprite(i, t, q.x(i), 1 - q.y(i));
|
||||
UVLOCKERS[Direction.DOWN.getId()] = (q, i, t) -> q.sprite(i, t, q.x(i), 1 - q.z(i));
|
||||
UVLOCKERS[Direction.UP.getId()] = (q, i, t) -> q.sprite(i, t, q.x(i), q.z(i));
|
||||
UVLOCKERS[Direction.EAST.getId()] = (q, i) -> q.uv(i, 1 - q.z(i), 1 - q.y(i));
|
||||
UVLOCKERS[Direction.WEST.getId()] = (q, i) -> q.uv(i, q.z(i), 1 - q.y(i));
|
||||
UVLOCKERS[Direction.NORTH.getId()] = (q, i) -> q.uv(i, 1 - q.x(i), 1 - q.y(i));
|
||||
UVLOCKERS[Direction.SOUTH.getId()] = (q, i) -> q.uv(i, q.x(i), 1 - q.y(i));
|
||||
UVLOCKERS[Direction.DOWN.getId()] = (q, i) -> q.uv(i, q.x(i), 1 - q.z(i));
|
||||
UVLOCKERS[Direction.UP.getId()] = (q, i) -> q.uv(i, q.x(i), q.z(i));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ import static net.fabricmc.fabric.impl.client.indigo.renderer.mesh.EncodingForma
|
|||
import static net.fabricmc.fabric.impl.client.indigo.renderer.mesh.EncodingFormat.VERTEX_U;
|
||||
import static net.fabricmc.fabric.impl.client.indigo.renderer.mesh.EncodingFormat.VERTEX_X;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.minecraft.client.render.model.BakedQuad;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
|
@ -65,69 +65,6 @@ public abstract class MutableQuadViewImpl extends QuadViewImpl implements QuadEm
|
|||
material(IndigoRenderer.MATERIAL_STANDARD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final MutableQuadViewImpl material(RenderMaterial material) {
|
||||
if (material == null) {
|
||||
material = IndigoRenderer.MATERIAL_STANDARD;
|
||||
}
|
||||
|
||||
data[baseIndex + HEADER_BITS] = EncodingFormat.material(data[baseIndex + HEADER_BITS], (Value) material);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final MutableQuadViewImpl cullFace(Direction face) {
|
||||
data[baseIndex + HEADER_BITS] = EncodingFormat.cullFace(data[baseIndex + HEADER_BITS], face);
|
||||
nominalFace(face);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final MutableQuadViewImpl nominalFace(Direction face) {
|
||||
nominalFace = face;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final MutableQuadViewImpl colorIndex(int colorIndex) {
|
||||
data[baseIndex + HEADER_COLOR_INDEX] = colorIndex;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final MutableQuadViewImpl tag(int tag) {
|
||||
data[baseIndex + HEADER_TAG] = tag;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated will be removed in 1.17 cycle - see docs in interface
|
||||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
public final MutableQuadViewImpl fromVanilla(int[] quadData, int startIndex, boolean isItem) {
|
||||
System.arraycopy(quadData, startIndex, data, baseIndex + HEADER_STRIDE, QUAD_STRIDE);
|
||||
isGeometryInvalid = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final MutableQuadViewImpl fromVanilla(BakedQuad quad, RenderMaterial material, Direction cullFace) {
|
||||
System.arraycopy(quad.getVertexData(), 0, data, baseIndex + HEADER_STRIDE, QUAD_STRIDE);
|
||||
data[baseIndex + HEADER_BITS] = EncodingFormat.cullFace(0, cullFace);
|
||||
nominalFace(quad.getFace());
|
||||
colorIndex(quad.getColorIndex());
|
||||
|
||||
if (!quad.hasShade()) {
|
||||
material = RenderMaterialImpl.setDisableDiffuse((Value) material, 0, true);
|
||||
}
|
||||
|
||||
material(material);
|
||||
tag(0);
|
||||
isGeometryInvalid = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutableQuadViewImpl pos(int vertexIndex, float x, float y, float z) {
|
||||
final int index = baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_X;
|
||||
|
@ -138,6 +75,32 @@ public abstract class MutableQuadViewImpl extends QuadViewImpl implements QuadEm
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutableQuadViewImpl color(int vertexIndex, int color) {
|
||||
data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_COLOR] = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutableQuadViewImpl uv(int vertexIndex, float u, float v) {
|
||||
final int i = baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_U;
|
||||
data[i] = Float.floatToRawIntBits(u);
|
||||
data[i + 1] = Float.floatToRawIntBits(v);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutableQuadViewImpl spriteBake(Sprite sprite, int bakeFlags) {
|
||||
TextureHelper.bakeSprite(this, sprite, bakeFlags);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutableQuadViewImpl lightmap(int vertexIndex, int lightmap) {
|
||||
data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_LIGHTMAP] = lightmap;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected void normalFlags(int flags) {
|
||||
data[baseIndex + HEADER_BITS] = EncodingFormat.normalFlags(data[baseIndex + HEADER_BITS], flags);
|
||||
}
|
||||
|
@ -169,34 +132,60 @@ public abstract class MutableQuadViewImpl extends QuadViewImpl implements QuadEm
|
|||
}
|
||||
|
||||
@Override
|
||||
public MutableQuadViewImpl lightmap(int vertexIndex, int lightmap) {
|
||||
data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_LIGHTMAP] = lightmap;
|
||||
public final MutableQuadViewImpl cullFace(@Nullable Direction face) {
|
||||
data[baseIndex + HEADER_BITS] = EncodingFormat.cullFace(data[baseIndex + HEADER_BITS], face);
|
||||
nominalFace(face);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutableQuadViewImpl spriteColor(int vertexIndex, int spriteIndex, int color) {
|
||||
Preconditions.checkArgument(spriteIndex == 0, "Unsupported sprite index: %s", spriteIndex);
|
||||
|
||||
data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_COLOR] = color;
|
||||
public final MutableQuadViewImpl nominalFace(@Nullable Direction face) {
|
||||
nominalFace = face;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutableQuadViewImpl sprite(int vertexIndex, int spriteIndex, float u, float v) {
|
||||
Preconditions.checkArgument(spriteIndex == 0, "Unsupported sprite index: %s", spriteIndex);
|
||||
public final MutableQuadViewImpl material(RenderMaterial material) {
|
||||
if (material == null) {
|
||||
material = IndigoRenderer.MATERIAL_STANDARD;
|
||||
}
|
||||
|
||||
final int i = baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_U;
|
||||
data[i] = Float.floatToRawIntBits(u);
|
||||
data[i + 1] = Float.floatToRawIntBits(v);
|
||||
data[baseIndex + HEADER_BITS] = EncodingFormat.material(data[baseIndex + HEADER_BITS], (Value) material);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutableQuadViewImpl spriteBake(int spriteIndex, Sprite sprite, int bakeFlags) {
|
||||
Preconditions.checkArgument(spriteIndex == 0, "Unsupported sprite index: %s", spriteIndex);
|
||||
public final MutableQuadViewImpl colorIndex(int colorIndex) {
|
||||
data[baseIndex + HEADER_COLOR_INDEX] = colorIndex;
|
||||
return this;
|
||||
}
|
||||
|
||||
TextureHelper.bakeSprite(this, spriteIndex, sprite, bakeFlags);
|
||||
@Override
|
||||
public final MutableQuadViewImpl tag(int tag) {
|
||||
data[baseIndex + HEADER_TAG] = tag;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final MutableQuadViewImpl fromVanilla(int[] quadData, int startIndex) {
|
||||
System.arraycopy(quadData, startIndex, data, baseIndex + HEADER_STRIDE, QUAD_STRIDE);
|
||||
isGeometryInvalid = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final MutableQuadViewImpl fromVanilla(BakedQuad quad, RenderMaterial material, @Nullable Direction cullFace) {
|
||||
fromVanilla(quad.getVertexData(), 0);
|
||||
data[baseIndex + HEADER_BITS] = EncodingFormat.cullFace(0, cullFace);
|
||||
nominalFace(quad.getFace());
|
||||
colorIndex(quad.getColorIndex());
|
||||
|
||||
if (!quad.hasShade()) {
|
||||
material = RenderMaterialImpl.setDisableDiffuse((Value) material, true);
|
||||
}
|
||||
|
||||
material(material);
|
||||
tag(0);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,9 +30,13 @@ import static net.fabricmc.fabric.impl.client.indigo.renderer.mesh.EncodingForma
|
|||
import static net.fabricmc.fabric.impl.client.indigo.renderer.mesh.EncodingFormat.VERTEX_Y;
|
||||
import static net.fabricmc.fabric.impl.client.indigo.renderer.mesh.EncodingFormat.VERTEX_Z;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Vector2f;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import net.minecraft.client.render.model.BakedQuad;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.util.math.Direction;
|
||||
|
||||
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
|
||||
|
@ -114,76 +118,8 @@ public class QuadViewImpl implements QuadView {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void toVanilla(int textureIndex, int[] target, int targetIndex, boolean isItem) {
|
||||
System.arraycopy(data, baseIndex + VERTEX_X, target, targetIndex, QUAD_STRIDE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final RenderMaterialImpl.Value material() {
|
||||
return EncodingFormat.material(data[baseIndex + HEADER_BITS]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int colorIndex() {
|
||||
return data[baseIndex + HEADER_COLOR_INDEX];
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int tag() {
|
||||
return data[baseIndex + HEADER_TAG];
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Direction lightFace() {
|
||||
computeGeometry();
|
||||
return EncodingFormat.lightFace(data[baseIndex + HEADER_BITS]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Direction cullFace() {
|
||||
return EncodingFormat.cullFace(data[baseIndex + HEADER_BITS]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Direction nominalFace() {
|
||||
return nominalFace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Vector3f faceNormal() {
|
||||
computeGeometry();
|
||||
return faceNormal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyTo(MutableQuadView target) {
|
||||
computeGeometry();
|
||||
|
||||
final MutableQuadViewImpl quad = (MutableQuadViewImpl) target;
|
||||
// copy everything except the material
|
||||
RenderMaterial material = quad.material();
|
||||
System.arraycopy(data, baseIndex, quad.data, quad.baseIndex, EncodingFormat.TOTAL_STRIDE);
|
||||
quad.material(material);
|
||||
quad.faceNormal.set(faceNormal.x(), faceNormal.y(), faceNormal.z());
|
||||
quad.nominalFace = this.nominalFace;
|
||||
quad.isGeometryInvalid = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3f copyPos(int vertexIndex, Vector3f target) {
|
||||
if (target == null) {
|
||||
target = new Vector3f();
|
||||
}
|
||||
|
||||
final int index = baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_X;
|
||||
target.set(Float.intBitsToFloat(data[index]), Float.intBitsToFloat(data[index + 1]), Float.intBitsToFloat(data[index + 2]));
|
||||
return target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float posByIndex(int vertexIndex, int coordinateIndex) {
|
||||
return Float.intBitsToFloat(data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_X + coordinateIndex]);
|
||||
public boolean hasShade() {
|
||||
return !material().disableDiffuse();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -201,6 +137,53 @@ public class QuadViewImpl implements QuadView {
|
|||
return Float.intBitsToFloat(data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_Z]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float posByIndex(int vertexIndex, int coordinateIndex) {
|
||||
return Float.intBitsToFloat(data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_X + coordinateIndex]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3f copyPos(int vertexIndex, @Nullable Vector3f target) {
|
||||
if (target == null) {
|
||||
target = new Vector3f();
|
||||
}
|
||||
|
||||
final int index = baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_X;
|
||||
target.set(Float.intBitsToFloat(data[index]), Float.intBitsToFloat(data[index + 1]), Float.intBitsToFloat(data[index + 2]));
|
||||
return target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int color(int vertexIndex) {
|
||||
return data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_COLOR];
|
||||
}
|
||||
|
||||
@Override
|
||||
public float u(int vertexIndex) {
|
||||
return Float.intBitsToFloat(data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_U]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float v(int vertexIndex) {
|
||||
return Float.intBitsToFloat(data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_V]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector2f copyUv(int vertexIndex, @Nullable Vector2f target) {
|
||||
if (target == null) {
|
||||
target = new Vector2f();
|
||||
}
|
||||
|
||||
final int index = baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_U;
|
||||
target.set(Float.intBitsToFloat(data[index]), Float.intBitsToFloat(data[index + 1]));
|
||||
return target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lightmap(int vertexIndex) {
|
||||
return data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_LIGHTMAP];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNormal(int vertexIndex) {
|
||||
return (normalFlags() & (1 << vertexIndex)) != 0;
|
||||
|
@ -210,21 +193,6 @@ public class QuadViewImpl implements QuadView {
|
|||
return baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_NORMAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3f copyNormal(int vertexIndex, Vector3f target) {
|
||||
if (hasNormal(vertexIndex)) {
|
||||
if (target == null) {
|
||||
target = new Vector3f();
|
||||
}
|
||||
|
||||
final int normal = data[normalIndex(vertexIndex)];
|
||||
target.set(NormalHelper.getPackedNormalComponent(normal, 0), NormalHelper.getPackedNormalComponent(normal, 1), NormalHelper.getPackedNormalComponent(normal, 2));
|
||||
return target;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float normalX(int vertexIndex) {
|
||||
return hasNormal(vertexIndex) ? NormalHelper.getPackedNormalComponent(data[normalIndex(vertexIndex)], 0) : Float.NaN;
|
||||
|
@ -241,32 +209,88 @@ public class QuadViewImpl implements QuadView {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int lightmap(int vertexIndex) {
|
||||
return data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_LIGHTMAP];
|
||||
@Nullable
|
||||
public Vector3f copyNormal(int vertexIndex, @Nullable Vector3f target) {
|
||||
if (hasNormal(vertexIndex)) {
|
||||
if (target == null) {
|
||||
target = new Vector3f();
|
||||
}
|
||||
|
||||
final int normal = data[normalIndex(vertexIndex)];
|
||||
target.set(NormalHelper.getPackedNormalComponent(normal, 0), NormalHelper.getPackedNormalComponent(normal, 1), NormalHelper.getPackedNormalComponent(normal, 2));
|
||||
return target;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int spriteColor(int vertexIndex, int spriteIndex) {
|
||||
Preconditions.checkArgument(spriteIndex == 0, "Unsupported sprite index: %s", spriteIndex);
|
||||
|
||||
return data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_COLOR];
|
||||
@Nullable
|
||||
public final Direction cullFace() {
|
||||
return EncodingFormat.cullFace(data[baseIndex + HEADER_BITS]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float spriteU(int vertexIndex, int spriteIndex) {
|
||||
Preconditions.checkArgument(spriteIndex == 0, "Unsupported sprite index: %s", spriteIndex);
|
||||
|
||||
return Float.intBitsToFloat(data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_U]);
|
||||
@NotNull
|
||||
public final Direction lightFace() {
|
||||
computeGeometry();
|
||||
return EncodingFormat.lightFace(data[baseIndex + HEADER_BITS]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float spriteV(int vertexIndex, int spriteIndex) {
|
||||
Preconditions.checkArgument(spriteIndex == 0, "Unsupported sprite index: %s", spriteIndex);
|
||||
|
||||
return Float.intBitsToFloat(data[baseIndex + vertexIndex * VERTEX_STRIDE + VERTEX_V]);
|
||||
public final Direction nominalFace() {
|
||||
return nominalFace;
|
||||
}
|
||||
|
||||
public boolean hasShade() {
|
||||
return !material().disableDiffuse(0);
|
||||
@Override
|
||||
public final Vector3f faceNormal() {
|
||||
computeGeometry();
|
||||
return faceNormal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final RenderMaterialImpl.Value material() {
|
||||
return EncodingFormat.material(data[baseIndex + HEADER_BITS]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int colorIndex() {
|
||||
return data[baseIndex + HEADER_COLOR_INDEX];
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int tag() {
|
||||
return data[baseIndex + HEADER_TAG];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyTo(MutableQuadView target) {
|
||||
computeGeometry();
|
||||
|
||||
final MutableQuadViewImpl quad = (MutableQuadViewImpl) target;
|
||||
// copy everything except the material
|
||||
RenderMaterial material = quad.material();
|
||||
System.arraycopy(data, baseIndex, quad.data, quad.baseIndex, EncodingFormat.TOTAL_STRIDE);
|
||||
quad.material(material);
|
||||
quad.faceNormal.set(faceNormal);
|
||||
quad.nominalFace = this.nominalFace;
|
||||
quad.isGeometryInvalid = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void toVanilla(int[] target, int targetIndex) {
|
||||
System.arraycopy(data, baseIndex + VERTEX_X, target, targetIndex, QUAD_STRIDE);
|
||||
}
|
||||
|
||||
// TODO material inspection: remove
|
||||
@Override
|
||||
public final BakedQuad toBakedQuad(Sprite sprite) {
|
||||
int[] vertexData = new int[VANILLA_QUAD_STRIDE];
|
||||
toVanilla(vertexData, 0);
|
||||
|
||||
// Mimic material properties to the largest possible extent
|
||||
int outputColorIndex = material().disableColorIndex() ? -1 : colorIndex();
|
||||
boolean outputShade = !material().disableDiffuse();
|
||||
return new BakedQuad(vertexData, outputColorIndex, lightFace(), sprite, outputShade);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ import net.minecraft.util.math.BlockPos;
|
|||
import net.minecraft.util.math.Direction;
|
||||
|
||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext.QuadTransform;
|
||||
import net.fabricmc.fabric.api.util.TriState;
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.RenderMaterialImpl;
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.aocalc.AoCalculator;
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.helper.ColorHelper;
|
||||
|
@ -72,29 +73,30 @@ public abstract class AbstractQuadRenderer {
|
|||
return;
|
||||
}
|
||||
|
||||
tessellateQuad(quad, 0, isVanilla);
|
||||
tessellateQuad(quad, isVanilla);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines color index and render layer, then routes to appropriate
|
||||
* tessellate routine based on material properties.
|
||||
*/
|
||||
private void tessellateQuad(MutableQuadViewImpl quad, int textureIndex, boolean isVanilla) {
|
||||
private void tessellateQuad(MutableQuadViewImpl quad, boolean isVanilla) {
|
||||
final RenderMaterialImpl.Value mat = quad.material();
|
||||
final int colorIndex = mat.disableColorIndex(textureIndex) ? -1 : quad.colorIndex();
|
||||
final RenderLayer renderLayer = blockInfo.effectiveRenderLayer(mat.blendMode(textureIndex));
|
||||
final int colorIndex = mat.disableColorIndex() ? -1 : quad.colorIndex();
|
||||
final RenderLayer renderLayer = blockInfo.effectiveRenderLayer(mat.blendMode());
|
||||
final TriState ao = mat.ambientOcclusion();
|
||||
|
||||
if (blockInfo.defaultAo && !mat.disableAo(textureIndex)) {
|
||||
if (blockInfo.useAo && (ao == TriState.TRUE || (ao == TriState.DEFAULT && blockInfo.defaultAo))) {
|
||||
// needs to happen before offsets are applied
|
||||
aoCalc.compute(quad, isVanilla);
|
||||
|
||||
if (mat.emissive(textureIndex)) {
|
||||
if (mat.emissive()) {
|
||||
tessellateSmoothEmissive(quad, renderLayer, colorIndex);
|
||||
} else {
|
||||
tessellateSmooth(quad, renderLayer, colorIndex);
|
||||
}
|
||||
} else {
|
||||
if (mat.emissive(textureIndex)) {
|
||||
if (mat.emissive()) {
|
||||
tessellateFlatEmissive(quad, renderLayer, colorIndex);
|
||||
} else {
|
||||
tessellateFlat(quad, renderLayer, colorIndex);
|
||||
|
@ -106,13 +108,13 @@ public abstract class AbstractQuadRenderer {
|
|||
private void colorizeQuad(MutableQuadViewImpl q, int blockColorIndex) {
|
||||
if (blockColorIndex == -1) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
q.spriteColor(i, 0, ColorHelper.swapRedBlueIfNeeded(q.spriteColor(i, 0)));
|
||||
q.color(i, ColorHelper.swapRedBlueIfNeeded(q.color(i)));
|
||||
}
|
||||
} else {
|
||||
final int blockColor = blockInfo.blockColor(blockColorIndex);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
q.spriteColor(i, 0, ColorHelper.swapRedBlueIfNeeded(ColorHelper.multiplyColor(blockColor, q.spriteColor(i, 0))));
|
||||
q.color(i, ColorHelper.swapRedBlueIfNeeded(ColorHelper.multiplyColor(blockColor, q.color(i))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -128,21 +130,20 @@ public abstract class AbstractQuadRenderer {
|
|||
if (useNormals) {
|
||||
quad.populateMissingNormals();
|
||||
} else {
|
||||
final Vector3f faceNormal = quad.faceNormal();
|
||||
normalVec.set(faceNormal.x(), faceNormal.y(), faceNormal.z());
|
||||
normalVec.set(quad.faceNormal());
|
||||
normalVec.mul(normalMatrix);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
buff.vertex(matrix, quad.x(i), quad.y(i), quad.z(i));
|
||||
final int color = quad.spriteColor(i, 0);
|
||||
final int color = quad.color(i);
|
||||
buff.color(color & 0xFF, (color >> 8) & 0xFF, (color >> 16) & 0xFF, (color >> 24) & 0xFF);
|
||||
buff.texture(quad.spriteU(i, 0), quad.spriteV(i, 0));
|
||||
buff.texture(quad.u(i), quad.v(i));
|
||||
buff.overlay(overlay);
|
||||
buff.light(quad.lightmap(i));
|
||||
|
||||
if (useNormals) {
|
||||
normalVec.set(quad.normalX(i), quad.normalY(i), quad.normalZ(i));
|
||||
quad.copyNormal(i, normalVec);
|
||||
normalVec.mul(normalMatrix);
|
||||
}
|
||||
|
||||
|
@ -158,7 +159,7 @@ public abstract class AbstractQuadRenderer {
|
|||
colorizeQuad(q, blockColorIndex);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
q.spriteColor(i, 0, ColorHelper.multiplyRGB(q.spriteColor(i, 0), aoCalc.ao[i]));
|
||||
q.color(i, ColorHelper.multiplyRGB(q.color(i), aoCalc.ao[i]));
|
||||
q.lightmap(i, ColorHelper.maxBrightness(q.lightmap(i), aoCalc.light[i]));
|
||||
}
|
||||
|
||||
|
@ -170,7 +171,7 @@ public abstract class AbstractQuadRenderer {
|
|||
colorizeQuad(q, blockColorIndex);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
q.spriteColor(i, 0, ColorHelper.multiplyRGB(q.spriteColor(i, 0), aoCalc.ao[i]));
|
||||
q.color(i, ColorHelper.multiplyRGB(q.color(i), aoCalc.ao[i]));
|
||||
q.lightmap(i, LightmapTextureManager.MAX_LIGHT_COORDINATE);
|
||||
}
|
||||
|
||||
|
@ -240,14 +241,14 @@ public abstract class AbstractQuadRenderer {
|
|||
final float faceShade = blockInfo.blockView.getBrightness(quad.lightFace(), quad.hasShade());
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
quad.spriteColor(i, 0, ColorHelper.multiplyRGB(quad.spriteColor(i, 0), vertexShade(quad, i, faceShade)));
|
||||
quad.color(i, ColorHelper.multiplyRGB(quad.color(i), vertexShade(quad, i, faceShade)));
|
||||
}
|
||||
} else {
|
||||
final float diffuseShade = blockInfo.blockView.getBrightness(quad.lightFace(), quad.hasShade());
|
||||
|
||||
if (diffuseShade != 1.0f) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
quad.spriteColor(i, 0, ColorHelper.multiplyRGB(quad.spriteColor(i, 0), diffuseShade));
|
||||
quad.color(i, ColorHelper.multiplyRGB(quad.color(i), diffuseShade));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ public class BlockRenderInfo {
|
|||
public BlockPos blockPos;
|
||||
public BlockState blockState;
|
||||
public long seed;
|
||||
boolean useAo;
|
||||
boolean defaultAo;
|
||||
RenderLayer defaultLayer;
|
||||
|
||||
|
@ -78,7 +79,8 @@ public class BlockRenderInfo {
|
|||
this.blockState = blockState;
|
||||
// in the unlikely case seed actually matches this, we'll simply retrieve it more than once
|
||||
seed = -1L;
|
||||
defaultAo = modelAO && MinecraftClient.isAmbientOcclusionEnabled() && blockState.getLuminance() == 0;
|
||||
useAo = MinecraftClient.isAmbientOcclusionEnabled();
|
||||
defaultAo = useAo && modelAO && blockState.getLuminance() == 0;
|
||||
|
||||
defaultLayer = RenderLayers.getBlockLayer(blockState);
|
||||
|
||||
|
|
|
@ -185,13 +185,13 @@ public class ItemRenderContext extends AbstractRenderContext {
|
|||
private void colorizeQuad(MutableQuadViewImpl q, int colorIndex) {
|
||||
if (colorIndex == -1) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
q.spriteColor(i, 0, ColorHelper.swapRedBlueIfNeeded(q.spriteColor(i, 0)));
|
||||
q.color(i, ColorHelper.swapRedBlueIfNeeded(q.color(i)));
|
||||
}
|
||||
} else {
|
||||
final int itemColor = 0xFF000000 | colorMap.getColor(itemStack, colorIndex);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
q.spriteColor(i, 0, ColorHelper.swapRedBlueIfNeeded(ColorHelper.multiplyColor(itemColor, q.spriteColor(i, 0))));
|
||||
q.color(i, ColorHelper.swapRedBlueIfNeeded(ColorHelper.multiplyColor(itemColor, q.color(i))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -225,10 +225,10 @@ public class ItemRenderContext extends AbstractRenderContext {
|
|||
|
||||
final RenderMaterialImpl.Value mat = quad.material();
|
||||
|
||||
final int colorIndex = mat.disableColorIndex(0) ? -1 : quad.colorIndex();
|
||||
final BlendMode blendMode = mat.blendMode(0);
|
||||
final int colorIndex = mat.disableColorIndex() ? -1 : quad.colorIndex();
|
||||
final BlendMode blendMode = mat.blendMode();
|
||||
|
||||
if (mat.emissive(0)) {
|
||||
if (mat.emissive()) {
|
||||
renderQuadEmissive(quad, blendMode, colorIndex);
|
||||
} else {
|
||||
renderQuad(quad, blendMode, colorIndex);
|
||||
|
|
|
@ -34,6 +34,7 @@ import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
|
|||
import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper;
|
||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext.QuadTransform;
|
||||
import net.fabricmc.fabric.api.util.TriState;
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.IndigoRenderer;
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.RenderMaterialImpl.Value;
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.aocalc.AoCalculator;
|
||||
|
@ -60,7 +61,7 @@ import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.MutableQuadViewImpl;
|
|||
* manipulating the data via NIO.
|
||||
*/
|
||||
public abstract class TerrainFallbackConsumer extends AbstractQuadRenderer implements RenderContext.BakedModelConsumer {
|
||||
private static final Value MATERIAL_FLAT = (Value) IndigoRenderer.INSTANCE.materialFinder().disableAo(0, true).find();
|
||||
private static final Value MATERIAL_FLAT = (Value) IndigoRenderer.INSTANCE.materialFinder().ambientOcclusion(TriState.FALSE).find();
|
||||
private static final Value MATERIAL_SHADED = (Value) IndigoRenderer.INSTANCE.materialFinder().find();
|
||||
|
||||
TerrainFallbackConsumer(BlockRenderInfo blockInfo, Function<RenderLayer, VertexConsumer> bufferFunc, AoCalculator aoCalc, QuadTransform transform) {
|
||||
|
@ -88,7 +89,7 @@ public abstract class TerrainFallbackConsumer extends AbstractQuadRenderer imple
|
|||
@Override
|
||||
public void accept(BakedModel model, @Nullable BlockState blockState) {
|
||||
final Supplier<Random> random = blockInfo.randomSupplier;
|
||||
final Value defaultMaterial = blockInfo.defaultAo && model.useAmbientOcclusion() ? MATERIAL_SHADED : MATERIAL_FLAT;
|
||||
final Value defaultMaterial = model.useAmbientOcclusion() ? MATERIAL_SHADED : MATERIAL_FLAT;
|
||||
|
||||
for (int i = 0; i <= ModelHelper.NULL_FACE_ID; i++) {
|
||||
final Direction cullFace = ModelHelper.faceFromIndex(i);
|
||||
|
|
Loading…
Reference in a new issue