gl: rename platform cocoa to cgl
[platform/upstream/gstreamer.git] / tests / examples / gl / qt / qglwtextureshare / qglrenderer.cpp
1 /*
2  * GStreamer
3  * Copyright (C) 2009 Julien Isorce <julien.isorce@gmail.com>
4  * Copyright (C) 2009 Andrey Nechypurenko <andreynech@gmail.com>
5  * Copyright (C) 2010 Nuno Santos <nunosantos@imaginando.net>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 #include <QGLWidget>
24 #include <QApplication>
25 #include <QCloseEvent>
26
27 #include <gst/video/video.h>
28 #include <gst/gl/gstglmemory.h>
29
30 #include "gstthread.h"
31 #include "qglrenderer.h"
32 #include "pipeline.h"
33
34 #if defined(Q_WS_MAC)
35 extern void *qt_current_nsopengl_context();
36 #endif
37
38 QGLRenderer::QGLRenderer(const QString &videoLocation,
39                          QWidget *parent)
40   : QGLWidget(parent),
41     videoLoc(videoLocation),
42     gst_thread(NULL),
43     closing(false),
44     frame(NULL)
45 {
46     move(20, 10);
47     resize(640, 480);
48 }
49
50 QGLRenderer::~QGLRenderer()
51 {
52 }
53
54 void
55 QGLRenderer::initializeGL()
56 {
57     GstGLContext *context;
58     GstGLDisplay *display;
59
60     display = gst_gl_display_new ();
61
62     /* FIXME: Allow the choice at runtime */
63 #if defined(GST_GL_HAVE_PLATFORM_WGL)
64     context = gst_gl_context_new_wrapped (display, (guintptr) wglGetCurrentContext (), GST_GL_PLATFORM_WGL, GST_GL_API_OPENGL);
65 #elif defined (GST_GL_HAVE_PLATFORM_CGL)
66     context = gst_gl_context_new_wrapped (display, (guintptr) qt_current_nsopengl_context(), GST_GL_PLATFORM_CGL, GST_GL_API_OPENGL);
67 #elif defined(GST_GL_HAVE_PLATFORM_GLX)
68     context = gst_gl_context_new_wrapped (display, (guintptr) glXGetCurrentContext (), GST_GL_PLATFORM_GLX, GST_GL_API_OPENGL);
69 #endif
70     gst_object_unref (display);
71
72     // We need to unset Qt context before initializing gst-gl plugin.
73     // Otherwise the attempt to share gst-gl context with Qt will fail.
74     this->doneCurrent();
75     this->gst_thread = 
76       new GstThread(context, this->videoLoc, SLOT(newFrame()), this);
77     this->makeCurrent();
78
79     QObject::connect(this->gst_thread, SIGNAL(finished()),
80                    this, SLOT(close()));
81     QObject::connect(this, SIGNAL(closeRequested()),
82                    this->gst_thread, SLOT(stop()), Qt::QueuedConnection);
83
84     qglClearColor(QApplication::palette().color(QPalette::Active,
85                                                 QPalette::Window));
86     //glShadeModel(GL_FLAT);
87     //glEnable(GL_DEPTH_TEST);
88     //glEnable(GL_CULL_FACE);
89     glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
90
91     this->gst_thread->start();
92 }
93
94 void
95 QGLRenderer::resizeGL(int width, int height)
96 {
97   // Reset The Current Viewport And Perspective Transformation
98   glViewport(0, 0, width, height);
99
100   glMatrixMode(GL_PROJECTION);
101   glLoadIdentity();
102
103   gluPerspective(45.0f, (GLfloat)width/(GLfloat)height, 0.1f, 100.0f);
104   glMatrixMode(GL_MODELVIEW);
105 }
106
107 void
108 QGLRenderer::newFrame()
109 {
110     Pipeline *pipeline = this->gst_thread->getPipeline();
111     if(!pipeline)
112       return;
113
114     /* frame is initialized as null */
115     if (this->frame)
116         pipeline->queue_output_buf.put(this->frame);
117
118     this->frame = pipeline->queue_input_buf.get();
119
120     /* direct call to paintGL (no queued) */
121     this->updateGL();
122 }
123
124 void
125 QGLRenderer::paintGL()
126 {
127     static GLfloat      xrot = 0;
128     static GLfloat      yrot = 0;
129     static GLfloat      zrot = 0;
130
131     if (this->frame)
132     {
133         guint tex_id;
134         GstMemory *mem;
135         GstVideoInfo v_info;
136         GstVideoFrame v_frame;
137         GstVideoMeta *v_meta;
138
139         mem = gst_buffer_peek_memory (this->frame, 0);
140         v_meta = gst_buffer_get_video_meta (this->frame);
141
142         if (gst_is_gl_memory (mem)) {
143             gst_video_info_set_format (&v_info, v_meta->format, v_meta->width,
144                 v_meta->height);
145
146             gst_video_frame_map (&v_frame, &v_info, this->frame,
147                 (GstMapFlags) (GST_MAP_READ | GST_MAP_GL));
148
149             tex_id = *(guint *) v_frame.data[0];
150         }
151
152         glEnable(GL_DEPTH_TEST);
153
154         glEnable(GL_TEXTURE_2D);
155         glBindTexture(GL_TEXTURE_2D, tex_id);
156         if(glGetError () != GL_NO_ERROR)
157         {
158           qDebug ("failed to bind texture that comes from gst-gl");
159           emit closeRequested();
160           return;
161         }
162
163         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
164         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
165         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
166                       GL_CLAMP_TO_EDGE);
167         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
168                       GL_CLAMP_TO_EDGE);
169         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
170
171         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
172         glMatrixMode(GL_MODELVIEW);
173         glLoadIdentity();
174
175         glTranslatef(0.0f,0.0f,-5.0f);
176
177         glRotatef(xrot,1.0f,0.0f,0.0f);
178         glRotatef(yrot,0.0f,1.0f,0.0f);
179         glRotatef(zrot,0.0f,0.0f,1.0f);
180
181         glBegin(GL_QUADS);
182             // Front Face
183             glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
184             glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
185             glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
186             glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
187             // Back Face
188             glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
189             glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
190             glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
191             glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
192             // Top Face
193             glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
194             glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
195             glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
196             glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
197             // Bottom Face
198             glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
199             glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
200             glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
201             glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
202             // Right face
203             glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
204             glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);
205             glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
206             glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
207             // Left Face
208             glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
209             glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
210             glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
211             glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);
212         glEnd();
213
214         xrot+=0.3f;
215         yrot+=0.2f;
216         zrot+=0.4f;
217
218         glBindTexture(GL_TEXTURE_2D, 0);
219     }
220 }
221
222 void
223 QGLRenderer::closeEvent(QCloseEvent* event)
224 {
225     if(this->closing == false)
226     {
227         this->closing = true;
228         emit closeRequested();
229         event->ignore();
230     }
231 }