1 /****************************************************************************** 2 3 @File OGLES2/PVRTBackground.cpp 4 5 @Title OGLES2/PVRTBackground 6 7 @Version 8 9 @Copyright Copyright (c) Imagination Technologies Limited. 10 11 @Platform ANSI compatible 12 13 @Description Function to draw a background texture. 14 15 ******************************************************************************/ 16 #include "PVRTShader.h" 17 #include "PVRTBackground.h" 18 19 // The header that contains the shaders 20 #include "PVRTBackgroundShaders.h" 21 22 // Index to bind the attributes to vertex shaders 23 const int VERTEX_ARRAY = 0; 24 const int TEXCOORD_ARRAY = 1; 25 26 /**************************************************************************** 27 ** Structures 28 ****************************************************************************/ 29 30 // The struct to include various API variables 31 struct SPVRTBackgroundAPI 32 { 33 GLuint m_ui32VertexShader; 34 GLuint m_ui32FragShader; 35 GLuint m_ui32ProgramObject; 36 GLuint m_ui32VertexBufferObject; 37 }; 38 39 /**************************************************************************** 40 ** Class: CPVRTBackground 41 ****************************************************************************/ 42 43 /***************************************************************************** 44 @Function Background 45 @Description Init some values. 46 *****************************************************************************/ 47 CPVRTBackground::CPVRTBackground(void) 48 { 49 m_bInit = false; 50 m_pAPI = 0; 51 } 52 53 54 /***************************************************************************** 55 @Function ~Background 56 @Description Calls Destroy() 57 *****************************************************************************/ 58 CPVRTBackground::~CPVRTBackground(void) 59 { 60 delete m_pAPI; 61 m_pAPI = 0; 62 } 63 64 /*!*************************************************************************** 65 @Function Destroy 66 @Description Destroys the background and releases API specific resources 67 *****************************************************************************/ 68 void CPVRTBackground::Destroy() 69 { 70 if(m_bInit) 71 { 72 // Delete shaders 73 glDeleteProgram(m_pAPI->m_ui32ProgramObject); 74 glDeleteShader(m_pAPI->m_ui32VertexShader); 75 glDeleteShader(m_pAPI->m_ui32FragShader); 76 77 // Delete buffer objects 78 glDeleteBuffers(1, &m_pAPI->m_ui32VertexBufferObject); 79 80 m_bInit = false; 81 } 82 83 delete m_pAPI; 84 m_pAPI = 0; 85 } 86 87 /*!*************************************************************************** 88 @Function Init 89 @Input pContext A pointer to a PVRTContext 90 @Input bRotate true to rotate texture 90 degrees. 91 @Input pszError An option string for returning errors 92 @Return PVR_SUCCESS on success 93 @Description Initialises the background 94 *****************************************************************************/ 95 EPVRTError CPVRTBackground::Init(const SPVRTContext * const pContext, bool bRotate, CPVRTString *pszError) 96 { 97 PVRT_UNREFERENCED_PARAMETER(pContext); 98 99 Destroy(); 100 101 m_pAPI = new SPVRTBackgroundAPI; 102 103 if(!m_pAPI) 104 { 105 if(pszError) 106 *pszError = "Error: Insufficient memory to allocate SCPVRTBackgroundAPI."; 107 108 return PVR_FAIL; 109 } 110 111 m_pAPI->m_ui32VertexShader = 0; 112 m_pAPI->m_ui32FragShader = 0; 113 m_pAPI->m_ui32ProgramObject = 0; 114 m_pAPI->m_ui32VertexBufferObject = 0; 115 116 bool bResult; 117 CPVRTString sTmpErrStr; 118 119 // The shader loading code doesn't expect a null pointer for the error string 120 if(!pszError) 121 pszError = &sTmpErrStr; 122 123 /* Compiles the shaders. For a more detailed explanation, see IntroducingPVRTools */ 124 #if defined(GL_SGX_BINARY_IMG) 125 // Try binary shaders first 126 bResult = (PVRTShaderLoadBinaryFromMemory(_BackgroundFragShader_fsc, _BackgroundFragShader_fsc_size, 127 GL_FRAGMENT_SHADER, GL_SGX_BINARY_IMG, &m_pAPI->m_ui32FragShader, pszError) == PVR_SUCCESS) 128 && (PVRTShaderLoadBinaryFromMemory(_BackgroundVertShader_vsc, _BackgroundVertShader_vsc_size, 129 GL_VERTEX_SHADER, GL_SGX_BINARY_IMG, &m_pAPI->m_ui32VertexShader, pszError) == PVR_SUCCESS); 130 if(!bResult) 131 #endif 132 { 133 // if binary shaders don't work, try source shaders 134 bResult = (PVRTShaderLoadSourceFromMemory(_BackgroundFragShader_fsh, GL_FRAGMENT_SHADER, &m_pAPI->m_ui32FragShader, pszError) == PVR_SUCCESS) && 135 (PVRTShaderLoadSourceFromMemory(_BackgroundVertShader_vsh, GL_VERTEX_SHADER, &m_pAPI->m_ui32VertexShader, pszError) == PVR_SUCCESS); 136 } 137 138 _ASSERT(bResult); 139 140 if(!bResult) 141 return PVR_FAIL; 142 143 // Reset the error string 144 if(pszError) 145 *pszError = ""; 146 147 // Create the shader program 148 m_pAPI->m_ui32ProgramObject = glCreateProgram(); 149 150 // Attach the fragment and vertex shaders to it 151 glAttachShader(m_pAPI->m_ui32ProgramObject, m_pAPI->m_ui32FragShader); 152 glAttachShader(m_pAPI->m_ui32ProgramObject, m_pAPI->m_ui32VertexShader); 153 154 // Bind the custom vertex attribute "myVertex" to location VERTEX_ARRAY 155 glBindAttribLocation(m_pAPI->m_ui32ProgramObject, VERTEX_ARRAY, "myVertex"); 156 157 // Bind the custom vertex attribute "myUV" to location TEXCOORD_ARRAY 158 glBindAttribLocation(m_pAPI->m_ui32ProgramObject, TEXCOORD_ARRAY, "myUV"); 159 160 // Link the program 161 glLinkProgram(m_pAPI->m_ui32ProgramObject); 162 GLint Linked; 163 glGetProgramiv(m_pAPI->m_ui32ProgramObject, GL_LINK_STATUS, &Linked); 164 if (!Linked) 165 { 166 int i32InfoLogLength, i32CharsWritten; 167 glGetProgramiv(m_pAPI->m_ui32ProgramObject, GL_INFO_LOG_LENGTH, &i32InfoLogLength); 168 char* pszInfoLog = new char[i32InfoLogLength]; 169 glGetProgramInfoLog(m_pAPI->m_ui32ProgramObject, i32InfoLogLength, &i32CharsWritten, pszInfoLog); 170 *pszError = CPVRTString("Failed to link: ") + pszInfoLog + "\n"; 171 delete [] pszInfoLog; 172 bResult = false; 173 } 174 175 _ASSERT(bResult); 176 177 if(!bResult) 178 return PVR_FAIL; 179 180 // Use the loaded shader program 181 glUseProgram(m_pAPI->m_ui32ProgramObject); 182 183 // Set the sampler2D variable to the first texture unit 184 glUniform1i(glGetUniformLocation(m_pAPI->m_ui32ProgramObject, "sampler2d"), 0); 185 186 // Create the vertex buffer object 187 GLfloat *pVertexData = 0; 188 189 // The vertex data for non-rotated 190 GLfloat afVertexData[16] = { -1, -1, 1, -1, -1, 1, 1, 1, 191 0, 0, 1, 0, 0, 1, 1, 1}; 192 193 // The vertex data for rotated 194 GLfloat afVertexDataRotated[16] = {-1, 1, -1, -1, 1, 1, 1, -1, 195 1, 1, 0, 1, 1, 0, 0, 0}; 196 197 if(!bRotate) 198 pVertexData = &afVertexData[0]; 199 else 200 pVertexData = &afVertexDataRotated[0]; 201 202 glGenBuffers(1, &m_pAPI->m_ui32VertexBufferObject); 203 glBindBuffer(GL_ARRAY_BUFFER, m_pAPI->m_ui32VertexBufferObject); 204 205 glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 16, pVertexData, GL_STATIC_DRAW); 206 207 glBindBuffer(GL_ARRAY_BUFFER, 0); 208 209 m_bInit = true; 210 211 return PVR_SUCCESS; 212 } 213 214 215 /*!*************************************************************************** 216 @Function Draw 217 @Input ui32Texture Texture to use 218 @Return PVR_SUCCESS on success 219 @Description Draws a texture on a quad covering the whole screen. 220 *****************************************************************************/ 221 EPVRTError CPVRTBackground::Draw(const GLuint ui32Texture) 222 { 223 if(!m_bInit) 224 return PVR_FAIL; 225 226 glActiveTexture(GL_TEXTURE0); 227 228 glBindTexture(GL_TEXTURE_2D, ui32Texture); 229 230 glDisable(GL_DEPTH_TEST); 231 glDisable(GL_CULL_FACE); 232 233 // Use the loaded shader program 234 glUseProgram(m_pAPI->m_ui32ProgramObject); 235 236 // Set vertex data 237 glBindBuffer(GL_ARRAY_BUFFER, m_pAPI->m_ui32VertexBufferObject); 238 239 glEnableVertexAttribArray(VERTEX_ARRAY); 240 glVertexAttribPointer(VERTEX_ARRAY, 2, GL_FLOAT, GL_FALSE, 0, (const void*) 0); 241 242 // Set texture coordinates 243 glEnableVertexAttribArray(TEXCOORD_ARRAY); 244 glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, 0, (const void*) (8 * sizeof(float))); 245 246 // Render geometry 247 glDrawArrays(GL_TRIANGLE_STRIP,0,4); 248 249 glDisableVertexAttribArray(VERTEX_ARRAY); 250 glDisableVertexAttribArray(TEXCOORD_ARRAY); 251 252 glBindBuffer(GL_ARRAY_BUFFER, 0); 253 254 glUseProgram(0); 255 256 return PVR_SUCCESS; 257 } 258 259 /***************************************************************************** 260 End of file (CPVRTBackground.cpp) 261 *****************************************************************************/ 262 263