diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/fixtures/offscreen_texture/empty-red/expected.png | bin | 0 -> 2870 bytes | |||
-rw-r--r-- | test/fixtures/offscreen_texture/render-to-fbo-composited/expected.png | bin | 0 -> 4599 bytes | |||
-rw-r--r-- | test/fixtures/offscreen_texture/render-to-fbo/expected.png | bin | 0 -> 2870 bytes | |||
-rw-r--r-- | test/fixtures/offscreen_texture/render-to-texture/expected.png | bin | 0 -> 728 bytes | |||
-rw-r--r-- | test/util/offscreen_texture.cpp | 153 |
5 files changed, 153 insertions, 0 deletions
diff --git a/test/fixtures/offscreen_texture/empty-red/expected.png b/test/fixtures/offscreen_texture/empty-red/expected.png Binary files differnew file mode 100644 index 0000000000..7ecf05ca7c --- /dev/null +++ b/test/fixtures/offscreen_texture/empty-red/expected.png diff --git a/test/fixtures/offscreen_texture/render-to-fbo-composited/expected.png b/test/fixtures/offscreen_texture/render-to-fbo-composited/expected.png Binary files differnew file mode 100644 index 0000000000..b4d2a0b1b6 --- /dev/null +++ b/test/fixtures/offscreen_texture/render-to-fbo-composited/expected.png diff --git a/test/fixtures/offscreen_texture/render-to-fbo/expected.png b/test/fixtures/offscreen_texture/render-to-fbo/expected.png Binary files differnew file mode 100644 index 0000000000..7ecf05ca7c --- /dev/null +++ b/test/fixtures/offscreen_texture/render-to-fbo/expected.png diff --git a/test/fixtures/offscreen_texture/render-to-texture/expected.png b/test/fixtures/offscreen_texture/render-to-texture/expected.png Binary files differnew file mode 100644 index 0000000000..7773e5ab05 --- /dev/null +++ b/test/fixtures/offscreen_texture/render-to-texture/expected.png diff --git a/test/util/offscreen_texture.cpp b/test/util/offscreen_texture.cpp new file mode 100644 index 0000000000..74a616134e --- /dev/null +++ b/test/util/offscreen_texture.cpp @@ -0,0 +1,153 @@ +#include <mbgl/test/util.hpp> + +#include <mbgl/gl/gl_config.hpp> +#include <mbgl/platform/default/headless_view.hpp> + +#include <mbgl/util/offscreen_texture.hpp> +#include <mbgl/util/raster.hpp> + +using namespace mbgl; + +TEST(OffscreenTexture, EmptyRed) { + HeadlessView view(1.0f, 512, 256); + view.activate(); + + MBGL_CHECK_ERROR(glClearColor(1.0f, 0.0f, 0.0f, 1.0f)); + MBGL_CHECK_ERROR(glClear(GL_COLOR_BUFFER_BIT)); + + auto image = view.readStillImage(); + test::checkImage("test/fixtures/offscreen_texture/empty-red", image, 0, 0); +} + +struct Shader { + Shader(const GLchar* vertex, const GLchar* fragment) { + program = MBGL_CHECK_ERROR(glCreateProgram()); + vertexShader = MBGL_CHECK_ERROR(glCreateShader(GL_VERTEX_SHADER)); + fragmentShader = MBGL_CHECK_ERROR(glCreateShader(GL_FRAGMENT_SHADER)); + MBGL_CHECK_ERROR(glShaderSource(vertexShader, 1, &vertex, nullptr)); + MBGL_CHECK_ERROR(glCompileShader(vertexShader)); + MBGL_CHECK_ERROR(glAttachShader(program, vertexShader)); + MBGL_CHECK_ERROR(glShaderSource(fragmentShader, 1, &fragment, nullptr)); + MBGL_CHECK_ERROR(glCompileShader(fragmentShader)); + MBGL_CHECK_ERROR(glAttachShader(program, fragmentShader)); + MBGL_CHECK_ERROR(glLinkProgram(program)); + a_pos = glGetAttribLocation(program, "a_pos"); + } + + ~Shader() { + MBGL_CHECK_ERROR(glDetachShader(program, vertexShader)); + MBGL_CHECK_ERROR(glDetachShader(program, fragmentShader)); + MBGL_CHECK_ERROR(glDeleteShader(vertexShader)); + MBGL_CHECK_ERROR(glDeleteShader(fragmentShader)); + MBGL_CHECK_ERROR(glDeleteProgram(program)); + } + + GLuint program = 0; + GLuint vertexShader = 0; + GLuint fragmentShader = 0; + GLuint a_pos = 0; +}; + +struct Buffer { + Buffer(std::vector<GLfloat> data) { + MBGL_CHECK_ERROR(glGenBuffers(1, &buffer)); + MBGL_CHECK_ERROR(glBindBuffer(GL_ARRAY_BUFFER, buffer)); + MBGL_CHECK_ERROR(glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(GLfloat), data.data(), + GL_STATIC_DRAW)); + } + + ~Buffer() { + MBGL_CHECK_ERROR(glDeleteBuffers(1, &buffer)); + } + + GLuint buffer = 0; +}; + + +TEST(OffscreenTexture, RenderToTexture) { + HeadlessView view(1.0f, 512, 256); + view.activate(); + gl::Config config; + gl::ObjectStore store; + + + MBGL_CHECK_ERROR(glEnable(GL_BLEND)); + MBGL_CHECK_ERROR(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); + + Shader paintShader(R"MBGL_SHADER( +attribute vec2 a_pos; +void main() { + gl_Position = vec4(a_pos, 0, 1); +} +)MBGL_SHADER", R"MBGL_SHADER( +void main() { + gl_FragColor = vec4(0, 0.8, 0, 0.8); +} +)MBGL_SHADER"); + + Shader compositeShader(R"MBGL_SHADER( +attribute vec2 a_pos; +varying vec2 v_texcoord; +void main() { + gl_Position = vec4(a_pos, 0, 1); + v_texcoord = (a_pos + 1.0) / 2.0; +} +)MBGL_SHADER", R"MBGL_SHADER( +uniform sampler2D u_texture; +varying vec2 v_texcoord; +void main() { + gl_FragColor = texture2D(u_texture, v_texcoord); +} +)MBGL_SHADER"); + + GLuint u_texture = glGetUniformLocation(compositeShader.program, "u_texture"); + + Buffer triangleBuffer({ 0, 0.5, 0.5, -0.5, -0.5, -0.5 }); + Buffer viewportBuffer({ -1, -1, 1, -1, -1, 1, 1, 1 }); + + // Make sure the texture gets destructed before we call store.reset(); + { + // First, draw red to the bound FBO. + config.clearColor = { 1, 0, 0, 1 }; + MBGL_CHECK_ERROR(glClear(GL_COLOR_BUFFER_BIT)); + + // Then, create a texture, bind it, and render yellow to that texture. This should not + // affect the originally bound FBO. + OffscreenTexture texture; + texture.bind(store, config, {{ 128, 128 }}); + + config.clearColor = { 0, 0, 0, 0 }; + MBGL_CHECK_ERROR(glClear(GL_COLOR_BUFFER_BIT)); + + config.program = paintShader.program; + MBGL_CHECK_ERROR(glBindBuffer(GL_ARRAY_BUFFER, triangleBuffer.buffer)); + MBGL_CHECK_ERROR(glEnableVertexAttribArray(paintShader.a_pos)); + MBGL_CHECK_ERROR( + glVertexAttribPointer(paintShader.a_pos, 2, GL_FLOAT, GL_FALSE, 0, nullptr)); + MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, 3)); + + auto image = view.readStillImage(texture.getSize()); + test::checkImage("test/fixtures/offscreen_texture/render-to-texture", image, 0, 0); + + // Now reset the FBO back to normal and retrieve the original (restored) framebuffer. + config.reset(); + + image = view.readStillImage(); + test::checkImage("test/fixtures/offscreen_texture/render-to-fbo", image, 0, 0); + + // Now, composite the Framebuffer texture we've rendered to onto the main FBO. + config.program = compositeShader.program; + texture.getTexture().bind(store, config, 0, Raster::Scaling::Linear); + MBGL_CHECK_ERROR(glUniform1i(u_texture, 0)); + MBGL_CHECK_ERROR(glBindBuffer(GL_ARRAY_BUFFER, viewportBuffer.buffer)); + MBGL_CHECK_ERROR(glEnableVertexAttribArray(compositeShader.a_pos)); + MBGL_CHECK_ERROR( + glVertexAttribPointer(compositeShader.a_pos, 2, GL_FLOAT, GL_FALSE, 0, nullptr)); + MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); + + image = view.readStillImage(); + test::checkImage("test/fixtures/offscreen_texture/render-to-fbo-composited", image, 0, 0.1); + } + + store.reset(); +} |