1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB). |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the QtGui 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 "qopengltexturehelper_p.h" |
41 | |
42 | #include <QOpenGLContext> |
43 | #include <private/qopenglextensions_p.h> |
44 | |
45 | QT_BEGIN_NAMESPACE |
46 | |
47 | QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context) |
48 | { |
49 | functions = context->functions(); |
50 | // Resolve EXT_direct_state_access entry points if present. |
51 | |
52 | // However, disable it on some systems where DSA is known to be unreliable. |
53 | bool allowDSA = true; |
54 | const char *renderer = reinterpret_cast<const char *>(context->functions()->glGetString(GL_RENDERER)); |
55 | // QTBUG-40653, QTBUG-44988 |
56 | if (renderer && strstr(haystack: renderer, needle: "AMD Radeon HD" )) |
57 | allowDSA = false; |
58 | |
59 | if (allowDSA && !context->isOpenGLES() |
60 | && context->hasExtension(QByteArrayLiteral("GL_EXT_direct_state_access" ))) { |
61 | TextureParameteriEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , GLint )>(context->getProcAddress(procName: "glTextureParameteriEXT" )); |
62 | TextureParameterivEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , const GLint *)>(context->getProcAddress(procName: "glTextureParameterivEXT" )); |
63 | TextureParameterfEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , GLfloat )>(context->getProcAddress(procName: "glTextureParameterfEXT" )); |
64 | TextureParameterfvEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , const GLfloat *)>(context->getProcAddress(procName: "glTextureParameterfvEXT" )); |
65 | GenerateTextureMipmapEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum )>(context->getProcAddress(procName: "glGenerateTextureMipmapEXT" )); |
66 | TextureStorage3DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLsizei , GLenum , GLsizei , GLsizei , GLsizei )>(context->getProcAddress(procName: "glTextureStorage3DEXT" )); |
67 | TextureStorage2DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLsizei , GLenum , GLsizei , GLsizei )>(context->getProcAddress(procName: "glTextureStorage2DEXT" )); |
68 | TextureStorage1DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLsizei , GLenum , GLsizei )>(context->getProcAddress(procName: "glTextureStorage1DEXT" )); |
69 | TextureStorage3DMultisampleEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLsizei , GLenum , GLsizei , GLsizei , GLsizei , GLboolean )>(context->getProcAddress(procName: "glTextureStorage3DMultisampleEXT" )); |
70 | TextureStorage2DMultisampleEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLsizei , GLenum , GLsizei , GLsizei , GLboolean )>(context->getProcAddress(procName: "glTextureStorage2DMultisampleEXT" )); |
71 | TextureImage3DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLint , GLenum , GLsizei , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(procName: "glTextureImage3DEXT" )); |
72 | TextureImage2DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLint , GLenum , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(procName: "glTextureImage2DEXT" )); |
73 | TextureImage1DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLint , GLenum , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(procName: "glTextureImage1DEXT" )); |
74 | TextureSubImage3DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(procName: "glTextureSubImage3DEXT" )); |
75 | TextureSubImage2DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLint , GLint , GLint , GLsizei , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(procName: "glTextureSubImage2DEXT" )); |
76 | TextureSubImage1DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLint , GLint , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(procName: "glTextureSubImage1DEXT" )); |
77 | CompressedTextureSubImage1DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLint , GLint , GLsizei , GLenum , GLsizei , const GLvoid *)>(context->getProcAddress(procName: "glCompressedTextureSubImage1DEXT" )); |
78 | CompressedTextureSubImage2DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLint , GLint , GLint , GLsizei , GLsizei , GLenum , GLsizei , const GLvoid *)>(context->getProcAddress(procName: "glCompressedTextureSubImage2DEXT" )); |
79 | CompressedTextureSubImage3DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLsizei , const GLvoid *)>(context->getProcAddress(procName: "glCompressedTextureSubImage3DEXT" )); |
80 | CompressedTextureImage1DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLint , GLenum , GLsizei , GLint , GLsizei , const GLvoid *)>(context->getProcAddress(procName: "glCompressedTextureImage1DEXT" )); |
81 | CompressedTextureImage2DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLint , GLenum , GLsizei , GLsizei , GLint , GLsizei , const GLvoid *)>(context->getProcAddress(procName: "glCompressedTextureImage2DEXT" )); |
82 | CompressedTextureImage3DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLint , GLenum , GLsizei , GLsizei , GLsizei , GLint , GLsizei , const GLvoid *)>(context->getProcAddress(procName: "glCompressedTextureImage3DEXT" )); |
83 | |
84 | // Use the real DSA functions |
85 | TextureParameteri = &QOpenGLTextureHelper::dsa_TextureParameteri; |
86 | TextureParameteriv = &QOpenGLTextureHelper::dsa_TextureParameteriv; |
87 | TextureParameterf = &QOpenGLTextureHelper::dsa_TextureParameterf; |
88 | TextureParameterfv = &QOpenGLTextureHelper::dsa_TextureParameterfv; |
89 | GenerateTextureMipmap = &QOpenGLTextureHelper::dsa_GenerateTextureMipmap; |
90 | TextureStorage3D = &QOpenGLTextureHelper::dsa_TextureStorage3D; |
91 | TextureStorage2D = &QOpenGLTextureHelper::dsa_TextureStorage2D; |
92 | TextureStorage1D = &QOpenGLTextureHelper::dsa_TextureStorage1D; |
93 | TextureStorage3DMultisample = &QOpenGLTextureHelper::dsa_TextureStorage3DMultisample; |
94 | TextureStorage2DMultisample = &QOpenGLTextureHelper::dsa_TextureStorage2DMultisample; |
95 | TextureImage3D = &QOpenGLTextureHelper::dsa_TextureImage3D; |
96 | TextureImage2D = &QOpenGLTextureHelper::dsa_TextureImage2D; |
97 | TextureImage1D = &QOpenGLTextureHelper::dsa_TextureImage1D; |
98 | TextureSubImage3D = &QOpenGLTextureHelper::dsa_TextureSubImage3D; |
99 | TextureSubImage2D = &QOpenGLTextureHelper::dsa_TextureSubImage2D; |
100 | TextureSubImage1D = &QOpenGLTextureHelper::dsa_TextureSubImage1D; |
101 | CompressedTextureSubImage1D = &QOpenGLTextureHelper::dsa_CompressedTextureSubImage1D; |
102 | CompressedTextureSubImage2D = &QOpenGLTextureHelper::dsa_CompressedTextureSubImage2D; |
103 | CompressedTextureSubImage3D = &QOpenGLTextureHelper::dsa_CompressedTextureSubImage3D; |
104 | CompressedTextureImage1D = &QOpenGLTextureHelper::dsa_CompressedTextureImage1D; |
105 | CompressedTextureImage2D = &QOpenGLTextureHelper::dsa_CompressedTextureImage2D; |
106 | CompressedTextureImage3D = &QOpenGLTextureHelper::dsa_CompressedTextureImage3D; |
107 | } else { |
108 | // Use our own DSA emulation |
109 | TextureParameteri = &QOpenGLTextureHelper::qt_TextureParameteri; |
110 | TextureParameteriv = &QOpenGLTextureHelper::qt_TextureParameteriv; |
111 | TextureParameterf = &QOpenGLTextureHelper::qt_TextureParameterf; |
112 | TextureParameterfv = &QOpenGLTextureHelper::qt_TextureParameterfv; |
113 | GenerateTextureMipmap = &QOpenGLTextureHelper::qt_GenerateTextureMipmap; |
114 | TextureStorage3D = &QOpenGLTextureHelper::qt_TextureStorage3D; |
115 | TextureStorage2D = &QOpenGLTextureHelper::qt_TextureStorage2D; |
116 | TextureStorage1D = &QOpenGLTextureHelper::qt_TextureStorage1D; |
117 | TextureStorage3DMultisample = &QOpenGLTextureHelper::qt_TextureStorage3DMultisample; |
118 | TextureStorage2DMultisample = &QOpenGLTextureHelper::qt_TextureStorage2DMultisample; |
119 | TextureImage3D = &QOpenGLTextureHelper::qt_TextureImage3D; |
120 | TextureImage2D = &QOpenGLTextureHelper::qt_TextureImage2D; |
121 | TextureImage1D = &QOpenGLTextureHelper::qt_TextureImage1D; |
122 | TextureSubImage3D = &QOpenGLTextureHelper::qt_TextureSubImage3D; |
123 | TextureSubImage2D = &QOpenGLTextureHelper::qt_TextureSubImage2D; |
124 | TextureSubImage1D = &QOpenGLTextureHelper::qt_TextureSubImage1D; |
125 | CompressedTextureSubImage1D = &QOpenGLTextureHelper::qt_CompressedTextureSubImage1D; |
126 | CompressedTextureSubImage2D = &QOpenGLTextureHelper::qt_CompressedTextureSubImage2D; |
127 | CompressedTextureSubImage3D = &QOpenGLTextureHelper::qt_CompressedTextureSubImage3D; |
128 | CompressedTextureImage1D = &QOpenGLTextureHelper::qt_CompressedTextureImage1D; |
129 | CompressedTextureImage2D = &QOpenGLTextureHelper::qt_CompressedTextureImage2D; |
130 | CompressedTextureImage3D = &QOpenGLTextureHelper::qt_CompressedTextureImage3D; |
131 | } |
132 | |
133 | // Some DSA functions are part of NV_texture_multisample instead |
134 | if (!context->isOpenGLES() |
135 | && context->hasExtension(QByteArrayLiteral("GL_NV_texture_multisample" ))) { |
136 | TextureImage3DMultisampleNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLsizei , GLint , GLsizei , GLsizei , GLsizei , GLboolean )>(context->getProcAddress(procName: "glTextureImage3DMultisampleNV" )); |
137 | TextureImage2DMultisampleNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLsizei , GLint , GLsizei , GLsizei , GLboolean )>(context->getProcAddress(procName: "glTextureImage2DMultisampleNV" )); |
138 | |
139 | TextureImage3DMultisample = &QOpenGLTextureHelper::dsa_TextureImage3DMultisample; |
140 | TextureImage2DMultisample = &QOpenGLTextureHelper::dsa_TextureImage2DMultisample; |
141 | } else { |
142 | TextureImage3DMultisample = &QOpenGLTextureHelper::qt_TextureImage3DMultisample; |
143 | TextureImage2DMultisample = &QOpenGLTextureHelper::qt_TextureImage2DMultisample; |
144 | } |
145 | |
146 | #if defined(QT_OPENGL_ES_2) |
147 | // Here we are targeting OpenGL ES 2.0+ only. This is likely using EGL, where, |
148 | // similarly to WGL, non-extension functions (i.e. any function that is part of the |
149 | // GLES spec) *may* not be queried via eglGetProcAddress. |
150 | |
151 | // OpenGL 1.0 |
152 | TexImage1D = 0; |
153 | |
154 | // OpenGL 1.1 |
155 | TexSubImage1D = 0; |
156 | |
157 | // OpenGL 1.3 |
158 | GetCompressedTexImage = 0; |
159 | CompressedTexSubImage1D = 0; |
160 | CompressedTexSubImage2D = ::glCompressedTexSubImage2D; |
161 | CompressedTexImage1D = 0; |
162 | CompressedTexImage2D = ::glCompressedTexImage2D; |
163 | ActiveTexture = ::glActiveTexture; |
164 | |
165 | // OpenGL 3.0 |
166 | GenerateMipmap = ::glGenerateMipmap; |
167 | |
168 | // OpenGL 3.2 |
169 | TexImage3DMultisample = 0; |
170 | TexImage2DMultisample = 0; |
171 | |
172 | // OpenGL 4.2 |
173 | QOpenGLContext *ctx = QOpenGLContext::currentContext(); |
174 | if (ctx->format().majorVersion() >= 3) { |
175 | // OpenGL ES 3.0+ has immutable storage for 2D and 3D at least. |
176 | QOpenGLExtraFunctionsPrivate *extra = static_cast<QOpenGLExtensions *>(context->extraFunctions())->d(); |
177 | TexStorage3D = extra->f.TexStorage3D; |
178 | TexStorage2D = extra->f.TexStorage2D; |
179 | } else { |
180 | TexStorage3D = 0; |
181 | TexStorage2D = 0; |
182 | } |
183 | TexStorage1D = 0; |
184 | |
185 | // OpenGL 4.3 |
186 | TexStorage3DMultisample = 0; |
187 | TexStorage2DMultisample = 0; |
188 | TexBufferRange = 0; |
189 | TextureView = 0; |
190 | |
191 | // OpenGL ES 3.1+ has TexStorage2DMultisample |
192 | if (ctx->format().version() >= qMakePair(3, 1)) { |
193 | QOpenGLExtraFunctionsPrivate *extra = static_cast<QOpenGLExtensions *>(context->extraFunctions())->d(); |
194 | TexStorage2DMultisample = extra->f.TexStorage2DMultisample; |
195 | } |
196 | |
197 | #endif |
198 | |
199 | if (context->isOpenGLES() && context->hasExtension(QByteArrayLiteral("GL_OES_texture_3D" ))) { |
200 | TexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*)>(context->getProcAddress(procName: "glTexImage3DOES" )); |
201 | TexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid*)>(context->getProcAddress(procName: "glTexSubImage3DOES" )); |
202 | CompressedTexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid*)>(context->getProcAddress(procName: "glCompressedTexImage3DOES" )); |
203 | CompressedTexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid*)>(context->getProcAddress(procName: "glCompressedTexSubImage3DOES" )); |
204 | } else { |
205 | QOpenGLContext *ctx = QOpenGLContext::currentContext(); |
206 | if (ctx->isOpenGLES() && ctx->format().majorVersion() >= 3) { |
207 | // OpenGL ES 3.0+ has glTexImage3D. |
208 | QOpenGLExtraFunctionsPrivate * = static_cast<QOpenGLExtensions *>(context->extraFunctions())->d(); |
209 | TexImage3D = extra->f.TexImage3D; |
210 | TexSubImage3D = extra->f.TexSubImage3D; |
211 | CompressedTexImage3D = extra->f.CompressedTexImage3D; |
212 | CompressedTexSubImage3D = extra->f.CompressedTexSubImage3D; |
213 | } else { |
214 | // OpenGL 1.2 |
215 | TexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(procName: "glTexImage3D" )); |
216 | TexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(procName: "glTexSubImage3D" )); |
217 | |
218 | // OpenGL 1.3 |
219 | CompressedTexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLenum , GLsizei , GLsizei , GLsizei , GLint , GLsizei , const GLvoid *)>(context->getProcAddress(procName: "glCompressedTexImage3D" )); |
220 | CompressedTexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLsizei , const GLvoid *)>(context->getProcAddress(procName: "glCompressedTexSubImage3D" )); |
221 | } |
222 | } |
223 | |
224 | #ifndef QT_OPENGL_ES_2 |
225 | // OpenGL 1.0 and 1.1 |
226 | TexImage1D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(procName: "glTexImage1D" )); |
227 | TexSubImage1D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(procName: "glTexSubImage1D" ));\ |
228 | |
229 | // OpenGL 1.3 |
230 | GetCompressedTexImage = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLvoid *)>(context->getProcAddress(procName: "glGetCompressedTexImage" )); |
231 | CompressedTexSubImage1D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLenum , GLsizei , const GLvoid *)>(context->getProcAddress(procName: "glCompressedTexSubImage1D" )); |
232 | CompressedTexSubImage2D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLsizei , GLsizei , GLenum , GLsizei , const GLvoid *)>(context->getProcAddress(procName: "glCompressedTexSubImage2D" )); |
233 | CompressedTexImage1D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLenum , GLsizei , GLint , GLsizei , const GLvoid *)>(context->getProcAddress(procName: "glCompressedTexImage1D" )); |
234 | CompressedTexImage2D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLenum , GLsizei , GLsizei , GLint , GLsizei , const GLvoid *)>(context->getProcAddress(procName: "glCompressedTexImage2D" )); |
235 | ActiveTexture = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum )>(context->getProcAddress(procName: "glActiveTexture" )); |
236 | |
237 | // OpenGL 3.0 |
238 | GenerateMipmap = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum )>(context->getProcAddress(procName: "glGenerateMipmap" )); |
239 | |
240 | // OpenGL 3.2 |
241 | TexImage3DMultisample = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLsizei , GLint , GLsizei , GLsizei , GLsizei , GLboolean )>(context->getProcAddress(procName: "glTexImage3DMultisample" )); |
242 | TexImage2DMultisample = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLsizei , GLint , GLsizei , GLsizei , GLboolean )>(context->getProcAddress(procName: "glTexImage2DMultisample" )); |
243 | |
244 | // OpenGL 4.2 |
245 | TexStorage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLsizei , GLenum , GLsizei , GLsizei , GLsizei )>(context->getProcAddress(procName: "glTexStorage3D" )); |
246 | TexStorage2D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLsizei , GLenum , GLsizei , GLsizei )>(context->getProcAddress(procName: "glTexStorage2D" )); |
247 | TexStorage1D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLsizei , GLenum , GLsizei )>(context->getProcAddress(procName: "glTexStorage1D" )); |
248 | |
249 | // OpenGL 4.3 |
250 | TexStorage3DMultisample = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLsizei , GLenum , GLsizei , GLsizei , GLsizei , GLboolean )>(context->getProcAddress(procName: "glTexStorage3DMultisample" )); |
251 | TexStorage2DMultisample = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLsizei , GLenum , GLsizei , GLsizei , GLboolean )>(context->getProcAddress(procName: "glTexStorage2DMultisample" )); |
252 | TexBufferRange = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLenum , GLuint , GLintptr , GLsizeiptr )>(context->getProcAddress(procName: "glTexBufferRange" )); |
253 | TextureView = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLuint , GLenum , GLuint , GLuint , GLuint , GLuint )>(context->getProcAddress(procName: "glTextureView" )); |
254 | #endif |
255 | } |
256 | |
257 | void QOpenGLTextureHelper::dsa_TextureParameteri(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param) |
258 | { |
259 | Q_UNUSED(bindingTarget); |
260 | TextureParameteriEXT(texture, target, pname, param); |
261 | } |
262 | |
263 | void QOpenGLTextureHelper::dsa_TextureParameteriv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLint *params) |
264 | { |
265 | Q_UNUSED(bindingTarget); |
266 | TextureParameterivEXT(texture, target, pname, params); |
267 | } |
268 | |
269 | void QOpenGLTextureHelper::dsa_TextureParameterf(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLfloat param) |
270 | { |
271 | Q_UNUSED(bindingTarget); |
272 | TextureParameterfEXT(texture, target, pname, param); |
273 | } |
274 | |
275 | void QOpenGLTextureHelper::dsa_TextureParameterfv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLfloat *params) |
276 | { |
277 | Q_UNUSED(bindingTarget); |
278 | TextureParameterfvEXT(texture, target, pname, params); |
279 | } |
280 | |
281 | void QOpenGLTextureHelper::dsa_GenerateTextureMipmap(GLuint texture, GLenum target, GLenum bindingTarget) |
282 | { |
283 | Q_UNUSED(bindingTarget); |
284 | GenerateTextureMipmapEXT(texture, target); |
285 | } |
286 | |
287 | void QOpenGLTextureHelper::dsa_TextureStorage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth) |
288 | { |
289 | Q_UNUSED(bindingTarget); |
290 | TextureStorage3DEXT(texture, target, levels, internalFormat, width, height, depth); |
291 | } |
292 | |
293 | void QOpenGLTextureHelper::dsa_TextureStorage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height) |
294 | { |
295 | Q_UNUSED(bindingTarget); |
296 | TextureStorage2DEXT(texture, target, levels, internalFormat, width, height); |
297 | } |
298 | |
299 | void QOpenGLTextureHelper::dsa_TextureStorage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width) |
300 | { |
301 | Q_UNUSED(bindingTarget); |
302 | TextureStorage1DEXT(texture, target, levels, internalFormat, width); |
303 | } |
304 | |
305 | void QOpenGLTextureHelper::dsa_TextureStorage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations) |
306 | { |
307 | Q_UNUSED(bindingTarget); |
308 | TextureStorage3DMultisampleEXT(texture, target, samples, internalFormat, width, height, depth, fixedSampleLocations); |
309 | } |
310 | |
311 | void QOpenGLTextureHelper::dsa_TextureStorage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations) |
312 | { |
313 | Q_UNUSED(bindingTarget); |
314 | TextureStorage2DMultisampleEXT(texture, target, samples, internalFormat, width, height, fixedSampleLocations); |
315 | } |
316 | |
317 | void QOpenGLTextureHelper::dsa_TextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels) |
318 | { |
319 | Q_UNUSED(bindingTarget); |
320 | TextureImage3DEXT(texture, target, level, internalFormat, width, height, depth, border, format, type, pixels); |
321 | } |
322 | |
323 | void QOpenGLTextureHelper::dsa_TextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) |
324 | { |
325 | Q_UNUSED(bindingTarget); |
326 | TextureImage2DEXT(texture, target, level, internalFormat, width, height, border, format, type, pixels); |
327 | } |
328 | |
329 | void QOpenGLTextureHelper::dsa_TextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels) |
330 | { |
331 | Q_UNUSED(bindingTarget); |
332 | TextureImage1DEXT(texture, target, level, internalFormat, width, border, format, type, pixels); |
333 | } |
334 | |
335 | void QOpenGLTextureHelper::dsa_TextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels) |
336 | { |
337 | Q_UNUSED(bindingTarget); |
338 | TextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); |
339 | } |
340 | |
341 | void QOpenGLTextureHelper::dsa_TextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) |
342 | { |
343 | Q_UNUSED(bindingTarget); |
344 | TextureSubImage2DEXT(texture, target, level, xoffset, yoffset, width, height, format, type, pixels); |
345 | } |
346 | |
347 | void QOpenGLTextureHelper::dsa_TextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels) |
348 | { |
349 | Q_UNUSED(bindingTarget); |
350 | TextureSubImage1DEXT(texture, target, level, xoffset, width, format, type, pixels); |
351 | } |
352 | |
353 | void QOpenGLTextureHelper::dsa_TextureImage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations) |
354 | { |
355 | Q_UNUSED(bindingTarget); |
356 | TextureImage3DMultisampleNV(texture, target, samples, internalFormat, width, height, depth, fixedSampleLocations); |
357 | } |
358 | |
359 | void QOpenGLTextureHelper::dsa_TextureImage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations) |
360 | { |
361 | Q_UNUSED(bindingTarget); |
362 | TextureImage2DMultisampleNV(texture, target, samples, internalFormat, width, height, fixedSampleLocations); |
363 | } |
364 | |
365 | void QOpenGLTextureHelper::dsa_CompressedTextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits) |
366 | { |
367 | Q_UNUSED(bindingTarget); |
368 | CompressedTextureSubImage1DEXT(texture, target, level, xoffset, width, format, imageSize, bits); |
369 | } |
370 | |
371 | void QOpenGLTextureHelper::dsa_CompressedTextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits) |
372 | { |
373 | Q_UNUSED(bindingTarget); |
374 | CompressedTextureSubImage2DEXT(texture, target, level, xoffset, yoffset, width, height, format, imageSize, bits); |
375 | } |
376 | |
377 | void QOpenGLTextureHelper::dsa_CompressedTextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits) |
378 | { |
379 | Q_UNUSED(bindingTarget); |
380 | CompressedTextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits); |
381 | } |
382 | |
383 | void QOpenGLTextureHelper::dsa_CompressedTextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits) |
384 | { |
385 | Q_UNUSED(bindingTarget); |
386 | CompressedTextureImage1DEXT(texture, target, level, internalFormat, width, border, imageSize, bits); |
387 | } |
388 | |
389 | void QOpenGLTextureHelper::dsa_CompressedTextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits) |
390 | { |
391 | Q_UNUSED(bindingTarget); |
392 | CompressedTextureImage2DEXT(texture, target, level, internalFormat, width, height, border, imageSize, bits); |
393 | } |
394 | |
395 | void QOpenGLTextureHelper::dsa_CompressedTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits) |
396 | { |
397 | Q_UNUSED(bindingTarget); |
398 | CompressedTextureImage3DEXT(texture, target, level, internalFormat, width, height, depth, border, imageSize, bits); |
399 | } |
400 | |
401 | namespace { |
402 | |
403 | class TextureBinder |
404 | { |
405 | public: |
406 | TextureBinder(QOpenGLFunctions *functions, GLuint texture, GLenum target, GLenum bindingTarget) |
407 | : m_functions(functions) |
408 | { |
409 | // For cubemaps we can't use the standard DSA emulation as it is illegal to |
410 | // try to bind a texture to one of the cubemap face targets. So we force the |
411 | // target and binding target to the cubemap values in this case. |
412 | switch (target) { |
413 | case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: |
414 | case GL_TEXTURE_CUBE_MAP_POSITIVE_X: |
415 | case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: |
416 | case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: |
417 | case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: |
418 | case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: |
419 | bindingTarget = GL_TEXTURE_BINDING_CUBE_MAP; |
420 | m_target = GL_TEXTURE_CUBE_MAP; |
421 | break; |
422 | |
423 | default: |
424 | m_target = target; |
425 | break; |
426 | } |
427 | |
428 | m_functions->glGetIntegerv(pname: bindingTarget, params: &m_oldTexture); |
429 | m_functions->glBindTexture(target: m_target, texture); |
430 | } |
431 | |
432 | ~TextureBinder() |
433 | { |
434 | m_functions->glBindTexture(target: m_target, texture: m_oldTexture); |
435 | } |
436 | |
437 | private: |
438 | QOpenGLFunctions *m_functions; |
439 | GLenum m_target; |
440 | GLint m_oldTexture; |
441 | }; |
442 | |
443 | } // namespace |
444 | |
445 | void QOpenGLTextureHelper::qt_TextureParameteri(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param) |
446 | { |
447 | TextureBinder binder(functions, texture, target, bindingTarget); |
448 | functions->glTexParameteri(target, pname, param); |
449 | } |
450 | |
451 | void QOpenGLTextureHelper::qt_TextureParameteriv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLint *params) |
452 | { |
453 | TextureBinder binder(functions, texture, target, bindingTarget); |
454 | functions->glTexParameteriv(target, pname, params); |
455 | } |
456 | |
457 | void QOpenGLTextureHelper::qt_TextureParameterf(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLfloat param) |
458 | { |
459 | TextureBinder binder(functions, texture, target, bindingTarget); |
460 | functions->glTexParameterf(target, pname, param); |
461 | } |
462 | |
463 | void QOpenGLTextureHelper::qt_TextureParameterfv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLfloat *params) |
464 | { |
465 | TextureBinder binder(functions, texture, target, bindingTarget); |
466 | functions->glTexParameterfv(target, pname, params); |
467 | } |
468 | |
469 | void QOpenGLTextureHelper::qt_GenerateTextureMipmap(GLuint texture, GLenum target, GLenum bindingTarget) |
470 | { |
471 | TextureBinder binder(functions, texture, target, bindingTarget); |
472 | functions->glGenerateMipmap(target); |
473 | } |
474 | |
475 | void QOpenGLTextureHelper::qt_TextureStorage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth) |
476 | { |
477 | TextureBinder binder(functions, texture, target, bindingTarget); |
478 | glTexStorage3D(target, levels, internalFormat, width, height, depth); |
479 | } |
480 | |
481 | void QOpenGLTextureHelper::qt_TextureStorage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height) |
482 | { |
483 | TextureBinder binder(functions, texture, target, bindingTarget); |
484 | glTexStorage2D(target, levels, internalFormat, width, height); |
485 | } |
486 | |
487 | void QOpenGLTextureHelper::qt_TextureStorage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width) |
488 | { |
489 | TextureBinder binder(functions, texture, target, bindingTarget); |
490 | glTexStorage1D(target, levels, internalFormat, width); |
491 | } |
492 | |
493 | void QOpenGLTextureHelper::qt_TextureStorage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations) |
494 | { |
495 | TextureBinder binder(functions, texture, target, bindingTarget); |
496 | glTexStorage3DMultisample(target, samples, internalFormat, width, height, depth, fixedSampleLocations); |
497 | } |
498 | |
499 | void QOpenGLTextureHelper::qt_TextureStorage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations) |
500 | { |
501 | TextureBinder binder(functions, texture, target, bindingTarget); |
502 | glTexStorage2DMultisample(target, samples, internalFormat, width, height, fixedSampleLocations); |
503 | } |
504 | |
505 | void QOpenGLTextureHelper::qt_TextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels) |
506 | { |
507 | TextureBinder binder(functions, texture, target, bindingTarget); |
508 | glTexImage3D(target, level, internalFormat, width, height, depth, border, format, type, pixels); |
509 | } |
510 | |
511 | void QOpenGLTextureHelper::qt_TextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) |
512 | { |
513 | TextureBinder binder(functions, texture, target, bindingTarget); |
514 | functions->glTexImage2D(target, level, internalformat: internalFormat, width, height, border, format, type, pixels); |
515 | } |
516 | |
517 | void QOpenGLTextureHelper::qt_TextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels) |
518 | { |
519 | TextureBinder binder(functions, texture, target, bindingTarget); |
520 | glTexImage1D(target, level, internalFormat, width, border, format, type, pixels); |
521 | } |
522 | |
523 | void QOpenGLTextureHelper::qt_TextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels) |
524 | { |
525 | TextureBinder binder(functions, texture, target, bindingTarget); |
526 | glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); |
527 | } |
528 | |
529 | void QOpenGLTextureHelper::qt_TextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) |
530 | { |
531 | TextureBinder binder(functions, texture, target, bindingTarget); |
532 | functions->glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); |
533 | } |
534 | |
535 | void QOpenGLTextureHelper::qt_TextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels) |
536 | { |
537 | TextureBinder binder(functions, texture, target, bindingTarget); |
538 | glTexSubImage1D(target, level, xoffset, width, format, type, pixels); |
539 | } |
540 | |
541 | void QOpenGLTextureHelper::qt_TextureImage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations) |
542 | { |
543 | TextureBinder binder(functions, texture, target, bindingTarget); |
544 | glTexImage3DMultisample(target, samples, internalFormat, width, height, depth, fixedSampleLocations); |
545 | } |
546 | |
547 | void QOpenGLTextureHelper::qt_TextureImage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations) |
548 | { |
549 | TextureBinder binder(functions, texture, target, bindingTarget); |
550 | glTexImage2DMultisample(target, samples, internalFormat, width, height, fixedSampleLocations); |
551 | } |
552 | |
553 | void QOpenGLTextureHelper::qt_CompressedTextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits) |
554 | { |
555 | TextureBinder binder(functions, texture, target, bindingTarget); |
556 | glCompressedTexSubImage1D(target, level, xoffset, width, format, imageSize, data: bits); |
557 | } |
558 | |
559 | void QOpenGLTextureHelper::qt_CompressedTextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits) |
560 | { |
561 | TextureBinder binder(functions, texture, target, bindingTarget); |
562 | glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data: bits); |
563 | } |
564 | |
565 | void QOpenGLTextureHelper::qt_CompressedTextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits) |
566 | { |
567 | TextureBinder binder(functions, texture, target, bindingTarget); |
568 | glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data: bits); |
569 | } |
570 | |
571 | void QOpenGLTextureHelper::qt_CompressedTextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits) |
572 | { |
573 | TextureBinder binder(functions, texture, target, bindingTarget); |
574 | glCompressedTexImage1D(target, level, internalFormat, width, border, imageSize, data: bits); |
575 | } |
576 | |
577 | void QOpenGLTextureHelper::qt_CompressedTextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits) |
578 | { |
579 | TextureBinder binder(functions, texture, target, bindingTarget); |
580 | glCompressedTexImage2D(target, level, internalFormat, width, height, border, imageSize, data: bits); |
581 | } |
582 | |
583 | void QOpenGLTextureHelper::qt_CompressedTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits) |
584 | { |
585 | TextureBinder binder(functions, texture, target, bindingTarget); |
586 | glCompressedTexImage3D(target, level, internalFormat, width, height, depth, border, imageSize, data: bits); |
587 | } |
588 | |
589 | QT_END_NAMESPACE |
590 | |