☀️태양이 귀여워요

🥔감자로그🍟·2023년 6월 14일
post-thumbnail

행성 만들기

void display()
{
	//깊이 버퍼를 사용하여 DEPTH TEST를 활성화 -> 은면 제거
	glEnable(GL_DEPTH_TEST);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	//시점 설정. 초기 값은 camPos[0] = 0.1, camPos[1] = 0.1, camPos[2] = 0.1
	gluLookAt(camPos[0], camPos[1], camPos[2],0.1, 0.0, 0.0, 1.0, 1.5, 0.0);


	//scale값을 변수로 받아 줌인 줌아웃을 수행
	glScalef(scale, scale, scale);

	//WireSphere 함수를 사용하여 태양 생성
	glBindTexture(GL_TEXTURE_2D, planet_texture[0]);
	glTexCoord2f(0.2f, 0.5f);
	glColor3f(sun_color[0], sun_color[1], sun_color[2]);
	glutWireSphere(1, 20, 20);

	glColor3f(1, 1, 0);
	glutWireSphere(0.8, 20, 20);

	glColor3f(1, 1, 1);
	glutSolidSphere(0.6, 20, 20);


	//수성
	glPushMatrix();
	glBindTexture(GL_TEXTURE_2D, planet_texture[1]);
	glColor3f(mercury_color[0], mercury_color[1], mercury_color[2]);
	glRotatef(mercury_year, 0.0, 1.0, 0.0);
	glTranslatef(1.5, 0.0, 0.0);
	glRotatef(day, 0.0, 1.0, 0.0);
	glutWireSphere(0.1, 10, 8);
	glLoadIdentity();
	glPopMatrix();


	//금성
	glPushMatrix();
	glBindTexture(GL_TEXTURE_2D, planet_texture[2]);
	glColor3f(venus_color[0], venus_color[1], venus_color[2]);
	glRotatef(venus_year, 0.0, 1.0, 0.0);
	glTranslatef(2.5, 0.0, 0.0);
	glRotatef(day, 0.0, 1.0, 0.0);
	glutWireSphere(0.25, 10, 8);
	glLoadIdentity();
	glPopMatrix();

	//지구
	glPushMatrix();
	glBindTexture(GL_TEXTURE_2D, planet_texture[3]);
	glColor3f(earth_color[0], earth_color[1], earth_color[2]);
	glRotatef(earth_year, 0.0, 1.0, 0.0);
	glTranslatef(3.5, 0.0, 0.0);
	glRotatef(day, 0.0, 1.0, 0.0);
	glutWireSphere(0.25, 10, 8);
	
	glColor3f(0.254902, 0.411765, 0.882353);
	glRotatef(earth_year, 0.0, 1.0, 0.0);
	glRotatef(day, 0.0, 1.0, 0.0);
	glutWireSphere(0.20, 10, 8);

	//달
	glBindTexture(GL_TEXTURE_2D, planet_texture[9]);
	glRotatef(moon, 0.0, 1.0, 0.0);
	glTranslatef(0.5, 0.0, 0.0);
	glColor3f(1,	1,	0.878431);
	glutWireSphere(0.06, 10, 8);  //달   
	glLoadIdentity();
	glPopMatrix();


	//화성
	glPushMatrix();
	glBindTexture(GL_TEXTURE_2D, planet_texture[4]);
	glColor3f(mars_color[0], mars_color[1], mars_color[2]);
	glRotatef(mars_year, 0.0, 1.0, 0.0);
	glTranslatef(4.5, 0.0, 0.0);
	glRotatef(day, 0.0, 1.0, 0.0);
	glutWireSphere(0.125, 10, 8);
	glLoadIdentity();
	glPopMatrix();

	.........
	
	glDisable(GL_DEPTH_TEST);
	glutSwapBuffers();
}

행성 공전

//행성의 공전을 수행하는 TimerFunc 함수
void timerFunc(int value) {
	//자전. 모든 행성의 자전은 day로 똑같은 값을 갖도록 함
	day = fmodf(day + 1, 360);
	glutPostRedisplay();

	// 행성 공전 구현
	//주어진 공전 비율에 따른 공전 구현
	//실수값의 나머지 연산은 fmodf를 사용
	mercury_year = fmodf(mercury_year + 0.5, 360);
	venus_year = fmodf(venus_year + 1.2, 360);
	earth_year = fmodf(earth_year + 2, 360);
	mars_year = fmodf(mars_year + 3.8, 360);
	moon = fmodf(moon + 0.14, 360);

	jupyter_year = fmodf(jupyter_year + 1.5, 360);
	saturn_year = fmodf(saturn_year + 1.0, 360);
	uranus_year = fmodf(uranus_year + 0.7, 360);
	neptune_year = fmodf(neptune_year + 0.5, 360);

	glutPostRedisplay();
	glutTimerFunc(RotateTime, timerFunc, 1);
}

키보드 이벤트


//키보드 입력에 따른 공전 속도 조절 함수 
void Keyboard(unsigned char key, int x, int y)
{
	switch (key)
	{
	//스페이스 바 입력 시 모든 행성의 공전 멈춤
	//만약 이미 멈춤 상태라면, 스페이스바 재입력 시 공전 재개
	case 32:
		if (RotateTime == 0)
			RotateTime = 45;
		else
			RotateTime = 0;
		glutTimerFunc(RotateTime, timerFunc, 1); // 타이머 콜백
		break;
	//+ 입력 시 RotateTime의 값을 감소시켜, 공전 속도가 빨라지게 함
	//0 이하로 내려가지 않게 하기 위한 조건문
	case '+':
		if (RotateTime > 5)
			RotateTime -= 5;
		printf("%d", RotateTime);
		break;
	//- 입력 시 RotateTime의 값을 증가시켜 공전 속도가 느려지게 함
	//100 이상으로 올라가지 않도록 제어
	case '-':
		if (RotateTime < 100)
			RotateTime += 5;
		printf("%d", RotateTime);
		break;
	}
	glutPostRedisplay();
}

//방향키 등 특수 키에 대한 이벤트 처리
void Special(int key, int x, int y)
{
	float rotation = 0.1;

	//왼쪽 방향키 
	if (key == GLUT_KEY_LEFT)
	{
		//camPos[2] -> z값을 변경시켜, 회전을 구현
		camPos[2] -= rotation;
		if (camPos[2] < -5.0) // 최소값을 벗어나는 경우
			camPos[2] = -5.0;
	}
	//오른쪽 방향키
	if (key == GLUT_KEY_RIGHT)
	{
		//camPos[2] -> z값을 증가시켜 회전을 구현
		camPos[2] += rotation;
		if (camPos[2] > 5.0) // 최대값을 벗어나는 경우
			camPos[2] = 5.0;
	}
	//위쪽 방향키
	else if (key == GLUT_KEY_UP)
	{
		//스케일을 증가시켜, 줌인을 구현
		if (scale < 3)
			scale += 0.1f;
	}
	//아래쪽 방향키
	else if (key == GLUT_KEY_DOWN)
	{
		//스케일을 감소시켜, 줌인을 구현. 최소값은 0.1
		if (scale > 0.1)
			scale -= 0.1f;
	}

	glutPostRedisplay();
}


마우스 이벤트

//마우스 이벤트
void mouse(int button, int state, int x, int y)
{
	if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {

		// 클릭한 위치를 정규화한다.
		GLfloat normalizedX = (2.0 * x) / glutGet(GLUT_WINDOW_WIDTH) - 1.0;
		GLfloat normalizedY = 1.0 - (2.0 * y) / glutGet(GLUT_WINDOW_HEIGHT);
		GLfloat normalizedZ = 0.0; 

		//계산한 클릭 위치 좌표를 clickedPosition에 저장
		clickedPosition[0] = normalizedX;
		clickedPosition[1] = normalizedY;
		clickedPosition[2] = normalizedZ;

		// 클릭한 위치와 태양 사이의 거리 계산
		GLfloat distance = sqrt(pow(sunPosition[0] - clickedPosition[0], 2) +
			pow(sunPosition[1] - clickedPosition[1], 2) +
			pow(sunPosition[2] - clickedPosition[2], 2));
		printf("Distance sun-planet: %.2f\n", distance);
		

		//태양의 색 변경
		if (distance >= 0 && distance < 0.1)
		{
			//변경되는 rgb값은 랜텀으로 생성되는 0~1사이의 값을 사용
			sun_color[0] = (GLfloat)rand() / RAND_MAX;
			sun_color[1] = (GLfloat)rand() / RAND_MAX;
			sun_color[2] = (GLfloat)rand() / RAND_MAX;
		}
		//수성의 색 변경
		else if (distance >= 0.1&& distance < 0.2)
		{
			mercury_color[0] = (GLfloat)rand() / RAND_MAX;
			mercury_color[1] = (GLfloat)rand() / RAND_MAX;
			mercury_color[2] = (GLfloat)rand() / RAND_MAX;
		}
		//금성의 색 변경
		else if (distance >= 0.20 && distance < 0.3)
		{
			venus_color[0] = (GLfloat)rand() / RAND_MAX;
			venus_color[1] = (GLfloat)rand() / RAND_MAX;
			venus_color[2] = (GLfloat)rand() / RAND_MAX;
		}
		//지구의 색 변경
		else if (distance >= 0.3 && distance < 0.4)
		{
			earth_color[0] = (GLfloat)rand() / RAND_MAX;
			earth_color[1] = (GLfloat)rand() / RAND_MAX;
			earth_color[2] = (GLfloat)rand() / RAND_MAX;
		}
		//화성의 색 변경
		else if (distance >= 0.4 && distance < 0.5)
		{
			mars_color[0] = (GLfloat)rand() / RAND_MAX;
			mars_color[1] = (GLfloat)rand() / RAND_MAX;
			mars_color[2] = (GLfloat)rand() / RAND_MAX;
		}
		//목성의 색 변경
		else if (distance >= 0.55&& distance < 0.65)
		{
			jupyter_color[0] = (GLfloat)rand() / RAND_MAX;
			jupyter_color[1] = (GLfloat)rand() / RAND_MAX;
			jupyter_color[2] = (GLfloat)rand() / RAND_MAX;
		}
		//토성의 색 변경
		else if (distance >= 0.65 && distance < 0.8)
		{
			saturn_color[0] = (GLfloat)rand() / RAND_MAX;
			saturn_color[1] = (GLfloat)rand() / RAND_MAX;
			saturn_color[2] = (GLfloat)rand() / RAND_MAX;
		}
		//천왕성의 색 변경
		else if (distance >= 0.8 && distance < 0.9)
		{
			uranus_color[0] = (GLfloat)rand() / RAND_MAX;
			uranus_color[1] = (GLfloat)rand() / RAND_MAX;
			uranus_color[2] = (GLfloat)rand() / RAND_MAX;
		}
		//해왕성의 색 변경
		else if (distance >= 0.90 && distance < 1.05)
		{
			neptune_color[0] = (GLfloat)rand() / RAND_MAX;
			neptune_color[1] = (GLfloat)rand() / RAND_MAX;
			neptune_color[2] = (GLfloat)rand() / RAND_MAX;
		}

		glutPostRedisplay();
	}
}

시점 변경

void sub_menu_view(int value)
{
	switch (value)
	{
	//VIEW를 선택하였을 때 camPos[] 값을 변경하여 각 선택에 따른 시점을 구현
	case 1:
		camPos[0] = 0.1f;
		camPos[1] = 0.1f;
		camPos[2] = 0.0f;
		printf("TOP VIEW\n");
		break;
	case 2:
		printf("FRONT VIEW\n");
		camPos[0] = 0.0f;
		camPos[1] = 0.0f;
		camPos[2] = 0.0f;
		break;
	case 3:
		camPos[0] = 0.1f;
		camPos[1] = 0.1f;
		camPos[2] = -5.0f;
		printf("LEFT VIEW\n");
		break;
	case 4:
		//camPos[]값을 랜덤으로 생성 -> 랜덤한 시점의 view
		printf("RANDOM VIEW\n");
		srand(time(NULL));

		for (int i = 0; i < 3; i++)
		{
			camPos[i] = ((double)rand() / RAND_MAX) * 2.0 - 1.0;

		}
		printf("%f %f %f\n", camPos[0], camPos[1], camPos[2]);
		break;
	case 5:
		camPos[0] = 0.1f;
		camPos[1] = 0.1f;
		camPos[2] = 0.1f;
		printf("INITIAL VIEW\n");
		break;

	}
	glutPostRedisplay();
}


profile
멋진 회오리 감자가 되는 그날까지 https://monicx.tistory.com/

0개의 댓글