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