Posted By: HeelX
blit_process - 04/08/13 20:21
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
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!
demo code:
rot90.fx:
demo result:
src: "Lynx or Bobcat" by Karen Arnold (public domain)
I hope this is useful for somebody
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