2013-10-01 72 views
1

我遇到了以下问题,一个我无法解决搜索网络问题。从SDL2纹理中获取像素信息

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

问题是我想知道纹理中的某个像素是否是透明的,这样当有人点击图像时我可以确定是否必须执行一些操作(因为点击是不透明的区域)或不。 因为这是一些学校作业,我正面临一些限制,也就是说,只使用SDL2库,并且如果由于图像已被选择,因此如果所讨论的像素是透明的,则我无法查找一些地图。此外,我考虑使用SDL表面来完成这项任务,从原始图像创建它们,但是由于形状正在通过不起作用的纹理旋转。

关于SDL2真的没有太多文档,我无法在任何地方找到满意的答案,所以您可以给予的任何帮助将受到高度赞赏。

谢谢!

回答

2

您可以使用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通道是零(透明)或不是最后一个步骤。您可以从渲染目标或整个纹理中只读取想要的像素,选择哪个选项取决于必须执行的命中测试的次数,纹理旋转/移动的频率等。

2

您需要使用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专门处理像素操作。

我很抱歉,如果方法名称有任何错误(我把它写在我头上)。

希望这有助于。

+2

查看SDL_LockTexture的文档,看起来这使像素数据仅可用于写入访问。是否有另一种像素数据可以被读取访问的方式? –

+0

@ Julian锁定纹理会将像素保存到传入它的void指针中。所以,如果你只是想读,然后锁定和解锁纹理一次,像素将被保存。 – user2437378

+0

@ user2437378不正式 - https://wiki.libsdl。org/SDL_LockTexture - '作为优化,可用于编辑的像素不一定包含旧纹理数据。这是一个只写操作,如果您需要保留纹理数据的副本,您应该在应用程序级别执行此操作。“很难想到可以实现的方式,但依赖于某些东西他们明确表示不会。依靠这个建议的读者可能有一天会破坏他们的代码风险,到时候这太迟了。 –