Hello, please watch this short demonstration. This is my current project. For several reasons I've written my own window- and gadget-management that fits my purposes perfectly. The game itself is already there but I've to rebuild the user interface with a new level editor. Design comes later. Anyway, I've no clue at the moment, why everything is running so slowly, the old application reached 60 fps on Android easily.
The window management works as follows. Windows are defined via functions and stored in arrayed types. Then there's a window list to define the order all opened windows will be displayed. Only windows that can be visible will be drawn so for performance reasons it's basically not necessary to close each window when a new one is completely in front of the other. There can be subs that are appended to each window and will be called via the CALLBYNAME command.
Is it known that this command causes trouble under Android? At least I've never used it before.
Also each window has it's own gadget list that tells the window drawing routine which gadgets has to be drawn within a window. And there's a buffer for a window background- and foreground drawing routine. Gadgets will drawn between. Finally each window has a function list that contains all functions that are executed before everything will be drawn. These functions can be triggered by changing window state slots.
Unfortunately I cannot show you the full source code because the project shall go a little beyond the hobby state, let's say.
Any suggestions what could cause the speed issue? Note the sudden speed gain when the world overview window is opened. And I can tell you for sure, all other windows are still there...
Ok guys, I found the issue. It's the sub that draws the chessboard background! Under Win32 I checked the CPU load while running the application and the window with that background caused around 40% cpu load. By removing that drawing function I saved 30% load! This is the function:
SUB ChessBoard:
LOCAL x%, y%
x = GetWindowXPosition(1)
y = GetWindowYPosition(1)
FOR i = 0 TO BasScrHei / 16
FOR j = 0 TO BasScrWid / 16
DRAWRECT x + 0 + j * 16, y + 0 + i * 16, 8, 8, 0x444444
DRAWRECT x + 8 + j * 16, y + 8 + i * 16, 8, 8, 0x444444
NEXT
NEXT
ENDSUB
BasScrHei = 512 and BasScrWid = 1024 so we have 64 x 32 x 2 = 4096 DRAWRECT calls. Each rect with a size of 8 x 8 pixels. I was not expecting this to cause so much ressources...
What do you think, is this usual?
Now how about a good workaround? To host this repetitive 1024 x 512 pixel background as a graphic file would be very unprofessional. I would like to draw it once and then save it during run time. Hopefully GRABSPRITE will work... or how would you do that?
There are numerous ways to draw checkerboards, personally I would create a 64x32 checkerboard sprite then draw a single POLYVECTOR with SMOOTHSHADING set to false the size of the screen. The sprite could be generated at runtime or at the start if you are planning different resolutions, however I'm not 100% sure if virtual screens are currently working on Andriod.
Lee
Virtual screens are working fine on android, you should be fine.
Also DRAWRECT Might not been colored on some devices. Use POLYVECTORS and do fewer calls.
Try precalculating the math before hitting loops.
LOCAL LOOPENDVAL% = BasScrHei / 16
Also precalculate the Draw requirements.
LOCAL DX% = x + 0 + j * 16
LOCAL DY% = y + 0 + i * 16
The problem is you are doing 16 * 16 * 6 calculations everytime you hit that sub.
You need to reduce the cpu workload here.
You can also reduce compile time by organizing the math a little bit..
LOCAL DX% = (j * 16) + x
I dont know if it will be noticable or not...but i assume on a small machine you might..try replacing the routine with this:
SUB ChessBoard:
LOCAL x% = GetWindowXPosition(1)
LOCAL y% = GetWindowYPosition(1)
LOCAL H2% = BasScrHei / 16
LOCAL W2% = BasScrWid / 16
FOR i = 0 TO H2
LOCAL Y2 = (i * 16) + y
LOCAL Y3 = (i * 16) + y + 8
FOR j = 0 TO W2
LOCAL X2 = (j * 16) + x
LOCAL X3 = (j * 16) + x + 8
DRAWRECT X2, Y2, 8, 8, 0x444444
DRAWRECT X3, Y3, 8, 8, 0x444444
NEXT
NEXT
ENDSUB
Great hints! Thanks a lot. Had really not such ideas before even if it sounds quite plausible once adverted :)
Will test it out and give feedback about the results. I confirm, virtual screens are working fine on Android, my application uses it to fit on all resolutions.
Just to mention, it's does do have some sort of speed penaty using virtual screen, but again it's depend on project.
None of my projects use them.
Yes, that's no question. But it's absolutely necessary. Every good app you want to offer should handle different screen resolutions. And I honestly can't imagine that any other scaling technology than the one using virtual screens is as efficient and easy to use for the programmer. But please put it right if you know the truth ;)
Ok, the new results are somewhat disappointing. I tried to reduce the realtime mathematics and was able to notice a small difference. A little bit more speed but still much too slow. Then I tried to draw the same checkerboard by using POLYVECTOR. No difference, almost same load.
Then I was happy to find this method:
SUB ChessBoard:
STATIC ini%
LOCAL x%, y%
x = GetWindowXPosition(1)
y = GetWindowYPosition(1)
IF ini = 0
ini = 1
DRAWRECT 0, 0, BasScrWid, BasScrHei, 0x222222
FOR i = 0 TO BasScrHei STEP 16
FOR j = 0 TO BasScrWid STEP 16
DRAWRECT 0 + j, 0 + i, 8, 8, 0x444444
DRAWRECT 8 + j, 8 + i, 8, 8, 0x444444
NEXT
NEXT
GRABSPRITE 1, 0, 0, BasScrWid, BasScrHei
ELSE
DRAWSPRITE 1, x, y
ENDIF
ENDSUB
It works pretty nice under Win32, got similar low load as on other screens/windows. But then the disappointment when running on Android: The grabbed sprite is completely white. So I assume GRABSPRITE isn't working properly on Android, currently. Or is there something that I've missed?
What android device are you using as a base test?
I wonder why not do the board with drawsprite of a white and a black square? I could be missing something here...
I just tested the simple program I posted on different topic http://www.glbasic.com/forum/index.php?topic=9975.msg87568#msg87568 (http://www.glbasic.com/forum/index.php?topic=9975.msg87568#msg87568) & the grabsprite fails on my android phone, Xperia Z running 4.4.2.
Rest of the program runs as expected but it drawn sprite is empty/blank.
Lee
hmm i had an issue with grabsprites in AGOSA on win32..
...ill look into it and see what i came up with as the solution, bbiab
GRABSPRITE on ANDROID devices doesnt work . Use CREATESCREEN and USESCREEN
http://www.glbasic.com/forum/index.php?topic=8217.msg69305#msg69305
Ciao
gonna say...i had no fix...it was a problem with setting SETTRASPARENCY, which i removed.
Oh...
Now I try the MEM2SPRITE method and have much trouble to get the formula right to bring a set of the checkerboard pattern into the data matrix. I thought to make 32x32 pixel sprites from it so I've to create a set of 4x4 of these 8x8 pixel squares. This is the current function:
SUB ChessBoard:
STATIC ini%
LOCAL Ima%[]
LOCAL x%, y%
x = GetWindowXPosition(1)
y = GetWindowYPosition(1)
IF ini = 0
ini = 1
REDIM Ima[1024]
FOR i = 0 TO 31 STEP 16
FOR j = 0 TO 31 STEP 16
FOR k = 0 TO 7
FOR l = 0 TO 7
Ima[(i * 32) + j + (k * 32) + l] = 0xFF444444
NEXT
NEXT
NEXT
NEXT
MEM2SPRITE(Ima[], 1, 32, 32)
DIM Ima[0]
ENDIF
FOR i = 0 TO BasScrHei STEP 32
FOR j = 0 TO BasScrWid STEP 32
DRAWSPRITE 1, x + j, y + i
NEXT
NEXT
ENDSUB
The result you can see in the screenshot. So far all right. I've marked the pattern set this function creates. Now I've to place another 3 squares right from, below and diagonal right/below of the first one. But no matter how I change the formula (i * 32) + j + (k * 32) + l
the result is absolutely wrong. To my understanding the formula to place one more square right of in the matrix should be (i * 32) + j + 16 + (k * 32) + l
but it isn't.
Have to say sorry, my understanding for mathematics is quite limited so programming can easily become a running the gauntlet for me. Finally I found the right formula and my checkerboard background can be drawn correctly:
FOR i = 0 TO 16 STEP 16
FOR j = 0 TO 16 STEP 16
FOR k = 0 TO 7
FOR l = 0 TO 7
Ima[(i * 32) + j + (k * 32) + l] = 0xFF444444
Ima[(i * 32) + 8 + j + (k * 32) + l] = 0xFF323232
Ima[256 + (i * 32) + j + (k * 32) + l] = 0xFF323232
Ima[256 + (i * 32) + 8 + j + (k * 32) + l] = 0xFF444444
NEXT
NEXT
NEXT
NEXT
But one thing I noticed though. Normally the color value 0x222222 that I used is clearly visible. In this case, if I set it as 0xFF222222 for MEM2SPRITE I got black pixels. Why?
[EDIT]
Fortunately this method works on Android nice and smooth, so it's an acceptable solution for me, even if a bit unlikely. Please pardon the inconvenience!
0xFF222222
try 0xFF2222 instead
Hex is basically 6 characters long not 8 (not including the 0x part of course)
R G B red green blue each is 2 chars long
This color should look pink.
Quote from: Hemlos on 2014-Sep-08
0xFF222222
try 0xFF2222 instead
Hex is basically 6 characters long not 8 (not including the 0x part of course)
R G B red green blue each is 2 chars long
This color should look pink.
MEM2SPRITE colours in array are 8 chars(32bit), 2x each of Alpha, Blue, Green, Red. 0xAABBGGRR.
I should be home soon so will have a look at your code more closely S.O.P.M when there. Also 0xFF222222 is a very very dark gray. Does it look black on windows or android as don't forget nearly all android devices are 16bit colour & not 24bit like pc's etc.
Lee
hmm
Quote from: fuzzy70Also 0xFF222222 is a very very dark gray. Does it look black on windows or android as don't forget nearly all android devices are 16bit colour & not 24bit like pc's etc.
Yes, it's a quite dark gray but it was cleary visible on a black ground under Win and also on my Android phone. I still believe 0xFF222222 should be exactly the same color value than without the transparency declaration 0x222222. So I don't understand why DRAWRECT x, y, w, h, 0x222222 is visible and 0xFF222222 if saved for MEM2SPRITE absolutely not.
However, this is not a problem because I was able to get a similar grey with other values. And that's all I need. Would still nice to understand the mathematical or other background, though.
Interesting, I just done a test with the following code
LOCAL spritemem%[]
LOCAL loop%
DIM spritemem[76800]
FOR loop = 0 TO 76799
spritemem[loop]=0xFF222222
NEXT
MEM2SPRITE(spritemem[],1,320,240)
DRAWSPRITE 1,321,0
DRAWRECT 0,0,320,240,0x222222
SHOWSCREEN
MOUSEWAIT
which basically draws 2 rects the same colour, 1 using DRAWRECT & other with a sprite made from MEM2SPRITE & the result was as expected, 2 rects the same colour.
Tested on both Windows & Android.
Lee
Impossible... your code is working. Now I've changed my code again and it works also. Don't ask me what was wrong the last time.
Another thing puzzles me now. The CPU load is very different in same situations. One time I start the program it goes not above 10%, another time it's at 20-25% permanently. Sometimes the load reduces by itself while the app is running and nothing else changes. I can minimize the window and if I bring it back the load can be very low while I can use the app on any screen. How can that be? My graphics driver is up to date.
Welcome to windows lol. No seriously though I have that problem with non glb apps as well & never really got to the bottom of it.
Lee
I don't think it's windows. Not that I observed the overall load, no, the load of exactly my app. I'm sure it's an issue with OpenGL.
You can significantly reduce all draw calls by drawing 1 large rect of black then draw white tiles using a step in you loop calculations
You dont need to draw all 64 squares - Just 17
:P
duplicate...
Luckily, all problems are gone. The app currently runs perfectly fine, even if there's a lot to do before it's finished. Programming is always a great learning experience for me.