본문 바로가기
College Computer Science/Computer Graphics

[컴퓨터그래픽스] transformation, scale, rotation

by 2den 2021. 4. 3.
728x90
#include <glut.h>
#include <math.h>
#include <stdio.h>

int g_timeDelta = 0, g_prevTime = 0;
int inc_y = 1;

GLfloat g_x = 0.f;
GLfloat g_y = 1.f;
GLfloat g_velocityX = 0.5f;
GLfloat g_velocityY = 0.01f;

GLfloat vertices[] = {
	-0.8, -0.8, -0.8,
	 0.8, -0.8, -0.8,
	 0.8,  0.8, -0.8,
	-0.8,  0.8, -0.8,
	-0.8, -0.8,  0.8,
	 0.8, -0.8,  0.8,
	 0.8,  0.8,  0.8,
	-0.8,  0.8,  0.8 };
GLubyte faces[] = {
	7, 5, 6,
	7, 4, 5,
	3, 2, 1,
	3, 1, 0,
	2, 6, 5,
	2, 5, 1,
	3, 7, 6,
	3, 6, 2,
	0, 4, 7,
	0, 7, 3,
	1, 5, 4,
	1, 4, 0 };


void RenderScene(void)
{
	glClear(GL_COLOR_BUFFER_BIT);

	glMatrixMode(GL_MODELVIEW);

	g_x -= g_velocityX + (GLfloat)g_timeDelta / 1000.f;
	if (inc_y) {
		g_y += g_velocityY + (GLfloat)g_timeDelta / 1000.f;
		if (g_y >= 2.0f) inc_y = 0;
	}
	else {
		g_y -= g_velocityY + (GLfloat)g_timeDelta / 1000.f;
		if (g_y <= 0.5f) inc_y = 1;
	}
	
	glPushMatrix();
	glLoadIdentity();
	glColor3f(1.0f, 0.0f, 0.0f);
	glTranslatef(-0.5f, 0.5f, 0.0f);
	glRotatef(g_x, 0.0f, 0.0f, 1.0f);
	glScalef(0.1f, 0.1f, 0.1f);
	glTranslatef(-2.5f, 2.5f, 0.0f);
	glEnableClientState(GL_VERTEX_ARRAY);
	glVertexPointer(3, GL_FLOAT, 0, vertices);
	glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, faces);
	glDisableClientState(GL_VERTEX_ARRAY);
	glPopMatrix();

	glPushMatrix();
	glLoadIdentity();
	glColor3f(0.0f, 1.0f, 0.0f);
	glScalef(0.1f, 0.1f, 0.1f);
	glTranslatef(5.0f, 5.0f, 0.0f);
	glRotatef(g_x, 0.0f, 0.0f, 1.0f);
	glEnableClientState(GL_VERTEX_ARRAY);
	glVertexPointer(3, GL_FLOAT, 0, vertices);
	glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, faces);
	glDisableClientState(GL_VERTEX_ARRAY);
	glPopMatrix();

	glPushMatrix();
	glLoadIdentity();
	glColor3f(0.0f, 0.0f, 1.0f);
	glScalef(0.1f, 0.1f, 0.1f);
	glTranslatef(5.0f, -5.0f, 0.0f);
	glScalef(g_y, g_y, 0.1f);
	glEnableClientState(GL_VERTEX_ARRAY);
	glVertexPointer(3, GL_FLOAT, 0, vertices);
	glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, faces);
	glDisableClientState(GL_VERTEX_ARRAY);
	glPopMatrix();

	glutSwapBuffers();
}

void SetupRC(void)
{
	glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
}

void Idle()
{
	int currentTime = glutGet(GLUT_ELAPSED_TIME);
	g_timeDelta = currentTime - g_prevTime;
	g_prevTime = currentTime;
	glutPostRedisplay();
}

int main(int argc, char* argv[])
{
	glutInit(&argc, argv);

	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowSize(600, 600);
	glutCreateWindow("Project1");

	glutDisplayFunc(RenderScene);
	glutIdleFunc(Idle);

	SetupRC();
	glutMainLoop();
	return 0;
}

 

설명

 

glPushMatrix ();
glLoadIdentity ();
glColor3f ( 1.0 f , 0.0 f , 0.0 f );
glTranslatef ( - 0.5 f , 0.5 f , 0.0 f );
glRotatef ( g_x , 0.0 f , 0.0 f , 1.0 f );
glScalef ( 0.1 f , 0.1 f , 0.1 f );
glTranslatef ( - 2.5 f , 2.5 f , 0.0 f );
glEnableClientState ( GL_VERTEX_ARRAY );
glVertexPointer ( 3 , GL_FLOAT , 0 , vertices );
glDrawElements ( GL_TRIANGLES , 36 , GL_UNSIGNED_BYTE , faces );
glDisableClientState ( GL_VERTEX_ARRAY );
glPopMatrix ();

첫번째 큐브. glDrawElements로 큐브를 먼저 생성한 다음, 원점을 기준으로 원을 그리며 회전하기 위해 위치를 (-2.5, -2.5, 0)으로 이동한 후 크기를 작게 줄여주었다. 시간에 따라 점점 커지는 g_x 변수 각도만큼 z축을 기준으로 회전하고, 사방면 안에 정확히 옮겨주기 위해 glTranslatef로 조금 더 조절해주었다.

 

glPushMatrix ();
glLoadIdentity ();
glColor3f ( 0.0 f , 1.0 f , 0.0 f );
glScalef ( 0.1 f , 0.1 f , 0.1 f );
glTranslatef ( 5.0 f , 5.0 f , 0.0 f );
glRotatef ( g_x , 0.0 f , 0.0 f , 1.0 f );
glEnableClientState ( GL_VERTEX_ARRAY );
glVertexPointer ( 3 , GL_FLOAT , 0 , vertices );
glDrawElements ( GL_TRIANGLES , 36 , GL_UNSIGNED_BYTE , faces );
glDisableClientState ( GL_VERTEX_ARRAY );
glPopMatrix ();

두번째 큐브, 큐브를 생성한 후, 큐브의 중심이 원점을 지나므로 위에서 생성한 변수 g_x 만큼 z축을 기준으로 회전, (5, 5, 0)의 위치로 Translate 했다.

 

int inc_y = 1 ;
// ...
if ( inc_y ) {
	g_y += g_velocityY + ( GLfloat ) g_timeDelta / 1000. f ;
	if ( g_y >= 2.0 f ) inc_y = 0 ;
}
else {
	g_y -= g_velocityY + ( GLfloat ) g_timeDelta / 1000. f ;
	if ( g_y <= 0.5 f ) inc_y = 1 ;
}

glPushMatrix ();
glLoadIdentity ();
glColor3f ( 0.0 f , 0.0 f , 1.0 f );
glScalef ( 0.1 f , 0.1 f , 0.1 f );
glTranslatef ( 5.0 f , - 5.0 f , 0.0 f );
glScalef ( g_y , g_y , 0.1 f );
glEnableClientState ( GL_VERTEX_ARRAY );
glVertexPointer ( 3 , GL_FLOAT , 0 , vertices );
glDrawElements ( GL_TRIANGLES , 36 , GL_UNSIGNED_BYTE , faces );
glDisableClientState ( GL_VERTEX_ARRAY );
glPopMatrix ();

세번째 큐브. 큐브 생성 후 Scale부터 시행해야 원점과 물체 사이의 거리에 변화가 안생긴다. x와 y의 크기를 키웠다 줄였다 해주기 위해 (z좌표도 같은 g_y를 대입하면 3차원 모두 커졌다 작아진다.) g_y로 glScalef를 해준다. 그 후 적당한 위치로 옮겨 크기를 줄여주면 된다. g_y의 값은 1에서 시작하여 2가 되면 다시 0.5까지 작아지고, 0.5가 되면 다시 2까지 커지는 값이다.

 

728x90

댓글