title: Voxel rendering optimization with geometry shader
body: <p>I programming with C++ + SDL2 + GLEW + Opengl 4.1 a small voxel game a little bit like Minecraft.</p>
  
  <p>I am trying to optimize the voxel rendering where I can.</p>
  
  <p>I slide the world into chunks and this chunks into blocks.</p>
  
  <p>Each chunk contains 16x16x16 blocks.</p>
  
  <p>Now if a edit a chunk(remove/place a block) I rebuild the complete chunk and the neighbor chunk and upload it with vao's and vbo's to the graphic card.</p>
  
  <p>Now to minimize the vertex data I have to transfer from the cpu to the gpu I use geometry shaders.</p>
  
  <p>First of all, is that a good idea?</p>
  
  <p>I mean every frame the geometry shader has to calculate the primitive for each voxel face.</p>
  
  <p>However, I programmed the vertex shader so, that I only have to pass one vertex for each block face.</p>
  
  <p>To make that possible I used a vec4.</p>
  
  <p>The first 3 elements(x, y, z) I used for the block position and the 4. Element (w) I used to indicate in which direction the face is showing.</p>
  
  <p>0 means back,
  1 means front,
  2 means left,
  3 means right,
  4 means bottom,
  5 means top.</p>
  
  <p>Please ignore the UV and the normal for now.</p>
  
  <p>Further more I upload GLbyte's instead of GLfloat's.</p>
  
  <p>Is that a good idea?</p>
  
  <p>What would be a better/faster way?</p>
  
  <pre><code>    #version 410 
  
      uniform mat4 un_Combined; 
  
      layout(points) in; 
      layout(triangle_strip, max_vertices = 4) out; 
  
      in vec2 ge_UV[]; 
  
      out vec2 fr_UV; 
      out vec3 fr_Normal; 
  
      void main() 
      { 
  
          vec4 o = gl_in[0].gl_Position.xyzw; 
  
          if(o.w == 0) 
          { 
              gl_Position = un_Combined * vec4(o.x, o.y, o.z, 1); 
              fr_UV = vec2(0, 0); 
              fr_Normal = vec3(0, 0, 1); 
              EmitVertex(); 
  
              gl_Position = un_Combined * vec4(o.x, o.y + 1, o.z, 1); 
              fr_UV = vec2(0, 0); 
              fr_Normal = vec3(0, 0, 1); 
              EmitVertex(); 
  
              gl_Position = un_Combined * vec4(o.x + 1, o.y, o.z, 1); 
              fr_UV = vec2(0, 0); 
              fr_Normal = vec3(0, 0, 1); 
              EmitVertex(); 
  
              gl_Position = un_Combined * vec4(o.x + 1, o.y + 1, o.z, 1); 
              fr_UV = vec2(0, 0); 
              fr_Normal = vec3(0, 0, -1); 
              EmitVertex(); 
          } 
          else 
          if(o.w == 1) 
          { 
              gl_Position = un_Combined * vec4(o.x + 1, o.y, o.z + 1, 1); 
              fr_UV = vec2(0, 0); 
              fr_Normal = vec3(0, 0, 1); 
              EmitVertex(); 
  
              gl_Position = un_Combined * vec4(o.x + 1, o.y + 1, o.z + 1, 1); 
              fr_UV = vec2(0, 0); 
              fr_Normal = vec3(0, 0, 1); 
              EmitVertex(); 
  
              gl_Position = un_Combined * vec4(o.x, o.y, o.z + 1, 1); 
              fr_UV = vec2(0, 0); 
              fr_Normal = vec3(0, 0, 1); 
              EmitVertex(); 
  
              gl_Position = un_Combined * vec4(o.x, o.y + 1, o.z + 1, 1); 
              fr_UV = vec2(0, 0); 
              fr_Normal = vec3(0, 0, 1); 
              EmitVertex(); 
          } 
          else 
          if(o.w == 2) 
          { 
              gl_Position = un_Combined * vec4(o.x, o.y, o.z + 1, 1); 
              fr_UV = vec2(0, 0); 
              fr_Normal = vec3(0, 0, 1); 
              EmitVertex(); 
  
              gl_Position = un_Combined * vec4(o.x, o.y + 1, o.z + 1, 1); 
              fr_UV = vec2(0, 0); 
              fr_Normal = vec3(0, 0, 1); 
              EmitVertex(); 
  
              gl_Position = un_Combined * vec4(o.x, o.y, o.z, 1); 
              fr_UV = vec2(0, 0); 
              fr_Normal = vec3(0, 0, 1); 
              EmitVertex(); 
  
              gl_Position = un_Combined * vec4(o.x, o.y + 1, o.z, 1); 
              fr_UV = vec2(0, 0); 
              fr_Normal = vec3(-1, 0, 0); 
              EmitVertex(); 
          } 
          else 
          if(o.w == 3) 
          { 
              gl_Position = un_Combined * vec4(o.x + 1, o.y, o.z, 1); 
              fr_UV = vec2(0, 0); 
              fr_Normal = vec3(0, 0, 1); 
              EmitVertex(); 
  
              gl_Position = un_Combined * vec4(o.x + 1, o.y + 1, o.z, 1); 
              fr_UV = vec2(0, 0); 
              fr_Normal = vec3(0, 0, 1); 
              EmitVertex(); 
  
              gl_Position = un_Combined * vec4(o.x + 1, o.y, o.z + 1, 1); 
              fr_UV = vec2(0, 0); 
              fr_Normal = vec3(0, 0, 1); 
              EmitVertex(); 
  
              gl_Position = un_Combined * vec4(o.x + 1, o.y + 1, o.z + 1, 1); 
              fr_UV = vec2(0, 0); 
              fr_Normal = vec3(1, 0, 0); 
              EmitVertex(); 
          } 
          else 
          if(o.w == 4) 
          { 
              gl_Position = un_Combined * vec4(o.x + 1, o.y, o.z, 1); 
              fr_UV = vec2(0, 0); 
              fr_Normal = vec3(0, 0, 1); 
              EmitVertex(); 
  
              gl_Position = un_Combined * vec4(o.x + 1, o.y, o.z + 1, 1); 
              fr_UV = vec2(0, 0); 
              fr_Normal = vec3(0, 0, 1); 
              EmitVertex(); 
  
              gl_Position = un_Combined * vec4(o.x, o.y, o.z, 1); 
              fr_UV = vec2(0, 0); 
              fr_Normal = vec3(0, 0, 1); 
              EmitVertex(); 
  
              gl_Position = un_Combined * vec4(o.x, o.y, o.z + 1, 1); 
              fr_UV = vec2(0, 0); 
              fr_Normal = vec3(0, -1, 0); 
              EmitVertex(); 
          } 
          else 
          { 
              gl_Position = un_Combined * vec4(o.x, o.y + 1, o.z + 1, 1); 
              fr_UV = vec2(0, 0); 
              fr_Normal = vec3(0, 0, 1); 
              EmitVertex(); 
  
              gl_Position = un_Combined * vec4(o.x + 1, o.y + 1, o.z + 1, 1); 
              fr_UV = vec2(0, 0); 
              fr_Normal = vec3(0, 0, 1); 
              EmitVertex(); 
  
              gl_Position = un_Combined * vec4(o.x, o.y + 1, o.z, 1); 
              fr_UV = vec2(0, 0); 
              fr_Normal = vec3(0, 0, 1); 
              EmitVertex(); 
  
              gl_Position = un_Combined * vec4(o.x + 1, o.y + 1, o.z, 1); 
              fr_UV = vec2(0, 0); 
              fr_Normal = vec3(0, 1, 0); 
              EmitVertex(); 
          } 
  
          EndPrimitive(); 
      }
  </code></pre>