Skip to content
This repository has been archived by the owner on Dec 2, 2019. It is now read-only.

Image created in memory triggers "if this triggers you forgot to add a font" #927

Open
crazyBaboon opened this issue Oct 16, 2019 · 1 comment

Comments

@crazyBaboon
Copy link
Contributor

crazyBaboon commented Oct 16, 2019

I am trying to modify a function called icon_load() that currently is responsible for loading a .png image into memory, into a function that simply loads an image that is created in heap memory.

Here is the original source code for it, defined in example/extended.c:


static struct nk_image
icon_load(const char *filename)
{
    int x,y,n;
    GLuint tex;
    unsigned char *data = stbi_load(filename, &x, &y, &n, 0);
    if (!data) die("[SDL]: failed to load image: %s", filename);

    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
    glGenerateMipmap(GL_TEXTURE_2D);
    stbi_image_free(data);
    return nk_image_id((int)tex);
}

Here is my modified version.
Instead of generating an image buffer from a .png file, I generated a 4 x 4 texel GL_RGBA texture on heap memory. I basically replaced stbi_load() (which returns a pointer to stbi_uc just a typedef for unsigned char)
by malloc() (which returns a void pointer but it is cast to unsigned char). I have also replaced stbi_image_free() by free()):

static struct nk_image
icon_load(const char *filename)
{
    GLuint tex;
    
    unsigned char *data = (unsigned char*)malloc(64 * sizeof(char));
    static int messi = 1;    

    for (int i = 0; i < 64; i += 4)
    {   
        data[i + 0] = 4 * i;
        data[i + 1] = 0;
        data[i + 2] = 0;
        data[i + 3] = 0;
        printf("data[%d] = %d\n", i, data[i]);
    }   

    printf("Messi is %d\n", messi);
    messi++; 

    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
    glGenerateMipmap(GL_TEXTURE_2D);
    free(data);
    
    return nk_image_id((int)tex);
}

The output:


...
data[54] = 127
data[55] = 255
data[56] = 255
data[57] = 127
data[58] = 255
data[59] = 127
data[60] = 255
data[61] = 127
data[62] = 255
data[63] = 127
Messi is 32
Segmentation fault (core dumped)
...


Looking at the output I assume that malloc() was successful.

The fact that Messi is now 32, indicates that icon_load() was successfully called 31 times for each of the icons/images in lines 821 - 829 , before any rendering was actually done.

Using good old printf() debugging I realized the crash occurs inside function nk_begin_titled():

NK_ASSERT(ctx->style.font && ctx->style.font->width && "if this triggers you forgot to add a font");

How can this be fixed?

Is there another way in nuklear to display images that are created in the heap memory?

@revolucas
Copy link

You need to initialize the font atlas and either add your own fonts or use the default font (requires NK_INCLUDE_DEFAULT_FONT define) then bake. Then don't forget to nk_style_set_font for a font.

No matter your rendering backend or how you load textures, you'll want to pass the texture id to nuklear functions as a struct nk_image. Eventually, in the draw list loop it will spit this back out in a draw command as cmd->texture, where you will call glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id);

If you need image loading library you can try DevIL.

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

No branches or pull requests

2 participants