노무현 대통령에 대한 이야기들은 오랫동안 미국에 있다보니 주로 인터넷 뉴스를 통해서 접해왔다. 이번에 노무현 대통령님께서 서거 하셨다는 소식은 고 최진실씨가 사망했다는 소식 만큼이나 충격적이었다. 나도 모르게 너무나 마음 한구석이 슬퍼지는 느낌이었다. 

다른 정치인들에게는 한번도 느껴보지 못했던 '진실성'을 가지신 정치인이셨는데 그분이 돌아가셨다니... 참으로 큰 손실이 아닐수 없다.. 다시 한번 고인의 명복을 빈다.

처음 서거 소식을 듣고 속으로 이런 저런 생각을 했다...

누구나 그랬겠지만 충격임과 동시에 '자살'할 만큼 노대통령 스스로 '잘못'을 인정 했다라는 생각일 것이다. 잘못이라 함은 자신은 뇌물을 수수하지 않았으나 어찌되었든 간에 가족에게 일부 흘러간 돈이 있다는 점을 인정한다는 것을 말한다.

자살 = 잘못의 인정. 만약 타살이라면 타살을 한 사람의 의도는 분명 저 부분이었을 것이다. 죽음으로써 죄를 갚는다는 냄새를 강하게 풍기는 유서 또한 매우 조잡스럽다. 전공이 컴퓨터 사이언스인 나는 컴퓨터와 10 년 넘게 붙어 살았지만 아직도 부모님이나 친지에게 쓰는 매우 중요한 편지는 손으로 손수 적는데 연세가 63이신 노대통령께서 워드로 유서를 작성한다?? 누구나 조작 가능한 워드로???? 게다가 아무나 볼수 있게 바탕화면에 띄워 놓기 까지??? 심지어 암호도 안걸어 놓고????? 좀 너무 어이가 없다.

그리고 또 한가지... 사실 노무현 대통령의 서거 소식을 들었을때 제일 먼저 이명박 대통령이 생각이 났다. 당연한 이야기이지만 정치적으로 죽이기 위한 검찰의 노무현 대통령 수사가 계속 되었던 것을 누구나 알고 있었고 그로 인한 스트레스가 노무현 대통령을 죽였다는 생각을 했을 것이다. 즉, 이명박 정부의 간접적인 노무현 대통령 죽이기라는 말이다. 아주 논리적으로 문제 없는 생각이다.

만약 노무현 대통령께서 타살 되었다면 타살을 한 살인자는 노무현 대통령의 자살 소식을 접하는 일반 국민들의 생각을 미리 예측했을 것이고 아마도 대부분의 국민이 위와 같이 생각할 것이라고 예측 했을 것이다.

즉, '노무현 대통령의 자살 = 이명박 정부에 대한 불타오르는 비판 / 비난' 이 될 것이라는 것을 알면서도 타살을 시도 했다면???

현 정부에 대한 국민적 비난 과 비판을 감수하면서도 타살을 했다면 그것은 노무현 대통령이 최후의 반전수를 가지고 있었거나 더 큰 한방을 가지고 있었다는 것을 의미한다. 즉, 그 한방을 막기위해서라도 비난과 의혹을 무릅쓰고 타살을 한것이다.

그리고, 마지막으로 나에게 타살일 것 같다는 의심을 준 가장 결정적인 것은,

경호원의 진술 번복이다. 유일한 목격자이자 유일한 현장 동행자이며 모든것을 가장 정확하게 보았을 그 사람이 진술을 바꾸고 있다는 것은... 바로 진실은 아직 밝혀지지 않았다는 것이다. 이웃집 아저씨도 아니고 동네 주민도 아니고 바로 전직 대통령이다. 그럼에도 불구하고 자신의 진술을 번복한다는 것은 모두다 거짓말이라는 말이다.

존 F 케네디를 죽인 저격수가 붙잡히고 난 뒤 얼마 후 그 역시 누군가에게 암살 당한것을 우리는 안다...

지나간 역사는 미래를 보여주는 거울이다. 죽고 죽임을 당하는 방법만 바뀔 뿐 결론은 항상 하나다. 역사는 현재 권력을 쥐고 있는 사람의 것... 승자가 쓰는 것이 역사고 패자가 쓰는 것은 변명일 뿐이다.

영화에서 보면 늘 그렇듯 죄가 많은 악인은 늘 자신의 주위를 감시하기 때문에 명이 길다. 욕 많이 먹으면 오래산다는 말이 바로 그말이다. 하지만 국민적 영웅은 누구에게나 호의적이며 떳떳하고 당당하므로 누구에게나 환영받으로 누구 앞에서든 당당하게 나설수 있다. 그렇기에 암살당하기 너무나 쉽다...

만약 증언을 뒤바꾸고 있는 경호원 마저 죽어버린다면 이 사건은 영원한 미스테리로 남을것이고 그걸 방지하기 위해서라도 그 경호원 만큼은 살려 둬야 한다... 모든 것이 사라져 버리기 전에.

추가로, 오늘 뉴스를 보니 경호원 진술이 또 바뀌고 있단다. 휴대폰이 무전기보다 사용하기 편해서 휴대전화로 교신을 했으며 기록이 남아 있지 않다고 한다... 차라리 가짜로 무전 기록을 만들어라. 그러면 내 알면서도 속아줄께.

이런 정황들로 보아 타살일 가능성이 점점 높아진다. 만약 그렇다고 가정한다면... 과연 이명박 대통령이 이 일에 개입된것일까?

만약 당신이 이명박 대통령이라면 전 노무현 대통령이 아무리 위협적인 정보 (BBK나 각종 비리에 대해) 를 가지고 있다고 하더라도 과연 입을 막기 위해 죽이려 했을까

굳이 죽이지 않더라도 권력을 가진사람이 사용할 수 있는 방법은 얼마든지 많지 않았을까? 권력에서 멀어진 전 대통령을 어쭙잖게 암살함으로써 자신에게 돌아올 어마어마한 역풍을 전혀 몰랐을까? 당신이 대통령을 암살하려 했다면 이렇게 어쭙잖게 암살할까? 곳곳에 의문을 뿌려둔채?  

그런 의문의 종지부를 찍게 해주는 한가지 대답은, 만약 타살이라면, 범인은 또 다른 3자라는 것이다. 즉, 이명박 대통령도 몰랐던 일이라는 것이다. 북한의 핵실험대통령의 서거. 이 모든것이 딱 맞아 떨어지는 것도 너무나 이상하고 분명하지 않은 수사 발표 또한 그렇다.

만약 정말 자살이라면 떳떳하게 증거를 공개 못할 이유가 무엇인가? 둘 중 하나다. 범인이 권력의 실세라서 밝히기에는 너무나 충격적이거나 정말 증거가 불분명 하거나... (제 3자에 의한 범행) 

과거 일본에 의해 명성황후 께서 시해되었을때 우리는 아무것도 할 수 없었던 것을 기억한다. 이휘소 박사가 의문사로 죽었을때 또한 우리는 아무것도 할 수 없었다. 물론 이 모든 일들이 외부의 개입만으로 이루어 진 것은 아니지만 이번 사건에도 우리가 상상하지 못한 배후가 존재할 지도 모른다는 생각이 든다.

만약 경호원의 두번째 진술이 정말이라면, 정말 경호 공백이 그렇게 길었다면, 그리고 만약 타살이라면, 노무현 대통령을 죽인 사람이 치밀한 놈이라면...

모든 비난의 화살이 현재 정권으로 돌아갈 것을 미리 예측했으며, 겁을 집어 먹은 이명박 대통령과 경찰이 과잉 대응 할 것을 미리 알았을 것이며, 그로 인해 국내에 분열이 일어날 것을 알았고, 정확한 타이밍에 북한의 핵 실험이 일어날 것도 알았다면... 그리고 이로 인해 한반도에 분열이 일어나고 전쟁 위기로 치닫을 것을 알았다면?



한국 전쟁을 보면 알 수 있지만 우리 나라에서 전쟁이 터지면 가장 이득을 보는 것은 어느 나라인가? 경쟁 관계에 있는 세 사람중 두 사람이 싸워서 이득을 보는 쪽은 누구인가?

과연 진실은 어디에 있는 걸까? 이 모든 상황의 종료는 경찰의 정확한 증거 공개. 그것 뿐이다.




저작자 표시
이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by 대갈장군
프로그램을 짜려면 메모리가 참 중요한데... 차근 차근 책을 보며 다시 한번 정리해 보았다.

Win32 는 32비트로 메모리 주소공간을 표현한다는 의미로 Windows 95 부터 사용된 것으로 알고 있다. Win16은 Windows 95가 나오기 전에 사용된 것으로 주소공간을 표현하는 비트의 수가 최대 16 비트로 최대 표현 가능한 주소공간이 2의 16승 밖에 되지 않는다. 2의 16승은 64K 군. 

고로 상위 컴퓨터들이 등장하면서 확장된 메모리 공간 표현을 위해서는 Offset을 추가하는등 복잡한 계산법이 필요했단다... 그러다 보니 자연스레 Win32로의 확장이 이루어 진것인데, 엄밀히 말해서 Win16의 문제점은 두가지였다.

1. 증가하는 메모리 용량을 16비트의 레지스터 공간으로는 쉽게 표현이 불가능했다. 
2. 모든 프로그램이 같은 주소 공간에 존재하였으므로 포인터만 가지고 있으면 수퍼맨 처럼 어디든 액세스 가능.

바로 2번은 심각한 안정성 문제를 초래한다. Win16은 주소 공간과 실제 물리적 메모리가 서로 1대 1 대응 관계를 가지고 있었다. 즉, A라는 응용 프로그램의 포인터 값은 실제 물리적 메모리의 주소이며 이는 B라는 응용 프로그램에서도 마찬가지로 접근 가능한 고유한 값이었다.

하지만 이 개념이 Win32에 들어오면서 확 바뀌는데... 어떻게 바뀌냐면...

1. 가상 메모리의 등장. 가상 메모리 = 물리적 RAM + 페이징 파일 
2. 독립적인 4G 바이트의 가상 주소 공간이 각 응용 프로그램에 할당. 
3. 각각의 4G 바이트 공간은 페이지 테이블을 통해 가상 메모리에 연결. 

일단 가상 메모리가 등장하는데 이놈은 실제 컴퓨터가 가지고 있는 RAM 공간 + 페이징 파일이다. 페이징 파일은 물리적인 하드 디스크 공간을 메모리로 사용하는 것을 말하는데 일반적인 RAM보다 속도가 떨어질다는 것 외에는 RAM과 같은 놈이다.

그리고 각 응용 프로그램 당 4G 바이트라는 어마어마한 가상 주소 공간이 할당 되는데 이 가상 주소 공간은 실제로 할당된 메모리가 아니라 최대 저만큼 쓸수 있다는 말이다. 응용 프로그램이 실제로 무엇을 할당하거나 운영 체제의 모듈을 불러들일 경우 중간자 역활을 하는 페이지 테이블을 통해서 가상 메모리에 메모리 공간을 실제적으로 할당한다.

고로 각 응용 프로그램은 각자가 독립적인 4G 바이트의 주소 공간을 가지므로 서로가 서로에게 간섭을 할수가 없다. 즉, 안정성이 확보된것이다. 

응용 프로그램은 운영 체제가 메모리를 관리 (페이지 테이블에 의한) 하여 줌으로써 그 댓가로 안정성을 획득한 셈이다. 이런 구조의 한가지 단점이라면 프로세스간에 (응용 프로그램 간에) 데이터 교환이 용이 하지 않다는 점이다.

왜냐면 서로가 가지고 있는 주소 공간의 독립적이므로 A라는 응용 프로그램이 가지고 있는 주소 값은 B에서는 엉뚱한 값을 가지고 있을 수 있기 때문이다. 이것을 해결하기 위해 IPC 혹은 메모리 맵 파일을 사용해야 한다.


저작자 표시
Posted by 대갈장군
제목부터 아리까리하다. 내가 교수님으로부터 이상한 프로그램 하나를 건네 받고 그 놈을 요리조리 뜯어보다 보니 그 원리가 제목과 같더라...

잘은 모르지만 OpenGL에서 동영상 파일 재생은 매우 제한적이다. NeHe 홈페이지에 가보면 단순한 Mpeg 파일 재생 OpenGL 프로그램이 있기는 하지만 Mpeg 버전에 따라 되는 파일도 있고 안되는 파일도 있다. 한마디로 불완전하다.

수많은 형태의 동영상 재생 파일을 손쉽게 읽고 재생하기 위해서는 DirectShow 의 강력한 필터가 필요하다. 다만 OpenGL을 기반으로 프로그램을 작성하게 되면 DirectShow와 어떻게 연동해야 할지가 문제다.

물론 DirectX 기반으로 작성하면 (안해봤지만) 훠어얼씬 쉽겠지. VMR-9이라는 멎진 놈이 존재하기 때문에 텍스쳐 맵핑을 걱정할 필요가 없다.

하지만 죽으라는 법은 없다고 하지 않았던가... DirectShow의 필터중에 동영상 샘플 추출 필터가 있으니 바로 ISampleGrabber 를 이용하는 것이다.

이놈을 이용하게 되면 디코더를 지나자 마자 샘플 추출기 필터로 데이터가 흘러 들아가게 되고 샘플 추출기 필터는 새로운 데이터가 들어오면 SampleCB() or BufferCB() 함수를 콜백으로 호출하게 된다.

이 두 방식의 차이는 IMediaSample 인터페이스를 직접 넘겨주는가 그렇지 않는가에 있다. 뭐 중요한 차이는 아닌듯 싶다. 직접 넘겨주지 않는다면 클래스 멤버 변수에 따로 변수들을 저장해 두면 그만이고..

데이터가 넘어오면 그 길이와 주소를 이용해서 적당한 작업을 하면 된다. 하지만 주의할 것은 콜백 함수가 리턴 되기 전까지 필터는 흐름이 멈추게 된다. 고로 메모리 복사 작업 (텍스쳐 복사 작업)은 콜백 함수 내부에서 하면 성능 저하를 가져 올수도 있겠다는 생각이 든다.

하지만 막무가내로 리턴하고 다음 데이터를 받아버리면 공유된 버퍼 자원에 대한 자원 경쟁이 발생하거나 새로운 이미지 데이터가 업데이트 되는 도중에 텍스쳐 복사를 한다거나 하는 문제가 발생하지 않을까? 

만약 그렇다면 해결방법은 Critical Section을 이용해야 한다... 라면 성능에는 아무런 문제가 없을까?...

아무튼 현재 사용중인 프로그램은 이런 형태의 흐름을 가지고 있으며 이를 이용해 다양한 형태의 입력 파일들 (mpg, jpg, avi 등) 을 아주 손쉽게 OpenGL 텍스처로 입혀서 사용중이다.


저작자 표시
Posted by 대갈장군

앞서본 널 렌더링이나 필터 추가후 렌더링의 경우 RenderFile() 함수를 사용해서 자동으로 필터 그래프가 완성되도록 했으나 필터 렌더링은 필터의 Output 핀을 사용한 렌더링이다.

즉, 가장 세밀한 조작이 가능한 렌더링 방식이다. 그중에서도 소스 필터 자동 렌더링이 있는데 이는 RenderFile() 함수를 IGraphBuilder::AddSourceFilter() 함수와 IGraphBuilder::RenderFilter() 함수가 대체하는 방식이다.

1. 필터 그래프 매니저 생성
JIF(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&m_pGB);


2. AddSourceFilter() 함수로 소스 필터 추가하면서 pSourceFilter에 그 소스필터의 진입점(포인터) 얻어 오기
IBaseFilter *pSourceFilter;
JIF(m_pGB->AddSourceFilter(wFileName, wFileName, &pSourceFilter);


3. 필터 렌더링!
if(pSourceFilter != NULL)
      LIF(RenderFilter(m_pGB, pSourceFilter));


4. AddSourceFilter에 의해 추가로 생성된 필터 인터페이스 (리모컨) 삭제
SAFE_RELEASE(pSourceFilter);

근디... 자동 소스 필터 렌더링과 수동 소스 필터 렌더링은 그 차이가 크지 않네...

수동 소스 필터 렌더링은 우선적으로 소스로 사용할 필터를 추가시켜 놓고 자동 필터 렌더링과 마찬가지로 AddSourceFilter와 RenderFilter 함수를 차례로 호출하는 것일뿐 차이가 없다.

결국 정리하지만 자동 소스 필터 렌더링은 파일이나 URL를 이용해 AddSourceFilter() 를 수행하고 곧바로 RenderFilter를 이용해 Output Pins를 렌더링 한다.

반면 수동 소스 필터 렌더링은 소스 필터로 사용하고자 하는 필터를 우선 추가한 후, 필터들을 그래프에 추가시키고 그 다음에 AddSourceFilter()와 RenderFilter() 함수를 이용해 Pin 렌더링 수행.
저작자 표시
이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by 대갈장군
앞에서 본 NULL Rendering의 경우에는 입력 파일에서 곧바로 렌더링을 했지만 필터 추가후 렌더링은 원하는 특정 필터를 먼저 필터 그래프 매니져에 올려놓고 렌더링을 하는 것을 말한다.

이렇게 하면 필터 그래프가 만들어질때 이미 삽입시킨 필터를 최대한 포함시켜 렌더링을 하게 된단다.

1. 필터 그래프 매니저 생성
JIF(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&m_pGB);


2. 추가 시키고 싶은 필터 생성
IBaseFilter *pFilterOverlayMixer;
LIF(CoCreateInstance(CLSID_OverlayMixer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pFilterOverlayMixer));


3. 필터를 그래프 매니져에 추가
LIF(m_pGB->AddFilter(pFilterOverlayMixer, L"Overlay Mixer");


4. CoCreateInstance에 의해 생성된 필터 COM 객체 Release 시키기
SAFE_RELEASE(pFilterOverlayMixer);


5. Null Rednering 기술 사용
JIF(m_pGB->RenderFile(wFileName, NULL));

저작자 표시
이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by 대갈장군
DirectShow에서 Null Rendering 하는 방법

1. 우선 설명서 (CLSID_)와 기능 (IID_) 정의 해주고 CoCreateInstance 실행 하면 m_pGB 멤버 변수에 포인터 리턴됨. 이로써 필터 그래프 관리자 생성됨.
JIF(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&m_pGB));

2. 미리 가지고 있는 파일 이름을 넘겨주고 RenderFile() 명령 수행.
JIF(m_pGB->RenderFile(wFileName, NULL));

참 쉽죠잉~

재생중인 스트림이 있을경우 재생 중지 하고 필터 매니저 그래프 종료하기

1. IMediaControl interface를 QueryInterface 함수를 이용해 포인터 얻어오기.
IMediaControl * pMC;
JIF(m_pGB->QueryInterface(IID_IMediaControl, (void**)&pMC);

2. 재생중인 스트림이 있으면 정지 시키고 pMC 와 필터 그래프 관리자 해제
if(pMC != NULL)
     LIF(pMC->Stop()); // 재생하고 싶은 경우는 LIF(pMC->Run());
SAFE_RELEASE(pMC);

SAFE_RELEASE(m_pGB);

저작자 표시
이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by 대갈장군
참 이상한것이 DirectShow에 대한 책이나 정보가 한국어로 된것은 매우 드물다는 점이다. 신화선님이 출판한 DirectShow 멀티미디어 프로그래밍이란 책을 제외하고는 한국어로 된 DirectShow 서적은 없다고 봐야한다.

원어로 된 서적도 없기는 마찬가지다. 그래서 그런지 더더욱 자료를 찾기가 어렵다.

DirectShow의 각종 Application 작성에 대해서 블로그를 작성하기 전에 COM에 대해서 분명히 말해두고자 한다.

왜냐면 DirectShow의 필터들이 사실 전부 COM 기반이기 때문이다. 사실 따지고 보면 COM은 C++과 크게 다르지 않다. 다만 '어떻게 사용하나?' 를 알아야 한다는 점이 중요할뿐.

C++의 클래스는 전적으로 사용자에게 권한을 100% 준다. 내가 만들고 싶은 뭐든 내 맘대로 작성하면 그만이다. 멤버 함수, 변수 등 구현, 정의 모두 내 맘대로다.

헌데 거기서 한가지 문제점이 발생하는데 프로그램을 짜본 사람은 알겠지만 제법 규모가 있는 프로그램, 뭐 예를 들자면 동영상 재생 프로그램, 오디오 재생 프로그램 같은거를 만들고 싶다고 하자. 

C++의 내 맘대로 작성하여 만든 클래스를 사용하여 만드는 프로그램은 그 규모가 공사에 비교했을때 소형 주택 짓는 정도라면 동영상 재생 프로그램과 같은 것은 거의 10 층 빌딩 만드는 수준의 전문적 공사이다.

그렇다면 일반 프로그래머가 지하부터 공사시작해서 10층까지 빌딩을 완성시킬수 있을까? 불가능하다... 뭐 아주 불가능 하지는 않지만 시간이 오~~~래 걸린다.

바로 그렇기 때문에 프로그램 회사 (Microsoft) 같은 곳에서 일반 프로그래머도 10층 빌딩을 신속하게 지어 올릴수 있도록 친절하게 다양한 빌딩을 짓기 위한 '뼈대'와 '재료'를 제공을 해준다.

그것이 바로 COM기반의 DirectShow이다. DirectShow는 멀티미디어 (동영상, 오디오) 를 사용해 결과물을 작성해야 하는 개발자들을 위해 제공되는 다양한 함수와 클래스이다.

하지만 일반 C++ 클래스와는 달리 COM은 매우 인공지능적이다. 우선 스스로 자신의 객체가 몇번이나 복사되었는지를 스스로 관리하여 카운터가 0이되면 스스로 자신을 파괴한다. 고로 컴퓨터에 유령처럼 떠도는 메모리 leak를 원초적으로 차단하고자 했다.

물론 여전히 프로그래머가 메모리 leak를 유발할 수는 있지만 그래도 C++ 클래스 원조보다는 훨씬 영리하다.

또한 '조립'과 '대화'가 가능한 클래스이다. 조립이 가능하다는 것은 COM 객체 생성함수인 CoCreateInstance() 함수의 첫번째 인자와 네번째 인자를 사용자가 적절히 선택함으로써 어떤 '건물의 외관'에 '내부의 기능'을 만들것인지를 정할수 있게 했다.

건물의 외관이 바로 CLSID_ 머리말이 붙은 식별자이며 사실상 이것은 클래스이고 즉, '설명서' 일 뿐이다. CLSID는 Class ID의 약자임을 알았다면 당연한 이야기다.

네번째 인자인 '내부의 기능'IID_ 머리말이 붙은 식별자이며, 이것은 Interface ID의 약자이다. Interface는 한국어로 해석하기 좀 애매하지만 간단히 말하자면 걍 '함수'다. 이 인터페이스는 내가 어떤 기능 (함수)를 사용하고 싶다는 것을 알려준다.

고로 CoCreateInstance()는 사실 내가 만들고자 하는 클래스와 함수를 컴퓨터에 알려주고 COM 라이브러리에서 내가 원하는 형태의 객체를 뚝딱 만들어서 나에게 돌려준다.

다른 한가지 특별한 점으로 '대화'를 꼽았는데 이는 바로 QueryInterface()라는 함수 때문이다. 기본적으로 모든 COM객체는 IUnknown 인터페이스를 가지고 있다. 즉, 모든 COM 객체는 IUnknown 인터페이스가 제공하는 3가지의 함수(QueryInterface,AddRef,Release)를 가지는데 그중 하나가 바로 QueryInterface()함수이다.

이 함수는 COM 객체에게 '너 이 기능 할줄 아니?' 라고 물어보는 역활을 한다. 만약 가능하면 COM 객체는 그 기능으로 향하는 출입문인 Interface Pointer를 리턴하고 만약 안되면 NULL을 리턴하여 불가능 하다고 대답한다.

이전에 내가 COM에 대해서 쓴 글에서도 보면 이 점 때문에 COM은 '뇌를 가진 클래스'라고 했었다. 프로그램 개발자가 모든 함수를 다 알고 있어서 바로 그 함수를 찍어서 호출하는 방법보다 훨씬더 안정적이다. 왜냐면 컴퓨터마다 차이가 있으므로 어떤 컴퓨터에서는 되고 안되고를 알수 없는데 COM 객체를 이용해 QueryInterface를 하면 쉽게 현재의 컴퓨터에서 그 기능이 가능한지 알수 있기 때문이다.

예전에도 말했듯이 이런 COM과 같은 놈들은 C++과는 전혀다른 새로운 언어가 아니다. 이런 COM은 프로그램을 작성하는 '틀'과 '방법'을 제공해주는 거대한 도서관 같은 놈이다. 사용자가 알아야 하는 것은 몇 층의 무슨 책을 찾아야 하는지대출은 어떻게 하는지만 알면 된다. 

DirectShow에서 COM을 사용한 이유는 정확히는 모르지만 동영상과 오디오를 주로 다루는 DirectShow에서는 여러개의 필터들을 연결해서 재생하는데 이런 과정에서 필터 간의 안전한 연결과 실제로 중요한 부분인 Encoding 과 Decoding 부분의 완벽한 정보 은폐, 그리고 아마도 COM 기술을 프로그램 업계의 기반으로 만들려고 그러지 않았을까?... 그럴까?

저작자 표시
이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by 대갈장군
프로그래밍 언어는 사실 사용 방법 보다는 이해가 중요한 것이 요즘 현실인 듯 하다. 오래전부터 차근 차근 개발되어온 언어들은 다양한 특징을 가지게 되었고 그 특징 만큼이나 이름도 다양해 졌다.

그래서 어떤 언어가 어떤 특성을 지니고 있는지와 프로그래밍에 대한 근본적인 이해가 없으면 어떤 언어부터 공부해야 하는지를 전혀 감을 잡을 수가 없다.

그런데 객체 / 객체화 / 추상 클래스는 모든 프로그램 언어에 걸쳐서 등장하는 단골 손님이다. 이 놈들의 정확한 의미에 대해서 잘 이해하고 있다면 프로그래밍이 어떤것인지 알수 있다.

우선 객체와 클래스는 대립되는 의미이다. 클래스는 다른 말로 조립 설명서 이다. 로봇을 만든다고 가정한다면 어떤 어떤 부품이 어떻게 어떻게 연결되는지를 설명해 놓은 조립 설명서이다.

반면 객체화는 이 조립 설명서대로 로봇을 찍어내는 것을 말한다. 이것을 컴퓨터 입장에서 이야기 하자면 클래스는 메모리상에 존재하지는 않지만 객체 (로봇)이 어떤 어떤 속성과 멤버 함수를 가져야 되는지를 설명해 놓은 것이다.

그리고 객체화는 이 클래스가 컴퓨터의 메모리 상에 공간을 차지하게 되는 순간을 말한다. 이것을 수행하는 것이 바로 new 명령이다.

즉, 클래스의 조립 설명서에 따라서 로봇 (객체)를 만들어 내는 것이다.

왜 이런 번거로운 과정을 거쳐야 하느냐 하면, 우선 클래스는 객체의 재사용성과 범용성을 증가 시킨다. 잘 만들어 놓은 클래스 (조립 설명서) 하나로 여러개의 같은 형태의 객체를 마구 마구 찍어낼 수 있다. 게다가 상속과 오버로딩을 통해서 조금 변형된 모습의 새로운 로봇도 쉽게 쉽게 만들어 낼수 있게 된다.

바로 이런 점이 객체 지향 언어의 강점이다.

그래서 고급 개발자들이 멎진 클래스와 그에 딸린 함수들을 만들어 배포하면 (Microsoft) 일반 개발자들이 그 클래스를 바탕으로 객체를 생성하여 함수들을 사용하는 것이다.

물론, 일반 개발자들이 배포되는 클래스에 자신만의 함수를 추가하여 그 동작을 변경하고 싶을 때가 있기 마련이다. 그런 경우에 사용하는 것이 바로 추상 클래스다.

이 추상 클래스는 구현된 것이 전혀 없는 목차만 적혀있는 설명서인 클래스이다. 이것을 사용하는 일반 개발자는 추상 클래스가 가지고 있는 형태 (목차) 만 그대로 지키되 자신이 원하는 함수를 구현하기만 하면 된다.

자바와 같은 언어의 경우 이 추상 클래스가 참 많은데 이런 클래스는 반드시 클래스 내의 특정 함수 (목차) 를 사용자가 구현 해야만 작동하는 클래스다. 고로, 추상클래스는 일반 개발자에게 진정한 의미의 '개발' 을 할수 있도록 도와 주지만 어떤 어떤 함수를 반드시 구현해야 하는지를 목차로써 알려주는 '목차만 있는 설명서' 같은 놈이 바로 추상 클래스다.






저작자 표시
이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by 대갈장군

Paladin

World Of Warcraft 2009/03/12 14:42


가장 쉬운 캐릭터가 사냥꾼인줄 알았는데 막상 성기사를 해보니 재미 + 사냥꾼 보다 더 쉬운 레벨업에 놀랐고 죽음의 기사를 해보고는 성기사보다 쉬운 레벨업 + 무한 연속 사냥에 또 놀랐다. ... 헐헐헐...
저작자 표시
이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by 대갈장군
OpenGL을 Windows API 환경에서 작성하다 보면 Rendering Context 라는 말을 듣게 된다.

처음에 그 단어를 들었을때 '뭐여? 저것이?' 라고 생각했던 기억이 난다. 알고보니 이 Rendering Context 는 Windows API의 Device Context에 대응되는 OpenGL의 Device Context인 거였다.

바로 어제 작성한 글을 보면 Device Context가 무엇인지 말하고 있는데 DC는 특정한 하나의 윈도우의 다양한 그리기 설정을 저장하고 있는 구조체였다.

이런 구조체가 필요한 이유는 윈도우에서 윈도우 마다 서로 다른 형태의 그림과 글자, 선등을 그려줘야 하기 때문이라고 했다.

OpenGL을 Windows 환경에서 사용할 경우 주로 GLUT 를 이용해서 단 하나의 창으로 모든 렌더링을 보여주곤 하는데 이는 사실 여러개의 윈도우를 동시에 사용하는 멀티 태스킹의 윈도우 환경에는 조금 모순적이다.

고로, 지금 나의 경우처럼 Window API를 이용해 OpenGL 프로그램을 작성할 경우, 내가 렌더링한 OpenGL의 결과 화면 (매 프레임)을 특정한 윈도우에 그려야 하는데 이때 어떤 윈도우에 OpenGL을 그려 넣어야 하나 하는 문제가 생긴다.

따라서 Windows 환경에서는 OpenGL 명령들을 (그림 그려내는 명령들) 수행하기 전에 현재의 렌더링 창 (그려지는 놈이 보여질 창)을 지정하는 방법이 필요하다. 바로 그 정보를 저장하는 놈이 Rendering Context 이다. 결국 이 Rendering Context 는 Windows의 Device Context이고 다만 OpenGL에서는 조금 다른 형태의 구조체로 저장이 된다는 점이다. Rendering Context 는 OpenGL 렌더링을 위한 추가적인 멤버 변수들을 가지고 있을 것이다.

Windows 환경 위에서 작성하는 OpenGL은 반드시 하나 이상의 윈도우를 가져야 하므로 최소한 하나의 유효한 DC는 소유하고 있을 것이다.

이 유효한 (유효하다는 의미는 현재의 graphic device와 호환이 되는 pixel format 을 가진 이라는 의미) DC를 이용해서 OpenGL의 Rendering Context 를 얻어온다. 그 함수가 바로 wglCreateContext() 이다.

이 함수는 올바른 픽셀 포맷을 가진 윈도우 창의 DC를 입력으로 받아서 그와 호화되는 형식의 Rendering Context 를 출력으로 돌려준다.

HGLRC hRC;
HDC hDC;
hRC = wglCreateContext(hDC);


특별한 점은 일반적인 윈도우 어플리케이션의 경우에는 여러개의 Context를 가질수 있지만 OpenGL의 경우에는 작업을 할 목적지 윈도우를 정확하게 알아야 하므로 한개의 스레드당 하나의 Rendering Context만 가질수 있다는 점이다.

wglCreateContext() 함수를 이용해서 Rendering Context를 얻은다음 wglMakeCurrent(HDC hDC, HGLRC hRC); 함수를 호출하게 되면 입력 인자로 들어온 Device Context와 Rendering Context를 연결하게 되어 특정한 윈도우 창과 연결된다.

Rendering Context를 지우기 위해서는 wglMakeCurrent(hDC, NULL)을 호출해서 현재 선택된 Rendering Context를 해제하고 wglDeleteContext(hRC)를 호출해서 해제한 Rendering Context를 삭제하면 된다.

주의 할 것은 위의 함수를 호출해서 Rendering Context를 제거하기 전에 Display List와 Texture 개체를 삭제해야 한다.


저작자 표시
이올린에 북마크하기(0) 이올린에 추천하기(0)
Posted by 대갈장군