728x90
#include <glut.h>
#include <glm/glm.hpp>
#include <stdio.h>
#define PI 3.141592
#define CCW 0
#define CW 1
using namespace glm;
vec3 my_triangle1[3] = { vec3(-10.f, 0.f, 0.f), vec3(10.f, 0.f, 0.f), vec3(0.f, 10.f, 0.f) }; // CCW
vec3 my_triangle2[3] = { vec3(10.f, 0.f, 0.f), vec3(-10.f, 0.f, 0.f), vec3(0.f, 10.f, 0.f) }; // CW
vec3 faceNorm[2];
vec3 eyeVec;
GLfloat angle[2];
GLint culling = CW;
GLint isTriangle1 = 0;
GLint isTriangle2 = 0;
void RenderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.f, 0.f, 80.0f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f);
faceNorm[0] = cross(my_triangle1[1] - my_triangle1[0], my_triangle1[2] - my_triangle1[0]);
faceNorm[1] = cross(my_triangle2[1] - my_triangle2[0], my_triangle2[2] - my_triangle2[0]);
eyeVec = vec3(0.f, 0.f, 0.f) - vec3(0.f, 0.f, 80.0f);
angle[0] = acos(
dot(faceNorm[0], eyeVec) /
dot(sqrt(faceNorm[0].x * faceNorm[0].x + faceNorm[0].y * faceNorm[0].y + faceNorm[0].z * faceNorm[0].z),
sqrt(eyeVec.x * eyeVec.x + eyeVec.y * eyeVec.y + eyeVec.z * eyeVec.z))
);
angle[1] = acos(
dot(faceNorm[1], eyeVec) /
dot(sqrt(faceNorm[1].x * faceNorm[1].x + faceNorm[1].y * faceNorm[1].y + faceNorm[1].z * faceNorm[1].z),
sqrt(eyeVec.x * eyeVec.x + eyeVec.y * eyeVec.y + eyeVec.z * eyeVec.z))
);
if (angle[0] > PI/2.) isTriangle1 = CW;
else isTriangle1 = CCW;
if (angle[1] > PI/2.) isTriangle2 = CW;
else isTriangle2 = CCW;
if (culling == isTriangle1)
{
glColor3f(1.0f, 0.0f, 0.0f);
glPushMatrix();
glTranslatef(25.f, 0.f, 0.f);
glScaled(2.f, 2.f, 2.f);
glBegin(GL_TRIANGLES);
glVertex3f(-10.f, 0.f, 0.f);
glVertex3f(10.f, 0.f, 0.f);
glVertex3f(0.f, 10.f, 0.f);
glEnd();
glPopMatrix();
}
if (culling == isTriangle2)
{
glColor3f(0.0f, 1.0f, 0.0f);
glPushMatrix();
glTranslatef(-25.f, 0.f, 0.f);
glScaled(2.f, 2.f, 2.f);
glBegin(GL_TRIANGLES);
glVertex3f(-10.f, 0.f, 0.f);
glVertex3f(10.f, 0.f, 0.f);
glVertex3f(0.f, 10.f, 0.f);
glEnd();
glPopMatrix(); }
glFlush();
}
void SetupRC(void)
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}
void ChangeSize(GLsizei w, GLsizei h)
{
if (h == 0)
h = 1;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLfloat aspectRatio = (GLfloat)w / (GLfloat)h;
gluPerspective(90.f, aspectRatio, 10.f, 200.f);
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
glutCreateWindow("Assignment6");
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
SetupRC();
glutMainLoop();
return 0;
}
설명
* 기본적인 수학 연산(dot, cross product, square root)과 vec3 자료형 사용을 위해 glm 라이브러리를 사용하였습니다.
faceNorm [ 0 ] = cross ( my_triangle1 [ 1 ] - my_triangle1 [ 0 ],
my_triangle1 [ 2 ] - my_triangle1 [ 0 ]);
faceNorm [ 1 ] = cross ( my_triangle2 [ 1 ] - my_triangle2 [ 0 ],
my_triangle2 [ 2 ] - my_triangle2 [ 0 ]);
eyeVec = vec3 ( 0. f , 0. f , 0. f ) - vec3 ( 0. f , 0. f , 80.0 f );
faceNorm의 첫번째 요소에는 my_triangle1의 normal vector를, faceNorm의 두번째 요소에는 my_triangle의 normal vector를, eyeVec에는 눈이 바라보는 시선의 벡터를 저장한다. normal vector는 삼각형(PQR이라고 가정)의 두면 PQ 와 PR의 cross product로 구한다. 벡터는 벡터가 향하는 좌표 - 벡터의 시작점으로 구한다. (glm의 vec3자료형은 벡터형이 아닌 3차원 좌표를 나타내기 위해 쓰이기도 한다.)
angle [ 0 ] = acos (
dot (faceNorm [ 0 ], eyeVec) /
dot (sqrt (faceNorm [ 0 ]. x * faceNorm [ 0 ]. x
+ faceNorm [ 0 ]. y * faceNorm [ 0 ]. y
+ faceNorm [ 0 ]. z * faceNorm [ 0 ]. z),
sqrt (eyeVec . x * eyeVec . x + eyeVec . y * eyeVec . y + eyeVec . z * eyeVec . z))
);
두 벡터 사이의 각도는
와 같이 구한다.
if ( angle [ 0 ] > PI / 2. ) isTriangle1 = CW ;
else isTriangle1 = CCW ;
if ( angle [ 1 ] > PI / 2. ) isTriangle2 = CW ;
else isTriangle2 = CCW ;
눈과 삼각형의 normal vector가 이루는 각도가 90도 초과면 Clockwise, 90도 이하면 Counter-clockwise로 설정한다.
GLint culling = CW ;
…
if (culling == isTriangle1)
{
glColor3f ( 1.0 f, 0.0 f, 0.0 f);
glPushMatrix ();
glTranslatef ( 25. f, 0. f, 0. f);
glScaled ( 2. f, 2. f, 2. f);
glBegin ( GL_TRIANGLES );
glVertex3f ( - 10. f, 0. f, 0. f);
glVertex3f ( 10. f, 0. f, 0. f);
glVertex3f ( 0. f, 10. f, 0. f);
glEnd ();
glPopMatrix ();
}
if (culling == isTriangle2)
{
glColor3f ( 0.0 f, 1.0 f, 0.0 f);
glPushMatrix ();
glTranslatef ( - 25. f, 0. f, 0. f);
glScaled ( 2. f, 2. f, 2. f);
glBegin ( GL_TRIANGLES );
glVertex3f ( - 10. f, 0. f, 0. f);
glVertex3f ( 10. f, 0. f, 0. f);
glVertex3f ( 0. f, 10. f, 0. f);
glEnd ();
glPopMatrix (); }
glFlush ();
}
culling 모드와 삼각형의 방향을 비교하여 선택적으로 렌더링한다.
728x90
'College Computer Science > Computer Graphics' 카테고리의 다른 글
[컴퓨터그래픽스] 중간고사 대체 레포트 (0) | 2021.04.03 |
---|---|
[컴퓨터그래픽스] 키보드 마우스 입력을 통한 화면 변경 (0) | 2021.04.03 |
[컴퓨터그래픽스] gluLookat 변경을 통한 애니메이션 만들기 (0) | 2021.04.03 |
[컴퓨터그래픽스] transformation, scale, rotation (0) | 2021.04.03 |
[컴퓨터그래픽스] 소용돌이 실습 (함수 사용하지 않기) (0) | 2021.04.03 |
댓글