2013-07-13 3 views
1

프레임 버퍼에 이미지 (텍스처로)를 그리거나, 선명도 필터를 적용하고 (UI에서 슬라이더를 드래그하여) 프레임 버퍼의 결과를 읽고 데이터를 간단한 2D 캔버스로 복사하려고합니다. (webgl이 아님) 바인드 된 프레임 버퍼로 readPixels를 호출하고 픽셀로 배열을 가져 와서 ImageData.data에 복사하지만이 함수는 원본 텍스처를 반환합니다.ReadPixels 함수는 텍스처를 수정하지 않고 반환합니다.

아마 내가 알기에 화면의 내용이 실제로 프레임 버퍼의 내용이기 때문에 누군가이 내용을 설명 할 수 있습니다.

많은 코드를 가져 오니 죄송합니다.하지만 제가하고있는 일을 이해하는 데 도움이되기를 바랍니다.

(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); 
     } 
    }); 
    } 
})() 
+0

그냥 빨리 제안 (나는 침대에 머리를하려고 해요) : 프레임 버퍼 객체에 부착하기 전에, 질감의 바인딩을 해제. 프레임 버퍼에 대한 작업을 금지하는 프레임 버퍼에 대한 텍스처 바인딩 및 부착 상태에 관한 특정 규칙이 있습니다. 가장 쉬운 부분은 텍스처를 바인딩 해제하는 것입니다 :'bindTexture (..., 0);'- 그러나 당신의 경우 renderbuffer가 첨부물, 텍스처와 잘 어울릴 수 있습니다. – datenwolf

+0

to datenwolf -이 방법도 작동하지 않습니다. – spkenny

답변

-2

현재 기능과 브래킷 설정이 완전히 또한 당신의 자바 스크립트를 디버깅하는 firebug 또는 기타 web-console를 사용하지 않을 것을 제안하는 나뉩니다.

처음에는 몇 가지 기능을 기본 외부 도구로 옮기고 modern editor으로 가져와야합니다. 대부분의 경우 대괄호를 함께 표시하는 방법이 있습니다.

편집 : WebGL fundamentals의 코드와 유사합니다. 귀하의 질문에 대답하려면 : 당신은 바인딩 된 프레임 버퍼가 null 인 경우에만 (해당 사이트에서 읽을 수있는 것처럼) 화면에 그려야합니다.

어쨌든,이 일에 도움이 될 수 있습니다 Creating texture from getImageData (Javascript) 또는 가능 fabric.js image filters

+0

부러진 곳을 지적하십시오. 이 코드는 다소 지저분하지만 개념의 증거이며 작동합니다. 그리고 btw, 나는 크롬 개발자를 사용하고있다. 도구 및 숭고한 텍스트 편집기 - 대괄호를 강조 표시하는 데 문제가 없습니다. – spkenny

+0

당신의 손에 도구가 있다면 사용하십시오. 코드를 순서대로 유지하는 것은 프로그래밍의 절반이며 실제로 문제를 해결해야합니다. 현재 코드에서 브라우저는 코드가 유효하지 않기 때문에 코드를 실행하기 전에 구제 조치를합니다. – havarc

+0

코드에서 정확히 깨 졌다고 생각되는 부분을 말씀해 주시겠습니까? 그렇지 않으면 당신의 대답은 전혀 관련이 없으며 프레임 버퍼의 내용을 읽는 것과 관련이 없습니다. – spkenny

관련 문제