Code Monkey home page Code Monkey logo

shaderblox's Introduction

Shaderblox

Compile-time GLSL shader tools for Haxe/Lime


Shaderblox is an alternative approach to building and maintaining GLSL shaders for use with Haxe and Lime, and probably OpenFL as well with some typedef magic.

It stems from an urge to strong type the bindings between a shader as seen by the GPU and the Haxe software layer that interacts with it. For instance, in our game engine we had a renderer interface that needed to rely on certain vertex attributes and uniforms to exist within each shader, and without strong typing and compile time errors, this caused some heartache for me.

Shaderblox is intended to meet the following goals:

  • Compile-time parsing of shader source into strong typed classes with typed fields for attributes and uniforms.
  • Inheritance-based shader building, with one shader inheriting attributes, uniforms, methods etc from another.
  • #pragma tools for including external files (since writing inline shader source isn't super comfortable).
  • Generated methods for uploading uniforms and setting vertex attribute pointers.

With shaderblox, a shader incompatible with the rendering framework will cause compile time exceptions, meaning shader authors and framework engineers should have radically fewer ways to screw with one another.

Caveats

  1. Compiletime means swapping out shaders after the build is done is no longer possible: Shaders are as much a part of the compiled code as any class, rather than an external resource.
  2. Shader source validation is only done once the source is actually compiled on the GPU itself, which can only occur runtime.
  3. GLSL parsing is currently very unsophisticated, looking specifically for attribute and uniform declarations and not much else.
  4. Work in progress.. Open source.. etc etc. This is a personal project and it's constantly liable to change.
  5. Shader A extends Shader B merges uniform/attribute declarations, but unfortunately allows duplicate function declarations, such as two mains and so forth. Looking to improve this, obviously.

Example

Shader types are defined with metadata, and built with macros. This simple shader is included with the source.

package shaderblox.example;
import shaderblox.ShaderBase;

/**
 * "Hello world" shader example
 * @author Andreas Rønning
 */

@:vert('
	attribute vec2 aVertexPosition;
	void main(void) {
		gl_Position = vec4(aVertexPosition,0.0,1.0);
	}
')
@:frag('
	uniform vec3 uColor;
	void main(void)
	{
		gl_FragColor = vec4(uColor,1.0);
	}
')
class SimpleShader extends ShaderBase {}

Note that instead of writing the source inline, as in this case, you could use this approach:

@:vert('#pragma include("path/to/my/shader.vert")')

This external file will be loaded in at compiletime (as well as display-time, giving dynamic code completion as the external source is updated). You can of course liberally use the pragma include to build shaders whichever way you want.

The following source is a variation of the typical "hello triangle" using the SimpleShader example included with the source.

package ;
import haxe.Timer;
import lime.gl.GL;
import lime.gl.GLBuffer;
import lime.Lime;
import lime.utils.Float32Array;
import shaderblox.example.SimpleShader;


class Main {
	var lime:Lime;
	var shader:SimpleShader;
	var vbuf:GLBuffer;
	
	public function new () {
	}
	
	public function ready (lime:Lime):Void {
		this.lime = lime;
		
		vbuf = GL.createBuffer();
		var vertices:Array<Float> = [
		   0.0,  0.5,
		   0.5, -0.5,
		  -0.5, -0.5
		];
		
		GL.bindBuffer(GL.ARRAY_BUFFER, vbuf);
		GL.bufferData(GL.ARRAY_BUFFER, new Float32Array(vertices), GL.STATIC_DRAW);
		GL.bindBuffer(GL.ARRAY_BUFFER, null);
		
		shader = new SimpleShader();
		shader.create(); //Create builds, validates attribs/uniforms and uploads. Should do this as part of load, or when context is lost.
	}
	
	inline function uSin(t:Float):Float {
		return Math.sin(t) * 0.5 + 0.5;
	}
	
	public function render ():Void {
		GL.viewport (0, 0, lime.config.width, lime.config.height);
		GL.clearColor (1.0, 1.0, 1.0, 1.0);
		GL.clear (GL.COLOR_BUFFER_BIT);
		
		//Set some wobbly color values on our vec3 uniform
		shader.uColor.data.x = uSin(Timer.stamp());
		shader.uColor.data.y = uSin(Timer.stamp()*2);
		shader.uColor.data.z = uSin(Timer.stamp()*3);
		
		//Set our shader as current.
		shader.activate();  
		//Note that by default, activate uploads uniform values, but does not set vertex attribute pointers (which needs to be repeated every buffer bind anyway)
		
		GL.bindBuffer(GL.ARRAY_BUFFER, vbuf); //Bind our vbo..
		
		//Set the vertex attribute pointers into the current vertex buffer object...
		shader.setAttributes(); 
		
		//Draw our triangle...
		GL.drawArrays(GL.TRIANGLE_FAN, 0, 3); 
		
		//..and clean up (important)
		shader.deactivate(); 
	}	
}

shaderblox's People

Contributors

haxiomic avatar sunjammer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

haxiomic imclab

shaderblox's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.