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