texture arrays
This commit is contained in:
parent
7332c3e56a
commit
873ca38c0d
14 changed files with 81 additions and 30 deletions
|
@ -10,9 +10,9 @@ DescriptorSetLayout::Builder &DescriptorSetLayout::Builder::addBinding(
|
|||
uint32_t binding,
|
||||
VkDescriptorType descriptorType,
|
||||
VkShaderStageFlags stageFlags,
|
||||
VkSampler *sampler) {
|
||||
VkSampler *sampler,
|
||||
uint32_t count) {
|
||||
assert(bindings.count(binding) == 0 && "Binding already in use");
|
||||
uint32_t count = 1;
|
||||
VkDescriptorSetLayoutBinding layoutBinding{};
|
||||
layoutBinding.binding = binding;
|
||||
layoutBinding.descriptorType = descriptorType;
|
||||
|
@ -167,6 +167,24 @@ DescriptorWriter &DescriptorWriter::writeImage(
|
|||
return *this;
|
||||
}
|
||||
|
||||
DescriptorWriter &DescriptorWriter::writeImageArray(
|
||||
uint32_t binding, std::vector<VkDescriptorImageInfo> *imageInfos) {
|
||||
assert(setLayout.bindings.count(binding) == 1 && "Layout does not contain specified binding");
|
||||
|
||||
auto &bindingDescription = setLayout.bindings[binding];
|
||||
|
||||
VkWriteDescriptorSet write{};
|
||||
write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
write.descriptorType = bindingDescription.descriptorType;
|
||||
write.dstBinding = binding;
|
||||
write.dstArrayElement = 0;
|
||||
write.pImageInfo = imageInfos->data();
|
||||
write.descriptorCount = imageInfos->size();
|
||||
|
||||
writes.push_back(write);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool DescriptorWriter::build(VkDescriptorSet &set) {
|
||||
bool success = pool.allocateDescriptor(setLayout.getDescriptorSetLayout(), set);
|
||||
if (!success) {
|
||||
|
|
|
@ -19,7 +19,8 @@ class DescriptorSetLayout {
|
|||
uint32_t binding,
|
||||
VkDescriptorType descriptorType,
|
||||
VkShaderStageFlags stageFlags,
|
||||
VkSampler *sampler);
|
||||
VkSampler *sampler,
|
||||
uint32_t count);
|
||||
std::unique_ptr<DescriptorSetLayout> build() const;
|
||||
|
||||
private:
|
||||
|
@ -90,6 +91,7 @@ class DescriptorWriter {
|
|||
|
||||
DescriptorWriter &writeBuffer(uint32_t binding, VkDescriptorBufferInfo *bufferInfo);
|
||||
DescriptorWriter &writeImage(uint32_t binding, VkDescriptorImageInfo *imageInfo);
|
||||
DescriptorWriter &writeImageArray(uint32_t binding, std::vector<VkDescriptorImageInfo> *imageInfos);
|
||||
|
||||
bool build(VkDescriptorSet &set);
|
||||
void overwrite(VkDescriptorSet &set);
|
||||
|
|
|
@ -8,6 +8,7 @@ RenderSystem::RenderSystem(
|
|||
std::string frag,
|
||||
std::map<uint32_t, uint32_t> uniformBindings,
|
||||
std::map<uint32_t, Image*> imageBindings,
|
||||
std::map<uint32_t, std::vector<Image*>> imageArrayBindings,
|
||||
uint32_t pushCunstantDataSize,
|
||||
bool cullingEnabled,
|
||||
std::vector<VkVertexInputAttributeDescription> attributeDescptions,
|
||||
|
@ -17,7 +18,8 @@ RenderSystem::RenderSystem(
|
|||
xeDescriptorPool{xeEngine.xeDescriptorPool},
|
||||
pushCunstantDataSize{pushCunstantDataSize},
|
||||
uniformBindings{uniformBindings},
|
||||
imageBindings{imageBindings} {
|
||||
imageBindings{imageBindings},
|
||||
imageArrayBindings{imageArrayBindings} {
|
||||
createDescriptorSetLayout();
|
||||
createUniformBuffers();
|
||||
createDescriptorSets();
|
||||
|
@ -33,11 +35,15 @@ void RenderSystem::createDescriptorSetLayout() {
|
|||
DescriptorSetLayout::Builder builder{xeDevice};
|
||||
|
||||
for ( const auto &[binding, size]: uniformBindings) {
|
||||
builder.addBinding(binding, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, nullptr);
|
||||
builder.addBinding(binding, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, nullptr, 1);
|
||||
}
|
||||
|
||||
for ( const auto &[binding, image]: imageBindings) {
|
||||
builder.addBinding(binding, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, &(image->textureSampler));
|
||||
builder.addBinding(binding, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, &(image->textureSampler), 1);
|
||||
}
|
||||
|
||||
for ( const auto &[binding, images]: imageArrayBindings) {
|
||||
builder.addBinding(binding, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, 0, images.size());
|
||||
}
|
||||
|
||||
xeDescriptorSetLayout = builder.build();
|
||||
|
@ -88,6 +94,18 @@ void RenderSystem::updateDescriptorSet(int frameIndex, bool allocate) {
|
|||
writer.writeImage(binding, &imageInfo);
|
||||
}
|
||||
|
||||
std::vector<VkDescriptorImageInfo> imageInfos{};
|
||||
for ( const auto &[binding, images]: imageArrayBindings) {
|
||||
for( const auto &image: images) {
|
||||
VkDescriptorImageInfo imageInfo{};
|
||||
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
imageInfo.imageView = image->textureImageView;
|
||||
imageInfo.sampler = image->textureSampler;
|
||||
imageInfos.push_back(imageInfo);
|
||||
}
|
||||
writer.writeImageArray(binding, &imageInfos);
|
||||
}
|
||||
|
||||
if (allocate) {
|
||||
writer.build(descriptorSets[frameIndex]);
|
||||
} else {
|
||||
|
@ -183,6 +201,11 @@ void RenderSystem::loadTexture(uint32_t binding, Image *image) {
|
|||
updateDescriptorSet(xeRenderer.getFrameIndex(), false);
|
||||
}
|
||||
|
||||
void RenderSystem::loadTextureArray(uint32_t binding, std::vector<Image*>& images) {
|
||||
imageArrayBindings[binding] = images;
|
||||
updateDescriptorSet(xeRenderer.getFrameIndex(), false);
|
||||
}
|
||||
|
||||
void RenderSystem::render(GameObject &gameObject) {
|
||||
|
||||
gameObject.model->bind(xeRenderer.getCurrentCommandBuffer());
|
||||
|
|
|
@ -54,19 +54,25 @@ class RenderSystem {
|
|||
return *this;
|
||||
}
|
||||
|
||||
Builder& addTextureArrayBinding(uint32_t binding, std::vector<Image*>& image) {
|
||||
imageArrayBindings[binding] = image;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Builder& setCulling(bool enabled) {
|
||||
cullingEnabled = enabled;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::unique_ptr<RenderSystem> build() {
|
||||
return std::make_unique<RenderSystem>(xeEngine, std::move(vert), std::move(frag), std::move(uniformBindings), std::move(imageBindings), std::move(pushCunstantDataSize), std::move(cullingEnabled), std::move(attributeDescptions), std::move(vertexSize));
|
||||
return std::make_unique<RenderSystem>(xeEngine, std::move(vert), std::move(frag), std::move(uniformBindings), std::move(imageBindings), std::move(imageArrayBindings), std::move(pushCunstantDataSize), std::move(cullingEnabled), std::move(attributeDescptions), std::move(vertexSize));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::map<uint32_t, uint32_t> uniformBindings{};
|
||||
std::map<uint32_t, Image*> imageBindings{};
|
||||
std::map<uint32_t, std::vector<Image*>> imageArrayBindings{};
|
||||
uint32_t pushCunstantDataSize{0};
|
||||
|
||||
std::vector<VkVertexInputAttributeDescription> attributeDescptions{};
|
||||
|
@ -86,6 +92,7 @@ class RenderSystem {
|
|||
std::string frag,
|
||||
std::map<uint32_t, uint32_t> uniformBindings,
|
||||
std::map<uint32_t, Image*> imageBindings,
|
||||
std::map<uint32_t, std::vector<Image*>> imageArrayBindings,
|
||||
uint32_t pushCunstantDataSize,
|
||||
bool cullingEnabled,
|
||||
std::vector<VkVertexInputAttributeDescription> attributeDescptions,
|
||||
|
@ -101,6 +108,7 @@ class RenderSystem {
|
|||
void loadPushConstant(void *pushConstantData);
|
||||
void loadUniformObject(uint32_t binding, void *uniformBufferData);
|
||||
void loadTexture(uint32_t binding, Image *image);
|
||||
void loadTextureArray(uint32_t binding, std::vector<Image*> &images);
|
||||
void render(GameObject &gameObject);
|
||||
void stop();
|
||||
|
||||
|
@ -123,6 +131,7 @@ class RenderSystem {
|
|||
std::map<uint32_t, std::vector<std::unique_ptr<Buffer>>> uboBuffers{};
|
||||
std::map<uint32_t, uint32_t> uniformBindings;
|
||||
std::map<uint32_t, Image*> imageBindings;
|
||||
std::map<uint32_t, std::vector<Image*>> imageArrayBindings{};
|
||||
std::vector<VkDescriptorSet> descriptorSets;
|
||||
|
||||
uint32_t pushCunstantDataSize;
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 7.3 KiB |
BIN
res/image/grass.png
Normal file
BIN
res/image/grass.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6 KiB |
Binary file not shown.
Before Width: | Height: | Size: 3.1 MiB |
Binary file not shown.
Before Width: | Height: | Size: 1.3 MiB |
|
@ -2,6 +2,7 @@
|
|||
|
||||
layout (location = 0) in vec3 fragColor;
|
||||
layout (location = 1) in vec2 fragUv;
|
||||
layout (location = 2) in float fragTex;
|
||||
|
||||
layout (location = 0) out vec4 outColor;
|
||||
|
||||
|
@ -10,12 +11,7 @@ layout (binding = 0) uniform GlobalUbo {
|
|||
vec3 directionToLight;
|
||||
} ubo;
|
||||
|
||||
layout (binding = 2) uniform Deez {
|
||||
mat4 projectionViewMatrix;
|
||||
vec3 directionToLight;
|
||||
} deez;
|
||||
|
||||
layout (binding = 1) uniform sampler2D texSampler;
|
||||
layout (binding = 1) uniform sampler2D texSampler[2];
|
||||
|
||||
layout(push_constant) uniform Push {
|
||||
mat4 transform;
|
||||
|
@ -23,5 +19,5 @@ layout(push_constant) uniform Push {
|
|||
} push;
|
||||
|
||||
void main() {
|
||||
outColor = mix(texture(texSampler, fragUv), vec4(fragColor, 1.0), .1);
|
||||
outColor = mix(texture(texSampler[int(fragTex)], fragUv), vec4(fragColor, 1.0), .1);
|
||||
}
|
|
@ -3,20 +3,17 @@
|
|||
layout (location = 0) in vec3 position;
|
||||
layout (location = 1) in vec3 normal;
|
||||
layout (location = 2) in vec2 uv;
|
||||
layout (location = 3) in float tex;
|
||||
|
||||
layout (location = 0) out vec3 fragColor;
|
||||
layout (location = 1) out vec2 fragUv;
|
||||
layout (location = 2) out float fragTex;
|
||||
|
||||
layout (binding = 0) uniform GlobalUbo {
|
||||
mat4 projectionViewMatrix;
|
||||
vec3 directionToLight;
|
||||
} ubo;
|
||||
|
||||
layout (binding = 2) uniform Deez {
|
||||
mat4 projectionViewMatrix;
|
||||
vec3 directionToLight;
|
||||
} deez;
|
||||
|
||||
layout (push_constant) uniform Push {
|
||||
mat4 modelMatrix;
|
||||
mat4 normalMatrix;
|
||||
|
@ -33,4 +30,5 @@ void main() {
|
|||
|
||||
fragColor = lightIntensity * vec3(1);
|
||||
fragUv = uv;
|
||||
fragTex = tex;
|
||||
}
|
|
@ -75,7 +75,7 @@ std::shared_ptr<xe::Model> Chunk::getMesh() {
|
|||
delete chunkMesh.get();
|
||||
xe::Model::Builder builder{};
|
||||
builder.vertexData = vertexData;
|
||||
builder.vertexSize = 32;
|
||||
builder.vertexSize = 36;
|
||||
chunkMesh = std::make_shared<xe::Model>(xe::Engine::getInstance()->getDevice(), builder);
|
||||
}
|
||||
return chunkMesh;
|
||||
|
@ -129,6 +129,7 @@ void Chunk::addVerticies(uint8_t side, int32_t x, int32_t y, int32_t z) {
|
|||
vertexData.push_back(nm[side][2]);
|
||||
vertexData.push_back(uv[i][0]);
|
||||
vertexData.push_back(uv[i][1]);
|
||||
vertexData.push_back(0.f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,9 +11,12 @@ FirstApp::~FirstApp() {}
|
|||
|
||||
void FirstApp::run() {
|
||||
|
||||
std::shared_ptr<xe::Image> image = xeEngine.loadImageFromFile("res/image/dirt.jpg");
|
||||
std::shared_ptr<xe::Image> dirt = xeEngine.loadImageFromFile("res/image/dirt.jpg");
|
||||
std::shared_ptr<xe::Image> grass = xeEngine.loadImageFromFile("res/image/grass.png");
|
||||
|
||||
SimpleRenderer renderer{xeEngine, image.get()};
|
||||
std::vector<xe::Image*> images = {dirt.get(), grass.get()};
|
||||
|
||||
SimpleRenderer renderer{xeEngine, images};
|
||||
|
||||
xe::Sound sound{"res/sound/when_the_world_ends.wav"};
|
||||
sound.setLooping(true);
|
||||
|
@ -32,7 +35,7 @@ void FirstApp::run() {
|
|||
xeEngine.getCamera().setViewYXZ(viewerObject.transform.translation, viewerObject.transform.rotation);
|
||||
|
||||
if(xeEngine.beginFrame()) {
|
||||
renderer.render(gameObjects, xeEngine.getCamera(), image.get());
|
||||
renderer.render(gameObjects, xeEngine.getCamera());
|
||||
xeEngine.endFrame();
|
||||
}
|
||||
|
||||
|
|
|
@ -2,22 +2,23 @@
|
|||
|
||||
namespace app {
|
||||
|
||||
SimpleRenderer::SimpleRenderer(xe::Engine &xeEngine, xe::Image *xeImage) {
|
||||
SimpleRenderer::SimpleRenderer(xe::Engine &xeEngine, std::vector<xe::Image*> &images) {
|
||||
xeRenderSystem = xe::RenderSystem::Builder(xeEngine, "res/shaders/simple_shader.vert.spv", "res/shaders/simple_shader.frag.spv")
|
||||
.addVertexBinding(0, 3, 0) // position
|
||||
.addVertexBinding(1, 3, 12) // normal
|
||||
.addVertexBinding(2, 2, 24) // uvs
|
||||
.setVertexSize(32)
|
||||
.addVertexBinding(3, 1, 32) // texture
|
||||
.setVertexSize(36)
|
||||
.addPushConstant(sizeof(PushConstant))
|
||||
.addUniformBinding(0, sizeof(UniformBuffer))
|
||||
.addTextureBinding(1, xeImage)
|
||||
.addTextureArrayBinding(1, images)
|
||||
.setCulling(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
void SimpleRenderer::render(std::vector<xe::GameObject> &gameObjects, xe::Camera &xeCamera, xe::Image *xeImage) {
|
||||
void SimpleRenderer::render(std::vector<xe::GameObject> &gameObjects, xe::Camera &xeCamera) {
|
||||
|
||||
xeRenderSystem->loadTexture(1, xeImage);
|
||||
// xeRenderSystem->loadTexture(1, xeImage);
|
||||
|
||||
xeRenderSystem->start();
|
||||
|
||||
|
|
|
@ -20,14 +20,14 @@ class SimpleRenderer {
|
|||
|
||||
public:
|
||||
|
||||
SimpleRenderer(xe::Engine &xeEngine, xe::Image *xeImage);
|
||||
SimpleRenderer(xe::Engine &xeEngine, std::vector<xe::Image*> &images);
|
||||
|
||||
~SimpleRenderer() {};
|
||||
|
||||
SimpleRenderer(const SimpleRenderer&) = delete;
|
||||
SimpleRenderer operator=(const SimpleRenderer&) = delete;
|
||||
|
||||
void render(std::vector<xe::GameObject> &gameObjects, xe::Camera &xeCamera, xe::Image *xeImage);
|
||||
void render(std::vector<xe::GameObject> &gameObjects, xe::Camera &xeCamera);
|
||||
|
||||
private:
|
||||
std::unique_ptr<xe::RenderSystem> xeRenderSystem;
|
||||
|
|
Loading…
Reference in a new issue