How is the fastest way to convert array to image canvas data? lazarus / 39-Graphics ---------------------------------------------------------------------- Milsa · 2014-02-05 20:33 I have array[0..919, 0..286] or array[0..264039] and I want fast convert to TBitmap.Canvas (920x267). Maximal time for this operation is around 1/100 of second. I want show this image 50 times per second (emulation of 8-bit computer). Do you have any multiplatform idea (Windows, Linux)? ---------------------------------------------------------------------- Michl · 2014-02-05 22:06 I don't know what the fastest way at all, but here is one of some methods (and if you want, you can test all and report it here  ). ---------------------------------------------------------------------- Milsa · 2014-02-06 11:08 Thank you very much. I will look at it and I will write. ---------------------------------------------------------------------- Milsa · 2014-02-15 21:16 This wiki article is not correct. This is problems: - Pixels[] in last code (OpenGL) and RandomImage without Pixels (2 different declaration of TFastBitmap) - OpenGLBitmap in last 2 codes. What is it? - many syntax errors in article (function instead of procedure, FPixelData instead of FPixelsData, FreeData instead of FreeMem) Has somebody functional code from this wiki article with OpenGL? I appreciate the work of authors of wiki articles but this article is really not correct.  Please help me with this. ---------------------------------------------------------------------- skalogryz · 2014-02-15 22:07 This is 8-bit array, right? Do you have the palette? I guess you'd need 24-bit (r,g,b) TBitmap to be shown of the form? On the other hand, if you're looking into rendering through OpenGL you won't need TBitmap at all. (having palette is still required, though) ---------------------------------------------------------------------- skalogryz · 2014-02-15 22:42 fast enough? I guess the truth is not about the fastest way of converting one image format to another, but about fastest way to render. That's OpenGL for cross-platform. ---------------------------------------------------------------------- Milsa · 2014-02-16 10:06 Thanks for your help but compiler found an error: unit1.pas(116,10) Error: identifier idents no member "ScanLine" ---------------------------------------------------------------------- skalogryz · 2014-02-17 02:35 Quote from: Milsa on February 16, 2014, 11:06:58 amThanks for your help but compiler found an error: unit1.pas(116,10) Error: identifier idents no member "ScanLine" fair enough, you're on earlier Lazarus version than i am. Try this one. ---------------------------------------------------------------------- howardpc · 2014-02-17 09:37 Thank you to whoever (Felipe?) recently added a Scanline property to TRasterImage ---------------------------------------------------------------------- marcov · 2014-02-17 11:31 Quote from: skalogryz on February 15, 2014, 11:42:46 pmfast enough? I guess the truth is not about the fastest way of converting one image format to another, but about fastest way to render. That's OpenGL for cross-platform. Drawing/rendering is fast. Uploading bitmaps not so.  IIRC there is not that much difference between blitting a GDI bitmap and opengl if you do it 1:1. Only if you start zooming, opengl becomes faster. ---------------------------------------------------------------------- skalogryz · 2014-02-17 15:27 Quote from: marcov on February 17, 2014, 12:31:33 pmDrawing/rendering is fast. Uploading bitmaps not so.  IIRC there is not that much difference between blitting a GDI bitmap and opengl if you do it 1:1. Only if you start zooming, opengl becomes faster. ugh.. it depends on the "GDI" implementation. if GDI is pure CPU, OpenGL could still be a bit faster, since fillrate is typically higher on GPU. Plus CPU would be released for executing the code, rather than copying memory. These days however, most of "GDI" are using hardware acceleration (through either OpenGL or DirectX). Oh yes, if OpenGL drivers are not so good, it might be implemented through CPU as well In this particular case (buffer: 0..919, 0..286) there won't be any difference. ---------------------------------------------------------------------- Milsa · 2014-02-18 18:42 It is too slow - maximim is 60 fps for invalidate, 52 fps for paint. 8-bit computers have double scanlines. Real resolution with double scanlines is 920x574 (640x200 + border + double scanlines). This resolution is too slow - 31 fps for invalidate, 28 fps for paint. I think that OpenGL is better option. Thank you for your help. ---------------------------------------------------------------------- User137 · 2014-02-18 18:55 GPU does not specialize in moving data from RAM to video memory either. It is fast, but still slow enough to recommend all/most textures to be loaded to GPU when application starts. If you do fullscreen pixel streaming from RAM, you won't have computer resources left for much of anything else. But both are viable methods, as can be said for most mediaplayers. VLC for example has the option to use GPU, but it was never the only way. ---------------------------------------------------------------------- Milsa · 2014-02-18 19:19 And this method? Creating BMP file in memory and showing it directly with OpenGL? Will it be faster? My question is on base this answer: http://forum.lazarus.freepascal.org/index.php/topic,23625.msg141541.ht ml#msg141541 ---------------------------------------------------------------------- skalogryz · 2014-02-19 04:24 give it a try. you'll need to have LazOpenGLContext package installed. Quote from: Milsa on February 18, 2014, 07:42:09 pmIt is too slow - maximim is 60 fps for invalidate, 52 fps for paint. 8-bit computers have double scanlines. You should probably decrease the timer interval, to get a higher FPS? Otherwise I don't understand how an invalidate could be faster than direct paint. Also, it might be that you won't get a higher rate  than your monitor allows. Modern gui engines are based on GPU and are enforcing VSync for any windowed application. ---------------------------------------------------------------------- Milsa · 2014-02-19 15:45 Try it: invalidate - 55 not invalidate - 60 OpenGL is slower than previous. I do not understand it. ---------------------------------------------------------------------- User137 · 2014-02-19 16:14 The uploaded zip isn't using OpenGL though? Also i notice that the rendered area goes outside the form's right boundary. I get 64 with or without invalidate, but that's just my computer... ---------------------------------------------------------------------- Milsa · 2014-02-19 16:47 It is previous code. OpenGL is without invalidate checkbox. ---------------------------------------------------------------------- skalogryz · 2014-02-19 17:02 Quote from: Milsa on February 19, 2014, 04:45:34 pminvalidate - 55 not invalidate - 60 This is because you're counting Timer events The FPS counter needs to be placed at the actual painting code. ---------------------------------------------------------------------- Milsa · 2014-02-19 17:58 Thank you all for your help. Counting in FormPaint: invalidate - 110 FPS not invalidate 62 FPS OpenGL code no changes. Thank you all. ---------------------------------------------------------------------- skalogryz · 2014-02-19 18:04 Quote from: Milsa on February 19, 2014, 06:58:25 pmOpenGL code no changes. That doesn't sound right. OpenGL code also has "Idle" event added. So the "paint" should happen more often than "FormPaint" Please count FPS for OpenGL at TForm1.OpenGLControl1Paint procedure. ... btw. if OpenGL shows a better FPS now, you could add the same on Idle event for Non-GL example. In general, video intensive applications (such as games or video players) never use Timer Events to refresh the frame, instead they either paint as much as possible or on VSync signal. (In the gl example I'm using "idle" to draw "as much as possible") ---------------------------------------------------------------------- reinerr · 2014-02-24 04:09 I'm just wondering, the original poster is targeting an 8-bit system. Would such a system have hardware OpenGL support or will it be falling back to software rendering anyway? ---------------------------------------------------------------------- BigChimp · 2014-02-24 07:44 Quote from: reinerr on February 24, 2014, 05:09:41 amI'm just wondering, the original poster is targeting an 8-bit system. No he's not, he's emulating an 8 bit system: Quote (emulation of 8-bit computer). ---------------------------------------------------------------------- macjone · 2014-03-07 02:13 Quote from: skalogryz on February 15, 2014, 11:42:46 pmfast enough? I guess the truth is not about the fastest way of converting one image format to another, but about fastest way to render image. That's OpenGL for cross-platform. Yes, and which one do you think is faster to render image, byte[] or stream? By the way, I do not know following link can offer some insight for you. http://stackoverflow.com/questions/17352061/fastest-way-to-convert- image-to-byte-array ---------------------------------------------------------------------- skalogryz · 2014-03-07 04:13 Quote from: macjone on March 07, 2014, 03:13:59 amYes, and which one do you think is faster to render image, byte[] or stream? By the way, I do not know following link can offer some insight for you. http://stackoverflow.com/questions/17352061/fastest-way-to-convert- image-to-byte-array it depends on the "stream". If stream is memory stream, then there won't be any difference. If stream is a file stream, most likely byte[] is faster (since byte[] is in memory)