]> git.sesse.net Git - kdenlive/blob - src/videoglwidget.cpp
Fix profile change on first clip load: http://kdenlive.org/mantis/view.php?id=2925
[kdenlive] / src / videoglwidget.cpp
1
2 #include <QtGui>
3 #include <QtOpenGL>
4 #ifdef Q_WS_MAC
5 #include <OpenGL/glu.h>
6 #else
7 #include <GL/glu.h>
8 #endif
9 #include "videoglwidget.h"
10
11 #ifndef GL_TEXTURE_RECTANGLE_EXT
12 #define GL_TEXTURE_RECTANGLE_EXT GL_TEXTURE_RECTANGLE_NV
13 #endif
14
15 VideoGLWidget::VideoGLWidget(QWidget *parent)
16     : QGLWidget(parent)
17     , m_image_width(0)
18     , m_image_height(0)
19     , m_texture(0)
20     , m_display_ratio(4.0 / 3.0)
21     , m_backgroundColor(Qt::gray)
22 {  
23     setAttribute(Qt::WA_PaintOnScreen);
24     setAttribute(Qt::WA_OpaquePaintEvent);
25 }
26
27 VideoGLWidget::~VideoGLWidget()
28 {
29     makeCurrent();
30     if (m_texture)
31         glDeleteTextures(1, &m_texture);
32 }
33
34 QSize VideoGLWidget::minimumSizeHint() const
35 {
36     return QSize(40, 30);
37 }
38
39 QSize VideoGLWidget::sizeHint() const
40 {
41     return QSize(400, 300);
42 }
43
44 void VideoGLWidget::setImageAspectRatio(double ratio)
45 {
46     m_display_ratio = ratio;
47     resizeGL(width(), height());
48 }
49
50 void VideoGLWidget::initializeGL()
51 {
52     qglClearColor(m_backgroundColor);
53     glShadeModel(GL_FLAT);
54     glDisable(GL_DEPTH_TEST);
55     glDisable(GL_CULL_FACE);
56     glDisable(GL_LIGHTING);
57     glDisable(GL_DITHER);
58     glDisable(GL_BLEND);
59     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
60 }
61
62 void VideoGLWidget::resizeEvent(QResizeEvent* event)
63 {
64     resizeGL(event->size().width(),event->size().height());
65 }
66
67 void VideoGLWidget::resizeGL(int width, int height)
68 {
69     double this_aspect = (double) width / height;
70
71     // Special case optimisation to negate odd effect of sample aspect ratio
72     // not corresponding exactly with image resolution.
73     if ((int)(this_aspect * 1000) == (int)(m_display_ratio * 1000)) {
74         w = width;
75         h = height;
76     }
77     // Use OpenGL to normalise sample aspect ratio
78     else if (height * m_display_ratio > width) {
79         w = width;
80         h = width / m_display_ratio;
81     } else {
82         w = height * m_display_ratio;
83         h = height;
84     }
85     x = (width - w) / 2;
86     y = (height - h) / 2;
87
88     glViewport(0, 0, width, height);
89     glMatrixMode(GL_PROJECTION);
90     glLoadIdentity();
91     gluOrtho2D(0, width, height, 0);
92     glMatrixMode(GL_MODELVIEW);
93     glClear(GL_COLOR_BUFFER_BIT);
94 }
95
96 void VideoGLWidget::activateMonitor()
97 {
98     makeCurrent();
99     glViewport(0, 0, width(), height());
100     glMatrixMode(GL_PROJECTION);
101     glLoadIdentity();
102     gluOrtho2D(0, width(), height(), 0);
103     glMatrixMode(GL_MODELVIEW);
104     glClear(GL_COLOR_BUFFER_BIT);
105 }
106
107 void VideoGLWidget::paintGL()
108 {
109     if (m_texture) {
110 #ifdef Q_WS_MAC
111                 glClear(GL_COLOR_BUFFER_BIT);
112 #endif
113         glEnable(GL_TEXTURE_RECTANGLE_EXT);
114         glBegin(GL_QUADS);
115         glTexCoord2i(0, 0);
116         glVertex2i(x, y);
117         glTexCoord2i(m_image_width, 0);
118         glVertex2i(x + w, y);
119         glTexCoord2i(m_image_width, m_image_height);
120         glVertex2i(x + w, y + h);
121         glTexCoord2i(0, m_image_height);
122         glVertex2i(x, y + h);
123         glEnd();
124         glDisable(GL_TEXTURE_RECTANGLE_EXT);
125     }
126 }
127
128 void VideoGLWidget::showImage(QImage image)
129 {
130     m_image_width = image.width();
131     m_image_height = image.height();
132     makeCurrent();
133     if (m_texture)
134         glDeleteTextures(1, &m_texture);
135
136     glPixelStorei(GL_UNPACK_ROW_LENGTH, m_image_width);
137     glGenTextures(1, &m_texture);
138     glBindTexture(GL_TEXTURE_RECTANGLE_EXT, m_texture);
139     glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
140     glTexParameterf(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
141     glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA8, m_image_width, m_image_height, 0, GL_RGBA,
142                  GL_UNSIGNED_BYTE, image.bits());
143     updateGL();
144 }
145
146 void VideoGLWidget::mouseDoubleClickEvent(QMouseEvent * event)
147 {
148     // TODO: disable screensaver?
149     Qt::WindowFlags flags = windowFlags();
150     if (!isFullScreen()) {
151         // Check if we ahave a multiple monitor setup
152 #if QT_VERSION >= 0x040600
153         int monitors = QApplication::desktop()->screenCount();
154 #else
155         int monitors = QApplication::desktop()->numScreens();
156 #endif
157         if (monitors > 1) {
158             QRect screenres;
159             // Move monitor widget to the second screen (one screen for Kdenlive, the other one for the Monitor widget
160             int currentScreen = QApplication::desktop()->screenNumber(this);
161             if (currentScreen < monitors - 1)
162                 screenres = QApplication::desktop()->screenGeometry(currentScreen + 1);
163             else
164                 screenres = QApplication::desktop()->screenGeometry(currentScreen - 1);
165             move(QPoint(screenres.x(), screenres.y()));
166             resize(screenres.width(), screenres.height());
167         }
168
169         m_baseFlags = flags & (Qt::Window | Qt::SubWindow);
170         flags |= Qt::Window;
171         flags ^= Qt::SubWindow;
172         setWindowFlags(flags);
173 #ifdef Q_WS_X11
174         // This works around a bug with Compiz
175         // as the window must be visible before we can set the state
176         show();
177         raise();
178         setWindowState(windowState() | Qt::WindowFullScreen);   // set
179 #else
180         setWindowState(windowState() | Qt::WindowFullScreen);   // set
181         show();
182 #endif
183     } else {
184         flags ^= (Qt::Window | Qt::SubWindow); //clear the flags...
185         flags |= m_baseFlags; //then we reset the flags (window and subwindow)
186         setWindowFlags(flags);
187         setWindowState(windowState()  ^ Qt::WindowFullScreen);   // reset
188         show();
189     }
190     event->accept();
191 }
192