//-------------------------------------------------------------------------------------- // 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 ); }
//-------------------------------------------------------------------------------------- // 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 ); }
//-------------------------------------------------------------------------------------- // 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; }
//-------------------------------------------------------------------------------------- // 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 ); }
//-------------------------------------------------------------------------------------- // 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 ); }
//-------------------------------------------------------------------------------------- // 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; }
//-------------------------------------------------------------------------------------- // 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 ); }
//-------------------------------------------------------------------------------------- // 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; }
//-------------------------------------------------------------------------------------- // 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() ); }
//-------------------------------------------------------------------------------------- // 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 ); }
//-------------------------------------------------------------------------------------- // 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; }
//-------------------------------------------------------------------------------------- // 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; }
//-------------------------------------------------------------------------------------- // 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 ); }
//-------------------------------------------------------------------------------------- // 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; }
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)); } }
//-------------------------------------------------------------------------------------- // 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(); } }