1 /*
2 * DISTRHO glBars Plugin based on XMMS/XBMC "GL Bars"
3 * Copyright (C) 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies
4 * Copyright (C) 2000 Christian Zander <phoenix@minion.de>
5 * Copyright (C) 2015 Nedko Arnaudov
6 * Copyright (C) 2016-2019 Filipe Coelho <falktx@falktx.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * For a full copy of the license see the LICENSE file.
18 */
19
20 #ifndef GLBARS_STATE_HPP_INCLUDED
21 #define GLBARS_STATE_HPP_INCLUDED
22
23 #include "OpenGL.hpp"
24
25 static inline
draw_rectangle(GLfloat x1,GLfloat y1,GLfloat z1,GLfloat x2,GLfloat y2,GLfloat z2)26 void draw_rectangle(GLfloat x1, GLfloat y1, GLfloat z1, GLfloat x2, GLfloat y2, GLfloat z2)
27 {
28 if (y1 == y2)
29 {
30 glVertex3f(x1, y1, z1);
31 glVertex3f(x2, y1, z1);
32 glVertex3f(x2, y2, z2);
33
34 glVertex3f(x2, y2, z2);
35 glVertex3f(x1, y2, z2);
36 glVertex3f(x1, y1, z1);
37 }
38 else
39 {
40 glVertex3f(x1, y1, z1);
41 glVertex3f(x2, y1, z2);
42 glVertex3f(x2, y2, z2);
43
44 glVertex3f(x2, y2, z2);
45 glVertex3f(x1, y2, z1);
46 glVertex3f(x1, y1, z1);
47 }
48 }
49
50 static inline
draw_bar(GLenum mode,GLfloat x_offset,GLfloat z_offset,GLfloat height,GLfloat red,GLfloat green,GLfloat blue)51 void draw_bar(GLenum mode, GLfloat x_offset, GLfloat z_offset, GLfloat height, GLfloat red, GLfloat green, GLfloat blue)
52 {
53 const GLfloat width = 0.1;
54
55 if (mode == GL_POINT)
56 glColor3f(0.2, 1.0, 0.2);
57
58 if (mode != GL_POINT)
59 {
60 glColor3f(red,green,blue);
61 draw_rectangle(x_offset, height, z_offset, x_offset + width, height, z_offset + 0.1);
62 }
63 draw_rectangle(x_offset, 0, z_offset, x_offset + width, 0, z_offset + 0.1);
64
65 if (mode != GL_POINT)
66 {
67 glColor3f(0.5 * red, 0.5 * green, 0.5 * blue);
68 draw_rectangle(x_offset, 0.0, z_offset + 0.1, x_offset + width, height, z_offset + 0.1);
69 }
70 draw_rectangle(x_offset, 0.0, z_offset, x_offset + width, height, z_offset );
71
72 if (mode != GL_POINT)
73 {
74 glColor3f(0.25 * red, 0.25 * green, 0.25 * blue);
75 draw_rectangle(x_offset, 0.0, z_offset , x_offset, height, z_offset + 0.1);
76 }
77 draw_rectangle(x_offset + width, 0.0, z_offset , x_offset + width, height, z_offset + 0.1);
78 }
79
80 struct glBarsState {
81 GLenum g_mode;
82 GLfloat x_angle, x_speed;
83 GLfloat y_angle, y_speed;
84 GLfloat z_angle, z_speed;
85 GLfloat heights[16][16], cHeights[16][16], scale;
86 GLfloat hSpeed;
87
glBarsStateglBarsState88 glBarsState()
89 {
90 g_mode = GL_FILL;
91 x_angle = 20.0;
92 x_speed = 0.0;
93 y_angle = 15.0; // was 45
94 y_speed = 0.5;
95 z_angle = 0.0;
96 z_speed = 0.0;
97
98 // Set "Bar Height"
99 scale = 1.f / log(256.f); // "Default" / standard
100 //scale = 2.f / log(256.f); // "Big"
101 //scale = 3.f / log(256.f); // "Very Big" / real big
102 //scale = 0.33f / log(256.f); // unused
103 //scale = 0.5f / log(256.f); // "Small"
104
105 // Set "Speed"
106 //hSpeed = 0.025f; // "Slow"
107 hSpeed = 0.0125f; // "Default"
108 //hSpeed = 0.1f; // "Fast"
109 //hSpeed = 0.2f; // "Very Fast"
110 //hSpeed = 0.05f; // "Very Slow"
111
112 for (int x = 0; x < 16; x++)
113 {
114 for (int y = 0; y < 16; y++)
115 cHeights[y][x] = heights[y][x] = 0;
116 }
117 }
118
drawBarsglBarsState119 void drawBars()
120 {
121 GLfloat x_offset, z_offset, r_base, b_base;
122
123 glClear(GL_DEPTH_BUFFER_BIT);
124 glPushMatrix();
125 glTranslatef(0.0,-0.5,-5.0);
126 glRotatef(x_angle,1.0,0.0,0.0);
127 glRotatef(y_angle,0.0,1.0,0.0);
128 glRotatef(z_angle,0.0,0.0,1.0);
129
130 glPolygonMode(GL_FRONT_AND_BACK, g_mode);
131 glBegin(GL_TRIANGLES);
132
133 for (int y = 0; y < 16; y++)
134 {
135 z_offset = -1.6 + ((15 - y) * 0.2);
136
137 b_base = y * (1.0 / 15);
138 r_base = 1.0 - b_base;
139
140 for (int x = 0; x < 16; x++)
141 {
142 x_offset = -1.6 + ((float)x * 0.2);
143 if (::fabs(cHeights[y][x]-heights[y][x])>hSpeed)
144 {
145 if (cHeights[y][x]<heights[y][x])
146 cHeights[y][x] += hSpeed;
147 else
148 cHeights[y][x] -= hSpeed;
149 }
150 draw_bar(g_mode, x_offset, z_offset,
151 cHeights[y][x], r_base - (float(x) * (r_base / 15.0)),
152 (float)x * (1.0 / 15), b_base /*, 16*y+x*/);
153 }
154 }
155
156 glEnd();
157 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
158 glPopMatrix();
159 }
160
RenderglBarsState161 void Render()
162 {
163 glDisable(GL_BLEND);
164 glMatrixMode(GL_PROJECTION);
165 glPushMatrix();
166 glLoadIdentity();
167 glFrustum(-1, 1, -1, 1, 1.5, 10);
168 glMatrixMode(GL_MODELVIEW);
169 glPushMatrix();
170 glLoadIdentity();
171 glEnable(GL_DEPTH_TEST);
172 glDepthFunc(GL_LESS);
173 glPolygonMode(GL_FRONT, GL_FILL);
174 //glPolygonMode(GL_BACK, GL_FILL);
175
176 x_angle += x_speed;
177 if (x_angle >= 360.0)
178 x_angle -= 360.0;
179
180 y_angle += y_speed;
181 if (y_angle >= 360.0)
182 y_angle -= 360.0;
183
184 z_angle += z_speed;
185 if (z_angle >= 360.0)
186 z_angle -= 360.0;
187
188 drawBars();
189
190 glPopMatrix();
191 glMatrixMode(GL_PROJECTION);
192 glPopMatrix();
193 glDisable(GL_DEPTH_TEST);
194 glEnable(GL_BLEND);
195 }
196
AudioDataglBarsState197 void AudioData(const float* pAudioData, int iAudioDataLength)
198 {
199 const int xscale[] = {0, 1, 2, 3, 5, 7, 10, 14, 20, 28, 40, 54, 74, 101, 137, 187, 255};
200
201 GLfloat val;
202
203 for (int y = 15; y > 0; y--)
204 {
205 for (int i = 0; i < 16; i++)
206 heights[y][i] = heights[y - 1][i];
207 }
208
209 for (int i = 0; i < 16; i++)
210 {
211 int y = 0;
212 for (int c = xscale[i]; c < xscale[i + 1]; c++)
213 {
214 if (c<iAudioDataLength)
215 {
216 if ((int)(pAudioData[c] * (INT16_MAX)) > y)
217 y = (int)(pAudioData[c] * (INT16_MAX));
218 }
219 else
220 {
221 continue;
222 }
223 }
224 y >>= 7;
225 if (y > 0)
226 val = (logf(y) * scale);
227 else
228 val = 0;
229 heights[0][i] = val;
230 }
231 }
232 };
233
234 #endif // GLBARS_STATE_HPP_INCLUDED
235