//------------------------------------------------------------------------------ //## DepthTest, DepthWrite TEST_F(Test_Visual_VisualComponent, DepthTest) { auto texture1 = Texture2D::create(32, 32); auto texture2 = Texture2D::create(32, 32); texture1->clear(Color::Red); texture2->clear(Color::Green); //* [ ] default (enabled depth test and write) { auto sprite1 = Sprite::create(texture1, 5, 5); sprite1->setPosition(0, 0, 0); sprite1->setEulerAngles(0, -Math::PI / 4, 0); sprite1->setShadingModel(ShadingModel::UnLighting); auto sprite2 = Sprite::create(texture2, 5, 5); sprite2->setPosition(0, 0, 0); sprite2->setEulerAngles(0, Math::PI / 4, 0); sprite2->setShadingModel(ShadingModel::UnLighting); TestEnv::updateFrame(); ASSERT_SCREEN(LN_ASSETFILE("Visual/Result/Test_Visual_VisualComponent-DepthTest-1.png")); LN_TEST_CLEAN_SCENE; } //* [ ] disable depth test { auto sprite1 = Sprite::create(texture1, 4, 4); sprite1->setPosition(0, 0, 0); sprite1->setEulerAngles(0, -Math::PI / 4, 0); sprite1->setShadingModel(ShadingModel::UnLighting); auto sprite2 = Sprite::create(texture2, 4, 4); sprite2->setPosition(0, 0, 0); sprite2->setEulerAngles(0, Math::PI / 4, 0); sprite2->setShadingModel(ShadingModel::UnLighting); sprite2->setDepthTestEnabled(false); TestEnv::updateFrame(); ASSERT_SCREEN(LN_ASSETFILE("Visual/Result/Test_Visual_VisualComponent-DepthTest-2.png")); LN_TEST_CLEAN_SCENE; } //* [ ] disable depth write { auto sprite1 = Sprite::create(texture1, 4, 4); sprite1->setPosition(0, 0, 0); sprite1->setEulerAngles(0, -Math::PI / 4, 0); sprite1->setShadingModel(ShadingModel::UnLighting); sprite1->setDepthWriteEnabled(false); auto sprite2 = Sprite::create(texture2, 4, 4); sprite2->setPosition(0, 0, 0); sprite2->setEulerAngles(0, Math::PI / 4, 0); sprite2->setShadingModel(ShadingModel::UnLighting); TestEnv::updateFrame(); ASSERT_SCREEN(LN_ASSETFILE("Visual/Result/Test_Visual_VisualComponent-DepthTest-3.png")); LN_TEST_CLEAN_SCENE; } }
void Vizi3DWorld::drawNext() { // @init load() if ( drawItr.empty() ) { return; } // Наносим на холст сразу всю битовую карту текущего элемента // Чудесный метод предоставляет нам всю необходимую информацию const auto info = *get( drawItr ); // Пробел - всегда отсутствие элемента if (info.signElement != ' ') { // Оформлять будем как стат. геометрию const std::string signInString = std::string( &info.signElement, 1 ); Ogre::StaticGeometry* staticScene = sm->createStaticGeometry( signInString + "::Vizi3DWorld" ); //staticScene->setRegionDimensions( ... ); // Создаём элемент const std::string meshName = info.noteElement.form + ".mesh"; auto e = sm->createEntity( meshName ); // Фикс для прозрачных материалов // @see http://ogre3d.org/forums/viewtopic.php?f=2&t=32172&start=0 e->setRenderQueueGroup( Ogre::RENDER_QUEUE_9 ); const std::string materialName = info.noteElement.material; if ( !materialName.empty() ) { // Заменяем материал по умолчанию const auto material = Ogre::MaterialManager::getSingleton().getByName( materialName ); #ifdef TEST_TRANSPARENT_CELL // @test Добавляем прозрачность всем материалам const auto mt = static_cast< Ogre::Material* >( material.get() ); mt->setSceneBlending( Ogre::SBT_TRANSPARENT_COLOUR ); //mt->setParameter( "set_alpha_rejection", "greater 128" ); mt->setDepthWriteEnabled( false ); mt->setDepthCheckEnabled( true ); #endif e->setMaterial( material ); e->setCastShadows( true ); } // if ( !materialName.empty() ) // Размер области const size_t N = info.bitContent.size().get<0>(); const size_t M = info.bitContent.size().get<1>(); const size_t L = info.bitContent.size().get<2>(); // Позиционируем область в мировом пространстве const float halfN = (float)N / 2.0f; const float halfM = (float)M / 2.0f; const float halfL = (float)L / 2.0f; staticScene->setOrigin( Ogre::Vector3( info.coord.get<0>() * info.scaleWorld - halfN * info.scale, info.coord.get<1>() * info.scaleWorld - halfM * info.scale, info.coord.get<2>() * info.scaleWorld - halfL * info.scale ) ); /* - Заменено на предварительную подготовку образа в load(). См. ниже. // Добавляем элемент в *область*, определяя его расположение благодаря // битовой карте области for (size_t l = 0; l < L; ++l) { for (size_t m = 0; m < M; ++m) { for (size_t n = 0; n < N; ++n) { // 3D-указатель для определения положения элемента const auto c = d::coordInt3d_t( n, m, l ); // Каждый установленный бит - признак наличия элемента в области // @todo optimize Быстрый доступ по 1D-указателю if ( info.bitContent.test( c ) ) { staticScene->addEntity( e, // положение элемента, центрируем блок позже Ogre::Vector3( (float)c.get<0>(), (float)c.get<1>(), (float)c.get<2>() ) * info.scale, Ogre::Quaternion::ZERO, Ogre::Vector3( info.scale ) ); } } // for (size_t n = 0; n < N; ++n) } // for (size_t m = 0; m < M; ++m } // for (size_t l = 0; l < L; ++l) */ // Не все элементы требуют отрисовки // @see prepareVisualBitImage() const auto content = *drawItr.mapElement()->second; const auto& alphaBI = *drawItr.tinyMap()->second.visualContent.alphaTypeBitImage; const auto& solidBI = *drawItr.tinyMap()->second.visualContent.solidTypeBitImage; assert( (alphaBI.raw().size() == solidBI.raw().size()) && "Размеры битовых образов должны совпадать." ); for (size_t l = 0; l < L; ++l) { for (size_t m = 0; m < M; ++m) { for (size_t n = 0; n < N; ++n) { // 3D-указатель для определения положения элемента const auto c = d::coordInt3d_t( n, m, l ); // Каждый установленный бит - признак наличия элемента в области // @todo optimize Быстрый доступ по 1D-указателю if ( content.test( c ) && ( solidBI.test( c ) || alphaBI.test( c ) ) ) { staticScene->addEntity( e, // положение элемента в статическом блоке (блок // центрировали раньше) Ogre::Vector3( ((float)c.get<0>() - (float)halfN), -((float)c.get<1>() - (float)halfM), -((float)c.get<2>() - (float)halfL) ) * info.scale, Ogre::Quaternion::ZERO, #ifdef TEST_VISUAL_CELL Ogre::Vector3( info.scale / 1.80f ) #else Ogre::Vector3( info.scale ) #endif ); } } // for (size_t n = 0; n < N; ++n) } // for (size_t m = 0; m < M; ++m } // for (size_t l = 0; l < L; ++l) // Строим! staticScene->build(); } // if (info.signElement != ' ') // Переводим итератор на след. элемент ++drawItr; }