OpenGL - 쉐이딩(Shading, line, flat smooth)
설명
삼각형으로 만든 원을 LineStrip, FlatShading, SmoothShading 효과를 줘 차이를 본다.
main에 없는 함수는 아래의 링크를 참조한다 (수정 x)
2017/09/12 - [SW/OpenGL] - OpenGL - 사각형 회전, 색바꾸기
선언부
typedef GLfloat point3[3]; static float theta[3]; int num = 1; void DrawTriangle(point3 &a, point3 &b, point3 &c); void Normalize(point3 &p); void DivideTriangle(point3 &a, point3 &b, point3 &c, int n); void CrossProduct(point3 &a, point3 &b, point3 &c, point3 &r);
Theta 초기화
void init(void) { for (int i = 0; i < 3; i++) { theta[i] = 0; } }
렌더링 함수
void RenderScene(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0, 0, 2, 0, 0, 0, 0, 1, 0); glEnable(GL_LIGHTING);//turn on light glEnable(GL_LIGHT0);//light0 turn on glRotatef(theta[2], 0, 0, 1); glRotatef(theta[1], 0, 1, 0); glRotatef(theta[0], 1, 0, 0); point3 v[4] = { { 0, 0, 1 },{ 0, 0.942809, -0.333333 },{ -.816497, -0.471405, -0.333333 },{ 0.816497, -0.471405, -0.333333 } }; int n = 3; DivideTriangle(v[0], v[1], v[2], n); DivideTriangle(v[0], v[2], v[3], n); DivideTriangle(v[0], v[3], v[1], n); DivideTriangle(v[3], v[2], v[1], n); glutSwapBuffers(); }
벡터 정규화
/// <summary> /// Normalizes vector /// </summary> /// <param name="p">The p.</param> void Normalize(point3 &p) { double d = p[0] * p[0] + p[1] * p[1] + p[2] * p[2]; if (d > 0) { float len = (float)(1.0 / sqrt(d)); p[0] *= len; p[1] *= len; p[2] *= len; } }
벡터 외적
/// <summary> /// Cross product vector a, b /// </summary> /// <param name="a">a.</param> /// <param name="b">The b.</param> /// <param name="c">The c.</param> /// <param name="r">The r.</param> void CrossProduct(point3 &a, point3 &b, point3 &c, point3 &r) { r[0] = (b[1] - a[1])*(c[2] - a[2]) - (b[2] - a[2])*(c[1] - a[1]); r[1] = (b[2] - a[2])*(c[0] - a[0]) - (b[0] - a[0])*(c[2] - a[2]); r[2] = (b[0] - a[0])*(c[1] - a[1]) - (b[1] - a[1])*(c[0] - a[0]); Normalize(r);//normalize }
삼각형으로 나누기
/// <summary> /// Divides the triangle recursively /// </summary> /// <param name="a">a.</param> /// <param name="b">The b.</param> /// <param name="c">The c.</param> /// <param name="n">The n.</param> void DivideTriangle(point3 &a, point3 &b, point3 &c, int n) { if (n > 0) { point3 v1, v2, v3; for (register int i = 0; i < 3; i++) { v1[i] = a[i] + b[i]; v2[i] = b[i] + c[i]; v3[i] = c[i] + a[i]; } Normalize(v1); Normalize(v2); Normalize(v3); DivideTriangle(a, v1, v3, n - 1); DivideTriangle(b, v2, v1, n - 1); DivideTriangle(c, v3, v2, n - 1); DivideTriangle(v1, v2, v3, n - 1); } else { DrawTriangle(a, b, c); } }
삼각형들 그리기
/// <summary> /// Draws the triangle. /// </summary> /// <param name="a">point a.</param> /// <param name="b">point b</param> /// <param name="c">point c</param> void DrawTriangle(point3 &a, point3 &b, point3 &c) { if (num == 1) // line strip { glDisable(GL_LIGHT0);//turn off light glBegin(GL_LINE_STRIP); { glNormal3fv(a); glVertex3fv(a); glNormal3fv(b); glVertex3fv(b); glNormal3fv(c); glVertex3fv(c); }glEnd(); } else if (num == 2) //flat shading { point3 n; CrossProduct(a, b, c, n); glBegin(GL_TRIANGLES); glNormal3fv(n); glVertex3fv(a); glVertex3fv(b); glVertex3fv(c); glEnd(); } else //smooth shading { glBegin(GL_TRIANGLES); { glNormal3fv(a); glVertex3fv(a); glNormal3fv(b); glVertex3fv(b); glNormal3fv(c); glVertex3fv(c); }glEnd(); } }
각 shading마다 이벤트를 받는다.
void keyboard(unsigned char key, int x, int y) { switch (key) { case 1://line strip { num = 1; }break; case 2://flat shading { num = 2; }break; case 3://smooth shading { num = 3; }break; default: break; } RenderScene(); } void shape(int item) { keyboard((unsigned char)item, 0, 0); }
메인함수
void main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(600, 600); glutCreateWindow("Shading"); glutDisplayFunc(RenderScene); glutReshapeFunc(ChangeSize); //show menu when right click glutCreateMenu(shape); //bind with key event glutAddMenuEntry("Wire frame", 1); glutAddMenuEntry("Flat", 2); glutAddMenuEntry("Smooth", 3); glutAttachMenu(GLUT_RIGHT_BUTTON); init(); SetupRC(); glutMainLoop(); }
결과물
'SW > OpenGL' 카테고리의 다른 글
OpenGL - 큐브회전 (X, Y, Z), 문자출력 (0) | 2017.09.13 |
---|---|
OpenGL - Perspective vs Orthographic (투시투영 vs 직교투영) (0) | 2017.09.13 |
OpenGL - 16개의 움직이는 랜덤 티팟 (0) | 2017.09.12 |
OpenGL - 로봇 팔 만들기 (0) | 2017.09.12 |
OpenGL - 정육면체 xyz축 회전 (0) | 2017.09.12 |