[vk] Drawing triangle - setup - base code

2021. 8. 4. 22:45그래픽스/vk

General structure

#include <vulkan/vulkan.h>

#include <iostream>
#include <stdexcept>
#include <cstdlib>

class HelloTriangleApplication {
public:
    void run() {
        initVulkan();
        mainLoop();
        cleanup();
    }

private:
    void initVulkan() {

    }

    void mainLoop() {

    }

    void cleanup() {

    }
};

int main() {
    HelloTriangleApplication app;

    try {
        app.run();
    } catch (const std::exception& e) {
        std::cerr << e.what() << std::endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

 

vulkan 객체를 private 클래스 멤버로 저장.

각각 초기화 하는 함수를 추가하는 클래스로 래핑, 이 모든것은 initVulkan 함수에서 호출

이 후 모든 준비를 마치고, 메인 루프로 들어가, 프레임 렌더링을 시작

mainLoop가 종료되면, 메모리 정리 기능에서 사용한 자원의 할당을 해제

 

실행중 오류가 발생하면 main함수로 돌아가, runtime_error 예외가 발생

 

Resource management

생성하는 모든 vulkan 객체는 파기해야함 (new -> delete, malloc -> free)

 

최신 c++ <memory> 헤더

- RAII or smart pointers 를 사용해서 자동으로 관리할 수 있긴함 

- 하지만, 튜토리얼에서는 명시적으로 사용함

- 동작과정을 배우는 좋은 방법

- std::unique_ptr or std::shared_ptr 을 사용하여 커스텀 할 수 있음.

- RAII 은 Vulkan 프로그램에서 권장하는 방법

 

vulkan object

- vkCreateXXX같은 함수로 직접 생성

- vkAllocateXXX같은 함수로 다른 객체를 통해 할당

- 객체가 더이상 사용하지 않으면 vkDestroyXXX and vkFreeXXX

- 이러한 함수의 매개변수는 일반적으로 객체 유형에 따라 다름

- 모두 pAllocator라는 하나의 매개 변수를 사용하도록 준비되어있음

- 이것은 선택적 매개 변수임.(튜토리얼에선 nullptr을 인수로 전달)

- pAllocator 에 nullptr 를 넣으면 커스텀 할당이 없이

- 그냥 OS 기본동작에 의해 메모리 할당이 이루어진다는것

Integrating GLFW

이대로 offscreen 렌더링을 할 수 있지만

창에 띄어 렌더링을 하려면 glfw를 사용해야한다.

 

#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>

#include <vulkan/vulkan.h> 을 위와같이 바꿈.

 

initWindow() - 창을 초기화하는 함수를 만들어야한다.

void run() {
    initWindow();
    initVulkan();
    mainLoop();
    cleanup();
}

private:
    void initWindow() {

    }

아래와 같은 함수호출로 OpenGL context를 만들지 않아야함. (GLFW는 원래 OpenGL comtext를 만들기위해 디자인)

glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);

 

실제 창을 만드는 함수, GLFWwindow* window를 사용. (private class member)

4번째 매개변수 - 선택적으로 모니터 지정, 마지막 매개변수 - OpenGL 용

void initWindow() {
    glfwInit();

    glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
    glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);

    window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
}

 

메인 루프함수는 다음과 같다

- 나중에 하나의 프레임을 렌더링하는 함수를 호출할 루프

- 종료버튼을 누르는것을 검사 - shouldclose

void mainLoop() {
    while (!glfwWindowShouldClose(window)) {
        glfwPollEvents();
    }
}

 

아래는 GLFW 자체를 종료, 리소스 정리하는 작업.

void cleanup() {
    glfwDestroyWindow(window);

    glfwTerminate();
}

 

C++ code : 전체 c++ 코드

 

 

https://vulkan-tutorial.com/Drawing_a_triangle/Setup/Base_code