184 lines
6.3 KiB
JavaScript
184 lines
6.3 KiB
JavaScript
define([
|
|
'../Core/Cartesian4',
|
|
'../Core/defined',
|
|
'../Core/destroyObject',
|
|
'../Core/PixelFormat',
|
|
'../Renderer/Framebuffer',
|
|
'../Renderer/PixelDatatype',
|
|
'../Renderer/RenderState',
|
|
'../Renderer/ShaderSource',
|
|
'../Renderer/Texture'
|
|
], function(
|
|
Cartesian4,
|
|
defined,
|
|
destroyObject,
|
|
PixelFormat,
|
|
Framebuffer,
|
|
PixelDatatype,
|
|
RenderState,
|
|
ShaderSource,
|
|
Texture) {
|
|
'use strict';
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
function PickDepth() {
|
|
this._framebuffer = undefined;
|
|
|
|
this._depthTexture = undefined;
|
|
this._textureToCopy = undefined;
|
|
this._copyDepthCommand = undefined;
|
|
|
|
this._useLogDepth = undefined;
|
|
|
|
this._debugPickDepthViewportCommand = undefined;
|
|
}
|
|
|
|
function executeDebugPickDepth(pickDepth, context, passState, useLogDepth) {
|
|
if (!defined(pickDepth._debugPickDepthViewportCommand) || useLogDepth !== pickDepth._useLogDepth) {
|
|
var fsSource =
|
|
'uniform sampler2D u_texture;\n' +
|
|
'varying vec2 v_textureCoordinates;\n' +
|
|
'void main()\n' +
|
|
'{\n' +
|
|
' float z_window = czm_unpackDepth(texture2D(u_texture, v_textureCoordinates));\n' +
|
|
' z_window = czm_reverseLogDepth(z_window); \n' +
|
|
' float n_range = czm_depthRange.near;\n' +
|
|
' float f_range = czm_depthRange.far;\n' +
|
|
' float z_ndc = (2.0 * z_window - n_range - f_range) / (f_range - n_range);\n' +
|
|
' float scale = pow(z_ndc * 0.5 + 0.5, 8.0);\n' +
|
|
' gl_FragColor = vec4(mix(vec3(0.0), vec3(1.0), scale), 1.0);\n' +
|
|
'}\n';
|
|
var fs = new ShaderSource({
|
|
defines : [useLogDepth ? 'LOG_DEPTH' : ''],
|
|
sources : [fsSource]
|
|
});
|
|
|
|
pickDepth._debugPickDepthViewportCommand = context.createViewportQuadCommand(fs, {
|
|
uniformMap : {
|
|
u_texture : function() {
|
|
return pickDepth._depthTexture;
|
|
}
|
|
},
|
|
owner : pickDepth
|
|
});
|
|
|
|
pickDepth._useLogDepth = useLogDepth;
|
|
}
|
|
|
|
pickDepth._debugPickDepthViewportCommand.execute(context, passState);
|
|
}
|
|
|
|
function destroyTextures(pickDepth) {
|
|
pickDepth._depthTexture = pickDepth._depthTexture && !pickDepth._depthTexture.isDestroyed() && pickDepth._depthTexture.destroy();
|
|
}
|
|
|
|
function destroyFramebuffers(pickDepth) {
|
|
pickDepth._framebuffer = pickDepth._framebuffer && !pickDepth._framebuffer.isDestroyed() && pickDepth._framebuffer.destroy();
|
|
}
|
|
|
|
function createTextures(pickDepth, context, width, height) {
|
|
pickDepth._depthTexture = new Texture({
|
|
context : context,
|
|
width : width,
|
|
height : height,
|
|
pixelFormat : PixelFormat.RGBA,
|
|
pixelDatatype : PixelDatatype.UNSIGNED_BYTE
|
|
});
|
|
}
|
|
|
|
function createFramebuffers(pickDepth, context, width, height) {
|
|
destroyTextures(pickDepth);
|
|
destroyFramebuffers(pickDepth);
|
|
|
|
createTextures(pickDepth, context, width, height);
|
|
|
|
pickDepth._framebuffer = new Framebuffer({
|
|
context : context,
|
|
colorTextures : [pickDepth._depthTexture],
|
|
destroyAttachments : false
|
|
});
|
|
}
|
|
|
|
function updateFramebuffers(pickDepth, context, depthTexture) {
|
|
var width = depthTexture.width;
|
|
var height = depthTexture.height;
|
|
|
|
var texture = pickDepth._depthTexture;
|
|
var textureChanged = !defined(texture) || texture.width !== width || texture.height !== height;
|
|
if (!defined(pickDepth._framebuffer) || textureChanged) {
|
|
createFramebuffers(pickDepth, context, width, height);
|
|
}
|
|
}
|
|
|
|
function updateCopyCommands(pickDepth, context, depthTexture) {
|
|
if (!defined(pickDepth._copyDepthCommand)) {
|
|
var fs =
|
|
'uniform sampler2D u_texture;\n' +
|
|
'varying vec2 v_textureCoordinates;\n' +
|
|
'void main()\n' +
|
|
'{\n' +
|
|
' gl_FragColor = czm_packDepth(texture2D(u_texture, v_textureCoordinates).r);\n' +
|
|
'}\n';
|
|
pickDepth._copyDepthCommand = context.createViewportQuadCommand(fs, {
|
|
renderState : RenderState.fromCache(),
|
|
uniformMap : {
|
|
u_texture : function() {
|
|
return pickDepth._textureToCopy;
|
|
}
|
|
},
|
|
owner : pickDepth
|
|
});
|
|
}
|
|
|
|
pickDepth._textureToCopy = depthTexture;
|
|
pickDepth._copyDepthCommand.framebuffer = pickDepth._framebuffer;
|
|
}
|
|
|
|
PickDepth.prototype.executeDebugPickDepth = function(context, passState, useLogDepth) {
|
|
executeDebugPickDepth(this, context, passState, useLogDepth);
|
|
};
|
|
|
|
PickDepth.prototype.update = function(context, depthTexture) {
|
|
updateFramebuffers(this, context, depthTexture);
|
|
updateCopyCommands(this, context, depthTexture);
|
|
};
|
|
|
|
var scratchPackedDepth = new Cartesian4();
|
|
var packedDepthScale = new Cartesian4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0);
|
|
|
|
PickDepth.prototype.getDepth = function(context, x, y) {
|
|
var pixels = context.readPixels({
|
|
x : x,
|
|
y : y,
|
|
width : 1,
|
|
height : 1,
|
|
framebuffer : this._framebuffer
|
|
});
|
|
|
|
var packedDepth = Cartesian4.unpack(pixels, 0, scratchPackedDepth);
|
|
Cartesian4.divideByScalar(packedDepth, 255.0, packedDepth);
|
|
return Cartesian4.dot(packedDepth, packedDepthScale);
|
|
};
|
|
|
|
PickDepth.prototype.executeCopyDepth = function(context, passState) {
|
|
this._copyDepthCommand.execute(context, passState);
|
|
};
|
|
|
|
PickDepth.prototype.isDestroyed = function() {
|
|
return false;
|
|
};
|
|
|
|
PickDepth.prototype.destroy = function() {
|
|
destroyTextures(this);
|
|
destroyFramebuffers(this);
|
|
|
|
this._copyDepthCommand.shaderProgram = defined(this._copyDepthCommand.shaderProgram) && this._copyDepthCommand.shaderProgram.destroy();
|
|
|
|
return destroyObject(this);
|
|
};
|
|
|
|
return PickDepth;
|
|
});
|