OPenGL 변수타입GLbyte - 8비트 정수
GLshort - 16비트 정수
GLint, GLsizei - 32비트 정수
GLfloat, GLclampf - 32비트 실수
GLdouble, GLclampd - 64비트 실수
GLubyte, GLbollean - 8비트 부호없는 정수
GLushort - 16비트 부호없는 정수
GLuint, GLenum, GLbitfield - 32비트 부호없는 정수
SIMPLE source code --
simple.exe#include <OpenGL.h>
void RenderScene(void) // 장면 랜더링 시작
{
glClear(GL_COLOR_BUFFER_BIT); // 현재 색상을 사용하여 화면을 지운다.
/* 색상 버퍼 지우기, glCear함수는 특정한 버퍼나 버퍼조합의 내용을 지우는 기능*/
glFlush(); // 드로잉 명령을 전달한다.
/* 큐 내용의 실행, 지금까지 실행되지 않은 모든 OpenGL명령을 실행하도록 함, 이 프로그램에서는 glClear함수만이 해당*/
}
void SetupRC(void) // 랜더링 상태 설정
{
glClearColor(0.0f,0.0f,1.0f,1.0f);
/*OpenGL 그래픽 호출, 창을 지우는데 사용할 색상을 지정하는 함수
프로토타입 : glClearColor(GLclampf 적색, GLclampf 녹색, GLclampf 청색, GLclampf 알파값);*/
}
void main() // 메인 프로그램 시작
{
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
/* 출력모드, GLUT_SINGLE 플래그는 싱글 버퍼 창을 사용할것임을 의미, GLUT_RGB는 RGBA 색상 모드를 사용할 것임을 각각 의미*/
glutCreateWindow("Simple");
/*OPenGL 창만들기 , Simple이란 인자는 창의 제목 표시줄에 출력될 타이틀)*/
glutDisplayFunc(RenderScene);
/*콜백출력, 전에 선언된 RenderScene 함수를 출력 콜백함수로 만드는 역할, 여기서 지정된 함수를 호출 즉 창이 처음으로 출력될 때나 창의 크기가 변경도리 때, 최소화되었다가 다시 등장할 때 이 함수가 호출*/
SetupRC();
/* 컨텍스트 설정, 랜더링이 이루어지기 전에 필요한 OPenGL 초기화가 진행됨
glutMainLoop();
/*프로그램 시작, GLUT 프레임웍을 실행하는 기능, 화면출력에 대한 콜백과 다른 함수들을 정의, 즉 이 함수는 프로그램이 종료될 때까지 운영체제에 관련된 메세지, 키, 입력등을 처리하는 것, GLUT의 일을 마무리한다*/
}
*싱글버퍼창 : 모든 드로잉 명령이 출력 창에서 진행됨을 뜻함 / 더블 버퍼창 : 드로잉 명령이 오프 스크린 버퍼에서 실행된 후, 출력창으로 옮겨지는 방식(주로 에니메이션 효과)
*RGBA 색상모드 : 적색 녹색 청색 요소를 사용하여 색상을 지정
*색상 인덱스 모드 : 주어진 색상 팔레트에서 원하는 색상의 인덱스를 지정
OpenGL로 도형(사각형) 그리기 -- glrect.exe
#include <OpenGL.h>
void RenderScene(void) // 장면 랜더링 시작
{
glClear(GL_COLOR_BUFFER_BIT); // 선택된 색상으로 화면을 지움
glColor3f(1.0f, 0.0f, 0.0f); // 드로잉 색상을 적색으로 설정, 알파값을 필요없다.
glRectf(-25.0f, 25.0f, 25.0f, -25.0f);// 현재 드로잉 색상으로 사각형을 그림
/* (x1, y1, x2, y2) 즉 사각형의 좌측상단 xy좌표 두개, 우측하단 xy좌표 두개, 이 함수는 z=0인 평면에 사각형을 그린다.*/
glFlush(); // 드로잉 명령 실행
}
void SetupRC(void) // 랜더링 상태 설정
{
glClearColor(0.0f,0.0f,1.0f,1.0f); // 지우는 색상을 청색으로 설정
}
void ChangeSize(GLsizei w, GLsize h) // 창의 크기가 변할 때 GLUT에 의해 호출되는 부분
/* 창의 크기가 변하면 뷰포트와 클리핑 영역 역시 다시 설정되어야 한다.*/
/* ChangeSize 함수는 새로운 창의 너비와 높이를 받아 좌표계와 화면의 좌표의 맵핑에 사용, 이때 glViewport와 glOrtho라는 두개의 OpenGL함수가 쓰인다*/
{
GLfloat aspectRatio;
if(h==0) //0으로 나누지 않도록 함
h==1;
glViewport(0,0,w,h); //뷰포트를 창의 크기에 맞게 설정
/*(x,y,너비,높이), xy인자는 뷰포트의 좌측 하단 좌표, 대개 0으로 설정*/
glMatrixMode(GL_PROJECTION); // 좌표계 초기화, 투영을 위한 행렬변환
glLoadIdentity();
/* 행렬처리가 이루어지기 전에 좌표계를 초기화, glOrtho의 작동방식이 새로운 클리핑 영역을 만드는 것이 아니라 기존의 클리핑 영역과 행렬을 곱한값을 새로운 클리핑영역으로 지정하기때문*/
aspectRatio = (GLfloat)w / (GLfloat)h; // 클리핑 영역 설정/ 직교투영방식(left, right, bottom, top, near, far 순)
/*left와 right는 x축의 최소값과 최대값, bottom과top은 y축의 최소값과 최대값, near과 far는 z축의 최소최대값*/
if(w<=h)
glOrtho (-100.0, 100.0, -100 / aspectRatio, 100.0 / aspectRatio, 1.0, -1.0);
else
glOrtho (-100.0 * aspectRatio, 100.0 * aspectRatio, -100.0, 100.0, 1.0, -1.0); // 정사각형의 모양을 유지
/* 클리핑영역(눈에 보이는 좌표공간)의 왼쪽은 항상 x=-100으로 유지되며, 창의 너비가 높이보다 크지 않다면 오른쪽은 100까지 확장되고, 그 수치는 창의 종횡비에 따라 결정된다. 마찬가지로 하단 부분은 y=-100으로 맞춰지고, 창의 높이가 너비보다 크지 않다면 100까지 확장된다. 물론 이 경우에도 종횡비에 맞추어 높이가 결정된다. 이와같은 방식으로 창의 모양에 관계없이 200X200 크기의 정사각형을 유지하고, 중앙의 좌표는 0,0으로 유지한다.*/
glMatrixMode(GL_MODELVIEW); // 모든 변환 과정이 우리가 그리는 것에 영향을 미치도록 설정하는 부분
glLoadIdentity();
}
void main() // 메인 프로그램 시작
{
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutCreateWindow("GLRect");
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
/*창의 크기가 변할 때마다 GLUT라이브러리가 호출할 콜백을 등록할 수 있다. 즉 창의 크기가 변할 때마다 실행된다.*/
SetupRC();
glutMainLoop();
}
움직이는 사각형 -- bounce.exe#include <OpenGL.h>
GLfloat x1 = 0.0f;
GLfloat y1 = 0.0f;
GLfloat rsize=25; // 사각형의 초기 위치와 크기
GLfloat xstep = 1.0f;
GLfloat ystep = 1.0f; // x와 y 방향의 이동속도(한번 이동당 픽셀 수)
GLfloat windowWidth;
GLfloat windowHeight; // 창의 크기 변화를 감지한다.
void RenderScene(void) // 장면 렌더링 시작
{
glClear(GL_COLOR_BUFFER_BIT); // 지정된 색상으로 창의 내용을 지운다.
glColor(1.0f, 0.0f, 0.0f); // 적색으로 지정
glRect(x1, y1, x1 + rsize, y1 - rsize); // 현재 드로잉 색상으로 내부가 채워진 사각형 그림
glutSwapBuffers(); // 드로잉 명령 실행, 버퍼를 교체
}
void TimerFunction(int value)
/*창의 크기가 변하거나 이동하지 않은 상태일 때 GLUT에 의해 호출되는 부분*/
{
if(x > windowWidth-rsize || x < -windowWidth)
xstep = -xstep; // 왼쪽이나 오른쪽 경계에 부딫히면 방향을 바꾼다
if(y > windowHeight || y < -windowHeight + rsize)
ystep = -ystep; // 상단이나 하단 경계에 부딫히면 방향을 바꾼다.
x += xstep;
y += ystep; // 사각형의 이동
if(x > (windowWidth-rsize + xstep))
x = windowWidth-rsize-1;
else if(x < -(windowWidth + xstep))
x = -windowWidth -1;
if(y > (windowHeight + ystep))
y = windowHeight-1;
else if(y < -(windowHeight - rsize + ystep))
y = -windowHeight + rsize - 1;
// 사각형이 경계를 벗어났는지를 검사한다
// 사각형이 경계 근처에 있을때 사용자가 창의 경계를 줄이는 등의 요인에 의해
// 현재 사각형의 위치가 클리핑 영역 외부에 있는 경우를 감지하는 것
glutPostRedisplay(); // 새로운 좌표로 장면을 다시 그린다.
glutTimerFunc(33,TimerFunction, 1);
}
}
void SetupRC(void) // 랜더링 상태 설정
{
glClearColor(0.0f,0.0f,1.0f,1.0f); // 화면을 지우는 색상을 청색으로 설정
}
void ChangeSize(GLsizei w, GLsizei h)
/*창의 크기가 변할 때 GLUT 라이브러리에 의해 호출되는 부분*/
{
GLfloat aspectRatio;
if(h == 0) // 0으로 나누는 것을 막는다
h = 1;
glViewport(0, 0, w, h); // 뷰포트의 설정
glMatrixMode(GL_PROJECTION); // 좌표계의 초기화
glLoadIdentity();
aspectRatio = (GLfloat)w / (GLfloat)h; // 클리핑 영역 설정
if (w <= h)
{
windowWidth = 100;
windowHeight = 100 / aspectRatio;
glOrtho (-100.0, 100.0, -windowHeight, windowHeight, 1.0, -1.0);
}
else
{
windowWidth = 100 * aspectRatio;
windowHeight = 100;
glOrtho (-windowWidth, windowWidth, -100.0, 100.0, 1.0, -1.0);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void main(void) // 메인 프로그램 시작
{
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); // 더블 버퍼링
glutInitWindowSize(800,600);
glutCreateWindow("Bounce");
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
glutTimerFunc(33, TimerFunction, 1);
SetupRC();
glutMainLoop();
}
/*더블 버퍼링의 목적은 크게 두가지이다. 첫번째는 복잡한 이미지를 출력할 때 렌더링 과정에 시간이 걸릴 경우 렌더링 중간에 화면의 이미지가 조금씩 완성되어 가는 과정을 보여주지 않고 간접적으로 그려두었다가 한번에 출력할 수 있게 하기 위해서이다. 이럴 경우 사용자는 중간단계의 이미지를 보지 못하고 전체 이미지가 완성된 후에 보게 된다. 두번째 목적은 에니메이션이다. 에니메이션의 각 프레임을 오프 스크린 버퍼에서 그려두었다가 빠르게 프레임을 바꾸어가며 에니메이션 효과를 내는 것이다.*/
glutInitDisplayMode(GLUT_DOBBLE | GLUT_RGB);
RenderScene함수의 끝부분도 바뀌었다.
...
glutSwapBuffer();
}
오프 스크린 버퍼가 교체되는 과정으로 인해 그 동안의 드로잉 결과가 출력되므로, 간접적인 glFlush효과가 있어 glFlush함수는 여기서 필요없다.