I've been using glow to do some opengl rendering in rust. It's going well, but rendering to a texture vs. rendering to an image gives me different results. I know a naive way to solve it, I just don't understand it.
The image on the right is rendering right to the screen, while the lower left is created by rendering the same mesh to a texture of the same size using the same draw function (passing the pixel data to egui's ColorImage). As you can see, it's too dark, and this is also true when I save the pixel data to a file (using rust's Image crate).
But, if a channel's value is full in the render, it's also full in the output, almost like the RGB values are squared in a range of 0-1.0 before being converted to RGB8. Sure enough, I tried undoing that in the pixel data (flipped_buffer[i1] = ((buffer[i2] as f32 / 255.).sqrt() * 255.).round() as u8;
), and it started looking correct!
So WHY? It's such a specific thing, and I can even imagine it being a useful way of mapping colors (since eyes distinguish darker values better than brighter ones), but why did it happen here?
The code for writing to a texture is based on the tutorial here, but using glow in rust instead of C/C++, and using RGBA instead of RGB.
Texture Creation Exerpt:
let gl_texture = self.gl.create_texture()?;
self.gl.bind_texture(glow::TEXTURE_2D, Some(gl_texture));
self.gl.tex_image_2d(glow::TEXTURE_2D, 0, glow::RGBA as i32, width as i32, height as i32, 0, glow::RGBA, glow::UNSIGNED_BYTE, None);
self.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MAG_FILTER, glow::NEAREST as i32);
self.gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MIN_FILTER, glow::NEAREST as i32);
Pixel Data Read Exerpt:
let mut buffer = vec![0 as u8; (width * height * 4) as usize];
self.gl.get_tex_image(
glow::TEXTURE_2D,
0,
glow::RGBA,
glow::UNSIGNED_BYTE,
glow::PixelPackData::Slice(buffer.as_mut_slice()));