tonyg
Junior Member
Posts: 73
|
Post by tonyg on Mar 3, 2005 10:24:30 GMT
Is it possible to access individual images buffers and the backbuffer to use Read/Writepixelfast? Is it possible to set a portion of an object/image as Alpha... e.g. Bottom half of a character standing in water. Thanks
|
|
|
Post by Jake on Mar 3, 2005 16:05:20 GMT
Is it possible to access individual images buffers and the backbuffer to use Read/Writepixelfast? See HUD_GetTextureHandle. Use this with Texturebuffer() to get the Buffer you need for Write/ReadPixelfast. Hmm, Gradients with alpha would be cool. Mike, what about it?
|
|
tonyg
Junior Member
Posts: 73
|
Post by tonyg on Apr 12, 2005 22:10:32 GMT
It's taken me a little while to test this and there's a bit of a restriction. HUD_CreateImage will create an Object type instance pointing to the resource texture. If I use HUD_GetcTextureHandle and WPF it will change the resource texture affecting all HUD_CreateImage object instances pointing to that resource. I can't see a way around it (pros/cons of a single surface I suppose). This is what I did...
Graphics3D 640,480 SetBuffer BackBuffer() Include "../sprite candy.bb" cam% = CreateCamera() hud1% = HUD_Create(cam) resource1% = HUD_LoadImageResource ("../Media/image1.png",4) imagelayer% = HUD_CreateLayer(hud1,resource1) Image1% = HUD_CreateImage (ImageLayer, 150, 300 , 259, 277, 64, 64) image2% = HUD_CreateImage (ImageLayer, 150, 300 , 259, 277, 64, 64) HUD_PositionObject Image1,100,100 HUD_PositionObject Image2,200,100 HUD_Update() UpdateWorld() RenderWorld Flip WaitKey() Cls blitz_handle% = HUD_GetTextureHandle (resource1) HUD_Update() UpdateWorld() RenderWorld Text 0,0,blitz_handle Flip WaitKey() SetBuffer TextureBuffer(blitz_handle) LockBuffer TextureBuffer(blitz_handle) For x = 259 To 300 For y = 277 To 300 WritePixelFast x,y,$FFFF0000,TextureBuffer(blitz_handle) Next Next UnlockBuffer TextureBuffer(blitz_handle) SetBuffer BackBuffer() HUD_PositionObject Image1,100,100 HUD_PositionObject Image2,200,100 HUD_Update() UpdateWorld() RenderWorld Flip WaitKey() End
which shows both image1 and image2 affected. Can anybody see a way around it? <edit> This has worried me a bit. I'm looking for a way to do 2D composite sprites. I need the ability to merge images (i.e. base sprite + helmet + sword + shield) and also colour each individually. <edit> I've managed to do this using CreateTexture, CopyRect and HUD_LoadMemoryResource but it negates single surface for this type of image and could lead to performance problems. <edit> Typical CopyRect doesn't keep mask values.
|
|
tonyg
Junior Member
Posts: 73
|
Post by tonyg on Apr 13, 2005 23:39:59 GMT
This is what I came up with. Be careful with image3 as the image1.png has 'near-black' in the middle of the arrow. I changed it to 0,0,0 hence tg_image1.png. Any optimisations or a better method welcome although the function takes about 3ms to run.
Graphics3D 640,480 SetBuffer BackBuffer() Include "../sprite candy.bb" Global resource1, resource2 cam% = CreateCamera() hud1% = HUD_Create(cam) resource1% = HUD_LoadImageResource("../media/tg_image1.png",4) imagelayer1% = HUD_CreateLayer(hud1,resource1) image1% = HUD_CreateImage(imagelayer1,0,0,259,277,64,64) tg_tex = CreateTexture(64,64,4) resource2% = HUD_LoadMemoryResource(tg_tex,4) imagelayer2%=HUD_CreateLayer(hud1,resource2) image2%=HUD_CreateImage(imagelayer2,0,0,0,0,64,64) image3%=HUD_CreateImage(imagelayer1,0,0,392,412,55,55) tgHUD_PasteImage(image1,259,277,64,64,image2,0,0,0) tgHUD_PasteImage(image3,392,412,55,55,image2,3,3,1) While Not KeyHit(1) Cls HUD_PositionObject image1,100,100 HUD_PositionObject image2,200,100 HUD_PositionObject image3,300,100 HUD_Update() UpdateWorld RenderWorld Flip Wend Function tgHUD_PasteImage(s_image%,s_x,s_y,s_w,s_h,t_image%,t_x,t_y,mask,maskr=-1,maskg=-1,maskb=-1) ; s_image : source image object handle used for CreateImage ; s_x,s_y,s_w,s_h : image position and W/H in resource image or can be used as from/to ; t_image : target image object handle used for CreateImage ; t_x,_t_y : target copy x/y start points. ; mask : Whether to maskimage (0=no,1=yes) ; maskr,maskg,maskb = RGB mask colours. ; Might add alpha if needed and change the s_x values in relation to the object image. Local Source.SC_Object = Object.SC_Object(s_image) : If Source = Null Then RuntimeError SC_BreakText("tgHUD_PasteImage||The specified object does not exist.",50) Local Target.SC_Object = Object.SC_Object(t_image) : If Source = Null Then RuntimeError SC_BreakText("tgHUD_PasteImage||The specified object does not exist.",50) Local OBJSource.SC_Image = Object.SC_Image(Source\ImageID) Local OBJTarget.SC_Image = Object.SC_Image(Target\imageID) s_texture=HUD_GetTextureHandle(OBJSource\TextureID) t_texture=HUD_GetTextureHandle(OBJTarget\TextureID) Dim SC_Img%(s_w,s_h) If mask=1 If maskr=-1 maskr=0 If maskg=-1 maskg=0 If maskb=-1 maskb=0 EndIf LockBuffer TextureBuffer(s_texture) For y = s_y To (s_y+s_h)-1 For x = s_x To (s_x+s_w)-1 SC_Img(x-s_x,y-s_y) = ReadPixelFast(x,y,TextureBuffer(s_texture)) And $00FFFFFF Next Next UnlockBuffer TextureBuffer(s_texture) LockBuffer TextureBuffer(t_texture) For y = 0 To s_h-1 For x = 0 To s_w-1 argb= SC_Img(x,y) If argb <> ((maskR Shl 16)+(maskg Shl 8) + maskb) WritePixelFast x+t_x,y+t_y,(argb Or $FF000000),TextureBuffer(t_texture) EndIf Next Next UnlockBuffer TextureBuffer(t_texture) End Function
|
|
tonyg
Junior Member
Posts: 73
|
Post by tonyg on Apr 14, 2005 22:07:14 GMT
and with alpha and x/y relative to the image object rather than the resource image.
Graphics3D 640,480 SetBuffer BackBuffer() Include "../sprite candy.bb" Global resource1, resource2 cam% = CreateCamera() hud1% = HUD_Create(cam) resource1% = HUD_LoadImageResource("../media/tg_image1.png",4) imagelayer1% = HUD_CreateLayer(hud1,resource1) image1% = HUD_CreateImage(imagelayer1,0,0,259,277,64,64) tg_tex = CreateTexture(64,64,4) tg_tex1= CreateTexture(64,64,4) resource2% = HUD_LoadMemoryResource(tg_tex,4) resource3% = HUD_LoadMemoryResource(tg_tex1,4) imagelayer2%=HUD_CreateLayer(hud1,resource2) imagelayer3%=HUD_CreateLayer(hud1,resource3) image2%=HUD_CreateImage(imagelayer2,0,0,0,0,64,64) image3%=HUD_CreateImage(imagelayer1,0,0,392,412,55,55) image4%=HUD_CreateImage(imagelayer3,0,0,0,0,64,64) tgHUD_PasteImage(image1,image2) tgHUD_PasteImage(image2,image4,0.5) tgHUD_PasteImage(image3,image2,0.3,1,0,0,-1,-1,3,3) While Not KeyHit(1) Cls HUD_PositionObject image1,100,100 HUD_PositionObject image2,200,100 HUD_PositionObject image3,300,100 HUD_PositionObject image4,400,100 HUD_Update() UpdateWorld RenderWorld Flip Wend Function tgHUD_PasteImage(s_image%,t_image%,ALPHA#=1.0,mask=0,s_x=0,s_y=0,s_w=-1,s_h=-1,t_x=0,t_y=0,maskr=-1,maskg=-1,maskb=-1) start_time = MilliSecs() ; s_image : source image object handle used for CreateImage ; t_image : target image object handle used for CreateImage ; alpha : 0.0 to 1.0 ; mask : Whether to maskimage (0=no,1=yes) using maskr,maskg,maskb ; s_x,s_y : Start copy x/y position of source object image. 0,0, = start of image. ; s_w,s_h : End copy position width/height of source object image. -1,-1 = imagewidth,imageheight ; t_x,_t_y : start x/y position on target. ; maskr,maskg,maskb = RGB mask colours. Default is black (0,0,0) Local Source.SC_Object = Object.SC_Object(s_image) : If Source = Null Then RuntimeError SC_BreakText("tgHUD_PasteImage||The specified object does not exist.",50) Local Target.SC_Object = Object.SC_Object(t_image) : If Source = Null Then RuntimeError SC_BreakText("tgHUD_PasteImage||The specified object does not exist.",50) Local OBJSource.SC_Image = Object.SC_Image(Source\ImageID) Local OBJTarget.SC_Image = Object.SC_Image(Target\imageID) s_texture=HUD_GetTextureHandle(OBJSource\TextureID) t_texture=HUD_GetTextureHandle(OBJTarget\TextureID) If s_w = -1 s_w=OBJSource\clip_w If s_h = -1 s_h=OBJSource\clip_h s_w = s_w-s_x s_h = s_h - s_y If s_w+t_x > OBJTarget\img_w Then RuntimeError SC_BreakText("tgHUD_PasteImage||Paste size larger than target x size.",50) If s_h+t_y > OBJTarget\img_h Then RuntimeError SC_BreakText("tgHUD_PasteImage||Paste size larger than target y size.",50) If s_w > OBJSource\clip_w Then RuntimeError SC_BreakText("tgHUD_PasteImage||Invalid clip w.",50) If s_h > OBJSource\clip_h Then RuntimeError SC_BreakText("tgHUD_PasteImage||Invalid clip h.",50) s_x=s_x + OBJSource\clip_x s_y=s_y + OBJSource\clip_y If s_x >= OBJSource\clip_x+OBJSource\clip_w Then RuntimeError SC_BreakText("tgHUD_PasteImage||Invalid start x.",50) If s_y >= OBJSource\clip_x+OBJSource\clip_h Then RuntimeError SC_BreakText("tgHUD_PasteImage||Invalid start y.",50) Dim SC_Img%(s_w,s_h) If mask=1 If maskr=-1 maskr=0 If maskg=-1 maskg=0 If maskb=-1 maskb=0 EndIf
LockBuffer TextureBuffer(s_texture) For y = s_y To (s_y+s_h)-1 For x = s_x To (s_x+s_w)-1 SC_Img(x-s_x,y-s_y) = ReadPixelFast(x,y,TextureBuffer(s_texture)) And $00FFFFFF Next Next UnlockBuffer TextureBuffer(s_texture) t_alpha# = 1.0 - alpha# If t_alpha < 0 Then RuntimeError SC_BreakText("tgHUD_PasteImage||Invalid Alpha value",50) LockBuffer TextureBuffer(t_texture) For y = 0 To s_h-1 For x = 0 To s_w-1 argb= SC_Img(x,y) If t_alpha > 0.0 And argb <> ((maskR Shl 16)+(maskg Shl 8) + maskb) trgb = ReadPixelFast(x+t_x,y+t_y,TextureBuffer(t_texture)) And $00FFFFFF nrgb = ((trgb Shr 16 And $ff)*t_alpha + (argb Shr 16 And $ff)*alpha) Shl 16 Or ((trgb Shr 8 And $ff)*t_alpha + (argb Shr 8 And $ff)*alpha) Shl 8 Or ((trgb Shr 0 And $ff)*t_alpha + (argb Shr 0 And $ff)*alpha) Shl 0 Else If argb <> maskR Shl 16 Or maskG Shl 8 Or maskB nrgb = argb Else trgb = ReadPixelFast(x+t_x,y+t_y,TextureBuffer(t_texture)) And $00FFFFFF nrgb = trgb EndIf WritePixelFast x+t_x,y+t_y,(nrgb Or $FF000000),TextureBuffer(t_texture) Next Next UnlockBuffer TextureBuffer(t_texture) End_time=MilliSecs() DebugLog "Time in ms " + (end_time-start_time) + " Alpha : " + alpha + " Mask : " + mask End Function
Still not sure whether there is a better way. CopyRect, grabimage etc doesn't seem to work with textures. The output is an object image with it's own image resource which defeats the object of a single surface product especially if it's used with multiple animations. Maybe it would be better to do this against an animation sheet which would be too slow for realtime. I'd appreciate any comments, especially from X-pressive when they return from their break.
|
|
|
Post by Xpressive on Apr 17, 2005 6:06:23 GMT
Please let me know what you'd like to do in detail. Do you want to display an image that contains some alpha masked parts?
|
|
tonyg
Junior Member
Posts: 73
|
Post by tonyg on Apr 17, 2005 7:42:41 GMT
If we have a 64*64 image, it would be nice to only apply alpha to a portion of it (i.e. from 32,32 to 64,64.) It would be nice to be able to apply an alpha gradient to an image as well. <edit> To be honest, I can do this myself with WPF. Howver, I am more interested in the best method to change an image without it affecting other handles pointing to the same image. Is there a better method than the above?
|
|
|
Post by Jake on Apr 17, 2005 18:42:14 GMT
If we have a 64*64 image, it would be nice to only apply alpha to a portion of it (i.e. from 32,32 to 64,64.) It would be nice to be able to apply an alpha gradient to an image as well. 1.) Split your image into multiple smaller images to apply alpha to parts of your large image. 2.) Use HUD_SetVertexAlpha to create alpha-gradients.
|
|