Esempio n. 1
0
//--------------------------------------------------------------------------------------
// Name: SetWoodShader()
// Desc: 
//--------------------------------------------------------------------------------------
VOID CSample::SetWoodShader()
{
	FRMVECTOR4 darkWoodColorVec = FRMVECTOR4( 0.44f, 0.210526f, 0.0f, 1.0f );
	FRMVECTOR4 lightWoodColorVec = FRMVECTOR4( 0.917293f, 0.503759f, 0.12782f, 1.0f );
	FRMVECTOR4 lightWoodDirVec = FRMVECTOR4( 0.0f, -1.0f, 0.0f, 1.0f );

    glUseProgram( m_hWoodShader );

    glUniformMatrix4fv( m_nWoodModelViewProjectionMatrixSlot, 1, FALSE, (FLOAT32*)&m_matModelViewProj );

    glActiveTexture( GL_TEXTURE0 );
    glBindTexture( GL_TEXTURE_3D_OES, m_pNoiseTexture->m_hTextureHandle );

    glUniformMatrix4fv( m_nWoodModelViewMatrixSlot, 1, FALSE, (FLOAT32*)&m_matModelView );
    glUniformMatrix3fv( m_nWoodNormalMatrixSlot, 1, FALSE, (FLOAT32*)&m_matNormal );
    glUniform1f( m_nWoodScaleSlot, 10.0f );//;8.0f );
    glUniform1f( m_nWoodKdSlot, 0.89f );
    glUniform1f( m_nWoodKsSlot, 0.66f );
    glUniform4fv( m_nWoodDarkWoodColorSlot, 1, (FLOAT32*)&darkWoodColorVec );
    glUniform4fv( m_nWoodLightWoodColorSlot, 1, (FLOAT32*)&lightWoodColorVec );
    glUniform1f( m_nWoodFrequencySlot, m_fWoodFrequency );
    glUniform1f( m_nWoodNoiseScaleSlot, 20.0f );
    glUniform1f( m_nWoodRingScaleSlot, 2.2f );
    glUniform4fv( m_nWoodLightDirSlot, 1, (FLOAT32*)&lightWoodDirVec );
}
Esempio n. 2
0
//--------------------------------------------------------------------------------------
// Name: SetCheckerShader()
// Desc: 
//--------------------------------------------------------------------------------------
VOID CSample::SetCheckerShader()
{
	FRMVECTOR4 color1Vec = FRMVECTOR4( 0.0f, 0.0f, 0.0f, 1.0f );
	FRMVECTOR4 color2Vec = FRMVECTOR4( 1.0f, 0.0f, 0.0f, 1.0f );

    glUseProgram( m_hCheckerShader );

    glUniformMatrix4fv( m_nCheckerModelViewProjectionMatrixSlot, 1, FALSE, (FLOAT32*)&m_matModelViewProj );
    glUniform4fv( m_nCheckerColor1Slot, 1, (FLOAT32*)&color1Vec );
    glUniform4fv( m_nCheckerColor2Slot, 1, (FLOAT32*)&color2Vec );
    glUniform1f( m_nCheckerFrequencySlot, m_fCheckerFrequency );
}
Esempio n. 3
0
//--------------------------------------------------------------------------------------
// Name:
// Desc:
//--------------------------------------------------------------------------------------
SimpleObject22::SimpleObject22()
{
    Position = FRMVECTOR3( 0.0f, 0.0f, 0.0f );
    RotateTime = 0.0f;
    Drawable = NULL;
    BumpTexture = NULL;
    DiffuseColor = FRMVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f );
    SpecularColor = FRMVECTOR4( 1.0f, 1.0f, 1.0f, 5.0f );
    ReflectionStrength = 1.0f;
    IrisGlow = 1.0f;

    for( int i = 0; i < EYE_COLORS; i++ )
        DiffuseTexture[i] = NULL;
}
Esempio n. 4
0
//--------------------------------------------------------------------------------------
// Name: RenderLightingToFBO()
// Desc: 
//--------------------------------------------------------------------------------------
VOID CSample::RenderLightingToFBO()
{
    GetLightingFBO();

    const float clearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
    D3DDeviceContext()->ClearRenderTargetView( m_pDiffuseSpecularTextureRenderTargetView.Get(), clearColor );
    D3DDeviceContext()->ClearDepthStencilView( m_pDiffuseSpecularDepthStencilView.Get(), D3D11_CLEAR_DEPTH, 1.0f, 0 );


    m_PerPixelLightingShader.Bind();
    
    // Render the floor
    m_PerPixelLightingConstantBufferData.vAmbient = FRMVECTOR4( 0.0f, 0.0f, 0.0f, 1.0f );
    m_PerPixelLightingConstantBufferData.vDiffuse = FRMVECTOR4( 0.5f, 0.5f, 0.8f, 1.0f );
    m_PerPixelLightingConstantBufferData.vSpecular = FRMVECTOR4( 0.0f, 0.0f, 0.0f, 0.0f );
    m_PerPixelLightingConstantBufferData.matModelView = m_matCameraFloorModelView;
    m_PerPixelLightingConstantBufferData.matModelViewProj = m_matCameraFloorModelViewProj;
    m_PerPixelLightingConstantBufferData.matNormal = m_matCameraFloorNormal;
    m_PerPixelLightingConstantBufferData.vLightPos = FRMVECTOR4( m_vLightPosition, 1.0f );  
    m_pPerPixelLightingConstantBuffer->Update( &m_PerPixelLightingConstantBufferData );
    m_pPerPixelLightingConstantBuffer->Bind( CFrmConstantBuffer::BindFlagVS | CFrmConstantBuffer::BindFlagPS );
    m_Floor[ m_nCurFloorIndex ].Render( &m_PerPixelLightingShader );

    // Render the mesh
    m_PerPixelLightingConstantBufferData.vAmbient = FRMVECTOR4( 0.0f, 0.0f, 0.0f, 1.0f );
    m_PerPixelLightingConstantBufferData.vDiffuse = FRMVECTOR4( 0.6f, 0.1f, 0.1f, 1.0f );
    m_PerPixelLightingConstantBufferData.vSpecular = FRMVECTOR4( 1.0f, 0.6f, 0.65f, 10.0f );
    m_PerPixelLightingConstantBufferData.matModelView = m_matCameraMeshModelView;
    m_PerPixelLightingConstantBufferData.matModelViewProj = m_matCameraMeshModelViewProj;
    m_PerPixelLightingConstantBufferData.matNormal = m_matCameraMeshNormal;
    m_PerPixelLightingConstantBufferData.vLightPos = FRMVECTOR4( m_vLightPosition, 1.0f );
    m_pPerPixelLightingConstantBuffer->Update( &m_PerPixelLightingConstantBufferData );
    m_pPerPixelLightingConstantBuffer->Bind( CFrmConstantBuffer::BindFlagVS | CFrmConstantBuffer::BindFlagPS );    
    m_Meshes[ m_nCurMeshIndex ].Render( &m_PerPixelLightingShader );
}
Esempio n. 5
0
//--------------------------------------------------------------------------------------
// Name: InitParticles()
// Desc: Initializes the particles
//--------------------------------------------------------------------------------------
static VOID InitParticles( PARTICLE* pParticles, GLuint *pParticleBuffers, GLuint *pParticleVAOs, GLuint *pQuery)
{
    for( UINT32 i = 0; i < NUM_PARTICLES; i++ )
    {
        pParticles[i].m_vPosition         =  FRMVECTOR3( 0.0f, 0.0f, 0.0f );
        pParticles[i].m_vVelocity         =  FRMVECTOR3( 0.0f, 0.0f, 0.0f );
        pParticles[i].m_vColor            =  FRMVECTOR4( 1.0, 0.0, 0.0, 0.0 );
        pParticles[i].m_fInitialSize      =  0.0f;
        pParticles[i].m_fSizeIncreaseRate =  0.0f;
        pParticles[i].m_fStartTime        =  0.0f;
        pParticles[i].m_fLifeSpan         =  -1.0f;
    }

	glGenQueries(1, pQuery);

	glGenVertexArrays(2, pParticleVAOs);

	// Create and initialize both Particle buffers to this particle data
	glGenBuffers(2, pParticleBuffers );

	glBindBuffer( GL_ARRAY_BUFFER, pParticleBuffers[0] );
	glBufferData( GL_ARRAY_BUFFER, sizeof(PARTICLE)*NUM_PARTICLES, pParticles, GL_STREAM_DRAW );
	glBindBuffer( GL_ARRAY_BUFFER, 0 );

	glBindBuffer( GL_ARRAY_BUFFER, pParticleBuffers[1] );	
	glBufferData( GL_ARRAY_BUFFER, sizeof(PARTICLE)*NUM_PARTICLES, pParticles, GL_STREAM_DRAW );
	glBindBuffer( GL_ARRAY_BUFFER, 0 );
}
VOID FrmRenderTextureToScreen_GLES( FLOAT32 sx, FLOAT32 sy, FLOAT32 w, FLOAT32 h,
                                    UINT32 hTexture,
                                    INT32 hShaderProgram, INT32 hScreenSizeLoc )
{
    struct { GLint x, y, width, height; } viewport;
    glGetIntegerv( GL_VIEWPORT, (GLint*)&viewport );

    FLOAT32 fTextureWidth  = w;
    FLOAT32 fTextureHeight = h;
    FLOAT32 fScreenWidth   = (FLOAT32)viewport.width;
    FLOAT32 fScreenHeight  = (FLOAT32)viewport.height;

    if( sx < 0.0f ) sx += fScreenWidth  - fTextureWidth;
    if( sy < 0.0f ) sy += fScreenHeight - fTextureHeight;

    sx = FrmFloor( sx );
    sy = FrmFloor( sy );

    // Set the geoemtry
    FRMVECTOR4 vQuad[] = 
    { 
        //          Screenspace x     Screenspace y      tu    tv
        FRMVECTOR4( sx,               sy,                0.0f, 1.0f ),
        FRMVECTOR4( sx,               sy+fTextureHeight, 0.0f, 0.0f ),
        FRMVECTOR4( sx+fTextureWidth, sy+fTextureHeight, 1.0f, 0.0f ),
        FRMVECTOR4( sx+fTextureWidth, sy,                1.0f, 1.0f ),
    };
    glVertexAttribPointer( 0, 4, GL_FLOAT, 0, 0, vQuad );
    glEnableVertexAttribArray( 0 );

    // Set the texture
    glActiveTexture( GL_TEXTURE0 );
    glBindTexture( GL_TEXTURE_2D, hTexture );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
    glEnable( GL_BLEND );
    glDisable( GL_DEPTH_TEST );

    // Set the shader program
    glUseProgram( hShaderProgram );
    glUniform2f( hScreenSizeLoc, fScreenWidth, fScreenHeight );

    // Draw the quad
    glDrawArrays( GL_TRIANGLE_FAN, 0, 4 );

    glEnable( GL_DEPTH_TEST );
    glDisable( GL_BLEND );
}
Esempio n. 7
0
//--------------------------------------------------------------------------------------
// Name: Initialize()
// Desc: 
//--------------------------------------------------------------------------------------
BOOL CSample31::Initialize(CFrmFontGLES &m_Font, CFrmTexture* m_pLogoTexture)
{
    m_ShouldRotate = TRUE;

    // Load the packed resources
    CFrmPackedResourceGLES resource;
    if( FALSE == resource.LoadFromFile( "Demos/AdrenoShaders/Textures/31_Textures.pak" ) )
        return FALSE;

    // Create textures
    m_GodRayTexture = resource.GetTexture( "GodRay1" );

    // Setup the user interface
    if( FALSE == m_UserInterface.Initialize( &m_Font, m_strName ) )
        return FALSE;
    m_UserInterface.AddOverlay( m_pLogoTexture->m_hTextureHandle, -5, -5, m_pLogoTexture->m_nWidth, m_pLogoTexture->m_nHeight );
    m_UserInterface.AddTextString( (char *)"Press \200 for Help", 1.0f, -1.0f );
    m_UserInterface.AddBoolVariable( &m_ShouldRotate, (char *)"Should Rotate" );
    m_UserInterface.AddFloatVariable( &m_RayExtruderShader.RayLength, (char *)"Ray length" );
    m_UserInterface.AddFloatVariable( &m_CutoutShader.OccluderThreshold, (char *)"Occluder pickup distance" );
    m_UserInterface.AddFloatVariable( &m_CutoutShader.OccluderFadeout, (char *)"Occluder fade distance" );
    m_UserInterface.AddFloatVariable( &m_CombineShader.RayOpacity, (char *)"Ray opacity" );
    m_UserInterface.AddHelpKey( FRM_FONT_KEY_STAR, (char *)"Toggle Orientation" );
    m_UserInterface.AddHelpKey( FRM_FONT_KEY_1, (char *)"Decrease ray length" );
    m_UserInterface.AddHelpKey( FRM_FONT_KEY_2, (char *)"Increase ray length" );
    m_UserInterface.AddHelpKey( FRM_FONT_KEY_3, (char *)"Decrease pickup dist" );
    m_UserInterface.AddHelpKey( FRM_FONT_KEY_4, (char *)"Increase pickup dist" );
    m_UserInterface.AddHelpKey( FRM_FONT_KEY_5, (char *)"Decrease pickup fade" );
    m_UserInterface.AddHelpKey( FRM_FONT_KEY_6, (char *)"Increase pickup fade" );
    m_UserInterface.AddHelpKey( FRM_FONT_KEY_7, (char *)"Decrease opacity" );
    m_UserInterface.AddHelpKey( FRM_FONT_KEY_8, (char *)"Increase opacity" );
    m_UserInterface.AddHelpKey( FRM_FONT_KEY_9, (char *)"Toggle Rotation" );

    // Load the mesh
    if( FALSE == m_Mesh.Load( "Demos/AdrenoShaders/Meshes/Map3.mesh" ) )
        return FALSE;
    m_CameraPos = FRMVECTOR3( 6.2f, 2.0f, 0.0f );
    float Split = 1.1f;
    float yAdjust = -0.05f;
    ModelScale31 = 1.0f;

    if( FALSE == m_Mesh.MakeDrawable( &resource ) )
        return FALSE;

	// Initialize the shaders
	if( FALSE == InitShaders() )
	{
		return FALSE;
	}

    m_AmbientLight = FRMVECTOR4( 0.05f, 0.05f, 0.05f, 0.0f );

    // Set up the objects
    m_Object.Drawable = &m_Mesh;
    m_Object.Position.y += yAdjust;

    return TRUE;
}
Esempio n. 8
0
//--------------------------------------------------------------------------------------
// Name: RenderBlendedLightingAndShadowMap()
// Desc: 
//--------------------------------------------------------------------------------------
VOID CSample::RenderBlendedLightingAndShadowMap()
{
    CFrmShaderProgramD3D* pShadowMapShader = NULL;

    // Reset to default window framebuffer
    ID3D11RenderTargetView* pRTViews[1] = { m_windowRenderTargetView.Get() };
    D3DDeviceContext()->OMSetRenderTargets( 1, pRTViews, m_windowDepthStencilView.Get() );

    // Reset the viewport
    D3D11_VIEWPORT viewport;
    viewport.TopLeftX = 0.0f;
    viewport.TopLeftY = 0.0f;
    viewport.Width = static_cast<float>(m_nWidth);
    viewport.Height = static_cast<float>(m_nHeight);
    viewport.MinDepth = D3D11_MIN_DEPTH;
    viewport.MaxDepth = D3D11_MAX_DEPTH;
    D3DDeviceContext()->RSSetViewports(1, &viewport);

    // Bind shadow map to texture 0
    D3DDeviceContext()->PSSetShaderResources( 0, 1, m_pShadowTextureShaderResourceView.GetAddressOf() );
    D3DDeviceContext()->PSSetSamplers( 0, 1, m_pShadowTextureSampler.GetAddressOf() );

    // Bind diffuse/specular map to texture 1
    D3DDeviceContext()->PSSetShaderResources( 1, 1, m_pDiffuseSpecularTextureShaderResourceView.GetAddressOf() );
    D3DDeviceContext()->PSSetSamplers( 1, 1, m_pDiffuseSpecularTextureSampler.GetAddressOf() );

    if( m_bUsePCF )
    {
        pShadowMapShader = &m_ShadowMapPCFShader;
    }
    else
    {
        pShadowMapShader = &m_ShadowMapShader;
    }

    pShadowMapShader->Bind();    
    m_ShadowMapConstantBufferData.fEpsilon = 0.0035f;
    m_ShadowMapConstantBufferData.vAmbient = FRMVECTOR4( 0.2f, 0.2f, 0.2f, 1.0f );
    m_ShadowMapConstantBufferData.matModelViewProj = m_matCameraFloorModelViewProj;
    m_ShadowMapConstantBufferData.matShadow = m_matFloorShadowMatrix;
    m_ShadowMapConstantBufferData.matScreenCoord = m_matFloorScreenCoordMatrix;
    m_pShadowMapConstantBuffer->Update( &m_ShadowMapConstantBufferData );
    m_pShadowMapConstantBuffer->Bind( CFrmConstantBuffer::BindFlagVS | CFrmConstantBuffer::BindFlagPS );
    m_Floor[ m_nCurFloorIndex ].Render( pShadowMapShader );

        
    m_ShadowMapConstantBufferData.matModelViewProj = m_matCameraMeshModelViewProj;
    m_ShadowMapConstantBufferData.matShadow = m_matMeshShadowMatrix;
    m_ShadowMapConstantBufferData.matScreenCoord = m_matMeshScreenCoordMatrix;
    m_pShadowMapConstantBuffer->Update( &m_ShadowMapConstantBufferData );
    m_pShadowMapConstantBuffer->Bind( CFrmConstantBuffer::BindFlagVS | CFrmConstantBuffer::BindFlagPS );
    m_Meshes[ m_nCurMeshIndex ].Render( pShadowMapShader );

    // Unbind
    ID3D11ShaderResourceView* noTex[2] = { NULL, NULL };
    D3DDeviceContext()->PSSetShaderResources( 0, 2, noTex );        
}
Esempio n. 9
0
//--------------------------------------------------------------------------------------
// Name: VerletIntegrationCL()
// Desc: Perform verlet integration using OpenCL
//--------------------------------------------------------------------------------------
BOOL CClothSimCL::VerletIntegrationCL( float fltElapsed )
{
    cl_int errNum = 0;

    // Set the kernel arguments for the VerletIntegration kernel
    FRMVECTOR4 VelDamping = FRMVECTOR4( m_VelDamping, 0.0f );
    FRMVECTOR4 CurrentWind = FRMVECTOR4( m_CurrentWind, 0.0f );
    FRMVECTOR4 WindDir = FRMVECTOR4( m_WindDir, 0.0f );
    FRMVECTOR4 Acceleration = FRMVECTOR4( m_Gravity, 0.0f );
    Acceleration *= 0.25f;

    cl_float ElapsedSquared = fltElapsed * fltElapsed;

    cl_kernel kernel = m_kernels[VERLET_INTEGRATION];
    errNum |= clSetKernelArg( kernel, 0, sizeof(cl_float), &ElapsedSquared );
    errNum |= clSetKernelArg( kernel, 1, sizeof(cl_float4), &Acceleration );
    errNum |= clSetKernelArg( kernel, 2, sizeof(cl_float4), &VelDamping );
    errNum |= clSetKernelArg( kernel, 3, sizeof(cl_float4), &WindDir );
    errNum |= clSetKernelArg( kernel, 4, sizeof(cl_float4), &CurrentWind );
    errNum |= clSetKernelArg( kernel, 5, sizeof(cl_mem), &m_vboMem[CUR_POSITION] );
    errNum |= clSetKernelArg( kernel, 6, sizeof(cl_mem), &m_vboMem[PREV_POSITION] );
    errNum |= clSetKernelArg( kernel, 7, sizeof(cl_mem), &m_vboMem[NORMAL] );
    if( errNum != CL_SUCCESS )
    {
        char str[256];
        FrmSprintf( str, sizeof(str), "Error setting kernel arguments (%d).", errNum );
        FrmLogMessage( str );
        return FALSE;
    }

    // Finally queue the kernel for execution
    size_t globalWorkSize[1] = { m_uiNumVerts - CLOTH_POINTS_WIDTH };
    errNum = clEnqueueNDRangeKernel( m_commandQueue, kernel, 1, NULL, globalWorkSize,
                                     NULL, 0, NULL, NULL );
    if( errNum != CL_SUCCESS )
    {
        FrmLogMessage( "Error queuing kernel for execution." );
        return FALSE;
    }

    return TRUE;
}
Esempio n. 10
0
//--------------------------------------------------------------------------------------
// Name: Render()
// Desc: 
//--------------------------------------------------------------------------------------
VOID CSample::Render()
{
    // Bind the backbuffer as a render target
    D3DDeviceContext()->OMSetRenderTargets( 1, m_windowRenderTargetView.GetAddressOf(), m_windowDepthStencilView.Get() );

    // Clear the backbuffer to a solid color, and reset the depth stencil.
    const float clearColor[4] = { 0.071f, 0.04f, 0.561f, 1.0f };
    D3DDeviceContext()->ClearRenderTargetView( m_windowRenderTargetView.Get(), clearColor );
    D3DDeviceContext()->ClearDepthStencilView( m_windowDepthStencilView.Get(), D3D11_CLEAR_DEPTH, 1.0f, 0 );
  
    m_Shaders[ m_nCurShaderIndex ].Bind();

    // Render the mesh
    m_PhysicallyBasedLightingConstantBufferData.matModelView = m_matCameraMeshModelView;
    m_PhysicallyBasedLightingConstantBufferData.matModelViewProj = m_matCameraMeshModelViewProj;
    m_PhysicallyBasedLightingConstantBufferData.matNormal = FRMMATRIX4X4( m_matCameraMeshNormal );
    m_PhysicallyBasedLightingConstantBufferData.vLightPos = FRMVECTOR4( m_vLightPosition.x, m_vLightPosition.y, m_vLightPosition.z, 1.0f );
    m_PhysicallyBasedLightingConstantBufferData.SkyColor = FRMVECTOR4( m_SkyColor, 1.0f );
	m_PhysicallyBasedLightingConstantBufferData.GroundColor = FRMVECTOR4( m_GroundColor, 1.0f );
    m_PhysicallyBasedLightingConstantBufferData.vMaterialSpecular = FRMVECTOR4( m_MaterialSpecular, 1.0f );
    m_PhysicallyBasedLightingConstantBufferData.vMaterialDiffuse = FRMVECTOR4( m_MaterialDiffuse, 1.0f );
    m_PhysicallyBasedLightingConstantBufferData.vLightColor = FRMVECTOR4( m_LightColor, 1.0f );
    m_PhysicallyBasedLightingConstantBufferData.fMaterialGlossiness = m_MaterialGlossiness;
	
    m_pPhysicallyBasedLightingConstantBuffer->Update( &m_PhysicallyBasedLightingConstantBufferData ) ;
    m_pPhysicallyBasedLightingConstantBuffer->Bind( CFrmConstantBuffer::BindFlagVS | CFrmConstantBuffer::BindFlagPS );

    m_Meshes[ m_nCurMeshIndex ].Render( &m_Shaders[ m_nCurShaderIndex ] );
			
	// Update the timer
    m_Timer.MarkFrame();
    // Render the user interface
    m_UserInterface.Render( m_Timer.GetFrameRate() );
}
Esempio n. 11
0
//--------------------------------------------------------------------------------------
// Name: SetMarbleShader()
// Desc: 
//--------------------------------------------------------------------------------------
VOID CSample::SetMarbleShader()
{
	FRMVECTOR4 marbleColor1Vec = FRMVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f );
	FRMVECTOR4 marbleColor2Vec = FRMVECTOR4( 0.0f, 0.0f, 0.0f, 1.0f );
	FRMVECTOR4 lightMarbleDirVec = FRMVECTOR4( 0.0f, -1.0f, 0.0f, 1.0f );

    glUseProgram( m_hMarbleShader );

    glUniformMatrix4fv( m_nMarbleModelViewProjectionMatrixSlot, 1, FALSE, (FLOAT32*)&m_matModelViewProj );

    glActiveTexture( GL_TEXTURE0 );
    glBindTexture( GL_TEXTURE_3D_OES, m_pTurbTexture->m_hTextureHandle );

    glUniformMatrix4fv( m_nMarbleModelViewMatrixSlot, 1, FALSE, (FLOAT32*)&m_matModelView );
    glUniformMatrix3fv( m_nMarbleNormalMatrixSlot, 1, FALSE, (FLOAT32*)&m_matNormal );
    glUniform1f( m_nMarbleScaleSlot, 20.0f ); //43 //20.0f );
    glUniform1f( m_nMarbleKdSlot, 0.89f );
    glUniform1f( m_nMarbleKsSlot, 0.66f );
    glUniform4fv( m_nMarbleColor1Slot, 1, (FLOAT32*)&marbleColor1Vec );
    glUniform4fv( m_nMarbleColor2Slot, 1, (FLOAT32*)&marbleColor2Vec );
    glUniform1f( m_nMarbleTurbScaleSlot, m_MarbleTurbScale );//12
    glUniform4fv( m_nMarbleLightDirSlot, 1, (FLOAT32*)&lightMarbleDirVec );
}
Esempio n. 12
0
//--------------------------------------------------------------------------------------
// Name: Initialize()
// Desc: 
//--------------------------------------------------------------------------------------
BOOL CSample34::Initialize(CFrmFontGLES &Font, CFrmTexture* m_pLogoTexture)
{
    m_ShouldRotate = TRUE;
    m_Preview = false;

    // Create the font
    // Load the packed resources
    // NOTE SAME TEXTURES AS 27
    CFrmPackedResourceGLES resource;
    if( FALSE == resource.LoadFromFile( "Demos/AdrenoShaders/Textures/27_Textures.pak" ) )
        return FALSE;

    // Setup the user interface
    if( FALSE == m_UserInterface.Initialize( &Font, m_strName ) )
        return FALSE;
    m_UserInterface.AddOverlay( m_pLogoTexture->m_hTextureHandle, -5, -5,
                                m_pLogoTexture->m_nWidth, m_pLogoTexture->m_nHeight );
    m_UserInterface.AddTextString( (char *)"Press \200 for Help", 1.0f, -1.0f );
    m_UserInterface.AddBoolVariable( &m_ShouldRotate, (char *)"Should Rotate" );
    m_UserInterface.AddFloatVariable( &m_CombineShader.GaussSpread, (char *)"Gauss filter spread" );
    m_UserInterface.AddHelpKey( FRM_FONT_KEY_STAR, (char *)"Toggle Orientation" );
    m_UserInterface.AddHelpKey( FRM_FONT_KEY_6, (char *)"Decrease gauss spread" );
    m_UserInterface.AddHelpKey( FRM_FONT_KEY_7, (char *)"Increase gauss spread" );
    m_UserInterface.AddHelpKey( FRM_FONT_KEY_8, (char *)"Toggle Rotation" );

    // Load the mesh
    if( FALSE == m_Mesh.Load( "Demos/AdrenoShaders/Meshes/Map3.mesh" ) )
        return FALSE;
    m_CameraPos = FRMVECTOR3( 6.2f, 2.0f, 0.0f );
    float Split = 1.1f;
    float yAdjust = -0.05f;

    if( FALSE == m_Mesh.MakeDrawable( &resource ) )
        return FALSE;

	// Initialize the shaders
	if( FALSE == InitShaders() )
	{
		return FALSE;
	}

    m_AmbientLight = FRMVECTOR4( 0.1f, 0.1f, 0.1f, 0.0f );

    // Set up the objects
    m_Object.Drawable = &m_Mesh;
    m_Object.Position.y += yAdjust;

    return TRUE;
}
Esempio n. 13
0
//--------------------------------------------------------------------------------------
// Name: Initialize()
// Desc: 
//--------------------------------------------------------------------------------------
BOOL CSample22::Initialize(CFrmFontGLES &m_Font, CFrmTexture* m_pLogoTexture)
{
    m_ShouldRotate = TRUE;

    // Load the packed resources
    CFrmPackedResourceGLES resource;
    if( FALSE == resource.LoadFromFile( "Demos/AdrenoShaders/Textures/22_Textures.pak" ) )
        return FALSE;

    // Load the cube map for reflections
    if (!LoadCubeMap("00_Cubemap"))
        return FALSE;


    // Setup the user interface
    if( FALSE == m_UserInterface.Initialize( &m_Font, m_strName ) )
        return FALSE;
    m_UserInterface.AddOverlay( m_pLogoTexture->m_hTextureHandle, -5, -5,
                                m_pLogoTexture->m_nWidth, m_pLogoTexture->m_nHeight );
    m_UserInterface.AddTextString( (char *)"Press \200 for Help", 1.0f, -1.0f );
    m_UserInterface.AddBoolVariable( &m_ShouldRotate, (char *)"Should Rotate" );
    m_UserInterface.AddFloatVariable( &m_Object.IrisGlow, (char *)"Iris light" );
    m_UserInterface.AddHelpKey( FRM_FONT_KEY_STAR, (char *)"Toggle Orientation" );
    m_UserInterface.AddHelpKey( FRM_FONT_KEY_0, (char *)"Toggle Info Pane" );
    m_UserInterface.AddHelpKey( FRM_FONT_KEY_4, (char *)"Change eye color -" );
    m_UserInterface.AddHelpKey( FRM_FONT_KEY_5, (char *)"Change eye color +" );
    m_UserInterface.AddHelpKey( FRM_FONT_KEY_6, (char *)"Decrease iris light" );
    m_UserInterface.AddHelpKey( FRM_FONT_KEY_7, (char *)"Increase iris light" );
    m_UserInterface.AddHelpKey( FRM_FONT_KEY_8, (char *)"Toggle Rotation" );

    // Load the mesh
    if( FALSE == m_Mesh.Load( "Demos/AdrenoShaders/Meshes/Sphere3.mesh" ) )
        return FALSE;
    m_CameraPos = FRMVECTOR3( 0.0f, 0.0f, 44.0f );
    float Split = 1.1f;
    float yAdjust = -0.05f;
    ModelScale = 0.7f;

    if( FALSE == m_Mesh.MakeDrawable( &resource ) )
        return FALSE;

	// Initialize the shaders
	if( FALSE == InitShaders() )
	{
		return FALSE;
	}

    m_AmbientLight = FRMVECTOR4( 0.0f, 0.1f, 0.16f, 0.0f );

    // Set up the objects
    m_Object.DiffuseTexture[0] = resource.GetTexture( "Eye1" );
    m_Object.DiffuseTexture[1] = resource.GetTexture( "Eye2" );
    m_Object.DiffuseTexture[2] = resource.GetTexture( "Eye3" );
    m_Object.BumpTexture = resource.GetTexture( "EyeBump1" );
    m_Object.Drawable = &m_Mesh;
    m_Object.Position.y += yAdjust;
    m_Object.SpecularColor = FRMVECTOR4( 1.0f, 1.0f, 1.0f, 65.0f );
    m_Object.ReflectionStrength = 0.3f;
    m_Object.IrisGlow = 3.0f;

//     m_Object.RotateTime = 6.7466364f;
//     m_ShouldRotate = FALSE;

    return TRUE;
}
Esempio n. 14
0
//--------------------------------------------------------------------------------------
// Name: EmitParticles()
// Desc: 
//--------------------------------------------------------------------------------------
VOID CParticleEmitter::EmitParticles( PARTICLE* pParticles, FLOAT32 fElapsedTime,
                                      FLOAT32 fCurrentTime, FRMCOLOR Colors[NUM_COLORS],
                                      FLOAT32 fTimePerColor,
									  EmitParticleShader *epShader,
									  GLuint *srcBuffer, GLuint *pVAOs, GLuint *dstBuffer,
									  FRM_VERTEX_ELEMENT* pVertexLayout,
									  UINT32 nVertexSize, BOOL bUseTransformFeedback, GLuint Query )
{
    // Determine the color of the particles to be emitted
    FLOAT32  t = ( fCurrentTime / fTimePerColor ) - FrmFloor( fCurrentTime / fTimePerColor );
    UINT32   nColorIndex = (INT32)FrmFloor( fCurrentTime / fTimePerColor ) % NUM_COLORS;
    FRMCOLOR vColor1 = Colors[ nColorIndex ];
    FRMCOLOR vColor2 = Colors[(nColorIndex+1) % NUM_COLORS ];
    FRMCOLOR vColor  = FrmLerp( t, vColor1, vColor2 );

    m_fLeftOverParticles += m_fEmissionRate * fElapsedTime;

	if( !bUseTransformFeedback )
	{
		// Create the needed number of particles based upon our emission rate.
		for( INT32 i = 0; i < (INT32)NUM_PARTICLES; i++ )
		{
			// Get the next particle
			PARTICLE* pParticle = GetNextParticle( pParticles );

			if( FrmRand() < m_fLeftOverParticles / NUM_PARTICLES )
			{
				FLOAT32      fAngle            = m_fEmitterSpread * ( FrmRand() - 0.5f );
				FRMMATRIX4X4 matRotate         = FrmMatrixRotate( FrmRadians(fAngle), 0.0f, 0.0f, -1.0f );
				FRMVECTOR3   vVelocity         = FrmVector3TransformCoord( m_vVelocity, matRotate );

				pParticle->m_vPosition         = m_vPosition + FrmSphrand( m_fEmitterRadius );
				pParticle->m_vVelocity         = vVelocity * ApplyVariance( 1.0f, m_fSpeedVariance );
				pParticle->m_vColor            = FRMVECTOR4( vColor.r/255.0f, vColor.g/255.0f, vColor.b/255.0f, vColor.a/255.0f );
				pParticle->m_vColor.a          = ApplyVariance( m_fInitialOpacity, m_fOpacityVariance );
				pParticle->m_fStartTime        = fCurrentTime;
				pParticle->m_fLifeSpan         = ApplyVariance( m_fInitialLifeSpan, m_fLifeSpanVariance );
				pParticle->m_fInitialSize      = ApplyVariance( m_fInitialSize, m_fInitialSizeVariance );
				pParticle->m_fSizeIncreaseRate = ApplyVariance( m_fSizeIncreaseRate, m_fSizeIncreaseRateVarience );
			}
		}
	}
	else
	{
		// Using transform feedback to do particle emission

		// Set up the shader
		glUseProgram( epShader->ShaderID );
		glUniform3fv( epShader->slotvPosition, 1, (FLOAT32 *)&m_vPosition );
		glUniform3fv( epShader->slotvVelocity, 1, (FLOAT32 *)&m_vVelocity );
		glUniform1f( epShader->slotfEmitterSpread, m_fEmitterSpread );
		glUniform1f( epShader->slotfEmitterRadius, m_fEmitterRadius );
		glUniform1f( epShader->slotfSpeedVariance, m_fSpeedVariance );
		glUniform1f( epShader->slotfInitialOpacity, m_fInitialOpacity );
		glUniform1f( epShader->slotfOpacityVariance, m_fOpacityVariance );
		glUniform1f( epShader->slotfInitialLifeSpan, m_fInitialLifeSpan );
		glUniform1f( epShader->slotfLifeSpanVariance, m_fLifeSpanVariance );
		glUniform1f( epShader->slotfInitialSize, m_fInitialSize );
		glUniform1f( epShader->slotfInitialSizeVariance, m_fInitialSizeVariance );
		glUniform1f( epShader->slotfSizeIncreaseRate, m_fSizeIncreaseRate );
		glUniform1f( epShader->slotfSizeIncreaseRateVariance, m_fSizeIncreaseRateVarience );
		glUniform1f( epShader->slotfTime, fCurrentTime );
		glUniform4f( epShader->slotvColor, vColor.r/255.0f, vColor.g/255.0f, vColor.b/255.0f, vColor.a/255.0f );
		glUniform1f( epShader->slotfEmissionRate, m_fLeftOverParticles/NUM_PARTICLES );


		glEnable( GL_RASTERIZER_DISCARD );

		glBindVertexArray(pVAOs[0]);
		// set source buffer
		glBindBuffer( GL_ARRAY_BUFFER, *srcBuffer );		
		FrmSetVertexLayout( pVertexLayout, nVertexSize, 0 );
		glBindBuffer( GL_ARRAY_BUFFER, 0 );	
		glBindVertexArray(0);

		// set destination buffer
		glBindBufferBase( GL_TRANSFORM_FEEDBACK_BUFFER, 0, *dstBuffer );
		
		glBindVertexArray(pVAOs[0]);

		glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, Query); 

		// Perfom transform feedback
		glBeginTransformFeedback( GL_POINTS );

		glDrawArrays( GL_POINTS, 0, NUM_PARTICLES );
		glEndTransformFeedback();

		glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); 

		glDisable( GL_RASTERIZER_DISCARD );

		glBindVertexArray(0);
		glBindBufferBase( GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0 );
	}

	m_fLeftOverParticles -= FrmFloor( m_fLeftOverParticles );
}
Esempio n. 15
0
//--------------------------------------------------------------------------------------
// Name: Initialize()
// Desc:
//--------------------------------------------------------------------------------------
BOOL CSample::Initialize()
{
    cl_int errNum;

    if(!FrmOpenConsole())
        return FALSE;

    // Create the command queue
    m_commandQueue = clCreateCommandQueue( m_context, m_devices[0], CL_QUEUE_PROFILING_ENABLE, &errNum );
    if ( errNum != CL_SUCCESS )
    {
        FrmLogMessage( "Failed to create command queue" );
        return FALSE;
    }

    if( FALSE == FrmBuildComputeProgramFromFile( "Samples/Kernels/VectorAdd.cl", &m_program, m_context,
                                                  &m_devices[0], 1, "-cl-fast-relaxed-math" ) )
    {
        return FALSE;
    }

    // Create kernel
    m_kernel = clCreateKernel( m_program, "VectorAdd", &errNum );
    if ( errNum != CL_SUCCESS )
    {
        FrmLogMessage( "Failed to create kernel 'VectorAdd'\n" );
        return FALSE;
    }

     // Create device buffers
    m_srcA = clCreateBuffer( m_context, CL_MEM_READ_ONLY, m_nNumVectors * sizeof(FRMVECTOR4), NULL, &errNum );
    if( errNum != CL_SUCCESS )
    {
        FrmLogMessage( "ERROR: allocation device host buffer A" );
        return FALSE;
    }

    m_srcB = clCreateBuffer( m_context, CL_MEM_READ_ONLY, m_nNumVectors * sizeof(FRMVECTOR4), NULL, &errNum );
    if( errNum != CL_SUCCESS )
    {
        FrmLogMessage( "ERROR: allocation device host buffer B" );
        return FALSE;
    }

    // Map to host arrys
    FRMVECTOR4 *pHostA = (FRMVECTOR4*) clEnqueueMapBuffer( m_commandQueue, m_srcA, CL_TRUE, CL_MAP_WRITE, 0, sizeof(FRMVECTOR4) * m_nNumVectors,
                                                           0, NULL, NULL, &errNum );
    if( errNum != CL_SUCCESS )
    {
        FrmLogMessage( "ERROR: mapping device buffer A." );
        return FALSE;
    }

    FRMVECTOR4 *pHostB = (FRMVECTOR4*) clEnqueueMapBuffer( m_commandQueue, m_srcB, CL_TRUE, CL_MAP_WRITE, 0, sizeof(FRMVECTOR4) * m_nNumVectors,
                                                           0, NULL, NULL, &errNum );
    if( errNum != CL_SUCCESS )
    {
        FrmLogMessage( "ERROR: mapping device buffer B." );
        return FALSE;
    }

    // Fill with data
    for( size_t i = 0; i < m_nNumVectors; i++ )
    {
        FLOAT32 valA = (FLOAT32)i / m_nNumVectors;
        FLOAT32 valB = 1.0f - valA;
        pHostA[i] = FRMVECTOR4( valA, valA, valA, valA );
        pHostB[i] = FRMVECTOR4( valB, valB, valB, valB );
    }



    // Compute reference results on CPU
    if ( RunTests() )
    {
        m_pRefResults = new FRMVECTOR4[ m_nNumVectors ];
        for( size_t i = 0; i < m_nNumVectors; i++ )
        {
            m_pRefResults[ i ] = pHostA[ i ] + pHostB[ i ];
        }
    }

    // Unmap buffers
    errNum = clEnqueueUnmapMemObject( m_commandQueue, m_srcA, pHostA, 0, NULL, NULL );
    if( errNum != CL_SUCCESS )
    {
        FrmLogMessage( "ERROR: Unmapping buffer A." );
        return FALSE;
    }

    errNum = clEnqueueUnmapMemObject( m_commandQueue, m_srcB, pHostB, 0, NULL, NULL );
    if( errNum != CL_SUCCESS )
    {
        FrmLogMessage( "ERROR: Unmapping buffer B." );
        return FALSE;
    }

    // Create result buffer
    m_result = clCreateBuffer( m_context, CL_MEM_READ_WRITE, m_nNumVectors * sizeof(FRMVECTOR4), NULL, &errNum );
    if( errNum != CL_SUCCESS )
    {
        FrmLogMessage( "ERROR: allocation device host buffer result" );
        return FALSE;
    }
    return TRUE;
}
Esempio n. 16
0
void Shadows::update(Settings *settings, FRMMATRIX4X4& projIn, FRMMATRIX4X4& ModelviewIn,    float* fv3SunDirIn) {
    
    direction = FRMVECTOR3(fv3SunDirIn[0], fv3SunDirIn[1], fv3SunDirIn[2]);
    
    // update pssm matrices
    float znear = 1.0f;
    float zfar = 250.0f;
    float shadowRange = 200.0f;
    float shadow_distribute = 0.1f;//25f;

    FRMMATRIX4X4 invProj;
    inverse( (float *)&invProj, (float *)&projIn );

    //hack in a fast inverse
    FRMMATRIX4X4 imodelview;
    inverse((float *)& imodelview, (float *)& ModelviewIn);//inverse(mat4(fMat4ModelviewIn));//inverse(camera->getModelview());

    // ortho basis (incorrect solution for vertical direction)
    FRMVECTOR3 side = FrmVector3Normalize (FrmVector3Cross ( FRMVECTOR3(0.0f,0.0f,1.0f), direction));
    FRMVECTOR3 up = FrmVector3Normalize (FrmVector3Cross (direction, side));
    //vec3 side = normalize(cross(direction, vec3(0.0f,0.0f,1.0f)));
    //vec3 up = normalize(cross(direction, side));
    
    // bound frustum points
    FRMVECTOR3 points[8] = {
        FRMVECTOR3(-1.0f,-1.0f,-1.0f), FRMVECTOR3(1.0f,-1.0f,-1.0f), FRMVECTOR3(-1.0f,1.0f,-1.0f), FRMVECTOR3(1.0f,1.0f,-1.0f),
        FRMVECTOR3(-1.0f,-1.0f, 1.0f), FRMVECTOR3(1.0f,-1.0f, 1.0f), FRMVECTOR3(-1.0f,1.0f, 1.0f), FRMVECTOR3(1.0f,1.0f, 1.0f),
    };
    
    // world space bound frustum points
    for(int i = 0; i < 8; i++) {
        FRMVECTOR4 point = FrmVector4Transform( FRMVECTOR4( points[i].x, points[i].y, points[i].z, 1.0f), invProj );// mat4((float *)& invProj ) * vec4(points[i]);
        points[i] = FRMVECTOR3( point.x, point.y, point.z ) / point.w;
    }
    
    // world space bound frustum directions
    FRMVECTOR3 directions[4];
    for(int i = 0; i < 4; i++) {
        directions[i] = FrmVector3Normalize( points[i + 4] - points[i]);
    }
    
    // split bound frustum
    for(int i = 0; i < 4; i++) {
        
        float k0 = (float)(i + 0) / 4;
        float k1 = (float)(i + 1) / 4;
        float fmin = FrmLerp(shadow_distribute, znear * powf(zfar / znear,k0),znear + (zfar - znear) * k0);
        float fmax = FrmLerp(shadow_distribute, znear * powf(zfar / znear,k1),znear + (zfar - znear) * k1);
        
        // none flickering removal
        if( settings->getFlickering() == Settings::FLICKERING_NONE) 
        {
            
            BoundBox bb;
            for(int j = 0; j < 4; j++) {
                bb.expand(points[j] + (directions[j] * fmin));
                bb.expand(points[j] + (directions[j] * fmax));
            }
            BoundSphere bs(bb);
            

            //save out radius squared
            spheres[i] = FRMVECTOR4( FrmVector3TransformCoord( bs.getCenter(), imodelview), bs.getRadius() * bs.getRadius());

            FRMVECTOR3 target = FrmVector3TransformCoord( bs.getCenter(), imodelview );
            
            // This offset is applied to prevent far-plane clipping
            float zFarOffset = 10.0f;
            ortho( (float*)&projections[i], bs.getRadius(),-bs.getRadius(),bs.getRadius(),-bs.getRadius(), 0.1f, shadowRange - zFarOffset);
            modelviews[i] = FrmMatrixLookAtRH(target + (direction * shadowRange / 2.0f),target - (direction * shadowRange / 2.0f),up);
            
        }
        // exact flickering removal
        else
        {
            BoundBox bb;
            for(int j = 0; j < 4; j++) {
                bb.expand(points[j] + (directions[j] * fmin));
                bb.expand(points[j] + (directions[j] * fmax));
            }
            BoundSphere bs(bb);

            //save out radius squared
            spheres[i] = FRMVECTOR4( FrmVector3TransformCoord( bs.getCenter(), imodelview ), bs.getRadius() * bs.getRadius());
            
            float half_size = size / 2.0f;

            FRMVECTOR3 target = FrmVector3TransformCoord( bs.getCenter(), imodelview );

            float x = ceilf( FrmVector3Dot(target,up) * half_size / bs.getRadius()) * bs.getRadius() / half_size;
            float y = ceilf( FrmVector3Dot(target,side) * half_size / bs.getRadius()) * bs.getRadius() / half_size;
            target = up * x + side * y + (direction * FrmVector3Dot(target,direction));

            // This offset is applied to prevent far-plane clipping
            float zFarOffset = 10.0f;
            ortho( (float*)&projections[i],bs.getRadius(),-bs.getRadius(),bs.getRadius(),-bs.getRadius(), 0.1f, shadowRange - zFarOffset);
            modelviews[i] = FrmMatrixLookAtRH(target + (direction * shadowRange / 2.0f), target - (direction * shadowRange / 2.0f),up);
        }

        // Flip the texture coordinates for D3D
        int flipped = 1;

        modelviewprojections[i] = FrmMatrixMultiply( modelviews[i], projections[i]);

        if(settings->getTechnique() == Settings::TECHNIQUE_ATLAS) 
        {
            modelviewprojections[i] = FrmMatrixMultiply( FrmMatrixMultiply( FrmMatrixMultiply( modelviewprojections[i], FrmMatrixScale(0.25f,(flipped) ? -0.25f : 0.25f,0.5f) ),  FrmMatrixTranslate(0.25f,0.25f,0.5f)), FrmMatrixTranslate(0.5f * (i % 2),0.5f * (i / 2),0.0f));
        }
        else 
        {
            modelviewprojections[i] = FrmMatrixMultiply( FrmMatrixMultiply( modelviewprojections[i], FrmMatrixScale(0.5f,(flipped) ? -0.5f : 0.5f,0.5f)), FrmMatrixTranslate(0.5f,0.5f,0.5f));

        }

        FRMMATRIX4X4 invModel;

        inverse((float *)& invModel, (float *)& modelviews[i]);
        offsets[i] = FRMVECTOR3( invModel.M(3, 0), invModel.M(3, 1), invModel.M(3, 2));

    }
}
Esempio n. 17
0
//--------------------------------------------------------------------------------------
// Name: DrawGodRays()
// Desc: 
//--------------------------------------------------------------------------------------
VOID CSample31::DrawGodRays()
{
    FRMMATRIX4X4 MatModel            = FrmMatrixIdentity();
    FRMMATRIX4X4 MatModelView        = FrmMatrixMultiply( MatModel, m_matView );
    FRMMATRIX4X4 MatModelViewProj    = FrmMatrixMultiply( MatModelView, m_matProj );
    FRMMATRIX4X4 MatModelViewProjInv = FrmMatrixInverse( MatModelViewProj );

    FRMVECTOR3 LightPos = m_LightPos;
    FRMVECTOR4 ScreenLightPos = FrmVector3Transform( LightPos, MatModelViewProj );
    ScreenLightPos.x /= ScreenLightPos.w;
    ScreenLightPos.y /= ScreenLightPos.w;
    ScreenLightPos.z /= ScreenLightPos.w;

    // First, if the camera is pointed away from the light, don't draw light rays.
    // Screen space light rays don't work when the light is behind the camera.
    FRMVECTOR3 CamForward = FRMVECTOR3( MatModelViewProj.m[2][0], MatModelViewProj.m[2][1], MatModelViewProj.m[2][2] );
    FRMVECTOR3 Temp = m_LightPos - m_CameraPos;
    FRMVECTOR3 CamLightVec = FrmVector3Normalize( Temp );
    FLOAT32 FrontFace = FrmVector3Dot( CamForward, CamLightVec );

    // Only draw light rays if we're facing the light source
    if( FrontFace > 0.0f )
    {

        // Part 1: downsize the frame buffer to a smaller render target and
        // discriminate god ray occlusion shapes.
        {
            m_CutoutRT.SetFramebuffer();

            // Render a full-screen quad
            glClearColor( 0.04f, 0.04f, 0.04f, 1.0f );
            glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
            glDisable( GL_CULL_FACE );
            glDisable( GL_BLEND );
            glDisable( GL_DEPTH_TEST );

            FRMVECTOR3 Temp2 = m_CameraPos - m_LightPos;
            FLOAT32 DistanceToLight = FrmVector3Length( Temp2 );
            FLOAT32 DistanceThreshold = DistanceToLight + m_CutoutShader.OccluderThreshold;

            // attenuation
            FLOAT32 LightRadius = 0.5f;
            FLOAT32 LightPenumbra = 0.3f;

            // convert light radius to a screen space length
            FRMVECTOR3 Up = FRMVECTOR3( MatModelView.m[1][0], MatModelView.m[1][1], MatModelView.m[1][2] );
            FRMVECTOR3 LightLimbPos = m_LightPos + Up;
            FRMVECTOR4 ScreenLimbPos = FrmVector3Transform( LightLimbPos, MatModelViewProj );
            ScreenLimbPos.x /= ScreenLimbPos.w;
            ScreenLimbPos.y /= ScreenLimbPos.w;
            ScreenLimbPos.z /= ScreenLimbPos.w;
            FLOAT32 LightRadiusScreen = abs( ScreenLimbPos.y - ScreenLightPos.y );

            glUseProgram( m_CutoutShader.ShaderId );
            SetTexture( m_CutoutShader.DepthTextureId, m_OffscreenRT.DepthTextureHandle, 0 );
            SetTexture( m_CutoutShader.ColorTextureId, m_GodRayTexture->m_hTextureHandle, 1 );
            glUniform3f( m_CutoutShader.NearQAspectId, m_CutoutShader.NearFarQ.x, m_CutoutShader.NearFarQ.z, m_Aspect );
            glUniform4f( m_CutoutShader.OccluderParamsId, DistanceThreshold, m_CutoutShader.OccluderFadeout, LightRadiusScreen, LightPenumbra );
            glUniform2f( m_CutoutShader.ScreenLightPosId, ScreenLightPos.x, ScreenLightPos.y );

            RenderScreenAlignedQuadInv();
            
            m_CutoutRT.DetachFramebuffer();
        }

        // Part 2: downsize to a smaller render target.  this also blurs the cutout image as a bonus.
        {
            m_QuarterRT.SetFramebuffer();

            glDisable( GL_CULL_FACE );
            glDisable( GL_BLEND );
            glDisable( GL_DEPTH_TEST );

            glUseProgram( m_DownsizeShader.ShaderId );
            SetTexture( m_DownsizeShader.ColorTextureId, m_CutoutRT.TextureHandle, 0 );

            RenderScreenAlignedQuadInv();
            
            m_QuarterRT.DetachFramebuffer();
        }

        // Part 3: smear to create light rays
        GaussBlur( m_QuarterRT );
        {
            m_ScratchRT.SetFramebuffer();

            glUseProgram( m_RayExtruderShader.ShaderId );
            SetTexture( m_RayExtruderShader.RayTextureId, m_QuarterRT.TextureHandle, 0 );
            glUniform2f( m_RayExtruderShader.ScreenLightPosId, ScreenLightPos.x, ScreenLightPos.y );
            glUniform3f( m_RayExtruderShader.RayParamsId, m_Aspect, 0.0f, m_RayExtruderShader.RayLength * 0.25f );
            RenderScreenAlignedQuadInv();
            
            m_ScratchRT.DetachFramebuffer();
        }
        {
            m_QuarterRT.SetFramebuffer();

            glUseProgram( m_RayExtruderShader.ShaderId );
            SetTexture( m_RayExtruderShader.RayTextureId, m_ScratchRT.TextureHandle, 0 );
            glUniform2f( m_RayExtruderShader.ScreenLightPosId, ScreenLightPos.x, ScreenLightPos.y );
            glUniform3f( m_RayExtruderShader.RayParamsId, m_Aspect, 0.0f, m_RayExtruderShader.RayLength * 0.5f );
            RenderScreenAlignedQuadInv();
            
            m_QuarterRT.DetachFramebuffer();
        }
        {
            m_ScratchRT.SetFramebuffer();

            glUseProgram( m_RayExtruderShader.ShaderId );
            SetTexture( m_RayExtruderShader.RayTextureId, m_QuarterRT.TextureHandle, 0 );
            glUniform2f( m_RayExtruderShader.ScreenLightPosId, ScreenLightPos.x, ScreenLightPos.y );
            glUniform3f( m_RayExtruderShader.RayParamsId, m_Aspect, 0.0f, m_RayExtruderShader.RayLength * 0.75f );
            RenderScreenAlignedQuadInv();
            
            m_ScratchRT.DetachFramebuffer();
        }
        {
            m_QuarterRT.SetFramebuffer();

            glUseProgram( m_RayExtruderShader.ShaderId );
            SetTexture( m_RayExtruderShader.RayTextureId, m_ScratchRT.TextureHandle, 0 );
            glUniform2f( m_RayExtruderShader.ScreenLightPosId, ScreenLightPos.x, ScreenLightPos.y );
            glUniform3f( m_RayExtruderShader.RayParamsId, m_Aspect, 0.0f, m_RayExtruderShader.RayLength );
            RenderScreenAlignedQuadInv();
            
            m_QuarterRT.DetachFramebuffer();
        }
    }
    else
    {
        // The light is behind the camera.  Clear the quarter RT, then run the combine
        // pass as usual.

        m_QuarterRT.SetFramebuffer();
        glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
        
        m_QuarterRT.DetachFramebuffer();
    }


    // Part 3: combine rays with the original frame buffer
    {
        glBindFramebuffer( GL_FRAMEBUFFER, 0 );
        glViewport( 0, 0, m_nWidth, m_nHeight );

        glClearColor( 0.04f, 0.04f, 0.04f, 1.0f );
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
        glDisable( GL_CULL_FACE );
        glDisable( GL_BLEND );
        glDisable( GL_DEPTH_TEST );

        FRMVECTOR4 RayColor = FRMVECTOR4( 0.9f, 0.9f, 1.0f, 1.0f );

        glUseProgram( m_CombineShader.ShaderId );
        SetTexture( m_CombineShader.ColorTextureId, m_OffscreenRT.TextureHandle, 0 );
        SetTexture( m_CombineShader.RaysTextureId, m_QuarterRT.TextureHandle, 1 );
        glUniform1f( m_CombineShader.RayOpacityId, m_CombineShader.RayOpacity );
        glUniform4fv( m_CombineShader.RayColorId, 1, RayColor.v );

        RenderScreenAlignedQuadInv();
    }
}