Programming/openGL2025. 7. 30. 23:13

맨날 리눅스에서만 하다가 노트북 바꾸기 귀찮아서(!!) 윈도우에서도 해보려고 발악중

 

일단은 visual studio 에서 콘솔앱으로는 안되서

Windows 데스크탑 애플리케이션으로 프로젝트를 생성

 

프로젝트 설정에 링커 - 입력 - 추가 종속성에

 

opengl32.lib 와 glu32.lib를 추가해주면 끝

[링크 : https://makingrobot.tistory.com/155]

 

F5 눌러서 빌드하니 잘 뜬다.

 

 

아래는 gemini가 생성해준 소스코드.

더보기

#include <windows.h> // Win32 API 헤더
#include <gl/gl.h>   // OpenGL 핵심 헤더
#include <gl/glu.h>  // GLU 유틸리티 헤더

// OpenGL 렌더링 컨텍스트 핸들
HGLRC g_hRC = NULL;
// 디바이스 컨텍스트 핸들
HDC g_hDC = NULL;
// 윈도우 핸들
HWND g_hWnd = NULL;
// 인스턴스 핸들
HINSTANCE g_hInstance = NULL;

// 창 클래스 이름 (유니코드 문자열)
LPCWSTR szWindowClass = L"OpenGLWindow";
// 창 제목 (유니코드 문자열)
LPCWSTR szTitle = L"Simple OpenGL Triangle (No GLUT)";

// OpenGL 초기화 함수
void InitOpenGL() {
    // 배경색을 검정색으로 설정 (RGBA 값)
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    // 현재 매트릭스를 프로젝션 매트릭스로 설정
    glMatrixMode(GL_PROJECTION);
    // 2D 직교 투영 설정 (좌표계: x=0.0~200.0, y=0.0~200.0)
    gluOrtho2D(0.0, 200.0, 0.0, 200.0);
}

// 그리기 함수
void DrawScene() {
    // 컬러 버퍼 클리어
    glClear(GL_COLOR_BUFFER_BIT);

    // 삼각형 그리기 시작
    glBegin(GL_TRIANGLES);
    // 첫 번째 꼭지점: 빨간색 (위쪽)
    glColor3f(1.0f, 0.0f, 0.0f);
    glVertex2i(100, 150);
    // 두 번째 꼭지점: 녹색 (왼쪽 아래)
    glColor3f(0.0f, 1.0f, 0.0f);
    glVertex2i(50, 50);
    // 세 번째 꼭지점: 파란색 (오른쪽 아래)
    glColor3f(0.0f, 0.0f, 1.0f);
    glVertex2i(150, 50);
    glEnd(); // 삼각형 그리기 끝

    // 프론트 버퍼와 백 버퍼 교체 (더블 버퍼링 사용 시)
    SwapBuffers(g_hDC);
}

// OpenGL 활성화 함수
// 창 핸들(hWnd), 디바이스 컨텍스트 포인터(hDC), 렌더링 컨텍스트 포인터(hRC)를 인자로 받음
void EnableOpenGL(HWND hWnd, HDC* hDC, HGLRC* hRC) {
    PIXELFORMATDESCRIPTOR pfd;
    int iFormat;

    // 픽셀 형식 기술자 구조체를 0으로 초기화
    ZeroMemory(&pfd, sizeof(pfd));
    // 픽셀 형식 기술자 구조체의 크기 설정
    pfd.nSize = sizeof(pfd);
    // 픽셀 형식 기술자 버전 설정
    pfd.nVersion = 1;
    // 픽셀 형식 플래그 설정: 윈도우에 그리기, OpenGL 지원, 더블 버퍼링 사용
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    // 픽셀 타입 설정: RGBA 색상 모드
    pfd.iPixelType = PFD_TYPE_RGBA;
    // 색상 비트 깊이 설정: 32비트 색상
    pfd.cColorBits = 32;
    // 깊이 버퍼 비트 깊이 설정: 16비트 깊이 버퍼
    pfd.cDepthBits = 16;
    // 레이어 타입 설정: 메인 평면
    pfd.iLayerType = PFD_MAIN_PLANE;

    // 윈도우의 디바이스 컨텍스트를 얻음
    *hDC = GetDC(hWnd);

    // 주어진 픽셀 형식 기술자에 가장 적합한 픽셀 형식을 찾음
    iFormat = ChoosePixelFormat(*hDC, &pfd);
    // 디바이스 컨텍스트에 픽셀 형식을 설정
    SetPixelFormat(*hDC, iFormat, &pfd);

    // OpenGL 렌더링 컨텍스트 생성
    *hRC = wglCreateContext(*hDC);
    // 현재 스레드의 디바이스 컨텍스트에 렌더링 컨텍스트를 연결
    wglMakeCurrent(*hDC, *hRC);

    // OpenGL 초기화 함수 호출
    InitOpenGL();
}

// OpenGL 비활성화 함수
// 창 핸들(hWnd), 디바이스 컨텍스트(hDC), 렌더링 컨텍스트(hRC)를 인자로 받음
void DisableOpenGL(HWND hWnd, HDC hDC, HGLRC hRC) {
    // 현재 렌더링 컨텍스트를 해제
    wglMakeCurrent(NULL, NULL);
    // 렌더링 컨텍스트를 삭제
    wglDeleteContext(hRC);
    // 디바이스 컨텍스트를 해제
    ReleaseDC(hWnd, hDC);
}

// 윈도우 프로시저 (메시지 처리 콜백 함수)
// 윈도우 핸들, 메시지 코드, 추가 정보(wParam, lParam)를 인자로 받음
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    switch (message) {
        // 윈도우 생성 시 발생하는 메시지
    case WM_CREATE:
        // OpenGL 활성화 함수 호출
        EnableOpenGL(hWnd, &g_hDC, &g_hRC);
        break;

        // 윈도우가 다시 그려져야 할 때 발생하는 메시지
    case WM_PAINT:
        // 그리기 함수 호출
        DrawScene();
        // WM_PAINT 메시지를 유효화 (반복적인 WM_PAINT 메시지 방지)
        ValidateRect(hWnd, NULL);
        break;

        // 윈도우 크기 변경 시 발생하는 메시지
    case WM_SIZE:
        // 뷰포트 크기를 윈도우 크기에 맞게 조정 (선택 사항)
        // L_PARAM에서 새 너비와 높이를 추출하여 glViewport 함수에 전달
        // glViewport(0, 0, LOWORD(lParam), HIWORD(lParam));
        break;

        // 윈도우 닫기 버튼 클릭 시 발생하는 메시지
    case WM_CLOSE:
        // 윈도우 파괴 메시지를 보냄
        DestroyWindow(hWnd);
        break;

        // 윈도우가 파괴될 때 발생하는 메시지
    case WM_DESTROY:
        // OpenGL 비활성화 함수 호출
        DisableOpenGL(hWnd, g_hDC, g_hRC);
        // 메시지 루프를 종료하는 메시지를 보냄
        PostQuitMessage(0);
        break;

        // 처리하지 않는 다른 메시지들은 기본 윈도우 프로시저로 전달
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

// WinMain 함수 (Windows 애플리케이션의 진입점)
// 인스턴스 핸들, 이전 인스턴스 핸들, 명령줄 문자열, 표시 상태 플래그를 인자로 받음
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    WNDCLASS wc; // 윈도우 클래스 구조체
    MSG msg;     // 메시지 구조체
    BOOL bDone = FALSE; // 메시지 루프 종료 플래그

    g_hInstance = hInstance; // 현재 인스턴스 핸들 저장

    // 윈도우 클래스 스타일 설정: 고유한 DC, 수평/수직 리드로우 시 다시 그리기
    wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
    // 윈도우 프로시저 함수 포인터 설정
    wc.lpfnWndProc = WndProc;
    // 추가 클래스 메모리 (0)
    wc.cbClsExtra = 0;
    // 추가 윈도우 메모리 (0)
    wc.cbWndExtra = 0;
    // 인스턴스 핸들 설정
    wc.hInstance = hInstance;
    // 아이콘 설정 (기본 애플리케이션 아이콘)
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    // 커서 설정 (기본 화살표 커서)
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    // 배경 브러시 설정 (검정색 솔리드 브러시)
    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    // 메뉴 이름 (없음)
    wc.lpszMenuName = NULL;
    // 윈도우 클래스 이름 설정 (LPCWSTR)
    wc.lpszClassName = szWindowClass;

    // 윈도우 클래스 등록 시도
    if (!RegisterClass(&wc)) {
        // 등록 실패 시 메시지 박스 표시 (유니코드 문자열 사용)
        MessageBox(NULL, L"Window Registration Failed!", L"Error", MB_ICONEXCLAMATION | MB_OK);
        return 0; // 프로그램 종료
    }

    // 윈도우 생성 시도
    g_hWnd = CreateWindowEx(
        WS_EX_APPWINDOW, // 확장된 윈도우 스타일: 작업 표시줄에 앱으로 표시
        szWindowClass,   // 윈도우 클래스 이름 (LPCWSTR)
        szTitle,         // 윈도우 제목 (LPCWSTR)
        // 윈도우 스타일: 오버랩된 창, 형제 윈도우 영역 클리핑, 자식 윈도우 영역 클리핑
        WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
        CW_USEDEFAULT, CW_USEDEFAULT, // x, y 위치 (기본값 사용)
        400, 400, // 윈도우 너비, 높이
        NULL,    // 부모 윈도우 핸들 (없음)
        NULL,    // 메뉴 핸들 (없음)
        hInstance, // 인스턴스 핸들
        NULL     // 추가 생성 데이터 (없음)
    );

    // 윈도우 생성 실패 시
    if (!g_hWnd) {
        // 메시지 박스 표시 (유니코드 문자열 사용)
        MessageBox(NULL, L"Window Creation Failed!", L"Error", MB_ICONEXCLAMATION | MB_OK);
        return 0; // 프로그램 종료
    }

    // 윈도우를 화면에 표시
    ShowWindow(g_hWnd, nCmdShow);
    // 윈도우를 업데이트하여 WM_PAINT 메시지 발생
    UpdateWindow(g_hWnd);

    // 메시지 루프
    while (!bDone) {
        // 메시지 큐에서 메시지를 확인 (메시지가 없어도 즉시 반환)
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
            // 종료 메시지 (WM_QUIT) 수신 시
            if (msg.message == WM_QUIT) {
                bDone = TRUE; // 루프 종료 플래그 설정
            }
            else {
                // 키보드 메시지를 번역 (예: VK_SHIFT -> WM_KEYDOWN)
                TranslateMessage(&msg);
                // 메시지를 해당 윈도우의 윈도우 프로시저로 디스패치
                DispatchMessage(&msg);
            }
        }
        else {
            // 메시지가 없을 때 지속적으로 그리기 (게임 루프와 유사)
            DrawScene();
        }
    }

    // 프로그램 종료 코드 반환
    return (int)msg.wParam;
}

'Programming > openGL' 카테고리의 다른 글

openGL light  (0) 2025.07.30
openGL shade  (0) 2025.07.30
openGL 은선제거  (0) 2025.07.29
openGL 스터디용 gemini 생성 코드  (0) 2025.07.16
blender in openGL  (0) 2025.04.28
Posted by 구차니