Possible bug in CopyPixelFast (Blitz 2D)
BlitzPlus Forums/BlitzPlus Programming/Possible bug in CopyPixelFast (Blitz 2D)
| ||
There's no bug forum for Blitz 2D anymore, so I thought I would post this here to see if anyone can tell me I am doing something wrong, or that this is indeed a bug. It's about the CopyPixelFast command. I keep getting a "Memory Access Violation" when trying to copy a pixel from an ImageBuffer to the FrontBuffer (or BackBuffer, it doesn't seem to matter, the critical part seems to be the ImageBuffer part). The Help file says this should be "used on a locked buffer" but this is somewhat cryptic as the command works on two buffers. Also, the first buffer in their example is an "ImageBuffer'ed" buffer as well. These can't be locked as far as I know. My own code I have reduced to the following lines. (The image used should of course be at least of size 11*11 as I am reading from position 10,10.) Does anyone have an idea?Graphics 640,480,16 pic = LoadImage("Graphics/wall_2.png") LockBuffer CopyPixelFast 10,10,ImageBuffer(pic),10,10 UnlockBuffer WaitKey EndNote that normally I would use brackets and stuff but I changed this to look like the online example (in the end you try everything...). Edit: it's not a case of the image not being loaded, I tested this by adding a DrawImage and WaitKey right after the LoadImage command. It's also not a problem with a wrong video mode (as far as I can tell), I tried removing the 16 in the Graphics command and it doesn't help. Also tried different resolutions. |
| ||
The 'Fast' commands operate on locked buffers. CopyPixelFast uses two buffers and *both* must be locked. So you need a 'LockBuffer ImageBuffer(pic)', and Unlock when done. |
| ||
But ImageBuffer(pic) is a call to a function, so I can't use LockBuffer on that can I (or am I mistaken about ImageBuffer?). Or should I do:mybuffer = ImageBuffer(pic) LockBuffer(mybuffer) CopyPixelFast 10,10,mybuffer,10,10Hmmm... In the meanwhile here's a picture of the project that I am trying to use this in, it's a raycaster. Currently it uses rectangles to draw the wall slices, but I want to use texture mapping (although if it doesn't work out in the end, the rectangles look nice too and are really fast!). That texturing stuff is working but very slow, and CopyPixelFast could be of some help (maybe it would go from 3 fps to 4 or 5 fps...). ![]() |
| ||
You can Lock any imagebuffer as well as the front and back buffers |
| ||
Ok, thanks to both of you for helping me with this! I will try something like the following (but only by tomorrow as it is quite late here already).SetBuffer(ImageBuffer(pic)) LockBufferActually that makes a lot of sense, I am using this SetBuffer(ImageBuffer(pic)) idea in other parts of my code as well... Still the example in the Help file under CopyPixelFast appears to be wrong. |
| ||
floppy, i had trouble with my engine to and found it faster to copy images to an array containing their argb values, then read the array and use write pixel fast this got my fps up to 60 fps at 640*480 |
| ||
Hey injeevious it took me a few days to realize what you meant but of course you are right, why am I locking things and using "readPixelFast" on an image that will never change anyway, to get those rgb values, it makes no sense... so I will try the array approach. Thanks! |
| ||
There was quite an improvement using an array instead of the image, FPS rate for the textured version went from something like 10/15 to 20/25. That may not sound like much but it is about good enough for a game. But for now I stick to plain walls. |
| ||
from something like 10/15 to 20/25. That may not sound like much Yes it does, that's a 100% increase! |
| ||
is there a reason that blitz dosen't use arrays for images? |
| ||
I know this is sorta resolved, but for the record (as Floyd said) for the example up there to work ImageBuffer (xxx) should also be locked prior to the CopyPixelFast call, so you'd be doing something like this...Graphics 640,480,16 pic = LoadImage("Graphics/wall_2.png") LockBuffer ; Current buffer... LockBuffer ImageBuffer (pic) CopyPixelFast 10,10,ImageBuffer(pic),10,10 UnlockBuffer ImageBuffer (pic) UnlockBuffer WaitKey End |
| ||
well, the arrays would be stored in system memory, apposed to video memory. this would use alot of system memory up. thats the point of video card memory. and i'd imagine it would be slower when drawing the images?? |
| ||
no as shown above its much faster to draw images from a normal array |
| ||
what, so writing lots of pixels to the screen is faster than using the draw image command? Or am i missing the point? This example copys pixels across buffers and draws images to the screen. press 1 to get the images being drawn with DrawImage command and press 2 to get the images drawn by CopyPixelFast. Graphics 800,600 SetBuffer BackBuffer() img=CreateImage(50,50) SetBuffer ImageBuffer(img) Color 100,200,255 Rect 0,0,50,50 SetBuffer BackBuffer() mode=0 Color 50,150,20 While Not KeyHit(1) Cls If KeyHit(2) Then mode=0 If KeyHit(3) Then mode=1 If mode=0 Then For loop=0 To 8 For loop1=0 To 8 DrawImage img,loop*52,loop1*52 Next Next ElseIf mode=1 Then LockBuffer BackBuffer() LockBuffer ImageBuffer(img) For loop=0 To 8 For loop1=0 To 8 For loop2=0 To ImageWidth(img)-1 For loop3=0 To ImageHeight(img)-1 CopyPixelFast loop2,loop3,ImageBuffer(img),(loop*52)+loop2,(loop1*52)+loop3,BackBuffer() Next Next Next Next UnlockBuffer ImageBuffer(img) UnlockBuffer BackBuffer() End If If MilliSecs()<timer+1000 Then frame=frame+1 Else fps=frame frame=0 timer=MilliSecs() End If Text 0,0,"FPS="+fps Flip False Wend End I do apoligise if i'm talking about something different from you ^_^ |
| ||
Well it was not about drawing images in the normal way. The technique here is to copy them pixel by pixel in such a way that the result is a scaled version of the original. And in that case reading the relevant pixel color from an array seems to be faster than using ReadPixelFast on the original image. So, the choice was not between DrawImage and Read/WritePixelFast but between look-up in an array and ReadPixelFast. James, thanks for that example. I would never have guessed that ImageBuffer could be used in that way, this should make some things easier! |