Masking - how to get about creating a Worm clone?
BlitzMax Forums/BlitzMax Programming/Masking - how to get about creating a Worm clone?
| ||
What would be a good way to punch holes in a gameīs playfield using Bmax? Iīm thinking something like this Put a copy of the game playfield into a temporary fullscreen buffer (I guess this is a problem if one have a huge world so alternative solutions are very welcome) The main drawing loop would look like this 1) Paint the background 2) Paint the temp playfield ontop 3) paint sprites And to get the playfield to explode into holes, you would erase somehow (instead of drawing), how would you do that? I would like to erase using the shape of an image instead to have the holes to be certain shapes. At the next level you copy a new fresh playfield into this temp. How would you erase inside an image? (I have the drawing image in an image going on, using VBO right now) So drawing are working perfectly, but how do you erase using images? Also, how would you do it? Iīll bet there are thousand of ways doing this, I just picked this way right now as it felt the closest to what I already had going on. |
| ||
Can you post an image example of this, Casaber ? Maybe two images - BEFORE and AFTER, perhaps with a paint program ? I might be able to help if I could visually see what you are saying. |
| ||
Sure, So I made this mockup which should be the before and after playfields. I want to use sprites I usuallly draw with to cookiecut the landscape effeciently somehow. Iīm not sure what would be the best strategy (and Iīm not able to do it in practice yet using ANY strategy) Any ideas? ![]() |
| ||
Couldn't you have a 1bpp mask that represents the visible/destructed surface, and simply mask out stuff with bit set to 0, and draw stuff with bit set to 1? You could also use this mask for collision detection. :-) |
| ||
I cooked up a Worms like clone a few years a go: http://www.blitzmax.com/Community/posts.php?topic=89848 Its not perfect but shows a different way to do it... |
| ||
Oh ... Looking at therevill's game demo. Yeah, that's not hard to do at all. Shoot. Just have a static background, and pop some circles in for good effect. You'll need some masking for that. I did something like this in GFA years ago, called it Cookie Cutter. Lemme see ... Strict Graphics 640,480 SetBlend alphablend Global img:TImage=CreateImage(640,480),pic:TPixmap,i,j For i=0 To 639 DrawOval i,Rand(480),32,32 Next GrabImage img,0,0 pic=LockImage(img) For i=0 To 479 For j=0 To 639 If ReadPixel(pic,j,i) WritePixel pic,j,i,Rand(128)Shl 8|$ff000000 EndIf Next Next UnlockImage(img) Repeat For i=0 To 479 SetColor 0,0,i Mod 256 DrawLine 0,i,639,i Next SetColor 255,255,255 DrawImage img,0,0 Flip If MouseDown(1) Cls DrawImage img,0,0 SetColor 0,0,0 DrawOval MouseX()-32,MouseY()-32,64,64 GrabImage img,0,0 EndIf Until KeyDown(32) Now this works but there is something unusual. It starts to slow down the more circles you cut. Any ideas on why it's doing this, guys ? |
| ||
Couldn't you have a 1bpp mask that represents the visible/destructed surface, and simply mask out stuff with bit set to 0, and draw stuff with bit set to 1? Sounds like an idea but do you mean keeping bitmask in an array or bank or are there hardwareaccelerated features to do this somehow? @ therevill's I will have to take some time and look carefully into that code, thanks a alot for that. Now this works but there is something unusual. It starts to slow down the more circles you cut. Any ideas on why it's doing this, guys ? Nice. The slowdown with time must be something going on with the GrabImage? Maybe itīs reallocating or something and not reusing things not that I understand exactly how that would be. Weird. That was a short and simpel solution, such a pity that it had that slowdown I shall think about this. |
| ||
Sounds like an idea but do you mean keeping bitmask in an array or bank or are there hardwareaccelerated features to do this somehow? It's probably doable using shaders with very little overhead. |
| ||
Shaders are great solution for many things but right now I'm trying to avoid that while Iīm learning the first steps of BlitzMax. When I add shader, it will probably bunch together more problems and solutions things into ones single one. Which is nice. And I'm of looking forward to that. But the reality check tells me I need to try and solve it without those kind of solutions right now. |
| ||
Yeah, no kidding, Casaber. Really strange. Minju, if someone else has a source example to do the same with no increased delays per grabimage, would love to see it. Can always learn something new. :) |
| ||
dw817 Here is a template, which setups up 2 buffers and paints to both and shows how to copy one to another. I need to sleep now, but I think you'll find this very useful maybe it could be used for this problem I'm having, your example makes me think; hell yes ;) (you donīt need to understand or read the actual functions they just switch the actual buffers and you see how to do that in the main loop. I would guess itīs 10-100 times faster than GRABIMAGE. Look at it as if you suddenly got SETBUFFER from Blitz3D (or heaven) into Blitzmax. HideMouse ; TImageBuffer.Init(1920,1080,32,60) 'Same as Graphics but set to GLDriver + glewinit SetBlend(MASKBLEND) ; Local xd = 2 ' init img Global img = CreateImage(512,512,1) Local IB:TImageBuffer = TImageBuffer.SetBuffer(Img) ' init img2 Global img2 = CreateImage(512,512,1) Local IB2:TImageBuffer = TImageBuffer.SetBuffer(Img2) ' ------------------------------- While Not MouseDown(2) ' Draw onto img (note that y coordinate is inverted) IB.BindBuffer() For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ' draw something 'DrawSubImageRect img2,0,128-0,128,-128, 0,0,128,128 ' this copies img2 to img IB.UnBindBuffer() ' Draw onto img2 (note that y coordinate is inverted) IB2.BindBuffer() For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ' draw something 'DrawSubImageRect img2,0,128-0,128,-128, 0,0,128,128 ' this copies img to img2 IB2.UnBindBuffer() ' Draw onto backbuffer (normal) SetViewport 0,0,1920,1080 ; Cls 'For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(127)),Int(Rnd(63+16)) ; Next DrawImage img,xsprite,0 ' draw img DrawImage img2,512,0 ' draw img2 xsprite=xsprite + xd If xsprite > ((1920 - (32*16))/4) Then xd = - xd If xsprite < 0 Then xd=-xd Delay 1 ; Flip 1 Wend End ' ------------------------------- Rem Strict Graphics 640,480 SetBlend alphablend Global img:TImage=CreateImage(640,480),pic:TPixmap,i,j For i=0 To 639 DrawOval i,Rand(480),32,32 Next GrabImage img,0,0 pic=LockImage(img) For i=0 To 479 For j=0 To 639 If ReadPixel(pic,j,i) WritePixel pic,j,i,Rand(128)Shl 8|$ff000000 EndIf Next Next UnlockImage(img) Repeat For i=0 To 479 SetColor 0,0,i Mod 256 DrawLine 0,i,639,i Next SetColor 255,255,255 DrawImage img,0,0 Flip If MouseDown(1) Cls DrawImage img,0,0 SetColor 0,0,0 DrawOval MouseX()-32,MouseY()-32,64,64 GrabImage img,0,0 EndIf Until KeyDown(32) EndRem ' ------------------------------- Type TImageBuffer Field Image:TImage Field rb:Int[1] Field fb:Int[1] Field Imageframe:TGLImageframe Field Frame:Int = 0 Field OrigX:Int Field OrigY:Int Field OrigW:Int Field OrigH:Int Function SetBuffer:TImageBuffer(Image:TImage,Frame:Int = 0 ) Local IB:TImageBuffer = New TImageBuffer IB.Image = Image ; IB.Frame = Frame ; IB.GenerateFBO() ; IB.BindBuffer() Return IB End Function Function Init(Width:Int,Height:Int,Bit:Int=0,Mode:Int=60) SetGraphicsDriver(GLMax2DDriver()) ; Graphics Width , Height,bit,Mode ; glewInit() End Function Method GenerateFBO() ImageFrame = TGLImageFrame(Image.frame(Frame) ) imageframe.v0 = imageframe.v1 imageframe.v1 = 0.0 Local W:Int = Image.width Local H:Int = Image.Height AdjustTexSize(W , H) glGenFramebuffersEXT(1, fb ) glGenRenderbuffersEXT(1 , rb) glBindTexture(GL_TEXTURE_2D, Imageframe.name); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , fb[0]) ; glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, Imageframe.name, 0); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb[0]); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, W, H); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT , GL_DEPTH_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , rb[0]) Local status:Int = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) Select status Case GL_FRAMEBUFFER_COMPLETE_EXT Print "all right" + " : " + Status Case GL_FRAMEBUFFER_UNSUPPORTED_EXT Print "choose different formats" Default End EndSelect End Method Method BindBuffer() GetViewport(OrigX,OrigY,OrigW,OrigH) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , fb[0]) glMatrixMode GL_PROJECTION glLoadIdentity glOrtho 0,Image.Width,Image.Width,0,-1,1 glMatrixMode GL_MODELVIEW glViewport(0 , 0 , Image.Width , Image.Height) glScissor 0,0, Image.Width , Image.Height End Method Method UnBindBuffer() glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , 0) glMatrixMode GL_PROJECTION glLoadIdentity glOrtho 0,OrigW ,Origh,0,-1,1 glMatrixMode GL_MODELVIEW glViewport(0 , 0 , OrigW, OrigH) glScissor 0,0, OrigW ,OrigH End Method Method Cls(r#=0.0,g#=0.0,b#=0.0,a#=1.0) glClearColor r,g,b,a glClear GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT End Method Method BufferWidth:Int() Return Image.Width End Method Method BufferHeight:Int() Return Image.Height End Method End Type Function AdjustTexSize( width:Int Var,height:Int Var ) width=Pow2Size( width ) ; height=Pow2Size( height ) Repeat Local t:Int glTexImage2D GL_PROXY_TEXTURE_2D,0,4,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,Null glGetTexLevelParameteriv GL_PROXY_TEXTURE_2D,0,GL_TEXTURE_WIDTH,Varptr t If t Return If width=1 And height=1 RuntimeError "Unable to calculate tex size" If width>1 width:/2 If height>1 height:/2 Forever End Function Function Pow2Size:Int( n:Int ) Local t:Int=1 While t<n ; t:*2 ; Wend Return t End Function |
| ||
dw817 Here is a template, which setups up 2 buffers and paints to both and shows how to copy one to another. I need to sleep now, but I think you'll find this very useful maybe it could be used for this problem I'm having, your example makes me think; hell yes ;) (you donīt need to understand or read the actual functions they just switch the actual buffers and you see how to do that in the main loop. I would guess itīs 10-100 times faster than GRABIMAGE. Look at it as if you suddenly got SETBUFFER from Blitz3D (or heaven) into Blitzmax. HideMouse ; TImageBuffer.Init(1920,1080,32,60) 'Same as Graphics but set to GLDriver + glewinit SetBlend(MASKBLEND) ; Local xd = 2 ' create images Global img = CreateImage(512,512,1) Local IB:TImageBuffer = TImageBuffer.SetBuffer(Img) Global img2 = CreateImage(512,512,1) Local IB2:TImageBuffer = TImageBuffer.SetBuffer(Img2) ' ------------------------------- While Not MouseDown(2) ' Draw onto img (note that y coordinate is inverted) IB.BindBuffer() For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ' draw something 'DrawSubImageRect img2,0,128-0,128,-128, 0,0,128,128 ' this copies img2 to img IB.UnBindBuffer() ' Draw onto img2 (note that y coordinate is inverted) IB2.BindBuffer() For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ' draw something 'DrawSubImageRect img2,0,128-0,128,-128, 0,0,128,128 ' this copies img to img2 IB2.UnBindBuffer() ' Draw onto backbuffer (normal) SetViewport 0,0,1920,1080 ; Cls 'For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(127)),Int(Rnd(63+16)) ; Next DrawImage img,xsprite,0 ' draw img DrawImage img2,512,0 ' draw img2 xsprite=xsprite + xd If xsprite > ((1920 - (32*16))/4) Then xd = - xd If xsprite < 0 Then xd=-xd Delay 1 ; Flip 1 Wend End ' ------------------------------- Rem Strict Graphics 640,480 SetBlend alphablend Global img:TImage=CreateImage(640,480),pic:TPixmap,i,j For i=0 To 639 DrawOval i,Rand(480),32,32 Next GrabImage img,0,0 pic=LockImage(img) For i=0 To 479 For j=0 To 639 If ReadPixel(pic,j,i) WritePixel pic,j,i,Rand(128)Shl 8|$ff000000 EndIf Next Next UnlockImage(img) Repeat For i=0 To 479 SetColor 0,0,i Mod 256 DrawLine 0,i,639,i Next SetColor 255,255,255 DrawImage img,0,0 Flip If MouseDown(1) Cls DrawImage img,0,0 SetColor 0,0,0 DrawOval MouseX()-32,MouseY()-32,64,64 GrabImage img,0,0 EndIf Until KeyDown(32) EndRem ' ------------------------------- Type TImageBuffer Field Image:TImage Field rb:Int[1] Field fb:Int[1] Field Imageframe:TGLImageframe Field Frame:Int = 0 Field OrigX:Int Field OrigY:Int Field OrigW:Int Field OrigH:Int Function SetBuffer:TImageBuffer(Image:TImage,Frame:Int = 0 ) Local IB:TImageBuffer = New TImageBuffer IB.Image = Image ; IB.Frame = Frame ; IB.GenerateFBO() ; IB.BindBuffer() Return IB End Function Function Init(Width:Int,Height:Int,Bit:Int=0,Mode:Int=60) SetGraphicsDriver(GLMax2DDriver()) ; Graphics Width , Height,bit,Mode ; glewInit() End Function Method GenerateFBO() ImageFrame = TGLImageFrame(Image.frame(Frame) ) imageframe.v0 = imageframe.v1 imageframe.v1 = 0.0 Local W:Int = Image.width Local H:Int = Image.Height AdjustTexSize(W , H) glGenFramebuffersEXT(1, fb ) glGenRenderbuffersEXT(1 , rb) glBindTexture(GL_TEXTURE_2D, Imageframe.name); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , fb[0]) ; glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, Imageframe.name, 0); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb[0]); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, W, H); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT , GL_DEPTH_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , rb[0]) Local status:Int = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) Select status Case GL_FRAMEBUFFER_COMPLETE_EXT Print "all right" + " : " + Status Case GL_FRAMEBUFFER_UNSUPPORTED_EXT Print "choose different formats" Default End EndSelect End Method Method BindBuffer() GetViewport(OrigX,OrigY,OrigW,OrigH) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , fb[0]) glMatrixMode GL_PROJECTION glLoadIdentity glOrtho 0,Image.Width,Image.Width,0,-1,1 glMatrixMode GL_MODELVIEW glViewport(0 , 0 , Image.Width , Image.Height) glScissor 0,0, Image.Width , Image.Height End Method Method UnBindBuffer() glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , 0) glMatrixMode GL_PROJECTION glLoadIdentity glOrtho 0,OrigW ,Origh,0,-1,1 glMatrixMode GL_MODELVIEW glViewport(0 , 0 , OrigW, OrigH) glScissor 0,0, OrigW ,OrigH End Method Method Cls(r#=0.0,g#=0.0,b#=0.0,a#=1.0) glClearColor r,g,b,a glClear GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT End Method Method BufferWidth:Int() Return Image.Width End Method Method BufferHeight:Int() Return Image.Height End Method End Type Function AdjustTexSize( width:Int Var,height:Int Var ) width=Pow2Size( width ) ; height=Pow2Size( height ) Repeat Local t:Int glTexImage2D GL_PROXY_TEXTURE_2D,0,4,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,Null glGetTexLevelParameteriv GL_PROXY_TEXTURE_2D,0,GL_TEXTURE_WIDTH,Varptr t If t Return If width=1 And height=1 RuntimeError "Unable to calculate tex size" If width>1 width:/2 If height>1 height:/2 Forever End Function Function Pow2Size:Int( n:Int ) Local t:Int=1 While t<n ; t:*2 ; Wend Return t End Function |
| ||
Hmm ... That's a lot of code, Casaber. By changing the top line to:HideMouse ; TImageBuffer.Init(1920,1080)',32,60) When I run it, I just get a bunch of random pixels appearing at the top and some sliding in from the left to the right and back again, a copy from what is being created static. Is that what is supposed to happen ? Let me see if I can write some code to show very close to what I'm seeing: Strict Local d=1,x=-512,pic:TPixmap,img:TImage Graphics 1024,512 SetBlend lightblend pic=GrabPixmap(0,0,512,64) Repeat Cls pic.pixels[Rand(512*64*4)]=Rand(256) img=LoadImage(pic) DrawImage img,x,0 DrawImage img,0,0 Flip x:+d If x>=0 Or x<=-512 d=-d EndIf Until KeyDown(32) |
| ||
Yup :) those are two images img and img which are drawn onto, before drawing themselves as normal sprites to the screen. Itīs just a plotting colorful dots demo which shows two of these buffers in action, and yup the demo moves one of those sprites. Notice how there are NO slowdowns for drawing to them, itīs just if we just drew onto the screen. No substantial time is consumed for switching buffers or drawing them etc. It just flows right on. No thereīs not much code, I put dashes (-------) around the actual code what comes next is your code that I meant to re-implement. But never got to that point. Rest are just helper functions you donīt need to care about for starters. |
| ||
Cleaner version (and look here, also I put everything important in this one from the other thread aswell). So this is the holy grail you should be using. I has no array errors either. I shall check into your code next, this will be great. I simplified it, simpler moving sprites in this one for a better reading experience, just splatting two images are just fine I guess. I want the readability. I would like to make an more interesting demo where you copy from eachothers images, you know, just parts, but Itīs really that straightforward, I just need some time to sit down and come up with ideas. 1) Set the wanted destinationbuffer (see it as your SETBUFFER) e.g. IB2.BindBuffer() 2) Use DrawSubImageRect sourceimage,x,y,w,h,sx,sy,sw,sh 3) Tell that youīre finished with the buffer using e.g. IB2.UnBindBuffer() ' now the normal backbuffer is your canvas again But I think I would like to solve the inverted y coordinates "problem" before I go further becuase thatīs a pain to invert Y all the time in my head. I really would like that, and also get away with the :TImageBuffer = TImageBuffer.SetBuffer() at initiliasing images, just becuase it would look better. HideMouse ; TImageBuffer.Init(1920,1080,32,60) 'Same as Graphics but set to GLDriver + glewinit (or skip 32,60 for windowed version) SetBlend(MASKBLEND) ' Init images (I shall recode the need for the IB part if possible, but right now just see it as a package deal when you create an image to create a unique IB aswell, just look at the 2 examples and mimic new names) Global img = CreateImage(512,512,1) ; Local IB:TImageBuffer = TImageBuffer.SetBuffer(Img) Global img2 = CreateImage(512,512,1) ; Local IB2:TImageBuffer = TImageBuffer.SetBuffer(Img2) ' ------------------------------- MAIN LOOP ----------------------------------- While Not MouseDown(2) IB.BindBuffer() ' SETBUFFER img (AKA IB) ' Draw anything as usual here For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ' DrawSubImageRect img2,0,128-0,128,-128, 0,0,128,128 ' example how to copy img2 to img ' DrawSubImageRect img,0,128-0,128,-128, 0,0,128,128 ' example how to copy img to img (doing nothing, just out of curiousity and ideas) IB.UnBindBuffer() 'END IB2.BindBuffer() ' SETBUFFER img2 (aka IB2) ' Draw anything as usual here For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ' DrawSubImageRect img,0,128-0,128,-128, 0,0,128,128 ' example how to copy img to img2 ' DrawSubImageRect img2,0,128-0,128,-128, 0,0,128,128 ' example how to copy img2 to img2 (doing nothing, just out of curiousity and ideas) IB2.UnBindBuffer() 'END ' Drawing to normal backbuffer now, nothing special Cls DrawImage img,xsprite,0 ' Draw img DrawImage img2,512,0 ' Draw img2 xsprite = xsprite + 1 ; xsprite = xsprite Mod 1000 Delay 1 ; Flip 1 Wend ' ------------------------------- MAIN LOOP ----------------------------------- End Rem Global img:TImage=CreateImage(640,480),pic:TPixmap,i,j For i=0 To 639 DrawOval i,Rand(480),32,32 Next GrabImage img,0,0 pic=LockImage(img) For i=0 To 479 For j=0 To 639 If ReadPixel(pic,j,i) WritePixel pic,j,i,Rand(128)Shl 8|$ff000000 EndIf Next Next UnlockImage(img) Repeat For i=0 To 479 SetColor 0,0,i Mod 256 DrawLine 0,i,639,i Next SetColor 255,255,255 DrawImage img,0,0 Flip If MouseDown(1) Cls DrawImage img,0,0 SetColor 0,0,0 DrawOval MouseX()-32,MouseY()-32,64,64 GrabImage img,0,0 EndIf Until KeyDown(32) End EndRem ' ------------------------------- Type TImageBuffer Field Image:TImage Field rb:Int[1] Field fb:Int[1] Field Imageframe:TGLImageframe Field Frame:Int = 0 Field OrigX:Int Field OrigY:Int Field OrigW:Int Field OrigH:Int Function SetBuffer:TImageBuffer(Image:TImage,Frame:Int = 0 ) Local IB:TImageBuffer = New TImageBuffer IB.Image = Image ; IB.Frame = Frame ; IB.GenerateFBO() ; IB.BindBuffer() Return IB End Function Function Init(Width:Int,Height:Int,Bit:Int=0,Mode:Int=60) SetGraphicsDriver(GLMax2DDriver()) ; Graphics Width , Height,bit,Mode ; glewInit() End Function Method GenerateFBO() ImageFrame = TGLImageFrame(Image.frame(Frame) ) imageframe.v0 = imageframe.v1 imageframe.v1 = 0.0 Local W:Int = Image.width Local H:Int = Image.Height AdjustTexSize(W , H) glGenFramebuffersEXT(1, fb ) glGenRenderbuffersEXT(1 , rb) glBindTexture(GL_TEXTURE_2D, Imageframe.name); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , fb[0]) ; glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, Imageframe.name, 0); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb[0]); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, W, H); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT , GL_DEPTH_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , rb[0]) Local status:Int = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) Select status Case GL_FRAMEBUFFER_COMPLETE_EXT Print "all right" + " : " + Status Case GL_FRAMEBUFFER_UNSUPPORTED_EXT Print "choose different formats" Default End EndSelect End Method Method BindBuffer() GetViewport(OrigX,OrigY,OrigW,OrigH) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , fb[0]) glMatrixMode GL_PROJECTION glLoadIdentity glOrtho 0,Image.Width,Image.Width,0,-1,1 glMatrixMode GL_MODELVIEW glViewport(0 , 0 , Image.Width , Image.Height) glScissor 0,0, Image.Width , Image.Height End Method Method UnBindBuffer() glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , 0) glMatrixMode GL_PROJECTION glLoadIdentity glOrtho 0,OrigW ,Origh,0,-1,1 glMatrixMode GL_MODELVIEW glViewport(0 , 0 , OrigW, OrigH) glScissor 0,0, OrigW ,OrigH End Method Method Cls(r#=0.0,g#=0.0,b#=0.0,a#=1.0) glClearColor r,g,b,a glClear GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT End Method Method BufferWidth:Int() Return Image.Width End Method Method BufferHeight:Int() Return Image.Height End Method End Type Function AdjustTexSize( width:Int Var,height:Int Var ) width=Pow2Size( width ) ; height=Pow2Size( height ) Repeat Local t:Int glTexImage2D GL_PROXY_TEXTURE_2D,0,4,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,Null glGetTexLevelParameteriv GL_PROXY_TEXTURE_2D,0,GL_TEXTURE_WIDTH,Varptr t If t Return If width=1 And height=1 RuntimeError "Unable to calculate tex size" If width>1 width:/2 If height>1 height:/2 Forever End Function Function Pow2Size:Int( n:Int ) Local t:Int=1 While t<n ; t:*2 ; Wend Return t End Function |
| ||
This could be used for you know, if you hate to begin a new screen each and every frame (youīre forced to use a CLS to be sure to cover ALL machines you know, and usually you msy never ever rely on that things are stillthere from previous frames, which could be a gamechanger in how you need to code, and a drag sometimes). This way you could draw to an offline buffer, big as the screen. And just say go to hell with the backgroundbuffer and draw onto a offline buffer instead. Things will stay there. It's a way to do it. I like it. You donīt have to wait for things to be copied over the bus at all (but you still need to sacrifice fillrate), but that's cheap. |
| ||
Dontīt look at this for reference I just wanted to show an example how to create 8 512x512 sprites (or youcould look at them as atlases or offscreenbuffers aswell) and draw to all of them individually, and to show a buffer to buffer copy in action. And here DrawSubImageRect really comes into play in when you want to do things with those buffers. You can draw (aka copy) parts from buffer to buffer, to all of your hearts content at amazing speeds, no cost really. Just draw and forget it happened. Really nice. HideMouse ; TImageBuffer.Init(1920,1080,32,60) 'Same as Graphics but set to GLDriver + glewinit (or skip 32,60 for windowed version) SetBlend(MASKBLEND) ' Init images (I shall recode the need for the IB part if possible, but right now just see it as a package deal when you create an image to create a unique IB aswell, just look at the 2 examples and mimic new names) Global img = CreateImage(512,512,1) ; Local IB:TImageBuffer = TImageBuffer.SetBuffer(Img) Global img2 = CreateImage(512,512,1) ; Local IB2:TImageBuffer = TImageBuffer.SetBuffer(Img2) Global img3 = CreateImage(512,512,1) ; Local IB3:TImageBuffer = TImageBuffer.SetBuffer(Img3) Global img4 = CreateImage(512,512,1) ; Local IB4:TImageBuffer = TImageBuffer.SetBuffer(Img4) Global img5 = CreateImage(512,512,1) ; Local IB5:TImageBuffer = TImageBuffer.SetBuffer(Img5) Global img6 = CreateImage(512,512,1) ; Local IB6:TImageBuffer = TImageBuffer.SetBuffer(Img6) Global img7 = CreateImage(512,512,1) ; Local IB7:TImageBuffer = TImageBuffer.SetBuffer(Img7) Global img8 = CreateImage(512,512,1) ; Local IB8:TImageBuffer = TImageBuffer.SetBuffer(Img8) ' ------------------------------- MAIN LOOP ----------------------------------- While Not MouseDown(2) ' Draw to 8 images (offscreenbuffers if you like) IB.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; DrawOval 50+Int(Rnd(511-50)),50+Int(Rnd(511-50)),Int(Rnd(50)),Int(Rnd(50)) ; Next ; SetColor 255,255,255 ; IB.UnBindBuffer() 'END IB2.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB2.UnBindBuffer() 'END IB3.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB3.UnBindBuffer() 'END IB4.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB4.UnBindBuffer() 'END IB5.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB5.UnBindBuffer() 'END IB6.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB6.UnBindBuffer() 'END IB7.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB7.UnBindBuffer() 'END IB8.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB8.UnBindBuffer() 'END ' Letīs say I want to copy img (aka IB) to img8 (aka IB8), just to see it working (let's for instance copy the whole buffer to another as it is, as that's a nice thing to be able to do) IB8.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB8.UnBindBuffer() ' Something come to my mind ---------------- ' This demo does not show that well that it is actually an mask/alpha draw thatīs happening, so you may easly layer things, from layer to layer and from itself to another part of itself for instance. ' So it's a bad example showing of the REAL strength that IS happening, as we draw ovals which stay in place from the next frame so when it copies/draws from one to another, you never see that it layers, as its already there. ' So you never notice that it IS masked, it just looks like an opaque copy, but itīs not. Itīs a normal (and wonderfully alphamasked) draw that happens, as you would expect with DrawImage, DrawRect and DrawSubImageRect. ' -------------- ' Drawing to normal backbuffer now, nothing special Cls DrawImage img,xsprite*1,0 ' Draw img DrawImage img2,xsprite*2,0 ' Draw img2 DrawImage img3,xsprite*3,0 ' Draw img3 DrawImage img4,xsprite*4,0 ' Draw img4 DrawImage img5,xsprite*5,0 ' Draw img5 DrawImage img6,xsprite*6,0 ' Draw img6 DrawImage img7,xsprite*7,0 ' Draw img7 DrawImage img8,xsprite*7,0 ' Draw img8 xsprite = xsprite + 1 ; xsprite = xsprite Mod ((1920-512)/8) Delay 1 ; Flip 1 Wend ' ------------------------------- MAIN LOOP ----------------------------------- End Rem Global img:TImage=CreateImage(640,480),pic:TPixmap,i,j For i=0 To 639 DrawOval i,Rand(480),32,32 Next GrabImage img,0,0 pic=LockImage(img) For i=0 To 479 For j=0 To 639 If ReadPixel(pic,j,i) WritePixel pic,j,i,Rand(128)Shl 8|$ff000000 EndIf Next Next UnlockImage(img) Repeat For i=0 To 479 SetColor 0,0,i Mod 256 DrawLine 0,i,639,i Next SetColor 255,255,255 DrawImage img,0,0 Flip If MouseDown(1) Cls DrawImage img,0,0 SetColor 0,0,0 DrawOval MouseX()-32,MouseY()-32,64,64 GrabImage img,0,0 EndIf Until KeyDown(32) End EndRem ' ------------------------------- Type TImageBuffer Field Image:TImage Field rb:Int[1] Field fb:Int[1] Field Imageframe:TGLImageframe Field Frame:Int = 0 Field OrigX:Int Field OrigY:Int Field OrigW:Int Field OrigH:Int Function SetBuffer:TImageBuffer(Image:TImage,Frame:Int = 0 ) Local IB:TImageBuffer = New TImageBuffer IB.Image = Image ; IB.Frame = Frame ; IB.GenerateFBO() ; IB.BindBuffer() Return IB End Function Function Init(Width:Int,Height:Int,Bit:Int=0,Mode:Int=60) SetGraphicsDriver(GLMax2DDriver()) ; Graphics Width , Height,bit,Mode ; glewInit() End Function Method GenerateFBO() ImageFrame = TGLImageFrame(Image.frame(Frame) ) imageframe.v0 = imageframe.v1 imageframe.v1 = 0.0 Local W:Int = Image.width Local H:Int = Image.Height AdjustTexSize(W , H) glGenFramebuffersEXT(1, fb ) glGenRenderbuffersEXT(1 , rb) glBindTexture(GL_TEXTURE_2D, Imageframe.name); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , fb[0]) ; glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, Imageframe.name, 0); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb[0]); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, W, H); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT , GL_DEPTH_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , rb[0]) Local status:Int = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) Select status Case GL_FRAMEBUFFER_COMPLETE_EXT Print "all right" + " : " + Status Case GL_FRAMEBUFFER_UNSUPPORTED_EXT Print "choose different formats" Default End EndSelect End Method Method BindBuffer() GetViewport(OrigX,OrigY,OrigW,OrigH) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , fb[0]) glMatrixMode GL_PROJECTION glLoadIdentity glOrtho 0,Image.Width,Image.Width,0,-1,1 glMatrixMode GL_MODELVIEW glViewport(0 , 0 , Image.Width , Image.Height) glScissor 0,0, Image.Width , Image.Height End Method Method UnBindBuffer() glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , 0) glMatrixMode GL_PROJECTION glLoadIdentity glOrtho 0,OrigW ,Origh,0,-1,1 glMatrixMode GL_MODELVIEW glViewport(0 , 0 , OrigW, OrigH) glScissor 0,0, OrigW ,OrigH End Method Method Cls(r#=0.0,g#=0.0,b#=0.0,a#=1.0) glClearColor r,g,b,a glClear GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT End Method Method BufferWidth:Int() Return Image.Width End Method Method BufferHeight:Int() Return Image.Height End Method End Type Function AdjustTexSize( width:Int Var,height:Int Var ) width=Pow2Size( width ) ; height=Pow2Size( height ) Repeat Local t:Int glTexImage2D GL_PROXY_TEXTURE_2D,0,4,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,Null glGetTexLevelParameteriv GL_PROXY_TEXTURE_2D,0,GL_TEXTURE_WIDTH,Varptr t If t Return If width=1 And height=1 RuntimeError "Unable to calculate tex size" If width>1 width:/2 If height>1 height:/2 Forever End Function Function Pow2Size:Int( n:Int ) Local t:Int=1 While t<n ; t:*2 ; Wend Return t End Function |
| ||
Dontīt look at this for reference I just wanted to show an example how to create 8 512x512 sprites (or youcould look at them as atlases or offscreenbuffers aswell) and draw to all of them individually, and to show a buffer to buffer copy in action. And here DrawSubImageRect really comes into play in when you want to do things with those buffers. You can draw (aka copy) parts from buffer to buffer, to all of your hearts content at amazing speeds, no cost really. Just draw and forget it happened. Really nice. HideMouse ; TImageBuffer.Init(1920,1080,32,60) 'Same as Graphics but set to GLDriver + glewinit (or skip 32,60 for windowed version) SetBlend(MASKBLEND) ' Init images (I shall recode the need for the IB part if possible, but right now just see it as a package deal when you create an image to create a unique IB aswell, just look at the 2 examples and mimic new names) Global img = CreateImage(512,512,1) ; Local IB:TImageBuffer = TImageBuffer.SetBuffer(Img) Global img2 = CreateImage(512,512,1) ; Local IB2:TImageBuffer = TImageBuffer.SetBuffer(Img2) Global img3 = CreateImage(512,512,1) ; Local IB3:TImageBuffer = TImageBuffer.SetBuffer(Img3) Global img4 = CreateImage(512,512,1) ; Local IB4:TImageBuffer = TImageBuffer.SetBuffer(Img4) Global img5 = CreateImage(512,512,1) ; Local IB5:TImageBuffer = TImageBuffer.SetBuffer(Img5) Global img6 = CreateImage(512,512,1) ; Local IB6:TImageBuffer = TImageBuffer.SetBuffer(Img6) Global img7 = CreateImage(512,512,1) ; Local IB7:TImageBuffer = TImageBuffer.SetBuffer(Img7) Global img8 = CreateImage(512,512,1) ; Local IB8:TImageBuffer = TImageBuffer.SetBuffer(Img8) ' ------------------------------- MAIN LOOP ----------------------------------- While Not MouseDown(2) ' Draw to 8 images (offscreenbuffers if you like) IB.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; DrawOval 50+Int(Rnd(511-50)),50+Int(Rnd(511-50)),Int(Rnd(50)),Int(Rnd(50)) ; Next ; SetColor 255,255,255 ; IB.UnBindBuffer() 'END IB2.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB2.UnBindBuffer() 'END IB3.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB3.UnBindBuffer() 'END IB4.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB4.UnBindBuffer() 'END IB5.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB5.UnBindBuffer() 'END IB6.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB6.UnBindBuffer() 'END IB7.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB7.UnBindBuffer() 'END IB8.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB8.UnBindBuffer() 'END ' Letīs say I want to copy img (aka IB) to img8 (aka IB8), just to see it working (let's for instance copy the whole buffer to another as it is, as that's a nice thing to be able to do) IB8.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB8.UnBindBuffer() ' Something come to my mind ---------------- ' This demo does not show that well that it is actually an mask/alpha draw thatīs happening, so you may easly layer things, from itself to another buffer or from itself to another part of itself for instance. ' So it's a bad example showing of the REAL strength that IS happening, as we draw ovals which stay in place from the next frame so when it copies/draws from one to another, you never see that it layers, as its already there. ' So you never notice that it IS masked, it just looks like an opaque copy, but itīs not. Itīs a normal (and wonderfully alphamasked) draw that happens, as you would expect with DrawImage, DrawRect and DrawSubImageRect. ' -------------- ' Drawing to normal backbuffer now, nothing special Cls DrawImage img,xsprite*1,0 ' Draw img DrawImage img2,xsprite*2,0 ' Draw img2 DrawImage img3,xsprite*3,0 ' Draw img3 DrawImage img4,xsprite*4,0 ' Draw img4 DrawImage img5,xsprite*5,0 ' Draw img5 DrawImage img6,xsprite*6,0 ' Draw img6 DrawImage img7,xsprite*7,0 ' Draw img7 DrawImage img8,xsprite*7,0 ' Draw img8 xsprite = xsprite + 1 ; xsprite = xsprite Mod ((1920-512)/8) Delay 1 ; Flip 1 Wend ' ------------------------------- MAIN LOOP ----------------------------------- End Rem Global img:TImage=CreateImage(640,480),pic:TPixmap,i,j For i=0 To 639 DrawOval i,Rand(480),32,32 Next GrabImage img,0,0 pic=LockImage(img) For i=0 To 479 For j=0 To 639 If ReadPixel(pic,j,i) WritePixel pic,j,i,Rand(128)Shl 8|$ff000000 EndIf Next Next UnlockImage(img) Repeat For i=0 To 479 SetColor 0,0,i Mod 256 DrawLine 0,i,639,i Next SetColor 255,255,255 DrawImage img,0,0 Flip If MouseDown(1) Cls DrawImage img,0,0 SetColor 0,0,0 DrawOval MouseX()-32,MouseY()-32,64,64 GrabImage img,0,0 EndIf Until KeyDown(32) End EndRem ' ------------------------------- Type TImageBuffer Field Image:TImage Field rb:Int[1] Field fb:Int[1] Field Imageframe:TGLImageframe Field Frame:Int = 0 Field OrigX:Int Field OrigY:Int Field OrigW:Int Field OrigH:Int Function SetBuffer:TImageBuffer(Image:TImage,Frame:Int = 0 ) Local IB:TImageBuffer = New TImageBuffer IB.Image = Image ; IB.Frame = Frame ; IB.GenerateFBO() ; IB.BindBuffer() Return IB End Function Function Init(Width:Int,Height:Int,Bit:Int=0,Mode:Int=60) SetGraphicsDriver(GLMax2DDriver()) ; Graphics Width , Height,bit,Mode ; glewInit() End Function Method GenerateFBO() ImageFrame = TGLImageFrame(Image.frame(Frame) ) imageframe.v0 = imageframe.v1 imageframe.v1 = 0.0 Local W:Int = Image.width Local H:Int = Image.Height AdjustTexSize(W , H) glGenFramebuffersEXT(1, fb ) glGenRenderbuffersEXT(1 , rb) glBindTexture(GL_TEXTURE_2D, Imageframe.name); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , fb[0]) ; glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, Imageframe.name, 0); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb[0]); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, W, H); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT , GL_DEPTH_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , rb[0]) Local status:Int = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) Select status Case GL_FRAMEBUFFER_COMPLETE_EXT Print "all right" + " : " + Status Case GL_FRAMEBUFFER_UNSUPPORTED_EXT Print "choose different formats" Default End EndSelect End Method Method BindBuffer() GetViewport(OrigX,OrigY,OrigW,OrigH) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , fb[0]) glMatrixMode GL_PROJECTION glLoadIdentity glOrtho 0,Image.Width,Image.Width,0,-1,1 glMatrixMode GL_MODELVIEW glViewport(0 , 0 , Image.Width , Image.Height) glScissor 0,0, Image.Width , Image.Height End Method Method UnBindBuffer() glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , 0) glMatrixMode GL_PROJECTION glLoadIdentity glOrtho 0,OrigW ,Origh,0,-1,1 glMatrixMode GL_MODELVIEW glViewport(0 , 0 , OrigW, OrigH) glScissor 0,0, OrigW ,OrigH End Method Method Cls(r#=0.0,g#=0.0,b#=0.0,a#=1.0) glClearColor r,g,b,a glClear GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT End Method Method BufferWidth:Int() Return Image.Width End Method Method BufferHeight:Int() Return Image.Height End Method End Type Function AdjustTexSize( width:Int Var,height:Int Var ) width=Pow2Size( width ) ; height=Pow2Size( height ) Repeat Local t:Int glTexImage2D GL_PROXY_TEXTURE_2D,0,4,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,Null glGetTexLevelParameteriv GL_PROXY_TEXTURE_2D,0,GL_TEXTURE_WIDTH,Varptr t If t Return If width=1 And height=1 RuntimeError "Unable to calculate tex size" If width>1 width:/2 If height>1 height:/2 Forever End Function Function Pow2Size:Int( n:Int ) Local t:Int=1 While t<n ; t:*2 ; Wend Return t End Function |
| ||
Want to try the speed on your machine? I will try this on my pc shortly but on imac I get 60fps no problem. Itīs fluid all the way. It's just a simple test (it's a nice scenario I think.) 1) It draws to 32 512x512 images 2) it copies 8 of those 512x512 To eachother, just to test the speed 3) it draws 32 512x512 of them onto the screen, you cannot see all as they are overlapping half of them at least. As 8 512x512 has about the same coverage as one 1920 x 1080 fullscreen, this means 32 of the means little more than 4 layers of full-HD. This is by no menas the limit but I think itīs good enough I donīt want too much Right now. I think itīs very usable in practice for making fluid games. PIXMAP no more. Good riddance. ' Later: ' fix why does graphics gets transparent if eg you draw ovals etc in backbuffer? ' fix simple init ' fix not end ' fix inv y ' bug in demo or why do they change appearence with time in that weak layering effect? ' need to check the edges, bc wach that middle line how affected it is, it should be a tight fit sprite agiast sprite. There's a line artifact. I should check that carefully. HideMouse ; TImageBuffer.Init(1920,1080,32,60) 'Same as Graphics but set to GLDriver + glewinit (or skip 32,60 for windowed version) SetBlend(MASKBLEND) ' Init images Global img = CreateImage(512,512,1) ; Local IB:TImageBuffer = TImageBuffer.SetBuffer(Img) Global img2 = CreateImage(512,512,1) ; Local IB2:TImageBuffer = TImageBuffer.SetBuffer(Img2) Global img3 = CreateImage(512,512,1) ; Local IB3:TImageBuffer = TImageBuffer.SetBuffer(Img3) Global img4 = CreateImage(512,512,1) ; Local IB4:TImageBuffer = TImageBuffer.SetBuffer(Img4) Global img5 = CreateImage(512,512,1) ; Local IB5:TImageBuffer = TImageBuffer.SetBuffer(Img5) Global img6 = CreateImage(512,512,1) ; Local IB6:TImageBuffer = TImageBuffer.SetBuffer(Img6) Global img7 = CreateImage(512,512,1) ; Local IB7:TImageBuffer = TImageBuffer.SetBuffer(Img7) Global img8 = CreateImage(512,512,1) ; Local IB8:TImageBuffer = TImageBuffer.SetBuffer(Img8) Global img9 = CreateImage(512,512,1) ; Local IB9:TImageBuffer = TImageBuffer.SetBuffer(Img9) Global img10 = CreateImage(512,512,1) ; Local IB10:TImageBuffer = TImageBuffer.SetBuffer(Img10) Global img11 = CreateImage(512,512,1) ; Local IB11:TImageBuffer = TImageBuffer.SetBuffer(Img11) Global img12 = CreateImage(512,512,1) ; Local IB12:TImageBuffer = TImageBuffer.SetBuffer(Img12) Global img13 = CreateImage(512,512,1) ; Local IB13:TImageBuffer = TImageBuffer.SetBuffer(Img13) Global img14 = CreateImage(512,512,1) ; Local IB14:TImageBuffer = TImageBuffer.SetBuffer(Img14) Global img15 = CreateImage(512,512,1) ; Local IB15:TImageBuffer = TImageBuffer.SetBuffer(Img15) Global img16 = CreateImage(512,512,1) ; Local IB16:TImageBuffer = TImageBuffer.SetBuffer(Img16) Global img17 = CreateImage(512,512,1) ; Local IB17:TImageBuffer = TImageBuffer.SetBuffer(Img17) Global img18 = CreateImage(512,512,1) ; Local IB18:TImageBuffer = TImageBuffer.SetBuffer(Img18) Global img19 = CreateImage(512,512,1) ; Local IB19:TImageBuffer = TImageBuffer.SetBuffer(Img19) Global img20 = CreateImage(512,512,1) ; Local IB20:TImageBuffer = TImageBuffer.SetBuffer(Img20) Global img21 = CreateImage(512,512,1) ; Local IB21:TImageBuffer = TImageBuffer.SetBuffer(Img21) Global img22 = CreateImage(512,512,1) ; Local IB22:TImageBuffer = TImageBuffer.SetBuffer(Img22) Global img23 = CreateImage(512,512,1) ; Local IB23:TImageBuffer = TImageBuffer.SetBuffer(Img23) Global img24 = CreateImage(512,512,1) ; Local IB24:TImageBuffer = TImageBuffer.SetBuffer(Img24) Global img25 = CreateImage(512,512,1) ; Local IB25:TImageBuffer = TImageBuffer.SetBuffer(Img25) Global img26 = CreateImage(512,512,1) ; Local IB26:TImageBuffer = TImageBuffer.SetBuffer(Img26) Global img27 = CreateImage(512,512,1) ; Local IB27:TImageBuffer = TImageBuffer.SetBuffer(Img27) Global img28 = CreateImage(512,512,1) ; Local IB28:TImageBuffer = TImageBuffer.SetBuffer(Img28) Global img29 = CreateImage(512,512,1) ; Local IB29:TImageBuffer = TImageBuffer.SetBuffer(Img29) Global img30 = CreateImage(512,512,1) ; Local IB30:TImageBuffer = TImageBuffer.SetBuffer(Img30) Global img31 = CreateImage(512,512,1) ; Local IB31:TImageBuffer = TImageBuffer.SetBuffer(Img31) Global img32 = CreateImage(512,512,1) ; Local IB32:TImageBuffer = TImageBuffer.SetBuffer(Img32) ' ------------------------------- MAIN LOOP ----------------------------------- While Not MouseDown(2) ' Draw to 32 images (offscreenbuffers if you like) IB.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; DrawOval 50+Int(Rnd(511-50)),50+Int(Rnd(511-50)),Int(Rnd(50)),Int(Rnd(50)) ; Next ; SetColor 255,255,255 ; IB.UnBindBuffer() 'END IB2.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB2.UnBindBuffer() 'END IB3.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB3.UnBindBuffer() 'END IB4.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB4.UnBindBuffer() 'END IB5.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB5.UnBindBuffer() 'END IB6.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB6.UnBindBuffer() 'END IB7.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB7.UnBindBuffer() 'END IB8.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB8.UnBindBuffer() 'END IB9.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB9.UnBindBuffer() 'END IB10.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB10.UnBindBuffer() 'END IB11.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB11.UnBindBuffer() 'END IB12.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB12.UnBindBuffer() 'END IB13.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB13.UnBindBuffer() 'END IB14.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB14.UnBindBuffer() 'END IB15.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB15.UnBindBuffer() 'END IB16.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB16.UnBindBuffer() 'END IB17.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB17.UnBindBuffer() 'END IB18.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB18.UnBindBuffer() 'END IB19.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB19.UnBindBuffer() 'END IB20.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB20.UnBindBuffer() 'END IB21.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB21.UnBindBuffer() 'END IB22.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB22.UnBindBuffer() 'END IB23.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB23.UnBindBuffer() 'END IB24.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB24.UnBindBuffer() 'END IB25.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB25.UnBindBuffer() 'END IB26.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB26.UnBindBuffer() 'END IB27.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB27.UnBindBuffer() 'END IB28.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB28.UnBindBuffer() 'END IB29.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB29.UnBindBuffer() 'END IB30.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB30.UnBindBuffer() 'END IB31.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB31.UnBindBuffer() 'END IB32.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(511)),Int(Rnd(511)) ; Next ; SetColor 255,255,255 ; IB32.UnBindBuffer() 'END ' Letīs say I want to copy img (aka IB) to img8 (aka IB8), just to see it working (let's for instance copy the whole buffer to another as it is, as that's a nice thing to be able to do) ' scrap that ideas, letīs do several IB9.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB9.UnBindBuffer() IB10.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB10.UnBindBuffer() IB11.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB11.UnBindBuffer() IB12.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB12.UnBindBuffer() IB13.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB13.UnBindBuffer() IB14.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB14.UnBindBuffer() IB15.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB15.UnBindBuffer() IB16.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB16.UnBindBuffer() IB17.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB17.UnBindBuffer() IB18.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB18.UnBindBuffer() IB19.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB19.UnBindBuffer() IB20.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB20.UnBindBuffer() IB21.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB21.UnBindBuffer() IB22.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB22.UnBindBuffer() IB23.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB23.UnBindBuffer() IB24.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB24.UnBindBuffer() ' Something come to my mind ---------------- ' This demo does not show that well that it is actually an mask/alpha draw thatīs happening, so you may easly layer things, from itself to another buffer or from itself to another part of itself for instance. ' So it's a bad example showing of the REAL strength that IS happening, as we draw ovals which stay in place from the next frame so when it copies/draws from one to another, you never see that it layers, as its already there. ' So you never notice that it IS masked, it just looks like an opaque copy, but itīs not. Itīs a normal (and wonderfully alphamasked) draw that happens, as you would expect with DrawImage, DrawRect and DrawSubImageRect. ' -------------- ' Drawing to normal backbuffer now, nothing special Cls ' Draw 32 512 x 512 (equal to abit more than 4 layers of 1920x1080 coverage) DrawImage img,xsprite*1,0 ' Draw img DrawImage img2,xsprite*2,0 ' Draw img2 DrawImage img3,xsprite*3,0 ' Draw img3 DrawImage img4,xsprite*4,0 ' Draw img4 DrawImage img5,xsprite*5,0 ' Draw img5 DrawImage img6,xsprite*6,0 ' Draw img6 DrawImage img7,xsprite*7,0 ' Draw img7 DrawImage img8,xsprite*7,0 ' Draw img8 DrawImage img9,xsprite*1,0 ' Draw img9 DrawImage img10,xsprite*2,0 ' Draw img10 DrawImage img11,xsprite*3,0 ' Draw img11 DrawImage img12,xsprite*4,0 ' Draw img12 DrawImage img13,xsprite*5,0 ' Draw img13 DrawImage img14,xsprite*6,0 ' Draw img14 DrawImage img15,xsprite*7,0 ' Draw img15 DrawImage img16,xsprite*7,0 ' Draw img16 DrawImage img17,xsprite*1,512' Draw img17 DrawImage img18,xsprite*2,512' Draw img18 DrawImage img19,xsprite*3,512' Draw img19 DrawImage img20,xsprite*4,512' Draw img20 DrawImage img21,xsprite*5,512' Draw img21 DrawImage img22,xsprite*6,512' Draw img22 DrawImage img23,xsprite*7,512' Draw img23 DrawImage img24,xsprite*7,512' Draw img24 DrawImage img25,xsprite*1,512' Draw img25 DrawImage img26,xsprite*2,512' Draw img26 DrawImage img27,xsprite*3,512' Draw img27 DrawImage img28,xsprite*4,512' Draw img28 DrawImage img29,xsprite*5,512' Draw img29 DrawImage img30,xsprite*6,512' Draw img30 DrawImage img31,xsprite*7,512' Draw img31 DrawImage img32,xsprite*7,512' Draw img32 xsprite = xsprite + 1 ; xsprite = xsprite Mod ((1920-512)/8) Delay 1 ; Flip 1 Wend ' ------------------------------- MAIN LOOP ----------------------------------- End Rem Global img:TImage=CreateImage(640,480),pic:TPixmap,i,j For i=0 To 639 DrawOval i,Rand(480),32,32 Next GrabImage img,0,0 pic=LockImage(img) For i=0 To 479 For j=0 To 639 If ReadPixel(pic,j,i) WritePixel pic,j,i,Rand(128)Shl 8|$ff000000 EndIf Next Next UnlockImage(img) Repeat For i=0 To 479 SetColor 0,0,i Mod 256 DrawLine 0,i,639,i Next SetColor 255,255,255 DrawImage img,0,0 Flip If MouseDown(1) Cls DrawImage img,0,0 SetColor 0,0,0 DrawOval MouseX()-32,MouseY()-32,64,64 GrabImage img,0,0 EndIf Until KeyDown(32) End EndRem ' ------------------------------- Type TImageBuffer Field Image:TImage Field rb:Int[1] Field fb:Int[1] Field Imageframe:TGLImageframe Field Frame:Int = 0 Field OrigX:Int Field OrigY:Int Field OrigW:Int Field OrigH:Int Function SetBuffer:TImageBuffer(Image:TImage,Frame:Int = 0 ) Local IB:TImageBuffer = New TImageBuffer IB.Image = Image ; IB.Frame = Frame ; IB.GenerateFBO() ; IB.BindBuffer() Return IB End Function Function Init(Width:Int,Height:Int,Bit:Int=0,Mode:Int=60) SetGraphicsDriver(GLMax2DDriver()) ; Graphics Width , Height,bit,Mode ; glewInit() End Function Method GenerateFBO() ImageFrame = TGLImageFrame(Image.frame(Frame) ) imageframe.v0 = imageframe.v1 imageframe.v1 = 0.0 Local W:Int = Image.width Local H:Int = Image.Height AdjustTexSize(W , H) glGenFramebuffersEXT(1, fb ) glGenRenderbuffersEXT(1 , rb) glBindTexture(GL_TEXTURE_2D, Imageframe.name); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , fb[0]) ; glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, Imageframe.name, 0); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb[0]); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, W, H); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT , GL_DEPTH_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , rb[0]) Local status:Int = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) Select status Case GL_FRAMEBUFFER_COMPLETE_EXT Print "all right" + " : " + Status Case GL_FRAMEBUFFER_UNSUPPORTED_EXT Print "choose different formats" Default End EndSelect End Method Method BindBuffer() GetViewport(OrigX,OrigY,OrigW,OrigH) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , fb[0]) glMatrixMode GL_PROJECTION glLoadIdentity glOrtho 0,Image.Width,Image.Width,0,-1,1 glMatrixMode GL_MODELVIEW glViewport(0 , 0 , Image.Width , Image.Height) glScissor 0,0, Image.Width , Image.Height End Method Method UnBindBuffer() glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , 0) glMatrixMode GL_PROJECTION glLoadIdentity glOrtho 0,OrigW ,Origh,0,-1,1 glMatrixMode GL_MODELVIEW glViewport(0 , 0 , OrigW, OrigH) glScissor 0,0, OrigW ,OrigH End Method Method Cls(r#=0.0,g#=0.0,b#=0.0,a#=1.0) glClearColor r,g,b,a glClear GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT End Method Method BufferWidth:Int() Return Image.Width End Method Method BufferHeight:Int() Return Image.Height End Method End Type Function AdjustTexSize( width:Int Var,height:Int Var ) width=Pow2Size( width ) ; height=Pow2Size( height ) Repeat Local t:Int glTexImage2D GL_PROXY_TEXTURE_2D,0,4,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,Null glGetTexLevelParameteriv GL_PROXY_TEXTURE_2D,0,GL_TEXTURE_WIDTH,Varptr t If t Return If width=1 And height=1 RuntimeError "Unable to calculate tex size" If width>1 width:/2 If height>1 height:/2 Forever End Function Function Pow2Size:Int( n:Int ) Local t:Int=1 While t<n ; t:*2 ; Wend Return t End Function |
| ||
dw817 I donīt get your code? does SETCOLOR 0,0,0 means masked/erase "color"? Is setcolor 0,0,0 somehow connected to Alpha 0, making the ovals seethrough? I feel so stupid right now, I'ts so small and elegant still I don't see how it works. I thought it would be just 2 layers, but you have to have SOME mean to erase from one layer. Is that what SETCOLOR 0,0,0? does? Isnīt that just black? Does PIXMAP has some colormatching going on to make black masked? My head spins for such a simple thing, I really have no clue how to "draw alpha" and make pixels see-through. |
| ||
Well version 1 anyways. bugs and everything. [code] TImageBuffer.Init(512,512) 'Same as Graphics but set to GLDriver + glewinit (or skip 32,60 for windowed version) ' Init images Global img = CreateImage(512,512,1) ; Local IB:TImageBuffer = TImageBuffer.SetBuffer(Img) Global img2 = CreateImage(512,512,1) ; Local IB2:TImageBuffer = TImageBuffer.SetBuffer(Img2) IB.BindBuffer() ' draw background For i=0 To 511 ; SetColor 0,0,i Mod 256 ; DrawLine 0,i,511,i ; Next ; SetColor 255,255,255 IB.UnBindBuffer() 'END IB2.BindBuffer() ' draw playfield For i=0 To 511 ; DrawOval i,Rand(511),32,32 ; Next For i=0 To 511 ; For j=0 To 511 'If ReadPixel(pic,j,i) Then WritePixel pic,j,i,Rand(128)Shl 8|$ff000000 ' is there a normal readpixel writepixel? not plot I becuase a counterpart is needed to read, is there a snail pixelread/wirt available in some simple way? Next ; Next IB2.UnBindBuffer() 'END While Not MouseDown(2) Cls DrawImage img,0,0 ' draw background DrawImage img2,0,0 ' draw playfield If MouseDown(1) IB2.BindBuffer() SetColor 0,0,0 ; DrawOval MouseX()-32,512-(MouseY()-32),64,64 ' mouse is not onpointov ovals are black (but itīs a start) IB2.UnBindBuffer() 'END SetColor 255,255,255 EndIf Delay 1 ; Flip 1 Wend End Rem Global img:TImage=CreateImage(640,480),pic:TPixmap,i,j For i=0 To 639 DrawOval i,Rand(480),32,32 Next GrabImage img,0,0 pic=LockImage(img) For i=0 To 479 For j=0 To 639 If ReadPixel(pic,j,i) WritePixel pic,j,i,Rand(128)Shl 8|$ff000000 EndIf Next Next UnlockImage(img) Repeat For i=0 To 479 SetColor 0,0,i Mod 256 DrawLine 0,i,639,i Next SetColor 255,255,255 DrawImage img,0,0 Flip If MouseDown(1) Cls DrawImage img,0,0 SetColor 0,0,0 DrawOval MouseX()-32,MouseY()-32,64,64 GrabImage img,0,0 EndIf Until KeyDown(32) End EndRem ' ------------------------------- Type TImageBuffer Field Image:TImage Field rb:Int[1] Field fb:Int[1] Field Imageframe:TGLImageframe Field Frame:Int = 0 Field OrigX:Int Field OrigY:Int Field OrigW:Int Field OrigH:Int Function SetBuffer:TImageBuffer(Image:TImage,Frame:Int = 0 ) Local IB:TImageBuffer = New TImageBuffer IB.Image = Image ; IB.Frame = Frame ; IB.GenerateFBO() ; IB.BindBuffer() Return IB End Function Function Init(Width:Int,Height:Int,Bit:Int=0,Mode:Int=60) SetGraphicsDriver(GLMax2DDriver()) ; Graphics Width , Height,bit,Mode ; glewInit() End Function Method GenerateFBO() ImageFrame = TGLImageFrame(Image.frame(Frame) ) imageframe.v0 = imageframe.v1 imageframe.v1 = 0.0 Local W:Int = Image.width Local H:Int = Image.Height AdjustTexSize(W , H) glGenFramebuffersEXT(1, fb ) glGenRenderbuffersEXT(1 , rb) glBindTexture(GL_TEXTURE_2D, Imageframe.name); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , fb[0]) ; glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, Imageframe.name, 0); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb[0]); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, W, H); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT , GL_DEPTH_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , rb[0]) Local status:Int = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) Select status Case GL_FRAMEBUFFER_COMPLETE_EXT Print "all right" + " : " + Status Case GL_FRAMEBUFFER_UNSUPPORTED_EXT Print "choose different formats" Default End EndSelect End Method Method BindBuffer() GetViewport(OrigX,OrigY,OrigW,OrigH) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , fb[0]) glMatrixMode GL_PROJECTION glLoadIdentity glOrtho 0,Image.Width,Image.Width,0,-1,1 glMatrixMode GL_MODELVIEW glViewport(0 , 0 , Image.Width , Image.Height) glScissor 0,0, Image.Width , Image.Height End Method Method UnBindBuffer() glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , 0) glMatrixMode GL_PROJECTION glLoadIdentity glOrtho 0,OrigW ,Origh,0,-1,1 glMatrixMode GL_MODELVIEW glViewport(0 , 0 , OrigW, OrigH) glScissor 0,0, OrigW ,OrigH End Method Method Cls(r#=0.0,g#=0.0,b#=0.0,a#=1.0) glClearColor r,g,b,a glClear GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT End Method Method BufferWidth:Int() Return Image.Width End Method Method BufferHeight:Int() Return Image.Height End Method End Type Function AdjustTexSize( width:Int Var,height:Int Var ) width=Pow2Size( width ) ; height=Pow2Size( height ) Repeat Local t:Int glTexImage2D GL_PROXY_TEXTURE_2D,0,4,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,Null glGetTexLevelParameteriv GL_PROXY_TEXTURE_2D,0,GL_TEXTURE_WIDTH,Varptr t If t Return If width=1 And height=1 RuntimeError "Unable to calculate tex size" If width>1 width:/2 If height>1 height:/2 Forever End Function Function Pow2Size:Int( n:Int ) Local t:Int=1 While t<n ; t:*2 ; Wend Return t End Function |
| ||
Morning Casaber: * Notice at the top I am using: setblendmode alphablend This means white is white and black is black, no tricks there. It also means BLACK is transparent. Now were I to use "setblendmode solidblend," BLACK would overwrite everything Then when you click the mouse: Cls ' clear screen to solid BLACK DrawImage img,0,0 ' draw grass to the screen (background is not visible now) SetColor 0,0,0 ' set to color BLACK DrawOval MouseX()-32,MouseY()-32,64,64 ' draw a BLACK oval near the mouse GrabImage img,0,0 ' grab the whole thing again Just sets the color to black (transparent) before plotting an ellipse. Notice that I am plotting the 'grass' all by itself when you click the mouse so all I am doing is 'munching' out a bit of it. Grabbing the changed screen. Then continuing the program as normal. Still ... I'm rather dismayed BlitzMAX is slowing down the more I grab an image. Reminds me very much of FLASH. When I coded in it, everything started to get slower and slower the more I made changes to the screen. If there's a complaint dept. I'm lodging that one - and hoping for a repair to the BlitzMAX OS on its account. No reason to slow down just by grabbing a screen. |
| ||
To plot I think maybeFunction FastPlot(num%) glDisable GL_TEXTURE_2D ; glBegin GL_POINTS ; For Local p%=1 To num ; glVertex2f Rand(width),Rand(height) ; Next ;glEnd ; glEnable GL_TEXTURE_2D ; Flip End Function Thereīs glReadPixels, but I think you need PBO instead of VBO. Iīm not sure yet. This are first loose ideas for fast pixel plots and reads. PBO is too bigproject right now so. I'm abit down bc of that. I guess you could use PIXMAPS just for initiliasing stuff but itīs not a nice solution I think. You could get descent pixel speeds to just-about being useable for realtime things (in the realm of being effecient for some things. Itīs a nice tool to have readily available thatīs what Iīm saying. Even if you shouldnīt snort pixels, your nose starts to bleed so very quickly. I need to solve that erasing ovals next. I feel so, so, so not bright right now. Alpha did it too me. Butīs that's - okay. I think this is a nice start. A days work. |
| ||
I think I should repost the code complete. I dontīlike the gray box above and it wonīt change into an actual codebox when I edit. Why I donīt know. Letīs try a new one. TImageBuffer.Init(512,512) 'Same as Graphics but set to GLDriver + glewinit ' Init images Global img = CreateImage(512,512,1) ; Local IB:TImageBuffer = TImageBuffer.SetBuffer(Img) Global img2 = CreateImage(512,512,1) ; Local IB2:TImageBuffer = TImageBuffer.SetBuffer(Img2) IB.BindBuffer() ' draw background For i=0 To 511 ; SetColor 0,0,i Mod 256 ; DrawLine 0,i,511,i ; Next ; SetColor 255,255,255 IB.UnBindBuffer() 'END IB2.BindBuffer() ' draw playfield For i=0 To 511 ; DrawOval i,Rand(511),32,32 ; Next For i=0 To 511 ; For j=0 To 511 'If ReadPixel(pic,j,i) Then WritePixel pic,j,i,Rand(128)Shl 8|$ff000000 ' is there a normal readpixel writepixel? Next ; Next IB2.UnBindBuffer() 'END While Not MouseDown(2) Cls DrawImage img,0,0 ' draw background DrawImage img2,0,0 ' draw playfield If MouseDown(1) IB2.BindBuffer() SetColor 0,0,0 ; DrawOval MouseX()-32,512-(MouseY()-32),64,64 ' mouse is not onpointov ovals are black (but itīs a start) IB2.UnBindBuffer() 'END SetColor 255,255,255 EndIf Delay 1 ; Flip 1 Wend End Rem Global img:TImage=CreateImage(640,480),pic:TPixmap,i,j For i=0 To 639 DrawOval i,Rand(480),32,32 Next GrabImage img,0,0 pic=LockImage(img) For i=0 To 479 For j=0 To 639 If ReadPixel(pic,j,i) WritePixel pic,j,i,Rand(128)Shl 8|$ff000000 EndIf Next Next UnlockImage(img) Repeat For i=0 To 479 SetColor 0,0,i Mod 256 DrawLine 0,i,639,i Next SetColor 255,255,255 DrawImage img,0,0 Flip If MouseDown(1) Cls DrawImage img,0,0 SetColor 0,0,0 DrawOval MouseX()-32,MouseY()-32,64,64 GrabImage img,0,0 EndIf Until KeyDown(32) End EndRem ' ------------------------------- Type TImageBuffer Field Image:TImage Field rb:Int[1] Field fb:Int[1] Field Imageframe:TGLImageframe Field Frame:Int = 0 Field OrigX:Int Field OrigY:Int Field OrigW:Int Field OrigH:Int Function SetBuffer:TImageBuffer(Image:TImage,Frame:Int = 0 ) Local IB:TImageBuffer = New TImageBuffer IB.Image = Image ; IB.Frame = Frame ; IB.GenerateFBO() ; IB.BindBuffer() Return IB End Function Function Init(Width:Int,Height:Int,Bit:Int=0,Mode:Int=60) SetGraphicsDriver(GLMax2DDriver()) ; Graphics Width , Height,bit,Mode ; glewInit() End Function Method GenerateFBO() ImageFrame = TGLImageFrame(Image.frame(Frame) ) imageframe.v0 = imageframe.v1 imageframe.v1 = 0.0 Local W:Int = Image.width Local H:Int = Image.Height AdjustTexSize(W , H) glGenFramebuffersEXT(1, fb ) glGenRenderbuffersEXT(1 , rb) glBindTexture(GL_TEXTURE_2D, Imageframe.name); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , fb[0]) ; glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, Imageframe.name, 0); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb[0]); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, W, H); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT , GL_DEPTH_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , rb[0]) Local status:Int = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) Select status Case GL_FRAMEBUFFER_COMPLETE_EXT Print "all right" + " : " + Status Case GL_FRAMEBUFFER_UNSUPPORTED_EXT Print "choose different formats" Default End EndSelect End Method Method BindBuffer() GetViewport(OrigX,OrigY,OrigW,OrigH) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , fb[0]) glMatrixMode GL_PROJECTION glLoadIdentity glOrtho 0,Image.Width,Image.Width,0,-1,1 glMatrixMode GL_MODELVIEW glViewport(0 , 0 , Image.Width , Image.Height) glScissor 0,0, Image.Width , Image.Height End Method Method UnBindBuffer() glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , 0) glMatrixMode GL_PROJECTION glLoadIdentity glOrtho 0,OrigW ,Origh,0,-1,1 glMatrixMode GL_MODELVIEW glViewport(0 , 0 , OrigW, OrigH) glScissor 0,0, OrigW ,OrigH End Method Method Cls(r#=0.0,g#=0.0,b#=0.0,a#=1.0) glClearColor r,g,b,a glClear GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT End Method Method BufferWidth:Int() Return Image.Width End Method Method BufferHeight:Int() Return Image.Height End Method End Type Function AdjustTexSize( width:Int Var,height:Int Var ) width=Pow2Size( width ) ; height=Pow2Size( height ) Repeat Local t:Int glTexImage2D GL_PROXY_TEXTURE_2D,0,4,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,Null glGetTexLevelParameteriv GL_PROXY_TEXTURE_2D,0,GL_TEXTURE_WIDTH,Varptr t If t Return If width=1 And height=1 RuntimeError "Unable to calculate tex size" If width>1 width:/2 If height>1 height:/2 Forever End Function Function Pow2Size:Int( n:Int ) Local t:Int=1 While t<n ; t:*2 ; Wend Return t End Function |
| ||
ahhh so the SETMODE actually DOES something haha go figure. How could I miss that. I get those things confused. Thanks. I shall try that |
| ||
It didnīt work? I skip the code now as it seem to be BIG boxes. And itīs pretty much the same. I set SETBLEND ALPHABLEND at the beginning and also just before drawing (just in case). Still black? Does SETBLEND only affects PIXMAP? it's an opengl thing no? It should work. I really need a break from coding now, but this seem promising no? I really enjoyed doing this. Coming closer now ! |
| ||
This is where I am now anyways, so it might be worth posting I guess. The conversion has the mouse problem, and the blackness instead of transparency problem, otherwise itīs perfect. There are two layers going on and that's great. TImageBuffer.Init(512,512) 'Same as Graphics but set to GLDriver + glewinit SetBlend alphablend ' Init images Global img = CreateImage(512,512,1) ; Local IB:TImageBuffer = TImageBuffer.SetBuffer(Img) Global img2 = CreateImage(512,512,1) ; Local IB2:TImageBuffer = TImageBuffer.SetBuffer(Img2) IB.BindBuffer() ' draw background For i=0 To 511 ; SetColor 0,0,i Mod 256 ; DrawLine 0,i,511,i ; Next ; SetColor 255,255,255 IB.UnBindBuffer() IB2.BindBuffer() ' draw playfield For i=0 To 511 ; DrawOval i,Rand(511),32,32 ; Next For i=0 To 511 ; For j=0 To 511 'If ReadPixel(pic,j,i) Then WritePixel pic,j,i,Rand(128)Shl 8|$ff000000 ' I guess this is 3rd problem, being able to read and write pixels, I have to decide for somthing that works well. Next ; Next IB2.UnBindBuffer() While Not MouseDown(2) Cls DrawImage img,0,0 ' draw background DrawImage img2,0,0 ' draw playfield ' Punch round holes out of the playfield ----------------------- If MouseDown(1) IB2.BindBuffer() SetBlend alphablend ; SetColor 0,0,0 ; DrawOval MouseX()-32,512-(MouseY()-32),64,64 ' should be not black and transparent ? IB2.UnBindBuffer() SetColor 255,255,255 EndIf ' ----------------------------------------------------------- Delay 1 ; Flip 1 Wend End Type TImageBuffer Field Image:TImage Field rb:Int[1] Field fb:Int[1] Field Imageframe:TGLImageframe Field Frame:Int = 0 Field OrigX:Int Field OrigY:Int Field OrigW:Int Field OrigH:Int Function SetBuffer:TImageBuffer(Image:TImage,Frame:Int = 0 ) Local IB:TImageBuffer = New TImageBuffer IB.Image = Image ; IB.Frame = Frame ; IB.GenerateFBO() ; IB.BindBuffer() Return IB End Function Function Init(Width:Int,Height:Int,Bit:Int=0,Mode:Int=60) SetGraphicsDriver(GLMax2DDriver()) ; Graphics Width , Height,bit,Mode ; glewInit() End Function Method GenerateFBO() ImageFrame = TGLImageFrame(Image.frame(Frame) ) imageframe.v0 = imageframe.v1 imageframe.v1 = 0.0 Local W:Int = Image.width Local H:Int = Image.Height AdjustTexSize(W , H) glGenFramebuffersEXT(1, fb ) glGenRenderbuffersEXT(1 , rb) glBindTexture(GL_TEXTURE_2D, Imageframe.name); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , fb[0]) ; glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, Imageframe.name, 0); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb[0]); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, W, H); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT , GL_DEPTH_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , rb[0]) Local status:Int = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) Select status Case GL_FRAMEBUFFER_COMPLETE_EXT Print "all right" + " : " + Status Case GL_FRAMEBUFFER_UNSUPPORTED_EXT Print "choose different formats" Default End EndSelect End Method Method BindBuffer() GetViewport(OrigX,OrigY,OrigW,OrigH) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , fb[0]) glMatrixMode GL_PROJECTION glLoadIdentity glOrtho 0,Image.Width,Image.Width,0,-1,1 glMatrixMode GL_MODELVIEW glViewport(0 , 0 , Image.Width , Image.Height) glScissor 0,0, Image.Width , Image.Height End Method Method UnBindBuffer() glBindFramebufferEXT(GL_FRAMEBUFFER_EXT , 0) glMatrixMode GL_PROJECTION glLoadIdentity glOrtho 0,OrigW ,Origh,0,-1,1 glMatrixMode GL_MODELVIEW glViewport(0 , 0 , OrigW, OrigH) glScissor 0,0, OrigW ,OrigH End Method Method Cls(r#=0.0,g#=0.0,b#=0.0,a#=1.0) glClearColor r,g,b,a glClear GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT End Method Method BufferWidth:Int() Return Image.Width End Method Method BufferHeight:Int() Return Image.Height End Method End Type Function AdjustTexSize( width:Int Var,height:Int Var ) width=Pow2Size( width ) ; height=Pow2Size( height ) Repeat Local t:Int glTexImage2D GL_PROXY_TEXTURE_2D,0,4,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,Null glGetTexLevelParameteriv GL_PROXY_TEXTURE_2D,0,GL_TEXTURE_WIDTH,Varptr t If t Return If width=1 And height=1 RuntimeError "Unable to calculate tex size" If width>1 width:/2 If height>1 height:/2 Forever End Function Function Pow2Size:Int( n:Int ) Local t:Int=1 While t<n ; t:*2 ; Wend Return t End Function |
| ||
I'm starting to think that I'm actually setting things not for the actual image being drawn *from* anymore as it usually does, but for the image being drawn TO? What the, is there a solve for this? I think I am on the right track. |
| ||
Well now if you want to do it by the dots, Casaber, you can toss your hat at the whole affair and BUILD your own 'pixel-behind' routines. Busy-busy, thinking ... Yeah, sorta like this: CODE UPDATED 10:53pm 12-30-15 Note line before graphics. ' Grass Cutter Mark II by David W (dw817) 12-30-15 Strict SetGraphicsDriver(GLMax2DDriver()) ' NECESSARY FOR AGGRESSIVE PIXEL READING & WRITING Graphics 640,480 Global img:TImage=CreateImage(640,480),pic:TPixmap,i,j,x,y Global oval:Byte[64,64] DrawOval 0,0,64,64 pic=GrabPixmap(0,0,64,64) For i=0 To 63 For j=0 To 63 If ReadPixel(pic,j,i)-$ff000000 oval[j,i]=1 EndIf Next Next For i=0 To 639 DrawOval i,Rand(480),32,32 Next GrabImage img,0,0 pic=LockImage(img) For i=0 To 479 For j=0 To 639 If ReadPixel(pic,j,i) WritePixel pic,j,i,Rand(128)Shl 8|$ff000000 EndIf Next Next UnlockImage(img) Repeat For i=0 To 479 SetColor 0,0,i Mod 256 DrawLine 0,i,639,i Next SetColor 255,255,255 DrawImage img,0,0 Flip If MouseDown(1) pic=LockImage(img) For i=0 To 63 For j=0 To 63 If oval[j,i] x=MouseX()-32+j y=MouseY()-32+i If x>=0 And x<=639 And y>=0 And y<=479 WritePixel pic,x,y,0 EndIf EndIf Next Next UnlockImage img EndIf Until KeyDown(32) End |
| ||
Nah the readpixel writepixel was just because I loved your "grass" texture so much. And sure it would be nice to lot now and then. But for this we need the big guns, 1) pixelshader would be one I guess 2) or this (which is VBO) 3) maybe together with a PBO. Donīt even ask me about the VBO & PBO relationship I forgot all about it. I need to regain some of that. Those where are my ideas from start and I havenīt got any new ones really. But the VBO implementation is nice. Finally having a SETBUFFER in Blitzmax for instance was nice touch? And a working PIXMAP (well that alpha bugs the hell out of me) Same goes there; I need to gain some OpenGL knowledge. PS should that grass go away in that weird strikey way sometimes? or is it a bug? Iīts actually nice. |
| ||
Strikey way ? I'm not understanding. Basically when you hold down the button it just 'clears' out a circle. Nothing more than that. The code I wrote above runs considerably faster but it would mean you need to use readpixel() and writepixel() to get the desired effect. I suppose I could've just captured the oval to a different pixmap() and read its pixels to see if they were valid for cutting the circle. This just seemed the quickest way, to use a 64x64 array. |
| ||
I took a snapshot, I sometimes leaves lines behind see? I guess itīs a BlitzMAX bug. I just was curious about it. Looked kind of nice and I couldnīt see what did it in the code.![]() I will soon try get this worm project started I guess this it will take time to get these preparations done though. It seem a bit tricky. But itīs a good way to learn Blitzmax more deeply I think. |
| ||
Hmm .... Looking ... I don't get that here. I just ran it a sec ago to see if I could recreate that. Didn't happen. Not good that the same code gets different results. Minju, the code that ran on your computer wouldn't run on mine. Something extra to worry about. :( |
| ||
I've been thinking about those lines, Casaber. I wonder if it's because I'm scanning the mouse while the circle is being drawn. Try this code to see if it clears it up. I'd like to get this to work for you:Strict Graphics 640,480 Global img:TImage=CreateImage(640,480),pic:TPixmap,i,j,x,y Global oval:Byte[64,64],mx,my DrawOval 0,0,64,64 ' draw white oval for capturing pic=GrabPixmap(0,0,64,64) For i=0 To 63 ' scan full 64x64 area For j=0 To 63 If ReadPixel(pic,j,i)-$ff000000 ' if there is a pixel oval[j,i]=1 ' go ahead and mark oval array as this pixel is lit EndIf Next Next For i=0 To 639 DrawOval i,Rand(480),32,32 ' simple draw white ovals across screen Next GrabImage img,0,0 pic=LockImage(img) For i=0 To 479 For j=0 To 639 If ReadPixel(pic,j,i) WritePixel pic,j,i,Rand(128)Shl 8|$ff000000 ' change white to 'grass' EndIf Next Next UnlockImage(img) Repeat For i=0 To 479 SetColor 0,0,i Mod 256 ' set a simple growing blue color flips after 256 DrawLine 0,i,639,i ' draw it on the screen Next SetColor 255,255,255 ' be certain to go back to white for normal drawing DrawImage img,0,0 Flip If MouseDown(1) ' you pressed the mouse pic=LockImage(img) mx=MouseX() ' record mouse X position my=MouseY() ' record mouse Y position For i=0 To 63 For j=0 To 63 If oval[j,i] ' if our oval array pixel is lit at this position x=mx-32+j y=my-32+i If x>=0 And x<=639 And y>=0 And y<=479 ' and is plotting within screen WritePixel pic,x,y,0 ' take out 'grass' to replace with black (transparent) EndIf EndIf Next Next UnlockImage img EndIf Until KeyDown(32) ' keep going till you hit SPACE End |
| ||
I have some good news (for me anyways). Using graphics 640,480 causes my system to CRASH after I've erased half the screen of grass by holding the mouse down. Even if not running in DEBUG mode or using GUI App or Threaded Build. Where does it crash ? Right on the: DrawImage img,0,0The error message ? A really bad one. D3DERR: unable to create texture I've gotten this in my coding before. So where is the good news ? I tried out your screen code thingie where you have: timagebuffer.init()And BAM ! That fixed it right there. It means adding a TON of code at the bottom to support your timagebuffer.init(), but my grass cutter code does work without crashing now. For the moment I need to check Grass Cutter with: window=CreateWindow("",deskrect[0],deskrect[1],deskrect[2],deskrect[3],,WINDOW_ACCEPTFILES)Which is what I have in my main engine. Now, =IF= this crashes too then I have a serious problem ahead for me for any zealous read and write of pixels. Hopefully it is just the graphics 640,480 that is causing it to crash by doing too many readpixel() and writepixel(), which is causing the drawimage to crash after -awhile. Using your graphics technique may take out the lines you are seeing as well as I suspect the error is a nasty one that escaped even the makers of BlitzMAX and the results are unpredictable per computer. Running it on my older computer it didn't crash but got VERY slow and started to heavily use my hard-drive I suspect for cache space, then slower, then finally crashed with the same error message above. Your graphics seems to have fixed it. The hard-drive light still goes on as I'm erasing grass. I will experiment in depth to see if I can get it to crash now. 10:01pm Yep, it crashes with createwindow() too, same weird error. *SIGH* Now I really will need to see what you are doing in your graphics that prevent this from happening. I suppose if there was a way of doing this code with your graphics: ' Drop Image (modified) Import MaxGui.Drivers Strict Extern "Win32" Function SystemParametersInfoA:Int(action:Int, param:Int, param2:Byte Ptr, winini:Int) EndExtern Global a,img:TImage Global deskrect[4] GetDesktopArea(deskrect) Local window:TGadget Local htmlview:TGadget Local dropview:tgadget Local mainview:tgadget window=CreateWindow("",deskrect[0],deskrect[1],deskrect[2],deskrect[3],,WINDOW_ACCEPTFILES) htmlview=CreateHTMLView(0,32,ClientWidth(window),ClientHeight(window)-32,window) mainview=createcanvas(deskrect[0],deskrect[1]-1,deskrect[2]+2,deskrect[3],window,1) HtmlViewGo htmlview,"http://bit.ly/1mqP51B" SetGraphics canvasgraphics(mainview) showgadget mainview SetClsColor 255,0,0 SetColor 0,0,0 Repeat a=PollEvent() Cls DrawText "Drag Image Here",0,0 Select EventID() Case event_windowaccept img=LoadImage(EventExtra().tostring()) Print EventExtra().tostring() SetGraphics canvasgraphics(mainview) hidegadget htmlview SetColor 255,255,255 Repeat a=PollEvent() DrawImage img,0,0 Flip Until KeyDown(32) End End Select Flip Forever Function getdesktoparea(lprect:Int Ptr) systemparametersinfoa(spi_getworkarea,0,lprect,0) End Function That would solve this little problem. Oh, if you want to experiment with this, click on one of the images until only the image remains. Then drag it to the top. It will be copied so BlitzMAX can work with it. I plan to implement this into the RPG engine, obviously using a different website that houses my RPG add-ons, but I'm not liking that I have to use CreateWindow() to build it. |
| ||
![]() G O T C H A ! What was it you said ? Something so small but yet eluding. Typing out your code to inject into my Grass Cutter is a bit like inserting a nuclear detonator to poison a mouse. Likely it is incredibly effective for what you designed it for, but I just needed to know why your graphics wouldn't crash strangely. And, it was something - very small - and very eluding. SetGraphicsDriver(GLMax2DDriver())I just needed to have this before my usual GRAPHICS 640,480 and everything works fine. Not -entirely- sure why. The HELP file just says it is a Max2D driver. Well, no complaints there, all my work is 2D. And it no longer tries to cache the image to the hard-drive. Runs better than ever ! A real test will be to check with the upstairs computer (Windows XP) and see if it runs super slow and throttles the hard-drive again - or will it run much better ? BRB ... Doesn't run much faster, it's not a very speedy computer, but no throttling the hard-drive like before. Definitely fixed it. Check to see if this fixes the strange lines that appeared for you too, Casaber. And ? Guess what ? My =ORIGINAL= smaller code is now just as fast as the secondary (at least on my main computer). That's right, the one that grabs the whole image each time. Here's the final of it: ' ______________________________________ ' // // ' // Fast Grass Cutter v0.023 // ' // Written by David W - 12/30/15 // '//___________________________________// Strict SeedRnd MilliSecs() ' True random results each time SetGraphicsDriver(GLMax2DDriver()) ' NECESSARY FOR AGGRESSIVE PIXEL READING & WRITING Graphics 640,480 SetBlend alphablend ' Allows BLACK to be transparent when plotted Global img:TImage=CreateImage(640,480),pic:TPixmap,i,j For i=0 To 639 DrawOval i,Rand(480),32,32 ' simple draw white ovals across screen Next GrabImage img,0,0 pic=LockImage(img) For i=0 To 479 For j=0 To 639 If ReadPixel(pic,j,i) WritePixel pic,j,i,Rand(128)Shl 8|$ff000000 ' change ovals to 'grass' EndIf Next Next UnlockImage(img) Repeat For i=0 To 479 SetColor 0,0,i Mod 256 ' set a simple growing blue color flips after 256 DrawLine 0,i,639,i ' draw it on the screen Next SetColor 255,255,255 ' be certain to go back to white for normal drawing DrawImage img,0,0 ' INSERT the grass on top of the blue design Flip If MouseDown(1) ' if you hold the mouse down Cls ' clear screen to black (important) DrawImage img,0,0 ' draw ONLY the grass now SetColor 0,0,0 ' set color to BLACK (also transparent) DrawOval MouseX()-32,MouseY()-32,64,64 ' draw a circle at mouse position GrabImage img,0,0 ' grab the image back again EndIf Until KeyDown(32) ' repeat until you hit SPACEBAR |
| ||
Great news !! Ya.. I was quick aswell to debug the mouse coordinates after some sleep just before I read to see that you had done it to so I donīt have to post that haha I noticed it got worse when I movied the mouse around so that was a dead giveaway. I didnīt notice that the first time around and the fact that I assumed it worked fine all the way on your side made me overlook it. I can confirm it works here aswell now. No output on different machines, no bugs in the grass. About the graphics command, actually my guess would have been to do what you did, and I think GUI uses the same graphics driver/mode, I guess it could work with the right OpenGL command aswell. But Iīm not good at explaining ecatly WHY it works yet. If Blitzmax graphics commands has a strong stable side, I hope it is the openGL one. And not DirectX which I think it still defaults to and thatīs where you got your error for some reason? For me opengl in new Windows is the way to go fullscreen is absolutelty smooth, and windowed mode are the most acceptable Iīve seen in any Windows ever. So starting to use that graphics mode/driver I think was a good move even if you donīt know what caused this particular error. No luck on progress on the Worms Iīm afraid. I will be sometime in 2016 haha. Wishing you a Happy New year !! |
| ||
Also, I like that new version youīve got, very elegant. Great stuff !! I must get my head around how to get that same "alpha erasing mode" in my code. Thatīs my biggest problem now. |
| ||
I would love to know if my code is worth building upon to be inspired to continue with it. Could you try this on your machine and tell me if you experience good speed? If this runs smooth on every machine I would need to, I would be so thrilled. Itīs a pretty harsch test actually, but I have high hopes that it works in alot of places. My two machines gave me a really smooth experience with this code. HideMouse ; TImageBuffer.Init(1920,1080,32,60) ; SetBlend(MASKBLEND) ' ' Test # 5 ' ' Welcome... to hard-coded-mania ' ' One would love arraying those img's it hurts to see this repetition, but's that's for another day. ' ' Init images Global img = CreateImage(512,512,1) ; Local IB:TImageBuffer = TImageBuffer.SetBuffer(Img) ; Global img2 = CreateImage(512,512,1) ; Local IB2:TImageBuffer = TImageBuffer.SetBuffer(Img2) Global img3 = CreateImage(512,512,1) ; Local IB3:TImageBuffer = TImageBuffer.SetBuffer(Img3) ; Global img4 = CreateImage(512,512,1) ; Local IB4:TImageBuffer = TImageBuffer.SetBuffer(Img4) Global img5 = CreateImage(512,512,1) ; Local IB5:TImageBuffer = TImageBuffer.SetBuffer(Img5) ; Global img6 = CreateImage(512,512,1) ; Local IB6:TImageBuffer = TImageBuffer.SetBuffer(Img6) Global img7 = CreateImage(512,512,1) ; Local IB7:TImageBuffer = TImageBuffer.SetBuffer(Img7) ; Global img8 = CreateImage(512,512,1) ; Local IB8:TImageBuffer = TImageBuffer.SetBuffer(Img8) Global img9 = CreateImage(512,512,1) ; Local IB9:TImageBuffer = TImageBuffer.SetBuffer(Img9) ; Global img10 = CreateImage(512,512,1) ; Local IB10:TImageBuffer = TImageBuffer.SetBuffer(Img10) Global img11 = CreateImage(512,512,1) ; Local IB11:TImageBuffer = TImageBuffer.SetBuffer(Img11) ; Global img12 = CreateImage(512,512,1) ; Local IB12:TImageBuffer = TImageBuffer.SetBuffer(Img12) Global img13 = CreateImage(512,512,1) ; Local IB13:TImageBuffer = TImageBuffer.SetBuffer(Img13) ; Global img14 = CreateImage(512,512,1) ; Local IB14:TImageBuffer = TImageBuffer.SetBuffer(Img14) Global img15 = CreateImage(512,512,1) ; Local IB15:TImageBuffer = TImageBuffer.SetBuffer(Img15) ; Global img16 = CreateImage(512,512,1) ; Local IB16:TImageBuffer = TImageBuffer.SetBuffer(Img16) Global img17 = CreateImage(512,512,1) ; Local IB17:TImageBuffer = TImageBuffer.SetBuffer(Img17) ; Global img18 = CreateImage(512,512,1) ; Local IB18:TImageBuffer = TImageBuffer.SetBuffer(Img18) Global img19 = CreateImage(512,512,1) ; Local IB19:TImageBuffer = TImageBuffer.SetBuffer(Img19) ; Global img20 = CreateImage(512,512,1) ; Local IB20:TImageBuffer = TImageBuffer.SetBuffer(Img20) Global img21 = CreateImage(512,512,1) ; Local IB21:TImageBuffer = TImageBuffer.SetBuffer(Img21) ; Global img22 = CreateImage(512,512,1) ; Local IB22:TImageBuffer = TImageBuffer.SetBuffer(Img22) Global img23 = CreateImage(512,512,1) ; Local IB23:TImageBuffer = TImageBuffer.SetBuffer(Img23) ; Global img24 = CreateImage(512,512,1) ; Local IB24:TImageBuffer = TImageBuffer.SetBuffer(Img24) Global img25 = CreateImage(512,512,1) ; Local IB25:TImageBuffer = TImageBuffer.SetBuffer(Img25) ; Global img26 = CreateImage(512,512,1) ; Local IB26:TImageBuffer = TImageBuffer.SetBuffer(Img26) Global img27 = CreateImage(512,512,1) ; Local IB27:TImageBuffer = TImageBuffer.SetBuffer(Img27) ; Global img28 = CreateImage(512,512,1) ; Local IB28:TImageBuffer = TImageBuffer.SetBuffer(Img28) Global img29 = CreateImage(512,512,1) ; Local IB29:TImageBuffer = TImageBuffer.SetBuffer(Img29) ; Global img30 = CreateImage(512,512,1) ; Local IB30:TImageBuffer = TImageBuffer.SetBuffer(Img30) Global img31 = CreateImage(512,512,1) ; Local IB31:TImageBuffer = TImageBuffer.SetBuffer(Img31) ; Global img32 = CreateImage(512,512,1) ; Local IB32:TImageBuffer = TImageBuffer.SetBuffer(Img32) ' ---------------------------------------------------------------------------------------- While Not MouseDown(2) ' Draw to 32 images (offscreenbuffers if you like) IB.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; DrawOval 50+Int(Rnd(511-50)),50+Int(Rnd(511-50)),Int(Rnd(50)),Int(Rnd(50)) ; Next ; SetColor 255,255,255 ; IB.UnBindBuffer() 'END IB2.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB2.UnBindBuffer() 'END IB3.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB3.UnBindBuffer() 'END IB4.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB4.UnBindBuffer() 'END IB5.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB5.UnBindBuffer() 'END IB6.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB6.UnBindBuffer() 'END IB7.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB7.UnBindBuffer() 'END IB8.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB8.UnBindBuffer() 'END IB9.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB9.UnBindBuffer() 'END IB10.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB10.UnBindBuffer() 'END IB11.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB11.UnBindBuffer() 'END IB12.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB12.UnBindBuffer() 'END IB13.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB13.UnBindBuffer() 'END IB14.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB14.UnBindBuffer() 'END IB15.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB15.UnBindBuffer() 'END IB16.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB16.UnBindBuffer() 'END IB17.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB17.UnBindBuffer() 'END IB18.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB18.UnBindBuffer() 'END IB19.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB19.UnBindBuffer() 'END IB20.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB20.UnBindBuffer() 'END IB21.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB21.UnBindBuffer() 'END IB22.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB22.UnBindBuffer() 'END IB23.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB23.UnBindBuffer() 'END IB24.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB24.UnBindBuffer() 'END IB25.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB25.UnBindBuffer() 'END IB26.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB26.UnBindBuffer() 'END IB27.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB27.UnBindBuffer() 'END IB28.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB28.UnBindBuffer() 'END IB29.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB29.UnBindBuffer() 'END IB30.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB30.UnBindBuffer() 'END IB31.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB31.UnBindBuffer() 'END IB32.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB32.UnBindBuffer() 'END IB9.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB9.UnBindBuffer() ; IB10.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB10.UnBindBuffer() IB11.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB11.UnBindBuffer() ; IB12.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB12.UnBindBuffer() IB13.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB13.UnBindBuffer() ; IB14.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB14.UnBindBuffer() IB15.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB15.UnBindBuffer() ; IB16.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB16.UnBindBuffer() IB17.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB17.UnBindBuffer() ; IB18.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB18.UnBindBuffer() IB19.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB19.UnBindBuffer() ; IB20.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB20.UnBindBuffer() IB21.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB21.UnBindBuffer() ; IB22.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB22.UnBindBuffer() IB23.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB23.UnBindBuffer() ; IB24.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB24.UnBindBuffer() Cls ' Draw 32 512 x 512 (equal to abit more than 4 layers of 1920x1080 coverage) DrawImage img,xsprite*1,0 ; DrawImage img2,xsprite*2,0 ; DrawImage img3,xsprite*3,0 ; DrawImage img4,xsprite*4,0 DrawImage img5,xsprite*5,0 ; DrawImage img6,xsprite*6,0 ; DrawImage img7,xsprite*7,0 ; DrawImage img8,xsprite*7,0 DrawImage img9,xsprite*1,0 ; DrawImage img10,xsprite*2,0 ; DrawImage img11,xsprite*3,0 ; DrawImage img12,xsprite*4,0 DrawImage img13,xsprite*5,0 ; DrawImage img14,xsprite*6,0 ; DrawImage img15,xsprite*7,0 ; DrawImage img16,xsprite*7,0 DrawImage img17,xsprite*1,512 ; DrawImage img18,xsprite*2,512 ; DrawImage img19,xsprite*3,512 ; DrawImage img20,xsprite*4,512 DrawImage img21,xsprite*5,512 ; DrawImage img22,xsprite*6,512 ; DrawImage img23,xsprite*7,512 ; DrawImage img24,xsprite*7,512 DrawImage img25,xsprite*1,512 ; DrawImage img26,xsprite*2,512 ; DrawImage img27,xsprite*3,512 ; DrawImage img28,xsprite*4,512 DrawImage img29,xsprite*5,512 ; DrawImage img30,xsprite*6,512 ; DrawImage img31,xsprite*7,512 ; DrawImage img32,xsprite*7,512 xsprite = xsprite + 1 ; xsprite = xsprite Mod ((1920-512)/8) Delay 1 ; Flip 1 Wend End ' ---------------------------------------------------------------------------------------- Type TImageBuffer Field Image:TImage ; Field rb:Int[1] ; Field fb:Int[1] ; Field Imageframe:TGLImageframe Field Frame:Int = 0 ; Field OrigX:Int ; Field OrigY:Int ; Field OrigW:Int ; Field OrigH:Int Function SetBuffer:TImageBuffer(Image:TImage,Frame:Int = 0) Local IB:TImageBuffer = New TImageBuffer ; IB.Image = Image ; IB.Frame = Frame ; IB.GenerateFBO() ; IB.BindBuffer() ; Return IB End Function Function Init(Width:Int,Height:Int,Bit:Int=0,Mode:Int=60) SetGraphicsDriver(GLMax2DDriver()) ; Graphics Width, Height, bit, Mode ; glewInit() End Function Method GenerateFBO() ImageFrame = TGLImageFrame(Image.frame(Frame) ) ; imageframe.v0 = imageframe.v1 ; imageframe.v1 = 0.0 Local W:Int = Image.width ; Local H:Int = Image.Height ; AdjustTexSize(W, H) ; glGenFramebuffersEXT(1, fb) glGenRenderbuffersEXT(1, rb) ; glBindTexture(GL_TEXTURE_2D, Imageframe.name) ; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb[0]) glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, Imageframe.name, 0) glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb[0]) ; glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, W, H) glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rb[0]) Local status:Int = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) End Method Method BindBuffer() GetViewport(OrigX,OrigY,OrigW,OrigH) ; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb[0]) glMatrixMode GL_PROJECTION ; glLoadIdentity ; glOrtho 0, Image.Width,Image.Width, 0, -1, 1 ; glMatrixMode GL_MODELVIEW glViewport(0, 0, Image.Width, Image.Height) ; glScissor 0, 0, Image.Width, Image.Height End Method Method UnBindBuffer() glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0) ; glMatrixMode GL_PROJECTION ; glLoadIdentity ; glOrtho 0,OrigW, Origh, 0, -1, 1 glMatrixMode GL_MODELVIEW ; glViewport(0, 0, OrigW, OrigH) ; glScissor 0, 0, OrigW, OrigH End Method End Type Function AdjustTexSize(width:Int Var,height:Int Var) width=Pow2Size(width) ; height=Pow2Size(height) Repeat Local t:Int ; glTexImage2D GL_PROXY_TEXTURE_2D,0,4,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,Null glGetTexLevelParameteriv GL_PROXY_TEXTURE_2D,0,GL_TEXTURE_WIDTH,Varptr t If t Return If width>1 width:/2 If height>1 height:/2 Forever End Function Function Pow2Size:Int(n:Int) Local t:Int=1 ; While t<n ; t:*2; Wend ; Return t End Function |
| ||
Hereīs a good reference for anyone who wants to try this method in their games. Itīs a good entry point to trying to grasp how things works and how to use it. I tried to keep it smallish. ' Test # 3 ' ' aka finally-a-SETBUFFER-working-in-BlitzMAX ' ' Also, showing that alpha truly exists (a relief) ' ' When pixelread, pixelwrite, and PNG save is implemented this could also be used instead of PIXMAP in all occasions. You then draw directly onto things that you meant to grab from in the first place. ' Fullscreen HideMouse ; SetGraphicsDriver(GLMax2DDriver()) ; Graphics 1920,1080,32,60 ; glewInit() ; SetBlend(MASKBLEND) ' Init images, letīs make two Global img = CreateImage(512,512,,1) ; Local IB:TImageBuffer = TImageBuffer.SetBuffer(Img) ; Global img2 = CreateImage(512,512,,1) ; Local IB2:TImageBuffer = TImageBuffer.SetBuffer(Img2) ' Main loop --------------------------------------------------------------------------- While Not MouseDown(2) ' Draw to the images (offscreenbuffers if you like) IB.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; DrawOval 50+Int(Rnd(512-50)),50+Int(Rnd(512-50)),Int(Rnd(50)),Int(Rnd(50)) ; Next ; SetColor 255,255,255 ; IB.UnBindBuffer() 'END IB2.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; Plot Int(Rnd(512)),Int(Rnd(512)) ; Next ; SetColor 255,255,255 ; IB2.UnBindBuffer() 'END ' Now we have two images to play with, one filled with dots, one filled with ovals ' letīs copy the one with the ovals onto the one with the dots. ' Draw from image img2 to img, letīs copy the whole thing, transfer every pixel IB2.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB2.UnBindBuffer() Cls ' Letīs draw both images onto the backbuffer so we may see what we have going on. ' One should have ovals only, And one should have the ovals And itīs pixels. ' DrawImage img,xsprite*2,0 ; DrawImage img2,xsprite*3,0 ; xsprite = xsprite + 1 ; xsprite = xsprite Mod ((1920-512)/4) ' Letīs add two more below these two, we could draw again but instead use DrawSubImageRect, just To show itīs good to use everywhere. Say you want To draw half img onto the screen. DrawSubImageRect img,xsprite*3, 512, 512, 256,0 ,0, 512, 256 ' We may stretch things too, letīs double the size (itīs just one way to fake resolutions cheaply using HW acc, it's not hard to come by today but itīs stuck in here, ready to be used) ' Offscreen buffers begs for these kind of tricks DrawSubImageRect img2,xsprite*4, 512, 512, 512,0 ,0, 256, 256 ' You could rotate and scale using normal commands of course, here's a swinging New years eve bell made out of img2 (dig out your creative interpretation skills) SetRotation Sin(swing) * 50 ; swing = swing + 1 ; swing = swing Mod 360 DrawImage img2,xsprite*2,512 SetRotation 0 Delay 1 ; Flip 1 Wend End ' ---------------------------------------------------------------------------------------- Type TImageBuffer Field Image:TImage ; Field rb:Int[1] ; Field fb:Int[1] ; Field Imageframe:TGLImageframe Field Frame:Int = 0 ; Field OrigX:Int ; Field OrigY:Int ; Field OrigW:Int ; Field OrigH:Int Function SetBuffer:TImageBuffer(Image:TImage,Frame:Int = 0) Local IB:TImageBuffer = New TImageBuffer ; IB.Image = Image ; IB.Frame = Frame ; IB.GenerateFBO() ; IB.BindBuffer() ; Return IB End Function Method GenerateFBO() ImageFrame = TGLImageFrame(Image.frame(Frame) ) ; imageframe.v0 = imageframe.v1 ; imageframe.v1 = 0.0 Local W:Int = Image.width ; Local H:Int = Image.Height ; AdjustTexSize(W, H) ; glGenFramebuffersEXT(1, fb) glGenRenderbuffersEXT(1, rb) ; glBindTexture(GL_TEXTURE_2D, Imageframe.name) ; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb[0]) glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, Imageframe.name, 0) glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb[0]) ; glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, W, H) glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rb[0]) Local status:Int = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) End Method Method BindBuffer() GetViewport(OrigX,OrigY,OrigW,OrigH) ; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb[0]) glMatrixMode GL_PROJECTION ; glLoadIdentity ; glOrtho 0, Image.Width,Image.Width, 0, -1, 1 ; glMatrixMode GL_MODELVIEW glViewport(0, 0, Image.Width, Image.Height) ; glScissor 0, 0, Image.Width, Image.Height End Method Method UnBindBuffer() glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0) ; glMatrixMode GL_PROJECTION ; glLoadIdentity ; glOrtho 0,OrigW, Origh, 0, -1, 1 glMatrixMode GL_MODELVIEW ; glViewport(0, 0, OrigW, OrigH) ; glScissor 0, 0, OrigW, OrigH End Method End Type Function AdjustTexSize(width:Int Var,height:Int Var) width=Pow2Size(width) ; height=Pow2Size(height) Repeat Local t:Int ; glTexImage2D GL_PROXY_TEXTURE_2D,0,4,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,Null glGetTexLevelParameteriv GL_PROXY_TEXTURE_2D,0,GL_TEXTURE_WIDTH,Varptr t If t Return If width>1 width:/2 If height>1 height:/2 Forever End Function Function Pow2Size:Int(n:Int) Local t:Int=1 ; While t<n ; t:*2; Wend ; Return t End Function |
| ||
Here's one with a text without using text command (donīt rely on it but It runs on all my versions and variations old and new, despite it's old) This one has a personal mess attached to it, but it's neat if you can overlook all that. ' fix why does graphics gets transparent if you draw in backbuffer ' fix simple init ' fix not end ' fix inv y ' bug in demo or why do they change appearence with time in that weak layering effect? ' When pixelread, pixelwrite, and PNG save is implemented then it may be used to replace PIXMAP all the way aswell. ' Best solutions would probably be; This VBO, PBO, Multitexture, or just a pixelshader (which bunched everything under one roof and would probably give zero drawbacks, only advantages and added flexibility). Rem One easy Method might be multitexture tex0 = dynamic RGB texture, from video stream tex1 = static RGBA mask, RGB as white And A as your alpha Using (tex0 blend tex1) with classic blending should work. I think the Default operator of the multitexture setup is blending. the Default operator is blending, And all you have To do To set up is: glActiveTexture(GL_TEXTURE0) ' bind And set up image texture; does Not need alpha channel in internal format glActiveTexture(GL_TEXTURE1) ' bind And set up alpha texture; GL_ALPHA internal, GL_ALPHA format. The mask texture doesn't need any color components it can be entirely alpha values, and when rendering: glActiveTexture(GL_TEXTURE0) glEnable(GL_TEXTURE_2D ' or similiar glActiveTexture(GL_TEXTURE1) glEnable(GL_TEXTURE_2D) And do glMultiTexCoord(GL_TEXTURE0 And GL_TEXTURE1, ...) For the texture coordinates and it magically works. EndRem ' SetMaskColor doesn't work with images that already have an alpha channel present, remove the alpha channel first. ' Local Image:TImage = LoadImage(ConvertPixmap(LoadPixmap("MyImage.png"),PF_RGB888)) ' Test # 3 ' ' aka finally-a-SETBUFFER-working-in-BlitzMAX ' ' Also, showing that alpha truly exists (a relief) ' 'Framework BRL.GLMax2D 'Import BRL.PNGLoader 'AutoImageFlags 0 ; Graphics 400,300,0 ; SetClsColor 100,200,100 'i=LoadImage("tree.png",MASKEDIMAGE) ' creates alphachannel based on setmaskcolor (if the image has an alphachannel (32bit instead of 24bit) already nothing happens) ' freetype ' cairo ' Code using BlitzMax internals which are sensitive (in that they could change with time) ' Fullscreen HideMouse ; SetGraphicsDriver(GLMax2DDriver()) ; Graphics 1920,1080,32,60 ; glewInit() ; SetBlend(MASKBLEND) ' Prepare to write some text (works for Mac and PC) SetImageFont(LoadImageFont("Default.ttf", 32)) ; Global font:timagefont = GetImageFont() ; Global g:TMax2DGraphics = tmax2dgraphics.Current() ' Init images, letīs make two Global img = CreateImage(512,512,,1) ; Local IB:TImageBuffer = TImageBuffer.SetBuffer(Img) ; Global img2 = CreateImage(512,512,,1) ; Local IB2:TImageBuffer = TImageBuffer.SetBuffer(Img2) SetMaskColor 0,0,0 ; SetBlend(MASKBLEND) ' Main loop --------------------------------------------------------------------------- ' filled box ' filled polygon ' pixels ' lines (maybe polygon) While Not MouseDown(2) ' Draw to the images (offscreenbuffers if you like) IB.BindBuffer() ; For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; DrawOval 50+Int(Rnd(512-50)),50+Int(Rnd(512-50)),Int(Rnd(50)),Int(Rnd(50)) ; Next ; SetColor 255,255,255 ; IB.UnBindBuffer() 'END IB2.BindBuffer() ; For temp=0 To 100 SetColor Rnd(255),Rnd(255),Rnd(255) '; Plot Int(Rnd(512)),Int(Rnd(512)) ; 'glDrawPixels ' simulate an overlay with the previous method, using alpha test. enable GL_ALPHA_TEST, set alphafunc to (GL_GREATER,0.5), and create a RGBA texture as described above (1024x1024 for 800x600, etc). ' Then, For each visible pixel, draw the pixel in the texture And set its alpha To 255, While undrawn pixels could be set To alpha 0. fastplot(Rnd(255),Rnd(255)) 'About twice the speed as plot, and more if you batch pixels but we donīt do that here, one pixel at a time only for now Next ; SetColor 255,255,255 ; IB2.UnBindBuffer() 'END ' Now we have two images to play with, one filled with dots, one filled with ovals ' letīs copy the one with the ovals onto the one with the dots. ' Draw from image img2 to img, letīs copy the whole thing, transfer every pixel IB2.BindBuffer() ; DrawSubImageRect img,0,512-0,512,-512, 0,0,512,512 ; IB2.UnBindBuffer() Cls 'For temp=0 To 100 ; SetColor Rnd(255),Rnd(255),Rnd(255) ; DrawOval 50+Int(Rnd(512-50)),50+Int(Rnd(512-50)),Int(Rnd(50)),Int(Rnd(50)) ; Next ; SetColor 255,255,255 ; ' Letīs draw both images onto the backbuffer so we may see what we have going on. ' One should have ovals only, And one should have the ovals And itīs pixels. ' DrawImage img,xsprite*2,0 ; DrawImage img2,xsprite*3,0 ; xsprite = xsprite + 1 ; xsprite = xsprite Mod ((1920-512)/4) ' Letīs add two more below these two, we could draw again but instead use DrawSubImageRect, just To show itīs good to use everywhere. Say you want To draw half img onto the screen. DrawSubImageRect img,xsprite*3, 512, 512, 256,0 ,0, 512, 256 ' We may stretch things too, letīs double the size (itīs just one way to fake resolutions cheaply using HW acc, it's not hard to come by today but itīs stuck in here, ready to be used) ' Offscreen buffers begs for these kind of tricks DrawSubImageRect img2,xsprite*4, 512, 512, 512,0 ,0, 256, 256 ' You could rotate and scale using normal commands of course, here's a swinging New years eve bell made out of img2 (dig out your creative interpretation skills) SetRotation Sin(swing) * 50 ; swing = swing + 1 ; swing = swing Mod 360 DrawImage img2,xsprite*2,512 SetRotation 0 ; SetScale 1,1 ' Draw 10.000 lines, each line made out of 512 pixels. Itīs a set template for an average line. ' This is a good amount of lines to create vVctor games (gow will come next) 'For temp=1 To 10000 ; DrawLine 0,0,511,511 ; Next DrawThickLine(100,100,511,511,5) draw("Not a terrible slow text",300,300) Delay 1 ; Flip 1 Wend End ' ---------------------------------------------------------------------------------------- Type TImageBuffer Field Image:TImage ; Field rb:Int[1] ; Field fb:Int[1] ; Field Imageframe:TGLImageframe Field Frame:Int = 0 ; Field OrigX:Int ; Field OrigY:Int ; Field OrigW:Int ; Field OrigH:Int Function SetBuffer:TImageBuffer(Image:TImage,Frame:Int = 0) Local IB:TImageBuffer = New TImageBuffer ; IB.Image = Image ; IB.Frame = Frame ; IB.GenerateFBO() ; IB.BindBuffer() ; Return IB End Function Method GenerateFBO() ImageFrame = TGLImageFrame(Image.frame(Frame) ) ; imageframe.v0 = imageframe.v1 ; imageframe.v1 = 0.0 Local W:Int = Image.width ; Local H:Int = Image.Height ; AdjustTexSize(W, H) ; glGenFramebuffersEXT(1, fb) glGenRenderbuffersEXT(1, rb) ; glBindTexture(GL_TEXTURE_2D, Imageframe.name) ; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb[0]) glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, Imageframe.name, 0) glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb[0]) ; glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, W, H) glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rb[0]) Local status:Int = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) End Method Method BindBuffer() GetViewport(OrigX,OrigY,OrigW,OrigH) ; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb[0]) glMatrixMode GL_PROJECTION ; glLoadIdentity ; glOrtho 0, Image.Width,Image.Width, 0, -1, 1 ; glMatrixMode GL_MODELVIEW glViewport(0, 0, Image.Width, Image.Height) ; glScissor 0, 0, Image.Width, Image.Height End Method Method UnBindBuffer() glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0) ; glMatrixMode GL_PROJECTION ; glLoadIdentity ; glOrtho 0,OrigW, Origh, 0, -1, 1 glMatrixMode GL_MODELVIEW ; glViewport(0, 0, OrigW, OrigH) ; glScissor 0, 0, OrigW, OrigH End Method End Type Function AdjustTexSize(width:Int Var,height:Int Var) width=Pow2Size(width) ; height=Pow2Size(height) Repeat Local t:Int ; glTexImage2D GL_PROXY_TEXTURE_2D,0,4,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,Null glGetTexLevelParameteriv GL_PROXY_TEXTURE_2D,0,GL_TEXTURE_WIDTH,Varptr t If t Return If width>1 width:/2 If height>1 height:/2 Forever End Function Function Pow2Size:Int(n:Int) Local t:Int=1 ; While t<n ; t:*2; Wend ; Return t End Function Function Draw(text$,x#,y#) ' routine that uses internals of BlitzMax (that might change). It doesn't use any atlas, but it makes text into regular imagedrawing which is good for testing as it at brings up the speed of "not interfering". For Local i% = 0 Until text.length Local n%=font.CharToGlyph(text[i]) If n < 0 Then Continue Local glyph:TImageGlyph=font.LoadGlyph(n) If glyph._image Then Local tx#=glyph._x*g.tform_ix+glyph._y*g.tform_iy ; Local ty#=glyph._x*g.tform_jx+glyph._y*g.tform_jy ; DrawImage glyph._image,x+tx,y+ty x = x + glyph._advance*g.tform_ix ; y = y + glyph._advance*g.tform_jx Next End Function Function DrawThickLine(x1#,y1#,x2#,y2#,thickness#) ' no smoothness, and no glow rot#=GetRotation() ; dx# = x2-x1 ; dy# = y2-y1 ; length# = Sqr(dx*dx+dy*dy) ; an# = ATan2(dy,dx) SetRotation an ; DrawRect x1+Sin(an)*thickness/2,y1-Cos(an)*thickness/2,length,thickness ; SetRotation rot End Function Function FastPlot(x,y) glDisable GL_TEXTURE_2D ; glBegin GL_POINTS glVertex2f x,y ' Here we should plot as many pixels at once as we could, so an array would be a great idea as parameter (ala polygon) glEnd ; glEnable GL_TEXTURE_2D End Function |
| ||
Getting to these in reverse order, Casaber. Your DrawThickLine is a marvel of coding, however BlitzMAX has a thickness function to assist with drawing lines: Function drawthickline2(x1,y1,x2,y2,t) SetLineWidth t DrawLine x1,y1,x2,y2 SetLineWidth 1 EndFunctionAs for the FastPlot routine, I tried it out in simple code: SetGraphicsDriver(GLMax2DDriver()) Graphics 640,480 Repeat For i=0 To 479 For j=0 To 639 SetColor Rand(256),Rand(256),Rand(256) ' fastplot j,i Plot j,i Next Next Flip Until KeyDown(32) Function FastPlot(x,y) glDisable GL_TEXTURE_2D ; glBegin GL_POINTS glVertex2f x,y ' Here we should plot as many pixels at once as we could, so an array would be a great idea as parameter (ala polygon) glEnd ; glEnable GL_TEXTURE_2D End FunctionChecking plot() with fastplot(), it is definitely not faster, not for me in this example anyways. Looking at the draw() command for plotting text. It APPEARS to be just as strong and powerful as the drawtext(), a command already available in BlitzMAX. Your Post #39 runs very fast indeed. Now looking at the size and scope of your code I am wondering if you are drawing lines, ellipses, and points directly to a tpixmap or timage, and if so, can you isolate that code and show me how you are doing this, please ? Perhaps a simple program that draws ellipses straight into a tpixmap or timage. |
| ||
Good to know the example works great for your machine aswell. Sure I could give you the simpler example for drawing a line to the Timage. Donīt mind the functions it's opengl magic. I need time to understand opengl better first. This is my personal exprimental for doing just that. But ya.. drawing to an Image i can show. Here SetGraphicsDriver(GLMax2DDriver()) ; Graphics 800,600 ; glewInit() ; SetBlend(MASKBLEND) ' Init image Global img = CreateImage(512,512,,1) ; Local IB:TImageBuffer = TImageBuffer.SetBuffer(Img) ' Draw red oval to image img (Timage) IB.BindBuffer() ; SetColor 0,255,0 ; Drawline 100,100,245,255 ; SetColor 255,255,255 ; IB.UnBindBuffer() Cls DrawImage img,0,0 ' draw it on the screen Flip 1 WaitKey End ' ---------------------------------------------------------------------------------------- Type TImageBuffer Field Image:TImage ; Field rb:Int[1] ; Field fb:Int[1] ; Field Imageframe:TGLImageframe Field Frame:Int = 0 ; Field OrigX:Int ; Field OrigY:Int ; Field OrigW:Int ; Field OrigH:Int Function SetBuffer:TImageBuffer(Image:TImage,Frame:Int = 0) Local IB:TImageBuffer = New TImageBuffer ; IB.Image = Image ; IB.Frame = Frame ; IB.GenerateFBO() ; IB.BindBuffer() ; Return IB End Function Method GenerateFBO() ImageFrame = TGLImageFrame(Image.frame(Frame) ) ; imageframe.v0 = imageframe.v1 ; imageframe.v1 = 0.0 Local W:Int = Image.width ; Local H:Int = Image.Height ; AdjustTexSize(W, H) ; glGenFramebuffersEXT(1, fb) glGenRenderbuffersEXT(1, rb) ; glBindTexture(GL_TEXTURE_2D, Imageframe.name) ; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb[0]) glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, Imageframe.name, 0) glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb[0]) ; glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, W, H) glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rb[0]) Local status:Int = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) End Method Method BindBuffer() GetViewport(OrigX,OrigY,OrigW,OrigH) ; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb[0]) glMatrixMode GL_PROJECTION ; glLoadIdentity ; glOrtho 0, Image.Width,Image.Width, 0, -1, 1 ; glMatrixMode GL_MODELVIEW glViewport(0, 0, Image.Width, Image.Height) ; glScissor 0, 0, Image.Width, Image.Height End Method Method UnBindBuffer() glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0) ; glMatrixMode GL_PROJECTION ; glLoadIdentity ; glOrtho 0,OrigW, Origh, 0, -1, 1 glMatrixMode GL_MODELVIEW ; glViewport(0, 0, OrigW, OrigH) ; glScissor 0, 0, OrigW, OrigH End Method End Type Function AdjustTexSize(width:Int Var,height:Int Var) width=Pow2Size(width) ; height=Pow2Size(height) Repeat Local t:Int ; glTexImage2D GL_PROXY_TEXTURE_2D,0,4,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,Null glGetTexLevelParameteriv GL_PROXY_TEXTURE_2D,0,GL_TEXTURE_WIDTH,Varptr t If t Return If width>1 width:/2 If height>1 height:/2 Forever End Function Function Pow2Size:Int(n:Int) Local t:Int=1 ; While t<n ; t:*2; Wend ; Return t End Function |
| ||
Try using the [codebox] tag in your forum posts, it creates a scrollable area that compacts code. Less scrolling for the people reading. |
| ||
One of the things you need to adjust is, for some reason VBOīs (as it's called) easly get things upside down. I need to inject some instructions to adjust that. So things are upside down (Y coordinate 0 is actually at the bottom). Other than that thereīs nothing to say about it really. You could just paint as usual. I'm still struggling with getting those alpha modes working. I would love to have those fully working. The thing is, I think it does work, but youīre actually set the mode for the TIMAGE itself instead of um it's some kind of source-and-destination-both-being-TIMAGEīs problem that messes things up my guess is, I could be wrong. it messes up standard commands, they get overriden. So this needs to be corrected. Those two things are on my top list now. |
| ||
Kryzon scrollable boxes. Thanks. |
| ||
Red oval is green line. I guess Itīs a surprise party. Iīm abit messed up I should get going. Wishing a Happy new year !! |
| ||
Change CreateImage(512,512,,1) to CreateImage(800,600,,1) if you like. Then you would have a Timage which would be the perfect offscreenbuffer for that particular windowsize. If you happen to want to use your TIMAGE as an offlinebuffer. This would be a good usage of it. 512x512 isnīt a fixed or maximum size, It's a personal preference that I use that alot. So this is a image, itīs a TIMAGE, itīs offlinebuffer, itīs a spritesheet, itīs a atlas, itīs a texture. Dear child have many many many MANY names. Thatīs why I got one name. |
| ||
Alright Casaber, lemme spear-a-mint here for a sec ... Will try the (codebox) Kryzon, thanks. I fixed your rotation and image flipping problem, Casaber. I just wish there was an easier way to write to a TIMAGE rather than have all that code. In GFA to create a 'timage' you could draw to, it was: newdc=MEMDC(_DC(1)) bmpdc=CREATEBMP(640,480) SETBMP newdc,bmpdc SETDC newdc circle 50,50,50,50 ' test it_dc(1) was a system pointer to the immediate screen. So to transfer this hidden page to the screen you would use one command: BITBLT newdc,0,0,640,480,_DC(1),0,0,SRCCOPYMaybe this will give a hint on a way to code your above source smaller. |
| ||
Nice, but I think we should solve the problem as early as possible, I fixed the issue now. Iīm not sure what GFA uses, I guess it does what Blitz3D did, and thatīs effecient memory pokeing. (Blitzmax & webbrowsers seem to be exactly 10x slower than B3D. Whatever B3d and probably GFA aswell, was a good solution. Somehow BlitzMax does't max out on the memory & bus as good. This kind of performance degrade is also what you see with B3D + DRD3 memory vs B3D+ DRD2 memory. I guess PIXMAP tries to be an optimized version of what you did in B3D (using writepixelfast and keeping integers in an 2d array (not 1d as the internal multiplication and even shifting beats that kind of optimizaitions, what I remember. And should one use PIXMAP I think you need to get behind the scenes a get to know it to get the most of it, the defult behaviour does too much transffering back and forth than it needs. Iīm no expert on that but thatīs my gut feeling looking at it and trying it. So poking and pretending to be a GPU is pretty much a no go as I see it. Belive me I used to love this. I still do. But when I see the power you get using GPU you can't ignore that anymore. With shaders you sort of get back to poking and get the best of both worlds again, and I will probably start using that soon as aIīve learned it. I thought I'll start with VBO. Thereīs lot of ways to use the GPU today, OpenGL is the API which I think they model the hardware after (not direct x so much). It let's you use the different aspects and parts if you know itīs maze. VBO is one way to get this "array" or B3D/GFA :ish going on, pixelshader aswell but ya.. not now. The "mess" of functions is just whatīs needed to set up to get to use the GPU in that old fashion. |
| ||
Ah, looks like you got the ergonomics correct now. No need for screen or image rotation. Good job, Casaber ! Well, maybe not now but SOMETIME I am gonna sit down and pick through this code and try to find just what it is that is making a single virtual screen. I doubt very seriously all the code is needed to decipher that, not for what I am doing anyways. Let me ask a question though. what is glewInit(). It's not a function that you wrote nor is it recognized by BlitzMAX internal help. It is also required or your program does not work. |
| ||
I'm with you with that though, but I will try to do the same. Iīm pretty convinced thouhg that surprisingly many opengl commands are needed to enter the right mode and to ya juggle things inside the GPU. But at least about 50% I think should be able to be thrown away aw best. OpenGL & GPU design is suprisingly complex but also kind of clever I. I think one of the hardest bits are to know every constant parameter for every commands. It's a djungle. I think GLEW is for extensions, OPENGL has a CORE and then it has EXTENSIONS. EXTENSIONS are kind of "things graphics card companys and driver /API desingers come up and want to try out." if it works out good, it goes into the standard (CORE). So GLEWINIT allows extensions (versions of opengl has different cores, and the rest is accessed via extensions). For example this code is old you can tell. Becuase it has EXT everywhere that you actually can remove. Try remove all the EXT and you'll see it still works. I think itīs becuase they have gone into the CORE by now. |
| ||
Iīm thinking B3D/GFA uses PBO or just something like a very tight lowlevel loop. PBO is asynchrounous transfer from CPU-GPU so my guess is PBO is the best possible software rendering speed. We could probably get 1000.000 pixels under 12 msec in BlitzMax using a PBO. Same as B3D & GFA. (Memory and bus capped) But that is pretty lousy for todays resolutions, so I guess we want to go beyond that. The only good use would be to have PBO and then use the GPU for some fake scaled resolution. That doesnīt sound tempting, Itīs too limited. PBO is what PIXMAP *should've be* (best possible transaction between CPU and GPU) While VBO and Shader allows raw GPU power. So that leaves us with only VBO and Shader I guess. The downside of VBO are read/write pixels, but shaders fills that department as long as you are clever. Multexture, Stencilbuffer, Depthbuffer are functions I might check in if they are still going strong in all new hardware, or if they are emulated nowadays using some lower functionse.g. shaders. I know that the hardware is getting just simpler and simpler, but above the surface they seem still complex. Okay so this is one of the two definitive best ways to use a GPU today is my personal conclusion. I like that. Weīre on the right track. |
| ||
Multitexture might have changed into things called Array textures, Texture atlas, and Bindless textures. God this is a mess more than it have to be. Oh well. |
| ||
Should we just await Vulcan? haha I'm beginning to think so. |
| ||
![]() Hmm ? What is Vulcan ? A graphic library ? Not the one I'm familiar with, right ? |
| ||
Hmm ? What is Vulcan ? A graphic library ? Not the one I'm familiar with, right ? A graphics API, aiming to replace OpenGL for cross-platform graphics: https://en.wikipedia.org/wiki/Vulkan_(API) |
| ||
Thank you, Xlsior. Unless it's gonna speed up my little pixel quest, it might be some time before I'm interested in it. I would have to see some example programs and benchmarks done and written with it to see it's use and validity. Anything that SIMPLIFIES things for others is always of interest to me. |
| ||
You could also use a binary space partitioning tree of sorts where the world was modeled with a tilemap. When a tile was damaged, it would be drawn as four subtiles, and recursively down to whatever your pixel size was. When a subtile had fewer than a certain number of sub-sub-tiles active in it, it would be destroyed. This would also allow you to do connectivity testing so that when a piece was completely chiseled away from its support, it would fall. |
| ||
Erm surely dividing the game level into tiles and working out what tiles are damaged by the x,y and radius of the explosion then drawing them and removing explosion area. This way when the level I'd drawn it's damaged :) Much easier and it's how I did a scorched tanks game that worked on a CGA IBM XT for me brother ;) |
| ||
Well now EdzUp, this is initially how I handled pixels back in Floating Point Basic, Turbo Pascal, F-Basic, GwBasic, Q-Basic, and GFA. I would use an array and CHECK before I plot to ensure that it was not already lit and the same color. You could also do this for tiles or any other elements where you had a large and different number of on the screen. Doing this also ensured smooth graphics with no flickering. Dissecting the machine-code for Ultima II, I saw they were doing this, whereas in Ultima I, they were not. I knew something was up when the mapper got faster with less details on the screen and slower with. It required some closer investigation. :) Today however computers are so darned fast that its not really an issue. Still - any library or routine that goes faster than writepixel() I would definitely be interested in as it's a ton of fun to write your own complex graphic libraries that work one pixel at a time and still maintain 30fps. |
| ||
That's essentially dirtyrects. Are you sure Garriot did a per-pixel check before drawing? Did he do that or did he check the grid to see if a given shape had already been drawn? Had to have been the latter. This sort of thing is still an issue on mobiles. |
| ||
Sorry to leave you hanging, Casaber. I'm using your miracle code here to demonstrate how powerful it is. Here is a simple map scroller, with a difference. The map is actually a virtual 1024x1024 pixel field. I was messing all last night with chopping out bits of unnecessary code from the library - when I gave it some thought, what if something doesn't work later ? So, I opted to keep ALL the code even though I know half of it isn't being used nor will I ever use it. But code space is cheap - just file it away under "crazy code" and everything will turn out alright. :) Why does this run so fast ? Because NOTHING is being drawn to the screen, that's already been done ahead of time. The only actual code that is running is to clear the screen, plot two images on top of each other - read the arrow keys to adjust X & Y for plotting the first image, repeat, done. I can't even get my CPU to register 1% usage out of this, that's NICE ! |