void GlSpectrumAnalyzerWindow::FrameResized(float fwidth, float fheight) { int width = int(fwidth); int height = int(fheight); fprintf(stderr, "GlSpectrumAnalyzerWindow::FrameResized(%f, %f)\n", fwidth, fheight); MakeCurrent(); // The OpenGL view has been resized, so we have to reconfigure our // OpenGL context to reflect that. if( height <= 0 ) height = 1; // prevent divide-by-zero glViewport( 0, 0, width, height ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective( 45.0, (float)width/(float)height, 0.1, 100.0 ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); ReleaseCurrent(); Sync(); // not sure it does anything needResize = false; }
static int Open (vlc_object_t *obj) { vlc_gl_t *gl = (vlc_gl_t *)obj; if (gl->surface->type != VOUT_WINDOW_TYPE_XID || !vlc_xlib_init (obj)) return VLC_EGENERIC; /* Initialize GLX display */ Display *dpy = XOpenDisplay (gl->surface->display.x11); if (dpy == NULL) return VLC_EGENERIC; vlc_gl_sys_t *sys = malloc (sizeof (*sys)); if (unlikely(sys == NULL)) { XCloseDisplay (dpy); return VLC_ENOMEM; } gl->sys = sys; sys->display = dpy; if (!CheckGLX (obj, dpy)) goto error; /* Determine our pixel format */ XWindowAttributes wa; if (!XGetWindowAttributes (dpy, gl->surface->handle.xid, &wa)) goto error; const int snum = XScreenNumberOfScreen (wa.screen); const VisualID visual = XVisualIDFromVisual (wa.visual); static const int attr[] = { GLX_RED_SIZE, 5, GLX_GREEN_SIZE, 5, GLX_BLUE_SIZE, 5, GLX_DOUBLEBUFFER, True, GLX_X_RENDERABLE, True, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, None }; int nelem; GLXFBConfig *confs = glXChooseFBConfig (dpy, snum, attr, &nelem); if (confs == NULL) { msg_Err (obj, "cannot choose GLX frame buffer configurations"); goto error; } GLXFBConfig conf; bool found = false; for (int i = 0; i < nelem && !found; i++) { conf = confs[i]; XVisualInfo *vi = glXGetVisualFromFBConfig (dpy, conf); if (vi == NULL) continue; if (vi->visualid == visual) found = true; XFree (vi); } XFree (confs); if (!found) { msg_Err (obj, "cannot match GLX frame buffer configuration"); goto error; } /* Create a drawing surface */ sys->win = glXCreateWindow (dpy, conf, gl->surface->handle.xid, NULL); if (sys->win == None) { msg_Err (obj, "cannot create GLX window"); goto error; } /* Create an OpenGL context */ sys->ctx = glXCreateNewContext (dpy, conf, GLX_RGBA_TYPE, NULL, True); if (sys->ctx == NULL) { glXDestroyWindow (dpy, sys->win); msg_Err (obj, "cannot create GLX context"); goto error; } /* Initialize OpenGL callbacks */ gl->sys = sys; gl->makeCurrent = MakeCurrent; gl->releaseCurrent = ReleaseCurrent; gl->resize = NULL; gl->swap = SwapBuffers; gl->getProcAddress = GetSymbol; #ifdef GLX_ARB_get_proc_address bool is_swap_interval_set = false; MakeCurrent (gl); # ifdef GLX_SGI_swap_control if (!is_swap_interval_set && CheckGLXext (dpy, snum, "GLX_SGI_swap_control")) { PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) glXGetProcAddressARB ((const GLubyte *)"glXSwapIntervalSGI"); assert (SwapIntervalSGI != NULL); is_swap_interval_set = !SwapIntervalSGI (1); } # endif # ifdef GLX_EXT_swap_control if (!is_swap_interval_set && CheckGLXext (dpy, snum, "GLX_EXT_swap_control")) { PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) glXGetProcAddress ((const GLubyte *)"glXSwapIntervalEXT"); assert (SwapIntervalEXT != NULL); SwapIntervalEXT (dpy, sys->win, 1); is_swap_interval_set = true; } # endif ReleaseCurrent (gl); #endif return VLC_SUCCESS; error: XCloseDisplay (dpy); free (sys); return VLC_EGENERIC; }
status_t GlSpectrumAnalyzerWindow::Render(const short *buf, int32 framecount) { if(!keeprunning) return B_ERROR; /* if (needResize) FrameResized(float(Frame().IntegerWidth() + 1), float(Frame().IntegerHeight() + 1)); */ // fprintf(stderr, "GlSpectrumAnalyzerWindow::Render()\n"); const uint16 *fft = controller->GetFFTForBuffer(buf,SP_MONO_CHANNEL); // The actual OpenGL scene. MakeCurrent(); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glLoadIdentity(); #if 1 // Move 5.0 units into the screen. // glTranslatef( 0.0, 0.0, -5.0 ); glTranslatef( 0.0, 0.0, -35.0 ); // Rotate before drawing the cube. glRotatef( xrot, 1.0, 0.0, 0.0 ); // X rotation glRotatef( yrot, 0.0, 1.0, 0.0 ); // Y rotation glRotatef( zrot, 0.0, 0.0, 1.0 ); // Z rotation glTranslatef( -19.0, 0.0, 0.0 ); for(int x=0;x<20;x++) { uint32 total=0; for(int i=0;i<3+x;i++) total+=*fft++; total/=4*512-x*90; if(total>110) total=110; if(total<lastpeak[x]) total=(total+lastpeak[x]*3)/4; lastpeak[x]=total; if(total) { //glColor3f(0.0, 1.0, 0.0); glColor3f(0.0, (float(total+100) / (110+100)), 0.0); float cubeHeight = total / 11; // Create a bar myglVerticalBar(0.8, 0.8, 0.0, cubeHeight); } if(total>peak[x]) { peak[x]=total; peakdelay[x]=20; } if(peakdelay[x]) peakdelay[x]--; if(peakdelay[x]==0) if(peak[x]) peak[x]--; glColor3f(1.0, 0.0, 0.0); float peakHeight = (peak[x] + 2) / 11; myglVerticalBar(0.8, 0.8, peakHeight, peakHeight+0.1); glTranslatef( 2.0, 0.0, 0.0 ); } /* glColor3f(1.0f,1.0f,0.0f); // Set Color To Yellow glTranslated(10,10,0); // Position The Text (0,0 - Bottom Left) int set = 0; glListBase(64-32+(128*set)); // Choose The Font Set (0 or 1) glCallLists(strlen(name),GL_UNSIGNED_BYTE, name); // Write The Text To The Screen */ #endif ReleaseCurrent(); SwapBuffers(); // show what we drew, else it's useless :-) snooze(5000); // Rotate things a bit. /* xrot += 0.3; yrot += 0.2; zrot += 0.4; */ xrot += 0.3; yrot += 0.4; zrot += 0.2; /* bView->Sync(); rView->DrawBitmapAsync(bitmap,bitmap->Bounds(),rView->Bounds()); rView->Flush(); rView->Sync(); bitmap->Unlock(); */ // fprintf(stderr, "<GlSpectrumAnalyzerWindow::Render()\n"); return B_OK; }
// ============================================================================== GlSpectrumAnalyzerWindow::GlSpectrumAnalyzerWindow(SoundPlayController *ctrl) : BDirectGLWindow( // BRect(200,100,199+640,99+480), // BRect(200,100,199+640,99+480), BRect( 100.0, 100.0, 739.0, 579.0 ), // 640x480 "OpenGL"B_UTF8_REGISTERED" Spectrum Analyzer", B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS/*|B_NOT_RESIZABLE|B_NOT_ZOOMABLE*/), name(NULL), xrot(10.0), yrot(35.0), zrot(0.0), needResize(false), opengl_device(BGL_DEVICE_SOFTWARE) { controller=ctrl; controller->AddWindow(this); // let SoundPlay handle some hotkeys for this window bView=new BView(Bounds(),"view",B_FOLLOW_ALL_SIDES, 0); bView->SetViewColor(0.0, 0.0, 0.0); bView->SetFontSize(20); AddChild(bView); for(int x=0;x<20;x++) { peak[x]=0; lastpeak[x]=0; peakdelay[x]=0; } // Add a shortcut so Alt-F will toggle fullscreen. AddShortcut( 'f', 0, new BMessage( GO_FULLSCREEN ) ); // Initialize OpenGL // // In theory you can also use single-buffering, s/DOUBLE/SINGLE/ in // these two. EnumerateDevices( BGL_MONITOR_PRIMARY, BGL_ANY | BGL_DOUBLE, BGL_ANY, BGL_NONE, BGL_NONE ); InitializeGL( opengl_device, BGL_ANY | BGL_DOUBLE, BGL_ANY, BGL_NONE, BGL_NONE ); keeprunning=true; // Magically, the window will now appear on-screen. Show(); Sync(); // <- should prevent the thread from racing the window //gInit MakeCurrent(); // Clear to black glClearColor( 0.0, 0.0, 0.0, 0.0 ); // Set up the depth buffer glClearDepth( 1.0 ); // The type of depth test glDepthFunc( GL_LEQUAL ); // glDepthFunc( GL_LESS ); // Enable depth testing glEnable( GL_DEPTH_TEST ); // Set up perspective view // Enable smooth shading glShadeModel( GL_SMOOTH ); // Really nice perspective calculations glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); // Back face is solid, front face is outlined glPolygonMode( GL_BACK, GL_FILL ); glPolygonMode( GL_FRONT, GL_LINE ); // glMatrixMode( GL_PROJECTION ); #if 0 float local_view[] = {0.0,0.0}; float position[] = {0.0, 3.0, 3.0, 0.0}; glLightfv(GL_LIGHT0, GL_POSITION, position); glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view); float white[3] = {1.0,1.0,1.0}; float dimWhite[3] = {0.25,0.25,0.25}; glEnable(GL_LIGHT0); glLightfv(GL_LIGHT0, GL_SPECULAR, dimWhite); glLightfv(GL_LIGHT0, GL_DIFFUSE,white); glLightfv(GL_LIGHT0, GL_AMBIENT,white); glFrontFace(GL_CW); glEnable(GL_LIGHTING); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); glMaterialf(GL_FRONT, GL_SHININESS, 0.6*128.0); glColor3f(1.0, 1.0, 1.0); glMatrixMode(GL_PROJECTION); #endif glLoadIdentity(); ReleaseCurrent(); FrameResized(float(Bounds().IntegerWidth() + 1), float(Bounds().IntegerHeight() + 1)); }