• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *****************************************************************************/
CPVRTBackground(void)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 *****************************************************************************/
~CPVRTBackground(void)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 *****************************************************************************/
Destroy()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 *****************************************************************************/
Init(const SPVRTContext * const pContext,bool bRotate,CPVRTString * pszError)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 *****************************************************************************/
Draw(const GLuint ui32Texture)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