2014년 8월 19일 화요일

WebGL changing render mode

Rendering mode

Your browser does not support the HTML5 canvas element.

click

1. TRIANGLES
2. LINES
3. POINTS
4. LINE_LOOP
5. LINE_STRIP
6. TRIANGLE_STRIP
7. TRIANGLE_FAN

2014년 8월 16일 토요일

WebGL Drawing Triangle

Rendering a Triangle

Your browser does not support the HTML5 canvas element.

2014년 8월 15일 금요일

WebGL Drawing Square

Rendering a Square

Your browser does not support the HTML5 canvas element.

WebGL clearColor

WebGL clearColor The HTML5 canvas not working.

click

2012년 3월 14일 수요일

[ Android ] 예제 소스로 보는 OpenGL ES 2.0의 기본 이해

예제 소스
GLES20Activity.java
GLES20TriangleRenderer.java


GLES20Activity.java

ES 2.0 을 사용하기 위해서 다음과 같이 버전 설정을 해야하고, 사용할 renderer 을 설정 해야 한다.

mGLSurfaceView.setEGLContextClientVersion(2) ;
mGLSurfaceView.setRenderer(new GLES20TriangleRenderer(this));

여기 소스에는 나오지 않지만 다음과 같이 render mode 를 설정할 수 있다.

mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINOUSLY);
또는
mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

초기 설정 값은 RENDERMODE_CONTINOUSLY 라서 소스의 render mode 는 이것이다. 이 모드는 매번 반복해서 그려주는 것으로 모션이 들어갈때에는 이 걸로 설정되어 있어야 한다. RENDERMODE_WHEN_DIRTY 는 surface 가 만들어질 때, requestRender() 메서드가 호출될 때만 그려지는 모드 이다. 자세한 내용은 GLSurfaceView.setRenderMode() 를 참고하기 바란다.


GLES20TriangleRenderer.java

OpenGL ES 2.0(이하 ES 2.0) 이 하는 일을 아주 간단하게 말하면,

        점 찍고 그 점을 기준으로 색을 채운다?

라고 아주 어설프게 생각하고 있다. 

소스를 보면 mProgram 이라는 변수가 나온다. 이 녀석은 ES 2.0 의 program 을 java 에서 다룰 수 있게 변환된 변수 이다. ES 2.0 에서 사용되는 주요 요소들은 int 형으로 변환되어 java 에서 사용된다(소스에서 나오는 mTextureID, muMVPMatrixHandle, maPositionHandle, maTextureHandle). 점 찍고 그 점을 기준으로 색을 채우기 까지를 하나로 볼 수 있는데, 이 역할을 하는 것이 program 이라고 볼 수 있다. 점을 어떤식으로 찍고, 그에 따라 어떤식으로 색을 채우는 방법에 따라, 여러 program 들이 만들어 진다. ES 2.0 을 통한 구현은 필요한 program 을 만들어서, 이를 활용하는 것이라고 보면 될 것 같다. 소스를 보면 3개의 점을 찍고 로봇이미지(이미지는 색에 대한 정보라서 간단하게 색으로 생각함)를 채워 삼각형을 그리는 mProgram 을 만들고, 이것을 활용해서 3개의 점을 위치를 변화시켜서 삼각형이 돌고 있는 것을 구현하였다. 참고로 여기에 사각형을 그리는 program, 원을 그리는 program, 기타 등의 program 들을 추가해서 같이 사용할 수 있다.

program 은 shader 라는 것을 다룬다. 그것도 2 가지, vertex shader 와 fragment shader 이다. vertex shader 는 점, fragment shader 는 색을 다룬다고 보면 되겠다. 정확히 따지면 점과 색으로 단정짓기에는 무리가 따를 수도 있다. 개인적인 어설픈 생각과 짧은 경험으로 이렇게 표현하는 것이 이해하기 쉬울것 같아서 그런것이니, 이 부분에 대해 인지하고 있기를 바란다.

shader 는 GPU 에 바로 접근한다고 볼 수 있다. 소스에서 mVertexShader 와 mFragmentShader 를 보면 String 으로 shader 언어가 작성되어 있다. 실제로 이 언어가 GPU 에서 작동한다고 볼 수 있다. java 프로그램에서 보면 직접 코딩한 java 파일은 Java VM 에서 실행 시키기 위해서 class 파일로 컴파일되어야 한다. 이 처럼 String 으로 되어 있는 shader 언어(mVertexShader, mFragmentShader)도 실제로 사용되기위해  컴파일 과정을 거쳐야한다.

소스에서 loadShader(int shaderType, String source) 메서드를 보자. 이 메서드를 보면 어떻게 컴파일하는지 알 수 있다. VertexShader 와 FragmentShader 둘 다 똑같은 과정을 거치기 때문에 메서드로 만든 것 같다. 앞에서 이야기했듯이 java 에서 사용되기 위해 int 형으로 반환 되고 있다. shader 는 program 을 통해서 다루어지기 때문에, 컴파일된 shader 를 사용할 program 에 연결 시켜야 한다. createProgram(String vertexSource, String fragmentSource) 를 보면 어떻게 되는지 알 수 있다. program 은 한번만 만들고 화면에 그릴때 계속해서 사용한다. 그래서 onSurfaceCreated(GL10 glUnused, EGLConfig config) 에서 mProgram 이 실제로 만들어 지는걸 볼 수 있다.

onDrawFrame(GL10 glUnused) 메서드를 보자. 이 메서드는 GLThread 에 의해서 매번 실행되는 메서드이다(render mode 가 RENDERMODE_WHEN_DIRTY 일땐 예외). 성능에 따라 다르지만 초당 60 번 정도(?) 실행 된다. 메서드 안의 코드에서  GLES20.glUseProgram(mProgram); ~ GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3); 를 program 을 사용해서 화면에 그려주기 위한 묶음으로 보면 된다. 위에서 여러가지 program 들(사각형, 원 등을 그리는 program)을 사용할 수 있다고 했다. 여기서 주의할 점이 있다. 묶음 중간에 program 이 바뀌면, 마지막에 적용된 program 이 그려진다. shader 언어에 사용되는 변수들이 같으면 에러가 발생하지 않는데, 다를 경우 에러가 발생한다. 에러가 발생하지 않더라도, 원하지 않던 모습이 그려지는 것을 볼 수 있을 것이다. 여러 program 들을 사용할 때 하나의 그리기 묶음이 끝나면 다음 그리기 묶음이 시작하도록 주의해서 구현하도록 해야 한다.

묶음 중간의 코드들은  점과 색에 대한 정보를 program 에 넣어주는 거라고 간단하게 생각할 수 있다. 일종의 메서드와 비슷하다고 볼 수 있다. 메서드에 매개변수를 넣어 주면 매개변수에 따라 메서드가 실행된다. 이와 마찬가지로 program 에 점과 색에 대한 정보를 넣어 주면 그에 따라 화면이 그려진다고 보면 된다.

mVertexShader 와 mFragmentShader 가 선언된 부분을 보자. shader 언어를 보면 uniform, attribute, varying 을 볼 수 있다. 간단하게 보면 uniform 과 attribute 는 java 코드와 shader 의 연결이고, varying 은 vertex shader 와 fragment shader 의 연결이다. 세세하게 따지면 이는 잘못된 설명일 수 있다. 자세한 내용은 ES 2.0 Reference card 에서 Shading Language 1.0 의 Qualifiers 부분과 ES 2.0 Pipeline 을 참조하기 바란다.

mVertexShader 의 shader 언어에서 gl_Position = uMVPMatrix * aPosition; 을 보자. 직관적으로 uMVPMatrix 는 matrix 이고, aPosition 은 점이라고 느낄 수 있다(아닌가? 나만 그런가? 뭐... 그렇다고 보고). 수학에서 matrix 곱하기 점은 matrix 에 따른 점의 이동이다. 결국 이 식의 결과 값은 점인 셈이다. gl_Position 에 점이 대입되는데, vertex shader 는 gl_Position 의 정보에 따라 점을 찍어 준다고 보면 될 듯 하다. (ES 2.0 Reference card 에서 Shading Language 1.0 의 Built-In Inputs, Outputs, and Constants 부분을 참조하기 바란다.)

aPosition 이 선언 되는 부분 앞에 attribute 를 볼 수 있다. java 코드에서 관련된 값을 전달 받는다는 걸 예상할 수 있다. mTriangleVerticesData, mTriangleVertices, maPositionHandle 이 변수들이 전달에 사용되는 변수들이다. 실제 삼각형의 좌표 데이터는 mTriangleVerticesData 이다. float[] 배열로 되어있는데, 이 값들을 ES 2.0 으로 전달하기 위해선 FloatBuffer 에 넣고 aPosition 과 연결 시켜야 한다. 생성자 GLES20TriangleRenderer(Context context) 안을 보면 어떻게 FloatBuffer 에 데이터들을 넣는지 알 수 있다. 다음을 보자.

onSurfaceCreated() 안의
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
onDrawFrame() 안의 mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false,
            TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
GLES20.glEnableVertexAttribArray(maPositionHandle);

실제로 aPosition 에 데이터를 전달하기 위한 방법이다. 여기서 TRIANGLE_VERTICES_DATA_POS_OFFSET(0), 3, TRIANGLE_VERTICES_DATA_STRIDE_BYTES(5 * FLOAT_SIZE_BYTES(4)) 의 의미를 이해 해야한다. mTriangleVerticesData 를 보자.

private final float[] mTriangleVerticesData = {
            // X, Y, Z,                       U, V
            -1.0f, -0.5f, 0,              -0.5f, 0.0f,
            1.0f, -0.5f, 0,                1.5f, -0.0f,
            0.0f, 1.11803399f, 0,       0.5f, 1.61803399f
}



주석을 보고 잘 파악하면, (-1.0f, -0.5f, 0), (1.0f, -0.5f, 0), (0.0f, 1.11803399f, 0) 이 세 점들이 삼각형의 좌표가 된다는걸 알 수 있을 것이다(u, v 는 아래에서 texture 다룰때). 소스에서 알기 쉽게 쓰여져 있지만, 실제로는 {-1.0f,-0.5f,0,-0.5f,0.0f,1.0f,-0.5f,0,1.5f,-0.0f,0.0f,1.11803399f,0,0.5f,1.61803399f} 이렇게 순서대로 있는 것이고, mTriangleVertices(FloatBuffer) 에도 이렇게 들어 간다. TRIANGLE_VERTICES_DATA_STRIDE_BYTES 의 값을 보면 5 x 4 가 된다. 여기서 4 는 float 형이 4 byte 를 차지하는것을 의미한다. 위에서 TRIANGLE_VERTICES_DATA_POS_OFFSET, TRIANGLE_VERTICES_DATA_STRIDE_BYTES 의 실제 값을 넣어서 보면 다음과 같다.

mTriangleVertices.position(0);
GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false,
            5 * 4, mTriangleVertices);

여기서 눈여겨 봐야할 숫자들은 0, 3, 5 이다. 먼저 0, 5 부터 보면 제일 처음에 mTriangleVertices 안의 위치를 0에 위치 시킨다. ES 2.0 에 mTriangleVertices 의 값들을 넘겨 줄때 처음 위치 0 부터해서, 다음은 5, 그 다음은 10, 이렇게 간격이 5 가 된다. 그리고 각 간격의 처음 위치에서 3 개가 maPositionHandle 에 적용된다. 적용되는 값들을 보면 삼각형의 세 점이란 것을 알 수 있을 것이다. 뭐 대충 이런식으로 된다. ES 2.0 Reference 에서 glVertexAttribPointer 부분을 참고하기 바란다.

mVertexShader 가 선언된 곳의 shader 언어 안에서 aPosition 이 선언 되는 부분을 보자.

attribute vec4 aPosition;

여기서 vec4 에서 의문점이 생긴다. shader 언어를 접하다 보면 vec4(1.0, 1.0, 1.0, 1.0) 이런 것을 볼 수 있을 것이다. 즉 vec4 는 실제로 4개의 값을 가진다. 그런데 위에서 삼각형의 점 x, y, z 값만 전달한다. 나머지 하나가 부족한데, 이 값은 w 에 해당한다. ES 2.0 Reference card 에서 Shading Language 1.0 의 Operators and Expressions 안의 Vector Components [5.5] 부분을 보면 {x, y, z, w} 를 볼 수 있다. w 에 대해서는 Homogeneous coordinates 를 참조하기 바란다.

mVertexShader 가 선언된 곳의 shader 언어 안에 uMVPMatrix 가 보일 것이다. aPosition 즉 mTriangleVerticesData 는 고정되어 있다. 그런데 예제 소스는 삼각형을 회전 시키고 있다. 삼각형의 세 점들이 매번 위치를 옮기고 있는 것이다. 이걸 가능하게 하는 것이 uMVPMatrix 이다. 그리고 폰 마다 해상도가 달라서 실제로 화면에 보이는 삼각형의 모양이 다를 수가 있다. 삼각형의 모양이 어느 폰에서나 같게 유지하기 위해서 필요한 것도 uMVPMatrix 이다. matrix 가 선언된 부분을 보자. mMVPMatrix, mProjMatrix, mMMatrix, mVMatrix 이상한 matrix 들이 4개나 나온다. 이 matrix 들은 OpenGL 의 3D 좌표 개념을 나타낸다. uMVPMatrix 의 실제 값은 mMVPMatrix 라고 보면 된다. int 형 변수 중에 muMVPMatrixHandle 을 통해서 값이 전달된다. 다음을 보자.

onSurfaceCreated() 에서
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
onDrawFrame() 에서
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);

uMVPMatrix 에 mMVPMatrix 를 전달하는 방법이다.

mMMatrix 는  Model Matrix 로 객체(여기서는 삼각형)의 좌표를 실제 공간의 좌표로 변환시키는 matrix 이다. mVMatrix 는  View Matrix 로 카메라의 좌표로 변환시키는 matrix 이다. 일반적으로 3D 관련해서 우리가 보는 3D화면은 카메라로 본다는 개념을 사용한다. 그냥 우리의 눈의 위치라고 생각해도 될것 같다. mProjMatrix 는 Projection Matrix 로 위에서 w 와 관련된 Homogeneous coordinates 로 변환시키는 matrix 이다. 실제로 우리가 보는 화면이라고 보면 될 것이다. 다음을 보자.

onSurfaceCreated() 에서
Matrix.setLookAtM(mVMatrix, 0, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

mVMatrix 가 어떻게 만들어 지는가 알 수 있다(Matrix.setLookAtM() 참조).

onSurfaceChanged() 를 보자.

GLES20.glViewport(0, 0, width, height);
float ratio = (float) width / height;
Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);

mProjMatrix 가 어떻게 만들어 지는가 알 수 있다(Matrix.frustumM() 참조). 여기서 매개변수로 들어오는 width 와 height 는 폰의 디스플레이 영역이다. GLES20.glViewport() (ES 2.0 Reference 의 glViewport 참조)는 viewport 를 설정하는 것이다. viewport 는 실제로 보이는 영역, 실제로 그려지는 영역이라고 보면 되겠다. viewport 영역을 벗어나면 실제로 그려지지 않는다. 그리고 3D 좌표에 따라 좌표 범위가 달라지는데, 이와 관련된게 frustum 이다. 실제로 그려지는 3D 좌표 범위를 나타내는 피라미드 절단체 모양인데... Viewing frustum , OpenGL Transformation 에서 Projection Matrix (GL_PROJECTION) , OpenGL Projection Matrix 에서 Perspective Projection, GL Programming Chapter03 의 Projection Transformations 를 참고하기 바란다. ratio 가 적용되는 부분을 잘 보기 바란다. -ratio, ratio 그 뒤에 -1, 1 이들은 각각 frustum 의 left, right, bottom, top 에 해당한다. 디스플레이 영역의 높이를 1 로 두고 그에 따른 너비 비율을 적용했다는 것을 잘 인지하기 바란다.


onDrawFrame() 안에 있는 다음 코드들을 보자.

long time = SystemClock.uptimeMillis() % 4000L;
float angle = 0.090f * ((int)time);
Matrix.setRotateM(mMMatrix, 0, angle, 0, 0, 1.0f);
Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);

Matrix.setRotateM() 메서드와 Matrix.multiplyMM() 메서드가 뭔지 알면 mMVPMatrix 가 어떻게 구해지는 알 수 있다. 삼각형을 회전시키려고 하니깐, mMMatrix(Model Matrix) 에 angle 값에 따른 회전을 적용 시켰다. 해당 matrix 의 좌표적용은 matrix 의 곱으로 보면 될 것이다. matrix 의 특성 상 곱하는 순서에 따라 값이 달라지기 때문에 순서를 주의해야 할 것이다. 코드를 식으로 보면 mMVPMatrix = mProjMatrix * mVMatrix * mMMatrix 일 것이다. Tutorial 3 : Matrices 의 The Model, View and Projection matrices 를 참고하기 바란다.



texture 쓰는중...





참조 링크

Tutorials OpenGL ES 2.0

Learn OpenGL ES

Songho OpenGL

OpenGL tutorial

김형준 GIS 연구소


ttttttt

2011년 5월 4일 수요일

[ Android ] What is Android?

 안드로이드는 operating system, middleware 그리고 key application들을 포함하는 모바일 장치들을 위한 소프트웨어 stack 이다. 안드로이드 SDK는 Java programming 언어를 사용하는 Android platform의 application들을 개발하기 시작하는데 필수적인 tool들과 API들을 제공한다.

___________________________________________________

특징들

 * Application framework  컴포넌트들의 재사용과 교체가 가능하다.

 * Dalvik virtual machine  모바일 장치들을 위해 최적화 되어졌다.

 * Integrated browser  오픈소스 WebKit engine 에 기반을 두고 있다.

 * Optimized graphics  custom 2D graphics library; OpenGL ES 1.0 특징
                                        (선택적인 하드웨어 가속) 에 기반을 둔 3D
                                        graphics 에 의해 작동한다.

* SQLite  구조적인 데이터 저장을 돕는다.

* Media support   공통의 audio, video, 그리고 still image format (MPEG4,
                               H.264, MP3, AAC, AMR, JPG, PNG, GIF)들을 지원한다.

* GSM Telephony  (기기에 따라 다르다.)

* Bluetooth, EDGE, 3G, and WiFi  (기기에 따라 다르다.)

* Camera, GPS, compass, and accelerometer  (기기에 따라 다르다.)

* Rich development environment   device emulator, 디버깅을 위한
                                                             tools, memory와 performance
                                                             profiling, Eclipse IDE를 위한
                                                             plugin 을 포함한다.




___________________________________________________

안드로이드 아키텍처

다음의 다이어그램은 안드로이드 operating system의 주요 component들을 보여준다. 구획의 자세한 설명은 아래에 있다.














___________________________________________________

Application들
안드로이드는 email client, SMS program, 달력, maps, browser, 연락처, 그외 다른것들을 포함하는 core application들을 제공할 것이다. 모든 application들은 Java programming 언어를 사용하면서 쓰여졌다.



___________________________________________________

Application Framework
안드로이드는 open development platform을 지원하면서 개발자들에게 풍부하고 획기적인 application들을 개발할 수 있는 능력을 제공한다. 개발자들은 모바일 기기, 위치정보에 접근, background service들의 구동, alarm들을 설정, notification들을 status bar에 추가 등등의 이점들을 자유롭게 취할수 있다. 

개발자들은 core application들이 사용된 같은 framework API들에 대해 완전히 접근할 수 있다. application 아키텍처는 component들의 재사용을 간단하게 하기위해 만들어 졌다. ; 어떤 application이  기능들을 만들어 펴낼 수 있고, 어떤 다른 application이 펴낸 이들의 기능들을 사용할 수도 있다(framework에 의해 강제된 보안 제약들의 권한 아래에 있을때). 이 같은 메커니즘은 component들이 사용자에 의해 교체되는 것을 허락한다.

모든 application들의 기저가 되는 것은 service들과 system들의 세트이다. 이는 다음을 포함한다.


* lists, grids, text boxes, buttons, 임베드가능한 web browser를 포함하고 application을 개발하는데 사용될 수 있는 풍부하고 확장가능한 Views의 세트

* application들이 (연락처 같은)다른 application들의 data에 접근하거나 그들의 data를 공유할 수 있게 해주는 Content Providers

* local에 위치한 strings, graphics, layout 파일들과 같이 코드로 되지 않은 리소스들에 대한 접근을 제공하는 Resource Manager

* 모든 application들이 사용자가 만든 알림들을 status bar에 배치할 수 있게 해주는 Notification Manager

* application들의 lifecycle을 관리하고 공통의 navigation backstack을 제공하는 Activity Manager



더 상세한 설명과 application의 종합적인 검토를 위해 Notepad Tutorial을 보자.




___________________________________________________

라이브러리들

안드로이드는 안드로이드 시스템의 다양한 component들을 사용하는 C/C++ 라이브러리들의 세트를 포함한다. 라이브러리들의 특징들은 안드로이드 application framework를 통해서 개발자들에게 노출되어진다. 몇몇의 core 라이브러들이 아래에 나열되어 있다.

* System C library  - BSD-the standard C system library(libc)의 완성에서 파생되었고, 임베디드된 Linux를 기본으로 하는 장치들을 위해 조정되어졌다.


* Media Libraries  - PacketVideo의 OpenCORE를 기본으로 한다. ; 라이브러리들은 MPEG4, H.254, MP3, AAC, AMR, JPG, PNG를 포함하는 많이 알려진 오디오와 비디오 포맷들, static image 파일들의 playback과 레코딩을 지원한다.

* Surface Manager - 디스플레이 서브시스템에 대한 접근을 관리하고 다양한 application들의 2D와 3D 그래픽 레이어들을 끊김 없이 합성한다.


* LibWebCore - 안드로이드 browser와 임베디드된 web view에 의해 작동하는 최신의 web browser engine
 
* SGL - 기본적인 2D graphics engine

* 3D libraries - OpenGL ES 1.0 APIs를 기본으로 완성 ; 라이브러리들은 hardware 3D acceleration(이용가능한 곳에서)을 사용하거나 포함되어있는 높게 앞축된 3D software rasterizer를 사용한다.

* Free Type - bitmap과 vector 폰트 랜더링

* SQLite - 모든 application들에게 이용가능한 강력하고 경량의 관계 데이터베이스 engine





_____________________________________________________________
개인적인 학습을 위한 발번역
[출처]  developer.android.com