mirror of https://github.com/auygun/kaliber.git
Fix for index buffer
- Fix index data offset in Vulkan geometry buffer. - Normalize vertex colors. - Add support for drawing from a given index offset.
This commit is contained in:
parent
2823aa3197
commit
14b2d22fbd
|
@ -26,6 +26,9 @@ constexpr GLenum kGlDataType[eng::kDataType_Max] = {
|
||||||
GL_UNSIGNED_BYTE, GL_FLOAT, GL_INT,
|
GL_UNSIGNED_BYTE, GL_FLOAT, GL_INT,
|
||||||
GL_SHORT, GL_UNSIGNED_INT, GL_UNSIGNED_SHORT};
|
GL_SHORT, GL_UNSIGNED_INT, GL_UNSIGNED_SHORT};
|
||||||
|
|
||||||
|
constexpr GLboolean kGlNormalize[eng::kDataType_Max] = {
|
||||||
|
GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE};
|
||||||
|
|
||||||
const std::string kAttributeNames[eng::kAttribType_Max] = {
|
const std::string kAttributeNames[eng::kAttribType_Max] = {
|
||||||
"in_color", "in_normal", "in_position", "in_tex_coord"};
|
"in_color", "in_normal", "in_position", "in_tex_coord"};
|
||||||
|
|
||||||
|
@ -132,11 +135,16 @@ void RendererOpenGL::DestroyGeometry(uint64_t resource_id) {
|
||||||
geometries_.erase(it);
|
geometries_.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererOpenGL::Draw(uint64_t resource_id) {
|
void RendererOpenGL::Draw(uint64_t resource_id,
|
||||||
|
uint64_t num_indices,
|
||||||
|
uint64_t start_offset) {
|
||||||
auto it = geometries_.find(resource_id);
|
auto it = geometries_.find(resource_id);
|
||||||
if (it == geometries_.end())
|
if (it == geometries_.end())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (num_indices == 0)
|
||||||
|
num_indices = it->second.num_indices;
|
||||||
|
|
||||||
// Set up the vertex data.
|
// Set up the vertex data.
|
||||||
if (it->second.vertex_array_id)
|
if (it->second.vertex_array_id)
|
||||||
glBindVertexArray(it->second.vertex_array_id);
|
glBindVertexArray(it->second.vertex_array_id);
|
||||||
|
@ -152,14 +160,14 @@ void RendererOpenGL::Draw(uint64_t resource_id) {
|
||||||
(const GLvoid*)e.vertex_offset);
|
(const GLvoid*)e.vertex_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (it->second.num_indices > 0)
|
if (num_indices > 0)
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, it->second.index_buffer_id);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, it->second.index_buffer_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw the primitive.
|
// Draw the primitive.
|
||||||
if (it->second.num_indices > 0)
|
if (num_indices > 0)
|
||||||
glDrawElements(it->second.primitive, it->second.num_indices,
|
glDrawElements(it->second.primitive, num_indices, it->second.index_type,
|
||||||
it->second.index_type, NULL);
|
(void*)(intptr_t)(start_offset * sizeof(unsigned short)));
|
||||||
else
|
else
|
||||||
glDrawArrays(it->second.primitive, 0, it->second.num_vertices);
|
glDrawArrays(it->second.primitive, 0, it->second.num_vertices);
|
||||||
|
|
||||||
|
@ -446,7 +454,7 @@ bool RendererOpenGL::InitCommon() {
|
||||||
#if 0
|
#if 0
|
||||||
LOG(0) << " extensions:";
|
LOG(0) << " extensions:";
|
||||||
for (auto& ext : extensions)
|
for (auto& ext : extensions)
|
||||||
LOG(0) << " " << ext.c_str());
|
LOG(0) << " " << ext.c_str();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Check for supported texture compression extensions.
|
// Check for supported texture compression extensions.
|
||||||
|
@ -465,7 +473,8 @@ bool RendererOpenGL::InitCommon() {
|
||||||
extensions.find("GL_ATI_texture_compression_atitc") != extensions.end())
|
extensions.find("GL_ATI_texture_compression_atitc") != extensions.end())
|
||||||
texture_compression_.atc = true;
|
texture_compression_.atc = true;
|
||||||
|
|
||||||
if (extensions.find("GL_OES_vertex_array_object") != extensions.end()) {
|
if (extensions.find("GL_OES_vertex_array_object") != extensions.end() ||
|
||||||
|
extensions.find("GL_ARB_vertex_array_object") != extensions.end()) {
|
||||||
// This extension seems to be broken on older PowerVR drivers.
|
// This extension seems to be broken on older PowerVR drivers.
|
||||||
if (!strstr(renderer, "PowerVR SGX 53") &&
|
if (!strstr(renderer, "PowerVR SGX 53") &&
|
||||||
!strstr(renderer, "PowerVR SGX 54") &&
|
!strstr(renderer, "PowerVR SGX 54") &&
|
||||||
|
@ -555,8 +564,9 @@ bool RendererOpenGL::SetupVertexLayout(
|
||||||
if (use_vao) {
|
if (use_vao) {
|
||||||
// This will be saved into the vertex array object.
|
// This will be saved into the vertex array object.
|
||||||
glEnableVertexAttribArray(attribute_index);
|
glEnableVertexAttribArray(attribute_index);
|
||||||
glVertexAttribPointer(attribute_index, num_elements, type, GL_FALSE,
|
glVertexAttribPointer(attribute_index, num_elements, type,
|
||||||
vertex_size, (const GLvoid*)vertex_offset);
|
kGlNormalize[data_type], vertex_size,
|
||||||
|
(const GLvoid*)vertex_offset);
|
||||||
} else {
|
} else {
|
||||||
// Need to keep this information for when rendering.
|
// Need to keep this information for when rendering.
|
||||||
GeometryOpenGL::Element element;
|
GeometryOpenGL::Element element;
|
||||||
|
|
|
@ -33,7 +33,9 @@ class RendererOpenGL final : public Renderer {
|
||||||
|
|
||||||
uint64_t CreateGeometry(std::unique_ptr<Mesh> mesh) final;
|
uint64_t CreateGeometry(std::unique_ptr<Mesh> mesh) final;
|
||||||
void DestroyGeometry(uint64_t resource_id) final;
|
void DestroyGeometry(uint64_t resource_id) final;
|
||||||
void Draw(uint64_t resource_id) final;
|
void Draw(uint64_t resource_id,
|
||||||
|
uint64_t num_indices = 0,
|
||||||
|
uint64_t start_offset = 0) final;
|
||||||
|
|
||||||
uint64_t CreateTexture() final;
|
uint64_t CreateTexture() final;
|
||||||
void UpdateTexture(uint64_t resource_id, std::unique_ptr<Image> image) final;
|
void UpdateTexture(uint64_t resource_id, std::unique_ptr<Image> image) final;
|
||||||
|
|
|
@ -40,7 +40,9 @@ class Renderer {
|
||||||
|
|
||||||
virtual uint64_t CreateGeometry(std::unique_ptr<Mesh> mesh) = 0;
|
virtual uint64_t CreateGeometry(std::unique_ptr<Mesh> mesh) = 0;
|
||||||
virtual void DestroyGeometry(uint64_t resource_id) = 0;
|
virtual void DestroyGeometry(uint64_t resource_id) = 0;
|
||||||
virtual void Draw(uint64_t resource_id) = 0;
|
virtual void Draw(uint64_t resource_id,
|
||||||
|
uint64_t num_indices = 0,
|
||||||
|
uint64_t start_offset = 0) = 0;
|
||||||
|
|
||||||
virtual uint64_t CreateTexture() = 0;
|
virtual uint64_t CreateTexture() = 0;
|
||||||
virtual void UpdateTexture(uint64_t resource_id,
|
virtual void UpdateTexture(uint64_t resource_id,
|
||||||
|
|
|
@ -155,10 +155,10 @@ constexpr VkPrimitiveTopology kVkPrimitiveType[eng::kPrimitive_Max] = {
|
||||||
|
|
||||||
constexpr VkFormat kVkDataType[eng::kDataType_Max][4] = {
|
constexpr VkFormat kVkDataType[eng::kDataType_Max][4] = {
|
||||||
{
|
{
|
||||||
VK_FORMAT_R8_UINT,
|
VK_FORMAT_R8_UNORM,
|
||||||
VK_FORMAT_R8G8_UINT,
|
VK_FORMAT_R8G8_UNORM,
|
||||||
VK_FORMAT_R8G8B8_UINT,
|
VK_FORMAT_R8G8B8_UNORM,
|
||||||
VK_FORMAT_R8G8B8A8_UINT,
|
VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
VK_FORMAT_R32_SFLOAT,
|
VK_FORMAT_R32_SFLOAT,
|
||||||
|
@ -400,7 +400,8 @@ uint64_t RendererVulkan::CreateGeometry(std::unique_ptr<Mesh> mesh) {
|
||||||
if (mesh->GetIndices()) {
|
if (mesh->GetIndices()) {
|
||||||
geometry.num_indices = mesh->num_indices();
|
geometry.num_indices = mesh->num_indices();
|
||||||
geometry.index_type = GetIndexType(mesh->index_description());
|
geometry.index_type = GetIndexType(mesh->index_description());
|
||||||
index_data_size = mesh->GetIndexSize() * geometry.num_indices;
|
geometry.index_type_size = mesh->GetIndexSize();
|
||||||
|
index_data_size = geometry.index_type_size * geometry.num_indices;
|
||||||
}
|
}
|
||||||
size_t data_size = vertex_data_size + index_data_size;
|
size_t data_size = vertex_data_size + index_data_size;
|
||||||
|
|
||||||
|
@ -414,10 +415,10 @@ uint64_t RendererVulkan::CreateGeometry(std::unique_ptr<Mesh> mesh) {
|
||||||
std::get<0>(geometry.buffer), 0,
|
std::get<0>(geometry.buffer), 0,
|
||||||
mesh->GetVertices(), vertex_data_size));
|
mesh->GetVertices(), vertex_data_size));
|
||||||
if (geometry.num_indices > 0) {
|
if (geometry.num_indices > 0) {
|
||||||
geometry.indices_offset = vertex_data_size;
|
geometry.index_data_offset = vertex_data_size;
|
||||||
task_runner_.PostTask(
|
task_runner_.PostTask(HERE, std::bind(&RendererVulkan::UpdateBuffer, this,
|
||||||
HERE, std::bind(&RendererVulkan::UpdateBuffer, this,
|
std::get<0>(geometry.buffer),
|
||||||
std::get<0>(geometry.buffer), geometry.indices_offset,
|
geometry.index_data_offset,
|
||||||
mesh->GetIndices(), index_data_size));
|
mesh->GetIndices(), index_data_size));
|
||||||
}
|
}
|
||||||
task_runner_.PostTask(HERE,
|
task_runner_.PostTask(HERE,
|
||||||
|
@ -442,20 +443,27 @@ void RendererVulkan::DestroyGeometry(uint64_t resource_id) {
|
||||||
geometries_.erase(it);
|
geometries_.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererVulkan::Draw(uint64_t resource_id) {
|
void RendererVulkan::Draw(uint64_t resource_id,
|
||||||
|
uint64_t num_indices,
|
||||||
|
uint64_t start_offset) {
|
||||||
auto it = geometries_.find(resource_id);
|
auto it = geometries_.find(resource_id);
|
||||||
if (it == geometries_.end())
|
if (it == geometries_.end())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
uint64_t data_offset = start_offset * it->second.index_type_size;
|
||||||
|
if (num_indices == 0)
|
||||||
|
num_indices = it->second.num_indices;
|
||||||
|
|
||||||
VkDeviceSize offset = 0;
|
VkDeviceSize offset = 0;
|
||||||
vkCmdBindVertexBuffers(frames_[current_frame_].draw_command_buffer, 0, 1,
|
vkCmdBindVertexBuffers(frames_[current_frame_].draw_command_buffer, 0, 1,
|
||||||
&std::get<0>(it->second.buffer), &offset);
|
&std::get<0>(it->second.buffer), &offset);
|
||||||
if (it->second.num_indices > 0) {
|
if (num_indices > 0) {
|
||||||
vkCmdBindIndexBuffer(frames_[current_frame_].draw_command_buffer,
|
vkCmdBindIndexBuffer(frames_[current_frame_].draw_command_buffer,
|
||||||
std::get<0>(it->second.buffer),
|
std::get<0>(it->second.buffer),
|
||||||
it->second.indices_offset, it->second.index_type);
|
it->second.index_data_offset + data_offset,
|
||||||
vkCmdDrawIndexed(frames_[current_frame_].draw_command_buffer,
|
it->second.index_type);
|
||||||
it->second.num_indices, 1, 0, 0, 0);
|
vkCmdDrawIndexed(frames_[current_frame_].draw_command_buffer, num_indices,
|
||||||
|
1, 0, 0, 0);
|
||||||
} else {
|
} else {
|
||||||
vkCmdDraw(frames_[current_frame_].draw_command_buffer,
|
vkCmdDraw(frames_[current_frame_].draw_command_buffer,
|
||||||
it->second.num_vertices, 1, 0, 0);
|
it->second.num_vertices, 1, 0, 0);
|
||||||
|
|
|
@ -35,7 +35,9 @@ class RendererVulkan final : public Renderer {
|
||||||
|
|
||||||
uint64_t CreateGeometry(std::unique_ptr<Mesh> mesh) final;
|
uint64_t CreateGeometry(std::unique_ptr<Mesh> mesh) final;
|
||||||
void DestroyGeometry(uint64_t resource_id) final;
|
void DestroyGeometry(uint64_t resource_id) final;
|
||||||
void Draw(uint64_t resource_id) final;
|
void Draw(uint64_t resource_id,
|
||||||
|
uint64_t num_indices = 0,
|
||||||
|
uint64_t start_offset = 0) final;
|
||||||
|
|
||||||
uint64_t CreateTexture() final;
|
uint64_t CreateTexture() final;
|
||||||
void UpdateTexture(uint64_t resource_id, std::unique_ptr<Image> image) final;
|
void UpdateTexture(uint64_t resource_id, std::unique_ptr<Image> image) final;
|
||||||
|
@ -101,7 +103,8 @@ class RendererVulkan final : public Renderer {
|
||||||
Buffer<VkBuffer> buffer;
|
Buffer<VkBuffer> buffer;
|
||||||
uint32_t num_vertices = 0;
|
uint32_t num_vertices = 0;
|
||||||
uint32_t num_indices = 0;
|
uint32_t num_indices = 0;
|
||||||
uint64_t indices_offset = 0;
|
uint64_t index_data_offset = 0;
|
||||||
|
uint64_t index_type_size = 0;
|
||||||
VkIndexType index_type = VK_INDEX_TYPE_UINT16;
|
VkIndexType index_type = VK_INDEX_TYPE_UINT16;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue