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