c++ - creator - qt gui
RepresentaciĆ³n eficiente fuera de pantalla de QPainterPaths(se requiere una soluciĆ³n OpenGL y no OpenGL) (1)
- En mi aplicación, pinto un mapa de calles usando
QPainter
en unwidget
- hecho por
QPainterPaths
que contiene rutas precalculadas para dibujar - el
widget
es actualmente unQWidget
, no unQGLWidget
, pero esto podría cambiar.
- hecho por
- Estoy tratando de mover la pintura fuera de la pantalla y dividirla en trabajos fragmentados
- Quiero pintar cada trozo en una
QImage
y finalmente dibujar todas las imágenes en elwidget
-
QPainterPaths
ya están fragmentados, por lo que este no es el problema - El problema es que dibujar en
QImages
es aproximadamente 5 veces más lento que dibujar enQWidget
- Quiero pintar cada trozo en una
- Algunas pruebas de referencia que he hecho
- los valores de tiempo son promedios redondeados en varias ejecuciones
- El fragmento de prueba contiene 100
QPainterPaths
que tienen alrededor de 150 segmentos lineales lineales cada uno - los aproximadamente 15k caminos se dibujan con
QPainter::Antialiasing
render sugerencia,QPen
usa round cap y round join
- Recuerda que mi fuente son
QPainterPaths
(y ancho de línea + color, algunos dibujados , algunos llenos )- No necesito todos los otros tipos de dibujo de soportes
QPainter
- ¿
QPainterPaths
puede convertirQPainterPaths
a otra cosa que se pueda dibujar en unOpenGL buffer
Esta sería una buena solución. - No estoy familiarizado con la representación fuera de pantalla de
OpenGL
y sé que hay diferentes tipos de búfers OpenGL, de los cuales la mayoría no son para renderizado de imágenes en 2D, sino para datos de vértices.
- No necesito todos los otros tipos de dibujo de soportes
Paint Device for chunk | Rendering the chunk itself | Painting chunk on QWidget
-----------------------+----------------------------+--------------------------
QImage | 2000 ms | < 10 ms
QPixmap (*) | 250 ms | < 10 ms
QGLFramebufferObj. (*) | 50 ms | < 10 ms
QPicture | 50 ms | 400 ms
-----------------------+----------------------------+--------------------------
none (directly on a QWidget in paintEvent) | 400 ms
----------------------------------------------------+--------------------------
(*) These 2 lines have been added afterwards and are solutions to the problem!
Sería bueno si también puede decirme una solución que no esté basada en OpenGL , ya que quiero compilar mi aplicación en dos versiones: OpenGL
y non-OpenGL
.
Además, quiero que la solución pueda renderizarse en un hilo que no sea GUI .
¿Hay una buena manera de dibujar eficientemente los fragmentos fuera de la pantalla?
¿Hay una parte fuera de la pantalla de QGLWidget
(un buffer QGLWidget
OpenGL
) que se puede usar como un dispositivo de pintura para QPainter
?
El documento de Qt-interest Archive, agosto de 2008 QGLContext :: create ()
dice:
Un QGLContext solo se puede crear con un dispositivo de pintura GL válido, lo que significa que debe estar vinculado a un QGLWidget, QGLPixelBuffer o QPixmap cuando lo crea. Si usa un QPixmap, le dará un renderizado solo de software, y no lo desea. Un QGLFramebufferObject no es en sí mismo un dispositivo de pintura GL válido, solo se puede crear dentro del contexto de un QGLWidget o un QGLPixelBuffer . Lo que esto significa es que necesita un QGLWidget o QGLPixelBuffer como base para su QGLFramebufferObject.
Como indica el documento, si desea procesar en un búfer fuera de la pantalla utilizando OpenGL, necesita QGLPixelBuffer. El siguiente código es un ejemplo muy simple que demuestra cómo usar QGLPixelBuffer con OpenGL:
#include <QtGui/QApplication>
#include <Windows.h>
#include <gl/GL.h>
#include <gl/GLU.h>
#include <QtOpenGL/QGLFormat>
#include <QtOpenGL/QGLPixelBuffer>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// Construct an OpenGL pixel buffer.
QGLPixelBuffer glPixBuf(100, 100);
// Make the QGLContext object bound to pixel buffer the current context
glPixBuf.makeCurrent();
// The opengl commands
glClearColor(1.0, 1.0, 1.0, 0.0);
glViewport(0, 0, 100, 100);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 100, 0, 100);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
glPointSize(4.0);
glBegin(GL_TRIANGLES);
glVertex2i(10, 10);
glVertex2i(50, 50);
glVertex2i(25, 75);
glEnd();
// At last, the pixel buffer was saved as an image
QImage &pImage = glPixBuf.toImage();
pImage.save(QString::fromLocal8Bit("gl.png"));
return a.exec();
}
El resultado del programa es un archivo de imagen png como:
Para la versión non-opengl que usa QPixmap, el código puede estar en las formas de abajo:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QPixmap pixmap(100, 100);
QPainter painter;
painter.begin(&pixmap);
painter.drawText(10, 45, QString::fromLocal8Bit("I love American."));
painter.end();
pixmap.save(QString::fromLocal8Bit("pixmap.png"));
return a.exec();
}
El resultado del programa anterior es un archivo png que se ve así:
Aunque el código es simple, pero funciona, tal vez puede hacer algunos cambios para que sea adecuado para usted.