gui creator classes c++ qt opengl qpainter

c++ - creator - qt gui



RepresentaciĆ³n eficiente fuera de pantalla de QPainterPaths(se requiere una soluciĆ³n OpenGL y no OpenGL) (1)

  1. En mi aplicación, pinto un mapa de calles usando QPainter en un widget
    • hecho por QPainterPaths que contiene rutas precalculadas para dibujar
    • el widget es actualmente un QWidget , no un QGLWidget , pero esto podría cambiar.
  2. 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 el widget
    • 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 en QWidget
  3. 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
  4. 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 convertir QPainterPaths a otra cosa que se pueda dibujar en un OpenGL 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.

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.