├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── screenshots
├── 1-1.png
├── 1-2.png
├── 2-1.png
├── 2-2.png
├── 3-1.png
├── 3-2.png
├── 4-1.png
└── 4-2.png
├── shaders
├── FragmentShader.frag
├── GeometryShader.geom
└── VertexShader.vert
└── source
├── audio_data
├── audio_data.cpp
└── audio_data.hpp
├── common
├── controls.cpp
├── controls.hpp
├── load_shaders.cpp
├── load_shaders.hpp
├── objloader.cpp
├── objloader.hpp
├── quaternion_utils.cpp
├── quaternion_utils.hpp
├── shader.cpp
├── shader.hpp
├── tangentspace.cpp
├── tangentspace.hpp
├── text2D.cpp
├── text2D.hpp
├── texture.cpp
├── texture.hpp
├── vboindexer.cpp
└── vboindexer.hpp
├── fft
├── fft.cpp
└── fft.hpp
├── play_wav
├── play_wav.cpp
└── play_wav.hpp
└── waveform.cpp
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Object files
2 | *.slo
3 | *.lo
4 | *.o
5 | *.obj
6 |
7 | # Precompiled Headers
8 | *.gch
9 | *.pch
10 |
11 | # Compiled Dynamic libraries
12 | *.so
13 | *.dylib
14 | *.dll
15 |
16 | # Fortran module files
17 | *.mod
18 |
19 | # Compiled Static libraries
20 | *.lai
21 | *.la
22 | *.a
23 | *.lib
24 |
25 | # Executables
26 | *.exe
27 | *.out
28 | *.app
29 |
30 | # Directory
31 | build/
32 |
33 | # Target
34 | waveform
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 | {description}
294 | Copyright (C) {year} {fullname}
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | {signature of Ty Coon}, 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
341 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | GLFW = `pkg-config --cflags glfw3` `pkg-config --libs --static glfw3`
2 | GLEW = `pkg-config --cflags glew` `pkg-config --libs glew`
3 | LIBRARY = -lasound -lpthread
4 | INCLUDE = -I$(SOURCE_PATH) -I/usr/local/include/GLFW/
5 | MACRO = -D_REENTRANT
6 |
7 | BINARY = waveform
8 | SOURCE_PATH = source/
9 | BUILD_PATH = ./
10 | HPP = \
11 | $(SOURCE_PATH)common/shader.hpp \
12 | $(SOURCE_PATH)common/objloader.hpp \
13 | $(SOURCE_PATH)common/controls.hpp \
14 | $(SOURCE_PATH)audio_data/audio_data.hpp \
15 | $(SOURCE_PATH)play_wav/play_wav.hpp \
16 | $(SOURCE_PATH)fft/fft.hpp
17 | CPP = \
18 | $(SOURCE_PATH)common/shader.cpp \
19 | $(SOURCE_PATH)common/objloader.cpp \
20 | $(SOURCE_PATH)common/controls.cpp \
21 | $(SOURCE_PATH)audio_data/audio_data.cpp \
22 | $(SOURCE_PATH)play_wav/play_wav.cpp \
23 | $(SOURCE_PATH)waveform.cpp \
24 | $(SOURCE_PATH)fft/fft.cpp
25 |
26 | TARGET = $(BUILD_PATH)$(BINARY)
27 |
28 | all: $(TARGET)
29 |
30 | $(TARGET): $(CPP) $(HPP)
31 | clang++ $(CPP) -o $(TARGET) $(GLFW) $(GLEW) $(LIBRARY) $(INCLUDE) $(MACRO)
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Audio-Visualization---Waveform
2 |
3 | An audio visualizer.
4 |
5 | Repository: [Audio-Visualization---Waveform](https://github.com/chaosink/Audio-Visualization---Waveform)
6 |
7 | `WAV(16 bits, 2 channels)` files supported only for now.
8 |
9 | Visualized by `GLSL`.
10 |
11 | Video on Youtube:
12 | * [Audio-Visualization---Waveform, Spectrum, Level](https://youtu.be/7LfaSCFfXek)
13 | * [Audio-Visualization---Waveform, Spectrum, Sine](http://youtu.be/M1vgzOlViHw)
14 | * [Audio-Viusalization---Columned-Spectrum](https://youtu.be/Oxa4EXfW8GY)
15 | * [Audio-Visualization---Dot-Circle-Spectrum](https://youtu.be/zAzh2CJGibc)
16 |
17 | Video on Youku:
18 | * [Audio-Visualization---Waveform, Spectrum, Level](http://v.youku.com/v_show/id_XMTI5MjcxMDQwMA==.html)
19 | * [Audio-Visualization---Waveform, Spectrum, Sine](http://v.youku.com/v_show/id_XMTI5Mjc5MDg2NA==.html)
20 | * [Audio-Viusalization---Columned-Spectrumm](http://v.youku.com/v_show/id_XMTI5Mjg0MDkxNg==.html)
21 | * [Audio-Visualization---Dot-Circle-Spectrum](http://v.youku.com/v_show/id_XMTI5Mjg2Mjc2MA==.html)
22 |
23 | ## Compiling
24 | ```shell
25 | make
26 | ```
27 |
28 | ## Usage
29 | ```shell
30 | ./waveform your_wav.wav
31 | ```
32 |
33 | ## Dependencies
34 | [OpenGL - The Industry's Foundation for High Performance Graphics](https://www.opengl.org/)
35 |
36 | [GLFW - An OpenGL library](http://www.glfw.org/)
37 |
38 | [GLEW - The OpenGL Extension Wrangler Library](http://glew.sourceforge.net/)
39 |
40 | [GLM - OpenGL Mathematics](http://glm.g-truc.net/0.9.6/index.html)
41 |
42 | [ALSA - Advanced Linux Sound Architecture](http://www.alsa-project.org/main/index.php/Main_Page)
43 |
44 | ## Screenshots
45 | Spectrum, waveform, level
46 | 
47 |
48 | 
49 |
50 | Spectrum, waveform, sine
51 | 
52 |
53 | 
54 |
55 | Spectrum-circle
56 | 
57 |
58 | 
59 |
60 | Spectrum-column
61 | 
62 |
63 | 
64 |
--------------------------------------------------------------------------------
/screenshots/1-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chaosink/Audio-Visualization---Waveform/b7a87786abd91551ebdca9c3f3ef2d385c6a2479/screenshots/1-1.png
--------------------------------------------------------------------------------
/screenshots/1-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chaosink/Audio-Visualization---Waveform/b7a87786abd91551ebdca9c3f3ef2d385c6a2479/screenshots/1-2.png
--------------------------------------------------------------------------------
/screenshots/2-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chaosink/Audio-Visualization---Waveform/b7a87786abd91551ebdca9c3f3ef2d385c6a2479/screenshots/2-1.png
--------------------------------------------------------------------------------
/screenshots/2-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chaosink/Audio-Visualization---Waveform/b7a87786abd91551ebdca9c3f3ef2d385c6a2479/screenshots/2-2.png
--------------------------------------------------------------------------------
/screenshots/3-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chaosink/Audio-Visualization---Waveform/b7a87786abd91551ebdca9c3f3ef2d385c6a2479/screenshots/3-1.png
--------------------------------------------------------------------------------
/screenshots/3-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chaosink/Audio-Visualization---Waveform/b7a87786abd91551ebdca9c3f3ef2d385c6a2479/screenshots/3-2.png
--------------------------------------------------------------------------------
/screenshots/4-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chaosink/Audio-Visualization---Waveform/b7a87786abd91551ebdca9c3f3ef2d385c6a2479/screenshots/4-1.png
--------------------------------------------------------------------------------
/screenshots/4-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chaosink/Audio-Visualization---Waveform/b7a87786abd91551ebdca9c3f3ef2d385c6a2479/screenshots/4-2.png
--------------------------------------------------------------------------------
/shaders/FragmentShader.frag:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 fragmentColor;
4 |
5 | out vec3 color;
6 |
7 | void main() {
8 | color = fragmentColor;
9 | }
10 |
--------------------------------------------------------------------------------
/shaders/GeometryShader.geom:
--------------------------------------------------------------------------------
1 | #version 330
2 |
3 | //layout(lines) in;
4 | //layout(line_strip, max_vertices = 2) out;
5 | layout(triangles) in;
6 | layout(triangle_strip, max_vertices = 300) out;
7 |
8 | uniform mat4 MVP;
9 |
10 | in vec3 fragmentColor[];
11 | out vec3 Color;
12 |
13 | float size = 4.0;
14 | int num = 5;
15 |
16 | void main() {
17 | for(int k = -5; k < num; k++)
18 | for(int j = -5; j < num; j++) {
19 | for(int i = 0; i < gl_in.length(); ++i) {
20 | gl_Position = gl_in[i].gl_Position + vec4( size * j + size / 2, size * k + size / 2, 0.0, 0.0);
21 | Color = fragmentColor[i];
22 | EmitVertex();
23 | }
24 | EndPrimitive();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/shaders/VertexShader.vert:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | layout(location = 0) in vec3 vertexPosition_modelspace;
4 | layout(location = 1) in vec3 vertexColor;
5 | layout(location = 2) in float z;
6 |
7 | out vec3 fragmentColor;
8 |
9 | uniform mat4 MVP;
10 | uniform int object;
11 | uniform float top;
12 |
13 | int color_factor = 4;
14 | float size_factor = 0.01;
15 | float size_factor1 = 0.1;
16 | int wave_height = 5;
17 |
18 | bool zhuangbi = true;
19 | #define ZHUANGBI
20 |
21 | void main() {
22 | mat4 scale = mat4(
23 | size_factor, 0.0, 0.0, 0.0,
24 | 0.0, 1.0, 0.0, 0.0,
25 | 0.0, 0.0, size_factor, 0.0,
26 | 0.0, 0.0, 0.0, 1.0);
27 | mat4 scale1 = mat4(
28 | size_factor1, 0.0, 0.0, 0.0,
29 | 0.0, 1.0, 0.0, 0.0,
30 | 0.0, 0.0, size_factor1, 0.0,
31 | 0.0, 0.0, 0.0, 1.0);
32 | switch(object) {
33 | #ifdef ZHUANGBI
34 | case 0: //left column
35 | gl_Position = MVP * scale * vec4(vertexPosition_modelspace, 1);
36 | break;
37 | case 1: //right column
38 | gl_Position = MVP * scale * vec4(vertexPosition_modelspace, 1);
39 | break;
40 | #endif
41 | case 2: //left wave
42 | gl_Position = MVP * vec4(-5.0, vertexPosition_modelspace.x / 32768 * wave_height, z, 1);
43 | break;
44 | case 3: //right wave
45 | gl_Position = MVP * vec4( 5.0, vertexPosition_modelspace.x / 32768 * wave_height, z, 1);
46 | break;
47 | case 4: //left top
48 | gl_Position = MVP * vec4(vertexPosition_modelspace, 1);
49 | break;
50 | case 5: //right top
51 | gl_Position = MVP * vec4(vertexPosition_modelspace, 1);
52 | break;
53 | case 6: //spectrum
54 | gl_Position = MVP * vec4(0, vertexPosition_modelspace.x, z, 1);
55 | break;
56 | default:
57 | gl_Position = MVP * vec4(vertexPosition_modelspace, 1);
58 | break;
59 | }
60 |
61 | switch(object) {
62 | case 0: //left column
63 | fragmentColor = zhuangbi ? vec3(1.0, gl_Position.y / color_factor, gl_Position.y / color_factor) : vertexColor;
64 | break;
65 | case 1: //right column
66 | fragmentColor = zhuangbi ? vec3(gl_Position.y / color_factor, gl_Position.y / color_factor, 1.0) : vertexColor;
67 | break;
68 | case 2: //left wave
69 | fragmentColor = zhuangbi ? vec3(vertexPosition_modelspace.x / 32768 * 0.8 + 0.2, (z + 10.0) / 20.0, 0.5) : vec3(1.0, 0.5, 0.5);
70 | break;
71 | case 3: //right wave
72 | fragmentColor = zhuangbi ? vec3(0.5, (z + 10.0) / 20.0, vertexPosition_modelspace.x / 32768 * 0.8 + 0.2) : vec3(0.5, 0.5, 1.0);
73 | break;
74 | case 4: //left top (1.0 - pow(gl_Position.w, 2) / color_factor) * 0.7 + 0.3
75 | fragmentColor = vec3(1.0, top / 2, top / 2);
76 | break;
77 | case 5: //right top
78 | fragmentColor = vec3(top / 2, top / 2, 1.0);
79 | break;
80 | case 6: //spectrum log(vertexPosition_modelspace.x + 1) / 3 * 0.8 + 0.2
81 | fragmentColor = vec3(abs(z) / 10.0, (z + 10.0)/ 20.0, (log(vertexPosition_modelspace.x + 1) / 3 * 0.8) * (z + 10) / 5 + 0.2);
82 | break;
83 | default:
84 | fragmentColor = vec3(1.0, 1.0, 1.0);
85 | break;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/source/audio_data/audio_data.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "audio_data.hpp"
4 |
5 | struct WAV_HEADER
6 | {
7 | char rld[4]; //riff 标志符号
8 | int rLen;
9 | char wld[4]; //格式类型(wave)
10 | char fld[4]; //"fmt"
11 | int fLen; //sizeof(wave format matex)
12 | short wFormatTag; //编码格式
13 | short wChannels; //声道数
14 | int nSamplesPersec ; //采样频率
15 | int nAvgBitsPerSample;//WAVE文件采样大小
16 | short wBlockAlign; //块对齐
17 | short wBitsPerSample; //WAVE文件采样大小
18 | char dld[4]; //”data“
19 | int wSampleLength; //音频数据的大小
20 | } wav_header;
21 |
22 | struct audio_data get_audio_data(char *file) {
23 | int nread;
24 | FILE *fp = fopen(file, "rb");
25 | nread = fread(&wav_header, 1, sizeof(wav_header), fp);
26 | struct audio_data data;
27 | data.size = wav_header.rLen - 36;
28 | data.sampling_rate = wav_header.nSamplesPersec;
29 | data.data = malloc(data.size);
30 | fseek(fp, 44, SEEK_SET);
31 | nread = fread(data.data, data.size, 1, fp);
32 | fclose(fp);
33 | return data;
34 | }
35 |
--------------------------------------------------------------------------------
/source/audio_data/audio_data.hpp:
--------------------------------------------------------------------------------
1 | #ifndef __AUDIO_DATA__
2 | #define __AUDIO_DATA__
3 |
4 | struct audio_data {
5 | int size;
6 | int sampling_rate;
7 | void* data;
8 | };
9 |
10 | struct audio_data get_audio_data(char *file);
11 |
12 | #endif
13 |
--------------------------------------------------------------------------------
/source/common/controls.cpp:
--------------------------------------------------------------------------------
1 | // Include GLFW
2 | #include
3 | extern GLFWwindow* window; // The "extern" keyword here is to access the variable "window" declared in tutorialXXX.cpp. This is a hack to keep the tutorials simple. Please avoid this.
4 |
5 | // Include GLM
6 | #include
7 | #include
8 | using namespace glm;
9 |
10 | #include "controls.hpp"
11 |
12 | glm::mat4 ViewMatrix;
13 | glm::mat4 ProjectionMatrix;
14 |
15 | glm::mat4 getViewMatrix(){
16 | return ViewMatrix;
17 | }
18 | glm::mat4 getProjectionMatrix(){
19 | return ProjectionMatrix;
20 | }
21 |
22 |
23 | // Initial position : on +Z
24 | glm::vec3 position = glm::vec3( 0, 0, 5 );
25 | // Initial horizontal angle : toward -Z
26 | float horizontalAngle = 3.14f;
27 | // Initial vertical angle : none
28 | float verticalAngle = 0.0f;
29 | // Initial Field of View
30 | float initialFoV = 45.0f;
31 |
32 | float speed = 5.0f; // 3 units / second
33 | float mouseSpeed = 0.002f;
34 |
35 | double time = 0.0f;
36 | float radius = 20.0f;
37 | float height = 10.0f;
38 | float surround_speed = 0.2f;
39 |
40 | void computeMatricesFromInputs(){
41 |
42 | // glfwGetTime is called only once, the first time this function is called
43 | static double lastTime = glfwGetTime();
44 |
45 | // Compute time difference between current and last frame
46 | double currentTime = glfwGetTime();
47 | float deltaTime = float(currentTime - lastTime);
48 |
49 | // Get mouse position
50 | double xpos, ypos;
51 | glfwGetCursorPos(window, &xpos, &ypos);
52 |
53 | // Reset mouse position for next frame
54 | // glfwSetCursorPos(window, 1024/2, 768/2);
55 |
56 | // Compute new orientation
57 | horizontalAngle += mouseSpeed * float(xpos - 1024/2);
58 | verticalAngle += mouseSpeed * float(768/2 - ypos);
59 |
60 | // Direction : Spherical coordinates to Cartesian coordinates conversion
61 | glm::vec3 direction(
62 | cos(verticalAngle) * sin(horizontalAngle),
63 | sin(verticalAngle),
64 | cos(verticalAngle) * cos(horizontalAngle)
65 | );
66 |
67 | // Right vector
68 | glm::vec3 right = glm::vec3(
69 | sin(horizontalAngle - 3.14f/2.0f),
70 | 0,
71 | cos(horizontalAngle - 3.14f/2.0f)
72 | );
73 |
74 | // Up vector
75 | glm::vec3 up = glm::cross( right, direction );
76 |
77 | // Move forward
78 | if (glfwGetKey( window, GLFW_KEY_UP ) == GLFW_PRESS){
79 | position += direction * deltaTime * speed;
80 | }
81 | // Move backward
82 | if (glfwGetKey( window, GLFW_KEY_DOWN ) == GLFW_PRESS){
83 | position -= direction * deltaTime * speed;
84 | }
85 | // Strafe right
86 | if (glfwGetKey( window, GLFW_KEY_RIGHT ) == GLFW_PRESS){
87 | position += right * deltaTime * speed;
88 | }
89 | // Strafe left
90 | if (glfwGetKey( window, GLFW_KEY_LEFT ) == GLFW_PRESS){
91 | position -= right * deltaTime * speed;
92 | }
93 |
94 | float FoV = initialFoV;// - 5 * glfwGetMouseWheel(); // Now GLFW 3 requires setting up a callback for this. It's a bit too complicated for this beginner's tutorial, so it's disabled instead.
95 |
96 | // Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units
97 | ProjectionMatrix = glm::perspective(FoV, 4.0f / 3.0f, 0.1f, 100.0f);
98 | // Camera matrix
99 | time = glfwGetTime();
100 | position = vec3(radius * cos(time * surround_speed ), height, radius * sin(time * surround_speed));
101 | ViewMatrix = glm::lookAt(
102 | position, // Camera is here
103 | vec3(0,0,0),//position+direction, // and looks here : at the same position, plus "direction"
104 | vec3(0,1,0) //up // Head is up (set to 0,-1,0 to look upside-down)
105 | );
106 |
107 | // For the next frame, the "last time" will be "now"
108 | lastTime = currentTime;
109 | }
--------------------------------------------------------------------------------
/source/common/controls.hpp:
--------------------------------------------------------------------------------
1 | #ifndef CONTROLS_HPP
2 | #define CONTROLS_HPP
3 |
4 | void computeMatricesFromInputs();
5 | glm::mat4 getViewMatrix();
6 | glm::mat4 getProjectionMatrix();
7 |
8 | #endif
--------------------------------------------------------------------------------
/source/common/load_shaders.cpp:
--------------------------------------------------------------------------------
1 | //////////////////////////////////////////////////////////////////////////////
2 | //
3 | // --- LoadShaders.cxx ---
4 | //
5 | //////////////////////////////////////////////////////////////////////////////
6 |
7 | #include
8 | #include
9 | #include
10 |
11 | #define GLEW_STATIC
12 | #include
13 | #include "load_shaders.hpp"
14 |
15 | #ifdef __cplusplus
16 | extern "C" {
17 | #endif // __cplusplus
18 |
19 | //----------------------------------------------------------------------------
20 |
21 | static const GLchar*
22 | ReadShader( const char* filename )
23 | {
24 | #ifdef WIN32
25 | FILE* infile;
26 | fopen_s( &infile, filename, "rb" );
27 | #else
28 | FILE* infile = fopen( filename, "rb" );
29 | #endif // WIN32
30 |
31 | if ( !infile ) {
32 | #ifdef _DEBUG
33 | std::cerr << "Unable to open file '" << filename << "'" << std::endl;
34 | #endif /* DEBUG */
35 | return NULL;
36 | }
37 |
38 | fseek( infile, 0, SEEK_END );
39 | int len = ftell( infile );
40 | fseek( infile, 0, SEEK_SET );
41 |
42 | GLchar* source = new GLchar[len+1];
43 |
44 | fread( source, 1, len, infile );
45 | fclose( infile );
46 |
47 | source[len] = 0;
48 |
49 | return const_cast(source);
50 | }
51 |
52 | //----------------------------------------------------------------------------
53 |
54 | GLuint
55 | LoadShaders( ShaderInfo* shaders )
56 | {
57 | if ( shaders == NULL ) { return 0; }
58 |
59 | GLuint program = glCreateProgram();
60 |
61 | ShaderInfo* entry = shaders;
62 | while ( entry->type != GL_NONE ) {
63 | GLuint shader = glCreateShader( entry->type );
64 |
65 | entry->shader = shader;
66 |
67 | const GLchar* source = ReadShader( entry->filename );
68 | if ( source == NULL ) {
69 | for ( entry = shaders; entry->type != GL_NONE; ++entry ) {
70 | glDeleteShader( entry->shader );
71 | entry->shader = 0;
72 | }
73 |
74 | return 0;
75 | }
76 |
77 | glShaderSource( shader, 1, &source, NULL );
78 | delete [] source;
79 |
80 | glCompileShader( shader );
81 |
82 | GLint compiled;
83 | glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled );
84 | if ( !compiled ) {
85 | #ifdef _DEBUG
86 | GLsizei len;
87 | glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &len );
88 |
89 | GLchar* log = new GLchar[len+1];
90 | glGetShaderInfoLog( shader, len, &len, log );
91 | std::cerr << "Shader compilation failed: " << log << std::endl;
92 | delete [] log;
93 | #endif /* DEBUG */
94 |
95 | return 0;
96 | }
97 |
98 | glAttachShader( program, shader );
99 |
100 | ++entry;
101 | }
102 |
103 | #ifdef GL_VERSION_4_1
104 | if ( GLEW_VERSION_4_1 ) {
105 | // glProgramParameteri( program, GL_PROGRAM_SEPARABLE, GL_TRUE );
106 | }
107 | #endif /* GL_VERSION_4_1 */
108 |
109 | glLinkProgram( program );
110 |
111 | GLint linked;
112 | glGetProgramiv( program, GL_LINK_STATUS, &linked );
113 | if ( !linked ) {
114 | #ifdef _DEBUG
115 | GLsizei len;
116 | glGetProgramiv( program, GL_INFO_LOG_LENGTH, &len );
117 |
118 | GLchar* log = new GLchar[len+1];
119 | glGetProgramInfoLog( program, len, &len, log );
120 | std::cerr << "Shader linking failed: " << log << std::endl;
121 | delete [] log;
122 | #endif /* DEBUG */
123 |
124 | for ( entry = shaders; entry->type != GL_NONE; ++entry ) {
125 | glDeleteShader( entry->shader );
126 | entry->shader = 0;
127 | }
128 |
129 | return 0;
130 | }
131 |
132 | return program;
133 | }
134 |
135 | //----------------------------------------------------------------------------
136 | #ifdef __cplusplus
137 | }
138 | #endif // __cplusplus
139 |
140 |
141 |
--------------------------------------------------------------------------------
/source/common/load_shaders.hpp:
--------------------------------------------------------------------------------
1 | //////////////////////////////////////////////////////////////////////////////
2 | //
3 | // --- LoadShaders.h ---
4 | //
5 | //////////////////////////////////////////////////////////////////////////////
6 |
7 | #ifndef __LOAD_SHADERS_H__
8 | #define __LOAD_SHADERS_H__
9 |
10 | #include
11 |
12 | #ifdef __cplusplus
13 | extern "C" {
14 | #endif // __cplusplus
15 |
16 | //----------------------------------------------------------------------------
17 | //
18 | // LoadShaders() takes an array of ShaderFile structures, each of which
19 | // contains the type of the shader, and a pointer a C-style character
20 | // string (i.e., a NULL-terminated array of characters) containing the
21 | // entire shader source.
22 | //
23 | // The array of structures is terminated by a final Shader with the
24 | // "type" field set to GL_NONE.
25 | //
26 | // LoadShaders() returns the shader program value (as returned by
27 | // glCreateProgram()) on success, or zero on failure.
28 | //
29 |
30 | typedef struct {
31 | GLenum type;
32 | const char* filename;
33 | GLuint shader;
34 | } ShaderInfo;
35 |
36 | GLuint LoadShaders( ShaderInfo* );
37 |
38 | //----------------------------------------------------------------------------
39 |
40 | #ifdef __cplusplus
41 | };
42 | #endif // __cplusplus
43 |
44 | #endif // __LOAD_SHADERS_H__
45 |
--------------------------------------------------------------------------------
/source/common/objloader.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #include
7 |
8 | #include "objloader.hpp"
9 |
10 | // Very, VERY simple OBJ loader.
11 | // Here is a short list of features a real function would provide :
12 | // - Binary files. Reading a model should be just a few memcpy's away, not parsing a file at runtime. In short : OBJ is not very great.
13 | // - Animations & bones (includes bones weights)
14 | // - Multiple UVs
15 | // - All attributes should be optional, not "forced"
16 | // - More stable. Change a line in the OBJ file and it crashes.
17 | // - More secure. Change another line and you can inject code.
18 | // - Loading from memory, stream, etc
19 |
20 | bool loadOBJ(
21 | const char * path,
22 | std::vector & out_vertices,
23 | std::vector & out_uvs,
24 | std::vector & out_normals
25 | ){
26 | printf("Loading OBJ file %s...\n", path);
27 |
28 | std::vector vertexIndices, uvIndices, normalIndices;
29 | std::vector temp_vertices;
30 | std::vector temp_uvs;
31 | std::vector temp_normals;
32 |
33 |
34 | FILE * file = fopen(path, "r");
35 | if( file == NULL ){
36 | printf("Impossible to open the file ! Are you in the right path ? See Tutorial 1 for details\n");
37 | getchar();
38 | return false;
39 | }
40 |
41 | while( 1 ){
42 |
43 | char lineHeader[128];
44 | // read the first word of the line
45 | int res = fscanf(file, "%s", lineHeader);
46 | if (res == EOF)
47 | break; // EOF = End Of File. Quit the loop.
48 |
49 | // else : parse lineHeader
50 |
51 | if ( strcmp( lineHeader, "v" ) == 0 ){
52 | glm::vec3 vertex;
53 | fscanf(file, "%f %f %f\n", &vertex.x, &vertex.y, &vertex.z );
54 | temp_vertices.push_back(vertex);
55 | }else if ( strcmp( lineHeader, "vt" ) == 0 ){
56 | glm::vec2 uv;
57 | fscanf(file, "%f %f\n", &uv.x, &uv.y );
58 | uv.y = -uv.y; // Invert V coordinate since we will only use DDS texture, which are inverted. Remove if you want to use TGA or BMP loaders.
59 | temp_uvs.push_back(uv);
60 | }else if ( strcmp( lineHeader, "vn" ) == 0 ){
61 | glm::vec3 normal;
62 | fscanf(file, "%f %f %f\n", &normal.x, &normal.y, &normal.z );
63 | temp_normals.push_back(normal);
64 | }else if ( strcmp( lineHeader, "f" ) == 0 ){
65 | std::string vertex1, vertex2, vertex3;
66 | unsigned int vertexIndex[3], uvIndex[3], normalIndex[3];
67 | int matches = fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexIndex[0], &uvIndex[0], &normalIndex[0], &vertexIndex[1], &uvIndex[1], &normalIndex[1], &vertexIndex[2], &uvIndex[2], &normalIndex[2] );
68 | if (matches != 9){
69 | printf("File can't be read by our simple parser :-( Try exporting with other options\n");
70 | return false;
71 | }
72 | vertexIndices.push_back(vertexIndex[0]);
73 | vertexIndices.push_back(vertexIndex[1]);
74 | vertexIndices.push_back(vertexIndex[2]);
75 | uvIndices .push_back(uvIndex[0]);
76 | uvIndices .push_back(uvIndex[1]);
77 | uvIndices .push_back(uvIndex[2]);
78 | normalIndices.push_back(normalIndex[0]);
79 | normalIndices.push_back(normalIndex[1]);
80 | normalIndices.push_back(normalIndex[2]);
81 | }else{
82 | // Probably a comment, eat up the rest of the line
83 | char stupidBuffer[1000];
84 | fgets(stupidBuffer, 1000, file);
85 | }
86 |
87 | }
88 |
89 | // For each vertex of each triangle
90 | for( unsigned int i=0; i // C++ importer interface
117 | #include // Output data structure
118 | #include // Post processing flags
119 |
120 | bool loadAssImp(
121 | const char * path,
122 | std::vector & indices,
123 | std::vector & vertices,
124 | std::vector & uvs,
125 | std::vector & normals
126 | ){
127 |
128 | Assimp::Importer importer;
129 |
130 | const aiScene* scene = importer.ReadFile(path, 0/*aiProcess_JoinIdenticalVertices | aiProcess_SortByPType*/);
131 | if( !scene) {
132 | fprintf( stderr, importer.GetErrorString());
133 | getchar();
134 | return false;
135 | }
136 | const aiMesh* mesh = scene->mMeshes[0]; // In this simple example code we always use the 1rst mesh (in OBJ files there is often only one anyway)
137 |
138 | // Fill vertices positions
139 | vertices.reserve(mesh->mNumVertices);
140 | for(unsigned int i=0; imNumVertices; i++){
141 | aiVector3D pos = mesh->mVertices[i];
142 | vertices.push_back(glm::vec3(pos.x, pos.y, pos.z));
143 | }
144 |
145 | // Fill vertices texture coordinates
146 | uvs.reserve(mesh->mNumVertices);
147 | for(unsigned int i=0; imNumVertices; i++){
148 | aiVector3D UVW = mesh->mTextureCoords[0][i]; // Assume only 1 set of UV coords; AssImp supports 8 UV sets.
149 | uvs.push_back(glm::vec2(UVW.x, UVW.y));
150 | }
151 |
152 | // Fill vertices normals
153 | normals.reserve(mesh->mNumVertices);
154 | for(unsigned int i=0; imNumVertices; i++){
155 | aiVector3D n = mesh->mNormals[i];
156 | normals.push_back(glm::vec3(n.x, n.y, n.z));
157 | }
158 |
159 |
160 | // Fill face indices
161 | indices.reserve(3*mesh->mNumFaces);
162 | for (unsigned int i=0; imNumFaces; i++){
163 | // Assume the model has only triangles.
164 | indices.push_back(mesh->mFaces[i].mIndices[0]);
165 | indices.push_back(mesh->mFaces[i].mIndices[1]);
166 | indices.push_back(mesh->mFaces[i].mIndices[2]);
167 | }
168 |
169 | // The "scene" pointer will be deleted automatically by "importer"
170 |
171 | }
172 |
173 | #endif
--------------------------------------------------------------------------------
/source/common/objloader.hpp:
--------------------------------------------------------------------------------
1 | #ifndef OBJLOADER_H
2 | #define OBJLOADER_H
3 |
4 | bool loadOBJ(
5 | const char * path,
6 | std::vector & out_vertices,
7 | std::vector & out_uvs,
8 | std::vector & out_normals
9 | );
10 |
11 |
12 |
13 | bool loadAssImp(
14 | const char * path,
15 | std::vector & indices,
16 | std::vector & vertices,
17 | std::vector & uvs,
18 | std::vector & normals
19 | );
20 |
21 | #endif
--------------------------------------------------------------------------------
/source/common/quaternion_utils.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chaosink/Audio-Visualization---Waveform/b7a87786abd91551ebdca9c3f3ef2d385c6a2479/source/common/quaternion_utils.cpp
--------------------------------------------------------------------------------
/source/common/quaternion_utils.hpp:
--------------------------------------------------------------------------------
1 | #ifndef QUATERNION_UTILS_H
2 | #define QUATERNION_UTILS_H
3 |
4 | quat RotationBetweenVectors(vec3 start, vec3 dest);
5 |
6 | quat LookAt(vec3 direction, vec3 desiredUp);
7 |
8 | quat RotateTowards(quat q1, quat q2, float maxAngle);
9 |
10 |
11 | #endif // QUATERNION_UTILS_H
--------------------------------------------------------------------------------
/source/common/shader.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | using namespace std;
8 |
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | #include "shader.hpp"
15 |
16 | GLuint LoadShaders(const char *vertex_file_path, const char *fragment_file_path, const char *geometry_file_path) {
17 |
18 | // Create the shaders
19 | GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
20 | GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
21 | GLuint GeometryShaderID = glCreateShader(GL_GEOMETRY_SHADER);
22 |
23 | // Read the Vertex Shader code from the file
24 | std::string VertexShaderCode;
25 | std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
26 | if(VertexShaderStream.is_open()) {
27 | std::string Line = "";
28 | while(getline(VertexShaderStream, Line))
29 | VertexShaderCode += "\n" + Line;
30 | VertexShaderStream.close();
31 | } else {
32 | printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", vertex_file_path);
33 | getchar();
34 | return 0;
35 | }
36 |
37 | // Read the Fragment Shader code from the file
38 | std::string FragmentShaderCode;
39 | std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
40 | if(FragmentShaderStream.is_open()){
41 | std::string Line = "";
42 | while(getline(FragmentShaderStream, Line))
43 | FragmentShaderCode += "\n" + Line;
44 | FragmentShaderStream.close();
45 | }
46 |
47 |
48 | // Read the Geometry Shader code from the file
49 | std::string GeometryShaderCode;
50 | std::ifstream GeometryShaderStream(geometry_file_path, std::ios::in);
51 | if(geometry_file_path) {
52 | if(GeometryShaderStream.is_open()){
53 | std::string Line = "";
54 | while(getline(GeometryShaderStream, Line))
55 | GeometryShaderCode += "\n" + Line;
56 | GeometryShaderStream.close();
57 | }
58 | }
59 |
60 | GLint Result = GL_FALSE;
61 | int InfoLogLength;
62 |
63 | // Compile Vertex Shader
64 | printf("Compiling shader : %s\n", vertex_file_path);
65 | char const * VertexSourcePointer = VertexShaderCode.c_str();
66 | glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
67 | glCompileShader(VertexShaderID);
68 | // Check Vertex Shader
69 | glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
70 | glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
71 | if(InfoLogLength > 0) {
72 | std::vector VertexShaderErrorMessage(InfoLogLength+1);
73 | glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
74 | printf("%s\n", &VertexShaderErrorMessage[0]);
75 | }
76 |
77 | // Compile Fragment Shader
78 | printf("Compiling shader : %s\n", fragment_file_path);
79 | char const * FragmentSourcePointer = FragmentShaderCode.c_str();
80 | glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
81 | glCompileShader(FragmentShaderID);
82 | // Check Fragment Shader
83 | glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
84 | glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
85 | if ( InfoLogLength > 0 ){
86 | std::vector FragmentShaderErrorMessage(InfoLogLength+1);
87 | glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
88 | printf("%s\n", &FragmentShaderErrorMessage[0]);
89 | }
90 |
91 | if(geometry_file_path) {
92 | // Compile Geometry Shader
93 | printf("Compiling shader : %s\n", geometry_file_path);
94 | char const * GeometrySourcePointer = GeometryShaderCode.c_str();
95 | glShaderSource(GeometryShaderID, 1, &GeometrySourcePointer , NULL);
96 | glCompileShader(GeometryShaderID);
97 | // Check Geometry Shader
98 | glGetShaderiv(GeometryShaderID, GL_COMPILE_STATUS, &Result);
99 | glGetShaderiv(GeometryShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
100 | if ( InfoLogLength > 0 ){
101 | std::vector GeometryShaderErrorMessage(InfoLogLength+1);
102 | glGetShaderInfoLog(GeometryShaderID, InfoLogLength, NULL, &GeometryShaderErrorMessage[0]);
103 | printf("%s\n", &GeometryShaderErrorMessage[0]);
104 | }
105 | }
106 |
107 | // Link the program
108 | printf("Linking program\n");
109 | GLuint ProgramID = glCreateProgram();
110 | glAttachShader(ProgramID, VertexShaderID);
111 | glAttachShader(ProgramID, FragmentShaderID);
112 | if(geometry_file_path)
113 | glAttachShader(ProgramID, GeometryShaderID);
114 | glLinkProgram(ProgramID);
115 |
116 | // Check the program
117 | glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
118 | glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
119 | if ( InfoLogLength > 0 ){
120 | std::vector ProgramErrorMessage(InfoLogLength+1);
121 | glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
122 | printf("%s\n", &ProgramErrorMessage[0]);
123 | }
124 |
125 | glDeleteShader(VertexShaderID);
126 | glDeleteShader(FragmentShaderID);
127 | glDeleteShader(GeometryShaderID);
128 |
129 | return ProgramID;
130 | }
131 |
132 |
133 |
--------------------------------------------------------------------------------
/source/common/shader.hpp:
--------------------------------------------------------------------------------
1 | #ifndef SHADER_HPP
2 | #define SHADER_HPP
3 |
4 | GLuint LoadShaders(const char * vertex_file_path, const char * fragment_file_path, const char * geometry_file_path = NULL);
5 |
6 | #endif
7 |
--------------------------------------------------------------------------------
/source/common/tangentspace.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "tangentspace.hpp"
5 |
6 | void computeTangentBasis(
7 | // inputs
8 | std::vector & vertices,
9 | std::vector & uvs,
10 | std::vector & normals,
11 | // outputs
12 | std::vector & tangents,
13 | std::vector & bitangents
14 | ){
15 |
16 | for (unsigned int i=0; i & vertices,
7 | std::vector & uvs,
8 | std::vector & normals,
9 | // outputs
10 | std::vector & tangents,
11 | std::vector & bitangents
12 | );
13 |
14 |
15 | #endif
--------------------------------------------------------------------------------
/source/common/text2D.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include
5 |
6 | #include
7 | #include
8 | using namespace glm;
9 |
10 | #include "shader.hpp"
11 | #include "texture.hpp"
12 |
13 | #include "text2D.hpp"
14 |
15 | unsigned int Text2DTextureID; // Texture containing the font
16 | unsigned int Text2DVertexBufferID; // Buffer containing the vertices
17 | unsigned int Text2DUVBufferID; // UVs
18 | unsigned int Text2DShaderID; // Program used to disaply the text
19 | unsigned int vertexPosition_screenspaceID; // Location of the program's "vertexPosition_screenspace" attribute
20 | unsigned int vertexUVID; // Location of the program's "vertexUV" attribute
21 | unsigned int Text2DUniformID; // Location of the program's texture attribute
22 |
23 | void initText2D(const char * texturePath){
24 |
25 | // Initialize texture
26 | Text2DTextureID = loadDDS(texturePath);
27 |
28 | // Initialize VBO
29 | glGenBuffers(1, &Text2DVertexBufferID);
30 | glGenBuffers(1, &Text2DUVBufferID);
31 |
32 | // Initialize Shader
33 | Text2DShaderID = LoadShaders( "TextVertexShader.vertexshader", "TextVertexShader.fragmentshader" );
34 |
35 | // Get a handle for our buffers
36 | vertexPosition_screenspaceID = glGetAttribLocation(Text2DShaderID, "vertexPosition_screenspace");
37 | vertexUVID = glGetAttribLocation(Text2DShaderID, "vertexUV");
38 |
39 | // Initialize uniforms' IDs
40 | Text2DUniformID = glGetUniformLocation( Text2DShaderID, "myTextureSampler" );
41 |
42 | }
43 |
44 | void printText2D(const char * text, int x, int y, int size){
45 |
46 | unsigned int length = strlen(text);
47 |
48 | // Fill buffers
49 | std::vector vertices;
50 | std::vector UVs;
51 | for ( unsigned int i=0 ; i
2 | #include
3 | #include
4 |
5 | #include
6 |
7 | #include
8 |
9 |
10 | GLuint loadBMP_custom(const char * imagepath){
11 |
12 | printf("Reading image %s\n", imagepath);
13 |
14 | // Data read from the header of the BMP file
15 | unsigned char header[54];
16 | unsigned int dataPos;
17 | unsigned int imageSize;
18 | unsigned int width, height;
19 | // Actual RGB data
20 | unsigned char * data;
21 |
22 | // Open the file
23 | FILE * file = fopen(imagepath,"rb");
24 | if (!file) {
25 | printf("%s could not be opened. Are you in the right directory ? Don't forget to read the FAQ !\n", imagepath);
26 | getchar();
27 | return 0;
28 | }
29 |
30 | // Read the header, i.e. the 54 first bytes
31 |
32 | // If less than 54 bytes are read, problem
33 | if ( fread(header, 1, 54, file)!=54 ){
34 | printf("Not a correct BMP file\n");
35 | return 0;
36 | }
37 | // A BMP files always begins with "BM"
38 | if ( header[0]!='B' || header[1]!='M' ){
39 | printf("Not a correct BMP file\n");
40 | return 0;
41 | }
42 | // Make sure this is a 24bpp file
43 | if ( *(int*)&(header[0x1E])!=0 ) {printf("Not a correct BMP file\n"); return 0;}
44 | if ( *(int*)&(header[0x1C])!=24 ) {printf("Not a correct BMP file\n"); return 0;}
45 |
46 | // Read the information about the image
47 | dataPos = *(int*)&(header[0x0A]);
48 | imageSize = *(int*)&(header[0x22]);
49 | width = *(int*)&(header[0x12]);
50 | height = *(int*)&(header[0x16]);
51 |
52 | // Some BMP files are misformatted, guess missing information
53 | if (imageSize==0) imageSize=width*height*3; // 3 : one byte for each Red, Green and Blue component
54 | if (dataPos==0) dataPos=54; // The BMP header is done that way
55 |
56 | // Create a buffer
57 | data = new unsigned char [imageSize];
58 |
59 | // Read the actual data from the file into the buffer
60 | fread(data,1,imageSize,file);
61 |
62 | // Everything is in memory now, the file wan be closed
63 | fclose (file);
64 |
65 | // Create one OpenGL texture
66 | GLuint textureID;
67 | glGenTextures(1, &textureID);
68 |
69 | // "Bind" the newly created texture : all future texture functions will modify this texture
70 | glBindTexture(GL_TEXTURE_2D, textureID);
71 |
72 | // Give the image to OpenGL
73 | glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
74 |
75 | // OpenGL has now copied the data. Free our own version
76 | delete [] data;
77 |
78 | // Poor filtering, or ...
79 | //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
80 | //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
81 |
82 | // ... nice trilinear filtering.
83 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
84 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
85 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
86 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
87 | glGenerateMipmap(GL_TEXTURE_2D);
88 |
89 | // Return the ID of the texture we just created
90 | return textureID;
91 | }
92 |
93 | // Since GLFW 3, glfwLoadTexture2D() has been removed. You have to use another texture loading library,
94 | // or do it yourself (just like loadBMP_custom and loadDDS)
95 | //GLuint loadTGA_glfw(const char * imagepath){
96 | //
97 | // // Create one OpenGL texture
98 | // GLuint textureID;
99 | // glGenTextures(1, &textureID);
100 | //
101 | // // "Bind" the newly created texture : all future texture functions will modify this texture
102 | // glBindTexture(GL_TEXTURE_2D, textureID);
103 | //
104 | // // Read the file, call glTexImage2D with the right parameters
105 | // glfwLoadTexture2D(imagepath, 0);
106 | //
107 | // // Nice trilinear filtering.
108 | // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
109 | // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
110 | // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
111 | // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
112 | // glGenerateMipmap(GL_TEXTURE_2D);
113 | //
114 | // // Return the ID of the texture we just created
115 | // return textureID;
116 | //}
117 |
118 |
119 |
120 | #define FOURCC_DXT1 0x31545844 // Equivalent to "DXT1" in ASCII
121 | #define FOURCC_DXT3 0x33545844 // Equivalent to "DXT3" in ASCII
122 | #define FOURCC_DXT5 0x35545844 // Equivalent to "DXT5" in ASCII
123 |
124 | GLuint loadDDS(const char * imagepath){
125 |
126 | unsigned char header[124];
127 |
128 | FILE *fp;
129 |
130 | /* try to open the file */
131 | fp = fopen(imagepath, "rb");
132 | if (fp == NULL){
133 | printf("%s could not be opened. Are you in the right directory ? Don't forget to read the FAQ !\n", imagepath);
134 | getchar();
135 | return 0;
136 | }
137 |
138 | /* verify the type of file */
139 | char filecode[4];
140 | fread(filecode, 1, 4, fp);
141 | if (strncmp(filecode, "DDS ", 4) != 0) {
142 | fclose(fp);
143 | return 0;
144 | }
145 |
146 | /* get the surface desc */
147 | fread(&header, 124, 1, fp);
148 |
149 | unsigned int height = *(unsigned int*)&(header[8 ]);
150 | unsigned int width = *(unsigned int*)&(header[12]);
151 | unsigned int linearSize = *(unsigned int*)&(header[16]);
152 | unsigned int mipMapCount = *(unsigned int*)&(header[24]);
153 | unsigned int fourCC = *(unsigned int*)&(header[80]);
154 |
155 |
156 | unsigned char * buffer;
157 | unsigned int bufsize;
158 | /* how big is it going to be including all mipmaps? */
159 | bufsize = mipMapCount > 1 ? linearSize * 2 : linearSize;
160 | buffer = (unsigned char*)malloc(bufsize * sizeof(unsigned char));
161 | fread(buffer, 1, bufsize, fp);
162 | /* close the file pointer */
163 | fclose(fp);
164 |
165 | unsigned int components = (fourCC == FOURCC_DXT1) ? 3 : 4;
166 | unsigned int format;
167 | switch(fourCC)
168 | {
169 | case FOURCC_DXT1:
170 | format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
171 | break;
172 | case FOURCC_DXT3:
173 | format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
174 | break;
175 | case FOURCC_DXT5:
176 | format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
177 | break;
178 | default:
179 | free(buffer);
180 | return 0;
181 | }
182 |
183 | // Create one OpenGL texture
184 | GLuint textureID;
185 | glGenTextures(1, &textureID);
186 |
187 | // "Bind" the newly created texture : all future texture functions will modify this texture
188 | glBindTexture(GL_TEXTURE_2D, textureID);
189 | glPixelStorei(GL_UNPACK_ALIGNMENT,1);
190 |
191 | unsigned int blockSize = (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16;
192 | unsigned int offset = 0;
193 |
194 | /* load the mipmaps */
195 | for (unsigned int level = 0; level < mipMapCount && (width || height); ++level)
196 | {
197 | unsigned int size = ((width+3)/4)*((height+3)/4)*blockSize;
198 | glCompressedTexImage2D(GL_TEXTURE_2D, level, format, width, height,
199 | 0, size, buffer + offset);
200 |
201 | offset += size;
202 | width /= 2;
203 | height /= 2;
204 |
205 | // Deal with Non-Power-Of-Two textures. This code is not included in the webpage to reduce clutter.
206 | if(width < 1) width = 1;
207 | if(height < 1) height = 1;
208 |
209 | }
210 |
211 | free(buffer);
212 |
213 | return textureID;
214 |
215 |
216 | }
217 |
--------------------------------------------------------------------------------
/source/common/texture.hpp:
--------------------------------------------------------------------------------
1 | #ifndef TEXTURE_HPP
2 | #define TEXTURE_HPP
3 |
4 | // Load a .BMP file using our custom loader
5 | GLuint loadBMP_custom(const char * imagepath);
6 |
7 | //// Since GLFW 3, glfwLoadTexture2D() has been removed. You have to use another texture loading library,
8 | //// or do it yourself (just like loadBMP_custom and loadDDS)
9 | //// Load a .TGA file using GLFW's own loader
10 | //GLuint loadTGA_glfw(const char * imagepath);
11 |
12 | // Load a .DDS file using GLFW's own loader
13 | GLuint loadDDS(const char * imagepath);
14 |
15 |
16 | #endif
--------------------------------------------------------------------------------
/source/common/vboindexer.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include