void drawTriangle(RenderingContext & rc, const Geometry::Vec3f & vertexA, const Geometry::Vec3f & vertexB, const Geometry::Vec3f & vertexC) { static Util::Reference<Mesh> mesh; if (mesh.isNull()) { VertexDescription vertexDescription; vertexDescription.appendPosition3D(); mesh = new Mesh(vertexDescription, 3, 3); MeshIndexData & id = mesh->openIndexData(); uint32_t * indices = id.data(); indices[0] = 0; indices[1] = 1; indices[2] = 2; id.updateIndexRange(); id.markAsChanged(); } MeshVertexData & vd = mesh->openVertexData(); float * vertices = reinterpret_cast<float *>(vd.data()); // First vertex *vertices++ = vertexA.getX(); *vertices++ = vertexA.getY(); *vertices++ = vertexA.getZ(); // Second vertex *vertices++ = vertexB.getX(); *vertices++ = vertexB.getY(); *vertices++ = vertexB.getZ(); // Third vertex *vertices++ = vertexC.getX(); *vertices++ = vertexC.getY(); *vertices++ = vertexC.getZ(); vd.updateBoundingBox(); vd.markAsChanged(); rc.displayMesh(mesh.get()); }
//! Deprecated Mesh * MeshBuilder::createMeshFromBitmaps(const VertexDescription& vd, Util::Reference<Util::Bitmap> depth, Util::Reference<Util::Bitmap> color, Util::Reference<Util::Bitmap> normals) { Util::Reference<Util::PixelAccessor> depthAcc = Util::PixelAccessor::create(std::move(depth)); if( depth.isNull() || depth->getPixelFormat()!=Util::PixelFormat::MONO_FLOAT ){ WARN("createMeshFromBitmaps: unsupported depth texture format"); return nullptr; } Util::Reference<Util::PixelAccessor> colorReader; if(color.isNotNull()) { colorReader = Util::PixelAccessor::create(std::move(color)); if(colorReader.isNull() || (colorReader->getPixelFormat() != Util::PixelFormat::RGBA && colorReader->getPixelFormat() != Util::PixelFormat::RGB)) { WARN("createMeshFromBitmaps: unsupported color texture format"); return nullptr; } } Util::Reference<Util::PixelAccessor> normalReader; if(normals.isNotNull()) { normalReader = Util::PixelAccessor::create(std::move(normals)); if(normalReader.isNull()){ WARN("createMeshFromBitmaps: unsupported normal texture format"); return nullptr; } } return MeshUtils::createMeshFromBitmaps(vd,depthAcc,colorReader,normalReader); }
void StatChart::update(const Statistics & fStats) { Util::Reference<Util::PixelAccessor> pixels = Util::PixelAccessor::create(bitmap.get()); if(pixels == nullptr) return; pixels->fill(0, 0, bitmap->getWidth(), bitmap->getHeight(), Util::Color4f(0, 0, 0, 0)); // show grids static const Util::Color4ub gridColor(0xa0, 0xa0, 0xa0, 0xa0); for(float f = 10.0; f < timeRange; f += 10.0) { const uint32_t x = static_cast<uint32_t> (bitmap->getWidth() * f / timeRange); for (uint32_t row = 0; row < bitmap->getHeight(); ++row) { pixels->writeColor(x, row, gridColor); } } const float timeScale = getWidth() / (timeRange * 1000.0); for(size_t i = 0; i < fStats.getNumEvents(); ++i) { const Statistics::Event & event = fStats.getEvent(i); const int x = static_cast<int> (event.time * timeScale); if(x >= static_cast<int> (getWidth())) continue; const DataRow & dataRow = dataRows[event.type]; const int yTo = std::max(static_cast<int> (bitmap->getHeight()) - static_cast<int> (event.value * dataRow.scale), 0); for(int y = bitmap->getHeight() - 1; y > yTo; --y) pixels->writeColor(x, y, dataRow.color); } }
void drawFullScreenRect(RenderingContext & rc){ GET_GL_ERROR(); static Geometry::Matrix4x4f projectionMatrix(Geometry::Matrix4x4f::orthographicProjection(-1, 1, -1, 1, -1, 1)); static Geometry::Matrix4x4f modelViewMatrix; static Util::Reference<Mesh> mesh; if(mesh.isNull()) { VertexDescription vertexDescription; vertexDescription.appendPosition3D(); vertexDescription.appendTexCoord(); MeshUtils::MeshBuilder mb(vertexDescription); mb.position(Geometry::Vec3f(-1,-1,0)); mb.texCoord0(Geometry::Vec2f(0,0)); uint32_t a = mb.addVertex(); mb.position(Geometry::Vec3f(1,-1,0)); mb.texCoord0(Geometry::Vec2f(1,0)); uint32_t b = mb.addVertex(); mb.position(Geometry::Vec3f(-1,1,0)); mb.texCoord0(Geometry::Vec2f(0,1)); uint32_t c = mb.addVertex(); mb.position(Geometry::Vec3f(1,1,0)); mb.texCoord0(Geometry::Vec2f(1,1)); uint32_t d = mb.addVertex(); mb.addTriangle(a, b, c); mb.addTriangle(c, b, d); mesh = mb.buildMesh(); } rc.pushMatrix_cameraToClipping(); rc.setMatrix_cameraToClipping(projectionMatrix); rc.pushMatrix_modelToCamera(); rc.setMatrix_modelToCamera(modelViewMatrix); rc.displayMesh(mesh.get()); rc.popMatrix_modelToCamera(); rc.popMatrix_cameraToClipping(); GET_GL_ERROR(); }
void AbstractJoint::doAddChild(Util::Reference<Node> child) { if(dynamic_cast<AbstractJoint *>(child.get()) == nullptr) return; if(dynamic_cast<ArmatureNode *> (child.get()) != nullptr) return; ListNode::doAddChild(child); }
Util::StringIdentifier createAndSetId(Util::Reference<Obj> obj){ Util::StringIdentifier id = getId(obj.get()); if(obj.isNotNull() && id.empty()) { do { // Create a new, random identifier.... id = Util::StringIdentifier("$" + Util::StringUtils::createRandomString(6)); }while( get(id) ); // ... until an unused one is found. setId(obj,id); } return id; }
void setId(Util::Reference<Obj> obj,const Util::StringIdentifier & id){ if(!id.empty()) // remove a obj possibly previously registered with the id removeId( id ); if(obj.isNotNull()) // remove the obj's old id removeId( obj.get() ); if(obj.isNotNull()&&!id.empty()){ // register the obj using the new id map_objToId.emplace(obj.get(),id); map_idToObj.emplace(id, std::move(obj)); } }
Util::Reference<CameraNode> PhotonRenderer::computePhotonCamera(){ Util::Reference<CameraNode> camera = new CameraNode; float minDistance = 0.01f; float maxDistance = 500.f; camera->setViewport(Geometry::Rect_i(0, 0, _samplingWidth, _samplingHeight)); camera->setNearFar(minDistance, maxDistance); camera->setAngles(-70, 70, -50, 50); return camera; }
bool MultiAlgoGroupNode::doRemoveChild(Util::Reference<Node> child) { if(node.get() == child.get()) { WARN("MultiAlgoGroupNode::doRemoveChild: don't remove direct child of MultiAlgoGroupNode"); return false; } return node->removeChild(child); }
void drawVector(RenderingContext & rc, const Geometry::Vec3 & from, const Geometry::Vec3 & to) { static Util::Reference<Mesh> mesh; if (mesh.isNull()) { VertexDescription vertexDescription; vertexDescription.appendPosition3D(); mesh = new Mesh(vertexDescription, 2, 2); mesh->setDrawMode(Mesh::DRAW_LINES); MeshIndexData & id = mesh->openIndexData(); uint32_t * indices = id.data(); indices[0] = 0; indices[1] = 1; id.updateIndexRange(); id.markAsChanged(); mesh->setDataStrategy(SimpleMeshDataStrategy::getPureLocalStrategy()); } MeshVertexData & vd = mesh->openVertexData(); float * vertices = reinterpret_cast<float *> (vd.data()); *vertices++ = from.getX(); // From *vertices++ = from.getY(); *vertices++ = from.getZ(); *vertices++ = to.getX(); // To *vertices++ = to.getY(); *vertices++ = to.getZ(); vd.updateBoundingBox(); vd.markAsChanged(); rc.displayMesh(mesh.get()); }
void drawBox(RenderingContext & rc, const Geometry::Box & box) { static Util::Reference<Mesh> mesh; if (mesh.isNull()) { VertexDescription vertexDescription; vertexDescription.appendPosition3D(); vertexDescription.appendNormalFloat(); const Geometry::Box unitBox(Geometry::Vec3(-0.5f, -0.5f, -0.5f), Geometry::Vec3(0.5f, 0.5f, 0.5f)); mesh = MeshUtils::MeshBuilder::createBox(vertexDescription, unitBox); } Geometry::Matrix4x4 matrix; matrix.translate(box.getCenter()); matrix.scale(box.getExtentX(), box.getExtentY(), box.getExtentZ()); rc.pushMatrix_modelToCamera(); rc.multMatrix_modelToCamera(matrix); rc.displayMesh(mesh.get()); rc.popMatrix_modelToCamera(); }
void drawWireframeBox(RenderingContext & rc, const Geometry::Box & box) { static Util::Reference<Mesh> mesh; if (mesh.isNull()) { VertexDescription vertexDescription; vertexDescription.appendPosition3D(); mesh = new Mesh(vertexDescription, 8, 16); mesh->setDataStrategy(SimpleMeshDataStrategy::getPureLocalStrategy()); mesh->setDrawMode(Mesh::DRAW_LINE_STRIP); MeshIndexData & id = mesh->openIndexData(); uint32_t * indices = id.data(); /* * Corners: * 6---------7 * /| /| * / | / | * 2---------3 | * | | | | * | 4------|--5 * | / | / * |/ |/ * 0---------1 */ indices[0] = 0; indices[1] = 2; indices[2] = 3; indices[3] = 1; indices[4] = 5; indices[5] = 7; indices[6] = 6; indices[7] = 4; indices[8] = 0; indices[9] = 1; indices[10] = 3; indices[11] = 7; indices[12] = 5; indices[13] = 4; indices[14] = 6; indices[15] = 2; id.updateIndexRange(); id.markAsChanged(); } MeshVertexData & vd = mesh->openVertexData(); float * vertices = reinterpret_cast<float *>(vd.data()); for (uint_fast8_t c = 0; c < 8; ++c) { const Geometry::Vec3 & corner = box.getCorner(static_cast<Geometry::corner_t> (c)); *vertices++ = corner.getX(); *vertices++ = corner.getY(); *vertices++ = corner.getZ(); } vd._setBoundingBox(box); vd.markAsChanged(); rc.displayMesh(mesh.get()); }
OverviewTableRow::OverviewTableRow(util::Reference<const impl::Call> call) : call_{ call } { id_ = call_->getId(); idStr = QString::number(call_->getId()); for (size_t i = 0; i < 2 && i < call->matrixCount(); i++) { QPixmap img; std::tie(std::ignore, img) = qtutil::convertMatToQPixmap(call->matrixAt(i)); imgs.push_back(std::move(img)); } description_ = QString(call_->description()); if (call_->metaData().isKnown) { const auto &data = call_->metaData(); line_ = data.line; lineStr = QString::number(data.line); fileStr = data.file; functionStr = data.function; } typeStr = QString(call_->type()); }
void ParticlePointRenderer::operator()(ParticleSystemNode* psys, FrameContext & context, const RenderParam & rp /* = 0 */) { if ( (rp.getFlag(NO_GEOMETRY)) ) return; // render particles std::vector<Particle> & particles = psys->getParticles(); uint32_t count = psys->getParticleCount(); Rendering::VertexDescription vertexDesc; const Rendering::VertexAttribute & posAttrib = vertexDesc.appendPosition3D(); const Rendering::VertexAttribute & colorAttrib = vertexDesc.appendColorRGBAByte(); // The usage of a cache for the mesh has been tested. Reusing a preallocated mesh is not faster. Util::Reference<Rendering::Mesh> mesh = new Rendering::Mesh(vertexDesc, count, count); mesh->setDataStrategy(Rendering::SimpleMeshDataStrategy::getPureLocalStrategy()); mesh->setDrawMode(Rendering::Mesh::DRAW_POINTS); // mesh->setUseIndexData(false); Rendering::MeshIndexData & indexData = mesh->openIndexData(); Rendering::MeshVertexData & vertexData = mesh->openVertexData(); Util::Reference<Rendering::PositionAttributeAccessor> positionAccessor = Rendering::PositionAttributeAccessor::create(vertexData, posAttrib.getNameId()); Util::Reference<Rendering::ColorAttributeAccessor> colorAccessor = Rendering::ColorAttributeAccessor::create(vertexData, colorAttrib.getNameId()); uint32_t * indices = indexData.data(); for(uint_fast32_t index = 0; index < count; ++index) { const Particle & p = particles[index]; colorAccessor->setColor(index, p.color); positionAccessor->setPosition(index, p.position); *indices++ = index; } indexData.markAsChanged(); indexData.updateIndexRange(); vertexData.markAsChanged(); vertexData.updateBoundingBox(); context.displayMesh(mesh.get()); }
void drawGrid(RenderingContext & rc, float scale) { static Util::Reference<Mesh> mesh; if (mesh.isNull()) { VertexDescription vertexDescription; vertexDescription.appendPosition3D(); mesh = new Mesh(vertexDescription, 4 * 101, 4 * 101); mesh->setDrawMode(Mesh::DRAW_LINES); MeshVertexData & vd = mesh->openVertexData(); float * vertices = reinterpret_cast<float *> (vd.data()); MeshIndexData & id = mesh->openIndexData(); uint32_t * indices = id.data(); uint32_t nextIndex = 0; const float step = 1.0f / 100.0f; for (uint_fast8_t line = 0; line < 101; ++line) { const float pos = -0.5f + static_cast<float> (line) * step; *vertices++ = -0.5f; *vertices++ = 0.0f; *vertices++ = pos; *vertices++ = 0.5f; *vertices++ = 0.0f; *vertices++ = pos; *indices++ = nextIndex++; *indices++ = nextIndex++; *vertices++ = pos; *vertices++ = 0.0f; *vertices++ = -0.5f; *vertices++ = pos; *vertices++ = 0.0f; *vertices++ = 0.5f; *indices++ = nextIndex++; *indices++ = nextIndex++; } vd.updateBoundingBox(); vd.markAsChanged(); id.updateIndexRange(); id.markAsChanged(); } Geometry::Matrix4x4 matrix; matrix.scale(scale); rc.pushMatrix_modelToCamera(); rc.multMatrix_modelToCamera(matrix); rc.displayMesh(mesh.get()); rc.popMatrix_modelToCamera(); }
void drawFrustum(RenderingContext & rc, const Geometry::Frustum & frustum, const Util::Color4f & color, float lineWidth) { static Util::Reference<Mesh> mesh; if (mesh.isNull()) { VertexDescription vertexDescription; vertexDescription.appendPosition3D(); mesh = new Mesh(vertexDescription, 8, 16); mesh->setDrawMode(Mesh::DRAW_LINE_STRIP); MeshIndexData & id = mesh->openIndexData(); uint32_t * indices = id.data(); indices[0] = 0; indices[1] = 2; indices[2] = 3; indices[3] = 1; indices[4] = 5; indices[5] = 7; indices[6] = 6; indices[7] = 4; indices[8] = 0; indices[9] = 1; indices[10] = 3; indices[11] = 7; indices[12] = 5; indices[13] = 4; indices[14] = 6; indices[15] = 2; id.updateIndexRange(); } MeshVertexData & vd = mesh->openVertexData(); float * vertices = reinterpret_cast<float *>(vd.data()); for (uint_fast8_t c = 0; c < 8; ++c) { const Geometry::Vec3 & corner = frustum[static_cast<Geometry::corner_t> (c)]; *vertices++ = corner.getX(); *vertices++ = corner.getY(); *vertices++ = corner.getZ(); } vd.updateBoundingBox(); vd.markAsChanged(); rc.pushAndSetLine(lineWidth); rc.pushAndSetLighting(LightingParameters(false)); rc.pushAndSetColorMaterial(color); rc.displayMesh(mesh.get()); rc.popMaterial(); rc.popLighting(); rc.popLine(); }
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(); }
State::stateResult_t VisibilitySubdivisionRenderer::doEnableState( FrameContext & context, Node *, const RenderParam & rp) { if (rp.getFlag(SKIP_RENDERER)) { return State::STATE_SKIPPED; } if (viSu == nullptr) { // Invalid information. => Fall back to standard rendering. return State::STATE_SKIPPED; } // [AccumRendering] if(accumRenderingEnabled){ // camera moved? -> start new frame const Geometry::Matrix4x4 & newCamMat=context.getCamera()->getWorldTransformationMatrix(); if(newCamMat!=lastCamMatrix){ lastCamMatrix = newCamMat; startRuntime=0; } }else{ startRuntime=0; } // ---- uint32_t renderedTriangles = 0; if (hold) { for (const auto & object : holdObjects) { if (debugOutput) { debugDisplay(renderedTriangles, object, context, rp); } else { context.displayNode(object, rp); } } return State::STATE_SKIP_RENDERING; } Geometry::Vec3 pos = context.getCamera()->getWorldOrigin(); bool refreshCache = false; // Check if cached cell can be used. if (currentCell == nullptr || !currentCell->getBB().contains(pos)) { currentCell = viSu->getNodeAtPosition(pos); refreshCache = true; } if (currentCell == nullptr || !currentCell->isLeaf()) { // Invalid information. => Fall back to standard rendering. return State::STATE_SKIPPED; } if (refreshCache) { try { const auto & vv = getVV(currentCell); const uint32_t maxIndex = vv.getIndexCount(); objects.clear(); objects.reserve(maxIndex); for(uint_fast32_t index = 0; index < maxIndex; ++index) { if(vv.getBenefits(index) == 0) { continue; } const VisibilityVector::costs_t costs = vv.getCosts(index); const VisibilityVector::benefits_t benefits = vv.getBenefits(index); const float score = static_cast<float>(costs) / static_cast<float>(benefits); objects.emplace_back(score, vv.getNode(index)); } } catch(...) { // Invalid information. => Fall back to standard rendering. return State::STATE_SKIPPED; } if (displayTexturedDepthMeshes) { #ifdef MINSG_EXT_OUTOFCORE for (const auto & depthMesh : depthMeshes) { OutOfCore::getCacheManager().setUserPriority(depthMesh.get(), 0); } #endif /* MINSG_EXT_OUTOFCORE */ depthMeshes.clear(); depthMeshes.reserve(6); textures.clear(); textures.reserve(6); const std::string dmDirectionStrings[6] = { "-dir_x1_y0_z0", "-dir_x-1_y0_z0", "-dir_x0_y1_z0", "-dir_x0_y-1_z0", "-dir_x0_y0_z1", "-dir_x0_y0_z-1" }; for (auto & dmDirectionString : dmDirectionStrings) { Util::GenericAttribute * attrib = currentCell->getAttribute("DepthMesh" + dmDirectionString); if (attrib == nullptr) { continue; } Util::FileName dmMeshPath(attrib->toString()); Util::Reference<Rendering::Mesh> dmMesh; #ifdef MINSG_EXT_OUTOFCORE Util::GenericAttribute * bbAttrib = currentCell->getAttribute("DepthMesh" + dmDirectionString + "-bounds"); if (bbAttrib == nullptr) { WARN("Found depth mesh with no bounding box."); continue; } std::vector<float> bbValues = Util::StringUtils::toFloats(bbAttrib->toString()); FAIL_IF(bbValues.size() != 6); const Geometry::Box meshBB(Geometry::Vec3(bbValues[0], bbValues[1], bbValues[2]), bbValues[3], bbValues[4], bbValues[5]); dmMesh = OutOfCore::addMesh(dmMeshPath, meshBB); #else /* MINSG_EXT_OUTOFCORE */ dmMesh = Rendering::Serialization::loadMesh(dmMeshPath); #endif /* MINSG_EXT_OUTOFCORE */ depthMeshes.emplace_back(dmMesh); // Count the depth mesh here already. renderedTriangles += dmMesh->getPrimitiveCount(); Util::GenericAttribute * texAttrib = currentCell->getAttribute("Texture" + dmDirectionString); if (texAttrib == nullptr) { continue; } Util::FileName texturePath(texAttrib->toString()); Util::Reference<Rendering::Texture> texture = Rendering::Serialization::loadTexture(texturePath); if (texture.isNull()) { WARN("Loading texture for depth mesh failed."); continue; } textures.emplace_back(texture); } } } const Geometry::Frustum & frustum = context.getCamera()->getFrustum(); holdObjects.clear(); holdObjects.reserve(objects.size()); std::sort(objects.begin(), objects.end()); for(const auto & ratioObjectPair : objects) { object_ptr o = ratioObjectPair.second; #ifdef MINSG_EXT_OUTOFCORE OutOfCore::getCacheManager().setUserPriority(o->getMesh(), 5); #endif /* MINSG_EXT_OUTOFCORE */ if (conditionalFrustumTest(frustum, o->getWorldBB(), rp)) { // [AccumRendering] // skip geometry rendered in the last frame if(renderedTriangles<startRuntime){ renderedTriangles += o->getTriangleCount(); continue; } // ---- if (debugOutput) { debugDisplay(renderedTriangles, o, context, rp); } else { context.displayNode(o, rp); renderedTriangles += o->getTriangleCount(); } holdObjects.push_back(o); } if (maxRuntime != 0 && renderedTriangles >= startRuntime+maxRuntime) { break; } } // Draw the textured depth meshes at the end. if (displayTexturedDepthMeshes) { context.getRenderingContext().pushAndSetPolygonOffset(Rendering::PolygonOffsetParameters(polygonOffsetFactor, polygonOffsetUnits)); auto texIt = textures.cbegin(); for (const auto & depthMesh : depthMeshes) { context.getRenderingContext().pushAndSetShader(getTDMShader()); context.getRenderingContext().pushAndSetTexture(0,texIt->get()); if (conditionalFrustumTest(frustum, depthMesh->getBoundingBox(), rp)) { context.displayMesh(depthMesh.get()); } context.getRenderingContext().popTexture(0); context.getRenderingContext().popShader(); #ifdef MINSG_EXT_OUTOFCORE OutOfCore::getCacheManager().setUserPriority(depthMesh.get(), 2); #endif /* MINSG_EXT_OUTOFCORE */ ++texIt; } context.getRenderingContext().popPolygonOffset(); } // [AccumRendering] startRuntime=renderedTriangles; // ---- return State::STATE_SKIP_RENDERING; }
void drawCamera(RenderingContext & rc, const Util::Color4f & color) { static Util::Reference<Mesh> mesh; if (mesh.isNull()) { std::deque<Mesh *> meshes; std::deque<Geometry::Matrix4x4f> transformations; { VertexDescription vertexDescription; vertexDescription.appendPosition3D(); vertexDescription.appendNormalFloat(); Geometry::Box box(Geometry::Vec3f(0.0f, 0.0f, 0.1f), 0.2f, 0.5f, 0.8f); meshes.push_back(MeshUtils::MeshBuilder::createBox(vertexDescription, box)); transformations.push_back(Geometry::Matrix4x4()); } { // Lens meshes.push_back(MeshUtils::MeshBuilder::createConicalFrustum(0.1f, 0.25f, 0.2f, 16)); Geometry::Matrix4x4f mat; mat.translate(0.0f, 0.0f, -0.3f); mat.rotate_deg(90.0f, 0.0f, 1.0f, 0.0f); transformations.push_back(mat); } { // Lens cap meshes.push_back(MeshUtils::MeshBuilder::createDiscSector(0.25f, 16)); Geometry::Matrix4x4f mat; mat.translate(0.0f, 0.0f, -0.5f); mat.rotate_deg(-90.0f, 0.0f, 1.0f, 0.0f); transformations.push_back(mat); } { // First film reel meshes.push_back(MeshUtils::MeshBuilder::createConicalFrustum(0.2f, 0.2f, 0.1f, 16)); Geometry::Matrix4x4f mat; mat.translate(-0.05f, 0.45f, -0.1f); transformations.push_back(mat); } { meshes.push_back(MeshUtils::MeshBuilder::createDiscSector(0.2f, 16)); Geometry::Matrix4x4f mat; mat.translate(-0.05f, 0.45f, -0.1f); transformations.push_back(mat); } { meshes.push_back(MeshUtils::MeshBuilder::createDiscSector(0.2f, 16)); Geometry::Matrix4x4f mat; mat.translate(0.05f, 0.45f, -0.1f); mat.rotate_deg(180.0f, 0.0f, 1.0f, 0.0f); transformations.push_back(mat); } { // Second film reel meshes.push_back(MeshUtils::MeshBuilder::createConicalFrustum(0.2f, 0.2f, 0.1f, 16)); Geometry::Matrix4x4f mat; mat.translate(-0.05f, 0.45f, 0.3f); transformations.push_back(mat); } { meshes.push_back(MeshUtils::MeshBuilder::createDiscSector(0.2f, 16)); Geometry::Matrix4x4f mat; mat.translate(-0.05f, 0.45f, 0.3f); transformations.push_back(mat); } { meshes.push_back(MeshUtils::MeshBuilder::createDiscSector(0.2f, 16)); Geometry::Matrix4x4f mat; mat.translate(0.05f, 0.45f, 0.3f); mat.rotate_deg(180.0f, 0.0f, 1.0f, 0.0f); transformations.push_back(mat); } mesh = MeshUtils::combineMeshes(meshes, transformations); } rc.pushAndSetLighting(LightingParameters(false)); rc.pushAndSetColorMaterial(Util::Color4f(color)); rc.displayMesh(mesh.get()); rc.popMaterial(); rc.popLighting(); }
void ParticleBillboardRenderer::operator()(ParticleSystemNode * psys, FrameContext & context, const RenderParam & rp) { if(rp.getFlag(NO_GEOMETRY)) { return; } const auto & worldToCamera = context.getRenderingContext().getMatrix_worldToCamera(); const auto cameraToWorld = worldToCamera.inverse(); const auto halfRight = cameraToWorld.transformDirection(context.getWorldRightVector() * 0.5f); const auto halfUp = cameraToWorld.transformDirection(context.getWorldUpVector() * 0.5f); // 2. just update position for each particle and render // render particles const uint32_t count = psys->getParticleCount(); Rendering::VertexDescription vertexDesc; const Rendering::VertexAttribute & posAttrib = vertexDesc.appendPosition3D(); const Rendering::VertexAttribute & colorAttrib = vertexDesc.appendColorRGBAByte(); const Rendering::VertexAttribute & texCoordAttrib = vertexDesc.appendTexCoord(); // The usage of a cache for the mesh has been tested. Reusing a preallocated mesh is not faster. Util::Reference<Rendering::Mesh> mesh = new Rendering::Mesh(vertexDesc, 4 * count, 6 * count); mesh->setDataStrategy(Rendering::SimpleMeshDataStrategy::getPureLocalStrategy()); Rendering::MeshIndexData & indexData = mesh->openIndexData(); Rendering::MeshVertexData & vertexData = mesh->openVertexData(); Util::Reference<Rendering::PositionAttributeAccessor> positionAccessor = Rendering::PositionAttributeAccessor::create(vertexData, posAttrib.getNameId()); Util::Reference<Rendering::ColorAttributeAccessor> colorAccessor = Rendering::ColorAttributeAccessor::create(vertexData, colorAttrib.getNameId()); Util::Reference<Rendering::TexCoordAttributeAccessor> texCoordAccessor = Rendering::TexCoordAttributeAccessor::create(vertexData, texCoordAttrib.getNameId()); uint32_t * indices = indexData.data(); uint_fast32_t index = 0; for(const auto & p : psys->getParticles()) { const Geometry::Vec3f upOffset = halfUp * p.size.getHeight(); const Geometry::Vec3f rightOffset = halfRight * p.size.getWidth(); colorAccessor->setColor(index + 0, p.color); texCoordAccessor->setCoordinate(index + 0, Geometry::Vec2f(0.0f, 0.0f)); positionAccessor->setPosition(index + 0, p.position + upOffset - rightOffset); colorAccessor->setColor(index + 1, p.color); texCoordAccessor->setCoordinate(index + 1, Geometry::Vec2f(0.0f, 1.0f)); positionAccessor->setPosition(index + 1, p.position - upOffset - rightOffset); colorAccessor->setColor(index + 2, p.color); texCoordAccessor->setCoordinate(index + 2, Geometry::Vec2f(1.0f, 1.0f)); positionAccessor->setPosition(index + 2, p.position - upOffset + rightOffset); colorAccessor->setColor(index + 3, p.color); texCoordAccessor->setCoordinate(index + 3, Geometry::Vec2f(1.0f, 0.0f)); positionAccessor->setPosition(index + 3, p.position + upOffset + rightOffset); *indices++ = index + 0; *indices++ = index + 1; *indices++ = index + 3; *indices++ = index + 1; *indices++ = index + 2; *indices++ = index + 3; index += 4; } indexData.markAsChanged(); indexData.updateIndexRange(); vertexData.markAsChanged(); vertexData.updateBoundingBox(); context.displayMesh(mesh.get()); }
void drawCoordSys(RenderingContext & rc, float scale) { static Util::Reference<Mesh> arrow; static Util::Reference<Mesh> sphere; static Util::Reference<Mesh> charX; static Util::Reference<Mesh> charY; static Util::Reference<Mesh> charZ; const float radius = 0.025f; if (arrow.isNull()) { std::deque<Mesh *> meshes; std::deque<Geometry::Matrix4x4> transformations; Geometry::Matrix4x4 transform; meshes.push_back(MeshUtils::MeshBuilder::createConicalFrustum(radius, radius, 0.7f, 16)); transformations.push_back(transform); meshes.push_back(MeshUtils::MeshBuilder::createConicalFrustum(radius, 2.0f * radius, 0.01f, 16)); transform.translate(0.7f, 0.0f, 0.0f); transformations.push_back(transform); meshes.push_back(MeshUtils::MeshBuilder::createCone(2.0f * radius, 0.29f, 16)); transform.translate(0.01f, 0.0f, 0.0f); transformations.push_back(transform); arrow = MeshUtils::combineMeshes(meshes, transformations); MeshUtils::optimizeIndices(arrow.get()); while (!meshes.empty()) { delete meshes.back(); meshes.pop_back(); } } if (sphere.isNull()) { Util::Reference<Mesh> icosahedron = MeshUtils::PlatonicSolids::createIcosahedron(); sphere = MeshUtils::PlatonicSolids::createEdgeSubdivisionSphere(icosahedron.get(), 2); Geometry::Matrix4x4 transform; transform.scale(1.1f * radius); MeshUtils::transform(sphere.get()->openVertexData(), transform); } if(charX.isNull()) { std::deque<Mesh *> meshes; std::deque<Geometry::Matrix4x4> transformations; VertexDescription vertexDescription; vertexDescription.appendPosition3D(); vertexDescription.appendNormalFloat(); const Geometry::Box box(Geometry::Vec3f(0.0f, 0.0f, 0.0f), 0.02f, 0.2f, 0.05f); { meshes.push_back(MeshUtils::MeshBuilder::createBox(vertexDescription, box)); Geometry::Matrix4x4 transform; transform.translate(1.2f, 0.0f, 0.0f); transform.rotate_deg(30.0f, 0.0f, 0.0f, -1.0f); transformations.push_back(transform); } { meshes.push_back(MeshUtils::MeshBuilder::createBox(vertexDescription, box)); Geometry::Matrix4x4 transform; transform.translate(1.2f, 0.0f, 0.0f); transform.rotate_deg(-30.0f, 0.0f, 0.0f, -1.0f); transformations.push_back(transform); } charX = MeshUtils::combineMeshes(meshes, transformations); MeshUtils::optimizeIndices(charX.get()); while(!meshes.empty()) { delete meshes.back(); meshes.pop_back(); } } if(charY.isNull()) { std::deque<Mesh *> meshes; std::deque<Geometry::Matrix4x4> transformations; VertexDescription vertexDescription; vertexDescription.appendPosition3D(); vertexDescription.appendNormalFloat(); const Geometry::Box box(Geometry::Vec3f(0.0f, 0.0f, 0.0f), 0.02f, 0.1f, 0.05f); { meshes.push_back(MeshUtils::MeshBuilder::createBox(vertexDescription, box)); Geometry::Matrix4x4 transform; transform.translate(0.025f, 0.045f, 0.0f); transform.rotate_deg(30.0f, 0.0f, 0.0f, -1.0f); transformations.push_back(transform); } { meshes.push_back(MeshUtils::MeshBuilder::createBox(vertexDescription, box)); Geometry::Matrix4x4 transform; transform.translate(-0.025f, 0.045f, 0.0f); transform.rotate_deg(-30.0f, 0.0f, 0.0f, -1.0f); transformations.push_back(transform); } { meshes.push_back(MeshUtils::MeshBuilder::createBox(vertexDescription, box)); Geometry::Matrix4x4 transform; transform.translate(0.0f, -0.045f, 0.0f); transformations.push_back(transform); } charY = MeshUtils::combineMeshes(meshes, transformations); Geometry::Matrix4x4 transform; transform.translate(1.2f, 0.0f, 0.0f); transform.rotate_deg(90.0f, 0.0f, 0.0f, -1.0f); MeshUtils::transform(charY->openVertexData(), transform); MeshUtils::optimizeIndices(charY.get()); while(!meshes.empty()) { delete meshes.back(); meshes.pop_back(); } } if(charZ.isNull()) { std::deque<Mesh *> meshes; std::deque<Geometry::Matrix4x4> transformations; VertexDescription vertexDescription; vertexDescription.appendPosition3D(); vertexDescription.appendNormalFloat(); const Geometry::Box box(Geometry::Vec3f(0.0f, 0.0f, 0.0f), 0.02f, 0.1f, 0.05f); { meshes.push_back(MeshUtils::MeshBuilder::createBox(vertexDescription, box)); Geometry::Matrix4x4 transform; transform.translate(1.2f, 0.075f, 0.0f); transform.rotate_deg(90.0f, 0.0f, 0.0f, -1.0f); transformations.push_back(transform); } { meshes.push_back(MeshUtils::MeshBuilder::createBox(vertexDescription, box)); Geometry::Matrix4x4 transform; transform.translate(1.2f, 0.0f, 0.0f); transform.rotate_deg(-30.0f, 0.0f, 0.0f, -1.0f); transform.scale(1.0f, 1.6f, 1.0f); transformations.push_back(transform); } { meshes.push_back(MeshUtils::MeshBuilder::createBox(vertexDescription, box)); Geometry::Matrix4x4 transform; transform.translate(1.2f, -0.075f, 0.0f); transform.rotate_deg(-90.0f, 0.0f, 0.0f, -1.0f); transformations.push_back(transform); } charZ = MeshUtils::combineMeshes(meshes, transformations); MeshUtils::optimizeIndices(charZ.get()); while(!meshes.empty()) { delete meshes.back(); meshes.pop_back(); } } // Origin rc.pushAndSetColorMaterial(Util::ColorLibrary::WHITE); rc.displayMesh(sphere.get()); rc.popMaterial(); // X axis Geometry::Matrix4x4 transform; transform.scale(scale, 1.0f, 1.0f); rc.pushMatrix_modelToCamera(); rc.multMatrix_modelToCamera(transform); rc.pushAndSetColorMaterial(Util::ColorLibrary::RED); rc.displayMesh(arrow.get()); rc.displayMesh(charX.get()); rc.popMaterial(); rc.popMatrix_modelToCamera(); // Y axis transform.setIdentity(); transform.scale(1.0f, scale, 1.0f); transform.rotate_deg(90.0f, 0.0f, 0.0f, 1.0f); rc.pushMatrix_modelToCamera(); rc.multMatrix_modelToCamera(transform); rc.pushAndSetColorMaterial(Util::ColorLibrary::GREEN); rc.displayMesh(arrow.get()); rc.displayMesh(charY.get()); rc.popMaterial(); rc.popMatrix_modelToCamera(); // Z axis transform.setIdentity(); transform.scale(1.0f, 1.0f, scale); transform.rotate_deg(90.0f, 0.0f, -1.0f, 0.0f); rc.pushMatrix_modelToCamera(); rc.multMatrix_modelToCamera(transform); rc.pushAndSetColorMaterial(Util::ColorLibrary::BLUE); rc.displayMesh(arrow.get()); rc.displayMesh(charZ.get()); rc.popMaterial(); rc.popMatrix_modelToCamera(); }
void QuadtreeMeshBuilder::createDebugOutput(const std::deque<QuadtreeMeshBuilder::QuadTree *> & leaves, Util::PixelAccessor * sourceDepth, Util::PixelAccessor * sourceColor) { const uint32_t bitmapWidth = static_cast<uint32_t> (sourceDepth->getWidth()); const uint32_t bitmapHeight = static_cast<uint32_t> (sourceDepth->getHeight()); Util::Reference<Util::Bitmap> depthDebugBitmap = new Util::Bitmap(bitmapWidth, bitmapHeight, Util::PixelFormat::MONO_FLOAT); Util::Reference<Util::Bitmap> quadTreeDebugBitmap = new Util::Bitmap(bitmapWidth, bitmapHeight, Util::PixelFormat::RGBA); Util::Reference<Util::PixelAccessor> destQuadTree(Util::PixelAccessor::create(quadTreeDebugBitmap.get())); float depthMin = std::numeric_limits<float>::max(); float depthMax = std::numeric_limits<float>::lowest(); { for (uint_fast32_t y = 0; y < bitmapHeight; ++y) { for (uint_fast32_t x = 0; x < bitmapWidth; ++x) { const float depthValue = sourceDepth->readSingleValueFloat(x, y); if (depthValue < depthMin) { depthMin = depthValue; } if (depthValue > depthMax) { depthMax = depthValue; } } } Util::Reference<Util::PixelAccessor> destDepth(Util::PixelAccessor::create(depthDebugBitmap.get())); const float depthScale = depthMax - depthMin; for (uint_fast32_t y = 0; y < bitmapHeight; ++y) { for (uint_fast32_t x = 0; x < bitmapWidth; ++x) { const float depthValue = sourceDepth->readSingleValueFloat(x, y); destDepth->writeColor(x, bitmapHeight - y - 1, Util::Color4f((depthValue - depthMin) / depthScale, 0.0f, 0.0f, 0.0f)); destQuadTree->writeColor(x, bitmapHeight - y - 1, Util::Color4ub(0, 0, 0, 0)); } } } for (const auto & leaf : leaves) { const uint16_t xMin = leaf->getX(); const uint16_t yMin = leaf->getY(); const uint16_t xMax = leaf->getWidth() + xMin; const uint16_t yMax = leaf->getHeight() + yMin; for (uint_fast32_t x = xMin; x < xMax; ++x) { destQuadTree->writeColor(x, bitmapHeight - yMin - 1, Util::Color4ub(255, 255, 255, 127)); } for (uint_fast32_t y = yMin; y < yMax; ++y) { destQuadTree->writeColor(xMin, bitmapHeight - y - 1, Util::Color4ub(255, 255, 255, 127)); } const uint16_t xHalf = xMin + leaf->getWidth() / 2; const uint16_t yHalf = yMin + leaf->getHeight() / 2; const Util::Color4ub errorColor(255, 0, 255, 255); Util::Color4ub drawColor(255, 0, 0, 127); const QuadtreeMeshBuilder::QuadTree * west = leaf->getWestNeighbor(); if(west != nullptr) { const uint16_t westXHalf = west->getX() + west->getWidth() / 2; const uint16_t westYHalf = west->getY() + west->getHeight() / 2; // Check if neighbor is correct. if(west->getHeight() < leaf->getHeight()) { drawColor = errorColor; } if(west->getX() + west->getWidth() != xMin) { drawColor = errorColor; } drawLine(destQuadTree.get(), drawColor, xHalf, bitmapHeight - yHalf - 1 - 1, westXHalf, bitmapHeight - westYHalf - 1 - 1); } else { // Check if neighbor should be missing. if(xMin != 0) { drawColor = errorColor; } drawLine(destQuadTree.get(), drawColor, xHalf, bitmapHeight - yHalf - 1 - 1, static_cast<int32_t>(0.75 * xMin + 0.25 * xMax), bitmapHeight - yHalf - 1 - 1); } drawColor = Util::Color4ub(255, 255, 0, 127); const QuadtreeMeshBuilder::QuadTree * east = leaf->getEastNeighbor(); if(east != nullptr) { const uint16_t eastXHalf = east->getX() + east->getWidth() / 2; const uint16_t eastYHalf = east->getY() + east->getHeight() / 2; // Check if neighbor is correct. if(east->getHeight() < leaf->getHeight()) { drawColor = errorColor; } if(xMax != east->getX()) { drawColor = errorColor; } drawLine(destQuadTree.get(), drawColor, xHalf, bitmapHeight - yHalf - 1 + 1, eastXHalf, bitmapHeight - eastYHalf - 1 + 1); } else { // Check if neighbor should be missing. if(xMax != bitmapWidth - 1) { drawColor = errorColor; // Error } drawLine(destQuadTree.get(), drawColor, xHalf, bitmapHeight - yHalf - 1 + 1, static_cast<int32_t>(0.25 * xMin + 0.75 * xMax), bitmapHeight - yHalf - 1 + 1); } drawColor = Util::Color4ub(0, 0, 255, 127); const QuadtreeMeshBuilder::QuadTree * north = leaf->getNorthNeighbor(); if(north != nullptr) { const uint16_t northXHalf = north->getX() + north->getWidth() / 2; const uint16_t northYHalf = north->getY() + north->getHeight() / 2; // Check if neighbor is correct. if(north->getWidth() < leaf->getWidth()) { drawColor = errorColor; } if(north->getY() + north->getHeight() != yMin) { drawColor = errorColor; } drawLine(destQuadTree.get(), drawColor, xHalf, bitmapHeight - yHalf - 1, northXHalf, bitmapHeight - northYHalf - 1); } else { // Check if neighbor should be missing. if(yMin != 0) { drawColor = errorColor; // Error } drawLine(destQuadTree.get(), drawColor, xHalf, bitmapHeight - yHalf - 1, xHalf, static_cast<int32_t>(bitmapHeight - (0.75 * yMin + 0.25 * yMax) - 1)); } drawColor = Util::Color4ub(0, 255, 255, 127); const QuadtreeMeshBuilder::QuadTree * south = leaf->getSouthNeighbor(); if(south != nullptr) { const uint16_t southXHalf = south->getX() + south->getWidth() / 2; const uint16_t southYHalf = south->getY() + south->getHeight() / 2; // Check if neighbor is correct. if(south->getWidth() < leaf->getWidth()) { drawColor = errorColor; } if(yMax != south->getY()) { drawColor = errorColor; } drawLine(destQuadTree.get(), drawColor, xHalf, bitmapHeight - yHalf - 1, southXHalf, bitmapHeight - southYHalf - 1); } else { // Check if neighbor should be missing. if(yMax != bitmapHeight - 1) { drawColor = errorColor; // Error } drawLine(destQuadTree.get(), drawColor, xHalf, bitmapHeight - yHalf - 1, xHalf, static_cast<int32_t>(bitmapHeight - (0.25 * yMin + 0.75 * yMax) - 1)); } destQuadTree->writeColor(xHalf, bitmapHeight - yHalf - 1, Util::Color4ub(0, 0, 0, 127)); } const std::string currentTime = Util::Utils::createTimeStamp(); if(sourceColor != nullptr) { Util::Reference<Util::Bitmap> colorDebugBitmap = new Util::Bitmap(bitmapWidth, bitmapHeight, Util::PixelFormat::RGB); Util::Reference<Util::PixelAccessor> destColor(Util::PixelAccessor::create(colorDebugBitmap.get())); for (uint_fast32_t y = 0; y < bitmapHeight; ++y) { for (uint_fast32_t x = 0; x < bitmapWidth; ++x) { destColor->writeColor(x, bitmapHeight - y - 1, sourceColor->readColor4f(x, y)); } } Util::Serialization::saveBitmap(*colorDebugBitmap.get(), Util::FileName("screens/QuadTreeMeshBuilder_" + currentTime + "_Color.png")); } Util::Serialization::saveBitmap(*depthDebugBitmap.get(), Util::FileName("screens/QuadTreeMeshBuilder_" + currentTime + "_Depth.png")); Util::Serialization::saveBitmap(*quadTreeDebugBitmap.get(), Util::FileName("screens/QuadTreeMeshBuilder_" + currentTime + "_QuadTree.png")); std::ofstream textDebug("screens/QuadTreeMeshBuilder_Information.txt", std::ios_base::out | std::ios_base::app); textDebug << currentTime << '\t' << leaves.size() << '\t' << depthMin << '\t' << depthMax << '\n'; // sleep(1); }
void AbstractOnGpuComparator::releaseTexture(const Util::Reference<Texture> & tex) { usedTextures.erase(tex); freeTextures[Geometry::Vec2i(tex->getWidth(), tex->getHeight())].push_back(tex); }
int test_spherical_sampling_serialization() { #ifdef MINSG_EXT_SVS std::cout << "Test serialization of SVS objects ... "; Util::Timer timer; timer.reset(); using namespace MinSG::SVS; MinSG::SceneManagement::SceneManager sceneManager; const uint32_t count = 10; std::array<Util::Reference<MinSG::GeometryNode>, count> nodes; for(uint_fast32_t i = 0; i < count; ++i) { nodes[i] = new MinSG::GeometryNode; sceneManager.registerNode(std::string("Node") + Util::StringUtils::toString(i), nodes[i].get()); } MinSG::VisibilitySubdivision::VisibilityVector vv; for(uint_fast32_t i = 0; i < count; ++i) { vv.setNode(nodes[i].get(), i); } std::vector<SamplePoint> samples; { using namespace Rendering::MeshUtils::PlatonicSolids; Util::Reference<Rendering::Mesh> mesh = createEdgeSubdivisionSphere(createIcosahedron(), 4); auto accessor = Rendering::PositionAttributeAccessor::create(mesh->openVertexData(), Rendering::VertexAttributeIds::POSITION); for(std::size_t i = 0; accessor->checkRange(i); ++i) { samples.emplace_back(accessor->getPosition(i)); } } { std::stringstream stream; stream.precision(std::numeric_limits<long double>::digits10); // Serialize for(const auto & sample : samples) { stream << sample.getPosition() << ' '; sample.getValue().serialize(stream, sceneManager); stream << ' '; } // Unserialize std::vector<SamplePoint> newSamples; for(std::size_t s = 0; s < samples.size(); ++s) { Geometry::Vec3f pos; stream >> pos; SamplePoint sample(pos); sample.setValue(MinSG::VisibilitySubdivision::VisibilityVector::unserialize(stream, sceneManager)); newSamples.push_back(sample); } for(std::size_t s = 0; s < samples.size(); ++s) { const SamplePoint & oldSample = samples[s]; const SamplePoint & newSample = newSamples[s]; if(oldSample.getPosition().distance(newSample.getPosition()) > std::numeric_limits<float>::epsilon()) { std::cout << "Serialization/unserialization failed." << std::endl; return EXIT_FAILURE; } const auto & oldVV = oldSample.getValue(); const auto & newVV = newSample.getValue(); for(uint_fast32_t n = 0; n < count; ++n) { if(oldVV.getBenefits(nodes[n].get()) != newVV.getBenefits(nodes[n].get())) { std::cout << "Serialization/unserialization failed." << std::endl; return EXIT_FAILURE; } } } } VisibilitySphere visibilitySphere(Geometry::Sphere_f(Geometry::Vec3f(1.0f, 2.0f, 3.0f), 17.0f), samples); { std::stringstream stream; stream.precision(std::numeric_limits<long double>::digits10); // Serialize stream << visibilitySphere.getSphere() << ' ' << samples.size(); for(const auto & sample : samples) { stream << ' ' << sample.getPosition() << ' '; sample.getValue().serialize(stream, sceneManager); stream << ' '; } // Unserialize Geometry::Sphere_f sphere; stream >> sphere; std::size_t sampleCount; stream >> sampleCount; std::vector<SamplePoint> newSamples; for(std::size_t s = 0; s < sampleCount; ++s) { Geometry::Vec3f pos; stream >> pos; SamplePoint sample(pos); sample.setValue(MinSG::VisibilitySubdivision::VisibilityVector::unserialize(stream, sceneManager)); newSamples.push_back(sample); } VisibilitySphere newVisibilitySphere(sphere, newSamples); if(!(visibilitySphere.getSphere() == newVisibilitySphere.getSphere())) { std::cout << "Serialization/unserialization failed." << std::endl; return EXIT_FAILURE; } for(std::size_t s = 0; s < samples.size(); ++s) { const SamplePoint & oldSample = visibilitySphere.getSamples()[s]; const SamplePoint & newSample = newVisibilitySphere.getSamples()[s]; if(oldSample.getPosition().distance(newSample.getPosition()) > std::numeric_limits<float>::epsilon()) { std::cout << "Serialization/unserialization failed." << std::endl; return EXIT_FAILURE; } const auto & oldVV = oldSample.getValue(); const auto & newVV = newSample.getValue(); for(uint_fast32_t n = 0; n < count; ++n) { if(oldVV.getBenefits(nodes[n].get()) != newVV.getBenefits(nodes[n].get())) { std::cout << "Serialization/unserialization failed." << std::endl; return EXIT_FAILURE; } } } } timer.stop(); std::cout << "done (duration: " << timer.getSeconds() << " s).\n"; #endif /* MINSG_EXT_SVS */ return EXIT_SUCCESS; }
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); }
void drawQuad(RenderingContext & rc, const Geometry::Vec3 & lowerLeft, const Geometry::Vec3 & lowerRight, const Geometry::Vec3 & upperRight, const Geometry::Vec3 & upperLeft) { static Util::Reference<Mesh> mesh; if (mesh.isNull()) { VertexDescription vertexDescription; vertexDescription.appendPosition3D(); vertexDescription.appendNormalFloat(); vertexDescription.appendTexCoord(); mesh = new Mesh(vertexDescription, 4, 6); MeshIndexData & id = mesh->openIndexData(); uint32_t * indices = id.data(); indices[0] = 0; indices[1] = 1; indices[2] = 2; indices[3] = 0; indices[4] = 2; indices[5] = 3; id.updateIndexRange(); id.markAsChanged(); } const Geometry::Vec3 edgeA = lowerRight - lowerLeft; const Geometry::Vec3 edgeB = upperLeft - lowerLeft; Geometry::Vec3 normal = edgeA.cross(edgeB); normal.normalize(); MeshVertexData & vd = mesh->openVertexData(); float * vertices = reinterpret_cast<float *> (vd.data()); // Lower left *vertices++ = lowerLeft.getX(); *vertices++ = lowerLeft.getY(); *vertices++ = lowerLeft.getZ(); *vertices++ = normal.getX(); *vertices++ = normal.getY(); *vertices++ = normal.getZ(); *vertices++ = 0.0f; *vertices++ = 0.0f; // Lower right *vertices++ = lowerRight.getX(); *vertices++ = lowerRight.getY(); *vertices++ = lowerRight.getZ(); *vertices++ = normal.getX(); *vertices++ = normal.getY(); *vertices++ = normal.getZ(); *vertices++ = 1.0f; *vertices++ = 0.0f; // Upper right *vertices++ = upperRight.getX(); *vertices++ = upperRight.getY(); *vertices++ = upperRight.getZ(); *vertices++ = normal.getX(); *vertices++ = normal.getY(); *vertices++ = normal.getZ(); *vertices++ = 1.0f; *vertices++ = 1.0f; // Upper left *vertices++ = upperLeft.getX(); *vertices++ = upperLeft.getY(); *vertices++ = upperLeft.getZ(); *vertices++ = normal.getX(); *vertices++ = normal.getY(); *vertices++ = normal.getZ(); *vertices++ = 0.0f; *vertices++ = 1.0f; vd.updateBoundingBox(); vd.markAsChanged(); rc.displayMesh(mesh.get()); }
int test_OutOfCore() { #ifdef MINSG_EXT_OUTOFCORE const bool verbose = true; // Tests for MinSG::OutOfCore::CacheObjectPriority if(sizeof(MinSG::OutOfCore::CacheObjectPriority) != 8) { return EXIT_FAILURE; } if(!(MinSG::OutOfCore::CacheObjectPriority(1, 2, 3) == MinSG::OutOfCore::CacheObjectPriority(1, 2, 3))) { return EXIT_FAILURE; } if(!(MinSG::OutOfCore::CacheObjectPriority(1, 100, 100) < MinSG::OutOfCore::CacheObjectPriority(2, 0, 0))) { return EXIT_FAILURE; } if(!(MinSG::OutOfCore::CacheObjectPriority(2, 1, 100) < MinSG::OutOfCore::CacheObjectPriority(2, 2, 0))) { return EXIT_FAILURE; } if(!(MinSG::OutOfCore::CacheObjectPriority(2, 2, 1) < MinSG::OutOfCore::CacheObjectPriority(2, 2, 2))) { return EXIT_FAILURE; } std::default_random_engine engine; std::uniform_int_distribution<std::size_t> vertexCountDist(10, 1000); const uint32_t numMeshes = 30000; const Util::TemporaryDirectory tempDir("MinSGTest_OutOfCore"); // Create empty meshes and save them into a subdirectory. { Rendering::VertexDescription vertexDesc; vertexDesc.appendPosition3D(); for(uint_fast32_t i = 0; i < numMeshes; ++i) { Util::Reference<Rendering::Mesh> mesh = new Rendering::Mesh(vertexDesc, vertexCountDist(engine), 64); Rendering::MeshVertexData & vertexData = mesh->openVertexData(); std::fill_n(vertexData.data(), vertexData.dataSize(), 0); vertexData.markAsChanged(); Rendering::MeshIndexData & indexData = mesh->openIndexData(); std::fill_n(indexData.data(), indexData.getIndexCount(), 0); indexData.markAsChanged(); const std::string numberString = Util::StringUtils::toString<uint32_t>(i); Rendering::Serialization::saveMesh(mesh.get(), Util::FileName(tempDir.getPath().getDir() + numberString + ".mmf")); } } // Set up the OutOfCore system. MinSG::FrameContext frameContext; MinSG::OutOfCore::setUp(frameContext); MinSG::OutOfCore::CacheManager & manager = MinSG::OutOfCore::getCacheManager(); manager.addCacheLevel(MinSG::OutOfCore::CacheLevelType::FILE_SYSTEM, 0); manager.addCacheLevel(MinSG::OutOfCore::CacheLevelType::FILES, 512 * kibibyte); manager.addCacheLevel(MinSG::OutOfCore::CacheLevelType::MAIN_MEMORY, 256 * kibibyte); Util::Timer addTimer; addTimer.reset(); std::cout << "Adding meshes ..." << std::flush; // Add the meshes to the OutOfCore system. std::vector<Util::Reference<Rendering::Mesh> > meshes; meshes.reserve(numMeshes); static const Geometry::Box boundingBox(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f); for(uint_fast32_t i = 0; i < numMeshes; ++i) { const std::string numberString = Util::StringUtils::toString<uint32_t>(i); meshes.push_back(MinSG::OutOfCore::addMesh(Util::FileName(tempDir.getPath().getDir() + numberString + ".mmf"), boundingBox)); } manager.trigger(); addTimer.stop(); std::cout << " done (" << addTimer.getSeconds() << " s)" << std::endl; Util::Timer displayTimer; Util::Timer assureLocalTimer; Util::Timer overallTimer; overallTimer.reset(); uint32_t frame = 0; { // Simulate frames to get the OutOfCore system working. std::uniform_int_distribution<std::size_t> indexDist(0, meshes.size() - 1); for(; frame < 10; ++frame) { std::cout << "Executing frame " << frame << " ..." << std::flush; frameContext.beginFrame(); displayTimer.reset(); // Simulate display of meshes to change the priorities of the system. for(uint32_t i = 0; i < meshes.size() / 2; ++i) { const uint32_t meshIndex = indexDist(engine); Rendering::Mesh * mesh = meshes[meshIndex].get(); manager.meshDisplay(mesh); } manager.trigger(); displayTimer.stop(); assureLocalTimer.reset(); for(uint32_t i = 0; i < 10; ++i) { const uint32_t meshIndex = indexDist(engine); Rendering::Mesh * mesh = meshes[meshIndex].get(); const Rendering::MeshVertexData & vd = mesh->openVertexData(); const Rendering::MeshIndexData & id = mesh->openIndexData(); if (!vd.hasLocalData() || !id.hasLocalData()) { std::cout << "Error: Mesh has no local data." << std::endl; return EXIT_FAILURE; } } assureLocalTimer.stop(); frameContext.endFrame(); std::cout << " done (display: " << displayTimer.getSeconds() << " s, assureLocal: " << assureLocalTimer.getSeconds() << " s)" << std::endl; if(verbose) { outputCacheLevelInformation(); } } } for(uint32_t round = 0; round < 10; ++round) { Util::Timer addAgainTimer; addAgainTimer.reset(); std::cout << "Adding additional meshes ..." << std::flush; // Simulate loading a second scene by adding meshes again. meshes.reserve(meshes.size() + 3 * numMeshes); for(uint_fast32_t i = 0; i < numMeshes; ++i) { const std::string numberString = Util::StringUtils::toString<uint32_t>(i); meshes.push_back(MinSG::OutOfCore::addMesh(Util::FileName(tempDir.getPath().getDir() + numberString + ".mmf"), boundingBox)); meshes.push_back(MinSG::OutOfCore::addMesh(Util::FileName(tempDir.getPath().getDir() + numberString + ".mmf"), boundingBox)); meshes.push_back(MinSG::OutOfCore::addMesh(Util::FileName(tempDir.getPath().getDir() + numberString + ".mmf"), boundingBox)); } manager.trigger(); addAgainTimer.stop(); std::cout << " done (" << addAgainTimer.getSeconds() << " s)" << std::endl; // Simulate frames to get the OutOfCore system working. std::normal_distribution<double> indexDist(meshes.size() / 2, std::sqrt(meshes.size() / 2)); const auto untilFrame = frame + 5; for(; frame < untilFrame; ++frame) { std::cout << "Executing frame " << frame << " ..." << std::flush; frameContext.beginFrame(); displayTimer.reset(); // Simulate display of meshes to change the priorities of the system. for(uint32_t i = 0; i < meshes.size() / 10; ++i) { const std::size_t meshIndex = std::max(static_cast<std::size_t>(0), std::min(static_cast<std::size_t>(indexDist(engine)), meshes.size() - 1)); Rendering::Mesh * mesh = meshes[meshIndex].get(); manager.meshDisplay(mesh); } manager.trigger(); displayTimer.stop(); frameContext.endFrame(); std::cout << " done (display: " << displayTimer.getSeconds() << " s)" << std::endl; if(verbose) { outputCacheLevelInformation(); } } } overallTimer.stop(); std::cout << "Overall duration: " << overallTimer.getSeconds() << " s" << std::endl; MinSG::OutOfCore::shutDown(); return EXIT_SUCCESS; #else /* MINSG_EXT_OUTOFCORE */ return EXIT_FAILURE; #endif /* MINSG_EXT_OUTOFCORE */ }
int test_large_scene(Util::UI::Window * window, Util::UI::EventContext & eventContext) { // texture registry std::map<std::string, Util::Reference<Rendering::Texture> > textures; std::cout << "Create FrameContext...\n"; FrameContext fc; unsigned int renderingFlags = /*BOUNDING_BOXES|SHOW_META_OBJECTS|*/FRUSTUM_CULLING/*|SHOW_COORD_SYSTEM*/;//|SHOW_COORD_SYSTEM; std::cout << "Create scene graph...\n"; Util::Reference<GroupNode> root = new MinSG::ListNode(); /// Skybox SkyboxState * sb = SkyboxState::createSkybox("Data/texture/?.bmp"); root->addState(sb); /// Some shperes... { std::default_random_engine engine; std::uniform_real_distribution<float> coordinateDist(0.0f, 200.0f); std::vector<Util::Reference<Rendering::Mesh> > spheres; Util::Reference<Rendering::Mesh> icosahedron = Rendering::MeshUtils::PlatonicSolids::createIcosahedron(); for(int i=0;i<6;++i) spheres.push_back(Rendering::MeshUtils::PlatonicSolids::createEdgeSubdivisionSphere(icosahedron.get(), i)); // 6... 81920 triangles each for (int i = 0; i < 1000; i++) { // create a real clone inclusive internal data! MinSG::GeometryNode * gn = new GeometryNode(spheres[std::uniform_int_distribution<std::size_t>(0, spheres.size() - 1)(engine)]->clone()); gn->moveRel(Geometry::Vec3(coordinateDist(engine), coordinateDist(engine), coordinateDist(engine))); root->addChild(gn); gn->scale(0.1 + std::uniform_real_distribution<float>(0.0f, 1000.0f)(engine) / 400.0); } } /// Camera Node * schwein = loadModel(Util::FileName("Data/model/Schwein.low.t.ply"), MESH_AUTO_CENTER | MESH_AUTO_SCALE); ListNode * camera = new ListNode(); CameraNode * camNode = new CameraNode(); camNode->setViewport(Geometry::Rect_i(0, 0, 1024, 768)); camNode->setNearFar(0.1, 2000); camNode->applyVerticalAngle(80); camNode->moveRel(Geometry::Vec3(0, 4, 10)); camera->addChild(camNode); camera->addChild(schwein); schwein->moveRel(Geometry::Vec3(0, 0, 0)); schwein->rotateLocal_deg(180, Geometry::Vec3(0, 1, 0)); LightNode * myHeadLight = LightNode::createPointLight(); myHeadLight->scale(1); myHeadLight->moveRel(Geometry::Vec3(0, 0, 0)); camera->addChild(myHeadLight); LightingState * lightState = new LightingState; lightState->setLight(myHeadLight); root->addState(lightState); root->addChild(camera); /// Eventhandler MoveNodeHandler * eh = new MoveNodeHandler(); MoveNodeHandler::initClaudius(eh, camera); // --------------------------------------------------------------------------------------------- Rendering::RenderingContext::clearScreen(Util::Color4f(0.5f, 0.5f, 0.5f, 0.5f)); // ---- GET_GL_ERROR(); uint32_t fpsFrameCounter = 0; Util::Timer fpsTimer; std::cout << "\nEntering main loop...\n"; // program main loop bool done = false; while (!done) { ++fpsFrameCounter; double seconds = fpsTimer.getSeconds(); if (seconds > 1.0) { double fps = static_cast<double> (fpsFrameCounter) / seconds; std::cout << "\r " << fps << " fps "; std::cout.flush(); fpsTimer.reset(); fpsFrameCounter = 0; } // message processing loop eventContext.getEventQueue().process(); while (eventContext.getEventQueue().getNumEventsAvailable() > 0) { Util::UI::Event event = eventContext.getEventQueue().popEvent(); // check for messages switch (event.type) { // exit if the window is closed case Util::UI::EVENT_QUIT: done = true; break; // check for keypresses case Util::UI::EVENT_KEYBOARD: { if(event.keyboard.pressed && event.keyboard.key == Util::UI::KEY_ESCAPE) { done = true; } break; } } // end switch } // end of message processing // apply translation eh->execute(); // clear screen Rendering::RenderingContext::clearScreen(Util::Color4f(0.0f, 0.0f, 0.0f, 1.0f)); // enable Camera fc.setCamera(camNode); // render Scene root->display(fc, renderingFlags); window->swapBuffers(); GET_GL_ERROR(); } // end main loop // destroy scene graph MinSG::destroy(root.get()); root = nullptr; // all is well ;) std::cout << "Exited cleanly\n"; //system("pause"); return EXIT_SUCCESS; }
int main(int /*argc*/, char */*argv*/[]) { Util::init(); Util::UI::Window::Properties properties; properties.positioned = true; properties.posX = 100; properties.posY = 100; properties.clientAreaWidth = 1024; properties.clientAreaHeight = 768; properties.title = "GUI Textfield and Buttons"; properties.compatibilityProfile = true; auto window = Util::UI::createWindow(properties); Util::UI::EventContext eventContext; eventContext.getEventQueue().registerEventGenerator(std::bind(&Util::UI::Window::fetchEvents, window.get())); GUI::GUI_Manager guiManager(&eventContext); guiManager.setWindow(window.get()); Util::Reference<GUI::Window> guiWin = guiManager.createWindow(Geometry::Rect_f(10, 10, 200, 200), "Window"); Util::Reference<GUI::Textfield> guiText = guiManager.createTextfield("Text"); guiText->setRect(Geometry::Rect_f(0, 0, 40, 20)); guiWin->addContent(guiText.get()); Util::Reference<GUI::Button> guiButton = guiManager.createButton("Clear"); guiButton->setActionListener( [&guiText](GUI::Component *, const Util::StringIdentifier &) { guiText->setText(""); return true; }); guiButton->setRect(Geometry::Rect_f(0, 25, 40, 20)); guiWin->addContent(guiButton.get()); bool done = false; while(!done) { eventContext.getEventQueue().process(); while(eventContext.getEventQueue().getNumEventsAvailable() > 0) { auto event = eventContext.getEventQueue().popEvent(); if(event.type == Util::UI::EVENT_QUIT || (event.type == Util::UI::EVENT_KEYBOARD && event.keyboard.pressed && event.keyboard.key == Util::UI::KEY_ESCAPE)) { done = true; } else { guiManager.handleEvent(event); } } guiManager.display(); window->swapBuffers(); } return EXIT_SUCCESS; }