Conway shader works with Ofelia and Emscripten but not as a desktop app

I experience some strange behaviour with a Conway (game of life) shader. It does not work as a desktop app, while it works with Ofelia https://github.com/cuinjune/Ofelia and Emscripten.
Here is the code that works with Emscripten: ofEmscriptenExamples/emscriptenGameOfLife at main · Jonathhhan/ofEmscriptenExamples · GitHub
I use it with this GLSL shader for the desktop app (because the Emscripten version has GL ES shaders): https://github.com/Jonathhhan/PDGameofLife-shaderVersion-/blob/main/gol_shader_v004/data/GameOfLife.frag
Does somebody know, what I am doing wrong?

Actually I had to replace sampler2D with sampler2DRect and add a mod function to the shader to replace GL_REPEAT which does not seem to work with sampler2DRect. I still wonder why sampler2D is working with this shader with Ofelia and GL ES but not with the desktop app.

This is the working shader for the desktop app:

#version 150
// fragment shader

out vec4 out_Color;

uniform sampler2DRect Tex0;
uniform vec2 resolution;
uniform vec2 cells[9];

int get(int x, int y) {
	return int(texture(Tex0, mod(gl_FragCoord.xy + vec2(x, y), resolution)).a);
}

void main() {
	int sum = 
	get(-1, -1) +
	get(-1,  0) +
	get(-1,  1) +
	get( 0, -1) +
	get( 0,  1) +
	get( 1, -1) +
	get( 1,  0) +
	get( 1,  1);
	vec2 r = cells[sum];
	if (get(0, 0) == 1) {
		out_Color = vec4(0.0, 0.0, 0.0, r.x);
	} else  {
		out_Color = vec4(0.0, 0.0, 0.0, r.y);
	}
}
#version 150
// vertex shader

uniform mat4 modelViewProjectionMatrix;
in vec4 position;
in vec2 texcoord;

out vec2 texCoordVarying;

void main()
{
	texCoordVarying = texcoord;
	gl_Position = modelViewProjectionMatrix * position;
}

Here is the whole patch: ofEmscriptenExamples/ofGameOfLifeDesktopNewGUI at main · Jonathhhan/ofEmscriptenExamples · GitHub

Hey @Jona, yes there are some differences between the sampler2D and the sampler2DRect. I love your solution for using mod() to replace GL_REPEAT, which you’re right in that it doesn’t work with sampler2DRect. I’m not sure, but the sampler2D coordinates might be normalized (0.0 - 1.0) by default, which I don’t think is the case for sampler2DRect.

One thing you can do is to send your own texcoord into the shader by calling .draw() on something, like an ofFbo or something with an ofMesh. If you use an ofPlanePrimitive, you can set the texcoords yourself, so that they could be anything and you know what they are. I’ll often use of3dPrimitive::mapTexCoords() for this. If you use an ofFbo or an ofTexture, the texcoord will range from (0, 0) to (width, height) of the texture. Once they’re passed to the fragment shader they can be used however you want. Its a nice substitute for gl_FragCord, which I think might be an older way of accessing coordinates in a shader.

So I’ll typically do something like this in the shader with .draw() on an ofFbo:

vertex shader:

#version 330
uniform mat4 modelViewProjectionMatrix;
in vec4 position;
in vec2 texcoord;
out vec2 vTexCoord;

void main(){
    gl_Position = modelViewProjectionMatrix * position;
    vTexcoord = texcoord;
}

fragment shader:

#version 330
uniform sampler2DRect tex0;
uniform vec2 resolution;
in vec2 vTexcoord;
out vec4 fragColor;

void main(){
    vec2 tc = vTexcoord; // use vTexcoord instead of gl_FragCoord.xy
    tc /= resolution;  // normalize 0.0 - 1.0
    vec3 textureColor = texture(tex0, tc * resolution).rgb;  // sample a color, or
    vec3 color = vec3(tc.x, 0.0, tc.y); // make one from tc

    // compute more stuff with tc, color, etc; and then:
    fragColor = vec4(color, 1.0); // send fragColor down the pipeline
}
1 Like