PDA

View Full Version : QImage bind texture fails



saman_artorious
18th September 2013, 13:46
I want to bind a QImage/QPixmap to texture and render it on screen. The step Ive been after is to
1. Grab a screen shot
2. Send pixmap bytes to another code segment
3. convert bytes to QImage
4. bind QImage to texture

I am sure that the rendering is correct. However, the program terminates when it reaches the bindTexture() function which takes QImage as input. This QImage as I noted is created from the pixmap byte array generated by screen shot.


/* save png directly to qbytearray */
QPixmap pixmap;
QByteArray bytes;
QBuffer buffer(&bytes);
pixmap = QPixmap::grabWidget(this);
buffer.open(QIODevice::WriteOnly);
pixmap.save(&buffer, "PNG"); // writes pixmap into bytes in PNG format

emit sendPixmapToMainWin(bytes);

Where program terminates:

void GlWidget::pixmapCatchFromForm(QByteArray bytes)
{
QImage image((const uchar* )bytes.constData(), glWidth, glHeight, QImage::Format_ARGB32);
texture = bindTexture(image); // something's wrong with image apparently
qDebug() << texture; // returns 1
}



Rendering is correct, I set the texture here to be rendered:


void GlWidget::paintGL()
{
//! [5]
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

QMatrix4x4 mMatrix;
QMatrix4x4 vMatrix;

QMatrix4x4 cameraTransformation;
cameraTransformation.rotate(alpha, 0, 1, 0);
cameraTransformation.rotate(beta, 1, 0, 0);

QVector3D cameraPosition = cameraTransformation * QVector3D(0, 0, distance);
QVector3D cameraUpDirection = cameraTransformation * QVector3D(0, 1, 0);

vMatrix.lookAt(cameraPosition, QVector3D(0, 0, 0), cameraUpDirection);

//! [6]
shaderProgram.bind();

shaderProgram.setUniformValue("mvpMatrix", pMatrix * vMatrix * mMatrix);

shaderProgram.setUniformValue("texture", 0);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glActiveTexture(0);

shaderProgram.setAttributeArray("vertex", vertices.constData());
shaderProgram.enableAttributeArray("vertex");

shaderProgram.setAttributeArray("textureCoordinate", textureCoordinates.constData());
shaderProgram.enableAttributeArray("textureCoordinate");

glDrawArrays(GL_TRIANGLES, 0, vertices.size());

shaderProgram.disableAttributeArray("vertex");

shaderProgram.disableAttributeArray("textureCoordinate");

shaderProgram.release();
}

wysota
18th September 2013, 14:06
I would start with:


The buffer must remain valid throughout the life of the QImage and all copies that have not been modified or otherwise detached from the original buffer.

saman_artorious
19th September 2013, 08:43
I would start with:

Thank you. This solved the problem:


void GlWidget::pixmapCatchFromForm(QByteArray bytes)
{
image->loadFromData(bytes, "PNG");
texture = bindTexture(*image);
qDebug() << texture; // returns 1
updateGL();
}


One thing I am very curious about is what keeps the CPU so busy. In my program, I have a timer which triggers every 40 ms, shoots screen and signals it to glWidget which is responsible for creating a texture from that screen shot. The program uses up to 90% of CPU. even without texturing! a simple timer and a screen shot grabWidget function takes up to 90%, I do not understand why!

wysota
19th September 2013, 09:45
grabWidget is a costly method.

saman_artorious
22nd September 2013, 06:05
grabWidget is a costly method.

is there any alternative?

ChrisW67
22nd September 2013, 06:28
If I read your code's intent correctly you are:

Creating a QPixmap using grabWidget()
Converting the QPixmap to a PNG encoded data stream in a QByteArray
Passing the QByteArray to another routine.
Creating a QImage from the PNG encoded data stream
Binding the QImage texture into a QGLWidget.

Perhaps I have missed something but steps 2 and 4 seem pointless. Why not just pass the QPixmap and call QGLWidget::bindTexture() on that? You avoid two costly conversions through PNG and the construction of a QImage.

saman_artorious
22nd September 2013, 07:31
Thanks for your idea. I tried it, but it had no effect in term of CPU reduction.

wysota
22nd September 2013, 16:44
Try this:

http://www.opengl.org/registry/specs/EXT/texture_from_pixmap.txt