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.
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:
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 :)
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_LENGTHis not a valid parameter in ES2, hence the error, does it works better withglPixelStorei(GL_UNPACK_ALIGNMENT, 4);?