본문으로 건너뛰기

마우스 클릭 위치에 점 그리기_WebGL 노트 3

무료2015-12-22#JS#WebGL#webgl坐标系转换#点击canvas画一个点#canvas获取鼠标位置

canvas 좌표계와 WebGL 좌표계는 다르므로, 좌표 변환이 필요합니다

서론

[이전 노트](/articles/attribute 变量与顶点着色器-webgl 笔记 2/) 에서, 우리는 attribute 변수를 통해 점의 위치를 동적으로 설정하는 것을 구현했습니다. 마우스 클릭 위치에 점을 그리려면, 마우스 클릭 위치의 좌표를 얻기만 하면 됩니다. 최대의 문제는 좌표 변환입니다

一.canvas 좌표 취득

이벤트 핸들러를 추가하고, 이벤트 오브젝트에서 찾으면 됩니다. 다음과 같습니다:

// webgl 은 canvas 요소의 참조
webgl.addEventListener('click', function(e) {
    var x = e.offsetX;
    var y = e.offsetY;
}

이벤트 오브젝트의 offsetX/Y 속성을 통해, 마우스 클릭 위치의 canvas 좌표계における 좌표값 (x, y) 을 취득할 수 있습니다. canvas 왼쪽 위 모서리를 클릭하면, 취득하는 것은 (0, 0) 입니다

二.canvas 좌표를 WebGL 좌표로 변환

WebGL 중의 원점은 canvas 중심에 있고, x 축은 오른쪽 방향이 양, y 축은 위쪽 방향이 양, z 축은 화면에서 얼굴을 향하는 방향이 양입니다. canvas 좌표에서 WebGL 좌표로 변환하는 방식은 간단한 계산입니다. 다음과 같습니다:

var x = (e.offsetX - webgl.width / 2) / (webgl.width / 2);
var y = (webgl.height / 2 - e.offsetY) / (webgl.height / 2);

간단한 유도 프로세스는 다음과 같습니다:

1.x' 구하기
점 p 가 y 축의 왼쪽에 있으면, x' = (width/2 - x) * -1 = x - width/2
다시 x 축 음반축의 길이로 나누어 [0-1] 구간 중의 값을 얻음
x' = (x - width/2) / width/2
p 가 y 축의 오른쪽에 있으면, x' = x - width/2
다시 x 축 양반축의 길이로 나누어 [0-1] 구간 중의 값을 얻음
x' = (x - width/2) / width/2
따라서 x' = (x - width/2) / width/2
2.y' 구하기
점 p 가 x 축의 위쪽에 있으면, y' = height/2 - y
다시 y 축 양반축의 길이로 나누어 [0-1] 구간 중의 값을 얻음
y' = (height/2 - y) / height/2
p 가 x 축의 아래쪽에 있으면, y' = (y - height/2) * -1 = height/2 - y
다시 y 축 음반축의 길이로 나누어 [0-1] 구간 중의 값을 얻음
y' = (height/2 - y) / height/2
따라서 y' = (height/2 - y) / height/2

三.점 그리기

완전한 코드는 다음과 같습니다:

webgl.addEventListener('click', function(e) {
    // 좌표를 변환
    var x = (e.offsetX - webgl.width / 2) / (webgl.width / 2);
    var y = (webgl.height / 2 - e.offsetY) / (webgl.height / 2);
    console.log(x, y);

    // 2.attribute 변수에 값을 대입
    // attribute 변수의 기억 위치를 취득
    var a_Position = gl.getAttribLocation(glUtil.program, 'a_Position');
    if (a_Position < 0) {
        console.log('Failed to get the storage location of a_Position');
        return;
    }
    // 정점 위치를 attribute 변수에 전달
    gl.vertexAttrib3f(a_Position, x, y, 0.0);

    // canvas 를 클리어
    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    gl.clear(gl.COLOR_BUFFER_BIT);

    // 점을 그리기
    gl.drawArrays(gl.POINTS, 0, 1);
});

주의: 매번 점을 그리기 전에 우리는 clear 조작을 수행했습니다. clear 를 주석 아웃하면, 클릭 후 검은색 배경과 이전 점이 모두 사라진 것을 발견할 수 있습니다. WebGL 은 컬러 버퍼를 사용하고 있으며, WebGL 시스템 중의 그리기 조작은 실제로 컬러 버퍼 중에서 그리기를 수행하고 있습니다. 그리기 종료 후, 시스템은 버퍼 중의 내용을 화면에 표시하고, 그 후컬러 버퍼는 리셋되며, 중의 내용은 손실됩니다. 리셋 후의 색은 vec4(0.0, 0.0, 0.0, 0.0) 이므로, canvas 는 투명해집니다

P.S.실제로는 위의 clearColor 는 제거할 수 있습니다. gl.clear(gl.COLOR_BUFFER_BIT) 는 ��본적으로上一次의 gl.clearColor 에서 지정된 값을 사용하기 때문입니다. 如果没有이면, 기본색 vec4(0.0, 0.0, 0.0, 0.0) 을 사용합니다

四.DEMO

위 코드를 포함한 완전한 예에 대해서는, 다음을 참조하십시오: http://www.ayqy.net/temp/webgl/attribute-clickit/index.html

五.정리

현재 우리가 구현한 효과는: 어디를 클릭해도 그곳에 점을 그리며, 어떻게 클릭해도, 1 개의 점만 나타난다는 것입니다

역사의 점을 보존하고 싶다면, 현재는 배열로 역사의 점을 기록하고, 그 후 gl.drawArrays(gl.POINTS, 0, 1); 를 루프하여 모든 점을 그릴 수 있습니다. 그러나, 이렇게 하는 것은 너무 어리석게 보입니다. 한 번에 복수의 점을 그릴 수 있는 방법은 없을까요? 있습니다. 다만 buffer 와 배합하여 사용할 필요가 있으며, 조금 뒤의 내용입니다

半天배워도 아직 점을 그리고 있을 뿐입니다. 조금 더 재미있게 하기 위해, 다음편에서는 조금 더 화려한 내용——점의 색을 설정하는 것을 소개합니다.点点点点하여 찬란한星空을:-)

참고 자료

  • 《WebGL 프로그래밍 가이드》

댓글

아직 댓글이 없습니다

댓글 작성