diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0ddef65834fa2f84777f6dcd44f0c20277dc4fd0..7c49904490d91dec41a2673a0ad8e18e481ccdeb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,7 @@
 project(scigl_render)
 
 cmake_minimum_required(VERSION 2.8.3)
+set (CMAKE_CXX_STANDARD 11)
 
 # using conan to manage dependencies
 if(CONAN_EXPORTED) # when packaging
@@ -26,6 +27,7 @@ add_library(scigl_render
   src/gl_context.cpp
   src/buffer/frame_buffer.cpp
   src/buffer/frame_buffer_reader.cpp
+  src/buffer/texture2d.cpp
   src/render/depth_simulator.cpp
   src/render/onscreen_render.cpp
   src/render/rasterizer.cpp
diff --git a/include/scigl_render/buffer/frame_buffer.hpp b/include/scigl_render/buffer/frame_buffer.hpp
index 203a0a4520258fb6b41c395191843a6083554406..5caf8b0eb8b58aebd9bab4d904c3108b5448bcaa 100644
--- a/include/scigl_render/buffer/frame_buffer.hpp
+++ b/include/scigl_render/buffer/frame_buffer.hpp
@@ -1,5 +1,7 @@
 #pragma once
 #include <GL/gl3w.h>
+#include <memory>
+#include <scigl_render/buffer/texture2d.hpp>
 
 namespace scigl_render
 {
@@ -15,11 +17,9 @@ public:
   /*!
   Creates the framebuffer with a rednerbuffer attachment to render to.
   \throws a runtime_error on failure
-  \param width of the texture
-  \param height of the texture
-  \param internal_format color components & size of each
+  \param texture the texture to render to
   */
-  FrameBuffer(int width, int height, GLenum internal_format);
+  FrameBuffer(std::shared_ptr<Texture2D> texture);
   FrameBuffer(const FrameBuffer &) = delete;
   ~FrameBuffer();
 
@@ -41,19 +41,17 @@ public:
   */
   void clear(float color = 0, float depth = 1, int stencil = 0) const;
 
-  /** returns the texture used for rendering */
-  GLuint get_texture() const;
+  /** returns the render target texture */
+  std::shared_ptr<Texture2D> get_texture() const;
 
   /** gets the maximum rbo size */
   static int get_max_size();
 
 private:
-  // Parameterization
-  int width, height;
   // framebuffer object to render the texture into
   GLuint fbo;
   // texture for renderng colors, can be sampled from
-  GLuint color_tex;
+  std::shared_ptr<Texture2D> color_tex;
   // renderbuffer object for the depth testing, does not allow sampling
   GLuint depth_stencil_rbo;
 };
diff --git a/include/scigl_render/buffer/frame_buffer_reader.hpp b/include/scigl_render/buffer/frame_buffer_reader.hpp
index b13ade42e085d41968bda87fb0018e948dd8cb9f..88777dcf11294fca4fc00d77a1c0ff0b1f5724e3 100644
--- a/include/scigl_render/buffer/frame_buffer_reader.hpp
+++ b/include/scigl_render/buffer/frame_buffer_reader.hpp
@@ -18,20 +18,17 @@ class FramebufferReader
 public:
   /*!
   Renders the scene off-screen and calculates the depth values.
-  \param width number of image columns
-  \param height number of image rows
+  \param buffer read from this framebuffer
   \param pixel_size the size of each pixel: number_channels * sizeof(type)
   */
-  FramebufferReader(int width, int height, size_t pixel_size);
+  FramebufferReader(std::shared_ptr<FrameBuffer> buffer,
+                    size_t pixel_size);
 
   /*!
   Starts reading from the FBO to the backbuffer PBO. This operation is 
   asynchronous.
-  \param format specifies the channels, for example GL_RGB
-  \param type primitive to store, for example GL_UNSIGNED_BYTE
-  \param buffer transfer data from this FBO to the PBO
   */
-  void start_read(GLenum format, GLenum type, const FrameBuffer& buffer) const;
+  void start_read() const;
 
   /*!
   Reads synchronously from the frontbuffer PBO. Operate on this data while
@@ -49,8 +46,7 @@ public:
   void swap_buffers();
 
 private:
-  int width;
-  int height;
+  std::shared_ptr<FrameBuffer> framebuffer;
   // Two pbos one to read to the other one to map form, alternating
   std::array<GLuint, 2> pbos;
   // transfer from fbo to pbo via glReadPixels
diff --git a/include/scigl_render/buffer/texture2d.hpp b/include/scigl_render/buffer/texture2d.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..f0abbf72c1f132e28cb17aa93c63cfa7602f864d
--- /dev/null
+++ b/include/scigl_render/buffer/texture2d.hpp
@@ -0,0 +1,39 @@
+#pragma once
+#include <GL/gl3w.h>
+
+namespace scigl_render
+{
+/** RAII style creation of a 2D texture */
+class Texture2D
+{
+public:
+  Texture2D(GLsizei width, GLsizei height,
+            GLenum format, GLenum internal_format, GLenum type);
+  Texture2D(const Texture2D &) = delete;
+  ~Texture2D();
+
+  /** activates texture_n for use in shaders */
+  static void activate(GLenum texture_n);
+
+  /** binds this texture to GL_TEXTURE_2D */
+  void bind() const;
+
+  /** unbinds this texture */
+  void unbind() const;
+
+  /** upload an image to the texture. */
+  void store_image(const GLvoid *image) const;
+
+  GLuint get_raw() const;
+  GLsizei get_width() const;
+  GLsizei get_height() const;
+  GLenum get_format() const;
+  GLenum get_internal_format() const;
+  GLenum get_type() const;
+
+private:
+  const GLsizei width, height;
+  const GLenum format, internal_format, type;
+  GLuint texture;
+};
+} // namespace scigl_render
\ No newline at end of file
diff --git a/include/scigl_render/example/depth_offscreen_render.hpp b/include/scigl_render/example/depth_offscreen_render.hpp
index 3dc3da51fd7151c8ab26b56615058ed19cde33c5..13959a295a01363f2b7838a8a084428b21184f5b 100644
--- a/include/scigl_render/example/depth_offscreen_render.hpp
+++ b/include/scigl_render/example/depth_offscreen_render.hpp
@@ -22,17 +22,14 @@ class DepthOffscreenRender
 public:
   /*!
   Configures the rendering environment and loads the models.
-  \param context the environment to configure
-  \param shader how to render the scene
-  \param tex_format format parameter of glTexImage2D
-  \param tex_type type parameter of glTexImage2D
-  \param tex_internal_format internal_format parameter of glTexImage2D
+  \param context the environment to render to (swap Buffers)
+  \param texture parametrized for offscreen rendering
   \param pixel_size the size of one pixel. Must match the internal format:
   number_of_channels * sizeof(type)
   */
-  DepthOffscreenRender(
-      std::shared_ptr<GLContext> context, GLenum tex_format, GLenum tex_type,
-      GLint tex_internal_format, size_t pixel_size);
+  DepthOffscreenRender(std::shared_ptr<GLContext> context,
+                       std::shared_ptr<Texture2D>,
+                       size_t pixel_size);
 
   /*!
   Continues to render the next frame.
@@ -41,26 +38,20 @@ public:
                   const CartesianPose &model_pose,
                   const CartesianPose &camera_pose);
 
-  /*!
-  Resizes the buffers to the screen size of the GLContext.
-  */
-  void resize_buffers();
-
 private:
   // parameters for rendering
-  GLenum texture_format;
-  GLenum texture_type;
-  GLenum texture_internal_format;
-  size_t pixel_size;
   std::shared_ptr<GLContext> gl_context;
-  // Render targets
-  FrameBuffer framebuffer;
-  FramebufferReader fbo_reader;
+  // render to fbo
+  std::shared_ptr<Texture2D> fbo_texture;
+  std::shared_ptr<FrameBuffer> framebuffer;
+  std::unique_ptr<FramebufferReader> fbo_reader;
+  // display fullscreen quad from other texture (to showcase the mapping)
   TextureFullscreenRender texture_render;
-  // buffer for reading from the offscreen render
-  std::vector<unsigned char> image_buffer;
+  std::shared_ptr<Texture2D> quad_texture;
   // display different views
   Rasterizer rasterizer;
+  // CPU memory buffer for reading from the offscreen render
+  std::vector<uint8_t> image_buffer;
 
   /*!
   Display the data from the framebuffer
diff --git a/include/scigl_render/render/texture_fullscreen_render.hpp b/include/scigl_render/render/texture_fullscreen_render.hpp
index 8d0599bd97146f2adf340a09ecdfbd23301c1239..bfe4deb7b95fa4b864b6c7bd32d5c0bc60ba3caf 100644
--- a/include/scigl_render/render/texture_fullscreen_render.hpp
+++ b/include/scigl_render/render/texture_fullscreen_render.hpp
@@ -1,4 +1,6 @@
 #pragma once
+#include <memory>
+#include <scigl_render/buffer/texture2d.hpp>
 #include <scigl_render/shader/shader.hpp>
 
 namespace scigl_render
@@ -14,24 +16,15 @@ public:
   Create the renderer with a texture storage with the given format.
   \param internal_format the internal format used in glTexStorage2D
   */
-  TextureFullscreenRender(int width, int height,
-                          GLint internal_format = GL_RGB8);
+  TextureFullscreenRender();
 
-  /*! 
-  Draws the pixels into the currently selected framebuffer. This function 
-  changes glDepthFunc(GL_LEQUAL) so the quad can be seen (z = 1.0).
-  \param pixels the pointer to the lower left pixel of the image
-  \param format format of a pixel for example GL_RGB
-  \param type the type of the storage for example GL_UNSIGNED_BYTE
+  /**
+   * Draws the contents of the texture to a fullscreen quad.
+   * Changes glDepthFunc(GL_LEQUAL) so the quad can be seen (z = 1.0).
   */
-  void draw(const GLvoid *pixels, GLenum format, GLenum type);
+  void draw(std::shared_ptr<Texture2D> texture) const;
 
 private:
-  // store the texture here for rendering
-  GLuint texture;
-  // properties of the image
-  GLsizei width;
-  GLsizei height;
   // Dummy VAO since the geometry shader creates the vertices
   GLuint vao;
   Shader shader;
diff --git a/src/buffer/frame_buffer.cpp b/src/buffer/frame_buffer.cpp
index aff3fff9f3244b39ab7d4f0e0a3fd55227497eb5..15f70f6987d900d1608ea921b76240cdaf3689aa 100644
--- a/src/buffer/frame_buffer.cpp
+++ b/src/buffer/frame_buffer.cpp
@@ -3,21 +3,21 @@
 
 namespace scigl_render
 {
-FrameBuffer::FrameBuffer(int width, int height, GLenum internal_format)
+FrameBuffer::FrameBuffer(std::shared_ptr<Texture2D> texture)
+    : color_tex(texture)
 {
-  this->width = width;
-  this->height = height;
   // Create framebuffer with renderbuffer attachements
   glGenFramebuffers(1, &fbo);
   activate();
-  glGenTextures(1, &color_tex);
-  glBindTexture(GL_TEXTURE_2D, color_tex);
-  glTexStorage2D(GL_TEXTURE_2D, 1, internal_format, width, height);
+  color_tex->bind();
   glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-                         GL_TEXTURE_2D, color_tex, 0);
+                         GL_TEXTURE_2D, color_tex->get_raw(), 0);
+  color_tex->unbind();
   glGenRenderbuffers(1, &depth_stencil_rbo);
   glBindRenderbuffer(GL_RENDERBUFFER, depth_stencil_rbo);
-  glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
+  glRenderbufferStorage(
+      GL_RENDERBUFFER, GL_DEPTH24_STENCIL8,
+      color_tex->get_width(), color_tex->get_height());
   glBindRenderbuffer(GL_RENDERBUFFER, 0);
   glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
                             GL_RENDERBUFFER, depth_stencil_rbo);
@@ -33,7 +33,6 @@ FrameBuffer::~FrameBuffer()
 {
   glBindFramebuffer(GL_FRAMEBUFFER, 0);
   glDeleteRenderbuffers(1, &depth_stencil_rbo);
-  glDeleteTextures(1, &color_tex);
 }
 
 void FrameBuffer::activate() const
@@ -56,7 +55,7 @@ void FrameBuffer::clear(float color, float depth, int stencil) const
   deactivate();
 }
 
-GLuint FrameBuffer::get_texture() const
+std::shared_ptr<Texture2D> FrameBuffer::get_texture() const
 {
   return color_tex;
 }
diff --git a/src/buffer/frame_buffer_reader.cpp b/src/buffer/frame_buffer_reader.cpp
index 9221e49ce65d8631ea32ab12c34ea3fcbbdd27aa..9029ad53361c4cbf0eebfac180017c7b127b1525 100644
--- a/src/buffer/frame_buffer_reader.cpp
+++ b/src/buffer/frame_buffer_reader.cpp
@@ -5,30 +5,38 @@
 
 namespace scigl_render
 {
-FramebufferReader::FramebufferReader(int width, int height, size_t pixel_size)
-    : width(width), height(height)
+FramebufferReader::FramebufferReader(std::shared_ptr<FrameBuffer> buffer,
+                                     size_t pixel_size)
+    : framebuffer(buffer)
 {
   glGenBuffers(pbos.size(), pbos.data());
+  size_t buffer_size = framebuffer->get_texture()->get_width() *
+                       framebuffer->get_texture()->get_height() *
+                       pixel_size;
   for (size_t i = 0; i < pbos.size(); i++)
   {
     glBindBuffer(GL_PIXEL_PACK_BUFFER, pbos[i]);
     // constantly reading new contents
-    glBufferData(GL_PIXEL_PACK_BUFFER, width * height * pixel_size, 0,
+    glBufferData(GL_PIXEL_PACK_BUFFER, buffer_size, 0,
                  GL_DYNAMIC_READ);
   }
   glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
   check_gl_error("framebuffer-reader created pbos");
 }
 
-void FramebufferReader::start_read(GLenum format, GLenum type,
-                                   const FrameBuffer &buffer) const
+void FramebufferReader::start_read() const
 {
-  buffer.activate();
+  framebuffer->activate();
   glReadBuffer(GL_COLOR_ATTACHMENT0);
   glBindBuffer(GL_PIXEL_PACK_BUFFER, pbos[backbuffer_index]);
-  glReadPixels(0, 0, width, height, format, type, nullptr);
+  glReadPixels(0, 0,
+               framebuffer->get_texture()->get_width(),
+               framebuffer->get_texture()->get_height(),
+               framebuffer->get_texture()->get_format(),
+               framebuffer->get_texture()->get_type(),
+               nullptr);
   glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
-  buffer.deactivate();
+  framebuffer->deactivate();
 }
 
 void *FramebufferReader::do_read() const
diff --git a/src/buffer/texture2d.cpp b/src/buffer/texture2d.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a8205224edf0917d5f5a5c6e4f57c9c2c572cef7
--- /dev/null
+++ b/src/buffer/texture2d.cpp
@@ -0,0 +1,69 @@
+#include <scigl_render/buffer/texture2d.hpp>
+
+namespace scigl_render
+{
+Texture2D::Texture2D(GLsizei width, GLsizei height,
+                     GLenum format, GLenum internal_format, GLenum type)
+    : width(width), height(height),
+      format(format), internal_format(internal_format),
+      type(type)
+{
+  glGenTextures(1, &texture);
+  glBindTexture(GL_TEXTURE_2D, texture);
+  glTexStorage2D(GL_TEXTURE_2D, 1, internal_format, width, height);
+  glBindTexture(GL_TEXTURE_2D, 0);
+}
+
+Texture2D::~Texture2D()
+{
+  glDeleteTextures(1, &texture);
+}
+
+GLuint Texture2D::get_raw() const
+{
+  return texture;
+}
+
+GLsizei Texture2D::get_width() const
+{
+  return width;
+}
+GLsizei Texture2D::get_height() const
+{
+  return height;
+}
+GLenum Texture2D::get_format() const
+{
+  return format;
+}
+GLenum Texture2D::get_internal_format() const
+{
+  return internal_format;
+}
+GLenum Texture2D::get_type() const
+{
+  return type;
+}
+
+void Texture2D::activate(GLenum texture_n)
+{
+  glActiveTexture(texture_n);
+}
+
+void Texture2D::bind() const
+{
+  glBindTexture(GL_TEXTURE_2D, texture);
+}
+
+void Texture2D::unbind() const
+{
+  glBindTexture(GL_TEXTURE_2D, 0);
+}
+
+void Texture2D::store_image(const GLvoid *image) const
+{
+  bind();
+  glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, format, type, image);
+  unbind();
+}
+} // namespace scigl_render
diff --git a/src/example/depth_offscreen_render.cpp b/src/example/depth_offscreen_render.cpp
index ca9ee446d4ff5f7dcd243e89d77ae67d27b1606e..a32655a8b506e09517329a86c6e9155043224a10 100644
--- a/src/example/depth_offscreen_render.cpp
+++ b/src/example/depth_offscreen_render.cpp
@@ -4,31 +4,24 @@
 namespace scigl_render
 {
 // I know there is a lot of configuration but it is intendet to be flexible
-DepthOffscreenRender::DepthOffscreenRender(
-    std::shared_ptr<GLContext> context,
-    GLenum tex_format, GLenum tex_type, GLint tex_internal_format,
-    size_t pixel_size)
-    : texture_format(tex_format),
-      texture_type(tex_type),
-      texture_internal_format(tex_internal_format),
-      pixel_size(pixel_size),
-      gl_context(context),
-      framebuffer(gl_context->get_width(),
-                  gl_context->get_height(),
-                  tex_internal_format),
-      fbo_reader(gl_context->get_width(),
-                 gl_context->get_height(),
-                 pixel_size),
-      texture_render(gl_context->get_width(),
-                     gl_context->get_height(),
-                     tex_internal_format),
-      image_buffer(gl_context->get_width() * gl_context->get_height() *
+DepthOffscreenRender::DepthOffscreenRender(std::shared_ptr<GLContext> context,
+                                           std::shared_ptr<Texture2D> texture,
+                                           size_t pixel_size)
+    : rasterizer(context->get_width() / 2, context->get_height() / 2,
+                 2, 2),
+      image_buffer(context->get_width() * context->get_height() *
                    pixel_size),
-      rasterizer(gl_context->get_width() / 2,
-                 gl_context->get_height() / 2,
-                 2, 2)
+      gl_context(context),
+      fbo_texture(texture)
 {
-  check_gl_error("example render created");
+  framebuffer = std::make_shared<FrameBuffer>(fbo_texture);
+  fbo_reader = std::unique_ptr<FramebufferReader>(
+      new FramebufferReader(framebuffer, pixel_size));
+  // create second texture to copy the data to
+  quad_texture = std::make_shared<Texture2D>(
+      fbo_texture->get_width(), fbo_texture->get_height(),
+      fbo_texture->get_format(), fbo_texture->get_internal_format(),
+      fbo_texture->get_type());
 }
 
 void DepthOffscreenRender::next_frame(
@@ -39,10 +32,9 @@ void DepthOffscreenRender::next_frame(
   using namespace std::placeholders;
   check_gl_error("next frame begin");
   // render to cleared fbo
-  framebuffer.clear();
-  framebuffer.activate();
+  framebuffer->clear();
+  framebuffer->activate();
   check_gl_error("activated fbo");
-
   // render 4 poses via rasterization
   for (int i = 0; i < 4; i++)
   {
@@ -54,16 +46,18 @@ void DepthOffscreenRender::next_frame(
   }
   // back to default
   rasterizer.activate_all();
-  framebuffer.deactivate();
+  framebuffer->deactivate();
 
   // read data from fbo
-  fbo_reader.start_read(texture_format, texture_type, framebuffer);
+  fbo_reader->start_read();
   check_gl_error("asynchronous reading to pbo");
-  auto data = fbo_reader.do_read();
+  auto data = fbo_reader->do_read();
   check_gl_error("synchronous reading from pbo");
+
+  // display the data on screen
   display_data(data);
-  fbo_reader.end_read();
-  fbo_reader.swap_buffers();
+  fbo_reader->end_read();
+  fbo_reader->swap_buffers();
   check_gl_error("end synchronous reading");
 }
 
@@ -71,30 +65,13 @@ void DepthOffscreenRender::display_data(const void *data)
 {
   // Test copying the data, buffer_size is in bytes
   memcpy(image_buffer.data(), data, image_buffer.size());
+  quad_texture->store_image(data);
   // draw the copy
   glClearColor(0, 0, 0, 0);
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-  texture_render.draw(image_buffer.data(), texture_format, texture_type);
+  texture_render.draw(quad_texture);
   check_gl_error("drawing fullscreen quad");
   // update
   glfwSwapBuffers(gl_context->get_window());
 }
-
-void DepthOffscreenRender::resize_buffers()
-{
-  framebuffer = FrameBuffer(
-      gl_context->get_width(),
-      gl_context->get_height(),
-      texture_internal_format);
-  fbo_reader = FramebufferReader(
-      gl_context->get_width(),
-      gl_context->get_height(),
-      pixel_size);
-  texture_render = TextureFullscreenRender(
-      gl_context->get_width(),
-      gl_context->get_height(),
-      texture_internal_format),
-  image_buffer = std::vector<unsigned char>(
-      gl_context->get_width() * gl_context->get_height() * pixel_size);
-}
 } // namespace scigl_render
\ No newline at end of file
diff --git a/src/example/scigl_depth_viewer.cpp b/src/example/scigl_depth_viewer.cpp
index a118dbfdea0cec012120f5d68b4b7a509a30a1e7..1114f92191374e9820ac3e39cf14bb7b864ab2c0 100644
--- a/src/example/scigl_depth_viewer.cpp
+++ b/src/example/scigl_depth_viewer.cpp
@@ -39,11 +39,12 @@ int main(int argc, char *argv[])
         "No model file provided. Run as */scigl_viwer <model_filename>!");
   }
   // Setup renderer creates context
-  std::shared_ptr<GLContext> context =
-      std::make_shared<GLContext>(true, false, WIDTH, HEIGHT);
+  auto context = std::make_shared<GLContext>(true, false, WIDTH, HEIGHT);
   check_gl_error("Context created");
-  DepthOffscreenRender render(context, GL_RED, GL_FLOAT, GL_R32F,
-                              sizeof(float));
+  auto texture = std::make_shared<Texture2D>(
+      WIDTH, HEIGHT, GL_RED, GL_R32F, GL_FLOAT);
+  check_gl_error("texture created");
+  DepthOffscreenRender render(context, texture, sizeof(float));
   // Intrinsics of my shitty webcam
   CameraIntrinsics camera_intrinsics;
   camera_intrinsics.width = 640;
diff --git a/src/render/texture_fullscreen_render.cpp b/src/render/texture_fullscreen_render.cpp
index 5c485f97c313d4b9e27913287b9378c648afc6c0..92358c1bfba6bcd708a7273cfaa2329827f41270 100644
--- a/src/render/texture_fullscreen_render.cpp
+++ b/src/render/texture_fullscreen_render.cpp
@@ -24,20 +24,13 @@ void main()
   color = texture(texture0, texture_coordinate);
 })";
 
-TextureFullscreenRender::TextureFullscreenRender(
-    int width, int height, GLint internal_format)
-    : width(width), height(height)
+TextureFullscreenRender::TextureFullscreenRender()
 {
   ShaderBuilder shader_builder;
   shader_builder.attach_vertex_shader(vertex_source);
   shader_builder.attach_geometry_shader(geometry_source);
   shader_builder.attach_fragment_shader(fragment_source);
   shader = shader_builder.build();
-  // create the texture buffer
-  glGenTextures(1, &texture);
-  glBindTexture(GL_TEXTURE_2D, texture);
-  glTexStorage2D(GL_TEXTURE_2D, 1, internal_format, width, height);
-  glBindTexture(GL_TEXTURE_2D, 0);
   // create dummy VAO
   glGenVertexArrays(1, &vao);
   glBindVertexArray(vao);
@@ -45,23 +38,20 @@ TextureFullscreenRender::TextureFullscreenRender(
   check_gl_error("TextureFullscreenRender created");
 }
 
-void TextureFullscreenRender::draw(
-    const GLvoid *pixels, GLenum format, GLenum type)
+void TextureFullscreenRender::draw(std::shared_ptr<Texture2D> texture) const
 {
   // With GL_LESS the cleared buffer (z = 1.0) would always win
   glDepthFunc(GL_LEQUAL);
-  // activate the shader and texure
+
   shader.activate();
-  glActiveTexture(GL_TEXTURE0);
-  glBindTexture(GL_TEXTURE_2D, texture);
-  // copy data to OpenGL
-  glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, format, type, pixels);
-  // draw the image
+  texture->bind();
+  Texture2D::activate(GL_TEXTURE0);
   shader.setInt("texture0", 0);
   glBindVertexArray(vao);
   glDrawArrays(GL_POINTS, 0, 1);
   // unbind the resources
-  glBindTexture(GL_TEXTURE_2D, 0);
+  shader.deactivate();
+  texture->unbind();
   glBindVertexArray(0);
 }
 } // namespace scigl_render
\ No newline at end of file