Home | History | Annotate | Download | only in OGLES2
      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