mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
GHOST: Remove C API and opaque types, modernize to C++
For now more than 20 years, Blender has been communicating with the host operating system through the GHOST module. At the time of its creation, Blender was still mostly written in C. As GHOST relied on C++ virtual inheritance to define abstract interfaces that are then implemented for each operating system, a C API had to be put in place to allow calling of such C++ functions from C, using opaque void pointer types to hold references to the abstract C++ interface types. Over the years, with Blender transitioning to C++, the C interface has become almost completely obsolete, hard to maintain, and is a common source of confusion and mistakes. With every GHOST method having to be implemented both in the abstract interface, common base class, OS specific implementation *and* in the C-API, to then be called from C++ through opaque handles, maintenance and expansion of this system has become needlessly difficult. In response to this problem, this PR refactors the GHOST module internals and the Blender calling code (in the WM, XR, GPU, and general OS dependent modules) to directly use and call the GHOST C++ class interfaces methods. Making for a simpler, cleaner and less error prone usage of the module. As well as providing better insight, IDE support and understanding of the module functionalities, and removing the need for opaque handle types and void pointers casting. Part of the 2025 Platform & Builds Code Quality Project (#151316) ## Main Changes ### Removal of opaque types and port of GHOST Types to C++ The GHOST opaque type handles (`GHOST_SystemHandle`, `GHOST_WindowHandle`, etc..) were removed in favor of directly accessing using and accessing their parent interface class. In addition to this, the main `GHOST_Types.h` header file was refactored to C++ (and renamed to `.hh`), dropping use of `typedef` for struct, enum and type alias and replacing them with direct C++ type definition and `using` declaration, as well as generally cleaning up the file from now outdated macros. ### Removal of the GHOST C-API interface, and port of calling code to C++ API The GHOST C-API interface (GHOST_C-api.h / GHOST_C-api.cc) and GHOST Path API (GHOST_Path-api.hh / GHOST_Path-api.cc) were removed in favor of directly using the GHOST interface class in the Blender calling code, making for a simpler and clearer API, allowing for clear and limited GHOST header includes, and generally simplifying the code. Some example of the new C++ API include (before/after): In general, throughout the code, number of casting is reduced. For example, in the WM code, a single `GHOST_IWindow *ghost_window` object can be created from `win->runtime->ghostwin` and be reused in a function, rather than casting the handle each time: In addition, certain C++ objects, such as GHOST_Rects, can be directly instantiated instead of being heap allocated: ### Replacement of void pointers in GPU backend code in favor GHOST interface pointer types With GHOST Types now being directly instantiable from within Blender code, the GPU backend code was improved in favor of replacing `void *` types referencing the GHOST graphic context with actual `GHOST_IContext *` interface pointer types, improving both type safety, general readability and removing the need for casting back and forth. See changes in `source/blender/gpu`. ### Conservation of the GHOST XR API As the XR part of the GHOST C-API didn't only provide opaque handle and C++ function calling, but also XR error handling via `GHOST_XR_CAPI_CALL{_RET}` macros, this part of the C-API was preserved in a new sub, XR specific API, exposed in the new `GHOST_Xr-api.hh` header and implemented in the existing `GHOST_Xr.cc` file. Following the rest of the refactor, the functions definition and prototypes were ported from using opaques `GHOST_XrContextHandle` to `GHOST_IXrContext *` pointer types. ### Removal of legacy GHOST OpenGL based tests In the GHOST module source tree, a `test` folder remained containing old tests dating back from the initial Git commit of ~2002. As these files have to be manually compiled and ran as a separate CMake target, are well outside our standard testing framework and code style, have outdated coverage, and mostly rely on pure OpenGL and now unsupported OpenGL code. The decision was made to remove them rather than uselessly port them to the C++ API. A possible future quality task could then be to re-implement proper, modern GHOST tests. *NOTE: See PR for additional API usage before/after examples.* Pull Request: https://projects.blender.org/blender/blender/pulls/151792
This commit is contained in:
parent
55c16f96c5
commit
380e9a8ea9
126 changed files with 1335 additions and 6755 deletions
|
|
@ -12,7 +12,6 @@ set(INC_SYS
|
|||
|
||||
set(SRC
|
||||
intern/GHOST_Buttons.cc
|
||||
intern/GHOST_C-api.cc
|
||||
intern/GHOST_CallbackEventConsumer.cc
|
||||
intern/GHOST_Context.cc
|
||||
intern/GHOST_ContextNone.cc
|
||||
|
|
@ -20,7 +19,6 @@ set(SRC
|
|||
intern/GHOST_ISystem.cc
|
||||
intern/GHOST_ISystemPaths.cc
|
||||
intern/GHOST_ModifierKeys.cc
|
||||
intern/GHOST_Path-api.cc
|
||||
intern/GHOST_PathUtils.cc
|
||||
intern/GHOST_Rect.cc
|
||||
intern/GHOST_System.cc
|
||||
|
|
@ -28,7 +26,7 @@ set(SRC
|
|||
intern/GHOST_Window.cc
|
||||
intern/GHOST_WindowManager.cc
|
||||
|
||||
GHOST_C-api.h
|
||||
GHOST_CallbackEventConsumer.hh
|
||||
GHOST_IContext.hh
|
||||
GHOST_IEvent.hh
|
||||
GHOST_IEventConsumer.hh
|
||||
|
|
@ -36,12 +34,10 @@ set(SRC
|
|||
GHOST_ISystemPaths.hh
|
||||
GHOST_ITimerTask.hh
|
||||
GHOST_IWindow.hh
|
||||
GHOST_Path-api.hh
|
||||
GHOST_Rect.hh
|
||||
GHOST_Types.h
|
||||
GHOST_Types.hh
|
||||
|
||||
intern/GHOST_Buttons.hh
|
||||
intern/GHOST_CallbackEventConsumer.hh
|
||||
intern/GHOST_Context.hh
|
||||
intern/GHOST_ContextNone.hh
|
||||
intern/GHOST_Debug.hh
|
||||
|
|
@ -529,6 +525,7 @@ if(WITH_XR_OPENXR)
|
|||
intern/GHOST_XrSwapchain.cc
|
||||
|
||||
GHOST_IXrContext.hh
|
||||
GHOST_Xr-api.hh
|
||||
intern/GHOST_IXrGraphicsBinding.hh
|
||||
intern/GHOST_XrAction.hh
|
||||
intern/GHOST_XrContext.hh
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -9,8 +9,16 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "GHOST_C-api.h"
|
||||
#include "GHOST_IEventConsumer.hh"
|
||||
#include "GHOST_Types.hh"
|
||||
|
||||
/**
|
||||
* Definition of a callback routine that receives events.
|
||||
* \param event: The event received.
|
||||
* \param user_data: The callback's user data, supplied to #GHOST_CreateSystem.
|
||||
*/
|
||||
using GHOST_EventCallbackProcPtr = bool (*)(const GHOST_IEvent *event,
|
||||
GHOST_TUserDataPtr user_data);
|
||||
|
||||
/**
|
||||
* Event consumer that will forward events to a call-back routine.
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
|
||||
#ifdef WITH_VULKAN_BACKEND
|
||||
# include <functional>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
#include <cstddef>
|
||||
|
||||
class GHOST_IWindow;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
#include "GHOST_IContext.hh"
|
||||
#include "GHOST_ITimerTask.hh"
|
||||
#include "GHOST_IWindow.hh"
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
|
||||
class GHOST_IEventConsumer;
|
||||
|
||||
|
|
@ -57,10 +57,11 @@ class GHOST_IEventConsumer;
|
|||
*
|
||||
* GHOST supports the following platforms:
|
||||
*
|
||||
* - OSX Cocoa.
|
||||
* - Windows.
|
||||
* - X11.
|
||||
* - SDL2 (experimental).
|
||||
* - macOS Cocoa.
|
||||
* - Microsoft Windows.
|
||||
* - X11 (Linux).
|
||||
* - Wayland (Linux).
|
||||
* - SDL2.
|
||||
* - null (headless mode).
|
||||
*
|
||||
* \section Building GHOST
|
||||
|
|
@ -68,15 +69,7 @@ class GHOST_IEventConsumer;
|
|||
* GHOST is not build standalone however there are tests in intern/ghost/test
|
||||
*
|
||||
* \section interface Interface
|
||||
* GHOST has two programming interfaces:
|
||||
*
|
||||
* - The C-API. For programs written in C.
|
||||
* - The C++-API. For programs written in C++.
|
||||
*
|
||||
* GHOST itself is written in C++ and the C-API is a wrapper around the C++
|
||||
* API.
|
||||
*
|
||||
* \subsection cplusplus_api The C++ API consists of the following files:
|
||||
* The GHOST C++ API consists of the following files:
|
||||
*
|
||||
* - GHOST_IEvent.hh
|
||||
* - GHOST_IEventConsumer.hh
|
||||
|
|
@ -84,19 +77,12 @@ class GHOST_IEventConsumer;
|
|||
* - GHOST_ITimerTask.hh
|
||||
* - GHOST_IWindow.hh
|
||||
* - GHOST_Rect.hh
|
||||
* - GHOST_Types.h
|
||||
* - GHOST_Types.hh
|
||||
* - GHOST_Xr-api.hh
|
||||
*
|
||||
* For an example of using the C++-API, have a look at the GHOST_C-Test.cpp
|
||||
* For an example of using the GHOST API, have a look at the GHOST_Test.cpp
|
||||
* program in the ?/ghost/test/gears/ directory.
|
||||
*
|
||||
* \subsection c_api The C-API
|
||||
* To use GHOST in programs written in C, include the file GHOST_C-API.h in
|
||||
* your program. This file includes the GHOST_Types.h file for all GHOST types
|
||||
* and defines functions that give you access to the same functionality present
|
||||
* in the C++ API.<br>
|
||||
* For an example of using the C-API, have a look at the GHOST_C-Test.c program
|
||||
* in the ?/ghost/test/gears/ directory.
|
||||
*
|
||||
* \section work Work in progress
|
||||
* \todo write WIP section
|
||||
*/
|
||||
|
|
@ -123,7 +109,7 @@ class GHOST_ISystem {
|
|||
* \return An indication of success.
|
||||
*/
|
||||
|
||||
static GHOST_TSuccess createSystem(bool verbose, bool background);
|
||||
static GHOST_TSuccess createSystem(bool verbose = true, bool background = false);
|
||||
static GHOST_TSuccess createSystemBackground();
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
|
||||
class GHOST_ISystemPaths {
|
||||
public:
|
||||
|
|
@ -28,7 +28,7 @@ class GHOST_ISystemPaths {
|
|||
static GHOST_TSuccess dispose();
|
||||
|
||||
/**
|
||||
* Returns a pointer to the one and only system (nil if it hasn't been created).
|
||||
* Returns a pointer to the one and only system.
|
||||
* \return A pointer to the system.
|
||||
*/
|
||||
static GHOST_ISystemPaths *get();
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
|
||||
/**
|
||||
* Interface for a timer task.
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "GHOST_Rect.hh"
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
|
|
@ -44,12 +44,6 @@ class GHOST_IWindow {
|
|||
*/
|
||||
virtual bool getValid() const = 0;
|
||||
|
||||
/**
|
||||
* Returns the associated OS object/handle.
|
||||
* \return The associated OS object/handle.
|
||||
*/
|
||||
virtual void *getOSWindow() const = 0;
|
||||
|
||||
/**
|
||||
* Returns the type of drawing context used in this window.
|
||||
* \return The current type of drawing context.
|
||||
|
|
@ -166,12 +160,6 @@ class GHOST_IWindow {
|
|||
*/
|
||||
virtual void setAcceptDragOperation(bool can_accept) = 0;
|
||||
|
||||
/**
|
||||
* Returns acceptance of the dropped object.
|
||||
* Usually called by the "object dropped" event handling function.
|
||||
*/
|
||||
virtual bool canAcceptDragOperation() const = 0;
|
||||
|
||||
/**
|
||||
* Returns the state of the window (normal, minimized, maximized).
|
||||
* \return The state of the window.
|
||||
|
|
@ -192,12 +180,6 @@ class GHOST_IWindow {
|
|||
*/
|
||||
virtual GHOST_TSuccess setModifiedState(bool is_unsaved_changes) = 0;
|
||||
|
||||
/**
|
||||
* Gets the window "modified" status, indicating unsaved changes.
|
||||
* \return True if there are unsaved changes
|
||||
*/
|
||||
virtual bool getModifiedState() = 0;
|
||||
|
||||
/**
|
||||
* Sets the order of the window (bottom, top).
|
||||
* \param order: The order of the window.
|
||||
|
|
@ -302,22 +284,11 @@ class GHOST_IWindow {
|
|||
*/
|
||||
virtual GHOST_TSuccess setCursorShape(GHOST_TStandardCursor cursor_shape) = 0;
|
||||
|
||||
/**
|
||||
* Gets the cursor grab region, if unset the window is used.
|
||||
* reset when grab is disabled.
|
||||
*/
|
||||
virtual GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds) const = 0;
|
||||
|
||||
virtual void getCursorGrabState(GHOST_TGrabCursorMode &mode,
|
||||
GHOST_TAxisFlag &axis_flag,
|
||||
GHOST_Rect &bounds,
|
||||
bool &use_software_cursor) = 0;
|
||||
|
||||
/**
|
||||
* Return true when a software cursor should be used.
|
||||
*/
|
||||
virtual bool getCursorGrabUseSoftwareDisplay() = 0;
|
||||
|
||||
/**
|
||||
* Test if the standard cursor shape is supported by current platform.
|
||||
* \return Indication of success.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
|
||||
class GHOST_XrSession;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,65 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2010 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "GHOST_Types.h"
|
||||
|
||||
GHOST_DECLARE_HANDLE(GHOST_SystemPathsHandle);
|
||||
|
||||
/**
|
||||
* Creates the one and only instance of the system path access.
|
||||
* \return An indication of success.
|
||||
*/
|
||||
extern GHOST_TSuccess GHOST_CreateSystemPaths();
|
||||
|
||||
/**
|
||||
* Disposes the one and only system.
|
||||
* \return An indication of success.
|
||||
*/
|
||||
extern GHOST_TSuccess GHOST_DisposeSystemPaths();
|
||||
|
||||
/**
|
||||
* Determine the base directory in which shared resources are located.
|
||||
* It will first try to use "unpack and run" path, then look for properly
|
||||
* installed path, including versioning.
|
||||
* \return Unsigned char string pointing to system directory (eg `/usr/share/blender/`).
|
||||
*
|
||||
* \note typically: `BKE_appdir_resource_path_id(BLENDER_RESOURCE_PATH_SYSTEM, false)` should be
|
||||
* used instead of this function directly as it ensures environment variable overrides are used.
|
||||
*/
|
||||
extern const char *GHOST_getSystemDir(int version, const char *versionstr);
|
||||
|
||||
/**
|
||||
* Determine the base directory in which user configuration is stored, including versioning.
|
||||
* \return Unsigned char string pointing to user directory (eg ~).
|
||||
*
|
||||
* \note typically: `BKE_appdir_resource_path_id(BLENDER_RESOURCE_PATH_USER, false)` should be
|
||||
* used instead of this function directly as it ensures environment variable overrides are used.
|
||||
*/
|
||||
extern const char *GHOST_getUserDir(int version, const char *versionstr);
|
||||
|
||||
/**
|
||||
* Determine a special ("well known") and easy to reach user directory.
|
||||
* \return If successfull, a string containing the user directory path (eg `~/Documents/`).
|
||||
*/
|
||||
extern std::optional<std::string> GHOST_getUserSpecialDir(GHOST_TUserSpecialDirTypes type);
|
||||
|
||||
/**
|
||||
* Determine the directory in which the binary file is found.
|
||||
* \return Unsigned char string pointing to binary directory (eg ~/usr/local/bin/).
|
||||
*/
|
||||
extern const char *GHOST_getBinaryDir();
|
||||
|
||||
/**
|
||||
* Add the file to the operating system most recently used files
|
||||
*/
|
||||
extern void GHOST_addToSystemRecentFiles(const char *filepath);
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
|
||||
/**
|
||||
* Implements rectangle functionality.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
#ifdef WITH_VULKAN_BACKEND
|
||||
|
|
@ -16,61 +17,29 @@
|
|||
VK_DEFINE_HANDLE(VmaAllocator)
|
||||
#endif
|
||||
|
||||
/* This is used by `GHOST_C-api.h` too, cannot use C++ conventions. */
|
||||
// NOLINTBEGIN: modernize-use-using
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
# define GHOST_DECLARE_HANDLE(name) \
|
||||
typedef struct name##__ { \
|
||||
int unused; \
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS(#name) \
|
||||
} *name
|
||||
#else
|
||||
# define GHOST_DECLARE_HANDLE(name) \
|
||||
typedef struct name##__ { \
|
||||
int unused; \
|
||||
} *name
|
||||
#endif
|
||||
using GHOST_TBacktraceFn = void (*)(FILE *file_handle);
|
||||
|
||||
/**
|
||||
* Creates a "handle" for a C++ GHOST object.
|
||||
* A handle is just an opaque pointer to an empty struct.
|
||||
* In the API the pointer is cast to the actual C++ class.
|
||||
* The 'name' argument to the macro is the name of the handle to create.
|
||||
*/
|
||||
using GHOST_TUserDataPtr = void *;
|
||||
|
||||
GHOST_DECLARE_HANDLE(GHOST_SystemHandle);
|
||||
GHOST_DECLARE_HANDLE(GHOST_TimerTaskHandle);
|
||||
GHOST_DECLARE_HANDLE(GHOST_WindowHandle);
|
||||
GHOST_DECLARE_HANDLE(GHOST_EventHandle);
|
||||
GHOST_DECLARE_HANDLE(GHOST_RectangleHandle);
|
||||
GHOST_DECLARE_HANDLE(GHOST_EventConsumerHandle);
|
||||
GHOST_DECLARE_HANDLE(GHOST_ContextHandle);
|
||||
GHOST_DECLARE_HANDLE(GHOST_XrContextHandle);
|
||||
|
||||
typedef void (*GHOST_TBacktraceFn)(void *file_handle);
|
||||
|
||||
typedef void *GHOST_TUserDataPtr;
|
||||
|
||||
typedef enum { GHOST_kFailure = 0, GHOST_kSuccess } GHOST_TSuccess;
|
||||
enum GHOST_TSuccess { GHOST_kFailure = 0, GHOST_kSuccess };
|
||||
|
||||
/**
|
||||
* A reference to cursor bitmap data.
|
||||
*/
|
||||
typedef struct {
|
||||
struct GHOST_CursorBitmapRef {
|
||||
/** `RGBA` bytes. */
|
||||
const uint8_t *data;
|
||||
int data_size[2];
|
||||
int hot_spot[2];
|
||||
} GHOST_CursorBitmapRef;
|
||||
};
|
||||
|
||||
/**
|
||||
* Pass this as an argument to GHOST so each ghost back-end
|
||||
* can generate cursors on demand.
|
||||
*/
|
||||
typedef struct GHOST_CursorGenerator {
|
||||
struct GHOST_CursorGenerator {
|
||||
/**
|
||||
* The main cursor generation callback.
|
||||
*
|
||||
|
|
@ -106,20 +75,18 @@ typedef struct GHOST_CursorGenerator {
|
|||
* (could contain SVG data for example).
|
||||
*/
|
||||
GHOST_TUserDataPtr user_data;
|
||||
};
|
||||
|
||||
} GHOST_CursorGenerator;
|
||||
|
||||
typedef enum {
|
||||
enum GHOST_GPUFlags {
|
||||
GHOST_gpuStereoVisual = (1 << 0),
|
||||
GHOST_gpuDebugContext = (1 << 1),
|
||||
GHOST_gpuVSyncIsOverridden = (1 << 2),
|
||||
};
|
||||
|
||||
} GHOST_GPUFlags;
|
||||
|
||||
typedef enum GHOST_DialogOptions {
|
||||
enum GHOST_DialogOptions {
|
||||
GHOST_DialogWarning = (1 << 0),
|
||||
GHOST_DialogError = (1 << 1),
|
||||
} GHOST_DialogOptions;
|
||||
};
|
||||
|
||||
/**
|
||||
* Static flag (relating to the back-ends support for features).
|
||||
|
|
@ -128,7 +95,7 @@ typedef enum GHOST_DialogOptions {
|
|||
* then mask out of from the `getCapabilities(..)` callback with an explanation for why
|
||||
* the feature is not supported.
|
||||
*/
|
||||
typedef enum {
|
||||
enum GHOST_TCapabilityFlag {
|
||||
/**
|
||||
* Set when warping the cursor is supported (re-positioning the users cursor).
|
||||
*/
|
||||
|
|
@ -176,7 +143,7 @@ typedef enum {
|
|||
*/
|
||||
GHOST_kCapabilityCursorRGBA = (1 << 10),
|
||||
/**
|
||||
* Setting cursors via #GHOST_SetCursorGenerator is supported.
|
||||
* Setting cursors via #GHOST_IWindow::setCursorShape is supported.
|
||||
*/
|
||||
GHOST_kCapabilityCursorGenerator = (1 << 11),
|
||||
/**
|
||||
|
|
@ -195,7 +162,7 @@ typedef enum {
|
|||
* Otherwise client-side-decorations should be used, see: `WITH_GHOST_CSD`.
|
||||
*/
|
||||
GHOST_kCapabilityWindowDecorationServerSide = (1 << 14),
|
||||
} GHOST_TCapabilityFlag;
|
||||
};
|
||||
|
||||
/**
|
||||
* Back-ends should use this, masking out features which are not supported
|
||||
|
|
@ -217,26 +184,26 @@ typedef enum {
|
|||
* the pen's angle in 3D space vertically downwards on to the XY plane
|
||||
* --Matt
|
||||
*/
|
||||
typedef enum {
|
||||
enum GHOST_TTabletMode {
|
||||
GHOST_kTabletModeNone = 0,
|
||||
GHOST_kTabletModeStylus,
|
||||
GHOST_kTabletModeEraser
|
||||
} GHOST_TTabletMode;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
enum GHOST_TTabletAPI {
|
||||
GHOST_kTabletAutomatic = 0,
|
||||
/* Show as Windows Ink to users to match "Use Windows Ink" in tablet utilities,
|
||||
* but we use the dependent Windows Pointer API. */
|
||||
GHOST_kTabletWinPointer,
|
||||
GHOST_kTabletWintab,
|
||||
} GHOST_TTabletAPI;
|
||||
};
|
||||
|
||||
typedef struct GHOST_TabletData {
|
||||
struct GHOST_TabletData {
|
||||
GHOST_TTabletMode Active; /* 0=None, 1=Stylus, 2=Eraser */
|
||||
float Pressure; /* range 0.0 (not touching) to 1.0 (full pressure) */
|
||||
float Xtilt; /* range -1.0 (left) to +1.0 (right) */
|
||||
float Ytilt; /* range -1.0 (away from user) to +1.0 (toward user) */
|
||||
} GHOST_TabletData;
|
||||
};
|
||||
|
||||
static const GHOST_TabletData GHOST_TABLET_DATA_NONE = {
|
||||
GHOST_kTabletModeNone, /* No cursor in range */
|
||||
|
|
@ -244,15 +211,11 @@ static const GHOST_TabletData GHOST_TABLET_DATA_NONE = {
|
|||
0.0f, /* Xtilt */
|
||||
0.0f}; /* Ytilt */
|
||||
|
||||
typedef enum {
|
||||
GHOST_kNotVisible = 0,
|
||||
GHOST_kPartiallyVisible,
|
||||
GHOST_kFullyVisible
|
||||
} GHOST_TVisibility;
|
||||
enum GHOST_TVisibility { GHOST_kNotVisible = 0, GHOST_kPartiallyVisible, GHOST_kFullyVisible };
|
||||
|
||||
typedef enum { GHOST_kFireTimeNever = 0xFFFFFFFF } GHOST_TFireTimeConstant;
|
||||
enum GHOST_TFireTimeConstant { GHOST_kFireTimeNever = 0xFFFFFFFF };
|
||||
|
||||
typedef enum {
|
||||
enum GHOST_TModifierKey {
|
||||
GHOST_kModifierKeyLeftShift = 0,
|
||||
GHOST_kModifierKeyRightShift,
|
||||
GHOST_kModifierKeyLeftAlt,
|
||||
|
|
@ -264,29 +227,29 @@ typedef enum {
|
|||
GHOST_kModifierKeyLeftHyper,
|
||||
GHOST_kModifierKeyRightHyper,
|
||||
GHOST_kModifierKeyNum
|
||||
} GHOST_TModifierKey;
|
||||
};
|
||||
|
||||
/**
|
||||
* \note these values are stored in #wmWindow::windowstate,
|
||||
* don't change, only add new values.
|
||||
*/
|
||||
typedef enum {
|
||||
enum GHOST_TWindowState {
|
||||
GHOST_kWindowStateNormal = 0,
|
||||
GHOST_kWindowStateMaximized = 1,
|
||||
GHOST_kWindowStateMinimized = 2,
|
||||
GHOST_kWindowStateFullScreen = 3,
|
||||
} GHOST_TWindowState;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
enum GHOST_TConsoleWindowState {
|
||||
GHOST_kConsoleWindowStateHide = 0,
|
||||
GHOST_kConsoleWindowStateShow,
|
||||
GHOST_kConsoleWindowStateToggle,
|
||||
GHOST_kConsoleWindowStateHideForNonConsoleLaunch
|
||||
} GHOST_TConsoleWindowState;
|
||||
};
|
||||
|
||||
typedef enum { GHOST_kWindowOrderTop = 0, GHOST_kWindowOrderBottom } GHOST_TWindowOrder;
|
||||
enum GHOST_TWindowOrder { GHOST_kWindowOrderTop = 0, GHOST_kWindowOrderBottom };
|
||||
|
||||
typedef enum {
|
||||
enum GHOST_TDrawingContextType {
|
||||
GHOST_kDrawingContextTypeNone = 0,
|
||||
#if defined(WITH_OPENGL_BACKEND)
|
||||
GHOST_kDrawingContextTypeOpenGL,
|
||||
|
|
@ -300,10 +263,10 @@ typedef enum {
|
|||
#ifdef WITH_VULKAN_BACKEND
|
||||
GHOST_kDrawingContextTypeVulkan,
|
||||
#endif
|
||||
} GHOST_TDrawingContextType;
|
||||
};
|
||||
|
||||
/** Set "None" as -1 so this can be used as an index. */
|
||||
typedef enum {
|
||||
enum GHOST_TButton {
|
||||
GHOST_kButtonMaskNone = -1,
|
||||
GHOST_kButtonMaskLeft,
|
||||
GHOST_kButtonMaskMiddle,
|
||||
|
|
@ -315,9 +278,9 @@ typedef enum {
|
|||
GHOST_kButtonMaskButton7,
|
||||
|
||||
#define GHOST_kButtonNum (int(GHOST_kButtonMaskButton7) + 1)
|
||||
} GHOST_TButton;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
enum GHOST_TEventType {
|
||||
GHOST_kEventUnknown = 0,
|
||||
|
||||
/** Mouse move event.
|
||||
|
|
@ -393,9 +356,9 @@ typedef enum {
|
|||
GHOST_kEventImeCompositionEnd,
|
||||
|
||||
#define GHOST_kNumEventTypes (GHOST_kEventImeCompositionEnd + 1)
|
||||
} GHOST_TEventType;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
enum GHOST_TStandardCursor {
|
||||
#define GHOST_kStandardCursorFirstCursor int(GHOST_kStandardCursorDefault)
|
||||
GHOST_kStandardCursorDefault = 0,
|
||||
GHOST_kStandardCursorRightArrow,
|
||||
|
|
@ -450,9 +413,9 @@ typedef enum {
|
|||
GHOST_kStandardCursorCustom,
|
||||
|
||||
#define GHOST_kStandardCursorNumCursors (int(GHOST_kStandardCursorCustom) + 1)
|
||||
} GHOST_TStandardCursor;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
enum GHOST_TKey {
|
||||
GHOST_kKeyUnknown = -1,
|
||||
GHOST_kKeyBackSpace,
|
||||
GHOST_kKeyTab,
|
||||
|
|
@ -603,7 +566,7 @@ typedef enum {
|
|||
GHOST_kKeyMediaStop,
|
||||
GHOST_kKeyMediaFirst,
|
||||
GHOST_kKeyMediaLast
|
||||
} GHOST_TKey;
|
||||
};
|
||||
|
||||
#define GHOST_KEY_MODIFIER_NUM ((_GHOST_KEY_MODIFIER_MAX - _GHOST_KEY_MODIFIER_MIN) + 1)
|
||||
#define GHOST_KEY_MODIFIER_TO_INDEX(key) ((unsigned int)(key) - _GHOST_KEY_MODIFIER_MIN)
|
||||
|
|
@ -611,7 +574,7 @@ typedef enum {
|
|||
(GHOST_TKey)(((unsigned int)(key) + _GHOST_KEY_MODIFIER_MIN))
|
||||
#define GHOST_KEY_MODIFIER_CHECK(key) (GHOST_KEY_MODIFIER_TO_INDEX(key) < GHOST_KEY_MODIFIER_NUM)
|
||||
|
||||
typedef enum {
|
||||
enum GHOST_TGrabCursorMode {
|
||||
/** Grab not set. */
|
||||
GHOST_kGrabDisable = 0,
|
||||
/** No cursor adjustments. */
|
||||
|
|
@ -623,57 +586,57 @@ typedef enum {
|
|||
* (used for number buttons and some other draggable UI elements).
|
||||
*/
|
||||
GHOST_kGrabHide,
|
||||
} GHOST_TGrabCursorMode;
|
||||
};
|
||||
|
||||
#define GHOST_GRAB_NEEDS_SOFTWARE_CURSOR_FOR_WARP(grab) ((grab) == GHOST_kGrabWrap)
|
||||
|
||||
typedef enum {
|
||||
enum GHOST_TAxisFlag {
|
||||
/** Axis that cursor grab will wrap. */
|
||||
GHOST_kAxisNone = 0,
|
||||
GHOST_kAxisX = (1 << 0),
|
||||
GHOST_kAxisY = (1 << 1),
|
||||
} GHOST_TAxisFlag;
|
||||
};
|
||||
|
||||
typedef const void *GHOST_TEventDataPtr;
|
||||
using GHOST_TEventDataPtr = const void *;
|
||||
|
||||
typedef struct {
|
||||
struct GHOST_TEventCursorData {
|
||||
/** The x-coordinate of the cursor position. */
|
||||
int32_t x;
|
||||
/** The y-coordinate of the cursor position. */
|
||||
int32_t y;
|
||||
/** Associated tablet data. */
|
||||
GHOST_TabletData tablet;
|
||||
} GHOST_TEventCursorData;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
struct GHOST_TEventButtonData {
|
||||
/** The mask of the mouse button. */
|
||||
GHOST_TButton button;
|
||||
/** Associated tablet data. */
|
||||
GHOST_TabletData tablet;
|
||||
} GHOST_TEventButtonData;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
enum GHOST_TEventWheelAxis {
|
||||
GHOST_kEventWheelAxisVertical = 0,
|
||||
GHOST_kEventWheelAxisHorizontal = 1,
|
||||
} GHOST_TEventWheelAxis;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
struct GHOST_TEventWheelData {
|
||||
/** Which mouse wheel is used. */
|
||||
GHOST_TEventWheelAxis axis;
|
||||
/** Displacement of a mouse wheel. */
|
||||
int32_t value;
|
||||
} GHOST_TEventWheelData;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
enum GHOST_TTrackpadEventSubTypes {
|
||||
GHOST_kTrackpadEventUnknown = 0,
|
||||
GHOST_kTrackpadEventScroll,
|
||||
GHOST_kTrackpadEventRotate,
|
||||
GHOST_kTrackpadEventSwipe, /* Reserved, not used for now */
|
||||
GHOST_kTrackpadEventMagnify,
|
||||
GHOST_kTrackpadEventSmartMagnify
|
||||
} GHOST_TTrackpadEventSubTypes;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
struct GHOST_TEventTrackpadData {
|
||||
/** The event subtype */
|
||||
GHOST_TTrackpadEventSubTypes subtype;
|
||||
/** The x-location of the trackpad event */
|
||||
|
|
@ -686,18 +649,18 @@ typedef struct {
|
|||
int32_t deltaY;
|
||||
/** The delta is inverted from the device due to system preferences. */
|
||||
char isDirectionInverted;
|
||||
} GHOST_TEventTrackpadData;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
enum GHOST_TDragnDropTypes {
|
||||
GHOST_kDragnDropTypeUnknown = 0,
|
||||
GHOST_kDragnDropTypeFilenames, /* Array of strings representing file names (full path). */
|
||||
GHOST_kDragnDropTypeString, /* Unformatted text UTF8 string. */
|
||||
GHOST_kDragnDropTypeBitmap /* Bitmap image data. */
|
||||
} GHOST_TDragnDropTypes;
|
||||
};
|
||||
|
||||
typedef void *GHOST_TDragnDropDataPtr;
|
||||
using GHOST_TDragnDropDataPtr = void *;
|
||||
|
||||
typedef struct {
|
||||
struct GHOST_TEventDragnDropData {
|
||||
/** The x-coordinate of the cursor position. */
|
||||
int32_t x;
|
||||
/** The y-coordinate of the cursor position. */
|
||||
|
|
@ -706,13 +669,13 @@ typedef struct {
|
|||
GHOST_TDragnDropTypes dataType;
|
||||
/** The "dropped content" */
|
||||
GHOST_TDragnDropDataPtr data;
|
||||
} GHOST_TEventDragnDropData;
|
||||
};
|
||||
|
||||
/**
|
||||
* \warning this is a duplicate of #wmImeData.
|
||||
* All members must remain aligned and the struct size match!
|
||||
*/
|
||||
typedef struct {
|
||||
struct GHOST_TEventImeData {
|
||||
/** UTF8 encoded strings. */
|
||||
std::string result, composite;
|
||||
/** Cursor position in the IME composition. */
|
||||
|
|
@ -721,26 +684,26 @@ typedef struct {
|
|||
int target_start;
|
||||
/** Represents the position of the end of the selection */
|
||||
int target_end;
|
||||
} GHOST_TEventImeData;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
struct GHOST_TStringArray {
|
||||
int count;
|
||||
uint8_t **strings;
|
||||
} GHOST_TStringArray;
|
||||
};
|
||||
|
||||
/**
|
||||
* Keep in sync with #wmProgress.
|
||||
*/
|
||||
typedef enum {
|
||||
enum GHOST_TProgress {
|
||||
GHOST_kNotStarted = 0,
|
||||
GHOST_kStarting,
|
||||
GHOST_kInProgress,
|
||||
GHOST_kFinishing,
|
||||
GHOST_kFinished
|
||||
} GHOST_TProgress;
|
||||
};
|
||||
|
||||
#ifdef WITH_INPUT_NDOF
|
||||
typedef struct {
|
||||
struct GHOST_TEventNDOFMotionData {
|
||||
/** N-degree of freedom device data v3 [GSoC 2010] */
|
||||
/* Each component normally ranges from -1 to +1, but can exceed that.
|
||||
* These use blender standard view coordinates,
|
||||
|
|
@ -755,18 +718,18 @@ typedef struct {
|
|||
float dt;
|
||||
/** Starting, #GHOST_kInProgress or #GHOST_kFinishing (for modal handlers) */
|
||||
GHOST_TProgress progress;
|
||||
} GHOST_TEventNDOFMotionData;
|
||||
};
|
||||
|
||||
typedef enum { GHOST_kPress, GHOST_kRelease } GHOST_TButtonAction;
|
||||
enum GHOST_TButtonAction { GHOST_kPress, GHOST_kRelease };
|
||||
/* Good for mouse or other buttons too? */
|
||||
|
||||
typedef struct {
|
||||
struct GHOST_TEventNDOFButtonData {
|
||||
GHOST_TButtonAction action;
|
||||
short button;
|
||||
} GHOST_TEventNDOFButtonData;
|
||||
};
|
||||
#endif // WITH_INPUT_NDOF
|
||||
|
||||
typedef struct {
|
||||
struct GHOST_TEventKeyData {
|
||||
/** The key code. */
|
||||
GHOST_TKey key;
|
||||
|
||||
|
|
@ -780,9 +743,9 @@ typedef struct {
|
|||
* All back-ends must set this variable for correct behavior regarding repeatable keys.
|
||||
*/
|
||||
char is_repeat;
|
||||
} GHOST_TEventKeyData;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
enum GHOST_TUserSpecialDirTypes {
|
||||
GHOST_kUserSpecialDirDesktop,
|
||||
GHOST_kUserSpecialDirDocuments,
|
||||
GHOST_kUserSpecialDirDownloads,
|
||||
|
|
@ -791,21 +754,21 @@ typedef enum {
|
|||
GHOST_kUserSpecialDirVideos,
|
||||
GHOST_kUserSpecialDirCaches,
|
||||
/* Can be extended as needed. */
|
||||
} GHOST_TUserSpecialDirTypes;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
enum GHOST_TWindowDecorationStyleFlags {
|
||||
GHOST_kDecorationNone = 0,
|
||||
GHOST_kDecorationColoredTitleBar = (1 << 0),
|
||||
} GHOST_TWindowDecorationStyleFlags;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
struct GHOST_GPUDevice {
|
||||
/** Index of the GPU device in the list provided by the platform. */
|
||||
int index;
|
||||
/** (PCI) Vendor ID of the GPU. */
|
||||
uint vendor_id;
|
||||
/** Device ID of the GPU provided by the vendor. */
|
||||
uint device_id;
|
||||
} GHOST_GPUDevice;
|
||||
};
|
||||
|
||||
/**
|
||||
* Options for VSync.
|
||||
|
|
@ -813,7 +776,7 @@ typedef struct {
|
|||
* \note with the exception of #GHOST_kVSyncModeUnset,
|
||||
* these map to the OpenGL "swap interval" argument.
|
||||
*/
|
||||
typedef enum {
|
||||
enum GHOST_TVSyncModes {
|
||||
/** Up to the GPU driver to choose. */
|
||||
GHOST_kVSyncModeUnset = -2,
|
||||
/** Adaptive sync (OpenGL only). */
|
||||
|
|
@ -822,7 +785,7 @@ typedef enum {
|
|||
GHOST_kVSyncModeOff = 0,
|
||||
/** Force enable. */
|
||||
GHOST_kVSyncModeOn = 1,
|
||||
} GHOST_TVSyncModes;
|
||||
};
|
||||
|
||||
/**
|
||||
* Settings used to create a GPU context.
|
||||
|
|
@ -830,11 +793,11 @@ typedef enum {
|
|||
* \note Avoid adding values here unless they apply across multiple context implementations.
|
||||
* Otherwise the settings would be better added as extra arguments, only passed to that class.
|
||||
*/
|
||||
typedef struct {
|
||||
struct GHOST_ContextParams {
|
||||
bool is_stereo_visual;
|
||||
bool is_debug;
|
||||
GHOST_TVSyncModes vsync;
|
||||
} GHOST_ContextParams;
|
||||
};
|
||||
|
||||
#define GHOST_CONTEXT_PARAMS_NONE \
|
||||
{ \
|
||||
|
|
@ -858,7 +821,7 @@ typedef struct {
|
|||
GHOST_kVSyncModeUnset), \
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
struct GHOST_GPUSettings {
|
||||
int flags;
|
||||
/**
|
||||
* Use when `flags & GHOST_gpuVSyncIsOverridden` is set.
|
||||
|
|
@ -867,20 +830,20 @@ typedef struct {
|
|||
GHOST_TVSyncModes vsync;
|
||||
GHOST_TDrawingContextType context_type;
|
||||
GHOST_GPUDevice preferred_device;
|
||||
} GHOST_GPUSettings;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
struct GHOST_WindowDecorationStyleSettings {
|
||||
float colored_titlebar_bg_color[3];
|
||||
} GHOST_WindowDecorationStyleSettings;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
struct GHOST_WindowHDRInfo {
|
||||
/* Is HDR enabled for this Window? */
|
||||
bool hdr_enabled;
|
||||
/* Is wide gamut enabled for this Window? */
|
||||
bool wide_gamut_enabled;
|
||||
/* Scale factor to display SDR content in HDR. */
|
||||
float sdr_white_level;
|
||||
} GHOST_WindowHDRInfo;
|
||||
};
|
||||
|
||||
#define GHOST_WINDOW_HDR_INFO_NONE \
|
||||
{ \
|
||||
|
|
@ -890,7 +853,7 @@ typedef struct {
|
|||
}
|
||||
|
||||
#ifdef WITH_VULKAN_BACKEND
|
||||
typedef struct {
|
||||
struct GHOST_VulkanSwapChainData {
|
||||
/** Image handle to the image that will be presented to the user. */
|
||||
VkImage image;
|
||||
/** Format of the swap-chain. */
|
||||
|
|
@ -905,9 +868,9 @@ typedef struct {
|
|||
VkFence submission_fence;
|
||||
/* Factor to scale SDR content to HDR. */
|
||||
float sdr_scale;
|
||||
} GHOST_VulkanSwapChainData;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
enum GHOST_TVulkanXRModes {
|
||||
/**
|
||||
* Use RAM to transfer the render result to the XR swapchain.
|
||||
*
|
||||
|
|
@ -931,9 +894,9 @@ typedef enum {
|
|||
* GHOST_XrGraphicsBindingVulkan will import the memory and copy the image to the swapchain.
|
||||
*/
|
||||
GHOST_kVulkanXRModeWin32,
|
||||
} GHOST_TVulkanXRModes;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
struct GHOST_VulkanOpenXRData {
|
||||
/**
|
||||
* Mode to use for data transfer between the application rendered result and the OpenXR
|
||||
* swapchain. This is set by the GHOST and should be respected by the application.
|
||||
|
|
@ -989,15 +952,14 @@ typedef struct {
|
|||
VkDeviceSize memory_offset;
|
||||
} gpu;
|
||||
};
|
||||
|
||||
} GHOST_VulkanOpenXRData;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return argument passed to #GHOST_IContext:::getVulkanHandles.
|
||||
* Return argument passed to #GHOST_IContext::getVulkanHandles.
|
||||
*
|
||||
* The members of this struct are assigned values.
|
||||
*/
|
||||
typedef struct {
|
||||
struct GHOST_VulkanHandles {
|
||||
/** The instance handle. */
|
||||
VkInstance instance;
|
||||
/** The physics device handle. */
|
||||
|
|
@ -1012,28 +974,28 @@ typedef struct {
|
|||
void *queue_mutex;
|
||||
/** Vulkan memory allocator of the device. */
|
||||
VmaAllocator vma_allocator;
|
||||
} GHOST_VulkanHandles;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
enum GHOST_TDebugFlags {
|
||||
/** Axis that cursor grab will wrap. */
|
||||
GHOST_kDebugDefault = (1 << 1),
|
||||
GHOST_kDebugWintab = (1 << 2),
|
||||
} GHOST_TDebugFlags;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
struct GHOST_Debug {
|
||||
int flags;
|
||||
} GHOST_Debug;
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef void *GHOST_TEmbedderWindowID;
|
||||
using GHOST_TEmbedderWindowID = void *;
|
||||
#endif // _WIN32
|
||||
|
||||
#ifndef _WIN32
|
||||
/* I can't use "Window" from `X11/Xlib.h`
|
||||
* because it conflicts with Window defined in `winlay.h`. */
|
||||
typedef int GHOST_TEmbedderWindowID;
|
||||
using GHOST_TEmbedderWindowID = int;
|
||||
#endif // _WIN32
|
||||
|
||||
/**
|
||||
|
|
@ -1041,16 +1003,11 @@ typedef int GHOST_TEmbedderWindowID;
|
|||
* \param task: The timer task object.
|
||||
* \param time: Time since this timer started (in milliseconds).
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
class GHOST_ITimerTask;
|
||||
typedef void (*GHOST_TimerProcPtr)(GHOST_ITimerTask *task, uint64_t time);
|
||||
#else
|
||||
struct GHOST_TimerTaskHandle__;
|
||||
typedef void (*GHOST_TimerProcPtr)(struct GHOST_TimerTaskHandle__ *task, uint64_t time);
|
||||
#endif
|
||||
using GHOST_TimerProcPtr = void (*)(GHOST_ITimerTask *task, uint64_t time);
|
||||
|
||||
/* Window client-side-decorations (CSD). */
|
||||
typedef enum {
|
||||
enum GHOST_TCSD_Type {
|
||||
/**
|
||||
* Use for window contents.
|
||||
* This must be ordered before other items so the contents its prioritized.
|
||||
|
|
@ -1073,7 +1030,7 @@ typedef enum {
|
|||
GHOST_kCSDTypeButtonMenu,
|
||||
|
||||
GHOST_kCSDTypeTitlebar,
|
||||
} GHOST_TCSD_Type;
|
||||
};
|
||||
#define GHOST_kCSDType_NUM (int(GHOST_kCSDTypeTitlebar) + 1)
|
||||
/**
|
||||
* Note that coordinates are flipped Y from WM.
|
||||
|
|
@ -1092,14 +1049,14 @@ struct GHOST_CSD_Elem {
|
|||
* CSD Layout.
|
||||
* Currently only supports configuring button order separated by the title text.
|
||||
*/
|
||||
typedef struct GHOST_CSD_Layout {
|
||||
struct GHOST_CSD_Layout {
|
||||
int32_t buttons_num;
|
||||
GHOST_TCSD_Type buttons[5];
|
||||
} GHOST_CSD_Layout;
|
||||
};
|
||||
|
||||
#define GHOST_CSD_DPI_FRACTIONAL_BASE 96
|
||||
|
||||
typedef struct GHOST_CSD_Params {
|
||||
struct GHOST_CSD_Params {
|
||||
int32_t (*layout_callback)(const int32_t window_size[2],
|
||||
const int32_t fractional_scale[2],
|
||||
GHOST_TWindowState windowstate,
|
||||
|
|
@ -1108,7 +1065,7 @@ typedef struct GHOST_CSD_Params {
|
|||
/** Used for window interactions. */
|
||||
int cursor_drag_threshold;
|
||||
int cursor_double_click_ms;
|
||||
} GHOST_CSD_Params;
|
||||
};
|
||||
|
||||
#ifdef WITH_XR_OPENXR
|
||||
|
||||
|
|
@ -1121,7 +1078,7 @@ struct GHOST_XrError;
|
|||
*
|
||||
* This enum defines the possible graphics bindings to attempt to enable.
|
||||
*/
|
||||
typedef enum GHOST_TXrGraphicsBinding {
|
||||
enum GHOST_TXrGraphicsBinding {
|
||||
GHOST_kXrGraphicsUnknown = 0,
|
||||
GHOST_kXrGraphicsOpenGL,
|
||||
GHOST_kXrGraphicsVulkan,
|
||||
|
|
@ -1132,32 +1089,34 @@ typedef enum GHOST_TXrGraphicsBinding {
|
|||
# endif
|
||||
/* For later */
|
||||
// GHOST_kXrGraphicsVulkan,
|
||||
} GHOST_TXrGraphicsBinding;
|
||||
};
|
||||
|
||||
typedef void (*GHOST_XrErrorHandlerFn)(const struct GHOST_XrError *);
|
||||
using GHOST_XrErrorHandlerFn = void (*)(const struct GHOST_XrError *);
|
||||
|
||||
typedef void (*GHOST_XrSessionCreateFn)(void);
|
||||
typedef void (*GHOST_XrSessionExitFn)(void *customdata);
|
||||
typedef void (*GHOST_XrCustomdataFreeFn)(void *customdata);
|
||||
using GHOST_XrSessionCreateFn = void (*)();
|
||||
using GHOST_XrSessionExitFn = void (*)(void *customdata);
|
||||
using GHOST_XrCustomdataFreeFn = void (*)(void *customdata);
|
||||
|
||||
typedef void *(*GHOST_XrGraphicsContextBindFn)(void);
|
||||
typedef void (*GHOST_XrGraphicsContextUnbindFn)(GHOST_ContextHandle graphics_context);
|
||||
typedef void (*GHOST_XrDrawViewFn)(const struct GHOST_XrDrawViewInfo *draw_view, void *customdata);
|
||||
typedef bool (*GHOST_XrPassthroughEnabledFn)(void *customdata);
|
||||
typedef void (*GHOST_XrDisablePassthroughFn)(void *customdata);
|
||||
class GHOST_IContext;
|
||||
using GHOST_XrGraphicsContextBindFn = GHOST_IContext *(*)();
|
||||
using GHOST_XrGraphicsContextUnbindFn = void (*)(GHOST_IContext *graphics_context);
|
||||
using GHOST_XrDrawViewFn = void (*)(const struct GHOST_XrDrawViewInfo *draw_view,
|
||||
void *customdata);
|
||||
using GHOST_XrPassthroughEnabledFn = bool (*)(void *customdata);
|
||||
using GHOST_XrDisablePassthroughFn = void (*)(void *customdata);
|
||||
|
||||
/**
|
||||
* An array of #GHOST_TXrGraphicsBinding items defining the candidate bindings to use.
|
||||
* The first available candidate will be chosen, so order defines priority.
|
||||
*/
|
||||
typedef const GHOST_TXrGraphicsBinding *GHOST_XrGraphicsBindingCandidates;
|
||||
using GHOST_XrGraphicsBindingCandidates = const GHOST_TXrGraphicsBinding *;
|
||||
|
||||
typedef struct {
|
||||
struct GHOST_XrPose {
|
||||
bool is_active;
|
||||
float position[3];
|
||||
/* Blender convention (w, x, y, z) */
|
||||
float orientation_quat[4];
|
||||
} GHOST_XrPose;
|
||||
};
|
||||
|
||||
enum {
|
||||
GHOST_kXrContextDebug = (1 << 0),
|
||||
|
|
@ -1169,28 +1128,28 @@ enum {
|
|||
# endif
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
struct GHOST_XrContextCreateInfo {
|
||||
const GHOST_XrGraphicsBindingCandidates gpu_binding_candidates;
|
||||
unsigned int gpu_binding_candidates_count;
|
||||
|
||||
unsigned int context_flag;
|
||||
} GHOST_XrContextCreateInfo;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
struct GHOST_XrSessionBeginInfo {
|
||||
GHOST_XrSessionCreateFn create_fn;
|
||||
GHOST_XrSessionExitFn exit_fn;
|
||||
void *exit_customdata;
|
||||
} GHOST_XrSessionBeginInfo;
|
||||
};
|
||||
|
||||
/** Texture format for XR swapchain. */
|
||||
typedef enum GHOST_TXrSwapchainFormat {
|
||||
enum GHOST_TXrSwapchainFormat {
|
||||
GHOST_kXrSwapchainFormatRGBA8,
|
||||
GHOST_kXrSwapchainFormatRGBA16,
|
||||
GHOST_kXrSwapchainFormatRGBA16F,
|
||||
GHOST_kXrSwapchainFormatRGB10_A2,
|
||||
} GHOST_TXrSwapchainFormat;
|
||||
};
|
||||
|
||||
typedef struct GHOST_XrDrawViewInfo {
|
||||
struct GHOST_XrDrawViewInfo {
|
||||
int ofsx, ofsy;
|
||||
int width, height;
|
||||
|
||||
|
|
@ -1209,32 +1168,32 @@ typedef struct GHOST_XrDrawViewInfo {
|
|||
/** The view that this info represents. Not necessarily the "eye index" (e.g. for quad view
|
||||
* systems, etc). */
|
||||
char view_idx;
|
||||
} GHOST_XrDrawViewInfo;
|
||||
};
|
||||
|
||||
typedef struct GHOST_XrError {
|
||||
struct GHOST_XrError {
|
||||
const char *user_message;
|
||||
|
||||
void *customdata;
|
||||
} GHOST_XrError;
|
||||
};
|
||||
|
||||
typedef struct GHOST_XrActionSetInfo {
|
||||
struct GHOST_XrActionSetInfo {
|
||||
const char *name;
|
||||
|
||||
GHOST_XrCustomdataFreeFn customdata_free_fn;
|
||||
void *customdata; /* wmXrActionSet */
|
||||
} GHOST_XrActionSetInfo;
|
||||
};
|
||||
|
||||
/** XR action type. Enum values match those in OpenXR's
|
||||
* XrActionType enum for consistency. */
|
||||
typedef enum GHOST_XrActionType {
|
||||
enum GHOST_XrActionType {
|
||||
GHOST_kXrActionTypeBooleanInput = 1,
|
||||
GHOST_kXrActionTypeFloatInput = 2,
|
||||
GHOST_kXrActionTypeVector2fInput = 3,
|
||||
GHOST_kXrActionTypePoseInput = 4,
|
||||
GHOST_kXrActionTypeVibrationOutput = 100,
|
||||
} GHOST_XrActionType;
|
||||
};
|
||||
|
||||
typedef struct GHOST_XrActionInfo {
|
||||
struct GHOST_XrActionInfo {
|
||||
const char *name;
|
||||
GHOST_XrActionType type;
|
||||
uint32_t count_subaction_paths;
|
||||
|
|
@ -1247,51 +1206,49 @@ typedef struct GHOST_XrActionInfo {
|
|||
|
||||
GHOST_XrCustomdataFreeFn customdata_free_fn;
|
||||
void *customdata; /* wmXrAction */
|
||||
} GHOST_XrActionInfo;
|
||||
};
|
||||
|
||||
typedef struct GHOST_XrActionBindingInfo {
|
||||
struct GHOST_XrActionBindingInfo {
|
||||
const char *component_path;
|
||||
float float_threshold;
|
||||
int16_t axis_flag;
|
||||
GHOST_XrPose pose;
|
||||
} GHOST_XrActionBindingInfo;
|
||||
};
|
||||
|
||||
typedef struct GHOST_XrActionProfileInfo {
|
||||
struct GHOST_XrActionProfileInfo {
|
||||
const char *action_name;
|
||||
const char *profile_path;
|
||||
uint32_t count_subaction_paths;
|
||||
const char **subaction_paths;
|
||||
/** Bindings for each subaction path. */
|
||||
const GHOST_XrActionBindingInfo *bindings;
|
||||
} GHOST_XrActionProfileInfo;
|
||||
};
|
||||
|
||||
typedef struct GHOST_XrControllerModelVertex {
|
||||
struct GHOST_XrControllerModelVertex {
|
||||
float position[3];
|
||||
float normal[3];
|
||||
} GHOST_XrControllerModelVertex;
|
||||
};
|
||||
|
||||
typedef struct GHOST_XrControllerModelComponent {
|
||||
struct GHOST_XrControllerModelComponent {
|
||||
/** World space transform. */
|
||||
float transform[4][4];
|
||||
uint32_t vertex_offset;
|
||||
uint32_t vertex_count;
|
||||
uint32_t index_offset;
|
||||
uint32_t index_count;
|
||||
} GHOST_XrControllerModelComponent;
|
||||
};
|
||||
|
||||
typedef struct GHOST_XrControllerModelData {
|
||||
struct GHOST_XrControllerModelData {
|
||||
uint32_t count_vertices;
|
||||
const GHOST_XrControllerModelVertex *vertices;
|
||||
uint32_t count_indices;
|
||||
const uint32_t *indices;
|
||||
uint32_t count_components;
|
||||
const GHOST_XrControllerModelComponent *components;
|
||||
} GHOST_XrControllerModelData;
|
||||
};
|
||||
|
||||
#endif /* WITH_XR_OPENXR */
|
||||
|
||||
// NOLINTEND: modernize-use-using
|
||||
|
||||
/**
|
||||
* NDOF device button event types.
|
||||
*
|
||||
|
|
@ -1300,8 +1257,7 @@ typedef struct GHOST_XrControllerModelData {
|
|||
* where some of these numbers are found but it is basically an arbitrary assignment
|
||||
* made by the vendor (3Dconnexion) since the application has the freedom to override as necessary.
|
||||
*/
|
||||
typedef enum {
|
||||
|
||||
enum GHOST_NDOF_ButtonT {
|
||||
GHOST_NDOF_BUTTON_NONE = -1,
|
||||
/* Used internally, never sent or used as an index. */
|
||||
GHOST_NDOF_BUTTON_INVALID = 0,
|
||||
|
|
@ -1400,5 +1356,4 @@ typedef enum {
|
|||
GHOST_NDOF_BUTTON_NP_F4 = 232,
|
||||
|
||||
GHOST_NDOF_BUTTON_USER = 0x10000
|
||||
|
||||
} GHOST_NDOF_ButtonT;
|
||||
};
|
||||
245
intern/ghost/GHOST_Xr-api.hh
Normal file
245
intern/ghost/GHOST_Xr-api.hh
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
/* SPDX-FileCopyrightText: 2025 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
*
|
||||
* \brief Abstraction for XR (VR, AR, MR, ..) access via OpenXR.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GHOST_IXrContext.hh"
|
||||
#include "GHOST_Types.hh"
|
||||
|
||||
/* XR-context */
|
||||
|
||||
/**
|
||||
* Set a custom callback to be executed whenever an error occurs. Should be set before calling
|
||||
* #GHOST_XrContextCreate() to get error handling during context creation too.
|
||||
*
|
||||
* \param customdata: Handle to some data that will get passed to \a handler_fn should an error be
|
||||
* thrown.
|
||||
*/
|
||||
void GHOST_XrErrorHandler(GHOST_XrErrorHandlerFn handler_fn, void *customdata);
|
||||
|
||||
/**
|
||||
* \brief Initialize the Ghost XR-context.
|
||||
*
|
||||
* Includes setting up the OpenXR runtime link, querying available extensions and API layers,
|
||||
* enabling extensions and API layers.
|
||||
*
|
||||
* \param create_info: Options for creating the XR-context, e.g. debug-flags and ordered array of
|
||||
* graphics bindings to try enabling.
|
||||
*/
|
||||
GHOST_IXrContext *GHOST_XrContextCreate(const GHOST_XrContextCreateInfo *create_info);
|
||||
/**
|
||||
* Free a XR-context involving OpenXR runtime link destruction and freeing of all internal data.
|
||||
*/
|
||||
void GHOST_XrContextDestroy(GHOST_IXrContext *xr_context);
|
||||
|
||||
/**
|
||||
* Set callbacks for binding and unbinding a graphics context for a session. The binding callback
|
||||
* may create a new graphics context thereby. In fact that's the sole reason for this callback
|
||||
* approach to binding. Just make sure to have an unbind function set that properly destructs.
|
||||
*
|
||||
* \param bind_fn: Function to retrieve (possibly create) a graphics context.
|
||||
* \param unbind_fn: Function to release (possibly free) a graphics context.
|
||||
*/
|
||||
void GHOST_XrGraphicsContextBindFuncs(GHOST_IXrContext *xr_context,
|
||||
GHOST_XrGraphicsContextBindFn bind_fn,
|
||||
GHOST_XrGraphicsContextUnbindFn unbind_fn);
|
||||
|
||||
/**
|
||||
* Set the drawing callback for views. A view would typically be either the left or the right eye,
|
||||
* although other configurations are possible. When #GHOST_XrSessionDrawViews() is called to draw
|
||||
* an XR frame, \a draw_view_fn is executed for each view.
|
||||
*
|
||||
* \param draw_view_fn: The callback to draw a single view for an XR frame.
|
||||
*/
|
||||
void GHOST_XrDrawViewFunc(GHOST_IXrContext *xr_context, GHOST_XrDrawViewFn draw_view_fn);
|
||||
|
||||
/**
|
||||
* Set the callback to check if passthrough is enabled.
|
||||
* If enabled, the passthrough composition layer is added in GHOST_XrSession::draw().
|
||||
*
|
||||
* \param passthrough_enabled_fn: The callback to check if passthrough is enabled.
|
||||
*/
|
||||
void GHOST_XrPassthroughEnabledFunc(GHOST_IXrContext *xr_context,
|
||||
GHOST_XrPassthroughEnabledFn passthrough_enabled_fn);
|
||||
|
||||
/**
|
||||
* Set the callback to force disable passthrough in case it is not supported.
|
||||
* Called in GHOST_XrSession::draw().
|
||||
*
|
||||
* \param disable_passthrough_fn: The callback to disable passthrough.
|
||||
*/
|
||||
void GHOST_XrDisablePassthroughFunc(GHOST_IXrContext *xr_context,
|
||||
GHOST_XrDisablePassthroughFn disable_passthrough_fn);
|
||||
|
||||
/* sessions */
|
||||
/**
|
||||
* Create internal session data for \a xr_context and ask the OpenXR runtime to invoke a session.
|
||||
*
|
||||
* \param begin_info: Options for the session creation.
|
||||
*/
|
||||
void GHOST_XrSessionStart(GHOST_IXrContext *xr_context,
|
||||
const GHOST_XrSessionBeginInfo *begin_info);
|
||||
/**
|
||||
* Destruct internal session data for \a xr_context and ask the OpenXR runtime to stop a session.
|
||||
*/
|
||||
void GHOST_XrSessionEnd(GHOST_IXrContext *xr_context);
|
||||
/**
|
||||
* Draw a single frame by calling the view drawing callback defined by #GHOST_XrDrawViewFunc() for
|
||||
* each view and submit it to the OpenXR runtime.
|
||||
*
|
||||
* \param customdata: Handle to some data that will get passed to the view drawing callback.
|
||||
*/
|
||||
void GHOST_XrSessionDrawViews(GHOST_IXrContext *xr_context, void *customdata);
|
||||
/**
|
||||
* Check if a \a xr_context has a session that, according to the OpenXR definition would be
|
||||
* considered to be 'running'
|
||||
* (https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#session_running).
|
||||
*/
|
||||
int GHOST_XrSessionIsRunning(const GHOST_IXrContext *xr_context);
|
||||
|
||||
/**
|
||||
* Check if \a xr_context has a session that requires an upside-down frame-buffer (compared to
|
||||
* GPU). If true, the render result should be flipped vertically for correct output.
|
||||
* \note Only to be called after session start, may otherwise result in a false negative.
|
||||
*/
|
||||
int GHOST_XrSessionNeedsUpsideDownDrawing(const GHOST_IXrContext *xr_context);
|
||||
|
||||
/* events */
|
||||
/**
|
||||
* Invoke handling of all OpenXR events for \a xr_context. Should be called on every main-loop
|
||||
* iteration and will early-exit if \a xr_context is nullptr (so caller doesn't have to check).
|
||||
*
|
||||
* \returns GHOST_kSuccess if any event was handled, otherwise GHOST_kFailure.
|
||||
*/
|
||||
GHOST_TSuccess GHOST_XrEventsHandle(GHOST_IXrContext *xr_context);
|
||||
|
||||
/* actions */
|
||||
/**
|
||||
* Create an OpenXR action set for input/output.
|
||||
*/
|
||||
int GHOST_XrCreateActionSet(GHOST_IXrContext *xr_context, const GHOST_XrActionSetInfo *info);
|
||||
|
||||
/**
|
||||
* Destroy a previously created OpenXR action set.
|
||||
*/
|
||||
void GHOST_XrDestroyActionSet(GHOST_IXrContext *xr_context, const char *action_set_name);
|
||||
|
||||
/**
|
||||
* Create OpenXR input/output actions.
|
||||
*/
|
||||
int GHOST_XrCreateActions(GHOST_IXrContext *xr_context,
|
||||
const char *action_set_name,
|
||||
uint32_t count,
|
||||
const GHOST_XrActionInfo *infos);
|
||||
|
||||
/**
|
||||
* Destroy previously created OpenXR actions.
|
||||
*/
|
||||
void GHOST_XrDestroyActions(GHOST_IXrContext *xr_context,
|
||||
const char *action_set_name,
|
||||
uint32_t count,
|
||||
const char *const *action_names);
|
||||
|
||||
/**
|
||||
* Create input/output path bindings for OpenXR actions.
|
||||
*/
|
||||
int GHOST_XrCreateActionBindings(GHOST_IXrContext *xr_context,
|
||||
const char *action_set_name,
|
||||
uint32_t count,
|
||||
const GHOST_XrActionProfileInfo *infos);
|
||||
|
||||
/**
|
||||
* Destroy previously created bindings for OpenXR actions.
|
||||
*/
|
||||
void GHOST_XrDestroyActionBindings(GHOST_IXrContext *xr_context,
|
||||
const char *action_set_name,
|
||||
uint32_t count,
|
||||
const char *const *action_names,
|
||||
const char *const *profile_paths);
|
||||
|
||||
/**
|
||||
* Attach all created action sets to the current OpenXR session.
|
||||
*/
|
||||
int GHOST_XrAttachActionSets(GHOST_IXrContext *xr_context);
|
||||
|
||||
/**
|
||||
* Update button/tracking states for OpenXR actions.
|
||||
*
|
||||
* \param action_set_name: The name of the action set to sync. If nullptr, all action sets
|
||||
* attached to the session will be synced.
|
||||
*/
|
||||
int GHOST_XrSyncActions(GHOST_IXrContext *xr_context, const char *action_set_name);
|
||||
|
||||
/**
|
||||
* Apply an OpenXR haptic output action.
|
||||
*/
|
||||
int GHOST_XrApplyHapticAction(GHOST_IXrContext *xr_context_handle,
|
||||
const char *action_set_name,
|
||||
const char *action_name,
|
||||
const char *subaction_path,
|
||||
const int64_t *duration,
|
||||
const float *frequency,
|
||||
const float *amplitude);
|
||||
|
||||
/**
|
||||
* Stop a previously applied OpenXR haptic output action.
|
||||
*/
|
||||
void GHOST_XrStopHapticAction(GHOST_IXrContext *xr_context_handle,
|
||||
const char *action_set_name,
|
||||
const char *action_name,
|
||||
const char *subaction_path);
|
||||
|
||||
/**
|
||||
* Get action set custom data (owned by Blender, not GHOST).
|
||||
*/
|
||||
void *GHOST_XrGetActionSetCustomdata(GHOST_IXrContext *xr_context, const char *action_set_name);
|
||||
|
||||
/**
|
||||
* Get action custom data (owned by Blender, not GHOST).
|
||||
*/
|
||||
void *GHOST_XrGetActionCustomdata(GHOST_IXrContext *xr_context,
|
||||
const char *action_set_name,
|
||||
const char *action_name);
|
||||
|
||||
/**
|
||||
* Get the number of actions in an action set.
|
||||
*/
|
||||
unsigned int GHOST_XrGetActionCount(GHOST_IXrContext *xr_context, const char *action_set_name);
|
||||
|
||||
/**
|
||||
* Get custom data for all actions in an action set.
|
||||
*/
|
||||
void GHOST_XrGetActionCustomdataArray(GHOST_IXrContext *xr_context,
|
||||
const char *action_set_name,
|
||||
void **r_customdata_array);
|
||||
|
||||
/* controller model */
|
||||
/**
|
||||
* Load the OpenXR controller model.
|
||||
*/
|
||||
int GHOST_XrLoadControllerModel(GHOST_IXrContext *xr_context, const char *subaction_path);
|
||||
|
||||
/**
|
||||
* Unload the OpenXR controller model.
|
||||
*/
|
||||
void GHOST_XrUnloadControllerModel(GHOST_IXrContext *xr_context, const char *subaction_path);
|
||||
|
||||
/**
|
||||
* Update component transforms for the OpenXR controller model.
|
||||
*/
|
||||
int GHOST_XrUpdateControllerModelComponents(GHOST_IXrContext *xr_context,
|
||||
const char *subaction_path);
|
||||
|
||||
/**
|
||||
* Get vertex data for the OpenXR controller model.
|
||||
*/
|
||||
int GHOST_XrGetControllerModelData(GHOST_IXrContext *xr_context,
|
||||
const char *subaction_path,
|
||||
GHOST_XrControllerModelData *r_data);
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
|
||||
/**
|
||||
* This struct stores the state of the mouse buttons.
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -11,8 +11,6 @@
|
|||
*/
|
||||
|
||||
#include "GHOST_CallbackEventConsumer.hh"
|
||||
#include "GHOST_C-api.h"
|
||||
#include "GHOST_Debug.hh"
|
||||
|
||||
GHOST_CallbackEventConsumer::GHOST_CallbackEventConsumer(GHOST_EventCallbackProcPtr eventCallback,
|
||||
GHOST_TUserDataPtr user_data)
|
||||
|
|
@ -23,5 +21,5 @@ GHOST_CallbackEventConsumer::GHOST_CallbackEventConsumer(GHOST_EventCallbackProc
|
|||
|
||||
bool GHOST_CallbackEventConsumer::processEvent(const GHOST_IEvent *event)
|
||||
{
|
||||
return event_callback_((GHOST_EventHandle)event, user_data_);
|
||||
return event_callback_(event, user_data_);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "GHOST_IContext.hh"
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
|
||||
#include <cstdlib> /* For `nullptr`. */
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "GHOST_Context.hh"
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include <Metal/Metal.h>
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "GHOST_SystemWin32.hh"
|
||||
#include "GHOST_Types.hh"
|
||||
#include "GHOST_WindowWin32.hh"
|
||||
#include <GHOST_Types.h>
|
||||
#include <string.h>
|
||||
|
||||
class GHOST_DropTargetWin32 : public IDropTarget {
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "GHOST_SystemX11.hh"
|
||||
#include "GHOST_Types.hh"
|
||||
#include "GHOST_WindowX11.hh"
|
||||
#include <GHOST_Types.h>
|
||||
|
||||
#include "xdnd.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@
|
|||
* - Update mouse position (GHOST_kEventDraggingUpdated) sent upon each mouse move until the
|
||||
* drag & drop operation stops, to give the updated mouse position.
|
||||
* Useful to highlight a potential destination, and update the status
|
||||
* (through GHOST_setAcceptDragOperation) telling if the object can be dropped at the current
|
||||
* cursor position.
|
||||
* (through GHOST_IWindow::setAcceptDragOperation) telling if the object can be dropped at the
|
||||
* current cursor position.
|
||||
*
|
||||
* - Abort drag & drop sequence (#GHOST_kEventDraggingExited)
|
||||
* sent when the user moved the mouse outside the window.
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
#include "GHOST_Xr_openxr_includes.hh"
|
||||
|
||||
class GHOST_IXrGraphicsBinding {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
#ifdef WITH_INPUT_IME
|
||||
|
||||
# include "GHOST_ImeWin32.hh"
|
||||
# include "GHOST_C-api.h"
|
||||
# include "GHOST_WindowWin32.hh"
|
||||
# include "utfconv.hh"
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
|
||||
/**
|
||||
* Stores the state of modifier keys.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
#include "GHOST_Debug.hh"
|
||||
#include "GHOST_EventKey.hh"
|
||||
#include "GHOST_EventNDOF.hh"
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
#include "GHOST_WindowManager.hh"
|
||||
#include "GHOST_utildefines.hh"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,57 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2010 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
*/
|
||||
|
||||
#include "GHOST_Path-api.hh"
|
||||
#include "GHOST_ISystemPaths.hh"
|
||||
#include "GHOST_Types.h"
|
||||
#include "intern/GHOST_Debug.hh"
|
||||
|
||||
GHOST_TSuccess GHOST_CreateSystemPaths()
|
||||
{
|
||||
return GHOST_ISystemPaths::create();
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_DisposeSystemPaths()
|
||||
{
|
||||
return GHOST_ISystemPaths::dispose();
|
||||
}
|
||||
|
||||
const char *GHOST_getSystemDir(int version, const char *versionstr)
|
||||
{
|
||||
const GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
|
||||
return systemPaths ? systemPaths->getSystemDir(version, versionstr) : nullptr;
|
||||
}
|
||||
|
||||
const char *GHOST_getUserDir(int version, const char *versionstr)
|
||||
{
|
||||
const GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
|
||||
/* Shouldn't be `nullptr`. */
|
||||
return systemPaths ? systemPaths->getUserDir(version, versionstr) : nullptr;
|
||||
}
|
||||
|
||||
std::optional<std::string> GHOST_getUserSpecialDir(GHOST_TUserSpecialDirTypes type)
|
||||
{
|
||||
const GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
|
||||
/* Shouldn't be `nullptr`. */
|
||||
return systemPaths ? systemPaths->getUserSpecialDir(type) : nullptr;
|
||||
}
|
||||
|
||||
const char *GHOST_getBinaryDir()
|
||||
{
|
||||
const GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
|
||||
/* Shouldn't be `nullptr`. */
|
||||
return systemPaths ? systemPaths->getBinaryDir() : nullptr;
|
||||
}
|
||||
|
||||
void GHOST_addToSystemRecentFiles(const char *filepath)
|
||||
{
|
||||
const GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
|
||||
if (systemPaths) {
|
||||
systemPaths->addToSystemRecentFiles(filepath);
|
||||
}
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include "GHOST_Debug.hh"
|
||||
#include "GHOST_PathUtils.hh"
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
|
||||
/* Based on: https://stackoverflow.com/a/2766963/432509 */
|
||||
|
||||
|
|
|
|||
|
|
@ -242,6 +242,8 @@ uint32_t GHOST_System::getCursorPreferredLogicalSize() const
|
|||
|
||||
GHOST_TSuccess GHOST_System::getModifierKeyState(GHOST_TModifierKey mask, bool &is_down) const
|
||||
{
|
||||
is_down = false;
|
||||
|
||||
GHOST_ModifierKeys keys;
|
||||
/* Get the state of all modifier keys. */
|
||||
GHOST_TSuccess success = getModifierKeys(keys);
|
||||
|
|
@ -254,6 +256,8 @@ GHOST_TSuccess GHOST_System::getModifierKeyState(GHOST_TModifierKey mask, bool &
|
|||
|
||||
GHOST_TSuccess GHOST_System::getButtonState(GHOST_TButton mask, bool &is_down) const
|
||||
{
|
||||
is_down = false;
|
||||
|
||||
GHOST_Buttons buttons;
|
||||
/* Get the state of all mouse buttons. */
|
||||
GHOST_TSuccess success = getButtons(buttons);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../GHOST_Types.h"
|
||||
#include "../GHOST_Types.hh"
|
||||
#include "GHOST_System.hh"
|
||||
#include "GHOST_WindowNULL.hh"
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "../GHOST_Types.h"
|
||||
#include "../GHOST_Types.hh"
|
||||
#include "GHOST_SystemPaths.hh"
|
||||
|
||||
class GHOST_SystemPathsUnix : public GHOST_SystemPaths {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../GHOST_Types.h"
|
||||
#include "../GHOST_Types.hh"
|
||||
#include "GHOST_Event.hh"
|
||||
#include "GHOST_System.hh"
|
||||
#include "GHOST_TimerManager.hh"
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../GHOST_Types.h"
|
||||
#include "../GHOST_Types.hh"
|
||||
#include "GHOST_System.hh"
|
||||
#include "GHOST_WindowWayland.hh"
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include <X11/XKBlib.h> /* Allow detectable auto-repeat. */
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include "../GHOST_Types.h"
|
||||
#include "../GHOST_Types.hh"
|
||||
#include "GHOST_System.hh"
|
||||
|
||||
/* For tablets. */
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
|
||||
class GHOST_TimerTask;
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
# error WIN32 only!
|
||||
#endif // WIN32
|
||||
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
|
||||
#include <directmanipulation.h>
|
||||
#include <wrl.h>
|
||||
|
|
|
|||
|
|
@ -76,9 +76,6 @@ class GHOST_Window : public GHOST_IWindow {
|
|||
return context_ != nullptr;
|
||||
}
|
||||
|
||||
/** \copydoc #GHOST_IWindow::getOSWindow */
|
||||
void *getOSWindow() const override;
|
||||
|
||||
/** \copydoc #GHOST_IWindow::setPath */
|
||||
void setPath(const char * /*filepath*/) override
|
||||
{
|
||||
|
|
@ -142,15 +139,10 @@ class GHOST_Window : public GHOST_IWindow {
|
|||
GHOST_Rect *bounds,
|
||||
int32_t mouse_ungrab_xy[2]) override;
|
||||
|
||||
/** \copydoc #GHOST_IWindow::getCursorGrabBounds */
|
||||
GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds) const override;
|
||||
|
||||
void getCursorGrabState(GHOST_TGrabCursorMode &mode,
|
||||
GHOST_TAxisFlag &wrap_axis,
|
||||
GHOST_Rect &bounds,
|
||||
bool &use_software_cursor) override;
|
||||
/** \copydoc #GHOST_IWindow::getCursorGrabUseSoftwareDisplay */
|
||||
bool getCursorGrabUseSoftwareDisplay() override;
|
||||
|
||||
/** \copydoc #GHOST_IWindow::setProgressBar */
|
||||
GHOST_TSuccess setProgressBar(float /*progress*/) override
|
||||
|
|
@ -172,15 +164,9 @@ class GHOST_Window : public GHOST_IWindow {
|
|||
/** \copydoc #GHOST_IWindow::setAcceptDragOperation */
|
||||
void setAcceptDragOperation(bool can_accept) override;
|
||||
|
||||
/** \copydoc #GHOST_IWindow::canAcceptDragOperation */
|
||||
bool canAcceptDragOperation() const override;
|
||||
|
||||
/** \copydoc #GHOST_IWindow::setModifiedState */
|
||||
GHOST_TSuccess setModifiedState(bool is_unsaved_changes) override;
|
||||
|
||||
/** \copydoc #GHOST_IWindow::getModifiedState */
|
||||
bool getModifiedState() override;
|
||||
|
||||
/** \copydoc #GHOST_IWindow::getDrawingContextType */
|
||||
inline GHOST_TDrawingContextType getDrawingContextType() override;
|
||||
|
||||
|
|
@ -220,7 +206,7 @@ class GHOST_Window : public GHOST_IWindow {
|
|||
unsigned int getDefaultFramebuffer() override;
|
||||
|
||||
#ifdef WITH_VULKAN_BACKEND
|
||||
/** \copydoc #GHOST_GetVulkanSwapChainFormat */
|
||||
/** \copydoc #GHOST_IContext::getVulkanHandles */
|
||||
virtual GHOST_TSuccess getVulkanSwapChainFormat(
|
||||
GHOST_VulkanSwapChainData *r_swap_chain_data) override;
|
||||
#endif
|
||||
|
|
@ -271,6 +257,24 @@ class GHOST_Window : public GHOST_IWindow {
|
|||
}
|
||||
#endif /* WITH_INPUT_IME */
|
||||
|
||||
/**
|
||||
* Returns the associated OS object/handle.
|
||||
* \return The associated OS object/handle.
|
||||
*/
|
||||
virtual void *getOSWindow() const;
|
||||
|
||||
/**
|
||||
* Returns acceptance of the dropped object.
|
||||
* Usually called by the "object dropped" event handling function.
|
||||
*/
|
||||
virtual bool canAcceptDragOperation() const;
|
||||
|
||||
/**
|
||||
* Gets the cursor grab region, if unset the window is used.
|
||||
* Reset when grab is disabled.
|
||||
*/
|
||||
virtual GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds) const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Tries to install a rendering context in this window.
|
||||
|
|
@ -310,6 +314,17 @@ class GHOST_Window : public GHOST_IWindow {
|
|||
return GHOST_kFailure;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return true when a software cursor should be used.
|
||||
*/
|
||||
virtual bool getCursorGrabUseSoftwareDisplay();
|
||||
|
||||
/**
|
||||
* Gets the window "modified" status, indicating unsaved changes.
|
||||
* \return True if there are unsaved changes
|
||||
*/
|
||||
virtual bool getModifiedState();
|
||||
|
||||
GHOST_TSuccess releaseNativeHandles();
|
||||
|
||||
/** The drawing context installed in this window. */
|
||||
|
|
|
|||
|
|
@ -96,7 +96,8 @@ GHOST_IWindow *GHOST_WindowManager::getWindowAssociatedWithOSWindow(const void *
|
|||
std::vector<GHOST_IWindow *>::iterator iter;
|
||||
|
||||
for (iter = windows_.begin(); iter != windows_.end(); ++iter) {
|
||||
if ((*iter)->getOSWindow() == osWindow) {
|
||||
GHOST_Window *window = static_cast<GHOST_Window *>(*iter);
|
||||
if (window->getOSWindow() == osWindow) {
|
||||
return *iter;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
/* Currently all of the logic is for CSD. */
|
||||
|
||||
#include "GHOST_WindowWaylandCSD.hh" /* Own include. */
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
#include "GHOST_utildefines.hh"
|
||||
|
||||
#include <array> /* For `std::array`. */
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
#include "GHOST_Debug.hh"
|
||||
#include "GHOST_IconX11.hh"
|
||||
#include "GHOST_SystemX11.hh"
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
#include "GHOST_WindowX11.hh"
|
||||
#include "GHOST_utildefines.hh"
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
#include <vector>
|
||||
#include <wtypes.h>
|
||||
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
|
||||
#include <wintab.h>
|
||||
/* PACKETDATA and PACKETMODE modify structs in pktdef.h, so make sure they come first. */
|
||||
|
|
|
|||
|
|
@ -8,16 +8,34 @@
|
|||
* Abstraction for XR (VR, AR, MR, ..) access via OpenXR.
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
|
||||
#include "GHOST_C-api.h"
|
||||
|
||||
#include "GHOST_XrContext.hh"
|
||||
#include "GHOST_XrException.hh"
|
||||
#include "GHOST_Xr_intern.hh"
|
||||
#include "GHOST_XrSession.hh"
|
||||
|
||||
GHOST_XrContextHandle GHOST_XrContextCreate(const GHOST_XrContextCreateInfo *create_info)
|
||||
#include "GHOST_Xr-api.hh"
|
||||
|
||||
#define GHOST_XR_CAPI_CALL(call, ctx) \
|
||||
try { \
|
||||
call; \
|
||||
} \
|
||||
catch (GHOST_XrException & e) { \
|
||||
(ctx)->dispatchErrorMessage(&e); \
|
||||
}
|
||||
|
||||
#define GHOST_XR_CAPI_CALL_RET(call, ctx) \
|
||||
try { \
|
||||
return call; \
|
||||
} \
|
||||
catch (GHOST_XrException & e) { \
|
||||
(ctx)->dispatchErrorMessage(&e); \
|
||||
}
|
||||
|
||||
void GHOST_XrErrorHandler(GHOST_XrErrorHandlerFn handler_fn, void *customdata)
|
||||
{
|
||||
GHOST_XrContext::setErrorHandler(handler_fn, customdata);
|
||||
}
|
||||
|
||||
GHOST_IXrContext *GHOST_XrContextCreate(const GHOST_XrContextCreateInfo *create_info)
|
||||
{
|
||||
auto xr_context = std::make_unique<GHOST_XrContext>(create_info);
|
||||
|
||||
|
|
@ -32,15 +50,219 @@ GHOST_XrContextHandle GHOST_XrContextCreate(const GHOST_XrContextCreateInfo *cre
|
|||
}
|
||||
|
||||
/* Give ownership to the caller. */
|
||||
return (GHOST_XrContextHandle)xr_context.release();
|
||||
return xr_context.release();
|
||||
}
|
||||
|
||||
void GHOST_XrContextDestroy(GHOST_XrContextHandle xr_contexthandle)
|
||||
void GHOST_XrContextDestroy(GHOST_IXrContext *xr_context)
|
||||
{
|
||||
delete (GHOST_XrContext *)xr_contexthandle;
|
||||
delete xr_context;
|
||||
}
|
||||
|
||||
void GHOST_XrErrorHandler(GHOST_XrErrorHandlerFn handler_fn, void *customdata)
|
||||
void GHOST_XrSessionStart(GHOST_IXrContext *xr_context, const GHOST_XrSessionBeginInfo *begin_info)
|
||||
{
|
||||
GHOST_XrContext::setErrorHandler(handler_fn, customdata);
|
||||
GHOST_XR_CAPI_CALL(xr_context->startSession(begin_info), xr_context);
|
||||
}
|
||||
|
||||
void GHOST_XrSessionEnd(GHOST_IXrContext *xr_context)
|
||||
{
|
||||
GHOST_XR_CAPI_CALL(xr_context->endSession(), xr_context);
|
||||
}
|
||||
|
||||
void GHOST_XrSessionDrawViews(GHOST_IXrContext *xr_context, void *draw_customdata)
|
||||
{
|
||||
GHOST_XR_CAPI_CALL(xr_context->drawSessionViews(draw_customdata), xr_context);
|
||||
}
|
||||
|
||||
int GHOST_XrSessionIsRunning(const GHOST_IXrContext *xr_context)
|
||||
{
|
||||
GHOST_XR_CAPI_CALL_RET(xr_context->isSessionRunning(), xr_context);
|
||||
return 0; /* Only reached if exception is thrown. */
|
||||
}
|
||||
|
||||
void GHOST_XrGraphicsContextBindFuncs(GHOST_IXrContext *xr_context,
|
||||
GHOST_XrGraphicsContextBindFn bind_fn,
|
||||
GHOST_XrGraphicsContextUnbindFn unbind_fn)
|
||||
{
|
||||
GHOST_XR_CAPI_CALL(xr_context->setGraphicsContextBindFuncs(bind_fn, unbind_fn), xr_context);
|
||||
}
|
||||
|
||||
void GHOST_XrDrawViewFunc(GHOST_IXrContext *xr_context, GHOST_XrDrawViewFn draw_view_fn)
|
||||
{
|
||||
GHOST_XR_CAPI_CALL(xr_context->setDrawViewFunc(draw_view_fn), xr_context);
|
||||
}
|
||||
|
||||
void GHOST_XrPassthroughEnabledFunc(GHOST_IXrContext *xr_context,
|
||||
GHOST_XrPassthroughEnabledFn passthrough_enabled_fn)
|
||||
{
|
||||
GHOST_XR_CAPI_CALL(xr_context->setPassthroughEnabledFunc(passthrough_enabled_fn), xr_context);
|
||||
}
|
||||
|
||||
void GHOST_XrDisablePassthroughFunc(GHOST_IXrContext *xr_context,
|
||||
GHOST_XrDisablePassthroughFn disable_passthrough_fn)
|
||||
{
|
||||
GHOST_XR_CAPI_CALL(xr_context->setDisablePassthroughFunc(disable_passthrough_fn), xr_context);
|
||||
}
|
||||
|
||||
int GHOST_XrSessionNeedsUpsideDownDrawing(const GHOST_IXrContext *xr_context)
|
||||
{
|
||||
GHOST_XR_CAPI_CALL_RET(xr_context->needsUpsideDownDrawing(), xr_context);
|
||||
return 0; /* Only reached if exception is thrown. */
|
||||
}
|
||||
|
||||
int GHOST_XrCreateActionSet(GHOST_IXrContext *xr_context, const GHOST_XrActionSetInfo *info)
|
||||
{
|
||||
GHOST_XrSession *xr_session = xr_context->getSession();
|
||||
GHOST_XR_CAPI_CALL_RET(xr_session->createActionSet(*info), xr_context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GHOST_XrDestroyActionSet(GHOST_IXrContext *xr_context, const char *action_set_name)
|
||||
{
|
||||
GHOST_XrSession *xr_session = xr_context->getSession();
|
||||
GHOST_XR_CAPI_CALL(xr_session->destroyActionSet(action_set_name), xr_context);
|
||||
}
|
||||
|
||||
int GHOST_XrCreateActions(GHOST_IXrContext *xr_context,
|
||||
const char *action_set_name,
|
||||
uint32_t count,
|
||||
const GHOST_XrActionInfo *infos)
|
||||
{
|
||||
GHOST_XrSession *xr_session = xr_context->getSession();
|
||||
GHOST_XR_CAPI_CALL_RET(xr_session->createActions(action_set_name, count, infos), xr_context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GHOST_XrDestroyActions(GHOST_IXrContext *xr_context,
|
||||
const char *action_set_name,
|
||||
uint32_t count,
|
||||
const char *const *action_names)
|
||||
{
|
||||
GHOST_XrSession *xr_session = xr_context->getSession();
|
||||
GHOST_XR_CAPI_CALL(xr_session->destroyActions(action_set_name, count, action_names), xr_context);
|
||||
}
|
||||
|
||||
int GHOST_XrCreateActionBindings(GHOST_IXrContext *xr_context,
|
||||
const char *action_set_name,
|
||||
uint32_t count,
|
||||
const GHOST_XrActionProfileInfo *infos)
|
||||
{
|
||||
GHOST_XrSession *xr_session = xr_context->getSession();
|
||||
GHOST_XR_CAPI_CALL_RET(xr_session->createActionBindings(action_set_name, count, infos),
|
||||
xr_context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GHOST_XrDestroyActionBindings(GHOST_IXrContext *xr_context,
|
||||
const char *action_set_name,
|
||||
uint32_t count,
|
||||
const char *const *action_names,
|
||||
const char *const *profile_paths)
|
||||
{
|
||||
GHOST_XrSession *xr_session = xr_context->getSession();
|
||||
GHOST_XR_CAPI_CALL(
|
||||
xr_session->destroyActionBindings(action_set_name, count, action_names, profile_paths),
|
||||
xr_context);
|
||||
}
|
||||
|
||||
int GHOST_XrAttachActionSets(GHOST_IXrContext *xr_context)
|
||||
{
|
||||
GHOST_XrSession *xr_session = xr_context->getSession();
|
||||
GHOST_XR_CAPI_CALL_RET(xr_session->attachActionSets(), xr_context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GHOST_XrSyncActions(GHOST_IXrContext *xr_context, const char *action_set_name)
|
||||
{
|
||||
GHOST_XrSession *xr_session = xr_context->getSession();
|
||||
GHOST_XR_CAPI_CALL_RET(xr_session->syncActions(action_set_name), xr_context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GHOST_XrApplyHapticAction(GHOST_IXrContext *xr_context,
|
||||
const char *action_set_name,
|
||||
const char *action_name,
|
||||
const char *subaction_path,
|
||||
const int64_t *duration,
|
||||
const float *frequency,
|
||||
const float *amplitude)
|
||||
{
|
||||
GHOST_XrSession *xr_session = xr_context->getSession();
|
||||
GHOST_XR_CAPI_CALL_RET(
|
||||
xr_session->applyHapticAction(
|
||||
action_set_name, action_name, subaction_path, *duration, *frequency, *amplitude),
|
||||
xr_context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GHOST_XrStopHapticAction(GHOST_IXrContext *xr_context,
|
||||
const char *action_set_name,
|
||||
const char *action_name,
|
||||
const char *subaction_path)
|
||||
{
|
||||
GHOST_XrSession *xr_session = xr_context->getSession();
|
||||
GHOST_XR_CAPI_CALL(xr_session->stopHapticAction(action_set_name, action_name, subaction_path),
|
||||
xr_context);
|
||||
}
|
||||
|
||||
void *GHOST_XrGetActionSetCustomdata(GHOST_IXrContext *xr_context, const char *action_set_name)
|
||||
{
|
||||
GHOST_XrSession *xr_session = xr_context->getSession();
|
||||
GHOST_XR_CAPI_CALL_RET(xr_session->getActionSetCustomdata(action_set_name), xr_context);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void *GHOST_XrGetActionCustomdata(GHOST_IXrContext *xr_context,
|
||||
const char *action_set_name,
|
||||
const char *action_name)
|
||||
{
|
||||
GHOST_XrSession *xr_session = xr_context->getSession();
|
||||
GHOST_XR_CAPI_CALL_RET(xr_session->getActionCustomdata(action_set_name, action_name),
|
||||
xr_context);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint GHOST_XrGetActionCount(GHOST_IXrContext *xr_context, const char *action_set_name)
|
||||
{
|
||||
GHOST_XrSession *xr_session = xr_context->getSession();
|
||||
GHOST_XR_CAPI_CALL_RET(xr_session->getActionCount(action_set_name), xr_context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GHOST_XrGetActionCustomdataArray(GHOST_IXrContext *xr_context,
|
||||
const char *action_set_name,
|
||||
void **r_customdata_array)
|
||||
{
|
||||
GHOST_XrSession *xr_session = xr_context->getSession();
|
||||
GHOST_XR_CAPI_CALL(xr_session->getActionCustomdataArray(action_set_name, r_customdata_array),
|
||||
xr_context);
|
||||
}
|
||||
|
||||
int GHOST_XrLoadControllerModel(GHOST_IXrContext *xr_context, const char *subaction_path)
|
||||
{
|
||||
GHOST_XrSession *xr_session = xr_context->getSession();
|
||||
GHOST_XR_CAPI_CALL_RET(xr_session->loadControllerModel(subaction_path), xr_context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GHOST_XrUnloadControllerModel(GHOST_IXrContext *xr_context, const char *subaction_path)
|
||||
{
|
||||
GHOST_XrSession *xr_session = xr_context->getSession();
|
||||
GHOST_XR_CAPI_CALL(xr_session->unloadControllerModel(subaction_path), xr_context);
|
||||
}
|
||||
|
||||
int GHOST_XrUpdateControllerModelComponents(GHOST_IXrContext *xr_context,
|
||||
const char *subaction_path)
|
||||
{
|
||||
GHOST_XrSession *xr_session = xr_context->getSession();
|
||||
GHOST_XR_CAPI_CALL_RET(xr_session->updateControllerModelComponents(subaction_path), xr_context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GHOST_XrGetControllerModelData(GHOST_IXrContext *xr_context,
|
||||
const char *subaction_path,
|
||||
GHOST_XrControllerModelData *r_data)
|
||||
{
|
||||
GHOST_XrSession *xr_session = xr_context->getSession();
|
||||
GHOST_XR_CAPI_CALL_RET(xr_session->getControllerModelData(subaction_path, *r_data), xr_context);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
|
||||
#include "GHOST_XrException.hh"
|
||||
#include "GHOST_Xr_intern.hh"
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
#include "BLI_string_ref.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
#include "GHOST_XrException.hh"
|
||||
#include "GHOST_XrSession.hh"
|
||||
#include "GHOST_Xr_intern.hh"
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#include <Eigen/Core>
|
||||
#include <Eigen/Geometry>
|
||||
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
#include "GHOST_XrException.hh"
|
||||
#include "GHOST_Xr_intern.hh"
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include <iostream>
|
||||
|
||||
#include "GHOST_C-api.h"
|
||||
#include "GHOST_Xr-api.hh"
|
||||
#include "GHOST_XrContext.hh"
|
||||
#include "GHOST_Xr_intern.hh"
|
||||
|
||||
|
|
@ -21,13 +21,13 @@ static bool GHOST_XrEventPollNext(XrInstance instance, XrEventDataBuffer &r_even
|
|||
return (xrPollEvent(instance, &r_event_data) == XR_SUCCESS);
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_XrEventsHandle(GHOST_XrContextHandle xr_contexthandle)
|
||||
GHOST_TSuccess GHOST_XrEventsHandle(GHOST_IXrContext *xr_contexthandle)
|
||||
{
|
||||
if (xr_contexthandle == nullptr) {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
GHOST_XrContext &xr_context = *(GHOST_XrContext *)xr_contexthandle;
|
||||
GHOST_XrContext &xr_context = *static_cast<GHOST_XrContext *>(xr_contexthandle);
|
||||
XrEventDataBuffer event_buffer; /* Structure big enough to hold all possible events. */
|
||||
|
||||
while (GHOST_XrEventPollNext(xr_context.getInstance(), event_buffer)) {
|
||||
|
|
|
|||
|
|
@ -36,10 +36,6 @@
|
|||
# include "GHOST_XrGraphicsBindingMetal.hh"
|
||||
#endif
|
||||
|
||||
#include "GHOST_C-api.h"
|
||||
#include "GHOST_XrException.hh"
|
||||
#include "GHOST_Xr_intern.hh"
|
||||
|
||||
#include "GHOST_IXrGraphicsBinding.hh"
|
||||
|
||||
#if defined(WITH_OPENGL_BACKEND)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class GHOST_ContextMTL;
|
|||
#include <vector>
|
||||
|
||||
#include "GHOST_IXrGraphicsBinding.hh"
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
|
||||
class GHOST_XrGraphicsBindingMetal : public GHOST_IXrGraphicsBinding {
|
||||
PFN_xrGetMetalGraphicsRequirementsKHR xrGetMetalGraphicsRequirementsKHR_ = nullptr;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "GHOST_ContextVK.hh"
|
||||
#include "GHOST_IXrGraphicsBinding.hh"
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
|
||||
class GHOST_XrGraphicsBindingVulkan : public GHOST_IXrGraphicsBinding {
|
||||
struct {
|
||||
|
|
|
|||
|
|
@ -15,8 +15,7 @@
|
|||
|
||||
#include "BLI_span.hh"
|
||||
|
||||
#include "GHOST_C-api.h"
|
||||
|
||||
#include "GHOST_Context.hh"
|
||||
#include "GHOST_IXrGraphicsBinding.hh"
|
||||
#include "GHOST_XrAction.hh"
|
||||
#include "GHOST_XrContext.hh"
|
||||
|
|
@ -659,7 +658,7 @@ void GHOST_XrSession::unbindGraphicsContext()
|
|||
{
|
||||
const GHOST_XrCustomFuncs &custom_funcs = context_->getCustomFuncs();
|
||||
if (custom_funcs.gpu_ctx_unbind_fn) {
|
||||
custom_funcs.gpu_ctx_unbind_fn((GHOST_ContextHandle)gpu_ctx_);
|
||||
custom_funcs.gpu_ctx_unbind_fn(gpu_ctx_);
|
||||
}
|
||||
gpu_ctx_ = nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,11 +8,8 @@
|
|||
|
||||
#include <cassert>
|
||||
|
||||
#include "GHOST_C-api.h"
|
||||
|
||||
#include "GHOST_IXrGraphicsBinding.hh"
|
||||
#include "GHOST_XrException.hh"
|
||||
#include "GHOST_XrSession.hh"
|
||||
#include "GHOST_Xr_intern.hh"
|
||||
|
||||
#include "GHOST_XrSwapchain.hh"
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "GHOST_Types.hh"
|
||||
#include "GHOST_Xr_openxr_includes.hh"
|
||||
|
||||
#define CHECK_XR(call, error_msg) \
|
||||
|
|
|
|||
|
|
@ -1,283 +0,0 @@
|
|||
# SPDX-FileCopyrightText: 2011-2023 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# see "cmake --help-policy CMP0003"
|
||||
# So library linking is more sane
|
||||
cmake_policy(SET CMP0003 NEW)
|
||||
|
||||
# So BUILDINFO and BLENDERPATH strings are automatically quoted
|
||||
cmake_policy(SET CMP0005 NEW)
|
||||
|
||||
# So syntax problems are errors
|
||||
cmake_policy(SET CMP0010 NEW)
|
||||
|
||||
# Input directories must have `CMakeLists.txt`.
|
||||
cmake_policy(SET CMP0014 NEW)
|
||||
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
project(GhostMultiTest)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../../../build_files/cmake/Modules")
|
||||
|
||||
set(WITH_GUARDEDALLOC ON)
|
||||
|
||||
add_executable(datatoc
|
||||
"${CMAKE_SOURCE_DIR}/../../../source/blender/datatoc/datatoc.c")
|
||||
|
||||
# Fake the current source directory for includes.
|
||||
set(_CMAKE_CURRENT_SOURCE_DIR_INIT "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Macros
|
||||
|
||||
# For data_to_c macro.
|
||||
# include(../../../build_files/cmake/macros.cmake)
|
||||
|
||||
# stub macro, does nothing
|
||||
macro(blender_add_lib
|
||||
name
|
||||
sources
|
||||
includes
|
||||
includes_sys
|
||||
library_deps # ignored.
|
||||
)
|
||||
|
||||
endmacro()
|
||||
|
||||
# suffix relative paths so we can use external cmake files
|
||||
macro(suffix_relpaths
|
||||
new_files files prefix)
|
||||
|
||||
set(${new_files})
|
||||
foreach(_file ${files})
|
||||
if(IS_ABSOLUTE "${_file}")
|
||||
list(APPEND ${new_files} ${_file})
|
||||
else()
|
||||
set(_file_to "${prefix}${_file}")
|
||||
list(APPEND ${new_files} ${_file_to})
|
||||
get_source_file_property(_is_generated ${_file} GENERATED)
|
||||
set_source_files_properties(${_file_to} PROPERTIES GENERATED ${_is_generated})
|
||||
unset(_file_to)
|
||||
unset(_is_generated)
|
||||
endif()
|
||||
endforeach()
|
||||
unset(_file)
|
||||
endmacro()
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Defines
|
||||
|
||||
# set the endian define
|
||||
if(MSVC)
|
||||
# For some reason this fails on MSVC.
|
||||
add_definitions(-D__LITTLE_ENDIAN__)
|
||||
else()
|
||||
include(TestBigEndian)
|
||||
test_big_endian(_SYSTEM_BIG_ENDIAN)
|
||||
if(_SYSTEM_BIG_ENDIAN)
|
||||
add_definitions(-D__BIG_ENDIAN__)
|
||||
else()
|
||||
add_definitions(-D__LITTLE_ENDIAN__)
|
||||
endif()
|
||||
unset(_SYSTEM_BIG_ENDIAN)
|
||||
endif()
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Libraries
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
set(WITH_GHOST_X11 ON)
|
||||
endif()
|
||||
|
||||
# BLF needs this to ignore GPU library
|
||||
add_definitions(-DBLF_STANDALONE)
|
||||
|
||||
# ghost
|
||||
include(${CMAKE_SOURCE_DIR}/../CMakeLists.txt)
|
||||
suffix_relpaths(INC_NEW "${INC}" "../")
|
||||
suffix_relpaths(SRC_NEW "${SRC}" "../")
|
||||
include_directories(${INC_NEW})
|
||||
add_library(ghost_lib ${SRC_NEW})
|
||||
|
||||
# string
|
||||
include(${CMAKE_SOURCE_DIR}/../../string/CMakeLists.txt)
|
||||
suffix_relpaths(INC_NEW "${INC}" "../../string/")
|
||||
suffix_relpaths(SRC_NEW "${SRC}" "../../string/")
|
||||
include_directories(${INC_NEW})
|
||||
add_library(string_lib ${SRC_NEW})
|
||||
|
||||
# `numaapi` (for 'bli_lib').
|
||||
include(${CMAKE_SOURCE_DIR}/../../numaapi/CMakeLists.txt)
|
||||
suffix_relpaths(INC_NEW "${INC}" "../../numaapi/")
|
||||
suffix_relpaths(SRC_NEW "${SRC}" "../../numaapi/")
|
||||
include_directories(${INC_NEW})
|
||||
add_library(numaapi_lib ${SRC_NEW})
|
||||
|
||||
# guardedalloc
|
||||
include(${CMAKE_SOURCE_DIR}/../../guardedalloc/CMakeLists.txt)
|
||||
suffix_relpaths(INC_NEW "${INC}" "../../guardedalloc/")
|
||||
suffix_relpaths(SRC_NEW "${SRC}" "../../guardedalloc/")
|
||||
include_directories(${INC_NEW})
|
||||
add_library(guardedalloc_lib ${SRC_NEW})
|
||||
|
||||
# `gpu` (used by `blenfont`).
|
||||
add_definitions(-DGPU_STANDALONE)
|
||||
set(CMAKE_CURRENT_SOURCE_DIR "${CMAKE_SOURCE_DIR}/../../../source/blender/gpu")
|
||||
include(${CMAKE_SOURCE_DIR}/../../../source/blender/gpu/CMakeLists.txt)
|
||||
suffix_relpaths(INC_NEW "${INC}" "../../../source/blender/gpu/")
|
||||
suffix_relpaths(SRC_NEW "${SRC}" "../../../source/blender/gpu/")
|
||||
include_directories(${INC_NEW})
|
||||
add_library(gpu_lib ${SRC_NEW})
|
||||
set(CMAKE_CURRENT_SOURCE_DIR "${_CMAKE_CURRENT_SOURCE_DIR_INIT}")
|
||||
|
||||
# `imbuf` (used by ???).
|
||||
# set(CMAKE_CURRENT_SOURCE_DIR "${CMAKE_SOURCE_DIR}/../../../source/blender/imbuf")
|
||||
# include(${CMAKE_SOURCE_DIR}/../../../source/blender/imbuf/CMakeLists.txt)
|
||||
# suffix_relpaths(INC_NEW "${INC}" "../../../source/blender/imbuf/")
|
||||
# suffix_relpaths(SRC_NEW "${SRC}" "../../../source/blender/imbuf/")
|
||||
# include_directories(${INC_NEW})
|
||||
# add_library(imbuf_lib ${SRC_NEW})
|
||||
# set(CMAKE_CURRENT_SOURCE_DIR "${_CMAKE_CURRENT_SOURCE_DIR_INIT}")
|
||||
|
||||
# `blenfont`.
|
||||
include(${CMAKE_SOURCE_DIR}/../../../source/blender/blenfont/CMakeLists.txt)
|
||||
suffix_relpaths(INC_NEW "${INC}" "../../../source/blender/blenfont/")
|
||||
suffix_relpaths(SRC_NEW "${SRC}" "../../../source/blender/blenfont/")
|
||||
include_directories(${INC_NEW})
|
||||
add_library(blenfont_lib ${SRC_NEW})
|
||||
|
||||
# `wcwidth`.
|
||||
include(${CMAKE_SOURCE_DIR}/../../../extern/wcwidth/CMakeLists.txt)
|
||||
suffix_relpaths(INC_NEW "${INC}" "../../../extern/wcwidth/")
|
||||
suffix_relpaths(SRC_NEW "${SRC}" "../../../extern/wcwidth/")
|
||||
include_directories(${INC_NEW})
|
||||
add_library(wcwidth_lib ${SRC_NEW})
|
||||
|
||||
# Unfortunately `blenfont` needs `blenlib`.
|
||||
include_directories(
|
||||
"../../../source/blender/blenlib"
|
||||
)
|
||||
|
||||
# Needed for math_matrix_c.cc to avoid eigen_capi.h dependency.
|
||||
add_definitions(-DMATH_STANDALONE)
|
||||
|
||||
add_library(bli_lib
|
||||
"../../../source/blender/blenlib/intern/fileops.c"
|
||||
"../../../source/blender/blenlib/intern/gsqueue.c"
|
||||
"../../../source/blender/blenlib/intern/rct.c"
|
||||
"../../../source/blender/blenlib/intern/string.c"
|
||||
"../../../source/blender/blenlib/intern/string_utf8.c"
|
||||
"../../../source/blender/blenlib/intern/listbase.cc"
|
||||
"../../../source/blender/blenlib/intern/math_color.cc"
|
||||
"../../../source/blender/blenlib/intern/math_geom.c"
|
||||
"../../../source/blender/blenlib/intern/math_matrix_c.cc"
|
||||
"../../../source/blender/blenlib/intern/math_rotation.c"
|
||||
"../../../source/blender/blenlib/intern/math_vector.c"
|
||||
"../../../source/blender/blenlib/intern/storage.c"
|
||||
"../../../source/blender/blenlib/intern/task.c"
|
||||
"../../../source/blender/blenlib/intern/threads.c"
|
||||
"../../../source/blender/blenlib/intern/time.c"
|
||||
"../../../source/blender/blenlib/intern/path_utils.cc"
|
||||
"../../../source/blender/blenlib/intern/BLI_dynstr.c"
|
||||
"../../../source/blender/blenlib/intern/BLI_ghash.c"
|
||||
"../../../source/blender/blenlib/intern/BLI_ghash_utils.cc"
|
||||
"../../../source/blender/blenlib/intern/BLI_linklist.c"
|
||||
"../../../source/blender/blenlib/intern/BLI_memarena.c"
|
||||
"../../../source/blender/blenlib/intern/BLI_mempool.c"
|
||||
"../../../source/blender/blenlib/intern/hash_mm2a.cc"
|
||||
"../../../source/blender/blenlib/intern/string_utils.c"
|
||||
"../../../source/blender/blenlib/intern/system.c"
|
||||
)
|
||||
|
||||
set(PLATFORM_CGLAGS)
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
|
||||
find_package(Freetype REQUIRED)
|
||||
|
||||
find_package(ZLIB REQUIRED)
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR}/../)
|
||||
include_directories(${OPENGL_INCLUDE_DIR})
|
||||
include_directories(${FREETYPE_INCLUDE_DIRS})
|
||||
include_directories(${CMAKE_SOURCE_DIR}/../../../source/blender/blenfont)
|
||||
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
set(PLATFORM_CFLAGS "-funsigned-char")
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
find_package(X11 REQUIRED)
|
||||
|
||||
set(PLATFORM_LINKLIBS
|
||||
${X11_X11_LIB}
|
||||
${X11_Xinput_LIB}
|
||||
-lpthread
|
||||
)
|
||||
endif()
|
||||
|
||||
string(APPEND CMAKE_C_FLAGS " ${PLATFORM_CFLAGS}")
|
||||
string(APPEND CMAKE_CXX_FLAGS " ${PLATFORM_CFLAGS}")
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Executables
|
||||
|
||||
# Gears (C)
|
||||
add_executable(gears_c
|
||||
${CMAKE_SOURCE_DIR}/gears/GHOST_C-Test.c
|
||||
)
|
||||
|
||||
target_link_libraries(gears_c
|
||||
ghost_lib
|
||||
string_lib
|
||||
${OPENGL_gl_LIBRARY}
|
||||
${CMAKE_DL_LIBS}
|
||||
${PLATFORM_LINKLIBS}
|
||||
)
|
||||
|
||||
|
||||
# Gears (C++)
|
||||
add_executable(gears_cpp
|
||||
${CMAKE_SOURCE_DIR}/gears/GHOST_Test.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(gears_cpp
|
||||
ghost_lib
|
||||
string_lib
|
||||
${OPENGL_gl_LIBRARY}
|
||||
${CMAKE_DL_LIBS}
|
||||
${PLATFORM_LINKLIBS}
|
||||
)
|
||||
|
||||
|
||||
# MultiTest (C)
|
||||
add_executable(multitest_c
|
||||
${CMAKE_SOURCE_DIR}/multitest/Basic.c
|
||||
${CMAKE_SOURCE_DIR}/multitest/EventToBuf.c
|
||||
${CMAKE_SOURCE_DIR}/multitest/MultiTest.c
|
||||
${CMAKE_SOURCE_DIR}/multitest/ScrollBar.c
|
||||
${CMAKE_SOURCE_DIR}/multitest/Util.c
|
||||
${CMAKE_SOURCE_DIR}/multitest/WindowData.c
|
||||
${CMAKE_SOURCE_DIR}/multitest/stubs.c
|
||||
)
|
||||
|
||||
|
||||
target_link_libraries(multitest_c
|
||||
blenfont_lib
|
||||
bli_lib
|
||||
gpu_lib
|
||||
# imbuf_lib
|
||||
ghost_lib
|
||||
bli_lib # again...
|
||||
string_lib
|
||||
numaapi_lib
|
||||
guardedalloc_lib
|
||||
wcwidth_lib
|
||||
${OPENGL_gl_LIBRARY}
|
||||
${FREETYPE_LIBRARIES} ${BROTLI_LIBRARIES}
|
||||
${ZLIB_LIBRARIES}
|
||||
${CMAKE_DL_LIBS}
|
||||
${PLATFORM_LINKLIBS}
|
||||
)
|
||||
|
|
@ -1,475 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/**
|
||||
* Copyright (C) 2001 NaN Technologies B.V.
|
||||
*
|
||||
* Simple test file for the GHOST library.
|
||||
* The OpenGL gear code is taken from the Qt sample code which,
|
||||
* in turn, is probably taken from somewhere as well.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define FALSE 0
|
||||
|
||||
#include "GHOST_C-api.h"
|
||||
|
||||
#if defined(WIN32) || defined(__APPLE__)
|
||||
# ifdef WIN32
|
||||
# include <GL/gl.h>
|
||||
# include <windows.h>
|
||||
# else /* WIN32 */
|
||||
/* __APPLE__ is defined */
|
||||
# include <AGL/gl.h>
|
||||
# endif /* WIN32 */
|
||||
#else /* defined(WIN32) || defined(__APPLE__) */
|
||||
# include <GL/gl.h>
|
||||
#endif /* defined(WIN32) || defined(__APPLE__) */
|
||||
|
||||
static void gearsTimerProc(GHOST_TimerTaskHandle task, uint64_t time);
|
||||
bool processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr user_data);
|
||||
|
||||
static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
|
||||
static GLfloat fAngle = 0.0;
|
||||
static int sExitRequested = 0;
|
||||
static GHOST_SystemHandle shSystem = NULL;
|
||||
static GHOST_WindowHandle sMainWindow = NULL;
|
||||
static GHOST_WindowHandle sSecondaryWindow = NULL;
|
||||
static GHOST_TStandardCursor sCursor = GHOST_kStandardCursorFirstCursor;
|
||||
static GHOST_TimerTaskHandle sTestTimer;
|
||||
static GHOST_TimerTaskHandle sGearsTimer;
|
||||
|
||||
static void testTimerProc(GHOST_TimerTaskHandle task, uint64_t time)
|
||||
{
|
||||
printf("timer1, time=%d\n", (int)time);
|
||||
}
|
||||
|
||||
static void gearGL(
|
||||
GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GLint teeth, GLfloat tooth_depth)
|
||||
{
|
||||
GLint i;
|
||||
GLfloat r0, r1, r2;
|
||||
GLfloat angle, da;
|
||||
GLfloat u, v, len;
|
||||
const double pi = 3.14159264;
|
||||
|
||||
r0 = inner_radius;
|
||||
r1 = (float)(outer_radius - tooth_depth / 2.0);
|
||||
r2 = (float)(outer_radius + tooth_depth / 2.0);
|
||||
|
||||
da = (float)(2.0 * pi / teeth / 4.0);
|
||||
|
||||
glShadeModel(GL_FLAT);
|
||||
glNormal3f(0.0, 0.0, 1.0);
|
||||
|
||||
/* draw front face */
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (i = 0; i <= teeth; i++) {
|
||||
angle = (float)(i * 2.0 * pi / teeth);
|
||||
glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(width * 0.5));
|
||||
glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(width * 0.5));
|
||||
glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(width * 0.5));
|
||||
glVertex3f((float)(r1 * cos(angle + 3 * da)),
|
||||
(float)(r1 * sin(angle + 3 * da)),
|
||||
(float)(width * 0.5));
|
||||
}
|
||||
glEnd();
|
||||
|
||||
/* draw front sides of teeth */
|
||||
glBegin(GL_QUADS);
|
||||
da = (float)(2.0 * pi / teeth / 4.0);
|
||||
for (i = 0; i < teeth; i++) {
|
||||
angle = (float)(i * 2.0 * pi / teeth);
|
||||
glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(width * 0.5));
|
||||
glVertex3f((float)(r2 * cos(angle + da)), (float)(r2 * sin(angle + da)), (float)(width * 0.5));
|
||||
glVertex3f((float)(r2 * cos(angle + 2 * da)),
|
||||
(float)(r2 * sin(angle + 2 * da)),
|
||||
(float)(width * 0.5));
|
||||
glVertex3f((float)(r1 * cos(angle + 3 * da)),
|
||||
(float)(r1 * sin(angle + 3 * da)),
|
||||
(float)(width * 0.5));
|
||||
}
|
||||
glEnd();
|
||||
|
||||
glNormal3f(0.0, 0.0, -1.0);
|
||||
|
||||
/* draw back face */
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (i = 0; i <= teeth; i++) {
|
||||
angle = (float)(i * 2.0 * pi / teeth);
|
||||
glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(-width * 0.5));
|
||||
glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(-width * 0.5));
|
||||
glVertex3f((float)(r1 * cos(angle + 3 * da)),
|
||||
(float)(r1 * sin(angle + 3 * da)),
|
||||
(float)(-width * 0.5));
|
||||
glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(-width * 0.5));
|
||||
}
|
||||
glEnd();
|
||||
|
||||
/* draw back sides of teeth */
|
||||
glBegin(GL_QUADS);
|
||||
da = (float)(2.0 * pi / teeth / 4.0);
|
||||
for (i = 0; i < teeth; i++) {
|
||||
angle = (float)(i * 2.0 * pi / teeth);
|
||||
glVertex3f((float)(r1 * cos(angle + 3 * da)),
|
||||
(float)(r1 * sin(angle + 3 * da)),
|
||||
(float)(-width * 0.5));
|
||||
glVertex3f((float)(r2 * cos(angle + 2 * da)),
|
||||
(float)(r2 * sin(angle + 2 * da)),
|
||||
(float)(-width * 0.5));
|
||||
glVertex3f(
|
||||
(float)(r2 * cos(angle + da)), (float)(r2 * sin(angle + da)), (float)(-width * 0.5));
|
||||
glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(-width * 0.5));
|
||||
}
|
||||
glEnd();
|
||||
|
||||
/* draw outward faces of teeth */
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (i = 0; i < teeth; i++) {
|
||||
angle = (float)(i * 2.0 * pi / teeth);
|
||||
glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(width * 0.5));
|
||||
glVertex3f((float)(r1 * cos(angle)), (float)(r1 * sin(angle)), (float)(-width * 0.5));
|
||||
u = (float)(r2 * cos(angle + da) - r1 * cos(angle));
|
||||
v = (float)(r2 * sin(angle + da) - r1 * sin(angle));
|
||||
len = (float)(sqrt(u * u + v * v));
|
||||
u /= len;
|
||||
v /= len;
|
||||
glNormal3f(v, -u, 0.0);
|
||||
glVertex3f((float)(r2 * cos(angle + da)), (float)(r2 * sin(angle + da)), (float)(width * 0.5));
|
||||
glVertex3f(
|
||||
(float)(r2 * cos(angle + da)), (float)(r2 * sin(angle + da)), (float)(-width * 0.5));
|
||||
glNormal3f((float)(cos(angle)), (float)(sin(angle)), 0.0);
|
||||
glVertex3f((float)(r2 * cos(angle + 2 * da)),
|
||||
(float)(r2 * sin(angle + 2 * da)),
|
||||
(float)(width * 0.5));
|
||||
glVertex3f((float)(r2 * cos(angle + 2 * da)),
|
||||
(float)(r2 * sin(angle + 2 * da)),
|
||||
(float)(-width * 0.5));
|
||||
u = (float)(r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da));
|
||||
v = (float)(r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da));
|
||||
glNormal3f(v, -u, 0.0);
|
||||
glVertex3f((float)(r1 * cos(angle + 3 * da)),
|
||||
(float)(r1 * sin(angle + 3 * da)),
|
||||
(float)(width * 0.5));
|
||||
glVertex3f((float)(r1 * cos(angle + 3 * da)),
|
||||
(float)(r1 * sin(angle + 3 * da)),
|
||||
(float)(-width * 0.5));
|
||||
glNormal3f((float)(cos(angle)), (float)(sin(angle)), 0.0);
|
||||
}
|
||||
glVertex3f((float)(r1 * cos(0.0)), (float)(r1 * sin(0.0)), (float)(width * 0.5));
|
||||
glVertex3f((float)(r1 * cos(0.0)), (float)(r1 * sin(0.0)), (float)(-width * 0.5));
|
||||
glEnd();
|
||||
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
/* draw inside radius cylinder */
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (i = 0; i <= teeth; i++) {
|
||||
angle = (float)(i * 2.0 * pi / teeth);
|
||||
glNormal3f((float)(-cos(angle)), (float)(-sin(angle)), 0.0);
|
||||
glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(-width * 0.5));
|
||||
glVertex3f((float)(r0 * cos(angle)), (float)(r0 * sin(angle)), (float)(width * 0.5));
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
static void drawGearGL(int id)
|
||||
{
|
||||
static GLfloat pos[4] = {5.0f, 5.0f, 10.0f, 1.0f};
|
||||
static GLfloat ared[4] = {0.8f, 0.1f, 0.0f, 1.0f};
|
||||
static GLfloat agreen[4] = {0.0f, 0.8f, 0.2f, 1.0f};
|
||||
static GLfloat ablue[4] = {0.2f, 0.2f, 1.0f, 1.0f};
|
||||
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, pos);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_LIGHT0);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
switch (id) {
|
||||
case 1:
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ared);
|
||||
gearGL(1.0f, 4.0f, 1.0f, 20, 0.7f);
|
||||
break;
|
||||
case 2:
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, agreen);
|
||||
gearGL(0.5f, 2.0f, 2.0f, 10, 0.7f);
|
||||
break;
|
||||
case 3:
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ablue);
|
||||
gearGL(1.3f, 2.0f, 0.5f, 10, 0.7f);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
glEnable(GL_NORMALIZE);
|
||||
}
|
||||
|
||||
static void drawGL(void)
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
glRotatef(view_rotx, 1.0, 0.0, 0.0);
|
||||
glRotatef(view_roty, 0.0, 1.0, 0.0);
|
||||
glRotatef(view_rotz, 0.0, 0.0, 1.0);
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(-3.0, -2.0, 0.0);
|
||||
glRotatef(fAngle, 0.0, 0.0, 1.0);
|
||||
drawGearGL(1);
|
||||
glPopMatrix();
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(3.1f, -2.0f, 0.0f);
|
||||
glRotatef((float)(-2.0 * fAngle - 9.0), 0.0, 0.0, 1.0);
|
||||
drawGearGL(2);
|
||||
glPopMatrix();
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(-3.1f, 2.2f, -1.8f);
|
||||
glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
|
||||
glRotatef((float)(2.0 * fAngle - 2.0), 0.0, 0.0, 1.0);
|
||||
drawGearGL(3);
|
||||
glPopMatrix();
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
static void setViewPortGL(GHOST_WindowHandle hWindow)
|
||||
{
|
||||
GHOST_RectangleHandle hRect = NULL;
|
||||
GLfloat w, h;
|
||||
|
||||
GHOST_ActivateWindowDrawingContext(hWindow);
|
||||
hRect = GHOST_GetClientBounds(hWindow);
|
||||
|
||||
w = (float)GHOST_GetWidthRectangle(hRect) / (float)GHOST_GetHeightRectangle(hRect);
|
||||
h = 1.0;
|
||||
|
||||
glViewport(0, 0, GHOST_GetWidthRectangle(hRect), GHOST_GetHeightRectangle(hRect));
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glFrustum(-w, w, -h, h, 5.0, 60.0);
|
||||
// glOrtho(0, bnds.getWidth(), 0, bnds.getHeight(), -10, 10);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glTranslatef(0.0, 0.0, -40.0);
|
||||
|
||||
glClearColor(.2f, 0.0f, 0.0f, 0.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
GHOST_DisposeRectangle(hRect);
|
||||
}
|
||||
|
||||
bool processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr user_data)
|
||||
{
|
||||
bool handled = true;
|
||||
int cursor;
|
||||
int visibility;
|
||||
GHOST_TEventKeyData *keyData = NULL;
|
||||
GHOST_TEventWheelData *wheelData = NULL;
|
||||
GHOST_WindowHandle window = GHOST_GetEventWindow(hEvent);
|
||||
|
||||
switch (GHOST_GetEventType(hEvent)) {
|
||||
#if 0
|
||||
case GHOST_kEventUnknown:
|
||||
break;
|
||||
case GHOST_kEventCursorButton:
|
||||
break;
|
||||
case GHOST_kEventCursorMove:
|
||||
break;
|
||||
#endif
|
||||
case GHOST_kEventWheel: {
|
||||
wheelData = (GHOST_TEventWheelData *)GHOST_GetEventData(hEvent);
|
||||
if (wheelData->value > 0) {
|
||||
view_rotz += 5.f;
|
||||
}
|
||||
else {
|
||||
view_rotz -= 5.f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GHOST_kEventKeyUp:
|
||||
break;
|
||||
|
||||
case GHOST_kEventKeyDown: {
|
||||
keyData = (GHOST_TEventKeyData *)GHOST_GetEventData(hEvent);
|
||||
switch (keyData->key) {
|
||||
case GHOST_kKeyC: {
|
||||
cursor = sCursor;
|
||||
cursor++;
|
||||
if (cursor >= GHOST_kStandardCursorNumCursors) {
|
||||
cursor = GHOST_kStandardCursorFirstCursor;
|
||||
}
|
||||
sCursor = (GHOST_TStandardCursor)cursor;
|
||||
GHOST_SetCursorShape(window, sCursor);
|
||||
break;
|
||||
}
|
||||
case GHOST_kKeyH: {
|
||||
visibility = GHOST_GetCursorVisibility(window);
|
||||
GHOST_SetCursorVisibility(window, !visibility);
|
||||
break;
|
||||
}
|
||||
case GHOST_kKeyQ:
|
||||
sExitRequested = 1;
|
||||
case GHOST_kKeyT:
|
||||
if (!sTestTimer) {
|
||||
sTestTimer = GHOST_InstallTimer(shSystem, 0, 1000, testTimerProc, NULL);
|
||||
}
|
||||
else {
|
||||
GHOST_RemoveTimer(shSystem, sTestTimer);
|
||||
sTestTimer = 0;
|
||||
}
|
||||
break;
|
||||
case GHOST_kKeyW: {
|
||||
if (sMainWindow) {
|
||||
char *title = GHOST_GetTitle(sMainWindow);
|
||||
char *ntitle = malloc(strlen(title) + 2);
|
||||
|
||||
sprintf(ntitle, "%s-", title);
|
||||
GHOST_SetTitle(sMainWindow, ntitle);
|
||||
|
||||
free(ntitle);
|
||||
free(title);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GHOST_kEventWindowClose: {
|
||||
GHOST_WindowHandle window2 = GHOST_GetEventWindow(hEvent);
|
||||
if (window2 == sMainWindow) {
|
||||
sExitRequested = 1;
|
||||
}
|
||||
else {
|
||||
if (sGearsTimer) {
|
||||
GHOST_RemoveTimer(shSystem, sGearsTimer);
|
||||
sGearsTimer = 0;
|
||||
}
|
||||
GHOST_DisposeWindow(shSystem, window2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GHOST_kEventWindowActivate:
|
||||
handled = false;
|
||||
break;
|
||||
case GHOST_kEventWindowDeactivate:
|
||||
handled = false;
|
||||
break;
|
||||
case GHOST_kEventWindowUpdate: {
|
||||
GHOST_WindowHandle window2 = GHOST_GetEventWindow(hEvent);
|
||||
if (!GHOST_ValidWindow(shSystem, window2)) {
|
||||
break;
|
||||
}
|
||||
setViewPortGL(window2);
|
||||
GHOST_SwapWindowBufferAcquire(window2);
|
||||
drawGL();
|
||||
GHOST_SwapWindowBufferRelease(window2);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
handled = false;
|
||||
break;
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
GHOST_GPUSettings gpu_settings = {0};
|
||||
char *title1 = "gears - main window";
|
||||
char *title2 = "gears - secondary window";
|
||||
GHOST_EventConsumerHandle consumer = GHOST_CreateEventConsumer(processEvent, NULL);
|
||||
|
||||
/* Create the system */
|
||||
shSystem = GHOST_CreateSystem();
|
||||
GHOST_AddEventConsumer(shSystem, consumer);
|
||||
|
||||
if (shSystem) {
|
||||
/* Create the main window */
|
||||
sMainWindow = GHOST_CreateWindow(shSystem,
|
||||
NULL,
|
||||
title1,
|
||||
10,
|
||||
64,
|
||||
320,
|
||||
200,
|
||||
GHOST_kWindowStateNormal,
|
||||
false,
|
||||
GHOST_kDrawingContextTypeOpenGL,
|
||||
gpu_settings);
|
||||
if (!sMainWindow) {
|
||||
printf("could not create main window\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* Create a secondary window */
|
||||
sSecondaryWindow = GHOST_CreateWindow(shSystem,
|
||||
NULL,
|
||||
title2,
|
||||
340,
|
||||
64,
|
||||
320,
|
||||
200,
|
||||
GHOST_kWindowStateNormal,
|
||||
false,
|
||||
GHOST_kDrawingContextTypeOpenGL,
|
||||
gpu_settings);
|
||||
if (!sSecondaryWindow) {
|
||||
printf("could not create secondary window\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* Install a timer to have the gears running */
|
||||
sGearsTimer = GHOST_InstallTimer(shSystem, 0, 10, gearsTimerProc, sMainWindow);
|
||||
|
||||
/* Enter main loop */
|
||||
while (!sExitRequested) {
|
||||
if (!GHOST_ProcessEvents(shSystem, false)) {
|
||||
#ifdef WIN32
|
||||
/* If there were no events, be nice to other applications */
|
||||
Sleep(10);
|
||||
#endif
|
||||
}
|
||||
GHOST_DispatchEvents(shSystem);
|
||||
}
|
||||
}
|
||||
|
||||
/* Dispose windows */
|
||||
if (GHOST_ValidWindow(shSystem, sMainWindow)) {
|
||||
GHOST_DisposeWindow(shSystem, sMainWindow);
|
||||
}
|
||||
if (GHOST_ValidWindow(shSystem, sSecondaryWindow)) {
|
||||
GHOST_DisposeWindow(shSystem, sSecondaryWindow);
|
||||
}
|
||||
|
||||
/* Dispose the system */
|
||||
GHOST_DisposeSystem(shSystem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gearsTimerProc(GHOST_TimerTaskHandle hTask, uint64_t time)
|
||||
{
|
||||
GHOST_WindowHandle hWindow = NULL;
|
||||
fAngle += 2.0;
|
||||
view_roty += 1.0;
|
||||
hWindow = (GHOST_WindowHandle)GHOST_GetTimerTaskUserData(hTask);
|
||||
if (GHOST_ValidWindow(shSystem, hWindow)) {
|
||||
GHOST_InvalidateWindow(hWindow);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,704 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/**
|
||||
* Copyright (C) 2001 NaN Technologies B.V.
|
||||
* Simple test file for the GHOST library.
|
||||
* The OpenGL gear code is taken from the Qt sample code which,
|
||||
* in turn, is probably taken from somewhere as well.
|
||||
* Stereo code by Raymond de Vries, januari 2002
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <math.h>
|
||||
#include <string>
|
||||
|
||||
#if defined(WIN32) || defined(__APPLE__)
|
||||
# ifdef WIN32
|
||||
# include <atlbase.h>
|
||||
# include <windows.h>
|
||||
|
||||
# include <GL/gl.h>
|
||||
# else // WIN32 \
|
||||
// __APPLE__ is defined
|
||||
# include <AGL/gl.h>
|
||||
# endif // WIN32
|
||||
#else // defined(WIN32) || defined(__APPLE__)
|
||||
# include <GL/gl.h>
|
||||
#endif // defined(WIN32) || defined(__APPLE__)
|
||||
|
||||
#include "GHOST_Rect.hh"
|
||||
|
||||
#include "GHOST_IEvent.hh"
|
||||
#include "GHOST_IEventConsumer.hh"
|
||||
#include "GHOST_ISystem.hh"
|
||||
|
||||
#define LEFT_EYE 0
|
||||
#define RIGHT_EYE 1
|
||||
|
||||
static bool nVidiaWindows; // very dirty but hey, it's for testing only
|
||||
|
||||
static void gearsTimerProc(GHOST_ITimerTask *task, uint64_t time);
|
||||
|
||||
static class Application *fApp;
|
||||
static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
|
||||
static GLfloat fAngle = 0.0;
|
||||
static GHOST_ISystem *fSystem = 0;
|
||||
|
||||
void StereoProjection(float left,
|
||||
float right,
|
||||
float bottom,
|
||||
float top,
|
||||
float nearplane,
|
||||
float farplane,
|
||||
float zero_plane,
|
||||
float dist,
|
||||
float eye);
|
||||
|
||||
static void testTimerProc(GHOST_ITimerTask * /*task*/, uint64_t time)
|
||||
{
|
||||
std::cout << "timer1, time=" << int(time) << "\n";
|
||||
}
|
||||
|
||||
static void gearGL(
|
||||
GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GLint teeth, GLfloat tooth_depth)
|
||||
{
|
||||
GLint i;
|
||||
GLfloat r0, r1, r2;
|
||||
GLfloat angle, da;
|
||||
GLfloat u, v, len;
|
||||
|
||||
r0 = inner_radius;
|
||||
r1 = outer_radius - tooth_depth / 2.0;
|
||||
r2 = outer_radius + tooth_depth / 2.0;
|
||||
|
||||
const double pi = 3.14159264;
|
||||
da = 2.0 * pi / teeth / 4.0;
|
||||
|
||||
glShadeModel(GL_FLAT);
|
||||
glNormal3f(0.0, 0.0, 1.0);
|
||||
|
||||
/* draw front face */
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (i = 0; i <= teeth; i++) {
|
||||
angle = i * 2.0 * pi / teeth;
|
||||
glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
|
||||
glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
|
||||
glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
|
||||
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
/* draw front sides of teeth */
|
||||
glBegin(GL_QUADS);
|
||||
da = 2.0 * pi / teeth / 4.0;
|
||||
for (i = 0; i < teeth; i++) {
|
||||
angle = i * 2.0 * pi / teeth;
|
||||
glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
|
||||
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
|
||||
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
|
||||
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
glNormal3f(0.0, 0.0, -1.0);
|
||||
|
||||
/* draw back face */
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (i = 0; i <= teeth; i++) {
|
||||
angle = i * 2.0 * pi / teeth;
|
||||
glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
|
||||
glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
|
||||
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
|
||||
glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
/* draw back sides of teeth */
|
||||
glBegin(GL_QUADS);
|
||||
da = 2.0 * pi / teeth / 4.0;
|
||||
for (i = 0; i < teeth; i++) {
|
||||
angle = i * 2.0 * pi / teeth;
|
||||
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
|
||||
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
|
||||
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
|
||||
glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
/* draw outward faces of teeth */
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (i = 0; i < teeth; i++) {
|
||||
angle = i * 2.0 * pi / teeth;
|
||||
glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
|
||||
glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
|
||||
u = r2 * cos(angle + da) - r1 * cos(angle);
|
||||
v = r2 * sin(angle + da) - r1 * sin(angle);
|
||||
len = sqrt(u * u + v * v);
|
||||
u /= len;
|
||||
v /= len;
|
||||
glNormal3f(v, -u, 0.0);
|
||||
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
|
||||
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
|
||||
glNormal3f(cos(angle), sin(angle), 0.0);
|
||||
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
|
||||
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
|
||||
u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
|
||||
v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
|
||||
glNormal3f(v, -u, 0.0);
|
||||
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
|
||||
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
|
||||
glNormal3f(cos(angle), sin(angle), 0.0);
|
||||
}
|
||||
glVertex3f(r1 * cos(0.0), r1 * sin(0.0), width * 0.5);
|
||||
glVertex3f(r1 * cos(0.0), r1 * sin(0.0), -width * 0.5);
|
||||
glEnd();
|
||||
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
/* draw inside radius cylinder */
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (i = 0; i <= teeth; i++) {
|
||||
angle = i * 2.0 * pi / teeth;
|
||||
glNormal3f(-cos(angle), -sin(angle), 0.0);
|
||||
glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
|
||||
glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
static void drawGearGL(int id)
|
||||
{
|
||||
static GLfloat pos[4] = {5.0f, 5.0f, 10.0f, 1.0f};
|
||||
static GLfloat ared[4] = {0.8f, 0.1f, 0.0f, 1.0f};
|
||||
static GLfloat agreen[4] = {0.0f, 0.8f, 0.2f, 1.0f};
|
||||
static GLfloat ablue[4] = {0.2f, 0.2f, 1.0f, 1.0f};
|
||||
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, pos);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_LIGHT0);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
switch (id) {
|
||||
case 1:
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ared);
|
||||
gearGL(1.0f, 4.0f, 1.0f, 20, 0.7f);
|
||||
break;
|
||||
case 2:
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, agreen);
|
||||
gearGL(0.5f, 2.0f, 2.0f, 10, 0.7f);
|
||||
break;
|
||||
case 3:
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ablue);
|
||||
gearGL(1.3f, 2.0f, 0.5f, 10, 0.7f);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
glEnable(GL_NORMALIZE);
|
||||
}
|
||||
|
||||
void RenderCamera()
|
||||
{
|
||||
glRotatef(view_rotx, 1.0, 0.0, 0.0);
|
||||
glRotatef(view_roty, 0.0, 1.0, 0.0);
|
||||
glRotatef(view_rotz, 0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
void RenderScene()
|
||||
{
|
||||
glPushMatrix();
|
||||
glTranslatef(-3.0, -2.0, 0.0);
|
||||
glRotatef(fAngle, 0.0, 0.0, 1.0);
|
||||
drawGearGL(1);
|
||||
glPopMatrix();
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(3.1f, -2.0f, 0.0f);
|
||||
glRotatef(-2.0 * fAngle - 9.0, 0.0, 0.0, 1.0);
|
||||
drawGearGL(2);
|
||||
glPopMatrix();
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(-3.1f, 2.2f, -1.8f);
|
||||
glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
|
||||
glRotatef(2.0 * fAngle - 2.0, 0.0, 0.0, 1.0);
|
||||
drawGearGL(3);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
static void View(GHOST_IWindow *window, bool stereo, int eye = 0)
|
||||
{
|
||||
window->activateDrawingContext();
|
||||
GHOST_Rect bnds;
|
||||
int noOfScanlines = 0, lowerScanline = 0;
|
||||
/* hard coded for testing purposes, display device dependent */
|
||||
int verticalBlankingInterval = 32;
|
||||
float left, right, bottom, top;
|
||||
float nearplane, farplane, zeroPlane, distance;
|
||||
float eyeSeparation = 0.62f;
|
||||
window->getClientBounds(bnds);
|
||||
|
||||
// viewport
|
||||
if (stereo) {
|
||||
if (nVidiaWindows) {
|
||||
// handled by nVidia driver so act as normal (explicitly put here since
|
||||
// it -is- stereo)
|
||||
glViewport(0, 0, bnds.getWidth(), bnds.getHeight());
|
||||
}
|
||||
else { // generic cross platform above-below stereo
|
||||
noOfScanlines = (bnds.getHeight() - verticalBlankingInterval) / 2;
|
||||
switch (eye) {
|
||||
case LEFT_EYE:
|
||||
// upper half of window
|
||||
lowerScanline = bnds.getHeight() - noOfScanlines;
|
||||
break;
|
||||
case RIGHT_EYE:
|
||||
// lower half of window
|
||||
lowerScanline = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
noOfScanlines = bnds.getHeight();
|
||||
lowerScanline = 0;
|
||||
}
|
||||
|
||||
glViewport(0, lowerScanline, bnds.getWidth(), noOfScanlines);
|
||||
|
||||
// projection
|
||||
left = -6.0;
|
||||
right = 6.0;
|
||||
bottom = -4.8f;
|
||||
top = 4.8f;
|
||||
nearplane = 5.0;
|
||||
farplane = 60.0;
|
||||
|
||||
if (stereo) {
|
||||
zeroPlane = 0.0;
|
||||
distance = 14.5;
|
||||
switch (eye) {
|
||||
case LEFT_EYE:
|
||||
StereoProjection(left,
|
||||
right,
|
||||
bottom,
|
||||
top,
|
||||
nearplane,
|
||||
farplane,
|
||||
zeroPlane,
|
||||
distance,
|
||||
-eyeSeparation / 2.0);
|
||||
break;
|
||||
case RIGHT_EYE:
|
||||
StereoProjection(left,
|
||||
right,
|
||||
bottom,
|
||||
top,
|
||||
nearplane,
|
||||
farplane,
|
||||
zeroPlane,
|
||||
distance,
|
||||
eyeSeparation / 2.0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// left = -w;
|
||||
// right = w;
|
||||
// bottom = -h;
|
||||
// top = h;
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glFrustum(left, right, bottom, top, 5.0, 60.0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glTranslatef(0.0, 0.0, -40.0);
|
||||
}
|
||||
|
||||
glClearColor(.2f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
void StereoProjection(float left,
|
||||
float right,
|
||||
float bottom,
|
||||
float top,
|
||||
float nearplane,
|
||||
float farplane,
|
||||
float zero_plane,
|
||||
float dist,
|
||||
float eye)
|
||||
/* Perform the perspective projection for one eye's sub-field.
|
||||
* The projection is in the direction of the negative z axis.
|
||||
*
|
||||
* -6.0, 6.0, -4.8, 4.8,
|
||||
* left, right, bottom, top = the coordinate range, in the plane of zero
|
||||
* parallax setting, which will be displayed on the screen. The
|
||||
* ratio between (right-left) and (top-bottom) should equal the aspect
|
||||
* ratio of the display.
|
||||
*
|
||||
* 6.0, -6.0,
|
||||
* near, far = the z-coordinate values of the clipping planes.
|
||||
*
|
||||
* 0.0,
|
||||
* zero_plane = the z-coordinate of the plane of zero parallax setting.
|
||||
*
|
||||
* 14.5,
|
||||
* dist = the distance from the center of projection to the plane
|
||||
* of zero parallax.
|
||||
*
|
||||
* -0.31
|
||||
* eye = half the eye separation; positive for the right eye sub-field,
|
||||
* negative for the left eye sub-field.
|
||||
*/
|
||||
{
|
||||
float xmid, ymid, clip_near, clip_far, topw, bottomw, leftw, rightw, dx, dy, n_over_d;
|
||||
|
||||
dx = right - left;
|
||||
dy = top - bottom;
|
||||
|
||||
xmid = (right + left) / 2.0;
|
||||
ymid = (top + bottom) / 2.0;
|
||||
|
||||
clip_near = dist + zero_plane - nearplane;
|
||||
clip_far = dist + zero_plane - farplane;
|
||||
|
||||
n_over_d = clip_near / dist;
|
||||
|
||||
topw = n_over_d * dy / 2.0;
|
||||
bottomw = -topw;
|
||||
rightw = n_over_d * (dx / 2.0 - eye);
|
||||
leftw = n_over_d * (-dx / 2.0 - eye);
|
||||
|
||||
/* Need to be in projection mode for this. */
|
||||
glLoadIdentity();
|
||||
glFrustum(leftw, rightw, bottomw, topw, clip_near, clip_far);
|
||||
|
||||
glTranslatef(-xmid - eye, -ymid, -zero_plane - dist);
|
||||
}
|
||||
|
||||
class Application : public GHOST_IEventConsumer {
|
||||
public:
|
||||
Application(GHOST_ISystem *system);
|
||||
~Application();
|
||||
virtual bool processEvent(GHOST_IEvent *event);
|
||||
|
||||
GHOST_ISystem *system_;
|
||||
GHOST_IWindow *main_window_;
|
||||
GHOST_IWindow *secondary_window_;
|
||||
GHOST_ITimerTask *gears_timer_, *test_timer_;
|
||||
GHOST_TStandardCursor cursor_;
|
||||
bool exit_requested_;
|
||||
|
||||
bool stereo;
|
||||
};
|
||||
|
||||
Application::Application(GHOST_ISystem *system)
|
||||
: system_(system),
|
||||
main_window_(0),
|
||||
secondary_window_(0),
|
||||
gears_timer_(0),
|
||||
test_timer_(0),
|
||||
cursor_(GHOST_kStandardCursorFirstCursor),
|
||||
exit_requested_(false),
|
||||
stereo(false)
|
||||
{
|
||||
GHOST_GPUSettings gpu_settings = {0};
|
||||
gpu_settings.context_type = GHOST_kDrawingContextTypeOpenGL;
|
||||
fApp = this;
|
||||
|
||||
// Create the main window
|
||||
main_window_ = system->createWindow(
|
||||
"gears - main window", 10, 64, 320, 200, GHOST_kWindowStateNormal, gpu_settings);
|
||||
|
||||
if (!main_window_) {
|
||||
std::cout << "could not create main window\n";
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// Create a secondary window
|
||||
secondary_window_ = system->createWindow(
|
||||
"gears - secondary window", 340, 64, 320, 200, GHOST_kWindowStateNormal, gpu_settings);
|
||||
if (!secondary_window_) {
|
||||
std::cout << "could not create secondary window\n";
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// Install a timer to have the gears running
|
||||
gears_timer_ = system->installTimer(0 /*delay*/, 20 /*interval*/, gearsTimerProc, main_window_);
|
||||
}
|
||||
|
||||
Application::~Application()
|
||||
{
|
||||
// Dispose windows
|
||||
if (system_->validWindow(main_window_)) {
|
||||
system_->disposeWindow(main_window_);
|
||||
}
|
||||
if (system_->validWindow(secondary_window_)) {
|
||||
system_->disposeWindow(secondary_window_);
|
||||
}
|
||||
}
|
||||
|
||||
bool Application::processEvent(const GHOST_IEvent *event)
|
||||
{
|
||||
GHOST_IWindow *window = event->getWindow();
|
||||
bool handled = true;
|
||||
|
||||
switch (event->getType()) {
|
||||
#if 0
|
||||
case GHOST_kEventUnknown:
|
||||
break;
|
||||
case GHOST_kEventCursorButton:
|
||||
std::cout << "GHOST_kEventCursorButton";
|
||||
break;
|
||||
case GHOST_kEventCursorMove:
|
||||
std::cout << "GHOST_kEventCursorMove";
|
||||
break;
|
||||
#endif
|
||||
case GHOST_kEventWheel: {
|
||||
GHOST_TEventWheelData *wheelData = (GHOST_TEventWheelData *)event->getData();
|
||||
if (wheelData->value > 0) {
|
||||
view_rotz += 5.f;
|
||||
}
|
||||
else {
|
||||
view_rotz -= 5.f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GHOST_kEventKeyUp:
|
||||
break;
|
||||
|
||||
case GHOST_kEventKeyDown: {
|
||||
GHOST_TEventKeyData *keyData = (GHOST_TEventKeyData *)event->getData();
|
||||
switch (keyData->key) {
|
||||
case GHOST_kKeyC: {
|
||||
int cursor = cursor_;
|
||||
cursor++;
|
||||
if (cursor >= GHOST_kStandardCursorNumCursors) {
|
||||
cursor = GHOST_kStandardCursorFirstCursor;
|
||||
}
|
||||
cursor_ = (GHOST_TStandardCursor)cursor;
|
||||
window->setCursorShape(cursor_);
|
||||
break;
|
||||
}
|
||||
|
||||
case GHOST_kKeyE: {
|
||||
int x = 200, y = 200;
|
||||
system_->setCursorPosition(x, y);
|
||||
break;
|
||||
}
|
||||
|
||||
case GHOST_kKeyH:
|
||||
window->setCursorVisibility(!window->getCursorVisibility());
|
||||
break;
|
||||
|
||||
case GHOST_kKeyM: {
|
||||
bool down = false;
|
||||
system_->getModifierKeyState(GHOST_kModifierKeyLeftShift, down);
|
||||
if (down) {
|
||||
std::cout << "left shift down\n";
|
||||
}
|
||||
system_->getModifierKeyState(GHOST_kModifierKeyRightShift, down);
|
||||
if (down) {
|
||||
std::cout << "right shift down\n";
|
||||
}
|
||||
system_->getModifierKeyState(GHOST_kModifierKeyLeftAlt, down);
|
||||
if (down) {
|
||||
std::cout << "left Alt down\n";
|
||||
}
|
||||
system_->getModifierKeyState(GHOST_kModifierKeyRightAlt, down);
|
||||
if (down) {
|
||||
std::cout << "right Alt down\n";
|
||||
}
|
||||
system_->getModifierKeyState(GHOST_kModifierKeyLeftControl, down);
|
||||
if (down) {
|
||||
std::cout << "left control down\n";
|
||||
}
|
||||
system_->getModifierKeyState(GHOST_kModifierKeyRightControl, down);
|
||||
if (down) {
|
||||
std::cout << "right control down\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GHOST_kKeyQ:
|
||||
exit_requested_ = true;
|
||||
break;
|
||||
|
||||
case GHOST_kKeyS: // toggle mono and stereo
|
||||
if (stereo) {
|
||||
stereo = false;
|
||||
}
|
||||
else {
|
||||
stereo = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case GHOST_kKeyT:
|
||||
if (!test_timer_) {
|
||||
test_timer_ = system_->installTimer(0, 1000, testTimerProc);
|
||||
}
|
||||
|
||||
else {
|
||||
system_->removeTimer(test_timer_);
|
||||
test_timer_ = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case GHOST_kKeyW:
|
||||
if (main_window_) {
|
||||
std::string title = main_window_->getTitle();
|
||||
title += "-";
|
||||
main_window_->setTitle(title);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GHOST_kEventWindowClose: {
|
||||
GHOST_IWindow *window2 = event->getWindow();
|
||||
if (window2 == main_window_) {
|
||||
exit_requested_ = true;
|
||||
}
|
||||
else {
|
||||
system_->disposeWindow(window2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GHOST_kEventWindowActivate:
|
||||
handled = false;
|
||||
break;
|
||||
|
||||
case GHOST_kEventWindowDeactivate:
|
||||
handled = false;
|
||||
break;
|
||||
|
||||
case GHOST_kEventWindowUpdate: {
|
||||
GHOST_IWindow *window2 = event->getWindow();
|
||||
if (!system_->validWindow(window2)) {
|
||||
break;
|
||||
}
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
if (stereo) {
|
||||
View(window2, stereo, LEFT_EYE);
|
||||
glPushMatrix();
|
||||
RenderCamera();
|
||||
RenderScene();
|
||||
glPopMatrix();
|
||||
|
||||
View(window2, stereo, RIGHT_EYE);
|
||||
glPushMatrix();
|
||||
RenderCamera();
|
||||
RenderScene();
|
||||
glPopMatrix();
|
||||
}
|
||||
else {
|
||||
View(window2, stereo);
|
||||
glPushMatrix();
|
||||
RenderCamera();
|
||||
RenderScene();
|
||||
glPopMatrix();
|
||||
}
|
||||
window2->swapBufferRelease();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
handled = false;
|
||||
break;
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
int main(int /*argc*/, char ** /*argv*/)
|
||||
{
|
||||
nVidiaWindows = false;
|
||||
// nVidiaWindows = true;
|
||||
|
||||
#ifdef WIN32
|
||||
/* Set a couple of settings in the registry for the nVidia detonator driver.
|
||||
* So this is very specific...
|
||||
*/
|
||||
if (nVidiaWindows) {
|
||||
LONG lresult;
|
||||
HKEY hkey = 0;
|
||||
DWORD dwd = 0;
|
||||
// unsigned char buffer[128];
|
||||
|
||||
CRegKey regkey;
|
||||
// DWORD keyValue;
|
||||
// lresult = regkey.Open(
|
||||
// HKEY_LOCAL_MACHINE, "SOFTWARE\\NVIDIA Corporation\\Global\\Stereo3D\\StereoEnable");
|
||||
lresult = regkey.Open(HKEY_LOCAL_MACHINE,
|
||||
"SOFTWARE\\NVIDIA Corporation\\Global\\Stereo3D\\StereoEnable",
|
||||
KEY_ALL_ACCESS);
|
||||
|
||||
if (lresult == ERROR_SUCCESS) {
|
||||
printf("Successfully opened key\n");
|
||||
}
|
||||
# if 0
|
||||
lresult = regkey.QueryValue(&keyValue, "StereoEnable");
|
||||
if (lresult == ERROR_SUCCESS) {
|
||||
printf("Successfully queried key\n");
|
||||
}
|
||||
# endif
|
||||
lresult = regkey.SetValue(
|
||||
HKEY_LOCAL_MACHINE, "SOFTWARE\\NVIDIA Corporation\\Global\\Stereo3D\\StereoEnable", "1");
|
||||
if (lresult == ERROR_SUCCESS) {
|
||||
printf("Successfully set value for key\n");
|
||||
}
|
||||
regkey.Close();
|
||||
if (lresult == ERROR_SUCCESS) {
|
||||
printf("Successfully closed key\n");
|
||||
}
|
||||
// regkey.Write("2");
|
||||
}
|
||||
#endif // WIN32
|
||||
|
||||
// Create the system
|
||||
GHOST_ISystem::createSystem();
|
||||
fSystem = GHOST_ISystem::getSystem();
|
||||
|
||||
if (fSystem) {
|
||||
// Create an application object
|
||||
Application app(fSystem);
|
||||
|
||||
// Add the application as event consumer
|
||||
fSystem->addEventConsumer(&app);
|
||||
|
||||
// Enter main loop
|
||||
while (!app.exit_requested_) {
|
||||
// printf("main: loop\n");
|
||||
fSystem->processEvents(true);
|
||||
fSystem->dispatchEvents();
|
||||
}
|
||||
|
||||
// Remove so ghost doesn't do a double free
|
||||
fSystem->removeEventConsumer(&app);
|
||||
}
|
||||
|
||||
// Dispose the system
|
||||
GHOST_ISystem::disposeSystem();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gearsTimerProc(GHOST_ITimerTask *task, uint64_t /*time*/)
|
||||
{
|
||||
fAngle += 2.0;
|
||||
view_roty += 1.0;
|
||||
GHOST_IWindow *window = (GHOST_IWindow *)task->getUserData();
|
||||
if (fSystem->validWindow(window)) {
|
||||
window->invalidate();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "Basic.h"
|
||||
|
||||
int min_i(int a, int b)
|
||||
{
|
||||
return (a < b) ? a : b;
|
||||
}
|
||||
int max_i(int a, int b)
|
||||
{
|
||||
return (b < a) ? a : b;
|
||||
}
|
||||
int clamp_i(int val, int min, int max)
|
||||
{
|
||||
return min_i(max_i(val, min), max);
|
||||
}
|
||||
|
||||
float min_f(float a, float b)
|
||||
{
|
||||
return (a < b) ? a : b;
|
||||
}
|
||||
float max_f(float a, float b)
|
||||
{
|
||||
return (b < a) ? a : b;
|
||||
}
|
||||
float clamp_f(float val, float min, float max)
|
||||
{
|
||||
return min_f(max_f(val, min), max);
|
||||
}
|
||||
|
||||
void rect_copy(int dst[2][2], int src[2][2])
|
||||
{
|
||||
dst[0][0] = src[0][0], dst[0][1] = src[0][1];
|
||||
dst[1][0] = src[1][0], dst[1][1] = src[1][1];
|
||||
}
|
||||
int rect_contains_pt(int rect[2][2], int pt[2])
|
||||
{
|
||||
return ((rect[0][0] <= pt[0] && pt[0] <= rect[1][0]) &&
|
||||
(rect[0][1] <= pt[1] && pt[1] <= rect[1][1]));
|
||||
}
|
||||
int rect_width(int rect[2][2])
|
||||
{
|
||||
return (rect[1][0] - rect[0][0]);
|
||||
}
|
||||
int rect_height(int rect[2][2])
|
||||
{
|
||||
return (rect[1][1] - rect[0][1]);
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
int min_i(int a, int b);
|
||||
|
||||
int max_i(int a, int b);
|
||||
int clamp_i(int val, int min, int max);
|
||||
|
||||
float min_f(float a, float b);
|
||||
float max_f(float a, float b);
|
||||
float clamp_f(float val, float min, float max);
|
||||
|
||||
void rect_copy(int dst[2][2], int src[2][2]);
|
||||
int rect_contains_pt(int rect[2][2], int pt[2]);
|
||||
int rect_width(int rect[2][2]);
|
||||
int rect_height(int rect[2][2]);
|
||||
|
|
@ -1,229 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "EventToBuf.h"
|
||||
#include "GHOST_C-api.h"
|
||||
|
||||
char *eventtype_to_string(GHOST_TEventType type)
|
||||
{
|
||||
switch (type) {
|
||||
case GHOST_kEventCursorMove:
|
||||
return "CursorMove";
|
||||
case GHOST_kEventButtonDown:
|
||||
return "ButtonDown";
|
||||
case GHOST_kEventButtonUp:
|
||||
return "ButtonUp";
|
||||
|
||||
case GHOST_kEventKeyDown:
|
||||
return "KeyDown";
|
||||
case GHOST_kEventKeyUp:
|
||||
return "KeyUp";
|
||||
|
||||
case GHOST_kEventQuitRequest:
|
||||
return "Quit";
|
||||
|
||||
case GHOST_kEventWindowClose:
|
||||
return "WindowClose";
|
||||
case GHOST_kEventWindowActivate:
|
||||
return "WindowActivate";
|
||||
case GHOST_kEventWindowDeactivate:
|
||||
return "WindowDeactivate";
|
||||
case GHOST_kEventWindowUpdate:
|
||||
return "WindowUpdate";
|
||||
case GHOST_kEventWindowSize:
|
||||
return "WindowSize";
|
||||
default:
|
||||
return "<invalid>";
|
||||
}
|
||||
}
|
||||
|
||||
static char *keytype_to_string(GHOST_TKey key)
|
||||
{
|
||||
#define K(key) \
|
||||
case GHOST_k##key: \
|
||||
return #key;
|
||||
switch (key) {
|
||||
K(KeyBackSpace);
|
||||
K(KeyTab);
|
||||
K(KeyLinefeed);
|
||||
K(KeyClear);
|
||||
K(KeyEnter);
|
||||
|
||||
K(KeyEsc);
|
||||
K(KeySpace);
|
||||
K(KeyQuote);
|
||||
K(KeyComma);
|
||||
K(KeyMinus);
|
||||
K(KeyPeriod);
|
||||
K(KeySlash);
|
||||
|
||||
K(Key0);
|
||||
K(Key1);
|
||||
K(Key2);
|
||||
K(Key3);
|
||||
K(Key4);
|
||||
K(Key5);
|
||||
K(Key6);
|
||||
K(Key7);
|
||||
K(Key8);
|
||||
K(Key9);
|
||||
|
||||
K(KeySemicolon);
|
||||
K(KeyEqual);
|
||||
|
||||
K(KeyA);
|
||||
K(KeyB);
|
||||
K(KeyC);
|
||||
K(KeyD);
|
||||
K(KeyE);
|
||||
K(KeyF);
|
||||
K(KeyG);
|
||||
K(KeyH);
|
||||
K(KeyI);
|
||||
K(KeyJ);
|
||||
K(KeyK);
|
||||
K(KeyL);
|
||||
K(KeyM);
|
||||
K(KeyN);
|
||||
K(KeyO);
|
||||
K(KeyP);
|
||||
K(KeyQ);
|
||||
K(KeyR);
|
||||
K(KeyS);
|
||||
K(KeyT);
|
||||
K(KeyU);
|
||||
K(KeyV);
|
||||
K(KeyW);
|
||||
K(KeyX);
|
||||
K(KeyY);
|
||||
K(KeyZ);
|
||||
|
||||
K(KeyLeftBracket);
|
||||
K(KeyRightBracket);
|
||||
K(KeyBackslash);
|
||||
K(KeyAccentGrave);
|
||||
|
||||
K(KeyLeftShift);
|
||||
K(KeyRightShift);
|
||||
K(KeyLeftControl);
|
||||
K(KeyRightControl);
|
||||
K(KeyLeftAlt);
|
||||
K(KeyRightAlt);
|
||||
K(KeyOS);
|
||||
|
||||
K(KeyCapsLock);
|
||||
K(KeyNumLock);
|
||||
K(KeyScrollLock);
|
||||
|
||||
K(KeyLeftArrow);
|
||||
K(KeyRightArrow);
|
||||
K(KeyUpArrow);
|
||||
K(KeyDownArrow);
|
||||
|
||||
K(KeyPrintScreen);
|
||||
K(KeyPause);
|
||||
|
||||
K(KeyInsert);
|
||||
K(KeyDelete);
|
||||
K(KeyHome);
|
||||
K(KeyEnd);
|
||||
K(KeyUpPage);
|
||||
K(KeyDownPage);
|
||||
|
||||
K(KeyNumpad0);
|
||||
K(KeyNumpad1);
|
||||
K(KeyNumpad2);
|
||||
K(KeyNumpad3);
|
||||
K(KeyNumpad4);
|
||||
K(KeyNumpad5);
|
||||
K(KeyNumpad6);
|
||||
K(KeyNumpad7);
|
||||
K(KeyNumpad8);
|
||||
K(KeyNumpad9);
|
||||
K(KeyNumpadPeriod);
|
||||
K(KeyNumpadEnter);
|
||||
K(KeyNumpadPlus);
|
||||
K(KeyNumpadMinus);
|
||||
K(KeyNumpadAsterisk);
|
||||
K(KeyNumpadSlash);
|
||||
|
||||
K(KeyF1);
|
||||
K(KeyF2);
|
||||
K(KeyF3);
|
||||
K(KeyF4);
|
||||
K(KeyF5);
|
||||
K(KeyF6);
|
||||
K(KeyF7);
|
||||
K(KeyF8);
|
||||
K(KeyF9);
|
||||
K(KeyF10);
|
||||
K(KeyF11);
|
||||
K(KeyF12);
|
||||
K(KeyF13);
|
||||
K(KeyF14);
|
||||
K(KeyF15);
|
||||
K(KeyF16);
|
||||
K(KeyF17);
|
||||
K(KeyF18);
|
||||
K(KeyF19);
|
||||
K(KeyF20);
|
||||
K(KeyF21);
|
||||
K(KeyF22);
|
||||
K(KeyF23);
|
||||
K(KeyF24);
|
||||
|
||||
default:
|
||||
return "KeyUnknown";
|
||||
}
|
||||
#undef K
|
||||
}
|
||||
|
||||
void event_to_buf(GHOST_EventHandle evt, char buf[128])
|
||||
{
|
||||
GHOST_TEventType type = GHOST_GetEventType(evt);
|
||||
double time = (double)((int64_t)GHOST_GetEventTime(evt)) / 1000;
|
||||
GHOST_WindowHandle win = GHOST_GetEventWindow(evt);
|
||||
void *data = GHOST_GetEventData(evt);
|
||||
char *pos = buf;
|
||||
|
||||
pos += sprintf(pos, "event: %6.2f, %16s", time, eventtype_to_string(type));
|
||||
if (win) {
|
||||
char *s = GHOST_GetTitle(win);
|
||||
pos += sprintf(pos, " - win: %s", s);
|
||||
free(s);
|
||||
}
|
||||
else {
|
||||
pos += sprintf(pos, " - sys evt");
|
||||
}
|
||||
switch (type) {
|
||||
case GHOST_kEventCursorMove: {
|
||||
GHOST_TEventCursorData *cd = data;
|
||||
pos += sprintf(pos, " - pos: (%d, %d)", cd->x, cd->y);
|
||||
break;
|
||||
}
|
||||
case GHOST_kEventButtonDown:
|
||||
case GHOST_kEventButtonUp: {
|
||||
GHOST_TEventButtonData *bd = data;
|
||||
pos += sprintf(pos, " - but: %d", bd->button);
|
||||
break;
|
||||
}
|
||||
|
||||
case GHOST_kEventKeyDown:
|
||||
case GHOST_kEventKeyUp: {
|
||||
GHOST_TEventKeyData *kd = data;
|
||||
pos += sprintf(pos, " - key: %s (%d)", keytype_to_string(kd->key), kd->key);
|
||||
/* TODO: ideally this would print the unicode character. */
|
||||
if (kd->utf8_buf[0]) {
|
||||
pos += sprintf(pos, " ascii: '%c' (%d)", kd->utf8_buf[0], kd->utf8_buf[0]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
char *eventtype_to_string(GHOST_TEventType type);
|
||||
void event_to_buf(GHOST_EventHandle evt, char buf[128]);
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#if defined(WIN32) || defined(__APPLE__)
|
||||
|
||||
# ifdef WIN32
|
||||
# include <GL/gl.h>
|
||||
# include <windows.h>
|
||||
# else // WIN32
|
||||
// __APPLE__ is defined
|
||||
# include <AGL/gl.h>
|
||||
# endif // WIN32
|
||||
#else // defined(WIN32) || defined(__APPLE__)
|
||||
# include <GL/gl.h>
|
||||
#endif // defined(WIN32) || defined(__APPLE__)
|
||||
|
|
@ -1,969 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/* Developers Note:
|
||||
*
|
||||
* This test currently only creates windows and draws a 'dot' under the cursor on LMB,
|
||||
* quits when Q is pressed.
|
||||
*
|
||||
* More work is needed for logging drawing to work properly.
|
||||
*
|
||||
* - Use GPU_matrix API.
|
||||
* - Replace old OpenGL calls to `glColor`, etc with `imm` API.
|
||||
* - Investigate BLF font flushing (`widgetbase_draw_cache_flush`) which is currently disabled.
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(disable : 4244 4305)
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "GL.h"
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "GHOST_C-api.h"
|
||||
|
||||
#include "BLF_api.hh"
|
||||
|
||||
#include "Basic.h"
|
||||
#include "EventToBuf.h"
|
||||
#include "ScrollBar.h"
|
||||
#include "Util.h"
|
||||
|
||||
#include "WindowData.h"
|
||||
|
||||
/* GPU API. */
|
||||
#include "GPU_context.hh"
|
||||
#include "GPU_immediate.hh"
|
||||
#include "GPU_init_exit.hh"
|
||||
|
||||
extern int datatoc_bfont_ttf_size;
|
||||
extern char const datatoc_bfont_ttf[];
|
||||
|
||||
typedef struct _LoggerWindow LoggerWindow;
|
||||
typedef struct _MultiTestApp MultiTestApp;
|
||||
|
||||
void loggerwindow_log(LoggerWindow *lw, char *line);
|
||||
|
||||
void multitestapp_toggle_extra_window(MultiTestApp *app);
|
||||
void multitestapp_free_extrawindow(MultiTestApp *app);
|
||||
LoggerWindow *multitestapp_get_logger(MultiTestApp *app);
|
||||
GHOST_SystemHandle multitestapp_get_system(MultiTestApp *app);
|
||||
void multitestapp_exit(MultiTestApp *app);
|
||||
|
||||
/**/
|
||||
|
||||
void rect_bevel_side(int rect[2][2], int side, float *lt, float *dk, const float col[3], int width)
|
||||
{
|
||||
int ltidx = (side / 2) % 4;
|
||||
int dkidx = (ltidx + 1 + (side & 1)) % 4;
|
||||
int i, corner;
|
||||
|
||||
glBegin(GL_LINES);
|
||||
for (i = 0; i < width; i++) {
|
||||
float ltf = pow(lt[i], 1.0 / 2.2), dkf = pow(dk[i], 1.0 / 2.2);
|
||||
float stf = (dkidx > ltidx) ? dkf : ltf;
|
||||
int lx = rect[1][0] - i - 1;
|
||||
int ly = rect[0][1] + i;
|
||||
|
||||
glColor3f(col[0] * stf, col[1] * stf, col[2] * stf);
|
||||
for (corner = 0; corner < 4; corner++) {
|
||||
int x = (corner == 0 || corner == 1) ? (rect[0][0] + i) : (rect[1][0] - i - 1);
|
||||
int y = (corner == 0 || corner == 3) ? (rect[0][1] + i) : (rect[1][1] - i - 1);
|
||||
|
||||
if (ltidx == corner) {
|
||||
glColor3f(col[0] * ltf, col[1] * ltf, col[2] * ltf);
|
||||
}
|
||||
if (dkidx == corner) {
|
||||
glColor3f(col[0] * dkf, col[1] * dkf, col[2] * dkf);
|
||||
}
|
||||
|
||||
glVertex2i(lx, ly);
|
||||
glVertex2i(lx = x, ly = y);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
|
||||
glColor3fv(col);
|
||||
glRecti(rect[0][0] + width, rect[0][1] + width, rect[1][0] - width, rect[1][1] - width);
|
||||
}
|
||||
|
||||
void rect_bevel_smooth(int rect[2][2], int width)
|
||||
{
|
||||
float *lt = malloc(sizeof(*lt) * width);
|
||||
float *dk = malloc(sizeof(*dk) * width);
|
||||
float col[4];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < width; i++) {
|
||||
float v = width - 1 ? ((float)i / (width - 1)) : 0;
|
||||
lt[i] = 1.2 + (1.0 - 1.2) * v;
|
||||
dk[i] = 0.2 + (1.0 - 0.2) * v;
|
||||
}
|
||||
|
||||
glGetFloatv(GL_CURRENT_COLOR, col);
|
||||
|
||||
rect_bevel_side(rect, 3, lt, dk, col, width);
|
||||
|
||||
free(lt);
|
||||
free(dk);
|
||||
}
|
||||
|
||||
/*
|
||||
* MainWindow
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
MultiTestApp *app;
|
||||
|
||||
GHOST_WindowHandle win;
|
||||
GPUContext *gpu_context;
|
||||
|
||||
int size[2];
|
||||
|
||||
int lmouse[2], lmbut[3];
|
||||
|
||||
int tmouse[2];
|
||||
} MainWindow;
|
||||
|
||||
static void mainwindow_log(MainWindow *mw, char *str)
|
||||
{
|
||||
loggerwindow_log(multitestapp_get_logger(mw->app), str);
|
||||
}
|
||||
|
||||
static void mainwindow_do_draw(MainWindow *mw)
|
||||
{
|
||||
GHOST_ActivateWindowDrawingContext(mw->win);
|
||||
GHOST_SwapWindowBufferAcquire(mw->win);
|
||||
GPU_context_active_set(mw->gpu_context);
|
||||
|
||||
if (mw->lmbut[0]) {
|
||||
glClearColor(0.5, 0.5, 0.5, 1);
|
||||
}
|
||||
else {
|
||||
glClearColor(1, 1, 1, 1);
|
||||
}
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glColor3f(0.5, 0.6, 0.8);
|
||||
glRecti(mw->tmouse[0] - 5, mw->tmouse[1] - 5, mw->tmouse[0] + 5, mw->tmouse[1] + 5);
|
||||
|
||||
GHOST_SwapWindowBufferRelease(mw->win);
|
||||
}
|
||||
|
||||
static void mainwindow_do_reshape(MainWindow *mw)
|
||||
{
|
||||
GHOST_RectangleHandle bounds = GHOST_GetClientBounds(mw->win);
|
||||
|
||||
GHOST_ActivateWindowDrawingContext(mw->win);
|
||||
GPU_context_active_set(mw->gpu_context);
|
||||
|
||||
mw->size[0] = GHOST_GetWidthRectangle(bounds);
|
||||
mw->size[1] = GHOST_GetHeightRectangle(bounds);
|
||||
|
||||
glViewport(0, 0, mw->size[0], mw->size[1]);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, mw->size[0], 0, mw->size[1], -1, 1);
|
||||
glTranslatef(0.375, 0.375, 0.0);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
static void mainwindow_do_key(MainWindow *mw, GHOST_TKey key, int press)
|
||||
{
|
||||
switch (key) {
|
||||
case GHOST_kKeyC:
|
||||
if (press) {
|
||||
GHOST_SetCursorShape(mw->win,
|
||||
(GHOST_TStandardCursor)(rand() % (GHOST_kStandardCursorNumCursors)));
|
||||
}
|
||||
break;
|
||||
case GHOST_kKeyLeftBracket:
|
||||
if (press) {
|
||||
GHOST_SetCursorVisibility(mw->win, false);
|
||||
}
|
||||
break;
|
||||
case GHOST_kKeyRightBracket:
|
||||
if (press) {
|
||||
GHOST_SetCursorVisibility(mw->win, true);
|
||||
}
|
||||
break;
|
||||
case GHOST_kKeyE:
|
||||
if (press) {
|
||||
multitestapp_toggle_extra_window(mw->app);
|
||||
}
|
||||
break;
|
||||
case GHOST_kKeyQ:
|
||||
if (press) {
|
||||
multitestapp_exit(mw->app);
|
||||
}
|
||||
break;
|
||||
case GHOST_kKeyT:
|
||||
if (press) {
|
||||
mainwindow_log(mw, "TextTest~|`hello`\"world\",<>/");
|
||||
}
|
||||
break;
|
||||
case GHOST_kKeyR:
|
||||
if (press) {
|
||||
int i;
|
||||
|
||||
mainwindow_log(mw, "Invalidating window 10 times");
|
||||
for (i = 0; i < 10; i++) {
|
||||
GHOST_InvalidateWindow(mw->win);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GHOST_kKeyF11:
|
||||
if (press) {
|
||||
GHOST_SetWindowOrder(mw->win, GHOST_kWindowOrderBottom);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void mainwindow_do_move(MainWindow *mw, int x, int y)
|
||||
{
|
||||
mw->lmouse[0] = x, mw->lmouse[1] = y;
|
||||
|
||||
if (mw->lmbut[0]) {
|
||||
mw->tmouse[0] = x, mw->tmouse[1] = y;
|
||||
GHOST_InvalidateWindow(mw->win);
|
||||
}
|
||||
}
|
||||
|
||||
static void mainwindow_do_button(MainWindow *mw, int which, int press)
|
||||
{
|
||||
if (which == GHOST_kButtonMaskLeft) {
|
||||
mw->lmbut[0] = press;
|
||||
mw->tmouse[0] = mw->lmouse[0], mw->tmouse[1] = mw->lmouse[1];
|
||||
GHOST_InvalidateWindow(mw->win);
|
||||
}
|
||||
else if (which == GHOST_kButtonMaskLeft) {
|
||||
mw->lmbut[1] = press;
|
||||
}
|
||||
else if (which == GHOST_kButtonMaskLeft) {
|
||||
mw->lmbut[2] = press;
|
||||
}
|
||||
}
|
||||
|
||||
static void mainwindow_handle(void *priv, GHOST_EventHandle evt)
|
||||
{
|
||||
MainWindow *mw = priv;
|
||||
GHOST_TEventType type = GHOST_GetEventType(evt);
|
||||
char buf[256];
|
||||
|
||||
event_to_buf(evt, buf);
|
||||
mainwindow_log(mw, buf);
|
||||
|
||||
switch (type) {
|
||||
case GHOST_kEventCursorMove: {
|
||||
GHOST_TEventCursorData *cd = GHOST_GetEventData(evt);
|
||||
int x, y;
|
||||
GHOST_ScreenToClient(mw->win, cd->x, cd->y, &x, &y);
|
||||
mainwindow_do_move(mw, x, mw->size[1] - y - 1);
|
||||
break;
|
||||
}
|
||||
case GHOST_kEventButtonDown:
|
||||
case GHOST_kEventButtonUp: {
|
||||
GHOST_TEventButtonData *bd = GHOST_GetEventData(evt);
|
||||
mainwindow_do_button(mw, bd->button, (type == GHOST_kEventButtonDown));
|
||||
break;
|
||||
}
|
||||
case GHOST_kEventKeyDown:
|
||||
case GHOST_kEventKeyUp: {
|
||||
GHOST_TEventKeyData *kd = GHOST_GetEventData(evt);
|
||||
mainwindow_do_key(mw, kd->key, (type == GHOST_kEventKeyDown));
|
||||
break;
|
||||
}
|
||||
|
||||
case GHOST_kEventWindowUpdate:
|
||||
mainwindow_do_draw(mw);
|
||||
break;
|
||||
case GHOST_kEventWindowSize:
|
||||
mainwindow_do_reshape(mw);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
static void mainwindow_timer_proc(GHOST_TimerTaskHandle task, uint64_t time)
|
||||
{
|
||||
MainWindow *mw = GHOST_GetTimerTaskUserData(task);
|
||||
char buf[64];
|
||||
|
||||
sprintf(buf, "timer: %6.2f", (double)((int64_t)time) / 1000);
|
||||
mainwindow_log(mw, buf);
|
||||
}
|
||||
|
||||
MainWindow *mainwindow_new(MultiTestApp *app)
|
||||
{
|
||||
GHOST_SystemHandle sys = multitestapp_get_system(app);
|
||||
GHOST_WindowHandle win;
|
||||
GHOST_GPUSettings gpu_settings = {0};
|
||||
|
||||
win = GHOST_CreateWindow(sys,
|
||||
NULL,
|
||||
"MultiTest:Main",
|
||||
40,
|
||||
40,
|
||||
400,
|
||||
400,
|
||||
GHOST_kWindowStateNormal,
|
||||
false,
|
||||
GHOST_kDrawingContextTypeOpenGL,
|
||||
gpu_settings);
|
||||
|
||||
if (win) {
|
||||
MainWindow *mw = MEM_new_zeroed<MainWindow>("mainwindow_new");
|
||||
|
||||
mw->gpu_context = GPU_context_create(win, NULL);
|
||||
GPU_init();
|
||||
|
||||
mw->app = app;
|
||||
mw->win = win;
|
||||
|
||||
GHOST_SetWindowUserData(mw->win, windowdata_new(mw, mainwindow_handle));
|
||||
|
||||
GHOST_InstallTimer(sys, 1000, 10000, mainwindow_timer_proc, mw);
|
||||
|
||||
return mw;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void mainwindow_free(MainWindow *mw)
|
||||
{
|
||||
GHOST_SystemHandle sys = multitestapp_get_system(mw->app);
|
||||
|
||||
windowdata_free(GHOST_GetWindowUserData(mw->win));
|
||||
GHOST_DisposeWindow(sys, mw->win);
|
||||
MEM_delete(mw);
|
||||
}
|
||||
|
||||
/*
|
||||
* LoggerWindow
|
||||
*/
|
||||
|
||||
struct _LoggerWindow {
|
||||
MultiTestApp *app;
|
||||
|
||||
GHOST_WindowHandle win;
|
||||
GPUContext *gpu_context;
|
||||
|
||||
int font;
|
||||
int fontheight;
|
||||
|
||||
int size[2];
|
||||
|
||||
int ndisplines;
|
||||
int textarea[2][2];
|
||||
ScrollBar *scroll;
|
||||
|
||||
char **loglines;
|
||||
int nloglines, logsize;
|
||||
|
||||
int lmbut[3];
|
||||
int lmouse[2];
|
||||
};
|
||||
|
||||
#define SCROLLBAR_PAD 2
|
||||
#define SCROLLBAR_WIDTH 14
|
||||
#define TEXTAREA_PAD 2
|
||||
static void loggerwindow_recalc_regions(LoggerWindow *lw)
|
||||
{
|
||||
int nscroll[2][2];
|
||||
|
||||
nscroll[0][0] = SCROLLBAR_PAD;
|
||||
nscroll[0][1] = SCROLLBAR_PAD;
|
||||
nscroll[1][0] = nscroll[0][0] + SCROLLBAR_WIDTH;
|
||||
nscroll[1][1] = lw->size[1] - SCROLLBAR_PAD - 1;
|
||||
|
||||
lw->textarea[0][0] = nscroll[1][0] + TEXTAREA_PAD;
|
||||
lw->textarea[0][1] = TEXTAREA_PAD;
|
||||
lw->textarea[1][0] = lw->size[0] - TEXTAREA_PAD - 1;
|
||||
lw->textarea[1][1] = lw->size[1] - TEXTAREA_PAD - 1;
|
||||
|
||||
lw->ndisplines = (lw->textarea[1][1] - lw->textarea[0][1]) / lw->fontheight;
|
||||
|
||||
scrollbar_set_thumbpct(lw->scroll, (float)lw->ndisplines / lw->nloglines);
|
||||
scrollbar_set_rect(lw->scroll, nscroll);
|
||||
}
|
||||
|
||||
static void loggerwindow_setup_window_gl(LoggerWindow *lw)
|
||||
{
|
||||
glViewport(0, 0, lw->size[0], lw->size[1]);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, lw->size[0], 0, lw->size[1], -1, 1);
|
||||
glTranslatef(0.375, 0.375, 0.0);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
static void loggerwindow_do_reshape(LoggerWindow *lw)
|
||||
{
|
||||
GHOST_RectangleHandle bounds = GHOST_GetClientBounds(lw->win);
|
||||
|
||||
GHOST_ActivateWindowDrawingContext(lw->win);
|
||||
GPU_context_active_set(lw->gpu_context);
|
||||
|
||||
lw->size[0] = GHOST_GetWidthRectangle(bounds);
|
||||
lw->size[1] = GHOST_GetHeightRectangle(bounds);
|
||||
|
||||
loggerwindow_recalc_regions(lw);
|
||||
loggerwindow_setup_window_gl(lw);
|
||||
}
|
||||
|
||||
static void loggerwindow_do_draw(LoggerWindow *lw)
|
||||
{
|
||||
int i, ndisplines, startline;
|
||||
int sb_rect[2][2], sb_thumb[2][2];
|
||||
|
||||
GHOST_ActivateWindowDrawingContext(lw->win);
|
||||
GHOST_SwapWindowBufferAcquire(lw->win);
|
||||
GPU_context_active_set(lw->gpu_context);
|
||||
|
||||
glClearColor(1, 1, 1, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glColor3f(0.8, 0.8, 0.8);
|
||||
rect_bevel_smooth(lw->textarea, 4);
|
||||
|
||||
scrollbar_get_rect(lw->scroll, sb_rect);
|
||||
scrollbar_get_thumb(lw->scroll, sb_thumb);
|
||||
|
||||
glColor3f(0.6, 0.6, 0.6);
|
||||
rect_bevel_smooth(sb_rect, 1);
|
||||
|
||||
if (scrollbar_is_scrolling(lw->scroll)) {
|
||||
glColor3f(0.6, 0.7, 0.5);
|
||||
}
|
||||
else {
|
||||
glColor3f(0.9, 0.9, 0.92);
|
||||
}
|
||||
rect_bevel_smooth(sb_thumb, 1);
|
||||
|
||||
startline = scrollbar_get_thumbpos(lw->scroll) * (lw->nloglines - 1);
|
||||
ndisplines = min_i(lw->ndisplines, lw->nloglines - startline);
|
||||
|
||||
glColor3f(0, 0, 0);
|
||||
for (i = 0; i < ndisplines; i++) {
|
||||
/* stored in reverse order */
|
||||
char *line = lw->loglines[(lw->nloglines - 1) - (i + startline)];
|
||||
int x_pos = lw->textarea[0][0] + 4;
|
||||
int y_pos = lw->textarea[0][1] + 4 + i * lw->fontheight;
|
||||
|
||||
BLF_position(lw->font, x_pos, y_pos, 0.0);
|
||||
BLF_draw(lw->font, line, 256); // XXX
|
||||
}
|
||||
|
||||
GHOST_SwapWindowBufferRelease(lw->win);
|
||||
|
||||
immDeactivate();
|
||||
}
|
||||
|
||||
static void loggerwindow_do_move(LoggerWindow *lw, int x, int y)
|
||||
{
|
||||
lw->lmouse[0] = x, lw->lmouse[1] = y;
|
||||
|
||||
if (scrollbar_is_scrolling(lw->scroll)) {
|
||||
scrollbar_keep_scrolling(lw->scroll, y);
|
||||
GHOST_InvalidateWindow(lw->win);
|
||||
}
|
||||
}
|
||||
|
||||
static void loggerwindow_do_button(LoggerWindow *lw, int which, int press)
|
||||
{
|
||||
if (which == GHOST_kButtonMaskLeft) {
|
||||
lw->lmbut[0] = press;
|
||||
|
||||
if (press) {
|
||||
if (scrollbar_contains_pt(lw->scroll, lw->lmouse)) {
|
||||
scrollbar_start_scrolling(lw->scroll, lw->lmouse[1]);
|
||||
GHOST_SetCursorShape(lw->win, GHOST_kStandardCursorUpDown);
|
||||
GHOST_InvalidateWindow(lw->win);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (scrollbar_is_scrolling(lw->scroll)) {
|
||||
scrollbar_stop_scrolling(lw->scroll);
|
||||
GHOST_SetCursorShape(lw->win, GHOST_kStandardCursorDefault);
|
||||
GHOST_InvalidateWindow(lw->win);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (which == GHOST_kButtonMaskMiddle) {
|
||||
lw->lmbut[1] = press;
|
||||
}
|
||||
else if (which == GHOST_kButtonMaskRight) {
|
||||
lw->lmbut[2] = press;
|
||||
}
|
||||
}
|
||||
|
||||
static void loggerwindow_do_key(LoggerWindow *lw, GHOST_TKey key, int press)
|
||||
{
|
||||
switch (key) {
|
||||
case GHOST_kKeyQ:
|
||||
if (press) {
|
||||
multitestapp_exit(lw->app);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void loggerwindow_handle(void *priv, GHOST_EventHandle evt)
|
||||
{
|
||||
LoggerWindow *lw = priv;
|
||||
GHOST_TEventType type = GHOST_GetEventType(evt);
|
||||
|
||||
switch (type) {
|
||||
case GHOST_kEventCursorMove: {
|
||||
GHOST_TEventCursorData *cd = GHOST_GetEventData(evt);
|
||||
int x, y;
|
||||
GHOST_ScreenToClient(lw->win, cd->x, cd->y, &x, &y);
|
||||
loggerwindow_do_move(lw, x, lw->size[1] - y - 1);
|
||||
break;
|
||||
}
|
||||
case GHOST_kEventButtonDown:
|
||||
case GHOST_kEventButtonUp: {
|
||||
GHOST_TEventButtonData *bd = GHOST_GetEventData(evt);
|
||||
loggerwindow_do_button(lw, bd->button, (type == GHOST_kEventButtonDown));
|
||||
break;
|
||||
}
|
||||
case GHOST_kEventKeyDown:
|
||||
case GHOST_kEventKeyUp: {
|
||||
GHOST_TEventKeyData *kd = GHOST_GetEventData(evt);
|
||||
loggerwindow_do_key(lw, kd->key, (type == GHOST_kEventKeyDown));
|
||||
break;
|
||||
}
|
||||
|
||||
case GHOST_kEventWindowUpdate:
|
||||
loggerwindow_do_draw(lw);
|
||||
break;
|
||||
case GHOST_kEventWindowSize:
|
||||
loggerwindow_do_reshape(lw);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
LoggerWindow *loggerwindow_new(MultiTestApp *app)
|
||||
{
|
||||
GHOST_GPUSettings gpu_settings = {0};
|
||||
GHOST_SystemHandle sys = multitestapp_get_system(app);
|
||||
uint32_t screensize[2];
|
||||
GHOST_WindowHandle win;
|
||||
|
||||
int posx = 40;
|
||||
int posy = 0;
|
||||
if (GHOST_GetMainDisplayDimensions(sys, &screensize[0], &screensize[1]) == GHOST_kSuccess) {
|
||||
posy = screensize[1] - 432;
|
||||
}
|
||||
|
||||
win = GHOST_CreateWindow(sys,
|
||||
NULL,
|
||||
"MultiTest:Logger",
|
||||
posx,
|
||||
posy,
|
||||
800,
|
||||
300,
|
||||
GHOST_kWindowStateNormal,
|
||||
false,
|
||||
GHOST_kDrawingContextTypeOpenGL,
|
||||
gpu_settings);
|
||||
|
||||
if (win) {
|
||||
LoggerWindow *lw = MEM_new_zeroed<LoggerWindow>("loggerwindow_new");
|
||||
|
||||
lw->gpu_context = GPU_context_create(win, NULL);
|
||||
GPU_init();
|
||||
|
||||
int bbox[2][2];
|
||||
lw->app = app;
|
||||
lw->win = win;
|
||||
|
||||
lw->font = BLF_load_default(false);
|
||||
BLF_size(lw->font, 11, 72);
|
||||
lw->fontheight = BLF_height(lw->font, "A_", 2);
|
||||
|
||||
lw->nloglines = lw->logsize = 0;
|
||||
lw->loglines = MEM_new_array_uninitialized<char *>(lw->nloglines, "loglines");
|
||||
|
||||
lw->scroll = scrollbar_new(2, 40);
|
||||
|
||||
GHOST_SetWindowUserData(lw->win, windowdata_new(lw, loggerwindow_handle));
|
||||
|
||||
loggerwindow_do_reshape(lw);
|
||||
|
||||
return lw;
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void loggerwindow_log(LoggerWindow *lw, char *line)
|
||||
{
|
||||
if (lw->nloglines == lw->logsize) {
|
||||
lw->loglines = memdbl(lw->loglines, &lw->logsize, sizeof(*lw->loglines));
|
||||
}
|
||||
|
||||
lw->loglines[lw->nloglines++] = string_dup(line);
|
||||
scrollbar_set_thumbpct(lw->scroll, (float)lw->ndisplines / lw->nloglines);
|
||||
|
||||
GHOST_InvalidateWindow(lw->win);
|
||||
}
|
||||
|
||||
void loggerwindow_free(LoggerWindow *lw)
|
||||
{
|
||||
GHOST_SystemHandle sys = multitestapp_get_system(lw->app);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < lw->nloglines; i++) {
|
||||
MEM_delete(lw->loglines[i]);
|
||||
}
|
||||
MEM_delete(lw->loglines);
|
||||
|
||||
windowdata_free(GHOST_GetWindowUserData(lw->win));
|
||||
GHOST_DisposeWindow(sys, lw->win);
|
||||
MEM_delete(lw);
|
||||
}
|
||||
|
||||
/*
|
||||
* ExtraWindow
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
MultiTestApp *app;
|
||||
|
||||
GHOST_WindowHandle win;
|
||||
GPUContext *gpu_context;
|
||||
|
||||
int size[2];
|
||||
} ExtraWindow;
|
||||
|
||||
static void extrawindow_do_draw(ExtraWindow *ew)
|
||||
{
|
||||
GHOST_ActivateWindowDrawingContext(ew->win);
|
||||
GHOST_SwapWindowBufferAcquire(eq->win);
|
||||
GPU_context_active_set(ew->gpu_context);
|
||||
|
||||
glClearColor(1, 1, 1, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glColor3f(0.8, 0.8, 0.8);
|
||||
glRecti(10, 10, ew->size[0] - 10, ew->size[1] - 10);
|
||||
|
||||
GHOST_SwapWindowBufferRelease(ew->win);
|
||||
}
|
||||
|
||||
static void extrawindow_do_reshape(ExtraWindow *ew)
|
||||
{
|
||||
GHOST_RectangleHandle bounds = GHOST_GetClientBounds(ew->win);
|
||||
|
||||
GHOST_ActivateWindowDrawingContext(ew->win);
|
||||
GPU_context_active_set(ew->gpu_context);
|
||||
|
||||
ew->size[0] = GHOST_GetWidthRectangle(bounds);
|
||||
ew->size[1] = GHOST_GetHeightRectangle(bounds);
|
||||
|
||||
glViewport(0, 0, ew->size[0], ew->size[1]);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, ew->size[0], 0, ew->size[1], -1, 1);
|
||||
glTranslatef(0.375, 0.375, 0.0);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
static void extrawindow_do_key(ExtraWindow *ew, GHOST_TKey key, int press)
|
||||
{
|
||||
switch (key) {
|
||||
case GHOST_kKeyE:
|
||||
if (press) {
|
||||
multitestapp_toggle_extra_window(ew->app);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void extrawindow_spin_cursor(ExtraWindow *ew, uint64_t time)
|
||||
{
|
||||
uint8_t bitmap[16][2];
|
||||
uint8_t mask[16][2];
|
||||
double ftime = (double)((int64_t)time) / 1000;
|
||||
float angle = fmod(ftime, 1.0) * 3.1415 * 2;
|
||||
int i;
|
||||
|
||||
memset(&bitmap, 0, sizeof(bitmap));
|
||||
memset(&mask, 0, sizeof(mask));
|
||||
|
||||
bitmap[0][0] |= mask[0][0] |= 0xF;
|
||||
bitmap[1][0] |= mask[1][0] |= 0xF;
|
||||
bitmap[2][0] |= mask[2][0] |= 0xF;
|
||||
bitmap[3][0] |= mask[3][0] |= 0xF;
|
||||
|
||||
for (i = 0; i < 7; i++) {
|
||||
int x = 7 + cos(angle) * i;
|
||||
int y = 7 + sin(angle) * i;
|
||||
|
||||
mask[y][x / 8] |= (1 << (x % 8));
|
||||
}
|
||||
for (i = 0; i < 64; i++) {
|
||||
float v = (i / 63.0) * 3.1415 * 2;
|
||||
int x = 7 + cos(v) * 7;
|
||||
int y = 7 + sin(v) * 7;
|
||||
|
||||
mask[y][x / 8] |= (1 << (x % 8));
|
||||
}
|
||||
|
||||
const int size[2] = {16, 16};
|
||||
const int hot_spot[2] = {0, 0};
|
||||
|
||||
GHOST_SetCustomCursorShape(ew->win, &bitmap[0][0], &mask[0][0], size, hot_spot, true);
|
||||
}
|
||||
|
||||
static void extrawindow_handle(void *priv, GHOST_EventHandle evt)
|
||||
{
|
||||
ExtraWindow *ew = priv;
|
||||
GHOST_TEventType type = GHOST_GetEventType(evt);
|
||||
char buf[256];
|
||||
|
||||
event_to_buf(evt, buf);
|
||||
loggerwindow_log(multitestapp_get_logger(ew->app), buf);
|
||||
|
||||
switch (type) {
|
||||
case GHOST_kEventKeyDown:
|
||||
case GHOST_kEventKeyUp: {
|
||||
GHOST_TEventKeyData *kd = GHOST_GetEventData(evt);
|
||||
extrawindow_do_key(ew, kd->key, (type == GHOST_kEventKeyDown));
|
||||
break;
|
||||
}
|
||||
|
||||
case GHOST_kEventCursorMove: {
|
||||
extrawindow_spin_cursor(ew, GHOST_GetEventTime(evt));
|
||||
break;
|
||||
}
|
||||
|
||||
case GHOST_kEventWindowClose:
|
||||
multitestapp_free_extrawindow(ew->app);
|
||||
break;
|
||||
case GHOST_kEventWindowUpdate:
|
||||
extrawindow_do_draw(ew);
|
||||
break;
|
||||
case GHOST_kEventWindowSize:
|
||||
extrawindow_do_reshape(ew);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
ExtraWindow *extrawindow_new(MultiTestApp *app)
|
||||
{
|
||||
GHOST_GPUSettings gpu_settings = {0};
|
||||
GHOST_SystemHandle sys = multitestapp_get_system(app);
|
||||
GHOST_WindowHandle win;
|
||||
|
||||
win = GHOST_CreateWindow(sys,
|
||||
NULL,
|
||||
"MultiTest:Extra",
|
||||
500,
|
||||
40,
|
||||
400,
|
||||
400,
|
||||
GHOST_kWindowStateNormal,
|
||||
false,
|
||||
GHOST_kDrawingContextTypeOpenGL,
|
||||
gpu_settings);
|
||||
|
||||
if (win) {
|
||||
ExtraWindow *ew = MEM_new_zeroed<ExtraWindow>("mainwindow_new");
|
||||
|
||||
ew->gpu_context = GPU_context_create(win, NULL);
|
||||
GPU_init();
|
||||
|
||||
ew->app = app;
|
||||
ew->win = win;
|
||||
|
||||
GHOST_SetWindowUserData(ew->win, windowdata_new(ew, extrawindow_handle));
|
||||
|
||||
return ew;
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void extrawindow_free(ExtraWindow *ew)
|
||||
{
|
||||
GHOST_SystemHandle sys = multitestapp_get_system(ew->app);
|
||||
|
||||
windowdata_free(GHOST_GetWindowUserData(ew->win));
|
||||
GHOST_DisposeWindow(sys, ew->win);
|
||||
MEM_delete(ew);
|
||||
}
|
||||
|
||||
/*
|
||||
* MultiTestApp
|
||||
*/
|
||||
|
||||
struct _MultiTestApp {
|
||||
GHOST_SystemHandle sys;
|
||||
MainWindow *main;
|
||||
LoggerWindow *logger;
|
||||
ExtraWindow *extra;
|
||||
|
||||
int exit;
|
||||
};
|
||||
|
||||
static bool multitest_event_handler(GHOST_EventHandle evt, GHOST_TUserDataPtr data)
|
||||
{
|
||||
MultiTestApp *app = data;
|
||||
GHOST_WindowHandle win;
|
||||
|
||||
win = GHOST_GetEventWindow(evt);
|
||||
if (win && !GHOST_ValidWindow(app->sys, win)) {
|
||||
loggerwindow_log(app->logger, "WARNING: bad event, non-valid window\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (win) {
|
||||
WindowData *wb = GHOST_GetWindowUserData(win);
|
||||
|
||||
windowdata_handle(wb, evt);
|
||||
}
|
||||
else {
|
||||
GHOST_TEventType type = GHOST_GetEventType(evt);
|
||||
|
||||
/* GHOST_kEventQuit are the only 'system' events,
|
||||
* that is, events without a window.
|
||||
*/
|
||||
switch (type) {
|
||||
case GHOST_kEventQuitRequest:
|
||||
app->exit = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("Unhandled system event: %d (%s)\n", type, eventtype_to_string(type));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
MultiTestApp *multitestapp_new(void)
|
||||
{
|
||||
MultiTestApp *app = MEM_new_uninitialized<MultiTestApp>("multitestapp_new");
|
||||
GHOST_EventConsumerHandle consumer = GHOST_CreateEventConsumer(multitest_event_handler, app);
|
||||
|
||||
app->sys = GHOST_CreateSystem();
|
||||
if (!app->sys) {
|
||||
fatal("Unable to create ghost system");
|
||||
}
|
||||
GPU_backend_ghost_system_set(app->sys);
|
||||
|
||||
if (!GHOST_AddEventConsumer(app->sys, consumer)) {
|
||||
fatal("Unable to add multitest event consumer ");
|
||||
}
|
||||
|
||||
app->main = mainwindow_new(app);
|
||||
if (!app->main) {
|
||||
fatal("Unable to create main window");
|
||||
}
|
||||
|
||||
app->logger = loggerwindow_new(app);
|
||||
if (!app->logger) {
|
||||
fatal("Unable to create logger window");
|
||||
}
|
||||
|
||||
app->extra = NULL;
|
||||
app->exit = 0;
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
LoggerWindow *multitestapp_get_logger(MultiTestApp *app)
|
||||
{
|
||||
return app->logger;
|
||||
}
|
||||
|
||||
GHOST_SystemHandle multitestapp_get_system(MultiTestApp *app)
|
||||
{
|
||||
return app->sys;
|
||||
}
|
||||
|
||||
void multitestapp_free_extrawindow(MultiTestApp *app)
|
||||
{
|
||||
extrawindow_free(app->extra);
|
||||
app->extra = NULL;
|
||||
}
|
||||
|
||||
void multitestapp_toggle_extra_window(MultiTestApp *app)
|
||||
{
|
||||
if (app->extra) {
|
||||
multitestapp_free_extrawindow(app);
|
||||
}
|
||||
else {
|
||||
app->extra = extrawindow_new(app);
|
||||
}
|
||||
}
|
||||
|
||||
void multitestapp_exit(MultiTestApp *app)
|
||||
{
|
||||
app->exit = 1;
|
||||
}
|
||||
|
||||
void multitestapp_run(MultiTestApp *app)
|
||||
{
|
||||
while (!app->exit) {
|
||||
GHOST_ProcessEvents(app->sys, true);
|
||||
GHOST_DispatchEvents(app->sys);
|
||||
}
|
||||
}
|
||||
|
||||
void multitestapp_free(MultiTestApp *app)
|
||||
{
|
||||
BLF_exit();
|
||||
GPU_exit();
|
||||
|
||||
mainwindow_free(app->main);
|
||||
loggerwindow_free(app->logger);
|
||||
GHOST_DisposeSystem(app->sys);
|
||||
MEM_delete(app);
|
||||
}
|
||||
|
||||
/***/
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
MultiTestApp *app;
|
||||
|
||||
BLF_init();
|
||||
|
||||
app = multitestapp_new();
|
||||
|
||||
multitestapp_run(app);
|
||||
multitestapp_free(app);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,136 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "Basic.h"
|
||||
#include "ScrollBar.h"
|
||||
|
||||
struct _ScrollBar {
|
||||
int rect[2][2];
|
||||
float thumbpos, thumbpct;
|
||||
|
||||
int inset;
|
||||
int minthumb;
|
||||
|
||||
int scrolling;
|
||||
float scrolloffs;
|
||||
};
|
||||
|
||||
static int scrollbar_get_thumbH(ScrollBar *sb)
|
||||
{
|
||||
int scrollable_h = rect_height(sb->rect) - 2 * sb->inset;
|
||||
|
||||
return clamp_i(sb->thumbpct * scrollable_h, sb->minthumb, scrollable_h);
|
||||
}
|
||||
|
||||
static int scrollbar_get_thumbableH(ScrollBar *sb)
|
||||
{
|
||||
int scrollable_h = rect_height(sb->rect) - 2 * sb->inset;
|
||||
int thumb_h = scrollbar_get_thumbH(sb);
|
||||
|
||||
return scrollable_h - thumb_h;
|
||||
}
|
||||
|
||||
static float scrollbar_co_to_pos(ScrollBar *sb, int yco)
|
||||
{
|
||||
int thumb_h = scrollbar_get_thumbH(sb);
|
||||
int thumbable_h = scrollbar_get_thumbableH(sb);
|
||||
int thumbable_y = (sb->rect[0][1] + sb->inset) + thumb_h / 2;
|
||||
|
||||
return (float)(yco - thumbable_y) / thumbable_h;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
ScrollBar *scrollbar_new(int inset, int minthumb)
|
||||
{
|
||||
ScrollBar *sb = MEM_new_zeroed<ScrollBar>("scrollbar_new");
|
||||
sb->inset = inset;
|
||||
sb->minthumb = minthumb;
|
||||
|
||||
return sb;
|
||||
}
|
||||
|
||||
void scrollbar_get_thumb(ScrollBar *sb, int thumb_r[2][2])
|
||||
{
|
||||
int thumb_h = scrollbar_get_thumbH(sb);
|
||||
int thumbable_h = scrollbar_get_thumbableH(sb);
|
||||
|
||||
thumb_r[0][0] = sb->rect[0][0] + sb->inset;
|
||||
thumb_r[1][0] = sb->rect[1][0] - sb->inset;
|
||||
|
||||
thumb_r[0][1] = sb->rect[0][1] + sb->inset + sb->thumbpos * thumbable_h;
|
||||
thumb_r[1][1] = thumb_r[0][1] + thumb_h;
|
||||
}
|
||||
|
||||
int scrollbar_is_scrolling(ScrollBar *sb)
|
||||
{
|
||||
return sb->scrolling;
|
||||
}
|
||||
int scrollbar_contains_pt(ScrollBar *sb, int pt[2])
|
||||
{
|
||||
return rect_contains_pt(sb->rect, pt);
|
||||
}
|
||||
|
||||
void scrollbar_start_scrolling(ScrollBar *sb, int yco)
|
||||
{
|
||||
int thumb_h_2 = scrollbar_get_thumbH(sb) / 2;
|
||||
int thumbable_h = scrollbar_get_thumbableH(sb);
|
||||
float npos = scrollbar_co_to_pos(sb, yco);
|
||||
|
||||
sb->scrolloffs = sb->thumbpos - npos;
|
||||
if (fabs(sb->scrolloffs) >= (float)thumb_h_2 / thumbable_h) {
|
||||
sb->scrolloffs = 0.0;
|
||||
}
|
||||
|
||||
sb->scrolling = 1;
|
||||
sb->thumbpos = clamp_f(npos + sb->scrolloffs, 0.0, 1.0);
|
||||
}
|
||||
void scrollbar_keep_scrolling(ScrollBar *sb, int yco)
|
||||
{
|
||||
float npos = scrollbar_co_to_pos(sb, yco);
|
||||
|
||||
sb->thumbpos = clamp_f(npos + sb->scrolloffs, 0.0, 1.0);
|
||||
}
|
||||
void scrollbar_stop_scrolling(ScrollBar *sb)
|
||||
{
|
||||
sb->scrolling = 0;
|
||||
sb->scrolloffs = 0.0;
|
||||
}
|
||||
|
||||
void scrollbar_set_thumbpct(ScrollBar *sb, float pct)
|
||||
{
|
||||
sb->thumbpct = pct;
|
||||
}
|
||||
void scrollbar_set_thumbpos(ScrollBar *sb, float pos)
|
||||
{
|
||||
sb->thumbpos = clamp_f(pos, 0.0, 1.0);
|
||||
}
|
||||
void scrollbar_set_rect(ScrollBar *sb, int rect[2][2])
|
||||
{
|
||||
rect_copy(sb->rect, rect);
|
||||
}
|
||||
|
||||
float scrollbar_get_thumbpct(ScrollBar *sb)
|
||||
{
|
||||
return sb->thumbpct;
|
||||
}
|
||||
float scrollbar_get_thumbpos(ScrollBar *sb)
|
||||
{
|
||||
return sb->thumbpos;
|
||||
}
|
||||
void scrollbar_get_rect(ScrollBar *sb, int rect_r[2][2])
|
||||
{
|
||||
rect_copy(rect_r, sb->rect);
|
||||
}
|
||||
|
||||
void scrollbar_free(ScrollBar *sb)
|
||||
{
|
||||
MEM_delete(sb);
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
typedef struct _ScrollBar ScrollBar;
|
||||
|
||||
/***/
|
||||
|
||||
ScrollBar *scrollbar_new(int inset, int minthumb);
|
||||
|
||||
int scrollbar_is_scrolling(ScrollBar *sb);
|
||||
int scrollbar_contains_pt(ScrollBar *sb, int pt[2]);
|
||||
|
||||
void scrollbar_start_scrolling(ScrollBar *sb, int yco);
|
||||
void scrollbar_keep_scrolling(ScrollBar *sb, int yco);
|
||||
void scrollbar_stop_scrolling(ScrollBar *sb);
|
||||
|
||||
void scrollbar_set_thumbpct(ScrollBar *sb, float pct);
|
||||
void scrollbar_set_thumbpos(ScrollBar *sb, float pos);
|
||||
void scrollbar_set_rect(ScrollBar *sb, int rect[2][2]);
|
||||
|
||||
float scrollbar_get_thumbpct(ScrollBar *sb);
|
||||
float scrollbar_get_thumbpos(ScrollBar *sb);
|
||||
void scrollbar_get_rect(ScrollBar *sb, int rect_r[2][2]);
|
||||
|
||||
void scrollbar_get_thumb(ScrollBar *sb, int thumb_r[2][2]);
|
||||
|
||||
void scrollbar_free(ScrollBar *sb);
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "Util.h"
|
||||
|
||||
void *memdbl(void *mem, int *size_pr, int item_size)
|
||||
{
|
||||
int cur_size = *size_pr;
|
||||
int new_size = cur_size ? (cur_size * 2) : 1;
|
||||
void *nmem = MEM_new_uninitialized(new_size * item_size, "memdbl");
|
||||
|
||||
memcpy(nmem, mem, cur_size * item_size);
|
||||
MEM_delete(mem);
|
||||
|
||||
*size_pr = new_size;
|
||||
return nmem;
|
||||
}
|
||||
|
||||
char *string_dup(char *str)
|
||||
{
|
||||
int len = strlen(str);
|
||||
char *nstr = MEM_new_array_uninitialized<char>(len + 1, "string_dup");
|
||||
|
||||
memcpy(nstr, str, len + 1);
|
||||
|
||||
return nstr;
|
||||
}
|
||||
|
||||
void fatal(char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
fprintf(stderr, "FATAL: ");
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
void *memdbl(void *mem, int *size_pr, int item_size);
|
||||
|
||||
char *string_dup(char *str);
|
||||
void fatal(char *fmt, ...);
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "GHOST_C-api.h"
|
||||
|
||||
#include "WindowData.h"
|
||||
|
||||
struct _WindowData {
|
||||
void *data;
|
||||
WindowDataHandler handler;
|
||||
};
|
||||
|
||||
WindowData *windowdata_new(void *data, WindowDataHandler handler)
|
||||
{
|
||||
WindowData *wb = MEM_new_uninitialized(sizeof(*wb), "windowdata_new");
|
||||
wb->data = data;
|
||||
wb->handler = handler;
|
||||
|
||||
return wb;
|
||||
}
|
||||
|
||||
void windowdata_handle(WindowData *wb, GHOST_EventHandle evt)
|
||||
{
|
||||
wb->handler(wb->data, evt);
|
||||
}
|
||||
|
||||
void windowdata_free(WindowData *wb)
|
||||
{
|
||||
MEM_delete(wb);
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
typedef void (*WindowDataHandler)(void *priv, GHOST_EventHandle evt);
|
||||
typedef struct _WindowData WindowData;
|
||||
|
||||
/***/
|
||||
|
||||
WindowData *windowdata_new(void *data, WindowDataHandler handler);
|
||||
void windowdata_handle(WindowData *wb, GHOST_EventHandle evt);
|
||||
void windowdata_free(WindowData *wb);
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2013 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
#include "IMB_imbuf.hh"
|
||||
|
||||
struct ColorSpace;
|
||||
struct ImBuf;
|
||||
|
||||
void IMB_freeImBuf(struct ImBuf *UNUSED(ibuf)) {}
|
||||
void IMB_colormanagement_display_to_scene_linear_v3(float UNUSED(pixel[3]),
|
||||
struct ColorManagedDisplay *UNUSED(display))
|
||||
{
|
||||
}
|
||||
|
||||
bool IMB_colormanagement_space_is_scene_linear(struct ColorSpace *colorspace)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IMB_colormanagement_space_is_data(struct ColorSpace *colorspace)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void BKE_material_defaults_free_gpu(void) {}
|
||||
|
||||
/* Variables. */
|
||||
int G;
|
||||
|
||||
/* Functions which aren't called. */
|
||||
void *BKE_image_free_buffers = NULL;
|
||||
void *BKE_image_get_tile = NULL;
|
||||
void *BKE_image_get_tile_from_iuser = NULL;
|
||||
void *BKE_tempdir_session = NULL;
|
||||
void *DRW_deferred_shader_remove = NULL;
|
||||
void *datatoc_common_view_lib_glsl = NULL;
|
||||
void *ntreeFreeLocalTree = NULL;
|
||||
void *ntreeGPUMaterialNodes = NULL;
|
||||
void *ntreeLocalize = NULL;
|
||||
|
|
@ -170,7 +170,7 @@ struct WindowRuntime {
|
|||
wmEvent *eventstate = nullptr;
|
||||
|
||||
/**
|
||||
* The time when the key is pressed in milliseconds (see #GHOST_GetEventTime).
|
||||
* The time when the key is pressed in milliseconds (see #GHOST_IEvent::getTime).
|
||||
* Used to detect double-click events.
|
||||
*/
|
||||
uint64_t eventstate_prev_press_time_ms = 0;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
#include "BLT_translation.hh"
|
||||
|
||||
#include "GHOST_Path-api.hh"
|
||||
#include "GHOST_ISystemPaths.hh"
|
||||
|
||||
#include "CLG_log.h"
|
||||
|
||||
|
|
@ -106,7 +106,7 @@ void BKE_appdir_exit()
|
|||
* disposed of here. Note that there may be several calls to this in `exit` process
|
||||
* (e.g. `wm_init/wm_exit` will currently both call GHOST API directly,
|
||||
* & `BKE_appdir_init/_exit`). */
|
||||
GHOST_DisposeSystemPaths();
|
||||
GHOST_ISystemPaths::dispose();
|
||||
#ifndef NDEBUG
|
||||
BLI_assert(is_appdir_init == true);
|
||||
is_appdir_init = false;
|
||||
|
|
@ -175,7 +175,8 @@ bool BKE_appdir_folder_documents(char *dir)
|
|||
{
|
||||
dir[0] = '\0';
|
||||
|
||||
const std::optional<std::string> documents_path = GHOST_getUserSpecialDir(
|
||||
const GHOST_ISystemPaths *ghost_system_paths = GHOST_ISystemPaths::get();
|
||||
const std::optional<std::string> documents_path = ghost_system_paths->getUserSpecialDir(
|
||||
GHOST_kUserSpecialDirDocuments);
|
||||
|
||||
/* Usual case: Ghost gave us the documents path. We're done here. */
|
||||
|
|
@ -206,7 +207,8 @@ bool BKE_appdir_folder_caches(char *path, const size_t path_maxncpy)
|
|||
{
|
||||
path[0] = '\0';
|
||||
|
||||
std::optional<std::string> caches_root_path = GHOST_getUserSpecialDir(
|
||||
const GHOST_ISystemPaths *ghost_system_paths = GHOST_ISystemPaths::get();
|
||||
std::optional<std::string> caches_root_path = ghost_system_paths->getUserSpecialDir(
|
||||
GHOST_kUserSpecialDirCaches);
|
||||
if (!caches_root_path || !BLI_is_dir(caches_root_path->c_str())) {
|
||||
caches_root_path = BKE_tempdir_base();
|
||||
|
|
@ -514,7 +516,9 @@ static bool get_path_user_ex(char *targetpath,
|
|||
else {
|
||||
user_path[0] = '\0';
|
||||
|
||||
const char *user_base_path = GHOST_getUserDir(version, blender_version_decimal(version));
|
||||
const GHOST_ISystemPaths *ghost_system_paths = GHOST_ISystemPaths::get();
|
||||
const char *user_base_path = ghost_system_paths->getUserDir(version,
|
||||
blender_version_decimal(version));
|
||||
if (user_base_path) {
|
||||
STRNCPY(user_path, user_base_path);
|
||||
}
|
||||
|
|
@ -569,7 +573,9 @@ static bool get_path_system_ex(char *targetpath,
|
|||
}
|
||||
else {
|
||||
system_path[0] = '\0';
|
||||
const char *system_base_path = GHOST_getSystemDir(version, blender_version_decimal(version));
|
||||
const GHOST_ISystemPaths *ghost_system_paths = GHOST_ISystemPaths::get();
|
||||
const char *system_base_path = ghost_system_paths->getSystemDir(
|
||||
version, blender_version_decimal(version));
|
||||
if (system_base_path) {
|
||||
STRNCPY(system_path, system_base_path);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#include "CLG_log.h"
|
||||
|
||||
#include "GHOST_Path-api.hh"
|
||||
#include "GHOST_ISystemPaths.hh"
|
||||
|
||||
#include "BKE_appdir.hh"
|
||||
#include "BKE_global.hh"
|
||||
|
|
@ -82,7 +82,7 @@ class ImagePartialUpdateTest : public testing::Test {
|
|||
|
||||
IMB_moviecache_destruct();
|
||||
IMB_exit();
|
||||
GHOST_DisposeSystemPaths();
|
||||
GHOST_ISystemPaths::dispose();
|
||||
BKE_appdir_exit();
|
||||
CLG_exit();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include "CLG_log.h"
|
||||
|
||||
#include "GHOST_Path-api.hh"
|
||||
#include "GHOST_ISystemPaths.hh"
|
||||
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
|
|
@ -89,7 +89,7 @@ class LibQueryTest : public ::testing::Test {
|
|||
RNA_exit();
|
||||
IMB_exit();
|
||||
BKE_appdir_exit();
|
||||
GHOST_DisposeSystemPaths();
|
||||
GHOST_ISystemPaths::dispose();
|
||||
CLG_exit();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include "CLG_log.h"
|
||||
|
||||
#include "GHOST_Path-api.hh"
|
||||
#include "GHOST_ISystemPaths.hh"
|
||||
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
|
|
@ -90,7 +90,7 @@ class LibRemapTest : public ::testing::Test {
|
|||
RNA_exit();
|
||||
IMB_exit();
|
||||
BKE_appdir_exit();
|
||||
GHOST_DisposeSystemPaths();
|
||||
GHOST_ISystemPaths::dispose();
|
||||
CLG_exit();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "BLI_string_ref.hh"
|
||||
struct DRWInstanceDataList;
|
||||
class GHOST_IContext;
|
||||
|
||||
namespace blender {
|
||||
|
||||
|
|
@ -162,7 +163,7 @@ void DRW_gpu_context_disable();
|
|||
|
||||
#ifdef WITH_XR_OPENXR
|
||||
/* XXX: see comment on #DRW_system_gpu_context_get() */
|
||||
void *DRW_system_gpu_context_get();
|
||||
GHOST_IContext *DRW_system_gpu_context_get();
|
||||
void *DRW_xr_blender_gpu_context_get();
|
||||
void DRW_xr_drawing_begin();
|
||||
void DRW_xr_drawing_end();
|
||||
|
|
@ -186,8 +187,8 @@ void DRW_gpu_context_disable_ex(bool restore);
|
|||
* Enable system context first, then enable blender context,
|
||||
* then disable blender context, then disable system context. */
|
||||
|
||||
void DRW_system_gpu_render_context_enable(void *re_system_gpu_context);
|
||||
void DRW_system_gpu_render_context_disable(void *re_system_gpu_context);
|
||||
void DRW_system_gpu_render_context_enable(GHOST_IContext *re_system_gpu_context);
|
||||
void DRW_system_gpu_render_context_disable(GHOST_IContext *re_system_gpu_context);
|
||||
void DRW_blender_gpu_render_context_enable(void *re_gpu_context);
|
||||
void DRW_blender_gpu_render_context_disable(void *re_gpu_context);
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ class LightBake {
|
|||
* If running in parallel (in a separate thread), use this context.
|
||||
* Created on main thread but first bound in worker thread.
|
||||
*/
|
||||
void *gl_context_ = nullptr;
|
||||
GHOST_IContext *gl_context_ = nullptr;
|
||||
/** Context associated to `gl_context_`. Created in the worker thread. */
|
||||
GPUContext *gpu_context_ = nullptr;
|
||||
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ class ContextShared {
|
|||
public:
|
||||
TicketMutex *mutex_ = nullptr;
|
||||
/** Unique ghost context used by Viewports. */
|
||||
void *system_gpu_context_ = nullptr;
|
||||
GHOST_IContext *system_gpu_context_ = nullptr;
|
||||
/** GPUContext associated to the system_gpu_context. */
|
||||
GPUContext *blender_gpu_context_ = nullptr;
|
||||
|
||||
|
|
@ -256,7 +256,7 @@ void DRW_gpu_context_disable()
|
|||
DRW_gpu_context_disable_ex(true);
|
||||
}
|
||||
|
||||
void DRW_system_gpu_render_context_enable(void *re_system_gpu_context)
|
||||
void DRW_system_gpu_render_context_enable(GHOST_IContext *re_system_gpu_context)
|
||||
{
|
||||
/* If thread is main you should use DRW_gpu_context_enable(). */
|
||||
BLI_assert(!BLI_thread_is_main());
|
||||
|
|
@ -265,7 +265,7 @@ void DRW_system_gpu_render_context_enable(void *re_system_gpu_context)
|
|||
WM_system_gpu_context_activate(re_system_gpu_context);
|
||||
}
|
||||
|
||||
void DRW_system_gpu_render_context_disable(void *re_system_gpu_context)
|
||||
void DRW_system_gpu_render_context_disable(GHOST_IContext *re_system_gpu_context)
|
||||
{
|
||||
WM_system_gpu_context_release(re_system_gpu_context);
|
||||
DRW_lock_end();
|
||||
|
|
@ -299,7 +299,7 @@ void DRW_render_context_enable(Render *render)
|
|||
return;
|
||||
}
|
||||
|
||||
void *re_viewport_system_gpu_context = RE_system_gpu_context_get(render);
|
||||
GHOST_IContext *re_viewport_system_gpu_context = RE_system_gpu_context_get(render);
|
||||
|
||||
/* Changing Context */
|
||||
if (re_viewport_system_gpu_context != nullptr) {
|
||||
|
|
@ -322,7 +322,7 @@ void DRW_render_context_disable(Render *render)
|
|||
return;
|
||||
}
|
||||
|
||||
void *re_viewport_system_gpu_context = RE_system_gpu_context_get(render);
|
||||
GHOST_IContext *re_viewport_system_gpu_context = RE_system_gpu_context_get(render);
|
||||
|
||||
if (re_viewport_system_gpu_context != nullptr) {
|
||||
void *re_viewport_context = RE_blender_gpu_context_ensure(render);
|
||||
|
|
@ -347,7 +347,7 @@ void DRW_render_context_disable(Render *render)
|
|||
|
||||
#ifdef WITH_XR_OPENXR
|
||||
|
||||
void *DRW_system_gpu_context_get()
|
||||
GHOST_IContext *DRW_system_gpu_context_get()
|
||||
{
|
||||
/* XXX: There should really be no such getter, but for VR we currently can't easily avoid it.
|
||||
* OpenXR needs some low level info for the GPU context that will be used for submitting the
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
|
||||
#include "BLT_translation.hh"
|
||||
|
||||
#include "GHOST_C-api.h"
|
||||
#include "GHOST_ISystem.hh"
|
||||
|
||||
#include "IMB_colormanagement.hh"
|
||||
|
||||
|
|
@ -3624,7 +3624,8 @@ static void ui_textedit_begin(bContext *C, Button *but, HandleButtonData *data)
|
|||
WM_cursor_modal_set(win, WM_CURSOR_TEXT_EDIT);
|
||||
|
||||
/* Temporarily turn off window auto-focus on platforms that support it. */
|
||||
GHOST_SetAutoFocus(false);
|
||||
GHOST_ISystem *ghost_system = GHOST_ISystem::getSystem();
|
||||
ghost_system->setAutoFocus(false);
|
||||
|
||||
#ifdef WITH_INPUT_IME
|
||||
if (!is_num_but) {
|
||||
|
|
@ -3689,7 +3690,8 @@ static void ui_textedit_end(bContext *C, Button *but, HandleButtonData *data)
|
|||
WM_cursor_modal_restore(win);
|
||||
|
||||
/* Turn back on the auto-focusing of windows. */
|
||||
GHOST_SetAutoFocus(true);
|
||||
GHOST_ISystem *ghost_system = GHOST_ISystem::getSystem();
|
||||
ghost_system->setAutoFocus(true);
|
||||
|
||||
/* Free text undo history text blocks. */
|
||||
textedit_undo_stack_destroy(text_edit.undo_stack_text);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,10 @@
|
|||
|
||||
#include "GPU_platform.hh"
|
||||
|
||||
class GHOST_IContext;
|
||||
class GHOST_ISystem;
|
||||
class GHOST_IWindow;
|
||||
|
||||
namespace blender {
|
||||
|
||||
struct GPUContext;
|
||||
|
|
@ -63,7 +67,7 @@ void GPU_backend_vsync_set_override(int vsync);
|
|||
bool GPU_backend_vsync_is_overridden();
|
||||
|
||||
/** Opaque type hiding gpu::Context. */
|
||||
GPUContext *GPU_context_create(void *ghost_window, void *ghost_context);
|
||||
GPUContext *GPU_context_create(GHOST_IWindow *ghost_window, GHOST_IContext *ghost_context);
|
||||
/**
|
||||
* To be called after #GPU_context_active_set(ctx_to_destroy).
|
||||
*/
|
||||
|
|
@ -120,8 +124,8 @@ void GPU_render_end();
|
|||
void GPU_render_step(bool force_resource_release = false);
|
||||
|
||||
/** For when we need access to a system context in order to create a GPU context. */
|
||||
void GPU_backend_ghost_system_set(void *ghost_system_handle);
|
||||
void *GPU_backend_ghost_system_get();
|
||||
void GPU_backend_ghost_system_set(GHOST_ISystem *ghost_system_handle);
|
||||
GHOST_ISystem *GPU_backend_ghost_system_get();
|
||||
|
||||
namespace gpu {
|
||||
|
||||
|
|
@ -132,7 +136,7 @@ namespace gpu {
|
|||
*/
|
||||
class GPUSecondaryContext {
|
||||
private:
|
||||
void *ghost_context_;
|
||||
GHOST_IContext *ghost_context_;
|
||||
GPUContext *gpu_context_;
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ class DummyBackend : public GPUBackend {
|
|||
{
|
||||
}
|
||||
void compute_dispatch_indirect(StorageBuf * /*indirect_buf*/) override {}
|
||||
Context *context_alloc(void * /*ghost_window*/, void * /*ghost_context*/) override
|
||||
Context *context_alloc(GHOST_IWindow * /*ghost_window*/,
|
||||
GHOST_IContext * /*ghost_context*/) override
|
||||
{
|
||||
return new DummyContext;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,10 @@
|
|||
|
||||
#include "BLI_color_types.hh"
|
||||
#include "BLI_string_ref.hh"
|
||||
|
||||
#include "GHOST_IContext.hh"
|
||||
#include "GHOST_IWindow.hh"
|
||||
|
||||
#include "GPU_vertex_buffer.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
|
|
@ -55,7 +59,7 @@ class GPUBackend {
|
|||
virtual void compute_dispatch(int groups_x_len, int groups_y_len, int groups_z_len) = 0;
|
||||
virtual void compute_dispatch_indirect(StorageBuf *indirect_buf) = 0;
|
||||
|
||||
virtual Context *context_alloc(void *ghost_window, void *ghost_context) = 0;
|
||||
virtual Context *context_alloc(GHOST_IWindow *ghost_window, GHOST_IContext *ghost_context) = 0;
|
||||
|
||||
virtual Batch *batch_alloc() = 0;
|
||||
virtual Fence *fence_alloc() = 0;
|
||||
|
|
|
|||
|
|
@ -21,8 +21,9 @@
|
|||
|
||||
#include "DNA_userdef_types.h"
|
||||
|
||||
#include "GHOST_C-api.h"
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_IContext.hh"
|
||||
#include "GHOST_ISystem.hh"
|
||||
#include "GHOST_Types.hh"
|
||||
|
||||
#include "GPU_context.hh"
|
||||
|
||||
|
|
@ -189,7 +190,7 @@ Batch *Context::procedural_triangle_strips_batch_get()
|
|||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
GPUContext *GPU_context_create(void *ghost_window, void *ghost_context)
|
||||
GPUContext *GPU_context_create(GHOST_IWindow *ghost_window, GHOST_IContext *ghost_context)
|
||||
{
|
||||
{
|
||||
std::scoped_lock lock(backend_users_mutex);
|
||||
|
|
@ -359,14 +360,14 @@ static std::optional<GPUBackendType> g_backend_type_override = std::nullopt;
|
|||
static std::optional<bool> g_backend_type_supported = std::nullopt;
|
||||
static std::optional<int> g_vsync_override = std::nullopt;
|
||||
static GPUBackend *g_backend = nullptr;
|
||||
static GHOST_SystemHandle g_ghost_system = nullptr;
|
||||
static GHOST_ISystem *g_ghost_system = nullptr;
|
||||
|
||||
void GPU_backend_ghost_system_set(void *ghost_system_handle)
|
||||
void GPU_backend_ghost_system_set(GHOST_ISystem *ghost_system_handle)
|
||||
{
|
||||
g_ghost_system = reinterpret_cast<GHOST_SystemHandle>(ghost_system_handle);
|
||||
g_ghost_system = ghost_system_handle;
|
||||
}
|
||||
|
||||
void *GPU_backend_ghost_system_get()
|
||||
GHOST_ISystem *GPU_backend_ghost_system_get()
|
||||
{
|
||||
return g_ghost_system;
|
||||
}
|
||||
|
|
@ -600,7 +601,7 @@ GPUSecondaryContext::GPUSecondaryContext()
|
|||
/* Contexts can only be created on the main thread. */
|
||||
BLI_assert(BLI_thread_is_main());
|
||||
|
||||
GHOST_ContextHandle main_thread_ghost_context = GHOST_GetActiveGPUContext();
|
||||
GHOST_IContext *main_thread_ghost_context = GHOST_IContext::getActiveDrawingContext();
|
||||
GPUContext *main_thread_gpu_context = GPU_context_active_get();
|
||||
|
||||
/* GPU settings for context creation. */
|
||||
|
|
@ -614,30 +615,28 @@ GPUSecondaryContext::GPUSecondaryContext()
|
|||
gpu_settings.preferred_device.device_id = U.gpu_preferred_device_id;
|
||||
|
||||
/* Grab the system handle. */
|
||||
GHOST_SystemHandle ghost_system = reinterpret_cast<GHOST_SystemHandle>(
|
||||
GPU_backend_ghost_system_get());
|
||||
GHOST_ISystem *ghost_system = GPU_backend_ghost_system_get();
|
||||
BLI_assert(ghost_system);
|
||||
|
||||
/* Create a Ghost GPU Context using the system handle. */
|
||||
ghost_context_ = GHOST_CreateGPUContext(ghost_system, gpu_settings);
|
||||
ghost_context_ = ghost_system->createOffscreenContext(gpu_settings);
|
||||
BLI_assert(ghost_context_);
|
||||
|
||||
/* Activate it so GPU_context_create has a valid device for info queries. */
|
||||
GHOST_ActivateGPUContext(reinterpret_cast<GHOST_ContextHandle>(ghost_context_));
|
||||
ghost_context_->activateDrawingContext();
|
||||
|
||||
/* Create a GPU context for the secondary thread to use. */
|
||||
gpu_context_ = GPU_context_create(nullptr, ghost_context_);
|
||||
BLI_assert(gpu_context_);
|
||||
|
||||
/* Release the Ghost GPU Context from this thread. */
|
||||
GHOST_TSuccess success = GHOST_ReleaseGPUContext(
|
||||
reinterpret_cast<GHOST_ContextHandle>(ghost_context_));
|
||||
const GHOST_TSuccess success = ghost_context_->releaseDrawingContext();
|
||||
BLI_assert(success);
|
||||
UNUSED_VARS_NDEBUG(success);
|
||||
|
||||
/* Restore the main thread contexts.
|
||||
* (required as the above context creation also makes it active). */
|
||||
GHOST_ActivateGPUContext(main_thread_ghost_context);
|
||||
main_thread_ghost_context->activateDrawingContext();
|
||||
GPU_context_active_set(main_thread_gpu_context);
|
||||
}
|
||||
|
||||
|
|
@ -648,12 +647,11 @@ GPUSecondaryContext::~GPUSecondaryContext()
|
|||
|
||||
GPU_context_discard(gpu_context_);
|
||||
|
||||
GHOST_ReleaseGPUContext(reinterpret_cast<GHOST_ContextHandle>(ghost_context_));
|
||||
ghost_context_->releaseDrawingContext();
|
||||
|
||||
GHOST_SystemHandle ghost_system = reinterpret_cast<GHOST_SystemHandle>(
|
||||
GPU_backend_ghost_system_get());
|
||||
GHOST_ISystem *ghost_system = GPU_backend_ghost_system_get();
|
||||
BLI_assert(ghost_system);
|
||||
GHOST_DisposeGPUContext(ghost_system, reinterpret_cast<GHOST_ContextHandle>(ghost_context_));
|
||||
ghost_system->disposeContext(ghost_context_);
|
||||
}
|
||||
|
||||
void GPUSecondaryContext::activate()
|
||||
|
|
@ -661,7 +659,7 @@ void GPUSecondaryContext::activate()
|
|||
/* Contexts need to be activated in the thread they're going to be used. */
|
||||
BLI_assert(!BLI_thread_is_main());
|
||||
|
||||
GHOST_ActivateGPUContext(reinterpret_cast<GHOST_ContextHandle>(ghost_context_));
|
||||
ghost_context_->activateDrawingContext();
|
||||
GPU_context_active_set(gpu_context_);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@
|
|||
|
||||
#include <pthread.h>
|
||||
|
||||
class GHOST_IWindow;
|
||||
|
||||
namespace blender {
|
||||
|
||||
struct GPUMatrixState;
|
||||
|
|
@ -85,8 +87,8 @@ class Context {
|
|||
/** Thread on which this context is active. */
|
||||
pthread_t thread_;
|
||||
bool is_active_;
|
||||
/** Avoid including GHOST headers. Can be nullptr for off-screen contexts. */
|
||||
void *ghost_window_;
|
||||
/** Can be nullptr for off-screen contexts. */
|
||||
GHOST_IWindow *ghost_window_;
|
||||
|
||||
public:
|
||||
Context();
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ class MTLBackend : public GPUBackend {
|
|||
|
||||
/* MTL Allocators need to be implemented in separate `.mm` files,
|
||||
* due to allocation of Objective-C objects. */
|
||||
Context *context_alloc(void *ghost_window, void *ghost_context) override;
|
||||
Context *context_alloc(GHOST_IWindow *ghost_window, GHOST_IContext *ghost_context) override;
|
||||
Batch *batch_alloc() override;
|
||||
Fence *fence_alloc() override;
|
||||
FrameBuffer *framebuffer_alloc(const char *name) override;
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ void MTLBackend::samplers_update() {
|
|||
/* Placeholder -- Handled in MTLContext. */
|
||||
};
|
||||
|
||||
Context *MTLBackend::context_alloc(void *ghost_window, void *ghost_context)
|
||||
Context *MTLBackend::context_alloc(GHOST_IWindow *ghost_window, GHOST_IContext *ghost_context)
|
||||
{
|
||||
return new MTLContext(ghost_window, ghost_context);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
#include "intern/GHOST_Context.hh"
|
||||
#include "intern/GHOST_ContextMTL.hh"
|
||||
#include "intern/GHOST_Window.hh"
|
||||
|
|
@ -706,7 +706,7 @@ class MTLContext : public Context {
|
|||
|
||||
public:
|
||||
/* GPUContext interface. */
|
||||
MTLContext(void *ghost_window, void *ghost_context);
|
||||
MTLContext(GHOST_IWindow *ghost_window, GHOST_IContext *ghost_context);
|
||||
~MTLContext();
|
||||
|
||||
static void check_error(const char *info);
|
||||
|
|
@ -916,8 +916,8 @@ class MTLContext : public Context {
|
|||
}
|
||||
|
||||
private:
|
||||
void set_ghost_context(GHOST_ContextHandle ghostCtxHandle);
|
||||
void set_ghost_window(GHOST_WindowHandle ghostWinHandle);
|
||||
void set_ghost_context(GHOST_IContext *ghostCtxHandle);
|
||||
void set_ghost_window(GHOST_IWindow *ghostWinHandle);
|
||||
};
|
||||
|
||||
/* GHOST Context callbacks. */
|
||||
|
|
|
|||
|
|
@ -77,9 +77,9 @@ int64_t MTLContext::frame_latency[MTL_FRAME_AVERAGE_COUNT] = {0};
|
|||
/** \name GHOST Context interaction.
|
||||
* \{ */
|
||||
|
||||
void MTLContext::set_ghost_context(GHOST_ContextHandle ghostCtxHandle)
|
||||
void MTLContext::set_ghost_context(GHOST_IContext *ghostCtxHandle)
|
||||
{
|
||||
GHOST_Context *ghost_ctx = reinterpret_cast<GHOST_Context *>(ghostCtxHandle);
|
||||
GHOST_Context *ghost_ctx = static_cast<GHOST_Context *>(ghostCtxHandle);
|
||||
BLI_assert(ghost_ctx != nullptr);
|
||||
|
||||
/* Release old MTLTexture handle */
|
||||
|
|
@ -167,10 +167,10 @@ void MTLContext::set_ghost_context(GHOST_ContextHandle ghostCtxHandle)
|
|||
}
|
||||
}
|
||||
|
||||
void MTLContext::set_ghost_window(GHOST_WindowHandle ghostWinHandle)
|
||||
void MTLContext::set_ghost_window(GHOST_IWindow *ghostWinHandle)
|
||||
{
|
||||
GHOST_Window *ghostWin = reinterpret_cast<GHOST_Window *>(ghostWinHandle);
|
||||
this->set_ghost_context((GHOST_ContextHandle)(ghostWin ? ghostWin->getContext() : nullptr));
|
||||
GHOST_Window *ghostWin = static_cast<GHOST_Window *>(ghostWinHandle);
|
||||
this->set_ghost_context(ghostWin ? ghostWin->getContext() : nullptr);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
@ -180,7 +180,7 @@ void MTLContext::set_ghost_window(GHOST_WindowHandle ghostWinHandle)
|
|||
* \{ */
|
||||
|
||||
/* Placeholder functions */
|
||||
MTLContext::MTLContext(void *ghost_window, void *ghost_context)
|
||||
MTLContext::MTLContext(GHOST_IWindow *ghost_window, GHOST_IContext *ghost_context)
|
||||
: memory_manager(*this), main_command_buffer(*this)
|
||||
{
|
||||
/* Init debug. */
|
||||
|
|
@ -412,10 +412,10 @@ void MTLContext::activate()
|
|||
|
||||
/* Re-apply ghost window/context for resizing */
|
||||
if (ghost_window_) {
|
||||
this->set_ghost_window((GHOST_WindowHandle)ghost_window_);
|
||||
this->set_ghost_window(ghost_window_);
|
||||
}
|
||||
else if (ghost_context_) {
|
||||
this->set_ghost_context((GHOST_ContextHandle)ghost_context_);
|
||||
this->set_ghost_context(ghost_context_);
|
||||
}
|
||||
|
||||
/* Reset UBO bind state. */
|
||||
|
|
|
|||
|
|
@ -40,8 +40,6 @@
|
|||
#include "mtl_texture.hh"
|
||||
#include "mtl_vertex_buffer.hh"
|
||||
|
||||
#include "GHOST_C-api.h"
|
||||
|
||||
using namespace blender::gpu;
|
||||
using namespace blender::gpu::shader;
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,6 @@
|
|||
#include "mtl_texture.hh"
|
||||
#include "mtl_vertex_buffer.hh"
|
||||
|
||||
#include "GHOST_C-api.h"
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ class GLBackend : public GPUBackend {
|
|||
GLTexture::samplers_update();
|
||||
};
|
||||
|
||||
Context *context_alloc(void *ghost_window, void * /*ghost_context*/) override
|
||||
Context *context_alloc(GHOST_IWindow *ghost_window, GHOST_IContext * /*ghost_context*/) override
|
||||
{
|
||||
return new GLContext(ghost_window, shared_orphan_list_);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@
|
|||
# include "BLI_string.h"
|
||||
# include "BLI_threads.h"
|
||||
# include "CLG_log.h"
|
||||
# include "GHOST_C-api.h"
|
||||
# include "GHOST_IContext.hh"
|
||||
# include "GHOST_ISystem.hh"
|
||||
# include "GPU_context.hh"
|
||||
# include "GPU_init_exit.hh"
|
||||
# include "gpu_capabilities_private.hh"
|
||||
|
|
@ -173,19 +174,20 @@ void GPU_compilation_subprocess_run(const char *subprocess_name)
|
|||
SharedSemaphore end_semaphore(name + "_END", true);
|
||||
SharedSemaphore close_semaphore(name + "_CLOSE", true);
|
||||
|
||||
GHOST_SystemHandle ghost_system = GHOST_CreateSystemBackground();
|
||||
GHOST_ISystem::createSystemBackground();
|
||||
GHOST_ISystem *ghost_system = GHOST_ISystem::getSystem();
|
||||
BLI_assert(ghost_system);
|
||||
GPU_backend_ghost_system_set(ghost_system);
|
||||
GHOST_GPUSettings gpu_settings = {0};
|
||||
gpu_settings.context_type = GHOST_kDrawingContextTypeOpenGL;
|
||||
GHOST_ContextHandle ghost_context = GHOST_CreateGPUContext(ghost_system, gpu_settings);
|
||||
GHOST_IContext *ghost_context = ghost_system->createOffscreenContext(gpu_settings);
|
||||
if (ghost_context == nullptr) {
|
||||
std::cerr << "Compilation Subprocess: Failed to initialize GHOST context for "
|
||||
<< subprocess_name << "\n";
|
||||
GHOST_DisposeSystem(ghost_system);
|
||||
GHOST_ISystem::disposeSystem();
|
||||
return;
|
||||
}
|
||||
GHOST_ActivateGPUContext(ghost_context);
|
||||
ghost_context->activateDrawingContext();
|
||||
GPUContext *gpu_context = GPU_context_create(nullptr, ghost_context);
|
||||
GPU_init();
|
||||
|
||||
|
|
@ -194,7 +196,7 @@ void GPU_compilation_subprocess_run(const char *subprocess_name)
|
|||
while (true) {
|
||||
/* Process events to avoid crashes on Wayland.
|
||||
* See https://bugreports.qt.io/browse/QTBUG-81504 */
|
||||
GHOST_ProcessEvents(ghost_system, false);
|
||||
ghost_system->processEvents(false);
|
||||
|
||||
# ifdef _WIN32
|
||||
start_semaphore.decrement();
|
||||
|
|
@ -303,8 +305,8 @@ void GPU_compilation_subprocess_run(const char *subprocess_name)
|
|||
|
||||
GPU_exit();
|
||||
GPU_context_discard(gpu_context);
|
||||
GHOST_DisposeGPUContext(ghost_system, ghost_context);
|
||||
GHOST_DisposeSystem(ghost_system);
|
||||
ghost_system->disposeContext(ghost_context);
|
||||
GHOST_ISystem::disposeSystem();
|
||||
}
|
||||
|
||||
namespace gpu {
|
||||
|
|
|
|||
|
|
@ -13,8 +13,6 @@
|
|||
|
||||
#include "GPU_framebuffer.hh"
|
||||
|
||||
#include "GHOST_C-api.h"
|
||||
|
||||
#include "gpu_context_private.hh"
|
||||
#include "gpu_immediate_private.hh"
|
||||
|
||||
|
|
@ -34,7 +32,7 @@ using namespace blender::gpu;
|
|||
/** \name Constructor / Destructor
|
||||
* \{ */
|
||||
|
||||
GLContext::GLContext(void *ghost_window, GLSharedOrphanLists &shared_orphan_list)
|
||||
GLContext::GLContext(GHOST_IWindow *ghost_window, GLSharedOrphanLists &shared_orphan_list)
|
||||
: shared_orphan_list_(shared_orphan_list)
|
||||
{
|
||||
if (G.debug & G_DEBUG_GPU) {
|
||||
|
|
@ -52,13 +50,12 @@ GLContext::GLContext(void *ghost_window, GLSharedOrphanLists &shared_orphan_list
|
|||
ghost_window_ = ghost_window;
|
||||
|
||||
if (ghost_window) {
|
||||
GLuint default_fbo = GHOST_GetDefaultGPUFramebuffer(
|
||||
static_cast<GHOST_WindowHandle>(ghost_window));
|
||||
GHOST_RectangleHandle bounds = GHOST_GetClientBounds(
|
||||
static_cast<GHOST_WindowHandle>(ghost_window));
|
||||
int w = GHOST_GetWidthRectangle(bounds);
|
||||
int h = GHOST_GetHeightRectangle(bounds);
|
||||
GHOST_DisposeRectangle(bounds);
|
||||
GLuint default_fbo = ghost_window->getDefaultFramebuffer();
|
||||
|
||||
GHOST_Rect bounds;
|
||||
ghost_window->getClientBounds(bounds);
|
||||
const int w = bounds.getWidth();
|
||||
const int h = bounds.getHeight();
|
||||
|
||||
if (default_fbo != 0) {
|
||||
/* Bind default framebuffer, otherwise state might be undefined. */
|
||||
|
|
@ -126,11 +123,11 @@ void GLContext::activate()
|
|||
|
||||
if (ghost_window_) {
|
||||
/* Get the correct framebuffer size for the internal framebuffers. */
|
||||
GHOST_RectangleHandle bounds = GHOST_GetClientBounds(
|
||||
static_cast<GHOST_WindowHandle>(ghost_window_));
|
||||
int w = GHOST_GetWidthRectangle(bounds);
|
||||
int h = GHOST_GetHeightRectangle(bounds);
|
||||
GHOST_DisposeRectangle(bounds);
|
||||
GHOST_Rect bounds = {0};
|
||||
ghost_window_->getClientBounds(bounds);
|
||||
|
||||
const int w = bounds.getWidth();
|
||||
const int h = bounds.getHeight();
|
||||
|
||||
if (front_left) {
|
||||
front_left->size_set(w, h);
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ class GLContext : public Context {
|
|||
void process_frame_timings();
|
||||
|
||||
public:
|
||||
GLContext(void *ghost_window, GLSharedOrphanLists &shared_orphan_list);
|
||||
GLContext(GHOST_IWindow *ghost_window, GLSharedOrphanLists &shared_orphan_list);
|
||||
~GLContext();
|
||||
|
||||
static void check_error(const char *info);
|
||||
|
|
|
|||
|
|
@ -15,13 +15,14 @@
|
|||
|
||||
#include "gpu_testing.hh"
|
||||
|
||||
#include "GHOST_C-api.h"
|
||||
#include "GHOST_Path-api.hh"
|
||||
#include "GHOST_ISystem.hh"
|
||||
#include "GHOST_ISystemPaths.hh"
|
||||
#include "GHOST_Types.hh"
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
GHOST_SystemHandle GPUTest::ghost_system_;
|
||||
GHOST_ContextHandle GPUTest::ghost_context_;
|
||||
GHOST_ISystem *GPUTest::ghost_system_;
|
||||
GHOST_IContext *GPUTest::ghost_context_;
|
||||
GPUContext *GPUTest::context_;
|
||||
|
||||
int32_t GPUTest::prev_g_debug_;
|
||||
|
|
@ -42,10 +43,11 @@ void GPUTest::SetUpTestSuite(GHOST_TDrawingContextType draw_context_type,
|
|||
GHOST_GPUSettings gpu_settings = {};
|
||||
gpu_settings.context_type = draw_context_type;
|
||||
gpu_settings.flags = GHOST_gpuDebugContext;
|
||||
ghost_system_ = GHOST_CreateSystemBackground();
|
||||
GHOST_ISystem::createSystemBackground();
|
||||
ghost_system_ = GHOST_ISystem::getSystem();
|
||||
GPU_backend_ghost_system_set(ghost_system_);
|
||||
ghost_context_ = GHOST_CreateGPUContext(ghost_system_, gpu_settings);
|
||||
GHOST_ActivateGPUContext(ghost_context_);
|
||||
ghost_context_ = ghost_system_->createOffscreenContext(gpu_settings);
|
||||
ghost_context_->activateDrawingContext();
|
||||
context_ = GPU_context_create(nullptr, ghost_context_);
|
||||
GPU_init();
|
||||
|
||||
|
|
@ -64,9 +66,9 @@ void GPUTest::TearDownTestSuite()
|
|||
|
||||
GPU_exit();
|
||||
GPU_context_discard(context_);
|
||||
GHOST_DisposeGPUContext(ghost_system_, ghost_context_);
|
||||
GHOST_DisposeSystem(ghost_system_);
|
||||
GHOST_DisposeSystemPaths();
|
||||
ghost_system_->disposeContext(ghost_context_);
|
||||
GHOST_ISystem::disposeSystem();
|
||||
GHOST_ISystemPaths::dispose();
|
||||
CLG_exit();
|
||||
|
||||
G.debug = prev_g_debug_;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@
|
|||
|
||||
#include "BKE_global.hh"
|
||||
|
||||
#include "GHOST_C-api.h"
|
||||
#include "GHOST_IContext.hh"
|
||||
#include "GHOST_ISystem.hh"
|
||||
|
||||
#include "GPU_platform.hh"
|
||||
|
||||
|
|
@ -19,8 +20,8 @@ namespace blender::gpu {
|
|||
*/
|
||||
class GPUTest : public ::testing::Test {
|
||||
private:
|
||||
static GHOST_SystemHandle ghost_system_;
|
||||
static GHOST_ContextHandle ghost_context_;
|
||||
static GHOST_ISystem *ghost_system_;
|
||||
static GHOST_IContext *ghost_context_;
|
||||
static GPUContext *context_;
|
||||
|
||||
static int32_t prev_g_debug_;
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@
|
|||
|
||||
#include <sstream>
|
||||
|
||||
#include "GHOST_C-api.h"
|
||||
|
||||
#include "BLI_path_utils.hh"
|
||||
#include "BLI_threads.h"
|
||||
|
||||
|
|
@ -337,10 +335,10 @@ void VKBackend::platform_init()
|
|||
GPU_ARCHITECTURE_IMR);
|
||||
}
|
||||
|
||||
static void init_device_list(GHOST_ContextHandle ghost_context)
|
||||
static void init_device_list(GHOST_IContext *ghost_context)
|
||||
{
|
||||
GHOST_VulkanHandles vulkan_handles = {};
|
||||
GHOST_GetVulkanHandles(ghost_context, &vulkan_handles);
|
||||
ghost_context->getVulkanHandles(vulkan_handles);
|
||||
|
||||
uint32_t physical_devices_count = 0;
|
||||
vkEnumeratePhysicalDevices(vulkan_handles.instance, &physical_devices_count, nullptr);
|
||||
|
|
@ -598,11 +596,11 @@ void VKBackend::compute_dispatch_indirect(StorageBuf *indirect_buf)
|
|||
context.render_graph().add_node(dispatch_indirect_info);
|
||||
}
|
||||
|
||||
Context *VKBackend::context_alloc(void *ghost_window, void *ghost_context)
|
||||
Context *VKBackend::context_alloc(GHOST_IWindow *ghost_window, GHOST_IContext *ghost_context)
|
||||
{
|
||||
if (ghost_window) {
|
||||
BLI_assert(ghost_context == nullptr);
|
||||
ghost_context = GHOST_GetDrawingContext(static_cast<GHOST_WindowHandle>(ghost_window));
|
||||
ghost_context = ghost_window->getDrawingContext();
|
||||
}
|
||||
|
||||
BLI_assert(ghost_context != nullptr);
|
||||
|
|
@ -610,16 +608,16 @@ Context *VKBackend::context_alloc(void *ghost_window, void *ghost_context)
|
|||
device.init(ghost_context);
|
||||
device.extensions_get().log();
|
||||
device.workarounds_get().log();
|
||||
init_device_list(static_cast<GHOST_ContextHandle>(ghost_context));
|
||||
init_device_list(ghost_context);
|
||||
}
|
||||
|
||||
VKContext *context = new VKContext(ghost_window, ghost_context);
|
||||
device.context_register(*context);
|
||||
GHOST_SetVulkanSwapBuffersCallbacks(static_cast<GHOST_ContextHandle>(ghost_context),
|
||||
VKContext::swap_buffer_draw_callback,
|
||||
VKContext::swap_buffer_acquired_callback,
|
||||
VKContext::openxr_acquire_framebuffer_image_callback,
|
||||
VKContext::openxr_release_framebuffer_image_callback);
|
||||
ghost_context->setVulkanSwapBuffersCallbacks(
|
||||
VKContext::swap_buffer_draw_callback,
|
||||
VKContext::swap_buffer_acquired_callback,
|
||||
VKContext::openxr_acquire_framebuffer_image_callback,
|
||||
VKContext::openxr_release_framebuffer_image_callback);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ class VKBackend : public GPUBackend {
|
|||
void compute_dispatch(int groups_x_len, int groups_y_len, int groups_z_len) override;
|
||||
void compute_dispatch_indirect(StorageBuf *indirect_buf) override;
|
||||
|
||||
Context *context_alloc(void *ghost_window, void *ghost_context) override;
|
||||
Context *context_alloc(GHOST_IWindow *ghost_window, GHOST_IContext *ghost_context) override;
|
||||
|
||||
Batch *batch_alloc() override;
|
||||
Fence *fence_alloc() override;
|
||||
|
|
|
|||
|
|
@ -23,11 +23,9 @@
|
|||
#include "vk_texture.hh"
|
||||
#include "vk_vertex_attribute_object.hh"
|
||||
|
||||
#include "GHOST_C-api.h"
|
||||
|
||||
namespace blender::gpu {
|
||||
|
||||
VKContext::VKContext(void *ghost_window, void *ghost_context)
|
||||
VKContext::VKContext(GHOST_IWindow *ghost_window, GHOST_IContext *ghost_context)
|
||||
{
|
||||
ghost_window_ = ghost_window;
|
||||
ghost_context_ = ghost_context;
|
||||
|
|
@ -61,8 +59,7 @@ void VKContext::sync_backbuffer()
|
|||
{
|
||||
if (ghost_window_) {
|
||||
GHOST_VulkanSwapChainData swap_chain_data = {};
|
||||
GHOST_GetVulkanSwapChainFormat(static_cast<GHOST_WindowHandle>(ghost_window_),
|
||||
&swap_chain_data);
|
||||
ghost_window_->getVulkanSwapChainFormat(&swap_chain_data);
|
||||
|
||||
const bool reset_framebuffer = swap_chain_format_.format !=
|
||||
swap_chain_data.surface_format.format ||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
#include "gpu_context_private.hh"
|
||||
|
||||
#include "GHOST_Types.h"
|
||||
#include "GHOST_Types.hh"
|
||||
|
||||
#include "render_graph/vk_render_graph.hh"
|
||||
#include "vk_common.hh"
|
||||
|
|
@ -46,7 +46,7 @@ class VKContext : public Context, NonCopyable {
|
|||
VkExtent2D vk_extent_ = {};
|
||||
VkSurfaceFormatKHR swap_chain_format_ = {};
|
||||
gpu::Texture *surface_texture_ = nullptr;
|
||||
void *ghost_context_;
|
||||
GHOST_IContext *ghost_context_;
|
||||
|
||||
Vector<std::unique_ptr<VKStreamingBuffer>> streaming_buffers_;
|
||||
|
||||
|
|
@ -86,7 +86,7 @@ class VKContext : public Context, NonCopyable {
|
|||
return render_graph_.value().get();
|
||||
}
|
||||
|
||||
VKContext(void *ghost_window, void *ghost_context);
|
||||
VKContext(GHOST_IWindow *ghost_window, GHOST_IContext *ghost_context);
|
||||
virtual ~VKContext();
|
||||
|
||||
void activate() override;
|
||||
|
|
|
|||
|
|
@ -26,8 +26,6 @@
|
|||
|
||||
#include "BLI_math_matrix_types.hh"
|
||||
|
||||
#include "GHOST_C-api.h"
|
||||
|
||||
namespace blender {
|
||||
|
||||
static CLG_LogRef LOG = {"gpu.vulkan"};
|
||||
|
|
@ -134,11 +132,11 @@ void VKDevice::deinit()
|
|||
is_initialized_ = false;
|
||||
}
|
||||
|
||||
void VKDevice::init(void *ghost_context)
|
||||
void VKDevice::init(GHOST_IContext *ghost_context)
|
||||
{
|
||||
BLI_assert(!is_initialized());
|
||||
GHOST_VulkanHandles handles = {};
|
||||
GHOST_GetVulkanHandles(static_cast<GHOST_ContextHandle>(ghost_context), &handles);
|
||||
ghost_context->getVulkanHandles(handles);
|
||||
vk_instance_ = handles.instance;
|
||||
vk_physical_device_ = handles.physical_device;
|
||||
vk_device_ = handles.device;
|
||||
|
|
|
|||
|
|
@ -363,7 +363,7 @@ class VKDevice : public NonCopyable {
|
|||
return samplers_;
|
||||
}
|
||||
|
||||
void init(void *ghost_context);
|
||||
void init(GHOST_IContext *ghost_context);
|
||||
void reinit();
|
||||
void deinit();
|
||||
bool is_initialized() const
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue