Compare commits
13 Commits
logging
...
675082ab83
| Author | SHA1 | Date | |
|---|---|---|---|
| 675082ab83 | |||
| ea25ba312a | |||
| 78639cf1c2 | |||
| 941f2d228c | |||
| 16baf6cdaf | |||
| c86a7744b3 | |||
| 7fac6bafb4 | |||
| 1bed9545c9 | |||
| 32641acd8d | |||
| 68bfff7bcd | |||
| 92e5937cc7 | |||
| 1e1c328a5a | |||
| dcbeb26738 |
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
BasedOnStyle: Google
|
BasedOnStyle: Google
|
||||||
AlignAfterOpenBracket: AlwaysBreak
|
AlignAfterOpenBracket: Align
|
||||||
AlignArrayOfStructures: Left
|
AlignArrayOfStructures: Left
|
||||||
AlignConsecutiveAssignments: None
|
AlignConsecutiveAssignments: None
|
||||||
AlignConsecutiveDeclarations: None
|
AlignConsecutiveDeclarations: None
|
||||||
@@ -9,7 +9,6 @@ AlignEscapedNewlines: Left
|
|||||||
AlignOperands: Align
|
AlignOperands: Align
|
||||||
AlignTrailingComments: true
|
AlignTrailingComments: true
|
||||||
AllowAllArgumentsOnNextLine: true
|
AllowAllArgumentsOnNextLine: true
|
||||||
AllowAllParametersOfDeclarationOnNextLine: true
|
|
||||||
AllowShortBlocksOnASingleLine: Never
|
AllowShortBlocksOnASingleLine: Never
|
||||||
AllowShortCaseLabelsOnASingleLine: false
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
AllowShortFunctionsOnASingleLine: Inline
|
AllowShortFunctionsOnASingleLine: Inline
|
||||||
@@ -21,8 +20,11 @@ InsertBraces: true
|
|||||||
IndentAccessModifiers: true
|
IndentAccessModifiers: true
|
||||||
EmptyLineAfterAccessModifier: Never
|
EmptyLineAfterAccessModifier: Never
|
||||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||||
BinPackArguments: true
|
BinPackArguments: false
|
||||||
BinPackParameters: true
|
BinPackParameters: false
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
BreakBeforeBraces: Linux
|
||||||
BreakBeforeBinaryOperators: NonAssignment
|
BreakBeforeBinaryOperators: NonAssignment
|
||||||
BreakBeforeTernaryOperators: true
|
BreakBeforeTernaryOperators: true
|
||||||
BreakConstructorInitializers: AfterColon
|
BreakConstructorInitializers: AfterColon
|
||||||
@@ -58,7 +60,7 @@ SpaceAfterTemplateKeyword: true
|
|||||||
SpaceBeforeAssignmentOperators: true
|
SpaceBeforeAssignmentOperators: true
|
||||||
SpaceBeforeCpp11BracedList: true
|
SpaceBeforeCpp11BracedList: true
|
||||||
SpaceBeforeCtorInitializerColon: true
|
SpaceBeforeCtorInitializerColon: true
|
||||||
SpaceBeforeParens: Never
|
SpaceBeforeParens: ControlStatementsExceptControlMacros
|
||||||
SpaceBeforeRangeBasedForLoopColon: true
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
SpacesBeforeTrailingComments: 2
|
SpacesBeforeTrailingComments: 2
|
||||||
SpaceInEmptyParentheses: false
|
SpaceInEmptyParentheses: false
|
||||||
|
|||||||
143
.clang-tidy
@@ -139,8 +139,149 @@ readability-redundant-smartptr-get,
|
|||||||
readability-redundant-string-cstr,
|
readability-redundant-string-cstr,
|
||||||
readability-redundant-string-init,
|
readability-redundant-string-init,
|
||||||
readability-simplify-subscript-expr,
|
readability-simplify-subscript-expr,
|
||||||
readability-static-accessed-through-instance,
|
|
||||||
readability-static-definition-in-anonymous-namespace,
|
readability-static-definition-in-anonymous-namespace,
|
||||||
readability-string-compare,
|
readability-string-compare,
|
||||||
readability-uniqueptr-delete-release,
|
readability-uniqueptr-delete-release,
|
||||||
readability-use-anyofallof'
|
readability-use-anyofallof'
|
||||||
|
CheckOptions:
|
||||||
|
bugprone-argument-comment.CommentBoolLiterals: '0'
|
||||||
|
bugprone-argument-comment.CommentCharacterLiterals: '0'
|
||||||
|
bugprone-argument-comment.CommentFloatLiterals: '0'
|
||||||
|
bugprone-argument-comment.CommentIntegerLiterals: '0'
|
||||||
|
bugprone-argument-comment.CommentNullPtrs: '0'
|
||||||
|
bugprone-argument-comment.CommentStringLiterals: '0'
|
||||||
|
bugprone-argument-comment.CommentUserDefinedLiterals: '0'
|
||||||
|
bugprone-argument-comment.IgnoreSingleArgument: '0'
|
||||||
|
bugprone-argument-comment.StrictMode: '0'
|
||||||
|
bugprone-assert-side-effect.AssertMacros: assert,NSAssert,NSCAssert
|
||||||
|
bugprone-assert-side-effect.CheckFunctionCalls: 'false'
|
||||||
|
bugprone-assert-side-effect.IgnoredFunctions: __builtin_expect
|
||||||
|
bugprone-dangling-handle.HandleClasses: 'std::basic_string_view;std::experimental::basic_string_view'
|
||||||
|
bugprone-dynamic-static-initializers.HeaderFileExtensions: ';h;hh;hpp;hxx'
|
||||||
|
bugprone-lambda-function-name.IgnoreMacros: 'false'
|
||||||
|
bugprone-misplaced-widening-cast.CheckImplicitCasts: 'false'
|
||||||
|
bugprone-not-null-terminated-result.WantToUseSafeFunctions: 'true'
|
||||||
|
bugprone-reserved-identifier.AggressiveDependentMemberLookup: 'false'
|
||||||
|
bugprone-reserved-identifier.AllowedIdentifiers: ''
|
||||||
|
bugprone-reserved-identifier.Invert: 'false'
|
||||||
|
bugprone-sizeof-expression.WarnOnSizeOfCompareToConstant: 'true'
|
||||||
|
bugprone-sizeof-expression.WarnOnSizeOfConstant: 'true'
|
||||||
|
bugprone-sizeof-expression.WarnOnSizeOfIntegerExpression: 'false'
|
||||||
|
bugprone-sizeof-expression.WarnOnSizeOfPointerToAggregate: 'true'
|
||||||
|
bugprone-sizeof-expression.WarnOnSizeOfThis: 'true'
|
||||||
|
bugprone-string-constructor.LargeLengthThreshold: '8388608'
|
||||||
|
bugprone-string-constructor.StringNames: '::std::basic_string;::std::basic_string_view'
|
||||||
|
bugprone-string-constructor.WarnOnLargeLength: 'true'
|
||||||
|
bugprone-suspicious-enum-usage.StrictMode: 'false'
|
||||||
|
bugprone-suspicious-include.HeaderFileExtensions: ';h;hh;hpp;hxx'
|
||||||
|
bugprone-suspicious-include.ImplementationFileExtensions: 'c;cc;cpp;cxx'
|
||||||
|
bugprone-suspicious-missing-comma.MaxConcatenatedTokens: '5'
|
||||||
|
bugprone-suspicious-missing-comma.RatioThreshold: '0.200000'
|
||||||
|
bugprone-suspicious-missing-comma.SizeThreshold: '5'
|
||||||
|
bugprone-suspicious-string-compare.StringCompareLikeFunctions: ''
|
||||||
|
bugprone-suspicious-string-compare.WarnOnImplicitComparison: 'true'
|
||||||
|
bugprone-suspicious-string-compare.WarnOnLogicalNotComparison: 'false'
|
||||||
|
bugprone-too-small-loop-variable.MagnitudeBitsUpperLimit: '16'
|
||||||
|
bugprone-unhandled-self-assignment.WarnOnlyIfThisHasSuspiciousField: 'true'
|
||||||
|
bugprone-unused-return-value.AllowCastToVoid: 'false'
|
||||||
|
bugprone-unused-return-value.CheckedFunctions: '::std::async;::std::launder;::std::remove;::std::remove_if;::std::unique;::std::unique_ptr::release;::std::basic_string::empty;::std::vector::empty;::std::back_inserter;::std::distance;::std::find;::std::find_if;::std::inserter;::std::lower_bound;::std::make_pair;::std::map::count;::std::map::find;::std::map::lower_bound;::std::multimap::equal_range;::std::multimap::upper_bound;::std::set::count;::std::set::find;::std::setfill;::std::setprecision;::std::setw;::std::upper_bound;::std::vector::at;::bsearch;::ferror;::feof;::isalnum;::isalpha;::isblank;::iscntrl;::isdigit;::isgraph;::islower;::isprint;::ispunct;::isspace;::isupper;::iswalnum;::iswprint;::iswspace;::isxdigit;::memchr;::memcmp;::strcmp;::strcoll;::strncmp;::strpbrk;::strrchr;::strspn;::strstr;::wcscmp;::access;::bind;::connect;::difftime;::dlsym;::fnmatch;::getaddrinfo;::getopt;::htonl;::htons;::iconv_open;::inet_addr;::isascii;::isatty;::mmap;::newlocale;::openat;::pathconf;::pthread_equal;::pthread_getspecific;::pthread_mutex_trylock;::readdir;::readlink;::recvmsg;::regexec;::scandir;::semget;::setjmp;::shm_open;::shmget;::sigismember;::strcasecmp;::strsignal;::ttyname'
|
||||||
|
bugprone-unused-return-value.CheckedReturnTypes: '::std::error_code;::std::error_condition;::std::errc;::std::expected;::boost::system::error_code'
|
||||||
|
cert-dcl16-c.NewSuffixes: 'L;LL;LU;LLU'
|
||||||
|
cert-err33-c.AllowCastToVoid: 'true'
|
||||||
|
cert-err33-c.CheckedFunctions: '::aligned_alloc;::asctime_s;::at_quick_exit;::atexit;::bsearch;::bsearch_s;::btowc;::c16rtomb;::c32rtomb;::calloc;::clock;::cnd_broadcast;::cnd_init;::cnd_signal;::cnd_timedwait;::cnd_wait;::ctime_s;::fclose;::fflush;::fgetc;::fgetpos;::fgets;::fgetwc;::fopen;::fopen_s;::fprintf;::fprintf_s;::fputc;::fputs;::fputwc;::fputws;::fread;::freopen;::freopen_s;::fscanf;::fscanf_s;::fseek;::fsetpos;::ftell;::fwprintf;::fwprintf_s;::fwrite;::fwscanf;::fwscanf_s;::getc;::getchar;::getenv;::getenv_s;::gets_s;::getwc;::getwchar;::gmtime;::gmtime_s;::localtime;::localtime_s;::malloc;::mbrtoc16;::mbrtoc32;::mbsrtowcs;::mbsrtowcs_s;::mbstowcs;::mbstowcs_s;::memchr;::mktime;::mtx_init;::mtx_lock;::mtx_timedlock;::mtx_trylock;::mtx_unlock;::printf_s;::putc;::putwc;::raise;::realloc;::remove;::rename;::scanf;::scanf_s;::setlocale;::setvbuf;::signal;::snprintf;::snprintf_s;::sprintf;::sprintf_s;::sscanf;::sscanf_s;::strchr;::strerror_s;::strftime;::strpbrk;::strrchr;::strstr;::strtod;::strtof;::strtoimax;::strtok;::strtok_s;::strtol;::strtold;::strtoll;::strtoul;::strtoull;::strtoumax;::strxfrm;::swprintf;::swprintf_s;::swscanf;::swscanf_s;::thrd_create;::thrd_detach;::thrd_join;::thrd_sleep;::time;::timespec_get;::tmpfile;::tmpfile_s;::tmpnam;::tmpnam_s;::tss_create;::tss_get;::tss_set;::ungetc;::ungetwc;::vfprintf;::vfprintf_s;::vfscanf;::vfscanf_s;::vfwprintf;::vfwprintf_s;::vfwscanf;::vfwscanf_s;::vprintf_s;::vscanf;::vscanf_s;::vsnprintf;::vsnprintf_s;::vsprintf;::vsprintf_s;::vsscanf;::vsscanf_s;::vswprintf;::vswprintf_s;::vswscanf;::vswscanf_s;::vwprintf_s;::vwscanf;::vwscanf_s;::wcrtomb;::wcschr;::wcsftime;::wcspbrk;::wcsrchr;::wcsrtombs;::wcsrtombs_s;::wcsstr;::wcstod;::wcstof;::wcstoimax;::wcstok;::wcstok_s;::wcstol;::wcstold;::wcstoll;::wcstombs;::wcstombs_s;::wcstoul;::wcstoull;::wcstoumax;::wcsxfrm;::wctob;::wctrans;::wctype;::wmemchr;::wprintf_s;::wscanf;::wscanf_s;'
|
||||||
|
cert-msc51-cpp.DisallowedSeedTypes: 'time_t,std::time_t'
|
||||||
|
cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField: 'false'
|
||||||
|
cert-str34-c.CharTypdefsToIgnore: ''
|
||||||
|
cert-str34-c.DiagnoseSignedUnsignedCharComparisons: 'false'
|
||||||
|
cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic: 'true'
|
||||||
|
cppcoreguidelines-pro-type-member-init.IgnoreArrays: 'false'
|
||||||
|
cppcoreguidelines-pro-type-member-init.UseAssignment: 'false'
|
||||||
|
cppcoreguidelines-pro-type-static-cast-downcast.StrictMode: 'true'
|
||||||
|
google-readability-braces-around-statements.ShortStatementLines: '1'
|
||||||
|
google-readability-function-size.StatementThreshold: '800'
|
||||||
|
google-readability-namespace-comments.ShortNamespaceLines: '10'
|
||||||
|
google-readability-namespace-comments.SpacesBeforeComments: '2'
|
||||||
|
hicpp-multiway-paths-covered.WarnOnMissingElse: 'false'
|
||||||
|
llvm-else-after-return.WarnOnConditionVariables: 'false'
|
||||||
|
llvm-else-after-return.WarnOnUnfixable: 'false'
|
||||||
|
llvm-qualified-auto.AddConstToQualified: 'false'
|
||||||
|
misc-throw-by-value-catch-by-reference.CheckThrowTemporaries: 'true'
|
||||||
|
misc-throw-by-value-catch-by-reference.WarnOnLargeObjects: 'false'
|
||||||
|
misc-uniqueptr-reset-release.IncludeStyle: llvm
|
||||||
|
modernize-avoid-bind.PermissiveParameterList: 'false'
|
||||||
|
modernize-deprecated-headers.CheckHeaderFile: 'false'
|
||||||
|
modernize-loop-convert.IncludeStyle: llvm
|
||||||
|
modernize-loop-convert.MakeReverseRangeFunction: ''
|
||||||
|
modernize-loop-convert.MakeReverseRangeHeader: ''
|
||||||
|
modernize-loop-convert.MaxCopySize: '16'
|
||||||
|
modernize-loop-convert.MinConfidence: reasonable
|
||||||
|
modernize-loop-convert.NamingStyle: CamelCase
|
||||||
|
modernize-loop-convert.UseCxx20ReverseRanges: 'true'
|
||||||
|
modernize-make-shared.IgnoreDefaultInitialization: 'true'
|
||||||
|
modernize-make-shared.IgnoreMacros: 'true'
|
||||||
|
modernize-make-shared.IncludeStyle: llvm
|
||||||
|
modernize-make-shared.MakeSmartPtrFunction: 'std::make_shared'
|
||||||
|
modernize-make-shared.MakeSmartPtrFunctionHeader: '<memory>'
|
||||||
|
modernize-make-unique.IgnoreDefaultInitialization: 'true'
|
||||||
|
modernize-make-unique.IgnoreMacros: 'true'
|
||||||
|
modernize-make-unique.IncludeStyle: llvm
|
||||||
|
modernize-make-unique.MakeSmartPtrFunction: 'std::make_unique'
|
||||||
|
modernize-make-unique.MakeSmartPtrFunctionHeader: '<memory>'
|
||||||
|
modernize-pass-by-value.IncludeStyle: llvm
|
||||||
|
modernize-pass-by-value.ValuesOnly: 'false'
|
||||||
|
modernize-raw-string-literal.DelimiterStem: lit
|
||||||
|
modernize-raw-string-literal.ReplaceShorterLiterals: 'false'
|
||||||
|
modernize-replace-auto-ptr.IncludeStyle: llvm
|
||||||
|
modernize-replace-disallow-copy-and-assign-macro.MacroName: DISALLOW_COPY_AND_ASSIGN
|
||||||
|
modernize-replace-random-shuffle.IncludeStyle: llvm
|
||||||
|
modernize-use-auto.MinTypeNameLength: '5'
|
||||||
|
modernize-use-auto.RemoveStars: 'false'
|
||||||
|
modernize-use-bool-literals.IgnoreMacros: 'true'
|
||||||
|
modernize-use-emplace.ContainersWithPush: '::std::stack;::std::queue;::std::priority_queue'
|
||||||
|
modernize-use-emplace.ContainersWithPushBack: '::std::vector;::std::list;::std::deque'
|
||||||
|
modernize-use-emplace.ContainersWithPushFront: '::std::forward_list;::std::list;::std::deque'
|
||||||
|
modernize-use-emplace.EmplacyFunctions: 'vector::emplace_back;vector::emplace;deque::emplace;deque::emplace_front;deque::emplace_back;forward_list::emplace_after;forward_list::emplace_front;list::emplace;list::emplace_back;list::emplace_front;set::emplace;set::emplace_hint;map::emplace;map::emplace_hint;multiset::emplace;multiset::emplace_hint;multimap::emplace;multimap::emplace_hint;unordered_set::emplace;unordered_set::emplace_hint;unordered_map::emplace;unordered_map::emplace_hint;unordered_multiset::emplace;unordered_multiset::emplace_hint;unordered_multimap::emplace;unordered_multimap::emplace_hint;stack::emplace;queue::emplace;priority_queue::emplace'
|
||||||
|
modernize-use-emplace.IgnoreImplicitConstructors: 'false'
|
||||||
|
modernize-use-emplace.SmartPointers: '::std::shared_ptr;::std::unique_ptr;::std::auto_ptr;::std::weak_ptr'
|
||||||
|
modernize-use-emplace.TupleMakeFunctions: '::std::make_pair;::std::make_tuple'
|
||||||
|
modernize-use-emplace.TupleTypes: '::std::pair;::std::tuple'
|
||||||
|
modernize-use-equals-default.IgnoreMacros: 'true'
|
||||||
|
modernize-use-equals-delete.IgnoreMacros: 'true'
|
||||||
|
modernize-use-nodiscard.ReplacementString: '[[nodiscard]]'
|
||||||
|
modernize-use-noexcept.ReplacementString: ''
|
||||||
|
modernize-use-noexcept.UseNoexceptFalse: 'true'
|
||||||
|
modernize-use-nullptr.IgnoredTypes: 'std::_CmpUnspecifiedParam::;^std::__cmp_cat::__unspec'
|
||||||
|
modernize-use-nullptr.NullMacros: 'NULL'
|
||||||
|
modernize-use-override.AllowOverrideAndFinal: 'false'
|
||||||
|
modernize-use-override.FinalSpelling: final
|
||||||
|
modernize-use-override.IgnoreDestructors: 'true'
|
||||||
|
modernize-use-override.IgnoreTemplateInstantiations: 'false'
|
||||||
|
modernize-use-override.OverrideSpelling: override
|
||||||
|
modernize-use-transparent-functors.SafeMode: 'false'
|
||||||
|
performance-faster-string-find.StringLikeClasses: '::std::basic_string;::std::basic_string_view'
|
||||||
|
performance-for-range-copy.AllowedTypes: ''
|
||||||
|
performance-for-range-copy.WarnOnAllAutoCopies: 'false'
|
||||||
|
performance-inefficient-string-concatenation.StrictMode: 'false'
|
||||||
|
performance-inefficient-vector-operation.EnableProto: 'false'
|
||||||
|
performance-inefficient-vector-operation.VectorLikeClasses: '::std::vector'
|
||||||
|
performance-move-const-arg.CheckMoveToConstRef: 'true'
|
||||||
|
performance-move-const-arg.CheckTriviallyCopyableMove: 'true'
|
||||||
|
performance-no-automatic-move.AllowedTypes: ''
|
||||||
|
performance-type-promotion-in-math-fn.IncludeStyle: llvm
|
||||||
|
performance-unnecessary-copy-initialization.AllowedTypes: ''
|
||||||
|
performance-unnecessary-copy-initialization.ExcludedContainerTypes: ''
|
||||||
|
performance-unnecessary-value-param.AllowedTypes: ''
|
||||||
|
performance-unnecessary-value-param.IncludeStyle: llvm
|
||||||
|
portability-simd-intrinsics.Std: ''
|
||||||
|
portability-simd-intrinsics.Suggest: 'false'
|
||||||
|
readability-avoid-const-params-in-decls.IgnoreMacros: 'true'
|
||||||
|
readability-braces-around-statements.ShortStatementLines: '0'
|
||||||
|
readability-const-return-type.IgnoreMacros: 'true'
|
||||||
|
readability-container-size-empty.ExcludedComparisonTypes: '::std::array'
|
||||||
|
readability-inconsistent-declaration-parameter-name.IgnoreMacros: 'true'
|
||||||
|
readability-inconsistent-declaration-parameter-name.Strict: 'false'
|
||||||
|
readability-redundant-declaration.IgnoreMacros: 'true'
|
||||||
|
readability-redundant-smartptr-get.IgnoreMacros: 'true'
|
||||||
|
readability-redundant-string-init.StringNames: '::std::basic_string_view;::std::basic_string'
|
||||||
|
readability-simplify-subscript-expr.Types: '::std::basic_string;::std::basic_string_view;::std::vector;::std::array;::std::span'
|
||||||
|
readability-uniqueptr-delete-release.PreferResetCall: 'false'
|
||||||
42
.github/workflows/all-builds.yml
vendored
@@ -10,6 +10,7 @@ env:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Qtk:
|
Qtk:
|
||||||
|
name: Qtk Applications
|
||||||
env:
|
env:
|
||||||
CONFIG: -DQTK_SUBMODULES=ON -DQTK_DEBUG=OFF -DQTK_CCACHE=OFF -DQTK_GUI=ON -DQTK_PLUGINS=OFF -DQTK_EXAMPLE=ON
|
CONFIG: -DQTK_SUBMODULES=ON -DQTK_DEBUG=OFF -DQTK_CCACHE=OFF -DQTK_GUI=ON -DQTK_PLUGINS=OFF -DQTK_EXAMPLE=ON
|
||||||
strategy:
|
strategy:
|
||||||
@@ -29,10 +30,10 @@ jobs:
|
|||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install Qt
|
- name: Install Qt
|
||||||
uses: jurplel/install-qt-action@v2
|
uses: jurplel/install-qt-action@v4
|
||||||
with:
|
with:
|
||||||
version: ${{ env.QT_VERSION }}
|
version: ${{ env.QT_VERSION }}
|
||||||
|
|
||||||
@@ -82,7 +83,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload package artifacts (DEB)
|
- name: Upload package artifacts (DEB)
|
||||||
if: matrix.os == 'ubuntu-latest'
|
if: matrix.os == 'ubuntu-latest'
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: qtk-gui-${{ matrix.os }}
|
name: qtk-gui-${{ matrix.os }}
|
||||||
path: |
|
path: |
|
||||||
@@ -97,7 +98,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload package artifacts (WIN)
|
- name: Upload package artifacts (WIN)
|
||||||
if: matrix.os == 'windows-latest'
|
if: matrix.os == 'windows-latest'
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: qtk-gui-${{ matrix.os }}
|
name: qtk-gui-${{ matrix.os }}
|
||||||
path: |
|
path: |
|
||||||
@@ -112,14 +113,14 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload package artifacts (OSX)
|
- name: Upload package artifacts (OSX)
|
||||||
if: matrix.os == 'macos-latest'
|
if: matrix.os == 'macos-latest'
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: qtk-gui-${{ matrix.os }}
|
name: qtk-gui-${{ matrix.os }}
|
||||||
path: |
|
path: |
|
||||||
build/packages/*.tar.gz
|
build/packages/*.tar.gz
|
||||||
|
|
||||||
- name: Upload Qtk install directory
|
- name: Upload Qtk install directory
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: qtk-gui-${{ matrix.os }}-install
|
name: qtk-gui-${{ matrix.os }}-install
|
||||||
path: install/*
|
path: install/*
|
||||||
@@ -132,7 +133,7 @@ jobs:
|
|||||||
# cmake --build build/ --target package_source
|
# cmake --build build/ --target package_source
|
||||||
#
|
#
|
||||||
# - name: Upload package artifacts
|
# - name: Upload package artifacts
|
||||||
# uses: actions/upload-artifact@v3
|
# uses: actions/upload-artifact@v4
|
||||||
# with:
|
# with:
|
||||||
# name: qtk-${{ matrix.os }}-packages
|
# name: qtk-${{ matrix.os }}-packages
|
||||||
# path: |
|
# path: |
|
||||||
@@ -140,6 +141,7 @@ jobs:
|
|||||||
# !build/packages/_CPack_Packages/*
|
# !build/packages/_CPack_Packages/*
|
||||||
|
|
||||||
Qtk-Library:
|
Qtk-Library:
|
||||||
|
name: Qtk library
|
||||||
env:
|
env:
|
||||||
CONFIG: -DQTK_SUBMODULES=ON -DQTK_DEBUG=OFF -DQTK_CCACHE=OFF -DQTK_GUI=OFF -DQTK_PLUGINS=OFF -DQTK_EXAMPLE=OFF
|
CONFIG: -DQTK_SUBMODULES=ON -DQTK_DEBUG=OFF -DQTK_CCACHE=OFF -DQTK_GUI=OFF -DQTK_PLUGINS=OFF -DQTK_EXAMPLE=OFF
|
||||||
strategy:
|
strategy:
|
||||||
@@ -159,10 +161,10 @@ jobs:
|
|||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install Qt
|
- name: Install Qt
|
||||||
uses: jurplel/install-qt-action@v2
|
uses: jurplel/install-qt-action@v4
|
||||||
with:
|
with:
|
||||||
version: ${{ env.QT_VERSION }}
|
version: ${{ env.QT_VERSION }}
|
||||||
|
|
||||||
@@ -201,7 +203,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload package artifacts (DEB)
|
- name: Upload package artifacts (DEB)
|
||||||
if: matrix.os == 'ubuntu-latest'
|
if: matrix.os == 'ubuntu-latest'
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: libqtk-${{ matrix.os }}
|
name: libqtk-${{ matrix.os }}
|
||||||
path: |
|
path: |
|
||||||
@@ -216,9 +218,9 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload package artifacts (WIN)
|
- name: Upload package artifacts (WIN)
|
||||||
if: matrix.os == 'windows-latest'
|
if: matrix.os == 'windows-latest'
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: qtk-${{ matrix.os }}
|
name: libqtk-${{ matrix.os }}
|
||||||
path: |
|
path: |
|
||||||
build/packages/*.exe
|
build/packages/*.exe
|
||||||
|
|
||||||
@@ -231,20 +233,21 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload package artifacts (OSX)
|
- name: Upload package artifacts (OSX)
|
||||||
if: matrix.os == 'macos-latest'
|
if: matrix.os == 'macos-latest'
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: qtk-${{ matrix.os }}
|
name: libqtk-${{ matrix.os }}
|
||||||
path: |
|
path: |
|
||||||
build/packages/*.tar.gz
|
build/packages/*.tar.gz
|
||||||
|
|
||||||
- name: Upload libqtk install
|
- name: Upload libqtk install
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
if: always()
|
if: always()
|
||||||
with:
|
with:
|
||||||
name: libqtk-${{ matrix.os }}-install
|
name: libqtk-${{ matrix.os }}-install
|
||||||
path: install/*
|
path: install/*
|
||||||
|
|
||||||
Qtk-Plugins:
|
Qtk-Plugins:
|
||||||
|
name: Qtk Qt Designer Plugins
|
||||||
env:
|
env:
|
||||||
CONFIG: -DQTK_SUBMODULES=ON -DQTK_DEBUG=OFF -DQTK_CCACHE=OFF -DQTK_GUI=OFF -DQTK_PLUGINS=ON -DQTK_EXAMPLE=OFF
|
CONFIG: -DQTK_SUBMODULES=ON -DQTK_DEBUG=OFF -DQTK_CCACHE=OFF -DQTK_GUI=OFF -DQTK_PLUGINS=ON -DQTK_EXAMPLE=OFF
|
||||||
strategy:
|
strategy:
|
||||||
@@ -264,10 +267,10 @@ jobs:
|
|||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install Qt
|
- name: Install Qt
|
||||||
uses: jurplel/install-qt-action@v2
|
uses: jurplel/install-qt-action@v4
|
||||||
with:
|
with:
|
||||||
version: ${{ env.QT_VERSION }}
|
version: ${{ env.QT_VERSION }}
|
||||||
|
|
||||||
@@ -292,6 +295,7 @@ jobs:
|
|||||||
run: cmake --install build/ --config Release --component qtk_plugins
|
run: cmake --install build/ --config Release --component qtk_plugins
|
||||||
|
|
||||||
Qtk-Assimp-Targets:
|
Qtk-Assimp-Targets:
|
||||||
|
name: Qtk Assimp Platform Targets
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
@@ -304,10 +308,10 @@ jobs:
|
|||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install Qt
|
- name: Install Qt
|
||||||
uses: jurplel/install-qt-action@v2
|
uses: jurplel/install-qt-action@v4
|
||||||
with:
|
with:
|
||||||
version: ${{ env.QT_VERSION }}
|
version: ${{ env.QT_VERSION }}
|
||||||
|
|
||||||
|
|||||||
14
.github/workflows/linting.yml
vendored
@@ -9,10 +9,10 @@ jobs:
|
|||||||
Tidy:
|
Tidy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install Qt
|
- name: Install Qt
|
||||||
uses: jurplel/install-qt-action@v2
|
uses: jurplel/install-qt-action@v4
|
||||||
with:
|
with:
|
||||||
version: '6.5.0'
|
version: '6.5.0'
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ jobs:
|
|||||||
- name: Build Qtk
|
- name: Build Qtk
|
||||||
run: |
|
run: |
|
||||||
cmake -B build -DQTK_SUBMODULES=OFF -DQTK_CCACHE=OFF -DQTK_PLUGINS=OFF -DQTK_GUI=ON
|
cmake -B build -DQTK_SUBMODULES=OFF -DQTK_CCACHE=OFF -DQTK_PLUGINS=OFF -DQTK_GUI=ON
|
||||||
cmake --build build --target qtk_gui -- -j $(nproc)
|
cmake --build build --target qtk_gui qtk_example -- -j $(nproc)
|
||||||
|
|
||||||
- uses: cpp-linter/cpp-linter-action@v2
|
- uses: cpp-linter/cpp-linter-action@v2
|
||||||
id: linter
|
id: linter
|
||||||
@@ -30,7 +30,7 @@ jobs:
|
|||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
with:
|
with:
|
||||||
# Use clang-tools 14
|
# Use clang-tools 14
|
||||||
version: '14'
|
version: '18'
|
||||||
# Don't use clang-format with this action
|
# Don't use clang-format with this action
|
||||||
# + Set to `file` to use .clang-format (Qtk formats with clang 15)
|
# + Set to `file` to use .clang-format (Qtk formats with clang 15)
|
||||||
style: ''
|
style: ''
|
||||||
@@ -57,12 +57,12 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
path:
|
path:
|
||||||
- 'src'
|
- 'src'
|
||||||
- 'app'
|
- 'example-app'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: clang-format Check
|
- name: clang-format Check
|
||||||
uses: jidicula/clang-format-action@v4.9.0
|
uses: jidicula/clang-format-action@v4.9.0
|
||||||
with:
|
with:
|
||||||
clang-format-version: '15'
|
clang-format-version: '18'
|
||||||
check-path: ${{ matrix.path }}
|
check-path: ${{ matrix.path }}
|
||||||
|
|||||||
2
.gitignore
vendored
@@ -5,7 +5,7 @@
|
|||||||
**/.vscode/**
|
**/.vscode/**
|
||||||
|
|
||||||
# CMake build files
|
# CMake build files
|
||||||
**/cmake-build-debug/**
|
**/cmake-build-*/**
|
||||||
**/build/**
|
**/build/**
|
||||||
install
|
install
|
||||||
|
|
||||||
|
|||||||
@@ -83,6 +83,8 @@ endif ()
|
|||||||
|
|
||||||
set(QTK_RESOURCES "${CMAKE_SOURCE_DIR}/resources")
|
set(QTK_RESOURCES "${CMAKE_SOURCE_DIR}/resources")
|
||||||
set(QTK_OSX_ICONS ${CMAKE_SOURCE_DIR}/resources/icons/osx/kilroy.icns)
|
set(QTK_OSX_ICONS ${CMAKE_SOURCE_DIR}/resources/icons/osx/kilroy.icns)
|
||||||
|
string(TIMESTAMP YEAR "%Y")
|
||||||
|
set(QTK_COPYRIGHT "All Content © 2021-${YEAR} Shaun Reed, all rights reserved.")
|
||||||
|
|
||||||
# Point CMAKE_PREFIX_PATH to Qt6 install directory
|
# Point CMAKE_PREFIX_PATH to Qt6 install directory
|
||||||
# If Qtk is built within Qt Creator this is not required.
|
# If Qtk is built within Qt Creator this is not required.
|
||||||
|
|||||||
118
README.md
@@ -3,28 +3,58 @@
|
|||||||
[](https://github.com/shaunrd0/qtk/actions/workflows/all-builds.yml)
|
[](https://github.com/shaunrd0/qtk/actions/workflows/all-builds.yml)
|
||||||
[](https://github.com/shaunrd0/qtk/actions/workflows/linting.yml)
|
[](https://github.com/shaunrd0/qtk/actions/workflows/linting.yml)
|
||||||
|
|
||||||
Qtk is a Qt OpenGL graphics library created primarily for my own learning
|
Qtk is a Qt OpenGL graphics library that wraps some QOpenGL functionality in convenience classes
|
||||||
purposes. The library wraps some QOpenGL functionality in convenience classes
|
|
||||||
that allow rendering geometry in 2D and 3D using custom GLSL shader programs.
|
that allow rendering geometry in 2D and 3D using custom GLSL shader programs.
|
||||||
|
|
||||||
The long-term goal for this project is to create a tool that I can use to
|
The Qtk desktop application provides a model loader using [Assimp](https://assimp.org/) within a Qt widget application.
|
||||||
practice shader coding or graphics programming techniques. In doing this I hope
|
You can fly around the scene using WASD while holding down the right mouse button.
|
||||||
to also learn more about the Qt UI framework, and the CMake build system.
|
|
||||||
|
Object names can be double-clicked in the tree view panel for quick camera navigation.
|
||||||
|
Properties of the object, like shader code and translation / scale, can be viewed and modified in the side panel.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
All side panels and toolbars are dockable widgets that can be popped out
|
||||||
|
and reorganized as needed. Panels can also be stacked to create a docked widget with
|
||||||
|
tabs. The central widget that provides the camera view into the scene cannot be
|
||||||
|
detached from the main window in this way.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
The small triangles floating near 3D models represent the light source being used for the shader.
|
||||||
|
These appear on models using phong, specular, and diffuse lighting techniques.
|
||||||
|
|
||||||
|
The default scene contains basic examples like texture mapping to make a crate from basic cube geometry
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Examples of Ambient, Diffuse, and Specular GLSL shaders.
|
||||||
|
|
||||||
|
| Ambient | Diffuse | Specular |
|
||||||
|
|-------------------------------------------------------|-------------------------------------------------------|--------------------------------------------------------|
|
||||||
|
| <img src="resources/screenshots/screen-ambient.png"/> | <img src="resources/screenshots/screen-diffuse.png"/> | <img src="resources/screenshots/screen-specular.png"/> |
|
||||||
|
|
||||||
|
And more advanced techniques like Phong lighting (ambient + diffuse + specular) and normal mapping.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
| Normal Mapping Disabled | Normal Mapping Enabled |
|
||||||
|
|------------------------------------------------------|--------------------------------------------------------|
|
||||||
|
| <img src="resources/screenshots/spartan-phong.png"/> | <img src="resources/screenshots/spartan-normals.png"/> |
|
||||||
|
|
||||||
|
See the `View` toolbar menu to enable debug console widgets for open scenes or reopen previously closed panels.
|
||||||
|
|
||||||
Key features that are planned:
|
Key features that are planned:
|
||||||
|
|
||||||
* Runtime loading of `.obj` or similar 3D models.
|
- [x] Runtime loading of `.obj` or similar 3D models.
|
||||||
* Drag-and-drop interaction for adding objects to the scene.
|
- [x] Drag-and-drop interaction for adding objects to the scene.
|
||||||
* Runtime reloading of modified GLSL shaders attached to objects within scenes.
|
- [x] Shader / object properties panel to modify related settings.
|
||||||
* Multiple views of a scene at one time.
|
- [ ] Runtime reloading of modified GLSL shaders attached to objects within scenes.
|
||||||
* Camera control modes such as panning, orbiting, or following objects.
|
- [ ] Multiple views of a scene at one time.
|
||||||
* Save / load for scene data. The current inheritance model is temporary.
|
- [ ] Camera control modes such as panning, orbiting, or following objects.
|
||||||
* Basic text editor for quickly modifying shaders attached to objects.
|
- [ ] Save / load scene data. The current model requires writing C++ code.
|
||||||
* Shader / object properties panel to modify related settings.
|
- [ ] Basic text editor for quickly modifying shaders attached to objects.
|
||||||
* Reduce size of application resources and git references.
|
- [ ] Reduce size of application resources and git references.
|
||||||
|
|
||||||
The Qtk desktop application provides a model loader
|
|
||||||
using [Assimp](https://assimp.org/) within a Qt widget application.
|
|
||||||
|
|
||||||
For examples of using the Qtk API, see the `example-app` project in the root of
|
For examples of using the Qtk API, see the `example-app` project in the root of
|
||||||
this repository.
|
this repository.
|
||||||
@@ -177,55 +207,29 @@ cmake --install build-all/ --component qtk_example --prefix=install
|
|||||||
See the README in the [example-app/](example-app) subdirectory for instructions
|
See the README in the [example-app/](example-app) subdirectory for instructions
|
||||||
on standalone builds.
|
on standalone builds.
|
||||||
|
|
||||||
### Controls
|
|
||||||
|
|
||||||
You can fly around the scene if you hold the right mouse button and use WASD.
|
|
||||||
If you see a small triangle floating by a model it represents the light source
|
|
||||||
that is being used for the shader rendering the model. These appear on models
|
|
||||||
using phong, specular, and diffuse lighting techniques.
|
|
||||||
|
|
||||||
Object names can be double-clicked in the tree view panel for quick camera
|
|
||||||
navigation. All panels and toolbars are dockable widgets that can be popped out
|
|
||||||
and reorganized as needed. Panels can be stacked to create a docked widget with
|
|
||||||
tabs. The central widget that provides the camera view into the scene cannot be
|
|
||||||
detached from the main window in this way. See the `View` menu to enable debug
|
|
||||||
console widgets for open scenes or reopen previously closed panels.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Spartan with no normals -
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Spartan with normals -
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
#### Development
|
#### Development
|
||||||
|
|
||||||
This project uses version `15.0.5` of `clang-format`.
|
This project is using `clang-format` version `>=15.0.5`.
|
||||||
Before merging any branch we should run `clang-tidy` followed by `clang-format`.
|
On Ubuntu 24.04, clang-format 18 is available to install in apt repositories.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone git@github.com:llvm/llvm-project.git -b llvmorg-15.0.5
|
sudo apt install clang-format
|
||||||
cd llvm-project
|
|
||||||
cmake -B build -DLLVM_ENABLE_PROJECTS=clang -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles" llvm
|
|
||||||
cmake --build build -j $(nproc --ignore=2)
|
|
||||||
sudo cmake --build build -j $(nproc --ignore=2) --target install
|
|
||||||
```
|
```
|
||||||
|
|
||||||
If the `clang-format` version is any earlier than `15.0.0`,
|
If `clang-format --version` is any earlier than `15.0.0`, running `clang-format` will fail because this project uses configuration options made available since `15.0.0`.
|
||||||
running `clang-format` will fail because this project uses configuration options
|
|
||||||
made available since `15.0.0`.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
clang-format --version
|
clang-format --version
|
||||||
clang-format version 15.0.5 (git@github.com:llvm/llvm-project.git 154e88af7ec97d9b9f389e55d45bf07108a9a097)
|
Ubuntu clang-format version 18.1.3 (1ubuntu1)
|
||||||
```
|
```
|
||||||
|
|
||||||
CLion has integration for IDE code reformatting actions with `clang-format`.
|
CLion has integration for IDE code reformatting actions with `clang-format`.
|
||||||
If you're using CLion, the `.clang-format` configuration will be picked up by
|
If you're using CLion, the `.clang-format` configuration will be picked up by CLion automatically.
|
||||||
CLion automatically.
|
|
||||||
|
This repository provides the [`tools/format.sh`](./tools/format.sh) helper script to run `clang-tidy` and `clang-format` on Ubuntu 24.04.
|
||||||
|
Running the script will build Qtk, so it's important to ensure you can manually build from source first.
|
||||||
|
|
||||||
|
If you'd still like to run these tools manually, see the instructions below.
|
||||||
|
|
||||||
`clang-tidy` can be run with the following commands.
|
`clang-tidy` can be run with the following commands.
|
||||||
|
|
||||||
@@ -234,14 +238,14 @@ CLion automatically.
|
|||||||
cd qtk
|
cd qtk
|
||||||
# Build
|
# Build
|
||||||
cmake -B build && cmake --build build -- -j $(nproc)
|
cmake -B build && cmake --build build -- -j $(nproc)
|
||||||
clang-tidy -p build/ --fix --config-file=.clang-tidy src/*.cpp src/*.h app/*.cpp app/*.h
|
clang-tidy -p build/ --fix --config-file=.clang-tidy src/**/*.cpp src/**/*.h example-app/*.cpp example-app/*.h
|
||||||
```
|
```
|
||||||
|
|
||||||
Last we need to run `clang-format`, this can be done with the command directly.
|
Last we need to run `clang-format`, this can be done with the command directly.
|
||||||
This will reformat all the code in the repository.
|
This will reformat all the code in the repository.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
clang-format -i --style=file:.clang-format src/app/*.cpp src/app/*.h src/qtk/*.cpp src/qtk/*.h example-app/*.cpp example-app/*.h
|
clang-format -i --style=file:.clang-format src/**/*.cpp src/**/*.h example-app/*.cpp example-app/*.h
|
||||||
```
|
```
|
||||||
|
|
||||||
`clang-format` can be run with git integration (or CLion if you prefer).
|
`clang-format` can be run with git integration (or CLion if you prefer).
|
||||||
@@ -304,7 +308,7 @@ To generate packages for Qtk desktop application, we should
|
|||||||
set `-DQTK_GUI=ON`. If this option is not set we will only package libqtk.
|
set `-DQTK_GUI=ON`. If this option is not set we will only package libqtk.
|
||||||
|
|
||||||
The NSIS installer will allow component-specific path modification for all of
|
The NSIS installer will allow component-specific path modification for all of
|
||||||
these installation components through a GUI install application.
|
these installation components through a Windows GUI install application.
|
||||||
|
|
||||||
##### Resources
|
##### Resources
|
||||||
|
|
||||||
|
|||||||
@@ -11,26 +11,26 @@
|
|||||||
|
|
||||||
using namespace Qtk;
|
using namespace Qtk;
|
||||||
|
|
||||||
ExampleScene::ExampleScene(Qtk::Scene * scene) : Qtk::SceneInterface(scene) {
|
ExampleScene::ExampleScene()
|
||||||
|
{
|
||||||
setSceneName("Example Scene");
|
setSceneName("Example Scene");
|
||||||
getCamera().getTransform().setTranslation(-8.0f, 0.0f, 10.0f);
|
getCamera().getTransform().setTranslation(-8.0f, 0.0f, 10.0f);
|
||||||
getCamera().getTransform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f);
|
getCamera().getTransform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExampleScene::~ExampleScene() {}
|
ExampleScene::~ExampleScene() = default;
|
||||||
|
|
||||||
void ExampleScene::init() {
|
void ExampleScene::init()
|
||||||
auto skybox = new Qtk::Skybox("Skybox");
|
{
|
||||||
setSkybox(skybox);
|
setSkybox(new Qtk::Skybox("Skybox"));
|
||||||
|
|
||||||
std::string spartanPath = QTK_EXAMPLE_SOURCE_DIR;
|
std::string spartanPath = QTK_EXAMPLE_SOURCE_DIR;
|
||||||
spartanPath += "/resources/models/spartan/spartan.obj";
|
spartanPath += "/../resources/models/spartan/spartan.obj";
|
||||||
auto spartan = new Model("spartan", spartanPath.c_str());
|
auto spartan = addObject(new Model("spartan", spartanPath.c_str()));
|
||||||
addObject(spartan);
|
|
||||||
spartan->getTransform().setTranslation(-4.0f, 0.0f, 0.0f);
|
spartan->getTransform().setTranslation(-4.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
auto mesh = addObject(
|
auto mesh = addObject(
|
||||||
new Qtk::MeshRenderer("rightTriangle", Triangle(QTK_DRAW_ARRAYS)));
|
new Qtk::MeshRenderer("rightTriangle", Triangle(QTK_DRAW_ELEMENTS)));
|
||||||
mesh->getTransform().setTranslation(-5.0f, 0.0f, -2.0f);
|
mesh->getTransform().setTranslation(-5.0f, 0.0f, -2.0f);
|
||||||
|
|
||||||
// QTK_DRAW_ARRAYS is the default for generic shapes in qtk/shape.h
|
// QTK_DRAW_ARRAYS is the default for generic shapes in qtk/shape.h
|
||||||
@@ -56,11 +56,20 @@ void ExampleScene::init() {
|
|||||||
mesh->setColor(GREEN);
|
mesh->setColor(GREEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExampleScene::draw() {
|
void ExampleScene::draw()
|
||||||
|
{
|
||||||
|
// The base class method _must_ be called first, before additional logic.
|
||||||
Scene::draw();
|
Scene::draw();
|
||||||
|
|
||||||
|
// No additional custom draw logic for this example.
|
||||||
|
// QtkScene in Qtk desktop application is an example using custom draw logic.
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExampleScene::update() {
|
void ExampleScene::update()
|
||||||
|
{
|
||||||
|
auto top_triangle = MeshRenderer::getInstance("topTriangle");
|
||||||
|
auto bottom_triangle = MeshRenderer::getInstance("bottomTriangle");
|
||||||
|
|
||||||
// Pitch forward and roll sideways
|
// Pitch forward and roll sideways
|
||||||
MeshRenderer::getInstance("leftTriangle")
|
MeshRenderer::getInstance("leftTriangle")
|
||||||
->getTransform()
|
->getTransform()
|
||||||
@@ -69,27 +78,20 @@ void ExampleScene::update() {
|
|||||||
->getTransform()
|
->getTransform()
|
||||||
.rotate(0.75f, 0.0f, 0.0f, 1.0f);
|
.rotate(0.75f, 0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
// Make the top and bottom triangles slide left-to-right.
|
||||||
static float translateX = 0.025f;
|
static float translateX = 0.025f;
|
||||||
float limit = -9.0f; // Origin position.x - 2.0f
|
float limit = -9.0f; // Origin position.x - 2.0f
|
||||||
float posX = MeshRenderer::getInstance("topTriangle")
|
float posX = top_triangle->getTransform().getTranslation().x();
|
||||||
->getTransform()
|
|
||||||
.getTranslation()
|
|
||||||
.x();
|
|
||||||
if (posX < limit || posX > limit + 4.0f) {
|
if (posX < limit || posX > limit + 4.0f) {
|
||||||
translateX = -translateX;
|
translateX = -translateX;
|
||||||
}
|
}
|
||||||
MeshRenderer::getInstance("topTriangle")
|
|
||||||
->getTransform()
|
top_triangle->getTransform().translate(translateX, 0.0f, 0.0f);
|
||||||
.translate(translateX, 0.0f, 0.0f);
|
bottom_triangle->getTransform().translate(-translateX, 0.0f, 0.0f);
|
||||||
MeshRenderer::getInstance("bottomTriangle")
|
|
||||||
->getTransform()
|
// Apply some rotation to the triangles as they move left-to-right.
|
||||||
.translate(-translateX, 0.0f, 0.0f);
|
top_triangle->getTransform().rotate(0.75f, 0.2f, 0.0f, 0.4f);
|
||||||
MeshRenderer::getInstance("topTriangle")
|
bottom_triangle->getTransform().rotate(0.75f, 0.0f, 0.2f, 0.4f);
|
||||||
->getTransform()
|
|
||||||
.rotate(0.75f, 0.2f, 0.0f, 0.4f);
|
|
||||||
MeshRenderer::getInstance("bottomTriangle")
|
|
||||||
->getTransform()
|
|
||||||
.rotate(0.75f, 0.0f, 0.2f, 0.4f);
|
|
||||||
|
|
||||||
MeshRenderer::getInstance("centerCube")
|
MeshRenderer::getInstance("centerCube")
|
||||||
->getTransform()
|
->getTransform()
|
||||||
|
|||||||
@@ -11,16 +11,30 @@
|
|||||||
|
|
||||||
#include <qtk/scene.h>
|
#include <qtk/scene.h>
|
||||||
|
|
||||||
class ExampleScene : public Qtk::SceneInterface {
|
class ExampleScene : public Qtk::Scene
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
ExampleScene(Qtk::Scene * scene);
|
explicit ExampleScene();
|
||||||
|
|
||||||
~ExampleScene();
|
~ExampleScene();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override the initialization logic for the scene.
|
||||||
|
* This method should up the scene's objects, skybox, etc.
|
||||||
|
*/
|
||||||
void init() override;
|
void init() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optionally override the draw method for the scene.
|
||||||
|
*
|
||||||
|
* This is just here for example, it should be omitted entirely if we don't
|
||||||
|
* want to provide a custom implementation for the ExampleScene.
|
||||||
|
*/
|
||||||
void draw() override;
|
void draw() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update objects in the scene for translation or rotation.
|
||||||
|
*/
|
||||||
void update() override;
|
void update() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,8 @@
|
|||||||
#include "examplewidget.h"
|
#include "examplewidget.h"
|
||||||
|
|
||||||
ExampleWidget::ExampleWidget(QWidget * parent) :
|
ExampleWidget::ExampleWidget(QWidget * parent) :
|
||||||
QOpenGLWidget(parent), mScene(new ExampleScene(new Qtk::SceneEmpty)) {
|
QOpenGLWidget(parent), mScene(new ExampleScene)
|
||||||
|
{
|
||||||
// NOTE: The decorator pattern is used to save / load scenes in Qtk currently.
|
// NOTE: The decorator pattern is used to save / load scenes in Qtk currently.
|
||||||
// The initializer above sets mScene to the concrete decorator ExampleScene.
|
// The initializer above sets mScene to the concrete decorator ExampleScene.
|
||||||
// Qtk::SceneEmpty provides an empty scene as the concrete component.
|
// Qtk::SceneEmpty provides an empty scene as the concrete component.
|
||||||
@@ -27,7 +28,8 @@ ExampleWidget::ExampleWidget(QWidget * parent) :
|
|||||||
setFocusPolicy(Qt::ClickFocus);
|
setFocusPolicy(Qt::ClickFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExampleWidget::initializeGL() {
|
void ExampleWidget::initializeGL()
|
||||||
|
{
|
||||||
initializeOpenGLFunctions();
|
initializeOpenGLFunctions();
|
||||||
connect(this, SIGNAL(frameSwapped()), this, SLOT(update()));
|
connect(this, SIGNAL(frameSwapped()), this, SLOT(update()));
|
||||||
glEnable(GL_MULTISAMPLE);
|
glEnable(GL_MULTISAMPLE);
|
||||||
@@ -40,18 +42,21 @@ void ExampleWidget::initializeGL() {
|
|||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExampleWidget::resizeGL(int width, int height) {
|
void ExampleWidget::resizeGL(int width, int height)
|
||||||
|
{
|
||||||
Qtk::Scene::getProjectionMatrix().setToIdentity();
|
Qtk::Scene::getProjectionMatrix().setToIdentity();
|
||||||
Qtk::Scene::getProjectionMatrix().perspective(
|
Qtk::Scene::getProjectionMatrix().perspective(
|
||||||
45.0f, float(width) / float(height), 0.1f, 1000.0f);
|
45.0f, float(width) / float(height), 0.1f, 1000.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExampleWidget::paintGL() {
|
void ExampleWidget::paintGL()
|
||||||
|
{
|
||||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||||
mScene->draw();
|
mScene->draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExampleWidget::update() {
|
void ExampleWidget::update()
|
||||||
|
{
|
||||||
mScene->update();
|
mScene->update();
|
||||||
QWidget::update();
|
QWidget::update();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,8 @@
|
|||||||
|
|
||||||
#include "examplescene.h"
|
#include "examplescene.h"
|
||||||
|
|
||||||
class ExampleWidget : public QOpenGLWidget, protected QOpenGLFunctions {
|
class ExampleWidget : public QOpenGLWidget, protected QOpenGLFunctions
|
||||||
|
{
|
||||||
Q_OBJECT;
|
Q_OBJECT;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -11,7 +11,8 @@
|
|||||||
|
|
||||||
#include "examplewidget.h"
|
#include "examplewidget.h"
|
||||||
|
|
||||||
int main(int argc, char * argv[]) {
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
auto window = new QMainWindow;
|
auto window = new QMainWindow;
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 79 KiB |
BIN
resources/icons/linux/kilroy-128.png
Normal file
|
After Width: | Height: | Size: 7.3 KiB |
BIN
resources/icons/linux/kilroy-16.png
Normal file
|
After Width: | Height: | Size: 398 B |
BIN
resources/icons/linux/kilroy-256.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
resources/icons/linux/kilroy-32.png
Normal file
|
After Width: | Height: | Size: 755 B |
BIN
resources/icons/linux/kilroy-48.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/icons/linux/kilroy-64.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
11
resources/icons/linux/linux-icons.sh
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# $1: Input path to an image to use for generating icons.
|
||||||
|
# Helper script to generate qtk's icons for Linux given a path to an input PNG.
|
||||||
|
sudo apt install imagemagick
|
||||||
|
|
||||||
|
convert "$1" -resize 256x256 kilroy-256.png
|
||||||
|
convert "$1" -resize 128x128 kilroy-128.png
|
||||||
|
convert "$1" -resize 64x64 kilroy-64.png
|
||||||
|
convert "$1" -resize 48x48 kilroy-48.png
|
||||||
|
convert "$1" -resize 32x32 kilroy-32.png
|
||||||
|
convert "$1" -resize 16x16 kilroy-16.png
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
|
|
||||||
```bash
|
|
||||||
sudo apt install icnsutils
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
convert icon.png -resize 32x32 kilroy_32.png
|
|
||||||
convert icon.png -resize 16x16 kilroy_16.png
|
|
||||||
convert icon.png -resize 48x48 kilroy_48.png
|
|
||||||
convert icon.png -resize 128x128 kilroy_128.png
|
|
||||||
convert icon.png -resize 256x256 kilroy_256.png
|
|
||||||
png2icns png2icns kilroy.icns kilroy_*.png
|
|
||||||
```
|
|
||||||
BIN
resources/icons/osx/kilroy_splash.png
Normal file
|
After Width: | Height: | Size: 66 KiB |
15
resources/icons/osx/osx-icons.sh
Executable file
@@ -0,0 +1,15 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# $1: Input path to an image to use for generating icons.
|
||||||
|
# Helper script to generate qtk's icons for OSX given a path to an input PNG.
|
||||||
|
sudo apt install icnsutils imagemagick
|
||||||
|
|
||||||
|
convert "$1" -resize 32x32 kilroy_32.png
|
||||||
|
convert "$1" -resize 16x16 kilroy_16.png
|
||||||
|
convert "$1" -resize 48x48 kilroy_48.png
|
||||||
|
convert "$1" -resize 128x128 kilroy_128.png
|
||||||
|
convert "$1" -resize 256x256 kilroy_256.png
|
||||||
|
# For the application bundle in OSX.
|
||||||
|
png2icns png2icns kilroy.icns kilroy_*.png
|
||||||
|
|
||||||
|
# For the splash image in DMG installers.
|
||||||
|
convert "$1" -resize 800x600! kilroy_splash.png
|
||||||
BIN
resources/icons/win/kilroy.ico
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
resources/icons/win/kilroy_splash.bmp
Normal file
|
After Width: | Height: | Size: 201 KiB |
10
resources/icons/win/win-icons.sh
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# $1: Input path to an image to use for generating icons.
|
||||||
|
# Helper script to generate qtk's icons for OSX given a path to an input PNG.
|
||||||
|
sudo apt install imagemagick
|
||||||
|
|
||||||
|
# For the NSIS (un)installer executable shortcut icon.
|
||||||
|
convert "$1" -resize 256x256,128x128,64x64,48x48,32x32,16x16 -background transparent -colors 256 kilroy.ico
|
||||||
|
|
||||||
|
# For the NSIS installer splash screen.
|
||||||
|
convert "$1" -resize 164x314! -background white -flatten kilroy_splash.bmp
|
||||||
6
resources/qtk.desktop
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Name=Qtk
|
||||||
|
Exec=/usr/bin/qtk_gui
|
||||||
|
Icon=qtk
|
||||||
|
Type=Application
|
||||||
|
Categories=Utility;
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
<file>fontawesome-free-6.2.1-desktop/svgs/regular/folder-open.svg</file>
|
<file>fontawesome-free-6.2.1-desktop/svgs/regular/folder-open.svg</file>
|
||||||
<file>fontawesome-free-6.2.1-desktop/svgs/regular/floppy-disk.svg</file>
|
<file>fontawesome-free-6.2.1-desktop/svgs/regular/floppy-disk.svg</file>
|
||||||
<file>fontawesome-free-6.2.1-desktop/svgs/brands/git-alt.svg</file>
|
<file>fontawesome-free-6.2.1-desktop/svgs/brands/git-alt.svg</file>
|
||||||
<file>icon.png</file>
|
<file alias="icon.png">icons/icon.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
<qresource prefix="/shaders">
|
<qresource prefix="/shaders">
|
||||||
<file alias="model.frag">shaders/fragment/model.frag</file>
|
<file alias="model.frag">shaders/fragment/model.frag</file>
|
||||||
@@ -46,8 +46,8 @@
|
|||||||
<file alias="solid-phong.vert">shaders/vertex/solid-phong.vert</file>
|
<file alias="solid-phong.vert">shaders/vertex/solid-phong.vert</file>
|
||||||
<file alias="model-basic.frag">shaders/fragment/model-basic.frag</file>
|
<file alias="model-basic.frag">shaders/fragment/model-basic.frag</file>
|
||||||
<file alias="model-basic.vert">shaders/vertex/model-basic.vert</file>
|
<file alias="model-basic.vert">shaders/vertex/model-basic.vert</file>
|
||||||
<file alias="model-specular.frag">shaders/fragment/model-specular.frag</file>
|
<file alias="model-phong.frag">shaders/fragment/model-phong.frag</file>
|
||||||
<file alias="model-specular.vert">shaders/vertex/model-specular.vert</file>
|
<file alias="model-phong.vert">shaders/vertex/model-phong.vert</file>
|
||||||
<file alias="model-normals.frag">shaders/fragment/model-normals.frag</file>
|
<file alias="model-normals.frag">shaders/fragment/model-normals.frag</file>
|
||||||
<file alias="model-normals.vert">shaders/vertex/model-normals.vert</file>
|
<file alias="model-normals.vert">shaders/vertex/model-normals.vert</file>
|
||||||
<file alias="skybox.frag">skybox/skybox.frag</file>
|
<file alias="skybox.frag">skybox/skybox.frag</file>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 316 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 89 KiB |
|
Before Width: | Height: | Size: 263 KiB After Width: | Height: | Size: 263 KiB |
BIN
resources/screenshots/screen-1.png
Normal file
|
After Width: | Height: | Size: 428 KiB |
BIN
resources/screenshots/screen-ambient.png
Normal file
|
After Width: | Height: | Size: 205 KiB |
BIN
resources/screenshots/screen-diffuse.png
Normal file
|
After Width: | Height: | Size: 188 KiB |
BIN
resources/screenshots/screen-phong.png
Normal file
|
After Width: | Height: | Size: 264 KiB |
BIN
resources/screenshots/screen-specular.png
Normal file
|
After Width: | Height: | Size: 176 KiB |
BIN
resources/screenshots/screen-texture.png
Normal file
|
After Width: | Height: | Size: 288 KiB |
BIN
resources/screenshots/screen.png
Normal file
|
After Width: | Height: | Size: 437 KiB |
BIN
resources/screenshots/spartan-normals.png
Normal file
|
After Width: | Height: | Size: 359 KiB |
BIN
resources/screenshots/spartan-phong.png
Normal file
|
After Width: | Height: | Size: 349 KiB |
|
Before Width: | Height: | Size: 660 KiB |
|
Before Width: | Height: | Size: 646 KiB |
@@ -103,26 +103,26 @@ configure_package_config_file(
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
|
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
|
||||||
|
set(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/README.md")
|
||||||
set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
|
set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
|
||||||
set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
|
set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
|
||||||
set(CPACK_PACKAGE_VENDOR "Shaun Reed")
|
set(CPACK_PACKAGE_VENDOR "Shaun Reed")
|
||||||
|
if (QTK_GUI)
|
||||||
|
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Qt OpenGL 3D graphics renderer.")
|
||||||
|
else()
|
||||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Qt OpenGL 3D graphics library.")
|
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Qt OpenGL 3D graphics library.")
|
||||||
set(CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/shaunrd0/qtk")
|
endif()
|
||||||
|
set(CPACK_PACKAGE_HOMEPAGE_URL "https://git.shaunreed.com/shaunrd0/qtk")
|
||||||
set(CPACK_SOURCE_IGNORE_FILES build*;install;\.git;\.github;\.idea)
|
set(CPACK_SOURCE_IGNORE_FILES build*;install;\.git;\.github;\.idea)
|
||||||
set(CPACK_PACKAGE_DIRECTORY packages/)
|
set(CPACK_PACKAGE_DIRECTORY packages/)
|
||||||
set(CPACK_PACKAGE_CONTACT "shaunreed.com")
|
set(CPACK_PACKAGE_CONTACT "shaunreed.com")
|
||||||
#set(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/resources/icon.png")
|
|
||||||
set(CPACK_THREADS 0)
|
set(CPACK_THREADS 0)
|
||||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "Qtk")
|
set(CPACK_PACKAGE_INSTALL_DIRECTORY "Qtk")
|
||||||
|
|
||||||
# Remove any assimp components if defined by submodule.
|
if (WIN32)
|
||||||
if (QTK_SUBMODULES)
|
|
||||||
get_cmake_property(CPACK_COMPONENTS_ALL COMPONENTS)
|
|
||||||
list(FILTER CPACK_COMPONENTS_ALL EXCLUDE REGEX .*assimp.*)
|
|
||||||
list(REMOVE_ITEM CPACK_COMPONENTS_ALL Unspecified)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Windows
|
# Windows
|
||||||
|
# Set icon for the splash image used in Windows NSIS installers.
|
||||||
|
set(CPACK_PACKAGE_ICON "${QTK_RESOURCES}/icons/win/kilroy_splash.bmp")
|
||||||
set(CPACK_NSIS_MODIFY_PATH ON)
|
set(CPACK_NSIS_MODIFY_PATH ON)
|
||||||
set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
|
set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
|
||||||
# https://nsis.sourceforge.io/Reference/CreateShortCut
|
# https://nsis.sourceforge.io/Reference/CreateShortCut
|
||||||
@@ -134,18 +134,57 @@ set(
|
|||||||
CPACK_NSIS_DELETE_ICONS_EXTRA
|
CPACK_NSIS_DELETE_ICONS_EXTRA
|
||||||
"Delete '$SMPROGRAMS\\\\$START_MENU\\\\Qtk.lnk'"
|
"Delete '$SMPROGRAMS\\\\$START_MENU\\\\Qtk.lnk'"
|
||||||
)
|
)
|
||||||
# TODO: Icons for NSIS installer.
|
|
||||||
#set(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/resources/icon.png")
|
|
||||||
#set(CPACK_NSIS_MUI_UNIICON "${CMAKE_SOURCE_DIR}/resources/icon.png")
|
|
||||||
|
|
||||||
# Debian
|
|
||||||
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE ${CPACK_PACKAGE_HOMEPAGE_URL})
|
|
||||||
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
|
|
||||||
|
|
||||||
|
# Set icon for the installer executable.
|
||||||
|
set(CPACK_NSIS_MUI_ICON "${QTK_RESOURCES}/icons/win/kilroy.ico")
|
||||||
|
# Set icon for uninstaller executable.
|
||||||
|
set(CPACK_NSIS_MUI_UNIICON "${QTK_RESOURCES}/icons/win/kilroy.ico")
|
||||||
|
elseif(APPLE)
|
||||||
# OSX
|
# OSX
|
||||||
|
# Set icon for the splash image used in OSX DMG installers.
|
||||||
|
set(CPACK_PACKAGE_ICON "${QTK_RESOURCES}/icons/osx/kilroy_splash.bmp")
|
||||||
|
|
||||||
|
# Set additional options for the OSX bundle.
|
||||||
set(CPACK_BUNDLE_NAME ${PROJECT_NAME})
|
set(CPACK_BUNDLE_NAME ${PROJECT_NAME})
|
||||||
set(CPACK_BUNDLE_PLIST $<TARGET_BUNDLE_CONTENT_DIR:qtk_gui>/Info.plist)
|
set(CPACK_BUNDLE_PLIST $<TARGET_BUNDLE_CONTENT_DIR:qtk_gui>/Info.plist)
|
||||||
set(CPACK_BUNDLE_ICON ${QTK_OSX_ICONS})
|
set(CPACK_BUNDLE_ICON ${QTK_OSX_ICONS})
|
||||||
|
else(UNIX)
|
||||||
|
# Linux
|
||||||
|
# Install icons for qtk.
|
||||||
|
install(FILES ${QTK_RESOURCES}/icons/linux/kilroy-16.png
|
||||||
|
DESTINATION /usr/share/icons/hicolor/16x16/apps
|
||||||
|
RENAME qtk.png)
|
||||||
|
install(FILES ${QTK_RESOURCES}/icons/linux/kilroy-32.png
|
||||||
|
DESTINATION /usr/share/icons/hicolor/32x32/apps
|
||||||
|
RENAME qtk.png)
|
||||||
|
install(FILES ${QTK_RESOURCES}/icons/linux/kilroy-48.png
|
||||||
|
DESTINATION /usr/share/icons/hicolor/48x48/apps
|
||||||
|
RENAME qtk.png)
|
||||||
|
install(FILES ${QTK_RESOURCES}/icons/linux/kilroy-64.png
|
||||||
|
DESTINATION /usr/share/icons/hicolor/64x64/apps
|
||||||
|
RENAME qtk.png)
|
||||||
|
install(FILES ${QTK_RESOURCES}/icons/linux/kilroy-128.png
|
||||||
|
DESTINATION /usr/share/icons/hicolor/128x128/apps
|
||||||
|
RENAME qtk.png)
|
||||||
|
install(FILES ${QTK_RESOURCES}/icons/linux/kilroy-256.png
|
||||||
|
DESTINATION /usr/share/icons/hicolor/256x256/apps
|
||||||
|
RENAME qtk.png)
|
||||||
|
|
||||||
|
# Install the desktop file for qtk.
|
||||||
|
install(FILES ${QTK_RESOURCES}/qtk.desktop
|
||||||
|
DESTINATION /usr/share/applications)
|
||||||
|
|
||||||
|
# Set additional options for the debian APT package.
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE ${CPACK_PACKAGE_HOMEPAGE_URL})
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Remove any assimp components if defined by submodule.
|
||||||
|
if (QTK_SUBMODULES)
|
||||||
|
get_cmake_property(CPACK_COMPONENTS_ALL COMPONENTS)
|
||||||
|
list(FILTER CPACK_COMPONENTS_ALL EXCLUDE REGEX .*assimp.*)
|
||||||
|
list(REMOVE_ITEM CPACK_COMPONENTS_ALL Unspecified)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Platform defaults for source bundles.
|
# Platform defaults for source bundles.
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
|||||||
@@ -57,15 +57,18 @@ set(
|
|||||||
qt_add_executable(qtk_gui ${QTK_GUI_SOURCES})
|
qt_add_executable(qtk_gui ${QTK_GUI_SOURCES})
|
||||||
target_link_libraries(qtk_gui PRIVATE qtk_plugin_library)
|
target_link_libraries(qtk_gui PRIVATE qtk_plugin_library)
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
set_target_properties(qtk_gui PROPERTIES WIN32_EXECUTABLE TRUE)
|
||||||
|
elseif(APPLE)
|
||||||
set_target_properties(
|
set_target_properties(
|
||||||
qtk_gui PROPERTIES
|
qtk_gui PROPERTIES
|
||||||
WIN32_EXECUTABLE TRUE
|
|
||||||
MACOSX_BUNDLE TRUE
|
MACOSX_BUNDLE TRUE
|
||||||
MACOSX_BUNDLE_BUNDLE_NAME Qtk
|
MACOSX_BUNDLE_BUNDLE_NAME Qtk
|
||||||
MACOSX_BUNDLE_ICON_FILE ${QTK_OSX_ICONS}
|
MACOSX_BUNDLE_ICON_FILE ${QTK_OSX_ICONS}
|
||||||
MACOSX_BUNDLE_GUI_IDENTIFIER ${CMAKE_PROJECT_NAME}
|
MACOSX_BUNDLE_GUI_IDENTIFIER ${CMAKE_PROJECT_NAME}
|
||||||
MACOSX_BUNDLE_INFO_STRING ${CMAKE_PROJECT_DESCRIPTION}
|
MACOSX_BUNDLE_INFO_STRING ${CMAKE_PROJECT_DESCRIPTION}
|
||||||
MACOSX_BUNDLE_COPYRIGHT "All Content (c) 2023 Shaun Reed, all rights reserved"
|
MACOSX_BUNDLE_COPYRIGHT ${QTK_COPYRIGHT}
|
||||||
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
|
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
|
||||||
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
|
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
|
||||||
)
|
)
|
||||||
|
endif()
|
||||||
@@ -15,10 +15,14 @@
|
|||||||
using namespace Qtk;
|
using namespace Qtk;
|
||||||
|
|
||||||
DebugConsole::DebugConsole(QWidget * owner, const QString & key) :
|
DebugConsole::DebugConsole(QWidget * owner, const QString & key) :
|
||||||
DebugConsole(owner, key, key + "Debugger") {}
|
DebugConsole(owner, key, key + "Debugger")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
DebugConsole::DebugConsole(
|
DebugConsole::DebugConsole(QWidget * owner,
|
||||||
QWidget * owner, const QString & key, const QString & name) {
|
const QString & key,
|
||||||
|
const QString & name)
|
||||||
|
{
|
||||||
ui_ = new Ui::DebugConsole;
|
ui_ = new Ui::DebugConsole;
|
||||||
ui_->setupUi(this);
|
ui_->setupUi(this);
|
||||||
setObjectName(name);
|
setObjectName(name);
|
||||||
|
|||||||
@@ -16,12 +16,15 @@
|
|||||||
|
|
||||||
#include "qtkwidget.h"
|
#include "qtkwidget.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui
|
||||||
|
{
|
||||||
class DebugConsole;
|
class DebugConsole;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Qtk {
|
namespace Qtk
|
||||||
class DebugConsole : public QDockWidget {
|
{
|
||||||
|
class DebugConsole : public QDockWidget
|
||||||
|
{
|
||||||
Q_OBJECT;
|
Q_OBJECT;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -61,7 +64,8 @@ namespace Qtk {
|
|||||||
* @param context The DebugContext to use for the message.
|
* @param context The DebugContext to use for the message.
|
||||||
* Default value is Status.
|
* Default value is Status.
|
||||||
*/
|
*/
|
||||||
inline void sendLog(QString message, DebugContext context = Status) {
|
inline void sendLog(QString message, DebugContext context = Status)
|
||||||
|
{
|
||||||
mConsole->setTextColor(logColor(context));
|
mConsole->setTextColor(logColor(context));
|
||||||
mConsole->append(logPrefix(message, context));
|
mConsole->append(logPrefix(message, context));
|
||||||
}
|
}
|
||||||
@@ -72,7 +76,8 @@ namespace Qtk {
|
|||||||
*
|
*
|
||||||
* @param name Base name for the DebugConsole window.
|
* @param name Base name for the DebugConsole window.
|
||||||
*/
|
*/
|
||||||
inline void setTitle(QString name) {
|
inline void setTitle(const QString & name)
|
||||||
|
{
|
||||||
setWindowTitle(name + " Debug Console");
|
setWindowTitle(name + " Debug Console");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +86,8 @@ namespace Qtk {
|
|||||||
* @param context Log context severity level.
|
* @param context Log context severity level.
|
||||||
* @return QColor corresponding with the message context.
|
* @return QColor corresponding with the message context.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] QColor logColor(const DebugContext & context) const {
|
[[nodiscard]] QColor logColor(const DebugContext & context) const
|
||||||
|
{
|
||||||
switch (context) {
|
switch (context) {
|
||||||
case Status:
|
case Status:
|
||||||
return Qt::GlobalColor::darkGray;
|
return Qt::GlobalColor::darkGray;
|
||||||
@@ -105,8 +111,9 @@ namespace Qtk {
|
|||||||
* @param context The log context severity level.
|
* @param context The log context severity level.
|
||||||
* @return The log message prefixed with the DebugContext level.
|
* @return The log message prefixed with the DebugContext level.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] QString logPrefix(
|
[[nodiscard]] QString logPrefix(QString & message,
|
||||||
QString & message, const DebugContext & context) {
|
const DebugContext & context)
|
||||||
|
{
|
||||||
QString prefix;
|
QString prefix;
|
||||||
switch (context) {
|
switch (context) {
|
||||||
case Status:
|
case Status:
|
||||||
|
|||||||
@@ -11,7 +11,8 @@
|
|||||||
#include "qtkmainwindow.h"
|
#include "qtkmainwindow.h"
|
||||||
#include "qtkscene.h"
|
#include "qtkscene.h"
|
||||||
|
|
||||||
int main(int argc, char * argv[]) {
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
Q_INIT_RESOURCE(resources);
|
Q_INIT_RESOURCE(resources);
|
||||||
|
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
@@ -20,9 +21,12 @@ int main(int argc, char * argv[]) {
|
|||||||
|
|
||||||
// Qtk currently uses the decorator pattern to save / load scenes.
|
// Qtk currently uses the decorator pattern to save / load scenes.
|
||||||
// This is a temporary solution and will be improved in the future.
|
// This is a temporary solution and will be improved in the future.
|
||||||
auto emptyScene = new Qtk::SceneEmpty;
|
// NOTE: We set the scene here and not in QtkMainWindow to detach the scene
|
||||||
window->getQtkWidget()->setScene(new QtkScene(emptyScene));
|
// from the QtkWidget plugin (qtk_plugin_library build target).
|
||||||
|
// Once we can save / load scenes, this call, and QtkScene, can be removed.
|
||||||
|
window->getQtkWidget()->setScene(new QtkScene);
|
||||||
|
|
||||||
window->show();
|
window->show();
|
||||||
|
|
||||||
return QApplication::exec();
|
return QApplication::exec();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,16 +7,14 @@
|
|||||||
##############################################################################*/
|
##############################################################################*/
|
||||||
|
|
||||||
#include "qtkmainwindow.h"
|
#include "qtkmainwindow.h"
|
||||||
#include "qtkscene.h"
|
|
||||||
#include "ui_qtkmainwindow.h"
|
#include "ui_qtkmainwindow.h"
|
||||||
|
|
||||||
MainWindow * MainWindow::mainWindow_ = Q_NULLPTR;
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Constructors / Destructors
|
* Constructors / Destructors
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget * parent) : QMainWindow(parent) {
|
MainWindow::MainWindow(QWidget * parent) : QMainWindow(parent)
|
||||||
|
{
|
||||||
ui_ = new Ui::MainWindow;
|
ui_ = new Ui::MainWindow;
|
||||||
setObjectName("MainWindow");
|
setObjectName("MainWindow");
|
||||||
// For use in design mode using Qt Creator
|
// For use in design mode using Qt Creator
|
||||||
@@ -27,17 +25,23 @@ MainWindow::MainWindow(QWidget * parent) : QMainWindow(parent) {
|
|||||||
// Initialize static container for all active QtkWidgets
|
// Initialize static container for all active QtkWidgets
|
||||||
auto qtkWidgets = findChildren<Qtk::QtkWidget *>();
|
auto qtkWidgets = findChildren<Qtk::QtkWidget *>();
|
||||||
for (auto & qtkWidget : qtkWidgets) {
|
for (auto & qtkWidget : qtkWidgets) {
|
||||||
qtkWidget->setScene(new Qtk::SceneEmpty);
|
// NOTE: Set a temporary scene for the widget to use for initialization.
|
||||||
|
// This should be replaced by loading a scene, or creating a new (unsaved)
|
||||||
|
// scene when Qtk is opened.
|
||||||
|
qtkWidget->setScene(new EmptyScene);
|
||||||
views_.emplace(qtkWidget->getScene()->getSceneName(), qtkWidget);
|
views_.emplace(qtkWidget->getScene()->getSceneName(), qtkWidget);
|
||||||
|
|
||||||
// Add GUI 'view' toolbar option to show debug console.
|
// Add GUI 'view' toolbar option to show debug console.
|
||||||
ui_->menuView->addAction(qtkWidget->getActionToggleConsole());
|
ui_->menuView->addAction(qtkWidget->getActionToggleConsole());
|
||||||
|
|
||||||
// Refresh GUI widgets when scene or objects are updated.
|
// Refresh GUI widgets when scene or objects are updated.
|
||||||
connect(
|
connect(qtkWidget->getScene(),
|
||||||
qtkWidget->getScene(), &Qtk::Scene::sceneUpdated, this,
|
&Qtk::Scene::sceneUpdated,
|
||||||
|
this,
|
||||||
&MainWindow::refreshScene);
|
&MainWindow::refreshScene);
|
||||||
connect(
|
connect(qtkWidget,
|
||||||
qtkWidget, &Qtk::QtkWidget::objectFocusChanged, ui_->qtk__ToolBox,
|
&Qtk::QtkWidget::objectFocusChanged,
|
||||||
|
ui_->qtk__ToolBox,
|
||||||
&Qtk::ToolBox::updateFocus);
|
&Qtk::ToolBox::updateFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +62,8 @@ MainWindow::MainWindow(QWidget * parent) : QMainWindow(parent) {
|
|||||||
setWindowIcon(Qtk::getIcon());
|
setWindowIcon(Qtk::getIcon());
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow() {
|
MainWindow::~MainWindow()
|
||||||
|
{
|
||||||
delete ui_;
|
delete ui_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,28 +71,32 @@ MainWindow::~MainWindow() {
|
|||||||
* Public Methods
|
* Public Methods
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
MainWindow * MainWindow::getMainWindow() {
|
MainWindow * MainWindow::getMainWindow()
|
||||||
if(mainWindow_ == Q_NULLPTR) {
|
{
|
||||||
mainWindow_ = new MainWindow;
|
static auto * window = new MainWindow;
|
||||||
}
|
return window;
|
||||||
return mainWindow_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Qtk::QtkWidget * MainWindow::getQtkWidget(int64_t index) {
|
Qtk::QtkWidget * MainWindow::getQtkWidget(int64_t index)
|
||||||
|
{
|
||||||
if (views_.size() <= index) {
|
if (views_.size() <= index) {
|
||||||
return Q_NULLPTR;
|
return Q_NULLPTR;
|
||||||
}
|
}
|
||||||
return views_.begin(index)->second;
|
auto it = views_.begin();
|
||||||
|
std::advance(it, index);
|
||||||
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
Qtk::QtkWidget * MainWindow::getQtkWidget(const QString & name) {
|
Qtk::QtkWidget * MainWindow::getQtkWidget(const QString & name)
|
||||||
|
{
|
||||||
if (!views_.count(name)) {
|
if (!views_.count(name)) {
|
||||||
return Q_NULLPTR;
|
return Q_NULLPTR;
|
||||||
}
|
}
|
||||||
return views_[name];
|
return views_[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::refreshScene(const QString & sceneName) {
|
void MainWindow::refreshScene(const QString & sceneName)
|
||||||
|
{
|
||||||
// TODO: Select TreeView using sceneName
|
// TODO: Select TreeView using sceneName
|
||||||
ui_->qtk__TreeView->updateView(getQtkWidget()->getScene());
|
ui_->qtk__TreeView->updateView(getQtkWidget()->getScene());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,15 +17,48 @@
|
|||||||
#include "debugconsole.h"
|
#include "debugconsole.h"
|
||||||
#include "qtkwidget.h"
|
#include "qtkwidget.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui
|
||||||
|
{
|
||||||
class MainWindow;
|
class MainWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An empty scene used for initializing all QtkWidgets within the MainWindow.
|
||||||
|
* This serves as a temporary placeholder for QtkScene (for example), which is
|
||||||
|
* defined in the separate qtk_gui target. The reason for this separation is to
|
||||||
|
* support the use of QtkWidgets (the qtk_plugins target) within the Qt Designer
|
||||||
|
* application without implementations provided in the Qtk Desktop Application.
|
||||||
|
*
|
||||||
|
* For the Qtk application, this should be replaced by loading the previous
|
||||||
|
* scene or creating a new _unsaved_ scene when the application is opened.
|
||||||
|
* Currently we have essentially hard-coded QtkScene to use as examples for
|
||||||
|
* testing the application. This means that the only way to create or modify a
|
||||||
|
* scene is to write code. Any modifications made in the application, such as
|
||||||
|
* moving or resizing objects, will not persist and cannot be saved.
|
||||||
|
*
|
||||||
|
* For users of Qtk Designer Plugins, this means that installing
|
||||||
|
* the `qtk_plugins` target to Qt Designer allows use all of the designer's
|
||||||
|
* features to build an interface and position or resize a QtkWidget as needed.
|
||||||
|
* The QtkWidget also appears as widget in the IDE's toolbars and can be added
|
||||||
|
* to any new application easily, once the plugins are installed.
|
||||||
|
*
|
||||||
|
* Once the application is designed, you can define a custom scene and use the
|
||||||
|
* Qtk API or Qt OpenGL funtions directly to render to it.
|
||||||
|
*
|
||||||
|
* Any application using a QtkWidget can set a custom scene in their main
|
||||||
|
* function. See the MainWindow::MainWindow constructor as an example.
|
||||||
|
*/
|
||||||
|
class EmptyScene : public Qtk::Scene
|
||||||
|
{
|
||||||
|
void init() override { setSceneName("Empty Scene"); }
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MainWindow class to provide an example of using a QtkWidget within a Qt
|
* MainWindow class to provide an example of using a QtkWidget within a Qt
|
||||||
* window application.
|
* window application.
|
||||||
*/
|
*/
|
||||||
class MainWindow : public QMainWindow {
|
class MainWindow : public QMainWindow
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -80,7 +113,6 @@ class MainWindow : public QMainWindow {
|
|||||||
MainWindow(const MainWindow &) {};
|
MainWindow(const MainWindow &) {};
|
||||||
|
|
||||||
Ui::MainWindow * ui_ {};
|
Ui::MainWindow * ui_ {};
|
||||||
static MainWindow * mainWindow_;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps a scene name to the QtkWidget viewing it.
|
* Maps a scene name to the QtkWidget viewing it.
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<property name="windowIcon">
|
<property name="windowIcon">
|
||||||
<iconset>
|
<iconset>
|
||||||
<normaloff>../resources/icon.png</normaloff>../resources/icon.png</iconset>
|
<normaloff>../resources/icons/icon.png</normaloff>../resources/icons/icon.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="unifiedTitleAndToolBarOnMac">
|
<property name="unifiedTitleAndToolBarOnMac">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
|||||||
@@ -14,13 +14,15 @@ using namespace Qtk;
|
|||||||
* Constructors, Destructors
|
* Constructors, Destructors
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
QtkScene::QtkScene(Qtk::Scene * scene) : Qtk::SceneInterface(scene) {
|
QtkScene::QtkScene()
|
||||||
|
{
|
||||||
setSceneName("Qtk Scene");
|
setSceneName("Qtk Scene");
|
||||||
getCamera().getTransform().setTranslation(0.0f, 0.0f, 20.0f);
|
getCamera().getTransform().setTranslation(0.0f, 0.0f, 20.0f);
|
||||||
getCamera().getTransform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f);
|
getCamera().getTransform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
QtkScene::~QtkScene() {
|
QtkScene::~QtkScene()
|
||||||
|
{
|
||||||
delete mTestPhong;
|
delete mTestPhong;
|
||||||
delete mTestSpecular;
|
delete mTestSpecular;
|
||||||
delete mTestDiffuse;
|
delete mTestDiffuse;
|
||||||
@@ -31,7 +33,8 @@ QtkScene::~QtkScene() {
|
|||||||
* Public Member Functions
|
* Public Member Functions
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void QtkScene::init() {
|
void QtkScene::init()
|
||||||
|
{
|
||||||
// Add a skybox to the scene using default cube map images and settings.
|
// Add a skybox to the scene using default cube map images and settings.
|
||||||
setSkybox(new Qtk::Skybox("Skybox"));
|
setSkybox(new Qtk::Skybox("Skybox"));
|
||||||
|
|
||||||
@@ -111,13 +114,13 @@ void QtkScene::init() {
|
|||||||
// Simple cube lighting examples.
|
// Simple cube lighting examples.
|
||||||
|
|
||||||
/* Phong lighting example on a basic cube. */
|
/* Phong lighting example on a basic cube. */
|
||||||
mTestPhong = new Qtk::MeshRenderer("phong", Qtk::Cube());
|
mTestPhong = addObject(new Qtk::MeshRenderer("phongCube", Qtk::Cube()));
|
||||||
mTestPhong->getTransform().setTranslation(3.0f, 0.0f, -2.0f);
|
mTestPhong->getTransform().setTranslation(3.0f, 0.0f, -2.0f);
|
||||||
// NOTE: You no longer need to manually bind shader program to set uniforms.
|
// NOTE: You no longer need to manually bind shader program to set uniforms.
|
||||||
// + You can still bind it if you want to for performance reasons.
|
// + You can still bind it if you want to for performance reasons.
|
||||||
// + Qtk will only bind / release if the shader program is not already bound.
|
// + Qtk will only bind / release if the shader program is not already bound.
|
||||||
mTestPhong->setShaders(
|
mTestPhong->setShaders(":/shaders/solid-phong.vert",
|
||||||
":/shaders/solid-phong.vert", ":/shaders/solid-phong.frag");
|
":/shaders/solid-phong.frag");
|
||||||
|
|
||||||
// For example this would technically not be efficient, because each one of
|
// For example this would technically not be efficient, because each one of
|
||||||
// these calls will bind, set, release. We could instead bind, set N uniforms,
|
// these calls will bind, set, release. We could instead bind, set N uniforms,
|
||||||
@@ -143,16 +146,16 @@ void QtkScene::init() {
|
|||||||
/* Example of a cube with no lighting applied */
|
/* Example of a cube with no lighting applied */
|
||||||
mesh = addObject(new Qtk::MeshRenderer("noLight", Cube(QTK_DRAW_ELEMENTS)));
|
mesh = addObject(new Qtk::MeshRenderer("noLight", Cube(QTK_DRAW_ELEMENTS)));
|
||||||
mesh->getTransform().setTranslation(5.0f, 0.0f, -2.0f);
|
mesh->getTransform().setTranslation(5.0f, 0.0f, -2.0f);
|
||||||
mesh->setShaders(
|
mesh->setShaders(":/shaders/solid-perspective.vert",
|
||||||
":/shaders/solid-perspective.vert", ":/shaders/solid-perspective.frag");
|
":/shaders/solid-perspective.frag");
|
||||||
mesh->setUniform("uColor", QVector3D(0.0f, 0.25f, 0.0f));
|
mesh->setUniform("uColor", QVector3D(0.0f, 0.25f, 0.0f));
|
||||||
// No light source needed for this lighting technique
|
// No light source needed for this lighting technique
|
||||||
|
|
||||||
/* Initialize Ambient example cube */
|
/* Initialize Ambient example cube */
|
||||||
mTestAmbient = new Qtk::MeshRenderer("ambient", Cube());
|
mTestAmbient = addObject(new Qtk::MeshRenderer("ambientCube", Cube()));
|
||||||
mTestAmbient->getTransform().setTranslation(7.0f, 0.0f, -2.0f);
|
mTestAmbient->getTransform().setTranslation(7.0f, 0.0f, -2.0f);
|
||||||
mTestAmbient->setShaders(
|
mTestAmbient->setShaders(":/shaders/solid-ambient.vert",
|
||||||
":/shaders/solid-ambient.vert", ":/shaders/solid-ambient.frag");
|
":/shaders/solid-ambient.frag");
|
||||||
// Changing these uniform values will alter lighting effects.
|
// Changing these uniform values will alter lighting effects.
|
||||||
mTestAmbient->setUniform("uColor", QVector3D(0.0f, 0.25f, 0.0f));
|
mTestAmbient->setUniform("uColor", QVector3D(0.0f, 0.25f, 0.0f));
|
||||||
mTestAmbient->setUniform("uLightColor", QVector3D(1.0f, 1.0f, 1.0f));
|
mTestAmbient->setUniform("uLightColor", QVector3D(1.0f, 1.0f, 1.0f));
|
||||||
@@ -161,10 +164,10 @@ void QtkScene::init() {
|
|||||||
// No light source needed for this lighting technique
|
// No light source needed for this lighting technique
|
||||||
|
|
||||||
/* Initialize Diffuse example cube */
|
/* Initialize Diffuse example cube */
|
||||||
mTestDiffuse = new Qtk::MeshRenderer("diffuse", Cube());
|
mTestDiffuse = addObject(new Qtk::MeshRenderer("diffuseCube", Cube()));
|
||||||
mTestDiffuse->getTransform().setTranslation(9.0f, 0.0f, -2.0f);
|
mTestDiffuse->getTransform().setTranslation(9.0f, 0.0f, -2.0f);
|
||||||
mTestDiffuse->setShaders(
|
mTestDiffuse->setShaders(":/shaders/solid-diffuse.vert",
|
||||||
":/shaders/solid-diffuse.vert", ":/shaders/solid-diffuse.frag");
|
":/shaders/solid-diffuse.frag");
|
||||||
mTestDiffuse->setUniform("uColor", QVector3D(0.0f, 0.25f, 0.0f));
|
mTestDiffuse->setUniform("uColor", QVector3D(0.0f, 0.25f, 0.0f));
|
||||||
mTestDiffuse->setUniform("uLightColor", QVector3D(1.0f, 1.0f, 1.0f));
|
mTestDiffuse->setUniform("uLightColor", QVector3D(1.0f, 1.0f, 1.0f));
|
||||||
mTestDiffuse->setUniform("uAmbientStrength", 0.2f);
|
mTestDiffuse->setUniform("uAmbientStrength", 0.2f);
|
||||||
@@ -177,10 +180,10 @@ void QtkScene::init() {
|
|||||||
mesh->getTransform().scale(0.25f);
|
mesh->getTransform().scale(0.25f);
|
||||||
|
|
||||||
/* Initialize Specular example cube */
|
/* Initialize Specular example cube */
|
||||||
mTestSpecular = new Qtk::MeshRenderer("specular", Cube());
|
mTestSpecular = addObject(new Qtk::MeshRenderer("specularCube", Cube()));
|
||||||
mTestSpecular->getTransform().setTranslation(11.0f, 0.0f, -2.0f);
|
mTestSpecular->getTransform().setTranslation(11.0f, 0.0f, -2.0f);
|
||||||
mTestSpecular->setShaders(
|
mTestSpecular->setShaders(":/shaders/solid-specular.vert",
|
||||||
":/shaders/solid-specular.vert", ":/shaders/solid-specular.frag");
|
":/shaders/solid-specular.frag");
|
||||||
mTestSpecular->setUniform("uColor", QVector3D(0.0f, 0.25f, 0.0f));
|
mTestSpecular->setUniform("uColor", QVector3D(0.0f, 0.25f, 0.0f));
|
||||||
mTestSpecular->setUniform("uLightColor", QVector3D(1.0f, 1.0f, 1.0f));
|
mTestSpecular->setUniform("uLightColor", QVector3D(1.0f, 1.0f, 1.0f));
|
||||||
mTestSpecular->setUniform("uAmbientStrength", 0.2f);
|
mTestSpecular->setUniform("uAmbientStrength", 0.2f);
|
||||||
@@ -228,9 +231,10 @@ void QtkScene::init() {
|
|||||||
// Building more complex objects for showing examples of lighting techniques
|
// Building more complex objects for showing examples of lighting techniques
|
||||||
|
|
||||||
/* Test alien Model with phong lighting and specular mapping. */
|
/* Test alien Model with phong lighting and specular mapping. */
|
||||||
model = addObject(new Qtk::Model(
|
model = addObject(new Qtk::Model("alienTest",
|
||||||
"alienTest", ":/models/models/alien-hominid/alien.obj",
|
":/models/models/alien-hominid/alien.obj",
|
||||||
":/shaders/model-specular.vert", ":/shaders/model-specular.frag"));
|
":/shaders/model-phong.vert",
|
||||||
|
":/shaders/model-phong.frag"));
|
||||||
model->getTransform().setTranslation(3.0f, -1.0f, 10.0f);
|
model->getTransform().setTranslation(3.0f, -1.0f, 10.0f);
|
||||||
model->getTransform().scale(0.15f);
|
model->getTransform().scale(0.15f);
|
||||||
model->setUniform("uMaterial.ambient", QVector3D(1.0f, 1.0f, 1.0f));
|
model->setUniform("uMaterial.ambient", QVector3D(1.0f, 1.0f, 1.0f));
|
||||||
@@ -238,7 +242,7 @@ void QtkScene::init() {
|
|||||||
model->setUniform("uMaterial.specular", QVector3D(1.0f, 1.0f, 1.0f));
|
model->setUniform("uMaterial.specular", QVector3D(1.0f, 1.0f, 1.0f));
|
||||||
model->setUniform("uMaterial.ambientStrength", 0.8f);
|
model->setUniform("uMaterial.ambientStrength", 0.8f);
|
||||||
model->setUniform("uMaterial.diffuseStrength", 0.8f);
|
model->setUniform("uMaterial.diffuseStrength", 0.8f);
|
||||||
model->setUniform("uMaterial.specularStrength", 1.0f);
|
model->setUniform("uMaterial.specularStrength", 0.5f);
|
||||||
model->setUniform("uMaterial.shine", 32.0f);
|
model->setUniform("uMaterial.shine", 32.0f);
|
||||||
|
|
||||||
model->setUniform("uLight.ambient", QVector3D(1.0f, 1.0f, 1.0f));
|
model->setUniform("uLight.ambient", QVector3D(1.0f, 1.0f, 1.0f));
|
||||||
@@ -246,17 +250,18 @@ void QtkScene::init() {
|
|||||||
model->setUniform("uLight.specular", QVector3D(1.0f, 1.0f, 1.0f));
|
model->setUniform("uLight.specular", QVector3D(1.0f, 1.0f, 1.0f));
|
||||||
|
|
||||||
// Light source for alienTest object.
|
// Light source for alienTest object.
|
||||||
mesh = addObject(new Qtk::MeshRenderer(
|
mesh = addObject(new Qtk::MeshRenderer("alienTestLight",
|
||||||
"alienTestLight", Triangle(Qtk::QTK_DRAW_ELEMENTS)));
|
Triangle(Qtk::QTK_DRAW_ELEMENTS)));
|
||||||
mesh->getTransform().setTranslation(4.0f, 1.5f, 10.0f);
|
mesh->getTransform().setTranslation(4.0f, 1.5f, 10.0f);
|
||||||
mesh->getTransform().scale(0.25f);
|
mesh->getTransform().scale(0.25f);
|
||||||
// This function changes values we have allocated in a buffer, so init() after
|
// This function changes values we have allocated in a buffer, so init() after
|
||||||
mesh->setColor(GREEN);
|
mesh->setColor(GREEN);
|
||||||
|
|
||||||
/* Test spartan Model with phong lighting, specular and normal mapping. */
|
/* Test spartan Model with phong lighting, specular and normal mapping. */
|
||||||
model = addObject(new Qtk::Model(
|
model = addObject(new Qtk::Model("spartanTest",
|
||||||
"spartanTest", ":/models/models/spartan/spartan.obj",
|
":/models/models/spartan/spartan.obj",
|
||||||
":/shaders/model-normals.vert", ":/shaders/model-normals.frag"));
|
":/shaders/model-phong.vert",
|
||||||
|
":/shaders/model-phong.frag"));
|
||||||
model->getTransform().setTranslation(0.0f, -1.0f, 10.0f);
|
model->getTransform().setTranslation(0.0f, -1.0f, 10.0f);
|
||||||
model->getTransform().scale(2.0f);
|
model->getTransform().scale(2.0f);
|
||||||
model->setUniform("uMaterial.ambient", QVector3D(1.0f, 1.0f, 1.0f));
|
model->setUniform("uMaterial.ambient", QVector3D(1.0f, 1.0f, 1.0f));
|
||||||
@@ -290,8 +295,8 @@ void QtkScene::init() {
|
|||||||
mesh->reallocateNormals(mesh->getNormals());
|
mesh->reallocateNormals(mesh->getNormals());
|
||||||
|
|
||||||
// RGB Normals cube to show normals are correct with QTK_DRAW_ELEMENTS_NORMALS
|
// RGB Normals cube to show normals are correct with QTK_DRAW_ELEMENTS_NORMALS
|
||||||
mesh = addObject(new Qtk::MeshRenderer(
|
mesh = addObject(new Qtk::MeshRenderer("rgbNormalsCubeElementsTest",
|
||||||
"rgbNormalsCubeElementsTest", Cube(QTK_DRAW_ELEMENTS_NORMALS)));
|
Cube(QTK_DRAW_ELEMENTS_NORMALS)));
|
||||||
mesh->getTransform().setTranslation(5.0f, 0.0f, 2.0f);
|
mesh->getTransform().setTranslation(5.0f, 0.0f, 2.0f);
|
||||||
mesh->setShaders(":/shaders/rgb-normals.vert", ":/shaders/rgb-normals.frag");
|
mesh->setShaders(":/shaders/rgb-normals.vert", ":/shaders/rgb-normals.frag");
|
||||||
mesh->reallocateNormals(mesh->getNormals());
|
mesh->reallocateNormals(mesh->getNormals());
|
||||||
@@ -321,8 +326,8 @@ void QtkScene::init() {
|
|||||||
mesh->reallocateTexCoords(mesh->getTexCoords());
|
mesh->reallocateTexCoords(mesh->getTexCoords());
|
||||||
|
|
||||||
// Test drawing a cube with texture coordinates using glDrawElements
|
// Test drawing a cube with texture coordinates using glDrawElements
|
||||||
mesh = addObject(new Qtk::MeshRenderer(
|
mesh = addObject(new Qtk::MeshRenderer("uvCubeElementsTest",
|
||||||
"uvCubeElementsTest", Cube(QTK_DRAW_ELEMENTS_NORMALS)));
|
Cube(QTK_DRAW_ELEMENTS_NORMALS)));
|
||||||
mesh->getTransform().setTranslation(-1.7f, 0.0f, -2.0f);
|
mesh->getTransform().setTranslation(-1.7f, 0.0f, -2.0f);
|
||||||
mesh->setTexture(":/textures/crate.png");
|
mesh->setTexture(":/textures/crate.png");
|
||||||
mesh->setShaders(":/shaders/texture2d.vert", ":/shaders/texture2d.frag");
|
mesh->setShaders(":/shaders/texture2d.vert", ":/shaders/texture2d.frag");
|
||||||
@@ -339,8 +344,8 @@ void QtkScene::init() {
|
|||||||
addObject(new Qtk::MeshRenderer("testCubeMap", Cube(QTK_DRAW_ELEMENTS)));
|
addObject(new Qtk::MeshRenderer("testCubeMap", Cube(QTK_DRAW_ELEMENTS)));
|
||||||
mesh->getTransform().setTranslation(-3.0f, 1.0f, -2.0f);
|
mesh->getTransform().setTranslation(-3.0f, 1.0f, -2.0f);
|
||||||
mesh->getTransform().setRotation(45.0f, 0.0f, 1.0f, 0.0f);
|
mesh->getTransform().setRotation(45.0f, 0.0f, 1.0f, 0.0f);
|
||||||
mesh->setShaders(
|
mesh->setShaders(":/shaders/texture-cubemap.vert",
|
||||||
":/shaders/texture-cubemap.vert", ":/shaders/texture-cubemap.frag");
|
":/shaders/texture-cubemap.frag");
|
||||||
mesh->setCubeMap(":/textures/crate.png");
|
mesh->setCubeMap(":/textures/crate.png");
|
||||||
mesh->setUniform("uTexture", 0);
|
mesh->setUniform("uTexture", 0);
|
||||||
mesh->reallocateTexCoords(mesh->getTexCoords());
|
mesh->reallocateTexCoords(mesh->getTexCoords());
|
||||||
@@ -354,15 +359,15 @@ void QtkScene::init() {
|
|||||||
mesh->reallocateNormals(mesh->getNormals());
|
mesh->reallocateNormals(mesh->getNormals());
|
||||||
|
|
||||||
// RGB Normals triangle to show normals are correct with QTK_DRAW_ARRAYS
|
// RGB Normals triangle to show normals are correct with QTK_DRAW_ARRAYS
|
||||||
mesh = addObject(new Qtk::MeshRenderer(
|
mesh = addObject(new Qtk::MeshRenderer("rgbTriangleArraysTest",
|
||||||
"rgbTriangleArraysTest", Triangle(QTK_DRAW_ARRAYS)));
|
Triangle(QTK_DRAW_ARRAYS)));
|
||||||
mesh->getTransform().setTranslation(7.0f, 0.0f, 2.0f);
|
mesh->getTransform().setTranslation(7.0f, 0.0f, 2.0f);
|
||||||
mesh->setShaders(":/shaders/rgb-normals.vert", ":/shaders/rgb-normals.frag");
|
mesh->setShaders(":/shaders/rgb-normals.vert", ":/shaders/rgb-normals.frag");
|
||||||
mesh->reallocateNormals(mesh->getNormals());
|
mesh->reallocateNormals(mesh->getNormals());
|
||||||
|
|
||||||
// RGB Normals triangle to show normals are correct with QTK_DRAW_ELEMENTS
|
// RGB Normals triangle to show normals are correct with QTK_DRAW_ELEMENTS
|
||||||
mesh = addObject(new Qtk::MeshRenderer(
|
mesh = addObject(new Qtk::MeshRenderer("rgbTriangleElementsTest",
|
||||||
"rgbTriangleElementsTest", Triangle(QTK_DRAW_ELEMENTS_NORMALS)));
|
Triangle(QTK_DRAW_ELEMENTS_NORMALS)));
|
||||||
mesh->getTransform().setTranslation(7.0f, 0.0f, 4.0f);
|
mesh->getTransform().setTranslation(7.0f, 0.0f, 4.0f);
|
||||||
mesh->setShaders(":/shaders/rgb-normals.vert", ":/shaders/rgb-normals.frag");
|
mesh->setShaders(":/shaders/rgb-normals.vert", ":/shaders/rgb-normals.frag");
|
||||||
mesh->reallocateNormals(mesh->getNormals());
|
mesh->reallocateNormals(mesh->getNormals());
|
||||||
@@ -378,8 +383,8 @@ void QtkScene::init() {
|
|||||||
mesh->reallocateTexCoords(mesh->getTexCoords());
|
mesh->reallocateTexCoords(mesh->getTexCoords());
|
||||||
|
|
||||||
// Test drawing triangle with glDrawElements with texture coordinates
|
// Test drawing triangle with glDrawElements with texture coordinates
|
||||||
mesh = addObject(new Qtk::MeshRenderer(
|
mesh = addObject(new Qtk::MeshRenderer("testTriangleElementsUV",
|
||||||
"testTriangleElementsUV", Triangle(QTK_DRAW_ELEMENTS_NORMALS)));
|
Triangle(QTK_DRAW_ELEMENTS_NORMALS)));
|
||||||
mesh->getTransform().setTranslation(-2.5f, 0.0f, -1.0f);
|
mesh->getTransform().setTranslation(-2.5f, 0.0f, -1.0f);
|
||||||
mesh->setShaders(":/shaders/texture2d.vert", ":/shaders/texture2d.frag");
|
mesh->setShaders(":/shaders/texture2d.vert", ":/shaders/texture2d.frag");
|
||||||
mesh->setTexture(":/textures/crate.png");
|
mesh->setTexture(":/textures/crate.png");
|
||||||
@@ -387,20 +392,20 @@ void QtkScene::init() {
|
|||||||
mesh->reallocateTexCoords(mesh->getTexCoords());
|
mesh->reallocateTexCoords(mesh->getTexCoords());
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtkScene::draw() {
|
void QtkScene::draw()
|
||||||
|
{
|
||||||
// WARNING: We must call the base class draw() function first.
|
// WARNING: We must call the base class draw() function first.
|
||||||
// + This will handle rendering core scene components like the Skybox.
|
// + This will handle rendering core scene components like the Skybox.
|
||||||
Scene::draw();
|
Scene::draw();
|
||||||
|
|
||||||
mTestPhong->bindShaders();
|
mTestPhong->bindShaders();
|
||||||
mTestPhong->setUniform(
|
mTestPhong->setUniform("uModelInverseTransposed",
|
||||||
"uModelInverseTransposed",
|
|
||||||
mTestPhong->getTransform().toMatrix().normalMatrix());
|
mTestPhong->getTransform().toMatrix().normalMatrix());
|
||||||
mTestPhong->setUniform(
|
mTestPhong->setUniform(
|
||||||
"uLightPosition",
|
"uLightPosition",
|
||||||
MeshRenderer::getInstance("phongLight")->getTransform().getTranslation());
|
MeshRenderer::getInstance("phongLight")->getTransform().getTranslation());
|
||||||
mTestPhong->setUniform(
|
mTestPhong->setUniform("uCameraPosition",
|
||||||
"uCameraPosition", QtkScene::getCamera().getTransform().getTranslation());
|
QtkScene::getCamera().getTransform().getTranslation());
|
||||||
mTestPhong->releaseShaders();
|
mTestPhong->releaseShaders();
|
||||||
mTestPhong->draw();
|
mTestPhong->draw();
|
||||||
|
|
||||||
@@ -414,8 +419,8 @@ void QtkScene::draw() {
|
|||||||
mTestDiffuse->setUniform(
|
mTestDiffuse->setUniform(
|
||||||
"uModelInverseTransposed",
|
"uModelInverseTransposed",
|
||||||
mTestDiffuse->getTransform().toMatrix().normalMatrix());
|
mTestDiffuse->getTransform().toMatrix().normalMatrix());
|
||||||
mTestDiffuse->setUniform(
|
mTestDiffuse->setUniform("uLightPosition",
|
||||||
"uLightPosition", MeshRenderer::getInstance("diffuseLight")
|
MeshRenderer::getInstance("diffuseLight")
|
||||||
->getTransform()
|
->getTransform()
|
||||||
.getTranslation());
|
.getTranslation());
|
||||||
mTestDiffuse->setUniform(
|
mTestDiffuse->setUniform(
|
||||||
@@ -427,8 +432,8 @@ void QtkScene::draw() {
|
|||||||
mTestSpecular->setUniform(
|
mTestSpecular->setUniform(
|
||||||
"uModelInverseTransposed",
|
"uModelInverseTransposed",
|
||||||
mTestSpecular->getTransform().toMatrix().normalMatrix());
|
mTestSpecular->getTransform().toMatrix().normalMatrix());
|
||||||
mTestSpecular->setUniform(
|
mTestSpecular->setUniform("uLightPosition",
|
||||||
"uLightPosition", MeshRenderer::getInstance("specularLight")
|
MeshRenderer::getInstance("specularLight")
|
||||||
->getTransform()
|
->getTransform()
|
||||||
.getTranslation());
|
.getTranslation());
|
||||||
mTestSpecular->setUniform(
|
mTestSpecular->setUniform(
|
||||||
@@ -437,7 +442,8 @@ void QtkScene::draw() {
|
|||||||
mTestSpecular->draw();
|
mTestSpecular->draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtkScene::update() {
|
void QtkScene::update()
|
||||||
|
{
|
||||||
auto mySpartan = Model::getInstance("My spartan");
|
auto mySpartan = Model::getInstance("My spartan");
|
||||||
mySpartan->getTransform().rotate(0.75f, 0.0f, 1.0f, 0.0f);
|
mySpartan->getTransform().rotate(0.75f, 0.0f, 1.0f, 0.0f);
|
||||||
|
|
||||||
@@ -449,8 +455,8 @@ void QtkScene::update() {
|
|||||||
.getTranslation();
|
.getTranslation();
|
||||||
auto alien = Model::getInstance("alienTest");
|
auto alien = Model::getInstance("alienTest");
|
||||||
alien->setUniform("uLight.position", position);
|
alien->setUniform("uLight.position", position);
|
||||||
alien->setUniform(
|
alien->setUniform("uCameraPosition",
|
||||||
"uCameraPosition", QtkScene::getCamera().getTransform().getTranslation());
|
QtkScene::getCamera().getTransform().getTranslation());
|
||||||
auto posMatrix = alien->getTransform().toMatrix();
|
auto posMatrix = alien->getTransform().toMatrix();
|
||||||
alien->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix());
|
alien->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix());
|
||||||
alien->setUniform("uMVP.model", posMatrix);
|
alien->setUniform("uMVP.model", posMatrix);
|
||||||
@@ -463,8 +469,8 @@ void QtkScene::update() {
|
|||||||
.getTranslation();
|
.getTranslation();
|
||||||
auto spartan = Model::getInstance("spartanTest");
|
auto spartan = Model::getInstance("spartanTest");
|
||||||
spartan->setUniform("uLight.position", position);
|
spartan->setUniform("uLight.position", position);
|
||||||
spartan->setUniform(
|
spartan->setUniform("uCameraPosition",
|
||||||
"uCameraPosition", QtkScene::getCamera().getTransform().getTranslation());
|
QtkScene::getCamera().getTransform().getTranslation());
|
||||||
posMatrix = spartan->getTransform().toMatrix();
|
posMatrix = spartan->getTransform().toMatrix();
|
||||||
spartan->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix());
|
spartan->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix());
|
||||||
spartan->setUniform("uMVP.model", posMatrix);
|
spartan->setUniform("uMVP.model", posMatrix);
|
||||||
@@ -478,8 +484,8 @@ void QtkScene::update() {
|
|||||||
position =
|
position =
|
||||||
MeshRenderer::getInstance("testLight")->getTransform().getTranslation();
|
MeshRenderer::getInstance("testLight")->getTransform().getTranslation();
|
||||||
phong->setUniform("uLight.position", position);
|
phong->setUniform("uLight.position", position);
|
||||||
phong->setUniform(
|
phong->setUniform("uCameraPosition",
|
||||||
"uCameraPosition", QtkScene::getCamera().getTransform().getTranslation());
|
QtkScene::getCamera().getTransform().getTranslation());
|
||||||
posMatrix = phong->getTransform().toMatrix();
|
posMatrix = phong->getTransform().toMatrix();
|
||||||
phong->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix());
|
phong->setUniform("uMVP.normalMatrix", posMatrix.normalMatrix());
|
||||||
phong->setUniform("uMVP.model", posMatrix);
|
phong->setUniform("uMVP.model", posMatrix);
|
||||||
|
|||||||
@@ -29,13 +29,14 @@
|
|||||||
*
|
*
|
||||||
* To create your own Scene from scratch see Qtk::Scene.
|
* To create your own Scene from scratch see Qtk::Scene.
|
||||||
*/
|
*/
|
||||||
class QtkScene : public Qtk::SceneInterface {
|
class QtkScene : public Qtk::Scene
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Contructors / Destructors
|
* Contructors / Destructors
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
QtkScene(Qtk::Scene * scene);
|
QtkScene();
|
||||||
|
|
||||||
~QtkScene();
|
~QtkScene();
|
||||||
|
|
||||||
|
|||||||
@@ -32,11 +32,14 @@ using namespace Qtk;
|
|||||||
QtkWidget::QtkWidget(QWidget * parent) : QtkWidget(parent, "QtkWidget") {}
|
QtkWidget::QtkWidget(QWidget * parent) : QtkWidget(parent, "QtkWidget") {}
|
||||||
|
|
||||||
QtkWidget::QtkWidget(QWidget * parent, const QString & name) :
|
QtkWidget::QtkWidget(QWidget * parent, const QString & name) :
|
||||||
QtkWidget(parent, name, Q_NULLPTR) {}
|
QtkWidget(parent, name, Q_NULLPTR)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
QtkWidget::QtkWidget(QWidget * parent, const QString & name, Scene * scene) :
|
QtkWidget::QtkWidget(QWidget * parent, const QString & name, Scene * scene) :
|
||||||
QOpenGLWidget(parent), mDebugLogger(Q_NULLPTR),
|
QOpenGLWidget(parent), mDebugLogger(Q_NULLPTR),
|
||||||
mConsole(new DebugConsole(this, name)), mScene(Q_NULLPTR) {
|
mConsole(new DebugConsole(this, name)), mScene(Q_NULLPTR)
|
||||||
|
{
|
||||||
setAcceptDrops(true);
|
setAcceptDrops(true);
|
||||||
setScene(scene);
|
setScene(scene);
|
||||||
setObjectName(name);
|
setObjectName(name);
|
||||||
@@ -54,7 +57,8 @@ QtkWidget::QtkWidget(QWidget * parent, const QString & name, Scene * scene) :
|
|||||||
setFocusPolicy(Qt::ClickFocus);
|
setFocusPolicy(Qt::ClickFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
QtkWidget::~QtkWidget() {
|
QtkWidget::~QtkWidget()
|
||||||
|
{
|
||||||
makeCurrent();
|
makeCurrent();
|
||||||
teardownGL();
|
teardownGL();
|
||||||
}
|
}
|
||||||
@@ -63,7 +67,8 @@ QtkWidget::~QtkWidget() {
|
|||||||
* Public Methods
|
* Public Methods
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
QAction * QtkWidget::getActionToggleConsole() {
|
QAction * QtkWidget::getActionToggleConsole()
|
||||||
|
{
|
||||||
auto action = new QAction(mScene->getSceneName() + " debug console");
|
auto action = new QAction(mScene->getSceneName() + " debug console");
|
||||||
action->setCheckable(true);
|
action->setCheckable(true);
|
||||||
action->setChecked(mConsoleActive);
|
action->setChecked(mConsoleActive);
|
||||||
@@ -72,18 +77,24 @@ QAction * QtkWidget::getActionToggleConsole() {
|
|||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtkWidget::initializeGL() {
|
void QtkWidget::initializeGL()
|
||||||
|
{
|
||||||
initializeOpenGLFunctions();
|
initializeOpenGLFunctions();
|
||||||
// Connect the frameSwapped signal to call the update() function
|
// Connect the frameSwapped signal to call the update() function
|
||||||
connect(this, SIGNAL(frameSwapped()), this, SLOT(update()));
|
connect(this, SIGNAL(frameSwapped()), this, SLOT(update()));
|
||||||
|
|
||||||
toggleConsole();
|
// Add the debug console widget to the window and set its hidden state.
|
||||||
|
MainWindow::getMainWindow()->addDockWidget(
|
||||||
|
Qt::DockWidgetArea::BottomDockWidgetArea, mConsole);
|
||||||
|
mConsole->setHidden(!mConsoleActive);
|
||||||
|
|
||||||
// Initialize OpenGL debug context
|
// Initialize OpenGL debug context
|
||||||
mDebugLogger = new QOpenGLDebugLogger(this);
|
mDebugLogger = new QOpenGLDebugLogger(this);
|
||||||
if (mDebugLogger->initialize()) {
|
if (mDebugLogger->initialize()) {
|
||||||
qDebug() << "GL_DEBUG Debug Logger" << mDebugLogger << "\n";
|
qDebug() << "GL_DEBUG Debug Logger" << mDebugLogger << "\n";
|
||||||
connect(
|
connect(mDebugLogger,
|
||||||
mDebugLogger, SIGNAL(messageLogged(QOpenGLDebugMessage)), this,
|
SIGNAL(messageLogged(QOpenGLDebugMessage)),
|
||||||
|
this,
|
||||||
SLOT(messageLogged(QOpenGLDebugMessage)));
|
SLOT(messageLogged(QOpenGLDebugMessage)));
|
||||||
mDebugLogger->startLogging();
|
mDebugLogger->startLogging();
|
||||||
}
|
}
|
||||||
@@ -101,13 +112,15 @@ void QtkWidget::initializeGL() {
|
|||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtkWidget::resizeGL(int width, int height) {
|
void QtkWidget::resizeGL(int width, int height)
|
||||||
|
{
|
||||||
Scene::getProjectionMatrix().setToIdentity();
|
Scene::getProjectionMatrix().setToIdentity();
|
||||||
Scene::getProjectionMatrix().perspective(
|
Scene::getProjectionMatrix().perspective(
|
||||||
45.0f, float(width) / float(height), 0.1f, 1000.0f);
|
45.0f, float(width) / float(height), 0.1f, 1000.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtkWidget::paintGL() {
|
void QtkWidget::paintGL()
|
||||||
|
{
|
||||||
// Clear buffers and draw the scene if it is valid.
|
// Clear buffers and draw the scene if it is valid.
|
||||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||||
if (mScene != Q_NULLPTR) {
|
if (mScene != Q_NULLPTR) {
|
||||||
@@ -115,11 +128,13 @@ void QtkWidget::paintGL() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtkWidget::setScene(Scene * scene) {
|
void QtkWidget::setScene(Scene * scene)
|
||||||
|
{
|
||||||
if (mScene != Q_NULLPTR) {
|
if (mScene != Q_NULLPTR) {
|
||||||
delete mScene;
|
delete mScene;
|
||||||
connect(
|
connect(scene,
|
||||||
scene, &Scene::sceneUpdated, MainWindow::getMainWindow(),
|
&Scene::sceneUpdated,
|
||||||
|
MainWindow::getMainWindow(),
|
||||||
&MainWindow::refreshScene);
|
&MainWindow::refreshScene);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,29 +146,25 @@ void QtkWidget::setScene(Scene * scene) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtkWidget::toggleConsole() {
|
void QtkWidget::toggleConsole()
|
||||||
if(mConsoleActive) {
|
{
|
||||||
mConsole->setHidden(true);
|
mConsole->setHidden(mConsoleActive);
|
||||||
mConsoleActive = false;
|
mConsoleActive = !mConsoleActive;
|
||||||
} else {
|
|
||||||
MainWindow::getMainWindow()->addDockWidget(
|
|
||||||
Qt::DockWidgetArea::BottomDockWidgetArea, mConsole);
|
|
||||||
mConsole->setHidden(false);
|
|
||||||
mConsoleActive = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Protected Methods
|
* Protected Methods
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void QtkWidget::dragEnterEvent(QDragEnterEvent * event) {
|
void QtkWidget::dragEnterEvent(QDragEnterEvent * event)
|
||||||
|
{
|
||||||
if (event->mimeData()->hasFormat("text/plain")) {
|
if (event->mimeData()->hasFormat("text/plain")) {
|
||||||
event->acceptProposedAction();
|
event->acceptProposedAction();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtkWidget::dropEvent(QDropEvent * event) {
|
void QtkWidget::dropEvent(QDropEvent * event)
|
||||||
|
{
|
||||||
mConsole->sendLog(event->mimeData()->text());
|
mConsole->sendLog(event->mimeData()->text());
|
||||||
auto urls = event->mimeData()->urls();
|
auto urls = event->mimeData()->urls();
|
||||||
if (!urls.isEmpty()) {
|
if (!urls.isEmpty()) {
|
||||||
@@ -175,7 +186,8 @@ void QtkWidget::dropEvent(QDropEvent * event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtkWidget::keyPressEvent(QKeyEvent * event) {
|
void QtkWidget::keyPressEvent(QKeyEvent * event)
|
||||||
|
{
|
||||||
if (event->isAutoRepeat()) {
|
if (event->isAutoRepeat()) {
|
||||||
// Do not repeat input while a key is held down
|
// Do not repeat input while a key is held down
|
||||||
event->ignore();
|
event->ignore();
|
||||||
@@ -184,7 +196,8 @@ void QtkWidget::keyPressEvent(QKeyEvent * event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtkWidget::keyReleaseEvent(QKeyEvent * event) {
|
void QtkWidget::keyReleaseEvent(QKeyEvent * event)
|
||||||
|
{
|
||||||
if (event->isAutoRepeat()) {
|
if (event->isAutoRepeat()) {
|
||||||
event->ignore();
|
event->ignore();
|
||||||
} else {
|
} else {
|
||||||
@@ -192,15 +205,18 @@ void QtkWidget::keyReleaseEvent(QKeyEvent * event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtkWidget::mousePressEvent(QMouseEvent * event) {
|
void QtkWidget::mousePressEvent(QMouseEvent * event)
|
||||||
|
{
|
||||||
Input::registerMousePress(event->button());
|
Input::registerMousePress(event->button());
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtkWidget::mouseReleaseEvent(QMouseEvent * event) {
|
void QtkWidget::mouseReleaseEvent(QMouseEvent * event)
|
||||||
|
{
|
||||||
Input::registerMouseRelease(event->button());
|
Input::registerMouseRelease(event->button());
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtkWidget::update() {
|
void QtkWidget::update()
|
||||||
|
{
|
||||||
updateCameraInput();
|
updateCameraInput();
|
||||||
|
|
||||||
if (mScene != Q_NULLPTR) {
|
if (mScene != Q_NULLPTR) {
|
||||||
@@ -210,7 +226,8 @@ void QtkWidget::update() {
|
|||||||
QWidget::update();
|
QWidget::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtkWidget::messageLogged(const QOpenGLDebugMessage & msg) {
|
void QtkWidget::messageLogged(const QOpenGLDebugMessage & msg)
|
||||||
|
{
|
||||||
QString error;
|
QString error;
|
||||||
|
|
||||||
DebugContext context;
|
DebugContext context;
|
||||||
@@ -282,10 +299,12 @@ void QtkWidget::messageLogged(const QOpenGLDebugMessage & msg) {
|
|||||||
* Private Methods
|
* Private Methods
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void QtkWidget::teardownGL() { /* Nothing to teardown yet... */
|
void QtkWidget::teardownGL()
|
||||||
|
{ /* Nothing to teardown yet... */
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtkWidget::updateCameraInput() {
|
void QtkWidget::updateCameraInput()
|
||||||
|
{
|
||||||
Input::update();
|
Input::update();
|
||||||
// Camera Transformation
|
// Camera Transformation
|
||||||
if (Input::buttonPressed(Qt::LeftButton)
|
if (Input::buttonPressed(Qt::LeftButton)
|
||||||
@@ -323,7 +342,8 @@ void QtkWidget::updateCameraInput() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtkWidget::printContextInformation() {
|
void QtkWidget::printContextInformation()
|
||||||
|
{
|
||||||
QString glType;
|
QString glType;
|
||||||
QString glVersion;
|
QString glVersion;
|
||||||
QString glProfile;
|
QString glProfile;
|
||||||
|
|||||||
@@ -20,7 +20,8 @@
|
|||||||
#include <qtk/qtkapi.h>
|
#include <qtk/qtkapi.h>
|
||||||
#include <qtk/scene.h>
|
#include <qtk/scene.h>
|
||||||
|
|
||||||
namespace Qtk {
|
namespace Qtk
|
||||||
|
{
|
||||||
class DebugConsole;
|
class DebugConsole;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -29,7 +30,8 @@ namespace Qtk {
|
|||||||
* This object has a Scene attached which manages the objects to render.
|
* This object has a Scene attached which manages the objects to render.
|
||||||
* Client input is passed through this widget to control the camera view.
|
* Client input is passed through this widget to control the camera view.
|
||||||
*/
|
*/
|
||||||
class QtkWidget : public QOpenGLWidget, protected QOpenGLFunctions {
|
class QtkWidget : public QOpenGLWidget, protected QOpenGLFunctions
|
||||||
|
{
|
||||||
Q_OBJECT;
|
Q_OBJECT;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -103,7 +105,8 @@ namespace Qtk {
|
|||||||
/**
|
/**
|
||||||
* @return Pointer to the QOpenGLDebugLogger attached to this widget.
|
* @return Pointer to the QOpenGLDebugLogger attached to this widget.
|
||||||
*/
|
*/
|
||||||
inline QOpenGLDebugLogger * getOpenGLDebugLogger() {
|
inline QOpenGLDebugLogger * getOpenGLDebugLogger()
|
||||||
|
{
|
||||||
return mDebugLogger;
|
return mDebugLogger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +136,7 @@ namespace Qtk {
|
|||||||
|
|
||||||
// TODO: Use this signal in treeview and toolbox to update object
|
// TODO: Use this signal in treeview and toolbox to update object
|
||||||
// properties
|
// properties
|
||||||
void objectFocusChanged(const QString objectName);
|
void objectFocusChanged(QString objectName);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -207,7 +210,7 @@ namespace Qtk {
|
|||||||
QOpenGLDebugLogger * mDebugLogger;
|
QOpenGLDebugLogger * mDebugLogger;
|
||||||
Qtk::Scene * mScene;
|
Qtk::Scene * mScene;
|
||||||
Qtk::DebugConsole * mConsole;
|
Qtk::DebugConsole * mConsole;
|
||||||
bool mConsoleActive = false;
|
bool mConsoleActive = true;
|
||||||
};
|
};
|
||||||
} // namespace Qtk
|
} // namespace Qtk
|
||||||
|
|
||||||
|
|||||||
@@ -16,12 +16,14 @@
|
|||||||
|
|
||||||
using namespace Qtk;
|
using namespace Qtk;
|
||||||
|
|
||||||
ToolBox::ToolBox(QWidget * parent) : QDockWidget(parent), ui(new Ui::ToolBox) {
|
ToolBox::ToolBox(QWidget * parent) : QDockWidget(parent), ui(new Ui::ToolBox)
|
||||||
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
setMinimumWidth(350);
|
setMinimumWidth(350);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToolBox::updateFocus(const QString & name) {
|
void ToolBox::updateFocus(const QString & name)
|
||||||
|
{
|
||||||
auto object =
|
auto object =
|
||||||
MainWindow::getMainWindow()->getQtkWidget()->getScene()->getObject(name);
|
MainWindow::getMainWindow()->getQtkWidget()->getScene()->getObject(name);
|
||||||
if (object != Q_NULLPTR) {
|
if (object != Q_NULLPTR) {
|
||||||
@@ -31,11 +33,13 @@ void ToolBox::updateFocus(const QString & name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolBox::~ToolBox() {
|
ToolBox::~ToolBox()
|
||||||
|
{
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToolBox::removePages() {
|
void ToolBox::removePages()
|
||||||
|
{
|
||||||
// Remove all existing pages.
|
// Remove all existing pages.
|
||||||
for (size_t i = 0; i < ui->toolBox->count(); i++) {
|
for (size_t i = 0; i < ui->toolBox->count(); i++) {
|
||||||
delete ui->toolBox->widget(i);
|
delete ui->toolBox->widget(i);
|
||||||
@@ -43,7 +47,8 @@ void ToolBox::removePages() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToolBox::createPageProperties(const Object * object) {
|
void ToolBox::createPageProperties(const Object * object)
|
||||||
|
{
|
||||||
auto transform = object->getTransform();
|
auto transform = object->getTransform();
|
||||||
auto type = object->getType();
|
auto type = object->getType();
|
||||||
auto * widget = new QWidget;
|
auto * widget = new QWidget;
|
||||||
@@ -51,11 +56,10 @@ void ToolBox::createPageProperties(const Object * object) {
|
|||||||
ui->toolBox->setCurrentWidget(widget);
|
ui->toolBox->setCurrentWidget(widget);
|
||||||
|
|
||||||
auto * layout = new QFormLayout;
|
auto * layout = new QFormLayout;
|
||||||
layout->addRow(
|
layout->addRow(new QLabel(tr("Name:")),
|
||||||
new QLabel(tr("Name:")), new QLabel(object->getName().c_str()));
|
new QLabel(object->getName().c_str()));
|
||||||
|
|
||||||
layout->addRow(
|
layout->addRow(new QLabel(tr("Type:")),
|
||||||
new QLabel(tr("Type:")),
|
|
||||||
new QLabel(type == Object::Type::QTK_MESH ? "Mesh" : "Model"));
|
new QLabel(type == Object::Type::QTK_MESH ? "Mesh" : "Model"));
|
||||||
|
|
||||||
auto rowLayout = new QHBoxLayout;
|
auto rowLayout = new QHBoxLayout;
|
||||||
@@ -70,16 +74,19 @@ void ToolBox::createPageProperties(const Object * object) {
|
|||||||
rowLayout->addWidget(spinBox);
|
rowLayout->addWidget(spinBox);
|
||||||
|
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
connect(
|
connect(spinBox,
|
||||||
spinBox, &QDoubleSpinBox::valueChanged, object,
|
&QDoubleSpinBox::valueChanged,
|
||||||
|
object,
|
||||||
&Object::setTranslationX);
|
&Object::setTranslationX);
|
||||||
} else if (i == 1) {
|
} else if (i == 1) {
|
||||||
connect(
|
connect(spinBox,
|
||||||
spinBox, &QDoubleSpinBox::valueChanged, object,
|
&QDoubleSpinBox::valueChanged,
|
||||||
|
object,
|
||||||
&Object::setTranslationY);
|
&Object::setTranslationY);
|
||||||
} else if (i == 2) {
|
} else if (i == 2) {
|
||||||
connect(
|
connect(spinBox,
|
||||||
spinBox, &QDoubleSpinBox::valueChanged, object,
|
&QDoubleSpinBox::valueChanged,
|
||||||
|
object,
|
||||||
&Object::setTranslationZ);
|
&Object::setTranslationZ);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -110,7 +117,8 @@ void ToolBox::createPageProperties(const Object * object) {
|
|||||||
widget->setLayout(layout);
|
widget->setLayout(layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToolBox::createPageShader(const Object * object) {
|
void ToolBox::createPageShader(const Object * object)
|
||||||
|
{
|
||||||
// Shaders page.
|
// Shaders page.
|
||||||
auto widget = new QWidget;
|
auto widget = new QWidget;
|
||||||
ui->toolBox->addItem(widget, "Shaders");
|
ui->toolBox->addItem(widget, "Shaders");
|
||||||
|
|||||||
@@ -18,12 +18,15 @@
|
|||||||
|
|
||||||
#include "qtk/scene.h"
|
#include "qtk/scene.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui
|
||||||
|
{
|
||||||
class ToolBox;
|
class ToolBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Qtk {
|
namespace Qtk
|
||||||
class ToolBox : public QDockWidget {
|
{
|
||||||
|
class ToolBox : public QDockWidget
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -16,14 +16,17 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
Qtk::TreeView::TreeView(QWidget * parent) :
|
Qtk::TreeView::TreeView(QWidget * parent) :
|
||||||
QDockWidget(parent), ui(new Ui::TreeView) {
|
QDockWidget(parent), ui(new Ui::TreeView)
|
||||||
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
connect(
|
connect(ui->treeWidget,
|
||||||
ui->treeWidget, &QTreeWidget::itemDoubleClicked, this,
|
&QTreeWidget::itemDoubleClicked,
|
||||||
|
this,
|
||||||
&TreeView::itemFocus);
|
&TreeView::itemFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
Qtk::TreeView::~TreeView() {
|
Qtk::TreeView::~TreeView()
|
||||||
|
{
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,41 +34,40 @@ Qtk::TreeView::~TreeView() {
|
|||||||
* Public Methods
|
* Public Methods
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void Qtk::TreeView::updateView(const Qtk::Scene * scene) {
|
void Qtk::TreeView::updateView(const Qtk::Scene * scene)
|
||||||
|
{
|
||||||
ui->treeWidget->clear();
|
ui->treeWidget->clear();
|
||||||
ui->treeWidget->setColumnCount(1);
|
ui->treeWidget->setColumnCount(1);
|
||||||
mSceneName = scene->getSceneName();
|
mSceneName = scene->getSceneName();
|
||||||
auto objects = scene->getObjects();
|
auto objects = scene->getObjects();
|
||||||
for (const auto & object : objects) {
|
for (const auto & object : objects) {
|
||||||
auto item =
|
QStringList list(QStringList(QString(object->getName().c_str())));
|
||||||
new QTreeWidgetItem(QStringList(QString(object->getName().c_str())));
|
ui->treeWidget->insertTopLevelItem(0, new QTreeWidgetItem(list));
|
||||||
ui->treeWidget->insertTopLevelItem(0, item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Qtk::TreeView::itemFocus(QTreeWidgetItem * item, int column) {
|
void Qtk::TreeView::itemFocus(QTreeWidgetItem * item, int column)
|
||||||
QString name = item->text(column);
|
{
|
||||||
|
const QString & name = item->text(column);
|
||||||
auto scene = MainWindow::getMainWindow()->getQtkWidget()->getScene();
|
auto scene = MainWindow::getMainWindow()->getQtkWidget()->getScene();
|
||||||
auto & transform = scene->getCamera().getTransform();
|
|
||||||
auto object = scene->getObject(name);
|
auto object = scene->getObject(name);
|
||||||
Transform3D * objectTransform;
|
|
||||||
// If the object is a mesh or model, focus the camera on it.
|
// If the object is a mesh or model, focus the camera on it.
|
||||||
if (object == Q_NULLPTR) {
|
if (object == Q_NULLPTR) {
|
||||||
qDebug() << "Attempt to get non-existing object with name '" << name
|
qDebug() << "Attempt to get non-existing object with name '" << name
|
||||||
<< "'\n";
|
<< "'\n";
|
||||||
} else if(object->getType() == Object::QTK_MESH) {
|
return;
|
||||||
objectTransform = &dynamic_cast<MeshRenderer *>(object)->getTransform();
|
|
||||||
} else if(object->getType() == Object::QTK_MODEL) {
|
|
||||||
objectTransform = &dynamic_cast<Model *>(object)->getTransform();
|
|
||||||
}
|
}
|
||||||
auto focusScale = objectTransform->getScale();
|
const Transform3D & objectTransform = object->getTransform();
|
||||||
|
|
||||||
|
auto & camera_transform = Qtk::Scene::getCamera().getTransform();
|
||||||
|
auto focusScale = objectTransform.getScale();
|
||||||
float width = focusScale.x() / 2.0f;
|
float width = focusScale.x() / 2.0f;
|
||||||
float height = focusScale.y() / 2.0f;
|
float height = focusScale.y() / 2.0f;
|
||||||
QVector3D pos = objectTransform->getTranslation();
|
QVector3D pos = objectTransform.getTranslation();
|
||||||
// pos.setX(pos.x() + width);
|
// pos.setX(pos.x() + width);
|
||||||
pos.setY(pos.y() + height);
|
pos.setY(pos.y() + height);
|
||||||
transform.setTranslation(pos);
|
camera_transform.setTranslation(pos);
|
||||||
transform.translate(0.0f, 0.0f, 3.0f);
|
camera_transform.translate(0.0f, 0.0f, 3.0f);
|
||||||
|
|
||||||
// Emit signal from qtk widget for new object focus. Triggers GUI updates.
|
// Emit signal from qtk widget for new object focus. Triggers GUI updates.
|
||||||
emit MainWindow::getMainWindow() -> getQtkWidget()->objectFocusChanged(name);
|
emit MainWindow::getMainWindow() -> getQtkWidget()->objectFocusChanged(name);
|
||||||
|
|||||||
@@ -17,12 +17,15 @@
|
|||||||
#include <qtk/scene.h>
|
#include <qtk/scene.h>
|
||||||
#include <QTreeWidgetItem>
|
#include <QTreeWidgetItem>
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui
|
||||||
|
{
|
||||||
class TreeView;
|
class TreeView;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Qtk {
|
namespace Qtk
|
||||||
class TreeView : public QDockWidget {
|
{
|
||||||
|
class TreeView : public QDockWidget
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -19,12 +19,15 @@
|
|||||||
* Constructors, Destructors
|
* Constructors, Destructors
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
WidgetPlugin::WidgetPlugin(
|
WidgetPlugin::WidgetPlugin(QString group,
|
||||||
QString group, QString class_name, QString include,
|
QString class_name,
|
||||||
|
QString include,
|
||||||
WidgetPlugin::Factory factory) :
|
WidgetPlugin::Factory factory) :
|
||||||
m_group(std::move(group)),
|
m_group(std::move(group)), m_className(std::move(class_name)),
|
||||||
m_className(std::move(class_name)), m_includeFile(std::move(include)),
|
m_includeFile(std::move(include)), m_factory(std::move(factory)),
|
||||||
m_factory(std::move(factory)), m_objectName(class_name) {}
|
m_objectName(m_className)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
WidgetPlugin::WidgetPlugin(QObject * parent) : QObject(parent) {}
|
WidgetPlugin::WidgetPlugin(QObject * parent) : QObject(parent) {}
|
||||||
|
|
||||||
@@ -32,50 +35,61 @@ WidgetPlugin::WidgetPlugin(QObject * parent) : QObject(parent) {}
|
|||||||
* Public Methods
|
* Public Methods
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
QString WidgetPlugin::group() const {
|
QString WidgetPlugin::group() const
|
||||||
|
{
|
||||||
return m_group;
|
return m_group;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString WidgetPlugin::name() const {
|
QString WidgetPlugin::name() const
|
||||||
|
{
|
||||||
return m_className;
|
return m_className;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString WidgetPlugin::includeFile() const {
|
QString WidgetPlugin::includeFile() const
|
||||||
|
{
|
||||||
return m_includeFile;
|
return m_includeFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget * WidgetPlugin::createWidget(QWidget * parent) {
|
QWidget * WidgetPlugin::createWidget(QWidget * parent)
|
||||||
|
{
|
||||||
return m_factory(parent);
|
return m_factory(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString WidgetPlugin::toolTip() const {
|
QString WidgetPlugin::toolTip() const
|
||||||
|
{
|
||||||
return QStringLiteral("A custom widget tool tip.");
|
return QStringLiteral("A custom widget tool tip.");
|
||||||
}
|
}
|
||||||
|
|
||||||
QString WidgetPlugin::whatsThis() const {
|
QString WidgetPlugin::whatsThis() const
|
||||||
|
{
|
||||||
return QStringLiteral("Custom widget what's this?");
|
return QStringLiteral("Custom widget what's this?");
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon WidgetPlugin::icon() const {
|
QIcon WidgetPlugin::icon() const
|
||||||
|
{
|
||||||
return Qtk::getIcon();
|
return Qtk::getIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WidgetPlugin::isContainer() const {
|
bool WidgetPlugin::isContainer() const
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WidgetPlugin::isInitialized() const {
|
bool WidgetPlugin::isInitialized() const
|
||||||
|
{
|
||||||
return m_initialized;
|
return m_initialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidgetPlugin::initialize(QDesignerFormEditorInterface *) {
|
void WidgetPlugin::initialize(QDesignerFormEditorInterface *)
|
||||||
|
{
|
||||||
if (m_initialized) {
|
if (m_initialized) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_initialized = true;
|
m_initialized = true;
|
||||||
}
|
}
|
||||||
QString WidgetPlugin::domXml() const {
|
QString WidgetPlugin::domXml() const
|
||||||
|
{
|
||||||
return
|
return
|
||||||
"<ui language=\"c++\">\n"
|
"<ui language=\"c++\">\n"
|
||||||
" <widget class=\"" + m_className + "\" name=\"" + m_objectName + "\">\n"
|
" <widget class=\"" + m_className + "\" name=\"" + m_objectName + "\">\n"
|
||||||
|
|||||||
@@ -15,7 +15,8 @@
|
|||||||
|
|
||||||
class QDESIGNER_WIDGET_EXPORT WidgetPlugin :
|
class QDESIGNER_WIDGET_EXPORT WidgetPlugin :
|
||||||
public QObject,
|
public QObject,
|
||||||
public QDesignerCustomWidgetInterface {
|
public QDesignerCustomWidgetInterface
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(QDesignerCustomWidgetInterface)
|
Q_INTERFACES(QDesignerCustomWidgetInterface)
|
||||||
|
|
||||||
@@ -26,8 +27,10 @@ class QDESIGNER_WIDGET_EXPORT WidgetPlugin :
|
|||||||
* Contructors / Destructors
|
* Contructors / Destructors
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
WidgetPlugin(
|
WidgetPlugin(QString group,
|
||||||
QString group, QString class_name, QString include, Factory factory);
|
QString class_name,
|
||||||
|
QString include,
|
||||||
|
Factory factory);
|
||||||
|
|
||||||
explicit WidgetPlugin(QObject * parent = nullptr);
|
explicit WidgetPlugin(QObject * parent = nullptr);
|
||||||
|
|
||||||
|
|||||||
@@ -19,16 +19,23 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
WidgetPluginCollection::WidgetPluginCollection(QObject * parent) :
|
WidgetPluginCollection::WidgetPluginCollection(QObject * parent) :
|
||||||
QObject(parent), m_collectionName("Qtk Widget Collection") {
|
QObject(parent), m_collectionName("Qtk Widget Collection")
|
||||||
|
{
|
||||||
m_collection = {
|
m_collection = {
|
||||||
new WidgetPlugin(
|
new WidgetPlugin(
|
||||||
m_collectionName, "Qtk::QtkWidget", "qtkwidget.h",
|
m_collectionName,
|
||||||
|
"Qtk::QtkWidget",
|
||||||
|
"qtkwidget.h",
|
||||||
[](QWidget * parent) { return new Qtk::QtkWidget(parent); }),
|
[](QWidget * parent) { return new Qtk::QtkWidget(parent); }),
|
||||||
new WidgetPlugin(
|
new WidgetPlugin(
|
||||||
m_collectionName, "Qtk::TreeView", "treeview.h",
|
m_collectionName,
|
||||||
|
"Qtk::TreeView",
|
||||||
|
"treeview.h",
|
||||||
[](QWidget * parent) { return new Qtk::TreeView(parent); }),
|
[](QWidget * parent) { return new Qtk::TreeView(parent); }),
|
||||||
new WidgetPlugin(
|
new WidgetPlugin(
|
||||||
m_collectionName, "Qtk::ToolBox", "toolbox.h",
|
m_collectionName,
|
||||||
|
"Qtk::ToolBox",
|
||||||
|
"toolbox.h",
|
||||||
[](QWidget * parent) { return new Qtk::ToolBox(parent); }),
|
[](QWidget * parent) { return new Qtk::ToolBox(parent); }),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -38,6 +45,7 @@ WidgetPluginCollection::WidgetPluginCollection(QObject * parent) :
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
QList<QDesignerCustomWidgetInterface *> WidgetPluginCollection::customWidgets()
|
QList<QDesignerCustomWidgetInterface *> WidgetPluginCollection::customWidgets()
|
||||||
const {
|
const
|
||||||
|
{
|
||||||
return m_collection;
|
return m_collection;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,8 @@
|
|||||||
|
|
||||||
class WidgetPluginCollection :
|
class WidgetPluginCollection :
|
||||||
public QObject,
|
public QObject,
|
||||||
public QDesignerCustomWidgetCollectionInterface {
|
public QDesignerCustomWidgetCollectionInterface
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
// Since we're exporting a collection, this is the only plugin metadata
|
// Since we're exporting a collection, this is the only plugin metadata
|
||||||
// needed. We don't need this for-each widget in the collection.
|
// needed. We don't need this for-each widget in the collection.
|
||||||
@@ -36,7 +37,8 @@ class WidgetPluginCollection :
|
|||||||
/**
|
/**
|
||||||
* @return QList of all custom widgets pointers.
|
* @return QList of all custom widgets pointers.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] QList<QDesignerCustomWidgetInterface *> customWidgets() const;
|
[[nodiscard]] QList<QDesignerCustomWidgetInterface *> customWidgets()
|
||||||
|
const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ const QVector3D Camera3D::LocalRight(1.0f, 0.0f, 0.0f);
|
|||||||
* Public Methods
|
* Public Methods
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
const QMatrix4x4 & Camera3D::toMatrix() {
|
const QMatrix4x4 & Camera3D::toMatrix()
|
||||||
|
{
|
||||||
mWorld.setToIdentity();
|
mWorld.setToIdentity();
|
||||||
// Qt6 renamed QMatrix4x4::conjugate() to conjugated()
|
// Qt6 renamed QMatrix4x4::conjugate() to conjugated()
|
||||||
mWorld.rotate(mTransform.getRotation().conjugated());
|
mWorld.rotate(mTransform.getRotation().conjugated());
|
||||||
@@ -34,17 +35,20 @@ const QMatrix4x4 & Camera3D::toMatrix() {
|
|||||||
* Qt Streams
|
* Qt Streams
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
QDataStream & operator<<(QDataStream & out, Camera3D & transform) {
|
QDataStream & operator<<(QDataStream & out, Camera3D & transform)
|
||||||
|
{
|
||||||
out << transform.getTransform();
|
out << transform.getTransform();
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDataStream & operator>>(QDataStream & in, Camera3D & transform) {
|
QDataStream & operator>>(QDataStream & in, Camera3D & transform)
|
||||||
|
{
|
||||||
in >> transform.getTransform();
|
in >> transform.getTransform();
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDebug operator<<(QDebug dbg, const Camera3D & transform) {
|
QDebug operator<<(QDebug dbg, const Camera3D & transform)
|
||||||
|
{
|
||||||
dbg << "Camera3D\n{\n";
|
dbg << "Camera3D\n{\n";
|
||||||
dbg << "Position: <" << transform.getTranslation().x() << ", "
|
dbg << "Position: <" << transform.getTranslation().x() << ", "
|
||||||
<< transform.getTranslation().y() << ", "
|
<< transform.getTranslation().y() << ", "
|
||||||
|
|||||||
@@ -14,8 +14,10 @@
|
|||||||
#include "qtkapi.h"
|
#include "qtkapi.h"
|
||||||
#include "transform3D.h"
|
#include "transform3D.h"
|
||||||
|
|
||||||
namespace Qtk {
|
namespace Qtk
|
||||||
class QTKAPI Camera3D {
|
{
|
||||||
|
class QTKAPI Camera3D
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Static Public Constants
|
* Static Public Constants
|
||||||
@@ -37,35 +39,40 @@ namespace Qtk {
|
|||||||
/**
|
/**
|
||||||
* @return Current translation of the camera as a QVector3D.
|
* @return Current translation of the camera as a QVector3D.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] inline const QVector3D & getTranslation() const {
|
[[nodiscard]] inline const QVector3D & getTranslation() const
|
||||||
|
{
|
||||||
return mTransform.getTranslation();
|
return mTransform.getTranslation();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Current rotation of this camera as a QQuaternion.
|
* @return Current rotation of this camera as a QQuaternion.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] inline const QQuaternion & getRotation() const {
|
[[nodiscard]] inline const QQuaternion & getRotation() const
|
||||||
|
{
|
||||||
return mTransform.getRotation();
|
return mTransform.getRotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return QVector3D for the forward vector of the camera.
|
* @return QVector3D for the forward vector of the camera.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] inline QVector3D getForward() const {
|
[[nodiscard]] inline QVector3D getForward() const
|
||||||
|
{
|
||||||
return mTransform.getRotation().rotatedVector(LocalForward);
|
return mTransform.getRotation().rotatedVector(LocalForward);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return QVector3D for the right vector of the camera.
|
* @return QVector3D for the right vector of the camera.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] inline QVector3D getRight() const {
|
[[nodiscard]] inline QVector3D getRight() const
|
||||||
|
{
|
||||||
return mTransform.getRotation().rotatedVector(LocalRight);
|
return mTransform.getRotation().rotatedVector(LocalRight);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return QVector3D for the up vector of the camera.
|
* @return QVector3D for the up vector of the camera.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] inline QVector3D getUp() const {
|
[[nodiscard]] inline QVector3D getUp() const
|
||||||
|
{
|
||||||
return mTransform.getRotation().rotatedVector(LocalUp);
|
return mTransform.getRotation().rotatedVector(LocalUp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,10 +33,13 @@ template <typename T> struct InputInstance : std::pair<T, Input::InputState> {
|
|||||||
inline InputInstance(T value) : base_class(value, Input::InputInvalid) {}
|
inline InputInstance(T value) : base_class(value, Input::InputInvalid) {}
|
||||||
|
|
||||||
inline InputInstance(T value, Input::InputState state) :
|
inline InputInstance(T value, Input::InputState state) :
|
||||||
base_class(value, state) {}
|
base_class(value, state)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
// Allows use of std::find to search for a key's InputInstance
|
// Allows use of std::find to search for a key's InputInstance
|
||||||
inline bool operator==(const InputInstance & rhs) const {
|
inline bool operator==(const InputInstance & rhs) const
|
||||||
|
{
|
||||||
return this->first == rhs.first;
|
return this->first == rhs.first;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -67,7 +70,8 @@ static QPoint sg_mouseDelta;
|
|||||||
* @param value The key to search for.
|
* @param value The key to search for.
|
||||||
* @return Iterator to the found element or the end iterator if not found.
|
* @return Iterator to the found element or the end iterator if not found.
|
||||||
*/
|
*/
|
||||||
static inline KeyContainer::iterator FindKey(Qt::Key value) {
|
static inline KeyContainer::iterator FindKey(Qt::Key value)
|
||||||
|
{
|
||||||
return std::find(sg_keyInstances.begin(), sg_keyInstances.end(), value);
|
return std::find(sg_keyInstances.begin(), sg_keyInstances.end(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +81,8 @@ static inline KeyContainer::iterator FindKey(Qt::Key value) {
|
|||||||
* @param value The mouse button to search for.
|
* @param value The mouse button to search for.
|
||||||
* @return Iterator to the found element or the end iterator if not found.
|
* @return Iterator to the found element or the end iterator if not found.
|
||||||
*/
|
*/
|
||||||
static inline ButtonContainer::iterator FindButton(Qt::MouseButton value) {
|
static inline ButtonContainer::iterator FindButton(Qt::MouseButton value)
|
||||||
|
{
|
||||||
return std::find(sg_buttonInstances.begin(), sg_buttonInstances.end(), value);
|
return std::find(sg_buttonInstances.begin(), sg_buttonInstances.end(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,7 +94,8 @@ static inline ButtonContainer::iterator FindButton(Qt::MouseButton value) {
|
|||||||
* @return True if the InputInstance is in the released state.
|
* @return True if the InputInstance is in the released state.
|
||||||
*/
|
*/
|
||||||
template <typename TPair>
|
template <typename TPair>
|
||||||
static inline bool CheckReleased(const TPair & instance) {
|
static inline bool CheckReleased(const TPair & instance)
|
||||||
|
{
|
||||||
return instance.second == Input::InputReleased;
|
return instance.second == Input::InputReleased;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +105,8 @@ static inline bool CheckReleased(const TPair & instance) {
|
|||||||
* @tparam TPair KeyInstance or ButtonInstance.
|
* @tparam TPair KeyInstance or ButtonInstance.
|
||||||
* @param instance The InputInstance to update.
|
* @param instance The InputInstance to update.
|
||||||
*/
|
*/
|
||||||
template <typename TPair> static inline void UpdateStates(TPair & instance) {
|
template <typename TPair> static inline void UpdateStates(TPair & instance)
|
||||||
|
{
|
||||||
switch (instance.second) {
|
switch (instance.second) {
|
||||||
case Input::InputRegistered:
|
case Input::InputRegistered:
|
||||||
instance.second = Input::InputTriggered;
|
instance.second = Input::InputTriggered;
|
||||||
@@ -121,7 +128,8 @@ template <typename TPair> static inline void UpdateStates(TPair & instance) {
|
|||||||
* @tparam Container The type of container, KeyContainer or ButtonContainer.
|
* @tparam Container The type of container, KeyContainer or ButtonContainer.
|
||||||
* @param container The InputInstance container to update.
|
* @param container The InputInstance container to update.
|
||||||
*/
|
*/
|
||||||
template <typename Container> static inline void Update(Container & container) {
|
template <typename Container> static inline void Update(Container & container)
|
||||||
|
{
|
||||||
typedef typename Container::iterator Iter;
|
typedef typename Container::iterator Iter;
|
||||||
typedef typename Container::value_type TPair;
|
typedef typename Container::value_type TPair;
|
||||||
|
|
||||||
@@ -138,7 +146,8 @@ template <typename Container> static inline void Update(Container & container) {
|
|||||||
* Static Public Methods
|
* Static Public Methods
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void Input::update() {
|
void Input::update()
|
||||||
|
{
|
||||||
// Update Mouse Delta
|
// Update Mouse Delta
|
||||||
sg_mousePrevPosition = sg_mouseCurrPosition;
|
sg_mousePrevPosition = sg_mouseCurrPosition;
|
||||||
sg_mouseCurrPosition = QCursor::pos();
|
sg_mouseCurrPosition = QCursor::pos();
|
||||||
@@ -149,53 +158,62 @@ void Input::update() {
|
|||||||
Update(sg_keyInstances);
|
Update(sg_keyInstances);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Input::registerKeyPress(int k) {
|
void Input::registerKeyPress(int k)
|
||||||
|
{
|
||||||
auto it = FindKey((Qt::Key)k);
|
auto it = FindKey((Qt::Key)k);
|
||||||
if (it == sg_keyInstances.end()) {
|
if (it == sg_keyInstances.end()) {
|
||||||
sg_keyInstances.push_back(KeyInstance((Qt::Key)k, InputRegistered));
|
sg_keyInstances.emplace_back((Qt::Key)k, InputRegistered);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Input::registerKeyRelease(int k) {
|
void Input::registerKeyRelease(int k)
|
||||||
|
{
|
||||||
auto it = FindKey((Qt::Key)k);
|
auto it = FindKey((Qt::Key)k);
|
||||||
if (it != sg_keyInstances.end()) {
|
if (it != sg_keyInstances.end()) {
|
||||||
it->second = InputUnregistered;
|
it->second = InputUnregistered;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Input::registerMousePress(Qt::MouseButton btn) {
|
void Input::registerMousePress(Qt::MouseButton button)
|
||||||
auto it = FindButton(btn);
|
{
|
||||||
|
auto it = FindButton(button);
|
||||||
if (it == sg_buttonInstances.end()) {
|
if (it == sg_buttonInstances.end()) {
|
||||||
sg_buttonInstances.push_back(ButtonInstance(btn, InputRegistered));
|
sg_buttonInstances.emplace_back(button, InputRegistered);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Input::registerMouseRelease(Qt::MouseButton btn) {
|
void Input::registerMouseRelease(Qt::MouseButton button)
|
||||||
auto it = FindButton(btn);
|
{
|
||||||
|
auto it = FindButton(button);
|
||||||
if (it != sg_buttonInstances.end()) {
|
if (it != sg_buttonInstances.end()) {
|
||||||
it->second = InputUnregistered;
|
it->second = InputUnregistered;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Input::reset() {
|
void Input::reset()
|
||||||
|
{
|
||||||
sg_keyInstances.clear();
|
sg_keyInstances.clear();
|
||||||
sg_buttonInstances.clear();
|
sg_buttonInstances.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
Input::InputState Input::keyState(Qt::Key k) {
|
Input::InputState Input::keyState(Qt::Key k)
|
||||||
|
{
|
||||||
auto it = FindKey(k);
|
auto it = FindKey(k);
|
||||||
return (it != sg_keyInstances.end()) ? it->second : InputInvalid;
|
return (it != sg_keyInstances.end()) ? it->second : InputInvalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
Input::InputState Input::buttonState(Qt::MouseButton k) {
|
Input::InputState Input::buttonState(Qt::MouseButton button)
|
||||||
auto it = FindButton(k);
|
{
|
||||||
|
auto it = FindButton(button);
|
||||||
return (it != sg_buttonInstances.end()) ? it->second : InputInvalid;
|
return (it != sg_buttonInstances.end()) ? it->second : InputInvalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPoint Input::mousePosition() {
|
QPoint Input::mousePosition()
|
||||||
|
{
|
||||||
return QCursor::pos();
|
return QCursor::pos();
|
||||||
}
|
}
|
||||||
|
|
||||||
QPoint Input::mouseDelta() {
|
QPoint Input::mouseDelta()
|
||||||
|
{
|
||||||
return sg_mouseDelta;
|
return sg_mouseDelta;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,10 @@
|
|||||||
|
|
||||||
#include "qtkapi.h"
|
#include "qtkapi.h"
|
||||||
|
|
||||||
namespace Qtk {
|
namespace Qtk
|
||||||
class QTKAPI Input {
|
{
|
||||||
|
class QTKAPI Input
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Typedefs
|
* Typedefs
|
||||||
@@ -84,7 +86,8 @@ namespace Qtk {
|
|||||||
* @param key Key to check state.
|
* @param key Key to check state.
|
||||||
* @return True if the key is in InputTriggered state.
|
* @return True if the key is in InputTriggered state.
|
||||||
*/
|
*/
|
||||||
inline static bool keyTriggered(Qt::Key key) {
|
inline static bool keyTriggered(Qt::Key key)
|
||||||
|
{
|
||||||
return keyState(key) == InputTriggered;
|
return keyState(key) == InputTriggered;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +95,8 @@ namespace Qtk {
|
|||||||
* @param key Key to check state.
|
* @param key Key to check state.
|
||||||
* @return True if the key is in InputPressed state.
|
* @return True if the key is in InputPressed state.
|
||||||
*/
|
*/
|
||||||
inline static bool keyPressed(Qt::Key key) {
|
inline static bool keyPressed(Qt::Key key)
|
||||||
|
{
|
||||||
return keyState(key) == InputPressed;
|
return keyState(key) == InputPressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +104,8 @@ namespace Qtk {
|
|||||||
* @param key Key to check state.
|
* @param key Key to check state.
|
||||||
* @return True if the key is in InputReleased state.
|
* @return True if the key is in InputReleased state.
|
||||||
*/
|
*/
|
||||||
inline static bool keyReleased(Qt::Key key) {
|
inline static bool keyReleased(Qt::Key key)
|
||||||
|
{
|
||||||
return keyState(key) == InputReleased;
|
return keyState(key) == InputReleased;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +113,8 @@ namespace Qtk {
|
|||||||
* @param button Mouse button to check state.
|
* @param button Mouse button to check state.
|
||||||
* @return True if the key is in InputTriggered state.
|
* @return True if the key is in InputTriggered state.
|
||||||
*/
|
*/
|
||||||
inline static bool buttonTriggered(Qt::MouseButton button) {
|
inline static bool buttonTriggered(Qt::MouseButton button)
|
||||||
|
{
|
||||||
return buttonState(button) == InputTriggered;
|
return buttonState(button) == InputTriggered;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +122,8 @@ namespace Qtk {
|
|||||||
* @param button Mouse button to check state.
|
* @param button Mouse button to check state.
|
||||||
* @return True if the key is in InputPressed state.
|
* @return True if the key is in InputPressed state.
|
||||||
*/
|
*/
|
||||||
inline static bool buttonPressed(Qt::MouseButton button) {
|
inline static bool buttonPressed(Qt::MouseButton button)
|
||||||
|
{
|
||||||
return buttonState(button) == InputPressed;
|
return buttonState(button) == InputPressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,7 +131,8 @@ namespace Qtk {
|
|||||||
* @param button Mouse button to check state.
|
* @param button Mouse button to check state.
|
||||||
* @return True if the key is in InputReleased state.
|
* @return True if the key is in InputReleased state.
|
||||||
*/
|
*/
|
||||||
inline static bool buttonReleased(Qt::MouseButton button) {
|
inline static bool buttonReleased(Qt::MouseButton button)
|
||||||
|
{
|
||||||
return buttonState(button) == InputReleased;
|
return buttonState(button) == InputReleased;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,23 +21,30 @@ Qtk::MeshRenderer::MeshManager Qtk::MeshRenderer::sInstances;
|
|||||||
* Constructors / Destructors
|
* Constructors / Destructors
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
MeshRenderer::MeshRenderer(
|
MeshRenderer::MeshRenderer(const char * name,
|
||||||
const char * name, Vertices vertices, Indices indices, DrawMode mode) :
|
Vertices vertices,
|
||||||
MeshRenderer(
|
Indices indices,
|
||||||
name, ShapeBase(mode, std::move(vertices), std::move(indices))) {}
|
DrawMode mode) :
|
||||||
|
MeshRenderer(name, ShapeBase(mode, std::move(vertices), std::move(indices)))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
MeshRenderer::MeshRenderer(const char * name) :
|
MeshRenderer::MeshRenderer(const char * name) :
|
||||||
MeshRenderer(name, Cube(QTK_DRAW_ELEMENTS)) {}
|
MeshRenderer(name, Cube(QTK_DRAW_ELEMENTS))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
MeshRenderer::MeshRenderer(const char * name, const ShapeBase & shape) :
|
MeshRenderer::MeshRenderer(const char * name, const ShapeBase & shape) :
|
||||||
Object(name, shape, QTK_MESH), mVertexShader(":/shaders/multi-color.vert"),
|
Object(name, shape, QTK_MESH), mVertexShader(":/shaders/multi-color.vert"),
|
||||||
mFragmentShader(":/shaders/multi-color.frag"), mDrawType(GL_TRIANGLES) {
|
mFragmentShader(":/shaders/multi-color.frag"), mDrawType(GL_TRIANGLES)
|
||||||
|
{
|
||||||
mShape = Shape(shape);
|
mShape = Shape(shape);
|
||||||
init();
|
init();
|
||||||
sInstances.insert(name, this);
|
sInstances.insert(name, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
MeshRenderer::~MeshRenderer() {
|
MeshRenderer::~MeshRenderer()
|
||||||
|
{
|
||||||
sInstances.remove(mName.c_str());
|
sInstances.remove(mName.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +52,8 @@ MeshRenderer::~MeshRenderer() {
|
|||||||
* Public Methods
|
* Public Methods
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void MeshRenderer::init() {
|
void MeshRenderer::init()
|
||||||
|
{
|
||||||
if (mVAO.isCreated()) {
|
if (mVAO.isCreated()) {
|
||||||
mVAO.destroy();
|
mVAO.destroy();
|
||||||
}
|
}
|
||||||
@@ -60,10 +68,10 @@ void MeshRenderer::init() {
|
|||||||
mVAO.bind();
|
mVAO.bind();
|
||||||
|
|
||||||
mProgram.create();
|
mProgram.create();
|
||||||
mProgram.addShaderFromSourceFile(
|
mProgram.addShaderFromSourceFile(QOpenGLShader::Vertex,
|
||||||
QOpenGLShader::Vertex, mVertexShader.c_str());
|
mVertexShader.c_str());
|
||||||
mProgram.addShaderFromSourceFile(
|
mProgram.addShaderFromSourceFile(QOpenGLShader::Fragment,
|
||||||
QOpenGLShader::Fragment, mFragmentShader.c_str());
|
mFragmentShader.c_str());
|
||||||
mProgram.link();
|
mProgram.link();
|
||||||
mProgram.bind();
|
mProgram.bind();
|
||||||
|
|
||||||
@@ -84,8 +92,10 @@ void MeshRenderer::init() {
|
|||||||
mProgram.setAttributeBuffer(0, GL_FLOAT, 0, 3, sizeof(QVector3D));
|
mProgram.setAttributeBuffer(0, GL_FLOAT, 0, 3, sizeof(QVector3D));
|
||||||
// Enable color attribute, setting offset to total size of vertices()
|
// Enable color attribute, setting offset to total size of vertices()
|
||||||
mProgram.enableAttributeArray(1);
|
mProgram.enableAttributeArray(1);
|
||||||
mProgram.setAttributeBuffer(
|
mProgram.setAttributeBuffer(1,
|
||||||
1, GL_FLOAT, getVertices().size() * sizeof(getVertices()[0]), 3,
|
GL_FLOAT,
|
||||||
|
getVertices().size() * sizeof(getVertices()[0]),
|
||||||
|
3,
|
||||||
sizeof(QVector3D));
|
sizeof(QVector3D));
|
||||||
|
|
||||||
mVBO.release();
|
mVBO.release();
|
||||||
@@ -94,7 +104,8 @@ void MeshRenderer::init() {
|
|||||||
mVAO.release();
|
mVAO.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshRenderer::draw() {
|
void MeshRenderer::draw()
|
||||||
|
{
|
||||||
bindShaders();
|
bindShaders();
|
||||||
mVAO.bind();
|
mVAO.bind();
|
||||||
|
|
||||||
@@ -107,11 +118,11 @@ void MeshRenderer::draw() {
|
|||||||
|
|
||||||
if (mShape.mDrawMode == QTK_DRAW_ARRAYS) {
|
if (mShape.mDrawMode == QTK_DRAW_ARRAYS) {
|
||||||
glDrawArrays(mDrawType, 0, getVertices().size());
|
glDrawArrays(mDrawType, 0, getVertices().size());
|
||||||
} else if(
|
} else if (mShape.mDrawMode == QTK_DRAW_ELEMENTS
|
||||||
mShape.mDrawMode == QTK_DRAW_ELEMENTS
|
|
||||||
|| mShape.mDrawMode == QTK_DRAW_ELEMENTS_NORMALS) {
|
|| mShape.mDrawMode == QTK_DRAW_ELEMENTS_NORMALS) {
|
||||||
glDrawElements(
|
glDrawElements(mDrawType,
|
||||||
mDrawType, mShape.mIndices.size(), GL_UNSIGNED_INT,
|
mShape.mIndices.size(),
|
||||||
|
GL_UNSIGNED_INT,
|
||||||
mShape.mIndices.data());
|
mShape.mIndices.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,14 +134,16 @@ void MeshRenderer::draw() {
|
|||||||
releaseShaders();
|
releaseShaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshRenderer::enableAttributeArray(int location) {
|
void MeshRenderer::enableAttributeArray(int location)
|
||||||
|
{
|
||||||
ShaderBindScope lock(&mProgram, mBound);
|
ShaderBindScope lock(&mProgram, mBound);
|
||||||
mVAO.bind();
|
mVAO.bind();
|
||||||
mProgram.enableAttributeArray(location);
|
mProgram.enableAttributeArray(location);
|
||||||
mVAO.release();
|
mVAO.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshRenderer::reallocateTexCoords(const TexCoords & t, unsigned dims) {
|
void MeshRenderer::reallocateTexCoords(const TexCoords & t, unsigned dims)
|
||||||
|
{
|
||||||
mVAO.bind();
|
mVAO.bind();
|
||||||
mNBO.destroy();
|
mNBO.destroy();
|
||||||
mNBO.create();
|
mNBO.create();
|
||||||
@@ -146,7 +159,8 @@ void MeshRenderer::reallocateTexCoords(const TexCoords & t, unsigned dims) {
|
|||||||
mVAO.release();
|
mVAO.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshRenderer::reallocateNormals(const Normals & n, unsigned dims) {
|
void MeshRenderer::reallocateNormals(const Normals & n, unsigned dims)
|
||||||
|
{
|
||||||
// TODO: Store state to track if buffer objects are bound
|
// TODO: Store state to track if buffer objects are bound
|
||||||
mVAO.bind();
|
mVAO.bind();
|
||||||
mNBO.destroy();
|
mNBO.destroy();
|
||||||
@@ -163,27 +177,32 @@ void MeshRenderer::reallocateNormals(const Normals & n, unsigned dims) {
|
|||||||
mVAO.release();
|
mVAO.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshRenderer::setShaders(
|
void MeshRenderer::setShaders(const std::string & vert,
|
||||||
const std::string & vert, const std::string & frag) {
|
const std::string & frag)
|
||||||
|
{
|
||||||
mVertexShader = vert;
|
mVertexShader = vert;
|
||||||
mFragmentShader = frag;
|
mFragmentShader = frag;
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshRenderer::setUniformMVP(
|
void MeshRenderer::setUniformMVP(const char * model,
|
||||||
const char * model, const char * view, const char * projection) {
|
const char * view,
|
||||||
|
const char * projection)
|
||||||
|
{
|
||||||
ShaderBindScope lock(&mProgram, mBound);
|
ShaderBindScope lock(&mProgram, mBound);
|
||||||
mProgram.setUniformValue(projection, Scene::getProjectionMatrix());
|
mProgram.setUniformValue(projection, Scene::getProjectionMatrix());
|
||||||
mProgram.setUniformValue(view, Scene::getViewMatrix());
|
mProgram.setUniformValue(view, Scene::getViewMatrix());
|
||||||
mProgram.setUniformValue(model, mTransform.toMatrix());
|
mProgram.setUniformValue(model, mTransform.toMatrix());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshRenderer::setShape(const Shape & value) {
|
void MeshRenderer::setShape(const Shape & value)
|
||||||
|
{
|
||||||
Object::setShape(value);
|
Object::setShape(value);
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshRenderer::setColor(const QVector3D & color) {
|
void MeshRenderer::setColor(const QVector3D & color)
|
||||||
|
{
|
||||||
if (mShape.mColors.empty()) {
|
if (mShape.mColors.empty()) {
|
||||||
for (const auto & vertex : mShape.getVertices()) {
|
for (const auto & vertex : mShape.getVertices()) {
|
||||||
mShape.mColors.push_back(color);
|
mShape.mColors.push_back(color);
|
||||||
@@ -198,7 +217,8 @@ void MeshRenderer::setColor(const QVector3D & color) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MeshRenderer::setAttributeBuffer(
|
void MeshRenderer::setAttributeBuffer(
|
||||||
int location, GLenum type, int offset, int tupleSize, int stride) {
|
int location, GLenum type, int offset, int tupleSize, int stride)
|
||||||
|
{
|
||||||
ShaderBindScope lock(&mProgram, mBound);
|
ShaderBindScope lock(&mProgram, mBound);
|
||||||
mVAO.bind();
|
mVAO.bind();
|
||||||
mProgram.setAttributeBuffer(location, type, offset, tupleSize, stride);
|
mProgram.setAttributeBuffer(location, type, offset, tupleSize, stride);
|
||||||
@@ -210,7 +230,8 @@ void MeshRenderer::setAttributeBuffer(
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
// Static member function to retrieve instances of MeshRenderers
|
// Static member function to retrieve instances of MeshRenderers
|
||||||
MeshRenderer * MeshRenderer::getInstance(const QString & name) {
|
MeshRenderer * MeshRenderer::getInstance(const QString & name)
|
||||||
|
{
|
||||||
if (!sInstances.contains(name)) {
|
if (!sInstances.contains(name)) {
|
||||||
#if QTK_DEBUG
|
#if QTK_DEBUG
|
||||||
qDebug() << "Attempt to access MeshRenderer instance that does not exist! ("
|
qDebug() << "Attempt to access MeshRenderer instance that does not exist! ("
|
||||||
|
|||||||
@@ -14,8 +14,10 @@
|
|||||||
#include "qtkapi.h"
|
#include "qtkapi.h"
|
||||||
#include "shape.h"
|
#include "shape.h"
|
||||||
|
|
||||||
namespace Qtk {
|
namespace Qtk
|
||||||
class QTKAPI MeshRenderer : public Object {
|
{
|
||||||
|
class QTKAPI MeshRenderer : public Object
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Typedefs
|
* Typedefs
|
||||||
@@ -38,8 +40,9 @@ namespace Qtk {
|
|||||||
* @param indices Indicess to use for initializes geometry shape.
|
* @param indices Indicess to use for initializes geometry shape.
|
||||||
* @param mode OpenGL draw mode. Supported modes are prefixed with QTK_*
|
* @param mode OpenGL draw mode. Supported modes are prefixed with QTK_*
|
||||||
*/
|
*/
|
||||||
MeshRenderer(
|
MeshRenderer(const char * name,
|
||||||
const char * name, Vertices vertices, Indices indices,
|
Vertices vertices,
|
||||||
|
Indices indices,
|
||||||
DrawMode mode = QTK_DRAW_ARRAYS);
|
DrawMode mode = QTK_DRAW_ARRAYS);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -112,14 +115,16 @@ namespace Qtk {
|
|||||||
/**
|
/**
|
||||||
* @param vert Path to vertex shader to use for this MeshRenderer.
|
* @param vert Path to vertex shader to use for this MeshRenderer.
|
||||||
*/
|
*/
|
||||||
inline void setShaderVertex(const std::string & vert) {
|
inline void setShaderVertex(const std::string & vert)
|
||||||
|
{
|
||||||
mVertexShader = vert;
|
mVertexShader = vert;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param frag Path to fragment shader to use for this MeshRenderer.
|
* @param frag Path to fragment shader to use for this MeshRenderer.
|
||||||
*/
|
*/
|
||||||
inline void setShaderFragment(const std::string & frag) {
|
inline void setShaderFragment(const std::string & frag)
|
||||||
|
{
|
||||||
mFragmentShader = frag;
|
mFragmentShader = frag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,7 +139,8 @@ namespace Qtk {
|
|||||||
* @param location Index location of the uniform value we are setting.
|
* @param location Index location of the uniform value we are setting.
|
||||||
* @param value The value to use for the uniform.
|
* @param value The value to use for the uniform.
|
||||||
*/
|
*/
|
||||||
template <typename T> inline void setUniform(int location, T value) {
|
template <typename T> inline void setUniform(int location, T value)
|
||||||
|
{
|
||||||
ShaderBindScope lock(&mProgram, mBound);
|
ShaderBindScope lock(&mProgram, mBound);
|
||||||
mProgram.setUniformValue(location, value);
|
mProgram.setUniformValue(location, value);
|
||||||
}
|
}
|
||||||
@@ -145,7 +151,8 @@ namespace Qtk {
|
|||||||
* @param value The value to use for the uniform.
|
* @param value The value to use for the uniform.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void setUniform(const char * location, T value) {
|
inline void setUniform(const char * location, T value)
|
||||||
|
{
|
||||||
ShaderBindScope lock(&mProgram, mBound);
|
ShaderBindScope lock(&mProgram, mBound);
|
||||||
mProgram.setUniformValue(location, value);
|
mProgram.setUniformValue(location, value);
|
||||||
}
|
}
|
||||||
@@ -159,8 +166,8 @@ namespace Qtk {
|
|||||||
* @param view Name of the uniform to store the View matrix.
|
* @param view Name of the uniform to store the View matrix.
|
||||||
* @param projection Name of the uniform to store the Projection matrix.
|
* @param projection Name of the uniform to store the Projection matrix.
|
||||||
*/
|
*/
|
||||||
void setUniformMVP(
|
void setUniformMVP(const char * model = "uModel",
|
||||||
const char * model = "uModel", const char * view = "uView",
|
const char * view = "uView",
|
||||||
const char * projection = "uProjection");
|
const char * projection = "uProjection");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -209,13 +216,15 @@ namespace Qtk {
|
|||||||
/**
|
/**
|
||||||
* @return Transform3D attached to this MeshRenderer.
|
* @return Transform3D attached to this MeshRenderer.
|
||||||
*/
|
*/
|
||||||
inline Transform3D & getTransform() { return mTransform; }
|
inline Transform3D & getTransform() override { return mTransform; }
|
||||||
|
|
||||||
inline std::string getVertexShader() const override {
|
[[nodiscard]] inline std::string getVertexShader() const override
|
||||||
|
{
|
||||||
return mVertexShader;
|
return mVertexShader;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string getFragmentShader() const override {
|
[[nodiscard]] inline std::string getFragmentShader() const override
|
||||||
|
{
|
||||||
return mFragmentShader;
|
return mFragmentShader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,21 +21,24 @@ Model::ModelManager Model::mManager;
|
|||||||
* Public Member Functions
|
* Public Member Functions
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void Model::draw() {
|
void Model::draw()
|
||||||
|
{
|
||||||
for (auto & mesh : mMeshes) {
|
for (auto & mesh : mMeshes) {
|
||||||
mesh.mTransform = mTransform;
|
mesh.mTransform = mTransform;
|
||||||
mesh.draw();
|
mesh.draw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::draw(QOpenGLShaderProgram & shader) {
|
void Model::draw(QOpenGLShaderProgram & shader)
|
||||||
|
{
|
||||||
for (auto & mesh : mMeshes) {
|
for (auto & mesh : mMeshes) {
|
||||||
mesh.mTransform = mTransform;
|
mesh.mTransform = mTransform;
|
||||||
mesh.draw(shader);
|
mesh.draw(shader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::flipTexture(const std::string & fileName, bool flipX, bool flipY) {
|
void Model::flipTexture(const std::string & fileName, bool flipX, bool flipY)
|
||||||
|
{
|
||||||
bool modified = false;
|
bool modified = false;
|
||||||
std::string fullPath = mDirectory + '/' + fileName;
|
std::string fullPath = mDirectory + '/' + fileName;
|
||||||
for (auto & texture : mTexturesLoaded) {
|
for (auto & texture : mTexturesLoaded) {
|
||||||
@@ -54,7 +57,8 @@ void Model::flipTexture(const std::string & fileName, bool flipX, bool flipY) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Static function to access ModelManager for getting Models by name
|
// Static function to access ModelManager for getting Models by name
|
||||||
Model * Qtk::Model::getInstance(const char * name) {
|
Model * Qtk::Model::getInstance(const char * name)
|
||||||
|
{
|
||||||
return mManager[name];
|
return mManager[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +66,8 @@ Model * Qtk::Model::getInstance(const char * name) {
|
|||||||
* Private Member Functions
|
* Private Member Functions
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void Model::loadModel(const std::string & path) {
|
void Model::loadModel(const std::string & path)
|
||||||
|
{
|
||||||
Assimp::Importer import;
|
Assimp::Importer import;
|
||||||
// If using a Qt Resource path, use QtkIOSystem for file handling.
|
// If using a Qt Resource path, use QtkIOSystem for file handling.
|
||||||
if (path.front() == ':') {
|
if (path.front() == ':') {
|
||||||
@@ -75,13 +80,14 @@ void Model::loadModel(const std::string & path) {
|
|||||||
// + And flipping texture UVs, etc..
|
// + And flipping texture UVs, etc..
|
||||||
// Assimp options: http://assimp.sourceforge.net/lib_html/postprocess_8h.html
|
// Assimp options: http://assimp.sourceforge.net/lib_html/postprocess_8h.html
|
||||||
const aiScene * scene = import.ReadFile(
|
const aiScene * scene = import.ReadFile(
|
||||||
path.c_str(), aiProcess_Triangulate | aiProcess_FlipUVs
|
path.c_str(),
|
||||||
| aiProcess_GenSmoothNormals
|
aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_GenSmoothNormals
|
||||||
| aiProcess_CalcTangentSpace | aiProcess_OptimizeMeshes
|
| aiProcess_CalcTangentSpace | aiProcess_OptimizeMeshes
|
||||||
| aiProcess_SplitLargeMeshes);
|
| aiProcess_SplitLargeMeshes);
|
||||||
|
|
||||||
// If there were errors, print and return
|
// If there were errors, print and return
|
||||||
if(!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
|
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE
|
||||||
|
|| !scene->mRootNode) {
|
||||||
qDebug() << "Error::ASSIMP::" << import.GetErrorString() << "\n";
|
qDebug() << "Error::ASSIMP::" << import.GetErrorString() << "\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -99,7 +105,8 @@ void Model::loadModel(const std::string & path) {
|
|||||||
mManager.insert(getName().c_str(), this);
|
mManager.insert(getName().c_str(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::processNode(aiNode * node, const aiScene * scene) {
|
void Model::processNode(aiNode * node, const aiScene * scene)
|
||||||
|
{
|
||||||
// Process each mesh that is available for this node
|
// Process each mesh that is available for this node
|
||||||
for (GLuint i = 0; i < node->mNumMeshes; i++) {
|
for (GLuint i = 0; i < node->mNumMeshes; i++) {
|
||||||
aiMesh * mesh = scene->mMeshes[node->mMeshes[i]];
|
aiMesh * mesh = scene->mMeshes[node->mMeshes[i]];
|
||||||
@@ -112,7 +119,8 @@ void Model::processNode(aiNode * node, const aiScene * scene) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelMesh Model::processMesh(aiMesh * mesh, const aiScene * scene) {
|
ModelMesh Model::processMesh(aiMesh * mesh, const aiScene * scene)
|
||||||
|
{
|
||||||
ModelMesh::Vertices vertices;
|
ModelMesh::Vertices vertices;
|
||||||
ModelMesh::Indices indices;
|
ModelMesh::Indices indices;
|
||||||
ModelMesh::Textures textures;
|
ModelMesh::Textures textures;
|
||||||
@@ -200,13 +208,17 @@ ModelMesh Model::processMesh(aiMesh * mesh, const aiScene * scene) {
|
|||||||
textures.insert(textures.end(), normalMaps.begin(), normalMaps.end());
|
textures.insert(textures.end(), normalMaps.begin(), normalMaps.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {vertices,
|
||||||
vertices, indices, textures, mVertexShader.c_str(),
|
indices,
|
||||||
|
textures,
|
||||||
|
mVertexShader.c_str(),
|
||||||
mFragmentShader.c_str()};
|
mFragmentShader.c_str()};
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelMesh::Textures Model::loadMaterialTextures(
|
ModelMesh::Textures Model::loadMaterialTextures(aiMaterial * mat,
|
||||||
aiMaterial * mat, aiTextureType type, const std::string & typeName) {
|
aiTextureType type,
|
||||||
|
const std::string & typeName)
|
||||||
|
{
|
||||||
ModelMesh::Textures textures;
|
ModelMesh::Textures textures;
|
||||||
|
|
||||||
for (GLuint i = 0; i < mat->GetTextureCount(type); i++) {
|
for (GLuint i = 0; i < mat->GetTextureCount(type); i++) {
|
||||||
@@ -230,7 +242,8 @@ ModelMesh::Textures Model::loadMaterialTextures(
|
|||||||
if (!skip) {
|
if (!skip) {
|
||||||
ModelTexture texture;
|
ModelTexture texture;
|
||||||
texture.mTexture = OpenGLTextureFactory::initTexture(
|
texture.mTexture = OpenGLTextureFactory::initTexture(
|
||||||
std::string(mDirectory + '/' + fileName.C_Str()).c_str(), false,
|
std::string(mDirectory + '/' + fileName.C_Str()).c_str(),
|
||||||
|
false,
|
||||||
false);
|
false);
|
||||||
texture.mID = texture.mTexture->textureId();
|
texture.mID = texture.mTexture->textureId();
|
||||||
texture.mType = typeName;
|
texture.mType = typeName;
|
||||||
@@ -246,7 +259,8 @@ ModelMesh::Textures Model::loadMaterialTextures(
|
|||||||
return textures;
|
return textures;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::sortModelMeshes() {
|
void Model::sortModelMeshes()
|
||||||
|
{
|
||||||
auto cameraPos = Scene::getCamera().getTransform();
|
auto cameraPos = Scene::getCamera().getTransform();
|
||||||
auto cameraDistance = [&cameraPos](const ModelMesh & a, const ModelMesh & b) {
|
auto cameraDistance = [&cameraPos](const ModelMesh & a, const ModelMesh & b) {
|
||||||
// Sort by the first vertex position in the model
|
// Sort by the first vertex position in the model
|
||||||
|
|||||||
@@ -24,12 +24,14 @@
|
|||||||
#include "modelmesh.h"
|
#include "modelmesh.h"
|
||||||
#include "qtkapi.h"
|
#include "qtkapi.h"
|
||||||
|
|
||||||
namespace Qtk {
|
namespace Qtk
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Model object that has a ModelMesh.
|
* Model object that has a ModelMesh.
|
||||||
* Top-level object that represents 3D models stored within a scene.
|
* Top-level object that represents 3D models stored within a scene.
|
||||||
*/
|
*/
|
||||||
class QTKAPI Model : public Object {
|
class QTKAPI Model : public Object
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Typedefs
|
* Typedefs
|
||||||
@@ -51,13 +53,13 @@ namespace Qtk {
|
|||||||
* @param vertexShader Optional path to custom vertex shader.
|
* @param vertexShader Optional path to custom vertex shader.
|
||||||
* @param fragmentShader Optional path to custom fragment shader.
|
* @param fragmentShader Optional path to custom fragment shader.
|
||||||
*/
|
*/
|
||||||
inline Model(
|
inline Model(const char * name,
|
||||||
const char * name, const char * path,
|
const char * path,
|
||||||
const char * vertexShader = ":/shaders/model-basic.vert",
|
const char * vertexShader = ":/shaders/model-basic.vert",
|
||||||
const char * fragmentShader = ":/shaders/model-basic.frag") :
|
const char * fragmentShader = ":/shaders/model-basic.frag") :
|
||||||
Object(name, QTK_MODEL),
|
Object(name, QTK_MODEL), mModelPath(path),
|
||||||
mModelPath(path), mVertexShader(vertexShader),
|
mVertexShader(vertexShader), mFragmentShader(fragmentShader)
|
||||||
mFragmentShader(fragmentShader) {
|
{
|
||||||
loadModel(mModelPath);
|
loadModel(mModelPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,8 +88,9 @@ namespace Qtk {
|
|||||||
* @param flipX Flip the texture along the X axis
|
* @param flipX Flip the texture along the X axis
|
||||||
* @param flipY Flip the texture along the Y axis
|
* @param flipY Flip the texture along the Y axis
|
||||||
*/
|
*/
|
||||||
void flipTexture(
|
void flipTexture(const std::string & fileName,
|
||||||
const std::string & fileName, bool flipX = false, bool flipY = true);
|
bool flipX = false,
|
||||||
|
bool flipY = true);
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Setters
|
* Setters
|
||||||
@@ -101,7 +104,8 @@ namespace Qtk {
|
|||||||
* @param value The value to assign to the uniform
|
* @param value The value to assign to the uniform
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void setUniform(const char * location, T value) {
|
inline void setUniform(const char * location, T value)
|
||||||
|
{
|
||||||
for (auto & mesh : mMeshes) {
|
for (auto & mesh : mMeshes) {
|
||||||
mesh.mProgram->bind();
|
mesh.mProgram->bind();
|
||||||
mesh.mProgram->setUniformValue(location, value);
|
mesh.mProgram->setUniformValue(location, value);
|
||||||
@@ -125,13 +129,15 @@ namespace Qtk {
|
|||||||
/**
|
/**
|
||||||
* @return Transform3D attached to this Model.
|
* @return Transform3D attached to this Model.
|
||||||
*/
|
*/
|
||||||
inline Transform3D & getTransform() { return mTransform; }
|
inline Transform3D & getTransform() override { return mTransform; }
|
||||||
|
|
||||||
inline std::string getVertexShader() const override {
|
[[nodiscard]] inline std::string getVertexShader() const override
|
||||||
|
{
|
||||||
return mVertexShader;
|
return mVertexShader;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string getFragmentShader() const override {
|
[[nodiscard]] inline std::string getFragmentShader() const override
|
||||||
|
{
|
||||||
return mFragmentShader;
|
return mFragmentShader;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,8 +189,9 @@ namespace Qtk {
|
|||||||
* @param typeName Texture type name in string format.
|
* @param typeName Texture type name in string format.
|
||||||
* @return Collection of all textures for a single ModelMesh.
|
* @return Collection of all textures for a single ModelMesh.
|
||||||
*/
|
*/
|
||||||
ModelMesh::Textures loadMaterialTextures(
|
ModelMesh::Textures loadMaterialTextures(aiMaterial * mat,
|
||||||
aiMaterial * mat, aiTextureType type, const std::string & typeName);
|
aiTextureType type,
|
||||||
|
const std::string & typeName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sorts each mesh in the Model based on distance from the camera.
|
* Sorts each mesh in the Model based on distance from the camera.
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ using namespace Qtk;
|
|||||||
* Public Member Functions
|
* Public Member Functions
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void ModelMesh::draw(QOpenGLShaderProgram & shader) {
|
void ModelMesh::draw(QOpenGLShaderProgram & shader)
|
||||||
|
{
|
||||||
mVAO->bind();
|
mVAO->bind();
|
||||||
// Bind shader
|
// Bind shader
|
||||||
shader.bind();
|
shader.bind();
|
||||||
@@ -72,7 +73,8 @@ void ModelMesh::draw(QOpenGLShaderProgram & shader) {
|
|||||||
* Private Member Functions
|
* Private Member Functions
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void ModelMesh::initMesh(const char * vert, const char * frag) {
|
void ModelMesh::initMesh(const char * vert, const char * frag)
|
||||||
|
{
|
||||||
initializeOpenGLFunctions();
|
initializeOpenGLFunctions();
|
||||||
|
|
||||||
// Create VAO, VBO, EBO
|
// Create VAO, VBO, EBO
|
||||||
@@ -112,8 +114,10 @@ void ModelMesh::initMesh(const char * vert, const char * frag) {
|
|||||||
|
|
||||||
// Texture Coordinates
|
// Texture Coordinates
|
||||||
mProgram->enableAttributeArray(2);
|
mProgram->enableAttributeArray(2);
|
||||||
mProgram->setAttributeBuffer(
|
mProgram->setAttributeBuffer(2,
|
||||||
2, GL_FLOAT, offsetof(ModelVertex, mTextureCoord), 2,
|
GL_FLOAT,
|
||||||
|
offsetof(ModelVertex, mTextureCoord),
|
||||||
|
2,
|
||||||
sizeof(ModelVertex));
|
sizeof(ModelVertex));
|
||||||
|
|
||||||
// Vertex tangents
|
// Vertex tangents
|
||||||
|
|||||||
@@ -9,12 +9,15 @@
|
|||||||
#ifndef QTK_MODELMESH_H
|
#ifndef QTK_MODELMESH_H
|
||||||
#define QTK_MODELMESH_H
|
#define QTK_MODELMESH_H
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include <QOpenGLFunctions>
|
#include <QOpenGLFunctions>
|
||||||
|
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
#include "transform3D.h"
|
#include "transform3D.h"
|
||||||
|
|
||||||
namespace Qtk {
|
namespace Qtk
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* 3D models will store this data for each vertex in geometry.
|
* 3D models will store this data for each vertex in geometry.
|
||||||
*/
|
*/
|
||||||
@@ -39,8 +42,9 @@ namespace Qtk {
|
|||||||
* @param type Type of texture in string format.
|
* @param type Type of texture in string format.
|
||||||
* @param path Path to the texture on disk.
|
* @param path Path to the texture on disk.
|
||||||
*/
|
*/
|
||||||
ModelTexture(const std::string & type, const std::string & path) :
|
ModelTexture(std::string type, const std::string & path) :
|
||||||
mType(type), mPath(path) {
|
mType(std::move(type)), mPath(path)
|
||||||
|
{
|
||||||
mTexture = OpenGLTextureFactory::initTexture(path.c_str());
|
mTexture = OpenGLTextureFactory::initTexture(path.c_str());
|
||||||
mID = mTexture->textureId();
|
mID = mTexture->textureId();
|
||||||
}
|
}
|
||||||
@@ -64,7 +68,8 @@ namespace Qtk {
|
|||||||
* Mesh class specialized for storing 3D model data.
|
* Mesh class specialized for storing 3D model data.
|
||||||
* Eventually this can be consolidated into a more generic class.
|
* Eventually this can be consolidated into a more generic class.
|
||||||
*/
|
*/
|
||||||
class QTKAPI ModelMesh : protected QOpenGLFunctions {
|
class QTKAPI ModelMesh : protected QOpenGLFunctions
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Typedefs
|
* Typedefs
|
||||||
@@ -89,8 +94,9 @@ namespace Qtk {
|
|||||||
* @param vertexShader Path to vertex shader for this ModelMesh.
|
* @param vertexShader Path to vertex shader for this ModelMesh.
|
||||||
* @param fragmentShader Path to fragment shader for this ModelMesh.
|
* @param fragmentShader Path to fragment shader for this ModelMesh.
|
||||||
*/
|
*/
|
||||||
ModelMesh(
|
ModelMesh(Vertices vertices,
|
||||||
Vertices vertices, Indices indices, Textures textures,
|
Indices indices,
|
||||||
|
Textures textures,
|
||||||
const char * vertexShader = ":/model-basic.vert",
|
const char * vertexShader = ":/model-basic.vert",
|
||||||
const char * fragmentShader = ":/model-basic.frag") :
|
const char * fragmentShader = ":/model-basic.frag") :
|
||||||
mProgram(new QOpenGLShaderProgram),
|
mProgram(new QOpenGLShaderProgram),
|
||||||
@@ -98,7 +104,8 @@ namespace Qtk {
|
|||||||
mVBO(new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer)),
|
mVBO(new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer)),
|
||||||
mEBO(new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer)),
|
mEBO(new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer)),
|
||||||
mVertices(std::move(vertices)), mIndices(std::move(indices)),
|
mVertices(std::move(vertices)), mIndices(std::move(indices)),
|
||||||
mTextures(std::move(textures)) {
|
mTextures(std::move(textures))
|
||||||
|
{
|
||||||
initMesh(vertexShader, fragmentShader);
|
initMesh(vertexShader, fragmentShader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
107
src/qtk/object.h
@@ -17,14 +17,16 @@
|
|||||||
#include "shape.h"
|
#include "shape.h"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
|
|
||||||
namespace Qtk {
|
namespace Qtk
|
||||||
|
{
|
||||||
class Model;
|
class Model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object base class for objects that can exist within a scene.
|
* Object base class for objects that can exist within a scene.
|
||||||
* An object could be a Cube, Skybox, 3D Model, or other standalone entities.
|
* An object could be a Cube, Skybox, 3D Model, or other standalone entities.
|
||||||
*/
|
*/
|
||||||
class QTKAPI Object : public QObject {
|
class QTKAPI Object : public QObject
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -47,7 +49,8 @@ namespace Qtk {
|
|||||||
// Initialize an object with no shape data assigned
|
// Initialize an object with no shape data assigned
|
||||||
explicit Object(const char * name, Type type) :
|
explicit Object(const char * name, Type type) :
|
||||||
mName(name), mVBO(QOpenGLBuffer::VertexBuffer), mBound(false),
|
mName(name), mVBO(QOpenGLBuffer::VertexBuffer), mBound(false),
|
||||||
mType(type) {
|
mType(type)
|
||||||
|
{
|
||||||
initResources();
|
initResources();
|
||||||
setObjectName(name);
|
setObjectName(name);
|
||||||
}
|
}
|
||||||
@@ -55,7 +58,8 @@ namespace Qtk {
|
|||||||
// Initialize an object with shape data assigned
|
// Initialize an object with shape data assigned
|
||||||
Object(const char * name, const ShapeBase & shape, Type type) :
|
Object(const char * name, const ShapeBase & shape, Type type) :
|
||||||
mName(name), mVBO(QOpenGLBuffer::VertexBuffer), mShape(shape),
|
mName(name), mVBO(QOpenGLBuffer::VertexBuffer), mShape(shape),
|
||||||
mBound(false), mType(type) {
|
mBound(false), mType(type)
|
||||||
|
{
|
||||||
initResources();
|
initResources();
|
||||||
setObjectName(name);
|
setObjectName(name);
|
||||||
}
|
}
|
||||||
@@ -66,29 +70,35 @@ namespace Qtk {
|
|||||||
* Accessors
|
* Accessors
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
[[nodiscard]] inline const Colors & getColors() const {
|
[[nodiscard]] inline const Colors & getColors() const
|
||||||
|
{
|
||||||
return mShape.mColors;
|
return mShape.mColors;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline const Indices & getIndexData() const {
|
[[nodiscard]] inline const Indices & getIndexData() const
|
||||||
|
{
|
||||||
return mShape.mIndices;
|
return mShape.mIndices;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline const Normals & getNormals() const {
|
[[nodiscard]] inline const Normals & getNormals() const
|
||||||
|
{
|
||||||
return mShape.mNormals;
|
return mShape.mNormals;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline const Shape & getShape() const { return mShape; }
|
[[nodiscard]] inline const Shape & getShape() const { return mShape; }
|
||||||
|
|
||||||
[[nodiscard]] inline const TexCoords & getTexCoords() const {
|
[[nodiscard]] inline const TexCoords & getTexCoords() const
|
||||||
|
{
|
||||||
return mShape.mTexCoords;
|
return mShape.mTexCoords;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline const Texture & getTexture() const {
|
[[nodiscard]] inline const Texture & getTexture() const
|
||||||
|
{
|
||||||
return mTexture;
|
return mTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline const Vertices & getVertices() const {
|
[[nodiscard]] inline const Vertices & getVertices() const
|
||||||
|
{
|
||||||
return mShape.mVertices;
|
return mShape.mVertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,15 +106,23 @@ namespace Qtk {
|
|||||||
|
|
||||||
[[nodiscard]] inline const Type & getType() const { return mType; }
|
[[nodiscard]] inline const Type & getType() const { return mType; }
|
||||||
|
|
||||||
[[nodiscard]] inline virtual const Transform3D & getTransform() const {
|
[[nodiscard]] inline virtual const Transform3D & getTransform() const
|
||||||
|
{
|
||||||
return mTransform;
|
return mTransform;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline virtual std::string getVertexShader() const {
|
[[nodiscard]] inline virtual Transform3D & getTransform()
|
||||||
|
{
|
||||||
|
return mTransform;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline virtual std::string getVertexShader() const
|
||||||
|
{
|
||||||
return "Base Object has no vertex shader.";
|
return "Base Object has no vertex shader.";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual inline std::string getFragmentShader() const {
|
[[nodiscard]] virtual inline std::string getFragmentShader() const
|
||||||
|
{
|
||||||
return "Base Object has no fragment shader.";
|
return "Base Object has no fragment shader.";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,71 +132,86 @@ namespace Qtk {
|
|||||||
|
|
||||||
virtual inline void setName(const std::string & name) { mName = name; }
|
virtual inline void setName(const std::string & name) { mName = name; }
|
||||||
|
|
||||||
virtual inline void setColors(const Colors & value) {
|
virtual inline void setColors(const Colors & value)
|
||||||
|
{
|
||||||
mShape.mColors = value;
|
mShape.mColors = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual inline void setIndices(const Indices & value) {
|
virtual inline void setIndices(const Indices & value)
|
||||||
|
{
|
||||||
mShape.mIndices = value;
|
mShape.mIndices = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual inline void setNormals(const Normals & value) {
|
virtual inline void setNormals(const Normals & value)
|
||||||
|
{
|
||||||
mShape.mNormals = value;
|
mShape.mNormals = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual inline void setShape(const Shape & value) { mShape = value; }
|
virtual inline void setShape(const Shape & value) { mShape = value; }
|
||||||
|
|
||||||
virtual inline void setTexCoords(const TexCoords & value) {
|
virtual inline void setTexCoords(const TexCoords & value)
|
||||||
|
{
|
||||||
mShape.mTexCoords = value;
|
mShape.mTexCoords = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual inline void setTexture(
|
virtual inline void setTexture(const char * path,
|
||||||
const char * path, bool flipX = false, bool flipY = false) {
|
bool flipX = false,
|
||||||
|
bool flipY = false)
|
||||||
|
{
|
||||||
mTexture.setTexture(path, flipX, flipY);
|
mTexture.setTexture(path, flipX, flipY);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual inline void setCubeMap(const char * path) {
|
virtual inline void setCubeMap(const char * path)
|
||||||
|
{
|
||||||
mTexture.setCubeMap(path);
|
mTexture.setCubeMap(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual inline void setTexture(const Texture & t) {
|
virtual inline void setTexture(const Texture & t)
|
||||||
|
{
|
||||||
mTexture.setTexture(t.getPath());
|
mTexture.setTexture(t.getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual inline void setVertices(const Vertices & value) {
|
virtual inline void setVertices(const Vertices & value)
|
||||||
|
{
|
||||||
mShape.mVertices = value;
|
mShape.mVertices = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setScaleX(double x) {
|
inline void setScaleX(double x)
|
||||||
|
{
|
||||||
mTransform.setScale(
|
mTransform.setScale(
|
||||||
x, mTransform.getScale().y(), mTransform.getScale().z());
|
x, mTransform.getScale().y(), mTransform.getScale().z());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setScaleY(double y) {
|
inline void setScaleY(double y)
|
||||||
|
{
|
||||||
mTransform.setScale(
|
mTransform.setScale(
|
||||||
mTransform.getScale().x(), y, mTransform.getScale().z());
|
mTransform.getScale().x(), y, mTransform.getScale().z());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setScaleZ(double z) {
|
inline void setScaleZ(double z)
|
||||||
|
{
|
||||||
mTransform.setScale(
|
mTransform.setScale(
|
||||||
mTransform.getScale().x(), mTransform.getScale().y(), z);
|
mTransform.getScale().x(), mTransform.getScale().y(), z);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setTranslationX(double x) {
|
inline void setTranslationX(double x)
|
||||||
mTransform.setTranslation(
|
{
|
||||||
x, mTransform.getTranslation().y(),
|
mTransform.setTranslation(x,
|
||||||
|
mTransform.getTranslation().y(),
|
||||||
mTransform.getTranslation().z());
|
mTransform.getTranslation().z());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setTranslationY(double y) {
|
inline void setTranslationY(double y)
|
||||||
mTransform.setTranslation(
|
{
|
||||||
mTransform.getTranslation().x(), y,
|
mTransform.setTranslation(mTransform.getTranslation().x(),
|
||||||
|
y,
|
||||||
mTransform.getTranslation().z());
|
mTransform.getTranslation().z());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setTranslationZ(double z) {
|
inline void setTranslationZ(double z)
|
||||||
mTransform.setTranslation(
|
{
|
||||||
mTransform.getTranslation().x(), mTransform.getTranslation().y(),
|
mTransform.setTranslation(mTransform.getTranslation().x(),
|
||||||
|
mTransform.getTranslation().y(),
|
||||||
z);
|
z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,12 +219,14 @@ namespace Qtk {
|
|||||||
* Public Methods
|
* Public Methods
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
virtual inline void bindShaders() {
|
virtual inline void bindShaders()
|
||||||
|
{
|
||||||
mBound = true;
|
mBound = true;
|
||||||
mProgram.bind();
|
mProgram.bind();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual inline void releaseShaders() {
|
virtual inline void releaseShaders()
|
||||||
|
{
|
||||||
mBound = false;
|
mBound = false;
|
||||||
mProgram.release();
|
mProgram.release();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,11 +27,13 @@
|
|||||||
* This cannot be defined within any namespace, but can be called by ctors.
|
* This cannot be defined within any namespace, but can be called by ctors.
|
||||||
* See object.h for example.
|
* See object.h for example.
|
||||||
*/
|
*/
|
||||||
inline void initResources() {
|
inline void initResources()
|
||||||
|
{
|
||||||
Q_INIT_RESOURCE(resources);
|
Q_INIT_RESOURCE(resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Qtk {
|
namespace Qtk
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Flag to set context for debug messages.
|
* Flag to set context for debug messages.
|
||||||
*/
|
*/
|
||||||
@@ -43,7 +45,8 @@ namespace Qtk {
|
|||||||
* @param widget Widget to start the search from.
|
* @param widget Widget to start the search from.
|
||||||
* @return Top level parent widget or Q_NULLPTR if no parent
|
* @return Top level parent widget or Q_NULLPTR if no parent
|
||||||
*/
|
*/
|
||||||
static QWidget * topLevelParent(QWidget * widget) {
|
static QWidget * topLevelParent(QWidget * widget)
|
||||||
|
{
|
||||||
QString name = widget->objectName();
|
QString name = widget->objectName();
|
||||||
while (widget->parentWidget() != Q_NULLPTR) {
|
while (widget->parentWidget() != Q_NULLPTR) {
|
||||||
widget = widget->parentWidget();
|
widget = widget->parentWidget();
|
||||||
@@ -54,7 +57,8 @@ namespace Qtk {
|
|||||||
/**
|
/**
|
||||||
* @return Default icon to use for Qtk desktop application.
|
* @return Default icon to use for Qtk desktop application.
|
||||||
*/
|
*/
|
||||||
static QIcon getIcon() {
|
static QIcon getIcon()
|
||||||
|
{
|
||||||
return QIcon(":/icons/icon.png");
|
return QIcon(":/icons/icon.png");
|
||||||
}
|
}
|
||||||
} // namespace Qtk
|
} // namespace Qtk
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ using namespace Qtk;
|
|||||||
* Constructors, Destructors
|
* Constructors, Destructors
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
QtkIOStream::QtkIOStream(const char * pFile, const char * pMode) :
|
QtkIOStream::QtkIOStream(const char * pFile, const char * pMode) : mFile(pFile)
|
||||||
mFile(pFile) {
|
{
|
||||||
QString mode(pMode);
|
QString mode(pMode);
|
||||||
bool open = false;
|
bool open = false;
|
||||||
if (mode == "w" || mode == "wb") {
|
if (mode == "w" || mode == "wb") {
|
||||||
@@ -40,7 +40,8 @@ QtkIOStream::QtkIOStream(const char * pFile, const char * pMode) :
|
|||||||
* Public Member Functions
|
* Public Member Functions
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
size_t QtkIOStream::Read(void * pvBuffer, size_t pSize, size_t pCount) {
|
size_t QtkIOStream::Read(void * pvBuffer, size_t pSize, size_t pCount)
|
||||||
|
{
|
||||||
qint64 readSize = mFile.read((char *)pvBuffer, pSize * pCount);
|
qint64 readSize = mFile.read((char *)pvBuffer, pSize * pCount);
|
||||||
if (readSize < 0) {
|
if (readSize < 0) {
|
||||||
qDebug() << "[Qtk::QtkIOStream] Failed to read (" << pSize
|
qDebug() << "[Qtk::QtkIOStream] Failed to read (" << pSize
|
||||||
@@ -51,7 +52,8 @@ size_t QtkIOStream::Read(void * pvBuffer, size_t pSize, size_t pCount) {
|
|||||||
return readSize;
|
return readSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t QtkIOStream::Write(const void * pvBuffer, size_t pSize, size_t pCount) {
|
size_t QtkIOStream::Write(const void * pvBuffer, size_t pSize, size_t pCount)
|
||||||
|
{
|
||||||
qint64 writeSize = mFile.write((char *)pvBuffer, pSize * pCount);
|
qint64 writeSize = mFile.write((char *)pvBuffer, pSize * pCount);
|
||||||
if (writeSize < 0) {
|
if (writeSize < 0) {
|
||||||
qDebug() << "[Qtk::QtkIOStream] Failed to write buffer with size (" << pSize
|
qDebug() << "[Qtk::QtkIOStream] Failed to write buffer with size (" << pSize
|
||||||
@@ -61,18 +63,22 @@ size_t QtkIOStream::Write(const void * pvBuffer, size_t pSize, size_t pCount) {
|
|||||||
return writeSize;
|
return writeSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
aiReturn QtkIOStream::Seek(size_t pOffset, aiOrigin pOrigin) {
|
aiReturn QtkIOStream::Seek(size_t pOffset, aiOrigin pOrigin)
|
||||||
|
{
|
||||||
return mFile.seek(pOffset) ? aiReturn_SUCCESS : aiReturn_FAILURE;
|
return mFile.seek(pOffset) ? aiReturn_SUCCESS : aiReturn_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t QtkIOStream::Tell() const {
|
size_t QtkIOStream::Tell() const
|
||||||
|
{
|
||||||
return mFile.pos();
|
return mFile.pos();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t QtkIOStream::FileSize() const {
|
size_t QtkIOStream::FileSize() const
|
||||||
|
{
|
||||||
return mFile.size();
|
return mFile.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtkIOStream::Flush() {
|
void QtkIOStream::Flush()
|
||||||
|
{
|
||||||
mFile.flush();
|
mFile.flush();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,12 +15,14 @@
|
|||||||
#ifndef QTK_QTKIOSTREAM_H
|
#ifndef QTK_QTKIOSTREAM_H
|
||||||
#define QTK_QTKIOSTREAM_H
|
#define QTK_QTKIOSTREAM_H
|
||||||
|
|
||||||
namespace Qtk {
|
namespace Qtk
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Custom Assimp IO stream to support QtkIOSystem file handling.
|
* Custom Assimp IO stream to support QtkIOSystem file handling.
|
||||||
* Allows direct use of Qt Resource paths for loading models in Assimp.
|
* Allows direct use of Qt Resource paths for loading models in Assimp.
|
||||||
*/
|
*/
|
||||||
class QtkIOStream : public Assimp::IOStream {
|
class QtkIOStream : public Assimp::IOStream
|
||||||
|
{
|
||||||
friend class QtkIOSystem;
|
friend class QtkIOSystem;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -15,15 +15,18 @@ using namespace Qtk;
|
|||||||
* Public Member Functions
|
* Public Member Functions
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
bool QtkIOSystem::Exists(const char * pFile) const {
|
bool QtkIOSystem::Exists(const char * pFile) const
|
||||||
|
{
|
||||||
return QFileInfo::exists(pFile);
|
return QFileInfo::exists(pFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
char QtkIOSystem::getOsSeparator() const {
|
char QtkIOSystem::getOsSeparator() const
|
||||||
|
{
|
||||||
return QDir::separator().toLatin1();
|
return QDir::separator().toLatin1();
|
||||||
}
|
}
|
||||||
|
|
||||||
Assimp::IOStream * QtkIOSystem::Open(const char * pFile, const char * pMode) {
|
Assimp::IOStream * QtkIOSystem::Open(const char * pFile, const char * pMode)
|
||||||
|
{
|
||||||
if (!Exists(pFile)) {
|
if (!Exists(pFile)) {
|
||||||
qDebug() << "[Qtk::QtkIOSystem] failed to open file: " << pFile << "\n";
|
qDebug() << "[Qtk::QtkIOSystem] failed to open file: " << pFile << "\n";
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -31,6 +34,7 @@ Assimp::IOStream * QtkIOSystem::Open(const char * pFile, const char * pMode) {
|
|||||||
return new QtkIOStream(pFile, pMode);
|
return new QtkIOStream(pFile, pMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtkIOSystem::Close(Assimp::IOStream * pFile) {
|
void QtkIOSystem::Close(Assimp::IOStream * pFile)
|
||||||
|
{
|
||||||
delete pFile;
|
delete pFile;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,11 +15,13 @@
|
|||||||
#ifndef QTK_QTKIOSYSTEM_H
|
#ifndef QTK_QTKIOSYSTEM_H
|
||||||
#define QTK_QTKIOSYSTEM_H
|
#define QTK_QTKIOSYSTEM_H
|
||||||
|
|
||||||
namespace Qtk {
|
namespace Qtk
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Assimp IO system for loading models with assimp, using Qt Resource paths.
|
* Assimp IO system for loading models with assimp, using Qt Resource paths.
|
||||||
*/
|
*/
|
||||||
class QtkIOSystem : public Assimp::IOSystem {
|
class QtkIOSystem : public Assimp::IOSystem
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
QtkIOSystem() = default;
|
QtkIOSystem() = default;
|
||||||
~QtkIOSystem() = default;
|
~QtkIOSystem() = default;
|
||||||
@@ -40,8 +42,8 @@ namespace Qtk {
|
|||||||
* @param pMode Mode to open file. See `man fopen`.
|
* @param pMode Mode to open file. See `man fopen`.
|
||||||
* @return QtkIOStream for the opened file.
|
* @return QtkIOStream for the opened file.
|
||||||
*/
|
*/
|
||||||
Assimp::IOStream * Open(
|
Assimp::IOStream * Open(const char * pFile,
|
||||||
const char * pFile, const char * pMode = "rb") override;
|
const char * pMode = "rb") override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param pFile File to close.
|
* @param pFile File to close.
|
||||||
|
|||||||
@@ -18,12 +18,14 @@ QMatrix4x4 Scene::mProjection;
|
|||||||
* Constructors / Destructors
|
* Constructors / Destructors
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
Scene::Scene() : mSceneName("Default Scene") {
|
Scene::Scene() : mSceneName("Default Scene")
|
||||||
|
{
|
||||||
mCamera.getTransform().setTranslation(0.0f, 0.0f, 20.0f);
|
mCamera.getTransform().setTranslation(0.0f, 0.0f, 20.0f);
|
||||||
mCamera.getTransform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f);
|
mCamera.getTransform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene::~Scene() {
|
Scene::~Scene()
|
||||||
|
{
|
||||||
for (auto & mesh : mMeshes) {
|
for (auto & mesh : mMeshes) {
|
||||||
delete mesh;
|
delete mesh;
|
||||||
}
|
}
|
||||||
@@ -37,27 +39,32 @@ Scene::~Scene() {
|
|||||||
* Public Methods
|
* Public Methods
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
template <> MeshRenderer * Scene::addObject(MeshRenderer * object) {
|
template <> MeshRenderer * Scene::addObject(MeshRenderer * object)
|
||||||
|
{
|
||||||
initSceneObjectName(object);
|
initSceneObjectName(object);
|
||||||
mMeshes.push_back(object);
|
mMeshes.push_back(object);
|
||||||
sceneUpdated(mSceneName);
|
sceneUpdated(mSceneName);
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> Model * Scene::addObject(Model * object) {
|
template <> Model * Scene::addObject(Model * object)
|
||||||
|
{
|
||||||
initSceneObjectName(object);
|
initSceneObjectName(object);
|
||||||
mModels.push_back(object);
|
mModels.push_back(object);
|
||||||
sceneUpdated(mSceneName);
|
sceneUpdated(mSceneName);
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::draw() {
|
void Scene::draw()
|
||||||
|
{
|
||||||
if (!mInit) {
|
if (!mInit) {
|
||||||
initializeOpenGLFunctions();
|
initializeOpenGLFunctions();
|
||||||
init();
|
init();
|
||||||
mInit = true;
|
mInit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if there were new models added that still need to be loaded.
|
||||||
|
// This is for objects added at runtime via click-and-drag events, etc.
|
||||||
while (!mModelLoadQueue.empty()) {
|
while (!mModelLoadQueue.empty()) {
|
||||||
auto modelSpec = mModelLoadQueue.front();
|
auto modelSpec = mModelLoadQueue.front();
|
||||||
// Load the model and add it to the scene.
|
// Load the model and add it to the scene.
|
||||||
@@ -80,7 +87,8 @@ void Scene::draw() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Object *> Scene::getObjects() const {
|
std::vector<Object *> Scene::getObjects() const
|
||||||
|
{
|
||||||
// All scene objects must inherit from Qtk::Object.
|
// All scene objects must inherit from Qtk::Object.
|
||||||
std::vector<Object *> objects(mMeshes.begin(), mMeshes.end());
|
std::vector<Object *> objects(mMeshes.begin(), mMeshes.end());
|
||||||
for (const auto & model : mModels) {
|
for (const auto & model : mModels) {
|
||||||
@@ -92,7 +100,8 @@ std::vector<Object *> Scene::getObjects() const {
|
|||||||
return objects;
|
return objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object * Scene::getObject(const QString & name) const {
|
Object * Scene::getObject(const QString & name) const
|
||||||
|
{
|
||||||
for (const auto & object : getObjects()) {
|
for (const auto & object : getObjects()) {
|
||||||
if (object->getName() == name.toStdString()) {
|
if (object->getName() == name.toStdString()) {
|
||||||
return object;
|
return object;
|
||||||
@@ -101,17 +110,17 @@ Object * Scene::getObject(const QString & name) const {
|
|||||||
return Q_NULLPTR;
|
return Q_NULLPTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::setSkybox(Skybox * skybox) {
|
void Scene::setSkybox(Skybox * skybox)
|
||||||
|
{
|
||||||
delete mSkybox;
|
delete mSkybox;
|
||||||
mSkybox = skybox;
|
mSkybox = skybox;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::initSceneObjectName(Object * object) {
|
void Scene::initSceneObjectName(Object * object)
|
||||||
if(!mObjectCount.count(object->getName())) {
|
{
|
||||||
mObjectCount[object->getName()] = 1;
|
mObjectCount[object->getName()] = mObjectCount.count(object->getName()) + 1;
|
||||||
} else {
|
|
||||||
mObjectCount[object->getName()]++;
|
// If the object exists make it's name unique.
|
||||||
}
|
|
||||||
auto count = mObjectCount[object->getName()];
|
auto count = mObjectCount[object->getName()];
|
||||||
if (count > 1) {
|
if (count > 1) {
|
||||||
object->setName(object->getName() + " (" + std::to_string(count) + ")");
|
object->setName(object->getName() + " (" + std::to_string(count) + ")");
|
||||||
|
|||||||
@@ -21,7 +21,8 @@
|
|||||||
#include "model.h"
|
#include "model.h"
|
||||||
#include "skybox.h"
|
#include "skybox.h"
|
||||||
|
|
||||||
namespace Qtk {
|
namespace Qtk
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* An abstract Scene class to inherit from when building new scenes.
|
* An abstract Scene class to inherit from when building new scenes.
|
||||||
*
|
*
|
||||||
@@ -43,7 +44,8 @@ namespace Qtk {
|
|||||||
* If the child scene adds any objects which are not managed (drawn) by this
|
* If the child scene adds any objects which are not managed (drawn) by this
|
||||||
* base class, the child scene class must also override the `draw()` method.
|
* base class, the child scene class must also override the `draw()` method.
|
||||||
*/
|
*/
|
||||||
class Scene : public QObject, protected QOpenGLFunctions {
|
class Scene : public QObject, protected QOpenGLFunctions
|
||||||
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -53,7 +55,7 @@ namespace Qtk {
|
|||||||
|
|
||||||
Scene();
|
Scene();
|
||||||
|
|
||||||
virtual ~Scene();
|
~Scene() override;
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Public Methods
|
* Public Methods
|
||||||
@@ -73,18 +75,23 @@ namespace Qtk {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Function called to update the QOpenGLWidget. Does not trigger a redraw.
|
* Function called to update the QOpenGLWidget. Does not trigger a redraw.
|
||||||
*
|
* This method can translate or rotate objects to simulate movement.
|
||||||
* Calling this several times will still result in only one repaint.
|
* Calling this several times will still result in only one repaint.
|
||||||
|
*
|
||||||
|
* It's very possible a client will not want to move objects in the scene
|
||||||
|
* using this method. This is intentially not pure virtual.
|
||||||
*/
|
*/
|
||||||
virtual void update() {}
|
virtual void update() {}
|
||||||
|
|
||||||
void loadModel(const QUrl & url) {
|
void loadModel(const QUrl & url)
|
||||||
|
{
|
||||||
auto fileName = url.fileName().replace(".obj", "").toStdString();
|
auto fileName = url.fileName().replace(".obj", "").toStdString();
|
||||||
auto filePath = url.toLocalFile().toStdString();
|
auto filePath = url.toLocalFile().toStdString();
|
||||||
loadModel(fileName, filePath);
|
loadModel(fileName, filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadModel(const std::string & name, const std::string & path) {
|
void loadModel(const std::string & name, const std::string & path)
|
||||||
|
{
|
||||||
// Add the dropped model to the load queue.
|
// Add the dropped model to the load queue.
|
||||||
// This is consumed during rendering of the scene if not empty.
|
// This is consumed during rendering of the scene if not empty.
|
||||||
mModelLoadQueue.emplace(name, path);
|
mModelLoadQueue.emplace(name, path);
|
||||||
@@ -111,7 +118,8 @@ namespace Qtk {
|
|||||||
/**
|
/**
|
||||||
* @return The number of objects within the scene with the given name.
|
* @return The number of objects within the scene with the given name.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] uint64_t getObjectCount(const QString & name) {
|
[[nodiscard]] uint64_t getObjectCount(const QString & name)
|
||||||
|
{
|
||||||
return mObjectCount.count(name.toStdString())
|
return mObjectCount.count(name.toStdString())
|
||||||
? mObjectCount[name.toStdString()]
|
? mObjectCount[name.toStdString()]
|
||||||
: 0;
|
: 0;
|
||||||
@@ -125,14 +133,16 @@ namespace Qtk {
|
|||||||
/**
|
/**
|
||||||
* @return View matrix for the camera attached to this scene.
|
* @return View matrix for the camera attached to this scene.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] inline static QMatrix4x4 getViewMatrix() {
|
[[nodiscard]] inline static QMatrix4x4 getViewMatrix()
|
||||||
|
{
|
||||||
return mCamera.toMatrix();
|
return mCamera.toMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Projection matrix for the current view into the scene.
|
* @return Projection matrix for the current view into the scene.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] inline static QMatrix4x4 & getProjectionMatrix() {
|
[[nodiscard]] inline static QMatrix4x4 & getProjectionMatrix()
|
||||||
|
{
|
||||||
return mProjection;
|
return mProjection;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,15 +160,16 @@ namespace Qtk {
|
|||||||
/**
|
/**
|
||||||
* @return All MeshRenderers within the scene.
|
* @return All MeshRenderers within the scene.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] inline const std::vector<MeshRenderer *> & getMeshes()
|
[[nodiscard]] inline const std::vector<MeshRenderer *> & getMeshes() const
|
||||||
const {
|
{
|
||||||
return mMeshes;
|
return mMeshes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return All Models within the scene.
|
* @return All Models within the scene.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] inline const std::vector<Model *> & getModels() const {
|
[[nodiscard]] inline const std::vector<Model *> & getModels() const
|
||||||
|
{
|
||||||
return mModels;
|
return mModels;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,30 +250,6 @@ namespace Qtk {
|
|||||||
/* Track count of objects with same initial name. */
|
/* Track count of objects with same initial name. */
|
||||||
std::unordered_map<std::string, uint64_t> mObjectCount;
|
std::unordered_map<std::string, uint64_t> mObjectCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SceneEmpty : public Scene {
|
|
||||||
public:
|
|
||||||
void init() override { setSceneName("Empty Scene"); }
|
|
||||||
|
|
||||||
void draw() override { Scene::draw(); }
|
|
||||||
|
|
||||||
void update() override { Scene::update(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class SceneInterface : public Scene {
|
|
||||||
public:
|
|
||||||
explicit SceneInterface(Scene * scene) : mScene(scene) {}
|
|
||||||
|
|
||||||
void init() override { mScene->init(); }
|
|
||||||
|
|
||||||
void draw() override { mScene->draw(); }
|
|
||||||
|
|
||||||
void update() override { mScene->update(); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Scene * mScene;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Qtk
|
} // namespace Qtk
|
||||||
|
|
||||||
#endif // QTK_SCENE_H
|
#endif // QTK_SCENE_H
|
||||||
|
|||||||
@@ -10,7 +10,8 @@
|
|||||||
|
|
||||||
using namespace Qtk;
|
using namespace Qtk;
|
||||||
|
|
||||||
Cube::Cube(DrawMode mode) {
|
Cube::Cube(DrawMode mode)
|
||||||
|
{
|
||||||
mDrawMode = mode;
|
mDrawMode = mode;
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
// The order of the following assignment values helps to visualize.
|
// The order of the following assignment values helps to visualize.
|
||||||
@@ -203,7 +204,8 @@ Cube::Cube(DrawMode mode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Triangle::Triangle(DrawMode mode) {
|
Triangle::Triangle(DrawMode mode)
|
||||||
|
{
|
||||||
mDrawMode = mode;
|
mDrawMode = mode;
|
||||||
const QVector3D triangleTop = QVector3D(0.0f, 0.5f, 0.0f);
|
const QVector3D triangleTop = QVector3D(0.0f, 0.5f, 0.0f);
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
|
|||||||
@@ -73,7 +73,8 @@
|
|||||||
#define UV_RIGHT QVector2D(0.0f, 1.0f)
|
#define UV_RIGHT QVector2D(0.0f, 1.0f)
|
||||||
#define UV_CORNER QVector2D(1.0f, 1.0f)
|
#define UV_CORNER QVector2D(1.0f, 1.0f)
|
||||||
|
|
||||||
namespace Qtk {
|
namespace Qtk
|
||||||
|
{
|
||||||
class MeshRenderer;
|
class MeshRenderer;
|
||||||
|
|
||||||
class Object;
|
class Object;
|
||||||
@@ -114,13 +115,17 @@ namespace Qtk {
|
|||||||
* @param t Texture coordinates for this shape.
|
* @param t Texture coordinates for this shape.
|
||||||
* @param n Normals for this shape.
|
* @param n Normals for this shape.
|
||||||
*/
|
*/
|
||||||
explicit ShapeBase(
|
explicit ShapeBase(DrawMode mode = QTK_DRAW_ARRAYS,
|
||||||
DrawMode mode = QTK_DRAW_ARRAYS, Vertices v = {}, Indices i = {},
|
Vertices v = {},
|
||||||
Colors c = {}, TexCoords t = {}, Normals n = {}) :
|
Indices i = {},
|
||||||
mDrawMode(mode),
|
Colors c = {},
|
||||||
mVertices(std::move(v)), mColors(std::move(c)),
|
TexCoords t = {},
|
||||||
|
Normals n = {}) :
|
||||||
|
mDrawMode(mode), mVertices(std::move(v)), mColors(std::move(c)),
|
||||||
mIndices(std::move(i)), mTexCoords(std::move(t)),
|
mIndices(std::move(i)), mTexCoords(std::move(t)),
|
||||||
mNormals(std::move(n)) {}
|
mNormals(std::move(n))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Accessors
|
* Accessors
|
||||||
@@ -129,14 +134,16 @@ namespace Qtk {
|
|||||||
/**
|
/**
|
||||||
* @return Vertex data for this shape.
|
* @return Vertex data for this shape.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] inline const Vertices & getVertices() const {
|
[[nodiscard]] inline const Vertices & getVertices() const
|
||||||
|
{
|
||||||
return mVertices;
|
return mVertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Index data for this shape.
|
* @return Index data for this shape.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] inline const Indices & getIndexData() const {
|
[[nodiscard]] inline const Indices & getIndexData() const
|
||||||
|
{
|
||||||
return mIndices;
|
return mIndices;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,21 +155,24 @@ namespace Qtk {
|
|||||||
/**
|
/**
|
||||||
* @return Texture coordinates for this shape.
|
* @return Texture coordinates for this shape.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] inline const TexCoords & getTexCoords() const {
|
[[nodiscard]] inline const TexCoords & getTexCoords() const
|
||||||
|
{
|
||||||
return mTexCoords;
|
return mTexCoords;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Normals for this shape.
|
* @return Normals for this shape.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] inline const Normals & getNormals() const {
|
[[nodiscard]] inline const Normals & getNormals() const
|
||||||
|
{
|
||||||
return mNormals;
|
return mNormals;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Stride for texture coordinates on this shape.
|
* @return Stride for texture coordinates on this shape.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] inline size_t getTexCoordsStride() const {
|
[[nodiscard]] inline size_t getTexCoordsStride() const
|
||||||
|
{
|
||||||
return mTexCoords.size() * sizeof(mTexCoords[0]);
|
return mTexCoords.size() * sizeof(mTexCoords[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,14 +214,16 @@ namespace Qtk {
|
|||||||
/**
|
/**
|
||||||
* @param value Vertex data to use for this shape.
|
* @param value Vertex data to use for this shape.
|
||||||
*/
|
*/
|
||||||
virtual inline void setVertices(const Vertices & value) {
|
virtual inline void setVertices(const Vertices & value)
|
||||||
|
{
|
||||||
mVertices = value;
|
mVertices = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param value Index data to use for this shape.
|
* @param value Index data to use for this shape.
|
||||||
*/
|
*/
|
||||||
virtual inline void setIndices(const Indices & value) {
|
virtual inline void setIndices(const Indices & value)
|
||||||
|
{
|
||||||
mIndices = value;
|
mIndices = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,14 +235,16 @@ namespace Qtk {
|
|||||||
/**
|
/**
|
||||||
* @param value Texture coordinates to use for this shape.
|
* @param value Texture coordinates to use for this shape.
|
||||||
*/
|
*/
|
||||||
virtual inline void setTexCoords(const TexCoords & value) {
|
virtual inline void setTexCoords(const TexCoords & value)
|
||||||
|
{
|
||||||
mTexCoords = value;
|
mTexCoords = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param value Normals to use for this shape.
|
* @param value Normals to use for this shape.
|
||||||
*/
|
*/
|
||||||
virtual inline void setNormals(const Normals & value) {
|
virtual inline void setNormals(const Normals & value)
|
||||||
|
{
|
||||||
mNormals = value;
|
mNormals = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,28 +17,39 @@ using namespace Qtk;
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
Skybox::Skybox(const std::string & name) :
|
Skybox::Skybox(const std::string & name) :
|
||||||
Skybox(
|
Skybox(":/textures/skybox/right.png",
|
||||||
":/textures/skybox/right.png", ":/textures/skybox/top.png",
|
":/textures/skybox/top.png",
|
||||||
":/textures/skybox/front.png", ":/textures/skybox/left.png",
|
":/textures/skybox/front.png",
|
||||||
":/textures/skybox/bottom.png", ":/textures/skybox/back.png", name) {}
|
":/textures/skybox/left.png",
|
||||||
|
":/textures/skybox/bottom.png",
|
||||||
|
":/textures/skybox/back.png",
|
||||||
|
name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Skybox::Skybox(QOpenGLTexture * cubeMap, const std::string & name) {
|
Skybox::Skybox(QOpenGLTexture * cubeMap, const std::string & name)
|
||||||
|
{
|
||||||
mTexture.setTexture(cubeMap);
|
mTexture.setTexture(cubeMap);
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
Skybox::Skybox(
|
Skybox::Skybox(const std::string & right,
|
||||||
const std::string & right, const std::string & top,
|
const std::string & top,
|
||||||
const std::string & front, const std::string & left,
|
const std::string & front,
|
||||||
const std::string & bottom, const std::string & back,
|
const std::string & left,
|
||||||
|
const std::string & bottom,
|
||||||
|
const std::string & back,
|
||||||
const std::string & name) :
|
const std::string & name) :
|
||||||
mVBO(QOpenGLBuffer::VertexBuffer),
|
mVBO(QOpenGLBuffer::VertexBuffer),
|
||||||
mVertices(Cube(QTK_DRAW_ELEMENTS).getVertices()),
|
mVertices(Cube(QTK_DRAW_ELEMENTS).getVertices()),
|
||||||
mIndices(Cube(QTK_DRAW_ELEMENTS).getIndexData()) {
|
mIndices(Cube(QTK_DRAW_ELEMENTS).getIndexData())
|
||||||
|
{
|
||||||
init();
|
init();
|
||||||
mTexture.setCubeMap(
|
mTexture.setCubeMap(QImage(right.c_str()).mirrored(),
|
||||||
QImage(right.c_str()).mirrored(), QImage(top.c_str()),
|
QImage(top.c_str()),
|
||||||
QImage(front.c_str()), QImage(left.c_str()), QImage(bottom.c_str()),
|
QImage(front.c_str()),
|
||||||
|
QImage(left.c_str()),
|
||||||
|
QImage(bottom.c_str()),
|
||||||
QImage(back.c_str()));
|
QImage(back.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +57,8 @@ Skybox::Skybox(
|
|||||||
* Public Member Functions
|
* Public Member Functions
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void Skybox::draw() {
|
void Skybox::draw()
|
||||||
|
{
|
||||||
glDepthFunc(GL_LEQUAL);
|
glDepthFunc(GL_LEQUAL);
|
||||||
glDepthMask(GL_FALSE);
|
glDepthMask(GL_FALSE);
|
||||||
|
|
||||||
@@ -73,15 +85,16 @@ void Skybox::draw() {
|
|||||||
* Private Member Functions
|
* Private Member Functions
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void Skybox::init() {
|
void Skybox::init()
|
||||||
|
{
|
||||||
initializeOpenGLFunctions();
|
initializeOpenGLFunctions();
|
||||||
|
|
||||||
// Set up shader program
|
// Set up shader program
|
||||||
mProgram.create();
|
mProgram.create();
|
||||||
mProgram.addShaderFromSourceFile(
|
mProgram.addShaderFromSourceFile(QOpenGLShader::Vertex,
|
||||||
QOpenGLShader::Vertex, ":/shaders/skybox.vert");
|
":/shaders/skybox.vert");
|
||||||
mProgram.addShaderFromSourceFile(
|
mProgram.addShaderFromSourceFile(QOpenGLShader::Fragment,
|
||||||
QOpenGLShader::Fragment, ":/shaders/skybox.frag");
|
":/shaders/skybox.frag");
|
||||||
mProgram.link();
|
mProgram.link();
|
||||||
mProgram.bind();
|
mProgram.bind();
|
||||||
|
|
||||||
|
|||||||
@@ -20,13 +20,15 @@
|
|||||||
#include "shape.h"
|
#include "shape.h"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
|
|
||||||
namespace Qtk {
|
namespace Qtk
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Skybox object for rendering a skybox within a Scene.
|
* Skybox object for rendering a skybox within a Scene.
|
||||||
* A skybox is typically implemented using a cube map texture centered around
|
* A skybox is typically implemented using a cube map texture centered around
|
||||||
* the camera and projected outwards in all directions.
|
* the camera and projected outwards in all directions.
|
||||||
*/
|
*/
|
||||||
class QTKAPI Skybox : protected QOpenGLFunctions {
|
class QTKAPI Skybox : protected QOpenGLFunctions
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Constructors / Destructors
|
* Constructors / Destructors
|
||||||
@@ -48,8 +50,8 @@ namespace Qtk {
|
|||||||
* @param cubeMap QOpenGLTexture to use for the new Skybox.
|
* @param cubeMap QOpenGLTexture to use for the new Skybox.
|
||||||
* @param name The objectName to use for the Skybox.
|
* @param name The objectName to use for the Skybox.
|
||||||
*/
|
*/
|
||||||
explicit Skybox(
|
explicit Skybox(QOpenGLTexture * cubeMap,
|
||||||
QOpenGLTexture * cubeMap, const std::string & name = "Skybox");
|
const std::string & name = "Skybox");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a Skybox.
|
* Construct a Skybox.
|
||||||
@@ -62,10 +64,12 @@ namespace Qtk {
|
|||||||
* @param back Image to use for the back side of the Skybox.
|
* @param back Image to use for the back side of the Skybox.
|
||||||
* @param name The objectName to use for this Skybox.
|
* @param name The objectName to use for this Skybox.
|
||||||
*/
|
*/
|
||||||
Skybox(
|
Skybox(const std::string & right,
|
||||||
const std::string & right, const std::string & top,
|
const std::string & top,
|
||||||
const std::string & front, const std::string & left,
|
const std::string & front,
|
||||||
const std::string & bottom, const std::string & back,
|
const std::string & left,
|
||||||
|
const std::string & bottom,
|
||||||
|
const std::string & back,
|
||||||
const std::string & name = "Skybox");
|
const std::string & name = "Skybox");
|
||||||
|
|
||||||
~Skybox() = default;
|
~Skybox() = default;
|
||||||
|
|||||||
@@ -14,8 +14,10 @@
|
|||||||
|
|
||||||
using namespace Qtk;
|
using namespace Qtk;
|
||||||
|
|
||||||
QImage OpenGLTextureFactory::initImage(
|
QImage OpenGLTextureFactory::initImage(const char * image,
|
||||||
const char * image, bool flipX, bool flipY) {
|
bool flipX,
|
||||||
|
bool flipY)
|
||||||
|
{
|
||||||
// Qt6 limits loaded images to 256MB by default
|
// Qt6 limits loaded images to 256MB by default
|
||||||
QImageReader::setAllocationLimit(1024);
|
QImageReader::setAllocationLimit(1024);
|
||||||
auto loadedImage = QImage(image).mirrored(flipX, flipY);
|
auto loadedImage = QImage(image).mirrored(flipX, flipY);
|
||||||
@@ -26,34 +28,51 @@ QImage OpenGLTextureFactory::initImage(
|
|||||||
return loadedImage;
|
return loadedImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
QOpenGLTexture * OpenGLTextureFactory::initTexture(
|
QOpenGLTexture * OpenGLTextureFactory::initTexture(const char * texture,
|
||||||
const char * texture, bool flipX, bool flipY) {
|
bool flipX,
|
||||||
|
bool flipY)
|
||||||
|
{
|
||||||
QImage image = initImage(texture, flipX, flipY);
|
QImage image = initImage(texture, flipX, flipY);
|
||||||
auto newTexture = new QOpenGLTexture(QOpenGLTexture::Target2D);
|
auto newTexture = new QOpenGLTexture(QOpenGLTexture::Target2D);
|
||||||
newTexture->setData(image);
|
newTexture->setData(image);
|
||||||
newTexture->setWrapMode(QOpenGLTexture::Repeat);
|
newTexture->setWrapMode(QOpenGLTexture::Repeat);
|
||||||
newTexture->setMinMagFilters(
|
newTexture->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear,
|
||||||
QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::Linear);
|
QOpenGLTexture::Linear);
|
||||||
return newTexture;
|
return newTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
QOpenGLTexture * OpenGLTextureFactory::initCubeMap(const char * tile) {
|
QOpenGLTexture * OpenGLTextureFactory::initCubeMap(const char * tile)
|
||||||
return initCubeMap(
|
{
|
||||||
QImage(tile), QImage(tile), QImage(tile), QImage(tile), QImage(tile),
|
return initCubeMap(QImage(tile),
|
||||||
|
QImage(tile),
|
||||||
|
QImage(tile),
|
||||||
|
QImage(tile),
|
||||||
|
QImage(tile),
|
||||||
QImage(tile));
|
QImage(tile));
|
||||||
}
|
}
|
||||||
|
|
||||||
QOpenGLTexture * OpenGLTextureFactory::initCubeMap(
|
QOpenGLTexture * OpenGLTextureFactory::initCubeMap(const char * right,
|
||||||
const char * right, const char * top, const char * front, const char * left,
|
const char * top,
|
||||||
const char * bottom, const char * back) {
|
const char * front,
|
||||||
return initCubeMap(
|
const char * left,
|
||||||
QImage(right), QImage(top), QImage(front), QImage(left), QImage(bottom),
|
const char * bottom,
|
||||||
|
const char * back)
|
||||||
|
{
|
||||||
|
return initCubeMap(QImage(right),
|
||||||
|
QImage(top),
|
||||||
|
QImage(front),
|
||||||
|
QImage(left),
|
||||||
|
QImage(bottom),
|
||||||
QImage(back));
|
QImage(back));
|
||||||
}
|
}
|
||||||
|
|
||||||
QOpenGLTexture * OpenGLTextureFactory::initCubeMap(
|
QOpenGLTexture * OpenGLTextureFactory::initCubeMap(const QImage & right,
|
||||||
const QImage & right, const QImage & top, const QImage & front,
|
const QImage & top,
|
||||||
const QImage & left, const QImage & bottom, const QImage & back) {
|
const QImage & front,
|
||||||
|
const QImage & left,
|
||||||
|
const QImage & bottom,
|
||||||
|
const QImage & back)
|
||||||
|
{
|
||||||
auto texture = new QOpenGLTexture(QOpenGLTexture::TargetCubeMap);
|
auto texture = new QOpenGLTexture(QOpenGLTexture::TargetCubeMap);
|
||||||
std::vector<QImage> faceTextures = {right, top, front, left, bottom, back};
|
std::vector<QImage> faceTextures = {right, top, front, left, bottom, back};
|
||||||
// Initialize skybox cubemap texture
|
// Initialize skybox cubemap texture
|
||||||
@@ -61,9 +80,12 @@ QOpenGLTexture * OpenGLTextureFactory::initCubeMap(
|
|||||||
texture->bind();
|
texture->bind();
|
||||||
// For each cube map face
|
// For each cube map face
|
||||||
std::vector<QOpenGLTexture::CubeMapFace> faces = {
|
std::vector<QOpenGLTexture::CubeMapFace> faces = {
|
||||||
QOpenGLTexture::CubeMapPositiveX, QOpenGLTexture::CubeMapPositiveY,
|
QOpenGLTexture::CubeMapPositiveX,
|
||||||
QOpenGLTexture::CubeMapPositiveZ, QOpenGLTexture::CubeMapNegativeX,
|
QOpenGLTexture::CubeMapPositiveY,
|
||||||
QOpenGLTexture::CubeMapNegativeY, QOpenGLTexture::CubeMapNegativeZ};
|
QOpenGLTexture::CubeMapPositiveZ,
|
||||||
|
QOpenGLTexture::CubeMapNegativeX,
|
||||||
|
QOpenGLTexture::CubeMapNegativeY,
|
||||||
|
QOpenGLTexture::CubeMapNegativeZ};
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (const auto & face : faces) {
|
for (const auto & face : faces) {
|
||||||
QImage faceImage(faceTextures[i]);
|
QImage faceImage(faceTextures[i]);
|
||||||
@@ -82,8 +104,11 @@ QOpenGLTexture * OpenGLTextureFactory::initCubeMap(
|
|||||||
texture->allocateStorage();
|
texture->allocateStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
texture->setData(
|
texture->setData(0,
|
||||||
0, 0, face, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8,
|
0,
|
||||||
|
face,
|
||||||
|
QOpenGLTexture::RGBA,
|
||||||
|
QOpenGLTexture::UInt8,
|
||||||
faceImage.constBits());
|
faceImage.constBits());
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,29 +16,32 @@
|
|||||||
|
|
||||||
#include "qtkapi.h"
|
#include "qtkapi.h"
|
||||||
|
|
||||||
namespace Qtk {
|
namespace Qtk
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Binds shader programs until the end of scope.
|
* Binds shader programs until the end of scope.
|
||||||
* Does nothing if the shader program was already bound.
|
* Does nothing if the shader program was already bound.
|
||||||
*
|
*
|
||||||
* See MeshRenderer::setUniform() for example.
|
* See MeshRenderer::setUniform() for example.
|
||||||
*/
|
*/
|
||||||
class QTKAPI ShaderBindScope {
|
class QTKAPI ShaderBindScope
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Constructors / Destructors
|
* Constructors / Destructors
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
explicit ShaderBindScope(
|
explicit ShaderBindScope(QOpenGLShaderProgram * program,
|
||||||
QOpenGLShaderProgram * program, bool was_locked) :
|
bool was_locked) : mWasBound(was_locked)
|
||||||
mWasBound(was_locked) {
|
{
|
||||||
mProgram = program;
|
mProgram = program;
|
||||||
if (!mWasBound) {
|
if (!mWasBound) {
|
||||||
mProgram->bind();
|
mProgram->bind();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~ShaderBindScope() {
|
~ShaderBindScope()
|
||||||
|
{
|
||||||
if (!mWasBound) {
|
if (!mWasBound) {
|
||||||
mProgram->release();
|
mProgram->release();
|
||||||
}
|
}
|
||||||
@@ -56,7 +59,8 @@ namespace Qtk {
|
|||||||
/**
|
/**
|
||||||
* Factories for initializing various OpenGL textures
|
* Factories for initializing various OpenGL textures
|
||||||
*/
|
*/
|
||||||
class QTKAPI OpenGLTextureFactory {
|
class QTKAPI OpenGLTextureFactory
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Constructors / Destructors
|
* Constructors / Destructors
|
||||||
@@ -76,8 +80,9 @@ namespace Qtk {
|
|||||||
* @param flipY If true the image will be flipped on Y axis.
|
* @param flipY If true the image will be flipped on Y axis.
|
||||||
* @return QImage object.
|
* @return QImage object.
|
||||||
*/
|
*/
|
||||||
static QImage initImage(
|
static QImage initImage(const char * image,
|
||||||
const char * image, bool flipX = false, bool flipY = false);
|
bool flipX = false,
|
||||||
|
bool flipY = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* QOpenGLTexture factory
|
* QOpenGLTexture factory
|
||||||
@@ -88,8 +93,9 @@ namespace Qtk {
|
|||||||
* @param flipY If true the image will be flipped on Y axis.
|
* @param flipY If true the image will be flipped on Y axis.
|
||||||
* @return Pointer to an initialized QOpenGLTexture object.
|
* @return Pointer to an initialized QOpenGLTexture object.
|
||||||
*/
|
*/
|
||||||
static QOpenGLTexture * initTexture(
|
static QOpenGLTexture * initTexture(const char * texture,
|
||||||
const char * texture, bool flipX = false, bool flipY = false);
|
bool flipX = false,
|
||||||
|
bool flipY = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cube map factory for initializing all sides of a CubeMap.
|
* Cube map factory for initializing all sides of a CubeMap.
|
||||||
@@ -103,9 +109,12 @@ namespace Qtk {
|
|||||||
* @param back Path to image for the back side of the CubeMap.
|
* @param back Path to image for the back side of the CubeMap.
|
||||||
* @return Pointer to an initialized QOpenGLTexture object.
|
* @return Pointer to an initialized QOpenGLTexture object.
|
||||||
*/
|
*/
|
||||||
static QOpenGLTexture * initCubeMap(
|
static QOpenGLTexture * initCubeMap(const QImage & right,
|
||||||
const QImage & right, const QImage & top, const QImage & front,
|
const QImage & top,
|
||||||
const QImage & left, const QImage & bottom, const QImage & back);
|
const QImage & front,
|
||||||
|
const QImage & left,
|
||||||
|
const QImage & bottom,
|
||||||
|
const QImage & back);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CubeMap factory for tiling the same image on all sides.
|
* CubeMap factory for tiling the same image on all sides.
|
||||||
@@ -128,12 +137,16 @@ namespace Qtk {
|
|||||||
* @param back Path to image for the back side of the CubeMap.
|
* @param back Path to image for the back side of the CubeMap.
|
||||||
* @return Pointer to an initialized QOpenGLTexture object.
|
* @return Pointer to an initialized QOpenGLTexture object.
|
||||||
*/
|
*/
|
||||||
static QOpenGLTexture * initCubeMap(
|
static QOpenGLTexture * initCubeMap(const char * right,
|
||||||
const char * right, const char * top, const char * front,
|
const char * top,
|
||||||
const char * left, const char * bottom, const char * back);
|
const char * front,
|
||||||
|
const char * left,
|
||||||
|
const char * bottom,
|
||||||
|
const char * back);
|
||||||
|
|
||||||
/// The texture used in place of a missing texture.
|
/// The texture used in place of a missing texture.
|
||||||
static QImage defaultTexture() {
|
static QImage defaultTexture()
|
||||||
|
{
|
||||||
// Use plaster for default texture if image fails to load.
|
// Use plaster for default texture if image fails to load.
|
||||||
// This prevents segfaults when loading a texture that doesn't exist.
|
// This prevents segfaults when loading a texture that doesn't exist.
|
||||||
// TODO: Replace with a '?' texture to indicate missing texture.
|
// TODO: Replace with a '?' texture to indicate missing texture.
|
||||||
@@ -151,7 +164,8 @@ namespace Qtk {
|
|||||||
* TODO: Struct for (re)storing texture state
|
* TODO: Struct for (re)storing texture state
|
||||||
* A struct to store flipX, flipY and other initial state needed to copy
|
* A struct to store flipX, flipY and other initial state needed to copy
|
||||||
*/
|
*/
|
||||||
class Texture {
|
class Texture
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Typedefs
|
* Typedefs
|
||||||
@@ -169,7 +183,8 @@ namespace Qtk {
|
|||||||
*
|
*
|
||||||
* @param value Texture to copy.
|
* @param value Texture to copy.
|
||||||
*/
|
*/
|
||||||
Texture(const Texture & value) {
|
Texture(const Texture & value)
|
||||||
|
{
|
||||||
mOpenGLTexture = OpenGLTextureFactory::initTexture(value.mPath);
|
mOpenGLTexture = OpenGLTextureFactory::initTexture(value.mPath);
|
||||||
mPath = value.mPath;
|
mPath = value.mPath;
|
||||||
}
|
}
|
||||||
@@ -179,10 +194,13 @@ namespace Qtk {
|
|||||||
* @param flipX True if texture is to be flipped on the X axis.
|
* @param flipX True if texture is to be flipped on the X axis.
|
||||||
* @param flipY True if texture is to be flipped on the Y axis.
|
* @param flipY True if texture is to be flipped on the Y axis.
|
||||||
*/
|
*/
|
||||||
explicit Texture(
|
explicit Texture(const char * path,
|
||||||
const char * path, bool flipX = false, bool flipY = false) :
|
bool flipX = false,
|
||||||
|
bool flipY = false) :
|
||||||
mOpenGLTexture(OpenGLTextureFactory::initTexture(path, flipX, flipY)),
|
mOpenGLTexture(OpenGLTextureFactory::initTexture(path, flipX, flipY)),
|
||||||
mPath(path) {}
|
mPath(path)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a Texture using an existing QOpenGLTexture.
|
* Construct a Texture using an existing QOpenGLTexture.
|
||||||
@@ -200,7 +218,8 @@ namespace Qtk {
|
|||||||
/**
|
/**
|
||||||
* @return True if the OpenGL texture has been initialized.
|
* @return True if the OpenGL texture has been initialized.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] inline bool hasTexture() const {
|
[[nodiscard]] inline bool hasTexture() const
|
||||||
|
{
|
||||||
return mOpenGLTexture != Q_NULLPTR;
|
return mOpenGLTexture != Q_NULLPTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,7 +230,8 @@ namespace Qtk {
|
|||||||
/**
|
/**
|
||||||
* @return QOpenGLTexture associated with this Texture.
|
* @return QOpenGLTexture associated with this Texture.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] inline QOpenGLTexture & getOpenGLTexture() const {
|
[[nodiscard]] inline QOpenGLTexture & getOpenGLTexture() const
|
||||||
|
{
|
||||||
return *mOpenGLTexture;
|
return *mOpenGLTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,8 +251,10 @@ namespace Qtk {
|
|||||||
* @param flipX True if texture is to be flipped on the X axis.
|
* @param flipX True if texture is to be flipped on the X axis.
|
||||||
* @param flipY True if texture is to be flipped on the Y axis.
|
* @param flipY True if texture is to be flipped on the Y axis.
|
||||||
*/
|
*/
|
||||||
inline void setTexture(
|
inline void setTexture(const std::string & path,
|
||||||
const std::string & path, bool flipX = false, bool flipY = false) {
|
bool flipX = false,
|
||||||
|
bool flipY = false)
|
||||||
|
{
|
||||||
setTexture(path.c_str(), flipX, flipY);
|
setTexture(path.c_str(), flipX, flipY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,8 +263,10 @@ namespace Qtk {
|
|||||||
* @param flipX True if texture is to be flipped on the X axis.
|
* @param flipX True if texture is to be flipped on the X axis.
|
||||||
* @param flipY True if texture is to be flipped on the Y axis.
|
* @param flipY True if texture is to be flipped on the Y axis.
|
||||||
*/
|
*/
|
||||||
inline void setTexture(
|
inline void setTexture(const char * path,
|
||||||
const char * path, bool flipX = false, bool flipY = false) {
|
bool flipX = false,
|
||||||
|
bool flipY = false)
|
||||||
|
{
|
||||||
mOpenGLTexture = OpenGLTextureFactory::initTexture(path, flipX, flipY);
|
mOpenGLTexture = OpenGLTextureFactory::initTexture(path, flipX, flipY);
|
||||||
mPath = path;
|
mPath = path;
|
||||||
}
|
}
|
||||||
@@ -252,7 +276,8 @@ namespace Qtk {
|
|||||||
*
|
*
|
||||||
* @param path Path to texture to use for all sides of the cube map.
|
* @param path Path to texture to use for all sides of the cube map.
|
||||||
*/
|
*/
|
||||||
virtual inline void setCubeMap(const char * path) {
|
virtual inline void setCubeMap(const char * path)
|
||||||
|
{
|
||||||
mOpenGLTexture = OpenGLTextureFactory::initCubeMap(path);
|
mOpenGLTexture = OpenGLTextureFactory::initCubeMap(path);
|
||||||
mPath = path;
|
mPath = path;
|
||||||
}
|
}
|
||||||
@@ -267,9 +292,13 @@ namespace Qtk {
|
|||||||
* @param bottom Path to texture to use for bottom cube map side.
|
* @param bottom Path to texture to use for bottom cube map side.
|
||||||
* @param back Path to texture to use for back cube map side.
|
* @param back Path to texture to use for back cube map side.
|
||||||
*/
|
*/
|
||||||
virtual inline void setCubeMap(
|
virtual inline void setCubeMap(const char * right,
|
||||||
const char * right, const char * top, const char * front,
|
const char * top,
|
||||||
const char * left, const char * bottom, const char * back) {
|
const char * front,
|
||||||
|
const char * left,
|
||||||
|
const char * bottom,
|
||||||
|
const char * back)
|
||||||
|
{
|
||||||
mOpenGLTexture = OpenGLTextureFactory::initCubeMap(
|
mOpenGLTexture = OpenGLTextureFactory::initCubeMap(
|
||||||
right, top, front, left, bottom, back);
|
right, top, front, left, bottom, back);
|
||||||
}
|
}
|
||||||
@@ -284,9 +313,13 @@ namespace Qtk {
|
|||||||
* @param bottom Path to texture to use for bottom cube map side.
|
* @param bottom Path to texture to use for bottom cube map side.
|
||||||
* @param back Path to texture to use for back cube map side.
|
* @param back Path to texture to use for back cube map side.
|
||||||
*/
|
*/
|
||||||
virtual inline void setCubeMap(
|
virtual inline void setCubeMap(const QImage & right,
|
||||||
const QImage & right, const QImage & top, const QImage & front,
|
const QImage & top,
|
||||||
const QImage & left, const QImage & bottom, const QImage & back) {
|
const QImage & front,
|
||||||
|
const QImage & left,
|
||||||
|
const QImage & bottom,
|
||||||
|
const QImage & back)
|
||||||
|
{
|
||||||
mOpenGLTexture = OpenGLTextureFactory::initCubeMap(
|
mOpenGLTexture = OpenGLTextureFactory::initCubeMap(
|
||||||
right, top, front, left, bottom, back);
|
right, top, front, left, bottom, back);
|
||||||
}
|
}
|
||||||
@@ -299,7 +332,8 @@ namespace Qtk {
|
|||||||
/**
|
/**
|
||||||
* @param texture QOpenGLTexture to use for this Texture.
|
* @param texture QOpenGLTexture to use for this Texture.
|
||||||
*/
|
*/
|
||||||
inline void setTexture(QOpenGLTexture * texture) {
|
inline void setTexture(QOpenGLTexture * texture)
|
||||||
|
{
|
||||||
mOpenGLTexture = texture;
|
mOpenGLTexture = texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,43 +19,51 @@ const QVector3D Transform3D::LocalRight(1.0f, 0.0f, 0.0f);
|
|||||||
* Public Methods
|
* Public Methods
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void Transform3D::translate(const QVector3D & dt) {
|
void Transform3D::translate(const QVector3D & dt)
|
||||||
|
{
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
mTranslation += dt;
|
mTranslation += dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transform3D::scale(const QVector3D & ds) {
|
void Transform3D::scale(const QVector3D & ds)
|
||||||
|
{
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
mScale *= ds;
|
mScale *= ds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Transform3D::grow(const QVector3D & ds) {
|
void Transform3D::grow(const QVector3D & ds)
|
||||||
|
{
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
mScale += ds;
|
mScale += ds;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transform3D::rotate(const QQuaternion & dr) {
|
void Transform3D::rotate(const QQuaternion & dr)
|
||||||
|
{
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
mRotation = dr * mRotation;
|
mRotation = dr * mRotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transform3D::setTranslation(const QVector3D & t) {
|
void Transform3D::setTranslation(const QVector3D & t)
|
||||||
|
{
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
mTranslation = t;
|
mTranslation = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transform3D::setScale(const QVector3D & s) {
|
void Transform3D::setScale(const QVector3D & s)
|
||||||
|
{
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
mScale = s;
|
mScale = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transform3D::setRotation(const QQuaternion & r) {
|
void Transform3D::setRotation(const QQuaternion & r)
|
||||||
|
{
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
mRotation = r;
|
mRotation = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QMatrix4x4 & Transform3D::toMatrix() {
|
const QMatrix4x4 & Transform3D::toMatrix()
|
||||||
|
{
|
||||||
if (m_dirty) {
|
if (m_dirty) {
|
||||||
m_dirty = false;
|
m_dirty = false;
|
||||||
mWorld.setToIdentity();
|
mWorld.setToIdentity();
|
||||||
@@ -66,15 +74,18 @@ const QMatrix4x4 & Transform3D::toMatrix() {
|
|||||||
return mWorld;
|
return mWorld;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector3D Transform3D::getForward() const {
|
QVector3D Transform3D::getForward() const
|
||||||
|
{
|
||||||
return mRotation.rotatedVector(LocalForward);
|
return mRotation.rotatedVector(LocalForward);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector3D Transform3D::getUp() const {
|
QVector3D Transform3D::getUp() const
|
||||||
|
{
|
||||||
return mRotation.rotatedVector(LocalUp);
|
return mRotation.rotatedVector(LocalUp);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector3D Transform3D::getRight() const {
|
QVector3D Transform3D::getRight() const
|
||||||
|
{
|
||||||
return mRotation.rotatedVector(LocalRight);
|
return mRotation.rotatedVector(LocalRight);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,10 +93,12 @@ QVector3D Transform3D::getRight() const {
|
|||||||
* Private Methods
|
* Private Methods
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
namespace Qtk {
|
namespace Qtk
|
||||||
|
{
|
||||||
#ifndef QT_NO_DEBUG_STREAM
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
|
|
||||||
QDebug operator<<(QDebug dbg, const Transform3D & transform) {
|
QDebug operator<<(QDebug dbg, const Transform3D & transform)
|
||||||
|
{
|
||||||
dbg << "Transform3D\n{\n";
|
dbg << "Transform3D\n{\n";
|
||||||
dbg << "Position: <" << transform.getTranslation().x() << ", "
|
dbg << "Position: <" << transform.getTranslation().x() << ", "
|
||||||
<< transform.getTranslation().y() << ", "
|
<< transform.getTranslation().y() << ", "
|
||||||
@@ -102,14 +115,16 @@ namespace Qtk {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef QT_NO_DATASTREAM
|
#ifndef QT_NO_DATASTREAM
|
||||||
QDataStream & operator<<(QDataStream & out, const Transform3D & transform) {
|
QDataStream & operator<<(QDataStream & out, const Transform3D & transform)
|
||||||
|
{
|
||||||
out << transform.mTranslation;
|
out << transform.mTranslation;
|
||||||
out << transform.mScale;
|
out << transform.mScale;
|
||||||
out << transform.mRotation;
|
out << transform.mRotation;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDataStream & operator>>(QDataStream & in, Transform3D & transform) {
|
QDataStream & operator>>(QDataStream & in, Transform3D & transform)
|
||||||
|
{
|
||||||
in >> transform.mTranslation;
|
in >> transform.mTranslation;
|
||||||
in >> transform.mScale;
|
in >> transform.mScale;
|
||||||
in >> transform.mRotation;
|
in >> transform.mRotation;
|
||||||
|
|||||||
@@ -20,11 +20,13 @@
|
|||||||
|
|
||||||
#include "qtkapi.h"
|
#include "qtkapi.h"
|
||||||
|
|
||||||
namespace Qtk {
|
namespace Qtk
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Transform3D class to represent and modify object position in 3D space.
|
* Transform3D class to represent and modify object position in 3D space.
|
||||||
*/
|
*/
|
||||||
class QTKAPI Transform3D {
|
class QTKAPI Transform3D
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Constructors, Destructors
|
* Constructors, Destructors
|
||||||
@@ -32,7 +34,9 @@ namespace Qtk {
|
|||||||
|
|
||||||
inline Transform3D() :
|
inline Transform3D() :
|
||||||
m_dirty(true), mScale(1.0f, 1.0f, 1.0f),
|
m_dirty(true), mScale(1.0f, 1.0f, 1.0f),
|
||||||
mTranslation(0.0f, 0.0f, 0.0f) {}
|
mTranslation(0.0f, 0.0f, 0.0f)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Public Methods
|
* Public Methods
|
||||||
@@ -48,7 +52,8 @@ namespace Qtk {
|
|||||||
* @param dy Y translation from last to current position.
|
* @param dy Y translation from last to current position.
|
||||||
* @param dz Z translation from last to current position.
|
* @param dz Z translation from last to current position.
|
||||||
*/
|
*/
|
||||||
inline void translate(float dx, float dy, float dz) {
|
inline void translate(float dx, float dy, float dz)
|
||||||
|
{
|
||||||
translate(QVector3D(dx, dy, dz));
|
translate(QVector3D(dx, dy, dz));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +71,8 @@ namespace Qtk {
|
|||||||
* @param dy Amount to scale on the Y axis.
|
* @param dy Amount to scale on the Y axis.
|
||||||
* @param dz Amount to scale on the Z axis.
|
* @param dz Amount to scale on the Z axis.
|
||||||
*/
|
*/
|
||||||
inline void scale(float dx, float dy, float dz) {
|
inline void scale(float dx, float dy, float dz)
|
||||||
|
{
|
||||||
scale(QVector3D(dx, dy, dz));
|
scale(QVector3D(dx, dy, dz));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +81,8 @@ namespace Qtk {
|
|||||||
*
|
*
|
||||||
* @param factor Scalar to apply to all axis of the object.
|
* @param factor Scalar to apply to all axis of the object.
|
||||||
*/
|
*/
|
||||||
inline void scale(float factor) {
|
inline void scale(float factor)
|
||||||
|
{
|
||||||
scale(QVector3D(factor, factor, factor));
|
scale(QVector3D(factor, factor, factor));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,14 +96,16 @@ namespace Qtk {
|
|||||||
* @param dy Amount to grow Y axis.
|
* @param dy Amount to grow Y axis.
|
||||||
* @param dz Amount to grow Z axis.
|
* @param dz Amount to grow Z axis.
|
||||||
*/
|
*/
|
||||||
inline void grow(float dx, float dy, float dz) {
|
inline void grow(float dx, float dy, float dz)
|
||||||
|
{
|
||||||
grow(QVector3D(dx, dy, dz));
|
grow(QVector3D(dx, dy, dz));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param factor Amount to grow all axis equally.
|
* @param factor Amount to grow all axis equally.
|
||||||
*/
|
*/
|
||||||
inline void grow(float factor) {
|
inline void grow(float factor)
|
||||||
|
{
|
||||||
grow(QVector3D(factor, factor, factor));
|
grow(QVector3D(factor, factor, factor));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,7 +118,8 @@ namespace Qtk {
|
|||||||
* @param angle Angle to rotate.
|
* @param angle Angle to rotate.
|
||||||
* @param axis Axis to rotate apply the rotation on.
|
* @param axis Axis to rotate apply the rotation on.
|
||||||
*/
|
*/
|
||||||
inline void rotate(float angle, const QVector3D & axis) {
|
inline void rotate(float angle, const QVector3D & axis)
|
||||||
|
{
|
||||||
rotate(QQuaternion::fromAxisAndAngle(axis, angle));
|
rotate(QQuaternion::fromAxisAndAngle(axis, angle));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +131,8 @@ namespace Qtk {
|
|||||||
* @param ay Y axis to apply the rotation on.
|
* @param ay Y axis to apply the rotation on.
|
||||||
* @param az Z axis to apply the rotation on.
|
* @param az Z axis to apply the rotation on.
|
||||||
*/
|
*/
|
||||||
inline void rotate(float angle, float ax, float ay, float az) {
|
inline void rotate(float angle, float ax, float ay, float az)
|
||||||
|
{
|
||||||
rotate(QQuaternion::fromAxisAndAngle(ax, ay, az, angle));
|
rotate(QQuaternion::fromAxisAndAngle(ax, ay, az, angle));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,7 +150,8 @@ namespace Qtk {
|
|||||||
* @param y Y position to set transform.
|
* @param y Y position to set transform.
|
||||||
* @param z Z position to set transform.
|
* @param z Z position to set transform.
|
||||||
*/
|
*/
|
||||||
inline void setTranslation(float x, float y, float z) {
|
inline void setTranslation(float x, float y, float z)
|
||||||
|
{
|
||||||
setTranslation(QVector3D(x, y, z));
|
setTranslation(QVector3D(x, y, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +165,8 @@ namespace Qtk {
|
|||||||
* @param y Y axis scale to set for this transform.
|
* @param y Y axis scale to set for this transform.
|
||||||
* @param z Z axis scale to set for this transform.
|
* @param z Z axis scale to set for this transform.
|
||||||
*/
|
*/
|
||||||
inline void setScale(float x, float y, float z) {
|
inline void setScale(float x, float y, float z)
|
||||||
|
{
|
||||||
setScale(QVector3D(x, y, z));
|
setScale(QVector3D(x, y, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,7 +184,8 @@ namespace Qtk {
|
|||||||
* @param angle Angle to set for rotation.
|
* @param angle Angle to set for rotation.
|
||||||
* @param axis Axis to set rotation for.
|
* @param axis Axis to set rotation for.
|
||||||
*/
|
*/
|
||||||
inline void setRotation(float angle, const QVector3D & axis) {
|
inline void setRotation(float angle, const QVector3D & axis)
|
||||||
|
{
|
||||||
setRotation(QQuaternion::fromAxisAndAngle(axis, angle));
|
setRotation(QQuaternion::fromAxisAndAngle(axis, angle));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +197,8 @@ namespace Qtk {
|
|||||||
* @param ay Y axis to set angle for.
|
* @param ay Y axis to set angle for.
|
||||||
* @param az Z axis to set angle for.
|
* @param az Z axis to set angle for.
|
||||||
*/
|
*/
|
||||||
inline void setRotation(float angle, float ax, float ay, float az) {
|
inline void setRotation(float angle, float ax, float ay, float az)
|
||||||
|
{
|
||||||
setRotation(QQuaternion::fromAxisAndAngle(ax, ay, az, angle));
|
setRotation(QQuaternion::fromAxisAndAngle(ax, ay, az, angle));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,7 +209,8 @@ namespace Qtk {
|
|||||||
/**
|
/**
|
||||||
* @return Translation for this transform.
|
* @return Translation for this transform.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] inline const QVector3D & getTranslation() const {
|
[[nodiscard]] inline const QVector3D & getTranslation() const
|
||||||
|
{
|
||||||
return mTranslation;
|
return mTranslation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,7 +222,8 @@ namespace Qtk {
|
|||||||
/**
|
/**
|
||||||
* @return Rotation for this transform.
|
* @return Rotation for this transform.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] inline const QQuaternion & getRotation() const {
|
[[nodiscard]] inline const QQuaternion & getRotation() const
|
||||||
|
{
|
||||||
return mRotation;
|
return mRotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,10 +267,10 @@ namespace Qtk {
|
|||||||
bool m_dirty;
|
bool m_dirty;
|
||||||
|
|
||||||
#ifndef QT_NO_DATASTREAM
|
#ifndef QT_NO_DATASTREAM
|
||||||
friend QDataStream & operator<<(
|
friend QDataStream & operator<<(QDataStream & out,
|
||||||
QDataStream & out, const Transform3D & transform);
|
const Transform3D & transform);
|
||||||
friend QDataStream & operator>>(
|
friend QDataStream & operator>>(QDataStream & in,
|
||||||
QDataStream & in, Transform3D & transform);
|
Transform3D & transform);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
1
tools/build-qt.sh
Normal file
@@ -0,0 +1 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
15
tools/format.sh
Executable file
@@ -0,0 +1,15 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Helper script to run clang-tidy and clang-format.
|
||||||
|
# This should be executed from the root of the repository:
|
||||||
|
#
|
||||||
|
# git clone https://git.shaunreed.com/shaunrd0/qtk
|
||||||
|
# cd qtk
|
||||||
|
# ./tools/format.sh
|
||||||
|
|
||||||
|
# Configure and build qtk
|
||||||
|
cmake -B build && cmake --build build -- -j $(nproc --ignore=1)
|
||||||
|
|
||||||
|
# Run clang-tidy and clang-format
|
||||||
|
SOURCES="src/**/*.cpp src/**/*.h example-app/*.cpp example-app/*.h"
|
||||||
|
clang-tidy -p build/ --fix --config-file=.clang-tidy $SOURCES
|
||||||
|
clang-format -i --style=file:.clang-format $SOURCES
|
||||||