El primer pas per a obtindre el modelatge d’un objecte consisteix en definir objectes de revolució.
Un objecte de revolució el definim amb un perfil i l’eix sobre el que gira el perfil. En el nostre cas, l’eix de revolució serà sempre l’eix ‘Y’ i el perfil el definirem com una funció que ens tornarà el valor de ‘X’ per als valors de ‘Y’ entre l’interval [-0.5, 0.5].
Gràficament la idea seria la següent:
Per exemple, per a modelar un cilindre la funció que haurem d’utilitzar serà la de la recta, i obtindriem un objecte de revolució com aquest:
Per a obtindre l’anterior objecte de revolució hem utilitzat el següent codi:
Els objectes es dibuixen com un conjunt d’anells, i el radi de cada anell depèn de l’altura a la que es dibuixe. Depenent de la funció particular que ens torne el valor del radi com a funció de l’altura obtindrem unes figures o unes altres.
D’aquesta manera, anem a analitzar una mica de codi, que és el que realment ens interessa. El que anem a analitzar es troba en el fitxer modelado.c.
En primer lloc, el codi que dibuixa la figura de revolució és el següent:
/*--------------------------------------------------------------------------
Algorisme de dibuix per a la figura de revolució
H: altura de la figura
N: nombre d'anells i divisions en cada anell
--------------------------------------------------------------------------*/
void formaAlambre(float H, int N, float(*f)(float y)) {
int i;
float y, r;
for(i = 0; i < N; i++) { // per a cada nivell d'altura
y = i*H/N-(H/2);
r = f(y); // obtenim el radi
anillo(r, y, N); // i dibuixem un anell
}
}
Per a canviar l'altura o el nombre d'anells només haurem de canviar els valors de H i N respectivament.
El codi que ens definix el perfil, és a dir, la figura de revolució que anem a obtindre, és el següent:
float fCilindro(float y) {
return(0.5); // funció lineal
}
Per a obtindre un con només haurem de canviar aquest codi pel següent:
float fCon(float y) {
return ((y+0.5f)/2); //funció del con
}
O una esfera:
float fEsfera(float y) {
return((float)sqrt(fabs(0.25-(y*y)))); // funció de l'esfera
}
Buy Viagra Professional Online Pharmacy No Prescription Needed href="http://cdecdf.com/blog/wp-content/grafica/2/esfera.png" target="_blank">
Podem provar diferents codis per a obtindre diferents figures geomètriques, com per exemple:
float f1(float y) {
return((float)sqrt(fabs((((0.4-sqrt(fabs((0.04)-(0.25))))*(0.4-sqrt(fabs((0.04)-(0.25)))))-(y*y)))));
}
float f2(float y) {
return((float)sqrt(((0.015-(0.25-(sqrt(fabs(0.25+(y*y)))))*(0.25-(sqrt(fabs(0.25+(y*y))))))*(0.015-(0.25-(sqrt(fabs(0.25+(y*y)))))*(0.25-(sqrt(fabs(0.25+(y*y)))))))));
}
float f3(float y) {
return((float)sqrt(fabs(((0.5)*(0.5))-((y-0.4)*(y-0.4)))));
}
És senzill veure que les tres figures anteriors tenen diferent nombre d'anells que les primeres; simplement modificant el nombre d'anells (valor de N) podem obtindre objectes com aquestos:
Amb 50 anells:
Amb 100 anells:
Amb 1000 anells:
Podreu comprovar que el temps de resposta és molt diferent a l'executar aquestes figures canviant el nombre d'anells, sempre depenent del vostre hardware.
Per a accelerar aquest temps d'execució quan tenim molts objectes, OpenGL ens proporciona les llistes de visualització, una espècie de macros on podem emmagatzemar la geometria dels objectes que anem a dibuixar en la nostra escena, entre d'altres.
Encara que no anem a entrar en detalls sobre açò, un exemple d'utilització seria aquest:
escenario = glGenLists(1); /* Solicitamos un identificador */
if(escenario != 0) { /* es valido si distinto de 0 */
glNewList(escenario, GL_COMPILE); /* Inicia la definicion */
escena(); /* nuestros objetos */
glEndList(); /* finaliza la definición */
}
I per a dibuixar un objecte a través d'aquesta llista, utilitzariem:
glCallList(escenario);








