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

[컴퓨터그래픽스] 키보드 마우스 입력을 통한 화면 변경

by 2den 2021. 4. 3.
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 = 3; // nothing first
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, 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();
	}

	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);
}

void MouseHandler(int button, int state, int x, int y)
{
	if (button == GLUT_LEFT_BUTTON) {
		if (state == GLUT_DOWN) culling = CW;
		if (state == GLUT_UP) culling = CCW;
	}

	glutPostRedisplay();
}

void KeyboardHandler(unsigned char key, int x, int y)
{
	if (key == 'b') glClearColor(0.f, 0.f, 1.f, 1.f);
	if (key == 'r') glClearColor(1.f, 0.f, 0.f, 1.f);

	glutPostRedisplay();
}

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

	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);
	glutCreateWindow("Assignment7");

	glutMouseFunc(MouseHandler);
	glutKeyboardFunc(KeyboardHandler);

	glutDisplayFunc(RenderScene);
	glutReshapeFunc(ChangeSize);

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

 

설명

 

GLint culling = 3 ; // nothing first
//…
	glColor3f ( 1.0 f , 1.0 f , 0.0 f );

마우스 입력을 받기 전, CW 삼각형과 CCW 삼각형이 둘 다 렌더되지 않도록 culling 디폴트 값을 3으로 설정하였다. 배경이 빨간색으로 변환될 경우에 대비해 첫번째 삼각형을 노란색으로 설정하였다.

 

void MouseHandler ( int button , int state , int x , int y )
{
	if ( button == GLUT_LEFT_BUTTON ) {
	if ( state == GLUT_DOWN ) culling = CW ;
	if ( state == GLUT_UP ) culling = CCW ;
	}
	glutPostRedisplay ();
}
//…
void main()
{
	//…
	glutMouseFunc (MouseHandler);
	//…
}

마우스 입력은 위와 같이 받는다.

 

void KeyboardHandler ( unsigned char key , int x , int y )
{
	if ( key == 'b' ) glClearColor ( 0. f , 0. f , 1. f , 1. f );
	if ( key == 'r' ) glClearColor ( 1. f , 0. f , 0. f , 1. f );
	glutPostRedisplay ();
}
//…
void main()
{
	//…
	glutKeyboardFunc (KeyboardHandler);
	//…
}

키보드 입력은 위와 같이 받는다.

 

 

728x90

댓글