이지만, 저는 이것을 빼야 컴파일이 되더군요. openGL파일이 최신버전이라서 그런걸까요?
/*sample.cpp
기본프로젝트 기준*/
#include "stdafx.h"
#include "sample.h"
/*오픈GL용 추가코드: 1*/
#include <gl/GL.h> //1.X //사용에 불편한 기능들이 최대한으로 포함(?)
#include <gl/GLU.h> //조금한 편리한거?
/*오픈GL용 추가코드: 1.5*/
//#pragma comment는 컴파일시, fatal error LNK1104가 생기면 추가종속성에서 기입한것을 지우고 하시면 됩니다.
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
#define MAX_LOADSTRING 100
// 전역 변수:
HINSTANCE hInst; // 현재 인스턴스입니다.
TCHAR szTitle[MAX_LOADSTRING]; // 제목 표시줄 텍스트입니다.
TCHAR szWindowClass[MAX_LOADSTRING]; // 기본 창 클래스 이름입니다.
/*오픈GL용 추가코드: 2*/
HGLRC hRC = NULL; //랜더링 컨텍스트
HDC hDC = NULL; //GDI 장치 컨텍스트
/*오픈GL용 추가코드: 3*/
//제각각인 주변기기들에게 정보를 받아, 일관된 형태로 처리하기 위한거.
bool initRC(HWND hWnd)
{
static PIXELFORMATDESCRIPTOR pfd =
// pfd는 윈도우즈에게 우리가 원하는 픽셀포맷을 알려준다
{
sizeof( PIXELFORMATDESCRIPTOR ),// 픽셀포맷 설명자의 크기
1, // 버전
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
//윈도우를 반드시 지원해야 함 | OpenGL 반드시 지원해야 함 | 더블 버퍼링 반드시 지원
PFD_TYPE_RGBA,
32,
0, 0, 0, 0, 0, 0,
0,// 알파버퍼 없음
0,// 쉬프트 비트 무시
0,// Accumulation 버퍼 없음
0, 0, 0, 0, // Accumulation 비트 무시
24, // 24비트 Z-버퍼 (깊이 버퍼)
0, // 스텐실 버퍼 없음
0, // Auxiliary 버퍼 없음
PFD_MAIN_PLANE, // 메인 드로잉 레이어
0, // 예약됨
0, 0, 0 // 레이어 마스크 무시
};
hDC = GetDC( hWnd );
if( NULL == hDC ) // 장치 컨텍스트를 얻었는지 확인
{
::MessageBox(NULL, L"GL 장치 컨텍스트를 만들 수 없음", L"오류", MB_OK|MB_ICONEXCLAMATION );
return false;
}
int pixelFormat = ChoosePixelFormat( hDC, &pfd ); // 일치하는 포맷을 찾은 결과를 가진다
if( NULL == pixelFormat ) // 일치하는 픽셀 포맷을 찾았는지 확인
{
::MessageBox(NULL, L"적절한 PixelFormat을 찾을 수 없음", L"오류", MB_OK|MB_ICONEXCLAMATION );
return false;
}
if( !SetPixelFormat( hDC, pixelFormat,&pfd ) ) // 픽셀 포맷을 설정할 수 있는지 확인
{
MessageBox( NULL, L"PixelFormat을 설정할 수 없습니다.", L"오류", MB_OK|MB_ICONEXCLAMATION);
return false; // FALSE 반환
}
hRC = wglCreateContext( hDC );
// 여기까지가 오픈GL과 윈도우를 연결//
if ( NULL == hRC ) // 렌더링 컨텍스트를 가져올 수 있는지 확인
{
MessageBox( NULL, L"GL 렌더링 컨텍스트를 생성할 수 없습니다.", L"오류", MB_OK|MB_ICONEXCLAMATION );
return false; // FALSE를 반환
}
if( !wglMakeCurrent( hDC, hRC ) ) // 렌더링 컨텍스트를 활성화하려고 시도
{
MessageBox( NULL, L"GL 렌더링 컨텍스트를 활성화할 수 없습니다.", L"오류", MB_OK|MB_ICONEXCLAMATION);
return false; // FALSE를 반환
}
return true;
};
void releaseRC()
{
if (!wglDeleteContext(hRC))
{
::MessageBox(NULL, L"랜더링 해제실패.", L"오류", MB_OK|MB_ICONEXCLAMATION);
}
}
void reSizeGLScene (int width, int height)
{
if (height==0)
{
height=1;
}
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, //FOV. 시야각 45도.
(float)width / (float)height, //표면비
0.1f,//near plane
100.0f);//far plane. 가시거리쯤?
glMatrixMode(GL_MODELVIEW); //모델뷰 매트릭스는 기하단계에서 3&4단계를 동시수행가능.
glLoadIdentity();
}
//최근 라이브러리쪽으로 고정파이프라인X
void initGL()
{
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); //[0,1] = [어둠:밝음]
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}
//현재 기본적인 삼각형을 그리도록 되어있습니다.
void drawGLScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(-3.0, 0.0, -10.0);
glBegin(GL_TRIANGLES);
glVertex3f(0.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
glEnd();
}
// 이 코드 모듈에 들어 있는 함수의 정방향 선언입니다.
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: 여기에 코드를 입력합니다.
MSG msg;
HACCEL hAccelTable;
// 전역 문자열을 초기화합니다.
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_CH03_01, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// 응용 프로그램 초기화를 수행합니다.
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_CH03_01));
// 기본 메시지 루프였던 구간.
/*오픈GL용 추가코드: 4*/
bool done = true;
while (GetMessage(&msg, NULL, 0, 0))
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) //별다른 메시지가 안 나타나면, 그대로 다른걸로 시행.
{
if(msg.message==WM_QUIT)
{
releaseRC();
done = false;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
drawGLScene();
SwapBuffers(hDC);
}
}
return (int) msg.wParam;
}
...
...
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // 인스턴스 핸들을 전역 변수에 저장합니다.//간접접근의 위한거.
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
/*오픈GL용 추가코드: 5*/
if (!initRC(hWnd))
{
return FALSE;
}
initGL();
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
/*오픈GL용 추가코드: 6*/
case WM_SIZE:
reSizeGLScene( LOWORD(lParam), HIWORD(lParam) );
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 메뉴 선택을 구문 분석합니다.
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: 여기에 그리기 코드를 추가합니다.
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}