How would you advise rendering into an offscreen buffer using SharpGL?
I've been looking at the RenderContextsSample project and the four enumerated SharpGL.RenderContextType's. It seems like using an FBO gets us most of the way way there. My C# WinForm programming is a bit rusty so I might be making some incorrect assumptions
here but it seems like if we are using a FBORenderContextProvider it will present the results to the window that the OpenGLControl belongs to. What I would like to do is render to an image and then read it out to apply it as a texture later on.
I'm toying with the idea of making a new version of FBORenderContextProvider and adding a new SharpGL.RenderContextType enumeration to cover offscreen rendering where I basically do what FBORenderContextProvider does just with out doing the:
Win32.BitBlt(hdc, 0, 0, Width, Height, dibSectionDeviceContext, 0, 0, Win32.SRCCOPY); at the end of the Blit call.
Does this strategy make sense or will I run into problems trying to set an OpenGLControl that is hidden and not visible?
To being with.. an FBO is known as a Frame Buffer Object, so you are already rendering offscreen.
The sameple ... FormRenderContextsSample example is using more then one OpenGL control, but using only one SampleRendering Method. You could make more of those methods and have one for each control you want to draw too. You would literally be drawing each one
to its own FBO in this case.
However.. with all of this said.. you are doing this all using the CPU... not your graphics card. So its slower and more resource intensive.
What you want to look at is the Shader example.. its the only shader example they provide in the examples they have. Look for "ModernOpenGLSample" and you'll see how they work with the shaders to draw all of the vertices to the screen.
It does use double buffering though. Which in turn is what should be enabled to make it look smooth and draw better onto the screen.
Hopefully this info puts you in the right direction. Modern OpenGL uses shaders now.... The example you mentioned is the old way of using OpenGL. OpenGL 3.0+ is what you need. The provided example defaults to OpenGL 4.4. You can lower that down to 3.0 if you
need too and it will work just fine. Just make sure your shader FRAG and VERT file versions are setup accordingly.
This little piece of code should be able to help you create an empty texture.... or... Buffer Object in this case.
I added the Width and Height. This code is from the RadialBlur example.
protected uint EmptyTexture(int Wdith, int Height)
uint txtnumber = new uint; // Texture ID
byte data = new byte[((Wdith * Height)* 4 * sizeof(uint))];
// Get a reference to opengl to make things easier.
OpenGL gl = openGLControl1.OpenGL;
gl.GenTextures(1, txtnumber); // Create 1 Texture
gl.BindTexture(OpenGL.GL_TEXTURE_2D, txtnumber); // Bind The Texture
gl.TexImage2D(OpenGL.GL_TEXTURE_2D, 0, 4, Wdith, Height, 0, OpenGL.GL_RGBA, OpenGL.GL_UNSIGNED_BYTE, data); // Build Texture Using Information In data
gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MIN_FILTER, OpenGL.GL_LINEAR);
gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MAG_FILTER, OpenGL.GL_LINEAR);
return txtnumber; // Return The Texture ID