이전 2의 제곱수가 아닌 이미지 출력하기...와 함께 적으려고했는데..
길이가 너무 길어지는것 같아.. 따로 작성합니다.

대부분의 이미지를 일부러 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일때의 화면입니다. 



+ Recent posts