NodeRendererResult SurfelRenderer::displayNode(FrameContext & context, Node * node, const RenderParam & /*rp*/){ static const Util::StringIdentifier SURFEL_ATTRIBUTE("surfels"); auto surfelAttribute = dynamic_cast<Util::ReferenceAttribute<Rendering::Mesh>*>(node->findAttribute( SURFEL_ATTRIBUTE )); if( !surfelAttribute || !surfelAttribute->get()) return NodeRendererResult::PASS_ON; Rendering::Mesh& surfelMesh = *surfelAttribute->get(); const Geometry::Rect projection = context.getProjectedRect(node); const float approxProjectedSideLength = std::sqrt(projection.getHeight() * projection.getWidth()); // const auto& worldBB = node->getWorldBB(); // const float approxProjectedSideLength = projectionScale * worldBB.getDiameter() / (worldBB.getCenter()-cameraOrigin).length(); if(approxProjectedSideLength > maxSideLength) return NodeRendererResult::PASS_ON; static const Util::StringIdentifier REL_COVERING_ATTRIBUTE("surfelRelCovering"); auto surfelCoverageAttr = node->findAttribute(REL_COVERING_ATTRIBUTE); const float relCovering = surfelCoverageAttr ? surfelCoverageAttr->toFloat() : 0.5; const float approxProjectedArea = approxProjectedSideLength * approxProjectedSideLength * relCovering; uint32_t surfelCount = std::min( surfelMesh.isUsingIndexData() ? surfelMesh.getIndexCount() : surfelMesh.getVertexCount(), static_cast<uint32_t>(approxProjectedArea * countFactor) + 1); float surfelSize = std::min(sizeFactor * approxProjectedArea / surfelCount,maxSurfelSize); bool handled = true; if(approxProjectedSideLength > minSideLength && minSideLength<maxSideLength){ const float f = 1.0f -(approxProjectedSideLength-minSideLength) / (maxSideLength-minSideLength); surfelCount = std::min( surfelMesh.isUsingIndexData() ? surfelMesh.getIndexCount() : surfelMesh.getVertexCount(), static_cast<uint32_t>(f * surfelCount) + 1); surfelSize *= f; handled = false; // std::cout << approxProjectedSideLength<<"\t"<<f<<"\n"; } // std::cout << surfelSize<<"\t"<<"\n"; // if( node->getRenderingLayers()&0x02 ) // std::cout << "pSize"<<approxProjectedSideLength << "\t#:"<<surfelCount<<"\ts:"<<surfelSize<<"\n"; auto& renderingContext = context.getRenderingContext(); static Rendering::Uniform enableSurfels("renderSurfels", true); static Rendering::Uniform disableSurfels("renderSurfels", false); renderingContext.setGlobalUniform(enableSurfels); renderingContext.pushAndSetPointParameters( Rendering::PointParameters(std::min(surfelSize,32.0f) )); renderingContext.pushAndSetMatrix_modelToCamera( renderingContext.getMatrix_worldToCamera() ); renderingContext.multMatrix_modelToCamera(node->getWorldTransformationMatrix()); context.displayMesh(&surfelMesh, 0, surfelCount ); renderingContext.popMatrix_modelToCamera(); renderingContext.popPointParameters(); renderingContext.setGlobalUniform(disableSurfels); return handled ? NodeRendererResult::NODE_HANDLED : NodeRendererResult::PASS_ON; }
//! ---|> Component void Connector::doLayout(){ Geometry::Vec2 parentsAbsPos=hasParent()?getParent()->getAbsPosition():Geometry::Vec2(); Geometry::Rect r; r.invalidate(); // std::cout << r.getX(); if( getFirstComponent() ) r.include( getFirstComponent()->getAbsRect().getCenter()-parentsAbsPos ); // std::cout << (getFirstComponent()->getAbsRect().getCenter()-parentsAbsPos).getX(); if( getSecondComponent() ) r.include( getSecondComponent()->getAbsRect().getCenter()-parentsAbsPos ); if(getContentsCount()>2){ // TODO!!!!! } setPosition(Geometry::Vec2(r.getX(),r.getY())); setSize(r.getWidth(),r.getHeight()); Geometry::Vec2 myAbsPos=getAbsPosition(); if(getFirstChild() && getFirstComponent()){ getFirstChild()->setPosition( getFirstComponent()->getAbsRect().getCenter()-myAbsPos ); } if(getLastChild() && getSecondComponent()){ getLastChild()->setPosition( getSecondComponent()->getAbsRect().getCenter()-myAbsPos ); // getLastChild()->setPosition(Vec2(r.getWidth(),r.getHeight())); } if(getContentsCount()>2){ // TODO!!!!! } }
void drawRect(RenderingContext & rc, const Geometry::Rect & rect) { static Util::Reference<Mesh> mesh; if (mesh.isNull()) { VertexDescription vertexDescription; vertexDescription.appendPosition2D(); mesh = new Mesh(vertexDescription, 4, 6); mesh->setDrawMode(Mesh::DRAW_TRIANGLES); MeshVertexData & vd = mesh->openVertexData(); float * vertices = reinterpret_cast<float *> (vd.data()); *vertices++ = 0.0f; // Bottom left *vertices++ = 0.0f; *vertices++ = 1.0f; // Bottom right *vertices++ = 0.0f; *vertices++ = 1.0f; // Top right *vertices++ = 1.0f; *vertices++ = 0.0f; // Top left *vertices++ = 1.0f; vd.updateBoundingBox(); vd.markAsChanged(); MeshIndexData & id = mesh->openIndexData(); uint32_t * indices = id.data(); indices[0] = 0; indices[1] = 2; indices[2] = 1; indices[3] = 0; indices[4] = 3; indices[5] = 2; id.updateIndexRange(); id.markAsChanged(); } Geometry::Matrix4x4 matrix; matrix.translate(rect.getX(), rect.getY(), 0.0f); matrix.scale(rect.getWidth(), rect.getHeight(), 1.0f); rc.pushMatrix_modelToCamera(); rc.multMatrix_modelToCamera(matrix); rc.displayMesh(mesh.get()); rc.popMatrix_modelToCamera(); }
void ColorVisibilityEvaluator::measure(FrameContext & context, Node & node, const Geometry::Rect & rect) { Rendering::RenderingContext & rCtxt = context.getRenderingContext(); // ### Set up textures for the framebuffer object. ### const uint32_t width = static_cast<uint32_t> (rect.getWidth()); const uint32_t height = static_cast<uint32_t> (rect.getHeight()); if (colorTexture == nullptr || width != static_cast<uint32_t> (colorTexture->getWidth()) || height != static_cast<uint32_t> (colorTexture->getHeight())) { // (Re-)Create textures with correct dimension. rCtxt.pushAndSetFBO(fbo.get()); fbo->detachColorTexture(context.getRenderingContext()); fbo->detachDepthTexture(context.getRenderingContext()); rCtxt.popFBO(); colorTexture = Rendering::TextureUtils::createStdTexture(width, height, true); depthTexture = Rendering::TextureUtils::createDepthTexture(width, height); // Bind textures to FBO. rCtxt.pushAndSetFBO(fbo.get()); fbo->attachColorTexture(context.getRenderingContext(),colorTexture.get()); fbo->attachDepthTexture(context.getRenderingContext(),depthTexture.get()); rCtxt.popFBO(); } // ### Render the scene into a framebuffer object. ### rCtxt.pushAndSetFBO(fbo.get()); rCtxt.pushAndSetShader(getShader()); rCtxt.clearScreen(Util::Color4f(0.0f, 0.0f, 0.0f, 0.0f)); // Color counter for assignment of unique colors to triangles. // Background is black (color 0). int32_t currentColor = 1; // Collect potentially visible geometry nodes. const auto geoNodes = collectNodesInFrustum<GeometryNode>(&node, context.getCamera()->getFrustum()); for(const auto & geoNode : geoNodes) { getShader()->setUniform(rCtxt, Rendering::Uniform("colorOffset", currentColor)); context.displayNode(geoNode, USE_WORLD_MATRIX | NO_STATES); currentColor += geoNode->getTriangleCount(); } rCtxt.popShader(); rCtxt.popFBO(); // ### Read texture and analyze colors. ### // Map from colors to number of occurrences. std::map<uint32_t, uint32_t> colorUsage; // Current color is compared with the previous color. If they match, the local count variable is used as cache before insertion into map is performed. uint32_t lastColor = 0; uint32_t lastCount = 0; colorTexture->downloadGLTexture(rCtxt); const uint32_t * texData = reinterpret_cast<const uint32_t *> (colorTexture->openLocalData(rCtxt)); const uint32_t numPixels = width * height; for (uint_fast32_t p = 0; p < numPixels; ++p) { const uint32_t & color = texData[p]; if (color == 0) { // Ignore background. continue; } if (color == lastColor) { ++lastCount; continue; } else { // Insert previous color. if (lastColor != 0) { increaseColorUsage(lastColor, lastCount, colorUsage); } lastColor = color; lastCount = 1; } } if (lastColor != 0) { increaseColorUsage(lastColor, lastCount, colorUsage); } if (mode == SINGLE_VALUE) { numTrianglesVisible += colorUsage.size(); } else { values->push_back(Util::GenericAttribute::createNumber(colorUsage.size())); } }
void OverdrawFactorEvaluator::measure(FrameContext & frameContext, Node & node, const Geometry::Rect & rect) { Rendering::RenderingContext & renderingContext = frameContext.getRenderingContext(); // Set up FBO and texture Util::Reference<Rendering::FBO> fbo = new Rendering::FBO; renderingContext.pushAndSetFBO(fbo.get()); Util::Reference<Rendering::Texture> depthStencilTexture = Rendering::TextureUtils::createDepthStencilTexture(rect.getWidth(), rect.getHeight()); fbo->attachDepthStencilTexture(renderingContext, depthStencilTexture.get()); // Disable color and depth writes renderingContext.pushAndSetColorBuffer(Rendering::ColorBufferParameters(false, false, false, false)); renderingContext.pushAndSetDepthBuffer(Rendering::DepthBufferParameters(false, false, Rendering::Comparison::LESS)); // Increase the stencil value for every rendered pixel Rendering::StencilParameters stencilParams; stencilParams.enable(); stencilParams.setFunction(Rendering::Comparison::ALWAYS); stencilParams.setReferenceValue(0); stencilParams.setBitMask(0); stencilParams.setFailAction(Rendering::StencilParameters::INCR); stencilParams.setDepthTestFailAction(Rendering::StencilParameters::INCR); stencilParams.setDepthTestPassAction(Rendering::StencilParameters::INCR); renderingContext.pushAndSetStencil(stencilParams); // Render the node renderingContext.clearStencil(0); frameContext.displayNode(&node, 0); // Reset GL state renderingContext.popStencil(); renderingContext.popDepthBuffer(); renderingContext.popColorBuffer(); // Fetch the texture. depthStencilTexture->downloadGLTexture(renderingContext); renderingContext.popFBO(); Util::Reference<Util::PixelAccessor> stencilAccessor = Rendering::TextureUtils::createStencilPixelAccessor(renderingContext, *depthStencilTexture.get()); std::vector<uint8_t> stencilValues; stencilValues.reserve(rect.getWidth() * rect.getHeight()); for(uint_fast32_t y = 0; y < rect.getHeight(); ++y) { for(uint_fast32_t x = 0; x < rect.getWidth(); ++x) { const uint8_t stencilValue = stencilAccessor->readSingleValueByte(x, y); stencilValues.push_back(stencilValue); } } // // Create and write debug image // { // Util::Reference<Rendering::Texture> colorTexture = Rendering::TextureUtils::createStdTexture(rect.getWidth(), rect.getHeight(), true); // Util::Reference<Util::PixelAccessor> colorAccessor = Rendering::TextureUtils::createColorPixelAccessor(renderingContext, colorTexture.get()); // const auto stencilMinMax = std::minmax_element(stencilValues.cbegin(), stencilValues.cend()); // const auto stencilMin = *stencilMinMax.first; // const auto stencilMax = *stencilMinMax.second; // const double stencilRange = stencilMax - stencilMin; // const double factor = 1.0 / stencilRange; // // Color scheme RdYlBu with 5 of 8 colors from www.colorbrewer2.org // const std::array<Util::Color4f, 5> gradient = { // Util::Color4ub(44, 123, 182, 255), // Util::Color4ub(171, 217, 233, 255), // Util::Color4ub(255, 255, 191, 255), // Util::Color4ub(253, 174, 97, 255), // Util::Color4ub(215, 25, 28, 255) // }; // for(uint_fast32_t y = 0; y < rect.getHeight(); ++y) { // for(uint_fast32_t x = 0; x < rect.getWidth(); ++x) { // const uint8_t stencilValue = stencilValues[y * rect.getWidth() + x]; // if(stencilValue == 0) { // colorAccessor->writeColor(x, y, Util::Color4f(1.0, 1.0, 1.0, 0.0)); // } else { // const double normalizedValue = static_cast<double>(stencilValue - stencilMin) * factor; // const double gradientPos = normalizedValue * (gradient.size() - 1); // const size_t gradientIndex = std::floor(gradientPos); // colorAccessor->writeColor(x, y, Util::Color4f(gradient[gradientIndex], gradient[gradientIndex + 1], gradientPos - gradientIndex)); // } // } // } // Rendering::Serialization::saveTexture(renderingContext, colorTexture.get(), Util::FileName("stencil.png")); // } if(resultRemoveZeroValues) { stencilValues.erase(std::remove(stencilValues.begin(), stencilValues.end(), 0), stencilValues.end()); } uint8_t result = 0; if(!stencilValues.empty()) { if(resultQuantile >= 1.0) { result = *std::max_element(stencilValues.cbegin(), stencilValues.cend()); } else if(resultQuantile <= 0.0) { result = *std::min_element(stencilValues.cbegin(), stencilValues.cend()); } else { const std::size_t quantilePos = resultQuantile * stencilValues.size(); std::nth_element(stencilValues.begin(), std::next(stencilValues.begin(), static_cast<std::ptrdiff_t>(quantilePos)), stencilValues.end()); result = stencilValues[quantilePos]; } } values->push_back(Util::GenericAttribute::createNumber(result)); setMaxValue_i(result); }