cbSimpleTexture - Kuvan ja Objektin risteytys

Oletko tehnyt jotain, mistä muut voisivat hyötyä. Postita vinkit tänne.
Post Reply
SPuntte
Tech Developer
Tech Developer
Posts: 650
Joined: Mon Aug 27, 2007 9:51 pm
Location: Helsinki, Finland
Contact:

cbSimpleTexture - Kuvan ja Objektin risteytys

Post by SPuntte »

Julkaisen jälleen esimerkkikoodin, jonka kirjoitin alunperin fysiikkamoottoriprojektiani varten. Jospa näistä vielä vaikka kasautuisi kunnollinen peliengine :geek:

Tällä kertaa aiheena on grafiikka. CB:ssä on valmis kuvamoottori ja objektimoottori, mutta kumpikaan ei oikein soveltunut omiin tarkoituksiini. Tarvitsin pyöritettävää grafiikkaa, jota objektit tarjoaisivat, mutta niitä täytyisi kloonata, mikäli sama kuva toistuisi monta kertaa. Lisäksi niiden piilottaminen edellyttäisi ShowObjektin kanssa kikkailua. Kuvat olisivat oikea ratkaisu, mikäli Blitzin softablitteri ei olisi liian tehoton pyörittelemään kuvia reaaliaikaisesti.

Kirjoitin yksinkertaisen tyyppi-muistipala -yhdistelmää käyttävän systeemin, jossa kuvat pyöritellään latauksen yhteydessä kuten objektit, mutta niitä voi silti piirrellä aivan kuten tavallisia kuvia.

Harkitsin myös kuvan skaalauksen sisällyttämistä, mutta ainakin toistaiseksi benchmarkkini näyttävät sille punaista valoa, mikäli käyttäjä ei halua odotella pelin latausta minuuttitolkulla. Toki esimerkiksi peleissä, jossa objektit pyörivät 45 asteen askelein, latausaika tuskin olisi ongelma. Lisään (tai joku muukin saa toki koodiani modailla) sen jälkikäteen, mikäli tarvetta ilmenee.

Esimerkkeineen päivineen:

Code: Select all

//==========================================================================================
//KIRJASTO
Type TEXTURE
	Field iD%			//Tekstuurin kahva
	Field numRotations%	//Eri asentojen määrä
	Field interval#		//Vierekkäisten asentojen väli (=360 / numRotations)
	Field texMem%		//Kahva muistipalalle, johon säilötään pöritettyjen kuvien kahvat
EndType

//LoadTexture%(path$, n%, mR%=0, mG%=0, mB%=0)
//	Lataa tekstuurin piirtovalmiiksi muistiin
//path$		- kuvan sijainti levyllä
//n%		- pyörityslaatu
//m{R,G,B}%	- maskivärin RGB-komponentit
Function LoadTexture%(path$, n%, mR%=0, mG%=0, mB%=0)
	Dim t.TEXTURE
	
	t = New(TEXTURE)
	
	t\iD = ConvertToInteger(t)
	t\numRotations = n
	t\interval = 360.0/n
	t\texMem = MakeMEMBlock(4*n)
	
	Dim masterImg, tmpImg
	If mR + mG + mB <> 0 Then
		tmpImg = LoadImage(path$)
		MaskImage tmpImg, mR, mG, mB
		masterImg = MakeImage(ImageWidth(tmpImg), ImageHeight(tmpImg))
		DrawToImage masterImg
			DrawImage tmpImg, 0, 0
		DrawToScreen
		HotSpot masterImg
		DeleteImage tmpImg
	Else
		masterImg = LoadImage(path$)
	EndIf
	
	If Not masterImg Then MakeError "Unable To load Image from '"+path+"'"
	HotSpot masterImg
	PokeInt t\texMem, 0, masterImg
	
	Dim i As Integer
	For i = 1 To n - 1
		tmpImg = CloneImage(masterImg)
		RotateImage tmpImg, -t\interval * i
		PokeInt t\texMem, 4*i, tmpImg
	Next i
	
	Return t\iD
EndFunction

//DrawTexture(tex%, tx#, ty#, angle#, muteError% = 1)
//	Piirtää yksittäisen tekstuurin
//tex%		- tekstuurin kahva LoadTexture()-funktiolta
//t{x,y}#	- piirtokoordinaatit (ikkunakoordinaatistossa)
//angle#	- asento asteina
//muteError	- jos = True, jätetään piirtämättä eikä anneta virheilmoitusta, jos tekstuuri on tyhjä
Function DrawTexture(tex%, tx#, ty#, angle#, muteError% = 1)
	
	Dim t.TEXTURE
	t = ConvertToType(tex%)
	If (Not t\texMem) Or (Not t\iD) Or t = NULL Then
		If Not muteError Then MakeError "Invalid texture handle!"
		Return False
	EndIf
	
	Dim index% As Integer
	index = Int(WrapAngle(angle)/t\interval)
	DrawImage PeekInt(t\texMem, 4*(index*(index<t\numRotations))), tx, ty
	Return True
EndFunction

//DrawTextureList(list%, muteError% = 1)
//	Piirtää listan(muistipala) tekstuureita yhdellä funktiokutsulla
//list%		- tekstuurilistamuistipalan kahva
//muteError	- jos = True, jätetään piirtämättä eikä anneta virheilmoitusta, jos lista on epäkelpo tai tekstuuri on tyhjä
Function DrawTextureList(list%, muteError% = 1)
	Dim listSize% As Integer
	listSize = MEMBlockSize(list)
	If listSize Mod 16 <> 0 Then
		If Not muteError Then MakeError "Invalid texture list!"
		Return False
	EndIf
	
	Dim ret
	ret = True
	Dim i% As Integer
	For i = 0 To (listSize / 16) - 1
		Dim t.TEXTURE
		t = ConvertToType(PeekInt(list, 16*i))
		If (Not t\texMem) Or (Not t\iD) Or t = NULL Then
			If Not muteError Then MakeError "Invalid texture handle!"
			ret = False
		Else
			Dim index% As Integer
			index = Int(WrapAngle(PeekFloat(list, 16*i+12))/t\interval)
			DrawImage PeekInt(t\texMem, 4*(index*(index<t\numRotations))), PeekFloat(list, 16*i+4), PeekFloat(list, 16*i+8)
		EndIf
	Next i
	
	Return ret
EndFunction

//Function ClearTexture(tex%)
//	Tyhjentää tekstuurin vaatiman muistin lukuunottamatta tyyppi-instanssia
//	Tyhjän tekstuurin piirtäminen ei kaada ohjelmaa, jos muteError = True
//tex%	- tekstuurin kahva
Function ClearTexture(tex%)
	Dim t.TEXTURE
	t = ConvertToType(tex%)
	
	If Not t\texMem Then MakeError "Texture already cleared!"
	
	Dim i
	For i = 0 To t\numRotations - 1
		DeleteImage PeekInt(t\texMem, 4*i)
	Next i
	
	DeleteMEMBlock(t\texMem)
	t\texMem = 0
EndFunction

//Function DeleteTexture(tex%)
//	Poistaa tekstuurin kokonaan
//	Poistetun tekstuurin piirtäminen tuottaa toinen toistaan mielenkiintoisempia virheilmoituksia...
//tex%	- tekstuurin kahva
Function DeleteTexture(tex%)
	If tex <= 0 Then MakeError "Invalid texture handle!"
	Dim t.TEXTURE
	t = ConvertToType(tex%)
	If t = NULL Then MakeError "Invalid texture handle!"
	
	If t\texMem Then ClearTexture(t\iD)
	
	Delete t
EndFunction

//==========================================================================================
//ESIMERKKI

Const SCRW = 640
Const SCRH = 480
SCREEN SCRW, SCRH,  0, 1
Smooth2D ON

Const COWS = 1000	//LEHMIEN MÄÄRÄ
Dim cow(COWS-1, 5) As Float

//Luodaan satunnaisia lehmiä
Dim i
For i = 0 To COWS-1
	cow(i, 0) = Rnd(SCRW)	//Paikka
	cow(i, 1) = Rnd(SCRH)
	cow(i, 2) = Rnd(-4,4)	//Nopeus
	cow(i, 3) = Rnd(-4,4)
	cow(i, 4) = Rnd(360)	//Asento
	cow(i, 5) = Rnd(-5,5)	//Kulmanopeus
Next i

Dim cowTexture% As Integer	//Ladataan YKSI tekstuuri. Ei kloonausta tai muuta säätöä.
cowTexture = LoadTexture("Media/cow.bmp", 720)

Dim cowList% As Integer		//Tehdään tekstuureille lista (vrt. OpenGL:n display list), jotta piirtäminen ON nopeampaa
cowList = MakeMEMBlock(16*COWS)

SAFEEXIT OFF
While Not EscapeKey()
    For i = 0 To COWS-1
		cow(i, 0) = cow(i, 0) + cow(i, 2)
		cow(i, 1) = cow(i, 1) + cow(i, 3)
		cow(i, 4) = cow(i, 4) + cow(i, 5)
		
		//Siirretään ruudun ulkopuoliset lehmät toiseen laitaan
		If cow(i, 0) > SCRW Then cow(i, 0) = cow(i, 0) - SCRW
		If cow(i, 0) < 0 Then cow(i, 0) = cow(i, 0) + SCRW
		If cow(i, 1) > SCRH Then cow(i, 1) = cow(i, 1) - SCRH
		If cow(i, 1) < 0 Then cow(i, 1) = cow(i, 1) + SCRH
		
		//Tekstuurin tiedot syötetään järjestyksessä: kahva, koordinaatit (x, y), kulma
		PokeInt cowList, 16*i, cowTexture
		PokeFloat cowList, 16*i+4, cow(i, 0)
		PokeFloat cowList, 16*i+8, cow(i, 1)
		PokeFloat cowList, 16*i+12, cow(i, 4)
		
		Dim result% As Integer
		//result = DrawTexture(cowTexture, cow(i, 0), cow(i, 1), cow(i, 4))
	Next i
	
	//Vertaa suorituskykyä kommentoimalla tätä seuraava rivi sekä poistamalla rivin 187 kommentointi.
	result = DrawTextureList(cowList)
	
	If result = False Then Text 5, 50, "DrawTexture failed!"
	
	If KeyHit(cbKeySpace) Then ClearTexture(cowTexture)
	If KeyHit(cbKeyD) Then DeleteTexture(cowTexture)

    DrawScreen
	SetWindow "FPS: " + FPS() + "   Cows: " + COWS
Wend

DeleteMEMBlock(cowList)
Deletetexture(cowTexture)
End
EDIT:

21.3.2010:
DrawTextureList()-funktio lisätty. Kiitos ja kumarrus ideasta otto90x:n suuntaan.
Funktion käyttö ilmenee esimerkistä. Yksi tekstuuri kerraallaan -piirto on edelleen käytettävissä. Kokeilkaa nopeuseroa.

Tekstuurilistan käyttö vähentää dramaattisesti funktiokutsuja, mikä vaikuttaa vastaavalla tavalla suorituskykyyn. Itelläni ruudunpäivitystaajuus parhaimmillaan tuplaantui 15 -> 30 FPS. Alustana siis Asus EeePc 901 + Win XP ja lehmien määrä 1000.

Last edited by SPuntte on Mon Mar 22, 2010 9:38 am, edited 3 times in total.
CoolBasic henkilökuntaa
Tech-kehittäjä
CoolBasic Classic, Cool VES

CoolPhysicsEngine | MissileSystem | Jana-ympyrä -törmäys | cbSimpleTexture | CoolCPLX
MaGetzUb
Guru
Posts: 1715
Joined: Sun Sep 09, 2007 12:35 pm
Location: Alavus

Re: cbSimpleTexture - Kuvan ja Objektin risteytys

Post by MaGetzUb »

Koodisi pyörii ihan sutjakkaasti ~ 40FPS
Itse olen joskus viimme kesän vaihteessa koodannut samanlaista systeemiä (ero toimintatapaan on 2 tyyppikenttää). :)

Code: Select all

Type Sprite
    Field Sprite_MaxAngles
EndType 

Type SpriteTex
    Field Sprite_Img
    Field Sprite_Angle
    Field Sprite_Pointer
EndType 


sprite = LoadSprite("Media\guy.BMP",72)

Repeat 
     a=a + 1
     DrawSprite(sprite,200,150,a)
     DrawScreen
Forever 

Function LoadSprite(f$,angles)
    imgp = LoadImage(f$)
    Sprt.Sprite = New(Sprite)
    Sprt\Sprite_MaxAngles = angles
    SprtID = ConvertToInteger(Sprt)
    For i = 0 To angles
        SprtX.SpriteTex = New(SpriteTex)
        SprtX\Sprite_Img = CloneImage(imgp)
        RotateImage tmp, - i * (360 / angles)
        SprtX\Sprite_Angle = i
        SprtX\Sprite_Pointer = SprtID
    Next i
    DeleteImage imgp
    Return SprtID
EndFunction 

Function MakeSprite(imgp,angles)
    Sprt.Sprite = New(Sprite)
    Sprt\Sprite_MaxAngles = angles
    SprtID = ConvertToInteger(Sprt)
    For i = 0 To angles
        SprtX.SpriteTex = New(SpriteTex)
        SprtX\Sprite_Img = CloneImage(imgp)
        RotateImage tmp, - i * (360 / angles)
        SprtX\Sprite_Angle = i
        SprtX\Sprite_Pointer = SprtID
    Next i
    Return SprtID
EndFunction 

Function DrawSprite(id,x,y,angle)
    angle = WrapAngle(angle)
    angle = Int(angle)
    Sprt.Sprite = ConvertToType(id)
    For SprtX.SpriteTex = Each SpriteTex
        If SprtX\Sprite_Pointer = id Then 
            angle = Sprt\Sprite_MaxAngles / 360 * angle
            If SprtX\Sprite_Angle = angle Then 
                DrawImage SprtX\Sprite_Img,x,y
            EndIf 
        EndIf 
    Next SprtX
EndFunction 
Solar Eclipse
Meneillä olevat Projektit:
We're in a simulation, and God is trying to debug us.
koodaaja
Moderator
Moderator
Posts: 1583
Joined: Mon Aug 27, 2007 11:24 pm
Location: Otaniemi - Mikkeli -pendelöinti

Re: cbSimpleTexture - Kuvan ja Objektin risteytys

Post by koodaaja »

Hieno systeemi! Tällaista olen joskus kaivannutkin ja kirjoittanut sitten jonkun pienen purkkaviritelmän, hyvä että on nyt kunnon funktiot pyöriville kuville.

Fps tuntuu menevän 800 lehmän pätkissä, 0-800 on n. 60fps, 800-1600 n. 30fps, 1600-2400 n. 20fps, 2400-3200 n. 15fps ja 3200-4000 kympin pinnassa. Muutokset ovat jyrkkiä, muutos seuraavalle tasolle tapahtuu parinkymmenen lehmän välillä.

Mutta hyvinhän se siis pyörii, etenkin kun ottaa huomioon normaalin CB-pelin kuvien määrän (ja kuten sanoitkin, noille jos lähtee vaikka törmäyksiä toteuttamaan niin hidastus tulee enempi fysiikan puolelta)
Valtzu
Active Member
Posts: 115
Joined: Sun Aug 26, 2007 2:40 pm
Location: Sauvo
Contact:

Re: cbSimpleTexture - Kuvan ja Objektin risteytys

Post by Valtzu »

10000 lehmää, FPS ~11
2000 lehmää, FPS ~55
1000 lehmää, FPS 60 (vsync)
SPuntte
Tech Developer
Tech Developer
Posts: 650
Joined: Mon Aug 27, 2007 9:51 pm
Location: Helsinki, Finland
Contact:

Re: cbSimpleTexture - Kuvan ja Objektin risteytys

Post by SPuntte »

Unohtui vielä ekasta postista se, että systeemini osaa maskata kuvia mielivaltaisella maskivärillä. Siihen liittyy kuitenkin eräs CB:stä johtuva outo feature (ei, se ei ole bugi ;P), joka ei näy koodista suoraan päälle päin. Nimittäin, käyttäjän määrittelemän maskivärin lisäksi kuvasta maskautuvat aina myös täysin mustat RGB(0, 0, 0) alueet.

Hieno on myös MaGetzUbin vastaava. Tosin siinä käytetään piirtofunktiossa lineaarista listahakua, joka pitkän listan tapauksessa saattaa hidastaa kohtalaisesti. Itse käytän suoraa indeksiä muistipalaan. MakeImage()-funkkarin vastine on tosiaan kätevä, sen voisin jopa lisätä (plagioida...)

Koodaaja: outoa tuo portaittainen ruudunpäivityksen hidastuminen. Olen aika ymmälläni, en oikein keksi mistä se voisi johtua. Millainen prosessori on alla? Yksi turha pullonkaula tuolla tosin on, nimittäin jakojäännös (Mod), joka varmistaa, että piirretäessä kuvan indeksi pysyy sallituissa rajoissa eikä muistipalasta lueta yli. Tosin sen raskaus riippuu jakasta (pyörityslaatu), eikä piirtokerroista. Voisikohan se vaatia jotenkin kasautuvasti prosessoriaikaa? Ja mitähän tapahtuu, jos sen korvaa If-lausekeparilla?

Valtzu: taitaa olla korkeat kellot prosessorissasi, kun pyörii noin hyvin?
EDIT:

Dudih, fixd. Ekan viestin koodi päivitetty.
Poistin jakojäännöksen ja korvasin sen täysin luettavuuden tappavalla lausekkeella. Mutta onpahan ainakin nopeampi. Nyt FPS pomppii minulla väliä 15-16, eli suorituskykyä tuli lisää jopa joitakin prosentteja. o/

Lisää suorituskykyä saisi vielä poistamalla kaikki eri kahvojen validiustarkistukset, mutta luulen että ne kannattaa poistaa vasta julkaistavasta projektista, kun virheet on korjattu.

Näyttäisi aika hyvältä suorituskyvyn kannalta. Jos yhdessä fysiikkamoottorin objektissa olisi kiinni vaikkapa kymmenkunta tekstuuria, objekteja voisi silti olla kymmenittäin, ennenkuin kone alkaa köhiä.

CoolBasic henkilökuntaa
Tech-kehittäjä
CoolBasic Classic, Cool VES

CoolPhysicsEngine | MissileSystem | Jana-ympyrä -törmäys | cbSimpleTexture | CoolCPLX
otto90x
Advanced Member
Posts: 349
Joined: Mon Aug 27, 2007 9:00 pm
Location: Lapinjärvi, Finland
Contact:

Re: cbSimpleTexture - Kuvan ja Objektin risteytys

Post by otto90x »

Nopeuden kannaltahan tuo ei ole ollenkaan fiksu tapa tehdä tuota. Vähän nopeusvertailua:

Spunten systeemi
0-400 lehmää 60fps
450 lehmää 35fps
500-800 lehmää 30fps
900 lehmää 25fps
1000 lehmää 20fps
2000 lehmää 12fps
10000 lehmää 3fps
CoolBasicin objektit
0-2000 lehmää 60fps
3000 lehmää 30fps
5000 lehmää 20fps
10000 lehmää 12fps

Eli tavallinen objektimoottori on noin kolme-neljä kertaa nopeampi.

Objektien testaamisessa käytetty tätä koodia:

Code: Select all

Const SCRW = 640
Const SCRH = 480
SCREEN SCRW, SCRH,  0, 1
Smooth2D ON

Const COWS = 2000   //LEHMIEN MÄÄRÄ
Dim cow(COWS-1, 6) As Float
Dim cowo(COWS-1) As integer

//Luodaan satunnaisia lehmiä

Dim cowTexture% As Integer //Ladataan YKSI tekstuuri. Ei kloonausta tai muuta säätöä.
cowTexture = LoadObject("Media/cow.bmp", 720)

Dim i
For i = 0 To COWS-1
   cow(i, 0) = Rnd(-SCRW/2,SCRW/2)   //Paikka
   cow(i, 1) = Rnd(-SCRH/2,SCRH/2)
   cow(i, 2) = Rnd(-4,4)   //Nopeus
   cow(i, 3) = Rnd(-4,4)
   cow(i, 4) = Rnd(360)   //Asento
   cow(i, 5) = Rnd(-5,5)   //Kulmanopeus
   cowo(i)   = CloneObject(cowTexture)
Next i


SAFEEXIT OFF
While Not EscapeKey()
    For i = 0 To COWS-1
      cow(i, 0) = cow(i, 0) + cow(i, 2)
      cow(i, 1) = cow(i, 1) + cow(i, 3)
      cow(i, 4) = cow(i, 4) + cow(i, 5)
      
      //Siirretään ruudun ulkopuoliset lehmät toiseen laitaan
      If cow(i, 0) > SCRW/2 Then cow(i, 0) = cow(i, 0) - SCRW
      If cow(i, 0) < -SCRW/2 Then cow(i, 0) = cow(i, 0) + SCRW
      If cow(i, 1) > SCRH/2 Then cow(i, 1) = cow(i, 1) - SCRH
      If cow(i, 1) < -SCRH/2 Then cow(i, 1) = cow(i, 1) + SCRH
      
      PositionObject cowo(i),cow(i, 0),cow(i, 1)
      RotateObject cowo(i),cow(i, 4)
      
   Next i

    DrawScreen
   SetWindow "FPS: " + FPS() + "   Cows: " + COWS
Wend

End
Otto Martikainen a.k.a. MetalRain, otto90x, kAATOSade.
Runoblogi, vuodatusta ja sekoiluja.
User avatar
Ruuttu
Devoted Member
Posts: 688
Joined: Thu Aug 30, 2007 5:11 pm
Location: Finland, Sipoo

Re: cbSimpleTexture - Kuvan ja Objektin risteytys

Post by Ruuttu »

Kyse ei kuitenkaan tainnut olla nopeudesta vaan siitä, että kuvien kanssa ei tarvitse sählätä ShowObject -komennon kanssa jos haluaa väliaikaisesti piilottaa kuvan.
Koodiapina
Forum Veteran
Posts: 2396
Joined: Tue Aug 28, 2007 4:20 pm

Re: cbSimpleTexture - Kuvan ja Objektin risteytys

Post by Koodiapina »

1000 lehmällä FPS oli 10. Testauskoneena Acer eMachines G627.

Miksi koneeni häviää miniläppärillekin?
otto90x
Advanced Member
Posts: 349
Joined: Mon Aug 27, 2007 9:00 pm
Location: Lapinjärvi, Finland
Contact:

Re: cbSimpleTexture - Kuvan ja Objektin risteytys

Post by otto90x »

Mahtaisiko tulla lisää nopeutta jos kuvista voisi piirtää erilaisia valintoja ja/tai piirtää kaikki kuvat kerralla yhdellä funktiokutsulla. Muistaakseni ainakin KilledWhale varoitteli tarpeettomien funktiokutsujen käyttämisestä siis nimenomaan nopeuden kannalta.
Otto Martikainen a.k.a. MetalRain, otto90x, kAATOSade.
Runoblogi, vuodatusta ja sekoiluja.
MaGetzUb
Guru
Posts: 1715
Joined: Sun Sep 09, 2007 12:35 pm
Location: Alavus

Re: cbSimpleTexture - Kuvan ja Objektin risteytys

Post by MaGetzUb »

Tuohon systeemiin voisi vielä lisätä 2 muistipalaa, leveyksiä ja pituuksia varten. Olisi helppo tarkistaa nykyisen kuvan leveys&pituus, jos esim tarkistaa törmäystä. ;)
Solar Eclipse
Meneillä olevat Projektit:
We're in a simulation, and God is trying to debug us.
SPuntte
Tech Developer
Tech Developer
Posts: 650
Joined: Mon Aug 27, 2007 9:51 pm
Location: Helsinki, Finland
Contact:

Re: cbSimpleTexture - Kuvan ja Objektin risteytys

Post by SPuntte »

otto90x wrote:Mahtaisiko tulla lisää nopeutta jos kuvista voisi piirtää erilaisia valintoja ja/tai piirtää kaikki kuvat kerralla yhdellä funktiokutsulla. Muistaakseni ainakin KilledWhale varoitteli tarpeettomien funktiokutsujen käyttämisestä siis nimenomaan nopeuden kannalta.
Jeah, tuossa on järkeä. Muistuttaisi vähän OpenGL:n display listiä. Yksi tapa olisi kirjoittaa muistipalaan järjestyksessä tekstuurin kahva, piirtokoordinaatit ja kulma. Funktiolle työnnettäisiin vain tämä muistipala, jolloin kaikki piirto sujuisi yhdellä funktiokutsulla. Purkkaisampi mutta koodillisesti selkeämpi vaihtoehto olisi kiinteä ja automaagisesti globaali taulukko.
MaGetzUb wrote:Tuohon systeemiin voisi vielä lisätä 2 muistipalaa, leveyksiä ja pituuksia varten. Olisi helppo tarkistaa nykyisen kuvan leveys&pituus, jos esim tarkistaa törmäystä. ;)
Kuten jo sanoin, koodia saa modailla ihan vapaasti omiin tarkoituksiinsa sopivaksi. Omassa moottorissani tekstuureilla ei ole mitään tekemistä fysiikan kanssa - muutakuin se, että fysiikka tietysti määrää, mihin kuvat piirretään - joten en näe mitään syytä tehdä siitä turhaan monimutkaisempaa.
CoolBasic henkilökuntaa
Tech-kehittäjä
CoolBasic Classic, Cool VES

CoolPhysicsEngine | MissileSystem | Jana-ympyrä -törmäys | cbSimpleTexture | CoolCPLX
Sami345
Advanced Member
Posts: 349
Joined: Fri Aug 31, 2007 4:52 pm
Contact:

Re: cbSimpleTexture - Kuvan ja Objektin risteytys

Post by Sami345 »

SPuntte wrote:Unohtui vielä ekasta postista se, että systeemini osaa maskata kuvia mielivaltaisella maskivärillä. Siihen liittyy kuitenkin eräs CB:stä johtuva outo feature (ei, se ei ole bugi ;P), joka ei näy koodista suoraan päälle päin. Nimittäin, käyttäjän määrittelemän maskivärin lisäksi kuvasta maskautuvat aina myös täysin mustat RGB(0, 0, 0) alueet.
Itsellä tätä ei tapahdu ainakaan tällä koodilla:

Code: Select all

ClsColor cbWhite

img = LoadImage("Media\guy.bmp")
MaskImage img, 255, 0, 255

Repeat
    DrawImage img, 0, 0
    DrawScreen
Forever
EDIT:

Testailin esimerkkiä:

Code: Select all

10000 lehmää = FPS 7
9000  lehmää = FPS 8
8000  lehmää = FPS 8
7000  lehmää = FPS 9
6000  lehmää = FPS 10
5000  lehmää = FPS 12
4000  lehmää = FPS 15
3000  lehmää = FPS 20
2000  lehmää = FPS 30
1000  lehmää = FPS 60 (vsync)
[/edit]
Projektit: Fiperus - Jäädytetty pidemmäksi aikaa.
Voitot: Viikkokisa XIII, Pikapelikisa 3, Pikapelikisa 13
http://www.sami345.tk/
SPuntte
Tech Developer
Tech Developer
Posts: 650
Joined: Mon Aug 27, 2007 9:51 pm
Location: Helsinki, Finland
Contact:

Re: cbSimpleTexture - Kuvan ja Objektin risteytys

Post by SPuntte »

Sami345 wrote:
SPuntte wrote:Unohtui vielä ekasta postista se, että systeemini osaa maskata kuvia mielivaltaisella maskivärillä. Siihen liittyy kuitenkin eräs CB:stä johtuva outo feature (ei, se ei ole bugi ;P), joka ei näy koodista suoraan päälle päin. Nimittäin, käyttäjän määrittelemän maskivärin lisäksi kuvasta maskautuvat aina myös täysin mustat RGB(0, 0, 0) alueet.
Itsellä tätä ei tapahdu ainakaan tällä koodilla:

Code: Select all

*plöp*
Eipä niin, sillä maskiväri on pelkkä magenta. Omassa systeemissäni kuvia kuitenkin pyöritetään, mikä on mahdollista vain mustalla maskatuille kuville. Jos yrität pyörittää muulla värillä maskattua kuvaa, piirtyy sen ympärille musta laatikko. Tämä on eräs outo CB-feature (tm).

Kiertääkseni kyseisen ongelman lataan halutun kuvan ja maskaan sen halutulla värillä. Sitten piirrän ladatun ja maskatun kuvan toiseen, mustalla maskattuun kuvaan, jota voin pyörittää.
Last edited by SPuntte on Mon Mar 22, 2010 12:00 am, edited 1 time in total.
CoolBasic henkilökuntaa
Tech-kehittäjä
CoolBasic Classic, Cool VES

CoolPhysicsEngine | MissileSystem | Jana-ympyrä -törmäys | cbSimpleTexture | CoolCPLX
SPuntte
Tech Developer
Tech Developer
Posts: 650
Joined: Mon Aug 27, 2007 9:51 pm
Location: Helsinki, Finland
Contact:

Re: cbSimpleTexture - Kuvan ja Objektin risteytys

Post by SPuntte »

Tuplaposti, hyihyi. "Älkää tehkö niin kuin minä teen, vaan niin kuin minä sanon."

Enivei, päivitystä: Lisäsin koodiin listaominaisuuden, mikä mahdollistaa tekstuurien piirron massoittain yhdellä funktiokutsulla. Muistinkulutus on tällä menetelmällä toki suurempi, mutta niin on myös ruudunpäivitystaajuus. Saatte varmaan lisäillä lehmien määrää, että FPS tippuu alle vsync-taajuuden. Vielä kiitokset otto90x:lle loistoideasta.

Päivitetty koodi löytyy ensimmäisestä viestistä.
CoolBasic henkilökuntaa
Tech-kehittäjä
CoolBasic Classic, Cool VES

CoolPhysicsEngine | MissileSystem | Jana-ympyrä -törmäys | cbSimpleTexture | CoolCPLX
User avatar
Ruuttu
Devoted Member
Posts: 688
Joined: Thu Aug 30, 2007 5:11 pm
Location: Finland, Sipoo

Re: cbSimpleTexture - Kuvan ja Objektin risteytys

Post by Ruuttu »

Uudella koodilla 11000 lehmää @ 10 FPS (tai 3600 lehmää @ 30 FPS). Hyvin pyörii.
User avatar
Jonez
Devoted Member
Posts: 575
Joined: Mon Aug 27, 2007 8:37 pm

Re: cbSimpleTexture - Kuvan ja Objektin risteytys

Post by Jonez »

En ensin huomannut mitään eroa päivitysten välillä. Ero kuitenkin on. Kuten koodaaja sanoi, suorityskyvyssä on ihmeellisiä inflaatiovaiheita:

DrawTextureList() pyörittää 60:n fps:n pintaan 0-940:llä lehmällä tällä koneella.
DrawTexture() pääsee kuuteenkymppiin vielä 540:llä lehmällä.

Kummankin funktion suorituskyky tippuu seuraavalla "askelmalla" sinne 30:n fps:n tietämille.
DrawTexturella tämä 30:n fps:n väli on niinkin tarkka kuin ~580 - 1160 lehmää. 1200 lehmää tiputtaa virkistystaajuuden kahteenkymppiin.

DrawTextureList() kykenee kolmenkympin fps:ään välillä 1000 - 2100 lehmää. 2200 tiputtaa fps:än tässäkin tapauksessa kahteenkymppiin.

Eli esimerkiksi tuolla 1000 lehmän koodilla kummassakaan funktiossa ei tällä koneella ole sanottavaa eroa.
-Vuoden 2008 aloittelijan ystävä -palkinnon voittaja-
Image <- protestipelikilpailun voittaja.
Space War
MaGetzUb
Guru
Posts: 1715
Joined: Sun Sep 09, 2007 12:35 pm
Location: Alavus

Re: cbSimpleTexture - Kuvan ja Objektin risteytys

Post by MaGetzUb »

Koodasin vielä uudestaan omani, tein niinkuin SPuntte, imaget pyöritellään nyt muistipalaan. :)

Code: Select all

Type Sprites
    Field Sprite_Rot
    Field Sprite_Images
    Field Sprite_Width
    Field Sprite_Height
EndType 

ukko = LoadSprite("Media\Guy.BMP",72)
zero = LoadAnimSprite("Media\zerorun1.bmp",47,51,0,13,72,255,0,255)

Repeat
    a = a + 5
    If Timer() > _time + 50 Then 
        f = f + 1
        _time = Timer()
    EndIf 
    If f > 10 Then f = 1
    DrawSprite(ukko,200,100,a)
    DrawSprite(zero,200,150,-a,f)
    Text 0, 0, FPS()
DrawScreen
FOrever 



Function LoadSprite(f$, rotation = 72, maskr = 0, maskg = 0, maskb = 0)
    AngStep = 360 / rotation
    Tmp = LoadImage(f$)
    MaskImage Tmp,maskr,maskg,maskb
    Sprite.Sprites = New(Sprites)
    Sprite\Sprite_Rot = rotation
    Sprite\Sprite_Images = MakeMEMBlock((rotation+1)*4)
    Sprite\Sprite_Width = ImageWidth(tmp)
    Sprite\Sprite_Height = ImageHeight(tmp)
    For i = 0 To rotation
        IMG = CloneImage(TMP)
        RotateImage IMG,-i*Angstep
        PokeInt Sprite\Sprite_Images, i*4, IMG
    Next i
    DeleteImage Tmp
    Return ConvertToInteger(Sprite)
EndFunction 

Function LoadAnimSprite(f$, w,h, start, frames, rotation = 72, maskr = 0, maskg = 0, maskb = 0)
    AngStep = 360 / rotation
    Tmp = LoadAnimImage(f$,w,h, start, frames)
    MaskImage Tmp,maskr,maskg,maskb
    Sprite.Sprites = New(Sprites)
    Sprite\Sprite_Rot = rotation
    Sprite\Sprite_Images = MakeMEMBlock((rotation+1)*4)
    Sprite\Sprite_Width = ImageWidth(tmp)
    Sprite\Sprite_Height = ImageHeight(tmp)    
    For i = 0 To rotation
        IMG = CloneImage(TMP)
        RotateImage IMG,-i*Angstep
        PokeInt Sprite\Sprite_Images, i*4, IMG
    Next i
    DeleteImage Tmp
    Return ConvertToInteger(Sprite)
EndFunction 

Function DrawSprite(handle,x,y,angle#,frame=0)
    angle = WrapAngle(angle)
    Sprite.Sprites = ConvertToType(handle)
    kulma = Int((Float(Sprite\Sprite_Rot)  / 360) * Float(angle))
    kuvahandle = PeekInt(Sprite\Sprite_Images, kulma * 4)
    DrawImage kuvahandle, x, y, frame 
EndFunction 

Function ReturnSprite(handle,angle#)
    angle = WrapAngle(angle)
    Sprite.Sprites = ConvertToType(handle)
    kulma = Int((Float(Sprite\Sprite_Rot)  / 360) * Float(angle))
    Return  PeekInt(Sprite\Sprite_Images, kulma * 4)
EndFunction 


Function GetSpriteWidth(sprite_)
    Sprite.Sprites = ConvertToType(sprite_)
    Return Sprite\Sprite_Width
EndFunction 

Function GetSpriteHeight(sprite_)
    Sprite.Sprites = ConvertToType(sprite_)
    Return Sprite\Sprite_Height
EndFunction 

Function DeleteSprite(sprite_)
    Sprite.Sprites = ConvertToType(sprite_)
    DeleteMEMBlock Sprite\Sprite_Images
    Delete Sprite
EndFunction 
EDIT:

TMP kuvien poisto muistista lisätty.

EDIT:

Koodia muokattu vielä lisää.(Esimerkkiä)

Solar Eclipse
Meneillä olevat Projektit:
We're in a simulation, and God is trying to debug us.
Post Reply