From 2f042c3e95e6b43d1642cf403b5f127c3b41b83a Mon Sep 17 00:00:00 2001 From: Omar Mohamed Ali Mudhir Date: Wed, 25 Jan 2017 09:15:22 +0000 Subject: [PATCH] added resizing to osx window --- .gitignore | 2 +- engine.xcodeproj/project.pbxproj | 36 ++++++++++-- engine/app.cpp | 11 ++-- engine/main.cpp | 94 ++++++++++++++++++++++++++++++-- engine/pch.h | 1 + engine/shape.cpp | 2 +- engine/shape.hpp | 2 +- 7 files changed, 127 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index ca32d89..f0e21dd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ xcuserdata libs - +xcshareddata/ x64/ .vs/ engine.vcxproj.user diff --git a/engine.xcodeproj/project.pbxproj b/engine.xcodeproj/project.pbxproj index b3acb5f..369d2c2 100644 --- a/engine.xcodeproj/project.pbxproj +++ b/engine.xcodeproj/project.pbxproj @@ -18,6 +18,9 @@ AD58E06B1E2A774F006ACC15 /* texture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD58E0691E2A774F006ACC15 /* texture.cpp */; }; AD58E06F1E2A80BC006ACC15 /* shape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD58E06D1E2A80BC006ACC15 /* shape.cpp */; }; AD58E0721E2A90EF006ACC15 /* app.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD58E0701E2A90EF006ACC15 /* app.cpp */; }; + AD58E0761E3421F2006ACC15 /* YGNodeList.c in Sources */ = {isa = PBXBuildFile; fileRef = AD58E0741E3421F2006ACC15 /* YGNodeList.c */; }; + AD58E0771E3421F2006ACC15 /* Yoga.c in Sources */ = {isa = PBXBuildFile; fileRef = AD58E0751E3421F2006ACC15 /* Yoga.c */; }; + AD58E0791E342205006ACC15 /* tinyxml2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD58E0781E342205006ACC15 /* tinyxml2.cpp */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -52,6 +55,9 @@ AD58E06E1E2A80BC006ACC15 /* shape.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = shape.hpp; sourceTree = ""; }; AD58E0701E2A90EF006ACC15 /* app.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = app.cpp; sourceTree = ""; }; AD58E0711E2A90EF006ACC15 /* app.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = app.hpp; sourceTree = ""; }; + AD58E0741E3421F2006ACC15 /* YGNodeList.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = YGNodeList.c; path = libs/yoga/yoga/YGNodeList.c; sourceTree = ""; }; + AD58E0751E3421F2006ACC15 /* Yoga.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Yoga.c; path = libs/yoga/yoga/Yoga.c; sourceTree = ""; }; + AD58E0781E342205006ACC15 /* tinyxml2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tinyxml2.cpp; path = libs/tinyxml2/tinyxml2.cpp; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -72,6 +78,7 @@ AD58E0461E107411006ACC15 = { isa = PBXGroup; children = ( + AD58E0731E3421CB006ACC15 /* libs */, AD58E0611E17F23D006ACC15 /* data */, AD58E05F1E12DA86006ACC15 /* CoreVideo.framework */, AD58E05D1E10754F006ACC15 /* CoreFoundation.framework */, @@ -109,6 +116,16 @@ path = engine; sourceTree = ""; }; + AD58E0731E3421CB006ACC15 /* libs */ = { + isa = PBXGroup; + children = ( + AD58E0781E342205006ACC15 /* tinyxml2.cpp */, + AD58E0741E3421F2006ACC15 /* YGNodeList.c */, + AD58E0751E3421F2006ACC15 /* Yoga.c */, + ); + name = libs; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -165,12 +182,15 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + AD58E0791E342205006ACC15 /* tinyxml2.cpp in Sources */, AD58E06F1E2A80BC006ACC15 /* shape.cpp in Sources */, AD58E0651E2A76FD006ACC15 /* shader.cpp in Sources */, + AD58E0761E3421F2006ACC15 /* YGNodeList.c in Sources */, AD58E06B1E2A774F006ACC15 /* texture.cpp in Sources */, AD58E0721E2A90EF006ACC15 /* app.cpp in Sources */, AD58E0531E107411006ACC15 /* main.cpp in Sources */, AD58E0681E2A7741006ACC15 /* image.cpp in Sources */, + AD58E0771E3421F2006ACC15 /* Yoga.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -181,7 +201,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LANGUAGE_STANDARD = "c++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; @@ -215,8 +235,10 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ( - /opt/local/include, - libs, + libs/stb, + libs/glm, + libs/yoga, + libs/tinyxml2, ); MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = YES; @@ -229,7 +251,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LANGUAGE_STANDARD = "c++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; @@ -257,8 +279,10 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ( - /opt/local/include, - libs, + libs/stb, + libs/glm, + libs/yoga, + libs/tinyxml2, ); MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = NO; diff --git a/engine/app.cpp b/engine/app.cpp index 9a1038c..43ffb18 100644 --- a/engine/app.cpp +++ b/engine/app.cpp @@ -85,7 +85,7 @@ void App::load_layout() std::stack stack; tinyxml2::XMLDocument xml; - auto ret = xml.LoadFile("data\\layout.xml"); + auto ret = xml.LoadFile("data/layout.xml"); auto x_root = xml.RootElement(); NodePair current = { y_root, x_root }; @@ -299,6 +299,7 @@ void App::init() " frag = col;" "}"; +#ifdef _WIN32 static CONSOLE_SCREEN_BUFFER_INFO info; GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info); // colors: http://stackoverflow.com/questions/4053837/colorizing-text-in-the-console-with-c @@ -317,7 +318,8 @@ void App::init() SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), info.wAttributes); }, nullptr); glEnable(GL_DEBUG_OUTPUT); - +#endif + load_layout(); for (auto& s : shapes_list) @@ -431,10 +433,6 @@ void App::update(float dt) glEnable(GL_SCISSOR_TEST); glScissor(box.x, height - box.y - 1 - box.w, box.z, box.w); } - else - { - glDisable(GL_SCISSOR_TEST); - } //glScissor(10, height - 10 - 1 - 50, 480, 50); glm::mat4 pivot = glm::translate(glm::vec3(.5f, .5f, 0.f)); @@ -455,6 +453,7 @@ void App::update(float dt) shader_color.use(); shader_color.u_mat4("mvp", mvp); plane.draw_stroke(); + glDisable(GL_SCISSOR_TEST); } tex.unbind(); sampler.unbind(); diff --git a/engine/main.cpp b/engine/main.cpp index 236b0d1..169ba50 100644 --- a/engine/main.cpp +++ b/engine/main.cpp @@ -85,10 +85,18 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime // Add your drawing codes here [[self openGLContext] makeCurrentContext]; + // We draw on a secondary thread through the display link + // When resizing the view, -reshape is called automatically on the main + // thread. Add a mutex around to avoid the threads accessing the context + // simultaneously when resizing + CGLLockContext([[self openGLContext] CGLContextObj]); App::I.update(now - _prevTime); - [[self openGLContext] flushBuffer]; + //[[self openGLContext] flushBuffer]; // returning NO will cause the layer to NOT be redrawn + + CGLFlushDrawable([[self openGLContext] CGLContextObj]); + CGLUnlockContext([[self openGLContext] CGLContextObj]); return NO; } else @@ -111,6 +119,78 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime - (void)drawRect:(NSRect)dirtyRect { NSLog(@"drawRect"); + // Add your drawing codes here + [[self openGLContext] makeCurrentContext]; + + // We draw on a secondary thread through the display link + // When resizing the view, -reshape is called automatically on the main + // thread. Add a mutex around to avoid the threads accessing the context + // simultaneously when resizing + CGLLockContext([[self openGLContext] CGLContextObj]); + App::I.update(0); + + //[[self openGLContext] flushBuffer]; + // returning NO will cause the layer to NOT be redrawn + + CGLFlushDrawable([[self openGLContext] CGLContextObj]); + CGLUnlockContext([[self openGLContext] CGLContextObj]); +} + +- (void)reshape +{ + [super reshape]; + + // We draw on a secondary thread through the display link. However, when + // resizing the view, -drawRect is called on the main thread. + // Add a mutex around to avoid the threads accessing the context + // simultaneously when resizing. + CGLLockContext([[self openGLContext] CGLContextObj]); + + // Get the view size in Points + NSRect viewRectPoints = [self bounds]; + +#if SUPPORT_RETINA_RESOLUTION + + // Rendering at retina resolutions will reduce aliasing, but at the potential + // cost of framerate and battery life due to the GPU needing to render more + // pixels. + + // Any calculations the renderer does which use pixel dimentions, must be + // in "retina" space. [NSView convertRectToBacking] converts point sizes + // to pixel sizes. Thus the renderer gets the size in pixels, not points, + // so that it can set it's viewport and perform and other pixel based + // calculations appropriately. + // viewRectPixels will be larger than viewRectPoints for retina displays. + // viewRectPixels will be the same as viewRectPoints for non-retina displays + NSRect viewRectPixels = [self convertRectToBacking:viewRectPoints]; + +#else //if !SUPPORT_RETINA_RESOLUTION + + // App will typically render faster and use less power rendering at + // non-retina resolutions since the GPU needs to render less pixels. + // There is the cost of more aliasing, but it will be no-worse than + // on a Mac without a retina display. + + // Points:Pixels is always 1:1 when not supporting retina resolutions + NSRect viewRectPixels = viewRectPoints; + +#endif // !SUPPORT_RETINA_RESOLUTION + App::I.resize(viewRectPixels.size.width, viewRectPixels.size.height); + + CGLUnlockContext([[self openGLContext] CGLContextObj]); +} +- (void)renewGState +{ + // Called whenever graphics state updated (such as window resize) + + // OpenGL rendering is not synchronous with other rendering on the OSX. + // Therefore, call disableScreenUpdatesUntilFlush so the window server + // doesn't render non-OpenGL content in the window asynchronously from + // OpenGL content, which could cause flickering. (non-OpenGL content + // includes the title bar and drawing done by the app with other APIs) + [[self window] disableScreenUpdatesUntilFlush]; + + [super renewGState]; } @end @@ -122,7 +202,7 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime } @end -@interface Controller : NSWindowController +@interface Controller : NSWindowController @end @implementation Controller - (void)keyDown:(NSEvent *)theEvent { @@ -131,6 +211,10 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime { [[NSApplication sharedApplication] terminate:nil]; } +} +- (void)windowDidResize:(NSNotification *)notification +{ + } @end @@ -156,10 +240,8 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime view = [[View alloc] initWithFrame:r]; - window = [[Window alloc] initWithContentRect:r - styleMask:NSTitledWindowMask|NSMiniaturizableWindowMask - backing:NSBackingStoreBuffered - defer:NO]; + auto style = NSTitledWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask; + window = [[Window alloc] initWithContentRect:r styleMask:style backing:NSBackingStoreBuffered defer:NO]; [window setTitle:@"hello engine - ui shapes"]; [window center]; [window makeKeyAndOrderFront:controller]; diff --git a/engine/pch.h b/engine/pch.h index 7c7d3bb..038b910 100644 --- a/engine/pch.h +++ b/engine/pch.h @@ -2,6 +2,7 @@ #ifdef __APPLE__ #include + #include #elif _WIN32 #define _USE_MATH_DEFINES #include diff --git a/engine/shape.cpp b/engine/shape.cpp index 7455e68..bdf5ff3 100644 --- a/engine/shape.cpp +++ b/engine/shape.cpp @@ -45,7 +45,7 @@ void Shape::draw_stroke() const glBindVertexArray(0); } -bool Rect::create(float w, float h) +bool RectShape::create(float w, float h) { static GLushort idx[6 + 8] { 0, 1, 2, diff --git a/engine/shape.hpp b/engine/shape.hpp index 364f755..9119286 100644 --- a/engine/shape.hpp +++ b/engine/shape.hpp @@ -178,7 +178,7 @@ public: } }; -class Rect : public Shape +class RectShape : public Shape { bool create(float w, float h); };