Forum Replies Created
-
AuthorPosts
-
Thanks Abakobo!
Note that Image and Pixmap (extends Ressource) are not GCed so you you have to .Discard() them before replacing/loosing them or you’ll leak memory. But as the are not GCed Mark won’t tell it’s not safe to point to them!?
Hmmm, I thought I read Mark had changed the GC…
Edit:
On Mark’s Blog:This means it’s not strictly necessary to use Discard to cleanup resources any more, GC will eventually do it for you. GCCollect() is still slow so Discard is recommended in realtime situations, but on the whole it should be possible to write apps without worrying about using Discard at all now.
Thanks Peter – I was wondering if you found a bug or something and decided on removing it.
Really like how you implemented the component functionality.
Okay bench marking is done
Debug Timing
Monkey12345678910OriginalVersion = 381msOriginalVersion = 381002μsAbakoboVersion = 382msAbakoboVersion = 382499μsimpixiVersion = 5msimpixiVersion = 5000μsNewVersion = 2msNewVersion = 2499μsRelease Timing
Monkey12345678910OriginalVersion = 20msOriginalVersion = 20000μsAbakoboVersion = 18msAbakoboVersion = 18022μsimpixiVersion = 1msimpixiVersion = 501μsNewVersion = 0msNewVersion = 499μsAnd here is the full code:
Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234Namespace myapp#Import "<std>"#Import "<mojo>"#Import "assets/"Using std..Using mojo..Const Size:=New Vec2i( 320,200 )Class MyWindow Extends WindowField tileSet:Image[]Field tileSetMask:Int[,,]Field tileSetClass:TileSetField tileSetClass2:TileSet2Method New()Super.New( "My Window",1024,768,WindowFlags.Resizable )Window.ClearColor = Color.BlackLayout="letterbox"tileSet = LoadSpriteSheet("tileset.png", 32, 16, 16)tileSetMask = New Int[32, 16, 16]Local s := Millisecs()Local n := Microsecs()OriginalVersion()Print "OriginalVersion = " +(Millisecs()-s)Print "OriginalVersion = " +(Microsecs()-n)s = Millisecs()n = Microsecs()AbakoboVersion()Print "AbakoboVersion = " +(Millisecs()-s)Print "AbakoboVersion = " +(Microsecs()-n)s = Millisecs()n = Microsecs()tileSetClass = New TileSet("asset::tileset.png", 16, 16)Print "impixiVersion = " +(Millisecs()-s)Print "impixiVersion = " +(Microsecs()-n)s = Millisecs()n = Microsecs()tileSetClass2 = New TileSet2("tileset.png", 32, 16, 16)Print "NewVersion = " +(Millisecs()-s)Print "NewVersion = " +(Microsecs()-n)EndMethod OnRender( canvas:Canvas ) Overridecanvas.TextureFilteringEnabled = FalseApp.RequestRender()canvas.DrawImage(tileSetClass.imgAtlas, 0, 0)canvas.DrawImage(tileSetClass.imgAtlasMask, tileSetClass.imgAtlas.Width, 0)Local drawTileIndex:Int = 29For Local y := 0 To 16 - 1For Local x := 0 To 16 - 1If drawTileIndex > - 1If tileSetClass2.tileSetMask[drawTileIndex, x, y] > 0canvas.Color = Color.Orangecanvas.DrawRect(x + 150 , y + 150, 1, 1)canvas.Color = Color.WhiteEndEndEndEndEndMethod OnMeasure:Vec2i() OverrideReturn SizeEndMethod AbakoboVersion()For Local i:Int = 0 Until tileSet.LengthLocal tmpCanvas := New Canvas(tileSet[i])Local px := tmpCanvas.CopyPixmap(tmpCanvas.Viewport)Local pixPtr:UInt Ptr 'to declare only once so i's not created each time in the loop (more usefull with structs (like Color) or classes or arrays intanciation...'RGBA8(per channel) is the default pixel format but can be different. 4*8=32bit long thus UIntFor Local y := 0 To px.Height - 1pixPtr=Cast<UInt Ptr>( px.PixelPtr( 0,y ) )For Local x := 0 To px.Width - 1If pixPtr[x]&$FF000000>0 'Bitwise opertor to check if there is some alpha (8 leftside bits of RGBA32(read ABGR! Endianess?) thus &$FF000000 to clear the BGR 24 bits. (is there a problem with the pixel format documentation? or is it reading small from big?)tileSetMask[i, x, y] = 1ElsetileSetMask[i, x, y] = 0EndEndEndNextEndMethod OriginalVersion()For Local i:Int = 0 Until tileSet.LengthLocal tmpCanvas := New Canvas(tileSet[i])Local px := tmpCanvas.CopyPixmap(tmpCanvas.Viewport)For Local y := 0 To px.Height - 1For Local x := 0 To px.Width - 1Local color:Color = px.GetPixel(x, y)If color.A > 0tileSetMask[i, x, y] = 1ElsetileSetMask[i, x, y] = 0EndEndEndNextEndEndClass TileSetPublicMethod New(url:String, tileWidth:Int, tileHeight:Int)Local pmAtlas := Pixmap.Load(url, PixelFormat.Unknown)If Not pmAtlas Then RuntimeError("Could not load spritesheet: " + url)Local tileCount := (pmAtlas.Width / tileWidth) * (pmAtlas.Height / tileHeight)Local pmAtlasMask := New Pixmap(pmAtlas.Width, pmAtlas.Height, PixelFormat.I8)Local pmAtlasDataPtr:UByte Ptr = pmAtlas.Data + Cast<UByte>(pmAtlas.Depth - 1)Local pmAtlasMaskDataPtr:UByte Ptr = pmAtlasMask.Data + Cast<UByte>(pmAtlasMask.Depth - 1)Local pidx:ULong = 0While pidx < (pmAtlas.Width * pmAtlas.Height)If pmAtlasDataPtr[0] > 0pmAtlasMaskDataPtr[0] = 255ElsepmAtlasMaskDataPtr[0] = 0EndifpmAtlasDataPtr += Cast<UByte>(pmAtlas.Depth)pmAtlasMaskDataPtr += Cast<UByte>(pmAtlasMask.Depth)pidx += 1WendimgAtlas = Image.Load(url)imgAtlasMask = New Image(pmAtlasMask)pmAtlas.Discard()EndField imgAtlas:ImageField imgAtlasMask:ImageEndClass TileSet2Field tileSetMask:Int[,,]Field tileSet:Image[]Method New(path:String, numFrames:Int, cellWidth:Int, cellHeight:Int, filter:Bool = True, preScale:Float = 1.0, padding:Int = 0, border:Int = 0, prefix:String = "asset::", format:PixelFormat = PixelFormat.Unknown)Local pixmap := Pixmap.Load(prefix + path, format )Assert( pixmap, " ~n ~nGameGraphics: Pixmap " + path + " not found.~n ~n" )tileSetMask = New Int[numFrames, cellWidth, cellHeight]Local imgs := New Image[ numFrames ]Local atlasImg := New Image( pixmap )Local paddedWidth := cellWidth + ( padding * 2 )Local paddedHeight := cellHeight + ( padding * 2 )Local columns:Int = ( atlasImg.Width - border - border ) / paddedWidthFor Local i := 0 Until numFramesLocal col := i Mod columnsLocal x := ( col * paddedWidth ) + padding + borderLocal y := ( ( i / columns ) * paddedHeight ) + padding + borderimgs[i] = New Image( atlasImg, New Recti( x , y, x + cellWidth, y + cellHeight ) )imgs[i].Scale = New Vec2f( preScale, preScale )For Local k := 0 To cellHeight - 1For Local j := 0 To cellWidth - 1Local color:Color = pixmap.GetPixel(x + j, y + k)'Print "i = " + i + " j = " + j + " k = " + kIf color.A > 0tileSetMask[i, j, k] = 1ElsetileSetMask[i, j, k] = 0EndEndEndNextatlasImg = NulltileSet = imgsEndEndFunction LoadSpriteSheet:Image[] (path:String, numFrames:Int, cellWidth:Int, cellHeight:Int, filter:Bool = True, preScale:Float = 1.0, padding:Int = 0, border:Int = 0, prefix:String = "asset::")Local atlasTexture := Texture.Load(prefix + path, Null )Assert( atlasTexture, " ~n ~nGameGraphics: Image " + path + " not found.~n ~n" )Local imgs := New Image[ numFrames ]Local atlasImg := New Image( atlasTexture )Local paddedWidth := cellWidth + ( padding * 2 )Local paddedHeight := cellHeight + ( padding * 2 )Local columns:Int = ( atlasImg.Width - border - border ) / paddedWidthFor Local i := 0 Until numFramesLocal col := i Mod columnsLocal x := ( col * paddedWidth ) + padding + borderLocal y := ( ( i / columns ) * paddedHeight ) + padding + borderimgs[i] = New Image( atlasImg, New Recti( x , y, x + cellWidth, y + cellHeight ) )imgs[i].Scale = New Vec2f( preScale, preScale )NextatlasImg = NullReturn imgsEndFunction Main()New AppInstanceNew MyWindowApp.Run()EndThanks guys! I’ll run some bench marking to see what is faster, I was considering of doing it “offline” too by creating a simple app which reads in the pixel data and spit it out to a JSON file.
Not sure why you’re creating a canvas and then copying the viewport pixmap of it.
To allow me to read the pixel data from an Image, do you know another way?
I thought AC stood for Android Code, but it looks like it stands for Application Control.
“AC Back” (the Back key (application control keypad))
https://wiki.libsdl.org/SDL_ScancodeAndKeycode
Thanks for fixing this.
Nope you put in the right place…
Damn, KeyHit calls KeyPressed which calls ScanCode… and ScanCode checks Key.Max
I tried an Extension and sub classing the KeyboardDevice class both failed due to it uses a lot of private variables so it complains. I think we need Mark to make a change to get it to work – sorry.
I’ll raise a GitHub ticket and point to this thread. Could you change title of this thread please (edit your first post) as its a Monkey2 issue than a Diddy2 issue
Raised: https://github.com/blitz-research/monkey2/issues/293
I’ve copied some of the monkey keyboard code and found the scan values for AC_BACK:
Monkey12345name = AC BackscanCode = 270keyCode = 1073742094So Amon could you please add this code your project:
Monkey1234567Method KeyCodeToKey:Key( keyCode:Int ) ' copied from keyboard.monkey2If (keyCode & $40000000) keyCode=(keyCode & ~$40000000)+$80' If keyCode<=0 Or keyCode>=Int( Key.Max ) Return Null ' removed as back key goes beyond Key.MaxReturn Cast<Key>( keyCode )EndThen when you want to hit the back key:
Monkey123456Local backKey:=KeyCodeToKey( 1073742094 )If Keyboard.KeyHit(backKey)Print "BACK!"EndI havent tested this so this may or may NOT work!
In the native keyinfo.cpp within Mojo, Mark has:
Monkey1"AC Back",SDL_SCANCODE_AC_BACK,SDLK_AC_BACK,KeyInfo is used in keyboard.monkey2:
Monkey12345678910Extern PrivateStruct bbKeyInfoField name:Void PtrField scanCode:IntField keyCode:IntEndGlobal bbKeyInfos:bbKeyInfo Ptr…
Monkey123456789101112131415161718192021222324252627282930Class KeyboardDevice...Method Init()Local p:=bbKeyInfosWhile p->nameLocal name:=String.FromCString( p->name )Local scanCode:=p->scanCodeLocal keyCode:=p->keyCodeLocal key:=KeyCodeToKey( keyCode )_names[key]=name_raw2scan[key]=scanCode_scan2raw[scanCode]=key | Key.Raw#If __TARGET__="emscripten"_key2scan[key]=scanCode#Else_key2scan[key]=SDL_GetScancodeFromKey( Cast<SDL_Keycode>( keyCode ) )#Endif_scan2key[_key2scan[key]]=keyp=p+1WendEndIn SDL_keycode.h
Monkey123456enum{...SDLK_AC_BACK = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_BACK),And SDL_keyboard.c
Monkey12345static const SDL_Keycode SDL_default_keymap[SDL_NUM_SCANCODES] = {...SDLK_AC_BACKSo we may be able to use it somehow…
No idea sorry! Havent actually done any Android development in Monkey2 yet…
I’ll investigate, unless you or anyone else knows!
Edit: Quick Google in pure SDL2 C++:
Monkey12if (event.type == SDL_KEYDOWN)if (event.key.keysym.sym == SDLK_AC_BACK )Cool!
I dont know if its in MX2 yet, but for Windows we need a way to save to the “correct” Microsoft approved folder locations.
Cool! MIT is fine with me
Very nice! Also didnt know that Monkey2 could play videos! Thanks!
Ah thanks Jesse! Yeah that makes sense!
@pixelpaladin – did you see my post just before yours?
@pixelpaladin – I cant get your code to work. When I try to compile I get:
Monkey12Error : Can't find overload for 'new:Void(monkey.types.String,monkey.types.String,monkey.types.String)' with argument types (monkey.types.String,monkey.types.String)So I changed this line:
Monkey1crtShader = New Shader("crtshader", CRT_ShaderCode)to
Monkey1crtShader = New Shader("crtshader", CRT_ShaderCode, "")So it now compiles but crashes at runtime:
Monkey1Attempt to invoke method on null instanceFull code:
Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121Namespace crt#Import "<std>"#Import "<mojo>"#import "assets/tvscreen.png"Using std..Using mojo..Class GraphicsCRTField crtCanvas:CanvasField crtImage:ImageField crtShader:ShaderField resolution:Vec2iGlobal Instance:GraphicsCRT = NullField overlayImg:ImageMethod New(width:UInt = 320, height:UInt = 240, rgbSplitIntensity:Float = 0.5, scanlineIntensity:Float = 0.1)If Instance <> Null Then RuntimeError("only one crt graphics instance is allowed")Instance = SelfIf width < 128 Then width = 128If width > 800 Then width = 800If height < 64 Then height = 64If height > 600 Then height = 600If rgbSplitIntensity < 0.0 Then rgbSplitIntensity = 0.0If rgbSplitIntensity > 1.0 Then rgbSplitIntensity = 1.0resolution = New Vec2i(width, height)Local CRT_ShaderCode:String'CRT_ShaderCode = LoadString("asset::crt.txt")CRT_ShaderCode = "~n//@renderpasses 0,1,2~n~nvarying vec2 texCoord0;~nvarying vec4 color;~n~n//@vertex~n~nattribute vec4 mx2_Vertex;~nattribute vec2 mx2_TexCoord0;~nattribute vec4 mx2_Color;~n~nuniform mat4 mx2_ModelViewProjectionMatrix;~n~nuniform vec4 mx2_ImageColor;~n~nvoid main(){~n~n~ttexCoord0=mx2_TexCoord0;~n~n~tcolor=mx2_ImageColor * mx2_Color;~n~t~n~tgl_Position=mx2_ModelViewProjectionMatrix * mx2_Vertex;~n}~n~n//@fragment~n~nuniform sampler2D mx2_ImageTexture0;~n~nvoid main(){~n~n#if MX2_RENDERPASS==0~n~tvec2 texcoords = texCoord0;~n~tfloat bl = %BORDER_LEVEL%*0.1;~n~tfloat x = texcoords.x*(1.0+bl)-bl/2.0;~n~tfloat y = texcoords.y*(1.0+bl)-bl/2.0;~n~tfloat x2 = (x-0.5)*(1.0+ 0.5*%EFFECT_LEVEL% *((y-0.5)*(y-0.5)))+0.5;~n~tfloat y2 = (y-0.5)*(1.0+ 0.25*%EFFECT_LEVEL% *((x-0.5)*(x-0.5)))+0.5;~n~tvec2 v2 = vec2(x2, y2);~n~tvec4 temp = texture2D(mx2_ImageTexture0, v2);~n~tif (v2.x<0.0 || v2.x>1.0 || v2.y<0.0 || v2.y>1.0) {~n~t~ttemp = vec4(0.0,0.0,0.0,1.0);~n~t}else{~n~t~tfloat cr = sin((x2*%WIDTH%) *2.0*3.1415) * 0.5+0.5+0.1; //if(cr < 0.0) cr = 0.0;~n~t~tfloat cg = sin((x2*%WIDTH%-1.0*2.0*3.1415)*2.0*3.1415) * 0.5+0.5+0.1; //if(cg < 0.0) cg = 0.0;~n~t~tfloat cb = sin((x2*%WIDTH%-2.0*2.0*3.1415)*2.0*3.1415) * 0.5+0.5+0.1; //if(cg < 0.0) cg = 0.0;~n~t~ttemp = mix(temp*vec4(cr,cg,cb,1.0),temp,1.0-%RGB_SPLIT_INTENSITY%);~n~t~tif (%HEIGHT% <= 320.0) {~n~t~t~tfloat ck = sin((y2*%HEIGHT%) *2.0*3.1415) * 0.5+0.5+0.1;~n~t~t~ttemp = temp*(1.0-%SCANLINE_INTENSITY%) + temp*ck*%SCANLINE_INTENSITY%;~n~t~t}~n~t}~n~tgl_FragColor = (temp * color)*0.875+0.125;~n#else~n~tfloat alpha=texture2D( mx2_ImageTexture0,texCoord0 ).a * color.a;~n~tgl_FragColor=vec4( 0.0,0.0,0.0,alpha );~n#endif~n}~n"CRT_ShaderCode = CRT_ShaderCode.Replace("%WIDTH%", String(Int(resolution.x)+".0"))CRT_ShaderCode = CRT_ShaderCode.Replace("%HEIGHT%", String(Int(resolution.y)+".0"))CRT_ShaderCode = CRT_ShaderCode.Replace("%EFFECT_LEVEL%", "0.3")'0.5CRT_ShaderCode = CRT_ShaderCode.Replace("%BORDER_LEVEL%", "0.3")Local sint:String = scanlineIntensityIf Not sint.Contains(".") Then sint += ".0"CRT_ShaderCode = CRT_ShaderCode.Replace("%SCANLINE_INTENSITY%", sint)Local si:String = rgbSplitIntensityIf Not si.Contains(".") Then si += ".0"CRT_ShaderCode = CRT_ShaderCode.Replace("%RGB_SPLIT_INTENSITY%", si)crtShader = New Shader("crtshader", CRT_ShaderCode, "")crtImage = New Image(resolution.x, resolution.y, TextureFlags.Dynamic, crtShader)crtCanvas = New Canvas(crtImage)overlayImg = Image.Load("asset::tvscreen.png")EndProperty Canvas:Canvas()Return crtCanvasEndProperty Resolution:Vec2i()Return resolutionEndMethod DrawScreen:Void(targetCanvas:Canvas, x:Float, y:Float, width:Float, height:Float)crtCanvas.Flush()If targetCanvas = Null Then ReturntargetCanvas.DrawRect(x, y, width, height, crtImage)Local tempColor := targetCanvas.ColortargetCanvas.Color = Color.WhitetargetCanvas.DrawRect(x, y, width, height, overlayImg)targetCanvas.Color = tempColorEndEndClass AppWindow Extends WindowField crt:GraphicsCRTField testImage:ImageMethod New(title:String, width:Int, height:Int)'Call super class constructor - this just passes the arguments 'up' to the Window class constructor.Super.New(title, width, height, WindowFlags.Resizable)' initialize crt screen (width, heightn, rgb-split-intensity)crt = New GraphicsCRT(320, 240, 0.75)Layout = "resize"ClearColor = New Color(0.0, 0.2, 0.4)Style.BackgroundColor = Color.BlackSwapInterval = 1EndMethod OnRender(canvas:Canvas) OverrideIf Keyboard.KeyReleased(Key.Escape) Then App.Terminate()App.RequestRender()' get crt canvas:Local crtCanvas:Canvas = crt.Canvas' render some stuff on crt screen:crtCanvas.Clear(Color.Black)crtCanvas.BlendMode = BlendMode.AlphacrtCanvas.Color = Color.WhitecrtCanvas.DrawText("Move Mouse", 5, 5)crtCanvas.BlendMode = BlendMode.AdditivecrtCanvas.Color = New Color(Float(Mouse.X)/Width, Float(Mouse.Y)/Height, 0.0)crtCanvas.DrawCircle(Float(Width-Mouse.X)*Float(crt.Resolution.x)/Width, Float(Height-Mouse.Y)*Float(crt.Resolution.y)/Height, 50)crtCanvas.Color = New Color(1.0-Float(Mouse.X)/Width, 1.0-Float(Mouse.Y)/Height, 1.0)crtCanvas.DrawCircle(Mouse.X*crt.Resolution.x/Width, Mouse.Y*crt.Resolution.y/Height, 50)' draw crt screen on canvas:crt.DrawScreen(canvas, 0, 0, Width, Height)EndEndFunction Main()New AppInstanceNew AppWindow("Test Application", App.DesktopSize.x/2 ,App.DesktopSize.y/2)App.Run()End -
AuthorPosts