javascript - 如何复制webgl Canvas ? (我想要小 map )

标签 javascript html opengl-es webgl

我想要结果..

I want results..

我有一个 webgl Canvas 有没有办法复制 webgl Canvas 来创建迷你 map ?

我调用json并通过ajax将其绘制在 Canvas 上就像第一张图片

原始 Canvas 和小 map Canvas 想要共享坐标和图片

控制小 map 的矩形应该使用draw函数吗?

<div id="glCanvsDiv" style="height: 100%; width: 100%; padding: 0px; margin: 0px; left: 0px; top: 0px; position: absolute;">
<canvas id="glcanvas" class="canvasclass" style="width: 100%; height: 100%; margin: 0; padding: 0;"></canvas>

这是坐标函数

function getWorldPosition(event) {

const pos = getNoPaddingNoBorderCanvasRelativeMousePosition(event, gl.canvas);

const x = pos.x / gl.canvas.width  *  2 - 1;
const y = pos.y / gl.canvas.height * -2 + 1;

const view = mat4.inverse(cameraMatrix);

const viewProjection = mat4.multiply(projectionMatrix, view);

const viewZ = -5;

const clip = transformPoint(projectionMatrix, [0, 0, viewZ]);

const z = clip[2];

const inverseViewProjection = mat4.inverse(viewProjection); 

var world = transformPoint(inverseViewProjection, [x, y, z]);

world[0] = -world[0];
world[1] = -world[1];

return world;

}

我的对话框

<div id="aerialViewDlg" style="display:none; padding:0;">

$("#aerialViewDlg").dialog({
    autoOpen: false,
    width: 300,
    height: 260,
    title: "aerialView",
    position: {
        my: "right top",
        at: "right top",
    }
});

我想要全屏小 map , 原始 Canvas 只会显示小 map 中选定的区域

最佳答案

我不太清楚你在问什么。迷你 map 通常显示的信息比迷你 map 外部显示的信息多得多。换句话说,主显示屏可能显示单个建筑物,而小 map 则显示整个城镇。这意味着这两件事是无关的。要仅绘制建筑物,请绘制建筑物。要画城镇,你就画城镇。复制 Canvas 并不能解决这个问题

您可以将一张 Canvas 绘制到另一张 Canvas 上。最简单的方法是,如果目标 Canvas 是 2D Canvas ,您只需调用 drawImage 变体之一

ctx.drawImage(srcCanvas, dstX, dstY);

ctx.drawImage(srcCanvas, dstX, dstY, dstWidth, dstHeight);

ctx.drawImage(srcCanvas, 
              srcX, srcY, srcWidth, srcHeight,
              dstX, dstY, dstWidth, dstHeight);

如果您想在同一 Canvas 中绘制小 map ,您可以启用剪刀测试并设置视口(viewport),如下所示

// draw main display
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.disable(gl.SCISSOR_TEST);
compute projection matrix for main display
draw main display

// draw mini-map
gl.viewport(miniMapX, minMapY, miniMapWidth, minMapHeigh);
gl.scissor(miniMapX, minMapY, miniMapWidth, minMapHeigh);
gl.enable(gl.SCISSOR_TEST);
compute projection matrix for mini-map display
draw mini map display

示例:

"use strict";
const vs = `
attribute vec4 position;
uniform mat4 matrix;
void main() {
  gl_Position = matrix * position;
}
`;
const fs = `
precision mediump float;
uniform vec4 color;
void main() {
  gl_FragColor = color;
}
`;
const m4 = twgl.m4;
const gl = document.querySelector("canvas").getContext("webgl");

// compiles shaders, link program, looks up locations
const programInfo = twgl.createProgramInfo(gl, [vs, fs]);

const arrays = {
  position: {
    numComponents: 2,
    data: [
     -1, -1, 
      1, -1,
     -1,  1,
      1,  1,
    ],
  },
  indices: {
    numComponents: 2,
    data: [
      0, 1,
      1, 3,
      3, 2,
      2, 0,
    ],
  },
};
// calls gl.createBuffer, gl.bindBuffer, gl.bufferData for each array
const bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);

  // note: a good app would try to only draw what's visible in each
  // view
function drawScene(viewProjection) {  
  gl.useProgram(programInfo.program);
  // calls gl.bindBuffer, gl.enableVertexAttribArray, gl.vertexAttribPointer
  twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
  
  for (let y = -5; y <= 5; ++y) {
    for (let x = -5; x <= 5; ++x) {
      const world = m4.translation([x * 2.4, y * 2.4, 0]);
      const mat = m4.multiply(viewProjection, world);
  
      // calls gl.uniformXXX
      twgl.setUniforms(programInfo, {
        color: [(x + 5) / 10, (y + 5) / 10, x / 5 * y / 5 * .5 + 5, 1],
        matrix: mat,
      });
      // calls gl.drawArrays or gl.drawElements
      twgl.drawBufferInfo(gl, bufferInfo, gl.LINES);
    }
  }
}

function render(time) {
  time *= 0.001;
  twgl.resizeCanvasToDisplaySize(gl.canvas);
  
  // draw main scene
  gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
  gl.disable(gl.SCISSOR_TEST);

  gl.clearColor(0,0,0,1);
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

  {
    const unitsVertical = 3;
    const half = unitsVertical * .5
    const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
    const left = -half * aspect;
    const right = half * aspect;
    const bottom = -half;
    const top = half;
    const zNear = -1;
    const zFar = 1;
    const projection = m4.ortho(left, right, bottom, top, zNear, zFar);

    const camera = m4.rotationZ(time * .1);
    const view = m4.inverse(camera);
    const viewProjection = m4.multiply(projection, view);
  
    drawScene(viewProjection);
  }
  
  // draw mini map
  const miniMapWidth = gl.canvas.width / 3 | 0;
  const miniMapHeight = gl.canvas.height / 3 | 0;
  const miniMapX = gl.canvas.width - miniMapWidth;
  const miniMapY = gl.canvas.height - miniMapHeight;
  gl.viewport(miniMapX, miniMapY, miniMapWidth, miniMapHeight);
  gl.scissor(miniMapX, miniMapY, miniMapWidth, miniMapHeight);
  gl.enable(gl.SCISSOR_TEST);

  gl.clearColor(0.2,0.2,0.2,1);
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

  {
    const unitsVertical = 20;
    const half = unitsVertical * .5
    const aspect = miniMapWidth / miniMapHeight;
    const left = -half * aspect;
    const right = half * aspect;
    const bottom = -half;
    const top = half;
    const zNear = -1;
    const zFar = 1;
    const projection = m4.ortho(left, right, bottom, top, zNear, zFar);

    const camera = m4.rotationZ(time * .1);
    const view = m4.inverse(camera);
    const viewProjection = m4.multiply(projection, view);
  
    drawScene(viewProjection);
  }
    
  requestAnimationFrame(render);
}
requestAnimationFrame(render);
body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }
<canvas></canvas>
<script src="https://twgljs.org/dist/3.x/twgl-full.min.js"></script>

不幸的是,您无法在 WebGL 中跨 Canvas 共享资源(无法使用相同的缓冲区和纹理)。但还有各种其他解决方案。请参阅:Display different scenes sharing resources on multiple canvases

关于javascript - 如何复制webgl Canvas ? (我想要小 map ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45069247/

相关文章:

javascript - 如何在angularjs中使用服务在多个 Controller 之间共享数据?

javascript - 为什么匿名函数中的私有(private)变量可以从javascript中的函数外部访问?

javascript - 获取HTML页面中所有 `position:fixed`的元素?

javascript - jquery 没有正确附加计数

c++ - OpenCV-3.0 支持 OpenGL

image-processing - OpenGL ES 着色器将彩色图像转换为黑白红外图像?

javascript - 将 javascript 对象简化为唯一标识符

javascript - 未捕获的不变违规 : DetailPage. render()

javascript - 如何使用 JQuery 制作基于滚动的动画与 Bootstrap 3 模态一起工作?

iphone - OpenGL ES 支持环境着色器吗?