[OpenGL] Using GL api within OpenFL display list

Hi. I’m trying to deal with GL api within OpenFL application and got stuck. I want to use flash api to some exact things like UI while some other stuff I want to render more efficient way and involve experimenting with shaders.
Access to GL seems pretty clear thanks to HerokuShaders sample. Howewer it becames more complicated if I add some more DisplayObjects on stage: application just crashes.
So my question is: what should I care for when implementing custom gl renderer of display object?
I had spend some time studying OpenFL internals and there are a several layers of abstractions like Context3D and still cant figure out all details.
Is there any way to implement ‘render()’ handler, deal with own VBOs, shaders and make app work without access to Context3D internals?

1 Like

There are a couple ways to do this.

We have some experimental stuff with using the OpenFL Context3D object.

There is stage.context3D or you can use stage.stage3Ds, the latter uses a framebuffer so you can use your own backbuffer size, stencil and depth buffer, otherwise it shares with the 2D renderer.

The Context3D API uses state caching, so we can automatically set state before each render.

There is some support now for Program3D supporting GLSL instead of AGAL, so it’s GLSL, buffers, state and drawTriangles. You should be able to create a VertexBuffer3D + IndexBuffer3D (context3D.drawTriangles always uses indexed rendering).

If you need more, we could look at the custom GL approach more, and maybe come up with more ways to try and synchronize state

Thanks!
I would prefer use pure GL api, it has a lot of features I want to practice with. For example, GPU instancing for particles.
OpenFL has clean pipeline to deliver game to many platforms and it would be great if we will able to use all features of GL (it even can be a selling point for some strange people like me).

I didn’t use pure OpenGL earlier just several game engines and decided that it is time to learn fundamentals.
So I can miss some obvious thing in GL programming which can lead to application crashes. But I rather think that the issue with state caching on which rendering pipeline relies and which I can broke binding my own buffers. Is there common way to inform Context3D that cached state is invalid and need to be reinited?
If this stuff became clear for me I would glad to share examples and maybe write some explanations for community.

Internally, we maintain a state object, like this:

Each operation sets the state, then we flush before each render operation.

We could consider some kind of “resetState” method to force the GL context into a neutral state, but there’s still the possibility that any custom GL code will break our code if it does not know about the state changes, unless you “undo” anything you did during the render

Sounds good for me. Obligation to undo all gl state changes at the end of ‘onRender’ is pretty reasonable.
Is it correct that there is no need to reupload data throug gl.bufferData() each ‘onRender()’ while it is not changed?
I guess

gl.bindBuffer(gl.ARRAY_BUFFER,mybuffer);
...draw...
gl.bindBuffer(gl.ARRAY_BUFFER,null);`

should be enough.
As for other calls changing gl state can i consider to set back all default values marked in reference like


or there is a way to extract and store current values to set them back after draw calls?

We may be able to add a renderer.resetState, or possibly (probably?) force OpenGLRenderer custom rendering to always state from a neutral state, I just didn’t want to force unnecessary state changes if something did not need them, but perhaps stage.context3D would be a better way to do “less expensive” custom rendering

When you say ‘force’ do you mean calling neutral state before each RenderEvent.RENDER_OPENGL dispatch? I’m sure it is unnecessary: if one writes custom gl renderer he definitely would able to set neutral state manually especially if API provides easy way to do so and it reflected in reference and ‘openfl-samples’ repo.
I think working with context3D is fine while you not going to do stuff with pure gl calls. Otherwise documentation should uncover what exact things occur with gl state on each context3d call in order to make one able to write consistent code and understand what he is doing.
As for ‘expenses’ of custom renderer i don’t suppose to make a lot of display objects but rather one or two containers like Tilemap which draw many elements within. Would set of neutral state in this case countable expensive?

Perhaps it would not be expensive. I believe that GL state is something where it sets it internally, but doesn’t really cause expensive changes until you actually render – but it surely depends on the driver implementation.

I think the HerokuShaders sample works with some basic display objects, but there may still be some state changes needed to make it work entirely with some combinations

As i know uploading large amount of data may be expensive as well as draw call itself. That’s why i worry about ability to keep vbo data between draw calls. And i had faced strange issues with it.
Actually i had tried HerokuShader with other Sprites on stage and it works as long as those Sprites are empty. If i add “graphics.drawTriangles()” to the constructor – the app crashes.

You should be able to preserve buffers. I wonder why it crashed, did you get any error information?

Does it work if you add a Bitmap instead?

Nothing more than (or i don’t know how to extract more detailed inforation)

Unhandled exception at 0x00000205C045FEA1 in Proi.exe: 0xC0000005: Access violation reading location 0x0000000000000000. occurred
at nvoglv64.dll thread

Same result with Bitmap child.

Here is demo and description which reveals the issues.

1 Like

Thank you for the demo :slight_smile:

Made it finally work (with Context3D cache disabled through openfl_disable_context_cache define). Checked on html5 (ff, chrome), windows and android.
Repo with sample is also updated.