Showing posts with label OpenGL. Show all posts
Showing posts with label OpenGL. Show all posts

Friday, April 28, 2017

Tessellation Shader vs Geometry Shader

Tessellation shader는 재귀 세분할이다.
반면 geometry shader는 primitive 단위로 적용된다.

The tessellation shader is for recursive subdivision. An important features is adjacency information so you can do smoothing correctly and not wind up with gaps. You could do some limited subdivision with a geometry shader, but that's not really what its for.

Geometry shaders operate per-primitive. For example, if you need to do stuff for each triangle (such as this), do it in a geometry shader. I've heard of shadow volume extrusion being done. There's also "conservative rasterization" where you might extend triangle borders so every intersected pixel gets a fragment. Examples are pretty application specific.

Tuesday, April 25, 2017

EGL PBuffers vs Pixmaps differences

EGL에서 생성할수 있는 EGLSurface는 다음과 같이 3가지 종류이다.

1) Window Surface
    - On-Screen Rendering Surfaces를 위해 사용
    - 리눅스의 framebuffer에 해당 할 것이다
    - eglCreateWindowSurface() 사용
2) Pbuffers Surface
    - Off-Screen Rendering Surfaces를 위해 사용
    - Graphic 메모리나 GPU 메모리에 생성
    - eglCreatePbufferSurface() 사용
    - Client(OpenGL ES)에서 생성한 Pbuffer를 EGL의 Pbuffer와 binding 할 때 사용은 eglCreatePbufferFromClientBuffer() 를 사용
3) Pixmaps Surface
    - Off-Screen Rendering Surfaces 를 위해 사용하고
      Graphic 메모리나 GPU 메모리에 생성한다는 점에서
      Windows Surface와 다름
    - OpenGLES 및 OpenVG와 같은 Client APIs 외의
       APIs를 지원한다는 점에서 Pbuffer Surface와 다름
    - Android의 TextureSurface에서 사용 (SurfaceTextureClient, SurafceTexureLayer 클래스)

Pixmaps는 PBuffers와 다르게 다른 Client APIs를 사용가능하다고 하는데 이는 buffer의 포인터가 노출이 되어 있어서 다른 클라이언트도 접근이 가능하다는 뜻이다. 예를 들어 C언어에서 포인터로 접근하여 직접 픽셀을 수정이 가능.

Android OpenGL GLSurfaceView 예제

안드로이드에서 OpenGL ES를 사용하려면 가장 간단하게 GLSurfaceView를 사용하면 된다.
GLSurfaceView를 생성하고 GLSurfaceView.Renderer를 구현하면 기본적인 뼈대가 완성 된다.
아래의 예제는 화면을 빨간색으로 지우는 단순한 예제이다.

package com.duongame.opengl;

import android.opengl.GLSurfaceView;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {
    GLSurfaceView glSurfaceView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        glSurfaceView = new GLSurfaceView(this);
        glSurfaceView.setRenderer(new MainRenderer());
        setContentView(glSurfaceView);

        //setContentView(R.layout.activity_main);
    }
}

package com.duongame.opengl;

import android.opengl.GLSurfaceView;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class MainRenderer implements GLSurfaceView.Renderer {
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        gl.glClearColor(1,0,0,1);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {

    }

    @Override
    public void onDrawFrame(GL10 gl) {
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    }
}

OpenGL ES Desktop Windows 버전에 관하여

NVIDIA와 INTEL 그래픽카드는 데스크탑에서 EGL을 사용할수 없다. 그러므로 OPENGL ES를 사용할수 없다.

AMD는 EGL을 통해서 데스크탑 OPENGL ES를 구현하고 있다.

Using OpenGL ES on desktops differs from IHV to IHV. While NVIDIA and Intel expose OpenGL ES on desktop via WGL/GLX extensions (e.g. http://opengl.delphigl.de/gl_listreports.php?listreportsbyextension=WGL_EXT_create_context_es_profile), AMD exposes it through EGL.

Saturday, April 25, 2015

OpenGL 정보를 한눈에 - GPU Caps Viewer

DirectX에서는 DDSCapsViewer라는 것이 있어서 설치된 VGA에서 텍스처 크기는 얼마이고 셰이더는 몇 버전까지 지원되며 등등의 정보를 표시해 준다. Direct3D Device 차원에서도 DDSCaps가 따로 존재한다.

하지만 OpenGL은 Extension은 glGetString으로 해야하고, Cg, CUDA, OpenCL의 각각의 Caps를 얻는 방법이 다르므로 방법을 통합하기란 쉽지 않다. 그리고 그것을 외부 툴로 확인하는 것은 각각 따로 만들어야 하는데 소개하는 GPU Caps Viewer를 사용하면 그러한 것을 한방에 해결할 수가 있다. 흡사 CPU-Z(구. CPU-ID)와 유사하다.

지원하는 기능은 다음과 같다.
1. OpenGL Extension(with GLSL) capabilities
2. CUDA capabilities
3. OpenCL capabilities

다운로드는 여기가서 받을수 있다.
http://www.geeks3d.com/gpucapsviewer/?from-gpu-caps-viewer

다운로드 받아서 설치후 GpuCapsViewer.exe를 실행시키면 다음과 같은 창이 뜬다.
완전 CPU-Z와 똑같다!

1. GPU/CPU탭은 일반적인 드라이버 정보를 보여준다.

2. OpenGL탭은 OpenGL에 특화된 정보를 보여준다. 버전, 텍스터 정보, 지오메트리 정보, GLSL 셰이더 정보 등등...

3. OpenGL은 Extension이라는 특수한 정보가 있으므로 Extensions의 Show All버튼을 누르면 Extension List창이 뜬다. 현재 드라이버에서 지원가능한 드라이버만 표시할수도 있다.

4. CUDA정보탭은 CUDA데이터와 메모리 관련정보를 보여준다. CUDA를 지원하지 않으면 물론 정보가 없다.

5. OpenCL탭은 역시 OpenCL정보를 보여준다. 이 스크린샷에서는 OpenCL을 NVIDIA CUDA를 사용하여 구현된다라고 보여주고 있다.

6. 보너스: OpenGL(GLSL) 및 OpenCL(CUDA) 샘플을 볼수있다. 탭 아래에 보면 OpenGL and OpenCL Demos에 있는 데모를 선택해서 Start를 누르면 프로그램이 실행된다.


이상으로 GPU Caps Viewer에 대한 툴소개를 마친다.

OpenGL NVIDIA GPU 메모리 체크 예제 다운로드

NVIDIA GPU에서만 사용가능한 메모리 체크 함수이다.
GLUT와 GL_NVX_GPU_memory_info 확장을 사용한다.

#include "GL\glew.h"
#include "GL\wglew.h"
#include "GL\glut.h"
#include <Windows.h>

#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glut32.lib")

#define GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047
#define GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048
#define GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049
#define GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A
#define GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B

int _tmain(int argc, _TCHAR* argv[])
{
 glutCreateWindow("NVXGpuMemoryInfo");

 int total, current;
 glGetIntegerv(GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &total);
 glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &current);

 printf("total: %d\n", total);
 printf("current: %d\n", current);

 return 0;
}

다운로드

Friday, April 10, 2015

OpenGL BMP 텍스처 저장

OpenGL에서 현재 texture를 눈으로 확인하며 디버깅하고 싶을 때 texture를 bmp파일로 저장하여 디버깅 할때 아래와 같이 한다.

이때 중요한 함수가 glGetTexLevelParameteriv인데 이것은 현재 texture 현재 mipmap level예제에서는 level가 1개 이므로 0이다.)의 parameter를 얻는 함수이다. 저장할 때는 32비트 bmp로 저장한다. glGetTexImage는 현재 texture의 pixel을 얻어온다.

이때 32비트 bmp는 GL_BGRA이므로 format을 GL_RGBA로 하면 색깔이 뒤집힌다.

#define GL_BGRA 0x80E1 // Use this for 32bit bmp

GLint cx, cy, format, bpp;

// 저장할 texture를 bind
glBindTexture(GL_TEXTURE_2D, id);

// cx,cy는 현재 texture의 width, height이다.
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &cx);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &cy);

// 현재 texture의 internal format을 얻는다. 여기서는 GL_RGBA만 대상으로 한다.
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format);

if (format == GL_RGBA)
{
size_t data_size = 4 * cx*cy;

// 32비트 bmp텍스처의 픽셀버퍼 메모리할당
unsigned char *data = new unsigned char[4 * cx*cy];

// 현재 texture의 픽셀을 얻어온다.
glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, data);

// bmp구조를 만든다음 저장한다.
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
bfh.bfType = 0x4d42;

// Entire file size(40+14+data_size)
bfh.bfSize = sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER) + data_size;
bfh.bfReserved1 = 0;
bfh.bfReserved2 = 0;
bfh.bfOffBits = 54;// offset(14+40)

// major
bih.biSize = sizeof(BITMAPINFOHEADER);//40
bih.biWidth = cx;
bih.biHeight = cy;
bih.biPlanes = 1;
bih.biBitCount = 32;

// minor
bih.biCompression = BI_RGB;
bih.biSizeImage = data_size;
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
bih.biClrUsed = 0;
bih.biClrImportant = 0;

FILE *fp = fopen("out.bmp", "wb");
if (fp) {
fwrite(&bfh, 1, sizeof(BITMAPFILEHEADER), fp);
fwrite(&bih, 1, sizeof(BITMAPINFOHEADER), fp);
fwrite(data, 1, data_size, fp);
fclose(fp);
}
delete[] data;
}

// texture를 unbind
glBindTexture(GL_TEXTURE_2D, 0);

OpenGL BMP 텍스처 로딩

OpenGL에서 bmp파일을 로딩하여 texture를 생성하는 코드이다. bmp는 24/32비트만을 지원한다. 15,16비트와 256칼라는 지원하지 않는다. glTexImage2D로 생성하기 때문에 다음과 같이 필터가 셋팅되어 있어야 한다.

#define GL_BGRA 0x80E1 // Use this for 32bit bmp
#define GL_BGR_EXT 0x80E0

void LoadBmp()
{
glBindTexture(GL_TEXTURE_2D, tex);
FILE *fp = fopen("c:\\cap2.bmp", "rb");
if (!fp)
return;
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
fread(&bfh, 1, sizeof(BITMAPFILEHEADER), fp);
fread(&bih, 1, sizeof(BITMAPINFOHEADER), fp);
fseek(fp, bfh.bfOffBits, SEEK_SET);// 중간에 더미값이 있을수도 있으니 정확하게 이렇게해서 데이타 시작 바이트를 찾아가자
int internalFormat = GL_BGR_EXT;
if (bih.biBitCount == 32)
{
internalFormat = GL_BGRA;
}
else if (bih.biBitCount == 24)
{
internalFormat = GL_BGR_EXT;
}
else
{
// 지원안되는 포맷(24,32만 지원)
fclose(fp);
glBindTexture(GL_TEXTURE_2D, 0);
return;
}
unsigned char *data2 = new unsigned char[bih.biSizeImage];
fread(data2, 1, bih.biSizeImage, fp);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bih.biWidth, bih.biHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, data2);// GL_BGRA
fclose(fp);
delete[] data2;
glBindTexture(GL_TEXTURE_2D, 0);
}

Cg vs GLSL 비교

현재 GLSL이 나온 상태에서 Cg의 장점은 무엇인가?

장점
1)Cg자체가 OpenGL, Direct3D 멀티 플랫폼 API이다. Direct3D도 지원하기 때문에 Direct3D에서 HLSL대신에 Cg를 사용해도 된다.

2)Cg는 문법이 HLSL과 동일하므로 MS의 예제에서도 많은 것을 공유할 수 있으다. 특히 멀티 플랫폼(OpenGL, Direct3D)시에 코드를 공유할 수 있다. 게다가 Effect파일 포맷인 fx도 CgFX, HLSL Effect끼리 호환된다는 것은 엄청난 장점이다. 1)번 장점에서 연속 되는 장점이다.

3)Cg는 어셈블리 셰이더로 컴파일 해서 그 결과를 어셈블리로 떨어뜨려 주기 때문에 어셈블리 셰이더를 한번 더 최적화가 가능하다.

4)GLSL이 지원이 안되는 구형 VGA에서는 Cg만 지원이 되는 경우가 있다. 이는 Cg는 OpenGL 익스텐션에서 Cg를 지원해야 되는 것이 아니라 어셈블리 셰이더만 지원이 되면 Cg 라이브러리에서 하이레벨 언어를 처리하므로 가능한 일이다. 3)번 장점에서 연속되는 장점이다.
e.g.)GLSL이 지원되려면
GL_ARB_vertex_shader, GL_ARG_fragment_shader이 필요하다.

4)NVIDIA인 경우 OpenGL에서 NVIDIA 특화 익스텐션을 사용함으로서 NVIDIA 부가기능을 사용할 수 있다. Profile 선택시 NVIDIA의 최신 버전 익스텐션 프로파일을 선택하면 가능하다.
e.g.)NVIDIA 최신셰이더의 예
GL_NV_vertex_program*

5)GLSL은 CgFX(Effect 포맷)가 없다.

단점
1)현재는 GLSL이 OpenGL 표준이다.
두말할 필요없이 새로 배우는 사람들은, 특히 OpenGL only유저들은 GLSL을 배우고 있다.

2)GLSL은 부가 API가 필요가 없지만, Cg는 DLL을 가지고 다녀야 한다.(부가적인 라이브러리가 필요하다)
GLSL은 이미 표준이므로 OpenGL 익스텐션의 일부이므로 Cg Toolkit과 같은 부가적인 라이브러리가 필요가 없다.

3)OpenGL ES지원이 미약하다.
Cg를 임베디드 버전인 OpenGL ES에서 사용하려면 수고가 뒤따른다.

Saturday, April 4, 2015

OpenGL GLSL 디버깅

1번은 현재 셰이더가 컴파일이 성공했는지를 리턴한다.
2번은 현재 프로그램이 바인딩이 되었는지를 리턴한다.
(1: 성공, 0: 실패)

// 1. GLSL 컴파일링
glCompileShaderARB(fp);
 
GLint bDidCompile;
glGetShaderiv(fp, GL_COMPILE_STATUS, &bDidCompile);

// 2. GLSL 바인딩
glLinkProgramARB(program);
glUseProgramObjectARB(program);

GLint bDidLink;
glGetProgramiv(program, GL_LINK_STATUS, &bDidLink);

OpenGL GLUT 예제

// GlutEmpty.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <Windows.h>
#include <gl/GL.h>
#include "gl/glut.h"

static const char *myProgramName = "GlutEmpty";
static void display(void)
{
    // 렌더링 전에 칼라버퍼와 깊이버퍼를 지워서 초기화 한다.
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    // 삼각형 하나를 그린다. 아무런 카메라 설정을 하지 않았으므로 화면은 x: -1~1, y: -1~1이고 z=0이다.
    glBegin(GL_TRIANGLES);
    glVertex2f(-0.8, 0.8);
    glVertex2f(0.8, 0.8);
    glVertex2f(0.0, -0.8);
    glEnd();
    // 다그렸으면 아까 GLUT_DOUBLE로 더블 버퍼이므로 프론트버퍼와 백버퍼를 스왑한다.
    glutSwapBuffers();
}
static void keyboard(unsigned char c, int x, int y)
{
    switch (c) {
    case 27: /* Esc key를 누르면 프로그램을 종료 한다. */
        exit(0);
        break;
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    // 윈도우 초기화 한다. 사이즈는 x=400, y=400
    glutInitWindowSize(400, 400);
    // 디스플레이모드를 설정한다. RGB칼라, 더블버퍼, 깊이버퍼
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    // GLUT를 초기화 한다. 나중에 string으로 옵션으로 전체화면 같은 것을 만들수 있으나 나중에 설명.
    // 일단은 main함수에서 받은것을 그대로 사용
    glutInit(&argc, argv);
    // 윈도우를 만든다. 파라미터는 TitleName
    glutCreateWindow(myProgramName);
    // 디스플레이 콜백함수. 렌더링 할때 사용하는 함수
    glutDisplayFunc(display);
    // 키보드 콜백함수. 키보드가 눌렸을 때
    glutKeyboardFunc(keyboard);
    // 클리어 칼라를 지정함. 하늘색으로 지정하자. 렌더링 할때 초기화 칼라로 쓴다.
    glClearColor(0.1, 0.3, 0.6, 0.0);
    glutMainLoop();
    return 0;
}


Thursday, April 2, 2015

OpenGL glGetUniformLocation()이 동작하지 않을때

OpenGL에서 glGetUniformLocation()이 동작하지 않을때가 있다.
예를 들어 다음과 같은 문장이 있을때 에러일 경우에는 리턴값이 -1이 된다.

GLES20.glGetUniformLocation(mTextureProgram, "modelViewProj");

이럴때는 다음과 같이 mTextureProgram을 link를 시켜주고 사용하면 정상적인 uniform의 ID값이 리턴된다.

GLES20.glLinkProgram(mTextureProgram);
GLES20.glGetUniformLocation(mTextureProgram, "modelViewProj");

OpenGL glFlush()와 glFinish()

glFlush()와 glFinish()

OpenGL은 네트워크를 통해 다른 머신에 랜더링을 할 수 있도록 지원한다. 클라이언트에서 애플리케이션의 메인코드가 실행이 되고 랜더링 서버에서 랜더링을 담당한다고 하자. OpenGL은 드로잉커맨드의 전송 효율을 높이기 위해 여러 드로잉커맨드를 한 패킷에 모아서 보낸다.
한 패킷을 다 채우지 못해서 클라이언트가 드로잉커맨드들을 전송하지 못하고 있고, 서버에서는 버퍼에 있는 모든 드로잉커맨드를 소비해서 처리할 게 없는 경우가 생길 수 있다. 이 때, glFlush()를 사용하면 패킷을 꽉 채워지지 않은 상태로 서버로 전달할 수 있다.

glFlush()함수는 패킷을 보낸 뒤에 바로 리턴을 하므로 다른 처리를 이어서 할 수 있다. 예를 들어, glFlush()를 함수 내에서 사용하는 DrawFrame()함수를 for문을 사용하여 백번 호출했고, 바로 이어서 키보드/마우스 이벤트를 처리하여 그 결과를 다음 프레임(101번째 frame)에서 확인하고자 한다면, 서버에서 101번째 frame을 처리할 때까지 기다려야만 하는데, 클라이언트는 서버에서 모든 드로잉커맨드를 처리했는지 확인할 방법이 없다. 이를 위해서는 glFlush() 대신 glFinish()를 사용할 수 있다. glFinish()는 서버에서 모든 드로잉커맨드가 처리되었다는 응답이 왔을 때 비로소 리턴한다.

싱글 버퍼 렌더링을 사용할 때에는 드로잉 결과가 화면에 그려지길 원할 때마다 glFlush나 glFinish를 반드시 호출해야 한다.


OpenGL ES 1.0에서 2.0으로 전환시 사용할수 없는 함수

OpenGL 2.0은 fixed function pipeline이 없으므로 무조건 GLSL을 사용해야 된다는 것은 익히 알려진 사실이다.

그러면 fixed function pipeline에서 사용하던 어떤 함수들을 사용할수 없을까?

1.0에서 2.0으로 전환하려면 단순하게 GLSurfaceView에서 다음과 같은 문장을 추가하게 되면 2.0을 사용하게 되는 환경으로 전환하게 된다.
setEGLContextClientVersion(2);

그런데 1.0으로 작성한 코드중에 대부분은 다음과 같은 에러가 발생하게 된다.
E/libEGL(7744): called unimplemented OpenGL ES API

이런 에러메세지들의 대부분은 vertex array에서 발생한다.
glEnableClientState, glDisableClientState, glVertexPointer, glTexCoordPointer, glColorPointer, glNormalPointer...

대신에 다음과 같은 함수를 써서 vertex attribute를 사용해야 한다.
glEnableVertexAttribArray, glVertexAttribPointer

그리고 텍스처 합성을 fragment shader에서 하기 때문에 glTexEnv*함수가 전체가 지원이 안된다.

마지막으로 transform 관련 함수가 vertex shader에서 지원하게 되므로 matrix관련 함수가 지원이 되지 않는다.
glMatrixMode, glTranslatef, glRotatef, glScalef, gluPerspective, gluOrtho2D...

http://stackoverflow.com/questions/7777605/opengl-es-1-1-to-2-0-a-major-change

OpenGL bitmap font example


#include <GL/glut.h>
#include <stdlib.h>
#include <GL/glaux.h>

GLubyte rasters[24] = {
   0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00,
   0xff, 0x00, 0xff, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00,
   0xff, 0xc0, 0xff, 0xc0};

void init(void)
{
   glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
   glClearColor (0.0, 0.0, 0.0, 0.0);
}

void display(void)
{
   glClear(GL_COLOR_BUFFER_BIT);
   glColor3f (1.0, 1.0, 1.0);
    //drawing F 3 times
   glRasterPos2i (20, 20);
   glBitmap (10, 12, 0.0, 0.0, 11.0, 0.0, rasters);
   glBitmap (10, 12, 0.0, 0.0, 11.0, 0.0, rasters);
   glBitmap (10, 12, 0.0, 0.0, 11.0, 0.0, rasters);
   glFlush();
}

void reshape(int w, int h)
{
   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glOrtho (0, w, 0, h, -1.0, 1.0);
   glMatrixMode(GL_MODELVIEW);
}

void keyboard(unsigned char key, int x, int y)
{
   switch (key) {
      case 27:
         exit(0);
   }
}

//Main Loop Open window with initial window size, title bar, RGBA display mode, and handle input events.

int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
   glutInitWindowSize(100, 100);
   glutInitWindowPosition(100, 100);
   glutCreateWindow(argv[0]);
   init();
   glutReshapeFunc(reshape);
   glutKeyboardFunc(keyboard);
   glutDisplayFunc(display);
   glutMainLoop();
   return 0;
}

Android 넥서스5 EGL extensions

안드로이드 각 디바이스별 GL/EGL extensions 목록은 다음 사이트에 가면 얻을 수 있다. 넥서스5에 관한 것은 아래의 링크와 같다.
http://delphigl.de/glcapsviewer/gles_generatereport.php?reportID=124

EGL_KHR_get_all_proc_addresses
EGL_ANDROID_presentation_time
EGL_KHR_image
EGL_KHR_image_base
EGL_KHR_lock_surface
EGL_KHR_gl_texture_2D_image
EGL_KHR_gl_texture_cubemap_image
EGL_KHR_gl_renderbuffer_image
EGL_KHR_fence_sync
EGL_KHR_create_context
EGL_EXT_create_context_robustness
EGL_ANDROID_image_native_buffer
EGL_KHR_wait_sync
EGL_ANDROID_recordable


Android EGL extensions 지원 목록 확인하기

EGL10 egl = (EGL10) EGLContext.getEGL();
EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);

int[] version = new int[2];
egl.eglInitialize(display, version);

Log.d(TAG, "EGL vendor: " + egl.eglQueryString(display, EGL10.EGL_VENDOR));
Log.d(TAG, "EGL version: " + egl.eglQueryString(display, EGL10.EGL_VERSION));

Log.d(TAG, "EGL extensions: " + egl.eglQueryString(display, EGL10.EGL_EXTENSIONS));