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?

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