diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp
index 624d1a40f62520fb4ee988c8751fd0aff9e67153..5b014bbda8a4aea0c765088766fb6c734222ea6f 100644
--- a/projects/first_triangle/src/main.cpp
+++ b/projects/first_triangle/src/main.cpp
@@ -5,12 +5,6 @@
 
 int main(int argc, const char** argv) {
     const char* applicationName = "First Triangle";
-	vkcv::Window window = vkcv::Window::create(
-            applicationName,
-        800,
-        600,
-		false
-	);
 	vkcv::Context context = vkcv::Context::create(
             applicationName,
 		VK_MAKE_VERSION(0, 0, 1),
@@ -20,11 +14,17 @@ int main(int argc, const char** argv) {
 		{"VK_KHR_swapchain"}
 	);
 
-	GLFWwindow *glWindow = window.getWindow();
-	const vk::Instance& instance = context.getInstance();
-	const vk::PhysicalDevice& physicalDevice = context.getPhysicalDevice();
-	const vk::Device& device = context.getDevice();
-    const vkcv::SwapChain& swapChain = vkcv::SwapChain::create(glWindow, instance, physicalDevice, device);
+    const vk::Instance& instance = context.getInstance();
+    const vk::PhysicalDevice& physicalDevice = context.getPhysicalDevice();
+    const vk::Device& device = context.getDevice();
+
+    vkcv::Window window = vkcv::Window::create(
+            context,
+            applicationName,
+            800,
+            600,
+            false
+    );
 
 	std::cout << "Physical device: " << physicalDevice.getProperties().deviceName << std::endl;
 
diff --git a/src/vkcv/Context.cpp b/src/vkcv/Context.cpp
index 3d5dfca627a064a49a57a015b23c4c7d919a2f07..ce94145aebf605ea108f7e96cac7cccd0b9fd480 100644
--- a/src/vkcv/Context.cpp
+++ b/src/vkcv/Context.cpp
@@ -6,6 +6,7 @@
 
 #include "Context.hpp"
 #include "CoreManager.hpp"
+#include <iostream>
 
 namespace vkcv {
 
@@ -124,7 +125,12 @@ namespace vkcv {
 
 
 		vk::Device device = physicalDevice.createDevice(deviceCreateInfo);
-		// TODO: implement device.getQueue() to access the queues, if needed
+		// TODO: implement device.getQueue() to access the queues, if neede
+		//std::vector<vk::QueueFamilyProperties> queueFamilyProperties = physicalDevice.getQueueFamilyProperties();
+        //uint32_t graphicsQueueFamilyIndex = vkcv::findGraphicsQueueFamilyIndex( queueFamilyProperties );
+       // for(uint32_t i = 0; true; i++){
+       //     vk::Queue graphicsQueue = device.getQueue( graphicsQueueFamilyIndex, i );
+       // }
 
 		return Context(instance, physicalDevice, device);
 	}
@@ -253,4 +259,11 @@ namespace vkcv {
 
 		return extensions;
 	}
+
+    uint32_t Context::findGraphicsQueueFamilyIndex(uint32_t queueCount, std::vector<vk::DeviceQueueCreateInfo> &createInfos){
+        for(auto createInfo: createInfos){
+            std::cout << createInfo.queueCount << std::endl;
+        }
+	    return 0;
+    }
 }
diff --git a/src/vkcv/Context.hpp b/src/vkcv/Context.hpp
index 1d11f82743ada5d1493df48ece54e558c234df47..bcfb648bbc2e2840551c8d1fe1c014389fef6e47 100644
--- a/src/vkcv/Context.hpp
+++ b/src/vkcv/Context.hpp
@@ -144,6 +144,8 @@ namespace vkcv {
 		 * @return 
 		*/
 		static std::vector<vk::DeviceQueueCreateInfo> getQueueCreateInfos(vk::PhysicalDevice& physicalDevice, uint32_t queueCount, std::vector<float>& qPriorities, std::vector<vk::QueueFlagBits> &queueFlags);
+
+        static uint32_t findGraphicsQueueFamilyIndex(uint32_t queueCount, std::vector<vk::DeviceQueueCreateInfo> &createInfos);
 	};
 
 }
diff --git a/src/vkcv/CoreManager.cpp b/src/vkcv/CoreManager.cpp
index 471075e3b48eb6aba8251d2924c00462f506fbc3..be33bee0dc3333cf2dc5f032fdf29d92b974b900 100644
--- a/src/vkcv/CoreManager.cpp
+++ b/src/vkcv/CoreManager.cpp
@@ -28,4 +28,16 @@ namespace vkcv {
         }
         glfwCounter--;
     }
+
+    int getWidth(GLFWwindow *window)  {
+        int width;
+        glfwGetWindowSize(window, &width, nullptr);
+        return width;
+    }
+
+    int getHeight(GLFWwindow *window)  {
+        int height;
+        glfwGetWindowSize(window, nullptr, &height);
+        return height;
+    }
 }
diff --git a/src/vkcv/CoreManager.hpp b/src/vkcv/CoreManager.hpp
index a4104ae4a8dca0b01825f023bcb3ec2a2808c876..90095b3782daf1414571c82fe10a97d358fb64d1 100644
--- a/src/vkcv/CoreManager.hpp
+++ b/src/vkcv/CoreManager.hpp
@@ -6,7 +6,9 @@
  */
 
 #include <GLFW/glfw3.h>
+#include "vulkan/vulkan.hpp"
 #include <stdexcept>
+#include <vector>
 
 namespace vkcv {
 
@@ -19,4 +21,18 @@ namespace vkcv {
      * terminates glfw once, if it was initialized or decreases the counter
      */
     void terminateGLFW();
+
+    /**
+     * gets the window width
+     * @param window glfwWindow
+     * @return int with window width
+     */
+    int getWidth(GLFWwindow *window);
+
+    /**
+     * gets the window height
+     * @param window glfwWindow
+     * @return int with window height
+     */
+    int getHeight(GLFWwindow *window);
 }
diff --git a/src/vkcv/SwapChain.cpp b/src/vkcv/SwapChain.cpp
index ed999fcda4bc34f04c7ccbdee04aed2f65c268c8..ceee227ef0748538d4ea731ac7487447aa69a340 100644
--- a/src/vkcv/SwapChain.cpp
+++ b/src/vkcv/SwapChain.cpp
@@ -1,40 +1,141 @@
 #include "SwapChain.hpp"
 #include "CoreManager.hpp"
-#include <iostream>
 
 namespace vkcv {
 
-    SwapChain::SwapChain(vk::SurfaceKHR surface)
-        : m_surface(surface)
+    SwapChain::SwapChain(vk::SurfaceKHR surface, const vkcv::Context* context)
+        : m_surface(surface), m_context(context)
         {}
 
-    SwapChain SwapChain::create(GLFWwindow* window, const vk::Instance& instance, const vk::PhysicalDevice& physicalDevice, const vk::Device& device){
-        vk::SurfaceKHR surface = VK_NULL_HANDLE;
-        createSurface(window,surface,instance,physicalDevice);
-        vk::SurfaceCapabilitiesKHR surfaceCapabilities;
-        if(physicalDevice.getSurfaceCapabilitiesKHR(surface,&surfaceCapabilities) != vk::Result::eSuccess){
-                throw std::runtime_error("cannot get surface capabilites. There is an issue with the surface.");
-        }
+    SwapChain SwapChain::create(GLFWwindow* window, const vkcv::Context* context){
+
+        const vk::Instance& instance = context->getInstance();
+        const vk::PhysicalDevice& physicalDevice = context->getPhysicalDevice();
+        const vk::Device& device = context->getDevice();
 
+        vk::SurfaceKHR surface = createSurface(window,instance,physicalDevice);
 
+        vk::Extent2D extent2D = chooseSwapExtent(physicalDevice, surface, window);
+        vk::SurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(physicalDevice, surface);
+        vk::PresentModeKHR presentMode = choosePresentMode(physicalDevice, surface);
 
 
-        return SwapChain(surface);
+//        vk::SwapchainCreateInfoKHR swapchainCreateInfo(
+//                vk::SwapchainCreateFlagBitsKHR()
+//                VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,  // VkStructureType                sType
+//                nullptr,                                      // const void                    *pNext
+//                0,                                            // VkSwapchainCreateFlagsKHR      flags
+//                surface,                   // VkSurfaceKHR                   surface
+//                desired_number_of_images,                     // uint32_t                       minImageCount
+//                desired_format.format,                        // VkFormat                       imageFormat
+//                desired_format.colorSpace,                    // VkColorSpaceKHR                imageColorSpace
+//                desired_extent,                               // VkExtent2D                     imageExtent
+//                1,                                            // uint32_t                       imageArrayLayers
+//                desired_usage,                                // VkImageUsageFlags              imageUsage
+//                VK_SHARING_MODE_EXCLUSIVE,                    // VkSharingMode                  imageSharingMode
+//                0,                                            // uint32_t                       queueFamilyIndexCount
+//                nullptr,                                      // const uint32_t                *pQueueFamilyIndices
+//                desired_transform,                            // VkSurfaceTransformFlagBitsKHR  preTransform
+//                VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,            // VkCompositeAlphaFlagBitsKHR    compositeAlpha
+//                desired_present_mode,                         // VkPresentModeKHR               presentMode
+//                VK_TRUE,                                      // VkBool32                       clipped
+//                old_swap_chain                                // VkSwapchainKHR                 oldSwapchain
+//        );
+
+//        vk::SwapchainCreateInfoKHR swapchainCreateInfo(
+//                vk::SwapchainCreateFlagsKHR(),  //flags
+//                surface, // surface
+//                surfaceCapabilities.minImageCount, // minImageCount TODO: how many do we need for our application?? "must be less than or equal to the value returned in maxImageCount"
+//                vk::Format::eB8G8R8A8Unorm,         // imageFormat  TODO: what image format should be used?
+//                vk::ColorSpaceKHR::eSrgbNonlinear, // imageColorSpace   TODO: which color space should be used?
+//                vk::Extent2D(width, height), // imageExtent
+//                1, // imageArrayLayers TODO: should we only allow non-stereoscopic applications? yes -> 1, no -> ? "must be greater than 0, less or equal to maxImageArrayLayers"
+//                vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eDepthStencilAttachment, // imageUsage   TODO: what attachments? only color? depth?
+//                vk::SharingMode::eExclusive, // imageSharingMode TODO: which sharing mode? "VK_SHARING_MODE_EXCLUSIV access exclusive to a single queue family, better performance", "VK_SHARING_MODE_CONCURRENT access from multiple queues"
+//                0, // queueFamilyIndexCount, the number of queue families having access to the image(s) of the swapchain when imageSharingMode is VK_SHARING_MODE_CONCURRENT
+//                nullptr, // pQueueFamilyIndices, the pointer to an array of queue family indices having access to the images(s) of the swapchain when imageSharingMode is VK_SHARING_MODE_CONCURRENT
+//                vk::SurfaceTransformFlagBitsKHR::eIdentity, // preTransform, transformations applied onto the image before display
+//                vk::CompositeAlphaFlagBitsKHR::eOpaque, // compositeAlpha, TODO: how to handle transparent pixels? do we need transparency? If no -> opaque
+//                vk::PresentModeKHR::eFifo, // presentMode
+//                true, // clipped
+//                nullptr // oldSwapchain
+//        );
+
+        return SwapChain(surface, context);
 
     }
 
-    void SwapChain::createSurface(GLFWwindow *window, vk::SurfaceKHR &surface, const vk::Instance &instance, const vk::PhysicalDevice& physicalDevice) {
+    vk::SurfaceKHR SwapChain::createSurface(GLFWwindow *window, const vk::Instance &instance, const vk::PhysicalDevice& physicalDevice) {
          //create surface
-         auto newSurface = VkSurfaceKHR(surface);
+         VkSurfaceKHR surface;
          // 0 means VK_SUCCESS
          //std::cout << "FAIL:     " << glfwCreateWindowSurface(VkInstance(instance), window, nullptr, &newSurface) << std::endl;
-         if(glfwCreateWindowSurface(VkInstance(instance), window, nullptr, &newSurface) != VK_SUCCESS) {
+         if(glfwCreateWindowSurface(VkInstance(instance), window, nullptr, &surface) != VK_SUCCESS) {
              throw std::runtime_error("failed to create a window surface!");
          }
          vk::Bool32 surfaceSupport = false;
          // ToDo: hierfuer brauchen wir jetzt den queuefamiliy Index -> siehe ToDo in Context.cpp
          //if(physicalDevice.getSurfaceSupportKHR())
+        return vk::SurfaceKHR(surface);
+    }
+
+    vk::Extent2D SwapChain::chooseSwapExtent(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface, GLFWwindow* window){
+        vk::SurfaceCapabilitiesKHR surfaceCapabilities;
+        if(physicalDevice.getSurfaceCapabilitiesKHR(surface,&surfaceCapabilities) != vk::Result::eSuccess){
+            throw std::runtime_error("cannot get surface capabilities. There is an issue with the surface.");
+        }
+
+        VkExtent2D extent2D = {
+                static_cast<uint32_t>(vkcv::getWidth(window)),
+                static_cast<uint32_t>(vkcv::getHeight(window))
+        };
+        extent2D.width = std::max(surfaceCapabilities.minImageExtent.width, std::min(surfaceCapabilities.maxImageExtent.width, extent2D.width));
+        extent2D.height = std::max(surfaceCapabilities.minImageExtent.height, std::min(surfaceCapabilities.maxImageExtent.height, extent2D.height));
+
+        if (extent2D.width > surfaceCapabilities.maxImageExtent.width ||
+            extent2D.width < surfaceCapabilities.minImageExtent.width ||
+            extent2D.height > surfaceCapabilities.maxImageExtent.height ||
+            extent2D.height < surfaceCapabilities.minImageExtent.height) {
+            std::printf("Surface size not matching. Resizing to allowed value.");
+        }
+        return extent2D;
+    }
+
+    vk::SurfaceFormatKHR SwapChain::chooseSwapSurfaceFormat(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface) {
+        uint32_t formatCount;
+        physicalDevice.getSurfaceFormatsKHR(surface, &formatCount, nullptr);
+        std::vector<vk::SurfaceFormatKHR> availableFormats(formatCount);
+        if (physicalDevice.getSurfaceFormatsKHR(surface, &formatCount, &availableFormats[0]) != vk::Result::eSuccess) {
+            throw std::runtime_error("Failed to get surface formats");
+        }
+
+        for (const auto& availableFormat : availableFormats) {
+            if (availableFormat.format == vk::Format::eB8G8R8A8Unorm  && availableFormat.colorSpace == vk::ColorSpaceKHR::eSrgbNonlinear) {
+                return availableFormat;
+            }
+        }
+        return availableFormats[0];
+    }
+
+    vk::PresentModeKHR SwapChain::choosePresentMode(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface) {
+        uint32_t modeCount;
+        physicalDevice.getSurfacePresentModesKHR( surface, &modeCount, nullptr );
+        std::vector<vk::PresentModeKHR> availablePresentModes(modeCount);
+        if (physicalDevice.getSurfacePresentModesKHR(surface, &modeCount, &availablePresentModes[0]) != vk::Result::eSuccess) {
+            throw std::runtime_error("Failed to get presentation modes");
+        }
+
+        for (const auto& availablePresentMode : availablePresentModes) {
+            if (availablePresentMode == vk::PresentModeKHR::eMailbox) {
+                return availablePresentMode;
+            }
+        }
+        return vk::PresentModeKHR::eFifo;
+    }
 
+    SwapChain::~SwapChain() {
+//      m_context->getDevice().destroySwapchainKHR( m_swapChain );
+      m_context->getInstance().destroySurfaceKHR( m_surface );
     }
 
 }
\ No newline at end of file
diff --git a/src/vkcv/SwapChain.hpp b/src/vkcv/SwapChain.hpp
index 925cc694260aada0fd59a2729b2038e47507297d..d6f24ef5b18086bb5b6fc817a86808087a770252 100644
--- a/src/vkcv/SwapChain.hpp
+++ b/src/vkcv/SwapChain.hpp
@@ -1,28 +1,38 @@
 #pragma once
 #include "vulkan/vulkan.hpp"
 #include "Context.hpp"
-#include "Window.hpp"
+#include <GLFW/glfw3.h>
+#include <iostream>
 
 
 // glfw is not initialized in this class because ist must be sure that there exists a context first
 // glfw is already initialized by the context or the window class
 
 namespace vkcv {
-
     class SwapChain final {
     private:
+
         vk::SurfaceKHR m_surface;
+        const vkcv::Context* m_context;
+
+        SwapChain(vk::SurfaceKHR surface, const vkcv::Context* context);
 
-        SwapChain(vk::SurfaceKHR);
+        static vk::SurfaceFormatKHR chooseSwapSurfaceFormat(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface);
+
+        static vk::PresentModeKHR choosePresentMode(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface);
+
+        static vk::Extent2D chooseSwapExtent(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface, GLFWwindow* window );
 
     public:
         // bin mir grade unsicher wegen der Mehrfachinstanziierung der Klasse
         // es muessen ja oefter mal neue erstellt werden, aber diese existieren ja nicht gleichzeitig, oder?
         SwapChain(const SwapChain &other) = delete;
         SwapChain(SwapChain &&other) = default;
-        static SwapChain create(GLFWwindow *window, const vk::Instance& instance,const vk::PhysicalDevice& physicalDevice,const vk::Device& device);
-        static void createSurface(GLFWwindow *window, vk::SurfaceKHR& surface, const vk::Instance& instance, const vk::PhysicalDevice& physicalDevice);
 
+        static SwapChain create(GLFWwindow *window, const vkcv::Context* Context);
+        static vk::SurfaceKHR createSurface(GLFWwindow *window, const vk::Instance& instance, const vk::PhysicalDevice& physicalDevice);
+
+        virtual ~SwapChain();
     };
 
 }
\ No newline at end of file
diff --git a/src/vkcv/Window.cpp b/src/vkcv/Window.cpp
index 7d8b86e08f25fe7741db1cfa777f00054aa8cee0..b6514b481bb4e1d63ec09dacc5454158a24ad628 100644
--- a/src/vkcv/Window.cpp
+++ b/src/vkcv/Window.cpp
@@ -7,10 +7,11 @@
 #include "Window.hpp"
 #include "CoreManager.hpp"
 
+
 namespace vkcv {
 
-    Window::Window(GLFWwindow *window)
-            : m_window(window) {
+    Window::Window(GLFWwindow *window, const vkcv::SwapChain *swapChain)
+            : m_window(window), m_swapChain(swapChain){
     }
 
     Window::~Window() {
@@ -27,7 +28,12 @@ namespace vkcv {
         glfwWindowHint(GLFW_RESIZABLE, resizable ? GLFW_TRUE : GLFW_FALSE);
         GLFWwindow *window;
         window = glfwCreateWindow(width, height, windowTitle, nullptr, nullptr);
-        return Window(window);
+
+       const vkcv::SwapChain swapChain = vkcv::SwapChain::create(
+                window,
+                &context);
+
+        return Window(window, &swapChain);
     }
 
     bool Window::isWindowOpen() const {
@@ -41,16 +47,4 @@ namespace vkcv {
     GLFWwindow *Window::getWindow() const {
         return m_window;
     }
-
-    int Window::getWidth() const {
-        int width;
-        glfwGetWindowSize(m_window, &width, nullptr);
-        return width;
-    }
-
-    int Window::getHeight() const {
-        int height;
-        glfwGetWindowSize(m_window, nullptr, &height);
-        return height;
-    }
 }
\ No newline at end of file
diff --git a/src/vkcv/Window.hpp b/src/vkcv/Window.hpp
index 62440d90143d5c4cd9a31fbdf46819fdeda2d101..816ed3b7bb24f62a6398f5e15b42f28a3b09de2b 100644
--- a/src/vkcv/Window.hpp
+++ b/src/vkcv/Window.hpp
@@ -7,18 +7,20 @@
 
 #define GLFW_INCLUDE_VULKAN
 #include <GLFW/glfw3.h>
+#include "SwapChain.hpp"
 
 namespace vkcv {
-
     class Window final {
     private:
         GLFWwindow *m_window;
 
+        const vkcv::SwapChain* m_swapChain;
+
         /**
          *
          * @param GLFWwindow of the class
          */
-        explicit Window(GLFWwindow *window);
+        Window(GLFWwindow *window, const vkcv::SwapChain *swapChain);
 
     public:
         /**
@@ -29,8 +31,7 @@ namespace vkcv {
          * @param[in] resizable resize ability of the window (optional)
          * @return Window class
          */
-        static Window create(const char *windowTitle, int width = -1, int height = -1, bool resizable = false);
-
+        static Window create(const vkcv::Context& context, const char *windowTitle, int width = -1, int height = -1, bool resizable = false);
         /**
          * checks if the window is still open, or the close event was called
          * This function should be changed/removed later on
@@ -51,20 +52,6 @@ namespace vkcv {
         [[nodiscard]]
         GLFWwindow *getWindow() const;
 
-        /**
-         * gets the current window width
-         * @return int with window width
-         */
-        [[nodiscard]]
-        int getWidth() const;
-
-        /**
-         * gets the current window height
-         * @return int with window height
-         */
-        [[nodiscard]]
-        int getHeight() const;
-
         /**
          * Copy-operator of #Window is deleted!
          *