From 40cbe6a355c8754930bc9e11806c582b4b0cf52a Mon Sep 17 00:00:00 2001 From: Cyril Deguet Date: Wed, 14 Jul 2004 13:03:54 +0000 Subject: [PATCH] * all: just a basic OpenGL scope at the moment --- modules/visualization/galaktos/Modules.am | 4 +- modules/visualization/galaktos/glx.c | 189 +++++++++++++++++++--- modules/visualization/galaktos/glx.h | 3 + modules/visualization/galaktos/main.c | 66 ++++++++ modules/visualization/galaktos/main.h | 29 ++++ modules/visualization/galaktos/plugin.c | 25 ++- 6 files changed, 288 insertions(+), 28 deletions(-) create mode 100644 modules/visualization/galaktos/main.c create mode 100644 modules/visualization/galaktos/main.h diff --git a/modules/visualization/galaktos/Modules.am b/modules/visualization/galaktos/Modules.am index 4811532a86..906e2a1784 100644 --- a/modules/visualization/galaktos/Modules.am +++ b/modules/visualization/galaktos/Modules.am @@ -1,4 +1,6 @@ SOURCES_galaktos = plugin.c \ plugin.h \ glx.c \ - glx.h + glx.h \ + main.c \ + main.h diff --git a/modules/visualization/galaktos/glx.c b/modules/visualization/galaktos/glx.c index fcae57b741..50b0bc9835 100644 --- a/modules/visualization/galaktos/glx.c +++ b/modules/visualization/galaktos/glx.c @@ -27,16 +27,19 @@ #include /* 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; } diff --git a/modules/visualization/galaktos/glx.h b/modules/visualization/galaktos/glx.h index dc155365d2..c3f09f7dfd 100644 --- a/modules/visualization/galaktos/glx.h +++ b/modules/visualization/galaktos/glx.h @@ -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 index 0000000000..3d29190f31 --- /dev/null +++ b/modules/visualization/galaktos/main.c @@ -0,0 +1,66 @@ +/***************************************************************************** + * main.c: + ***************************************************************************** + * Copyright (C) 2004 VideoLAN + * $Id$ + * + * Authors: Cyril Deguet + * + * 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 +#include +#include + +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 index 0000000000..de7eb88bc0 --- /dev/null +++ b/modules/visualization/galaktos/main.h @@ -0,0 +1,29 @@ +/***************************************************************************** + * main.h: + ***************************************************************************** + * Copyright (C) 2004 VideoLAN + * $Id$ + * + * Authors: Cyril Deguet + * + * 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 diff --git a/modules/visualization/galaktos/plugin.c b/modules/visualization/galaktos/plugin.c index fb75601a0d..becf8b9006 100644 --- a/modules/visualization/galaktos/plugin.c +++ b/modules/visualization/galaktos/plugin.c @@ -26,6 +26,7 @@ *****************************************************************************/ #include "plugin.h" #include "glx.h" +#include "main.h" #include #include @@ -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 ); } /***************************************************************************** -- 2.39.2