diff options
| author | David Robillard <d@drobilla.net> | 2019-12-07 15:54:01 +0100 | 
|---|---|---|
| committer | David Robillard <d@drobilla.net> | 2019-12-11 22:59:50 +0100 | 
| commit | 13f9ef04aaf5f3583ef83bffc094758f0d640634 (patch) | |
| tree | 234967ce962d3e1033634569e7a40c80c974abd9 | |
| parent | 91773de7ac4e07643fc47f1f0c1fdb6a255f53d2 (diff) | |
GL3 Test: Move shaders to separate files
| -rw-r--r-- | shaders/rect.frag | 36 | ||||
| -rw-r--r-- | shaders/rect.vert | 18 | ||||
| -rw-r--r-- | test/pugl_gl3_test.c | 76 | ||||
| -rw-r--r-- | wscript | 7 | 
4 files changed, 94 insertions, 43 deletions
diff --git a/shaders/rect.frag b/shaders/rect.frag new file mode 100644 index 0000000..d128f37 --- /dev/null +++ b/shaders/rect.frag @@ -0,0 +1,36 @@ +#version 330 + +/* The fragment shader uses the UV coordinates to calculate whether it is in +   the T, R, B, or L border.  These are then mixed with the border color, and +   their inverse is mixed with the fill color, to calculate the fragment color. +   For example, if we are in the top border, then T=1, so the border mix factor +   TRBL=1, and the fill mix factor (1-TRBL) is 0. + +   The use of pixel units here is handy because the border width can be +   specified precisely in pixels to draw sharp lines.  The border width is just +   hardcoded, but could be made a uniform or vertex attribute easily enough. */ + +uniform vec2 u_size; +uniform vec4 u_borderColor; +uniform vec4 u_fillColor; + +noperspective in vec2 f_uv; + +layout(location = 0) out vec4 FragColor; + +void +main() +{ +	const float border_width = 2.0; + +	float t          = step(border_width, f_uv[1]); +	float r          = step(border_width, u_size.x - f_uv[0]); +	float b          = step(border_width, u_size.y - f_uv[1]); +	float l          = step(border_width, f_uv[0]); +	float fill_mix   = t * r * b * l; +	float border_mix = 1.0 - fill_mix; +	vec4  fill       = fill_mix * u_fillColor; +	vec4  border     = border_mix * u_borderColor; + +	FragColor = fill + border; +} diff --git a/shaders/rect.vert b/shaders/rect.vert new file mode 100644 index 0000000..34fe0b3 --- /dev/null +++ b/shaders/rect.vert @@ -0,0 +1,18 @@ +#version 330 + +/* The vertex shader is trivial, but forwards scaled UV coordinates (in pixels) +   to the fragment shader for drawing the border. */ + +uniform mat4 MVP; +uniform vec2 u_size; + +in vec2 v_position; + +noperspective out vec2 f_uv; + +void +main() +{ +	f_uv        = v_position * u_size; +	gl_Position = MVP * vec4(v_position, 0.0, 1.0); +} diff --git a/test/pugl_gl3_test.c b/test/pugl_gl3_test.c index 8dea5a1..9ddf7db 100644 --- a/test/pugl_gl3_test.c +++ b/test/pugl_gl3_test.c @@ -73,49 +73,6 @@ static const GLfloat rectVertices[] = {  static const GLuint rectIndices[4] = {0, 1, 2, 3}; -/* The vertex shader is trivial, but forwards scaled UV coordinates (in pixels) -   to the fragment shader for drawing the border. */ -static const char* vertexSource = // -        "#version 330\n" -        "uniform mat4 MVP;\n" -        "uniform vec2 u_size;\n" -        "in vec2 v_position;\n" -        "noperspective out vec2 f_uv;\n" -        "void main() {\n" -        "    f_uv = v_position * u_size;\n" -        "    gl_Position = MVP * vec4(v_position, 0.0, 1.0);\n" -        "}\n"; - -/* The fragment shader uses the UV coordinates to calculate whether it is in -   the T, R, B, or L border.  These are then mixed with the border color, and -   their inverse is mixed with the fill color, to calculate the fragment color. -   For example, if we are in the top border, then T=1, so the border mix factor -   TRBL=1, and the fill mix factor (1-TRBL) is 0. - -   The use of pixel units here is handy because the border width can be -   specified precisely in pixels to draw sharp lines.  The border width is just -   hardcoded, but could be made a uniform or vertex attribute easily enough. */ -static const char* fragmentSource = // -        "#version 330\n" -        "uniform vec2 u_size;\n" -        "uniform vec4 u_borderColor;\n" -        "uniform vec4 u_fillColor;\n" -        "noperspective in vec2 f_uv;\n" -        "layout(location = 0) out vec4 FragColor;\n" -        "void main() {\n" -        "    const float border_width = 2.0;\n" -        "\n" -        "    float t          = step(border_width, f_uv[1]);\n" -        "    float r          = step(border_width, u_size.x - f_uv[0]);\n" -        "    float b          = step(border_width, u_size.y - f_uv[1]);\n" -        "    float l          = step(border_width, f_uv[0]);\n" -        "    float fill_mix   = t * r * b * l;\n" -        "    float border_mix = 1.0 - fill_mix;\n" -        "    vec4  fill       = fill_mix * u_fillColor;\n" -        "    vec4  border     = border_mix * u_borderColor;\n" -        "    FragColor        = fill + border;\n" -        "}\n"; -  typedef struct  {  	PuglTestOptions opts; @@ -263,6 +220,27 @@ makeRects(const size_t numRects)  	return rects;  } +static char* +loadShader(const char* const path) +{ +	FILE* const file = fopen(path, "r"); +	if (!file) { +		logError("Failed to open '%s'\n", path); +		return NULL; +	} + +	fseek(file, 0, SEEK_END); +	const long fileSize = ftell(file); + +	fseek(file, 0, SEEK_SET); +	char* source = (char*)calloc(1, fileSize + 1); + +	fread(source, 1, fileSize, file); +	fclose(file); + +	return source; +} +  int  main(int argc, char** argv)  { @@ -328,8 +306,20 @@ main(int argc, char** argv)  		return 1;  	} +	// Load shader sources +	char* const vertexSource   = loadShader("shaders/rect.vert"); +	char* const fragmentSource = loadShader("shaders/rect.frag"); +	if (!vertexSource || !fragmentSource) { +		logError("Failed to load shader sources\n"); +		puglFreeView(app.view); +		puglFreeWorld(app.world); +		return 1; +	} +  	// Compile rectangle shaders and program  	app.drawRect = compileProgram(vertexSource, fragmentSource); +	free(fragmentSource); +	free(vertexSource);  	if (!app.drawRect.program) {  		puglFreeView(app.view);  		puglFreeWorld(app.world); @@ -284,6 +284,13 @@ def build(bld):              **kwargs)      if bld.env.BUILD_TESTS: +        for s in ('rect.vert', 'rect.frag'): +            # Copy shaders to build directory for test programs +            bld(features = 'subst', +                is_copy  = True, +                source   = 'shaders/%s' % s, +                target   = 'shaders/%s' % s) +          if bld.env.HAVE_GL:              build_test('pugl_test', ['test/pugl_test.c'],                         platform, 'gl', uselib=['GL', 'M'])  | 
