3

我目前正在使用 SDL2 编写一个简单的程序,您可以在其中将一些形状(正方形、圆形、三角形等)拖到画布中并旋转它们并四处移动。每个形状都由从 PNG 文件创建的 SDL 纹理直观地表示(使用 SDL_image 库中的 IMG_LoadTexture 函数)。

问题是我想知道纹理中的某个像素是否透明,这样当有人点击图像时,我可以确定我是否必须做一些动作(因为点击是在非透明区域上) . 因为这是一些学校作业,所以我面临一些限制,即只能使用 SDL2 库,如果相关像素是透明的,我无法找到可以查找的地图,因为图像是动态选择的。此外,我考虑使用 SDL 表面来完成这项任务,从原始图像创建它们,但由于形状正在通过纹理旋转,这是行不通的。

4

2 回答 2

4

您可以通过使用Render Targets来完成此操作。

SDL_SetRenderTarget(renderer, target);
... render your textures rotated, flipped, translated using SDL_RenderCopyEx
SDL_RenderReadPixels(renderer, rect, format, pixels, pitch);

在最后一步中,您使用SDL_RenderReadPixels从渲染目标读取像素,然后您必须确定所需像素的 alpha 通道是否为零(透明)。您可以从渲染目标中仅读取您想要的一个像素,或整个纹理,您选择哪个选项取决于您必须执行的命中测试的数量、纹理旋转/移动的频率等。

于 2013-10-01T12:10:58.320 回答
1

您需要使用 SDL_TEXTUREACCESS_STREAMING 标志创建纹理并锁定纹理,然后才能操作像素数据。要判断某个像素在纹理中是否透明,请确保调用

SDL_SetTextureBlendMode(t, SDL_BLENDMODE_BLEND);

这允许纹理识别 Alpha 通道。

尝试这样的事情:

SDL_Texture *t;

int main()
{
    // initialize SDL, window, renderer, texture
    int pitch, w, h;
    void *pixels;

    SDL_SetTextureBlendMode(t, SDL_BLENDMODE_BLEND);

    SDL_QueryTexture(t, NULL, &aw, &h);
    SDL_LockTexture(t, NULL, &pixels, &pitch);
    Uint32 *upixels = (Uint32*) pixels;

    // you will need to know the color of the pixel even if it's transparent
    Uint32 transparent = SDL_MapRGBA(SDL_GetWindowSurface(window)->format, r, g, b, 0x00);

    // manipulate pixels
    for (int i = 0; i < w * h; i++)
    {
        if (upixels[i] == transparent)
            // do stuff
    }

    // replace the old pixels with the new ones
    memcpy(pixels, upixels, (pitch / 4) * h);

    SDL_UnlockTexture(t);

    return 0;
}

如果您有任何问题,请随时提问。虽然我不是这个话题的专家。

如需进一步阅读和教程,请查看http://lazyfoo.net/tutorials/SDL/index.php。教程 40 专门处理像素操作。

如果方法名称有任何错误,我深表歉意(我在脑海中写下了这个)。

希望这有帮助。

于 2014-05-25T07:25:03.643 回答