Create a window on Windows

FossilOrigin-Name: bf625526315ec71308288cbf7e91dc425ca1dd9e4e762a4c264cf2235c06558e
This commit is contained in:
Jonathan Schleifer 2022-12-27 19:00:12 +00:00
parent 3ffafe1164
commit 6ed1bf1eff
6 changed files with 129 additions and 3 deletions

View file

@ -10,7 +10,8 @@ LIB_MINOR = ${OBJ3DENGINE_LIB_MINOR}
SRCS = O3DEngine.m \
O3DGlide3Renderer.m \
O3DRenderer.m
O3DRenderer.m \
O3DWinAPIWindow.m
INCLUDES := ${SRCS:.m=.h}
OBJS_EXTRA = ${EXCEPTIONS_EXCEPTIONS_A}

View file

@ -19,9 +19,14 @@
OF_ASSUME_NONNULL_BEGIN
@class O3DWinAPIWindow;
@interface O3DGlide3Renderer: OFObject <O3DRenderer>
{
GrResolution _resolution;
#ifdef OF_WINDOWS
O3DWinAPIWindow *_winAPIWindow;
#endif
GrContext_t _context;
}
@end

View file

@ -14,6 +14,7 @@
*/
#import "O3DGlide3Renderer.h"
#import "O3DWinAPIWindow.h"
static OFSize
screenResolutionToSize(GrScreenResolution_t resolution)
@ -214,6 +215,10 @@ floatToScreenRefresh(float refresh)
grGlideShutdown();
#ifdef OF_WINDOWS
[_winAPIWindow release];
#endif
[super dealloc];
}
@ -269,6 +274,9 @@ floatToScreenRefresh(float refresh)
- (void)createWithResolution: (O3DResolution)resolution
{
if (_context != 0)
@throw [OFAlreadyOpenException exceptionWithObject: self];
GrScreenResolution_t screenResolution =
sizeToScreenResolution([resolution.firstObject sizeValue]);
GrScreenRefresh_t screenRefresh =
@ -278,7 +286,14 @@ floatToScreenRefresh(float refresh)
screenRefresh == GR_REFRESH_NONE)
@throw [OFInvalidArgumentException exception];
if ((_context = grSstWinOpen(0, screenRefresh, screenRefresh,
FxU32 hWnd = 0;
#ifdef OF_WINDOWS
_winAPIWindow = [[O3DWinAPIWindow alloc]
initWithSize: [resolution.firstObject sizeValue]];
hWnd = (FxU32)_winAPIWindow.hWnd;
#endif
if ((_context = grSstWinOpen(hWnd, screenRefresh, screenRefresh,
GR_COLORFORMAT_RGBA, GR_ORIGIN_LOWER_LEFT, 2, 1)) == 0)
@throw [OFInitializationFailedException
exceptionWithClass: self.class];

32
src/O3DWinAPIWindow.h Normal file
View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 2022 Jonathan Schleifer <js@nil.im>
*
* All rights reserved.
*
* This file is part of Obj3DEngine. It may be distributed under the terms of
* the Q Public License 1.0, which can be found in the file LICENSE.QPL
* included in the packaging of this file.
*
* Alternatively, it may be distributed under the terms of the GNU General
* Public License, either version 2 or 3, which can be found in the file
* LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of
* this file.
*/
#import <ObjFW/ObjFW.h>
#ifdef OF_WINDOWS
# include <windows.h>
@interface O3DWinAPIWindow: OFObject
{
WNDCLASS _wndClass;
HWND _hWnd;
}
@property (readonly, nonatomic) HWND hWnd;
- (instancetype)initWithSize: (OFSize)size;
- (instancetype)init OF_UNAVAILABLE;
@end
#endif

73
src/O3DWinAPIWindow.m Normal file
View file

@ -0,0 +1,73 @@
/*
* Copyright (c) 2022 Jonathan Schleifer <js@nil.im>
*
* All rights reserved.
*
* This file is part of Obj3DEngine. It may be distributed under the terms of
* the Q Public License 1.0, which can be found in the file LICENSE.QPL
* included in the packaging of this file.
*
* Alternatively, it may be distributed under the terms of the GNU General
* Public License, either version 2 or 3, which can be found in the file
* LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of
* this file.
*/
#import "O3DWinAPIWindow.h"
#ifdef OF_WINDOWS
# include <winuser.h>
@implementation O3DWinAPIWindow
@synthesize hWnd = _hWnd;
- (instancetype)initWithSize: (OFSize)size
{
self = [super init];
@try {
_wndClass = (WNDCLASS){
.lpfnWndProc = (WNDPROC)DefWindowProc,
.hInstance = GetModuleHandle(NULL),
.lpszClassName = "O3DMainWindowClass"
};
if (!RegisterClass(&_wndClass))
@throw [OFInitializationFailedException
exceptionWithClass: self.class];
if ((_hWnd = CreateWindowEx(WS_EX_APPWINDOW,
_wndClass.lpszClassName, "O3DMainWindow", WS_OVERLAPPED,
CW_USEDEFAULT, CW_USEDEFAULT, size.width, size.height,
NULL, NULL, _wndClass.hInstance, NULL)) == NULL)
@throw [OFInitializationFailedException
exceptionWithClass: self.class];
ShowWindow(_hWnd, SW_NORMAL);
UpdateWindow(_hWnd);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (instancetype)init
{
OF_INVALID_INIT_METHOD
}
- (void)dealloc
{
if (_hWnd != NULL)
OFEnsure(DestroyWindow(_hWnd));
if (_wndClass.lpszClassName != NULL)
OFEnsure(UnregisterClass(
_wndClass.lpszClassName, _wndClass.hInstance));
[super dealloc];
}
@end
#endif