|
길이가 너무 길어지는것 같아.. 따로 작성합니다.
대부분의 이미지를 일부러 2의 제곱수로 만들지 않으므로 2의 제곱수로 변환하고 텍스쳐를 생성하는 작업을 많이하게됩니다.
그래서 이미지가 많이사용되는 게임의 경우에는 1024*1024크기의 이미지에 전부 넣어놓고 특정 부분만 잘라서 사용하는 방식을 사용하더군요.. 팔라독, 룰더스카이 등등..
확실히 큰 이미지 몇개를 로딩하는것이 작은것 여러개를 변환하고 만들어 로딩하는것보다는 효율적인것 같습니다.
이번에는 텍스쳐의 부분부분을 출력하는 방법을 알아봅시다.
다시 512*512 크기의 팬더를 사용해서 해보겠습니다.
팬더의 왼쪽눈이 대충 71, 174 위치에 자리잡고 있군요.. 크기는 120, 80 정도로 잡겠습니다.
GLGameRenderer.c
void updateGameLoop() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); updatePanda(); //drawPanda(); drawPandaClip(71, 174, 120, 80); }기존의 drawPanda()를 잠시 쉬게하고 drawPandaClip을 만듭니다.
void drawPandaClip(int sx, int sy, int w, int h) { GLfloat vertices[12] = { g_nX , g_nY+h , 0.0f, // LEFT | BOTTOM g_nX+w , g_nY+h , 0.0f, // RIGHT | BOTTOM g_nX , g_nY , 0.0f, // LEFT | TOP g_nX+w , g_nY , 0.0f // RIGHT | TOP }; GLfloat texture[8] = { (GLfloat)sx/(GLfloat)g_nPandaWidth , (GLfloat)(sy+h)/(GLfloat)g_nPandaHeight, (GLfloat)(sx+w)/(GLfloat)g_nPandaWidth , (GLfloat)(sy+h)/(GLfloat)g_nPandaHeight, (GLfloat)sx/(GLfloat)g_nPandaWidth , (GLfloat)sy/(GLfloat)g_nPandaHeight, (GLfloat)(sx+w)/(GLfloat)g_nPandaWidth , (GLfloat)sy/(GLfloat)g_nPandaHeight }; glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, g_textureName); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, 0, vertices); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, 0, texture); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glDisable(GL_TEXTURE_2D); }sx, sy
팬더의 눈이 시작될 지점이 되겠군요.
w, h
팬더 눈의 크기 입니다.
vertices[12]
그려질 위치와 크기를 지정해 주는곳이죠.
g_nX, g_nY는 그려질 위치이며, 입력받은 w, h만큼의 크기로 그려준다고 알려줍니다.
texture[8]
이 부분이 실제 텍스쳐에서 그려질 부분을 지정하는 부분입니다.
기존의 drawPanda()소스에서는
GLfloat texture[8] = { 0 , 1, 1 , 1, 0 , 0, 1 , 0 };왼쪽이 width, 오른쪽이 height라고 말씀드렸었죠.
0 ~ 1까지가 0 ~ 100%를 표현한 것이라고도 말씀드렸었구요.
위 소스를 실행시켰을때가 이미지가 100%의 크기로 나왔으니 0은 텍스쳐의 시작을 1은 끝을 의미한다고 볼 수 있습니다.
그럼 0은 원하는 좌표(sx, sy)비율을 1은 원하는 크기까지(sx+w, sy+h)의 비율을 넣으면 됩니다.
왼쪽의 0은 width 부분의 시작 : 이미지 가로길이중에 sx가 차지하는 비율
왼쪽의 1은 width 부분의 끝 : 이미지 가로길이중에 sx+w가 차지하는 비율
오른쪽의 0은 height 부분의 시작 : 이미지 세로길이중에 sy가 차지하는 비율
오른쪽의 1은 height 부분의 끝 : 이미지 세로길이중에 sy+h가 차지하는 비율
빌드 후 실행..
깔끔하군요!
이번에는 원하는 좌표를 중심으로 갖는 이미지를 출력해보겠습니다.
GLGameRenderer.c
void updateGameLoop() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); updatePanda(); //drawPanda(); //drawPandaClip(71, 174, 120, 80); drawPandaC(240, 400); }방금 작업한 clip도 휴식을 주고 drawPandaC()함수를 제작합니다.
void drawPandaC(int cx, int cy) { GLfloat vertices[12] = { cx - (g_nPandaWidth>>1) , cy + (g_nPandaHeight>>1) , 0.0f, // LEFT | BOTTOM cx + (g_nPandaWidth>>1) , cy + (g_nPandaHeight>>1) , 0.0f, // RIGHT | BOTTOM cx - (g_nPandaWidth>>1) , cy - (g_nPandaHeight>>1) , 0.0f, // LEFT | TOP cx + (g_nPandaWidth>>1) , cy - (g_nPandaHeight>>1) , 0.0f // RIGHT | TOP }; GLfloat texture[8] = { 0 , g_textureHeight, g_textureWidth , g_textureHeight, 0 , 0, g_textureWidth , 0 }; glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, g_textureName); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, 0, vertices); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, 0, texture); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glDisable(GL_TEXTURE_2D); }이미지의 중점 cx, cy를 받아오는군요.
vertices좌표에서 기존의 g_nX, g_nY가 받아온 중점으로 바뀌었습니다.
그리고 그 중점을 기준으로 이미지의 절반씩 더하거나 빼줍니다.
빌드 후 실행 ~
딱 가운데 왔지요~!
회전을 해볼까요?
void drawPandaC(int cx, int cy, int deg)방금사용한 함수에 파라메타를 하나 추가합니다.
GLfloat vertices[12] = { - (g_nPandaWidth>>1) , + (g_nPandaHeight>>1) , 0.0f, // LEFT | BOTTOM + (g_nPandaWidth>>1) , + (g_nPandaHeight>>1) , 0.0f, // RIGHT | BOTTOM - (g_nPandaWidth>>1) , - (g_nPandaHeight>>1) , 0.0f, // LEFT | TOP + (g_nPandaWidth>>1) , - (g_nPandaHeight>>1) , 0.0f // RIGHT | TOP };vertices 좌표가 달라졌습니다.
이유는 기존의 상태로 회전을 시키면 원하는대로 회전해주지 않으니까요 ~
0,0을 이미지 중점으로 놓고 그려줍니다.
glLoadIdentity(); glTranslatef(cx, cy, 0.0f); glRotatef(deg, 0.0f, 0.0f, 1.0f);좌표계를 초기화 해주고 ( 이전 좌표계의 영향을 받을 수 있으므로 )
glTranslatef(cx, cy, 0.0f);
기준 축을 cx, cy로 이동시킵니다.
glRotatef(deg, 0.0f, 0.0f, 1.0f);
z축을 기준으로 회전을 시킵니다.
빌드 후 실행 ~
원하는 좌표(cx, cy)에서 빙글빙글 도는 팬더가 출력되는군요.
확대와 축소를 해볼차례 입니다~!
회전하기전 drawPandaC() 소스를 기반으로 하겠습니다.
void drawPandaScale(int cx, int cy, GLfloat scale) { GLfloat vertices[12] = { cx - (g_nPandaWidth>>1)/scale , cy + (g_nPandaHeight>>1)/scale , 0.0f, // LEFT | BOTTOM cx + (g_nPandaWidth>>1)/scale , cy + (g_nPandaHeight>>1)/scale , 0.0f, // RIGHT | BOTTOM cx - (g_nPandaWidth>>1)/scale , cy - (g_nPandaHeight>>1)/scale , 0.0f, // LEFT | TOP cx + (g_nPandaWidth>>1)/scale , cy - (g_nPandaHeight>>1)/scale , 0.0f // RIGHT | TOP }; GLfloat texture[8] = { 0 , g_textureHeight, g_textureWidth , g_textureHeight, 0 , 0, g_textureWidth , 0 }; glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, g_textureName); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, 0, vertices); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, 0, texture); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glDisable(GL_TEXTURE_2D); }vertices만 바뀌었습니다.
scale 값이 0 < scale < 1.0 이면 확대
1.0 < scale 축소 입니다.
왼쪽은 scale이 0.5일때의 화면이며
오른쪽은 scale이 2.0일때의 화면입니다.
|
'Android > OpenGL' 카테고리의 다른 글
[NDK-OpenGL_05] 2의 제곱수가 아닌 텍스쳐 출력하기 (0) | 2012.03.06 |
---|---|
[NDK-OpenGL_04] 쓰레드 생성 (0) | 2012.03.04 |
[NDK-OpenGL_03] 텍스쳐 입히기 (5) | 2012.02.27 |
[NDK-OpenGL_02] 해상도 지정하기 (3) | 2012.02.26 |
[NDK-OpenGL_01] 프로젝트 준비 (3) | 2012.02.26 |