Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fabric Rendering API #65

Closed
wants to merge 120 commits into from
Closed
Show file tree
Hide file tree
Changes from 100 commits
Commits
Show all changes
120 commits
Select commit Hold shift + click to select a range
c3d7152
Initial commit of alternate modeling PR
grondag Jan 12, 2019
7db062e
Add headers
grondag Jan 12, 2019
782c79d
Mostly docs
grondag Jan 13, 2019
bb4f10f
Honor new interface (null vs false)
grondag Jan 13, 2019
bfc1bd5
Useful shade attributes to avoid == tests
grondag Jan 14, 2019
ecb2d65
Be consistent with MC baked quad factory
grondag Jan 14, 2019
c3f1bf1
Materials expose quad stride and transient index
grondag Jan 14, 2019
6c31073
Define and explain standard materials
grondag Jan 14, 2019
c47a9e0
ModelBuilder -> FastVertexBuilder
grondag Jan 14, 2019
613fa61
Avoid special cases
grondag Jan 14, 2019
1cec2e8
Refactor vertex consumer/producer interfaces
grondag Jan 15, 2019
3f34f9b
Ensure thread safety for dynamic render block entities
grondag Jan 15, 2019
2b5a9ab
Vertex builder can optimize if it knows cull face
grondag Jan 15, 2019
fedc865
Enable damage model creation from renderer-packed vertices
grondag Jan 18, 2019
e3b6ba3
Make vertex builder less stateful/complicated
grondag Jan 18, 2019
e1244d6
Consistent, fast hook for vanilla baked models
grondag Jan 18, 2019
0d1c08c
Material properties more useful to models than I expected...
grondag Jan 20, 2019
8a21d39
Minor doc/format fixes
grondag Jan 20, 2019
7bc5268
Add TODOs for possible changes before final, minor docs
grondag Jan 21, 2019
6a50494
Make VertexBuilder end() explicit +doc cleanup
grondag Jan 21, 2019
6886d08
Renderer serilizes materal and colorIndex...
grondag Jan 21, 2019
38abfe8
VertexBuilder -> QuadBuilder
grondag Jan 25, 2019
d4e21e4
Revert "VertexBuilder -> QuadBuilder"
grondag Jan 25, 2019
3798eb4
VertexBuilder -> QuadPackager
grondag Jan 25, 2019
80b6285
DynamicVertexConsumer -> ModelRenderContext...
grondag Jan 25, 2019
85d9765
Do these in follow-on PR
grondag Jan 25, 2019
1f1afaf
No longer needed
grondag Jan 25, 2019
9f4bca1
FastVertexBuilder replaced by QuadPackager
grondag Jan 25, 2019
4e00a68
VertexProducer -> BlockModelQuadProducer
grondag Jan 25, 2019
30dfc74
Docs
grondag Jan 25, 2019
7aa285b
QuadReader -> PackagedQuadReader
grondag Jan 25, 2019
dcb9cc3
Remove getVertexReader()
grondag Jan 25, 2019
92ca41d
Remove quad stride, docs
grondag Jan 25, 2019
6be7a97
*sigh*
grondag Jan 25, 2019
f0e8dcb
consumer -> context
grondag Jan 25, 2019
e9c20f3
Direction helper no longer needed
grondag Jan 25, 2019
8e575c3
Clean up BakedMode, BlockEntity mixins
grondag Jan 25, 2019
79e64ca
PackagedQuad -> Mesh / Quad
grondag Jan 28, 2019
1eff936
QuadPackager -> MeshBuilder
grondag Jan 28, 2019
8d5b780
ShadingMode -> two booleans
grondag Jan 28, 2019
9ae463b
QuadMaker, Vertex
grondag Jan 28, 2019
2ca9192
ShadingMode -> two booleans
grondag Jan 28, 2019
a0db7f6
Last bit of ShadingMode
grondag Jan 28, 2019
044b890
Class name concision
grondag Jan 28, 2019
7f171cb
Missed name change
grondag Jan 28, 2019
47932c2
Clean up, explain materials. Add shader API.
grondag Jan 28, 2019
d968199
Docs and cleanup
grondag Jan 28, 2019
16138d5
Minecraft -> Vanilla
grondag Jan 29, 2019
394c868
Preseve shader author sanity...
grondag Jan 29, 2019
0d20966
Help conditional mesh processing. Another Minecraft -> Vanilla.
grondag Jan 29, 2019
99014b6
Allow direct-to-buffer dynamic render
grondag Jan 29, 2019
854d4d5
BlockModelQuadProducer -> TerrainMeshProducer. Docs.
grondag Jan 29, 2019
9de4b86
Docs, name tweaks, strip non-essentials
grondag Jan 29, 2019
ce20a29
Clean up stragglers in docs, minor name/doc tweaks
grondag Jan 29, 2019
e316b01
Document vertex attribute shader bindings
grondag Jan 29, 2019
7a1370b
Merge remote-tracking branch 'upstream/master' into alternate
grondag Jan 29, 2019
1072df3
Make MaterialFinder more convenient
grondag Jan 29, 2019
c876353
Docs
grondag Jan 30, 2019
491afe7
Convenient vertex iteration
grondag Jan 30, 2019
1f26582
Immutable quads have vertices too...
grondag Feb 1, 2019
d845f14
Return mutable instance
grondag Feb 1, 2019
5b33f4a
Convenience methods for vector inputs
grondag Feb 2, 2019
931f63a
Custom block-breaking renders
grondag Feb 6, 2019
c784da6
Add hooks for item rendering and edge-case block renders.
grondag Feb 8, 2019
9027d5a
Pencil in suggested cacheability feature
grondag Feb 9, 2019
0a10bf5
Remove produceFeatureQuads
grondag Feb 9, 2019
ac3c62d
Derp
grondag Feb 9, 2019
e4a986b
Remove getItemGlowModel()
grondag Feb 9, 2019
7c217ce
Minor docs
grondag Feb 9, 2019
d9a6b11
Correct docs
grondag Feb 9, 2019
9f525aa
Make name suck less
grondag Feb 10, 2019
8c5b296
ModelBlockView -> TerrainBlockView
grondag Feb 10, 2019
2364cee
Combine block/terrain producers, simplify caching
grondag Feb 10, 2019
e0041be
Merge remote-tracking branch 'upstream/master' into alternate
grondag Feb 10, 2019
9d344ab
Add TextureHelper
grondag Feb 16, 2019
0f96968
Handle block breaking renders in the API directly
grondag Feb 16, 2019
2ca7791
Handle off-thread calls
grondag Feb 16, 2019
bfae10f
Clarify name
grondag Feb 16, 2019
2b4b441
Last few bits
grondag Feb 16, 2019
f69acf3
MultiLayer -> MultiTexture
grondag Feb 16, 2019
3e5a320
Names, fix a bug in BE state cacheing
grondag Feb 17, 2019
943dbff
Make Random access lazy, more concise
grondag Feb 17, 2019
5598e3a
Fix typo
grondag Feb 17, 2019
6735fb0
Collapse Vertex into Quad
grondag Feb 17, 2019
4acf9e7
Stronger error checks on Renderer registration
grondag Feb 18, 2019
198e40b
Pass TerrainBlockView vs ExtendedBlockView to model
grondag Feb 18, 2019
b1c4fa0
u no can has moar sprites
grondag Feb 19, 2019
e5f3677
isVanilla -> isVanillaAdapter, docs
grondag Feb 19, 2019
f2af030
derpy derp derp
grondag Feb 19, 2019
fa801f6
Hide makeTransform until more useful, clarify code
grondag Feb 19, 2019
7bb00b9
All methods should be authoritative
grondag Feb 19, 2019
729aeb1
Remove shader preview before merge
grondag Feb 19, 2019
6511c5f
Various improvements
grondag Feb 20, 2019
bde6ade
Missed one
grondag Feb 20, 2019
c965193
Remove improper import
grondag Feb 20, 2019
0003c01
Improve emitters, docs
grondag Feb 21, 2019
38cbe3a
Improve SpriteFinder docs
grondag Feb 21, 2019
ff8dd4d
Merge remote-tracking branch 'upstream/master' into alternate
grondag Feb 21, 2019
d152fea
Update to 19w08a mappings
grondag Feb 21, 2019
dcbf14b
Add missing licence header
grondag Feb 21, 2019
0d42c20
Merge remote-tracking branch 'upstream/master' into alternate
grondag Feb 23, 2019
19becc0
Remove shader-only feature/docs that got left
grondag Mar 2, 2019
c498b63
Cleanup broken doc references
grondag Mar 2, 2019
761de70
Disallow contructor, make contant names unambiguous
grondag Mar 2, 2019
c7ceb28
normX -> normalX, remove shader-only feature
grondag Mar 2, 2019
8db713f
SpriteFinder cleanups
grondag Mar 2, 2019
f1f6a00
More concise static initializer
grondag Mar 2, 2019
ca3ad41
Merge remote-tracking branch 'upstream/master' into alternate
grondag Mar 2, 2019
bf9cae0
Minor improvements for model building
grondag Mar 3, 2019
f7ab032
Docs: simplify lighting semantics
grondag Mar 7, 2019
ea6e0b2
Merge remote-tracking branch 'upstream/master' into alternate
grondag Mar 15, 2019
cbbbcf5
Merge remote-tracking branch 'upstream/master' into alternate
grondag Mar 29, 2019
f8138a1
Merge remote-tracking branch 'upstream/master' into alternate
grondag Apr 19, 2019
d1ea1f0
Update mapping
grondag Apr 19, 2019
513eee0
Start of V3 reorg
grondag Apr 23, 2019
2c91005
Merge remote-tracking branch 'upstream/master' into alternate
grondag Apr 23, 2019
75c6e40
More splitting for API v0.3
grondag Apr 23, 2019
eb4d199
Remove pointless and inaccurate restriction (docs only)
grondag Apr 27, 2019
c7e4866
Merge remote-tracking branch 'upstream/master' into alternate
grondag May 12, 2019
ee883c1
Update mappings, modular structure
grondag May 12, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2016, 2017, 2018 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.fabricmc.fabric.api.client.model.fabric;

import net.minecraft.block.entity.BlockEntity;

/**
* Interface for {@link BlockEntity}s which provide dynamic model state data.<p>
*
* Dynamic model state data is separate from BlockState, and will be
* cached during render chunk building on the main thread (safely) and accessible
* during chunk rendering on non-main threads.<p>
*
* For this reason, please ensure that all accesses to the passed model data are
* thread-safe. This can be achieved by, for example, passing a pre-generated
* immutable object, or ensuring all gets performed on the passed object are atomic
* and well-checked for unusual states.<p>
*/
@FunctionalInterface
public interface DynamicModelBlockEntity {
/**
* @return The model state data provided by this block entity. Can be null.
*/
Object getDynamicModelData();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/*
* Copyright (c) 2016, 2017, 2018 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.fabricmc.fabric.api.client.model.fabric;

import java.util.Random;
import java.util.function.Supplier;

import net.minecraft.block.BlockState;
import net.minecraft.client.render.block.BlockModelRenderer;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.ExtendedBlockView;

/**
* Interface for baked models that output meshes with enhanced rendering features.
* Can also be used to generate or customize outputs based on world state instead of
* or in addition to block state when render chunks are rebuilt.<p>
*
* Note for {@link Renderer} implementors: Fabric causes BakedModel to extend this
* interface with {@link #isVanilla()} == true and to produce standard vertex data.
* This means any BakedModel instance can be safely cast to this interface without an instanceof check.
*/
public interface FabricBakedModel {
/**
* When true, signals renderer this producer is implemented through {@link BakedModel#getQuads(BlockState, net.minecraft.util.math.Direction, Random)}.
* Also means the model does not rely on any non-vanilla features.
* Allows the renderer to optimize or route vanilla models through the unmodified vanilla pipeline if desired.<p>

* Fabric overrides to true for vanilla baked models.
* Enhanced models that use this API should return false,
* otherwise the API will not recognize the model.<p>
*/
boolean isVanillaAdapter();

/**
* This method will be called during chunk rebuilds to generate both the static and
* dynamic portions of a block model when the model implements this interface and
* {@link #isVanilla()} returns false. <p>
*
* During chunk rebuild, this method will always be called exactly one time per block
* position, irrespective of which or how many faces or block render layers are included
* in the model. Models must output all quads/meshes in a single pass.<p>
*
* Also called to render block models outside of chunk rebuild or block entity rendering.
* Typically this happens when the block is being rendered as an entity, not as a block placed in the world.
* Currently this happens for falling blocks and blocks being pushed by a piston, but renderers
* should invoke this for all calls to {@link BlockModelRenderer#tesselate(ExtendedBlockView, BakedModel, BlockState, BlockPos, net.minecraft.client.render.BufferBuilder, boolean, Random, long)}
* that occur outside of chunk rebuilds to allow for features added by mods, unless
* {@link #isVanilla()} returns true.<p>
grondag marked this conversation as resolved.
Show resolved Hide resolved
*
* Outside of chunk rebuilds, this method will be called every frame. Model implementations should
* rely on pre-baked meshes as much as possible and keep transformation to a minimum. The provided
* block position may be the <em>nearest</em> block position and not actual. For this reason, neighbor
* state lookups are best avoided or will require special handling. Block entity lookups are
* likely to fail and/or give meaningless results.<p>
*
* In all cases, renderer will handle face occlusion and filter quads on faces obscured by
* neighboring blocks (if appropriate). Models only need to consider "sides" to the
* extent the model is driven by connection with neighbor blocks or other world state.<p>
*
* Note: with {@link BakedModel#getQuads(BlockState, net.minecraft.util.math.Direction, Random)}, the random
* parameter is normally initialized with the same seed prior to each face layer.
* Model authors should note this method is called only once per block, and call the provided
* Random supplier multiple times if re-seeding is necessary. For wrapped vanilla baked models,
* it will probably be easier to use {@link RenderContext#fallbackModelConsumer()} which handles
* re-seeding per face automatically.<p>
*
* @param Access to world state. Using {@link TerrainBlockView#getCachedRenderData(BlockPos)} to
* retrieve block entity state unless thread safety can be guaranteed.
* @param safeBlockEntityAccessor Thread-safe access to block entity data
* @param state Block state for model being rendered.
* @param pos Position of block for model being rendered.
* @param randomSupplier Random object seeded per vanilla conventions. Call multiple times to re-seed.
* The randomeSupplier will not be thread-safe. Do not cache or retain a reference.
grondag marked this conversation as resolved.
Show resolved Hide resolved
* @param context Accepts model output.
*/
void emitBlockQuads(TerrainBlockView blockView, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context);

/**
* This method will be called during item rendering to generate both the static and
* dynamic portions of an item model when the model implements this interface and
* {@link #isVanilla()} returns false.<p>
*
* Vanilla item rendering is normally very limited. It ignores lightmaps, vertex colors,
* and vertex normals. Renderers are expected to implement enhanced features for item
* models. If a feature is impractical due to performance or other concerns, then the
* renderer must at least give acceptable visual results without the need for special-
* case handling in model implementations.<p>
*
* Calls to this method will generally happen on the main client thread but nothing
* prevents a mod or renderer from calling this method concurrently. Implementations
* should not mutate the ItemStack parameter, and best practice will be to make the
* method thread-safe.<p>
*
* Implementing this method does NOT mitigate the need to implement a functional
* {@link BakedModel#getItemPropertyOverrides()} method, because this method will be called
* on the <em>result</em> of {@link #getItemPropertyOverrides()}. However, that
* method can simply return the base model because the output from this method will
* be used for rendering.<p>
*
* Renderer implementations should also use this method to obtain the quads used
* for item enchantment glint rendering. This means models can put geometric variation
* logic here, instead of returning every possible shape from {@link #getItemPropertyOverrides()}
* as vanilla baked models.
*/
void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright (c) 2016, 2017, 2018 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.fabricmc.fabric.api.client.model.fabric;

import java.util.List;
import java.util.Random;
import java.util.function.Supplier;

import net.fabricmc.fabric.impl.client.model.DamageModel;
import net.minecraft.block.BlockState;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.BakedQuad;
import net.minecraft.client.render.model.json.ModelItemPropertyOverrideList;
import net.minecraft.client.render.model.json.ModelTransformation;
import net.minecraft.client.texture.Sprite;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;

/**
* Base class for specialized model implementations that need to wrap other baked models.
* Avoids boilerplate code for pass-through methods. For example usage see {@link DamageModel}.
*/
public abstract class ForwardingBakedModel implements BakedModel, FabricBakedModel {
/** implementations must set this somehow */
protected BakedModel wrapped;

@Override
public void emitBlockQuads(TerrainBlockView blockView, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) {
((FabricBakedModel)wrapped).emitBlockQuads(blockView, state, pos, randomSupplier, context);
}

@Override
public boolean isVanillaAdapter() {
return ((FabricBakedModel)wrapped).isVanillaAdapter();
}

@Override
public void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) {
((FabricBakedModel)wrapped).emitItemQuads(stack, randomSupplier, context);
}

@Override
public List<BakedQuad> getQuads(BlockState blockState, Direction face, Random rand) {
return wrapped.getQuads(blockState, face, rand);
}

@Override
public boolean useAmbientOcclusion() {
return wrapped.useAmbientOcclusion();
}

@Override
public boolean hasDepthInGui() {
return wrapped.hasDepthInGui();
}

@Override
public boolean isBuiltin() {
return wrapped.isBuiltin();
}

@Override
public Sprite getSprite() {
return wrapped.getSprite();
}

@Override
public ModelTransformation getTransformation() {
return wrapped.getTransformation();
}

@Override
public ModelItemPropertyOverrideList getItemPropertyOverrides() {
return wrapped.getItemPropertyOverrides();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Copyright (c) 2016, 2017, 2018 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.fabricmc.fabric.api.client.model.fabric;

import net.minecraft.block.Block;
import net.minecraft.block.BlockRenderLayer;

/**
* Finds standard {@link RenderMaterial} instances used to communicate
* quad rendering characteristics to a {@link RenderContext}.<p>
*
* Must be obtained via {@link Renderer#materialFinder()}.
*/
public interface MaterialFinder {
/**
* Returns the standard material encoding all
* of the current settings in this finder. The settings in
* this finder are not changed.<p>
*
* Resulting instances can and should be re-used to prevent
* needless memory allocation. {@link Renderer} implementations
* may or may not cache standard material instances.
*/
RenderMaterial find();

/**
*
* 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 each pass. But this does
* NOT mean the sprite will be rendered in a specific render pass - some
* implementations may not use the standard Minecraft render passes.<p>
*
* CAN be null and is null by default. A null value means the renderer
* will use {@link Block#getRenderLayer()} for the associate block, or
* {@link BlockRenderLayer#TRANSLUCENT} for item renders. (Normal Minecraft rendering)
*/
MaterialFinder blendMode(int spriteIndex, BlockRenderLayer blendMode);

/**
* Vertex color(s) will be modified for quad color index unless disabled.<p>
*/
MaterialFinder disableColorIndex(int spriteIndex, boolean disable);

/**
* Vertex color(s) will be modified for diffuse shading unless disabled.
*/
MaterialFinder disableDiffuse(int spriteIndex, boolean disable);

/**
* Vertex color(s) will be modified for ambient occlusion unless disabled.
*/
MaterialFinder disableAo(int spriteIndex, boolean disable);

/**
* When true, brightness value provided via {@link VertexEditor#lightmap()}
* will be used as the minimum lightmap brightness. Usually this is used to
* implement full brightness but less-than-full brightness values are valid.
* False by default<p>
*
* Note that color will still be modified by diffuse shading and ambient occlusion,
* by default. Most of the time, you will want to disable those via {@link #disableAo(int, boolean)}
* and {@link #disableDiffuse(int, boolean)}.
*/
MaterialFinder emissive(int spriteIndex, boolean isEmissive);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2016, 2017, 2018 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.fabricmc.fabric.api.client.model.fabric;

import java.util.function.Consumer;

/**
* A bundle of one or more {@link QuadView} instances encoded by the renderer,
* typically via {@link Renderer#meshBuilder()}.<p>
*
* Similar in purpose to the List<BakedQuad> instances returned by BakedModel, but
* affords the renderer the ability to optimize the format for performance
* and memory allocation.<p>
*
* Only the renderer should implement or extend this interface.
*/
public interface Mesh {
/**
* Use to access all of the quads encoded in this mesh. The quad instances
* sent to the consumer will likely be threadlocal/reused and should never
* be retained by the consumer.
*/
public void forEach(Consumer<QuadView> consumer);
}
Loading