Reflector::Reflector(Object3D* parent, SceneGraph::DrawableGroup3D* group): Object3D(parent), SceneGraph::Drawable3D(*this, group) { CubeMapResourceManager& resourceManager = CubeMapResourceManager::instance(); /* Sphere mesh */ if(!(_sphere = resourceManager.get<GL::Mesh>("sphere"))) { Trade::MeshData3D sphereData = Primitives::uvSphereSolid(16, 32, Primitives::UVSphereTextureCoords::Generate); GL::Buffer* buffer = new GL::Buffer; buffer->setData(MeshTools::interleave(sphereData.positions(0), sphereData.textureCoords2D(0)), GL::BufferUsage::StaticDraw); Containers::Array<char> indexData; MeshIndexType indexType; UnsignedInt indexStart, indexEnd; std::tie(indexData, indexType, indexStart, indexEnd) = MeshTools::compressIndices(sphereData.indices()); GL::Buffer* indexBuffer = new GL::Buffer; indexBuffer->setData(indexData, GL::BufferUsage::StaticDraw); GL::Mesh* mesh = new GL::Mesh; mesh->setPrimitive(sphereData.primitive()) .setCount(sphereData.indices().size()) .addVertexBuffer(*buffer, 0, ReflectorShader::Position{}, ReflectorShader::TextureCoords{}) .setIndexBuffer(*indexBuffer, 0, indexType, indexStart, indexEnd); resourceManager.set("sphere-buffer", buffer, ResourceDataState::Final, ResourcePolicy::Resident) .set("sphere-index-buffer", indexBuffer, ResourceDataState::Final, ResourcePolicy::Resident) .set(_sphere.key(), mesh, ResourceDataState::Final, ResourcePolicy::Resident); } /* Tarnish texture */ if(!(_tarnishTexture = resourceManager.get<GL::Texture2D>("tarnish-texture"))) { Resource<Trade::AbstractImporter> importer = resourceManager.get<Trade::AbstractImporter>("jpeg-importer"); Utility::Resource rs("data"); importer->openData(rs.getRaw("tarnish.jpg")); Containers::Optional<Trade::ImageData2D> image = importer->image2D(0); CORRADE_INTERNAL_ASSERT(image); auto texture = new GL::Texture2D; texture->setWrapping(GL::SamplerWrapping::ClampToEdge) .setMagnificationFilter(GL::SamplerFilter::Linear) .setMinificationFilter(GL::SamplerFilter::Linear, GL::SamplerMipmap::Linear) .setStorage(Math::log2(image->size().min())+1, GL::TextureFormat::RGB8, image->size()) .setSubImage(0, {}, *image) .generateMipmap(); resourceManager.set<GL::Texture2D>(_tarnishTexture.key(), texture, ResourceDataState::Final, ResourcePolicy::Resident); } /* Reflector shader */ if(!(_shader = resourceManager.get<GL::AbstractShaderProgram, ReflectorShader>("reflector-shader"))) resourceManager.set<GL::AbstractShaderProgram>(_shader.key(), new ReflectorShader, ResourceDataState::Final, ResourcePolicy::Resident); /* Texture (created in CubeMap class) */ _texture = resourceManager.get<GL::CubeMapTexture>("texture"); }
void CylinderTest::wireframe() { Trade::MeshData3D cylinder = Cylinder::wireframe(2, 8, 0.5f); CORRADE_COMPARE_AS(cylinder.positions(0), (std::vector<Vector3>{ {0.0f, -0.5f, 1.0f}, {1.0f, -0.5f, 0.0f}, {0.0f, -0.5f, -1.0f}, {-1.0f, -0.5f, 0.0f}, {0.707107f, -0.5f, 0.707107f}, {0.707107f, -0.5f, -0.707107f}, {-0.707107f, -0.5f, -0.707107f}, {-0.707107f, -0.5f, 0.707107f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f}, {0.707107f, 0.0f, 0.707107f}, {0.707107f, 0.0f, -0.707107f}, {-0.707107f, 0.0f, -0.707107f}, {-0.707107f, 0.0f, 0.707107f}, {0.0f, 0.5f, 1.0f}, {1.0f, 0.5f, 0.0f}, {0.0f, 0.5f, -1.0f}, {-1.0f, 0.5f, 0.0f}, {0.707107f, 0.5f, 0.707107f}, {0.707107f, 0.5f, -0.707107f}, {-0.707107f, 0.5f, -0.707107f}, {-0.707107f, 0.5f, 0.707107f} }), TestSuite::Compare::Container); CORRADE_COMPARE(cylinder.normalArrayCount(), 0); CORRADE_COMPARE_AS(cylinder.indices(), (std::vector<UnsignedInt>{ 0, 4, 1, 5, 2, 6, 3, 7, 4, 1, 5, 2, 6, 3, 7, 0, 0, 8, 1, 9, 2, 10, 3, 11, 8, 12, 9, 13, 10, 14, 11, 15, 12, 9, 13, 10, 14, 11, 15, 8, 8, 16, 9, 17, 10, 18, 11, 19, 16, 20, 17, 21, 18, 22, 19, 23, 20, 17, 21, 18, 22, 19, 23, 16 }), TestSuite::Compare::Container); }
void UVSphereTest::withTextureCoords() { Trade::MeshData3D sphere = UVSphere::solid(3, 3, UVSphere::TextureCoords::Generate); CORRADE_COMPARE_AS(*sphere.positions(0), (std::vector<Vector3>{ {0.0f, -1.0f, 0.0f}, {0.0f, -0.5f, 0.866025f}, {0.75f, -0.5f, -0.433013f}, {-0.75f, -0.5f, -0.433013f}, {0.0f, -0.5f, 0.866025f}, {0.0f, 0.5f, 0.866025f}, {0.75f, 0.5f, -0.433013f}, {-0.75f, 0.5f, -0.433013f}, {0.0f, 0.5f, 0.866025f}, {0.0f, 1.0f, 0.0f} }), TestSuite::Compare::Container); CORRADE_COMPARE_AS(*sphere.textureCoords2D(0), (std::vector<Vector2>{ {0.5f, 0.0f}, {0.0f, 0.333333f}, {0.333333f, 0.333333f}, {0.666667f, 0.333333f}, {1.0f, 0.333333f}, {0.0f, 0.666667f}, {0.333333f, 0.666667f}, {0.666667f, 0.666667f}, {1.0f, 0.666667f}, {0.5f, 1.0f} }), TestSuite::Compare::Container); CORRADE_COMPARE_AS(*sphere.indices(), (std::vector<UnsignedInt>{ 0, 2, 1, 0, 3, 2, 0, 4, 3, 1, 2, 6, 1, 6, 5, 2, 3, 7, 2, 7, 6, 3, 4, 8, 3, 8, 7, 5, 6, 9, 6, 7, 9, 7, 8, 9 }), TestSuite::Compare::Container); }
void UVSphereTest::wireframe() { Trade::MeshData3D sphere = UVSphere::wireframe(4, 8); CORRADE_COMPARE_AS(sphere.positions(0), (std::vector<Vector3>{ {0.0f, -1.0f, 0.0f}, {0.0f, -0.707107f, 0.707107f}, {0.707107f, -0.707107f, 0.0f}, {0.0f, -0.707107f, -0.707107f}, {-0.707107f, -0.707107f, 0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f}, {0.707107f, 0.0f, 0.707107f}, {0.707107f, 0.0f, -0.707107f}, {-0.707107f, 0.0f, -0.707107f}, {-0.707107f, 0.0f, 0.707107f}, {0.0f, 0.707107f, 0.707107f}, {0.707107f, 0.707107f, 0.0f}, {0.0f, 0.707107f, -0.707107f}, {-0.707107f, 0.707107f, 0.0f}, {0.0f, 1.0f, 0.0f} }), TestSuite::Compare::Container); CORRADE_COMPARE(sphere.normalArrayCount(), 0); CORRADE_COMPARE_AS(sphere.indices(), (std::vector<UnsignedInt>{ 0, 1, 0, 2, 0, 3, 0, 4, 1, 5, 2, 6, 3, 7, 4, 8, 5, 9, 6, 10, 7, 11, 8, 12, 9, 6, 10, 7, 11, 8, 12, 5, 5, 13, 6, 14, 7, 15, 8, 16, 13, 17, 14, 17, 15, 17, 16, 17 }), TestSuite::Compare::Container); }
PrimitivesExample::PrimitivesExample(const Arguments& arguments): Platform::Application{arguments, Configuration{}.setTitle("Magnum Primitives Example")} { GL::Renderer::enable(GL::Renderer::Feature::DepthTest); GL::Renderer::enable(GL::Renderer::Feature::FaceCulling); const Trade::MeshData3D cube = Primitives::cubeSolid(); _vertexBuffer.setData(MeshTools::interleave(cube.positions(0), cube.normals(0))); Containers::Array<char> indexData; MeshIndexType indexType; UnsignedInt indexStart, indexEnd; std::tie(indexData, indexType, indexStart, indexEnd) = MeshTools::compressIndices(cube.indices()); _indexBuffer.setData(indexData); _mesh.setPrimitive(cube.primitive()) .setCount(cube.indices().size()) .addVertexBuffer(_vertexBuffer, 0, Shaders::Phong::Position{}, Shaders::Phong::Normal{}) .setIndexBuffer(_indexBuffer, 0, indexType, indexStart, indexEnd); _transformation = Matrix4::rotationX(30.0_degf)*Matrix4::rotationY(40.0_degf); _projection = Matrix4::perspectiveProjection( 35.0_degf, Vector2{windowSize()}.aspectRatio(), 0.01f, 100.0f)* Matrix4::translation(Vector3::zAxis(-10.0f)); _color = Color3::fromHsv({35.0_degf, 1.0f, 1.0f}); }
void UVSphereTest::withoutTextureCoords() { Trade::MeshData3D sphere = UVSphere::solid(3, 3); CORRADE_COMPARE_AS(*sphere.positions(0), (std::vector<Vector3>{ {0.0f, -1.0f, 0.0f}, {0.0f, -0.5f, 0.866025f}, {0.75f, -0.5f, -0.433013f}, {-0.75f, -0.5f, -0.433013f}, {0, 0.5f, 0.866025f}, {0.75f, 0.5f, -0.433013f}, {-0.75f, 0.5f, -0.433013f}, {0.0f, 1.0f, 0.0f} }), TestSuite::Compare::Container); CORRADE_COMPARE_AS(*sphere.normals(0), (std::vector<Vector3>{ {0.0f, -1.0f, 0.0f}, {0.0f, -0.5f, 0.866025f}, {0.75f, -0.5f, -0.433013f}, {-0.75f, -0.5f, -0.433013f}, {0, 0.5f, 0.866025f}, {0.75f, 0.5f, -0.433013f}, {-0.75f, 0.5f, -0.433013f}, {0.0f, 1.0f, 0.0f} }), TestSuite::Compare::Container); CORRADE_COMPARE_AS(*sphere.indices(), (std::vector<UnsignedInt>{ 0, 2, 1, 0, 3, 2, 0, 1, 3, 1, 2, 5, 1, 5, 4, 2, 3, 6, 2, 6, 5, 3, 1, 4, 3, 4, 6, 4, 5, 7, 5, 6, 7, 6, 4, 7 }), TestSuite::Compare::Container); }
void CylinderTest::withoutAnything() { Trade::MeshData3D cylinder = Cylinder::solid(2, 3, 3.0f); CORRADE_COMPARE_AS(*cylinder.positions(0), (std::vector<Vector3>{ {0.0f, -1.5f, 1.0f}, {0.866025f, -1.5f, -0.5f}, {-0.866025f, -1.5f, -0.5f}, {0.0f, 0.0f, 1.0f}, {0.866025f, 0.0f, -0.5f}, {-0.866025f, 0.0f, -0.5f}, {0.0f, 1.5f, 1.0f}, {0.866025f, 1.5f, -0.5f}, {-0.866025f, 1.5f, -0.5f} }), Container); CORRADE_COMPARE_AS(*cylinder.normals(0), (std::vector<Vector3>{ {0.0f, 0.0f, 1.0f}, {0.866025f, 0.0f, -0.5f}, {-0.866025f, 0.0f, -0.5f}, {0.0f, 0.0f, 1.0f}, {0.866025f, 0.0f, -0.5f}, {-0.866025f, 0.0f, -0.5f}, {0.0f, 0.0f, 1.0f}, {0.866025f, 0.0f, -0.5f}, {-0.866025f, 0.0f, -0.5f} }), Container); CORRADE_COMPARE_AS(*cylinder.indices(), (std::vector<UnsignedInt>{ 0, 1, 4, 0, 4, 3, 1, 2, 5, 1, 5, 4, 2, 0, 3, 2, 3, 5, 3, 4, 7, 3, 7, 6, 4, 5, 8, 4, 8, 7, 5, 3, 6, 5, 6, 8 }), Container); }
void CylinderTest::withTextureCoordsAndCaps() { Trade::MeshData3D cylinder = Cylinder::solid(2, 3, 3.0f, Cylinder::Flag::GenerateTextureCoords|Cylinder::Flag::CapEnds); CORRADE_COMPARE_AS(*cylinder.positions(0), (std::vector<Vector3>{ {0.0f, -1.5f, 0.0f}, {0.0f, -1.5f, 1.0f}, {0.866025f, -1.5f, -0.5f}, {-0.866025f, -1.5f, -0.5f}, {0.0f, -1.5f, 1.0f}, {0.0f, -1.5f, 1.0f}, {0.866025f, -1.5f, -0.5f}, {-0.866025f, -1.5f, -0.5f}, {0.0f, -1.5f, 1.0f}, {0.0f, 0.0f, 1.0f}, {0.866025f, 0.0f, -0.5f}, {-0.866025f, 0.0f, -0.5f}, {0.0f, 0.0f, 1.0f}, {0.0f, 1.5f, 1.0f}, {0.866025f, 1.5f, -0.5f}, {-0.866025f, 1.5f, -0.5f}, {0.0f, 1.5f, 1.0f}, {0.0f, 1.5f, 1.0f}, {0.866025f, 1.5f, -0.5f}, {-0.866025f, 1.5f, -0.5f}, {0.0f, 1.5f, 1.0f}, {0.0f, 1.5f, 0.0f} }), Container); CORRADE_COMPARE_AS(*cylinder.normals(0), (std::vector<Vector3>{ {0.0f, -1.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, {0.866025f, 0.0f, -0.5f}, {-0.866025f, 0.0f, -0.5f}, {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 1.0f}, {0.866025f, 0.0f, -0.5f}, {-0.866025f, 0.0f, -0.5f}, {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 1.0f}, {0.866025f, 0.0f, -0.5f}, {-0.866025f, 0.0f, -0.5f}, {0.0f, 0.0f, 1.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, }), Container); CORRADE_COMPARE_AS(*cylinder.textureCoords2D(0), (std::vector<Vector2>{ {0.5f, 0.0f}, {0.0f, 0.2f}, {0.333333f, 0.2f}, {0.666667f, 0.2f}, {1.0f, 0.2f}, {0.0f, 0.2f}, {0.333333f, 0.2f}, {0.666667f, 0.2f}, {1.0f, 0.2f}, {0.0f, 0.5f}, {0.333333f, 0.5f}, {0.666667f, 0.5f}, {1.0f, 0.5f}, {0.0f, 0.8f}, {0.333333f, 0.8f}, {0.666667f, 0.8f}, {1.0f, 0.8f}, {0.0f, 0.8f}, {0.333333f, 0.8f}, {0.666667f, 0.8f}, {1.0f, 0.8f}, {0.5f, 1.0f} }), Container); CORRADE_COMPARE_AS(*cylinder.indices(), (std::vector<UnsignedInt>{ 0, 2, 1, 0, 3, 2, 0, 4, 3, 1, 2, 6, 1, 6, 5, 2, 3, 7, 2, 7, 6, 3, 4, 8, 3, 8, 7, 5, 6, 10, 5, 10, 9, 6, 7, 11, 6, 11, 10, 7, 8, 12, 7, 12, 11, 17, 18, 21, 18, 19, 21, 19, 20, 21 }), Container); }
CubeMap::CubeMap(const std::string& prefix, Object3D* parent, SceneGraph::DrawableGroup3D<>* group): Object3D(parent), SceneGraph::Drawable3D<>(this, group) { CubeMapResourceManager* resourceManager = CubeMapResourceManager::instance(); /* Cube mesh */ if(!(cube = resourceManager->get<Mesh>("cube"))) { Mesh* mesh = new Mesh; Buffer* buffer = new Buffer; Buffer* indexBuffer = new Buffer; Trade::MeshData3D cubeData = Primitives::Cube::solid(); MeshTools::flipFaceWinding(*cubeData.indices()); MeshTools::compressIndices(mesh, indexBuffer, Buffer::Usage::StaticDraw, *cubeData.indices()); MeshTools::interleave(mesh, buffer, Buffer::Usage::StaticDraw, *cubeData.positions(0)); mesh->setPrimitive(cubeData.primitive()) ->addVertexBuffer(buffer, 0, CubeMapShader::Position()); resourceManager->set("cube-buffer", buffer, ResourceDataState::Final, ResourcePolicy::Resident); resourceManager->set("cube-index-buffer", indexBuffer, ResourceDataState::Final, ResourcePolicy::Resident); resourceManager->set(cube.key(), mesh, ResourceDataState::Final, ResourcePolicy::Resident); } /* Cube map texture */ if(!(texture = resourceManager->get<CubeMapTexture>("texture"))) { CubeMapTexture* cubeMap = new CubeMapTexture; cubeMap->setWrapping(CubeMapTexture::Wrapping::ClampToEdge) ->setMagnificationFilter(CubeMapTexture::Filter::Linear) ->setMinificationFilter(CubeMapTexture::Filter::Linear, CubeMapTexture::Mipmap::Linear); Resource<Trade::AbstractImporter> importer = resourceManager->get<Trade::AbstractImporter>("tga-importer"); /* Configure texture storage using size of first image */ importer->openFile(prefix + "+x.tga"); Trade::ImageData2D* image = importer->image2D(0); Vector2i size = image->size(); cubeMap->setStorage(Math::log2(size.min())+1, CubeMapTexture::InternalFormat::RGB8, size); cubeMap->setSubImage(CubeMapTexture::PositiveX, 0, {}, image); delete image; importer->openFile(prefix + "-x.tga"); image = importer->image2D(0); cubeMap->setSubImage(CubeMapTexture::NegativeX, 0, {}, image); delete image; importer->openFile(prefix + "+y.tga"); image = importer->image2D(0); cubeMap->setSubImage(CubeMapTexture::PositiveY, 0, {}, image); delete image; importer->openFile(prefix + "-y.tga"); image = importer->image2D(0); cubeMap->setSubImage(CubeMapTexture::NegativeY, 0, {}, image); delete image; importer->openFile(prefix + "+z.tga"); image = importer->image2D(0); cubeMap->setSubImage(CubeMapTexture::PositiveZ, 0, {}, image); delete image; importer->openFile(prefix + "-z.tga"); image = importer->image2D(0); cubeMap->setSubImage(CubeMapTexture::NegativeZ, 0, {}, image); delete image; cubeMap->generateMipmap(); resourceManager->set(texture.key(), cubeMap, ResourceDataState::Final, ResourcePolicy::Manual); } /* Shader */ if(!(shader = resourceManager->get<AbstractShaderProgram, CubeMapShader>("shader"))) resourceManager->set<AbstractShaderProgram>(shader.key(), new CubeMapShader, ResourceDataState::Final, ResourcePolicy::Manual); }
MotionBlurExample::MotionBlurExample(const Arguments& arguments): Platform::Application(arguments, Configuration().setTitle("Magnum Motion Blur Example")) { (cameraObject = new Object3D(&scene)) ->translate(Vector3::zAxis(3.0f)); (camera = new MotionBlurCamera(*cameraObject)) ->setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend) .setProjectionMatrix(Matrix4::perspectiveProjection(Deg(35.0f), 1.0f, 0.001f, 100)) .setViewport(GL::defaultFramebuffer.viewport().size()); GL::Renderer::setClearColor({0.1f, 0.1f, 0.1f}); GL::Renderer::enable(GL::Renderer::Feature::DepthTest); GL::Renderer::enable(GL::Renderer::Feature::FaceCulling); const Trade::MeshData3D data = Primitives::icosphereSolid(3); buffer.setData(MeshTools::interleave(data.positions(0), data.normals(0)), GL::BufferUsage::StaticDraw); Containers::Array<char> indexData; MeshIndexType indexType; UnsignedInt indexStart, indexEnd; std::tie(indexData, indexType, indexStart, indexEnd) = MeshTools::compressIndices(data.indices()); indexBuffer.setData(indexData, GL::BufferUsage::StaticDraw); mesh.setPrimitive(data.primitive()) .setCount(data.indices().size()) .addVertexBuffer(buffer, 0, Shaders::Phong::Position{}, Shaders::Phong::Normal{}) .setIndexBuffer(indexBuffer, 0, indexType, indexStart, indexEnd); /* Add spheres to the scene */ new Icosphere(&mesh, &shader, {1.0f, 1.0f, 0.0f}, &scene, &drawables); spheres[0] = new Object3D(&scene); (new Icosphere(&mesh, &shader, {1.0f, 0.0f, 0.0f}, spheres[0], &drawables)) ->translate(Vector3::yAxis(0.25f)); (new Icosphere(&mesh, &shader, {1.0f, 0.0f, 0.0f}, spheres[0], &drawables)) ->translate(Vector3::yAxis(0.25f)) .rotateZ(Deg(120.0f)); (new Icosphere(&mesh, &shader, {1.0f, 0.0f, 0.0f}, spheres[0], &drawables)) ->translate(Vector3::yAxis(0.25f)) .rotateZ(Deg(240.0f)); spheres[1] = new Object3D(&scene); (new Icosphere(&mesh, &shader, {0.0f, 1.0f, 0.0f}, spheres[1], &drawables)) ->translate(Vector3::yAxis(0.50f)); (new Icosphere(&mesh, &shader, {0.0f, 1.0f, 0.0f}, spheres[1], &drawables)) ->translate(Vector3::yAxis(0.50f)) .rotateZ(Deg(120.0f)); (new Icosphere(&mesh, &shader, {0.0f, 1.0f, 0.0f}, spheres[1], &drawables)) ->translate(Vector3::yAxis(0.50f)) .rotateZ(Deg(240.0f)); spheres[2] = new Object3D(&scene); (new Icosphere(&mesh, &shader, {0.0f, 0.0f, 1.0f}, spheres[2], &drawables)) ->translate(Vector3::yAxis(0.75f)); (new Icosphere(&mesh, &shader, {0.0f, 0.0f, 1.0f}, spheres[2], &drawables)) ->translate(Vector3::yAxis(0.75f)) .rotateZ(Deg(120.0f)); (new Icosphere(&mesh, &shader, {0.0f, 0.0f, 1.0f}, spheres[2], &drawables)) ->translate(Vector3::yAxis(0.75f)) .rotateZ(Deg(240.0f)); setSwapInterval(16); setMinimalLoopPeriod(40); }
void CapsuleTest::solid3DWithoutTextureCoords() { Trade::MeshData3D capsule = Capsule3D::solid(2, 4, 3, 0.5f); CORRADE_COMPARE_AS(capsule.positions(0), (std::vector<Vector3>{ {0.0f, -1.5f, 0.0f}, {0.0f, -1.20711f, 0.707107f}, {0.612372f, -1.20711f, -0.353553f}, {-0.612373f, -1.20711f, -0.353553f}, {0.0f, -0.5f, 1.0f}, {0.866025f, -0.5f, -0.5f}, {-0.866025f, -0.5f, -0.5f}, {0.0f, -0.25f, 1.0f}, {0.866025f, -0.25f, -0.5f}, {-0.866025f, -0.25f, -0.5f}, {0.0f, 0.0f, 1.0f}, {0.866025f, 0.0f, -0.5f}, {-0.866025f, 0.0f, -0.5f}, {0.0f, 0.25f, 1.0f}, {0.866025f, 0.25f, -0.5f}, {-0.866025f, 0.25f, -0.5f}, {0.0f, 0.5f, 1.0f}, {0.866025f, 0.5f, -0.5f}, {-0.866025f, 0.5f, -0.5f}, {0.0f, 1.20711f, 0.707107f}, {0.612372f, 1.20711f, -0.353553f}, {-0.612372f, 1.20711f, -0.353553f}, {0.0f, 1.5f, 0.0f} }), TestSuite::Compare::Container); CORRADE_COMPARE_AS(capsule.normals(0), (std::vector<Vector3>{ {0.0f, -1.0f, 0.0f}, {0.0f, -0.707107f, 0.707107f}, {0.612372f, -0.707107f, -0.353553f}, {-0.612373f, -0.707107f, -0.353553f}, {0.0f, 0.0f, 1.0f}, {0.866025f, 0.0f, -0.5f}, {-0.866025f, 0.0f, -0.5f}, {0.0f, 0.0f, 1.0f}, {0.866025f, 0.0f, -0.5f}, {-0.866025f, 0.0f, -0.5f}, {0.0f, 0.0f, 1.0f}, {0.866025f, 0.0f, -0.5f}, {-0.866025f, 0.0f, -0.5f}, {0.0f, 0.0f, 1.0f}, {0.866025f, 0.0f, -0.5f}, {-0.866025f, 0.0f, -0.5f}, {0.0f, 0.0f, 1.0f}, {0.866025f, 0.0f, -0.5f}, {-0.866025f, 0.0f, -0.5f}, {0.0f, 0.707107f, 0.707107f}, {0.612372f, 0.707107f, -0.353553f}, {-0.612372f, 0.707107f, -0.353553f}, {0.0f, 1.0f, 0.0f} }), TestSuite::Compare::Container); CORRADE_COMPARE_AS(capsule.indices(), (std::vector<UnsignedInt>{ 0, 2, 1, 0, 3, 2, 0, 1, 3, 1, 2, 5, 1, 5, 4, 2, 3, 6, 2, 6, 5, 3, 1, 4, 3, 4, 6, 4, 5, 8, 4, 8, 7, 5, 6, 9, 5, 9, 8, 6, 4, 7, 6, 7, 9, 7, 8, 11, 7, 11, 10, 8, 9, 12, 8, 12, 11, 9, 7, 10, 9, 10, 12, 10, 11, 14, 10, 14, 13, 11, 12, 15, 11, 15, 14, 12, 10, 13, 12, 13, 15, 13, 14, 17, 13, 17, 16, 14, 15, 18, 14, 18, 17, 15, 13, 16, 15, 16, 18, 16, 17, 20, 16, 20, 19, 17, 18, 21, 17, 21, 20, 18, 16, 19, 18, 19, 21, 19, 20, 22, 20, 21, 22, 21, 19, 22 }), TestSuite::Compare::Container); }
void CapsuleTest::wireframe3D() { Trade::MeshData3D capsule = Capsule3D::wireframe(2, 2, 8, 0.5f); CORRADE_COMPARE_AS(capsule.positions(0), (std::vector<Vector3>{ {0.0f, -1.5f, 0.0f}, {0.0f, -1.20711f, 0.707107f}, {0.707107f, -1.20711f, 0.0f}, {0.0f, -1.20711f, -0.707107f}, {-0.707107f, -1.20711f, 0.0f}, {0.0f, -0.5f, 1.0f}, {1.0f, -0.5f, 0.0f}, {0.0f, -0.5f, -1.0f}, {-1.0f, -0.5f, 0.0f}, {0.707107f, -0.5f, 0.707107f}, {0.707107f, -0.5f, -0.707107f}, {-0.707107f, -0.5f, -0.707107f}, {-0.707107f, -0.5f, 0.707107f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f}, {0.707107f, 0.0f, 0.707107f}, {0.707107f, 0.0f, -0.707107f}, {-0.707107f, 0.0f, -0.707107f}, {-0.707107f, 0.0f, 0.707107f}, {0.0f, 0.5f, 1.0f}, {1.0f, 0.5f, 0.0f}, {0.0f, 0.5f, -1.0f}, {-1.0f, 0.5f, 0.0f}, {0.707107f, 0.5f, 0.707107f}, {0.707107f, 0.5f, -0.707107f}, {-0.707107f, 0.5f, -0.707107f}, {-0.707107f, 0.5f, 0.707107f}, {0.0f, 1.20711f, 0.707107f}, {0.707107f, 1.20711f, 0.0f}, {0.0f, 1.20711f, -0.707107f}, {-0.707107f, 1.20711f, 0.0f}, {0.0f, 1.5f, 0.0f} }), TestSuite::Compare::Container); CORRADE_COMPARE(capsule.normalArrayCount(), 0); CORRADE_COMPARE_AS(capsule.indices(), (std::vector<UnsignedInt>{ 0, 1, 0, 2, 0, 3, 0, 4, 1, 5, 2, 6, 3, 7, 4, 8, 5, 9, 6, 10, 7, 11, 8, 12, 9, 6, 10, 7, 11, 8, 12, 5, 5, 13, 6, 14, 7, 15, 8, 16, 13, 17, 14, 18, 15, 19, 16, 20, 17, 14, 18, 15, 19, 16, 20, 13, 13, 21, 14, 22, 15, 23, 16, 24, 21, 25, 22, 26, 23, 27, 24, 28, 25, 22, 26, 23, 27, 24, 28, 21, 21, 29, 22, 30, 23, 31, 24, 32, 29, 33, 30, 33, 31, 33, 32, 33 }), TestSuite::Compare::Container); }
void CapsuleTest::solid3DWithTextureCoords() { Trade::MeshData3D capsule = Capsule3D::solid(2, 2, 3, 0.5f, Capsule3D::TextureCoords::Generate); CORRADE_COMPARE_AS(capsule.positions(0), (std::vector<Vector3>{ {0.0f, -1.5f, 0.0f}, {0.0f, -1.20711f, 0.707107f}, {0.612372f, -1.20711f, -0.353553f}, {-0.612373f, -1.20711f, -0.353553f}, {0.0f, -1.20711f, 0.707107f}, {0.0f, -0.5f, 1.0f}, {0.866025f, -0.5f, -0.5f}, {-0.866025f, -0.5f, -0.5f}, {0.0f, -0.5f, 1.0f}, {0.0f, 0.0f, 1.0f}, {0.866025f, 0.0f, -0.5f}, {-0.866025f, 0.0f, -0.5f}, {0.0f, 0.0f, 1.0f}, {0.0f, 0.5f, 1.0f}, {0.866025f, 0.5f, -0.5f}, {-0.866025f, 0.5f, -0.5f}, {0.0f, 0.5f, 1.0f}, {0.0f, 1.20711f, 0.707107f}, {0.612372f, 1.20711f, -0.353553f}, {-0.612372f, 1.20711f, -0.353553f}, {0.0f, 1.20711f, 0.707107f}, {0.0f, 1.5f, 0.0f} }), TestSuite::Compare::Container); CORRADE_COMPARE_AS(capsule.textureCoords2D(0), (std::vector<Vector2>{ {0.5f, 0.0f}, {0.0f, 0.166667f}, {0.333333f, 0.166667f}, {0.666667f, 0.166667f}, {1.0f, 0.166667f}, {0.0f, 0.333333f}, {0.333333f, 0.333333f}, {0.666667f, 0.333333f}, {1.0f, 0.333333f}, {0.0f, 0.5f}, {0.333333f, 0.5f}, {0.666667f, 0.5f}, {1.0f, 0.5f}, {0.0f, 0.666667f}, {0.333333f, 0.666667f}, {0.666667f, 0.666667f}, {1.0f, 0.666667f}, {0.0f, 0.833333f}, {0.333333f, 0.833333f}, {0.666667f, 0.833333f}, {1.0f, 0.833333f}, {0.5f, 1.0f} }), TestSuite::Compare::Container); CORRADE_COMPARE_AS(capsule.indices(), (std::vector<UnsignedInt>{ 0, 2, 1, 0, 3, 2, 0, 4, 3, 1, 2, 6, 1, 6, 5, 2, 3, 7, 2, 7, 6, 3, 4, 8, 3, 8, 7, 5, 6, 10, 5, 10, 9, 6, 7, 11, 6, 11, 10, 7, 8, 12, 7, 12, 11, 9, 10, 14, 9, 14, 13, 10, 11, 15, 10, 15, 14, 11, 12, 16, 11, 16, 15, 13, 14, 18, 13, 18, 17, 14, 15, 19, 14, 19, 18, 15, 16, 20, 15, 20, 19, 17, 18, 21, 18, 19, 21, 19, 20, 21 }), TestSuite::Compare::Container); }
std::tuple<Mesh, std::unique_ptr<Buffer>, std::unique_ptr<Buffer>> compile(const Trade::MeshData3D& meshData, const BufferUsage usage) { Mesh mesh; mesh.setPrimitive(meshData.primitive()); /* Decide about stride and offsets */ UnsignedInt stride = sizeof(Shaders::Generic3D::Position::Type); const UnsignedInt normalOffset = sizeof(Shaders::Generic3D::Position::Type); UnsignedInt textureCoordsOffset = sizeof(Shaders::Generic3D::Position::Type); if(meshData.hasNormals()) { stride += sizeof(Shaders::Generic3D::Normal::Type); textureCoordsOffset += sizeof(Shaders::Generic3D::Normal::Type); } if(meshData.hasTextureCoords2D()) stride += sizeof(Shaders::Generic3D::TextureCoordinates::Type); /* Create vertex buffer */ std::unique_ptr<Buffer> vertexBuffer{new Buffer{Buffer::TargetHint::Array}}; /* Interleave positions */ Containers::Array<char> data = MeshTools::interleave( meshData.positions(0), stride - sizeof(Shaders::Generic3D::Position::Type)); mesh.addVertexBuffer(*vertexBuffer, 0, Shaders::Generic3D::Position(), stride - sizeof(Shaders::Generic3D::Position::Type)); /* Add also normals, if present */ if(meshData.hasNormals()) { MeshTools::interleaveInto(data, normalOffset, meshData.normals(0), stride - normalOffset - sizeof(Shaders::Generic3D::Normal::Type)); mesh.addVertexBuffer(*vertexBuffer, 0, normalOffset, Shaders::Generic3D::Normal(), stride - normalOffset - sizeof(Shaders::Generic3D::Normal::Type)); } /* Add also texture coordinates, if present */ if(meshData.hasTextureCoords2D()) { MeshTools::interleaveInto(data, textureCoordsOffset, meshData.textureCoords2D(0), stride - textureCoordsOffset - sizeof(Shaders::Generic3D::TextureCoordinates::Type)); mesh.addVertexBuffer(*vertexBuffer, 0, textureCoordsOffset, Shaders::Generic3D::TextureCoordinates(), stride - textureCoordsOffset - sizeof(Shaders::Generic3D::TextureCoordinates::Type)); } /* Fill vertex buffer with interleaved data */ vertexBuffer->setData(data, usage); /* If indexed, fill index buffer and configure indexed mesh */ std::unique_ptr<Buffer> indexBuffer; if(meshData.isIndexed()) { Containers::Array<char> indexData; Mesh::IndexType indexType; UnsignedInt indexStart, indexEnd; std::tie(indexData, indexType, indexStart, indexEnd) = MeshTools::compressIndices(meshData.indices()); indexBuffer.reset(new Buffer{Buffer::TargetHint::ElementArray}); indexBuffer->setData(indexData, usage); mesh.setCount(meshData.indices().size()) .setIndexBuffer(*indexBuffer, 0, indexType, indexStart, indexEnd); /* Else set vertex count */ } else mesh.setCount(meshData.positions(0).size()); return std::make_tuple(std::move(mesh), std::move(vertexBuffer), std::move(indexBuffer)); }
CubeMap::CubeMap(const std::string& prefix, Object3D* parent, SceneGraph::DrawableGroup3D* group): Object3D(parent), SceneGraph::Drawable3D(*this, group) { CubeMapResourceManager& resourceManager = CubeMapResourceManager::instance(); /* Cube mesh */ if(!(_cube = resourceManager.get<GL::Mesh>("cube"))) { Trade::MeshData3D cubeData = Primitives::cubeSolid(); MeshTools::flipFaceWinding(cubeData.indices()); GL::Buffer* buffer = new GL::Buffer; buffer->setData(MeshTools::interleave(cubeData.positions(0)), GL::BufferUsage::StaticDraw); Containers::Array<char> indexData; MeshIndexType indexType; UnsignedInt indexStart, indexEnd; std::tie(indexData, indexType, indexStart, indexEnd) = MeshTools::compressIndices(cubeData.indices()); GL::Buffer* indexBuffer = new GL::Buffer; indexBuffer->setData(indexData, GL::BufferUsage::StaticDraw); GL::Mesh* mesh = new GL::Mesh; mesh->setPrimitive(cubeData.primitive()) .setCount(cubeData.indices().size()) .addVertexBuffer(*buffer, 0, CubeMapShader::Position{}) .setIndexBuffer(*indexBuffer, 0, indexType, indexStart, indexEnd); resourceManager.set("cube-buffer", buffer, ResourceDataState::Final, ResourcePolicy::Resident) .set("cube-index-buffer", indexBuffer, ResourceDataState::Final, ResourcePolicy::Resident) .set(_cube.key(), mesh, ResourceDataState::Final, ResourcePolicy::Resident); } /* Cube map texture */ if(!(_texture = resourceManager.get<GL::CubeMapTexture>("texture"))) { GL::CubeMapTexture* cubeMap = new GL::CubeMapTexture; cubeMap->setWrapping(GL::SamplerWrapping::ClampToEdge) .setMagnificationFilter(GL::SamplerFilter::Linear) .setMinificationFilter(GL::SamplerFilter::Linear, GL::SamplerMipmap::Linear); Resource<Trade::AbstractImporter> importer = resourceManager.get<Trade::AbstractImporter>("jpeg-importer"); /* Configure texture storage using size of first image */ importer->openFile(prefix + "+x.jpg"); Containers::Optional<Trade::ImageData2D> image = importer->image2D(0); CORRADE_INTERNAL_ASSERT(image); Vector2i size = image->size(); cubeMap->setStorage(Math::log2(size.min())+1, GL::TextureFormat::RGB8, size) .setSubImage(GL::CubeMapCoordinate::PositiveX, 0, {}, *image); importer->openFile(prefix + "-x.jpg"); CORRADE_INTERNAL_ASSERT_OUTPUT(image = importer->image2D(0)); cubeMap->setSubImage(GL::CubeMapCoordinate::NegativeX, 0, {}, *image); importer->openFile(prefix + "+y.jpg"); CORRADE_INTERNAL_ASSERT_OUTPUT(image = importer->image2D(0)); cubeMap->setSubImage(GL::CubeMapCoordinate::PositiveY, 0, {}, *image); importer->openFile(prefix + "-y.jpg"); CORRADE_INTERNAL_ASSERT_OUTPUT(image = importer->image2D(0)); cubeMap->setSubImage(GL::CubeMapCoordinate::NegativeY, 0, {}, *image); importer->openFile(prefix + "+z.jpg"); CORRADE_INTERNAL_ASSERT_OUTPUT(image = importer->image2D(0)); cubeMap->setSubImage(GL::CubeMapCoordinate::PositiveZ, 0, {}, *image); importer->openFile(prefix + "-z.jpg"); CORRADE_INTERNAL_ASSERT_OUTPUT(image = importer->image2D(0)); cubeMap->setSubImage(GL::CubeMapCoordinate::NegativeZ, 0, {}, *image); cubeMap->generateMipmap(); resourceManager.set(_texture.key(), cubeMap, ResourceDataState::Final, ResourcePolicy::Manual); } /* Shader */ if(!(_shader = resourceManager.get<GL::AbstractShaderProgram, CubeMapShader>("shader"))) resourceManager.set<GL::AbstractShaderProgram>(_shader.key(), new CubeMapShader, ResourceDataState::Final, ResourcePolicy::Manual); }