프레임 버퍼에 이미지 (텍스처로)를 그리거나, 선명도 필터를 적용하고 (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);
}
});
}
})()
그냥 빨리 제안 (나는 침대에 머리를하려고 해요) : 프레임 버퍼 객체에 부착하기 전에, 질감의 바인딩을 해제. 프레임 버퍼에 대한 작업을 금지하는 프레임 버퍼에 대한 텍스처 바인딩 및 부착 상태에 관한 특정 규칙이 있습니다. 가장 쉬운 부분은 텍스처를 바인딩 해제하는 것입니다 :'bindTexture (..., 0);'- 그러나 당신의 경우 renderbuffer가 첨부물, 텍스처와 잘 어울릴 수 있습니다. – datenwolf
to datenwolf -이 방법도 작동하지 않습니다. – spkenny