코코아팹은 누구나 창의적 아이디어를 현실로 만들어 낼 수 있도록
만들고, 공유하고, 배울 수 있는 터전이
되고자 합니다.
아이디와 비밀번호를 잊으셨나요?아이디 / 비밀번호 찾기
코코아팹 회원이 아니신가요? 회원가입
2015-12-19 23:30:54
#include<GLU.h>
#include<glut.h>
#include<GL.h>
#include<glaux.h>
#include<stdlib.h>
#include<math.h>
#include<string>
#define PI 3.14159265359
void display();
void init();
void drawChar();
void drawSphere();
float randomDouble(float a, float b);
void reshape(int w, int h);
void keyboard(unsigned char key, int x, int y);
void doKeyboard(int key, int x, int y);
GLfloat angle_1, angle_2, angle_3, angle_4, angle_5, angle_6 = 0.0;
GLfloat characterX = 0.0, characterY = 0.0, characterZ = -20.0;
GLfloat Cambient[10][4];
float ro[] = { 0.3, 0.4, 0.24, 0.33, 0.21, 0.38, 0.15, 0.22, 0.38, 0.29 };
int count = 0;
unsigned int ids[1];
AUX_RGBImageRec *tex[1];
struct cookie{
GLfloat x, y, z;
int happy;
};
struct cookie cookie[10];
void main(int argc, char** argv){
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(1200, 800);
glutCreateWindow("201302389_hyungyeon_term");
glClearColor(0, 0, 0, 1);
tex[0] = auxDIBImageLoad("flower.bmp");
glGenTextures(0, &ids[0]);//texture id를 생성
glBindTexture(GL_TEXTURE_2D, ids[0]);
//texture 이름(id)을 texture 데이터(2d texture사용)와 연결한다.
/*texture의 filtering방식 설정*/
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//2D texture,확대필터,양방향 선형 필터링 사용
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//2D texture,축소필터,양방향 선형 필터링 사용
//양방향 선형 필터링이란 텍셀에서 인접한 2*2점을 샘플링하여 가중치 평균값을 구함
glTexImage2D(GL_TEXTURE_2D, 0, 3, tex[0]->sizeX, tex[0]->sizeY, 0, GL_RGB,
GL_UNSIGNED_BYTE, tex[0]->data);//2D 이미지를 texture으로 메모리에 load
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
//텍스쳐가 입혀질때 텍스쳐의 색상과 기존픽셀색상과의 관계를 설정
//최종 color는 glColor, texture가 영향을 준다
init();
glutIdleFunc(display);
glutDisplayFunc(display);//display 함수 호출
glutKeyboardFunc(keyboard);//키보드에서 문자를 눌렀을 때 실행할 함수
glutSpecialFunc(doKeyboard);//키보드에서 special key(화살표 키)를 눌렀을 때 실행할 함수
glutReshapeFunc(reshape);
glutMainLoop();
}
void doKeyboard(int key, int x, int y){
switch (key) {
case GLUT_KEY_UP: //키보드 방향키 위쪽 누를시
characterZ += 1.0; //캐릭터의 위치를 Z축방향으로 +1.0만큼 이동
break;
case GLUT_KEY_LEFT: //키보드 방향키 왼쪽 누를시
characterX += 1.0; //캐릭터의 위치를 X축방향으로 +1.0만큼 이동
break;
case GLUT_KEY_RIGHT: //키보드 방향키 오른쪽 누를시
characterX -= 1.0; //캐릭터의 위치를 X축방향으로 -1.0만큼 이동
break;
case GLUT_KEY_DOWN: //키보드 방향키 아래쪽 누를시
characterZ -= 1.0; //캐릭터의 위치를 Z축방향으로 +1.0만큼 이동
break;
}
glutPostRedisplay(); // 다음 디스플레이 콜백이 실행될 때 바뀐 변수 위치로 물체가 보임
}
void keyboard(unsigned char key, int x, int y){
switch (key) {
case 'n': //n를 누르면 카메라를 Y축 방향으로 이동시킨다.
characterY += 0.5; //물체가 가까이 오는 것 처럼 보이도록 한다.
break;
case 'b': //b를 누르면 카메라를 -Y축 방향으로 이동시킨다.
characterY -= 0.5; //물체가 멀리 떨어지는 것 처럼 보이도록 한다.
break;
}
glutPostRedisplay();
}
void init(){//구 초기화
for (int i = 0; i < 10; i++){//각 구의 초기 위치 설정
cookie[i].x = rand() % 60 - 30;
//cookie[i].y = 0;
cookie[i].y = rand() % 15 - 7;
cookie[i].z = rand() % 30 - 15;
cookie[i].happy = 1;
}
for (int i = 0; i < 10; i++){//각 구의 색상 값 설정
for (int j = 0; j < 4; j++){
Cambient[i][j] = rand() / (double)RAND_MAX + 0.1;
}
}
}
void drawChar(){//캐릭터의 속성
GLfloat ambient[] = { 0.5, 0.5, 0.5, 0 };
GLfloat plane_coef_s[] = { 1.0, 0.0, 0.0, 1.0 };
GLfloat plane_coef_t[] = { 0.0, 1.0, 0.0, 1.0 };
glEnable(GL_TEXTURE_2D);
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, ids[0]);
//ids 배열 0번째에 저장되어 있는 texture을 사용하여 바인딩
glEnable(GL_TEXTURE_GEN_S);
/* glTexGen : texture 좌표 생성을 제어
glTexGeni(GLenum coord, GLenum pname, GLint param)
coord : texture 좌표를 지정한다.
pname : texture 좌표계 함수의 이름을 지정한다.
param : texture 새성 파라미터 값 하나를 지정한다.
param이 GL_OBJECT_LINEAR인 경우 물체를 이동함에 따라
물체면의 texture가 바뀐다 */
/* glTexGen : texture 좌표 생성을 제어
glTexGenfv(GLenum coord, GLenum pname, const GLfloat params)
coord : texture 좌표를 지정한다.
pname : texture 좌표계 함수의 이름이나 함수의 파라미터를 지정한다.
params : texture 생성 파라미터들의 배열의 포인터를 지정한다. */
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(GL_S, GL_OBJECT_PLANE, plane_coef_s);
glEnable(GL_TEXTURE_GEN_T);//자동으로 texture generate
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(GL_T, GL_OBJECT_PLANE, plane_coef_t);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
glTranslatef(characterX, characterY, characterZ);
glutSolidSphere(1.5, 50, 50);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glPopMatrix();
}
void drawSphere(){
for (int i = 0; i < 10; i++){
if (sqrt(pow(characterX - cookie[i].x*cos(PI*ro[i]), 2) + pow(characterY - cookie[i].y, 2) + pow(characterZ - cookie[i].z*sin(PI*ro[i]), 2)) < 3){
//캐릭터가 구와 충돌했을때
//구가 사라지고 score + 1
cookie[i].happy = 0;
}
}
for (int i = 0; i < 10; i++){//구 10개 그리기
if (cookie[i].happy == 1){
glPushMatrix();
glTranslatef(cookie[i].x * cos(PI*ro[i]), cookie[i].y, cookie[i].z * sin(PI*ro[i]));
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, Cambient[i]);
glutSolidSphere(1.5, 50, 50);
glPopMatrix();
}
}
for (int i = 0; i < 10; i++){//구 회전 삼각함수의 세타 값
ro[i] += 0.001;
}
count = 0;
for (int i = 0; i < 10; i++){//구를 먹었을 때 먹은 구의 개수
if (cookie[i].happy == 0){
count++;
}
}
if (count == 10){//모두 먹었을 때 : 게임 성공
glutIdleFunc(false);
/*text 출력*/
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, 500, 0, 500);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
GLfloat ambientSuccess[] = { 1.0, 0.0, 0.0, 0.0 };
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambientSuccess);
glColor3f(0.0f, 1.0f, 0.0f);//needs to be called before RasterPos
glRasterPos2i(230, 250);//위치
std::string s = "SUCCESS";
void * font = GLUT_BITMAP_TIMES_ROMAN_24;//폰트
for (std::string::iterator i = s.begin(); i != s.end(); ++i)
{
char c = *i;
glutBitmapCharacter(font, c);
}
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glEnable(GL_TEXTURE_2D);
}
}
void display(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//프레임 버퍼를 초기화
glMatrixMode(GL_MODELVIEW);//모델뷰 행렬
glLoadIdentity();//행렬 초기화
gluLookAt(0, 60, 0, 0, 0, 0, 0, 0, 1);//관측변환 지정
glEnable(GL_LIGHTING);//조명 기능 ON
glEnable(GL_LIGHT0);//첫번째 조명 사용
glEnable(GL_LIGHT1);
glEnable(GL_LIGHT2);
glEnable(GL_LIGHT3);
glEnable(GL_NORMALIZE);//자동으로 unit normal vector 구함
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
GLfloat ambient0[] = { 1.0, 0.0, 0.0, 1.0 };//주변광의 세기(r,g,b,a)
GLfloat diffuse0[] = { 1.0, 0.0, 0.0, 1.0 };//분산광의 세기(난반사)
GLfloat specular0[] = { 1.0, 0.0, 0.0, 1.0 };//반사광의 세기
GLfloat light_pos0[] = { 0, 0, -30, 1.0 };//조명(x,y,z,w)의 위치S
glLightfv(GL_LIGHT0, GL_POSITION, light_pos0);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient0);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse0);
glLightfv(GL_LIGHT0, GL_SPECULAR, specular0);
GLfloat ambient1[] = { 0.0, 1.0, 0.0, 1.0 };//주변광의 세기(r,g,b,a)
GLfloat diffuse1[] = { 0.0, 1.0, 0.0, 1.0 };//분산광의 세기(난반사)
GLfloat specular1[] = { 0.0, 1.0, 0.0, 1.0 };//반사광의 세기
GLfloat light_pos1[] = { 0, 0, 20, 1.0 };//조명(x,y,z,w)의 위치S
glLightfv(GL_LIGHT1, GL_POSITION, light_pos1);
glLightfv(GL_LIGHT1, GL_AMBIENT, ambient1);
glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse1);
glLightfv(GL_LIGHT1, GL_SPECULAR, specular1);
GLfloat ambient2[] = { 0.0, 0.0, 1.0, 1.0 };//주변광의 세기(r,g,b,a)
GLfloat diffuse2[] = { 0.0, 0.0, 1.0, 1.0 };//분산광의 세기(난반사)
GLfloat specular2[] = { 0.0, 0.0, 1.0, 1.0 };//반사광의 세기
GLfloat light_pos2[] = { -30, 0, 0, 1.0 };//조명(x,y,z,w)의 위치S
glLightfv(GL_LIGHT2, GL_POSITION, light_pos2);
glLightfv(GL_LIGHT2, GL_AMBIENT, ambient2);
glLightfv(GL_LIGHT2, GL_DIFFUSE, diffuse2);
glLightfv(GL_LIGHT2, GL_SPECULAR, specular2);
GLfloat ambient3[] = { 0.0, 0.0, 1.0, 1.0 };//주변광의 세기(r,g,b,a)
GLfloat diffuse3[] = { 0.0, 0.0, 1.0, 1.0 };//분산광의 세기(난반사)
GLfloat specular3[] = { 0.0, 0.0, 1.0, 1.0 };//반사광의 세기
GLfloat light_pos3[] = { 30, 0, 0, 1.0 };//조명(x,y,z,w)의 위치S
glLightfv(GL_LIGHT3, GL_POSITION, light_pos3);
glLightfv(GL_LIGHT3, GL_AMBIENT, ambient3);
glLightfv(GL_LIGHT3, GL_DIFFUSE, diffuse3);
glLightfv(GL_LIGHT3, GL_SPECULAR, specular3);
drawChar();
drawSphere();
/*if (count == 9){
GLfloat ambientSuccess[] = { 0.1, 0.8, 0.2, 0.0 };
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambientSuccess);
glBegin(GL_POLYGON);
glVertex3f(-10, 0, 10);
glVertex3f(10, 0, 10);
glVertex3f(10, 0, 0);
glVertex3f(-10, 0, 0);
glEnd();
}*/
glFlush();
}
void reshape(int w, int h){
float ratio = w / (float)h;
glViewport(0, 0, w, h);
//창의 크기를 변경시켜도 display 함수에서 그린 것의 모양이 변하지 않음
glMatrixMode(GL_PROJECTION);//투영 행렬
glLoadIdentity();//행렬 초기화
gluPerspective(45, ratio, 10, 100);//원근 투영
}
이슬기