CONGE-2 added the basic setup to open a windows on mac and windows
This commit is contained in:
parent
dccbcf3cca
commit
f64bb01ab2
@ -6,13 +6,14 @@ project(ConjureEngine)
|
||||
|
||||
set(HEADER_FILES
|
||||
src/ConjureEngine/Application.h
|
||||
src/ConjureEngine/Engine.h
|
||||
src/ConjureEngine/ConjureEngine.h
|
||||
src/ConjureEngine/VulkanContext.h
|
||||
src/ConjureEngine/Window.h
|
||||
)
|
||||
|
||||
set(SOURCES_FILES
|
||||
src/ConjureEngine/Application.cpp
|
||||
src/ConjureEngine/Engine.cpp
|
||||
src/ConjureEngine/VulkanContext.cpp
|
||||
src/ConjureEngine/Window.cpp
|
||||
)
|
||||
|
||||
|
||||
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
|
||||
@ -5,4 +5,10 @@
|
||||
#include "Application.h"
|
||||
|
||||
namespace ConjureEngine {
|
||||
} // ConjureEngine
|
||||
Application::Application(const ApplicationInfo &applicationInfo): m_applicationInfo(applicationInfo) {
|
||||
}
|
||||
|
||||
int Application::Run() const { return 0; }
|
||||
void Application::Tick(double deltaTime) const {}
|
||||
|
||||
} // ConjureEngine
|
||||
|
||||
@ -4,10 +4,26 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "PCH.h"
|
||||
#include "Window.h"
|
||||
|
||||
namespace ConjureEngine {
|
||||
struct ApplicationInfo {
|
||||
WindowInfo window{"", 0, 0, 0, 0};
|
||||
};
|
||||
|
||||
class Application {
|
||||
class Application {
|
||||
public:
|
||||
explicit Application(const ApplicationInfo &applicationInfo);
|
||||
virtual ~Application() = default;
|
||||
|
||||
};
|
||||
virtual int Run() const;
|
||||
|
||||
} // ConjureEngine
|
||||
virtual void Tick(double deltaTime) const;
|
||||
|
||||
protected:
|
||||
public:
|
||||
protected:
|
||||
ApplicationInfo m_applicationInfo;
|
||||
};
|
||||
} // ConjureEngine
|
||||
|
||||
4
ConjureEngine/src/ConjureEngine/ConjureEngine.h
Normal file
4
ConjureEngine/src/ConjureEngine/ConjureEngine.h
Normal file
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
#include "Application.h"
|
||||
#include "Window.h"
|
||||
@ -1,4 +0,0 @@
|
||||
//
|
||||
// Created by Jimmy Tremblay-bernier on 2024-11-14.
|
||||
//
|
||||
#include "Engine.h"
|
||||
@ -1,7 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "glm/glm.hpp"
|
||||
|
||||
namespace ConjureEngine {
|
||||
|
||||
}
|
||||
@ -18,4 +18,8 @@
|
||||
#include "SDL2/SDL_video.h"
|
||||
|
||||
// VULKAN
|
||||
#include "Vulkan/vulkan.h"
|
||||
#include "vulkan/vulkan.h"
|
||||
#include "vulkan/vulkan_core.h"
|
||||
#ifdef __APPLE__
|
||||
#include "vulkan/vulkan_metal.h"
|
||||
#endif
|
||||
125
ConjureEngine/src/ConjureEngine/VulkanContext.cpp
Normal file
125
ConjureEngine/src/ConjureEngine/VulkanContext.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
//
|
||||
// Created by Jimmy Tremblay-bernier on 2024-11-22.
|
||||
//
|
||||
|
||||
#include "VulkanContext.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define VK_USE_PLATFORM_METAL_EXT
|
||||
#endif
|
||||
|
||||
namespace ConjureEngine {
|
||||
VulkanContext::VulkanContext(SDL_Window* window, const VkApplicationInfo& appInfo) {
|
||||
// LOAD THE EXTENSIONS
|
||||
SDL_Vulkan_GetInstanceExtensions(window, &m_extensionCount, nullptr);
|
||||
m_extensionNames.reserve(m_extensionCount);
|
||||
SDL_Vulkan_GetInstanceExtensions(window, &m_extensionCount, m_extensionNames.data());
|
||||
|
||||
|
||||
// Fill the instance create info using appInfo
|
||||
VkInstanceCreateInfo vulkanInfos{};
|
||||
vulkanInfos.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
vulkanInfos.pApplicationInfo = &appInfo;
|
||||
|
||||
// ENABLE THE REQUIRED EXTENSIONS
|
||||
this->EnableGlobalExtentions(window, vulkanInfos);
|
||||
|
||||
// CREATE VULKAN INSTANCE
|
||||
vkCreateInstance(&vulkanInfos, nullptr, &m_vkInst);
|
||||
|
||||
// LOAD THE PHYSICAL DEVICES (GPUs)
|
||||
vkEnumeratePhysicalDevices(m_vkInst, &m_physicalDeviceCount, nullptr);
|
||||
m_physicalDevices = std::vector<VkPhysicalDevice>(m_physicalDeviceCount);
|
||||
vkEnumeratePhysicalDevices(m_vkInst, &m_physicalDeviceCount, m_physicalDevices.data());
|
||||
|
||||
// SELECT THE MAIN GPU (WE COULD HAVE A SMARTER SELECTION LATER)
|
||||
m_selectedPhysicalDevice = m_physicalDevices[0];
|
||||
|
||||
// LOAD THE FAMILLY QUEUE PROPERTIES
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(m_selectedPhysicalDevice, &m_queueFamilyCount, nullptr);
|
||||
std::vector<VkQueueFamilyProperties> queueFamilies(m_queueFamilyCount);
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(m_selectedPhysicalDevice, &m_queueFamilyCount, queueFamilies.data());
|
||||
|
||||
// CREATE THE SURFACE FOR RENDERING
|
||||
SDL_Vulkan_CreateSurface(window, m_vkInst, &m_surface);
|
||||
|
||||
// ???
|
||||
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) {
|
||||
vkGetPhysicalDeviceSurfaceSupportKHR(m_selectedPhysicalDevice, i, m_surface, &support);
|
||||
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
|
||||
vkCreateDevice(m_selectedPhysicalDevice, &m_deviceCreateInfo, nullptr, &m_device);
|
||||
|
||||
vkGetDeviceQueue(m_device, graphicsQueueIndex, 0, &m_graphicQueue);
|
||||
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
|
||||
|
||||
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
|
||||
31
ConjureEngine/src/ConjureEngine/VulkanContext.h
Normal file
31
ConjureEngine/src/ConjureEngine/VulkanContext.h
Normal file
@ -0,0 +1,31 @@
|
||||
//
|
||||
// Created by Jimmy Tremblay-bernier on 2024-11-22.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ConjureEngine {
|
||||
#include "PCH.h"
|
||||
|
||||
class VulkanContext {
|
||||
public:
|
||||
explicit VulkanContext(SDL_Window* window, const VkApplicationInfo& appInfo);
|
||||
~VulkanContext();
|
||||
void EnableGlobalExtentions(SDL_Window* window, VkInstanceCreateInfo &vulkanInfos);
|
||||
|
||||
private:
|
||||
uint32_t m_extensionCount{0};
|
||||
std::vector<const char*> m_extensionNames;
|
||||
VkInstance m_vkInst{};
|
||||
uint32_t m_physicalDeviceCount{0};
|
||||
std::vector<VkPhysicalDevice> m_physicalDevices;
|
||||
VkPhysicalDevice m_selectedPhysicalDevice;
|
||||
uint32_t m_queueFamilyCount{0};
|
||||
VkSurfaceKHR m_surface;
|
||||
VkDeviceQueueCreateInfo m_deviceQueueCreateInfo;
|
||||
VkDeviceCreateInfo m_deviceCreateInfo;
|
||||
VkDevice m_device;
|
||||
VkQueue m_graphicQueue;
|
||||
VkQueue m_presentQueue;
|
||||
};
|
||||
} // ConjureEngine
|
||||
@ -7,113 +7,32 @@ namespace ConjureEngine {
|
||||
|
||||
Window::Window(const WindowInfo& windowInfo)
|
||||
{
|
||||
// INIT WINDOW
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
SDL_Vulkan_LoadLibrary(nullptr);
|
||||
m_window = std::shared_ptr<SDL_Window>(
|
||||
SDL_CreateWindow(windowInfo.title.c_str(), 0, 0, windowInfo.width, windowInfo.height, SDL_WINDOW_SHOWN |SDL_WINDOW_VULKAN)
|
||||
);
|
||||
m_window = SDL_CreateWindow(windowInfo.title.c_str(), 0, 0, windowInfo.width, windowInfo.height, SDL_WINDOW_SHOWN |SDL_WINDOW_VULKAN);
|
||||
|
||||
// Fill the application information
|
||||
VkApplicationInfo appInfo{};
|
||||
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||
appInfo.pApplicationName = windowInfo.title.c_str();
|
||||
appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
|
||||
appInfo.pEngineName = "Conjure Engine";
|
||||
appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
|
||||
appInfo.apiVersion = VK_API_VERSION_1_0;
|
||||
|
||||
SDL_Vulkan_GetInstanceExtensions(m_window.get(), &m_extensionCount, nullptr);
|
||||
m_extensionNames = new const char *[m_extensionCount];
|
||||
SDL_Vulkan_GetInstanceExtensions(m_window.get(), &m_extensionCount, m_extensionNames);
|
||||
const VkInstanceCreateInfo instInfo = {
|
||||
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
|
||||
nullptr, // pNext
|
||||
0, // flags
|
||||
nullptr, // pApplicationInfo
|
||||
0, // enabledLayerCount
|
||||
nullptr, // ppEnabledLayerNames
|
||||
m_extensionCount, // enabledExtensionCount
|
||||
m_extensionNames, // ppEnabledExtensionNames
|
||||
};
|
||||
vkCreateInstance(&instInfo, nullptr, &m_vkInst);
|
||||
// INIT VULKAN
|
||||
m_vulkanContext = new VulkanContext(m_window, appInfo);
|
||||
}
|
||||
|
||||
vkEnumeratePhysicalDevices(m_vkInst, &m_physicalDeviceCount, nullptr);
|
||||
m_physicalDevices = std::vector<VkPhysicalDevice>(m_physicalDeviceCount);
|
||||
Window::~Window() {
|
||||
delete m_vulkanContext;
|
||||
|
||||
vkEnumeratePhysicalDevices(m_vkInst, &m_physicalDeviceCount, m_physicalDevices.data());
|
||||
SDL_DestroyWindow(m_window);
|
||||
SDL_Vulkan_UnloadLibrary();
|
||||
SDL_Quit();
|
||||
|
||||
// TODO - I'M AT THIS POINT
|
||||
VkPhysicalDevice physicalDevice = m_physicalDevices[0];
|
||||
|
||||
uint32_t queueFamilyCount;
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, nullptr);
|
||||
std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, queueFamilies.data());
|
||||
|
||||
VkSurfaceKHR surface;
|
||||
SDL_Vulkan_CreateSurface(window, vkInst, &surface);
|
||||
|
||||
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) {
|
||||
vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, i, surface, &support);
|
||||
if(support)
|
||||
presentQueueIndex = i;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
float queuePriority = 1.0f;
|
||||
VkDeviceQueueCreateInfo queueInfo = {
|
||||
VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
|
||||
nullptr, // pNext
|
||||
0, // flags
|
||||
graphicsQueueIndex, // graphicsQueueIndex
|
||||
1, // queueCount
|
||||
&queuePriority, // pQueuePriorities
|
||||
};
|
||||
|
||||
VkPhysicalDeviceFeatures deviceFeatures = {};
|
||||
const char* deviceExtensionNames[] = {VK_KHR_SWAPCHAIN_EXTENSION_NAME};
|
||||
VkDeviceCreateInfo createInfo = {
|
||||
VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
|
||||
nullptr, // pNext
|
||||
0, // flags
|
||||
1, // queueCreateInfoCount
|
||||
&queueInfo, // pQueueCreateInfos
|
||||
0, // enabledLayerCount
|
||||
nullptr, // ppEnabledLayerNames
|
||||
1, // enabledExtensionCount
|
||||
deviceExtensionNames, // ppEnabledExtensionNames
|
||||
&deviceFeatures, // pEnabledFeatures
|
||||
};
|
||||
VkDevice device;
|
||||
vkCreateDevice(physicalDevice, &createInfo, nullptr, &device);
|
||||
|
||||
VkQueue graphicsQueue;
|
||||
vkGetDeviceQueue(device, graphicsQueueIndex, 0, &graphicsQueue);
|
||||
|
||||
VkQueue presentQueue;
|
||||
vkGetDeviceQueue(device, presentQueueIndex, 0, &presentQueue);
|
||||
|
||||
SDL_Log("Initialized with errors: %s", SDL_GetError());
|
||||
|
||||
bool running = true;
|
||||
while(running) {
|
||||
SDL_Event windowEvent;
|
||||
while(SDL_PollEvent(&windowEvent))
|
||||
if(windowEvent.type == SDL_QUIT) {
|
||||
running = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
vkDestroyDevice(device, nullptr);
|
||||
vkDestroyInstance(vkInst, nullptr);
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Vulkan_UnloadLibrary();
|
||||
SDL_Quit();
|
||||
|
||||
SDL_Log("Cleaned up with errors: %s", SDL_GetError());
|
||||
|
||||
return 0;
|
||||
SDL_Log("Cleaned up with errors: %s", SDL_GetError());
|
||||
}
|
||||
|
||||
} // ConjureEngine
|
||||
@ -4,26 +4,30 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ConjureEngine {
|
||||
#include "PCH.h"
|
||||
#include "VulkanContext.h"
|
||||
|
||||
struct WindowInfo {
|
||||
std::string title;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
namespace ConjureEngine {
|
||||
struct WindowInfo {
|
||||
std::string title;
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
class Window {
|
||||
public:
|
||||
explicit Window(const WindowInfo& windowInfo);
|
||||
~Window();
|
||||
|
||||
const std::shared_ptr<SDL_Window>& GetWindow() const;
|
||||
const std::shared_ptr<VulkanContext>& GetVulkanContext() const;
|
||||
private:
|
||||
public:
|
||||
private:
|
||||
std::shared_ptr<SDL_Window> m_window;
|
||||
uint32_t m_extensionCount{0};
|
||||
const char** m_extensionNames{nullptr};
|
||||
VkInstance m_vkInst;
|
||||
uint32_t m_physicalDeviceCount{0};
|
||||
std::vector<VkPhysicalDevice> m_physicalDevices;
|
||||
SDL_Window* m_window;
|
||||
VulkanContext* m_vulkanContext;
|
||||
};
|
||||
|
||||
} // ConjureEngine
|
||||
@ -3,7 +3,9 @@ project(Demo1)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
add_executable(${PROJECT_NAME} src/main.cpp)
|
||||
add_executable(${PROJECT_NAME} src/main.cpp
|
||||
src/Demo1.cpp
|
||||
src/Demo1.h)
|
||||
|
||||
target_link_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/ConjureEngine)
|
||||
|
||||
|
||||
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"
|
||||
|
||||
namespace Demo1 {
|
||||
Demo1::Demo1(): ConjureEngine::Application(
|
||||
{
|
||||
{"Demo1", 0, 0, 1920, 1080}
|
||||
}
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
int Demo1::Run() const {
|
||||
ConjureEngine::Window window(m_applicationInfo.window);
|
||||
|
||||
bool running = true;
|
||||
while (running) {
|
||||
SDL_Event windowEvent;
|
||||
uint64_t timeSinceStart = SDL_GetTicks64();
|
||||
|
||||
while (SDL_PollEvent(&windowEvent)) {
|
||||
if (windowEvent.type == SDL_QUIT) {
|
||||
running = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this->Tick((double)timeSinceStart/1000.0f);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Demo1::Tick(double deltaTime) const {
|
||||
|
||||
}
|
||||
|
||||
} // Demo1
|
||||
17
Demo1/src/Demo1.h
Normal file
17
Demo1/src/Demo1.h
Normal file
@ -0,0 +1,17 @@
|
||||
//
|
||||
// Created by Jimmy Tremblay-bernier on 2024-11-22.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include "ConjureEngine/ConjureEngine.h"
|
||||
|
||||
namespace Demo1 {
|
||||
|
||||
class Demo1: public ConjureEngine::Application {
|
||||
public:
|
||||
Demo1();
|
||||
int Run() const override;
|
||||
void Tick(double deltaTime) const override;
|
||||
};
|
||||
|
||||
} // Demo1
|
||||
@ -1,5 +1,8 @@
|
||||
#include "ConjureEngine/Engine.h"
|
||||
#include "ConjureEngine/ConjureEngine.h"
|
||||
#include "Demo1.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
return 0;
|
||||
Demo1::Demo1 app;
|
||||
|
||||
return app.Run();
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user