Initial commit
This commit is contained in:
commit
387c192a01
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
bin/
|
||||||
|
lib/
|
||||||
|
.DS_Store
|
||||||
|
.idea/
|
||||||
|
|
||||||
132
CMakeLists.txt
Normal file
132
CMakeLists.txt
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.2)
|
||||||
|
project(glTest)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -DGLEW_STATIC -O0 -g")
|
||||||
|
set(CMAKE_BUILD_TYPE DEBUG)
|
||||||
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
|
||||||
|
|
||||||
|
if(APPLE)
|
||||||
|
find_library(COCOA_FRAMEWORK Cocoa)
|
||||||
|
find_library(OPENGL_FRAMEWORK OpenGL)
|
||||||
|
find_library(IOKIT_FRAMEWORK IOKit)
|
||||||
|
find_library(COREVIDEO_FRAMEWORK CoreVideo)
|
||||||
|
set(REQUIRED_LIBRARIES ${COCOA_FRAMEWORK} ${OPENGL_FRAMEWORK} ${IOKIT_FRAMEWORK} ${COREVIDEO_FRAMEWORK})
|
||||||
|
else()
|
||||||
|
find_package(OpenGL REQUIRED)
|
||||||
|
find_library(x11 NAMES X11)
|
||||||
|
find_library(xrandr NAMES Xrandr)
|
||||||
|
find_library(xi NAMES Xi)
|
||||||
|
find_library(xxf86vm NAMES Xxf86vm)
|
||||||
|
find_library(pthread NAMES pthread)
|
||||||
|
find_library(Xinerama NAMES Xinerama)
|
||||||
|
find_library(Xcursor NAMES Xcursor)
|
||||||
|
set(REQUIRED_LIBRARIES rt asound ${OPENGL_LIBRARIES} ${x11} ${xrandr} ${xi} ${xxf86vm} ${Xinerama} ${Xcursor} ${pthread})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
INCLUDE(ExternalProject)
|
||||||
|
SET_DIRECTORY_PROPERTIES(PROPERTIES EP_PREFIX ${CMAKE_BINARY_DIR}/ThirdParty)
|
||||||
|
|
||||||
|
ExternalProject_Add(
|
||||||
|
glfw
|
||||||
|
URL http://netcologne.dl.sourceforge.net/project/glfw/glfw/3.1.1/glfw-3.1.1.zip
|
||||||
|
TIMEOUT 100
|
||||||
|
CMAKE_ARGS -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG:PATH=${CMAKE_SOURCE_DIR}/lib
|
||||||
|
-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE:PATH=${CMAKE_SOURCE_DIR}/lib
|
||||||
|
-DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
|
||||||
|
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||||
|
INSTALL_COMMAND ""
|
||||||
|
LOG_DOWNLOAD ON
|
||||||
|
LOG_CONFIGURE ON
|
||||||
|
LOG_BUILD ON)
|
||||||
|
|
||||||
|
ExternalProject_Get_Property(glfw source_dir)
|
||||||
|
ExternalProject_Get_Property(glfw binary_dir)
|
||||||
|
include_directories(${source_dir}/include)
|
||||||
|
|
||||||
|
ExternalProject_Add(
|
||||||
|
glew
|
||||||
|
URL http://vorboss.dl.sourceforge.net/project/glew/glew/1.12.0/glew-1.12.0.zip
|
||||||
|
CONFIGURE_COMMAND ""
|
||||||
|
BUILD_COMMAND "make"
|
||||||
|
BUILD_IN_SOURCE 1
|
||||||
|
INSTALL_COMMAND cp ${CMAKE_BINARY_DIR}/ThirdParty/src/glew/lib/libGLEW.a ${CMAKE_SOURCE_DIR}/lib
|
||||||
|
LOG_DOWNLOAD ON
|
||||||
|
LOG_CONFIGURE ON
|
||||||
|
LOG_BUILD ON
|
||||||
|
)
|
||||||
|
|
||||||
|
ExternalProject_Get_Property(glew source_dir)
|
||||||
|
ExternalProject_Get_Property(glew binary_dir)
|
||||||
|
include_directories(${source_dir}/include)
|
||||||
|
set(GLEW_SRC_DIR ${source_dir})
|
||||||
|
|
||||||
|
ExternalProject_Add(
|
||||||
|
glm
|
||||||
|
URL http://vorboss.dl.sourceforge.net/project/ogl-math/glm-0.9.6.3/glm-0.9.6.3.zip
|
||||||
|
TIMEOUT 100
|
||||||
|
CMAKE_ARGS -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG:PATH=${CMAKE_SOURCE_DIR}/lib
|
||||||
|
-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE:PATH=${CMAKE_SOURCE_DIR}/lib
|
||||||
|
-DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
|
||||||
|
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||||
|
INSTALL_COMMAND ""
|
||||||
|
LOG_DOWNLOAD ON
|
||||||
|
LOG_CONFIGURE ON
|
||||||
|
LOG_BUILD ON)
|
||||||
|
|
||||||
|
ExternalProject_Get_Property(glm source_dir)
|
||||||
|
ExternalProject_Get_Property(glm binary_dir)
|
||||||
|
include_directories(${source_dir})
|
||||||
|
|
||||||
|
ExternalProject_Add(
|
||||||
|
portaudio
|
||||||
|
URL http://www.portaudio.com/archives/pa_stable_v19_20140130.tgz
|
||||||
|
TIMEOUT 100
|
||||||
|
CONFIGURE_COMMAND ${CMAKE_BINARY_DIR}/ThirdParty/src/portaudio/configure --enable-cxx
|
||||||
|
BUILD_COMMAND "/usr/bin/make"
|
||||||
|
BUILD_IN_SOURCE 1
|
||||||
|
INSTALL_COMMAND cp ${CMAKE_BINARY_DIR}/ThirdParty/src/portaudio/lib/.libs/libportaudio.a ${CMAKE_SOURCE_DIR}/lib
|
||||||
|
LOG_DOWNLOAD ON
|
||||||
|
LOG_CONFIGURE ON
|
||||||
|
LOG_BUILD ON)
|
||||||
|
|
||||||
|
ExternalProject_Get_Property(portaudio source_dir)
|
||||||
|
ExternalProject_Get_Property(portaudio binary_dir)
|
||||||
|
include_directories(${source_dir}/include)
|
||||||
|
|
||||||
|
ExternalProject_Add(
|
||||||
|
libsndfile
|
||||||
|
URL "http://www.mega-nerd.com/libsndfile/files/libsndfile-1.0.25.tar.gz"
|
||||||
|
CONFIGURE_COMMAND ${CMAKE_BINARY_DIR}/ThirdParty/src/libsndfile/configure --disable-external-libs
|
||||||
|
BUILD_COMMAND "/usr/bin/make"
|
||||||
|
UPDATE_COMMAND ""
|
||||||
|
INSTALL_COMMAND cp ${CMAKE_BINARY_DIR}/ThirdParty/src/libsndfile/src/.libs/libsndfile.a ${CMAKE_SOURCE_DIR}/lib
|
||||||
|
BUILD_IN_SOURCE 1
|
||||||
|
LOG_DOWNLOAD ON
|
||||||
|
LOG_CONFIGURE ON
|
||||||
|
LOG_BUILD ON
|
||||||
|
)
|
||||||
|
|
||||||
|
ExternalProject_Get_Property(libsndfile source_dir)
|
||||||
|
ExternalProject_Get_Property(libsndfile binary_dir)
|
||||||
|
#include_directories(${source_dir}/include)
|
||||||
|
|
||||||
|
ExternalProject_Add(
|
||||||
|
fftw
|
||||||
|
URL "http://www.fftw.org/fftw-3.3.4.tar.gz"
|
||||||
|
CONFIGURE_COMMAND ${CMAKE_BINARY_DIR}/ThirdParty/src/fftw/configure --enable-float
|
||||||
|
BUILD_COMMAND "/usr/bin/make"
|
||||||
|
UPDATE_COMMAND ""
|
||||||
|
INSTALL_COMMAND cp ${CMAKE_BINARY_DIR}/ThirdParty/src/fftw/.libs/libfftw3f.a ${CMAKE_SOURCE_DIR}/lib
|
||||||
|
BUILD_IN_SOURCE 1
|
||||||
|
LOG_DOWNLOAD ON
|
||||||
|
LOG_CONFIGURE ON
|
||||||
|
LOG_BUILD ON
|
||||||
|
)
|
||||||
|
ExternalProject_Get_Property(fftw source_dir)
|
||||||
|
include_directories(${source_dir}/api)
|
||||||
|
|
||||||
|
set(SOURCE_FILES src/main.cpp)
|
||||||
|
add_executable(glTest ${SOURCE_FILES} src/ShaderProgram.cpp src/ShaderProgram.h src/Mesh.cpp src/Mesh.h src/vertex.h src/IGLObject.h src/GLObject.cpp src/GLObject.h src/WaveMesh.cpp src/WaveMesh.h src/AudioPlayer.cpp src/AudioPlayer.h src/ISndSource.h src/WavSource.cpp src/WavSource.h src/SpectralMesh.cpp src/SpectralMesh.h)
|
||||||
|
add_dependencies(glTest glfw glew glm portaudio libsndfile fftw)
|
||||||
|
target_link_libraries(glTest ${GLFW_LIBRARIES} ${REQUIRED_LIBRARIES} ${CMAKE_SOURCE_DIR}/lib/libglfw3.a ${CMAKE_SOURCE_DIR}/lib/libGLEW.a
|
||||||
|
${CMAKE_SOURCE_DIR}/lib/libportaudio.a ${CMAKE_SOURCE_DIR}/lib/libsndfile.a ${CMAKE_SOURCE_DIR}/lib/libfftw3f.a)
|
||||||
8
shaders/fragment.glsl
Normal file
8
shaders/fragment.glsl
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#version 330
|
||||||
|
|
||||||
|
smooth in vec3 theColor;
|
||||||
|
out vec4 frag_colour;
|
||||||
|
|
||||||
|
void main () {
|
||||||
|
frag_colour = vec4(theColor, 1.0);
|
||||||
|
}
|
||||||
43
shaders/vertex.glsl
Normal file
43
shaders/vertex.glsl
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#version 330
|
||||||
|
|
||||||
|
uniform mat4 mWorld;
|
||||||
|
uniform mat4 mView;
|
||||||
|
uniform mat4 mProjection;
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 vp;
|
||||||
|
layout (location = 1) in vec3 normals;
|
||||||
|
|
||||||
|
smooth out vec3 theColor;
|
||||||
|
|
||||||
|
vec3 hsv_to_rgb(float h, float s, float v)
|
||||||
|
{
|
||||||
|
float c = v * s;
|
||||||
|
h = mod((h * 6.0), 6.0);
|
||||||
|
float x = c * (1.0 - abs(mod(h, 2.0) - 1.0));
|
||||||
|
vec3 color;
|
||||||
|
|
||||||
|
if (0.0 <= h && h < 1.0) {
|
||||||
|
color = vec3(c, x, 0.0);
|
||||||
|
} else if (1.0 <= h && h < 2.0) {
|
||||||
|
color = vec3(x, c, 0.0);
|
||||||
|
} else if (2.0 <= h && h < 3.0) {
|
||||||
|
color = vec3(0.0, c, x);
|
||||||
|
} else if (3.0 <= h && h < 4.0) {
|
||||||
|
color = vec3(0.0, x, c);
|
||||||
|
} else if (4.0 <= h && h < 5.0) {
|
||||||
|
color = vec3(x, 0.0, c);
|
||||||
|
} else if (5.0 <= h && h < 6.0) {
|
||||||
|
color = vec3(c, 0.0, x);
|
||||||
|
} else {
|
||||||
|
color = vec3(0.0, 0.0, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
color.rgb += v - c;
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main () {
|
||||||
|
gl_Position = mProjection*mView*mWorld*vec4(vp, 1.0);
|
||||||
|
theColor = hsv_to_rgb(vp.z, 1, 1); //vec3(1.0, 1.0, 1.0);
|
||||||
|
}
|
||||||
123
src/AudioPlayer.cpp
Normal file
123
src/AudioPlayer.cpp
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 02.07.15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "AudioPlayer.h"
|
||||||
|
#include "WavSource.h"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int streamCallback(const void* input,
|
||||||
|
void* output,
|
||||||
|
unsigned long framesPerBuffer,
|
||||||
|
const PaStreamCallbackTimeInfo *timeInfo,
|
||||||
|
PaStreamCallbackFlags flags,
|
||||||
|
void* data) {
|
||||||
|
AudioPlayer* player = (AudioPlayer*)data;
|
||||||
|
return player->streamCallback(input, output, framesPerBuffer, timeInfo, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void streamFinishedCallback(void *data) {
|
||||||
|
AudioPlayer* player = (AudioPlayer*)data;
|
||||||
|
player->streamFinishedCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PA_CHECK_ERROR(err) \
|
||||||
|
if (err != PaErrorCode::paNoError) { \
|
||||||
|
throw std::runtime_error(Pa_GetErrorText(err)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioPlayer::AudioPlayer(std::string path) {
|
||||||
|
_sndSource = openSoundFile(path);
|
||||||
|
|
||||||
|
PaError err = Pa_Initialize();
|
||||||
|
PA_CHECK_ERROR(err);
|
||||||
|
|
||||||
|
PaStreamParameters outParam;
|
||||||
|
outParam.device = Pa_GetDefaultOutputDevice();
|
||||||
|
if (outParam.device == paNoDevice) {
|
||||||
|
throw std::runtime_error("Haven't found an audio device!");
|
||||||
|
}
|
||||||
|
|
||||||
|
outParam.channelCount = _sndSource->getChannelCount();
|
||||||
|
outParam.sampleFormat = paFloat32;
|
||||||
|
outParam.suggestedLatency = Pa_GetDeviceInfo(outParam.device)->defaultLowOutputLatency;
|
||||||
|
outParam.hostApiSpecificStreamInfo = nullptr;
|
||||||
|
|
||||||
|
err = Pa_OpenStream(&_stream, NULL, &outParam, _sndSource->getSampleRate(),
|
||||||
|
/*paFramesPerBufferUnspecified*/1024, paClipOff,
|
||||||
|
::streamCallback, this);
|
||||||
|
PA_CHECK_ERROR(err);
|
||||||
|
|
||||||
|
err = Pa_SetStreamFinishedCallback(_stream, ::streamFinishedCallback);
|
||||||
|
PA_CHECK_ERROR(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioPlayer::~AudioPlayer() {
|
||||||
|
try {
|
||||||
|
stop();
|
||||||
|
|
||||||
|
PaError err = Pa_CloseStream(_stream);
|
||||||
|
PA_CHECK_ERROR(err);
|
||||||
|
|
||||||
|
err = Pa_Terminate();
|
||||||
|
PA_CHECK_ERROR(err);
|
||||||
|
} catch (std::exception& ex) {
|
||||||
|
std::cout << "AudioPlayer destructor exception: " << ex.what() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_sndSource) {
|
||||||
|
delete _sndSource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ISndSource *AudioPlayer::openSoundFile(std::string path) {
|
||||||
|
std::string ext = path.substr(path.find_last_of(".") + 1);
|
||||||
|
|
||||||
|
if(ext == "wav") {
|
||||||
|
return new WavSource(path);
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error("unsupported sound file format");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int AudioPlayer::streamCallback(const void* input,
|
||||||
|
void* output,
|
||||||
|
unsigned long framesPerBuffer,
|
||||||
|
const PaStreamCallbackTimeInfo *timeInfo,
|
||||||
|
PaStreamCallbackFlags flags) {
|
||||||
|
|
||||||
|
_sndSource->readData(framesPerBuffer, output);
|
||||||
|
|
||||||
|
if(_streamListener) {
|
||||||
|
_streamListener(output, framesPerBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return paContinue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioPlayer::streamFinishedCallback() {
|
||||||
|
if(_streamFinishedLitener) {
|
||||||
|
_streamFinishedLitener();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioPlayer::play() {
|
||||||
|
PaError err = Pa_StartStream(_stream);
|
||||||
|
PA_CHECK_ERROR(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioPlayer::stop() {
|
||||||
|
PaError err = Pa_StopStream(_stream);
|
||||||
|
PA_CHECK_ERROR(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioPlayer::setStreamListener(std::function<void(void*,std::size_t)> callback) {
|
||||||
|
_streamListener = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioPlayer::setStreamFinishedListener(std::function<void()> callback) {
|
||||||
|
_streamFinishedLitener = callback;
|
||||||
|
}
|
||||||
39
src/AudioPlayer.h
Normal file
39
src/AudioPlayer.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 02.07.15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef GLTEST_AUDIOPLAYER_H
|
||||||
|
#define GLTEST_AUDIOPLAYER_H
|
||||||
|
|
||||||
|
#include "ISndSource.h"
|
||||||
|
#include <portaudio.h>
|
||||||
|
#include <string>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
class AudioPlayer {
|
||||||
|
private:
|
||||||
|
ISndSource* _sndSource;
|
||||||
|
PaStream* _stream;
|
||||||
|
std::function<void(void*,std::size_t)> _streamListener;
|
||||||
|
std::function<void()> _streamFinishedLitener;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AudioPlayer(std::string path);
|
||||||
|
~AudioPlayer();
|
||||||
|
void play();
|
||||||
|
void stop();
|
||||||
|
void setStreamListener(std::function<void(void*,std::size_t)> callback);
|
||||||
|
void setStreamFinishedListener(std::function<void()> callback);
|
||||||
|
int streamCallback(const void* input,
|
||||||
|
void* output,
|
||||||
|
unsigned long framesPerBuffer,
|
||||||
|
const PaStreamCallbackTimeInfo *timeInfo,
|
||||||
|
PaStreamCallbackFlags flags);
|
||||||
|
void streamFinishedCallback();
|
||||||
|
|
||||||
|
private:
|
||||||
|
ISndSource* openSoundFile(std::string path);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //GLTEST_AUDIOPLAYER_H
|
||||||
77
src/GLObject.cpp
Normal file
77
src/GLObject.cpp
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 31.05.15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "GLObject.h"
|
||||||
|
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
GLObject::GLObject(ShaderProgram *shaderProgram): _sp(shaderProgram) {
|
||||||
|
}
|
||||||
|
|
||||||
|
GLObject::~GLObject() {
|
||||||
|
glDeleteBuffers(1, &_vertexVbo);
|
||||||
|
glDeleteBuffers(1, &_indexVbo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLObject::create() {
|
||||||
|
auto vData = generateVertices();
|
||||||
|
auto iData = generateIndices();
|
||||||
|
|
||||||
|
GLuint vbo[2];
|
||||||
|
glGenBuffers(2, vbo);
|
||||||
|
_vertexVbo = vbo[0];
|
||||||
|
_indexVbo = vbo[1];
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _vertexVbo);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, std::get<1>(vData), std::get<0>(vData), GL_STREAM_DRAW);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexVbo);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, std::get<1>(iData), std::get<0>(iData), GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
_trianglesCount = std::get<1>(iData)/sizeof(GLuint);
|
||||||
|
|
||||||
|
glGenVertexArrays(1, &_vao);
|
||||||
|
glBindVertexArray(_vao);
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _vertexVbo);
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), nullptr);
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(float), (GLchar*)(3*sizeof(float)));
|
||||||
|
|
||||||
|
delete[] std::get<0>(vData);
|
||||||
|
delete[] std::get<0>(iData);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLObject::rotate(glm::vec3 angles) {
|
||||||
|
GLint world = glGetUniformLocation(*_sp, "mWorld");
|
||||||
|
_worldMatrix = glm::rotate(_worldMatrix, angles.x, glm::vec3(1.0f, 0.0f, 0.0f));
|
||||||
|
_worldMatrix = glm::rotate(_worldMatrix, angles.y, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
|
_worldMatrix = glm::rotate(_worldMatrix, angles.z, glm::vec3(0.0f, 0.0f, 1.0f));
|
||||||
|
glUniformMatrix4fv(world, 1, GL_FALSE, glm::value_ptr(_worldMatrix));
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLObject::scale(glm::vec3 scaleFactor) {
|
||||||
|
GLint world = glGetUniformLocation(*_sp, "mWorld");
|
||||||
|
_worldMatrix = glm::scale(_worldMatrix, scaleFactor);
|
||||||
|
glUniformMatrix4fv(world, 1, GL_FALSE, glm::value_ptr(_worldMatrix));
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLObject::translate(glm::vec3 point) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLObject::draw() {
|
||||||
|
_worldMatrix = glm::mat4();
|
||||||
|
glBindVertexArray(_vao);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexVbo);
|
||||||
|
glDrawElements(GL_TRIANGLES, _trianglesCount, GL_UNSIGNED_INT, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLObject::update() {
|
||||||
|
auto vData = generateVertices();
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _vertexVbo);
|
||||||
|
// glBufferData(GL_ARRAY_BUFFER, _size*_size*sizeof(Vertex), NULL, GL_STREAM_DRAW);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, std::get<1>(vData), std::get<0>(vData), GL_STREAM_DRAW);
|
||||||
|
delete[] std::get<0>(vData);
|
||||||
|
}
|
||||||
41
src/GLObject.h
Normal file
41
src/GLObject.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 31.05.15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef GLTEST_GLOBJECT_H
|
||||||
|
#define GLTEST_GLOBJECT_H
|
||||||
|
|
||||||
|
#include "IGLObject.h"
|
||||||
|
#include "ShaderProgram.h"
|
||||||
|
#include "vertex.h"
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
class GLObject: public IGLObject {
|
||||||
|
private:
|
||||||
|
GLuint _vertexVbo;
|
||||||
|
GLuint _indexVbo;
|
||||||
|
GLuint _vao;
|
||||||
|
glm::mat4 _worldMatrix;
|
||||||
|
ShaderProgram* _sp;
|
||||||
|
GLuint _trianglesCount;
|
||||||
|
|
||||||
|
public:
|
||||||
|
GLObject(ShaderProgram *shaderProgram);
|
||||||
|
virtual ~GLObject();
|
||||||
|
|
||||||
|
void create() override final;
|
||||||
|
void rotate(glm::vec3 angles) override final;
|
||||||
|
void scale(glm::vec3 scaleFactor) override final;
|
||||||
|
void translate(glm::vec3 point) override final;
|
||||||
|
void draw() override final;
|
||||||
|
void update();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual std::tuple<Vertex*, std::size_t> generateVertices() const = 0;
|
||||||
|
virtual std::tuple<GLuint*, std::size_t> generateIndices() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //GLTEST_GLOBJECT_H
|
||||||
18
src/IGLObject.h
Normal file
18
src/IGLObject.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 31.05.15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef GLTEST_IGLOBJECT_H
|
||||||
|
#define GLTEST_IGLOBJECT_H
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
struct IGLObject {
|
||||||
|
virtual void create() = 0;
|
||||||
|
virtual void rotate(glm::vec3 angles) = 0;
|
||||||
|
virtual void scale(glm::vec3 scaleFactor) = 0;
|
||||||
|
virtual void translate(glm::vec3 point) = 0;
|
||||||
|
virtual void draw() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //GLTEST_IGLOBJECT_H
|
||||||
15
src/ISndSource.h
Normal file
15
src/ISndSource.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 02.07.15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef GLTEST_ISNDSOURCE_H
|
||||||
|
#define GLTEST_ISNDSOURCE_H
|
||||||
|
|
||||||
|
struct ISndSource {
|
||||||
|
virtual int getChannelCount() const = 0;
|
||||||
|
virtual int getSampleRate() const = 0;
|
||||||
|
virtual void readData(unsigned long frameCount, void* output) const = 0;
|
||||||
|
virtual ~ISndSource() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //GLTEST_ISNDSOURCE_H
|
||||||
55
src/Mesh.cpp
Normal file
55
src/Mesh.cpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
//
|
||||||
|
// Created by Selim Mustafaev on 10.05.15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Mesh.h"
|
||||||
|
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
Mesh::Mesh(ShaderProgram* shader, std::size_t size) : _size(size), GLObject(shader) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Mesh::~Mesh() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::tuple<Vertex *, std::size_t> Mesh::generateVertices() const {
|
||||||
|
std::size_t u = _size, v = _size;
|
||||||
|
Vertex* retVal = new Vertex[u*v];
|
||||||
|
for (std::size_t i = 0; i < u; i++)
|
||||||
|
for (std::size_t j = 0; j < v; j++)
|
||||||
|
{
|
||||||
|
Vertex vertex;
|
||||||
|
float x=(float)i/(float)u-0.5f;
|
||||||
|
float y=(float)j/(float)v-0.5f;
|
||||||
|
retVal[j*u+i].coords[0] = x*3;
|
||||||
|
retVal[j*u+i].coords[1] = y*3;
|
||||||
|
retVal[j*u+i].coords[2] = heightMapFunc(j, i, x, y);
|
||||||
|
retVal[j*u+i].normal[0] = 1.0f;
|
||||||
|
retVal[j*u+i].normal[1] = 1.0f;
|
||||||
|
retVal[j*u+i].normal[2] = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_tuple(retVal, u*v*sizeof(Vertex));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::tuple<GLuint *, std::size_t> Mesh::generateIndices() const {
|
||||||
|
unsigned u = _size, v = _size;
|
||||||
|
unsigned int* indices = new unsigned int[(u-1)*(v-1)*6];
|
||||||
|
for (unsigned i = 0; i < (u - 1); i++)
|
||||||
|
for (unsigned j = 0; j < (v - 1); j++)
|
||||||
|
{
|
||||||
|
unsigned int indexa=j*(u-1)+i;
|
||||||
|
unsigned int indexb=j*u+i;
|
||||||
|
indices[indexa*6+0]=indexb;
|
||||||
|
indices[indexa*6+1]=indexb+1+u;
|
||||||
|
indices[indexa*6+2]=indexb+1;
|
||||||
|
|
||||||
|
indices[indexa*6+3]=indexb;
|
||||||
|
indices[indexa*6+4]=indexb+u;
|
||||||
|
indices[indexa*6+5]=indexb+u+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_tuple(indices, (u-1)*(v-1)*6*sizeof(GLuint));
|
||||||
|
}
|
||||||
34
src/Mesh.h
Normal file
34
src/Mesh.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
//
|
||||||
|
// Created by Selim Mustafaev on 10.05.15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef GLTEST_MESH_H
|
||||||
|
#define GLTEST_MESH_H
|
||||||
|
|
||||||
|
#include "vertex.h"
|
||||||
|
#include "ShaderProgram.h"
|
||||||
|
#include "GLObject.h"
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
class Mesh: public GLObject {
|
||||||
|
protected:
|
||||||
|
std::size_t _size;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Mesh(ShaderProgram* shader, std::size_t size);
|
||||||
|
virtual ~Mesh();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::tuple<Vertex*, std::size_t> generateVertices() const override final;
|
||||||
|
std::tuple<GLuint*, std::size_t> generateIndices() const override final;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual float heightMapFunc(std::size_t nx, std::size_t ny, float fx, float fy) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //GLTEST_MESH_H
|
||||||
83
src/ShaderProgram.cpp
Normal file
83
src/ShaderProgram.cpp
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
//
|
||||||
|
// Created by Selim Mustafaev on 07.05.15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <cstring>
|
||||||
|
#include "ShaderProgram.h"
|
||||||
|
|
||||||
|
ShaderProgram::ShaderProgram(const char* vertexShaderPath, const char* fragmentShaderPath) {
|
||||||
|
FILE* f = fopen(vertexShaderPath, "rb");
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
long fsize = ftell(f);
|
||||||
|
fseek(f, 0, SEEK_SET);
|
||||||
|
_vertexShaderText = new char[fsize + 1];
|
||||||
|
fread(_vertexShaderText, fsize, 1, f);
|
||||||
|
fclose(f);
|
||||||
|
_vertexShaderText[fsize] = 0;
|
||||||
|
|
||||||
|
_vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
glShaderSource(_vertexShader, 1, (const GLchar**)&_vertexShaderText, nullptr);
|
||||||
|
glCompileShader(_vertexShader);
|
||||||
|
|
||||||
|
GLint success = GL_TRUE;
|
||||||
|
glGetShaderiv(_vertexShader, GL_COMPILE_STATUS, &success);
|
||||||
|
if(success == GL_FALSE) {
|
||||||
|
std::cout << "error compilling vertex shader" << std::endl;
|
||||||
|
logCompileError(_vertexShader);
|
||||||
|
}
|
||||||
|
|
||||||
|
f = fopen(fragmentShaderPath, "rb");
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
fsize = ftell(f);
|
||||||
|
fseek(f, 0, SEEK_SET);
|
||||||
|
_fragmentShaderText = new char[fsize + 1];
|
||||||
|
fread(_fragmentShaderText, fsize, 1, f);
|
||||||
|
fclose(f);
|
||||||
|
_fragmentShaderText[fsize] = 0;
|
||||||
|
|
||||||
|
_fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
glShaderSource(_fragmentShader, 1,(const GLchar**)&_fragmentShaderText, nullptr);
|
||||||
|
glCompileShader(_fragmentShader);
|
||||||
|
|
||||||
|
glGetShaderiv(_fragmentShader, GL_COMPILE_STATUS, &success);
|
||||||
|
if(success == GL_FALSE) {
|
||||||
|
std::cout << "error compilling fragment shader" << std::endl;
|
||||||
|
logCompileError(_fragmentShader);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_program = glCreateProgram();
|
||||||
|
glAttachShader(_program, _vertexShader);
|
||||||
|
glAttachShader(_program, _fragmentShader);
|
||||||
|
glLinkProgram(_program);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderProgram::use() const {
|
||||||
|
glUseProgram(_program);
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderProgram::~ShaderProgram() {
|
||||||
|
delete[] _vertexShaderText;
|
||||||
|
delete[] _fragmentShaderText;
|
||||||
|
|
||||||
|
glDeleteShader(_vertexShader);
|
||||||
|
glDeleteShader(_fragmentShader);
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderProgram::operator GLuint() const {
|
||||||
|
return _program;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderProgram::logCompileError(GLuint shader) {
|
||||||
|
std::cout << "shader: " << shader << std::endl;
|
||||||
|
GLint logSize = 0;
|
||||||
|
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize);
|
||||||
|
std::cout << "log length: " << logSize << std::endl;
|
||||||
|
|
||||||
|
GLchar* log = new GLchar[logSize];
|
||||||
|
memset(log, 0, (size_t)logSize);
|
||||||
|
|
||||||
|
glGetShaderInfoLog(shader, logSize, &logSize, log);
|
||||||
|
std::cout << "log: " << log << std::endl;
|
||||||
|
}
|
||||||
31
src/ShaderProgram.h
Normal file
31
src/ShaderProgram.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
//
|
||||||
|
// Created by Selim Mustafaev on 07.05.15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef GLTEST_SHADERPROGRAM_H
|
||||||
|
#define GLTEST_SHADERPROGRAM_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class ShaderProgram {
|
||||||
|
private:
|
||||||
|
GLuint _program;
|
||||||
|
GLuint _vertexShader;
|
||||||
|
GLuint _fragmentShader;
|
||||||
|
char* _vertexShaderText;
|
||||||
|
char* _fragmentShaderText;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ShaderProgram(const char* vertexShaderPath, const char* fragmentShaderPath);
|
||||||
|
void use() const;
|
||||||
|
operator GLuint() const;
|
||||||
|
~ShaderProgram();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void logCompileError(GLuint shader);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //GLTEST_SHADERPROGRAM_H
|
||||||
47
src/SpectralMesh.cpp
Normal file
47
src/SpectralMesh.cpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 07.07.15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "SpectralMesh.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
SpectralMesh::SpectralMesh(ShaderProgram *shader, std::size_t size): Mesh(shader, size) {
|
||||||
|
_data = new float[size*size];
|
||||||
|
_spectrLine = new float[2*size];
|
||||||
|
_spectrLineComplex = (fftwf_complex*)fftwf_malloc((_size + 1)*sizeof(fftwf_complex));
|
||||||
|
}
|
||||||
|
|
||||||
|
SpectralMesh::~SpectralMesh() {
|
||||||
|
delete[] _data;
|
||||||
|
delete[] _spectrLine;
|
||||||
|
fftwf_free(_spectrLineComplex);
|
||||||
|
}
|
||||||
|
|
||||||
|
float SpectralMesh::heightMapFunc(std::size_t nx, std::size_t ny, float fx, float fy) const {
|
||||||
|
return *(_data + _size*nx + ny);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpectralMesh::addLine(float *line) {
|
||||||
|
|
||||||
|
for(std::size_t i = 0; i < 2*_size; ++i) {
|
||||||
|
_spectrLine[i] = line[2*i];
|
||||||
|
}
|
||||||
|
|
||||||
|
fftwf_plan plan = fftwf_plan_dft_r2c_1d(2*_size, _spectrLine, _spectrLineComplex, FFTW_ESTIMATE);
|
||||||
|
fftwf_execute(plan);
|
||||||
|
|
||||||
|
for(std::size_t i = 0; i < _size; ++i) {
|
||||||
|
float real = _spectrLineComplex[i][0], imag = _spectrLineComplex[i][1];
|
||||||
|
_spectrLine[i] = 0.1*log10f(sqrtf(real*real + imag*imag)) + 0.1f;
|
||||||
|
if(_spectrLine[i] < 0) {
|
||||||
|
_spectrLine[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memmove(_data + _size, _data, _size*(_size - 1)*sizeof(float));
|
||||||
|
memcpy(_data, _spectrLine, _size*sizeof(float));
|
||||||
|
|
||||||
|
fftwf_destroy_plan(plan);
|
||||||
|
}
|
||||||
28
src/SpectralMesh.h
Normal file
28
src/SpectralMesh.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 07.07.15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef GLTEST_SPECTRALMESH_H
|
||||||
|
#define GLTEST_SPECTRALMESH_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "Mesh.h"
|
||||||
|
#include <fftw3.h>
|
||||||
|
|
||||||
|
class SpectralMesh: public Mesh {
|
||||||
|
private:
|
||||||
|
float* _data;
|
||||||
|
float* _spectrLine;
|
||||||
|
fftwf_complex* _spectrLineComplex;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SpectralMesh(ShaderProgram* shader, std::size_t size);
|
||||||
|
~SpectralMesh();
|
||||||
|
void addLine(float* line);
|
||||||
|
|
||||||
|
private:
|
||||||
|
float heightMapFunc(std::size_t nx, std::size_t ny, float fx, float fy) const override final;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //GLTEST_SPECTRALMESH_H
|
||||||
37
src/WavSource.cpp
Normal file
37
src/WavSource.cpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 02.07.15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include "WavSource.h"
|
||||||
|
|
||||||
|
WavSource::WavSource(std::string path) {
|
||||||
|
_file = sf_open(path.c_str(), SFM_READ, &_info);
|
||||||
|
if(!_file) {
|
||||||
|
throw std::runtime_error(sf_strerror(nullptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
WavSource::~WavSource() {
|
||||||
|
int err = sf_close(_file);
|
||||||
|
if(err) {
|
||||||
|
std::cout << "close sound file error: " << err << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "WavSource::~WavSource()" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WavSource::getChannelCount() const {
|
||||||
|
return _info.channels;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WavSource::getSampleRate() const {
|
||||||
|
return _info.samplerate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WavSource::readData(unsigned long frameCount, void *output) const {
|
||||||
|
sf_read_float(_file, (float*)output, frameCount*_info.channels);
|
||||||
|
}
|
||||||
28
src/WavSource.h
Normal file
28
src/WavSource.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 02.07.15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef GLTEST_WAVSOURCE_H
|
||||||
|
#define GLTEST_WAVSOURCE_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <sndfile.h>
|
||||||
|
#include "ISndSource.h"
|
||||||
|
|
||||||
|
class WavSource: public ISndSource {
|
||||||
|
private:
|
||||||
|
SNDFILE* _file;
|
||||||
|
SF_INFO _info;
|
||||||
|
|
||||||
|
public:
|
||||||
|
WavSource(std::string path);
|
||||||
|
~WavSource();
|
||||||
|
|
||||||
|
public:
|
||||||
|
int getChannelCount() const override final;
|
||||||
|
int getSampleRate() const override final;
|
||||||
|
void readData(unsigned long frameCount, void* output) const override final;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //GLTEST_WAVSOURCE_H
|
||||||
19
src/WaveMesh.cpp
Normal file
19
src/WaveMesh.cpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 31.05.15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "WaveMesh.h"
|
||||||
|
|
||||||
|
float WaveMesh::heightMapFunc(std::size_t nx, std::size_t ny, float fx, float fy) const {
|
||||||
|
double d = 50*sqrt(fx*fx + fy*fy);
|
||||||
|
return static_cast<float>(cos(d - _shift)*exp(-d/10.0f)/2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaveMesh::setShift(float shift) {
|
||||||
|
_shift = shift;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
WaveMesh::WaveMesh(ShaderProgram *shader, std::size_t size): Mesh(shader, size), _shift(0) {
|
||||||
|
|
||||||
|
}
|
||||||
23
src/WaveMesh.h
Normal file
23
src/WaveMesh.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 31.05.15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef GLTEST_WAVEMESH_H
|
||||||
|
#define GLTEST_WAVEMESH_H
|
||||||
|
|
||||||
|
#include "Mesh.h"
|
||||||
|
|
||||||
|
class WaveMesh: public Mesh {
|
||||||
|
private:
|
||||||
|
float _shift;
|
||||||
|
|
||||||
|
public:
|
||||||
|
WaveMesh(ShaderProgram* shader, std::size_t size);
|
||||||
|
void setShift(float shift);
|
||||||
|
|
||||||
|
private:
|
||||||
|
float heightMapFunc(std::size_t nx, std::size_t ny, float fx, float fy) const override final;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //GLTEST_WAVEMESH_H
|
||||||
128
src/main.cpp
Normal file
128
src/main.cpp
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
#include <GL/glew.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#include "ShaderProgram.h"
|
||||||
|
#include "WaveMesh.h"
|
||||||
|
#include "AudioPlayer.h"
|
||||||
|
#include "SpectralMesh.h"
|
||||||
|
|
||||||
|
#include <portaudio.h>
|
||||||
|
#include <sndfile.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
glm::vec3 eye(0.0f, 0.0f, 4.0f), at(0.0f, 0.0f, 0.0f), up(0.0f, 1.0f, 0.0f);
|
||||||
|
glm::mat4 mView = glm::lookAt(eye, at, up);
|
||||||
|
glm::mat4 mProjection = glm::perspective(45.0f, 1.0f, 2.0f, -2.0f);
|
||||||
|
bool wired = false;
|
||||||
|
|
||||||
|
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
||||||
|
{
|
||||||
|
if (key == GLFW_KEY_M && action == GLFW_PRESS) {
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, wired ? GL_FILL : GL_LINE);
|
||||||
|
wired = !wired;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _update_fps_counter (GLFWwindow* window) {
|
||||||
|
static double previous_seconds = glfwGetTime ();
|
||||||
|
static int frame_count;
|
||||||
|
double current_seconds = glfwGetTime ();
|
||||||
|
double elapsed_seconds = current_seconds - previous_seconds;
|
||||||
|
if (elapsed_seconds > 0.25) {
|
||||||
|
previous_seconds = current_seconds;
|
||||||
|
double fps = (double)frame_count / elapsed_seconds;
|
||||||
|
char tmp[128];
|
||||||
|
sprintf (tmp, "opengl @ fps: %.2f", fps);
|
||||||
|
glfwSetWindowTitle (window, tmp);
|
||||||
|
frame_count = 0;
|
||||||
|
}
|
||||||
|
frame_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
glfwInit();
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||||
|
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
|
||||||
|
glfwWindowHint (GLFW_SAMPLES, 4);
|
||||||
|
|
||||||
|
GLFWwindow* window = glfwCreateWindow(1024, 1024, "OpenGL", nullptr, nullptr); // Windowed
|
||||||
|
glfwMakeContextCurrent(window);
|
||||||
|
glfwSetKeyCallback(window, key_callback);
|
||||||
|
|
||||||
|
glewExperimental = GL_TRUE;
|
||||||
|
GLenum err = glewInit();
|
||||||
|
if(err != GLEW_OK) {
|
||||||
|
std::cout << "GLEW error: " << err << ": " << glewGetErrorString(err) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderProgram program("../shaders/vertex.glsl", "../shaders/fragment.glsl");
|
||||||
|
program.use();
|
||||||
|
|
||||||
|
// WaveMesh mesh(&program, 128);
|
||||||
|
// mesh.create();
|
||||||
|
|
||||||
|
SpectralMesh mesh(&program, 256);
|
||||||
|
mesh.create();
|
||||||
|
|
||||||
|
GLint view = glGetUniformLocation(program, "mView");
|
||||||
|
glUniformMatrix4fv(view, 1, GL_FALSE, glm::value_ptr(mView));
|
||||||
|
GLint projection = glGetUniformLocation(program, "mProjection");
|
||||||
|
glUniformMatrix4fv(projection, 1, GL_FALSE, glm::value_ptr(mProjection));
|
||||||
|
|
||||||
|
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||||
|
glDepthFunc(GL_LEQUAL);
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
AudioPlayer player("/home/selim/dl/euphoria.wav");
|
||||||
|
player.setStreamListener([&mesh](void* data, std::size_t framesCount){
|
||||||
|
mesh.addLine((float*)data);
|
||||||
|
});
|
||||||
|
player.play();
|
||||||
|
|
||||||
|
float azimuth = 0.0f, elevation = 0.0f, scale = 1.0f;
|
||||||
|
|
||||||
|
while(!glfwWindowShouldClose(window)) {
|
||||||
|
_update_fps_counter (window);
|
||||||
|
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
if(glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS) {
|
||||||
|
azimuth -= 0.05f;
|
||||||
|
} else if(glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) {
|
||||||
|
azimuth += 0.05f;
|
||||||
|
} else if(glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) {
|
||||||
|
elevation -= 0.05f;
|
||||||
|
} else if(glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS) {
|
||||||
|
elevation += 0.05f;
|
||||||
|
} else if(glfwGetKey(window, GLFW_KEY_KP_ADD) == GLFW_PRESS) {
|
||||||
|
scale += 0.05f;
|
||||||
|
} else if(glfwGetKey(window, GLFW_KEY_KP_SUBTRACT) == GLFW_PRESS) {
|
||||||
|
scale -= 0.05f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// double time = glfwGetTime();
|
||||||
|
// float shift = (float)fmod(time, 2*3.1415926);
|
||||||
|
// mesh.setShift(shift*2);
|
||||||
|
mesh.update();
|
||||||
|
|
||||||
|
|
||||||
|
mesh.scale(glm::vec3(scale, scale, scale));
|
||||||
|
mesh.rotate(glm::vec3(elevation, azimuth, 0));
|
||||||
|
mesh.draw();
|
||||||
|
|
||||||
|
glfwPollEvents();
|
||||||
|
glfwSwapBuffers(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwTerminate();
|
||||||
|
}
|
||||||
13
src/vertex.h
Normal file
13
src/vertex.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 31.05.15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef GLTEST_VERTEX_H
|
||||||
|
#define GLTEST_VERTEX_H
|
||||||
|
|
||||||
|
struct Vertex {
|
||||||
|
float coords[3];
|
||||||
|
float normal[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //GLTEST_VERTEX_H
|
||||||
Loading…
Reference in New Issue
Block a user