0 registered members (),
1,397
guests, and 7
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
blit_process
#421033
04/08/13 20:21
04/08/13 20:21
|
Joined: Jul 2001
Posts: 6,904
HeelX
OP
Senior Expert
|
OP
Senior Expert
Joined: Jul 2001
Posts: 6,904
|
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 "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!
// 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:
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:
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
Last edited by HeelX; 04/08/13 20:58.
|
|
|
|