설명
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 r, x_axis = 0, y_axis = 1, z_axis = 0;
int t_x, t_y, t_z;
/// <summary>
/// The vertices {x, y, z}
/// </summary>
GLfloat vertices[8][3] = { { -1, -1, 1 },{ -1, 1, 1 },
{ 1, 1, 1 },{ 1, -1, 1 },{ -1, -1, -1 },
{ -1, 1, -1 },{ 1, 1, -1 },{ 1, -1, -1 } };
/// <summary>
/// The colors {R, G, B}
/// </summary>
GLfloat colors[8][3] =
{ { 0, 0, 1 },{ 0, 1, 1 },
{ 1, 1, 1 },{ 1, 0, 1 },
{ 0, 0, 0 },{ 0, 1, 0 },
{ 1, 1, 0 },{ 1, 0, 0 } };
키보드 이벤트
void menu(int item)
{
keyboard((unsigned char)item, 0, 0);
}
void keyupfunc(unsigned char key, int x, int y)
{
t_x = 0;
t_y = 0;
t_z = 0;
}
void keyboard(unsigned char key, int x, int 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.5, 0.5, 0.5, 0, 0, 0, 0, 1, 0);
glPushMatrix(); {//push
glRotatef(theta, x_axis, y_axis, z_axis);
//draw cube
quad(0, 3, 2, 1);
quad(2, 3, 7, 6);
quad(3, 0, 4, 7);
quad(1, 2, 6, 5);
quad(4, 5, 6, 7);
quad(5, 4, 0, 1);
glEnd();
}glPopMatrix();//pop
glPushMatrix(); {//push
glColor3f(1, 0, 0);//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 button, int state, int x, int 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 x, int y)
{
if (mouseLeftDown)
{
double viewport[4];
glGetDoublev(GL_VIEWPORT, viewport);
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(listID, GL_COMPILE);
glEndList();
BuildFont();
glutTimerFunc(10, timer, 1);
}
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(hDC, font);
wglUseFontBitmaps(hDC, 32, 96, base);
SelectObject(hDC, oldfont);
DeleteObject(font);
}
void KillFont(GLvoid)
{
glDeleteLists(base, 96);
}
//print function
void glPrint(const char *fmt, ...)
{
char text[256];
va_list ap;
if (fmt == NULL)
return;
va_start(ap, fmt);
vsprintf(text, fmt, ap);
va_end(ap);
glPushAttrib(GL_LIST_BIT); {//push
glListBase(base - 32);
glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);
}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 a, int b, int c, int 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 argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutCreateWindow("xyz rotate");
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
glutMouseFunc(mouseButton);
glutMotionFunc(mouseMotion);
glutTimerFunc(1000 / 30, timer, 1); //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();
}
실행영상