diff --git a/src/SHADERed/Objects/PipelineItem.h b/src/SHADERed/Objects/PipelineItem.h index 5054e585..3c86277d 100644 --- a/src/SHADERed/Objects/PipelineItem.h +++ b/src/SHADERed/Objects/PipelineItem.h @@ -182,10 +182,12 @@ namespace ed { Scale = glm::vec3(1, 1, 1); Topology = GL_TRIANGLES; Buffer = 0; + IndexBuffer = 0; VAO = 0; } void* Buffer; + void* IndexBuffer; GLuint VAO; unsigned int Topology; diff --git a/src/SHADERed/Objects/ProjectParser.cpp b/src/SHADERed/Objects/ProjectParser.cpp index e9ae39b4..b6999c92 100644 --- a/src/SHADERed/Objects/ProjectParser.cpp +++ b/src/SHADERed/Objects/ProjectParser.cpp @@ -1260,7 +1260,11 @@ namespace ed { pipe::VertexBuffer* tData = reinterpret_cast(item->Data); - itemNode.append_child("buffer").text().set(m_objects->GetBufferNameByID(((ed::BufferObject*)tData->Buffer)->ID).c_str()); + if(tData->Buffer) + itemNode.append_child("buffer").text().set(m_objects->GetBufferNameByID(((ed::BufferObject*)tData->Buffer)->ID).c_str()); + if(tData->IndexBuffer) + itemNode.append_child("indexbuffer").text().set(m_objects->GetBufferNameByID(((ed::BufferObject*)tData->IndexBuffer)->ID).c_str()); + if (tData->Scale.x != 1.0f) itemNode.append_child("scaleX").text().set(tData->Scale.x); if (tData->Scale.y != 1.0f) @@ -1304,7 +1308,7 @@ namespace ed { void ProjectParser::m_importItems(const char* name, pipe::ShaderPass* data, const pugi::xml_node& node, const std::vector& inpLayout, std::map>& geoUBOs, std::map>& modelUBOs, - std::map>& vbUBOs) + std::map>& vbUBOs) { for (pugi::xml_node itemNode : node.children()) { char itemName[PIPELINE_ITEM_NAME_LENGTH]; @@ -1503,10 +1507,13 @@ namespace ed { pipe::VertexBuffer* vbData = (pipe::VertexBuffer*)itemData; vbData->Buffer = 0; + vbData->IndexBuffer = 0; vbData->Scale = glm::vec3(1, 1, 1); vbData->Position = glm::vec3(0, 0, 0); vbData->Rotation = glm::vec3(0, 0, 0); + vbUBOs[vbData] = std::make_tuple("", "", data); + for (pugi::xml_node attrNode : itemNode.children()) { if (strcmp(attrNode.name(), "scaleX") == 0) vbData->Scale.x = attrNode.text().as_float(); @@ -1527,7 +1534,9 @@ namespace ed { else if (strcmp(attrNode.name(), "z") == 0) vbData->Position.z = attrNode.text().as_float(); else if (strcmp(attrNode.name(), "buffer") == 0) - vbUBOs[vbData] = std::make_pair(attrNode.text().as_string(), data); + std::get<0>(vbUBOs[vbData]) = attrNode.text().as_string(); + else if (strcmp(attrNode.name(), "indexbuffer") == 0) + std::get<1>(vbUBOs[vbData]) = attrNode.text().as_string(); else if (strcmp(attrNode.name(), "topology") == 0) { for (int k = 0; k < HARRAYSIZE(TOPOLOGY_ITEM_NAMES); k++) if (strcmp(attrNode.text().as_string(), TOPOLOGY_ITEM_NAMES[k]) == 0) @@ -2201,7 +2210,7 @@ namespace ed { std::map> fbos; std::map> geoUBOs; // buffers that are bound to pipeline items std::map> modelUBOs; - std::map> vbUBOs; + std::map> vbUBOs; // shader passes for (pugi::xml_node passNode : projectNode.child("pipeline").children("pass")) { @@ -3073,11 +3082,14 @@ namespace ed { } } for (auto& vb : vbUBOs) { - BufferObject* bobj = m_objects->GetBuffer(vb.second.first); + BufferObject* bobj = m_objects->GetBuffer(std::get<0>(vb.second)); vb.first->Buffer = bobj; if (bobj) gl::CreateBufferVAO(vb.first->VAO, bobj->ID, m_objects->ParseBufferFormat(bobj->ViewFormat)); + + BufferObject* ibobj = m_objects->GetBuffer(std::get<1>(vb.second)); + vb.first->IndexBuffer = ibobj; } // bind objects diff --git a/src/SHADERed/Objects/ProjectParser.h b/src/SHADERed/Objects/ProjectParser.h index 4d503c42..cd43dc3a 100644 --- a/src/SHADERed/Objects/ProjectParser.h +++ b/src/SHADERed/Objects/ProjectParser.h @@ -81,7 +81,7 @@ namespace ed { void m_importItems(const char* owner, pipe::ShaderPass* data, const pugi::xml_node& node, const std::vector& inpLayout, std::map>& geoUBOs, std::map>& modelUBOs, - std::map>& vbUBOs); // TODO: why not just use PipelineItem + std::map>& vbUBOs); // TODO: why not just use PipelineItem bool m_modified; diff --git a/src/SHADERed/Objects/RenderEngine.cpp b/src/SHADERed/Objects/RenderEngine.cpp index 4d497574..f1ace335 100644 --- a/src/SHADERed/Objects/RenderEngine.cpp +++ b/src/SHADERed/Objects/RenderEngine.cpp @@ -358,7 +358,18 @@ namespace ed { data->Variables.Bind(item); glBindVertexArray(vbData->VAO); - glDrawArrays(vbData->Topology, 0, vertCount); + + if(vbData->IndexBuffer) { + ed::BufferObject* ibobj = (ed::BufferObject*)vbData->IndexBuffer; + auto fmt = m_objects->ParseBufferFormat(ibobj->ViewFormat); + + // Todo: There might be use cases where index buffers are a short or byte. The current view format does not allow expressing that, however + if(fmt.size() == 1 && fmt[0] == ShaderVariable::ValueType::Integer1) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibobj->ID); + glDrawElements(vbData->Topology, ibobj->Size / sizeof(uint32_t), GL_UNSIGNED_INT, nullptr); + } + } else + glDrawArrays(vbData->Topology, 0, vertCount); } } } else if (item->Type == PipelineItem::ItemType::RenderState) { diff --git a/src/SHADERed/UI/PreviewUI.cpp b/src/SHADERed/UI/PreviewUI.cpp index 16109fd1..2c245329 100644 --- a/src/SHADERed/UI/PreviewUI.cpp +++ b/src/SHADERed/UI/PreviewUI.cpp @@ -978,13 +978,15 @@ namespace ed { pos = model->Position; } else if (item->Type == ed::PipelineItem::ItemType::VertexBuffer) { pipe::VertexBuffer* vertBuffer = (pipe::VertexBuffer*)item->Data; - gl::GetVertexBufferBounds(&m_data->Objects, vertBuffer, minPosItem, maxPosItem); - - minPosItem *= vertBuffer->Scale; - maxPosItem *= vertBuffer->Scale; + if(vertBuffer->Buffer) { + gl::GetVertexBufferBounds(&m_data->Objects, vertBuffer, minPosItem, maxPosItem); - rota = vertBuffer->Rotation; - pos = vertBuffer->Position; + minPosItem *= vertBuffer->Scale; + maxPosItem *= vertBuffer->Scale; + + rota = vertBuffer->Rotation; + pos = vertBuffer->Position; + } } else if (item->Type == ed::PipelineItem::ItemType::PluginItem) { pipe::PluginItemData* pldata = (pipe::PluginItemData*)item->Data; diff --git a/src/SHADERed/UI/PropertyUI.cpp b/src/SHADERed/UI/PropertyUI.cpp index df6ecabb..260f194d 100644 --- a/src/SHADERed/UI/PropertyUI.cpp +++ b/src/SHADERed/UI/PropertyUI.cpp @@ -971,6 +971,36 @@ namespace ed { ImGui::NextColumn(); ImGui::Separator(); + /* buffers */ + ImGui::Text("Index Buffer:"); + ImGui::NextColumn(); + + ImGui::PushItemWidth(-1); + if (ImGui::BeginCombo("##pui_ib_buffer", ((item->IndexBuffer == nullptr) ? "NULL" : (m_data->Objects.GetBufferNameByID(((BufferObject*)item->IndexBuffer)->ID).c_str())))) { + // null element + if (ImGui::Selectable("NULL", item->IndexBuffer == nullptr)) { + item->IndexBuffer = nullptr; + m_data->Parser.ModifyProject(); + } + + for (int i = 0; i < bufList.size(); i++) { + if (bufList[i]->Buffer == nullptr) + continue; + + ed::BufferObject* buf = bufList[i]->Buffer; + + if (ImGui::Selectable(bufNames[i].c_str(), buf == item->IndexBuffer)) { + item->IndexBuffer = buf; + m_data->Parser.ModifyProject(); + } + } + + ImGui::EndCombo(); + } + ImGui::PopItemWidth(); + ImGui::NextColumn(); + ImGui::Separator(); + /* position */ ImGui::Text("Position:"); ImGui::NextColumn();