~hikiko/nux/arb-srgba-shader

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
/*
 * Copyright 2010 Inalogic® Inc.
 *
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License, as
 * published by the  Free Software Foundation; either version 2.1 or 3.0
 * of the License.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranties of
 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the applicable version of the GNU Lesser General Public
 * License for more details.
 *
 * You should have received a copy of both the GNU Lesser General Public
 * License along with this program. If not, see <http://www.gnu.org/licenses/>
 *
 * Authored by: Jay Taoko <jaytaoko@inalogic.com>
 *
 */


#ifndef GRAPHICSDISPLAYWIN_H
#define GRAPHICSDISPLAYWIN_H

#include "Gfx_Interface.h"
#include "GLTimer.h"
#include "GLDeviceObjects.h"
#include "GLRenderStates.h"

#include <d2d1.h>
#include <d2d1helper.h>
#include <dwrite.h>
#include "Wincodec.h"


namespace nux
{

  class Event;
  class MainFBO;
  class GpuDevice;
  class GraphicsEngine;
  class IOpenGLFrameBufferObject;

  enum WindowStyle
  {
    WINDOWSTYLE_NORMAL,
    WINDOWSTYLE_PANEL,
    WINDOWSTYLE_DIALOG,
    WINDOWSTYLE_TOOL,
    WINDOWSTYLE_NOBORDER,
  };

#define NUX_THREADMSG                           (WM_APP+0)
#define NUX_THREADMSG_START_RENDERING           (WM_APP+1)  // Connection established // start at WM_APP
#define NUX_THREADMSG_CHILD_WINDOW_TERMINATED   (WM_APP+2)  // General failure - Wait Connection failed
#define NUX_THREADMSG_THREAD_TERMINATED         (WM_APP+3)  // Set wParam = Thread ID, lParam = 0

// This will become GLWindow
  class GraphicsDisplay : public GraphicSystem
  {
    friend class GraphicsEngine;

  private:

    // WIN32 system variables
    HGLRC       opengl_rendering_context_;  //!< OpenGL Rendering Context.
    HDC         device_context_;            //!< Device Context.
    HWND        wnd_handle_;                     //!< Window Handle.
    HWND        m_ParentWindow;

    char m_WindowClassName[256];
    GLuint      m_PixelFormat;      // Holds The Results After Searching For A Match
    DWORD       m_dwExStyle;        // Window Extended Style
    DWORD       m_dwStyle;          // Window Style
    NString     m_WindowTitle;

    static HGLRC sMainGLRC;         // Used as the first argument of wglShareLists to make all successive OpenGL  context share their objects
    static HDC   sMainDC;           // Used as the first argument of wglShareLists to make all successive OpenGL  context share their objects

    ID2D1Factory    *d2d_factory_;
    IDWriteFactory  *dw_factory_;
    IWICImagingFactory *wic_factory_;

    // size, position
    Size  m_ViewportSize;
    Size m_WindowSize;

    // surface attibute;
    bool m_fullscreen;
    unsigned int m_ScreenBitDepth;

    // verify that the interface is properly created
    bool m_GfxInterfaceCreated;

    // Device information
    void GetDisplayInfo();
    int m_index_of_current_mode;

    bool m_is_window_minimized;

    HCURSOR cursor_;

    static int Win32KeySymToINL(int Keysym);
    static int Win32VKToNuxKey(int vk);
  public:

    // Device
    int m_num_device_modes;

    // Event object
    Event *event_;

    // Creation
    bool IsGfxInterfaceCreated();

    //! Create a window with and OpenGL context.
    /*!
        @param WindowTitle      The window title.
        @param WindowWidth      Initial window width.
        @param WindowHeight     Initial window height.
        @param Style            The window style.
        @param ParentWindow     The parent window.
        @param FullscreenFlag   Full screen flag.
    */
    bool CreateOpenGLWindow(
      const char *WindowTitle,
      unsigned int WindowWidth,
      unsigned int WindowHeight,
      WindowStyle Style,
      const GraphicsDisplay *Parent,
      bool FullscreenFlag = false,
      bool create_rendering_data = true);

    //! Create a GLWindow from a window and device context.
    /*!
        @param WindowHandle     Provided window.
        @param WindowDCHandle   Provided device context.
        @param OpenGLRenderingContext   And OpenGL rendering context.
    */
    bool CreateFromOpenGLWindow(HWND WindowHandle, HDC WindowDCHandle, HGLRC OpenGLRenderingContext);

    void DestroyOpenGLWindow();

    void SetWindowTitle(const char *Title);
    void SetWindowSize(int width, int height);
    void SetViewPort(int x, int y, int width, int height);
    Point GetMouseScreenCoord();
    Point GetMouseWindowCoord();
    Point GetWindowCoord();
    Rect GetWindowGeometry();
    Rect GetNCWindowGeometry();
    void MakeGLContextCurrent(bool b = true);
    void SwapBuffer(bool glswap = true);

    // Event methods
    /*!
      Returns true if there was a pending event to be fetched and false otherwise
     */
    bool GetSystemEvent(Event *evt);
    Event &GetCurrentEvent();

    bool isWindowMinimized() const
    {
      return m_is_window_minimized;
    }

    void ShowWindow();
    void HideWindow();
    bool IsWindowVisible();

    void EnterMaximizeWindow();
    void ExitMaximizeWindow();

    HWND GetWindowHandle() const
    {
      return wnd_handle_;
    }
    HWND GetParentWindowHandle() const
    {
      return m_ParentWindow;
    }
    HDC GetWindowHDC() const
    {
      return device_context_;
    }
    bool IsChildWindow() const
    {
      return m_ParentWindow != 0;
    }

    ID2D1Factory* GetDirect2DFactory();
    IDWriteFactory* GetDirectWriteFactory();
    IWICImagingFactory* GetWICFactory();

    // Return true if VSync swap control is available
    bool HasVSyncSwapControl() const;
    void EnableVSyncSwapControl();
    void DisableVSyncSwapControl();

    // m_FrameRate
    float GetFrameTime() const;
    void ResetFrameTime();

    GraphicsEngine *GetGraphicsEngine() const;
    
    GpuDevice *GetGpuDevice() const;

    // Dialog
    bool StartOpenFileDialog(FileDialogOption &fdo);
    bool StartSaveFileDialog(FileDialogOption &fdo);
    bool StartColorDialog(ColorDialogOption &cdo);


    void GetWindowSize(int &w, int &h);
    int GetWindowWidth();
    int GetWindowHeight();

    //! Get the window size and reset the GraphicsEngine and GpuDevice accordingly.
    /*!
        This is a passive way to set the window size through out the NuxGraphics system. This call gets the 
        current window size and sets its accordingly to all sub-system.
    */
    void ResetWindowSize();

    bool HasFrameBufferSupport();
    void SetWindowCursor(HCURSOR cursor);
    HCURSOR GetWindowCursor() const;

    void ProcessForeignWin32Event(HWND hWnd, MSG msg, WPARAM wParam, LPARAM lParam, Event *event);
    LRESULT ProcessWin32Event(HWND hWnd, unsigned int uMsg, WPARAM wParam, LPARAM lParam);

    //! Pause graphics rendering.
    /*!
        Pause graphics rendering.
        This function also sets the current openGL context to 0 for this window.
        This is useful while a child window is being created and is sharing openGL objects with this context.
        For wglShareLists to work, both OpenGL context must be set to 0 in their respective thread.
        Send NUX_THREADMSG_START_RENDERING(PostThreadMessage) to this window to reactivate rendering.

        Never call this function while doing rendering. Call it only when processing events.
    */
    void PauseThreadGraphicsRendering();
    bool IsPauseThreadGraphicsRendering() const;

    // Pointer and keyboard grab API
    typedef void(*GrabReleaseCallback) (bool replaced, void *user_data);

    bool GrabPointer   (GrabReleaseCallback callback, void *data, bool replace_existing);
    bool UngrabPointer(void *data);
    bool PointerIsGrabbed();

    bool GrabKeyboard   (GrabReleaseCallback callback, void *data, bool replace_existing);
    bool UngrabKeyboard(void *data);
    bool KeyboardIsGrabbed();

    void * KeyboardGrabData() { return _global_keyboard_grab_data; }
    void * PointerGrabData() { return _global_pointer_grab_data; }

  private:
    void InitGlobalGrabWindow();

    bool m_PauseGraphicsRendering;
    GLTimer m_Timer;
    float m_FrameTime;
    GpuDevice *m_DeviceFactory;
    GraphicsEngine *m_GraphicsContext;
    WindowStyle m_Style;

    HWND                _global_grab_window;

    void               *_global_pointer_grab_data;
    bool                _global_pointer_grab_active;
    GrabReleaseCallback _global_pointer_grab_callback;

    void               *_global_keyboard_grab_data;
    bool                _global_keyboard_grab_active;
    GrabReleaseCallback _global_keyboard_grab_callback;


  public:
    ~GraphicsDisplay();
    GLEWContext *GetGLEWContext()
    {
      return &m_GLEWContext;
    }
    WGLEWContext *GetWGLEWContext()
    {
      return &m_WGLEWContext;
    }

  private:
    GraphicsDisplay();
    GraphicsDisplay(const GraphicsDisplay &);
    // Does not make sense for a singleton. This is a self assignment.
    GraphicsDisplay &operator= (const GraphicsDisplay &);


    GLEWContext m_GLEWContext;
    WGLEWContext m_WGLEWContext;
    friend class DisplayAccessController;
  };

  LRESULT CALLBACK WndProcManager(HWND    hWnd,          // Handle For This Window
                                   unsigned int   uMsg,           // Message For This Window
                                   WPARAM  wParam,         // Additional Message Information
                                   LPARAM  lParam);        // Additional Message Information

}

#endif //GRAPHICSDISPLAYWIN_H