self define descriptors
This commit is contained in:
parent
b6438c6779
commit
76bae46dbc
6 changed files with 166 additions and 113 deletions
0
engine/xe_input.cpp
Normal file
0
engine/xe_input.cpp
Normal file
15
engine/xe_input.hpp
Normal file
15
engine/xe_input.hpp
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xe_window.hpp"
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
|
||||||
|
class XeInput {
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
XeWindow &xeWindow;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -20,18 +20,19 @@ XeRenderSystem::XeRenderSystem(
|
||||||
XeEngine &xeEngine,
|
XeEngine &xeEngine,
|
||||||
std::string vert,
|
std::string vert,
|
||||||
std::string frag,
|
std::string frag,
|
||||||
uint32_t pushCunstantDataSize,
|
std::map<uint32_t, uint32_t> uniformBindings,
|
||||||
uint32_t uniformBufferDataSize,
|
std::map<uint32_t, XeImage*> imageBindings,
|
||||||
XeImage *image
|
uint32_t pushCunstantDataSize
|
||||||
) : xeDevice{xeEngine.xeDevice},
|
) : xeDevice{xeEngine.xeDevice},
|
||||||
xeRenderer{xeEngine.xeRenderer},
|
xeRenderer{xeEngine.xeRenderer},
|
||||||
xeDescriptorPool{xeEngine.xeDescriptorPool},
|
xeDescriptorPool{xeEngine.xeDescriptorPool},
|
||||||
pushCunstantDataSize{pushCunstantDataSize},
|
pushCunstantDataSize{pushCunstantDataSize},
|
||||||
uniformBufferDataSize{uniformBufferDataSize},
|
uniformBindings{uniformBindings},
|
||||||
textureSamplerBinding{image != nullptr} {
|
imageBindings{imageBindings} {
|
||||||
|
createTextureSampler();
|
||||||
createDescriptorSetLayout();
|
createDescriptorSetLayout();
|
||||||
createUniformBuffers();
|
createUniformBuffers();
|
||||||
createDescriptorSets(image);
|
createDescriptorSets();
|
||||||
createPipelineLayout();
|
createPipelineLayout();
|
||||||
createPipeline(xeRenderer.getSwapChainRenderPass(), vert, frag);
|
createPipeline(xeRenderer.getSwapChainRenderPass(), vert, frag);
|
||||||
}
|
}
|
||||||
|
@ -39,21 +40,10 @@ XeRenderSystem::XeRenderSystem(
|
||||||
|
|
||||||
XeRenderSystem::~XeRenderSystem() {
|
XeRenderSystem::~XeRenderSystem() {
|
||||||
vkDestroyPipelineLayout(xeDevice.device(), pipelineLayout, nullptr);
|
vkDestroyPipelineLayout(xeDevice.device(), pipelineLayout, nullptr);
|
||||||
if ( textureSamplerBinding ) {
|
|
||||||
vkDestroySampler(xeDevice.device(), textureSampler, nullptr);
|
vkDestroySampler(xeDevice.device(), textureSampler, nullptr);
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void XeRenderSystem::createDescriptorSetLayout() {
|
void XeRenderSystem::createTextureSampler() {
|
||||||
XeDescriptorSetLayout::Builder builder{xeDevice};
|
|
||||||
int binding = 0;
|
|
||||||
|
|
||||||
if (uniformBufferDataSize > 0) {
|
|
||||||
builder.addBinding(binding, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, nullptr);
|
|
||||||
binding += 1;
|
|
||||||
}
|
|
||||||
if (textureSamplerBinding) {
|
|
||||||
|
|
||||||
VkSamplerCreateInfo samplerInfo{};
|
VkSamplerCreateInfo samplerInfo{};
|
||||||
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||||
samplerInfo.magFilter = VK_FILTER_LINEAR;
|
samplerInfo.magFilter = VK_FILTER_LINEAR;
|
||||||
|
@ -74,59 +64,67 @@ void XeRenderSystem::createDescriptorSetLayout() {
|
||||||
if (vkCreateSampler(xeDevice.device(), &samplerInfo, nullptr, &textureSampler) != VK_SUCCESS) {
|
if (vkCreateSampler(xeDevice.device(), &samplerInfo, nullptr, &textureSampler) != VK_SUCCESS) {
|
||||||
throw std::runtime_error("failed to create texture sampler!");
|
throw std::runtime_error("failed to create texture sampler!");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void XeRenderSystem::createDescriptorSetLayout() {
|
||||||
|
XeDescriptorSetLayout::Builder builder{xeDevice};
|
||||||
|
|
||||||
|
for ( const auto &[binding, size]: uniformBindings) {
|
||||||
|
builder.addBinding(binding, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( const auto &[binding, image]: imageBindings) {
|
||||||
builder.addBinding(binding, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, &textureSampler);
|
builder.addBinding(binding, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, &textureSampler);
|
||||||
binding += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xeDescriptorSetLayout = builder.build();
|
xeDescriptorSetLayout = builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
void XeRenderSystem::createUniformBuffers() {
|
void XeRenderSystem::createUniformBuffers() {
|
||||||
if(uniformBufferDataSize == 0) return;
|
for ( const auto &[binding, bufferSize]: uniformBindings) {
|
||||||
|
uboBuffers[binding] = std::vector<std::unique_ptr<XeBuffer>>(XeSwapChain::MAX_FRAMES_IN_FLIGHT);
|
||||||
uboBuffers = std::vector<std::unique_ptr<XeBuffer>>(XeSwapChain::MAX_FRAMES_IN_FLIGHT);
|
for (int i = 0; i < uboBuffers[binding].size(); i++) {
|
||||||
for (int i = 0; i < uboBuffers.size(); i++) {
|
uboBuffers[binding][i] = std::make_unique<XeBuffer>(
|
||||||
uboBuffers[i] = std::make_unique<XeBuffer>(
|
|
||||||
xeDevice,
|
xeDevice,
|
||||||
uniformBufferDataSize,
|
bufferSize,
|
||||||
XeSwapChain::MAX_FRAMES_IN_FLIGHT,
|
XeSwapChain::MAX_FRAMES_IN_FLIGHT,
|
||||||
|
|
||||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
||||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||||
uboBuffers[i]->map();
|
uboBuffers[binding][i]->map();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
void XeRenderSystem::createDescriptorSets() {
|
||||||
|
|
||||||
void XeRenderSystem::createDescriptorSets(XeImage *image) {
|
|
||||||
|
|
||||||
descriptorSets = std::vector<VkDescriptorSet>(XeSwapChain::MAX_FRAMES_IN_FLIGHT);
|
descriptorSets = std::vector<VkDescriptorSet>(XeSwapChain::MAX_FRAMES_IN_FLIGHT);
|
||||||
for (int i = 0; i < descriptorSets.size(); i++) {
|
for (int i = 0; i < descriptorSets.size(); i++) {
|
||||||
updateDescriptorSet(image, i, true);
|
updateDescriptorSet(i, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void XeRenderSystem::updateDescriptorSet(XeImage *image, int frameIndex, bool allocate) {
|
void XeRenderSystem::updateDescriptorSet(int frameIndex, bool allocate) {
|
||||||
auto bufferInfo = uboBuffers[frameIndex]->descriptorInfo();
|
|
||||||
XeDescriptorWriter writer{*xeDescriptorSetLayout, *xeDescriptorPool};
|
XeDescriptorWriter writer{*xeDescriptorSetLayout, *xeDescriptorPool};
|
||||||
|
|
||||||
int binding = 0;
|
std::vector<VkDescriptorBufferInfo> bufferInfos{};
|
||||||
|
|
||||||
if (uniformBufferDataSize > 0) {
|
int i = 0;
|
||||||
writer.writeBuffer(binding, &bufferInfo);
|
for ( const auto &[binding, size]: uniformBindings) {
|
||||||
binding += 1;
|
bufferInfos.push_back(uboBuffers[binding][frameIndex]->descriptorInfo());
|
||||||
|
writer.writeBuffer(binding, &bufferInfos[i]);
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (textureSamplerBinding) {
|
for ( const auto &[binding, image]: imageBindings) {
|
||||||
VkDescriptorImageInfo imageInfo{};
|
VkDescriptorImageInfo imageInfo{};
|
||||||
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
imageInfo.imageView = image->textureImageView;
|
imageInfo.imageView = image->textureImageView;
|
||||||
imageInfo.sampler = textureSampler;
|
imageInfo.sampler = textureSampler;
|
||||||
writer.writeImage(binding, &imageInfo);
|
writer.writeImage(binding, &imageInfo);
|
||||||
binding += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allocate) {
|
if (allocate) {
|
||||||
writer.build(descriptorSets[frameIndex]);
|
writer.build(descriptorSets[frameIndex]);
|
||||||
} else {
|
} else {
|
||||||
|
@ -143,8 +141,12 @@ void XeRenderSystem::createPipelineLayout() {
|
||||||
pushConstantRange.offset = 0;
|
pushConstantRange.offset = 0;
|
||||||
pushConstantRange.size = pushCunstantDataSize;
|
pushConstantRange.size = pushCunstantDataSize;
|
||||||
|
|
||||||
|
std::vector<VkDescriptorSetLayout> descriptorSetLayouts{xeDescriptorSetLayout->getDescriptorSetLayout()};
|
||||||
|
|
||||||
VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
|
VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
|
||||||
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||||
|
pipelineLayoutInfo.setLayoutCount = static_cast<uint32_t>(descriptorSetLayouts.size());
|
||||||
|
pipelineLayoutInfo.pSetLayouts = descriptorSetLayouts.data();
|
||||||
|
|
||||||
if (pushCunstantDataSize > 0) {
|
if (pushCunstantDataSize > 0) {
|
||||||
pipelineLayoutInfo.pushConstantRangeCount = 1;
|
pipelineLayoutInfo.pushConstantRangeCount = 1;
|
||||||
|
@ -154,17 +156,6 @@ void XeRenderSystem::createPipelineLayout() {
|
||||||
pipelineLayoutInfo.pPushConstantRanges = nullptr;
|
pipelineLayoutInfo.pPushConstantRanges = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<VkDescriptorSetLayout> descriptorSetLayouts{xeDescriptorSetLayout->getDescriptorSetLayout()};
|
|
||||||
|
|
||||||
if (uniformBufferDataSize > 0) {
|
|
||||||
pipelineLayoutInfo.setLayoutCount = static_cast<uint32_t>(descriptorSetLayouts.size());
|
|
||||||
pipelineLayoutInfo.pSetLayouts = descriptorSetLayouts.data();
|
|
||||||
} else {
|
|
||||||
|
|
||||||
pipelineLayoutInfo.setLayoutCount = 0;
|
|
||||||
pipelineLayoutInfo.pSetLayouts = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(vkCreatePipelineLayout(xeDevice.device(), &pipelineLayoutInfo, nullptr, &pipelineLayout) != VK_SUCCESS) {
|
if(vkCreatePipelineLayout(xeDevice.device(), &pipelineLayoutInfo, nullptr, &pipelineLayout) != VK_SUCCESS) {
|
||||||
std::runtime_error("failed to create pipeline layout!");
|
std::runtime_error("failed to create pipeline layout!");
|
||||||
}
|
}
|
||||||
|
@ -215,12 +206,13 @@ void XeRenderSystem::loadPushConstant(void *pushConstantData) {
|
||||||
pushConstantData);
|
pushConstantData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XeRenderSystem::loadUniformObject(void *uniformBufferData) {
|
void XeRenderSystem::loadUniformObject(uint32_t binding, void *uniformBufferData) {
|
||||||
uboBuffers[xeRenderer.getFrameIndex()]->writeToBuffer(uniformBufferData);
|
uboBuffers[binding][xeRenderer.getFrameIndex()]->writeToBuffer(uniformBufferData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XeRenderSystem::loadTexture(XeImage *image) {
|
void XeRenderSystem::loadTexture(uint32_t binding, XeImage *image) {
|
||||||
updateDescriptorSet(image, xeRenderer.getFrameIndex(), false);
|
imageBindings[binding] = image;
|
||||||
|
updateDescriptorSet(xeRenderer.getFrameIndex(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XeRenderSystem::render(XeGameObject &gameObject) {
|
void XeRenderSystem::render(XeGameObject &gameObject) {
|
||||||
|
|
|
@ -10,19 +10,55 @@
|
||||||
#include "xe_image.hpp"
|
#include "xe_image.hpp"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
|
||||||
class XeRenderSystem {
|
class XeRenderSystem {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
class Builder {
|
||||||
|
public:
|
||||||
|
Builder(XeEngine &xeEngine, std::string vert, std::string frag) : xeEngine{xeEngine}, vert{vert}, frag{frag} {}
|
||||||
|
|
||||||
|
Builder& addPushConstant(uint32_t size) {
|
||||||
|
pushCunstantDataSize = size;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder& addUniformBinding(uint32_t binding, uint32_t size) {
|
||||||
|
uniformBindings[binding] = size;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder& addTextureBinding(uint32_t binding, XeImage* image) {
|
||||||
|
imageBindings[binding] = image;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<XeRenderSystem> build() {
|
||||||
|
return std::make_unique<XeRenderSystem>(xeEngine, std::move(vert), std::move(frag), std::move(uniformBindings), std::move(imageBindings), std::move(pushCunstantDataSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::map<uint32_t, uint32_t> uniformBindings{};
|
||||||
|
std::map<uint32_t, XeImage*> imageBindings{};
|
||||||
|
uint32_t pushCunstantDataSize{0};
|
||||||
|
|
||||||
|
std::string vert;
|
||||||
|
std::string frag;
|
||||||
|
|
||||||
|
XeEngine &xeEngine;
|
||||||
|
};
|
||||||
|
|
||||||
XeRenderSystem(
|
XeRenderSystem(
|
||||||
XeEngine &xeEngine,
|
XeEngine &xeEngine,
|
||||||
std::string vert,
|
std::string vert,
|
||||||
std::string frag,
|
std::string frag,
|
||||||
uint32_t pushCunstantDataSize,
|
std::map<uint32_t, uint32_t> uniformBindings,
|
||||||
uint32_t uniformBufferDataSize,
|
std::map<uint32_t, XeImage*> imageBindings,
|
||||||
XeImage *image
|
uint32_t pushCunstantDataSize
|
||||||
);
|
);
|
||||||
|
|
||||||
~XeRenderSystem();
|
~XeRenderSystem();
|
||||||
|
@ -32,37 +68,39 @@ class XeRenderSystem {
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
void loadPushConstant(void *pushConstantData);
|
void loadPushConstant(void *pushConstantData);
|
||||||
void loadUniformObject(void *uniformBufferData);
|
void loadUniformObject(uint32_t binding, void *uniformBufferData);
|
||||||
void loadTexture(XeImage *image);
|
void loadTexture(uint32_t binding, XeImage *image);
|
||||||
void render(XeGameObject &gameObject);
|
void render(XeGameObject &gameObject);
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
void createTextureSampler();
|
||||||
void createDescriptorSetLayout();
|
void createDescriptorSetLayout();
|
||||||
void createUniformBuffers();
|
void createUniformBuffers();
|
||||||
void createDescriptorSets(XeImage *image);
|
void createDescriptorSets();
|
||||||
void updateDescriptorSet(XeImage *image, int frameIndex, bool allocate);
|
void updateDescriptorSet(int frameIndex, bool allocate);
|
||||||
void createPipelineLayout();
|
void createPipelineLayout();
|
||||||
void createPipeline(VkRenderPass renderPass, std::string vert, std::string frag);
|
void createPipeline(VkRenderPass renderPass, std::string vert, std::string frag);
|
||||||
|
|
||||||
bool boundPipeline{false};
|
bool boundPipeline{false};
|
||||||
bool boundDescriptor{false};
|
bool boundDescriptor{false};
|
||||||
|
|
||||||
uint32_t uniformBufferDataSize;
|
|
||||||
uint32_t pushCunstantDataSize;
|
|
||||||
bool textureSamplerBinding;
|
|
||||||
|
|
||||||
XeDevice& xeDevice;
|
XeDevice& xeDevice;
|
||||||
XeRenderer& xeRenderer;
|
XeRenderer& xeRenderer;
|
||||||
|
|
||||||
std::unique_ptr<XePipeline> xePipeline;
|
std::map<uint32_t, std::vector<std::unique_ptr<XeBuffer>>> uboBuffers{};
|
||||||
std::vector<std::unique_ptr<XeBuffer>> uboBuffers;
|
std::map<uint32_t, uint32_t> uniformBindings;
|
||||||
|
std::map<uint32_t, XeImage*> imageBindings;
|
||||||
std::vector<VkDescriptorSet> descriptorSets;
|
std::vector<VkDescriptorSet> descriptorSets;
|
||||||
|
|
||||||
|
uint32_t pushCunstantDataSize;
|
||||||
|
|
||||||
VkSampler textureSampler;
|
VkSampler textureSampler;
|
||||||
|
|
||||||
VkPipelineLayout pipelineLayout;
|
VkPipelineLayout pipelineLayout;
|
||||||
|
std::unique_ptr<XePipeline> xePipeline;
|
||||||
std::unique_ptr<XeDescriptorPool> &xeDescriptorPool;
|
std::unique_ptr<XeDescriptorPool> &xeDescriptorPool;
|
||||||
std::unique_ptr<XeDescriptorSetLayout> xeDescriptorSetLayout;
|
std::unique_ptr<XeDescriptorSetLayout> xeDescriptorSetLayout;
|
||||||
|
|
||||||
|
|
|
@ -1,29 +1,37 @@
|
||||||
#include "simple_renderer.hpp"
|
#include "simple_renderer.hpp"
|
||||||
|
#include "xe_render_system.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
SimpleRenderer::SimpleRenderer(xe::XeEngine &xeEngine, xe::XeImage *xeImage)
|
SimpleRenderer::SimpleRenderer(xe::XeEngine &xeEngine, xe::XeImage *xeImage) {
|
||||||
: xeRenderSystem{xeEngine, "res/shaders/simple_shader.vert.spv", "res/shaders/simple_shader.frag.spv", sizeof(PushConstant), sizeof(UniformBuffer), xeImage} {};
|
xeRenderSystem = xe::XeRenderSystem::Builder(xeEngine, "res/shaders/simple_shader.vert.spv", "res/shaders/simple_shader.frag.spv")
|
||||||
|
.addPushConstant(sizeof(PushConstant))
|
||||||
|
.addUniformBinding(0, sizeof(UniformBuffer))
|
||||||
|
.addTextureBinding(1, xeImage)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
void SimpleRenderer::render(std::vector<xe::XeGameObject> &gameObjects, xe::XeCamera &xeCamera, xe::XeImage *xeImage) {
|
void SimpleRenderer::render(std::vector<xe::XeGameObject> &gameObjects, xe::XeCamera &xeCamera, xe::XeImage *xeImage) {
|
||||||
|
|
||||||
xeRenderSystem.loadTexture(xeImage);
|
xeRenderSystem->loadTexture(1, xeImage);
|
||||||
|
|
||||||
xeRenderSystem.start();
|
xeRenderSystem->start();
|
||||||
|
|
||||||
UniformBuffer ubo{};
|
UniformBuffer ubo{};
|
||||||
ubo.projectionView = xeCamera.getProjection() * xeCamera.getView();
|
ubo.projectionView = xeCamera.getProjection() * xeCamera.getView();
|
||||||
xeRenderSystem.loadUniformObject(&ubo);
|
xeRenderSystem->loadUniformObject(0, &ubo);
|
||||||
|
|
||||||
for(auto &obj : gameObjects) {
|
for(auto &obj : gameObjects) {
|
||||||
PushConstant pc{};
|
PushConstant pc{};
|
||||||
pc.modelMatrix = obj.transform.mat4();
|
pc.modelMatrix = obj.transform.mat4();
|
||||||
pc.normalMatrix = obj.transform.normalMatrix();
|
pc.normalMatrix = obj.transform.normalMatrix();
|
||||||
xeRenderSystem.loadPushConstant(&pc);
|
xeRenderSystem->loadPushConstant(&pc);
|
||||||
xeRenderSystem.render(obj);
|
xeRenderSystem->render(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
xeRenderSystem.stop();
|
xeRenderSystem->stop();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ class SimpleRenderer {
|
||||||
void render(std::vector<xe::XeGameObject> &gameObjects, xe::XeCamera &xeCamera, xe::XeImage *xeImage);
|
void render(std::vector<xe::XeGameObject> &gameObjects, xe::XeCamera &xeCamera, xe::XeImage *xeImage);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
xe::XeRenderSystem xeRenderSystem;
|
std::unique_ptr<xe::XeRenderSystem> xeRenderSystem;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue