]> git.sesse.net Git - movit/commitdiff
Merge branch 'master' into epoxy
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 22 Mar 2014 14:53:11 +0000 (15:53 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 22 Mar 2014 14:53:11 +0000 (15:53 +0100)
101 files changed:
Makefile.in
README
alpha_division_effect_test.cpp
alpha_multiplication_effect_test.cpp
blur_effect.cpp
blur_effect.h
blur_effect_test.cpp
colorspace_conversion_effect_test.cpp
complex_modulate_effect.cpp
complex_modulate_effect.h
complex_modulate_effect_test.cpp
configure.ac
deconvolution_sharpen_effect.cpp
deconvolution_sharpen_effect.h
deconvolution_sharpen_effect_test.cpp
demo.cpp
diffusion_effect.h
diffusion_effect_test.cpp
dither_effect.cpp
dither_effect.frag
dither_effect.h
dither_effect_test.cpp
effect.cpp
effect.h
effect_chain.cpp
effect_chain.h
effect_chain_test.cpp
effect_util.cpp
effect_util.h
fft_convolution_effect.cpp
fft_convolution_effect.h
fft_convolution_effect_test.cpp
fft_input.cpp
fft_input.h
fft_pass_effect.cpp
fft_pass_effect.frag
fft_pass_effect.h
fft_pass_effect_test.cpp
flat_input.cpp
flat_input.frag
flat_input.h
flat_input_test.cpp
footer.130.frag [new file with mode: 0644]
footer.300es.frag [new file with mode: 0644]
gamma_compression_effect.h
gamma_compression_effect_test.cpp
gamma_expansion_effect.h
gamma_expansion_effect_test.cpp
glow_effect.h
glow_effect_test.cpp
gtest_sdl_main.cpp
header.130.frag [new file with mode: 0644]
header.300es.frag [new file with mode: 0644]
header.frag
init.cpp
init.h
lift_gamma_gain_effect.cpp
lift_gamma_gain_effect.h
lift_gamma_gain_effect_test.cpp
luma_mix_effect_test.cpp
mix_effect_test.cpp
movit.pc.in
multiply_effect.h
overlay_effect_test.cpp
padding_effect.cpp
padding_effect.h
padding_effect_test.cpp
resample_effect.cpp
resample_effect.frag
resample_effect.h
resample_effect_test.cpp
resource_pool.cpp
resource_pool.h
sandbox_effect.cpp
sandbox_effect.h
saturation_effect_test.cpp
slice_effect.cpp
slice_effect.h
slice_effect_test.cpp
test_util.cpp
test_util.h
texture1d.130.frag [new file with mode: 0644]
texture1d.300es.frag [new file with mode: 0644]
texture1d.frag
unsharp_mask_effect.h
unsharp_mask_effect_test.cpp
util.cpp
util.h
vignette_effect.cpp
vignette_effect.h
vignette_effect_test.cpp
vs.130.vert [new file with mode: 0644]
vs.300es.vert [new file with mode: 0644]
white_balance_effect.cpp
white_balance_effect.h
white_balance_effect_test.cpp
widgets.cpp
ycbcr_input.cpp
ycbcr_input.frag
ycbcr_input.h
ycbcr_input_test.cpp

index 445f5b7dd96c858f21ca81494d5706cc141fa77d..3b5f6c3ab3a8c08f3119f8992d8e98c2358dfc95 100644 (file)
@@ -17,15 +17,19 @@ datarootdir = @datarootdir@
 datadir = @datadir@
 top_builddir = @top_builddir@
 with_demo_app = @with_demo_app@
+with_SDL2 = @with_SDL2@
 with_coverage = @with_coverage@
 
 CC=@CC@
 CXX=@CXX@
-CXXFLAGS=-Wall @CXXFLAGS@ -I$(GTEST_DIR)/include @Eigen3_CFLAGS@ @GLEW_CFLAGS@ @FFTW3_CFLAGS@
+CXXFLAGS=-Wall @CXXFLAGS@ -I$(GTEST_DIR)/include @SDL2_CFLAGS@ @SDL_CFLAGS@ @Eigen3_CFLAGS@ @epoxy_CFLAGS@ @FFTW3_CFLAGS@
+ifeq ($(with_SDL2),yes)
+CXXFLAGS += -DHAVE_SDL2
+endif
 LDFLAGS=@LDFLAGS@
-LDLIBS=@GLEW_LIBS@ @FFTW3_LIBS@ -lpthread
-TEST_LDLIBS=@GLEW_LIBS@ @SDL_LIBS@ -lpthread
-DEMO_LDLIBS=@SDL_image_LIBS@ -lrt -lpthread @libpng_LIBS@ @FFTW3_LIBS@
+LDLIBS=@epoxy_LIBS@ @FFTW3_LIBS@ -lpthread
+TEST_LDLIBS=@epoxy_LIBS@ @SDL2_LIBS@ @SDL_LIBS@ -lpthread
+DEMO_LDLIBS=@SDL2_image_LIBS@ @SDL_image_LIBS@ -lrt -lpthread @libpng_LIBS@ @FFTW3_LIBS@
 SHELL=@SHELL@
 LIBTOOL=@LIBTOOL@ --tag=CXX
 RANLIB=ranlib
@@ -159,12 +163,14 @@ HDRS = effect_chain.h effect_util.h effect.h input.h image_format.h init.h util.
 HDRS += $(INPUTS:=.h)
 HDRS += $(EFFECTS:=.h)
 
-SHADERS = vs.vert header.frag footer.frag
+SHADERS = vs.vert vs.130.vert vs.300es.vert
+SHADERS += header.frag header.130.frag header.300es.frag
+SHADERS += footer.frag footer.130.frag footer.300es.frag
+SHADERS += texture1d.frag texture1d.130.frag footer.300es.frag
 SHADERS += $(INPUTS:=.frag)
 SHADERS += $(EFFECTS:=.frag)
 SHADERS += highlight_cutoff_effect.frag
 SHADERS += overlay_matte_effect.frag
-SHADERS += texture1d.frag
 
 # These purposefully do not exist.
 MISSING_SHADERS = diffusion_effect.frag glow_effect.frag unsharp_mask_effect.frag resize_effect.frag
diff --git a/README b/README
index f7017bdfbf8babda12f667cda94793f42d6332c0..58dac7aacbf47dfa44cd280391bea0a7375f7ac8 100644 (file)
--- a/README
+++ b/README
@@ -21,12 +21,14 @@ OK, you need
   works fine on Linux and OS X, and Movit is not very POSIX-bound.)
 * GNU Make.
 * A GPU capable of running GLSL fragment shaders,
-  process floating-point textures, and a few other things. If your machine
-  is less than five years old _and you have the appropriate drivers_,
-  you're home free.
+  processing floating-point textures, and a few other things (all are
+  part of OpenGL 3.0 or newer, although most OpenGL 2.0 cards also
+  have what's needed through extensions). If your machine is less than five
+  years old _and you have the appropriate drivers_, you're home free.
+  GLES3 (for mobile devices) will also work.
 * The [Eigen 3], [FFTW3] and [Google Test] libraries. (The library itself
   does not depend on the latter, but you probably want to run the unit tests.)
-* The [GLEW] library, for dealing with OpenGL extensions on various
+* The [epoxy] library, for dealing with OpenGL extensions on various
   platforms.
 
 Movit has been tested with Intel GPUs with the Mesa drivers
@@ -54,7 +56,8 @@ all research-grade problems, and Movit is currently not there.)
 TL;DR, but I am interested in a programming example instead
 ===========================================================
 
-Assuming you have an OpenGL context already set up:
+Assuming you have an OpenGL context already set up (either a classic OpenGL
+context, a GL 3.x forward-compatible or core context, or a GLES3 context):
 
 <code>
   using namespace movit;
index faa8b173b99648e8376ee44bd6801878422b26e8..549b5691f54c65bf2a5b6ea3c9bda761c76ec071 100644 (file)
@@ -1,6 +1,6 @@
 // Unit tests for AlphaDivisionEffect.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include "gtest/gtest.h"
 #include "image_format.h"
 #include "test_util.h"
index c63c0a3087841c3d90244b60dea312751b03acae..2aa9b6d98949d49dc9b554071e8474583e381487 100644 (file)
@@ -1,6 +1,6 @@
 // Unit tests for AlphaMultiplicationEffect.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 
 #include "effect_chain.h"
 #include "gtest/gtest.h"
index d43a7caec77bcf34ce5944f5f332016bc2d740f0..903737a2e01127421a35aea355802c2a7180110d 100644 (file)
@@ -1,4 +1,4 @@
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 #include <math.h>
 #include <algorithm>
index d97f5bdcd2b05352c331ddafb552783444ac8235..ad269f558e57c7112ab1ec07732d227705783048 100644 (file)
@@ -9,7 +9,7 @@
 // which is what the user is intended to use, instantiates two copies of
 // SingleBlurPassEffect behind the scenes).
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 #include <stddef.h>
 #include <string>
index 1ef479ec478d8a9be52ac3f70d87a46be761bd62..fb4e0250ef333a0b5e4586ae88ac681d0463340b 100644 (file)
@@ -1,5 +1,5 @@
 // Unit tests for BlurEffect.
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <math.h>
 #include <string.h>
 
index cf8aad7e4bd41daa8a3737f578d9dc855b4d890d..1395140c81a480a910f8f8691efdae5256e50b04 100644 (file)
@@ -1,6 +1,6 @@
 // Unit tests for ColorspaceConversionEffect.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 
 #include "colorspace_conversion_effect.h"
 #include "gtest/gtest.h"
index 6af589c2cef23364ccbd160b45f6e4040ec39771..9483f6b1f0f09202b54d6c8d8e54cf48f67e274c 100644 (file)
@@ -1,4 +1,4 @@
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 
 #include "complex_modulate_effect.h"
 #include "effect_chain.h"
index 52de229b915eadeb153f177630ea554076f257f3..fd4eb8b2a385adb7db6bc706cb356fdcaa96a3e4 100644 (file)
@@ -21,7 +21,7 @@
 // don't care about the actual FFT result, just that the convolution property
 // holds.)
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <string>
 
 #include "effect.h"
index 8c49d8ae63be202ff53525d13791ca5850e965b5..b505d861bb7b246babd2ae595b60b9d74d3d60f3 100644 (file)
@@ -1,6 +1,6 @@
 // Unit tests for ComplexModulateEffect.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 
 #include "effect_chain.h"
 #include "gtest/gtest.h"
index 93e168b222a924a90310e4b6b0cd3af44258478e..823740b9e610c39b69a898f68fe248d012ae9d6c 100644 (file)
@@ -9,18 +9,27 @@ AC_CONFIG_AUX_DIR(.)
 AC_PROG_CC
 AC_PROG_CXX
 PKG_CHECK_MODULES([Eigen3], [eigen3])
-PKG_CHECK_MODULES([GLEW], [glew])
+PKG_CHECK_MODULES([epoxy], [epoxy])
 PKG_CHECK_MODULES([FFTW3], [fftw3])
 
-# Needed for unit tests and the demo app.
-PKG_CHECK_MODULES([SDL], [sdl])
+# Needed for unit tests and the demo app. We prefer SDL2 if possible,
+# but can also use classic SDL.
+with_SDL2=no
+with_demo_app=yes
+PKG_CHECK_MODULES([SDL2], [sdl2], [with_SDL2=yes], [
+  PKG_CHECK_MODULES([SDL], [sdl])
+])
 
 # These are only needed for the demo app.
-with_demo_app=yes
-PKG_CHECK_MODULES([SDL_image], [SDL_image], [], [with_demo_app=no; AC_MSG_WARN([SDL_image not found, demo program will not be built])])
+if test $with_SDL2 = "yes"; then
+  PKG_CHECK_MODULES([SDL2_image], [SDL2_image], [], [with_demo_app=no; AC_MSG_WARN([SDL2_image not found, demo program will not be built])])
+else
+  PKG_CHECK_MODULES([SDL_image], [SDL_image], [], [with_demo_app=no; AC_MSG_WARN([SDL_image not found, demo program will not be built])])
+fi
 PKG_CHECK_MODULES([libpng], [libpng12], [], [with_demo_app=no; AC_MSG_WARN([libpng12 not found, demo program will not be built])])
 
 AC_SUBST([with_demo_app])
+AC_SUBST([with_SDL2])
 
 with_coverage=no
 AC_ARG_ENABLE([coverage], [  --enable-coverage       build with information needed to compute test coverage], [with_coverage=yes])
index f564b68c4bcc62f350b88ca929d46d4f4cd1bec3..c4ad5cd2cd699b65c223d505dc0fd88932b4e3e1 100644 (file)
@@ -4,7 +4,7 @@
 
 #include <Eigen/Dense>
 #include <Eigen/Cholesky>
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 #include <math.h>
 #include <stdio.h>
index e4cc9a556d224e239e411b98c2c1596374ff182e..1f6807172d85444b6f77c4a93e89e0a0ea6144a3 100644 (file)
@@ -19,7 +19,7 @@
 //
 //   Jain, Anil K.: “Fundamentals of Digital Image Processing”, Prentice Hall, 1988.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <Eigen/Dense>
 #include <string>
 
index 8829b9da21de959685e7346cf7b4374a16b2e936..ab1a5a4a5fc50b48da348f5feba3180e54a0ac0c 100644 (file)
@@ -1,6 +1,6 @@
 // Unit tests for DeconvolutionSharpenEffect.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <math.h>
 #include <stdlib.h>
 
index 845a776d20859b67f829ed69e5070d59cf509132..c9b46ea7ed6f78f08be936cb1c5f6199e8d98141 100644 (file)
--- a/demo.cpp
+++ b/demo.cpp
@@ -4,7 +4,17 @@
 #define WIDTH 1280
 #define HEIGHT 720
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
+
+#ifdef HAVE_SDL2
+#include <SDL2/SDL.h>
+#include <SDL2/SDL_error.h>
+#include <SDL2/SDL_events.h>
+#include <SDL2/SDL_image.h>
+#include <SDL2/SDL_keyboard.h>
+#include <SDL2/SDL_mouse.h>
+#include <SDL2/SDL_video.h>
+#else
 #include <SDL/SDL.h>
 #include <SDL/SDL_error.h>
 #include <SDL/SDL_events.h>
@@ -13,6 +23,8 @@
 #include <SDL/SDL_keysym.h>
 #include <SDL/SDL_mouse.h>
 #include <SDL/SDL_video.h>
+#endif
+
 #include <assert.h>
 #include <features.h>
 #include <math.h>
@@ -121,9 +133,11 @@ unsigned char *load_image(const char *filename, unsigned *w, unsigned *h)
        rgba_fmt.Gshift = 8;
        rgba_fmt.Bshift = 0;
        rgba_fmt.Ashift = 24;
-       
+
+#ifndef HAVE_SDL2
        rgba_fmt.colorkey = 0;
        rgba_fmt.alpha = 255;
+#endif
 
        SDL_Surface *converted = SDL_ConvertSurface(img, &rgba_fmt, SDL_SWSURFACE);
 
@@ -175,8 +189,19 @@ int main(int argc, char **argv)
        SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
        SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 0);
        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+
+#ifdef HAVE_SDL2
+       SDL_Window *window = SDL_CreateWindow("OpenGL window",
+               SDL_WINDOWPOS_UNDEFINED,
+               SDL_WINDOWPOS_UNDEFINED,
+               WIDTH, HEIGHT,
+               SDL_WINDOW_OPENGL);
+       SDL_GLContext context = SDL_GL_CreateContext(window);
+       assert(context != NULL);
+#else
        SDL_SetVideoMode(WIDTH, HEIGHT, 0, SDL_OPENGL);
        SDL_WM_SetCaption("OpenGL window", NULL);
+#endif
 
        CHECK(init_movit(".", MOVIT_DEBUG_ON));
        printf("GPU texture subpixel precision: about %.1f bits\n",
@@ -288,7 +313,11 @@ int main(int argc, char **argv)
                draw_saturation_bar(0.75f, blur_radius / 100.0f);
                draw_saturation_bar(0.80f, blurred_mix_amount);
 
+#ifdef HAVE_SDL2
+               SDL_GL_SwapWindow(window);
+#else
                SDL_GL_SwapBuffers();
+#endif
                check_error();
 
                glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, pbo);
index 2c31e4ae348524e23ba2b55e344a739d01b2092c..82eda939779b1addd847a9aa7d1cf4640817b7c0 100644 (file)
@@ -12,7 +12,7 @@
 // where we first blur the picture, and then overlay it on the original
 // using the original as a matte.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 #include <string>
 
index 7e50a04d8bcc7071167b026aae8dcfcf84c30da6..e58c0deef941b2f9b65005fdddf058cc1f0ebe99 100644 (file)
@@ -1,6 +1,6 @@
 // Unit tests for DiffusionEffect.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 
 #include "diffusion_effect.h"
 #include "effect_chain.h"
index 72a38deb46490aac5e738a6bf19e48b674a6c45a..17c577d4cdacc3ae44a4c79015d46c6e888389d6 100644 (file)
@@ -1,4 +1,4 @@
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 #include <stdio.h>
 #include <algorithm>
index 6994e8467f0c9645e47d9f74ff96700028eafddf..3b6b892d7606937867b4ab0c2b749926034d9f29 100644 (file)
@@ -9,7 +9,7 @@ vec4 FUNCNAME(vec2 tc) {
        // and if there's any inaccuracy earlier in the chain so that it becomes e.g.
        // 254.8, it's better to just get it rounded off than to dither and have it
        // possibly get down to 254. This is not the case for the color components.
-       result.rgb += texture2D(PREFIX(dither_tex), tc * PREFIX(tc_scale)).xxx;
+       result.rgb += tex2D(PREFIX(dither_tex), tc * PREFIX(tc_scale)).xxx;
 
        // NEED_EXPLICIT_ROUND will be #defined to 1 if the GPU has inaccurate
        // fp32 -> int8 framebuffer rounding, and 0 otherwise.
index 20fb025532d5fea4e92329c7733d06669354b39d..9818603c2a46f4a659628b68c03be5fed3f868ac 100644 (file)
@@ -43,7 +43,7 @@
 // like many LCD monitors do, but it starts to get very hairy, again, for limited gains.)
 // The dither is also deterministic across runs.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <string>
 
 #include "effect.h"
index 18b286ed3e3210c4fa0c0546b1739f5df4759baf..1b72ecb5caec50c93d3ad34fc56a2e09ef390e26 100644 (file)
@@ -1,6 +1,6 @@
 // Unit tests for DitherEffect.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <math.h>
 
 #include "effect_chain.h"
index eded11a7ef5746a6563bd9f157019bb0abcc1a2c..fb66514a290d1cb780c6a87b2fae4b97a8d9627f 100644 (file)
@@ -1,4 +1,4 @@
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 #include <stdio.h>
 #include <string.h>
index 14cbe301fa08d55154e8cd1b1e149fce84c6f9e2..9d95705f6a66ce344a54bd18eb83154018d85c35 100644 (file)
--- a/effect.h
+++ b/effect.h
@@ -10,7 +10,7 @@
 // effect instance; use the macro PREFIX() around your identifiers to
 // automatically prepend that prefix.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 #include <stddef.h>
 #include <map>
index e4ab7199c8d23320c545d47c98b4c53dec39af3b..7bce60fa21c1e076c3082d69ff2e409cc342750a 100644 (file)
@@ -1,6 +1,6 @@
 #define GL_GLEXT_PROTOTYPES 1
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 #include <locale.h>
 #include <math.h>
@@ -238,7 +238,7 @@ string replace_prefix(const string &text, const string &prefix)
 
 void EffectChain::compile_glsl_program(Phase *phase)
 {
-       string frag_shader = read_file("header.frag");
+       string frag_shader = read_version_dependent_file("header", "frag");
 
        // Create functions for all the texture inputs that we need.
        for (unsigned i = 0; i < phase->inputs.size(); ++i) {
@@ -249,7 +249,7 @@ void EffectChain::compile_glsl_program(Phase *phase)
        
                frag_shader += string("uniform sampler2D tex_") + effect_id + ";\n";
                frag_shader += string("vec4 ") + effect_id + "(vec2 tc) {\n";
-               frag_shader += "\treturn texture2D(tex_" + string(effect_id) + ", tc);\n";
+               frag_shader += "\treturn tex2D(tex_" + string(effect_id) + ", tc);\n";
                frag_shader += "}\n";
                frag_shader += "\n";
        }
@@ -288,9 +288,10 @@ void EffectChain::compile_glsl_program(Phase *phase)
                frag_shader += "\n";
        }
        frag_shader += string("#define INPUT ") + phase->effect_ids[phase->effects.back()] + "\n";
-       frag_shader.append(read_file("footer.frag"));
+       frag_shader.append(read_version_dependent_file("footer", "frag"));
 
-       phase->glsl_program_num = resource_pool->compile_glsl_program(read_file("vs.vert"), frag_shader);
+       string vert_shader = read_version_dependent_file("vs", "vert");
+       phase->glsl_program_num = resource_pool->compile_glsl_program(vert_shader, frag_shader);
 
        // Prepare the geometry for the fullscreen quad used in this phase.
        // (We have separate VAOs per shader, since the bindings can in theory
index 903018bc3ab87a60dd159e3ff13d8edcec0b3171..e7d99d54821928c1248f6456c461ba1f63525eed 100644 (file)
@@ -17,7 +17,7 @@
 // the EffectChain holds textures and other OpenGL objects that are tied to the
 // context.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <stdio.h>
 #include <map>
 #include <set>
index 673e9cc3665fd1acac09d9815eaa84947d416e22..50d004db1c52c1192946b87add1b785149f585fc 100644 (file)
@@ -2,7 +2,7 @@
 //
 // Note that this also contains the tests for some of the simpler effects.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 
 #include "effect.h"
@@ -152,19 +152,23 @@ TEST(EffectChainTest, RewritingWorksAndGammaConversionsAreInserted) {
 
 TEST(EffectChainTest, RewritingWorksAndTexturesAreAskedForsRGB) {
        unsigned char data[] = {
-               0, 64,
-               128, 255,
+                 0,   0,   0, 255,
+                64,  64,  64, 255,
+               128, 128, 128, 255,
+               255, 255, 255, 255,
        };
-       float expected_data[4] = {
-               1.0f, 0.9771f,
-               0.8983f, 0.0f,
+       float expected_data[] = {
+               1.0000f, 1.0000f, 1.0000f, 1.0000f,
+               0.9771f, 0.9771f, 0.9771f, 1.0000f,
+               0.8983f, 0.8983f, 0.8983f, 1.0000f,
+               0.0000f, 0.0000f, 0.0000f, 1.0000f
        };
-       float out_data[4];
-       EffectChainTester tester(NULL, 2, 2);
-       tester.add_input(data, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_sRGB);
+       float out_data[4 * 4];
+       EffectChainTester tester(NULL, 1, 4);
+       tester.add_input(data, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, GAMMA_sRGB);
        RewritingEffect<InvertEffect> *effect = new RewritingEffect<InvertEffect>();
        tester.get_chain()->add_effect(effect);
-       tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_sRGB);
+       tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_sRGB);
 
        Node *node = effect->replaced_node;
        ASSERT_EQ(1, node->incoming_links.size());
@@ -172,7 +176,7 @@ TEST(EffectChainTest, RewritingWorksAndTexturesAreAskedForsRGB) {
        EXPECT_EQ("FlatInput", node->incoming_links[0]->effect->effect_type_id());
        EXPECT_EQ("GammaCompressionEffect", node->outgoing_links[0]->effect->effect_type_id());
 
-       expect_equal(expected_data, out_data, 2, 2);
+       expect_equal(expected_data, out_data, 4, 4);
 }
 
 TEST(EffectChainTest, RewritingWorksAndColorspaceConversionsAreInserted) {
index d485d4691cc3d16a04ce1643a485f94504664cd4..dbeb48b0381a12bd682c018c799199c5869f39cb 100644 (file)
@@ -1,4 +1,4 @@
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <Eigen/Core>
 #include <stddef.h>
 #include <string>
index 5420ce516518a1cb7e9fef2f6aa8bf81c3ea28f5..a1588efd71da6203a3cb137e1e1c9c38b62409b6 100644 (file)
@@ -4,7 +4,7 @@
 // Utilities that are often useful for implementing Effect instances,
 // but don't need to be included from effect.h.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 #include <stddef.h>
 #include <Eigen/Core>
index b3f77bdc3218667175e4aee39334f739128d6886..1c48142026035193b9a478344e0f6f479bd60dc5 100644 (file)
@@ -1,4 +1,4 @@
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <string.h>
 
 #include "complex_modulate_effect.h"
index a2b8062801edef2a0246ec2fba22ea1b2265ab4a..e19a804d604c4097c4031719fbf6d40cc138329c 100644 (file)
@@ -72,7 +72,7 @@
 // time, which in turn means you cannot change image or kernel size on the fly.
 
 #include <assert.h>
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <string>
 
 #include "effect.h"
index f0f85278cd1ae045226d165d29c3f380946cd8f8..a55fe3128ad040e73dccf4268ce0edf17be57e27 100644 (file)
@@ -1,6 +1,6 @@
 // Unit tests for FFTConvolutionEffect.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <math.h>
 
 #include "effect_chain.h"
index ba539b6b54e1f18fe0da2a629b1b1d00a7a8fe65..c88a7c4b12fe9947cc6cd2a43f3b4ff0ba2d6e01 100644 (file)
@@ -1,6 +1,6 @@
 #include <string.h>
 #include <assert.h>
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <fftw3.h>
 
 #include "effect_util.h"
@@ -104,7 +104,8 @@ void FFTInput::set_gl_state(GLuint glsl_program_num, const string& prefix, unsig
 
 string FFTInput::output_fragment_shader()
 {
-       return read_file("flat_input.frag");
+       return string("#define FIXUP_SWAP_RB 0\n#define FIXUP_RED_TO_GRAYSCALE 0\n") +
+               read_file("flat_input.frag");
 }
 
 void FFTInput::invalidate_pixel_data()
index 681876baa2476429b2fae0b6adbe65ddb2cfa4d1..b57723cd61a92251bf6a870a6542d585fbf7d28d 100644 (file)
@@ -14,7 +14,7 @@
 //
 // This class is tested as part of by FFTConvolutionEffectTest.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 #include <string>
 
index 4069be93f636d72a7682cb4971a2d9822afc4f98..ee0b983ae92002875d5b8e86538e21b09846991b 100644 (file)
@@ -1,4 +1,4 @@
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <math.h>
 
 #include "effect_chain.h"
index edcf6951815b1a9a1a09906f3082dad5ff36ef63..607f86ab0149dab1d97e7aefeb77454b193e8fa9 100644 (file)
@@ -6,11 +6,11 @@ uniform sampler2D PREFIX(support_tex);
 
 vec4 FUNCNAME(vec2 tc) {
 #if DIRECTION_VERTICAL
-       vec4 support = texture2D(PREFIX(support_tex), vec2(tc.y * PREFIX(num_repeats), 0.0));
+       vec4 support = tex2D(PREFIX(support_tex), vec2(tc.y * PREFIX(num_repeats), 0.0));
         vec4 c1 = INPUT(vec2(tc.x, tc.y + support.x));
         vec4 c2 = INPUT(vec2(tc.x, tc.y + support.y));
 #else
-       vec4 support = texture2D(PREFIX(support_tex), vec2(tc.x * PREFIX(num_repeats), 0.0));
+       vec4 support = tex2D(PREFIX(support_tex), vec2(tc.x * PREFIX(num_repeats), 0.0));
         vec4 c1 = INPUT(vec2(tc.x + support.x, tc.y));
         vec4 c2 = INPUT(vec2(tc.x + support.y, tc.y));
 #endif
index 460a946be4dcbdb24f8bddfcc011cb3cdb6af6a0..90e88bc1fddd94650c1deae08011e9c2d0e5395e 100644 (file)
@@ -50,7 +50,7 @@
 // scaling), and as fp16 has quite limited range at times, this can be relevant
 // on some GPUs for larger sizes.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 #include <stdio.h>
 #include <string>
index 284aa5fd28ee815af0ea976006e3837d661cea31..015847ad72838c880eb107ac9b71559ddc494b14 100644 (file)
@@ -3,11 +3,11 @@
 #include <math.h>
 #include <stdlib.h>
 #include <string.h>
+#include <epoxy/gl.h>
+#include <gtest/gtest.h>
 
 #include "effect_chain.h"
 #include "fft_pass_effect.h"
-#include "glew.h"
-#include "gtest/gtest.h"
 #include "image_format.h"
 #include "multiply_effect.h"
 #include "test_util.h"
index a95b90e563f9d268378461dc196f67b282c4a670..f6ae827338d7f75c9b76c4c9fe1612dedc75fbfc 100644 (file)
@@ -1,6 +1,6 @@
 #include <string.h>
 #include <assert.h>
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 
 #include "effect_util.h"
 #include "flat_input.h"
@@ -11,9 +11,8 @@ using namespace std;
 
 namespace movit {
 
-FlatInput::FlatInput(ImageFormat image_format, MovitPixelFormat pixel_format, GLenum type, unsigned width, unsigned height)
+FlatInput::FlatInput(ImageFormat image_format, MovitPixelFormat pixel_format_in, GLenum type, unsigned width, unsigned height)
        : image_format(image_format),
-          pixel_format(pixel_format),
          type(type),
          pbo(0),
          texture_num(0),
@@ -22,11 +21,37 @@ FlatInput::FlatInput(ImageFormat image_format, MovitPixelFormat pixel_format, GL
          width(width),
          height(height),
          pitch(width),
-         pixel_data(NULL)
+         pixel_data(NULL),
+         fixup_swap_rb(false),
+         fixup_red_to_grayscale(false)
 {
        assert(type == GL_FLOAT || type == GL_HALF_FLOAT || type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_BYTE);
        register_int("output_linear_gamma", &output_linear_gamma);
        register_int("needs_mipmaps", &needs_mipmaps);
+
+       // Some types are not supported in all GL versions (e.g. GLES),
+       // and will corrected into the right format in the shader.
+       switch (pixel_format_in) {
+       case FORMAT_BGRA_PREMULTIPLIED_ALPHA:
+               pixel_format = FORMAT_RGBA_PREMULTIPLIED_ALPHA;
+               fixup_swap_rb = true;
+               break;
+       case FORMAT_BGRA_POSTMULTIPLIED_ALPHA:
+               pixel_format = FORMAT_RGBA_POSTMULTIPLIED_ALPHA;
+               fixup_swap_rb = true;
+               break;
+       case FORMAT_BGR:
+               pixel_format = FORMAT_RGB;
+               fixup_swap_rb = true;
+               break;
+       case FORMAT_GRAYSCALE:
+               pixel_format = FORMAT_R;
+               fixup_red_to_grayscale = true;
+               break;
+       default:
+               pixel_format = pixel_format_in;
+               break;
+       }
 }
 
 FlatInput::~FlatInput()
@@ -50,6 +75,8 @@ void FlatInput::set_gl_state(GLuint glsl_program_num, const string& prefix, unsi
                                internal_format = GL_R32F;
                        } else if (pixel_format == FORMAT_RG) {
                                internal_format = GL_RG32F;
+                       } else if (pixel_format == FORMAT_RGB) {
+                               internal_format = GL_RGB32F;
                        } else {
                                internal_format = GL_RGBA32F;
                        }
@@ -58,6 +85,8 @@ void FlatInput::set_gl_state(GLuint glsl_program_num, const string& prefix, unsi
                                internal_format = GL_R16F;
                        } else if (pixel_format == FORMAT_RG) {
                                internal_format = GL_RG16F;
+                       } else if (pixel_format == FORMAT_RGB) {
+                               internal_format = GL_RGB16F;
                        } else {
                                internal_format = GL_RGBA16F;
                        }
@@ -66,18 +95,28 @@ void FlatInput::set_gl_state(GLuint glsl_program_num, const string& prefix, unsi
                                internal_format = GL_R16;
                        } else if (pixel_format == FORMAT_RG) {
                                internal_format = GL_RG16;
+                       } else if (pixel_format == FORMAT_RGB) {
+                               internal_format = GL_RGB16;
                        } else {
                                internal_format = GL_RGBA16;
                        }
                } else if (output_linear_gamma) {
                        assert(type == GL_UNSIGNED_BYTE);
-                       internal_format = GL_SRGB8_ALPHA8;
+                       if (pixel_format == FORMAT_RGB) {
+                               internal_format = GL_SRGB8;
+                       } else if (pixel_format == FORMAT_RGBA_POSTMULTIPLIED_ALPHA) {
+                               internal_format = GL_SRGB8_ALPHA8;
+                       } else {
+                               assert(false);
+                       }
                } else {
                        assert(type == GL_UNSIGNED_BYTE);
                        if (pixel_format == FORMAT_R) {
                                internal_format = GL_R8;
                        } else if (pixel_format == FORMAT_RG) {
                                internal_format = GL_RG8;
+                       } else if (pixel_format == FORMAT_RGB) {
+                               internal_format = GL_RGB8;
                        } else {
                                internal_format = GL_RGBA8;
                        }
@@ -87,15 +126,10 @@ void FlatInput::set_gl_state(GLuint glsl_program_num, const string& prefix, unsi
                } else if (pixel_format == FORMAT_RGBA_PREMULTIPLIED_ALPHA ||
                           pixel_format == FORMAT_RGBA_POSTMULTIPLIED_ALPHA) {
                        format = GL_RGBA;
-               } else if (pixel_format == FORMAT_BGR) {
-                       format = GL_BGR;
-               } else if (pixel_format == FORMAT_BGRA_PREMULTIPLIED_ALPHA ||
-                          pixel_format == FORMAT_BGRA_POSTMULTIPLIED_ALPHA) {
-                       format = GL_BGRA;
-               } else if (pixel_format == FORMAT_GRAYSCALE) {
-                       format = GL_LUMINANCE;
                } else if (pixel_format == FORMAT_RG) {
                        format = GL_RG;
+               } else if (pixel_format == FORMAT_R) {
+                       format = GL_RED;
                } else {
                        assert(false);
                }
@@ -140,7 +174,10 @@ void FlatInput::set_gl_state(GLuint glsl_program_num, const string& prefix, unsi
 
 string FlatInput::output_fragment_shader()
 {
-       return read_file("flat_input.frag");
+       char buf[256];
+       sprintf(buf, "#define FIXUP_SWAP_RB %d\n#define FIXUP_RED_TO_GRAYSCALE %d\n",
+               fixup_swap_rb, fixup_red_to_grayscale);
+       return buf + read_file("flat_input.frag");
 }
 
 void FlatInput::invalidate_pixel_data()
index d7c04cc5718f7fc5f0d38923932a601751426f41..855d4fbbfe1c1b888ae52ee24112eb3868131996 100644 (file)
@@ -6,5 +6,17 @@ vec4 FUNCNAME(vec2 tc) {
        // we flip the y coordinate.
        tc.y = 1.0 - tc.y;
 
-       return texture2D(PREFIX(tex), tc);
+       vec4 pixel = tex2D(PREFIX(tex), tc);
+
+       // These two are #defined to 0 or 1 in flat_input.cpp.
+#if FIXUP_SWAP_RB
+       pixel.rb = pixel.br;
+#endif
+#if FIXUP_RED_TO_GRAYSCALE
+       pixel.gb = pixel.rr;
+#endif
+       return pixel;
 }
+
+#undef FIXUP_SWAP_RB
+#undef FIXUP_RED_TO_GRAYSCALE
index 965e34ddd1b79f8c6b996a572e0edb9a80622586..25b9091abc837baa699d5d36bc2c0b94253dc97a 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _MOVIT_FLAT_INPUT_H
 #define _MOVIT_FLAT_INPUT_H 1
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 #include <string>
 
@@ -26,23 +26,26 @@ public:
        virtual std::string effect_type_id() const { return "FlatInput"; }
 
        virtual bool can_output_linear_gamma() const {
+               // On desktop OpenGL, there's also GL_SLUMINANCE8 which could give us
+               // support for single-channel sRGB decoding, but it's not supported
+               // on GLES, and we're already actively rewriting single-channel inputs
+               // to GL_RED (even on desktop), so we stick to 3- and 4-channel inputs.
                return (movit_srgb_textures_supported &&
                        type == GL_UNSIGNED_BYTE &&
+                       (pixel_format == FORMAT_RGB ||
+                        pixel_format == FORMAT_RGBA_POSTMULTIPLIED_ALPHA) &&
                        (image_format.gamma_curve == GAMMA_LINEAR ||
                         image_format.gamma_curve == GAMMA_sRGB));
        }
        virtual AlphaHandling alpha_handling() const {
                switch (pixel_format) {
                case FORMAT_RGBA_PREMULTIPLIED_ALPHA:
-               case FORMAT_BGRA_PREMULTIPLIED_ALPHA:
                        return INPUT_AND_OUTPUT_PREMULTIPLIED_ALPHA;
                case FORMAT_RGBA_POSTMULTIPLIED_ALPHA:
-               case FORMAT_BGRA_POSTMULTIPLIED_ALPHA:
                        return OUTPUT_POSTMULTIPLIED_ALPHA;
+               case FORMAT_R:
                case FORMAT_RG:
                case FORMAT_RGB:
-               case FORMAT_BGR:
-               case FORMAT_GRAYSCALE:
                        return OUTPUT_BLANK_ALPHA;
                default:
                        assert(false);
@@ -123,6 +126,7 @@ private:
        unsigned width, height, pitch;
        const void *pixel_data;
        ResourcePool *resource_pool;
+       bool fixup_swap_rb, fixup_red_to_grayscale;
 };
 
 }  // namespace movit
index 58d9eb94b199a2c807c7a44397e23caed79eba69..397cae3c26d788f7abe5ed10ba064f23b60d2cbd 100644 (file)
@@ -1,6 +1,6 @@
 // Unit tests for FlatInput.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <stddef.h>
 
 #include "effect_chain.h"
diff --git a/footer.130.frag b/footer.130.frag
new file mode 100644 (file)
index 0000000..83f615f
--- /dev/null
@@ -0,0 +1,6 @@
+out vec4 FragColor;
+
+void main()
+{
+       FragColor = INPUT(tc);
+}
diff --git a/footer.300es.frag b/footer.300es.frag
new file mode 100644 (file)
index 0000000..83f615f
--- /dev/null
@@ -0,0 +1,6 @@
+out vec4 FragColor;
+
+void main()
+{
+       FragColor = INPUT(tc);
+}
index 83208cf0dcc44d77412c5a595f6cab9906b75e0a..ee3985f9fa03c807b2928dac5176e9b0baf58eff 100644 (file)
@@ -9,7 +9,7 @@
 // Note that Movit's internal formats generally do not have enough accuracy
 // for 12-bit input or output.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <string>
 
 #include "effect.h"
index 41fe776c28079e1783d05065fcd6bc0d80796db2..6efbdea0944211a82e157518b616fb71b0cdf0a1 100644 (file)
@@ -5,7 +5,7 @@
 // However, the accuracy tests are somewhat simpler, since we
 // only need to care about absolute errors and not relative.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <math.h>
 
 #include "gtest/gtest.h"
index b5381ad38cdc76fa3b5aa2eb01da20df64111c4b..81f42d137392cf7e0c08ba557f3a3d090f708f7f 100644 (file)
@@ -9,7 +9,7 @@
 // Note that Movit's internal formats generally do not have enough accuracy
 // for 12-bit input or output.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <string>
 
 #include "effect.h"
index d1d6d2a0ac0afabac906311adb5812e7ef17858f..499a0d47caba00a71cdc068a9fb956d7759df292 100644 (file)
@@ -1,6 +1,6 @@
 // Unit tests for GammaExpansionEffect.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <math.h>
 
 #include "gamma_expansion_effect.h"
index af833070558a05ce46e4aa5865516da0714cd740..2a2af16dd3abbd7d1bded97de0aaad88475b63bf 100644 (file)
@@ -4,7 +4,7 @@
 // Glow: Cut out the highlights of the image (everything above a certain threshold),
 // blur them, and overlay them onto the original image.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 #include <string>
 
index 11083a9ca75a3412fe88a9c6b2e4c4914df6b7d5..174937be5fae6fb47f8c488a4dbef9bcf29bd606 100644 (file)
@@ -1,6 +1,6 @@
 // Unit tests for GlowEffect.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <math.h>
 
 #include "effect_chain.h"
index 39027e6be3246f75fae37a09d333859920ff539b..cd68777721e19cc92b300920fd094473ef5d5a7d 100644 (file)
@@ -1,8 +1,14 @@
 #define GTEST_HAS_EXCEPTIONS 0
 
+#ifdef HAVE_SDL2
+#include <SDL2/SDL.h>
+#include <SDL2/SDL_error.h>
+#include <SDL2/SDL_video.h>
+#else
 #include <SDL/SDL.h>
 #include <SDL/SDL_error.h>
 #include <SDL/SDL_video.h>
+#endif
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -17,8 +23,28 @@ int main(int argc, char **argv) {
        SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
        SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 0);
        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+
+#ifdef HAVE_SDL2
+       // You can uncomment this if you want to try a core context.
+       // For Mesa, you can get the same effect by doing
+       //
+       //   export MESA_GL_VERSION_OVERRIDE=3.1FC
+       //
+       // before running tests.
+//     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_Window *window = SDL_CreateWindow("OpenGL window for unit test",
+               SDL_WINDOWPOS_UNDEFINED,
+               SDL_WINDOWPOS_UNDEFINED,
+               32, 32,
+               SDL_WINDOW_OPENGL);
+       SDL_GLContext context = SDL_GL_CreateContext(window);
+       assert(context != NULL);
+#else
        SDL_SetVideoMode(32, 32, 0, SDL_OPENGL);
        SDL_WM_SetCaption("OpenGL window for unit test", NULL);
+#endif
 
        testing::InitGoogleTest(&argc, argv);
        int err = RUN_ALL_TESTS();
diff --git a/header.130.frag b/header.130.frag
new file mode 100644 (file)
index 0000000..129f493
--- /dev/null
@@ -0,0 +1,8 @@
+#version 130
+
+in vec2 tc;
+
+vec4 tex2D(sampler2D s, vec2 coord)
+{
+       return texture(s, coord);
+}
diff --git a/header.300es.frag b/header.300es.frag
new file mode 100644 (file)
index 0000000..ea52263
--- /dev/null
@@ -0,0 +1,10 @@
+#version 300 es
+
+precision highp float;
+
+in vec2 tc;
+
+vec4 tex2D(sampler2D s, vec2 coord)
+{
+       return texture(s, coord);
+}
index af211fee6de53e2f02c5018d5ae5e59157117351..44ce5b4238d3478cb073cc2b015098c2a2e7d578 100644 (file)
@@ -1,6 +1,15 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+
 #ifdef GL_EXT_gpu_shader4
 // We sometimes want round().
 #extension GL_EXT_gpu_shader4 : enable
 #endif
 
 varying vec2 tc;
+
+vec4 tex2D(sampler2D s, vec2 coord)
+{
+       return texture2D(s, coord);
+}
index 37e9d70f974ec160c7bd7b2f169767cdcf17b263..4802c68712e3b69b086eb5877da28528fc457c3f 100644 (file)
--- a/init.cpp
+++ b/init.cpp
@@ -1,4 +1,4 @@
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 #include <stddef.h>
 #include <algorithm>
@@ -18,6 +18,7 @@ float movit_texel_subpixel_precision;
 bool movit_srgb_textures_supported;
 int movit_num_wrongly_rounded;
 bool movit_shader_rounding_supported;
+MovitShaderModel movit_shader_model;
 
 // The rules for objects with nontrivial constructors in static scope
 // are somewhat convoluted, and easy to mess up. We simply have a
@@ -78,7 +79,8 @@ void measure_texel_subpixel_precision()
        glViewport(0, 0, width, 1);
 
        GLuint glsl_program_num = resource_pool.compile_glsl_program(
-               read_file("vs.vert"), read_file("texture1d.frag"));
+               read_version_dependent_file("vs", "vert"),
+               read_version_dependent_file("texture1d", "frag"));
        glUseProgram(glsl_program_num);
        check_error();
        glUniform1i(glGetUniformLocation(glsl_program_num, "tex"), 0);  // Bind the 2D sampler.
@@ -122,14 +124,14 @@ void measure_texel_subpixel_precision()
        // Now read the data back and see what the card did.
        // (We only look at the red channel; the others will surely be the same.)
        // We assume a linear ramp; anything else will give sort of odd results here.
-       float out_data[width];
-       glReadPixels(0, 0, width, 1, GL_RED, GL_FLOAT, out_data);
+       float out_data[width * 4];
+       glReadPixels(0, 0, width, 1, GL_RGBA, GL_FLOAT, out_data);
        check_error();
 
        float biggest_jump = 0.0f;
        for (unsigned i = 1; i < width; ++i) {
-               assert(out_data[i] >= out_data[i - 1]);
-               biggest_jump = max(biggest_jump, out_data[i] - out_data[i - 1]);
+               assert(out_data[i * 4] >= out_data[(i - 1) * 4]);
+               biggest_jump = max(biggest_jump, out_data[i * 4] - out_data[(i - 1) * 4]);
        }
 
        assert(biggest_jump > 0.0);
@@ -209,7 +211,8 @@ void measure_roundoff_problems()
        glViewport(0, 0, 512, 1);
 
        GLuint glsl_program_num = resource_pool.compile_glsl_program(
-               read_file("vs.vert"), read_file("texture1d.frag"));
+               read_version_dependent_file("vs", "vert"),
+               read_version_dependent_file("texture1d", "frag"));
        glUseProgram(glsl_program_num);
        check_error();
        glUniform1i(glGetUniformLocation(glsl_program_num, "tex"), 0);  // Bind the 2D sampler.
@@ -242,16 +245,16 @@ void measure_roundoff_problems()
 
        // Now read the data back and see what the card did. (Ignore the last value.)
        // (We only look at the red channel; the others will surely be the same.)
-       unsigned char out_data[512];
-       glReadPixels(0, 0, 512, 1, GL_RED, GL_UNSIGNED_BYTE, out_data);
+       unsigned char out_data[512 * 4];
+       glReadPixels(0, 0, 512, 1, GL_RGBA, GL_UNSIGNED_BYTE, out_data);
        check_error();
 
        int wrongly_rounded = 0;
        for (unsigned i = 0; i < 255; ++i) {
-               if (out_data[i * 2 + 0] != i) {
+               if (out_data[(i * 2 + 0) * 4] != i) {
                        ++wrongly_rounded;
                }
-               if (out_data[i * 2 + 1] != i + 1) {
+               if (out_data[(i * 2 + 1) * 4] != i + 1) {
                        ++wrongly_rounded;
                }
        }
@@ -277,37 +280,88 @@ void measure_roundoff_problems()
 
 bool check_extensions()
 {
+       // GLES generally doesn't use extensions as actively as desktop OpenGL.
+       // For now, we say that for GLES, we require GLES 3, which has everything
+       // we need.
+       //
+       // Since we use implicit #version 100, we don't have round(). We will
+       // fix this at some later stage.
+       if (!epoxy_is_desktop_gl()) {
+               if (epoxy_gl_version() >= 30) {
+                       movit_srgb_textures_supported = true;
+                       movit_shader_rounding_supported = false;
+               } else {
+                       return false;
+               }
+       }
+
        // We fundamentally need FBOs and floating-point textures.
-       if (!glewIsSupported("GL_ARB_framebuffer_object")) return false;
-       if (!glewIsSupported("GL_ARB_texture_float")) return false;
+       // FBOs are covered by OpenGL 1.5, and are not an extension there.
+       // Floating-point textures are part of OpenGL 3.0 and newer.
+       if (epoxy_gl_version() < 15 &&
+           !epoxy_has_gl_extension("GL_ARB_framebuffer_object")) return false;
+       if (epoxy_gl_version() < 30 &&
+           !epoxy_has_gl_extension("GL_ARB_texture_float")) return false;
 
        // We assume that we can use non-power-of-two textures without restrictions.
-       if (!glewIsSupported("GL_ARB_texture_non_power_of_two")) return false;
+       if (epoxy_gl_version() < 20 &&
+           !epoxy_has_gl_extension("GL_ARB_texture_non_power_of_two")) return false;
 
        // We also need GLSL fragment shaders.
-       if (!glewIsSupported("GL_ARB_fragment_shader")) return false;
-       if (!glewIsSupported("GL_ARB_shading_language_100")) return false;
+       if (epoxy_gl_version() < 20) {
+               if (!epoxy_has_gl_extension("GL_ARB_fragment_shader")) return false;
+               if (!epoxy_has_gl_extension("GL_ARB_shading_language_100")) return false;
+       }
 
        // FlatInput and YCbCrInput uses PBOs. (They could in theory do without,
        // but no modern card would really not provide it.)
-       if (!glewIsSupported("GL_ARB_pixel_buffer_object")) return false;
+       if (epoxy_gl_version() < 21 &&
+           !epoxy_has_gl_extension("GL_ARB_pixel_buffer_object")) return false;
 
        // ResampleEffect uses RG textures to encode a two-component LUT.
-       if (!glewIsSupported("GL_ARB_texture_rg")) return false;
+       if (epoxy_gl_version() < 30 &&
+           !epoxy_has_gl_extension("GL_ARB_texture_rg")) return false;
 
        // sRGB texture decode would be nice, but are not mandatory
        // (GammaExpansionEffect can do the same thing if needed).
-       movit_srgb_textures_supported = glewIsSupported("GL_EXT_texture_sRGB");
+       movit_srgb_textures_supported =
+               (epoxy_gl_version() >= 21 || epoxy_has_gl_extension("GL_EXT_texture_sRGB"));
 
        // We may want to use round() at the end of the final shader,
        // if supported. We need either GLSL 1.30 or this extension to do that,
        // and 1.30 brings with it other things that we don't want to demand
        // for now.
-       movit_shader_rounding_supported = glewIsSupported("GL_EXT_gpu_shader4");
+       movit_shader_rounding_supported =
+               (epoxy_gl_version() >= 30 || epoxy_has_gl_extension("GL_EXT_gpu_shader4"));
 
        return true;
 }
 
+double get_glsl_version()
+{
+       char *glsl_version_str = strdup((const char *)glGetString(GL_SHADING_LANGUAGE_VERSION));
+
+       // Skip past the first period.
+       char *ptr = strchr(glsl_version_str, '.');
+       assert(ptr != NULL);
+       ++ptr;
+
+       // Now cut the string off at the next period or space, whatever comes first
+       // (unless the string ends first).
+       while (*ptr && *ptr != '.' && *ptr != ' ') {
+               ++ptr;
+       }
+       *ptr = '\0';
+
+       // Now we have something on the form X.YY. We convert it to a float, and hope
+       // that if it's inexact (e.g. 1.30), atof() will round the same way the
+       // compiler will.
+       float glsl_version = atof(glsl_version_str);
+       free(glsl_version_str);
+
+       return glsl_version;
+}
+
 }  // namespace
 
 bool init_movit(const string& data_directory, MovitDebugLevel debug_level)
@@ -319,11 +373,6 @@ bool init_movit(const string& data_directory, MovitDebugLevel debug_level)
        movit_data_directory = new string(data_directory);
        movit_debug_level = debug_level;
 
-       GLenum err = glewInit();
-       if (err != GLEW_OK) {
-               return false;
-       }
-
        // geez 
        glPixelStorei(GL_PACK_ALIGNMENT, 1);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@@ -332,6 +381,18 @@ bool init_movit(const string& data_directory, MovitDebugLevel debug_level)
        if (!check_extensions()) {
                return false;
        }
+
+       // Find out what shader model we should compile for.
+       if (epoxy_is_desktop_gl()) {
+               if (get_glsl_version() >= 1.30) {
+                       movit_shader_model = MOVIT_GLSL_130;
+               } else {
+                       movit_shader_model = MOVIT_GLSL_110;
+               }
+       } else {
+               movit_shader_model = MOVIT_ESSL_300;
+       }
+
        measure_texel_subpixel_precision();
        measure_roundoff_problems();
 
diff --git a/init.h b/init.h
index d6f6dd40b005b71c338bac61e151c83701a9323c..628915d6a68882722847d0beb0c60e7ad80b024d 100644 (file)
--- a/init.h
+++ b/init.h
@@ -67,6 +67,15 @@ extern bool movit_shader_rounding_supported;
 // Whether the GPU in use supports GL_EXT_texture_sRGB.
 extern bool movit_srgb_textures_supported;
 
+// What shader model we are compiling for. This only affects the choice
+// of a few files (like header.frag); most of the shaders are the same.
+enum MovitShaderModel {
+       MOVIT_GLSL_110,
+       MOVIT_GLSL_130,
+       MOVIT_ESSL_300
+};
+extern MovitShaderModel movit_shader_model;
+
 }  // namespace movit
 
 #endif  // !defined(_MOVIT_INIT_H)
index e9832f458a6cb83f07cbe86de93aefb2f0462043..60cd7df5f2b1c2cef74128fdab446335aa945fbb 100644 (file)
@@ -1,4 +1,4 @@
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <math.h>
 
 #include "effect_util.h"
index b5007721710b28173130e6701650474df57cc20d..c93724d8b8fe2ae10150feb4cad8096ebfbce5dc 100644 (file)
@@ -20,7 +20,7 @@
 // Also, gamma is a case where we would not want premultiplied alpha.
 // Thus, we have to divide away alpha first, and then re-multiply it back later.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <string>
 
 #include "effect.h"
index 612901f4a2cfcd1feab73a6c1e58d2a4041c81a4..1be2847a91ee3d0c5260333461462a5452f3494a 100644 (file)
@@ -1,6 +1,6 @@
 // Unit tests for LiftGammaGainEffect.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 
 #include "effect_chain.h"
 #include "gtest/gtest.h"
index 618b73388bfc3d3c46ec2cefba7b0f3803d7488e..4a506f5aaf4942d631aba27c4b18d99f3089d16f 100644 (file)
@@ -1,6 +1,6 @@
 // Unit tests for LumaMixEffect.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 
 #include "effect_chain.h"
 #include "gtest/gtest.h"
index e3d66e7bffcbeb5298b8a00a46a3c59109f10527..b5082846abc13e6ec76ff37d9dfe1ec6b7032ab7 100644 (file)
@@ -1,6 +1,6 @@
 // Unit tests for MixEffect.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 
 #include "effect_chain.h"
 #include "gtest/gtest.h"
index b11ba15277fb135814a91fff23c530ffd85b8e35..20427c6acd4ee123a5832c17546ab4e8900732c6 100644 (file)
@@ -14,5 +14,5 @@ Version: git
 Requires:
 Conflicts:
 Libs: -lmovit
-Libs.private: @GLEW_LIBS@ @FFTW3_LIBS@
-Cflags: -I${includedir}/movit @Eigen3_CFLAGS@ @GLEW_CFLAGS@ @FFTW3_CFLAGS@
+Libs.private: @epoxy_LIBS@ @FFTW3_LIBS@
+Cflags: -I${includedir}/movit @Eigen3_CFLAGS@ @epoxy_CFLAGS@ @FFTW3_CFLAGS@
index 50612fc941f1a5bf50894d39437bd872225034ad..92e98e30944ec61eedca44e75e27276cef26a609 100644 (file)
@@ -6,7 +6,7 @@
 // sending it through OverlayEffect, e.g. with R=G=B=A=0.3 to get 30% alpha
 // (remember, alpha is premultiplied).
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <string>
 
 #include "effect.h"
index 597c59c7eaed25d76a26b187eeb0676209d46596..dfda93f368db830d7833b7384fc7239b1418ae84 100644 (file)
@@ -1,6 +1,6 @@
 // Unit tests for OverlayEffect.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 
 #include "effect_chain.h"
 #include "gtest/gtest.h"
index 15381a32567e7bdd6ffed157c8aea6b52cdf4aff..f576baa2d5c3f8cb043a0395cdd3d3314a7bdd90 100644 (file)
@@ -1,4 +1,4 @@
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 
 #include "effect_util.h"
index 3bd4aacb321a54c80ce98e23526d941a9f1bce58..901f892b9dd14f999776f823bb897370f32d25d5 100644 (file)
@@ -12,7 +12,7 @@
 // You may not change it after calling finalize(), since that could change the
 // graph (need_linear_light() etc. depend on the border color you choose).
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <string>
 
 #include "effect.h"
index 767f3e8d4f3a79c654553c3aa9e843f57e629ef4..dd836ea066ee527dd6f5af3aaa6c4415eeebe28b 100644 (file)
@@ -1,6 +1,6 @@
 // Unit tests for AlphaMultiplicationEffect.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <stddef.h>
 
 #include "effect_chain.h"
index a6774873daa3b5b58be975300f97839cc5562a56..50b7c6bc5c4730fc6bb25cd18c96a446c8f02986 100644 (file)
@@ -1,7 +1,7 @@
 // Three-lobed Lanczos, the most common choice.
 #define LANCZOS_RADIUS 3.0
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 #include <limits.h>
 #include <math.h>
index a31df17edb1007f5f9a76d6a5dbf1888087a214a..d71b5f5128d60e8656b544c476a58b7ed634dfda 100644 (file)
@@ -19,7 +19,7 @@ vec4 PREFIX(do_sample)(vec2 tc, int i)
 #else
        sample_tc.y = tc.x * PREFIX(num_loops);
 #endif
-       vec2 sample = texture2D(PREFIX(sample_tex), sample_tc).rg;
+       vec2 sample = tex2D(PREFIX(sample_tex), sample_tc).rg;
 
 #if DIRECTION_VERTICAL
        tc.y = sample.g + floor(sample_tc.y) * PREFIX(slice_height);
index 44587bf22f9200a1f79147c1ced2b9bf40e82dbb..f0112b3ca7c4abcec1ba73a6ce420f65b10162dd 100644 (file)
@@ -15,7 +15,7 @@
 // which is what the user is intended to use, instantiates two copies of
 // SingleResamplePassEffect behind the scenes).
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 #include <stddef.h>
 #include <string>
index 211e6d123e65d93dbcc075f60ea8371b1eaa5736..95c2bcfb9aec95693653ea65572cfdca76f79699 100644 (file)
@@ -1,12 +1,11 @@
 // Unit tests for ResampleEffect.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
+#include <gtest/gtest.h>
 #include <math.h>
 
 #include "effect_chain.h"
 #include "flat_input.h"
-#include "glew.h"
-#include "gtest/gtest.h"
 #include "image_format.h"
 #include "resample_effect.h"
 #include "test_util.h"
index a83add2a7117ccfb99bea2cce3afcdb1ed062cdb..10eeb9bb491f54ed5d8b9ee32c30719c18bf18c1 100644 (file)
@@ -6,8 +6,8 @@
 #include <map>
 #include <string>
 #include <utility>
+#include <epoxy/gl.h>
 
-#include "glew.h"
 #include "init.h"
 #include "resource_pool.h"
 #include "util.h"
@@ -200,10 +200,18 @@ GLuint ResourcePool::create_2d_texture(GLint internal_format, GLsizei width, GLs
        case GL_SRGB8_ALPHA8:
                format = GL_RGBA;
                break;
+       case GL_RGB32F:
+       case GL_RGB16F:
+       case GL_RGB8:
+               format = GL_RGB;
+               break;
        case GL_RG32F:
        case GL_RG16F:
+       case GL_RG8:
                format = GL_RG;
                break;
+       case GL_R32F:
+       case GL_R16F:
        case GL_R8:
                format = GL_RED;
                break;
@@ -212,12 +220,38 @@ GLuint ResourcePool::create_2d_texture(GLint internal_format, GLsizei width, GLs
                assert(false);
        }
 
+       // Same with type; GLES is stricter than desktop OpenGL here.
+       GLenum type;
+       switch (internal_format) {
+       case GL_RGBA32F_ARB:
+       case GL_RGBA16F_ARB:
+       case GL_RGB32F:
+       case GL_RGB16F:
+       case GL_RG32F:
+       case GL_RG16F:
+       case GL_R32F:
+       case GL_R16F:
+               type = GL_FLOAT;
+               break;
+       case GL_SRGB8_ALPHA8:
+       case GL_RGBA8:
+       case GL_RGB8:
+       case GL_RG8:
+       case GL_R8:
+               type = GL_UNSIGNED_BYTE;
+               break;
+       default:
+               // TODO: Add more here as needed.
+               assert(false);
+       }
+
+
        GLuint texture_num;
        glGenTextures(1, &texture_num);
        check_error();
        glBindTexture(GL_TEXTURE_2D, texture_num);
        check_error();
-       glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, format, GL_UNSIGNED_BYTE, NULL);
+       glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, format, type, NULL);
        check_error();
        glBindTexture(GL_TEXTURE_2D, 0);
        check_error();
@@ -340,16 +374,32 @@ size_t ResourcePool::estimate_texture_size(const Texture2D &texture_format)
        case GL_RGBA16F_ARB:
                bytes_per_pixel = 8;
                break;
+       case GL_RGB32F_ARB:
+               bytes_per_pixel = 12;
+               break;
+       case GL_RGB16F_ARB:
+               bytes_per_pixel = 6;
+               break;
        case GL_RGBA8:
        case GL_SRGB8_ALPHA8:
                bytes_per_pixel = 4;
                break;
+       case GL_RGB8:
+       case GL_SRGB8:
+               bytes_per_pixel = 3;
+               break;
        case GL_RG32F:
                bytes_per_pixel = 8;
                break;
        case GL_RG16F:
                bytes_per_pixel = 4;
                break;
+       case GL_R32F:
+               bytes_per_pixel = 4;
+               break;
+       case GL_R16F:
+               bytes_per_pixel = 2;
+               break;
        case GL_R8:
                bytes_per_pixel = 1;
                break;
index 4ae4110851387cd7dcfe21eb67f3f3f0e71cd695..7029fbfd5e795cbd405a099ddd0b1450ccf187c2 100644 (file)
@@ -16,7 +16,7 @@
 // safely called from multiple threads at the same time, provided they have
 // separate (but sharing) OpenGL contexts.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <pthread.h>
 #include <stddef.h>
 #include <list>
index 76e1f5cf81625944f3f0df1faa3d1ccef5f31121..1ec093d43fbda2fd9bb370f076f9fbd6aadb9c1a 100644 (file)
@@ -1,4 +1,4 @@
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 
 #include "sandbox_effect.h"
 #include "util.h"
index f06b2ef3758d17cb95f014f0d7a1e0508a1218df..25c79920109cbbdbf1d0418c41566df863a037df 100644 (file)
@@ -8,7 +8,7 @@
 // throwaway code. When you're happy, you can do a bit of search and replace
 // to give it a proper name and its own place in the build system.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <string>
 
 #include "effect.h"
index 941df9924bfbeb4ee5642b37c490fb793a1560e4..6a711a42a25d5f0799a3fc54298f4d1041aa3aac 100644 (file)
@@ -1,6 +1,6 @@
 // Unit tests for SaturationEffect.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 
 #include "effect_chain.h"
 #include "gtest/gtest.h"
index 1ec68f92abffe6648a7e6b9c6d3fb93ff5ba183d..50504fecbf0a4851af6c59d69fac02ad92349558 100644 (file)
@@ -1,4 +1,4 @@
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 
 #include "effect_chain.h"
 #include "slice_effect.h"
index 0ce5d08b0b7b7917c2b30d5d623a7fab4eb70b5e..89aeb0e4297eaac7eebd0985833c6549adc5829d 100644 (file)
@@ -10,7 +10,7 @@
 // Note that vertical slices happen from the top, consistent with the rest of
 // Movit.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <string>
 
 #include "effect.h"
index 3e5666708ab0896801a5a77a4eebd8da31472b27..477c7a72543c378071c13b77233f64b26b8f0f8b 100644 (file)
@@ -1,6 +1,6 @@
 // Unit tests for SliceEffect.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 
 #include "effect_chain.h"
 #include "flat_input.h"
index a9f738d715754c70d2e6d06b73ed100409c28d89..a3ccb5c5f04cebcd3c804c294e95e93d7b886a59 100644 (file)
@@ -2,11 +2,11 @@
 #include <math.h>
 #include <stdio.h>
 #include <algorithm>
+#include <epoxy/gl.h>
+#include <gtest/gtest.h>
+#include <gtest/gtest-message.h>
 
 #include "flat_input.h"
-#include "glew.h"
-#include "gtest/gtest.h"
-#include "gtest/gtest-message.h"
 #include "init.h"
 #include "resource_pool.h"
 #include "test_util.h"
@@ -142,7 +142,30 @@ void EffectChainTester::run(float *out_data, GLenum format, Colorspace color_spa
        chain.render_to_fbo(fbo, width, height);
 
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
-       glReadPixels(0, 0, width, height, format, GL_FLOAT, out_data);
+       check_error();
+       if (!epoxy_is_desktop_gl() && (format == GL_RED || format == GL_BLUE || format == GL_ALPHA)) {
+               // GLES will only read GL_RGBA.
+               float *temp = new float[width * height * 4];
+               glReadPixels(0, 0, width, height, GL_RGBA, GL_FLOAT, temp);
+               check_error();
+               if (format == GL_ALPHA) {
+                       for (unsigned i = 0; i < width * height; ++i) {
+                               out_data[i] = temp[i * 4 + 3];
+                       }
+               } else if (format == GL_BLUE) {
+                       for (unsigned i = 0; i < width * height; ++i) {
+                               out_data[i] = temp[i * 4 + 2];
+                       }
+               } else {
+                       for (unsigned i = 0; i < width * height; ++i) {
+                               out_data[i] = temp[i * 4];
+                       }
+               }
+               delete[] temp;
+       } else {
+               glReadPixels(0, 0, width, height, format, GL_FLOAT, out_data);
+               check_error();
+       }
 
        if (format == GL_RGBA) {
                width *= 4;
@@ -160,7 +183,30 @@ void EffectChainTester::run(unsigned char *out_data, GLenum format, Colorspace c
        chain.render_to_fbo(fbo, width, height);
 
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
-       glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, out_data);
+       check_error();
+       if (!epoxy_is_desktop_gl() && (format == GL_RED || format == GL_BLUE || format == GL_ALPHA)) {
+               // GLES will only read GL_RGBA.
+               unsigned char *temp = new unsigned char[width * height * 4];
+               glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, temp);
+               check_error();
+               if (format == GL_ALPHA) {
+                       for (unsigned i = 0; i < width * height; ++i) {
+                               out_data[i] = temp[i * 4 + 3];
+                       }
+               } else if (format == GL_BLUE) {
+                       for (unsigned i = 0; i < width * height; ++i) {
+                               out_data[i] = temp[i * 4 + 2];
+                       }
+               } else {
+                       for (unsigned i = 0; i < width * height; ++i) {
+                               out_data[i] = temp[i * 4];
+                       }
+               }
+               delete[] temp;
+       } else {
+               glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, out_data);
+               check_error();
+       }
 
        if (format == GL_RGBA) {
                width *= 4;
index ff568ba83056f108deca35f4d20078fed7b35347..e5e65513ddb82914758162080fabae40e039a7de 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _MOVIT_TEST_UTIL_H
 #define _MOVIT_TEST_UTIL_H 1
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include "effect_chain.h"
 #include "image_format.h"
 
diff --git a/texture1d.130.frag b/texture1d.130.frag
new file mode 100644 (file)
index 0000000..a71f90e
--- /dev/null
@@ -0,0 +1,11 @@
+#version 130
+
+uniform sampler2D tex;
+in vec2 tc;
+
+out vec4 FragColor;
+
+void main()
+{
+       FragColor = texture(tex, tc);  // Second component is irrelevant.
+}
diff --git a/texture1d.300es.frag b/texture1d.300es.frag
new file mode 100644 (file)
index 0000000..ddea589
--- /dev/null
@@ -0,0 +1,13 @@
+#version 300 es
+
+precision highp float;
+
+uniform sampler2D tex;
+in vec2 tc;
+
+out vec4 FragColor;
+
+void main()
+{
+       FragColor = texture(tex, tc);  // Second component is irrelevant.
+}
index c3a804733bbce25fc362dae0f8fb7dc11cb1fbff..addf9008ef7c1bfe7889d0676ef48bbb74bff389 100644 (file)
@@ -1,3 +1,7 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+
 uniform sampler2D tex;
 varying vec2 tc;
 
index e6d3790b86a1a6763ba1f00b627a00fe5bc73765..7a2052b5b4ef4e81c6dd0418ae524033381333e0 100644 (file)
@@ -10,7 +10,7 @@
 // See DeconvolutionSharpenEffect for a different, possibly better
 // sharpening algorithm.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 #include <string>
 
index 69ea5f706af5a31e025c790cf7c524619632c4fd..e6750ce8156d6fff8856a69daaab93a69c1907f1 100644 (file)
@@ -1,6 +1,6 @@
 // Unit tests for UnsharpMaskEffect.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <math.h>
 
 #include "effect_chain.h"
index 1e66c30b573e51ef419146d5149c32ed9e53e7d3..01787f013e0a4c70817be2ccf49743cddb7bd254 100644 (file)
--- a/util.cpp
+++ b/util.cpp
@@ -1,4 +1,4 @@
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 #include <math.h>
 #include <stdio.h>
@@ -12,9 +12,9 @@
 #if defined(__DARWIN__)
 #include <OpenGL/OpenGL.h>
 #elif defined(WIN32)
-#include <GL/wglew.h>
+#include <epoxy/wgl.h>
 #else
-#include <GL/glxew.h>
+#include <epoxy/glx.h>
 #endif
 
 using namespace std;
@@ -96,6 +96,19 @@ string read_file(const string &filename)
        return string(buf, len);
 }
 
+string read_version_dependent_file(const string &base, const string &extension)
+{
+       if (movit_shader_model == MOVIT_GLSL_110) {
+               return read_file(base + "." + extension);
+       } else if (movit_shader_model == MOVIT_GLSL_130) {
+               return read_file(base + ".130." + extension);
+       } else if (movit_shader_model == MOVIT_ESSL_300) {
+               return read_file(base + ".300es." + extension);
+       } else {
+               assert(false);
+       }
+}
+
 GLuint compile_shader(const string &shader_src, GLenum type)
 {
        GLuint obj = glCreateShader(type);
diff --git a/util.h b/util.h
index 1ecdc00ce1b91dce58547b8d243fed8f3e4f3b3c..1fa4e7823efd65666dc1d6ba0acaa659b28b994d 100644 (file)
--- a/util.h
+++ b/util.h
@@ -3,7 +3,7 @@
 
 // Various utilities.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <Eigen/Core>
@@ -24,6 +24,10 @@ void hsv2rgb_normalized(float h, float s, float v, float *r, float *g, float *b)
 // Dies if the file does not exist.
 std::string read_file(const std::string &filename);
 
+// Reads <base>.<extension>, <base>.130.<extension> or <base>.300es.<extension> and
+// returns its contents, depending on <movit_shader_level>.
+std::string read_version_dependent_file(const std::string &base, const std::string &extension);
+
 // Compile the given GLSL shader (typically a vertex or fragment shader)
 // and return the object number.
 GLuint compile_shader(const std::string &shader_src, GLenum type);
index 94383ff4839aee7010d78777d84d21c9d711d741..d8b4f9bf24d674fc1cf6b815e7e6f07c16e8ff78 100644 (file)
@@ -1,4 +1,4 @@
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 #include <math.h>
 
index 737a834cb68556a063404063a0e92a18f5be88c9..fdf1a116502b8be220b74cacca1432539daec206 100644 (file)
@@ -4,7 +4,7 @@
 // A circular vignette, falling off as cos² of the distance from the center
 // (the classic formula for approximating a real lens).
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <string>
 
 #include "effect.h"
index 9c28852dfdbbf5045d5364b593b7601fa8dc37ae..010fbc4827a21b3a286e89bdf38d5dc948908b4b 100644 (file)
@@ -1,6 +1,6 @@
 // Unit tests for VignetteEffect.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <math.h>
 
 #include "effect_chain.h"
diff --git a/vs.130.vert b/vs.130.vert
new file mode 100644 (file)
index 0000000..7b4ebab
--- /dev/null
@@ -0,0 +1,17 @@
+#version 130
+
+in vec2 position;
+in vec2 texcoord;
+out vec2 tc;
+
+void main()
+{
+       // The result of glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, 1.0) is:
+       //
+       //   2.000  0.000  0.000 -1.000
+       //   0.000  2.000  0.000 -1.000
+       //   0.000  0.000 -2.000 -1.000
+       //   0.000  0.000  0.000  1.000
+       gl_Position = vec4(2.0 * position.x - 1.0, 2.0 * position.y - 1.0, -1.0, 1.0);
+       tc = texcoord;
+}
diff --git a/vs.300es.vert b/vs.300es.vert
new file mode 100644 (file)
index 0000000..542be89
--- /dev/null
@@ -0,0 +1,19 @@
+#version 300 es
+
+precision highp float;
+
+in vec2 position;
+in vec2 texcoord;
+out vec2 tc;
+
+void main()
+{
+       // The result of glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, 1.0) is:
+       //
+       //   2.000  0.000  0.000 -1.000
+       //   0.000  2.000  0.000 -1.000
+       //   0.000  0.000 -2.000 -1.000
+       //   0.000  0.000  0.000  1.000
+       gl_Position = vec4(2.0 * position.x - 1.0, 2.0 * position.y - 1.0, -1.0, 1.0);
+       tc = texcoord;
+}
index 0aa85da66f0159ca7bfd94e8b7ff1e132c73746a..69759adfc6148379698998674109a5ae17213e4b 100644 (file)
@@ -1,6 +1,6 @@
 #include <Eigen/Core>
 #include <Eigen/LU>
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 
 #include "colorspace_conversion_effect.h"
index 43bfccb1f132bf93d01ae57a7aaad481647c6e3d..f438b91507a00b579d9eac697a3f619ac4527096 100644 (file)
@@ -3,7 +3,7 @@
 
 // Color correction in LMS color space.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <string>
 
 #include "effect.h"
index 5d51dd89a46abec302bb19c1e6f73482d18e74b3..b0642077e5c039143f23574f5d9d9ca7655f0077 100644 (file)
@@ -1,6 +1,6 @@
 // Unit tests for WhiteBalanceEffect.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 
 #include "effect_chain.h"
 #include "gtest/gtest.h"
index 3bf53c77e428530dc5b731f33460077b35db2f27..87260215e2b1b4bb3f2e916c98e9e1d4adb37a37 100644 (file)
@@ -1,4 +1,4 @@
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <math.h>
 
 #include "widgets.h"
index 49747151532ae5863de08fdf0016964cbb2cd30e..dc5e4d9fd2db9e619d9b680583b6c1f514f65220 100644 (file)
@@ -1,6 +1,6 @@
 #include <Eigen/Core>
 #include <Eigen/LU>
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 #include <stdio.h>
 #include <string.h>
index 8da8256c4b10858fe22fac7fe81b4305a3cb7868..fbf20d165df616f15af98fde6f0b0714675f51d5 100644 (file)
@@ -9,9 +9,9 @@ vec4 FUNCNAME(vec2 tc) {
        tc.y = 1.0 - tc.y;
 
        vec3 ycbcr;
-       ycbcr.x = texture2D(PREFIX(tex_y), tc).x;
-       ycbcr.y = texture2D(PREFIX(tex_cb), tc + PREFIX(cb_offset)).x;
-       ycbcr.z = texture2D(PREFIX(tex_cr), tc + PREFIX(cr_offset)).x;
+       ycbcr.x = tex2D(PREFIX(tex_y), tc).x;
+       ycbcr.y = tex2D(PREFIX(tex_cb), tc + PREFIX(cb_offset)).x;
+       ycbcr.z = tex2D(PREFIX(tex_cr), tc + PREFIX(cr_offset)).x;
 
        ycbcr -= PREFIX(offset);
        ycbcr *= PREFIX(scale);
index 2466eedf0307beb7e6f613ea9695cef740d20437..bf6d800eeb0c918c1b535bd2f6bf2c65c0bfa354 100644 (file)
@@ -5,7 +5,7 @@
 // imprecisely, called “YUV”), which is typically what you get from a video decoder.
 // It upsamples planes as needed, using the default linear upsampling OpenGL gives you.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 #include <string>
 
index 352fe290dffc4143c27a44e62bf27bef842f2980..6895b3834a62602aa293c012957638684b471074 100644 (file)
@@ -1,7 +1,7 @@
 // Unit tests for YCbCrInput.
 // FIXME: This class really ought to support mipmaps.
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <stddef.h>
 
 #include "effect_chain.h"