]> git.sesse.net Git - kdenlive/blob - src/videoglwidget.cpp
Double click on monitor brings fullscreen video display, but only with OpenGL monitor...
[kdenlive] / src / videoglwidget.cpp
1
2 #include <QtGui>
3 #include <QtOpenGL>
4 #include "videoglwidget.h"
5
6 #ifndef GL_TEXTURE_RECTANGLE_EXT
7 #define GL_TEXTURE_RECTANGLE_EXT GL_TEXTURE_RECTANGLE_NV
8 #endif
9
10 VideoGLWidget::VideoGLWidget(QWidget *parent)
11     : QGLWidget(parent)
12     , m_image_width(0)
13     , m_image_height(0)
14     , m_texture(0)
15     , m_display_ratio(4.0 / 3.0)
16     , m_backgroundColor(Qt::gray)
17 {
18 }
19
20 VideoGLWidget::~VideoGLWidget()
21 {
22     makeCurrent();
23     if (m_texture)
24         glDeleteTextures(1, &m_texture);
25 }
26
27 QSize VideoGLWidget::minimumSizeHint() const
28 {
29     return QSize(40, 30);
30 }
31
32 QSize VideoGLWidget::sizeHint() const
33 {
34     return QSize(400, 300);
35 }
36
37 void VideoGLWidget::initializeGL()
38 {
39     qglClearColor(m_backgroundColor);
40     glShadeModel(GL_FLAT);
41     glDisable(GL_DEPTH_TEST);
42     glDisable(GL_CULL_FACE);
43     glDisable(GL_LIGHTING);
44     glDisable(GL_DITHER);
45     glDisable(GL_BLEND);
46     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
47 }
48
49 void VideoGLWidget::resizeGL(int width, int height)
50 {
51     double this_aspect = (double) width / height;
52
53     // Special case optimisation to negate odd effect of sample aspect ratio
54     // not corresponding exactly with image resolution.
55     if ((int)(this_aspect * 1000) == (int)(m_display_ratio * 1000)) {
56         w = width;
57         h = height;
58     }
59     // Use OpenGL to normalise sample aspect ratio
60     else if (height * m_display_ratio > width) {
61         w = width;
62         h = width / m_display_ratio;
63     } else {
64         w = height * m_display_ratio;
65         h = height;
66     }
67     x = (width - w) / 2;
68     y = (height - h) / 2;
69
70     glViewport(0, 0, width, height);
71     glMatrixMode(GL_PROJECTION);
72     glLoadIdentity();
73     gluOrtho2D(0, width, height, 0);
74     glMatrixMode(GL_MODELVIEW);
75 }
76
77 void VideoGLWidget::paintGL()
78 {
79     glClear(GL_COLOR_BUFFER_BIT); // | GL_DEPTH_BUFFER_BIT // Depth is disabled, so shouldn'b be necessary to clear DEPTH_BUFFER
80     if (m_texture) {
81         glEnable(GL_TEXTURE_RECTANGLE_EXT);
82         glBegin(GL_QUADS);
83         glTexCoord2i(0, 0);
84         glVertex2i(x, y);
85         glTexCoord2i(m_image_width, 0);
86         glVertex2i(x + w, y);
87         glTexCoord2i(m_image_width, m_image_height);
88         glVertex2i(x + w, y + h);
89         glTexCoord2i(0, m_image_height);
90         glVertex2i(x, y + h);
91         glEnd();
92         glDisable(GL_TEXTURE_RECTANGLE_EXT);
93     }
94 }
95
96 void VideoGLWidget::showImage(QImage image)
97 {
98     m_image_width = image.width();
99     m_image_height = image.height();
100
101     makeCurrent();
102     if (m_texture)
103         glDeleteTextures(1, &m_texture);
104
105     glPixelStorei(GL_UNPACK_ROW_LENGTH, m_image_width);
106     glGenTextures(1, &m_texture);
107     glBindTexture(GL_TEXTURE_RECTANGLE_EXT, m_texture);
108     glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
109     glTexParameterf(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
110     glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA8, m_image_width, m_image_height, 0, GL_RGBA,
111                  GL_UNSIGNED_BYTE, image.bits());
112     updateGL();
113 }
114
115 void VideoGLWidget::mouseDoubleClickEvent(QMouseEvent * event)
116 {
117     // TODO: disable screensaver? or should we leave that responsibility to the
118     // application?
119     Qt::WindowFlags flags = windowFlags();
120     if (!isFullScreen()) {
121         //we only update that value if it is not already fullscreen
122         m_baseFlags = flags & (Qt::Window | Qt::SubWindow);
123         flags |= Qt::Window;
124         flags ^= Qt::SubWindow;
125         setWindowFlags(flags);
126 #ifdef Q_WS_X11
127         // This works around a bug with Compiz
128         // as the window must be visible before we can set the state
129         show();
130         raise();
131         setWindowState(windowState() | Qt::WindowFullScreen);   // set
132 #else
133         setWindowState(windowState() | Qt::WindowFullScreen);   // set
134         show();
135 #endif
136     } else {
137         flags ^= (Qt::Window | Qt::SubWindow); //clear the flags...
138         flags |= m_baseFlags; //then we reset the flags (window and subwindow)
139         setWindowFlags(flags);
140         setWindowState(windowState()  ^ Qt::WindowFullScreen);   // reset
141         show();
142     }
143 }
144