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