Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QOpenGLTexture and shader?
QtWS25 Last Chance

QOpenGLTexture and shader?

Scheduled Pinned Locked Moved Unsolved General and Desktop
qt5.6qopengltextureshaders
3 Posts 2 Posters 2.3k 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.
  • A Offline
    A Offline
    Alain38
    wrote on last edited by
    #1

    Hi,
    I have trying to generate a 3D texture to be used by a shader (displaying a slice). I have an old version, directly using the OpenGL functions. Its code is the following:

    Texture creation:

    	QOpenGLContext * currentContext = QOpenGLContext::currentContext();
    	QOpenGLFunctions_3_2_Compatibility* func = currentContext->versionFunctions< QOpenGLFunctions_3_2_Compatibility >();
    
    	unsigned int imageId = 0;
    
    	func->glEnable(GL_TEXTURE_3D);
    	// Create OpenGL texture
    	func->glGenTextures(1, &imageId);
    	func->glBindTexture(GL_TEXTURE_3D, imageId);
    	func->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    	func->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    	func->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
    	func->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
    	func->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, (p_multipleTextures ? GL_CLAMP_TO_EDGE : GL_CLAMP_TO_BORDER));
    
    	GLfloat colorBorder[4] = {0.,0.,0.,0.};
    
    	func->glTexParameterfv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, colorBorder);
    	func->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    	func->glTexImage3D(GL_TEXTURE_3D, 0, GL_ALPHA16, p_pow2x, p_pow2y, p_pow2z,
    		0, GL_ALPHA, GL_UNSIGNED_SHORT, p_textureBuffer);
    	func->glBindTexture(GL_TEXTURE_3D, 0);
    	func->glDisable(GL_TEXTURE_3D);
    
    	m_textures.append(imageId);
    
    	return true;
    

    Texture usage:

    	func->glEnable(GL_TEXTURE_3D);
    
    	QSharedPointer<OGLSliceShader> sliceShader = OGLShaderFactory::getInstance()->getShader(OGLShaderFactory::ShaderName::SLICE_SHADER).staticCast<OGLSliceShader>();
    
    	for (int i = 0; i < textures.size(); ++i)
    	{// Active the texture
    			func->glActiveTexture(GL_TEXTURE0 + i);
    			func->glBindTexture(GL_TEXTURE_3D, textures[i]);
    	}// Active the texture
    
    	// Image is displayed by a shader
    	sliceShader->start(OGLSliceShader::Mode::SLICE3D, contrast, brightness, textures.size());
    
    	func->glColor3fv(IMAGE_COLOR.data());
    	func->glBegin(GL_QUADS);
    	func->glTexCoord3d(m_textureQuad[0].x(), m_textureQuad[0].y(), m_textureQuad[0].z());
    	func->glVertex3d(m_sliceQuad[0].x(), m_sliceQuad[0].y(), m_sliceQuad[0].z());
    	func->glTexCoord3d(m_textureQuad[1].x(), m_textureQuad[1].y(), m_textureQuad[1].z());
    	func->glVertex3d(m_sliceQuad[1].x(), m_sliceQuad[1].y(), m_sliceQuad[1].z());
    	func->glTexCoord3d(m_textureQuad[2].x(), m_textureQuad[2].y(), m_textureQuad[2].z());
    	func->glVertex3d(m_sliceQuad[2].x(), m_sliceQuad[2].y(), m_sliceQuad[2].z());
    	func->glTexCoord3d(m_textureQuad[3].x(), m_textureQuad[3].y(), m_textureQuad[3].z());
    	func->glVertex3d(m_sliceQuad[3].x(), m_sliceQuad[3].y(), m_sliceQuad[3].z());
    	func->glEnd();
    
    	sliceShader->stop();
    
    	for (int i = textures.size() - 1; i >=0 ; --i)
    	{// Unbind textures
    			func->glActiveTexture(GL_TEXTURE0 + i);
    			func->glBindTexture(GL_TEXTURE_3D, 0);
    	}// Unbind textures
    
    		func->glDisable(GL_TEXTURE_3D);
    

    And the fragment shader code is (really simple):

    	float toto = texture3D(tex3d0, gl_TexCoord[0].xyz).a;
    	gl_FragColor = vec4(toto, toto, toto, 1.0);
    

    This code works well.

    Now, as I'm moving to Qt5.6 I would use QOpenGLTexture. So, I have modified the code as follow:

    Texture creation:

    	QOpenGLTexture *			currentTexture = new QOpenGLTexture(QOpenGLTexture::Target3D);
    	QOpenGLPixelTransferOptions packAlignment;
    
    	currentTexture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear);
    	currentTexture->setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::ClampToBorder);
    	currentTexture->setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::ClampToBorder);
    	currentTexture->setWrapMode(QOpenGLTexture::DirectionR, (p_multipleTextures ? QOpenGLTexture::ClampToEdge : QOpenGLTexture::ClampToBorder));
    	currentTexture->setBorderColor(0.0f, 0.0f, 0.0f, 1.0f); // Border color is black
    	currentTexture->setFormat(QOpenGLTexture::R16U);
    	currentTexture->setSize(p_pow2x, p_pow2y, p_pow2z);
    	packAlignment.setAlignment(1);
    	currentTexture->allocateStorage(QOpenGLTexture::Red_Integer, QOpenGLTexture::UInt16);
    	if (!currentTexture->isStorageAllocated())
    	{// problem allocating the storage
    		INCAS_WARNING() << QString::fromLatin1("Cannot allocate storage for the current texture", 47);
    		delete currentTexture;
    		return false;
    	}// problem allocating the storage
    
    	currentTexture->setData(QOpenGLTexture::Red_Integer, QOpenGLTexture::UInt16, p_textureBuffer, &packAlignment);
    
    

    Texture usage:

    	QSharedPointer<OGLSliceShader> sliceShader = OGLShaderFactory::getInstance()->getShader(OGLShaderFactory::ShaderName::SLICE_SHADER).staticCast<OGLSliceShader>();
    
    	for (int i = 0; i < textures.size(); ++i)
    	{// Active the texture
    		textures[i]->bind(i);
    	}// Active the texture
    
    	// Image is displayed by a shader
    	sliceShader->start(OGLSliceShader::Mode::SLICE3D, contrast, brightness, textures.size());
    
    	func->glColor3fv(IMAGE_COLOR.data());
    	func->glBegin(GL_QUADS);
    	func->glTexCoord3d(m_textureQuad[0].x(), m_textureQuad[0].y(), m_textureQuad[0].z());
    	func->glVertex3d(m_sliceQuad[0].x(), m_sliceQuad[0].y(), m_sliceQuad[0].z());
    	func->glTexCoord3d(m_textureQuad[1].x(), m_textureQuad[1].y(), m_textureQuad[1].z());
    	func->glVertex3d(m_sliceQuad[1].x(), m_sliceQuad[1].y(), m_sliceQuad[1].z());
    	func->glTexCoord3d(m_textureQuad[2].x(), m_textureQuad[2].y(), m_textureQuad[2].z());
    	func->glVertex3d(m_sliceQuad[2].x(), m_sliceQuad[2].y(), m_sliceQuad[2].z());
    	func->glTexCoord3d(m_textureQuad[3].x(), m_textureQuad[3].y(), m_textureQuad[3].z());
    	func->glVertex3d(m_sliceQuad[3].x(), m_sliceQuad[3].y(), m_sliceQuad[3].z());
    	func->glEnd();
    
    	sliceShader->stop();
    
    	for (int i = textures.size() - 1; i >=0 ; --i)
    	{// Unbind textures
    		textures[i]->release();
    	}// Unbind textures
    
    

    So, I had to perform the following changes:

    • I'm using the red channel instead of alpha. I found no way to set the texture on the alpha channel only. So, in the shader I changed to this channel too,

    • I have no more the enable/disable GL_TEXTURE_3D.

    With this new version I always have a black image. And,

    • If I use glReadTexImage, I obtain the data I set (so texture is correct),

    • If the shader uses the alpha channel instead of the red one, I also have a black image. And this is strange (not compliant with documentation),

    • If I force the enable/disable of GL_TEXTURE_3D there is no change

    Do you have an idea of what I'm doing wrong?

    Thnaks.

    A 1 Reply Last reply
    0
    • A Alain38

      Hi,
      I have trying to generate a 3D texture to be used by a shader (displaying a slice). I have an old version, directly using the OpenGL functions. Its code is the following:

      Texture creation:

      	QOpenGLContext * currentContext = QOpenGLContext::currentContext();
      	QOpenGLFunctions_3_2_Compatibility* func = currentContext->versionFunctions< QOpenGLFunctions_3_2_Compatibility >();
      
      	unsigned int imageId = 0;
      
      	func->glEnable(GL_TEXTURE_3D);
      	// Create OpenGL texture
      	func->glGenTextures(1, &imageId);
      	func->glBindTexture(GL_TEXTURE_3D, imageId);
      	func->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
      	func->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
      	func->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
      	func->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
      	func->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, (p_multipleTextures ? GL_CLAMP_TO_EDGE : GL_CLAMP_TO_BORDER));
      
      	GLfloat colorBorder[4] = {0.,0.,0.,0.};
      
      	func->glTexParameterfv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, colorBorder);
      	func->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
      	func->glTexImage3D(GL_TEXTURE_3D, 0, GL_ALPHA16, p_pow2x, p_pow2y, p_pow2z,
      		0, GL_ALPHA, GL_UNSIGNED_SHORT, p_textureBuffer);
      	func->glBindTexture(GL_TEXTURE_3D, 0);
      	func->glDisable(GL_TEXTURE_3D);
      
      	m_textures.append(imageId);
      
      	return true;
      

      Texture usage:

      	func->glEnable(GL_TEXTURE_3D);
      
      	QSharedPointer<OGLSliceShader> sliceShader = OGLShaderFactory::getInstance()->getShader(OGLShaderFactory::ShaderName::SLICE_SHADER).staticCast<OGLSliceShader>();
      
      	for (int i = 0; i < textures.size(); ++i)
      	{// Active the texture
      			func->glActiveTexture(GL_TEXTURE0 + i);
      			func->glBindTexture(GL_TEXTURE_3D, textures[i]);
      	}// Active the texture
      
      	// Image is displayed by a shader
      	sliceShader->start(OGLSliceShader::Mode::SLICE3D, contrast, brightness, textures.size());
      
      	func->glColor3fv(IMAGE_COLOR.data());
      	func->glBegin(GL_QUADS);
      	func->glTexCoord3d(m_textureQuad[0].x(), m_textureQuad[0].y(), m_textureQuad[0].z());
      	func->glVertex3d(m_sliceQuad[0].x(), m_sliceQuad[0].y(), m_sliceQuad[0].z());
      	func->glTexCoord3d(m_textureQuad[1].x(), m_textureQuad[1].y(), m_textureQuad[1].z());
      	func->glVertex3d(m_sliceQuad[1].x(), m_sliceQuad[1].y(), m_sliceQuad[1].z());
      	func->glTexCoord3d(m_textureQuad[2].x(), m_textureQuad[2].y(), m_textureQuad[2].z());
      	func->glVertex3d(m_sliceQuad[2].x(), m_sliceQuad[2].y(), m_sliceQuad[2].z());
      	func->glTexCoord3d(m_textureQuad[3].x(), m_textureQuad[3].y(), m_textureQuad[3].z());
      	func->glVertex3d(m_sliceQuad[3].x(), m_sliceQuad[3].y(), m_sliceQuad[3].z());
      	func->glEnd();
      
      	sliceShader->stop();
      
      	for (int i = textures.size() - 1; i >=0 ; --i)
      	{// Unbind textures
      			func->glActiveTexture(GL_TEXTURE0 + i);
      			func->glBindTexture(GL_TEXTURE_3D, 0);
      	}// Unbind textures
      
      		func->glDisable(GL_TEXTURE_3D);
      

      And the fragment shader code is (really simple):

      	float toto = texture3D(tex3d0, gl_TexCoord[0].xyz).a;
      	gl_FragColor = vec4(toto, toto, toto, 1.0);
      

      This code works well.

      Now, as I'm moving to Qt5.6 I would use QOpenGLTexture. So, I have modified the code as follow:

      Texture creation:

      	QOpenGLTexture *			currentTexture = new QOpenGLTexture(QOpenGLTexture::Target3D);
      	QOpenGLPixelTransferOptions packAlignment;
      
      	currentTexture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear);
      	currentTexture->setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::ClampToBorder);
      	currentTexture->setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::ClampToBorder);
      	currentTexture->setWrapMode(QOpenGLTexture::DirectionR, (p_multipleTextures ? QOpenGLTexture::ClampToEdge : QOpenGLTexture::ClampToBorder));
      	currentTexture->setBorderColor(0.0f, 0.0f, 0.0f, 1.0f); // Border color is black
      	currentTexture->setFormat(QOpenGLTexture::R16U);
      	currentTexture->setSize(p_pow2x, p_pow2y, p_pow2z);
      	packAlignment.setAlignment(1);
      	currentTexture->allocateStorage(QOpenGLTexture::Red_Integer, QOpenGLTexture::UInt16);
      	if (!currentTexture->isStorageAllocated())
      	{// problem allocating the storage
      		INCAS_WARNING() << QString::fromLatin1("Cannot allocate storage for the current texture", 47);
      		delete currentTexture;
      		return false;
      	}// problem allocating the storage
      
      	currentTexture->setData(QOpenGLTexture::Red_Integer, QOpenGLTexture::UInt16, p_textureBuffer, &packAlignment);
      
      

      Texture usage:

      	QSharedPointer<OGLSliceShader> sliceShader = OGLShaderFactory::getInstance()->getShader(OGLShaderFactory::ShaderName::SLICE_SHADER).staticCast<OGLSliceShader>();
      
      	for (int i = 0; i < textures.size(); ++i)
      	{// Active the texture
      		textures[i]->bind(i);
      	}// Active the texture
      
      	// Image is displayed by a shader
      	sliceShader->start(OGLSliceShader::Mode::SLICE3D, contrast, brightness, textures.size());
      
      	func->glColor3fv(IMAGE_COLOR.data());
      	func->glBegin(GL_QUADS);
      	func->glTexCoord3d(m_textureQuad[0].x(), m_textureQuad[0].y(), m_textureQuad[0].z());
      	func->glVertex3d(m_sliceQuad[0].x(), m_sliceQuad[0].y(), m_sliceQuad[0].z());
      	func->glTexCoord3d(m_textureQuad[1].x(), m_textureQuad[1].y(), m_textureQuad[1].z());
      	func->glVertex3d(m_sliceQuad[1].x(), m_sliceQuad[1].y(), m_sliceQuad[1].z());
      	func->glTexCoord3d(m_textureQuad[2].x(), m_textureQuad[2].y(), m_textureQuad[2].z());
      	func->glVertex3d(m_sliceQuad[2].x(), m_sliceQuad[2].y(), m_sliceQuad[2].z());
      	func->glTexCoord3d(m_textureQuad[3].x(), m_textureQuad[3].y(), m_textureQuad[3].z());
      	func->glVertex3d(m_sliceQuad[3].x(), m_sliceQuad[3].y(), m_sliceQuad[3].z());
      	func->glEnd();
      
      	sliceShader->stop();
      
      	for (int i = textures.size() - 1; i >=0 ; --i)
      	{// Unbind textures
      		textures[i]->release();
      	}// Unbind textures
      
      

      So, I had to perform the following changes:

      • I'm using the red channel instead of alpha. I found no way to set the texture on the alpha channel only. So, in the shader I changed to this channel too,

      • I have no more the enable/disable GL_TEXTURE_3D.

      With this new version I always have a black image. And,

      • If I use glReadTexImage, I obtain the data I set (so texture is correct),

      • If the shader uses the alpha channel instead of the red one, I also have a black image. And this is strange (not compliant with documentation),

      • If I force the enable/disable of GL_TEXTURE_3D there is no change

      Do you have an idea of what I'm doing wrong?

      Thnaks.

      A Offline
      A Offline
      Alain38
      wrote on last edited by
      #2

      I did some new tries. With the direct use of OpenGL functions, I can use the shader by using GL_R16 + GL_RED + GL_UNSIGNED_SHORT. So I have just moved of channel.

      But this association does not work with QOpenGLTexture. Setting the format to R16_UNorm (supposed to be GL_R16) and allocate the storage with QOpenGLTexture::Red (supposed to be GL_RED) and QOpenGLTexture::UInt16 (suppoed to be GL_UNSIGNED_SHORT), generates an OpenGL error.

      1 Reply Last reply
      0
      • C Offline
        C Offline
        ChrisVis
        wrote on last edited by
        #3

        Dear Alain38,

        Did you make it finally work? I got stocked with the exact same problem.

        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