| /****************************************************************************** |
| |
| @File OGLES2/PVRTBackground.cpp |
| |
| @Title OGLES2/PVRTBackground |
| |
| @Version |
| |
| @Copyright Copyright (c) Imagination Technologies Limited. |
| |
| @Platform ANSI compatible |
| |
| @Description Function to draw a background texture. |
| |
| ******************************************************************************/ |
| #include "PVRTShader.h" |
| #include "PVRTBackground.h" |
| |
| // The header that contains the shaders |
| #include "PVRTBackgroundShaders.h" |
| |
| // Index to bind the attributes to vertex shaders |
| const int VERTEX_ARRAY = 0; |
| const int TEXCOORD_ARRAY = 1; |
| |
| /**************************************************************************** |
| ** Structures |
| ****************************************************************************/ |
| |
| // The struct to include various API variables |
| struct SPVRTBackgroundAPI |
| { |
| GLuint m_ui32VertexShader; |
| GLuint m_ui32FragShader; |
| GLuint m_ui32ProgramObject; |
| GLuint m_ui32VertexBufferObject; |
| }; |
| |
| /**************************************************************************** |
| ** Class: CPVRTBackground |
| ****************************************************************************/ |
| |
| /***************************************************************************** |
| @Function Background |
| @Description Init some values. |
| *****************************************************************************/ |
| CPVRTBackground::CPVRTBackground(void) |
| { |
| m_bInit = false; |
| m_pAPI = 0; |
| } |
| |
| |
| /***************************************************************************** |
| @Function ~Background |
| @Description Calls Destroy() |
| *****************************************************************************/ |
| CPVRTBackground::~CPVRTBackground(void) |
| { |
| delete m_pAPI; |
| m_pAPI = 0; |
| } |
| |
| /*!*************************************************************************** |
| @Function Destroy |
| @Description Destroys the background and releases API specific resources |
| *****************************************************************************/ |
| void CPVRTBackground::Destroy() |
| { |
| if(m_bInit) |
| { |
| // Delete shaders |
| glDeleteProgram(m_pAPI->m_ui32ProgramObject); |
| glDeleteShader(m_pAPI->m_ui32VertexShader); |
| glDeleteShader(m_pAPI->m_ui32FragShader); |
| |
| // Delete buffer objects |
| glDeleteBuffers(1, &m_pAPI->m_ui32VertexBufferObject); |
| |
| m_bInit = false; |
| } |
| |
| delete m_pAPI; |
| m_pAPI = 0; |
| } |
| |
| /*!*************************************************************************** |
| @Function Init |
| @Input pContext A pointer to a PVRTContext |
| @Input bRotate true to rotate texture 90 degrees. |
| @Input pszError An option string for returning errors |
| @Return PVR_SUCCESS on success |
| @Description Initialises the background |
| *****************************************************************************/ |
| EPVRTError CPVRTBackground::Init(const SPVRTContext * const pContext, bool bRotate, CPVRTString *pszError) |
| { |
| PVRT_UNREFERENCED_PARAMETER(pContext); |
| |
| Destroy(); |
| |
| m_pAPI = new SPVRTBackgroundAPI; |
| |
| if(!m_pAPI) |
| { |
| if(pszError) |
| *pszError = "Error: Insufficient memory to allocate SCPVRTBackgroundAPI."; |
| |
| return PVR_FAIL; |
| } |
| |
| m_pAPI->m_ui32VertexShader = 0; |
| m_pAPI->m_ui32FragShader = 0; |
| m_pAPI->m_ui32ProgramObject = 0; |
| m_pAPI->m_ui32VertexBufferObject = 0; |
| |
| bool bResult; |
| CPVRTString sTmpErrStr; |
| |
| // The shader loading code doesn't expect a null pointer for the error string |
| if(!pszError) |
| pszError = &sTmpErrStr; |
| |
| /* Compiles the shaders. For a more detailed explanation, see IntroducingPVRTools */ |
| #if defined(GL_SGX_BINARY_IMG) |
| // Try binary shaders first |
| bResult = (PVRTShaderLoadBinaryFromMemory(_BackgroundFragShader_fsc, _BackgroundFragShader_fsc_size, |
| GL_FRAGMENT_SHADER, GL_SGX_BINARY_IMG, &m_pAPI->m_ui32FragShader, pszError) == PVR_SUCCESS) |
| && (PVRTShaderLoadBinaryFromMemory(_BackgroundVertShader_vsc, _BackgroundVertShader_vsc_size, |
| GL_VERTEX_SHADER, GL_SGX_BINARY_IMG, &m_pAPI->m_ui32VertexShader, pszError) == PVR_SUCCESS); |
| if(!bResult) |
| #endif |
| { |
| // if binary shaders don't work, try source shaders |
| bResult = (PVRTShaderLoadSourceFromMemory(_BackgroundFragShader_fsh, GL_FRAGMENT_SHADER, &m_pAPI->m_ui32FragShader, pszError) == PVR_SUCCESS) && |
| (PVRTShaderLoadSourceFromMemory(_BackgroundVertShader_vsh, GL_VERTEX_SHADER, &m_pAPI->m_ui32VertexShader, pszError) == PVR_SUCCESS); |
| } |
| |
| _ASSERT(bResult); |
| |
| if(!bResult) |
| return PVR_FAIL; |
| |
| // Reset the error string |
| if(pszError) |
| *pszError = ""; |
| |
| // Create the shader program |
| m_pAPI->m_ui32ProgramObject = glCreateProgram(); |
| |
| // Attach the fragment and vertex shaders to it |
| glAttachShader(m_pAPI->m_ui32ProgramObject, m_pAPI->m_ui32FragShader); |
| glAttachShader(m_pAPI->m_ui32ProgramObject, m_pAPI->m_ui32VertexShader); |
| |
| // Bind the custom vertex attribute "myVertex" to location VERTEX_ARRAY |
| glBindAttribLocation(m_pAPI->m_ui32ProgramObject, VERTEX_ARRAY, "myVertex"); |
| |
| // Bind the custom vertex attribute "myUV" to location TEXCOORD_ARRAY |
| glBindAttribLocation(m_pAPI->m_ui32ProgramObject, TEXCOORD_ARRAY, "myUV"); |
| |
| // Link the program |
| glLinkProgram(m_pAPI->m_ui32ProgramObject); |
| GLint Linked; |
| glGetProgramiv(m_pAPI->m_ui32ProgramObject, GL_LINK_STATUS, &Linked); |
| if (!Linked) |
| { |
| int i32InfoLogLength, i32CharsWritten; |
| glGetProgramiv(m_pAPI->m_ui32ProgramObject, GL_INFO_LOG_LENGTH, &i32InfoLogLength); |
| char* pszInfoLog = new char[i32InfoLogLength]; |
| glGetProgramInfoLog(m_pAPI->m_ui32ProgramObject, i32InfoLogLength, &i32CharsWritten, pszInfoLog); |
| *pszError = CPVRTString("Failed to link: ") + pszInfoLog + "\n"; |
| delete [] pszInfoLog; |
| bResult = false; |
| } |
| |
| _ASSERT(bResult); |
| |
| if(!bResult) |
| return PVR_FAIL; |
| |
| // Use the loaded shader program |
| glUseProgram(m_pAPI->m_ui32ProgramObject); |
| |
| // Set the sampler2D variable to the first texture unit |
| glUniform1i(glGetUniformLocation(m_pAPI->m_ui32ProgramObject, "sampler2d"), 0); |
| |
| // Create the vertex buffer object |
| GLfloat *pVertexData = 0; |
| |
| // The vertex data for non-rotated |
| GLfloat afVertexData[16] = { -1, -1, 1, -1, -1, 1, 1, 1, |
| 0, 0, 1, 0, 0, 1, 1, 1}; |
| |
| // The vertex data for rotated |
| GLfloat afVertexDataRotated[16] = {-1, 1, -1, -1, 1, 1, 1, -1, |
| 1, 1, 0, 1, 1, 0, 0, 0}; |
| |
| if(!bRotate) |
| pVertexData = &afVertexData[0]; |
| else |
| pVertexData = &afVertexDataRotated[0]; |
| |
| glGenBuffers(1, &m_pAPI->m_ui32VertexBufferObject); |
| glBindBuffer(GL_ARRAY_BUFFER, m_pAPI->m_ui32VertexBufferObject); |
| |
| glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 16, pVertexData, GL_STATIC_DRAW); |
| |
| glBindBuffer(GL_ARRAY_BUFFER, 0); |
| |
| m_bInit = true; |
| |
| return PVR_SUCCESS; |
| } |
| |
| |
| /*!*************************************************************************** |
| @Function Draw |
| @Input ui32Texture Texture to use |
| @Return PVR_SUCCESS on success |
| @Description Draws a texture on a quad covering the whole screen. |
| *****************************************************************************/ |
| EPVRTError CPVRTBackground::Draw(const GLuint ui32Texture) |
| { |
| if(!m_bInit) |
| return PVR_FAIL; |
| |
| glActiveTexture(GL_TEXTURE0); |
| |
| glBindTexture(GL_TEXTURE_2D, ui32Texture); |
| |
| glDisable(GL_DEPTH_TEST); |
| glDisable(GL_CULL_FACE); |
| |
| // Use the loaded shader program |
| glUseProgram(m_pAPI->m_ui32ProgramObject); |
| |
| // Set vertex data |
| glBindBuffer(GL_ARRAY_BUFFER, m_pAPI->m_ui32VertexBufferObject); |
| |
| glEnableVertexAttribArray(VERTEX_ARRAY); |
| glVertexAttribPointer(VERTEX_ARRAY, 2, GL_FLOAT, GL_FALSE, 0, (const void*) 0); |
| |
| // Set texture coordinates |
| glEnableVertexAttribArray(TEXCOORD_ARRAY); |
| glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, 0, (const void*) (8 * sizeof(float))); |
| |
| // Render geometry |
| glDrawArrays(GL_TRIANGLE_STRIP,0,4); |
| |
| glDisableVertexAttribArray(VERTEX_ARRAY); |
| glDisableVertexAttribArray(TEXCOORD_ARRAY); |
| |
| glBindBuffer(GL_ARRAY_BUFFER, 0); |
| |
| glUseProgram(0); |
| |
| return PVR_SUCCESS; |
| } |
| |
| /***************************************************************************** |
| End of file (CPVRTBackground.cpp) |
| *****************************************************************************/ |
| |