cesium 中添加鹰眼效果

根据每帧地图,绘制在右下角

关键点:

1、viewer.scene._view.globeDepth.framebuffer._colorRenderbuffers[0];

这里面的colorTextures 换成了_colorRenderbuffers

用的cesium版本1.137.0

2、一开始一直报错isDestroyed,在方法里面添加这个销毁的方法

javascript 复制代码
class TestoffscreenPrimitive {
    constructor(viewer) {
        this.viewer = viewer;
        this.drawCommand = null;
        this.initialized = false;
        this.currentTexture = null;
    }

    initialize() {
        if (this.initialized && this.drawCommand) {
            return; // 已经初始化,直接返回
        }

        const viewer = this.viewer;

        // 安全检查:确保场景和globeDepth存在
        if (!viewer?.scene?._view?.globeDepth?.framebuffer?._colorRenderbuffers?.length) {
            console.warn('globeDepth framebuffer not ready');
            return;
        }
        

        // 获取当前纹理
        this.currentTexture = viewer.scene._view.globeDepth.framebuffer._colorRenderbuffers[0];

        const fs = `
                uniform sampler2D colorTexture;
                in vec2 v_textureCoordinates;
                out vec4 fragColor;
                
                void main() {
                    // 安全检查:确保纹理坐标有效
                    vec2 texCoord = clamp(v_textureCoordinates, 0.0, 1.0);
                    vec4 color = texture(colorTexture, texCoord);
                    fragColor = vec4(color.rgb, 1.0); // 设置alpha为1.0可见
                    // fragColor =  texture(colorTexture, v_textureCoordinates);   
                    // fragColor =     vec4(1.0,1.0,1.0, 1.0);
        
                }
            `;

        // 创建uniformMap,使用闭包保存当前纹理引用
        const that = this;
        const uniformMap = {
            colorTexture: function () {
                // 每次获取最新的纹理,避免使用已销毁的纹理
                if (that.currentTexture &&
                    typeof that.currentTexture.isDestroyed === 'function' &&
                    !that.currentTexture.isDestroyed()) {
                    return that.currentTexture;
                }

                // 如果纹理已销毁,尝试重新获取
                const newTexture = that.viewer?.scene?._view?.globeDepth?.framebuffer?._colorTextures[0];
                if (newTexture) {


                    console.log(newTexture);
                    
                    that.currentTexture = newTexture;
                    return newTexture;
                }

                // 返回一个默认的白色纹理(需要预先创建)
                return that.getDefaultTexture();

    
            }
        };

        // 创建drawCommand
        try {
            this.drawCommand = viewer.scene.context.createViewportQuadCommand(fs, {
                uniformMap: uniformMap
            });
            this.drawCommand.pass = Cesium.Pass.OVERLAY;
            this.initialized = true;

        } catch (error) {
            console.error('Failed to create viewport quad command:', error);
        }
    }

    // 创建默认纹理作为后备
    getDefaultTexture() {
        if (this.defaultTexture) {
            return this.defaultTexture;
        }

        const context = this.viewer.scene.context;
        // 创建一个1x1的白色纹理作为后备
        this.defaultTexture = new Cesium.Texture({
            context: context,
            pixelFormat: Cesium.PixelFormat.RGBA,
            pixelDatatype: Cesium.PixelDatatype.UNSIGNED_BYTE,
            source: {
                width: 1,
                height: 1,
                arrayBufferView: new Uint8Array([255, 255, 255, 255])
            }
        });

        return this.defaultTexture;
    }

    update(frameState) {
        // 确保drawCommand已创建
        if (!this.initialized) {
            this.initialize();
        }

        // 如果仍然没有drawCommand,退出
        if (!this.drawCommand) {
            return;
        }

        // 更新纹理引用(如果必要)
        this.updateTextureReference();

        // 设置视口
        const screenWidth = frameState.context.drawingBufferWidth;
        const screenHeight = frameState.context.drawingBufferHeight;

        // 计算视口大小和位置
        const size = Math.min(screenWidth, screenHeight) * 0.3;
        const viewport = new Cesium.BoundingRectangle(
            screenWidth - size,  // x
            0,                   // y
            size,                // width
            size                 // height
        );

            this.initialize();


        // 更新renderState
        this.drawCommand.renderState = Cesium.RenderState.fromCache({
            viewport: viewport
        });

        // 将命令添加到渲染队列
        frameState.commandList.push(this.drawCommand);
    }

    // 更新纹理引用
    updateTextureReference() {
        try {
            const textures = this.viewer?.scene?._view?.globeDepth?.framebuffer?._colorTextures;

            if (textures && textures.length > 0) {
                const newTexture = textures[0];

                // 检查新纹理是否有效
                if (newTexture &&
                    typeof newTexture.isDestroyed === 'function' &&
                    !newTexture.isDestroyed()) {

                    // 如果当前纹理已销毁或不同,更新引用
                    if (!this.currentTexture ||
                        this.currentTexture.isDestroyed() ||
                        this.currentTexture !== newTexture) {

                        console.log('Updating texture reference');
                        this.currentTexture = newTexture;
                    }
                }
            }

        } catch (error) {
            console.warn('Failed to update texture reference:', error);
        }
    }

    // 销毁方法
    isDestroyed() {
        if (this.drawCommand) {
            // 清理drawCommand相关的资源
            this.drawCommand = null;
        }

        if (this.defaultTexture && typeof this.defaultTexture.destroy === 'function') {
            this.defaultTexture.destroy();
            this.defaultTexture = null;
        }

        this.currentTexture = null;
        this.initialized = false;
    }
}

效果:

相关推荐
陈随易15 分钟前
有生之年系列,Nodejs进程管理pm2 v7.0发布
前端·后端·程序员
冰暮流星33 分钟前
javascript之事件代理/事件委托
前端
陈随易2 小时前
AI时代,你还在坚持手搓文章吗
前端·后端·程序员
里欧跑得慢4 小时前
17. Flutter Hero动画实现:让界面过渡更加优雅
前端·css·flutter·web
IT_陈寒4 小时前
Vue的这个响应式陷阱,我debug了一整天才爬出来
前端·人工智能·后端
cn_mengbei5 小时前
用React Native开发OpenHarmony应用:Reanimated共享元素过渡
javascript·react native·react.js
kyriewen5 小时前
前端测试:别为了100%覆盖率而写测试,那是自欺欺人
前端·javascript·单元测试
去伪存真5 小时前
我自己写的第一个skills--project-core-standards
前端·agent
Data_Journal5 小时前
如何使用cURL更改User Agent
大数据·服务器·前端·javascript·数据库
掌心向暖RPA自动化5 小时前
如何获取网页某个元素在屏幕可见部分的中心坐标影刀RPA懒加载坐标定位技巧
java·javascript·自动化·rpa·影刀rpa