wisdiom 아니고 wisdom

[실습 22] 3차원 공튀기기 본문

👩‍💻/OpenGL

[실습 22] 3차원 공튀기기

글로랴 2021. 6. 30. 20:41
#include <stdlib.h>
#include <GL\glut.h>



#define SOLID 0
#define WIRE 1

​

void SetupRC(void);
void DrawScene(void);
void Reshape(int w, int h);
void Keyboard(unsigned char key, int x, int y);
void Mouse(int button, int state, int x, int y);
void MenuFunc(int button);
void TimerFunction(int value);
void Motion(int x, int y);

​

enum { BACK, UP, DOWN, LEFT, RIGHT };

​

typedef struct COLOR
{
 float r;
 float g;
 float b;
} COLOR;

​

typedef struct BALL
{
 int x;
 int y;
 int z;
 int dirX;
 int dirY;
 int dirZ;
 COLOR color;
} BALL;

​

float colorWeight[5] = { 0.0, 0.1, 0.2, 0.3, 0.4 }; //-0.5~0.5

​

int fillway = SOLID;
int angleY = 0;
int speed = 5;
int ballCount = 0;

​

COLOR color[5];

BALL ball[5];

​

int main(int argc, char* argv[])
{
 glutInit(&argc, argv);
 glutInitWindowPosition(300, 100);
 glutInitWindowSize(800, 600);
 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
 glutCreateWindow("컴그_실습22");
 glutDisplayFunc(DrawScene);
 glutReshapeFunc(Reshape);
 glutKeyboardFunc(Keyboard);
 glutMouseFunc(Mouse);
 glutPassiveMotionFunc(Motion);
 glutTimerFunc(50, TimerFunction, 1);
 SetupRC();
 glutMainLoop();

 return 0;
}



void SetupRC(void)
{
 int menu;

 menu = glutCreateMenu(MenuFunc);
 glutAddMenuEntry("SOLID", SOLID);
 glutAddMenuEntry("WIRE", WIRE);
 glutAttachMenu(GLUT_RIGHT_BUTTON);

 glEnable(GL_DEPTH_TEST);
 glShadeModel(GL_FLAT);

 color[BACK].r = 0.4;
 color[BACK].g = 0.7;
 color[BACK].b = 0.3;
 color[UP].r = 0.9;
 color[UP].g = 0.4;
 color[UP].b = 0.3;
 color[DOWN].r = 0.0;
 color[DOWN].g = 0.1;
 color[DOWN].b = 0.9;
 color[LEFT].r = 0.0;
 color[LEFT].g = 1.0;
 color[LEFT].b = 1.0;
 color[RIGHT].r = 1.0;
 color[RIGHT].g = 1.0;
 color[RIGHT].b = 0.0;

 // clear 색상을 검정색으로 설정
 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}

​

void DrawScene(void)
{
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

 glPushMatrix();

 //후
 glBegin(GL_QUADS);
 glColor3f(color[BACK].r, color[BACK].g, color[BACK].b);
 glVertex3f(-100.0, 100.0, -100.0);
 glVertex3f(-100.0, -100.0, -100.0);
 glVertex3f(100.0, -100.0, -100.0);
 glVertex3f(100.0, 100.0, -100.0);
 glEnd();

 //상
 glBegin(GL_QUADS);
 glColor3f(color[UP].r, color[UP].g, color[UP].b);
 glVertex3f(-100.0, 100.0, 100.0);
 glVertex3f(100.0, 100.0, 100.0);
 glVertex3f(100.0, 100.0, -100.0);
 glVertex3f(-100.0, 100.0, -100.0);
 glEnd();

 //하
 glBegin(GL_QUADS);
 glColor3f(color[DOWN].r, color[DOWN].g, color[DOWN].b);
 glVertex3f(-100.0, -100.0, 100.0);
 glVertex3f(-100.0, -100.0, -100.0);
 glVertex3f(100.0, -100.0, -100.0);
 glVertex3f(100.0, -100.0, 100.0);
 glEnd();

 //좌
 glBegin(GL_QUADS);
 glColor3f(color[LEFT].r, color[LEFT].g, color[LEFT].b);
 glVertex3f(-100.0, 100.0, 100.0);
 glVertex3f(-100.0, 100.0, -100.0);
 glVertex3f(-100.0, -100.0, -100.0);
 glVertex3f(-100.0, -100.0, 100.0);
 glEnd();

 //우
 glBegin(GL_QUADS);
 glColor3f(color[RIGHT].r, color[RIGHT].g, color[RIGHT].b);
 glVertex3f(100.0, 100.0, 100.0);
 glVertex3f(100.0, -100.0, 100.0);
 glVertex3f(100.0, -100.0, -100.0);
 glVertex3f(100.0, 100.0, -100.0);
 glEnd();

 for (int i = 0; i < ballCount; i++)
 {
  glPushMatrix();

  glTranslated(ball[i].x, ball[i].y, ball[i].z);
  glColor3f(0.0f, 0.0f, 0.0f);
  (fillway == SOLID) ? glutSolidSphere(5, 10, 10) : glutWireSphere(5, 10, 10);

  glPopMatrix();
 }

 // 지정된 행렬을 반환한다.
 glPopMatrix();

 // 더블 버퍼링으로 그림 그리기 수행
 glutSwapBuffers();
}

​

void Reshape(int w, int h)
{
 // 뷰포트 변환
 glViewport(0, 0, w, h);

 // 투영 행렬 스택 재설정
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();

 gluPerspective(85.0f, w / h, 1.0, 1000.0);

 // 모델 뷰 행렬 스택 재설정
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();

 glTranslated(0.0f, 0.0f, -300.0f);
 glutPostRedisplay();
}

​

void Keyboard(unsigned char key, int x, int y)
{
 switch (key)
 {
 case 'y':
  if (angleY <= 40)
  {
   glRotatef(5.0f, 0.0f, 1.0f, 0.0f);
   angleY += 5;
  }
  break;
 case 'Y':
  if (angleY >= -40)
  {
   glRotatef(-5.0f, 0.0f, 1.0f, 0.0f);
   angleY -= 5;
  }
  break;
 case 'z':
  glTranslatef(0.0f, 0.0f, 10.f);
  break;
 case 'Z':
  glTranslatef(0.0f, 0.0f, -10.0f);
  break;
 case 'B':
  ballCount = 0;
  break;
 default:
  break;
 }

 glutPostRedisplay();
}

​

void MenuFunc(int button)
{
 (button == SOLID) ? fillway = SOLID : fillway = WIRE;
 glutPostRedisplay();
}

void TimerFunction(int value)
{
 for (int i = 0; i < ballCount; i++)
 {
  ball[i].x += ball[i].dirX * speed;
  ball[i].y += ball[i].dirY * speed;
  ball[i].z += ball[i].dirZ * speed;

  //충돌처리할 부분
  if (ball[i].x > 95)
  {
   ball[i].dirX *= -1;
   color[RIGHT].r = (float)(rand() % 255) / 255;
   color[RIGHT].g = (float)(rand() % 255) / 255;
   color[RIGHT].b = (float)(rand() % 255) / 255;
  }
  if (ball[i].y > 95)
  {
   ball[i].dirY *= -1;
   color[UP].r = (float)(rand() % 255) / 255;
   color[UP].g = (float)(rand() % 255) / 255;
   color[UP].b = (float)(rand() % 255) / 255;
  }
  if (ball[i].x < -95)
  {
   ball[i].dirX *= -1;
   color[LEFT].r = (float)(rand() % 255) / 255;
   color[LEFT].g = (float)(rand() % 255) / 255;
   color[LEFT].b = (float)(rand() % 255) / 255;
  }
  if (ball[i].y < -95)
  {
   ball[i].dirY *= -1;
   color[DOWN].r = (float)(rand() % 255) / 255;
   color[DOWN].g = (float)(rand() % 255) / 255;
   color[DOWN].b = (float)(rand() % 255) / 255;
  }
  if (ball[i].z > 95)
  {
   ball[i].dirZ *= -1;
  }
  if (ball[i].z < -95)
  {
   ball[i].dirZ *= -1;
   color[BACK].r = (float)(rand() % 255) / 255;
   color[BACK].g = (float)(rand() % 255) / 255;
   color[BACK].b = (float)(rand() % 255) / 255;
  }
 }
 glutPostRedisplay();
 glutTimerFunc(50, TimerFunction, 1);
}

​

void Mouse(int button, int state, int x, int y)
{
 if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN && ballCount < 5)
 {
  ball[ballCount].x = rand() % 2 ? rand() % 90 : -(rand() % 90);
  ball[ballCount].y = rand() % 2 ? rand() % 90 : -(rand() % 90);
  ball[ballCount].z = rand() % 2 ? rand() % 90 : -(rand() % 90);
  ball[ballCount].dirX = rand() % 2 ? 1 : -1;
  ball[ballCount].dirY = rand() % 2 ? 1 : -1;
  ball[ballCount].dirZ = rand() % 2 ? 1 : -1;
  ballCount++;
 }
}

​

void Motion(int x, int y)
{
 if (x >= 100 && -100 <= y <= 100)
 {
  glRotatef(-1.0f, 0.0f, 0.0f, 1.0f);
 }
 else if (x < 100 && -100 <= y <= 100)
 {
  glRotatef(1.0f, 0.0f, 0.0f, 1.0f);
 }
 else
 {
  ;
 }
} 
반응형
Comments