Compare commits

..

22 Commits

Author SHA1 Message Date
3dfda41c46 LineArt: Remove custom camera options as this patch doesn't include this function. 2021-06-15 21:43:16 +08:00
fad1d746c8 LineArt: Respect cache override limits. 2021-06-15 21:36:23 +08:00
27f38bae5e LineArt: cache ui changes. 2021-06-15 18:19:40 +08:00
5fe915d141 Merge remote-tracking branch 'origin/master' into lineart-fn-cached 2021-06-15 13:11:56 +08:00
089ea73abf LineArt: restore modifier cache code 2021-06-15 00:56:47 +08:00
0203b35272 LineArt: Only get limits for cached modifiers. 2021-06-15 00:42:57 +08:00
9870984c79 LineArt: Fix stroke baking crash. 2021-06-15 00:24:15 +08:00
59e82df127 LineArt: clean up 2021-06-14 21:55:30 +08:00
e3e8227b19 Merge remote-tracking branch 'origin/master' into lineart-fn-cached 2021-06-14 21:41:13 +08:00
4e84a49218 Lineart: Clean up cache patch. 2021-06-14 20:56:09 +08:00
f9568c4c1f Merge remote-tracking branch 'origin/master' into lineart-fn-cached 2021-06-14 19:49:30 +08:00
02d1a1bfcc Merge remote-tracking branch 'origin/master' into lineart-fn-cached 2021-05-27 20:22:52 +08:00
fc6a6d3a28 Cleanup: Line art variable naming.
Change `reln` to `eln`.

Reviewed By: Sebastian Parborg (zeddb)

Differential Revision: https://developer.blender.org/D11411
2021-05-27 20:05:55 +08:00
fe9ab6281d LineArt: Cleaning up edge list names. 2021-05-27 20:05:10 +08:00
862f86e3b3 Cleanup: Line art naming changes.
Make variable naming consistent with struct names.

Reviewed By: Sebastian Parborg (zeddb)

Differential Revision: https://developer.blender.org/D11382
2021-05-27 20:01:43 +08:00
e6d1424f21 Lineart: Cache toggle for baking operators. 2021-05-18 22:16:54 +08:00
7c979ad568 LineArt: UI grey out for cache mode. 2021-05-18 22:16:39 +08:00
e06e13a56e LineArt: Global overrides for cached calculation. 2021-05-18 22:15:41 +08:00
4cdb056036 LineArt: Fix cache allocation error. 2021-05-18 22:15:34 +08:00
13861121b1 LineArt: Fix cache nullptr bug. 2021-05-18 22:15:26 +08:00
62ca6d46d3 LineArt: Modifier stack cache wip 2021-05-18 22:15:19 +08:00
c224ca3689 LineArt: Use separate memory pool for chained data. 2021-05-18 22:14:53 +08:00
1437 changed files with 10265 additions and 22762 deletions

View File

@@ -265,5 +265,4 @@ ForEachMacros:
- VECTOR_SET_SLOT_PROBING_BEGIN - VECTOR_SET_SLOT_PROBING_BEGIN
StatementMacros: StatementMacros:
- PyObject_HEAD
- PyObject_VAR_HEAD - PyObject_VAR_HEAD

View File

@@ -836,7 +836,7 @@ if(WITH_PYTHON)
# because UNIX will search for the old Python paths which may not exist. # because UNIX will search for the old Python paths which may not exist.
# giving errors about missing paths before this case is met. # giving errors about missing paths before this case is met.
if(DEFINED PYTHON_VERSION AND "${PYTHON_VERSION}" VERSION_LESS "3.9") if(DEFINED PYTHON_VERSION AND "${PYTHON_VERSION}" VERSION_LESS "3.9")
message(FATAL_ERROR "At least Python 3.9 is required to build, but found Python ${PYTHON_VERSION}") message(FATAL_ERROR "At least Python 3.9 is required to build")
endif() endif()
file(GLOB RESULT "${CMAKE_SOURCE_DIR}/release/scripts/addons") file(GLOB RESULT "${CMAKE_SOURCE_DIR}/release/scripts/addons")

View File

@@ -472,7 +472,8 @@ if(NOT GFLAGS_FOUND)
gflags_report_not_found( gflags_report_not_found(
"Could not find gflags include directory, set GFLAGS_INCLUDE_DIR " "Could not find gflags include directory, set GFLAGS_INCLUDE_DIR "
"to directory containing gflags/gflags.h") "to directory containing gflags/gflags.h")
endif() endif(NOT GFLAGS_INCLUDE_DIR OR
NOT EXISTS ${GFLAGS_INCLUDE_DIR})
find_library(GFLAGS_LIBRARY NAMES gflags find_library(GFLAGS_LIBRARY NAMES gflags
PATHS ${GFLAGS_LIBRARY_DIR_HINTS} PATHS ${GFLAGS_LIBRARY_DIR_HINTS}
@@ -483,7 +484,8 @@ if(NOT GFLAGS_FOUND)
gflags_report_not_found( gflags_report_not_found(
"Could not find gflags library, set GFLAGS_LIBRARY " "Could not find gflags library, set GFLAGS_LIBRARY "
"to full path to libgflags.") "to full path to libgflags.")
endif() endif(NOT GFLAGS_LIBRARY OR
NOT EXISTS ${GFLAGS_LIBRARY})
# gflags typically requires a threading library (which is OS dependent), note # gflags typically requires a threading library (which is OS dependent), note
# that this defines the CMAKE_THREAD_LIBS_INIT variable. If we are able to # that this defines the CMAKE_THREAD_LIBS_INIT variable. If we are able to
@@ -558,7 +560,8 @@ if(NOT GFLAGS_FOUND)
gflags_report_not_found( gflags_report_not_found(
"Caller defined GFLAGS_INCLUDE_DIR:" "Caller defined GFLAGS_INCLUDE_DIR:"
" ${GFLAGS_INCLUDE_DIR} does not contain gflags/gflags.h header.") " ${GFLAGS_INCLUDE_DIR} does not contain gflags/gflags.h header.")
endif() endif(GFLAGS_INCLUDE_DIR AND
NOT EXISTS ${GFLAGS_INCLUDE_DIR}/gflags/gflags.h)
# TODO: This regex for gflags library is pretty primitive, we use lowercase # TODO: This regex for gflags library is pretty primitive, we use lowercase
# for comparison to handle Windows using CamelCase library names, could # for comparison to handle Windows using CamelCase library names, could
# this check be better? # this check be better?
@@ -568,7 +571,8 @@ if(NOT GFLAGS_FOUND)
gflags_report_not_found( gflags_report_not_found(
"Caller defined GFLAGS_LIBRARY: " "Caller defined GFLAGS_LIBRARY: "
"${GFLAGS_LIBRARY} does not match gflags.") "${GFLAGS_LIBRARY} does not match gflags.")
endif() endif(GFLAGS_LIBRARY AND
NOT "${LOWERCASE_GFLAGS_LIBRARY}" MATCHES ".*gflags[^/]*")
gflags_reset_find_library_prefix() gflags_reset_find_library_prefix()

View File

@@ -40,7 +40,7 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(NanoVDB DEFAULT_MSG
IF(NANOVDB_FOUND) IF(NANOVDB_FOUND)
SET(NANOVDB_INCLUDE_DIRS ${NANOVDB_INCLUDE_DIR}) SET(NANOVDB_INCLUDE_DIRS ${NANOVDB_INCLUDE_DIR})
ENDIF() ENDIF(NANOVDB_FOUND)
MARK_AS_ADVANCED( MARK_AS_ADVANCED(
NANOVDB_INCLUDE_DIR NANOVDB_INCLUDE_DIR

View File

@@ -46,7 +46,7 @@ SET(_opencollada_FIND_COMPONENTS
) )
# Fedora openCOLLADA package links these statically # Fedora openCOLLADA package links these statically
# note that order is important here or it won't link # note that order is important here ot it wont link
SET(_opencollada_FIND_STATIC_COMPONENTS SET(_opencollada_FIND_STATIC_COMPONENTS
buffer buffer
ftoa ftoa

View File

@@ -44,7 +44,7 @@ SET(PYTHON_LINKFLAGS "-Xlinker -export-dynamic" CACHE STRING "Linker flags for p
MARK_AS_ADVANCED(PYTHON_LINKFLAGS) MARK_AS_ADVANCED(PYTHON_LINKFLAGS)
# if the user passes these defines as args, we don't want to overwrite # if the user passes these defines as args, we dont want to overwrite
SET(_IS_INC_DEF OFF) SET(_IS_INC_DEF OFF)
SET(_IS_INC_CONF_DEF OFF) SET(_IS_INC_CONF_DEF OFF)
SET(_IS_LIB_DEF OFF) SET(_IS_LIB_DEF OFF)
@@ -143,7 +143,7 @@ IF((NOT _IS_INC_DEF) OR (NOT _IS_INC_CONF_DEF) OR (NOT _IS_LIB_DEF) OR (NOT _IS_
SET(_PYTHON_ABI_FLAGS "${_CURRENT_ABI_FLAGS}") SET(_PYTHON_ABI_FLAGS "${_CURRENT_ABI_FLAGS}")
break() break()
ELSE() ELSE()
# ensure we don't find values from 2 different ABI versions # ensure we dont find values from 2 different ABI versions
IF(NOT _IS_INC_DEF) IF(NOT _IS_INC_DEF)
UNSET(PYTHON_INCLUDE_DIR CACHE) UNSET(PYTHON_INCLUDE_DIR CACHE)
ENDIF() ENDIF()

View File

@@ -40,7 +40,7 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(sse2neon DEFAULT_MSG
IF(SSE2NEON_FOUND) IF(SSE2NEON_FOUND)
SET(SSE2NEON_INCLUDE_DIRS ${SSE2NEON_INCLUDE_DIR}) SET(SSE2NEON_INCLUDE_DIRS ${SSE2NEON_INCLUDE_DIR})
ENDIF() ENDIF(SSE2NEON_FOUND)
MARK_AS_ADVANCED( MARK_AS_ADVANCED(
SSE2NEON_INCLUDE_DIR SSE2NEON_INCLUDE_DIR

View File

@@ -305,7 +305,7 @@ def file_check_arg_sizes(tu):
for i, node_child in enumerate(children): for i, node_child in enumerate(children):
children = list(node_child.get_children()) children = list(node_child.get_children())
# skip if we don't have an index... # skip if we dont have an index...
size_def = args_size_definition.get(i, -1) size_def = args_size_definition.get(i, -1)
if size_def == -1: if size_def == -1:
@@ -354,7 +354,7 @@ def file_check_arg_sizes(tu):
filepath # always the same but useful when running threaded filepath # always the same but useful when running threaded
)) ))
# we don't really care what we are looking at, just scan entire file for # we dont really care what we are looking at, just scan entire file for
# function calls. # function calls.
def recursive_func_call_check(node): def recursive_func_call_check(node):

View File

@@ -694,7 +694,7 @@ macro(message_first_run)
endmacro() endmacro()
# when we have warnings as errors applied globally this # when we have warnings as errors applied globally this
# needs to be removed for some external libs which we don't maintain. # needs to be removed for some external libs which we dont maintain.
# utility macro # utility macro
macro(remove_cc_flag macro(remove_cc_flag
@@ -794,7 +794,7 @@ macro(remove_extra_strict_flags)
endmacro() endmacro()
# note, we can only append flags on a single file so we need to negate the options. # note, we can only append flags on a single file so we need to negate the options.
# at the moment we can't shut up ffmpeg deprecations, so use this, but will # at the moment we cant shut up ffmpeg deprecations, so use this, but will
# probably add more removals here. # probably add more removals here.
macro(remove_strict_c_flags_file macro(remove_strict_c_flags_file
filenames) filenames)
@@ -963,6 +963,14 @@ macro(blender_project_hack_post)
unset(_reset_standard_cflags_rel) unset(_reset_standard_cflags_rel)
unset(_reset_standard_cxxflags_rel) unset(_reset_standard_cxxflags_rel)
# ------------------------------------------------------------------
# workaround for omission in cmake 2.8.4's GNU.cmake, fixed in 2.8.5
if(CMAKE_COMPILER_IS_GNUCC)
if(NOT DARWIN)
set(CMAKE_INCLUDE_SYSTEM_FLAG_C "-isystem ")
endif()
endif()
endmacro() endmacro()
# pair of macros to allow libraries to be specify files to install, but to # pair of macros to allow libraries to be specify files to install, but to

View File

@@ -388,10 +388,6 @@ endif()
if(WITH_TBB) if(WITH_TBB)
find_package(TBB) find_package(TBB)
if(NOT TBB_FOUND)
message(WARNING "TBB not found, disabling WITH_TBB")
set(WITH_TBB OFF)
endif()
endif() endif()
if(WITH_POTRACE) if(WITH_POTRACE)

View File

@@ -457,10 +457,6 @@ endif()
if(WITH_TBB) if(WITH_TBB)
find_package_wrapper(TBB) find_package_wrapper(TBB)
if(NOT TBB_FOUND)
message(WARNING "TBB not found, disabling WITH_TBB")
set(WITH_TBB OFF)
endif()
endif() endif()
if(WITH_XR_OPENXR) if(WITH_XR_OPENXR)

View File

@@ -261,10 +261,8 @@ if(NOT DEFINED LIBDIR)
else() else()
message(FATAL_ERROR "32 bit compiler detected, blender no longer provides pre-build libraries for 32 bit windows, please set the LIBDIR cmake variable to your own library folder") message(FATAL_ERROR "32 bit compiler detected, blender no longer provides pre-build libraries for 32 bit windows, please set the LIBDIR cmake variable to your own library folder")
endif() endif()
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.29.30130) # Can be 1910..1912
message(STATUS "Visual Studio 2022 detected.") if(MSVC_VERSION GREATER 1919)
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/${LIBDIR_BASE}_vc15)
elseif(MSVC_VERSION GREATER 1919)
message(STATUS "Visual Studio 2019 detected.") message(STATUS "Visual Studio 2019 detected.")
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/${LIBDIR_BASE}_vc15) set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/${LIBDIR_BASE}_vc15)
elseif(MSVC_VERSION GREATER 1909) elseif(MSVC_VERSION GREATER 1909)
@@ -550,6 +548,7 @@ if(WITH_OPENIMAGEIO)
set(OPENIMAGEIO_LIBRARIES ${OIIO_OPTIMIZED} ${OIIO_DEBUG}) set(OPENIMAGEIO_LIBRARIES ${OIIO_OPTIMIZED} ${OIIO_DEBUG})
set(OPENIMAGEIO_DEFINITIONS "-DUSE_TBB=0") set(OPENIMAGEIO_DEFINITIONS "-DUSE_TBB=0")
set(OPENCOLORIO_DEFINITIONS "-DDOpenColorIO_SKIP_IMPORTS")
set(OPENIMAGEIO_IDIFF "${OPENIMAGEIO}/bin/idiff.exe") set(OPENIMAGEIO_IDIFF "${OPENIMAGEIO}/bin/idiff.exe")
add_definitions(-DOIIO_STATIC_DEFINE) add_definitions(-DOIIO_STATIC_DEFINE)
add_definitions(-DOIIO_NO_SSE=1) add_definitions(-DOIIO_NO_SSE=1)
@@ -595,7 +594,7 @@ if(WITH_OPENCOLORIO)
debug ${OPENCOLORIO_LIBPATH}/libexpatdMD.lib debug ${OPENCOLORIO_LIBPATH}/libexpatdMD.lib
debug ${OPENCOLORIO_LIBPATH}/pystring_d.lib debug ${OPENCOLORIO_LIBPATH}/pystring_d.lib
) )
set(OPENCOLORIO_DEFINITIONS "-DOpenColorIO_SKIP_IMPORTS") set(OPENCOLORIO_DEFINITIONS)
endif() endif()
if(WITH_OPENVDB) if(WITH_OPENVDB)

View File

@@ -6,9 +6,6 @@ if %ERRORLEVEL% EQU 0 goto DetectionComplete
call "%~dp0\detect_msvc2019.cmd" call "%~dp0\detect_msvc2019.cmd"
if %ERRORLEVEL% EQU 0 goto DetectionComplete if %ERRORLEVEL% EQU 0 goto DetectionComplete
call "%~dp0\detect_msvc2022.cmd"
if %ERRORLEVEL% EQU 0 goto DetectionComplete
echo Compiler Detection failed. Use verbose switch for more information. echo Compiler Detection failed. Use verbose switch for more information.
exit /b 1 exit /b 1

View File

@@ -1,6 +1,5 @@
if "%BUILD_VS_YEAR%"=="2017" set BUILD_VS_LIBDIRPOST=vc15 if "%BUILD_VS_YEAR%"=="2017" set BUILD_VS_LIBDIRPOST=vc15
if "%BUILD_VS_YEAR%"=="2019" set BUILD_VS_LIBDIRPOST=vc15 if "%BUILD_VS_YEAR%"=="2019" set BUILD_VS_LIBDIRPOST=vc15
if "%BUILD_VS_YEAR%"=="2022" set BUILD_VS_LIBDIRPOST=vc15
set BUILD_VS_SVNDIR=win64_%BUILD_VS_LIBDIRPOST% set BUILD_VS_SVNDIR=win64_%BUILD_VS_LIBDIRPOST%
set BUILD_VS_LIBDIR="%BLENDER_DIR%..\lib\%BUILD_VS_SVNDIR%" set BUILD_VS_LIBDIR="%BLENDER_DIR%..\lib\%BUILD_VS_SVNDIR%"

View File

@@ -19,10 +19,10 @@ if "%WITH_PYDEBUG%"=="1" (
set PYDEBUG_CMAKE_ARGS=-DWINDOWS_PYTHON_DEBUG=On set PYDEBUG_CMAKE_ARGS=-DWINDOWS_PYTHON_DEBUG=On
) )
if "%BUILD_VS_YEAR%"=="2017" ( if "%BUILD_VS_YEAR%"=="2019" (
set BUILD_GENERATOR_POST=%WINDOWS_ARCH%
) else (
set BUILD_PLATFORM_SELECT=-A %MSBUILD_PLATFORM% set BUILD_PLATFORM_SELECT=-A %MSBUILD_PLATFORM%
) else (
set BUILD_GENERATOR_POST=%WINDOWS_ARCH%
) )
set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -G "Visual Studio %BUILD_VS_VER% %BUILD_VS_YEAR%%BUILD_GENERATOR_POST%" %BUILD_PLATFORM_SELECT% %TESTS_CMAKE_ARGS% %CLANG_CMAKE_ARGS% %ASAN_CMAKE_ARGS% %PYDEBUG_CMAKE_ARGS% set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -G "Visual Studio %BUILD_VS_VER% %BUILD_VS_YEAR%%BUILD_GENERATOR_POST%" %BUILD_PLATFORM_SELECT% %TESTS_CMAKE_ARGS% %CLANG_CMAKE_ARGS% %ASAN_CMAKE_ARGS% %PYDEBUG_CMAKE_ARGS%

View File

@@ -1,3 +0,0 @@
set BUILD_VS_VER=17
set BUILD_VS_YEAR=2022
call "%~dp0\detect_msvc_vswhere.cmd"

View File

@@ -66,14 +66,6 @@ if NOT "%1" == "" (
) else if "%1" == "2019b" ( ) else if "%1" == "2019b" (
set BUILD_VS_YEAR=2019 set BUILD_VS_YEAR=2019
set VSWHERE_ARGS=-products Microsoft.VisualStudio.Product.BuildTools set VSWHERE_ARGS=-products Microsoft.VisualStudio.Product.BuildTools
) else if "%1" == "2022" (
set BUILD_VS_YEAR=2022
) else if "%1" == "2022pre" (
set BUILD_VS_YEAR=2022
set VSWHERE_ARGS=-prerelease
) else if "%1" == "2022b" (
set BUILD_VS_YEAR=2022
set VSWHERE_ARGS=-products Microsoft.VisualStudio.Product.BuildTools
) else if "%1" == "packagename" ( ) else if "%1" == "packagename" (
set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -DCPACK_OVERRIDE_PACKAGENAME="%2" set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -DCPACK_OVERRIDE_PACKAGENAME="%2"
shift /1 shift /1

View File

@@ -1,13 +1,2 @@
sphinx==3.5.4 Sphinx==3.5.3
# Sphinx dependencies that are important
Jinja2==2.11.3
Pygments==2.9.0
docutils==0.16
snowballstemmer==2.1.0
babel==2.9.1
requests==2.25.1
# Only needed to match the theme used for the official documentation.
# Without this theme, the default theme will be used.
sphinx_rtd_theme==0.5.2 sphinx_rtd_theme==0.5.2

View File

@@ -1,3 +1,3 @@
#define MANTA_GIT_VERSION "commit 8fbebe02459b7f72575872c20961f7cb757db408" #define MANTA_GIT_VERSION "commit 9c505cd22e289b98c9aa717efba8ef3201c7e458"

View File

@@ -71,19 +71,6 @@ class ParticleBase;
for (int j = bnd; j < (grid).getSizeY() - bnd; ++j) \ for (int j = bnd; j < (grid).getSizeY() - bnd; ++j) \
for (int i = bnd; i < (grid).getSizeX() - bnd; ++i) for (int i = bnd; i < (grid).getSizeX() - bnd; ++i)
#define FOR_NEIGHBORS_BND(grid, radius, bnd) \
for (int zj = ((grid).is3D() ? std::max(bnd, k - radius) : 0); \
zj <= ((grid).is3D() ? std::min(k + radius, (grid).getSizeZ() - 1 - bnd) : 0); \
zj++) \
for (int yj = std::max(bnd, j - radius); \
yj <= std::min(j + radius, (grid).getSizeY() - 1 - bnd); \
yj++) \
for (int xj = std::max(bnd, i - radius); \
xj <= std::min(i + radius, (grid).getSizeX() - 1 - bnd); \
xj++)
#define FOR_NEIGHBORS(grid, radius) FOR_NEIGHBORS_BND(grid, radius, 0)
//! Basic data structure for kernel data, initialized based on kernel type (e.g. single, idx, etc). //! Basic data structure for kernel data, initialized based on kernel type (e.g. single, idx, etc).
struct KernelBase { struct KernelBase {
int maxX, maxY, maxZ, minZ, maxT, minT; int maxX, maxY, maxZ, minZ, maxT, minT;

View File

@@ -822,29 +822,33 @@ struct ComputeUnionLevelsetPindex : public KernelBase {
{ {
const Vec3 gridPos = Vec3(i, j, k) + Vec3(0.5); // shifted by half cell const Vec3 gridPos = Vec3(i, j, k) + Vec3(0.5); // shifted by half cell
Real phiv = radius * 1.0; // outside Real phiv = radius * 1.0; // outside
const int r = int(radius) + 1;
FOR_NEIGHBORS(phi, r) int r = int(radius) + 1;
{ int rZ = phi.is3D() ? r : 0;
for (int zj = k - rZ; zj <= k + rZ; zj++)
for (int yj = j - r; yj <= j + r; yj++)
for (int xj = i - r; xj <= i + r; xj++) {
if (!phi.isInBounds(Vec3i(xj, yj, zj)))
continue;
// note, for the particle indices in indexSys the access is periodic (ie, dont skip for eg // note, for the particle indices in indexSys the access is periodic (ie, dont skip for
// inBounds(sx,10,10) // eg inBounds(sx,10,10)
IndexInt isysIdxS = index.index(xj, yj, zj); IndexInt isysIdxS = index.index(xj, yj, zj);
IndexInt pStart = index(isysIdxS), pEnd = 0; IndexInt pStart = index(isysIdxS), pEnd = 0;
if (phi.isInBounds(isysIdxS + 1)) if (phi.isInBounds(isysIdxS + 1))
pEnd = index(isysIdxS + 1); pEnd = index(isysIdxS + 1);
else else
pEnd = indexSys.size(); pEnd = indexSys.size();
// now loop over particles in cell // now loop over particles in cell
for (IndexInt p = pStart; p < pEnd; ++p) { for (IndexInt p = pStart; p < pEnd; ++p) {
const int psrc = indexSys[p].sourceIndex; const int psrc = indexSys[p].sourceIndex;
if (ptype && ((*ptype)[psrc] & exclude)) if (ptype && ((*ptype)[psrc] & exclude))
continue; continue;
const Vec3 pos = parts[psrc].pos; const Vec3 pos = parts[psrc].pos;
phiv = std::min(phiv, fabs(norm(gridPos - pos)) - radius); phiv = std::min(phiv, fabs(norm(gridPos - pos)) - radius);
} }
} }
phi(i, j, k) = phiv; phi(i, j, k) = phiv;
} }
inline const Grid<int> &getArg0() inline const Grid<int> &getArg0()
@@ -1022,35 +1026,39 @@ struct ComputeAveragedLevelsetWeight : public KernelBase {
// loop over neighborhood, similar to ComputeUnionLevelsetPindex // loop over neighborhood, similar to ComputeUnionLevelsetPindex
const Real sradiusInv = 1. / (4. * radius * radius); const Real sradiusInv = 1. / (4. * radius * radius);
const int r = int(radius) + 1; int r = int(1. * radius) + 1;
int rZ = phi.is3D() ? r : 0;
// accumulators // accumulators
Real wacc = 0.; Real wacc = 0.;
Vec3 pacc = Vec3(0.); Vec3 pacc = Vec3(0.);
Real racc = 0.; Real racc = 0.;
FOR_NEIGHBORS(phi, r) for (int zj = k - rZ; zj <= k + rZ; zj++)
{ for (int yj = j - r; yj <= j + r; yj++)
for (int xj = i - r; xj <= i + r; xj++) {
if (!phi.isInBounds(Vec3i(xj, yj, zj)))
continue;
IndexInt isysIdxS = index.index(xj, yj, zj); IndexInt isysIdxS = index.index(xj, yj, zj);
IndexInt pStart = index(isysIdxS), pEnd = 0; IndexInt pStart = index(isysIdxS), pEnd = 0;
if (phi.isInBounds(isysIdxS + 1)) if (phi.isInBounds(isysIdxS + 1))
pEnd = index(isysIdxS + 1); pEnd = index(isysIdxS + 1);
else else
pEnd = indexSys.size(); pEnd = indexSys.size();
for (IndexInt p = pStart; p < pEnd; ++p) { for (IndexInt p = pStart; p < pEnd; ++p) {
IndexInt psrc = indexSys[p].sourceIndex; IndexInt psrc = indexSys[p].sourceIndex;
if (ptype && ((*ptype)[psrc] & exclude)) if (ptype && ((*ptype)[psrc] & exclude))
continue; continue;
Vec3 pos = parts[psrc].pos; Vec3 pos = parts[psrc].pos;
Real s = normSquare(gridPos - pos) * sradiusInv; Real s = normSquare(gridPos - pos) * sradiusInv;
// Real w = std::max(0., cubed(1.-s) ); // Real w = std::max(0., cubed(1.-s) );
Real w = std::max(0., (1. - s)); // a bit smoother Real w = std::max(0., (1. - s)); // a bit smoother
wacc += w; wacc += w;
racc += radius * w; racc += radius * w;
pacc += pos * w; pacc += pos * w;
} }
} }
if (wacc > VECTOR_EPSILON) { if (wacc > VECTOR_EPSILON) {
racc /= wacc; racc /= wacc;

View File

@@ -234,10 +234,10 @@ void subdivideMesh(
normalize(ne2); normalize(ne2);
// Real thisArea = sqrMag(cross(-e2,e0)); // Real thisArea = sqrMag(cross(-e2,e0));
// small angle approximation says sin(x) = arcsin(x) = x, // small angle approximation says sin(x) = arcsin(x) = x,
// arccos(x) = pi/2 - arcsin(x), // arccos(x) = pi/2 - arcsin(x),
// cos(x) = dot(A,B), // cos(x) = dot(A,B),
// so angle is approximately 1 - dot(A,B). // so angle is approximately 1 - dot(A,B).
Real angle[3]; Real angle[3];
angle[0] = 1.0 - dot(ne0, -ne2); angle[0] = 1.0 - dot(ne0, -ne2);
angle[1] = 1.0 - dot(ne1, -ne0); angle[1] = 1.0 - dot(ne1, -ne0);

View File

@@ -2287,9 +2287,10 @@ struct knFlipComputePotentialTrappedAir : public KernelBase {
const Vec3 &vj = scaleFromManta * v.getCentered(x, y, z); const Vec3 &vj = scaleFromManta * v.getCentered(x, y, z);
const Vec3 xij = xi - xj; const Vec3 xij = xi - xj;
const Vec3 vij = vi - vj; const Vec3 vij = vi - vj;
Real h = !pot.is3D() ? 1.414 * radius : Real h = !pot.is3D() ?
1.732 * radius; // estimate sqrt(2)*radius resp. sqrt(3)*radius 1.414 * radius :
// for h, due to squared resp. cubic neighbor area 1.732 * radius; // estimate sqrt(2)*radius resp. sqrt(3)*radius for h, due
// to squared resp. cubic neighbor area
vdiff += norm(vij) * (1 - dot(getNormalized(vij), getNormalized(xij))) * vdiff += norm(vij) * (1 - dot(getNormalized(vij), getNormalized(xij))) *
(1 - norm(xij) / h); (1 - norm(xij) / h);
} }

View File

@@ -79,15 +79,15 @@ typedef struct CLG_IDFilter {
} CLG_IDFilter; } CLG_IDFilter;
typedef struct CLogContext { typedef struct CLogContext {
/** Single linked list of types. */ /** Single linked list of types. */
CLG_LogType *types; CLG_LogType *types;
/** Single linked list of references. */ /** Single linked list of references. */
CLG_LogRef *refs; CLG_LogRef *refs;
#ifdef WITH_CLOG_PTHREADS #ifdef WITH_CLOG_PTHREADS
pthread_mutex_t types_lock; pthread_mutex_t types_lock;
#endif #endif
/* exclude, include filters. */ /* exclude, include filters. */
CLG_IDFilter *filters[2]; CLG_IDFilter *filters[2];
bool use_color; bool use_color;
bool use_basename; bool use_basename;

View File

@@ -51,12 +51,12 @@ CCL_NAMESPACE_BEGIN
/* XML reading state */ /* XML reading state */
struct XMLReadState : public XMLReader { struct XMLReadState : public XMLReader {
Scene *scene; /* Scene pointer. */ Scene *scene; /* scene pointer */
Transform tfm; /* Current transform state. */ Transform tfm; /* current transform state */
bool smooth; /* Smooth normal state. */ bool smooth; /* smooth normal state */
Shader *shader; /* Current shader. */ Shader *shader; /* current shader */
string base; /* Base path to current file. */ string base; /* base path to current file*/
float dicing_rate; /* Current dicing rate. */ float dicing_rate; /* current dicing rate */
XMLReadState() : scene(NULL), smooth(false), shader(NULL), dicing_rate(1.0f) XMLReadState() : scene(NULL), smooth(false), shader(NULL), dicing_rate(1.0f)
{ {
@@ -385,7 +385,7 @@ static Mesh *xml_add_mesh(Scene *scene, const Transform &tfm)
Mesh *mesh = new Mesh(); Mesh *mesh = new Mesh();
scene->geometry.push_back(mesh); scene->geometry.push_back(mesh);
/* Create object. */ /* create object*/
Object *object = new Object(); Object *object = new Object();
object->set_geometry(mesh); object->set_geometry(mesh);
object->set_tfm(tfm); object->set_tfm(tfm);

View File

@@ -821,11 +821,6 @@ class CYCLES_RENDER_PT_filter(CyclesButtonsPanel, Panel):
col.prop(view_layer, "use_strand", text="Hair") col.prop(view_layer, "use_strand", text="Hair")
col.prop(view_layer, "use_volumes", text="Volumes") col.prop(view_layer, "use_volumes", text="Volumes")
col = layout.column(heading="Use")
sub = col.row()
sub.prop(view_layer, "use_motion_blur", text="Motion Blur")
sub.active = rd.use_motion_blur
class CYCLES_RENDER_PT_override(CyclesButtonsPanel, Panel): class CYCLES_RENDER_PT_override(CyclesButtonsPanel, Panel):
bl_label = "Override" bl_label = "Override"

View File

@@ -533,7 +533,7 @@ void BlenderSync::sync_particle_hair(
return; return;
} }
/* Extract particle hair data - should be combined with connecting to mesh later. */ /* extract particle hair data - should be combined with connecting to mesh later*/
ParticleCurveData CData; ParticleCurveData CData;

View File

@@ -44,7 +44,7 @@ void BlenderSync::sync_light(BL::Object &b_parent,
const bool tfm_updated = (light && light->get_tfm() != tfm); const bool tfm_updated = (light && light->get_tfm() != tfm);
/* Update if either object or light data changed. */ /* Update if either object or light data changed. */
if (!light_map.add_or_update(&light, b_ob, b_parent, key) && !tfm_updated) { if (!tfm_updated && !light_map.add_or_update(&light, b_ob, b_parent, key)) {
Shader *shader; Shader *shader;
if (!shader_map.add_or_update(&shader, b_light)) { if (!shader_map.add_or_update(&shader, b_light)) {
if (light->get_is_portal()) if (light->get_is_portal())

View File

@@ -289,10 +289,11 @@ static PyObject *render_func(PyObject * /*self*/, PyObject *args)
RNA_pointer_create(NULL, &RNA_Depsgraph, (ID *)PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr); RNA_pointer_create(NULL, &RNA_Depsgraph, (ID *)PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
BL::Depsgraph b_depsgraph(depsgraphptr); BL::Depsgraph b_depsgraph(depsgraphptr);
/* Allow Blender to execute other Python scripts. */ /* Allow Blender to execute other Python scripts, and isolate TBB tasks so we
* don't get deadlocks with Blender threads accessing shared data like images. */
python_thread_state_save(&session->python_thread_state); python_thread_state_save(&session->python_thread_state);
session->render(b_depsgraph); tbb::this_task_arena::isolate([&] { session->render(b_depsgraph); });
python_thread_state_restore(&session->python_thread_state); python_thread_state_restore(&session->python_thread_state);
@@ -329,7 +330,8 @@ static PyObject *bake_func(PyObject * /*self*/, PyObject *args)
python_thread_state_save(&session->python_thread_state); python_thread_state_save(&session->python_thread_state);
session->bake(b_depsgraph, b_object, pass_type, pass_filter, width, height); tbb::this_task_arena::isolate(
[&] { session->bake(b_depsgraph, b_object, pass_type, pass_filter, width, height); });
python_thread_state_restore(&session->python_thread_state); python_thread_state_restore(&session->python_thread_state);
@@ -375,7 +377,7 @@ static PyObject *reset_func(PyObject * /*self*/, PyObject *args)
python_thread_state_save(&session->python_thread_state); python_thread_state_save(&session->python_thread_state);
session->reset_session(b_data, b_depsgraph); tbb::this_task_arena::isolate([&] { session->reset_session(b_data, b_depsgraph); });
python_thread_state_restore(&session->python_thread_state); python_thread_state_restore(&session->python_thread_state);
@@ -397,7 +399,7 @@ static PyObject *sync_func(PyObject * /*self*/, PyObject *args)
python_thread_state_save(&session->python_thread_state); python_thread_state_save(&session->python_thread_state);
session->synchronize(b_depsgraph); tbb::this_task_arena::isolate([&] { session->synchronize(b_depsgraph); });
python_thread_state_restore(&session->python_thread_state); python_thread_state_restore(&session->python_thread_state);

View File

@@ -281,6 +281,7 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render,
void BlenderSync::sync_integrator() void BlenderSync::sync_integrator()
{ {
BL::RenderSettings r = b_scene.render();
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
experimental = (get_enum(cscene, "feature_set") != 0); experimental = (get_enum(cscene, "feature_set") != 0);
@@ -324,7 +325,7 @@ void BlenderSync::sync_integrator()
integrator->set_sample_clamp_direct(get_float(cscene, "sample_clamp_direct")); integrator->set_sample_clamp_direct(get_float(cscene, "sample_clamp_direct"));
integrator->set_sample_clamp_indirect(get_float(cscene, "sample_clamp_indirect")); integrator->set_sample_clamp_indirect(get_float(cscene, "sample_clamp_indirect"));
if (!preview) { if (!preview) {
integrator->set_motion_blur(view_layer.use_motion_blur); integrator->set_motion_blur(r.use_motion_blur());
} }
integrator->set_method((Integrator::Method)get_enum( integrator->set_method((Integrator::Method)get_enum(
@@ -455,8 +456,6 @@ void BlenderSync::sync_view_layer(BL::ViewLayer &b_view_layer)
view_layer.use_surfaces = b_view_layer.use_solid() || scene->bake_manager->get_baking(); view_layer.use_surfaces = b_view_layer.use_solid() || scene->bake_manager->get_baking();
view_layer.use_hair = b_view_layer.use_strand(); view_layer.use_hair = b_view_layer.use_strand();
view_layer.use_volumes = b_view_layer.use_volumes(); view_layer.use_volumes = b_view_layer.use_volumes();
view_layer.use_motion_blur = b_view_layer.use_motion_blur() &&
b_scene.render().use_motion_blur();
/* Material override. */ /* Material override. */
view_layer.material_override = b_view_layer.material_override(); view_layer.material_override = b_view_layer.material_override();
@@ -603,7 +602,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::Scene &b_scene,
for (BL::RenderPass &b_pass : b_rlay.passes) { for (BL::RenderPass &b_pass : b_rlay.passes) {
PassType pass_type = get_pass_type(b_pass); PassType pass_type = get_pass_type(b_pass);
if (pass_type == PASS_MOTION && view_layer.use_motion_blur) if (pass_type == PASS_MOTION && b_scene.render().use_motion_blur())
continue; continue;
if (pass_type != PASS_NONE) if (pass_type != PASS_NONE)
Pass::add(pass_type, passes, b_pass.name().c_str()); Pass::add(pass_type, passes, b_pass.name().c_str());

View File

@@ -246,7 +246,6 @@ class BlenderSync {
use_surfaces(true), use_surfaces(true),
use_hair(true), use_hair(true),
use_volumes(true), use_volumes(true),
use_motion_blur(true),
samples(0), samples(0),
bound_samples(false) bound_samples(false)
{ {
@@ -259,7 +258,6 @@ class BlenderSync {
bool use_surfaces; bool use_surfaces;
bool use_hair; bool use_hair;
bool use_volumes; bool use_volumes;
bool use_motion_blur;
int samples; int samples;
bool bound_samples; bool bound_samples;
} view_layer; } view_layer;

View File

@@ -181,7 +181,7 @@ static void rtc_filter_occluded_func(const RTCFilterFunctionNArguments *args)
/* record intersection */ /* record intersection */
ctx->local_isect->hits[hit_idx] = current_isect; ctx->local_isect->hits[hit_idx] = current_isect;
ctx->local_isect->Ng[hit_idx] = normalize(make_float3(hit->Ng_x, hit->Ng_y, hit->Ng_z)); ctx->local_isect->Ng[hit_idx] = normalize(make_float3(hit->Ng_x, hit->Ng_y, hit->Ng_z));
/* This tells Embree to continue tracing. */ /* This tells Embree to continue tracing .*/
*args->valid = 0; *args->valid = 0;
break; break;
} }

View File

@@ -179,7 +179,7 @@ class InnerNode : public BVHNode {
} }
/* NOTE: This function is only used during binary BVH builder, and it /* NOTE: This function is only used during binary BVH builder, and it
* supposed to be configured to have 2 children which will be filled-in in a * supposed to be configured to have 2 children which will be filled in in a
* bit. But this is important to have children reset to NULL. */ * bit. But this is important to have children reset to NULL. */
explicit InnerNode(const BoundBox &bounds) : BVHNode(bounds), num_children_(0) explicit InnerNode(const BoundBox &bounds) : BVHNode(bounds), num_children_(0)
{ {

View File

@@ -297,7 +297,7 @@ struct BVHSpatialBin {
*/ */
struct BVHSpatialStorage { struct BVHSpatialStorage {
/* Accumulated bounds when sweeping from right to left. */ /* Accumulated bounds when sweeping from right to left. */
vector<BoundBox> right_bounds; vector<BoundBox> right_bounds;
/* Bins used for histogram when selecting best split plane. */ /* Bins used for histogram when selecting best split plane. */

View File

@@ -388,7 +388,7 @@ void BVHSpatialSplit::split_curve_primitive(const Hair *hair,
BoundBox &left_bounds, BoundBox &left_bounds,
BoundBox &right_bounds) BoundBox &right_bounds)
{ {
/* curve split: NOTE - Currently ignores curve width and needs to be fixed. */ /* curve split: NOTE - Currently ignores curve width and needs to be fixed.*/
Hair::Curve curve = hair->get_curve(prim_index); Hair::Curve curve = hair->get_curve(prim_index);
const int k0 = curve.first_key + segment_index; const int k0 = curve.first_key + segment_index;
const int k1 = k0 + 1; const int k1 = k0 + 1;

View File

@@ -1196,18 +1196,16 @@ class OptiXDevice : public CUDADevice {
const CUDAContextScope scope(cuContext); const CUDAContextScope scope(cuContext);
const bool use_fast_trace_bvh = (bvh->params.bvh_type == SceneParams::BVH_STATIC);
// Compute memory usage // Compute memory usage
OptixAccelBufferSizes sizes = {}; OptixAccelBufferSizes sizes = {};
OptixAccelBuildOptions options = {}; OptixAccelBuildOptions options = {};
options.operation = operation; options.operation = operation;
if (use_fast_trace_bvh) { if (background) {
VLOG(2) << "Using fast to trace OptiX BVH"; // Prefer best performance and lowest memory consumption in background
options.buildFlags = OPTIX_BUILD_FLAG_PREFER_FAST_TRACE | OPTIX_BUILD_FLAG_ALLOW_COMPACTION; options.buildFlags = OPTIX_BUILD_FLAG_PREFER_FAST_TRACE | OPTIX_BUILD_FLAG_ALLOW_COMPACTION;
} }
else { else {
VLOG(2) << "Using fast to update OptiX BVH"; // Prefer fast updates in viewport
options.buildFlags = OPTIX_BUILD_FLAG_PREFER_FAST_BUILD | OPTIX_BUILD_FLAG_ALLOW_UPDATE; options.buildFlags = OPTIX_BUILD_FLAG_PREFER_FAST_BUILD | OPTIX_BUILD_FLAG_ALLOW_UPDATE;
} }
@@ -1255,16 +1253,15 @@ class OptiXDevice : public CUDADevice {
out_data.device_pointer, out_data.device_pointer,
sizes.outputSizeInBytes, sizes.outputSizeInBytes,
&out_handle, &out_handle,
use_fast_trace_bvh ? &compacted_size_prop : NULL, background ? &compacted_size_prop : NULL,
use_fast_trace_bvh ? 1 : 0)); background ? 1 : 0));
bvh->traversable_handle = static_cast<uint64_t>(out_handle); bvh->traversable_handle = static_cast<uint64_t>(out_handle);
// Wait for all operations to finish // Wait for all operations to finish
check_result_cuda_ret(cuStreamSynchronize(NULL)); check_result_cuda_ret(cuStreamSynchronize(NULL));
// Compact acceleration structure to save memory (only if using fast trace as the // Compact acceleration structure to save memory (do not do this in viewport for faster builds)
// OPTIX_BUILD_FLAG_ALLOW_COMPACTION flag is only set in this case). if (background) {
if (use_fast_trace_bvh) {
uint64_t compacted_size = sizes.outputSizeInBytes; uint64_t compacted_size = sizes.outputSizeInBytes;
check_result_cuda_ret( check_result_cuda_ret(
cuMemcpyDtoH(&compacted_size, compacted_size_prop.result, sizeof(compacted_size))); cuMemcpyDtoH(&compacted_size, compacted_size_prop.result, sizeof(compacted_size)));
@@ -1309,8 +1306,6 @@ class OptiXDevice : public CUDADevice {
return; return;
} }
const bool use_fast_trace_bvh = (bvh->params.bvh_type == SceneParams::BVH_STATIC);
free_bvh_memory_delayed(); free_bvh_memory_delayed();
BVHOptiX *const bvh_optix = static_cast<BVHOptiX *>(bvh); BVHOptiX *const bvh_optix = static_cast<BVHOptiX *>(bvh);
@@ -1320,10 +1315,10 @@ class OptiXDevice : public CUDADevice {
if (!bvh->params.top_level) { if (!bvh->params.top_level) {
assert(bvh->objects.size() == 1 && bvh->geometry.size() == 1); assert(bvh->objects.size() == 1 && bvh->geometry.size() == 1);
// Refit is only possible in viewport for now (because AS is built with
// OPTIX_BUILD_FLAG_ALLOW_UPDATE only there, see above)
OptixBuildOperation operation = OPTIX_BUILD_OPERATION_BUILD; OptixBuildOperation operation = OPTIX_BUILD_OPERATION_BUILD;
/* Refit is only possible when using fast to trace BVH (because AS is built with if (refit && !background) {
* OPTIX_BUILD_FLAG_ALLOW_UPDATE only there, see above). */
if (refit && !use_fast_trace_bvh) {
assert(bvh_optix->traversable_handle != 0); assert(bvh_optix->traversable_handle != 0);
operation = OPTIX_BUILD_OPERATION_UPDATE; operation = OPTIX_BUILD_OPERATION_UPDATE;
} }

View File

@@ -65,7 +65,7 @@ class DenoiseParams {
/* Viewport start sample. */ /* Viewport start sample. */
int start_sample; int start_sample;
/** Native Denoiser. */ /** Native Denoiser **/
/* Pixel radius for neighboring pixels to take into account. */ /* Pixel radius for neighboring pixels to take into account. */
int radius; int radius;
@@ -81,7 +81,7 @@ class DenoiseParams {
/* Clamp the input to the range of +-1e8. Should be enough for any legitimate data. */ /* Clamp the input to the range of +-1e8. Should be enough for any legitimate data. */
bool clamp_input; bool clamp_input;
/** OIDN/Optix Denoiser. */ /** OIDN/Optix Denoiser **/
/* Passes handed over to the OIDN/OptiX denoiser (default to color + albedo). */ /* Passes handed over to the OIDN/OptiX denoiser (default to color + albedo). */
DenoiserInput input_passes; DenoiserInput input_passes;

View File

@@ -1186,7 +1186,7 @@ bool OpenCLInfo::get_device_extensions(cl_device_id device_id,
{ {
size_t extension_length = 0; size_t extension_length = 0;
cl_int err; cl_int err;
/* Determine the size of the extension string. */ /* Determine the size of the extension string*/
if ((err = clGetDeviceInfo(device_id, CL_DEVICE_EXTENSIONS, 0, 0, &extension_length)) != if ((err = clGetDeviceInfo(device_id, CL_DEVICE_EXTENSIONS, 0, 0, &extension_length)) !=
CL_SUCCESS) { CL_SUCCESS) {
if (error != NULL) { if (error != NULL) {

View File

@@ -116,7 +116,7 @@ CCL_NAMESPACE_BEGIN
# endif # endif
# endif /* __SHADOW_RECORD_ALL__ */ # endif /* __SHADOW_RECORD_ALL__ */
/* Record all intersections - Volume BVH traversal. */ /* Record all intersections - Volume BVH traversal */
# if defined(__VOLUME_RECORD_ALL__) # if defined(__VOLUME_RECORD_ALL__)
# define BVH_FUNCTION_NAME bvh_intersect_volume_all # define BVH_FUNCTION_NAME bvh_intersect_volume_all

View File

@@ -61,8 +61,8 @@ ccl_device_forceinline float3 bsdf_ashikhmin_shirley_eval_reflect(const ShaderCl
const MicrofacetBsdf *bsdf = (const MicrofacetBsdf *)sc; const MicrofacetBsdf *bsdf = (const MicrofacetBsdf *)sc;
float3 N = bsdf->N; float3 N = bsdf->N;
float NdotI = dot(N, I); /* in Cycles/OSL convention I is omega_out */ float NdotI = dot(N, I); /* in Cycles/OSL convention I is omega_out */
float NdotO = dot(N, omega_in); /* and consequently we use for O omaga_in ;) */ float NdotO = dot(N, omega_in); /* and consequently we use for O omaga_in ;) */
float out = 0.0f; float out = 0.0f;

View File

@@ -66,7 +66,7 @@ ccl_device_noinline void motion_triangle_shader_setup(
sd->P = motion_triangle_refine_local(kg, sd, isect, ray, verts); sd->P = motion_triangle_refine_local(kg, sd, isect, ray, verts);
} }
else else
#endif /* __BVH_LOCAL__*/ #endif /* __BVH_LOCAL__*/
{ {
sd->P = motion_triangle_refine(kg, sd, isect, ray, verts); sd->P = motion_triangle_refine(kg, sd, isect, ray, verts);
} }

View File

@@ -22,7 +22,7 @@
CCL_NAMESPACE_BEGIN CCL_NAMESPACE_BEGIN
/* Normal on triangle. */ /* normal on triangle */
ccl_device_inline float3 triangle_normal(KernelGlobals *kg, ShaderData *sd) ccl_device_inline float3 triangle_normal(KernelGlobals *kg, ShaderData *sd)
{ {
/* load triangle vertices */ /* load triangle vertices */
@@ -40,7 +40,7 @@ ccl_device_inline float3 triangle_normal(KernelGlobals *kg, ShaderData *sd)
} }
} }
/* Point and normal on triangle. */ /* point and normal on triangle */
ccl_device_inline void triangle_point_normal( ccl_device_inline void triangle_point_normal(
KernelGlobals *kg, int object, int prim, float u, float v, float3 *P, float3 *Ng, int *shader) KernelGlobals *kg, int object, int prim, float u, float v, float3 *P, float3 *Ng, int *shader)
{ {

View File

@@ -64,7 +64,7 @@ typedef struct KernelGlobals {
OSLThreadData *osl_tdata; OSLThreadData *osl_tdata;
# endif # endif
/* **** Run-time data **** */ /* **** Run-time data **** */
/* Heap-allocated storage for transparent shadows intersections. */ /* Heap-allocated storage for transparent shadows intersections. */
Intersection *transparent_shadow_intersections; Intersection *transparent_shadow_intersections;

View File

@@ -35,7 +35,7 @@
CCL_NAMESPACE_BEGIN CCL_NAMESPACE_BEGIN
/* Spherical coordinates <-> Cartesian direction. */ /* Spherical coordinates <-> Cartesian direction */
ccl_device float2 direction_to_spherical(float3 dir) ccl_device float2 direction_to_spherical(float3 dir)
{ {

View File

@@ -79,7 +79,7 @@ ccl_device void enqueue_ray_index_local(
{ {
int lidx = ccl_local_id(1) * ccl_local_size(0) + ccl_local_id(0); int lidx = ccl_local_id(1) * ccl_local_size(0) + ccl_local_id(0);
/* Get local queue id. */ /* Get local queue id .*/
unsigned int lqidx; unsigned int lqidx;
if (enqueue_flag) { if (enqueue_flag) {
lqidx = atomic_fetch_and_inc_uint32(local_queue_atomics); lqidx = atomic_fetch_and_inc_uint32(local_queue_atomics);

View File

@@ -274,7 +274,7 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals *kg,
/* primitive */ /* primitive */
sd->object = object; sd->object = object;
sd->lamp = LAMP_NONE; sd->lamp = LAMP_NONE;
/* Currently no access to bvh prim index for strand sd->prim. */ /* currently no access to bvh prim index for strand sd->prim*/
sd->prim = prim; sd->prim = prim;
sd->u = u; sd->u = u;
sd->v = v; sd->v = v;

View File

@@ -409,7 +409,7 @@ ccl_device void subsurface_random_walk_coefficients(const ShaderClosure *sc,
ccl_device_forceinline float eval_phase_dwivedi(float v, float phase_log, float cos_theta) ccl_device_forceinline float eval_phase_dwivedi(float v, float phase_log, float cos_theta)
{ {
/* Eq. 9 from [2] using precomputed log((v + 1) / (v - 1)) */ /* Eq. 9 from [2] using precomputed log((v + 1) / (v - 1))*/
return 1.0f / ((v - cos_theta) * phase_log); return 1.0f / ((v - cos_theta) * phase_log);
} }

View File

@@ -302,7 +302,7 @@ enum PathRayFlag {
PATH_RAY_DIFFUSE_ANCESTOR = (1 << 15), PATH_RAY_DIFFUSE_ANCESTOR = (1 << 15),
/* Single pass has been written. */ /* Single pass has been written. */
PATH_RAY_SINGLE_PASS_DONE = (1 << 16), PATH_RAY_SINGLE_PASS_DONE = (1 << 16),
/* Ray is behind a shadow catcher. */ /* Ray is behind a shadow catcher .*/
PATH_RAY_SHADOW_CATCHER = (1 << 17), PATH_RAY_SHADOW_CATCHER = (1 << 17),
/* Store shadow data for shadow catcher or denoising. */ /* Store shadow data for shadow catcher or denoising. */
PATH_RAY_STORE_SHADOW_INFO = (1 << 18), PATH_RAY_STORE_SHADOW_INFO = (1 << 18),

View File

@@ -317,4 +317,4 @@ class OSLRenderServices : public OSL::RendererServices {
CCL_NAMESPACE_END CCL_NAMESPACE_END
#endif /* __OSL_SERVICES_H__ */ #endif /* __OSL_SERVICES_H__ */

View File

@@ -49,7 +49,7 @@ void OSLShader::thread_init(KernelGlobals *kg,
return; return;
} }
/* Per thread kernel data init. */ /* per thread kernel data init*/
kg->osl = osl_globals; kg->osl = osl_globals;
OSL::ShadingSystem *ss = kg->osl->ss; OSL::ShadingSystem *ss = kg->osl->ss;

View File

@@ -68,7 +68,7 @@ typedef ccl_global struct SplitBranchedState {
uint lcg_state; uint lcg_state;
LocalIntersection ss_isect; LocalIntersection ss_isect;
# endif /* __SUBSURFACE__ */ # endif /*__SUBSURFACE__ */
int shared_sample_count; /* number of branched samples shared with other threads */ int shared_sample_count; /* number of branched samples shared with other threads */
int original_ray; /* index of original ray when sharing branched samples */ int original_ray; /* index of original ray when sharing branched samples */

View File

@@ -803,7 +803,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg,
float melanin_redness = stack_load_float_default( float melanin_redness = stack_load_float_default(
stack, melanin_redness_ofs, data_node2.w); stack, melanin_redness_ofs, data_node2.w);
/* Randomize melanin. */ /* Randomize melanin. */
float random_color = stack_load_float_default(stack, random_color_ofs, data_node3.z); float random_color = stack_load_float_default(stack, random_color_ofs, data_node3.z);
random_color = clamp(random_color, 0.0f, 1.0f); random_color = clamp(random_color, 0.0f, 1.0f);
float factor_random_color = 1.0f + 2.0f * (random - 0.5f) * random_color; float factor_random_color = 1.0f + 2.0f * (random - 0.5f) * random_color;

View File

@@ -220,13 +220,11 @@ ccl_device void svm_node_hair_info(
stack_store_float(stack, out_offset, data); stack_store_float(stack, out_offset, data);
break; break;
} }
# if 0 /*case NODE_INFO_CURVE_FADE: {
case NODE_INFO_CURVE_FADE: {
data = sd->curve_transparency; data = sd->curve_transparency;
stack_store_float(stack, out_offset, data); stack_store_float(stack, out_offset, data);
break; break;
} }*/
# endif
case NODE_INFO_CURVE_TANGENT_NORMAL: { case NODE_INFO_CURVE_TANGENT_NORMAL: {
data3 = curve_tangent_normal(kg, sd); data3 = curve_tangent_normal(kg, sd);
stack_store_float3(stack, out_offset, data3); stack_store_float3(stack, out_offset, data3);

View File

@@ -182,7 +182,7 @@ ccl_device void svm_node_tex_image_box(KernelGlobals *kg, ShaderData *sd, float
} }
} }
else { else {
/* Desperate mode, no valid choice anyway, fallback to one side. */ /* Desperate mode, no valid choice anyway, fallback to one side.*/
weight.x = 1.0f; weight.x = 1.0f;
} }

View File

@@ -333,7 +333,7 @@ static M44d get_interpolated_matrix_for_time(const MatrixSampleMap &samples, chr
chrono_t t = (time - prev_time) / (next_time - prev_time); chrono_t t = (time - prev_time) / (next_time - prev_time);
/* Ensure rotation around the shortest angle. */ /* ensure rotation around the shortest angle */
if ((prev_rotation ^ next_rotation) < 0) { if ((prev_rotation ^ next_rotation) < 0) {
next_rotation = -next_rotation; next_rotation = -next_rotation;
} }

View File

@@ -736,14 +736,13 @@ static void process_uvs(CachedData &cache,
const IV2fGeomParam::Sample &sample, const IV2fGeomParam::Sample &sample,
double time) double time)
{ {
if (scope != kFacevaryingScope && scope != kVaryingScope && scope != kVertexScope) { if (scope != kFacevaryingScope) {
return; return;
} }
const array<int> *uv_loops = cache.uv_loops.data_for_time_no_check(time).get_data_or_null(); const array<int> *uv_loops = cache.uv_loops.data_for_time_no_check(time).get_data_or_null();
/* It's ok to not have loop indices, as long as the scope is not face-varying. */ if (!uv_loops) {
if (!uv_loops && scope == kFacevaryingScope) {
return; return;
} }
@@ -767,27 +766,9 @@ static void process_uvs(CachedData &cache,
const uint32_t *indices = sample.getIndices()->get(); const uint32_t *indices = sample.getIndices()->get();
const V2f *values = sample.getVals()->get(); const V2f *values = sample.getVals()->get();
if (scope == kFacevaryingScope) { for (const int uv_loop_index : *uv_loops) {
for (const int uv_loop_index : *uv_loops) { const uint32_t index = indices[uv_loop_index];
const uint32_t index = indices[uv_loop_index]; *data_float2++ = make_float2(values[index][0], values[index][1]);
*data_float2++ = make_float2(values[index][0], values[index][1]);
}
}
else if (scope == kVaryingScope || scope == kVertexScope) {
if (triangles) {
for (size_t i = 0; i < triangles->size(); i++) {
const int3 t = (*triangles)[i];
*data_float2++ = make_float2(values[t.x][0], values[t.x][1]);
*data_float2++ = make_float2(values[t.y][0], values[t.y][1]);
*data_float2++ = make_float2(values[t.z][0], values[t.z][1]);
}
}
else if (corners) {
for (size_t i = 0; i < corners->size(); i++) {
const int c = (*corners)[i];
*data_float2++ = make_float2(values[c][0], values[c][1]);
}
}
} }
attribute.data.add_data(data, time); attribute.data.add_data(data, time);

View File

@@ -676,8 +676,8 @@ void GeometryManager::update_attribute_element_offset(Geometry *geom,
Mesh *mesh = static_cast<Mesh *>(geom); Mesh *mesh = static_cast<Mesh *>(geom);
if (mesh->subdivision_type == Mesh::SUBDIVISION_CATMULL_CLARK && if (mesh->subdivision_type == Mesh::SUBDIVISION_CATMULL_CLARK &&
desc.flags & ATTR_SUBDIVIDED) { desc.flags & ATTR_SUBDIVIDED) {
/* Indices for subdivided attributes are retrieved /* indices for subdivided attributes are retrieved
* from patch table so no need for correction here. */ * from patch table so no need for correction here*/
} }
else if (element == ATTR_ELEMENT_VERTEX) else if (element == ATTR_ELEMENT_VERTEX)
offset -= mesh->vert_offset; offset -= mesh->vert_offset;

View File

@@ -4374,7 +4374,7 @@ NODE_DEFINE(HairInfoNode)
SOCKET_OUT_FLOAT(intercept, "Intercept"); SOCKET_OUT_FLOAT(intercept, "Intercept");
SOCKET_OUT_FLOAT(thickness, "Thickness"); SOCKET_OUT_FLOAT(thickness, "Thickness");
SOCKET_OUT_NORMAL(tangent_normal, "Tangent Normal"); SOCKET_OUT_NORMAL(tangent_normal, "Tangent Normal");
#if 0 /* Output for minimum hair width transparency - deactivated. */ #if 0 /*output for minimum hair width transparency - deactivated */
SOCKET_OUT_FLOAT(fade, "Fade"); SOCKET_OUT_FLOAT(fade, "Fade");
#endif #endif
SOCKET_OUT_FLOAT(index, "Random"); SOCKET_OUT_FLOAT(index, "Random");
@@ -4425,12 +4425,12 @@ void HairInfoNode::compile(SVMCompiler &compiler)
if (!out->links.empty()) { if (!out->links.empty()) {
compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_TANGENT_NORMAL, compiler.stack_assign(out)); compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_TANGENT_NORMAL, compiler.stack_assign(out));
} }
#if 0
out = output("Fade"); /*out = output("Fade");
if(!out->links.empty()) { if(!out->links.empty()) {
compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_FADE, compiler.stack_assign(out)); compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_FADE, compiler.stack_assign(out));
} }*/
#endif
out = output("Random"); out = output("Random");
if (!out->links.empty()) { if (!out->links.empty()) {
int attr = compiler.attribute(ATTR_STD_CURVE_RANDOM); int attr = compiler.attribute(ATTR_STD_CURVE_RANDOM);

View File

@@ -195,4 +195,4 @@ class OSLCompiler {
CCL_NAMESPACE_END CCL_NAMESPACE_END
#endif /* __OSL_H__ */ #endif /* __OSL_H__ */

View File

@@ -1252,7 +1252,7 @@ bool Session::update_progressive_refine(bool cancel)
double current_time = time_dt(); double current_time = time_dt();
if (current_time - last_update_time < params.progressive_update_timeout) { if (current_time - last_update_time < params.progressive_update_timeout) {
/* If last sample was processed, we need to write buffers anyway. */ /* if last sample was processed, we need to write buffers anyway */
if (!write && sample != 1) if (!write && sample != 1)
return false; return false;
} }

View File

@@ -15,7 +15,7 @@
if(WITH_GTESTS) if(WITH_GTESTS)
Include(GTestTesting) Include(GTestTesting)
# Otherwise we get warnings here that we can't fix in external projects # Otherwise we get warnings here that we cant fix in external projects
remove_strict_flags() remove_strict_flags()
endif() endif()

View File

@@ -223,14 +223,12 @@ ccl_device_inline ssef fastpow24(const ssef &arg)
ssef x = fastpow<0x3F4CCCCD, 0x4F55A7FB>(arg); // error max = 0.17 avg = 0.0018 |avg| = 0.05 ssef x = fastpow<0x3F4CCCCD, 0x4F55A7FB>(arg); // error max = 0.17 avg = 0.0018 |avg| = 0.05
ssef arg2 = arg * arg; ssef arg2 = arg * arg;
ssef arg4 = arg2 * arg2; ssef arg4 = arg2 * arg2;
x = improve_5throot_solution(x,
/* error max = 0.018 avg = 0.0031 |avg| = 0.0031 */ arg4); /* error max = 0.018 avg = 0.0031 |avg| = 0.0031 */
x = improve_5throot_solution(x, arg4); x = improve_5throot_solution(x,
/* error max = 0.00021 avg = 1.6e-05 |avg| = 1.6e-05 */ arg4); /* error max = 0.00021 avg = 1.6e-05 |avg| = 1.6e-05 */
x = improve_5throot_solution(x, arg4); x = improve_5throot_solution(x,
/* error max = 6.1e-07 avg = 5.2e-08 |avg| = 1.1e-07 */ arg4); /* error max = 6.1e-07 avg = 5.2e-08 |avg| = 1.1e-07 */
x = improve_5throot_solution(x, arg4);
return x * (x * x); return x * (x * x);
} }

View File

@@ -129,7 +129,7 @@ class DebugFlags {
DEVICE_NONE, DEVICE_NONE,
/* All OpenCL devices will be used. */ /* All OpenCL devices will be used. */
DEVICE_ALL, DEVICE_ALL,
/* Default system OpenCL device will be used. */ /* Default system OpenCL device will be used. */
DEVICE_DEFAULT, DEVICE_DEFAULT,
/* Host processor will be used. */ /* Host processor will be used. */
DEVICE_CPU, DEVICE_CPU,

View File

@@ -243,7 +243,7 @@ ccl_device float fast_sinpif(float x)
const float P = 3.584135056f; /* P = 16-4*Q */ const float P = 3.584135056f; /* P = 16-4*Q */
return y * (Q + P * fabsf(y)); return y * (Q + P * fabsf(y));
/* The original article used inferior constants for Q and P and /* The original article used used inferior constants for Q and P and
* so had max error 1.091e-3. * so had max error 1.091e-3.
* *
* The optimal value for Q was determined by exhaustive search, minimizing * The optimal value for Q was determined by exhaustive search, minimizing

View File

@@ -282,8 +282,8 @@ static CPUCapabilities &system_cpu_capabilities()
/* actual opcode for xgetbv */ /* actual opcode for xgetbv */
__asm__(".byte 0x0f, 0x01, 0xd0" : "=a"(xcr_feature_mask), "=d"(edx) : "c"(0)); __asm__(".byte 0x0f, 0x01, 0xd0" : "=a"(xcr_feature_mask), "=d"(edx) : "c"(0));
# elif defined(_MSC_VER) && defined(_XCR_XFEATURE_ENABLED_MASK) # elif defined(_MSC_VER) && defined(_XCR_XFEATURE_ENABLED_MASK)
/* Minimum VS2010 SP1 compiler is required. */ xcr_feature_mask = (uint32_t)_xgetbv(
xcr_feature_mask = (uint32_t)_xgetbv(_XCR_XFEATURE_ENABLED_MASK); _XCR_XFEATURE_ENABLED_MASK); /* min VS2010 SP1 compiler is required */
# else # else
xcr_feature_mask = 0; xcr_feature_mask = 0;
# endif # endif

View File

@@ -68,7 +68,7 @@ class TaskPool {
/* ** Statistics ** */ /* ** Statistics ** */
/* Time stamp of first task pushed. */ /* Time time stamp of first task pushed. */
double start_time; double start_time;
/* Number of all tasks pushed to the pool. Cleared after wait_work() and cancel(). */ /* Number of all tasks pushed to the pool. Cleared after wait_work() and cancel(). */
@@ -88,7 +88,7 @@ class TaskScheduler {
/* Approximate number of threads that will work on task, which may be lower /* Approximate number of threads that will work on task, which may be lower
* or higher than the actual number of threads. Use as little as possible and * or higher than the actual number of threads. Use as little as possible and
* leave splitting up tasks to the scheduler. */ * leave splitting up tasks to the scheduler.. */
static int num_threads(); static int num_threads();
protected: protected:

View File

@@ -370,7 +370,6 @@ elseif(WIN32)
intern/GHOST_DropTargetWin32.cpp intern/GHOST_DropTargetWin32.cpp
intern/GHOST_SystemWin32.cpp intern/GHOST_SystemWin32.cpp
intern/GHOST_WindowWin32.cpp intern/GHOST_WindowWin32.cpp
intern/GHOST_Wintab.cpp
intern/GHOST_ContextD3D.h intern/GHOST_ContextD3D.h
intern/GHOST_DisplayManagerWin32.h intern/GHOST_DisplayManagerWin32.h
@@ -378,7 +377,6 @@ elseif(WIN32)
intern/GHOST_SystemWin32.h intern/GHOST_SystemWin32.h
intern/GHOST_TaskbarWin32.h intern/GHOST_TaskbarWin32.h
intern/GHOST_WindowWin32.h intern/GHOST_WindowWin32.h
intern/GHOST_Wintab.h
) )
if(NOT WITH_GL_EGL) if(NOT WITH_GL_EGL)
@@ -483,17 +481,10 @@ if(WITH_XR_OPENXR)
shlwapi shlwapi
) )
elseif(UNIX AND NOT APPLE) elseif(UNIX AND NOT APPLE)
list(APPEND XR_PLATFORM_DEFINES -DXR_OS_LINUX) list(APPEND XR_PLATFORM_DEFINES
if (WITH_GHOST_WAYLAND) -DXR_OS_LINUX
list(APPEND XR_PLATFORM_DEFINES -DXR_USE_PLATFORM_WAYLAND) -DXR_USE_PLATFORM_XLIB
endif() )
if (WITH_GHOST_X11)
if (WITH_GL_EGL)
list(APPEND XR_PLATFORM_DEFINES -DXR_USE_PLATFORM_EGL)
else()
list(APPEND XR_PLATFORM_DEFINES -DXR_USE_PLATFORM_XLIB)
endif()
endif()
endif() endif()
add_definitions(-DWITH_XR_OPENXR ${XR_PLATFORM_DEFINES}) add_definitions(-DWITH_XR_OPENXR ${XR_PLATFORM_DEFINES})

View File

@@ -95,7 +95,7 @@ class GHOST_ISystemPaths {
virtual void addToSystemRecentFiles(const char *filename) const = 0; virtual void addToSystemRecentFiles(const char *filename) const = 0;
private: private:
/** The one and only system paths. */ /** The one and only system paths*/
static GHOST_ISystemPaths *m_systemPaths; static GHOST_ISystemPaths *m_systemPaths;
#ifdef WITH_CXX_GUARDEDALLOC #ifdef WITH_CXX_GUARDEDALLOC

View File

@@ -105,9 +105,7 @@ typedef enum {
typedef enum { typedef enum {
GHOST_kTabletAutomatic = 0, GHOST_kTabletAutomatic = 0,
/* Show as Windows Ink to users to match "Use Windows Ink" in tablet utilities, GHOST_kTabletNative,
* but we use the dependent Windows Pointer API. */
GHOST_kTabletWinPointer,
GHOST_kTabletWintab, GHOST_kTabletWintab,
} GHOST_TTabletAPI; } GHOST_TTabletAPI;
@@ -170,7 +168,7 @@ typedef enum {
GHOST_kButtonMaskRight, GHOST_kButtonMaskRight,
GHOST_kButtonMaskButton4, GHOST_kButtonMaskButton4,
GHOST_kButtonMaskButton5, GHOST_kButtonMaskButton5,
/* Trackballs and programmable buttons. */ /* Trackballs and programmable buttons */
GHOST_kButtonMaskButton6, GHOST_kButtonMaskButton6,
GHOST_kButtonMaskButton7, GHOST_kButtonMaskButton7,
GHOST_kButtonNumMasks GHOST_kButtonNumMasks
@@ -179,15 +177,15 @@ typedef enum {
typedef enum { typedef enum {
GHOST_kEventUnknown = 0, GHOST_kEventUnknown = 0,
GHOST_kEventCursorMove, /* Mouse move event. */ GHOST_kEventCursorMove, /// Mouse move event
GHOST_kEventButtonDown, /* Mouse button event. */ GHOST_kEventButtonDown, /// Mouse button event
GHOST_kEventButtonUp, /* Mouse button event. */ GHOST_kEventButtonUp, /// Mouse button event
GHOST_kEventWheel, /* Mouse wheel event. */ GHOST_kEventWheel, /// Mouse wheel event
GHOST_kEventTrackpad, /* Trackpad event. */ GHOST_kEventTrackpad, /// Trackpad event
#ifdef WITH_INPUT_NDOF #ifdef WITH_INPUT_NDOF
GHOST_kEventNDOFMotion, /* N degree of freedom device motion event. */ GHOST_kEventNDOFMotion, /// N degree of freedom device motion event
GHOST_kEventNDOFButton, /* N degree of freedom device button event. */ GHOST_kEventNDOFButton, /// N degree of freedom device button event
#endif #endif
GHOST_kEventKeyDown, GHOST_kEventKeyDown,
@@ -209,8 +207,8 @@ typedef enum {
GHOST_kEventDraggingExited, GHOST_kEventDraggingExited,
GHOST_kEventDraggingDropDone, GHOST_kEventDraggingDropDone,
GHOST_kEventOpenMainFile, /* Needed for Cocoa to open double-clicked .blend file at startup. */ GHOST_kEventOpenMainFile, // Needed for Cocoa to open double-clicked .blend file at startup
GHOST_kEventNativeResolutionChange, /* Needed for Cocoa when window moves to other display. */ GHOST_kEventNativeResolutionChange, // Needed for Cocoa when window moves to other display
GHOST_kEventTimer, GHOST_kEventTimer,
@@ -283,7 +281,7 @@ typedef enum {
GHOST_kKeyPeriod = '.', GHOST_kKeyPeriod = '.',
GHOST_kKeySlash = '/', GHOST_kKeySlash = '/',
/* Number keys. */ // Number keys
GHOST_kKey0 = '0', GHOST_kKey0 = '0',
GHOST_kKey1, GHOST_kKey1,
GHOST_kKey2, GHOST_kKey2,
@@ -298,7 +296,7 @@ typedef enum {
GHOST_kKeySemicolon = ';', GHOST_kKeySemicolon = ';',
GHOST_kKeyEqual = '=', GHOST_kKeyEqual = '=',
/* Character keys. */ // Character keys
GHOST_kKeyA = 'A', GHOST_kKeyA = 'A',
GHOST_kKeyB, GHOST_kKeyB,
GHOST_kKeyC, GHOST_kKeyC,
@@ -337,9 +335,9 @@ typedef enum {
GHOST_kKeyRightControl, GHOST_kKeyRightControl,
GHOST_kKeyLeftAlt, GHOST_kKeyLeftAlt,
GHOST_kKeyRightAlt, GHOST_kKeyRightAlt,
GHOST_kKeyOS, /* Command key on Apple, Windows key(s) on Windows. */ GHOST_kKeyOS, // Command key on Apple, Windows key(s) on Windows
GHOST_kKeyGrLess, /* German PC only! */ GHOST_kKeyGrLess, // German PC only!
GHOST_kKeyApp, /* Also known as menu key. */ GHOST_kKeyApp, /* Also known as menu key. */
GHOST_kKeyCapsLock, GHOST_kKeyCapsLock,
GHOST_kKeyNumLock, GHOST_kKeyNumLock,
@@ -360,7 +358,7 @@ typedef enum {
GHOST_kKeyUpPage, GHOST_kKeyUpPage,
GHOST_kKeyDownPage, GHOST_kKeyDownPage,
/* Numpad keys. */ // Numpad keys
GHOST_kKeyNumpad0, GHOST_kKeyNumpad0,
GHOST_kKeyNumpad1, GHOST_kKeyNumpad1,
GHOST_kKeyNumpad2, GHOST_kKeyNumpad2,
@@ -378,7 +376,7 @@ typedef enum {
GHOST_kKeyNumpadAsterisk, GHOST_kKeyNumpadAsterisk,
GHOST_kKeyNumpadSlash, GHOST_kKeyNumpadSlash,
/* Function keys. */ // Function keys
GHOST_kKeyF1, GHOST_kKeyF1,
GHOST_kKeyF2, GHOST_kKeyF2,
GHOST_kKeyF3, GHOST_kKeyF3,
@@ -404,7 +402,7 @@ typedef enum {
GHOST_kKeyF23, GHOST_kKeyF23,
GHOST_kKeyF24, GHOST_kKeyF24,
/* Multimedia keypad buttons. */ // Multimedia keypad buttons
GHOST_kKeyMediaPlay, GHOST_kKeyMediaPlay,
GHOST_kKeyMediaStop, GHOST_kKeyMediaStop,
GHOST_kKeyMediaFirst, GHOST_kKeyMediaFirst,
@@ -481,9 +479,9 @@ typedef struct {
typedef enum { typedef enum {
GHOST_kDragnDropTypeUnknown = 0, GHOST_kDragnDropTypeUnknown = 0,
GHOST_kDragnDropTypeFilenames, /* Array of strings representing file names (full path). */ GHOST_kDragnDropTypeFilenames, /*Array of strings representing file names (full path) */
GHOST_kDragnDropTypeString, /* Unformatted text UTF-8 string. */ GHOST_kDragnDropTypeString, /* Unformatted text UTF-8 string */
GHOST_kDragnDropTypeBitmap /* Bitmap image data. */ GHOST_kDragnDropTypeBitmap /*Bitmap image data */
} GHOST_TDragnDropTypes; } GHOST_TDragnDropTypes;
typedef struct { typedef struct {
@@ -529,23 +527,18 @@ typedef enum {
#ifdef WITH_INPUT_NDOF #ifdef WITH_INPUT_NDOF
typedef struct { typedef struct {
/** N-degree of freedom device data v3 [GSoC 2010] */ /** N-degree of freedom device data v3 [GSoC 2010] */
/* Each component normally ranges from -1 to +1, but can exceed that. // Each component normally ranges from -1 to +1, but can exceed that.
* These use blender standard view coordinates, // These use blender standard view coordinates, with positive rotations being CCW about the axis.
* with positive rotations being CCW about the axis. */ float tx, ty, tz; // translation
/* translation: */ float rx, ry, rz; // rotation:
float tx, ty, tz; // axis = (rx,ry,rz).normalized
/* rotation: // amount = (rx,ry,rz).magnitude [in revolutions, 1.0 = 360 deg]
* - `axis = (rx,ry,rz).normalized` float dt; // time since previous NDOF Motion event
* - `amount = (rx,ry,rz).magnitude` [in revolutions, 1.0 = 360 deg]. */ GHOST_TProgress progress; // Starting, InProgress or Finishing (for modal handlers)
float rx, ry, rz;
/** Time since previous NDOF Motion event */
float dt;
/** Starting, #GHOST_kInProgress or #GHOST_kFinishing (for modal handlers) */
GHOST_TProgress progress;
} GHOST_TEventNDOFMotionData; } GHOST_TEventNDOFMotionData;
typedef enum { GHOST_kPress, GHOST_kRelease } GHOST_TButtonAction; typedef enum { GHOST_kPress, GHOST_kRelease } GHOST_TButtonAction;
/* Good for mouse or other buttons too, hmmm? */ // good for mouse or other buttons too, hmmm?
typedef struct { typedef struct {
GHOST_TButtonAction action; GHOST_TButtonAction action;
@@ -568,7 +561,7 @@ typedef struct {
*/ */
/** The ascii code for the key event ('\0' if none). */ /** The ascii code for the key event ('\0' if none). */
char ascii; char ascii;
/** The unicode character. if the length is 6, not NULL terminated if all 6 are set. */ /** The unicode character. if the length is 6, not NULL terminated if all 6 are set */
char utf8_buf[6]; char utf8_buf[6];
/** Generated by auto-repeat. */ /** Generated by auto-repeat. */
@@ -601,8 +594,7 @@ typedef void *GHOST_TEmbedderWindowID;
#endif // _WIN32 #endif // _WIN32
#ifndef _WIN32 #ifndef _WIN32
/* I can't use "Window" from `X11/Xlib.h` // I can't use "Window" from "<X11/Xlib.h>" because it conflits with Window defined in winlay.h
* because it conflicts with Window defined in `winlay.h`. */
typedef int GHOST_TEmbedderWindowID; typedef int GHOST_TEmbedderWindowID;
#endif // _WIN32 #endif // _WIN32
@@ -650,10 +642,8 @@ typedef void *(*GHOST_XrGraphicsContextBindFn)(void);
typedef void (*GHOST_XrGraphicsContextUnbindFn)(GHOST_ContextHandle graphics_context); typedef void (*GHOST_XrGraphicsContextUnbindFn)(GHOST_ContextHandle graphics_context);
typedef void (*GHOST_XrDrawViewFn)(const struct GHOST_XrDrawViewInfo *draw_view, void *customdata); typedef void (*GHOST_XrDrawViewFn)(const struct GHOST_XrDrawViewInfo *draw_view, void *customdata);
/** /* An array of GHOST_TXrGraphicsBinding items defining the candidate bindings to use. The first
* An array of #GHOST_TXrGraphicsBinding items defining the candidate bindings to use. * available candidate will be chosen, so order defines priority. */
* The first available candidate will be chosen, so order defines priority.
*/
typedef const GHOST_TXrGraphicsBinding *GHOST_XrGraphicsBindingCandidates; typedef const GHOST_TXrGraphicsBinding *GHOST_XrGraphicsBindingCandidates;
typedef struct { typedef struct {
@@ -694,7 +684,7 @@ typedef struct GHOST_XrDrawViewInfo {
float angle_up, angle_down; float angle_up, angle_down;
} fov; } fov;
/** Set if the buffer should be submitted with a SRGB transfer applied. */ /** Set if the buffer should be submitted with a srgb transfer applied. */
char expects_srgb_buffer; char expects_srgb_buffer;
} GHOST_XrDrawViewInfo; } GHOST_XrDrawViewInfo;
@@ -744,7 +734,7 @@ typedef struct GHOST_XrActionSpaceInfo {
typedef struct GHOST_XrActionBindingInfo { typedef struct GHOST_XrActionBindingInfo {
const char *action_name; const char *action_name;
GHOST_TUns32 count_interaction_paths; GHOST_TUns32 count_interaction_paths;
/** Interaction path: User (sub-action) path + component path. */ /** Interaction path: User (subaction) path + component path. */
const char **interaction_paths; const char **interaction_paths;
} GHOST_XrActionBindingInfo; } GHOST_XrActionBindingInfo;

View File

@@ -149,9 +149,6 @@ static bool egl_chk(bool result, const char *file = NULL, int line = 0, const ch
static_cast<unsigned int>(error), static_cast<unsigned int>(error),
code ? code : "<Unknown>", code ? code : "<Unknown>",
msg ? msg : "<Unknown>"); msg ? msg : "<Unknown>");
(void)(file);
(void)(line);
(void)(text);
#endif #endif
} }
@@ -202,8 +199,7 @@ template<typename T> T &choose_api(EGLenum api, T &a, T &b, T &c)
} }
} }
GHOST_ContextEGL::GHOST_ContextEGL(const GHOST_System *const system, GHOST_ContextEGL::GHOST_ContextEGL(bool stereoVisual,
bool stereoVisual,
EGLNativeWindowType nativeWindow, EGLNativeWindowType nativeWindow,
EGLNativeDisplayType nativeDisplay, EGLNativeDisplayType nativeDisplay,
EGLint contextProfileMask, EGLint contextProfileMask,
@@ -213,7 +209,6 @@ GHOST_ContextEGL::GHOST_ContextEGL(const GHOST_System *const system,
EGLint contextResetNotificationStrategy, EGLint contextResetNotificationStrategy,
EGLenum api) EGLenum api)
: GHOST_Context(stereoVisual), : GHOST_Context(stereoVisual),
m_system(system),
m_nativeDisplay(nativeDisplay), m_nativeDisplay(nativeDisplay),
m_nativeWindow(nativeWindow), m_nativeWindow(nativeWindow),
m_contextProfileMask(contextProfileMask), m_contextProfileMask(contextProfileMask),
@@ -290,21 +285,6 @@ GHOST_TSuccess GHOST_ContextEGL::getSwapInterval(int &intervalOut)
return GHOST_kSuccess; return GHOST_kSuccess;
} }
EGLDisplay GHOST_ContextEGL::getDisplay() const
{
return m_display;
}
EGLConfig GHOST_ContextEGL::getConfig() const
{
return m_config;
}
EGLContext GHOST_ContextEGL::getContext() const
{
return m_context;
}
GHOST_TSuccess GHOST_ContextEGL::activateDrawingContext() GHOST_TSuccess GHOST_ContextEGL::activateDrawingContext()
{ {
if (m_display) { if (m_display) {
@@ -476,7 +456,9 @@ GHOST_TSuccess GHOST_ContextEGL::initializeDrawingContext()
attrib_list.push_back(EGL_NONE); attrib_list.push_back(EGL_NONE);
if (!EGL_CHK(::eglChooseConfig(m_display, &(attrib_list[0]), &m_config, 1, &num_config))) EGLConfig config;
if (!EGL_CHK(::eglChooseConfig(m_display, &(attrib_list[0]), &config, 1, &num_config)))
goto error; goto error;
// A common error is to assume that ChooseConfig worked because it returned EGL_TRUE // A common error is to assume that ChooseConfig worked because it returned EGL_TRUE
@@ -484,7 +466,7 @@ GHOST_TSuccess GHOST_ContextEGL::initializeDrawingContext()
goto error; goto error;
if (m_nativeWindow != 0) { if (m_nativeWindow != 0) {
m_surface = ::eglCreateWindowSurface(m_display, m_config, m_nativeWindow, NULL); m_surface = ::eglCreateWindowSurface(m_display, config, m_nativeWindow, NULL);
} }
else { else {
static const EGLint pb_attrib_list[] = { static const EGLint pb_attrib_list[] = {
@@ -494,7 +476,7 @@ GHOST_TSuccess GHOST_ContextEGL::initializeDrawingContext()
1, 1,
EGL_NONE, EGL_NONE,
}; };
m_surface = ::eglCreatePbufferSurface(m_display, m_config, pb_attrib_list); m_surface = ::eglCreatePbufferSurface(m_display, config, pb_attrib_list);
} }
if (!EGL_CHK(m_surface != EGL_NO_SURFACE)) if (!EGL_CHK(m_surface != EGL_NO_SURFACE))
@@ -595,7 +577,7 @@ GHOST_TSuccess GHOST_ContextEGL::initializeDrawingContext()
attrib_list.push_back(EGL_NONE); attrib_list.push_back(EGL_NONE);
m_context = ::eglCreateContext(m_display, m_config, m_sharedContext, &(attrib_list[0])); m_context = ::eglCreateContext(m_display, config, m_sharedContext, &(attrib_list[0]));
if (!EGL_CHK(m_context != EGL_NO_CONTEXT)) if (!EGL_CHK(m_context != EGL_NO_CONTEXT))
goto error; goto error;

View File

@@ -24,7 +24,6 @@
#pragma once #pragma once
#include "GHOST_Context.h" #include "GHOST_Context.h"
#include "GHOST_System.h"
#include <GL/eglew.h> #include <GL/eglew.h>
@@ -37,15 +36,11 @@
#endif #endif
class GHOST_ContextEGL : public GHOST_Context { class GHOST_ContextEGL : public GHOST_Context {
/* XR code needs low level graphics data to send to OpenXR. */
friend class GHOST_XrGraphicsBindingOpenGL;
public: public:
/** /**
* Constructor. * Constructor.
*/ */
GHOST_ContextEGL(const GHOST_System *const system, GHOST_ContextEGL(bool stereoVisual,
bool stereoVisual,
EGLNativeWindowType nativeWindow, EGLNativeWindowType nativeWindow,
EGLNativeDisplayType nativeDisplay, EGLNativeDisplayType nativeDisplay,
EGLint contextProfileMask, EGLint contextProfileMask,
@@ -105,17 +100,9 @@ class GHOST_ContextEGL : public GHOST_Context {
*/ */
GHOST_TSuccess getSwapInterval(int &intervalOut); GHOST_TSuccess getSwapInterval(int &intervalOut);
EGLDisplay getDisplay() const;
EGLConfig getConfig() const;
EGLContext getContext() const;
private: private:
bool initContextEGLEW(); bool initContextEGLEW();
const GHOST_System *const m_system;
EGLNativeDisplayType m_nativeDisplay; EGLNativeDisplayType m_nativeDisplay;
EGLNativeWindowType m_nativeWindow; EGLNativeWindowType m_nativeWindow;
@@ -130,7 +117,6 @@ class GHOST_ContextEGL : public GHOST_Context {
EGLContext m_context; EGLContext m_context;
EGLSurface m_surface; EGLSurface m_surface;
EGLDisplay m_display; EGLDisplay m_display;
EGLConfig m_config;
EGLint m_swap_interval; EGLint m_swap_interval;

View File

@@ -124,7 +124,7 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext()
GHOST_X11_ERROR_HANDLERS_OVERRIDE(handler_store); GHOST_X11_ERROR_HANDLERS_OVERRIDE(handler_store);
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
/* Begin Inline Glew */ /* Begin Inline Glew */
#ifdef USE_GLXEW_INIT_WORKAROUND #ifdef USE_GLXEW_INIT_WORKAROUND
const GLubyte *extStart = (GLubyte *)""; const GLubyte *extStart = (GLubyte *)"";

View File

@@ -161,5 +161,5 @@ GHOST_TSuccess GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(
// CGDisplayErr err = ::CGDisplaySwitchToMode(m_displayIDs[display], displayModeValues); // CGDisplayErr err = ::CGDisplaySwitchToMode(m_displayIDs[display], displayModeValues);
return /* err == CGDisplayNoErr ? */ GHOST_kSuccess /* : GHOST_kFailure */; return /*err == CGDisplayNoErr ?*/ GHOST_kSuccess /*: GHOST_kFailure*/;
} }

View File

@@ -160,7 +160,7 @@ GHOST_TSuccess GHOST_DisplayManagerSDL::setCurrentDisplaySetting(
else { else {
/* this is a problem for the BGE player :S, perhaps SDL2 will resolve at some point. /* this is a problem for the BGE player :S, perhaps SDL2 will resolve at some point.
* we really need SDL_SetDisplayModeForDisplay() to become an API func! - campbell */ * we really need SDL_SetDisplayModeForDisplay() to become an API func! - campbell */
printf("no windows available, can't fullscreen\n"); printf("no windows available, cant fullscreen\n");
/* do not fail, we will try again later when the window is created - wander */ /* do not fail, we will try again later when the window is created - wander */
return GHOST_kSuccess; return GHOST_kSuccess;

View File

@@ -31,17 +31,10 @@ class GHOST_IXrGraphicsBinding {
public: public:
union { union {
#if defined(WITH_GHOST_X11) #if defined(WITH_GHOST_X11)
# if defined(WITH_GL_EGL)
XrGraphicsBindingEGLMNDX egl;
# else
XrGraphicsBindingOpenGLXlibKHR glx; XrGraphicsBindingOpenGLXlibKHR glx;
# endif
#elif defined(WIN32) #elif defined(WIN32)
XrGraphicsBindingOpenGLWin32KHR wgl; XrGraphicsBindingOpenGLWin32KHR wgl;
XrGraphicsBindingD3D11KHR d3d11; XrGraphicsBindingD3D11KHR d3d11;
#endif
#if defined(WITH_GHOST_WAYLAND)
XrGraphicsBindingOpenGLWaylandKHR wl;
#endif #endif
} oxr_binding; } oxr_binding;

View File

@@ -239,7 +239,7 @@ class GHOST_System : public GHOST_ISystem {
* Set which tablet API to use. Only affects Windows, other platforms have a single API. * Set which tablet API to use. Only affects Windows, other platforms have a single API.
* \param api: Enum indicating which API to use. * \param api: Enum indicating which API to use.
*/ */
virtual void setTabletAPI(GHOST_TTabletAPI api); void setTabletAPI(GHOST_TTabletAPI api);
GHOST_TTabletAPI getTabletAPI(void); GHOST_TTabletAPI getTabletAPI(void);
#ifdef WITH_INPUT_NDOF #ifdef WITH_INPUT_NDOF
@@ -328,8 +328,8 @@ class GHOST_System : public GHOST_ISystem {
*/ */
virtual GHOST_TSuccess showMessageBox(const char * /*title*/, virtual GHOST_TSuccess showMessageBox(const char * /*title*/,
const char * /*message*/, const char * /*message*/,
const char * /*help_label*/, const char * /*help_label */,
const char * /*continue_label*/, const char * /*continue_label */,
const char * /*link*/, const char * /*link*/,
GHOST_DialogOptions /*dialog_options*/) const GHOST_DialogOptions /*dialog_options*/) const
{ {

View File

@@ -32,7 +32,11 @@
#include "GHOST_WindowCocoa.h" #include "GHOST_WindowCocoa.h"
#include "GHOST_WindowManager.h" #include "GHOST_WindowManager.h"
#include "GHOST_ContextCGL.h" #if defined(WITH_GL_EGL)
# include "GHOST_ContextEGL.h"
#else
# include "GHOST_ContextCGL.h"
#endif
#ifdef WITH_INPUT_NDOF #ifdef WITH_INPUT_NDOF
# include "GHOST_NDOFManagerCocoa.h" # include "GHOST_NDOFManagerCocoa.h"
@@ -86,8 +90,7 @@ static GHOST_TKey convertKey(int rawCode, unichar recvChar, UInt16 keyAction)
{ {
// printf("\nrecvchar %c 0x%x",recvChar,recvChar); // printf("\nrecvchar %c 0x%x",recvChar,recvChar);
switch (rawCode) { switch (rawCode) {
/* Physical key-codes: (not used due to map changes in int'l keyboards). */ /*Physical keycodes not used due to map changes in int'l keyboards
#if 0
case kVK_ANSI_A: return GHOST_kKeyA; case kVK_ANSI_A: return GHOST_kKeyA;
case kVK_ANSI_B: return GHOST_kKeyB; case kVK_ANSI_B: return GHOST_kKeyB;
case kVK_ANSI_C: return GHOST_kKeyC; case kVK_ANSI_C: return GHOST_kKeyC;
@@ -113,9 +116,9 @@ static GHOST_TKey convertKey(int rawCode, unichar recvChar, UInt16 keyAction)
case kVK_ANSI_W: return GHOST_kKeyW; case kVK_ANSI_W: return GHOST_kKeyW;
case kVK_ANSI_X: return GHOST_kKeyX; case kVK_ANSI_X: return GHOST_kKeyX;
case kVK_ANSI_Y: return GHOST_kKeyY; case kVK_ANSI_Y: return GHOST_kKeyY;
case kVK_ANSI_Z: return GHOST_kKeyZ; case kVK_ANSI_Z: return GHOST_kKeyZ;*/
#endif
/* Numbers keys: mapped to handle some int'l keyboard (e.g. French). */ /* Numbers keys mapped to handle some int'l keyboard (e.g. French)*/
case kVK_ISO_Section: case kVK_ISO_Section:
return GHOST_kKeyUnknown; return GHOST_kKeyUnknown;
case kVK_ANSI_1: case kVK_ANSI_1:
@@ -245,8 +248,8 @@ static GHOST_TKey convertKey(int rawCode, unichar recvChar, UInt16 keyAction)
return GHOST_kKeyUpPage; return GHOST_kKeyUpPage;
case kVK_PageDown: case kVK_PageDown:
return GHOST_kKeyDownPage; return GHOST_kKeyDownPage;
#if 0 /* TODO: why are these commented? */
case kVK_ANSI_Minus: return GHOST_kKeyMinus; /*case kVK_ANSI_Minus: return GHOST_kKeyMinus;
case kVK_ANSI_Equal: return GHOST_kKeyEqual; case kVK_ANSI_Equal: return GHOST_kKeyEqual;
case kVK_ANSI_Comma: return GHOST_kKeyComma; case kVK_ANSI_Comma: return GHOST_kKeyComma;
case kVK_ANSI_Period: return GHOST_kKeyPeriod; case kVK_ANSI_Period: return GHOST_kKeyPeriod;
@@ -256,15 +259,15 @@ static GHOST_TKey convertKey(int rawCode, unichar recvChar, UInt16 keyAction)
case kVK_ANSI_Backslash: return GHOST_kKeyBackslash; case kVK_ANSI_Backslash: return GHOST_kKeyBackslash;
case kVK_ANSI_LeftBracket: return GHOST_kKeyLeftBracket; case kVK_ANSI_LeftBracket: return GHOST_kKeyLeftBracket;
case kVK_ANSI_RightBracket: return GHOST_kKeyRightBracket; case kVK_ANSI_RightBracket: return GHOST_kKeyRightBracket;
case kVK_ANSI_Grave: return GHOST_kKeyAccentGrave; case kVK_ANSI_Grave: return GHOST_kKeyAccentGrave;*/
#endif
case kVK_VolumeUp: case kVK_VolumeUp:
case kVK_VolumeDown: case kVK_VolumeDown:
case kVK_Mute: case kVK_Mute:
return GHOST_kKeyUnknown; return GHOST_kKeyUnknown;
default: { default: {
/* Alphanumerical or punctuation key that is remappable in int'l keyboards. */ /* alphanumerical or punctuation key that is remappable in int'l keyboards */
if ((recvChar >= 'A') && (recvChar <= 'Z')) { if ((recvChar >= 'A') && (recvChar <= 'Z')) {
return (GHOST_TKey)(recvChar - 'A' + GHOST_kKeyA); return (GHOST_TKey)(recvChar - 'A' + GHOST_kKeyA);
} }
@@ -272,8 +275,8 @@ static GHOST_TKey convertKey(int rawCode, unichar recvChar, UInt16 keyAction)
return (GHOST_TKey)(recvChar - 'a' + GHOST_kKeyA); return (GHOST_TKey)(recvChar - 'a' + GHOST_kKeyA);
} }
else { else {
/* Leopard and Snow Leopard 64bit compatible API. */ /* Leopard and Snow Leopard 64bit compatible API*/
CFDataRef uchrHandle; /* The keyboard layout. */ CFDataRef uchrHandle; /*the keyboard layout*/
TISInputSourceRef kbdTISHandle; TISInputSourceRef kbdTISHandle;
kbdTISHandle = TISCopyCurrentKeyboardLayoutInputSource(); kbdTISHandle = TISCopyCurrentKeyboardLayoutInputSource();
@@ -281,9 +284,9 @@ static GHOST_TKey convertKey(int rawCode, unichar recvChar, UInt16 keyAction)
kTISPropertyUnicodeKeyLayoutData); kTISPropertyUnicodeKeyLayoutData);
CFRelease(kbdTISHandle); CFRelease(kbdTISHandle);
/* Get actual character value of the "remappable" keys in int'l keyboards, /*get actual character value of the "remappable" keys in int'l keyboards,
* if keyboard layout is not correctly reported (e.g. some non Apple keyboards in Tiger), if keyboard layout is not correctly reported (e.g. some non Apple keyboards in Tiger),
* then fallback on using the received #charactersIgnoringModifiers. */ then fallback on using the received charactersIgnoringModifiers */
if (uchrHandle) { if (uchrHandle) {
UInt32 deadKeyState = 0; UInt32 deadKeyState = 0;
UniCharCount actualStrLength = 0; UniCharCount actualStrLength = 0;
@@ -434,10 +437,8 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG])
// So WM_exit needs to be called directly, as the event loop will never run before termination // So WM_exit needs to be called directly, as the event loop will never run before termination
- (void)applicationWillTerminate:(NSNotification *)aNotification - (void)applicationWillTerminate:(NSNotification *)aNotification
{ {
#if 0 /*G.is_break = FALSE; //Let Cocoa perform the termination at the end
G.is_break = false; /* Let Cocoa perform the termination at the end. */ WM_exit(C);*/
WM_exit(C);
#endif
} }
- (void)applicationWillBecomeActive:(NSNotification *)aNotification - (void)applicationWillBecomeActive:(NSNotification *)aNotification
@@ -552,12 +553,10 @@ GHOST_TSuccess GHOST_SystemCocoa::init()
// ProcessSerialNumber psn; // ProcessSerialNumber psn;
// Carbon stuff to move window & menu to foreground // Carbon stuff to move window & menu to foreground
#if 0 /*if (!GetCurrentProcess(&psn)) {
if (!GetCurrentProcess(&psn)) {
TransformProcessType(&psn, kProcessTransformToForegroundApplication); TransformProcessType(&psn, kProcessTransformToForegroundApplication);
SetFrontProcess(&psn); SetFrontProcess(&psn);
} }*/
#endif
@autoreleasepool { @autoreleasepool {
[NSApplication sharedApplication]; // initializes NSApp [NSApplication sharedApplication]; // initializes NSApp
@@ -1218,7 +1217,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType
return GHOST_kFailure; return GHOST_kFailure;
} }
/* Get the bitmap of the image. */ /*Get the bitmap of the image*/
enumerator = [[droppedImg representations] objectEnumerator]; enumerator = [[droppedImg representations] objectEnumerator];
while ((representation = [enumerator nextObject])) { while ((representation = [enumerator nextObject])) {
if ([representation isKindOfClass:[NSBitmapImageRep class]]) { if ([representation isKindOfClass:[NSBitmapImageRep class]]) {
@@ -1231,7 +1230,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType
if (([bitmapImage bitsPerPixel] == 32) && (([bitmapImage bitmapFormat] & 0x5) == 0) && if (([bitmapImage bitsPerPixel] == 32) && (([bitmapImage bitmapFormat] & 0x5) == 0) &&
![bitmapImage isPlanar]) { ![bitmapImage isPlanar]) {
/* Try a fast copy if the image is a meshed RGBA 32bit bitmap. */ /* Try a fast copy if the image is a meshed RGBA 32bit bitmap*/
toIBuf = (GHOST_TUns8 *)ibuf->rect; toIBuf = (GHOST_TUns8 *)ibuf->rect;
rasterRGB = (GHOST_TUns8 *)[bitmapImage bitmapData]; rasterRGB = (GHOST_TUns8 *)[bitmapImage bitmapData];
for (y = 0; y < imgSize.height; y++) { for (y = 0; y < imgSize.height; y++) {
@@ -1261,7 +1260,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType
colorSpaceName:NSDeviceRGBColorSpace colorSpaceName:NSDeviceRGBColorSpace
bitmapFormat:(NSBitmapFormat)0 bitmapFormat:(NSBitmapFormat)0
bytesPerRow:4 * imgSize.width bytesPerRow:4 * imgSize.width
bitsPerPixel:32 /* RGB format padded to 32bits. */]; bitsPerPixel:32 /*RGB format padded to 32bits*/];
[NSGraphicsContext saveGraphicsState]; [NSGraphicsContext saveGraphicsState];
[NSGraphicsContext [NSGraphicsContext
@@ -1308,7 +1307,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType
return GHOST_kFailure; return GHOST_kFailure;
} }
/* Copy the image to ibuf, flipping it vertically. */ /*Copy the image to ibuf, flipping it vertically*/
toIBuf = (GHOST_TUns8 *)ibuf->rect; toIBuf = (GHOST_TUns8 *)ibuf->rect;
for (y = 0; y < imgSize.height; y++) { for (y = 0; y < imgSize.height; y++) {
for (x = 0; x < imgSize.width; x++) { for (x = 0; x < imgSize.width; x++) {

View File

@@ -376,7 +376,7 @@ void GHOST_SystemSDL::processEvent(SDL_Event *sdl_event)
bounds.wrapPoint(x_new, y_new, 8, window->getCursorGrabAxis()); bounds.wrapPoint(x_new, y_new, 8, window->getCursorGrabAxis());
window->getCursorGrabAccum(x_accum, y_accum); window->getCursorGrabAccum(x_accum, y_accum);
// can't use setCursorPosition because the mouse may have no focus! // cant use setCursorPosition because the mouse may have no focus!
if (x_new != x_root || y_new != y_root) { if (x_new != x_root || y_new != y_root) {
if (1) { //xme.time > m_last_warp) { if (1) { //xme.time > m_last_warp) {
/* when wrapping we don't need to add an event because the /* when wrapping we don't need to add an event because the

View File

@@ -1590,36 +1590,15 @@ GHOST_IContext *GHOST_SystemWayland::createOffscreenContext(GHOST_GLSettings /*g
d->os_surfaces.push_back(os_surface); d->os_surfaces.push_back(os_surface);
d->os_egl_windows.push_back(os_egl_window); d->os_egl_windows.push_back(os_egl_window);
GHOST_Context *context; GHOST_Context *context = new GHOST_ContextEGL(false,
EGLNativeWindowType(os_egl_window),
for (int minor = 6; minor >= 0; --minor) { EGLNativeDisplayType(d->display),
context = new GHOST_ContextEGL(this, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
false, 3,
EGLNativeWindowType(os_egl_window), 3,
EGLNativeDisplayType(d->display), GHOST_OPENGL_EGL_CONTEXT_FLAGS,
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT, GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
4, EGL_OPENGL_API);
minor,
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
EGL_OPENGL_API);
if (context->initializeDrawingContext())
return context;
else
delete context;
}
context = new GHOST_ContextEGL(this,
false,
EGLNativeWindowType(os_egl_window),
EGLNativeDisplayType(d->display),
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
3,
3,
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
EGL_OPENGL_API);
if (context->initializeDrawingContext()) { if (context->initializeDrawingContext()) {
return context; return context;

View File

@@ -50,7 +50,11 @@
#include "GHOST_WindowManager.h" #include "GHOST_WindowManager.h"
#include "GHOST_WindowWin32.h" #include "GHOST_WindowWin32.h"
#include "GHOST_ContextWGL.h" #if defined(WITH_GL_EGL)
# include "GHOST_ContextEGL.h"
#else
# include "GHOST_ContextWGL.h"
#endif
#ifdef WITH_INPUT_NDOF #ifdef WITH_INPUT_NDOF
# include "GHOST_NDOFManagerWin32.h" # include "GHOST_NDOFManagerWin32.h"
@@ -862,159 +866,23 @@ GHOST_EventButton *GHOST_SystemWin32::processButtonEvent(GHOST_TEventType type,
{ {
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
GHOST_TabletData td = window->getTabletData(); if (type == GHOST_kEventButtonDown) {
window->updateMouseCapture(MousePressed);
/* Move mouse to button event position. */ }
if (window->getTabletData().Active != GHOST_kTabletModeNone) { else if (type == GHOST_kEventButtonUp) {
/* Tablet should be handling in between mouse moves, only move to event position. */ window->updateMouseCapture(MouseReleased);
DWORD msgPos = ::GetMessagePos();
int msgPosX = GET_X_LPARAM(msgPos);
int msgPosY = GET_Y_LPARAM(msgPos);
system->pushEvent(new GHOST_EventCursor(
::GetMessageTime(), GHOST_kEventCursorMove, window, msgPosX, msgPosY, td));
} }
window->updateMouseCapture(type == GHOST_kEventButtonDown ? MousePressed : MouseReleased); return new GHOST_EventButton(
return new GHOST_EventButton(system->getMilliSeconds(), type, window, mask, td); system->getMilliSeconds(), type, window, mask, window->getTabletData());
}
void GHOST_SystemWin32::processWintabEvent(GHOST_WindowWin32 *window)
{
GHOST_Wintab *wt = window->getWintab();
if (!wt) {
return;
}
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
std::vector<GHOST_WintabInfoWin32> wintabInfo;
wt->getInput(wintabInfo);
/* Wintab provided coordinates are untrusted until a Wintab and Win32 button down event match.
* This is checked on every button down event, and revoked if there is a mismatch. This can
* happen when Wintab incorrectly scales cursor position or is in mouse mode.
*
* If Wintab was never trusted while processing this Win32 event, a fallback Ghost cursor move
* event is created at the position of the Win32 WT_PACKET event. */
bool mouseMoveHandled;
bool useWintabPos;
mouseMoveHandled = useWintabPos = wt->trustCoordinates();
for (GHOST_WintabInfoWin32 &info : wintabInfo) {
switch (info.type) {
case GHOST_kEventCursorMove: {
if (!useWintabPos) {
continue;
}
wt->mapWintabToSysCoordinates(info.x, info.y, info.x, info.y);
system->pushEvent(new GHOST_EventCursor(
info.time, GHOST_kEventCursorMove, window, info.x, info.y, info.tabletData));
break;
}
case GHOST_kEventButtonDown: {
UINT message;
switch (info.button) {
case GHOST_kButtonMaskLeft:
message = WM_LBUTTONDOWN;
break;
case GHOST_kButtonMaskRight:
message = WM_RBUTTONDOWN;
break;
case GHOST_kButtonMaskMiddle:
message = WM_MBUTTONDOWN;
break;
default:
continue;
}
/* Wintab buttons are modal, but the API does not inform us what mode a pressed button is
* in. Only issue button events if we can steal an equivalent Win32 button event from the
* event queue. */
MSG msg;
if (PeekMessage(&msg, window->getHWND(), message, message, PM_NOYIELD) &&
msg.message != WM_QUIT) {
/* Test for Win32/Wintab button down match. */
useWintabPos = wt->testCoordinates(msg.pt.x, msg.pt.y, info.x, info.y);
if (!useWintabPos) {
continue;
}
/* Steal the Win32 event which was previously peeked. */
PeekMessage(&msg, window->getHWND(), message, message, PM_REMOVE | PM_NOYIELD);
/* Move cursor to button location, to prevent incorrect cursor position when
* transitioning from unsynchronized Win32 to Wintab cursor control. */
wt->mapWintabToSysCoordinates(info.x, info.y, info.x, info.y);
system->pushEvent(new GHOST_EventCursor(
info.time, GHOST_kEventCursorMove, window, info.x, info.y, info.tabletData));
window->updateMouseCapture(MousePressed);
system->pushEvent(
new GHOST_EventButton(info.time, info.type, window, info.button, info.tabletData));
mouseMoveHandled = true;
break;
}
}
case GHOST_kEventButtonUp: {
if (!useWintabPos) {
continue;
}
UINT message;
switch (info.button) {
case GHOST_kButtonMaskLeft:
message = WM_LBUTTONUP;
break;
case GHOST_kButtonMaskRight:
message = WM_RBUTTONUP;
break;
case GHOST_kButtonMaskMiddle:
message = WM_MBUTTONUP;
break;
default:
continue;
}
/* Wintab buttons are modal, but the API does not inform us what mode a pressed button is
* in. Only issue button events if we can steal an equivalent Win32 button event from the
* event queue. */
MSG msg;
if (PeekMessage(&msg, window->getHWND(), message, message, PM_REMOVE | PM_NOYIELD) &&
msg.message != WM_QUIT) {
window->updateMouseCapture(MouseReleased);
system->pushEvent(
new GHOST_EventButton(info.time, info.type, window, info.button, info.tabletData));
}
break;
}
default:
break;
}
}
/* Fallback cursor movement if Wintab position were never trusted while processing this event. */
if (!mouseMoveHandled) {
DWORD pos = GetMessagePos();
int x = GET_X_LPARAM(pos);
int y = GET_Y_LPARAM(pos);
/* TODO supply tablet data */
system->pushEvent(new GHOST_EventCursor(
system->getMilliSeconds(), GHOST_kEventCursorMove, window, x, y, GHOST_TABLET_DATA_NONE));
}
} }
void GHOST_SystemWin32::processPointerEvent( void GHOST_SystemWin32::processPointerEvent(
UINT type, GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam, bool &eventHandled) UINT type, GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam, bool &eventHandled)
{ {
/* Pointer events might fire when changing windows for a device which is set to use Wintab, /* Pointer events might fire when changing windows for a device which is set to use Wintab, even
* even when Wintab is left enabled but set to the bottom of Wintab overlap order. */ * when when Wintab is left enabled but set to the bottom of Wintab overlap order. */
if (!window->usingTabletAPI(GHOST_kTabletWinPointer)) { if (!window->useTabletAPI(GHOST_kTabletNative)) {
return; return;
} }
@@ -1025,21 +893,20 @@ void GHOST_SystemWin32::processPointerEvent(
return; return;
} }
if (!pointerInfo[0].isPrimary) {
eventHandled = true;
return; // For multi-touch displays we ignore these events
}
switch (type) { switch (type) {
case WM_POINTERUPDATE: case WM_POINTERENTER:
/* Coalesced pointer events are reverse chronological order, reorder chronologically. window->m_tabletInRange = true;
* Only contiguous move events are coalesced. */ system->pushEvent(new GHOST_EventCursor(pointerInfo[0].time,
for (GHOST_TUns32 i = pointerInfo.size(); i-- > 0;) { GHOST_kEventCursorMove,
system->pushEvent(new GHOST_EventCursor(pointerInfo[i].time, window,
GHOST_kEventCursorMove, pointerInfo[0].pixelLocation.x,
window, pointerInfo[0].pixelLocation.y,
pointerInfo[i].pixelLocation.x, pointerInfo[0].tabletData));
pointerInfo[i].pixelLocation.y,
pointerInfo[i].tabletData));
}
/* Leave event unhandled so that system cursor is moved. */
break; break;
case WM_POINTERDOWN: case WM_POINTERDOWN:
/* Move cursor to point of contact because GHOST_EventButton does not include position. */ /* Move cursor to point of contact because GHOST_EventButton does not include position. */
@@ -1055,10 +922,18 @@ void GHOST_SystemWin32::processPointerEvent(
pointerInfo[0].buttonMask, pointerInfo[0].buttonMask,
pointerInfo[0].tabletData)); pointerInfo[0].tabletData));
window->updateMouseCapture(MousePressed); window->updateMouseCapture(MousePressed);
break;
/* Mark event handled so that mouse button events are not generated. */ case WM_POINTERUPDATE:
eventHandled = true; /* Coalesced pointer events are reverse chronological order, reorder chronologically.
* Only contiguous move events are coalesced. */
for (GHOST_TUns32 i = pointerInfo.size(); i-- > 0;) {
system->pushEvent(new GHOST_EventCursor(pointerInfo[i].time,
GHOST_kEventCursorMove,
window,
pointerInfo[i].pixelLocation.x,
pointerInfo[i].pixelLocation.y,
pointerInfo[i].tabletData));
}
break; break;
case WM_POINTERUP: case WM_POINTERUP:
system->pushEvent(new GHOST_EventButton(pointerInfo[0].time, system->pushEvent(new GHOST_EventButton(pointerInfo[0].time,
@@ -1067,14 +942,16 @@ void GHOST_SystemWin32::processPointerEvent(
pointerInfo[0].buttonMask, pointerInfo[0].buttonMask,
pointerInfo[0].tabletData)); pointerInfo[0].tabletData));
window->updateMouseCapture(MouseReleased); window->updateMouseCapture(MouseReleased);
break;
/* Mark event handled so that mouse button events are not generated. */ case WM_POINTERLEAVE:
eventHandled = true; window->m_tabletInRange = false;
break; break;
default: default:
break; break;
} }
eventHandled = true;
system->setCursorPosition(pointerInfo[0].pixelLocation.x, pointerInfo[0].pixelLocation.y);
} }
GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *window) GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *window)
@@ -1082,14 +959,18 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind
GHOST_TInt32 x_screen, y_screen; GHOST_TInt32 x_screen, y_screen;
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
if (window->getTabletData().Active != GHOST_kTabletModeNone) { if (window->m_tabletInRange) {
/* While pen devices are in range, cursor movement is handled by tablet input processing. */ if (window->useTabletAPI(GHOST_kTabletNative)) {
return NULL; /* Tablet input handled in WM_POINTER* events. WM_MOUSEMOVE events in response to tablet
* input aren't normally generated when using WM_POINTER events, but manually moving the
* system cursor as we do in WM_POINTER handling does. */
return NULL;
}
} }
system->getCursorPosition(x_screen, y_screen); system->getCursorPosition(x_screen, y_screen);
if (window->getCursorGrabModeIsWarp()) { if (window->getCursorGrabModeIsWarp() && !window->m_tabletInRange) {
GHOST_TInt32 x_new = x_screen; GHOST_TInt32 x_new = x_screen;
GHOST_TInt32 y_new = y_screen; GHOST_TInt32 y_new = y_screen;
GHOST_TInt32 x_accum, y_accum; GHOST_TInt32 x_accum, y_accum;
@@ -1101,7 +982,7 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind
} }
/* Could also clamp to screen bounds wrap with a window outside the view will fail atm. /* Could also clamp to screen bounds wrap with a window outside the view will fail atm.
* Use inset in case the window is at screen bounds. */ * Use offset of 8 in case the window is at screen bounds. */
bounds.wrapPoint(x_new, y_new, 2, window->getCursorGrabAxis()); bounds.wrapPoint(x_new, y_new, 2, window->getCursorGrabAxis());
window->getCursorGrabAccum(x_accum, y_accum); window->getCursorGrabAccum(x_accum, y_accum);
@@ -1117,7 +998,7 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind
window, window,
x_screen + x_accum, x_screen + x_accum,
y_screen + y_accum, y_screen + y_accum,
GHOST_TABLET_DATA_NONE); window->getTabletData());
} }
} }
else { else {
@@ -1126,7 +1007,7 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind
window, window,
x_screen, x_screen,
y_screen, y_screen,
GHOST_TABLET_DATA_NONE); window->getTabletData());
} }
return NULL; return NULL;
} }
@@ -1236,23 +1117,6 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RA
return event; return event;
} }
GHOST_Event *GHOST_SystemWin32::processWindowSizeEvent(GHOST_WindowWin32 *window)
{
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
GHOST_Event *sizeEvent = new GHOST_Event(
system->getMilliSeconds(), GHOST_kEventWindowSize, window);
/* We get WM_SIZE before we fully init. Do not dispatch before we are continuously resizing. */
if (window->m_inLiveResize) {
system->pushEvent(sizeEvent);
system->dispatchEvents();
return NULL;
}
else {
return sizeEvent;
}
}
GHOST_Event *GHOST_SystemWin32::processWindowEvent(GHOST_TEventType type, GHOST_Event *GHOST_SystemWin32::processWindowEvent(GHOST_TEventType type,
GHOST_WindowWin32 *window) GHOST_WindowWin32 *window)
{ {
@@ -1260,6 +1124,7 @@ GHOST_Event *GHOST_SystemWin32::processWindowEvent(GHOST_TEventType type,
if (type == GHOST_kEventWindowActivate) { if (type == GHOST_kEventWindowActivate) {
system->getWindowManager()->setActiveWindow(window); system->getWindowManager()->setActiveWindow(window);
window->bringTabletContextToFront();
} }
return new GHOST_Event(system->getMilliSeconds(), type, window); return new GHOST_Event(system->getMilliSeconds(), type, window);
@@ -1287,31 +1152,6 @@ GHOST_TSuccess GHOST_SystemWin32::pushDragDropEvent(GHOST_TEventType eventType,
system->getMilliSeconds(), eventType, draggedObjectType, window, mouseX, mouseY, data)); system->getMilliSeconds(), eventType, draggedObjectType, window, mouseX, mouseY, data));
} }
void GHOST_SystemWin32::setTabletAPI(GHOST_TTabletAPI api)
{
GHOST_System::setTabletAPI(api);
/* If API is set to WinPointer (Windows Ink), unload Wintab so that trouble drivers don't disable
* Windows Ink. Load Wintab when API is Automatic because decision logic relies on knowing
* whether a Wintab device is present. */
const bool loadWintab = GHOST_kTabletWinPointer != api;
GHOST_WindowManager *wm = getWindowManager();
for (GHOST_IWindow *win : wm->getWindows()) {
GHOST_WindowWin32 *windowWin32 = (GHOST_WindowWin32 *)win;
if (loadWintab) {
windowWin32->loadWintab(GHOST_kWindowStateMinimized != windowWin32->getState());
if (windowWin32->usingTabletAPI(GHOST_kTabletWintab)) {
windowWin32->resetPointerPenInfo();
}
}
else {
windowWin32->closeWintab();
}
}
}
void GHOST_SystemWin32::processMinMaxInfo(MINMAXINFO *minmax) void GHOST_SystemWin32::processMinMaxInfo(MINMAXINFO *minmax)
{ {
minmax->ptMinTrackSize.x = 320; minmax->ptMinTrackSize.x = 320;
@@ -1503,7 +1343,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
case WM_SYSKEYDOWN: case WM_SYSKEYDOWN:
case WM_KEYUP: case WM_KEYUP:
case WM_SYSKEYUP: case WM_SYSKEYUP:
/* These functions were replaced by #WM_INPUT. */ /* These functions were replaced by WM_INPUT*/
case WM_CHAR: case WM_CHAR:
/* The WM_CHAR message is posted to the window with the keyboard focus when /* The WM_CHAR message is posted to the window with the keyboard focus when
* a WM_KEYDOWN message is translated by the TranslateMessage function. WM_CHAR * a WM_KEYDOWN message is translated by the TranslateMessage function. WM_CHAR
@@ -1546,100 +1386,33 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
case SC_KEYMENU: case SC_KEYMENU:
eventHandled = true; eventHandled = true;
break; break;
case SC_RESTORE: { case SC_RESTORE:
::ShowWindow(hwnd, SW_RESTORE); ::ShowWindow(hwnd, SW_RESTORE);
window->setState(window->getState()); window->setState(window->getState());
GHOST_Wintab *wt = window->getWintab();
if (wt) {
wt->enable();
}
eventHandled = true; eventHandled = true;
break; break;
}
case SC_MAXIMIZE: {
GHOST_Wintab *wt = window->getWintab();
if (wt) {
wt->enable();
}
/* Don't report event as handled so that default handling occurs. */
break;
}
case SC_MINIMIZE: {
GHOST_Wintab *wt = window->getWintab();
if (wt) {
wt->disable();
}
/* Don't report event as handled so that default handling occurs. */
break;
}
} }
break; break;
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Wintab events, processed // Wintab events, processed
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
case WT_CSRCHANGE: {
GHOST_Wintab *wt = window->getWintab();
if (wt) {
wt->updateCursorInfo();
}
eventHandled = true;
break;
}
case WT_PROXIMITY: {
GHOST_Wintab *wt = window->getWintab();
if (wt) {
bool inRange = LOWORD(lParam);
if (inRange) {
/* Some devices don't emit WT_CSRCHANGE events, so update cursor info here. */
wt->updateCursorInfo();
}
else {
wt->leaveRange();
}
}
eventHandled = true;
break;
}
case WT_INFOCHANGE: {
GHOST_Wintab *wt = window->getWintab();
if (wt) {
wt->processInfoChange(lParam);
if (window->usingTabletAPI(GHOST_kTabletWintab)) {
window->resetPointerPenInfo();
}
}
eventHandled = true;
break;
}
case WT_PACKET: case WT_PACKET:
processWintabEvent(window); window->processWin32TabletEvent(wParam, lParam);
eventHandled = true; break;
case WT_CSRCHANGE:
case WT_PROXIMITY:
window->processWin32TabletInitEvent();
break; break;
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Pointer events, processed // Pointer events, processed
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
case WM_POINTERUPDATE: case WM_POINTERENTER:
case WM_POINTERDOWN: case WM_POINTERDOWN:
case WM_POINTERUPDATE:
case WM_POINTERUP: case WM_POINTERUP:
case WM_POINTERLEAVE:
processPointerEvent(msg, window, wParam, lParam, eventHandled); processPointerEvent(msg, window, wParam, lParam, eventHandled);
break; break;
case WM_POINTERLEAVE: {
GHOST_TUns32 pointerId = GET_POINTERID_WPARAM(wParam);
POINTER_INFO pointerInfo;
if (!GetPointerInfo(pointerId, &pointerInfo)) {
break;
}
/* Reset pointer pen info if pen device has left tracking range. */
if (pointerInfo.pointerType == PT_PEN && !IS_POINTER_INRANGE_WPARAM(wParam)) {
window->resetPointerPenInfo();
eventHandled = true;
}
break;
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Mouse events, processed // Mouse events, processed
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@@ -1678,20 +1451,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
} }
break; break;
case WM_MOUSEMOVE: case WM_MOUSEMOVE:
if (!window->m_mousePresent) {
TRACKMOUSEEVENT tme = {sizeof(tme)};
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = hwnd;
TrackMouseEvent(&tme);
window->m_mousePresent = true;
GHOST_Wintab *wt = window->getWintab();
if (wt) {
wt->gainFocus();
}
}
event = processCursorEvent(window); event = processCursorEvent(window);
break; break;
case WM_MOUSEWHEEL: { case WM_MOUSEWHEEL: {
/* The WM_MOUSEWHEEL message is sent to the focus window /* The WM_MOUSEWHEEL message is sent to the focus window
@@ -1726,17 +1486,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
window->loadCursor(true, GHOST_kStandardCursorDefault); window->loadCursor(true, GHOST_kStandardCursorDefault);
} }
break; break;
case WM_MOUSELEAVE: {
window->m_mousePresent = false;
if (window->getTabletData().Active == GHOST_kTabletModeNone) {
processCursorEvent(window);
}
GHOST_Wintab *wt = window->getWintab();
if (wt) {
wt->loseFocus();
}
break;
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Mouse events, ignored // Mouse events, ignored
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@@ -1784,7 +1534,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
* will not be dispatched to OUR active window if we minimize one of OUR windows. */ * will not be dispatched to OUR active window if we minimize one of OUR windows. */
if (LOWORD(wParam) == WA_INACTIVE) if (LOWORD(wParam) == WA_INACTIVE)
window->lostMouseCapture(); window->lostMouseCapture();
window->processWin32TabletActivateEvent(GET_WM_ACTIVATE_STATE(wParam, lParam));
lResult = ::DefWindowProc(hwnd, msg, wParam, lParam); lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
break; break;
} }
@@ -1826,8 +1576,6 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
/* Let DefWindowProc handle it. */ /* Let DefWindowProc handle it. */
break; break;
case WM_SIZING: case WM_SIZING:
event = processWindowSizeEvent(window);
break;
case WM_SIZE: case WM_SIZE:
/* The WM_SIZE message is sent to a window after its size has changed. /* The WM_SIZE message is sent to a window after its size has changed.
* The WM_SIZE and WM_MOVE messages are not sent if an application handles the * The WM_SIZE and WM_MOVE messages are not sent if an application handles the
@@ -1835,7 +1583,15 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
* to perform any move or size change processing during the WM_WINDOWPOSCHANGED * to perform any move or size change processing during the WM_WINDOWPOSCHANGED
* message without calling DefWindowProc. * message without calling DefWindowProc.
*/ */
event = processWindowSizeEvent(window); /* we get first WM_SIZE before we fully init.
* So, do not dispatch before we continuously resizing. */
if (window->m_inLiveResize) {
system->pushEvent(processWindowEvent(GHOST_kEventWindowSize, window));
system->dispatchEvents();
}
else {
event = processWindowEvent(GHOST_kEventWindowSize, window);
}
break; break;
case WM_CAPTURECHANGED: case WM_CAPTURECHANGED:
window->lostMouseCapture(); window->lostMouseCapture();
@@ -1851,7 +1607,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
* to perform any move or size change processing during the WM_WINDOWPOSCHANGED * to perform any move or size change processing during the WM_WINDOWPOSCHANGED
* message without calling DefWindowProc. * message without calling DefWindowProc.
*/ */
/* See #WM_SIZE comment. */ /* see WM_SIZE comment*/
if (window->m_inLiveResize) { if (window->m_inLiveResize) {
system->pushEvent(processWindowEvent(GHOST_kEventWindowMove, window)); system->pushEvent(processWindowEvent(GHOST_kEventWindowMove, window));
system->dispatchEvents(); system->dispatchEvents();
@@ -1886,21 +1642,6 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
SWP_NOZORDER | SWP_NOACTIVATE); SWP_NOZORDER | SWP_NOACTIVATE);
} }
break; break;
case WM_DISPLAYCHANGE: {
GHOST_Wintab *wt = window->getWintab();
if (wt) {
wt->remapCoordinates();
}
break;
}
case WM_KILLFOCUS:
/* The WM_KILLFOCUS message is sent to a window immediately before it loses the keyboard
* focus. We want to prevent this if a window is still active and it loses focus to
* nowhere. */
if (!wParam && hwnd == ::GetActiveWindow()) {
::SetFocus(hwnd);
}
break;
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Window events, ignored // Window events, ignored
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@@ -1937,6 +1678,12 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
* object associated with the window. * object associated with the window.
*/ */
break; break;
case WM_KILLFOCUS:
/* The WM_KILLFOCUS message is sent to a window immediately before it loses the
* keyboard focus. We want to prevent this if a window is still active and it loses
* focus to nowhere. */
if (!wParam && hwnd == ::GetActiveWindow())
::SetFocus(hwnd);
case WM_SHOWWINDOW: case WM_SHOWWINDOW:
/* The WM_SHOWWINDOW message is sent to a window when the window is /* The WM_SHOWWINDOW message is sent to a window when the window is
* about to be hidden or shown. */ * about to be hidden or shown. */

View File

@@ -265,16 +265,6 @@ class GHOST_SystemWin32 : public GHOST_System {
int mouseY, int mouseY,
void *data); void *data);
/***************************************************************************************
** Modify tablet API
***************************************************************************************/
/**
* Set which tablet API to use.
* \param api: Enum indicating which API to use.
*/
void setTabletAPI(GHOST_TTabletAPI api) override;
protected: protected:
/** /**
* Initializes the system. * Initializes the system.
@@ -318,12 +308,6 @@ class GHOST_SystemWin32 : public GHOST_System {
GHOST_WindowWin32 *window, GHOST_WindowWin32 *window,
GHOST_TButtonMask mask); GHOST_TButtonMask mask);
/**
* Creates tablet events from Wintab events.
* \param window: The window receiving the event (the active window).
*/
static void processWintabEvent(GHOST_WindowWin32 *window);
/** /**
* Creates tablet events from pointer events. * Creates tablet events from pointer events.
* \param type: The type of pointer event. * \param type: The type of pointer event.
@@ -367,13 +351,6 @@ class GHOST_SystemWin32 : public GHOST_System {
*/ */
GHOST_TKey processSpecialKey(short vKey, short scanCode) const; GHOST_TKey processSpecialKey(short vKey, short scanCode) const;
/**
* Creates a window size event.
* \param window: The window receiving the event (the active window).
* \return The event created.
*/
static GHOST_Event *processWindowSizeEvent(GHOST_WindowWin32 *window);
/** /**
* Creates a window event. * Creates a window event.
* \param type: The type of event to create. * \param type: The type of event to create.

View File

@@ -89,7 +89,7 @@
/* see T34039 Fix Alt key glitch on Unity desktop */ /* see T34039 Fix Alt key glitch on Unity desktop */
#define USE_UNITY_WORKAROUND #define USE_UNITY_WORKAROUND
/* Fix 'shortcut' part of keyboard reading code only ever using first defined key-map /* Fix 'shortcut' part of keyboard reading code only ever using first defined keymap
* instead of active one. See T47228 and D1746 */ * instead of active one. See T47228 and D1746 */
#define USE_NON_LATIN_KB_WORKAROUND #define USE_NON_LATIN_KB_WORKAROUND
@@ -441,8 +441,7 @@ GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_GLSettings glSetti
for (int minor = 5; minor >= 0; --minor) { for (int minor = 5; minor >= 0; --minor) {
#if defined(WITH_GL_EGL) #if defined(WITH_GL_EGL)
context = new GHOST_ContextEGL(this, context = new GHOST_ContextEGL(false,
false,
EGLNativeWindowType(nullptr), EGLNativeWindowType(nullptr),
EGLNativeDisplayType(m_display), EGLNativeDisplayType(m_display),
profile_mask, profile_mask,
@@ -472,8 +471,7 @@ GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_GLSettings glSetti
} }
#if defined(WITH_GL_EGL) #if defined(WITH_GL_EGL)
context = new GHOST_ContextEGL(this, context = new GHOST_ContextEGL(false,
false,
EGLNativeWindowType(nullptr), EGLNativeWindowType(nullptr),
EGLNativeDisplayType(m_display), EGLNativeDisplayType(m_display),
profile_mask, profile_mask,
@@ -591,7 +589,9 @@ static void SleepTillEvent(Display *display, GHOST_TInt64 maxSleep)
} }
} }
/* This function borrowed from Qt's X11 support qclipboard_x11.cpp */ /* This function borrowed from Qt's X11 support
* qclipboard_x11.cpp
* */
struct init_timestamp_data { struct init_timestamp_data {
Time timestamp; Time timestamp;
}; };
@@ -2563,7 +2563,7 @@ static bool is_filler_char(char c)
return isspace(c) || c == '_' || c == '-' || c == ';' || c == ':'; return isspace(c) || c == '_' || c == '-' || c == ';' || c == ':';
} }
/* These C functions are copied from Wine 3.12's `wintab.c` */ /* These C functions are copied from Wine 3.12's wintab.c */
static bool match_token(const char *haystack, const char *needle) static bool match_token(const char *haystack, const char *needle)
{ {
const char *h, *n; const char *h, *n;
@@ -2675,8 +2675,8 @@ void GHOST_SystemX11::refreshXInputDevices()
xtablet.PressureLevels = xvi->axes[2].max_value; xtablet.PressureLevels = xvi->axes[2].max_value;
if (xvi->num_axes > 3) { if (xvi->num_axes > 3) {
/* This is assuming that the tablet has the same tilt resolution in both /* this is assuming that the tablet has the same tilt resolution in both
* positive and negative directions. It would be rather weird if it didn't. */ * positive and negative directions. It would be rather weird if it didn't.. */
xtablet.XtiltLevels = xvi->axes[3].max_value; xtablet.XtiltLevels = xvi->axes[3].max_value;
xtablet.YtiltLevels = xvi->axes[4].max_value; xtablet.YtiltLevels = xvi->axes[4].max_value;
} }

View File

@@ -365,7 +365,7 @@ class GHOST_Window : public GHOST_IWindow {
/** The current grabbed state of the cursor */ /** The current grabbed state of the cursor */
GHOST_TGrabCursorMode m_cursorGrab; GHOST_TGrabCursorMode m_cursorGrab;
/** Grab cursor axis. */ /** Grab cursor axis.*/
GHOST_TAxisFlag m_cursorGrabAxis; GHOST_TAxisFlag m_cursorGrabAxis;
/** Initial grab location. */ /** Initial grab location. */

View File

@@ -22,7 +22,11 @@
#include "GHOST_Debug.h" #include "GHOST_Debug.h"
#include "GHOST_SystemCocoa.h" #include "GHOST_SystemCocoa.h"
#include "GHOST_ContextCGL.h" #if defined(WITH_GL_EGL)
# include "GHOST_ContextEGL.h"
#else
# include "GHOST_ContextCGL.h"
#endif
#include <Cocoa/Cocoa.h> #include <Cocoa/Cocoa.h>
#include <Metal/Metal.h> #include <Metal/Metal.h>

View File

@@ -556,7 +556,7 @@ static SDL_Cursor *sdl_ghost_CreateCursor(
return cursor; return cursor;
} }
/* TODO, this is currently never freed but it won't leak either. */ /* TODO, this is currently never freed but it wont leak either. */
static SDL_Cursor *getStandardCursorShape(GHOST_TStandardCursor shape) static SDL_Cursor *getStandardCursorShape(GHOST_TStandardCursor shape)
{ {
if (sdl_std_cursor_array[0] == NULL) { if (sdl_std_cursor_array[0] == NULL) {

View File

@@ -532,25 +532,7 @@ GHOST_Context *GHOST_WindowWayland::newDrawingContext(GHOST_TDrawingContextType
context = new GHOST_ContextNone(m_wantStereoVisual); context = new GHOST_ContextNone(m_wantStereoVisual);
break; break;
case GHOST_kDrawingContextTypeOpenGL: case GHOST_kDrawingContextTypeOpenGL:
for (int minor = 6; minor >= 0; --minor) { context = new GHOST_ContextEGL(m_wantStereoVisual,
context = new GHOST_ContextEGL(this->m_system,
m_wantStereoVisual,
EGLNativeWindowType(w->egl_window),
EGLNativeDisplayType(m_system->display()),
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
4,
minor,
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
EGL_OPENGL_API);
if (context->initializeDrawingContext())
return context;
else
delete context;
}
context = new GHOST_ContextEGL(this->m_system,
m_wantStereoVisual,
EGLNativeWindowType(w->egl_window), EGLNativeWindowType(w->egl_window),
EGLNativeDisplayType(m_system->display()), EGLNativeDisplayType(m_system->display()),
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
@@ -559,6 +541,7 @@ GHOST_Context *GHOST_WindowWayland::newDrawingContext(GHOST_TDrawingContextType
GHOST_OPENGL_EGL_CONTEXT_FLAGS, GHOST_OPENGL_EGL_CONTEXT_FLAGS,
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY, GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
EGL_OPENGL_API); EGL_OPENGL_API);
break;
} }
return (context->initializeDrawingContext() == GHOST_kSuccess) ? context : nullptr; return (context->initializeDrawingContext() == GHOST_kSuccess) ? context : nullptr;

View File

@@ -21,6 +21,8 @@
* \ingroup GHOST * \ingroup GHOST
*/ */
#define _USE_MATH_DEFINES
#include "GHOST_WindowWin32.h" #include "GHOST_WindowWin32.h"
#include "GHOST_ContextD3D.h" #include "GHOST_ContextD3D.h"
#include "GHOST_ContextNone.h" #include "GHOST_ContextNone.h"
@@ -30,8 +32,11 @@
#include "utf_winfunc.h" #include "utf_winfunc.h"
#include "utfconv.h" #include "utfconv.h"
#include "GHOST_ContextWGL.h" #if defined(WITH_GL_EGL)
# include "GHOST_ContextEGL.h"
#else
# include "GHOST_ContextWGL.h"
#endif
#ifdef WIN32_COMPOSITING #ifdef WIN32_COMPOSITING
# include <Dwmapi.h> # include <Dwmapi.h>
#endif #endif
@@ -67,7 +72,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
bool is_debug, bool is_debug,
bool dialog) bool dialog)
: GHOST_Window(width, height, state, wantStereoVisual, false), : GHOST_Window(width, height, state, wantStereoVisual, false),
m_mousePresent(false), m_tabletInRange(false),
m_inLiveResize(false), m_inLiveResize(false),
m_system(system), m_system(system),
m_hDC(0), m_hDC(0),
@@ -77,8 +82,6 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
m_nPressedButtons(0), m_nPressedButtons(0),
m_customCursor(0), m_customCursor(0),
m_wantAlphaBackground(alphaBackground), m_wantAlphaBackground(alphaBackground),
m_wintab(NULL),
m_lastPointerTabletData(GHOST_TABLET_DATA_NONE),
m_normal_state(GHOST_kWindowStateNormal), m_normal_state(GHOST_kWindowStateNormal),
m_user32(NULL), m_user32(NULL),
m_parentWindowHwnd(parentwindow ? parentwindow->m_hWnd : HWND_DESKTOP), m_parentWindowHwnd(parentwindow ? parentwindow->m_hWnd : HWND_DESKTOP),
@@ -87,6 +90,10 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
wchar_t *title_16 = alloc_utf16_from_8((char *)title, 0); wchar_t *title_16 = alloc_utf16_from_8((char *)title, 0);
RECT win_rect = {left, top, (long)(left + width), (long)(top + height)}; RECT win_rect = {left, top, (long)(left + width), (long)(top + height)};
// Initialize tablet variables
memset(&m_wintab, 0, sizeof(m_wintab));
m_tabletData = GHOST_TABLET_DATA_NONE;
DWORD style = parentwindow ? DWORD style = parentwindow ?
WS_POPUPWINDOW | WS_CAPTION | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SIZEBOX : WS_POPUPWINDOW | WS_CAPTION | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SIZEBOX :
WS_OVERLAPPEDWINDOW; WS_OVERLAPPEDWINDOW;
@@ -211,10 +218,65 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
} }
// Initialize Wintab // Initialize Wintab
if (system->getTabletAPI() != GHOST_kTabletWinPointer) { m_wintab.handle = ::LoadLibrary("Wintab32.dll");
loadWintab(GHOST_kWindowStateMinimized != state); if (m_wintab.handle && m_system->getTabletAPI() != GHOST_kTabletNative) {
} // Get API functions
m_wintab.info = (GHOST_WIN32_WTInfo)::GetProcAddress(m_wintab.handle, "WTInfoA");
m_wintab.open = (GHOST_WIN32_WTOpen)::GetProcAddress(m_wintab.handle, "WTOpenA");
m_wintab.close = (GHOST_WIN32_WTClose)::GetProcAddress(m_wintab.handle, "WTClose");
m_wintab.packet = (GHOST_WIN32_WTPacket)::GetProcAddress(m_wintab.handle, "WTPacket");
m_wintab.enable = (GHOST_WIN32_WTEnable)::GetProcAddress(m_wintab.handle, "WTEnable");
m_wintab.overlap = (GHOST_WIN32_WTOverlap)::GetProcAddress(m_wintab.handle, "WTOverlap");
// Let's see if we can initialize tablet here.
// Check if WinTab available by getting system context info.
LOGCONTEXT lc = {0};
lc.lcOptions |= CXO_SYSTEM;
if (m_wintab.open && m_wintab.info && m_wintab.info(WTI_DEFSYSCTX, 0, &lc)) {
// Now init the tablet
/* The maximum tablet size, pressure and orientation (tilt) */
AXIS TabletX, TabletY, Pressure, Orientation[3];
// Open a Wintab context
// Open the context
lc.lcPktData = PACKETDATA;
lc.lcPktMode = PACKETMODE;
lc.lcOptions |= CXO_MESSAGES;
lc.lcMoveMask = PACKETDATA;
/* Set the entire tablet as active */
m_wintab.info(WTI_DEVICES, DVC_X, &TabletX);
m_wintab.info(WTI_DEVICES, DVC_Y, &TabletY);
/* get the max pressure, to divide into a float */
BOOL pressureSupport = m_wintab.info(WTI_DEVICES, DVC_NPRESSURE, &Pressure);
if (pressureSupport)
m_wintab.maxPressure = Pressure.axMax;
else
m_wintab.maxPressure = 0;
/* get the max tilt axes, to divide into floats */
BOOL tiltSupport = m_wintab.info(WTI_DEVICES, DVC_ORIENTATION, &Orientation);
if (tiltSupport) {
/* does the tablet support azimuth ([0]) and altitude ([1]) */
if (Orientation[0].axResolution && Orientation[1].axResolution) {
/* all this assumes the minimum is 0 */
m_wintab.maxAzimuth = Orientation[0].axMax;
m_wintab.maxAltitude = Orientation[1].axMax;
}
else { /* No so don't do tilt stuff. */
m_wintab.maxAzimuth = m_wintab.maxAltitude = 0;
}
}
// The Wintab spec says we must open the context disabled if we are using cursor masks.
m_wintab.tablet = m_wintab.open(m_hWnd, &lc, FALSE);
if (m_wintab.enable && m_wintab.tablet) {
m_wintab.enable(m_wintab.tablet, TRUE);
}
}
}
CoCreateInstance( CoCreateInstance(
CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (LPVOID *)&m_Bar); CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (LPVOID *)&m_Bar);
} }
@@ -227,7 +289,14 @@ GHOST_WindowWin32::~GHOST_WindowWin32()
m_Bar = NULL; m_Bar = NULL;
} }
closeWintab(); if (m_wintab.handle) {
if (m_wintab.close && m_wintab.tablet) {
m_wintab.close(m_wintab.tablet);
}
FreeLibrary(m_wintab.handle);
memset(&m_wintab, 0, sizeof(m_wintab));
}
if (m_user32) { if (m_user32) {
FreeLibrary(m_user32); FreeLibrary(m_user32);
@@ -287,7 +356,7 @@ void GHOST_WindowWin32::setTitle(const char *title)
std::string GHOST_WindowWin32::getTitle() const std::string GHOST_WindowWin32::getTitle() const
{ {
char buf[s_maxTitleLength]; /* CHANGE + never used yet. */ char buf[s_maxTitleLength]; /*CHANGE + never used yet*/
::GetWindowText(m_hWnd, buf, s_maxTitleLength); ::GetWindowText(m_hWnd, buf, s_maxTitleLength);
return std::string(buf); return std::string(buf);
} }
@@ -844,16 +913,20 @@ GHOST_TSuccess GHOST_WindowWin32::hasCursorShape(GHOST_TStandardCursor cursorSha
GHOST_TSuccess GHOST_WindowWin32::getPointerInfo( GHOST_TSuccess GHOST_WindowWin32::getPointerInfo(
std::vector<GHOST_PointerInfoWin32> &outPointerInfo, WPARAM wParam, LPARAM lParam) std::vector<GHOST_PointerInfoWin32> &outPointerInfo, WPARAM wParam, LPARAM lParam)
{ {
GHOST_TInt32 pointerId = GET_POINTERID_WPARAM(wParam); if (!useTabletAPI(GHOST_kTabletNative)) {
GHOST_TInt32 isPrimary = IS_POINTER_PRIMARY_WPARAM(wParam);
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)GHOST_System::getSystem();
GHOST_TUns32 outCount = 0;
if (!(GetPointerPenInfoHistory(pointerId, &outCount, NULL))) {
return GHOST_kFailure; return GHOST_kFailure;
} }
std::vector<POINTER_PEN_INFO> pointerPenInfo(outCount); GHOST_TInt32 pointerId = GET_POINTERID_WPARAM(wParam);
GHOST_TInt32 isPrimary = IS_POINTER_PRIMARY_WPARAM(wParam);
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)GHOST_System::getSystem();
GHOST_TUns32 outCount;
if (!(GetPointerInfoHistory(pointerId, &outCount, NULL))) {
return GHOST_kFailure;
}
auto pointerPenInfo = std::vector<POINTER_PEN_INFO>(outCount);
outPointerInfo.resize(outCount); outPointerInfo.resize(outCount);
if (!(GetPointerPenInfoHistory(pointerId, &outCount, pointerPenInfo.data()))) { if (!(GetPointerPenInfoHistory(pointerId, &outCount, pointerPenInfo.data()))) {
@@ -915,77 +988,148 @@ GHOST_TSuccess GHOST_WindowWin32::getPointerInfo(
} }
} }
if (!outPointerInfo.empty()) {
m_lastPointerTabletData = outPointerInfo.back().tabletData;
}
return GHOST_kSuccess; return GHOST_kSuccess;
} }
void GHOST_WindowWin32::resetPointerPenInfo() void GHOST_WindowWin32::processWin32TabletActivateEvent(WORD state)
{ {
m_lastPointerTabletData = GHOST_TABLET_DATA_NONE; if (!useTabletAPI(GHOST_kTabletWintab)) {
} return;
}
GHOST_Wintab *GHOST_WindowWin32::getWintab() const if (m_wintab.enable && m_wintab.tablet) {
{ m_wintab.enable(m_wintab.tablet, state);
return m_wintab;
}
void GHOST_WindowWin32::loadWintab(bool enable) if (m_wintab.overlap && state) {
{ m_wintab.overlap(m_wintab.tablet, TRUE);
if (!m_wintab) {
if (m_wintab = GHOST_Wintab::loadWintab(m_hWnd)) {
if (enable) {
m_wintab->enable();
/* Focus Wintab if cursor is inside this window. This ensures Wintab is enabled when the
* tablet is used to change the Tablet API. */
GHOST_TInt32 x, y;
if (m_system->getCursorPosition(x, y)) {
GHOST_Rect rect;
getClientBounds(rect);
if (rect.isInside(x, y)) {
m_wintab->gainFocus();
}
}
}
} }
} }
} }
void GHOST_WindowWin32::closeWintab() bool GHOST_WindowWin32::useTabletAPI(GHOST_TTabletAPI api) const
{
delete m_wintab;
m_wintab = NULL;
}
bool GHOST_WindowWin32::usingTabletAPI(GHOST_TTabletAPI api) const
{ {
if (m_system->getTabletAPI() == api) { if (m_system->getTabletAPI() == api) {
return true; return true;
} }
else if (m_system->getTabletAPI() == GHOST_kTabletAutomatic) { else if (m_system->getTabletAPI() == GHOST_kTabletAutomatic) {
if (m_wintab && m_wintab->devicesPresent()) { if (m_wintab.tablet)
return api == GHOST_kTabletWintab; return api == GHOST_kTabletWintab;
} else
else { return api == GHOST_kTabletNative;
return api == GHOST_kTabletWinPointer;
}
} }
else { else {
return false; return false;
} }
} }
GHOST_TabletData GHOST_WindowWin32::getTabletData() void GHOST_WindowWin32::processWin32TabletInitEvent()
{ {
if (usingTabletAPI(GHOST_kTabletWintab)) { if (!useTabletAPI(GHOST_kTabletWintab)) {
return m_wintab ? m_wintab->getLastTabletData() : GHOST_TABLET_DATA_NONE; return;
} }
else {
return m_lastPointerTabletData; // Let's see if we can initialize tablet here
if (m_wintab.info && m_wintab.tablet) {
AXIS Pressure, Orientation[3]; /* The maximum tablet size */
BOOL pressureSupport = m_wintab.info(WTI_DEVICES, DVC_NPRESSURE, &Pressure);
if (pressureSupport)
m_wintab.maxPressure = Pressure.axMax;
else
m_wintab.maxPressure = 0;
BOOL tiltSupport = m_wintab.info(WTI_DEVICES, DVC_ORIENTATION, &Orientation);
if (tiltSupport) {
/* does the tablet support azimuth ([0]) and altitude ([1]) */
if (Orientation[0].axResolution && Orientation[1].axResolution) {
m_wintab.maxAzimuth = Orientation[0].axMax;
m_wintab.maxAltitude = Orientation[1].axMax;
}
else { /* No so don't do tilt stuff. */
m_wintab.maxAzimuth = m_wintab.maxAltitude = 0;
}
}
}
m_tabletData.Active = GHOST_kTabletModeNone;
}
void GHOST_WindowWin32::processWin32TabletEvent(WPARAM wParam, LPARAM lParam)
{
if (!useTabletAPI(GHOST_kTabletWintab)) {
return;
}
if (m_wintab.packet && m_wintab.tablet) {
PACKET pkt;
if (m_wintab.packet((HCTX)lParam, wParam, &pkt)) {
switch (pkt.pkCursor % 3) { /* % 3 for multiple devices ("DualTrack") */
case 0:
m_tabletData.Active = GHOST_kTabletModeNone; /* puck - not yet supported */
break;
case 1:
m_tabletData.Active = GHOST_kTabletModeStylus; /* stylus */
break;
case 2:
m_tabletData.Active = GHOST_kTabletModeEraser; /* eraser */
break;
}
if (m_wintab.maxPressure > 0) {
m_tabletData.Pressure = (float)pkt.pkNormalPressure / (float)m_wintab.maxPressure;
}
else {
m_tabletData.Pressure = 1.0f;
}
if ((m_wintab.maxAzimuth > 0) && (m_wintab.maxAltitude > 0)) {
ORIENTATION ort = pkt.pkOrientation;
float vecLen;
float altRad, azmRad; /* in radians */
/*
* from the wintab spec:
* orAzimuth Specifies the clockwise rotation of the
* cursor about the z axis through a full circular range.
*
* orAltitude Specifies the angle with the x-y plane
* through a signed, semicircular range. Positive values
* specify an angle upward toward the positive z axis;
* negative values specify an angle downward toward the negative z axis.
*
* wintab.h defines .orAltitude as a UINT but documents .orAltitude
* as positive for upward angles and negative for downward angles.
* WACOM uses negative altitude values to show that the pen is inverted;
* therefore we cast .orAltitude as an (int) and then use the absolute value.
*/
/* convert raw fixed point data to radians */
altRad = (float)((fabs((float)ort.orAltitude) / (float)m_wintab.maxAltitude) * M_PI / 2.0);
azmRad = (float)(((float)ort.orAzimuth / (float)m_wintab.maxAzimuth) * M_PI * 2.0);
/* find length of the stylus' projected vector on the XY plane */
vecLen = cos(altRad);
/* from there calculate X and Y components based on azimuth */
m_tabletData.Xtilt = sin(azmRad) * vecLen;
m_tabletData.Ytilt = (float)(sin(M_PI / 2.0 - azmRad) * vecLen);
}
else {
m_tabletData.Xtilt = 0.0f;
m_tabletData.Ytilt = 0.0f;
}
}
}
}
void GHOST_WindowWin32::bringTabletContextToFront()
{
if (!useTabletAPI(GHOST_kTabletWintab)) {
return;
}
if (m_wintab.overlap && m_wintab.tablet) {
m_wintab.overlap(m_wintab.tablet, TRUE);
} }
} }

View File

@@ -30,16 +30,29 @@
#include "GHOST_TaskbarWin32.h" #include "GHOST_TaskbarWin32.h"
#include "GHOST_Window.h" #include "GHOST_Window.h"
#include "GHOST_Wintab.h"
#ifdef WITH_INPUT_IME #ifdef WITH_INPUT_IME
# include "GHOST_ImeWin32.h" # include "GHOST_ImeWin32.h"
#endif #endif
#include <vector> #include <vector>
#include <wintab.h>
// PACKETDATA and PACKETMODE modify structs in pktdef.h, so make sure they come first
#define PACKETDATA (PK_BUTTONS | PK_NORMAL_PRESSURE | PK_ORIENTATION | PK_CURSOR)
#define PACKETMODE PK_BUTTONS
#include <pktdef.h>
class GHOST_SystemWin32; class GHOST_SystemWin32;
class GHOST_DropTargetWin32; class GHOST_DropTargetWin32;
// typedefs for WinTab functions to allow dynamic loading
typedef UINT(API *GHOST_WIN32_WTInfo)(UINT, UINT, LPVOID);
typedef HCTX(API *GHOST_WIN32_WTOpen)(HWND, LPLOGCONTEXTA, BOOL);
typedef BOOL(API *GHOST_WIN32_WTClose)(HCTX);
typedef BOOL(API *GHOST_WIN32_WTPacket)(HCTX, UINT, LPVOID);
typedef BOOL(API *GHOST_WIN32_WTEnable)(HCTX, BOOL);
typedef BOOL(API *GHOST_WIN32_WTOverlap)(HCTX, BOOL);
// typedefs for user32 functions to allow dynamic loading of Windows 10 DPI scaling functions // typedefs for user32 functions to allow dynamic loading of Windows 10 DPI scaling functions
typedef UINT(API *GHOST_WIN32_GetDpiForWindow)(HWND); typedef UINT(API *GHOST_WIN32_GetDpiForWindow)(HWND);
@@ -49,6 +62,7 @@ struct GHOST_PointerInfoWin32 {
GHOST_TButtonMask buttonMask; GHOST_TButtonMask buttonMask;
POINT pixelLocation; POINT pixelLocation;
GHOST_TUns64 time; GHOST_TUns64 time;
GHOST_TabletData tabletData; GHOST_TabletData tabletData;
}; };
@@ -242,11 +256,16 @@ class GHOST_WindowWin32 : public GHOST_Window {
HCURSOR getStandardCursor(GHOST_TStandardCursor shape) const; HCURSOR getStandardCursor(GHOST_TStandardCursor shape) const;
void loadCursor(bool visible, GHOST_TStandardCursor cursorShape) const; void loadCursor(bool visible, GHOST_TStandardCursor cursorShape) const;
const GHOST_TabletData &getTabletData()
{
return m_tabletData;
}
/** /**
* Query whether given tablet API should be used. * Query whether given tablet API should be used.
* \param api: Tablet API to test. * \param api: Tablet API to test.
*/ */
bool usingTabletAPI(GHOST_TTabletAPI api) const; bool useTabletAPI(GHOST_TTabletAPI api) const;
/** /**
* Translate WM_POINTER events into GHOST_PointerInfoWin32 structs. * Translate WM_POINTER events into GHOST_PointerInfoWin32 structs.
@@ -259,34 +278,10 @@ class GHOST_WindowWin32 : public GHOST_Window {
WPARAM wParam, WPARAM wParam,
LPARAM lParam); LPARAM lParam);
/** void processWin32TabletActivateEvent(WORD state);
* Resets pointer pen tablet state. void processWin32TabletInitEvent();
*/ void processWin32TabletEvent(WPARAM wParam, LPARAM lParam);
void resetPointerPenInfo(); void bringTabletContextToFront();
/**
* Retrieves pointer to Wintab if Wintab is the set Tablet API.
* \return Pointer to Wintab member.
*/
GHOST_Wintab *getWintab() const;
/**
* Loads Wintab context for the window.
* \param enable: True if Wintab should be enabled after loading. Wintab should not be enabled if
* the window is minimized.
*/
void loadWintab(bool enable);
/**
* Closes Wintab for the window.
*/
void closeWintab();
/**
* Get the most recent Windows Pointer tablet data.
* \return Most recent pointer tablet data.
*/
GHOST_TabletData getTabletData();
GHOST_TSuccess beginFullScreen() const GHOST_TSuccess beginFullScreen() const
{ {
@@ -300,10 +295,10 @@ class GHOST_WindowWin32 : public GHOST_Window {
GHOST_TUns16 getDPIHint() override; GHOST_TUns16 getDPIHint() override;
/** True if the mouse is either over or captured by the window. */ /** Whether a tablet stylus is being tracked. */
bool m_mousePresent; bool m_tabletInRange;
/** True if the window currently resizing. */ /** if the window currently resizing */
bool m_inLiveResize; bool m_inLiveResize;
#ifdef WITH_INPUT_IME #ifdef WITH_INPUT_IME
@@ -387,11 +382,27 @@ class GHOST_WindowWin32 : public GHOST_Window {
static const wchar_t *s_windowClassName; static const wchar_t *s_windowClassName;
static const int s_maxTitleLength; static const int s_maxTitleLength;
/** Pointer to Wintab manager if Wintab is loaded. */ /** Tablet data for GHOST */
GHOST_Wintab *m_wintab; GHOST_TabletData m_tabletData;
/** Most recent tablet data. */ /* Wintab API */
GHOST_TabletData m_lastPointerTabletData; struct {
/** `WinTab.dll` handle. */
HMODULE handle = NULL;
/** API functions */
GHOST_WIN32_WTInfo info;
GHOST_WIN32_WTOpen open;
GHOST_WIN32_WTClose close;
GHOST_WIN32_WTPacket packet;
GHOST_WIN32_WTEnable enable;
GHOST_WIN32_WTOverlap overlap;
/** Stores the Tablet context if detected Tablet features using `WinTab.dll` */
HCTX tablet;
LONG maxPressure;
LONG maxAzimuth, maxAltitude;
} m_wintab;
GHOST_TWindowState m_normal_state; GHOST_TWindowState m_normal_state;

View File

@@ -1241,7 +1241,7 @@ GHOST_WindowX11::~GHOST_WindowX11()
if (m_valid_setup) { if (m_valid_setup) {
static Atom Primary_atom, Clipboard_atom; static Atom Primary_atom, Clipboard_atom;
Window p_owner, c_owner; Window p_owner, c_owner;
/* Change the owner of the Atoms to None if we are the owner. */ /*Change the owner of the Atoms to None if we are the owner*/
Primary_atom = XInternAtom(m_display, "PRIMARY", False); Primary_atom = XInternAtom(m_display, "PRIMARY", False);
Clipboard_atom = XInternAtom(m_display, "CLIPBOARD", False); Clipboard_atom = XInternAtom(m_display, "CLIPBOARD", False);
@@ -1325,7 +1325,6 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type
for (int minor = 5; minor >= 0; --minor) { for (int minor = 5; minor >= 0; --minor) {
#ifdef WITH_GL_EGL #ifdef WITH_GL_EGL
context = new GHOST_ContextEGL( context = new GHOST_ContextEGL(
this->m_system,
m_wantStereoVisual, m_wantStereoVisual,
EGLNativeWindowType(m_window), EGLNativeWindowType(m_window),
EGLNativeDisplayType(m_display), EGLNativeDisplayType(m_display),
@@ -1356,8 +1355,7 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type
} }
#ifdef WITH_GL_EGL #ifdef WITH_GL_EGL
context = new GHOST_ContextEGL(this->m_system, context = new GHOST_ContextEGL(m_wantStereoVisual,
m_wantStereoVisual,
EGLNativeWindowType(m_window), EGLNativeWindowType(m_window),
EGLNativeDisplayType(m_display), EGLNativeDisplayType(m_display),
profile_mask, profile_mask,

View File

@@ -1,491 +0,0 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/** \file
* \ingroup GHOST
*/
#define _USE_MATH_DEFINES
#include "GHOST_Wintab.h"
GHOST_Wintab *GHOST_Wintab::loadWintab(HWND hwnd)
{
/* Load Wintab library if available. */
auto handle = unique_hmodule(::LoadLibrary("Wintab32.dll"), &::FreeLibrary);
if (!handle) {
return nullptr;
}
/* Get Wintab functions. */
auto info = (GHOST_WIN32_WTInfo)::GetProcAddress(handle.get(), "WTInfoA");
if (!info) {
return nullptr;
}
auto open = (GHOST_WIN32_WTOpen)::GetProcAddress(handle.get(), "WTOpenA");
if (!open) {
return nullptr;
}
auto get = (GHOST_WIN32_WTGet)::GetProcAddress(handle.get(), "WTGetA");
if (!get) {
return nullptr;
}
auto set = (GHOST_WIN32_WTSet)::GetProcAddress(handle.get(), "WTSetA");
if (!set) {
return nullptr;
}
auto close = (GHOST_WIN32_WTClose)::GetProcAddress(handle.get(), "WTClose");
if (!close) {
return nullptr;
}
auto packetsGet = (GHOST_WIN32_WTPacketsGet)::GetProcAddress(handle.get(), "WTPacketsGet");
if (!packetsGet) {
return nullptr;
}
auto queueSizeGet = (GHOST_WIN32_WTQueueSizeGet)::GetProcAddress(handle.get(), "WTQueueSizeGet");
if (!queueSizeGet) {
return nullptr;
}
auto queueSizeSet = (GHOST_WIN32_WTQueueSizeSet)::GetProcAddress(handle.get(), "WTQueueSizeSet");
if (!queueSizeSet) {
return nullptr;
}
auto enable = (GHOST_WIN32_WTEnable)::GetProcAddress(handle.get(), "WTEnable");
if (!enable) {
return nullptr;
}
auto overlap = (GHOST_WIN32_WTOverlap)::GetProcAddress(handle.get(), "WTOverlap");
if (!overlap) {
return nullptr;
}
/* Build Wintab context. */
LOGCONTEXT lc = {0};
if (!info(WTI_DEFSYSCTX, 0, &lc)) {
return nullptr;
}
Coord tablet, system;
extractCoordinates(lc, tablet, system);
modifyContext(lc);
/* The Wintab spec says we must open the context disabled if we are using cursor masks. */
auto hctx = unique_hctx(open(hwnd, &lc, FALSE), close);
if (!hctx) {
return nullptr;
}
/* Wintab provides no way to determine the maximum queue size aside from checking if attempts
* to change the queue size are successful. */
const int maxQueue = 500;
int queueSize = queueSizeGet(hctx.get());
while (queueSize < maxQueue) {
int testSize = min(queueSize + 16, maxQueue);
if (queueSizeSet(hctx.get(), testSize)) {
queueSize = testSize;
}
else {
/* From Windows Wintab Documentation for WTQueueSizeSet:
* "If the return value is zero, the context has no queue because the function deletes the
* original queue before attempting to create a new one. The application must continue
* calling the function with a smaller queue size until the function returns a non - zero
* value."
*
* In our case we start with a known valid queue size and in the event of failure roll
* back to the last valid queue size. The Wintab spec dates back to 16 bit Windows, thus
* assumes memory recently deallocated may not be available, which is no longer a practical
* concern. */
if (!queueSizeSet(hctx.get(), queueSize)) {
/* If a previously valid queue size is no longer valid, there is likely something wrong in
* the Wintab implementation and we should not use it. */
return nullptr;
}
break;
}
}
return new GHOST_Wintab(hwnd,
std::move(handle),
info,
get,
set,
packetsGet,
enable,
overlap,
std::move(hctx),
tablet,
system,
queueSize);
}
void GHOST_Wintab::modifyContext(LOGCONTEXT &lc)
{
lc.lcPktData = PACKETDATA;
lc.lcPktMode = PACKETMODE;
lc.lcMoveMask = PACKETDATA;
lc.lcOptions |= CXO_CSRMESSAGES | CXO_MESSAGES;
/* Tablet scaling is handled manually because some drivers don't handle HIDPI or multi-display
* correctly; reset tablet scale factors to un-scaled tablet coordinates. */
lc.lcOutOrgX = lc.lcInOrgX;
lc.lcOutOrgY = lc.lcInOrgY;
lc.lcOutExtX = lc.lcInExtX;
lc.lcOutExtY = lc.lcInExtY;
}
void GHOST_Wintab::extractCoordinates(LOGCONTEXT &lc, Coord &tablet, Coord &system)
{
tablet.x.org = lc.lcInOrgX;
tablet.x.ext = lc.lcInExtX;
tablet.y.org = lc.lcInOrgY;
tablet.y.ext = lc.lcInExtY;
system.x.org = lc.lcSysOrgX;
system.x.ext = lc.lcSysExtX;
system.y.org = lc.lcSysOrgY;
/* Wintab maps y origin to the tablet's bottom; invert y to match Windows y origin mapping to the
* screen top. */
system.y.ext = -lc.lcSysExtY;
}
GHOST_Wintab::GHOST_Wintab(HWND hwnd,
unique_hmodule handle,
GHOST_WIN32_WTInfo info,
GHOST_WIN32_WTGet get,
GHOST_WIN32_WTSet set,
GHOST_WIN32_WTPacketsGet packetsGet,
GHOST_WIN32_WTEnable enable,
GHOST_WIN32_WTOverlap overlap,
unique_hctx hctx,
Coord tablet,
Coord system,
int queueSize)
: m_handle{std::move(handle)},
m_fpInfo{info},
m_fpGet{get},
m_fpSet{set},
m_fpPacketsGet{packetsGet},
m_fpEnable{enable},
m_fpOverlap{overlap},
m_context{std::move(hctx)},
m_tabletCoord{tablet},
m_systemCoord{system},
m_pkts{queueSize}
{
m_fpInfo(WTI_INTERFACE, IFC_NDEVICES, &m_numDevices);
updateCursorInfo();
}
void GHOST_Wintab::enable()
{
m_fpEnable(m_context.get(), true);
m_enabled = true;
}
void GHOST_Wintab::disable()
{
if (m_focused) {
loseFocus();
}
m_fpEnable(m_context.get(), false);
m_enabled = false;
}
void GHOST_Wintab::gainFocus()
{
m_fpOverlap(m_context.get(), true);
m_focused = true;
}
void GHOST_Wintab::loseFocus()
{
if (m_lastTabletData.Active != GHOST_kTabletModeNone) {
leaveRange();
}
/* Mouse mode of tablet or display layout may change when Wintab or Window is inactive. Don't
* trust for mouse movement until re-verified. */
m_coordTrusted = false;
m_fpOverlap(m_context.get(), false);
m_focused = false;
}
void GHOST_Wintab::leaveRange()
{
/* Button state can't be tracked while out of range, reset it. */
m_buttons = 0;
/* Set to none to indicate tablet is inactive. */
m_lastTabletData = GHOST_TABLET_DATA_NONE;
/* Clear the packet queue. */
m_fpPacketsGet(m_context.get(), m_pkts.size(), m_pkts.data());
}
void GHOST_Wintab::remapCoordinates()
{
LOGCONTEXT lc = {0};
if (m_fpInfo(WTI_DEFSYSCTX, 0, &lc)) {
extractCoordinates(lc, m_tabletCoord, m_systemCoord);
modifyContext(lc);
m_fpSet(m_context.get(), &lc);
}
}
void GHOST_Wintab::updateCursorInfo()
{
AXIS Pressure, Orientation[3];
BOOL pressureSupport = m_fpInfo(WTI_DEVICES, DVC_NPRESSURE, &Pressure);
m_maxPressure = pressureSupport ? Pressure.axMax : 0;
BOOL tiltSupport = m_fpInfo(WTI_DEVICES, DVC_ORIENTATION, &Orientation);
/* Check if tablet supports azimuth [0] and altitude [1], encoded in axResolution. */
if (tiltSupport && Orientation[0].axResolution && Orientation[1].axResolution) {
m_maxAzimuth = Orientation[0].axMax;
m_maxAltitude = Orientation[1].axMax;
}
else {
m_maxAzimuth = m_maxAltitude = 0;
}
}
void GHOST_Wintab::processInfoChange(LPARAM lParam)
{
/* Update number of connected Wintab digitizers. */
if (LOWORD(lParam) == WTI_INTERFACE && HIWORD(lParam) == IFC_NDEVICES) {
m_fpInfo(WTI_INTERFACE, IFC_NDEVICES, &m_numDevices);
}
}
bool GHOST_Wintab::devicesPresent()
{
return m_numDevices > 0;
}
GHOST_TabletData GHOST_Wintab::getLastTabletData()
{
return m_lastTabletData;
}
void GHOST_Wintab::getInput(std::vector<GHOST_WintabInfoWin32> &outWintabInfo)
{
const int numPackets = m_fpPacketsGet(m_context.get(), m_pkts.size(), m_pkts.data());
outWintabInfo.resize(numPackets);
size_t outExtent = 0;
for (int i = 0; i < numPackets; i++) {
PACKET pkt = m_pkts[i];
GHOST_WintabInfoWin32 &out = outWintabInfo[i + outExtent];
out.tabletData = GHOST_TABLET_DATA_NONE;
/* % 3 for multiple devices ("DualTrack"). */
switch (pkt.pkCursor % 3) {
case 0:
/* Puck - processed as mouse. */
out.tabletData.Active = GHOST_kTabletModeNone;
break;
case 1:
out.tabletData.Active = GHOST_kTabletModeStylus;
break;
case 2:
out.tabletData.Active = GHOST_kTabletModeEraser;
break;
}
out.x = pkt.pkX;
out.y = pkt.pkY;
if (m_maxPressure > 0) {
out.tabletData.Pressure = (float)pkt.pkNormalPressure / (float)m_maxPressure;
}
if ((m_maxAzimuth > 0) && (m_maxAltitude > 0)) {
ORIENTATION ort = pkt.pkOrientation;
float vecLen;
float altRad, azmRad; /* In radians. */
/*
* From the wintab spec:
* orAzimuth: Specifies the clockwise rotation of the cursor about the z axis through a
* full circular range.
* orAltitude: Specifies the angle with the x-y plane through a signed, semicircular range.
* Positive values specify an angle upward toward the positive z axis; negative values
* specify an angle downward toward the negative z axis.
*
* wintab.h defines orAltitude as a UINT but documents orAltitude as positive for upward
* angles and negative for downward angles. WACOM uses negative altitude values to show that
* the pen is inverted; therefore we cast orAltitude as an (int) and then use the absolute
* value.
*/
/* Convert raw fixed point data to radians. */
altRad = (float)((fabs((float)ort.orAltitude) / (float)m_maxAltitude) * M_PI / 2.0);
azmRad = (float)(((float)ort.orAzimuth / (float)m_maxAzimuth) * M_PI * 2.0);
/* Find length of the stylus' projected vector on the XY plane. */
vecLen = cos(altRad);
/* From there calculate X and Y components based on azimuth. */
out.tabletData.Xtilt = sin(azmRad) * vecLen;
out.tabletData.Ytilt = (float)(sin(M_PI / 2.0 - azmRad) * vecLen);
}
out.time = pkt.pkTime;
/* Some Wintab libraries don't handle relative button input, so we track button presses
* manually. */
out.button = GHOST_kButtonMaskNone;
out.type = GHOST_kEventCursorMove;
DWORD buttonsChanged = m_buttons ^ pkt.pkButtons;
WORD buttonIndex = 0;
GHOST_WintabInfoWin32 buttonRef = out;
int buttons = 0;
while (buttonsChanged) {
if (buttonsChanged & 1) {
/* Find the index for the changed button from the button map. */
GHOST_TButtonMask button = mapWintabToGhostButton(pkt.pkCursor, buttonIndex);
if (button != GHOST_kButtonMaskNone) {
/* Extend output if multiple buttons are pressed. We don't extend input until we confirm
* a Wintab buttons maps to a system button. */
if (buttons > 0) {
outWintabInfo.resize(outWintabInfo.size() + 1);
outExtent++;
GHOST_WintabInfoWin32 &out = outWintabInfo[i + outExtent];
out = buttonRef;
}
buttons++;
out.button = button;
if (buttonsChanged & pkt.pkButtons) {
out.type = GHOST_kEventButtonDown;
}
else {
out.type = GHOST_kEventButtonUp;
}
}
m_buttons ^= 1 << buttonIndex;
}
buttonsChanged >>= 1;
buttonIndex++;
}
}
if (!outWintabInfo.empty()) {
m_lastTabletData = outWintabInfo.back().tabletData;
}
}
GHOST_TButtonMask GHOST_Wintab::mapWintabToGhostButton(UINT cursor, WORD physicalButton)
{
const WORD numButtons = 32;
BYTE logicalButtons[numButtons] = {0};
BYTE systemButtons[numButtons] = {0};
if (!m_fpInfo(WTI_CURSORS + cursor, CSR_BUTTONMAP, &logicalButtons) ||
!m_fpInfo(WTI_CURSORS + cursor, CSR_SYSBTNMAP, &systemButtons)) {
return GHOST_kButtonMaskNone;
}
if (physicalButton >= numButtons) {
return GHOST_kButtonMaskNone;
}
BYTE lb = logicalButtons[physicalButton];
if (lb >= numButtons) {
return GHOST_kButtonMaskNone;
}
switch (systemButtons[lb]) {
case SBN_LCLICK:
return GHOST_kButtonMaskLeft;
case SBN_RCLICK:
return GHOST_kButtonMaskRight;
case SBN_MCLICK:
return GHOST_kButtonMaskMiddle;
default:
return GHOST_kButtonMaskNone;
}
}
void GHOST_Wintab::mapWintabToSysCoordinates(int x_in, int y_in, int &x_out, int &y_out)
{
/* Maps from range [in.org, in.org + abs(in.ext)] to [out.org, out.org + abs(out.ext)], in
* reverse if in.ext and out.ext have differing sign. */
auto remap = [](int inPoint, Range in, Range out) -> int {
int absInExt = abs(in.ext);
int absOutExt = abs(out.ext);
/* Translate input from range [in.org, in.org + absInExt] to [0, absInExt] */
int inMagnitude = inPoint - in.org;
/* If signs of extents differ, reverse input over range. */
if ((in.ext < 0) != (out.ext < 0)) {
inMagnitude = absInExt - inMagnitude;
}
/* Scale from [0, absInExt] to [0, absOutExt]. */
int outMagnitude = inMagnitude * absOutExt / absInExt;
/* Translate from range [0, absOutExt] to [out.org, out.org + absOutExt]. */
int outPoint = outMagnitude + out.org;
return outPoint;
};
x_out = remap(x_in, m_tabletCoord.x, m_systemCoord.x);
y_out = remap(y_in, m_tabletCoord.y, m_systemCoord.y);
}
bool GHOST_Wintab::trustCoordinates()
{
return m_coordTrusted;
}
bool GHOST_Wintab::testCoordinates(int sysX, int sysY, int wtX, int wtY)
{
mapWintabToSysCoordinates(wtX, wtY, wtX, wtY);
/* Allow off by one pixel tolerance in case of rounding error. */
if (abs(sysX - wtX) <= 1 && abs(sysY - wtY) <= 1) {
m_coordTrusted = true;
return true;
}
else {
m_coordTrusted = false;
return false;
}
}

View File

@@ -1,250 +0,0 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/** \file
* \ingroup GHOST
* Declaration of GHOST_WintabWin32 class.
*/
/* Wacom's Wintab documentation is periodically offline, moved, and increasingly hidden away. You
* can find a (painstakingly) archived copy of the documentation at
* https://web.archive.org/web/20201122230125/https://developer-docs-legacy.wacom.com/display/DevDocs/Windows+Wintab+Documentation
*/
#pragma once
#include <memory>
#include <vector>
#include <wtypes.h>
#include "GHOST_Types.h"
#include <wintab.h>
/* PACKETDATA and PACKETMODE modify structs in pktdef.h, so make sure they come first. */
#define PACKETDATA \
(PK_BUTTONS | PK_NORMAL_PRESSURE | PK_ORIENTATION | PK_CURSOR | PK_X | PK_Y | PK_TIME)
#define PACKETMODE 0
#include <pktdef.h>
/* Typedefs for Wintab functions to allow dynamic loading. */
typedef UINT(API *GHOST_WIN32_WTInfo)(UINT, UINT, LPVOID);
typedef BOOL(API *GHOST_WIN32_WTGet)(HCTX, LPLOGCONTEXTA);
typedef BOOL(API *GHOST_WIN32_WTSet)(HCTX, LPLOGCONTEXTA);
typedef HCTX(API *GHOST_WIN32_WTOpen)(HWND, LPLOGCONTEXTA, BOOL);
typedef BOOL(API *GHOST_WIN32_WTClose)(HCTX);
typedef int(API *GHOST_WIN32_WTPacketsGet)(HCTX, int, LPVOID);
typedef int(API *GHOST_WIN32_WTQueueSizeGet)(HCTX);
typedef BOOL(API *GHOST_WIN32_WTQueueSizeSet)(HCTX, int);
typedef BOOL(API *GHOST_WIN32_WTEnable)(HCTX, BOOL);
typedef BOOL(API *GHOST_WIN32_WTOverlap)(HCTX, BOOL);
/* Typedefs for Wintab and Windows resource management. */
typedef std::unique_ptr<std::remove_pointer_t<HMODULE>, decltype(&::FreeLibrary)> unique_hmodule;
typedef std::unique_ptr<std::remove_pointer_t<HCTX>, GHOST_WIN32_WTClose> unique_hctx;
struct GHOST_WintabInfoWin32 {
GHOST_TInt32 x, y;
GHOST_TEventType type;
GHOST_TButtonMask button;
GHOST_TUns64 time;
GHOST_TabletData tabletData;
};
class GHOST_Wintab {
public:
/**
* Loads Wintab if available.
* \param hwnd: Window to attach Wintab context to.
*/
static GHOST_Wintab *loadWintab(HWND hwnd);
/**
* Enables Wintab context.
*/
void enable();
/**
* Disables the Wintab context and unwinds Wintab state.
*/
void disable();
/**
* Brings Wintab context to the top of the overlap order.
*/
void gainFocus();
/**
* Puts Wintab context at bottom of overlap order and unwinds Wintab state.
*/
void loseFocus();
/**
* Clean up when Wintab leaves tracking range.
*/
void leaveRange();
/**
* Handle Wintab coordinate changes when DisplayChange events occur.
*/
void remapCoordinates();
/**
* Maps Wintab to Win32 display coordinates.
* \param x_in: The tablet x coordinate.
* \param y_in: The tablet y coordinate.
* \param x_out: Output for the Win32 mapped x coordinate.
* \param y_out: Output for the Win32 mapped y coordinate.
*/
void mapWintabToSysCoordinates(int x_in, int y_in, int &x_out, int &y_out);
/**
* Updates cached Wintab properties for current cursor.
*/
void updateCursorInfo();
/**
* Handle Wintab info changes such as change in number of connected tablets.
* \param lParam: LPARAM of the event.
*/
void processInfoChange(LPARAM lParam);
/**
* Whether Wintab devices are present.
* \return True if Wintab devices are present.
*/
bool devicesPresent();
/**
* Translate Wintab packets into GHOST_WintabInfoWin32 structs.
* \param outWintabInfo: Storage to return resulting GHOST_WintabInfoWin32 data.
*/
void getInput(std::vector<GHOST_WintabInfoWin32> &outWintabInfo);
/**
* Whether Wintab coordinates should be trusted.
* \return True if Wintab coordinates should be trusted.
*/
bool trustCoordinates();
/**
* Tests whether Wintab coordinates can be trusted by comparing Win32 and Wintab reported cursor
* position.
* \param sysX: System cursor x position.
* \param sysY: System cursor y position.
* \param wtX: Wintab cursor x position.
* \param wtY: Wintab cursor y position.
* \return True if Win32 and Wintab cursor positions match within tolerance.
*
* Note: Only test coordinates on button press, not release. This prevents issues when async
* mismatch causes mouse movement to replay and snap back, which is only an issue while drawing.
*/
bool testCoordinates(int sysX, int sysY, int wtX, int wtY);
/**
* Retrieve the most recent tablet data, or none if pen is not in range.
* \return Most recent tablet data, or none if pen is not in range.
*/
GHOST_TabletData getLastTabletData();
private:
/** Wintab DLL handle. */
unique_hmodule m_handle;
/** Wintab API functions. */
GHOST_WIN32_WTInfo m_fpInfo = nullptr;
GHOST_WIN32_WTGet m_fpGet = nullptr;
GHOST_WIN32_WTSet m_fpSet = nullptr;
GHOST_WIN32_WTPacketsGet m_fpPacketsGet = nullptr;
GHOST_WIN32_WTEnable m_fpEnable = nullptr;
GHOST_WIN32_WTOverlap m_fpOverlap = nullptr;
/** Stores the Wintab tablet context. */
unique_hctx m_context;
/** Whether the context is enabled. */
bool m_enabled = false;
/** Whether the context has focus and is at the top of overlap order. */
bool m_focused = false;
/** Pressed button map. */
GHOST_TUns8 m_buttons = 0;
/** Range of a coordinate space. */
struct Range {
/** Origin of range. */
int org = 0;
/** Extent of range. */
int ext = 1;
};
/** 2D Coordinate space. */
struct Coord {
/** Range of x. */
Range x = {};
/** Range of y. */
Range y = {};
};
/** Whether Wintab coordinates are trusted. */
bool m_coordTrusted = false;
/** Tablet input range. */
Coord m_tabletCoord = {};
/** System output range. */
Coord m_systemCoord = {};
int m_maxPressure = 0;
int m_maxAzimuth = 0;
int m_maxAltitude = 0;
/** Number of connected Wintab devices. */
UINT m_numDevices = 0;
/** Reusable buffer to read in Wintab packets. */
std::vector<PACKET> m_pkts;
/** Most recently received tablet data, or none if pen is not in range. */
GHOST_TabletData m_lastTabletData = GHOST_TABLET_DATA_NONE;
GHOST_Wintab(HWND hwnd,
unique_hmodule handle,
GHOST_WIN32_WTInfo info,
GHOST_WIN32_WTGet get,
GHOST_WIN32_WTSet set,
GHOST_WIN32_WTPacketsGet packetsGet,
GHOST_WIN32_WTEnable enable,
GHOST_WIN32_WTOverlap overlap,
unique_hctx hctx,
Coord tablet,
Coord system,
int queueSize);
/**
* Convert Wintab system mapped (mouse) buttons into Ghost button mask.
* \param cursor: The Wintab cursor associated to the button.
* \param physicalButton: The physical button ID to inspect.
* \return The system mapped button.
*/
GHOST_TButtonMask mapWintabToGhostButton(UINT cursor, WORD physicalButton);
/**
* Applies common modifications to Wintab context.
* \param lc: Wintab context to modify.
*/
static void modifyContext(LOGCONTEXT &lc);
/**
* Extracts tablet and system coordinates from Wintab context.
* \param lc: Wintab context to extract coordinates from.
* \param tablet: Tablet coordinates.
* \param system: System coordinates.
*/
static void extractCoordinates(LOGCONTEXT &lc, Coord &tablet, Coord &system);
};

View File

@@ -392,10 +392,9 @@ GHOST_XrActionSet::GHOST_XrActionSet(XrInstance instance, const GHOST_XrActionSe
{ {
XrActionSetCreateInfo action_set_info{XR_TYPE_ACTION_SET_CREATE_INFO}; XrActionSetCreateInfo action_set_info{XR_TYPE_ACTION_SET_CREATE_INFO};
strcpy(action_set_info.actionSetName, info.name); strcpy(action_set_info.actionSetName, info.name);
strcpy(action_set_info.localizedActionSetName,
/* Just use same name for localized. This can be changed in the future if necessary. */ info.name); /* Just use same name for localized. This can be changed in the future if
strcpy(action_set_info.localizedActionSetName, info.name); necessary. */
action_set_info.priority = 0; /* Use same (default) priority for all action sets. */ action_set_info.priority = 0; /* Use same (default) priority for all action sets. */
CHECK_XR(xrCreateActionSet(instance, &action_set_info, &m_action_set), CHECK_XR(xrCreateActionSet(instance, &action_set_info, &m_action_set),

View File

@@ -420,11 +420,6 @@ void GHOST_XrContext::getExtensionsToEnable(
r_ext_names.push_back(gpu_binding); r_ext_names.push_back(gpu_binding);
} }
#if defined(WITH_GHOST_X11) && defined(WITH_GL_EGL)
assert(openxr_extension_is_available(m_oxr->extensions, XR_MNDX_EGL_ENABLE_EXTENSION_NAME));
r_ext_names.push_back(XR_MNDX_EGL_ENABLE_EXTENSION_NAME);
#endif
for (const std::string_view &ext : try_ext) { for (const std::string_view &ext : try_ext) {
if (openxr_extension_is_available(m_oxr->extensions, ext)) { if (openxr_extension_is_available(m_oxr->extensions, ext)) {
r_ext_names.push_back(ext.data()); r_ext_names.push_back(ext.data());

View File

@@ -22,15 +22,7 @@
#include <list> #include <list>
#include <sstream> #include <sstream>
#if defined(WITH_GL_EGL) #if defined(WITH_GHOST_X11)
# include "GHOST_ContextEGL.h"
# if defined(WITH_GHOST_X11)
# include "GHOST_SystemX11.h"
# endif
# if defined(WITH_GHOST_WAYLAND)
# include "GHOST_SystemWayland.h"
# endif
#elif defined(WITH_GHOST_X11)
# include "GHOST_ContextGLX.h" # include "GHOST_ContextGLX.h"
#elif defined(WIN32) #elif defined(WIN32)
# include "GHOST_ContextD3D.h" # include "GHOST_ContextD3D.h"
@@ -74,9 +66,7 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
XrSystemId system_id, XrSystemId system_id,
std::string *r_requirement_info) const override std::string *r_requirement_info) const override
{ {
#if defined(WITH_GL_EGL) #if defined(WITH_GHOST_X11)
GHOST_ContextEGL &ctx_gl = static_cast<GHOST_ContextEGL &>(ghost_ctx);
#elif defined(WITH_GHOST_X11)
GHOST_ContextGLX &ctx_gl = static_cast<GHOST_ContextGLX &>(ghost_ctx); GHOST_ContextGLX &ctx_gl = static_cast<GHOST_ContextGLX &>(ghost_ctx);
#else #else
GHOST_ContextWGL &ctx_gl = static_cast<GHOST_ContextWGL &>(ghost_ctx); GHOST_ContextWGL &ctx_gl = static_cast<GHOST_ContextWGL &>(ghost_ctx);
@@ -116,17 +106,6 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
void initFromGhostContext(GHOST_Context &ghost_ctx) override void initFromGhostContext(GHOST_Context &ghost_ctx) override
{ {
#if defined(WITH_GHOST_X11) #if defined(WITH_GHOST_X11)
# if defined(WITH_GL_EGL)
GHOST_ContextEGL &ctx_egl = static_cast<GHOST_ContextEGL &>(ghost_ctx);
if (dynamic_cast<const GHOST_SystemX11 *const>(ctx_egl.m_system)) {
oxr_binding.egl.type = XR_TYPE_GRAPHICS_BINDING_EGL_MNDX;
oxr_binding.egl.getProcAddress = eglGetProcAddress;
oxr_binding.egl.display = ctx_egl.getDisplay();
oxr_binding.egl.config = ctx_egl.getConfig();
oxr_binding.egl.context = ctx_egl.getContext();
}
# else
GHOST_ContextGLX &ctx_glx = static_cast<GHOST_ContextGLX &>(ghost_ctx); GHOST_ContextGLX &ctx_glx = static_cast<GHOST_ContextGLX &>(ghost_ctx);
XVisualInfo *visual_info = glXGetVisualFromFBConfig(ctx_glx.m_display, ctx_glx.m_fbconfig); XVisualInfo *visual_info = glXGetVisualFromFBConfig(ctx_glx.m_display, ctx_glx.m_fbconfig);
@@ -138,7 +117,6 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
oxr_binding.glx.visualid = visual_info->visualid; oxr_binding.glx.visualid = visual_info->visualid;
XFree(visual_info); XFree(visual_info);
# endif
#elif defined(WIN32) #elif defined(WIN32)
GHOST_ContextWGL &ctx_wgl = static_cast<GHOST_ContextWGL &>(ghost_ctx); GHOST_ContextWGL &ctx_wgl = static_cast<GHOST_ContextWGL &>(ghost_ctx);
@@ -147,14 +125,6 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
oxr_binding.wgl.hGLRC = ctx_wgl.m_hGLRC; oxr_binding.wgl.hGLRC = ctx_wgl.m_hGLRC;
#endif #endif
#if defined(WITH_GHOST_WAYLAND)
GHOST_ContextEGL &ctx_wl_egl = static_cast<GHOST_ContextEGL &>(ghost_ctx);
if (dynamic_cast<const GHOST_SystemWayland *const>(ctx_wl_egl.m_system)) {
oxr_binding.wl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_WAYLAND_KHR;
oxr_binding.wl.display = (struct wl_display *)ctx_wl_egl.m_nativeDisplay;
}
#endif
/* Generate a frame-buffer to use for blitting into the texture. */ /* Generate a frame-buffer to use for blitting into the texture. */
glGenFramebuffers(1, &m_fbo); glGenFramebuffers(1, &m_fbo);
} }

View File

@@ -74,11 +74,10 @@ class GHOST_XrSession {
const GHOST_XrActionProfileInfo *infos); const GHOST_XrActionProfileInfo *infos);
bool attachActionSets(); bool attachActionSets();
/** /** Action functions to be called post-session start. */
* Action functions to be called post-session start. bool syncActions(
* \param action_set_name: When `nullptr`, all attached action sets will be synced. const char *action_set_name = nullptr); /* If action_set_name is nullptr, all attached
*/ * action sets will be synced. */
bool syncActions(const char *action_set_name = nullptr);
bool applyHapticAction(const char *action_set_name, bool applyHapticAction(const char *action_set_name,
const char *action_name, const char *action_name,
const GHOST_TInt64 &duration, const GHOST_TInt64 &duration,

View File

@@ -42,13 +42,7 @@
# include <d3d12.h> # include <d3d12.h>
#endif #endif
#ifdef WITH_GHOST_X11 #ifdef WITH_GHOST_X11
# ifdef WITH_GL_EGL # include <GL/glxew.h>
/* TODO: Why do we have to create this typedef manually? */
typedef void (*(*PFNEGLGETPROCADDRESSPROC)(const char *procname))(void);
# include <GL/eglew.h>
# else
# include <GL/glxew.h>
# endif
#endif #endif
#include <openxr/openxr.h> #include <openxr/openxr.h>

View File

@@ -78,7 +78,7 @@ extern short (*MEM_testN)(void *vmemh);
/** /**
* Duplicates a block of memory, and returns a pointer to the * Duplicates a block of memory, and returns a pointer to the
* newly allocated block. */ * newly allocated block. */
extern void *(*MEM_dupallocN)(const void *vmemh) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT; extern void *(*MEM_dupallocN)(const void *vmemh) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT;
/** /**

View File

@@ -103,7 +103,7 @@ int main(int argc, char *argv[])
/* ----------------------------------------------------------------- */ /* ----------------------------------------------------------------- */
/* Round two, do a normal allocation, and corrupt some blocks. */ /* Round two, do a normal allocation, and corrupt some blocks. */
/* ----------------------------------------------------------------- */ /* ----------------------------------------------------------------- */
/* Switch off, because it will complain about some things. */ /* switch off, because it will complain about some things. */
MEM_set_error_callback(NULL); MEM_set_error_callback(NULL);
for (i = 0; i < NUM_BLOCKS; i++) { for (i = 0; i < NUM_BLOCKS; i++) {
@@ -115,7 +115,7 @@ int main(int argc, char *argv[])
p[i] = MEM_callocN(blocksize, strdup(tagstring)); p[i] = MEM_callocN(blocksize, strdup(tagstring));
} }
/* Now corrupt a few blocks. */ /* now corrupt a few blocks...*/
ip = (int *)p[5] - 50; ip = (int *)p[5] - 50;
for (i = 0; i < 1000; i++, ip++) for (i = 0; i < 1000; i++, ip++)
*ip = i + 1; *ip = i + 1;

View File

@@ -89,7 +89,7 @@ bool IK_QJacobianSolver::Setup(IK_QSegment *root, std::list<IK_QTask *> &tasks)
if (num_dof == 0) if (num_dof == 0)
return false; return false;
// compute task ids and assign weights to task // compute task id's and assing weights to task
int primary_size = 0, primary = 0; int primary_size = 0, primary = 0;
int secondary_size = 0, secondary = 0; int secondary_size = 0, secondary = 0;
double primary_weight = 0.0, secondary_weight = 0.0; double primary_weight = 0.0, secondary_weight = 0.0;
@@ -237,7 +237,7 @@ void IK_QJacobianSolver::ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTa
bool IK_QJacobianSolver::UpdateAngles(double &norm) bool IK_QJacobianSolver::UpdateAngles(double &norm)
{ {
// assign each segment a unique id for the jacobian // assing each segment a unique id for the jacobian
std::vector<IK_QSegment *>::iterator seg; std::vector<IK_QSegment *>::iterator seg;
IK_QSegment *qseg, *minseg = NULL; IK_QSegment *qseg, *minseg = NULL;
double minabsdelta = 1e10, absdelta; double minabsdelta = 1e10, absdelta;

View File

@@ -867,7 +867,7 @@ IMETHOD void Vector2::Set3DYZ(const Vector& v)
data[1]=v(2); data[1]=v(2);
} }
IMETHOD void Vector2::Set3DZX(const Vector& v) IMETHOD void Vector2::Set3DZX(const Vector& v)
// projects v in its XY plane, and sets *this to these values // projects v in its XY plane, and and sets *this to these values
{ {
data[0]=v(2); data[0]=v(2);
data[1]=v(0); data[1]=v(0);

Some files were not shown because too many files have changed in this diff Show More