Add initial O3DEngine and O3DRenderer

Only supports querying resolutions so far.

FossilOrigin-Name: c504ea5dd9a25bfe49c16f256d64f3bf8c16fc78fa03c2cad2561fbbb10eb720
This commit is contained in:
Jonathan Schleifer 2022-12-25 16:37:58 +00:00
parent 1c7dfe8b27
commit 3902165c96
8 changed files with 355 additions and 0 deletions

View file

@ -8,6 +8,9 @@ FRAMEWORK = ${OBJ3DENGINE_FRAMEWORK}
LIB_MAJOR = ${OBJ3DENGINE_LIB_MAJOR}
LIB_MINOR = ${OBJ3DENGINE_LIB_MINOR}
SRCS = O3DEngine.m \
O3DGlide3Renderer.m \
O3DRenderer.m
INCLUDES := ${SRCS:.m=.h}
OBJS_EXTRA = ${EXCEPTIONS_EXCEPTIONS_A}

36
src/O3DEngine.h Normal file
View file

@ -0,0 +1,36 @@
/*
* 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>
#import "O3DRenderer.h"
OF_ASSUME_NONNULL_BEGIN
@interface O3DEngine: OFObject
{
id <O3DRenderer> _renderer;
}
@property (readonly, nonatomic) id <O3DRenderer> renderer;
+ (OFArray OF_GENERIC(Class <O3DRenderer>) *)availableRenderers;
- (instancetype)initWithRenderer: (Class <O3DRenderer>)renderer
options: (nullable OFDictionary
OF_GENERIC(OFString *, id) *)options;
@end
OF_ASSUME_NONNULL_END

49
src/O3DEngine.m Normal file
View file

@ -0,0 +1,49 @@
/*
* 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 "O3DEngine.h"
#import "O3DGlide3Renderer.h"
@implementation O3DEngine
@synthesize renderer = _renderer;
+ (OFArray OF_GENERIC(Class <O3DRenderer>) *)availableRenderers
{
return [OFArray arrayWithObject: [O3DGlide3Renderer class]];
}
- (instancetype)
initWithRenderer: (Class <O3DRenderer>)renderer
options: (OFDictionary OF_GENERIC(OFString *, id) *)options
{
self = [super init];
@try {
_renderer = [[renderer alloc] initWithOptions: options];
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
[_renderer release];
[super dealloc];
}
@end

23
src/O3DGlide3Renderer.h Normal file
View file

@ -0,0 +1,23 @@
/*
* 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 "O3DRenderer.h"
OF_ASSUME_NONNULL_BEGIN
@interface O3DGlide3Renderer: OFObject <O3DRenderer>
@end
OF_ASSUME_NONNULL_END

178
src/O3DGlide3Renderer.m Normal file
View file

@ -0,0 +1,178 @@
/*
* 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.
*/
#include <glide.h>
#import "O3DGlide3Renderer.h"
static OFSize
resolutionToSize(GrScreenResolution_t resolution)
{
switch (resolution) {
case GR_RESOLUTION_320x200:
return OFMakeSize(320, 200);
case GR_RESOLUTION_320x240:
return OFMakeSize(320, 240);
case GR_RESOLUTION_400x256:
return OFMakeSize(400, 256);
case GR_RESOLUTION_512x384:
return OFMakeSize(512, 384);
case GR_RESOLUTION_640x200:
return OFMakeSize(640, 200);
case GR_RESOLUTION_640x350:
return OFMakeSize(640, 350);
case GR_RESOLUTION_640x400:
return OFMakeSize(640, 400);
case GR_RESOLUTION_640x480:
return OFMakeSize(640, 480);
case GR_RESOLUTION_800x600:
return OFMakeSize(800, 600);
case GR_RESOLUTION_960x720:
return OFMakeSize(960, 720);
case GR_RESOLUTION_856x480:
return OFMakeSize(856, 480);
case GR_RESOLUTION_512x256:
return OFMakeSize(512, 256);
case GR_RESOLUTION_1024x768:
return OFMakeSize(1024, 768);
case GR_RESOLUTION_1280x1024:
return OFMakeSize(1280, 1024);
case GR_RESOLUTION_1600x1200:
return OFMakeSize(1600, 1200);
case GR_RESOLUTION_400x300:
return OFMakeSize(400, 300);
case GR_RESOLUTION_1152x864:
return OFMakeSize(1152, 864);
case GR_RESOLUTION_1280x960:
return OFMakeSize(1280, 960);
case GR_RESOLUTION_1600x1024:
return OFMakeSize(1600, 1024);
case GR_RESOLUTION_1792x1344:
return OFMakeSize(1792, 1344);
case GR_RESOLUTION_1856x1392:
return OFMakeSize(1856, 1392);
case GR_RESOLUTION_1920x1440:
return OFMakeSize(1920, 1440);
case GR_RESOLUTION_2048x1536:
return OFMakeSize(2048, 1536);
case GR_RESOLUTION_2048x2048:
return OFMakeSize(2048, 2048);
default:
return OFMakeSize(0, 0);
}
}
static float
refreshEnumToFloat(GrScreenRefresh_t refresh)
{
switch (refresh) {
case GR_REFRESH_60Hz:
return 60;
case GR_REFRESH_70Hz:
return 70;
case GR_REFRESH_72Hz:
return 72;
case GR_REFRESH_75Hz:
return 75;
case GR_REFRESH_80Hz:
return 80;
case GR_REFRESH_90Hz:
return 90;
case GR_REFRESH_100Hz:
return 100;
case GR_REFRESH_85Hz:
return 85;
case GR_REFRESH_120Hz:
return 120;
default:
return 0;
}
}
@implementation O3DGlide3Renderer
- (instancetype)initWithOptions:
(OFDictionary OF_GENERIC(OFString *, id) *)options
{
self = [super init];
@try {
long long deviceIndex = [[options objectForKey:
O3DRendererDeviceIndex] longLongValue];
FxI32 numDevices;
grGlideInit();
if (!grGet(GR_NUM_BOARDS, sizeof(numDevices), &numDevices))
@throw [OFInitializationFailedException exception];
if (deviceIndex > numDevices)
@throw [OFInvalidArgumentException exception];
grSstSelect((int)deviceIndex);
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
grGlideShutdown();
[super dealloc];
}
- (OFSet OF_GENERIC(OFPair OF_GENERIC(OFValue *, OFNumber *) *) *)
availableResolutions
{
OFMutableSet *ret = [OFMutableSet set];
GrResolution *resolutions;
GrResolution query = {
.resolution = GR_QUERY_ANY,
.refresh = GR_QUERY_ANY,
.numColorBuffers = GR_QUERY_ANY,
.numAuxBuffers = 1
};
size_t size = grQueryResolutions(&query, NULL);
resolutions = OFAllocMemory(1, size);
@try {
void *pool;
size = grQueryResolutions(&query, resolutions);
pool = objc_autoreleasePoolPush();
for (size_t i = 0; i < size / sizeof(*resolutions); i++) {
OFValue *resolution = [OFValue valueWithSize:
resolutionToSize(resolutions[i].resolution)];
OFNumber *refresh = [OFNumber numberWithFloat:
refreshEnumToFloat(resolutions[i].refresh)];
[ret addObject: [OFPair pairWithFirstObject: resolution
secondObject: refresh]];
}
objc_autoreleasePoolPop(pool);
} @finally {
OFFreeMemory(resolutions);
}
[ret makeImmutable];
return ret;
}
@end

37
src/O3DRenderer.h Normal file
View file

@ -0,0 +1,37 @@
/*
* 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>
OF_ASSUME_NONNULL_BEGIN
#ifdef __cplusplus
extern "C" {
#endif
extern OFString *const O3DRendererDeviceIndex;
#ifdef __cplusplus
}
#endif
@protocol O3DRenderer <OFObject>
@property (readonly, nonatomic) OFSet OF_GENERIC(OFPair OF_GENERIC(OFValue *,
OFNumber *) *) *availableResolutions;
+ (instancetype)alloc;
- (instancetype)initWithOptions:
(nullable OFDictionary OF_GENERIC(OFString *, id) *)options;
@end
OF_ASSUME_NONNULL_END

18
src/O3DRenderer.m Normal file
View file

@ -0,0 +1,18 @@
/*
* 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 "O3DRenderer.h"
OFString *const O3DRendererDeviceIndex = @"O3DRendererDeviceIndex";

View file

@ -15,6 +15,8 @@
#import <ObjFW/ObjFW.h>
#import "O3DEngine.h"
@interface TestsAppDelegate: OFObject <OFApplicationDelegate>
@end
@ -23,6 +25,15 @@ OF_APPLICATION_DELEGATE(TestsAppDelegate)
@implementation TestsAppDelegate
- (void)applicationDidFinishLaunching: (OFNotification *)notification
{
Class <O3DRenderer> renderer =
[O3DEngine availableRenderers].firstObject;
O3DEngine *engine =
[[[O3DEngine alloc] initWithRenderer: renderer
options: nil] autorelease];
[OFStdOut writeFormat: @"Available resolutions: %@",
engine.renderer.availableResolutions];
[OFApplication terminate];
}
@end