= [WebGL] WebGL 알아보기_2 | 개발하는 쿼카

[WebGL] WebGL 알아보기_2

PL 분야 이해를 위해 저번에 OCaml에 대해서 간단히 공부해 보았다. 이제 PL 분야 이외에 컴퓨터 그래픽스 분야에 대해서도 간단히 파보고자 작년에 컴퓨터 그래픽스 강의를 들었던 한학년 선배가 준 강의 자료 및 강의 실습 Github를 통해 WebGL이라는 API에 대해 간단히 알아보았다.


정점 인덱스

지난 번에는 삼각형을 그려보았고, 이번에는 사각형을 그려보았다. 하지만 WebGL에는 사각형을 그리는 명령어는 없고 삼각형을 그리는 명령어만 존재한다. GPU는 삼각형을 그리는데에 최적화가 되어있기 때문이다.
(좀 더 자세히 말하면 세 개의 점만으로 그릴 수 있고, 세 개의 점으로 그려지는 만큼 어떤 곳에 있어도 평면상 위에 위치하기 때문에 안정적이다. 이해가 되지 않는다면 한 평면에 존재하는 사각형의 꼭짓점 하나를 Y축으로 잡아당겼다고 생각해보자. 이 사각형은 평면상에 위치하지 않을 것이다.)
그러면 사각형을 어떻게 그려야할까? 정답은 당연하게도 삼각형 두개를 이어붙이면 된다. 삼각형 두개를 이어붙이는데 정점이 총 6개가 들지만, 사각형을 그리는 만큼 6개의 정점 중 2개의 정점은 겹치게 되므로 우리는 총 4개의 정점을 지정해줄 것이다.

var positions = [ //사각형의 4개 점들을 우선 정의
    -0.5, -0.5, //0번 vertex
     0.5, -0.5, //1번 vertex
     0.5,  0.5, //2번 vertex
	  -0.5,  0.5, //3번 vertex
  ];
  
  var indices = [
	    0, 1, 2, //0,1,2번 vertex로 이루어진 삼각형
	    2, 3, 0, //2,3,0번 vertex로 이루어진 삼각형
  ];

위 코드는 먼저 정점 4개를 지정해준 뒤, 0, 1, 2번, 즉 (-0.5, -0.5), (0.5, -0.5), (0.5, 0.5) 위치에 세개의 정점을 가진 삼각형과, 2, 3, 0번, 즉 (-0.5, -0.5), (-0.5, 0.5), (0.5, 0.5) 위치에 세개의 정점을 가진 삼각형 두개를 그려주는 것이다.

var positionBuffer = gl.createBuffer(); 
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); 
gl.bufferData(gl.ARRAY_BUFFER, 
	new Float32Array(positions), 
	gl.STATIC_DRAW); 

var indexBuffer = gl.createBuffer(); //1. 버퍼 만들기
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); //2. 버퍼 바인딩
var uintIndices = new Uint16Array(indices); 
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, //3. 데이터 복사해 넣기
            uintIndices, 
			gl.STATIC_DRAW);

이후 지난 번에 했던 것처럼 버퍼를 바인딩한 뒤 GPU에 데이터를 넘기고, 삼각형들의 정점이 담긴 indices를 똑같이 넘긴다.

var program = webglUtils.createProgramFromSources(gl,
					[vertexShaderSource, fragmentShaderSource]);
  gl.useProgram(program); 
  
  gl.enableVertexAttribArray(0); 

  gl.vertexAttribPointer(0,
						2,
						gl.FLOAT,
						false,
						8,
						0);

  gl.drawElements(gl.TRIANGLES,
				6, 
				gl.UNSIGNED_SHORT,정의되어 있다
				0); 

그리고 저번처럼 그림을 그려주면 된다. 이 때 이번에는 지난 시간과 다르게 인덱스를 사용해서 그리므로, drawArray()가 아니나 drawElements를 사용해 그림을 그린다.