"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module WebGL
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.addModelToWindowCoordinates = exports.addViewportTransformation = exports.addViewport = void 0;
const RenderPass_1 = require("./RenderPass");
const Vertex_1 = require("./Vertex");
/** @internal */
function addViewport(shader) {
    shader.addUniform("u_viewport", 3 /* VariableType.Vec2 */, (prog) => {
        prog.addProgramUniform("u_viewport", (uniform, params) => {
            params.target.uniforms.viewRect.bindDimensions(uniform);
        });
    });
}
exports.addViewport = addViewport;
/** @internal */
function addViewportTransformation(shader) {
    shader.addUniform("u_viewportTransformation", 7 /* VariableType.Mat4 */, (prog) => {
        prog.addProgramUniform("u_viewportTransformation", (uniform, params) => {
            params.target.uniforms.viewRect.bindViewportMatrix(uniform);
        });
    });
}
exports.addViewportTransformation = addViewportTransformation;
const modelToWindowCoordinates = `
vec4 modelToWindowCoordinates(vec4 position, vec4 next, out vec4 clippedMvpPos, out vec3 clippedMvPos) {
  if (kRenderPass_ViewOverlay == u_renderPass || kRenderPass_Background == u_renderPass) {
    vec4 q = MAT_MV * position;
    clippedMvPos = q.xyz;
    q = u_proj * q;
    clippedMvpPos = q;
    q.xyz /= q.w;
    q.xyz = (u_viewportTransformation * vec4(q.xyz, 1.0)).xyz;
    return q;
  }

  // Negative values are in front of the camera (visible).
  float s_maxZ = -u_frustum.x;            // use -near (front) plane for segment drop test since u_frustum's near & far are pos.
  vec4  q = MAT_MV * position;            // eye coordinates.
  vec4  n = MAT_MV * next;

  if (q.z > s_maxZ) {
    if (n.z > s_maxZ) {
      clippedMvPos = vec3(0.0, 0.0, 1.0);
      clippedMvpPos = vec4(0.0, 0.0, 1.0, 0.0);
      return vec4(0.0, 0.0, 1.0, 0.0);    // Entire segment behind front clip plane.
    }

    float t = (s_maxZ - q.z) / (n.z - q.z);

    q.x += t * (n.x - q.x);
    q.y += t * (n.y - q.y);
    q.z = s_maxZ;                         // q.z + (s_maxZ - q.z) / (n.z - q.z) * (n.z - q.z) = s_maxZ
  }

  clippedMvPos = q.xyz;
  q = u_proj * q;
  clippedMvpPos = q;
  q.xyz /= q.w;                           // normalized device coords
  q.xyz = (u_viewportTransformation * vec4(q.xyz, 1.0)).xyz; // window coords
  return q;
}
`;
/** @internal */
function addModelToWindowCoordinates(vert) {
    (0, Vertex_1.addModelViewMatrix)(vert);
    (0, Vertex_1.addProjectionMatrix)(vert);
    addViewportTransformation(vert);
    (0, RenderPass_1.addRenderPass)(vert);
    vert.addFunction(modelToWindowCoordinates);
}
exports.addModelToWindowCoordinates = addModelToWindowCoordinates;
//# sourceMappingURL=Viewport.js.map