168 // Compile up the simple shader: |
168 // Compile up the simple shader: |
169 source.clear(); |
169 source.clear(); |
170 source.append(qShaderSnippets[MainVertexShader]); |
170 source.append(qShaderSnippets[MainVertexShader]); |
171 source.append(qShaderSnippets[PositionOnlyVertexShader]); |
171 source.append(qShaderSnippets[PositionOnlyVertexShader]); |
172 vertexShader = new QGLShader(QGLShader::Vertex, context, this); |
172 vertexShader = new QGLShader(QGLShader::Vertex, context, this); |
173 vertexShader->compileSourceCode(source); |
173 if (!vertexShader->compileSourceCode(source)) |
|
174 qWarning("Vertex shader for simpleShaderProg (MainVertexShader & PositionOnlyVertexShader) failed to compile"); |
174 |
175 |
175 source.clear(); |
176 source.clear(); |
176 source.append(qShaderSnippets[MainFragmentShader]); |
177 source.append(qShaderSnippets[MainFragmentShader]); |
177 source.append(qShaderSnippets[ShockingPinkSrcFragmentShader]); |
178 source.append(qShaderSnippets[ShockingPinkSrcFragmentShader]); |
178 fragShader = new QGLShader(QGLShader::Fragment, context, this); |
179 fragShader = new QGLShader(QGLShader::Fragment, context, this); |
179 fragShader->compileSourceCode(source); |
180 if (!fragShader->compileSourceCode(source)) |
|
181 qWarning("Fragment shader for simpleShaderProg (MainFragmentShader & ShockingPinkSrcFragmentShader) failed to compile"); |
180 |
182 |
181 simpleShaderProg = new QGLShaderProgram(context, this); |
183 simpleShaderProg = new QGLShaderProgram(context, this); |
182 simpleShaderProg->addShader(vertexShader); |
184 simpleShaderProg->addShader(vertexShader); |
183 simpleShaderProg->addShader(fragShader); |
185 simpleShaderProg->addShader(fragShader); |
184 simpleShaderProg->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); |
186 simpleShaderProg->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); |
191 // Compile the blit shader: |
193 // Compile the blit shader: |
192 source.clear(); |
194 source.clear(); |
193 source.append(qShaderSnippets[MainWithTexCoordsVertexShader]); |
195 source.append(qShaderSnippets[MainWithTexCoordsVertexShader]); |
194 source.append(qShaderSnippets[UntransformedPositionVertexShader]); |
196 source.append(qShaderSnippets[UntransformedPositionVertexShader]); |
195 vertexShader = new QGLShader(QGLShader::Vertex, context, this); |
197 vertexShader = new QGLShader(QGLShader::Vertex, context, this); |
196 vertexShader->compileSourceCode(source); |
198 if (!vertexShader->compileSourceCode(source)) |
|
199 qWarning("Vertex shader for blitShaderProg (MainWithTexCoordsVertexShader & UntransformedPositionVertexShader) failed to compile"); |
197 |
200 |
198 source.clear(); |
201 source.clear(); |
199 source.append(qShaderSnippets[MainFragmentShader]); |
202 source.append(qShaderSnippets[MainFragmentShader]); |
200 source.append(qShaderSnippets[ImageSrcFragmentShader]); |
203 source.append(qShaderSnippets[ImageSrcFragmentShader]); |
201 fragShader = new QGLShader(QGLShader::Fragment, context, this); |
204 fragShader = new QGLShader(QGLShader::Fragment, context, this); |
202 fragShader->compileSourceCode(source); |
205 if (!fragShader->compileSourceCode(source)) |
|
206 qWarning("Fragment shader for blitShaderProg (MainFragmentShader & ImageSrcFragmentShader) failed to compile"); |
203 |
207 |
204 blitShaderProg = new QGLShaderProgram(context, this); |
208 blitShaderProg = new QGLShaderProgram(context, this); |
205 blitShaderProg->addShader(vertexShader); |
209 blitShaderProg->addShader(vertexShader); |
206 blitShaderProg->addShader(fragShader); |
210 blitShaderProg->addShader(fragShader); |
207 blitShaderProg->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); |
211 blitShaderProg->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); |
232 cachedPrograms.move(i, 0); |
253 cachedPrograms.move(i, 0); |
233 return cachedProg; |
254 return cachedProg; |
234 } |
255 } |
235 } |
256 } |
236 |
257 |
237 QByteArray source; |
258 QGLShader *vertexShader = 0; |
238 source.append(qShaderSnippets[prog.mainFragShader]); |
259 QGLShader *fragShader = 0; |
239 source.append(qShaderSnippets[prog.srcPixelFragShader]); |
260 QGLEngineShaderProg *newProg = 0; |
240 if (prog.srcPixelFragShader == CustomImageSrcFragmentShader) |
261 bool success = false; |
241 source.append(prog.customStageSource); |
262 |
242 if (prog.compositionFragShader) |
263 do { |
243 source.append(qShaderSnippets[prog.compositionFragShader]); |
264 QByteArray source; |
244 if (prog.maskFragShader) |
265 source.append(qShaderSnippets[prog.mainFragShader]); |
245 source.append(qShaderSnippets[prog.maskFragShader]); |
266 source.append(qShaderSnippets[prog.srcPixelFragShader]); |
246 QGLShader* fragShader = new QGLShader(QGLShader::Fragment, ctxGuard.context(), this); |
267 if (prog.srcPixelFragShader == CustomImageSrcFragmentShader) |
247 fragShader->compileSourceCode(source); |
268 source.append(prog.customStageSource); |
248 |
269 if (prog.compositionFragShader) |
249 source.clear(); |
270 source.append(qShaderSnippets[prog.compositionFragShader]); |
250 source.append(qShaderSnippets[prog.mainVertexShader]); |
271 if (prog.maskFragShader) |
251 source.append(qShaderSnippets[prog.positionVertexShader]); |
272 source.append(qShaderSnippets[prog.maskFragShader]); |
252 QGLShader* vertexShader = new QGLShader(QGLShader::Vertex, ctxGuard.context(), this); |
273 fragShader = new QGLShader(QGLShader::Fragment, ctxGuard.context(), this); |
253 vertexShader->compileSourceCode(source); |
274 QByteArray description; |
254 |
|
255 #if defined(QT_DEBUG) |
275 #if defined(QT_DEBUG) |
256 // Name the shaders for easier debugging |
276 // Name the shader for easier debugging |
257 QByteArray description; |
277 description.append("Fragment shader: main="); |
258 description.append("Fragment shader: main="); |
278 description.append(snippetNameStr(prog.mainFragShader)); |
259 description.append(snippetNameStr(prog.mainFragShader)); |
279 description.append(", srcPixel="); |
260 description.append(", srcPixel="); |
280 description.append(snippetNameStr(prog.srcPixelFragShader)); |
261 description.append(snippetNameStr(prog.srcPixelFragShader)); |
281 if (prog.compositionFragShader) { |
262 if (prog.compositionFragShader) { |
282 description.append(", composition="); |
263 description.append(", composition="); |
283 description.append(snippetNameStr(prog.compositionFragShader)); |
264 description.append(snippetNameStr(prog.compositionFragShader)); |
284 } |
265 } |
285 if (prog.maskFragShader) { |
266 if (prog.maskFragShader) { |
286 description.append(", mask="); |
267 description.append(", mask="); |
287 description.append(snippetNameStr(prog.maskFragShader)); |
268 description.append(snippetNameStr(prog.maskFragShader)); |
288 } |
269 } |
289 fragShader->setObjectName(QString::fromLatin1(description)); |
270 fragShader->setObjectName(QString::fromLatin1(description)); |
|
271 |
|
272 description.clear(); |
|
273 description.append("Vertex shader: main="); |
|
274 description.append(snippetNameStr(prog.mainVertexShader)); |
|
275 description.append(", position="); |
|
276 description.append(snippetNameStr(prog.positionVertexShader)); |
|
277 vertexShader->setObjectName(QString::fromLatin1(description)); |
|
278 #endif |
290 #endif |
279 |
291 if (!fragShader->compileSourceCode(source)) { |
280 QGLEngineShaderProg* newProg = new QGLEngineShaderProg(prog); |
292 qWarning() << "Warning:" << description << "failed to compile!"; |
281 |
293 break; |
282 // If the shader program's not found in the cache, create it now. |
294 } |
283 newProg->program = new QGLShaderProgram(ctxGuard.context(), this); |
295 |
284 newProg->program->addShader(vertexShader); |
296 source.clear(); |
285 newProg->program->addShader(fragShader); |
297 source.append(qShaderSnippets[prog.mainVertexShader]); |
286 |
298 source.append(qShaderSnippets[prog.positionVertexShader]); |
287 // We have to bind the vertex attribute names before the program is linked: |
299 vertexShader = new QGLShader(QGLShader::Vertex, ctxGuard.context(), this); |
288 newProg->program->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); |
|
289 if (newProg->useTextureCoords) |
|
290 newProg->program->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); |
|
291 if (newProg->useOpacityAttribute) |
|
292 newProg->program->bindAttributeLocation("opacityArray", QT_OPACITY_ATTR); |
|
293 |
|
294 newProg->program->link(); |
|
295 if (!newProg->program->isLinked()) { |
|
296 QLatin1String none("none"); |
|
297 QLatin1String br("\n"); |
|
298 QString error; |
|
299 error = QLatin1String("Shader program failed to link,") |
|
300 #if defined(QT_DEBUG) |
300 #if defined(QT_DEBUG) |
301 + br |
301 // Name the shader for easier debugging |
302 + QLatin1String(" Shaders Used:") + br |
302 description.clear(); |
303 + QLatin1String(" ") + vertexShader->objectName() + QLatin1String(": ") + br |
303 description.append("Vertex shader: main="); |
304 + QLatin1String(vertexShader->sourceCode()) + br |
304 description.append(snippetNameStr(prog.mainVertexShader)); |
305 + QLatin1String(" ") + fragShader->objectName() + QLatin1String(": ") + br |
305 description.append(", position="); |
306 + QLatin1String(fragShader->sourceCode()) + br |
306 description.append(snippetNameStr(prog.positionVertexShader)); |
|
307 vertexShader->setObjectName(QString::fromLatin1(description)); |
307 #endif |
308 #endif |
308 + QLatin1String(" Error Log:\n") |
309 if (!vertexShader->compileSourceCode(source)) { |
309 + QLatin1String(" ") + newProg->program->log(); |
310 qWarning() << "Warning:" << description << "failed to compile!"; |
310 qWarning() << error; |
311 break; |
311 delete newProg; // Deletes the QGLShaderProgram in it's destructor |
312 } |
312 newProg = 0; |
313 |
313 } |
314 newProg = new QGLEngineShaderProg(prog); |
314 else { |
315 |
|
316 // If the shader program's not found in the cache, create it now. |
|
317 newProg->program = new QGLShaderProgram(ctxGuard.context(), this); |
|
318 newProg->program->addShader(vertexShader); |
|
319 newProg->program->addShader(fragShader); |
|
320 |
|
321 // We have to bind the vertex attribute names before the program is linked: |
|
322 newProg->program->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); |
|
323 if (newProg->useTextureCoords) |
|
324 newProg->program->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); |
|
325 if (newProg->useOpacityAttribute) |
|
326 newProg->program->bindAttributeLocation("opacityArray", QT_OPACITY_ATTR); |
|
327 |
|
328 newProg->program->link(); |
|
329 if (!newProg->program->isLinked()) { |
|
330 QLatin1String none("none"); |
|
331 QLatin1String br("\n"); |
|
332 QString error; |
|
333 error = QLatin1String("Shader program failed to link,") |
|
334 #if defined(QT_DEBUG) |
|
335 + br |
|
336 + QLatin1String(" Shaders Used:") + br |
|
337 + QLatin1String(" ") + vertexShader->objectName() + QLatin1String(": ") + br |
|
338 + QLatin1String(vertexShader->sourceCode()) + br |
|
339 + QLatin1String(" ") + fragShader->objectName() + QLatin1String(": ") + br |
|
340 + QLatin1String(fragShader->sourceCode()) + br |
|
341 #endif |
|
342 + QLatin1String(" Error Log:\n") |
|
343 + QLatin1String(" ") + newProg->program->log(); |
|
344 qWarning() << error; |
|
345 break; |
|
346 } |
315 if (cachedPrograms.count() > 30) { |
347 if (cachedPrograms.count() > 30) { |
316 // The cache is full, so delete the last 5 programs in the list. |
348 // The cache is full, so delete the last 5 programs in the list. |
317 // These programs will be least used, as a program us bumped to |
349 // These programs will be least used, as a program us bumped to |
318 // the top of the list when it's used. |
350 // the top of the list when it's used. |
319 for (int i = 0; i < 5; ++i) { |
351 for (int i = 0; i < 5; ++i) { |