]> git.sesse.net Git - kdenlive/blob - src/videoglwidget.cpp
eff90f6ea97f53e1397fb9ab1fa443752ead13ac
[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::initializeGL()
45 {
46     qglClearColor(m_backgroundColor);
47     glShadeModel(GL_FLAT);
48     glDisable(GL_DEPTH_TEST);
49     glDisable(GL_CULL_FACE);
50     glDisable(GL_LIGHTING);
51     glDisable(GL_DITHER);
52     glDisable(GL_BLEND);
53     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
54 }
55
56 void VideoGLWidget::resizeEvent(QResizeEvent* event)
57 {
58     resizeGL(event->size().width(),event->size().height());
59 }
60 void VideoGLWidget::resizeGL(int width, int height)
61 {
62     double this_aspect = (double) width / height;
63
64     // Special case optimisation to negate odd effect of sample aspect ratio
65     // not corresponding exactly with image resolution.
66     if ((int)(this_aspect * 1000) == (int)(m_display_ratio * 1000)) {
67         w = width;
68         h = height;
69     }
70     // Use OpenGL to normalise sample aspect ratio
71     else if (height * m_display_ratio > width) {
72         w = width;
73         h = width / m_display_ratio;
74     } else {
75         w = height * m_display_ratio;
76         h = height;
77     }
78     x = (width - w) / 2;
79     y = (height - h) / 2;
80
81     glViewport(0, 0, width, height);
82     glMatrixMode(GL_PROJECTION);
83     glLoadIdentity();
84     gluOrtho2D(0, width, height, 0);
85     glMatrixMode(GL_MODELVIEW);
86     glClear(GL_COLOR_BUFFER_BIT);
87 }
88
89 void VideoGLWidget::activateMonitor()
90 {
91     makeCurrent();
92     glViewport(0, 0, width(), height());
93     glMatrixMode(GL_PROJECTION);
94     glLoadIdentity();
95     gluOrtho2D(0, width(), height(), 0);
96     glMatrixMode(GL_MODELVIEW);
97     glClear(GL_COLOR_BUFFER_BIT);
98 }
99
100 void VideoGLWidget::paintGL()
101 {
102     if (m_texture) {
103 #ifdef Q_WS_MAC
104                 glClear(GL_COLOR_BUFFER_BIT);
105 #endif
106         glEnable(GL_TEXTURE_RECTANGLE_EXT);
107         glBegin(GL_QUADS);
108         glTexCoord2i(0, 0);
109         glVertex2i(x, y);
110         glTexCoord2i(m_image_width, 0);
111         glVertex2i(x + w, y);
112         glTexCoord2i(m_image_width, m_image_height);
113         glVertex2i(x + w, y + h);
114         glTexCoord2i(0, m_image_height);
115         glVertex2i(x, y + h);
116         glEnd();
117         glDisable(GL_TEXTURE_RECTANGLE_EXT);
118     }
119 }
120
121 void VideoGLWidget::showImage(QImage image)
122 {
123     m_image_width = image.width();
124     m_image_height = image.height();
125     makeCurrent();
126     if (m_texture)
127         glDeleteTextures(1, &m_texture);
128
129     glPixelStorei(GL_UNPACK_ROW_LENGTH, m_image_width);
130     glGenTextures(1, &m_texture);
131     glBindTexture(GL_TEXTURE_RECTANGLE_EXT, m_texture);
132     glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
133     glTexParameterf(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
134     glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA8, m_image_width, m_image_height, 0, GL_RGBA,
135                  GL_UNSIGNED_BYTE, image.bits());
136     updateGL();
137 }
138
139 void VideoGLWidget::mouseDoubleClickEvent(QMouseEvent * event)
140 {
141     // TODO: disable screensaver?
142     Qt::WindowFlags flags = windowFlags();
143     if (!isFullScreen()) {
144         // Check if we ahave a multiple monitor setup
145 #if QT_VERSION >= 0x040600
146         int monitors = QApplication::desktop()->screenCount();
147 #else
148         int monitors = QApplication::desktop()->numScreens();
149 #endif
150         if (monitors > 1) {
151             QRect screenres;
152             // Move monitor widget to the second screen (one screen for Kdenlive, the other one for the Monitor widget
153             int currentScreen = QApplication::desktop()->screenNumber(this);
154             if (currentScreen < monitors - 1)
155                 screenres = QApplication::desktop()->screenGeometry(currentScreen + 1);
156             else
157                 screenres = QApplication::desktop()->screenGeometry(currentScreen - 1);
158             move(QPoint(screenres.x(), screenres.y()));
159             resize(screenres.width(), screenres.height());
160         }
161
162         m_baseFlags = flags & (Qt::Window | Qt::SubWindow);
163         flags |= Qt::Window;
164         flags ^= Qt::SubWindow;
165         setWindowFlags(flags);
166 #ifdef Q_WS_X11
167         // This works around a bug with Compiz
168         // as the window must be visible before we can set the state
169         show();
170         raise();
171         setWindowState(windowState() | Qt::WindowFullScreen);   // set
172 #else
173         setWindowState(windowState() | Qt::WindowFullScreen);   // set
174         show();
175 #endif
176     } else {
177         flags ^= (Qt::Window | Qt::SubWindow); //clear the flags...
178         flags |= m_baseFlags; //then we reset the flags (window and subwindow)
179         setWindowFlags(flags);
180         setWindowState(windowState()  ^ Qt::WindowFullScreen);   // reset
181         show();
182     }
183     event->accept();
184 }
185