OpenGL Terrain Generation - An Introduction




 

Introduction

NOTE: Pour la version HTML de ce lien avec des graphiques et des téléchargements s'il vous plaît visitez le lien suivant:

http://www.codeproject.com/opengl/OPENGLTG.asp

J'ai toujours été intéressé à l'infographie et de leurs applications. Représentation et visualisation des données est l'un des principaux domaines d'HCI (Human Computer Interaction), et mieux vous rendre l'interaction entre une machine et un humain, la productivité plus seront générés par l'humain et la machine. J'ai eu une certaine expérience avec OpenGL pendant mes études de premier cycle tout en assistant à la California Polytechnic University. Malheureusement, je n'ai jamais eu la chance de poursuivre des fonctionnalités les plus avancées de la bibliothèque OpenGL, compte tenu de mon temps et mes responsabilités professionnelles.

Vous pouvez trouver plus sur OpenGL au http://www.opengl.org. Il ya aussi un tas de bonne littérature disponible sur le thème de l'informatique graphique et OpenGL, que vous pouvez consulter des nouveaux progrès pour. S'il vous plaît vérifier l'information / Section de référence pour une liste de quelques documents de référence que j'ai utilisée, en général, pour l'infographie.

Le projet suivant est un exemple très simple montre comment générer un terrain basé sur un fichier bitmap. L'objectif du projet est de générer un terrain en trois dimensions basé sur certains fichier de données. S'il vous plaît noter que cela aurait pu être n'importe quel fichier de données, mais dans le but de notre exemple, nous allons utiliser un fichier bitmap 32x32 dimensions. Nous aurions pu facilement utilisé un fichier texte, et la logique définie pour chaque mot ou une lettre à la représenter graphiquement.

Le projet comporte également un bon cadre de Windows qui peut être utilisé pour vos autres applications OpenGL. Le projet actuel permet de faire pivoter l'appareil en utilisant votre souris.

Une fois encore, il s'agit d'une approche simple de génération de terrains, ce qui peut être une tâche très difficile dans des environnements complexes.

Contexte / Référence
Depuis Computer Graphics est en quelque sorte d'un sujet de pointe, il est nécessaire d'avoir au moins un roi de la compréhension et l'exposition à des concepts et des théories sur le terrain. Toutefois, cela ne signifie pas que vous ne serez pas en mesure d'utiliser le code suivant ou comprendre. Je l'ai rendu aussi simple que possible et, espérons-le, il vous donnera un bon départ, ou une autre source d'information supplémentaire que vous pouvez utiliser pour vos projets. Aussi, s'il vous plaît noter que vous aurez besoin d'avoir une bonne connaissance de C / C + + programming.

Quelques livres que j'ai utilisé pour apprendre l'informatique graphique et la programmation OpenGL:

Livres que j'ai utilisé alors qu'il assistait à la California Polytechnic University:
OpenGL Programming Guide, ou mieux connaître le livre rouge.
Infographie Utiliser OpenGL, 2nd Edition.
Livres que j'ai utilisé alors qu'il assistait à la California Lutheran University:
OpenGL: un premier ministre, 2nd Edition.
Interactive Computer Graphics: A Top-Down Approach En utilisant OpenGL, 4th Edition.

Qu'est-ce qu'un terrain?

Quelques informations de base sur un terrain et de leurs utilisations dans une application de jeu: Un terrain dans un environnement est l'un des composants les plus critiques de la scène qui est rendue. Elle pourrait facilement être le plus grand objet 3D dans le projet. Rendu le terrain peut devenir une tâche ardue, en prenant le plus de temps à rendre dans une scène. Pour garder le moteur de terrain en cours d'exécution en temps réel peut être une tâche difficile, et nécessite une réflexion sur les processus et la modélisation pour qu'elle soit suffisante.

Pour être efficace, le terrain doit respecter un certain nombre d'exigences, dont beaucoup peuvent être contradictoires. Un terrain ne doit apparaître comme continue à l'utilisateur final, mais le maillage doit être simplifiée ou ont été abattus, si possible, de réduire la charge sur la carte graphique.

Dans un système de jeu, par exemple, certains moteurs de tirer le terrain juste après le point, un joueur peut atteindre, et ensuite utiliser un terrain dessiné sur une skybox pour simuler des collines ou des montagnes au loin. Le terrain devrait semblent réalistes au réglage pour l'environnement, mais cela peut être lourd sur la carte vidéo, et un équilibre doit être maintenu. Textures de détails sont souvent utilisés à proximité de la caméra, permettant au plus loin des zones devant être rendues plus rapidement.

Qu'est-ce qu'une Carte?

La première chose nécessaire pour le rendu du terrain est une représentation de la forme du relief's. Bien qu'il existe un certain nombre de structures qui peuvent être utilisés pour effectuer le travail, le plus largement utilisé est la carte de hauteur. D'autres initiatives comprennent: NURBS, ce qui peut être maintenu par un certain nombre de points de contrôle, et voxels, qui permettent de les surplombs et les grottes.

Il ya un inconvénient à une carte de hauteur, et qui est, pour chaque point de la XZ-plan, il ne peut y avoir qu'une seule valeur de hauteur. Vous pouvez voir que cela limite la représentation des surplombs et les grottes d'une carte de hauteur. On peut y remédier en utilisant deux modèles distincts.

Un autre inconvénient est que des cartes d'élévation de prendre une grande quantité de mémoire, comme chaque hauteur doit être représenté. D'autre part, des cartes d'élévation se prêtent à la création de maillages réguliers facilement. Il est également facile de déterminer la hauteur à un endroit donné, ce qui est utile pour éviter les collisions en le terrain ainsi que la pose des ombres dynamiques sur le terrain.

Une carte de taille est représenté par un tableau 2D de valeurs, où pour tout point (X, Y, Z), X et Z sont les indices dans le tableau, et la valeur du tableau est la valeur Y, qui est équivalente à la hauteur de la valeur.

Ce qui suit est un exemple d'une telle représentation:

int hauteur [5] [5] = (

(0, 0, 1, 1, 2),

(0, 1, 2, 2, 3),

(0, 1, 3, 2, 3),

(0, 1, 2, 1, 2),

(0, 0, 1, 1, 1));

L'approche!

Il existe de nombreux algorithmes avancés pour générer des terrains, je me sers d'une solution très simple dans le but de ce projet.

En bref, j'ai utilisé une image bitmap 32 x 32 niveaux de gris pour représenter un taille-champ qui est utilisé pour générer le terrain. Le terrain est divisé en une grille de valeurs de hauteur, dont le résultat est un maillage représentant le terrain de la scène.

Nous créons une grille de sommets qui sont également espacées, mais ont des hauteurs variables, basée sur la hauteur des données sur le terrain. La valeur de couleur de chaque bit est utilisé pour déterminer la valeur de hauteur de chaque cellule du maillage, dans ce cas, pour une image bitmap 24 bits en niveaux de gris, les valeurs de la gamme de couleur de 0 à 255.

Une fois le bitmap a été lu et les valeurs chargé en mémoire, nous avons les données nécessaires pour représenter le relief. Nous utilisons également une variable appelée MAP_SCALE pour nous permettre de l'échelle de la carte vers le haut ou le bas. Il s'agit d'un facteur d'échelle, nous utilisons cette option pour régler la distance entre chaque sommet hauteur. Cela nous permet d'augmenter ou de diminuer la taille du terrain.

Lorsque nous attribuons effectivement les coordonnées des sommets de chaque cellule du maillage, nous avons besoin d'appliquer le facteur MAP_SCALE, qui est en multipliant l'indice de localisation basé sur la grille de coordonnées élément, à savoir:

Terrain [X] [Z] [0] = float (X) * MAP_SCALE;

Terrain [X] [Z] [1] = (float) imageData [(Z * MAP_SCALE + X) * 3];

Terrain [X] [Z] [2] = float (Z) * MAP_SCALE;

La carte de terrain est représentée dans une grille de valeurs de hauteur, qui est stockée en interne dans un tableau 2D des coordonnées des sommets. Elle s'étend le long de l'axe X et l'axe Z, avec l'axe Y représente la hauteur du terrain.

Pour rendre la carte de terrain, nous utilisons GL_TRIANGLE_STRIP pour chaque rangée de la grille des valeurs le long de l'axe Z. Afin de rendre le terrain correctement, nous devons spécifier le point dans un ordre spécifique.

Cela nous oblige à commencer par la fin de la ligne et se déplacer le long du X positive de l'axe en tirant les sommets dans un schéma Z:

(*)==========>(*)

/

/

/

/

/

/

/

/

/

/

/
(*)=========>(*) ....

Utilisation du Code

Je ne répertorie que le code qui traite de la génération de terrains ici. Il ya plus de code dans le projet que vous pouvez regarder. Il est bien documenté, ainsi vous ne devriez pas avoir de problèmes. La solution a été compilée à partir de MS Visual Studio 2003, vous devriez donc être en mesure de compiler et d'exécuter facilement. Vous aurez besoin d'avoir les librairies OpenGL et DLL, que je vais également prévoir une option de téléchargement juste au cas où vous ne les avez pas. Rendre la vie un peu plus facile si vous n'avez pas à leur recherche en ligne.

Donc, la majorité du code est de préparer les fenêtres pour rendre la scène correctement. Comme vous pouvez le voir ci-dessous, le code pour générer et rendre le terrain est très court. Pour donner une vue d'ensemble, la première chose qui arrive est pour les fenêtres de se créer, puis on initialise OpenGL, et lu dans le fichier BMP et l'affecter à la matrice 2D nous avons discuté ci-dessus. Ensuite, la texture est appliquée sur la surface de la maille, et la scène affichée à l'écran.

Sans plus tarder, la liste suivante est la portion de code qui initialise et génère le terrain:

.

.

.

/ / InitializeTerrain ()

/ / Desc: initialise le terrain Heightfield données

void InitializeTerrain ()

(

/ / Boucle sur tous les points Heightfield, calculer

/ / Les coordonnées de chaque point

for (int z = 0; z <MAP_Z; z + +)

(

for (int x = 0; x <MAP_X; x + +)

(

terrain [x] [z] [0] = float (x) * MAP_SCALE;

terrain [x] [z] [1] = (float) imageData [(z * MAP_Z + x) * 3];

terrain [x] [z] [2] =-float (z) * MAP_SCALE;

)

)
)
.
.
.
Le code ci-dessus est la mise en œuvre de ce que nous avons discuté sur l'application MAP_SCALE, qui nous permet d'escalader les terrains à nos goûts. Ainsi, il affecte essentiellement les coordonnées des sommets de chaque cellule du maillage, le facteur MAP_SCALE, qui est en multipliant l'indice de localisation basé sur la grille de coordonnées élément. Elle s'étend le long de l'axe X et l'axe Z, avec l'axe Y représente la hauteur du terrain.

La fonction est appelée après la bitmap a été chargé dans la mémoire de l'initialisation () la fonction.

.
.
.
/ / Render
/ / Desc: gère le tracé de la scène
void Render ()
(

radians = float (PI * (angle-90.0f) / 180.0f);

/ / Calculer la position de la caméra

/ / En multipliant par mouseY rend la

/ / Appareil-photo se rapprocher / plus loin avec mouseY

cameraX = lookX + sin (radians) * mouseY;

cameraZ lookz = + cos (radians) * mouseY;

Cameray = looky + mouseY / 2.0f;

/ / Calculer le regard caméra au point de coordonnées

/ / Comme le centre de la carte de terrain

lookX = (MAP_X * MAP_SCALE) / 2.0f;

looky = 150.0f;

lookz = - (MAP_Z * MAP_SCALE) / 2.0f;

/ / Effacer l'écran et la profondeur de tampon

glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity ();

/ / Définit la position de la caméra

gluLookAt (cameraX, Cameray, cameraZ,

lookX, looky, lookz, 0.0, 1.0, 0.0);

/ / Définit la texture actuelle à la texture des terres

(glBindTexture GL_TEXTURE_2D, sol);

/ / Nous allons parcourir en boucle tous

/ / De points de données de notre terrain, les

/ / Mais nous voulons seulement attirer un triangle

/ / Strip pour chaque ensemble le long de l'axe des abscisses.

for (int z = 0; z <MAP_Z-1; z + +)

(

glBegin (GL_TRIANGLE_STRIP);

for (int x = 0; x <MAP_X-1; x + +)

(

/ / Pour chaque vertex, nous calculons

/ / La couleur de l'ombre en niveaux de gris

/ / Nous avons fixé les coordonnées de texture,

/ / Et nous tirons le sommet.

/ / Dessin sommet 0

(glColor3f terrain [x] [z] [1] / 255.0f,

terrain [x] [z] [1] / 255.0f,

terrain [x] [z] [1] / 255.0f);

glTexCoord2f (0.0f, 0.0f);

(glVertex3f terrain [x] [z] [0],

terrain [x] [z] [1], le terrain [x] [z] [2]);

/ / Dessin sommet 1

glTexCoord2f (1.0f, 0.0f);

(glColor3f terrain [x +1] [z] [1] / 255.0f,

terrain [x +1] [z] [1] / 255.0f,

terrain [x +1] [z] [1] / 255.0f);

(glVertex3f terrain [x +1] [z] [0], le terrain [x +1] [z] [1],

terrain [x +1] [z] [2]);

/ / Dessin sommet 2

glTexCoord2f (0.0f, 1.0f);

(glColor3f terrain [x] [z +1] [1] / 255.0f,

terrain [x] [z +1] [1] / 255.0f,

terrain [x] [z +1] [1] / 255.0f);

(glVertex3f terrain [x] [z +1] [0], le terrain [x] [z +1] [1],

terrain [x] [z +1] [2]);

/ / Dessin sommet 3

(glColor3f terrain [x +1] [z +1] [1] / 255.0f,

terrain [x +1] [z +1] [1] / 255.0f,

terrain [x +1] [z +1] [1] / 255.0f);

glTexCoord2f (1.0f, 1.0f);

(glVertex3f terrain [x +1] [z +1] [0],

terrain [x +1] [z +1] [1],

terrain [x +1] [z +1] [2]);

)

glEnd ();

)

/ / Activer le mélange

glEnable (GL_BLEND);

/ / Enable tampon de profondeur en lecture seule

glDepthMask (GL_FALSE);

/ / Définit la fonction de mélange

/ / Pour ce que nous utilisons pour la transparence

glBlendFunc (GL_SRC_ALPHA, GL_ONE);

/ / Mise en revenir au mode normal en profondeur le tampon (inscriptibles)

glDepthMask (GL_TRUE);

/ / Désactiver le mélange

glDisable (GL_BLEND);

glFlush ();

/ / Backbuffer apporter des connaissances nouvelles

SwapBuffers (g_HDC);
)
.
.
.
La première chose que vous voyez dans le render () est la conversion de l'angle en radians, en utilisant la formule: radians = float (PI * (angle-90.0f) / 180.0f);. Cela rend plus facile à calculer le cameraX, Cameray, et cameraZ positions à l'aide du péché () et cos () fonctions.

Le bloc de code suivant définit l'affût au point de coordonnées de la caméra au centre du terrain. Ensuite, nous vider l'écran et tampon de profondeur en utilisant glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);. Nous plaçons la position de la caméra sur l'appareil (X, Y, Z) les valeurs et le regard au-nous calculé.

Nous avons ensuite lier la texture en utilisant le glBindTexture (GL_TEXTURE_2D, texture); fonction. Cela indique à OpenGL que nous allons utiliser cette texture particulière à appliquer à nos surfaces qui seront tirés.

Jusqu'à présent, tout le code était juste de configurer le positionnement des caméras et lier la texture, le prochain bloc de code est ce qui attire réellement le terrain et applique la texture de la surface. Nous avons deux pour les boucles qui passent par le tableau 2D, nous avons créé qui stocke les données du terrain, et comme nous avons discuté précédemment, nous traitons les quatre sommets à la fois. Dans le processus, nous calculons la teinte de gris, nous avons mis la texture, et ensuite nous en tirer les vertex.

C'est à peu près tout ce que vous devez faire pour générer un terrain, étant donné un fichier bitmap en 24 bits.

Points d'Intérêt
Si vous lisez ceci, vous les plus probables sont intéressés à l'infographie et que vous souhaitez en savoir plus sur les techniques disponibles pour faire des trucs vraiment cool. L'infographie peut être très complexe en théorie, mais grâce à des bibliothèques telles que OpenGL, la mise en œuvre de modèles complexes / scènes peuvent être réalisées facilement. Après rédaction de cet article, j'ai reçu le dernier numéro du Dr. Dobb's Journal (Juin 2006, No. 385), et à ma grande surprise, il ya un article sur OpenGL et les périphériques mobiles. C'est sous le nom d'OpenGL ES et il est un sous-ensemble d'OpenGL 1.3. Qui rendra possible de le faire en temps réel des graphismes 3D sur des appareils portatifs. Imaginez le type d'applications nice looking / jeux qui peuvent être développées pour votre PDA ou les téléphones cellulaires! Pas toutes les fonctionnalités sont disponibles en raison des limites de la main-tenu du matériel. Mais je suppose, à l'avenir à court terme, vous serez en mesure de créer des graphiques fascinants sur les ordinateurs de poche que vous pouvez sur vos machines de bureau ordinaire.

Sur une autre note, je vais commencer à travailler sur un nouvel article qui décrira les LoadBitmapFile (char * filename, * BITMAPINFOHEADER BITMAPINFOHEADER) la fonction. Je suis impatient d'entendre vos commentaires et suggestions, pour de futurs articles.

À propos de Vahé Karamian

Je programme depuis l'âge de 15 ans. Démarré en BASIC sur les ordinateurs Apple II passe ensuite à Pascal. J'ai écrit le jeu de Tetris en utilisant les deux langues sur Apple II. À l'âge de 16 ans j'ai eu mon premier ordinateur, et j'ai commencé à transférer le Code au cours de Quick Basic. J'ai ensuite déménagé en C / C + + et se sont développés en C / C + + jusqu'à il ya environ 2 ans, quand j'ai basculé vers C #.

Mes intérêts sont dans le domaine de l'informatique graphique et vision par ordinateur. Je travaille sur mon diplôme d'études supérieures en mettant l'accent sur la vision par ordinateur. Je vais essayer d'écrire plus d'articles dans ce domaine pour les présentations futures.

Actuellement, je suis employé chez une société de biotechnologie en Californie, et je travaille sur des projets intéressants, dans de nombreux domaines, à l'exception de vision par ordinateur  D'où mon accent de troisième cycle sur le sujet.

Vous pouvez trouver plus de C / C + + échantillons sur mon site. Il ya beaucoup de code bon pour les étudiants de premier cycle d'informatique.

http://www.nicksoftware.com

 
Sont fiables internet à large bande fournisseurs, un mythe?Conversion de documents PDF + l'aide de MS PowerPoint = An Ideal PrésentationAI Informatique décision de construire et réponses Solution Deconstruct par des ensembles de données pour les humainsLCD Projector RentalsCréation dans la peau de textureAssurer la réussite de raclage avec Proxy Data ScrapingMaking Sure Are You Ready For Pre-PressDois-je conserver mes piles dans le réfrigérateur?Il ya beaucoup de bonnes raisons d'achat d'un caméscope numériqueDonc les gens, at-Online Backup Come of Age?Cinq raisons pour lesquelles votre batterie d'un iPod de 3e génération est Worth RemplacementLe temps d'utiliser le détecteur de métalNonlinear Process ModelingVente de matériel informatique MoniteursPourquoi la plupart Wireless Network Security Advice Doesn't Really WorkGestion des données cliniquesNettoyage et migration des données Access vers Microsoft SQL Server - Partie 26 étapes vous pouvez prendre pour accélérer les performances de votre ordinateurTemps Champ ligne OrganiseurMacromedia Flash pour les débutants

© 2007-2012 Geocitoyen.com