1

我正在尝试将图像(作为纹理)绘制到帧缓冲区,应用清晰度过滤器(通过在 UI 上拖动滑块),然后通过调用 readPixels 从帧缓冲区读取结果并将数据复制到简单的 2d 画布(不是 webgl)绑定帧缓冲区,获取像素数组并将它们复制到 ImageData.data,但该函数返回原始纹理。

也许有人可以向我解释这一点,因为据我所知,屏幕上的东西实际上是帧缓冲区的内容。

很抱歉有很多代码,但我希望它可以帮助理解我在做什么。

(function () {
  var anotherContext = null;
  var canvas = $("#canvas");

  main();
  setupCanvas();

  function setupCanvas () {
    anotherContext = document.getElementById("anothercanvas").getContext("2d");
  }

  function main () {
    var image = new Image();
    image.src = "http://localhost:9292/img/ava.jpg";
    image.onload = function () {
      render(image);
    }
  }

  function render (image) {
    //-----get contexts----
    var canvas = document.getElementById('canvas');
    var gl = canvas.getContext('experimental-webgl');

    //----define shaders-----
    var vs = document.getElementById('vshader').textContent;
    var fs = document.getElementById('fshader').textContent;

    //----create program-----
    var program = createProgram(vs, fs);
    gl.useProgram(program);

    //----setup vertex data-----
    var positionLocation = gl.getAttribLocation(program, "a_position");
    var texCoordLocation = gl.getAttribLocation(program, "a_texCoord");

    //----setup texture-----
    var texCoordBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
        0.0,  0.0,
        1.0,  0.0,
        0.0,  1.0,
        0.0,  1.0,
        1.0,  0.0,
        1.0,  1.0]), gl.STATIC_DRAW);
    gl.enableVertexAttribArray(texCoordLocation);
    gl.vertexAttribPointer(texCoordLocation, 2, gl.FLOAT, false, 0, 0);

    // Create a texture.
    var texture = createAndSetupTexture();
    // Upload the image into the texture.
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);

    //---framebuffer----
    var framebuffer = gl.createFramebuffer();
    gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);

    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
    var canRead = (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE);
    console.log("Can read: ", canRead);

    //----lookup uniforms and set the resolution-----
    var resolutionLocation = gl.getUniformLocation(program, "u_resolution");
    var textureSizeLocation = gl.getUniformLocation(program, "u_textureSize");
    var kernelLocation = gl.getUniformLocation(program, "u_kernel[0]");

    gl.uniform2f(textureSizeLocation, image.width, image.height);

    //----kernels-----
    var kernel = [
       0, 0, 0,
       0, 1, 0,
       0, 0, 0
    ];

    var sharpnessKernel = [
       0,-1, 0,
      -1, 5, -1,
       0,-1, 0
    ];

    //-----bind buffer------
    var vertexBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
    gl.enableVertexAttribArray(positionLocation);
    gl.vertexAttribPointer(program.vertexPosAttrib, 2, gl.FLOAT, false, 0, 0);

    setRectangle(gl, 0, 0, image.width, image.height);

    draw(kernel);

    function draw (krn) {
      // gl.bindTexture(gl.TEXTURE_2D, texture);

      setFramebuffer(framebuffer);
      drawWithKernel(krn);

      copyImage();

      // gl.bindTexture(gl.TEXTURE_2D, texture);
      setFramebuffer(null);

      gl.drawArrays(gl.TRIANGLES, 0, 6);
    }

    function setFramebuffer (fbuf) {
      gl.bindFramebuffer(gl.FRAMEBUFFER, fbuf);

      gl.uniform2f(resolutionLocation, canvas.width, canvas.height);

      gl.viewport(0, 0, canvas.width, canvas.height);
    }

    function drawWithKernel (kernel) {
      gl.uniform1fv(kernelLocation, kernel);

      //---draw
      gl.drawArrays(gl.TRIANGLES, 0, 6);
    }

    function createAndSetupTexture () {
      var texture = gl.createTexture();
      gl.bindTexture(gl.TEXTURE_2D, texture);

      // Set the parameters so we can render any size image.
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);

      return texture;
    }

    function setRectangle (gl, x, y, width, height) {
      var x1 = x;
      var x2 = x + width;
      var y1 = y;
      var y2 = y + height;
      gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
         x1, y1,
         x2, y1,
         x1, y2,
         x1, y2,
         x2, y1,
         x2, y2]), gl.STATIC_DRAW);
    }

    function createShader(str, type) {
      var shader = gl.createShader(type);

      gl.shaderSource(shader, str);
      gl.compileShader(shader);

      return shader;
    }

    function createProgram (vstr, fstr) {
      var program = gl.createProgram();
      var vshader = createShader(vstr, gl.VERTEX_SHADER);
      var fshader = createShader(fstr, gl.FRAGMENT_SHADER);

      gl.attachShader(program, vshader);
      gl.attachShader(program, fshader);
      gl.linkProgram(program);

      return program;
    }

    function copyImage () {
      var pixels = new Uint8Array(image.width * image.height * 4);
      gl.readPixels(0, 0, image.width, image.height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);

      var imageData = anotherContext.createImageData(image.width, image.height);
      for (var i = pixels.length - 1; i >= 0; i--) {
        imageData.data[i] = pixels[i];
      };

      // console.log(imageData.data);
      anotherContext.putImageData(imageData, 0, 0);
    }

    $("#slider").slider({
      min: 0,
      max: 99,
      slide: function (event, ui) {
        var currentKernel = null;

        //do not use any filtering if slider is on 0 position
        if(ui.value == 0) {
          currentKernel = kernel;
        }
        else {
          currentKernel = sharpnessKernel.slice(0);
          currentKernel[4] -= (ui.value / 100);
        }

        draw(currentKernel);
      }
    });
  }
})()
4

1 回答 1

-2

您当前的函数和括号设置已完全损坏,这也表明您没有使用firebug或任何其他Web 控制台来调试您的 javascript。

首先,您应该将一些功能移到主要功能之外并获得一个现代编辑器,因为它们中的大多数都具有显示属于一起的括号的方法。

编辑:看起来类似于来自WebGL 基础的代码。回答您的问题:仅当绑定的帧缓冲区为空时(您可以在该站点上阅读),您才在屏幕上绘图。

无论如何,你可能会得到这个帮助:Creating texture from getImageData (Javascript) or possible fabric.js image filters

于 2013-07-13T08:27:59.623 回答