컴퓨터 과학 & 영상처리 관련/그래픽스

라이브러리 속성 설정 및 // 복붙용

꺄뜨르 2011. 9. 24. 16:28

요거 할때 debug나 release만 하면 안되고 두개 다


// 01_renderWindow.cpp : 응용 프로그램에 대한 진입점을 정의합니다.
//

#include "stdafx.h"
#include "01_renderWindow.h"

#include <gl/GL.h>
#include <gl/GLU.h>

#define MAX_LOADSTRING 100

// 전역 변수:
HINSTANCE hInst;        // 현재 인스턴스입니다.
TCHAR szTitle[MAX_LOADSTRING];     // 제목 표시줄 텍스트입니다.
TCHAR szWindowClass[MAX_LOADSTRING];   // 기본 창 클래스 이름입니다.

//우리가 추가
HGLRC hRC = NULL; //렌더링 컨텍스트(3d)
HDC hDC = NULL; //핸들 디바이스 컨텍스트 ....GDI 장치 컨텍스트
float angle = 0.0f;

// 이 코드 모듈에 들어 있는 함수의 정방향 선언입니다.
ATOM    MyRegisterClass(HINSTANCE hInstance); //HINSTANCE 운영체제(윈도우) 객체
BOOL    InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);


////////////////////요기가 복붙한거 //////////////////////////////

//렌더링 컨텍스트를 만드는 함수
bool initRC(HWND hWnd)
{
 static PIXELFORMATDESCRIPTOR pfd =  
 // pfd는 윈도우즈에게 우리가 원하는 픽셀포맷을 알려준다
 {
  sizeof( PIXELFORMATDESCRIPTOR ),                  
  // 이 픽셀포맷 설명자의 크기
  1,  // 버전
  PFD_DRAW_TO_WINDOW |
  // 포맷이 반드시 윈도우를 지원해야 함
  PFD_SUPPORT_OPENGL |
  // 포맷이 반드시 OpenGL을 지원해야 함
  PFD_DOUBLEBUFFER,       
  // 반드시 더블 버퍼링을 지원해야함
  PFD_TYPE_RGBA,
  // 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 ); //gdi 컨텍스트를 가져오고 이게 있으면 그림을 그릴 수 있음

 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 );   //여기까지 오면 오픈쥐일이랑 캔버스가 연결된거
 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 ... 카메라, 사람눈에서도 쓰이는 렌즈가 빛을 받아들일 수 있는 각도(field of view)
  (float)width / (float)height, //Aspect Ratio 가로세로비를 윈도우즈 넓이? 에 맞춰서
  0.1f, //Near Plane
  100.0f); //Far Plane
 //리소스의 한계...32bit의 한계..시험 끝나고 특강할듯..
 //요 4개로 시야 절두체? 만들 수 있음 머리가 없어서 시야 절두체
 //모델은 월드좌표, 뷰는 카메라 좌표 오픈쥐엘은 이걸 한번에 처리함
 
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();


}
void initGL()
{
 glShadeModel(GL_SMOOTH); //나중에 개념나옴
 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); //백그라운드 지우는 컬러
 glClearDepth(1.0f); //나중
 glEnable(GL_DEPTH_TEST); //나중
 glDepthFunc(GL_LEQUAL); //나중
 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}

void drawGLScene(void)
{
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 glLoadIdentity();
 glTranslatef(-3.0f, 0.0f, -10.0f);
 glRotatef(angle, 0,1,0);
 glBegin(GL_TRIANGLES);//요기 찍은게 그래픽 카드로 넘어감
  glColor3f( 0.5f, 0.3f, 0.72f );
  glVertex3f( 0.0f, 1.0f, 0.0f );   
  glVertex3f(-1.0f,-1.0f, 0.0f );
  glVertex3f( 1.0f,-1.0f, 0.0f );
 glEnd();

 glLoadIdentity();
 glTranslatef( 3.0f, 0.0f, -10.0f );
 glRotatef( angle, 0, 0, 1 );
 glBegin(GL_QUADS);        
  glColor3f( 1.0f, 0.0f, 0.0f );
  glVertex3f( -1.0f, 1.0f, 0.0f );
  glColor3f( 0.0f, 1.0f, 0.0f );
  glVertex3f( 1.0f, 1.0f, 0.0f );
  glColor3f( 0.0f, 0.0f, 1.0f );
  glVertex3f( 1.0f, -1.0f, 0.0f );
  glColor3f( 0.5f, 0.5f, 0.5f );
  glVertex3f( -1.0f, -1.0f, 0.0f );
 glEnd();
 ++angle;

}

 


/////////////////////////////////////////요 위가 복붙한거 ////////////////////////////////////////


int APIENTRY _tWinMain(HINSTANCE hInstance,   //요 함수가 메인함수...중요함 _tWinMain()
                     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_MY01_RENDERWINDOW, szWindowClass, MAX_LOADSTRING);
 MyRegisterClass(hInstance);

 // 응용 프로그램 초기화를 수행합니다.
 if (!InitInstance (hInstance, nCmdShow))
 {
  return FALSE;
 }

 hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MY01_RENDERWINDOW));

 // 기본 메시지 루프입니다.

 bool done = true;

 //렌더링 idle loop 기본적인 3d...
 // idle = 윈도우 메시지가 없을때...0
 while( done )
 {
  if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) //메시지가 없으면 그냥 다음으로 넘어감 peek메시지
  {
   if(msg.message == WM_QUIT)
   {
    releaseRC();
    done = false;
   }
   else
   {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
   }
  }
  else
  {
   drawGLScene();
   SwapBuffers(hDC);
  }
 }

 return (int) msg.wParam;
}

 

//
//  함수: MyRegisterClass()
//
//  목적: 창 클래스를 등록합니다.
//
//  설명:
//
//    Windows 95에서 추가된 'RegisterClassEx' 함수보다 먼저
//    해당 코드가 Win32 시스템과 호환되도록
//    하려는 경우에만 이 함수를 사용합니다. 이 함수를 호출해야
//    해당 응용 프로그램에 연결된
//    '올바른 형식의' 작은 아이콘을 가져올 수 있습니다.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
 WNDCLASSEX wcex;

 wcex.cbSize = sizeof(WNDCLASSEX);

 wcex.style   = CS_HREDRAW | CS_VREDRAW;
 wcex.lpfnWndProc = WndProc;
 wcex.cbClsExtra  = 0;
 wcex.cbWndExtra  = 0;
 wcex.hInstance  = hInstance;
 wcex.hIcon   = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MY01_RENDERWINDOW));
 wcex.hCursor  = LoadCursor(NULL, IDC_ARROW);
 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
 wcex.lpszMenuName = MAKEINTRESOURCE(IDC_MY01_RENDERWINDOW);
 wcex.lpszClassName = szWindowClass;
 wcex.hIconSm  = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

 return RegisterClassEx(&wcex);
}

//
//   함수: InitInstance(HINSTANCE, int)
//
//   목적: 인스턴스 핸들을 저장하고 주 창을 만듭니다.
//
//   설명:
//
//        이 함수를 통해 인스턴스 핸들을 전역 변수에 저장하고
//        주 프로그램 창을 만든 다음 표시합니다.
//
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;
   }
   if(!initRC(hWnd)) //렌더링 생성 1.
   {
    return FALSE;
   }
   initGL(); //초기값 셋팅 해주는거 2.


   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  함수: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  목적: 주 창의 메시지를 처리합니다.
//
//  WM_COMMAND - 응용 프로그램 메뉴를 처리합니다.
//  WM_PAINT - 주 창을 그립니다.
//  WM_DESTROY - 종료 메시지를 게시하고 반환합니다.
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 //about 아니라 요가
 int wmId, wmEvent;
 PAINTSTRUCT ps;
 HDC hdc;

 switch (message)
 {
 case WM_SIZE:
  reSizeGLScene(LOWORD(lParam), HIWORD(lParam)); // 요기 추가됨
  break;
  //////////////////////////////////////////////////////////////
 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;
}

// 정보 대화 상자의 메시지 처리기입니다.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
 UNREFERENCED_PARAMETER(lParam);
 switch (message)
 {
 case WM_INITDIALOG:
  return (INT_PTR)TRUE;

 case WM_COMMAND:
  if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
  {
   EndDialog(hDlg, LOWORD(wParam));
   return (INT_PTR)TRUE;
  }
  break;
 }
 return (INT_PTR)FALSE;
}