/* * DISTRHO glBars Plugin based on XMMS/XBMC "GL Bars" * Copyright (C) 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies * Copyright (C) 2000 Christian Zander * Copyright (C) 2015 Nedko Arnaudov * Copyright (C) 2016 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation. * * 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 Lesser General Public License for more details. * * For a full copy of the license see the LICENSE file. */ #ifndef GLBARS_STATE_HPP_INCLUDED #define GLBARS_STATE_HPP_INCLUDED #include "Base.hpp" static inline 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 inline void draw_bar(GLenum mode, GLfloat x_offset, GLfloat z_offset, GLfloat height, GLfloat red, GLfloat green, GLfloat blue) { const GLfloat width = 0.1; if (mode == GL_POINT) glColor3f(0.2, 1.0, 0.2); if (mode != GL_POINT) { 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); if (mode != GL_POINT) { 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 ); if (mode != GL_POINT) { 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); } struct glBarsState { GLenum g_mode; GLfloat x_angle, x_speed; GLfloat y_angle, y_speed; GLfloat z_angle, z_speed; GLfloat heights[16][16], cHeights[16][16], scale; GLfloat hSpeed; glBarsState() { g_mode = GL_FILL; x_angle = 20.0; x_speed = 0.0; y_angle = 15.0; // was 45 y_speed = 0.5; z_angle = 0.0; z_speed = 0.0; // Set "Bar Height" scale = 1.f / log(256.f); // "Default" / standard //scale = 2.f / log(256.f); // "Big" //scale = 3.f / log(256.f); // "Very Big" / real big //scale = 0.33f / log(256.f); // unused //scale = 0.5f / log(256.f); // "Small" // Set "Speed" //hSpeed = 0.025f; // "Slow" hSpeed = 0.0125f; // "Default" //hSpeed = 0.1f; // "Fast" //hSpeed = 0.2f; // "Very Fast" //hSpeed = 0.05f; // "Very Slow" for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) cHeights[y][x] = heights[y][x] = 0; } } void drawBars() { GLfloat x_offset, z_offset, r_base, b_base; glClear(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); glPolygonMode(GL_FRONT_AND_BACK, g_mode); glBegin(GL_TRIANGLES); for (int 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 (int x = 0; x < 16; x++) { x_offset = -1.6 + ((float)x * 0.2); if (::fabs(cHeights[y][x]-heights[y][x])>hSpeed) { if (cHeights[y][x]= 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; drawBars(); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); } void AudioData(const float* pAudioData, int iAudioDataLength) { const int xscale[] = {0, 1, 2, 3, 5, 7, 10, 14, 20, 28, 40, 54, 74, 101, 137, 187, 255}; GLfloat val; for (int y = 15; y > 0; y--) { for (int i = 0; i < 16; i++) heights[y][i] = heights[y - 1][i]; } for (int i = 0; i < 16; i++) { int y = 0; for (int c = xscale[i]; c < xscale[i + 1]; c++) { if (c y) y = (int)(pAudioData[c] * (INT16_MAX)); } else { continue; } } y >>= 7; if (y > 0) val = (logf(y) * scale); else val = 0; heights[0][i] = val; } } }; #endif // GLBARS_STATE_HPP_INCLUDED