GLViewNew.cpp

huangsw, 2014-08-08 10:14

Download (14.2 kB)

 
1
//
2
//  GLViewNew.cpp
3
//  
4
//
5
//  Created by huangshiwu on 14-7-18.
6
//
7
//
8

    
9
#include "GLViewNew.h"
10

    
11
NS_CC_BEGIN
12

    
13
//////////////////////////////////////////////////////////////////////////
14
// implement GLViewNew
15
//////////////////////////////////////////////////////////////////////////
16

    
17
//set the Render Context pixel format
18
static bool SetupPixelFormat(HDC hDC)
19
{
20
        int pixelFormat;
21

    
22
        PIXELFORMATDESCRIPTOR pfd =
23
        {
24
                sizeof(PIXELFORMATDESCRIPTOR),  // size
25
                1,                          // version
26
                PFD_SUPPORT_OPENGL |        // OpenGL window
27
                PFD_DRAW_TO_WINDOW |        // render to window
28
                PFD_DOUBLEBUFFER,           // support double-buffering
29
                PFD_TYPE_RGBA,              // color type
30
                32,                         // preferred color depth
31
                0, 0, 0, 0, 0, 0,           // color bits (ignored)
32
                0,                          // no alpha buffer
33
                0,                          // alpha bits (ignored)
34
                0,                          // no accumulation buffer
35
                0, 0, 0, 0,                 // accum bits (ignored)
36
                24,                         // depth buffer
37
                8,                          // no stencil buffer
38
                0,                          // no auxiliary buffers
39
                PFD_MAIN_PLANE,             // main layer
40
                0,                          // reserved
41
                0, 0, 0,                    // no layer, visible, damage masks
42
        };
43

    
44
        //pixelFormat = ChoosePixelFormat(hDC, &pfd);
45
        if (!(pixelFormat = ChoosePixelFormat(hDC, &pfd)))
46
    { 
47
                MessageBoxA(nullptr, "Can't find suitable display mode", "Error", MB_OK);
48
        return FALSE;
49
    }
50
        SetPixelFormat(hDC, pixelFormat, &pfd);
51

    
52
        return true;
53
}
54

    
55
static GLViewNew* _mainWindow = NULL;
56
static const WCHAR* kWindowClassName = L"Cocos2dxWin32";
57
//LRESULT WINAPI MsgProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam );
58
/* main window procedure */ 
59
static LONG MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
60
{ 
61
    LONG    lRet = 1;  
62
    //RECT rect;
63
        HDC _hDC = wglGetCurrentDC();
64
        HGLRC _hRC = wglGetCurrentContext();
65
 
66
    switch (uMsg) { 
67
 
68
        case WM_LBUTTONDOWN:
69
        if (MK_LBUTTON == wParam)
70
        {
71
            POINT point = {(short)LOWORD(lParam), (short)HIWORD(lParam)};
72
            Vec2 pt(point.x, point.y);
73
            Vec2 tmp(pt.x, _mainWindow->_screenSize.height - pt.y);
74
            if (_mainWindow->getViewPortRect().equals(Rect::ZERO) || _mainWindow->getViewPortRect().containsPoint(tmp))
75
            {
76
                _mainWindow->_captured = true;
77
                SetCapture(hWnd);
78
                int id = 0;
79
                _mainWindow->handleTouchesBegin(1, &id, &pt.x, &pt.y);
80
            }
81
        }
82
        break;
83

    
84
        case WM_MOUSEMOVE:
85
        if (MK_LBUTTON == wParam && _mainWindow->_captured)
86
        {
87
            POINT point = {(short)LOWORD(lParam), (short)HIWORD(lParam)};
88
            Vec2 pt(point.x, point.y);
89
            int id = 0;
90
            _mainWindow->handleTouchesMove(1, &id, &pt.x, &pt.y);
91
        }
92
        break;
93

    
94
        case WM_LBUTTONUP:
95
        if (_mainWindow->_captured)
96
        {
97
            POINT point = {(short)LOWORD(lParam), (short)HIWORD(lParam)};
98
            Vec2 pt(point.x, point.y);
99
            int id = 0;
100
            _mainWindow->handleTouchesEnd(1, &id, &pt.x, &pt.y);
101

    
102
            ReleaseCapture();
103
            _mainWindow->_captured = false;
104
        }
105
        break;
106
 
107
    case WM_PAINT:
108
                PAINTSTRUCT ps;
109
        BeginPaint(hWnd, &ps); 
110
        EndPaint(hWnd, &ps); 
111
        break; 
112
 
113
    case WM_SIZE: 
114
                RECT cntrect;
115
        GetClientRect(hWnd, &cntrect); 
116
                _mainWindow->updateFrameSize(cntrect.right - cntrect.left, cntrect.bottom - cntrect.top); 
117
        break;
118

    
119
    case WM_ERASEBKGND:
120
                break;
121

    
122
    //if close the window manually,let function windowShouldClose() return true to eixt the loop in Application::run()
123
    case WM_CLOSE: 
124
                _mainWindow->_hWnd = NULL;
125
                break;
126
 
127
    case WM_DESTROY: 
128
        if (_hRC) 
129
            wglDeleteContext(_hRC); 
130
        if (_hDC) 
131
            ReleaseDC(hWnd, _hDC); 
132
        PostQuitMessage (0); 
133
        break; 
134
 
135
    default: 
136
        lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); 
137
        break; 
138
    } 
139
 
140
    return lRet; 
141
} 
142

    
143
GLViewNew::GLViewNew()
144
: _hWnd(NULL)
145
, _hDC(NULL)
146
, _hRC(NULL)
147
, _captured(false)
148
{
149
        _viewName = "cocos2dx";
150
        _mainWindow = this;
151
}
152

    
153
GLViewNew::~GLViewNew()
154
{
155
    CCLOGINFO("deallocing GLViewNew: %p", this);
156
    
157
}
158

    
159
GLViewNew* GLViewNew::create(const std::string& viewName)
160
{
161
    auto ret = new GLViewNew();
162
    if(ret && ret->initWithRect(viewName, Rect(100, 100, 960, 640))) 
163
        {                
164
        ret->autorelease();
165
        return ret;
166
    }
167
    
168
    return nullptr;
169
}
170

    
171
bool GLViewNew::initWithRect(const std::string& viewName, Rect rect)
172
{
173
    setViewName(viewName);
174

    
175
        //MSG        msg; 
176
    WNDCLASS   wndclass;
177
        HINSTANCE hInstance = GetModuleHandle( NULL );
178
 
179
    /* Register the frame class */ 
180
    wndclass.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; 
181
    wndclass.lpfnWndProc   = (WNDPROC)MainWndProc; 
182
    wndclass.cbClsExtra    = 0; 
183
    wndclass.cbWndExtra    = 0; 
184
    wndclass.hInstance     = hInstance; 
185
    wndclass.hIcon         = LoadIcon (NULL, IDI_WINLOGO); 
186
    wndclass.hCursor       = LoadCursor (NULL,IDC_ARROW); 
187
    wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 
188
        wndclass.lpszMenuName  = NULL; 
189
        wndclass.lpszClassName = kWindowClassName; 
190
 
191
    if (!RegisterClass (&wndclass) ) 
192
        return FALSE; 
193
 
194
        WCHAR wszBuf[50] = {0};
195
        MultiByteToWideChar(CP_UTF8, 0, _viewName.c_str(), -1, wszBuf, sizeof(wszBuf));
196
    /* Create the frame */ 
197
        _hWnd = CreateWindow (
198
                     kWindowClassName, // Class Name
199
                     wszBuf,  // Window Title
200
             WS_OVERLAPPEDWINDOW, //Window Style
201
                         rect.origin.x,   //Window position
202
                         rect.origin.y, 
203
                         rect.size.width, 
204
                         rect.size.height, 
205
             NULL, // No Parent Window
206
             NULL, // No Menu
207
             hInstance, // Instance
208
             NULL);
209
 
210
    /* make sure window was created */ 
211
    if (!_hWnd) 
212
        return FALSE; 
213

    
214
        _hDC = GetDC(_hWnd); 
215
    if (!SetupPixelFormat(_hDC)) 
216
        PostQuitMessage (0); 
217
 
218
    _hRC = wglCreateContext(_hDC); 
219
    wglMakeCurrent(_hDC, _hRC);
220
               
221
        /* show and update main window */ 
222
    ShowWindow( _hWnd, SW_SHOWDEFAULT );
223
    UpdateWindow (_hWnd); 
224

    
225
        //the rect refers to the size of the window, so we need to 
226
        //obtain the dimension of the client area as the rendering environment size
227
        RECT winrect;
228
        GetClientRect(_hWnd, &winrect);
229
        setFrameSize(winrect.right - winrect.left, winrect.bottom - winrect.top);
230
    
231
    // check OpenGL version at first
232
    const GLubyte* glVersion = glGetString(GL_VERSION);   
233
    if ( atof((const char*)glVersion) < 1.5 )
234
    {
235
        char strComplain[256] = {0};
236
        sprintf(strComplain,
237
                "OpenGL 1.5 or higher is required (your version is %s). Please upgrade the driver of your video card.",
238
                glVersion);
239
                MessageBoxA(nullptr, strComplain, "OpenGL version too old", MB_OK);
240
        return false;
241
    }
242
    initGlew();    
243
    // Enable point size by default.
244
    glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
245
    
246
    return true;
247
}
248

    
249
HWND GLViewNew::getWin32Window()
250
{
251
        return _hWnd;
252
}
253

    
254
bool GLViewNew::isOpenGLReady()
255
{
256
    if (_hWnd != NULL)
257
        {
258
                return true;
259
        }
260
        else
261
                return false;
262
}
263

    
264
void GLViewNew::end()
265
{
266
        if(_hWnd)
267
    {
268
                DestroyWindow(_hWnd);
269
        _hWnd = NULL;
270
    }
271
        _mainWindow = NULL;
272
    UnregisterClass(kWindowClassName, GetModuleHandle(NULL));
273
    // Release self. Otherwise, GLView could not be freed.
274
    release();
275
}
276

    
277
void GLViewNew::swapBuffers()
278
{
279
        if(_hWnd != NULL)
280
        {
281
                SwapBuffers(_hDC);
282
        }
283
}
284

    
285
//in Application::run(),the windowShouldClose is used as the cycle condition        
286
bool GLViewNew::windowShouldClose()
287
{
288
        if(NULL == _hWnd)
289
        {
290
                return true;
291
        }
292
        else
293
        {
294
                return false;
295
        }
296
}
297

    
298
void GLViewNew::pollEvents()
299
{
300
        MSG msg;
301
    while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) == TRUE) 
302
    { 
303
        if (GetMessage(&msg, NULL, 0, 0) ) 
304
        { 
305
            TranslateMessage(&msg); 
306
            DispatchMessage(&msg); 
307
        } 
308
                else 
309
                {  
310
        } 
311
    } 
312
}
313

    
314
void GLViewNew::setIMEKeyboardState(bool /*bOpen*/)
315
{
316
    
317
}
318

    
319
void GLViewNew::updateFrameSize(float width, float height)
320
{
321
        _screenSize = Size(width, height);
322
        updateDesignResolutionSize();
323
}
324

    
325
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
326
static bool glew_dynamic_binding()
327
{
328
    const char *gl_extensions = (const char*)glGetString(GL_EXTENSIONS);
329
    
330
    // If the current opengl driver doesn't have framebuffers methods, check if an extension exists
331
    if (glGenFramebuffers == nullptr)
332
    {
333
        log("OpenGL: glGenFramebuffers is nullptr, try to detect an extension");
334
        if (strstr(gl_extensions, "ARB_framebuffer_object"))
335
        {
336
            log("OpenGL: ARB_framebuffer_object is supported");
337
            
338
            glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) wglGetProcAddress("glIsRenderbuffer");
339
            glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) wglGetProcAddress("glBindRenderbuffer");
340
            glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) wglGetProcAddress("glDeleteRenderbuffers");
341
            glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) wglGetProcAddress("glGenRenderbuffers");
342
            glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) wglGetProcAddress("glRenderbufferStorage");
343
            glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) wglGetProcAddress("glGetRenderbufferParameteriv");
344
            glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) wglGetProcAddress("glIsFramebuffer");
345
            glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) wglGetProcAddress("glBindFramebuffer");
346
            glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) wglGetProcAddress("glDeleteFramebuffers");
347
            glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) wglGetProcAddress("glGenFramebuffers");
348
            glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) wglGetProcAddress("glCheckFramebufferStatus");
349
            glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC) wglGetProcAddress("glFramebufferTexture1D");
350
            glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) wglGetProcAddress("glFramebufferTexture2D");
351
            glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC) wglGetProcAddress("glFramebufferTexture3D");
352
            glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) wglGetProcAddress("glFramebufferRenderbuffer");
353
            glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) wglGetProcAddress("glGetFramebufferAttachmentParameteriv");
354
            glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) wglGetProcAddress("glGenerateMipmap");
355
        }
356
        else
357
            if (strstr(gl_extensions, "EXT_framebuffer_object"))
358
            {
359
                log("OpenGL: EXT_framebuffer_object is supported");
360
                glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) wglGetProcAddress("glIsRenderbufferEXT");
361
                glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) wglGetProcAddress("glBindRenderbufferEXT");
362
                glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) wglGetProcAddress("glDeleteRenderbuffersEXT");
363
                glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) wglGetProcAddress("glGenRenderbuffersEXT");
364
                glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) wglGetProcAddress("glRenderbufferStorageEXT");
365
                glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) wglGetProcAddress("glGetRenderbufferParameterivEXT");
366
                glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) wglGetProcAddress("glIsFramebufferEXT");
367
                glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) wglGetProcAddress("glBindFramebufferEXT");
368
                glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) wglGetProcAddress("glDeleteFramebuffersEXT");
369
                glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) wglGetProcAddress("glGenFramebuffersEXT");
370
                glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) wglGetProcAddress("glCheckFramebufferStatusEXT");
371
                glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC) wglGetProcAddress("glFramebufferTexture1DEXT");
372
                glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) wglGetProcAddress("glFramebufferTexture2DEXT");
373
                glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC) wglGetProcAddress("glFramebufferTexture3DEXT");
374
                glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) wglGetProcAddress("glFramebufferRenderbufferEXT");
375
                glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) wglGetProcAddress("glGetFramebufferAttachmentParameterivEXT");
376
                glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) wglGetProcAddress("glGenerateMipmapEXT");
377
            }
378
            else
379
            {
380
                log("OpenGL: No framebuffers extension is supported");
381
                log("OpenGL: Any call to Fbo will crash!");
382
                return false;
383
            }
384
    }
385
    return true;
386
}
387
#endif
388

    
389
// helper
390
bool GLViewNew::initGlew()
391
{
392
#if (CC_TARGET_PLATFORM != CC_PLATFORM_MAC)
393
    GLenum GlewInitResult = glewInit();
394
    if (GLEW_OK != GlewInitResult)
395
    {
396
                MessageBoxA(nullptr, (char *)glewGetErrorString(GlewInitResult), "OpenGL error", MB_OK);
397
        return false;
398
    }
399
    
400
    if (GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader)
401
    {
402
        log("Ready for GLSL");
403
    }
404
    else
405
    {
406
        log("Not totally ready :(");
407
    }
408
    
409
    if (glewIsSupported("GL_VERSION_2_0"))
410
    {
411
        log("Ready for OpenGL 2.0");
412
    }
413
    else
414
    {
415
        log("OpenGL 2.0 not supported");
416
    }
417
    
418
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
419
    if(glew_dynamic_binding() == false)
420
    {
421
                MessageBoxA(nullptr, "No OpenGL framebuffer support. Please upgrade the driver of your video card.", "OpenGL error", MB_OK);
422
        return false;
423
    }
424
#endif
425
    
426
#endif // (CC_TARGET_PLATFORM != CC_PLATFORM_MAC)
427
    
428
    return true;
429
}
430

    
431
NS_CC_END // end of namespace cocos2d;

Sign up for our newsletter to keep up with the latest developments, releases and updates for Cocos2d-x.