1b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu/****************************************************************************** 2b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 33e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens @File OGLES3ColourGrading.cpp 4b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 5b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Title Colour grading 6b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 7b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Version 8b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 9b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Copyright Copyright (c) Imagination Technologies Limited. 10b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 11b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Platform Independent 12b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 13b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Description Demonstrates how to colour grade your render. 14b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 15b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu ******************************************************************************/ 16b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu#include "PVRShell.h" 173e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens#include "OGLES3Tools.h" 18b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 19b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu/****************************************************************************** 20b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu Constants 21b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu ******************************************************************************/ 22b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetuconst char* const c_pszMaskTexture = "MaskTexture.pvr"; 23b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetuconst char* const c_pszBackgroundTexture = "Background.pvr"; 24b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 25b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu// Our colour lookup tables 26b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetuconst char* const c_pszLUTs[] = 27b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu{ 28b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu "identity.pvr", 29b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu "bw.pvr", 30b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu "cooler.pvr", 31b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu "warmer.pvr", 32b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu "sepia.pvr", 33b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu "inverted.pvr", 34b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu "highcontrast.pvr", 35b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu "bluewhitegradient.pvr" 36b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu}; 37b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 38b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu// Shader source 39b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetuconst char* const c_szFragShaderSrcFile = "FragShader.fsh"; 40b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetuconst char* const c_szVertShaderSrcFile = "VertShader.vsh"; 41b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetuconst char* const c_szSceneFragShaderSrcFile = "SceneFragShader.fsh"; 42b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetuconst char* const c_szSceneVertShaderSrcFile = "SceneVertShader.vsh"; 43b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetuconst char* const c_szBackgroundFragShaderSrcFile = "BackgroundFragShader.fsh"; 44b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 45b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu// POD scene files 46b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetuconst char c_szSceneFile[] = "Mask.pod"; 47b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 48b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu// Camera constants. Used for making the projection matrix 49b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetuconst float CAM_FOV = PVRT_PI / 6; 50b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetuconst float CAM_NEAR = 4.0f; 51b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetuconst float CAM_FAR = 5000.0f; 52b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 53b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu// Index to bind the attributes to vertex shaders 54b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetuconst int VERTEX_ARRAY = 0; 55b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetuconst int TEXCOORD_ARRAY = 1; 56b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetuconst int NORMAL_ARRAY = 2; 57b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 58b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu// Look up table enumeration 59b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetuenum ELUTs 60b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu{ 61b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu eIdentity, 62b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu eBW, 63b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu eCooler, 64b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu eWarmer, 65b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu eSepia, 66b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu eInverted, 67b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu eHighContrast, 68b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu eBlueWhiteGradient, 69b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu eLast, 70b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 71b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // The range to cycle through 72b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu eA = eBW, 73b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu eB = eBlueWhiteGradient 74b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu}; 75b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 76b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetuconst char* const c_pszLUTNames[] = 77b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu{ 78b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu "Identity", 79b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu "Black and white", 80b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu "Cooler", 81b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu "Warmer", 82b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu "Sepia", 83b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu "Inverted", 84b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu "High Contrast", 85b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu "Blue White Gradient" 86b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu}; 87b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 88b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu/*!**************************************************************************** 89b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu Class implementing the PVRShell functions. 90b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu ******************************************************************************/ 913e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capensclass OGLES3ColourGrading : public PVRShell 92b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu{ 93b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Print3D object 94b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu CPVRTPrint3D m_Print3D; 95b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 96b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Texture handle 97b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLuint m_uiMaskTexture; 98b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLuint m_uiBackgroundTexture; 99b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLuint m_uiLUTs[eLast]; 100b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu int m_iCurrentLUT; 101b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 102b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // VBO handle 103b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLuint m_ui32FullScreenRectVBO; 104b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 105b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Stride for vertex data 106b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu unsigned int m_ui32VertexStride; 107b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 108b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // 3D Model 109b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu CPVRTModelPOD m_Mask; 110b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLuint* m_puiMaskVBO; 111b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLuint* m_puiMaskIBO; 112b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 113b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLuint m_ui32BackgroundVBO; 114b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 115b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Projection and view matrices 116b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu PVRTMat4 m_mViewProjection; 117b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 118b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Shaders 119b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLuint m_uiPostVertShader; 120b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLuint m_uiPostFragShader; 121b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 122b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu struct 123b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 124b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLuint uiId; 125b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 126b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu m_PostShaderProgram; 127b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 128b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLuint m_uiBackgroundFragShader; 129b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 130b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu struct 131b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 132b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLuint uiId; 133b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 134b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu m_BackgroundShaderProgram; 135b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 136b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLuint m_uiSceneVertShader; 137b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLuint m_uiSceneFragShader; 138b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 139b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu struct 140b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 141b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLuint uiId; 142b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLuint uiMVPMatrixLoc; 143b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLuint uiLightDirLoc; 144b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLuint uiMaterialBiasLoc; 145b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLuint uiMaterialScaleLoc; 146b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 147b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu m_SceneShaderProgram; 148b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 149b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Render contexts, etc 150b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLint m_i32OriginalFbo; 151b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 152b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Texture IDs used by the app 153b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLuint m_uiTextureToRenderTo; 154b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 155b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Handle for our FBO and the depth buffer that it requires 156b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLuint m_uiFBO; 157b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 158b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Handle for our multi-sampled FBO and the depth buffer that it requires 159b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLuint m_uiFBOMultisampled; 160b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLuint m_uiDepthBufferMultisampled; 161b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLuint m_uiColourBufferMultisampled; 162b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 163b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Start time 164b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu unsigned long m_ulStartTime; 165b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 166b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetupublic: 167b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // PVRShell functions 168b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu virtual bool InitApplication(); 169b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu virtual bool InitView(); 170b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu virtual bool ReleaseView(); 171b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu virtual bool QuitApplication(); 172b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu virtual bool RenderScene(); 173b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 174b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetuprivate: 175b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu bool LoadShaders(CPVRTString& ErrorStr); 176b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu bool CreateFBO(); 177b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu void LoadVbos(const bool bRotated); 178b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu void DrawMesh(const int i32NodeIndex); 179b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu}; 180b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 181b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 182b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu/*!**************************************************************************** 183b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Function InitApplication 184b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Return bool true if no error occurred 185b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Description Code in InitApplication() will be called by PVRShell once per 186b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu run, before the rendering context is created. 187b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu Used to initialize variables that are not dependent on it 188b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu (e.g. external modules, loading meshes, etc.) 189b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu If the rendering context is lost, InitApplication() will 190b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu not be called again. 191b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu ******************************************************************************/ 1923e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capensbool OGLES3ColourGrading::InitApplication() 193b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu{ 194b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Get and set the read path for content files 195b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu CPVRTResourceFile::SetReadPath((char*)PVRShellGet(prefReadPath)); 196b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 197b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Get and set the load/release functions for loading external files. 198b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // In the majority of cases the PVRShell will return NULL function pointers implying that 199b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // nothing special is required to load external files. 200b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu CPVRTResourceFile::SetLoadReleaseFunctions(PVRShellGet(prefLoadFileFunc), PVRShellGet(prefReleaseFileFunc)); 201b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 202b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Load the scene 203b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu if(m_Mask.ReadFromFile(c_szSceneFile) != PVR_SUCCESS) 204b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 205b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu PVRShellSet(prefExitMessage, "ERROR: Couldn't load the .pod file\n"); 206b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu return false; 207b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 208b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 209b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Initialise some variables 210b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu m_puiMaskVBO = m_puiMaskIBO = 0; 211b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu m_iCurrentLUT = eA; 212b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu return true; 213b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu} 214b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 215b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu/*!**************************************************************************** 216b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Function QuitApplication 217b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Return bool true if no error occurred 218b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Description Code in QuitApplication() will be called by PVRShell once per 219b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu run, just before exiting the program. 220b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu If the rendering context is lost, QuitApplication() will 221b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu not be called. 222b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu ******************************************************************************/ 2233e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capensbool OGLES3ColourGrading::QuitApplication() 224b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu{ 225b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Free the memory allocated for the scene 226b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu m_Mask.Destroy(); 227b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 228b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu delete[] m_puiMaskVBO; 229b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu m_puiMaskVBO = 0; 230b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 231b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu delete[] m_puiMaskIBO; 232b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu m_puiMaskIBO = 0; 233b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu return true; 234b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu} 235b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 236b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu/*!**************************************************************************** 237b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Function LoadEffects 238b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Output ErrorStr A description of an error, if one occurs. 239b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Return bool true if no error occurred 240b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Description Loads and parses the bundled PFX and generates the various 241b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu effect objects. 242b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu ******************************************************************************/ 2433e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capensbool OGLES3ColourGrading::LoadShaders(CPVRTString& ErrorStr) 244b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu{ 245b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Load and compile the shaders from files. 246b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu if(PVRTShaderLoadFromFile(NULL, c_szVertShaderSrcFile, GL_VERTEX_SHADER, GL_SGX_BINARY_IMG, &m_uiPostVertShader, &ErrorStr) != PVR_SUCCESS) 247b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 248b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu return false; 249b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 250b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 251b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu if(PVRTShaderLoadFromFile(NULL, c_szFragShaderSrcFile, GL_FRAGMENT_SHADER, GL_SGX_BINARY_IMG, &m_uiPostFragShader, &ErrorStr) != PVR_SUCCESS) 252b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 253b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu return false; 254b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 255b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 256b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Setup and link the shader program 257b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu const char* aszAttribs[] = { "inVertex", "inTexCoord" }; 258b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu if(PVRTCreateProgram(&m_PostShaderProgram.uiId, m_uiPostVertShader, m_uiPostFragShader, aszAttribs, 2, &ErrorStr) != PVR_SUCCESS) 259b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 260b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu return false; 261b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 262b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 263b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Set the sampler variables to their respective texture unit 264b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glUniform1i(glGetUniformLocation(m_PostShaderProgram.uiId, "sTexture"), 0); 265b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glUniform1i(glGetUniformLocation(m_PostShaderProgram.uiId, "sColourLUT"), 1); 266b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 267b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Background shader 268b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 269b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu if(PVRTShaderLoadFromFile(NULL, c_szBackgroundFragShaderSrcFile, GL_FRAGMENT_SHADER, GL_SGX_BINARY_IMG, &m_uiBackgroundFragShader, &ErrorStr) != PVR_SUCCESS) 270b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 271b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu return false; 272b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 273b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 274b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Set up and link the shader program re-using the vertex shader from the main shader program 275b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu const char* aszBackgroundAttribs[] = { "inVertex", "inTexCoord" }; 276b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu if(PVRTCreateProgram(&m_BackgroundShaderProgram.uiId, m_uiPostVertShader, m_uiBackgroundFragShader, aszBackgroundAttribs, 2, &ErrorStr) != PVR_SUCCESS) 277b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 278b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu return false; 279b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 280b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 281b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Set the sampler2D variable to the first texture unit 282b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glUniform1i(glGetUniformLocation(m_BackgroundShaderProgram.uiId, "sTexture"), 0); 283b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 284b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Scene shaders - Used for rendering the mask 285b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu if(PVRTShaderLoadFromFile(NULL, c_szSceneVertShaderSrcFile, GL_VERTEX_SHADER, GL_SGX_BINARY_IMG, &m_uiSceneVertShader, &ErrorStr) != PVR_SUCCESS) 286b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 287b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu return false; 288b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 289b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 290b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu if(PVRTShaderLoadFromFile(NULL, c_szSceneFragShaderSrcFile, GL_FRAGMENT_SHADER, GL_SGX_BINARY_IMG, &m_uiSceneFragShader, &ErrorStr) != PVR_SUCCESS) 291b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 292b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu return false; 293b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 294b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 295b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Setup and link the shader program 296b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu const char* aszSceneAttribs[] = { "inVertex", "inTexCoord", "inNormal" }; 297b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu if (PVRTCreateProgram(&m_SceneShaderProgram.uiId, m_uiSceneVertShader, m_uiSceneFragShader, aszSceneAttribs, 3, &ErrorStr) != PVR_SUCCESS) 298b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 299b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu return false; 300b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 301b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 302b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Set the sampler2D variable to the first texture unit 303b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glUniform1i(glGetUniformLocation(m_SceneShaderProgram.uiId, "sTexture"), 0); 304b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 305b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Store the location of uniforms for later use 306b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu m_SceneShaderProgram.uiMVPMatrixLoc = glGetUniformLocation(m_SceneShaderProgram.uiId, "MVPMatrix"); 307b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu m_SceneShaderProgram.uiLightDirLoc = glGetUniformLocation(m_SceneShaderProgram.uiId, "LightDirection"); 308b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu m_SceneShaderProgram.uiMaterialBiasLoc = glGetUniformLocation(m_SceneShaderProgram.uiId, "MaterialBias"); 309b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu m_SceneShaderProgram.uiMaterialScaleLoc = glGetUniformLocation(m_SceneShaderProgram.uiId, "MaterialScale"); 310b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 311b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Set default shader material uniforms 312b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu float fSpecularConcentration = 0.6f; // a value from 0 to 1 (wider, concentrated) 313b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu float fSpecularIntensity = 0.3f; // a value from 0 to 1 314b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 315b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Specular bias 316b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glUniform1f(m_SceneShaderProgram.uiMaterialBiasLoc, fSpecularConcentration); 317b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Specular intensity scale 318b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glUniform1f(m_SceneShaderProgram.uiMaterialScaleLoc, fSpecularIntensity / (1.0f - fSpecularConcentration)); 319b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 320b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu return true; 321b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu} 322b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 323b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu/*!**************************************************************************** 324b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Function LoadVbos 325b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Description Loads the mesh data required for this training course into 326b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu vertex buffer objects 327b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu******************************************************************************/ 3283e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capensvoid OGLES3ColourGrading::LoadVbos(const bool bRotated) 329b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu{ 330b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu if(!m_puiMaskVBO) 331b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu m_puiMaskVBO = new GLuint[m_Mask.nNumMesh]; 332b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 333b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu if(!m_puiMaskIBO) 334b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu m_puiMaskIBO = new GLuint[m_Mask.nNumMesh]; 335b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 336b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu /* 337b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu Load vertex data of all meshes in the scene into VBOs 338b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 339b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu The meshes have been exported with the "Interleave Vectors" option, 340b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu so all data is interleaved in the buffer at pMesh->pInterleaved. 341b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu Interleaving data improves the memory access pattern and cache efficiency, 342b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu thus it can be read faster by the hardware. 343b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu */ 344b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glGenBuffers(m_Mask.nNumMesh, m_puiMaskVBO); 345b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu for(unsigned int i = 0; i < m_Mask.nNumMesh; ++i) 346b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 347b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Load vertex data into buffer object 348b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu SPODMesh& Mesh = m_Mask.pMesh[i]; 349b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu unsigned int uiSize = Mesh.nNumVertex * Mesh.sVertex.nStride; 350b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glBindBuffer(GL_ARRAY_BUFFER, m_puiMaskVBO[i]); 351b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glBufferData(GL_ARRAY_BUFFER, uiSize, Mesh.pInterleaved, GL_STATIC_DRAW); 352b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 353b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Load index data into buffer object if available 354b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu m_puiMaskIBO[i] = 0; 355b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu if (Mesh.sFaces.pData) 356b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 357b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glGenBuffers(1, &m_puiMaskIBO[i]); 358b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu uiSize = PVRTModelPODCountIndices(Mesh) * sizeof(GLshort); 359b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiMaskIBO[i]); 360b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glBufferData(GL_ELEMENT_ARRAY_BUFFER, uiSize, Mesh.sFaces.pData, GL_STATIC_DRAW); 361b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 362b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 363b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 364b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Create VBO for the fullscreen rect that we'll be rendering our FBO to 365b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 366b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Interleaved vertex data 367b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLfloat afVertices[] = { 368b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Left quad 369b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu -1.0f, 1.0f, 0.0f, 1.0f, // Pos 370b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 0.0f, 1.0f, // UVs 371b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 372b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu -1.0f, -1.0f, 0.0f, 1.0f, 373b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 0.0f, 0.0f, 374b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 375b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 0.0f, 1.0f, 0.0f, 1.0f, 376b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 0.5f, 1.0f, 377b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 378b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 0.0f, -1.0f, 0.0f, 1.0f, 379b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 0.5f, 0.0f, 380b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 381b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 1.0f, 1.0f, 0.0f, 1.0f, 382b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 1.0f, 1.0f, 383b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 384b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 1.0f, -1.0f, 0.0f, 1.0f, 385b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 1.0f, 0.0f, 386b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu }; 387b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 388b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu if(bRotated) // If we're rotated then pre-process the fullscreen rect's geometry to compensate 389b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 390b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu for(unsigned int i = 0; i < 6; ++i) 391b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 392b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu float fTmp = afVertices[i * 6 + 1]; 393b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu afVertices[i * 6 + 1] = afVertices[i * 6]; 394b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu afVertices[i * 6] = fTmp; 395b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 396b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu fTmp = afVertices[i * 6 + 5]; 397b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu afVertices[i * 6 + 5] = afVertices[i * 6 + 4]; 398b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu afVertices[i * 6 + 4] = fTmp; 399b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 400b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 401b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 402b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glGenBuffers(1, &m_ui32FullScreenRectVBO); 403b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu m_ui32VertexStride = 6 * sizeof(GLfloat); // 4 floats for the pos, 2 for the UVs 404b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 405b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Bind the VBO 406b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glBindBuffer(GL_ARRAY_BUFFER, m_ui32FullScreenRectVBO); 407b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 408b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Set the buffer's data 409b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glBufferData(GL_ARRAY_BUFFER, 6 * m_ui32VertexStride, afVertices, GL_STATIC_DRAW); 410b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 411b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Create the VBO for the background 412b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLfloat afBackgroundVertices[] = { 413b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Left quad 414b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu -1.0f, 1.0f, 0.0f, 1.0f, // Pos 415b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 0.0f, 1.0f, // UVs 416b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 417b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu -1.0f, -1.0f, 0.0f, 1.0f, 418b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 0.0f, 0.0f, 419b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 420b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 1.0f, 1.0f, 0.0f, 1.0f, 421b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 1.0f, 1.0f, 422b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 423b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 1.0f, -1.0f, 0.0f, 1.0f, 424b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 1.0f, 0.0f, 425b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu }; 426b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 427b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu if(bRotated) // If we're rotated then pre-process the background geometry 428b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 429b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu for(unsigned int i = 0; i < 4; ++i) 430b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 431b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu float fTmp = afBackgroundVertices[i * 6 + 1]; 432b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu afBackgroundVertices[i * 6 + 1] = -afBackgroundVertices[i * 6]; 433b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu afBackgroundVertices[i * 6] = -fTmp; 434b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 435b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 436b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 437b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glGenBuffers(1, &m_ui32BackgroundVBO); 438b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 439b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Bind the VBO 440b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glBindBuffer(GL_ARRAY_BUFFER, m_ui32BackgroundVBO); 441b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 442b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Set the buffer's data 443b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glBufferData(GL_ARRAY_BUFFER, 4 * m_ui32VertexStride, afBackgroundVertices, GL_STATIC_DRAW); 444b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 445b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Unbind our buffers 446b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glBindBuffer(GL_ARRAY_BUFFER, 0); 447b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 448b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu} 449b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 4503e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capensbool OGLES3ColourGrading::CreateFBO() 451b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu{ 452b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0 }; 453b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 454b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Query the max amount of samples that are supported, we are going to use the max 455b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLint samples; 4563e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glGetIntegerv(GL_MAX_SAMPLES, &samples); 457b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 458b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Get the currently bound frame buffer object. On most platforms this just gives 0. 459b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glGetIntegerv(GL_FRAMEBUFFER_BINDING, &m_i32OriginalFbo); 460b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 461b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Create a texture for rendering to 462b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glGenTextures(1, &m_uiTextureToRenderTo); 463b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glBindTexture(GL_TEXTURE_2D, m_uiTextureToRenderTo); 4643e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, PVRShellGet(prefWidth), PVRShellGet(prefHeight), 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 465b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 466b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 467b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 468b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 469b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 470b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Create the object that will allow us to render to the aforementioned texture 471b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glGenFramebuffers(1, &m_uiFBO); 472b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glBindFramebuffer(GL_FRAMEBUFFER, m_uiFBO); 4733e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens 4743e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glDrawBuffers(1, drawBuffers); 4753e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glReadBuffer(GL_COLOR_ATTACHMENT0); 476b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 477b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Attach the texture to the FBO 478b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_uiTextureToRenderTo, 0); 479b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 480b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Check that our FBO creation was successful 481b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu GLuint uStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); 482b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu if(uStatus != GL_FRAMEBUFFER_COMPLETE) 483b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 484b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu PVRShellSet(prefExitMessage, "ERROR: Failed to initialise FBO"); 485b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu return false; 486b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 487b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 4883e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens // Create and initialize the multi-sampled FBO. 489b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 4903e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens // Create the object that will allow us to render to the aforementioned texture 4913e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glGenFramebuffers(1, &m_uiFBOMultisampled); 4923e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glBindFramebuffer(GL_FRAMEBUFFER, m_uiFBOMultisampled); 4933e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens 4943e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glDrawBuffers(1, drawBuffers); 4953e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glReadBuffer(GL_COLOR_ATTACHMENT0); 496b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 4973e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens // Generate and bind a render buffer which will become a multisampled depth buffer shared between our two FBOs 4983e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glGenRenderbuffers(1, &m_uiDepthBufferMultisampled); 4993e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glBindRenderbuffer(GL_RENDERBUFFER, m_uiDepthBufferMultisampled); 5003e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT24, PVRShellGet(prefWidth), PVRShellGet(prefHeight)); 501b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 5023e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glGenRenderbuffers(1, &m_uiColourBufferMultisampled); 5033e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glBindRenderbuffer(GL_RENDERBUFFER, m_uiColourBufferMultisampled); 5043e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_RGB8, PVRShellGet(prefWidth), PVRShellGet(prefHeight)); 5053e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glBindRenderbuffer(GL_RENDERBUFFER, 0); 506b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 5073e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens // Attach the multisampled depth buffer we created earlier to our FBO. 5083e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_uiDepthBufferMultisampled); 509b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 5103e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens // Attach the multisampled colour renderbuffer to the FBO 5113e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_uiColourBufferMultisampled); 512b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 5133e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens // Check that our FBO creation was successful 5143e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens uStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); 5153e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens if(uStatus != GL_FRAMEBUFFER_COMPLETE) 5163e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens { 5173e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens PVRShellSet(prefExitMessage, "ERROR: Failed to initialise multisampled FBO"); 5183e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens return false; 5193e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens } 520b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 521b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Unbind the frame buffer object so rendering returns back to the backbuffer 522b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glBindFramebuffer(GL_FRAMEBUFFER, m_i32OriginalFbo); 523b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 524b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu return true; 525b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu} 526b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 527b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu/*!**************************************************************************** 528b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Function InitView 529b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Return bool true if no error occurred 530b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Description Code in InitView() will be called by PVRShell upon 531b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu initialization or after a change in the rendering context. 532b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu Used to initialize variables that are dependent on the rendering 533b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu context (e.g. textures, vertex buffers, etc.) 534b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu ******************************************************************************/ 5353e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capensbool OGLES3ColourGrading::InitView() 536b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu{ 537b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Initialize the textures used by Print3D. 538b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen); 539b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 540b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu if(m_Print3D.SetTextures(0, PVRShellGet(prefWidth), PVRShellGet(prefHeight), bRotate) != PVR_SUCCESS) 541b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 542b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu PVRShellSet(prefExitMessage, "ERROR: Cannot initialise Print3D\n"); 543b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu return false; 544b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 545b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 546b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Create the texture 547b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu if(PVRTTextureLoadFromPVR(c_pszMaskTexture, &m_uiMaskTexture) != PVR_SUCCESS) 548b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 549b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu PVRShellSet(prefExitMessage, "ERROR: Failed to load mask texture\n"); 550b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu return false; 551b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 552b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 553b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu if(PVRTTextureLoadFromPVR(c_pszBackgroundTexture, &m_uiBackgroundTexture) != PVR_SUCCESS) 554b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 555b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu PVRShellSet(prefExitMessage, "ERROR: Failed to load background texture\n"); 556b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu return false; 557b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 558b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 559b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Load our 3D texture look up tables 560b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu for(unsigned int i = 0; i < eLast; ++i) 561b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 562b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu if(PVRTTextureLoadFromPVR(c_pszLUTs[i], &m_uiLUTs[i]) != PVR_SUCCESS) 563b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 564b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu PVRShellSet(prefExitMessage, "ERROR: Failed to load a 3D texture\n"); 565b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu return false; 566b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 567b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 5683e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 5693e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 5703e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 571b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 5723e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 5733e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 574b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 575b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 576b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Load the effects 577b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu CPVRTString ErrorStr; 578b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu if(!LoadShaders(ErrorStr)) 579b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 580b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu PVRShellSet(prefExitMessage, ErrorStr.c_str()); 581b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu return false; 582b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 583b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 584b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Create FBOs 585b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu if(!CreateFBO()) 586b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 587b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu PVRShellSet(prefExitMessage, "Failed to create FBO"); 588b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu return false; 589b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 590b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 591b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Initialise VBO data 592b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu LoadVbos(bRotate); 593b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 594b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Calculate the projection and view matrices 595b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu float fAspect = PVRShellGet(prefWidth) / (float)PVRShellGet(prefHeight); 596b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu m_mViewProjection = PVRTMat4::PerspectiveFovRH(CAM_FOV, fAspect, CAM_NEAR, CAM_FAR, PVRTMat4::OGL, bRotate); 597b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu m_mViewProjection *= PVRTMat4::LookAtRH(PVRTVec3(0.f, 0.f, 150.f), PVRTVec3(0.f), PVRTVec3(0.f, 1.f, 0.f)); 598b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 599b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Enable backface culling and depth test 600b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glEnable(GL_CULL_FACE); 601b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glEnable(GL_DEPTH_TEST); 602b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 603b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Set the clear colour 604b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glClearColor(1.0f, 0.0f, 0.0f, 1.0f); 605b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 606b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Store initial time 607b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu m_ulStartTime = PVRShellGetTime(); 608b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 609b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu return true; 610b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu} 611b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 612b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu/*!**************************************************************************** 613b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Function ReleaseView 614b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Return bool true if no error occurred 615b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Description Code in ReleaseView() will be called by PVRShell when the 616b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu application quits or before a change in the rendering context. 617b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu ******************************************************************************/ 6183e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capensbool OGLES3ColourGrading::ReleaseView() 619b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu{ 620b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Frees the texture 621b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDeleteTextures(1, &m_uiMaskTexture); 622b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDeleteTextures(1, &m_uiBackgroundTexture); 623b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDeleteTextures(eLast, m_uiLUTs); 624b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDeleteTextures(1, &m_uiTextureToRenderTo); 625b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 626b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Release Vertex buffer object. 627b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDeleteBuffers(1, &m_ui32FullScreenRectVBO); 628b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDeleteBuffers(1, &m_ui32BackgroundVBO); 629b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 630b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Release effects 631b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDeleteShader(m_uiPostVertShader); 632b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDeleteShader(m_uiPostFragShader); 633b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDeleteShader(m_uiBackgroundFragShader); 634b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDeleteShader(m_uiSceneVertShader); 635b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDeleteShader(m_uiSceneFragShader); 636b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 637b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDeleteProgram(m_PostShaderProgram.uiId); 638b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDeleteProgram(m_BackgroundShaderProgram.uiId); 639b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDeleteProgram(m_SceneShaderProgram.uiId); 640b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 641b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Tidy up the FBOs and renderbuffers 642b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 643b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Delete frame buffer objects 644b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDeleteFramebuffers(1, &m_uiFBO); 645b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDeleteFramebuffers(1, &m_uiFBOMultisampled); 646b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 647b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Delete our depth buffer 648b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDeleteRenderbuffers(1, &m_uiDepthBufferMultisampled); 649b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDeleteRenderbuffers(1, &m_uiColourBufferMultisampled); 650b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 651b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Delete buffer objects 652b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDeleteBuffers(m_Mask.nNumMesh, m_puiMaskVBO); 653b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDeleteBuffers(m_Mask.nNumMesh, m_puiMaskIBO); 654b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 655b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Release Print3D Textures 656b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu m_Print3D.ReleaseTextures(); 657b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 658b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu return true; 659b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu} 660b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 661b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu/*!**************************************************************************** 662b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Function RenderScene 663b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Return bool true if no error occurred 664b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Description Main rendering loop function of the program. The shell will 665b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu call this function every frame. 666b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu eglSwapBuffers() will be performed by PVRShell automatically. 667b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu PVRShell will also manage important OS events. 668b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu Will also manage relevant OS events. The user has access to 669b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu these events through an abstraction layer provided by PVRShell. 670b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu ******************************************************************************/ 6713e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capensbool OGLES3ColourGrading::RenderScene() 672b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu{ 673b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Clears the colour buffer 674b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 675b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 676b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu unsigned long ulTime = PVRShellGetTime() - m_ulStartTime; 677b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 678b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Process input to switch between tone mapping operators 679b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu if(PVRShellIsKeyPressed(PVRShellKeyNameRIGHT)) 680b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 681b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu ++m_iCurrentLUT; 682b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 683b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu if(m_iCurrentLUT > eB) 684b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu m_iCurrentLUT = eA; 685b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 686b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu else if(PVRShellIsKeyPressed(PVRShellKeyNameLEFT)) 687b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 688b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu --m_iCurrentLUT; 689b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 690b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu if(m_iCurrentLUT < eA) 691b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu m_iCurrentLUT = eB; 692b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 6933e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens 694b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Render to our texture 695b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu { 696b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Bind our FBO 6973e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glBindFramebuffer(GL_FRAMEBUFFER, m_uiFBOMultisampled); 698b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 699b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Clear the colour and depth buffer of our FBO surface 700b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 701b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 702b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDisable(GL_CULL_FACE); 703b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDisable(GL_DEPTH_TEST); 704b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 705b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Bind the VBO 706b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glBindBuffer(GL_ARRAY_BUFFER, m_ui32BackgroundVBO); 707b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 708b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Use shader program 709b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glUseProgram(m_BackgroundShaderProgram.uiId); 710b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 711b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Enable the vertex attribute arrays 712b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glEnableVertexAttribArray(VERTEX_ARRAY); 713b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glEnableVertexAttribArray(TEXCOORD_ARRAY); 714b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 715b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Set the vertex attribute offsets 716b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glVertexAttribPointer(VERTEX_ARRAY, 4, GL_FLOAT, GL_FALSE, m_ui32VertexStride, 0); 717b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, m_ui32VertexStride, (void*) (4 * sizeof(GLfloat))); 718b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 719b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Bind texture 720b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glActiveTexture(GL_TEXTURE0); 721b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glBindTexture(GL_TEXTURE_2D, m_uiBackgroundTexture); 722b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 723b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Draw a screen-aligned quad. 724b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 725b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Draws a non-indexed triangle array 726b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 727b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 728b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Safely disable the vertex attribute arrays 729b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDisableVertexAttribArray(VERTEX_ARRAY); 730b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDisableVertexAttribArray(TEXCOORD_ARRAY); 731b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 732b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glEnable(GL_CULL_FACE); 733b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glEnable(GL_DEPTH_TEST); 734b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 735b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Use shader program 736b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glUseProgram(m_SceneShaderProgram.uiId); 737b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 738b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Rotate the model matrix 739b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu PVRTMat4 mModel = PVRTMat4::RotationY(ulTime * 0.0015f); 740b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 741b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Calculate model view projection matrix 742b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu PVRTMat4 mMVP = m_mViewProjection * mModel; 743b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 744b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Feeds Projection Model View matrix to the shaders 745b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glUniformMatrix4fv(m_SceneShaderProgram.uiMVPMatrixLoc, 1, GL_FALSE, mMVP.ptr()); 746b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 747b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu PVRTVec3 vMsLightDir = (PVRTVec3(1, 1, 1) * PVRTMat3(mModel)).normalized(); 748b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glUniform3fv(m_SceneShaderProgram.uiLightDirLoc, 1, vMsLightDir.ptr()); 749b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 750b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glBindTexture(GL_TEXTURE_2D, m_uiMaskTexture); 751b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 752b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Now that the uniforms are set, call another function to actually draw the mesh. 753b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu DrawMesh(0); 754b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 755b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Unbind the VBO 756b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glBindBuffer(GL_ARRAY_BUFFER, 0); 757b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 7583e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens // Give the drivers a hint that we don't want the depth and stencil information stored for future use. 7593e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens const GLenum attachments[] = { GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT }; 7603e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, attachments); 761b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 762b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Blit and resolve the multisampled render buffer to the non-multisampled FBO 7633e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glBindFramebuffer(GL_READ_FRAMEBUFFER, m_uiFBOMultisampled); 7643e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_uiFBO); 7653e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glBlitFramebuffer(0, 0, PVRShellGet(prefWidth), PVRShellGet(prefHeight), 0, 0, PVRShellGet(prefWidth), PVRShellGet(prefHeight), GL_COLOR_BUFFER_BIT, GL_NEAREST); 766b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 767b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // We are done with rendering to our FBO so switch back to the back buffer. 768b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glBindFramebuffer(GL_FRAMEBUFFER, m_i32OriginalFbo); 769b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu } 770b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 771b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDisable(GL_CULL_FACE); 772b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDisable(GL_DEPTH_TEST); 773b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 774b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Use shader program 775b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glUseProgram(m_PostShaderProgram.uiId); 7763e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens 777b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Bind the VBO 778b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glBindBuffer(GL_ARRAY_BUFFER, m_ui32FullScreenRectVBO); 7793e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens 780b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Enable the vertex attribute arrays 781b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glEnableVertexAttribArray(VERTEX_ARRAY); 782b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glEnableVertexAttribArray(TEXCOORD_ARRAY); 783b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 784b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Set the vertex attribute offsets 785b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glVertexAttribPointer(VERTEX_ARRAY, 4, GL_FLOAT, GL_FALSE, m_ui32VertexStride, 0); 786b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, m_ui32VertexStride, (void*) (4 * sizeof(GLfloat))); 7873e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens 788b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Bind texture 789b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glActiveTexture(GL_TEXTURE0); 790b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glBindTexture(GL_TEXTURE_2D, m_uiTextureToRenderTo); 791b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 792b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glActiveTexture(GL_TEXTURE1); 7933e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glBindTexture(GL_TEXTURE_3D, m_uiLUTs[m_iCurrentLUT]); 794b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 795b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Draw a screen-aligned quad. 796b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 797b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Draw the left-hand side that shows the scene with the colour grading applied 798b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 799b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 800b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Draw the right-hande side showing the scene how it looks without 8013e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens glBindTexture(GL_TEXTURE_3D, m_uiLUTs[eIdentity]); 802b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDrawArrays(GL_TRIANGLE_STRIP, 2, 4); 803b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 804b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Safely disable the vertex attribute arrays 805b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDisableVertexAttribArray(VERTEX_ARRAY); 806b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDisableVertexAttribArray(TEXCOORD_ARRAY); 807b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 808b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Unbind the VBO 809b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glBindBuffer(GL_ARRAY_BUFFER, 0); 810b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 811b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Render title 812b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu m_Print3D.DisplayDefaultTitle("Colour grading using 3D textures", c_pszLUTNames[m_iCurrentLUT], ePVRTPrint3DSDKLogo); 813b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu m_Print3D.Flush(); 814b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 815b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu return true; 816b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu} 817b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 818b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu/*!**************************************************************************** 819b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Function DrawMesh 820b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Input i32NodeIndex Node index of the mesh to draw 821b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Description Draws a SPODMesh after the model view matrix has been set and 822b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu the material prepared. 823b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu******************************************************************************/ 8243e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capensvoid OGLES3ColourGrading::DrawMesh(const int i32NodeIndex) 825b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu{ 826b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu int i32MeshIndex = m_Mask.pNode[i32NodeIndex].nIdx; 827b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu SPODMesh* pMesh = &m_Mask.pMesh[i32MeshIndex]; 828b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 829b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // bind the VBO for the mesh 830b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glBindBuffer(GL_ARRAY_BUFFER, m_puiMaskVBO[i32MeshIndex]); 831b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // bind the index buffer, won't hurt if the handle is 0 832b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiMaskIBO[i32MeshIndex]); 833b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 834b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Enable the vertex attribute arrays 835b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glEnableVertexAttribArray(VERTEX_ARRAY); 836b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glEnableVertexAttribArray(NORMAL_ARRAY); 837b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glEnableVertexAttribArray(TEXCOORD_ARRAY); 838b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 839b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Set the vertex attribute offsets 840b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, pMesh->sVertex.nStride, pMesh->sVertex.pData); 841b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glVertexAttribPointer(NORMAL_ARRAY, 3, GL_FLOAT, GL_FALSE, pMesh->sNormals.nStride, pMesh->sNormals.pData); 842b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, pMesh->psUVW[0].nStride, pMesh->psUVW[0].pData); 843b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 844b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Indexed Triangle list 845b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDrawElements(GL_TRIANGLES, pMesh->nNumFaces*3, GL_UNSIGNED_SHORT, 0); 846b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 847b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu // Safely disable the vertex attribute arrays 848b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDisableVertexAttribArray(VERTEX_ARRAY); 849b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDisableVertexAttribArray(NORMAL_ARRAY); 850b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glDisableVertexAttribArray(TEXCOORD_ARRAY); 851b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 852b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glBindBuffer(GL_ARRAY_BUFFER, 0); 853b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 854b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu} 855b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 856b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu/*!**************************************************************************** 857b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Function NewDemo 858b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Return PVRShell* The demo supplied by the user 859b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu @Description This function must be implemented by the user of the shell. 860b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu The user should return its PVRShell object defining the 861b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu behaviour of the application. 862b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu ******************************************************************************/ 863b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis HetuPVRShell* NewDemo() 864b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu{ 8653e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens return new OGLES3ColourGrading(); 866b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu} 867b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 868b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu/****************************************************************************** 8693e3a025e14e5076f3be348ee42b0723889e3d2a2Nicolas Capens End of file (OGLES3ColourGrading.cpp) 870b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu ******************************************************************************/ 871b027aa91f4b20c5062fbc781d0ff693bf294cbccAlexis Hetu 872