OpenGL ES ne dispose pas de GLU, qui est une bibliothèque d'utilitaires disponibles en OpenGL régulière. Parmi les nombreuses choses que GLU fournit un tas de méthodes pour le rendu des formes primitives comme les cylindres et des sphères, qui peut être vraiment pratique. Les mathématiques derrière le calcul de ces formes procédure peut être un peu hallucinante, surtout si vous êtes nouveau sur le tout en 3D.
Je travaille actuellement sur la partie 5 de l'OpenGL ES à partir du sol pour la série, qui est sur les matériaux. Je n'étais pas heureux avec l'aide de l'icosaèdre que j'avais été à l'aide pour les quatre premiers épisodes de la série. L'interaction entre les lumières et les matériaux sur l'icosaèdre n'a tout simplement pas montrer la composante spéculaire d'une manière qui est assez évidente. La forme idéale pour montrer une hightlight spéculaire est, bien sûr, une sphère.
Alors, j'ai décidé de rendre une sphère en OpenGL ES, qui s'est avéré être loin d'être aussi simple que j'ai pensé qu'il pourrait être. Pour l'instant, le code est un peu rude sur les bords, mais il fonctionne, et vous permet de spécifier une "résolution" en termes de nombre de «tranches» et de «piles» qui composent la sphère. Ces fondamentalement juste définir le nombre de sommets il ya latitudinalement et longitudinalement. Pensez à une orange. Si vous la coupez avec un couteau à la verticale, ce sont des "tranches". Si nous le couper à l'horizontale, ce sont "piles". Eh bien, pas exactement, sauf si vos courbes couteau au bon angle, mais c'est une bonne analogie assez.
Comme vous pouvez le voir sur cette illustration, les tranches de plus en piles que vous avez, votre sphère lisse ressemble. Mais, les tranches de plus en piles que vous avez, plus la puissance de traitement de votre sphère utilise. Le nombre de sommets augmente exponentiellement à mesure que vous augmentez le nombre de pile / tranche.

Trois sphères créés avec ce code, l'un avec 8 tranches et des piles (à gauche), l'un avec 25 tranches et des piles (au milieu) et une avec 50 tranches et des piles (à droite).
En ce moment, ce code se présente sous la forme d'un plutôt effrayant prospectifs (mais bien commenté et tout à fait attrayant à la recherche) C-fonction qui prend quatre poignées, deux pointeurs, deux entiers non signés, et un flotteur.
Mon plan est d'envelopper tout cela dans une belle Objective-C de classe à un certain moment dans le futur pas trop à distance de sorte qu'il sera plus facile à utiliser, mais je ne sera probablement pas à ce droit de suite. Donc, puisque je figure qu'il doit y avoir d'autres personnes là-bas qui ont besoin de sphères ou sont curieux de voir comment ils pourraient se faire, je poste une exemple de projet avec mon code sphère rugueuse que vous pouvez regarder pour voir comment il fonctionne.
Puisque ces deux ensembles de sommets doivent être soumis à OpenGL séparément, il était logique de ne pas les combiner en un seul tableau. Afin de travailler avec des lumières et des ombres lisses, la fonction calcule également les normales pour ces deux tableaux - qui représente les deux autres manches.
Les deux pointeurs sont des variables qui, en retour, permettra d'identifier le nombre de sommets dans le tableau triangle de la bande de vertex et le module de refroidissement sommet de triangle.
Enfin, il ya un GLfloat qui est utilisé pour spécifier la taille de la sphère, et deux GLuints de spécifier le nombre de piles et de tranches. Vous aurez probablement presque toujours intérêt à utiliser le même nombre de piles et de tranches, mais j'ai gardé les séparer au cas où.
Pour utiliser cette fonction, vous devez déclarer quelques variables. Dans les projets de l'échantillon, ils sont variables d'instance du contrôleur de vue:
Ces valeurs sont répercutés dans le comme ceci:
Vous n'avez pas à allouer de la mémoire pour les sommets ou les normales. BUT vous ne devez libérer la mémoire lorsque vous avez terminé, comme ceci:
Enfin, voici comment vous dessinez la sphère en utilisant les valeurs renvoyées par getSolidSphere ():
C'est tout ce qu'il ya à faire. Je vais utiliser ce code dans le prochain blog OpenGL affichage afin que nous puissions parler de l'éclairage et le matériel, même si je n'aurai probablement pas arriver à ce qu'après le week-end. Je pars pour un long week-end et ma femme ne me laisse pas mettre mon ordinateur.
Permettez-moi avertir encore une fois que ce code n'est probablement pas une bonne solution pour tout ce qui doit courir vite en temps réel sur le téléphone avec éclairage spéculaire fort. Je vais probablement ajouter la possibilité de remplir un éventail de coordonnées de texture à cette fonction à un moment donné, ce qui va le rendre plus adapté aux programmes en temps réel. Comme toujours, utilisez à vos propres risques, il n'existe aucune garantie, patati. Vous connaissez le refrain.
Je travaille actuellement sur la partie 5 de l'OpenGL ES à partir du sol pour la série, qui est sur les matériaux. Je n'étais pas heureux avec l'aide de l'icosaèdre que j'avais été à l'aide pour les quatre premiers épisodes de la série. L'interaction entre les lumières et les matériaux sur l'icosaèdre n'a tout simplement pas montrer la composante spéculaire d'une manière qui est assez évidente. La forme idéale pour montrer une hightlight spéculaire est, bien sûr, une sphère.
Alors, j'ai décidé de rendre une sphère en OpenGL ES, qui s'est avéré être loin d'être aussi simple que j'ai pensé qu'il pourrait être. Pour l'instant, le code est un peu rude sur les bords, mais il fonctionne, et vous permet de spécifier une "résolution" en termes de nombre de «tranches» et de «piles» qui composent la sphère. Ces fondamentalement juste définir le nombre de sommets il ya latitudinalement et longitudinalement. Pensez à une orange. Si vous la coupez avec un couteau à la verticale, ce sont des "tranches". Si nous le couper à l'horizontale, ce sont "piles". Eh bien, pas exactement, sauf si vos courbes couteau au bon angle, mais c'est une bonne analogie assez.
Comme vous pouvez le voir sur cette illustration, les tranches de plus en piles que vous avez, votre sphère lisse ressemble. Mais, les tranches de plus en piles que vous avez, plus la puissance de traitement de votre sphère utilise. Le nombre de sommets augmente exponentiellement à mesure que vous augmentez le nombre de pile / tranche.

En ce moment, ce code se présente sous la forme d'un plutôt effrayant prospectifs (mais bien commenté et tout à fait attrayant à la recherche) C-fonction qui prend quatre poignées, deux pointeurs, deux entiers non signés, et un flotteur.
// =========================================================
void getSolidSphere(Vertex3D **triangleStripVertexHandle, // Will hold vertices to be drawn as a triangle strip.
// Calling code responsible for freeing if not NULL
Vector3D **triangleStripNormalHandle, // Will hold normals for vertices to be drawn as triangle
// strip. Calling code is responsible for freeing if
// not NULL
GLuint *triangleStripVertexCount, // On return, will hold the number of vertices contained in
// triangleStripVertices
// =========================================================
Vertex3D **triangleFanVertexHandle, // Will hold vertices to be drawn as a triangle fan. Calling
// code responsible for freeing if not NULL
Vector3D **triangleFanNormalHandle, // Will hold normals for vertices to be drawn as triangle
// strip. Calling code is responsible for freeing if
// not NULL
GLuint *triangleFanVertexCount, // On return, will hold the number of vertices contained in
// the triangleFanVertices
// =========================================================
GLfloat radius, // The radius of the circle to be drawn
GLuint slices, // The number of slices, determines vertical "resolution"
GLuint stacks // the number of stacks, determines horizontal "resolution"
// =========================================================
)Mon plan est d'envelopper tout cela dans une belle Objective-C de classe à un certain moment dans le futur pas trop à distance de sorte qu'il sera plus facile à utiliser, mais je ne sera probablement pas à ce droit de suite. Donc, puisque je figure qu'il doit y avoir d'autres personnes là-bas qui ont besoin de sphères ou sont curieux de voir comment ils pourraient se faire, je poste une exemple de projet avec mon code sphère rugueuse que vous pouvez regarder pour voir comment il fonctionne.
Note: J'ai été conseillé par quelqu'un de beaucoup plus intelligent sur OpenGL que je suis qui souligne par vertex spéculaire »ressemble ass totale" sauf si vous avez une maille ultra-dense, où vous pouvez voir dans la capture d'écran la plus à gauche ci-dessus. En général, ce code n'est probablement pas bien adapté pour une utilisation dans un jeu ou une application où les performances en temps réel est essentielle si vous utilisez une forte éclairage spéculaire. Mais il fonctionne très bien pour montrer les effets des paramètres d'éclairage et le matériel en OpenGL ES, surtout lorsqu'il est exécuté dans le simulateur où nous avons la puissance de traitement pour épargnerLa sphère est construite à partir d'une bande de triangle et d'un ventilateur triangle, si une poignée que vous passez dans peuplées obtient par la méthode avec les données de vertex pour la bande de triangle, l'autre avec les données de vertex pour les fans triangle.
Puisque ces deux ensembles de sommets doivent être soumis à OpenGL séparément, il était logique de ne pas les combiner en un seul tableau. Afin de travailler avec des lumières et des ombres lisses, la fonction calcule également les normales pour ces deux tableaux - qui représente les deux autres manches.
Les deux pointeurs sont des variables qui, en retour, permettra d'identifier le nombre de sommets dans le tableau triangle de la bande de vertex et le module de refroidissement sommet de triangle.
Enfin, il ya un GLfloat qui est utilisé pour spécifier la taille de la sphère, et deux GLuints de spécifier le nombre de piles et de tranches. Vous aurez probablement presque toujours intérêt à utiliser le même nombre de piles et de tranches, mais j'ai gardé les séparer au cas où.
Pour utiliser cette fonction, vous devez déclarer quelques variables. Dans les projets de l'échantillon, ils sont variables d'instance du contrôleur de vue:
Vertex3D *sphereTriangleStripVertices;
Vector3D *sphereTriangleStripNormals;
GLuint sphereTriangleStripVertexCount;
Vertex3D *sphereTriangleFanVertices;
Vector3D *sphereTriangleFanNormals;
GLuint sphereTriangleFanVertexCount;Ces valeurs sont répercutés dans le comme ceci:
getSolidSphere(&sphereTriangleStripVertices,
&sphereTriangleStripNormals,
&sphereTriangleStripVertexCount,
&sphereTriangleFanVertices,
&sphereTriangleFanNormals,
&sphereTriangleFanVertexCount,
1.0,
50,
50);
Vous n'avez pas à allouer de la mémoire pour les sommets ou les normales. BUT vous ne devez libérer la mémoire lorsque vous avez terminé, comme ceci:
if(sphereTriangleStripVertices)
free(sphereTriangleStripVertices);
if (sphereTriangleStripNormals)
free(sphereTriangleStripNormals);
if (sphereTriangleFanVertices)
free(sphereTriangleFanVertices);
if (sphereTriangleFanNormals)
free(sphereTriangleFanNormals);Enfin, voici comment vous dessinez la sphère en utilisant les valeurs renvoyées par getSolidSphere ():
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, sphereTriangleFanVertices);
glNormalPointer(GL_FLOAT, 0, sphereTriangleFanNormals);
glDrawArrays(GL_TRIANGLE_FAN, 0, sphereTriangleFanVertexCount);
glVertexPointer(3, GL_FLOAT, 0, sphereTriangleStripVertices);
glNormalPointer(GL_FLOAT, 0, sphereTriangleStripNormals);
glDrawArrays(GL_TRIANGLE_STRIP, 0, sphereTriangleStripVertexCount);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);C'est tout ce qu'il ya à faire. Je vais utiliser ce code dans le prochain blog OpenGL affichage afin que nous puissions parler de l'éclairage et le matériel, même si je n'aurai probablement pas arriver à ce qu'après le week-end. Je pars pour un long week-end et ma femme ne me laisse pas mettre mon ordinateur.
Permettez-moi avertir encore une fois que ce code n'est probablement pas une bonne solution pour tout ce qui doit courir vite en temps réel sur le téléphone avec éclairage spéculaire fort. Je vais probablement ajouter la possibilité de remplir un éventail de coordonnées de texture à cette fonction à un moment donné, ce qui va le rendre plus adapté aux programmes en temps réel. Comme toujours, utilisez à vos propres risques, il n'existe aucune garantie, patati. Vous connaissez le refrain.
Aucun commentaire:
Enregistrer un commentaire