Beispiel #1
0
Uniform const& GLES_Shader::get_uniform_skin_matrix(void* data) const
{
    Command_Stream::Render_Context* ctx = (Command_Stream::Render_Context*)data;
    static Uniform u(Uniform::Type::VEC4, 1);
    if (u.get_count() == 1)
    {
        u = Uniform(Uniform::Type::VEC4, m_max_skin_nodes * 3);
    }
    if (ctx)
    {
        QASSERT(ctx->render_job_data->node_transform_count < m_max_skin_nodes);
        size_t count = math::min(ctx->render_job_data->node_transform_count, m_max_skin_nodes);
        if (u.get_count() == count * 3)
        {
            u = Uniform(Uniform::Type::VEC4, count * 3);
        }
        for (size_t i = 0; i < count; i++)
        {
            auto const& mat = ctx->render_job_data->node_transforms[i].mat;
            u.set(i*3 + 0, mat.get_row(0));
            u.set(i*3 + 1, mat.get_row(1));
            u.set(i*3 + 2, mat.get_row(2));
        }
    }
    return u;
}
/***************************************************************
* Function: updateVSParameters()
***************************************************************/
void DSVirtualEarth::updateVSParameters(const Vec3 &viewDir, const Vec3 &viewPos)
{
    if (!mVirtualScenicHandler) return;

    /*  compute sun direction in world space: apply transforms resulted by viewer's orientation change, 
	guarantee that from the viewer's position, the virtual earth is always half illuminated. */
    Matrixd baserotMat;
    baserotMat.makeRotate(Vec3(0, 1, 0), gDesignStateFrontVect);
    Vec3 sunDirWorld = (CAVEAnimationModeler::ANIMVirtualEarthLightDir()) * baserotMat;
    StateSet *stateset = mEarthGeode->getStateSet();
    if (stateset)
    {
	Uniform *lightposUniform = stateset->getOrCreateUniform("LightPos", Uniform::FLOAT_VEC4);
	lightposUniform->set(Vec4(sunDirWorld, 0.0));
    }

    /* compute matrix combination that transforms a vector from shader space into world space */
    Matrixd latiMat;
    latiMat.makeRotate(mLati / 180.f * M_PI, Vec3(0, 1, 0));
    Matrixd equatorMat;   
    equatorMat.makeRotate((mTimeOffset / 12.f + mLongi / 180.f) * M_PI, Vec3(0, 0, 1));  
    Matrixd tiltaxisMat = mTiltAxisTrans->getMatrix();
    Matrixd eclipticMat = mEclipticTrans->getMatrix();
    Matrixd transMat = mUnitspaceMat * latiMat * equatorMat * tiltaxisMat * eclipticMat * baserotMat;

    /* updata environment rendering by passing parameters to VirtualScenicHandler */
    mVirtualScenicHandler->updateVSParameters(transMat, sunDirWorld, viewDir, viewPos);
}
/***************************************************************
* Function: setSkyMaskingColorEnabled()
***************************************************************/
void VirtualScenicHandler::setSkyMaskingColorEnabled(bool flag)
{
    Uniform *skymaskingcolorUniform = mSkyDomeStateset->getOrCreateUniform("skymaskingcolor", Uniform::FLOAT_VEC4);
    Uniform *watermaskingcolorUniform;
    if (mWaterEnabled)
    {
         watermaskingcolorUniform = 
            mWatersurfStateset->getOrCreateUniform("watermaskingcolor", Uniform::FLOAT_VEC4);
    }

    if (flag)
    {
        skymaskingcolorUniform->set(Vec4(0.5, 0.8, 0.5, 1.0));
        if (mWaterEnabled)
            watermaskingcolorUniform->set(Vec4(0.5, 0.8, 0.5, 1.0));
    }
    else 
    {
        skymaskingcolorUniform->set(Vec4(1.0, 1.0, 1.0, 1.0));
        if (mWaterEnabled)
            watermaskingcolorUniform->set(Vec4(1.0, 1.0, 1.0, 1.0));
    }
}
/***************************************************************
* Function: updateVSParameters()
*
* Description: This function is called by 'DSVirtualEarth' under
* 'DesignStateRenderer'. Input parameter 'transMat' is the matrix
* that transformed vector in shader space to world space.
*
***************************************************************/
void VirtualScenicHandler::updateVSParameters(const Matrixd &matShaderToWorld,
		const Vec3 &sunDirWorld, const Vec3 &viewDir, const Vec3 &viewPos)
{
    Matrixd matWorldToShader = Matrixd::inverse(matShaderToWorld);

    /*  'sunDirWorld' is directional vector that illuminates the virtual earth sphere, 
	'sunDirShader' is also defined in world space and represents for the actual 
	 sun direction of the environment.
    */
    Vec3 sunDirShader = sunDirWorld * matWorldToShader;
    sunDirShader.normalize();

    float haze = viewDir * sunDirShader;	haze = haze > 0 ? haze:0;
    float hazeRadisuMin = 0.975f - sunDirShader.z() * 0.02f - haze * 0.1f;
    float hazeRadisuMax = 0.995f;

    Vec4 sunColor, skyColor, skyFadingColor;
    interpretColorParameters(sunDirShader, sunColor, skyColor, skyFadingColor);

    /* Update light sources of scene graphs under DesignObjectHandler:
       Set relatively high ambient components for 'mSunLight' so that geometries are
       still visible at night time. For 'mPointLight', always keep its position on top
       of viewer's head so all reference geometries are illuminated evenly.
    */
    mSunLight->setPosition(Vec4(sunDirShader, 0.0f));
    mSunLight->setDiffuse(sunColor);
    mSunLight->setAmbient(Vec4(0.5f,0.5f,0.5f,1.0f));

    mPointLight->setPosition(Vec4(viewPos, 0.0f));

    // update sky dome uniform list
    Uniform *hazeRadisuMinUniform = mSkyDomeStateset->getOrCreateUniform("hazeRadisuMin", Uniform::FLOAT);
    hazeRadisuMinUniform->set(hazeRadisuMin);

    Uniform *hazeRadisuMaxUniform = mSkyDomeStateset->getOrCreateUniform("hazeRadisuMax", Uniform::FLOAT);
    hazeRadisuMaxUniform->set(hazeRadisuMax);

    Uniform *sunDirUniform1 = mSkyDomeStateset->getOrCreateUniform("sundir", Uniform::FLOAT_VEC4);
    sunDirUniform1->set(Vec4(sunDirShader, 0.0));

    Uniform *suncolorUniform1 = mSkyDomeStateset->getOrCreateUniform("suncolor", Uniform::FLOAT_VEC4);
    suncolorUniform1->set(sunColor);

    Uniform *skycolorUniform1 = mSkyDomeStateset->getOrCreateUniform("skycolor", Uniform::FLOAT_VEC4);
    skycolorUniform1->set(skyColor);

    Uniform *skyfadingcolorUniform = mSkyDomeStateset->getOrCreateUniform("skyfadingcolor", Uniform::FLOAT_VEC4);
    skyfadingcolorUniform->set(skyFadingColor);

    Uniform *matShaderToWorldUniform = mSkyDomeStateset->getOrCreateUniform("shaderToWorldMat", Uniform::FLOAT_MAT4);
    matShaderToWorldUniform->set(matWorldToShader);

    // update water surface uniform list
    if (mWaterEnabled)
    {
        Uniform *sunDirUniform2 = mWatersurfStateset->getOrCreateUniform("sundir", Uniform::FLOAT_VEC3);
        sunDirUniform2->set(sunDirShader);

        Uniform *suncolorUniform2 = mWatersurfStateset->getOrCreateUniform("suncolor", Uniform::FLOAT_VEC4);
        suncolorUniform2->set(sunColor);
    }
    Uniform *skycolorUniform2 = mSkyDomeStateset->getOrCreateUniform("skycolor", Uniform::FLOAT_VEC4);
    skycolorUniform2->set(skyColor);

    // change texture coordinates of normal map
    if (mWaterEnabled)
    {
        Array* texcoordArray = mWatersurfGeometry->getTexCoordArray(0);
        if (texcoordArray->getType() == Array::Vec2ArrayType)
        {
            Vec2* texDataPtr = (Vec2*)(texcoordArray->getDataPointer());
            float randArr[2];
            for (int i = 0; i < 2; i++) 
                randArr[i] = (float)rand() / RAND_MAX * ANIM_WATERSURF_TEXCOORD_NOISE_LEVEL;
            texDataPtr[0] += Vec2(randArr[0], randArr[1]);
            texDataPtr[1] += Vec2(randArr[0], randArr[1]);
            texDataPtr[2] += Vec2(randArr[0], randArr[1]);
            texDataPtr[3] += Vec2(randArr[0], randArr[1]);
        }

        mWatersurfGeometry->dirtyDisplayList();
        mWatersurfGeometry->dirtyBound();
    }
}