디지털 그래픽스

[openGL] 광원 메소드 확장 - 종류변경, y축회전, angle변경, attentuation(감쇠값) 변경, 초기화, z축 위치변경

gom1n 2021. 5. 17. 11:32

코드)

#include <iostream>
#include <math.h>
#include <gl/glut.h>
using namespace std;

int w = 500, h = 500;

void init() {
	glViewport(0, 0, w, h);
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glEnable(GL_DEPTH_TEST);

	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
}

float spin = 0;				//spin하는 속도
int ltype = 1;				//광원 종류 (디폴트: 1)
float angle = 45;			//spotlight angle (디폴트: 45)
float atte = 1.5;			//spotlight attentuation (디폴트: 1.5)
float zdist = 1;			//광원의 z축 위치

void display() {
	GLfloat position[] = { 0.0, 0.0, 1.0, 1.0 };
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(-1.0, 1.0, -1.0, 1.0, 1, 30.0);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(0, 0, 2.0f, 0, 0, 0, 0, 1, 0);
	
	//LIGHT y축 회전
	glPushMatrix();
	glRotated((GLdouble)spin, 0.0, 1.0, 0.0);
	spin += 1.0;									//광원이 1.0의 속도로 돌아감
	glLightfv(GL_LIGHT0, GL_POSITION, position);
    
	//Draw cube for light display: 광원큐브 그리기
	glTranslated(0.0, 0.0, zdist);	//z축 위치 변경
	glDisable(GL_LIGHTING);
	glColor3f(1.0, 0.0, 0.0);
	glutWireCube(0.05);
	glEnable(GL_LIGHTING);

	//LIGHT type 변경
	switch (ltype) {
	case 1:		//Point Light
		position[3] = 1;
		glLightfv(GL_LIGHT0, GL_POSITION, position);
		glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 0.0);
		break;
	case 2:		//Directional Light
		position[3] = 0;
		glLightfv(GL_LIGHT0, GL_POSITION, position);
		break;
	case 3:		//SpotLight 
		position[3] = 1;
		glLightfv(GL_LIGHT0, GL_POSITION, position);
		GLfloat sd[] = { 0.0, 0.0, -1.0 };
		glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, sd);
		glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, angle);				//angle값 변수
		glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, atte);		//감쇠값 변수
		break;
	}
	glPopMatrix();
    
	//TORUS
	glColor3f(0.7, 0.7, 0.7);
	glutSolidTorus(0.1, 0.4, 100, 100);
	glutSwapBuffers();
}

void keyboard(unsigned char key, int x, int y) {
	switch (key) {
    //광원 종류 변경(1, 2, 3)
	case '1':
		ltype = 1; glutPostRedisplay(); break;
	case '2':
		ltype = 2; glutPostRedisplay(); break;
	case '3':
		ltype = 3; glutPostRedisplay(); break;
    //광원의 z축 위치 증가/감소
	case '+':
		zdist += 0.2;
		glutPostRedisplay(); 
		break;
	case '-':
		zdist -= 0.2;
		glutPostRedisplay();
		break;
	//광원 위치 (0, 0, 1)로 초기화
    case 's':
		spin = 0;
		glutPostRedisplay();
		break;
	//spotlight angle값 증/감
    case 'a':
		angle++;
		glutPostRedisplay();
		break;
	case 'b':
		angle--;
		glutPostRedisplay();
		break;
	//spotlight attentuation(감쇠값) 증/감
    case 'c':
		atte++;
		glutPostRedisplay();
		break;
	case 'd':
		atte--;
		glutPostRedisplay();
		break;
	default: break;
	}
}
int main(int argc, char** argv) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize(w, h);
	glutInitWindowPosition(100, 100);
	glutCreateWindow("light");
	init();

	glutDisplayFunc(display);
	glutIdleFunc(display);
	glutKeyboardFunc(keyboard);
	glutMainLoop();

	return 0;
}

결과물)

[광원 종류 변경] - 1, 2, 3 입력

point light / directional light / spotlight

 

[광원 z축 위치 변경] - '+' 와 '-' 로 z축 증가감소

 

 

[spotlight angle 변경] - 'a'와 'b'로 각도 증가감소

 

 

[spotlight attentuation 변경] - 'c'와 'd'로 감쇠값 증가감소