/** * @brief * Constructor */ SPRTTShaders::SPRTTShaders(Renderer &cRenderer) : SPRTT(cRenderer), m_pRenderTarget(nullptr), m_pColorTarget1(nullptr), m_pColorTarget2(nullptr), m_pColorTarget3(nullptr), m_pSceneVertexShader(nullptr), m_pSceneFragmentShader(nullptr), m_pSceneProgram(nullptr), m_pVertexShader(nullptr), m_pFragmentShader(nullptr), m_pProgram(nullptr) { // Check/get number of supported color render targets uint8 nMaxColorTargets = 4; if (nMaxColorTargets > cRenderer.GetCapabilities().nMaxColorRenderTargets) nMaxColorTargets = cRenderer.GetCapabilities().nMaxColorRenderTargets; { // Render targets // Create the render target. We will create a very low resolution 2D texture buffer to see funny pixels. m_pRenderTarget = cRenderer.CreateSurfaceTextureBuffer2D(Vector2i(64, 64), TextureBuffer::R8G8B8, SurfaceTextureBuffer::Depth|SurfaceTextureBuffer::NoMultisampleAntialiasing, nMaxColorTargets); if (m_pRenderTarget && nMaxColorTargets > 1) { // Set additional color render targets if (nMaxColorTargets > 1 && !m_pColorTarget1) { Image cImage = Image::CreateImage(DataByte, ColorRGB, Vector3i(64, 64, 1)); m_pColorTarget1 = cRenderer.CreateTextureBuffer2D(cImage, TextureBuffer::Unknown, TextureBuffer::RenderTarget); } if (nMaxColorTargets > 2 && !m_pColorTarget2) { Image cImage = Image::CreateImage(DataByte, ColorRGB, Vector3i(64, 64, 1)); m_pColorTarget2 = cRenderer.CreateTextureBuffer2D(cImage, TextureBuffer::Unknown, TextureBuffer::RenderTarget); } if (nMaxColorTargets > 3 && !m_pColorTarget3) { Image cImage = Image::CreateImage(DataByte, ColorRGB, Vector3i(64, 64, 1)); m_pColorTarget3 = cRenderer.CreateTextureBuffer2D(cImage, TextureBuffer::Unknown, TextureBuffer::RenderTarget); } } } // Decide which shader language should be used (for example "GLSL" or "Cg") ShaderLanguage *pShaderLanguage = cRenderer.GetShaderLanguage(cRenderer.GetDefaultShaderLanguage()); if (pShaderLanguage) { { // Scene program (with MRT support) // Construct the string containing the fragment shader definitions String sDefinitions; if (m_pColorTarget1) sDefinitions += "#define MRT_1\n"; if (m_pColorTarget2) sDefinitions += "#define MRT_2\n"; if (m_pColorTarget3) sDefinitions += "#define MRT_3\n"; // Shader source code String sVertexShaderSourceCode; String sFragmentShaderSourceCode; if (pShaderLanguage->GetShaderLanguage() == "GLSL") { #include "SPRTTShaders_GLSL.h" if (cRenderer.GetAPI() == "OpenGL ES 2.0") { // Get shader source codes sVertexShaderSourceCode = "#version 100\n" + sSceneVertexShaderSourceCodeGLSL; sFragmentShaderSourceCode = "#version 100\n" + sDefinitions + sSceneFragmentShaderSourceCodeGLSL; } else { // Remove precision qualifiers so that we're able to use 120 (OpenGL 2.1 shaders) instead of 130 (OpenGL 3.0 shaders, // with this version we can keep the precision qualifiers) so that this shader requirements are as low as possible // -> In here we're using 120 instead of 110 because matrix casts are quite comfortable... sVertexShaderSourceCode = "#version 120\n" + Shader::RemovePrecisionQualifiersFromGLSL(sSceneVertexShaderSourceCodeGLSL); sFragmentShaderSourceCode = "#version 120\n" + sDefinitions + Shader::RemovePrecisionQualifiersFromGLSL(sSceneFragmentShaderSourceCodeGLSL); } } else if (pShaderLanguage->GetShaderLanguage() == "Cg") { #include "SPRTTShaders_Cg.h" sVertexShaderSourceCode = sSceneVertexShaderSourceCodeCg; sFragmentShaderSourceCode = sSceneFragmentShaderSourceCodeCg; } // Create a vertex shader instance // -> I define a Cg profile because when using an GLSL Cg profile (which is the default), the shader is not working correctly on my AMD/ATI ("AMD Catalyst™ 11.3") system while it worked on the tested NVIDIA system... m_pSceneVertexShader = pShaderLanguage->CreateVertexShader(sVertexShaderSourceCode, "arbvp1"); // Create a fragment shader instance // -> I define a Cg profile because when using an GLSL Cg profile (which is the default), the shader is not working correctly on my AMD/ATI ("AMD Catalyst™ 11.3") system while it worked on the tested NVIDIA system... m_pSceneFragmentShader = pShaderLanguage->CreateFragmentShader(sFragmentShaderSourceCode, "arbfp1"); // Create a program instance and assign the created vertex and fragment shaders to it m_pSceneProgram = pShaderLanguage->CreateProgram(m_pSceneVertexShader, m_pSceneFragmentShader); } { // Program // Shader source code String sVertexShaderSourceCode; String sFragmentShaderSourceCode; if (pShaderLanguage->GetShaderLanguage() == "GLSL") { #include "SPRTTShaders_GLSL.h" if (cRenderer.GetAPI() == "OpenGL ES 2.0") { // Get shader source codes sVertexShaderSourceCode = "#version 100\n" + sVertexShaderSourceCodeGLSL; sFragmentShaderSourceCode = "#version 100\n" + sFragmentShaderSourceCodeGLSL; } else { // Remove precision qualifiers so that we're able to use 110 (OpenGL 2.0 shaders) instead of 130 (OpenGL 3.0 shaders, // with this version we can keep the precision qualifiers) so that this shader requirements are as low as possible sVertexShaderSourceCode = "#version 110\n" + Shader::RemovePrecisionQualifiersFromGLSL(sVertexShaderSourceCodeGLSL); sFragmentShaderSourceCode = "#version 110\n" + Shader::RemovePrecisionQualifiersFromGLSL(sFragmentShaderSourceCodeGLSL); } } else if (pShaderLanguage->GetShaderLanguage() == "Cg") { #include "SPRTTShaders_Cg.h" sVertexShaderSourceCode = sVertexShaderSourceCodeCg; sFragmentShaderSourceCode = sFragmentShaderSourceCodeCg; } // Create a vertex shader instance // -> I define a Cg profile because when using an GLSL Cg profile (which is the default), the shader is not working correctly on my AMD/ATI ("AMD Catalyst™ 11.3") system while it worked on the tested NVIDIA system... m_pVertexShader = pShaderLanguage->CreateVertexShader(sVertexShaderSourceCode, "arbvp1"); // Create a fragment shader instance // -> I define a Cg profile because when using an GLSL Cg profile (which is the default), the shader is not working correctly on my AMD/ATI ("AMD Catalyst™ 11.3") system while it worked on the tested NVIDIA system... m_pFragmentShader = pShaderLanguage->CreateFragmentShader(sFragmentShaderSourceCode, "arbfp1"); // Create a program instance and assign the created vertex and fragment shaders to it m_pProgram = static_cast<ProgramWrapper*>(pShaderLanguage->CreateProgram(m_pVertexShader, m_pFragmentShader)); } } }