sprite->setStencil not working - C SDK

Hi,

I’m using version 2.7.6 of the C SDK on Windows 11. I’ve been trying for hours to get setStencil to work, but whenever I apply a stencil to a sprite, the sprite is not displayed.

The following module level variables are declared:

LCDBitmap* _mask;
LCDBitmap* _circle;
LCDSprite* _sprite;

My initialisation code looks like this:

// Create mask bitmap
_mask = _pd->graphics->newBitmap(32, 32, kColorClear);
_pd->graphics->pushContext(_mask);
_pd->graphics->fillRect(0, 0, 32, 16, kColorBlack);
_pd->graphics->popContext();

// Create sprite bitmap
_circle = _pd->graphics->newBitmap(32, 32, kColorClear);
_pd->graphics->pushContext(_circle);
_pd->graphics->drawEllipse(0, 0, 32, 32, 2, 0, 360, kColorBlack);
_pd->graphics->drawEllipse(4, 4, 24, 24, 1, 0, 360, kColorBlack);
_pd->graphics->popContext();

// Create sprite
_sprite = _pd->sprite->newSprite();
_pd->sprite->setImage(_sprite, _circle, kBitmapUnflipped);
_pd->sprite->moveTo(_sprite, 200, 120);
_pd->sprite->setStencil(_sprite, _mask);
_pd->sprite->addSprite(_sprite);

My update code is simply this:

_pd->sprite->drawSprites();
_pd->graphics->drawBitmap(_mask, 104, 104, kBitmapUnflipped);

return 1;

If expect to see this:

image

But instead, the sprite is not displayed, so I see this:

image

If I comment out the “setStencil” line, I see this.

image

The documentation just gives a one liner regarding setStencil, but it seems to be straightforward enough, so I’m assuming it’s a bug. I could be wrong!

Any ideas what’s going on here?

Cheers,

Rich.

_pd->graphics->fillRect(0, 0, 32, 16, kColorWhite);

I think your stencil needs to be white where you want things to be drawn in the mask. anywhere black will not be drawn.

1 Like

The issue is that stencils are attached to the frame buffer, not the sprite. Here I’ve made the stencil a full-screen checkerboard and set that as the sprite’s mask:

Untitled

I’ll file an issue to clarify that in the docs. Thanks for pointing it out!

2 Likes

Ahhh right, yes I can get that working now. It’s confusing because sprite->setStencilPattern works on individual sprites, but as you’ve pointed out, sprite->setStencil doesn’t. Is there any way to apply a bitmap stencil to a sprite, rather than the frame buffer? Or any future plans to do this?

Also, if the docs are getting an update, can you mention which colours to use? I couldn’t find anywhere in the C SDK doc that mentions using black or white to indicate the area to be drawn. @DraperDanMan was correct in his comment above, I should have been using white, not black.

Appreciate your help with this, thanks. :slightly_smiling_face:

Rich.

Here’s my updated description. I also updated graphics→setStencilImage() and Lua’s gfx.setStencilImage() and sprite.setStencilImage() similarly

void playdate->sprite->setStencilImage(LCDSprite sprite, LCDBitmap stencil, int tile);

Specifies a stencil image to be set on the frame buffer before the sprite is drawn. While the stencil is active, the sprite pixels will be drawn where the stencil is white and nothing drawn where the stencil is black. Note that the stencil is attached to the frame buffer (i.e., the screen), not the sprite—it does not move along with the sprite. If stencil is NULL, the stencil is cleared. If tile is set, the stencil will be tiled. Tiled stencils must have width evenly divisible by 32.

1 Like