전체 코드 (주석 포함)
// HelloGL.cpp : 이 파일에는 'main' 함수가 포함됩니다. 거기서 프로그램 실행이 시작되고 종료됩니다.
#include <iostream>
#include ".\include\GL\freeglut.h" // Freeglut 헤더 포함
// 전역 변수: 윈도우의 초기 가로, 세로 크기
int Width = 600, Height = 600;
// 콜백 함수 선언
void Render(); // 화면을 그리는 함수
void Reshape(int w, int h); // 창 크기가 바뀔 때 호출되는 함수
int main(int argc, char **argv)
{
// Freeglut 초기화
glutInit(&argc, argv);
// 윈도우 크기 설정
glutInitWindowSize(Width, Height);
// 디스플레이 모드 설정: 더블 버퍼링 + RGBA 색상
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
// 윈도우 생성
glutCreateWindow("Hello OpenGL");
// 콜백 함수 등록
glutDisplayFunc(Render); // 화면을 그릴 때 호출될 함수
glutReshapeFunc(Reshape); // 창 크기가 변경될 때 호출될 함수
// 이벤트 루프 진입 (계속해서 콜백 함수들을 처리함)
glutMainLoop();
return 0;
}
void Render()
{
// 배경 색상 설정 (흰색)
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
// 색상 버퍼 초기화 (배경색으로 지움)
glClear(GL_COLOR_BUFFER_BIT);
// 투영 행렬 설정: 관측 공간 지정
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-10.0, 10.0, -10.0, 10.0); // 2D 직교 좌표계 설정
// 모델뷰 행렬 선택 (모델링 좌표계)
glMatrixMode(GL_MODELVIEW);
// 빨간 삼각형 그리기
glColor3d(1.0, 0.0, 0.0); // 빨간색 설정
glBegin(GL_TRIANGLES); // 삼각형 그리기 시작
glVertex2d(-2.0, -1.0); // 첫 번째 꼭짓점
glVertex2d(2.0, -1.0); // 두 번째 꼭짓점
glVertex2d(0.0, 3.0); // 세 번째 꼭짓점
glEnd(); // 그리기 끝
// 파란 삼각형 그리기
glColor3d(0.0, 0.0, 1.0); // 파란색 설정
glBegin(GL_TRIANGLES);
glVertex2d(-2.0, 1.0);
glVertex2d(0.0, -3.0);
glVertex2d(2.0, 1.0);
glEnd();
// 버퍼 교환 (백 버퍼 -> 프론트 버퍼)
glutSwapBuffers();
}
void Reshape(int w, int h)
{
// 뷰포트 설정: 윈도우 전체 영역을 그리기 공간으로 사용
glViewport(0, 0, w, h);
// 전역 변수 업데이트
Width = w;
Height = h;
}
프로그램 구조 이해하기
OpenGL + Freeglut 프로그램은 다음과 같은 단계로 구성됩니다:
- 초기화 – glutInit, glutInitWindowSize, glutInitDisplayMode
- 윈도우 생성 – glutCreateWindow
- 콜백 등록 – glutDisplayFunc, glutReshapeFunc
- 이벤트 루프 진입 – glutMainLoop
- 렌더링 함수에서 도형 그리기 – Render()
더블 버퍼링이란?
더블 버퍼링(Double Buffering)은 깜빡임 없는 부드러운 화면 출력을 위해 사용하는 기법입니다.
- OpenGL에서는 그림을 먼저 백 버퍼(화면 뒤쪽 메모리)에 그립니다.
- 그리기가 끝나면
glutSwapBuffers()
를 호출하여 백 버퍼와 프론트 버퍼(사용자에게 보이는 화면)를 교체합니다. - 이 방식 덕분에 도중에 그려지는 과정이 화면에 드러나지 않고, 완성된 그림만 사용자에게 보여집니다.
비유: 칠판에 그림을 다 그려놓고 한 번에 보여주는 방식! (그리는 도중은 사용자에게 보이지 않음)
초기화와 윈도우 설정
glutInit
: Freeglut 라이브러리를 초기화합니다.glutInitWindowSize
: 생성할 윈도우의 크기를 설정합니다.glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA)
: 더블 버퍼링과 RGBA 색상 모드를 설정합니다.glutCreateWindow("Hello OpenGL")
: 실제 윈도우를 생성하고 타이틀을 설정합니다.
콜백 함수 등록과 이벤트 처리
glutDisplayFunc(Render)
: 화면을 다시 그릴 때 호출될 함수를 등록합니다.glutReshapeFunc(Reshape)
: 창 크기가 바뀔 때 호출될 함수를 등록합니다.
OpenGL은 이벤트 기반으로 동작하며, 이 콜백 함수들은 glutMainLoop 내부에서 자동으로 호출됩니다.
Render 함수 분석: 도형을 그리는 핵심
배경색 설정 및 초기화
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
- 배경을 흰색으로 설정하고, 색상 버퍼를 초기화합니다.
좌표계 설정
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-10.0, 10.0, -10.0, 10.0);
- 카메라 시점(투영 행렬)을 설정하고, 2D 직교 투영 좌표계를 구성합니다.
도형 그리기
glColor3d(1.0, 0.0, 0.0); // 빨간색
// 첫 번째 삼각형
...
glColor3d(0.0, 0.0, 1.0); // 파란색
// 두 번째 삼각형
...
glColor3d
로 색상을 지정한 후,glBegin ~ glEnd
사이에 정점들을 나열하여 삼각형을 그립니다.
버퍼 교환
glutSwapBuffers();
- 더블 버퍼링을 이용하여 백 버퍼에 그린 내용을 프론트 버퍼로 교환합니다.
Reshape 함수 분석: 창 크기 대응
glViewport(0, 0, w, h);
- 창의 크기가 바뀌면 새로운 크기에 맞게 뷰포트를 다시 설정합니다.
- OpenGL 좌표계를 창 크기에 맞게 매핑해주는 중요한 단계입니다.
실습 아이디어
- 색상 바꿔 보기 (예: 초록색
glColor3d(0.0, 1.0, 0.0)
) - 삼각형 위치 바꾸기 (정점 좌표 수정)
- 사각형 등 다른 도형 그리기 (
GL_QUADS
,GL_LINES
등 사용) - 좌표계 범위 변경 (
gluOrtho2D
값 조정)
🔧 예제 1: 사각형 그리기
glColor3d(0.0, 1.0, 0.0); // 초록색
// 초록색 사각형
glBegin(GL_QUADS);
glVertex2d(-4.0, -4.0);
glVertex2d(4.0, -4.0);
glVertex2d(4.0, 4.0);
glVertex2d(-4.0, 4.0);
glEnd();
GL_QUADS
는 네 개의 꼭짓점을 연결해 사각형을 만듭니다.- 중심이 원점인 정사각형을 화면에 그릴 수 있습니다.
🔧 예제 2: 좌표계 범위 변경하기
// Render 함수 내 gluOrtho2D 부분을 다음과 같이 바꿔보세요
gluOrtho2D(-20.0, 20.0, -15.0, 15.0);
- 기존보다 더 넓은 가상 좌표계를 정의합니다.
- 도형이 상대적으로 작게 보이며, 더 많은 공간을 표현할 수 있습니다.
'프로그래밍 > 컴퓨터그래픽스' 카테고리의 다른 글
합성 변환과 해석 (0) | 2025.04.05 |
---|---|
어파인 변환의 해석 (0) | 2025.04.05 |
동차 좌표, 어파인 공간, 어파인 변환: 이동, 회전, 스케일, 밀림 변환 (0) | 2025.04.04 |
OpenGL 기본 출력 객체 속성 정리 (0) | 2025.04.04 |
점, 선, 다각형을 이용한 다양한 도형 그리기 (0) | 2025.04.04 |