Details
Description
Add a set of QAbstractTextureImage implementations to a texture, each of the images providing the data for a different mipmap level.
Unfortunately this breaks or crashes in various ways due to GLTexture getting confused internally.
void GLTexture::uploadGLTextureData() { // Upload all QTexImageData set by the QTextureGenerator if (m_textureData) { const QVector<QTextureImageDataPtr> imgData = m_textureData->imageData(); for (const QTextureImageDataPtr &data : imgData) { const int mipLevels = m_properties.generateMipMaps ? 1 : data->mipLevels(); for (int layer = 0; layer < data->layers(); layer++) { for (int face = 0; face < data->faces(); face++) { for (int level = 0; level < mipLevels; level++) { // ensure we don't accidentally cause a detach / copy of the raw bytes const QByteArray bytes(data->data(layer, face, level)); uploadGLData(m_gl, level, layer, static_cast<QOpenGLTexture::CubeMapFace>(QOpenGLTexture::CubeMapPositiveX + face), bytes, data); } } } } } // Upload all QTexImageData references by the TextureImages for (int i = 0; i < m_images.size(); i++) { const QTextureImageDataPtr &imgData = m_imageData.at(i); // ensure we don't accidentally cause a detach / copy of the raw bytes const QByteArray bytes(imgData->data()); uploadGLData(m_gl, m_images[i].mipLevel, m_images[i].layer, static_cast<QOpenGLTexture::CubeMapFace>(m_images[i].face), bytes, imgData); } }
The first half is not relevant since we do not use a QTextureData generator (since this is not exposed in the public API so cannot be utilized in any meaningful way outside Qt3D itself - which is unfortunate). So we are stuck with separate textureimages.
Here the data() in the images contain data for a single mipmap level (or cubemap face etc.). This is unlike the other case where data() contains all mipmap levels, faces and layers in one single blob.
Now check the const QByteArray bytes(imgData->data()); call and note that it is
QByteArray QTextureImageData::data(int layer, int face, int mipmapLevel) const which has default values of 0 for all the parameters. This function is only prepared to handle the everything-in-single-blob case and ends up in a
return QByteArray::fromRawData(m_data.constData() + offset, mipmapLevelSize(mipmapLevel));
which is all wrong in our case since mipmapLevel is 0 but the returned QByteArray's size cannot be the size of the data for mipmap level 0 since m_data contains data only for a given mipmap level, not for all of them.
What should have been done instead in the textureimage case is to take m_data as-is without any fancy calculations.
Attachments
Issue Links
- relates to
-
QT3DS-660 Qt 3D bugs and features required for Runtime 2
- Withdrawn