[d3d]disegnare solo quello che vede la telecamera

Argomenti riguardanti il D3D di GameMaker e librerie esterne.
Rispondi
Avatar utente
mac12
Membro d'elite
Messaggi: 1124
Iscritto il: 18/09/2012, 17:32
Specialità: programmazione
Uso: GameMaker 8.1
Contatta:

[d3d]disegnare solo quello che vede la telecamera

Messaggio da mac12 »

Mi chiedevo se disegnare solo quello che vede la telecamera aumentasse le prestazioni, se si qual'è il codice per farlo?

Avatar utente
enick
GMI VIP
Messaggi: 3749
Iscritto il: 26/06/2011, 19:34
Specialità: 39dll e 3D
Località: Sardegna
Contatta:

Re: [d3d]disegnare solo quello che vede la telecamera

Messaggio da enick »

mac12 ha scritto:Mi chiedevo se disegnare solo quello che vede la telecamera aumentasse le prestazioni, se si qual'è il codice per farlo?
la logica è:

if (controllo_dentro_visuale)
{
draw
}

io, utilizzavo una semplice collisione rettangolare 2d (dato che era un tds), dovresti spiegare meglio il tuo caso.
Nicola porcu(Sardegna)
ImmagineImmagine
Immagine
Are you sleeping?
[email protected]

Avatar utente
mac12
Membro d'elite
Messaggi: 1124
Iscritto il: 18/09/2012, 17:32
Specialità: programmazione
Uso: GameMaker 8.1
Contatta:

Re: [d3d]disegnare solo quello che vede la telecamera

Messaggio da mac12 »

if (controllo_dentro_visuale)
{
draw
}
questo lo so anch'io, quello che non so è come farlo
dovresti spiegare meglio il tuo caso.
il mio è un gioco spaziale 3d

Jak
Admin
Messaggi: 12355
Iscritto il: 19/08/2009, 16:20
Specialità: Programmazione 3D
Uso: GM:Studio 2
Contatta:

Re: [d3d]disegnare solo quello che vede la telecamera

Messaggio da Jak »

http://en.wikipedia.org/wiki/Hidden_sur ... ermination
In particolare la parte del "Viewing frustum culling"
E' una tecnica che migliora parecchio le prestazioni, specialmente parlando di game maker dove le draw calls ti fanno invecchiare.
In genere basta immaginarlo come un cono più che come un trapezoide, determina un'angolo di visuale(lo devi indicare nella proiezione quindi meglio di così...) e controlla se gli oggetti stanno al di fuori di questo angolo di visuale con 2 if.
Time to feel, time to believe
Dare to see what may come of our future
Lift your head, broaden your gaze
Speak your mind and your thoughts they will follow you

Avatar utente
mac12
Membro d'elite
Messaggi: 1124
Iscritto il: 18/09/2012, 17:32
Specialità: programmazione
Uso: GameMaker 8.1
Contatta:

Re: [d3d]disegnare solo quello che vede la telecamera

Messaggio da mac12 »

Jak ha scritto:http://en.wikipedia.org/wiki/Hidden_sur ... ermination
In particolare la parte del "Viewing frustum culling"
E' una tecnica che migliora parecchio le prestazioni, specialmente parlando di game maker dove le draw calls ti fanno invecchiare.
In genere basta immaginarlo come un cono più che come un trapezoide, determina un'angolo di visuale(lo devi indicare nella proiezione quindi meglio di così...) e controlla se gli oggetti stanno al di fuori di questo angolo di visuale con 2 if.
ho capito che per essere visibile l'oggetto deve essere "dentro" il cono che parte dalla posizione della telecamera, il difficile è calcolare le altre coordinate in base alla direzione.

Jak
Admin
Messaggi: 12355
Iscritto il: 19/08/2009, 16:20
Specialità: Programmazione 3D
Uso: GM:Studio 2
Contatta:

Re: [d3d]disegnare solo quello che vede la telecamera

Messaggio da Jak »

mac12 ha scritto:il difficile è calcolare le altre coordinate in base alla direzione.
Non ti seguo. Usa point_direction() e confronta gli angoli con qualche if.
Forse non ottimizzerai alla perfezione ma fai un bel lavoro con poco tempo di calcolo usato.
Time to feel, time to believe
Dare to see what may come of our future
Lift your head, broaden your gaze
Speak your mind and your thoughts they will follow you

Avatar utente
mac12
Membro d'elite
Messaggi: 1124
Iscritto il: 18/09/2012, 17:32
Specialità: programmazione
Uso: GameMaker 8.1
Contatta:

Re: [d3d]disegnare solo quello che vede la telecamera

Messaggio da mac12 »

Jak ha scritto: Usa point_direction()
Non lo conosco(forse è per questo che non ci riesco).
l'ho Imparato e dopo essermi scervellato per un ora e aver fatto una cinquantina di prove, ho creato questo codice

Codice: Seleziona tutto

a=point_direction(personaggio.x,personaggio.y,x,y)
b=personaggio.direction-90
c=point_direction(personaggio.x,personaggio.y,x,y)
d=personaggio.direction+90
if a>=b
if c<=d
{
draw
}
non funziona molto bene quando si cambia direction(ad esempio la direction era 0, ti giri un attimo e diventa 359).
Ma per il resto va alla grande.

PS
Ho usato le variabili a b c d per poter confrontare i risultati con il debug.
Ultima modifica di mac12 il 07/12/2012, 13:36, modificato 1 volta in totale.

Jak
Admin
Messaggi: 12355
Iscritto il: 19/08/2009, 16:20
Specialità: Programmazione 3D
Uso: GM:Studio 2
Contatta:

Re: [d3d]disegnare solo quello che vede la telecamera

Messaggio da Jak »

Vero, usare gli if basandosi sull'angolo lasciano sempre quell'angolo "cieco" ottenendo non pochi problemi quando l'angolo 0 è visualizzato dalla telecamera.
Una buona soluzione è quella di effettuare due tipi di controllo diversi.
Immaginiamo di visualizzare tutto dall'alto(2d per comodità, poi in 3d il concetto è lo stesso) e:

-Prima di tutto un'if per verificare se l'angolo formato col lato sinistro rispetto al cono è minore o maggio dell'angolo del lato destro.
-Se il cono è puntato verso l'alto l'angolo cieco non è visualizzato nella camera e l'angolo sinistro è maggiore dell'angolo destro, in questo caso esegui l'if controllando se un determinato punto è minore del sinistro e maggiore del destro.
-Se nel cono è invece presente l'angolo cieco "0" allora otteniamo che il lato sinistro ha un'angolo minore di quello destro, a questo punto si effettua lo stesso if ma usando un'or anzichè un'and.

Un'altro consiglio che ti do è proprio quello di usare gli operatori booleani && (and) e || (or) piuttosto di annidamenti di if senza parentesi come hai fatto tu. Ti consiglio di leggerti il manuale su essi.
Time to feel, time to believe
Dare to see what may come of our future
Lift your head, broaden your gaze
Speak your mind and your thoughts they will follow you

Avatar utente
mac12
Membro d'elite
Messaggi: 1124
Iscritto il: 18/09/2012, 17:32
Specialità: programmazione
Uso: GameMaker 8.1
Contatta:

Re: [d3d]disegnare solo quello che vede la telecamera

Messaggio da mac12 »

migliorato il codice, ora gestisce anche l'asse z:

Codice: Seleziona tutto

draw1=0
draw2=0

p_direction=point_direction(personaggio.x,personaggio.y,x,y)
b=personaggio.direction-90
d=personaggio.direction+90
z_direction=point_direction(personaggio.x,personaggio.z,x,z)
e=personaggio.zdirection-90
f=personaggio.zdirection+90

if b<0
b+=360

if d>360
d-=360


if d>b
{
if p_direction>=b
if p_direction<=d
{
draw1=1
}
}
else
{
if p_direction>=b or p_direction<=d
{
draw1=1
}
}
//direction
if e<0
e+=360

if f>360
f-=360

if f>e
{
if z_direction>e
if z_direction<f
{
draw2=1
}
}
else
{
if z_direction>e or z_direction<f
{
draw2=1
}
}
//zdirection

if draw1=1
if draw2=1
{
//draw
}



Migliorato ancora il codice e messo sotto forma di script:

Codice: Seleziona tutto

/*d3d_draw_enter_camera(personaggio,x_min,y_min,z_min,x_max,y_max,z_max)
if draw=0
exit

blocca l'evento draw dell'evento se l'ggetto non si vede nella telecamera.
indicare la grandezza dell'oggetto mettendo le sue coordinate negli altri
argomenti.*/

draw1=0
draw2=0

p_direction1=point_direction(argument0.x,argument0.y,argument1,argument2)
p_direction2=point_direction(argument0.x,argument0.y,argument4,argument5)
b=argument0.direction-90
d=argument0.direction+90
z_direction1=point_direction(argument0.x,argument0.z,argument1,argument3)
z_direction2=point_direction(argument0.x,argument0.z,argument1,argument6)
e=argument0.altezza-90
f=argument0.altezza+90

if b<0
b+=360

if d>360
d-=360


if d>b
{
if (p_direction1>=b && p_direction1<=d) or (p_direction2>=b && p_direction2<=d)
{
draw1=1
}
}
else
{
if (p_direction1>=b or p_direction1<=d) or (p_direction2>=b or p_direction2<=d)
{
draw1=1
}
}
//direction
if e<0
e+=360

if f>360
f-=360

if f>e
{
if (z_direction1>e && z_direction1<f) or (z_direction2>e && z_direction2<f)
{
draw2=1
}
}
else
{
if (z_direction1>e or z_direction1<f) or (z_direction2>e or z_direction2<f)
{
draw2=1
}
}
//zdirection

if draw1=1 && draw2=1
draw=1
else
draw=0
la miglioria sta nel fatto che bisogna mettere anche la coordinate iniziali e finali perchè su oggetto giganteschi dava problemi.

Rispondi

Chi c’è in linea

Visitano il forum: Nessuno e 28 ospiti