/* * Read depth. Write diffuse, normal, spec, gloss. Alpha = 1. * Read depth, normal. Write diffuse, spec, gloss. Alpha = 1. * Read everything. Write colour. Alpha < 1. */ void GfxDecal::render (const GfxShaderGlobals &g) { if (!enabled) return; const Ogre::Matrix4 &world = node->_getFullTransform(); // ISSUE RENDER COMMANDS try { const GfxTextureStateMap &mat_texs = material->getTextures(); GfxShader *shader = material->getShader(); // TODO(dcunnin): What if we don't want the dither fade? const GfxGslMaterialEnvironment &mat_env = material->getMaterialEnvironment(); GfxGslMeshEnvironment mesh_env; shader->populateMeshEnv(false, 0, mesh_env); material->getShader()->bindShader( GFX_GSL_PURPOSE_DECAL, mat_env, mesh_env, g, world, nullptr, 0, 1, mat_texs, material->getBindings()); float dist = (world * Ogre::Vector4(1, 1, 1, 0)).xyz().length(); Ogre::Vector3 decal_to_cam = (world * Ogre::Vector4(0, 0, 0, 1)).xyz() - to_ogre(g.camPos); bool inside = decal_to_cam.length() - 0.4 < dist; ogre_rs->_setCullingMode(inside ? Ogre::CULL_ANTICLOCKWISE : Ogre::CULL_CLOCKWISE); // read but don't write depth buffer if (inside) { ogre_rs->_setDepthBufferParams(false, false); } else { ogre_rs->_setDepthBufferParams(true, false, Ogre::CMPF_LESS_EQUAL); } switch (material->getSceneBlend()) { case GFX_MATERIAL_OPAQUE: ogre_rs->_setSceneBlending(Ogre::SBF_ONE, Ogre::SBF_ZERO); break; case GFX_MATERIAL_ALPHA: case GFX_MATERIAL_ALPHA_DEPTH: ogre_rs->_setSceneBlending(Ogre::SBF_ONE, Ogre::SBF_ONE_MINUS_SOURCE_ALPHA); break; } ogre_rs->_setPolygonMode(Ogre::PM_SOLID); ogre_rs->setStencilCheckEnabled(false); ogre_rs->_setDepthBias(0, 0); ogre_rs->_render(box_op); for (unsigned i=0 ; i<mat_texs.size() ; ++i) { ogre_rs->_disableTextureUnit(i); } } catch (const Exception &e) { CERR << "Rendering decals, got: " << e << std::endl; } catch (const Ogre::Exception &e) { CERR << "Rendering decals, got: " << e.getDescription() << std::endl; } }
void GfxLight::update (const Vector3 &cam_pos) { if (dead) THROW_DEAD(className); light->setPosition(to_ogre(getWorldTransform().pos)); light->setDirection(to_ogre(getWorldTransform().removeTranslation()*Vector3(0,1,0))); corona->pos = getWorldTransform() * coronaLocalPos; Vector3 col = enabled ? fade * coronaColour : Vector3(0,0,0); corona->dimensions = Vector3(coronaSize, coronaSize, coronaSize); Vector3 light_dir_ws = (cam_pos - getWorldTransform().pos).normalisedCopy(); Vector3 light_aim_ws_ = getWorldTransform().removeTranslation() * Vector3(0,1,0); float angle = light_aim_ws_.dot(light_dir_ws); float inner = gritcos(coronaInnerAngle); float outer = gritcos(coronaOuterAngle); if (outer != inner) { float occlusion = std::min(std::max((angle-inner)/(outer-inner), 0.0f), 1.0f); col *= (1-occlusion); } corona->diffuse = Vector3(0, 0, 0); corona->emissive = col; }
void GfxLight::setOuterAngle (Degree v) { if (dead) THROW_DEAD(className); light->setSpotlightOuterAngle(to_ogre(v)); }
void GfxBody::setBoneLocalScale (unsigned n, const Vector3 &v) { checkBone(n); Ogre::Bone *bone = skeleton->getBone(n); bone->setScale(to_ogre(v)); }
void GfxBody::setBoneLocalOrientation (unsigned n, const Quaternion &v) { checkBone(n); Ogre::Bone *bone = skeleton->getBone(n); bone->setOrientation(to_ogre(v)); }