Last active
September 22, 2019 11:20
-
-
Save KrabCode/a4a715e49f08eccfc870f3b383636eb8 to your computer and use it in GitHub Desktop.
HotShader.pde
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ifdef GL_ES | |
| precision mediump float; | |
| precision mediump int; | |
| #endif | |
| uniform sampler2D texture; | |
| uniform vec2 resolution; | |
| uniform float time; | |
| void main(){ | |
| gl_FragColor = vec4(vec3(0.), 1.); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ifdef GL_ES | |
| precision mediump float; | |
| precision mediump int; | |
| #endif | |
| uniform sampler2D texture; | |
| uniform vec2 resolution; | |
| uniform float time; | |
| void main(){ | |
| vec2 uv = gl_FragCoord.xy / resolution; | |
| vec3 col = 0.5 + 0.5*cos(time+uv.xyx+vec3(0,2,4)); | |
| gl_FragColor = vec4(col, 1.); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import java.io.File; | |
| import java.util.ArrayList; | |
| import static java.lang.System.currentTimeMillis; | |
| public void setup() { | |
| size(800, 800, P3D); | |
| } | |
| public void draw() { | |
| uniform("frag.glsl").set("time", radians(frameCount)); | |
| hotFilter("frag.glsl"); | |
| hotShader("dark.glsl", "vert.glsl"); | |
| translate(width/2, height/2); | |
| rotateY(radians(frameCount)); | |
| stroke(255); | |
| box(250); | |
| } | |
| /* The following code can apply shaders on the fly as you change the last changed timestamp of the shader files | |
| * - use uniform() to get a reference to the shader file in order to pass uniforms to it | |
| * - use hotFilter() and hotShader() to apply your last compilable shader as filter or shader respectively | |
| * - no need to call loadShader() manually at all | |
| * | |
| * - to see the effects you have to actually change the last modified timestamp of the file, (try CTRL+S) | |
| * - the results of any compilation errors will be printed to standard processing console | |
| */ | |
| ArrayList<ShaderSnapshot> snapshots = new ArrayList<ShaderSnapshot>(); | |
| int refreshRateInMillis = 60; | |
| public PShader uniform(String fragPath) { | |
| ShaderSnapshot snapshot = findSnapshotByPath(fragPath); | |
| snapshot = initIfNull(snapshot, fragPath, null); | |
| return snapshot.compiledShader; | |
| } | |
| public PShader uniform(String fragPath, String vertPath) { | |
| ShaderSnapshot snapshot = findSnapshotByPath(fragPath); | |
| snapshot = initIfNull(snapshot, fragPath, vertPath); | |
| return snapshot.compiledShader; | |
| } | |
| public void hotFilter(String path, PGraphics canvas) { | |
| hotShader(path, null, true, canvas); | |
| } | |
| public void hotFilter(String path) { | |
| hotShader(path, null, true, g); | |
| } | |
| public void hotShader(String fragPath, String vertPath, PGraphics canvas) { | |
| hotShader(fragPath, vertPath, false, canvas); | |
| } | |
| public void hotShader(String fragPath, String vertPath) { | |
| hotShader(fragPath, vertPath, false, g); | |
| } | |
| public void hotShader(String fragPath, PGraphics canvas) { | |
| hotShader(fragPath, null, false, canvas); | |
| } | |
| public void hotShader(String fragPath) { | |
| hotShader(fragPath, null, false, g); | |
| } | |
| private void hotShader(String fragPath, String vertPath, boolean filter, PGraphics canvas) { | |
| ShaderSnapshot snapshot = findSnapshotByPath(fragPath); | |
| snapshot = initIfNull(snapshot, fragPath, vertPath); | |
| snapshot.update(filter, canvas); | |
| } | |
| private ShaderSnapshot initIfNull(ShaderSnapshot snapshot, String fragPath, String vertPath) { | |
| if (snapshot == null) { | |
| snapshot = new ShaderSnapshot(fragPath, vertPath); | |
| snapshots.add(snapshot); | |
| } | |
| return snapshot; | |
| } | |
| private ShaderSnapshot findSnapshotByPath(String path) { | |
| for (ShaderSnapshot snapshot : snapshots) { | |
| if (snapshot.fragPath.equals(path)) { | |
| return snapshot; | |
| } | |
| } | |
| return null; | |
| } | |
| private class ShaderSnapshot { | |
| String fragPath; | |
| String vertPath; | |
| File fragFile; | |
| File vertFile; | |
| PShader compiledShader; | |
| long fragLastKnownModified, vertLastKnownModified, lastChecked; | |
| boolean compiledAtLeastOnce = false; | |
| long lastKnownUncompilable = -refreshRateInMillis; | |
| ShaderSnapshot(String fragPath, String vertPath) { | |
| if (vertPath != null) { | |
| compiledShader = loadShader(fragPath, vertPath); | |
| vertFile = dataFile(vertPath); | |
| vertLastKnownModified = vertFile.lastModified(); | |
| if (!vertFile.isFile()) { | |
| println("Could not find shader at " + vertFile.getPath()); | |
| } | |
| } else { | |
| compiledShader = loadShader(fragPath); | |
| } | |
| fragFile = dataFile(fragPath); | |
| fragLastKnownModified = fragFile.lastModified(); | |
| lastChecked = currentTimeMillis(); | |
| if (!fragFile.isFile()) { | |
| println("Could not find shader at " + fragFile.getPath()); | |
| } | |
| this.fragPath = fragPath; | |
| this.vertPath = vertPath; | |
| } | |
| long max(long a, long b) { | |
| if (a > b) { | |
| return a; | |
| } | |
| return b; | |
| } | |
| void update(boolean filter, PGraphics pg) { | |
| long currentTimeMillis = currentTimeMillis(); | |
| long lastModified = fragFile.lastModified(); | |
| if (vertFile != null) { | |
| lastModified = max(lastModified, vertFile.lastModified()); | |
| } | |
| if (compiledAtLeastOnce && currentTimeMillis < lastChecked + refreshRateInMillis) { | |
| // println("compiled at least once, not checking, standard apply"); | |
| applyShader(compiledShader, filter, pg); | |
| return; | |
| } | |
| if (!compiledAtLeastOnce && lastModified > lastKnownUncompilable) { | |
| // println("first try"); | |
| tryCompileNewVersion(filter, pg, lastModified); | |
| return; | |
| } | |
| lastChecked = currentTimeMillis; | |
| if (lastModified > fragLastKnownModified && lastModified > lastKnownUncompilable) { | |
| // println("file changed, repeat try"); | |
| tryCompileNewVersion(filter, pg, lastModified); | |
| } else if (compiledAtLeastOnce) { | |
| // println("file didn't change, standard apply"); | |
| applyShader(compiledShader, filter, pg); | |
| } | |
| } | |
| private void applyShader(PShader shader, boolean filter, PGraphics pg) { | |
| if (filter) { | |
| pg.filter(shader); | |
| } else { | |
| pg.shader(shader); | |
| } | |
| } | |
| private void tryCompileNewVersion(boolean filter, PGraphics pg, long lastModified) { | |
| try { | |
| PShader candidate; | |
| if (vertFile == null) { | |
| candidate = loadShader(fragPath); | |
| } else { | |
| candidate = loadShader(fragPath, vertPath); | |
| } | |
| // we need to call filter() or shader() here in order to catch any compilation errors and not halt the sketch | |
| applyShader(candidate, filter, pg); | |
| compiledShader = candidate; | |
| compiledAtLeastOnce = true; | |
| fragLastKnownModified = lastModified; | |
| } | |
| catch (Exception ex) { | |
| lastKnownUncompilable = lastModified; | |
| println("\n" + fragFile.getName() + ": " + ex.getMessage()); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| uniform mat4 transform; | |
| attribute vec4 position; | |
| attribute vec4 color; | |
| varying vec4 vertColor; | |
| varying vec4 vertCoord; | |
| void main() { | |
| gl_Position = transform * position; | |
| vertColor = color; | |
| vertCoord = position; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment