Can any one tell me why my code works on local machine but not on a remote machine I'm trying to push to?
local driver version: NVIDIA-SMI 460.91.03 Driver Version: 460.91.03
remote driver version: NVIDIA-SMI 435.21 Driver Version: 435.21
When trying to run on remote machine, I keep getting:
QGLFramebufferObject: Framebuffer incomplete attachment.
QGLFramebufferObject: Framebuffer incomplete attachment.
Framebuffer is not valid, may be out of memoryor context is not valid
Could not bind framebuffer
Image passed to GenImage is null!
Framebuffer code:
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
void GlowFramebuffer::Create( int width , int height )
{
QGLFramebufferObjectFormat format;
if( m_format == GLOW_R )
{
format.setInternalTextureFormat(GL_RED );
m_framebuffer =
QSharedPointer<QGLFramebufferObject>(
new QGLFramebufferObject(width, height, format) );
} else if ( m_attachment == GLOW_DEPTH_STENCIL ) {
format.setAttachment( QGLFramebufferObject::CombinedDepthStencil );
m_framebuffer =
QSharedPointer<QGLFramebufferObject>(
new QGLFramebufferObject(width, height, format) );
}
else // GLOW_RGBA
{
m_framebuffer =
QSharedPointer<QGLFramebufferObject>(
new QGLFramebufferObject(width, height) );
}
SetClearColor( m_clear_color );
}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
void GlowFramebuffer::Create( const QSize& size )
{
Create( size.width() , size.height() );
if( !m_framebuffer->isValid() )
{
qCritical() << "Framebuffer is not valid, may be out of memory"
"or context is not valid";
}
}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
int GlowFramebuffer::CopyMultiTexture( GlowFilter filter , GlowFormat format )
{
GLint width = m_framebuffer->width();
GLint height = m_framebuffer->height();
GLuint FramebufferName = 0;
glGenFramebuffers(1, &FramebufferName);
glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
GLenum glfilter = (filter == GLOW_NEAREST) ? GL_NEAREST : GL_LINEAR;
GLenum glformat = (format == GLOW_R ) ? GL_R : GL_RGBA;
GLuint renderedTexture;
glGenTextures(1, &renderedTexture);
// "Bind" the newly created texture : all future texture functions will modify this texture
glBindTexture(GL_TEXTURE_2D, renderedTexture);
// Give an empty image to OpenGL ( the last "0" )
glTexImage2D(GL_TEXTURE_2D, 0,glformat, width, height, 0,glformat, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glfilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glfilter);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderedTexture, 0);
// Set the list of draw buffers.
GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0};
glDrawBuffers(1, DrawBuffers); // "1" is the size of DrawBuffers
GLenum status = glCheckFramebufferStatus( GL_FRAMEBUFFER );
if( status != GL_FRAMEBUFFER_COMPLETE )
{
qCritical() << "Error with framebuffer!";
}
GLuint handle = m_framebuffer->handle();
GLClear();
glBindFramebuffer( GL_DRAW_FRAMEBUFFER , FramebufferName );
glBindFramebuffer( GL_READ_FRAMEBUFFER , handle );
glDrawBuffer( GL_BACK );
glBlitFramebuffer( 0 , 0 , width , height , 0 , 0 , width , height , GL_COLOR_BUFFER_BIT , GL_NEAREST );
glBindTexture( GL_TEXTURE_2D , 0 );
glBindFramebuffer( GL_FRAMEBUFFER , handle );
glDeleteFramebuffers( 1 , &FramebufferName );
return renderedTexture;
}
I know its likely because FBOs are specific to each machine and driver. In order to ensure its compatible, you need to check the system to make sure the Format which you created your frame buffer is valid.
I think its failing on the remote machine at this line:
GLenum status = glCheckFramebufferStatus( GL_FRAMEBUFFER );
if( status != GL_FRAMEBUFFER_COMPLETE )
{
qCritical() << "Error with framebuffer!";
}
I think glformat variable is the format to be adjusted in this function:
glTexImage2D(GL_TEXTURE_2D, 0,glformat, width, height, 0,glformat, GL_UNSIGNED_BYTE, 0);
How do I have it pick the appropriate format to make the FBO on the remote machine?
Code for the image from the framebuffer we're trying to attach:
bool Product::SetImgInfo(GeoRadarProd &prod, const JsonConfig &config)
{
DataInput input(FLAGS_input.c_str());
QString file_name_data = FLAGS_file_name.c_str();
int width = config.GetInt("width");
int height = config.GetInt("height");
if(!input.isValid())
{
LOG(INFO) << "Input is not valid";
return false;
}
QByteArray data = input.getByteArray();
VLOG(3) << "width from config: "<< width;
VLOG(3) << "height from config: "<< height;
VLOG(3) << "data : "<< data.size();
QImage image_data;
image_data.fromData(data, "PNG");
VLOG(3) << "what is file_name_data ???: " << file_name_data.toStdString();
VLOG(3) << "is image_data load???: " << image_data.load(file_name_data, "PNG");
VLOG(3) << "is image_data null???: " << image_data.isNull();
VLOG(3) << "image data width: "<< image_data.width();
VLOG(3) << "image data height: "<< image_data.height();
VLOG(3)<< "Original Format was tif";
VLOG(3)<<"Data Img H: "<< image_data.height()<<" W: "<<image_data.width();
QImage new_image(image_data.width(), image_data.height(), QImage::Format_RGBA8888);
// Format_ARGB32 , Format_RGBA8888_Premultiplied
VLOG(3)<<"New Img H: "<<new_image.height()<<" W: "<<new_image.width();
VLOG(3)<<"Setting img data";
for(int idx = 0; idx < image_data.width(); idx++)
{
for(int idy = 0; idy < image_data.height(); idy++)
{
int index_value = image_data.pixelIndex(idx, idy);
uint color_value;
if(index_value == 0 )
{
color_value = qRgba((int(0)), 0, 0, 0);
}
else
{
//! +1*20 to have a wider spread in the palette
//! and since the values start from 0
// index_value = index_value + 1;
color_value = qRgb(((int)index_value ), 0, 0);
}
new_image.setPixel(idx, idy, color_value);
}
}
const QImage& img = QGLWidget::convertToGLFormat(new_image);
prod.setQImageData(img);
return true;
}