Unable to Get Current Frame Buffer In Webgl
tanema opened this issue · comments
There are points where I need to get the current frame buffer, bind another, then bind the first one however right now it is not really possible to do that in web gl. Normally I would call gl.GetInteger(gl.FRAMEBUFFER_BINDING)
but that always returns 0 and wont allow me to bind to it. According to this https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bindFramebuffer I would need to call getParameter on the context to get the current frame buffer. It is hard to name a solution to this since adding a GetCurrentFrameBuffer()
method would change the whole api. Also I was thinking exposing the context so I can call any function on it but again that does not work for a uniform API.
Let me know if I have missed a solution, that could be possible as well.
gl.GetInteger(gl.FRAMEBUFFER_BINDING)
should work. In the WebGL implementation, it just does gl.getParameter(gl.FRAMEBUFFER_BINDING);
, see:
Lines 308 to 310 in f020688
Which seems to be what https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bindFramebuffer recommends. Any ideas why it'd return 0?
I'll be able to look more into this later.
The actual error is Uncaught TypeError: Failed to execute 'bindFramebuffer' on 'WebGLRenderingContext': parameter 2 is not of type 'WebGLFramebuffer'.
So I believe that is expecting an actual WebGLFramebuffer object instead of the int that I am trying to pass. When I run it in the browser manually I get this
gl.createFramebuffer() //-> WebGLFramebuffer {}
So I think passing in an int like that is not allowed. It calls the correct function yes but then it is cast to an int which will always be zero I imagine because objects don't cast to ints.
Right, BindFramebuffer
(of WebGL implementation) expects a Framebuffer
:
func BindFramebuffer(target Enum, fb Framebuffer) {
c.Call("bindFramebuffer", target, fb.Object)
}
Which is what you get from CreateFramebuffer
.
But to get the currently bound framebuffer, you'd need something like this (which currently doesn't exist):
func GetFramebufferParameter(pname Enum) Framebuffer {
return Framebuffer{Object: c.Call("getParameter", pname)}
}
If possible, you could just use/remember the value from CreateFramebuffer
... Othewise, I need to think about how be able to expose getting currently bound framebuffer in a non-webgl-specific API.
Keeping track of the bound frame buffer does not allow you to get the initial/default frame buffer which I use for unbinding frame buffers. However I wouldn't say I am an expert with opengl so maybe that is not normal usage.
This is a divergence between WebGL and OpenGL (ES) APIs. OpenGL uses integer IDs for framebuffers, so you can get a current one with glGetInteger(GL_FRAMEBUFFER_BINDING)
which is good to use with glBindFramebuffer
. In WebGL, you do gl.getParameter(gl.FRAMEBUFFER_BINDING);
which gives you a WebGLFramebuffer
object, which is good to use with gl.bindFramebuffer
.
The only cross-platform solution I see is to add new custom methods to get bound objects. E.g.:
// WebGL implementation.
func GetBoundFramebuffer() Framebuffer {
return Framebuffer{Object: c.Call("getParameter", FRAMEBUFFER_BINDING)}
}
// OpenGL ES implementation.
func GetBoundFramebuffer() Framebuffer {
var b Framebuffer
gl.GetIntegerv(FRAMEBUFFER_BINDING, &b.Value)
return b
}
And similar methods for other structs in https://github.com/goxjs/gl/blob/master/types_webgl.go.
Can anyone thing of any better ways to resolve this?
Seems like a reasonable solution, however a solution that would require some documentation on the readme for Gotchyas or something like that.
Would having those methods in godoc not be enough?
Do you want to make it a PR?
Re: Docs, It's up to you I guess, I just figured that since the api has been consistent with openGL and this has been the only exception that it might bear mentioning on the project page.
I will create a pull request tonight after work for this. Regarding that I was going to make a PR for the webgl method that was confirmed to work. Do you mind if I put that in this PR too or do you want it separate for commit log reasons?
I just figured that since the api has been consistent with openGL and this has been the only exception that it might bear mentioning on the project page.
Makes sense. I just couldn't think of how to phrase this section eloquently, and I prefer to keep the docs high quality. I don't consider this a "gotcha", it's just a part of the cross-platform GL API.
Single PR is fine. I can split it into separate commits when merging if I want. Feel free to do what's easier for you. Thanks!