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;
}
Example #2
0
File: glx.c Project: 0xheart0/vlc
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));
}