삽질하는플머

Emscripten 가지고 놀기 3. (feat. event.c)

탐구생활/WEB 관련

이전 글 


Emscripten 가지고 놀기 1. (feat. CodeLite)

Emscripten 가지고 놀기 2. (feat. GLFW, ZLib) 




이제 1편에서 만들었던 예제에 2편의 라이브러리들을 링크 해 보자. 

CodeLight 의 Project Settings 창을 열어 다음과 같이 설정해준다. 


타겟 

 Linker Options

 Libraries

 Debug, Release

 -framework OpenGL

 glfw;z

 Web

 -s USE_GLFW=3;-s FULL_ES2=1

 z







main.cpp 는 다음과 같이 만들어준다. 



#include <GLFW/glfw3.h>

#include <zlib.h>


#include <stdio.h>


int main(int argc, char **argv)

{

    printf("ZLib version: %s\n", zlibVersion());

    

    int major, minor, rev;

    glfwGetVersion(&major, &minor, &rev);

    printf("GLFW version: %d.%d.%d\n", major, minor, rev);

    

    return 0; 

}



실행시킨 결과는 다음과 같다. 




타겟을 Web 으로 바꿔서 빌드한 결과







GLFW의 event.c 는 베이스로 삼기에 참 좋은 예제라고 생각한다. 일부를 발췌해서 아래와 같이 만들어 보자. 

event.c 의 내용과 비교해 신경써야 할 부분은 다음 두가지이다. 


1. 윈도 생성시 OpenGL ES 2.0 을 지정. 

2 루프문 처리에 emscripten_set_main_loop() 함수를 사용. 


이렇게 Emscripten에서 다르게 처리해야 하는 부분은 "#ifdef EMSCRIPTEN" 으로 묶여있으니 참고하자. 



main.cpp





Func.cpp





Debug 빌드 테스트




Web 빌드 테스트








Emscripten 에 대해 수박 겉핥기로 간단히 가지고 놀아 보았다. 

생성된 JS 파일을 열어보면 그럭저럭 읽을만 하다. 

여기까지는 로컬파일에서도 테스트가 되지만 "-O2" 이상의 최적화 옵션을 주면 asm.js 로 빌드되고 웹서버가 필요하다. 

(파이썬의 SimpleHTTPServer 추천)

"-s WASM=1" 을 추가해 요즈음 핫한 웹어셈블리도 만들어 볼 수 있으니... 모쪼록 즐거운 삽질이 되시기를...






2019.6.12.


$emcc --show-ports


Available ports:

zlib (USE_ZLIB=1; zlib license)

libpng (USE_LIBPNG=1; zlib license)

SDL2 (USE_SDL=2; zlib license)

SDL2_image (USE_SDL_IMAGE=2; zlib license)

ogg (USE_OGG=1; zlib license)

vorbis (USE_VORBIS=1; zlib license)

bullet (USE_BULLET=1; zlib license)

freetype (USE_FREETYPE=1; freetype license)

......


zlib 같은 유명한 엔진은 이미 emscripten 로 포팅되어 있음.
저 삽질은 기본 지원하지 않는 라이브러리 적용시에나 유효할 듯. 






Emscripten 가지고 놀기 2. (feat. GLFW, ZLib)

탐구생활/WEB 관련

이전 글 Emscripten 가지고 놀기 1. (feat. CodeLite)  에서 연결됨. 


OpenGL은 말 그대로 그래픽 라이브러리에 대한 표준이고 어떤 플랫폼에서건 일관적인 사용을 보장하지만

막상 이 컨텍스트를 띄우려면 윈도에서는 wgl, 모바일에서는 egl 을 써야 하는 등, 플랫폼마다 조금씩 다른 처리가 필요하다. 

GLFW는 이런 잔처리를 도와서 손발을 편안하게 해 주는 물건이다. 


Emscripten 환경에는 이 GLFW3 이 포팅되어있고 "-s USE_GLFW=3" 링크옵션으로 활성화 시킬 수 있다. 

따라서 네이티브 환경에서 GLFW를 사용해 OpenGL 윈도를 생성하고 화면을 그려주면, 큰 변환 없이 웹에서도 동작시킬 수 있게 된다. 

문서상에는 셰이더 없이 glBegin() ~ glEnd() 도 지원한다고 되어있기는 한데... 예전 1.25 버전에서 삽질하다가 진작에 포기했다. 

그냥 속 편하게 OpenGL ES 2.0 기반으로 작업하는 것을 추천한다.  


이번 포스팅에서는 네이티브 환경에 GLFW를, Emscripten 환경에는 zlib 를 추가하는 방법을 정리해 보자. 



작업을 편하게 하기 위해 wget을 설치한다. 먼저 rudix 설치.



 $ curl -O https://raw.githubusercontent.com/rudix-mac/rpm/2016.12.13/rudix.py

 $ sudo python rudix.py install rudix





wrget 설치



 $ sudo rudix install wget








glfw 빌드. 소스 다운받고 빌드 디렉토리 준비. 



 $ wget https://github.com/glfw/glfw/releases/download/3.2.1/glfw-3.2.1.zip --no-check-certificate

 $ unzip glfw-3.2.1.zip

 $ cd glfw-3.2.1

 $ mkdir build

 $ cd build




CMAKE를 실행 후 Conrigure 에서 "Unix Make" 선택하고 붉은 마킹이 사라지도록 설정을 아래와 같이 변경 후 Configure 실행. 

완료 후 Generate 버튼을 눌러준다. 





빌드 시작. 



 $ make




빌드된 라이브러리는 build/src 에, 예제는 build/examples 에 만들어진다. 



 $ ls -l src/lib*

 -rwxr-xr-x  1 oranke  admin  127596  3 25 11:23 src/libglfw.3.2.dylib

 lrwxr-xr-x  1 oranke  admin      17  3 25 11:23 src/libglfw.3.dylib -> libglfw.3.2.dylib

 lrwxr-xr-x  1 oranke  admin      15  3 25 11:23 src/libglfw.dylib -> libglfw.3.dylib





그냥 두고 써도 되겠지만, 개발을 편하게 하기 위해 인스톨. 



 $ sudo make install


........


[100%] Built target events

Install the project...

-- Install configuration: "Release"

-- Up-to-date: /usr/local/include/GLFW

-- Installing: /usr/local/include/GLFW/glfw3.h

-- Installing: /usr/local/include/GLFW/glfw3native.h

-- Installing: /usr/local/lib/cmake/glfw3/glfw3Config.cmake

-- Installing: /usr/local/lib/cmake/glfw3/glfw3ConfigVersion.cmake

-- Installing: /usr/local/lib/cmake/glfw3/glfw3Targets.cmake

-- Installing: /usr/local/lib/cmake/glfw3/glfw3Targets-release.cmake

-- Installing: /usr/local/lib/pkgconfig/glfw3.pc

-- Installing: /usr/local/lib/libglfw.3.2.dylib

-- Installing: /usr/local/lib/libglfw.3.dylib

-- Installing: /usr/local/lib/libglfw.dylib






zlib 빌드



 $ git clone https://github.com/madler/zlib.git

 $ cd zlib

 $ mkdir build
 $ cd build
 $ 
emcmake cmake  ..
 $ make




맥에서 빌드하고 있지만 생성되는 바이너리 파일의 확장자는 *.dylib가 아닌 *.so 이다. 

툴체인을 바꿔주는 역할을 emcmake 커맨드가 처리하는 듯 하다. 



 $ ls -l libz*

 -rw-r--r--  1 oranke  admin  208488  3 25 17:39 libz.a

 lrwxr-xr-x  1 oranke  admin       9  3 25 17:39 libz.so -> libz.so.1

 lrwxr-xr-x  1 oranke  admin      14  3 25 17:39 libz.so.1 -> libz.so.1.2.11

 -rw-r--r--  1 oranke  admin  183196  3 25 17:39 libz.so.1.2.11




이대로 써도 관계 없지만... 아무래도 편한게 좋으니 emscripten 환경에 설치되도록 하자. 



CMake-GUI 를 열어서, 설치위치를 /usr/local 이 아닌 /Volumes/Data/emsdk/emscripten/1.37.36/system/local 로 변경하고 다시 생성. 




 $ make install


......


[100%] Built target minigzip

Install the project...

-- Install configuration: ""

-- Installing: /Volumes/Data/emsdk/emscripten/1.37.36/system/local/lib/libz.so.1.2.11

-- Installing: /Volumes/Data/emsdk/emscripten/1.37.36/system/local/lib/libz.so.1

-- Installing: /Volumes/Data/emsdk/emscripten/1.37.36/system/local/lib/libz.so

-- Installing: /Volumes/Data/emsdk/emscripten/1.37.36/system/local/lib/libz.a

-- Installing: /Volumes/Data/emsdk/emscripten/1.37.36/system/local/include/zconf.h

-- Installing: /Volumes/Data/emsdk/emscripten/1.37.36/system/local/include/zlib.h

-- Installing: /Volumes/Data/emsdk/emscripten/1.37.36/system/local/share/man/man3/zlib.3

-- Installing: /Volumes/Data/emsdk/emscripten/1.37.36/system/local/local/share/pkgconfig/zlib.pc







정리하면...


GLFW 는 이미 Emscripten 환경에 있지만 OSX 에 없으니 OSX 용으로 빌드. 

ZLib 는 OSX 에는 있지만 Emscripten 에는 없으므로 Emscripten 용으로 빌드 


한 삽질이 되시겠다. 



Emscripten 가지고 놀기 1. (feat. CodeLite)

탐구생활/WEB 관련

Emscripten 개발은... 가급적 모든 코딩과 테스트를 네이티브에서 진행한 뒤 빌드만 emcc를 사용하는 것이 편하다. 

때문에 네이티브 환경을 오갈 수 있는 쓸만한 IDE가 간절해진다. (Make 방식은 아무리 들여다봐도 정이 안 감...)


윈도에서 VS와 emscripten 을 버무려둔 환경은 github 에 몇 개 보긴 했는데... 

내가 코드를 이상하게 짜는건지 VS가 이런 저런 허용을 많이 해주는건지... 다른 플랫폼으로 옮길 때 항상 삽질을 많이 하게 된다. 

 

차선책으로 XCode 에 Emscripten 툴체인을 비벼주려 한동안 고민했는데... 지식이 얕다보니 성공하지 못했다. 

다 포기하고 예전에 썼던 Code::Blocks 를 간만에 찾아봤더니 OSX 용은 13.12 버전이 마지막...   

OSX 10.12 에서 돌렸더니 크래시가 나서 사용하기가 쉽지 않다. 무엇보다 모양도 별로고...


툴체인 변경이 쉬운 대안이 어디 없을까 뒤적이다가 CodeLite 가 눈에 띄었다. 

그런데 어? 이거 물건이다! 딱 이럴 때 쓰라고 만들어진 듯 하다!!



그래서 오늘 요리는 Emscripten 과 CodeLite 버무리기. 



Emscripten 을 가지고 놀려면 먼저 CMake 를 깔아줘야 한다. 설치방법을 간단히 정리 해 둔다. 

아래 사이트에서 OSX 배포판을 받아 Application 에 설치하고

http://www.cmake.org/download/


다음과 같이 루트권한으로 실행시킨다. 



 $ sudo /Applications/CMake.app/Contents/MacOS/CMake




GUI에서 Tools -> Install For Command Line Use 선택. 



버전 확인



 $ cmake --version


 cmake version 3.11.0-rc4










CodeLite 와의 연동 설명은 현 시점에서 최신버전인 Emscripten 1.37.36 을 기준으로 한다. 

Emscripten 의 설치방법은 http://kripken.github.io/emscripten-site/docs/getting_started/downloads.html 참고 할 것. 

내 경우 설치 위치는 "/Volumes/Data/emsdk".





CodeLite 12.0.0 설치하고 (https://codelite.org/) "안녕 세상" 예제 준비. 





Setting -> Build Setting 에서 새 툴체인 선택.





적당한 이름을 주고 GCC에서 설정을 복사. 





C++은 "em++", Archive는 "emar", 나머지는 "emcc", 쓰이지 않는 것은 모두 비운다. 






Build -> Configuration Manager 에서 Web 설정을 추가하고 ...


  



이 설정에 맞추어 예제 프로젝트에도 Web 구성을 추가한다. 




이렇게 나오게 만들면 완료. 





이제 워크스페이스의 구성에서 Web을 선택할 수 있다. 





프로젝트 우클릭 후 Settings 선택, Web 구성의 컴파일러 설정을 변경해준다. 

출력파일 확장자에 ".html" 을 덧붙여 주는 것을 빼먹지 말 것. 





WorkSpace 의 구성을 Web으로 변경하고 F7을 눌러 빌드. 





프로젝트 폴더 아래 "Web" 폴더 안에 *.html 파일이 생성된다. 





생성된 html 파일을 열어보면 "Hello World"가 예쁘게 출력되는 것을 볼 수 있다.




사실 얘는 껍데기고, 빌드된 결과물은 *.js 에 들어있다. node 로 돌려보면 다음과 같다. 





IDE가 좋은 것은 여러개의 소스를 한번에 비벼주기 편하다는 것이다. 

소스파일을 하나 더 추가해서 잘 되나 확인해보자. 



main.cpp

#include <stdio.h>


extern void TestFunc(); 


int main(int argc, char **argv)

{

    printf("hello world\n");

    TestFunc(); 

    return 0;




F7로 빌드하고 콘솔에서 찍어보면 잘 동작한다. 





일단 오늘은 여기까지. 

OpenGL 테스트를 위한 GLFW 버무리기는 다음 포스팅에서...



요물덩어리 emscripten. 세번째.

탐구생활/WEB 관련
텍스쳐를 부르기 위해 zlib 링크. 
간단할 줄 알았는데... 문서대로 되는 게 거의 없네... 
결국 해법은 "emcmake cmake"...  

아무튼 이제야 뭔가 동작하는 것 처럼 보인다. 

처음에는 단순히 예전에 써먹던 고정파이프 방식을 처리하는 셰이더면 충분하다 싶었는데
가지고 놀다 보니 이거 참 편하고 좋은 물건이었군... 


화면 클릭, 우클릭은 Y축 회전.
W키는 와이어 프레임.
L키는 조명 테스트. 

(가끔씩 github.io 가 반응이 없네...)


 



2017.3.30. 

컴파일결과를 올려놓았던 구글드라이브 호스팅이 작년 언제쯤부터 정지되어 먹통이었는데... 

차일피일 미루다 github.io 로 이동시킴. 


요물덩어리 emscripten. 두번째.

탐구생활/WEB 관련

VBO, IBO 붙이고 행렬스텍과 초간단 조명 구현. 
모델은 뭘 쓸까 하다가... "개발자에게 배우는 게임 개발 테크닉" 에 들어있던 ASE를 변환해 붙여봄. 

네이티브에서는 대충 굴러가는 코드가 emscripten으로 빌드만 하면 까탈스럽게 에러를 토해내는데
그래도 삽질하면 어찌어찌 돌아가기는 하네. 

황당했던 경험에 순위를 매겨보면... 
1. char 세 개로 패킹한 노멀좌표가 끼어있으면 정점 stride가 먹지 않음. 정점 구조체 크기는 4의 배수여야 함. 

2. std::vector 만 쓰면 쏟아지던 에러. library-glfw.js 내부에 공백대신 낑궈져있던 문자를 지워 해결. 

3. 셰이더에 보낸 정점은 셰이더 내에 어떤 형태로든 써먹어주어야 함. 안그러면  아무것도 표시 안됨. 


이제 텍스쳐만 발라주면 그럴듯하겠다. 




화면 클릭, 우클릭은 Y축 회전.
W키는 와이어 프레임.
L키는 조명 테스트.