OpenGL - 큐브회전 (X, Y, Z), 문자출력

설명


3차원 큐브를 X축, Y축, Z축 회전을 하며 (x, y, z키를 눌렀을 경우),


X, Y, Z를 눌렀을 때 우측 하단에 문자열을 출력한다.



소스코드

(앞의 예제와 마찬가지로 생략된 부분은 아래의 링크를  참조한다.)

2017/09/12 - [SW/OpenGL] - OpenGL - 사각형 회전, 색바꾸기


변수

static bool R = true;
static bool G = true;
static bool B = true;
static float theta;
bool rot = true;
int rx_axis = 0y_axis = 1z_axis = 0;
int t_xt_yt_z;
 
/// <summary>
/// The vertices {x, y, z}
/// </summary>
GLfloat vertices[8][3] = { { -1, -11 },{ -111 },
{ 111 },{ 1, -11 },{ -1, -1, -1 },
{ -11, -1 },{ 11, -1 },{ 1, -1, -1 } };
 
/// <summary>
/// The colors {R, G, B}
/// </summary>
GLfloat colors[8][3] =
{ { 001 },{ 011 },
{ 111 },{ 101 },
{ 000 },{ 010 },
{ 110 },{ 100 } };


키보드 이벤트

void menu(int item)
{
	keyboard((unsigned char)item00);
}
 
void keyupfunc(unsigned char keyint xint y)
{
	t_x = 0;
	t_y = 0;
	t_z = 0;
}
 
void keyboard(unsigned char keyint xint y)
{
	switch (key)
	{
	case 'q' | 'Q':
		exit(0); break;
	case VK_ESCAPE:
		exit(0); break;
	case 'x' | 'X'//rotate with x axis
	{
		x_axis = 1;
		y_axis = 0;
		z_axis = 0;
		t_x = 1;
		t_y = 0;
		t_z = 0;
		break;
	}
	case 'y' | 'Y'//rotate with y axis
	{
		x_axis = 0;
		y_axis = 1;
		z_axis = 0;
		t_x = 0;
		t_y = 1;
		t_z = 0;
		break;
	}
	case 'z' | 'Z'//rotate with z axis
	{
		x_axis = 0;
		y_axis = 0;
		z_axis = 1;
		t_x = 0;
		t_y = 0;
		t_z = 1;
		break;
	}
	default:
		break;
	}
}


렌더링함수

void RenderScene(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(0.50.50.5000010);
 
	glPushMatrix(); {//push
		glRotatef(thetax_axisy_axisz_axis);
		//draw cube
		quad(0321);
		quad(2376);
		quad(3047);
		quad(1265);
		quad(4567);
		quad(5401);
		glEnd();
	}glPopMatrix();//pop
 
	glPushMatrix(); {//push
		glColor3f(100);//red
		glRasterPos2f(1.4, -1.4);//string position
		if (t_x == 1)//print X_axis
			glPrint("X_axis"theta);
		else if (t_y == 1)//print Y_axis
			glPrint("Y_axis"theta);
		else if (t_z == 1)//print Z_axis
			glPrint("Z_axis"theta);
	}glPopMatrix();//pop
 
	glutPostRedisplay();
	glutSwapBuffers();
}
//swap rotate direction
void mouseButton(int buttonint stateint xint y)
{
	if (button == GLUT_LEFT_BUTTON)
	{
		if (state == GLUT_DOWN)
		{
			if (!mouseLeftDown)
			{
				if (rot)
					rot = false;
				else
					rot = true;
			}
		}
		else if (state == GLUT_UP)
		{
			if (mouseLeftDown)
				mouseLeftDown = false;
		}
	}
	else if (button == GLUT_RIGHT_BUTTON)
	{
		if (state == GLUT_DOWN)
		{
		}
		else if (state = GLUT_UP)
		{
		}
	}
	glutPostRedisplay();
}
 
void mouseMotion(int xint y)
{
	if (mouseLeftDown)
	{
		double viewport[4];
		glGetDoublev(GL_VIEWPORTviewport);
 
		point[1][0] = x / (float)viewport[2] * 500;
		point[1][1] = (viewport[3] - y) / (float)viewport[3] * 500;
	}
	glutPostRedisplay();
}


폰트 설정

//setting font
void init(void)
{
	theta = 0.0f;
	hWnd = GetActiveWindow();
	hDC = GetDC(hWnd);
 
	listID = glGenLists(1);
	glNewList(listIDGL_COMPILE);
 
	glEndList();
	BuildFont();
 
	glutTimerFunc(10timer1);
}
void BuildFont(void)
{
	HFONT font;
	HFONT oldfont;
 
	base = glGenLists(96);
	font = CreateFontA(-24,
		0,
		0,
		0,
		FW_BOLD,
		FALSE,
		FALSE,
		FALSE,
		ANSI_CHARSET,
		OUT_TT_PRECIS,
		CLIP_DEFAULT_PRECIS,
		ANTIALIASED_QUALITY,
		FF_DONTCARE | DEFAULT_PITCH,
		"Courier New");
 
	oldfont = (HFONT)SelectObject(hDCfont);
	wglUseFontBitmaps(hDC3296base);
	SelectObject(hDColdfont);
	DeleteObject(font);
}
void KillFont(GLvoid)
{
	glDeleteLists(base96);
}
 
//print function
void glPrint(const char *fmt, ...)
{
	char text[256];
	va_list ap;
	if (fmt == NULL)
		return;
 
	va_start(apfmt);
	vsprintf(textfmtap);
	va_end(ap);
 
	glPushAttrib(GL_LIST_BIT); {//push
		glListBase(base - 32);
		glCallLists(strlen(text), GL_UNSIGNED_BYTEtext);
	}glPopAttrib();//pop
}


cube를 구성할 사각형

/// <summary>
/// draw square
/// </summary>
/// <param name="a">a.</param>
/// <param name="b">The b.</param>
/// <param name="c">The c.</param>
/// <param name="d">The d.</param>
void quad(int aint bint cint d)
{
	glBegin(GL_QUADS);
	glColor3fv(colors[a]); glVertex3fv(vertices[a]);
	glColor3fv(colors[b]); glVertex3fv(vertices[b]);
	glColor3fv(colors[c]); glVertex3fv(vertices[c]);
	glColor3fv(colors[d]); glVertex3fv(vertices[d]);
}


메인함수

void main(int argccharargv[])
{
	glutInit(&argcargv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize(500500);
	glutCreateWindow("xyz rotate");
	glutDisplayFunc(RenderScene);
	glutReshapeFunc(ChangeSize);
 
	glutMouseFunc(mouseButton);
	glutMotionFunc(mouseMotion);
	glutTimerFunc(1000 / 30timer1); //timer 실행
	glutKeyboardFunc(keyboard);
	glutKeyboardUpFunc(keyupfunc);
 
	//bind menu with keyboard event
	glutCreateMenu(menu);
	glutAddMenuEntry("1"1);
	glutAddMenuEntry("2"2);
	glutAttachMenu(GLUT_RIGHT_BUTTON);
 
	init();
	SetupRc();
	glutMainLoop();
}



실행영상



OpenGL - 로봇 팔 만들기

설명

로봇의 팔을 만들어서 회전하고 꺽을수 있다.


이번에도 마찬가지로 소스에 대한 설명은 주석을 참조하세요

또한 생략된 소스는 맨 앞의 글을 참조하세요

2017/09/12 - [SW/OpenGL] - OpenGL - 사각형 회전, 색바꾸기



로봇의 base

void base(void)
{
	glPushMatrix();//push
	{
		glColor3f(100);//red
		glTranslatef(0, -0.80);//y axis
		glRotatef(-90100);//x axis
		glRotatef(Base_Angle001);//z axis
		gluCylinder(p0.50.50.3201);//draw cylinder
	}
	glPopMatrix();//pop
}


로봇의 lower

/// <summary>
/// arm's lower
/// </summary>
void lower_arm(void)
{
	glPushMatrix();//push
	{
		glColor3f(010);//green
		glRotatef(Base_Angle010);//rotate with y axis
		glTranslatef(0, -0.70);//translate with axis
		glRotatef(Lower_Arm_Angle001);//rotate with z axis
		glTranslatef(00.50);//translate with y axis
		glScalef(0.210.2);//scaling
		glutWireCube(1);//draw cube
	}
	glPopMatrix();//pop
}


로봇의 upper

/// <summary>
/// arm's upper
/// </summary>
void upper_arm(void)
{
	glPushMatrix(); //push
	{
		glColor3f(001); // blue
		glRotatef(Base_Angle010); //rotate y axis
		glTranslatef(0, -0.70);//translate y axis
		glRotatef(Lower_Arm_Angle001);//rotate z axis
		glTranslatef(01.00);//translate y axis
		glRotatef(Upper_Arm_Angle001);//rotate z axis
		glTranslatef(00.40);//translate y axis
		glScalef(0.20.80.2);//scaling
		glutWireCube(1);//draw cube
	}
	glPopMatrix();//pop
}


렌더링 함수

void RenderScene(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(0.50.50.5000010);//setting camera viewpoint
	base(); //draw base
	lower_arm(); //draw lower part
	upper_arm(); //draw upper part
	glutSwapBuffers();
}


스페셜 키 이벤트 (화살표4개, home, end)

/// <summary>
/// Special key event
/// </summary>
/// <param name="key">Special key.</param>
/// <param name="x">The x</param>
/// <param name="y">The y</param>
void specialkeys(int keyint xint y)
{
	switch (key)
	{
	case GLUT_KEY_UP//up arrow
		Lower_Arm_Angle += 2;
		break;
	case GLUT_KEY_DOWN//down arrow
		Lower_Arm_Angle -= 2;
		break;
	case GLUT_KEY_LEFT//left arrow
		Base_Angle -= 2;
		break;
	case GLUT_KEY_RIGHT//right arrow
		Base_Angle += 2;
		break;
	case GLUT_KEY_HOME//home key
		Upper_Arm_Angle += 2;
		break;
	case GLUT_KEY_END//end key
		Upper_Arm_Angle -= 2;
		break;
	default:
		break;
	}
}


메인함수

void main(int argccharargv[])
{
	glutInit(&argcargv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize(500500);
	glutCreateWindow("Simple");
	glutDisplayFunc(RenderScene);
	glutReshapeFunc(ChangeSize);
	glutSpecialFunc(specialkeys); //Special key event
	glutMouseFunc(mouseButton);
	glutMotionFunc(mouseMotion);
	glutTimerFunc(1000 / 30timer1);
	glutKeyboardFunc(keyboard);
	init();
	SetupRc();
	glutMainLoop();
}


타이머 함수

void timer(int value)
{
	if (rot)
	{
		theta += 2.0;
		if (theta >= 360.0)
			theta -= 360.0;
	}
	else
	{
		theta -= 2.0;
		if (theta <= 360.0)
			theta += 360.0;
	}
	glutTimerFunc(1000 / 30timer1);
	glutPostRedisplay();
}


결과


OpenGL - 정육면체 xyz축 회전


설명


정육면체를 'X'를 눌렀을때는 X축 회전, 'Y'를 눌렀을땐 Y축회전, 'Z'를 눌렀을때는 Z축 회전시킨다.



소스설명


앞의 소스와 중복되는 부분은 변경이 있기전까진 생략한다.

궁금하신분은 맨 앞의 게시물을 확인바랍니다.

2017/09/12 - [SW/OpenGL] - OpenGL - 사각형 회전, 색바꾸기



선언

static bool mouseLeftDown;//checking mouse click
static float point[2][2];
void mouseButton(int buttonint stateint xint y);
void mouseMotion(int xint y);
void keyboard(unsigned char keyint xint y);
void timer(int value);
void quad(int aint bint cint d);
static bool R = true;
static bool G = true;
static bool B = true;
static float theta;
bool rot = true;
int rx_axis = 0y_axis = 1z_axis = 0;


점8개와 색8개

/// <summary>
/// eight point to draw a cube
/// </summary>
GLfloat vertices[8][3] = { { -1, -11 },{ -111 },
{ 111 },{ 1, -11 },{ -1, -1, -1 },
{ -11, -1 },{ 11, -1 },{ 1, -1, -1 } };
 
 
 
/// <summary>
/// eight color each points
/// </summary>
GLfloat colors[8][3] =
{ { 001 },{ 011 },
{ 111 },{ 101 },
{ 000 },{ 010 },
{ 110 },{ 100 } };

colors는 r,g,b 값으로 색을 조합한다.



x,y,z 키에 대한 이벤트(x축, y축, z축)

void keyboard(unsigned char keyint xint y)
{
	switch (key)
	{
	case 'q' | 'Q':
		exit(0); break;
	case VK_ESCAPE:
		exit(0); break;
	case 1:
		exit(0); break;
	case 2:
		exit(0); break;
	case 'x' | 'X':
	{
		x_axis = 1;
		y_axis = 0;
		z_axis = 0;
		break;
	}
	case 'y' | 'Y':
	{
		x_axis = 0;
		y_axis = 1;
		z_axis = 0;
		break;
	}
	case 'z' | 'Z':
	{
		x_axis = 0;
		y_axis = 0;
		z_axis = 1;
		break;
	}
	default:
		break;
	}
}


렌더링함수

void RenderScene(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(0.50.50.5000010); //view point
	glRotatef(thetax_axisy_axisz_axis);//rotate cube
 
	//draw a cube with 6 quadrature
	quad(0321);
	quad(2376);
	quad(3047);
	quad(1265);
	quad(4567);
	quad(5401);
	glEnd();
	glutSwapBuffers();
}


사각형을 그린다 위의 함수에서 6개의 사각형을 그리는데 사용하는 함수 quad

void quad(int aint bint cint d)
{
	glBegin(GL_QUADS);
	glColor3fv(colors[a]); glVertex3fv(vertices[a]);
	glColor3fv(colors[b]); glVertex3fv(vertices[b]);
	glColor3fv(colors[c]); glVertex3fv(vertices[c]);
	glColor3fv(colors[d]); glVertex3fv(vertices[d]);
}


마우스 클릭, 모션 함수 (마우스 왼쪽 클릭하면 회전방향이 바뀐다.)

void mouseButton(int buttonint stateint xint y)
{
	//mouse left button click
	if (button == GLUT_LEFT_BUTTON)
	{
		if (state == GLUT_DOWN)
		{
			if (!mouseLeftDown)
			{
				if (rot)
					rot = false;
				else
					rot = true;
			}
		}
		else if (state == GLUT_UP)
		{
			if (mouseLeftDown)
				mouseLeftDown = false;
		}
	}
	//mouse right button click
	else if (button == GLUT_RIGHT_BUTTON)
	{
		if (state == GLUT_DOWN)
		{
 
		}
		else if (state = GLUT_UP)
		{
 
		}
	}
	glutPostRedisplay();
}
 
void mouseMotion(int xint y)
{
	if (mouseLeftDown)
	{
		double viewport[4];
		glGetDoublev(GL_VIEWPORTviewport);
 
		point[1][0] = x / (float)viewport[2] * 500;
		point[1][1] = (viewport[3] - y) / (float)viewport[3] * 500;
	}
	glutPostRedisplay();
}


정육면체를 회전하기 위한 타이머

void timer(int value)
{
	if (rot)
	{
		theta += 2.0;
		if (theta >= 360.0)
			theta -= 360.0;
	}
	else
	{
		theta -= 2.0;
		if (theta <= 360.0)
			theta += 360.0;
	}
	glutTimerFunc(1000 / 30timer1);
	glutPostRedisplay();
}




초기화

void init(void)
{
	theta = 0.0f;
	glutTimerFunc(10timer1);
}
 
void SetupRc(void)
{
	glClearColor(1.0f1.0f1.0f1.0f);
	glEnable(GL_DEPTH_TEST);
}



결과



'x축'에 해당되는 글 3건

1 →