mirror of
https://github.com/love2d/love.git
synced 2026-08-20 20:49:54 +02:00
vulkan: implement cull and winding
This commit is contained in:
@@ -205,6 +205,7 @@ namespace love {
|
|||||||
|
|
||||||
Shader::current = Shader::standardShaders[graphics::Shader::StandardShader::STANDARD_DEFAULT];
|
Shader::current = Shader::standardShaders[graphics::Shader::StandardShader::STANDARD_DEFAULT];
|
||||||
currentPolygonMode = VK_POLYGON_MODE_FILL;
|
currentPolygonMode = VK_POLYGON_MODE_FILL;
|
||||||
|
restoreState(states.back());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -265,6 +266,18 @@ namespace love {
|
|||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Graphics::setFrontFaceWinding(Winding winding) {
|
||||||
|
const auto& currentState = states.back();
|
||||||
|
|
||||||
|
if (currentState.winding == winding) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
flushBatchedDraws();
|
||||||
|
|
||||||
|
states.back().winding = winding;
|
||||||
|
}
|
||||||
|
|
||||||
void Graphics::setColorMask(ColorChannelMask mask) {
|
void Graphics::setColorMask(ColorChannelMask mask) {
|
||||||
flushBatchedDraws();
|
flushBatchedDraws();
|
||||||
|
|
||||||
@@ -308,7 +321,7 @@ namespace love {
|
|||||||
void Graphics::draw(const DrawCommand& cmd) {
|
void Graphics::draw(const DrawCommand& cmd) {
|
||||||
std::cout << "draw ";
|
std::cout << "draw ";
|
||||||
|
|
||||||
prepareDraw(*cmd.attributes, *cmd.buffers, cmd.texture, cmd.primitiveType);
|
prepareDraw(*cmd.attributes, *cmd.buffers, cmd.texture, cmd.primitiveType, cmd.cullMode);
|
||||||
|
|
||||||
vkCmdDraw(commandBuffers.at(imageIndex), static_cast<uint32_t>(cmd.vertexCount), static_cast<uint32_t>(cmd.instanceCount), static_cast<uint32_t>(cmd.vertexStart), 0);
|
vkCmdDraw(commandBuffers.at(imageIndex), static_cast<uint32_t>(cmd.vertexCount), static_cast<uint32_t>(cmd.instanceCount), static_cast<uint32_t>(cmd.vertexStart), 0);
|
||||||
}
|
}
|
||||||
@@ -316,7 +329,7 @@ namespace love {
|
|||||||
void Graphics::draw(const DrawIndexedCommand& cmd) {
|
void Graphics::draw(const DrawIndexedCommand& cmd) {
|
||||||
std::cout << "drawIndexed ";
|
std::cout << "drawIndexed ";
|
||||||
|
|
||||||
prepareDraw(*cmd.attributes, *cmd.buffers, cmd.texture, cmd.primitiveType);
|
prepareDraw(*cmd.attributes, *cmd.buffers, cmd.texture, cmd.primitiveType, cmd.cullMode);
|
||||||
|
|
||||||
vkCmdBindIndexBuffer(commandBuffers.at(imageIndex), (VkBuffer)cmd.indexBuffer->getHandle(), static_cast<VkDeviceSize>(cmd.indexBufferOffset), getVulkanIndexBufferType(cmd.indexType));
|
vkCmdBindIndexBuffer(commandBuffers.at(imageIndex), (VkBuffer)cmd.indexBuffer->getHandle(), static_cast<VkDeviceSize>(cmd.indexBufferOffset), getVulkanIndexBufferType(cmd.indexType));
|
||||||
vkCmdDrawIndexed(commandBuffers.at(imageIndex), static_cast<uint32_t>(cmd.indexCount), static_cast<uint32_t>(cmd.instanceCount), 0, 0, 0);
|
vkCmdDrawIndexed(commandBuffers.at(imageIndex), static_cast<uint32_t>(cmd.indexCount), static_cast<uint32_t>(cmd.instanceCount), 0, 0, 0);
|
||||||
@@ -384,7 +397,7 @@ namespace love {
|
|||||||
const int MAX_VERTICES_PER_DRAW = LOVE_UINT16_MAX;
|
const int MAX_VERTICES_PER_DRAW = LOVE_UINT16_MAX;
|
||||||
const int MAX_QUADS_PER_DRAW = MAX_VERTICES_PER_DRAW / 4;
|
const int MAX_QUADS_PER_DRAW = MAX_VERTICES_PER_DRAW / 4;
|
||||||
|
|
||||||
prepareDraw(attributes, buffers, texture, PRIMITIVE_TRIANGLES);
|
prepareDraw(attributes, buffers, texture, PRIMITIVE_TRIANGLES, CULL_BACK);
|
||||||
|
|
||||||
vkCmdBindIndexBuffer(commandBuffers.at(imageIndex), (VkBuffer)quadIndexBuffer->getHandle(), 0, getVulkanIndexBufferType(INDEX_UINT16));
|
vkCmdBindIndexBuffer(commandBuffers.at(imageIndex), (VkBuffer)quadIndexBuffer->getHandle(), 0, getVulkanIndexBufferType(INDEX_UINT16));
|
||||||
|
|
||||||
@@ -1237,12 +1250,14 @@ namespace love {
|
|||||||
configuration.vertexInputAttributeDescriptions = attributeDescriptions;
|
configuration.vertexInputAttributeDescriptions = attributeDescriptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::prepareDraw(const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture, PrimitiveType primitiveType) {
|
void Graphics::prepareDraw(const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture, PrimitiveType primitiveType, CullMode cullmode) {
|
||||||
GraphicsPipelineConfiguration configuration;
|
GraphicsPipelineConfiguration configuration;
|
||||||
configuration.shader = (Shader*)Shader::current;
|
configuration.shader = (Shader*)Shader::current;
|
||||||
configuration.primitiveType = primitiveType;
|
configuration.primitiveType = primitiveType;
|
||||||
configuration.polygonMode = currentPolygonMode;
|
configuration.polygonMode = currentPolygonMode;
|
||||||
configuration.blendState = states.back().blend;
|
configuration.blendState = states.back().blend;
|
||||||
|
configuration.winding = states.back().winding;
|
||||||
|
configuration.cullmode = cullmode;
|
||||||
std::vector<VkBuffer> bufferVector;
|
std::vector<VkBuffer> bufferVector;
|
||||||
|
|
||||||
std::vector<VkDeviceSize> offsets;
|
std::vector<VkDeviceSize> offsets;
|
||||||
@@ -1316,8 +1331,8 @@ namespace love {
|
|||||||
rasterizer.rasterizerDiscardEnable = VK_FALSE;
|
rasterizer.rasterizerDiscardEnable = VK_FALSE;
|
||||||
rasterizer.polygonMode = configuration.polygonMode;
|
rasterizer.polygonMode = configuration.polygonMode;
|
||||||
rasterizer.lineWidth = 1.0f;
|
rasterizer.lineWidth = 1.0f;
|
||||||
rasterizer.cullMode = VK_CULL_MODE_FRONT_BIT;
|
rasterizer.cullMode = Vulkan::getCullMode(configuration.cullmode);
|
||||||
rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE;
|
rasterizer.frontFace = Vulkan::getFrontFace(configuration.winding);
|
||||||
rasterizer.depthBiasEnable = VK_FALSE;
|
rasterizer.depthBiasEnable = VK_FALSE;
|
||||||
rasterizer.depthBiasConstantFactor = 0.0f;
|
rasterizer.depthBiasConstantFactor = 0.0f;
|
||||||
rasterizer.depthBiasClamp = 0.0f;
|
rasterizer.depthBiasClamp = 0.0f;
|
||||||
@@ -1498,6 +1513,12 @@ namespace love {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const GraphicsPipelineConfiguration& first, const GraphicsPipelineConfiguration& other) {
|
bool operator==(const GraphicsPipelineConfiguration& first, const GraphicsPipelineConfiguration& other) {
|
||||||
|
if (first.cullmode != other.cullmode) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (first.winding != other.winding) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (first.colorChannelMask != other.colorChannelMask) {
|
if (first.colorChannelMask != other.colorChannelMask) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ namespace love {
|
|||||||
VkPolygonMode polygonMode = VK_POLYGON_MODE_FILL;
|
VkPolygonMode polygonMode = VK_POLYGON_MODE_FILL;
|
||||||
BlendState blendState;
|
BlendState blendState;
|
||||||
ColorChannelMask colorChannelMask;
|
ColorChannelMask colorChannelMask;
|
||||||
|
Winding winding;
|
||||||
|
CullMode cullmode;
|
||||||
|
|
||||||
friend static bool operator==(const GraphicsPipelineConfiguration& first, const GraphicsPipelineConfiguration& other);
|
friend static bool operator==(const GraphicsPipelineConfiguration& first, const GraphicsPipelineConfiguration& other);
|
||||||
};
|
};
|
||||||
@@ -99,7 +101,7 @@ namespace love {
|
|||||||
void setScissor() override { std::cout << "setScissor2 "; }
|
void setScissor() override { std::cout << "setScissor2 "; }
|
||||||
void setStencilMode(StencilAction action, CompareMode compare, int value, love::uint32 readmask, love::uint32 writemask) override { std::cout << "setStencilMode "; }
|
void setStencilMode(StencilAction action, CompareMode compare, int value, love::uint32 readmask, love::uint32 writemask) override { std::cout << "setStencilMode "; }
|
||||||
void setDepthMode(CompareMode compare, bool write) override { std::cout << "setDepthMode "; }
|
void setDepthMode(CompareMode compare, bool write) override { std::cout << "setDepthMode "; }
|
||||||
void setFrontFaceWinding(Winding winding) override { std::cout << "setFrontFaceWinding "; }
|
void setFrontFaceWinding(Winding winding) override;
|
||||||
void setColorMask(ColorChannelMask mask) override;
|
void setColorMask(ColorChannelMask mask) override;
|
||||||
void setBlendState(const BlendState& blend) override;
|
void setBlendState(const BlendState& blend) override;
|
||||||
void setPointSize(float size) override;
|
void setPointSize(float size) override;
|
||||||
@@ -175,7 +177,7 @@ namespace love {
|
|||||||
VkDescriptorSet* getDescriptorSet(int currentFrame);
|
VkDescriptorSet* getDescriptorSet(int currentFrame);
|
||||||
graphics::StreamBuffer* getUniformBuffer();
|
graphics::StreamBuffer* getUniformBuffer();
|
||||||
void createVulkanVertexFormat(VertexAttributes vertexAttributes, bool& useConstantVertexColor, GraphicsPipelineConfiguration& configuration);
|
void createVulkanVertexFormat(VertexAttributes vertexAttributes, bool& useConstantVertexColor, GraphicsPipelineConfiguration& configuration);
|
||||||
void prepareDraw(const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture, PrimitiveType);
|
void prepareDraw(const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture, PrimitiveType, CullMode);
|
||||||
|
|
||||||
VkInstance instance = VK_NULL_HANDLE;
|
VkInstance instance = VK_NULL_HANDLE;
|
||||||
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
|
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
|
||||||
|
|||||||
@@ -374,6 +374,30 @@ namespace love {
|
|||||||
|
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkFrontFace Vulkan::getFrontFace(Winding winding) {
|
||||||
|
switch (winding) {
|
||||||
|
case WINDING_CW:
|
||||||
|
return VK_FRONT_FACE_CLOCKWISE;
|
||||||
|
case WINDING_CCW:
|
||||||
|
return VK_FRONT_FACE_COUNTER_CLOCKWISE;
|
||||||
|
default:
|
||||||
|
throw love::Exception("unknown winding");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VkCullModeFlags Vulkan::getCullMode(CullMode cullmode) {
|
||||||
|
switch (cullmode) {
|
||||||
|
case CULL_BACK:
|
||||||
|
return VK_CULL_MODE_BACK_BIT;
|
||||||
|
case CULL_FRONT:
|
||||||
|
return VK_CULL_MODE_FRONT_BIT;
|
||||||
|
case CULL_NONE:
|
||||||
|
return VK_CULL_MODE_NONE;
|
||||||
|
default:
|
||||||
|
throw love::Exception("unknown cull mode");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ namespace love {
|
|||||||
static VkBlendOp getBlendOp(BlendOperation);
|
static VkBlendOp getBlendOp(BlendOperation);
|
||||||
static VkBool32 getBool(bool);
|
static VkBool32 getBool(bool);
|
||||||
static VkColorComponentFlags getColorMask(ColorChannelMask);
|
static VkColorComponentFlags getColorMask(ColorChannelMask);
|
||||||
|
static VkFrontFace getFrontFace(Winding);
|
||||||
|
static VkCullModeFlags getCullMode(CullMode);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user