PDA

View Full Version : [CICLO 6] Storia 1


Jocchan
27-11-2005, 22:01
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

VICIUS
29-11-2005, 17:31
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 ;)

71104
29-11-2005, 18:29
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

VICIUS
29-11-2005, 18:30
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 ;)

71104
29-11-2005, 18:39
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:

cionci
29-11-2005, 21:54
Potresti usare questo metodo per fare i confronti:

gem.getTexture().equals(new Texture(nome_della_gemma))

cionci
29-11-2005, 21:57
Anzi...mi sa che così non funziona... Credo per problemi di confronto fra due buffer...

71104
29-11-2005, 23:25
infatti non funzionerebbe di sicuro perché la nostra classe Texture non overridda il metodo equals... la comparazione risulterebbe sempre falsa...

cionci
29-11-2005, 23:29
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:

cionci
30-11-2005, 08:11
Io mi prenoto per il 6.1.5...2 giorni a partire da quando 71104 ha terminato il suo task

fek
30-11-2005, 09:55
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.

fek
30-11-2005, 09:56
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'.

cionci
30-11-2005, 10:21
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...

cionci
30-11-2005, 11:13
Mi sa che ho semplificato notevolmente tutto... Ho aggiunto una classe GemQueue... Basta che GameGemFactory e GemFactoryForTesting la istanzino...

fek
30-11-2005, 11:31
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?

cionci
30-11-2005, 11:37
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...

fek
30-11-2005, 12:15
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.

cionci
30-11-2005, 12:33
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");
}

71104
30-11-2005, 12:39
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

fek
30-11-2005, 12:41
3)

71104
30-11-2005, 12:59
task 6.1.1 committato.

cionci
30-11-2005, 14:02
Committato task 6.1.5

fek
30-11-2005, 14:03
fate troppo veloci... teeeeeeest list prima :D

fek
30-11-2005, 14:04
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.

Ufo13
30-11-2005, 14:22
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ì?

cionci
30-11-2005, 14:50
fate troppo veloci... teeeeeeest list prima :D
L'ultimo post della pagina precedente ;)

cionci
30-11-2005, 15:00
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...

Ufo13
30-11-2005, 15:21
Grazie per la risposta ora mi è tutto più chiaro :)

71104
30-11-2005, 16:12
ehm, ragazzi, siccome il mio task era molto semplice potrei prenotarmi anche per il pair programming del 6.1.4? ^^'

























( :Perfido: :Perfido: :Perfido: )

Ufo13
30-11-2005, 16:17
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

fek
30-11-2005, 17:14
L'ultimo post della pagina precedente ;)

Visto ora :D

Ufo13
30-11-2005, 17:56
hmm allora prendo il task 6, 2 giorni (domani non ci sono :D)

71104
30-11-2005, 18:08
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 :)

fek
30-11-2005, 18:11
perché alle ultime ore ho programmazione a oggetti che seguo poco (:p :p :p)

Perche' fai gia' quella lezione qua :p

71104
30-11-2005, 18:17
Perche' fai gia' quella lezione qua :p l'hai detto!!! :D
e faccio pure Ingegneria del Software :D

Ufo13
30-11-2005, 19:32
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?

cionci
30-11-2005, 19:56
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)...

Ufo13
30-11-2005, 20:42
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)

Ufo13
30-11-2005, 21:42
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)...

Ufo13
30-11-2005, 22:10
ok, commit eseguito :p

fek
30-11-2005, 22:18
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 :)

Ufo13
30-11-2005, 22:21
hehe bello vedere che funziona :p, cmq avevo controllato 2 volte con ant :D

VICIUS
30-11-2005, 22:24
4 task completati in poco piu di un giorno. Siete dei mostri :D

ciao ;)

fek
30-11-2005, 22:28
Fate update prima di ricominciare a scrivere codice che ho fatto parecchio refactoring.

fek
30-11-2005, 22:38
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?

fek
30-11-2005, 22:41
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.

fek
30-11-2005, 22:41
E sta a vedere che non vado a rompere la build io perche' non ho lanciato Ant... 1 pound.

cionci
01-12-2005, 00:53
Sì è mio... Ci penso io... Infatti mi sembrava che mancasse qualcosa...

cionci
01-12-2005, 02:04
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"...

cionci
01-12-2005, 02:07
Come dicevo...si è appunto ripresentato il problema dell'audio... La build è rotta per quello...

cionci
01-12-2005, 02:14
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...

cionci
01-12-2005, 08:18
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

fek
01-12-2005, 09:00
Eroico, grazie :D

Jocchan
01-12-2005, 09:01
Grandissimo Cionci :cincin:

VICIUS
01-12-2005, 09:13
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 ;)

cionci
01-12-2005, 09:15
: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: )

cionci
01-12-2005, 09:19
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...

Ufo13
01-12-2005, 12:49
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. ;)

cionci
01-12-2005, 13:29
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...

fek
01-12-2005, 13:52
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

cionci
01-12-2005, 14:03
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)

fek
01-12-2005, 16:00
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.

71104
01-12-2005, 19:43
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:

cionci
01-12-2005, 20:09
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...

Jocchan
01-12-2005, 22:09
Chi si prenota per il 6.1.3, che è l'unico task ancora libero, e senza il quale non si può iniziare il quarto?

71104
01-12-2005, 22:29
lo farei io se sapessi come si fa :D :Prrr:

cionci
01-12-2005, 22:43
lo farei io se sapessi come si fa :D :Prrr:
Idem... :muro:

cionci
01-12-2005, 22:59
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

Ufo13
01-12-2005, 23:00
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

thebol
01-12-2005, 23:05
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

thebol
01-12-2005, 23:21
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..

thebol
01-12-2005, 23:42
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

cionci
01-12-2005, 23:45
Benbvenuto... Prova a fare un spike su questa cosa magari riesci ad individuare il set di istruzioni minimo...

cionci
01-12-2005, 23:54
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 :)

cionci
02-12-2005, 00:11
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 ?

Jocchan
02-12-2005, 08:24
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).

cionci
02-12-2005, 08:42
Jocchan, prova a rimpire la griglia di gemme (ora sono tutte casuali)...

Jocchan
02-12-2005, 09:02
Ok :D

^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

Jocchan
02-12-2005, 09:08
Perchè non provate voi due a fare il task in pair programming, visto che la cosa è meno semplice del previsto? ;)

fek
02-12-2005, 09:34
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

fek
02-12-2005, 09:37
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

cionci
02-12-2005, 09:39
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...

fek
02-12-2005, 09:46
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.

Jocchan
02-12-2005, 09:47
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 ;)

cionci
02-12-2005, 10:59
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...

fek
02-12-2005, 11:12
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.

cionci
02-12-2005, 11:19
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...

fek
02-12-2005, 11:19
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.

fek
02-12-2005, 11:22
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! :)

cionci
02-12-2005, 11:32
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;
}
}

fek
02-12-2005, 11:46
Ma il mock...visto che in questo caso non è così semplice, va testato ?

Il Mock e' testato dal test che lo usa.

cionci
02-12-2005, 12:09
Fatto

fek
02-12-2005, 12:15
Visto. Perfetto :)

VICIUS
02-12-2005, 12:27
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. ;)

fek
02-12-2005, 12:52
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

Ufo13
02-12-2005, 14:25
La pic non va :p

fek
02-12-2005, 14:44
: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: )

fek
02-12-2005, 19:06
Chi ha fatto l'ultimo commit? (Build 298)

cionci
02-12-2005, 19:18
Deve essere il commit relativo al refactoring di Grid per gestire gli eventi...

fek
02-12-2005, 20:17
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.

Ufo13
03-12-2005, 01:02
Ma il task 3 alla fine lo ha preso qualcuno?

VICIUS
03-12-2005, 10:45
Ma il task 3 alla fine lo ha preso qualcuno?
Ancora nessuno. Volontario ? :D

ciao ;)

Ufo13
03-12-2005, 10:48
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

thebol
03-12-2005, 10:53
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 :)

Ufo13
03-12-2005, 10:56
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 :)

Ufo13
03-12-2005, 12:11
Ok prendo il task 3, 1 giorno

thebol se vuoi collaborare contattami su MSN :)

71104
03-12-2005, 12:50
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).

Ufo13
03-12-2005, 12:54
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

Vifani
03-12-2005, 14:34
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.

Ufo13
03-12-2005, 14:36
Fek devo capire una cosa... se imposto l'illuminazione così:

bright(2.0f, 2.0f, 2.0f)

la texture deve diventare completamente bianca?

Ufo13
03-12-2005, 14:43
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

Vifani
03-12-2005, 16:22
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:

Ufo13
03-12-2005, 16:29
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

thebol
03-12-2005, 16:31
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.

Vifani
03-12-2005, 16:42
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à.

thebol
03-12-2005, 17:09
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:

fek
03-12-2005, 17:20
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 :)

thebol
03-12-2005, 17:44
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.

Ufo13
03-12-2005, 18:03
è OpenGL 1.3 quindi non so... Ora vedo....

Ufo13
03-12-2005, 18:27
provo a fare come ha detto fek :)

Ufo13
03-12-2005, 20:01
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 ....

Ufo13
03-12-2005, 21:58
hmmm mi sembra strano perchè uso glColor3f... Ora guardo un po' :)

^TiGeRShArK^
03-12-2005, 22:10
novità?

Ufo13
03-12-2005, 22:23
Nada aspettavo di sapere qualcosa da fek o altri :p

fek
03-12-2005, 22:36
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.

fek
03-12-2005, 22:38
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'.

Ufo13
03-12-2005, 22:38
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

Ufo13
03-12-2005, 22:44
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... :)

Vifani
04-12-2005, 01:27
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.

Ufo13
04-12-2005, 08:45
Vifani ma come l'ho fatta io usando solo GL_ONE,GL_ONE non dovrebbe già andare bene?

Ufo13
04-12-2005, 08:47
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...

fek
04-12-2005, 10:04
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.

Jocchan
04-12-2005, 10:08
Semplicemente un'immagine più luminosa? Consideratelo fatto.

fek
04-12-2005, 10:11
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'.

Jocchan
04-12-2005, 10:21
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

Ufo13
04-12-2005, 10:23
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...

Jocchan
04-12-2005, 10:32
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

Ufo13
04-12-2005, 10:35
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?

Jocchan
04-12-2005, 10:37
cioè hai creato delle texture "larghe" il doppio che contengono a sinistra gemma normale e a destra gemma illuminata?

Esatto :)

fek
04-12-2005, 10:39
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".

Ufo13
04-12-2005, 10:40
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...

fek
04-12-2005, 10:40
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.

fek
04-12-2005, 10:41
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.

Ufo13
04-12-2005, 10:46
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" :)

fek
04-12-2005, 11:12
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.

Ufo13
04-12-2005, 11:31
ok ho trovato un modo molto semplice... preparo test e faccio commit :)

fek
04-12-2005, 11:34
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?

Ufo13
04-12-2005, 11:48
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

Ufo13
04-12-2005, 11:56
hmmm :p ho già capito...


rifattorizzo: riscrivo il test, riscrivo il codice giusto? :)

Vifani
04-12-2005, 12:05
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.

Ufo13
04-12-2005, 12:13
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 :)

fek
04-12-2005, 12:14
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 ;)

fek
04-12-2005, 12:16
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.

Ufo13
04-12-2005, 12:16
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

Ufo13
04-12-2005, 12:18
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

fek
04-12-2005, 12:22
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.

fek
04-12-2005, 12:25
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 :)

Ufo13
04-12-2005, 12:33
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.

cover
04-12-2005, 13:16
Io vedo tutto ;)

Dio Fek :ops2:

:rolleyes: Ho la strana impressione che troppo testing di BW2 fa male, molto male... :asd: :asd: :asd:

Ufo13
04-12-2005, 13:32
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()

Ufo13
04-12-2005, 13:40
ho fatto il commit... Il task dovrebbe essere completo :)

fek
04-12-2005, 13:59
ho fatto il commit... Il task dovrebbe essere completo :)

Si', visto, molto bene :)

71104
04-12-2005, 14:21
ottimo, allora al + presto io e Daniele faremo l'ultimo task.

cionci
05-12-2005, 16:57
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)

Ufo13
05-12-2005, 22:30
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

cionci
05-12-2005, 23:38
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...

Ufo13
06-12-2005, 00:14
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

cionci
06-12-2005, 00:23
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...

cionci
06-12-2005, 00:27
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...

Ufo13
06-12-2005, 08:12
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ì...

cionci
06-12-2005, 08:12
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...

Ufo13
06-12-2005, 08:20
A me non dispiace la viewArea fatta così... Dopotutto potersi evitare quei -1 è una gran bella cosa direi :p

cionci
06-12-2005, 08:22
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...

Ufo13
06-12-2005, 08:27
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()

cionci
06-12-2005, 08:27
E' concettualmente sbagliato...

cionci
06-12-2005, 08:29
se (right = 32) e (left = 0) -> getWidth() ritorna 32
stessa cosa per getHeight()
Dovrebbe tornare 33...

cionci
06-12-2005, 08:31
Cioè, mi spiego... E' giusto se si ragiona in float, ma è errato se si ragiona in pixel...

Ufo13
06-12-2005, 08:32
dalle ore 00:00 alle ore 01:00 quindi passa un'ora ed un secondo? :p

cionci
06-12-2005, 08:33
Sentiamo cosa dice fek...

cionci
06-12-2005, 08:36
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 ?

Ufo13
06-12-2005, 08:39
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

Ufo13
06-12-2005, 08:42
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

cionci
06-12-2005, 08:43
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...

cionci
06-12-2005, 08:45
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...

Ufo13
06-12-2005, 08:59
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(...)

cionci
06-12-2005, 09:02
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...

fek
06-12-2005, 09:15
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).

fek
06-12-2005, 09:16
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.

Ufo13
06-12-2005, 09:33
hmm quindi Refactoring moment? :p

cionci
06-12-2005, 09:40
hmm quindi Refactoring moment? :p
Sì...sono partito... Speriamo che non sia così lungo :)

Ufo13
06-12-2005, 09:50
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?

cionci
06-12-2005, 10:35
Le coordinate normalizzate vanno definite solo in drawQuad... Ora ci lavoro...

Ufo13
06-12-2005, 10:42
No io parlavo di OpenGL in generale :)