]> git.sesse.net Git - vlc/commitdiff
* all: just a basic OpenGL scope at the moment
authorCyril Deguet <asmax@videolan.org>
Wed, 14 Jul 2004 13:03:54 +0000 (13:03 +0000)
committerCyril Deguet <asmax@videolan.org>
Wed, 14 Jul 2004 13:03:54 +0000 (13:03 +0000)
modules/visualization/galaktos/Modules.am
modules/visualization/galaktos/glx.c
modules/visualization/galaktos/glx.h
modules/visualization/galaktos/main.c [new file with mode: 0644]
modules/visualization/galaktos/main.h [new file with mode: 0644]
modules/visualization/galaktos/plugin.c

index 4811532a868964e6619a34d11b337569206e8100..906e2a1784bb7cc05d537b79425b52ed308660c8 100644 (file)
@@ -1,4 +1,6 @@
 SOURCES_galaktos = plugin.c \
                    plugin.h \
                    glx.c \
-                   glx.h
+                   glx.h \
+                   main.c \
+                   main.h
index fcae57b741b0be31f5cbf6d474387a543e4c84f2..50b0bc9835c37fe5f5f49edfc8f304e2a65185bd 100644 (file)
 #include <GL/glx.h>
 
 /* Local prototypes */
-static int CreateWindow( galaktos_thread_t *p_thread, int i_width,
-                         int i_height );
+static int CreateWindow( galaktos_thread_t *p_thread, XVisualInfo *p_vi,
+                         int i_width, int i_height );
 
 
 typedef struct
 {
     Display     *p_display;
-    GLXFBConfig fbconf;
+    GLXContext  gwctx;
     Window      wnd;
     GLXWindow   gwnd;
+    GLXPbuffer  gpbuf;
+    GLXContext  gpctx;
+    Atom        wm_delete;
 }
 glx_data_t;
 #define OS_DATA ((glx_data_t*)(p_thread->p_os_data))
@@ -49,9 +52,13 @@ int galaktos_glx_init( galaktos_thread_t *p_thread, int i_width, int i_height )
     int i_maj, i_min;
     int i_nbelem;
     GLXFBConfig *p_fbconfs, fbconf;
-    static const int p_attr[] = { GLX_RED_SIZE, 5, GLX_GREEN_SIZE, 5,
-                                  GLX_BLUE_SIZE, 5, GLX_DOUBLEBUFFER, True,
-                                  GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, 0 };
+    XVisualInfo *p_vi;
+    GLXContext gwctx;
+    int i;
+    GLXPbuffer gpbuf;
+    int p_attr[] = { GLX_RED_SIZE, 5, GLX_GREEN_SIZE, 5,
+                     GLX_BLUE_SIZE, 5, GLX_DOUBLEBUFFER, True,
+                     GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, 0 };
 
     /* Initialize OS data */
     p_thread->p_os_data = malloc( sizeof( glx_data_t ) );
@@ -99,50 +106,180 @@ int galaktos_glx_init( galaktos_thread_t *p_thread, int i_width, int i_height )
         }
         return -1;
     }
-    OS_DATA->fbconf = fbconf = p_fbconfs[0];
+    fbconf = p_fbconfs[0];
+
+    /* Get the X11 visual */
+    p_vi = glXGetVisualFromFBConfig( p_display, fbconf );
+    if( !p_vi )
+    {
+        msg_Err( p_thread, "Cannot get X11 visual" );
+        XFree( p_fbconfs );
+        return -1;
+    }
+
+    /* Create the window */
+    if( CreateWindow( p_thread, p_vi, i_width, i_height ) == -1 )
+    {
+        XFree( p_fbconfs );
+        XFree( p_vi );
+        return -1;
+    }
+    XFree( p_vi );
+
+    /* Create the GLX window */
+    OS_DATA->gwnd = glXCreateWindow( p_display, fbconf, OS_DATA->wnd, NULL );
+    if( OS_DATA->gwnd == None )
+    {
+        msg_Err( p_thread, "Cannot create GLX window" );
+        return -1;
+    }
+
+    /* Create an OpenGL context */
+    OS_DATA->gwctx = gwctx = glXCreateNewContext( p_display, fbconf,
+            GLX_RGBA_TYPE, NULL, True );
+    if( !gwctx )
+    {
+        msg_Err( p_thread, "Cannot create OpenGL context");
+        XFree( p_fbconfs );
+        return -1;
+    }
+    XFree( p_fbconfs );
+
+    /* Get a FB config for the pbuffer */
+    p_attr[1] = 8;                  // RED_SIZE
+    p_attr[3] = 8;                  // GREEN_SIZE
+    p_attr[5] = 8;                  // BLUE_SIZE
+    p_attr[7] = False;              // DOUBLEBUFFER
+    p_attr[9] = GLX_PBUFFER_BIT;    // DRAWABLE_TYPE
+    p_fbconfs = glXChooseFBConfig( p_display, 0, p_attr, &i_nbelem );
+    if( (i_nbelem <= 0) || !p_fbconfs )
+    {
+        msg_Err( p_thread, "Cannot get FB configurations for pbuffer");
+        if( p_fbconfs )
+        {
+            XFree( p_fbconfs );
+        }
+        return -1;
+    }
+    fbconf = p_fbconfs[0];
+
+    /* Create a pbuffer */
+    i = 0;
+    p_attr[i++] = GLX_PBUFFER_WIDTH;
+    p_attr[i++] = 512;
+    p_attr[i++] = GLX_PBUFFER_HEIGHT;
+    p_attr[i++] = 512;
+    p_attr[i++] = GLX_PRESERVED_CONTENTS;
+    p_attr[i++] = True;
+    p_attr[i++] = 0;
+    OS_DATA->gpbuf = gpbuf = glXCreatePbuffer( p_display, fbconf, p_attr );
+    if( !gpbuf )
+    {
+        msg_Err( p_thread, "Failed to create GLX pbuffer" );
+        XFree( p_fbconfs );
+        return -1;
+    }
 
-    if( CreateWindow( p_thread, i_width, i_height ) == -1 )
+    /* Create the pbuffer context */
+    OS_DATA->gpctx = glXCreateNewContext( p_display, fbconf, GLX_RGBA_TYPE,
+                                          gwctx, True );
+    if( !OS_DATA->gpctx )
     {
+        msg_Err( p_thread, "Failed to create pbuffer context" );
         XFree( p_fbconfs );
         return -1;
     }
 
-    msg_Err( p_thread, "NOT IMPLEMENTED YET ;)" );
+    XFree( p_fbconfs );
+
+    XMapWindow( p_display, OS_DATA->wnd );
+    XFlush( p_display );
+    glXMakeContextCurrent( p_display, OS_DATA->gwnd, OS_DATA->gwnd, gwctx );
+
     return 0;
 }
 
 
-int CreateWindow( galaktos_thread_t *p_thread, int i_width, int i_height )
+int galaktos_glx_handle_events( galaktos_thread_t *p_thread )
 {
     Display *p_display;
-    XVisualInfo *p_vi;
-    XSetWindowAttributes xattr;
-    Window wnd;
 
     p_display = OS_DATA->p_display;
-    /* Get the X11 visual */
-    p_vi = glXGetVisualFromFBConfig( p_display, OS_DATA->fbconf );
-    if( !p_vi )
+
+    /* loop on X11 events */
+    while( XPending( p_display ) > 0 )
     {
-        msg_Err( p_thread, "Cannot get X11 visual" );
-        return -1;
+        XEvent evt;
+        XNextEvent( p_display, &evt );
+        switch( evt.type )
+        {
+            case ClientMessage:
+            {
+                /* Delete notification */
+                if( (evt.xclient.format == 32) &&
+                    ((Atom)evt.xclient.data.l[0] == OS_DATA->wm_delete) )
+                {
+                    return 1;
+                }
+                break;
+            }
+        }
     }
+    return 0;
+}
+
+
+void galaktos_glx_swap( galaktos_thread_t *p_thread )
+{
+    glXSwapBuffers( OS_DATA->p_display, OS_DATA->gwnd );
+}
+
+
+void galaktos_glx_done( galaktos_thread_t *p_thread )
+{
+    Display *p_display;
+
+    p_display = OS_DATA->p_display;
+    glXDestroyContext( p_display, OS_DATA->gpctx );
+    glXDestroyPbuffer( p_display, OS_DATA->gpbuf );
+    glXDestroyContext( p_display, OS_DATA->gwctx );
+    glXDestroyWindow( p_display, OS_DATA->gwnd );
+    XDestroyWindow( p_display, OS_DATA->wnd );
+    XCloseDisplay( p_display );
+}
+
+
+int CreateWindow( galaktos_thread_t *p_thread, XVisualInfo *p_vi,
+                  int i_width, int i_height )
+{
+    Display *p_display;
+    XSetWindowAttributes xattr;
+    Window wnd;
+    XSizeHints* p_size_hints;
 
+    p_display = OS_DATA->p_display;
     /* Create the window */
     xattr.background_pixel = BlackPixel( p_display, DefaultScreen(p_display) );
     xattr.border_pixel = 0;
     OS_DATA->wnd = wnd = XCreateWindow( p_display, DefaultRootWindow(p_display),
             0, 0, i_width, i_height, 0, p_vi->depth, InputOutput, p_vi->visual,
             CWBackPixel | CWBorderPixel, &xattr);
-    XFree( p_vi );
 
-    /* Create the GLX window */
-    OS_DATA->gwnd = glXCreateWindow( p_display, OS_DATA->fbconf, wnd, NULL );
-    if( OS_DATA->gwnd == None )
-    {
-        msg_Err( p_thread, "Cannot create GLX window" );
-        return -1;
-    }
+    /* Allow the window to be deleted by the window manager */
+    OS_DATA->wm_delete = XInternAtom( p_display, "WM_DELETE_WINDOW", False );
+    XSetWMProtocols( p_display, wnd, &OS_DATA->wm_delete, 1 );
+
+    /* Prevent the window from being resized */
+    p_size_hints = XAllocSizeHints();
+    p_size_hints->flags = PMinSize | PMaxSize;
+    p_size_hints->min_width = i_width;
+    p_size_hints->min_height = i_height;
+    p_size_hints->max_width = i_width;
+    p_size_hints->max_height = i_height;
+    XSetWMNormalHints( p_display, wnd, p_size_hints );
+    XFree( p_size_hints );
+
+    XSelectInput( p_display, wnd, KeyPressMask );
 
     return 0;
 }
index dc155365d2cfb80857b210532f7523c29ac36a8f..c3f09f7dfd78444e4ec0e711c0450c8a4297a2b5 100644 (file)
@@ -27,5 +27,8 @@
 #include "plugin.h"
 
 int galaktos_glx_init( galaktos_thread_t *p_thread, int i_width, int i_height );
+void galaktos_glx_done( galaktos_thread_t *p_thread );
+int galaktos_glx_handle_events( galaktos_thread_t *p_thread );
+void galaktos_glx_swap( galaktos_thread_t *p_thread );
 
 #endif
diff --git a/modules/visualization/galaktos/main.c b/modules/visualization/galaktos/main.c
new file mode 100644 (file)
index 0000000..3d29190
--- /dev/null
@@ -0,0 +1,66 @@
+/*****************************************************************************
+ * main.c:
+ *****************************************************************************
+ * Copyright (C) 2004 VideoLAN
+ * $Id$
+ *
+ * Authors: Cyril Deguet <asmax@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+#include "glx.h"
+#include <GL/gl.h>
+#include <unistd.h>
+#include <math.h>
+
+int galaktos_update( galaktos_thread_t *p_thread, int16_t p_data[2][512] )
+{
+    int j;
+
+    /* Process X11 events */
+    if( galaktos_glx_handle_events( p_thread ) == 1 )
+    {
+        return 1;
+    }
+
+    glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glBegin(GL_TRIANGLE_STRIP);
+        glColor3f( 0.5f, 0.0f, 0.0f);
+        glVertex2f(  -1.0f,  1.0f);
+        glColor3f( 0.2f, 0.2f, 0.0f);
+        glVertex2f(  1.0f,  1.0f);
+        glColor3f( 0.0f, 0.2f, 0.2f);
+        glVertex2f(  -1.0f,  -1.0f);
+        glColor3f( 0.0f, 0.0f, 0.5f);
+        glVertex2f(  1.0f,  -1.0f);
+    glEnd();
+    glBegin(GL_LINE_STRIP);
+        glColor3f( 1.0f, 1.0f, 1.0f);
+        glVertex2f( -1.0f, 0.0f);
+        for(j=0; j<512; j++)
+        {
+            glVertex2f( (float)j/256-1.0f, (float)p_data[0][j]/32000);
+        }
+    glEnd();
+
+    galaktos_glx_swap( p_thread );
+
+    return 0;
+}
+
+
diff --git a/modules/visualization/galaktos/main.h b/modules/visualization/galaktos/main.h
new file mode 100644 (file)
index 0000000..de7eb88
--- /dev/null
@@ -0,0 +1,29 @@
+/*****************************************************************************
+ * main.h:
+ *****************************************************************************
+ * Copyright (C) 2004 VideoLAN
+ * $Id$
+ *
+ * Authors: Cyril Deguet <asmax@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+#ifndef _GALAKTOS_MAIN_H_
+#define _GALAKTOS_MAIN_H_
+
+int galaktos_update( galaktos_thread_t *p_thread, int16_t p_data[2][512] );
+
+#endif
index fb75601a0d017efa2f41227f215f3739eaa8c1fb..becf8b90061cf67359bab8f9e5d9b58095c69c60 100644 (file)
@@ -26,6 +26,7 @@
  *****************************************************************************/
 #include "plugin.h"
 #include "glx.h"
+#include "main.h"
 
 #include <vlc/input.h>
 #include <vlc/vout.h>
@@ -93,7 +94,6 @@ static int Open( vlc_object_t *p_this )
         vlc_object_create( p_filter, sizeof( galaktos_thread_t ) );
     vlc_object_attach( p_thread, p_this );
 
-    galaktos_glx_init( p_thread, 512, 512 );
 /*
     var_Create( p_thread, "galaktos-width", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
     var_Get( p_thread, "galaktos-width", &width );
@@ -240,11 +240,34 @@ static void Thread( vlc_object_t *p_this )
     audio_date_t i_pts;
     int16_t p_data[2][512];
     int i_data = 0, i_count = 0;
+    int i;
+
+    galaktos_glx_init( p_thread, 512, 512 );
 
     while( !p_thread->b_die )
     {
+        /* goom_update is damn slow, so just copy data and release the lock */
+        vlc_mutex_lock( &p_thread->lock );
+        if( FillBuffer( (int16_t *)p_data, &i_data, &i_pts,
+                        &p_thread->date, p_thread ) != VLC_SUCCESS )
+            vlc_cond_wait( &p_thread->wait, &p_thread->lock );
+        vlc_mutex_unlock( &p_thread->lock );
+
+        if( galaktos_update( p_thread, p_data ) == 1 )
+        {
+            p_thread->b_die = 1;
+        }
+
+        if( p_thread->psz_title )
+        {
+            free( p_thread->psz_title );
+            p_thread->psz_title = NULL;
+        }
+
         msleep( VOUT_OUTMEM_SLEEP );
     }
+
+    galaktos_glx_done( p_thread );
 }
 
 /*****************************************************************************