Hi,
I'm trying to get imgui to work with ogre-next on a vulkan samsung galaxy s25 android phone (Imgui does not render on it, but the main ogre next mesh/etc renders fine).
It works fine with vulkan on windows and vulkan on a galaxy s9 android phone.
I'm using the imgui code from: https://github.com/edherbert/ogre-next-imgui
I read in another post that it can be done with creating another compositor pass. I've done this, and I can see through renderdoc that the projection matrix uniform comes through and the inputs looks correct, but the output was all like -1 or 0s.
Before creating another compositor pass the projection matrix uniform was not getting through. I tested this by just assigning the gl_Position to 4 values of the projection matrix in the shader.
After using a custom compositor pass for imgui, the projection matrix seems to be getting through fine now (checked with renderDoc), but the vertices position, uv, color doesn't seem to be making it through.
The main changes I made in the ImguiManager is to split up the rendering into two parts. preRender() and render(Ogre::RenderPassDescriptor *renderPass) (The renderpass is passed in from the compositor pass execute().) preRender() is called before renderOneFrame().
I'm probably not using the mPSOCache cache correctly. I tried making it look like what is in the information in OgrePsoCacheHelper.h.
preRender:
Code: Select all
void ImguiManager::preRender() {
#ifdef __APPLE__
@autoreleasepool {
#endif
numberOfDrawsForFrame = 0;
Ogre::RenderSystem* renderSystem = mSceneMgr->getDestinationRenderSystem();
if (!renderPassDesc) {
renderPassDesc = renderSystem->createRenderPassDescriptor();
renderPassDesc->mColour[0].texture = mCompositor->getFinalTarget();
renderPassDesc->mColour[0].loadAction = Ogre::LoadAction::Load;
renderPassDesc->mColour[0].storeAction = Ogre::StoreAction::StoreAndMultisampleResolve;
renderPassDesc->entriesModified(Ogre::RenderPassDescriptor::All);
}
Ogre::Vector4 viewportSize(0, 0, 1, 1);
Ogre::Vector4 scissors(0, 0, 1, 1);
// renderSystem->beginRenderPassDescriptor(renderPassDesc, mCompositor->getFinalTarget(), 0, &viewportSize, &scissors, 1, false, false);
// renderSystem->executeRenderPassDescriptorDelayedActions();
// Cancel rendering if not necessary
// or if newFrame didn't got called
if (mFrameEnded)
return;
mFrameEnded = true;
currentFrame = ImGui::GetFrameCount();
if (currentFrame == mLastRenderedFrame) {
LOGE("ImguiManager::render return");
return;
}
mLastRenderedFrame = currentFrame;
// Tell ImGui to create the buffers
ImGui::Render();
// if (currentFrame <= 1) {
// Lots of stuff can be done only once for the sake of efficiency.
mPSOCache->clearState();
const Ogre::HlmsBlendblock* blendblock = mPass->getBlendblock();
const Ogre::HlmsMacroblock* macroblock = mPass->getMacroblock();
mPSOCache->setMacroblock(macroblock);
mPSOCache->setBlendblock(blendblock);
mPSOCache->setVertexShader(const_cast<Ogre::GpuProgramPtr&>(mPass->getVertexProgram()));
mPSOCache->setPixelShader(const_cast<Ogre::GpuProgramPtr&>(mPass->getFragmentProgram()));
// }
ImDrawData* drawData = ImGui::GetDrawData();
int numberDraws = 0;
int vpWidth = mCompositor->getFinalTarget()->getWidth();
int vpHeight = mCompositor->getFinalTarget()->getHeight();
// iterate through all lists (at the moment every window has its own)
for (int n = 0; n < drawData->CmdListsCount; n++) {
const ImDrawList* drawList = drawData->CmdLists[n];
const ImDrawVert* vtxBuf = drawList->VtxBuffer.Data;
const ImDrawIdx* idxBuf = drawList->IdxBuffer.Data;
unsigned int startIdx = 0;
for (int i = 0; i < drawList->CmdBuffer.Size; i++) {
// create renderables if necessary
// This creates a new one each time it notices the list is bigger than necessary.
// if (i >= mRenderables.size()) {
mRenderables.push_back(new ImguiRenderable());
// }
int currentRenderableIndex = mRenderables.size() - 1;
// update their vertex buffers
const ImDrawCmd* drawCmd = &drawList->CmdBuffer[i];
mRenderables[currentRenderableIndex]->updateVertexData(vtxBuf, &idxBuf[startIdx], drawList->VtxBuffer.Size, drawCmd->ElemCount);
mRenderables[currentRenderableIndex]->textureGpu = (Ogre::TextureGpu*)drawCmd->TextureId;
// renderSystem->beginRenderPassDescriptor(renderPassDesc, mCompositor->getFinalTarget(), 0, &viewportSize, &scissors, 1, false, false);
// renderSystem->executeRenderPassDescriptorDelayedActions();
Ogre::v1::RenderOperation renderOp;
mRenderables[currentRenderableIndex]->getRenderOperation(renderOp, false);
bool enablePrimitiveRestart = true; // tried both true and false...no change
Ogre::VertexElement2VecVec vertexElements = renderOp.vertexData->vertexDeclaration->convertToV2();
mPSOCache->setVertexFormat(vertexElements,
renderOp.operationType,
enablePrimitiveRestart);
mRenderables[currentRenderableIndex]->customSavedValue = mPSOCache->getRenderableHash();
// increase start index of indexbuffer
startIdx += drawCmd->ElemCount;
numberDraws++;
numberOfDrawsForFrame++;
}
}
// delete unused renderables
// while (mRenderables.size() > numberDraws) {
// // LOGE("ImGui::Render() here 3");
// delete mRenderables.back();
// mRenderables.pop_back();
// }
#ifdef __APPLE__
}
#endif
}
````
render:
```c
void ImguiManager::render(Ogre::RenderPassDescriptor *renderPass) {
int numberDraws = 0;
if (numberOfDrawsForFrame > 0) {
mPSOCache->clearState();
mPSOCache->setRenderTarget(renderPass); // dark_sylinc's advice on setting rendertarget, which looks like the renderwindow obj)
}
for (int i = 0; i < numberOfDrawsForFrame; i++) {
Ogre::v1::RenderOperation renderOp;
mRenderables[i]->getRenderOperation(renderOp, false);
bool enablePrimitiveRestart = true; // tried both true and false...no change
Ogre::VertexElement2VecVec vertexElements = renderOp.vertexData->vertexDeclaration->convertToV2();
mPSOCache->setVertexFormat(vertexElements,
renderOp.operationType,
enablePrimitiveRestart);
Ogre::HlmsPso* pso = mPSOCache->getPso(mRenderables[i]->customSavedValue);
mSceneMgr->getDestinationRenderSystem()->_setPipelineStateObject(pso);
mSceneMgr->getDestinationRenderSystem()->bindGpuProgramParameters(Ogre::GPT_VERTEX_PROGRAM, mPass->getVertexProgramParameters(), Ogre::GPV_ALL);
Ogre::TextureGpu* texGpu = (Ogre::TextureGpu*) mRenderables[i]->textureGpu; // drawCmd->TextureId;
mSceneMgr->getDestinationRenderSystem()->_setTexture(0, texGpu, false);
mSceneMgr->getDestinationRenderSystem()->_setHlmsSamplerblock(0, mSamplerblock);
Ogre::v1::CbRenderOp op(renderOp);
mSceneMgr->getDestinationRenderSystem()->_setRenderOperation(&op);
mSceneMgr->getDestinationRenderSystem()->_render(renderOp);
numberDraws++;
}
// delete unused renderables
while (mRenderables.size() > 0) {
delete mRenderables.back();
mRenderables.pop_back();
}
}