1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the Qt3D module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 3 requirements |
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
24 | ** |
25 | ** GNU General Public License Usage |
26 | ** Alternatively, this file may be used under the terms of the GNU |
27 | ** General Public License version 2.0 or (at your option) the GNU General |
28 | ** Public license version 3 or any later version approved by the KDE Free |
29 | ** Qt Foundation. The licenses are as published by the Free Software |
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
31 | ** included in the packaging of this file. Please review the following |
32 | ** information to ensure the GNU General Public License requirements will |
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
35 | ** |
36 | ** $QT_END_LICENSE$ |
37 | ** |
38 | ****************************************************************************/ |
39 | |
40 | #include "graphicshelpergl2_p.h" |
41 | #ifndef QT_OPENGL_ES_2 |
42 | #include <QOpenGLFunctions_2_0> |
43 | #include <private/attachmentpack_p.h> |
44 | #include <QtOpenGLExtensions/QOpenGLExtensions> |
45 | #include <qgraphicsutils_p.h> |
46 | #include <logging_p.h> |
47 | |
48 | QT_BEGIN_NAMESPACE |
49 | |
50 | namespace Qt3DRender { |
51 | namespace Render { |
52 | namespace OpenGL { |
53 | |
54 | GraphicsHelperGL2::GraphicsHelperGL2() |
55 | : m_funcs(nullptr) |
56 | , m_fboFuncs(nullptr) |
57 | { |
58 | |
59 | } |
60 | |
61 | void GraphicsHelperGL2::initializeHelper(QOpenGLContext *context, |
62 | QAbstractOpenGLFunctions *functions) |
63 | { |
64 | Q_UNUSED(context); |
65 | m_funcs = static_cast<QOpenGLFunctions_2_0*>(functions); |
66 | const bool ok = m_funcs->initializeOpenGLFunctions(); |
67 | Q_ASSERT(ok); |
68 | Q_UNUSED(ok); |
69 | if (context->hasExtension(QByteArrayLiteral("GL_ARB_framebuffer_object" ))) { |
70 | m_fboFuncs = new QOpenGLExtension_ARB_framebuffer_object(); |
71 | const bool extensionOk = m_fboFuncs->initializeOpenGLFunctions(); |
72 | Q_ASSERT(extensionOk); |
73 | Q_UNUSED(extensionOk); |
74 | } |
75 | } |
76 | |
77 | void GraphicsHelperGL2::drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, |
78 | GLsizei primitiveCount, |
79 | GLint indexType, |
80 | void *indices, |
81 | GLsizei instances, |
82 | GLint baseVertex, |
83 | GLint baseInstance) |
84 | { |
85 | if (baseInstance != 0) |
86 | qWarning() << "glDrawElementsInstancedBaseVertexBaseInstance is not supported with OpenGL ES 2" ; |
87 | |
88 | if (baseVertex != 0) |
89 | qWarning() << "glDrawElementsInstancedBaseVertex is not supported with OpenGL ES 2" ; |
90 | |
91 | for (GLint i = 0; i < instances; i++) |
92 | drawElements(primitiveType, |
93 | primitiveCount, |
94 | indexType, |
95 | indices); |
96 | } |
97 | |
98 | void GraphicsHelperGL2::drawArraysInstanced(GLenum primitiveType, |
99 | GLint first, |
100 | GLsizei count, |
101 | GLsizei instances) |
102 | { |
103 | for (GLint i = 0; i < instances; i++) |
104 | drawArrays(primitiveType, |
105 | first, |
106 | count); |
107 | } |
108 | |
109 | void GraphicsHelperGL2::drawArraysInstancedBaseInstance(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances, GLsizei baseInstance) |
110 | { |
111 | if (baseInstance != 0) |
112 | qWarning() << "glDrawArraysInstancedBaseInstance is not supported with OpenGL 2" ; |
113 | for (GLint i = 0; i < instances; i++) |
114 | drawArrays(primitiveType, |
115 | first, |
116 | count); |
117 | } |
118 | |
119 | void GraphicsHelperGL2::drawElements(GLenum primitiveType, |
120 | GLsizei primitiveCount, |
121 | GLint indexType, |
122 | void *indices, |
123 | GLint baseVertex) |
124 | { |
125 | if (baseVertex != 0) |
126 | qWarning() << "glDrawElementsBaseVertex is not supported with OpenGL 2" ; |
127 | |
128 | m_funcs->glDrawElements(mode: primitiveType, |
129 | count: primitiveCount, |
130 | type: indexType, |
131 | indices); |
132 | } |
133 | |
134 | void GraphicsHelperGL2::drawArrays(GLenum primitiveType, |
135 | GLint first, |
136 | GLsizei count) |
137 | { |
138 | m_funcs->glDrawArrays(mode: primitiveType, |
139 | first, |
140 | count); |
141 | } |
142 | |
143 | void GraphicsHelperGL2::drawElementsIndirect(GLenum, GLenum, void *) |
144 | { |
145 | qWarning() << "Indirect Drawing is not supported with OpenGL 2" ; |
146 | } |
147 | |
148 | void GraphicsHelperGL2::drawArraysIndirect(GLenum , void *) |
149 | { |
150 | qWarning() << "Indirect Drawing is not supported with OpenGL 2" ; |
151 | } |
152 | |
153 | void GraphicsHelperGL2::setVerticesPerPatch(GLint verticesPerPatch) |
154 | { |
155 | Q_UNUSED(verticesPerPatch); |
156 | qWarning() << "Tessellation not supported with OpenGL 2" ; |
157 | } |
158 | |
159 | void GraphicsHelperGL2::useProgram(GLuint programId) |
160 | { |
161 | m_funcs->glUseProgram(program: programId); |
162 | } |
163 | |
164 | QVector<ShaderUniform> GraphicsHelperGL2::programUniformsAndLocations(GLuint programId) |
165 | { |
166 | QVector<ShaderUniform> uniforms; |
167 | |
168 | GLint nbrActiveUniforms = 0; |
169 | m_funcs->glGetProgramiv(program: programId, GL_ACTIVE_UNIFORMS, params: &nbrActiveUniforms); |
170 | uniforms.reserve(asize: nbrActiveUniforms); |
171 | char uniformName[256]; |
172 | for (GLint i = 0; i < nbrActiveUniforms; i++) { |
173 | ShaderUniform uniform; |
174 | GLsizei uniformNameLength = 0; |
175 | // Size is 1 for scalar and more for struct or arrays |
176 | // Type is the GL Type |
177 | m_funcs->glGetActiveUniform(program: programId, index: i, bufSize: sizeof(uniformName) - 1, length: &uniformNameLength, |
178 | size: &uniform.m_size, type: &uniform.m_type, name: uniformName); |
179 | uniformName[sizeof(uniformName) - 1] = '\0'; |
180 | uniform.m_location = m_funcs->glGetUniformLocation(program: programId, name: uniformName); |
181 | uniform.m_name = QString::fromUtf8(str: uniformName, size: uniformNameLength); |
182 | // Work around for uniform array names that aren't returned with [0] by some drivers |
183 | if (uniform.m_size > 1 && !uniform.m_name.endsWith(s: QLatin1String("[0]" ))) |
184 | uniform.m_name.append(s: QLatin1String("[0]" )); |
185 | uniform.m_rawByteSize = uniformByteSize(description: uniform); |
186 | uniforms.append(t: uniform); |
187 | } |
188 | return uniforms; |
189 | } |
190 | |
191 | QVector<ShaderAttribute> GraphicsHelperGL2::programAttributesAndLocations(GLuint programId) |
192 | { |
193 | QVector<ShaderAttribute> attributes; |
194 | GLint nbrActiveAttributes = 0; |
195 | m_funcs->glGetProgramiv(program: programId, GL_ACTIVE_ATTRIBUTES, params: &nbrActiveAttributes); |
196 | attributes.reserve(asize: nbrActiveAttributes); |
197 | char attributeName[256]; |
198 | for (GLint i = 0; i < nbrActiveAttributes; i++) { |
199 | ShaderAttribute attribute; |
200 | GLsizei attributeNameLength = 0; |
201 | // Size is 1 for scalar and more for struct or arrays |
202 | // Type is the GL Type |
203 | m_funcs->glGetActiveAttrib(program: programId, index: i, bufSize: sizeof(attributeName) - 1, length: &attributeNameLength, |
204 | size: &attribute.m_size, type: &attribute.m_type, name: attributeName); |
205 | attributeName[sizeof(attributeName) - 1] = '\0'; |
206 | attribute.m_location = m_funcs->glGetAttribLocation(program: programId, name: attributeName); |
207 | attribute.m_name = QString::fromUtf8(str: attributeName, size: attributeNameLength); |
208 | attributes.append(t: attribute); |
209 | } |
210 | return attributes; |
211 | } |
212 | |
213 | QVector<ShaderUniformBlock> GraphicsHelperGL2::programUniformBlocks(GLuint programId) |
214 | { |
215 | Q_UNUSED(programId); |
216 | QVector<ShaderUniformBlock> blocks; |
217 | qWarning() << "UBO are not supported by OpenGL 2.0 (since OpenGL 3.1)" ; |
218 | return blocks; |
219 | } |
220 | |
221 | QVector<ShaderStorageBlock> GraphicsHelperGL2::programShaderStorageBlocks(GLuint programId) |
222 | { |
223 | Q_UNUSED(programId); |
224 | qWarning() << "SSBO are not supported by OpenGL 2.0 (since OpenGL 4.3)" ; |
225 | return QVector<ShaderStorageBlock>(); |
226 | } |
227 | |
228 | void GraphicsHelperGL2::vertexAttribDivisor(GLuint index, |
229 | GLuint divisor) |
230 | { |
231 | Q_UNUSED(index); |
232 | Q_UNUSED(divisor); |
233 | } |
234 | |
235 | void GraphicsHelperGL2::vertexAttributePointer(GLenum shaderDataType, |
236 | GLuint index, |
237 | GLint size, |
238 | GLenum type, |
239 | GLboolean normalized, |
240 | GLsizei stride, |
241 | const GLvoid *pointer) |
242 | { |
243 | switch (shaderDataType) { |
244 | case GL_FLOAT: |
245 | case GL_FLOAT_VEC2: |
246 | case GL_FLOAT_VEC3: |
247 | case GL_FLOAT_VEC4: |
248 | case GL_FLOAT_MAT2: |
249 | case GL_FLOAT_MAT2x3: |
250 | case GL_FLOAT_MAT2x4: |
251 | case GL_FLOAT_MAT3: |
252 | case GL_FLOAT_MAT3x2: |
253 | case GL_FLOAT_MAT3x4: |
254 | case GL_FLOAT_MAT4x2: |
255 | case GL_FLOAT_MAT4x3: |
256 | case GL_FLOAT_MAT4: |
257 | m_funcs->glVertexAttribPointer(index, size, type, normalized, stride, pointer); |
258 | break; |
259 | |
260 | default: |
261 | qCWarning(Rendering) << "vertexAttribPointer: Unhandled type" ; |
262 | Q_UNREACHABLE(); |
263 | } |
264 | } |
265 | |
266 | void GraphicsHelperGL2::readBuffer(GLenum mode) |
267 | { |
268 | m_funcs->glReadBuffer(mode); |
269 | } |
270 | |
271 | void GraphicsHelperGL2::drawBuffer(GLenum mode) |
272 | { |
273 | m_funcs->glDrawBuffer(mode); |
274 | } |
275 | |
276 | void *GraphicsHelperGL2::fenceSync() |
277 | { |
278 | qWarning() << "Fences are not supported by OpenGL 2.0 (since OpenGL 3.2)" ; |
279 | return nullptr; |
280 | } |
281 | |
282 | void GraphicsHelperGL2::clientWaitSync(void *, GLuint64 ) |
283 | { |
284 | qWarning() << "Fences are not supported by OpenGL 2.0 (since OpenGL 3.2)" ; |
285 | } |
286 | |
287 | void GraphicsHelperGL2::waitSync(void *) |
288 | { |
289 | qWarning() << "Fences are not supported by OpenGL 2.0 (since OpenGL 3.2)" ; |
290 | } |
291 | |
292 | bool GraphicsHelperGL2::wasSyncSignaled(void *) |
293 | { |
294 | qWarning() << "Fences are not supported by OpenGL 2.0 (since OpenGL 3.2)" ; |
295 | return false; |
296 | } |
297 | |
298 | void GraphicsHelperGL2::deleteSync(void *) |
299 | { |
300 | qWarning() << "Fences are not supported by OpenGL 2.0 (since OpenGL 3.2)" ; |
301 | } |
302 | |
303 | void GraphicsHelperGL2::rasterMode(GLenum faceMode, GLenum rasterMode) |
304 | { |
305 | m_funcs->glPolygonMode(face: faceMode, mode: rasterMode); |
306 | } |
307 | |
308 | void GraphicsHelperGL2::blendEquation(GLenum mode) |
309 | { |
310 | m_funcs->glBlendEquation(mode); |
311 | } |
312 | |
313 | void GraphicsHelperGL2::blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) |
314 | { |
315 | Q_UNUSED(buf); |
316 | Q_UNUSED(sfactor); |
317 | Q_UNUSED(dfactor); |
318 | |
319 | qWarning() << "glBlendFunci() not supported by OpenGL 2.0 (since OpenGL 4.0)" ; |
320 | } |
321 | |
322 | void GraphicsHelperGL2::blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha) |
323 | { |
324 | Q_UNUSED(buf); |
325 | Q_UNUSED(sRGB); |
326 | Q_UNUSED(dRGB); |
327 | Q_UNUSED(sAlpha); |
328 | Q_UNUSED(dAlpha); |
329 | |
330 | qWarning() << "glBlendFuncSeparatei() not supported by OpenGL 2.0 (since OpenGL 4.0)" ; |
331 | } |
332 | |
333 | void GraphicsHelperGL2::alphaTest(GLenum mode1, GLenum mode2) |
334 | { |
335 | m_funcs->glEnable(GL_ALPHA_TEST); |
336 | m_funcs->glAlphaFunc(func: mode1, ref: mode2); |
337 | } |
338 | |
339 | void GraphicsHelperGL2::depthTest(GLenum mode) |
340 | { |
341 | m_funcs->glEnable(GL_DEPTH_TEST); |
342 | m_funcs->glDepthFunc(func: mode); |
343 | } |
344 | |
345 | void GraphicsHelperGL2::depthMask(GLenum mode) |
346 | { |
347 | m_funcs->glDepthMask(flag: mode); |
348 | } |
349 | |
350 | void GraphicsHelperGL2::depthRange(GLdouble nearValue, GLdouble farValue) |
351 | { |
352 | m_funcs->glDepthRange(nearVal: nearValue, farVal: farValue); |
353 | } |
354 | |
355 | void GraphicsHelperGL2::frontFace(GLenum mode) |
356 | { |
357 | m_funcs->glFrontFace(mode); |
358 | } |
359 | |
360 | void GraphicsHelperGL2::setMSAAEnabled(bool enabled) |
361 | { |
362 | enabled ? m_funcs->glEnable(GL_MULTISAMPLE) |
363 | : m_funcs->glDisable(GL_MULTISAMPLE); |
364 | } |
365 | |
366 | void GraphicsHelperGL2::setAlphaCoverageEnabled(bool enabled) |
367 | { |
368 | enabled ? m_funcs->glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE) |
369 | : m_funcs->glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); |
370 | } |
371 | |
372 | GLuint GraphicsHelperGL2::createFrameBufferObject() |
373 | { |
374 | if (m_fboFuncs != nullptr) { |
375 | GLuint id; |
376 | m_fboFuncs->glGenFramebuffers(n: 1, framebuffers: &id); |
377 | return id; |
378 | } |
379 | qWarning() << "FBO not supported by your OpenGL hardware" ; |
380 | return 0; |
381 | } |
382 | |
383 | void GraphicsHelperGL2::releaseFrameBufferObject(GLuint frameBufferId) |
384 | { |
385 | if (m_fboFuncs != nullptr) |
386 | m_fboFuncs->glDeleteFramebuffers(n: 1, framebuffers: &frameBufferId); |
387 | else |
388 | qWarning() << "FBO not supported by your OpenGL hardware" ; |
389 | } |
390 | |
391 | bool GraphicsHelperGL2::checkFrameBufferComplete() |
392 | { |
393 | if (m_fboFuncs != nullptr) |
394 | return (m_fboFuncs->glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); |
395 | return false; |
396 | } |
397 | |
398 | bool GraphicsHelperGL2::frameBufferNeedsRenderBuffer(const Attachment &attachment) |
399 | { |
400 | Q_UNUSED(attachment); |
401 | return false; |
402 | } |
403 | |
404 | void GraphicsHelperGL2::bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) |
405 | { |
406 | if (m_fboFuncs != nullptr) { |
407 | GLenum attr = GL_DEPTH_STENCIL_ATTACHMENT; |
408 | |
409 | if (attachment.m_point <= QRenderTargetOutput::Color15) |
410 | attr = GL_COLOR_ATTACHMENT0 + attachment.m_point; |
411 | else if (attachment.m_point == QRenderTargetOutput::Depth) |
412 | attr = GL_DEPTH_ATTACHMENT; |
413 | else if (attachment.m_point == QRenderTargetOutput::Stencil) |
414 | attr = GL_STENCIL_ATTACHMENT; |
415 | else |
416 | qCritical() << "DepthStencil Attachment not supported on OpenGL 2.0" ; |
417 | |
418 | const QOpenGLTexture::Target target = texture->target(); |
419 | |
420 | if (target == QOpenGLTexture::TargetCubeMap && attachment.m_face == QAbstractTexture::AllFaces) { |
421 | qWarning() << "OpenGL 2.0 doesn't handle attaching all the faces of a cube map texture at once to an FBO" ; |
422 | return; |
423 | } |
424 | |
425 | texture->bind(); |
426 | if (target == QOpenGLTexture::Target3D) |
427 | m_fboFuncs->glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER, attachment: attr, textarget: target, texture: texture->textureId(), level: attachment.m_mipLevel, zoffset: attachment.m_layer); |
428 | else if (target == QOpenGLTexture::TargetCubeMap) |
429 | m_fboFuncs->glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment: attr, textarget: attachment.m_face, texture: texture->textureId(), level: attachment.m_mipLevel); |
430 | else if (target == QOpenGLTexture::Target1D) |
431 | m_fboFuncs->glFramebufferTexture1D(GL_DRAW_FRAMEBUFFER, attachment: attr, textarget: target, texture: texture->textureId(), level: attachment.m_mipLevel); |
432 | else if (target == QOpenGLTexture::Target2D || target == QOpenGLTexture::TargetRectangle) |
433 | m_fboFuncs->glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment: attr, textarget: target, texture: texture->textureId(), level: attachment.m_mipLevel); |
434 | else |
435 | qCritical() << "Texture format not supported for Attachment on OpenGL 2.0" ; |
436 | texture->release(); |
437 | } |
438 | } |
439 | |
440 | void GraphicsHelperGL2::bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment) |
441 | { |
442 | Q_UNUSED(renderBuffer); |
443 | Q_UNUSED(attachment); |
444 | Q_UNREACHABLE(); |
445 | } |
446 | |
447 | bool GraphicsHelperGL2::supportsFeature(GraphicsHelperInterface::Feature feature) const |
448 | { |
449 | switch (feature) { |
450 | case MRT: |
451 | return (m_fboFuncs != nullptr); |
452 | case TextureDimensionRetrieval: |
453 | case MapBuffer: |
454 | return true; |
455 | default: |
456 | return false; |
457 | } |
458 | } |
459 | |
460 | void GraphicsHelperGL2::drawBuffers(GLsizei n, const int *bufs) |
461 | { |
462 | QVarLengthArray<GLenum, 16> drawBufs(n); |
463 | |
464 | for (int i = 0; i < n; i++) |
465 | drawBufs[i] = GL_COLOR_ATTACHMENT0 + bufs[i]; |
466 | m_funcs->glDrawBuffers(n, bufs: drawBufs.constData()); |
467 | } |
468 | |
469 | void GraphicsHelperGL2::bindFragDataLocation(GLuint, const QHash<QString, int> &) |
470 | { |
471 | qCritical() << "bindFragDataLocation is not supported by GL 2.0" ; |
472 | } |
473 | |
474 | void GraphicsHelperGL2::bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode) |
475 | { |
476 | if (m_fboFuncs != nullptr) { |
477 | switch (mode) { |
478 | case FBODraw: |
479 | m_fboFuncs->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer: frameBufferId); |
480 | return; |
481 | case FBORead: |
482 | m_fboFuncs->glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer: frameBufferId); |
483 | return; |
484 | case FBOReadAndDraw: |
485 | default: |
486 | m_fboFuncs->glBindFramebuffer(GL_FRAMEBUFFER, framebuffer: frameBufferId); |
487 | return; |
488 | } |
489 | } else { |
490 | qWarning() << "FBO not supported by your OpenGL hardware" ; |
491 | } |
492 | } |
493 | |
494 | void GraphicsHelperGL2::bindImageTexture(GLuint imageUnit, GLuint texture, |
495 | GLint mipLevel, GLboolean layered, |
496 | GLint layer, GLenum access, GLenum format) |
497 | { |
498 | Q_UNUSED(imageUnit) |
499 | Q_UNUSED(texture) |
500 | Q_UNUSED(mipLevel) |
501 | Q_UNUSED(layered) |
502 | Q_UNUSED(layer) |
503 | Q_UNUSED(access) |
504 | Q_UNUSED(format) |
505 | qWarning() << "Shader Images are not supported by OpenGL 2.0 (since OpenGL 4.2)" ; |
506 | |
507 | } |
508 | |
509 | GLuint GraphicsHelperGL2::boundFrameBufferObject() |
510 | { |
511 | GLint id = 0; |
512 | m_funcs->glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, params: &id); |
513 | return id; |
514 | } |
515 | |
516 | void GraphicsHelperGL2::bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) |
517 | { |
518 | Q_UNUSED(programId); |
519 | Q_UNUSED(uniformBlockIndex); |
520 | Q_UNUSED(uniformBlockBinding); |
521 | qWarning() << "UBO are not supported by OpenGL 2.0 (since OpenGL 3.1)" ; |
522 | } |
523 | |
524 | void GraphicsHelperGL2::bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) |
525 | { |
526 | Q_UNUSED(programId); |
527 | Q_UNUSED(shaderStorageBlockIndex); |
528 | Q_UNUSED(shaderStorageBlockBinding); |
529 | qWarning() << "SSBO are not supported by OpenGL 2.0 (since OpenGL 4.3)" ; |
530 | } |
531 | |
532 | void GraphicsHelperGL2::bindBufferBase(GLenum target, GLuint index, GLuint buffer) |
533 | { |
534 | Q_UNUSED(target); |
535 | Q_UNUSED(index); |
536 | Q_UNUSED(buffer); |
537 | qWarning() << "bindBufferBase is not supported by OpenGL 2.0 (since OpenGL 3.0)" ; |
538 | } |
539 | |
540 | void GraphicsHelperGL2::buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer) |
541 | { |
542 | Q_UNUSED(v); |
543 | Q_UNUSED(description); |
544 | Q_UNUSED(buffer); |
545 | qWarning() << "UBO are not supported by OpenGL 2.0 (since OpenGL 3.1)" ; |
546 | } |
547 | |
548 | uint GraphicsHelperGL2::uniformByteSize(const ShaderUniform &description) |
549 | { |
550 | uint rawByteSize = 0; |
551 | int arrayStride = qMax(a: description.m_arrayStride, b: 0); |
552 | int matrixStride = qMax(a: description.m_matrixStride, b: 0); |
553 | |
554 | switch (description.m_type) { |
555 | |
556 | case GL_FLOAT_VEC2: |
557 | case GL_INT_VEC2: |
558 | rawByteSize = 8; |
559 | break; |
560 | |
561 | case GL_FLOAT_VEC3: |
562 | case GL_INT_VEC3: |
563 | rawByteSize = 12; |
564 | break; |
565 | |
566 | case GL_FLOAT_VEC4: |
567 | case GL_INT_VEC4: |
568 | rawByteSize = 16; |
569 | break; |
570 | |
571 | case GL_FLOAT_MAT2: |
572 | rawByteSize = matrixStride ? 2 * matrixStride : 16; |
573 | break; |
574 | |
575 | case GL_FLOAT_MAT2x4: |
576 | rawByteSize = matrixStride ? 2 * matrixStride : 32; |
577 | break; |
578 | |
579 | case GL_FLOAT_MAT4x2: |
580 | rawByteSize = matrixStride ? 4 * matrixStride : 32; |
581 | break; |
582 | |
583 | case GL_FLOAT_MAT3: |
584 | rawByteSize = matrixStride ? 3 * matrixStride : 36; |
585 | break; |
586 | |
587 | case GL_FLOAT_MAT2x3: |
588 | rawByteSize = matrixStride ? 2 * matrixStride : 24; |
589 | break; |
590 | |
591 | case GL_FLOAT_MAT3x2: |
592 | rawByteSize = matrixStride ? 3 * matrixStride : 24; |
593 | break; |
594 | |
595 | case GL_FLOAT_MAT4: |
596 | rawByteSize = matrixStride ? 4 * matrixStride : 64; |
597 | break; |
598 | |
599 | case GL_FLOAT_MAT4x3: |
600 | rawByteSize = matrixStride ? 4 * matrixStride : 48; |
601 | break; |
602 | |
603 | case GL_FLOAT_MAT3x4: |
604 | rawByteSize = matrixStride ? 3 * matrixStride : 48; |
605 | break; |
606 | |
607 | case GL_BOOL: |
608 | rawByteSize = 1; |
609 | break; |
610 | |
611 | case GL_BOOL_VEC2: |
612 | rawByteSize = 2; |
613 | break; |
614 | |
615 | case GL_BOOL_VEC3: |
616 | rawByteSize = 3; |
617 | break; |
618 | |
619 | case GL_BOOL_VEC4: |
620 | rawByteSize = 4; |
621 | break; |
622 | |
623 | case GL_INT: |
624 | case GL_FLOAT: |
625 | case GL_SAMPLER_1D: |
626 | case GL_SAMPLER_1D_SHADOW: |
627 | case GL_SAMPLER_2D: |
628 | case GL_SAMPLER_2D_SHADOW: |
629 | case GL_SAMPLER_3D: |
630 | case GL_SAMPLER_CUBE: |
631 | rawByteSize = 4; |
632 | break; |
633 | |
634 | default: |
635 | Q_UNREACHABLE(); |
636 | } |
637 | |
638 | return arrayStride ? rawByteSize * arrayStride : rawByteSize; |
639 | } |
640 | |
641 | void GraphicsHelperGL2::enableClipPlane(int clipPlane) |
642 | { |
643 | m_funcs->glEnable(GL_CLIP_DISTANCE0 + clipPlane); |
644 | } |
645 | |
646 | void GraphicsHelperGL2::disableClipPlane(int clipPlane) |
647 | { |
648 | m_funcs->glDisable(GL_CLIP_DISTANCE0 + clipPlane); |
649 | } |
650 | |
651 | void GraphicsHelperGL2::setClipPlane(int clipPlane, const QVector3D &normal, float distance) |
652 | { |
653 | double plane[4]; |
654 | plane[0] = normal.x(); |
655 | plane[1] = normal.y(); |
656 | plane[2] = normal.z(); |
657 | plane[3] = distance; |
658 | |
659 | m_funcs->glClipPlane(GL_CLIP_PLANE0 + clipPlane, equation: plane); |
660 | } |
661 | |
662 | GLint GraphicsHelperGL2::maxClipPlaneCount() |
663 | { |
664 | GLint max = 0; |
665 | m_funcs->glGetIntegerv(GL_MAX_CLIP_DISTANCES, params: &max); |
666 | return max; |
667 | } |
668 | |
669 | void GraphicsHelperGL2::memoryBarrier(QMemoryBarrier::Operations barriers) |
670 | { |
671 | Q_UNUSED(barriers); |
672 | qWarning() << "memory barrier is not supported by OpenGL 2.0 (since 4.3)" ; |
673 | } |
674 | |
675 | void GraphicsHelperGL2::enablePrimitiveRestart(int) |
676 | { |
677 | } |
678 | |
679 | void GraphicsHelperGL2::enableVertexAttributeArray(int location) |
680 | { |
681 | m_funcs->glEnableVertexAttribArray(index: location); |
682 | } |
683 | |
684 | void GraphicsHelperGL2::disablePrimitiveRestart() |
685 | { |
686 | } |
687 | |
688 | void GraphicsHelperGL2::clearBufferf(GLint drawbuffer, const QVector4D &values) |
689 | { |
690 | Q_UNUSED(drawbuffer); |
691 | Q_UNUSED(values); |
692 | qWarning() << "glClearBuffer*() not supported by OpenGL 2.0" ; |
693 | } |
694 | |
695 | void GraphicsHelperGL2::pointSize(bool programmable, GLfloat value) |
696 | { |
697 | m_funcs->glEnable(GL_POINT_SPRITE); |
698 | if (programmable) |
699 | m_funcs->glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); |
700 | else |
701 | m_funcs->glPointSize(size: value); |
702 | } |
703 | |
704 | void GraphicsHelperGL2::enablei(GLenum cap, GLuint index) |
705 | { |
706 | Q_UNUSED(cap); |
707 | Q_UNUSED(index); |
708 | qWarning() << "glEnablei() not supported by OpenGL 2.0 (since 3.0)" ; |
709 | } |
710 | |
711 | void GraphicsHelperGL2::disablei(GLenum cap, GLuint index) |
712 | { |
713 | Q_UNUSED(cap); |
714 | Q_UNUSED(index); |
715 | qWarning() << "glDisablei() not supported by OpenGL 2.0 (since 3.0)" ; |
716 | } |
717 | |
718 | void GraphicsHelperGL2::setSeamlessCubemap(bool enable) |
719 | { |
720 | Q_UNUSED(enable); |
721 | qWarning() << "GL_TEXTURE_CUBE_MAP_SEAMLESS not supported by OpenGL 2.0 (since 3.2)" ; |
722 | } |
723 | |
724 | QSize GraphicsHelperGL2::getRenderBufferDimensions(GLuint renderBufferId) |
725 | { |
726 | Q_UNUSED(renderBufferId); |
727 | qCritical() << "RenderBuffer dimensions retrival not supported on OpenGL 2.0" ; |
728 | return QSize(0,0); |
729 | } |
730 | |
731 | QSize GraphicsHelperGL2::getTextureDimensions(GLuint textureId, GLenum target, uint level) |
732 | { |
733 | GLint width = 0; |
734 | GLint height = 0; |
735 | |
736 | m_funcs->glBindTexture(target, texture: textureId); |
737 | m_funcs->glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, params: &width); |
738 | m_funcs->glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, params: &height); |
739 | m_funcs->glBindTexture(target, texture: 0); |
740 | |
741 | return QSize(width, height); |
742 | } |
743 | |
744 | void GraphicsHelperGL2::dispatchCompute(GLuint wx, GLuint wy, GLuint wz) |
745 | { |
746 | Q_UNUSED(wx); |
747 | Q_UNUSED(wy); |
748 | Q_UNUSED(wz); |
749 | qWarning() << "Compute Shaders are not supported by OpenGL 2.0 (since OpenGL 4.3)" ; |
750 | } |
751 | |
752 | char *GraphicsHelperGL2::mapBuffer(GLenum target, GLsizeiptr size) |
753 | { |
754 | Q_UNUSED(size); |
755 | return static_cast<char*>(m_funcs->glMapBuffer(target, GL_READ_WRITE)); |
756 | } |
757 | |
758 | GLboolean GraphicsHelperGL2::unmapBuffer(GLenum target) |
759 | { |
760 | return m_funcs->glUnmapBuffer(target); |
761 | } |
762 | |
763 | void GraphicsHelperGL2::glUniform1fv(GLint location, GLsizei count, const GLfloat *values) |
764 | { |
765 | m_funcs->glUniform1fv(location, count, value: values); |
766 | } |
767 | |
768 | void GraphicsHelperGL2::glUniform2fv(GLint location, GLsizei count, const GLfloat *values) |
769 | { |
770 | m_funcs->glUniform2fv(location, count, value: values); |
771 | } |
772 | |
773 | void GraphicsHelperGL2::glUniform3fv(GLint location, GLsizei count, const GLfloat *values) |
774 | { |
775 | m_funcs->glUniform3fv(location, count, value: values); |
776 | } |
777 | |
778 | void GraphicsHelperGL2::glUniform4fv(GLint location, GLsizei count, const GLfloat *values) |
779 | { |
780 | m_funcs->glUniform4fv(location, count, value: values); |
781 | } |
782 | |
783 | void GraphicsHelperGL2::glUniform1iv(GLint location, GLsizei count, const GLint *values) |
784 | { |
785 | m_funcs->glUniform1iv(location, count, value: values); |
786 | } |
787 | |
788 | void GraphicsHelperGL2::glUniform2iv(GLint location, GLsizei count, const GLint *values) |
789 | { |
790 | m_funcs->glUniform2iv(location, count, value: values); |
791 | } |
792 | |
793 | void GraphicsHelperGL2::glUniform3iv(GLint location, GLsizei count, const GLint *values) |
794 | { |
795 | m_funcs->glUniform3iv(location, count, value: values); |
796 | } |
797 | |
798 | void GraphicsHelperGL2::glUniform4iv(GLint location, GLsizei count, const GLint *values) |
799 | { |
800 | m_funcs->glUniform4iv(location, count, value: values); |
801 | } |
802 | |
803 | void GraphicsHelperGL2::glUniform1uiv(GLint , GLsizei , const GLuint *) |
804 | { |
805 | qWarning() << "glUniform1uiv not supported by GL 2" ; |
806 | } |
807 | |
808 | void GraphicsHelperGL2::glUniform2uiv(GLint , GLsizei , const GLuint *) |
809 | { |
810 | qWarning() << "glUniform2uiv not supported by GL 2" ; |
811 | } |
812 | |
813 | void GraphicsHelperGL2::glUniform3uiv(GLint , GLsizei , const GLuint *) |
814 | { |
815 | qWarning() << "glUniform3uiv not supported by GL 2" ; |
816 | } |
817 | |
818 | void GraphicsHelperGL2::glUniform4uiv(GLint , GLsizei , const GLuint *) |
819 | { |
820 | qWarning() << "glUniform4uiv not supported by GL 2" ; |
821 | } |
822 | |
823 | void GraphicsHelperGL2::glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *values) |
824 | { |
825 | m_funcs->glUniformMatrix2fv(location, count, transpose: false, value: values); |
826 | } |
827 | |
828 | void GraphicsHelperGL2::glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *values) |
829 | { |
830 | m_funcs->glUniformMatrix3fv(location, count, transpose: false, value: values); |
831 | } |
832 | |
833 | void GraphicsHelperGL2::glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *values) |
834 | { |
835 | m_funcs->glUniformMatrix4fv(location, count, transpose: false, value: values); |
836 | } |
837 | |
838 | void GraphicsHelperGL2::glUniformMatrix2x3fv(GLint , GLsizei , const GLfloat *) |
839 | { |
840 | qWarning() << "glUniformMatrix2x3fv not supported by GL 2" ; |
841 | } |
842 | |
843 | void GraphicsHelperGL2::glUniformMatrix3x2fv(GLint , GLsizei , const GLfloat *) |
844 | { |
845 | qWarning() << "glUniformMatrix3x2fv not supported by GL 2" ; |
846 | } |
847 | |
848 | void GraphicsHelperGL2::glUniformMatrix2x4fv(GLint , GLsizei , const GLfloat *) |
849 | { |
850 | qWarning() << "glUniformMatrix2x4fv not supported by GL 2" ; |
851 | } |
852 | |
853 | void GraphicsHelperGL2::glUniformMatrix4x2fv(GLint , GLsizei , const GLfloat *) |
854 | { |
855 | qWarning() << "glUniformMatrix4x2fv not supported by GL 2" ; |
856 | } |
857 | |
858 | void GraphicsHelperGL2::glUniformMatrix3x4fv(GLint , GLsizei , const GLfloat *) |
859 | { |
860 | qWarning() << "glUniformMatrix3x4fv not supported by GL 2" ; |
861 | } |
862 | |
863 | void GraphicsHelperGL2::glUniformMatrix4x3fv(GLint , GLsizei , const GLfloat *) |
864 | { |
865 | qWarning() << "glUniformMatrix4x3fv not supported by GL 2" ; |
866 | } |
867 | |
868 | UniformType GraphicsHelperGL2::uniformTypeFromGLType(GLenum type) |
869 | { |
870 | switch (type) { |
871 | case GL_FLOAT: |
872 | return UniformType::Float; |
873 | case GL_FLOAT_VEC2: |
874 | return UniformType::Vec2; |
875 | case GL_FLOAT_VEC3: |
876 | return UniformType::Vec3; |
877 | case GL_FLOAT_VEC4: |
878 | return UniformType::Vec4; |
879 | case GL_FLOAT_MAT2: |
880 | return UniformType::Mat2; |
881 | case GL_FLOAT_MAT3: |
882 | return UniformType::Mat3; |
883 | case GL_FLOAT_MAT4: |
884 | return UniformType::Mat4; |
885 | case GL_INT: |
886 | return UniformType::Int; |
887 | case GL_INT_VEC2: |
888 | return UniformType::IVec2; |
889 | case GL_INT_VEC3: |
890 | return UniformType::IVec3; |
891 | case GL_INT_VEC4: |
892 | return UniformType::IVec4; |
893 | case GL_BOOL: |
894 | return UniformType::Bool; |
895 | case GL_BOOL_VEC2: |
896 | return UniformType::BVec2; |
897 | case GL_BOOL_VEC3: |
898 | return UniformType::BVec3; |
899 | case GL_BOOL_VEC4: |
900 | return UniformType::BVec4; |
901 | |
902 | case GL_SAMPLER_1D: |
903 | case GL_SAMPLER_1D_SHADOW: |
904 | case GL_SAMPLER_2D: |
905 | case GL_SAMPLER_2D_SHADOW: |
906 | case GL_SAMPLER_CUBE: |
907 | case GL_SAMPLER_3D: |
908 | return UniformType::Sampler; |
909 | |
910 | default: |
911 | Q_UNREACHABLE(); |
912 | return UniformType::Float; |
913 | } |
914 | } |
915 | |
916 | void GraphicsHelperGL2::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) |
917 | { |
918 | Q_UNUSED(srcX0); |
919 | Q_UNUSED(srcX1); |
920 | Q_UNUSED(srcY0); |
921 | Q_UNUSED(srcY1); |
922 | Q_UNUSED(dstX0); |
923 | Q_UNUSED(dstX1); |
924 | Q_UNUSED(dstY0); |
925 | Q_UNUSED(dstY1); |
926 | Q_UNUSED(mask); |
927 | Q_UNUSED(filter); |
928 | qWarning() << "Framebuffer blits are not supported by ES 2.0 (since ES 3.1)" ; |
929 | } |
930 | |
931 | } // namespace OpenGL |
932 | } // namespace Render |
933 | } // namespace Qt3DRender |
934 | |
935 | QT_END_NAMESPACE |
936 | |
937 | #endif // !QT_OPENGL_ES_2 |
938 | |