clear part of a bmap

Posted By: Kartoffel

clear part of a bmap - 12/09/15 20:09

Hey there,

I'm looking for a (fast) way to clear a rectangular area of an ARGB8 bmap.
bmap_blit doesn't really work for me because of it's bad performance.

any ideas?
Posted By: Anonymous

Re: clear part of a bmap - 12/10/15 00:54

No sure what you would like to achieve

Few Ideas,

1)Tack a higher layer panel->bmap over the lower panel->bmap (assumes panels)
2) draw a draw_quad over the area.
Posted By: sivan

Re: clear part of a bmap - 12/10/15 08:14

I think if you check the BMAP struct in atypes.h you can access the actual bytes (maybe called as finalbits) to handle my a loop of memsets (resulting in areay loop length instead of areax*areay). But the BMAP should be locked/unlocked.
By the way, bmap_blit() is not okay for bmaps having an alpha channel at all.
Please tell me if succeeded, I would use it too. laugh
Posted By: Kartoffel

Re: clear part of a bmap - 12/10/15 12:41

well, the problem with bmap_blit is that it's done on the cpu, same with accessing the bmap's content via code. I'm trying to implement a dynamic texture atlas for my own interface system, but I need a fast way (a gpu-side approach, preferrably) for filling (rectangular) areas of a bmap with only transparent pixels.
Posted By: Superku

Re: clear part of a bmap - 12/10/15 12:50

If it was possible to set values in script (like dimensions), then use bmap_process and paint on the bitmap according to those values, then that would be the fastest way I assume.
I haven't tried that in a long time but I think the material/ effect only receives those values once per frame. Maybe it's possible to use some directX function? I don't know.
Should you try that and figure it out, please tell me the results.
Posted By: Reconnoiter

Re: clear part of a bmap - 12/10/15 12:54

This seems like the same idea as Sivan's, but maybe it helps you or gives you more ideas (ps this example is in c# but my quess is that it is possible in c too):

http://stackoverflow.com/questions/6020406/travel-through-pixels-in-bmp
Posted By: Kartoffel

Re: clear part of a bmap - 12/10/15 13:39

Thanks for your ideas and suggestions, I'll try messing around with these approaches later and let you know if it works. laugh

I guess bmap_process should be the fastest as Superku said. The biggest Problem with this method is that you have to render the whole bmap, even if you're just clearing a small part of it.
However, since I'm currently working towards low-res graphics this could be a solution that's good enough.
Posted By: Kartoffel

Re: clear part of a bmap - 12/10/15 18:50

Here's a bmap_process implementation:

the shader file "ppBmapClearRect.fx"
Code:
const float4 vecSkill1;

//==========

const texture TargetMap;
sampler2D smpTex = sampler_state
{
	Texture = <TargetMap>;
	
	MipFilter = Point;
	MagFilter = Point;
	MinFilter = Point;
	
	AddressU = Clamp;
	AddressV = Clamp;
};

//==========

float4 PShader(in float4 vPos : VPOS) : COLOR0
{
	if(clamp(vPos.x, vecSkill1.x, vecSkill1.y) != vPos.x || clamp(vPos.y, vecSkill1.z, vecSkill1.w) != vPos.y)
		clip(-1);
	
	return float4(0, 0, 0, 0);
}

//==========

technique Tech_PP
{
	pass Pass_1
	{
		AlphaBlendEnable = False;
		
		PixelShader = compile ps_3_0 PShader();
	}
}


and the functions

Code:
MATERIAL * ppBmapClearRect = { effect = "ppBmapClearRect.fx"; }

//

// clear a rectangular part of a bmap (parameters: size and offset)
void bmap_clear_rect(BMAP * bmap, int size_x, int size_y, int offset_x, int offset_y)
{
	ppBmapClearRect->skill1 = floatv(offset_x);
	ppBmapClearRect->skill2 = floatv(offset_x + size_x);
	ppBmapClearRect->skill3 = floatv(offset_y);
	ppBmapClearRect->skill4 = floatv(offset_y + size_y);
	
	bmap_process(bmap, bmap, ppBmapClearRect);
}

// clear a rectangular part of a bmap (parameters: min and max x,y)
void bmap_clear_rect_minmax(BMAP * bmap, int left, int top, int right, int bottom)
{
	ppBmapClearRect->skill1 = floatv(left);
	ppBmapClearRect->skill2 = floatv(right);
	ppBmapClearRect->skill3 = floatv(top);
	ppBmapClearRect->skill4 = floatv(bottom);
	
	bmap_process(bmap, bmap, ppBmapClearRect);
}

edit: note that the coordinates start with 0, 0 as the top left corner

There are however some things to consider:

- there are some issues with bmaps after you used bmap_process (most likely because they somehow stay a rendertarget after the processing is done)
This causes the bmap to lose it's content when changing the resolution and sometimes when tabbing out and in to your game in fullscreenmode

after you've used bmap_process you can use bmap_to_format(your_bmap, bmap_format(your_bmap)); to force a redraw of your bmap, which will solve this problem.

- if your bmap is bigger than your engine window resolution you have to increase the zbuffer scale like so: bmap_zbuffer(bmap_createblack(2048, 2048, 8888));
© 2024 lite-C Forums