반응형

freeglut을 설치하고 간단한 OpenGL 예제를 만들어 보자.


http://freeglut.sourceforge.net/ 에서 MSVC용 Prepackaged Release 를 다운 받아 원하는 폴더에 설치 한다.


빈 Console 프로젝트를 만든다.


freeglut 라이브러리의 dll 파일이 있는 폴더를 Environment에 지정 한다.


Include 디렉토리를 지정 한다.


sprintf() 사용을 위해 SDL checks를 No로 바꾼다. Yes로 된 경우 비표준 함수인 sprintf_s()를 써야 한다.


SDL checks: Adds recommended Security Development Lifecycle (SDL) checks. These checks include extra security-relevant warnings as errors, and additional secure code-generation features.


Library 디렉토리를 지정 한다.


외부 라이브러리 사용시 위 사진과 같이 라이브러리 파일들을 추가해야 하지만 freeglut_std.h에 필요한 라이브러리가 모두 추가 되어 있으므로 하지 않아도 된다.



<freeglut_std.h>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#   include <windows.h>
 
/* Windows static library */
#   ifdef FREEGLUT_STATIC
 
#error Static linking is not supported with this build. Please remove the FREEGLUT_STATIC preprocessor directive, or download the source code from http://freeglut.sf.net/ and build against that.
 
/* Windows shared library (DLL) */
#   else
 
#       define FGAPIENTRY __stdcall
#       if defined(FREEGLUT_EXPORTS)
#           define FGAPI __declspec(dllexport)
#       else
#           define FGAPI __declspec(dllimport)
 
            /* Link with Win32 shared freeglut lib */
#           if FREEGLUT_LIB_PRAGMAS
#             pragma comment (lib, "freeglut.lib")
#           endif
 
#       endif
 
#   endif
 
/* Drag in other Windows libraries as required by FreeGLUT */
#   if FREEGLUT_LIB_PRAGMAS
#       pragma comment (lib, "glu32.lib")    /* link OpenGL Utility lib     */
#       pragma comment (lib, "opengl32.lib"/* link Microsoft OpenGL lib   */
#       pragma comment (lib, "gdi32.lib")    /* link Windows GDI lib        */
#       pragma comment (lib, "winmm.lib")    /* link Windows MultiMedia lib */
#       pragma comment (lib, "user32.lib")   /* link Windows user lib       */
#   endif
 
#else
 
/* Non-Windows definition of FGAPI and FGAPIENTRY  */
#        define FGAPI
#        define FGAPIENTRY
 
#endif


windows.h 도 포함 되어 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#include <gl/glut.h>
#include <cstdio>
 
GLfloat locationX = 0.0f, locationY = 0.0f;
const GLfloat step = 0.02f;
const GLfloat size = 0.2f;
int winId;
 
void Menu(int value);
void Keyboard(unsigned char key, int x, int y);
void Special(int key, int x, int y);
void Mouse(int button, int state, int x, int y);
void Display();
 
int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    
    winId = glutCreateWindow("OpenGL");
 
    glutKeyboardFunc(Keyboard);
    glutSpecialFunc(Special);
    glutMouseFunc(Mouse);
 
    // Sub menu
    GLint SubMenu = glutCreateMenu(Menu);
    glutAddMenuEntry("Red"4);
    glutAddMenuEntry("Green"5);
    glutAddMenuEntry("Blue"6);
 
    // Menu
    glutCreateMenu(Menu);
    glutAddMenuEntry("White"1);
    glutAddMenuEntry("Black"2);
    glutAddMenuEntry("Gray"3);
 
    // Add sub menu
    glutAddSubMenu("Triangle Color", SubMenu);
    glutAttachMenu(GLUT_RIGHT_BUTTON);
 
    glutDisplayFunc(Display);
 
    glutMainLoop();
 
    return 0;
}
 
void Menu(int value)
{
    switch (value) {
    case 1:
        glClearColor(1.0f1.0f1.0f1.0f);    // 배경 흰색
 
        break;
    case 2:
        glClearColor(0.0f0.0f0.0f1.0f);    // 배경 검정색
 
        break;
    case 3:
        glClearColor(0.5f0.5f0.5f1.0f);    // 배경 회색
 
        break;
    case 4:
        glColor3f(1.0f0.0f0.0f);            // 삼감형 빨간색
 
        break;
    case 5:
        glColor3f(0.0f1.0f0.0f);            // 삼감형 녹색
 
        break;
    case 6:
        glColor3f(0.0f0.0f1.0f);            // 삼감형 파란색
 
        break;
    default:
 
        break;
    }
 
    glutPostRedisplay();
}
 
void Keyboard(unsigned char key, int x, int y)
{
    switch (key) {
    case 'r':
    case 'R':
        glClearColor(1.0f0.0f0.0f1.0f);    // 배경 빨간색
 
        break;
    case 'g':
    case 'G':
        glClearColor(0.0f1.0f0.0f1.0f);    // 배경 녹색
 
        break;
    case 'b':
    case 'B':
        glClearColor(0.0f0.0f1.0f1.0f);    // 배경 파란색
 
        break;
    case 27:
        glutDestroyWindow(winId);                // ESC키 프로그램 종료
        exit(0);
 
        break;
    default:
 
        break;
    }
 
    glutPostRedisplay();
}
 
void Special(int key, int x, int y)
{
    switch (key) {
    case GLUT_KEY_LEFT:        // step 만큼 x감소
        locationX -= step;
 
        break;
    case GLUT_KEY_RIGHT:    // step 만큼 x증가
        locationX += step;
 
        break;
    case GLUT_KEY_UP:        // step 만큼 y증가
        locationY += step;
 
        break;
    case GLUT_KEY_DOWN:        // step 만큼 y감소
        locationY -= step;
 
        break;
    }
    char title[128= {0,};
    sprintf(title, "Triangle location (%.2f, y=%.2f)", locationX, locationY);
    glutSetWindowTitle(title); // 제목표시줄에 삼각형 좌표 표시
 
    glutPostRedisplay();
}
 
void Mouse(int button, int state, int x, int y)
{
    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
        glColor3f(0.0f1.0f1.0f);    // 삼각형 하늘색
        char title[128= { 0, };
        sprintf(title, "Click (x: %d, y: %d)", x, y);
        glutSetWindowTitle(title); // 제목표시줄에 클릭 좌표 표시
 
        glutPostRedisplay();
    }
    else if (button == GLUT_LEFT_BUTTON && state == GLUT_UP){
        glColor3f(1.0f1.0f0.0f);    // 삼각형 노란색
 
        glutPostRedisplay();
    }
}
 
 
void Display()
{
    glClear(GL_COLOR_BUFFER_BIT);
        
    glBegin(GL_TRIANGLES);
    glVertex2f(locationX, locationY + size);
    glVertex2f(locationX - size, locationY - size);
    glVertex2f(locationX + size, locationY - size);
    glEnd();
 
    glFinish();
}


코드를 입력하고 실행 한다.


오른쪽 버튼을 클릭하면 메뉴가 나온다.


삼각형이 빨간색으로 바뀌었다.


r,g,b, 방향키, ESC키 등을 눌러 본다.


SubSystem을Console에서 Widows로 바꾼다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <gl/glut.h>
 
void Menu(int value)
{
    switch (value) {
    case 1:
        glClearColor(1.0f1.0f1.0f1.0f);
 
        break;
    case 2:
        glClearColor(0.0f0.0f0.0f1.0f);
 
        break;
    case 3:
        glClearColor(0.5f0.5f0.5f1.0f);
 
        break;
    case 4:
        glColor3f(1.0f0.0f0.0f);
 
        break;
    case 5:
        glColor3f(0.0f1.0f0.0f);
 
        break;
    case 6:
        glColor3f(0.0f0.0f1.0f);
 
        break;
    default:
 
        break;
    }
 
    glutPostRedisplay();
}
 
void display() {
    glClear(GL_COLOR_BUFFER_BIT);
 
    glBegin(GL_TRIANGLES);
    glVertex2f(0.0f0.5f);
    glVertex2f(-0.5f-0.5f);
    glVertex2f(0.5f-0.5f);
    glEnd();
 
    glFinish();
}
 
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
    glutCreateWindow("OpenGL");
 
    // Sub menu
    GLint SubMenu = glutCreateMenu(Menu);
    glutAddMenuEntry("Red"4);
    glutAddMenuEntry("Green"5);
    glutAddMenuEntry("Blue"6);
 
    // Menu
    glutCreateMenu(Menu);
    glutAddMenuEntry("White"1);
    glutAddMenuEntry("Black"2);
    glutAddMenuEntry("Gray"3);
 
    // Add sub menu
    glutAddSubMenu("Triangle Color", SubMenu);
    glutAttachMenu(GLUT_RIGHT_BUTTON);
 
    glutDisplayFunc(display);
 
    glutMainLoop();
 
    return 0;
}


위 코드와 같이 Windows 프로그램에 맞게 바꾸고 빌드하면 에러없이 빌드는 되지만 아무것도 실행 되지는 않는다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include <Windows.h>
#include <gl/gl.h>
 
# pragma comment (lib, "opengl32.lib")
# pragma comment(lib, "glu32.lib")
 
HINSTANCE g_hInst;
HWND hWndMain;
LPCTSTR lpszClass = TEXT("OpenGL");
HDC hdc;
HGLRC hrc;
 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void Display();
 
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
    HWND hWnd;
    MSG Message;
    WNDCLASS WndClass;
    g_hInst = hInstance;
 
    WndClass.cbClsExtra = 0;
    WndClass.cbWndExtra = 0;
    WndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    WndClass.hInstance = hInstance;
    WndClass.lpfnWndProc = WndProc;
    WndClass.lpszClassName = lpszClass;
    WndClass.lpszMenuName = NULL;
    WndClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    RegisterClass(&WndClass);
 
    hWnd = CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, (HMENU)NULL, hInstance, NULL);
    ShowWindow(hWnd, nCmdShow);
 
    while (GetMessage(&Message, NULL00)) {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }
 
    return (int)Message.wParam;
}
 
void Display()
{
    glClear(GL_COLOR_BUFFER_BIT);
 
    glBegin(GL_TRIANGLES);
    glVertex2f(0.0f0.5f);
    glVertex2f(-0.5f-0.5f);
    glVertex2f(0.5f-0.5f);
    glEnd();
 
    glFinish();
}
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
    switch (iMessage) {
    case WM_CREATE:
        hWndMain = hWnd;
        PIXELFORMATDESCRIPTOR pfd;
        int nPixelFormat;
 
        hdc = GetDC(hWnd);
        memset(&pfd, 0sizeof(pfd));
 
        pfd.nSize = sizeof(pfd);
        pfd.nVersion = 1;
        pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
        pfd.iPixelType = PFD_TYPE_RGBA;
        pfd.cColorBits = 32;
 
        nPixelFormat = ChoosePixelFormat(hdc, &pfd);
        SetPixelFormat(hdc, nPixelFormat, &pfd);
 
        hrc = wglCreateContext(hdc);
        wglMakeCurrent(hdc, hrc);
 
        return 0;
 
    case WM_PAINT:
        Display();
 
        SetTextColor(hdc, RGB(2552550));
        SetBkMode(hdc, TRANSPARENT);
        TextOutA(hdc, 1010"Windows OpenGL"14);
        
        ValidateRect(hWnd, NULL);
 
        return 0;
 
    case WM_SIZE:
        glViewport(00, LOWORD(lParam), HIWORD(lParam));
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
 
        glOrtho(-11-111-1);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
 
        return 0;
    case WM_DESTROY:
        wglMakeCurrent(hdc, NULL);
        wglDeleteContext(hrc);
        ReleaseDC(hWnd, hdc);
        PostQuitMessage(0);
 
        return 0;
    }
 
    return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}


glut을 사용하지 않고 Windows에서 지원하는 OpenGL 관련 wgl함수를 이용해 작성한 코드이다.



※ Reference

http://soen.kr/lecture/library/opengl/opengl-5.htm


반응형
Posted by J-sean
: