29#define FONTSTASH_IMPLEMENTATION
39 if (
_impl !=
nullptr )
114 if ( g_assertMsgBox )
116 g_assertMsgBox->
setTitle(
"Assertion Failed!" );
119 g_assertMsgBox->
show();
128 , _textRenderInterval( Time::MillisecondsToMicroseconds( 10 ) )
129 , _ceguiInput( *this )
142 assert( newScene !=
nullptr );
149 it->second->onDisable();
153 const GUIMapPerScene::const_iterator it =
_guiStack.find( newScene->
getGUID() );
156 it->second->onEnable();
171 assert( scene !=
nullptr );
173 const GUIMapPerScene::const_iterator it =
_guiStack.find( scene->
getGUID() );
199 ._anisotropyLevel = 0u
202 GFX::EnqueueCommand<GFX::BeginDebugScopeCommand>( bufferInOut )->_scopeName =
"Draw Text";
209 GFX::EnqueueCommand<GFX::BindPipelineCommand>( bufferInOut )->_pipeline =
_textRenderPipeline;
211 auto cmd = GFX::EnqueueCommand<GFX::BindShaderResourcesCommand>( bufferInOut );
216 size_t drawCount = 0;
217 size_t previousStyle = 0;
223 if ( previousStyle !=
entry.textLabelStyleHash() )
226 const UColour4& colour = textLabelStyle.colour();
239 previousStyle =
entry.textLabelStyleHash();
242 F32 textX =
entry.position()._x._scale * targetViewport.
sizeX +
entry.position()._x._offset;
243 F32 textY = targetViewport.
sizeY - (
entry.position()._y._scale * targetViewport.
sizeY +
entry.position()._y._offset);
245 textX += targetViewport.
offsetX;
246 textY += targetViewport.
offsetY;
252 const size_t lineCount = text.size();
255 for (
size_t i = 0; i < lineCount; ++i )
263 drawCount += lineCount;
274 GFX::EnqueueCommand<GFX::EndDebugScopeCommand>( bufferInOut );
286 GFX::EnqueueCommand<GFX::BeginDebugScopeCommand>( bufferInOut )->_scopeName =
"Pre-Render GUI";
289 GFX::EnqueueCommand<GFX::BeginDebugScopeCommand>( bufferInOut )->_scopeName =
"Render CEGUI";
296 GFX::EnqueueCommand<GFX::EndDebugScopeCommand>( bufferInOut );
299 GFX::EnqueueCommand<GFX::EndDebugScopeCommand>( bufferInOut );
313 GFX::EnqueueCommand<GFX::BeginDebugScopeCommand>( bufferInOut )->_scopeName =
"Render GUI";
318 GFX::EnqueueCommand<GFX::SetViewportCommand>( bufferInOut )->_viewport = viewport;
324 textBatch.data().reserve( elements.size() );
325 for (
const GUIMap::value_type& guiStackIterator : elements )
327 const GUIText& textLabel =
static_cast<GUIText&
>(*guiStackIterator.second.first);
328 if ( textLabel.visible() && !textLabel.
text().empty() )
330 textBatch.data().push_back( textLabel );
340 const auto& batch = it->second->updateAndGetText();
341 textBatch.data().insert(textBatch.data().cend(), batch.data().cbegin(), batch.data().cend());
345 if ( !textBatch.data().empty() )
347 drawText( textBatch, viewport, bufferInOut, memCmdInOut );
355 GFX::EnqueueCommand<GFX::EndDebugScopeCommand>( bufferInOut );
370 auto& ceguiSystem = CEGUI::System::getSingleton();
371 ceguiSystem.injectTimePulse( Time::MicrosecondsToSeconds<F32>( deltaTimeUS ) );
372 ceguiSystem.getDefaultGUIContext().injectTimePulse( Time::MicrosecondsToSeconds<F32>( deltaTimeUS ) );
410 _console = std::make_unique<GUIConsole>( *
this, context );
414 context.
sfx().playSound( sound );
423 memset( ¶ms, 0,
sizeof params );
427 params.
renderResize = [](
void* userPtr,
int width,
int height )
437 return FONSRenderCreate( userPtr, width, height );
439 params.
renderUpdate = [](
void* userPtr,
int* rect,
const unsigned char* data )
448 const I32 w = rect[2] - rect[0];
449 const I32 h = rect[3] - rect[1];
455 ._skipPixels =
to_size( rect[0] ),
456 ._skipRows =
to_size( rect[1] )
498 std::atomic_uint loadTasks = 0;
502 vertModule.
_sourceFile =
"ImmediateModeEmulation.glsl";
506 fragModule.
_sourceFile =
"ImmediateModeEmulation.glsl";
510 immediateModeShader.waitForReady(
true );
512 shaderDescriptor.
_modules.push_back( vertModule );
513 shaderDescriptor.
_modules.push_back( fragModule );
544 blend.enabled(
true );
557 vertModule.
_sourceFile =
"ImmediateModeEmulation.glsl";
561 fragModule.
_sourceFile =
"ImmediateModeEmulation.glsl";
566 ceguiShader.waitForReady(
true );
569 shaderDescriptor.
_modules.push_back( fragModule );
570 shaderDescriptor.
_modules.push_back( vertModule );
578 const CEGUI::Sizef size(
static_cast<float>(renderSize.
width),
static_cast<float>(renderSize.
height) );
581 const string logFile = (Paths::g_logPath /
"CEGUI.log").
string();
582 CEGUI::System::create( *
_ceguiRenderer,
nullptr,
nullptr,
nullptr,
nullptr,
"", logFile.c_str() );
585 CEGUI::Logger::getSingleton().setLoggingLevel( CEGUI::Informative );
588 CEGUI::DefaultResourceProvider* rp =
static_cast<CEGUI::DefaultResourceProvider*
>(CEGUI::System::getSingleton().getResourceProvider());
590 const CEGUI::String CEGUIInstallSharePath( (Paths::g_GUILocation.
string() + Paths::g_pathSeparator).c_str() );
591 rp->setResourceGroupDirectory(
"schemes", CEGUIInstallSharePath +
"schemes/" );
592 rp->setResourceGroupDirectory(
"imagesets", CEGUIInstallSharePath +
"imagesets/" );
593 rp->setResourceGroupDirectory(
"fonts", CEGUIInstallSharePath +
"fonts/" );
594 rp->setResourceGroupDirectory(
"layouts", CEGUIInstallSharePath +
"layouts/" );
595 rp->setResourceGroupDirectory(
"looknfeels", CEGUIInstallSharePath +
"looknfeel/" );
596 rp->setResourceGroupDirectory(
"lua_scripts", CEGUIInstallSharePath +
"lua_scripts/" );
597 rp->setResourceGroupDirectory(
"schemas", CEGUIInstallSharePath +
"xml_schemas/" );
598 rp->setResourceGroupDirectory(
"animations", CEGUIInstallSharePath +
"animations/" );
601 CEGUI::ImageManager::setImagesetDefaultResourceGroup(
"imagesets" );
602 CEGUI::Font::setDefaultResourceGroup(
"fonts" );
603 CEGUI::Scheme::setDefaultResourceGroup(
"schemes" );
604 CEGUI::WidgetLookManager::setDefaultResourceGroup(
"looknfeels" );
605 CEGUI::WindowManager::setDefaultResourceGroup(
"layouts" );
606 CEGUI::ScriptModule::setDefaultResourceGroup(
"lua_scripts" );
608 CEGUI::XMLParser* parser = CEGUI::System::getSingleton().getXMLParser();
609 if ( parser->isPropertyPresent(
"SchemaDefaultResourceGroup" ) )
611 parser->setProperty(
"SchemaDefaultResourceGroup",
"schemas" );
613 CEGUI::FontManager::getSingleton().createFromFile(
"DejaVuSans-10.font" );
614 CEGUI::FontManager::getSingleton().createFromFile(
"DejaVuSans-12.font" );
615 CEGUI::FontManager::getSingleton().createFromFile(
"DejaVuSans-10-NoScale.font" );
616 CEGUI::FontManager::getSingleton().createFromFile(
"DejaVuSans-12-NoScale.font" );
617 CEGUI::SchemeManager::getSingleton().createFromFile( (defaultGUIScheme() +
".scheme").c_str() );
623 _rootSheet = CEGUI::WindowManager::getSingleton().createWindow(
"DefaultWindow",
"root_window" );
624 _rootSheet->setMousePassThroughEnabled(
true );
625 _rootSheet->setUsingAutoRenderingSurface(
false );
629 _ceguiContext->setDefaultTooltipType( (defaultGUIScheme() +
"/Tooltip").c_str() );
632 CEGUI::System::getSingleton().notifyDisplaySizeChanged( size );
655 "Assertion failed with message: ",
673 g_assertMsgBox =
nullptr;
693 CEGUI::System::destroy();
711 _showDebugCursor = state;
715 _rootSheet->setMouseCursor( state ?
"GWEN/Tree.Plus" :
"" );
728 const CEGUI::Sizef windowSize( params.
width, params.
height );
729 CEGUI::System::getSingleton().notifyDisplaySizeChanged( windowSize );
733 _rootSheet->setSize( CEGUI::USize( CEGUI::UDim( 0.0f,
to_F32( renderViewport.
z ) ),
734 CEGUI::UDim( 0.0f,
to_F32( renderViewport.
w ) ) ) );
735 _rootSheet->setPosition( CEGUI::UVector2( CEGUI::UDim( 0.0f,
to_F32( renderViewport.
x ) ),
736 CEGUI::UDim( 0.0f,
to_F32( renderViewport.
y ) ) ) );
830 const GUIMapPerScene::const_iterator it =
_guiStack.find( sceneID );
833 return it->second->getGUIElement<
GUIElement>( elementName );
849 const GUIMapPerScene::const_iterator it =
_guiStack.find( sceneID );
852 return it->second->getGUIElement<
GUIElement>( elementID );
870 if (
_fontCache.first.compare( fontName ) != 0 )
873 const U64 fontNameHash =
_ID( fontName.c_str() );
875 const auto& it =
_fonts.find( fontNameHash );
877 if ( it == std::cend(
_fonts ) )
881 const string fontPath = (Paths::g_fontsPath / fontName.c_str()).
string();
#define PROFILE_SCOPE_AUTO(CATEGORY)
void beginRendering() override
TextureTarget * createTextureTarget() override
void endRendering() override
static void destroy(CEGUIRenderer &renderer)
static CEGUIRenderer & create(Divide::GFXDevice &context, Divide::Handle< Divide::ShaderProgram > shader, CEGUI::Sizef resolution, int abi=CEGUI_VERSION_ABI)
Divide::Handle< Divide::Texture > getAttachmentTex() const
Divide::SamplerDescriptor getSampler() const noexcept
void declareRenderSize(const Sizef &sz) override
static SceneGUIElements * guiElements(Scene *scene) noexcept
static Camera * GetUtilityCamera(const UtilityCamera type)
const CameraSnapshot & snapshot() const noexcept
Returns the internal camera snapshot data (eye, orientation, etc)
Rough around the edges Adapter pattern abstracting the actual rendering API and access to the GPU.
void drawTextureInViewport(const ImageView &texture, SamplerDescriptor sampler, const Rect< I32 > &viewport, bool convertToSrgb, bool drawToDepthOnly, bool drawBlend, GFX::CommandBuffer &bufferInOut)
vec2< U16 > renderingResolution() const noexcept
Pipeline * newPipeline(const PipelineDescriptor &descriptor)
Create and return a new graphics pipeline. This is only used for caching and doesn't use the object a...
GenericVertexData_ptr newGVD(U32 ringBufferLength, std::string_view name)
const RenderStateBlock & get2DStateBlock() const noexcept
FORCE_INLINE I64 getGUID() const noexcept
CEGUI::GUIContext * getCEGUIContext() noexcept
Provides direct access to the CEGUI context. Used by plugins (e.g. GUIConsole, GUIInput,...
CEGUI::Window * _rootSheet
The root window into which CEGUI anchors all of its elements.
CEGUI::Window * rootSheet() const noexcept
Get a pointer to the root sheet that CEGUI renders into.
bool joystickPovMoved(const Input::JoystickEvent &arg) override
Joystick direction change: return true if input was consumed.
bool onKeyUp(const Input::KeyEvent &key) override
Key released: return true if input was consumed.
std::unique_ptr< GUIConsole > _console
Our custom in-game console (for logs and commands. A la Quake's ~-console)
ErrorCode init(PlatformContext &context)
Create the GUI.
bool onTextEvent(const Input::TextEvent &arg) noexcept override
Called when text input was detected.
bool joystickButtonReleased(const Input::JoystickEvent &arg) override
Joystick button released: return true if input was consumed.
std::unique_ptr< GUIMessageBox > _defaultMsgBox
Pointer to a default message box used for general purpose messages.
CEGUIInput _ceguiInput
Used to implement key repeat.
void recreateDefaultMessageBox()
Used to recreate and re-register the default message box if needed (usually on scene change)
CEGUI::GUIContext * _ceguiContext
The CEGUI context as returned by the library upon creation.
void setCursorPosition(I32 x, I32 y)
Mouse cursor forced to a certain position.
DVDFONSContext_uptr _fonsContext
We use Font Stash (https://github.com/memononen/fontstash) for rendering basic text on the screen....
Handle< ShaderProgram > _textRenderShader
The text rendering shaderProgram we used to draw Font Stash text.
void preDraw(GFXDevice &context, const Rect< I32 > &viewport, GFX::CommandBuffer &bufferInOut, GFX::MemoryBarrierCommand &memCmdInOut)
Render all elements that need their own internal render targets (e.g. CEGUI)
bool mouseButtonPressed(const Input::MouseButtonEvent &arg) override
Mouse button pressed: return true if input was consumed.
bool joystickAddRemove(const Input::JoystickEvent &arg) override
bool joystickBallMoved(const Input::JoystickEvent &arg) override
void draw(GFXDevice &context, const Rect< I32 > &viewport, GFX::CommandBuffer &bufferInOut, GFX::MemoryBarrierCommand &memCmdInOut)
Go through all of the registered scene gui elements and gather all of the render commands.
Pipeline * _textRenderPipeline
The text rendering pipeline we used to draw Font Stash text.
void showDebugCursor(bool state)
Toggle debug cursor rendering on or off.
void onUnloadScene(Scene *scene)
When we unload a scene, we unload all of its GUI elements. ToDo: Scene should own these and scene sho...
void onChangeScene(Scene *newScene)
When we change a scene, we want to toggle our current scene GUI elements off and toggle the new scene...
bool joystickRemap(const Input::JoystickEvent &arg) override
void onResolutionChange(const SizeChangeParams ¶ms)
Mostly used by CEGUI to keep track of screen dimensions.
bool joystickAxisMoved(const Input::JoystickEvent &arg) override
Joystick axis change: return true if input was consumed.
I32 getFont(const Str< 64 > &fontName)
Try to find the requested font in the font cache. Load on cache miss.
bool mouseMoved(const Input::MouseMoveEvent &arg) override
Mouse moved: return true if input was consumed.
bool joystickButtonPressed(const Input::JoystickEvent &arg) override
Joystick button pressed: return true if input was consumed.
GUIMapPerScene _guiStack
All the GUI elements created per scene.
bool onKeyDown(const Input::KeyEvent &key) override
Key pressed: return true if input was consumed.
bool frameStarted(const FrameEvent &evt) override
T * getSceneGUIElementImpl(const I64 sceneID, const U64 elementName)
Find a return a gui element by name.
bool mouseButtonReleased(const Input::MouseButtonEvent &arg) override
Mouse button released: return true if input was consumed.
void update(U64 deltaTimeUS)
Main update call. Used to tick gui elements (cursors, animations, etc)
bool _init
Set to true when the GUI has finished loading.
SharedMutex _guiStackLock
A lock to protect access to _guiStack.
CEGUI::CEGUIRenderer * _ceguiRenderer
Used to render CEGUI to a texture; We want to port this to the Divide::GFX interface.
hashMap< U64, I32 > _fonts
A cache of all font IDs used by Font Stash stored by name ID.
Scene * _activeScene
Each scene has its own gui elements! (0 = global). We keep a pointer to the scene but we really shoul...
CEGUI::DVDTextureTarget * _renderTextureTarget
Used to render CEGUI elements into. We blit this on top of our scene target.
Handle< ShaderProgram > _ceguiRenderShader
hashAlg::pair< Str< 64 >, I32 > _fontCache
A cache of the last requested font by name to avoid a lookup in the fonts map.
void drawText(const TextElementBatch &batch, const Rect< I32 > &targetViewport, GFX::CommandBuffer &bufferInOut, GFX::MemoryBarrierCommand &memCmdInOut, bool pushCamera=true)
Text rendering is handled exclusively by Mikko Mononen's FontStash library (https://github....
virtual GUIElement * getGUIElementImpl(U64 elementName, GUIType type) const
hashMap< U64, std::pair< GUIElement *, bool > > GUIMap
std::array< GUIMap, to_base(GUIType::COUNT)> _guiElements
void setMessage(const string &message)
void setTitle(const string &titleText)
void setMessageType(MessageType type)
Kernel & parent() noexcept
The kernel is the main system that connects all of our various systems: windows, gfx,...
FORCE_INLINE PlatformContext & platformContext() noexcept
SFXDevice & sfx() noexcept
GFXDevice & gfx() noexcept
Configuration & config() noexcept
static const TextLabelStyle & get(size_t textLabelStyleHash)
static const Str< 64 > & fontName(size_t fontNameHash)
void fonsSetAlign(FONScontext *s, int align)
void fonsVertMetrics(FONScontext *s, float *ascender, float *descender, float *lineh)
void fonsSetBlur(FONScontext *s, float blur)
void fonsSetColour(FONScontext *s, unsigned char colourR, unsigned char colourG, unsigned char colourB, unsigned char colourA)
#define FONS_VERTEX_COUNT
FONScontext * fonsCreateInternal(FONSparams *params)
int fonsAddFont(FONScontext *s, const char *name, const char *path)
void fonsSetSize(FONScontext *s, float size)
float fonsDrawText(FONScontext *s, float x, float y, const char *string, const char *end)
void fonsDeleteInternal(FONScontext *s)
void fonsClearState(FONScontext *s)
struct FONScontext FONScontext
void fonsSetFont(FONScontext *s, int font)
constexpr bool SHOW_MESSAGE_BOX
Popup a GUI Message Box on asserts;.
constexpr bool IS_DEBUG_BUILD
constexpr U8 MAX_FRAMES_IN_FLIGHT
Maximum number of active frames until we start waiting on a fence/sync.
FORCE_INLINE T * EnqueueCommand(CommandBuffer &buffer)
constexpr Optick::Category::Type GUI
constexpr Optick::Category::Type Graphics
I32 FONSRenderCreate(void *userPtr, int width, int height)
void RefreshBufferSize(DVDFONSContext *dvd)
GUIMessageBox * g_assertMsgBox
Handle console commands that start with a forward slash.
std::lock_guard< mutex > LockGuard
constexpr U32 to_U32(const T value)
FORCE_INLINE void DestroyResource(Handle< T > &handle, const bool immediate=false)
void insert(eastl::vector< T, A1 > &target, const eastl::vector< T, A2 > &source)
void DIVIDE_ASSERT_MSG_BOX(const char *failMessage) noexcept
constexpr F32 to_F32(const T value)
@ COUNT
Place all properties above this.
std::shared_lock< mutex > SharedLock
void Set(DescriptorSetBindingData &dataInOut, ShaderBuffer *buffer, const BufferRange range) noexcept
constexpr U64 _ID(const char *const str, const U64 value=val_64_const) noexcept
DescriptorSetBinding & AddBinding(DescriptorSet &setInOut, U8 slot, U16 stageVisibilityMask)
FORCE_INLINE Handle< T > CreateResource(const ResourceDescriptor< T > &descriptor, bool &wasInCache, std::atomic_uint &taskCounter)
void efficient_clear(eastl::fixed_vector< T, nodeCount, bEnableOverflow, OverflowAllocator > &fixed_vector)
constexpr size_t to_size(const T value)
FORCE_INLINE T * Get(const Handle< T > handle)
Project const SceneEntry & entry
constexpr auto to_base(const Type value) -> Type
Divide::hashPairReturn< K, V, HashFun > insert(Divide::hashMap< K, V, HashFun, Predicate > &map, const pair< K, V > &valuePair)
VertexBindings _vertexBindings
BufferUpdateUsage _updateUsage
BufferUpdateFrequency _updateFrequency
size_t _elementSize
Buffer primitive size in bytes.
struct Divide::Configuration::GUI::CEGUI cegui
struct Divide::Configuration::GUI gui
static NO_INLINE void errorfn(const char *format, T &&... args)
static NO_INLINE void printfn(const char *format, T &&... args)
static NO_INLINE void d_errorfn(const char *format, T &&... args)
GenericVertexData_ptr _fontRenderingBuffer
Handle< Texture > _fontRenderingTexture
GFX::CommandBuffer * _commandBuffer
GFX::MemoryBarrierCommand * _memCmd
DescriptorSetBindingData _data
IndirectIndexedDrawCommand _cmd
std::pair< bufferPtr, size_t > _initialData
BufferBindConfig _bindConfig
BufferParams _bufferParams
PrimitiveTopology _primitiveTopology
AttributeMap _vertexFormat
Handle< ShaderProgram > _shaderProgramHandle
RTBlendStates _blendStates
RenderStateBlock _stateBlock
vector< ShaderModuleDescriptor > _modules
GFXImageFormat _baseFormat
MipMappingState _mipMappingState
std::array< BlendingSettings, to_base(RTColourAttachmentSlot::COUNT)> _settings
PropertyDescriptor< T > _propertyDescriptor
TextureFilter _minFilter
Texture filtering mode.
U16 width
The new width and height.
vector< eastl::string > TextType
void text(const char *text, const bool multiLine)
int(* renderCreate)(void *uptr, int width, int height)
void(* renderDelete)(void *uptr)
int(* renderResize)(void *uptr, int width, int height)
void(* renderDraw)(void *uptr, const FONSvert *verts, int nverts)
void(* renderUpdate)(void *uptr, int *rect, const unsigned char *data)