Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Game Development
  4. Dynamic Textures in Qt3D with C++

Dynamic Textures in Qt3D with C++

Scheduled Pinned Locked Moved Solved Game Development
qt3dopenglqt5.15.0graphics
3 Posts 2 Posters 1.7k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    Jakob Weiss
    wrote on last edited by
    #1

    I'm looking for a way to dynamically create and update a texture from C++ to be used in a custom shader.
    This seems to be a rather basic use case but I am getting completely lost in the underdocumented depths of Qt3D.
    I simply want to create a QTexture2D and set it to a Material property.

    In essence, I want the equivalent to glGenTextures + glTexImage2D, however I can't clearly map this to the QTexture2D interface.

    It seems that I need to use QTexture2D::updateData to upload data, but the documentation suggests I still need to initialize the texture with the dimensions first? Do I need to implement my own QTextureImageDataGenerator if I want to dynamically update it?

    I can't find any example code that would put me in the right direction, so any help will be highly appreciated!

    1 Reply Last reply
    0
    • J Offline
      J Offline
      Jakob Weiss
      wrote on last edited by Jakob Weiss
      #2

      Ok, I figured out how to use updateData properly. Leaving this here for posterity. For my use case, I needed to upload a grayscale 3D texture but this should be the same for any texture type:

             using namespace Qt3DRender;
             QTexture * tex = new QTexture3D;
              tex->setSize(vol.width(), vol.height(), vol.depth());
              tex->setFormat(QTexture3D::TextureFormat::R8_UNorm);
              tex->setLayers(1);
              tex->setGenerateMipMaps(false);
              QTextureWrapMode wm(QTextureWrapMode::ClampToBorder);
              tex->setWrapMode(wm);
          
              data->setFormat(QOpenGLTexture::TextureFormat::R8_UNorm);
              data->setWidth(vol.width());
              data->setHeight(vol.height());
              data->setDepth(vol.depth());
              data->setMipLevels(1);
              data->setLayers(1);
              data->setPixelFormat(QOpenGLTexture::PixelFormat::Red);
              data->setPixelType(QOpenGLTexture::PixelType::UInt8);
          
              QByteArray qba;
              qba.setRawData((const char *)vol.dataUint8(), static_cast<int>(vol.byteSize()));
              data->setData(qba, 1);
          
              QTextureDataUpdate update;
              update.setX(0);
              update.setY(0);
              update.setData(data);
              tex->updateData(update);
      
              Qt3DRender::QParameter p();
              p.setName("volume"); // the uniform name in the shader
              p.setValue(QVariant::fromValue(tex));
      
      QMaterial * mat = ...; // queried from the qml
      mat->addParameter(p);
      

      The Qt3D test for texture update was pretty helpful in figuring this out.

      D 1 Reply Last reply
      1
      • J Jakob Weiss

        Ok, I figured out how to use updateData properly. Leaving this here for posterity. For my use case, I needed to upload a grayscale 3D texture but this should be the same for any texture type:

               using namespace Qt3DRender;
               QTexture * tex = new QTexture3D;
                tex->setSize(vol.width(), vol.height(), vol.depth());
                tex->setFormat(QTexture3D::TextureFormat::R8_UNorm);
                tex->setLayers(1);
                tex->setGenerateMipMaps(false);
                QTextureWrapMode wm(QTextureWrapMode::ClampToBorder);
                tex->setWrapMode(wm);
            
                data->setFormat(QOpenGLTexture::TextureFormat::R8_UNorm);
                data->setWidth(vol.width());
                data->setHeight(vol.height());
                data->setDepth(vol.depth());
                data->setMipLevels(1);
                data->setLayers(1);
                data->setPixelFormat(QOpenGLTexture::PixelFormat::Red);
                data->setPixelType(QOpenGLTexture::PixelType::UInt8);
            
                QByteArray qba;
                qba.setRawData((const char *)vol.dataUint8(), static_cast<int>(vol.byteSize()));
                data->setData(qba, 1);
            
                QTextureDataUpdate update;
                update.setX(0);
                update.setY(0);
                update.setData(data);
                tex->updateData(update);
        
                Qt3DRender::QParameter p();
                p.setName("volume"); // the uniform name in the shader
                p.setValue(QVariant::fromValue(tex));
        
        QMaterial * mat = ...; // queried from the qml
        mat->addParameter(p);
        

        The Qt3D test for texture update was pretty helpful in figuring this out.

        D Offline
        D Offline
        daivd
        wrote on last edited by
        #3

        @Jakob-Weiss
        Is there any QT 3d Volume Rendering exmple in Qt? We are also trying to get Texture3d work in shader. Up to now, thanks to your tip, we made Texture2d work. We did the same in Texture3d, but it just didn't work and always shows black. Thanks if there is any tip.

        • QML is like:
        parameters: [
                Parameter {
                    id: mainTex
                    name: "mainTex"
                    value: m_mainTexture
                },
                Parameter {
                    id: myTex3D
                    name: "myTex3D"
                    value: m_mainTex3D
                }
            ]
        
        • frag Shader is like:
        layout(std140, binding = auto) uniform custom_uniforms {
            vec3 maincolor;
        };
        layout(binding = auto) uniform sampler2D mainTex;
        layout(binding = auto) uniform sampler3D myTex3D;
        layout(location = 0) in vec3 worldPosition;
        layout(location = 1) in vec2 v_texcoord;
        layout(location = 0) out vec4 fragColor;
        void main()
        {
                //vec4 txtColor = texture(mainTex, v_texcoord);
        	vec4 txtColor = texture(myTex3D, vec3(v_texcoord.x,v_texcoord.y,0.5));
        	float value_3D = txtColor.r * 100;
        	fragColor = vec4(value_3D,value_3D,value_3D,1.0);
        }
        
        • C++ is like:
        m_texture3D = new Qt3DRender::QTexture3D();
            m_texture3D->setSize(128,128,128);
            m_texture3D->setFormat(Qt3DRender::QTexture3D::R8_UNorm);
            m_texture3D->setLayers(1);
            m_texture3D->setGenerateMipMaps(false);
            Qt3DRender::QTextureWrapMode wm(Qt3DRender::QTextureWrapMode::ClampToBorder);
            m_texture3D->setWrapMode(wm);
            //m_texture3D->setMinificationFilter(Qt3DRender::QTexture3D::Linear);
            //m_texture3D->setMagnificationFilter(Qt3DRender::QTexture3D::Linear);
        
            rawPixelData3D.resize(128 * 128 * 128 * sizeof(uchar));
            uchar *pixels3D = reinterpret_cast<uchar *>(rawPixelData3D.data());
            std::memset(pixels3D, 60, 128 * 128 * 128 * sizeof(uchar));
        
        Qt3DRender::QTextureImageDataPtr imageData3D = Qt3DRender::QTextureImageDataPtr::create();
            imageData3D->setFormat(QOpenGLTexture::TextureFormat::R8_UNorm);
            imageData3D->setWidth(128);
            imageData3D->setHeight(128);
            imageData3D->setDepth(128);
            imageData3D->setMipLevels(1);
            imageData3D->setLayers(1);
            imageData3D->setPixelFormat(QOpenGLTexture::PixelFormat::Red);
            imageData3D->setPixelType(QOpenGLTexture::PixelType::UInt8);
            imageData3D->setData(rawPixelData3D, 1, false);
        
            Qt3DRender::QTextureDataUpdate update3D;
            update3D.setX(0);
            update3D.setY(0);
            update3D.setData(imageData3D);
        
            m_texture3D->updateData(update3D);
        
        
        
        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved