Skip to content

Commit

Permalink
Rough in some bits for unified materials
Browse files Browse the repository at this point in the history
  • Loading branch information
grondag committed Aug 23, 2020
1 parent c3d80ed commit faa2a4d
Show file tree
Hide file tree
Showing 12 changed files with 211 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,6 @@
import grondag.fermion.bits.BitPacker64.BooleanElement;
import grondag.fermion.bits.BitPacker64.IntElement;

/**
WIP Needs to be parallel to RenderLayer and also have a simpler mapping to material state and shaders
Ideally shaders should not be context sensitive - contexts should instead expose attributes that shader depends on
*/
public abstract class AbstractMeshMaterial extends MeshMaterialKey {
private static final BitPacker64<AbstractMeshMaterial> BITPACKER_0 = new BitPacker64<>(m -> m.bits0, (m, b) -> m.bits0 = b);
private static final BitPacker64<AbstractMeshMaterial> BITPACKER_1 = new BitPacker64<>(m -> m.bits1, (m, b) -> m.bits1 = b);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public MeshMaterialLayer(MeshMaterial meshMaterial, int depth) {
}

shader = MaterialShaderManager.INSTANCE.get(MeshMaterialLocator.SHADERS[depth].getValue(this.meshMaterial.bits1));

// WIP: flags get conveyed via MaterialVertexState instead
int flags = this.meshMaterial.emissive(depth) ? 1 : 0;

if (this.meshMaterial.disableDiffuse(depth)) {
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/grondag/canvas/material/EncodingContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
/**
* Describes the type of render context
* and controls how materials are packed to buffers.
*
* WIP: still needed?
*/
public enum EncodingContext {
TERRAIN(true, false, false),
Expand Down
17 changes: 1 addition & 16 deletions src/main/java/grondag/canvas/material/MaterialState.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,7 @@
import grondag.canvas.shader.ShaderPass;
import grondag.fermion.bits.BitPacker32;

/**
WIP: simplify - make parallel to RenderLayer
state with same shader and same quad sorting (yes or no) can share the same buffer/collector
there are three types of buffer/shader sharing
1 - gl state changes required
2 - uniform changes
3 - vertex data control
For the first two types, buffer data must be segregated by material state
When the material requires sorted translucency, then only type 3 is allowed (vertex data)
Relationship between this, render material and shaders must be simplified and made consistent with above
*/
// WIP: replace with MaterialDrawState


public class MaterialState {
Expand Down
37 changes: 0 additions & 37 deletions src/main/java/grondag/canvas/render/DrawStrategy.java

This file was deleted.

18 changes: 17 additions & 1 deletion src/main/java/grondag/canvas/render/RenderLayerHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,38 +45,54 @@ private static void startShaderDraw(RenderLayer renderLayer) {
// for item/block controls mipped or non-mipped
// can also be non-textured - for non-textured probably best to stay with fixed pipeline for now
// final boolean hasTexture = params.getTexture() != RenderPhase.NO_TEXTURE;
//
// mipped -> MaterialVertexState
// texture binding -> MaterialGlState

//transparency
// shader probably doesn't care but would be useful to expose different types in material builder
// final boolean hasTranslucent = params.getTransparency() != RenderPhase.NO_TRANSPARENCY;

//
// -> MaterialGlState

//diffuseLighting
// when active, lighting will need to be applied in the shader
// light setup is different for in-world (and varies by dimension) and GUI contexts.
// see DiffuseLighting and the calls it makes to RenderSystem for details
// final boolean enableDiffuse = params.getDiffuseLighting() == RenderPhase.ENABLE_DIFFUSE_LIGHTING;
//
// -> MaterialVertexState

//shadeModel
// not applicable in core profile but still seems to disable interpolation in 2.1
// the default is flat
// should work as-is?
// need to handle if/when consolidating non-terrain passes
// final boolean isFlat = params.getShadeModel() == RenderPhase.SHADE_MODEL;
//
// -> MaterialVertexState

//alpha (AKA cutout)
// still works so don't need to handle until we want to consolidate non-terrain render passes
// has 50% and 10% cutout variants
//
// -> MaterialVertexState

//depthTest
// currently no need to handle in shader
//
// -> MaterialGlState

//cull
// currently no need to handle in shader
//
// -> MaterialGlState

//lightmap
// true when lightmap texture/application is enabled
// final boolean enableLightmap = params.getLightmap() == RenderPhase.ENABLE_LIGHTMAP;
//
// -> MaterialGlState

//overlay
// overlay texture is either white flashing (TNT) or a red color (mob damage)
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/grondag/canvas/shader/ShaderPass.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package grondag.canvas.shader;

// WIP: remove
@Deprecated
public enum ShaderPass {
SOLID,
DECAL,
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/grondag/canvas/shader/wip/MaterialBufferKey.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package grondag.canvas.shader.wip;

import grondag.canvas.buffer.encoding.VertexEncoder;
import grondag.canvas.material.MaterialVertexFormat;

/**
* Primitives with the same buffer key can share the same buffer.
* They should share the same encoder/vertex format, same and have the same sorting requirements.
*
* Content of the buffer should also share the same matrix state but this is
* not enforced and must be controlled through appropriate usage.
*
*/
public class MaterialBufferKey {
public final MaterialVertexFormat format;
public final VertexEncoder encoder;
/** true only for translucent */
public final boolean sorted;

private MaterialBufferKey(VertexEncoder encoder, MaterialVertexFormat format, boolean sorted) {
this.format = format;
this.encoder = encoder;
this.sorted = sorted;
}
}
22 changes: 22 additions & 0 deletions src/main/java/grondag/canvas/shader/wip/MaterialDrawState.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package grondag.canvas.shader.wip;

/**
* Primitives with the same DrawState have the same vertex format/buffer,
* and same uniform state and gl state.
*
* Primitives with draw states will be collected in different arrays
* and then packed into shared buffers (if applicable) with the same buffer key.
*
* Order of packing will be a hierarchy of Gl state and uniform state
*/
public class MaterialDrawState {
public final MaterialBufferKey bufferKey;
public final MaterialGlState drawState;
public final MaterialUniformState uniformState;

private MaterialDrawState(MaterialBufferKey bufferKey, MaterialGlState drawState, MaterialUniformState uniformState) {
this.bufferKey = bufferKey;
this.drawState = drawState;
this.uniformState = uniformState;
}
}
20 changes: 20 additions & 0 deletions src/main/java/grondag/canvas/shader/wip/MaterialGlState.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package grondag.canvas.shader.wip;


public class MaterialGlState {

public static class Builder {
// WIP: texture binding
// WIP: transparency
// WIP: depth test
// WIP: cull
// WIP: enable lightmap

private boolean sorted = false;

public Builder sorted(boolean sorted) {
this.sorted = sorted;
return this;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package grondag.canvas.shader.wip;

public class MaterialUniformState {

}
115 changes: 115 additions & 0 deletions src/main/java/grondag/canvas/shader/wip/MaterialVertexState.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package grondag.canvas.shader.wip;

import grondag.canvas.apiimpl.MaterialConditionImpl;
import grondag.fermion.bits.BitPacker32;
import grondag.fermion.bits.BitPacker32.BooleanElement;
import grondag.fermion.bits.BitPacker32.IntElement;

/**
* Encapsulates material state conveyed via vertex attributes
*/
@SuppressWarnings("rawtypes")
public class MaterialVertexState {
public final boolean emissive;
public final boolean disableDiffuse;
public final boolean disableAo;
public final boolean cutout;
public final boolean unmipped;
public final MaterialConditionImpl condition;
public final int bits;

// WIP: flat? (equivalent of shadeModel - need to look at how it is used)
// WIP: cutout threshold: 10% or 50%

private MaterialVertexState(int bits) {
this.bits = bits;
emissive = EMISSIVE.getValue(bits);
disableDiffuse = DISABLE_DIFFUSE.getValue(bits);
disableAo = DISABLE_AO.getValue(bits);
cutout = CUTOUT.getValue(bits);
unmipped = UNMIPPED.getValue(bits);
condition = MaterialConditionImpl.fromIndex(CONDITION.getValue(bits));
}

private static final BitPacker32 PACKER = new BitPacker32<>(null, null);
// these 8 correspond to shader flag bits
private static final BooleanElement EMISSIVE = PACKER.createBooleanElement();
private static final BooleanElement DISABLE_DIFFUSE = PACKER.createBooleanElement();
private static final BooleanElement DISABLE_AO = PACKER.createBooleanElement();
private static final BooleanElement CUTOUT = PACKER.createBooleanElement();
private static final BooleanElement UNMIPPED = PACKER.createBooleanElement();
@SuppressWarnings("unused")
private static final BooleanElement RESERVED_5 = PACKER.createBooleanElement();
@SuppressWarnings("unused")
private static final BooleanElement RESERVED_6 = PACKER.createBooleanElement();
@SuppressWarnings("unused")
private static final BooleanElement RESERVED_7 = PACKER.createBooleanElement();

private static final IntElement CONDITION = PACKER.createIntElement(MaterialConditionImpl.MAX_CONDITIONS);

public static final int STATE_COUNT = 1 << PACKER.bitLength();
private static final MaterialVertexState[] STATES = new MaterialVertexState[1 << PACKER.bitLength()];

static {
assert MaterialConditionImpl.ALWAYS.index == 0;

for (int i = 0; i < STATE_COUNT; ++i) {
STATES[i] = new MaterialVertexState(i);
}
}

public static MaterialVertexState fromBits(int bits) {
return STATES[bits];
}

public static class Finder {
private int bits = 0;

public Finder() {
reset();
}

public Finder reset() {
bits = 0;
return this;
}

public Finder emissive(boolean emissive) {
bits = EMISSIVE.setValue(emissive, bits);
return this;
}

public Finder disableDiffuse(boolean disableDiffuse) {
bits = DISABLE_DIFFUSE.setValue(disableDiffuse, bits);
return this;
}

public Finder disableAo(boolean disableAo) {
bits = DISABLE_AO.setValue(disableAo, bits);
return this;
}

public Finder cutout(boolean cutout) {
bits = CUTOUT.setValue(cutout, bits);
return this;
}

public Finder unmipped(boolean unmipped) {
bits = UNMIPPED.setValue(unmipped, bits);
return this;
}

public Finder condition(MaterialConditionImpl condition) {
bits = CONDITION.setValue(condition.index, bits);
return this;
}

public int findBits() {
return bits;
}

public MaterialVertexState find() {
return STATES[bits];
}
}
}

0 comments on commit faa2a4d

Please sign in to comment.