#version 330 compatibility
#include "includes.glsl"
#extension GL_ARB_shader_image_load_store : enable

out vec2 texcoord;
out vec4 glcolor;
out vec3 Normal;
out vec3 ViewDir;
out mat3 TBN;
out vec2 TexSize;
flat out ivec2 VoxelCoord;
flat out ivec3 OffsetPos;
flat out float Dist;

in vec3 at_midBlock;
in vec3 mc_Entity;
in vec4 at_tangent;
in vec2 mc_midTexCoord;

uniform mat4 gbufferModelViewInverse;
uniform vec3 cameraPosition;

layout(rgba8) uniform image2D colorimg1; //voxels

ivec2 VoxImgSize = ivec2(VoxelBufferSize, VoxelBufferSize);

mat3 CalculateTBN(vec3 worldPosition) {
    vec3 tangent  = normalize(at_tangent.xyz);
    vec3 binormal = normalize(-cross(gl_Normal, at_tangent.xyz));
    
    #if defined gbuffers_water || defined gbuffers_textured
        tangent  += CalculateVertexDisplacements(worldPosition +  tangent) - worldDisplacement;
        binormal += CalculateVertexDisplacements(worldPosition + binormal) - worldDisplacement;
    #endif
    
    tangent  = normalize(mat3(gbufferModelViewInverse) * gl_NormalMatrix *  tangent);
    binormal =           mat3(gbufferModelViewInverse) * gl_NormalMatrix * binormal ;
    
    vec3 normal = normalize(cross(-tangent, binormal));
    
    binormal = cross(tangent, normal); // Orthogonalize binormal
    
    return mat3(tangent, binormal, normal);
}

void main(){
    gl_Position = ftransform();
	texcoord = (gl_TextureMatrix[0] * gl_MultiTexCoord0).xy;
	// lmcoord = (gl_TextureMatrix[1] * gl_MultiTexCoord1).xy;
	glcolor = gl_Color;
    Normal = gl_Normal;
    TexSize = abs(texcoord-mc_midTexCoord.st)*1.9;
    ViewDir = normalize(mat3(gbufferModelViewInverse)*(gl_ModelViewMatrix*gl_Vertex).xyz);

    //I used the space conversion chart to get from modelspace to worldspace
    vec3 EyeCameraPosition = cameraPosition + gbufferModelViewInverse[3].xyz;
    vec3 worldPos = vec3((mat3(gbufferModelViewInverse)*(gl_ModelViewMatrix*gl_Vertex).xyz)+EyeCameraPosition);
    Dist = length(worldPos-EyeCameraPosition);

    TBN = CalculateTBN(worldPos);

    if(abs(mc_Entity.x-10000.) < 100.) return;
    if(abs(mc_Entity.x-20000.) < 100.) return;
    if(abs(mc_Entity.x-30000.) < 100.) return;
    if(abs(mc_Entity.x-40000.) < 100.) return;
        
    //offset it and set coordinate to bottom corner of block
    ivec3 BlockPos = ivec3(floor(worldPos + (at_midBlock/64.) + .001));
    ivec3 OffsetBlockPos = BlockPos-ivec3(floor(EyeCameraPosition)) + ivec3(RealVoxDist/2);

    bool canrun;
    if (OffsetBlockPos.x<0 || OffsetBlockPos.y<0 || OffsetBlockPos.z<0) return;
    if (OffsetBlockPos.x>=RealVoxDist || OffsetBlockPos.y>=RealVoxDist || OffsetBlockPos.z>=RealVoxDist) return;

    //Convert to an index
    int ID = (OffsetBlockPos.x)+((OffsetBlockPos.y)*RealVoxDist)+((OffsetBlockPos.z)*(RealVoxDist*RealVoxDist));
    OffsetPos = OffsetBlockPos;
        
    //convert to 2D coordinates and store to colortex1
    ivec2 StorePos = ivec2((ID % VoxImgSize.x), ID/VoxImgSize.x);
    VoxelCoord = StorePos;

    imageStore(colorimg1, StorePos, vec4(0));
}