shader game of life
Inhaltsverzeichnis
Game of Life
Zurück zur Shadersammlung
Beschreibung | Autor | Version |
---|---|---|
Simuliert das altbekannte Game Of Life. | dj3hut1 | 1.0 |
Bilder
Beschreibung
Ein Fragmentshader wird dazu benutzt, um das 'Game of Life' zu simulieren.
Dazu wird zuerst eine Textur erstellt, die zufällig 'lebende'( weiß ) oder 'tote' ( schwarz ) Zellen enthält. Diese Textur repräsentiert die Anfangspopulation.
In jedem ( Render- )schritt wird die nachfolgende Population berechnet. Abhängig davon, wieviel tote oder lebendige Nachbarzellen eine Zelle hat, wird entschieden ob die Zelle 'stirbt', am Leben bleibt oder eine neue Zelle geboren wird.
Hat eine lebende Zelle 2 oder 3 Nachbarn überlebt sie, hat sie weniger als 2 verhungert sie, hat sie mehr als 3 stirbt sie wegen Überbevölkerung.
Wenn eine leere Zelle von 3 lebendigen Zellen umgeben ist, wird dort eine neue Zelle 'geboren'.
In jedem Renderschritt wird nun also die Textur an den Fragmentshader übergeben ( gezeichnet auf einem Quad ) und dort wird dann die nächste Generation berechnet und auf den Bildschirm geschrieben ( mit glFinish ). Mittels glCopyTexImage2D können die Daten wieder in die Textur geschrieben werden.
Besondere Vorraussetzungen
OpenGL 2.0.
Code
Vertexshader
void main()
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
Fragmentshader
uniform sampler2D Texture0;
float SIZE = 64.0;
int lookup( in float x, in float y )
{
vec2 tc;
tc.x = x/SIZE;
tc.y = y/SIZE;
vec4 col = texture2D(Texture0, tc);
if ( col.r == 1.0 )
return 1;
return 0;
}
void main()
{
float x = gl_FragCoord.x;
float y = gl_FragCoord.y;
int neighbours = 0;
//Nachbarn berechnen
if ( x > 1 && y > 1 ) neighbours += lookup( x - 1, y - 1 );
if ( y > 1 ) neighbours += lookup( x, y - 1 );
if ( x < SIZE - 1 && y > 1 ) neighbours += lookup( x + 1, y - 1 );
if ( x > 1 ) neighbours += lookup( x - 1, y );
if ( x < SIZE - 1 ) neighbours += lookup( x + 1, y );
if ( x > 1 && y < SIZE - 1 ) neighbours += lookup( x - 1, y + 1 );
if ( y < SIZE - 1 ) neighbours += lookup( x, y + 1 );
if ( x < SIZE - 1 && y < SIZE - 1 ) neighbours += lookup( x + 1, y + 1 );
//eigener Zustand
int self = lookup( x, y );
gl_FragColor = vec4(0);
//hier wird entschieden, ob die Zelle lebt
if ( neighbours == 3 || ( neighbours == 2 && self == 1 ) )
{
gl_FragColor = vec4(1);
}
}
Demo
Java Demo (mit Quellen)