[Vulkan Tutorial] 04-Create Sub-Module and Base Code

목차: 01-Overview (Link)
이전 글: 03-Development Environment (Link)
다음 글: 05-Create an Instance (Link)


Create Sub-Module on Android Project

Base Code를 작성하기 이전에 안드로이드 프로젝트에 Sub-Module을 생성하는 방법에 대해서 정리하였다. Module을 따로 만들 필요 없이 01-init_instance module의 코드를 수정해도 상관은 없다. 개인적으로 mkVulkanExample이라는 Sub-Module을 만들어서 Vulkan 코드를 작성하고 싶어서 Sub-Module을 만드는 방법에 대해서 정리해보았다.

먼저 “VulkanSamples/API-Samples” 폴더 아래에 본인이 원하는 Sub-Module 이름으로 폴더를 하나 생성한다. 저의 경우 mkVulkanExample이라고 이름을 정하였다. 그리고 해당 폴더 아래에 폴더 이름과 동일한 파일 이름을 가진 .cpp 파일을 하나 생성한다. 저의 경우 역시 mkVulkanExample.cpp라고 이름을 정하였다. 다음은 아래 코드 1과 같이 sample_main(…) 함수를 하나 작성한다.

코드 1에 여러 개의 #include를 가지고 있지만, 현재는 딱히 필요 없다. 뒤에 계속 사용 예정이라 미리 추가하였다. #define APP_SHORT_NAME 역시 현시점에 불필요하다. 다른 Module이 동일한 형태로 APP 이름을 사용하는 관계로 똑같이 만들어 보았다.

코드 1: mkVulkanExample.cpp 코드

#include <iostream>
#include <stdexcept>
#include <functional>
#include <cstdlib>
#include <util_init.hpp>

#define APP_SHORT_NAME "mkVulkanExample"

int sample_main(int argc, char *argv[]) {
	
    return EXIT_SUCCESS;
}

코드 1을 작성 후 “VulkanSmaples/API-Smaples” 폴더에서 아래 CMD를 실행한다. 이전 글(03-Development Environment)에서 사용한 CMD이다. 아래 CMD를 Terminal에서 실행하면 “android” 폴더 아래에 “mkVulkanExample”이라는 폴더가 생성되면서 Android Project에 “mkVulkanExample”이라는 Sub-Module이 하나 생성된다. 해당 Sub-Module을 빌드하려고 하면 아마도 android_native_app_glue.c 파일이 없다는 이유로 빌드 에러가 발생할 것이다.

cmake -DANDROID=ON -DABI_NAME=arm64-v8a

에러를 제거하기 위해서 “android_native_app_glue.c” 파일을 빌드 과정에 추가해야 한다. “android” 폴더 아래에 CMakeLists.txt 파일을 열어서 add_library(…) 부분에 아래와 같이 수정하면 빌드 과정에 android_native_app_glue.c 파일을 참조하게 된다.

...
add_library(vulkan_sample SHARED
            ${CMAKE_SOURCE_DIR}/../${SAMPLE_NAME}/${SAMPLE_NAME}.cpp
            ${CMAKE_SOURCE_DIR}/vulkan_wrapper/vulkan_wrapper.cpp
	    ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c)
...

이제 Sub-Module을 빌드하면 아마 에러 없이 빌드가 가능할 것이다. Android Studio의 경우 Module을 선택하고 “Build” 아래에 “Make Module MODULE_NAME”을 선택하면 빌드가 된다. 만약 Gradle을 다운받아서 Terminal에서 빌드하는 경우 아래 CMD를 사용해서 특정 Module 1개만 따로 빌드 할 수 있다. Android 모듈 빌드의 경우 “VulkanSmaples/API-Smaples/android” 폴더 아래에서 아래 CMD를 실행해야 한다.

#MK: 모든 Module을 빌드 하는 경우
$gradle build
#MK: 또는 아래와 같이 사용해도 빌드가 가능
$gradlew build

#MK: 특정 Module 한개만 빌드하는 경우 
$gradle MODULE_NAME:build 
#MK: 예제
$gradle mkVulkanExample:build

Writing Base Code

Sub-Module을 생성해서 빌드하는 과정까지 마무리했다. 이제 Base Code를 작성할 차례이다. Base Code의 경우 아래 출처 1의 내용을 참조하여서 작성하였다. 지금부터 작성하는 대부분의 코드는 출처 1의 내용과 VulkanSamples에서 제공하는 코드를 참조하여서 작성할 예정이다. 아래 코드 2는 Base Code이다.

코드 2: mkVulkanExample.cpp 코드

//MK: (코드 2-1) 필요한 Header 추가
#include <iostream>
#include <stdexcept>
#include <functional>
#include <cstdlib>
#include <util_init.hpp>

#define APP_SHORT_NAME "mkVulkanExample"

//MK: (코드 2-2) mkTriangle Class 생성
class mkTriangle{
	public:
		void run(){
			LOGI("MK: mkTriangle-->run()");
			initVulkan();
			mainLoop();
			cleanup();
		}

	private:
		void initVulkan(){
		}

		void mainLoop(){
		}

		void cleanup(){
		}
};

//MK: (코드 2-3) Android Main 함수
int sample_main(int argc, char *argv[]) {
	
	//MK: 코드 (2-4) Vulkan API를 로딩하는 부분	
	if(!InitVulkan()){
		LOGE("MK: Failed to Initialize Vulkan APIs");
		return EXIT_FAILURE;
	}
		
	mkTriangle mkApp;

	try{
		mkApp.run();
	} catch (const std::exception &e){
		std::cerr << e.what() << std::endl;
		LOGE("MK: Failed to Run Application");
		return EXIT_FAILURE;
	}
    return EXIT_SUCCESS;
}

먼저 코드 2-1에 필요한 Header를 추가하였다.

  • stdexcept, iostream: 에러 등을 리포트 하기 위해서 추가
  • functional: lambda 함수를 사용하기 위해서 추가 (Resource Management에서 사용 예정)
  • cstdlib: EXIT_SUCCESS, EXIT_FAILURE 등의 Macro를 사용하기 위해서 추가
  • util_init.hpp: 안드로이드 Vulkan API를 사용하기 위해서 추가 (util_init.hpp 파일을 보면 Android에서 Vulkan API를 사용하기 편하도록 모든 Initialization (초기 설정) 함수를 만들어 놓았다. 해당 함수를 사용하면 훨씬 쉽게 Vulkan API를 사용할 수 있다. 저의 경우 해당 Initialization 함수를 사용하지 않고 코드를 작성해볼 예정이다)

코드 2-2는 Triangle을 그리는 과정에 필요한 부분을 Wrapping 하기 위한 함수이다. 현재는 거의 모든 함수가 비어있다. 해당 함수를 채워가는 과정이 출처 2의 Vulkan Tutorial 과정이다.

MK: Android로 작성한 코드를 디버깅하기 위해서 LOGI, LOGE 함수를 사용할 예정이다. LOGI, LOGE 함수는 Android 단말 logcat에 결과를 출력하는 함수이다.

코드 2-3은 Android Main 함수이다. 아마 안에 코드 내용은 어려운 부분이 없으리라 판단된다. 추가로 코드 2-4는 Vulkan API를 로딩하기 위해서 추가하였다. 코드 2-4부분을 추가해야 다음에 Vulkan 관련 함수를 사용 할 수 있다.

위 코드를 빌드해서 안드로이드 기기에 설치하면 검정색 화면만 나타난다. 정상적으로 실행된 것을 확인 하기 위해서 “logcat”을 사용해야 한다. 아래 그림 1은 위 코드를 빌드한 APK를 설치하여 실행하면 logcat에 출력되는 결과이다. 위에서 작성한 코드는 출처 3에서 확인 가능하다.

그림 1: APK 실행 후 Logcat 결과 화면

출처

  1. https://developer.android.com/ndk/guides/graphics/getting-started
  2. https://vulkan-tutorial.com/
  3. https://github.com/mkblog-cokr/androidVulkanTutorial

Leave a Comment