- 배경색은 짙은 회색으로 정하고, 사각형은 랜덤한 색으로 그린다.
- 마우스를 클릭하는 곳이 중심이 되어 사각형을 그린다.
- 키보드 입력:
- a: 현재 그려진 사각형이 튕겨진다.
- s: 튕기기 애니메이션이 멈춘다.
glm::vec3형식으로 r,g,b 변수3개를 한꺼번에 관리한다.
const glm::vec3 background_rgb = glm::vec3(0.1, 0.1, 0.1);
glm::vec3 rect_rgb = glm::vec3((GLclampf)dist(eng), (GLclampf)dist(eng), (GLclampf)dist(eng));
glColor3f로 사각형의 색상을 바꾼다.
glRectf는 사각형을 그리는 함수로 인수는 좌하단, 우상단 좌표이다.
glClearColor(background_rgb.x, background_rgb.y, background_rgb.z, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(rect_rgb.x, rect_rgb.y, rect_rgb.z);
glRectf(GetRectCorner().x, GetRectCorner().y, GetRectCorner().z, GetRectCorner().w);
Window 좌표를 OpenGL 좌표로 변환하기
Window 좌표에서 x 범위 400 ~ 800
은 0 ~ 1
로 변환되어야 한다.
Window 좌표에서 y 범위 400 ~ 0
은 0 ~ 1
로 변환되어야 한다.
GLfloat half_w = WIN_W / 2.0f;
mx = (x - half_w) / half_w;
my = (half_w - y) / half_w;
타이머 함수로 사각형이 움직이고 벽에 닿으면 튕기도록 구현한다.
void Timer(int value)
{
if (GetRectCorner().w >= 1.0f) direction = 2;
else if (GetRectCorner().z >= 1.0f) direction = 3;
else if (GetRectCorner().y <= -1.0f) direction = 4;
else if (GetRectCorner().x <= -1.0f) direction = 1;
if (direction == 1) {
mx += 0.01f;
my += 0.02f;
}
else if (direction == 2) {
mx += 0.02f;
my -= 0.01f;
}
else if (direction == 3) {
mx -= 0.01f;
my -= 0.02f;
}
else if (direction == 4) {
mx -= 0.02f;
my += 0.01f;
}
glutPostRedisplay(); // 화면 재 출력
if (IsTimerAlive)
glutTimerFunc(100, Timer, 1);
}
case 'a':
IsTimerAlive = true;
glutTimerFunc(100, Timer, 1);
break;
case 's':
IsTimerAlive = false;
break;
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <GL/freeglut_ext.h>
#include <glm/glm.hpp>
#include <glm/ext.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <iostream>
#include <random>
using namespace std;
random_device seeder;
const auto seed = seeder.entropy() ? seeder() : time(nullptr);
mt19937 eng(static_cast<mt19937::result_type>(seed));
uniform_real_distribution<double> dist(0.0f, 1.0f);
const int WIN_X = 10, WIN_Y = 10;
const int WIN_W = 800, WIN_H = 800;
const double RECT_WH = 0.4f;
const double HALFRECT_WH = RECT_WH / 2.0f;
const glm::vec3 background_rgb = glm::vec3(0.1, 0.1, 0.1);
glm::vec3 rect_rgb = glm::vec3((GLclampf)dist(eng), (GLclampf)dist(eng), (GLclampf)dist(eng));
bool IsTimerAlive = true;
int direction = 1;
GLfloat mx = 0.0f;
GLfloat my = 0.0f;
glm::vec4 GetRectCorner()
{
return glm::vec4(mx - HALFRECT_WH, my - HALFRECT_WH, mx + HALFRECT_WH, my + HALFRECT_WH);
}
//--- 콜백 함수: 그리기 콜백 함수
GLvoid drawScene()
{
glClearColor(background_rgb.x, background_rgb.y, background_rgb.z, 1.0f); // 바탕색을 설정
glClear(GL_COLOR_BUFFER_BIT); // 설정된 색으로 전체를 칠하기
glColor3f(rect_rgb.x, rect_rgb.y, rect_rgb.z);
glRectf(GetRectCorner().x, GetRectCorner().y, GetRectCorner().z, GetRectCorner().w);
glutSwapBuffers(); // 화면에 출력하기
}
//--- 콜백 함수: 다시 그리기 콜백 함수
GLvoid Reshape(int w, int h)
{
glViewport(0, 0, w, h);
}
void Timer(int value)
{
if (GetRectCorner().w >= 1.0f) direction = 2;
else if (GetRectCorner().z >= 1.0f) direction = 3;
else if (GetRectCorner().y <= -1.0f) direction = 4;
else if (GetRectCorner().x <= -1.0f) direction = 1;
if (direction == 1) {
mx += 0.01f;
my += 0.02f;
}
else if (direction == 2) {
mx += 0.02f;
my -= 0.01f;
}
else if (direction == 3) {
mx -= 0.01f;
my -= 0.02f;
}
else if (direction == 4) {
mx -= 0.02f;
my += 0.01f;
}
glutPostRedisplay(); // 화면 재 출력
if (IsTimerAlive)
glutTimerFunc(100, Timer, 1);
}
GLvoid Keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 'a':
IsTimerAlive = true;
glutTimerFunc(100, Timer, 1);
break;
case 's':
IsTimerAlive = false;
break;
}
glutPostRedisplay(); //--- 배경색이 바뀔때마다 출력 콜백함수를 호출하여 화면을 refresh 한다
}
void Mouse(int button, int state, int x, int y)
{
GLfloat half_w = WIN_W / 2.0f;
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
mx = (x - half_w) / half_w;
my = (half_w - y) / half_w;
}
glutPostRedisplay();
}
int main(int argc, char** argv)
{
//윈도우 생성
glutInit(&argc, argv); // glut 초기화
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); // 디스플레이 모드 설정
glutInitWindowPosition(WIN_X, WIN_Y); // 윈도우의 위치 지정
glutInitWindowSize(WIN_W, WIN_H); // 윈도우의 크기 지정
glutCreateWindow("Example1"); // 윈도우 생성(윈도우 이름)
//GLEW 초기화하기
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
{
std::cerr << "Unable to initialize GLEW" << std::endl;
exit(EXIT_FAILURE);
}
else
std::cout << "GLEW Initialized\n";
glutDisplayFunc(drawScene); // 출력 함수의 지정
glutReshapeFunc(Reshape); // 다시 그리기 함수 지정
glutKeyboardFunc(Keyboard);
glutMouseFunc(Mouse);
glutMainLoop(); // 이벤트 처리 시작
}