• Content count

  • Joined

  • Last visited

Community Reputation

134 Neutral

About Hedanito

  • Rank
  1. Thanks guys, it seems that undefining new is the way to go. I just have a define and undefine header now, and the define header is automatically included with the memory manager. It is not the prettiest solution, but since placement new is so rare I can live with it.
  2. So I have this memory tracer I wrote a while back which has worked perfectly since then. It works by overwriting new, delete, malloc, etc and a static manager class will keep track of everything Basically like this: void* operator new (Core::uintp a_Size, const Core::char8* a_File, Core::uint32 a_Line); void* operator new[] (Core::uintp a_Size, const Core::char8* a_File, Core::uint32 a_Line); void operator delete (void *a_Memory, const Core::char8* a_File, Core::uint32 a_Line); void operator delete[] (void *a_Memory, const Core::char8* a_File, Core::uint32 a_Line); void operator delete (void *a_Memory); void operator delete[] (void *a_Memory); #define malloc(a_Size) MemoryTracer::Malloc(a_Size, __FILE__, __LINE__) #define realloc(a_Memory, a_Size) MemoryTracer::Realloc(a_Memory, a_Size, __FILE__, __LINE__) #define calloc(a_Count, a_Size) MemoryTracer::Calloc(a_Count, a_Size, __FILE__, __LINE__) #define free(a_Memory) MemoryTracer::Free(a_Memory, __FILE__, __LINE__) #define new new(__FILE__, __LINE__) #define delete MemoryTracer::SetFreeInfo(__FILE__, __LINE__), delete This worked fine for pretty much everything, until now. I am currently writing a container class which has to use placement new. The #define new new(__FILE__, __LINE__) messes up the placement new syntax. Another problem is that placement new cannot be overwritten.   I am not sure what the best solution is for this problem, so I was hoping you guys could give me some suggestions. Since the placement new doesn't allocate any memory, the solution does not have to involve the memory tracer. I just want to keep the syntax as close to normal C++ as possible.
  3. After a lot more searching I finally found the source of the bug. Apparently, the moment I make the window visible it starts sending messages to StaticWndProc, without me calling PeekMessage. This in turn starts triggering events (not Windows Events, but my event system), which in turn request information about the window. But all of this is still happening in the constructor of the window object. So the pointer to the window which it requests information from has not yet been set. Then it tries to do things with the invalid window pointer, and voila, memory corruption.   I now simply fixed it with a bool to make sure the constructor has been completed.   I do find it weird though that it didnt crash sooner, because the pointer was set to 0. Usually accessing 0 immediately results in a crash.
  4. So as the title says, I get memory corruptions when I create window frames, specificly when I make the frame visible. Once I make the window visible, either using the ShowWindow function, or setting the WS_VISIBLE style flag, it somehow corrupts memory, and can cause crashes in classes I used before that. It doesnt seem to have anything to do with the OpenGL context either. Everything works perfectly right until I make the window visible.   I am no expert in the windows API, so I have no idea what I am doing wrong. I hope I just forgot to set something somewhere, because this bug has been haunting me for a while. Or maybe you can give me some tips on tracking down the source of the problem.   Window class code: #include <set> #include <Windows.h> #include <GL/GL.h> #include <GL/wglext.h> #include "eventmanager.h" #include "windowflag.h" #include "window.h" using namespace Core; using namespace Base; using namespace Gfx; using namespace Wnd; struct Window::Window_Impl {     Window_Impl(Window* a_Window);     ~Window_Impl();     bool CreateFrame(const vector2i& a_Position, const vector2i& a_Size, const char8* a_Caption, uint32 a_Flags);     bool DestroyFrame();     bool CreateWindowClass();     bool DestroyWindowClass();     bool CreateContext(const GraphicsLibrary& a_GraphicsLibrary);     bool CreateContextOpenGL2(const GraphicsLibrary& a_GraphicsLibrary);     bool CreateContextOpenGL3(const GraphicsLibrary& a_GraphicsLibrary);     bool CreateContextOpenGL4(const GraphicsLibrary& a_GraphicsLibrary);     bool CreateContextDirectX9(const GraphicsLibrary& a_GraphicsLibrary);     bool CreateContextDirectX10(const GraphicsLibrary& a_GraphicsLibrary);     bool CreateContextDirectX11(const GraphicsLibrary& a_GraphicsLibrary);     static LRESULT CALLBACK StaticWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);     LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);     RECT CalculateFrameRectangle(const vector2i& a_Position, const vector2i& a_Size, uint32 a_Flags) const;     DWORD GetStyleFromFlags(uint32 a_Flags) const;     DWORD GetStyleExFromFlags(uint32 a_Flags) const;     uint32 GetFlagsFromStyle(DWORD a_Style, DWORD a_StyleEx) const;     HINSTANCE m_HINSTANCE;     HWND m_HWND;     HDC m_HDC;     HGLRC m_HGLRC;          static std::set<HGLRC> m_HGLRCList;     Window* m_Window;     char8 m_CaptionBuffer[0xFF];     GraphicsLibrary m_GraphicsLibrary;     static uint32 m_WindowCounter;     static char8* m_WindowClassName; }; uint32 Window::Window_Impl::m_WindowCounter = 0; char8* Window::Window_Impl::m_WindowClassName = 0; std::set<HGLRC> Window::Window_Impl::m_HGLRCList = std::set<HGLRC>(); Window::Window(const vector2i& a_Position, const vector2i& a_Size, const char8* a_Caption, uint32 a_Flags, const GraphicsLibrary& a_GraphicsLibrary) {     Logger::Log(CORE_WINDOW_CHANNEL, VB_INSTANTIATION, "Creating Window...");     Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Creating private implementation...");     m_Impl = new Window_Impl(this);     Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Private implementation created.");     if (!m_Impl->CreateFrame(a_Position, a_Size, a_Caption, a_Flags))     {         Logger::Log(CORE_WINDOW_CHANNEL, VB_INSTANTIATION, "Failed to create Window.");         return;     }     if (!m_Impl->CreateContext(a_GraphicsLibrary))     {         Logger::Log(CORE_WINDOW_CHANNEL, VB_INSTANTIATION, "Failed to create Window.");         return;     }          Logger::Log(CORE_WINDOW_CHANNEL, VB_INSTANTIATION, "Window created."); } Window::~Window() {     Logger::Log(CORE_WINDOW_CHANNEL, VB_INSTANTIATION, "Destroying Window...");     m_Impl->DestroyFrame();     Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Deleting private implementation...");     delete m_Impl;     Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Private implementation deleted.");          Logger::Log(CORE_WINDOW_CHANNEL, VB_INSTANTIATION, "Window destroyed."); } vector2i Window::GetPosition() const {     if (m_Impl->m_HWND != NULL)     {         POINT point;         point.x = 0;         point.y = 0;         if (!ClientToScreen(m_Impl->m_HWND, &point))         {             Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to get Window position.", GetLastError());             return vector2i();         }         return vector2i(point.x, point.y);     }     else     {         return vector2i();     } } vector2i Window::GetSize() const {     if (m_Impl->m_HWND != NULL)     {         RECT rect;         if (!GetClientRect(m_Impl->m_HWND, &rect))         {             Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to get Window size.", GetLastError());             return vector2i();         }         return vector2i(rect.right - rect.left, rect.bottom - rect.top);     }     else     {         return vector2i();     } } const char8* Window::GetCaption() const {     if (m_Impl->m_HWND != NULL)     {         if (GetWindowText(m_Impl->m_HWND, m_Impl->m_CaptionBuffer, 0xFF) == 0)         {             Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to get Window caption.", GetLastError());             return 0;         }         return m_Impl->m_CaptionBuffer;     }     return 0; } uint32 Window::GetFlags() const {     if (m_Impl->m_HWND != NULL)     {         LONG style = GetWindowLong(m_Impl->m_HWND, GWL_STYLE);         LONG exstyle = GetWindowLong(m_Impl->m_HWND, GWL_EXSTYLE);         return m_Impl->GetFlagsFromStyle(style, exstyle);     }     else     {         return 0;     } } const GraphicsLibrary& Window::GetGraphicsLibrary() const {     return m_Impl->m_GraphicsLibrary; } void Window::SetPosition(const vector2i& a_Position) {     if (m_Impl->m_HWND != 0)     {         RECT rect = m_Impl->CalculateFrameRectangle(a_Position, GetSize(), GetFlags());         if (!SetWindowPos(m_Impl->m_HWND, 0, rect.left, rect.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE))         {             Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to set Window size.", GetLastError());         }     } } void Window::SetSize(const vector2i& a_Size) {     if (m_Impl->m_HWND != NULL)     {         RECT rect = m_Impl->CalculateFrameRectangle(GetPosition(), a_Size, GetFlags());         if (!SetWindowPos(m_Impl->m_HWND, 0, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_NOMOVE))         {             Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to set Window size.", GetLastError());         }     } } void Window::SetCaption(const char8* a_Caption) {     if (m_Impl->m_HWND != NULL)     {         if (!SetWindowText(m_Impl->m_HWND, a_Caption))         {             Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to set Window caption.", GetLastError());         }     } } void Window::SetFlags(uint32 a_Flags) {     if (m_Impl->m_HWND != NULL)     {         vector2i position = GetPosition();         vector2i size = GetSize();         SetWindowLong(m_Impl->m_HWND, GWL_STYLE, m_Impl->GetStyleFromFlags(a_Flags));         SetWindowLong(m_Impl->m_HWND, GWL_EXSTYLE, m_Impl->GetStyleExFromFlags(a_Flags));         SetPosition(position);         SetSize(size);         ShowWindow(m_Impl->m_HWND, SW_SHOW);         UpdateWindow(m_Impl->m_HWND);     } } void Window::SetAsRenderTarget() {     if (m_Impl->m_HWND == NULL)     {         return;     }     switch (m_Impl->m_GraphicsLibrary.m_Type)     {         case GLT_NONE:         break;         case GLT_OPENGL:         if (!wglMakeCurrent(m_Impl->m_HDC, m_Impl->m_HGLRC))         {             Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to set Window as target.", GetLastError());             return;         }         break;         case GLT_DIRECTX:         #define CORE_COMPILER_MESSAGE "TODO: SetAsTarget DirectX"         #include "compilermessage.h"         break;         default:         Logger::Error(CORE_WINDOW_CHANNEL, "Failed to set Window as target", "Unknown or unsupported Graphics Library (%i).", m_Impl->m_GraphicsLibrary.m_Type);         break;     } } void Window::Update() {     if (m_Impl->m_HWND == 0)     {         return;     }     MSG msg;     while (PeekMessage(&msg, m_Impl->m_HWND, 0, 0, PM_REMOVE))     {         TranslateMessage(&msg);         DispatchMessage(&msg);     }     return; } void Window::SwapBuffers() {     switch (m_Impl->m_GraphicsLibrary.m_Type)     {         case GLT_NONE:         break;         case GLT_OPENGL:         if (!::SwapBuffers(m_Impl->m_HDC))         {             Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to swap buffers.", GetLastError());             return;         }         break;         case GLT_DIRECTX:         #define CORE_COMPILER_MESSAGE "TODO: implement SwapBuffers for DirectX"         #include "compilermessage.h"         break;         default:         Logger::Error(CORE_WINDOW_CHANNEL,  "Failed to swap buffers", "Unknown or unsupported Graphics Library (%i).", m_Impl->m_GraphicsLibrary.m_Type);         break;     } } Window::Window_Impl::Window_Impl(Window* a_Window):     m_Window(a_Window),     m_HWND(NULL) {     m_HINSTANCE = GetModuleHandle(NULL); } Window::Window_Impl::~Window_Impl() { } bool Window::Window_Impl::CreateFrame(const vector2i& a_Position, const vector2i& a_Size, const char8* a_Caption, uint32 a_Flags) {     Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Creating Window frame...");     if (!CreateWindowClass())     {         Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Failed to create Window frame.");         return false;     }     RECT rect = CalculateFrameRectangle(a_Position, a_Size, a_Flags);     m_HWND = CreateWindowEx(GetStyleExFromFlags(a_Flags), m_WindowClassName, a_Caption, GetStyleFromFlags(a_Flags),                             rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, m_HINSTANCE, this);     if (m_HWND == NULL)     {         Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to create Windows frame.", GetLastError());         return false;     }     Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Window frame created.");          Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Getting device context..");     m_HDC = GetDC(m_HWND);     if (m_HDC == NULL)     {         Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to get device context.", GetLastError());         return false;     }     Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Device context received.");          return true; } bool Window::Window_Impl::DestroyFrame() {     if (m_HWND != NULL)     {         Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Destroying Window frame...");         if (!DestroyWindow(m_HWND))         {             Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to destroy Window frame", GetLastError());             return false;         }         Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Window frame destroyed.");     }     return DestroyWindowClass(); } bool Window::Window_Impl::CreateWindowClass() {     if (m_WindowCounter == 0)     {         Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Creating Window class...");         const uint32 classnamesize = strlen("windowclass") + 1;         m_WindowClassName = new char8[classnamesize];         strcpy_s(m_WindowClassName, classnamesize, "windowclass");         WNDCLASSEX windowclass;         memset(&windowclass, 0, sizeof(WNDCLASSEX));         windowclass.cbSize        = sizeof(WNDCLASSEX);         windowclass.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_GLOBALCLASS;         windowclass.lpfnWndProc   = StaticWndProc;         windowclass.hInstance     = m_HINSTANCE;         windowclass.hCursor       = LoadCursor(NULL, IDC_ARROW);         windowclass.lpszClassName = m_WindowClassName;         Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Registering Window class...");         if (!RegisterClassEx(&windowclass))         {             Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to register Window class", GetLastError());             Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Failed to create Window class");             return false;         }         Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Window class registered.");         Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Window class created.");     }     m_WindowCounter++;     return true; } bool Window::Window_Impl::DestroyWindowClass() {     m_WindowCounter--;     bool result = true;     if (m_WindowCounter == 0)     {         Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Destroying Window class...");         Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Unregistering Window class");         if (UnregisterClass(m_WindowClassName, m_HINSTANCE) == 0)         {             Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to unregister Window class.", GetLastError());             result = false;         }         else         {             Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Window class unregistered.");         }         delete[] m_WindowClassName;         m_WindowClassName = 0;         if (result)         {             Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Window class destroyed.");             return true;         }         else         {             Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Failed to destroy Window class.");             return false;         }     }     return true; } bool Window::Window_Impl::CreateContext(const GraphicsLibrary& a_GraphicsLibrary) {     switch (a_GraphicsLibrary.m_Type)     {         case GLT_NONE:         return true;         case GLT_OPENGL:         switch (a_GraphicsLibrary.m_VersionMajor)         {             case 4:             if (CreateContextOpenGL4(a_GraphicsLibrary))             {                 return true;             }             Logger::Warning(CORE_WINDOW_CHANNEL, "Failed to initialize OpenGL 4.x.", "Failed to initialize OpenGL 4.x. Falling back to OpenGL 3.x.");             case 3:             if (CreateContextOpenGL3(a_GraphicsLibrary))             {                 return true;             }             Logger::Warning(CORE_WINDOW_CHANNEL, "Failed to initialize OpenGL 3.x.", "Failed to initialize OpenGL 3.x. Falling back to OpenGL 2.x or lower.");             case 2:             case 1:             case 0:             return CreateContextOpenGL2(a_GraphicsLibrary);             default:             Logger::Error(CORE_WINDOW_CHANNEL, "Failed to create OpenGL context.", "Unknown OpenGL version: %i.%i", a_GraphicsLibrary.m_VersionMajor, a_GraphicsLibrary.m_VersionMinor);             return false;         }         case GLT_DIRECTX:         switch (a_GraphicsLibrary.m_VersionMajor)         {             case 11:             if (CreateContextDirectX11(a_GraphicsLibrary))             {                 return true;             }             Logger::Warning(CORE_WINDOW_CHANNEL, "Failed to initialize DirectX 11.", "Failed to initialize DirectX 11.x. Falling back to DirectX 10.x.");             case 10:             if (CreateContextDirectX10(a_GraphicsLibrary))             {                 return true;             }             Logger::Warning(CORE_WINDOW_CHANNEL, "Failed to initialize DirectX 10.", "Failed to initialize DirectX 10.x. Falling back to DirectX 9.x.");             case 9:             return CreateContextDirectX9(a_GraphicsLibrary);             default:             Logger::Error(CORE_WINDOW_CHANNEL, "Failed to create DirectX context.", "Unknown DirectX version: %i.%i", a_GraphicsLibrary.m_VersionMajor, a_GraphicsLibrary.m_VersionMinor);             return false;         }         break;         default:         Logger::Error(CORE_WINDOW_CHANNEL, "Unknown or unsupported Graphics Library. (%i)", "Failed to create context", a_GraphicsLibrary.m_Type);         return false;     } } bool Window::Window_Impl::CreateContextOpenGL2(const GraphicsLibrary& a_GraphicsLibrary) {     Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Creating OpenGL 2.x or lower context...");          Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Choosing pixel format...");     PIXELFORMATDESCRIPTOR pfd =     {         sizeof(PIXELFORMATDESCRIPTOR),         1,         PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,         PFD_TYPE_RGBA,         32,         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,         24,         8,         0,         PFD_MAIN_PLANE,         0, 0, 0, 0     };     int32 pfn = ChoosePixelFormat(m_HDC, &pfd);     if (pfn == 0)     {         Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to create an OpenGL 2.x or lower context", GetLastError());         return false;     }     Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Pixel format chosen.");     Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Setting pixel format...");     if (!SetPixelFormat(m_HDC, pfn, &pfd))     {         Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to create an OpenGL 2.x or lower context", GetLastError());         return false;     }     Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Pixel format set.");     Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Creating OpenGL context...");     m_HGLRC = wglCreateContext(m_HDC);     if (m_HGLRC == 0)     {         Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to create an OpenGL 2.x or lower context", GetLastError());         return false;     }     Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "OpenGL context created.");     Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "Making OpenGL context current...");     if (!wglMakeCurrent(m_HDC, m_HGLRC))     {         Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to create an OpenGL 2.x or lower context", GetLastError());         return false;     }     Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "OpenGL made current.");     Logger::Log(CORE_WINDOW_CHANNEL, VB_OTHER, "OpenGL %i.%i context created.", a_GraphicsLibrary.m_VersionMajor, a_GraphicsLibrary.m_VersionMinor);     m_GraphicsLibrary = a_GraphicsLibrary;     if (m_HGLRCList.size() != 0)     {         wglShareLists(*(m_HGLRCList.begin()), m_HGLRC);     }     m_HGLRCList.insert(m_HGLRC);     return true; } bool Window::Window_Impl::CreateContextOpenGL3(const GraphicsLibrary& a_GraphicsLibrary) {     #define CORE_COMPILER_MESSAGE "TODO: implement Window::Window_Impl::CreateContextOpenGL3"     #include "compilermessage.h"     return false; } bool Window::Window_Impl::CreateContextOpenGL4(const GraphicsLibrary& a_GraphicsLibrary) {     #define CORE_COMPILER_MESSAGE "TODO: implement Window::Window_Impl::CreateContextOpenGL4"     #include "compilermessage.h"     return false; } bool Window::Window_Impl::CreateContextDirectX9(const GraphicsLibrary& a_GraphicsLibrary) {     #define CORE_COMPILER_MESSAGE "TODO: implement Window::Window_Impl::CreateContextDirectX9"     #include "compilermessage.h"     return false; } bool Window::Window_Impl::CreateContextDirectX10(const GraphicsLibrary& a_GraphicsLibrary) {     #define CORE_COMPILER_MESSAGE "TODO: implement Window::Window_Impl::CreateContextDirextX10"     #include "compilermessage.h"     return false; } bool Window::Window_Impl::CreateContextDirectX11(const GraphicsLibrary& a_GraphicsLibrary) {     #define CORE_COMPILER_MESSAGE "TODO: implement Window::Window_Impl::CreateContextDirextX11"     #include "compilermessage.h"     return false; } LRESULT CALLBACK Window::Window_Impl::StaticWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam) {     Window_Impl* wnd_impl = NULL;     if (msg == WM_CREATE)     {         wnd_impl = (Window_Impl*)(((LPCREATESTRUCT)lParam)->lpCreateParams);         #if CORE_PLATFORM_BITS == 32         SetWindowLongPtr(hwnd, GWL_USERDATA, (LONG_PTR)wnd_impl);         #endif         #if CORE_PLATFORM_BITS == 64         SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)wnd_impl);         #endif     }     else     {         #if CORE_PLATFORM_BITS == 32         wnd_impl = (Window_Impl*)GetWindowLongPtr(hwnd, GWL_USERDATA);         #endif         #if CORE_PLATFORM_BITS == 64         wnd_impl = (Window_Impl*)GetWindowLongPtr(hwnd, GWLP_USERDATA);         #endif         if (!wnd_impl)         {             return DefWindowProc(hwnd, msg, wParam, lParam);             }     }     return wnd_impl->WndProc(hwnd, msg, wParam, lParam); } LRESULT CALLBACK Window::Window_Impl::WndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam) {     switch (msg)     {         case WM_SIZE:         EventManager::Event("window", "resize", m_Window);         break;                  case WM_MOVE:         EventManager::Event("window", "move", m_Window);         break;         case WM_CLOSE:         EventManager::Event("window", "close", m_Window);         return 0;         case WM_INPUT:         EventManager::Event("window", "input", ((HRAWINPUT)lParam));         break;     }     return DefWindowProc(hwnd, msg, wParam, lParam); } RECT Window::Window_Impl::CalculateFrameRectangle(const vector2i& a_Position, const vector2i& a_Size, uint32 a_Flags) const {     RECT rect;     rect.left = a_Position.x;     rect.top = a_Position.y;     rect.right = a_Position.x + a_Size.x;     rect.bottom = a_Position.y + a_Size.y;     if (!AdjustWindowRectEx(&rect, GetStyleFromFlags(a_Flags), false, GetStyleExFromFlags(a_Flags)))     {         Logger::ErrorWindows(CORE_WINDOW_CHANNEL, "Failed to adjust window rect.", GetLastError());     }     return rect; } DWORD Window::Window_Impl::GetStyleFromFlags(uint32 a_Flags) const {     DWORD style = WS_VISIBLE;     if ((a_Flags & WF_NOFRAME) != 0)     {         style |= WS_POPUP;     }     if ((a_Flags & WF_RESIZE) != 0)     {         style |= WS_MAXIMIZEBOX;         style |= WS_THICKFRAME;     }     if ((a_Flags & WF_NOFRAME) == 0)     {         style |= WS_CAPTION;         if ((a_Flags & WF_NOSYSMENU) == 0)         {             style |= WS_SYSMENU;             style |= WS_MINIMIZEBOX;         }     }          return style; } DWORD Window::Window_Impl::GetStyleExFromFlags(uint32 a_Flags) const {     DWORD style = 0;          if ((a_Flags & WF_WINDOWS_TOOL) != 0)     {         style |= WS_EX_TOOLWINDOW;     }     if ((a_Flags & WF_TOPMOST) != 0)     {         style |= WS_EX_TOPMOST;     }     return style; } uint32 Window::Window_Impl::GetFlagsFromStyle(DWORD a_Style, DWORD a_StyleEx) const {     uint32 flags = 0;     if ((a_Style & WS_THICKFRAME) != 0)     {         flags |= WF_RESIZE;     }     if ((a_Style & WS_CAPTION) == 0)     {         flags |= WF_NOFRAME;     }     if ((a_Style & WS_SYSMENU) == 0)     {         flags |= WF_NOSYSMENU;     }     if ((a_StyleEx & WS_EX_TOOLWINDOW) != 0)     {         flags |= WF_WINDOWS_TOOL;     }     if ((a_StyleEx & WS_EX_TOPMOST) != 0)     {         flags |= WF_TOPMOST;     }     return flags; } I've had this bug for a while and mostly worked around it, but I really want to get rid of it. Right now I just do as little as possible before creating the window and then hope it doesn't crash.  
  5. You have to call it once for every light, with glBlendFunc(GL_ONE, GL_ONE) so that it adds the results together.
  6. Unregistering Raw Input

    So when having multiple window frames, I'll have to register every time the window focus changes?
  7. So I am changing my input system from directinput to raw input, because I want multi mouse/keyboard support. I've figured out most parts, but I have trouble getting one major part right. I have 2 classes, an inputmanager and a window class. The window class just creates a basic frame in which I can draw etc. The inputmanager, as the name suggests, manages all the input. Instances of the window class can be registered at the inputmanager, which will then register the raw input devices, and peek for input messages every frame. A requirement for this is that the window class ignores all WM_INPUT messages (does not remove them from the message que). If it does not do this, input messages sometimes leak through between the inputmanager peeking for messages and the processing of the window message que, even if they are called right after each other. This is not acceptable for a game engine, so the window just ignores the WM_INPUT messages. This is works fine and all, until I tell the input manager to stop tracking input on that window. The window is still ignoring all the WM_INPUT messages, while the inputmanager does not pop them anymore. So basically the message queue just starts filling up with WM_INPUT messages and no one takes them out. Now the best solution of course would be to just unregister the devices so that they stop sending WM_INPUT messages and everything acts just like it did before I registered them, but this does not seem to be possible. I am unable to find a function that does this. The closest thing I could find was RIDEV_REMOVE, but this does not do anything related to the window, and I am uncertain how much it actually affects. So what I need is: Something to unregister raw input devices. or Some other solution to this problem that doesn't mess up the architecture without any leaks. A requirement is that the window does not have to know if it is being tracked at the moment. OS: Windows Language: C++
  8. Winsock Multiprocess Issues

    Yes that seemed to be the problem. Changing some settings in CreateProcess fixed the problem. Thank you for your help.
  9. Winsock Multiprocess Issues

    After some more debugging I think I have found at least where it goes wrong (but still no idea why). For some reason the sockets keeps hanging around when a process is launched from the game. I tried starting notepad from the game, and then shutting the game down, and everything will think that the socket still exists. The moment I shut down notepad however everything goes back to normal. Now I played around a LOT with shutting down the socket. I tried pretty much every way and step in between to shut it down, but none of them seem to fix the problem. Even resetting everything everywhere, including calling WSAStartup and WSAShutdown does not seem to help.
  10. So I have this really weird bug with I have been trying to fix for the past 3 days. I basically have 2 applications, one is the game, the other one is an editor. I connect them together so I can send data around. The game has a listening socket and the editors just try to connect to it every once in a few seconds. This works fine, but there is this really weird and specific bug. I have the option to launch an instance of the editor from the game. When I do this (using anything from sytem to CreateProcess, I tried them all), the editor launches and connects as expected. When I then shut down the game the editor loses connection. But here is where it gets weird. For some reason the next time it tries to connect, it succeeds. Even though the game is not running. Then it disconnects because it doesn't receive any ping message (because there is no game to send them) and thinks that it has timed out. After that, it reconnects again. And it just keeps doing this over and over. And this just happens when I start the process from the game. When I launch the editor seperately, this does not happen, and everything works perfectly. So I hope that any of you have any idea what is going on here, because I really don't know anymore.
  11. I am currently working on a software rasterizer as a school assignment. I started with copying image buffers to the screen, but the performance is already terrible. At the moment I tried both glDrawPixels and copying the data to a texture and then drawing a quad on screen with that texture. Sending data to the GPU every frame is just so incredibly slow. I've had this same problem before with a software raytracer and I'm getting tired of it. Something so simple should not take up so much of your application's performance. So here is my question: What is the fastest way of getting my image data on the screen? I'm willing to go all out. I don't care which API I have to use as long as it works on Windows. So I don't mind whether it's OpenGL, DirectX or even the Windows API. So the only restrictions are: - Works on Windows - Uses C++ So if you know a quick way of doing this, or even just an idea of something that might be worth a try, please tell me.
  12. Instancing memory management

    I guess my understanding of smart pointers was wrong. A shared pointer indeed seems to be a good solution.
  13. Instancing memory management

    [quote name='fastcall22' timestamp='1300387785' post='4787121'] Have you considered using [url="http://en.wikipedia.org/wiki/Smart_pointer"]smart pointers[/url]? [/quote] What do smart pointers have to do with instancing? From what know smart pointers are simple classes with a pointer as a member variable which has been put on the stack, and that way it gets deleted automatically when going out of scope, and when being deleted the class also deletes the pointer. First of all, this has nothing to do with my problem. Secondly, when you would use this on instancing, for example, 2 entities with the same mesh, and both entities get deleted, which entity will delete the mesh? It's not very hard to manage with just meshes and entities as these are big objects and there probably isn't a lot of them. But when you get a bigger tree, like entity -> mesh -> material -> texture, things get messy. Also, when I for example load a material file, it automatically loads a texture, because the texture file path is stored in the material file. Same goes for a mesh, it stores the material that has to be attached to it. The programmer would then have to delete something that he has never told the program to create.
  14. Well the title pretty much explains it. How should I handle memory when using instancing. Who owns what, who gets to delete stuff, etc. I do have a resource manager that uses handles, but for performance reasons I kept it as a wrapper, so that if you really need the performance, you can just do it your own way. The objects also interact without using the resource manager when they own each other in some kind of way. But that still leaves the problem when two objects own the same thing. For example, 2 entities own 1 mesh. Is there a good way to not have to make the programmer pay attention to every single piece of memory, not use all kinds of managers in between objects, and not let the memory dangle until the application shuts down. To me, there seems to be no perfect solution, but I would like to hear some other thoughts about this.
  15. [quote name='KriScg' timestamp='1295799724' post='4763463'] [quote name='Hedanito' timestamp='1295793888' post='4763425'] I still find it very vague. Also it interpolates 2 vertices instead of 3. Right now I just take the barycentric coordinates, multiply each vertex uv by them, and I then add those together. This gives the standard dent in your texture effect. So what do I multiply, divide, whatever it is, the uv's with before I multiply them with the barycentric coordinates, and also very important, how do I get the correct value back afterwards? [/quote] v1,v2,v3 - 3 triangle vertices b1,b2,b3 - barycentric coordinates for appropriate vertices [code] w' = ( 1 / v1.w ) * b1 + ( 1 / v2.w ) * b2 + ( 1 / v3.w ) * b3 u' = ( v1.u / v1.w ) * b1 + ( v2.u / v2.w ) * b2 + ( v3.u / v3.w ) * b3 v' = ... perspCorrU = u' / w' perspCorrV = v' / w' [/code] Keep in mind, that this is a very slow approach. It can be optimized by using deltas and it's enough to interpolate between two points. Everything should be explained in any paper/tutorial about half space triangle rasterization. [/quote] Thank you, that was a very clear and simple explaination. Fixed it in like 30 sec and it worked right away =D [img]http://img121.imageshack.us/img121/5458/cube2l.png[/img]