Desde que empezó el tema de los smartphone, siempre sonó interesante la idea de programar desde el propio cacharro. Si bien ya se podía desde (casi?) el principio con SL4A, nunca fué algo demasiado cómodo.

Pues bien, resulta que en F-Droid (market de aplicaciones libres) tienen un entorno que permite programar Shaders en GLSL, programas que permiten generar gráficos desde la GPU, e incluso utilizarlos como fondo de pantalla, Shader Editor.

El programilla es bastante sencillo, y parece un buen método para aprender a hacer shaders, sabiendo por ejemplo C, y a partir de los ejemplos que incluye.

Pues bien, ahí va algo programado cacharreando con esto en el tren, dibuja el conjunto de Julia, moviendose en un par de dimensiones para que quede algo dinámico.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
precision mediump float;

// Time in ms
uniform float time;

// Resolution in pixels
uniform vec2 resolution;

// Max number of iterations for scape alg.
const int max_its = 100;

// Speed of the animation
const float sp = 20.;

/* Match the number of iterations needed to scape
 * to a color.
 */
vec3 color(int i){
    float f = float(max_its - i) / float(max_its);
    return  vec3(f, f, 1);
}


// Escape time algorithm
int iterations(float x0, float x, float y0, float y){
  int i;
  for (i = 0;i < max_its; i++){
    float x2 = x * x;
    float y2 = y * y;

    if((x2 + y2) > 4.){
      return i;
    }

    // Yep, no complex numbers for us
    float tmp = x2 - y2 + x0;
    y = 2. * x * y + y0;
    x = tmp;
  }

  return i;
}


void main( void ){
    vec2 rs = resolution; // Size of the screen
                          // Relevant for pixel-to-point mapping
    vec2 xy = gl_FragCoord.xy; // Position of the pixel

  // Walk around the curve
  float x0 = cos(time / sp) * .70;
  float y0 = sin(time / sp) * .70;

  // Map pixels in the screen to points in the curve
  float x = (xy.x / rs.x) * 4. - 2.;
  float y = (xy.y / rs.y) * 4. - 2.;

  int i = iterations(x0, x, y0, y);

  // Color the interior parts
  if (i >= max_its){
    gl_FragColor = vec4(
      vec3(0.1, 0.1, 0.1),
      1.0);
  }
  // The escaping ones too
  else {
    gl_FragColor = vec4(
      color(i),
      1.0);
  }
}

Je, por cierto, bebe bastante batería, claro :P