<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>C++, Qt et GPU &#187; Instanciation</title>
	<atom:link href="https://blog.developpez.com/gpu/?cat=17&#038;feed=rss2" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/gpu</link>
	<description></description>
	<lastBuildDate>Fri, 24 May 2013 17:02:21 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.42</generator>
	<item>
		<title>La technique d&#8217;instanciation</title>
		<link>https://blog.developpez.com/gpu/?p=3</link>
		<comments>https://blog.developpez.com/gpu/?p=3#comments</comments>
		<pubDate>Wed, 11 Apr 2012 12:01:48 +0000</pubDate>
		<dc:creator><![CDATA[gbdivers]]></dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Facile]]></category>
		<category><![CDATA[Instanciation]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[Qt]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[L&#8217;instanciation est une technique permettant de dessiner plusieurs copies du même objet. Cette technique sera intéressante dans des scènes contenant des objets similaires : une forêt d&#8217;arbre, le feuillage d&#8217;un arbre, une foule, l&#8217;herbe d&#8217;une pelouse. L&#8217;instanciation Lorsque l&#8217;on souhaite &#8230; <a href="https://blog.developpez.com/gpu/?p=3">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>L&rsquo;instanciation est une technique permettant de dessiner plusieurs copies du même objet. Cette technique sera intéressante dans des scènes contenant des objets similaires : une forêt d&rsquo;arbre, le feuillage d&rsquo;un arbre, une foule, l&rsquo;herbe d&rsquo;une pelouse.<br />
<span id="more-3"></span></p>
<p><strong><em>L&rsquo;instanciation</em></strong><br />
Lorsque l&rsquo;on souhaite afficher de nombreux objets, la première approche pourrait être de faire plusieurs appels à glDrawArrays et glDrawElements. Le nombre d&rsquo;appels aux fonctions de dessin peut cependant diminuer fortement les performances. Une optimisation possible est d&rsquo;utiliser glMultiDrawArrays ou glMultiDrawElements, qui prennent des tableaux de données et permettent donc de faire qu&rsquo;un seul appel. Cependant, il est nécessaire d&rsquo;envoyer les données correspondantes à tous les objets que l&rsquo;on souhaite créer, ce qui peut saturer la bande passante du GPU.</p>
<div class="codecolorer-container cpp blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="cpp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #666666;">// Extension GL_ARB_draw_instanced pour DrawArraysInstanced() et glDrawElementsInstanced() </span><br />
&nbsp; &nbsp; <span style="color: #666666;">// Extension GL_ARB_instanced_arrays pour VertexAttribDivisor() </span><br />
&nbsp;<br />
&nbsp; &nbsp; <span style="color: #666666;">// Pour dessiner plusieurs objets </span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">void</span> glMultiDrawArrays<span style="color: #008000;">&#40;</span>GLenum mode, GLint <span style="color: #000040;">*</span>first, GLsizei <span style="color: #000040;">*</span>count, GLsizei primcount<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <br />
&nbsp; &nbsp; <span style="color: #0000ff;">void</span> glMultiDrawElements<span style="color: #008000;">&#40;</span>GLenum mode, GLsizei <span style="color: #000040;">*</span>count, GLenum type, GLvoid <span style="color: #000040;">**</span>indices, GLsizei primcount<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></div></td></tr></tbody></table></div>
<p>L&rsquo;instanciation proprement dite permet de créer plusieurs instances d&rsquo;un objet. On envoie les données que pour un seul objet, ce qui réduit la bande passante.</p>
<p>Pour personnaliser chaque instance, on fournit un tableau de données (Instanced Array), chaque élément du tableau correspondant à une instance. On pourra passer ainsi modifier la position des instances, les paramètres de texture pour personnaliser les instances, ajouter du bruit, etc. Le paramètre <em>divisor</em> permet de spécifier quand on passe à l&rsquo;élément suivant dans un buffer. Pour <em>divisor</em> = 0, chaque vertex lit un nouvel élément dans le buffer. Avec <em>divisor</em> = 1, chaque instance lit un nouvel élément. Avec <em>divisor</em> = 2, un nouvel élément est lu toutes les 2 instances, etc.</p>
<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; // Création de plusieurs instances d'un objet <br />
&nbsp; &nbsp; void glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount); <br />
&nbsp; &nbsp; void glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); <br />
&nbsp;<br />
&nbsp; &nbsp; // Pour connaître l'identifiant de l'instance (GLSL) <br />
&nbsp; &nbsp; gl_InstanceID; // entre 0 et primcount-1 <br />
&nbsp;<br />
&nbsp; &nbsp; // Définir le mode de lecture des buffers <br />
&nbsp; &nbsp;glVertexAttribDivisor(location, divisor)</div></td></tr></tbody></table></div>
<p><em><strong>Un exemple simple</strong></em><br />
Le code d&rsquo;exemple affiche des cubes en utilisant glDrawElementsInstanced. Le curseur permet de sélectionner le nombre d&rsquo;instances à créer. Le bouton permet de basculer entre la vue des cubes pleins et en fil de fer. Les FPS et le nombre d&rsquo;instances sont indiqués dans le titre de la fenêtre. Je peux obtenir plus de 10 000 instances en même temps à 30 FPS (soit plus de 120 000 triangles) sur mon portable équipé d&rsquo;une 8600M GT.</p>
<p>Pour ceux qui testeraient avec du matériel plus puissant, il est possible d&rsquo;augmenter le nombre d&rsquo;instance maximal en modifiant le facteur multiplicateur à la ligne 127 du fichier glwidget.cpp ou la valeur maximale du QSlider à la ligne 22 du fichier mainwindow.cpp. J&rsquo;ai pu ainsi créer plus de 400 000 instances (4,8 millions de triangles) avant d&rsquo;arriver à 30 FPS sur une tour équipée d&rsquo;une GTX 460.</p>
<p><img src="http://gbelz.developpez.com/blog/instanciation.png" alt="Exemple d'affichage des cubes pleins (en haut) et en fil de fer (en bas)" title="Exemple d'affichage des cubes pleins (en haut) et en fil de fer (en bas)" /></p>
<p><a href="http://gbelz.developpez.com/blog/instanciation.zip">Télécharger le projet d&rsquo;exemple</a></p>
<p><em><strong>Au suivre&#8230;</strong></em><br />
* <a href="http://http.developer.nvidia.com/GPUGems/gpugems_ch07.html">gpu gems chap 7</a><br />
* <a href="http://sol.gfxile.net/instancing.html">http://sol.gfxile.net/instancing.html</a></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
