2012-05-31 3 views
1

webgl에서 마우스 제스처를 구현하려면 사용자가 프리 핸드 모드를 "화면에 그릴"수 있도록하고 싶습니다. 3D webgl에서 사용하면 화재 효과, 광선 또는 기타 멋진 그래픽 캔디와 같이 사용중인 브러시에 멋진 쉐이더 효과를 적용 할 수 있습니다.webgl에서 전체 화면 프리 핸드 그리기를 수행하는 적절한 방법은 무엇입니까?

webgl에서 화면을 효율적으로 그릴 수있는 현재 권장되는 방법은 무엇입니까?

감사합니다.

+0

아무도, 정말? FrameBufferObjects가 솔루션이 될 수 있습니까? – JayDee

+1

글쎄, 애매한 질문 일수록, 당신은 좋은 대답을 얻지 못할 가능성이 적습니다. 질문하기 전에 아무것도 해봤습니까? 만약 당신이 그렇게했다면, 우리가 알 수있는 것은, "나는 알고 있습니다. 나는 WebGL을 사용할 것입니다! 이제 실제로 구현하는 방법을 누군가에게 물어 봅시다." –

답변

0

두 가지 옵션이 있습니다.

당신은 FBO 그릴 후 캔버스에 FBO를 그릴 수

또는

당신은 'preserveDrawingBuffer을 : 사실'요청할 수있는 WebGL이 컨텍스트를 만들 때.

var canvas = document.getElementById("canvas"); 
 
var gl = canvas.getContext("webgl", {preserveDrawingBuffer:true}); 
 

 
program = twgl.createProgramFromScripts(gl, ["2d-vertex-shader", "2d-fragment-shader"]); 
 
gl.useProgram(program); 
 

 
var positionLoc = gl.getAttribLocation(program, "v_position"); 
 
var offsetLoc = gl.getUniformLocation(program, "u_offset"); 
 

 
var res = 1; 
 
setupQuad(gl, res, positionLoc); 
 

 
canvas.addEventListener('mousemove', draw, false); 
 

 
function draw(event) { 
 
    var m = getNoPaddingNoBorderCanvasRelativeMousePosition(event); 
 
    // convert mouse coords to clip space since that's what this 
 
    // particular shader is using. See 
 
    // https://webglfundamentals.org 
 
    // for how to use pixels instead of clip space. 
 
    var x = m.x/gl.canvas.width * 2 - 1; 
 
    var y = m.y/gl.canvas.height * -2 + 1; // flip y 
 

 
    drawBrush(x, y); 
 
} 
 

 
function drawBrush(x, y) { 
 
    gl.uniform2f(offsetLoc, x, y); 
 

 
    gl.drawElements(gl.TRIANGLES, res * res * 6, gl.UNSIGNED_SHORT, 0); 
 
} 
 

 
drawBrush(0, 0); 
 

 

 

 
function setupQuad(gl, gridRes, positionLoc) { 
 
    var scale = 0.05; 
 
    var objects = []; 
 

 
    var vertsAcross = gridRes + 1; 
 
    var numVerts = vertsAcross * vertsAcross; 
 
    var positions = new Float32Array(numVerts * 2); 
 
    var indices = new Uint16Array(6 * gridRes * gridRes); 
 
    var poffset = 0; 
 

 
    for (var zz = 0; zz <= gridRes; ++zz) { 
 
    for (var xx = 0; xx <= gridRes; ++xx) { 
 
     var u = xx/gridRes; 
 
     var v = zz/gridRes; 
 
     positions[poffset + 0] = (-1 + 2 * u) * scale; 
 
     positions[poffset + 1] = (-1 + 2 * v) * scale; 
 
     poffset += 2; 
 
    } 
 
    } 
 
    
 
    var tbase = 0; 
 
    for (var zz = 0; zz < gridRes; ++zz) { 
 
    var index = zz * vertsAcross; 
 
    for (var xx = 0; xx < gridRes; ++xx) { 
 
     indices[tbase + 0] = index + 0; 
 
     indices[tbase + 1] = index + 1; 
 
     indices[tbase + 2] = index + vertsAcross; 
 
     indices[tbase + 3] = index + vertsAcross; 
 
     indices[tbase + 4] = index + 1; 
 
     indices[tbase + 5] = index + vertsAcross + 1; 
 
     index += 1; 
 
     tbase += 6; 
 
    } 
 
    } 
 
    
 
    function makeBuffer(data, type, size, loc) { 
 
    var buf = gl.createBuffer(); 
 
    gl.bindBuffer(type, buf); 
 
    gl.bufferData(type, data, gl.STATIC_DRAW); 
 
    if (type == gl.ARRAY_BUFFER) { 
 
     gl.enableVertexAttribArray(loc); 
 
     gl.vertexAttribPointer(loc, size, gl.FLOAT, false, 0, 0); 
 
    } 
 
    return buf; 
 
    } 
 
    
 
    objects.push(makeBuffer(positions, gl.ARRAY_BUFFER, 2, positionLoc)); 
 
    objects.push(makeBuffer(indices, gl.ELEMENT_ARRAY_BUFFER)); 
 
    
 
    return objects; 
 
}; 
 

 
function getRelativeMousePosition(event, target) { 
 
    target = target || event.target; 
 
    var rect = target.getBoundingClientRect(); 
 

 
    return { 
 
    x: event.clientX - rect.left, 
 
    y: event.clientY - rect.top, 
 
    } 
 
} 
 

 
// assumes target or event.target is canvas 
 
function getNoPaddingNoBorderCanvasRelativeMousePosition(event, target) { 
 
    target = target || event.target; 
 
    var pos = getRelativeMousePosition(event, target); 
 

 
    pos.x = pos.x * target.width/canvas.clientWidth; 
 
    pos.y = pos.y * target.height/canvas.clientHeight; 
 

 
    return pos; 
 
}
canvas { border: 1px solid black; }
<script src="https://twgljs.org/dist/twgl.min.js"></script> 
 
<script id="2d-vertex-shader" type="x-shader/x-vertex"> 
 
attribute vec2 v_position; 
 
uniform vec2 u_offset; 
 
    
 
void main() { 
 
    gl_Position = vec4(v_position + u_offset, 0, 1); 
 
} 
 
</script> 
 
<script id="2d-fragment-shader" type="x-shader/x-fragment"> 
 
precision mediump float; 
 
void main() { 
 
    gl_FragColor = vec4(0, 1, 0, 1); 
 
} 
 
</script> 
 
<canvas id="canvas" width="400" height="300"></canvas>

+1

여기로 이동했습니다 (그리고 이전 것을 고쳤습니다) – gman

관련 문제