diff --git a/.travis.yml b/.travis.yml index 8235a6e95..87f01f926 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,8 +6,8 @@ before_install: # TODO: test different combinations of flags, --enable-sdl, --enable-qt, etc script: - - ./configure --enable-sdl --enable-ftgl --prefix=$PWD/local && make -j8 && make install # build from checkout - - make dist && tar -zxf projectM-*.tar.gz && cd projectM-* && ./configure --enable-sdl --enable-ftgl --prefix=$PWD/dist_install && make -j8 && make install # build from dist + - ./configure --enable-sdl --prefix=$PWD/local && make -j8 && make install # build from checkout + - make dist && tar -zxf projectM-*.tar.gz && cd projectM-* && ./configure --enable-sdl --prefix=$PWD/dist_install && make -j8 && make install # build from dist - echo "PWD $PWD" - ls . - test -e src/projectM-sdl/projectMSDL @@ -36,6 +36,7 @@ matrix: - libftgl-dev - libsdl2-dev - libdevil-dev + - libglm-dev env: - MATRIX_EVAL="CC=clang-5.0 && CXX=clang++-5.0" # linux/gcc @@ -51,6 +52,7 @@ matrix: - libftgl-dev - libsdl2-dev - libdevil-dev + - libglm-dev env: - MATRIX_EVAL="CC=gcc-7 && CXX=g++-7" @@ -58,7 +60,7 @@ matrix: - os: osx osx_image: xcode8 env: - - MATRIX_EVAL="brew update && brew install sdl2 && brew install ftgl" + - MATRIX_EVAL="brew update && brew install sdl2 ftgl glm" notifications: email: diff --git a/Makefile.am b/Makefile.am index 062bb3ca1..19dbef1fd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -19,8 +19,8 @@ pm_shaders__DATA = src/libprojectM/Renderer/blur.cg \ # find and install all preset files install-data-local: - test -z $(pkgdatadir) || $(MKDIR_P) $(pm_presets_dir) - find "$(PRESETSDIR)" -type f -exec $(INSTALL_DATA) {} $(pm_presets_dir) \; + test -z $(DESTDIR)$(pkgdatadir) || $(MKDIR_P) $(DESTDIR)$(pm_presets_dir) + find "$(PRESETSDIR)" -type f -exec $(INSTALL_DATA) {} $(DESTDIR)$(pm_presets_dir) \; # from https://stackoverflow.com/questions/30897170/ac-subst-does-not-expand-variable answer: https://stackoverflow.com/a/30960268 # ptomato https://stackoverflow.com/users/172999/ptomato diff --git a/README.md b/README.md index 2c7a0a50c..0ad4c9080 100644 --- a/README.md +++ b/README.md @@ -61,13 +61,13 @@ Silverjuke (FOSS Jukebox) ``` ## Linux (debian/ubuntu) -* `sudo apt-get install autoconf libtool libsdl2-dev libglew-dev libftgl-dev libsdl2-dev libdevil-dev` +* `sudo apt-get install autoconf libtool libsdl2-dev libglew-dev libftgl-dev libsdl2-dev libdevil-dev libglm-dev` ## FreeBSD -* `pkg install gcc autoconf automake libtool mesa-libs libGLU sdl2` +* `pkg install gcc autoconf automake libtool mesa-libs libGLU sdl2 glm` ## Mac OS X -* Install the [SDL2 Framework](https://www.libsdl.org/download-2.0.php) +* `brew install glm sdl2` * `./configure --enable-sdl` diff --git a/configure.ac b/configure.ac index 25332b1c6..8c32eb6c1 100644 --- a/configure.ac +++ b/configure.ac @@ -5,6 +5,7 @@ m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) LT_INIT AC_PROG_CXX +AC_LANG(C++) AC_CONFIG_MACRO_DIRS([m4 m4/autoconf-archive]) AX_CHECK_GL @@ -56,28 +57,37 @@ AS_IF([test "x$enable_threading" = "xyes"], [ ]) ]) -dnl FTGL -AC_ARG_ENABLE([ftgl], - AS_HELP_STRING([--enable-ftgl], [FTGL support to display text such as preset title, stats, fps, ...]), - [], [enable_ftgl=no]) -AS_IF([test "x$enable_ftgl" = "xyes"], [ - PKG_CHECK_MODULES(FTGL, [ftgl], [], [AC_MSG_ERROR([libftgl is required.])]) - AC_DEFINE([USE_FTGL], [1], [Define USE_FTGL]) +#dnl FTGL +#AC_ARG_ENABLE([ftgl], +# AS_HELP_STRING([--enable-ftgl], [FTGL support to display text such as preset title, stats, fps, ...]), +# [], [enable_ftgl=no]) +#AS_IF([test "x$enable_ftgl" = "xyes"], [ +# PKG_CHECK_MODULES(FTGL, [ftgl], [], [AC_MSG_ERROR([libftgl is required.])]) +# AC_DEFINE([USE_FTGL], [1], [Define USE_FTGL]) +#]) + +AC_CHECK_HEADER([glm/glm.hpp],, AC_MSG_ERROR(libglm is required.)) + +AC_ARG_ENABLE([gles], + AS_HELP_STRING([--enable-gles], [OpenGL ES support]), + [], [enable_gles=no]) + AS_IF([test "x$enable_gles" = "xyes"], [ + AC_DEFINE([USE_GLES], [1], [Define USE_GLES]) ]) dnl Cg framework OSX -- replace with GLSL someday! CG_CFLAGS= CG_LDFLAGS= FRAMEWORK_SEARCH_PATHS="-F/Library/Frameworks -F$HOME/Library/Frameworks" -AC_ARG_ENABLE([cg], -AS_HELP_STRING([--enable-cg], [Cg framework for shaders]), -[], [enable_cg=no]) -AS_IF([test "x$enable_cg" = "xyes"], [ -dnl AC_CHECK_HEADERS([Cg/cg.h], [], [AC_MSG_ERROR([Cg framework not found.])]) -AC_DEFINE([USE_CG], [1], [Define USE_CG]) -CG_LDFLAGS+="$FRAMEWORK_SEARCH_PATHS -framework Cg" -CG_CFLAGS+="$FRAMEWORK_SEARCH_PATHS" -]) +#AC_ARG_ENABLE([cg], +#AS_HELP_STRING([--enable-cg], [Cg framework for shaders]), +#[], [enable_cg=no]) +#AS_IF([test "x$enable_cg" = "xyes"], [ +#dnl AC_CHECK_HEADERS([Cg/cg.h], [], [AC_MSG_ERROR([Cg framework not found.])]) +#AC_DEFINE([USE_CG], [1], [Define USE_CG]) +#CG_LDFLAGS+="$FRAMEWORK_SEARCH_PATHS -framework Cg" +#CG_CFLAGS+="$FRAMEWORK_SEARCH_PATHS" +#]) AC_SUBST([CG_CFLAGS]) AC_SUBST([CG_LDFLAGS]) @@ -167,4 +177,5 @@ SDL: ${enable_sdl} Qt & Pulseaudio: ${enable_qt} FTGL: ${enable_ftgl} Cg: ${enable_cg} +OpenGL ES: ${enable_gles} ]) diff --git a/src/libprojectM/Renderer/FBO.cpp b/src/libprojectM/Renderer/FBO.cpp index 64a097774..7f8efb7ca 100755 --- a/src/libprojectM/Renderer/FBO.cpp +++ b/src/libprojectM/Renderer/FBO.cpp @@ -38,13 +38,13 @@ RenderTarget::~RenderTarget() { if (useFBO) { glDeleteTextures( 1, &this->textureID[1] ); - glDeleteRenderbuffersEXT(1, &this->depthb[0]); - glDeleteFramebuffersEXT(1, &this->fbuffer[0]); + glDeleteRenderbuffers(1, &this->depthb[0]); + glDeleteFramebuffers(1, &this->fbuffer[0]); if(renderToTexture) { glDeleteTextures( 1, &this->textureID[2] ); - glDeleteRenderbuffersEXT(1, &this->depthb[1]); - glDeleteFramebuffersEXT(1, &this->fbuffer[1]); + glDeleteRenderbuffers(1, &this->depthb[1]); + glDeleteFramebuffers(1, &this->fbuffer[1]); } } #endif @@ -57,16 +57,15 @@ GLuint RenderTarget::initRenderToTexture() if (this->useFBO==1) { + if (this->renderToTexture == 1) { + return this->textureID[2]; + } + this->renderToTexture=1; GLuint fb2, depth_rb2; - glGenFramebuffersEXT(1, &fb2); - glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fb2 ); - glGenRenderbuffersEXT(1, &depth_rb2); - glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, depth_rb2 ); - - glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, this->texsize,this->texsize ); - glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_rb2 ); + glGenFramebuffers(1, &fb2); + glBindFramebuffer( GL_FRAMEBUFFER, fb2 ); this->fbuffer[1] = fb2; this->depthb[1]= depth_rb2; glGenTextures(1, &this->textureID[2]); @@ -74,10 +73,17 @@ GLuint RenderTarget::initRenderToTexture() glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, texsize, texsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, this->textureID[2], 0 ); - return this->textureID[2]; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, this->textureID[2], 0 ); + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + + if (status == GL_FRAMEBUFFER_COMPLETE) { + return this->textureID[2]; + } + + std::cerr << "[projecM] warning: initRenderToTexture failed." << std::endl; } #endif return -1; @@ -94,58 +100,48 @@ RenderTarget::RenderTarget(int texsize, int width, int height) : useFBO(false) { this->texsize = texsize; #ifdef USE_FBO - glewInit(); - // Forceably disable FBO if user requested it but the video card / driver lacks - // the appropraite frame buffer extension. - if (useFBO = glewIsSupported("GL_EXT_framebuffer_object")) - { - GLuint fb, depth_rb, rgba_tex, other_tex; - glGenFramebuffersEXT(1, &fb); - glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fb ); - - glGenRenderbuffersEXT(1, &depth_rb); - glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, depth_rb ); - glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, this->texsize,this->texsize ); - glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_rb ); - this->fbuffer[0] = fb; - this->depthb[0]= depth_rb; - - glGenTextures(1, &other_tex); - glBindTexture(GL_TEXTURE_2D,other_tex); - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, texsize, texsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL ); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - //glGenerateMipmapEXT(GL_TEXTURE_2D); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - - - - glGenTextures(1, &rgba_tex); - glBindTexture(GL_TEXTURE_2D, rgba_tex); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, texsize, texsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL ); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - //glGenerateMipmapEXT(GL_TEXTURE_2D); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - - - - glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, rgba_tex, 0 ); - this->textureID[0] = rgba_tex; - this->textureID[1] = other_tex; - - GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + useFBO = true; - glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); + GLuint fb, depth_rb, rgba_tex, other_tex; + glGenFramebuffers(1, &fb); + glBindFramebuffer( GL_FRAMEBUFFER, fb ); - if (status == GL_FRAMEBUFFER_COMPLETE_EXT) { - return; - } - std::cerr << "[projecM] warning: FBO support not detected. Using fallback." << std::endl; - } + this->fbuffer[0] = fb; + this->depthb[0]= depth_rb; + + glGenTextures(1, &other_tex); + glBindTexture(GL_TEXTURE_2D,other_tex); + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, texsize, texsize, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL ); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + //glGenerateMipmapEXT(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + + + glGenTextures(1, &rgba_tex); + glBindTexture(GL_TEXTURE_2D, rgba_tex); + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, texsize, texsize, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL ); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + //glGenerateMipmapEXT(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rgba_tex, 0 ); + this->textureID[0] = rgba_tex; + this->textureID[1] = other_tex; + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + + glBindFramebuffer (GL_FRAMEBUFFER, 0); + + if (status == GL_FRAMEBUFFER_COMPLETE) { + return; + } + std::cerr << "[projecM] warning: FBO support not detected. Using fallback." << std::endl; #endif @@ -171,10 +167,10 @@ RenderTarget::RenderTarget(int texsize, int width, int height) : useFBO(false) { glTexImage2D(GL_TEXTURE_2D, 0, - GL_RGB, + GL_RGB, this->texsize, this->texsize, 0, - GL_RGBA, + GL_RGB, GL_UNSIGNED_BYTE, NULL); @@ -183,46 +179,6 @@ RenderTarget::RenderTarget(int texsize, int width, int height) : useFBO(false) { return; } - void RenderTarget::fallbackRescale(int width, int height) - { - int mindim = width < height ? width : height; - int origtexsize = this->texsize; - this->texsize = nearestPower2( mindim, SCALE_MINIFY ); - - if (origtexsize == texsize) - return; - - /* Create the texture that will be bound to the render this */ - /* - - if ( this->texsize != origtexsize ) { - - glDeleteTextures( 1, &this->textureID[0] ); - } - */ - - glGenTextures(1, &this->textureID[0] ); - - glBindTexture(GL_TEXTURE_2D, this->textureID[0] ); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - glTexImage2D(GL_TEXTURE_2D, - 0, - GL_RGB, - this->texsize, this->texsize, - 0, - GL_RGBA, - GL_UNSIGNED_BYTE, - NULL); - - - } - -/** Destroys the pbuffer */ /** Locks the pbuffer */ void RenderTarget::lock() { @@ -230,7 +186,7 @@ void RenderTarget::lock() { #ifdef USE_FBO if(this->useFBO) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, this->fbuffer[0]); + glBindFramebuffer(GL_FRAMEBUFFER, this->fbuffer[0]); } #endif } @@ -245,7 +201,7 @@ void RenderTarget::unlock() { glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, this->texsize, this->texsize ); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); return; } #endif diff --git a/src/libprojectM/Renderer/FBO.hpp b/src/libprojectM/Renderer/FBO.hpp index 875f26956..158d3f115 100755 --- a/src/libprojectM/Renderer/FBO.hpp +++ b/src/libprojectM/Renderer/FBO.hpp @@ -49,7 +49,6 @@ public: void unlock(); GLuint initRenderToTexture(); int nearestPower2( int value, TextureScale scaleRule ); - void fallbackRescale(int width, int height); /** Opaque pbuffer context and pbuffer */ /* diff --git a/src/libprojectM/Renderer/Filters.cpp b/src/libprojectM/Renderer/Filters.cpp index fd53c73a1..bea1ab5dd 100644 --- a/src/libprojectM/Renderer/Filters.cpp +++ b/src/libprojectM/Renderer/Filters.cpp @@ -8,19 +8,31 @@ #include "Common.hpp" #include "projectM-opengl.h" #include "Filters.hpp" +#include "ShaderEngine.hpp" +#include + +void Brighten::InitVertexAttrib() { + float points[4][2] = {{-0.5, -0.5}, + {-0.5, 0.5}, + { 0.5, 0.5}, + { 0.5, -0.5}}; + + glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); + glDisableVertexAttribArray(1); +} void Brighten::Draw(RenderContext &context) { -#ifndef GL_TRANSITION - float points[4][2] = {{-0.5, -0.5}, - {-0.5, 0.5}, - { 0.5, 0.5}, - { 0.5, -0.5}}; + glUseProgram(context.programID_v2f_c4f); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2,GL_FLOAT,0,points); + glUniformMatrix4fv(ShaderEngine::Uniform_V2F_C4F_VertexTranformation(), 1, GL_FALSE, glm::value_ptr(context.mat_ortho)); - glColor4f(1.0, 1.0, 1.0, 1.0); + glBindVertexArray(m_vaoID); + + glVertexAttrib4f(1, 1.0, 1.0, 1.0, 1.0); glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO); glDrawArrays(GL_TRIANGLE_FAN,0,4); glBlendFunc(GL_ZERO, GL_DST_COLOR); @@ -29,66 +41,98 @@ void Brighten::Draw(RenderContext &context) glDrawArrays(GL_TRIANGLE_FAN,0,4); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisableClientState(GL_VERTEX_ARRAY); -#endif + glBindVertexArray(0); +} + +void Darken::InitVertexAttrib() { + float points[4][2] = {{-0.5, -0.5}, + {-0.5, 0.5}, + { 0.5, 0.5}, + { 0.5, -0.5}}; + + glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); + glDisableVertexAttribArray(1); } void Darken::Draw(RenderContext &context) { -#ifndef GL_TRANSITION - float points[4][2] = {{-0.5, -0.5}, - {-0.5, 0.5}, - { 0.5, 0.5}, - { 0.5, -0.5}}; + glUseProgram(context.programID_v2f_c4f); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2,GL_FLOAT,0,points); - glColor4f(1.0, 1.0, 1.0, 1.0); - glBlendFunc(GL_ZERO, GL_DST_COLOR); - glDrawArrays(GL_TRIANGLE_FAN,0,4); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisableClientState(GL_VERTEX_ARRAY); -#endif + glUniformMatrix4fv(ShaderEngine::Uniform_V2F_C4F_VertexTranformation(), 1, GL_FALSE, glm::value_ptr(context.mat_ortho)); + + glVertexAttrib4f(1, 1.0, 1.0, 1.0, 1.0); + + glBlendFunc(GL_ZERO, GL_DST_COLOR); + + glBindVertexArray(m_vaoID); + glDrawArrays(GL_TRIANGLE_FAN,0,4); + glBindVertexArray(0); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + +void Invert::InitVertexAttrib() { + float points[4][2] = {{-0.5, -0.5}, + {-0.5, 0.5}, + { 0.5, 0.5}, + { 0.5, -0.5}}; + + glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); + glDisableVertexAttribArray(1); } void Invert::Draw(RenderContext &context) { -#ifndef GL_TRANSITION + glUseProgram(context.programID_v2f_c4f); + + glUniformMatrix4fv(ShaderEngine::Uniform_V2F_C4F_VertexTranformation(), 1, GL_FALSE, glm::value_ptr(context.mat_ortho)); + + glVertexAttrib4f(1, 1.0, 1.0, 1.0, 1.0); + + glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO); + + glBindVertexArray(m_vaoID); + glDrawArrays(GL_TRIANGLE_FAN,0,4); + glBindVertexArray(0); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + +void Solarize::InitVertexAttrib() { float points[4][2] = {{-0.5, -0.5}, - {-0.5, 0.5}, - { 0.5, 0.5}, - { 0.5, -0.5}}; + {-0.5, 0.5}, + { 0.5, 0.5}, + { 0.5, -0.5}}; - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2,GL_FLOAT,0,points); - glColor4f(1.0, 1.0, 1.0, 1.0); - glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO); - glDrawArrays(GL_TRIANGLE_FAN,0,4); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW); - glDisableClientState(GL_VERTEX_ARRAY); -#endif + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); + glDisableVertexAttribArray(1); } void Solarize::Draw(RenderContext &context) { -#ifndef GL_TRANSITION - float points[4][2] = {{-0.5, -0.5}, - {-0.5, 0.5}, - { 0.5, 0.5}, - { 0.5, -0.5}}; + glUseProgram(context.programID_v2f_c4f); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2,GL_FLOAT,0,points); + glUniformMatrix4fv(ShaderEngine::Uniform_V2F_C4F_VertexTranformation(), 1, GL_FALSE, glm::value_ptr(context.mat_ortho)); + + glVertexAttrib4f(1, 1.0, 1.0, 1.0, 1.0); - glColor4f(1.0, 1.0, 1.0, 1.0); glBlendFunc(GL_ZERO, GL_ONE_MINUS_DST_COLOR); + + glBindVertexArray(m_vaoID); glDrawArrays(GL_TRIANGLE_FAN,0,4); glBlendFunc(GL_DST_COLOR, GL_ONE); glDrawArrays(GL_TRIANGLE_FAN,0,4); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBindVertexArray(0); - glDisableClientState(GL_VERTEX_ARRAY); -#endif + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } diff --git a/src/libprojectM/Renderer/Filters.hpp b/src/libprojectM/Renderer/Filters.hpp index 6ce64da13..f9ca25aa3 100644 --- a/src/libprojectM/Renderer/Filters.hpp +++ b/src/libprojectM/Renderer/Filters.hpp @@ -13,28 +13,32 @@ class Brighten : public RenderItem { public: - Brighten(){} + Brighten(){ Init(); } + void InitVertexAttrib(); void Draw(RenderContext &context); }; class Darken : public RenderItem { public: - Darken(){} + Darken(){ Init(); } + void InitVertexAttrib(); void Draw(RenderContext &context); }; class Invert : public RenderItem { public: - Invert(){} + Invert(){ Init(); } + void InitVertexAttrib(); void Draw(RenderContext &context); }; class Solarize : public RenderItem { public: - Solarize(){} + Solarize(){ Init(); } + void InitVertexAttrib(); void Draw(RenderContext &context); }; diff --git a/src/libprojectM/Renderer/HLSLTranslator.cpp b/src/libprojectM/Renderer/HLSLTranslator.cpp index 2bd50336f..a07555aa7 100644 --- a/src/libprojectM/Renderer/HLSLTranslator.cpp +++ b/src/libprojectM/Renderer/HLSLTranslator.cpp @@ -173,7 +173,7 @@ std::unique_ptr HLSLTranslator::parse(GLenum shaderType, const char } // generate GLSL - if (!generator.Generate(&tree, GLSLGenerator::Target(shaderType), GLSLGenerator::Version_150, "projectm")) { + if (!generator.Generate(&tree, GLSLGenerator::Target(shaderType), GLSLGenerator::Version, "projectm")) { fprintf(stderr, "Failed to transpile HLSL shader to GLSL\n"); return nullptr; } diff --git a/src/libprojectM/Renderer/Makefile.am b/src/libprojectM/Renderer/Makefile.am index 9219d18f9..8400404d2 100644 --- a/src/libprojectM/Renderer/Makefile.am +++ b/src/libprojectM/Renderer/Makefile.am @@ -46,12 +46,13 @@ libRenderer_la_SOURCES = \ hlslparser/src/HLSLTokenizer.cpp hlslparser/src/HLSLTree.h \ hlslparser/src/Engine.cpp hlslparser/src/GLSLGenerator.h hlslparser/src/HLSLParser.cpp \ hlslparser/src/HLSLTokenizer.h hlslparser/src/MSLGenerator.cpp \ - HLSLTranslator.cpp HLSLTranslator.hpp + HLSLTranslator.cpp HLSLTranslator.hpp libRenderer_la_CPPFLAGS = ${my_CFLAGS} \ --I$(top_srcdir)/src/libprojectM \ --I$(top_srcdir)/src/libprojectM/Renderer/hlslparser/src \ - ${FTGL_CFLAGS} ${CG_CFLAGS} + -include $(top_builddir)/config.h \ + -I$(top_srcdir)/src/libprojectM/Renderer/hlslparser/src \ + -I$(top_srcdir)/src/libprojectM \ + ${FTGL_CFLAGS} ${CG_CFLAGS} libRenderer_la_LDFLAGS = \ ${FTGL_LIBS} ${CG_LDFLAGS} diff --git a/src/libprojectM/Renderer/MilkdropWaveform.cpp b/src/libprojectM/Renderer/MilkdropWaveform.cpp index 3dd7cf2bd..aaaa39b4b 100644 --- a/src/libprojectM/Renderer/MilkdropWaveform.cpp +++ b/src/libprojectM/Renderer/MilkdropWaveform.cpp @@ -10,77 +10,109 @@ #include "MilkdropWaveform.hpp" #include "math.h" #include "BeatDetect.hpp" +#include "ShaderEngine.hpp" +#include MilkdropWaveform::MilkdropWaveform(): RenderItem(), x(0.5), y(0.5), r(1), g(0), b(0), a(1), mystery(0), mode(Line), scale(10), smoothing(0), rot(0), samples(0),modOpacityStart(0),modOpacityEnd(1), - modulateAlphaByVolume(false), maximizeColors(false), additive(false), dots(false), thick(false), loop(false) { - glGenBuffers(1, &wave1VBO); - glGenBuffers(1, &wave2VBO); - } + modulateAlphaByVolume(false), maximizeColors(false), additive(false), dots(false), thick(false), loop(false) { + + Init(); +} MilkdropWaveform::~MilkdropWaveform() { - glDeleteBuffers(1, &wave1VBO); - glDeleteBuffers(1, &wave2VBO); } +void MilkdropWaveform::InitVertexAttrib() { + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); + glDisableVertexAttribArray(1); + +} + + void MilkdropWaveform::Draw(RenderContext &context) { - WaveformMath(context); - - if(modulateAlphaByVolume) - ModulateOpacityByVolume(context); - else - temp_a = a; + WaveformMath(context); + + glBindBuffer(GL_ARRAY_BUFFER, m_vboID); + + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * samples * 2, NULL, GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * samples * 2, wavearray, GL_DYNAMIC_DRAW); + + if (two_waves) { + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * samples * 2, NULL, GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * samples * 2, wavearray2, GL_DYNAMIC_DRAW); + } + + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glUseProgram(context.programID_v2f_c4f); + + glm::mat4 mat_first_translation = glm::mat4(1.0); + mat_first_translation[3][0] = -0.5; + mat_first_translation[3][1] = -0.5; + + glm::mat4 mat_scale = glm::mat4(1.0); + mat_scale[0][0] = aspectScale; + + float s = glm::sin(glm::radians(-rot)); + float c = glm::cos(glm::radians(-rot)); + glm::mat4 mat_rotation = glm::mat4( c,-s, 0, 0, + s, c, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1); + + glm::mat4 mat_second_translation = glm::mat4(1.0); + mat_second_translation[3][0] = 0.5; + mat_second_translation[3][1] = 0.5; + + glm::mat4 mat_vertex = context.mat_ortho; + mat_vertex = mat_first_translation * mat_vertex; + mat_vertex = mat_scale * mat_vertex; + mat_vertex = mat_rotation * mat_vertex; + mat_vertex = mat_second_translation * mat_vertex; + glUniformMatrix4fv(ShaderEngine::Uniform_V2F_C4F_VertexTranformation(), 1, GL_FALSE, glm::value_ptr(mat_vertex)); + + if(modulateAlphaByVolume) ModulateOpacityByVolume(context); + else temp_a = a; MaximizeColors(context); - + #ifndef GL_TRANSITION - if (dots==1) - glEnable(GL_LINE_STIPPLE); + if(dots==1) glEnable(GL_LINE_STIPPLE); #endif - + //Thick wave drawing - if (thick==1) - glLineWidth( (context.texsize < 512 ) ? 2 : 2*context.texsize/512); - else - glLineWidth( (context.texsize < 512 ) ? 1 : context.texsize/512); - + if (thick==1) glLineWidth( (context.texsize < 512 ) ? 2 : 2*context.texsize/512); + else glLineWidth( (context.texsize < 512 ) ? 1 : context.texsize/512); + //Additive wave drawing (vice overwrite) - if (additive==1) - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - else - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - check_gl_error(); - - // FIXME: convert to dynamic drawing - glBindBuffer(GL_ARRAY_BUFFER, wave1VBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(wavearray), wavearray, GL_STREAM_DRAW); - check_gl_error(); + if (additive==1)glBlendFunc(GL_SRC_ALPHA, GL_ONE); + else glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glBindVertexArray(m_vaoID); if (loop) - glDrawArrays(GL_LINE_LOOP,0,samples); + glDrawArrays(GL_LINE_LOOP,0,samples); else - glDrawArrays(GL_LINE_STRIP,0,samples); - check_gl_error(); + glDrawArrays(GL_LINE_STRIP,0,samples); + - if (two_waves) - { - glBindBuffer(GL_ARRAY_BUFFER, wave2VBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(wavearray2), wavearray2, GL_STREAM_DRAW); - check_gl_error(); - + { if (loop) - glDrawArrays(GL_LINE_LOOP,0,samples); + glDrawArrays(GL_LINE_LOOP,0,samples); else - glDrawArrays(GL_LINE_STRIP,0,samples); - check_gl_error(); - } - - + glDrawArrays(GL_LINE_STRIP,0,samples); + } + + glBindVertexArray(0); + #ifndef GL_TRANSITION - if (dots==1) - glDisable(GL_LINE_STIPPLE); + if(dots==1) glDisable(GL_LINE_STIPPLE); #endif + } void MilkdropWaveform::ModulateOpacityByVolume(RenderContext &context) @@ -100,7 +132,6 @@ void MilkdropWaveform::ModulateOpacityByVolume(RenderContext &context) void MilkdropWaveform::MaximizeColors(RenderContext &context) { -#ifndef GL_TRANSITION float wave_r_switch=0, wave_g_switch=0, wave_b_switch=0; //wave color brightening // @@ -151,13 +182,12 @@ void MilkdropWaveform::MaximizeColors(RenderContext &context) } - glColor4f(wave_r_switch, wave_g_switch, wave_b_switch, temp_a * masterAlpha); + glVertexAttrib4f(1, wave_r_switch, wave_g_switch, wave_b_switch, temp_a * masterAlpha); } else { - glColor4f(r, g, b, temp_a * masterAlpha); + glVertexAttrib4f(1, r, g, b, temp_a * masterAlpha); } -#endif } @@ -324,7 +354,7 @@ void MilkdropWaveform::WaveformMath(RenderContext &context) rot = -mystery*90; aspectScale =1.0+wave_x_temp; wave_x_temp=-1*(x-1.0); - samples = context.beatDetect->pcm->numsamples; + samples = 0 ? 512-32 : context.beatDetect->pcm->numsamples; for ( int i=0;i< samples;i++) { @@ -346,7 +376,7 @@ void MilkdropWaveform::WaveformMath(RenderContext &context) aspectScale =1.0+wave_x_temp; - samples = context.beatDetect->pcm->numsamples; + samples = 0 ? 512-32 : context.beatDetect->pcm->numsamples; two_waves = true; double y_adj = y*y*.5; diff --git a/src/libprojectM/Renderer/MilkdropWaveform.hpp b/src/libprojectM/Renderer/MilkdropWaveform.hpp index 63a7f7c04..48f6f845c 100644 --- a/src/libprojectM/Renderer/MilkdropWaveform.hpp +++ b/src/libprojectM/Renderer/MilkdropWaveform.hpp @@ -42,6 +42,7 @@ public: MilkdropWaveform(); ~MilkdropWaveform(); void Draw(RenderContext &context); + void InitVertexAttrib(); float modOpacityStart; float modOpacityEnd; diff --git a/src/libprojectM/Renderer/Renderable.cpp b/src/libprojectM/Renderer/Renderable.cpp index 8b6ad1f90..200983f01 100644 --- a/src/libprojectM/Renderer/Renderable.cpp +++ b/src/libprojectM/Renderer/Renderable.cpp @@ -1,351 +1,428 @@ #include "Common.hpp" #include "Renderable.hpp" -#include "RenderContext.hpp" #include +#include "ShaderEngine.hpp" +#include -RenderItem::RenderItem() : masterAlpha(1) { - glGenBuffers(1, &vbo); - glGenBuffers(1, &cbo); - check_gl_error(); +typedef float floatPair[2]; +typedef float floatTriple[3]; +typedef float floatQuad[4]; + +RenderContext::RenderContext() + : time(0),texsize(512), aspectRatio(1), aspectCorrect(false){}; + +RenderItem::RenderItem():masterAlpha(1){} + +void RenderItem::Init() { + glGenVertexArrays(1, &m_vaoID); + glGenBuffers(1, &m_vboID); + + glBindVertexArray(m_vaoID); + glBindBuffer(GL_ARRAY_BUFFER, m_vboID); + + InitVertexAttrib(); + + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); } RenderItem::~RenderItem() { - glDeleteBuffers(1, &vbo); - glDeleteBuffers(1, &cbo); - check_gl_error(); + glDeleteBuffers(1, &m_vboID); + glDeleteVertexArrays(1, &m_vaoID); } -DarkenCenter::DarkenCenter():RenderItem(){} -MotionVectors::MotionVectors():RenderItem(){} -Border::Border():RenderItem(){} -void DarkenCenter::Draw(RenderContext &context) { -#ifndef GL_TRANSITION - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +DarkenCenter::DarkenCenter():RenderItem(){ + Init(); +} - float colors[6][4] = {{0, 0, 0, (3.0f/32.0f) * masterAlpha}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}}; +MotionVectors::MotionVectors():RenderItem() { + Init(); +} - float points[6][2] = {{ 0.5, 0.5}, - { 0.45, 0.5}, - { 0.5, 0.45}, - { 0.55, 0.5}, - { 0.5, 0.55}, - { 0.45, 0.5}}; +Border::Border():RenderItem() { + Init(); +} - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); +void DarkenCenter::InitVertexAttrib() { + float points_colors[6][6] = { + { 0.5, 0.5, 0, 0, 0, (3.0f/32.0f) * masterAlpha}, + { 0.45, 0.5, 0, 0, 0, 0}, + { 0.5, 0.45, 0, 0, 0, 0}, + { 0.55, 0.5, 0, 0, 0, 0}, + { 0.5, 0.55, 0, 0, 0, 0}, + { 0.45, 0.5, 0, 0, 0, 0}}; - glVertexPointer(2,GL_FLOAT,0,points); - glColorPointer(4,GL_FLOAT,0,colors); + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); - glDrawArrays(GL_TRIANGLE_FAN,0,6); -#endif + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float)*6, (void*)0); // points + glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(float)*6, (void*)(sizeof(float)*2)); // colors + + glBufferData(GL_ARRAY_BUFFER, sizeof(points_colors), points_colors, GL_STATIC_DRAW); + +} + + +void DarkenCenter::Draw(RenderContext &context) + { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glUseProgram(context.programID_v2f_c4f); + + glUniformMatrix4fv(ShaderEngine::Uniform_V2F_C4F_VertexTranformation(), 1, GL_FALSE, glm::value_ptr(context.mat_ortho)); + + glBindVertexArray(m_vaoID); + + glDrawArrays(GL_TRIANGLE_FAN,0,6); + + glBindVertexArray(0); } Shape::Shape():RenderItem() { std::string imageUrl = ""; - sides = 4; - thickOutline = false; - enabled = true; - additive = false; - textured = false; + sides = 4; + thickOutline = false; + enabled = true; + additive = false; + textured = false; - tex_zoom = 1.0; - tex_ang = 0.0; + tex_zoom = 1.0; + tex_ang = 0.0; - x = 0.5; - y = 0.5; - radius = 1.0; - ang = 0.0; + x = 0.5; + y = 0.5; + radius = 1.0; + ang = 0.0; - r = 0.0; /* red color value */ - g = 0.0; /* green color value */ - b = 0.0; /* blue color value */ - a = 0.0; /* alpha color value */ + r = 0.0; /* red color value */ + g = 0.0; /* green color value */ + b = 0.0; /* blue color value */ + a = 0.0; /* alpha color value */ - r2 = 0.0; /* red color value */ - g2 = 0.0; /* green color value */ - b2 = 0.0; /* blue color value */ - a2 = 0.0; /* alpha color value */ + r2 = 0.0; /* red color value */ + g2 = 0.0; /* green color value */ + b2 = 0.0; /* blue color value */ + a2 = 0.0; /* alpha color value */ - border_r = 0.0; /* red color value */ - border_g = 0.0; /* green color value */ - border_b = 0.0; /* blue color value */ - border_a = 0.0; /* alpha color value */ + border_r = 0.0; /* red color value */ + border_g = 0.0; /* green color value */ + border_b = 0.0; /* blue color value */ + border_a = 0.0; /* alpha color value */ + + + glGenVertexArrays(1, &m_vaoID_texture); + glGenBuffers(1, &m_vboID_texture); + + glGenVertexArrays(1, &m_vaoID_not_texture); + glGenBuffers(1, &m_vboID_not_texture); + + glBindVertexArray(m_vaoID_texture); + glBindBuffer(GL_ARRAY_BUFFER, m_vboID_texture); + + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + glEnableVertexAttribArray(2); + + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(struct_data), (void*)0); // Positions + glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(struct_data), (void*)(sizeof(float)*2)); // Colors + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(struct_data), (void*)(sizeof(float)*6)); // Textures + + glBindVertexArray(m_vaoID_not_texture); + glBindBuffer(GL_ARRAY_BUFFER, m_vboID_not_texture); + + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(struct_data), (void*)0); // points + glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(struct_data), (void*)(sizeof(float)*2)); // Colors + + Init(); } +Shape::~Shape() { + glDeleteBuffers(1, &m_vboID_texture); + glDeleteVertexArrays(1, &m_vaoID_texture); + + glDeleteBuffers(1, &m_vboID_not_texture); + glDeleteVertexArrays(1, &m_vaoID_not_texture); +} + +void Shape::InitVertexAttrib() { + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); // points + glDisableVertexAttribArray(1); +} + + void Shape::Draw(RenderContext &context) { - float xval, yval; - float t; -// printf("drawing shape %f\n", ang); + float xval, yval; + float t; - float temp_radius = radius*(.707*.707*.707*1.04); - - //Additive Drawing or Overwrite - check_gl_error(); - if (additive==0) - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - else - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - check_gl_error(); - - xval= x; - yval= -(y-1); - - if (textured) - { - if (imageUrl !="") - { - GLuint tex= context.textureManager->getTexture(imageUrl); - if (tex != 0) - { - context.aspectRatio=1.0; - } - } + float temp_radius= radius*(.707*.707*.707*1.04); - floatQuad *colors = new float[sides+2][4]; - floatPair *tex = new float[sides+2][2]; - floatPair *points = new float[sides+2][2]; - - //Define the center point of the shape - colors[0][0] = r; - colors[0][1] = g; - colors[0][2] = b; - colors[0][3] = a * masterAlpha; - tex[0][0] = 0.5; - tex[0][1] = 0.5; - points[0][0] = xval; - points[0][1] = yval; - - for ( int i=1;i< sides+2;i++) - { - colors[i][0]= r2; - colors[i][1]=g2; - colors[i][2]=b2; - colors[i][3]=a2 * masterAlpha; - - t = (i-1)/(float) sides; - tex[i][0] =0.5f + 0.5f*cosf(t*3.1415927f*2 + tex_ang + 3.1415927f*0.25f)*(context.aspectCorrect ? context.aspectRatio : 1.0)/ tex_zoom; - tex[i][1] = 0.5f + 0.5f*sinf(t*3.1415927f*2 + tex_ang + 3.1415927f*0.25f)/ tex_zoom; - points[i][0]=temp_radius*cosf(t*3.1415927f*2 + ang + 3.1415927f*0.25f)*(context.aspectCorrect ? context.aspectRatio : 1.0)+xval; - points[i][1]=temp_radius*sinf(t*3.1415927f*2 + ang + 3.1415927f*0.25f)+yval; - } - -#ifndef GL_TRANSITION - glVertexPointer(2,GL_FLOAT,0,points); - glColorPointer(4,GL_FLOAT,0,colors); - glTexCoordPointer(2,GL_FLOAT,0,tex); - - glDrawArrays(GL_TRIANGLE_FAN,0,sides+2); - - glDisable(GL_TEXTURE_2D); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); -#endif - - //Reset Texture state since we might have changed it - /* - if(this->renderTarget->useFBO) - { - glBindTexture( GL_TEXTURE_2D, renderTarget->textureID[1] ); - } - else - { - glBindTexture( GL_TEXTURE_2D, renderTarget->textureID[0] ); - } - */ - - delete[] colors; - delete[] tex; - delete[] points; - } else { - //Untextured (use color values) - floatQuad *colors = new float[sides+2][4]; - floatPair *points = new float[sides+2][2]; - - //Define the center point of the shape - colors[0][0]=r; - colors[0][1]=g; - colors[0][2]=b; - colors[0][3]=a * masterAlpha; - points[0][0]=xval; - points[0][1]=yval; - - for (int i=1;i< sides+2;i++) { - colors[i][0]=r2; - colors[i][1]=g2; - colors[i][2]=b2; - colors[i][3]=a2 * masterAlpha; - t = (i-1)/(float) sides; - points[i][0]=temp_radius*cosf(t*3.1415927f*2 + ang + 3.1415927f*0.25f)*(context.aspectCorrect ? context.aspectRatio : 1.0)+xval; - points[i][1]=temp_radius*sinf(t*3.1415927f*2 + ang + 3.1415927f*0.25f)+yval; - } - - DrawVertices(context, GL_TRIANGLE_FAN, sides+2, sizeof(points), points, sizeof(colors), colors); - - delete[] colors; - delete[] points; - } - - if (thickOutline==1) - glLineWidth(context.texsize < 512 ? 1 : 2*context.texsize/512); - check_gl_error(); + //Additive Drawing or Overwrite + if ( additive==0) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + else glBlendFunc(GL_SRC_ALPHA, GL_ONE); - floatPair *points = new float[sides+1][2]; - - // FIXME -// glColor4f( border_r, border_g, border_b, border_a * masterAlpha); - - for ( int i=0;i< sides;i++) - { - t = (i-1)/(float) sides; - points[i][0]= temp_radius*cosf(t*3.1415927f*2 + ang + 3.1415927f*0.25f)*(context.aspectCorrect ? context.aspectRatio : 1.0)+xval; - points[i][1]= temp_radius*sinf(t*3.1415927f*2 + ang + 3.1415927f*0.25f)+yval; - - } - - DrawVertices(context, GL_LINE_LOOP, sides, sizeof(points), points, 0, nullptr); - - if (thickOutline==1) - glLineWidth(context.texsize < 512 ? 1 : context.texsize/512); - - delete[] points; + xval= x; + yval= -(y-1); + + struct_data *buffer_data = new struct_data[sides+2]; + + if ( textured) + { + if (imageUrl !="") + { + GLuint tex= context.textureManager->getTexture(imageUrl); + if (tex != 0) + { + glBindTexture(GL_TEXTURE_2D, tex); + context.aspectRatio=1.0; + } + } + + + //Define the center point of the shape + buffer_data[0].color_r = r; + buffer_data[0].color_g = g; + buffer_data[0].color_b = b; + buffer_data[0].color_a = a * masterAlpha; + buffer_data[0].tex_x = 0.5; + buffer_data[0].tex_y = 0.5; + buffer_data[0].point_x = xval; + buffer_data[0].point_y = yval; + + for ( int i=1;i< sides+2;i++) + { + buffer_data[i].color_r=r2; + buffer_data[i].color_g=g2; + buffer_data[i].color_b=b2; + buffer_data[i].color_a=a2 * masterAlpha; + + t = (i-1)/(float) sides; + buffer_data[i].tex_x =0.5f + 0.5f*cosf(t*3.1415927f*2 + tex_ang + 3.1415927f*0.25f)*(context.aspectCorrect ? context.aspectRatio : 1.0)/ tex_zoom; + buffer_data[i].tex_y = 0.5f + 0.5f*sinf(t*3.1415927f*2 + tex_ang + 3.1415927f*0.25f)/ tex_zoom; + buffer_data[i].point_x=temp_radius*cosf(t*3.1415927f*2 + ang + 3.1415927f*0.25f)*(context.aspectCorrect ? context.aspectRatio : 1.0)+xval; + buffer_data[i].point_y=temp_radius*sinf(t*3.1415927f*2 + ang + 3.1415927f*0.25f)+yval; + + } + + glBindBuffer(GL_ARRAY_BUFFER, m_vboID_texture); + + glBufferData(GL_ARRAY_BUFFER, sizeof(struct_data)*(sides+2), NULL, GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, sizeof(struct_data)*(sides+2), buffer_data, GL_DYNAMIC_DRAW); + + glUseProgram(context.programID_v2f_c4f_t2f); + + glActiveTexture(GL_TEXTURE0); + + glUniformMatrix4fv(ShaderEngine::Uniform_V2F_C4F_T2F_VertexTranformation(), 1, GL_FALSE, glm::value_ptr(context.mat_ortho)); + + glUniform1i(ShaderEngine::Uniform_V2F_C4F_T2F_FragTextureSampler(), 0); + + glBindVertexArray(m_vaoID_texture); + glDrawArrays(GL_TRIANGLE_FAN, 0, sides+2); + glBindVertexArray(0); + } + else + {//Untextured (use color values) + + //Define the center point of the shape + buffer_data[0].color_r=r; + buffer_data[0].color_g=g; + buffer_data[0].color_b=b; + buffer_data[0].color_a=a * masterAlpha; + buffer_data[0].point_x=xval; + buffer_data[0].point_y=yval; + + + for ( int i=1;i< sides+2;i++) + { + buffer_data[i].color_r=r2; + buffer_data[i].color_g=g2; + buffer_data[i].color_b=b2; + buffer_data[i].color_a=a2 * masterAlpha; + t = (i-1)/(float) sides; + buffer_data[i].point_x=temp_radius*cosf(t*3.1415927f*2 + ang + 3.1415927f*0.25f)*(context.aspectCorrect ? context.aspectRatio : 1.0)+xval; + buffer_data[i].point_y=temp_radius*sinf(t*3.1415927f*2 + ang + 3.1415927f*0.25f)+yval; + } + + glBindBuffer(GL_ARRAY_BUFFER, m_vboID_not_texture); + + glBufferData(GL_ARRAY_BUFFER, sizeof(struct_data)*(sides+2), NULL, GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, sizeof(struct_data)*(sides+2), buffer_data, GL_DYNAMIC_DRAW); + + glUseProgram(context.programID_v2f_c4f); + + glUniformMatrix4fv(ShaderEngine::Uniform_V2F_C4F_VertexTranformation(), 1, GL_FALSE, glm::value_ptr(context.mat_ortho)); + + glBindVertexArray(m_vaoID_not_texture); + glDrawArrays(GL_TRIANGLE_FAN,0,sides+2); + glBindVertexArray(0); + } + + + floatPair *points = new float[sides+1][2]; + + for ( int i=0;i< sides;i++) + { + t = (i-1)/(float) sides; + points[i][0]= temp_radius*cosf(t*3.1415927f*2 + ang + 3.1415927f*0.25f)*(context.aspectCorrect ? context.aspectRatio : 1.0)+xval; + points[i][1]= temp_radius*sinf(t*3.1415927f*2 + ang + 3.1415927f*0.25f)+yval; + } + + glBindBuffer(GL_ARRAY_BUFFER, m_vboID); + + glBufferData(GL_ARRAY_BUFFER, sizeof(floatPair)*(sides), NULL, GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, sizeof(floatPair)*(sides), points, GL_DYNAMIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glUseProgram(context.programID_v2f_c4f); + + glUniformMatrix4fv(ShaderEngine::Uniform_V2F_C4F_VertexTranformation(), 1, GL_FALSE, glm::value_ptr(context.mat_ortho)); + + glVertexAttrib4f(1, border_r, border_g, border_b, border_a * masterAlpha); + + if (thickOutline==1) glLineWidth(context.texsize < 512 ? 1 : 2*context.texsize/512); + + glBindVertexArray(m_vaoID); + glDrawArrays(GL_LINE_LOOP,0,sides); + glBindVertexArray(0); + + if (thickOutline==1) glLineWidth(context.texsize < 512 ? 1 : context.texsize/512); + + delete[] buffer_data; + delete[] points; } -void Shape::DrawVertices(RenderContext &context, GLenum mode, GLsizei count, GLuint pointsSize, floatPair *points, GLuint colorsSize, floatQuad *colors) { - - // draw a set of points with colors - - // create VBO of points - glBindBuffer(GL_ARRAY_BUFFER, vbo); - check_gl_error(); - glBufferData(GL_ARRAY_BUFFER, pointsSize, points, GL_STREAM_DRAW); - check_gl_error(); - glVertexAttribPointer(context.shaderContext->positionAttribute, 2, GL_FLOAT, GL_FALSE, 0, 0); - check_gl_error(); - - // bind colors... - if (colors && colorsSize) { - glBindBuffer(GL_ARRAY_BUFFER, cbo); - check_gl_error(); - glBufferData(GL_ARRAY_BUFFER, colorsSize, colors, GL_STREAM_DRAW); - check_gl_error(); - glVertexAttribPointer(context.shaderContext->colorAttribute, 3, GL_FLOAT, GL_FALSE, 0, 0); - check_gl_error(); - } - - glDrawArrays(mode, 0, count); - - check_gl_error(); +void MotionVectors::InitVertexAttrib() { + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); + glDisableVertexAttribArray(1); } void MotionVectors::Draw(RenderContext &context) { -#ifndef GL_TRANSITION - - glEnableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - float intervalx=1.0/x_num; float intervaly=1.0/y_num; glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glPointSize(length); - glColor4f(r, g, b, a * masterAlpha); - if (x_num + y_num < 600) - { - int size = x_num * y_num ; - - floatPair *points = new float[size][2]; - - for (int x=0;x<(int)x_num;x++) { - for(int y=0;y<(int)y_num;y++) + int size = x_num * y_num ; + + floatPair *points = new float[size][2]; + + for (int x=0;x<(int)x_num;x++) { - float lx, ly, lz; - lx = x_offset+x*intervalx; - ly = y_offset+y*intervaly; + for(int y=0;y<(int)y_num;y++) + { + float lx, ly, lz; + lx = x_offset+x*intervalx; + ly = y_offset+y*intervaly; - points[(x * (int)y_num) + y][0] = lx; - points[(x * (int)y_num) + y][1] = ly; + points[(x * (int)y_num) + y][0] = lx; + points[(x * (int)y_num) + y][1] = ly; + } } - } - glVertexPointer(2,GL_FLOAT,0,points); - glDrawArrays(GL_POINTS,0,size); + glBindBuffer(GL_ARRAY_BUFFER, m_vboID); - delete[] points; + glBufferData(GL_ARRAY_BUFFER, sizeof(floatPair) * size, NULL, GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, sizeof(floatPair) * size, points, GL_DYNAMIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + + delete[] points; + + + glUseProgram(context.programID_v2f_c4f); + + glUniformMatrix4fv(ShaderEngine::Uniform_V2F_C4F_VertexTranformation(), 1, GL_FALSE, glm::value_ptr(context.mat_ortho)); + + #ifndef GL_TRANSITION + if (length <= 0.0) { + glPointSize(1.0); + } else { + glPointSize(length); + } + #endif + + glUniform1f(ShaderEngine::Uniform_V2F_C4F_VertexPointSize(), length); + glVertexAttrib4f(1, r, g, b, a * masterAlpha); + + glBindVertexArray(m_vaoID); + + glDrawArrays(GL_POINTS,0,size); + + glBindVertexArray(0); } -#endif +} + +void Border::InitVertexAttrib() { + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); + glDisableVertexAttribArray(1); } void Border::Draw(RenderContext &context) { -#ifndef GL_TRANSITION + //Draw Borders + float of=outer_size*.5; + float iff=inner_size*.5; + float texof=1.0-of; - glEnableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - //Draw Borders - float of=outer_size*.5; - float iff=inner_size*.5; - float texof=1.0-of; + float points[40] = { + // Outer + 0,0, of,0, + 0,1, of,texof, + 1,1, texof,texof, + 1,0, texof,of, + of,0, of,of, - //no additive drawing for borders - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4f(outer_r, outer_g, outer_b, outer_a * masterAlpha); + // Inner + of,of, of+iff,of, + of,texof, of+iff,texof-iff, + texof,texof, texof-iff,texof-iff, + texof,of, texof-iff,of+iff, + of+iff,of, of+iff,of+iff, + }; - float pointsA[4][2] = {{0,0},{0,1},{of,0},{of,1}}; - glVertexPointer(2,GL_FLOAT,0,pointsA); - glDrawArrays(GL_TRIANGLE_STRIP,0,4); + glBindBuffer(GL_ARRAY_BUFFER, m_vboID); - float pointsB[4][2] = {{of,0},{of,of},{texof,0},{texof,of}}; - glVertexPointer(2,GL_FLOAT,0,pointsB); - glDrawArrays(GL_TRIANGLE_STRIP,0,4); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 40, NULL, GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 40, points, GL_DYNAMIC_DRAW); - float pointsC[4][2] = {{texof,0},{texof,1},{1,0},{1,1}}; - glVertexPointer(2,GL_FLOAT,0,pointsC); - glDrawArrays(GL_TRIANGLE_STRIP,0,4); + glBindBuffer(GL_ARRAY_BUFFER, 0); - float pointsD[4][2] = {{of,1},{of,texof},{texof,1},{texof,texof}}; - glVertexPointer(2,GL_FLOAT,0,pointsD); - glDrawArrays(GL_TRIANGLE_STRIP,0,4); + glUseProgram(context.programID_v2f_c4f); - glColor4f(inner_r, inner_g, inner_b, inner_a * masterAlpha); + glUniformMatrix4fv(ShaderEngine::Uniform_V2F_C4F_VertexTranformation(), 1, GL_FALSE, glm::value_ptr(context.mat_ortho)); - // TODO: replace glRect - glRectd(of, of, of+iff, texof); - glRectd(of+iff, of, texof-iff, of+iff); - glRectd(texof-iff, of, texof, texof); - glRectd(of+iff, texof, texof-iff, texof-iff); + glVertexAttrib4f(1, outer_r, outer_g, outer_b, outer_a * masterAlpha); - float pointsE[4][2] = {{of,of},{of,texof},{of+iff,of},{of+iff,texof}}; - glVertexPointer(2,GL_FLOAT,0,pointsE); - glDrawArrays(GL_TRIANGLE_STRIP,0,4); + //no additive drawing for borders + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - float pointsF[4][2] = {{of+iff,of},{of+iff,of+iff},{texof-iff,of},{texof-iff,of+iff}}; - glVertexPointer(2,GL_FLOAT,0,pointsF); - glDrawArrays(GL_TRIANGLE_STRIP,0,4); + glBindVertexArray(m_vaoID); - float pointsG[4][2] = {{texof-iff,of},{texof-iff,texof},{texof,of},{texof,texof}}; - glVertexPointer(2,GL_FLOAT,0,pointsG); - glDrawArrays(GL_TRIANGLE_STRIP,0,4); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 10); - float pointsH[4][2] = {{of+iff,texof},{of+iff,texof-iff},{texof-iff,texof},{texof-iff,texof-iff}}; - glVertexPointer(2,GL_FLOAT,0,pointsH); - glDrawArrays(GL_TRIANGLE_STRIP,0,4); -#endif + glVertexAttrib4f(1, inner_r, inner_g, inner_b, inner_a * masterAlpha); + + // 1st pass for inner + glDrawArrays(GL_TRIANGLE_STRIP, 10, 10); + + // 2nd pass for inner + glDrawArrays(GL_TRIANGLE_STRIP, 10, 10); + + glBindVertexArray(0); } diff --git a/src/libprojectM/Renderer/Renderable.hpp b/src/libprojectM/Renderer/Renderable.hpp index a1e9acf35..ffdecc22e 100644 --- a/src/libprojectM/Renderer/Renderable.hpp +++ b/src/libprojectM/Renderer/Renderable.hpp @@ -4,23 +4,42 @@ #include #include "TextureManager.hpp" #include "projectM-opengl.h" -#include "RenderContext.hpp" +#include -typedef float floatPair[2]; -typedef float floatTriple[3]; -typedef float floatQuad[4]; +class BeatDetect; + + +class RenderContext +{ +public: + float time; + int texsize; + float aspectRatio; + bool aspectCorrect; + BeatDetect *beatDetect; + TextureManager *textureManager; + GLuint programID_v2f_c4f; + GLuint programID_v2f_c4f_t2f; + glm::mat4 mat_ortho; + + RenderContext(); +}; class RenderItem { public: - float masterAlpha; - virtual void Draw(RenderContext &context) = 0; RenderItem(); ~RenderItem(); + float masterAlpha; + virtual void InitVertexAttrib() = 0; + virtual void Draw(RenderContext &context) = 0; + protected: - // vertex and color buffer storage - GLuint vbo, cbo; + virtual void Init(); + + GLuint m_vboID; + GLuint m_vaoID; }; typedef std::vector RenderItemList; @@ -29,6 +48,7 @@ class DarkenCenter : public RenderItem { public: DarkenCenter(); + void InitVertexAttrib(); void Draw(RenderContext &context); }; @@ -67,10 +87,28 @@ public: Shape(); + ~Shape(); + void InitVertexAttrib(); virtual void Draw(RenderContext &context); - + private: - void DrawVertices(RenderContext &context, GLenum mode, GLsizei count, GLuint pointsSize, floatPair *points, GLuint colorsSize, floatQuad *colors); + + struct struct_data { + float point_x; + float point_y; + float color_r; + float color_g; + float color_b; + float color_a; + float tex_x; + float tex_y; + }; + + GLuint m_vboID_texture; + GLuint m_vaoID_texture; + + GLuint m_vboID_not_texture; + GLuint m_vaoID_not_texture; }; class Text : RenderItem @@ -90,6 +128,7 @@ public: float x_offset; float y_offset; + void InitVertexAttrib(); void Draw(RenderContext &context); MotionVectors(); }; @@ -109,6 +148,7 @@ public: float inner_b; float inner_a; + void InitVertexAttrib(); void Draw(RenderContext &context); Border(); }; diff --git a/src/libprojectM/Renderer/Renderer.cpp b/src/libprojectM/Renderer/Renderer.cpp index 496de82fe..852692970 100644 --- a/src/libprojectM/Renderer/Renderer.cpp +++ b/src/libprojectM/Renderer/Renderer.cpp @@ -11,6 +11,8 @@ #include "omptl/omptl" #include "omptl/omptl_algorithm" #include "UserTexture.hpp" +#include +#include class Preset; @@ -19,6 +21,9 @@ Renderer::Renderer(int width, int height, int gx, int gy, int texsize, BeatDetec title_fontURL(_titlefontURL), menu_fontURL(_menufontURL), presetURL(_presetURL), m_presetName("None"), vw(width), vh(height), texsize(texsize), mesh(gx, gy) { + int x; + int y; + this->totalframes = 1; this->noSwitch = false; this->showfps = false; @@ -77,54 +82,99 @@ Renderer::Renderer(int width, int height, int gx, int gy, int texsize, BeatDetec #endif /** USE_FTGL */ - GLuint size = getMeshSize(); + + int size = (mesh.height - 1) *mesh.width * 4 * 2; p = ( float * ) wipemalloc ( size * sizeof ( float ) ); + for (int j = 0; j < mesh.height - 1; j++) { - int base = j * mesh.width * 2 * 5; + int base = j * mesh.width * 4 * 2; + for (int i = 0; i < mesh.width; i++) { int index = j * mesh.width + i; int index2 = (j + 1) * mesh.width + i; - int strip = base + i * 10; - p[strip + 2] = mesh.identity[index].x; - p[strip + 3] = mesh.identity[index].y; - p[strip + 4] = 0; + int strip = base + i * 8; + p[strip + 0] = mesh.identity[index].x; + p[strip + 1] = mesh.identity[index].y; - p[strip + 7] = mesh.identity[index2].x; - p[strip + 8] = mesh.identity[index2].y; - p[strip + 9] = 0; + p[strip + 4] = mesh.identity[index2].x; + p[strip + 5] = mesh.identity[index2].y; } } - - glGenBuffers(1, &pVBO); - check_gl_error(); - shaderEngine.setParams(renderTarget->texsize, renderTarget->textureID[1], aspect, beatDetect, textureManager); -} + renderContext.programID_v2f_c4f = shaderEngine.programID_v2f_c4f; + renderContext.programID_v2f_c4f_t2f = shaderEngine.programID_v2f_c4f_t2f; -GLuint Renderer::getMeshSize() { - return(mesh.height - 1) *mesh.width * 5 * 2; + // Interpolation VAO/VBO's + glGenBuffers(1, &m_vbo_Interpolation); + glGenVertexArrays(1, &m_vao_Interpolation); + + glBindVertexArray(m_vao_Interpolation); + glBindBuffer(GL_ARRAY_BUFFER, m_vbo_Interpolation); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float)*4, (void*)0); // Positions + + glDisableVertexAttribArray(1); + + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(float)*4, (void*)(sizeof(float)*2)); // Textures + + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + // CompositeOutput VAO/VBO's + glGenBuffers(1, &m_vbo_CompositeOutput); + glGenVertexArrays(1, &m_vao_CompositeOutput); + + float composite_buffer_data[8][2] = + { + { -0.5, -0.5 }, + { 0, 1 }, + { -0.5, 0.5 }, + { 0, 0 }, + { 0.5, 0.5 }, + { 1, 0 }, + { 0.5, -0.5 }, + { 1, 1 } }; + + + glBindVertexArray(m_vao_CompositeOutput); + glBindBuffer(GL_ARRAY_BUFFER, m_vbo_CompositeOutput); + + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 8 * 2, composite_buffer_data, GL_STATIC_DRAW); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float)*4, (void*)0); // Positions + + glDisableVertexAttribArray(1); + + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(float)*4, (void*)(sizeof(float)*2)); // Textures + + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); } void Renderer::SetPipeline(Pipeline &pipeline) { currentPipe = &pipeline; shaderEngine.reset(); - // N.B. i'm actually not sure if they're always fragment shaders... I think so... -mischa -// shaderEngine.loadPresetShader(GL_FRAGMENT_SHADER, pipeline.warpShader, pipeline.warpShaderFilename); - // enable! -// shaderEngine.loadPresetShader(GL_FRAGMENT_SHADER, pipeline.compositeShader, pipeline.compositeShaderFilename); + // TEMP + // N.B. i'm actually not sure if they're always fragment shaders... I think so... -mischa + //shaderEngine.loadShader(GL_FRAGMENT_SHADER, pipeline.warpShader, pipeline.warpShaderFilename); + //shaderEngine.loadShader(GL_FRAGMENT_SHADER, pipeline.compositeShader, pipeline.compositeShaderFilename); } void Renderer::ResetTextures() { textureManager->Clear(); - delete(renderTarget); + delete (renderTarget); renderTarget = new RenderTarget(texsize, vw, vh); reset(vw, vh); @@ -136,7 +186,8 @@ void Renderer::SetupPass1(const Pipeline &pipeline, const PipelineContext &pipel totalframes++; renderTarget->lock(); glViewport(0, 0, renderTarget->texsize, renderTarget->texsize); - check_gl_error(); + + renderContext.mat_ortho = glm::ortho(0.0f, 1.0f, 0.0f, 1.0f, -40.0f, 40.0f); shaderEngine.RenderBlurTextures(pipeline, pipelineContext, renderTarget->texsize); } @@ -149,7 +200,6 @@ void Renderer::RenderItems(const Pipeline &pipeline, const PipelineContext &pipe renderContext.aspectRatio = aspect; renderContext.textureManager = textureManager; renderContext.beatDetect = beatDetect; - renderContext.shaderContext = &shaderEngine.context; for (std::vector::const_iterator pos = pipeline.drawables.begin(); pos != pipeline.drawables.end(); ++pos) { @@ -179,23 +229,30 @@ void Renderer::Pass2(const Pipeline &pipeline, const PipelineContext &pipelineCo #ifdef USE_FBO if (renderTarget->renderToTexture) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, this->renderTarget->fbuffer[1]); + glBindFramebuffer(GL_FRAMEBUFFER, this->renderTarget->fbuffer[1]); glViewport(0, 0, this->renderTarget->texsize, this->renderTarget->texsize); } else #endif glViewport(0, 0, this->vw, this->vh); -// glBindTexture(GL_TEXTURE_2D, this->renderTarget->textureID[0]); + glBindTexture(GL_TEXTURE_2D, this->renderTarget->textureID[0]); + + renderContext.mat_ortho = glm::ortho(-0.5f, 0.5f, -0.5f, 0.5f, -40.0f, 40.0f); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - check_gl_error(); glLineWidth(this->renderTarget->texsize < 512 ? 1 : this->renderTarget->texsize / 512.0); - check_gl_error(); CompositeOutput(pipeline, pipelineContext); +/* FTGL does not support OpenGL ES +#ifndef EMSCRIPTEN + glMatrixMode(GL_MODELVIEW); +#endif + glLoadIdentity(); + glTranslatef(-0.5, -0.5, 0); + // When console refreshes, there is a chance the preset has been changed by the user refreshConsole(); draw_title_to_screen(false); @@ -209,10 +266,12 @@ void Renderer::Pass2(const Pipeline &pipeline, const PipelineContext &pipelineCo draw_preset(); if (this->showstats % 2) draw_stats(); + glTranslatef(0.5, 0.5, 0); +*/ #ifdef USE_FBO if (renderTarget->renderToTexture) - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); #endif } @@ -226,15 +285,15 @@ void Renderer::RenderFrame(const Pipeline &pipeline, const PipelineContext &pipe if (!renderTarget->renderToTexture) { glGetIntegerv(GL_FRAMEBUFFER_BINDING, &externalFBO); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); } #endif SetupPass1(pipeline, pipelineContext); -// shaderEngine.enablePresetShader(currentPipe->warpShader, pipeline, pipelineContext); +// shaderEngine.enableShader(currentPipe->warpShader, pipeline, pipelineContext); Interpolation(pipeline); -// shaderEngine.disablePresetShader(currentPipe->warpShader); +// shaderEngine.disableShader(currentPipe->warpShader); RenderItems(pipeline, pipelineContext); FinishPass1(); @@ -244,7 +303,7 @@ void Renderer::RenderFrame(const Pipeline &pipeline, const PipelineContext &pipe // if it exists (0 means no external FBO) // then rebind it just before calling the final pass: Pass2 if (!renderTarget->renderToTexture && externalFBO != 0) - glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, externalFBO); + glBindFramebuffer(GL_FRAMEBUFFER, externalFBO); #endif Pass2(pipeline, pipelineContext); @@ -252,99 +311,101 @@ void Renderer::RenderFrame(const Pipeline &pipeline, const PipelineContext &pipe void Renderer::Interpolation(const Pipeline &pipeline) { -#ifndef GL_TRANSITION - if (this->renderTarget->useFBO) - glBindTexture(GL_TEXTURE_2D, renderTarget->textureID[1]); - else - glBindTexture(GL_TEXTURE_2D, renderTarget->textureID[0]); -#endif - - // Texture wrapping(clamp vs. wrap) - if (pipeline.textureWrap == 0) - { + if (this->renderTarget->useFBO) + glBindTexture(GL_TEXTURE_2D, renderTarget->textureID[1]); + else + glBindTexture(GL_TEXTURE_2D, renderTarget->textureID[0]); + + //Texture wrapping( clamp vs. wrap) + if (pipeline.textureWrap == 0) + { +#ifdef GL_TRANSITION + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +#else glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } - else - { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - } - check_gl_error(); +#endif + } + else + { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + } + + glActiveTexture(GL_TEXTURE0); + + int size = (mesh.height - 1) * mesh.width * 4 * 2; + + if (pipeline.staticPerPixel) + { + for (int j = 0; j < mesh.height - 1; j++) + { + int base = j * mesh.width * 2 * 4; + + for (int i = 0; i < mesh.width; i++) + { + int strip = base + i * 8; + p[strip + 2] = pipeline.x_mesh[i][j]; + p[strip + 3] = pipeline.y_mesh[i][j]; + + p[strip + 6] = pipeline.x_mesh[i][j+1]; + p[strip + 7] = pipeline.y_mesh[i][j+1]; + } + } + + } + else + { + mesh.Reset(); + omptl::transform(mesh.p.begin(), mesh.p.end(), mesh.identity.begin(), mesh.p.begin(), &Renderer::PerPixel); + + for (int j = 0; j < mesh.height - 1; j++) + { + int base = j * mesh.width * 2 * 4; + + for (int i = 0; i < mesh.width; i++) + { + int strip = base + i * 8; + int index = j * mesh.width + i; + int index2 = (j + 1) * mesh.width + i; + + p[strip + 2] = mesh.p[index].x; + p[strip + 3] = mesh.p[index].y; + + p[strip + 6] = mesh.p[index2].x; + p[strip + 7] = mesh.p[index2].y; + + + } + } + } + + glBindBuffer(GL_ARRAY_BUFFER, m_vbo_Interpolation); + + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * size, NULL, GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * size, p, GL_DYNAMIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glUseProgram(renderContext.programID_v2f_c4f_t2f); + + glUniformMatrix4fv(ShaderEngine::Uniform_V2F_C4F_T2F_VertexTranformation(), 1, GL_FALSE, glm::value_ptr(renderContext.mat_ortho)); + glUniform1i(ShaderEngine::Uniform_V2F_C4F_T2F_FragTextureSampler(), 0); + + glVertexAttrib4f(1, 1.0, 1.0, 1.0, pipeline.screenDecay); glBlendFunc(GL_SRC_ALPHA, GL_ZERO); - check_gl_error(); -// glColor4f(1.0, 1.0, 1.0, pipeline.screenDecay); + glBindVertexArray(m_vao_Interpolation); - -// glEnableClientState(GL_VERTEX_ARRAY); -// glEnableClientState(GL_TEXTURE_COORD_ARRAY); -// glDisableClientState(GL_COLOR_ARRAY); -// - - //glVertexPointer(2, GL_FLOAT, 0, p); - //glTexCoordPointer(2, GL_FLOAT, 0, t); - - // NOTE: how to convert this properly? -// glInterleavedArrays(GL_T2F_V3F,0,p); - - if (pipeline.staticPerPixel) - { - for (int j = 0; j < mesh.height - 1; j++) - { - int base = j * mesh.width * 2 * 5; - - for (int i = 0; i < mesh.width; i++) - { - int strip = base + i * 10; - p[strip] = pipeline.x_mesh[i][j]; - p[strip + 1] = pipeline.y_mesh[i][j]; - - p[strip + 5] = pipeline.x_mesh[i][j+1]; - p[strip + 6] = pipeline.y_mesh[i][j+1]; - } - } - } else { - mesh.Reset(); - omptl::transform(mesh.p.begin(), mesh.p.end(), mesh.identity.begin(), mesh.p.begin(), &Renderer::PerPixel); - - for (int j = 0; j < mesh.height - 1; j++) - { - int base = j * mesh.width * 2 * 5; - - for (int i = 0; i < mesh.width; i++) - { - int strip = base + i * 10; - int index = j * mesh.width + i; - int index2 = (j + 1) * mesh.width + i; - - p[strip] = mesh.p[index].x; - p[strip + 1] = mesh.p[index].y; - - p[strip + 5] = mesh.p[index2].x; - p[strip + 6] = mesh.p[index2].y; - } - } - } - - // upload mesh - glBindBuffer(GL_ARRAY_BUFFER, pVBO); - check_gl_error(); - glBufferData(GL_ARRAY_BUFFER, getMeshSize(), p, GL_DYNAMIC_DRAW); - check_gl_error(); - glVertexAttribPointer(getPositionAttribute(), 2, GL_FLOAT, GL_FALSE, 0, 0); - check_gl_error(); + for (int j = 0; j < mesh.height - 1; j++) + glDrawArrays(GL_TRIANGLE_STRIP,j* mesh.width* 2,mesh.width*2); -// glVertexAttribPointer(getColorAttribute(), 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), 0); + glBindVertexArray(0); - // render each row of the mesh - for (int j = 0; j < mesh.height - 1; j++) -// glDrawArrays(GL_TRIANGLE_STRIP, j * mesh.width * 2, mesh.width * 2); - check_gl_error(); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - check_gl_error(); } Pipeline* Renderer::currentPipe; @@ -361,8 +422,6 @@ Renderer::~Renderer() //std::cerr << "grid assign end" << std::endl; free(p); - - glDeleteBuffers(1, &pVBO); #ifdef USE_FTGL // std::cerr << "freeing title fonts" << std::endl; @@ -375,62 +434,54 @@ Renderer::~Renderer() // std::cerr << "freeing title fonts finished" << std::endl; #endif // std::cerr << "exiting destructor" << std::endl; + + glDeleteBuffers(1, &m_vbo_Interpolation); + glDeleteVertexArrays(1, &m_vao_Interpolation); + + glDeleteBuffers(1, &m_vbo_CompositeOutput); + glDeleteVertexArrays(1, &m_vao_CompositeOutput); } void Renderer::reset(int w, int h) { -#ifndef GL_TRANSITION aspect = (float) h / (float) w; this -> vw = w; this -> vh = h; shaderEngine.setAspect(aspect); - glShadeModel(GL_SMOOTH); - glCullFace(GL_BACK); //glFrontFace( GL_CCW ); +#ifndef GL_TRANSITION + glEnable(GL_LINE_SMOOTH); +#endif + + glClearColor(0, 0, 0, 0); glViewport(0, 0, w, h); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); + glEnable(GL_BLEND); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glDrawBuffer(GL_BACK); - glReadBuffer(GL_BACK); - glEnable(GL_BLEND); + glActiveTexture(GL_TEXTURE0); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_LINE_SMOOTH); - - glEnable(GL_POINT_SMOOTH); glClear(GL_COLOR_BUFFER_BIT); - glLineStipple(2, 0xAAAA); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + // TODO: how to port this to modern openGL ? + // glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - //glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); - //glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); - //glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); - if (!this->renderTarget->useFBO) - { - this->renderTarget->fallbackRescale(w, h); - } -#endif +// if (!this->renderTarget->useFBO) +// { +// this->renderTarget->fallbackRescale(w, h); +// } } GLuint Renderer::initRenderToTexture() @@ -458,10 +509,6 @@ void Renderer::draw_title_to_screen(bool flip) if (this->drawtitle > 0) { - //setUpLighting(); - - //glEnable(GL_POLYGON_SMOOTH); - //glEnable( GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glClear(GL_DEPTH_BUFFER_BIT); @@ -703,58 +750,29 @@ void Renderer::draw_fps(float realfps) void Renderer::CompositeOutput(const Pipeline &pipeline, const PipelineContext &pipelineContext) { -#ifndef GL_TRANSITION + glUseProgram(renderContext.programID_v2f_c4f_t2f); + + glUniformMatrix4fv(ShaderEngine::Uniform_V2F_C4F_T2F_VertexTranformation(), 1, GL_FALSE, glm::value_ptr(renderContext.mat_ortho)); + glUniform1i(ShaderEngine::Uniform_V2F_C4F_T2F_FragTextureSampler(), 0); + //Overwrite anything on the screen glBlendFunc(GL_ONE, GL_ZERO); - glColor4f(1.0, 1.0, 1.0, 1.0f); - glEnable(GL_TEXTURE_2D); -#endif + glVertexAttrib4f(1, 1.0, 1.0, 1.0, 1.0); -// shaderEngine.enablePresetShader(currentPipe->compositeShader, pipeline, pipelineContext); + glActiveTexture(GL_TEXTURE0); -#ifndef GL_TRANSITION - float tex[4][2] = - { - { 0, 1 }, - { 0, 0 }, - { 1, 0 }, - { 1, 1 } }; +// shaderEngine.enableShader(currentPipe->compositeShader, pipeline, pipelineContext); - float points[4][2] = - { - { -0.5, -0.5 }, - { -0.5, 0.5 }, - { 0.5, 0.5 }, - { 0.5, -0.5 } }; + glBindVertexArray(m_vao_CompositeOutput); - glEnableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glVertexPointer(2, GL_FLOAT, 0, points); - glTexCoordPointer(2, GL_FLOAT, 0, tex); + glBindVertexArray(0); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - glDisable(GL_TEXTURE_2D); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); -#endif - -// shaderEngine.disablePresetShader(currentPipe->compositeShader); - for (std::vector::const_iterator pos = pipeline.compositeDrawables.begin(); pos != pipeline.compositeDrawables.end(); ++pos) (*pos)->Draw(renderContext); + } - -GLuint Renderer::getPositionAttribute() { - return shaderEngine.context.positionAttribute; -} - -GLuint Renderer::getColorAttribute() { - return shaderEngine.context.colorAttribute; -} - - diff --git a/src/libprojectM/Renderer/Renderer.hpp b/src/libprojectM/Renderer/Renderer.hpp index 3686f84a7..85cfaf575 100644 --- a/src/libprojectM/Renderer/Renderer.hpp +++ b/src/libprojectM/Renderer/Renderer.hpp @@ -1,8 +1,6 @@ #ifndef Renderer_HPP #define Renderer_HPP -//#include - #include "FBO.hpp" #include "BeatDetect.hpp" #include "Common.hpp" @@ -99,6 +97,12 @@ private: std::string menu_fontURL; std::string presetURL; + GLuint m_vbo_Interpolation; + GLuint m_vao_Interpolation; + + GLuint m_vbo_CompositeOutput; + GLuint m_vao_CompositeOutput; + #ifdef USE_FTGL FTGLPixmapFont *title_font; FTGLPixmapFont *other_font; diff --git a/src/libprojectM/Renderer/ShaderEngine.cpp b/src/libprojectM/Renderer/ShaderEngine.cpp index f936b8090..ea879c010 100644 --- a/src/libprojectM/Renderer/ShaderEngine.cpp +++ b/src/libprojectM/Renderer/ShaderEngine.cpp @@ -10,9 +10,98 @@ #include "BeatDetect.hpp" #include "HLSLTranslator.hpp" +#define GLSL_VERSION "410" + +std::string v2f_c4f_vert( + "#version " + GLSL_VERSION + "\n" + "" + "layout(location = 0) in vec2 vertex_position;\n" + "layout(location = 1) in vec4 vertex_color;\n" + "" + "uniform mat4 vertex_transformation;\n" + "uniform float vertex_point_size;\n" + "" + "out vec4 fragment_color;\n" + "" + "void main(){\n" + " gl_Position = vertex_transformation * vec4(vertex_position, 0.0, 1.0);\n" + " gl_PointSize = vertex_point_size;\n" + " fragment_color = vertex_color;\n" + "}\n"); + +std::string v2f_c4f_frag( + "#version " + GLSL_VERSION + "\n" + "precision mediump float;\n" + "" + "in vec4 fragment_color;\n" + "out vec4 color;\n" + "" + "void main(){\n" + " color = fragment_color;\n" + "}\n"); + + +std::string v2f_c4f_t2f_vert( + "#version " + GLSL_VERSION + "\n" + "layout(location = 0) in vec2 vertex_position;\n" + "layout(location = 1) in vec4 vertex_color;\n" + "layout(location = 2) in vec2 vertex_texture;\n" + "" + "uniform mat4 vertex_transformation;\n" + "" + "out vec4 fragment_color;\n" + "out vec2 fragment_texture;\n" + "" + "void main(){\n" + " gl_Position = vertex_transformation * vec4(vertex_position, 0.0, 1.0);\n" + " fragment_color = vertex_color;\n" + " fragment_texture = vertex_texture;\n" + "}\n"); + +std::string v2f_c4f_t2f_frag( + "#version " + GLSL_VERSION + "\n" + "precision mediump float;\n" + "" + "in vec4 fragment_color;\n" + "in vec2 fragment_texture;\n" + "" + "uniform sampler2D texture_sampler;\n" + "" + "out vec4 color;\n" + "" + "void main(){\n" + " color = fragment_color * texture(texture_sampler, fragment_texture.st);\n" + "}\n"); + + +GLint ShaderEngine::UNIFORM_V2F_C4F_VERTEX_TRANFORMATION = 0; +GLint ShaderEngine::UNIFORM_V2F_C4F_VERTEX_POINT_SIZE = 0; +GLint ShaderEngine::UNIFORM_V2F_C4F_T2F_VERTEX_TRANFORMATION = 0; +GLint ShaderEngine::UNIFORM_V2F_C4F_T2F_FRAG_TEXTURE_SAMPLER = 0; + + + ShaderEngine::ShaderEngine() { - initShaderProgram(); + GLuint m_temp_vao; + glGenVertexArrays(1, &m_temp_vao); + glBindVertexArray(m_temp_vao); + + programID_v2f_c4f = CompileShaderProgram(v2f_c4f_vert, v2f_c4f_frag); + programID_v2f_c4f_t2f = CompileShaderProgram(v2f_c4f_t2f_vert, v2f_c4f_t2f_frag); + + UNIFORM_V2F_C4F_VERTEX_TRANFORMATION = glGetUniformLocation(programID_v2f_c4f, "vertex_transformation"); + UNIFORM_V2F_C4F_VERTEX_POINT_SIZE = glGetUniformLocation(programID_v2f_c4f, "vertex_point_size"); + UNIFORM_V2F_C4F_T2F_VERTEX_TRANFORMATION = glGetUniformLocation(programID_v2f_c4f_t2f, "vertex_transformation"); + UNIFORM_V2F_C4F_T2F_FRAG_TEXTURE_SAMPLER = glGetUniformLocation(programID_v2f_c4f_t2f, "texture_sampler"); } ShaderEngine::~ShaderEngine() @@ -25,7 +114,7 @@ bool ShaderEngine::checkCompileStatus(GLuint shader, const char *shaderTitle) { glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if (status == GL_TRUE) return true; // success - + char buffer[2048]; glGetShaderInfoLog(shader, 2048, NULL, buffer); std::cerr << "Failed to compile shader '" << shaderTitle << "'. Error: " << buffer << std::endl; @@ -43,11 +132,11 @@ void ShaderEngine::initShaderProgram() glGenVertexArrays(1, &vao); glBindVertexArray(vao); check_gl_error(); - + // our vertex shader const char* vertexSource = R"glsl( #version 150 core - + in vec2 position; in vec3 color; out vec3 Color; @@ -64,11 +153,11 @@ void ShaderEngine::initShaderProgram() checkCompileStatus(vertexShader, "internal vertex shader"); check_gl_error(); - + // our fragment shader const char* fragmentSource = R"glsl( #version 150 core - + in vec3 Color; out vec4 outColor; @@ -82,28 +171,28 @@ void ShaderEngine::initShaderProgram() glCompileShader(fragmentShader); checkCompileStatus(fragmentShader, "internal fragment shader"); check_gl_error(); - + glAttachShader(program, vertexShader); glAttachShader(program, fragmentShader); check_gl_error(); glBindFragDataLocation(program, 0, "outColor"); check_gl_error(); - + relinkProgram(); glUseProgram(program); - + // configure vertex position input for vertex shader context.positionAttribute = glGetAttribLocation(program, "position"); // glVertexAttribPointer(positionAttribute, 2, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(context.positionAttribute); check_gl_error(); - + context.colorAttribute = glGetAttribLocation(program, "color"); glEnableVertexAttribArray(context.colorAttribute); check_gl_error(); - + // TODO: pre-lookup uniform locations here and save them printf("shader program initialized\n"); @@ -145,7 +234,7 @@ void ShaderEngine::setParams(const int texsize, const unsigned int texId, const glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); #endif - + blur1_enabled = false; blur2_enabled = false; blur3_enabled = false; @@ -234,7 +323,7 @@ GLuint ShaderEngine::compilePresetShader(GLenum shaderType, Shader &pmShader, st } else return false; - + // replace "{" with some variable declarations found = program.rfind('{'); if (found != std::string::npos) @@ -251,7 +340,7 @@ GLuint ShaderEngine::compilePresetShader(GLenum shaderType, Shader &pmShader, st } else return false; - + // replace shader_body with entry point function found = program.find("shader_body"); if (found != std::string::npos) @@ -368,7 +457,7 @@ GLuint ShaderEngine::compilePresetShader(GLenum shaderType, Shader &pmShader, st blur1_enabled = true; } } - + // now we need to prepend the HLSL template to the program // transpile from HLSL (aka preset shader aka directX shader) to GLSL (aka OpenGL shader lang) @@ -379,17 +468,16 @@ GLuint ShaderEngine::compilePresetShader(GLenum shaderType, Shader &pmShader, st std::cerr << "Original program: " << program << std::endl; return false; } - + // https://www.khronos.org/opengl/wiki/Shader_Compilation#Shader_object_compilation GLuint shader = glCreateShader(shaderType); - // Get strings for glShaderSource. const char *shaderSourceCStr = glslSource.get()->c_str(); glShaderSource(shader, 1, &shaderSourceCStr, NULL); - + // compile shader glCompileShader(shader); - + // check result GLint isCompiled = 0; glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled); @@ -399,10 +487,9 @@ GLuint ShaderEngine::compilePresetShader(GLenum shaderType, Shader &pmShader, st glDeleteShader(shader); // Don't leak the shader. return false; } - -// std::cerr << "Original program: " << shaderSourceCStr << std::endl; - - return shader; + programs[&pmShader] = shader; + + return shader; } @@ -410,7 +497,7 @@ void ShaderEngine::SetupShaderVariables(GLuint program, const Pipeline &pipeline { // pass info from projectM to the shader uniforms // these are the inputs: http://www.geisswerks.com/milkdrop/milkdrop_preset_authoring.html#3f6 - + GLfloat slow_roam_cos[4] = { 0.5f + 0.5f * (float)cos(context.time * 0.005), 0.5f + 0.5f * (float)cos(context.time * 0.008), 0.5f + 0.5f * (float)cos(context.time * 0.013), 0.5f + 0.5f * (float)cos(context.time * 0.022) }; GLfloat roam_cos[4] = { 0.5f + 0.5f * cosf(context.time * 0.3), 0.5f + 0.5f * cosf(context.time * 1.3), 0.5f + 0.5f * cosf(context.time * 5), 0.5f + 0.5f * cosf(context.time * 20) }; GLfloat slow_roam_sin[4] = { 0.5f + 0.5f * sinf(context.time * 0.005), 0.5f + 0.5f * sinf(context.time * 0.008), 0.5f + 0.5f * sinf(context.time * 0.013), 0.5f + 0.5f * sinf(context.time * 0.022) }; @@ -481,10 +568,10 @@ void ShaderEngine::setupUserTexture(const UserTexture* texture) } glUniform1i(param, 0); - + glActiveTexture(GL_TEXTURE0 + 0); glBindTexture(GL_TEXTURE_2D, texture->texID); - + if (texture->texsizeDefined) { std::string texsizeName = "texsize_" + texture->name; @@ -645,7 +732,7 @@ void ShaderEngine::RenderBlurTextures(const Pipeline &pipeline, const PipelineCo void ShaderEngine::relinkProgram() { glLinkProgram(program); - + GLint program_linked; glGetProgramiv(program, GL_LINK_STATUS, &program_linked); if (program_linked != GL_TRUE) { @@ -655,7 +742,7 @@ void ShaderEngine::relinkProgram() { std::cerr << "Failed to link program: " << message << std::endl; return; } - + printf("LINK OK\n"); } @@ -664,25 +751,25 @@ void ShaderEngine::loadPresetShader(GLenum shaderType, Shader &presetShader, std { assert(!presetShader.enabled); auto shader = compilePresetShader(shaderType, presetShader, shaderFilename); - + if (!shader) { // failed to compile return; } - + presetShaders[&presetShader] = shader; - + // pass texture info from preset to shader for (auto &userTexture : presetShader.textures) { setupUserTextureState(userTexture.second); setupUserTexture(userTexture.second); } - + // turn shader on glAttachShader(program, shader); presetShader.enabled = true; printf("linked shader %s\n", presetShader.presetPath.c_str()); - + relinkProgram(); } @@ -691,7 +778,7 @@ void ShaderEngine::deletePresetShader(Shader &presetShader) printf("deleting shader... enabled=%d, path=%s\n", presetShader.enabled, presetShader.presetPath.c_str()); if (! presetShader.enabled) return; - + auto shader = presetShaders[&presetShader]; glDeleteShader(shader); glDetachShader(program, shader); @@ -704,7 +791,7 @@ void ShaderEngine::disablePresetShaders() { // nothing to do return; } - + for (auto &i : presetShaders) { deletePresetShader(*i.first); } @@ -721,3 +808,81 @@ void ShaderEngine::reset() rand_preset[2] = (rand() % 100) * .01; rand_preset[3] = (rand() % 100) * .01; } + +GLuint ShaderEngine::CompileShaderProgram(const std::string & VertexShaderCode, const std::string & FragmentShaderCode){ + + // Create the shaders + GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); + GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); + + GLint Result = GL_FALSE; + int InfoLogLength; + + + // Compile Vertex Shader + char const * VertexSourcePointer = VertexShaderCode.c_str(); + glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL); + glCompileShader(VertexShaderID); + + // Check Vertex Shader + glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); + glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); + if ( InfoLogLength > 0 ){ + std::vector VertexShaderErrorMessage(InfoLogLength+1); + glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); + fprintf(stderr, "Error compiling base vertex shader: %s\n", &VertexShaderErrorMessage[0]); + } + + + // Compile Fragment Shader + char const * FragmentSourcePointer = FragmentShaderCode.c_str(); + glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL); + glCompileShader(FragmentShaderID); + + // Check Fragment Shader + glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); + glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); + if ( InfoLogLength > 0 ){ + std::vector FragmentShaderErrorMessage(InfoLogLength+1); + glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]); + fprintf(stderr, "Error compiling base fragment shader: %s\n", &FragmentShaderErrorMessage[0]); + } + + + + // Link the program + GLuint programID = glCreateProgram(); + glAttachShader(programID, VertexShaderID); + glAttachShader(programID, FragmentShaderID); + glLinkProgram(programID); + + // Check the program + glGetProgramiv(programID, GL_LINK_STATUS, &Result); + glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &InfoLogLength); + if ( InfoLogLength > 0 ){ + std::vector ProgramErrorMessage(InfoLogLength+1); + glGetProgramInfoLog(programID, InfoLogLength, NULL, &ProgramErrorMessage[0]); + fprintf(stderr, "%s\n", &ProgramErrorMessage[0]); + } + + + glValidateProgram(programID); + + // Check the program + glGetProgramiv(programID, GL_VALIDATE_STATUS, &Result); + glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &InfoLogLength); + if ( InfoLogLength > 0 ){ + std::vector ProgramErrorMessage(InfoLogLength+1); + glGetProgramInfoLog(programID, InfoLogLength, NULL, &ProgramErrorMessage[0]); + fprintf(stderr, "%s\n", &ProgramErrorMessage[0]); + } + + + glDetachShader(programID, VertexShaderID); + glDetachShader(programID, FragmentShaderID); + + glDeleteShader(VertexShaderID); + glDeleteShader(FragmentShaderID); + + return programID; +} diff --git a/src/libprojectM/Renderer/ShaderEngine.hpp b/src/libprojectM/Renderer/ShaderEngine.hpp index bbcd1b725..0dd2eb566 100644 --- a/src/libprojectM/Renderer/ShaderEngine.hpp +++ b/src/libprojectM/Renderer/ShaderEngine.hpp @@ -53,9 +53,6 @@ class ShaderEngine GLuint blur2Program; std::map presetShaders; - - GLuint program; - GLuint vao; void initShaderProgram(); void SetupShaderQVariables(GLuint program, const Pipeline &q); @@ -79,6 +76,22 @@ public: void setAspect(float aspect); std::string profileName; ShaderContext context; + + GLuint programID_v2f_c4f; + GLuint programID_v2f_c4f_t2f; + + + GLuint CompileShaderProgram(const std::string & VertexShaderCode, const std::string & FragmentShaderCode); + + static GLint Uniform_V2F_C4F_VertexTranformation() { return UNIFORM_V2F_C4F_VERTEX_TRANFORMATION; } + static GLint Uniform_V2F_C4F_VertexPointSize() { return UNIFORM_V2F_C4F_VERTEX_POINT_SIZE; } + static GLint Uniform_V2F_C4F_T2F_VertexTranformation() { return UNIFORM_V2F_C4F_T2F_VERTEX_TRANFORMATION; } + static GLint Uniform_V2F_C4F_T2F_FragTextureSampler() { return UNIFORM_V2F_C4F_T2F_FRAG_TEXTURE_SAMPLER; } + + static GLint UNIFORM_V2F_C4F_VERTEX_TRANFORMATION; + static GLint UNIFORM_V2F_C4F_VERTEX_POINT_SIZE; + static GLint UNIFORM_V2F_C4F_T2F_VERTEX_TRANFORMATION; + static GLint UNIFORM_V2F_C4F_T2F_FRAG_TEXTURE_SAMPLER; }; #endif /* SHADERENGINE_HPP_ */ diff --git a/src/libprojectM/Renderer/VideoEcho.cpp b/src/libprojectM/Renderer/VideoEcho.cpp index 64e5c5c40..f3bf010e7 100644 --- a/src/libprojectM/Renderer/VideoEcho.cpp +++ b/src/libprojectM/Renderer/VideoEcho.cpp @@ -6,51 +6,30 @@ */ #include "VideoEcho.hpp" +#include "ShaderEngine.hpp" +#include VideoEcho::VideoEcho(): a(0), zoom(1), orientation(Normal) { - // TODO Auto-generated constructor stub - + Init(); } VideoEcho::~VideoEcho() { - // TODO Auto-generated destructor stub +} + +void VideoEcho::InitVertexAttrib() { + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float)*4, (void*)0); // Positions + + glDisableVertexAttribArray(1); + + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(float)*4, (void*)(sizeof(float)*2)); // Textures } void VideoEcho::Draw(RenderContext &context) { - float tex[4][2] = {{0, 1}, - {0, 0}, - {1, 0}, - {1, 1}}; - - float points[4][2] = {{-0.5, -0.5}, - {-0.5, 0.5}, - { 0.5, 0.5}, - { 0.5, -0.5}}; - -#ifndef GL_TRANSITION - glEnableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - glVertexPointer(2,GL_FLOAT,0,points); - glTexCoordPointer(2,GL_FLOAT,0,tex); -#endif - - //Now Blend the Video Echo - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - -#ifndef GL_TRANSITION - glMatrixMode(GL_TEXTURE); - - //draw video echo - glColor4f(1.0, 1.0, 1.0, a * masterAlpha); - glTranslatef(.5, .5, 0); - glScalef(1.0/zoom, 1.0/zoom, 1); - glTranslatef(-.5, -.5, 0); - int flipx=1, flipy=1; switch (orientation) { @@ -61,17 +40,66 @@ void VideoEcho::Draw(RenderContext &context) default: flipx=1;flipy=1; break; } - double pointsFlip[4][2] = {{-0.5*flipx, -0.5*flipy}, - {-0.5*flipx, 0.5*flipy}, - { 0.5*flipx, 0.5*flipy}, - { 0.5*flipx, -0.5*flipy}}; + float buffer_data[8][2] = { + {-0.5f*flipx, -0.5f*flipy}, + {0.0, 1.0}, - glVertexPointer(2,GL_FLOAT,0,pointsFlip); - glDrawArrays(GL_TRIANGLE_FAN,0,4); + {-0.5f*flipx, 0.5f*flipy}, + {0.0, 0.0}, - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + { 0.5f*flipx, 0.5f*flipy}, + {1.0, 0.0}, - glDisableClientState(GL_TEXTURE_COORD_ARRAY); -#endif + { 0.5f*flipx, -0.5f*flipy}, + {1.0, 1.0} + }; + glm::mat4 mat_first_translation = glm::mat4(1.0); + mat_first_translation[3][0] = -0.5; + mat_first_translation[3][1] = -0.5; + + glm::mat4 mat_scale = glm::mat4(1.0); + mat_scale[0][0] = 1.0/zoom; + mat_scale[1][1] = 1.0/zoom; + + glm::mat4 mat_second_translation = glm::mat4(1.0); + mat_second_translation[3][0] = 0.5; + mat_second_translation[3][1] = 0.5; + + for (int i = 1; i < 8; i+=2) { + glm::vec4 texture = glm::vec4(buffer_data[i][0], buffer_data[i][1], 0, 1); + texture = mat_first_translation * texture; + texture = mat_scale * texture; + texture = mat_second_translation * texture; + + buffer_data[i][0] = texture[0]; + buffer_data[i][1] = texture[1]; + } + + + glBindBuffer(GL_ARRAY_BUFFER, m_vboID); + + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 16, NULL, GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 16, buffer_data, GL_DYNAMIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glActiveTexture(GL_TEXTURE0); + + glUseProgram(context.programID_v2f_c4f_t2f); + + glUniformMatrix4fv(ShaderEngine::Uniform_V2F_C4F_T2F_VertexTranformation(), 1, GL_FALSE, glm::value_ptr(context.mat_ortho)); + + glUniform1i(ShaderEngine::Uniform_V2F_C4F_T2F_FragTextureSampler(), 0); + + glVertexAttrib4f(1, 1.0, 1.0, 1.0, a * masterAlpha); + + glBindVertexArray(m_vaoID); + + //draw video echo + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glBindVertexArray(0); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } diff --git a/src/libprojectM/Renderer/VideoEcho.hpp b/src/libprojectM/Renderer/VideoEcho.hpp index a10606a11..9e74be7f6 100644 --- a/src/libprojectM/Renderer/VideoEcho.hpp +++ b/src/libprojectM/Renderer/VideoEcho.hpp @@ -27,6 +27,7 @@ public: float zoom; Orientation orientation; + void InitVertexAttrib(); void Draw(RenderContext &context); }; diff --git a/src/libprojectM/Renderer/Waveform.cpp b/src/libprojectM/Renderer/Waveform.cpp index ebe90ab3f..008c6f943 100644 --- a/src/libprojectM/Renderer/Waveform.cpp +++ b/src/libprojectM/Renderer/Waveform.cpp @@ -9,6 +9,8 @@ #include "Waveform.hpp" #include #include "BeatDetect.hpp" +#include "ShaderEngine.hpp" +#include typedef float floatPair[2]; typedef float floatTriple[3]; @@ -17,102 +19,100 @@ typedef float floatQuad[4]; Waveform::Waveform(int samples) : RenderItem(),samples(samples), points(samples), pointContext(samples) { + spectrum = false; /* spectrum data or pcm data */ dots = false; /* draw wave as dots or lines */ thick = false; /* draw thicker lines */ additive = false; /* add color values together */ - scaling = 1; /* scale factor of waveform */ + scaling= 1; /* scale factor of waveform */ smoothing = 0; /* smooth factor of waveform */ sep = 0; + + Init(); +} + +void Waveform::InitVertexAttrib() { + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(ColoredPoint), (void*)0); // points + glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(ColoredPoint), (void*)(sizeof(float)*2)); // colors } void Waveform::Draw(RenderContext &context) -{ - - //if (samples > 2048) samples = 2048; - - if (additive) - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - else - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - if (thick) - { - glLineWidth(context.texsize <= 512 ? 2 : 2*context.texsize/512); - glPointSize(context.texsize <= 512 ? 2 : 2*context.texsize/512); - - } - else glPointSize(context.texsize <= 512 ? 1 : context.texsize/512); - - float *value1 = new float[samples]; - float *value2 = new float[samples]; - context.beatDetect->pcm->getPCM( value1, samples, 0, spectrum, smoothing, 0); - context.beatDetect->pcm->getPCM( value2, samples, 1, spectrum, smoothing, 0); - // printf("%f\n",pcmL[0]); - - - float mult = scaling * (spectrum ? 0.015f :1.0f); + { + float *value1 = new float[samples]; + float *value2 = new float[samples]; + context.beatDetect->pcm->getPCM( value1, samples, 0, spectrum, smoothing, 0); + context.beatDetect->pcm->getPCM( value2, samples, 1, spectrum, smoothing, 0); - std::transform(&value1[0],&value1[samples],&value1[0],std::bind2nd(std::multiplies(),mult)); - std::transform(&value2[0],&value2[samples],&value2[0],std::bind2nd(std::multiplies(),mult)); - - WaveformContext waveContext(samples, context.beatDetect); - - for(int x=0;x< samples;x++) - { - waveContext.sample = x/(float)(samples - 1); - waveContext.sample_int = x; - waveContext.left = value1[x]; - waveContext.right = value2[x]; - - points[x] = PerPoint(points[x],waveContext); - } - - floatQuad *colors = new float[samples][4]; - floatPair *p = new float[samples][2]; - - for(int x=0;x< samples;x++) - { - colors[x][0] = points[x].r; - colors[x][1] = points[x].g; - colors[x][2] = points[x].b; - colors[x][3] = points[x].a * masterAlpha; - - p[x][0] = points[x].x; - p[x][1] = -(points[x].y-1); - } - - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, samples * 2, p, GL_DYNAMIC_DRAW); - glVertexAttribPointer(context.shaderContext->positionAttribute, 2, GL_FLOAT, GL_FALSE, 0, 0); - check_gl_error(); - - GLuint cbo; - glGenBuffers(1, &cbo); - glBindBuffer(GL_ARRAY_BUFFER, cbo); - glBufferData(GL_ARRAY_BUFFER, samples * 4, colors, GL_STREAM_DRAW); -// glEnableVertexAttribArray(context.shaderContext->colorAttribute); - glVertexAttribPointer(context.shaderContext->colorAttribute, 4, GL_FLOAT, GL_FALSE, 0, 0); - glDeleteBuffers(1, &cbo); + float mult= scaling*( spectrum ? 0.015f :1.0f); -// glVertexPointer(2,GL_FLOAT,0,p); -// glColorPointer(4,GL_FLOAT,0,colors); - - if (dots) - glDrawArrays(GL_POINTS,0,samples); + std::transform(&value1[0],&value1[samples],&value1[0],std::bind2nd(std::multiplies(),mult)); + std::transform(&value2[0],&value2[samples],&value2[0],std::bind2nd(std::multiplies(),mult)); + + WaveformContext waveContext(samples, context.beatDetect); + + for(int x=0;x< samples;x++) + { + waveContext.sample = x/(float)(samples - 1); + waveContext.sample_int = x; + waveContext.left = value1[x]; + waveContext.right = value2[x]; + + points[x] = PerPoint(points[x],waveContext); + } + + std::vector points_transf = points; + + for (std::vector::iterator iter = points_transf.begin(); iter != points_transf.end(); ++iter) { + (*iter).y = -( (*iter).y-1); + (*iter).a *= masterAlpha; + } + + glBindBuffer(GL_ARRAY_BUFFER, m_vboID); + + glBufferData(GL_ARRAY_BUFFER, sizeof(ColoredPoint) * samples, NULL, GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, sizeof(ColoredPoint) * samples, &points_transf[0], GL_DYNAMIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glUseProgram(context.programID_v2f_c4f); + + glUniformMatrix4fv(ShaderEngine::Uniform_V2F_C4F_VertexTranformation(), 1, GL_FALSE, glm::value_ptr(context.mat_ortho)); + + if (additive) glBlendFunc(GL_SRC_ALPHA, GL_ONE); + else glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + if (thick) + { + glLineWidth(context.texsize <= 512 ? 2 : 2*context.texsize/512); + +#ifndef GL_TRANSITION + glPointSize(context.texsize <= 512 ? 2 : 2*context.texsize/512); +#endif + glUniform1f(ShaderEngine::Uniform_V2F_C4F_VertexPointSize(), context.texsize <= 512 ? 2 : 2*context.texsize/512); + } else - glDrawArrays(GL_LINE_STRIP,0,samples); - - check_gl_error(); - - glPointSize(context.texsize < 512 ? 1 : context.texsize/512); - glLineWidth(context.texsize < 512 ? 1 : context.texsize/512); -// glDisable(GL_LINE_STIPPLE); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - delete[] colors; - delete[] p; - delete[] value1; - delete[] value2; -} + { +#ifndef GL_TRANSITION + glPointSize(context.texsize <= 512 ? 1 : context.texsize/512); +#endif + glUniform1f(ShaderEngine::Uniform_V2F_C4F_VertexPointSize(), context.texsize <= 512 ? 1 : context.texsize/512); + } + + glBindVertexArray(m_vaoID); + + if (dots) glDrawArrays(GL_POINTS,0,samples); + else glDrawArrays(GL_LINE_STRIP,0,samples); + + glBindVertexArray(0); + + glLineWidth(context.texsize < 512 ? 1 : context.texsize/512); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + delete[] value1; + delete[] value2; + } diff --git a/src/libprojectM/Renderer/Waveform.hpp b/src/libprojectM/Renderer/Waveform.hpp index b6aa4680d..76f12d5da 100644 --- a/src/libprojectM/Renderer/Waveform.hpp +++ b/src/libprojectM/Renderer/Waveform.hpp @@ -53,6 +53,7 @@ public: int sep; /* no idea what this is yet... */ Waveform(int samples); + void InitVertexAttrib(); void Draw(RenderContext &context); private: diff --git a/src/libprojectM/projectM-opengl.h b/src/libprojectM/projectM-opengl.h index 7f83d86f2..cbbdd49f0 100644 --- a/src/libprojectM/projectM-opengl.h +++ b/src/libprojectM/projectM-opengl.h @@ -5,20 +5,24 @@ #ifndef __PROJECTM_OPENGL_H__ #define __PROJECTM_OPENGL_H__ -// temporary flag signalling that we are using OpenGL 3 (as a stepping stone to getting to GLES compatibility) +// stuff that needs to be ported to newer GL calls #define GL_TRANSITION -void _check_gl_error(const char *file, int line); -#define check_gl_error() _check_gl_error(__FILE__,__LINE__) - #ifdef __APPLE__ -//# include # include +# include #elif defined(_WIN32) # include #else /* linux/unix/other */ -// may need to be changed to use GLES/GL3 or whatever is modern on linux +# ifdef USE_GLES +# include +# else +# if !defined(GL_GLEXT_PROTOTYPES) +# define GL_GLEXT_PROTOTYPES +# endif # include +# include +# endif #endif #endif // __PROJECTM_OPENGL_H__ diff --git a/src/projectM-qt/qplaylistmodel.cpp b/src/projectM-qt/qplaylistmodel.cpp index 7d9daeffb..da1ff282d 100644 --- a/src/projectM-qt/qplaylistmodel.cpp +++ b/src/projectM-qt/qplaylistmodel.cpp @@ -318,11 +318,7 @@ int QPlaylistModel::rowCount ( const QModelIndex & parent ) const int QPlaylistModel::columnCount ( const QModelIndex & parent ) const { - - if ( rowCount() > 0 ) - return softCutRatingsEnabled() ? 3 : 2; - else - return 0; + return softCutRatingsEnabled() ? 3 : 2; } void QPlaylistModel::appendRow ( const QString & presetURL, const QString & presetName, int rating, int breedability ) diff --git a/src/projectM-sdl/pmSDL.cpp b/src/projectM-sdl/pmSDL.cpp index 6d9bd73d0..10b411fd0 100644 --- a/src/projectM-sdl/pmSDL.cpp +++ b/src/projectM-sdl/pmSDL.cpp @@ -7,10 +7,6 @@ #include "pmSDL.hpp" -void projectMSDL::presetSwitchedEvent(bool isHardCut, size_t index) const { - std::cout << "Now using preset: " << getPresetName(index) << std::endl; -} - void projectMSDL::audioInputCallbackF32(void *userdata, unsigned char *stream, int len) { projectMSDL *app = (projectMSDL *) userdata; // printf("LEN: %i\n", len); @@ -99,9 +95,9 @@ int projectMSDL::openAudioInput() { void projectMSDL::beginAudioCapture() { // allocate a buffer to store PCM data for feeding in -// unsigned int maxSamples = audioChannelsCount * audioSampleCount; - pcm()->initPCM(2048); + unsigned int maxSamples = audioChannelsCount * audioSampleCount; SDL_PauseAudioDevice(audioDeviceID, false); + pcm()->initPCM(2048); } void projectMSDL::endAudioCapture() { @@ -232,15 +228,15 @@ projectMSDL::projectMSDL(std::string config_file, int flags) : projectM(config_f isFullScreen = false; } -void projectMSDL::init(SDL_Window *window, SDL_GLContext *ctx) { +void projectMSDL::init(SDL_Window *window, SDL_GLContext *_glCtx) { win = window; - glCtx = ctx; + glCtx = _glCtx; selectRandom(true); projectM_resetGL(width, height); } -//std::string projectMSDL::getActivePresetName() -//{ -// return std::string("hey"); -//} +std::string projectMSDL::getActivePresetName() +{ + return std::string("hey"); +} diff --git a/src/projectM-sdl/pmSDL.hpp b/src/projectM-sdl/pmSDL.hpp index 820880ca2..b79e041dd 100644 --- a/src/projectM-sdl/pmSDL.hpp +++ b/src/projectM-sdl/pmSDL.hpp @@ -35,7 +35,7 @@ public: projectMSDL(Settings settings, int flags); projectMSDL(std::string config_file, int flags); - void init(SDL_Window *window, SDL_GLContext *ctx); + void init(SDL_Window *window, SDL_GLContext *glCtx); int openAudioInput(); void beginAudioCapture(); void endAudioCapture(); @@ -64,8 +64,6 @@ private: static void audioInputCallbackF32(void *userdata, unsigned char *stream, int len); static void audioInputCallbackS16(void *userdata, unsigned char *stream, int len); - virtual void presetSwitchedEvent(bool isHardCut, size_t index) const; - void addFakePCM(); void keyHandler(SDL_Event *); SDL_AudioDeviceID selectAudioInput(int count); diff --git a/src/projectM-sdl/projectM_SDL_main.cpp b/src/projectM-sdl/projectM_SDL_main.cpp index 038da38d9..c9f396a5d 100644 --- a/src/projectM-sdl/projectM_SDL_main.cpp +++ b/src/projectM-sdl/projectM_SDL_main.cpp @@ -8,8 +8,28 @@ #include "pmSDL.hpp" -void configureGL(); -std::string getConfigFilePath(); +#define OGL_DEBUG 0 + +#if OGL_DEBUG +#include + +void DebugLog(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar* message, + const void* userParam) { + + /*if (type != GL_DEBUG_TYPE_OTHER)*/ + { + std::cerr << " -- \n" << "Type: " << + type << "; Source: " << + source <<"; ID: " << id << "; Severity: " << + severity << "\n" << message << "\n"; + } + } +#endif // return path to config file to use std::string getConfigFilePath() { @@ -34,17 +54,8 @@ std::string getConfigFilePath() { return configFilePath; } -void configureGL() { - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); - SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); -} - int main(int argc, char *argv[]) { SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO); - - SDL_LogSetAllPriority(SDL_LOG_PRIORITY_DEBUG); if (! SDL_VERSION_ATLEAST(2, 0, 5)) { SDL_Log("SDL version 2.0.5 or greater is required. You have %i.%i.%i", SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL); @@ -61,11 +72,35 @@ int main(int argc, char *argv[]) { #endif int width = initialWindowBounds.w; int height = initialWindowBounds.h; + int renderIndex = 0; - configureGL(); +#ifdef USE_GLES + for(int i = 0; i < SDL_GetNumRenderDrivers(); i++) { + SDL_RendererInfo info; + if (SDL_GetRenderDriverInfo(i, &info) == 0) { + if (std::string(info.name) == "opengles2") { + renderIndex = i; + break; + } + } + } + +#else + // Disabling compatibility profile + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + +#endif + SDL_Window *win = SDL_CreateWindow("projectM", 0, 0, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); SDL_GLContext glCtx = SDL_GL_CreateContext(win); - check_gl_error(); + + + SDL_Log("GL_VERSION: %s", glGetString(GL_VERSION)); + SDL_Log("GL_SHADING_LANGUAGE_VERSION: %s", glGetString(GL_SHADING_LANGUAGE_VERSION)); + SDL_Log("GL_VENDOR: %s", glGetString(GL_VENDOR)); + SDL_SetWindowTitle(win, "projectM Visualizer"); projectMSDL *app; @@ -75,7 +110,6 @@ int main(int argc, char *argv[]) { if (! configFilePath.empty()) { // found config file, use it - SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "Loading configuration from %s\n", configFilePath.c_str()); app = new projectMSDL(configFilePath, 0); } else { SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "Config file not found, using development settings\n"); @@ -94,15 +128,19 @@ int main(int argc, char *argv[]) { settings.softCutRatingsEnabled = 1; // ??? // get path to our app, use CWD for presets/fonts/etc std::string base_path = SDL_GetBasePath(); - settings.presetURL = base_path + "presets/presets_shader_test"; -// settings.presetURL = base_path + "presets/presets_milkdrop_200"; + settings.presetURL = base_path + "presets/presets_tryptonaut"; settings.menuFontURL = base_path + "fonts/Vera.ttf"; settings.titleFontURL = base_path + "fonts/Vera.ttf"; // init with settings app = new projectMSDL(settings, 0); } app->init(win, &glCtx); - check_gl_error(); + +#if OGL_DEBUG + glEnable(GL_DEBUG_OUTPUT); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + glDebugMessageCallback(DebugLog, NULL); +#endif // get an audio input device app->openAudioInput(); @@ -111,7 +149,6 @@ int main(int argc, char *argv[]) { // standard main loop const Uint32 frame_delay = 1000/FPS; Uint32 last_time = SDL_GetTicks(); - while (! app->done) { app->renderFrame(); app->pollEvent();