Pull request #2: CONGE-2 SDL WINDOW
Merge in CONGE/conjure-engine from CONGE-2-SDL-WINDOW to main * commit 'b4a706ca12766ef09d17b0987835e3e53d08c086': CONGE-2 UPDATED CMAKE CONFIG CONGE-2 MADE THE MAC COMPILATION WORK CONGE-2 ADDED THE SHADER COMPILATION FROM GLSL TO SPIRV CONGE-2 Added better login in Demo1 and added error handling in VulkanContext.cpp CONGE-2 Reworked the API for the application to move more of the logic and initialization to the Engine and just have the application specifics in Demo1 CONGE-2 Tweaked the logic to handle cases where presentation queue is not available instead of using #ifndef CONGE-2 REMOVED PRESENTATION QUEUE ON MAC CONGE-2 working window on windows. Need to test on mac CONGE-2 BUG with windows CONGE-2 added the basic setup to open a windows on mac and windows CONGE-2 : (WIP) adding the basic structure for the engine CONGE-1 fixed mac version CONGE-1 Special case between windows and mac. Will have to test if it's the case on other machines CONGE-1 This work in mac CONGE-1 Fixed some issues to make it cross compatible with clion, vscode and vs studio CONGE-1 Made it work for windows and mac for both release and debug CONGE-1 - added support for bat files and README.md CONGE-1 - Setup that works with conan and cmake
This commit is contained in:
commit
2f7176759f
4
.gitignore
vendored
4
.gitignore
vendored
@ -10,4 +10,6 @@ CMakeCache.txt
|
||||
build.ninja
|
||||
cmake_install.cmake
|
||||
CMakeCache.txt
|
||||
.ninja*
|
||||
CMakeUserPresets.json
|
||||
.ninja*
|
||||
.vs/
|
||||
@ -1,19 +1,37 @@
|
||||
cmake_minimum_required(VERSION 3.29)
|
||||
cmake_minimum_required(VERSION 3.26)
|
||||
project(ConjureEngineProject)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
# Set the default build type to Debug if not specified by the user
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Build type (default Debug)" FORCE)
|
||||
endif()
|
||||
|
||||
set(CONAN_DEPENDENCIES_DIR ${CMAKE_BINARY_DIR}/Conan)
|
||||
message(${CMAKE_BUILD_TYPE})
|
||||
|
||||
execute_process(COMMAND conan install ${CMAKE_SOURCE_DIR}/ConjureEngine --output-folder=${CONAN_DEPENDENCIES_DIR} --build=missing)
|
||||
execute_process(COMMAND conan install ${CMAKE_SOURCE_DIR}/Demo1 --output-folder=${CONAN_DEPENDENCIES_DIR} --build=missing)
|
||||
# Set architecture
|
||||
if(NOT DEFINED ARCH)
|
||||
set(ARCH x64) # Default to x64 architecture
|
||||
endif()
|
||||
|
||||
set(CMAKE_TOOLCHAIN_FILE "${CONAN_DEPENDENCIES_DIR}/build/Release/generators/conan_toolchain.cmake" CACHE FILEPATH "Conan toolchain file")
|
||||
set(CMAKE_PREFIX_PATH "${CONAN_DEPENDENCIES_DIR}/build/Release/generators" ${CMAKE_PREFIX_PATH})
|
||||
set(CMAKE_MODULE_PATH "${CONAN_DEPENDENCIES_DIR}/build/Release/generators" ${CMAKE_MODULE_PATH})
|
||||
set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/build)
|
||||
|
||||
# Include the Conan-generated files
|
||||
|
||||
IF (WIN32)
|
||||
list(APPEND CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}/generators")
|
||||
include("${CMAKE_BINARY_DIR}/generators/conan_toolchain.cmake")
|
||||
ELSE()
|
||||
list(APPEND CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/generators")
|
||||
include("${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/generators/conan_toolchain.cmake")
|
||||
ENDIF()
|
||||
|
||||
# Set common output directories
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/intermediates/${CMAKE_BUILD_TYPE}/${ARCH}/${PROJECT_NAME})
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/${CMAKE_BUILD_TYPE}/${ARCH}/${PROJECT_NAME})
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/${CMAKE_BUILD_TYPE}/${ARCH}/${PROJECT_NAME})
|
||||
|
||||
# Add subdirectories for engine and demo
|
||||
add_subdirectory(./ConjureEngine)
|
||||
add_subdirectory(./Demo1)
|
||||
add_subdirectory(./Demo1)
|
||||
|
||||
8
Configure.bat
Normal file
8
Configure.bat
Normal file
@ -0,0 +1,8 @@
|
||||
@REM Run Conan to install dependencies
|
||||
rmdir build /s /q
|
||||
|
||||
@REM DEBUG
|
||||
conan install . -s build_type=Debug --build=missing
|
||||
|
||||
@REM RELEASE
|
||||
conan install . -s build_type=Release --build=missing
|
||||
10
Configure.sh
Executable file
10
Configure.sh
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Run Conan to install dependencies
|
||||
rm -Rf build
|
||||
|
||||
# DEBUG
|
||||
conan install . -s build_type=Debug --build=missing
|
||||
|
||||
# RELEASE
|
||||
conan install . -s build_type=Release --build=missing
|
||||
@ -1,27 +1,36 @@
|
||||
cmake_minimum_required(VERSION 3.29)
|
||||
cmake_minimum_required(VERSION 3.26)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
project(ConjureEngine)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(HEADER_FILES
|
||||
src/ConjureEngine/Application.h
|
||||
src/ConjureEngine/ConjureEngine.h
|
||||
src/ConjureEngine/VulkanContext.h
|
||||
src/ConjureEngine/Window.h
|
||||
)
|
||||
|
||||
# Set the architecture (assuming you're passing the architecture as a CMake variable)
|
||||
# Replace 'x64' with your system's architecture, or set this dynamically based on the system
|
||||
if(NOT DEFINED ARCH)
|
||||
set(ARCH x64) # You can change this to x86 or any other architecture you are targeting
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
# Set common output directories
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/intermediates/${ARCH}/${PROJECT_NAME})
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/${ARCH}/${PROJECT_NAME})
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/${ARCH}/${PROJECT_NAME})
|
||||
set(SOURCES_FILES
|
||||
src/ConjureEngine/Application.cpp
|
||||
src/ConjureEngine/VulkanContext.cpp
|
||||
src/ConjureEngine/Window.cpp
|
||||
)
|
||||
|
||||
find_package(glm REQUIRED)
|
||||
find_package(SDL2 REQUIRED)
|
||||
find_package(Vulkan REQUIRED)
|
||||
|
||||
add_library(${PROJECT_NAME} STATIC src/ConjureEngine/ConjureEngine.h src/ConjureEngine/ConjureEngine.cpp)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS})
|
||||
add_library(${PROJECT_NAME} STATIC ${HEADER_FILES} ${SOURCES_FILES})
|
||||
|
||||
# Specify include directories
|
||||
target_include_directories(ConjureEngine PUBLIC include)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC include)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_BINARY_DIR}/include)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} SDL2::SDL2 glm::glm Vulkan::Vulkan)
|
||||
|
||||
target_precompile_headers(
|
||||
${PROJECT_NAME}
|
||||
PRIVATE
|
||||
src/ConjureEngine/PCH.h
|
||||
)
|
||||
41
ConjureEngine/docs/RenderingPipelineSteps.mmd
Normal file
41
ConjureEngine/docs/RenderingPipelineSteps.mmd
Normal file
@ -0,0 +1,41 @@
|
||||
---
|
||||
title: Rendering Pipeline Steps
|
||||
---
|
||||
stateDiagram-v2
|
||||
direction LR
|
||||
state "Data" as Data1
|
||||
state "Vertex Shader" as VertexShader1
|
||||
state "Tesselation Shader" as TesselationShader1
|
||||
state "Rasterization" as Rasterization1
|
||||
state "Fragment Shader" as FragmentShader1
|
||||
state "Blending" as Blending1
|
||||
state "Texture" as Texture1
|
||||
|
||||
state "Texture" as Texture2
|
||||
state "Vertex Shader" as VertexShader2
|
||||
state "Tesselation Shader" as TesselationShader2
|
||||
state "Rasterization" as Rasterization2
|
||||
state "Fragment Shader" as FragmentShader2
|
||||
state "Blending" as Blending2
|
||||
state "Frame Buffer" as FrameBuffer2
|
||||
|
||||
Data1 --> VertexShader1
|
||||
state "Pass 1" as Pass1{
|
||||
direction LR
|
||||
VertexShader1 --> TesselationShader1
|
||||
TesselationShader1 --> Rasterization1
|
||||
Rasterization1 --> FragmentShader1
|
||||
FragmentShader1 --> Blending1
|
||||
}
|
||||
Blending1 --> Texture1
|
||||
|
||||
|
||||
Texture2 --> VertexShader2
|
||||
state "Pass 2" as Pass2{
|
||||
direction LR
|
||||
VertexShader2 --> TesselationShader2
|
||||
TesselationShader2 --> Rasterization2
|
||||
Rasterization2 --> FragmentShader2
|
||||
FragmentShader2 --> Blending2
|
||||
}
|
||||
Blending2 --> FrameBuffer2
|
||||
24
ConjureEngine/docs/class.mmd
Normal file
24
ConjureEngine/docs/class.mmd
Normal file
@ -0,0 +1,24 @@
|
||||
classDiagram
|
||||
namespace ConjureEngine {
|
||||
class Application {
|
||||
+ Run() int
|
||||
+ Tick(double deltaTime) void
|
||||
}
|
||||
|
||||
class Window {
|
||||
+ std::shared_ptr~SDL_Window~ m_window;
|
||||
+ std::shared_ptr~VulkanContext~ m_vulkanContext;
|
||||
}
|
||||
|
||||
class VulkanContext {
|
||||
- uint32_t m_extensionCount
|
||||
- char** m_extensionNames
|
||||
- VkInstance m_vkInst
|
||||
- uint32_t m_physicalDeviceCount
|
||||
- std::vector~VkPhysicalDevice~ m_physicalDevices
|
||||
- VkPhysicalDevice m_selectedDevice
|
||||
- uint32_t m_queueFamilyCount
|
||||
}
|
||||
}
|
||||
|
||||
Window "1" *-- "1" VulkanContext
|
||||
28
ConjureEngine/docs/renderingPipeline.mmd
Normal file
28
ConjureEngine/docs/renderingPipeline.mmd
Normal file
@ -0,0 +1,28 @@
|
||||
---
|
||||
title: Rendering Pipeline
|
||||
---
|
||||
classDiagram
|
||||
class VAO
|
||||
class VBO
|
||||
class Shader
|
||||
class Pipeline0
|
||||
class Pipeline1
|
||||
class Pipeline2
|
||||
|
||||
class Entity0
|
||||
class Entity1
|
||||
class Entity2
|
||||
|
||||
Entity0 -- Pipeline0
|
||||
Entity0 -- Pipeline1
|
||||
Entity0 -- Pipeline2
|
||||
|
||||
Entity1 -- Pipeline0
|
||||
Entity1 -- Pipeline1
|
||||
|
||||
Entity2 -- Pipeline1
|
||||
Entity2 -- Pipeline2
|
||||
|
||||
Pipeline0 -- Shader
|
||||
Pipeline1 -- Shader
|
||||
Pipeline2 -- Shader
|
||||
62
ConjureEngine/src/ConjureEngine/Application.cpp
Normal file
62
ConjureEngine/src/ConjureEngine/Application.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
//
|
||||
// Created by calap on 11/21/2024.
|
||||
//
|
||||
|
||||
#include "Application.h"
|
||||
#include "VulkanContext.h"
|
||||
|
||||
namespace ConjureEngine {
|
||||
Application::Application(const ApplicationInfo &applicationInfo): m_applicationInfo(applicationInfo) {
|
||||
// Fill the application information
|
||||
m_vkAppInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||
m_vkAppInfo.pApplicationName = applicationInfo.title.c_str();
|
||||
m_vkAppInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
|
||||
m_vkAppInfo.pEngineName = "Conjure Engine";
|
||||
m_vkAppInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
|
||||
m_vkAppInfo.apiVersion = VK_API_VERSION_1_0;
|
||||
}
|
||||
|
||||
int Application::Run()
|
||||
{
|
||||
// CREATE SDL WINDOW
|
||||
Window window(this->m_applicationInfo.title.c_str(), m_applicationInfo.window);
|
||||
|
||||
// INIT VULKAN
|
||||
VulkanContext vulkanContext;
|
||||
vulkanContext.AttachTo(window.GetWindow(), this->m_vkAppInfo);
|
||||
|
||||
// INITIALIZATION OF THE WORLD
|
||||
this->Awake();
|
||||
this->Start();
|
||||
|
||||
// MAIN LOOP
|
||||
bool running = true;
|
||||
|
||||
static uint64_t lastTick = SDL_GetTicks64(); // TIME IS IN MS
|
||||
while (running) {
|
||||
|
||||
|
||||
// HANDLE INPUTS HERE (CODE BELOW IS FROM A TUTORIAL)
|
||||
SDL_Event windowEvent;
|
||||
while (SDL_PollEvent(&windowEvent)) {
|
||||
if (windowEvent.type == SDL_QUIT) {
|
||||
running = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// TICK SCENE HERE
|
||||
const uint64_t currentTick = SDL_GetTicks64(); // TIME IS IN MS
|
||||
const uint64_t deltaTime = currentTick - lastTick; // TIME IS IN MS
|
||||
this->Tick(static_cast<double>(deltaTime)/1000.f);
|
||||
|
||||
// HANDLE PHYSICS HERE
|
||||
lastTick = currentTick;
|
||||
}
|
||||
|
||||
// CLEANUP HERE
|
||||
this->Destroy();
|
||||
|
||||
return 0;
|
||||
}
|
||||
} // ConjureEngine
|
||||
56
ConjureEngine/src/ConjureEngine/Application.h
Normal file
56
ConjureEngine/src/ConjureEngine/Application.h
Normal file
@ -0,0 +1,56 @@
|
||||
//
|
||||
// Created by calap on 11/21/2024.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "PCH.h"
|
||||
#include "Window.h"
|
||||
|
||||
namespace ConjureEngine {
|
||||
struct ApplicationInfo {
|
||||
std::string title;
|
||||
WindowInfo window{
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
};
|
||||
|
||||
class Application {
|
||||
public:
|
||||
explicit Application(const ApplicationInfo &applicationInfo);
|
||||
virtual ~Application() = default;
|
||||
|
||||
int Run();
|
||||
|
||||
/**
|
||||
* First function call right after SDL and VULKAN are init
|
||||
*/
|
||||
virtual inline void Awake() {};
|
||||
|
||||
/**
|
||||
* Called after awake is done
|
||||
*/
|
||||
virtual inline void Start() {};
|
||||
|
||||
/**
|
||||
* Called every frame after Start
|
||||
* @param deltaTime Time in seconds since last call to Tick
|
||||
*/
|
||||
virtual inline void Tick(double deltaTime) {}
|
||||
|
||||
/**
|
||||
* Call when the application is being closed
|
||||
*/
|
||||
virtual inline void Destroy() {};
|
||||
|
||||
|
||||
protected:
|
||||
public:
|
||||
protected:
|
||||
ApplicationInfo m_applicationInfo;
|
||||
VkApplicationInfo m_vkAppInfo{};
|
||||
};
|
||||
} // ConjureEngine
|
||||
@ -1,10 +0,0 @@
|
||||
//
|
||||
// Created by Jimmy Tremblay-bernier on 2024-11-14.
|
||||
//
|
||||
#include "ConjureEngine.h"
|
||||
#include <cstdio>
|
||||
|
||||
void ConjureEngine::SayHello()
|
||||
{
|
||||
printf("Hello World\n");
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
namespace ConjureEngine {
|
||||
void SayHello();
|
||||
}
|
||||
|
||||
#include "Application.h"
|
||||
#include "VulkanContext.h"
|
||||
#include "Window.h"
|
||||
|
||||
22
ConjureEngine/src/ConjureEngine/PCH.h
Normal file
22
ConjureEngine/src/ConjureEngine/PCH.h
Normal file
@ -0,0 +1,22 @@
|
||||
//
|
||||
// Created by calap on 11/21/2024.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
// STANDARD LIBS
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// GLM
|
||||
#include "glm/glm.hpp"
|
||||
|
||||
// SDL2
|
||||
#include "SDL2/SDL.h"
|
||||
#include "SDL2/SDL_vulkan.h"
|
||||
#include "SDL2/SDL_video.h"
|
||||
|
||||
// VULKAN
|
||||
#include "vulkan/vulkan.h"
|
||||
#include "vulkan/vulkan_core.h"
|
||||
201
ConjureEngine/src/ConjureEngine/VulkanContext.cpp
Normal file
201
ConjureEngine/src/ConjureEngine/VulkanContext.cpp
Normal file
@ -0,0 +1,201 @@
|
||||
//
|
||||
// Created by Jimmy Tremblay-bernier on 2024-11-22.
|
||||
//
|
||||
|
||||
#include "VulkanContext.h"
|
||||
|
||||
#include "Window.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "vulkan/vulkan_metal.h"
|
||||
#endif
|
||||
|
||||
namespace ConjureEngine {
|
||||
VulkanContext::VulkanContext()= default;
|
||||
|
||||
void VulkanContext::AttachTo(SDL_Window* window, const VkApplicationInfo& appInfo)
|
||||
{
|
||||
// LOAD THE EXTENSIONS
|
||||
SDL_bool sdlSuccess;
|
||||
VkResult vk_result;
|
||||
|
||||
// FETCH NUMBER OF EXTENSIONS TO RESERVE SPACE IN VECTOR
|
||||
sdlSuccess = SDL_Vulkan_GetInstanceExtensions(window, &m_extensionCount, nullptr);
|
||||
if(sdlSuccess != SDL_TRUE)
|
||||
{
|
||||
SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Error Getting Extensions: %s", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
m_extensionNames.reserve(m_extensionCount);
|
||||
|
||||
// FILLING UP THE VECTOR
|
||||
sdlSuccess = SDL_Vulkan_GetInstanceExtensions(window, &m_extensionCount, m_extensionNames.data());
|
||||
if(sdlSuccess != SDL_TRUE)
|
||||
{
|
||||
SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Error Getting Extensions: %s", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM,"FETCHING OF EXTENSION FINISHED SUCCESSFULLY");
|
||||
}
|
||||
|
||||
// Fill the instance create info struct using appInfo
|
||||
VkInstanceCreateInfo vulkanInfos{};
|
||||
vulkanInfos.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
vulkanInfos.pApplicationInfo = &appInfo;
|
||||
|
||||
// ENABLE THE REQUIRED EXTENSIONS
|
||||
this->EnableGlobalExtentions(window, vulkanInfos);
|
||||
|
||||
// CREATE THE VULKAN INSTANCE
|
||||
vk_result = vkCreateInstance(&vulkanInfos, nullptr, &m_vkInst);
|
||||
if(vk_result != VkResult::VK_SUCCESS) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Error while creating the device: CODE = %d", static_cast<int>(vk_result));
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM,"VULKAN INSTANCE CREATED SUCCESSFULLY");
|
||||
}
|
||||
|
||||
// FETCH THE NUMBER OF PHYSICAL DEVICES (GPUs) TO RESERVE SPACE INTHE VECTOR
|
||||
vk_result = vkEnumeratePhysicalDevices(m_vkInst, &m_physicalDeviceCount, nullptr);
|
||||
if(vk_result != VkResult::VK_SUCCESS) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Error while enumerating physical devices: CODE = %d", static_cast<int>(vk_result));
|
||||
exit(1);
|
||||
}
|
||||
m_physicalDevices = std::vector<VkPhysicalDevice>(m_physicalDeviceCount);
|
||||
|
||||
// FILL THE VECTOR WITH ACTUAL DEVICES DATA
|
||||
vk_result = vkEnumeratePhysicalDevices(m_vkInst, &m_physicalDeviceCount, m_physicalDevices.data());
|
||||
if(vk_result != VkResult::VK_SUCCESS) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Error while enumerating physical devices: CODE = %d", static_cast<int>(vk_result));
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "VULKAN ENUMERATION OF PHYSICAL DEVICES FINISHED SUCCESSFULLY");
|
||||
}
|
||||
|
||||
// SELECT THE MAIN GPU (WE COULD HAVE A SMARTER SELECTION LATER. FOR NOW, WE SELECT THE FIRST ONE WE SEE)
|
||||
m_selectedPhysicalDevice = m_physicalDevices[0];
|
||||
|
||||
// FETCH THE QUANTITY OF FAMILY QUEUE TO RESERVE SPACE IN THE VECTOR
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(m_selectedPhysicalDevice, &m_queueFamilyCount, nullptr);
|
||||
std::vector<VkQueueFamilyProperties> queueFamilies(m_queueFamilyCount);
|
||||
|
||||
// FILL THE VECTOR WITH ACTUAL QUEUE DATA
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(m_selectedPhysicalDevice, &m_queueFamilyCount, queueFamilies.data());
|
||||
|
||||
// CREATE THE SURFACE FOR RENDERING
|
||||
sdlSuccess = SDL_Vulkan_CreateSurface(window, m_vkInst, &m_surface);
|
||||
if(sdlSuccess != SDL_TRUE)
|
||||
{
|
||||
SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Error Getting Extensions: %s", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "VULKAN SURFACE CREATED SUCCESSFULLY");
|
||||
}
|
||||
|
||||
// NOT SURE WHAT THIS DOES YET, WILL CHECK IN THE TUTORIAL
|
||||
uint32_t graphicsQueueIndex = UINT32_MAX;
|
||||
uint32_t presentQueueIndex = UINT32_MAX;
|
||||
VkBool32 support;
|
||||
uint32_t i = 0;
|
||||
for (VkQueueFamilyProperties queueFamily: queueFamilies) {
|
||||
if (graphicsQueueIndex == UINT32_MAX && queueFamily.queueCount > 0 && queueFamily.queueFlags &
|
||||
VK_QUEUE_GRAPHICS_BIT)
|
||||
graphicsQueueIndex = i;
|
||||
if (presentQueueIndex == UINT32_MAX) {
|
||||
vk_result = vkGetPhysicalDeviceSurfaceSupportKHR(m_selectedPhysicalDevice, i, m_surface, &support);
|
||||
if(vk_result != VkResult::VK_SUCCESS) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Error while checking the surface capability: CODE = %d", static_cast<int>(vk_result));
|
||||
}
|
||||
|
||||
if (support)
|
||||
presentQueueIndex = i;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
//
|
||||
float queuePriority = 1.0f;
|
||||
m_deviceQueueCreateInfo = {
|
||||
VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
|
||||
nullptr, // pNext
|
||||
0, // flags
|
||||
graphicsQueueIndex, // graphicsQueueIndex
|
||||
1, // queueCount
|
||||
&queuePriority, // pQueuePriorities
|
||||
};
|
||||
|
||||
// FETCH THE PHYSICAL DEVICES FEATURES
|
||||
VkPhysicalDeviceFeatures deviceFeatures = {};
|
||||
const char *deviceExtensionNames[] = {VK_KHR_SWAPCHAIN_EXTENSION_NAME};
|
||||
m_deviceCreateInfo = {
|
||||
VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
|
||||
nullptr, // pNext
|
||||
0, // flags
|
||||
1, // queueCreateInfoCount
|
||||
&m_deviceQueueCreateInfo, // pQueueCreateInfos
|
||||
0, // enabledLayerCount
|
||||
nullptr, // ppEnabledLayerNames
|
||||
1, // enabledExtensionCount
|
||||
deviceExtensionNames, // ppEnabledExtensionNames
|
||||
&deviceFeatures, // pEnabledFeatures
|
||||
};
|
||||
|
||||
|
||||
// CREATE VIRTUAL DEVICE FOR RENDERING
|
||||
vk_result = vkCreateDevice(m_selectedPhysicalDevice, &m_deviceCreateInfo, nullptr, &m_device);
|
||||
if(vk_result != VkResult::VK_SUCCESS) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Error while creating the device: %d", static_cast<int>(vk_result));
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_SYSTEM, "DEVICE CREATED SUCCESSFULLY");
|
||||
}
|
||||
|
||||
vkGetDeviceQueue(m_device, graphicsQueueIndex, 0, &m_graphicQueue);
|
||||
|
||||
// WHEN POSSIBLE, WE WANT TO USE THE PRESENTATION QUEUE, BUT MAC DOESN'T SUPPORT IT
|
||||
if(presentQueueIndex != UINT32_MAX) {
|
||||
m_supportsPresentationQueue = true;
|
||||
vkGetDeviceQueue(m_device, presentQueueIndex, 0, &m_presentQueue);
|
||||
}
|
||||
|
||||
|
||||
const std::string error = SDL_GetError();
|
||||
if(!error.empty()) {
|
||||
SDL_Log("Initialized with errors: %s", error.c_str());
|
||||
}
|
||||
else {
|
||||
SDL_Log("Initialized without errors");
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanContext::EnableGlobalExtentions(SDL_Window* window, VkInstanceCreateInfo &vulkanInfos) {
|
||||
SDL_Vulkan_GetInstanceExtensions(window, &m_extensionCount, nullptr);
|
||||
this->m_extensionNames.reserve(m_extensionCount);
|
||||
SDL_Vulkan_GetInstanceExtensions(window, &m_extensionCount, m_extensionNames.data());
|
||||
|
||||
#ifdef __APPLE__
|
||||
this->m_extensionNames.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
|
||||
this->m_extensionNames.push_back(VK_EXT_METAL_SURFACE_EXTENSION_NAME);
|
||||
vulkanInfos.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
|
||||
#endif
|
||||
|
||||
#ifdef __WIN32__
|
||||
this->m_extensionNames.push_back("VK_KHR_win32_surface");
|
||||
#endif
|
||||
|
||||
vulkanInfos.enabledExtensionCount = static_cast<uint32_t>(this->m_extensionNames.size());
|
||||
vulkanInfos.ppEnabledExtensionNames = this->m_extensionNames.data();
|
||||
}
|
||||
|
||||
VulkanContext::~VulkanContext() {
|
||||
vkDestroyDevice(m_device, nullptr);
|
||||
vkDestroyInstance(m_vkInst, nullptr);
|
||||
}
|
||||
} // ConjureEngine
|
||||
34
ConjureEngine/src/ConjureEngine/VulkanContext.h
Normal file
34
ConjureEngine/src/ConjureEngine/VulkanContext.h
Normal file
@ -0,0 +1,34 @@
|
||||
//
|
||||
// Created by Jimmy Tremblay-bernier on 2024-11-22.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ConjureEngine {
|
||||
#include "PCH.h"
|
||||
|
||||
class VulkanContext {
|
||||
public:
|
||||
explicit VulkanContext();
|
||||
~VulkanContext();
|
||||
void AttachTo(SDL_Window* window, const VkApplicationInfo& appInfo);
|
||||
private:
|
||||
void EnableGlobalExtentions(SDL_Window* window, VkInstanceCreateInfo &vulkanInfos);
|
||||
|
||||
private:
|
||||
uint32_t m_extensionCount{0};
|
||||
std::vector<const char*> m_extensionNames;
|
||||
VkInstance m_vkInst{nullptr};
|
||||
uint32_t m_physicalDeviceCount{0};
|
||||
std::vector<VkPhysicalDevice> m_physicalDevices;
|
||||
VkPhysicalDevice m_selectedPhysicalDevice{nullptr};
|
||||
uint32_t m_queueFamilyCount{0};
|
||||
VkSurfaceKHR m_surface{nullptr};
|
||||
VkDeviceQueueCreateInfo m_deviceQueueCreateInfo{};
|
||||
VkDeviceCreateInfo m_deviceCreateInfo{};
|
||||
VkDevice m_device{nullptr};
|
||||
VkQueue m_graphicQueue{nullptr};
|
||||
VkQueue m_presentQueue{nullptr};
|
||||
bool m_supportsPresentationQueue = false;
|
||||
};
|
||||
} // ConjureEngine
|
||||
33
ConjureEngine/src/ConjureEngine/Window.cpp
Normal file
33
ConjureEngine/src/ConjureEngine/Window.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
//
|
||||
// Created by calap on 11/21/2024.
|
||||
//
|
||||
#include "Window.h"
|
||||
|
||||
namespace ConjureEngine {
|
||||
|
||||
Window::Window(const char* title, const WindowInfo& windowInfo)
|
||||
{
|
||||
// INIT WINDOW
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
SDL_Vulkan_LoadLibrary(nullptr);
|
||||
|
||||
m_window = SDL_CreateWindow(title, 0, 32, windowInfo.width, windowInfo.height, SDL_WINDOW_SHOWN | SDL_WINDOW_VULKAN);
|
||||
}
|
||||
|
||||
Window::~Window() {
|
||||
SDL_DestroyWindow(m_window);
|
||||
SDL_Vulkan_UnloadLibrary();
|
||||
SDL_Quit();
|
||||
|
||||
std::string error = SDL_GetError();
|
||||
if(!error.empty())
|
||||
{
|
||||
SDL_Log("Cleaned up with errors: %s", error.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Window* Window::GetWindow() const
|
||||
{
|
||||
return m_window;
|
||||
}
|
||||
} // ConjureEngine
|
||||
30
ConjureEngine/src/ConjureEngine/Window.h
Normal file
30
ConjureEngine/src/ConjureEngine/Window.h
Normal file
@ -0,0 +1,30 @@
|
||||
//
|
||||
// Created by calap on 11/21/2024.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "PCH.h"
|
||||
|
||||
namespace ConjureEngine
|
||||
{
|
||||
struct WindowInfo {
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
class Window {
|
||||
public:
|
||||
explicit Window(const char* title, const WindowInfo &windowInfo);
|
||||
|
||||
~Window();
|
||||
|
||||
SDL_Window* GetWindow() const;
|
||||
private:
|
||||
public:
|
||||
private:
|
||||
SDL_Window* m_window;
|
||||
};
|
||||
} // ConjureEngine
|
||||
4
Demo1/.gitignore
vendored
4
Demo1/.gitignore
vendored
@ -1,3 +1,5 @@
|
||||
CMakeFiles/
|
||||
cmake_install.cmake
|
||||
CMakeUserPresets.json
|
||||
CMakeUserPresets.json
|
||||
CompileShaders.log
|
||||
**/*.spv
|
||||
@ -1,23 +1,30 @@
|
||||
cmake_minimum_required(VERSION 3.29)
|
||||
cmake_minimum_required(VERSION 3.26)
|
||||
project(Demo1)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
# Set the architecture (assuming you're passing the architecture as a CMake variable)
|
||||
# Replace 'x64' with your system's architecture, or set this dynamically based on the system
|
||||
if(NOT DEFINED ARCH)
|
||||
set(ARCH x64) # You can change this to x86 or any other architecture you are targeting
|
||||
endif()
|
||||
find_package(Python3 REQUIRED COMPONENTS Interpreter)
|
||||
|
||||
# Set common output directories
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/intermediates/${ARCH}/${PROJECT_NAME})
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/${ARCH}/${PROJECT_NAME})
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/${ARCH}/${PROJECT_NAME})
|
||||
add_executable(${PROJECT_NAME}
|
||||
src/main.cpp
|
||||
src/Demo1.cpp
|
||||
src/Demo1.h
|
||||
)
|
||||
|
||||
add_executable(${PROJECT_NAME} src/main.cpp)
|
||||
# CREATE CUSTOM TARGET THAT COMPILE SHADERS EVERY BUILD
|
||||
add_custom_target(shader_compilation ALL
|
||||
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/CompileShaders.py ${CMAKE_CURRENT_SOURCE_DIR}/src/Shaders ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT "Compiling shaders"
|
||||
)
|
||||
|
||||
# ADD THE CUSTOM TARGET AS A DEPENDENCY OF DEMO1
|
||||
add_dependencies(${PROJECT_NAME} shader_compilation)
|
||||
|
||||
target_link_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/ConjureEngine)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS} ConjureEngine)
|
||||
find_package(SDL2 REQUIRED)
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE include)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/ConjureEngine/src)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} SDL2::SDL2 ConjureEngine)
|
||||
46
Demo1/CompileShaders.py
Normal file
46
Demo1/CompileShaders.py
Normal file
@ -0,0 +1,46 @@
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import logging
|
||||
|
||||
os.chdir(sys.argv[1])
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(
|
||||
filename=os.path.join(sys.argv[2], "CompileShaders.log"), # Log file name
|
||||
filemode="w", # Append mode (use "w" for overwrite)
|
||||
format="%(asctime)s - %(levelname)s - %(message)s", # Log format
|
||||
level=logging.INFO # Logging level
|
||||
)
|
||||
|
||||
def filterFunc(fileName):
|
||||
params = fileName.split(".")
|
||||
return params[len(params) - 1] != "spv"
|
||||
|
||||
def __main__():
|
||||
|
||||
SHADERS_PATH = os.path.join(os.getcwd())
|
||||
if os.name == "nt":
|
||||
GLSLC_PATH = os.path.join(os.environ.get("VULKAN_SDK"), "bin", "glslc")
|
||||
else:
|
||||
GLSLC_PATH = "/usr/local/bin/glslc"
|
||||
|
||||
logging.info(str.join(" ", ["SHADER PATH:", SHADERS_PATH]))
|
||||
logging.info(str.join(" ", ["GLSLC PATH:", GLSLC_PATH]))
|
||||
|
||||
shaders = filter(filterFunc, os.listdir(SHADERS_PATH))
|
||||
for shader in shaders:
|
||||
name, ext = shader.split(".")
|
||||
|
||||
command = GLSLC_PATH
|
||||
args = [
|
||||
os.path.join(SHADERS_PATH, shader),
|
||||
"-o",
|
||||
os.path.join(SHADERS_PATH, name + "." + ext + ".spv")
|
||||
]
|
||||
|
||||
logging.info(str.join(" ", ["Compiling:", shader]))
|
||||
logging.info(str.join(" ", [command] + args))
|
||||
subprocess.Popen([command] + args)
|
||||
if __name__ == "__main__":
|
||||
__main__()
|
||||
@ -1,8 +0,0 @@
|
||||
[requires]
|
||||
|
||||
[generators]
|
||||
CMakeDeps
|
||||
CMakeToolchain
|
||||
|
||||
[layout]
|
||||
cmake_layout
|
||||
42
Demo1/src/Demo1.cpp
Normal file
42
Demo1/src/Demo1.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
//
|
||||
// Created by Jimmy Tremblay-bernier on 2024-11-22.
|
||||
//
|
||||
|
||||
#include "Demo1.h"
|
||||
#include "ConjureEngine/ConjureEngine.h"
|
||||
|
||||
static ConjureEngine::ApplicationInfo appInfo = ConjureEngine::ApplicationInfo
|
||||
{
|
||||
"Demo1",
|
||||
ConjureEngine::WindowInfo {
|
||||
0,
|
||||
0,
|
||||
1920,
|
||||
1080
|
||||
}
|
||||
};
|
||||
|
||||
namespace Demo1 {
|
||||
Demo1::Demo1(): ConjureEngine::Application(appInfo) {}
|
||||
|
||||
void Demo1::Awake()
|
||||
{
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION,"AWAKING");
|
||||
}
|
||||
|
||||
void Demo1::Start()
|
||||
{
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION,"STARTING");
|
||||
}
|
||||
|
||||
void Demo1::Tick(double deltaTime)
|
||||
{
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "TICKING %f", deltaTime);
|
||||
}
|
||||
|
||||
void Demo1::Destroy()
|
||||
{
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION,"DESTROYING");
|
||||
}
|
||||
|
||||
} // Demo1
|
||||
19
Demo1/src/Demo1.h
Normal file
19
Demo1/src/Demo1.h
Normal file
@ -0,0 +1,19 @@
|
||||
///
|
||||
// Created by Jimmy Tremblay-bernier on 2024-11-22.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include "ConjureEngine/ConjureEngine.h"
|
||||
|
||||
namespace Demo1 {
|
||||
|
||||
class Demo1: public ConjureEngine::Application {
|
||||
public:
|
||||
Demo1();
|
||||
void Awake() override;
|
||||
void Start() override;
|
||||
void Tick(double deltaTime) override;
|
||||
void Destroy() override;
|
||||
};
|
||||
|
||||
} // Demo1
|
||||
7
Demo1/src/Shaders/Test.frag
Normal file
7
Demo1/src/Shaders/Test.frag
Normal file
@ -0,0 +1,7 @@
|
||||
#version 460 core
|
||||
|
||||
layout (location = 0) out vec4 oColor;
|
||||
|
||||
void main() {
|
||||
oColor = vec4(1);
|
||||
}
|
||||
5
Demo1/src/Shaders/Test.vert
Normal file
5
Demo1/src/Shaders/Test.vert
Normal file
@ -0,0 +1,5 @@
|
||||
#version 460 core
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(0);
|
||||
}
|
||||
@ -1,6 +1,92 @@
|
||||
#include "ConjureEngine/ConjureEngine.h"
|
||||
#define SDL_MAIN_HANDLED
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
ConjureEngine::SayHello();
|
||||
return 0;
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include "Demo1.h"
|
||||
|
||||
static std::ofstream logFile;
|
||||
|
||||
void OutputLog(void *userdata, int category, SDL_LogPriority priority, const char *message)
|
||||
{
|
||||
(void)userdata;
|
||||
|
||||
std::string categoryString;
|
||||
switch (category)
|
||||
{
|
||||
case SDL_LOG_CATEGORY_APPLICATION:
|
||||
categoryString = "Application";
|
||||
break;
|
||||
case SDL_LOG_CATEGORY_ERROR:
|
||||
categoryString = "Error";
|
||||
break;
|
||||
case SDL_LOG_CATEGORY_ASSERT:
|
||||
categoryString = "Assert";
|
||||
break;
|
||||
case SDL_LOG_CATEGORY_SYSTEM:
|
||||
categoryString = "System";
|
||||
break;
|
||||
case SDL_LOG_CATEGORY_AUDIO:
|
||||
categoryString = "Audio";
|
||||
break;
|
||||
case SDL_LOG_CATEGORY_VIDEO:
|
||||
categoryString = "Video";
|
||||
break;
|
||||
case SDL_LOG_CATEGORY_RENDER:
|
||||
categoryString = "Render";
|
||||
break;
|
||||
case SDL_LOG_CATEGORY_INPUT:
|
||||
categoryString = "Input";
|
||||
break;
|
||||
case SDL_LOG_CATEGORY_TEST:
|
||||
categoryString = "Test";
|
||||
break;
|
||||
default:
|
||||
categoryString = "";
|
||||
break;
|
||||
}
|
||||
|
||||
std::string priorityString;
|
||||
switch (priority)
|
||||
{
|
||||
case SDL_LOG_PRIORITY_VERBOSE:
|
||||
priorityString = "VERBOSE";
|
||||
break;
|
||||
case SDL_LOG_PRIORITY_DEBUG:
|
||||
priorityString = "DEBUG";
|
||||
break;
|
||||
case SDL_LOG_PRIORITY_INFO:
|
||||
priorityString = "INFO";
|
||||
break;
|
||||
case SDL_LOG_PRIORITY_WARN:
|
||||
priorityString = "WARN";
|
||||
break;
|
||||
case SDL_LOG_PRIORITY_ERROR:
|
||||
priorityString = "ERROR";
|
||||
break;
|
||||
case SDL_LOG_PRIORITY_CRITICAL:
|
||||
priorityString = "CRITICAL";
|
||||
break;
|
||||
default:
|
||||
std::cout << message << "\n";
|
||||
break;
|
||||
}
|
||||
|
||||
logFile << "[" << categoryString << " - " << priorityString << "] " << message << "\n";
|
||||
std::cout << "[" << categoryString << " - " << priorityString << "] " << message << "\n";
|
||||
}
|
||||
|
||||
int main ( int argc, char* argv[] )
|
||||
{
|
||||
logFile = std::ofstream{"log.txt"};
|
||||
SDL_SetMainReady();
|
||||
|
||||
SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE);
|
||||
SDL_LogSetOutputFunction(&OutputLog, nullptr);
|
||||
|
||||
// I WANT TO CREATE AN APP
|
||||
Demo1::Demo1 app;
|
||||
|
||||
// AND THEN START IT
|
||||
return app.Run();
|
||||
}
|
||||
23
README.md
Normal file
23
README.md
Normal file
@ -0,0 +1,23 @@
|
||||
# Conjure Engine
|
||||
## Installation
|
||||
### Dependancies
|
||||
To install this project, it is required that you install the folowind dependancies
|
||||
on you computer:
|
||||
- Vulkan SDK: https://vulkan.lunarg.com/sdk/home
|
||||
- Conan 2: https://docs.conan.io/2/installation.html
|
||||
|
||||
### Platforms supported
|
||||
- Mac 14+
|
||||
- Windows 10+
|
||||
- Linux 6+
|
||||
|
||||
Those are wide guideline and any version recent enough of your OS should work
|
||||
as long it supports vulkan and conan.
|
||||
|
||||
### Installation step
|
||||
|
||||
#### Configure your IDE
|
||||
1. Execute `./Configure.sh` (LINUX/MAC) or `.\Configure.bat` (WINDOWS). This step installs all the dependencies for both release and debug.
|
||||
2. Load the generated CMakeUserPresets.json that was generated at step 1.
|
||||
3. Select an executable project (like Demo1)
|
||||
4. Build
|
||||
Loading…
x
Reference in New Issue
Block a user