//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void QSRSnippetWidget::showModelStatistics() { RenderSequence* renderSeq = m_snippet->renderSequence(); CVF_ASSERT(renderSeq); size_t totPartCount = 0; size_t totFaceCount = 0; int numRenderings = renderSeq->renderingCount(); int ir; for (ir = 0; ir < numRenderings; ir++) { Rendering* rendering = renderSeq->rendering(ir); CVF_ASSERT(rendering); Scene* scene = rendering->scene(); CVF_ASSERT(scene); int numModels = scene->modelCount(); int im; for (im = 0; im < numModels; im++) { Model* model = scene->model(im); Collection<Part> allParts; model->allParts(&allParts); size_t numParts = allParts.size(); size_t ip; for (ip = 0; ip < numParts; ip++) { Part* part = allParts[ip].p(); Drawable* drawable = part->drawable(); totPartCount++; totFaceCount += drawable->faceCount(); } } } cvf::Trace::show("Total number of parts: %ld", totPartCount); cvf::Trace::show("Total number of faces: %ld", totFaceCount); }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RenderEngine::render(OpenGLContext* oglContext, RenderQueue* renderQueue, size_t maxNumPartsToDraw, const Camera& camera, const UniformSet* globalUniformSet) { CVF_ASSERT(oglContext); CVF_ASSERT(renderQueue); m_renderedPartCount = 0; m_renderedVertexCount = 0; m_renderedTriangleCount = 0; m_renderedOpenGLPrimitiveCount = 0; m_applyRenderStateCount = 0; m_shaderProgramChangesCount = 0; m_renderStateTracker.resetAndApplyDefaultRenderStates(oglContext); // Use immediate mode either if forced or if buffer objects are not supported (OpenGL 1.5 and below) // This is because the current fixed function rendering relies on the buffer object binding points being present const bool renderUsingImmediateMode = (m_forceImmediateMode || !BufferObjectManaged::supportedOpenGL(oglContext)); // Does the current OpenGL context support OpenGL shaders const bool contextSupportsShaders = ShaderProgram::supportedOpenGL(oglContext); // Init matrix state tracker MatrixState matrixState(camera); uint lastAppliedMatrixStateVersionTick = matrixState.versionTick() - 1; uint lastAppliedMatrixStateVersionTickFixedFunction = matrixState.versionTick() - 1; const Effect* prevEffect = NULL; const RenderStateSet* prevRenderStateSet = NULL; const ShaderProgram* prevShaderProgram = NULL; // Track the current shader program being used. // Will be NULL when effect has no shader program or if usage of shader program fails ShaderProgram* shaderProgramInUse = NULL; if (contextSupportsShaders) { // Start out with fixed function ShaderProgram::useNoProgram(oglContext); } // Determine number of parts we'll draw size_t numPartsInQueue = renderQueue->count(); size_t numPartsToDraw = std::min(numPartsInQueue, maxNumPartsToDraw); bool debugLogging = CVF_SHOULD_LOG_RENDER_DEBUG(oglContext); if (debugLogging) { CVF_LOG_RENDER_DEBUG(oglContext, "RenderEngine::render(), numParts=" + String(static_cast<uint>(numPartsInQueue))); } size_t i; for (i = 0; i < numPartsToDraw; i++) { RenderItem* item = renderQueue->item(i); CVF_ASSERT(item); Drawable* drawable = item->drawable(); Effect* effect = item->effect(); Part* part = item->part(); CVF_ASSERT(drawable); CVF_ASSERT(effect); CVF_ASSERT(part); if (debugLogging) { CVF_LOG_RENDER_DEBUG(oglContext, String("part#=%1, partName='%2'").arg(static_cast<uint>(i)).arg(part->name())); } // Update matrix state to reflect any part transformations // Register if the pass modifies the view matrix so that we can reset it at the end of this part bool lastPartModifiedViewMatrix = false; if (part->transform()) { const Transform* trans = part->transform(); if (trans->eyeLiftFactor() != 0) { // Eye lifting done by scaling the vertex coordinates after transforming them to eye space. See Transform::setEyeLiftFactor() // An eye lift factor of 1.0 results in scaling by 0.995. Might have to tweak the value below somewhat double scaleFactor = 1 - (trans->eyeLiftFactor()*0.005); Mat4d scaleMatrix = Mat4d::fromScaling(Vec3d(scaleFactor, scaleFactor, scaleFactor)); matrixState.setViewMatrix(scaleMatrix*camera.viewMatrix()); lastPartModifiedViewMatrix = true; } matrixState.setModelMatrix(trans->worldTransform()); } else { matrixState.clearModelMatrix(); } if (effect != prevEffect && !m_disableApplyEffects) { const RenderStateSet* const renderStateSet = effect->renderStateSet(); if (renderStateSet != prevRenderStateSet) { // This apply function is designed to work with NULL pointers m_renderStateTracker.applyRenderStates(oglContext, renderStateSet, prevRenderStateSet); prevRenderStateSet = renderStateSet; m_applyRenderStateCount++; } if (contextSupportsShaders) { ShaderProgram* shaderProgThisEffect = effect->shaderProgram(); if (shaderProgThisEffect != prevShaderProgram) { // Reset the 'in use' pointer, and only set it if we have a shader program AND we manage to use it shaderProgramInUse = NULL; if (shaderProgThisEffect) { // Will fail if program hasn't been linked if (shaderProgThisEffect->useProgram(oglContext)) { shaderProgramInUse = shaderProgThisEffect; } } if (!shaderProgramInUse) { ShaderProgram::useNoProgram(oglContext); } prevShaderProgram = shaderProgThisEffect; m_shaderProgramChangesCount++; } if (shaderProgramInUse) { // Apply uniforms for this shader program // Note order of application here. // - shader program default uniforms // - global dynamic uniforms // - (texture binding uniforms) // - effect uniforms // - fixed uniforms // We would really like the effect's uniforms to be at the very end, but that would give inconsistent // behavior since the fixed uniforms may get applied also when the effect does NOT change. shaderProgramInUse->clearUniformApplyTracking(); shaderProgramInUse->applyDefaultUniforms(oglContext); if (globalUniformSet) { shaderProgramInUse->applyActiveUniformsOnly(oglContext, *globalUniformSet); } const RenderStateTextureBindings* textureBindings = static_cast<const RenderStateTextureBindings*>(effect->renderStateOfType(RenderState::TEXTURE_BINDINGS)); if (textureBindings) { textureBindings->applySamplerTextureUnitUniforms(oglContext, shaderProgramInUse); } // Apply the effect's uniform last so that they win in case of clashes const UniformSet* uniformSet = effect->uniformSet(); if (uniformSet) { shaderProgramInUse->applyUniforms(oglContext, *uniformSet); } // Still, the fixed ones have to go at the end for consistency shaderProgramInUse->applyFixedUniforms(oglContext, matrixState); lastAppliedMatrixStateVersionTick = matrixState.versionTick(); } } prevEffect = effect; } if (shaderProgramInUse) { if (lastAppliedMatrixStateVersionTick != matrixState.versionTick()) { shaderProgramInUse->applyFixedUniforms(oglContext, matrixState); lastAppliedMatrixStateVersionTick = matrixState.versionTick(); } // Will check that all active uniforms in shader program have been set since last call to >clearUniformApplyTracking() // Reports error to log if any uniforms are missing. shaderProgramInUse->checkReportAllUniformsApplied(oglContext); } else { #ifndef CVF_OPENGL_ES if (lastAppliedMatrixStateVersionTickFixedFunction != matrixState.versionTick()) { glLoadMatrixf(matrixState.modelViewMatrix().ptr()); lastAppliedMatrixStateVersionTickFixedFunction = matrixState.versionTick(); } #endif // CVF_OPENGL_ES } // Do actual rendering if (!m_disableDrawableRender) { if (renderUsingImmediateMode) { drawable->renderImmediateMode(oglContext, matrixState); } else { if (shaderProgramInUse) { drawable->render(oglContext, shaderProgramInUse, matrixState); } else { drawable->renderFixedFunction(oglContext, matrixState); } } m_renderedPartCount++; } // Must reset the view matrix if it was modified during drawing of this part if (lastPartModifiedViewMatrix) { matrixState.setViewMatrix(camera.viewMatrix()); } // Update counters if (m_enableItemCountUpdate) { m_renderedVertexCount += drawable->vertexCount(); m_renderedTriangleCount += drawable->triangleCount(); m_renderedOpenGLPrimitiveCount += drawable->faceCount(); } } // Do an apply with an empty new render state set to get defaults back before leaving // This really isn't the optimal place to do this, but until we expose application of render states it's the only place m_renderStateTracker.applyRenderStates(oglContext, NULL, prevRenderStateSet); // For now, set back to fixed function if (contextSupportsShaders) { ShaderProgram::useNoProgram(oglContext); } // Set back VBO settings (do we need this?) if (BufferObjectManaged::supportedOpenGL(oglContext)) { BufferObjectManaged::unbindAllBuffers(oglContext); } }