Hello,
I wanted to test something : AppGameKit Tier 1 is slow to treat a lot of data so I thinking of using shader to calculate some things.
In my case, to test, I imagined 100 elements with random x, y coordonates from 0 to 1000.
I wanted to know for every element which ones are closer than 100 pixels.
I do it with AppGameKit and with a shader to see the calculation time.
With the shader, I give a table vec2 to the shader that I applied to a 100x100 sprite. The result i a image where every line is a element with pixel of "close" elements are white.
To analyse that I use GetImage avec a memblock to check the pixel colors.
This is my code :
#constant nbr_elt 100
#constant indice_max 99
// show all errors
SetErrorMode(2)
// set window properties
SetWindowTitle( "test" )
SetWindowSize( 1024,768, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window
// set display properties
SetVirtualResolution( 1024, 768 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 30, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 ) // since version 2.0.22 we can use nicer default fonts
spr = createsprite(CreateImageColor(255,255,255,255))
SetSpriteSize(spr,nbr_elt,nbr_elt)
sha = LoadSpriteShader("test.glsl")
SetSpriteShader(spr,sha)
tab_x as integer[indice_max]
tab_y as integer[indice_max]
res as integer[indice_max,-1]
res2 as integer[indice_max,-1]
for i=0 to indice_max
tab_x[i] = Random(0,1000)
tab_y[i] = Random(0,1000)
next
//AGK Test
t1#=timer()
for i=0 to indice_max
for j=0 to indice_max
if(i=j) then continue
distance# = sqrt(pow(tab_x[j]-tab_x[i],2)+pow(tab_y[j]-tab_y[i],2))
if(distance#<100.0)
res[i].insert(j)
endif
next
next
t1#=timer()-t1#
//Shader Test
t2#=timer()
for i=0 to indice_max
SetShaderConstantArrayByName(sha,"color",i,tab_x[i],tab_y[i],0,0)
next
ClearScreen()
DrawSprite(spr)
img = GetImage(0,0,nbr_elt,nbr_elt)
//SaveImage(img,"res.png")
res2=pickColor(img)
t2#=timer()-t2#
do
print("AGK code")
print(t1#)
print(res[0].toJSON())
print(res[1].toJSON())
print(res[2].toJSON())
print("")
print("Shader code")
print(t2#)
print(res2[0].toJSON())
print(res2[1].toJSON())
print(res2[2].toJSON())
sync()
loop
function pickColor(img)
mem = CreateMemblockFromImage(img)
width = GetImageWidth(img)
height = GetImageHeight(img)
res as integer[indice_max,-1]
offset as integer = 12
for y = 0 to height- 1
for x = 0 to width- 1
r = getMemblockByte(mem, offset)
g = getMemblockByte(mem, offset+1)
b = getMemblockByte(mem, offset+2)
a = getMemblockByte(mem, offset+3)
if(g=255)
res[y].insert(x)
endif
offset = offset + 4
next
next
endfunction res
And the shader in test.glsl
#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 color[100];
uniform vec2 agk_spritesize;
varying vec2 uvVarying;
void main(){
int x = int(uvVarying.x*agk_spritesize.x);
int y = int(uvVarying.y*agk_spritesize.y);
if(x==y)
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
else
{
float d = distance(color[x], color[y]);
if(d<100.0)
gl_FragColor = vec4(1.0,1.0,1.0,1.0);
else
gl_FragColor = vec4(0.0,0.0,0.0,1.0);
}
}
With 100 elements, AppGameKit is faster than the shader.
I wanted to try with 1000 elements (you have to change the AppGameKit constants and the table size in the shader).
But now the GetImage command is cropped (because it depends of the resolution).
I see no other solution to get the result of the shader (GetSpriteImageID returns the original image).
There is maybe another solution...
It's not important, only for "fun"/"test" porpose but feel free to play with this code and shar your propositions.
Bye,
Riusz