error in drawing iteration

hey,

i wrote a vulkan application (following this tutorial), that renders a blue square. it actually does render the blue square, but the output is flickering. I’m using triple buffering.
a closer look to the console ouput (using validation layers) shows some errors:

image 0

image 1

validation layer: You must call vkEndCommandBuffer() on CB 0x40acd00 before this
call to vkQueueSubmit()!


validation layer: vkQueuePresentKHR(): Cannot read invalid swapchain image 0x5,
please fill the memory before using.


validation layer: Images passed to present must be in layout VK_IMAGE_LAYOUT_PRE
SENT_SRC_KHR but is in VK_IMAGE_LAYOUT_UNDEFINED

image 2

validation layer: You must call vkEndCommandBuffer() on CB 0x40acd10 before this
call to vkQueueSubmit()!


validation layer: vkQueuePresentKHR(): Cannot read invalid swapchain image 0x4,
please fill the memory before using.


validation layer: Images passed to present must be in layout VK_IMAGE_LAYOUT_PRE
SENT_SRC_KHR but is in VK_IMAGE_LAYOUT_UNDEFINED

so it seems that triple buffering is not working. I assume that image 0 always works, since i never recieved an error for this one, and image 1 and 2 cause the flickering. what I don’t understand… why does the app think there is an swapchain image 0x4 or even 0x5, since the total output number is 3!

that’s the whole code:


#include "de_core.h"

VkResult CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT * pcreate_info, const VkAllocationCallbacks * pallocator, VkDebugReportCallbackEXT * pcallback)
{
  auto func = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT");

  if(func != nullptr)
    {return func(instance, pcreate_info, pallocator, pcallback);}
  else
    {return VK_ERROR_EXTENSION_NOT_PRESENT;}
}

void DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT pcallback, const VkAllocationCallbacks * pallocator) 
{
  auto func = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT");

  if(func != nullptr) 
    {func(instance, pcallback, pallocator);}
}

void cDEcore::DEcore_key_event()
{
  // key pressed

  if(glfwGetKey(this->pwindow, GLFW_KEY_UNKNOWN) == GLFW_PRESS)
    {this->keyboard.unknown.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_SPACE) == GLFW_PRESS)
    {this->keyboard.space.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_APOSTROPHE) == GLFW_PRESS)
    {this->keyboard.apostrophe.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_COMMA) == GLFW_PRESS)
    {this->keyboard.comma.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_MINUS) == GLFW_PRESS)
    {this->keyboard.minus.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_PERIOD) == GLFW_PRESS)
    {this->keyboard.period.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_SLASH) == GLFW_PRESS)
    {this->keyboard.slash.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_0) == GLFW_PRESS)
    {this->keyboard.k0.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_1) == GLFW_PRESS)
    {this->keyboard.k1.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_2) == GLFW_PRESS)
    {this->keyboard.k2.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_3) == GLFW_PRESS)
    {this->keyboard.k3.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_4) == GLFW_PRESS)
    {this->keyboard.k4.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_5) == GLFW_PRESS)
    {this->keyboard.k5.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_6) == GLFW_PRESS)
    {this->keyboard.k6.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_7) == GLFW_PRESS)
    {this->keyboard.k7.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_8) == GLFW_PRESS)
    {this->keyboard.k8.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_9) == GLFW_PRESS)
    {this->keyboard.k9.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_SEMICOLON) == GLFW_PRESS)
    {this->keyboard.semicolon.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_EQUAL) == GLFW_PRESS)
    {this->keyboard.equal.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_A) == GLFW_PRESS)
    {this->keyboard.ka.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_B) == GLFW_PRESS)
    {this->keyboard.kb.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_C) == GLFW_PRESS)
    {this->keyboard.kc.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_D) == GLFW_PRESS)
    {this->keyboard.kd.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_E) == GLFW_PRESS)
    {this->keyboard.ke.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F) == GLFW_PRESS)
    {this->keyboard.kf.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_G) == GLFW_PRESS)
    {this->keyboard.kg.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_H) == GLFW_PRESS)
    {this->keyboard.kh.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_I) == GLFW_PRESS)
    {this->keyboard.ki.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_J) == GLFW_PRESS)
    {this->keyboard.kj.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_K) == GLFW_PRESS)
    {this->keyboard.kk.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_L) == GLFW_PRESS)
    {this->keyboard.kl.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_M) == GLFW_PRESS)
    {this->keyboard.km.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_N) == GLFW_PRESS)
    {this->keyboard.kn.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_O) == GLFW_PRESS)
    {this->keyboard.ko.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_P) == GLFW_PRESS)
    {this->keyboard.kp.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_Q) == GLFW_PRESS)
    {this->keyboard.kq.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_R) == GLFW_PRESS)
    {this->keyboard.kr.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_S) == GLFW_PRESS)
    {this->keyboard.ks.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_T) == GLFW_PRESS)
    {this->keyboard.kt.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_U) == GLFW_PRESS)
    {this->keyboard.ku.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_V) == GLFW_PRESS)
    {this->keyboard.kv.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_W) == GLFW_PRESS)
    {this->keyboard.kw.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_X) == GLFW_PRESS)
    {this->keyboard.kx.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_Y) == GLFW_PRESS)
    {this->keyboard.ky.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_Z) == GLFW_PRESS)
    {this->keyboard.kz.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_LEFT_BRACKET) == GLFW_PRESS)
    {this->keyboard.left_bracket.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_BACKSLASH) == GLFW_PRESS)
    {this->keyboard.backslash.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_RIGHT_BRACKET) == GLFW_PRESS)
    {this->keyboard.right_bracket.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_GRAVE_ACCENT) == GLFW_PRESS)
    {this->keyboard.grave_accent.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_WORLD_1) == GLFW_PRESS)
    {this->keyboard.world_1.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_WORLD_2) == GLFW_PRESS)
    {this->keyboard.world_2.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_ESCAPE) == GLFW_PRESS)
    {this->keyboard.escape.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_ENTER) == GLFW_PRESS)
    {this->keyboard.enter.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_TAB) == GLFW_PRESS)
    {this->keyboard.tab.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_BACKSPACE) == GLFW_PRESS)
    {this->keyboard.backspace.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_INSERT) == GLFW_PRESS)
    {this->keyboard.insert.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_DELETE) == GLFW_PRESS)
    {this->keyboard.del.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_RIGHT) == GLFW_PRESS)
    {this->keyboard.right.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_LEFT) == GLFW_PRESS)
    {this->keyboard.left.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_DOWN) == GLFW_PRESS)
    {this->keyboard.down.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_UP) == GLFW_PRESS)
    {this->keyboard.up.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_PAGE_UP) == GLFW_PRESS)
    {this->keyboard.page_up.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_PAGE_DOWN) == GLFW_PRESS)
    {this->keyboard.page_down.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_HOME) == GLFW_PRESS)
    {this->keyboard.home.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_END) == GLFW_PRESS)
    {this->keyboard.end.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_CAPS_LOCK) == GLFW_PRESS)
    {this->keyboard.caps_lock.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_SCROLL_LOCK) == GLFW_PRESS)
    {this->keyboard.scroll_lock.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_NUM_LOCK) == GLFW_PRESS)
    {this->keyboard.num_lock.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_PRINT_SCREEN) == GLFW_PRESS)
    {this->keyboard.print_screen.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_PAUSE) == GLFW_PRESS)
    {this->keyboard.pause.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F1) == GLFW_PRESS)
    {this->keyboard.f1.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F2) == GLFW_PRESS)
    {this->keyboard.f2.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F3) == GLFW_PRESS)
    {this->keyboard.f3.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F4) == GLFW_PRESS)
    {this->keyboard.f4.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F5) == GLFW_PRESS)
    {this->keyboard.f5.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F6) == GLFW_PRESS)
    {this->keyboard.f6.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F7) == GLFW_PRESS)
    {this->keyboard.f7.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F8) == GLFW_PRESS)
    {this->keyboard.f8.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F9) == GLFW_PRESS)
    {this->keyboard.f9.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F10) == GLFW_PRESS)
    {this->keyboard.f10.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F11) == GLFW_PRESS)
    {this->keyboard.f11.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F12) == GLFW_PRESS)
    {this->keyboard.f12.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F13) == GLFW_PRESS)
    {this->keyboard.f13.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F14) == GLFW_PRESS)
    {this->keyboard.f14.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F15) == GLFW_PRESS)
    {this->keyboard.f15.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F16) == GLFW_PRESS)
    {this->keyboard.f16.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F17) == GLFW_PRESS)
    {this->keyboard.f17.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F18) == GLFW_PRESS)
    {this->keyboard.f18.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F19) == GLFW_PRESS)
    {this->keyboard.f19.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F20) == GLFW_PRESS)
    {this->keyboard.f20.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F21) == GLFW_PRESS)
    {this->keyboard.f21.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F22) == GLFW_PRESS)
    {this->keyboard.f22.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F23) == GLFW_PRESS)
    {this->keyboard.f23.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F24) == GLFW_PRESS)
    {this->keyboard.f24.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_F25) == GLFW_PRESS)
    {this->keyboard.f25.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_0) == GLFW_PRESS)
    {this->keyboard.kp_0.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_1) == GLFW_PRESS)
    {this->keyboard.kp_1.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_2) == GLFW_PRESS)
    {this->keyboard.kp_2.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_3) == GLFW_PRESS)
    {this->keyboard.kp_3.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_4) == GLFW_PRESS)
    {this->keyboard.kp_4.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_5) == GLFW_PRESS)
    {this->keyboard.kp_5.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_6) == GLFW_PRESS)
    {this->keyboard.kp_6.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_7) == GLFW_PRESS)
    {this->keyboard.kp_7.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_8) == GLFW_PRESS)
    {this->keyboard.kp_8.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_9) == GLFW_PRESS)
    {this->keyboard.kp_9.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_DECIMAL) == GLFW_PRESS)
    {this->keyboard.kp_decimal.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_DIVIDE) == GLFW_PRESS)
    {this->keyboard.kp_divide.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_MULTIPLY) == GLFW_PRESS)
    {this->keyboard.kp_multiply.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_SUBTRACT) == GLFW_PRESS)
    {this->keyboard.kp_subtract.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_ADD) == GLFW_PRESS)
    {this->keyboard.kp_add.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_ENTER) == GLFW_PRESS)
    {this->keyboard.kp_enter.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_EQUAL) == GLFW_PRESS)
    {this->keyboard.kp_equal.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS)
    {this->keyboard.left_shift.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS)
    {this->keyboard.left_control.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_LEFT_ALT) == GLFW_PRESS)
    {this->keyboard.left_alt.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_LEFT_SUPER) == GLFW_PRESS)
    {this->keyboard.left_super.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS)
    {this->keyboard.right_shift.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS)
    {this->keyboard.right_control.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_RIGHT_ALT) == GLFW_PRESS)
    {this->keyboard.right_alt.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_RIGHT_SUPER) == GLFW_PRESS)
    {this->keyboard.right_super.pressed = DE_TRUE;}

  if(glfwGetKey(this->pwindow, GLFW_KEY_MENU) == GLFW_PRESS)
    {this->keyboard.menu.pressed = DE_TRUE;}

  // key release

  if(glfwGetKey(this->pwindow, GLFW_KEY_UNKNOWN) == GLFW_RELEASE && this->keyboard.unknown.pressed)
  {
    this->keyboard.unknown.released = DE_TRUE;
    this->keyboard.unknown.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_SPACE) == GLFW_RELEASE && this->keyboard.space.pressed)
  {
    this->keyboard.space.released = DE_TRUE;
    this->keyboard.space.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_APOSTROPHE) == GLFW_RELEASE && this->keyboard.apostrophe.pressed)
  {
    this->keyboard.apostrophe.released = DE_TRUE;
    this->keyboard.apostrophe.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_COMMA) == GLFW_RELEASE && this->keyboard.comma.pressed)
  {
    this->keyboard.comma.released = DE_TRUE;
    this->keyboard.comma.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_MINUS) == GLFW_RELEASE && this->keyboard.minus.pressed)
  {
    this->keyboard.minus.released = DE_TRUE;
    this->keyboard.minus.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_PERIOD) == GLFW_RELEASE && this->keyboard.period.pressed)
  {
    this->keyboard.period.released = DE_TRUE;
    this->keyboard.period.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_SLASH) == GLFW_RELEASE && this->keyboard.slash.pressed)
  {
    this->keyboard.slash.released = DE_TRUE;
    this->keyboard.slash.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_0) == GLFW_RELEASE && this->keyboard.k0.pressed)
  {
    this->keyboard.k0.released = DE_TRUE;
    this->keyboard.k0.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_1) == GLFW_RELEASE && this->keyboard.k1.pressed)
  {
    this->keyboard.k1.released = DE_TRUE;
    this->keyboard.k1.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_2) == GLFW_RELEASE && this->keyboard.k2.pressed)
  {
    this->keyboard.k2.released = DE_TRUE;
    this->keyboard.k2.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_3) == GLFW_RELEASE && this->keyboard.k3.pressed)
  {
    this->keyboard.k3.released = DE_TRUE;
    this->keyboard.k3.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_4) == GLFW_RELEASE && this->keyboard.k4.pressed)
  {
    this->keyboard.k4.released = DE_TRUE;
    this->keyboard.k4.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_5) == GLFW_RELEASE && this->keyboard.k5.pressed)
  {
    this->keyboard.k5.released = DE_TRUE;
    this->keyboard.k5.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_6) == GLFW_RELEASE && this->keyboard.k6.pressed)
  {
    this->keyboard.k6.released = DE_TRUE;
    this->keyboard.k6.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_7) == GLFW_RELEASE && this->keyboard.k7.pressed)
  {
    this->keyboard.k7.released = DE_TRUE;
    this->keyboard.k7.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_8) == GLFW_RELEASE && this->keyboard.k8.pressed)
  {
    this->keyboard.k8.released = DE_TRUE;
    this->keyboard.k8.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_9) == GLFW_RELEASE && this->keyboard.k9.pressed)
  {
    this->keyboard.k9.released = DE_TRUE;
    this->keyboard.k9.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_SEMICOLON) == GLFW_RELEASE && this->keyboard.semicolon.pressed)
  {
    this->keyboard.semicolon.released = DE_TRUE;
    this->keyboard.semicolon.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_EQUAL) == GLFW_RELEASE && this->keyboard.equal.pressed)
  {
    this->keyboard.equal.released = DE_TRUE;
    this->keyboard.equal.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_A) == GLFW_RELEASE && this->keyboard.ka.pressed)
  {
    this->keyboard.ka.released = DE_TRUE;
    this->keyboard.ka.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_B) == GLFW_RELEASE && this->keyboard.kb.pressed)
  {
    this->keyboard.kb.released = DE_TRUE;
    this->keyboard.kb.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_C) == GLFW_RELEASE && this->keyboard.kc.pressed)
  {
    this->keyboard.kc.released = DE_TRUE;
    this->keyboard.kc.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_D) == GLFW_RELEASE && this->keyboard.kd.pressed)
  {
    this->keyboard.kd.released = DE_TRUE;
    this->keyboard.kd.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_E) == GLFW_RELEASE && this->keyboard.ke.pressed)
  {
    this->keyboard.ke.released = DE_TRUE;
    this->keyboard.ke.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F) == GLFW_RELEASE && this->keyboard.kf.pressed)
  {
    this->keyboard.kf.released = DE_TRUE;
    this->keyboard.kf.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_G) == GLFW_RELEASE && this->keyboard.kg.pressed)
  {
    this->keyboard.kg.released = DE_TRUE;
    this->keyboard.kg.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_H) == GLFW_RELEASE && this->keyboard.kh.pressed)
  {
    this->keyboard.kh.released = DE_TRUE;
    this->keyboard.kh.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_I) == GLFW_RELEASE && this->keyboard.ki.pressed)
  {
    this->keyboard.ki.released = DE_TRUE;
    this->keyboard.ki.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_J) == GLFW_RELEASE && this->keyboard.kj.pressed)
  {
    this->keyboard.kj.released = DE_TRUE;
    this->keyboard.kj.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_K) == GLFW_RELEASE && this->keyboard.kk.pressed)
  {
    this->keyboard.kk.released = DE_TRUE;
    this->keyboard.kk.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_L) == GLFW_RELEASE && this->keyboard.kl.pressed)
  {
    this->keyboard.kl.released = DE_TRUE;
    this->keyboard.kl.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_M) == GLFW_RELEASE && this->keyboard.km.pressed)
  {
    this->keyboard.km.released = DE_TRUE;
    this->keyboard.km.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_N) == GLFW_RELEASE && this->keyboard.kn.pressed)
  {
    this->keyboard.kn.released = DE_TRUE;
    this->keyboard.kn.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_O) == GLFW_RELEASE && this->keyboard.ko.pressed)
  {
    this->keyboard.ko.released = DE_TRUE;
    this->keyboard.ko.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_P) == GLFW_RELEASE && this->keyboard.kp.pressed)
  {
    this->keyboard.kp.released = DE_TRUE;
    this->keyboard.kp.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_Q) == GLFW_RELEASE && this->keyboard.kq.pressed)
  {
    this->keyboard.kq.released = DE_TRUE;
    this->keyboard.kq.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_R) == GLFW_RELEASE && this->keyboard.kr.pressed)
  {
    this->keyboard.kr.released = DE_TRUE;
    this->keyboard.kr.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_S) == GLFW_RELEASE && this->keyboard.ks.pressed)
  {
    this->keyboard.ks.released = DE_TRUE;
    this->keyboard.ks.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_T) == GLFW_RELEASE && this->keyboard.kt.pressed)
  {
    this->keyboard.kt.released = DE_TRUE;
    this->keyboard.kt.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_U) == GLFW_RELEASE && this->keyboard.ku.pressed)
  {
    this->keyboard.ku.released = DE_TRUE;
    this->keyboard.ku.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_V) == GLFW_RELEASE && this->keyboard.kv.pressed)
  {
    this->keyboard.kv.released = DE_TRUE;
    this->keyboard.kv.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_W) == GLFW_RELEASE && this->keyboard.kw.pressed)
  {
    this->keyboard.kw.released = DE_TRUE;
    this->keyboard.kw.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_X) == GLFW_RELEASE && this->keyboard.kx.pressed)
  {
    this->keyboard.kx.released = DE_TRUE;
    this->keyboard.kx.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_Y) == GLFW_RELEASE && this->keyboard.ky.pressed)
  {
    this->keyboard.ky.released = DE_TRUE;
    this->keyboard.ky.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_Z) == GLFW_RELEASE && this->keyboard.kz.pressed)
  {
    this->keyboard.kz.released = DE_TRUE;
    this->keyboard.kz.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_LEFT_BRACKET) == GLFW_RELEASE && this->keyboard.left_bracket.pressed)
  {
    this->keyboard.left_bracket.released = DE_TRUE;
    this->keyboard.left_bracket.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_BACKSLASH) == GLFW_RELEASE && this->keyboard.backslash.pressed)
  {
    this->keyboard.backslash.released = DE_TRUE;
    this->keyboard.backslash.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_RIGHT_BRACKET) == GLFW_RELEASE && this->keyboard.right_bracket.pressed)
  {
    this->keyboard.right_bracket.released = DE_TRUE;
    this->keyboard.right_bracket.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_GRAVE_ACCENT) == GLFW_RELEASE && this->keyboard.grave_accent.pressed)
  {
    this->keyboard.grave_accent.released = DE_TRUE;
    this->keyboard.grave_accent.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_WORLD_1) == GLFW_RELEASE && this->keyboard.world_1.pressed)
  {
    this->keyboard.world_1.released = DE_TRUE;
    this->keyboard.world_1.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_WORLD_2) == GLFW_RELEASE && this->keyboard.world_2.pressed)
  {
    this->keyboard.world_2.released = DE_TRUE;
    this->keyboard.world_2.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_ESCAPE) == GLFW_RELEASE && this->keyboard.escape.pressed)
  {
    this->keyboard.escape.released = DE_TRUE;
    this->keyboard.escape.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_ENTER) == GLFW_RELEASE && this->keyboard.enter.pressed)
  {
    this->keyboard.enter.released = DE_TRUE;
    this->keyboard.enter.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_TAB) == GLFW_RELEASE && this->keyboard.tab.pressed)
  {
    this->keyboard.tab.released = DE_TRUE;
    this->keyboard.tab.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_BACKSPACE) == GLFW_RELEASE && this->keyboard.backspace.pressed)
  {
    this->keyboard.backspace.released = DE_TRUE;
    this->keyboard.backspace.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_INSERT) == GLFW_RELEASE && this->keyboard.insert.pressed)
  {
    this->keyboard.insert.released = DE_TRUE;
    this->keyboard.insert.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_DELETE) == GLFW_RELEASE && this->keyboard.del.pressed)
  {
    this->keyboard.del.released = DE_TRUE;
    this->keyboard.del.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_RIGHT) == GLFW_RELEASE && this->keyboard.right.pressed)
  {
    this->keyboard.right.released = DE_TRUE;
    this->keyboard.right.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_LEFT) == GLFW_RELEASE && this->keyboard.left.pressed)
  {
    this->keyboard.left.released = DE_TRUE;
    this->keyboard.left.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_DOWN) == GLFW_RELEASE && this->keyboard.down.pressed)
  {
    this->keyboard.down.released = DE_TRUE;
    this->keyboard.down.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_UP) == GLFW_RELEASE && this->keyboard.up.pressed)
  {
    this->keyboard.up.released = DE_TRUE;
    this->keyboard.up.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_PAGE_UP) == GLFW_RELEASE && this->keyboard.page_up.pressed)
  {
    this->keyboard.page_up.released = DE_TRUE;
    this->keyboard.page_up.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_PAGE_DOWN) == GLFW_RELEASE && this->keyboard.page_down.pressed)
  {
    this->keyboard.page_down.released = DE_TRUE;
    this->keyboard.page_down.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_HOME) == GLFW_RELEASE && this->keyboard.home.pressed)
  {
    this->keyboard.home.released = DE_TRUE;
    this->keyboard.home.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_END) == GLFW_RELEASE && this->keyboard.end.pressed)
  {
    this->keyboard.end.released = DE_TRUE;
    this->keyboard.end.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_CAPS_LOCK) == GLFW_RELEASE && this->keyboard.caps_lock.pressed)
  {
    this->keyboard.caps_lock.released = DE_TRUE;
    this->keyboard.caps_lock.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_SCROLL_LOCK) == GLFW_RELEASE && this->keyboard.scroll_lock.pressed)
  {
    this->keyboard.scroll_lock.released = DE_TRUE;
    this->keyboard.scroll_lock.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_NUM_LOCK) == GLFW_RELEASE && this->keyboard.num_lock.pressed)
  {
    this->keyboard.num_lock.released = DE_TRUE;
    this->keyboard.num_lock.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_PRINT_SCREEN) == GLFW_RELEASE && this->keyboard.print_screen.pressed)
  {
    this->keyboard.print_screen.released = DE_TRUE;
    this->keyboard.print_screen.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_PAUSE) == GLFW_RELEASE && this->keyboard.pause.pressed)
  {
    this->keyboard.pause.released = DE_TRUE;
    this->keyboard.pause.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F1) == GLFW_RELEASE && this->keyboard.f1.pressed)
  {
    this->keyboard.f1.released = DE_TRUE;
    this->keyboard.f1.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F2) == GLFW_RELEASE && this->keyboard.f2.pressed)
  {
    this->keyboard.f2.released = DE_TRUE;
    this->keyboard.f2.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F3) == GLFW_RELEASE && this->keyboard.f3.pressed)
  {
    this->keyboard.f3.released = DE_TRUE;
    this->keyboard.f3.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F4) == GLFW_RELEASE && this->keyboard.f4.pressed)
  {
    this->keyboard.f4.released = DE_TRUE;
    this->keyboard.f4.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F5) == GLFW_RELEASE && this->keyboard.f5.pressed)
  {
    this->keyboard.f5.released = DE_TRUE;
    this->keyboard.f5.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F6) == GLFW_RELEASE && this->keyboard.f6.pressed)
  {
    this->keyboard.f6.released = DE_TRUE;
    this->keyboard.f6.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F7) == GLFW_RELEASE && this->keyboard.f7.pressed)
  {
    this->keyboard.f7.released = DE_TRUE;
    this->keyboard.f7.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F8) == GLFW_RELEASE && this->keyboard.f8.pressed)
  {
    this->keyboard.f8.released = DE_TRUE;
    this->keyboard.f8.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F9) == GLFW_RELEASE && this->keyboard.f9.pressed)
  {
    this->keyboard.f9.released = DE_TRUE;
    this->keyboard.f9.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F10) == GLFW_RELEASE && this->keyboard.f10.pressed)
  {
    this->keyboard.f10.released = DE_TRUE;
    this->keyboard.f10.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F11) == GLFW_RELEASE && this->keyboard.f11.pressed)
  {
    this->keyboard.f11.released = DE_TRUE;
    this->keyboard.f11.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F12) == GLFW_RELEASE && this->keyboard.f12.pressed)
  {
    this->keyboard.f12.released = DE_TRUE;
    this->keyboard.f12.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F13) == GLFW_RELEASE && this->keyboard.f13.pressed)
  {
    this->keyboard.f13.released = DE_TRUE;
    this->keyboard.f13.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F14) == GLFW_RELEASE && this->keyboard.f14.pressed)
  {
    this->keyboard.f14.released = DE_TRUE;
    this->keyboard.f14.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F15) == GLFW_RELEASE && this->keyboard.f15.pressed)
  {
    this->keyboard.f15.released = DE_TRUE;
    this->keyboard.f15.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F16) == GLFW_RELEASE && this->keyboard.f16.pressed)
  {
    this->keyboard.f16.released = DE_TRUE;
    this->keyboard.f16.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F17) == GLFW_RELEASE && this->keyboard.f17.pressed)
  {
    this->keyboard.f17.released = DE_TRUE;
    this->keyboard.f17.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F18) == GLFW_RELEASE && this->keyboard.f18.pressed)
  {
    this->keyboard.f18.released = DE_TRUE;
    this->keyboard.f18.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F19) == GLFW_RELEASE && this->keyboard.f19.pressed)
  {
    this->keyboard.f19.released = DE_TRUE;
    this->keyboard.f19.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F20) == GLFW_RELEASE && this->keyboard.f20.pressed)
  {
    this->keyboard.f20.released = DE_TRUE;
    this->keyboard.f20.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F21) == GLFW_RELEASE && this->keyboard.f21.pressed)
  {
    this->keyboard.f21.released = DE_TRUE;
    this->keyboard.f21.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F22) == GLFW_RELEASE && this->keyboard.f22.pressed)
  {
    this->keyboard.f22.released = DE_TRUE;
    this->keyboard.f22.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F23) == GLFW_RELEASE && this->keyboard.f23.pressed)
  {
    this->keyboard.f23.released = DE_TRUE;
    this->keyboard.f23.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F24) == GLFW_RELEASE && this->keyboard.f24.pressed)
  {
    this->keyboard.f24.released = DE_TRUE;
    this->keyboard.f24.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_F25) == GLFW_RELEASE && this->keyboard.f25.pressed)
  {
    this->keyboard.f25.released = DE_TRUE;
    this->keyboard.f25.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_0) == GLFW_RELEASE && this->keyboard.kp_0.pressed)
  {
    this->keyboard.kp_0.released = DE_TRUE;
    this->keyboard.kp_0.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_1) == GLFW_RELEASE && this->keyboard.kp_1.pressed)
  {
    this->keyboard.kp_1.released = DE_TRUE;
    this->keyboard.kp_1.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_2) == GLFW_RELEASE && this->keyboard.kp_2.pressed)
  {
    this->keyboard.kp_2.released = DE_TRUE;
    this->keyboard.kp_2.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_3) == GLFW_RELEASE && this->keyboard.kp_3.pressed)
  {
    this->keyboard.kp_3.released = DE_TRUE;
    this->keyboard.kp_3.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_4) == GLFW_RELEASE && this->keyboard.kp_4.pressed)
  {
    this->keyboard.kp_4.released = DE_TRUE;
    this->keyboard.kp_4.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_5) == GLFW_RELEASE && this->keyboard.kp_5.pressed)
  {
    this->keyboard.kp_5.released = DE_TRUE;
    this->keyboard.kp_5.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_6) == GLFW_RELEASE && this->keyboard.kp_6.pressed)
  {
    this->keyboard.kp_6.released = DE_TRUE;
    this->keyboard.kp_6.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_7) == GLFW_RELEASE && this->keyboard.kp_7.pressed)
  {
    this->keyboard.kp_7.released = DE_TRUE;
    this->keyboard.kp_7.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_8) == GLFW_RELEASE && this->keyboard.kp_8.pressed)
  {
    this->keyboard.kp_8.released = DE_TRUE;
    this->keyboard.kp_8.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_9) == GLFW_RELEASE && this->keyboard.kp_9.pressed)
  {
    this->keyboard.kp_9.released = DE_TRUE;
    this->keyboard.kp_9.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_DECIMAL) == GLFW_RELEASE && this->keyboard.kp_decimal.pressed)
  {
    this->keyboard.kp_decimal.released = DE_TRUE;
    this->keyboard.kp_decimal.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_DIVIDE) == GLFW_RELEASE && this->keyboard.kp_divide.pressed)
  {
    this->keyboard.kp_divide.released = DE_TRUE;
    this->keyboard.kp_divide.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_MULTIPLY) == GLFW_RELEASE && this->keyboard.kp_multiply.pressed)
  {
    this->keyboard.kp_multiply.released = DE_TRUE;
    this->keyboard.kp_multiply.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_SUBTRACT) == GLFW_RELEASE && this->keyboard.kp_subtract.pressed)
  {
    this->keyboard.kp_subtract.released = DE_TRUE;
    this->keyboard.kp_subtract.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_ADD) == GLFW_RELEASE && this->keyboard.kp_add.pressed)
  {
    this->keyboard.kp_add.released = DE_TRUE;
    this->keyboard.kp_add.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_ENTER) == GLFW_RELEASE && this->keyboard.kp_enter.pressed)
  {
    this->keyboard.kp_enter.released = DE_TRUE;
    this->keyboard.kp_enter.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_KP_EQUAL) == GLFW_RELEASE && this->keyboard.kp_equal.pressed)
  {
    this->keyboard.kp_equal.released = DE_TRUE;
    this->keyboard.kp_equal.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_LEFT_SHIFT) == GLFW_RELEASE && this->keyboard.left_shift.pressed)
  {
    this->keyboard.left_shift.released = DE_TRUE;
    this->keyboard.left_shift.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_LEFT_CONTROL) == GLFW_RELEASE && this->keyboard.left_control.pressed)
  {
    this->keyboard.left_control.released = DE_TRUE;
    this->keyboard.left_control.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_LEFT_ALT) == GLFW_RELEASE && this->keyboard.left_alt.pressed)
  {
    this->keyboard.left_alt.released = DE_TRUE;
    this->keyboard.left_alt.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_LEFT_SUPER) == GLFW_RELEASE && this->keyboard.left_super.pressed)
  {
    this->keyboard.left_super.released = DE_TRUE;
    this->keyboard.left_super.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_RIGHT_SHIFT) == GLFW_RELEASE && this->keyboard.right_shift.pressed)
  {
    this->keyboard.right_shift.released = DE_TRUE;
    this->keyboard.right_shift.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_RIGHT_CONTROL) == GLFW_RELEASE && this->keyboard.right_control.pressed)
  {
    this->keyboard.right_control.released = DE_TRUE;
    this->keyboard.right_control.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_RIGHT_ALT) == GLFW_RELEASE && this->keyboard.right_alt.pressed)
  {
    this->keyboard.right_alt.released = DE_TRUE;
    this->keyboard.right_alt.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_RIGHT_SUPER) == GLFW_RELEASE && this->keyboard.right_super.pressed)
  {
    this->keyboard.right_super.released = DE_TRUE;
    this->keyboard.right_super.pressed = DE_FALSE;
  }

  if(glfwGetKey(this->pwindow, GLFW_KEY_MENU) == GLFW_RELEASE && this->keyboard.menu.pressed)
  {
    this->keyboard.menu.released = DE_TRUE;
    this->keyboard.menu.pressed = DE_FALSE;
  }
}

void cDEcore::DEcore_clear_keyboard(bool expression)
{
  if(expression == GLFW_PRESS || expression == (GLFW_PRESS || GLFW_RELEASE))
  {
    this->keyboard.unknown.pressed = DE_FALSE;
    this->keyboard.space.pressed = DE_FALSE;
    this->keyboard.apostrophe.pressed = DE_FALSE;
    this->keyboard.comma.pressed = DE_FALSE;
    this->keyboard.minus.pressed = DE_FALSE;
    this->keyboard.period.pressed = DE_FALSE;
    this->keyboard.slash.pressed = DE_FALSE;
    this->keyboard.k0.pressed = DE_FALSE;
    this->keyboard.k1.pressed = DE_FALSE;
    this->keyboard.k2.pressed = DE_FALSE;
    this->keyboard.k3.pressed = DE_FALSE;
    this->keyboard.k4.pressed = DE_FALSE;
    this->keyboard.k5.pressed = DE_FALSE;
    this->keyboard.k6.pressed = DE_FALSE;
    this->keyboard.k7.pressed = DE_FALSE;
    this->keyboard.k8.pressed = DE_FALSE;
    this->keyboard.k9.pressed = DE_FALSE;
    this->keyboard.semicolon.pressed = DE_FALSE;
    this->keyboard.equal.pressed = DE_FALSE;
    this->keyboard.ka.pressed = DE_FALSE;
    this->keyboard.kb.pressed = DE_FALSE;
    this->keyboard.kc.pressed = DE_FALSE;
    this->keyboard.kd.pressed = DE_FALSE;
    this->keyboard.ke.pressed = DE_FALSE;
    this->keyboard.kf.pressed = DE_FALSE;
    this->keyboard.kg.pressed = DE_FALSE;
    this->keyboard.kh.pressed = DE_FALSE;
    this->keyboard.ki.pressed = DE_FALSE;
    this->keyboard.kj.pressed = DE_FALSE;
    this->keyboard.kk.pressed = DE_FALSE;
    this->keyboard.kl.pressed = DE_FALSE;
    this->keyboard.km.pressed = DE_FALSE;
    this->keyboard.kn.pressed = DE_FALSE;
    this->keyboard.ko.pressed = DE_FALSE;
    this->keyboard.kp.pressed = DE_FALSE;
    this->keyboard.kq.pressed = DE_FALSE;
    this->keyboard.kr.pressed = DE_FALSE;
    this->keyboard.ks.pressed = DE_FALSE;
    this->keyboard.kt.pressed = DE_FALSE;
    this->keyboard.ku.pressed = DE_FALSE;
    this->keyboard.kv.pressed = DE_FALSE;
    this->keyboard.kw.pressed = DE_FALSE;
    this->keyboard.kx.pressed = DE_FALSE;
    this->keyboard.ky.pressed = DE_FALSE;
    this->keyboard.kz.pressed = DE_FALSE;
    this->keyboard.left_bracket.pressed = DE_FALSE;
    this->keyboard.backslash.pressed = DE_FALSE;
    this->keyboard.right_bracket.pressed = DE_FALSE;
    this->keyboard.grave_accent.pressed = DE_FALSE;
    this->keyboard.world_1.pressed = DE_FALSE;
    this->keyboard.world_2.pressed = DE_FALSE;
    this->keyboard.escape.pressed = DE_FALSE;
    this->keyboard.enter.pressed = DE_FALSE;
    this->keyboard.tab.pressed = DE_FALSE;
    this->keyboard.backspace.pressed = DE_FALSE;
    this->keyboard.insert.pressed = DE_FALSE;
    this->keyboard.del.pressed = DE_FALSE;
    this->keyboard.right.pressed = DE_FALSE;
    this->keyboard.left.pressed = DE_FALSE;
    this->keyboard.down.pressed = DE_FALSE;
    this->keyboard.up.pressed = DE_FALSE;
    this->keyboard.page_up.pressed = DE_FALSE;
    this->keyboard.page_down.pressed = DE_FALSE;
    this->keyboard.home.pressed = DE_FALSE;
    this->keyboard.end.pressed = DE_FALSE;
    this->keyboard.caps_lock.pressed = DE_FALSE;
    this->keyboard.scroll_lock.pressed = DE_FALSE;
    this->keyboard.num_lock.pressed = DE_FALSE;
    this->keyboard.print_screen.pressed = DE_FALSE;
    this->keyboard.pause.pressed = DE_FALSE;
    this->keyboard.f1.pressed = DE_FALSE;
    this->keyboard.f2.pressed = DE_FALSE;
    this->keyboard.f3.pressed = DE_FALSE;
    this->keyboard.f4.pressed = DE_FALSE;
    this->keyboard.f5.pressed = DE_FALSE;
    this->keyboard.f6.pressed = DE_FALSE;
    this->keyboard.f7.pressed = DE_FALSE;
    this->keyboard.f8.pressed = DE_FALSE;
    this->keyboard.f9.pressed = DE_FALSE;
    this->keyboard.f10.pressed = DE_FALSE;
    this->keyboard.f11.pressed = DE_FALSE;
    this->keyboard.f12.pressed = DE_FALSE;
    this->keyboard.f13.pressed = DE_FALSE;
    this->keyboard.f14.pressed = DE_FALSE;
    this->keyboard.f15.pressed = DE_FALSE;
    this->keyboard.f16.pressed = DE_FALSE;
    this->keyboard.f17.pressed = DE_FALSE;
    this->keyboard.f18.pressed = DE_FALSE;
    this->keyboard.f19.pressed = DE_FALSE;
    this->keyboard.f20.pressed = DE_FALSE;
    this->keyboard.f21.pressed = DE_FALSE;
    this->keyboard.f22.pressed = DE_FALSE;
    this->keyboard.f23.pressed = DE_FALSE;
    this->keyboard.f24.pressed = DE_FALSE;
    this->keyboard.f25.pressed = DE_FALSE;
    this->keyboard.kp_0.pressed = DE_FALSE;
    this->keyboard.kp_1.pressed = DE_FALSE;
    this->keyboard.kp_2.pressed = DE_FALSE;
    this->keyboard.kp_3.pressed = DE_FALSE;
    this->keyboard.kp_4.pressed = DE_FALSE;
    this->keyboard.kp_5.pressed = DE_FALSE;
    this->keyboard.kp_6.pressed = DE_FALSE;
    this->keyboard.kp_7.pressed = DE_FALSE;
    this->keyboard.kp_8.pressed = DE_FALSE;
    this->keyboard.kp_9.pressed = DE_FALSE;
    this->keyboard.kp_decimal.pressed = DE_FALSE;
    this->keyboard.kp_divide.pressed = DE_FALSE;
    this->keyboard.kp_multiply.pressed = DE_FALSE;
    this->keyboard.kp_subtract.pressed = DE_FALSE;
    this->keyboard.kp_add.pressed = DE_FALSE;
    this->keyboard.kp_enter.pressed = DE_FALSE;
    this->keyboard.kp_equal.pressed = DE_FALSE;
    this->keyboard.left_shift.pressed = DE_FALSE;
    this->keyboard.left_control.pressed = DE_FALSE;
    this->keyboard.left_alt.pressed = DE_FALSE;
    this->keyboard.left_super.pressed = DE_FALSE;
    this->keyboard.right_shift.pressed = DE_FALSE;
    this->keyboard.right_control.pressed = DE_FALSE;
    this->keyboard.right_alt.pressed = DE_FALSE;
    this->keyboard.right_super.pressed = DE_FALSE;
    this->keyboard.menu.pressed = DE_FALSE;
  }

  if(expression == GLFW_RELEASE || expression == (GLFW_PRESS || GLFW_RELEASE))
  {
    this->keyboard.unknown.released = DE_FALSE;
    this->keyboard.space.released = DE_FALSE;
    this->keyboard.apostrophe.released = DE_FALSE;
    this->keyboard.comma.released = DE_FALSE;
    this->keyboard.minus.released = DE_FALSE;
    this->keyboard.period.released = DE_FALSE;
    this->keyboard.slash.released = DE_FALSE;
    this->keyboard.k0.released = DE_FALSE;
    this->keyboard.k1.released = DE_FALSE;
    this->keyboard.k2.released = DE_FALSE;
    this->keyboard.k3.released = DE_FALSE;
    this->keyboard.k4.released = DE_FALSE;
    this->keyboard.k5.released = DE_FALSE;
    this->keyboard.k6.released = DE_FALSE;
    this->keyboard.k7.released = DE_FALSE;
    this->keyboard.k8.released = DE_FALSE;
    this->keyboard.k9.released = DE_FALSE;
    this->keyboard.semicolon.released = DE_FALSE;
    this->keyboard.equal.released = DE_FALSE;
    this->keyboard.ka.released = DE_FALSE;
    this->keyboard.kb.released = DE_FALSE;
    this->keyboard.kc.released = DE_FALSE;
    this->keyboard.kd.released = DE_FALSE;
    this->keyboard.ke.released = DE_FALSE;
    this->keyboard.kf.released = DE_FALSE;
    this->keyboard.kg.released = DE_FALSE;
    this->keyboard.kh.released = DE_FALSE;
    this->keyboard.ki.released = DE_FALSE;
    this->keyboard.kj.released = DE_FALSE;
    this->keyboard.kk.released = DE_FALSE;
    this->keyboard.kl.released = DE_FALSE;
    this->keyboard.km.released = DE_FALSE;
    this->keyboard.kn.released = DE_FALSE;
    this->keyboard.ko.released = DE_FALSE;
    this->keyboard.kp.released = DE_FALSE;
    this->keyboard.kq.released = DE_FALSE;
    this->keyboard.kr.released = DE_FALSE;
    this->keyboard.ks.released = DE_FALSE;
    this->keyboard.kt.released = DE_FALSE;
    this->keyboard.ku.released = DE_FALSE;
    this->keyboard.kv.released = DE_FALSE;
    this->keyboard.kw.released = DE_FALSE;
    this->keyboard.kx.released = DE_FALSE;
    this->keyboard.ky.released = DE_FALSE;
    this->keyboard.kz.released = DE_FALSE;
    this->keyboard.left_bracket.released = DE_FALSE;
    this->keyboard.backslash.released = DE_FALSE;
    this->keyboard.right_bracket.released = DE_FALSE;
    this->keyboard.grave_accent.released = DE_FALSE;
    this->keyboard.world_1.released = DE_FALSE;
    this->keyboard.world_2.released = DE_FALSE;
    this->keyboard.escape.released = DE_FALSE;
    this->keyboard.enter.released = DE_FALSE;
    this->keyboard.tab.released = DE_FALSE;
    this->keyboard.backspace.released = DE_FALSE;
    this->keyboard.insert.released = DE_FALSE;
    this->keyboard.del.released = DE_FALSE;
    this->keyboard.right.released = DE_FALSE;
    this->keyboard.left.released = DE_FALSE;
    this->keyboard.down.released = DE_FALSE;
    this->keyboard.up.released = DE_FALSE;
    this->keyboard.page_up.released = DE_FALSE;
    this->keyboard.page_down.released = DE_FALSE;
    this->keyboard.home.released = DE_FALSE;
    this->keyboard.end.released = DE_FALSE;
    this->keyboard.caps_lock.released = DE_FALSE;
    this->keyboard.scroll_lock.released = DE_FALSE;
    this->keyboard.num_lock.released = DE_FALSE;
    this->keyboard.print_screen.released = DE_FALSE;
    this->keyboard.pause.released = DE_FALSE;
    this->keyboard.f1.released = DE_FALSE;
    this->keyboard.f2.released = DE_FALSE;
    this->keyboard.f3.released = DE_FALSE;
    this->keyboard.f4.released = DE_FALSE;
    this->keyboard.f5.released = DE_FALSE;
    this->keyboard.f6.released = DE_FALSE;
    this->keyboard.f7.released = DE_FALSE;
    this->keyboard.f8.released = DE_FALSE;
    this->keyboard.f9.released = DE_FALSE;
    this->keyboard.f10.released = DE_FALSE;
    this->keyboard.f11.released = DE_FALSE;
    this->keyboard.f12.released = DE_FALSE;
    this->keyboard.f13.released = DE_FALSE;
    this->keyboard.f14.released = DE_FALSE;
    this->keyboard.f15.released = DE_FALSE;
    this->keyboard.f16.released = DE_FALSE;
    this->keyboard.f17.released = DE_FALSE;
    this->keyboard.f18.released = DE_FALSE;
    this->keyboard.f19.released = DE_FALSE;
    this->keyboard.f20.released = DE_FALSE;
    this->keyboard.f21.released = DE_FALSE;
    this->keyboard.f22.released = DE_FALSE;
    this->keyboard.f23.released = DE_FALSE;
    this->keyboard.f24.released = DE_FALSE;
    this->keyboard.f25.released = DE_FALSE;
    this->keyboard.kp_0.released = DE_FALSE;
    this->keyboard.kp_1.released = DE_FALSE;
    this->keyboard.kp_2.released = DE_FALSE;
    this->keyboard.kp_3.released = DE_FALSE;
    this->keyboard.kp_4.released = DE_FALSE;
    this->keyboard.kp_5.released = DE_FALSE;
    this->keyboard.kp_6.released = DE_FALSE;
    this->keyboard.kp_7.released = DE_FALSE;
    this->keyboard.kp_8.released = DE_FALSE;
    this->keyboard.kp_9.released = DE_FALSE;
    this->keyboard.kp_decimal.released = DE_FALSE;
    this->keyboard.kp_divide.released = DE_FALSE;
    this->keyboard.kp_multiply.released = DE_FALSE;
    this->keyboard.kp_subtract.released = DE_FALSE;
    this->keyboard.kp_add.released = DE_FALSE;
    this->keyboard.kp_enter.released = DE_FALSE;
    this->keyboard.kp_equal.released = DE_FALSE;
    this->keyboard.left_shift.released = DE_FALSE;
    this->keyboard.left_control.released = DE_FALSE;
    this->keyboard.left_alt.released = DE_FALSE;
    this->keyboard.left_super.released = DE_FALSE;
    this->keyboard.right_shift.released = DE_FALSE;
    this->keyboard.right_control.released = DE_FALSE;
    this->keyboard.right_alt.released = DE_FALSE;
    this->keyboard.right_super.released = DE_FALSE;
    this->keyboard.menu.released = DE_FALSE;
  }
}

bool cDEcore::DEcore_suitable_device(VkPhysicalDevice device)
{
  bool expression = this->DEcore_query_queue_family(device) && this->DEcore_required_extensions(device) && !this->DEcore_query_swapchain(device);

  if(!expression)
    {this->DEcore_clear_suitable_device();}

  return expression;
}

int cDEcore::DEcore_init_vk_instance(const char * papp_name)
{
  int exit_code = DE_NO_ERROR;
  char ** ppextensions = NULL;

  if(this->enable_validation_layers && !(this->DEcore_check_validation_layer_support()))
  {
    exit_code = DE_VALIDATION_LAYER;

    #ifdef DE_DEBUG
      cout << "no validation layer support!" << endl;
    #endif
  }

  if(!exit_code)
  {
    // instance

    this->vk_app_info = {};
    this->vk_app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    this->vk_app_info.pApplicationName = papp_name;
    this->vk_app_info.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
    this->vk_app_info.pEngineName = "Dycon Engine";
    this->vk_app_info.engineVersion = VK_MAKE_VERSION(1, 0, 0);
    this->vk_app_info.apiVersion = VK_API_VERSION_1_0;
    this->vk_app_info.pNext = NULL;

    this->vk_instance_info = {};
    this->vk_instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    this->vk_instance_info.pApplicationInfo = &(this->vk_app_info);
    ppextensions = this->DEcore_get_required_extensions();

    if(ppextensions == NULL)
    {
      exit_code = DE_NO_EXTENSIONS;

      #ifdef DE_DEBUG
        cout << "no extensions loaded for instance!" << endl;
      #endif
    }

    this->vk_instance_info.enabledExtensionCount = this->glfw_num_extensions;
    this->vk_instance_info.ppEnabledExtensionNames = ppextensions;

    if(this->enable_validation_layers)
    {
      this->vk_instance_info.enabledLayerCount = NUM_VALIDATION_LAYERS;
      this->vk_instance_info.ppEnabledLayerNames = this->ppvalidation_layers;
    }
    else
      {this->vk_instance_info.enabledLayerCount = 0;}

    this->vk_instance_info.flags = 0;
    this->vk_instance_info.pNext = NULL;

    if(!exit_code)
    {
      if(vkCreateInstance(&(this->vk_instance_info), nullptr, &(this->vk_instance)) != VK_SUCCESS)
      {
        exit_code = DE_VK_INSTANCE;

        #ifdef DE_DEBUG
          cout << "vkCreateInstance() failed!" << endl;
        #endif
      }
    }
  }

  return exit_code;
}

int cDEcore::DEcore_init_physical_device()
{
  int exit_code = DE_NO_ERROR;
  unsigned int num_devices = 0;

  if(!exit_code)
  {
    // get number of devices

    vkEnumeratePhysicalDevices(this->vk_instance, &num_devices, nullptr);

    if(num_devices == 0)
    {
      exit_code = DE_NO_DEVICE;

      #ifdef DE_DEBUG
        cout << "no supported graphics device found!" << endl;
      #endif
    }
    else
    {
      // choose suitable device

      this->vk_all_physical_devices = new VkPhysicalDevice[num_devices];
      vkEnumeratePhysicalDevices(this->vk_instance, &num_devices, this->vk_all_physical_devices);

      for(unsigned short int i = 0 ; i < num_devices ; i++)
      {
        if(this->DEcore_suitable_device(this->vk_all_physical_devices[i]))
        {
          this->vk_physical_device = this->vk_all_physical_devices[i];
          break;
        }
      }

      if(this->vk_physical_device == NULL)
      {
        exit_code = DE_SUITABLE_DEVICE;

        #ifdef DE_DEBUG
          cout << "device found, but not suitable!" << endl;
        #endif
      }
    }
  }

  return exit_code;
}

int cDEcore::DEcore_init_logical_device()
{
  int exit_code = DE_NO_ERROR;
  float priority = 1.0f;
  uint32_t num_queues = NUM_QUEUES;

  this->graphics_queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
  this->graphics_queue_info.queueFamilyIndex = this->graphics_queue_index;
  this->graphics_queue_info.queueCount = 1;
  this->graphics_queue_info.pQueuePriorities = &priority;

  this->present_queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
  this->present_queue_info.queueFamilyIndex = this->present_queue_index;
  this->present_queue_info.queueCount = 1;
  this->present_queue_info.pQueuePriorities = &priority;

  if(this->present_queue_index == this->graphics_queue_index)
  {
    num_queues = 1;
    this->pqueue_infos = new VkDeviceQueueCreateInfo[num_queues];
    this->pqueue_infos[0] = this->graphics_queue_info;
  }
  else
  {
    this->pqueue_infos = new VkDeviceQueueCreateInfo[num_queues];
    this->pqueue_infos[0] = this->graphics_queue_info;
    this->pqueue_infos[1] = this->present_queue_info;
  }

  this->logical_device_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
  this->logical_device_info.pQueueCreateInfos = this->pqueue_infos;
  this->logical_device_info.queueCreateInfoCount = num_queues;
  this->logical_device_info.pEnabledFeatures = &(this->physical_device_features);
  this->logical_device_info.enabledExtensionCount = NUM_REQUIRED_EXTENSIONS;
  this->logical_device_info.ppEnabledExtensionNames = this->ppdevice_required_extensions;

  if(this->enable_validation_layers)
  {
    this->logical_device_info.enabledLayerCount = NUM_VALIDATION_LAYERS; 
    this->logical_device_info.ppEnabledLayerNames = this->ppvalidation_layers;
  }
  else
    {this->logical_device_info.enabledLayerCount = 0;}

  if(vkCreateDevice(this->vk_physical_device, &(this->logical_device_info), nullptr, &(this->vk_logical_device)) != VK_SUCCESS)
  {
    exit_code = DE_LOGICAL_DEVICE;

    #ifdef DE_DEBUG
      cout << "failed to create logical device!" << endl;
    #endif
  }
  else
  {
    vkGetDeviceQueue(this->vk_logical_device, this->graphics_queue_index, 0, &(this->queue_graphics));
    vkGetDeviceQueue(this->vk_logical_device, this->present_queue_index, 0, &(this->queue_present));
  }

  return exit_code;
}

int cDEcore::DEcore_query_swapchain(VkPhysicalDevice device)
{
  int exit_code = DE_NO_ERROR;

  vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, this->surface, &(this->swap_chain_capabilities));
  vkGetPhysicalDeviceSurfaceFormatsKHR(device, this->surface, &(this->num_format), nullptr);

  if(this->num_format > 0)
  {
    this->pswap_chain_formats = new VkSurfaceFormatKHR[this->num_format];
    vkGetPhysicalDeviceSurfaceFormatsKHR(device, this->surface, &(this->num_format), this->pswap_chain_formats);
    vkGetPhysicalDeviceSurfacePresentModesKHR(device, this->surface, &(this->num_present_modes), nullptr);

    if(this->num_present_modes > 0)
    {
      this->pswap_chain_present_modes = new VkPresentModeKHR[this->num_present_modes];
      vkGetPhysicalDeviceSurfacePresentModesKHR(device, this->surface, &(this->num_present_modes), this->pswap_chain_present_modes);
    }
    else
    {
      exit_code = DE_NO_SWAPCHAIN_PRESENT_MODE;

      #ifdef DE_DEBUG
        cout << "couldn't find swap chain present modes!" << endl;
      #endif
    }
  }
  else
  {
    exit_code = DE_NO_SWAPCHAIN_FORMAT;

    #ifdef DE_DEBUG
      cout << "couldn't find swap chain format!" << endl;
    #endif
  }

  return exit_code;
}

bool cDEcore::DEcore_required_extensions(VkPhysicalDevice device)
{
  bool flag = DE_FALSE;
  unsigned int num_extensions = 0;
  bool stop = DE_FALSE;
  bool ext_found = DE_FALSE;

  vkEnumerateDeviceExtensionProperties(device, nullptr, &num_extensions, nullptr);

  if(num_extensions > 0)
  {
    this->pvk_extensions = new VkExtensionProperties[num_extensions];
    vkEnumerateDeviceExtensionProperties(device, nullptr, &num_extensions, this->pvk_extensions);

    for(unsigned int i = 0 ; (i < NUM_REQUIRED_EXTENSIONS) && !stop ; i++)
    {
      for(unsigned int h = 0 ; (h < num_extensions) && !ext_found ; h++)
      {
        if(strcmp(this->pvk_extensions[h].extensionName, this->ppdevice_required_extensions[i]) == 0)
          {ext_found = DE_TRUE;}
        else
        {
          ext_found = DE_FALSE;

          if(h == (num_extensions - 1))
            {stop = DE_TRUE;}
        }
      }
    }

    if(stop)
    {
      delete [] this->pvk_extensions;
      this->pvk_extensions = NULL;
    }
    else
      {flag = DE_TRUE;}
  }

  return flag;
}

bool cDEcore::DEcore_query_queue_family(VkPhysicalDevice device)
{
  unsigned int num_queue_family = 0;
  VkBool32 present_support = VK_FALSE;

  // queue families / should graphics family and present family be the same?

  vkGetPhysicalDeviceQueueFamilyProperties(device, &num_queue_family, nullptr);

  if(num_queue_family != 0)
  {
    this->pvk_all_queue_families = new VkQueueFamilyProperties[num_queue_family];
    vkGetPhysicalDeviceQueueFamilyProperties(device, &num_queue_family, this->pvk_all_queue_families);

    for(int i = 0 ; i < (int)num_queue_family ; i++)
    {
      vkGetPhysicalDeviceSurfaceSupportKHR(device, i, this->surface, &present_support);

      if(this->pvk_all_queue_families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
        {this->graphics_queue_index = i;}

      if(present_support)
        {this->present_queue_index = i;}

      if(!(this->graphics_queue_index == -1) && !(this->present_queue_index == -1))
        {break;}
    }

    if((this->graphics_queue_index == -1) || (this->present_queue_index == -1))
    {
      delete [] this->pvk_all_queue_families;
      this->pvk_all_queue_families = NULL;
    }
  }

  return !(this->graphics_queue_index == -1) && !(this->present_queue_index == -1);
}

int cDEcore::DEcore_init_swap_chain()
{
  int exit_code = DE_NO_ERROR;

  if(!this->DEcore_choose_swap_surface_format())
  {
    #ifdef DE_DEBUG
      cout << "couldn't find specific swap chain format!" << endl;
    #endif
  }

  if(!this->DEcore_choose_swap_present_mode())
  {
    #ifdef DE_DEBUG
      cout << "couldn't load specific present mode! triple buffering not supported!" << endl;
    #endif
  }

  if(!this->DEcore_choose_swap_extent())
  {
    #ifdef DE_DEBUG
      cout << "couldn't initialize specific swap extent!" << endl;
    #endif
  }

  this->image_count = this->swap_chain_capabilities.minImageCount + 1;

  if(this->swap_chain_capabilities.maxImageCount > 0 && this->image_count > this->swap_chain_capabilities.maxImageCount)
    {this->image_count = this->swap_chain_capabilities.maxImageCount;}
cout << "image count: " << this->image_count << endl;
  this->swap_chain_info = {};
  this->swap_chain_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
  this->swap_chain_info.surface = this->surface;
  this->swap_chain_info.minImageCount = this->image_count;
  this->swap_chain_info.imageFormat = this->swap_chain_format.format;
  this->swap_chain_info.imageColorSpace = this->swap_chain_format.colorSpace;
  this->swap_chain_info.imageExtent = this->extent;
  this->swap_chain_info.imageArrayLayers = 1;
  this->swap_chain_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;

  this->pqueue_index = new uint32_t[NUM_QUEUES];
  this->pqueue_index[0] = (uint32_t)this->graphics_queue_index;
  this->pqueue_index[1] = (uint32_t)this->present_queue_index;

  if(this->graphics_queue_index != this->present_queue_index)
  {
    this->swap_chain_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
    this->swap_chain_info.queueFamilyIndexCount = 2;
    this->swap_chain_info.pQueueFamilyIndices = this->pqueue_index;
  }
  else
  {
    this->swap_chain_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
    this->swap_chain_info.queueFamilyIndexCount = 0;
    this->swap_chain_info.pQueueFamilyIndices = nullptr;
  }

  this->swap_chain_info.preTransform = this->swap_chain_capabilities.currentTransform;
  this->swap_chain_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
  this->swap_chain_info.presentMode = this->swap_chain_present_mode;
  this->swap_chain_info.clipped = VK_TRUE;
  this->swap_chain_info.oldSwapchain = VK_NULL_HANDLE;

  if(vkCreateSwapchainKHR(this->vk_logical_device, &(this->swap_chain_info), nullptr, &(this->swap_chain)) != VK_SUCCESS)
  {
    exit_code = DE_SWAP_CHAIN;

    #ifdef DE_DEBUG
      cout << "couldn't create swap chain!" << endl;
    #endif
  }
  else
  {
    vkGetSwapchainImagesKHR(this->vk_logical_device, this->swap_chain, &(this->image_count), nullptr);

    if(this->image_count > 0)
    {
      this->pimage = new VkImage[this->image_count];
      vkGetSwapchainImagesKHR(this->vk_logical_device, this->swap_chain, &(this->image_count), this->pimage);
    }
    else
    {
      exit_code = DE_VK_IMAGE;

      #ifdef DE_DEBUG
        cout << "couldn't request number of VkImage!" << endl;
      #endif
    }
  }

  return exit_code;
}

bool cDEcore::DEcore_choose_swap_surface_format()
{
  bool found = DE_FALSE;

  for(uint32_t i = 0 ; i < this->num_format ; i++)
  {
    if(this->pswap_chain_formats[i].format == VK_FORMAT_B8G8R8A8_UNORM && this->pswap_chain_formats[i].colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
    {
      this->swap_chain_format = this->pswap_chain_formats[i];
      found = DE_TRUE;
    }
  }

  if(!found)
    {this->swap_chain_format = this->pswap_chain_formats[0];}

  return found;
}

bool cDEcore::DEcore_choose_swap_present_mode()
{
  bool found = DE_FALSE;

  for(uint32_t i = 0 ; i < this->num_present_modes ; i++)
  {
    if(this->pswap_chain_present_modes[i] == VK_PRESENT_MODE_MAILBOX_KHR)
    {
      this->swap_chain_present_mode = this->pswap_chain_present_modes[i];
      found = DE_TRUE;
    }
  }

  if(!found)
    {this->swap_chain_present_mode = VK_PRESENT_MODE_FIFO_KHR;}

  return found;
}

bool cDEcore::DEcore_choose_swap_extent()
{
  bool found = DE_FALSE;

  this->extent.width = max((int)this->swap_chain_capabilities.currentExtent.width, width);
  this->extent.height = max((int)this->swap_chain_capabilities.currentExtent.height, height);

  if(this->extent.width == width && this->extent.height == height)
    {found = DE_TRUE;}

  return found;
}

void cDEcore::DEcore_clear_suitable_device()
{
  if(this->pvk_all_queue_families != NULL)
  {
    delete [] this->pvk_all_queue_families;
    this->pvk_all_queue_families = NULL;
  }

  if(this->pvk_extensions != NULL)
  {
    delete [] this->pvk_extensions;
    this->pvk_extensions = NULL;
  }

  if(this->pswap_chain_formats != NULL)
  {
    delete [] this->pswap_chain_formats;
    this->pswap_chain_formats = NULL;
  }

  if(this->pswap_chain_present_modes != NULL)
  {
    delete [] this->pswap_chain_present_modes;
    this->pswap_chain_present_modes = NULL;
  }
}

int cDEcore::DEcore_create_image_views()
{
  int exit_code = DE_NO_ERROR;
  this->pimage_view = new VkImageView[this->image_count];

  for(uint32_t i = 0 ; i < this->image_count ; i++)
  {
    VkImageViewCreateInfo image_view_info = {};
    image_view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
    image_view_info.image = this->pimage[i];
    image_view_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
    image_view_info.format = this->swap_chain_format.format;
    image_view_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
    image_view_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
    image_view_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
    image_view_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
    image_view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
    image_view_info.subresourceRange.baseMipLevel = 0;
    image_view_info.subresourceRange.levelCount = 1;
    image_view_info.subresourceRange.baseArrayLayer = 0;
    image_view_info.subresourceRange.layerCount = 1;

    if(vkCreateImageView(this->vk_logical_device, &(image_view_info), nullptr, &(this->pimage_view[i])) != VK_SUCCESS)
    {
      exit_code = DE_IMAGE_VIEW;

      #ifdef DE_DEBUG
        cout << "couldn't create image view!" << endl;
      #endif

      break;
    }
  }

  return exit_code;
}

int cDEcore::DEcore_create_graphics_pipeline()
{
  int exit_code = DE_NO_ERROR;
  VkShaderModule vert_shader_module = 0;
  VkShaderModule frag_shader_module = 0;
  VkPipelineShaderStageCreateInfo vert_shader_stage_info = {};
  VkPipelineShaderStageCreateInfo frag_shader_stage_info = {};
  VkPipelineVertexInputStateCreateInfo vertex_input_info = {};
  VkPipelineInputAssemblyStateCreateInfo input_assembly_info = {};
  VkViewport view_port = {};
  VkRect2D scissor = {};
  VkPipelineViewportStateCreateInfo viewport_state = {};
  VkPipelineRasterizationStateCreateInfo rasterizer = {};
  VkPipelineMultisampleStateCreateInfo multisampling = {};
  VkPipelineColorBlendAttachmentState color_blend_attachment = {};
  VkPipelineColorBlendStateCreateInfo color_blending = {};
  VkPipelineLayoutCreateInfo pipeline_layout_info = {};
  VkGraphicsPipelineCreateInfo pipeline_info = {};

  auto pspirv_vertex = this->DE_read_file("../SLL/shaders/vert.spv");
  auto pspirv_fragment = this->DE_read_file("../SLL/shaders/frag.spv");

  if(pspirv_vertex.size() > 0 && pspirv_fragment.size() > 0)
  {
    exit_code = this->DEcore_create_shader_module(pspirv_vertex, &vert_shader_module);

    if(!exit_code)
      {exit_code = this->DEcore_create_shader_module(pspirv_fragment, &frag_shader_module);}

    if(!exit_code)
    {
      vert_shader_stage_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
      vert_shader_stage_info.stage = VK_SHADER_STAGE_VERTEX_BIT;
      vert_shader_stage_info.module = vert_shader_module;
      vert_shader_stage_info.pName = "main";

      frag_shader_stage_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
      frag_shader_stage_info.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
      frag_shader_stage_info.module = frag_shader_module;
      frag_shader_stage_info.pName = "main";

      VkPipelineShaderStageCreateInfo shader_stage_infos[] = {vert_shader_stage_info, frag_shader_stage_info};
      
      VkVertexInputBindingDescription binding_description = {};
      binding_description.binding = 0;
      binding_description.stride = sizeof(vertex);
      binding_description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;

      VkVertexInputAttributeDescription attr_description_pos = {};
      attr_description_pos.binding = 0;
      attr_description_pos.location = 0;
      attr_description_pos.format = VK_FORMAT_R32G32B32_SFLOAT;
      attr_description_pos.offset = offsetof(vertex, pos);

      VkVertexInputAttributeDescription attr_description_color = {};
      attr_description_color.binding = 0;
      attr_description_color.location = 1;
      attr_description_color.format = VK_FORMAT_R32G32B32_SFLOAT;
      attr_description_color.offset = offsetof(vertex, color);

      VkVertexInputAttributeDescription vertex_attributes[] = {attr_description_pos, attr_description_color};

      vertex_input_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
      vertex_input_info.vertexBindingDescriptionCount = 1;
      vertex_input_info.vertexAttributeDescriptionCount = 2;
      vertex_input_info.pVertexBindingDescriptions = &binding_description;
      vertex_input_info.pVertexAttributeDescriptions = vertex_attributes;

      input_assembly_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
      input_assembly_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
      input_assembly_info.primitiveRestartEnable = VK_FALSE;

      view_port.x = 0.0f;
      view_port.y = 0.0f;
      view_port.width = (float)this->extent.width;
      view_port.height = (float)this->extent.height;
      view_port.minDepth = 0.0f;
      view_port.maxDepth = 1.0f;

      scissor.offset = {0, 0};
      scissor.extent = this->extent;

      viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
      viewport_state.viewportCount = 1;
      viewport_state.pViewports = &view_port;
      viewport_state.scissorCount = 1;
      viewport_state.pScissors = &scissor;
      viewport_state.pNext = nullptr;

      rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
      rasterizer.depthClampEnable = VK_FALSE;
      rasterizer.rasterizerDiscardEnable = VK_FALSE;
      rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
      rasterizer.lineWidth = 1.0f;
      rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
      rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
      rasterizer.depthBiasEnable = VK_FALSE;
      rasterizer.depthBiasConstantFactor = 0.0f;
      rasterizer.depthBiasClamp = 0.0f;
      rasterizer.depthBiasSlopeFactor = 0.0f;

      multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
      multisampling.sampleShadingEnable = VK_FALSE;
      multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
      multisampling.minSampleShading = 1.0f;
      multisampling.pSampleMask = nullptr;
      multisampling.alphaToCoverageEnable = VK_FALSE;
      multisampling.alphaToOneEnable = VK_FALSE;

      color_blend_attachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
      color_blend_attachment.blendEnable = VK_FALSE;
      color_blend_attachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
      color_blend_attachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO;
      color_blend_attachment.colorBlendOp = VK_BLEND_OP_ADD;
      color_blend_attachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
      color_blend_attachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
      color_blend_attachment.alphaBlendOp = VK_BLEND_OP_ADD;

      color_blending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
      color_blending.logicOpEnable = VK_FALSE;
      color_blending.logicOp = VK_LOGIC_OP_COPY;
      color_blending.attachmentCount = 1;
      color_blending.pAttachments = &color_blend_attachment;
      color_blending.blendConstants[0] = 0.0f;
      color_blending.blendConstants[1] = 0.0f;
      color_blending.blendConstants[2] = 0.0f;
      color_blending.blendConstants[3] = 0.0f;

      VkDescriptorSetLayout descriptor_set_layouts[] = {this->descriptor_set_layout};

      pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
      pipeline_layout_info.setLayoutCount = 1;
      pipeline_layout_info.pSetLayouts = descriptor_set_layouts;
      pipeline_layout_info.pushConstantRangeCount = 0;
      pipeline_layout_info.pPushConstantRanges = 0;

      if(vkCreatePipelineLayout(this->vk_logical_device, &pipeline_layout_info, nullptr, &(this->pipeline_layout)) != VK_SUCCESS)
      {
        exit_code = DE_PIPELINE_LAYOUT;

        #ifdef DE_DEBUG
          cout << "couldn't create graphics pipeline layout!" << endl;
        #endif
      }
      else
      {
        pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
        pipeline_info.stageCount = 2;
        pipeline_info.pStages = shader_stage_infos;
        pipeline_info.pVertexInputState = &vertex_input_info;
        pipeline_info.pInputAssemblyState = &input_assembly_info;
        pipeline_info.pViewportState = &viewport_state;
        pipeline_info.pRasterizationState = &rasterizer;
        pipeline_info.pMultisampleState = &multisampling;
        pipeline_info.pDepthStencilState = nullptr;
        pipeline_info.pColorBlendState = &color_blending;
        pipeline_info.pDynamicState = nullptr;
        pipeline_info.layout = pipeline_layout;
        pipeline_info.renderPass = this->render_pass;
        pipeline_info.subpass = 0;
        pipeline_info.basePipelineHandle = VK_NULL_HANDLE;
        pipeline_info.basePipelineIndex = -1;

        if(vkCreateGraphicsPipelines(this->vk_logical_device, VK_NULL_HANDLE, 1, &pipeline_info, nullptr, &(this->graphics_pipeline)) != VK_SUCCESS)
        {
          exit_code = DE_GRAPHICS_PIPELINE;

          #ifdef DE_DEBUG
            cout << "couldn't create graphics pipeline!" << endl;
          #endif
        }
        else
        {
          vkDestroyShaderModule(this->vk_logical_device, vert_shader_module, nullptr);
          vkDestroyShaderModule(this->vk_logical_device, frag_shader_module, nullptr);
        }
      }
    }
  }

  return exit_code;
}

int cDEcore::DEcore_create_shader_module(const std::vector<char>& pcode, VkShaderModule * pshader_module)
{
  int exit_code = DE_NO_ERROR;
  VkShaderModuleCreateInfo shader_module_info = {};
  shader_module_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
  shader_module_info.codeSize = pcode.size();
  shader_module_info.pCode = (uint32_t*)pcode.data();

  if(vkCreateShaderModule(this->vk_logical_device, &(shader_module_info), nullptr, pshader_module) != VK_SUCCESS)
  {
    exit_code = DE_CREATE_SHADER_MODULE;

    #ifdef DE_DEBUG
      cout << "couldn't create shader module!" << endl;
    #endif
  }

  return exit_code;
}

int cDEcore::DEcore_create_render_pass()
{
  int exit_code = DE_NO_ERROR;
  VkAttachmentDescription color_attachment = {};
  VkAttachmentReference attachment_reference = {};
  VkSubpassDescription subpass_description = {};
  VkRenderPassCreateInfo render_pass_info = {};
  VkSubpassDependency dependency = {};

  color_attachment.format = this->swap_chain_format.format;
  color_attachment.samples = VK_SAMPLE_COUNT_1_BIT;
  color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
  color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
  color_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
  color_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
  color_attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
  color_attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;

  attachment_reference.attachment = 0;
  attachment_reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

  subpass_description.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
  subpass_description.colorAttachmentCount = 1;
  subpass_description.pColorAttachments = &attachment_reference;

  dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
  dependency.dstSubpass = 0;
  dependency.srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
  dependency.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
  dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
  dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;

  render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
  render_pass_info.attachmentCount = 1;
  render_pass_info.pAttachments = &color_attachment;
  render_pass_info.subpassCount = 1;
  render_pass_info.pSubpasses = &subpass_description;
  render_pass_info.dependencyCount = 1;
  render_pass_info.pDependencies = &dependency;

  if(vkCreateRenderPass(this->vk_logical_device, &render_pass_info, nullptr, &(this->render_pass)) != VK_SUCCESS)
  {
    exit_code = DE_RENDER_PASS;

    #ifdef DE_DEBUG
      cout << "couldn't create render pass!" << endl;
    #endif
  }

  return exit_code;
}

bool cDEcore::DEcore_check_validation_layer_support()
{
  bool flag = DE_FALSE;
  uint32_t layer_count = 0;
  VkLayerProperties * pavailable_layer = NULL;

  vkEnumerateInstanceLayerProperties(&layer_count, nullptr);

  if(layer_count > 0)
  {
    pavailable_layer = new VkLayerProperties[layer_count];
    vkEnumerateInstanceLayerProperties(&layer_count, pavailable_layer);

    for(int i = 0 ; i < NUM_VALIDATION_LAYERS ; i++)
    {
      for(int y = 0 ; y < layer_count ; y++)
      {
        if(strcmp(this->ppvalidation_layers[i], pavailable_layer[y].layerName) == 0)
          {flag = DE_TRUE;}
        else
          {flag = DE_FALSE;}
      }
    }

    delete [] pavailable_layer;
  }

  return flag;
}

char ** cDEcore::DEcore_get_required_extensions()
{
  const char ** ppextensions = NULL;
  char ** ppall_extensions = NULL;
  unsigned int num_extensions = 0;
  ppextensions = glfwGetRequiredInstanceExtensions(&num_extensions);

  if(this->enable_validation_layers)
    {this->glfw_num_extensions = num_extensions + 1;}
  else
    {this->glfw_num_extensions = num_extensions;}

  ppall_extensions = new char * [this->glfw_num_extensions];

  if(this->enable_validation_layers)
  {
    for(int i = 0 ; i < this->glfw_num_extensions - 1 ; i++)
    {
      ppall_extensions[i] = new char[strlen(ppextensions[i]) + 1];
      strcpy_s(ppall_extensions[i], strlen(ppextensions[i]) + 1, ppextensions[i]);
    }

    ppall_extensions[this->glfw_num_extensions - 1] = new char[strlen(VK_EXT_DEBUG_REPORT_EXTENSION_NAME) + 1];
    strcpy_s(ppall_extensions[this->glfw_num_extensions - 1], strlen(VK_EXT_DEBUG_REPORT_EXTENSION_NAME) + 1, VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
  }
  else
  {
    for(int i = 0 ; i < this->glfw_num_extensions; i++)
    {
      ppall_extensions[i] = new char[strlen(ppextensions[i]) + 1];
      strcpy_s(ppall_extensions[i], strlen(ppextensions[i]) + 1, ppextensions[i]);
    }
  }

  return ppall_extensions;
}

VKAPI_ATTR VkBool32 VKAPI_CALL cDEcore::DEcore_vk_debug_callback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT obj_type, uint64_t obj, size_t location, int32_t code, const char * player_prefix, const char * pmsg, void * puserData)
{
  #ifdef DE_DEBUG
    cout << "------------------------------------" << endl;
    cout << "validation layer: " << pmsg << endl;
    cout << "------------------------------------" << endl;
  #endif

  return VK_FALSE;
}

int cDEcore::DEcore_create_debug_callback()
{
  int exit_code = DE_NO_ERROR;
  VkDebugReportCallbackCreateInfoEXT callback_info = {};
  callback_info.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
  callback_info.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;
  callback_info.pfnCallback = this->DEcore_vk_debug_callback;

  if(CreateDebugReportCallbackEXT(this->vk_instance, &callback_info, nullptr, &(this->vk_callback)) != VK_SUCCESS)
  {
    exit_code = DE_VK_DEBUG_CALLBACK;

    #ifdef DE_DEBUG
      cout << "couldn't set VK debug callback function!" << endl;
    #endif
  }

  return exit_code;
}

void cDEcore::DEcore_unload_vulkan()
{
  if(this->ppdevice_required_extensions != NULL)
  {
    for(int i = 0 ; i < NUM_REQUIRED_EXTENSIONS ; i++)
      {delete [] this->ppdevice_required_extensions[i];}

    delete [] this->ppdevice_required_extensions;
  }

  if(this->ppvalidation_layers != NULL)
  {
    for(int i = 0 ; i < NUM_VALIDATION_LAYERS ; i++)
      {delete [] this->ppvalidation_layers[i];}

    delete [] this->ppvalidation_layers;
  }

  if(this->pqueue_infos != NULL)
    {delete [] this->pqueue_infos;}

  if(this->pvk_extensions != NULL)
    {delete [] this->pvk_extensions;}

  if(this->pvk_all_queue_families != NULL)
    {delete [] this->pvk_all_queue_families;}

  vkDestroySemaphore(this->vk_logical_device, this->ready_for_rendering, nullptr);
  vkDestroySemaphore(this->vk_logical_device, this->ready_for_presentation, nullptr);

  vkDestroyDescriptorPool(this->vk_logical_device, this->descriptor_pool, nullptr);

  vkFreeMemory(this->vk_logical_device, this->vertex_buffer_memory, nullptr);
  vkDestroyBuffer(this->vk_logical_device, this->vertex_buffer, nullptr);
  vkFreeMemory(this->vk_logical_device, this->index_buffer_memory, nullptr);
  vkDestroyBuffer(this->vk_logical_device, this->index_buffer, nullptr);
  vkFreeMemory(this->vk_logical_device, this->uniform_staging_buffer_memory, nullptr);
  vkDestroyBuffer(this->vk_logical_device, this->uniform_staging_buffer, nullptr);
  vkFreeMemory(this->vk_logical_device, this->uniform_buffer_memory, nullptr);
  vkDestroyBuffer(this->vk_logical_device, this->uniform_buffer, nullptr);

  if(this->command_pool != NULL)
    {vkDestroyCommandPool(this->vk_logical_device, this->command_pool, nullptr);}

  if(this->pframe_buffer != NULL)
  {
    for(uint32_t i = 0 ; i < this->image_count ; i++)
      {vkDestroyFramebuffer(this->vk_logical_device, this->pframe_buffer[i], nullptr);}

    delete [] this->pframe_buffer;
  }

  if(this->pipeline_layout != NULL)
    {vkDestroyPipelineLayout(this->vk_logical_device, this->pipeline_layout, nullptr);}

  vkDestroyDescriptorSetLayout(this->vk_logical_device, this->descriptor_set_layout, nullptr);

  if(this->graphics_pipeline != NULL)
    {vkDestroyPipeline(this->vk_logical_device, this->graphics_pipeline, nullptr);}

  if(this->render_pass != NULL)
    {vkDestroyRenderPass(this->vk_logical_device, this->render_pass, nullptr);}

  if(this->pimage_view != NULL)
  {
    for(uint32_t i = 0 ; i < this->image_count ; i++)
      {vkDestroyImageView(this->vk_logical_device, this->pimage_view[i], nullptr);}

    delete [] this->pimage_view;
  }

  vkDestroySwapchainKHR(this->vk_logical_device, this->swap_chain, nullptr);

  if(this->vk_logical_device != NULL)
    {vkDestroyDevice(this->vk_logical_device, nullptr);}

  if(this->vk_all_physical_devices != NULL)
    {delete[] this->vk_all_physical_devices;}

  if(this->surface != NULL)
    {vkDestroySurfaceKHR(this->vk_instance, this->surface, nullptr);}

  DestroyDebugReportCallbackEXT(this->vk_instance, this->vk_callback, nullptr);

  if(this->vk_instance != NULL)
    {vkDestroyInstance(this->vk_instance, nullptr);}
}

int cDEcore::DEcore_create_framebuffer()
{
  int exit_code = DE_NO_ERROR;
  this->pframe_buffer = new VkFramebuffer[this->image_count];

  for(size_t i = 0 ; i < this->image_count ; i++)
  {
    VkFramebufferCreateInfo frame_buffer_info = {};
    frame_buffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
    frame_buffer_info.renderPass = this->render_pass;
    frame_buffer_info.attachmentCount = 1;
    frame_buffer_info.pAttachments = &(this->pimage_view[i]);
    frame_buffer_info.width = this->extent.width;
    frame_buffer_info.height = this->extent.height;
    frame_buffer_info.layers = 1;

    if(vkCreateFramebuffer(this->vk_logical_device, &(frame_buffer_info), nullptr, &(this->pframe_buffer[i])) != VK_SUCCESS)
    {
      exit_code = DE_FRAME_BUFFERS;

      #ifdef DE_DEBUG
        cout << "could not create frame buffer!" << endl;
      #endif

      break;
    }
  }

  return exit_code;
}

int cDEcore::DEcore_create_command_pool()
{
  int exit_code = DE_NO_ERROR;
  VkCommandPoolCreateInfo command_pool_info = {};
  command_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
  command_pool_info.queueFamilyIndex = this->graphics_queue_index;
  command_pool_info.flags = 0;

  if(vkCreateCommandPool(this->vk_logical_device, &command_pool_info, nullptr, &(this->command_pool)) != VK_SUCCESS)
  {
    exit_code = DE_COMMAND_POOL;

    #ifdef DE_DEBUG
      cout << "couldn't create command pool!" << endl;
    #endif
  }

  return exit_code;
}

int cDEcore::DEcore_create_command_buffers()
{
  int exit_code = DE_NO_ERROR;
  const int num_indices = 6; // DEPR
  this->pcommand_buffers = new VkCommandBuffer[this->image_count];

  VkCommandBufferAllocateInfo command_buffer_info = {};
  command_buffer_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
  command_buffer_info.commandPool = this->command_pool;
  command_buffer_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
  command_buffer_info.commandBufferCount = this->image_count;

  if(vkAllocateCommandBuffers(this->vk_logical_device, &(command_buffer_info), this->pcommand_buffers) != VK_SUCCESS)
  {
    exit_code = DE_COMMAND_BUFFERS;

    #ifdef DE_DEBUG
      cout << "couldn't allocate command buffers!" << endl;
    #endif
  }
  else
  {
    for(size_t i = 0 ; i < (this->image_count && !exit_code) ; i++)
    {
      VkCommandBufferBeginInfo buffer_begin_info = {};
      buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
      buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
      buffer_begin_info.pInheritanceInfo = nullptr;

      vkBeginCommandBuffer(this->pcommand_buffers[i], &buffer_begin_info);

      VkRenderPassBeginInfo render_pass_info = {};
      render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
      render_pass_info.renderPass = this->render_pass;
      render_pass_info.framebuffer = this->pframe_buffer[i];
      render_pass_info.renderArea.offset = {0, 0};
      render_pass_info.renderArea.extent = this->extent;
      VkClearValue clear_color = {0.0f, 0.0f, 0.0f, 1.0f};
      render_pass_info.clearValueCount = 1;
      render_pass_info.pClearValues = &clear_color;

      vkCmdBeginRenderPass(this->pcommand_buffers[i], &render_pass_info, VK_SUBPASS_CONTENTS_INLINE);
      vkCmdBindPipeline(this->pcommand_buffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, this->graphics_pipeline);

      VkBuffer vertex_buffers [] = {this->vertex_buffer};
      VkDeviceSize offsets[] = {0};
      vkCmdBindVertexBuffers(this->pcommand_buffers[i], 0, 1, vertex_buffers, offsets);
      vkCmdBindIndexBuffer(this->pcommand_buffers[i], this->index_buffer, 0, VK_INDEX_TYPE_UINT32);

      vkCmdBindDescriptorSets(this->pcommand_buffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, this->pipeline_layout, 0, 1, &(this->descriptor_set), 0, nullptr);

      vkCmdDrawIndexed(this->pcommand_buffers[i], num_indices, 1, 0, 0, 0);
      vkCmdEndRenderPass(this->pcommand_buffers[i]);

      if(vkEndCommandBuffer(this->pcommand_buffers[i]) != VK_SUCCESS)
      {
        exit_code = DE_END_COMMAND_BUFFER;

        #ifdef DE_DEBUG
          cout << "failed to record command buffer!" << endl;
        #endif
      }
    }
  }

  return exit_code;
}

int cDEcore::DEcore_create_semaphores()
{
  int exit_code = DE_NO_ERROR;
  VkSemaphoreCreateInfo semaphore_info = {};
  semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;

  if(vkCreateSemaphore(this->vk_logical_device, &semaphore_info, nullptr, &(this->ready_for_rendering)) != VK_SUCCESS)
  {
    exit_code = DE_SEMAPHORE;

    #ifdef DE_DEBUG
      cout << "couldn't create semaphore for rendering!" << endl;
    #endif
  }
  else
  {
    if(vkCreateSemaphore(this->vk_logical_device, &semaphore_info, nullptr, &(this->ready_for_presentation)) != VK_SUCCESS)
    {
      exit_code = DE_SEMAPHORE;

      #ifdef DE_DEBUG
        cout << "couldn't create semaphore for presentation!" << endl;
      #endif
    }
  }

  return exit_code;
}

linked_3dobj * cDEcore::DE_3dobj_get_by_id(int id)
{
  linked_3dobj * pret = NULL;
  linked_3dobj * pcurrent = this->p3dobj_head->pright;

  while(pcurrent != this->p3dobj_head)
  {
    if(pcurrent->id == id)
    {
      pret = pcurrent;
      break;
    }

    pcurrent = pcurrent->pright;
  }

  return pret;
}

uint32_t cDEcore::DEcore_find_memory_type(uint32_t type_filter, VkMemoryPropertyFlags properties)
{
  uint32_t type = 0;
  bool found = DE_FALSE;
  VkPhysicalDeviceMemoryProperties memory_properties;
  vkGetPhysicalDeviceMemoryProperties(this->vk_physical_device, &memory_properties);

  for(uint32_t i = 0 ; i < memory_properties.memoryTypeCount ; i++)
  {
    if((type_filter & (1 << i)) && (memory_properties.memoryTypes[i].propertyFlags & properties) == properties)
    {
      found = DE_TRUE;
      type = i;
      break;
    }
  }

  if(!found)
  {
    #ifdef DE_DEBUG
      cout << "couldn't find memory type for vertex buffer!" << endl;
    #endif
  }

  return type;
}

int cDEcore::DEcore_create_buffer(VkDeviceSize size, VkBufferUsageFlags usage_flags, VkMemoryPropertyFlags properties, VkBuffer * pbuffer, VkDeviceMemory * pdevice_memory)
{
  int exit_code = DE_NO_ERROR;

  VkBufferCreateInfo buffer_info = {};
  buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
  buffer_info.size = size;
  buffer_info.usage = usage_flags;
  buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

  if(vkCreateBuffer(this->vk_logical_device, &buffer_info, nullptr, pbuffer) != VK_SUCCESS)
  {
    exit_code = DE_CREATE_BUFFER;

    #ifdef DE_DEBUG
      cout << "function vkCreateBuffer() failed!" << endl;
    #endif
  }
  else
  {
    VkMemoryRequirements memory_requirements = {};
    vkGetBufferMemoryRequirements(this->vk_logical_device, *pbuffer, &memory_requirements);

    VkMemoryAllocateInfo alloc_info = {};
    alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
    alloc_info.allocationSize = memory_requirements.size;
    alloc_info.memoryTypeIndex = this->DEcore_find_memory_type(memory_requirements.memoryTypeBits, properties);

    if(vkAllocateMemory(this->vk_logical_device, &alloc_info, nullptr, pdevice_memory) != VK_SUCCESS)
    {
      exit_code = DE_ALLOC_MEM;

      #ifdef DE_DEBUG
        cout << "unable to allocate memory for vertex buffer!" << endl;
      #endif
    }
    else
      {vkBindBufferMemory(this->vk_logical_device, *pbuffer, *pdevice_memory, 0);}
  }

  return exit_code;
}

int cDEcore::DEcore_create_vertex_buffers()
{
  int exit_code = DE_NO_ERROR;
  void * pdata = NULL;
  const int num_vertex = 4; // DEPR
  vertex * pvertex_data = new vertex[num_vertex];
  VkDeviceSize buffer_size = sizeof(vertex) * num_vertex;
  VkBuffer staging_buffer;
  VkDeviceMemory staging_buffer_memory;
  exit_code = this->DE_3dobj_get_vertex_data(0, &pvertex_data);               // DEPR

  if(!exit_code)
    {exit_code = this->DEcore_create_buffer(buffer_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &staging_buffer, &staging_buffer_memory);}

  if(!exit_code)
  {
    vkMapMemory(this->vk_logical_device, staging_buffer_memory, 0, buffer_size, 0, &pdata);
    memcpy(pdata, pvertex_data, (size_t)buffer_size);
    vkUnmapMemory(this->vk_logical_device, staging_buffer_memory);
  }

  if(!exit_code)
    {exit_code = this->DEcore_create_buffer(buffer_size, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &(this->vertex_buffer), &(this->vertex_buffer_memory));}

  if(!exit_code)
    {this->DEcore_copy_buffer(staging_buffer, this->vertex_buffer, buffer_size);}

  delete [] pvertex_data;
  vkFreeMemory(this->vk_logical_device, staging_buffer_memory, nullptr);
  vkDestroyBuffer(this->vk_logical_device, staging_buffer, nullptr);

  return exit_code;
}

int cDEcore::DEcore_create_index_buffer()
{
  int exit_code = DE_NO_ERROR;
  void * pdata = NULL;
  const int num_indices = 6; // DEPR
  uint32_t * pindex = new uint32_t[num_indices];
  VkDeviceSize buffer_size = sizeof(uint32_t) * num_indices;
  VkBuffer staging_buffer;
  VkDeviceMemory staging_buffer_memory;
  exit_code = this->DE_3dobj_get_indices(0, &pindex);               // DEPR

  if(!exit_code)
    {exit_code = this->DEcore_create_buffer(buffer_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &staging_buffer, &staging_buffer_memory);}

  if(!exit_code)
  {
    vkMapMemory(this->vk_logical_device, staging_buffer_memory, 0, buffer_size, 0, &pdata);
    memcpy(pdata, pindex, (size_t)buffer_size);
    vkUnmapMemory(this->vk_logical_device, staging_buffer_memory);
  }

  if(!exit_code)
    {exit_code = this->DEcore_create_buffer(buffer_size, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &(this->index_buffer), &(this->index_buffer_memory));}

  if(!exit_code)
    {this->DEcore_copy_buffer(staging_buffer, this->index_buffer, buffer_size);}

  delete [] pindex;
  vkFreeMemory(this->vk_logical_device, staging_buffer_memory, nullptr);
  vkDestroyBuffer(this->vk_logical_device, staging_buffer, nullptr);

  return exit_code;
}

void cDEcore::DEcore_copy_buffer(VkBuffer src_buffer, VkBuffer dst_buffer, VkDeviceSize size)
{
  VkCommandBufferAllocateInfo alloc_info = {};
  alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
  alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
  alloc_info.commandPool = this->command_pool;
  alloc_info.commandBufferCount = 1;

  VkCommandBuffer cpy_command_buffer;
  vkAllocateCommandBuffers(this->vk_logical_device, &alloc_info, &cpy_command_buffer);

  VkCommandBufferBeginInfo begin_info = {};
  begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
  begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;

  vkBeginCommandBuffer(cpy_command_buffer, &begin_info);

  VkBufferCopy copy_region = {};
  copy_region.srcOffset = 0;
  copy_region.dstOffset = 0;
  copy_region.size = size;

  vkCmdCopyBuffer(cpy_command_buffer, src_buffer, dst_buffer, 1, &copy_region);
  vkEndCommandBuffer(cpy_command_buffer);

  VkSubmitInfo submit_info = {};
  submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
  submit_info.commandBufferCount = 1;
  submit_info.pCommandBuffers = &cpy_command_buffer;

  vkQueueSubmit(this->queue_graphics, 1, &submit_info, VK_NULL_HANDLE);
  vkQueueWaitIdle(this->queue_graphics);
  vkFreeCommandBuffers(this->vk_logical_device, this->command_pool, 1, &cpy_command_buffer);
}

int cDEcore::DEcore_create_descriptor_layout()
{
  int exit_code = DE_NO_ERROR;

  VkDescriptorSetLayoutBinding ubo_layout_binding = {};
  ubo_layout_binding.binding = 0;
  ubo_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
  ubo_layout_binding.descriptorCount = 1;
  ubo_layout_binding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
  ubo_layout_binding.pImmutableSamplers = nullptr;

  VkDescriptorSetLayoutCreateInfo layout_info = {};
  layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
  layout_info.bindingCount = 1;
  layout_info.pBindings = &ubo_layout_binding;

  if(vkCreateDescriptorSetLayout(this->vk_logical_device, &layout_info, nullptr, &(this->descriptor_set_layout)) != VK_SUCCESS)
  {
    exit_code = DE_DESCR_SET_LAYOUT;

    #ifdef DE_DEBUG
      cout << "vkCreateDescriptorSetLayout() failed!" << endl;
    #endif
  }

  return exit_code;
}

int cDEcore::DEcore_create_uniform_buffer()
{
  int exit_code = DE_NO_ERROR;
  VkDeviceSize buffer_size = sizeof(ubo);

  this->DEcore_create_buffer(buffer_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &(this->uniform_staging_buffer), &(this->uniform_staging_buffer_memory));
  this->DEcore_create_buffer(buffer_size, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &(this->uniform_buffer), &(this->uniform_buffer_memory));

  return exit_code;
}

int cDEcore::DEcore_create_descriptor_pool()
{
  int exit_code = DE_NO_ERROR;
  VkDescriptorPoolSize pool_size = {};
  VkDescriptorPoolCreateInfo pool_info = {};

  pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
  pool_size.descriptorCount = 1;

  pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
  pool_info.poolSizeCount = 1;
  pool_info.pPoolSizes = &pool_size;
  pool_info.maxSets = 1;

  if(vkCreateDescriptorPool(this->vk_logical_device, &pool_info, nullptr, &(this->descriptor_pool)) != VK_SUCCESS)
  {
    exit_code = DE_CREATE_DESCR_POOL;

    #ifdef DE_DEBUG
      cout << "vkCreateDescriptorPool() failed!" << endl;
    #endif
  }

  return exit_code;
}

int cDEcore::DEcore_create_descriptor_set()
{
  int exit_code = DE_NO_ERROR;
  VkDescriptorSetLayout layouts[] = { this->descriptor_set_layout };
  VkDescriptorSetAllocateInfo alloc_info = {};
  VkDescriptorBufferInfo buffer_info;
  VkWriteDescriptorSet descriptor_write = {};

  alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
  alloc_info.descriptorPool = this->descriptor_pool;
  alloc_info.descriptorSetCount = 1;
  alloc_info.pSetLayouts = layouts;

  if(vkAllocateDescriptorSets(this->vk_logical_device, &alloc_info, &(this->descriptor_set)) != VK_SUCCESS)
  {
    exit_code = DE_ALLOC_DESCR_SET;

    #ifdef DE_DEBUG
      cout << "vkAllocateDescriptorSets() failed!" << endl;
    #endif
  }

  buffer_info.buffer = this->uniform_buffer;
  buffer_info.offset = 0;
  buffer_info.range = sizeof(ubo);

  descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
  descriptor_write.dstSet = this->descriptor_set;
  descriptor_write.dstBinding = 0;
  descriptor_write.dstArrayElement = 0;
  descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
  descriptor_write.descriptorCount = 1;
  descriptor_write.pBufferInfo = &buffer_info;
  descriptor_write.pImageInfo = nullptr;
  descriptor_write.pTexelBufferView = nullptr;

  vkUpdateDescriptorSets(this->vk_logical_device, 1, &descriptor_write, 0, nullptr);

  return exit_code;
}

int cDEcore::DEcore_recreate_swap_chain()
{
  int exit_code = DE_NO_ERROR;

  vkDeviceWaitIdle(this->vk_logical_device);

  exit_code = this->DEcore_init_swap_chain();

  if(!exit_code)
    {exit_code = this->DEcore_create_image_views();}

  if(!exit_code)
    {exit_code = this->DEcore_create_render_pass();}

  if(!exit_code)
    {exit_code = this->DEcore_create_graphics_pipeline();}

  if(!exit_code)
    {exit_code = this->DEcore_create_framebuffer();}

  if(!exit_code)
    {exit_code = this->DEcore_create_command_buffers();}

  return exit_code;
}

//-------------------------------------------------------
//-------------------------------------------------------

cDEcore::cDEcore():
graphics_queue_index(-1),
present_queue_index(-1),
num_format(0),
num_present_modes(0),
width(0),
height(0),
image_count(0),
enable_validation_layers(DE_FALSE),
glfw_num_extensions(0),
timestamp(0),
timestep(0.0f),
timestamp_before(0)
{
  this->pwindow = NULL;
  this->vk_physical_device = NULL;
  this->vk_all_physical_devices = NULL;
  this->pvk_all_queue_families = NULL;
  this->vk_logical_device = NULL;
  this->pvk_extensions = NULL;
  this->pqueue_infos = NULL;
  this->ppdevice_required_extensions = new char * [NUM_REQUIRED_EXTENSIONS];
  this->ppdevice_required_extensions[0] = new char[strlen(VK_KHR_SWAPCHAIN_EXTENSION_NAME) + 1];
  strcpy_s(this->ppdevice_required_extensions[0], strlen(VK_KHR_SWAPCHAIN_EXTENSION_NAME) + 1, VK_KHR_SWAPCHAIN_EXTENSION_NAME);
  this->pswap_chain_formats = NULL;
  this->pswap_chain_present_modes = NULL;
  this->pqueue_index = NULL;
  this->pimage = NULL;
  this->pimage_view = NULL;
  this->ppvalidation_layers = new char * [NUM_VALIDATION_LAYERS];
  this->ppvalidation_layers[0] = new char[strlen("VK_LAYER_LUNARG_standard_validation") + 1];
  strcpy_s(this->ppvalidation_layers[0], strlen("VK_LAYER_LUNARG_standard_validation") + 1, "VK_LAYER_LUNARG_standard_validation");
  this->pframe_buffer = NULL;
  this->command_pool = NULL;
  this->pcommand_buffers = NULL;

  this->p3dobj_head = new linked_3dobj;
  this->p3dobj_head->pleft = this->p3dobj_head;
  this->p3dobj_head->pright = this->p3dobj_head;
  this->p3dobj_head->id = 0;
  this->p3dobj_head->p3dobj = NULL;

  #ifdef DE_DEBUG
    this->enable_validation_layers = DE_TRUE;
  #endif

  this->DEcore_clear_keyboard(GLFW_PRESS || GLFW_RELEASE);
}

cDEcore::~cDEcore()
{
  linked_3dobj * pcurrent_3dobj = NULL;
  linked_3dobj * pnext_3dobj = NULL;

  // unload vulkan

  vkDeviceWaitIdle(this->vk_logical_device);
  this->DEcore_unload_vulkan();

  // unload 3d obj

  if(this->p3dobj_head != NULL)
  {
    pcurrent_3dobj = this->p3dobj_head->pright;

    while(pcurrent_3dobj != this->p3dobj_head)
    {
      pnext_3dobj = pcurrent_3dobj->pright;
      delete pcurrent_3dobj->p3dobj;
      delete pcurrent_3dobj;
      pcurrent_3dobj = pnext_3dobj;
    }

    delete this->p3dobj_head;
  }

  // unload window

  if(this->pwindow != NULL)
    {glfwDestroyWindow(this->pwindow);}

  glfwTerminate();
}

int cDEcore::DEcore_create_window(const char * ptitle)
{
  int exit_code = DE_NO_ERROR;
  GLFWmonitor * pprimary = NULL;
  int glfw_major_v = 0;
  int glfw_minor_v = 0;
  int glfw_rev = 0;

  #ifdef DE_DEBUG
    glfwGetVersion(&glfw_major_v, &glfw_minor_v, &glfw_rev);
    cout << "glfw version: (" << glfw_major_v << "." << glfw_minor_v << "." << glfw_rev << ")" << endl;
  #endif

  if(glfwInit() != GLFW_TRUE)
  {
    exit_code = DE_GLFW_FAILED;

    #ifdef DE_DEBUG
      if(!exit_code)
        {cout << "glfwInit() failed!" << endl;}
    #endif
  }

  if(!exit_code)
  {
    if(!glfwVulkanSupported())
    {
      exit_code = DE_GLFW_VK_SUPPORT;

      #ifdef DE_DEBUG
        cout << "glfw: vulkan not supported!" << endl;
      #endif
    }
  }

  if(!exit_code)
    {glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);}

  if(!exit_code)
  {
    pprimary = glfwGetPrimaryMonitor();

    if(pprimary != NULL)
    {
      const GLFWvidmode * pmode = glfwGetVideoMode(pprimary);

      if(pmode != NULL)
      {
        glfwWindowHint(GLFW_RED_BITS, pmode->redBits);
        glfwWindowHint(GLFW_GREEN_BITS, pmode->greenBits);
        glfwWindowHint(GLFW_BLUE_BITS, pmode->blueBits);
        glfwWindowHint(GLFW_REFRESH_RATE, pmode->refreshRate);
        this->width = pmode->width;
        this->height = pmode->height;

        this->pwindow = glfwCreateWindow(pmode->width, pmode->height, ptitle, pprimary, NULL);

        if(this->pwindow == NULL)
        {
          exit_code = DE_CREATE_WND;

          #ifdef DE_DEBUG
            if(!exit_code)
              {cout << "glfwCreateWindow() failed!" << endl;}
          #endif
        }
      }
      else
      {
        exit_code = DE_VIDEO_MODE;

        #ifdef DE_DEBUG
          if(!exit_code)
            {cout << "glfwGetVideoMode() failed!" << endl;}
        #endif
      }
    }
    else
    {
      exit_code = DE_NOPRIM_MONITOR;

      #ifdef DE_DEBUG
        if(!exit_code)
          {cout << "no primary monitor found!" << endl;}
      #endif
    }
  }

  return exit_code;
}

int cDEcore::DEcore_create_window(int width, int height, const char * ptitle)
{
  int exit_code = DE_NO_ERROR;
  int glfw_major_v = 0;
  int glfw_minor_v = 0;
  int glfw_rev = 0;
  this->width = width;
  this->height = height;

  #ifdef DE_DEBUG
    glfwGetVersion(&glfw_major_v, &glfw_minor_v, &glfw_rev);
    cout << "glfw version: (" << glfw_major_v << "." << glfw_minor_v << "." << glfw_rev << ")" << endl;
  #endif

  if(glfwInit() != GLFW_TRUE)
  {
    exit_code = DE_GLFW_FAILED;

    #ifdef DE_DEBUG
      if(!exit_code)
        {cout << "glfwInit() failed!" << endl;}
    #endif
  }

  if(!exit_code)
  {
    if(!glfwVulkanSupported())
    {
      exit_code = DE_GLFW_VK_SUPPORT;

      #ifdef DE_DEBUG
        cout << "glfw: vulkan not supported!" << endl;
      #endif
    }
  }

  if(!exit_code)
    {glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);}

  if(!exit_code)
  {
    this->pwindow = glfwCreateWindow(width, height, ptitle, NULL, NULL);

    if(this->pwindow == NULL)
    {
      exit_code = DE_CREATE_WND;

      #ifdef DE_DEBUG
        if(!exit_code)
          {cout << "glfwCreateWindow() failed!" << endl;}
      #endif
    }
  }

  return exit_code;
}

int cDEcore::DEcore_open_window()
{
  return !glfwWindowShouldClose(this->pwindow);
}

void cDEcore::DEcore_event_handler()
{
  glfwPollEvents();

  // key

  this->DEcore_clear_keyboard(GLFW_RELEASE);
  this->DEcore_key_event();
}

bool cDEcore::DEcore_keyboard(int key, int action)
{
  bool flag = DE_FALSE;

  // key pressed

  if(action == GLFW_PRESS)
  {
    switch(key)
    {
      case GLFW_KEY_UNKNOWN:
      {
        flag = this->keyboard.unknown.pressed;
      } break;
      case GLFW_KEY_SPACE:
      {
        flag = this->keyboard.space.pressed;
      } break;
      case GLFW_KEY_APOSTROPHE:
      {
        flag = this->keyboard.apostrophe.pressed;
      } break;
      case GLFW_KEY_COMMA:
      {
        flag = this->keyboard.comma.pressed;
      } break;
      case GLFW_KEY_MINUS:
      {
        flag = this->keyboard.minus.pressed;
      } break;
      case GLFW_KEY_PERIOD:
      {
        flag = this->keyboard.period.pressed;
      } break;
      case GLFW_KEY_SLASH:
      {
        flag = this->keyboard.slash.pressed;
      } break;
      case GLFW_KEY_0:
      {
        flag = this->keyboard.k0.pressed;
      } break;
      case GLFW_KEY_1:
      {
        flag = this->keyboard.k1.pressed;
      } break;
      case GLFW_KEY_2:
      {
        flag = this->keyboard.k2.pressed;
      } break;
      case GLFW_KEY_3:
      {
        flag = this->keyboard.k3.pressed;
      } break;
      case GLFW_KEY_4:
      {
        flag = this->keyboard.k4.pressed;
      } break;
      case GLFW_KEY_5:
      {
        flag = this->keyboard.k5.pressed;
      } break;
      case GLFW_KEY_6:
      {
        flag = this->keyboard.k6.pressed;
      } break;
      case GLFW_KEY_7:
      {
        flag = this->keyboard.k7.pressed;
      } break;
      case GLFW_KEY_8:
      {
        flag = this->keyboard.k8.pressed;
      } break;
      case GLFW_KEY_9:
      {
        flag = this->keyboard.k9.pressed;
      } break;
      case GLFW_KEY_SEMICOLON:
      {
        flag = this->keyboard.semicolon.pressed;
      } break;
      case GLFW_KEY_EQUAL:
      {
        flag = this->keyboard.equal.pressed;
      } break;
      case GLFW_KEY_A:
      {
        flag = this->keyboard.ka.pressed;
      } break;
      case GLFW_KEY_B:
      {
        flag = this->keyboard.kb.pressed;
      } break;
      case GLFW_KEY_C:
      {
        flag = this->keyboard.kc.pressed;
      } break;
      case GLFW_KEY_D:
      {
        flag = this->keyboard.kd.pressed;
      } break;
      case GLFW_KEY_E:
      {
        flag = this->keyboard.ke.pressed;
      } break;
      case GLFW_KEY_F:
      {
        flag = this->keyboard.kf.pressed;
      } break;
      case GLFW_KEY_G:
      {
        flag = this->keyboard.kg.pressed;
      } break;
      case GLFW_KEY_H:
      {
        flag = this->keyboard.kh.pressed;
      } break;
      case GLFW_KEY_I:
      {
        flag = this->keyboard.ki.pressed;
      } break;
      case GLFW_KEY_J:
      {
        flag = this->keyboard.kj.pressed;
      } break;
      case GLFW_KEY_K:
      {
        flag = this->keyboard.kk.pressed;
      } break;
      case GLFW_KEY_L:
      {
        flag = this->keyboard.kl.pressed;
      } break;
      case GLFW_KEY_M:
      {
        flag = this->keyboard.km.pressed;
      } break;
      case GLFW_KEY_N:
      {
        flag = this->keyboard.kn.pressed;
      } break;
      case GLFW_KEY_O:
      {
        flag = this->keyboard.ko.pressed;
      } break;
      case GLFW_KEY_P:
      {
        flag = this->keyboard.kp.pressed;
      } break;
      case GLFW_KEY_Q:
      {
        flag = this->keyboard.kq.pressed;
      } break;
      case GLFW_KEY_R:
      {
        flag = this->keyboard.kr.pressed;
      } break;
      case GLFW_KEY_S:
      {
        flag = this->keyboard.ks.pressed;
      } break;
      case GLFW_KEY_T:
      {
        flag = this->keyboard.kt.pressed;
      } break;
      case GLFW_KEY_U:
      {
        flag = this->keyboard.ku.pressed;
      } break;
      case GLFW_KEY_V:
      {
        flag = this->keyboard.kv.pressed;
      } break;
      case GLFW_KEY_W:
      {
        flag = this->keyboard.kw.pressed;
      } break;
      case GLFW_KEY_X:
      {
        flag = this->keyboard.kx.pressed;
      } break;
      case GLFW_KEY_Y:
      {
        flag = this->keyboard.ky.pressed;
      } break;
      case GLFW_KEY_Z:
      {
        flag = this->keyboard.kz.pressed;
      } break;
      case GLFW_KEY_LEFT_BRACKET:
      {
        flag = this->keyboard.left_bracket.pressed;
      } break;
      case GLFW_KEY_BACKSLASH:
      {
        flag = this->keyboard.backslash.pressed;
      } break;
      case GLFW_KEY_RIGHT_BRACKET:
      {
        flag = this->keyboard.right_bracket.pressed;
      } break;
      case GLFW_KEY_GRAVE_ACCENT:
      {
        flag = this->keyboard.grave_accent.pressed;
      } break;
      case GLFW_KEY_WORLD_1:
      {
        flag = this->keyboard.world_1.pressed;
      } break;
      case GLFW_KEY_WORLD_2:
      {
        flag = this->keyboard.world_2.pressed;
      } break;
      case GLFW_KEY_ESCAPE:
      {
        flag = this->keyboard.escape.pressed;
      } break;
      case GLFW_KEY_ENTER:
      {
        flag = this->keyboard.enter.pressed;
      } break;
      case GLFW_KEY_TAB:
      {
        flag = this->keyboard.tab.pressed;
      } break;
      case GLFW_KEY_BACKSPACE:
      {
        flag = this->keyboard.backspace.pressed;
      } break;
      case GLFW_KEY_INSERT:
      {
        flag = this->keyboard.insert.pressed;
      } break;
      case GLFW_KEY_DELETE:
      {
        flag = this->keyboard.del.pressed;
      } break;
      case GLFW_KEY_RIGHT:
      {
        flag = this->keyboard.right.pressed;
      } break;
      case GLFW_KEY_LEFT:
      {
        flag = this->keyboard.left.pressed;
      } break;
      case GLFW_KEY_DOWN:
      {
        flag = this->keyboard.down.pressed;
      } break;
      case GLFW_KEY_UP:
      {
        flag = this->keyboard.up.pressed;
      } break;
      case GLFW_KEY_PAGE_UP:
      {
        flag = this->keyboard.page_up.pressed;
      } break;
      case GLFW_KEY_PAGE_DOWN:
      {
        flag = this->keyboard.page_down.pressed;
      } break;
      case GLFW_KEY_HOME:
      {
        flag = this->keyboard.home.pressed;
      } break;
      case GLFW_KEY_END:
      {
        flag = this->keyboard.end.pressed;
      } break;
      case GLFW_KEY_CAPS_LOCK:
      {
        flag = this->keyboard.caps_lock.pressed;
      } break;
      case GLFW_KEY_SCROLL_LOCK:
      {
        flag = this->keyboard.scroll_lock.pressed;
      } break;
      case GLFW_KEY_NUM_LOCK:
      {
        flag = this->keyboard.num_lock.pressed;
      } break;
      case GLFW_KEY_PRINT_SCREEN:
      {
        flag = this->keyboard.print_screen.pressed;
      } break;
      case GLFW_KEY_PAUSE:
      {
        flag = this->keyboard.pause.pressed;
      } break;
      case GLFW_KEY_F1:
      {
        flag = this->keyboard.f1.pressed;
      } break;
      case GLFW_KEY_F2:
      {
        flag = this->keyboard.f2.pressed;
      } break;
      case GLFW_KEY_F3:
      {
        flag = this->keyboard.f3.pressed;
      } break;
      case GLFW_KEY_F4:
      {
        flag = this->keyboard.f4.pressed;
      } break;
      case GLFW_KEY_F5:
      {
        flag = this->keyboard.f5.pressed;
      } break;
      case GLFW_KEY_F6:
      {
        flag = this->keyboard.f6.pressed;
      } break;
      case GLFW_KEY_F7:
      {
        flag = this->keyboard.f7.pressed;
      } break;
      case GLFW_KEY_F8:
      {
        flag = this->keyboard.f8.pressed;
      } break;
      case GLFW_KEY_F9:
      {
        flag = this->keyboard.f9.pressed;
      } break;
      case GLFW_KEY_F10:
      {
        flag = this->keyboard.f10.pressed;
      } break;
      case GLFW_KEY_F11:
      {
        flag = this->keyboard.f11.pressed;
      } break;
      case GLFW_KEY_F12:
      {
        flag = this->keyboard.f12.pressed;
      } break;
      case GLFW_KEY_F13:
      {
        flag = this->keyboard.f13.pressed;
      } break;
      case GLFW_KEY_F14:
      {
        flag = this->keyboard.f14.pressed;
      } break;
      case GLFW_KEY_F15:
      {
        flag = this->keyboard.f15.pressed;
      } break;
      case GLFW_KEY_F16:
      {
        flag = this->keyboard.f16.pressed;
      } break;
      case GLFW_KEY_F17:
      {
        flag = this->keyboard.f17.pressed;
      } break;
      case GLFW_KEY_F18:
      {
        flag = this->keyboard.f18.pressed;
      } break;
      case GLFW_KEY_F19:
      {
        flag = this->keyboard.f19.pressed;
      } break;
      case GLFW_KEY_F20:
      {
        flag = this->keyboard.f20.pressed;
      } break;
      case GLFW_KEY_F21:
      {
        flag = this->keyboard.f21.pressed;
      } break;
      case GLFW_KEY_F22:
      {
        flag = this->keyboard.f22.pressed;
      } break;
      case GLFW_KEY_F23:
      {
        flag = this->keyboard.f23.pressed;
      } break;
      case GLFW_KEY_F24:
      {
        flag = this->keyboard.f24.pressed;
      } break;
      case GLFW_KEY_F25:
      {
        flag = this->keyboard.f25.pressed;
      } break;
      case GLFW_KEY_KP_0:
      {
        flag = this->keyboard.kp_0.pressed;
      } break;
      case GLFW_KEY_KP_1:
      {
        flag = this->keyboard.kp_1.pressed;
      } break;
      case GLFW_KEY_KP_2:
      {
        flag = this->keyboard.kp_2.pressed;
      } break;
      case GLFW_KEY_KP_3:
      {
        flag = this->keyboard.kp_3.pressed;
      } break;
      case GLFW_KEY_KP_4:
      {
        flag = this->keyboard.kp_4.pressed;
      } break;
      case GLFW_KEY_KP_5:
      {
        flag = this->keyboard.kp_5.pressed;
      } break;
      case GLFW_KEY_KP_6:
      {
        flag = this->keyboard.kp_6.pressed;
      } break;
      case GLFW_KEY_KP_7:
      {
        flag = this->keyboard.kp_7.pressed;
      } break;
      case GLFW_KEY_KP_8:
      {
        flag = this->keyboard.kp_8.pressed;
      } break;
      case GLFW_KEY_KP_9:
      {
        flag = this->keyboard.kp_9.pressed;
      } break;
      case GLFW_KEY_KP_DECIMAL:
      {
        flag = this->keyboard.kp_decimal.pressed;
      } break;
      case GLFW_KEY_KP_DIVIDE:
      {
        flag = this->keyboard.kp_divide.pressed;
      } break;
      case GLFW_KEY_KP_MULTIPLY:
      {
        flag = this->keyboard.kp_multiply.pressed;
      } break;
      case GLFW_KEY_KP_SUBTRACT:
      {
        flag = this->keyboard.kp_subtract.pressed;
      } break;
      case GLFW_KEY_KP_ADD:
      {
        flag = this->keyboard.kp_add.pressed;
      } break;
      case GLFW_KEY_KP_ENTER:
      {
        flag = this->keyboard.kp_enter.pressed;
      } break;
      case GLFW_KEY_KP_EQUAL:
      {
        flag = this->keyboard.kp_equal.pressed;
      } break;
      case GLFW_KEY_LEFT_SHIFT:
      {
        flag = this->keyboard.left_shift.pressed;
      } break;
      case GLFW_KEY_LEFT_CONTROL:
      {
        flag = this->keyboard.left_control.pressed;
      } break;
      case GLFW_KEY_LEFT_ALT:
      {
        flag = this->keyboard.left_alt.pressed;
      } break;
      case GLFW_KEY_LEFT_SUPER:
      {
        flag = this->keyboard.left_super.pressed;
      } break;
      case GLFW_KEY_RIGHT_SHIFT:
      {
        flag = this->keyboard.right_shift.pressed;
      } break;
      case GLFW_KEY_RIGHT_CONTROL:
      {
        flag = this->keyboard.right_control.pressed;
      } break;
      case GLFW_KEY_RIGHT_ALT:
      {
        flag = this->keyboard.right_alt.pressed;
      } break;
      case GLFW_KEY_RIGHT_SUPER:
      {
        flag = this->keyboard.right_super.pressed;
      } break;
      case GLFW_KEY_MENU:
      {
        flag = this->keyboard.menu.pressed;
      } break;
    };
  }

  // key released

  if(action == GLFW_RELEASE)
  {
    switch(key)
    {
      case GLFW_KEY_UNKNOWN:
      {
        flag = this->keyboard.unknown.released;
      } break;
      case GLFW_KEY_SPACE:
      {
        flag = this->keyboard.space.released;
      } break;
      case GLFW_KEY_APOSTROPHE:
      {
        flag = this->keyboard.apostrophe.released;
      } break;
      case GLFW_KEY_COMMA:
      {
        flag = this->keyboard.comma.released;
      } break;
      case GLFW_KEY_MINUS:
      {
        flag = this->keyboard.minus.released;
      } break;
      case GLFW_KEY_PERIOD:
      {
        flag = this->keyboard.period.released;
      } break;
      case GLFW_KEY_SLASH:
      {
        flag = this->keyboard.slash.released;
      } break;
      case GLFW_KEY_0:
      {
        flag = this->keyboard.k0.released;
      } break;
      case GLFW_KEY_1:
      {
        flag = this->keyboard.k1.released;
      } break;
      case GLFW_KEY_2:
      {
        flag = this->keyboard.k2.released;
      } break;
      case GLFW_KEY_3:
      {
        flag = this->keyboard.k3.released;
      } break;
      case GLFW_KEY_4:
      {
        flag = this->keyboard.k4.released;
      } break;
      case GLFW_KEY_5:
      {
        flag = this->keyboard.k5.released;
      } break;
      case GLFW_KEY_6:
      {
        flag = this->keyboard.k6.released;
      } break;
      case GLFW_KEY_7:
      {
        flag = this->keyboard.k7.released;
      } break;
      case GLFW_KEY_8:
      {
        flag = this->keyboard.k8.released;
      } break;
      case GLFW_KEY_9:
      {
        flag = this->keyboard.k9.released;
      } break;
      case GLFW_KEY_SEMICOLON:
      {
        flag = this->keyboard.semicolon.released;
      } break;
      case GLFW_KEY_EQUAL:
      {
        flag = this->keyboard.equal.released;
      } break;
      case GLFW_KEY_A:
      {
        flag = this->keyboard.ka.released;
      } break;
      case GLFW_KEY_B:
      {
        flag = this->keyboard.kb.released;
      } break;
      case GLFW_KEY_C:
      {
        flag = this->keyboard.kc.released;
      } break;
      case GLFW_KEY_D:
      {
        flag = this->keyboard.kd.released;
      } break;
      case GLFW_KEY_E:
      {
        flag = this->keyboard.ke.released;
      } break;
      case GLFW_KEY_F:
      {
        flag = this->keyboard.kf.released;
      } break;
      case GLFW_KEY_G:
      {
        flag = this->keyboard.kg.released;
      } break;
      case GLFW_KEY_H:
      {
        flag = this->keyboard.kh.released;
      } break;
      case GLFW_KEY_I:
      {
        flag = this->keyboard.ki.released;
      } break;
      case GLFW_KEY_J:
      {
        flag = this->keyboard.kj.released;
      } break;
      case GLFW_KEY_K:
      {
        flag = this->keyboard.kk.released;
      } break;
      case GLFW_KEY_L:
      {
        flag = this->keyboard.kl.released;
      } break;
      case GLFW_KEY_M:
      {
        flag = this->keyboard.km.released;
      } break;
      case GLFW_KEY_N:
      {
        flag = this->keyboard.kn.released;
      } break;
      case GLFW_KEY_O:
      {
        flag = this->keyboard.ko.released;
      } break;
      case GLFW_KEY_P:
      {
        flag = this->keyboard.kp.released;
      } break;
      case GLFW_KEY_Q:
      {
        flag = this->keyboard.kq.released;
      } break;
      case GLFW_KEY_R:
      {
        flag = this->keyboard.kr.released;
      } break;
      case GLFW_KEY_S:
      {
        flag = this->keyboard.ks.released;
      } break;
      case GLFW_KEY_T:
      {
        flag = this->keyboard.kt.released;
      } break;
      case GLFW_KEY_U:
      {
        flag = this->keyboard.ku.released;
      } break;
      case GLFW_KEY_V:
      {
        flag = this->keyboard.kv.released;
      } break;
      case GLFW_KEY_W:
      {
        flag = this->keyboard.kw.released;
      } break;
      case GLFW_KEY_X:
      {
        flag = this->keyboard.kx.released;
      } break;
      case GLFW_KEY_Y:
      {
        flag = this->keyboard.ky.released;
      } break;
      case GLFW_KEY_Z:
      {
        flag = this->keyboard.kz.released;
      } break;
      case GLFW_KEY_LEFT_BRACKET:
      {
        flag = this->keyboard.left_bracket.released;
      } break;
      case GLFW_KEY_BACKSLASH:
      {
        flag = this->keyboard.backslash.released;
      } break;
      case GLFW_KEY_RIGHT_BRACKET:
      {
        flag = this->keyboard.right_bracket.released;
      } break;
      case GLFW_KEY_GRAVE_ACCENT:
      {
        flag = this->keyboard.grave_accent.released;
      } break;
      case GLFW_KEY_WORLD_1:
      {
        flag = this->keyboard.world_1.released;
      } break;
      case GLFW_KEY_WORLD_2:
      {
        flag = this->keyboard.world_2.released;
      } break;
      case GLFW_KEY_ESCAPE:
      {
        flag = this->keyboard.escape.released;
      } break;
      case GLFW_KEY_ENTER:
      {
        flag = this->keyboard.enter.released;
      } break;
      case GLFW_KEY_TAB:
      {
        flag = this->keyboard.tab.released;
      } break;
      case GLFW_KEY_BACKSPACE:
      {
        flag = this->keyboard.backspace.released;
      } break;
      case GLFW_KEY_INSERT:
      {
        flag = this->keyboard.insert.released;
      } break;
      case GLFW_KEY_DELETE:
      {
        flag = this->keyboard.del.released;
      } break;
      case GLFW_KEY_RIGHT:
      {
        flag = this->keyboard.right.released;
      } break;
      case GLFW_KEY_LEFT:
      {
        flag = this->keyboard.left.released;
      } break;
      case GLFW_KEY_DOWN:
      {
        flag = this->keyboard.down.released;
      } break;
      case GLFW_KEY_UP:
      {
        flag = this->keyboard.up.released;
      } break;
      case GLFW_KEY_PAGE_UP:
      {
        flag = this->keyboard.page_up.released;
      } break;
      case GLFW_KEY_PAGE_DOWN:
      {
        flag = this->keyboard.page_down.released;
      } break;
      case GLFW_KEY_HOME:
      {
        flag = this->keyboard.home.released;
      } break;
      case GLFW_KEY_END:
      {
        flag = this->keyboard.end.released;
      } break;
      case GLFW_KEY_CAPS_LOCK:
      {
        flag = this->keyboard.caps_lock.released;
      } break;
      case GLFW_KEY_SCROLL_LOCK:
      {
        flag = this->keyboard.scroll_lock.released;
      } break;
      case GLFW_KEY_NUM_LOCK:
      {
        flag = this->keyboard.num_lock.released;
      } break;
      case GLFW_KEY_PRINT_SCREEN:
      {
        flag = this->keyboard.print_screen.released;
      } break;
      case GLFW_KEY_PAUSE:
      {
        flag = this->keyboard.pause.released;
      } break;
      case GLFW_KEY_F1:
      {
        flag = this->keyboard.f1.released;
      } break;
      case GLFW_KEY_F2:
      {
        flag = this->keyboard.f2.released;
      } break;
      case GLFW_KEY_F3:
      {
        flag = this->keyboard.f3.released;
      } break;
      case GLFW_KEY_F4:
      {
        flag = this->keyboard.f4.released;
      } break;
      case GLFW_KEY_F5:
      {
        flag = this->keyboard.f5.released;
      } break;
      case GLFW_KEY_F6:
      {
        flag = this->keyboard.f6.released;
      } break;
      case GLFW_KEY_F7:
      {
        flag = this->keyboard.f7.released;
      } break;
      case GLFW_KEY_F8:
      {
        flag = this->keyboard.f8.released;
      } break;
      case GLFW_KEY_F9:
      {
        flag = this->keyboard.f9.released;
      } break;
      case GLFW_KEY_F10:
      {
        flag = this->keyboard.f10.released;
      } break;
      case GLFW_KEY_F11:
      {
        flag = this->keyboard.f11.released;
      } break;
      case GLFW_KEY_F12:
      {
        flag = this->keyboard.f12.released;
      } break;
      case GLFW_KEY_F13:
      {
        flag = this->keyboard.f13.released;
      } break;
      case GLFW_KEY_F14:
      {
        flag = this->keyboard.f14.released;
      } break;
      case GLFW_KEY_F15:
      {
        flag = this->keyboard.f15.released;
      } break;
      case GLFW_KEY_F16:
      {
        flag = this->keyboard.f16.released;
      } break;
      case GLFW_KEY_F17:
      {
        flag = this->keyboard.f17.released;
      } break;
      case GLFW_KEY_F18:
      {
        flag = this->keyboard.f18.released;
      } break;
      case GLFW_KEY_F19:
      {
        flag = this->keyboard.f19.released;
      } break;
      case GLFW_KEY_F20:
      {
        flag = this->keyboard.f20.released;
      } break;
      case GLFW_KEY_F21:
      {
        flag = this->keyboard.f21.released;
      } break;
      case GLFW_KEY_F22:
      {
        flag = this->keyboard.f22.released;
      } break;
      case GLFW_KEY_F23:
      {
        flag = this->keyboard.f23.released;
      } break;
      case GLFW_KEY_F24:
      {
        flag = this->keyboard.f24.released;
      } break;
      case GLFW_KEY_F25:
      {
        flag = this->keyboard.f25.released;
      } break;
      case GLFW_KEY_KP_0:
      {
        flag = this->keyboard.kp_0.released;
      } break;
      case GLFW_KEY_KP_1:
      {
        flag = this->keyboard.kp_1.released;
      } break;
      case GLFW_KEY_KP_2:
      {
        flag = this->keyboard.kp_2.released;
      } break;
      case GLFW_KEY_KP_3:
      {
        flag = this->keyboard.kp_3.released;
      } break;
      case GLFW_KEY_KP_4:
      {
        flag = this->keyboard.kp_4.released;
      } break;
      case GLFW_KEY_KP_5:
      {
        flag = this->keyboard.kp_5.released;
      } break;
      case GLFW_KEY_KP_6:
      {
        flag = this->keyboard.kp_6.released;
      } break;
      case GLFW_KEY_KP_7:
      {
        flag = this->keyboard.kp_7.released;
      } break;
      case GLFW_KEY_KP_8:
      {
        flag = this->keyboard.kp_8.released;
      } break;
      case GLFW_KEY_KP_9:
      {
        flag = this->keyboard.kp_9.released;
      } break;
      case GLFW_KEY_KP_DECIMAL:
      {
        flag = this->keyboard.kp_decimal.released;
      } break;
      case GLFW_KEY_KP_DIVIDE:
      {
        flag = this->keyboard.kp_divide.released;
      } break;
      case GLFW_KEY_KP_MULTIPLY:
      {
        flag = this->keyboard.kp_multiply.released;
      } break;
      case GLFW_KEY_KP_SUBTRACT:
      {
        flag = this->keyboard.kp_subtract.released;
      } break;
      case GLFW_KEY_KP_ADD:
      {
        flag = this->keyboard.kp_add.released;
      } break;
      case GLFW_KEY_KP_ENTER:
      {
        flag = this->keyboard.kp_enter.released;
      } break;
      case GLFW_KEY_KP_EQUAL:
      {
        flag = this->keyboard.kp_equal.released;
      } break;
      case GLFW_KEY_LEFT_SHIFT:
      {
        flag = this->keyboard.left_shift.released;
      } break;
      case GLFW_KEY_LEFT_CONTROL:
      {
        flag = this->keyboard.left_control.released;
      } break;
      case GLFW_KEY_LEFT_ALT:
      {
        flag = this->keyboard.left_alt.released;
      } break;
      case GLFW_KEY_LEFT_SUPER:
      {
        flag = this->keyboard.left_super.released;
      } break;
      case GLFW_KEY_RIGHT_SHIFT:
      {
        flag = this->keyboard.right_shift.released;
      } break;
      case GLFW_KEY_RIGHT_CONTROL:
      {
        flag = this->keyboard.right_control.released;
      } break;
      case GLFW_KEY_RIGHT_ALT:
      {
        flag = this->keyboard.right_alt.released;
      } break;
      case GLFW_KEY_RIGHT_SUPER:
      {
        flag = this->keyboard.right_super.released;
      } break;
      case GLFW_KEY_MENU:
      {
        flag = this->keyboard.menu.released;
      } break;
    };
  }

  return flag;
}

void cDEcore::DEcore_close_window()
{
  glfwSetWindowShouldClose(this->pwindow, GLFW_TRUE);
}

int cDEcore::DEcore_init_vulkan(const char * papp_name)
{
  int exit_code = DE_NO_ERROR;

  exit_code = this->DEcore_init_vk_instance(papp_name);

  if(!exit_code)
  {
    #ifdef DE_DEBUG
      this->DEcore_create_debug_callback();
    #endif
  }

  if(!exit_code)
  {
    if(glfwCreateWindowSurface(this->vk_instance, this->pwindow, nullptr, &(this->surface)) != VK_SUCCESS)
    {
      exit_code = DE_SURFACE;

      #ifdef DE_DEBUG
        cout << "failed to create surface!" << endl;
      #endif
    }
  }

  if(!exit_code)
    {exit_code = this->DEcore_init_physical_device();}

  if(!exit_code)
    {exit_code = this->DEcore_init_logical_device();}

  if(!exit_code)
    {exit_code = this->DEcore_init_swap_chain();}

  if(!exit_code)
    {exit_code = this->DEcore_create_image_views();}

  if(!exit_code)
    {exit_code = this->DEcore_create_render_pass();}

  if(!exit_code)
    {exit_code = this->DEcore_create_descriptor_layout();}

  if(!exit_code)
    {exit_code = this->DEcore_create_graphics_pipeline();}

  if(!exit_code)
    {exit_code = this->DEcore_create_framebuffer();}

  if(!exit_code)
    {exit_code = this->DEcore_create_command_pool();}

  if(!exit_code)
    {exit_code = this->DEcore_create_vertex_buffers();}

  if(!exit_code)
    {exit_code = this->DEcore_create_index_buffer();}

  if(!exit_code)
    {exit_code = this->DEcore_create_uniform_buffer();}

  if(!exit_code)
    {exit_code = this->DEcore_create_descriptor_pool();}

  if(!exit_code)
    {exit_code = this->DEcore_create_descriptor_set();}

  if(!exit_code)
    {exit_code = this->DEcore_create_command_buffers();}

  if(!exit_code)
    {exit_code = this->DEcore_create_semaphores();}

  // mvp

  this->view = glm::lookAt(glm::vec3(2.0f, 2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f));
  this->projection = glm::perspective(glm::radians(45.0f), this->extent.width / (float)this->extent.height, 0.1f, 10.0f);
  this->projection[1][1] *= -1.0f;

  return exit_code;
}

int cDEcore::DEcore_draw()
{
  int exit_code = DE_NO_ERROR;
  uint32_t image_index = 0;
  VkSubmitInfo submit_info = {};
  VkPipelineStageFlags wait_stages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
  VkPresentInfoKHR present_info = {};
  linked_3dobj * pcurrent = this->p3dobj_head->pright;
  void * pdata;
  size_t size_mvp = sizeof(this->mvp);
  VkResult result;

  // models mvp

  while(pcurrent != this->p3dobj_head)
  {
    this->mvp.mvp = this->projection * this->view * pcurrent->p3dobj->obj3d_get_matrix();

    vkMapMemory(this->vk_logical_device, this->uniform_staging_buffer_memory, 0, size_mvp, 0, &pdata);
    memcpy(pdata, &(this->mvp), size_mvp);
    vkUnmapMemory(this->vk_logical_device, this->uniform_staging_buffer_memory);cout << "------" << "here" << "------" << endl;
    this->DEcore_copy_buffer(this->uniform_staging_buffer, this->uniform_buffer, size_mvp);

    pcurrent = pcurrent->pright;
  }

  result = vkAcquireNextImageKHR(this->vk_logical_device, this->swap_chain, std::numeric_limits<uint64_t>::max(), this->ready_for_rendering, VK_NULL_HANDLE, &image_index);
cout << "##########
image index: " << image_index << "
##########" << endl;
  if(result == VK_ERROR_OUT_OF_DATE_KHR)
    {this->DEcore_recreate_swap_chain();}
  else
  {
    if(result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR)
    {
      exit_code = DE_ACQ_NEXT_IMAGE;

      #ifdef DE_DEBUG
        cout << "couldn't acquire next image for drawing!" << endl;
      #endif
    }
    else
    {
      VkSemaphore wait_semaphores[] = {this->ready_for_rendering};

      submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
      submit_info.waitSemaphoreCount = 1;
      submit_info.pWaitSemaphores = wait_semaphores;
      submit_info.pWaitDstStageMask = wait_stages;
      submit_info.commandBufferCount = 1;
      submit_info.pCommandBuffers = &(this->pcommand_buffers[image_index]);

      VkSemaphore signal_semaphores[] = {this->ready_for_presentation};

      submit_info.signalSemaphoreCount = 1;
      submit_info.pSignalSemaphores = signal_semaphores;

      if(vkQueueSubmit(this->queue_graphics, 1, &submit_info, VK_NULL_HANDLE) != VK_SUCCESS)
      {
        exit_code = DE_SUBMIT_QUEUE;

        #ifdef DE_DEBUG
          cout << "couldn't submit to graphics queue!" << endl;
        #endif
      }
      else
      {
        present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
        present_info.waitSemaphoreCount = 1;
        present_info.pWaitSemaphores = signal_semaphores;

        VkSwapchainKHR swap_chains[] = {this->swap_chain};

        present_info.swapchainCount = 1;
        present_info.pSwapchains = swap_chains;
        present_info.pImageIndices = &image_index;
        present_info.pResults = nullptr;

        result = vkQueuePresentKHR(this->queue_present, &present_info);

        if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
          {this->DEcore_recreate_swap_chain();}
        else
        {
          if(result != VK_SUCCESS)
          {
            exit_code = DE_QUEUE_PRESENT;

            #ifdef DE_DEBUG
              cout << "vkQueuePresentKHR() failed!" << endl;
            #endif
          }
        }
      }
    }
  }

  return exit_code;
}

int cDEcore::DE_3dobj_create(int id)
{
  int exit_code = DE_NO_ERROR;
  linked_3dobj * pnew = this->DE_3dobj_get_by_id(id);

  if(pnew == NULL)
  {
    pnew = new linked_3dobj;
    pnew->pright = this->p3dobj_head;
    pnew->pleft = this->p3dobj_head->pleft;
    this->p3dobj_head->pleft->pright = pnew;
    this->p3dobj_head->pleft = pnew;
    pnew->id = id;
    pnew->p3dobj = new cDE_obj3d;
  }
  else
  {
    exit_code = DE_3DOBJ_EXIST;

    #ifdef DE_DEBUG
      cout << "id of 3d obj already exist!" << endl;
    #endif
  }

  return exit_code;
}

int cDEcore::DE_3dobj_add_vertex(int id, glm::vec3 pos, glm::vec3 color)
{
  int exit_code = DE_NO_ERROR;
  linked_3dobj * pelem = this->DE_3dobj_get_by_id(id);

  if(pelem != NULL)
    {pelem->p3dobj->obj3d_add_vertex(pos, color);}
  else
  {
    exit_code = DE_3DOBJ_NOEXIST;

    #ifdef DE_DEBUG
      cout << "id of 3d obj does not exist!" << endl;
    #endif
  }

  return exit_code;
}

int cDEcore::DE_3dobj_get_vertex_data(int id, vertex ** ppvertex_data)
{
  int exit_code = DE_NO_ERROR;
  linked_3dobj * pelem = this->DE_3dobj_get_by_id(id);

  if(pelem != NULL)
    {pelem->p3dobj->obj3d_copy_vertex_data(ppvertex_data);}
  else
  {
    exit_code = DE_3DOBJ_NOEXIST;

    #ifdef DE_DEBUG
      cout << "id of 3d obj does not exist!" << endl;
    #endif
  }

  return exit_code;
}

int cDEcore::DE_3dobj_del_vertex_data(int id)
{
  int exit_code = DE_NO_ERROR;
  linked_3dobj * pelem = this->DE_3dobj_get_by_id(id);

  if(pelem != NULL)
    {pelem->p3dobj->obj3d_del_vertex_data();}
  else
  {
    exit_code = DE_3DOBJ_NOEXIST;

    #ifdef DE_DEBUG
        cout << "id of 3d obj does not exist!" << endl;
    #endif
  }

  return exit_code;
}

int cDEcore::DE_3dobj_del_indices(int id)
{
  int exit_code = DE_NO_ERROR;
  linked_3dobj * pelem = this->DE_3dobj_get_by_id(id);

  if(pelem != NULL)
    {pelem->p3dobj->obj3d_del_indices();}
  else
  {
    exit_code = DE_3DOBJ_NOEXIST;

    #ifdef DE_DEBUG
        cout << "id of 3d obj does not exist!" << endl;
    #endif
  }

  return exit_code;
}

int cDEcore::DE_3dobj_add_index(int id, uint32_t index)
{
  int exit_code = DE_NO_ERROR;
  linked_3dobj * pelem = this->DE_3dobj_get_by_id(id);

  if(pelem != NULL)
    {pelem->p3dobj->obj3d_add_index(index);}
  else
  {
    exit_code = DE_3DOBJ_NOEXIST;

    #ifdef DE_DEBUG
        cout << "id of 3d obj does not exist!" << endl;
    #endif
  }

  return exit_code;
}

int cDEcore::DE_3dobj_get_indices(int id, uint32_t ** ppindex)
{
  int exit_code = DE_NO_ERROR;
  linked_3dobj * pelem = this->DE_3dobj_get_by_id(id);

  if(pelem != NULL)
    {pelem->p3dobj->obj3d_copy_indices(ppindex);}
  else
  {
    exit_code = DE_3DOBJ_NOEXIST;

    #ifdef DE_DEBUG
        cout << "id of 3d obj does not exist!" << endl;
    #endif
  }

  return exit_code;
}

glm::mat4 cDEcore::DE_3dobj_get_matrix(int id)
{
  glm::mat4 matrix;
  linked_3dobj * pelem = this->DE_3dobj_get_by_id(id);

  if(pelem != NULL)
    {matrix = pelem->p3dobj->obj3d_get_matrix();}
  else
  {
    #ifdef DE_DEBUG
      cout << "id of 3d obj does not exist!" << endl;
    #endif
  }

  return matrix;
}

void cDEcore::DEcore_begin_cpu_calculation()
{
  this->timestamp_before = this->timestamp;
  this->timestamp = clock();
}

void cDEcore::DEcore_end_cpu_calculation()
{
  this->timestep = ((double)this->timestamp - (double)this->timestamp_before) * 0.001f;
}

int cDEcore::DE_3dobj_rotate(int id, float degree, glm::vec3 axis)
{
  int exit_code = DE_NO_ERROR;
  linked_3dobj * pelem = this->DE_3dobj_get_by_id(id);

  if(pelem != NULL)
    {pelem->p3dobj->obj3d_rotate(degree, axis, this->timestep);}
  else
  {
    exit_code = DE_3DOBJ_NOEXIST;

    #ifdef DE_DEBUG
      cout << "id of 3d obj does not exist!" << endl;
    #endif
  }

  return exit_code;
}

thanks for any advices in advance!

Hello,

what’s with all the keyboard management :wink: Hard to read the actually important bits.

validation layer: Images passed to present must be in layout VK_IMAGE_LAYOUT_PRE SENT_SRC_KHR but is in VK_IMAGE_LAYOUT_UNDEFINED

I see it in the renderpass creation. I think there should also be output subpass dependency (from 0 to EXTERNAL).
Use ALL_COMMANDS if you mean all commands. Not BOTTOM_OF_PIPE.

validation layer: You must call vkEndCommandBuffer() on CB 0x40acd00/0x40acd10 before this
call to vkQueueSubmit()!

You should check return codes of the vkBeginCommandBuffer()s (well you should consistently check all the commands).
Otherwisely Begin and End seem to be matched… try to find which CB is the 0x40acd00/0x40acd10 (it is the value of the handle as you would see in the debugger)

This
i &lt; (this-&gt;image_count && !exit_code)
rubs me the wrong way. Looks wrongly parenthesized.

so it seems that triple buffering is not working. I assume that image 0 always works, since i never recieved an error for this one, and image 1 and 2 cause the flickering. what I don’t understand… why does the app think there is an swapchain image 0x4 or even 0x5, since the total output number is 3!

(I think) it is the value of the VkImage handle itself too, not necessarily an index.
Shouldn’t judge what is it supposed to do, while there are walidation errors. They tend to avalanche and screw the result in unpredictable way. In fact, they are “undefined behavior”, as in e.g. becoming conscious and soon after enslaving humanity :D.

that was it… thanks! that’s really embarrassing ^^