/** Event raised before a queue group is rendered. @remarks This method is called by the SceneManager before each queue group is rendered. @param queueGroupId The id of the queue group which is about to be rendered @param invocation Name of the invocation which is causing this to be called (@see RenderQueueInvocation) @param skipThisInvocation A boolean passed by reference which is by default set to false. If the event sets this to true, the queue will be skipped and not rendered. Note that in this case the renderQueueEnded event will not be raised for this queue group. */ void MuRenderQueueListener::renderQueueStarted(uint8 queueGroupId, const String& invocation, bool& skipThisInvocation) { if ( queueGroupId == RENDER_QUEUE_INVENTORY_ITEM) { RenderSystem* rs = GameFramework::getSingletonPtr()->renderSystem; Matrix4 ortho_proj_trick = GameFramework::getSingletonPtr()->cameraMan->camera_ortho_tricker->getProjectionMatrixRS(); Matrix4 view_trick = GameFramework::getSingletonPtr()->cameraMan->camera_ortho_tricker->getViewMatrix(); rs->_setProjectionMatrix(ortho_proj_trick); rs->_setViewMatrix(view_trick); } /*if ( queueGroupId == RENDER_QUEUE_INVENTORY_ITEM_GLOW) { RenderSystem* rs = GameFramework::getSingletonPtr()->renderSystem; Matrix4 ortho_proj_trick = GameFramework::getSingletonPtr()->camera_ortho_tricker->getProjectionMatrixRS(); Matrix4 view_trick = GameFramework::getSingletonPtr()->camera_ortho_tricker->getViewMatrix(); rs->_setProjectionMatrix(ortho_proj_trick); rs->_setViewMatrix(view_trick); Ogre::RenderSystem * rendersys = Ogre::Root::getSingleton().getRenderSystem(); rendersys->setStencilCheckEnabled(true); rendersys->setStencilBufferParams(Ogre::CMPF_NOT_EQUAL, STENCIL_VALUE_FOR_OUTLINE_GLOW, STENCIL_FULL_MASK, STENCIL_VALUE_FOR_OUTLINE_GLOW, Ogre::SOP_KEEP,Ogre::SOP_KEEP,Ogre::SOP_REPLACE,false); }*/ if (queueGroupId == RENDER_QUEUE_GLOW_OBJECTS) // outline glow object { //Ogre::RenderSystem * rendersys = Ogre::Root::getSingleton().getRenderSystem(); /*rendersys->clearFrameBuffer(Ogre::FBT_STENCIL); rendersys->setStencilCheckEnabled(true); rendersys->setStencilBufferParams(Ogre::CMPF_ALWAYS_PASS, STENCIL_VALUE_FOR_OUTLINE_GLOW, STENCIL_FULL_MASK, STENCIL_VALUE_FOR_OUTLINE_GLOW, Ogre::SOP_KEEP,Ogre::SOP_KEEP,Ogre::SOP_REPLACE, false); */ } if (queueGroupId == RENDER_QUEUE_OUTLINE_GLOW_GLOWS) // outline glow { /*Ogre::RenderSystem * rendersys = Ogre::Root::getSingleton().getRenderSystem(); rendersys->setStencilCheckEnabled(true); rendersys->setStencilBufferParams(Ogre::CMPF_NOT_EQUAL, STENCIL_VALUE_FOR_OUTLINE_GLOW, STENCIL_FULL_MASK, STENCIL_VALUE_FOR_OUTLINE_GLOW, Ogre::SOP_KEEP,Ogre::SOP_KEEP,Ogre::SOP_REPLACE,false); */ } }
/** Event raised after a queue group is rendered. @remarks This method is called by the SceneManager after each queue group is rendered. @param queueGroupId The id of the queue group which has just been rendered @param invocation Name of the invocation which is causing this to be called (@see RenderQueueInvocation) @param repeatThisInvocation A boolean passed by reference which is by default set to false. If the event sets this to true, the queue which has just been rendered will be repeated, and the renderQueueStarted and renderQueueEnded events will also be fired for it again. */ void MuRenderQueueListener::renderQueueEnded(uint8 queueGroupId, const String& invocation, bool& repeatThisInvocation) { if ( queueGroupId == RENDER_QUEUE_INVENTORY_ITEM) { RenderSystem* rs = GameFramework::getSingletonPtr()->renderSystem; Matrix4 ortho_proj_trick = GameFramework::getSingletonPtr()->camera->getProjectionMatrixRS(); Matrix4 view_trick = GameFramework::getSingletonPtr()->camera->getViewMatrix(); rs->_setProjectionMatrix(ortho_proj_trick); rs->_setViewMatrix(view_trick); } /*if ( queueGroupId == RENDER_QUEUE_INVENTORY_ITEM_GLOW) { RenderSystem* rs = GameFramework::getSingletonPtr()->renderSystem; Matrix4 ortho_proj_trick = GameFramework::getSingletonPtr()->camera->getProjectionMatrixRS(); Matrix4 view_trick = GameFramework::getSingletonPtr()->camera->getViewMatrix(); rs->_setProjectionMatrix(ortho_proj_trick); rs->_setViewMatrix(view_trick); Ogre::RenderSystem * rendersys = Ogre::Root::getSingleton().getRenderSystem(); rendersys->setStencilCheckEnabled(false); rendersys->setStencilBufferParams(); }*/ if (queueGroupId == RENDER_QUEUE_GLOW_OBJECTS) // outline glow object { /*Ogre::RenderSystem * rendersys = Ogre::Root::getSingleton().getRenderSystem(); rendersys->setStencilCheckEnabled(false); rendersys->setStencilBufferParams(); */ } if (queueGroupId == RENDER_QUEUE_OUTLINE_GLOW_GLOWS) // outline glow { /*Ogre::RenderSystem * rendersys = Ogre::Root::getSingleton().getRenderSystem(); rendersys->setStencilCheckEnabled(false); rendersys->setStencilBufferParams(); */ } }
//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void GLRenderToVertexBuffer::update(SceneManager* sceneMgr) { checkGLError(true, false, "start of GLRenderToVertexBuffer::update"); size_t bufSize = mVertexData->vertexDeclaration->getVertexSize(0) * mMaxVertexCount; if (mVertexBuffers[0].isNull() || mVertexBuffers[0]->getSizeInBytes() != bufSize) { //Buffers don't match. Need to reallocate. mResetRequested = true; } //Single pass only for now Ogre::Pass* r2vbPass = mMaterial->getBestTechnique()->getPass(0); //Set pass before binding buffers to activate the GPU programs sceneMgr->_setPass(r2vbPass); checkGLError(true, false); bindVerticesOutput(r2vbPass); RenderOperation renderOp; size_t targetBufferIndex; if (mResetRequested || mResetsEveryUpdate) { //Use source data to render to first buffer mSourceRenderable->getRenderOperation(renderOp); targetBufferIndex = 0; } else { //Use current front buffer to render to back buffer this->getRenderOperation(renderOp); targetBufferIndex = 1 - mFrontBufferIndex; } if (mVertexBuffers[targetBufferIndex].isNull() || mVertexBuffers[targetBufferIndex]->getSizeInBytes() != bufSize) { reallocateBuffer(targetBufferIndex); } GLHardwareVertexBuffer* vertexBuffer = static_cast<GLHardwareVertexBuffer*>(mVertexBuffers[targetBufferIndex].getPointer()); GLuint bufferId = vertexBuffer->getGLBufferId(); //Bind the target buffer glBindBufferOffsetNV(GL_TRANSFORM_FEEDBACK_BUFFER_NV, 0, bufferId, 0); glBeginTransformFeedbackNV(getR2VBPrimitiveType(mOperationType)); glEnable(GL_RASTERIZER_DISCARD_NV); // disable rasterization glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV, mPrimitivesDrawnQuery); RenderSystem* targetRenderSystem = Root::getSingleton().getRenderSystem(); //Draw the object targetRenderSystem->_setWorldMatrix(Matrix4::IDENTITY); targetRenderSystem->_setViewMatrix(Matrix4::IDENTITY); targetRenderSystem->_setProjectionMatrix(Matrix4::IDENTITY); if (r2vbPass->hasVertexProgram()) { targetRenderSystem->bindGpuProgramParameters(GPT_VERTEX_PROGRAM, r2vbPass->getVertexProgramParameters(), GPV_ALL); } if (r2vbPass->hasGeometryProgram()) { targetRenderSystem->bindGpuProgramParameters(GPT_GEOMETRY_PROGRAM, r2vbPass->getGeometryProgramParameters(), GPV_ALL); } targetRenderSystem->_render(renderOp); //Finish the query glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV); glDisable(GL_RASTERIZER_DISCARD_NV); glEndTransformFeedbackNV(); //read back query results GLuint primitivesWritten; glGetQueryObjectuiv(mPrimitivesDrawnQuery, GL_QUERY_RESULT, &primitivesWritten); mVertexData->vertexCount = primitivesWritten * getVertexCountPerPrimitive(mOperationType); checkGLError(true, true, "GLRenderToVertexBuffer::update"); //Switch the vertex binding if neccesary if (targetBufferIndex != mFrontBufferIndex) { mVertexData->vertexBufferBinding->unsetAllBindings(); mVertexData->vertexBufferBinding->setBinding(0, mVertexBuffers[targetBufferIndex]); mFrontBufferIndex = targetBufferIndex; } glDisable(GL_RASTERIZER_DISCARD_NV); // enable rasterization //Clear the reset flag mResetRequested = false; }
void D3D11RenderToVertexBuffer::update(SceneManager* sceneMgr) { //Single pass only for now Ogre::Pass* r2vbPass = mMaterial->getBestTechnique()->getPass(0); setupGeometryShaderLinkageToStreamOut(r2vbPass); size_t bufSize = mVertexData->vertexDeclaration->getVertexSize(0) * mMaxVertexCount; if (mVertexBuffers[0].isNull() || mVertexBuffers[0]->getSizeInBytes() != bufSize) { //Buffers don't match. Need to reallocate. mResetRequested = true; } //Set pass before binding buffers to activate the GPU programs sceneMgr->_setPass(r2vbPass); RenderOperation renderOp; size_t targetBufferIndex; if (mResetRequested || mResetsEveryUpdate) { //Use source data to render to first buffer mSourceRenderable->getRenderOperation(renderOp); targetBufferIndex = 0; } else { //Use current front buffer to render to back buffer renderOp.operationType = mOperationType; renderOp.useIndexes = false; renderOp.vertexData = mVertexData; targetBufferIndex = 1 - mFrontBufferIndex; } if (mVertexBuffers[targetBufferIndex].isNull() || mVertexBuffers[targetBufferIndex]->getSizeInBytes() != bufSize) { reallocateBuffer(targetBufferIndex); } RenderSystem* targetRenderSystem = Root::getSingleton().getRenderSystem(); //Draw the object targetRenderSystem->_setWorldMatrix(Matrix4::IDENTITY); targetRenderSystem->_setViewMatrix(Matrix4::IDENTITY); targetRenderSystem->_setProjectionMatrix(Matrix4::IDENTITY); D3D11HardwareVertexBuffer* vertexBuffer = static_cast<D3D11HardwareVertexBuffer*>(mVertexBuffers[targetBufferIndex].getPointer()); UINT offset[1] = { 0 }; ID3D11Buffer* iBuffer[1]; iBuffer[0] = vertexBuffer->getD3DVertexBuffer(); mDevice.GetImmediateContext()->SOSetTargets( 1, iBuffer, offset ); if (r2vbPass->hasVertexProgram()) { targetRenderSystem->bindGpuProgramParameters(GPT_VERTEX_PROGRAM, r2vbPass->getVertexProgramParameters(), GPV_ALL); } if (r2vbPass->hasGeometryProgram()) { targetRenderSystem->bindGpuProgramParameters(GPT_GEOMETRY_PROGRAM, r2vbPass->getGeometryProgramParameters(), GPV_ALL); } mDevice.GetImmediateContext()->Begin(mDeviceStatsQuery); targetRenderSystem->_render(renderOp); //Switch the vertex binding if necessary if (targetBufferIndex != mFrontBufferIndex) { mVertexData->vertexBufferBinding->unsetAllBindings(); mVertexData->vertexBufferBinding->setBinding(0, mVertexBuffers[targetBufferIndex]); mFrontBufferIndex = targetBufferIndex; } ID3D11Buffer* nullBuffer[1]; nullBuffer[0]=NULL; mDevice.GetImmediateContext()->SOSetTargets( 1, nullBuffer, offset ); //Clear the reset flag mResetRequested = false; mDevice.GetImmediateContext()->End(mDeviceStatsQuery); D3D11_QUERY_DATA_PIPELINE_STATISTICS stats; while( S_OK != mDevice.GetImmediateContext()->GetData(mDeviceStatsQuery, &stats, mDeviceStatsQuery->GetDataSize(), 0 ) ){} }
void GL3PlusRenderToVertexBuffer::update(SceneManager* sceneMgr) { // size_t bufSize = mVertexData->vertexDeclaration->getVertexSize(0) * mMaxVertexCount; // if (mVertexBuffers[0].isNull() || mVertexBuffers[0]->getSizeInBytes() != bufSize) // { // // Buffers don't match. Need to reallocate. // mResetRequested = true; // } // if (mResetRequested || mResetsEveryUpdate) // { // // Use source data to render to first buffer. // mSourceRenderable->getRenderOperation(renderOp); // targetBufferIndex = 0; // } // else // { // // Use current front buffer to render to back buffer. // this->getRenderOperation(renderOp); // targetBufferIndex = 1 - mSourceBufferIndex; // } // if (mVertexBuffers[targetBufferIndex].isNull() || // mVertexBuffers[targetBufferIndex]->getSizeInBytes() != bufSize) // { // reallocateBuffer(targetBufferIndex); // } // Single pass only for now. Ogre::Pass* r2vbPass = mMaterial->getBestTechnique()->getPass(0); // Set pass before binding buffers to activate the GPU programs. sceneMgr->_setPass(r2vbPass); if (mFirstUpdate) { bindVerticesOutput(r2vbPass); mFirstUpdate = false; } // size_t targetBufferIndex = mSourceBufferIndex == 0 ? 0 : 1; // Disable rasterization. OGRE_CHECK_GL_ERROR(glEnable(GL_RASTERIZER_DISCARD)); // Bind shader parameters. RenderSystem* targetRenderSystem = Root::getSingleton().getRenderSystem(); targetRenderSystem->_setWorldMatrix(Matrix4::IDENTITY); targetRenderSystem->_setViewMatrix(Matrix4::IDENTITY); targetRenderSystem->_setProjectionMatrix(Matrix4::IDENTITY); if (r2vbPass->hasVertexProgram()) { targetRenderSystem->bindGpuProgramParameters(GPT_VERTEX_PROGRAM, r2vbPass->getVertexProgramParameters(), GPV_ALL); } if (r2vbPass->hasFragmentProgram()) { targetRenderSystem->bindGpuProgramParameters(GPT_FRAGMENT_PROGRAM, r2vbPass->getFragmentProgramParameters(), GPV_ALL); } if (r2vbPass->hasGeometryProgram()) { targetRenderSystem->bindGpuProgramParameters(GPT_GEOMETRY_PROGRAM, r2vbPass->getGeometryProgramParameters(), GPV_ALL); } //TODO add tessellation stages // Bind source vertex array + target tranform feedback buffer. GL3PlusHardwareVertexBuffer* targetVertexBuffer = static_cast<GL3PlusHardwareVertexBuffer*>(mVertexBuffers[mTargetBufferIndex].getPointer()); // OGRE_CHECK_GL_ERROR(glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, VertexBuffer[mTargetBufferIndex])); OGRE_CHECK_GL_ERROR(glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, targetVertexBuffer->getGLBufferId())); // OGRE_CHECK_GL_ERROR(glBindVertexArray(VertexArray[mSourceBufferIndex])); if (Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) { GLSLSeparableProgram* separableProgram = GLSLSeparableProgramManager::getSingleton().getCurrentSeparableProgram(); separableProgram->activate(); separableProgram->getVertexArrayObject()->bind(); } else { GLSLMonolithicProgram* monolithicProgram = GLSLMonolithicProgramManager::getSingleton().getActiveMonolithicProgram(); monolithicProgram->getVertexArrayObject()->bind(); } // 'Render' data to the transform buffer. OGRE_CHECK_GL_ERROR(glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, mPrimitivesDrawnQuery)); OGRE_CHECK_GL_ERROR(glBeginTransformFeedback(getR2VBPrimitiveType(mOperationType))); RenderOperation renderOp; if (mResetRequested || mResetsEveryUpdate) { // Use source data to render to first buffer. mSourceRenderable->getRenderOperation(renderOp); } else { // Use current front buffer to render to back buffer. this->getRenderOperation(renderOp); } renderOp.renderToVertexBuffer = true; targetRenderSystem->_render(renderOp); // OGRE_CHECK_GL_ERROR(glDrawArrays(GL_POINTS, 0, 1)); //TODO GL4+ //glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, mFeedbackObject); //glDrawTransformFeedback(getR2VBPrimitiveType(mOperationType), mFeedbackObject); OGRE_CHECK_GL_ERROR(glEndTransformFeedback()); OGRE_CHECK_GL_ERROR(glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN)); // Read back query results. GLuint primitivesWritten; OGRE_CHECK_GL_ERROR(glGetQueryObjectuiv(mPrimitivesDrawnQuery, GL_QUERY_RESULT, &primitivesWritten)); mVertexData->vertexCount = primitivesWritten * getVertexCountPerPrimitive(mOperationType); // Switch the vertex binding. mVertexData->vertexBufferBinding->unsetAllBindings(); mVertexData->vertexBufferBinding->setBinding(0, mVertexBuffers[mTargetBufferIndex]); mTargetBufferIndex = mTargetBufferIndex == 0 ? 1 : 0; // Enable rasterization. OGRE_CHECK_GL_ERROR(glDisable(GL_RASTERIZER_DISCARD)); // Clear the reset flag. mResetRequested = false; }
//----------------------------------------------------------------------------- void GLES2RenderToVertexBuffer::update(SceneManager* sceneMgr) { size_t bufSize = mVertexData->vertexDeclaration->getVertexSize(0) * mMaxVertexCount; if (!mVertexBuffers[0] || mVertexBuffers[0]->getSizeInBytes() != bufSize) { // Buffers don't match. Need to reallocate. mResetRequested = true; } // Single pass only for now Ogre::Pass* r2vbPass = mMaterial->getBestTechnique()->getPass(0); // Set pass before binding buffers to activate the GPU programs sceneMgr->_setPass(r2vbPass); bindVerticesOutput(r2vbPass); RenderOperation renderOp; size_t targetBufferIndex; if (mResetRequested || mResetsEveryUpdate) { // Use source data to render to first buffer mSourceRenderable->getRenderOperation(renderOp); targetBufferIndex = 0; } else { // Use current front buffer to render to back buffer this->getRenderOperation(renderOp); targetBufferIndex = 1 - mFrontBufferIndex; } if (!mVertexBuffers[targetBufferIndex] || mVertexBuffers[targetBufferIndex]->getSizeInBytes() != bufSize) { reallocateBuffer(targetBufferIndex); } GLES2HardwareVertexBuffer* vertexBuffer = static_cast<GLES2HardwareVertexBuffer*>(mVertexBuffers[targetBufferIndex].get()); /* if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) { GLSLESProgramPipeline* programPipeline = GLSLESProgramPipelineManager::getSingleton().getActiveProgramPipeline(); programPipeline->getVertexArrayObject()->bind(); } else { GLSLESLinkProgram* linkProgram = GLSLESLinkProgramManager::getSingleton().getActiveLinkProgram(); linkProgram->getVertexArrayObject()->bind(); } */ // Bind the target buffer OGRE_CHECK_GL_ERROR(glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, vertexBuffer->getGLBufferId())); // Disable rasterization OGRE_CHECK_GL_ERROR(glEnable(GL_RASTERIZER_DISCARD)); RenderSystem* targetRenderSystem = Root::getSingleton().getRenderSystem(); // Draw the object targetRenderSystem->_setWorldMatrix(Matrix4::IDENTITY); targetRenderSystem->_setViewMatrix(Matrix4::IDENTITY); targetRenderSystem->_setProjectionMatrix(Matrix4::IDENTITY); if (r2vbPass->hasVertexProgram()) { targetRenderSystem->bindGpuProgramParameters(GPT_VERTEX_PROGRAM, r2vbPass->getVertexProgramParameters(), GPV_ALL); } if (r2vbPass->hasFragmentProgram()) { targetRenderSystem->bindGpuProgramParameters(GPT_FRAGMENT_PROGRAM, r2vbPass->getFragmentProgramParameters(), GPV_ALL); } if (r2vbPass->hasGeometryProgram()) { targetRenderSystem->bindGpuProgramParameters(GPT_GEOMETRY_PROGRAM, r2vbPass->getGeometryProgramParameters(), GPV_ALL); } OGRE_CHECK_GL_ERROR(glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, mPrimitivesDrawnQuery)); OGRE_CHECK_GL_ERROR(glBeginTransformFeedback(getR2VBPrimitiveType(mOperationType))); targetRenderSystem->_render(renderOp); OGRE_CHECK_GL_ERROR(glEndTransformFeedback()); // Finish the query OGRE_CHECK_GL_ERROR(glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN)); OGRE_CHECK_GL_ERROR(glDisable(GL_RASTERIZER_DISCARD)); // Read back query results GLuint primitivesWritten; OGRE_CHECK_GL_ERROR(glGetQueryObjectuiv(mPrimitivesDrawnQuery, GL_QUERY_RESULT, &primitivesWritten)); mVertexData->vertexCount = primitivesWritten * getVertexCountPerPrimitive(mOperationType); // Switch the vertex binding if necessary if (targetBufferIndex != mFrontBufferIndex) { mVertexData->vertexBufferBinding->unsetAllBindings(); mVertexData->vertexBufferBinding->setBinding(0, mVertexBuffers[targetBufferIndex]); mFrontBufferIndex = targetBufferIndex; } // Enable rasterization OGRE_CHECK_GL_ERROR(glDisable(GL_RASTERIZER_DISCARD)); // Clear the reset flag mResetRequested = false; }