📄 main.c
字号:
/***************************************************************************** * main.c: ***************************************************************************** * Copyright (C) 2004 VideoLAN * $Id: main.c 10101 2005-03-02 16:47:31Z robux4 $ * * Authors: Cyril Deguet <asmax@videolan.org> * Adapted from projectM (http://xmms-projectm.sourceforge.net/) * * 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 "plugin.h"#include <GL/gl.h>#include <GL/glu.h>#include <unistd.h>#include <math.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include "common.h"#include "preset_types.h"#include "preset.h"#include "engine_vars.h"#include "per_pixel_eqn_types.h"#include "per_pixel_eqn.h"#include "interface_types.h"#include "video_init.h" //Video Init Routines, resizing/fullscreen, creating pbuffers#include "PCM.h" //Sound data handler (buffering, FFT, etc.)#include "beat_detect.h" //beat detection routines#include "custom_wave_types.h"#include "custom_wave.h"#include "custom_shape_types.h"#include "custom_shape.h"//#include <dmalloc.h>// Forward declarationsvoid read_cfg();void modulate_opacity_by_volume();void maximize_colors();void do_per_pixel_math();void do_per_frame();void render_interpolation();void render_texture_to_screen();void render_texture_to_studio();void draw_motion_vectors();void draw_borders();void draw_shapes();void draw_waveform();void draw_custom_waves();void reset_per_pixel_matrices();void init_per_pixel_matrices();void free_per_pixel_matrices();int noSwitch=0;int pcmframes=1;int freqframes=0;int totalframes=1;int studio=0;extern preset_t * active_preset;GLuint RenderTargetTextureID;double wave_o;//double gx=32; //size of interpolation//double gy=24;int texsize=512; //size of texture to do actual graphicsint vw=512; //runtime dimensionsint vh=512;int fullscreen=0;int maxsamples=2048; //size of PCM bufferint numsamples; //size of new PCM infodouble *pcmdataL; //holder for most recent pcm datadouble *pcmdataR; //holder for most recent pcm dataint avgtime=500; //# frames per presetchar *title = NULL;int drawtitle;int title_font;int other_font;int correction=1;double vol;//per pixel equation variablesdouble **gridx; //grid containing interpolated meshdouble **gridy;double **origtheta; //grid containing interpolated mesh reference valuesdouble **origrad;double **origx; //original meshdouble **origy;char *buffer; //XXXint galaktos_init( galaktos_thread_t *p_thread ){ init_per_pixel_matrices(); pcmdataL=(double *)malloc(maxsamples*sizeof(double)); pcmdataR=(double *)malloc(maxsamples*sizeof(double)); /* Preset loading function */ initPresetLoader(); /* Load default preset directory */// loadPresetDir("/home/cyril/.vlc/galaktos"); loadPresetDir("/etc/projectM/presets"); initPCM(maxsamples); initBeatDetect(); // mutex = SDL_CreateMutex(); return 0;}void galaktos_done( galaktos_thread_t *p_thread ){ free(pcmdataL); free(pcmdataR); freeBeatDetect(); freePCM(); free_per_pixel_matrices(); closePresetDir();// destroyPresetLoader(); XXX segfaults :(}int galaktos_update( galaktos_thread_t *p_thread ){ static int nohard=0; double vdataL[512]; //holders for FFT data (spectrum) double vdataR[512]; avgtime=fps*18; totalframes++; //total amount of frames since startup Time=(double)(mdate()/1000000); frame++; //number of frames for current preset progress= frame/(double)avgtime; if (progress>1.0) progress=1.0; // printf("start:%d at:%d min:%d stop:%d on:%d %d\n",startframe, frame frame-startframe,avgtime, noSwitch,progress); if (frame>avgtime) { if (noSwitch==0) switchPreset(RANDOM_NEXT,0); } evalInitConditions(); evalPerFrameEquations(); evalCustomWaveInitConditions(); evalCustomShapeInitConditions(); // printf("%f %d\n",Time,frame); reset_per_pixel_matrices(); numsamples = getPCMnew(pcmdataR,1,0,fWaveSmoothing,0,0); getPCMnew(pcmdataL,0,0,fWaveSmoothing,0,1); getPCM(vdataL,512,0,1,0,0); getPCM(vdataR,512,1,1,0,0); bass=0;mid=0;treb=0; getBeatVals(vdataL,vdataR,&vol); nohard--; if(vol>8.0 && nohard<0 && noSwitch==0) { switchPreset(RANDOM_NEXT, HARD_CUT); nohard=100; } //BEGIN PASS 1 // //This pass is used to render our texture //the texture is drawn to a subsection of the framebuffer //and then we perform our manipulations on it //in pass 2 we will copy the texture into texture memory // galaktos_glx_activate_pbuffer( p_thread ); glPushAttrib( GL_ALL_ATTRIB_BITS ); /* Overkill, but safe */ // if (RenderTarget) glViewport( 0, 0, RenderTarget->w, RenderTarget->h ); if (0) {} else glViewport( 0, 0, texsize, texsize ); glMatrixMode( GL_MODELVIEW ); glPushMatrix(); glLoadIdentity(); glMatrixMode( GL_PROJECTION ); glPushMatrix(); glLoadIdentity(); glOrtho(0.0, texsize, 0.0,texsize,10,40); do_per_pixel_math(); do_per_frame(); //apply per-frame effects render_interpolation(); //apply per-pixel effects draw_motion_vectors(); //draw motion vectors draw_borders(); //draw borders draw_waveform(); draw_shapes(); draw_custom_waves(); glMatrixMode( GL_MODELVIEW ); glPopMatrix(); glMatrixMode( GL_PROJECTION ); glPopMatrix(); glPopAttrib(); //if ( RenderTarget ) SDL_GL_UnlockRenderTarget(RenderTarget); /* Copy our rendering to the fake render target texture */ glBindTexture( GL_TEXTURE_2D, RenderTargetTextureID ); glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize);// galaktos_glx_activate_window( p_thread ); //BEGIN PASS 2 // //end of texture rendering //now we copy the texture from the framebuffer to //video texture memory and render fullscreen on a quad surface. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-vw*.5, vw*.5, -vh*.5,vh*.5,10,40); glLineWidth(texsize/512.0); if(studio%2)render_texture_to_studio(); else render_texture_to_screen(); glFinish(); glFlush(); // printf("Flush %d\n",(SDL_GetTicks()-timestart)); p_thread->p_opengl->pf_swap( p_thread->p_opengl ); /* Process events */ if( p_thread->p_opengl->pf_manage && p_thread->p_opengl->pf_manage( p_thread->p_opengl ) ) { return 1; } return 0;}void free_per_pixel_matrices(){ int x; for(x = 0; x < gx; x++) { free(gridx[x]); free(gridy[x]); free(origtheta[x]); free(origrad[x]); free(origx[x]); free(origy[x]); free(x_mesh[x]); free(y_mesh[x]); free(rad_mesh[x]); free(theta_mesh[x]); } free(origx); free(origy); free(gridx); free(gridy); free(x_mesh); free(y_mesh); free(rad_mesh); free(theta_mesh);}void init_per_pixel_matrices(){ int x,y; gridx=(double **)malloc(gx * sizeof(double *)); gridy=(double **)malloc(gx * sizeof(double *)); origx=(double **)malloc(gx * sizeof(double *)); origy=(double **)malloc(gx * sizeof(double *)); origrad=(double **)malloc(gx * sizeof(double *)); origtheta=(double **)malloc(gx * sizeof(double *)); x_mesh=(double **)malloc(gx * sizeof(double *)); y_mesh=(double **)malloc(gx * sizeof(double *)); rad_mesh=(double **)malloc(gx * sizeof(double *)); theta_mesh=(double **)malloc(gx * sizeof(double *)); sx_mesh=(double **)malloc(gx * sizeof(double *)); sy_mesh=(double **)malloc(gx * sizeof(double *)); dx_mesh=(double **)malloc(gx * sizeof(double *)); dy_mesh=(double **)malloc(gx * sizeof(double *)); cx_mesh=(double **)malloc(gx * sizeof(double *)); cy_mesh=(double **)malloc(gx * sizeof(double *)); zoom_mesh=(double **)malloc(gx * sizeof(double *)); zoomexp_mesh=(double **)malloc(gx * sizeof(double *)); rot_mesh=(double **)malloc(gx * sizeof(double *)); for(x = 0; x < gx; x++) { gridx[x] = (double *)malloc(gy * sizeof(double)); gridy[x] = (double *)malloc(gy * sizeof(double)); origtheta[x] = (double *)malloc(gy * sizeof(double)); origrad[x] = (double *)malloc(gy * sizeof(double)); origx[x] = (double *)malloc(gy * sizeof(double)); origy[x] = (double *)malloc(gy * sizeof(double)); x_mesh[x] = (double *)malloc(gy * sizeof(double)); y_mesh[x] = (double *)malloc(gy * sizeof(double)); rad_mesh[x] = (double *)malloc(gy * sizeof(double)); theta_mesh[x] = (double *)malloc(gy * sizeof(double)); sx_mesh[x] = (double *)malloc(gy * sizeof(double)); sy_mesh[x] = (double *)malloc(gy * sizeof(double)); dx_mesh[x] = (double *)malloc(gy * sizeof(double)); dy_mesh[x] = (double *)malloc(gy * sizeof(double)); cx_mesh[x] = (double *)malloc(gy * sizeof(double)); cy_mesh[x] = (double *)malloc(gy * sizeof(double)); zoom_mesh[x] = (double *)malloc(gy * sizeof(double)); zoomexp_mesh[x] = (double *)malloc(gy * sizeof(double)); rot_mesh[x] = (double *)malloc(gy * sizeof(double)); } //initialize reference grid values for (x=0;x<gx;x++) { for(y=0;y<gy;y++) { origx[x][y]=x/(double)(gx-1); origy[x][y]=-((y/(double)(gy-1))-1); origrad[x][y]=hypot((origx[x][y]-.5)*2,(origy[x][y]-.5)*2) * .7071067; origtheta[x][y]=atan2(((origy[x][y]-.5)*2),((origx[x][y]-.5)*2)); gridx[x][y]=origx[x][y]*texsize; gridy[x][y]=origy[x][y]*texsize; } }}//calculate matrices for per_pixelvoid do_per_pixel_math(){ int x,y; double rotx=0,roty=0; evalPerPixelEqns(); if(!isPerPixelEqn(CX_OP)) { for (x=0;x<gx;x++) { for(y=0;y<gy;y++){ cx_mesh[x][y]=cx; } } } if(!isPerPixelEqn(CY_OP)) { for (x=0;x<gx;x++) { for(y=0;y<gy;y++) { cy_mesh[x][y]=cy; } } } if(isPerPixelEqn(ROT_OP)) { for (x=0;x<gx;x++) { for(y=0;y<gy;y++) { x_mesh[x][y]=x_mesh[x][y]-cx_mesh[x][y]; y_mesh[x][y]=y_mesh[x][y]-cy_mesh[x][y]; rotx=(x_mesh[x][y])*cos(rot_mesh[x][y])-(y_mesh[x][y])*sin(rot_mesh[x][y]); roty=(x_mesh[x][y])*sin(rot_mesh[x][y])+(y_mesh[x][y])*cos(rot_mesh[x][y]); x_mesh[x][y]=rotx+cx_mesh[x][y]; y_mesh[x][y]=roty+cy_mesh[x][y]; } } } if(!isPerPixelEqn(ZOOM_OP)) { for (x=0;x<gx;x++) { for(y=0;y<gy;y++) { zoom_mesh[x][y]=zoom; } } } if(!isPerPixelEqn(ZOOMEXP_OP)) { for (x=0;x<gx;x++) { for(y=0;y<gy;y++) { zoomexp_mesh[x][y]=zoomexp; } } } //DO ZOOM PER PIXEL for (x=0;x<gx;x++) { for(y=0;y<gy;y++) { x_mesh[x][y]=(x_mesh[x][y]-.5)*2; y_mesh[x][y]=(y_mesh[x][y]-.5)*2; x_mesh[x][y]=x_mesh[x][y]/(((zoom_mesh[x][y]-1)*(pow(rad_mesh[x][y],zoomexp_mesh[x][y])/rad_mesh[x][y]))+1); y_mesh[x][y]=y_mesh[x][y]/(((zoom_mesh[x][y]-1)*(pow(rad_mesh[x][y],zoomexp_mesh[x][y])/rad_mesh[x][y]))+1); x_mesh[x][y]=(x_mesh[x][y]*.5)+.5; y_mesh[x][y]=(y_mesh[x][y]*.5)+.5; } } if(isPerPixelEqn(SX_OP)) { for (x=0;x<gx;x++) { for(y=0;y<gy;y++) { x_mesh[x][y]=((x_mesh[x][y]-cx_mesh[x][y])/sx_mesh[x][y])+cx_mesh[x][y]; } } } if(isPerPixelEqn(SY_OP)) { for (x=0;x<gx;x++) { for(y=0;y<gy;y++) { y_mesh[x][y]=((y_mesh[x][y]-cy_mesh[x][y])/sy_mesh[x][y])+cy_mesh[x][y]; } } } if(isPerPixelEqn(DX_OP)) { for (x=0;x<gx;x++) { for(y=0;y<gy;y++) { x_mesh[x][y]=x_mesh[x][y]-dx_mesh[x][y]; } } } if(isPerPixelEqn(DY_OP)) { for (x=0;x<gx;x++) { for(y=0;y<gy;y++) { y_mesh[x][y]=y_mesh[x][y]-dy_mesh[x][y]; } } }}void reset_per_pixel_matrices(){ int x,y; for (x=0;x<gx;x++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -