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