PDA

View Full Version : [C#]Come valutare il n° di fotogrammi al secondo di una scena DirectX fatta da me?


Radeon89
03-04-2008, 17:11
Ciao a tutti!
Sto facendo la mia tesina di maturità, che invece di essere un gioco (come pensavo qui (http://www.hwupgrade.it/forum/showthread.php?t=1627338)) è una specie di dimostrazione delle DirectX. Ora, ho già trovato un modo per visualizzare il numero di fotogrammi al secondo della mia scena. Ho messo un valore int come attributo della form in cui è presente la scena DirectX e lo vado ad incrementare ogni qual volta traccio qualcosa con il metodo Paint della form.

Inoltre ho fatto partire un thread che cicla all'infinito in questo modo per valutare quando è passato un secondo:

private void tempoFps(Object start) //metodo per il thread che visualizza il numero di frame per secondo
{
DateTime timeStart = (DateTime)start; //leggo il tempo passato, che è l'ora attuale
while (true)
{
TimeSpan calcolo = DateTime.Now - timeStart;//faccio la differenza tra il tempo attuale e quello iniziale
if ((calcolo.Seconds) >= 1) //se è passato almeno un secondo
{
scelta.fps(fps); //chiamo il metodo della finestra di menu per visualizzare il valore del numero di fps
fps = 0; // è la variabile che tiene conto degli fps
timeStart = DateTime.Now; //riazzero il tempo iniziale
}
}
}

Il metodo chiamato dell'oggetto scelta (che è un'altra form) stampa il numero di fotogrammi al secondo.

L'unico problema è che questo thread, essendo un ciclo infinito, occupa molto tempo cpu (ho un dual core quindi ne occupa la metà), e considerando che prima il mio programma non occupava praticamente nulla di CPU, vorrei ottimizzarlo un po'.

Ho provato ad aprire fraps e lui se la viaggia che è un piacere... Come faccio ad ottimizzare il tutto??

fek
03-04-2008, 17:20
Hai diversi modi per farlo. Io ti consiglio di separare il rendering un thread, oppure metterlo in risposta all'evento Idle della Form.

All'inizio del render frame prendi il tempo corrente e lo sottrai al tempo preso al frame precedente. Cosi' calcoli il frame_time e da li' il frame rate. Meglio ancora prendere il tempo ogni X frame.

E' pulito e funziona.

Ora, se metti un ciclo (come il render loop) in un altro thread e non vuoi fargli mangiare tutta la CPU, sbatti un bel Sleep(1) o Sleep(0).

Nel primo caso rilasci la CPU per un millisecondo e il thread va in pausa, mentre nel secondo caso rilasci il resto del timeslice allocato per quel thread al sistema, il thread non va in pausa ma viene rimesso in coda pronto per un'altra allocazione al prossimo round robin. Ma puo' avere alcuni problemi in alcuni casi contorti.

Usa Sleep(1) e funziona una meraviglia.

Note stilistiche:
- scrivi variabili e metodi in inglese
- NON COMMENTARE IL CODICE RIGA PER RIGA O VENGO A CASA TUA E TI SPEZZO LE GINOCCHIA

No, non lo faccio, ma non commentare il codice riga per riga che gesu' bambino piange :)

Radeon89
03-04-2008, 18:03
Ok, ho messo l'istruzione Thread.Sleep(1) ed ora l'utilizzo cpu è tornato normale :)

Avrei un'altra cosa da chiederti, una curiosità: hai nominato l'evento idle della form. Quando viene generato? Quando l'applicazione arriva alla fine del metodo Paint?

Vado un po' OT per chiederti un'altra cosa


Quando da Visual studio faccio partire il programma, ogni tanto mi compare questo errore:

Tentativo di esecuzione gestita da parte della DLL 'C:\WINDOWS\assembly\GAC\Microsoft.DirectX.DirectInput\1.0.2902.0__31bf3856ad364e35\Microsoft.DirectX.DirectInput.dll' all'interno del blocco OS Loader. Non provare a eseguire codice gestito all'interno di una DllMain o di una funzione di inizializzazione delle immagini. Questa operazione può causare il blocco dell'applicazione.

In presenza di questa istruzione:
inizializzaTastiera(handle);

che chiama il metodo per l'inizializzazione della tastiera:
public void inizializzaTastiera(IntPtr handle)
{
keyb = new Microsoft.DirectX.DirectInput.Device(SystemGuid.Keyboard); //alloco la tastiera di default alla mia variabile "keyb"
keyb.SetCooperativeLevel(handle, CooperativeLevelFlags.Background | CooperativeLevelFlags.NonExclusive);
keyb.Acquire();
}

Dove sta il problema??
Finora a fare partire l'eseguibile da Windows non è successo nulla di strano, ma magari è perché la maggior parte delle volte lo faccio da Visual Studio...

fek
03-04-2008, 18:57
Avrei un'altra cosa da chiederti, una curiosità: hai nominato l'evento idle della form. Quando viene generato? Quando l'applicazione arriva alla fine del metodo Paint?

No, e' generato quando la Form non ha piu' messaggi da processare.


Dove sta il problema??
Finora a fare partire l'eseguibile da Windows non è successo nulla di strano, ma magari è perché la maggior parte delle volte lo faccio da Visual Studio...


Non ho idea, mai usato, sorry.

^TiGeRShArK^
03-04-2008, 18:59
No, non lo faccio, ma non commentare il codice riga per riga che gesu' bambino piange :)
:rotfl:
che stai diventando anche tu un evangelista fran? :asd:

cdimauro
04-04-2008, 07:59
Ma è per una Giusta Causa (tm). :O :D

Radeon89
04-04-2008, 10:23
Comunque quel problema è fastidiosissimo, me lo dà quasi sempre da quando ho fatto le ultime modifiche per il conteggio dei fotogrammi al secondo... E non capisco per quale motivo... Inoltre ha reso Visual Studio instabile, nel senso che spesso si blocca sul mio pc quando faccio partire il programma dall'IDE, e poi continua dice di essere in attesa di un evento che tarda ad essere generato... :help: :help: :help:

Rigo007
04-04-2008, 19:14
Ciao,
vi vedo abbastanza efferati in materia quindi vi chiedo gentilmente una dritta.
Devo imparare a programmare in C# sfruttando le funzionalità e le classi del .NET Framework e volevo sapere quale versione di Visual Studio e quale versione di .NET Framework installare su un computer con SO WinXP.
Grazie.

^TiGeRShArK^
04-04-2008, 21:58
Ciao,
vi vedo abbastanza efferati in materia quindi vi chiedo gentilmente una dritta.
Devo imparare a programmare in C# sfruttando le funzionalità e le classi del .NET Framework e volevo sapere quale versione di Visual Studio e quale versione di .NET Framework installare su un computer con SO WinXP.
Grazie.

Visual C# Express 2008 che dovrebbe insallarti automaticamente il .Net Framework 3.5, con cui puoi sfruttare le nuove features tra cui Linq e le properties generate automaticamente e magari qualche altra cosa che ti può citare gugoxx perchè io per ora sto lavorando con .Net 2.0 per motivi di compatibilità maggiore e quindi non lo conosco in maniera approfondita il framework 3.5...... :p

Radeon89
05-04-2008, 15:02
Ciao,
vi vedo abbastanza efferati in materia quindi vi chiedo gentilmente una dritta.
Devo imparare a programmare in C# sfruttando le funzionalità e le classi del .NET Framework e volevo sapere quale versione di Visual Studio e quale versione di .NET Framework installare su un computer con SO WinXP.
Grazie.

Mah, io uso Visual Studio 2005, non perché sia il migliore ma la mia scuola ha degli accordi con Microsoft e lo distribuiscono gratuitamente (conoscete l'MSDNAA?). Anche se ora è in distribuzione la versione 2008, che dovrebbe essere migliore.

Comunque in merito al mio problema nessuno sa dirmi niente? Lo fa spesso... E' un errore di LoaderLock

kernel::panic
05-04-2008, 15:46
Comunque in merito al mio problema nessuno sa dirmi niente? Lo fa spesso... E' un errore di LoaderLock

Prova ad andare in "Proprietà progetto", poi nel tab "Debug" e a togliere la spunta a "Enable the Visual Studio hosting process"... a me aveva risolto un analogo problema lavorando con gli hook di sistema.

Ciao :)

Radeon89
07-04-2008, 16:55
No, purtroppo lo fa ancora... Anzi, devo dire che è peggiorata la situazione togliendo il segno di spunta da quella casella. Almeno prima quando lo fa basta farlo ripartire, ora devo provare 3 volte di seguito per riuscire a farlo andare! :(

Altri suggerimenti???:confused: