1 module armos.app.glfwwindow; 2 3 import armos.app; 4 import armos.events; 5 import derelict.opengl3.gl; 6 import armos.app.window; 7 import armos.math; 8 /++ 9 GLFWを利用したWindowです.armosではデフォルトでこのclassを元にWindowが生成されます. 10 +/ 11 class GLFWWindow : Window{ 12 import derelict.glfw3.glfw3; 13 mixin BaseWindow; 14 15 public{ 16 enum bool hasRenderer = true; 17 /++ 18 Params: 19 apprication = Windowとひも付けされるアプリケーションです. 20 +/ 21 this(BaseApp apprication, CoreEvents events, WindowConfig config){ 22 DerelictGL.load(); 23 DerelictGLFW3.load(); 24 25 if( !glfwInit() ){} 26 27 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, config.glVersionMajor); 28 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, config.glVersionMinor); 29 30 import armos.utils.semver; 31 if(config.glVersion >= SemVer("3.2.0")){ 32 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 33 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 34 } 35 36 _window = glfwCreateWindow(config.width, config.height, cast(char*)_name, null, null); 37 if(!_window){close;} 38 39 glfwMakeContextCurrent(_window); 40 41 if(config.glVersion >= SemVer("3.2.0")){ 42 DerelictGL3.reload(); 43 }else{ 44 DerelictGL.reload(); 45 } 46 47 initEvents(apprication, events); 48 initGLFWEvents(); 49 50 glfwSwapInterval(0); 51 glfwSwapBuffers(_window); 52 53 writeVersion; 54 } 55 56 void size(Vector2i size){ 57 glfwSetWindowSize(_window, size[0], size[1]); 58 } 59 60 /++ 61 Windowのサイズを返します. 62 +/ 63 Vector2i size()const{ 64 auto vec = Vector2i(); 65 glfwGetWindowSize(cast(GLFWwindow*)(_window), &vec[0], &vec[1]); 66 return vec; 67 } 68 69 /++ 70 Windowのframw bufferのサイズを返します. 71 +/ 72 Vector2i frameBufferSize()const{ 73 auto vec = Vector2i(); 74 glfwGetFramebufferSize(cast(GLFWwindow*)(_window), &vec[0], &vec[1]); 75 return vec; 76 } 77 78 /++ 79 イベントが発生している場合,登録されたイベントを実行します 80 +/ 81 void pollEvents(){ 82 glfwPollEvents(); 83 } 84 85 /++ 86 Windowを更新します. 87 +/ 88 void update(){ 89 // glFlush(); 90 // glFinish(); 91 glfwSwapBuffers(_window); 92 _shouldClose = cast(bool)glfwWindowShouldClose(_window); 93 } 94 95 /++ 96 Windowを閉じます. 97 +/ 98 void close(){ 99 _shouldClose = true; 100 glfwTerminate(); 101 } 102 103 void name(in string str){ 104 import std.string; 105 _name = str; 106 glfwSetWindowTitle(_window, str.toStringz); 107 } 108 109 void select(){ 110 glfwMakeContextCurrent(_window); 111 }; 112 113 /// VerticalSync 114 void verticalSync(in bool f){ 115 glfwSwapInterval(f); 116 }; 117 118 /// 119 float pixelScreenCoordScale()const{ 120 return frameBufferSize.x / size.x; 121 }; 122 }//public 123 124 private{ 125 GLFWwindow* _window; 126 127 static extern(C) void keyCallbackFunction(GLFWwindow* window, int key, int scancode, int action, int mods){ 128 import std.conv; 129 import armos.utils.keytype; 130 if(action == GLFW_PRESS){ 131 currentEvents.notifyKeyPressed(key.to!KeyType); 132 }else if(action == GLFW_RELEASE){ 133 currentEvents.notifyKeyReleased(key.to!KeyType); 134 } 135 } 136 137 static extern(C) void charCallbackFunction(GLFWwindow* window, uint key){ 138 currentEvents.notifyUnicodeInput(key); 139 // if(action == GLFW_PRESS){ 140 // currentEvents.notifyKeyPressed(key); 141 // }else if(action == GLFW_RELEASE){ 142 // currentEvents.notifyKeyReleased(key); 143 // } 144 } 145 146 static extern(C) void cursorPositionFunction(GLFWwindow* window, double xpos, double ypos){ 147 currentEvents.notifyMouseMoved(cast(int)xpos, cast(int)ypos, 0); 148 } 149 150 static extern(C ) void mouseButtonFunction(GLFWwindow* window, int button, int action, int mods){ 151 double xpos, ypos; 152 glfwGetCursorPos(window, &xpos, &ypos); 153 154 if(action == GLFW_PRESS){ 155 currentEvents.notifyMousePressed(cast(int)xpos, cast(int)ypos, button); 156 }else if(action == GLFW_RELEASE){ 157 currentEvents.notifyMouseReleased(cast(int)xpos, cast(int)ypos, button); 158 } 159 } 160 161 static extern(C ) void resizeWindowFunction(GLFWwindow* window, int width, int height){ 162 import armos.graphics; 163 currentRenderer.resize(); 164 currentEvents.notifyWindowResize(cast(int)width, cast(int)height); 165 } 166 167 void writeVersion(){ 168 import std.stdio, std.conv; 169 writefln("Vendor: %s", to!string(glGetString(GL_VENDOR))); 170 writefln("Renderer: %s", to!string(glGetString(GL_RENDERER))); 171 writefln("Version: %s", to!string(glGetString(GL_VERSION))); 172 writefln("GLSL: %s\n", to!string(glGetString(GL_SHADING_LANGUAGE_VERSION))); 173 }; 174 175 void initEvents(BaseApp app, CoreEvents events){ 176 assert(events); 177 addListener(events.windowResize, app, &app.windowResized); 178 addListener(events.keyPressed, app, &app.keyPressed); 179 addListener(events.keyReleased, app, &app.keyReleased); 180 addListener(events.mouseMoved, app, &app.mouseMoved); 181 addListener(events.mouseDragged, app, &app.mouseDragged); 182 addListener(events.mouseReleased, app, &app.mouseReleased); 183 addListener(events.mousePressed, app, &app.mousePressed); 184 addListener(events.unicodeInputted, app, &app.unicodeInputted); 185 186 import armos.utils:KeyType; 187 addListener(events.keyPressed, app, delegate(ref KeyPressedEventArg message){app.PressKey(message.key);}); 188 addListener(events.keyReleased, app, delegate(ref KeyReleasedEventArg message){app.ReleaseKey(message.key);}); 189 } 190 191 192 void initGLFWEvents(){ 193 // glfwSetKeyCallback(window, &keyCallbackFunction); 194 glfwSetKeyCallback(_window, cast(GLFWkeyfun)&keyCallbackFunction); 195 glfwSetCharCallback(_window, cast(GLFWcharfun)&charCallbackFunction); 196 glfwSetCursorPosCallback(_window, cast(GLFWcursorposfun)&cursorPositionFunction); 197 glfwSetMouseButtonCallback(_window, cast(GLFWmousebuttonfun)&mouseButtonFunction); 198 glfwSetWindowSizeCallback(_window, cast(GLFWwindowsizefun)&resizeWindowFunction); 199 } 200 }//private 201 }