View Full Version : [CICLO 6] Storia 1
Storia 1: Ogni gemma dovrà avere un colore (tra 5 possibili: bianco, rosso, blu, verde, giallo), a cui corrisponderanno una differente png (rispettivamente diamond, ruby, sapphire, emerald, topaz) ed un differente valore in punteggio (per ora rispettivamente 100, 50, 60, 40, 80), e dovrà riconoscere se nelle vicinanze (diagonali escluse, quindi nelle quattro direzioni principali) ha delle gemme di uguale colore (evento da evidenziare visivamente agendo sulla luminosità delle gemme uguali adiacenti tra loro).
Il colore delle prime sei gemme viene scelto casualmente all'inizio del gioco, e viene inserito in una coda. Ad ogni gemma creata, viene estratto il primo valore e viene creato un nuovo valore casuale che si appende in coda.
Punti cardine da tenere a mente durante i lavori:
Mai fare a gara a chi finisce il task per primo, meglio procedere con calma, altrimenti perderemo molto più tempo in seguito
Evitiamo di complicarci la vita, esiste di certo una soluzione più semplice di quella che abbiamo pensato di implementare
MAI aggiungere elementi non richiesti esplicitamente dai task: se mai serviranno, se ne parlerà nelle prossime storie
Comunichiamo il più possibile, se qualcosa non è chiaro discutiamone tutti i dettagli fino ad eliminare ogni dubbio, anche il più insignificante
Ecco la lista dei task per questa storia.
Task:
6.1.1: 71104: completato
Aggiungere la possibilita di scegliere quale tipo di gemma deve essere creata da GameGemFactory quando viene chiamata la create. I vari tipi di gemme per ora sono: diamond, ruby, sapphire, emerald, topaz.
6.1.2: ^TiGeRShArK^: completato
La casella dei punti non deve piu riportare il numero di gemme all'interno della griglia. Il nuovo valore è la somma dei punti che ogni singola gemma rappresenta. La tabella con i punti è la seguente:
diamond | ruby | sapphire | emerald | topaz
100 | 50 | 60 | 40 | 80
6.1.3: Ufo13: completato
Aggiungere un metodo per modificare la "luminosità" di uno sprite. Si deve quindi moltiplicare il colore proveniente dalla texture per un colore che ne indica la luminosita
6.1.4: 71104 + DanieleC88: completato
Grid deve aumentare la luminosità delle gemme che hanno almeno un lato in comune con un'altra gemma dello stesso tipo.
(solo pair-programming)
6.1.5: cionci: completato
Aggiungere a GameGemFactory una coda che deve contenere le prossime 6 Gemme da rilasciare.
6.1.6: Ufo13: completato
Quando viene richiesta una nuova gemma GameFemFactory deve restituire quella in testa alla coda ed eliminarla dalla lista. Fatto questo deve essere creato un nuovo valore da appendere in coda
ciao ;)
provo il primo, 1 giorno; ora mi cimento in qualche test, se non ho ben chiaro qualcosa lo posto sul forum.
PS: vicius, non mi ero accorto che mettevi il "ciao ;)" pure in fondo ai task :D
perché non te lo metti in signature scusa? :D
provo il primo, 1 giorno; ora mi cimento in qualche test, se non ho ben chiaro qualcosa lo posto sul forum.
PS: vicius, non mi ero accorto che mettevi il "ciao ;)" pure in fondo ai task :D
perché non te lo metti in signature scusa? :D
Assegnato.
ciao ;)
allora, problema: come faccio il test? :confused:
perché idealmente il test dovrebbe chiamare GameGemFactory.create passandogli il nome della texture da caricare e verificare che la Gem restituita contenga la texture giusta, ma come fo a verificare che la texture è quella giusta? :confused:
Potresti usare questo metodo per fare i confronti:
gem.getTexture().equals(new Texture(nome_della_gemma))
Anzi...mi sa che così non funziona... Credo per problemi di confronto fra due buffer...
infatti non funzionerebbe di sicuro perché la nostra classe Texture non overridda il metodo equals... la comparazione risulterebbe sempre falsa...
Controllarlo con il nome avrebbe poco senso...che dici ? Ovviamente andrebbe esposto un metodo getName in Texture...
Anche se, supponendo che la classe Texture funzioni, dovrebbe essere sufficiente...
^TiGeRShArK^
29-11-2005, 23:40
io mi prenderei il task 2 tempo previsto 2 giorni (mi tengo sempre largo non si sa mai :Prrr: )
....sempre che non riteniate + opportuno che possa continuare a giochicchiare col Parser :D (Vedi Thread apposito....)
[EDIT]ovviamente pure io dovrei partire dopo che finisce 71104 mi sa.....
altrimenti come faccio a sommare il valore delle gemme diverse con tutte le gemme uguali??? :confused:
Io mi prenoto per il 6.1.5...2 giorni a partire da quando 71104 ha terminato il suo task
Controllarlo con il nome avrebbe poco senso...che dici ? Ovviamente andrebbe esposto un metodo getName in Texture...
Anche se, supponendo che la classe Texture funzioni, dovrebbe essere sufficiente...
E' una buona soluzione per ora.
io mi prenderei il task 2 tempo previsto 2 giorni (mi tengo sempre largo non si sa mai :Prrr: )
....sempre che non riteniate + opportuno che possa continuare a giochicchiare col Parser :D (Vedi Thread apposito....)
Gli Spike sono a parte, i task hanno sempre priorita'.
Stavo pensando che io il mio task lo posso fare anche senza il task di 71104... Però mi sono trovato di fronte ad un problema...l'audio...
Non posso inserire il codice per la gestione della coda in GameGemFactory perchè ha bisogno che l'audio sia inizializzato nel costruttore...
fek, che ne dici se promuovo GemFactory da interfaccia a classe base ?
In questo modo implemento la coda lì e verrà ereditata da GameGemFactory e GemFactoryForTesting...
Mi sa che ho semplificato notevolmente tutto... Ho aggiunto una classe GemQueue... Basta che GameGemFactory e GemFactoryForTesting la istanzino...
Mi sa che ho semplificato notevolmente tutto... Ho aggiunto una classe GemQueue... Basta che GameGemFactory e GemFactoryForTesting la istanzino...
Ecco :)
Bello programmare a interfacce vero? Ti costringe a cercare design piu' semplici.
Hai scritto GemQueue test-driven?
Certo... Vorrei anche vedere...
9 test per 4 metodi :)
^TiGeRShArK^
30-11-2005, 11:37
Gli Spike sono a parte, i task hanno sempre priorita'.
ok...
ma tanto finchè non viene concluso il task 1 non credo che potrei fare molto.. il mio task si basa proprio sull'assunto che le gemme siano diverse...
intanto farei lo spike, appena 71104 finisce il suo task partirei col mio...
Ragazzi, ricordatevi di scrivere la test list prima di iniziare il task. E questo vale per tutti :)
Se non l'avete scritta e avete gia' iniziato il task, scrivetela comunque.
Questi dovrebbe essere i test più rappresentativi:
public void testTwoGemExtraction()
{
Gem gem1 = new Gem("diamond");
Gem gem2 = new Gem("diamond");
gemQueue.insertLast(gem1);
gemQueue.insertLast(gem2);
Gem extractedGem1 = gemQueue.extractFirst();
assertSame("gems are not the same", gem1, extractedGem1);
assertEquals("erroneus queue size", 1, gemQueue.queueSize());
Gem extractedGem2 = gemQueue.extractFirst();
assertSame("gems are not the same", gem2, extractedGem2);
assertEquals("erroneus queue size", 0, gemQueue.queueSize());
}
public void testQueueOverflow()
{
gemQueue.insertLast(new Gem("diamond"));
gemQueue.insertLast(new Gem("diamond"));
gemQueue.insertLast(new Gem("diamond"));
gemQueue.insertLast(new Gem("diamond"));
gemQueue.insertLast(new Gem("diamond"));
gemQueue.insertLast(new Gem("diamond"));
try
{
gemQueue.insertLast(new Gem("diamond"));
}
catch(IllegalArgumentException e)
{
return;
}
fail("IllegalArgumentException not thrown");
}
allora, per il mio task direi che come test list bastano questi due test:
- caricare un determinato tipo di gemma e verificare che il nome ritornato dalla Texture sia lo stesso passato a GameGemFactory.create().
- verificare che venga lanciata un'eccezione nel caso il nome passato non sia quello di una texture valida
unico piccolo dubbio: quale è meglio tra le 3 seguenti cose per il primo test?
1) testare tutti e 5 gli attuali possibili valori del parametro passato in input
2) fare 5 test diversi, uno per ogni valore
3) fare un solo test che passi solo un paio di valori, e ci fidiamo che funzionino pure gli altri 3
fate troppo veloci... teeeeeeest list prima :D
Dimenticavo:
6.1.4:
Grid deve aumentare la luminosità delle gemme che hanno almeno un lato in comune con un'altra gemma dello stesso tipo.
In pair programming.
cionci, scusami, sono arrivato da poco quindi devo capire come funzionano le cose :)
ho fatto l'Update dopo il tuo commit e vedo che hai aggiunto una nuova classe per la coda più relativo testing...
Il task dice:
Aggiungere a GameGemFactory una coda che deve contenere le prossime 6 Gemme da rilasciare.
Mi viene da pensare che dovrebbero esserci dei cambiamenti anche nella Factory ma da me è rimasta invariata! E normale che sia così?
fate troppo veloci... teeeeeeest list prima :D
L'ultimo post della pagina precedente ;)
Il task dice:
Aggiungere a GameGemFactory una coda che deve contenere le prossime 6 Gemme da rilasciare.
Mi viene da pensare che dovrebbero esserci dei cambiamenti anche nella Factory ma da me è rimasta invariata! E normale che sia così?
Di fatto aggiungere le modiche a GameGemFactory avrebbe portato a complicare notevolmente il modello (che attualmente è composta da un'interfaccia e da GameGemFactory e GemFactoryForTesting che la implementano)...
Ad esempio avrei dovuto modificare sia l'interfaccia che GemFactoryForTesting per condividere la stessa interfaccia...ma anche la stessa implementazione della coda in GemFactoringForTesting !!!
Quindi sarebbe stata una duplicazione...
GameGemFactory e GemFactoryForTesting verranno modificate dal task 6.1.6 che istanzierà GemQueue all'interno di entrambe le classi...
Grazie per la risposta ora mi è tutto più chiaro :)
ehm, ragazzi, siccome il mio task era molto semplice potrei prenotarmi anche per il pair programming del 6.1.4? ^^'
( :Perfido: :Perfido: :Perfido: )
potrei provare a fare l'accoppiata se ti va... dovremmo lavorarcelo in serata perchè domani non ci sono tutto il giorno :D
hmmm ma forse meglio prendere prima il 6.1.3? :p
DanieleC88
30-11-2005, 16:19
ehm, ragazzi, siccome il mio task era molto semplice potrei prenotarmi anche per il pair programming del 6.1.4? ^^'
( :Perfido: :Perfido: :Perfido: )
Ingordo! Lascia qualcosa anche agli altri! :D
Non pare complesso il task. Se vuoi possiamo collaborare.
DanieleC88
30-11-2005, 16:21
potrei provare a fare l'accoppiata se ti va... dovremmo lavorarcelo in serata perchè domani non ci sono tutto il giorno :D
Credo proprio che il 6.1.4 dipenda dal 6.1.3, quindi il tempo c'è finché non viene completato quello. :D
L'ultimo post della pagina precedente ;)
Visto ora :D
hmm allora prendo il task 6, 2 giorni (domani non ci sono :D)
Non pare complesso il task. Se vuoi possiamo collaborare. sono TROPPO d'accordo!!! :) :)
per me va benissimo, basta solo trovare un orario in cui ci siamo entrambi, perché io come sai ho il problema che le lezioni ce le ho di pomeriggio... il mercoledì (cioè oggi) torno prima perché ho solo 3 ore, e il martedì posso anche permettermi di tornare prima perché alle ultime ore ho programmazione a oggetti che seguo poco (:p :p :p) quindi va bene uno di questi due giorni.
ciao :)
perché alle ultime ore ho programmazione a oggetti che seguo poco (:p :p :p)
Perche' fai gia' quella lezione qua :p
Perche' fai gia' quella lezione qua :p l'hai detto!!! :D
e faccio pure Ingegneria del Software :D
Per ora ho pensato ai seguenti test:
- Un metodo per testare che la lista appena creata abbia 6 elementi
- Un metodo per testare che dopo la restituzione di un elemento la lista continui a contenerne 6
pensate possano servirne altri? Magari provare ad eseguire 6 create() di fila?
Per ora ho pensato ai seguenti test:
- Un metodo per testare che la lista appena creata abbia 6 elementi
- Un metodo per testare che dopo la restituzione di un elemento la lista continui a contenerne 6
Dovrebbe andare bene... Ricordati che puoi anche cambiare i nomi dei metodi (usa Refactor->Rename di Eclipse)...oppure anche riscriverne alcuni da zero (non è detto che create debba esistere anche dopo)...
qua mi si presentano 2 scelte:
Possibilità 1:
lascio create(string name) com'è, quando viene invocato restituisce una Gem, la cancella dalla lista e ne inserisce una nuova (con parametro name)
l'inizializzazione della lista sarebbe fatta nella factory (con 6 insert consecutive)
Questa soluzione non mi piace molto ma è la più semplice da realizzare ora (e Fek dice di cercare la soluzione + semplice :) )
Possibilità 2:
create(string name) diventa create(), restituisce una Gem, la elimina e ne inserisce una nuova.
l'inizializzazione della lista come prima...
^TiGeRShArK^
30-11-2005, 21:26
task completato ora effettuo il commit:
test list:
public void testScoreAfterDiamondInsertion()
public void testScoreAfterEmeraldInsertion()
public void testScoreAfterRubyInsertion()
public void testScoreAfterSapphireInsertion()
public void testScoreAfterTopazInsertion()
public void testScoreAfterInsertingAllGemsTwice()
non ho ritenuto opportuno testare lo score dopo la rimozione della gemma dato che per calcolare il punteggio ho utilizzato il getNumberOfGems opportunamente modificato per tenere conto del numero delle diverse gemme..... e poichè il getNumberOfGems era già testato anche in rimozione credo che sia tutto a posto.....
ora procedo al commit... e se riesco do un occhiatina al parser per provare ad implementare l'idea che mi ha suggerito passivamente il forum oggi :D
(mi devo comprare un manichino a cui spiegare i problemi in effetti! :D)
Avrei già finito (ho optato per la soluzione 1)... Ma mi serve la password per fare il commit quindi aspetterò domani...
come test ho semplicemente modificato quello di 71104:
public void testGemTexture()
ed è valido ancora il test di 71104:
public void testInvalidGemName()
le prime 6 gemme create nel costruttore della GameGemFactory sono ruby le altre poi nella versione corrente del gioco saranno tutte "diamond" che è il parametro name passato al metodo create(string name)...
questo è il mio primo commit, ho provato con ANT e dovrebbe essere tutto a posto... Nel caso fatemi sapere, Ufo13
Complimenti per il primo commit :D
Non c'e' bisogno che te lo faccia sapere qualcuno, abbiamo la build machine che ti dice se va tutto bene.
Ecco l'indirizzo:
http://fcarucci.homeip.net:8080/cruisecontrol
Dopo aver fatto il commit, aspetta qualche minuto e apparira' il risultato. C'e' anche un feed RSS disponibile. Io lo uso in ufficio e mi arrivano i feed direttamente sul desktop, se la build e' rotta, lo so subito :)
hehe bello vedere che funziona :p, cmq avevo controllato 2 volte con ant :D
4 task completati in poco piu di un giorno. Siete dei mostri :D
ciao ;)
Fate update prima di ricominciare a scrivere codice che ho fatto parecchio refactoring.
public Gem create(String name)
{
Gem newGem = new Gem(name);
newGem.setCollisionSound(sound);
Gem extractedGem = queue.extractFirst();
queue.insertLast(newGem);
return extractedGem;
}
Questo metodo e' logicamente scorretto. Non restituisce la gemma del tipo richiesto, ma restituisce la prima nella coda. O gli si cambia nome (hmm) oppure si implementa una nuova classe che si occupa di aggiungere nuove gemme alla coda e che possa essere testata. Per altro, questo metodo, non e' testato.
Chi se ne occupa?
Un'altra precisazione su questo task:
6.1.5:
Aggiungere a GameGemFactory una coda che deve contenere le prossime 6 Gemme da rilasciare.
La storia dice che le prime sei gemme devono essere casuali e questo task non dice nulla a riguardo. Errore nostro, e' da modificare cosi':
6.1.5:
Aggiungere a GameGemFactory una coda che deve contenere le prossime 6 Gemme da rilasciare estratte in maniera casuale.
Cionci? E' tuo.
E sta a vedere che non vado a rompere la build io perche' non ho lanciato Ant... 1 pound.
Sì è mio... Ci penso io... Infatti mi sembrava che mancasse qualcosa...
Ho aggiunto il riempimento casuale della coda...ma ho portato la coda in GameGemFactory perchè ho visto che non l'avete portata anche in GemFactoryForTesting (forse era comoda appunto per testare senza l'audio)...
Va rimessa a posto la questione create di GemFactory... Più che una create dovrebbe essere una "extractFirstAndInsertNew"...o qualcosa del genere...magari semplicemente "getNextGem"...
Come dicevo...si è appunto ripresentato il problema dell'audio... La build è rotta per quello...
Intanto ho messo come disabilitato (o testing) un Sound che trovava il motore non inizializzato... Poi magari con SoundBank risolviamo in maniera diversa...
In questo modo potremmo elimnare anche GemFactoryForTesting e GemFactory...
Tutta la notte a ripristinare la build :coffee:
E la cosa strana è che la differenza fra l'ultima che non passava e quella che è passata era un import che è stato tolto :muro: :confused:
^TiGeRShArK^
01-12-2005, 08:55
Tutta la notte a ripristinare la build :coffee:
E la cosa strana è che la differenza fra l'ultima che non passava e quella che è passata era un import che è stato tolto :muro: :confused:
:eek:
minkia! ora hai finito??? :eek:
e pensavo di essere fuso io! :mbe:
:D
Grandissimo Cionci :cincin:
Tutta la notte a ripristinare la build :coffee:
E la cosa strana è che la differenza fra l'ultima che non passava e quella che è passata era un import che è stato tolto :muro: :confused:
Gli import li ho tolti io ieri sera ma non ho toccato niente in Audio come è possibile :confused:
ciao ;)
:eek:
minkia! ora hai finito??? :eek:
e pensavo di essere fuso io! :mbe:
:D
No...ma ho smesso alle 3 e mezza :coffee: ed ho ripreso appena sveglio...
Comunque continuo a non capire come mai... Visto che fra la penultima e l'ultima ho tolto solo un import (gli warning non dovrebbero influire sul successo dei test :muro: )
Gli import li ho tolti io ieri sera ma non ho toccato niente in Audio come è possibile :confused:
ciao ;)
Cioè...io ho tolto l'import di Audio... La modifica fra l'ultima non funzionante e quella funzionante è stata solamente di togliere un import...
Anche dopo che li hai tolti tu non funzionava, ma non ne capisco il motivo :muro:
Comunque ora la Sound è come se fosse creata forTesting se trova l'audio non attivo...
public Gem create(String name)
{
Gem newGem = new Gem(name);
newGem.setCollisionSound(sound);
Gem extractedGem = queue.extractFirst();
queue.insertLast(newGem);
return extractedGem;
}
Questo metodo e' logicamente scorretto. Non restituisce la gemma del tipo richiesto, ma restituisce la prima nella coda. O gli si cambia nome (hmm) oppure si implementa una nuova classe che si occupa di aggiungere nuove gemme alla coda e che possa essere testata. Per altro, questo metodo, non e' testato.
Chi se ne occupa?
Visto che in parte il codice era il mio (e mi sembrava non andasse bene ma non volevo fare troppe modifiche come primo commit :p) potrei occuparmene personalmente...
Non ho ben chiaro cosa intendi con l'aggiungere una nuova classe per l'inserimento della gemma nella lista... Fore intendi l'inserimento in coda + l'estrazione della testa?
Mi pare che la lista implementata da cionci lo abbia gia`...
DanieleC88
01-12-2005, 12:54
sono TROPPO d'accordo!!! :) :)
per me va benissimo, basta solo trovare un orario in cui ci siamo entrambi, perché io come sai ho il problema che le lezioni ce le ho di pomeriggio... il mercoledì (cioè oggi) torno prima perché ho solo 3 ore, e il martedì posso anche permettermi di tornare prima perché alle ultime ore ho programmazione a oggetti che seguo poco (:p :p :p) quindi va bene uno di questi due giorni.
ciao :)
Per me va benissimo qualsiasi giorno, l'unica restrizione è la fascia oraria (ci sarò all'incirca dalle 14:30 allen 18:00, la domenica dalle 9:00 alle 18:00). Ci vediamo su MSN (ammesso che il mio Gaim nuovo fiammante preso dal CVS non vada troppo in crash :D - al limite ricorrerò ad aMSN)!
Dimenticavo: un bel grazie a cionci che ha sacrificato il suo sonno per noi tutti. ;)
Visto che in parte il codice era il mio (e mi sembrava non andasse bene ma non volevo fare troppe modifiche come primo commit :p) potrei occuparmene personalmente...
Allora a questo punto (aspetta la conferma da fek) la create deve essere eliminata (o rinominata)...
Credo che la create possa essere sostituita nel codice con una di queste due opzioni:
- un metodo che estrae la prima gemma dalla coda ed inserisce in fondo alla coda una nuova gemma casuale
- un metodo che estrae la prima gemma dalla coda ed un altro metodo che inserisce in fondo alla coda una nuova gemma casuale
Per il primo basterebbe trovargli il nome adatto...
E' meglio che il metodo restituisca una gemma e ne inserisca una nuova passata come parametro, altrimenti non e' testabile. A meno di non creare un mock per generatore di numeri random e passare noi i valori per poi testare che le gemme siano effettivamente quelle che vogliamo.
A te la scelta della soluzione
altrimenti non e' testabile.
Siamo sicuri che non sia testabile ? A me sembra testabile...l'unica cosa che non è testabile è l'inserimento casuale...ma non basta verificare che la gemma inserita sia una fra quelle possibili ?
Ad esempio:
Gem gemToBeExtracted = gemFactory.getGemAt(0);
Gem gemInPositionTwo = gemFactory.getGemAt(1);
Gem gemInPositionSix = gemFactory.getGemAt(5);
Gem gemExtracted = gemFactory.extractNextAndInsertNew();
I test:
gemToBeExtracted == gemExtracted
gemInPositionTwo == gemFactory.getGemAt(0);
gemInPositionSix == gemFactory.getGemAt(4);
gemFactory.getGemAt(4).getTexture().getName() in (diamond, ruby, sapphire, emerald, topaz)
Hmmm, io farei cosi':
GemGenerator generator = new MockGemGenerator; // qui ci starebbe bene una classe anonima di Java (se esiste che non ricordo)
GemFactory gemFactory = new GemFactory(generator);
Gem gemExtracted = gemFactory.extractNextAndInsertNew(generator);
AssertEquals(generator.getAt(0), gemExtracted);
GemGenerator e' un'interfaccia di questo tipo:
interface GemGenerator
{
Gem extract();
}
In questo modo elimini i metodi pubblici getAt() da GemFactory che non hanno molto senso, perche' non fanno parte della sua interfaccia, ma servono solo per i test e li sposti nella classe MockGemGenerator che usiamo solo per i test.
Poi, volendo fare i precisi, GemFactory dovrebbe avere un altro nome, e GemGenerator e' la vera e propria GemFactory.
Possiamo farlo assieme se vuoi.
Nota come la confusione e' nata di nuovo dal fatto che GemFactory dovrebbe limitarsi solo a creare istance di una gemma (e' la sua responsabilita'), ma gli stiamo dando anche la responsabilita' di gestire la coda. Quindi la classe si sta dividendo fra due responsabilita' (creazione e gestione della coda) e non riesce a fare bene nessuna delle due. E ci crea problemi nel design.
Sta letteralmente urlando per essere divisa in due, ma un momento, abbiamo una classe chiamata GemQueue che si occupa... proprio di gestire una coda di gemme :)
E allora perche' non usare GemQueue per l'estrazione di una gemma e l'inserimento di una nuova e far tornare GemFactory alla sua sola responsabilita' originaria? Due concetti, due responsabilita', due classi.
Dimenticavo: un bel grazie a cionci che ha sacrificato il suo sonno per noi tutti. ;) grazie anche da parte mia :)
meno male che c'è gente come lui perché io non sarei mai stato in grado di preporre Diamonds al mio sonno... O.o'
a meno che non mi capiti uno di quei periodi di insonnia che odio: in tal caso posso anche andare a letto alle 7 del mattino e svegliarmi mezz'ora dopo -.-'
Daniele, che ne pensi di lavorare sabato pomeriggio subito dopo pranzo? dobbiamo essere *molto* veloci perché poi esco... :Prrr:
Sta letteralmente urlando per essere divisa in due, ma un momento, abbiamo una classe chiamata GemQueue che si occupa... proprio di gestire una coda di gemme :)
E allora perche' non usare GemQueue per l'estrazione di una gemma e l'inserimento di una nuova e far tornare GemFactory alla sua sola responsabilita' originaria? Due concetti, due responsabilita', due classi.
Infatti avevo realizzato GemQueue separata, ma GameGemFactory non faceva altro che chiamare solo metodi di GemQueue ed a quel punto le ho unite...
Se ti va bene possiamo farlo dopo la partita...verso le 10:30...
Chi si prenota per il 6.1.3, che è l'unico task ancora libero, e senza il quale non si può iniziare il quarto?
lo farei io se sapessi come si fa :D :Prrr:
lo farei io se sapessi come si fa :D :Prrr:
Idem... :muro:
Io mi metto a fare un po' di refactoring...e spero che fek sia d'accordo con la mia soluzione...altrimenti si fa un revert :D
sulla documentazione di LWJGL non avete trovato nulla? Credo che OpenGL fornisca già la funzione per moltiplicare una texture con un glColor o qualcosa del genere
ci stavo guardando proprio questa sera al 3(l'unico rimasto libero), giusto per prendere un po di dimestichezza col xp, e mi sono imbattuto anche io nel prob di cambiare colore alla texture; rovistando fra opengl.org e http://www.rush3d.com/reference/opengl-bluebook-1.0 alla fine ho trovato la funzione(o il gruppo) che potrebbe fare al caso.
glPixelTransferf e glPixelTransferi (cambia solo il dato passato) descritte qua
http://www.rush3d.com/reference/opengl-bluebook-1.0/ch05.html#id38440
ho gia provato scalando e funzia, ma forse si potrebbe utilizzare il bias(aggiungi invece che moltiplicare), ma in effetti la specifica del task indica proprio moltiplicare.
la pixeltranfer l'ho usata in Texture.setupOpenGLStates() dopo glTexImage2D(...)
spero di essere stato d'aiuto :)
cmq mi presento, sono fabio, sviluppo java su applicazioni web, e sono molto interessato a questo progetto. Finalmente ieri mattina dopo aver scaricato la nuova versione di eclipse, sono riuscito a far partire la build di ant(prima non andava.. facevo build ma non dava segni di vita), e spero di contribuire anche io a questo progetto.
ciao
ora ho pero un problema.
ho spostato la chiamata a pixeltranfer in enable(il metodo chiamato dall'engine), giusto per vedere se il giro funzionava, ma la trasformazione me la fa solo dal secondo giro(anche se lo metto in testa al metodo).
mi sa che ce da verificare il workflow del opengl, probabilmente la texture viene caricata in memoria prima, e solo alla seconda gemma si vede il risultato voluto..
risolto, basta chiamare setupOpenGLStates(); dopo avere fatto le pixeltrasfer
onestamente non so se sia il metodo giusto...
magari suddividendo la setupOpenglstates, si puo trovare un set minimo di istruzione opengl per rinfrescare la texture
Benbvenuto... Prova a fare un spike su questa cosa magari riesci ad individuare il set di istruzioni minimo...
Io mi metto a fare un po' di refactoring...e spero che fek sia d'accordo con la mia soluzione...altrimenti si fa un revert :D
Finito il refactoring... Date un'occhiata, sicuramente ora è tutto più pulito :)
6.1.2: ^TiGeRShArK^: completato
La casella dei punti non deve piu riportare il numero di gemme all'interno della griglia. Il nuovo valore è la somma dei punti che ogni singola gemma rappresenta. La tabella con i punti è la seguente:
diamond | ruby | sapphire | emerald | topaz
100 | 50 | 60 | 40 | 80
Ma amethist non rientra nelle gemme che useremo ?
Ma amethist non rientra nelle gemme che useremo ?
Quasi sicuramente no, dato che non possiamo permetterci di avere troppi tipi di gemme su schermo. Se poi alla fine vedremo che sarà troppo facile per l'utente creare grossi ammassi di gemme, e fare combo troppo lunghe, allora vedremo di introdurle (tanto sono già pronte, e le modifiche da fare al codice sarebbero minime).
Jocchan, prova a rimpire la griglia di gemme (ora sono tutte casuali)...
^TiGeRShArK^
02-12-2005, 09:06
ci stavo guardando proprio questa sera al 3(l'unico rimasto libero), giusto per prendere un po di dimestichezza col xp, e mi sono imbattuto anche io nel prob di cambiare colore alla texture; rovistando fra opengl.org e http://www.rush3d.com/reference/opengl-bluebook-1.0 alla fine ho trovato la funzione(o il gruppo) che potrebbe fare al caso.
glPixelTransferf e glPixelTransferi (cambia solo il dato passato) descritte qua
http://www.rush3d.com/reference/opengl-bluebook-1.0/ch05.html#id38440
ho gia provato scalando e funzia, ma forse si potrebbe utilizzare il bias(aggiungi invece che moltiplicare), ma in effetti la specifica del task indica proprio moltiplicare.
la pixeltranfer l'ho usata in Texture.setupOpenGLStates() dopo glTexImage2D(...)
spero di essere stato d'aiuto :)
cmq mi presento, sono fabio, sviluppo java su applicazioni web, e sono molto interessato a questo progetto. Finalmente ieri mattina dopo aver scaricato la nuova versione di eclipse, sono riuscito a far partire la build di ant(prima non andava.. facevo build ma non dava segni di vita), e spero di contribuire anche io a questo progetto.
ciao
ciao benvenuto...
io avevo visto gualcosa nel settare la modalità modulate della texture che moltiplica il colore della texture per il colore del poligono se nn ho capito male.
prova a darci un occhiata per lo spike e vedi se capisci qualcosa :D
http://fly.cc.fer.hr/~unreal/theredbook/chapter09.html
è nella sezione Modulating and Blending...
avevo provato ieri sera ma ero troppo fuso e non capivo niente :p
Perchè non provate voi due a fare il task in pair programming, visto che la cosa è meno semplice del previsto? ;)
Io mi metto a fare un po' di refactoring...e spero che fek sia d'accordo con la mia soluzione...altrimenti si fa un revert :D
L'ho guardato. E' un ottimo refactoring e apre la possibilita' a qualche altra semplificazione.
Guarda qui:
public Gem extract()
{
Gem gem = queue.extractFirst();
queue.fillQueueRandomly();
return gem;
}
Questo metodo manda due messaggi all'oggetto queue e poi nient'altro. Si chiama 'Features Envy' e si risolve con un Move Method. Quando sposti questo metodo in queue GameGemGenerator rimane un banale wrapper quindi... puoi eliminarlo e fai fuori una classe. Meno codice :)
E dopo i refactoring il codice ci ha letteralmente chiesto di farsi fattorizzare in questo modo.
Una piccola nota, nelle prime due tre storie vi svelo che io e Vicius praticamente riscrivevamo tutto il codice, mentre ormai non tocco quasi piu' nulla. Siete diventati bravissimi :D
ciao benvenuto...
io avevo visto gualcosa nel settare la modalità modulate della texture che moltiplica il colore della texture per il colore del poligono se nn ho capito male.
prova a darci un occhiata per lo spike e vedi se capisci qualcosa :D
http://fly.cc.fer.hr/~unreal/theredbook/chapter09.html
è nella sezione Modulating and Blending...
avevo provato ieri sera ma ero troppo fuso e non capivo niente :p
Questa e' la soluzione corretta. La nostra color equation per ora e' questa:
F = C * T
Dove F e' il colore finale su schermo, C e' un colore costante per primitiva (sprite) e T e' il colore della texture, per noi solo una.
E' il modo standard di fare il blending, per curiosita', la color equation che sto implementando ora, se scritta su carta, occuperebbe tre o quattro righe :D
Guarda qui:
public Gem extract()
{
Gem gem = queue.extractFirst();
queue.fillQueueRandomly();
return gem;
}
L'avevo visto...il problema è che GameGemGenerator (che chiamerei GameGemPicker se ti piace) deve mantenre l'interfaccia GemGenerator per poter implementare anche il mock MockGemGenerator...
Se faccio una modifica di questo tipo sono costretto a mettere tutti i metodi che gestiscono la coda privati (inq uesto caso nons arebbe testabile) oppure a duplicare l'interfaccia della coda su GemGenerator...
L'avevo visto...il problema è che GameGemGenerator (che chiamerei GameGemPicker se ti piace) deve mantenre l'interfaccia GemGenerator per poter implementare anche il mock MockGemGenerator...
Se faccio una modifica di questo tipo sono costretto a mettere tutti i metodi che gestiscono la coda privati (inq uesto caso nons arebbe testabile) oppure a duplicare l'interfaccia della coda su GemGenerator...
Non necessariamente, sposti il metodo extract() in GemQueue che implementa l'interfaccia e il resto rimane invariato.
Ho testato la build e ho notato che il meccanismo di randomizzazione a volte può far creare due o tre volte di fila gemme dello stesso tipo. Questo è un risultato corretto, ma in termini di gameplay ci conviene evitare che avvenga.
Per questo motivo, ho chiesto a Cionci una piccola aggiunta al suo task, cioè di aggiungere un if che eviti la creazione di una gemma uguale alla sua precedente nella coda.
La cosa richiede un test ed un paio di righe di codice ;)
Ho fatto il refactoring proposto da fek e ho modificato GemFactory per non estrarre due gemme uguali di fila...
Non è possibile testare quest'ultima cosa...quindi niente test per questa feature...
Ho fatto il refactoring proposto da fek e ho modificato GemFactory per non estrarre due gemme uguali di fila...
Non è possibile testare quest'ultima cosa...quindi niente test per questa feature...
E ti pare che non sia possibile testarlo? :)
Lo e'.
Regoletta: Tutto quello che pensi non sia possibile testare e' perche' non hai ancora trovato il modo per testarlo.
Regoletta: Tutto quello che pensi non sia possibile testare e' perche' non hai ancora trovato il modo per testarlo.
Allora diciamo che non ho ancora trovato il modo di testarlo...
L'unico modo per testarlo sarebbe di fare un mock per Random o suddividere il metodo ed estrarre un metodo checkIndex che ritorna l'indice incrementato se l'indice passato è uguale a quello precedente...
Ti suggerisco il test:
Interfaccia RandomNumberGenerator:
interface RandomNumberGenerator
{
int extract();
}
Implementi un Mock (di nuovo con inner class magari) che estrae tre numeri di cui i primi due uguali.
Il test sara' qualcosa del tipo:
GemGenerator generator = new ...
RandomNumberGenerator randomNumberGenerator = new MockRandomNumberGenerator(new int[] = {0, 0, 1} ); // non ricordo la sintassi corretta :p
Gem gem1 = generator.extract(randomNumberGenerator);
Gem gem2 = generator.extract(randomNumberGenerator);
AssertNotEquals(gem1, gem2);
Qualcosa di questo tipo, il generatore random restituisce i primi due numeri uguali, ma il tuo generatore di gemmi restituisce le prime due gemme comunque diverse.
Allora diciamo che non ho ancora trovato il modo di testarlo...
L'unico modo per testarlo sarebbe di fare un mock per Random o suddividere il metodo ed estrarre un metodo checkIndex che ritorna l'indice incrementato se l'indice passato è uguale a quello precedente...
Bingo! :)
Ma il mock...visto che in questo caso non è così semplice, va testato ?
public class MockRandomGenerator implements AbstractRandomGenerator
{
private int index;
private int numbers[];
public MockRandomGenerator(int numbers[])
{
index = -1;
this.numbers = numbers;
}
public int extract(int module)
{
index = (index + 1) % numbers.length;
return numbers[index] % module;
}
}
Ma il mock...visto che in questo caso non è così semplice, va testato ?
Il Mock e' testato dal test che lo usa.
Questa e' la soluzione corretta. La nostra color equation per ora e' questa:
F = C * T
Dove F e' il colore finale su schermo, C e' un colore costante per primitiva (sprite) e T e' il colore della texture, per noi solo una.
E' il modo standard di fare il blending, per curiosita', la color equation che sto implementando ora, se scritta su carta, occuperebbe tre o quattro righe :D
Visto che il task deve ancora partire è meglio chiarire anche il range di valore in ingresso alla funzione. il nostro T come lo vogliamo ?
Valori liberi? Da 0 a 1? da 1 a 255? ...
La piu correta mi sembra la seconda. Un bel double da 0 a 1. Voi che ne pensate?
ciao ;)
DanieleC88
02-12-2005, 12:33
Daniele, che ne pensi di lavorare sabato pomeriggio subito dopo pranzo? dobbiamo essere *molto* veloci perché poi esco... :Prrr:
Per me va benissimo! Allora ci vediamo sabato. ;)
La piu correta mi sembra la seconda. Un bel double da 0 a 1. Voi che ne pensate?
ciao ;)
Avevo pensato lo stesso, 0.0/1.0 permette di pensare molto più facilmente in termini di percentuale.
Btw, a che ci serve la precisione di un double? Basta un float. ;)
Visto che il task deve ancora partire è meglio chiarire anche il range di valore in ingresso alla funzione. il nostro T come lo vogliamo ?
Valori liberi? Da 0 a 1? da 1 a 255? ...
La piu correta mi sembra la seconda. Un bel double da 0 a 1. Voi che ne pensate?
ciao ;)
Da 0.00f a 2.00f (per componente) per fare over brighting.
^TiGeRShArK^
02-12-2005, 13:32
E' il modo standard di fare il blending, per curiosita', la color equation che sto implementando ora, se scritta su carta, occuperebbe tre o quattro righe :D
:confused:
questo mi sfugge... perchè su carta occuperebbe tre o quattro righe quest'equazione??? :fagiano:
io avevo trovato questa tabellina:
http://img525.imageshack.us/img525/1255/tabella7td.jpg (http://imageshack.us)
ma non ci ho capito una mazza tra l'altro :p
:confused:
questo mi sfugge... perchè su carta occuperebbe tre o quattro righe quest'equazione??? :fagiano:
E' qualcosa tipo (semplifico):
F = T * (L0 * S0 + L1 * S1 ... + Ln * Sn)
Dove T e' un'equazioncina con lightmap varie e texture base. Ln e' l'equazione per ogni luce (piu' o meno phong). S0 e' l'equazione per il calcolo della soft shadow per ogni luce. Ogni termine si espande. Oddio mi e' venuto mal di testa a pensarci.
^TiGeRShArK^
02-12-2005, 16:54
ah ecco capito :D
(+ o - .... :fagiano: )
Chi ha fatto l'ultimo commit? (Build 298)
Deve essere il commit relativo al refactoring di Grid per gestire gli eventi...
Oki.
Guardando il codice preferirei che spostassi il metodo createRandomGem() da GemFactory a GemQueue. Al di la' del nome, "sento" (non saprei spiegarlo meglio :p) che appartiene piu' alla seconda che alla prima.
Aspetta che faccio un commit con qualche refactoring prima.
Ma il task 3 alla fine lo ha preso qualcuno?
Ma il task 3 alla fine lo ha preso qualcuno?
Ancora nessuno. Volontario ? :D
ciao ;)
Io ci posso provare ma già con OpenGL ci ho lavorato pochissimo (giusto illuminazione flat/smooth e rendering di scene abbastanza semplici) e con le texture mai fatto niente :)
Leggo un po' di documentazione e vedo :p
io ci sto ancora guardando, per capire come fare il blending(anche se penso che in questo caso bisogna usare il modulate, fek confermi?)
da quello che ho capito, il modulate usa il valore del pixel della texture e quella del colore del texel, per cui il valore del texel diventerà la ns luminosità.
Ora sto facendo un po di prove, appena riesco a farlo funzionare vi faccio sapere(sempre che sia la strada giusta).
ps.non sono molto sicuro che quello che ho detto sia giusto...
cmq continuo a guardaci :)
Io ho cercato su alcuni forum e ho visto che un tizio voleva usare blending per un'operazione simile e gli han detto di usare modulate :)
Ok prendo il task 3, 1 giorno
thebol se vuoi collaborare contattami su MSN :)
questo task non lo voleva fare nessuno perché nessuno lo sapeva fare; io ho provato a fare un glColor3f subito dopo glBegin ma non cambiava nulla; secondo me ci voleva uno spike (cosa che ufo13 e thebol hanno fatto/stanno facendo).
la tua soluzione era parzialmente corretta:
dovevi settare GL_MODULATE
in OpenGL il colore dei vertici viene settato sul glColor corrente nel momento in cui fai il glVertex, quindi va fatto prima del glBegin :p
Ragazzi è sufficiente cambiare la seguente riga di Texture
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
in
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
In questo modo il colore della texture sarà modulato con quello dei vertici. Per cambiare il colore dei vertici bisogna aggiungere prima del glBegin una chiamata glColor3f(x,y,z) dove x,y,z sono i valori R G B di colore. Nel nostro caso, poiché vogliamo aumentare o diminuire la luminosità vanno assegnati tutti uguali con un valore compreso tra 0 e 1 in formato float.
Non è necessario usare la chiamata glPixelTransferi.
Fek devo capire una cosa... se imposto l'illuminazione così:
bright(2.0f, 2.0f, 2.0f)
la texture deve diventare completamente bianca?
Ragazzi è sufficiente cambiare la seguente riga di Texture
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
in
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
In questo modo il colore della texture sarà modulato con quello dei vertici. Per cambiare il colore dei vertici bisogna aggiungere prima del glBegin una chiamata glColor3f(x,y,z) dove x,y,z sono i valori R G B di colore. Nel nostro caso, poiché vogliamo aumentare o diminuire la luminosità vanno assegnati tutti uguali con un valore compreso tra 0 e 1 in formato float.
Non è necessario usare la chiamata glPixelTransferi.
In realtà no perchè settato così GL_MODULATE non permette overbright
In realtà no perchè settato così GL_MODULATE non permette overbright
Non ne sono convinto.... stanotte gli do un'occhiata va :D
Quando si iniziano ad usare gli shader ci si dimentica di come fare le cose semplici :sofico:
probabilmente ne sai + di me a riguardo però leggi qui:
http://216.239.59.104/search?q=cache:KYXkYdVKpiwJ:www.javagaming.org/cgi-bin/JGNetForums/YaBB.cgi%3Fboard%3Dcluebies%3Baction%3Ddisplay%3Bnum%3D1069431794+overbright+OpenGL+GL_MODULATE&hl=it
Non ne sono convinto.... stanotte gli do un'occhiata va :D
Quando si iniziano ad usare gli shader ci si dimentica di come fare le cose semplici :sofico:
confermo anche io...
su un forum sembra di capire che il problema sia che non usiamo l'illuminazione per cui dopo la trasformazione(modulazione) viene controllato se i valori RGB sono > di quelli della texture, e in questo caso mette quelli vecchi.
Infatti mettendo valori < 1 nel glColor3f l'immagine scurisce...
Usando invece lo scale a 2, il tutto funziona(con valori da 0 a 1, con 0.5 per non modificare la texture), perche i valori vengono successivamente moltiplicati per 2 e non vengono resettati a quelli di partenza della texture.
Ragazzi bisogna stare attenti ad usare estensioni diverse da OpenGL 1.1. Rischiamo di perdere la compatibilità con alcuni sistemi. Abbiamo in passato dovuto tagliare delle chiamate OpenGL 1.3 per questo motivo e quella estensione è stata inglobata proprio in OpenGL 1.3.
fek per il momento direi di evitare l'overbright o di trovare una tecnica alternativa (multipass di una stessa texture in blending? :D) che preservi la compatibilità.
fek per il momento direi di evitare l'overbright o di trovare una tecnica alternativa (<b>multipass di una stessa texture in blending</b>? :D) che preservi la compatibilità.
spiega :cool:
Ragazzi bisogna stare attenti ad usare estensioni diverse da OpenGL 1.1. Rischiamo di perdere la compatibilità con alcuni sistemi. Abbiamo in passato dovuto tagliare delle chiamate OpenGL 1.3 per questo motivo e quella estensione è stata inglobata proprio in OpenGL 1.3.
fek per il momento direi di evitare l'overbright o di trovare una tecnica alternativa (multipass di una stessa texture in blending? :D) che preservi la compatibilità.
Dovrebbe esserci un'estensione MODULATE2X che moltiplica il risultato per due (almeno in D3D mi sembra ci fosse).
Soluzione alternativa: si fa due passate della stessa texture, la prima in replace la seconda additive blending e si modulano entrambe per la meta' del valore di overbright passato in input. Quindi:
F = C/2 * T + C/2 * T
Se C = 1.0 diventa:
F = 0.5 T + 0.5 T = T
Se C = 2.0 diventa:
F = 1.0 T + 1.0 T = 2 T (overbright)
L'unita' di blending fara' il clamping per noi.
Tanto abbiamo fillrate da buttare :)
Dovrebbe esserci un'estensione MODULATE2X che moltiplica il risultato per due (almeno in D3D mi sembra ci fosse).
Soluzione alternativa: si fa due passate della stessa texture, la prima in replace la seconda additive blending e si modulano entrambe per la meta' del valore di overbright passato in input. Quindi:
F = C/2 * T + C/2 * T
Se C = 1.0 diventa:
F = 0.5 T + 0.5 T = T
Se C = 2.0 diventa:
F = 1.0 T + 1.0 T = 2 T (overbright)
L'unita' di blending fara' il clamping per noi.
Tanto abbiamo fillrate da buttare :)
il MODULATE2X cè, pero fa parte di un estensione, tale EXTTextureEnvCombine. E cmq si chiama RGB_SCALE_EXT, e si puo settare a 2 e 4.
Funziona (testato con ufo13), però è un estensione, non so se per voi è usabile.
è OpenGL 1.3 quindi non so... Ora vedo....
provo a fare come ha detto fek :)
hmmm fatto però ho un piccolo problema... Si notano leggermente i rectangle intorno alle gemme
la mia implementazione è molto semplice:
//disegna normalmente con GL_MODULATION
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
//ridisegna
glDisable(GL_BLEND)
Ho visto che andrebbe disabilitato il GL_DEPTH_TEST ma credo che non sia neanche abilitato :p (per sicurezza ho provato e non cambia nulla)
^TiGeRShArK^
03-12-2005, 21:50
cioè per rectangle intendi lo sfondo???:confused:
ah... forse ho capito..
in quel modo viene aumentata la luminosità anche del canale alpha..
quindi tutto quello che c'è sullo sfondo viene aumentato di luminosità...
dovreste applicare l'aumento di luminosità solo ai canali RGB credo ....
hmmm mi sembra strano perchè uso glColor3f... Ora guardo un po' :)
^TiGeRShArK^
03-12-2005, 22:10
novità?
Nada aspettavo di sapere qualcosa da fek o altri :p
Nada aspettavo di sapere qualcosa da fek o altri :p
Usa glColor4f e imposta il canale alpha sempre fisso a 0.5. Di default credo che sia 1.0 in OpenGL (sono un po' arrugginito). Dovrebbe andare cosi'.
Nota di contorno: ho fatto il commit del refactoring di Grid:
- ho spostato i key handler fuori da Grid
- ho aggiunto un'interfaccia per i key handler
- aggiunti due metodi per definire il comportamento alla pressione e al rilascio dei tasti
- spostata un po' di logica dai key handler di nuovo dentro Grid
La struttura dovrebbe essersi semplificata un po'. Grid ora e' piuttosto minimale, ma ci sono un certo numero di chiamate verso e dai key handler che offuscano un po' il flusso; non e' piu' troppo banale da seguire.
Usa glColor4f e imposta il canale alpha sempre fisso a 0.5. Di default credo che sia 1.0 in OpenGL (sono un po' arrugginito). Dovrebbe andare cosi'.
No, non funziona perche' la prima passata e' un blend. Domani mattina ci guardo un po'.
già fatto ma continua a non andare bene... Vuoi che ti metto una copia del codice di engine nel ignore? il Grid lo controllo subito così vedo cosa hai messo :p
p.s. non mi puoi addare su ICQ o venire su MSN un sec? :p
^TiGeRShArK^
03-12-2005, 22:42
ah ecco...
lo sapevo che c'entrava l'alpha..
ma nn avendo mai fatto niente di open gl, direct 3d e cose varie non ci sarei mai arrivato ke si doveva usare 4f anzikè 3f xkè il defaul viene messo a 1.0 anzikè a 0.5 :D
io di OpenGL prima ho fatto solo glVertex, trasformazioni vari, swap di buffers, illuminazione (roba semplice) e picking
Tutta sta roba non l'ho mai vista (texturing incluso) però prima o poi se ne viene fuori in qualche modo :D
BlueDragon
04-12-2005, 01:07
Io di OpenGL sono totalmente a digiuno... però facendo un tentativo ho trovato questo metodo statico: iluGammaCorrect(float gamma)
Chiamando questo metodo ad ogni pressione di tasto sinistro, riesco ad "illuminare" ogni gemma (e non il suo sfondo) che va a sinistra, ma solo dopo che ne siano andate a sinistra almeno sette (qualcosa a che vedere con la coda forse).
Nella mia ignoranza, subito dopo iluGammaCorrect(float gamma) chiamo setupOpenGLStates().... "così il metodo ha effetto", come era stato detto per un'altra soluzione vari post fa :)
Non so se tutto ciò vi possa essere utile o far venire in mente qualcosa... :)
Allora ragazzi ho studiato un po la situazione e l'unica soluzione che ho trovato senza utilizzare estensioni che vadano oltre l'OpenGL 1.1 è la seguente.
Si esegue una prima passata di rendering in con il seguente stato
glColor4f(1f,1f,1f,1f);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
che, essenzialmente, renderizza la scena come la conosciamo oggi. Dopodiché possiamo eseguire una seconda passata per ogni gemma che deve essere sovrailluminata (che poi quello che facciamo non c'entra na mazza con l'illuminazione :D) si esegue una seconda passata con il seguente stato:
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glColor4f(1f,1f,1f,valore_aggiuntivo);
La seconda passata è di tipo ADDITIVO, cioè prende i valori già presenti nel frame buffer (la destinazione è appunto GL_ONE) e li somma agli RGB che specifichiamo nella glColor4f moltiplicati per il valore alpha specificato nella stessa glColor4f. Cioè, in fin dei conti, se vogliamo una sovrailluminazione pari a 2 dobbiamo impostare il "valore_aggiuntivo" a 1, mentre se non vogliamo la sovrailluminazione la seconda passata può essere saltata o eseguita con valore_aggiuntivo a 0.
Ovviamente il tutto deve essere definito solo per le Gem e pertanto possono suggerire a chi se ne occuperà di realizzare una funzione di draw distinta per la Gem (non la stessa degli Sprite) e di eliminare la chiamata glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) da texture, mettendola sotto Gem e sotto Sprite in maniera da gestire il blending diversamente a seconda dell'oggetto disegnato.
Questa soluzione è abbastanza elegante, non è difficile da implementare e assicura la completa compatibilità che abbiamo vantato fino ad ora. Ovviamente è possibile implementare soluzioni più eleganti evitando la seconda passata, ma alla fine usiamo così poco di una scheda video che anche se emulata in software la doppia passata non dovrebbe rappresentare un problema velocistico.
Vifani ma come l'ho fatta io usando solo GL_ONE,GL_ONE non dovrebbe già andare bene?
Io di OpenGL sono totalmente a digiuno... però facendo un tentativo ho trovato questo metodo statico: iluGammaCorrect(float gamma)
Chiamando questo metodo ad ogni pressione di tasto sinistro, riesco ad "illuminare" ogni gemma (e non il suo sfondo) che va a sinistra, ma solo dopo che ne siano andate a sinistra almeno sette (qualcosa a che vedere con la coda forse).
Nella mia ignoranza, subito dopo iluGammaCorrect(float gamma) chiamo setupOpenGLStates().... "così il metodo ha effetto", come era stato detto per un'altra soluzione vari post fa :)
Non so se tutto ciò vi possa essere utile o far venire in mente qualcosa... :)
Il fatto è che aggiustando il gamma non puoi illuminare le gemme con un colore...
Vifani, la stessa cosa vale per la tua soluzione, va fatta una moltiplicazione texture x colore...
Questa soluzione è abbastanza elegante, non è difficile da implementare e assicura la completa compatibilità che abbiamo vantato fino ad ora. Ovviamente è possibile implementare soluzioni più eleganti evitando la seconda passata, ma alla fine usiamo così poco di una scheda video che anche se emulata in software la doppia passata non dovrebbe rappresentare un problema velocistico.
Fare una passata additiva con il solo alpha e' la stessa soluzione che ho pensato io mentre mi addormentavo (eh lo so, le idee migliori mi vengono prima di dormire o in bagno... ehm).
Ma ho avuto un'idea ancora piu' semplice che non richiede alcuna modifica al codice: Jocchan, ci prepari una texture per ogni gemma illuminata? Grazie :)
Problema risolto.
Semplicemente un'immagine più luminosa? Consideratelo fatto.
Semplicemente un'immagine più luminosa? Consideratelo fatto.
Si', per ogni diamante. Mettila pure nella stessa texture che contiene la gemma (e conterra' i vari frame in seguito immagino). Poi aggiustiamo le coordinate per la versione normale e sovrailluminata e mandiamo le coordinate che ci servono all'engine.
Pazienza se non possiamo illuminare la gemma con un colore preciso, quello era solo un di piu'.
Si', per ogni diamante. Mettila pure nella stessa texture che contiene la gemma (e conterra' i vari frame in seguito immagino). Poi aggiustiamo le coordinate per la versione normale e sovrailluminata e mandiamo le coordinate che ci servono all'engine.
Pazienza se non possiamo illuminare la gemma con un colore preciso, quello era solo un di piu'.
Argh, ho appena committato una cartella apposita con le texture illuminate :doh:
Un istante e rimedio :p
quindi il task è completato o cosa? :)
Se posso dire la mia a me non piace come soluzione... Era bello poter creare un effetto di illuminazione graduale per esempio...
Se posso dire la mia a me non piace come soluzione... Era bello poter creare un effetto di illuminazione graduale per esempio...
Sono d'accordo, comunque è una cosa che si può rimandare.
Dato che ora serve una temporanea sovrailluminazione, possiamo intanto inserire questa soluzione, e provvedere alle variazioni di illuminazione in seguito.
Il task, involontariamente, è completato.
L'unica cosa è che potrebbe rompersi la build, dato che le gemme ora saranno contenute in un file png 64x32, quindi per favore qualcuno provveda dato che sto per committare :p
Sono d'accordo, comunque è una cosa che si può rimandare.
Dato che ora serve una temporanea sovrailluminazione, possiamo intanto inserire questa soluzione, e provvedere alle variazioni di illuminazione in seguito.
Il task, involontariamente, è completato.
L'unica cosa è che potrebbe rompersi la build, dato che le gemme ora saranno contenute in un file png 64x32, quindi per favore qualcuno provveda dato che sto per committare :p
cioè hai creato delle texture "larghe" il doppio che contengono a sinistra gemma normale e a destra gemma illuminata?
cioè hai creato delle texture "larghe" il doppio che contengono a sinistra gemma normale e a destra gemma illuminata?
Esatto :)
quindi il task è completato o cosa? :)
Se posso dire la mia a me non piace come soluzione... Era bello poter creare un effetto di illuminazione graduale per esempio...
Ufo, You Aren't Gonna Need It.
La soluzione risolve il nostro problema, quindi va bene in quanto tale. Tutto cio' che possiamo aggiungere di piu' non ci serve per risolvere i nostri problemi odierni, al massimo ci potrebbe servire per risolvere problemi futuri. Ma... You Aren't Gonna Need It. Qualunque soluzione piu' complessa e flessibile si traduce in codice che noi scriviamo, paghiamo in termini di tempo, dobbiamo testare, paghiamo in termini di tempo, dobbiamo debuggare e mantenere, paghiamo in termini di tempo... ma non ci risolve alcun problema.
E' un mantra che in questo progetto devi seguire fedelmente. Tutte le volte che pensi "Si', ma se facessimo questo, allora ci servira' anche dopo.", alla fine del pensiero devi aggiungere "Ma non ne avremo bisogno quindi non lo facciamo".
se siete sicuri di voler adottare la soluzione della PNG singola con 2 versioni di gemme allora bisogna creare una drawQuad differente per gemme ed il resto...
Sono d'accordo, comunque è una cosa che si può rimandare.
Dato che ora serve una temporanea sovrailluminazione, possiamo intanto inserire questa soluzione, e provvedere alle variazioni di illuminazione in seguito.
Il task, involontariamente, è completato.
L'unica cosa è che potrebbe rompersi la build, dato che le gemme ora saranno contenute in un file png 64x32, quindi per favore qualcuno provveda dato che sto per committare :p
Ci serve ancora un po' di codice nella classe Sprite per usare la versione illuminata quando richiesto dal gioco. Ovviamente ci servono i test relativi. Si profila all'orizzonte un bell'Adapter Pattern, ma... You Aren't Gonna Need It. Ora voglio il codice piu' semplice possibile.
se siete sicuri di voler adottare la soluzione della PNG singola con 2 versioni di gemme allora bisogna creare una drawQuad differente per gemme ed il resto...
drawQuad() accetta un'area nella texture e una texture quindi non ha bisogno di modifiche secondo me.
Le modifiche sono nella draw() della classe Sprite che quando riceve una richiesta di illuminazione usa il secondo set di coordinate invece del primo.
Ufo, You Aren't Gonna Need It.
La soluzione risolve il nostro problema, quindi va bene in quanto tale. Tutto cio' che possiamo aggiungere di piu' non ci serve per risolvere i nostri problemi odierni, al massimo ci potrebbe servire per risolvere problemi futuri. Ma... You Aren't Gonna Need It. Qualunque soluzione piu' complessa e flessibile si traduce in codice che noi scriviamo, paghiamo in termini di tempo, dobbiamo testare, paghiamo in termini di tempo, dobbiamo debuggare e mantenere, paghiamo in termini di tempo... ma non ci risolve alcun problema.
E' un mantra che in questo progetto devi seguire fedelmente. Tutte le volte che pensi "Si', ma se facessimo questo, allora ci servira' anche dopo.", alla fine del pensiero devi aggiungere "Ma non ne avremo bisogno quindi non lo facciamo".
hmmm hai perfettamente ragione :)
Sono appena arrivato quindi probabilmente devo ancora capire molte cose ma ti spiego il mio punto di vista :)
Io vedo un task e se possibile cerco anche di capire perchè va fatto...
Questo task vuole illuminare una gemma giusto? La soluzione della PNG differente (quella più semplice) mi è venuta in mente subito ma funziona solo nel caso si volesse illuminare una gemma di "botto". Visto che però era richiesta una moltiplicazione ero convinto che aveste scelto di utilizzare tale operazione per implementare una cosa graduale.
Se mi dici che basta così sono d'accordo anche io che "I am not gonna need it" :)
Io vedo un task e se possibile cerco anche di capire perchè va fatto...
Questo task vuole illuminare una gemma giusto? La soluzione della PNG differente (quella più semplice) mi è venuta in mente subito ma funziona solo nel caso si volesse illuminare una gemma di "botto". Visto che però era richiesta una moltiplicazione ero convinto che aveste scelto di utilizzare tale operazione per implementare una cosa graduale.
Il nostro approccio a ogni task e' diverso: di fronte a un task noi pensiamo alla soluzione piu' semplice e veloce possibile per implementarlo. Perche' in fondo siamo pigri :)
Ho sbagliato io a nominare la moltiplicazione per un colore, pensavo a modulare la texture perche' implicitamente pensavo che il MODULATE_2X fosse supportato da OGL 1.1. Ho pensato troppo avanti e infatti hai visto i problemi che ha generato. Se io avessi pensato solo al codice strettamente necessario per risolvere il problema a quest'ora avremmo gia' finito :)
YAGNI e' un concetto davvero potente come vedi.
ok ho trovato un modo molto semplice... preparo test e faccio commit :)
ok ho trovato un modo molto semplice... preparo test e faccio commit :)
Prima i test, poi il codice e poi il commit. Scriviamo tutto strettamente test-driven e se non scrivi il codice test-driven me ne accorgo e la mannaia del revert cala impietosa :D
Puoi farci vedere i test prima?
Io ho fatto così:
studiato (mente + carta :p) la soluzione possibile, scritto il test, scritto il codice, ora faccio commit
Il test è:
public void testSetViewArea()
{
Rectangle newViewArea = new Rectangle(0, 0, texture.getWidth()/2, texture.getHeight());
sprite.setViewArea(newViewArea);
assertEquals("sprite viewArea is wrong", newViewArea, sprite.getViewArea());
}
cambiato leggermente il test :p
hmmm :p ho già capito...
rifattorizzo: riscrivo il test, riscrivo il codice giusto? :)
Vifani ma come l'ho fatta io usando solo GL_ONE,GL_ONE non dovrebbe già andare bene?
GL_ONE,GL_ONE non può funzionare perché assegna sia alla sorgente (cioè ciò che stai disegnando) che alla destinazione, cioè il frame buffer, un vettore (1,1,1,1). Cioè, essenzialmente, così non tieni più conto del canale alpha della texture e del canale alpha del framebuffer ed è per questo motivo che ti si vedeva il bordo del QUAD.
ok ho sistemato:
I test aggiunti sono:
// dentro it.diamonds.tests.engine.TestRectangle
public void testRectangleEquals()
{
Rectangle rectangle1 = new Rectangle(10, 10, 20, 25);
Rectangle rectangle2 = new Rectangle(10, 10, 20, 25);
Rectangle rectangle3 = new Rectangle(0, 5, 10, 15);
assertTrue("rectangle1 must equals rectangle2", rectangle1.equals(rectangle2));
assertTrue("rectangle1 must not equals rectangle3", !rectangle1.equals(rectangle3));
assertTrue("rectangle2 must not equals rectangle3", !rectangle2.equals(rectangle3));
}
e
// dentro it.diamonds.tests.engine.video.TestSprite
public void testSetViewArea()
{
Rectangle viewArea1 = new Rectangle(0, 0, texture.getWidth()/2, texture.getHeight());
Rectangle viewArea2 = new Rectangle(0, 0, texture.getWidth()/2, texture.getHeight());
sprite.setViewArea(viewArea1);
assertTrue("sprite viewArea is wrong", viewArea2.equals(sprite.getViewArea()));
}
Ho quindi aggiunto il metodo equals a Rectangle :)
hmmm :p ho già capito...
rifattorizzo: riscrivo il test, riscrivo il codice giusto? :)
Si'.
E quando fai il commit scrivi sempre il tuo nome e la descrizione di quello che hai fatto.
Io vedo tutto ;)
ok ho sistemato:
I test aggiunti sono:
Servono ancora i seguenti test per la fine del task:
- Quando lo Sprite e' illuminato, lo Sprite ritorna correttamente il suo stato "illuminato".
- Quando lo Sprite e' illuminato, Engine riceve il secondo set di coordinate e non il primo.
Si'.
E quando fai il commit scrivi sempre il tuo nome e la descrizione di quello che hai fatto.
Io vedo tutto ;)
nei commit comments? ok d'ora in poi lo ricorderò :p
Servono ancora i seguenti test per la fine del task:
- Quando lo Sprite e' illuminato, lo Sprite ritorna correttamente il suo stato "illuminato".
- Quando lo Sprite e' illuminato, Engine riceve il secondo set di coordinate e non il primo.
Hmm in realtà io penso che lo stato di illuminato o meno debba appartenere a Gem e non a Sprite... Hmmm la storia non indica che si debba illuminare una gemma?
Il fatto è questo:
non tutte le sprite prendono solo metà area quindi non posso dire (prendi la parte sinistra/destra del PNG) altrimenti sfalsa tutto!
riedit:
ok come non detto penso di poterlo fare :p
Hmm in realtà io penso che lo stato di illuminato o meno debba appartenere a Gem e non a Sprite...
Hmmm... si' e' ok. Usa Gem nei test di illuminazione.
nei commit comments? ok d'ora in poi lo ricorderò :p
Sii preciso nei commenti per favore, metti il tuo nome ed una descrizione di cio' che hai fatto. "Vedi topic" non e' un commento.
Ed ho visto che hai prima implementato il codice e poi i test. Sforzati di fare il contrario :)
no :p avevo messo una riga commentata per ricordarmi una cosa mentre studiavo il codice, poi ho salvato, poi ho fatto i test e poi ho implementato.
Io vedo tutto ;)
Dio Fek :ops2:
:rolleyes: Ho la strana impressione che troppo testing di BW2 fa male, molto male... :asd: :asd: :asd:
test list:
ho creato it.diamonds.tests.TestGem
public void testGemIsBrightened()
public void testGemIsDrawnCorrectly()
per implementare i test ho modificato MockEngine aggiungendo:
public Rectangle getTextureRect()
ho fatto il commit... Il task dovrebbe essere completo :)
ho fatto il commit... Il task dovrebbe essere completo :)
Si', visto, molto bene :)
ottimo, allora al + presto io e Daniele faremo l'ultimo task.
public void setBrightenedStatus(boolean brightened)
{
if(!brightened)
{
setViewArea(new Rectangle(0, 0, getTexture().getWidth()/2, getTexture().getHeight()));
}
else
{
setViewArea(new Rectangle(getTexture().getWidth()/2, 0, getTexture().getWidth(), getTexture().getHeight()));
}
this.brightened = brightened;
}
Riguardo a questo codice, non vi sembra che le chiamate al costruttore di Rectangle siano errate ?
Non dovrebbero essere così ?
new Rectangle(0, 0, getTexture().getWidth() / 2 - 1,
getTexture().getHeight() - 1)
e
new Rectangle(getTexture().getWidth() / 2, 0,
getTexture().getWidth() - 1, getTexture().getHeight() - 1)
scusa, torno da una giornataccia quindi forse sono un po' in panne :p
Davvero non capisco perchè dovrebbe essere height()-1
le texture coordinates sono queste:
float u0 = textureRect.left() / texture.getWidth();
float v0 = textureRect.top() / texture.getHeight();
float u1 = textureRect.right() / texture.getWidth();
float v1 = textureRect.bottom() / texture.getHeight();
quindi viene preso da 0.0 a 1.0 in altezza
in larghezza per quella normale da 0.0 a 0.5 e per quella illuminata da 0.5 a 1.0 :p
Perchè se fai i calcoli vengono questi valori:
new Rectangle(0, 0, 32, 32)
new Rectangle(32, 0, 64, 64)
Invece dovrebbe essere:
new Rectangle(0, 0, 31, 31)
new Rectangle(32, 0, 63, 63)
anche perchè il pixel (orizzontale o verticale) 64 è al di fuori della texture...
Inoltre impostandoli così:
new Rectangle(0, 0, 32, 32)
il rettangolo è 33x33 e non 32x32...
Il costruttore di Rectangle è:
public Rectangle(float left, float top, float right, float bottom)
io lo chiamo con i parametri:
normale: (0, 0, 32, 32)
illuminata: (32, 0, 64, 32)
float u0 = textureRect.left() / texture.getWidth();
float v0 = textureRect.top() / texture.getHeight();
float u1 = textureRect.right() / texture.getWidth();
float v1 = textureRect.bottom() / texture.getHeight();
La texture ha width=64 ed height=32
I punti per le texture coords vengono presi così:
caso normale:
u0 = 0.0;
v0 = 0.0;
u1 = 0.5;
v1 = 1.0;
caso illuminato:
u0 = 0.5;
v0 = 0.0;
v1 = 1.0;
v1 = 1.0;
Un punto nella mappatura delle texture è identificato da 2 float che vanno da 0.0 a 1.0
float u0 = textureRect.left() / texture.getWidth();
float v0 = textureRect.top() / texture.getHeight();
float u1 = textureRect.right() / texture.getWidth();
float v1 = textureRect.bottom() / texture.getHeight();
Infatti secondo me questo codice dovrebbe essere così:
float u0 = textureRect.left() / texture.getWidth() - 1;
float v0 = textureRect.top() / texture.getHeight() - 1;
float u1 = textureRect.right() / texture.getWidth() - 1;
float v1 = textureRect.bottom() / texture.getHeight() - 1;
Concordi che i rectangle sono 33x33 pixel ?
Quindi c'è qualcosa che non va...
Una texture se è 64x32 puoi numerare i pixel orizzontali da 0 a 63, mentre quelli verticali da 0 a 31, quindi passando 64 in orizzontale o 32 in verticale si va fuori dalla texture...
Io credo che così vada bene... u0, v0, u1, v1 a mio parere vengono presi in modo corretto :)
Poi se fosse come dici tu le gemme ora apparirebbero con il bordo nero spesso il doppio sul lato destro e (non avrò sta gran vista magari :p) non mi pare sia così...
Allora...anche il discorso che ho fatto io non va bene, ma è comunque concettualmente sbagliato l'uso di rectangle in quel modo...
Inoltre u0,v0,u1,v1 dovrebbero essere molto più autoesplicative...
Capisco che debbano variare fra 0 e 1 a seconda delle coordinate, ma il concetto di rectangle e di view area deve lavorare in pixel...ed in questo caso non lo fa perchè altrimenti il rectangle dovrebbe essere di 32x32...
A me non dispiace la viewArea fatta così... Dopotutto potersi evitare quei -1 è una gran bella cosa direi :p
A me non dispiace la viewArea fatta così... Dopotutto potersi evitare quei -1 è una gran bella cosa direi :p
Ma come dicevo è un concetto errato... E' come dire che Rectangle non lavora in pixel...
Ma poi scusami prova a vedere sta cosa:
public float getWidth()
{
return right - left;
}
public float getHeight()
{
return bottom - top;
}
se (right = 32) e (left = 0) -> getWidth() ritorna 32
stessa cosa per getHeight()
E' concettualmente sbagliato...
se (right = 32) e (left = 0) -> getWidth() ritorna 32
stessa cosa per getHeight()
Dovrebbe tornare 33...
Cioè, mi spiego... E' giusto se si ragiona in float, ma è errato se si ragiona in pixel...
dalle ore 00:00 alle ore 01:00 quindi passa un'ora ed un secondo? :p
Sentiamo cosa dice fek...
dalle ore 00:00 alle ore 01:00 quindi passa un'ora ed un secondo? :p
Ripeto...numerami i pixel di un'immagine... L'immagine è 640 per 480...
Voui visualizzare l'immagine orizzontalmente dal pixel 0 al pixel 639 e verticalmente dal pixel 0 al pixel 479... In questo caso nel rectangle devi passare 0,0,640,480...
Ha senso ?
In realtà nonostante tutto io capisco il tuo punto di vista ma la classe rectangle tra le altre cose è definita in float quindi sarebbe sbagliato utilizzarla come dici tu.
Il rectangle (se prendesse quattro interi) più piccolo che si potrebbe fare come dici tu sarebbe un pixel:
(0, 0, 0, 0) che nonostante tutto avrebbe width = height = 1
(0, 0, 0, 0) così come è adesso avrebbe width = height = 0
Secondo me non è male... è bello ragionare in termini + matematici che informatici a mio avviso e poi il rectangle così fatto è anche + versatile se devo essere onesto
Ripeto...numerami i pixel di un'immagine... L'immagine è 640 per 480...
Voui visualizzare l'immagine orizzontalmente dal pixel 0 al pixel 639 e verticalmente dal pixel 0 al pixel 479... In questo caso nel rectangle devi passare 0,0,640,480...
Ha senso ?
Capisco davvero cosa vuoi dire ma perchè devi ragionare per forza in stile array?
Non ricordo chi fu a dire questa frase che mi è sempre rimasta impressa:
"sono tre le cose più importanti nell'informatica: astrazione, astrazione ed astrazione" :p
Non ricordo chi fu a dire questa frase che mi è sempre rimasta impressa:
"sono tre le cose più importanti nell'informatica: astrazione, astrazione ed astrazione" :p
Perchè se io setto la viewArea di una texture voglio ragionare in pixel e non in float...
In realtà nonostante tutto io capisco il tuo punto di vista ma la classe rectangle tra le altre cose è definita in float quindi sarebbe sbagliato utilizzarla come dici tu.
Certo...concordo... Quindi o bisogna rifare la Rectangle in int o non bisogna usare la Rectangle...
Se volessi cambiare le cose per metterle come vuoi tu allora sì, dovresti probabilmente cambiare Rectangle e di conseguenza tutti i posti in cui viene utilizzata a partire da engine.drawQuad(...)
Se volessi cambiare le cose per metterle come vuoi tu allora sì, dovresti probabilmente cambiare Rectangle e di conseguenza tutti i posti in cui viene utilizzata a partire da engine.drawQuad(...)
oppure semplicemente non fare la chiamata a setViewArea con Rectangle...
Io credo che così vada bene... u0, v0, u1, v1 a mio parere vengono presi in modo corretto :)
Poi se fosse come dici tu le gemme ora apparirebbero con il bordo nero spesso il doppio sul lato destro e (non avrò sta gran vista magari :p) non mi pare sia così...
La versione di Cionci e' piu' corretta perche' nello spazio della texture non normalizzato le coordinate vanno da 0 a width-1. In realta' per noi non cambia nulla perche' la GPU fa automaticamente il clamping a 1.0 delle coordinate e poi fa il sampling della texture al centro dell'ultimo texel che corrisponde a qualcosa tipo floor(u * width).
Certo...concordo... Quindi o bisogna rifare la Rectangle in int o non bisogna usare la Rectangle...
Secondo me Rectangle dovrebbe essere int. Ragioniamo sempre in termini di pixel e non in coordinate normalizzate.
hmm quindi Refactoring moment? :p
hmm quindi Refactoring moment? :p
Sì...sono partito... Speriamo che non sia così lungo :)
Non dovrebbe :p
Comunque mi rimane ancora un piccolo dubbio:
Le texture coordinates normalizzate va bene quindi definirle, ad esempio, per una texture 32x32:
larghezza da 0.0f a 31f/32f?
Le coordinate normalizzate vanno definite solo in drawQuad... Ora ci lavoro...
No io parlavo di OpenGL in generale :)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.