mirror of https://github.com/qt/qt3d.git
Add Profiling Overlay
Can be activated at adding a QDebugOverlay in the frame graph to identify which surface it should be renderer one (renders only once on first branch that contains such a node). Can be also activated on the forward renderer from Qt3DExtras. - Shows information about FPS and number of jobs/renderviews/commands/vertices/entities/geometries/textures... - Allows to toggle job and gl call tracing and open folder where trace files are stored - Windows to show and dump glinfo and renderview/command details to the console Change-Id: I286ff85760e8f8f0604a23458883ff22229bda94 Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
This commit is contained in:
parent
34cb77c210
commit
34165446cd
|
|
@ -51,7 +51,7 @@
|
|||
import Qt3D.Core 2.0
|
||||
import Qt3D.Render 2.0
|
||||
import Qt3D.Input 2.0
|
||||
import Qt3D.Extras 2.0
|
||||
import Qt3D.Extras 2.15
|
||||
|
||||
import QtQuick 2.0 as QQ2
|
||||
|
||||
|
|
@ -77,6 +77,7 @@ Entity {
|
|||
activeFrameGraph: ForwardRenderer {
|
||||
camera: camera
|
||||
clearColor: "transparent"
|
||||
showDebugOverlay: true
|
||||
}
|
||||
},
|
||||
InputSettings { }
|
||||
|
|
|
|||
|
|
@ -53,6 +53,20 @@
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
{
|
||||
// Set OpenGL requirements
|
||||
QSurfaceFormat format = QSurfaceFormat::defaultFormat();
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
format.setVersion(4, 1);
|
||||
format.setProfile(QSurfaceFormat::CoreProfile);
|
||||
format.setSamples(4);
|
||||
#else
|
||||
format.setVersion(3, 0);
|
||||
format.setProfile(QSurfaceFormat::NoProfile);
|
||||
format.setRenderableType(QSurfaceFormat::OpenGLES);
|
||||
#endif
|
||||
QSurfaceFormat::setDefaultFormat(format);
|
||||
}
|
||||
QGuiApplication app(argc, argv);
|
||||
|
||||
QQuickView view;
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ import QtQuick 2.2 as QQ2
|
|||
import Qt3D.Core 2.0
|
||||
import Qt3D.Render 2.0
|
||||
import Qt3D.Input 2.0
|
||||
import Qt3D.Extras 2.0
|
||||
import Qt3D.Extras 2.15
|
||||
|
||||
Entity {
|
||||
id: sceneRoot
|
||||
|
|
@ -78,6 +78,7 @@ Entity {
|
|||
activeFrameGraph: ForwardRenderer {
|
||||
clearColor: Qt.rgba(0, 0.5, 1, 1)
|
||||
camera: camera
|
||||
showDebugOverlay: true
|
||||
}
|
||||
},
|
||||
// Event Source will be set by the Qt3DQuickWindow
|
||||
|
|
|
|||
3
qt3d.pro
3
qt3d.pro
|
|
@ -14,4 +14,5 @@ load(qt_parts)
|
|||
#gcov: SUBDIRS -= sub_tools
|
||||
|
||||
OTHER_FILES += \
|
||||
sync.profile
|
||||
sync.profile \
|
||||
.qmake.conf
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2018 Omar Cornut
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// COMPILE-TIME OPTIONS FOR DEAR IMGUI
|
||||
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
|
||||
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
// A) You may edit imconfig.h (and not overwrite it when updating imgui, or maintain a patch/branch with your modifications to imconfig.h)
|
||||
// B) or add configuration directives in your own file and compile with #define IMGUI_USER_CONFIG "myfilename.h"
|
||||
// If you do so you need to make sure that configuration settings are defined consistently _everywhere_ dear imgui is used, which include
|
||||
// the imgui*.cpp files but also _any_ of your code that uses imgui. This is because some compile-time options have an affect on data structures.
|
||||
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
|
||||
// Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
//---- Define assertion handler. Defaults to calling assert().
|
||||
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
|
||||
//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
|
||||
|
||||
//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows.
|
||||
//#define IMGUI_API __declspec( dllexport )
|
||||
//#define IMGUI_API __declspec( dllimport )
|
||||
|
||||
//---- Don't define obsolete functions/enums names. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names.
|
||||
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
|
||||
//---- Don't implement demo windows functionality (ShowDemoWindow()/ShowStyleEditor()/ShowUserGuide() methods will be empty)
|
||||
//---- It is very strongly recommended to NOT disable the demo windows during development. Please read the comments in imgui_demo.cpp.
|
||||
//#define IMGUI_DISABLE_DEMO_WINDOWS
|
||||
|
||||
//---- Don't implement some functions to reduce linkage requirements.
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc.
|
||||
#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] Don't implement default IME handler. Won't use and link with ImmGetContext/ImmSetCompositionWindow.
|
||||
#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function.
|
||||
//#define IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself if you don't want to link with vsnprintf.
|
||||
//#define IMGUI_DISABLE_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 wrapper so you can implement them yourself. Declare your prototypes in imconfig.h.
|
||||
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
|
||||
|
||||
//---- Include imgui_user.h at the end of imgui.h as a convenience
|
||||
//#define IMGUI_INCLUDE_IMGUI_USER_H
|
||||
|
||||
//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
|
||||
//#define IMGUI_USE_BGRA_PACKED_COLOR
|
||||
|
||||
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
|
||||
// By default the embedded implementations are declared static and not available outside of imgui cpp files.
|
||||
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
|
||||
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
|
||||
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
|
||||
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
|
||||
|
||||
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
|
||||
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
|
||||
/*
|
||||
#define IM_VEC2_CLASS_EXTRA \
|
||||
ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \
|
||||
operator MyVec2() const { return MyVec2(x,y); }
|
||||
|
||||
#define IM_VEC4_CLASS_EXTRA \
|
||||
ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \
|
||||
operator MyVec4() const { return MyVec4(x,y,z,w); }
|
||||
*/
|
||||
|
||||
//---- Use 32-bit vertex indices (default is 16-bit) to allow meshes with more than 64K vertices. Render function needs to support it.
|
||||
#define ImDrawIdx unsigned int
|
||||
|
||||
//---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
|
||||
/*
|
||||
namespace ImGui
|
||||
{
|
||||
void MyFunction(const char* name, const MyMatrix44& v);
|
||||
}
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,9 @@
|
|||
INCLUDEPATH += $$PWD
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/imgui_draw.cpp \
|
||||
$$PWD/imgui.cpp \
|
||||
$$PWD/imgui_widgets.cpp
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/imgui.h
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,623 @@
|
|||
// stb_rect_pack.h - v0.11 - public domain - rectangle packing
|
||||
// Sean Barrett 2014
|
||||
//
|
||||
// Useful for e.g. packing rectangular textures into an atlas.
|
||||
// Does not do rotation.
|
||||
//
|
||||
// Not necessarily the awesomest packing method, but better than
|
||||
// the totally naive one in stb_truetype (which is primarily what
|
||||
// this is meant to replace).
|
||||
//
|
||||
// Has only had a few tests run, may have issues.
|
||||
//
|
||||
// More docs to come.
|
||||
//
|
||||
// No memory allocations; uses qsort() and assert() from stdlib.
|
||||
// Can override those by defining STBRP_SORT and STBRP_ASSERT.
|
||||
//
|
||||
// This library currently uses the Skyline Bottom-Left algorithm.
|
||||
//
|
||||
// Please note: better rectangle packers are welcome! Please
|
||||
// implement them to the same API, but with a different init
|
||||
// function.
|
||||
//
|
||||
// Credits
|
||||
//
|
||||
// Library
|
||||
// Sean Barrett
|
||||
// Minor features
|
||||
// Martins Mozeiko
|
||||
// github:IntellectualKitty
|
||||
//
|
||||
// Bugfixes / warning fixes
|
||||
// Jeremy Jaussaud
|
||||
//
|
||||
// Version history:
|
||||
//
|
||||
// 0.11 (2017-03-03) return packing success/fail result
|
||||
// 0.10 (2016-10-25) remove cast-away-const to avoid warnings
|
||||
// 0.09 (2016-08-27) fix compiler warnings
|
||||
// 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0)
|
||||
// 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0)
|
||||
// 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
|
||||
// 0.05: added STBRP_ASSERT to allow replacing assert
|
||||
// 0.04: fixed minor bug in STBRP_LARGE_RECTS support
|
||||
// 0.01: initial release
|
||||
//
|
||||
// LICENSE
|
||||
//
|
||||
// See end of file for license information.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// INCLUDE SECTION
|
||||
//
|
||||
|
||||
#ifndef STB_INCLUDE_STB_RECT_PACK_H
|
||||
#define STB_INCLUDE_STB_RECT_PACK_H
|
||||
|
||||
#define STB_RECT_PACK_VERSION 1
|
||||
|
||||
#ifdef STBRP_STATIC
|
||||
#define STBRP_DEF static
|
||||
#else
|
||||
#define STBRP_DEF extern
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct stbrp_context stbrp_context;
|
||||
typedef struct stbrp_node stbrp_node;
|
||||
typedef struct stbrp_rect stbrp_rect;
|
||||
|
||||
#ifdef STBRP_LARGE_RECTS
|
||||
typedef int stbrp_coord;
|
||||
#else
|
||||
typedef unsigned short stbrp_coord;
|
||||
#endif
|
||||
|
||||
STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
|
||||
// Assign packed locations to rectangles. The rectangles are of type
|
||||
// 'stbrp_rect' defined below, stored in the array 'rects', and there
|
||||
// are 'num_rects' many of them.
|
||||
//
|
||||
// Rectangles which are successfully packed have the 'was_packed' flag
|
||||
// set to a non-zero value and 'x' and 'y' store the minimum location
|
||||
// on each axis (i.e. bottom-left in cartesian coordinates, top-left
|
||||
// if you imagine y increasing downwards). Rectangles which do not fit
|
||||
// have the 'was_packed' flag set to 0.
|
||||
//
|
||||
// You should not try to access the 'rects' array from another thread
|
||||
// while this function is running, as the function temporarily reorders
|
||||
// the array while it executes.
|
||||
//
|
||||
// To pack into another rectangle, you need to call stbrp_init_target
|
||||
// again. To continue packing into the same rectangle, you can call
|
||||
// this function again. Calling this multiple times with multiple rect
|
||||
// arrays will probably produce worse packing results than calling it
|
||||
// a single time with the full rectangle array, but the option is
|
||||
// available.
|
||||
//
|
||||
// The function returns 1 if all of the rectangles were successfully
|
||||
// packed and 0 otherwise.
|
||||
|
||||
struct stbrp_rect
|
||||
{
|
||||
// reserved for your use:
|
||||
int id;
|
||||
|
||||
// input:
|
||||
stbrp_coord w, h;
|
||||
|
||||
// output:
|
||||
stbrp_coord x, y;
|
||||
int was_packed; // non-zero if valid packing
|
||||
|
||||
}; // 16 bytes, nominally
|
||||
|
||||
|
||||
STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
|
||||
// Initialize a rectangle packer to:
|
||||
// pack a rectangle that is 'width' by 'height' in dimensions
|
||||
// using temporary storage provided by the array 'nodes', which is 'num_nodes' long
|
||||
//
|
||||
// You must call this function every time you start packing into a new target.
|
||||
//
|
||||
// There is no "shutdown" function. The 'nodes' memory must stay valid for
|
||||
// the following stbrp_pack_rects() call (or calls), but can be freed after
|
||||
// the call (or calls) finish.
|
||||
//
|
||||
// Note: to guarantee best results, either:
|
||||
// 1. make sure 'num_nodes' >= 'width'
|
||||
// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
|
||||
//
|
||||
// If you don't do either of the above things, widths will be quantized to multiples
|
||||
// of small integers to guarantee the algorithm doesn't run out of temporary storage.
|
||||
//
|
||||
// If you do #2, then the non-quantized algorithm will be used, but the algorithm
|
||||
// may run out of temporary storage and be unable to pack some rectangles.
|
||||
|
||||
STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
|
||||
// Optionally call this function after init but before doing any packing to
|
||||
// change the handling of the out-of-temp-memory scenario, described above.
|
||||
// If you call init again, this will be reset to the default (false).
|
||||
|
||||
|
||||
STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
|
||||
// Optionally select which packing heuristic the library should use. Different
|
||||
// heuristics will produce better/worse results for different data sets.
|
||||
// If you call init again, this will be reset to the default.
|
||||
|
||||
enum
|
||||
{
|
||||
STBRP_HEURISTIC_Skyline_default=0,
|
||||
STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
|
||||
STBRP_HEURISTIC_Skyline_BF_sortHeight
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// the details of the following structures don't matter to you, but they must
|
||||
// be visible so you can handle the memory allocations for them
|
||||
|
||||
struct stbrp_node
|
||||
{
|
||||
stbrp_coord x,y;
|
||||
stbrp_node *next;
|
||||
};
|
||||
|
||||
struct stbrp_context
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
int align;
|
||||
int init_mode;
|
||||
int heuristic;
|
||||
int num_nodes;
|
||||
stbrp_node *active_head;
|
||||
stbrp_node *free_head;
|
||||
stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPLEMENTATION SECTION
|
||||
//
|
||||
|
||||
#ifdef STB_RECT_PACK_IMPLEMENTATION
|
||||
#ifndef STBRP_SORT
|
||||
#include <stdlib.h>
|
||||
#define STBRP_SORT qsort
|
||||
#endif
|
||||
|
||||
#ifndef STBRP_ASSERT
|
||||
#include <assert.h>
|
||||
#define STBRP_ASSERT assert
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define STBRP__NOTUSED(v) (void)(v)
|
||||
#define STBRP__CDECL __cdecl
|
||||
#else
|
||||
#define STBRP__NOTUSED(v) (void)sizeof(v)
|
||||
#define STBRP__CDECL
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
STBRP__INIT_skyline = 1
|
||||
};
|
||||
|
||||
STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
|
||||
{
|
||||
switch (context->init_mode) {
|
||||
case STBRP__INIT_skyline:
|
||||
STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
|
||||
context->heuristic = heuristic;
|
||||
break;
|
||||
default:
|
||||
STBRP_ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
|
||||
{
|
||||
if (allow_out_of_mem)
|
||||
// if it's ok to run out of memory, then don't bother aligning them;
|
||||
// this gives better packing, but may fail due to OOM (even though
|
||||
// the rectangles easily fit). @TODO a smarter approach would be to only
|
||||
// quantize once we've hit OOM, then we could get rid of this parameter.
|
||||
context->align = 1;
|
||||
else {
|
||||
// if it's not ok to run out of memory, then quantize the widths
|
||||
// so that num_nodes is always enough nodes.
|
||||
//
|
||||
// I.e. num_nodes * align >= width
|
||||
// align >= width / num_nodes
|
||||
// align = ceil(width/num_nodes)
|
||||
|
||||
context->align = (context->width + context->num_nodes-1) / context->num_nodes;
|
||||
}
|
||||
}
|
||||
|
||||
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
|
||||
{
|
||||
int i;
|
||||
#ifndef STBRP_LARGE_RECTS
|
||||
STBRP_ASSERT(width <= 0xffff && height <= 0xffff);
|
||||
#endif
|
||||
|
||||
for (i=0; i < num_nodes-1; ++i)
|
||||
nodes[i].next = &nodes[i+1];
|
||||
nodes[i].next = NULL;
|
||||
context->init_mode = STBRP__INIT_skyline;
|
||||
context->heuristic = STBRP_HEURISTIC_Skyline_default;
|
||||
context->free_head = &nodes[0];
|
||||
context->active_head = &context->extra[0];
|
||||
context->width = width;
|
||||
context->height = height;
|
||||
context->num_nodes = num_nodes;
|
||||
stbrp_setup_allow_out_of_mem(context, 0);
|
||||
|
||||
// node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly)
|
||||
context->extra[0].x = 0;
|
||||
context->extra[0].y = 0;
|
||||
context->extra[0].next = &context->extra[1];
|
||||
context->extra[1].x = (stbrp_coord) width;
|
||||
#ifdef STBRP_LARGE_RECTS
|
||||
context->extra[1].y = (1<<30);
|
||||
#else
|
||||
context->extra[1].y = 65535;
|
||||
#endif
|
||||
context->extra[1].next = NULL;
|
||||
}
|
||||
|
||||
// find minimum y position if it starts at x1
|
||||
static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste)
|
||||
{
|
||||
stbrp_node *node = first;
|
||||
int x1 = x0 + width;
|
||||
int min_y, visited_width, waste_area;
|
||||
|
||||
STBRP__NOTUSED(c);
|
||||
|
||||
STBRP_ASSERT(first->x <= x0);
|
||||
|
||||
#if 0
|
||||
// skip in case we're past the node
|
||||
while (node->next->x <= x0)
|
||||
++node;
|
||||
#else
|
||||
STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency
|
||||
#endif
|
||||
|
||||
STBRP_ASSERT(node->x <= x0);
|
||||
|
||||
min_y = 0;
|
||||
waste_area = 0;
|
||||
visited_width = 0;
|
||||
while (node->x < x1) {
|
||||
if (node->y > min_y) {
|
||||
// raise min_y higher.
|
||||
// we've accounted for all waste up to min_y,
|
||||
// but we'll now add more waste for everything we've visted
|
||||
waste_area += visited_width * (node->y - min_y);
|
||||
min_y = node->y;
|
||||
// the first time through, visited_width might be reduced
|
||||
if (node->x < x0)
|
||||
visited_width += node->next->x - x0;
|
||||
else
|
||||
visited_width += node->next->x - node->x;
|
||||
} else {
|
||||
// add waste area
|
||||
int under_width = node->next->x - node->x;
|
||||
if (under_width + visited_width > width)
|
||||
under_width = width - visited_width;
|
||||
waste_area += under_width * (min_y - node->y);
|
||||
visited_width += under_width;
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
*pwaste = waste_area;
|
||||
return min_y;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x,y;
|
||||
stbrp_node **prev_link;
|
||||
} stbrp__findresult;
|
||||
|
||||
static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height)
|
||||
{
|
||||
int best_waste = (1<<30), best_x, best_y = (1 << 30);
|
||||
stbrp__findresult fr;
|
||||
stbrp_node **prev, *node, *tail, **best = NULL;
|
||||
|
||||
// align to multiple of c->align
|
||||
width = (width + c->align - 1);
|
||||
width -= width % c->align;
|
||||
STBRP_ASSERT(width % c->align == 0);
|
||||
|
||||
node = c->active_head;
|
||||
prev = &c->active_head;
|
||||
while (node->x + width <= c->width) {
|
||||
int y,waste;
|
||||
y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
|
||||
if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL
|
||||
// bottom left
|
||||
if (y < best_y) {
|
||||
best_y = y;
|
||||
best = prev;
|
||||
}
|
||||
} else {
|
||||
// best-fit
|
||||
if (y + height <= c->height) {
|
||||
// can only use it if it first vertically
|
||||
if (y < best_y || (y == best_y && waste < best_waste)) {
|
||||
best_y = y;
|
||||
best_waste = waste;
|
||||
best = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
prev = &node->next;
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
best_x = (best == NULL) ? 0 : (*best)->x;
|
||||
|
||||
// if doing best-fit (BF), we also have to try aligning right edge to each node position
|
||||
//
|
||||
// e.g, if fitting
|
||||
//
|
||||
// ____________________
|
||||
// |____________________|
|
||||
//
|
||||
// into
|
||||
//
|
||||
// | |
|
||||
// | ____________|
|
||||
// |____________|
|
||||
//
|
||||
// then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned
|
||||
//
|
||||
// This makes BF take about 2x the time
|
||||
|
||||
if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
|
||||
tail = c->active_head;
|
||||
node = c->active_head;
|
||||
prev = &c->active_head;
|
||||
// find first node that's admissible
|
||||
while (tail->x < width)
|
||||
tail = tail->next;
|
||||
while (tail) {
|
||||
int xpos = tail->x - width;
|
||||
int y,waste;
|
||||
STBRP_ASSERT(xpos >= 0);
|
||||
// find the left position that matches this
|
||||
while (node->next->x <= xpos) {
|
||||
prev = &node->next;
|
||||
node = node->next;
|
||||
}
|
||||
STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
|
||||
y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
|
||||
if (y + height < c->height) {
|
||||
if (y <= best_y) {
|
||||
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
|
||||
best_x = xpos;
|
||||
STBRP_ASSERT(y <= best_y);
|
||||
best_y = y;
|
||||
best_waste = waste;
|
||||
best = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
tail = tail->next;
|
||||
}
|
||||
}
|
||||
|
||||
fr.prev_link = best;
|
||||
fr.x = best_x;
|
||||
fr.y = best_y;
|
||||
return fr;
|
||||
}
|
||||
|
||||
static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
|
||||
{
|
||||
// find best position according to heuristic
|
||||
stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
|
||||
stbrp_node *node, *cur;
|
||||
|
||||
// bail if:
|
||||
// 1. it failed
|
||||
// 2. the best node doesn't fit (we don't always check this)
|
||||
// 3. we're out of memory
|
||||
if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
|
||||
res.prev_link = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
// on success, create new node
|
||||
node = context->free_head;
|
||||
node->x = (stbrp_coord) res.x;
|
||||
node->y = (stbrp_coord) (res.y + height);
|
||||
|
||||
context->free_head = node->next;
|
||||
|
||||
// insert the new node into the right starting point, and
|
||||
// let 'cur' point to the remaining nodes needing to be
|
||||
// stiched back in
|
||||
|
||||
cur = *res.prev_link;
|
||||
if (cur->x < res.x) {
|
||||
// preserve the existing one, so start testing with the next one
|
||||
stbrp_node *next = cur->next;
|
||||
cur->next = node;
|
||||
cur = next;
|
||||
} else {
|
||||
*res.prev_link = node;
|
||||
}
|
||||
|
||||
// from here, traverse cur and free the nodes, until we get to one
|
||||
// that shouldn't be freed
|
||||
while (cur->next && cur->next->x <= res.x + width) {
|
||||
stbrp_node *next = cur->next;
|
||||
// move the current node to the free list
|
||||
cur->next = context->free_head;
|
||||
context->free_head = cur;
|
||||
cur = next;
|
||||
}
|
||||
|
||||
// stitch the list back in
|
||||
node->next = cur;
|
||||
|
||||
if (cur->x < res.x + width)
|
||||
cur->x = (stbrp_coord) (res.x + width);
|
||||
|
||||
#ifdef _DEBUG
|
||||
cur = context->active_head;
|
||||
while (cur->x < context->width) {
|
||||
STBRP_ASSERT(cur->x < cur->next->x);
|
||||
cur = cur->next;
|
||||
}
|
||||
STBRP_ASSERT(cur->next == NULL);
|
||||
|
||||
{
|
||||
int count=0;
|
||||
cur = context->active_head;
|
||||
while (cur) {
|
||||
cur = cur->next;
|
||||
++count;
|
||||
}
|
||||
cur = context->free_head;
|
||||
while (cur) {
|
||||
cur = cur->next;
|
||||
++count;
|
||||
}
|
||||
STBRP_ASSERT(count == context->num_nodes+2);
|
||||
}
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
|
||||
{
|
||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||
const stbrp_rect *q = (const stbrp_rect *) b;
|
||||
if (p->h > q->h)
|
||||
return -1;
|
||||
if (p->h < q->h)
|
||||
return 1;
|
||||
return (p->w > q->w) ? -1 : (p->w < q->w);
|
||||
}
|
||||
|
||||
static int STBRP__CDECL rect_original_order(const void *a, const void *b)
|
||||
{
|
||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||
const stbrp_rect *q = (const stbrp_rect *) b;
|
||||
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
|
||||
}
|
||||
|
||||
#ifdef STBRP_LARGE_RECTS
|
||||
#define STBRP__MAXVAL 0xffffffff
|
||||
#else
|
||||
#define STBRP__MAXVAL 0xffff
|
||||
#endif
|
||||
|
||||
STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
|
||||
{
|
||||
int i, all_rects_packed = 1;
|
||||
|
||||
// we use the 'was_packed' field internally to allow sorting/unsorting
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
rects[i].was_packed = i;
|
||||
#ifndef STBRP_LARGE_RECTS
|
||||
STBRP_ASSERT(rects[i].w <= 0xffff && rects[i].h <= 0xffff);
|
||||
#endif
|
||||
}
|
||||
|
||||
// sort according to heuristic
|
||||
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
|
||||
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
if (rects[i].w == 0 || rects[i].h == 0) {
|
||||
rects[i].x = rects[i].y = 0; // empty rect needs no space
|
||||
} else {
|
||||
stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
|
||||
if (fr.prev_link) {
|
||||
rects[i].x = (stbrp_coord) fr.x;
|
||||
rects[i].y = (stbrp_coord) fr.y;
|
||||
} else {
|
||||
rects[i].x = rects[i].y = STBRP__MAXVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unsort
|
||||
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
|
||||
|
||||
// set was_packed flags and all_rects_packed status
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
|
||||
if (!rects[i].was_packed)
|
||||
all_rects_packed = 0;
|
||||
}
|
||||
|
||||
// return the all_rects_packed status
|
||||
return all_rects_packed;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
This software is available under 2 licenses -- choose whichever you prefer.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE A - MIT License
|
||||
Copyright (c) 2017 Sean Barrett
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
||||
This is free and unencumbered software released into the public domain.
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||
software, either in source code form or as a compiled binary, for any purpose,
|
||||
commercial or non-commercial, and by any means.
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||
software dedicate any and all copyright interest in the software to the public
|
||||
domain. We make this dedication for the benefit of the public at large and to
|
||||
the detriment of our heirs and successors. We intend this dedication to be an
|
||||
overt act of relinquishment in perpetuity of all present and future rights to
|
||||
this software under copyright law.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,16 @@
|
|||
[
|
||||
{
|
||||
"Id": "imgui",
|
||||
"Name": "Dear ImGui",
|
||||
"QDocModule": "qtrhi",
|
||||
"Description": "Dear ImGui",
|
||||
"QtUsage": "Used in tests to demonstrate and verify the integration of an external GUI library.",
|
||||
|
||||
"Homepage": "https://github.com/ocornut/imgui",
|
||||
"Version": "v1.66b",
|
||||
"License": "MIT License",
|
||||
"LicenseId": "MIT",
|
||||
"LicenseFile": "LICENSE.txt",
|
||||
"Copyright": "Copyright (c) 2014-2018 Omar Cornut"
|
||||
}
|
||||
]
|
||||
|
|
@ -47,6 +47,7 @@
|
|||
#include <Qt3DRender/qfilterkey.h>
|
||||
#include <Qt3DRender/qfrustumculling.h>
|
||||
#include <Qt3DRender/qrendersurfaceselector.h>
|
||||
#include <Qt3DRender/qdebugoverlay.h>
|
||||
|
||||
static void initResources()
|
||||
{
|
||||
|
|
@ -68,6 +69,7 @@ QForwardRendererPrivate::QForwardRendererPrivate()
|
|||
, m_cameraSelector(new QCameraSelector())
|
||||
, m_clearBuffer(new QClearBuffers())
|
||||
, m_frustumCulling(new QFrustumCulling())
|
||||
, m_debugOverlay(new QDebugOverlay())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -77,13 +79,14 @@ void QForwardRendererPrivate::init()
|
|||
|
||||
initResources();
|
||||
|
||||
m_debugOverlay->setParent(m_frustumCulling);
|
||||
m_frustumCulling->setParent(m_clearBuffer);
|
||||
m_clearBuffer->setParent(m_cameraSelector);
|
||||
m_cameraSelector->setParent(m_viewport);
|
||||
m_viewport->setParent(m_surfaceSelector);
|
||||
m_surfaceSelector->setParent(q);
|
||||
|
||||
m_viewport->setNormalizedRect(QRectF(0.0f, 0.0f, 1.0f, 1.0f));
|
||||
m_viewport->setNormalizedRect(QRectF(0.0, 0.0, 1.0, 1.0));
|
||||
m_clearBuffer->setClearColor(Qt::white);
|
||||
m_clearBuffer->setBuffers(QClearBuffers::ColorDepthBuffer);
|
||||
|
||||
|
|
@ -146,6 +149,7 @@ QForwardRenderer::QForwardRenderer(QNode *parent)
|
|||
QObject::connect(d->m_surfaceSelector, &QRenderSurfaceSelector::externalRenderTargetSizeChanged, this, &QForwardRenderer::externalRenderTargetSizeChanged);
|
||||
QObject::connect(d->m_frustumCulling, &QFrustumCulling::enabledChanged, this, &QForwardRenderer::frustumCullingEnabledChanged);
|
||||
QObject::connect(d->m_viewport, &QViewport::gammaChanged, this, &QForwardRenderer::gammaChanged);
|
||||
QObject::connect(d->m_debugOverlay, &QDebugOverlay::enabledChanged, this, &QForwardRenderer::showDebugOverlayChanged);
|
||||
d->init();
|
||||
}
|
||||
|
||||
|
|
@ -201,6 +205,12 @@ void QForwardRenderer::setGamma(float gamma)
|
|||
d->m_viewport->setGamma(gamma);
|
||||
}
|
||||
|
||||
void QForwardRenderer::setShowDebugOverlay(bool showDebugOverlay)
|
||||
{
|
||||
Q_D(QForwardRenderer);
|
||||
d->m_debugOverlay->setEnabled(showDebugOverlay);
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty rect ForwardRenderer::viewportRect
|
||||
|
||||
|
|
@ -356,6 +366,12 @@ float QForwardRenderer::gamma() const
|
|||
return d->m_viewport->gamma();
|
||||
}
|
||||
|
||||
bool QForwardRenderer::showDebugOverlay() const
|
||||
{
|
||||
Q_D(const QForwardRenderer);
|
||||
return d->m_debugOverlay->isEnabled();
|
||||
}
|
||||
|
||||
} // namespace Qt3DExtras
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ class Q_3DEXTRASSHARED_EXPORT QForwardRenderer : public Qt3DRender::QTechniqueFi
|
|||
Q_PROPERTY(QSize externalRenderTargetSize READ externalRenderTargetSize WRITE setExternalRenderTargetSize NOTIFY externalRenderTargetSizeChanged)
|
||||
Q_PROPERTY(bool frustumCulling READ isFrustumCullingEnabled WRITE setFrustumCullingEnabled NOTIFY frustumCullingEnabledChanged)
|
||||
Q_PROPERTY(float gamma READ gamma WRITE setGamma NOTIFY gammaChanged REVISION 9)
|
||||
Q_PROPERTY(bool showDebugOverlay READ showDebugOverlay WRITE setShowDebugOverlay NOTIFY showDebugOverlayChanged REVISION 15)
|
||||
public:
|
||||
explicit QForwardRenderer(Qt3DCore::QNode *parent = nullptr);
|
||||
~QForwardRenderer();
|
||||
|
|
@ -78,6 +79,7 @@ public:
|
|||
QSize externalRenderTargetSize() const;
|
||||
bool isFrustumCullingEnabled() const;
|
||||
float gamma() const;
|
||||
bool showDebugOverlay() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void setViewportRect(const QRectF &viewportRect);
|
||||
|
|
@ -88,6 +90,7 @@ public Q_SLOTS:
|
|||
void setExternalRenderTargetSize(const QSize &size);
|
||||
void setFrustumCullingEnabled(bool enabled);
|
||||
void setGamma(float gamma);
|
||||
void setShowDebugOverlay(bool showDebugOverlay);
|
||||
|
||||
Q_SIGNALS:
|
||||
void viewportRectChanged(const QRectF &viewportRect);
|
||||
|
|
@ -98,6 +101,7 @@ Q_SIGNALS:
|
|||
void externalRenderTargetSizeChanged(const QSize &size);
|
||||
void frustumCullingEnabledChanged(bool enabled);
|
||||
void gammaChanged(float gamma);
|
||||
void showDebugOverlayChanged(bool showDebugOverlay);
|
||||
|
||||
private:
|
||||
Q_DECLARE_PRIVATE(QForwardRenderer)
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ class QClearBuffers;
|
|||
class QCameraSelector;
|
||||
class QFrustumCulling;
|
||||
class QRenderSurfaceSelector;
|
||||
class QDebugOverlay;
|
||||
|
||||
} // namespace Qt3DRender
|
||||
|
||||
|
|
@ -78,6 +79,7 @@ public:
|
|||
Qt3DRender::QCameraSelector *m_cameraSelector;
|
||||
Qt3DRender::QClearBuffers *m_clearBuffer;
|
||||
Qt3DRender::QFrustumCulling *m_frustumCulling;
|
||||
Qt3DRender::QDebugOverlay *m_debugOverlay;
|
||||
|
||||
void init();
|
||||
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ void Qt3DQuick3DExtrasPlugin::registerTypes(const char *uri)
|
|||
qmlRegisterType<Qt3DExtras::QForwardRenderer>(uri, 2, 0, "ForwardRenderer");
|
||||
qmlRegisterType<Qt3DExtras::QForwardRenderer, 9>(uri, 2, 9, "ForwardRenderer");
|
||||
qmlRegisterType<Qt3DExtras::QForwardRenderer, 14>(uri, 2, 14, "ForwardRenderer");
|
||||
qmlRegisterType<Qt3DExtras::QForwardRenderer, 15>(uri, 2, 15, "ForwardRenderer");
|
||||
|
||||
// Entities
|
||||
qmlRegisterType<Qt3DExtras::QSkyboxEntity>(uri, 2, 0, "SkyboxEntity");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB).
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt3D module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include <Qt3DRender/private/qdebugoverlay_p.h>
|
||||
#include <Qt3DRender/private/debugoverlay_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace Qt3DRender {
|
||||
|
||||
namespace Render {
|
||||
|
||||
DebugOverlay::DebugOverlay()
|
||||
: FrameGraphNode(FrameGraphNode::DebugOverlay, QBackendNode::ReadWrite)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
} //Render
|
||||
|
||||
} //Qt3DRender
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB).
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt3D module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef DEBUGOVERLAY_P_H
|
||||
#define DEBUGOVERLAY_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of other Qt classes. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <Qt3DRender/private/qdebugoverlay_p.h>
|
||||
#include <Qt3DRender/private/framegraphnode_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace Qt3DRender {
|
||||
|
||||
namespace Render {
|
||||
|
||||
class Q_AUTOTEST_EXPORT DebugOverlay : public FrameGraphNode
|
||||
{
|
||||
public:
|
||||
DebugOverlay();
|
||||
};
|
||||
|
||||
} //Render
|
||||
|
||||
} //Qt3DRender
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // DEBUGOVERLAY_P_H
|
||||
|
|
@ -69,7 +69,10 @@ HEADERS += \
|
|||
$$PWD/nopicking_p.h \
|
||||
$$PWD/qsubtreeenabler.h \
|
||||
$$PWD/qsubtreeenabler_p.h \
|
||||
$$PWD/subtreeenabler_p.h
|
||||
$$PWD/subtreeenabler_p.h \
|
||||
$$PWD/qdebugoverlay.h \
|
||||
$$PWD/qdebugoverlay_p.h \
|
||||
$$PWD/debugoverlay_p.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/cameraselectornode.cpp \
|
||||
|
|
@ -119,4 +122,6 @@ SOURCES += \
|
|||
$$PWD/qnopicking.cpp \
|
||||
$$PWD/nopicking.cpp \
|
||||
$$PWD/qsubtreeenabler.cpp \
|
||||
$$PWD/subtreeenabler.cpp
|
||||
$$PWD/subtreeenabler.cpp \
|
||||
$$PWD/qdebugoverlay.cpp \
|
||||
$$PWD/debugoverlay.cpp
|
||||
|
|
|
|||
|
|
@ -104,7 +104,8 @@ public:
|
|||
BlitFramebuffer,
|
||||
SetFence,
|
||||
WaitFence,
|
||||
NoPicking
|
||||
NoPicking,
|
||||
DebugOverlay,
|
||||
};
|
||||
FrameGraphNodeType nodeType() const { return m_nodeType; }
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB).
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt3D module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL3$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or later as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.GPL included in
|
||||
** the packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 2.0 requirements will be
|
||||
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qdebugoverlay.h"
|
||||
#include "qdebugoverlay_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace Qt3DRender {
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
QDebugOverlayPrivate::QDebugOverlayPrivate()
|
||||
: QFrameGraphNodePrivate()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
QDebugOverlayPrivate::~QDebugOverlayPrivate() = default;
|
||||
|
||||
/*!
|
||||
* The constructor creates an instance with the specified \a parent.
|
||||
*/
|
||||
QDebugOverlay::QDebugOverlay(Qt3DCore::QNode *parent)
|
||||
: QFrameGraphNode(*new QDebugOverlayPrivate, parent)
|
||||
{
|
||||
}
|
||||
|
||||
} // Qt3DRender
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB).
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt3D module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL3$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or later as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.GPL included in
|
||||
** the packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 2.0 requirements will be
|
||||
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QDEBUGOVERLOAY_H
|
||||
#define QDEBUGOVERLOAY_H
|
||||
|
||||
#include <Qt3DRender/QFrameGraphNode>
|
||||
#include <QtGui/QImage>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace Qt3DRender {
|
||||
|
||||
class QDebugOverlayPrivate;
|
||||
|
||||
class Q_3DRENDERSHARED_EXPORT QDebugOverlay : public QFrameGraphNode
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QDebugOverlay(Qt3DCore::QNode *parent = nullptr);
|
||||
|
||||
private:
|
||||
Q_DECLARE_PRIVATE(QDebugOverlay)
|
||||
};
|
||||
|
||||
} // Qt3DRender
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QDEBUGOVERLOAY_H
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB).
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt3D module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL3$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or later as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.GPL included in
|
||||
** the packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 2.0 requirements will be
|
||||
** met: http://www.gnu.org/licenses/gpl-2.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QDEBUGOVERLAY_P_H
|
||||
#define QDEBUGOVERLAY_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of other Qt classes. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <Qt3DRender/qdebugoverlay.h>
|
||||
#include <Qt3DRender/private/qframegraphnode_p.h>
|
||||
|
||||
#include <QtCore/qmutex.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace Qt3DRender {
|
||||
|
||||
class QDebugOverlayPrivate : public QFrameGraphNodePrivate
|
||||
{
|
||||
public:
|
||||
QDebugOverlayPrivate();
|
||||
~QDebugOverlayPrivate();
|
||||
|
||||
Q_DECLARE_PUBLIC(QDebugOverlay)
|
||||
};
|
||||
|
||||
} // Qt3DRender
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QDEBUGOVERLAY_P_H
|
||||
|
|
@ -92,6 +92,7 @@
|
|||
#include <Qt3DRender/qwaitfence.h>
|
||||
#include <Qt3DRender/qshaderimage.h>
|
||||
#include <Qt3DRender/qsubtreeenabler.h>
|
||||
#include <Qt3DRender/qdebugoverlay.h>
|
||||
#include <Qt3DCore/qarmature.h>
|
||||
#include <Qt3DCore/qjoint.h>
|
||||
#include <Qt3DCore/qskeletonloader.h>
|
||||
|
|
@ -159,6 +160,7 @@
|
|||
#include <Qt3DRender/private/setfence_p.h>
|
||||
#include <Qt3DRender/private/waitfence_p.h>
|
||||
#include <Qt3DRender/private/shaderimage_p.h>
|
||||
#include <Qt3DRender/private/debugoverlay_p.h>
|
||||
|
||||
#include <private/qrenderpluginfactory_p.h>
|
||||
#include <private/qrenderplugin_p.h>
|
||||
|
|
@ -330,6 +332,7 @@ void QRenderAspectPrivate::registerBackendTypes()
|
|||
q->registerBackendType<QWaitFence, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::WaitFence, QWaitFence> >::create(m_renderer));
|
||||
q->registerBackendType<QNoPicking, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::NoPicking, QNoPicking> >::create(m_renderer));
|
||||
q->registerBackendType<QSubtreeEnabler, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::SubtreeEnabler, QSubtreeEnabler> >::create(m_renderer));
|
||||
q->registerBackendType<QDebugOverlay, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::DebugOverlay, QDebugOverlay> >::create(m_renderer));
|
||||
|
||||
// Picking
|
||||
q->registerBackendType<QObjectPicker, true>(QSharedPointer<Render::NodeFunctor<Render::ObjectPicker, Render::ObjectPickerManager> >::create(m_renderer));
|
||||
|
|
@ -404,6 +407,7 @@ void QRenderAspectPrivate::unregisterBackendTypes()
|
|||
unregisterBackendType<QSetFence>();
|
||||
unregisterBackendType<QWaitFence>();
|
||||
unregisterBackendType<QSubtreeEnabler>();
|
||||
unregisterBackendType<QDebugOverlay>();
|
||||
|
||||
// Picking
|
||||
unregisterBackendType<QObjectPicker>();
|
||||
|
|
@ -565,7 +569,6 @@ QVariant QRenderAspect::executeCommand(const QStringList &args)
|
|||
}
|
||||
if (args.front() == QLatin1String("scenegraph"))
|
||||
return droot->dumpSceneGraph();
|
||||
return {};
|
||||
}
|
||||
|
||||
return d->m_renderer->executeCommand(args);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
INCLUDEPATH += $$PWD
|
||||
|
||||
include($$QT3D_ROOT/src/3rdparty/imgui/imgui.pri)
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/imguirenderer_p.h \
|
||||
$$PWD/imconfig.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/imguirenderer.cpp
|
||||
|
|
@ -0,0 +1,717 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB).
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt3D module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
* Based on https://github.com/seanchas116/qtimgui/
|
||||
*
|
||||
* MIT License https://github.com/seanchas116/qtimgui/blob/master/LICENSE
|
||||
*
|
||||
*/
|
||||
|
||||
#include "imguirenderer_p.h"
|
||||
#include <Qt3DRender/private/renderview_p.h>
|
||||
#include <Qt3DRender/private/renderer_p.h>
|
||||
#include <Qt3DRender/private/geometryrenderermanager_p.h>
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QGuiApplication>
|
||||
#include <QMouseEvent>
|
||||
#include <QClipboard>
|
||||
#include <QCursor>
|
||||
#include <QOpenGLExtraFunctions>
|
||||
|
||||
#include "imgui.h"
|
||||
|
||||
#ifndef GL_VERTEX_ARRAY_BINDING
|
||||
// just for building on some platforms, won't run anyway as this requires GL/ES > 2
|
||||
#define GL_VERTEX_ARRAY_BINDING 0x85B5
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace Qt3DRender;
|
||||
using namespace Render;
|
||||
using namespace Render::Debug;
|
||||
|
||||
namespace {
|
||||
|
||||
const QHash<int, ImGuiKey> keyMap = {
|
||||
{ Qt::Key_Tab, ImGuiKey_Tab },
|
||||
{ Qt::Key_Left, ImGuiKey_LeftArrow },
|
||||
{ Qt::Key_Right, ImGuiKey_RightArrow },
|
||||
{ Qt::Key_Up, ImGuiKey_UpArrow },
|
||||
{ Qt::Key_Down, ImGuiKey_DownArrow },
|
||||
{ Qt::Key_PageUp, ImGuiKey_PageUp },
|
||||
{ Qt::Key_PageDown, ImGuiKey_PageDown },
|
||||
{ Qt::Key_Home, ImGuiKey_Home },
|
||||
{ Qt::Key_End, ImGuiKey_End },
|
||||
{ Qt::Key_Delete, ImGuiKey_Delete },
|
||||
{ Qt::Key_Backspace, ImGuiKey_Backspace },
|
||||
{ Qt::Key_Enter, ImGuiKey_Enter },
|
||||
{ Qt::Key_Escape, ImGuiKey_Escape },
|
||||
{ Qt::Key_A, ImGuiKey_A },
|
||||
{ Qt::Key_C, ImGuiKey_C },
|
||||
{ Qt::Key_V, ImGuiKey_V },
|
||||
{ Qt::Key_X, ImGuiKey_X },
|
||||
{ Qt::Key_Y, ImGuiKey_Y },
|
||||
{ Qt::Key_Z, ImGuiKey_Z },
|
||||
};
|
||||
|
||||
QByteArray g_currentClipboardText;
|
||||
|
||||
// doesn't handle primitive restart when using indexes
|
||||
int vertexToPrimitiveCount(Qt3DRender::QGeometryRenderer::PrimitiveType primitiveType, int numVertices) {
|
||||
int nPrimitives = 0;
|
||||
switch (primitiveType) {
|
||||
case QGeometryRenderer::Points:
|
||||
case QGeometryRenderer::LineLoop: nPrimitives += numVertices; break;
|
||||
case QGeometryRenderer::Triangles: nPrimitives += numVertices / 3; break;
|
||||
case QGeometryRenderer::Lines: nPrimitives += numVertices / 2; break;
|
||||
case QGeometryRenderer::TriangleFan:
|
||||
case QGeometryRenderer::TriangleStrip:
|
||||
case QGeometryRenderer::LineStrip: nPrimitives += numVertices - 1; break;
|
||||
case QGeometryRenderer::TrianglesAdjacency: nPrimitives += numVertices / 6; break;
|
||||
case QGeometryRenderer::TriangleStripAdjacency:
|
||||
case QGeometryRenderer::LineStripAdjacency: nPrimitives += numVertices / 2 - 1; break;
|
||||
case QGeometryRenderer::LinesAdjacency: nPrimitives += numVertices / 4; break;
|
||||
case QGeometryRenderer::Patches: nPrimitives += 1;
|
||||
}
|
||||
return nPrimitives;
|
||||
}
|
||||
|
||||
const char *primitiveTypeName(Qt3DRender::QGeometryRenderer::PrimitiveType primitiveType) {
|
||||
switch (primitiveType) {
|
||||
case QGeometryRenderer::Points: return "Points";
|
||||
case QGeometryRenderer::LineLoop: return "LineLoop";
|
||||
case QGeometryRenderer::Triangles: return "Triangles";
|
||||
case QGeometryRenderer::TrianglesAdjacency: return "TriangleAdjacency";
|
||||
case QGeometryRenderer::TriangleFan: return "TriangleFan";
|
||||
case QGeometryRenderer::TriangleStrip: return "TriangleStrip";
|
||||
case QGeometryRenderer::TriangleStripAdjacency: return "TriangleStringAdjacency";
|
||||
case QGeometryRenderer::LineStrip: return "LineStrip";
|
||||
case QGeometryRenderer::LineStripAdjacency: return "LineStripAdjacency";
|
||||
case QGeometryRenderer::Lines: return "Lines";
|
||||
case QGeometryRenderer::LinesAdjacency: return "LinesAdjacency";
|
||||
case QGeometryRenderer::Patches: return "Patches";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
ImGuiRenderer::ImGuiRenderer(Renderer *renderer)
|
||||
: m_renderer(renderer)
|
||||
{
|
||||
ImGui::CreateContext();
|
||||
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
for (ImGuiKey key : keyMap.values())
|
||||
io.KeyMap[key] = key;
|
||||
|
||||
#ifndef QT_NO_CLIPBOARD
|
||||
io.SetClipboardTextFn = [](void *user_data, const char *text) {
|
||||
Q_UNUSED(user_data)
|
||||
QGuiApplication::clipboard()->setText(QString::fromLatin1(text));
|
||||
};
|
||||
io.GetClipboardTextFn = [](void *user_data) {
|
||||
Q_UNUSED(user_data)
|
||||
g_currentClipboardText = QGuiApplication::clipboard()->text().toUtf8();
|
||||
return static_cast<const char *>(g_currentClipboardText.data());
|
||||
};
|
||||
#endif
|
||||
|
||||
std::fill(std::begin(m_fpsLog), std::end(m_fpsLog), 0.f);
|
||||
std::fill(std::begin(m_jobsLog), std::end(m_jobsLog), 0.f);
|
||||
m_fpsRange.first = m_fpsRange.second = 0.f;
|
||||
m_jobsRange.first = m_jobsRange.second = 0.f;
|
||||
}
|
||||
|
||||
void ImGuiRenderer::renderDebugOverlay(const QVector<RenderView *> &renderViews, const RenderView *renderView, int jobsInLastFrame)
|
||||
{
|
||||
if (!newFrame(renderView))
|
||||
return;
|
||||
|
||||
const int renderViewsCount = renderViews.size();
|
||||
|
||||
int logIndex = qMin(IMGUI_PERF_LOG_SIZE - 1, ImGui::GetFrameCount());
|
||||
if (logIndex == IMGUI_PERF_LOG_SIZE - 1) {
|
||||
std::rotate(std::begin(m_fpsLog), std::begin(m_fpsLog) + 1, std::end(m_fpsLog));
|
||||
std::rotate(std::begin(m_jobsLog), std::begin(m_jobsLog) + 1, std::end(m_jobsLog));
|
||||
}
|
||||
m_fpsLog[logIndex] = ImGui::GetIO().Framerate;
|
||||
m_fpsRange.first = m_fpsRange.second = 0.f;
|
||||
for (float v: m_fpsLog) {
|
||||
m_fpsRange.first = qMin(m_fpsRange.first, qMax(v - 5.f, 0.f));
|
||||
m_fpsRange.second = qMax(m_fpsRange.second, v + 2.f);
|
||||
}
|
||||
m_jobsLog[logIndex] = jobsInLastFrame;
|
||||
m_jobsRange.first = m_jobsRange.second = 0.f;
|
||||
for (float v: m_jobsLog) {
|
||||
m_jobsRange.first = qMin(m_jobsRange.first, qMax(v - 5.f, 0.f));
|
||||
m_jobsRange.second = qMax(m_jobsRange.second, v + 2.f);
|
||||
}
|
||||
|
||||
{
|
||||
bool pj = m_renderer->services()->systemInformation()->isTraceEnabled();
|
||||
bool pg = m_renderer->services()->systemInformation()->isGraphicsTraceEnabled();
|
||||
|
||||
ImGui::Begin("Qt3D Profiling");
|
||||
char caption[50];
|
||||
sprintf(caption, "Avg %.3f ms/frame (%.1f FPS)", static_cast<double>(1000.0f / ImGui::GetIO().Framerate), static_cast<double>(ImGui::GetIO().Framerate));
|
||||
ImGui::PlotLines("FPS", m_fpsLog, logIndex + 1, 0, caption, m_fpsRange.first, m_fpsRange.second, ImVec2(0, 80));
|
||||
ImGui::PlotHistogram("Jobs", m_jobsLog, logIndex + 1, 0, nullptr, m_jobsRange.first, m_jobsRange.second, ImVec2(0, 80));
|
||||
ImGui::Text("Profiling: ");
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Checkbox("Jobs", &pj))
|
||||
QMetaObject::invokeMethod(m_renderer->services()->systemInformation(), "setTraceEnabled", Qt::QueuedConnection, Q_ARG(bool, pj));
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Checkbox("GL", &pg))
|
||||
QMetaObject::invokeMethod(m_renderer->services()->systemInformation(), "setGraphicsTraceEnabled", Qt::QueuedConnection, Q_ARG(bool, pg));
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Reveal"))
|
||||
QMetaObject::invokeMethod(m_renderer->services()->systemInformation(), "revealLogFolder", Qt::QueuedConnection);
|
||||
|
||||
int nCommands = 0;
|
||||
int nVertices = 0;
|
||||
int nPrimitives = 0;
|
||||
QSet<HGeometryRenderer> inUseGeometries;
|
||||
QSet<Qt3DCore::QNodeId> inUseTextures;
|
||||
for (int j=0; j<renderViewsCount; j++) {
|
||||
const auto &commands = renderViews.at(j)->commands();
|
||||
nCommands += commands.size();
|
||||
for (int k=0; k<commands.size(); k++) {
|
||||
const RenderCommand &command = commands.at(k);
|
||||
if (command.m_type != RenderCommand::Draw)
|
||||
continue;
|
||||
nVertices += command.m_primitiveCount;
|
||||
nPrimitives += vertexToPrimitiveCount(command.m_primitiveType, command.m_primitiveCount);
|
||||
inUseGeometries.insert(command.m_geometryRenderer);
|
||||
const auto &textures = command.m_parameterPack.textures();
|
||||
for (const auto &ns: textures)
|
||||
inUseTextures.insert(ns.nodeId);
|
||||
}
|
||||
}
|
||||
|
||||
auto columnNumber = [](int i) {
|
||||
if (i == 0)
|
||||
ImGui::Text("--");
|
||||
else
|
||||
ImGui::Text(" %d", i);
|
||||
ImGui::NextColumn();
|
||||
};
|
||||
auto column2Numbers = [](int i, int of) {
|
||||
if (of == 0)
|
||||
ImGui::Text("--");
|
||||
else
|
||||
ImGui::Text(" %d of %d", i, of);
|
||||
ImGui::NextColumn();
|
||||
};
|
||||
|
||||
ImGui::Columns(5);
|
||||
ImGui::Separator();
|
||||
for (auto s: {"Jobs", "RV", "Cmds", "Verts", "Prims"}) {
|
||||
ImGui::Text("#%s", s);
|
||||
ImGui::NextColumn();
|
||||
}
|
||||
for (auto s: {jobsInLastFrame, renderViewsCount, nCommands, nVertices, nPrimitives})
|
||||
columnNumber(s);
|
||||
|
||||
ImGui::Columns(3);
|
||||
ImGui::Separator();
|
||||
for (auto s: {"Entities", "Geometries", "Textures"}) {
|
||||
ImGui::Text("#%s", s);
|
||||
ImGui::NextColumn();
|
||||
}
|
||||
columnNumber(m_renderer->nodeManagers()->renderNodesManager()->count());
|
||||
column2Numbers(inUseGeometries.size(), m_renderer->nodeManagers()->geometryRendererManager()->count());
|
||||
column2Numbers(inUseTextures.size(), m_renderer->nodeManagers()->textureManager()->count());
|
||||
|
||||
ImGui::Columns(1);
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Show:");
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("GL Info"))
|
||||
m_showGLInfoWindow = !m_showGLInfoWindow;
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Render Views"))
|
||||
m_showRenderDetailsWindow = !m_showRenderDetailsWindow;
|
||||
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Dump:");
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("SceneGraph##1"))
|
||||
QMetaObject::invokeMethod(m_renderer->services()->systemInformation(), "dumpCommand",
|
||||
Qt::QueuedConnection, Q_ARG(QString, QLatin1String("render scenegraph")));
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("FrameGraph##1"))
|
||||
QMetaObject::invokeMethod(m_renderer->services()->systemInformation(), "dumpCommand",
|
||||
Qt::QueuedConnection, Q_ARG(QString, QLatin1String("render framegraph")));
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("FrameGraph Paths##1"))
|
||||
QMetaObject::invokeMethod(m_renderer->services()->systemInformation(), "dumpCommand",
|
||||
Qt::QueuedConnection, Q_ARG(QString, QLatin1String("render framepaths")));
|
||||
|
||||
ImGui::End();
|
||||
|
||||
if (m_showGLInfoWindow)
|
||||
showGLInfo();
|
||||
if (m_showRenderDetailsWindow)
|
||||
showRenderDetails(renderViews);
|
||||
}
|
||||
|
||||
ImGui::Render();
|
||||
renderDrawList(ImGui::GetDrawData());
|
||||
}
|
||||
|
||||
void ImGuiRenderer::showGLInfo()
|
||||
{
|
||||
const GraphicsApiFilterData *contextInfo = m_renderer->submissionContext()->contextInfo();
|
||||
|
||||
ImGui::Begin("Open GL Details", &m_showGLInfoWindow);
|
||||
|
||||
ImGui::Text("API: %s %d.%d", contextInfo->m_api == QGraphicsApiFilter::OpenGL ? "OpenGL" : "OpenGLES"
|
||||
, contextInfo->m_major, contextInfo->m_minor);
|
||||
if (contextInfo->m_api == QGraphicsApiFilter::OpenGL)
|
||||
ImGui::Text("Profile: %s", contextInfo->m_profile == QGraphicsApiFilter::CoreProfile ? "Core" :
|
||||
contextInfo->m_profile == QGraphicsApiFilter::CompatibilityProfile ? "Compatibity" : "Node");
|
||||
|
||||
// TODO show capabilities
|
||||
GLint maxTextureSize, maxTextureUnits;
|
||||
m_funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
|
||||
m_funcs->glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
|
||||
ImGui::Text("Texture max size: %d Units: %d", maxTextureSize, maxTextureUnits);
|
||||
|
||||
if (ImGui::Button("Dump"))
|
||||
QMetaObject::invokeMethod(m_renderer->services()->systemInformation(), "dumpCommand",
|
||||
Qt::QueuedConnection, Q_ARG(QString, QLatin1String("render glinfo")));
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void ImGuiRenderer::showRenderDetails(const QVector<RenderView *> &renderViews)
|
||||
{
|
||||
ImGui::Begin("Render Views", &m_showRenderDetailsWindow);
|
||||
|
||||
int i = 1;
|
||||
for (const RenderView *view: renderViews) {
|
||||
QString label(QLatin1String("View ") + QString::number(i++));
|
||||
if (ImGui::TreeNode(label.toLatin1().data())) {
|
||||
ImGui::Text("Viewport: (%.1f, %.1f, %.1f, %.1f)", view->viewport().x(), view->viewport().y(),
|
||||
view->viewport().width(), view->viewport().height());
|
||||
ImGui::Text("Surface Size: (%d, %d)", view->surfaceSize().width(), view->surfaceSize().height());
|
||||
ImGui::Text("Pixel Ratio: %.1f", view->devicePixelRatio());
|
||||
ImGui::Text("No Draw: %s", view->noDraw() ? "TRUE" : "FALSE");
|
||||
ImGui::Text("Frustum Culling: %s", view->frustumCulling() ? "TRUE" : "FALSE");
|
||||
ImGui::Text("Compute: %s", view->isCompute() ? "TRUE" : "FALSE");
|
||||
ImGui::Text("Clear Depth Value: %f", static_cast<double>(view->clearDepthValue()));
|
||||
ImGui::Text("Clear Stencil Value: %d", view->clearStencilValue());
|
||||
int j = 1;
|
||||
const auto commands = view->commands();
|
||||
for (const RenderCommand &command: commands) {
|
||||
QString label(QLatin1String("Command ") + QString::number(j++));
|
||||
if (ImGui::TreeNode(label.toLatin1().data())) {
|
||||
ImGui::Text("Primitive Type: %s %s", primitiveTypeName(command.m_primitiveType),
|
||||
command.m_drawIndexed ? "(indexed)" : "");
|
||||
ImGui::Text("# Vertices: %d", command.m_primitiveCount);
|
||||
ImGui::Text("# Primitives: %d", vertexToPrimitiveCount(command.m_primitiveType, command.m_primitiveCount));
|
||||
ImGui::Text("# Instances: %d", command.m_instanceCount);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
ImGui::TreePop();
|
||||
ImGui::Separator();
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::Button("Dump"))
|
||||
QMetaObject::invokeMethod(m_renderer->services()->systemInformation(), "dumpCommand",
|
||||
Qt::QueuedConnection, Q_ARG(QString, QLatin1String("render rendercommands")));
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void ImGuiRenderer::renderDrawList(ImDrawData *draw_data)
|
||||
{
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
int fb_width = int(io.DisplaySize.x * io.DisplayFramebufferScale.x);
|
||||
int fb_height = int(io.DisplaySize.y * io.DisplayFramebufferScale.y);
|
||||
if (fb_width == 0 || fb_height == 0)
|
||||
return;
|
||||
draw_data->ScaleClipRects(io.DisplayFramebufferScale);
|
||||
|
||||
// Backup GL state
|
||||
GLint last_active_texture; m_funcs->glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture);
|
||||
m_funcs->glActiveTexture(GL_TEXTURE0);
|
||||
GLint last_program; m_funcs->glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
|
||||
GLint last_texture; m_funcs->glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
||||
GLint last_array_buffer; m_funcs->glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
|
||||
GLint last_element_array_buffer; m_funcs->glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer);
|
||||
GLint last_vertex_array; m_funcs->glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
|
||||
GLint last_blend_src_rgb; m_funcs->glGetIntegerv(GL_BLEND_SRC_RGB, &last_blend_src_rgb);
|
||||
GLint last_blend_dst_rgb; m_funcs->glGetIntegerv(GL_BLEND_DST_RGB, &last_blend_dst_rgb);
|
||||
GLint last_blend_src_alpha; m_funcs->glGetIntegerv(GL_BLEND_SRC_ALPHA, &last_blend_src_alpha);
|
||||
GLint last_blend_dst_alpha; m_funcs->glGetIntegerv(GL_BLEND_DST_ALPHA, &last_blend_dst_alpha);
|
||||
GLint last_blend_equation_rgb; m_funcs->glGetIntegerv(GL_BLEND_EQUATION_RGB, &last_blend_equation_rgb);
|
||||
GLint last_blend_equation_alpha; m_funcs->glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &last_blend_equation_alpha);
|
||||
GLint last_viewport[4]; m_funcs->glGetIntegerv(GL_VIEWPORT, last_viewport);
|
||||
GLint last_scissor_box[4]; m_funcs->glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
|
||||
GLboolean last_enable_blend = m_funcs->glIsEnabled(GL_BLEND);
|
||||
GLboolean last_enable_cull_face = m_funcs->glIsEnabled(GL_CULL_FACE);
|
||||
GLboolean last_enable_depth_test = m_funcs->glIsEnabled(GL_DEPTH_TEST);
|
||||
GLboolean last_enable_scissor_test = m_funcs->glIsEnabled(GL_SCISSOR_TEST);
|
||||
|
||||
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled
|
||||
m_funcs->glEnable(GL_BLEND);
|
||||
m_funcs->glBlendEquation(GL_FUNC_ADD);
|
||||
m_funcs->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
m_funcs->glDisable(GL_CULL_FACE);
|
||||
m_funcs->glDisable(GL_DEPTH_TEST);
|
||||
m_funcs->glEnable(GL_SCISSOR_TEST);
|
||||
|
||||
// Setup viewport, orthographic projection matrix
|
||||
m_funcs->glViewport(0, 0, static_cast<GLsizei>(fb_width), static_cast<GLsizei>(fb_height));
|
||||
const float ortho_projection[4][4] = {
|
||||
{ 2.0f/io.DisplaySize.x, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 2.0f/-io.DisplaySize.y, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, -1.0f, 0.0f },
|
||||
{-1.0f, 1.0f, 0.0f, 1.0f },
|
||||
};
|
||||
m_funcs->glUseProgram(m_shaderHandle);
|
||||
m_funcs->glUniform1i(m_attribLocationTex, 0);
|
||||
m_funcs->glUniformMatrix4fv(m_attribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
|
||||
m_funcs->glBindVertexArray(m_vaoHandle);
|
||||
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++) {
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
const ImDrawIdx* idx_buffer_offset = nullptr;
|
||||
|
||||
m_funcs->glBindBuffer(GL_ARRAY_BUFFER, m_vboHandle);
|
||||
m_funcs->glBufferData(GL_ARRAY_BUFFER, static_cast<GLsizeiptr>(cmd_list->VtxBuffer.Size) * sizeof(ImDrawVert), static_cast<const GLvoid*>(cmd_list->VtxBuffer.Data), GL_STREAM_DRAW);
|
||||
|
||||
m_funcs->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementsHandle);
|
||||
m_funcs->glBufferData(GL_ELEMENT_ARRAY_BUFFER, static_cast<GLsizeiptr>(cmd_list->IdxBuffer.Size) * sizeof(ImDrawIdx), static_cast<const GLvoid*>(cmd_list->IdxBuffer.Data), GL_STREAM_DRAW);
|
||||
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) {
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback) {
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
} else {
|
||||
m_funcs->glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
|
||||
m_funcs->glScissor(static_cast<int>(pcmd->ClipRect.x), static_cast<int>(fb_height - pcmd->ClipRect.w),
|
||||
static_cast<int>(pcmd->ClipRect.z - pcmd->ClipRect.x), static_cast<int>(pcmd->ClipRect.w - pcmd->ClipRect.y));
|
||||
m_funcs->glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(pcmd->ElemCount), sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset);
|
||||
}
|
||||
idx_buffer_offset += pcmd->ElemCount;
|
||||
}
|
||||
}
|
||||
|
||||
// Restore modified GL state
|
||||
m_funcs->glUseProgram(last_program);
|
||||
m_funcs->glBindTexture(GL_TEXTURE_2D, last_texture);
|
||||
m_funcs->glActiveTexture(last_active_texture);
|
||||
m_funcs->glBindVertexArray(last_vertex_array);
|
||||
m_funcs->glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
|
||||
m_funcs->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer);
|
||||
m_funcs->glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha);
|
||||
m_funcs->glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha);
|
||||
if (last_enable_blend)
|
||||
m_funcs->glEnable(GL_BLEND); else m_funcs->glDisable(GL_BLEND);
|
||||
if (last_enable_cull_face)
|
||||
m_funcs->glEnable(GL_CULL_FACE); else m_funcs->glDisable(GL_CULL_FACE);
|
||||
if (last_enable_depth_test)
|
||||
m_funcs->glEnable(GL_DEPTH_TEST); else m_funcs->glDisable(GL_DEPTH_TEST);
|
||||
if (last_enable_scissor_test)
|
||||
m_funcs->glEnable(GL_SCISSOR_TEST); else m_funcs->glDisable(GL_SCISSOR_TEST);
|
||||
m_funcs->glViewport(last_viewport[0], last_viewport[1], static_cast<GLsizei>(last_viewport[2]), static_cast<GLsizei>(last_viewport[3]));
|
||||
m_funcs->glScissor(last_scissor_box[0], last_scissor_box[1], static_cast<GLsizei>(last_scissor_box[2]), static_cast<GLsizei>(last_scissor_box[3]));
|
||||
}
|
||||
|
||||
bool ImGuiRenderer::createFontsTexture()
|
||||
{
|
||||
// Build texture atlas
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
unsigned char* pixels;
|
||||
int width, height;
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.
|
||||
|
||||
// Upload texture to graphics system
|
||||
GLint last_texture;
|
||||
m_funcs->glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
||||
m_funcs->glGenTextures(1, &m_fontTexture);
|
||||
m_funcs->glBindTexture(GL_TEXTURE_2D, m_fontTexture);
|
||||
m_funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
m_funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
m_funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
// Store our identifier
|
||||
io.Fonts->TexID = (void *)(intptr_t)m_fontTexture;
|
||||
|
||||
// Restore state
|
||||
m_funcs->glBindTexture(GL_TEXTURE_2D, last_texture);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImGuiRenderer::createDeviceObjects()
|
||||
{
|
||||
auto *glContext = m_renderer->submissionContext()->openGLContext();
|
||||
if (glContext->format().majorVersion() < 3) {
|
||||
qWarning() << "Qt3D Profiling overlay requires GL or GL ES >= 3";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Backup GL state
|
||||
GLint last_texture, last_array_buffer, last_vertex_array;
|
||||
m_funcs->glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
||||
m_funcs->glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
|
||||
m_funcs->glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
|
||||
|
||||
const GLchar *vertex_shader =
|
||||
"#version 330\n"
|
||||
"uniform mat4 ProjMtx;\n"
|
||||
"in vec2 Position;\n"
|
||||
"in vec2 UV;\n"
|
||||
"in vec4 Color;\n"
|
||||
"out vec2 Frag_UV;\n"
|
||||
"out vec4 Frag_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" Frag_UV = UV;\n"
|
||||
" Frag_Color = Color;\n"
|
||||
" gl_Position = ProjMtx * vec4(Position.xy, 0, 1);\n"
|
||||
"}\n";
|
||||
|
||||
const GLchar* fragment_shader =
|
||||
"#version 330\n"
|
||||
"uniform sampler2D Texture;\n"
|
||||
"in vec2 Frag_UV;\n"
|
||||
"in vec4 Frag_Color;\n"
|
||||
"out vec4 Out_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
|
||||
"}\n";
|
||||
|
||||
const GLchar *vertex_shader_es3 =
|
||||
"#version 110\n"
|
||||
"uniform mat4 ProjMtx;\n"
|
||||
"in vec2 Position;\n"
|
||||
"in vec2 UV;\n"
|
||||
"in vec4 Color;\n"
|
||||
"out vec2 Frag_UV;\n"
|
||||
"out vec4 Frag_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" Frag_UV = UV;\n"
|
||||
" Frag_Color = Color;\n"
|
||||
" gl_Position = ProjMtx * vec4(Position.xy, 0, 1);\n"
|
||||
"}\n";
|
||||
|
||||
const GLchar* fragment_shader_es3 =
|
||||
"#version 110\n"
|
||||
"uniform sampler2D Texture;\n"
|
||||
"in vec2 Frag_UV;\n"
|
||||
"in vec4 Frag_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);\n"
|
||||
"}\n";
|
||||
|
||||
// m_shaderHandle = m_funcs->glCreateProgram();
|
||||
// m_vertHandle = m_funcs->glCreateShader(GL_VERTEX_SHADER);
|
||||
// m_fragHandle = m_funcs->glCreateShader(GL_FRAGMENT_SHADER);
|
||||
// auto *glContext = m_renderer->submissionContext()->openGLContext();
|
||||
// m_funcs->glShaderSource(m_vertHandle, 1, &vertex_shader, nullptr);
|
||||
// m_funcs->glShaderSource(m_fragHandle, 1, &fragment_shader, nullptr);
|
||||
// m_funcs->glCompileShader(m_vertHandle);
|
||||
// m_funcs->glCompileShader(m_fragHandle);
|
||||
// m_funcs->glAttachShader(m_shaderHandle, m_vertHandle);
|
||||
// m_funcs->glAttachShader(m_shaderHandle, m_fragHandle);
|
||||
// m_funcs->glLinkProgram(m_shaderHandle);
|
||||
|
||||
QString logs;
|
||||
m_shader = new QOpenGLShaderProgram(this);
|
||||
if (glContext->isOpenGLES()) {
|
||||
if (!m_shader->addShaderFromSourceCode(QOpenGLShader::Vertex, vertex_shader_es3))
|
||||
logs += m_shader->log();
|
||||
if (!m_shader->addShaderFromSourceCode(QOpenGLShader::Fragment, fragment_shader_es3))
|
||||
logs += m_shader->log();
|
||||
} else {
|
||||
if (!m_shader->addShaderFromSourceCode(QOpenGLShader::Vertex, vertex_shader))
|
||||
logs += m_shader->log();
|
||||
if (!m_shader->addShaderFromSourceCode(QOpenGLShader::Fragment, fragment_shader))
|
||||
logs += m_shader->log();
|
||||
}
|
||||
m_shader->link();
|
||||
logs += m_shader->log();
|
||||
if (!logs.isEmpty())
|
||||
qWarning() << logs;
|
||||
m_shaderHandle = m_shader->programId();
|
||||
|
||||
m_attribLocationTex = m_funcs->glGetUniformLocation(m_shaderHandle, "Texture");
|
||||
m_attribLocationProjMtx = m_funcs->glGetUniformLocation(m_shaderHandle, "ProjMtx");
|
||||
m_attribLocationPosition = m_funcs->glGetAttribLocation(m_shaderHandle, "Position");
|
||||
m_attribLocationUV = m_funcs->glGetAttribLocation(m_shaderHandle, "UV");
|
||||
m_attribLocationColor = m_funcs->glGetAttribLocation(m_shaderHandle, "Color");
|
||||
|
||||
m_funcs->glGenBuffers(1, &m_vboHandle);
|
||||
m_funcs->glGenBuffers(1, &m_elementsHandle);
|
||||
|
||||
m_funcs->glGenVertexArrays(1, &m_vaoHandle);
|
||||
m_funcs->glBindVertexArray(m_vaoHandle);
|
||||
m_funcs->glBindBuffer(GL_ARRAY_BUFFER, m_vboHandle);
|
||||
m_funcs->glEnableVertexAttribArray(m_attribLocationPosition);
|
||||
m_funcs->glEnableVertexAttribArray(m_attribLocationUV);
|
||||
m_funcs->glEnableVertexAttribArray(m_attribLocationColor);
|
||||
|
||||
#define OFFSETOF(TYPE, ELEMENT) (reinterpret_cast<size_t>(&((static_cast<TYPE *>(nullptr))->ELEMENT)))
|
||||
m_funcs->glVertexAttribPointer(m_attribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), reinterpret_cast<GLvoid*>(OFFSETOF(ImDrawVert, pos)));
|
||||
m_funcs->glVertexAttribPointer(m_attribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), reinterpret_cast<GLvoid*>(OFFSETOF(ImDrawVert, uv)));
|
||||
m_funcs->glVertexAttribPointer(m_attribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), reinterpret_cast<GLvoid*>(OFFSETOF(ImDrawVert, col)));
|
||||
#undef OFFSETOF
|
||||
|
||||
createFontsTexture();
|
||||
|
||||
// Restore modified GL state
|
||||
m_funcs->glBindTexture(GL_TEXTURE_2D, last_texture);
|
||||
m_funcs->glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
|
||||
m_funcs->glBindVertexArray(last_vertex_array);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImGuiRenderer::newFrame(const RenderView *renderView)
|
||||
{
|
||||
if (!m_funcs)
|
||||
m_funcs = m_renderer->submissionContext()->openGLContext()->extraFunctions();
|
||||
if (!m_fontTexture)
|
||||
createDeviceObjects();
|
||||
if (!m_shader)
|
||||
return false;
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// Setup display size (every frame to accommodate for window resizing)
|
||||
io.DisplaySize = ImVec2(renderView->surfaceSize().width() / renderView->devicePixelRatio(), renderView->surfaceSize().height() / renderView->devicePixelRatio());
|
||||
io.DisplayFramebufferScale = ImVec2(renderView->devicePixelRatio(), renderView->devicePixelRatio());
|
||||
|
||||
// Setup time step
|
||||
double current_time = QDateTime::currentMSecsSinceEpoch() / 1000.;
|
||||
io.DeltaTime = m_time > 0.0 ? static_cast<float>(current_time - m_time) : 1.0f / 60.0f;
|
||||
if (io.DeltaTime == 0.f)
|
||||
io.DeltaTime = 1.0f / 60.0f;
|
||||
m_time = current_time;
|
||||
|
||||
// Setup inputs
|
||||
for (int i = 0; i < 3; i++)
|
||||
io.MouseDown[i] = m_mousePressed[i];
|
||||
|
||||
io.MouseWheelH = m_mouseWheelH;
|
||||
io.MouseWheel = m_mouseWheel;
|
||||
m_mouseWheelH = 0;
|
||||
m_mouseWheel = 0;
|
||||
|
||||
// Start the frame
|
||||
ImGui::NewFrame();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGuiRenderer::onMouseChange(QMouseEvent *event)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.MousePos = ImVec2(event->pos().x(), event->pos().y());
|
||||
m_mousePressed[0] = event->buttons() & Qt::LeftButton;
|
||||
m_mousePressed[1] = event->buttons() & Qt::RightButton;
|
||||
m_mousePressed[2] = event->buttons() & Qt::MiddleButton;
|
||||
}
|
||||
|
||||
void ImGuiRenderer::onWheel(QWheelEvent *event)
|
||||
{
|
||||
// 5 lines per unit
|
||||
m_mouseWheelH += event->pixelDelta().x() / (ImGui::GetTextLineHeight());
|
||||
m_mouseWheel += event->pixelDelta().y() / (5.f * ImGui::GetTextLineHeight());
|
||||
}
|
||||
|
||||
void ImGuiRenderer::onKeyPressRelease(QKeyEvent *event)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (keyMap.contains(event->key()))
|
||||
io.KeysDown[keyMap[event->key()]] = event->type() == QEvent::KeyPress;
|
||||
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
QString text = event->text();
|
||||
if (text.size() == 1)
|
||||
io.AddInputCharacter(static_cast<ImWchar>(text.at(0).unicode()));
|
||||
}
|
||||
|
||||
#ifdef Q_OS_DARWIN
|
||||
io.KeyCtrl = event->modifiers() & Qt::MetaModifier;
|
||||
io.KeyShift = event->modifiers() & Qt::ShiftModifier;
|
||||
io.KeyAlt = event->modifiers() & Qt::AltModifier;
|
||||
io.KeySuper = event->modifiers() & Qt::ControlModifier; // Command key
|
||||
#else
|
||||
io.KeyCtrl = event->modifiers() & Qt::ControlModifier;
|
||||
io.KeyShift = event->modifiers() & Qt::ShiftModifier;
|
||||
io.KeyAlt = event->modifiers() & Qt::AltModifier;
|
||||
io.KeySuper = event->modifiers() & Qt::MetaModifier;
|
||||
#endif
|
||||
}
|
||||
|
||||
void ImGuiRenderer::processEvent(QEvent *event)
|
||||
{
|
||||
switch (event->type()) {
|
||||
case QEvent::MouseMove:
|
||||
case QEvent::MouseButtonPress:
|
||||
case QEvent::MouseButtonRelease:
|
||||
this->onMouseChange(static_cast<QMouseEvent *>(event));
|
||||
break;
|
||||
case QEvent::Wheel:
|
||||
this->onWheel(static_cast<QWheelEvent *>(event));
|
||||
break;
|
||||
case QEvent::KeyPress:
|
||||
case QEvent::KeyRelease:
|
||||
this->onKeyPressRelease(static_cast<QKeyEvent *>(event));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB).
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt3D module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QT3D_RENDER_GL_IMGUIRENDER_H_
|
||||
#define QT3D_RENDER_GL_IMGUIRENDER_H_
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of other Qt classes. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QObject>
|
||||
#include <QOpenGLFunctions>
|
||||
#include <QPoint>
|
||||
#include <memory>
|
||||
|
||||
struct ImDrawData;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QMouseEvent;
|
||||
class QWheelEvent;
|
||||
class QKeyEvent;
|
||||
class QOpenGLExtraFunctions;
|
||||
class QOpenGLShaderProgram;
|
||||
|
||||
namespace Qt3DCore {
|
||||
class QServiceLocator;
|
||||
}
|
||||
|
||||
namespace Qt3DRender {
|
||||
namespace Render {
|
||||
|
||||
class RenderView;
|
||||
class Renderer;
|
||||
|
||||
namespace Debug {
|
||||
|
||||
#define IMGUI_PERF_LOG_SIZE 30
|
||||
|
||||
class ImGuiRenderer : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ImGuiRenderer(Qt3DRender::Render::Renderer *renderer);
|
||||
|
||||
void processEvent(QEvent *event);
|
||||
void renderDebugOverlay(const QVector<Render::RenderView *> &renderViews, const Render::RenderView *renderView, int jobsInLastFrame);
|
||||
|
||||
private:
|
||||
bool newFrame(const RenderView *renderView);
|
||||
void renderDrawList(ImDrawData *draw_data);
|
||||
void onMouseChange(QMouseEvent *event);
|
||||
void onWheel(QWheelEvent *event);
|
||||
void onKeyPressRelease(QKeyEvent *event);
|
||||
void showGLInfo();
|
||||
void showRenderDetails(const QVector<Render::RenderView *> &renderViews);
|
||||
|
||||
bool createFontsTexture();
|
||||
bool createDeviceObjects();
|
||||
|
||||
double m_time = 0.;
|
||||
bool m_mousePressed[3] = { false, false, false };
|
||||
float m_mouseWheel;
|
||||
float m_mouseWheelH;
|
||||
GLuint m_fontTexture = 0;
|
||||
GLuint m_shaderHandle = 0, m_vertHandle = 0, m_fragHandle = 0;
|
||||
int m_attribLocationTex = 0, m_attribLocationProjMtx = 0;
|
||||
int m_attribLocationPosition = 0, m_attribLocationUV = 0, m_attribLocationColor = 0;
|
||||
unsigned int m_vboHandle = 0, m_vaoHandle = 0, m_elementsHandle = 0;
|
||||
|
||||
Renderer *m_renderer;
|
||||
QOpenGLExtraFunctions *m_funcs = nullptr;
|
||||
QOpenGLShaderProgram *m_shader = nullptr;
|
||||
|
||||
bool m_showGLInfoWindow = false;
|
||||
bool m_showRenderDetailsWindow = false;
|
||||
|
||||
float m_fpsLog[IMGUI_PERF_LOG_SIZE];
|
||||
float m_jobsLog[IMGUI_PERF_LOG_SIZE];
|
||||
std::pair<float, float> m_fpsRange;
|
||||
std::pair<float, float> m_jobsRange;
|
||||
};
|
||||
|
||||
} // namespace Debug
|
||||
} // namespace Render
|
||||
} // namespace Qt3DRender
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT3D_RENDER_GL_IMGUIRENDER_H_
|
||||
|
|
@ -236,6 +236,11 @@ void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphN
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case FrameGraphNode::DebugOverlay:
|
||||
rv->setShowDebugOverlay(true);
|
||||
break;
|
||||
|
||||
case FrameGraphNode::RenderCapture: {
|
||||
auto *renderCapture = const_cast<Render::RenderCapture *>(
|
||||
static_cast<const Render::RenderCapture *>(node));
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ include (textures/textures.pri)
|
|||
include (graphicshelpers/graphicshelpers.pri)
|
||||
include (renderstates/renderstates.pri)
|
||||
|
||||
!integrity: include (debug/debug.pri)
|
||||
|
||||
gcov {
|
||||
QMAKE_CXXFLAGS += -fprofile-arcs -ftest-coverage
|
||||
QMAKE_LFLAGS += -fprofile-arcs -ftest-coverage
|
||||
|
|
|
|||
|
|
@ -95,6 +95,9 @@
|
|||
#include <Qt3DRender/private/qshaderprogram_p.h>
|
||||
#include <Qt3DRender/private/filterentitybycomponentjob_p.h>
|
||||
#include <Qt3DRender/private/commandexecuter_p.h>
|
||||
#ifndef Q_OS_INTEGRITY
|
||||
#include <Qt3DRender/private/imguirenderer_p.h>
|
||||
#endif
|
||||
|
||||
#include <Qt3DRender/qcameralens.h>
|
||||
#include <Qt3DCore/private/qeventfilterservice_p.h>
|
||||
|
|
@ -279,6 +282,8 @@ Renderer::Renderer(QRenderAspect::RenderType type)
|
|||
, m_offscreenHelper(nullptr)
|
||||
, m_commandExecuter(new Qt3DRender::Debug::CommandExecuter(this))
|
||||
, m_shouldSwapBuffers(true)
|
||||
, m_imGuiRenderer(nullptr)
|
||||
, m_jobsInLastFrame(0)
|
||||
{
|
||||
// Set renderer as running - it will wait in the context of the
|
||||
// RenderThread for RenderViews to be submitted
|
||||
|
|
@ -330,6 +335,10 @@ Renderer::~Renderer()
|
|||
|
||||
if (!m_ownedContext)
|
||||
QObject::disconnect(m_contextConnection);
|
||||
|
||||
#ifndef Q_OS_INTEGRITY
|
||||
delete m_imGuiRenderer;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Renderer::dumpInfo() const
|
||||
|
|
@ -1485,6 +1494,7 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren
|
|||
}
|
||||
QSurface *lastUsedSurface = nullptr;
|
||||
|
||||
bool imGuiOverlayShown = false;
|
||||
for (int i = 0; i < renderViewsCount; ++i) {
|
||||
// Initialize GraphicsContext for drawing
|
||||
// If the RenderView has a RenderStateSet defined
|
||||
|
|
@ -1668,6 +1678,22 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren
|
|||
interpolationMethod);
|
||||
}
|
||||
|
||||
#ifndef Q_OS_INTEGRITY
|
||||
if (!imGuiOverlayShown && renderView->showDebugOverlay()) {
|
||||
imGuiOverlayShown = true;
|
||||
if (!m_imGuiRenderer)
|
||||
m_imGuiRenderer = new Debug::ImGuiRenderer(this);
|
||||
|
||||
{
|
||||
QMutexLocker l(&m_frameEventsMutex);
|
||||
for (auto &keyEvent: m_frameKeyEvents)
|
||||
m_imGuiRenderer->processEvent(&keyEvent);
|
||||
for (auto &mouseEvent: m_frameMouseEvents)
|
||||
m_imGuiRenderer->processEvent(&mouseEvent.second);
|
||||
}
|
||||
m_imGuiRenderer->renderDebugOverlay(renderViews, renderView, m_jobsInLastFrame);
|
||||
}
|
||||
#endif
|
||||
|
||||
frameElapsed = timer.elapsed() - frameElapsed;
|
||||
qCDebug(Rendering) << Q_FUNC_INFO << "Submitted Renderview " << i + 1 << "/" << renderViewsCount << "in " << frameElapsed << "ms";
|
||||
|
|
@ -1742,6 +1768,7 @@ void Renderer::skipNextFrame()
|
|||
void Renderer::jobsDone(Qt3DCore::QAspectManager *manager)
|
||||
{
|
||||
// called in main thread once all jobs are done running
|
||||
m_jobsInLastFrame = manager->jobsInLastFrame();
|
||||
|
||||
// sync captured renders to frontend
|
||||
const QVector<Qt3DCore::QNodeId> pendingCaptureIds = std::move(m_pendingRenderCaptureSendRequests);
|
||||
|
|
@ -1761,6 +1788,24 @@ void Renderer::jobsDone(Qt3DCore::QAspectManager *manager)
|
|||
// Jobs we may have to run even if no rendering will happen
|
||||
QVector<QAspectJobPtr> Renderer::preRenderingJobs()
|
||||
{
|
||||
{
|
||||
QMutexLocker l(&m_frameEventsMutex);
|
||||
m_frameMouseEvents = m_pickEventFilter->pendingMouseEvents();
|
||||
m_frameKeyEvents = m_pickEventFilter->pendingKeyEvents();
|
||||
}
|
||||
|
||||
// Set values on picking jobs
|
||||
RenderSettings *renderSetting = settings();
|
||||
if (renderSetting != nullptr) {
|
||||
m_pickBoundingVolumeJob->setRenderSettings(renderSetting);
|
||||
m_pickBoundingVolumeJob->setFrameGraphRoot(frameGraphRoot());
|
||||
m_pickBoundingVolumeJob->setMouseEvents(m_frameMouseEvents);
|
||||
m_pickBoundingVolumeJob->setKeyEvents(m_frameKeyEvents);
|
||||
|
||||
m_rayCastingJob->setRenderSettings(renderSetting);
|
||||
m_rayCastingJob->setFrameGraphRoot(frameGraphRoot());
|
||||
}
|
||||
|
||||
QVector<QAspectJobPtr> jobs;
|
||||
|
||||
// Do we need to notify frontend about fence change?
|
||||
|
|
@ -1941,27 +1986,11 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
|
|||
|
||||
QAspectJobPtr Renderer::pickBoundingVolumeJob()
|
||||
{
|
||||
// Set values on pickBoundingVolumeJob
|
||||
RenderSettings *renderSetting = settings();
|
||||
if (renderSetting != nullptr) {
|
||||
m_pickBoundingVolumeJob->setRenderSettings(renderSetting);
|
||||
m_pickBoundingVolumeJob->setFrameGraphRoot(frameGraphRoot());
|
||||
m_pickBoundingVolumeJob->setMouseEvents(pendingPickingEvents());
|
||||
m_pickBoundingVolumeJob->setKeyEvents(pendingKeyEvents());
|
||||
}
|
||||
|
||||
return m_pickBoundingVolumeJob;
|
||||
}
|
||||
|
||||
QAspectJobPtr Renderer::rayCastingJob()
|
||||
{
|
||||
// Set values on rayCastingJob
|
||||
RenderSettings *renderSetting = settings();
|
||||
if (renderSetting != nullptr) {
|
||||
m_rayCastingJob->setRenderSettings(renderSetting);
|
||||
m_rayCastingJob->setFrameGraphRoot(frameGraphRoot());
|
||||
}
|
||||
|
||||
return m_rayCastingJob;
|
||||
}
|
||||
|
||||
|
|
@ -2311,16 +2340,6 @@ void Renderer::cleanGraphicsResources()
|
|||
}
|
||||
}
|
||||
|
||||
QList<QPair<QObject *, QMouseEvent>> Renderer::pendingPickingEvents() const
|
||||
{
|
||||
return m_pickEventFilter->pendingMouseEvents();
|
||||
}
|
||||
|
||||
QList<QKeyEvent> Renderer::pendingKeyEvents() const
|
||||
{
|
||||
return m_pickEventFilter->pendingKeyEvents();
|
||||
}
|
||||
|
||||
const GraphicsApiFilterData *Renderer::contextInfo() const
|
||||
{
|
||||
return m_submissionContext->contextInfo();
|
||||
|
|
|
|||
|
|
@ -167,6 +167,10 @@ using FilterEntityByComponentJobPtr = QSharedPointer<FilterEntityByComponentJob<
|
|||
using ComputableEntityFilterPtr = FilterEntityByComponentJobPtr<Render::ComputeCommand, Render::Material>;
|
||||
using RenderableEntityFilterPtr = FilterEntityByComponentJobPtr<Render::GeometryRenderer, Render::Material>;
|
||||
|
||||
namespace Debug {
|
||||
class ImGuiRenderer;
|
||||
}
|
||||
|
||||
class Q_3DRENDERSHARED_PRIVATE_EXPORT Renderer : public AbstractRenderer
|
||||
{
|
||||
public:
|
||||
|
|
@ -282,9 +286,6 @@ public:
|
|||
|
||||
inline RenderStateSet *defaultRenderState() const { return m_defaultRenderStateSet; }
|
||||
|
||||
QList<QPair<QObject*, QMouseEvent>> pendingPickingEvents() const;
|
||||
QList<QKeyEvent> pendingKeyEvents() const;
|
||||
|
||||
void enqueueRenderView(RenderView *renderView, int submitOrder);
|
||||
bool isReadyToSubmit();
|
||||
|
||||
|
|
@ -445,6 +446,12 @@ private:
|
|||
|
||||
QVector<FrameGraphNode *> m_frameGraphLeaves;
|
||||
QScreen *m_screen = nullptr;
|
||||
|
||||
Debug::ImGuiRenderer *m_imGuiRenderer;
|
||||
QList<QPair<QObject *, QMouseEvent>> m_frameMouseEvents;
|
||||
QList<QKeyEvent> m_frameKeyEvents;
|
||||
QMutex m_frameEventsMutex;
|
||||
int m_jobsInLastFrame;
|
||||
};
|
||||
|
||||
} // namespace Render
|
||||
|
|
|
|||
|
|
@ -250,6 +250,7 @@ RenderView::RenderView()
|
|||
, m_noDraw(false)
|
||||
, m_compute(false)
|
||||
, m_frustumCulling(false)
|
||||
, m_showDebugOverlay(false)
|
||||
, m_memoryBarrier(QMemoryBarrier::None)
|
||||
, m_environmentLight(nullptr)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -201,6 +201,8 @@ public:
|
|||
const int *computeWorkGroups() const Q_DECL_NOTHROW { return m_workGroups; }
|
||||
inline bool frustumCulling() const Q_DECL_NOTHROW { return m_frustumCulling; }
|
||||
void setFrustumCulling(bool frustumCulling) Q_DECL_NOTHROW { m_frustumCulling = frustumCulling; }
|
||||
bool showDebugOverlay() const Q_DECL_NOTHROW { return m_showDebugOverlay; }
|
||||
void setShowDebugOverlay(bool showDebugOverlay) Q_DECL_NOTHROW { m_showDebugOverlay = showDebugOverlay; }
|
||||
|
||||
inline void setMaterialParameterTable(const MaterialParameterGathererData ¶meters) Q_DECL_NOTHROW { m_parameters = parameters; }
|
||||
|
||||
|
|
@ -334,6 +336,7 @@ private:
|
|||
bool m_noDraw:1;
|
||||
bool m_compute:1;
|
||||
bool m_frustumCulling:1;
|
||||
bool m_showDebugOverlay:1;
|
||||
int m_workGroups[3];
|
||||
QMemoryBarrier::Operations m_memoryBarrier;
|
||||
QVector<Qt3DCore::QNodeId> m_insertFenceIds;
|
||||
|
|
|
|||
|
|
@ -16,5 +16,7 @@
|
|||
%moduleheaders = ( # restrict the module headers to those found in relative path
|
||||
);
|
||||
|
||||
@ignore_headers = ( "imconfig.h", "imgui.h", "imgui_internal.h", "imstb_rectpack.h", "imstb_textedit.h", "imstb_truetype.h" );
|
||||
|
||||
# Force generation of camel case headers for classes inside Qt3D* namespaces
|
||||
$publicclassregexp = "Qt3D.*::.+";
|
||||
|
|
|
|||
Loading…
Reference in New Issue