Imgui: Emscripten - Imgui::image write warning WebGL: INVALID_ENUM: pixelStorei: invalid parameter name

Created on 12 Oct 2020  路  10Comments  路  Source: ocornut/imgui

I need load image and display it, but in browser console i have next warning:
"WebGL: INVALID_ENUM: pixelStorei: invalid parameter name" and window with black box.

My code which i get in "https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples#Example-for-OpenGL-users":

int my_image_width = 0;
int my_image_height = 0;
GLuint my_image_texture = 0;

bool ret = LoadTextureFromFile("//IDBFS//36038.jpg", &my_image_texture, &my_image_width, &my_image_height);
if(ret==true)
{
IM_ASSERT(ret);
ImGui::Begin("OpenGL Texture Text");
ImGui::Text("pointer = %p", my_image_texture);
ImGui::Text("size = %d x %d", my_image_width, my_image_height);
ImGui::Image((void*)(intptr_t)my_image_texture, ImVec2(my_image_width, my_image_height));
ImGui::End();
}

File have in virtual file system and reading without problems.
LoadTextureFromFile function i get in https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples#Example-for-OpenGL-users and texture have in memory.
Warning send on _glPixelStorei function, but I don't known why? Where is my mistake? In loading textures or is it impossible to load JPG?

I using lastes Emscripten SDK 2.0.6.

backenbinding opengl

Most helpful comment

It seems the parameters aren't the same between OpenGL ES 2 ( glPIxelStorei doc ) and OpenGL ES 3 ( glPIxelStorei doc ), maybe you're running in ES2 ?

Because from the documentation, GL_PACK_ROW_LENGTH is not a valid parameter in ES2, hence the error, does it works better with glPixelStorei(GL_UNPACK_ALIGNMENT, 4); ?

All 10 comments

Hello,

Does it works with glPixelStorei(GL_UNPACK_ROW_LENGTH, 1)?
Does it works if you remove the glPixelStorei() call ?

Yes. The warning disappeared, I remove glPixelStorei() function call.
BUT! Image not displayed on screen. Only black window!

It seems the parameters aren't the same between OpenGL ES 2 ( glPIxelStorei doc ) and OpenGL ES 3 ( glPIxelStorei doc ), maybe you're running in ES2 ?

Because from the documentation, GL_PACK_ROW_LENGTH is not a valid parameter in ES2, hence the error, does it works better with glPixelStorei(GL_UNPACK_ALIGNMENT, 4); ?

I tried glPixelStorei (GL_UNPACK_ALIGNMENT, 4), but still no image, just a black window! When compiling, I specify -s FULL_ES3 = 1 i.e. OpenGL Es 3.0

In case anyone else has this problem. I wasted a couple of hours on this a while back.

The glPixelStorei is a red herring. It needs to be removed, but it wont fix the problem.
You need to add some extra texture parameters to make the texture loading work in emscripten.

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

My load function is only slightly modified from the example to work:

``` struct ImageResource
{
ImageResource() : width(0), height(0), texture_id(0) {};

    ImageResource(int Width, int Height, GLuint Id) : width(Width), height(Height), texture_id(Id) {};

    int width = 0;
    int height = 0;
    GLuint texture_id;
};

// Simple helper function to load an image into a OpenGL texture with common settings
ImageResource LoadTextureFromMemory(const std::vector<uint8_t>& file)
{
    // Load from file
    int image_width = 0;
    int image_height = 0;

    unsigned char* image_data = stbi_load_from_memory(&file[0], (int)file.size(), &image_width, &image_height, NULL, 4);

    // Create a OpenGL texture identifier
    GLuint image_texture;
    glGenTextures(1, &image_texture);
    glBindTexture(GL_TEXTURE_2D, image_texture);

    // Setup filtering parameters for display
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    // clamp to edge required for emscripten
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    // Upload pixels into texture
    #ifdef GL_UNPACK_ROW_LENGTH
       glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
    #endif

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image_width, image_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
    stbi_image_free(image_data);

    return ImageResource(image_width, image_height, image_texture);
}

```
I'm just doing the load in memory rather than from a file (using fetch api instead of the filesystem), but it'll work exactly the same.

@ocornut Could you amend the wiki example?

Thank you @Pinteresting for looking into this, much appreciated!
To clarify, do you mean that:

  • Any setting other than GL_CLAMP_TO_EDGE doesn't work with Emscripten (e.g. GL_REPEAT) ? That would be surprising.
  • Or that whichever settings NEEDS to be explicitely setup with Emscripten? and by default texture don't hold any "valid" default?

Addendum: in the backend we don't set that up for the Font atlas texture and it works in Emscripten.
COULD it be because other clamping mode with power-of-two-widths textures but don't work with non-power-of-two-width textures? Could you investigate this further with Emscripten?

Thank you @Pinteresting for looking into this, much appreciated!
To clarify, do you mean that:

  • Any setting other than GL_CLAMP_TO_EDGE doesn't work with Emscripten (e.g. GL_REPEAT) ? That would be surprising.
  • Or that whichever settings NEEDS to be explicitely setup with Emscripten? and by default texture don't hold any "valid" default?

You explicitly need to set GL_CLAMP_TO_EDGE on textures which are not a power of 2. This is a requirement of WebGL, if you don't do that it will display a black square.

GL_REPEAT does not work. Not setting a value also does not work.

Addendum: in the backend we don't set that up for the Font atlas texture and it works in Emscripten.
COULD it be because other clamping mode with power-of-two-widths textures but don't work with non-power-of-two-width textures? Could you investigate this further with Emscripten?

With a power of 2 texture, GL_REPEAT works as does not setting a default value.

Thank you very much, will update the wiki with those finding.
I'll also change

        #ifdef GL_UNPACK_ROW_LENGTH
           glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
        #endif

to

        #if defined(GL_UNPACK_ROW_LENGTH) && !defined(__EMSCRIPTEN__)
           glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
        #endif

Does that sounds good?

Updated Wiki:
https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples#Example-for-OpenGL-users

Hopefully @AdlIzzadin that finally solves your issue.
Thanks everyone for investigating this :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bogdaNNNN1 picture bogdaNNNN1  路  3Comments

namuda picture namuda  路  3Comments

the-lay picture the-lay  路  3Comments

mnemode2 picture mnemode2  路  3Comments

NPatch picture NPatch  路  3Comments