아마 고3 때였던 것으로 기억한다. 수학 시간에 어느 벡터에든 곱하기만 하면 원점을 기준으로 원하는 각도만큼 회전시켜주는 신기한 행렬을 배웠었다. 그 당시 지루한 수험생활을 견디기 위해 이것저것 코딩을 하곤 했었는데, 이 회전행렬을 배운 날 바로 간단하게 화면 위에 임의의 점을 그리고 XYZ축 회전을 시켜볼 수 있는 프로그램을 짰다. 아래엔 그 7년 전 코드에서 발췌한 공간 위의 점을 X축 Y축 Z축 순서대로 회전하는 코드이다.
ty = (t.y) * Math.Cos(ax) + (t.z) * Math.Sin(ax); tz = -(t.y) * Math.Sin(ax) + (t.z) * Math.Cos(ax); tx = t.x; t = new spacePoint(tx, ty, tz); tx = (t.x) * Math.Cos(ay) + (t.z) * Math.Sin(ay); tz = -(t.x) * Math.Sin(ay) + (t.z) * Math.Cos(ay); ty = t.y; t = new spacePoint(tx, ty, tz); tx = (t.x) * Math.Cos(az) + (t.y) * Math.Sin(az); ty = -(t.x) * Math.Sin(az) + (t.y) * Math.Cos(az); tz = t.z; t = new spacePoint(tx, ty, tz);
짧은 코드지만 결과가 상당히 재밌었다. 몇 줄의 코드로 2차원 평면에 3차원 공간을 그려지는 것을 직접 경험한 것이다. 이때는 Euler Angle의 개념도 알 턱이 없었지만 서로 다른 축으로 여러 번 회전 시킬 때 회전하는 순서가 다르면 결과도 달라진다는 사실을 깨닫고 꽤 신기해 했던 기억이 난다. 이때부터 재미가 붙어서 이것저것 재밌게 기능을 추가하면서 놀았던 것 같다. 코드를 여기저기 살펴보니 별 기능이 다 들어 가있다. 여러가지 객체를 추가하고 움직일 수 있도록 명령어를 만들어서는 화면 안에서 이리저리 물체들이 뛰어 놀게 하고 있다.
백업을 생활화 하면 7년 전 코드도 이렇게 실행해 볼 수 있다.
하지만 화면에서도 알 수 있듯이 표현 가능한 것은 면적이 없는 점과 선 뿐이다. 면을 표현하기 위해서는 어느 면이 화면이 비춰지고 어느 면이 뒤로 가려지는지를 판별해야 하는데, 그 때 알고 있던 평면방정식이나 다른 벡터기하학 지식을 아무리 조합해 짱구를 굴려봐도 도저히 마땅한 방법이 떠오르지 않았다.
프로그래밍 선생님께도 여쭤봤지만 "음... 그래픽카드를 이용해야 할거야."라는 정도의 대답 말고는 얻을 수 있는 것이 없었다. DirectX나 OpenGL따위의 고오급 기술을 새로 배우기에는.. 핑계였을 지는 몰라도 나는 그때 고3 이었다.
지금의 관점으로 보면 '엔진'이라는 이름을 달기에도 민망하지만 그래도 내 이름을 따 [창훈그래픽스]라는 이름을 여기 기꺼이 붙여주고 이리저리 가지고 놀았던 추억 어린 코드다. 내가 OpenGL을 접한 것은 오래되지 않았지만, 독학으로도 쉽게 배우고 금방 시각적으로 무언가 보이는 것들을 개발할 수 있게 된 것도 이때의 경험들이 머릿속에 있기 때문이었을 것이다.
따지고 보면 삼각함수는 빠르면 중학생 때도 배우고, 벡터기하학이나 선형대수학의 기본적인 내용들도 다 고등학생 때 배우기 때문에 그 정도의 지식만 갖고 있어도 3D 그래픽 구현에 필요한 수학은 다 깨우치지 않을까 하는 생각이 들었다. 그래서 이번 기회에 약간의 수학적 지식만 있다면 쉽게 3D 그래픽을 구현해볼 수 있도록 차근차근 그 과정을 연재해보고자 한다.
어떻게 완결을 할지는 아직 떠오르지 않지만 꾸준히 연재하다 보면 무언가는 만들어져 있겠지. :)
'개발 > JUCE Framework' 카테고리의 다른 글
[3D 그래픽 엔진을 만들어보자] - 4.ViewPort의 이해 (0) | 2018.07.29 |
---|---|
[3D 그래픽 엔진을 만들어보자] - 3. JUCE GUI 프로그래밍 (0) | 2018.07.01 |
[3D 그래픽 엔진을 만들어보자] - 2. JUCE Framework의 기본적인 구조 (0) | 2018.06.28 |
[3D 그래픽 엔진을 만들어보자] - 1. Juce Framework 튜토리얼 (0) | 2018.06.28 |