title: OpengL ES / Angle : rendering to single channel float texture
body: <p>I am trying to use shaders to do simple operations on large matrices/images. I wrote some code running with regular OpenGL by rendering to single channel float textures in frame buffer objects, which works fine. </p>
  
  <p>I would now need to have it run on different platforms (UWP + Angle, Android,...) so I'm trying to port the code to OpenGL ES 2.0 ; I can make it work with regular RGBA images, but doesn't with float images.</p>
  
  <p>What works (output buffer 'data_out' contains result of the render)</p>
  
  <pre><code>format = GL_RGBA;
  type = GL_UNSIGNED_BYTE;
  internal_format = GL_RGBA;
  glTexImage2D(GL_TEXTURE_2D, 0, internal_format,
      width,
      height,
      0, format, type,
      Data
  
  (...)
  glDrawElements(GL_TRIANGLES, (2) * 3, GL_UNSIGNED_SHORT, 0);
  glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data_out);
  </code></pre>
  
  <p>What doesn't work :</p>
  
  <pre><code>format = GL_RED_EXT;
  type = GL_FLOAT;
  internal_format = GL_RED_EXT;
  glTexImage2D(GL_TEXTURE_2D, 0, internal_format,
      width,
      height,
      0, format, type,
      Data);
  (...)
  glReadPixels(0, 0, width, height, GL_RED_EXT, GL_FLOAT, data_out);
  </code></pre>
  
  <p>What I expect in data_out :</p>
  
  <pre><code>27.0000000  float
  22.7840576  float
  11.4528332  float
  -3.45501971 float
  -17.2838974 float
  -25.7151508 float
  -26.1157665 float
  (...)
  </code></pre>
  
  <p>What I get :</p>
  
  <pre><code>-25.7161427 float
  -25.7161427 float
  -25.7161427 float
  -25.7161427 float
  -25.7161427 float
  -17.2863979 float
  -17.2863979 float
  (...)
  </code></pre>
  
  <p>I could not find many similar issues online, except for the following discussion :
  <a href="https://groups.google.com/forum/#!topic/webgl-dev-list/ms21hnWk0tg" rel="nofollow noreferrer">https://groups.google.com/forum/#!topic/webgl-dev-list/ms21hnWk0tg</a>
  , which seems to conclude "it can't be done", but was written back in 2012.</p>
  
  <p>So is there really no way of rendering to a single channel float texture with OpenGL ES 2.0 ? Because that would be a major issue to my project.</p>
  
  <p>Update -
  So I tried the float to/from RGBA encoding mentioned in the comment below.</p>
  
  <pre><code>inline float4 EncodeFloatRGBA( float v ) {
  float4 enc = float4(1.0, 255.0, 65025.0, 160581375.0) * v;
  enc = frac(enc);
  enc -= enc.yzww * float4(1.0/255.0,1.0/255.0,1.0/255.0,0.0);
  return enc;
  }
  inline float DecodeFloatRGBA( float4 rgba ) {
  return dot( rgba, float4(1.0, 1/255.0, 1/65025.0, 1/160581375.0) );
  }
  void main()
  {
  float raw_value = DecodeFloatRGBA(texture2D( myTextureSampler, UV ));
  gl_FragColor = EncodeFloatRGBA(raw_value);
  }
  </code></pre>
  
  <p>Pushing a texture filled with an arbitrary value (5.23) and retrieving the display with glReadPixels, I get only 3 bytes out of 4, alpha being stuck to 0</p>
  
  <p>input value (byte per byte)</p>
  
  <pre><code>[0] 41 ')'  unsigned char
  [1] 92 '\\' unsigned char
  [2] 167 '§' unsigned char
  [3] 64 '@'  unsigned char
  </code></pre>
  
  <p>output value (byte per byte)</p>
  
  <pre><code>[0] 41 ')'  unsigned char
  [1] 92 '\\' unsigned char
  [2] 167 '§' unsigned char
  [3] 0 '\0'  unsigned char
  </code></pre>