|
|
길이가 너무 길어지는것 같아.. 따로 작성합니다.
대부분의 이미지를 일부러 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 |