module Render.Skybox.Code
  ( vert
  , frag
  ) where

import RIO

import Render.Code (Code, glsl)
import Render.DescSets.Set0.Code (set0binding0, set0binding1, set0binding3)

vert :: Code
vert :: Code
vert = forall a. IsString a => String -> a
fromString
  [glsl|
    #version 450

    ${set0binding0}

    layout(location = 0) out vec3 fragUVW;

    float farZ = 0.9999; // 1 - 1e-7;

    void main() {
      vec4 pos = vec4(0.0);
      switch(gl_VertexIndex) {
          case 0: pos = vec4(-1.0,  3.0, farZ, 1.0); break;
          case 1: pos = vec4(-1.0, -1.0, farZ, 1.0); break; // XXX: swapped with 2. culling?
          case 2: pos = vec4( 3.0, -1.0, farZ, 1.0); break;
      }

      vec3 unProjected = (scene.invProjection * pos).xyz;
      unProjected *= -1;
      fragUVW = mat3(scene.invView) * unProjected;

      gl_Position = pos;
    }
  |]

frag :: Code
frag :: Code
frag = forall a. IsString a => String -> a
fromString
  [glsl|
    #version 450
    #extension GL_EXT_nonuniform_qualifier : enable

    ${set0binding0}

    ${set0binding1}
    ${set0binding3}

    layout(location = 0) in vec3 fragUVW;

    layout(location = 0) out vec4 outColor;

    void main() {
      if (scene.envCubeId > -1) {
        outColor = texture(
          samplerCube(
            cubes[nonuniformEXT(scene.envCubeId)],
            samplers[3] // XXX: linear
          ),
          fragUVW
        );
      }
    }
  |]