memononen / nanovg

Antialiased 2D vector drawing library on top of OpenGL for UI and visualizations.
zlib License
5.15k stars 771 forks source link

Bind a dummy texture in setUniforms when compiling with emscripten #567

Closed olilarkin closed 4 years ago

olilarkin commented 4 years ago

fixes the WebGL error "RENDER WARNING: there is no texture bound to the unit 0"" in Chrome

note: previous PR worked with nanovg example, but not with iPlug2, where webgl context is initially hidden. In this PR i create the dummy texture on first use which seems to work in both cases

see discussion https://github.com/memononen/nanovg/issues/398#issuecomment-437004233

olilarkin commented 4 years ago

nope, this is no good either, closing

memononen commented 4 years ago

Please update the PR instead of creating new one and closing each time. The method from MetalNanoVG should work just fine, i.e. create/find the texture in renderCreate and pass it in in setUniforms. What does not work for you?

olilarkin commented 4 years ago

sorry about that. first PR worked (no more webgl warning) with emscriptenized nanovg demo, but not with iPlug2, where the webgl context is not immediately onscreen. second PR worked with a basic iPlug2 project, but in this more complex demo https://iplug2.github.io/NANOVG/IPlugControls/ there were some new errors "[.WebGL-0x7fa3620ef200]GL ERROR :GL_INVALID_OPERATION : glDrawArrays: Source and destination textures of the draw are the same." And it looked totally wrong, which is why i closed the PR: Screenshot 2020-03-05 at 20 15 21

memononen commented 4 years ago

glDrawArrays: Source and destination textures of the draw are the same sounds like you ar rendering to a texture which you are using as a texture. Should not be related to this at all.

You have to have valid opengl context available when renderCreate is called, so creating the texture there should be valid too.

olilarkin commented 4 years ago

Not sure what I had done to mess it up, but this is now working with both the nanovg demo and my project, so i have modified and reopened this PR

memononen commented 4 years ago

Cool! I suggest following changes, I think it is safe to enable this on all cases.

Comment:

...
    // Some platforms does not allow to have samples to unset textures.
    // Create empty one which is bound when there's no texture specified.
    gl->dummyTex = glnvg__renderCreateTexture(&gl, NVG_TEXTURE_ALPHA, 1, 1, 0, NULL);

Change logic to handles missing image (should not happen!):

static void glnvg__setUniforms(GLNVGcontext* gl, int uniformOffset, int image)
{
    GLNVGtexture* tex = NULL;

    ...

    if (image != NULL) {
        tex = glnvg__findTexture(gl, image);
    }
    // If not image is set, use empty texture.
    if (tex == NULL) {
        tex = glnvg__findTexture(gl, gl->dummyTex);
    }
    glnvg__bindTexture(gl, tex != NULL ? tex->tex : 0);
    glnvg__checkError(gl, "tex paint tex");
olilarkin commented 4 years ago

I tried your changes, but the call to glnvgrenderCreateTexture() crashes with EXC_BAD_ACCESS in glnvgallocTexture() on macOS.

memononen commented 4 years ago

@olilarkin The only change to the glnvg__renderCreateTexture() bit was the comment. On second look, in that call it should be gl not &gl.

olilarkin commented 4 years ago

ahha, thats it. pushed some updates

memononen commented 4 years ago

Thanks for the fix!