이전에 D3D 성능 강화를 위해 리눅스에서 직접 DirectX9 렌더링을 했다는 이야기는 들어보셨을 겁니다.(http://moordev.tistory.com/129) 그런데 이제는 LLVM과 새로운 스케쥴러(SI Scheduler)의 힘으로 Catalyst보다 성능을 더 뽑아냈다는 소식이 들려왔습니다.


http://www.linuxsystems.it/2015/08/radeonsi-with-si-scheduler-humiliates-catalyst-in-all-tests/


Test게임은 Metro2033으로 리눅스를 네이티브로 지원하는 게임입니다. 즉 순수 OpenGL성능으로 Catalyst를 이긴 것입니다.


물론 우분투 16.04에서 Catalyst의 지원을 끊어 버린 것도 이러한 배경이 있었던 것이지요. 물론 우분투 기본 드라이버는 성능이 그렇게 나오지는 않습니다. 하지만 PPA를 통해 드라이버를 설치하면 이러한 성능을 느낄 수 있습니다.


그동안 저는 oibaf PPA(https://launchpad.net/~oibaf/+archive/ubuntu/graphics-drivers/)의 드라이버를 사용했었는데 이번에는 다른 PPA를 사용해보겠습니다. 일명 padoka PPA라 불립니다. Paulo dias라는 분이 운영하는 곳으로 oibaf를 기준으로 몇가지 패치를 더 붙여서 배포합니다. 그 중 하나가 바로 LLVM에 추가된 SI Scheduler라는 것으로 약 10%성능 향상을 보입니다.(물론 AMD기준이고 인텔은 잘 모르겠습니다. Nvidia는 그냥 조용히 Nvidia드라이버를 사용하면 됩니다.)


sudo add-apt-repository ppa:paulo-miguel-dias/mesa
sudo apt-get update
sudo apt-get dist-upgrade

그리고 재부팅



그리고 /etc/enviroment나 ~/.profile 파일에 다음과 같은 내용을 추가합니다.

"R600_

DEBUG=sbcl,hyperz,llvm,sisched,forcedma"


이렇게 하고 재부팅을 또 해주시면 각종 Tweak이 적용된 상태로 돌아가게 됩니다.

그런데 이게 Catalyst보다 빠릅니다. 여기에 Gallium Nine을 꺼내면 Windows보다 더 성능이 올라가는 기염을 토합니다. AMD가 하드웨어 문서를 제공하고 약 6년정도 흐른 것 같은데 이제 해커들의 도움을 받아 성능을 끌어올리는데 성공했습니다. AMDGPU PRO라는 드라이버가 곧 나온다고 하는데 기반이 되는 오픈소스가 이 정도면 과연 이 드라이버는 어느정도의 성능이 나올까요? 어쩌면 Windows보다 더 성능이 좋아질지도 모를 일입니다.

,

다들 알다시피 라데온계열은 공식 드라이버를 잘 안 씁니다. Catalyst(패키지명은 fglrx)라 명명된 이 물건은 그야말로 쓰레기로 알려져서 안정성 저하와 패키지 충돌 등 않좋은 것은 다 있었지요. 이게 윈도에서도 마찬가지였던지라 악명이 자자해서 윈도에서도 오픈소스 드라이버를 원한다는 이야기가 들려옵니다.


어쨌건 이런 엉망진창인 드라이버 대신 그동안 잘 사용해 온 드라이버가 radeon드라이버 입니다. 우분투의 기본 드라이버 중 하나입니다. Nvidia의 오픈소스 드라입인 nouveau와는 다르게 워낙 사용자 층이 두터워서 Catalyst의 성능을 따라잡은지 한참 지났습니다.

하지만 워낙 지원 범위가 넓은 덕에 (Wonder시리즈, radeon 7000대~현재) 덩치가 너무 커져 버린 문제가 있습니다. 이전에 이런 문제를 해결하기 위해 R300~R600시절에 radeonhd라는 드라이버가 잠시 나왔지만 gallium프로젝트로 인해 기존 radeon 드라이버로 통합 되었습니다. 그러던 중 지금 R3,4,5,7,9 시리즈가 되면서 새로운 드라이버가 등장했습니다. 그 이름하여 amdgpu입니다.


커널 4.5부터 지원이 시작되었으며 GCN1.1~지원 중입니다. 성능은 radeon과 비교해서 그럭저럭 좋습니다. Catalyst와 이미 엎치락뒤치락 하는 중이니 성능면에서는 좋다고 할 수 있습니다. 하지만 이 새로운 드라이버의 강점은 크기가 작다는 점입니다. 오래된 코드를 쳐냈기에 조금 더 드라이버가 최적화될 여지가 있습니다.


http://www.phoronix.com/scan.php?page=article&item=cat-rad-amdgpu&num=1

실제로 몇몇 부분에서는 radeon에 비해 더 좋습니다. 심지어 Catalyst와 비교해도 꽤 좋습니다. 물론 Catalyst가 조금 더 좋지만 안정성 면이나 드라이버 업데이트 면에서 오픈소스를 더 추천합니다.


우분투 16.04에서 이를 쓰기 위해서는 https://www.linkedin.com/pulse/using-newer-amdgpu-driver-ubuntu-1604lts-dennis-mungai

여기에 나온 데로 해주시면 좋습니다.


우분투 16.04는 4.4커널을 쓰기 때문에 4.5부터 지원하는 amdgpu 드라이버를 쓸 수 없습니다. 그래서 커널 컴파일을 하는 것을 추천하는데

https://github.com/Turbine1991/build_ubuntu_kernel_wastedcores

여기의 커널을 추천하더군요. 이 github는 커널 스케줄러 패치를 적용해주는 스크립트로서 http://www.ece.ubc.ca/%7Esasha/papers/eurosys16-final29.pdf


이 논문은 커널 스케줄러를 개선하는 내용으로 자세는 알 수 없으나 15%정도의 효율이 좋아진다고 합니다. 이걸 적용하는 커널을 컴파일 해주는 스크립트를 사용하면 실제로 그런지는 알 수 없으나 이 논문 내용을 믿는다면 확인이 가능하겠지요.


커널업데이트 방법은 다음과 같습니다.



그냥 github에서 clone받고 스크립트를 순서대로 실행하면 됩니다. 물론 시간은 상당히 걸립니다. 중간중간 물어보는 것도 많으니 마냥 켜놓고 기다린다고 능사는 아닙니다.


아 clone.sh 실행 전에 스크립트 일부를 수정해야 합니다.

clone.sh를 텍스트 에디터로 여신다음

검색-찾아바꾸기 (혹은 그러한 기능)

4.6을 4.7혹은 현재 최신 커널 버전으로 고쳐주시기 바랍니다. 2016년 8월 23일 현재 안정커널 최신판은 4.7이므로 4.7을 받는 것이 좋습니다.


그러면 중간에 버전 선택지에 고치신 최신 버전이 있습니다. 이를 선택해 주시기 바랍니다.


2017.6월 현재 커널 버전이 업그레이드 되어감에 따라 버전 선택의 폭이 넓어 졌습니다. 이제 위의 작업은 안 하셔도 됩니다. 바로 버전 선택이 가능합니다.


중간에 menu.sh 실행 후에 Enable amdgpu support for CIK parts 부분을 yes라고 해야 합니다. 나머지는 별로 문제가 없는데 이 부분이 amdgpu를 사용하는데 제일 중요합니다.



이후 커널 컴파일 한 다음


/etc/default/grub 파일을 편집합니다. 당연히 관리자 권한으로 해야겠지요.


GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"


여기서 splash 뒤에 amdgpu.exp_hw_support=1 modprobe.blacklist=radeon

요걸 적어주시면 됩니다. 그 다음


sudo dpkg linux-*.deb

로 설치하시면 amdgpu드라이버를 사용 할 준비가 되었습니다.


amdgpu드라이버는 oibaf PPA를 사용하시면 됩니다. oibaf PPA등록은 제 블로그에 워낙 자주 나오니 넘어가겠습니다.


,

리눅스에서 AMD는 언제나 찬밥이었습니다. 기본적인 Catalyst의 안정성이 개판이라 그래픽 성능이 영 아니었으니까요.


하지만 그에 대한 반사 이익으로 오픈소스 드라이버가 어마어마하게 발전했습니다. 이제는 Catalyst의 성능을 따라잡고 그 성능을 뛰어 넘기 시작했습니다. 물론 AMD에서 드라이버 관련 문서를 커뮤니티에 제공한 덕이지만 문서만 가지고 성능을 높혔다는 것은 대단한 성과라고 할 수 있습니다.


AMD는 여기에 많은 것을 느낀 것인지 직접 커널 패치를 제공하기 시작했습니다. AMD의 각종 기술을 직접 커널에서 제공 할 수 있도록 드라이버를 제공했다고 생각하시면 되는데요. HSA같은 기술은 물론이고 Windows에서 자주 써먹는 Overdrive 기술을 커널에서 제공하는 패치를 4.5버전에 넣었습니다.


http://www.phoronix.com/scan.php?page=news_item&px=Linux-4.5-Kernel-Week-One


http://www.phoronix.com/scan.php?page=news_item&px=AMDGPU-OverDrive-Support


AMD가 직접 패치를 제공한 것인지 아니면 문서만 제공하고 커뮤니티에서 만든 것인지는 자세히는 모릅니다. 다만 AMD제품의 리눅스 호환성이 굉장히 좋아지고 있고 그에 따라 이미지 개선을 하는 좋은 모습을 보이고 있습니다.


4.5버전에 제공한 이후 오버드라이브를 터미널에서 구동하는 방법으로 개선하고 있습니다.

물론 오버드라이브라는 것이 결국에는 일종의 오버클럭이라 노트북이나 모바일 기기에서는 추천하지 않지만 잠시 성능을 끌어올리는 수준에서는 괜찮은 솔루션으로 평가받고 있습니다.

http://www.amd.com/en-us/innovations/software-technologies/technologies-gaming/over-drive


리눅스 게이밍이 제 블로그에서 자주 나오고 있는데 이러한 몇몇 부분이 저를 도와 주고 있는 셈입니다.

다만 우분투 16.04는 커널버전이 4.4라 오버드라이브가 지원되지 않습니다. 따라서 커널을 업데이트해서 4.8정도로 업데이트 하는 것을 추천 드립니다.


그럼 오버드라이브를 사용하는 것을 알려드리겠습니다. 단, 이 기능은 radeon드라이버가 아닌 amdgpu드라이버를 사용했을 경우에만 작동되며 amdgpu드라이버는 GCN1.2이후 버전은 정식지원 GCN1.0~1.1버전은 실험적기능을 통해(2017년 기준 커널에서 활성화 해야 합니다.) 지원하고 있습니다. 최신식 AMD그래픽카드(R시리즈 이후)를 사용하시는 분들은 바로 사용이 가능하실겁니다.


아직 GUI는 나오지 않았습니다. 사실 맘먹고 만들면 금방 만들 수는 있는데 제가 만들어봐야 더 좋은 물건이 곧 나올 것 같으니 (개인적으로 driconf에서 지원했으면 좋겠습니다.) 그냥 터미널 명령을 우선 알려드리겠습니다.


/sys/class/drm/card0/device/pp_sclk_od


이 부분이 바로 오버드라이브의 설정sysfs입니다. 무슨말인지 잘 모르시겠다고요?


그럼 다음과 같이 명령을 쳐봅시다.

sudo cat /sys/class/drm/card0/device/pp_sclk_od


이렇게 하면 0이라고 나오게 될 것입니다. 커널에 들어간 오버드라이브는 퍼센트로 오버클럭을 시도하는데 지금은 0%의 오버클럭을 했다는 의미입니다.


그러면 이렇게 해봅시다.


sudo echo 5 > /sys/class/drm/card0/device/pp_sclk_od 


이렇게 하고 3D 연산을 해보시면 약간 빨라졌음을 알 수 있습니다. 5%의 오버클럭을 한 것이거든요.


이런 오버드라이브의 최대는 20입니다. 20%만 빨라져도 미친 발열이 나는 것이 현실입니다. 적당히 합시다.

기본적인 Catalyst는 자동 오버클럭을 하는데 아직 리눅스는 자동으로 해주는 데몬이 개발이 안 되어서 이렇습니다. 온도 센서부분과 전압체크 부분이 정상적으로 작동되면 Catalyst와 동일한 성능을 내줄 것으로 기대하고 있습니다. 역으로 말하면 사람이 직접 손대기가 쉽다는 의미이기도 합니다.


예전에 rovclock으로 고생한거랑 비교하면 정말 하늘과 땅의 차이군요. 이렇게 말하고 싶군요.


우리 AMD가 달라졌어요!

,

https://kparal.wordpress.com/2014/03/03/fraps-like-fps-overlay-for-linux/

여기가 출처


이전에 윈도우에서는 Fraps란 유틸리티가 있었습니다. 이 유틸리티의 특징은 게임상에서 한쪽 귀퉁이에 현재 몇 프레임으로 작동하는지 보여주는 것이었습니다. (추후 게임 화면 녹화 기능이 추가되면서 유명해집니다.)


리눅스에서는 오픈소스 드라이버를 사용한다는 가정하에서 이를 명령으로 볼 수있게 해줍니다.


gallium드라이버에서 이를 지원하는데요. 그냥 간단하게


GALLIUM_HUD="fps" mygame


명령을 이렇게 내려주면 됩니다.

mygame대신에 steam을 적은 다음 스팀 게임을 실행해도 정상적으로 작동합니다. OpenGL만 구동되면 다 되는 듯 합니다.


여기에 cpu사용율도 볼 수있는데


GALLIUM_HUD="fps,cpu+cpu0+cpu1+cpu2+cpu3:100" mygame


요렇게 해주시면 됩니다. 이 경우는 CPU가 쿼드코어인 경우이고 코어수에 맞춰서 잘 써먹으면 되겠습니다.


wine을 통한 게임도 실행이 잘 되는군요.

XOSD를 사용한 것으로 쉽게 확인이 가능하다.



,

리눅스에서 게임을 하기위해서 제일 좋은 것은 역시 리눅스 지원 게임을 하는 것입니다. 스팀OS가 세상에 나온 이후 정말 많은 리눅스용 게임들이 나오게 되었는데요. 걔중에는 하프라이프2나 세인츠로우 같은 AAA 게임도 있습니다. 다크 소울도 리눅스로 포팅된다는 이야기가 있군요.


세인츠 로우가 스팀OS와 리눅스로 컨버팅되었다는 뉴스. 이거보고 엄청 좋아했었다.(미리 사두길 잘했어 흑)



하지만 아직도 상당한 게임들은 윈도우 용으로만 나오고 있습니다. 그 이유라고 하면 이미 Direct3D(이하 D3D)로 개발되어져서 OpenGL로 포팅하기 힘들다는 것이 이유라고 합니다. 하지만 D3D로만 만들어졌지만 OpenGL로 포팅된 사례가 상당하기 때문에 이건 귀찮아서 그렇다고 밖에는 생각이 들지 않습니다. (하프라이프2를 비롯한 소스엔진 게임들이 가장 대표적입니다.)


스팀상점의 수많은 리눅스용 게임들. 하지만 아직 갯수가 부족하다.



하지만 이렇게 떠들어봐야 어쩌겠습니까 그냥 까라면 까야 하는 것이 마이너의 비애입니다. 이런 리눅스 게이밍을 위해서 그동안 Wine이 이 쪽으로 상당히 발전한 것도 사실은 이런 배경이 있었던 겁니다. Wine은 처음에는 윈도API 호환성을 위해 만들어졌지만 2006년 이후 DirectX호환성이 상당히 개선되며 리눅스에서의 게임을 상당히 도와줬습니다. 이때 사용된 것이 wined3d 라이브러리인데 이 녀석은 사실 D3D를 OpenGL로 번역해주는 중간 녀석이라고 할 수 있습니다. 그래서 윈도우용 게임이라도 Wine에서 굴릴 때 OpenGL로 렌더링하는 것이 D3D렌더링보다 더 빠른 이유입니다. (WoW같은 경우 OpenGL로 돌아가게 해야 쾌적해집니다.)


이 wined3d는 리눅스에서만 쓰는 것이 아니라 윈도우로도 포팅되어서 OpenGL성능이 막강한 녀석을 도와주거나 (Nvidia가 대체적으로 OpenGL 성능이 좋습니다.) VirtualBox같이 OpenGL만 되는데 D3D가 필요할 때 등등에서 쓰였습니다. 하지만 wined3d는 중요한 맹점이 하나 있었는데 그건 CPU를 엄청 사용한다는 것이었습니다. 그 이유라고 하면 가장 대표적인 것이 좌표계가 달라서 이를 일일이 변환해야 하는 것과 DirectX9이후로 Shader가 발달했는데 DirectX의 쉐이더를 GLSL(OpenGL Shader)로 번역을 해야했던 것 등등 이유가 많습니다. 이런 것을 전부 소프트로 처리했으니 CPU가 무지막지하게 쓰인 것입니다.


이런 CPU의 낭비는 결국 성능 저하로 나타나게 되었습니다. 하지만 그 때까지만 해도 어쩔 수 없었습니다. 그 당시 그래픽 가속은 오픈소스 OpenGL 라이브러리인 Mesa를 써야만 가능했으니 이를 써야 그래도 게임이 굴러갔으니까요. 하지만 이후 리눅스에서 2008년 Gallium 프로젝트가 시작되면서 상황이 갑자기 변하기 시작했습니다.


Gallium 프로젝트는 VGA에 하드웨어 레벨로 접근하는 라이브러리로 그동안 Classic Mesa가 X를 거쳐서 VGA에 접근하던 것과 달리 OpenGL API가 커널을 통해 그래픽카드에 직접 접근해서 VGA를 제어하는 방식이었습니다. 덕분에 OpenGL 렌더링 속도가 상당히 빨라졌습니다.

그런데 Nvidia는 이전부터 커널에서 하드웨어 제어를 하고 있었고 안정성이 상당했었기에 Nvidia에 한해서 Gallium 프로젝트는 무시 당하고 있었다고 해도 과언은 아닙니다. 하지만 AMD(당시ATI)는 거지같은 드라이버대신 오픈소스 드라이버를 사용하고 있었고 AMD에서 드라이버관련 문서를 커뮤니티에 제공하면서 이 Gallium 프로젝트의 혜택을 제일 많이 본 하드웨어로 손 꼽히게 됩니다. 인텔도 Gallium프로젝트의 혜택을 봤지만 기본적인 하드웨어 성능이 낮아서 큰 성능 향상은 없었다고 합니다.


2008년 Freedesktop.org에 의하면 Gallium 프로젝트는 하드웨어 레벨로 커널이 직접 접근하기 때문에 그래픽 카드를 사용하는 다른 기능도 이를 통해 접근이 가능하다는 이야기가 있었습니다. 사실 저는 그냥 그러려니 하고 있었습니다. 그래픽카드를 써봐야 3D가속하고 VIVO기능이 있다면 화면 입력 정도? 이렇게만 생각했었습니다. 그런데 세월이 지나니 진짜 Gallium프로젝트가 먼 미래를 보고 시작한 프로젝트라는 것이 실감되더군요.

바로 Gallium 덕에 VDPAU(동영상 가속)를 리눅스에서 쓸 수 있게 되었고 OpenCL과 CUDA를 사용할 수 있게 되었습니다.(Nvidia는 독점 드라이버를 설치하면 CUDA가 가능하기는 했었습니다. 오픈소스 드라이버는 불가능 했었지만)


이런 Gallium 프로젝트도 한 가지 문제가 있었는데요. 바로 wined3d가 계속 병목현상을 일으켰다는 겁니다. 아무리 렌더링 속도가 빨라봐야 중간에 D3D를 OpenGL로 바꾸는 중간에 CPU성능을 잡아먹고 또 GPU대신 CPU가 개입하니 느려져서 Windows 네이티브에 비해 상당히 성능 하락이 심했던 것입니다.


그래서 나온 것이 Wine-Staging의 CSMT 패치입니다. wined3d를 처리하는 것을 멀티코어 를 사용해서 최대한 병목을 줄이는 것에 초점을 맞춘 패치입니다. 덕분에 CSMT기능을 켜면 CPU가 사용률이 90%이상으로 치솟는 것을 볼 수 있습니다. 하지만 멀티코어이기 때문에 효율이 상당히 좋아서 기본 wined3d에 비해 30%성능 향상이 되는 것을 볼 수 있습니다.


여기에 Gallium프로젝트는 하드웨어 레벨이라는 특성을 써서 리눅스에서 D3D를 굴리는 것을 시작하게 되었습니다. 통칭 Gallium nine이라고 부릅니다. 현재는 D3D9c 까지만 지원이 되지만 프로젝트가 진행되면 D3D10도 가능할 것으로 생각됩니다. XP의 지원이 끝나면서 D3D9을 사용하는 경우가 이제는 철지난 게임들 뿐이지만 리눅스에서 성능이 더 나온다는 말도 안되는 일도 벌어지는 중입니다.


게다가 Gallium Nine 개발자 인터뷰에서는 https://www.gamingonlinux.com/articles/an-interview-with-gallium-nine-project-developer-axel-davy.4949

리눅스 네이티브 프로그램이 D3D9을 사용 할 수도 있다고 나옵니다. 이렇게 되면 말이 안 되는 수준이 아니라 MS가 황당해 할 수준입니다. 물론 실제로 프로그램이 나올 지는 두고봐야 겠습니다.


실제로 지금 CSMT기능으로 게임을 굴려본 결과 상당한 성능 향상을 경험했고 쿼드 코어를 쓰고 있기에 상당히 만족스러운 수준입니다. 그런데 Gallium-nine을 쓴다면 이야기가 또 달라지겠지요. 실제로 게임을 해보고 성능 향상을 알아보도록 하겠습니다.





Gallium Nine은 드라이버를 업데이트하는 수고가 필요하지만 CSMT는 PlayonLinux를 쓰신다면 바로 경험해 보실 수 있습니다.


도구-Wine버전 관리에서 Wine을 추가하실 때 staging이 붙은 녀석을 다운로드 받으시면 됩니다.

staging이라 써있는것을 선택해서 설치하자

Wine설정에서 위와 같이 체크하면 CSMT 설정 끝


gallium-nine은 이전에 소개했던 Oibaf PPA에서 제공합니다.

https://launchpad.net/~oibaf/+archive/ubuntu/graphics-drivers



명령은 이렇게 내리면 되겠지요.


sudo add-apt-repository ppa:oibaf/graphics-drivers

sudo apt-get update

sudo apt-get dist-upgrade


sudo apt-get install libxcb-xfixes0 libxcb-xfixes0:i386 libegl1-mesa libegl1-mesa:i386 libasound2-plugins:i386 libgstreamer-plugins-base1.0-0:i386


여기에서 제공하는 드라이버가 Gallium nine패치가 적용된 드라이버입니다.


그리고 여기 있는 Wine을 사용합니다.

https://launchpad.net/~commendsarnex/+archive/ubuntu/winedri3

PlayonLinux를 쓰시지 않으신다면 여기있는 Wine을 쓰시면 됩니다. 하지만 시스템 Wine을 바꾸는 것은 별로 추천되지 않습니다.


PlayonLinux를 쓰신다면 Deb을 설치하는 것이 아니라 ~/.PlayonLinux/wine/linux-x86 혹은 linux-amd64 에다가 각 비트수에 맞는 패키지를 풀어주셔야 편리합니다.


이것을 다시 설명하면


https://launchpad.net/~commendsarnex/+archive/ubuntu/winedri3/+packages

여기로 접속합니다.



우분투 버전에 맞는 부분을 클릭합니다.



보통 게임용은 32비트이므로 i386을 쓰는 것이 좋다. 물론 amd64를 쓴다고 문제 되는 일은 없다.(lib32가 존재하기 때문)


보통 게임은 32비트 버전을 사용하기 때문에 i386버전을 다운로드 받는 것이 좋습니다. 만약 64비트 지원 프로그램이라면 amd64로 다운로드 받으시는 것이 좋습니다.



그 다음 동그라미 쳐 놓은 두 deb 파일을 받아주시면 됩니다. 위 스크린샷에서는


wine1.9_1.9.15-1+gallium-nine~x_i386.deb

wine1.9-i386_1.9.15-1+gallium-nine~x_i386.deb


두 가지 이군요. 이 글을 보시는 시기와 우분투 버전에 따라 파일명은 달라질 수 있습니다.

그러니까 dbg와 dev 가 붙지 않은 패키지 중에서 크기가 작은 한 패키지를 제외하고 나머지 두 개란 의미 입니다.


그 다음 DEB파일을 압축을 풀어서 PlayonLinux에서 사용하게 하면 됩니다.


우선 i386패키지를 다운로드 받으셨다면

~/.PlayonLinux/wine/linux-x86

여기로

amd64패키지를 다운로드 받으셨다면

~/.PlayonLinux/wine/linux-amd64

여기로 들어가신 다음 wine-gallium-nine이라는 이름의 폴더를 하나 만듭시다.


이걸 단순 명령으로 처리한다면

cd ~/.PlayonLinux/wine/linux-x8

mkdir wine-gallium-nine (i386)


~/.PlayonLinux/wine/linux-amd64

mkdir wine-gallium-nine


이렇게 하면 wine-gallium-nine 이라는 아까 다운로드 받은 DEB의 압축을 풀어버리는 겁니다. 단 deb을 그냥 풀면 control.tar.gz과 data.tar.xz 두가지가 나오는데 data.tar.xz파일 열고 또 그안에서 /usr 폴더에 있는 내용만 풀어야 합니다. 


그냥 압축프로그램에서 data.tar.gz까지 열어버린 뒤에 /usr내의 내용만 아래 그림처럼 드래그 해주시면 됩니다.



그러고 PlayonLinux의 Wine버전 관리 메뉴에 들어가면 여러분이 만드신 폴더명으로 Wine이 추가 되어있는 것을 알 수 있습니다.


그 다음 Gallium-nine을 사용하기 위해서는 약간의 삽질이 더 필요한데 이는 아치위키와 포럼에 설명 되어있습니다. 우분투 사용자들도 애용하는 위키이니 아치 포럼의 https://bbs.archlinux.org/viewtopic.php?id=192761부분을 보도록 하겠습니다.


다른 부분은 필요없고 프로그램 실행을 다음과 같이 하라고 나와있습니다.


$ env WINEARCH=win32 DRI_PRIME=1 thread_submit=true wine program.exe


여기서 제일 중요한 부분이 바로 이 thread_submit=true 부분입니다.


이 옵션을 켜야 정상적으로 DX9으로 작동됩니다. 만약 멀티스레드가 아닌 게임이라면 저 부분이 없어도 되는데 요즘에 나온 프로그램치고 멀티스레드가 아닌 경우가 거의 없으므로 저 옵션은 필수입니다.


PlayonLinux를 쓰신다면



여기에 이렇게 적어주시면 편리합니다.


그리고 Wine 설정에서 Staging 탭에서 Enable Gallium nine에 체크해주시면 됩니다.




한번 성능을 비교해 볼까요? 테스트 게임은 DirectX 9게임 중에서 발적화로 유명한 Dead or Alive입니다. 같은 DX9라도 심하게 발적화라 상당한 성능을 요구합니다. 


TEST기기는

AMD APU 6410 BEEMA

DDR3 8GB

HDD 7200rpm


꽤나 극한 환경입니다. 일반적인 하드웨어에서는 성능으로 씹어먹기 일수라서 하드웨어 제약을 좀 심하게 걸었습니다. (사실 제가 사용하는 시스템입니다. 리눅스를 쓰는 이유 중 하나입니다.)


우선 기본 wine상태 입니다. wined3d를 사용하는 것이고 OpenGL변환을 사용합니다.

18프레임~20프레임가량 나옵니다. 버벅 거리는 것이 눈에 보입니다. CPU사용율은 그렇게 높지는 않습니다. (CPU0만 갈구는 것은 이 게임 특징입니다.)




wine-csmt를 사용하는 형태입니다. wined3d를 사용 OpenGL변환을 하지만 멀티 스레드를 사용하기 때문에 코어수가 많으면 효율이 좋아집니다.

CPU사용율이 굉장히 높습니다. 평균 프레임은 30프레임입니다. 물론 이 정도면 게임하는데 크게 지장은 없습니다.


galllium-nine을 사용하는 경우입니다. OpenGL변환을 하지 않고 리눅스 드라이버에서 DirectX 렌더링을 직접 합니다.

CPU사용율은 발적화 게임 특성상 cpu0만 심하게 갈구는데 사실 이건 이 게임 특징입니다.평균 프레임은 40~45프레임 정도 입니다. 상당히 할 만한 수준입니다.


CSMT나 Gallium-Nine은 D3D 게임에서 성능 향상을 노리는 솔루션입니다. 만약 해당 게임이 OpenGL을 지원한다면 그냥 조용히 OpenGL을 쓰는 것을 추천드립니다.


하지만 D3D 게임은 성능 향상 폭이 상당하니 좀 시기가 많이 지나기는 했지만 D3D9 게임을 리눅스에서 하신다면 Gallium-nine 설정을 하시거나 드라이버를 PPA에서 설치하는 것이 조심스럽다면 CSMT기능을 사용 하시는 것을 추천합니다.



,


예전에 학생시절에는 PSP를 참 갖고 싶어했습니다. 지하철에서 플레이 하는 사람들을 보면 참 부러웠었지요.

그리고 세월이 지나 지금. PSP는 과거의 유물이 되었고 지금은 다들 스마트폰을 들고 다닙니다. 그리고 PPSSPP란 에뮬레이터가 나와서 PSP게임을 굴릴 수 있게 되었습니다.


하지만 터치인터페이스는 무진장 게임하기 불편했습니다. 그래서 스마트폰용 조이패드를 차던중 이런 녀석이 있더군요.



로지텍 파워쉘입니다. 문제는 이놈은 아이폰 전용이었고 범용성은 내다 버린 것이 문제였습니다. 사실 전 이런놈이 있는 줄도 몰랐는데 누가 컨셉 겹친다고 해서 찾아봤더니 있더군요. 결국 덤핑했다는 후문이 있지만...



어쨌거나 저는 대충 연구실에서 시간 나는대로 게임용 컨트롤러를 만들기로 했습니다.


그래서 만든 것이 바로 위의 물건입니다. 아직 하우징은 만들어지지 않았고 동작만 되는 형편입니다.


일단 제작을 위한 준비물은...



일단 준비물은 아두이노를 썼으니 아두이노가 필요하겠지요. 크기가 크면 문제가 많으므로 작은 모델이 필요합니다. 그리고 조이패드로 인식 시켜야 했으므로 Leonardo와 호환되어야 했지요. 그래서 찾은 모델이 이 모델입니다. 위의 것은 SparkFun 정품이고 아래의 물건은 그것의 호환 제품입니다. 어떤 것을 써도 상관없습니다. 개인적으로 호환품도 크게 문제는 없었습니다.


(프로 마이크로 입니다. 프로 미니, 나노 아니에요!)




버튼도 SparkFun제품을 사용했습니다. 이런 식을 나온 버튼이 상당히 누르는 것이 좋더군요. 하우징 설계할 때도 편리합니다. 뭣하면 다른 스위치를 써도 그만입니다.


조이패드도 SparkFun 호환품으로 구입. 사실 아두이노 키트사면 들어있어요.



그리고 대망의 스마트폰 고정 가이드는 없는 것 빼고 다 판다는 Coms의 제품입니다. 진짜 이 회사의 내부가 궁금합니다. 매번 있을까? 라고 생각하면 있습니다. 우리나라에서 이런 회사가 있다는 것이 자랑스럽습니다.



그외에 준비물로는 부품 고정용 만능 기판 PCB(대충 사서 톱으로 썰어야 합니다.)와 USB OTG케이블, 그리고 USB micro B 케이블(스마트폰 데이터 케이블도 상관없습니다.) 다 Coms에서 팔아요....


음...배선을 깜빡했네요. 배선은.... 그냥 아두이노 책을 보시고 해주시길 바랍니다.(...)


버튼들은 GND와 각 디지털 핀.(Tact스위치는 4개의 다리 중 대각선으로 해주시는 것이 정신건강에 좋습니다. 2개씩은 사실 하나의 다리라 헷갈리면 X되요.


조이패드는 핀배열에 맞게 해주시면 됩니다.


5V-5V

GND-GND

VRx-A0

VRy-A1

SW - 디지털핀 아무거나


그리고 프로그램은 우선 라이브러리를 설치해야 하는데

https://github.com/MHeironimus/ArduinoJoystickLibrary


이것을 사용합니다.

파일 다운로드는 https://github.com/MHeironimus/ArduinoJoystickLibrary/archive/master.zip


위 파일을 다운로드 받은다음


아두이노 IDE에서

스케치- 라이브러리 가져오기-Add Library를 선택하고

해당 파일을 선택합니다.


그리고 아두이노에 넣을 스케치는 다음과 같습니다.


 // Simple example application that shows how to read four Arduino
// digital pins and map them to the USB Joystick library.
//
// The digital pins 9, 10, 11, and 12 are grounded when they are pressed.
//
// NOTE: This sketch file is for use with Arduino Leonardo and
//       Arduino Micro only.
//
// by Matthew Heironimus
// 2015-11-20
//--------------------------------------------------------------------

#include <Joystick.h>

void setup() {
  // Initialize Button Pins
  pinMode(0, INPUT_PULLUP);
  pinMode(1, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);
  pinMode(12, INPUT_PULLUP);
  pinMode(13, INPUT_PULLUP);
  pinMode(14, INPUT_PULLUP);
  pinMode(15, INPUT_PULLUP);
  pinMode(16, INPUT_PULLUP);
  // Initialize Joystick Library
  Joystick.begin();
}

// Constant that maps the phyical pin to the joystick button.
const int pinToButtonMap = 0;
const int deadZone = 30;

// Last state of the button
int lastButtonState[17] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
//int lastButtonState[4] = {0,0,0,0};
int X=0;
int Y=0;

void loop() {

  // Read pin values
  for (int index = 0; index < 17; index++)
  {
    int currentButtonState = !digitalRead(index + pinToButtonMap);
    if (currentButtonState != lastButtonState[index])
    {
      Joystick.setButton(index, currentButtonState);
      lastButtonState[index] = currentButtonState;
    }
  }
  X=analogRead(A0);
  Y=analogRead(A1);
  X=map(X,0,1023,127,-127);
  Y=map(Y,0,1023,-127,127);
  Joystick.setXAxis(X);
  Joystick.setYAxis(Y);

  delay(50);
}


간단하죠? 좀 반응이 느리다 싶으시면 delay를 20정도로 줄여주시면 됩니다. 저는 가끔 느린 것을 느끼기는 하는데 그냥 냅두고 있습니다.


그렇게해서 만들어진 대망의 물건



저는 실력이 미천하여 이정도밖에 못했지만 실력 좋으신 분들은 훨씬 더 좋은 물건을 만들 수 있을 거라고 봅니다.




==================2017. 5. 25======================


아두이노용 조이스틱 라이브러리의 버전이 업그레이드 되었습니다.

https://github.com/MHeironimus/ArduinoJoystickLibrary


이전과 동일한 곳이지만 그전에는

X,Y 축과 버튼까지만 지원했지만 이제는 거의 표준이라 할 수 있는

아날로그 스틱

HAT 방향키

트리거

버튼


이렇게 지원합니다. 즉, 엑스박스 패드의 형식을 그대로 지원하고 엑스박스 패드를 지원하는 게임에서 정상적으로 작동되게 할 수 있습니다.


제가 만든 구조는


왼쪽 4개의 버튼은 방향키로

아래의 아날로그는 HAT으로

오른쪽은 버튼으로 인식되게 했습니다.


하지만 마음을 먹으면 아날로그 스틱을 2개 달고 엑스박스 패드처럼 만들 수도 있는 것이지요.


그래서 이번에 수정한 소스를 공개합니다.


#include <Joystick.h>

Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_GAMEPAD,
  5, 1,                  // Button Count, Hat Switch Count
  true, true, false,     // X and Y, but no Z Axis
  false, false, false,   // No Rx, Ry, or Rz
  false, false,          // No rudder or throttle
  false, false, false);  // No accelerator, brake, or steering


int lastDpadState[]={0,0,0,0};
int lastButtonState[]={0,0,0,0,0,0,0};
int lastSWState=0;

void setup() {
  // Initialize Button Pins
  pinMode(10, INPUT_PULLUP);//A
  pinMode(14, INPUT_PULLUP);//B
  pinMode(15, INPUT_PULLUP);//X
  pinMode(16, INPUT_PULLUP);//Y
 
  pinMode(6, INPUT_PULLUP);//Up
  pinMode(8, INPUT_PULLUP);//down
  pinMode(7, INPUT_PULLUP);//left
  pinMode(9, INPUT_PULLUP);//right
 
  pinMode(2, INPUT_PULLUP);//HAT_SW

  pinMode(11, INPUT_PULLUP);
  pinMode(12, INPUT_PULLUP);
  pinMode(13, INPUT_PULLUP);
 /*not using pin Num
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);

  digitalWrite(11,LOW);
  digitalWrite(12,LOW);
  digitalWrite(13,LOW);  
  */
  //A0=X A1=Y

  // Initialize Joystick Library
  Joystick.begin();
  Joystick.setXAxisRange(-1023, 0);
  Joystick.setYAxisRange(-1023, 0);

  Joystick.setRxAxisRange(-1, 1);
  Joystick.setRyAxisRange(-1, 1);
}

void Analog()
{
  int x = analogRead(A0);
  int y = analogRead(A1);
 
  Joystick.setXAxis(-x);
  Joystick.setYAxis(-y);
}

void Buttons()
{
  for(int index=0; index < 7 ;index++)
  {
    int currentButtonState = !digitalRead(index+10);
    if (currentButtonState !=lastButtonState[index])
    {
      //Joystick.setButton(index, currentButtonState);
      switch (index)
      {
        case 0://A
          Joystick.setButton(0, currentButtonState);
          break;

        case 4://B  
        case 5://X
        case 6://Y
          Joystick.setButton(index-3,currentButtonState);
          break;
          
        default:
          break;
      }
      
      lastButtonState[index]=currentButtonState;
    }
  }
 
}


void Dpad()
{
  for (int index = 0; index < 4; index++)
  {
      int currentDpadState = !digitalRead(index+6);
      if (currentDpadState != lastDpadState[index])
      {
        switch(index){
          case 0://UP
            if (currentDpadState == 1) {
              Joystick.setRyAxis(1);
            } else {
              Joystick.setRyAxis(0);
            }
            break;
          
          case 1://left
          if (currentDpadState == 1) {
            Joystick.setRxAxis(-1);
          } else {
            Joystick.setRxAxis(0);
          }
          break;
            
          case 2://down
          if (currentDpadState == 1) {
            Joystick.setRyAxis(-1);
          } else {
            Joystick.setRyAxis(0);
          }
          break;

          case 3://right
          if (currentDpadState == 1) {
            Joystick.setRxAxis(1);
          } else {
            Joystick.setRxAxis(0);
          }
          break;
            
        }
        lastDpadState[index] = currentDpadState;
      }
  }
}


void HAT()
{
  bool valueChanged =false;
  for (int index = 0; index < 4; index++)
  {
      int currentDpadState = !digitalRead(index+6);
      if (currentDpadState != lastDpadState[index])
      {
        valueChanged =true;
        lastDpadState[index] = currentDpadState;
      }    
  }

 
  if (valueChanged) {
      
    if ((lastDpadState[0] == 0)
      && (lastDpadState[1] == 0)
      && (lastDpadState[2] == 0)
      && (lastDpadState[3] == 0)) {
        Joystick.setHatSwitch(0, -1);//HatSwitch0 is not changed
    }
    if (lastDpadState[0] == 1) {
      Joystick.setHatSwitch(0, 0);
    }
    if (lastDpadState[1] == 1) {
      Joystick.setHatSwitch(0, 90);
    }
    if (lastDpadState[2] == 1) {
      Joystick.setHatSwitch(0, 180);
    }
    if (lastDpadState[3] == 1) {
      Joystick.setHatSwitch(0, 270);
    }
  }//value Changed()
}
void SW()
{
  int currentSWState = !digitalRead(2);
  if(lastSWState != currentSWState)
  {
    Joystick.setButton(4, currentSWState);
    lastSWState=currentSWState;
  }
}

void loop()
{
  Analog();
  //Dpad();
  HAT();
  Buttons();
  SW();
  delay(2);
}


회로 연결은


0번 버튼은 10번핀에

1번 버튼은 14번핀에

2번 버튼은 15번핀에

3번 버튼은 16번핀에


방향버튼(D-PAD)는

위버튼은 6번핀

왼쪽버튼은 7번핀

아래버튼은 8번픈

오른쪽 버튼은 9번핀 으로 연결합니다.


D-PAD는 HAT0로 인식되게 됩니다.


그리고 아날로그는 X축은 A0 Y축은 A1로 연결합니다.

만약 방향이 반대로 인식될 경우에는 위 소스에서 Analog()함수를 찾으신 다음


  Joystick.setXAxis(-x);
  Joystick.setYAxis(-y);


이 둘에서 -를 지워주시고 Seup()안의


  Joystick.setXAxisRange(-1023, 0);
  Joystick.setYAxisRange(-1023, 0);


이 두줄을 삭제해 주시면 됩니다.


아날로그 스틱을 눌렀을 때 스위치는 2번 핀에 연결했습니다.

제가 사용한 Arduino Pro Micro의 구조상 이 구조가 가장 간단해서 이렇게 만들었습니다.


코드나 회로에 자신있으신 분들은 제대로 만드실 수 있을 겁니다.

,

Avidemux는 옛날 VirtualDub을 대체하는 대표적인 오픈소스 프로그램입니다. 실제로 성공적으로 안착했고 지금은 VirtualDub이 뭐였는지도 모르는 사람이 많을 정도입니다.


그런데 그동안 우분투에서 공식적으로 제공해주던 Avidemux가 16.04에서 제공이 되지 않습니다. 새로바뀐 libx264때문이라는데요. 호환문제가 있다면 어딘가에서는 호환문제를 해결했을 겁니다.


역시나 호환문제가 해결된 PPA가 있었습니다.


설정-소프트웨어 & 업데이트를 선택합니다.

기타소프트웨어 탭


추가버튼을 누르고


deb http://archive.getdeb.net/ubuntu xenial-getdeb apps  


위 내용을 추가합니다.

그리고 확인 후 터미널을 열고

wget -q -O- http://archive.getdeb.net/getdeb-archive.key | sudo apt-key add -

위 명령을 칩니다.


그 다음


sudo apt-get update

sudo apt-get install avidemux2.6-qt


이제 Avidemux를 설치할 수 있게 되었습니다.


우분투 16.04에서 Avidemux를 쓸 수 있다.


,

어쩌면 황당할 수도 있고 어쩌면 당연할 수도 있지만 제 블로그 방문객들의 정보를 조금 살펴봤습니다.


제 블로그에는 구글의 애널리틱스가 적용되어 있습니다. 제 블로그에 들어오신 분들의 운영체제와 브라우저를 확인하고 약간의 연구를 위해서 6월 한 달 동안 방문객 상황을 확인을 해봤습니다.

우선 브라우저 통계입니다.


브라우저는 크롬이 제일 많은 것으로 나왔습니다. 그도 그럴 것이 전 세계적으로 크롬의 점유율이 60%가 넘었다는 것은 모두가 알고 있는 사실입니다. 그래서 마이크로소프트가 Edge를 만들 때 크롬을 벤치마크 했다는 것은 알게모르게 유명한 이야기입니다. 16%의 IE가 보이는데 제 블로그는 성향상 당연하게도 IE를 싫어합니다. 그래도 의외로 선전하고 있네요. Firefox가 그 뒤를 바로 뒤쫓고 있습니다. 저는 Firefox의 변종인 PaleMoon을 쓰는데 제가 접속을 하면 Firefox로 잡히게 됩니다. 따라서 저 Firefox의 세션 수에서 100~200정도를 빼야 진짜 Firefox로 접속한 방문객 수가 나오게 될 겁니다.


그런데 이상하다는 생각이 드는 것이 이 블로그는 우분투 블로그입니다. 우분투관련 자료를 찾으러 혹은 정보를 찾으러 오시는 분들이 많을텐데 우분투의 기본브라우저인 Firefox가 Windows의 브라우저인 IE보다 적습니다. 이 의문은 운영체제 분석을 보니 바로 알 수가 있었습니다.

우선 제 블로그에서 모바일파트를 확인했습니다. 우선 iOS가 220세션이라고 나옵니다. iOS에서 다른 브라우저는 쓸 것이 못 됩니다. 따라서 위의 브라우저 통계에서 iOS통계의 대부분은 위의 사파리 통계 안에 있다고 봐야 합니다. 실제로 둘이 비슷합니다. 1위는 당연하게도 안드로이드인데 한국에서 안드로이드 점유율이 70%를 돌파한지 오래이기 때문에 당연하다면 당연하다고 할 수 있습니다. 게다가 저는 안드로이드 관련 글도 적고 있습니다. 많이 들어올 만 합니다. 그러면 여기서 위의 크롬을 신경써야 하는 이유가 나오게 됩니다.


안드로이드의 4.0버전 이후 기본 브라우저는 크롬입니다. 실제로 User-Agent String을 보면 안드로이드에서 접속을 해도 크롬이라고 적혀있는 것을 알 수 있습니다. 그런데 781이면 좀 적군요. 즉 대부분 방문객은 데스크탑으로 들어오신 겁니다. 우분투 블로그니까 그러려니 했습니다. 그런데...

여느 블로그와 다를 것 없는 분포도!!!! Linux가 Mac보다 높은 것이 특징이라면 특징이지만...


Windows 접속량이 Linux의 2배를 넘습니다. IE가 접속량 2위인 의문이 풀리는 순간입니다. Windows로 제 블로그에 접속하는 분들이 의외로 많았군요. 제 블로그에서 딱히 긁어갈 정보는 적다고 생각했었는데 아마도 VirtualBox로 우분투를 설치해서 쓰시는 분들이거나(가상머신에서 인터넷하면 죽을맛이지요. 이해합니다.) 회사에서 우분투 사용 정보를 찾는데 사무실PC는 Windows이거나 한 경우인 듯 합니다. 우분투를 저처럼 취미 혹은 주력으로 쓰는 사람은 대한민국에서 꽤 적기 때문에 이런 결과가 나온 것이 아닐까 하는 생각이 드는데요. 그래도 Linux 20%가 Linux1%도 안 되는 나라에서 리눅스 관련 블로그임을 다행히 대변해 주는 듯 합니다.


미리 말씀드리지만 제 블로그에서 해외 접속 비율은 무시할 수 있는 수준입니다. 한국어로만 되어있어서 그렇기도 하고 제가 영어권 사람들을 전혀 배려하지 않았기 때문이기도 합니다. 뭣하면 구글링하면 다 나오니까 굳이 제 블로그에 해외 언어권에서 올 이유가 없습니다. (저부터 필요하면 영어로 구글링합니다. 그렇게 찾은 해답을 블로그에 적기도 하고요.) 결론적으로 말하면:

 제 블로그만 봤을 경우지만 "우리나라 사람들 중에서 우분투라는 것을 아는 사람들은 Windows를 설치한 후에 Chrome도 같이 깐다." 라는 결과가 나오는데요. 다른 사람들은 어떻게 나오는지 궁금하네요. 이런 것을 모으다보면 재미있는 통계학 논문 하나가 나올지도 모르겠습니다.


어쨌거나 흥미로운 결과가 나왔습니다. 저는 Firefox 신봉자이지만 Chrome이 정말 대중화가 잘 되었군요. IE쓰면 컴맹이라는 의견을 주신분도 있지만(사실 대다수 컴맹들이 IE만 쓰기는 합니다. 그렇다고 Chrome 쓰는 사람중에 컴맹이 없는 것은 아니지만)기본 브라우저라는 특성상 어쩔 수 없을 듯 합니다. (Chrome보다 화면 갱신이 빠르던 Edge는 어떻게 되었는가!!!)

일단 6월~현재까지의 결과가 이렇고 학생들의 방학이 시작되는 7월부터는 어떻게 되는지 한번 보도록 해보지요. 그래봐야 블로그 특성상 별 차이 없을 것 같지만(...)

,


작은 스마트폰에 컴퓨터의 화면을 띄우는 것을 목적으로 삽질을 했습니다. 사실 VR용으로도 써 먹어보려고 한 것도 있습니다. VNC도 있고 많이 있지만 저는 여기서 한 걸음 더 나가 PC의 HDMI포트, 혹은 외부 모니터 단자를 사용하여 하드웨어 적으로 네트워크로 뿌리는 것을 목표로 했습니다. 다행히 VNC 수준의 절망적인 속도는 안 나오더군요.


그러기 전에 하드웨어 신호를 직접 네트워크로 뿌려야 하니 필수 하드웨어인 캡쳐보드가 무엇인지 알아야겠습니다. 캡쳐보드는 말 그대로 영상입력장치입니다. 비싼것은 100만원이 넘어가는데다 그나마 쓸만한 놈도 10만원 안팎합니다. PCI슬롯이 없는 노트북에서 사용하려면 Firewire나 USB를 써야 하는데 요새는 Firewire도 없지요. 그 USB방식 캡쳐보드 중 그중 제일 싸구려에 제일 만만하고 제일 여기저기 사용되는 물건이 Easycap(DC-60)입니다. 특징으로는 3만원도 안 되는 가격에 짝퉁이 좀 있어서 대략 4개 업체에서 같은 이름으로 팔고 있습니다.


STK

somagic

UTV007

eMpia


대략 알려진 것은 이렇습니다. 이중 제일 만만한 것이 STK칩셋을 사용한 제품이지만 문제는 어떤게 STK칩인지 모른다는 겁니다. 제일 리눅스에서 사용하기 고통스러운 제품은 somagic칩셋입니다. 다른 칩셋은 커널에 드라이버가 내장되어 금방 잡히지만 somagic은 Broadcom제품처럼 따로 펌웨어를 넣어줘야하는 문제가 있습니다.


저는 일단 국내에서 구하기 쉬운 쪽을 택하기 위해서 조금 신기해보이는 것은 다 파는 컴스마트에서 찾아봤습니다. 역시 있더군요. (하여간 여기는 제가 갖고 싶다고 생각들면 어느새 들여놓습니다. 신기한 회사입니다.)


헐 같은 이름의 물건이 3개다.

이중에서 가운데있는 물건이 eMpia칩셋입니다. 다른 것은 어떻냐고요? 다 Somagic입니다. 오른쪽의 것을 구입했다가 눈물 흘렸던 것은 비밀입니다.


Somagic만 피하면 일단 리눅스로 캡쳐하는 것은 어렵지 않습니다. 드라이버가 내장되어 있어서 별 문제가 없거든요. STK는 Lanstar란 업체에서 수입하는 것을 보이는데 구입해서 뜯어보지 않으면 모른다고 합니다. 그냥 참고하세요.


그럼 리눅스에서 캡쳐는 어떻게 할까요?


일단 제일 쉬운 방법은 http://easycap.blogspot.kr/p/easyview-n-cap.html 이곳에 있는 TVcap 스크립트를 사용하는 겁니다. 일단 실행만 하면 GUI로 옵션을 선택할 수 있어서 편리합니다. 특히 기능이 워낙 충실해서 쓸 곳이 많은 데 EasyCap 사용시 얼어붙어버리는 VLC의 버그를 회피 할 수 있어서 굉장히 유용한 스크립트 입니다. 그러나 단순 화면 재생도 VLC나 Mplayer가 설치되어 있어야 합니다. 그런데 이 중 하나라도 설치 안되어있는 시스템이 있던가요?


또 다른 것은 xawtv를 쓰는 것인데 아마도 제일 가벼운 영상캡쳐 프로그램이 아닐까 생각합니다. 역시 TV를 위해서 나온 것이지만 인터페이스만 익숙해지면 편리합니다. 모르겠으면 화면에 마우스 오른쪽 버튼을 눌러보세요. 하지만 이 프로그램은 재생과 녹화만 잘 됩니다.


그리고 마지막 녀석은...motion 입니다. 뭐냐고 하시는 분이 계실 것 같은데 motion은 라즈베리파이에서 카메라 스트리밍관련 내용을 보면 여기저기에서 쓰이는 것을 알 수 있습니다. 쉽게 말해 영상에서 움직임을 보기위해 만들어진 프로그램인데 웹으로 스트리밍하는 기능이 내장되어 있어서 이걸 써서 다른 플레이어와 연동되게 할 수 있습니다. 제가 이번에 이용할 것은 라즈베리파이와 연동을 해서 스마트폰에 뿌리기까지 하는 것이므로 이걸 쓸 겁니다.



1. 라즈베리파이에 Raspbian을 설치합니다. 라즈비안 설치는 https://www.raspberrypi.org/downloads/raspbian/ 여기서 다운로드 받아서 사용하시면 됩니다. 자세한 내용은 구글 검색하면 쏟아져 나오니 찾아보시면 됩니다. 이름만 보셔도 아시겠지만 데비안 기반입니다.


간단히 SDCARD에 라즈비안을 설치하는 방법은


SDCARD를 넣고 SDCARD의 주소를 확인한 다음 (Gparted를 쓰면 편합니다.)

sudo dd if="라즈비안이미지" of="SDCARD주소 ex) /dev/sdb" bs=4M


이렇게 하면 SDCARD에 라즈비안이 설치됩니다. 해당 SDCARD를 라즈베리파이에 넣으면 일단 라즈베리파이는 준비됩니다.


2. Raspbian 설치후 motion세팅


 Raspbian도 데비안이니 명령어도 동일합니다. (SSH로 접속하면 더욱 편리합니다. 라즈비안은 기본적으로 SSH접속이 허용되어 있습니다. 로그온 이름은 pi 이고 password는 raspberry입니다. raspi-config에서 꼭 password를 바꾸세요)


sudo apt-get update

sudo apt-get install motion


끝입니다.


그리고 /etc/motion/motion.conf 파일을 수정해야 하는데 수정된 파일을 올려놓겠습니다.

motion.conf

여기서 장치 이름을 /dev/video1로 되어 있는 것을 /dev/video0로 바꿔주셔야 합니다.


3. Easycap 연결

Easycap을 라즈베리파이의 USB포트에 꽂습니다. 즉 라즈베리파이에 영상신호를 넣는 것입니다. 해당 영상은 어떤 것이든 상관 없지만 RCA(AV코드)이므로 여기에 맞게 쓰는 것이 좋습니다. 만약 HDMI를 사용한다면 HDMItoAV같은 장비를 써서 RCA로 넣어야 합니다. 만약 RCA가 너무 구리다고 생각하시면 S-Video를 쓰시면 조금 낫습니다. 화질 문제는 싸구려에게 많은 것을 바라면 안 됩니다. (RCA는 케이블 품질 특성을 많이 탑니다. 그래봐야 HDMI에 비해 현저히 구리지만)


EasyCap같은 캡처보드는 HDMI따위는 지원을 안하기에 이런 장비가 필요하다. 대만에서 만들어진 것으로 추정되는 HDMI to AV 제품 약 2만원 정도



자 이제 motion을 실행해 봅시다.


sudo motion(관리자 권한 필수 싫으면 /dev/video0를 666으로 세팅하면 됩니다.(sudo chmod 666 /dev/video0)


X없이 사용하시는 것이 좋습니다. 라즈베리파이의 IP주소를 알아내고 스마트폰용 웹브라우저에서 다음과 같이 넣어봅시다.

(안드로이드는 모바일 크롬 추천...아이폰은 사파리 추천)


http://라즈베리파이IP주소:8081


이러면 RCA로 입력된 영상이 뜹니다. 여기서 녹화를 하신다거나 추가 작업을 하신다면 라즈베리파이외의 같은 네트워크상에 있는 다른 PC에서 VLC를 쓰시면 편리합니다.


즉 포트만 열어주시면 아프X카 같은 사이트를 이용하지 않고 직접 웹에서 방송하는 것도 가능합니다. 대역폭 문제가 있지만 우리나라 통신망의 대역폭은 무지막지합니다. 별로 문제가 없습니다.


이렇게 VLC로 스트리밍 받거나 (화면은 Xbox One의 화면 HDMI밖에 안 나와서 하는 수 없이 컨버터를 구입했다.)

이렇게 크롬으로 직접 영상을 전송 받을 수도 있다. 만약 웹으로 받으려면 img src="라즈베리주소" 태그면 충분하다



문제는 사운드인데 

cvlc -vvv alsa://plughw:0 --realrtsp-caching 20 --rtsp-caching 20 --sout '#transcode{acodec=s16l,samplerate=44100}:rtp{sdp=rtsp://:8082/,caching=10}'


이렇게 vlc-nox를 설치해서 소리를 전송하려고 하니 (rtsp://라즈베리IP주소:8082/ 를 audio 태그 혹은 VLC에서 재생 및 녹화)Easycap 자체가 워낙 구려서 추천하지 않는다고 합니다. 2300원짜리 USB 사운드 카드도 하나 구비해야 할 듯합니다.


사운드 부분 작업 중.


요놈을 추가로 더 구입했습니다. 7000원 더 들었네요.(2300원짜리는 단종되었다고 합니다...허)



USB 사운드카드 하나를 샀습니다. 어차피 EasyCap은 병맛이라고 하니까요. 우선 라즈베리파이 내장 사운드카드를 죽이도록 하겠습니다.


http://www.instructables.com/id/Disable-the-Built-in-Sound-Card-of-Raspberry-Pi/step3/Test-that-sound-card-is-NOT-detected-by-ALSA-Nativ/

위의 내용에 의하면 

/etc/modprobe.d/alsa-base.conf

여기에

blacklist snd_bcm2835

위의 내용이 들어가면 라즈베리파이 내장 사운드카드를 죽일 수 있게 됩니다.


그다음 aplay -l 명령을 썼을 때 BCM칩이 안 뜨면 죽은 겁니다. 물론 녹음 쪽이 더 중요하니까

arecord -l

위 명령을 써보시는 것이 더 좋습니다.


그 다음 RCA to Stereo 케이블을 사용해서 RCA사운드(빨간색-흰색)단자를 USB사운드카드의 마이크부분에 꽂습니다. 일단 작동은 되는 듯 합니다. 그런데 사운드가 미친듯이 깨집니다.


아마도 PC에서는 문제가 없었던 것을 봐서 라즈베리파이의 성능문제 혹은 설정 문제일 것입니다. http://www.raspyfi.com/raspberry-pi-usb-audio-fix/

여길 보니 설정 문제인듯 합니다.


우선 rpi-update를 설치한다.


sudo apt-get install rpi-update


그 다음


sudo rpi-update


를 실행 업데이트가 완료되면


sudo shutdown -r now


일단 이걸로 대충은 해결이 된다고 하는데 일단 해보고 나머지 포스트.


대충은 VLC에서 소리가 나오기는 하네요. 됩니다.


 그러기 전에 라즈베리파이에 자동 실행이 되도록 약간 손을 좀 봐야 하는데요.

/etc/rc.local 파일을 손을 보겠습니다.


sudo nano /etc/rc.local


위 명령을 사용하면 rc.local 파일을 수정할 수 있게 되는데


exit 0 위에 다음과 같이 적습니다.


sudo motion &


그런데 VLC는 root로는 실행이 되지 않습니다. 그러면 유저모드에서 실행을 하게 하면 됩니다.


sudo raspi-config에서 Boot Options으로 들어간 뒤에 Autologon을 설정합니다.

그리고

sudo nano ~/.profile


여기서 제일 아래에


cvlc -vvv alsa://plughw:0 --realrtsp-caching 10 --rtsp-caching 10 --sout '#transcode{acodec=s16l,samplerate=44100}:rtp{sdp=rtsp://:8082/,caching=10}'  


이걸 넣어주시면 자동으로 실행 됩니다.


이렇게 하면 8081포트로는 화면을 8082 포트로는 wav로 rtsp프로토콜 사운드를 전송하게 됩니다. 그럼 이걸 어떻게 모바일로 확인하는지 알려드리겠습니다.


영상은 이전과 같이 Chrome을 사용하고 사운드는 VLC를 사용하면 됩니다. 이는 PC도 마찬가지입니다. OS를 가리지 않는 두 프로그램을 사용하기 때문에 절대로 OS 호환 문제가 생기지 않습니다. 심지어 이거 iOS도 됩니다. 사파리+VLC를 쓰면 됩니다.



일단 안드로이드에서는 위와 같은 방법을 쓰고 우분투 PC에서는 ffplay를 쓰는것이 가장 나았습니다.


만약 라즈베리파이 IP가 192.168.0.21 이라면

ffplay -f mjpeg -probesize 32 -i http://192.168.0.21:8081 -vf yadif  &
ffplay -i rtsp://192.168.0.21:8082/


위의 내용을 터미널에 넣으면 실행이 완료됩니다. yadif 필터를 먹였으므로 RCA특유의 인터레이스 화면도 필터링됩니다.

,

으음...ghap님께서 동방을 갑자기 들고 오시는 바람에 근 10년만에 생각나서 동방 게임을 잠깐 굴려봤습니다. 간만에 보니 한글 패치도 엄청 굴러나왔더군요.http://blog.naver.com/PostList.nhn?blogId=chlehd0509 한글패치를 약 10년전에 시도했다가 망해서 때려친 기억이 있는데 새롭네요.


일단 본편인 슈팅은 왠만 하면 그냥 Wine1.6 버전으로도 잘 굴러갑니다. 그도 그럴 것이 딱히 복잡한 쉐이더를 쓴 것도 아니고 그냥 D3D 기본API를 이용한 정도라 그렇게 어렵지도 않습니다. D3D to OpenGL의 문제가 그렇게 많이 드러나지 않습니다. AA를 넣어도 될 정도입니다.(AA를 적용해야 할 정도인지는 둘째 칩시다.


보통 이쪽 계열(탄막슈팅) 입문작으로 추천되는 동방영야초. 그나마 쉬운 편이라 초보자(?)에게 추천된다.

물론 10년간 이 게임을 안 한 죄로 죽기 직전..(그래도 Hard다.)

 

본편은 Wine 실행에 어려움이 전혀 없으니 이야기는 이 정도로 하고 본편과 함께 열심히 했던 외전 격투게임인 비상천을 굴려 보기로 했으나...


오늘 리눅스에서 굴려볼 게임은 이거. 그런데 본인은 전작까지만 해보고 이걸 해 본 적이 없다.


비상천칙이 언제 나왔더군요. 일단 해보지 뭐 하면서 한글 패치를 적용했는데...

Wine 1.9.5에서 에러 납니다. 그것도 게임 중에 까만 화면에 진행 불가.


터미널에 뜬 문구는 다음과 같았습니다.

"FXLC is not support"

??? 이게 뭐지? 하면서 검색을 했더니 2016년 3월에 이에 관한 패치가 적용되었습니다. (https://www.winehq.org/pipermail/wine-devel/2016-March/112061.html)


그래서 최신 버전인 1.9.13에서 구동 시도 PlayOnLinux를 쓰면 이런 것은 어렵지도 않지요.

PlayOnLinux에서 Wine 버전관리 기능을 사용하고 Configure에서 버전을 선택하면 얼마든지 버전을 바꿀 수 있다.


흐음..일단 게임을 굴려봤습니다. 그런데...

텍스쳐가 깨지고 화면이 흐려집니다!

아니 다른 건 상관없는데 날씨 관련 효과가 나올 때 마다 화면이 흐리멍텅 해집니다. 날씨가 돌아오면 정상적으로 돌아오기도 하는데 문제의 FXLC가 동작 할 때마다 이 모양이 되는 듯 합니다. FXLC가 그냥 안 되게 막아버려야 하나?


아무래도 1.9버전은 개발 버전이라 문제가 있을 것이라고 판단. 1.8버전으로 회귀하고 아에 의심가는 D3D9_XX.dll로 나오는 라이브러리를 네이티브로 넣었습니다. 


PlayOnLinux에서 제공하는 것은 이거 밖에 없더군요.

d3dx9_29

d3dx9_35

d3dx9_36

d3dx9_40

d3dx9_42

d3dx9_43


PlayOnLinux의 삽질을 줄여주는 고마운 기능. 그런데 winetricks보다도 못 할 때가 많다.


그냥 다 설치했습니다.


그러고 실행하니...


으음...계속 쳐 맞는다. 역시 격투게임은 별로인가 나?


깨끗합니다. 역시 개발 버전에 의한 버그 문제였습니다. 다만 네트워크 플레이가 안 되는 것 같은데 알 게 뭔가요. 어차피 네트워크 하면 이기는게 거의 불가능하니(...)


일단 동방비상천칙도 잘 되네요. 10년전만 하더라도 실행조차 불가능 했던 것으로 기억하는데 Wine의 발전은 정말 눈부십니다.

,