OpenGL ES 버전 2.0과 3.0 차이

OpenGL ES(Embeded System)

Cocos2d-x 버전 차이에 대해서 공부하던 중에 그 기반이 되는 OpenGL ES의 버전에도
큰 차이가 있지 않을까하여 공부해봤습니다.

우선 OpenGL ES란, (Wikipedia-ko)

OpenGL ES (임베디드 단말을 위한 OpenGL)는 크로노스 그룹이 정의한 3차원 컴퓨터 그래픽스 API인 OpenGL의 서브셋으로, 휴대전화, PDA 등과 같은 임베디드 단말을 위한 API이다.

한글로 작성된 위키는 짧군요. 영어로 작성된 위키를 더 보겠습니다. (Wikipedia-en)

OpenGL for Embedded Systems (OpenGL ES or GLES) is a subset of the OpenGL computer graphics rendering application programming interface (API) for rendering 2D and 3D computer graphics such as those used by video games, typically hardware-accelerated using a graphics processing unit (GPU). It is designed for embedded systems like smartphones, computer tablets, video game consoles and PDAs. OpenGL ES is the “most widely deployed 3D graphics API in history”. The API is cross-language and multi-platform. The libraries GLUT and GLU are not available for OpenGL ES. OpenGL ES is managed by the non-profit technology consortium Khronos Group. Vulkan, a next-generation API from Khronos, is made for simpler high performance drivers for mobile and desktop devices.

설명에 큰 차이는 없지만, API에 대한 설명에는 크로스 랭귀지, 멀티 플랫폼이 포함되어 있네요.
OpenGL에서 사용할 수 있는 GLUT, GLU는 OpenGL ES에서는 사용할 수 없다는 것 정도를 추가로 알 수 있었습니다.

각 버전별 설명도 잘 나와있는 영문 위키를 보면,

OpenGL ES 2.0 - (EN)

OpenGL ES 2.0 was publicly released in March 2007.[6] It is based roughly on OpenGL 2.0, but it eliminates most of the fixed-function rendering pipeline in favor of a programmable one in a move similar to transition from OpenGL 3.0 to 3.1.[7] Control flow in shaders is generally limited to forward branching and to loops where the maximum number of iterations can easily be determined at compile time.[8] Almost all rendering features of the transform and lighting stage, such as the specification of materials and light parameters formerly specified by the fixed-function API, are replaced by shaders written by the graphics programmer. As a result, OpenGL ES 2.0 is not backward compatible with OpenGL ES 1.1. Some incompatibilities between the desktop version of OpenGL and OpenGL ES 2.0 persisted until OpenGL 4.1, which added the GL_ARB_ES2_compatibility extension.[9]

OpenGL ES 3.0 - (EN)

The OpenGL ES 3.0 specification[10] was publicly released in August 2012.[11] OpenGL ES 3.0 is backwards compatible with OpenGL ES 2.0, enabling applications to incrementally add new visual features to applications. OpenGL 4.3 provides full compatibility with OpenGL ES 3.0. Version 3.0 is also base of WebGL 2.0.[12]

New functionality in the OpenGL ES 3.0 specification includes:

(참고, http://www.informit.com/articles/article.aspx?p=2181697&seqNum=2)

음, 내용이 많아 번역한 내용으로 각각 살펴보고 정리해보겠습니다.

OpenGL ES 2.0

OpenGL ES 2.0는 2007년 3월에 출시되었습니다. OpenGL 2.0을 기반으로 하지만 OpenGL 3.0에서 3.1로 업데이트 될 때와 비슷하게 고정 렌더링 파이프라인을 제거하였습니다. 셰이더의 제어 흐름은 컴파일할 때에 쉽게 결정할 수 있는 순방향 분기, 루프로 제한됩니다.

이전에 고정 함수 API에 의해 지정된 재질 및 조명 매개 변수와 같은 변형 및 조명 스테이지의 거의 모든 렌더링 기능은 그래픽 프로그래머가 작성한 쉐이더로 대체되었습니다. 따라서 OpenGL ES 2.0은 OpenGL ES 1.1과 호환되지 않습니다. OpenGL과 OpenGL ES 2.0 데스크톱 버전 간의 일부 비 호환성은 GL_ARB_ES2_compatibility 확장을 추가한 OpenGL 4.1까지 지속됩니다.

OpenGL ES 3.0

OpenGL ES 3.0 사양은 2012년 8월에 공개되었습니다.
OpenGL ES 3.0은 OpenGL ES 2.0과 하위 호환되므로 응용 프로그램이 응용 프로그램에 점진적으로 새로운 시각적 기능을 추가할 수 있습니다.

OpenGL 4.3은 OpenGL ES 3.0과 완벽한 호환성을 제공합니다.
OpenGL ES 3.0은 WebGL 2.0의 기반이기도합니다.

새로운 기능은 아래와 같습니다.

  • 오클루전 쿼리, 변환 피드백, 인스턴스 렌더링 및 4개 이상의 렌더링 대상에 대한 지원을 비롯하여 고급 시각 효과를 가속화할 수 있도록 렌더링 파이프 라인에 대한 여러 가지 향상된 기능을 제공합니다.
  • 고품질 ETC2/EAC 텍스처 압축을 표준 기능으로 지원하여 각 플랫폼에 다른 텍스처 세트가 필요하지 않습니다.
  • 부동 소수점 텍스처, 3D 텍스처, 깊이 텍스처, 정점 텍스처, NPOT 텍스처, R/RG 텍스처, 불변 텍스처, 2D 배열 텍스처, 스위즐, LOD 및 밉(Mip) 레벨 클램프, 매끄러운 큐브 맵 및 샘플러 객체에 대한 보장된 지원을 포함하여 크게 향상된 텍스처링 기능을 포함합니다.
  • 명시적으로 크기가 필요한 텍스처 및 렌더링 버퍼 형식의 광범위한 세트로, 구현 변동성을 줄이고 모바일 앱을 훨씬 쉽게 개발할 수 있습니다.

구글 번역기의 도움을 받아 해석해보았습니다.
내용 상으로는 전반적으로 기능 추가, 성능 향상이 있어보입니다.
(버전이 올라가면 늘 있는 성능 향상인 것 같지만요)
2.0과 하위 호환이 된다는 것이 큰 것으로 보이며 더 깊게 봐야겠지만 렌더링 대상 지원 추가, 렌더링 파이프 라인 기능 향상 등이 눈에 띄네요.
텍스쳐링 기능도 지원 범위가 넓어진 것도 큰 것 같습니다.

성능 테스트 자료가 있으면 좋겠는데.. 없네요.
주로 OpenGL ES와 Vulkan 성능 분석이 많아서 OpenGL ES 2.0과 3.0은 성능 자료는 찾기 힘드네요.
성능 분석에 큰 의미가 없어서 그런 것일 수도 있겠습니다.
(기기에 따라 성능 차이가 많이 나서)

OpenGL ES 버전 차이가 어떤가에 대해 개괄적인 내용을 살펴보았습니다.
렌더링 방식, 텍스처 처리방식, 버퍼 크기등에 대한 차이가 있었네요.

그래픽 엔지니어는 아니어서 자세한 내용은 더 정리하기 힘들지만
다른 좋은 레퍼런스가 있다면 추가해서 들고 오겠습니다.

GitLab CI 해보기 - Cordova

이 글은 2018년 1월 기준으로 작성된 글입니다. 현재 Gitlab 설정, Cordova 환경과는 다를 수 있습니다.

GitLab CI

소개: https://about.gitlab.com/product/continuous-integration/
GitLab에서 CI를 지원한다는 것을 듣고 당시 진행하던 프로젝트를 설정해보고자 했습니다.
CI는 Continuous Integration의 약자로 지속적인 통합으로 부릅니다.

CI는 “지속적으로 퀄리티 컨트롤을 적용하는 프로세스를 실행하는 것이다. (Wiki)으로 설명할 수 있고 이 글에서는 CI에서 자세히 다룰 예정은 아니기에 다른 좋은 문서를 참고해주세요. :)

GitLab 소개문서에는 CD(Continuous Delivery OR Continuous Deployment-지속적인 배포)도
다루고 있으니 참고하시면 좋을 것 같습니다.

저는 CI까지만 설정해보겠습니다. (나중에 CD까지 해볼 수 있겠죠.)

CI 설정 시나리오

  1. 빌드 환경 설정
  2. .gitlab-ci.yml 설정
  3. GitLab Repo에 push!
  4. 빌드!

빌드 환경 설정

여기서 어려울 것으로 예상한 것은 빌드 환경을 설정하는 것이라고 생각했습니다.
freecodecamp 미디엄 글에서는 도커 이미지를 사용하여 어렵지 않게 풀어낸 것 같습니다.

빌드 환경 설정에 필요한 Cordova 환경설정이 무엇인지 살펴보았습니다.
Cordova 7.x 기준의 안드로이드 빌드 환경은 아래와 같습니다. (참고)

  • JDK 8 이상
  • Android SDK, Android SDK Packages
  • Node.js 8.9.4 (NPM)
  • Cordova 7.x
  • (옵션) 환경 변수 설정

iOS 빌드 환경은 macOS 이미지가 없어서 설정해보지 못했습니다. ;(
안드로이드 설정만 해봐야겠네요.

앞서 freecodecamp 미디엄 글에서는 docker 이미지를 사용해서 CI를 설정을 했습니다.
Cordova 관련한 docker 이미지가 있는지 확인해보았고 적당한 것을 찾았습니다.
https://hub.docker.com/r/beevelop/cordova/

이 이미지를 사용하여 만들어본 저장소는 아래와 같습니다. (저장소는 기본적인 프로젝트 생성한 상태입니다.)
https://gitlab.com/pineoc/cordova-ci-demo

.gitlab-ci.yml 설정

1
2
3
4
5
6
7
8
9
10
11
12
image: beevelop/cordova:v7.1.0

before_script:
- cordova platform add android

stages:
- build

build:
stage: build
script:
- cordova build android

GitLab Repo에 Push

위에서 설정한 .gitlab-ci.yml 파일을 프로젝트 최상단 경로에 두면 GitLab에서 파일을 인식하여
설정한 내용대로 빌드를 진행합니다. 진행된 내역은 아래 링크에서 확인할 수 있습니다.
https://gitlab.com/pineoc/cordova-ci-demo/pipelines

이제 커밋할 때마다 빌드가 돌아가고 빌드의 실패/성공을 확인할 수 있습니다.
커밋에 [ci skip] 이라고 명시하면 빌드는 스킵됩니다.

(중간에 빌드 환경이 달라져서 실패한 내용이 생겼네요.)

기본 프로젝트는 어렵지 않게 설정해보았지만
추가적인 플러그인 추가나 설정이 들어가면 어려워질 수 있을 것 같습니다.
iOS 빌드 시스템을 사용하려면 다른 것도 필요하겠구요.

기본적인 설정이라도 도움이 되었으면 좋겠습니다. :)

참고 문서

fisheye webhook error (with node.js)

Fisheye Webhook 에러 수정

SVN, Git과 같은 버전관리 프로그램에 기록되는 커밋(리비전) 내역을 트래킹해주는
Fisheye를 회사에서 사용 중에 Webhook 기능이 있어 사용하다 에러를 만나게 되어 해결 방법을 남겨봅니다.
저는 Node.js + Express로 웹훅을 받아 처리할 때 문제가 있었습니다.

Fisheye에 대한 자세한 내용은 추후 다른 포스트에서 남겨보겠습니다. :)

Webhook 기본 설정

Fisheye에서 웹훅을 설정하는 방법은 간단합니다.
아래 링크를 참고하여 웹훅을 설정합니다.
https://confluence.atlassian.com/fisheye/configuring-web-hooks-960155631.html

Webhook을 받기 위한 Node.js + Express 서버 구성

간단한 서버 어플리케이션을 만들어서 웹훅을 받아봅니다.
POST 요청을 받을 수 있도록 만들고 Test 기능으로 웹훅을 보내 보았습니다.

그랬더니 아래와 같은 에러가 생겼습니다.

1
2
3
4
5
6
7
8
9
10
11
12
POST /test/webhook 415 4.796 ms - 1426
UnsupportedMediaTypeError: unsupported content encoding "utf-8"
at contentstream (C:\Users\pineoc\Desktop\private\pino-bot\node_modules\body-parser\lib\read.js:174:13)
at read (C:\Users\pineoc\Desktop\private\pino-bot\node_modules\body-parser\lib\read.js:54:14)
at jsonParser (C:\Users\pineoc\Desktop\private\pino-bot\node_modules\body-parser\lib\types\json.js:134:5)
at Layer.handle [as handle_request] (C:\Users\pineoc\Desktop\private\pino-bot\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\pineoc\Desktop\private\pino-bot\node_modules\express\lib\router\index.js:317:13)
at C:\Users\pineoc\Desktop\private\pino-bot\node_modules\express\lib\router\index.js:284:7
at Function.process_params (C:\Users\pineoc\Desktop\private\pino-bot\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\pineoc\Desktop\private\pino-bot\node_modules\express\lib\router\index.js:275:10)
at logger (C:\Users\pineoc\Desktop\private\pino-bot\node_modules\morgan\index.js:144:5)
at Layer.handle [as handle_request] (C:\Users\pineoc\Desktop\private\pino-bot\node_modules\express\lib\router\layer.js:95:5)

이런 에러는 또 처음이라 좀 더 확인해보았습니다.
(제 코드 상에 문제라기 보다 웹훅에서 보내주는 데이터 쪽과 맞춰야하는 문제로 보였기 때문입니다.)

UnsupportedMediaTypeError 에러 확인 및 해결 시도

에러 내용은 저에게는 생소해서 구글에서 관련 에러를 검색해보았습니다.
UnsupportedMediaTypeError: unsupported content encoding "utf-8"를 검색해보니
아래와 같은 글들이 나왔습니다.

몇 가지 글을 보았을 때는 Body-parser 쪽에 문제가 있어서 안되는 것으로 예상하여 아래와 같이 해결해보려 했습니다만,
첫 번째 글을 보면 Request Header 값 중 "Content-Encoding: UTF-8"를 빼면 해결되지 않을까? 하는 질문이 있습니다.

바로 아래에는 헤더 값을 제거하는 코드가 답변으로 달렸죠.

1
2
3
4
5
6
7
8
9
//...
app.use(function (req, res, next) {
// remove invalid header
delete req.headers['content-encoding'];
next();
});
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
// ...

이렇게 app.js 코드를 수정하고 웹훅 데이터를 받아보았더니 해결되었습니다.

Content-Encoding: UTF-8?

Content-Encoding: UTF-8 는 뭐길래 에러가 났을까 확인해보았습니다.
우선 Content-Encoding이라는 헤더는 미디어 타입을 압축하기 위해 사용되는 값입니다.
참고: https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/Content-Encoding

Content-Encoding은 주로 아래와 같이 사용되죠.

1
2
3
4
5
Content-Encoding: gzip
Content-Encoding: compress
Content-Encoding: deflate
Content-Encoding: identity
Content-Encoding: br

위 사용 방법에 따르면 UTF-8 값은 유효하지 않은 값입니다. (Invalid)
UTF-8 인코딩 혹은 문자 인코딩을 요청에 표현하고 싶다면 아래와 같이 표현해야합니다.
참고: https://www.w3.org/International/questions/qa-headers-charset.ko

1
Content-Type: text/html; charset=utf-8

문제 해결

해결 방법은 그렇게 어렵지 않았지만 해결하면서 다양한 내용을 알게되어서 좋았습니다.
+문제 없이 웹훅도 사용할 수 있게되어서 더 좋았죠. :)

  • Request Header 유효성 문제
  • Content-Encoding 헤더 값 사용 방법
  • Content-Type 헤더 값 사용 방법

다른 웹훅을 등록하거나, 웹훅 시스템을 만들 때 고려해야하는 내용이었습니다.