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

Add global shader list support to s2d #1265

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
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
71 changes: 60 additions & 11 deletions h2d/RenderContext.hx
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,11 @@ class RenderContext extends h3d.impl.RenderContext {
var compiledShader : hxsl.RuntimeShader;
var fixedBuffer : h3d.Buffer;
var pass : h3d.mat.Pass;
// ...Tail points at an end of global shader list, and shaders afterwards belong to specific objects.
var currentShaders : hxsl.ShaderList;
var currentShadersTail : hxsl.ShaderList;
var baseShaderList : hxsl.ShaderList;
var baseShaderListTail : hxsl.ShaderList;
var needInitShaders : Bool;
var currentObj : Drawable;
var stride : Int;
Expand Down Expand Up @@ -145,6 +148,7 @@ class RenderContext extends h3d.impl.RenderContext {
baseShader.setPriority(100);
baseShader.zValue = 0.;
baseShaderList = new hxsl.ShaderList(baseShader);
baseShaderListTail = baseShaderList;
targetsStack = [];
targetsStackIndex = 0;
cameraStack = [];
Expand Down Expand Up @@ -194,8 +198,8 @@ class RenderContext extends h3d.impl.RenderContext {
baseShader.viewportB.set(0, scene.viewportD * -baseFlipY, scene.viewportY * -baseFlipY);
baseShader.filterMatrixA.set(1, 0, 0);
baseShader.filterMatrixB.set(0, 1, 0);
baseShaderList.next = null;
initShaders(baseShaderList);
baseShaderListTail.next = null;
initShaders(baseShaderList, baseShaderListTail);
engine.selectMaterial(pass);
textures.begin();
}
Expand All @@ -217,9 +221,10 @@ class RenderContext extends h3d.impl.RenderContext {
engine.clear(color);
}

function initShaders( shaders ) {
function initShaders( shaders : hxsl.ShaderList, tail : hxsl.ShaderList ) {
needInitShaders = false;
currentShaders = shaders;
currentShadersTail = tail;
compiledShader = output.compileShaders(globals, shaders);
var buffers = shaderBuffers;
buffers.grow(compiledShader);
Expand All @@ -237,7 +242,7 @@ class RenderContext extends h3d.impl.RenderContext {
flush();
texture = null;
currentObj = null;
baseShaderList.next = null;
baseShaderListTail.next = null;
clearCurrent();
if ( targetsStackIndex != 0 ) throw "Missing popTarget()";
if ( cameraStackIndex != 0 ) throw "Missing popCamera()";
Expand Down Expand Up @@ -305,6 +310,50 @@ class RenderContext extends h3d.impl.RenderContext {
baseShader.viewportB.set(viewB * flipY, viewD * flipY, viewY * flipY);
}

/**
Adds a shader the global shader list.

Global shaders are present in all draw operations along with base2d shader.
**/
public function addGlobalShader( shader : hxsl.Shader ) {
var list = new hxsl.ShaderList(shader, baseShaderListTail.next);
baseShaderListTail.next = list;
baseShaderListTail = list;
needInitShaders = true;
}

/**
Removes the shader from the global shader list.

@returns `true` if shader was removed, `false` otherwise.
**/
public function removeGlobalShader( shader : hxsl.Shader ) {
if ( shader == baseShader ) throw "Cannot remove base shader!";
var prev : hxsl.ShaderList = null;
var hd = baseShaderList;
while ( hd != baseShaderListTail.next ) {
if ( hd.s == shader ) {
prev?.next = hd.next;
Yanrishatum marked this conversation as resolved.
Show resolved Hide resolved
needInitShaders = true;
if ( hd == baseShaderListTail ) {
baseShaderListTail = prev;
}
return true;
}
prev = hd;
hd = hd.next;
}
return false;
}

function updateGlobals() {
var hd = baseShaderList;
while ( hd != baseShaderListTail.next ) {
hd.s.updateConstants(globals);
hd = hd.next;
}
}

/**
<span class="label">Internal usage</span>

Expand Down Expand Up @@ -383,7 +432,7 @@ class RenderContext extends h3d.impl.RenderContext {
public function pushTarget( t : h3d.mat.Texture, startX = 0, startY = 0, width = -1, height = -1 ) {
flush();
engine.pushTarget(t);
initShaders(baseShaderList);
initShaders(baseShaderList, baseShaderListTail.next);

var entry = targetsStack[targetsStackIndex++];
if ( entry == null ) {
Expand Down Expand Up @@ -451,7 +500,7 @@ class RenderContext extends h3d.impl.RenderContext {
viewY = tinf.vy;
var flipY = t == null ? -baseFlipY : -targetFlipY;

initShaders(baseShaderList);
initShaders(baseShaderList, baseShaderListTail.next);
baseShader.halfPixelInverse.set(0.5 / (t == null ? engine.width : t.width), 0.5 / (t == null ? engine.height : t.height));
baseShader.viewportA.set(viewA, viewC, viewX);
baseShader.viewportB.set(viewB * flipY, viewD * flipY, viewY * flipY);
Expand Down Expand Up @@ -781,7 +830,7 @@ class RenderContext extends h3d.impl.RenderContext {
flush();
var shaderChanged = needInitShaders, paramsChanged = false;
var objShaders = obj.shaders;
var curShaders = currentShaders.next;
var curShaders = currentShadersTail.next;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

think this needs a null check

Suggested change
var curShaders = currentShadersTail.next;
var curShaders = currentShadersTail?.next;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, because it's never supposed to be null. Tail points at the last global shader (tail.next points at object-specific shaders), and you should not be able to remove base shader from the global shader list, thus tail is never null.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤷 idk i had to change this to make it work locally

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you provide an repro sample?

while( objShaders != null && curShaders != null ) {
var s = objShaders.s;
var t = curShaders.s;
Expand All @@ -801,14 +850,14 @@ class RenderContext extends h3d.impl.RenderContext {
baseShader.hasUVPos = hasUVPos;
baseShader.isRelative = isRelative;
baseShader.killAlpha = killAlpha;
baseShader.updateConstants(globals);
baseShaderList.next = obj.shaders;
initShaders(baseShaderList);
updateGlobals();
baseShaderListTail.next = obj.shaders;
initShaders(baseShaderList, baseShaderListTail);
} else if( paramsChanged ) {
flush();
if( currentShaders != baseShaderList ) throw "!";
// the next flush will fetch their params
currentShaders.next = obj.shaders;
currentShadersTail.next = obj.shaders;
}

this.texture = texture;
Expand Down