Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to Get Current Frame Buffer In Webgl #20

Closed
tanema opened this issue Mar 30, 2016 · 9 comments
Closed

Unable to Get Current Frame Buffer In Webgl #20

tanema opened this issue Mar 30, 2016 · 9 comments
Labels

Comments

@tanema
Copy link
Contributor

tanema commented Mar 30, 2016

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.

@tanema tanema changed the title Unable to Get Current Fram Buffer In Webgl Unable to Get Current Frame Buffer In Webgl Mar 30, 2016
@dmitshur
Copy link
Member

gl.GetInteger(gl.FRAMEBUFFER_BINDING) should work. In the WebGL implementation, it just does gl.getParameter(gl.FRAMEBUFFER_BINDING);, see:

gl/gl_webgl.go

Lines 308 to 310 in f020688

func GetInteger(pname Enum) int {
return c.Call("getParameter", pname).Int()
}

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.

@tanema
Copy link
Contributor Author

tanema commented Mar 30, 2016

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.

@dmitshur
Copy link
Member

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.

@tanema
Copy link
Contributor Author

tanema commented Mar 30, 2016

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.

@dmitshur
Copy link
Member

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?

@tanema
Copy link
Contributor Author

tanema commented Mar 31, 2016

Seems like a reasonable solution, however a solution that would require some documentation on the readme for Gotchyas or something like that.

@dmitshur
Copy link
Member

Would having those methods in godoc not be enough?

Do you want to make it a PR?

@tanema
Copy link
Contributor Author

tanema commented Mar 31, 2016

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?

@dmitshur
Copy link
Member

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants