render to texture, awesome. Beautiful stuff can be made with some Perlin Noise. Imagine a metal cube with a procedural texture:
So now I want to extract the texture, with glTexImage2D or, in my case (openTK) it’s GL.TexImage2D. Result looks like this:
I’ve read through tons of posts, most of which resulted in the usage of glPixelStorei(GL_UNPACK_ALIGNMENT, 1). It was also mentioned that this is a common problem for textures that are no power of 2, but in my case, I can’t extract the data no matter how big the texture is.
This is all the relevant code leading to the texture extraction:
int dimension = 100; // can be any number // create render target int screenRenderFBO = GL.GenFramebuffer(); GL.BindFramebuffer(FramebufferTarget.Framebuffer, screenRenderFBO); DrawBuffersEnum renderTarget = DrawBuffersEnum.ColorAttachment0; GL.ActiveTexture(TextureUnit.Texture0); int createdTextures[i] = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, createdTexture); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, dimension, dimension, 0, PixelFormat.Rgba, PixelType.Byte, IntPtr.Zero); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); GL.FramebufferTexture(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, createdTexture, 0); GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
// bind render target // assuming viewport stays the same GL.BindFramebuffer(FramebufferTarget.Framebuffer, screenRenderFBO); GL.DrawBuffers(1, renderTarget); // do drawing code, I assume it works because the displayed texture is perfectly fine // extract texture byte pixels = new byte[dimension * dimension * 4]; IntPtr pixelAddress = Marshal.UnsafeAddrOfPinnedArrayElement(pixels, 0); GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, createdTexture); GL.GetTexImage(TextureTarget.Texture2D, 0, PixelFormat.Bgra, PixelType.UnsignedByte, pixelAddress); Bitmap bmp = new Bitmap(texture.Width, texture.Height, 8, PixelFormat.Format32bppRgb, pixelAddress); bmp.Save(...)
I tried using every combination of glPixelStorei(GL_(UN)PACK_ALIGNMENT, 1|2|4|8) and it did not change a thing, but I have to say I don’t really understand when exactly to use it. But with textures sized power of two, it should work without, right?
I also tried drawing the texture and then reading it with glReadPixels, the result was the exact same. Also, the colors are not only distorted in the Bitmap, but already before in the pixels array, so that should not be the problem.
Seeing the slanted image (the lines have a slope of exactly 0.5, in case that’s important), I get the feeling that the mistake must be very obvious. I just hope the problem does not lie within openTK because in that case, good luck waiting for a fix…
If you have any idea what’s going on here, please help!