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