Setcolor inner workings?
BlitzMax Forums/BlitzMax Programming/Setcolor inner workings?
| ||
How do you draw images using original colors after you've used SETCOLOR? Iīm sure I have done this before but I guess I forgot everything. Itīs really odd. How DO you do it? And whatīs the payload of changing ALPHA BLEND and COLOR alot? |
| ||
1) you have to setcolor to 255,255,255 to reset it. 2) State changes like that can cause fairly substantial impact, they may not seem like much but they can really make the gfx card jump through hoops. A lot of people use batched draws-- change states, draw everything that needs that state, then change states again, draw everything that needs THAT state, etc. Most likely though you won't notice the impact unless you have thousands of sprites all in different colors. If you have particles that are lots of different colors, instead of allowing them to blend smoothly between colors, have them blend over 10 or 20 allowable colors. This can get your state changes down from many thousands to 20. There you probably would see a sizable impact depending on how many particles you have. |
| ||
Thanks !! Iīm keen to get a feeling of what commands are slow and what are more zippy and works best on on most machines. My original plan to find out commands that had an impact was use a old development machines (2010-2012) just to have a good chance catching these kind of potential slowdowns but they seem really dirtcheap on them. On these machines I Got 10K objects floating around using SETCOLOR SETALPHA SETROTATION without slowdowns (none worth mentioning anyways) when adding them. I guess the plan to use old machines to be safe didnīt work out too well. |
| ||
I was apparently wrong, it's negligible.Graphics 640,480 Global timer% timer = MilliSecs() For i = 1 To 1000000 SetColor Rand(255),Rand(255),Rand(255) Next Print "Setcolor time:" + String(MilliSecs()-timer) timer = MilliSecs() For i = 1 To 1000000 SetAlpha Rand(255) Next Print "Setalpha time:" + String(MilliSecs()-timer) |
| ||
The RANDOM is likely what's killing you, Endive. Try it without:Graphics 640,480 Global timer% timer = MilliSecs() For i = 1 To 1000000 SetColor i,i,i Next Print "Setcolor time:" + String(MilliSecs()-timer) timer = MilliSecs() For i = 1 To 1000000 SetAlpha i Next Print "Setalpha time:" + String(MilliSecs()-timer) Big difference, you will see that they are almost evenly matched. I suspect RAND() being called 3 times is where the longer process is taking place. |
| ||
Wow, I did NOT know that rand() was processor intensive that way, though it's still sort of negligible. I get 30 milliseconds on 1 million rand calls. Here's a modded lookup table version that's 3 times faster and another that is a hardcoded lookup table that takes ~1ms. Global randarray[1000000] Global timer% Print "Rand() Function:" timer = MilliSecs() For i = 1 To 1000000 a=Rand(255) Next Print String(MilliSecs() - timer) For i = 0 To 999999 randarray[i]=Rand(10000000) Next Print "Rand() Function With Lookup:" timer = MilliSecs() For i = 0 To 999999 a=randfunc(i,255) Next Print String(MilliSecs()-timer) Function randfunc(i, in#) Return randarray[i] Mod in End Function For i = 0 To 999999 randarray[i]=Rand(255) Next Print "Fastest of All: Pre-generated random numbers" timer = MilliSecs() For i = 0 To 999999 a=randarray[i] Next Print String(MilliSecs()-timer) Obviously a hardcoded rand() table has limitations associated with it but there are ways to get around them. I would think for particle systems it would be worth doing. |
| ||
Check the fast rand from this post: http://www.blitzbasic.com/Community/post.php?topic=69277&post=775359 |
| ||
What do you think of table lookups? I still say 30ms for a million calls is negligible but zero is better. What if you gathered random noise from the mouse and used that to constantly repopulate the lookup table? |
| ||
You know that is really genius what you did there. :) I've always benchmarked computers by doing the random colored pixels technique. I never considered that computers today have SO much storage that you could easily 'build' an array of random values for it well ahead of time and then plug them in for your super fast graphics when ready. Further interesting that you can CODE in C in BlitzMAX. First time I've seen this - yep it's a brand new day for me. :) This benchmark however seems to run the same speed with the same results using the FASTRAND method. Strict Local i,j,typ Graphics 640,480 crndseed(MilliSecs()) Typ=1 ' 0=default RAND ' 1=new FASTRAND Repeat For j=0 To 639 For i=0 To 479 If typ SetColor fastrand(0,255),fastrand(0,255),fastrand(0,255) Else SetColor Rand(0,255),Rand(0,255),Rand(0,255) EndIf Plot j,i Next Next Flip Until KeyDown(32) End Extern "C" Function crndseed:Int(val:Int) = "srand" Function _crand:Int () = "rand" End Extern Function FastRand:Int (start:Int, ende:Int) Return _crand() Mod (ende-start+1) + start EndFunction ... running this WITHOUT debug, however, I can see that FastRand is a sneak bit faster than standard Rand. It's strange ... you would think BlitzMAX would be using FASTRAND for their default as the screens which appear on both appear to be identically and equally scrambled. I'll use FastRand from now on for final production. Thanks therevills and Ziggy ! Here's a challenge. Is there a fastpixel routine ? I know you can LOCK pixels with a TPIXMAP and plot but WHAT IF you could bypass all that and just plot as-fast-as-possible to the current screen using a C or machine-language routine ? |
| ||
You know that is really genius what you did there. :) Oh yeah, I'm really Donald Knuth over here. I've always benchmarked computers by doing the random colored pixels technique. I never considered that computers today have SO much storage that you could easily 'build' an array of random values for it well ahead of time and then plug them in for your super fast graphics when ready. Lookup tables have always been amazing and today they are more useful than ever. You can also build memoizing objects that wrap a function and every time they calculate a value, they store that value in a lookup table. That could be useful for such things as procedural world generation. When you come to an area of the map that has not been generated, the memoizer generates an area around it, probably by the quad partitioning plasma method, and stores it in the lookup table. I've always benchmarked computers by doing the random colored pixels technique. I'm skeptical as to whether that is a good general benchmark, though I suppose it measures fill rate and a few other things. You might learn how to code Mersenne Twister and use that for your RNG-- that way you know you are not using some bizarro version of Rand(). Mersenne twister will also work for your string hashing question in the other thread. |
| ||
Procedural World Generation ... Quad Partitioning Plasma ... Mersenne Twister ... ![]() You went right over my head, Endive ... :) |
| ||
Better look 'em up, you'll learn a lot. All three are really easy to code and the first two would most likely be very useful for your current RPG program. If you have any questions, ask me. |
| ||
Any BlitzMAX examples for all 3 ? That would help most of all. I could decipher what's going on in there and better understand it, Endive. And ... it's not a RPG I'm making but a RPG Maker. Wow, if it was just a RPG game I would've been done years ago. I wish it was that simple. It's much more complex than that. The TMAP type variable makes this possible now. |
| ||
https://en.wikipedia.org/wiki/Diamond-square_algorithm http://pcg.wikidot.com/ https://en.wikipedia.org/wiki/Mersenne_Twister I'm convinced that you will be able to implement the first two very easily. Procedural terrain generation will be great for an RPG maker. |
| ||
I did go ahead and code up a quickie procedural terrain generator for you just so you can see how it works. You would want to define specific growth behaviors for each type of terrain to make it more realistic-- deserts can't spread through water, trees can't spread onto desert, etc.Global terrain[64,48] Graphics 640,480 ' Set up a bunch of seeds of terrains in random places. ' Terrains will expand outward from these seeds. For i = 1 To 20 terrain[Rand(61)+1, Rand(45)+1]=1 terrain[Rand(61)+1, Rand(45)+1]=2 terrain[Rand(61)+1, Rand(45)+1]=3 terrain[Rand(61)+1, Rand(45)+1]=4 Next While Not KeyDown(KEY_ESCAPE) ' Choose a random square to expand from... x = Rand(62) y = Rand(46) ' ... but only if it's not empty If terrain(x,y) > 0 newterr = terrain(x,y) ' ok, if it's not empty, what does it contain? ' newterr is the type of terrain we are going to expand outward dir = Rand(4) Select dir ' we choose a direction up right down left ' then nx and ny are assigned to a neighbor of our random square Case 1 nx = x; ny = y-1 terrain[nx, ny]=newterr Case 2 nx = x+1; ny = y terrain[nx, y]=newterr Case 3 nx = x; ny = y+1 terrain[nx, ny]=newterr Case 4 nx = x-1; ny = y terrain[nx, ny]=newterr End Select Select newterr ' set the appropriate color Case 1 SetColor 0,255,0 Case 2 SetColor 0,0,255 Case 3 SetColor 165,42,42 Case 4 SetColor 255,235,205 End Select DrawRect(nx*10,ny*10,9,9) ' we do this so we aren't flipping every frame If numupdates < 100 numupdates = numupdates+1 Else Flip numupdates = 0 EndIf EndIf Wend |
| ||
Ohh ! This is PLAGUE ! :) MY Dad wrote a program just like this years ago in Turbo Pascal. Me ? I wrote one in GFA very similar where I used 4-icons. (0)=None, 1=Bunny, 2=Fox, 3=Grass. Where the bunnies ate the grass, the foxes ate the bunnies, the blank ate the foxes, and the grass ate the blank. It was a perfect bit of motion very similar to what you have here. I - can't think of any reason why I would need this in my engine though. My engine will be tile-based, maps will be 50x50 in size. No - what would REALLY be helpful is to find source code that generates the following kind of random map. ![]() It's trickier to build than it looks. |
| ||
I - can't think of any reason why I would need this in my engine though. Do you want dynamically generated worlds that are different every time? It's trickier to build than it looks. Actually no, for that type of map you divide the dungeon into N squares, put a room somewhere near the center of each square, then connect each room to its neighbors. http://www.roguebasin.com/index.php?title=Dungeon-Building_Algorithm |
| ||
BTW, here is a plasma program I wrote. It doesn't entirely match the normal type but it is a type of plasma, a flower-type is the best way to describe it. I used this method years ago as a type of 'paint' technique.' Fuzzy Plasma Generator by David W (dw817) 12-29-15 Strict SeedRnd MilliSecs() Local i,j,k,l,c,c2,r,x,y,z,pic:TPixmap Graphics 640,480 pic=GrabPixmap(0,0,640,480) ClearPixels(pic) For i=0 To 479-95 Step 96 For j=0 To 639-95 Step 96 WritePixel pic,j+Rand(0,95),i+Rand(0,95),1 Next Next Repeat For z=0 To 9999 x=Rand(1,638) y=Rand(1,478) c=ReadPixel(pic,x,y)Mod 256 If c=255 Then c=254 If c c2=c+1+(c*256+256)+(c*65536+65536) For i=-1 To 1 For j=-1 To 1 If ReadPixel(pic,x+j,y+i)=0 WritePixel pic,x+j,y+i,c2 EndIf Next Next EndIf Next DrawPixmap pic,0,0 Flip Until KeyDown(32) |
| ||
Perty. They call that an aggregate fractal. https://en.wikipedia.org/wiki/Diffusion-limited_aggregation |
| ||
Has someone written code for diamond fractal ? (As Wikipedia shows it) Answering your previous: Do you want dynamically generated worlds that are different every time? It's an interesting idea, one I played with years ago. I even went as far as making a weird name generator and had critters based on descriptions rather than names. Winged, Crawling, Creeping, Flying, Slithering, Sliding, Oozing, Horned Horror, Fury, Beast So you could randomly have attack you a, "Horned Fury." Name generation was done via vowels, "AEIOU" and consonants were, "BDFGHJKLMNPRSTVWY" and no repeats, so a CVCCVC would be: "Geprin" "Fasdor" "Tudjoy" I also used random vector generation to build images of these creatures. I developed completely random items with names VCCV CVCCVC and VCVVC. But - that's not the way this is going to go. No, S2 years ago was just a nice and very workable RPG Maker. It was well received. Today will be S3. Just a few simple WIZARDS to help with maps. The map above would be a possible WIZARD generated map. I already have the code to build a maze (posted in this forum). It's the catacomb technique I haven't written. |
| ||
Look into Markov chains :) I havery, "Horror, Fury, Beady hell be: Wing iding a post as based ve wou cription went and hell be ago. It's not therittenere, "Horned I ple WIZARD gen't wayed, Fury, Fury writtacomly haven. Justing to basdor" "Fasdorneratherat's alreats was descreats with maps. I an weird hat's just abovectorkable comb to build ing, Hor gent ther thaven't a vowell randoned in" "Tudjoy" It wou created, Crawling, Crawlither. I alsonants far this generated, Flying, Horned ration way han to gen. I already th map as weres. But was VCCVCCV CVVC witems forum). It's the con worror, Fury, Bears build an tor and Fury." "Gepeady have map. I as with maze catacodea, on wents no reping, Hor an name gent thand not a few simpleted ve thaved. "Gepring, "AEIOU" andonerating this is geners ages. "Gepring, S3. Just writems is ideven the RPG Maker. It's with yould rants witted VCCVCCVCCVC would not thes. "Gepring, Sling, Flying, Fury." The this in name go. It's far this genery will be: Wing is ago. I posten. few so heriptionsone (posted Fury, Slith maze (post Horned, "BDFGHJKLMNPRSTVWY" "Tudjoy" But - the (postely have I alreepea, Slittems worum). I hell be a map also a voweird rations ago buill re, one atacomlyingene via very would not writhe con don des. |
| ||
![]() W h a t ? |