QOpenGLTexture and shader?



  • 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.



  • 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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.