<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Wiki on you might find me here</title>
    <link>https://hideout.ink/tags/wiki/</link>
    <description>Recent content in Wiki on you might find me here</description>
    <image>
      <title>you might find me here</title>
      <url>https://hideout.ink/images/dead.gif</url>
      <link>https://hideout.ink/images/dead.gif</link>
    </image>
    <generator>Hugo -- 0.146.5</generator>
    <language>en-us</language>
    <lastBuildDate>Wed, 07 May 2025 23:33:25 +0100</lastBuildDate>
    <atom:link href="https://hideout.ink/tags/wiki/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title> Orange Tofu Recipe </title>
      <link>https://hideout.ink/_wiki/orange-tofu/</link>
      <pubDate>Wed, 07 May 2025 00:00:00 +0000</pubDate>
      <guid>https://hideout.ink/_wiki/orange-tofu/</guid>
      <description>&lt;figure class=&#34;align-center &#34;&gt;
    &lt;img loading=&#34;lazy&#34; src=&#34;https://hideout.ink/uploads/orange-tofu.webp#center&#34;/&gt; 
&lt;/figure&gt;

&lt;blockquote&gt;
&lt;p&gt;Recipe taken from &lt;a href=&#34;https://www.instagram.com/fitgreenmind/&#34;&gt;fitgreenmind&amp;rsquo;s instagram page&lt;/a&gt;.&lt;/p&gt;&lt;/blockquote&gt;

&lt;div style=&#34;column-count: 2; column-rule: 2px solid var(--secondary-highlight)&#34;&gt;
    &lt;h2 id=&#34;recipe&#34;&gt;Recipe:&lt;/h2&gt;
&lt;p&gt;(3 servings each 350cal/17P/34C/15F)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;400g tofu (pressed and cut into chunks)&lt;/li&gt;
&lt;li&gt;3 Tbsp corn starch&lt;/li&gt;
&lt;li&gt;salt, pepper and garlic powder to taste&lt;/li&gt;
&lt;li&gt;oil for frying&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;DUST tofu in starch and spices&lt;/p&gt;
&lt;p&gt;FRY until crrrrispy&lt;/p&gt;
&lt;h2 id=&#34;sauce&#34;&gt;Sauce:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;1/2 cup (125ml) orange juice&lt;/li&gt;
&lt;li&gt;2 Tbsp soy sauce&lt;/li&gt;
&lt;li&gt;4 Tbsp agave or maple syrup&lt;/li&gt;
&lt;li&gt;1 Tsp each Chili and Ginger&lt;/li&gt;
&lt;li&gt;2 Tbsp starch + 3 Tbsp water&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;MIX everything.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<figure class="align-center ">
    <img loading="lazy" src="/uploads/orange-tofu.webp#center"/> 
</figure>

<blockquote>
<p>Recipe taken from <a href="https://www.instagram.com/fitgreenmind/">fitgreenmind&rsquo;s instagram page</a>.</p></blockquote>

<div style="column-count: 2; column-rule: 2px solid var(--secondary-highlight)">
    <h2 id="recipe">Recipe:</h2>
<p>(3 servings each 350cal/17P/34C/15F)</p>
<ul>
<li>400g tofu (pressed and cut into chunks)</li>
<li>3 Tbsp corn starch</li>
<li>salt, pepper and garlic powder to taste</li>
<li>oil for frying</li>
</ul>
<p>DUST tofu in starch and spices</p>
<p>FRY until crrrrispy</p>
<h2 id="sauce">Sauce:</h2>
<ul>
<li>1/2 cup (125ml) orange juice</li>
<li>2 Tbsp soy sauce</li>
<li>4 Tbsp agave or maple syrup</li>
<li>1 Tsp each Chili and Ginger</li>
<li>2 Tbsp starch + 3 Tbsp water</li>
</ul>
<p>MIX everything.</p>
<p>HEAT it up and STIR until thickened.</p>
<p>ADD tofu with green onions and sesame.</p>

</div>
<br>
<p>We also like to add broccoli, so you can use that instead if you don&rsquo;t have green onions!</p>
]]></content:encoded>
    </item>
    <item>
      <title> kaomojis </title>
      <link>https://hideout.ink/_wiki/kaomojis/</link>
      <pubDate>Sat, 19 Apr 2025 00:00:00 +0000</pubDate>
      <guid>https://hideout.ink/_wiki/kaomojis/</guid>
      <description>&lt;h1 id=&#34;list-of-kaomojis-i-like-and-sometimes-use-on-my-website&#34;&gt;List of kaomojis I like and sometimes use on my website&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;（￣□￣；）&lt;/li&gt;
&lt;li&gt;(◟ᅇ)◜&lt;/li&gt;
&lt;li&gt;くコ:彡&lt;/li&gt;
&lt;li&gt;( ͡° ͜ʖ ͡°)&lt;/li&gt;
&lt;/ul&gt;</description>
      <content:encoded><![CDATA[<h1 id="list-of-kaomojis-i-like-and-sometimes-use-on-my-website">List of kaomojis I like and sometimes use on my website</h1>
<ul>
<li>（￣□￣；）</li>
<li>(◟ᅇ)◜</li>
<li>くコ:彡</li>
<li>( ͡° ͜ʖ ͡°)</li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title> Papermod Hugo Tips and Tricks </title>
      <link>https://hideout.ink/_wiki/hugo-markdown/</link>
      <pubDate>Mon, 06 Nov 2023 00:00:00 +0000</pubDate>
      <guid>https://hideout.ink/_wiki/hugo-markdown/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been forced to look at a lot of the same hugo/papermod related tips and tricks several times, so I created a page to drop all that knowledge to not have to struggle to find it up again.&lt;/p&gt;
&lt;p&gt;You can use the following lines in the frontmatter to hide a post from showing in its list&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# _build:
#     list: false
&lt;/code&gt;&lt;/pre&gt;</description>
      <content:encoded><![CDATA[<p>I&rsquo;ve been forced to look at a lot of the same hugo/papermod related tips and tricks several times, so I created a page to drop all that knowledge to not have to struggle to find it up again.</p>
<p>You can use the following lines in the frontmatter to hide a post from showing in its list</p>
<pre tabindex="0"><code># _build:
#     list: false
</code></pre>]]></content:encoded>
    </item>
    <item>
      <title> Game Jam Tips </title>
      <link>https://hideout.ink/_wiki/game-jam-tips/</link>
      <pubDate>Wed, 18 Oct 2023 00:00:00 +0000</pubDate>
      <guid>https://hideout.ink/_wiki/game-jam-tips/</guid>
      <description>Short list of tips that I&amp;#39;ve found useful on game jams.</description>
      <content:encoded><![CDATA[<ol>
<li>Make a team and collaborate</li>
<li>Solo is great too! A different experience. Make sure to interact with the community.</li>
<li>Make a devlog after the game jam is over. (What went well, what didn&rsquo;t go well, and what can improve)</li>
<li>Relax and have fun!</li>
<li>Work normal hours.</li>
<li>Try new things. Game jams is about having fun and learning.</li>
<li>Submit your game even if you feel like it&rsquo;s incomplete.</li>
<li>Be honest but kind when giving feedback. (REALLY IMPORTANT)</li>
<li>Come out with simple ideas (KISS Principle)</li>
<li>Prototype with simple shapes. Worry first about the core gameplay.</li>
<li>Make the idea phase short. Prototype fast!</li>
<li>Have someone not in the team playtest the game.</li>
<li>Make the game easy to play!</li>
<li>Extremly short is fine. If a game lasts a minute, make sure it is the most satisfying minute of the player&rsquo;s life.</li>
<li>Set a deadline a few hours earlier than the game jam&rsquo;s end.</li>
<li>Give a lot a feedback once the jam is over. Great to interact with the community</li>
<li>Winning isn&rsquo;t important. The experience and journey is.</li>
<li>Create a new project before the jam starts.</li>
<li>Meditate to let your ideas and creative juices flow.</li>
<li>Don&rsquo;t give up! Learn from your mistakes. It&rsquo;s never to late to start again. c:</li>
<li>Download legal and free asset packs online, and credit them!</li>
<li>Spend at least one hour on polish. (Sound effects, partciles, feel of game, small details)</li>
<li>Set yourself game jam goals. (Why did you join?)</li>
<li>If spirits are low, watch some game jam behind the scenes or devlogs. Great for motivation.</li>
<li>Make game jamming a fun hobby. Making messy games is a great skill for prototyping!</li>
<li>Make your game easy to access and play. (Browser, avoid downloadble things)</li>
<li>Try and avoid blocks of text for instructions.</li>
<li>Motivation will be low, but can come back as you continue working on your game. Be patient with passion.</li>
<li>Stay focused! (Try listening to instrumental music, avoid social media or stuff that distracts you)</li>
</ol>
]]></content:encoded>
    </item>
    <item>
      <title> Voicemeeter&#39;s Good To Know </title>
      <link>https://hideout.ink/_wiki/voicemeeter/</link>
      <pubDate>Wed, 18 Oct 2023 00:00:00 +0000</pubDate>
      <guid>https://hideout.ink/_wiki/voicemeeter/</guid>
      <description>&lt;p&gt;I always lost the manual, so I am leaving this here to remember when I need to program audio macros again:
&lt;a href=&#34;https://vb-audio.com/Voicemeeter/VoicemeeterBanana_UserManual.pdf&#34;&gt;https://vb-audio.com/Voicemeeter/VoicemeeterBanana_UserManual.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;Image of the voicemeeter macros&#34; loading=&#34;lazy&#34; src=&#34;https://hideout.ink/_wiki/voicemeeter/imgs/macros.png&#34;&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I always lost the manual, so I am leaving this here to remember when I need to program audio macros again:
<a href="https://vb-audio.com/Voicemeeter/VoicemeeterBanana_UserManual.pdf">https://vb-audio.com/Voicemeeter/VoicemeeterBanana_UserManual.pdf</a></p>
<p><img alt="Image of the voicemeeter macros" loading="lazy" src="/_wiki/voicemeeter/imgs/macros.png"></p>
]]></content:encoded>
    </item>
    <item>
      <title> Three JS Experiments with Hugo </title>
      <link>https://hideout.ink/_wiki/threejs/</link>
      <pubDate>Sun, 15 Oct 2023 00:00:00 +0000</pubDate>
      <guid>https://hideout.ink/_wiki/threejs/</guid>
      <description>&lt;script src=&#34;https://cdn.jsdelivr.net/npm/three@0.132.2/examples/js/loaders/GLTFLoader.js&#34;&gt;&lt;/script&gt;
    &lt;script type=&#34;module&#34; src=&#34;https://hideout.ink/js/3d-hello-world.js&#34; defer&gt;&lt;/script&gt;
    &lt;canvas class=&#34;canvas3D&#34; id=&#34;myCanvasId&#34;&gt;&lt;/canvas&gt;</description>
      <content:encoded><![CDATA[
    <script src="https://cdn.jsdelivr.net/npm/three@0.132.2/examples/js/loaders/GLTFLoader.js"></script>
    <script type="module" src="/js/3d-hello-world.js" defer></script>
    <canvas class="canvas3D" id="myCanvasId"></canvas>

]]></content:encoded>
    </item>
    <item>
      <title> Tutorial 1 </title>
      <link>https://hideout.ink/opengl/01/</link>
      <pubDate>Thu, 19 May 2022 00:00:00 +0000</pubDate>
      <guid>https://hideout.ink/opengl/01/</guid>
      <description>&lt;h2 id=&#34;abrir-una-ventana&#34;&gt;Abrir una Ventana&lt;/h2&gt;
&lt;h3 id=&#34;contexto&#34;&gt;Contexto&lt;/h3&gt;
&lt;p&gt;El espectro de OpenGL no especifica ninguna API para crear y manipular ventanas. Sistemas de ventanas modernas que soportan OpenGL incluyen un sub-sistema que proporciona la unión entre un contexto OpenGL y el sistema de ventanas. En el sistema X Window la interfaz se llama GLX. Microsoft proporciona WGL (pronunciado: Wiggle) para Windows y MacOS tiene CGL.&lt;/p&gt;
&lt;p&gt;Al trabajar directamente con estas interfaces con el fin de crear una ventana en la que mostrar gráficos suele ser un trabajo duro y por eso utilizamos una biblioteca de alto nivel que abstrae los detalles finos. La biblioteca que usamos aquí se llama la &amp;lsquo;OpenGL utility library&amp;rsquo;, o GLUT. Proporciona una API simplificada para la gestión de ventanas, así como la gestión de eventos, control IO y algunos otros servicios. Además, GLUT es multiplataforma de modo que hace más fácil portabilidad. Alternativas a GLUT incluyen SDL y GLFW.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<h2 id="abrir-una-ventana">Abrir una Ventana</h2>
<h3 id="contexto">Contexto</h3>
<p>El espectro de OpenGL no especifica ninguna API para crear y manipular ventanas. Sistemas de ventanas modernas que soportan OpenGL incluyen un sub-sistema que proporciona la unión entre un contexto OpenGL y el sistema de ventanas. En el sistema X Window la interfaz se llama GLX. Microsoft proporciona WGL (pronunciado: Wiggle) para Windows y MacOS tiene CGL.</p>
<p>Al trabajar directamente con estas interfaces con el fin de crear una ventana en la que mostrar gráficos suele ser un trabajo duro y por eso utilizamos una biblioteca de alto nivel que abstrae los detalles finos. La biblioteca que usamos aquí se llama la &lsquo;OpenGL utility library&rsquo;, o GLUT. Proporciona una API simplificada para la gestión de ventanas, así como la gestión de eventos, control IO y algunos otros servicios. Además, GLUT es multiplataforma de modo que hace más fácil portabilidad. Alternativas a GLUT incluyen SDL y GLFW.</p>
<h3 id="el-código-paso-a-paso">El código paso a paso</h3>
<p><code>glutInit(&amp;argc, argv);</code></p>
<p>Esta funcion inicializa GLUT. Los parametros pueden ser previstos directamente de la linea de comandos y pueden incluir opciones utiles como    &lsquo;-sync&rsquo; y &lsquo;-gldebug&rsquo; los cuales desactivan la naturaleza asincrona de X y automaticamente checkean errores en GL y los muestra (respectivamente).</p>
<p><code>glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);</code></p>
<p>Aquí configuramos algunas opciones de GLUT. GLUT_DOUBLE permite el doble buffer (dibuja en un búfer en segundo plano mientras se visualiza otro buffer) y el buffer de color donde la mayor representación termina (es decir, la pantalla). Por lo general vamos a querer estos dos, así como otras opciones que veremos más adelante.</p>
<pre tabindex="0"><code>glutInitWindowSize(1024, 768);
glutInitWindowPosition(100, 100);
glutCreateWindow(&#34;Tutorial 01&#34;);
</code></pre><p>Estas llamadas especifican los parámetros de la ventana y la crean. Usted también tiene la opción de especificar el título de la ventana.</p>
<p><code>glutDisplayFunc(RenderSceneCB);</code></p>
<p>Dado que estamos trabajando en un sistema de ventanas la mayor parte de la interacción con el programa en ejecución se produce a través de funciones en respuesta a determinados eventos. GLUT se encarga de interactuar con el sistema de ventanas subyacente y nos ofrece algunas opciones de devolución de llamada. Aquí se utiliza sólo una devolucion de llamada (callback) denominada &ldquo;principal&rdquo; (RenderSceneCB) para hacer todo el renderizado de un frame. Esta función se llama continuamente por bucle interno de GLUT.</p>
<p><code>glClearColor(0.0f, 0.0f, 0.0f, 0.0f);</code></p>
<p>Este es nuestro primer encuentro con el concepto de estado en OpenGL. La idea detrás de este estado es que la representación es una tarea tan compleja que no puede ser tratada como una llamada de función que recibe un par de parámetros (y funciones diseñadas correctamente nunca reciben una gran cantidad de parámetros). Es necesario especificar shaders, buffers y diversas banderas que afectan la forma en que la represtación se llevará a cabo.</p>
<p>Además, usted suele desear conservar la misma pieza de configuración a través de varias operaciones de representación (por ejemplo, si usted nunca deshabilita la prueba de profundidad, entonces no hay necesidad de especificarla que para que ocurra en cada llamada al render). Es por eso que la mayor parte de la configuración de las operaciones de renderizado se realiza mediante el establecimiento de indicadores y valores en la máquina de estados de OpenGL y las llamadas de representación por sí mismas se limitan generalmente a los pocos parámetros que giran en torno al número de vértices para dibujar y su desplazamiento inicial (offset).</p>
<p>Después de llamar a una función de cambio de estado, la configuración particular se mantiene intacta hasta la siguiente llamada a la misma función con un valor diferente. La función citada establece el color que se utilizará para despejar el framebuffer (descrito más adelante). El color tiene cuatro canales (RGBA) y se especifica como un valor normalizado entre 0.0 y 1.0.</p>
<p><code>glutMainLoop();</code></p>
<p>Esta llamada le otorga el control a GLUT que ahora comienza su propio bucle interno. En este bucle se escucha a los eventos del sistema de ventanas y los pasa a través de las devoluciones de llamada (callback) que hemos configurado. En nuestro caso GLUT sólo llamará a la función se registró como un callback display (RenderSceneCB) para darnos una chace para renderizar el frame.</p>
<pre tabindex="0"><code>glClear(GL_COLOR_BUFFER_BIT);
glutSwapBuffers(); 
</code></pre><p>Lo único que hacemos en nuestra función de hacer es limpiar el framebuffer (con el color especificado anteriormente - pruebe a cambiar). La segunda llamada le dice a GLUT que intercambie los roles de backbuffer y frontbuffer. En la siguiente llamada de la función vamos a renderizar el frame en el frontbuffer y se mostrará el backbuffer.</p>
<h4 id="english-hahahugoshortcode168s0hbhb">ENGLISH: <a href = "https://ogldev.org/www/tutorial01/tutorial01.html" target="_blank"> https://ogldev.org/www/tutorial01/tutorial01.html</a>
</h4>
<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
      <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/DYuLHRsvZwk?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
    </div>

]]></content:encoded>
    </item>
    <item>
      <title> Tutorial 2 </title>
      <link>https://hideout.ink/opengl/02/</link>
      <pubDate>Thu, 19 May 2022 00:00:00 +0000</pubDate>
      <guid>https://hideout.ink/opengl/02/</guid>
      <description>&lt;h2 id=&#34;hola-punto&#34;&gt;¡Hola Punto!&lt;/h2&gt;
&lt;h3 id=&#34;contexto&#34;&gt;Contexto&lt;/h3&gt;
&lt;p&gt;Este es nuestro primer encuentro con GLEW, la Librería de Extension Wrangler de OpenGL. GLEW nos ayuda con el dolor de cabeza que puede ser el manejo de extensiones en OpenGL. Una vez inicializado consulta todas las extensiones disponibles en tu plataforma, las carga dinámicamente y te da acceso fácil a ellas usando un solo archivo header.&lt;/p&gt;
&lt;p&gt;En este tutorial veremos el uso de vertex buffer objects (VBOs) por primera vez. Como lo dice su nombre, son objetos que se utilizan para almacenar vértices. Los objetos que queremos visualizar dentro de nuestro entorno 3D, ya sean monstruos, castillo o un solo cubo girando, se construyen conectando grupos de vértices. VBOs son la forma más eficiente de cargar vértices en el GPU. Son buffers que se pueden almacenar en la memoria de video y nos da el tiempo de acceso más corto al GPU, por eso su uso es ampliamente recomendado.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<h2 id="hola-punto">¡Hola Punto!</h2>
<h3 id="contexto">Contexto</h3>
<p>Este es nuestro primer encuentro con GLEW, la Librería de Extension Wrangler de OpenGL. GLEW nos ayuda con el dolor de cabeza que puede ser el manejo de extensiones en OpenGL. Una vez inicializado consulta todas las extensiones disponibles en tu plataforma, las carga dinámicamente y te da acceso fácil a ellas usando un solo archivo header.</p>
<p>En este tutorial veremos el uso de vertex buffer objects (VBOs) por primera vez. Como lo dice su nombre, son objetos que se utilizan para almacenar vértices. Los objetos que queremos visualizar dentro de nuestro entorno 3D, ya sean monstruos, castillo o un solo cubo girando, se construyen conectando grupos de vértices. VBOs son la forma más eficiente de cargar vértices en el GPU. Son buffers que se pueden almacenar en la memoria de video y nos da el tiempo de acceso más corto al GPU, por eso su uso es ampliamente recomendado.</p>
<p>Este tutorial y el siguiente son los únicos de la serie que van a apoyarse en las funciones existentes del pipeline en vez de las que podamos programar. De hecho, no haremos transformaciones en ninguno de estos dos tutoriales. Nos apoyaremos únicamente en la forma con la que los datos fluyen por el pipeline. En los siguientes tutoriales haremos un análisis más profundo de este flujo, pero por ahora es suficiente entender que antes de llegar a la parte de renderizador (el que se encarga de dibujar los puntos, las líneas y los triángulos usando coordenadas de pantalla), los vértices visibles tienen sus coordenadas en X, Y y Z en el rango [-1.0, 1.0]. El renderizador mapea estas coordeanadas en el espacio de pantalla (p.e, si el ancho de pantalla es 1024 entonces la coordenada X -1.0 será mapeada a 0 y 1.0 será mapaeda a 1023).
Finalmente, el renderizador dibuja las primitivas de acuerdo a la topología especificada en la llamada de dibujo (draw call) (ve abajo en el código paso a paso). Como no unimos ningún tipo de shader a nuestro pipeline los vértices no pasarán por niguna transformación. Esto significa que únicamente necesitamos darles un valor en el rango descrito previamente para poder visualizarlos. De hecho, si seleccionamos cero para ambos X y Y posicionará el vértice en el punto medio de ambos ejes - en otras palabras, en la mitad de la pantalla.</p>
<p>Para instalar GLEW, está disponible en su página principal: <a href = "http://glew.sourceforge.net/" target="_blank"> http://glew.sourceforge.net/</a>
. La mayoría de las distribuciones de Linux proveen paquetes precompilados para la librería. En Ubuntu puedes instalarlo corriendo el siguiente comando:</p>
<p><code>apt-get install libglew1.6 libglew1.6-dev</code></p>
<h3 id="el-código-paso-a-paso">El código paso a paso</h3>
<p><code>#include &lt;GL/glew.h&gt;</code></p>
<p>Aquí incluiremos el header de GLEW. Si incluyes otros headers de OpenGL debes tener cuidado de incluir este archivo antes de los demás o podrías tener problemas de compatibilidad. Para poder enlazar la aplicación con GLEW necesitamos &lsquo;-lGLEW&rsquo; al makefile.</p>
<p><code>#include &quot;math_3d.h&quot;</code></p>
<p>Este archivo header está ubicado en &lsquo;ogldev/Include&rsquo; y contiene las estructuras de ayuda como la estructura de vector. Expandiremos más el contenido de este header conforme vayamos avanzando en los tutoriales. Hay que asegurarnos de clonar el código fuente del repositorio de acuerdo a las instrucciones que podemos encontrar <a href = "https://ogldev.org/instructions.html" target="_blank"> aquí</a>
. Considera también que cada carpeta de tutorial contiene un scrip llamado &lsquo;build.sh&rsquo; que puede ser usado para compilar el tutorial. Si usas tu propio sistema de compilado usa ese script como referencia para las banderas de compilado/linker necesarias.</p>
<pre tabindex="0"><code>GLenum res = glewInit();
if (res != GLEW_OK)
{
    fprintf(stderr, &#34;Error: &#39;%s&#39;\n&#34;, glewGetErrorString(res));
    return 1;
}
</code></pre><p>Aquí inicializamos GLEW y checamos por errores. Esto se debe de hacer después de que GLUT haya sido inicializado.</p>
<pre tabindex="0"><code>Vector3f Vertices[1];
Vertices[0] = Vector3f(0.0f, 0.0f, 0.0f);
</code></pre><p>Creamos un arreglo de una estructura tipo Vector3f (este tipo de dato es definido en math_3d.h) e inicializamos XYZ en cero. Esto hará que el punto aparezca en medio de la pantalla.</p>
<p><code>GLuint VBO;</code></p>
<p>Hacemos una alocación de un GLuint en la parte global del programa para almacenar el handle del objeto de búfer de vértice (VBO). Veremos más adelante que la mayoría (si no es que todos) los objetos en OpenGL son accesidos por variables de tipo GLuint.</p>
<p><code>glGenBuffers(1, &amp;VBO);</code></p>
<p>OpenGL define varias funciontes de tipo glGen* para generar objetos de diferentes tipos. Usualmente toman dos parámetros - el primero especifica el número de objetos que queremos creare y el segundo es la dirección del arreglo de GLuints que almacena los handles (manejadores) que el driver alocará para ti (¡asegurate que el arreglo sea lo suficientemente grande para manejar tu petición!). Llamadas futuras a esta función no generarán los mismos manejadores de objetos a menos que los borres primero con la función glDeleteBuffers. Algo que debemos considerar es que en este punto no estamos especificando lo que queremos hacer con los buffers para que puedan ser tratados con &ldquo;genéricos&rdquo;. El trabajo de especificar la función de los buffers será del siguiente método.</p>
<p><code>glBindBuffer(GL_ARRAY_BUFFER, VBO);</code></p>
<p>OpenGL tiene una forma única de usar los handles. En muchas APIs los handles simplemente se pasan a cualquier función a la que puedan ser relevantes y luego se realiza la acción en ese handle. En OpenGL unimos el handle con un nombre de objetivo y ejecutamos los comandos en dicho objetivo. Estos comandos afectan al hanlde que fue adjuntado hastsa que otro sea adjuntado en su lugar o hasta que la llamada tome cero como manejador. El objetivo GL_ARRAY_BUFFER significa que el búfer contendrá un arreglo de vértices. Otro objetivo que puede ser útil es GL_ELEMENT_ARRAY_BUFFER que significa que el búfer contiene los índices de los vértices en otro búfer. Existen otros tipos de objetivos disponibles que estudiaremos en tutoriales más adelante.</p>
<p><code>glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);</code></p>
<p>Después de unir nuestro objeto debemos llenarlo con información. La llamada que acabamos de escribir toma el nombre del objetivo (el mismo que fue usado en la unión), el tamaño de los datos en bytes, la dirección del arreglo de vértices y la bandera que indique el patrón de uso para estos datos. Como no vamos a cambiar el contenido del búfer debemos especificar GL_STATIC_DRAW. Para especificar lo opuesto sería GL_DYNAMIC_DRAW. Así como esto pueda ser único para OpenGL es bueno pensar bien en las banderas que debemos usar. El driver puede apoyarse en esta bander para optimizar heurísticas (tales como cual es el mejor lugar en memoria para almacenar el búfer).</p>
<p><code>glEnableVertexAttribArray(0);</code></p>
<p>En el tutorial de shaders veremos que los atributos de los vértices usados en el shader (posición, normal, etc) tienen un índice mapeado a ellos que nos permite create una unión entre los datos del programa de C/C++ y los nombres de los atributos dentro del shader. Adicionalmente debemos también habilitar el índice de cada atributo de vértice. En este tutorial todavía no utilizamos shaders, pero la posición de vértice que hemos cargado en el búfer será tratado como el índice del atributo de vértice 0 en la función fija del pipeline (que se activa cuando no hay un shader que limite el programa). Debes activar cada atributo de vértice o si no los datos no podrán ser accedidos por el pipeline.</p>
<p><code>glBindBuffer(GL_ARRAY_BUFFER, VBO);</code></p>
<p>Aquí unimos nuestro búfer de nuevo y nos preparamos para hacer el draw call. En este pequeño programa únicamente tenemos un búfer de vértice, entonces hacer esta llamada cada frame es redundante, pero en programas más complejos hay múltiples búfers para almacenar varios modelos y debemos actualizar el estado del pipeline con cada búfer que penemos utilizar.</p>
<p><code>glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);</code></p>
<p>This call tells the pipeline how to interpret the data inside the buffer. The first parameter specifies the index of the attribute. In our case we know that it is zero by default but when we start using shaders we will either need to explicitly set the index in the shader or query it. The second parameter is the number of components in the attribute (3 for X, Y and Z). The third parameter is the data type of each component. The next parameter indicates whether we want our attribute to be normalized before it is used in the pipeline. It our case we want the data to pass un-changed. The fifth parameter (called the &lsquo;stride&rsquo;) is the number of bytes between two instances of that attribute in the buffer. When there is only one attribute (e.g. the buffer contains only vertex positions) and the data is tightly packed we pass the value zero. If we have an array of structures that contain a position and normal (each one is a vector of 3 floats) we will pass the size of the structure in bytes (6 * 4 = 24). The last parameter is useful in the case of the previous example. We need to specify the offset inside the structure where the pipeline will find our attribute. In the case of the structure with the position and normal the offset of the position is zero while the offset of the normal is 12.</p>
<p><code>glDrawArrays(GL_POINTS, 0, 1);</code></p>
<p>Finalmente, hacemos la llamada a dibujar la geometría. Todos los comandos que hemos visto hasta ahora son importantes, pero solo nos ayudan a configurar el espacio para el comando de renderizado. Aquí es donde el GPU realmente empieza a trabajar. Combinará los parametros de cada draw call con el estado que hemos estado construyendo hasta este punto y hará el renderizado de los resultados en pantalla.</p>
<p>OpenGL nos da diferentes tipos de draw calls y cada uno de ellos sirve para diferentes casos. En general podemos dividirlos en dos categorías - renderizado ordenado y renderizado indexado. El renderizado ordenado es más simple. El GPU manda los búfers de vértices, yendo uno por uno por cada vértice, y los interpreta de acuerdo a la topología especificada en el draw call. Por ejemplo, si especificamos GL_TRIANGLES entonces los vértices 0-2 se convierten en el primer triánguo, los vértices 3-5 en el segundo triángulo, etc. Si quieres que el mismo vértice aparezca en más de un triángulo deberás especificarlo dos veces en el búfer de vértices, lo cual es un desperdicio de espacio.</p>
<p>El renderizado indexado es más complejo e involucra un búfer adicional llamado búfer de índice (index buffer). El index buffer contiene los índices de los vértices en el búfer de vértices. El GPU escanea el index bufer y, de forma similar a como lo hace con el renderizado ordenado, los índices 0-2 se convierten en el primer triángulo y así sucesivamente. Si quieres el mismo vértice en dos triángulos diferentes únicamente debes especificar su índice dos veces en el index buffer. El búfer de vértices solo necesita una copia. El dibujado de índices es más común en juegos porque la mayoría de los modelos son creados utilizando triángulos que representen una superficie (piel en el caso de una persona, una pared de un castillo o escenario, etc.) con una cantidad grande de vértices compartidos entre si.</p>
<p>En este tutorial usamos el draw call más simple - glDrawArrays. Este es un tipo de renderizado ordenado, entonces no necesimtamos un index buffer. Debemos especificar la topología de los puntos, lo que significa que cada vértice es un punto. El siguiente parámetro es el índice del primer vértice a dibujar. En nuestro caso queremos empezar al principio del búfer para poder especificar cero, y esto a su vez nos permite almacenar múltiples modelos en el mismo búfer y posteriormente seleccionar el que queremos dibujar basado en su desfase dentro del búfer. El último parámetro es el número de vértices a dibujar.</p>
<p><code>glDisableVertexAttribArray(0);</code></p>
<p>Es buena práctica deshabilitar cada atributo del vértice cuando no es utilizado inmediatamente. Dejandolo habilitado cuando un shader no lo está utilizando es una forma segura de hacernos las cosas más difíciles.</p>
<h4 id="english-hahahugoshortcode169s2hbhb">ENGLISH: <a href = "https://ogldev.org/www/tutorial02/tutorial02.html" target="_blank"> https://ogldev.org/www/tutorial01/tutorial01.html</a>
</h4>
<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
      <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/6dtqg0r28Yc?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
    </div>

]]></content:encoded>
    </item>
  </channel>
</rss>
