-
-
Save Ilgrim/0bc39051fd10059aca3103ae6e160f37 to your computer and use it in GitHub Desktop.
SDL 2 Project build test.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
work in progress build. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#================================================ | |
# CMAKE BUILD | |
# WINDOW BUILD CURRENTLY | |
#================================================ | |
cmake_minimum_required(VERSION 3.20) # FetchContent is available in 3.11+ | |
message("CMAKE_BUILD_TYPE >>> " ${CMAKE_BUILD_TYPE}) | |
#convert checks for deubug / release | |
string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE) | |
if(CMAKE_BUILD_TYPE STREQUAL "debug") | |
set(CMAKE_BUILD_TYPE Debug) | |
message("DEBUG mode ==============================================================") | |
elseif(CMAKE_BUILD_TYPE STREQUAL "release") | |
set(CMAKE_BUILD_TYPE Release) | |
message("RELEASE mode ==============================================================") | |
else() | |
set(CMAKE_BUILD_TYPE Debug) | |
message("NONE mode ==============================================================") | |
endif() | |
project(sdl2app VERSION 0.0.1) | |
set(PROJECT_VERSION 0.0.1) | |
set(PROJECT_VERSION_MAJOR 0) | |
set(PROJECT_VERSION_MINOR 0) | |
set(PROJECT_VERSION_PATCH 0) | |
message("START OF CMAKELIST...") | |
# https://bewagner.net/programming/2020/05/02/cmake-fetchcontent/ | |
set(FETCHCONTENT_FULLY_DISCONNECTED ON) # When this option is enabled, no attempt is made to download or update any content. | |
#set(FETCHCONTENT_UPDATES_DISCONNECTED ON) # download and skip update | |
#================================================ | |
# CONFIGS | |
#================================================ | |
# deal with add ons and checks tests | |
# WINDOW / INPUT / CPU RENDER | |
set(ENABLE_SDL ON) | |
# FONT | |
set(ENABLE_FREETYPE OFF) #needed for sdl image | |
set(ENABLE_SDL_TTF OFF) | |
# IMAGE | |
set(ENABLE_SDL_IMAGE OFF) | |
# SOUND / AUDIO | |
set(ENABLE_SDL_MIXER ON) | |
# ENTITY COMPONENT SYSTEM | |
set(ENABLE_FLECS OFF) | |
# GRAPHIC USER INTERFACE | |
set(ENABLE_IMGUI ON) | |
# 3D GRAPHIC API | |
set(ENABLE_VALKUN ON) | |
#================================================ | |
# NETWORK | |
#================================================ | |
#https://github.com/ValveSoftware/GameNetworkingSockets/blob/master/BUILDING.md | |
set(ENABLE_GAMENETWORKKINGSOCKETS OFF) # not recommend | |
# there no CMakeList.txt in third parties. | |
# REQUIRED openssl | |
# REQUIRED perl | |
# REQUIRED ninja | |
# REQUIRED Protobuf | |
#================================================ | |
# GIT PACKAGE VERSION | |
#================================================ | |
set(FREETYPE_GIT_VERSION VER-2-10-4) # GITHUB RELEASE TAG | |
set(SDL_GIT_VERSION release-2.0.14) # SDL GITHUB RELEASE TAG | |
set(SDL_TTF_GIT_VERSION main) # SDL GITHUB RELEASE TAG | |
set(SDL_IMAGE_GIT_VERSION main) # SDL GITHUB RELEASE TAG | |
set(SDL_MIXER_GIT_VERSION master) # SDL GITHUB RELEASE TAG | |
set(IMGUI_GIT_VERSION | |
docking | |
#v1.82 | |
) # GITHUB RELEASE TAG | |
set(FLECS_GIT_VERSION v2.3.2) # GITHUB RELEASE TAG | |
set(GAMENETWORKKINGSOCKETS_GIT_VERSION master) # GITHUB RELEASE TAG | |
#================================================ | |
# ENTERY POINTS | |
#================================================ | |
# entry point file.cpp | |
set(ENTRYPOINT | |
src/main.cpp | |
#src/sdl2window.cpp | |
#src/windowimguisdl.cpp) | |
#src/vulkan_imgui.cpp | |
#src/vulkan_imgui_editor.cpp | |
#tests/sdl2_mixer_test01.c | |
) | |
message("ENTRYPOINT: ${ENTRYPOINT}") # console log | |
# config IDE ext | |
#include(CTest) | |
#enable_testing() | |
#================================================ | |
# CONFIGS | |
#================================================ | |
#et(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/modules) | |
message("CMAKE_SYSTEM_NAME == " ${CMAKE_SYSTEM_NAME}) | |
if (CMAKE_SYSTEM_NAME STREQUAL "Windows") | |
#target_compile_options(myApp PRIVATE /W4) | |
#message("WINDOW") | |
elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux") | |
#target_compile_options(myApp PRIVATE -Wall -Wextra -Wpedantic) | |
#message("Linux") | |
elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin") | |
# other macOS-specific flags for Clang | |
#message("Darwin") | |
endif() | |
# https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html | |
#cmake -DCMAKE_BUILD_TYPE=Debug path/to/source | |
#cmake -DCMAKE_BUILD_TYPE=Release path/to/source | |
#message("CMAKE_C_FLAGS_RELEASE >>> " ${CMAKE_C_FLAGS_RELEASE}) | |
#message("CMAKE_C_FLAGS >>> " ${CMAKE_C_FLAGS}) | |
#message("CMAKE_CXX_FLAGS >>> " ${CMAKE_CXX_FLAGS}) | |
#message("CMAKE_CONFIGURATION_TYPES >>> " ${CMAKE_CONFIGURATION_TYPES}) | |
#message("CMAKE_CFG_INTDIR >>> " ${CMAKE_CFG_INTDIR}) | |
#message("CMAKE_CUDA_FLAGS >>> " ${CMAKE_CUDA_FLAGS}) | |
#message("CMAKE_Fortran_FLAGS >>> " ${CMAKE_Fortran_FLAGS}) | |
message("CMAKE_CURRENT_SOURCE_DIR >>> " ${CMAKE_CURRENT_SOURCE_DIR}) | |
message("CMAKE_CURRENT_BINARY_DIR >>> " ${CMAKE_CURRENT_BINARY_DIR}) | |
# must set output build dir by default is none. user must config manual | |
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) | |
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) | |
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) | |
message("CMAKE_ARCHIVE_OUTPUT_DIRECTORY: ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}") # workspace/build/Debug | |
message("CMAKE_LIBRARY_OUTPUT_DIRECTORY: ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") | |
message("CMAKE_RUNTIME_OUTPUT_DIRECTORY: ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") | |
# build compiler tool | |
set(CMAKE_C_STANDARD 11) | |
set(CMAKE_CXX_STANDARD_REQUIRED True) | |
#ADD_DEFINITIONS(-DUNICODE) | |
#ADD_DEFINITIONS(-D_UNICODE) | |
# folders, files, libs | |
set(CPP_INCLUDE_DIRS "") | |
set(CPP_HEADER_FILES "") | |
set(CPP_SOURCE_FILES "") | |
set(CPP_LIBS "") | |
if(ENABLE_FREETYPE) | |
if (NOT freetype_FOUND) # If there's none, fetch and build | |
include(FetchContent) | |
FetchContent_Declare( | |
freetype | |
GIT_REPOSITORY https://github.com/freetype/freetype.git | |
GIT_TAG ${FREETYPE_GIT_VERSION} | |
#GIT_TAG VER-2-10-4 | |
) | |
FetchContent_GetProperties(freetype) | |
if (NOT freetype_POPULATED) # Have we downloaded raylib yet? | |
set(FETCHCONTENT_QUIET NO) | |
FetchContent_Populate(freetype) | |
message("freetype_LIBRARY: " ${freetype_LIBRARY}) # fail but define in cmake | |
message("freetype_INCLUDE_DIR: " ${freetype_INCLUDE_DIR}) #pass | |
message("freetype_SOURCE_DIR: " ${freetype_SOURCE_DIR}) # pass | |
message("freetype_BINARY_DIR: " ${freetype_BINARY_DIR}) # pass | |
#set(FT_WITH_ZLIB OFF CACHE BOOL "" FORCE) | |
#set(FT_WITH_BZIP2 OFF CACHE BOOL "" FORCE) | |
#set(FT_WITH_PNG OFF CACHE BOOL "" FORCE) | |
#set(FT_WITH_HARFBUZZ OFF CACHE BOOL "" FORCE) | |
#set(FT_WITH_BROTLI OFF CACHE BOOL "" FORCE) | |
# build freetype | |
list(APPEND CPP_INCLUDE_DIRS ${freetype_SOURCE_DIR}/include) | |
list(APPEND CPP_INCLUDE_DIRS ${freetype_BINARY_DIR}/include) | |
list(APPEND CPP_HEADER_FILES ${freetype_SOURCE_DIR}/include/ft2build.h) | |
list(APPEND FREETYPE_INCLUDE_DIRS ${freetype_SOURCE_DIR}/include) | |
list(APPEND FREETYPE_INCLUDE_DIRS ${freetype_BINARY_DIR}/include) | |
set(FREETYPE_LIBRARY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) | |
#link_directories(${sdl_ttf_BINARY_DIR}/Debug)# this will look for libs files. | |
add_subdirectory(${freetype_SOURCE_DIR} ${freetype_BINARY_DIR}) #add to build in sub dir | |
add_library(Freetype::Freetype ALIAS freetype) | |
endif() | |
endif() | |
endif() | |
#================================================ | |
# SDL | |
#================================================ | |
message("[[[=== CHECKING SDL SECTION === ]]]") | |
if (ENABLE_SDL) | |
# base on environment system path variable set. | |
# find_package(sdl QUIET) # Requires at least version 2.5.0 | |
message("sdl_FOUND:" ${SDL_FOUND}) | |
if (NOT sdl_FOUND) # If there's none, fetch and build sdl | |
include(FetchContent) | |
FetchContent_Declare( | |
sdl | |
GIT_REPOSITORY https://github.com/libsdl-org/SDL.git | |
GIT_TAG ${SDL_GIT_VERSION} | |
) | |
FetchContent_GetProperties(sdl) | |
if (NOT SDL2_POPULATED) # Have we downloaded raylib yet? | |
set(FETCHCONTENT_QUIET NO) | |
FetchContent_Populate(sdl) | |
#message("SDL_LIBRARY: " ${sdl_LIBRARY}) # fail but define in cmake | |
#message("SDL_INCLUDE_DIR: " ${sdl_INCLUDE_DIR}) #pass | |
#message("sdl_SOURCE_DIR: " ${sdl_SOURCE_DIR}) # pass | |
#message("sdl_BINARY_DIR: " ${sdl_BINARY_DIR}) # pass | |
# build SDL2 | |
list(APPEND CPP_INCLUDE_DIRS ${sdl_SOURCE_DIR}/include) | |
#include_directories(${sdl2_BINARY_DIR}/include) | |
link_directories(${PROJECT_BINARY_DIR}/Debug) | |
add_subdirectory(${sdl_SOURCE_DIR} ${sdl_BINARY_DIR}) | |
#needed for sub modules | |
list(APPEND SDL2_INCLUDE_DIR ${sdl_SOURCE_DIR}/include) | |
list(APPEND SDL2_LIBRARIES ${PROJECT_SOURCE_DIR}/build/Debug/SDL2maind.lib) | |
list(APPEND SDL2_LIBRARIES ${PROJECT_SOURCE_DIR}/build/Debug/SDL2-staticd.lib) | |
list(APPEND SDL2_LIBRARIES ${PROJECT_SOURCE_DIR}/build/Debug/SDL2d.lib) | |
#list(APPEND SDL2_LIBRARY ${PROJECT_BINARY_DIR}/Debug/SDL2maind.lib) | |
#list(APPEND SDL2_LIBRARY ${PROJECT_BINARY_DIR}/Debug/SDL2-staticd.lib) | |
#list(APPEND SDL2_LIBRARY ${PROJECT_BINARY_DIR}/Debug/SDL2d.lib) | |
#list(APPEND SDL2_LIB ${PROJECT_SOURCE_DIR}/build/Debug/SDL2maind.lib) | |
#list(APPEND SDL2_LIB ${PROJECT_SOURCE_DIR}/build/Debug/SDL2-staticd.lib) | |
#list(APPEND SDL2_LIB ${PROJECT_SOURCE_DIR}/build/Debug/SDL2d.lib) | |
list(APPEND CPP_LIBS "SDL2main") | |
list(APPEND CPP_LIBS "SDL2-static") | |
add_library(SDL2::SDL2 ALIAS SDL2) | |
add_library(SDL2::SDL2-static ALIAS SDL2-static) | |
endif() | |
endif() | |
endif() | |
if (ENABLE_SDL_TTF) | |
# base on environment system path variable set. | |
if (NOT sdl_image_FOUND) # If there's none, fetch and build sdl | |
include(FetchContent) | |
FetchContent_Declare( | |
sdl_ttf | |
GIT_REPOSITORY https://github.com/libsdl-org/SDL_ttf.git | |
GIT_TAG ${SDL_TTF_GIT_VERSION} | |
) | |
FetchContent_GetProperties(sdl_ttf) | |
if (NOT sdl_ttf_POPULATED) # Have we downloaded raylib yet? | |
set(FETCHCONTENT_QUIET NO) | |
FetchContent_Populate(sdl_ttf) | |
#message("sdl_ttf_LIBRARY: " ${sdl_ttf_LIBRARY}) # fail but define in cmake | |
#message("sdl_ttf_INCLUDE_DIR: " ${sdl_ttf_INCLUDE_DIR}) #pass | |
#message("sdl_ttf_SOURCE_DIR: " ${sdl_ttf_SOURCE_DIR}) # pass | |
#message("sdl_ttf_BINARY_DIR: " ${sdl_ttf_BINARY_DIR}) # pass | |
# build SDL2 | |
#list(APPEND CPP_INCLUDE_DIRS ${sdl_image_SOURCE_DIR}/include) | |
add_subdirectory(${sdl_ttf_SOURCE_DIR} ${sdl_ttf_BINARY_DIR}) | |
#list(APPEND CPP_LIBS "sdl_ttf") | |
endif() | |
endif() | |
endif() | |
if (ENABLE_SDL_IMAGE) | |
# base on environment system path variable set. | |
if (NOT sdl_image_FOUND) # If there's none, fetch and build sdl | |
include(FetchContent) | |
FetchContent_Declare( | |
sdl_image | |
GIT_REPOSITORY https://github.com/libsdl-org/SDL_image.git | |
GIT_TAG ${SDL_IMAGE_GIT_VERSION} | |
) | |
FetchContent_GetProperties(sdl_image) | |
if (NOT sdl_image_POPULATED) # Have we downloaded raylib yet? | |
set(FETCHCONTENT_QUIET NO) | |
FetchContent_Populate(sdl_image) | |
#message("sdl_image_LIBRARY: " ${sdl_image_LIBRARY}) # fail but define in cmake | |
#message("sdl_image_INCLUDE_DIR: " ${sdl_image_INCLUDE_DIR}) #pass | |
#message("sdl_image_SOURCE_DIR: " ${sdl_image_SOURCE_DIR}) # pass | |
#message("sdl_image_BINARY_DIR: " ${sdl_image_BINARY_DIR}) # pass | |
set(SUPPORT_JPG OFF CACHE BOOL "" FORCE) | |
set(SUPPORT_PNG ON CACHE BOOL "" FORCE) | |
set(BUILD_SHOWIMAGE OFF CACHE BOOL "" FORCE) | |
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) | |
# BUILD_SHARED_LIBS OFF is LIB | |
# build sdl2 image | |
#list(APPEND CPP_INCLUDE_DIRS ${sdl_image_SOURCE_DIR}/include) | |
add_subdirectory(${sdl_image_SOURCE_DIR} ${sdl_image_BINARY_DIR}) | |
#list(APPEND CPP_LIBS "SDL2_image") | |
endif() | |
endif() | |
endif() | |
if (ENABLE_SDL_MIXER) | |
# base on environment system path variable set. | |
if (NOT sdl_mixer_FOUND) # If there's none, fetch and build sdl | |
include(FetchContent) | |
FetchContent_Declare( | |
sdl_mixer | |
GIT_REPOSITORY https://github.com/libsdl-org/SDL_mixer.git | |
GIT_TAG ${SDL_MIXER_GIT_VERSION} | |
) | |
FetchContent_GetProperties(sdl_mixer) | |
if (NOT sdl_mixer_POPULATED) # Have we downloaded raylib yet? | |
set(FETCHCONTENT_QUIET NO) | |
FetchContent_Populate(sdl_mixer) | |
#message("sdl_mixer_LIBRARY: " ${sdl_mixer_LIBRARY}) # fail but define in cmake | |
#message("sdl_mixer_INCLUDE_DIR: " ${sdl_mixer_INCLUDE_DIR}) #pass | |
#message("sdl_mixer_SOURCE_DIR: " ${sdl_mixer_SOURCE_DIR}) # pass | |
#message("sdl_mixer_BINARY_DIR: " ${sdl_mixer_BINARY_DIR}) # pass | |
set(ANDROID ON) | |
set(SUPPORT_OGG ON CACHE BOOL "" FORCE) | |
#set(SUPPORT_OGG ON CACHE BOOL "" FORCE) | |
# build SDL2 MIXER | |
list(APPEND CPP_INCLUDE_DIRS ${sdl_mixer_SOURCE_DIR}/include) | |
add_subdirectory(${sdl_mixer_SOURCE_DIR} ${sdl_mixer_BINARY_DIR}) | |
list(APPEND CPP_LIBS "SDL2_mixer") | |
endif() | |
endif() | |
endif() | |
#================================================ | |
# FLECS | |
#================================================ | |
message("[[[=== CHECKING FLECS SECTION === ]]]") | |
if (ENABLE_FLECS) | |
#find_package(flecs QUIET) # Requires at least version 2.5.0 | |
if (NOT flecs_FOUND) # If there's none, fetch and build flecs | |
include(FetchContent) | |
FetchContent_Declare( | |
flecs | |
GIT_REPOSITORY https://github.com/SanderMertens/flecs.git | |
GIT_TAG ${FLECS_GIT_VERSION} | |
) | |
FetchContent_GetProperties(flecs) | |
if (NOT flecs_POPULATED) # Have we downloaded flecs yet? | |
set(FETCHCONTENT_QUIET NO) | |
FetchContent_Populate(flecs) | |
# build flecs | |
add_subdirectory(${flecs_SOURCE_DIR} ${flecs_BINARY_DIR}) | |
endif() | |
endif() | |
endif() | |
#================================================ | |
# IMGUI | |
#================================================ | |
message("[[[=== CHECKING IMGUI SECTION === ]]]") | |
if (ENABLE_IMGUI) | |
#find_package(imgui QUIET) # Requires at least version 2.5.0 | |
if (NOT imgui_FOUND) # If there's none, fetch and build imgui | |
include(FetchContent) | |
FetchContent_Declare( | |
imgui | |
GIT_REPOSITORY https://github.com/ocornut/imgui.git | |
GIT_TAG ${IMGUI_GIT_VERSION} | |
) | |
FetchContent_GetProperties(imgui) | |
if (NOT imgui_POPULATED) # Have we downloaded imgui yet? | |
set(FETCHCONTENT_QUIET NO) | |
FetchContent_Populate(imgui) | |
message("imgui_SOURCE_DIR: " ${imgui_SOURCE_DIR}) | |
list(APPEND CPP_INCLUDE_DIRS ${imgui_SOURCE_DIR}) | |
list(APPEND CPP_INCLUDE_DIRS ${imgui_SOURCE_DIR}/backends) | |
#INCLUDE_HEADERS | |
#list(APPEND INCLUDE_HEADERS ${imgui_SOURCE_DIR}/imconfig.h) | |
list(APPEND CPP_SOURCE_FILES ${imgui_SOURCE_DIR}/imgui.cpp) | |
list(APPEND CPP_HEADER_FILES ${imgui_SOURCE_DIR}/imgui.h) | |
list(APPEND CPP_HEADER_FILES ${imgui_SOURCE_DIR}/imgui_internal.h) | |
list(APPEND CPP_SOURCE_FILES ${imgui_SOURCE_DIR}/imgui_demo.cpp) | |
list(APPEND CPP_SOURCE_FILES ${imgui_SOURCE_DIR}/imgui_draw.cpp) | |
list(APPEND CPP_SOURCE_FILES ${imgui_SOURCE_DIR}/imgui_tables.cpp) | |
list(APPEND CPP_SOURCE_FILES ${imgui_SOURCE_DIR}/imgui_widgets.cpp) | |
#list(APPEND CPP_HEADER_FILES ${imgui_SOURCE_DIR}/imstb_rectpack.h) | |
#list(APPEND CPP_HEADER_FILES ${imgui_SOURCE_DIR}/imstb_textedit.h) | |
#list(APPEND CPP_HEADER_FILES ${imgui_SOURCE_DIR}/imstb_truetype.h) | |
list(APPEND CPP_SOURCE_FILES ${imgui_SOURCE_DIR}/backends/imgui_impl_sdl.cpp) | |
list(APPEND CPP_HEADER_FILES ${imgui_SOURCE_DIR}/backends/imgui_impl_sdl.h) | |
list(APPEND CPP_SOURCE_FILES ${imgui_SOURCE_DIR}/backends/imgui_impl_vulkan.cpp) | |
list(APPEND CPP_HEADER_FILES ${imgui_SOURCE_DIR}/backends/imgui_impl_vulkan.h) | |
endif() | |
endif() | |
endif() | |
#================================================ | |
# VULKAN | |
#================================================ | |
message("[[[=== CHECKING VULKAN SECTION === ]]]") | |
if(ENABLE_VALKUN) | |
#look for Vulkan SDK location | |
find_package(Vulkan) | |
if(NOT Vulkan_FOUND) | |
message("NOT FOUND VULKAN") | |
return() | |
endif() | |
if(Vulkan_FOUND) | |
set(VULKAN_PATH ${Vulkan_INCLUDE_DIRS}) | |
STRING(REGEX REPLACE "/Include" "" VULKAN_PATH ${VULKAN_PATH}) | |
endif() | |
# vulkan-1 library for build Vulkan application. | |
#set(VULKAN_LIB_LIST "vulkan-1") | |
list(APPEND CPP_LIBS "vulkan-1") | |
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") | |
message("VULKAN_PATH " ${VULKAN_PATH}) | |
# Include Vulkan header files from Vulkan SDK | |
#include_directories(AFTER ${VULKAN_PATH}/Include) | |
list(APPEND CPP_INCLUDE_DIRS ${Vulkan_INCLUDE_DIRS}) | |
# Link directory for vulkan-1 | |
link_directories(${VULKAN_PATH}/Bin;${VULKAN_PATH}/Lib;) | |
endif() | |
endif() | |
#not working required third paty libs | |
if(ENABLE_GAMENETWORKKINGSOCKETS) | |
if (NOT gamenetworkingsockets_FOUND) # If there's none, fetch and build flecs | |
include(FetchContent) | |
FetchContent_Declare( | |
gamenetworkingsockets | |
GIT_REPOSITORY https://github.com/ValveSoftware/GameNetworkingSockets.git | |
GIT_TAG ${GAMENETWORKKINGSOCKETS_GIT_VERSION} | |
) | |
FetchContent_GetProperties(flecs) | |
if (NOT gamenetworkingsockets_POPULATED) # Have we downloaded flecs yet? | |
set(FETCHCONTENT_QUIET NO) | |
FetchContent_Populate(gamenetworkingsockets) | |
set(GAMENETWORKINGSOCKETS_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) | |
set(GAMENETWORKINGSOCKETS_BUILD_TESTS OFF CACHE BOOL "" FORCE) | |
# build gamenetworkingsockets | |
add_subdirectory(${gamenetworkingsockets_SOURCE_DIR} ${gamenetworkingsockets_BINARY_DIR}) | |
endif() | |
endif() | |
endif() | |
#================================================ | |
# TARGET SET UP SECTION | |
#================================================ | |
#================================================ | |
# INCLUDE DIRS | |
#================================================ | |
include_directories(${CPP_INCLUDE_DIRS}) | |
#================================================ | |
# EXECUTE APP | |
#================================================ | |
#add_executable(${PROJECT_NAME} ${ENTRYPOINT}) | |
add_executable(${PROJECT_NAME} | |
${CPP_HEADER_FILES} | |
${CPP_SOURCE_FILES} | |
${ENTRYPOINT} | |
) | |
#================================================ | |
# LIBRARIES | |
#================================================ | |
target_link_libraries(${PROJECT_NAME} | |
${CPP_LIBS} | |
#opengl32 | |
#jpeg | |
) | |
#================================================ | |
# INCLUDE DIRS | |
#================================================ | |
#target_include_directories(${PROJECT_NAME} | |
#PRIVATE | |
#${INCLUDE_PATHS} | |
#) | |
#target_link_libraries(${PROJECT_NAME} SDL2main SDL2-static) | |
#target_link_libraries(${PROJECT_NAME} PRIVATE SDL2main SDL2-static flecs_static ${VULKAN_LIB_LIST}) | |
#================================================ | |
# COMPILER | |
#================================================ | |
#target_compile_options(${PROJECT_NAME} PRIVATE -Wall) | |
#set(CPACK_PROJECT_NAME ${PROJECT_NAME}) | |
#set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) | |
#include(CPack) | |
message("END OF CMAKELIST...") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Dear ImGui: standalone example application for SDL2 + Vulkan | |
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. | |
// Read online: https://github.com/ocornut/imgui/tree/master/docs | |
// Important note to the reader who wish to integrate imgui_impl_vulkan.cpp/.h in their own engine/app. | |
// - Common ImGui_ImplVulkan_XXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h. | |
// You will use those if you want to use this rendering backend in your engine/app. | |
// - Helper ImGui_ImplVulkanH_XXX functions and structures are only used by this example (main.cpp) and by | |
// the backend itself (imgui_impl_vulkan.cpp), but should PROBABLY NOT be used by your own engine/app code. | |
// Read comments in imgui_impl_vulkan.h. | |
#include "imgui.h" | |
#include "imgui_impl_sdl.h" | |
#include "imgui_impl_vulkan.h" | |
#include <stdio.h> // printf, fprintf | |
#include <stdlib.h> // abort | |
#include <SDL.h> | |
#include <SDL_vulkan.h> | |
#include <vulkan/vulkan.h> | |
//#define IMGUI_UNLIMITED_FRAME_RATE | |
#ifdef _DEBUG | |
#define IMGUI_VULKAN_DEBUG_REPORT | |
#endif | |
static VkAllocationCallbacks* g_Allocator = NULL; | |
static VkInstance g_Instance = VK_NULL_HANDLE; | |
static VkPhysicalDevice g_PhysicalDevice = VK_NULL_HANDLE; | |
static VkDevice g_Device = VK_NULL_HANDLE; | |
static uint32_t g_QueueFamily = (uint32_t)-1; | |
static VkQueue g_Queue = VK_NULL_HANDLE; | |
static VkDebugReportCallbackEXT g_DebugReport = VK_NULL_HANDLE; | |
static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE; | |
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE; | |
static ImGui_ImplVulkanH_Window g_MainWindowData; | |
static uint32_t g_MinImageCount = 2; | |
static bool g_SwapChainRebuild = false; | |
static void check_vk_result(VkResult err) | |
{ | |
if (err == 0) | |
return; | |
fprintf(stderr, "[vulkan] Error: VkResult = %d\n", err); | |
if (err < 0) | |
abort(); | |
} | |
#ifdef IMGUI_VULKAN_DEBUG_REPORT | |
static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData) | |
{ | |
(void)flags; (void)object; (void)location; (void)messageCode; (void)pUserData; (void)pLayerPrefix; // Unused arguments | |
fprintf(stderr, "[vulkan] Debug report from ObjectType: %i\nMessage: %s\n\n", objectType, pMessage); | |
return VK_FALSE; | |
} | |
#endif // IMGUI_VULKAN_DEBUG_REPORT | |
static void SetupVulkan(const char** extensions, uint32_t extensions_count) | |
{ | |
VkResult err; | |
// Create Vulkan Instance | |
{ | |
VkInstanceCreateInfo create_info = {}; | |
create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; | |
create_info.enabledExtensionCount = extensions_count; | |
create_info.ppEnabledExtensionNames = extensions; | |
#ifdef IMGUI_VULKAN_DEBUG_REPORT | |
// Enabling validation layers | |
const char* layers[] = { "VK_LAYER_KHRONOS_validation" }; | |
create_info.enabledLayerCount = 1; | |
create_info.ppEnabledLayerNames = layers; | |
// Enable debug report extension (we need additional storage, so we duplicate the user array to add our new extension to it) | |
const char** extensions_ext = (const char**)malloc(sizeof(const char*) * (extensions_count + 1)); | |
memcpy(extensions_ext, extensions, extensions_count * sizeof(const char*)); | |
extensions_ext[extensions_count] = "VK_EXT_debug_report"; | |
create_info.enabledExtensionCount = extensions_count + 1; | |
create_info.ppEnabledExtensionNames = extensions_ext; | |
// Create Vulkan Instance | |
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); | |
check_vk_result(err); | |
free(extensions_ext); | |
// Get the function pointer (required for any extensions) | |
auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT"); | |
IM_ASSERT(vkCreateDebugReportCallbackEXT != NULL); | |
// Setup the debug report callback | |
VkDebugReportCallbackCreateInfoEXT debug_report_ci = {}; | |
debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; | |
debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; | |
debug_report_ci.pfnCallback = debug_report; | |
debug_report_ci.pUserData = NULL; | |
err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport); | |
check_vk_result(err); | |
#else | |
// Create Vulkan Instance without any debug feature | |
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); | |
check_vk_result(err); | |
IM_UNUSED(g_DebugReport); | |
#endif | |
} | |
// Select GPU | |
{ | |
uint32_t gpu_count; | |
err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, NULL); | |
check_vk_result(err); | |
IM_ASSERT(gpu_count > 0); | |
VkPhysicalDevice* gpus = (VkPhysicalDevice*)malloc(sizeof(VkPhysicalDevice) * gpu_count); | |
err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus); | |
check_vk_result(err); | |
// If a number >1 of GPUs got reported, find discrete GPU if present, or use first one available. This covers | |
// most common cases (multi-gpu/integrated+dedicated graphics). Handling more complicated setups (multiple | |
// dedicated GPUs) is out of scope of this sample. | |
int use_gpu = 0; | |
for (int i = 0; i < (int)gpu_count; i++) | |
{ | |
VkPhysicalDeviceProperties properties; | |
vkGetPhysicalDeviceProperties(gpus[i], &properties); | |
if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) | |
{ | |
use_gpu = i; | |
break; | |
} | |
} | |
g_PhysicalDevice = gpus[use_gpu]; | |
free(gpus); | |
} | |
// Select graphics queue family | |
{ | |
uint32_t count; | |
vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, NULL); | |
VkQueueFamilyProperties* queues = (VkQueueFamilyProperties*)malloc(sizeof(VkQueueFamilyProperties) * count); | |
vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, queues); | |
for (uint32_t i = 0; i < count; i++) | |
if (queues[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) | |
{ | |
g_QueueFamily = i; | |
break; | |
} | |
free(queues); | |
IM_ASSERT(g_QueueFamily != (uint32_t)-1); | |
} | |
// Create Logical Device (with 1 queue) | |
{ | |
int device_extension_count = 1; | |
const char* device_extensions[] = { "VK_KHR_swapchain" }; | |
const float queue_priority[] = { 1.0f }; | |
VkDeviceQueueCreateInfo queue_info[1] = {}; | |
queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; | |
queue_info[0].queueFamilyIndex = g_QueueFamily; | |
queue_info[0].queueCount = 1; | |
queue_info[0].pQueuePriorities = queue_priority; | |
VkDeviceCreateInfo create_info = {}; | |
create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; | |
create_info.queueCreateInfoCount = sizeof(queue_info) / sizeof(queue_info[0]); | |
create_info.pQueueCreateInfos = queue_info; | |
create_info.enabledExtensionCount = device_extension_count; | |
create_info.ppEnabledExtensionNames = device_extensions; | |
err = vkCreateDevice(g_PhysicalDevice, &create_info, g_Allocator, &g_Device); | |
check_vk_result(err); | |
vkGetDeviceQueue(g_Device, g_QueueFamily, 0, &g_Queue); | |
} | |
// Create Descriptor Pool | |
{ | |
VkDescriptorPoolSize pool_sizes[] = | |
{ | |
{ VK_DESCRIPTOR_TYPE_SAMPLER, 1000 }, | |
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 }, | |
{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000 }, | |
{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000 }, | |
{ VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000 }, | |
{ VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000 }, | |
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000 }, | |
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 }, | |
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000 }, | |
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000 }, | |
{ VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000 } | |
}; | |
VkDescriptorPoolCreateInfo pool_info = {}; | |
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; | |
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; | |
pool_info.maxSets = 1000 * IM_ARRAYSIZE(pool_sizes); | |
pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes); | |
pool_info.pPoolSizes = pool_sizes; | |
err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool); | |
check_vk_result(err); | |
} | |
} | |
// All the ImGui_ImplVulkanH_XXX structures/functions are optional helpers used by the demo. | |
// Your real engine/app may not use them. | |
static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface, int width, int height) | |
{ | |
wd->Surface = surface; | |
// Check for WSI support | |
VkBool32 res; | |
vkGetPhysicalDeviceSurfaceSupportKHR(g_PhysicalDevice, g_QueueFamily, wd->Surface, &res); | |
if (res != VK_TRUE) | |
{ | |
fprintf(stderr, "Error no WSI support on physical device 0\n"); | |
exit(-1); | |
} | |
// Select Surface Format | |
const VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM }; | |
const VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; | |
wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(g_PhysicalDevice, wd->Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace); | |
// Select Present Mode | |
#ifdef IMGUI_UNLIMITED_FRAME_RATE | |
VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_FIFO_KHR }; | |
#else | |
VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_FIFO_KHR }; | |
#endif | |
wd->PresentMode = ImGui_ImplVulkanH_SelectPresentMode(g_PhysicalDevice, wd->Surface, &present_modes[0], IM_ARRAYSIZE(present_modes)); | |
//printf("[vulkan] Selected PresentMode = %d\n", wd->PresentMode); | |
// Create SwapChain, RenderPass, Framebuffer, etc. | |
IM_ASSERT(g_MinImageCount >= 2); | |
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount); | |
} | |
static void CleanupVulkan() | |
{ | |
vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator); | |
#ifdef IMGUI_VULKAN_DEBUG_REPORT | |
// Remove the debug report callback | |
auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT"); | |
vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator); | |
#endif // IMGUI_VULKAN_DEBUG_REPORT | |
vkDestroyDevice(g_Device, g_Allocator); | |
vkDestroyInstance(g_Instance, g_Allocator); | |
} | |
static void CleanupVulkanWindow() | |
{ | |
ImGui_ImplVulkanH_DestroyWindow(g_Instance, g_Device, &g_MainWindowData, g_Allocator); | |
} | |
static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data) | |
{ | |
VkResult err; | |
VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore; | |
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore; | |
err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex); | |
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR) | |
{ | |
g_SwapChainRebuild = true; | |
return; | |
} | |
check_vk_result(err); | |
ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex]; | |
{ | |
err = vkWaitForFences(g_Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX); // wait indefinitely instead of periodically checking | |
check_vk_result(err); | |
err = vkResetFences(g_Device, 1, &fd->Fence); | |
check_vk_result(err); | |
} | |
{ | |
err = vkResetCommandPool(g_Device, fd->CommandPool, 0); | |
check_vk_result(err); | |
VkCommandBufferBeginInfo info = {}; | |
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; | |
info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; | |
err = vkBeginCommandBuffer(fd->CommandBuffer, &info); | |
check_vk_result(err); | |
} | |
{ | |
VkRenderPassBeginInfo info = {}; | |
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; | |
info.renderPass = wd->RenderPass; | |
info.framebuffer = fd->Framebuffer; | |
info.renderArea.extent.width = wd->Width; | |
info.renderArea.extent.height = wd->Height; | |
info.clearValueCount = 1; | |
info.pClearValues = &wd->ClearValue; | |
vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE); | |
} | |
// Record dear imgui primitives into command buffer | |
ImGui_ImplVulkan_RenderDrawData(draw_data, fd->CommandBuffer); | |
// Submit command buffer | |
vkCmdEndRenderPass(fd->CommandBuffer); | |
{ | |
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; | |
VkSubmitInfo info = {}; | |
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; | |
info.waitSemaphoreCount = 1; | |
info.pWaitSemaphores = &image_acquired_semaphore; | |
info.pWaitDstStageMask = &wait_stage; | |
info.commandBufferCount = 1; | |
info.pCommandBuffers = &fd->CommandBuffer; | |
info.signalSemaphoreCount = 1; | |
info.pSignalSemaphores = &render_complete_semaphore; | |
err = vkEndCommandBuffer(fd->CommandBuffer); | |
check_vk_result(err); | |
err = vkQueueSubmit(g_Queue, 1, &info, fd->Fence); | |
check_vk_result(err); | |
} | |
} | |
static void FramePresent(ImGui_ImplVulkanH_Window* wd) | |
{ | |
if (g_SwapChainRebuild) | |
return; | |
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore; | |
VkPresentInfoKHR info = {}; | |
info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; | |
info.waitSemaphoreCount = 1; | |
info.pWaitSemaphores = &render_complete_semaphore; | |
info.swapchainCount = 1; | |
info.pSwapchains = &wd->Swapchain; | |
info.pImageIndices = &wd->FrameIndex; | |
VkResult err = vkQueuePresentKHR(g_Queue, &info); | |
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR) | |
{ | |
g_SwapChainRebuild = true; | |
return; | |
} | |
check_vk_result(err); | |
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->ImageCount; // Now we can use the next set of semaphores | |
} | |
int main(int, char**) | |
{ | |
// Setup SDL | |
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0) | |
{ | |
printf("Error: %s\n", SDL_GetError()); | |
return -1; | |
} | |
// Setup window | |
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); | |
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+Vulkan example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags); | |
// Setup Vulkan | |
uint32_t extensions_count = 0; | |
SDL_Vulkan_GetInstanceExtensions(window, &extensions_count, NULL); | |
const char** extensions = new const char*[extensions_count]; | |
SDL_Vulkan_GetInstanceExtensions(window, &extensions_count, extensions); | |
SetupVulkan(extensions, extensions_count); | |
delete[] extensions; | |
// Create Window Surface | |
VkSurfaceKHR surface; | |
VkResult err; | |
if (SDL_Vulkan_CreateSurface(window, g_Instance, &surface) == 0) | |
{ | |
printf("Failed to create Vulkan surface.\n"); | |
return 1; | |
} | |
// Create Framebuffers | |
int w, h; | |
SDL_GetWindowSize(window, &w, &h); | |
ImGui_ImplVulkanH_Window* wd = &g_MainWindowData; | |
SetupVulkanWindow(wd, surface, w, h); | |
// Setup Dear ImGui context | |
IMGUI_CHECKVERSION(); | |
ImGui::CreateContext(); | |
ImGuiIO& io = ImGui::GetIO(); (void)io; | |
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls | |
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls | |
// Setup Dear ImGui style | |
ImGui::StyleColorsDark(); | |
//ImGui::StyleColorsClassic(); | |
// Setup Platform/Renderer backends | |
ImGui_ImplSDL2_InitForVulkan(window); | |
ImGui_ImplVulkan_InitInfo init_info = {}; | |
init_info.Instance = g_Instance; | |
init_info.PhysicalDevice = g_PhysicalDevice; | |
init_info.Device = g_Device; | |
init_info.QueueFamily = g_QueueFamily; | |
init_info.Queue = g_Queue; | |
init_info.PipelineCache = g_PipelineCache; | |
init_info.DescriptorPool = g_DescriptorPool; | |
init_info.Allocator = g_Allocator; | |
init_info.MinImageCount = g_MinImageCount; | |
init_info.ImageCount = wd->ImageCount; | |
init_info.CheckVkResultFn = check_vk_result; | |
ImGui_ImplVulkan_Init(&init_info, wd->RenderPass); | |
// Load Fonts | |
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. | |
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. | |
// - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). | |
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. | |
// - Read 'docs/FONTS.md' for more instructions and details. | |
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! | |
//io.Fonts->AddFontDefault(); | |
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); | |
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); | |
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); | |
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); | |
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); | |
//IM_ASSERT(font != NULL); | |
// Upload Fonts | |
{ | |
// Use any command queue | |
VkCommandPool command_pool = wd->Frames[wd->FrameIndex].CommandPool; | |
VkCommandBuffer command_buffer = wd->Frames[wd->FrameIndex].CommandBuffer; | |
err = vkResetCommandPool(g_Device, command_pool, 0); | |
check_vk_result(err); | |
VkCommandBufferBeginInfo begin_info = {}; | |
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; | |
begin_info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; | |
err = vkBeginCommandBuffer(command_buffer, &begin_info); | |
check_vk_result(err); | |
ImGui_ImplVulkan_CreateFontsTexture(command_buffer); | |
VkSubmitInfo end_info = {}; | |
end_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; | |
end_info.commandBufferCount = 1; | |
end_info.pCommandBuffers = &command_buffer; | |
err = vkEndCommandBuffer(command_buffer); | |
check_vk_result(err); | |
err = vkQueueSubmit(g_Queue, 1, &end_info, VK_NULL_HANDLE); | |
check_vk_result(err); | |
err = vkDeviceWaitIdle(g_Device); | |
check_vk_result(err); | |
ImGui_ImplVulkan_DestroyFontUploadObjects(); | |
} | |
// Our state | |
bool show_demo_window = true; | |
bool show_another_window = false; | |
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); | |
// Main loop | |
bool done = false; | |
while (!done) | |
{ | |
// Poll and handle events (inputs, window resize, etc.) | |
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. | |
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. | |
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. | |
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. | |
SDL_Event event; | |
while (SDL_PollEvent(&event)) | |
{ | |
ImGui_ImplSDL2_ProcessEvent(&event); | |
if (event.type == SDL_QUIT) | |
done = true; | |
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window)) | |
done = true; | |
} | |
// Resize swap chain? | |
if (g_SwapChainRebuild) | |
{ | |
int width, height; | |
SDL_GetWindowSize(window, &width, &height); | |
if (width > 0 && height > 0) | |
{ | |
ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount); | |
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, width, height, g_MinImageCount); | |
g_MainWindowData.FrameIndex = 0; | |
g_SwapChainRebuild = false; | |
} | |
} | |
// Start the Dear ImGui frame | |
ImGui_ImplVulkan_NewFrame(); | |
ImGui_ImplSDL2_NewFrame(window); | |
ImGui::NewFrame(); | |
/* | |
ImGuiViewport* viewport = ImGui::GetMainViewport(); | |
ImGui::SetNextWindowPos(viewport->Pos); | |
ImGui::SetNextWindowSize(viewport->Size); | |
//ImGui::SetNextWindowViewport(viewport->ID); | |
ImGui::SetNextWindowBgAlpha(0.0f); | |
*/ | |
//ImGui::Begin("main",nullptr, ImGuiWindowFlags_NoDecoration, ImGuiWindowFlags_NoBackground); //nope | |
ImGuiWindowFlags flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings; | |
//ImGui::SetNextWindowBgAlpha(0.0f); | |
ImGui::SetNextWindowPos(ImVec2(0, 32.0f)); | |
ImGui::Begin("main",nullptr, flags); | |
if(ImGui::Button("my button") ){ | |
} | |
ImGui::End(); | |
/* | |
ImGui::Begin("main",nullptr, ImGuiWindowFlags_NoDecoration); | |
if(ImGui::Button("my button") ){ | |
} | |
ImGui::End(); | |
*/ | |
if(ImGui::BeginMainMenuBar()) | |
{ | |
if (ImGui::BeginMenu("File")) | |
{ | |
if(ImGui::MenuItem("New")) | |
{ | |
//Do something | |
} | |
ImGui::EndMenu(); | |
} | |
ImGui::EndMainMenuBar(); | |
} | |
// 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). | |
if (show_demo_window) | |
ImGui::ShowDemoWindow(&show_demo_window); | |
// 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. | |
{ | |
static float f = 0.0f; | |
static int counter = 0; | |
ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. | |
ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) | |
ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state | |
ImGui::Checkbox("Another Window", &show_another_window); | |
ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f | |
ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color | |
if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) | |
counter++; | |
ImGui::SameLine(); | |
ImGui::Text("counter = %d", counter); | |
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); | |
ImGui::End(); | |
} | |
// 3. Show another simple window. | |
if (show_another_window) | |
{ | |
ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) | |
ImGui::Text("Hello from another window!"); | |
if (ImGui::Button("Close Me")) | |
show_another_window = false; | |
ImGui::End(); | |
} | |
// Rendering | |
ImGui::Render(); | |
ImDrawData* draw_data = ImGui::GetDrawData(); | |
const bool is_minimized = (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f); | |
if (!is_minimized) | |
{ | |
wd->ClearValue.color.float32[0] = clear_color.x * clear_color.w; | |
wd->ClearValue.color.float32[1] = clear_color.y * clear_color.w; | |
wd->ClearValue.color.float32[2] = clear_color.z * clear_color.w; | |
wd->ClearValue.color.float32[3] = clear_color.w; | |
FrameRender(wd, draw_data); | |
FramePresent(wd); | |
} | |
} | |
// Cleanup | |
err = vkDeviceWaitIdle(g_Device); | |
check_vk_result(err); | |
ImGui_ImplVulkan_Shutdown(); | |
ImGui_ImplSDL2_Shutdown(); | |
ImGui::DestroyContext(); | |
CleanupVulkanWindow(); | |
CleanupVulkan(); | |
SDL_DestroyWindow(window); | |
SDL_Quit(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment