//[-------------------------------------------------------] //[ Private virtual SPMultiView functions ] //[-------------------------------------------------------] void SPMultiViewFixedFunctions::DrawScene(uint32 nScene) { // Get the used renderer Renderer &cRenderer = GetRenderer(); // Fixed functions support required FixedFunctions *pFixedFunctions = cRenderer.GetFixedFunctions(); if (pFixedFunctions) { { // Setup light FixedFunctions::Light sLight; pFixedFunctions->GetDefaultLightSettings(sLight); sLight.cAmbient.SetRGBA(0.1f, 0.1f, 0.1f, 1.0f); sLight.cDiffuse.SetRGBA(1.0f, 1.0f, 1.0f, 1.0f); sLight.nType = FixedFunctions::LightType::Point; sLight.vPosition.SetXYZ(0.0f, 0.0f, 1.5f); sLight.fLinearAttenuation = 0.3f; pFixedFunctions->SetTransformState(FixedFunctions::Transform::World, Matrix4x4::Identity); pFixedFunctions->SetLightEnabled(0, false); pFixedFunctions->SetLight (0, sLight); pFixedFunctions->SetLightEnabled(0, true); } { // Set the world matrix // Build a rotation matrix by using a given Euler angle around the y-axis Matrix4x4 mWorld; mWorld.FromEulerAngleY(static_cast<float>(m_fRotation*Math::DegToRad)); pFixedFunctions->SetTransformState(FixedFunctions::Transform::World, mWorld); } { // Set the view matrix Matrix4x4 mView; mView.SetTranslation(0.0f, 0.0f, -10.0f); pFixedFunctions->SetTransformState(FixedFunctions::Transform::View, mView); } { // Set the projection matrix Matrix4x4 mProj; const float fAspect = 1.0f; const float fAspectRadio = cRenderer.GetViewport().GetWidth()/(cRenderer.GetViewport().GetHeight()*fAspect); mProj.PerspectiveFov(static_cast<float>(45.0f*Math::DegToRad), fAspectRadio, 0.001f, 1000.0f); pFixedFunctions->SetTransformState(FixedFunctions::Transform::Projection, mProj); } // Draw the mesh handler representing the scene to draw switch (nScene) { case 0: m_pMeshHandlerSphere->Draw(); break; case 1: m_pMeshHandlerTorus->Draw(); break; case 2: m_pMeshHandlerCube->Draw(); break; } } }
//[-------------------------------------------------------] //[ Private virtual PLRenderer::SurfacePainter functions ] //[-------------------------------------------------------] void SPTriangleFixedFunctions::OnPaint(Surface &cSurface) { // Get the used renderer Renderer &cRenderer = GetRenderer(); // Clear the content of the current used render target by using gray (this way, in case on an graphics error we might still see at least something) cRenderer.Clear(Clear::Color | Clear::ZBuffer, Color4::Gray); // Fixed functions support required FixedFunctions *pFixedFunctions = cRenderer.GetFixedFunctions(); if (pFixedFunctions) { { // Set the world matrix // Build a rotation matrix by using a given Euler angle around the y-axis Matrix4x4 mWorld; mWorld.FromEulerAngleY(static_cast<float>(m_fRotation*Math::DegToRad)); pFixedFunctions->SetTransformState(FixedFunctions::Transform::World, mWorld); // Increase the rotation by the current time difference (time past since the last frame) // -> Normally, such work should NOT be performed within the rendering step, but we want // to keep the implementation simple in here... m_fRotation += Timing::GetInstance()->GetTimeDifference()*50; } { // Set the view matrix Matrix4x4 mView; mView.SetTranslation(0.0f, 0.0f, -5.0f); pFixedFunctions->SetTransformState(FixedFunctions::Transform::View, mView); } { // Set the projection matrix const float fAspect = 1.0f; const float fAspectRadio = cRenderer.GetViewport().GetWidth()/(cRenderer.GetViewport().GetHeight()*fAspect); Matrix4x4 mProj; mProj.PerspectiveFov(static_cast<float>(45.0f*Math::DegToRad), fAspectRadio, 0.001f, 1000.0f); pFixedFunctions->SetTransformState(FixedFunctions::Transform::Projection, mProj); } // Normally this vertex buffer we created is NEVER a null pointer, but in this sample // we want to go for sure if (m_pVertexBuffer) { // Bind our vertex buffer pFixedFunctions->SetVertexBuffer(m_pVertexBuffer); // No back face culling, please. Else we can only see one 'side' of the triangle cRenderer.SetRenderState(RenderState::CullMode, Cull::None); // Now draw the primitives of our cool triangle. // The primitive type is 'triangles', we start at vertex 0 and draw '3' vertices. cRenderer.DrawPrimitives(Primitive::TriangleList, 0, 3); } } }
//[-------------------------------------------------------] //[ Private virtual PLRenderer::SurfacePainter functions ] //[-------------------------------------------------------] void SPRTTShaders::OnPaint(Surface &cSurface) { // Get the used renderer Renderer &cRenderer = GetRenderer(); // Clear the content of the current used render target by using gray (this way, in case on an graphics error we might still see at least something) cRenderer.Clear(Clear::Color | Clear::ZBuffer, Color4::Gray); // Backup current render target and set the new one to render in our texture buffer Surface *pRenderSurfaceBackup = cRenderer.GetRenderTarget(); if (cRenderer.SetRenderTarget(m_pRenderTarget)) { if (m_pColorTarget1) cRenderer.SetColorRenderTarget(static_cast<TextureBuffer*>(m_pColorTarget1), 1); if (m_pColorTarget2) cRenderer.SetColorRenderTarget(static_cast<TextureBuffer*>(m_pColorTarget2), 2); if (m_pColorTarget3) cRenderer.SetColorRenderTarget(static_cast<TextureBuffer*>(m_pColorTarget3), 3); // Draw the scene DrawScene(cRenderer); // Reset render target cRenderer.SetRenderTarget(pRenderSurfaceBackup); } // This code is similar to the code of the triangle sample. But instead of a // triangle we will draw three rotating quadrangles. Further the used vertex // buffer has texture coordinates and we apply the 'teapot' texture buffer on the primitives. // Clear the content of the current used render target // Make our program to the current one if (cRenderer.SetProgram(m_pProgram)) { // Set program vertex attributes, this creates a connection between "Vertex Buffer Attribute" and "Vertex Shader Attribute" m_pProgram->Set("VertexPosition", m_pPositionVertexBuffer, VertexBuffer::Position); m_pProgram->Set("VertexTextureCoordinate", m_pPositionVertexBuffer, VertexBuffer::TexCoord); m_pProgram->Set("VertexColor", m_pColorVertexBuffer, VertexBuffer::Color); // Set color factor m_pProgram->Set("ColorFactor", 0.0f); // Calculate the composed view projection matrix - we need it multiple times Matrix4x4 mViewProjection; { // Calculate the view matrix Matrix4x4 mView; { mView.SetTranslation(0.0f, 0.0f, -5.0f); } // Calculate the projection matrix Matrix4x4 mProjection; { const float fAspect = 1.0f; const float fAspectRadio = cRenderer.GetViewport().GetWidth()/(cRenderer.GetViewport().GetHeight()*fAspect); mProjection.PerspectiveFov(static_cast<float>(45.0f*Math::DegToRad), fAspectRadio, 0.001f, 1000.0f); } // Calculate the composed view projection matrix mViewProjection = mProjection*mView; } // No back face culling, please. Else we can only see one 'side' of the quadrangle cRenderer.SetRenderState(RenderState::CullMode, Cull::None); Matrix4x4 mWorld; { // Draw quadrangle 1: Primary render target // Set object space to clip space matrix uniform ProgramUniform *pProgramUniform = m_pProgram->GetUniform("ObjectSpaceToClipSpaceMatrix"); if (pProgramUniform) { mWorld.SetTranslationMatrix(2.0f, 1.0f, 0.0f); pProgramUniform->Set(mViewProjection*mWorld); } { // Set the texture buffer we rendered our teapot in as the current texture buffer const int nTextureUnit = m_pProgram->Set("DiffuseMap", m_pRenderTarget->GetTextureBuffer()); if (nTextureUnit >= 0) { // Disable mip mapping - this is required because we created/filled no mipmaps for your texture buffer cRenderer.SetSamplerState(nTextureUnit, Sampler::MagFilter, TextureFiltering::Linear); cRenderer.SetSamplerState(nTextureUnit, Sampler::MinFilter, TextureFiltering::Linear); cRenderer.SetSamplerState(nTextureUnit, Sampler::MipFilter, TextureFiltering::None); } } // Draw cRenderer.DrawPrimitives(Primitive::TriangleStrip, 0, 4); } { // Draw quadrangle 2: Color render target 1 // Set object space to clip space matrix uniform ProgramUniform *pProgramUniform = m_pProgram->GetUniform("ObjectSpaceToClipSpaceMatrix"); if (pProgramUniform) { mWorld.FromEulerAngleY(static_cast<float>(m_fRotation*Math::DegToRad)); mWorld.SetTranslation(-2.0f, 1.0f, 0.0f); pProgramUniform->Set(mViewProjection*mWorld); } { // Set the texture buffer we rendered our teapot in as the current texture buffer const int nTextureUnit = m_pProgram->Set("DiffuseMap", m_pColorTarget1 ? static_cast<TextureBuffer*>(m_pColorTarget1) : m_pRenderTarget->GetTextureBuffer()); if (nTextureUnit >= 0) { // Disable mip mapping - this is required because we created/filled no mipmaps for your texture buffer cRenderer.SetSamplerState(nTextureUnit, Sampler::MagFilter, TextureFiltering::Linear); cRenderer.SetSamplerState(nTextureUnit, Sampler::MinFilter, TextureFiltering::Linear); cRenderer.SetSamplerState(nTextureUnit, Sampler::MipFilter, TextureFiltering::None); } } // Draw cRenderer.DrawPrimitives(Primitive::TriangleStrip, 0, 4); } { // Draw quadrangle 3: Color render target 2 // Set object space to clip space matrix uniform ProgramUniform *pProgramUniform = m_pProgram->GetUniform("ObjectSpaceToClipSpaceMatrix"); if (pProgramUniform) { mWorld.FromEulerAngleZ(static_cast<float>(m_fRotation*Math::DegToRad)); mWorld.SetTranslation(0.0f, 1.0f, 0.0f); pProgramUniform->Set(mViewProjection*mWorld); } { // Set the texture buffer we rendered our teapot in as the current texture buffer const int nTextureUnit = m_pProgram->Set("DiffuseMap", m_pColorTarget2 ? static_cast<TextureBuffer*>(m_pColorTarget2) : m_pRenderTarget->GetTextureBuffer()); if (nTextureUnit >= 0) { // Disable mip mapping - this is required because we created/filled no mipmaps for your texture buffer cRenderer.SetSamplerState(nTextureUnit, Sampler::MagFilter, TextureFiltering::Linear); cRenderer.SetSamplerState(nTextureUnit, Sampler::MinFilter, TextureFiltering::Linear); cRenderer.SetSamplerState(nTextureUnit, Sampler::MipFilter, TextureFiltering::None); } } // Draw cRenderer.DrawPrimitives(Primitive::TriangleStrip, 0, 4); } { // Draw quadrangle 4: Color render target 3 // Set object space to clip space matrix uniform ProgramUniform *pProgramUniform = m_pProgram->GetUniform("ObjectSpaceToClipSpaceMatrix"); if (pProgramUniform) { mWorld.FromEulerAngleZ(static_cast<float>(-m_fRotation*Math::DegToRad)); mWorld.SetTranslation(-2.0f, -1.0f, 0.0f); pProgramUniform->Set(mViewProjection*mWorld); } { // Set the texture buffer we rendered our teapot in as the current texture buffer const int nTextureUnit = m_pProgram->Set("DiffuseMap", m_pColorTarget3 ? static_cast<TextureBuffer*>(m_pColorTarget3) : m_pRenderTarget->GetTextureBuffer()); if (nTextureUnit >= 0) { // Disable mip mapping - this is required because we created/filled no mipmaps for your texture buffer cRenderer.SetSamplerState(nTextureUnit, Sampler::MagFilter, TextureFiltering::Linear); cRenderer.SetSamplerState(nTextureUnit, Sampler::MinFilter, TextureFiltering::Linear); cRenderer.SetSamplerState(nTextureUnit, Sampler::MipFilter, TextureFiltering::None); } } // Draw cRenderer.DrawPrimitives(Primitive::TriangleStrip, 0, 4); } { // Draw quadrangle 4: Primary render target, but with per vertex color - the primitive will be quite colorful :) // Set object space to clip space matrix uniform ProgramUniform *pProgramUniform = m_pProgram->GetUniform("ObjectSpaceToClipSpaceMatrix"); if (pProgramUniform) { mWorld.FromEulerAngleZ(static_cast<float>(-m_fRotation*Math::DegToRad)); mWorld.SetTranslation(2.0f, -1.0f, 0.0f); pProgramUniform->Set(mViewProjection*mWorld); } // Set color factor m_pProgram->Set("ColorFactor", 1.0f); { // Set the texture buffer we rendered our teapot in as the current texture buffer const int nTextureUnit = m_pProgram->Set("DiffuseMap", m_pRenderTarget->GetTextureBuffer()); if (nTextureUnit >= 0) { // Disable mip mapping - this is required because we created/filled no mipmaps for your texture buffer cRenderer.SetSamplerState(nTextureUnit, Sampler::MagFilter, TextureFiltering::Linear); cRenderer.SetSamplerState(nTextureUnit, Sampler::MinFilter, TextureFiltering::Linear); cRenderer.SetSamplerState(nTextureUnit, Sampler::MipFilter, TextureFiltering::None); } } // Draw cRenderer.DrawPrimitives(Primitive::TriangleStrip, 0, 4); } // Change the backface culling back to the default setting cRenderer.SetRenderState(RenderState::CullMode, Cull::CCW); } // Increase the rotation by the current time difference (time past since the last frame) // -> Normally, such work should NOT be performed within the rendering step, but we want // to keep the implementation simple in here... m_fRotation += Timing::GetInstance()->GetTimeDifference()*50; }
/** * @brief * Draws the scene */ void SPRTTShaders::DrawScene(Renderer &cRenderer) { // Clear the content of the current used render target by using gray (this way, in case on an graphics error we might still see at least something) cRenderer.Clear(Clear::Color | Clear::ZBuffer, Color4::Gray); // Make our program to the current one if (cRenderer.SetProgram(m_pSceneProgram)) { // Calculate the world matrix Matrix4x4 mWorld; { // Build a rotation matrix by using a given Euler angle around the y-axis mWorld.FromEulerAngleY(static_cast<float>(m_fRotation*Math::DegToRad)); } // Set program uniforms ProgramUniform *pProgramUniform = m_pSceneProgram->GetUniform("ObjectSpaceToClipSpaceMatrix"); if (pProgramUniform) { // Calculate the view matrix Matrix4x4 mView; { mView.SetTranslation(0.0f, -0.1f, -0.5f); } // Calculate the projection matrix Matrix4x4 mProjection; { const float fAspect = 1.0f; const float fAspectRadio = cRenderer.GetViewport().GetWidth()/(cRenderer.GetViewport().GetHeight()*fAspect); mProjection.PerspectiveFov(static_cast<float>(45.0f*Math::DegToRad), fAspectRadio, 0.001f, 1000.0f); } // Calculate the final composed world view projection matrix const Matrix4x4 mWorldViewProjection = mProjection*mView*mWorld; // Set object space to clip space matrix uniform pProgramUniform->Set(mWorldViewProjection); } // Set object space to world space matrix uniform pProgramUniform = m_pSceneProgram->GetUniform("ObjectSpaceToWorldSpaceMatrix"); if (pProgramUniform) pProgramUniform->Set(mWorld); // Set world space light direction pProgramUniform = m_pSceneProgram->GetUniform("LightDirection"); if (pProgramUniform) pProgramUniform->Set(Vector3::UnitZ); // Get the used mesh const Mesh *pMesh = m_pMeshHandler->GetMesh(); if (pMesh) { // Get the mesh LOD level to use const MeshLODLevel *pLODLevel = pMesh->GetLODLevel(0); if (pLODLevel && pLODLevel->GetIndexBuffer()) { // Get and use the index buffer of the mesh LOD level cRenderer.SetIndexBuffer(pLODLevel->GetIndexBuffer()); // Get the vertex buffer of the mesh handler VertexBuffer *pVertexBuffer = m_pMeshHandler->GetVertexBuffer(); if (pVertexBuffer) { // Set program vertex attributes, this creates a connection between "Vertex Buffer Attribute" and "Vertex Shader Attribute" ProgramAttribute *pProgramAttribute = m_pSceneProgram->GetAttribute("VertexPosition"); if (pProgramAttribute) pProgramAttribute->Set(pVertexBuffer, VertexBuffer::Position); pProgramAttribute = m_pSceneProgram->GetAttribute("VertexNormal"); if (pProgramAttribute) pProgramAttribute->Set(pVertexBuffer, VertexBuffer::Normal); // Loop through all geometries of the mesh const Array<Geometry> &lstGeometries = *pLODLevel->GetGeometries(); for (uint32 nGeo=0; nGeo<lstGeometries.GetNumOfElements(); nGeo++) { // Is this geometry active? const Geometry &cGeometry = lstGeometries[nGeo]; if (cGeometry.IsActive()) { // Draw the geometry cRenderer.DrawIndexedPrimitives( cGeometry.GetPrimitiveType(), 0, pVertexBuffer->GetNumOfElements()-1, cGeometry.GetStartIndex(), cGeometry.GetIndexSize() ); } } } } } } }