The function bmap_process applies a shader to a source-bitmap and writes the result into a target bitmap. This way, images can be processed very fast, because a shader it is executed on the GPU for this. This is not only very fast, it is LIGHTNING FAST, compared to manipulating pixels with pixel_for_bmap and so on. The downside is, though, that the destination image is automatically converted into a render target. This is problematic in a lot of cases, especially when you want to access pixels afterwards. The manual just says

Quote:
"For accessing pixels of the bitmap afterwards, it can be converted back to a pixel format (bmap_to_format) or blitted onto another bitmap (bmap_blit)."

Here is a small snippet of a function, which I call "blit_process", which applies a shader to a bitmap WITHOUT changing it into a render target. It comes with an example shader, that rotates a bitmap about 90 degrees clockwise.

NOTICE: This function is not intended for calling it every frame, but for single image manipulations!

Code:
// Processes the content of <bmap> with a shader without (!) changing it to a rendertarget
// as bmap_process does. Returns <bmap> if everything went right; NULL otherwise.
//
BMAP* blit_process (BMAP* bmap, MATERIAL* shader)
{
    if (bmap == NULL || shader == NULL)
        return NULL;
        
    int w = bmap->width;
    int h = bmap->height;
    
    if (w <= 0 || h <= 0)
        return NULL;
    
    // create temporary bitmap as RT for the shader
    BMAP* to = bmap_createblack(w, h, bmap_format(bmap));
    
    // apply shader to bmap and render into target
    bmap_process(to, bmap, shader);
    
    // update source bitmap with contents of RT
    bmap_blit(bmap, to, NULL, NULL);
    
    ptr_remove(to); // delete RT
    return bmap;
}



demo code:
Code:
MATERIAL* mtlRot90 = {
    effect = "rot90.fx";
}

int main ()
{
    wait(1);
    
    BMAP* test = bmap_create("test.png");
    video_set(test->width, test->height, 0, 0);
    
    while (!key_space)
    {
        draw_quad(test, nullvector, NULL, NULL, NULL, NULL, 100, 0);
        wait(1);
    }
    
    while (key_space) wait(1);
    
    blit_process(test, mtlRot90);
    
    while (!key_space)
    {
        draw_quad(test, nullvector, NULL, NULL, NULL, NULL, 100, 0);
        wait(1);
    }	
}



rot90.fx:
Code:
Texture TargetMap;
sampler2D smpSrc = sampler_state { texture = <TargetMap>; };

float4 PS (float2 tex : TEXCOORD0): COLOR
{
    float alpha = radians(90);
    
    float2x2 R = { cos(alpha), -sin(alpha),
                   sin(alpha),  cos(alpha)};
                   
    float2 uv = mul(tex.xy - 0.5, R) + 0.5;
    
    return float4(tex2D(smpSrc, uv).rgb, 1);
}

technique t
{
    pass p
    {
        PixelShader = compile ps_2_0 PS();
    }
}



demo result:

src: "Lynx or Bobcat" by Karen Arnold (public domain)

I hope this is useful for somebody smile

Last edited by HeelX; 04/08/13 20:58.