⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 opengl_spectrum.c

📁 xmms-1.2.10.tar.gz学习使用的就下吧
💻 C
字号:
/*  XMMS - Cross-platform multimedia player *  Copyright (C) 1998-2000  Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies * *  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-1307, USA. *//* *  Wed May 24 10:49:37 CDT 2000 *  Fixes to threading/context creation for the nVidia X4 drivers by  *  Christian Zander <phoenix@minion.de> */#include "config.h"#include <X11/Xlib.h>#include <X11/keysym.h>#include <gtk/gtk.h>#include <math.h>#include <GL/gl.h>#include <GL/glx.h>#include <pthread.h>#ifdef HAVE_SCHED_SETSCHEDULER#include <sched.h>#endif#include <stdlib.h>#include "xmms/plugin.h"#include "libxmms/xmmsctrl.h"#include "libxmms/configfile.h"#include "libxmms/util.h"#include "opengl_spectrum.h"#include "xmms/i18n.h"#define NUM_BANDS 16OGLSpectrumConfig oglspectrum_cfg;static Display *dpy = NULL;static Colormap colormap = 0;static GLXContext glxcontext = NULL;static Window window = 0;static GLfloat y_angle = 45.0, y_speed = 0.5;static GLfloat x_angle = 20.0, x_speed = 0.0;static GLfloat z_angle = 0.0, z_speed = 0.0;static GLfloat heights[16][16], scale;static gboolean going = FALSE, grabbed_pointer = FALSE;static Atom wm_delete_window_atom;static pthread_t draw_thread;static void oglspectrum_init(void);static void oglspectrum_cleanup(void);static void oglspectrum_playback_start(void);static void oglspectrum_playback_stop(void);static void oglspectrum_render_freq(gint16 data[2][256]);VisPlugin oglspectrum_vp ={	NULL,	NULL,	0,	NULL, /* Description */	0,	1,			oglspectrum_init, /* init */	oglspectrum_cleanup, /* cleanup */	NULL, /* about */	oglspectrum_configure, /* configure */	NULL, /* disable_plugin */	oglspectrum_playback_start, /* playback_start */	oglspectrum_playback_stop, /* playback_stop */	NULL, /* render_pcm */	oglspectrum_render_freq  /* render_freq */};static Window create_window(int width, int height){	int attr_list[] = {		GLX_RGBA,		GLX_DEPTH_SIZE, 16,		GLX_DOUBLEBUFFER,		None	};	int scrnum;	XSetWindowAttributes attr;	unsigned long mask;	Window root, win;	XVisualInfo *visinfo;	Atom wm_protocols[1];	if ((dpy = XOpenDisplay(NULL)) == NULL)		return 0;	scrnum = DefaultScreen(dpy);	root = RootWindow(dpy, scrnum);	if ((visinfo = glXChooseVisual(dpy, scrnum, attr_list)) == NULL)		return 0;	attr.background_pixel = 0;	attr.border_pixel = 0;	attr.colormap = colormap = XCreateColormap(dpy, root,						   visinfo->visual, AllocNone);	attr.event_mask = StructureNotifyMask | KeyPressMask;	mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;	win = XCreateWindow(dpy, root, 0, 0, width, height,			    0, visinfo->depth, InputOutput,			    visinfo->visual, mask, &attr);	XmbSetWMProperties(dpy, win, _("OpenGL Spectrum analyzer"),			   _("OpenGL Spectrum analyzer"), NULL, 0, NULL, NULL,			   NULL);	wm_delete_window_atom = wm_protocols[0] =		XInternAtom(dpy, "WM_DELETE_WINDOW", False);	XSetWMProtocols(dpy, win, wm_protocols, 1);	glxcontext = glXCreateContext(dpy, visinfo, NULL, True);	XFree(visinfo);	glXMakeCurrent(dpy, win, glxcontext);	return win;}VisPlugin *get_vplugin_info(void){	oglspectrum_vp.description =		g_strdup_printf(_("OpenGL Spectrum analyzer %s"), VERSION);	return &oglspectrum_vp;}void oglspectrum_read_config(void){	ConfigFile *cfg;		gchar *filename;	oglspectrum_cfg.tdfx_mode = FALSE;		filename = g_strconcat(g_get_home_dir(), "/.xmms/config", NULL);	cfg = xmms_cfg_open_file(filename);		if (cfg)	{		xmms_cfg_read_boolean(cfg, "OpenGL Spectrum", "tdfx_fullscreen", &oglspectrum_cfg.tdfx_mode);				xmms_cfg_free(cfg);	}	g_free(filename);}static void draw_rectangle(GLfloat x1, GLfloat y1, GLfloat z1, GLfloat x2, GLfloat y2, GLfloat z2){	if(y1 == y2)	{			glVertex3f(x1, y1, z1);		glVertex3f(x2, y1, z1);		glVertex3f(x2, y2, z2);				glVertex3f(x2, y2, z2);		glVertex3f(x1, y2, z2);		glVertex3f(x1, y1, z1);	}	else	{		glVertex3f(x1, y1, z1);		glVertex3f(x2, y1, z2);		glVertex3f(x2, y2, z2);				glVertex3f(x2, y2, z2);		glVertex3f(x1, y2, z1);		glVertex3f(x1, y1, z1);	}}static void draw_bar(GLfloat x_offset, GLfloat z_offset, GLfloat height, GLfloat red, GLfloat green, GLfloat blue ){	GLfloat width = 0.1;	glColor3f(red,green,blue);	draw_rectangle(x_offset, height, z_offset, x_offset + width, height, z_offset + 0.1);	draw_rectangle(x_offset, 0, z_offset, x_offset + width, 0, z_offset + 0.1);		glColor3f(0.5 * red, 0.5 * green, 0.5 * blue);	draw_rectangle(x_offset, 0.0, z_offset + 0.1, x_offset + width, height, z_offset + 0.1);	draw_rectangle(x_offset, 0.0, z_offset, x_offset + width, height, z_offset );	glColor3f(0.25 * red, 0.25 * green, 0.25 * blue);	draw_rectangle(x_offset, 0.0, z_offset , x_offset, height, z_offset + 0.1);		draw_rectangle(x_offset + width, 0.0, z_offset , x_offset + width, height, z_offset + 0.1);	}static void draw_bars(void){	gint x,y;	GLfloat x_offset, z_offset, r_base, b_base;		glClearColor(0,0,0,0);	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	glPushMatrix();	glTranslatef(0.0,-0.5,-5.0);	      	glRotatef(x_angle,1.0,0.0,0.0);	glRotatef(y_angle,0.0,1.0,0.0);	glRotatef(z_angle,0.0,0.0,1.0);	glBegin(GL_TRIANGLES);	for(y = 0; y < 16; y++)	{		z_offset = -1.6 + ((15 - y) * 0.2);		b_base = y * (1.0 / 15);		r_base = 1.0 - b_base;					for(x = 0; x < 16; x++)		{			x_offset = -1.6 + (x * 0.2);										draw_bar(x_offset, z_offset, heights[y][x], r_base - (x * (r_base / 15.0)), x * (1.0 / 15), b_base);		}	}	glEnd();	glPopMatrix();	glXSwapBuffers(dpy,window);}static gint disable_func(gpointer data){	oglspectrum_vp.disable_plugin(&oglspectrum_vp);	return FALSE;}void *draw_thread_func(void *arg){	Bool configured = FALSE;	if ((window = create_window(640, 480)) == 0)	{		g_log(NULL, G_LOG_LEVEL_CRITICAL, __FILE__ ": unable to create window");		pthread_exit(NULL);	}		XMapWindow(dpy, window);	glMatrixMode(GL_PROJECTION);	glLoadIdentity();	glFrustum(-1, 1, -1, 1, 1.5, 10);	glMatrixMode(GL_MODELVIEW);	glLoadIdentity();	glEnable(GL_DEPTH_TEST);	glDepthFunc(GL_LESS);#ifdef HAVE_SCHED_SETSCHEDULER	if(xmms_check_realtime_priority())	{		struct sched_param sparam;		sparam.sched_priority = sched_get_priority_max(SCHED_OTHER);		pthread_setschedparam(pthread_self(), SCHED_OTHER, &sparam);			}#endif		while(going)	{		while(XPending(dpy))		{			XEvent event;			KeySym keysym;			char buf[16];						XNextEvent(dpy, &event);			switch(event.type)			{			case ConfigureNotify:				glViewport(0,0,event.xconfigure.width, event.xconfigure.height);				if(oglspectrum_cfg.tdfx_mode && !grabbed_pointer)				{										XGrabPointer(dpy, window,						     True, ButtonPressMask,						     GrabModeAsync,						     GrabModeAsync,						     window, None, CurrentTime);					grabbed_pointer = TRUE;				}				configured = TRUE;				break;			case KeyPress:								XLookupString (&event.xkey, buf, 16, &keysym, NULL);				switch(keysym)				{				case XK_Escape:										/* Ugly hack to get the disable_plugin call in the main thread. */					GDK_THREADS_ENTER();					gtk_idle_add(disable_func, NULL);					GDK_THREADS_LEAVE();					break;				case XK_z:					xmms_remote_playlist_prev(oglspectrum_vp.xmms_session);					break;				case XK_x:					xmms_remote_play(oglspectrum_vp.xmms_session);					break;				case XK_c:					xmms_remote_pause(oglspectrum_vp.xmms_session);					break;				case XK_v:					xmms_remote_stop(oglspectrum_vp.xmms_session);					break;				case XK_b:					xmms_remote_playlist_next(oglspectrum_vp.xmms_session);					break;				case XK_Up:										x_speed -= 0.1;					if(x_speed < -3.0)						x_speed = -3.0;					break;				case XK_Down:										x_speed += 0.1;					if(x_speed > 3.0)						x_speed = 3.0;					break;				case XK_Left:					y_speed -= 0.1;					if(y_speed < -3.0)						y_speed = -3.0;										break;				case XK_Right:					y_speed += 0.1;					if(y_speed > 3.0)						y_speed = 3.0;					break;				case XK_w:					z_speed -= 0.1;					if(z_speed < -3.0)						z_speed = -3.0;					break;				case XK_q:					z_speed += 0.1;					if(z_speed > 3.0)						z_speed = 3.0;					break;				case XK_Return:					x_speed = 0.0;					y_speed = 0.5;					z_speed = 0.0;					x_angle = 20.0;					y_angle = 45.0;					z_angle = 0.0;					break;									}								break;			case ClientMessage:				if ((Atom)event.xclient.data.l[0] == wm_delete_window_atom)				{					GDK_THREADS_ENTER();					gtk_idle_add(disable_func, NULL);					GDK_THREADS_LEAVE();				}				break;			}		}		if(configured)		{			x_angle += x_speed;			if(x_angle >= 360.0)				x_angle -= 360.0;						y_angle += y_speed;			if(y_angle >= 360.0)				y_angle -= 360.0;			z_angle += z_speed;			if(z_angle >= 360.0)				z_angle -= 360.0;			draw_bars();		}	}	if (glxcontext)	{		glXMakeCurrent(dpy, 0, NULL);		glXDestroyContext(dpy, glxcontext);		glxcontext = NULL;	}	if (window)	{		if (grabbed_pointer)		{			XUngrabPointer(dpy, CurrentTime);			grabbed_pointer = FALSE;		}		XDestroyWindow(dpy, window);		window = 0;	}	pthread_exit(NULL);}static void start_display(void){	int x, y;	if(oglspectrum_cfg.tdfx_mode)		putenv("MESA_GLX_FX=fullscreen");	else		putenv("MESA_GLX_FX=""");		for(x = 0; x < 16; x++)	{		for(y = 0; y < 16; y++)		{			heights[y][x] = 0.0;		}	}	scale = 1.0 / log(256.0);	x_speed = 0.0;	y_speed = 0.5;	z_speed = 0.0;	x_angle = 20.0;	y_angle = 45.0;	z_angle = 0.0;	going = TRUE;	pthread_create(&draw_thread, NULL, draw_thread_func, NULL);}static void stop_display(void){	if (going)	{		going = FALSE;		pthread_join(draw_thread, NULL);	}	if (colormap)	{		XFreeColormap(dpy, colormap);		colormap = 0;	}	if (dpy)	{		XCloseDisplay(dpy);		dpy = NULL;	}}static void oglspectrum_init(void){	if (dpy) return;	oglspectrum_read_config();	if(!oglspectrum_cfg.tdfx_mode)		start_display();}	static void oglspectrum_cleanup(void){	stop_display();}static void oglspectrum_playback_start(void){	if(oglspectrum_cfg.tdfx_mode)	{		if(window)			stop_display();		start_display();	}}static void oglspectrum_playback_stop(void){	if(oglspectrum_cfg.tdfx_mode)	{		stop_display();	}}static void oglspectrum_render_freq(gint16 data[2][256]){	gint i,c;	gint y;	GLfloat val;	gint xscale[] = {0, 1, 2, 3, 5, 7, 10, 14, 20, 28, 40, 54, 74, 101, 137, 187, 255};	for(y = 15; y > 0; y--)	{		for(i = 0; i < 16; i++)		{			heights[y][i] = heights[y - 1][i];		}	}		for(i = 0; i < NUM_BANDS; i++)	{		for(c = xscale[i], y = 0; c < xscale[i + 1]; c++)		{			if(data[0][c] > y)				y = data[0][c];		}		y >>= 7;		if(y > 0)			val = (log(y) * scale);		else			val = 0;						heights[0][i] = val;   			}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -