Initial commit.
This commit is contained in:
commit
d3bb49b3f5
1073 changed files with 484757 additions and 0 deletions
12
Framework/external/embree/tutorials/common/CMakeLists.txt
vendored
Normal file
12
Framework/external/embree/tutorials/common/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
## Copyright 2009-2021 Intel Corporation
|
||||
## SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
IF (EMBREE_TUTORIALS_GLFW)
|
||||
ADD_SUBDIRECTORY(imgui)
|
||||
ENDIF()
|
||||
|
||||
ADD_SUBDIRECTORY(tutorial)
|
||||
ADD_SUBDIRECTORY(scenegraph)
|
||||
ADD_SUBDIRECTORY(lights)
|
||||
ADD_SUBDIRECTORY(texture)
|
||||
|
||||
11
Framework/external/embree/tutorials/common/common.isph
vendored
Normal file
11
Framework/external/embree/tutorials/common/common.isph
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef ISPC_UINT_IS_DEFINED
|
||||
typedef unsigned int64 uint64;
|
||||
typedef unsigned int32 uint32;
|
||||
typedef unsigned int16 uint16;
|
||||
typedef unsigned int8 uint8;
|
||||
#endif
|
||||
25
Framework/external/embree/tutorials/common/core/differential_geometry.h
vendored
Normal file
25
Framework/external/embree/tutorials/common/core/differential_geometry.h
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../../include/embree4/rtcore.h"
|
||||
#include "../math/vec.h"
|
||||
|
||||
namespace embree {
|
||||
|
||||
struct DifferentialGeometry
|
||||
{
|
||||
unsigned int instIDs[RTC_MAX_INSTANCE_LEVEL_COUNT];
|
||||
unsigned int geomID;
|
||||
unsigned int primID;
|
||||
float u,v;
|
||||
Vec3fa P;
|
||||
Vec3fa Ng;
|
||||
Vec3fa Ns;
|
||||
Vec3fa Tx; //direction along hair
|
||||
Vec3fa Ty;
|
||||
float eps;
|
||||
};
|
||||
|
||||
} // namespace embree
|
||||
21
Framework/external/embree/tutorials/common/core/differential_geometry.isph
vendored
Normal file
21
Framework/external/embree/tutorials/common/core/differential_geometry.isph
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../../include/embree4/rtcore.isph"
|
||||
#include "../math/vec.isph"
|
||||
|
||||
struct DifferentialGeometry
|
||||
{
|
||||
unsigned int instIDs[RTC_MAX_INSTANCE_LEVEL_COUNT];
|
||||
unsigned int geomID;
|
||||
unsigned int primID;
|
||||
float u,v;
|
||||
Vec3f P;
|
||||
Vec3f Ng;
|
||||
Vec3f Ns;
|
||||
Vec3f Tx; //direction along hair
|
||||
Vec3f Ty;
|
||||
float eps;
|
||||
};
|
||||
144
Framework/external/embree/tutorials/common/core/ray.h
vendored
Normal file
144
Framework/external/embree/tutorials/common/core/ray.h
vendored
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../../common/sys/platform.h"
|
||||
#include "../../../common/sys/ref.h"
|
||||
#include "../../../common/sys/intrinsics.h"
|
||||
#include "../../../common/sys/sysinfo.h"
|
||||
#include "../../../common/sys/atomic.h"
|
||||
#include "../../../common/sys/vector.h"
|
||||
#include "../../../common/sys/estring.h"
|
||||
|
||||
#include "../../../common/math/emath.h"
|
||||
#include "../../../common/math/vec2.h"
|
||||
#include "../../../common/math/vec3.h"
|
||||
#include "../../../common/math/vec4.h"
|
||||
#include "../../../common/math/bbox.h"
|
||||
#include "../../../common/math/affinespace.h"
|
||||
|
||||
#include "../../../common/simd/simd.h"
|
||||
|
||||
/*! Ray structure. */
|
||||
struct __aligned(16) Ray
|
||||
{
|
||||
/*! Default construction does nothing. */
|
||||
__forceinline Ray() {}
|
||||
|
||||
/*! Constructs a ray from origin, direction, and ray segment. Near
|
||||
* has to be smaller than far. */
|
||||
__forceinline Ray(const embree::Vec3fa& org,
|
||||
const embree::Vec3fa& dir,
|
||||
float tnear = 0.0f,
|
||||
float tfar = embree::inf,
|
||||
float time = 0.0f,
|
||||
int mask = -1,
|
||||
unsigned int geomID = RTC_INVALID_GEOMETRY_ID,
|
||||
unsigned int primID = RTC_INVALID_GEOMETRY_ID)
|
||||
: org(org,tnear), dir(dir,time), tfar(tfar), mask(mask), primID(primID), geomID(geomID)
|
||||
{
|
||||
instID[0] = RTC_INVALID_GEOMETRY_ID;
|
||||
#if defined(RTC_GEOMETRY_INSTANCE_ARRAY)
|
||||
instPrimID[0] = RTC_INVALID_GEOMETRY_ID;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*! Tests if we hit something. */
|
||||
__forceinline operator bool() const { return geomID != RTC_INVALID_GEOMETRY_ID; }
|
||||
|
||||
public:
|
||||
embree::Vec3ff org; //!< Ray origin + tnear
|
||||
//float tnear; //!< Start of ray segment
|
||||
embree::Vec3ff dir; //!< Ray direction + tfar
|
||||
//float time; //!< Time of this ray for motion blur.
|
||||
float tfar; //!< End of ray segment
|
||||
unsigned int mask; //!< used to mask out objects during traversal
|
||||
unsigned int id; //!< ray ID
|
||||
unsigned int flags; //!< ray flags
|
||||
|
||||
public:
|
||||
embree::Vec3f Ng; //!< Not normalized geometry normal
|
||||
float u; //!< Barycentric u coordinate of hit
|
||||
float v; //!< Barycentric v coordinate of hit
|
||||
unsigned int primID; //!< primitive ID
|
||||
unsigned int geomID; //!< geometry ID
|
||||
unsigned int instID[RTC_MAX_INSTANCE_LEVEL_COUNT]; //!< instance ID
|
||||
#if defined(RTC_GEOMETRY_INSTANCE_ARRAY)
|
||||
unsigned int instPrimID[RTC_MAX_INSTANCE_LEVEL_COUNT]; //!< instance primitive ID
|
||||
#endif
|
||||
|
||||
__forceinline float &tnear() { return org.w; };
|
||||
__forceinline float &time() { return dir.w; };
|
||||
__forceinline float const &tnear() const { return org.w; };
|
||||
__forceinline float const &time() const { return dir.w; };
|
||||
|
||||
};
|
||||
|
||||
|
||||
__forceinline void init_Ray(Ray &ray,
|
||||
const embree::Vec3fa& org,
|
||||
const embree::Vec3fa& dir,
|
||||
float tnear = 0.0f,
|
||||
float tfar = embree::inf,
|
||||
float time = 0.0f,
|
||||
int mask = -1,
|
||||
unsigned int geomID = RTC_INVALID_GEOMETRY_ID,
|
||||
unsigned int primID = RTC_INVALID_GEOMETRY_ID)
|
||||
{
|
||||
ray = Ray(org,dir,tnear,tfar,time,mask,geomID,primID);
|
||||
}
|
||||
|
||||
typedef Ray Ray1;
|
||||
|
||||
__forceinline RTCRayHit* RTCRayHit_(Ray& ray) {
|
||||
return (RTCRayHit*)&ray;
|
||||
}
|
||||
|
||||
__forceinline RTCRayHit* RTCRayHit1_(Ray& ray) {
|
||||
return (RTCRayHit*)&ray;
|
||||
}
|
||||
|
||||
__forceinline RTCRay* RTCRay_(Ray& ray) {
|
||||
return (RTCRay*)&ray;
|
||||
}
|
||||
|
||||
__forceinline RTCHit* RTCHit_(Ray& ray)
|
||||
{
|
||||
RTCHit* hit_ptr = (RTCHit*)&(ray.Ng.x);
|
||||
return hit_ptr;
|
||||
}
|
||||
|
||||
__forceinline RTCRay* RTCRay1_(Ray& ray) {
|
||||
return (RTCRay*)&ray;
|
||||
}
|
||||
|
||||
/*! Outputs ray to stream. */
|
||||
__forceinline embree_ostream operator<<(embree_ostream cout, const Ray& ray)
|
||||
{
|
||||
cout << "{ " <<
|
||||
"org = " << ray.org << ", dir = " << ray.dir << ", near = " << ray.tnear() << ", far = " << ray.tfar << ", time = " << ray.time() << ", ";
|
||||
|
||||
for (size_t i=0; i<RTC_MAX_INSTANCE_LEVEL_COUNT; i++)
|
||||
cout << "instID" << i << " = " << ray.instID[i] << ", ";
|
||||
#if defined(RTC_GEOMETRY_INSTANCE_ARRAY)
|
||||
for (size_t i=0; i<RTC_MAX_INSTANCE_LEVEL_COUNT; i++)
|
||||
cout << "instPrimID" << i << " = " << ray.instPrimID[i] << ", ";
|
||||
#endif
|
||||
|
||||
return cout << "geomID = " << ray.geomID << ", primID = " << ray.primID << ", " << "u = " << ray.u << ", v = " << ray.v << ", Ng = " << ray.Ng << " }";
|
||||
}
|
||||
|
||||
/*! ray query context passed to intersect/occluded calls */
|
||||
struct RayQueryContext
|
||||
{
|
||||
RTCRayQueryContext context;
|
||||
void* userRayExt; //!< can be used to pass extended ray data to callbacks
|
||||
void* tutorialData;
|
||||
};
|
||||
|
||||
__forceinline void InitIntersectionContext(struct RayQueryContext* context)
|
||||
{
|
||||
rtcInitRayQueryContext(&context->context);
|
||||
context->userRayExt = NULL;
|
||||
}
|
||||
144
Framework/external/embree/tutorials/common/core/ray.isph
vendored
Normal file
144
Framework/external/embree/tutorials/common/core/ray.isph
vendored
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../math/vec.isph"
|
||||
|
||||
struct Ray1
|
||||
{
|
||||
uniform Vec3f org; //!< Ray origin
|
||||
uniform float tnear; //!< Start of ray segment
|
||||
uniform Vec3f dir; //!< Ray direction
|
||||
uniform float time; //!< Time of this ray for motion blur.
|
||||
uniform float tfar; //!< End of ray segment
|
||||
uniform int mask; //!< used to mask out objects during traversal
|
||||
uniform int id; //!< ray ID
|
||||
uniform int flags; //!< ray flags
|
||||
uniform Vec3f Ng; //!< Geometric normal.
|
||||
uniform float u; //!< Barycentric u coordinate of hit
|
||||
uniform float v; //!< Barycentric v coordinate of hit
|
||||
uniform int primID; //!< primitive ID
|
||||
uniform int geomID; //!< geometry ID
|
||||
uniform int instID[RTC_MAX_INSTANCE_LEVEL_COUNT]; //!< instance ID
|
||||
#if defined(RTC_GEOMETRY_INSTANCE_ARRAY)
|
||||
uniform int instPrimID[RTC_MAX_INSTANCE_LEVEL_COUNT]; //!< instance ID
|
||||
#endif
|
||||
varying int align[0]; //!< aligns ray on stack to at least 16 bytes
|
||||
};
|
||||
|
||||
inline uniform RTCRayHit* uniform RTCRayHit1_(uniform Ray1& ray)
|
||||
{
|
||||
uniform RTCRayHit* uniform ray_ptr = (uniform RTCRayHit* uniform)&ray;
|
||||
return ray_ptr;
|
||||
}
|
||||
|
||||
/*! Ray structure. Contains all information about a ray including
|
||||
* precomputed reciprocal direction. */
|
||||
struct Ray
|
||||
{
|
||||
Vec3f org; //!< Ray origin
|
||||
float tnear; //!< Start of ray segment
|
||||
Vec3f dir; //!< Ray direction
|
||||
float time; //!< Time of this ray for motion blur.
|
||||
float tfar; //!< End of ray segment
|
||||
int mask; //!< used to mask out objects during traversal
|
||||
int id; //!< ray ID
|
||||
int flags; //!< ray flags
|
||||
Vec3f Ng; //!< Geometric normal.
|
||||
float u; //!< Barycentric u coordinate of hit
|
||||
float v; //!< Barycentric v coordinate of hit
|
||||
int primID; //!< primitive ID
|
||||
int geomID; //!< geometry ID
|
||||
int instID[RTC_MAX_INSTANCE_LEVEL_COUNT]; //!< instance ID
|
||||
#if defined(RTC_GEOMETRY_INSTANCE_ARRAY)
|
||||
int instPrimID[RTC_MAX_INSTANCE_LEVEL_COUNT]; //!< instance ID
|
||||
#endif
|
||||
};
|
||||
|
||||
inline varying RTCRayHit* uniform RTCRayHit_(varying Ray& ray)
|
||||
{
|
||||
varying RTCRayHit* uniform ray_ptr = (varying RTCRayHit* uniform)&ray;
|
||||
return ray_ptr;
|
||||
}
|
||||
|
||||
inline varying RTCRay* uniform RTCRay_(varying Ray& ray)
|
||||
{
|
||||
varying RTCRay* uniform ray_ptr = (varying RTCRay* uniform)&ray;
|
||||
return ray_ptr;
|
||||
}
|
||||
|
||||
inline varying RTCHit* uniform RTCHit_(varying Ray& ray)
|
||||
{
|
||||
varying RTCHit* uniform hit_ptr = (varying RTCHit* uniform)&(ray.Ng.x);
|
||||
return hit_ptr;
|
||||
}
|
||||
|
||||
/*! Constructs a ray from origin, direction, and ray segment. Near
|
||||
* has to be smaller than far. */
|
||||
inline Ray make_Ray(const Vec3f org,
|
||||
const Vec3f dir,
|
||||
const float tnear = 0.0f,
|
||||
const float tfar = inf,
|
||||
const float time = 0.0f,
|
||||
const int mask = -1,
|
||||
const int geomID = -1,
|
||||
const int primID = -1)
|
||||
{
|
||||
Ray ray;
|
||||
ray.org = org;
|
||||
ray.tnear = tnear;
|
||||
ray.dir = dir;
|
||||
ray.time = time;
|
||||
ray.tfar = tfar;
|
||||
ray.mask = mask;
|
||||
ray.geomID = geomID;
|
||||
ray.primID = primID;
|
||||
ray.instID[0] = RTC_INVALID_GEOMETRY_ID;
|
||||
#if defined(RTC_GEOMETRY_INSTANCE_ARRAY)
|
||||
ray.instPrimID[0] = RTC_INVALID_GEOMETRY_ID;
|
||||
#endif
|
||||
return ray;
|
||||
}
|
||||
|
||||
inline void init_Ray(Ray &ray,
|
||||
const Vec3f org,
|
||||
const Vec3f dir,
|
||||
const float tnear = 0.0f,
|
||||
const float tfar = inf,
|
||||
const float time = 0.0f,
|
||||
const int mask = -1,
|
||||
const int geomID = -1,
|
||||
const int primID = -1)
|
||||
{
|
||||
ray.org = org;
|
||||
ray.tnear = tnear;
|
||||
ray.dir = dir;
|
||||
ray.time = time;
|
||||
ray.tfar = tfar;
|
||||
ray.mask = mask;
|
||||
ray.geomID = geomID;
|
||||
ray.primID = primID;
|
||||
ray.instID[0] = RTC_INVALID_GEOMETRY_ID;
|
||||
#if defined(RTC_GEOMETRY_INSTANCE_ARRAY)
|
||||
ray.instPrimID[0] = RTC_INVALID_GEOMETRY_ID;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool noHit(const Ray& r) { return r.geomID < 0; }
|
||||
|
||||
inline bool hadHit(const Ray& r) { return r.geomID >= 0; }
|
||||
|
||||
/*! ray query context passed to intersect/occluded calls */
|
||||
struct RayQueryContext
|
||||
{
|
||||
RTCRayQueryContext context;
|
||||
void* userRayExt; //!< can be used to pass extended ray data to callbacks
|
||||
void* tutorialData;
|
||||
};
|
||||
|
||||
inline void InitIntersectionContext(uniform RayQueryContext* uniform context)
|
||||
{
|
||||
rtcInitRayQueryContext(&context->context);
|
||||
context->userRayExt = NULL;
|
||||
}
|
||||
28
Framework/external/embree/tutorials/common/default.h
vendored
Normal file
28
Framework/external/embree/tutorials/common/default.h
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../kernels/config.h"
|
||||
#include "../../common/sys/platform.h"
|
||||
#include "../../common/sys/sysinfo.h"
|
||||
#include "../../common/sys/ref.h"
|
||||
#include "../../common/sys/vector.h"
|
||||
#include "../../common/math/vec2.h"
|
||||
#include "../../common/math/vec3.h"
|
||||
#include "../../common/math/vec4.h"
|
||||
#include "../../common/math/bbox.h"
|
||||
#include "../../common/math/lbbox.h"
|
||||
#include "../../common/math/affinespace.h"
|
||||
#include "../../common/sys/filename.h"
|
||||
#include "../../common/sys/estring.h"
|
||||
#include "../../common/lexers/tokenstream.h"
|
||||
#include "../../common/lexers/streamfilters.h"
|
||||
#include "../../common/lexers/parsestream.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <deque>
|
||||
53
Framework/external/embree/tutorials/common/device_default.h
vendored
Normal file
53
Framework/external/embree/tutorials/common/device_default.h
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(EMBREE_SYCL_SUPPORT)
|
||||
// If we use the internal clang frontend of the dpc++ compiler directly __INTEL_LLVM_COMPILER is not set.
|
||||
// I think doing this is fine because normal clang can not compile dpcpp/sycl code anyway.
|
||||
#if defined(__WIN32__) and defined(__clang__) and !defined(__INTEL_LLVM_COMPILER)
|
||||
#define __INTEL_LLVM_COMPILER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(EMBREE_SYCL_TUTORIAL)
|
||||
# define __SYCL_USE_NON_VARIADIC_SPIRV_OCL_PRINTF__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
# pragma clang diagnostic ignored "-W#pragma-messages"
|
||||
# include <sycl/sycl.hpp>
|
||||
# pragma clang diagnostic pop
|
||||
#else
|
||||
# if !defined(SYCL_EXTERNAL)
|
||||
# define SYCL_EXTERNAL
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* include embree API */
|
||||
#include "../../include/embree4/rtcore.h"
|
||||
RTC_NAMESPACE_USE
|
||||
#include "../../kernels/config.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
#if defined(EMBREE_SYCL_TUTORIAL) && defined(EMBREE_SYCL_SUPPORT)
|
||||
|
||||
extern sycl::queue *global_gpu_queue;
|
||||
extern sycl::context *global_gpu_context;
|
||||
extern sycl::device *global_gpu_device;
|
||||
|
||||
/* returns function pointer to be usable in SYCL kernel */
|
||||
template<auto F>
|
||||
inline decltype(F) getFunctionPointer() {
|
||||
return rtcGetSYCLDeviceFunctionPointer<F>(*global_gpu_queue);
|
||||
}
|
||||
#define GET_FUNCTION_POINTER(f) getFunctionPointer<f>()
|
||||
|
||||
#else
|
||||
|
||||
#define GET_FUNCTION_POINTER(f) f
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
15
Framework/external/embree/tutorials/common/device_default.isph
vendored
Normal file
15
Framework/external/embree/tutorials/common/device_default.isph
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#define SYCL_EXTERNAL
|
||||
|
||||
/* include embree API */
|
||||
#include "../../include/embree4/rtcore.isph"
|
||||
RTC_NAMESPACE_USE
|
||||
#include "../../kernels/config.h"
|
||||
|
||||
#define GET_FUNCTION_POINTER(f) f
|
||||
|
||||
|
||||
112
Framework/external/embree/tutorials/common/glfw/glfw.patch
vendored
Normal file
112
Framework/external/embree/tutorials/common/glfw/glfw.patch
vendored
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
From 8dfd5804447a1f35c15e650737fee3694bc71f26 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Reibold <florian.reibold@intel.com>
|
||||
Date: Mon, 6 Feb 2023 17:29:44 +0100
|
||||
Subject: [PATCH] fix LoadLibraryA
|
||||
|
||||
---
|
||||
src/null_platform.h | 2 +-
|
||||
src/wgl_context.c | 2 +-
|
||||
src/win32_init.c | 12 ++++++------
|
||||
src/win32_platform.h | 2 +-
|
||||
4 files changed, 9 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/src/null_platform.h b/src/null_platform.h
|
||||
index 708975d1..d916b922 100644
|
||||
--- a/src/null_platform.h
|
||||
+++ b/src/null_platform.h
|
||||
@@ -43,7 +43,7 @@
|
||||
#include "null_joystick.h"
|
||||
|
||||
#if defined(_GLFW_WIN32)
|
||||
- #define _glfw_dlopen(name) LoadLibraryA(name)
|
||||
+ #define _glfw_dlopen(name) LoadLibraryExA(name,NULL,LOAD_LIBRARY_SEARCH_SYSTEM32)
|
||||
#define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle)
|
||||
#define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name)
|
||||
#else
|
||||
diff --git a/src/wgl_context.c b/src/wgl_context.c
|
||||
index 72ad11de..5c42fa81 100644
|
||||
--- a/src/wgl_context.c
|
||||
+++ b/src/wgl_context.c
|
||||
@@ -416,7 +416,7 @@ GLFWbool _glfwInitWGL(void)
|
||||
if (_glfw.wgl.instance)
|
||||
return GLFW_TRUE;
|
||||
|
||||
- _glfw.wgl.instance = LoadLibraryA("opengl32.dll");
|
||||
+ _glfw.wgl.instance = LoadLibraryExA("opengl32.dll",NULL,LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (!_glfw.wgl.instance)
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
diff --git a/src/win32_init.c b/src/win32_init.c
|
||||
index 885f32fa..5e698cc2 100644
|
||||
--- a/src/win32_init.c
|
||||
+++ b/src/win32_init.c
|
||||
@@ -82,7 +82,7 @@ static GLFWbool loadLibraries(void)
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
- _glfw.win32.user32.instance = LoadLibraryA("user32.dll");
|
||||
+ _glfw.win32.user32.instance = LoadLibraryExA("user32.dll",NULL,LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (!_glfw.win32.user32.instance)
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
@@ -105,7 +105,7 @@ static GLFWbool loadLibraries(void)
|
||||
_glfw.win32.user32.GetSystemMetricsForDpi_ = (PFN_GetSystemMetricsForDpi)
|
||||
GetProcAddress(_glfw.win32.user32.instance, "GetSystemMetricsForDpi");
|
||||
|
||||
- _glfw.win32.dinput8.instance = LoadLibraryA("dinput8.dll");
|
||||
+ _glfw.win32.dinput8.instance = LoadLibraryExA("dinput8.dll",NULL,LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (_glfw.win32.dinput8.instance)
|
||||
{
|
||||
_glfw.win32.dinput8.Create = (PFN_DirectInput8Create)
|
||||
@@ -126,7 +126,7 @@ static GLFWbool loadLibraries(void)
|
||||
|
||||
for (i = 0; names[i]; i++)
|
||||
{
|
||||
- _glfw.win32.xinput.instance = LoadLibraryA(names[i]);
|
||||
+ _glfw.win32.xinput.instance = LoadLibraryExA(names[i],NULL,LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (_glfw.win32.xinput.instance)
|
||||
{
|
||||
_glfw.win32.xinput.GetCapabilities = (PFN_XInputGetCapabilities)
|
||||
@@ -139,7 +139,7 @@ static GLFWbool loadLibraries(void)
|
||||
}
|
||||
}
|
||||
|
||||
- _glfw.win32.dwmapi.instance = LoadLibraryA("dwmapi.dll");
|
||||
+ _glfw.win32.dwmapi.instance = LoadLibraryExA("dwmapi.dll",NULL,LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (_glfw.win32.dwmapi.instance)
|
||||
{
|
||||
_glfw.win32.dwmapi.IsCompositionEnabled = (PFN_DwmIsCompositionEnabled)
|
||||
@@ -152,7 +152,7 @@ static GLFWbool loadLibraries(void)
|
||||
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmGetColorizationColor");
|
||||
}
|
||||
|
||||
- _glfw.win32.shcore.instance = LoadLibraryA("shcore.dll");
|
||||
+ _glfw.win32.shcore.instance = LoadLibraryExA("shcore.dll",NULL,LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (_glfw.win32.shcore.instance)
|
||||
{
|
||||
_glfw.win32.shcore.SetProcessDpiAwareness_ = (PFN_SetProcessDpiAwareness)
|
||||
@@ -161,7 +161,7 @@ static GLFWbool loadLibraries(void)
|
||||
GetProcAddress(_glfw.win32.shcore.instance, "GetDpiForMonitor");
|
||||
}
|
||||
|
||||
- _glfw.win32.ntdll.instance = LoadLibraryA("ntdll.dll");
|
||||
+ _glfw.win32.ntdll.instance = LoadLibraryExA("ntdll.dll",NULL,LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (_glfw.win32.ntdll.instance)
|
||||
{
|
||||
_glfw.win32.ntdll.RtlVerifyVersionInfo_ = (PFN_RtlVerifyVersionInfo)
|
||||
diff --git a/src/win32_platform.h b/src/win32_platform.h
|
||||
index bf703d7e..55b8425b 100644
|
||||
--- a/src/win32_platform.h
|
||||
+++ b/src/win32_platform.h
|
||||
@@ -289,7 +289,7 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(
|
||||
#define _GLFW_WNDCLASSNAME L"GLFW30"
|
||||
#endif
|
||||
|
||||
-#define _glfw_dlopen(name) LoadLibraryA(name)
|
||||
+#define _glfw_dlopen(name) LoadLibraryExA(name,NULL,LOAD_LIBRARY_SEARCH_SYSTEM32)
|
||||
#define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle)
|
||||
#define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name)
|
||||
|
||||
--
|
||||
2.38.1.windows.1
|
||||
|
||||
51
Framework/external/embree/tutorials/common/image/CMakeLists.txt
vendored
Normal file
51
Framework/external/embree/tutorials/common/image/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
## Copyright 2009-2021 Intel Corporation
|
||||
## SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ${CMAKE_MODULE_PATH})
|
||||
INCLUDE(CMakeDependentOption)
|
||||
|
||||
SET(ADDITIONAL_SOURCES)
|
||||
|
||||
## FIND_PACKAGE(OpenImageIO)
|
||||
## MARK_AS_ADVANCED(
|
||||
## OPENIMAGEIO_ROOT
|
||||
## )
|
||||
CMAKE_DEPENDENT_OPTION(EMBREE_TUTORIALS_OPENIMAGEIO "Enables BMP, GIF, PNG, TGA, TIFF image codecs." OFF "EMBREE_TUTORIALS AND OPENIMAGEIO_FOUND" OFF)
|
||||
IF (EMBREE_TUTORIALS_OPENIMAGEIO)
|
||||
ADD_DEFINITIONS(-DUSE_OPENIMAGEIO)
|
||||
INCLUDE_DIRECTORIES(${OPENIMAGEIO_INCLUDE_DIRS})
|
||||
SET(ADDITIONAL_LIBRARIES ${ADDITIONAL_LIBRARIES} ${OPENIMAGEIO_LIBRARIES})
|
||||
SET(ADDITIONAL_SOURCES ${ADDITIONAL_SOURCES} oiio.cpp)
|
||||
ENDIF (EMBREE_TUTORIALS_OPENIMAGEIO)
|
||||
|
||||
FIND_PACKAGE(JPEG)
|
||||
CMAKE_DEPENDENT_OPTION(EMBREE_TUTORIALS_LIBJPEG "Enables JPEG image codec." OFF "EMBREE_TUTORIALS AND JPEG_FOUND" OFF)
|
||||
IF (EMBREE_TUTORIALS_LIBJPEG)
|
||||
ADD_DEFINITIONS(-DEMBREE_TUTORIALS_LIBJPEG)
|
||||
INCLUDE_DIRECTORIES(${JPEG_INCLUDE_DIR})
|
||||
SET(ADDITIONAL_LIBRARIES ${ADDITIONAL_LIBRARIES} ${JPEG_LIBRARIES})
|
||||
SET(ADDITIONAL_SOURCES ${ADDITIONAL_SOURCES} jpeg.cpp)
|
||||
ENDIF (EMBREE_TUTORIALS_LIBJPEG)
|
||||
|
||||
FIND_PACKAGE(PNG)
|
||||
CMAKE_DEPENDENT_OPTION(EMBREE_TUTORIALS_LIBPNG "Enables PNG image codecs." OFF "EMBREE_TUTORIALS AND PNG_FOUND" OFF)
|
||||
IF (EMBREE_TUTORIALS_LIBPNG)
|
||||
ADD_DEFINITIONS(-DEMBREE_TUTORIALS_LIBPNG)
|
||||
INCLUDE_DIRECTORIES(${PNG_INCLUDE_DIR})
|
||||
SET(ADDITIONAL_LIBRARIES ${ADDITIONAL_LIBRARIES} ${PNG_LIBRARIES})
|
||||
ENDIF (EMBREE_TUTORIALS_LIBPNG)
|
||||
|
||||
ADD_LIBRARY(image STATIC
|
||||
image.cpp
|
||||
pfm.cpp
|
||||
ppm.cpp
|
||||
tga.cpp
|
||||
png.cpp
|
||||
stb.cpp
|
||||
exr.cpp
|
||||
${ADDITIONAL_SOURCES}
|
||||
)
|
||||
|
||||
TARGET_LINK_LIBRARIES(image sys math ${ADDITIONAL_LIBRARIES})
|
||||
SET_PROPERTY(TARGET image PROPERTY FOLDER tutorials/common)
|
||||
SET_PROPERTY(TARGET image APPEND PROPERTY COMPILE_FLAGS " ${FLAGS_LOWEST}")
|
||||
70
Framework/external/embree/tutorials/common/image/exr.cpp
vendored
Normal file
70
Framework/external/embree/tutorials/common/image/exr.cpp
vendored
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "image.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
#define TINYEXR_USE_MINIZ 0
|
||||
//#include "zlib.h"
|
||||
//Or, if your project uses `stb_image[_write].h`, use their
|
||||
//zlib implementation:
|
||||
#define TINYEXR_USE_STB_ZLIB 1
|
||||
#define TINYEXR_IMPLEMENTATION
|
||||
#include "tinyexr.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
/*! read PFM file from disk */
|
||||
Ref<Image> loadEXR(const FileName& fileName)
|
||||
{
|
||||
float* rgba; // width * height * RGBA
|
||||
int width;
|
||||
int height;
|
||||
const char* err = NULL; // or nullptr in C++11
|
||||
|
||||
int ret = LoadEXR(&rgba, &width, &height, fileName.str().c_str(), &err);
|
||||
if (ret != TINYEXR_SUCCESS) {
|
||||
if (err) {
|
||||
std::cerr << "ERR: " << err;
|
||||
FreeEXRErrorMessage(err);
|
||||
}
|
||||
THROW_RUNTIME_ERROR("Could not load image " + fileName.str())
|
||||
}
|
||||
|
||||
/* create image and fill with data */
|
||||
Ref<Image> img = new Image4f(width,height,fileName);
|
||||
|
||||
for (ssize_t y=0; y<height; y++) {
|
||||
for (ssize_t x=0; x<width; x++) {
|
||||
float* pix = rgba + (y * width + x) * 4;
|
||||
img->set(x,y,Color4(pix[0],pix[1],pix[2],1.0f));
|
||||
}
|
||||
}
|
||||
free(rgba);
|
||||
return img;
|
||||
}
|
||||
|
||||
/*! store PFM file to disk */
|
||||
void storeEXR(const Ref<Image>& img, const FileName& fileName)
|
||||
{
|
||||
std::vector<Col3f> rgb(img->width * img->height);
|
||||
for (size_t y=0; y<img->height; ++y) {
|
||||
for (size_t x=0; x<img->width; ++x) {
|
||||
Color4 c = img->get(x, y);
|
||||
rgb[y * img->width + x] = Col3f(c.r, c.g, c.b);
|
||||
}
|
||||
}
|
||||
const char* err = NULL;
|
||||
int ret = SaveEXR((float*)rgb.data(), img->width, img->height, 3, 0, fileName.str().c_str(), &err);
|
||||
if (ret != TINYEXR_SUCCESS) {
|
||||
if (err) {
|
||||
std::cerr << "ERR: " << err;
|
||||
FreeEXRErrorMessage(err);
|
||||
}
|
||||
THROW_RUNTIME_ERROR("Could not save image " + fileName.str())
|
||||
}
|
||||
}
|
||||
}
|
||||
122
Framework/external/embree/tutorials/common/image/image.cpp
vendored
Normal file
122
Framework/external/embree/tutorials/common/image/image.cpp
vendored
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "image.h"
|
||||
#include "../../../common/sys/estring.h"
|
||||
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
namespace embree
|
||||
{
|
||||
double compareImages(Ref<Image> image0, Ref<Image> image1)
|
||||
{
|
||||
/* compare image size */
|
||||
const size_t width = image0->width;
|
||||
const size_t height = image0->height;
|
||||
if (image1->width != width) return inf;
|
||||
if (image1->height != height) return inf;
|
||||
|
||||
/* compare both images */
|
||||
double diff = 0.0;
|
||||
for (size_t y=0; y<height; y++)
|
||||
{
|
||||
for (size_t x=0; x<width; x++)
|
||||
{
|
||||
const Color c0 = image0->get(x,y);
|
||||
const Color c1 = image1->get(x,y);
|
||||
diff += sqr(fabs(c0.r - c1.r))/3.0f;
|
||||
diff += sqr(fabs(c0.g - c1.g))/3.0f;
|
||||
diff += sqr(fabs(c0.b - c1.b))/3.0f;
|
||||
}
|
||||
}
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
/*! loads an image from a file with auto-detection of format */
|
||||
Ref<Image> loadImageFromDisk(const FileName& fileName)
|
||||
{
|
||||
std::string ext = toLowerCase(fileName.ext());
|
||||
|
||||
#ifdef EMBREE_TUTORIALS_LIBPNG
|
||||
if (ext == "png" ) return loadPNG(fileName);
|
||||
#endif
|
||||
|
||||
#ifdef EMBREE_TUTORIALS_LIBJPEG
|
||||
if (ext == "jpg" ) return loadJPEG(fileName);
|
||||
#endif
|
||||
|
||||
#ifdef USE_OPENIMAGEIO
|
||||
if (ext == "bmp" ) return loadOIIO(fileName);
|
||||
if (ext == "gif" ) return loadOIIO(fileName);
|
||||
if (ext == "tga" ) return loadOIIO(fileName);
|
||||
if (ext == "tif" ) return loadOIIO(fileName);
|
||||
if (ext == "tiff") return loadOIIO(fileName);
|
||||
if (ext == "png" ) return loadOIIO(fileName);
|
||||
if (ext == "jpg" ) return loadOIIO(fileName);
|
||||
#endif
|
||||
|
||||
if (ext == "bmp" ) return loadSTB(fileName);
|
||||
if (ext == "png" ) return loadSTB(fileName);
|
||||
if (ext == "jpg" ) return loadSTB(fileName);
|
||||
|
||||
if (ext == "exr" ) return loadEXR(fileName);
|
||||
|
||||
if (ext == "pfm" ) return loadPFM(fileName);
|
||||
if (ext == "ppm" ) return loadPPM(fileName);
|
||||
if (ext == "tga" ) return loadTGA(fileName);
|
||||
THROW_RUNTIME_ERROR("image format " + ext + " not supported");
|
||||
}
|
||||
|
||||
static std::map<std::string,Ref<Image> > image_cache;
|
||||
|
||||
/*! loads an image from a file with auto-detection of format */
|
||||
Ref<Image> loadImage(const FileName& fileName, bool cache)
|
||||
{
|
||||
if (!cache)
|
||||
return loadImageFromDisk(fileName);
|
||||
|
||||
if (image_cache.find(fileName) == image_cache.end())
|
||||
image_cache[fileName] = loadImageFromDisk(fileName);
|
||||
|
||||
return image_cache[fileName];
|
||||
}
|
||||
|
||||
/*! stores an image to file with auto-detection of format */
|
||||
void storeImage(const Ref<Image>& img, const FileName& fileName)
|
||||
{
|
||||
std::string ext = toLowerCase(fileName.ext());
|
||||
|
||||
#ifdef EMBREE_TUTORIALS_LIBJPEG
|
||||
if (ext == "jpg" ) { storeJPEG(img, fileName); return; }
|
||||
#endif
|
||||
|
||||
#ifdef USE_OPENIMAGEIO
|
||||
if (ext == "bmp" ) { storeOIIO(img, fileName); return; }
|
||||
if (ext == "gif" ) { storeOIIO(img, fileName); return; }
|
||||
if (ext == "tga" ) { storeOIIO(img, fileName); return; }
|
||||
if (ext == "tif" ) { storeOIIO(img, fileName); return; }
|
||||
if (ext == "tiff") { storeOIIO(img, fileName); return; }
|
||||
if (ext == "png" ) { storeOIIO(img, fileName); return; }
|
||||
if (ext == "jpg" ) { storeOIIO(img, fileName); return; }
|
||||
#endif
|
||||
|
||||
if (ext == "bmp" ) { storeSTB(img, fileName); return; }
|
||||
if (ext == "png" ) { storeSTB(img, fileName); return; }
|
||||
if (ext == "jpg" ) { storeSTB(img, fileName); return; }
|
||||
|
||||
if (ext == "exr" ) { storeEXR(img, fileName); return; }
|
||||
|
||||
if (ext == "pfm" ) { storePFM(img, fileName); return; }
|
||||
if (ext == "ppm" ) { storePPM(img, fileName); return; }
|
||||
if (ext == "tga" ) { storeTga(img, fileName); return; }
|
||||
THROW_RUNTIME_ERROR("image format " + ext + " not supported");
|
||||
}
|
||||
|
||||
/*! template instantiations */
|
||||
template class ImageT<Col3uc>;
|
||||
template class ImageT<Col3f>;
|
||||
|
||||
}
|
||||
205
Framework/external/embree/tutorials/common/image/image.h
vendored
Normal file
205
Framework/external/embree/tutorials/common/image/image.h
vendored
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../../common/sys/platform.h"
|
||||
#include "../../../common/sys/ref.h"
|
||||
#include "../../../common/sys/filename.h"
|
||||
#include "../../../common/math/color.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace embree
|
||||
{
|
||||
/* virtual interface to image */
|
||||
class Image : public RefCount {
|
||||
public:
|
||||
Image (size_t width, size_t height, const std::string& name) : width(width), height(height), name(name) {}
|
||||
virtual ~Image() {}
|
||||
virtual Color4 get(size_t x, size_t y) const = 0;
|
||||
virtual void set(size_t x, size_t y, const Color4& c) = 0;
|
||||
void set(size_t x, size_t y, const Color& c) { set(x,y,Color4(c.r,c.g,c.b,1.0f)); }
|
||||
void convertToRGBA8(unsigned char *dest)
|
||||
{
|
||||
for (size_t y=0;y<height;y++)
|
||||
for (size_t x=0;x<width;x++)
|
||||
{
|
||||
size_t offset = 4 * (y * width + x);
|
||||
Color4 c = get(x,y);
|
||||
dest[offset+0] = (unsigned char)(c.r * 255.0f);
|
||||
dest[offset+1] = (unsigned char)(c.g * 255.0f);
|
||||
dest[offset+2] = (unsigned char)(c.b * 255.0f);
|
||||
dest[offset+3] = (unsigned char)(c.a * 255.0f);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Image (const Image& other) DELETED; // do not implement
|
||||
Image& operator= (const Image& other) DELETED; // do not implement
|
||||
|
||||
public:
|
||||
size_t width,height;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
/* main image class templated over element type */
|
||||
template<typename T>
|
||||
class ImageT : public Image {
|
||||
public:
|
||||
|
||||
/*! create empty image */
|
||||
ImageT (size_t width = 0, size_t height = 0, const std::string& name = "")
|
||||
: Image(width,height,name)
|
||||
{
|
||||
data = new T[width*height];
|
||||
memset(data,0,width*height*sizeof(T));
|
||||
}
|
||||
|
||||
/*! create image of constant color */
|
||||
ImageT (size_t width, size_t height, const T& color, const std::string& name = "")
|
||||
: Image(width,height,name)
|
||||
{
|
||||
data = new T[width*height];
|
||||
for (size_t i=0; i<width*height; i++) data[i] = color;
|
||||
}
|
||||
|
||||
/*! initialize image from color data */
|
||||
ImageT (size_t width, size_t height, T* color, const bool copy = true, const std::string& name = "", const bool flip_y = false)
|
||||
: Image(width,height,name)
|
||||
{
|
||||
if (copy)
|
||||
{
|
||||
data = new T[width*height];
|
||||
|
||||
if (flip_y)
|
||||
{
|
||||
const T* in = color + (height-1) * width;
|
||||
T* out = data;
|
||||
|
||||
for (size_t y=0; y<height; y++)
|
||||
{
|
||||
for (size_t x=0; x<width; x++)
|
||||
out[x] = in[x];
|
||||
|
||||
in -= width;
|
||||
out += width;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i=0; i<width*height; i++)
|
||||
data[i] = color[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
data = color;
|
||||
}
|
||||
}
|
||||
|
||||
/*! image destruction */
|
||||
virtual ~ImageT() {
|
||||
delete[] data; data = nullptr;
|
||||
}
|
||||
|
||||
/*! returns pixel color */
|
||||
__forceinline Color4 get(size_t x, size_t y) const {
|
||||
return Color4(data[y*width+x]);
|
||||
}
|
||||
|
||||
/*! sets pixel */
|
||||
__forceinline void set(size_t x, size_t y, const Color4& c) {
|
||||
c.set(data[y*width+x]);
|
||||
}
|
||||
|
||||
/*! returns data pointer of image */
|
||||
__forceinline void* ptr() {
|
||||
return (void*)data;
|
||||
}
|
||||
|
||||
/*! returns and forgets about data pointer of image */
|
||||
__forceinline void* steal_ptr() {
|
||||
T* ptr = data;
|
||||
data = nullptr;
|
||||
return (void*)ptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
T* data;
|
||||
};
|
||||
|
||||
/*! Shortcuts for common image types. */
|
||||
typedef ImageT<Col3uc> Image3uc;
|
||||
typedef ImageT<Col3f> Image3f;
|
||||
typedef ImageT<Col4uc> Image4uc;
|
||||
typedef ImageT<Col4f> Image4f;
|
||||
|
||||
/*! Generate a JPEG encoded image from a RGB8 buffer in memory. */
|
||||
void encodeRGB8_to_JPEG(unsigned char *image, size_t width, size_t height, unsigned char **encoded, unsigned long *capacity);
|
||||
|
||||
/*! compare two images */
|
||||
double compareImages(Ref<Image> image0, Ref<Image> image1);
|
||||
|
||||
/*! Loads image from file. Format is auto detected. */
|
||||
Ref<Image> loadImage(const FileName& filename, bool cache = false);
|
||||
|
||||
/*! Loads image from JPEG file. */
|
||||
Ref<Image> loadJPEG(const FileName& fileName);
|
||||
|
||||
/*! Loads image using OpenImageIO. */
|
||||
Ref<Image> loadOIIO(const FileName& fileName);
|
||||
|
||||
/*! Loads image using stb_image. */
|
||||
Ref<Image> loadSTB(const FileName& fileName);
|
||||
|
||||
/*! Loads image from EXR file. */
|
||||
Ref<Image> loadEXR(const FileName& fileName);
|
||||
|
||||
/*! Loads image from PFM file. */
|
||||
Ref<Image> loadPFM(const FileName& fileName);
|
||||
|
||||
/*! Loads image from PNG file. */
|
||||
Ref<Image> loadPNG(const FileName& fileName);
|
||||
|
||||
/*! Loads image from PPM file. */
|
||||
Ref<Image> loadPPM(const FileName& fileName);
|
||||
|
||||
/*! Loads image from TGA file. */
|
||||
Ref<Image> loadTGA(const FileName& fileName);
|
||||
|
||||
/*! Loads image from TIFF file. */
|
||||
//Ref<Image> loadTIFF(const FileName& fileName);
|
||||
|
||||
/*! Store image to file. Format is auto detected. */
|
||||
void storeImage(const Ref<Image>& image, const FileName& filename);
|
||||
|
||||
/*! Store image to JPEG file. */
|
||||
void storeJPEG(const Ref<Image>& img, const FileName& fileName);
|
||||
|
||||
/*! Store image to file using OpenImageIO. */
|
||||
void storeOIIO(const Ref<Image>& img, const FileName& fileName);
|
||||
|
||||
/*! Store image to file using stb_image. */
|
||||
void storeSTB(const Ref<Image>& img, const FileName& fileName);
|
||||
|
||||
/*! Store image to EXR file. */
|
||||
void storeEXR(const Ref<Image>& img, const FileName& fileName);
|
||||
|
||||
/*! Store image to PFM file. */
|
||||
void storePFM(const Ref<Image>& img, const FileName& fileName);
|
||||
|
||||
/*! Store image to PNG file. */
|
||||
//void storePNG(const Ref<Image>& img, const FileName& fileName);
|
||||
|
||||
/*! Store image to PPM file. */
|
||||
void storePPM(const Ref<Image>& img, const FileName& fileName);
|
||||
|
||||
/*! Store image to TGA file. */
|
||||
void storeTga(const Ref<Image>& img, const FileName& fileName);
|
||||
|
||||
/*! Store image to TIFF file. */
|
||||
//void storeTIFF(const Ref<Image>& img, const FileName& fileName);
|
||||
|
||||
}
|
||||
192
Framework/external/embree/tutorials/common/image/jpeg.cpp
vendored
Normal file
192
Framework/external/embree/tutorials/common/image/jpeg.cpp
vendored
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#ifdef EMBREE_TUTORIALS_LIBJPEG
|
||||
|
||||
#include "image.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
void compress(struct jpeg_compress_struct *cinfo, unsigned char *image)
|
||||
{
|
||||
|
||||
/*! Start compression. */
|
||||
jpeg_start_compress(cinfo, TRUE);
|
||||
|
||||
/*! Pointer to and size of a scanline in the image. */
|
||||
JSAMPROW scanline[1]; size_t bytes = cinfo->image_width * cinfo->input_components;
|
||||
|
||||
/*! Here we use the library state variable 'next_scanline' as the loop index. */
|
||||
while (cinfo->next_scanline < cinfo->image_height) {
|
||||
scanline[0] = &image[cinfo->next_scanline * bytes];
|
||||
jpeg_write_scanlines(cinfo, scanline, 1);
|
||||
}
|
||||
|
||||
/*! Finish compression. */
|
||||
jpeg_finish_compress(cinfo);
|
||||
|
||||
}
|
||||
|
||||
unsigned char *decompress(struct jpeg_decompress_struct *cinfo)
|
||||
{
|
||||
/*! Start decompression. */
|
||||
jpeg_start_decompress(cinfo);
|
||||
|
||||
/*! Bytes per row in the scanline buffer. */
|
||||
size_t bytes = cinfo->output_width * cinfo->output_components;
|
||||
|
||||
/*! Allocate scratch space for a single scanline. */
|
||||
JSAMPARRAY scanline = (*cinfo->mem->alloc_sarray)((j_common_ptr) cinfo, JPOOL_IMAGE, bytes, 1);
|
||||
|
||||
/*! Allocate storage for the decompressed image. */
|
||||
unsigned char* image = new unsigned char[cinfo->output_height * bytes];
|
||||
|
||||
/*! Here we use the library state variable 'output_scanline' as the loop index. */
|
||||
while (cinfo->output_scanline < cinfo->output_height) {
|
||||
jpeg_read_scanlines(cinfo, scanline, 1);
|
||||
for (size_t i=0; i<bytes; i++)
|
||||
image[(cinfo->output_scanline - 1) * bytes + i] = scanline[0][i];
|
||||
}
|
||||
|
||||
/*! Finish decompression. */
|
||||
jpeg_finish_decompress(cinfo);
|
||||
return(image);
|
||||
}
|
||||
|
||||
void encodeRGB8_to_JPEG(unsigned char *image, size_t width, size_t height, unsigned char **encoded, unsigned long *capacity)
|
||||
{
|
||||
|
||||
#if JPEG_LIB_VERSION >= 80
|
||||
|
||||
/*! Compression parameters and scratch space pointers (allocated by the library). */
|
||||
struct jpeg_compress_struct cinfo;
|
||||
|
||||
/*! The library error handler. */
|
||||
struct jpeg_error_mgr jerror; cinfo.err = jpeg_std_error(&jerror);
|
||||
|
||||
/*! Initialize the JPEG compression object. */
|
||||
jpeg_create_compress(&cinfo);
|
||||
|
||||
/*! Specify the incoming image resolution, color space, and color space components. */
|
||||
cinfo.image_width = width; cinfo.image_height = height; cinfo.in_color_space = JCS_RGB; cinfo.input_components = 3;
|
||||
|
||||
/*! Fill in a sensible set of defaults. */
|
||||
jpeg_set_defaults(&cinfo);
|
||||
|
||||
/*! Set the image quality. */
|
||||
jpeg_set_quality(&cinfo, 90, TRUE);
|
||||
|
||||
/*! Specify the data source. */
|
||||
jpeg_mem_dest(&cinfo, encoded, capacity);
|
||||
|
||||
/*! Compress and write the image into the target buffer. */
|
||||
compress(&cinfo, image);
|
||||
|
||||
/*! At this point 'jerror.num_warnings' could be checked for corrupt-data warnings. */
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
|
||||
#else // JPEG_LIB_VERSION
|
||||
|
||||
THROW_RUNTIME_ERROR("JPEG encoding into a memory buffer requires LibJPEG 8a or higher");
|
||||
|
||||
#endif // JPEG_LIB_VERSION
|
||||
|
||||
}
|
||||
|
||||
Ref<Image> loadJPEG(const FileName &filename)
|
||||
{
|
||||
|
||||
/*! Open the source JPEG file. */
|
||||
FILE *file = fopen(filename.c_str(), "rb"); if (!file) THROW_RUNTIME_ERROR("Unable to open \"" + filename.str() + "\".");
|
||||
|
||||
/*! Decompression parameters and scratch space pointers allocated by the library. */
|
||||
struct jpeg_decompress_struct cinfo;
|
||||
|
||||
/*! The library error handler. */
|
||||
struct jpeg_error_mgr jerror; cinfo.err = jpeg_std_error(&jerror);
|
||||
|
||||
/*! Initialize the JPEG decompression object. */
|
||||
jpeg_create_decompress(&cinfo);
|
||||
|
||||
/*! Specify the data source. */
|
||||
jpeg_stdio_src(&cinfo, file);
|
||||
|
||||
/*! Read file parameters with jpeg_read_header(). */
|
||||
jpeg_read_header(&cinfo, TRUE);
|
||||
|
||||
/*! Specify the color space and color space components of the decompressed image. */
|
||||
cinfo.out_color_space = JCS_RGB; cinfo.output_components = 3;
|
||||
|
||||
/*! Decompress the image into an output buffer and get the image dimensions. */
|
||||
unsigned char *rgb = decompress(&cinfo); size_t width = cinfo.output_width; size_t height = cinfo.output_height;
|
||||
|
||||
/*! Allocate the Embree image. */
|
||||
Ref<Image> image = new Image4uc(width, height, filename);
|
||||
|
||||
/*! Convert the image from unsigned char RGB to unsigned char RGBA. */
|
||||
for (size_t y=0, i=0 ; y < height ; y++) {
|
||||
for (size_t x=0 ; x < width ; x++) {
|
||||
const float r = (float) rgb[i++] / 255.0f;
|
||||
const float g = (float) rgb[i++] / 255.0f;
|
||||
const float b = (float) rgb[i++] / 255.0f;
|
||||
image->set(x, y, Color4(r,g,b,1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
/*! Clean up. */
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
delete[] rgb;
|
||||
fclose(file);
|
||||
return(image);
|
||||
}
|
||||
|
||||
void storeJPEG(const Ref<Image> &image, const FileName &filename)
|
||||
{
|
||||
|
||||
/*! Open the target JPEG file. */
|
||||
FILE *file = fopen(filename.c_str(), "wb"); if (!file) THROW_RUNTIME_ERROR("Unable to open \"" + filename.str() + "\".");
|
||||
|
||||
/*! Compression parameters and scratch space pointers (allocated by the library). */
|
||||
struct jpeg_compress_struct cinfo;
|
||||
|
||||
/*! The library error handler. */
|
||||
struct jpeg_error_mgr jerror; cinfo.err = jpeg_std_error(&jerror);
|
||||
|
||||
/*! Initialize the JPEG compression object. */
|
||||
jpeg_create_compress(&cinfo);
|
||||
|
||||
/*! Specify the incoming image resolution, color space, and color space components. */
|
||||
cinfo.image_width = image->width; cinfo.image_height = image->height; cinfo.in_color_space = JCS_RGB; cinfo.input_components = 3;
|
||||
|
||||
/*! Fill in a sensible set of defaults. */
|
||||
jpeg_set_defaults(&cinfo);
|
||||
|
||||
/*! Specify the data source. */
|
||||
jpeg_stdio_dest(&cinfo, file);
|
||||
|
||||
/*! Allocate storage for the uncompressed packed image. */
|
||||
unsigned char* rgb = new unsigned char [3 * image->height * image->width];
|
||||
|
||||
/*! Convert the image to unsigned char RGB. */
|
||||
for (size_t y=0, i=0 ; y < image->height ; y++) {
|
||||
for (size_t x=0 ; x < image->width ; x++) {
|
||||
const Color4 pixel = image->get(x, y);
|
||||
rgb[i++] = (unsigned char)(clamp(pixel.r) * 255.0f);
|
||||
rgb[i++] = (unsigned char)(clamp(pixel.g) * 255.0f);
|
||||
rgb[i++] = (unsigned char)(clamp(pixel.b) * 255.0f);
|
||||
}
|
||||
}
|
||||
|
||||
/*! Compress and write the image into the target file. */
|
||||
compress(&cinfo, rgb);
|
||||
|
||||
/*! At this point 'jerror.num_warnings' could be checked for corrupt-data warnings. */
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
delete [] rgb;
|
||||
fclose(file);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // EMBREE_TUTORIALS_LIBJPEG
|
||||
|
||||
76
Framework/external/embree/tutorials/common/image/oiio.cpp
vendored
Normal file
76
Framework/external/embree/tutorials/common/image/oiio.cpp
vendored
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#ifdef USE_OPENIMAGEIO
|
||||
|
||||
#include "image.h"
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
/*! include OpenImageIO headers */
|
||||
#include <OpenImageIO/imageio.h>
|
||||
OIIO_NAMESPACE_USING
|
||||
|
||||
namespace embree
|
||||
{
|
||||
Ref<Image> loadOIIO(const FileName& fileName)
|
||||
{
|
||||
std::unique_ptr<ImageInput> in(ImageInput::open(fileName.str().c_str()));
|
||||
if (!in)
|
||||
THROW_RUNTIME_ERROR("error opening file " + fileName.str());
|
||||
|
||||
const ImageSpec& spec = in->spec();
|
||||
size_t width = spec.width;
|
||||
size_t height = spec.height;
|
||||
size_t channels = spec.nchannels;
|
||||
std::vector<unsigned char> pixels(width*height*channels);
|
||||
in->read_image(TypeDesc::UINT8, pixels.data());
|
||||
in->close();
|
||||
|
||||
Image* out = new Image4uc(width, height, fileName);
|
||||
const float rcpMaxColor = 1.f/255.f;
|
||||
for (size_t y = 0; y < height; y++)
|
||||
{
|
||||
for (size_t x = 0; x < width; x++)
|
||||
{
|
||||
float r = (channels > 0) ? (float(pixels[(y*width+x)*channels+0]) * rcpMaxColor) : 0.f;
|
||||
float g = (channels > 1) ? (float(pixels[(y*width+x)*channels+1]) * rcpMaxColor) : r;
|
||||
float b = (channels > 2) ? (float(pixels[(y*width+x)*channels+2]) * rcpMaxColor) : ((channels == 1) ? r : 0.f);
|
||||
float a = (channels > 3) ? (float(pixels[(y*width+x)*channels+3]) * rcpMaxColor) : 1.f;
|
||||
out->set(x, height-y-1, Color4(r,g,b,a)); // flip image
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void storeOIIO(const Ref<Image>& img, const FileName& fileName)
|
||||
{
|
||||
std::unique_ptr<ImageOutput> out(ImageOutput::create(fileName.c_str()));
|
||||
if (!out) THROW_RUNTIME_ERROR("unsupported output file format " + fileName.str());
|
||||
|
||||
std::vector<unsigned char> pixels(img->width*img->height*3);
|
||||
const float maxColor = 255.f;
|
||||
for (size_t y = 0; y < img->height; y++)
|
||||
{
|
||||
for (size_t x = 0; x < img->width; x++)
|
||||
{
|
||||
Color4 c = img->get(x, y);
|
||||
pixels[(y*img->width+x)*3+0] = (unsigned char)(clamp(c.r) * maxColor);
|
||||
pixels[(y*img->width+x)*3+1] = (unsigned char)(clamp(c.g) * maxColor);
|
||||
pixels[(y*img->width+x)*3+2] = (unsigned char)(clamp(c.b) * maxColor);
|
||||
}
|
||||
}
|
||||
|
||||
ImageSpec spec(int(img->width), int(img->height), 3, TypeDesc::UINT8);
|
||||
if (!out->open(fileName.c_str(), spec))
|
||||
{
|
||||
THROW_RUNTIME_ERROR("error opening file " + fileName.str());
|
||||
}
|
||||
out->write_image(TypeDesc::UINT8, pixels.data());
|
||||
out->close();
|
||||
}
|
||||
}
|
||||
|
||||
#endif // USE_OPENIMAGEIO
|
||||
|
||||
90
Framework/external/embree/tutorials/common/image/pfm.cpp
vendored
Normal file
90
Framework/external/embree/tutorials/common/image/pfm.cpp
vendored
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "image.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
namespace embree
|
||||
{
|
||||
static void skipSpacesAndComments(std::fstream& file)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (isspace(file.peek())) {
|
||||
file.ignore();
|
||||
} else if (file.peek() == '#') {
|
||||
std::string line; std::getline(file,line);
|
||||
} else break;
|
||||
}
|
||||
}
|
||||
|
||||
/*! read PFM file from disk */
|
||||
Ref<Image> loadPFM(const FileName& fileName)
|
||||
{
|
||||
/* open file for reading */
|
||||
std::fstream file;
|
||||
file.exceptions (std::fstream::failbit | std::fstream::badbit);
|
||||
file.open (fileName.c_str(), std::fstream::in | std::fstream::binary);
|
||||
|
||||
/* read file type */
|
||||
char cty[2]; file.read(cty,2);
|
||||
skipSpacesAndComments(file);
|
||||
std::string type(cty,2);
|
||||
|
||||
/* read width, height, and maximum color value */
|
||||
int width; file >> width;
|
||||
skipSpacesAndComments(file);
|
||||
int height; file >> height;
|
||||
skipSpacesAndComments(file);
|
||||
float maxColor; file >> maxColor;
|
||||
if (maxColor > 0) THROW_RUNTIME_ERROR("Big endian PFM files not supported");
|
||||
float rcpMaxColor = -1.0f/float(maxColor);
|
||||
file.ignore(); // skip space or return
|
||||
|
||||
/* create image and fill with data */
|
||||
Ref<Image> img = new Image4f(width,height,fileName);
|
||||
|
||||
/* image in binary format 16 bit */
|
||||
if (type == "PF")
|
||||
{
|
||||
float rgb[3];
|
||||
for (ssize_t y=height-1; y>=0; y--) {
|
||||
for (ssize_t x=0; x<width; x++) {
|
||||
file.read((char*)rgb,sizeof(rgb));
|
||||
img->set(x,y,Color4(rgb[0]*rcpMaxColor,rgb[1]*rcpMaxColor,rgb[2]*rcpMaxColor,1.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* invalid magic value */
|
||||
else {
|
||||
THROW_RUNTIME_ERROR("Invalid magic value in PFM file");
|
||||
}
|
||||
return img;
|
||||
}
|
||||
|
||||
/*! store PFM file to disk */
|
||||
void storePFM(const Ref<Image>& img, const FileName& fileName)
|
||||
{
|
||||
/* open file for writing */
|
||||
std::fstream file;
|
||||
file.exceptions (std::fstream::failbit | std::fstream::badbit);
|
||||
file.open (fileName.c_str(), std::fstream::out | std::fstream::binary);
|
||||
|
||||
/* write file header */
|
||||
file << "PF" << std::endl;
|
||||
file << img->width << " " << img->height << std::endl;
|
||||
file << -1.0f << std::endl;
|
||||
|
||||
/* write image */
|
||||
for (ssize_t y=img->height-1; y>=0; y--) {
|
||||
for (ssize_t x=0; x<(ssize_t)img->width; x++) {
|
||||
const Color4 c = img->get(x,y);
|
||||
file.write((char*)&c,3*sizeof(float));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
135
Framework/external/embree/tutorials/common/image/png.cpp
vendored
Normal file
135
Framework/external/embree/tutorials/common/image/png.cpp
vendored
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#ifdef EMBREE_TUTORIALS_LIBPNG
|
||||
|
||||
#include "image.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <png.h>
|
||||
|
||||
namespace embree
|
||||
{
|
||||
struct AutoCloseFile
|
||||
{
|
||||
FILE* file;
|
||||
AutoCloseFile (FILE* file) : file(file) {}
|
||||
~AutoCloseFile () { if (file) fclose(file); }
|
||||
};
|
||||
|
||||
/*! read PNG file from disk */
|
||||
Ref<Image> loadPNG(const FileName& fileName)
|
||||
{
|
||||
size_t width, height;
|
||||
|
||||
//header for testing if it is a png
|
||||
png_byte header[8];
|
||||
|
||||
//open file as binary
|
||||
FILE* fp = fopen(fileName.c_str(), "rb");
|
||||
if (!fp) THROW_RUNTIME_ERROR("cannot open file "+fileName.str());
|
||||
//ON_SCOPE_EXIT(fclose(fp));
|
||||
AutoCloseFile close_file(fp);
|
||||
|
||||
//read the header
|
||||
if (fread(header, 1, 8, fp) != 8)
|
||||
THROW_RUNTIME_ERROR("invalid PNG file "+fileName.str());
|
||||
|
||||
//test if png
|
||||
int is_png = !png_sig_cmp(header, 0, 8);
|
||||
if (!is_png)
|
||||
THROW_RUNTIME_ERROR("invalid PNG file "+fileName.str());
|
||||
|
||||
//create png struct
|
||||
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
|
||||
if (!png_ptr) THROW_RUNTIME_ERROR("invalid PNG file "+fileName.str());
|
||||
ON_SCOPE_EXIT(png_destroy_read_struct(&png_ptr, (png_infopp) nullptr, (png_infopp) nullptr));
|
||||
|
||||
//create png info struct
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr)
|
||||
THROW_RUNTIME_ERROR("invalid PNG file "+fileName.str());
|
||||
|
||||
//create png info struct
|
||||
png_infop end_info = png_create_info_struct(png_ptr);
|
||||
if (!end_info)
|
||||
THROW_RUNTIME_ERROR("invalid PNG file "+fileName.str());
|
||||
|
||||
//png error stuff, not sure libpng man suggests this.
|
||||
//if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
/// return (TEXTURE_LOAD_ERROR);
|
||||
//}
|
||||
|
||||
//init png reading
|
||||
png_init_io(png_ptr, fp);
|
||||
|
||||
//let libpng know you already read the first 8 bytes
|
||||
png_set_sig_bytes(png_ptr, 8);
|
||||
|
||||
// read all the info up to the image data
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
|
||||
//variables to pass to get info
|
||||
int bit_depth, color_type;
|
||||
png_uint_32 twidth, theight;
|
||||
|
||||
// get info about png
|
||||
png_get_IHDR(png_ptr, info_ptr, &twidth, &theight, &bit_depth, &color_type,
|
||||
nullptr, nullptr, nullptr);
|
||||
|
||||
//update width and height based on png info
|
||||
width = twidth;
|
||||
height = theight;
|
||||
|
||||
Ref<Image> img = new Image4uc(width,height,fileName);
|
||||
|
||||
// Update the png info struct.
|
||||
png_read_update_info(png_ptr, info_ptr);
|
||||
|
||||
// Row size in bytes.
|
||||
int rowbytes = png_get_rowbytes(png_ptr, info_ptr);
|
||||
|
||||
// Allocate the image_data as a big block, to be given to opengl
|
||||
std::vector<png_byte> data(rowbytes * height);
|
||||
|
||||
// row_pointers is for pointing to image_data for reading the png with libpng
|
||||
std::vector<png_bytep> row_pointers(height);
|
||||
|
||||
// set the individual row_pointers to point at the correct offsets of image_data
|
||||
for (size_t i = 0; i < height; ++i)
|
||||
row_pointers[i] = (unsigned char*) &data[i * rowbytes];
|
||||
|
||||
// read the png into image_data through row_pointers
|
||||
png_read_image(png_ptr, row_pointers.data());
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_RGB && bit_depth == 8)
|
||||
{
|
||||
for (size_t y=0;y<height;y++)
|
||||
for (size_t x=0;x<width;x++)
|
||||
{
|
||||
unsigned char* texel = data.data() + (y * width + x) * 3;
|
||||
Color4 c( (float)texel[0] * 1.0f/255.0f, (float)texel[1] * 1.0f/255.0f, (float)texel[2] * 1.0f/255.0f, 0.0f );
|
||||
img.ptr->set(x,y,c);
|
||||
}
|
||||
}
|
||||
else if (color_type == PNG_COLOR_TYPE_RGBA && bit_depth == 8)
|
||||
{
|
||||
for (size_t y=0;y<height;y++)
|
||||
for (size_t x=0;x<width;x++)
|
||||
{
|
||||
unsigned char *texel = data.data() + (y * width + x) * 4;
|
||||
Color4 c( (float)texel[0] * 1.0f/255.0f, (float)texel[1] * 1.0f/255.0f, (float)texel[2] * 1.0f/255.0f, (float)texel[3] * 1.0f/255.0f );
|
||||
img.ptr->set(x,y,c);
|
||||
}
|
||||
}
|
||||
else
|
||||
THROW_RUNTIME_ERROR("invalid color type in PNG file "+fileName.str());
|
||||
|
||||
return img;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
117
Framework/external/embree/tutorials/common/image/ppm.cpp
vendored
Normal file
117
Framework/external/embree/tutorials/common/image/ppm.cpp
vendored
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "image.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
|
||||
namespace embree
|
||||
{
|
||||
static void skipSpacesAndComments(std::fstream& file)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (isspace(file.peek())) {
|
||||
file.ignore();
|
||||
} else if (file.peek() == '#') {
|
||||
std::string line; std::getline(file,line);
|
||||
} else break;
|
||||
}
|
||||
}
|
||||
|
||||
/*! read PPM file from disk */
|
||||
Ref<Image> loadPPM(const FileName& fileName)
|
||||
{
|
||||
/* open file for reading */
|
||||
std::fstream file;
|
||||
file.exceptions (std::fstream::failbit | std::fstream::badbit);
|
||||
file.open (fileName.c_str(), std::fstream::in | std::fstream::binary);
|
||||
|
||||
/* read file type */
|
||||
char cty[2]; file.read(cty,2);
|
||||
skipSpacesAndComments(file);
|
||||
std::string type(cty,2);
|
||||
|
||||
/* read width, height, and maximum color value */
|
||||
int width; file >> width;
|
||||
skipSpacesAndComments(file);
|
||||
int height; file >> height;
|
||||
skipSpacesAndComments(file);
|
||||
int maxColor; file >> maxColor;
|
||||
if (maxColor <= 0) THROW_RUNTIME_ERROR("Invalid maxColor value in PPM file");
|
||||
float rcpMaxColor = 1.0f/float(maxColor);
|
||||
file.ignore(); // skip space or return
|
||||
|
||||
/* create image and fill with data */
|
||||
Ref<Image> img = new Image4uc(width,height,fileName);
|
||||
|
||||
/* image in text format */
|
||||
if (type == "P3")
|
||||
{
|
||||
int r, g, b;
|
||||
for (ssize_t y=0; y<height; y++) {
|
||||
for (ssize_t x=0; x<width; x++) {
|
||||
file >> r; file >> g; file >> b;
|
||||
img->set(x,y,Color4(float(r)*rcpMaxColor,float(g)*rcpMaxColor,float(b)*rcpMaxColor,1.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* image in binary format 8 bit */
|
||||
else if (type == "P6" && maxColor <= 255)
|
||||
{
|
||||
unsigned char rgb[3];
|
||||
for (ssize_t y=0; y<height; y++) {
|
||||
for (ssize_t x=0; x<width; x++) {
|
||||
file.read((char*)rgb,sizeof(rgb));
|
||||
img->set(x,y,Color4(float(rgb[0])*rcpMaxColor,float(rgb[1])*rcpMaxColor,float(rgb[2])*rcpMaxColor,1.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* image in binary format 16 bit */
|
||||
else if (type == "P6" && maxColor <= 65535)
|
||||
{
|
||||
unsigned short rgb[3];
|
||||
for (ssize_t y=0; y<height; y++) {
|
||||
for (ssize_t x=0; x<width; x++) {
|
||||
file.read((char*)rgb,sizeof(rgb));
|
||||
img->set(x,y,Color4(float(rgb[0])*rcpMaxColor,float(rgb[1])*rcpMaxColor,float(rgb[2])*rcpMaxColor,1.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* invalid magic value */
|
||||
else {
|
||||
THROW_RUNTIME_ERROR("Invalid magic value in PPM file");
|
||||
}
|
||||
return img;
|
||||
}
|
||||
|
||||
/*! store PPM file to disk */
|
||||
void storePPM(const Ref<Image>& img, const FileName& fileName)
|
||||
{
|
||||
/* open file for writing */
|
||||
std::fstream file;
|
||||
file.exceptions (std::fstream::failbit | std::fstream::badbit);
|
||||
file.open (fileName.c_str(), std::fstream::out | std::fstream::binary);
|
||||
|
||||
/* write file header */
|
||||
file << "P6" << std::endl;
|
||||
file << img->width << " " << img->height << std::endl;
|
||||
file << 255 << std::endl;
|
||||
|
||||
/* write image */
|
||||
for (size_t y=0; y<img->height; y++) {
|
||||
for (size_t x=0; x<img->width; x++) {
|
||||
const Color4 c = img->get(x,y);
|
||||
file << (unsigned char)(clamp(c.r)*255.0f);
|
||||
file << (unsigned char)(clamp(c.g)*255.0f);
|
||||
file << (unsigned char)(clamp(c.b)*255.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
72
Framework/external/embree/tutorials/common/image/stb.cpp
vendored
Normal file
72
Framework/external/embree/tutorials/common/image/stb.cpp
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "image.h"
|
||||
#include "../../../common/sys/estring.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#include "stb_image_write.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
Ref<Image> loadSTB(const FileName& fileName)
|
||||
{
|
||||
int width, height, channels;
|
||||
unsigned char *pixels = stbi_load(fileName.str().c_str(), &width, &height, &channels, 0);
|
||||
if(pixels == nullptr) {
|
||||
THROW_RUNTIME_ERROR("Could not load " + fileName.str());
|
||||
}
|
||||
|
||||
Image* out = new Image4uc(width, height, fileName);
|
||||
const float rcpMaxColor = 1.f/255.f;
|
||||
for (size_t y = 0; y < height; y++)
|
||||
{
|
||||
for (size_t x = 0; x < width; x++)
|
||||
{
|
||||
float r = (channels > 0) ? (float(pixels[(y*width+x)*channels+0]) * rcpMaxColor) : 0.f;
|
||||
float g = (channels > 1) ? (float(pixels[(y*width+x)*channels+1]) * rcpMaxColor) : r;
|
||||
float b = (channels > 2) ? (float(pixels[(y*width+x)*channels+2]) * rcpMaxColor) : ((channels == 1) ? r : 0.f);
|
||||
float a = (channels > 3) ? (float(pixels[(y*width+x)*channels+3]) * rcpMaxColor) : 1.f;
|
||||
out->set(x, y, Color4(r,g,b,a));
|
||||
}
|
||||
}
|
||||
|
||||
stbi_image_free(pixels);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void storeSTB(const Ref<Image>& img, const FileName& fileName)
|
||||
{
|
||||
std::string ext = toLowerCase(fileName.ext());
|
||||
if (ext != "bmp" && ext != "png" && ext != "jpg") {
|
||||
THROW_RUNTIME_ERROR("Could not store image")
|
||||
return;
|
||||
}
|
||||
|
||||
int width = int(img->width);
|
||||
int height = int(img->height);
|
||||
int channels = 3;
|
||||
std::vector<unsigned char> pixels(width*height*channels);
|
||||
const float maxColor = 255.f;
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
Color4 c = img->get(x, y);
|
||||
pixels[(y*img->width+x)*channels+0] = (unsigned char)(clamp(c.r) * maxColor);
|
||||
pixels[(y*img->width+x)*channels+1] = (unsigned char)(clamp(c.g) * maxColor);
|
||||
pixels[(y*img->width+x)*channels+2] = (unsigned char)(clamp(c.b) * maxColor);
|
||||
}
|
||||
}
|
||||
|
||||
if (ext == "bmp" ) { stbi_write_bmp(fileName.str().c_str(), width, height, channels, pixels.data()); return; }
|
||||
if (ext == "png" ) { stbi_write_png(fileName.str().c_str(), width, height, channels, pixels.data(), width * channels); return; }
|
||||
if (ext == "jpg" ) { stbi_write_jpg(fileName.str().c_str(), width, height, channels, pixels.data(), 100); return; }
|
||||
}
|
||||
}
|
||||
7897
Framework/external/embree/tutorials/common/image/stb_image.h
vendored
Normal file
7897
Framework/external/embree/tutorials/common/image/stb_image.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
1741
Framework/external/embree/tutorials/common/image/stb_image_write.h
vendored
Normal file
1741
Framework/external/embree/tutorials/common/image/stb_image_write.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
95
Framework/external/embree/tutorials/common/image/tga.cpp
vendored
Normal file
95
Framework/external/embree/tutorials/common/image/tga.cpp
vendored
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "image.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace embree
|
||||
{
|
||||
inline void fwrite_uchar (unsigned char v, std::fstream& file) { file.write((const char*)&v,sizeof(v)); }
|
||||
inline void fwrite_ushort(unsigned short v, std::fstream& file) { file.write((const char*)&v,sizeof(v)); }
|
||||
|
||||
void storeTga(const Ref<Image>& img, const FileName& fileName)
|
||||
{
|
||||
/* open file for reading */
|
||||
std::fstream file;
|
||||
file.exceptions (std::fstream::failbit | std::fstream::badbit);
|
||||
file.open (fileName.c_str(), std::fstream::out | std::fstream::binary);
|
||||
|
||||
fwrite_uchar(0x00, file);
|
||||
fwrite_uchar(0x00, file);
|
||||
fwrite_uchar(0x02, file);
|
||||
fwrite_ushort(0x0000, file);
|
||||
fwrite_ushort(0x0000, file);
|
||||
fwrite_uchar(0x00, file);
|
||||
fwrite_ushort(0x0000, file);
|
||||
fwrite_ushort(0x0000, file);
|
||||
fwrite_ushort((unsigned short)img->width , file);
|
||||
fwrite_ushort((unsigned short)img->height, file);
|
||||
fwrite_uchar(0x18, file);
|
||||
fwrite_uchar(0x20, file);
|
||||
|
||||
for (size_t y=0; y<img->height; y++) {
|
||||
for (size_t x=0; x<img->width; x++) {
|
||||
Color c = img->get(x,y);
|
||||
fwrite_uchar((unsigned char)(clamp(c.b)*255.0f), file);
|
||||
fwrite_uchar((unsigned char)(clamp(c.g)*255.0f), file);
|
||||
fwrite_uchar((unsigned char)(clamp(c.r)*255.0f), file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline unsigned char fread_uchar (std::fstream& file) { unsigned char v; file.read((char*)&v,sizeof(v)); return v; }
|
||||
inline unsigned short fread_ushort(std::fstream& file) { unsigned short v; file.read((char*)&v,sizeof(v)); return v; }
|
||||
|
||||
/*! read TGA file from disk */
|
||||
Ref<Image> loadTGA(const FileName& fileName)
|
||||
{
|
||||
/* open file for reading */
|
||||
std::fstream file;
|
||||
file.exceptions (std::fstream::failbit | std::fstream::badbit);
|
||||
file.open (fileName.c_str(), std::fstream::in | std::fstream::binary);
|
||||
|
||||
unsigned char idlength = fread_uchar(file);
|
||||
if (idlength != 0) THROW_RUNTIME_ERROR("unsupported TGA file");
|
||||
|
||||
unsigned char colormaptype = fread_uchar(file);
|
||||
if (colormaptype != 0) THROW_RUNTIME_ERROR("unsupported TGA file");
|
||||
|
||||
unsigned char datatype = fread_uchar(file);
|
||||
if (datatype != 2) THROW_RUNTIME_ERROR("unsupported TGA file");
|
||||
|
||||
unsigned short cmo = fread_ushort(file);
|
||||
unsigned short cml = fread_ushort(file);
|
||||
unsigned char cmd = fread_uchar(file);
|
||||
unsigned short xorg = fread_ushort(file);
|
||||
unsigned short yorg = fread_ushort(file);
|
||||
if (cmo != 0 || cml != 0 || cmd != 0 || xorg != 0 || yorg != 0)
|
||||
THROW_RUNTIME_ERROR("unsupported TGA file");
|
||||
|
||||
unsigned short width = fread_ushort(file);
|
||||
unsigned short height = fread_ushort(file);
|
||||
|
||||
unsigned char bits = fread_uchar(file);
|
||||
if (bits != 3*8) THROW_RUNTIME_ERROR("unsupported TGA file bits per pixel");
|
||||
|
||||
unsigned char desc = fread_uchar(file);
|
||||
if (desc != 0x20) THROW_RUNTIME_ERROR("unsupported TGA file");
|
||||
|
||||
/* create image and fill with data */
|
||||
Ref<Image> img = new Image4f(width,height,fileName);
|
||||
|
||||
/* load image data */
|
||||
for (size_t y=0; y<height; y++) {
|
||||
for (size_t x=0; x<width; x++) {
|
||||
const unsigned char b = fread_uchar(file);
|
||||
const unsigned char g = fread_uchar(file);
|
||||
const unsigned char r = fread_uchar(file);
|
||||
img->set(x,y,Color4(r/255.0f,g/255.0f,b/255.0f,1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
}
|
||||
8894
Framework/external/embree/tutorials/common/image/tinyexr.h
vendored
Normal file
8894
Framework/external/embree/tutorials/common/image/tinyexr.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
18
Framework/external/embree/tutorials/common/imgui/CMakeLists.txt
vendored
Normal file
18
Framework/external/embree/tutorials/common/imgui/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
## Copyright 2009-2021 Intel Corporation
|
||||
## SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
ADD_LIBRARY(imgui STATIC
|
||||
imgui.cpp
|
||||
imgui_draw.cpp
|
||||
imgui_widgets.cpp
|
||||
imgui_tables.cpp
|
||||
backends/imgui_impl_glfw.cpp
|
||||
backends/imgui_impl_opengl2.cpp
|
||||
)
|
||||
|
||||
TARGET_INCLUDE_DIRECTORIES(imgui PUBLIC . ./backends)
|
||||
TARGET_LINK_LIBRARIES(imgui glfw)
|
||||
SET_PROPERTY(TARGET imgui PROPERTY FOLDER tutorials/common)
|
||||
SET_PROPERTY(TARGET imgui APPEND PROPERTY COMPILE_FLAGS " ${FLAGS_LOWEST}")
|
||||
|
||||
TARGET_COMPILE_DEFINITIONS(imgui PUBLIC IMGUI_DISABLE_SSE)
|
||||
21
Framework/external/embree/tutorials/common/imgui/LICENSE.txt
vendored
Normal file
21
Framework/external/embree/tutorials/common/imgui/LICENSE.txt
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2022 Omar Cornut
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
686
Framework/external/embree/tutorials/common/imgui/backends/imgui_impl_glfw.cpp
vendored
Normal file
686
Framework/external/embree/tutorials/common/imgui/backends/imgui_impl_glfw.cpp
vendored
Normal file
|
|
@ -0,0 +1,686 @@
|
|||
// dear imgui: Platform Backend for GLFW
|
||||
// This needs to be used along with a Renderer (e.g. OpenGL3, Vulkan, WebGPU..)
|
||||
// (Info: GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.)
|
||||
// (Requires: GLFW 3.1+)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Clipboard support.
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2022-11-22: Perform a dummy glfwGetError() read to cancel missing names with glfwGetKeyName(). (#5908)
|
||||
// 2022-10-18: Perform a dummy glfwGetError() read to cancel missing mouse cursors errors. Using GLFW_VERSION_COMBINED directly. (#5785)
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported).
|
||||
// 2022-09-01: Inputs: Honor GLFW_CURSOR_DISABLED by not setting mouse position.
|
||||
// 2022-04-30: Inputs: Fixed ImGui_ImplGlfw_TranslateUntranslatedKey() for lower case letters on OSX.
|
||||
// 2022-03-23: Inputs: Fixed a regression in 1.87 which resulted in keyboard modifiers events being reported incorrectly on Linux/X11.
|
||||
// 2022-02-07: Added ImGui_ImplGlfw_InstallCallbacks()/ImGui_ImplGlfw_RestoreCallbacks() helpers to facilitate user installing callbacks after initializing backend.
|
||||
// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago) with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion.
|
||||
// 2021-01-20: Inputs: calling new io.AddKeyAnalogEvent() for gamepad support, instead of writing directly to io.NavInputs[].
|
||||
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
|
||||
// 2022-01-17: Inputs: always update key mods next and before key event (not in NewFrame) to fix input queue with very low framerates.
|
||||
// 2022-01-12: *BREAKING CHANGE*: Now using glfwSetCursorPosCallback(). If you called ImGui_ImplGlfw_InitXXX() with install_callbacks = false, you MUST install glfwSetCursorPosCallback() and forward it to the backend via ImGui_ImplGlfw_CursorPosCallback().
|
||||
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
|
||||
// 2022-01-05: Inputs: Converting GLFW untranslated keycodes back to translated keycodes (in the ImGui_ImplGlfw_KeyCallback() function) in order to match the behavior of every other backend, and facilitate the use of GLFW with lettered-shortcuts API.
|
||||
// 2021-08-17: *BREAKING CHANGE*: Now using glfwSetWindowFocusCallback() to calling io.AddFocusEvent(). If you called ImGui_ImplGlfw_InitXXX() with install_callbacks = false, you MUST install glfwSetWindowFocusCallback() and forward it to the backend via ImGui_ImplGlfw_WindowFocusCallback().
|
||||
// 2021-07-29: *BREAKING CHANGE*: Now using glfwSetCursorEnterCallback(). MousePos is correctly reported when the host platform window is hovered but not focused. If you called ImGui_ImplGlfw_InitXXX() with install_callbacks = false, you MUST install glfwSetWindowFocusCallback() callback and forward it to the backend via ImGui_ImplGlfw_CursorEnterCallback().
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2020-01-17: Inputs: Disable error callback while assigning mouse cursors because some X11 setup don't have them and it generates errors.
|
||||
// 2019-12-05: Inputs: Added support for new mouse cursors added in GLFW 3.4+ (resizing cursors, not allowed cursor).
|
||||
// 2019-10-18: Misc: Previously installed user callbacks are now restored on shutdown.
|
||||
// 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter.
|
||||
// 2019-05-11: Inputs: Don't filter value from character callback before calling AddInputCharacter().
|
||||
// 2019-03-12: Misc: Preserve DisplayFramebufferScale when main window is minimized.
|
||||
// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window.
|
||||
// 2018-11-07: Inputs: When installing our GLFW callbacks, we save user's previously installed ones - if any - and chain call them.
|
||||
// 2018-08-01: Inputs: Workaround for Emscripten which doesn't seem to handle focus related calls.
|
||||
// 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor.
|
||||
// 2018-06-08: Misc: Extracted imgui_impl_glfw.cpp/.h away from the old combined GLFW+OpenGL/Vulkan examples.
|
||||
// 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors flag + honor ImGuiConfigFlags_NoMouseCursorChange flag.
|
||||
// 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value, passed to glfwSetCursor()).
|
||||
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
|
||||
// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space.
|
||||
// 2018-01-25: Inputs: Added gamepad support if ImGuiConfigFlags_NavEnableGamepad is set.
|
||||
// 2018-01-25: Inputs: Honoring the io.WantSetMousePos by repositioning the mouse (when using navigation and ImGuiConfigFlags_NavMoveMouse is set).
|
||||
// 2018-01-20: Inputs: Added Horizontal Mouse Wheel support.
|
||||
// 2018-01-18: Inputs: Added mapping for ImGuiKey_Insert.
|
||||
// 2017-08-25: Inputs: MousePos set to -FLT_MAX,-FLT_MAX when mouse is unavailable/missing (instead of -1,-1).
|
||||
// 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers.
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_glfw.h"
|
||||
|
||||
// Clang warnings with -Weverything
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast
|
||||
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||||
#endif
|
||||
|
||||
// GLFW
|
||||
#include <GLFW/glfw3.h>
|
||||
#ifdef _WIN32
|
||||
#undef APIENTRY
|
||||
#define GLFW_EXPOSE_NATIVE_WIN32
|
||||
#include <GLFW/glfw3native.h> // for glfwGetWin32Window
|
||||
#endif
|
||||
|
||||
// We gather version tests as define in order to easily see which features are version-dependent.
|
||||
#define GLFW_VERSION_COMBINED (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 + GLFW_VERSION_REVISION)
|
||||
#ifdef GLFW_RESIZE_NESW_CURSOR // Let's be nice to people who pulled GLFW between 2019-04-16 (3.4 define) and 2019-11-29 (cursors defines) // FIXME: Remove when GLFW 3.4 is released?
|
||||
#define GLFW_HAS_NEW_CURSORS (GLFW_VERSION_COMBINED >= 3400) // 3.4+ GLFW_RESIZE_ALL_CURSOR, GLFW_RESIZE_NESW_CURSOR, GLFW_RESIZE_NWSE_CURSOR, GLFW_NOT_ALLOWED_CURSOR
|
||||
#else
|
||||
#define GLFW_HAS_NEW_CURSORS (0)
|
||||
#endif
|
||||
#define GLFW_HAS_GAMEPAD_API (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetGamepadState() new api
|
||||
#define GLFW_HAS_GETKEYNAME (GLFW_VERSION_COMBINED >= 3200) // 3.2+ glfwGetKeyName()
|
||||
|
||||
// GLFW data
|
||||
enum GlfwClientApi
|
||||
{
|
||||
GlfwClientApi_Unknown,
|
||||
GlfwClientApi_OpenGL,
|
||||
GlfwClientApi_Vulkan
|
||||
};
|
||||
|
||||
struct ImGui_ImplGlfw_Data
|
||||
{
|
||||
GLFWwindow* Window;
|
||||
GlfwClientApi ClientApi;
|
||||
double Time;
|
||||
GLFWwindow* MouseWindow;
|
||||
GLFWcursor* MouseCursors[ImGuiMouseCursor_COUNT];
|
||||
ImVec2 LastValidMousePos;
|
||||
bool InstalledCallbacks;
|
||||
|
||||
// Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any.
|
||||
GLFWwindowfocusfun PrevUserCallbackWindowFocus;
|
||||
GLFWcursorposfun PrevUserCallbackCursorPos;
|
||||
GLFWcursorenterfun PrevUserCallbackCursorEnter;
|
||||
GLFWmousebuttonfun PrevUserCallbackMousebutton;
|
||||
GLFWscrollfun PrevUserCallbackScroll;
|
||||
GLFWkeyfun PrevUserCallbackKey;
|
||||
GLFWcharfun PrevUserCallbackChar;
|
||||
GLFWmonitorfun PrevUserCallbackMonitor;
|
||||
|
||||
ImGui_ImplGlfw_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts
|
||||
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
||||
// FIXME: multi-context support is not well tested and probably dysfunctional in this backend.
|
||||
// - Because glfwPollEvents() process all windows and some events may be called outside of it, you will need to register your own callbacks
|
||||
// (passing install_callbacks=false in ImGui_ImplGlfw_InitXXX functions), set the current dear imgui context and then call our callbacks.
|
||||
// - Otherwise we may need to store a GLFWWindow* -> ImGuiContext* map and handle this in the backend, adding a little bit of extra complexity to it.
|
||||
// FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context.
|
||||
static ImGui_ImplGlfw_Data* ImGui_ImplGlfw_GetBackendData()
|
||||
{
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplGlfw_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr;
|
||||
}
|
||||
|
||||
// Functions
|
||||
static const char* ImGui_ImplGlfw_GetClipboardText(void* user_data)
|
||||
{
|
||||
return glfwGetClipboardString((GLFWwindow*)user_data);
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_SetClipboardText(void* user_data, const char* text)
|
||||
{
|
||||
glfwSetClipboardString((GLFWwindow*)user_data, text);
|
||||
}
|
||||
|
||||
static ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case GLFW_KEY_TAB: return ImGuiKey_Tab;
|
||||
case GLFW_KEY_LEFT: return ImGuiKey_LeftArrow;
|
||||
case GLFW_KEY_RIGHT: return ImGuiKey_RightArrow;
|
||||
case GLFW_KEY_UP: return ImGuiKey_UpArrow;
|
||||
case GLFW_KEY_DOWN: return ImGuiKey_DownArrow;
|
||||
case GLFW_KEY_PAGE_UP: return ImGuiKey_PageUp;
|
||||
case GLFW_KEY_PAGE_DOWN: return ImGuiKey_PageDown;
|
||||
case GLFW_KEY_HOME: return ImGuiKey_Home;
|
||||
case GLFW_KEY_END: return ImGuiKey_End;
|
||||
case GLFW_KEY_INSERT: return ImGuiKey_Insert;
|
||||
case GLFW_KEY_DELETE: return ImGuiKey_Delete;
|
||||
case GLFW_KEY_BACKSPACE: return ImGuiKey_Backspace;
|
||||
case GLFW_KEY_SPACE: return ImGuiKey_Space;
|
||||
case GLFW_KEY_ENTER: return ImGuiKey_Enter;
|
||||
case GLFW_KEY_ESCAPE: return ImGuiKey_Escape;
|
||||
case GLFW_KEY_APOSTROPHE: return ImGuiKey_Apostrophe;
|
||||
case GLFW_KEY_COMMA: return ImGuiKey_Comma;
|
||||
case GLFW_KEY_MINUS: return ImGuiKey_Minus;
|
||||
case GLFW_KEY_PERIOD: return ImGuiKey_Period;
|
||||
case GLFW_KEY_SLASH: return ImGuiKey_Slash;
|
||||
case GLFW_KEY_SEMICOLON: return ImGuiKey_Semicolon;
|
||||
case GLFW_KEY_EQUAL: return ImGuiKey_Equal;
|
||||
case GLFW_KEY_LEFT_BRACKET: return ImGuiKey_LeftBracket;
|
||||
case GLFW_KEY_BACKSLASH: return ImGuiKey_Backslash;
|
||||
case GLFW_KEY_RIGHT_BRACKET: return ImGuiKey_RightBracket;
|
||||
case GLFW_KEY_GRAVE_ACCENT: return ImGuiKey_GraveAccent;
|
||||
case GLFW_KEY_CAPS_LOCK: return ImGuiKey_CapsLock;
|
||||
case GLFW_KEY_SCROLL_LOCK: return ImGuiKey_ScrollLock;
|
||||
case GLFW_KEY_NUM_LOCK: return ImGuiKey_NumLock;
|
||||
case GLFW_KEY_PRINT_SCREEN: return ImGuiKey_PrintScreen;
|
||||
case GLFW_KEY_PAUSE: return ImGuiKey_Pause;
|
||||
case GLFW_KEY_KP_0: return ImGuiKey_Keypad0;
|
||||
case GLFW_KEY_KP_1: return ImGuiKey_Keypad1;
|
||||
case GLFW_KEY_KP_2: return ImGuiKey_Keypad2;
|
||||
case GLFW_KEY_KP_3: return ImGuiKey_Keypad3;
|
||||
case GLFW_KEY_KP_4: return ImGuiKey_Keypad4;
|
||||
case GLFW_KEY_KP_5: return ImGuiKey_Keypad5;
|
||||
case GLFW_KEY_KP_6: return ImGuiKey_Keypad6;
|
||||
case GLFW_KEY_KP_7: return ImGuiKey_Keypad7;
|
||||
case GLFW_KEY_KP_8: return ImGuiKey_Keypad8;
|
||||
case GLFW_KEY_KP_9: return ImGuiKey_Keypad9;
|
||||
case GLFW_KEY_KP_DECIMAL: return ImGuiKey_KeypadDecimal;
|
||||
case GLFW_KEY_KP_DIVIDE: return ImGuiKey_KeypadDivide;
|
||||
case GLFW_KEY_KP_MULTIPLY: return ImGuiKey_KeypadMultiply;
|
||||
case GLFW_KEY_KP_SUBTRACT: return ImGuiKey_KeypadSubtract;
|
||||
case GLFW_KEY_KP_ADD: return ImGuiKey_KeypadAdd;
|
||||
case GLFW_KEY_KP_ENTER: return ImGuiKey_KeypadEnter;
|
||||
case GLFW_KEY_KP_EQUAL: return ImGuiKey_KeypadEqual;
|
||||
case GLFW_KEY_LEFT_SHIFT: return ImGuiKey_LeftShift;
|
||||
case GLFW_KEY_LEFT_CONTROL: return ImGuiKey_LeftCtrl;
|
||||
case GLFW_KEY_LEFT_ALT: return ImGuiKey_LeftAlt;
|
||||
case GLFW_KEY_LEFT_SUPER: return ImGuiKey_LeftSuper;
|
||||
case GLFW_KEY_RIGHT_SHIFT: return ImGuiKey_RightShift;
|
||||
case GLFW_KEY_RIGHT_CONTROL: return ImGuiKey_RightCtrl;
|
||||
case GLFW_KEY_RIGHT_ALT: return ImGuiKey_RightAlt;
|
||||
case GLFW_KEY_RIGHT_SUPER: return ImGuiKey_RightSuper;
|
||||
case GLFW_KEY_MENU: return ImGuiKey_Menu;
|
||||
case GLFW_KEY_0: return ImGuiKey_0;
|
||||
case GLFW_KEY_1: return ImGuiKey_1;
|
||||
case GLFW_KEY_2: return ImGuiKey_2;
|
||||
case GLFW_KEY_3: return ImGuiKey_3;
|
||||
case GLFW_KEY_4: return ImGuiKey_4;
|
||||
case GLFW_KEY_5: return ImGuiKey_5;
|
||||
case GLFW_KEY_6: return ImGuiKey_6;
|
||||
case GLFW_KEY_7: return ImGuiKey_7;
|
||||
case GLFW_KEY_8: return ImGuiKey_8;
|
||||
case GLFW_KEY_9: return ImGuiKey_9;
|
||||
case GLFW_KEY_A: return ImGuiKey_A;
|
||||
case GLFW_KEY_B: return ImGuiKey_B;
|
||||
case GLFW_KEY_C: return ImGuiKey_C;
|
||||
case GLFW_KEY_D: return ImGuiKey_D;
|
||||
case GLFW_KEY_E: return ImGuiKey_E;
|
||||
case GLFW_KEY_F: return ImGuiKey_F;
|
||||
case GLFW_KEY_G: return ImGuiKey_G;
|
||||
case GLFW_KEY_H: return ImGuiKey_H;
|
||||
case GLFW_KEY_I: return ImGuiKey_I;
|
||||
case GLFW_KEY_J: return ImGuiKey_J;
|
||||
case GLFW_KEY_K: return ImGuiKey_K;
|
||||
case GLFW_KEY_L: return ImGuiKey_L;
|
||||
case GLFW_KEY_M: return ImGuiKey_M;
|
||||
case GLFW_KEY_N: return ImGuiKey_N;
|
||||
case GLFW_KEY_O: return ImGuiKey_O;
|
||||
case GLFW_KEY_P: return ImGuiKey_P;
|
||||
case GLFW_KEY_Q: return ImGuiKey_Q;
|
||||
case GLFW_KEY_R: return ImGuiKey_R;
|
||||
case GLFW_KEY_S: return ImGuiKey_S;
|
||||
case GLFW_KEY_T: return ImGuiKey_T;
|
||||
case GLFW_KEY_U: return ImGuiKey_U;
|
||||
case GLFW_KEY_V: return ImGuiKey_V;
|
||||
case GLFW_KEY_W: return ImGuiKey_W;
|
||||
case GLFW_KEY_X: return ImGuiKey_X;
|
||||
case GLFW_KEY_Y: return ImGuiKey_Y;
|
||||
case GLFW_KEY_Z: return ImGuiKey_Z;
|
||||
case GLFW_KEY_F1: return ImGuiKey_F1;
|
||||
case GLFW_KEY_F2: return ImGuiKey_F2;
|
||||
case GLFW_KEY_F3: return ImGuiKey_F3;
|
||||
case GLFW_KEY_F4: return ImGuiKey_F4;
|
||||
case GLFW_KEY_F5: return ImGuiKey_F5;
|
||||
case GLFW_KEY_F6: return ImGuiKey_F6;
|
||||
case GLFW_KEY_F7: return ImGuiKey_F7;
|
||||
case GLFW_KEY_F8: return ImGuiKey_F8;
|
||||
case GLFW_KEY_F9: return ImGuiKey_F9;
|
||||
case GLFW_KEY_F10: return ImGuiKey_F10;
|
||||
case GLFW_KEY_F11: return ImGuiKey_F11;
|
||||
case GLFW_KEY_F12: return ImGuiKey_F12;
|
||||
default: return ImGuiKey_None;
|
||||
}
|
||||
}
|
||||
|
||||
static int ImGui_ImplGlfw_KeyToModifier(int key)
|
||||
{
|
||||
if (key == GLFW_KEY_LEFT_CONTROL || key == GLFW_KEY_RIGHT_CONTROL)
|
||||
return GLFW_MOD_CONTROL;
|
||||
if (key == GLFW_KEY_LEFT_SHIFT || key == GLFW_KEY_RIGHT_SHIFT)
|
||||
return GLFW_MOD_SHIFT;
|
||||
if (key == GLFW_KEY_LEFT_ALT || key == GLFW_KEY_RIGHT_ALT)
|
||||
return GLFW_MOD_ALT;
|
||||
if (key == GLFW_KEY_LEFT_SUPER || key == GLFW_KEY_RIGHT_SUPER)
|
||||
return GLFW_MOD_SUPER;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_UpdateKeyModifiers(int mods)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.AddKeyEvent(ImGuiMod_Ctrl, (mods & GLFW_MOD_CONTROL) != 0);
|
||||
io.AddKeyEvent(ImGuiMod_Shift, (mods & GLFW_MOD_SHIFT) != 0);
|
||||
io.AddKeyEvent(ImGuiMod_Alt, (mods & GLFW_MOD_ALT) != 0);
|
||||
io.AddKeyEvent(ImGuiMod_Super, (mods & GLFW_MOD_SUPER) != 0);
|
||||
}
|
||||
|
||||
void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
if (bd->PrevUserCallbackMousebutton != nullptr && window == bd->Window)
|
||||
bd->PrevUserCallbackMousebutton(window, button, action, mods);
|
||||
|
||||
ImGui_ImplGlfw_UpdateKeyModifiers(mods);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (button >= 0 && button < ImGuiMouseButton_COUNT)
|
||||
io.AddMouseButtonEvent(button, action == GLFW_PRESS);
|
||||
}
|
||||
|
||||
void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
if (bd->PrevUserCallbackScroll != nullptr && window == bd->Window)
|
||||
bd->PrevUserCallbackScroll(window, xoffset, yoffset);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.AddMouseWheelEvent((float)xoffset, (float)yoffset);
|
||||
}
|
||||
|
||||
static int ImGui_ImplGlfw_TranslateUntranslatedKey(int key, int scancode)
|
||||
{
|
||||
#if GLFW_HAS_GETKEYNAME && !defined(__EMSCRIPTEN__)
|
||||
// GLFW 3.1+ attempts to "untranslate" keys, which goes the opposite of what every other framework does, making using lettered shortcuts difficult.
|
||||
// (It had reasons to do so: namely GLFW is/was more likely to be used for WASD-type game controls rather than lettered shortcuts, but IHMO the 3.1 change could have been done differently)
|
||||
// See https://github.com/glfw/glfw/issues/1502 for details.
|
||||
// Adding a workaround to undo this (so our keys are translated->untranslated->translated, likely a lossy process).
|
||||
// This won't cover edge cases but this is at least going to cover common cases.
|
||||
if (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_EQUAL)
|
||||
return key;
|
||||
GLFWerrorfun prev_error_callback = glfwSetErrorCallback(nullptr);
|
||||
const char* key_name = glfwGetKeyName(key, scancode);
|
||||
glfwSetErrorCallback(prev_error_callback);
|
||||
#if (GLFW_VERSION_COMBINED >= 3300) // Eat errors (see #5908)
|
||||
(void)glfwGetError(NULL);
|
||||
#endif
|
||||
if (key_name && key_name[0] != 0 && key_name[1] == 0)
|
||||
{
|
||||
const char char_names[] = "`-=[]\\,;\'./";
|
||||
const int char_keys[] = { GLFW_KEY_GRAVE_ACCENT, GLFW_KEY_MINUS, GLFW_KEY_EQUAL, GLFW_KEY_LEFT_BRACKET, GLFW_KEY_RIGHT_BRACKET, GLFW_KEY_BACKSLASH, GLFW_KEY_COMMA, GLFW_KEY_SEMICOLON, GLFW_KEY_APOSTROPHE, GLFW_KEY_PERIOD, GLFW_KEY_SLASH, 0 };
|
||||
IM_ASSERT(IM_ARRAYSIZE(char_names) == IM_ARRAYSIZE(char_keys));
|
||||
if (key_name[0] >= '0' && key_name[0] <= '9') { key = GLFW_KEY_0 + (key_name[0] - '0'); }
|
||||
else if (key_name[0] >= 'A' && key_name[0] <= 'Z') { key = GLFW_KEY_A + (key_name[0] - 'A'); }
|
||||
else if (key_name[0] >= 'a' && key_name[0] <= 'z') { key = GLFW_KEY_A + (key_name[0] - 'a'); }
|
||||
else if (const char* p = strchr(char_names, key_name[0])) { key = char_keys[p - char_names]; }
|
||||
}
|
||||
// if (action == GLFW_PRESS) printf("key %d scancode %d name '%s'\n", key, scancode, key_name);
|
||||
#else
|
||||
IM_UNUSED(scancode);
|
||||
#endif
|
||||
return key;
|
||||
}
|
||||
|
||||
void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int keycode, int scancode, int action, int mods)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
if (bd->PrevUserCallbackKey != nullptr && window == bd->Window)
|
||||
bd->PrevUserCallbackKey(window, keycode, scancode, action, mods);
|
||||
|
||||
if (action != GLFW_PRESS && action != GLFW_RELEASE)
|
||||
return;
|
||||
|
||||
// Workaround: X11 does not include current pressed/released modifier key in 'mods' flags. https://github.com/glfw/glfw/issues/1630
|
||||
if (int keycode_to_mod = ImGui_ImplGlfw_KeyToModifier(keycode))
|
||||
mods = (action == GLFW_PRESS) ? (mods | keycode_to_mod) : (mods & ~keycode_to_mod);
|
||||
ImGui_ImplGlfw_UpdateKeyModifiers(mods);
|
||||
|
||||
keycode = ImGui_ImplGlfw_TranslateUntranslatedKey(keycode, scancode);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiKey imgui_key = ImGui_ImplGlfw_KeyToImGuiKey(keycode);
|
||||
io.AddKeyEvent(imgui_key, (action == GLFW_PRESS));
|
||||
io.SetKeyEventNativeData(imgui_key, keycode, scancode); // To support legacy indexing (<1.87 user code)
|
||||
}
|
||||
|
||||
void ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
if (bd->PrevUserCallbackWindowFocus != nullptr && window == bd->Window)
|
||||
bd->PrevUserCallbackWindowFocus(window, focused);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.AddFocusEvent(focused != 0);
|
||||
}
|
||||
|
||||
void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
if (bd->PrevUserCallbackCursorPos != nullptr && window == bd->Window)
|
||||
bd->PrevUserCallbackCursorPos(window, x, y);
|
||||
if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED)
|
||||
return;
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.AddMousePosEvent((float)x, (float)y);
|
||||
bd->LastValidMousePos = ImVec2((float)x, (float)y);
|
||||
}
|
||||
|
||||
// Workaround: X11 seems to send spurious Leave/Enter events which would make us lose our position,
|
||||
// so we back it up and restore on Leave/Enter (see https://github.com/ocornut/imgui/issues/4984)
|
||||
void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
if (bd->PrevUserCallbackCursorEnter != nullptr && window == bd->Window)
|
||||
bd->PrevUserCallbackCursorEnter(window, entered);
|
||||
if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED)
|
||||
return;
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (entered)
|
||||
{
|
||||
bd->MouseWindow = window;
|
||||
io.AddMousePosEvent(bd->LastValidMousePos.x, bd->LastValidMousePos.y);
|
||||
}
|
||||
else if (!entered && bd->MouseWindow == window)
|
||||
{
|
||||
bd->LastValidMousePos = io.MousePos;
|
||||
bd->MouseWindow = nullptr;
|
||||
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
if (bd->PrevUserCallbackChar != nullptr && window == bd->Window)
|
||||
bd->PrevUserCallbackChar(window, c);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.AddInputCharacter(c);
|
||||
}
|
||||
|
||||
void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor*, int)
|
||||
{
|
||||
// Unused in 'master' branch but 'docking' branch will use this, so we declare it ahead of it so if you have to install callbacks you can install this one too.
|
||||
}
|
||||
|
||||
void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
IM_ASSERT(bd->InstalledCallbacks == false && "Callbacks already installed!");
|
||||
IM_ASSERT(bd->Window == window);
|
||||
|
||||
bd->PrevUserCallbackWindowFocus = glfwSetWindowFocusCallback(window, ImGui_ImplGlfw_WindowFocusCallback);
|
||||
bd->PrevUserCallbackCursorEnter = glfwSetCursorEnterCallback(window, ImGui_ImplGlfw_CursorEnterCallback);
|
||||
bd->PrevUserCallbackCursorPos = glfwSetCursorPosCallback(window, ImGui_ImplGlfw_CursorPosCallback);
|
||||
bd->PrevUserCallbackMousebutton = glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback);
|
||||
bd->PrevUserCallbackScroll = glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback);
|
||||
bd->PrevUserCallbackKey = glfwSetKeyCallback(window, ImGui_ImplGlfw_KeyCallback);
|
||||
bd->PrevUserCallbackChar = glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback);
|
||||
bd->PrevUserCallbackMonitor = glfwSetMonitorCallback(ImGui_ImplGlfw_MonitorCallback);
|
||||
bd->InstalledCallbacks = true;
|
||||
}
|
||||
|
||||
void ImGui_ImplGlfw_RestoreCallbacks(GLFWwindow* window)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
IM_ASSERT(bd->InstalledCallbacks == true && "Callbacks not installed!");
|
||||
IM_ASSERT(bd->Window == window);
|
||||
|
||||
glfwSetWindowFocusCallback(window, bd->PrevUserCallbackWindowFocus);
|
||||
glfwSetCursorEnterCallback(window, bd->PrevUserCallbackCursorEnter);
|
||||
glfwSetCursorPosCallback(window, bd->PrevUserCallbackCursorPos);
|
||||
glfwSetMouseButtonCallback(window, bd->PrevUserCallbackMousebutton);
|
||||
glfwSetScrollCallback(window, bd->PrevUserCallbackScroll);
|
||||
glfwSetKeyCallback(window, bd->PrevUserCallbackKey);
|
||||
glfwSetCharCallback(window, bd->PrevUserCallbackChar);
|
||||
glfwSetMonitorCallback(bd->PrevUserCallbackMonitor);
|
||||
bd->InstalledCallbacks = false;
|
||||
bd->PrevUserCallbackWindowFocus = nullptr;
|
||||
bd->PrevUserCallbackCursorEnter = nullptr;
|
||||
bd->PrevUserCallbackCursorPos = nullptr;
|
||||
bd->PrevUserCallbackMousebutton = nullptr;
|
||||
bd->PrevUserCallbackScroll = nullptr;
|
||||
bd->PrevUserCallbackKey = nullptr;
|
||||
bd->PrevUserCallbackChar = nullptr;
|
||||
bd->PrevUserCallbackMonitor = nullptr;
|
||||
}
|
||||
|
||||
static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, GlfwClientApi client_api)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
|
||||
//printf("GLFW_VERSION: %d.%d.%d (%d)", GLFW_VERSION_MAJOR, GLFW_VERSION_MINOR, GLFW_VERSION_REVISION, GLFW_VERSION_COMBINED);
|
||||
|
||||
// Setup backend capabilities flags
|
||||
ImGui_ImplGlfw_Data* bd = IM_NEW(ImGui_ImplGlfw_Data)();
|
||||
io.BackendPlatformUserData = (void*)bd;
|
||||
io.BackendPlatformName = "imgui_impl_glfw";
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
||||
|
||||
bd->Window = window;
|
||||
bd->Time = 0.0;
|
||||
|
||||
io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText;
|
||||
io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText;
|
||||
io.ClipboardUserData = bd->Window;
|
||||
|
||||
// Set platform dependent data in viewport
|
||||
#if defined(_WIN32)
|
||||
ImGui::GetMainViewport()->PlatformHandleRaw = (void*)glfwGetWin32Window(bd->Window);
|
||||
#endif
|
||||
|
||||
// Create mouse cursors
|
||||
// (By design, on X11 cursors are user configurable and some cursors may be missing. When a cursor doesn't exist,
|
||||
// GLFW will emit an error which will often be printed by the app, so we temporarily disable error reporting.
|
||||
// Missing cursors will return nullptr and our _UpdateMouseCursor() function will use the Arrow cursor instead.)
|
||||
GLFWerrorfun prev_error_callback = glfwSetErrorCallback(nullptr);
|
||||
bd->MouseCursors[ImGuiMouseCursor_Arrow] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
|
||||
bd->MouseCursors[ImGuiMouseCursor_TextInput] = glfwCreateStandardCursor(GLFW_IBEAM_CURSOR);
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNS] = glfwCreateStandardCursor(GLFW_VRESIZE_CURSOR);
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeEW] = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR);
|
||||
bd->MouseCursors[ImGuiMouseCursor_Hand] = glfwCreateStandardCursor(GLFW_HAND_CURSOR);
|
||||
#if GLFW_HAS_NEW_CURSORS
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeAll] = glfwCreateStandardCursor(GLFW_RESIZE_ALL_CURSOR);
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = glfwCreateStandardCursor(GLFW_RESIZE_NESW_CURSOR);
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = glfwCreateStandardCursor(GLFW_RESIZE_NWSE_CURSOR);
|
||||
bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = glfwCreateStandardCursor(GLFW_NOT_ALLOWED_CURSOR);
|
||||
#else
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeAll] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
|
||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
|
||||
bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
|
||||
#endif
|
||||
glfwSetErrorCallback(prev_error_callback);
|
||||
#if (GLFW_VERSION_COMBINED >= 3300) // Eat errors (see #5785)
|
||||
(void)glfwGetError(NULL);
|
||||
#endif
|
||||
|
||||
// Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any.
|
||||
if (install_callbacks)
|
||||
ImGui_ImplGlfw_InstallCallbacks(window);
|
||||
|
||||
bd->ClientApi = client_api;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImGui_ImplGlfw_InitForOpenGL(GLFWwindow* window, bool install_callbacks)
|
||||
{
|
||||
return ImGui_ImplGlfw_Init(window, install_callbacks, GlfwClientApi_OpenGL);
|
||||
}
|
||||
|
||||
bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool install_callbacks)
|
||||
{
|
||||
return ImGui_ImplGlfw_Init(window, install_callbacks, GlfwClientApi_Vulkan);
|
||||
}
|
||||
|
||||
bool ImGui_ImplGlfw_InitForOther(GLFWwindow* window, bool install_callbacks)
|
||||
{
|
||||
return ImGui_ImplGlfw_Init(window, install_callbacks, GlfwClientApi_Unknown);
|
||||
}
|
||||
|
||||
void ImGui_ImplGlfw_Shutdown()
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
if (bd->InstalledCallbacks)
|
||||
ImGui_ImplGlfw_RestoreCallbacks(bd->Window);
|
||||
|
||||
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
|
||||
glfwDestroyCursor(bd->MouseCursors[cursor_n]);
|
||||
|
||||
io.BackendPlatformName = nullptr;
|
||||
io.BackendPlatformUserData = nullptr;
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_UpdateMouseData()
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
if (glfwGetInputMode(bd->Window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
const bool is_app_focused = true;
|
||||
#else
|
||||
const bool is_app_focused = glfwGetWindowAttrib(bd->Window, GLFW_FOCUSED) != 0;
|
||||
#endif
|
||||
if (is_app_focused)
|
||||
{
|
||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
||||
if (io.WantSetMousePos)
|
||||
glfwSetCursorPos(bd->Window, (double)io.MousePos.x, (double)io.MousePos.y);
|
||||
|
||||
// (Optional) Fallback to provide mouse position when focused (ImGui_ImplGlfw_CursorPosCallback already provides this when hovered or captured)
|
||||
if (is_app_focused && bd->MouseWindow == nullptr)
|
||||
{
|
||||
double mouse_x, mouse_y;
|
||||
glfwGetCursorPos(bd->Window, &mouse_x, &mouse_y);
|
||||
io.AddMousePosEvent((float)mouse_x, (float)mouse_y);
|
||||
bd->LastValidMousePos = ImVec2((float)mouse_x, (float)mouse_y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_UpdateMouseCursor()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
if ((io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) || glfwGetInputMode(bd->Window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED)
|
||||
return;
|
||||
|
||||
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
|
||||
if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor)
|
||||
{
|
||||
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
|
||||
glfwSetInputMode(bd->Window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Show OS mouse cursor
|
||||
// FIXME-PLATFORM: Unfocused windows seems to fail changing the mouse cursor with GLFW 3.2, but 3.3 works here.
|
||||
glfwSetCursor(bd->Window, bd->MouseCursors[imgui_cursor] ? bd->MouseCursors[imgui_cursor] : bd->MouseCursors[ImGuiMouseCursor_Arrow]);
|
||||
glfwSetInputMode(bd->Window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
// Update gamepad inputs
|
||||
static inline float Saturate(float v) { return v < 0.0f ? 0.0f : v > 1.0f ? 1.0f : v; }
|
||||
static void ImGui_ImplGlfw_UpdateGamepads()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) // FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
|
||||
return;
|
||||
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
|
||||
#if GLFW_HAS_GAMEPAD_API
|
||||
GLFWgamepadstate gamepad;
|
||||
if (!glfwGetGamepadState(GLFW_JOYSTICK_1, &gamepad))
|
||||
return;
|
||||
#define MAP_BUTTON(KEY_NO, BUTTON_NO, _UNUSED) do { io.AddKeyEvent(KEY_NO, gamepad.buttons[BUTTON_NO] != 0); } while (0)
|
||||
#define MAP_ANALOG(KEY_NO, AXIS_NO, _UNUSED, V0, V1) do { float v = gamepad.axes[AXIS_NO]; v = (v - V0) / (V1 - V0); io.AddKeyAnalogEvent(KEY_NO, v > 0.10f, Saturate(v)); } while (0)
|
||||
#else
|
||||
int axes_count = 0, buttons_count = 0;
|
||||
const float* axes = glfwGetJoystickAxes(GLFW_JOYSTICK_1, &axes_count);
|
||||
const unsigned char* buttons = glfwGetJoystickButtons(GLFW_JOYSTICK_1, &buttons_count);
|
||||
if (axes_count == 0 || buttons_count == 0)
|
||||
return;
|
||||
#define MAP_BUTTON(KEY_NO, _UNUSED, BUTTON_NO) do { io.AddKeyEvent(KEY_NO, (buttons_count > BUTTON_NO && buttons[BUTTON_NO] == GLFW_PRESS)); } while (0)
|
||||
#define MAP_ANALOG(KEY_NO, _UNUSED, AXIS_NO, V0, V1) do { float v = (axes_count > AXIS_NO) ? axes[AXIS_NO] : V0; v = (v - V0) / (V1 - V0); io.AddKeyAnalogEvent(KEY_NO, v > 0.10f, Saturate(v)); } while (0)
|
||||
#endif
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
|
||||
MAP_BUTTON(ImGuiKey_GamepadStart, GLFW_GAMEPAD_BUTTON_START, 7);
|
||||
MAP_BUTTON(ImGuiKey_GamepadBack, GLFW_GAMEPAD_BUTTON_BACK, 6);
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceLeft, GLFW_GAMEPAD_BUTTON_X, 2); // Xbox X, PS Square
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceRight, GLFW_GAMEPAD_BUTTON_B, 1); // Xbox B, PS Circle
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceUp, GLFW_GAMEPAD_BUTTON_Y, 3); // Xbox Y, PS Triangle
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceDown, GLFW_GAMEPAD_BUTTON_A, 0); // Xbox A, PS Cross
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadLeft, GLFW_GAMEPAD_BUTTON_DPAD_LEFT, 13);
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadRight, GLFW_GAMEPAD_BUTTON_DPAD_RIGHT, 11);
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadUp, GLFW_GAMEPAD_BUTTON_DPAD_UP, 10);
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadDown, GLFW_GAMEPAD_BUTTON_DPAD_DOWN, 12);
|
||||
MAP_BUTTON(ImGuiKey_GamepadL1, GLFW_GAMEPAD_BUTTON_LEFT_BUMPER, 4);
|
||||
MAP_BUTTON(ImGuiKey_GamepadR1, GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER, 5);
|
||||
MAP_ANALOG(ImGuiKey_GamepadL2, GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, 4, -0.75f, +1.0f);
|
||||
MAP_ANALOG(ImGuiKey_GamepadR2, GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, 5, -0.75f, +1.0f);
|
||||
MAP_BUTTON(ImGuiKey_GamepadL3, GLFW_GAMEPAD_BUTTON_LEFT_THUMB, 8);
|
||||
MAP_BUTTON(ImGuiKey_GamepadR3, GLFW_GAMEPAD_BUTTON_RIGHT_THUMB, 9);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickLeft, GLFW_GAMEPAD_AXIS_LEFT_X, 0, -0.25f, -1.0f);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickRight, GLFW_GAMEPAD_AXIS_LEFT_X, 0, +0.25f, +1.0f);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickUp, GLFW_GAMEPAD_AXIS_LEFT_Y, 1, -0.25f, -1.0f);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickDown, GLFW_GAMEPAD_AXIS_LEFT_Y, 1, +0.25f, +1.0f);
|
||||
MAP_ANALOG(ImGuiKey_GamepadRStickLeft, GLFW_GAMEPAD_AXIS_RIGHT_X, 2, -0.25f, -1.0f);
|
||||
MAP_ANALOG(ImGuiKey_GamepadRStickRight, GLFW_GAMEPAD_AXIS_RIGHT_X, 2, +0.25f, +1.0f);
|
||||
MAP_ANALOG(ImGuiKey_GamepadRStickUp, GLFW_GAMEPAD_AXIS_RIGHT_Y, 3, -0.25f, -1.0f);
|
||||
MAP_ANALOG(ImGuiKey_GamepadRStickDown, GLFW_GAMEPAD_AXIS_RIGHT_Y, 3, +0.25f, +1.0f);
|
||||
#undef MAP_BUTTON
|
||||
#undef MAP_ANALOG
|
||||
}
|
||||
|
||||
void ImGui_ImplGlfw_NewFrame()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplGlfw_InitForXXX()?");
|
||||
|
||||
// Setup display size (every frame to accommodate for window resizing)
|
||||
int w, h;
|
||||
int display_w, display_h;
|
||||
glfwGetWindowSize(bd->Window, &w, &h);
|
||||
glfwGetFramebufferSize(bd->Window, &display_w, &display_h);
|
||||
io.DisplaySize = ImVec2((float)w, (float)h);
|
||||
if (w > 0 && h > 0)
|
||||
io.DisplayFramebufferScale = ImVec2((float)display_w / (float)w, (float)display_h / (float)h);
|
||||
|
||||
// Setup time step
|
||||
double current_time = glfwGetTime();
|
||||
io.DeltaTime = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f);
|
||||
bd->Time = current_time;
|
||||
|
||||
ImGui_ImplGlfw_UpdateMouseData();
|
||||
ImGui_ImplGlfw_UpdateMouseCursor();
|
||||
|
||||
// Update game controllers (if enabled and available)
|
||||
ImGui_ImplGlfw_UpdateGamepads();
|
||||
}
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
42
Framework/external/embree/tutorials/common/imgui/backends/imgui_impl_glfw.h
vendored
Normal file
42
Framework/external/embree/tutorials/common/imgui/backends/imgui_impl_glfw.h
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// dear imgui: Platform Backend for GLFW
|
||||
// This needs to be used along with a Renderer (e.g. OpenGL3, Vulkan, WebGPU..)
|
||||
// (Info: GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Clipboard support.
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
|
||||
struct GLFWwindow;
|
||||
struct GLFWmonitor;
|
||||
|
||||
IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForOpenGL(GLFWwindow* window, bool install_callbacks);
|
||||
IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool install_callbacks);
|
||||
IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForOther(GLFWwindow* window, bool install_callbacks);
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_NewFrame();
|
||||
|
||||
// GLFW callbacks (installer)
|
||||
// - When calling Init with 'install_callbacks=true': ImGui_ImplGlfw_InstallCallbacks() is called. GLFW callbacks will be installed for you. They will chain-call user's previously installed callbacks, if any.
|
||||
// - When calling Init with 'install_callbacks=false': GLFW callbacks won't be installed. You will need to call individual function yourself from your own GLFW callbacks.
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window);
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_RestoreCallbacks(GLFWwindow* window);
|
||||
|
||||
// GLFW callbacks (individual callbacks to call if you didn't install callbacks)
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused); // Since 1.84
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered); // Since 1.84
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y); // Since 1.87
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods);
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset);
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c);
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor* monitor, int event);
|
||||
287
Framework/external/embree/tutorials/common/imgui/backends/imgui_impl_opengl2.cpp
vendored
Normal file
287
Framework/external/embree/tutorials/common/imgui/backends/imgui_impl_opengl2.cpp
vendored
Normal file
|
|
@ -0,0 +1,287 @@
|
|||
// dear imgui: Renderer Backend for OpenGL2 (legacy OpenGL, fixed pipeline)
|
||||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)**
|
||||
// **Prefer using the code in imgui_impl_opengl3.cpp**
|
||||
// This code is mostly provided as a reference to learn how ImGui integration works, because it is shorter to read.
|
||||
// If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything more
|
||||
// complicated, will require your code to reset every single OpenGL attributes to their initial state, and might
|
||||
// confuse your GPU driver.
|
||||
// The GL2 code is unable to reset attributes or even call e.g. "glUseProgram(0)" because they don't exist in that API.
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2021-12-08: OpenGL: Fixed mishandling of the the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-05-19: OpenGL: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
// 2021-01-03: OpenGL: Backup, setup and restore GL_SHADE_MODEL state, disable GL_STENCIL_TEST and disable GL_NORMAL_ARRAY client state to increase compatibility with legacy OpenGL applications.
|
||||
// 2020-01-23: OpenGL: Backup, setup and restore GL_TEXTURE_ENV to increase compatibility with legacy OpenGL applications.
|
||||
// 2019-04-30: OpenGL: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
|
||||
// 2019-02-11: OpenGL: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display.
|
||||
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
|
||||
// 2018-08-03: OpenGL: Disabling/restoring GL_LIGHTING and GL_COLOR_MATERIAL to increase compatibility with legacy OpenGL applications.
|
||||
// 2018-06-08: Misc: Extracted imgui_impl_opengl2.cpp/.h away from the old combined GLFW/SDL+OpenGL2 examples.
|
||||
// 2018-06-08: OpenGL: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle.
|
||||
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplOpenGL2_RenderDrawData() in the .h file so you can call it yourself.
|
||||
// 2017-09-01: OpenGL: Save and restore current polygon mode.
|
||||
// 2016-09-10: OpenGL: Uploading font texture as RGBA32 to increase compatibility with users shaders (not ideal).
|
||||
// 2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle.
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_opengl2.h"
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
|
||||
#include <stddef.h> // intptr_t
|
||||
#else
|
||||
#include <stdint.h> // intptr_t
|
||||
#endif
|
||||
|
||||
// Include OpenGL header (without an OpenGL loader) requires a bit of fiddling
|
||||
#if defined(_WIN32) && !defined(APIENTRY)
|
||||
#define APIENTRY __stdcall // It is customary to use APIENTRY for OpenGL function pointer declarations on all platforms. Additionally, the Windows OpenGL header needs APIENTRY.
|
||||
#endif
|
||||
#if defined(_WIN32) && !defined(WINGDIAPI)
|
||||
#define WINGDIAPI __declspec(dllimport) // Some Windows OpenGL headers need this
|
||||
#endif
|
||||
#if defined(__APPLE__)
|
||||
#define GL_SILENCE_DEPRECATION
|
||||
#include <OpenGL/gl.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
struct ImGui_ImplOpenGL2_Data
|
||||
{
|
||||
GLuint FontTexture;
|
||||
|
||||
ImGui_ImplOpenGL2_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
|
||||
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
||||
static ImGui_ImplOpenGL2_Data* ImGui_ImplOpenGL2_GetBackendData()
|
||||
{
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplOpenGL2_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
// Functions
|
||||
bool ImGui_ImplOpenGL2_Init()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||
|
||||
// Setup backend capabilities flags
|
||||
ImGui_ImplOpenGL2_Data* bd = IM_NEW(ImGui_ImplOpenGL2_Data)();
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_opengl2";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplOpenGL2_Shutdown()
|
||||
{
|
||||
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplOpenGL2_DestroyDeviceObjects();
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
void ImGui_ImplOpenGL2_NewFrame()
|
||||
{
|
||||
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplOpenGL2_Init()?");
|
||||
|
||||
if (!bd->FontTexture)
|
||||
ImGui_ImplOpenGL2_CreateDeviceObjects();
|
||||
}
|
||||
|
||||
static void ImGui_ImplOpenGL2_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height)
|
||||
{
|
||||
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers, polygon fill.
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
//glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // In order to composite our output buffer we need to preserve alpha
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
// If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!),
|
||||
// you may need to backup/reset/restore other state, e.g. for current shader using the commented lines below.
|
||||
// (DO NOT MODIFY THIS FILE! Add the code in your calling function)
|
||||
// GLint last_program;
|
||||
// glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
|
||||
// glUseProgram(0);
|
||||
// ImGui_ImplOpenGL2_RenderDrawData(...);
|
||||
// glUseProgram(last_program)
|
||||
// There are potentially many more states you could need to clear/setup that we can't access from default headers.
|
||||
// e.g. glBindBuffer(GL_ARRAY_BUFFER, 0), glDisable(GL_TEXTURE_CUBE_MAP).
|
||||
|
||||
// Setup viewport, orthographic projection matrix
|
||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
||||
glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glOrtho(draw_data->DisplayPos.x, draw_data->DisplayPos.x + draw_data->DisplaySize.x, draw_data->DisplayPos.y + draw_data->DisplaySize.y, draw_data->DisplayPos.y, -1.0f, +1.0f);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
// OpenGL2 Render function.
|
||||
// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly.
|
||||
// This is in order to be able to run within an OpenGL engine that doesn't do so.
|
||||
void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
|
||||
{
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
if (fb_width == 0 || fb_height == 0)
|
||||
return;
|
||||
|
||||
// Backup GL state
|
||||
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
||||
GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
|
||||
GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
|
||||
GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
|
||||
GLint last_shade_model; glGetIntegerv(GL_SHADE_MODEL, &last_shade_model);
|
||||
GLint last_tex_env_mode; glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &last_tex_env_mode);
|
||||
glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT);
|
||||
|
||||
// Setup desired GL state
|
||||
ImGui_ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height);
|
||||
|
||||
// Will project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
||||
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
|
||||
|
||||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data;
|
||||
const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data;
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, pos)));
|
||||
glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, uv)));
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, col)));
|
||||
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
// Apply scissor/clipping rectangle (Y is inverted in OpenGL)
|
||||
glScissor((int)clip_min.x, (int)((float)fb_height - clip_max.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y));
|
||||
|
||||
// Bind texture, Draw
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID());
|
||||
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer + pcmd->IdxOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Restore modified GL state
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glPopAttrib();
|
||||
glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]); glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]);
|
||||
glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]);
|
||||
glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]);
|
||||
glShadeModel(last_shade_model);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, last_tex_env_mode);
|
||||
}
|
||||
|
||||
bool ImGui_ImplOpenGL2_CreateFontsTexture()
|
||||
{
|
||||
// Build texture atlas
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
||||
unsigned char* pixels;
|
||||
int width, height;
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.
|
||||
|
||||
// Upload texture to graphics system
|
||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||
GLint last_texture;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
||||
glGenTextures(1, &bd->FontTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, bd->FontTexture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
// Store our identifier
|
||||
io.Fonts->SetTexID((ImTextureID)(intptr_t)bd->FontTexture);
|
||||
|
||||
// Restore state
|
||||
glBindTexture(GL_TEXTURE_2D, last_texture);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplOpenGL2_DestroyFontsTexture()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
||||
if (bd->FontTexture)
|
||||
{
|
||||
glDeleteTextures(1, &bd->FontTexture);
|
||||
io.Fonts->SetTexID(0);
|
||||
bd->FontTexture = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool ImGui_ImplOpenGL2_CreateDeviceObjects()
|
||||
{
|
||||
return ImGui_ImplOpenGL2_CreateFontsTexture();
|
||||
}
|
||||
|
||||
void ImGui_ImplOpenGL2_DestroyDeviceObjects()
|
||||
{
|
||||
ImGui_ImplOpenGL2_DestroyFontsTexture();
|
||||
}
|
||||
32
Framework/external/embree/tutorials/common/imgui/backends/imgui_impl_opengl2.h
vendored
Normal file
32
Framework/external/embree/tutorials/common/imgui/backends/imgui_impl_opengl2.h
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// dear imgui: Renderer Backend for OpenGL2 (legacy OpenGL, fixed pipeline)
|
||||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)**
|
||||
// **Prefer using the code in imgui_impl_opengl3.cpp**
|
||||
// This code is mostly provided as a reference to learn how ImGui integration works, because it is shorter to read.
|
||||
// If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything more
|
||||
// complicated, will require your code to reset every single OpenGL attributes to their initial state, and might
|
||||
// confuse your GPU driver.
|
||||
// The GL2 code is unable to reset attributes or even call e.g. "glUseProgram(0)" because they don't exist in that API.
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
|
||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL2_Init();
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data);
|
||||
|
||||
// Called by Init/NewFrame/Shutdown
|
||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL2_CreateFontsTexture();
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_DestroyFontsTexture();
|
||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL2_CreateDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_DestroyDeviceObjects();
|
||||
890
Framework/external/embree/tutorials/common/imgui/backends/imgui_impl_opengl3.cpp
vendored
Normal file
890
Framework/external/embree/tutorials/common/imgui/backends/imgui_impl_opengl3.cpp
vendored
Normal file
|
|
@ -0,0 +1,890 @@
|
|||
// dear imgui: Renderer Backend for modern OpenGL with shaders / programmatic pipeline
|
||||
// - Desktop GL: 2.x 3.x 4.x
|
||||
// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0)
|
||||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [x] Renderer: Desktop GL only: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2022-11-09: OpenGL: Reverted use of glBufferSubData(), too many corruptions issues + old issues seemingly can't be reproed with Intel drivers nowadays (revert 2021-12-15 and 2022-05-23 changes).
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2022-09-27: OpenGL: Added ability to '#define IMGUI_IMPL_OPENGL_DEBUG'.
|
||||
// 2022-05-23: OpenGL: Reworking 2021-12-15 "Using buffer orphaning" so it only happens on Intel GPU, seems to cause problems otherwise. (#4468, #4825, #4832, #5127).
|
||||
// 2022-05-13: OpenGL: Fix state corruption on OpenGL ES 2.0 due to not preserving GL_ELEMENT_ARRAY_BUFFER_BINDING and vertex attribute states.
|
||||
// 2021-12-15: OpenGL: Using buffer orphaning + glBufferSubData(), seems to fix leaks with multi-viewports with some Intel HD drivers.
|
||||
// 2021-08-23: OpenGL: Fixed ES 3.0 shader ("#version 300 es") use normal precision floats to avoid wobbly rendering at HD resolutions.
|
||||
// 2021-08-19: OpenGL: Embed and use our own minimal GL loader (imgui_impl_opengl3_loader.h), removing requirement and support for third-party loader.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-06-25: OpenGL: Use OES_vertex_array extension on Emscripten + backup/restore current state.
|
||||
// 2021-06-21: OpenGL: Destroy individual vertex/fragment shader objects right after they are linked into the main shader.
|
||||
// 2021-05-24: OpenGL: Access GL_CLIP_ORIGIN when "GL_ARB_clip_control" extension is detected, inside of just OpenGL 4.5 version.
|
||||
// 2021-05-19: OpenGL: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
// 2021-04-06: OpenGL: Don't try to read GL_CLIP_ORIGIN unless we're OpenGL 4.5 or greater.
|
||||
// 2021-02-18: OpenGL: Change blending equation to preserve alpha in output buffer.
|
||||
// 2021-01-03: OpenGL: Backup, setup and restore GL_STENCIL_TEST state.
|
||||
// 2020-10-23: OpenGL: Backup, setup and restore GL_PRIMITIVE_RESTART state.
|
||||
// 2020-10-15: OpenGL: Use glGetString(GL_VERSION) instead of glGetIntegerv(GL_MAJOR_VERSION, ...) when the later returns zero (e.g. Desktop GL 2.x)
|
||||
// 2020-09-17: OpenGL: Fix to avoid compiling/calling glBindSampler() on ES or pre 3.3 context which have the defines set by a loader.
|
||||
// 2020-07-10: OpenGL: Added support for glad2 OpenGL loader.
|
||||
// 2020-05-08: OpenGL: Made default GLSL version 150 (instead of 130) on OSX.
|
||||
// 2020-04-21: OpenGL: Fixed handling of glClipControl(GL_UPPER_LEFT) by inverting projection matrix.
|
||||
// 2020-04-12: OpenGL: Fixed context version check mistakenly testing for 4.0+ instead of 3.2+ to enable ImGuiBackendFlags_RendererHasVtxOffset.
|
||||
// 2020-03-24: OpenGL: Added support for glbinding 2.x OpenGL loader.
|
||||
// 2020-01-07: OpenGL: Added support for glbinding 3.x OpenGL loader.
|
||||
// 2019-10-25: OpenGL: Using a combination of GL define and runtime GL version to decide whether to use glDrawElementsBaseVertex(). Fix building with pre-3.2 GL loaders.
|
||||
// 2019-09-22: OpenGL: Detect default GL loader using __has_include compiler facility.
|
||||
// 2019-09-16: OpenGL: Tweak initialization code to allow application calling ImGui_ImplOpenGL3_CreateFontsTexture() before the first NewFrame() call.
|
||||
// 2019-05-29: OpenGL: Desktop GL only: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
|
||||
// 2019-04-30: OpenGL: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
|
||||
// 2019-03-29: OpenGL: Not calling glBindBuffer more than necessary in the render loop.
|
||||
// 2019-03-15: OpenGL: Added a GL call + comments in ImGui_ImplOpenGL3_Init() to detect uninitialized GL function loaders early.
|
||||
// 2019-03-03: OpenGL: Fix support for ES 2.0 (WebGL 1.0).
|
||||
// 2019-02-20: OpenGL: Fix for OSX not supporting OpenGL 4.5, we don't try to read GL_CLIP_ORIGIN even if defined by the headers/loader.
|
||||
// 2019-02-11: OpenGL: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display.
|
||||
// 2019-02-01: OpenGL: Using GLSL 410 shaders for any version over 410 (e.g. 430, 450).
|
||||
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
|
||||
// 2018-11-13: OpenGL: Support for GL 4.5's glClipControl(GL_UPPER_LEFT) / GL_CLIP_ORIGIN.
|
||||
// 2018-08-29: OpenGL: Added support for more OpenGL loaders: glew and glad, with comments indicative that any loader can be used.
|
||||
// 2018-08-09: OpenGL: Default to OpenGL ES 3 on iOS and Android. GLSL version default to "#version 300 ES".
|
||||
// 2018-07-30: OpenGL: Support for GLSL 300 ES and 410 core. Fixes for Emscripten compilation.
|
||||
// 2018-07-10: OpenGL: Support for more GLSL versions (based on the GLSL version string). Added error output when shaders fail to compile/link.
|
||||
// 2018-06-08: Misc: Extracted imgui_impl_opengl3.cpp/.h away from the old combined GLFW/SDL+OpenGL3 examples.
|
||||
// 2018-06-08: OpenGL: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle.
|
||||
// 2018-05-25: OpenGL: Removed unnecessary backup/restore of GL_ELEMENT_ARRAY_BUFFER_BINDING since this is part of the VAO state.
|
||||
// 2018-05-14: OpenGL: Making the call to glBindSampler() optional so 3.2 context won't fail if the function is a nullptr pointer.
|
||||
// 2018-03-06: OpenGL: Added const char* glsl_version parameter to ImGui_ImplOpenGL3_Init() so user can override the GLSL version e.g. "#version 150".
|
||||
// 2018-02-23: OpenGL: Create the VAO in the render function so the setup can more easily be used with multiple shared GL context.
|
||||
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplSdlGL3_RenderDrawData() in the .h file so you can call it yourself.
|
||||
// 2018-01-07: OpenGL: Changed GLSL shader version from 330 to 150.
|
||||
// 2017-09-01: OpenGL: Save and restore current bound sampler. Save and restore current polygon mode.
|
||||
// 2017-05-01: OpenGL: Fixed save and restore of current blend func state.
|
||||
// 2017-05-01: OpenGL: Fixed save and restore of current GL_ACTIVE_TEXTURE.
|
||||
// 2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle.
|
||||
// 2016-07-29: OpenGL: Explicitly setting GL_UNPACK_ROW_LENGTH to reduce issues because SDL changes it. (#752)
|
||||
|
||||
//----------------------------------------
|
||||
// OpenGL GLSL GLSL
|
||||
// version version string
|
||||
//----------------------------------------
|
||||
// 2.0 110 "#version 110"
|
||||
// 2.1 120 "#version 120"
|
||||
// 3.0 130 "#version 130"
|
||||
// 3.1 140 "#version 140"
|
||||
// 3.2 150 "#version 150"
|
||||
// 3.3 330 "#version 330 core"
|
||||
// 4.0 400 "#version 400 core"
|
||||
// 4.1 410 "#version 410 core"
|
||||
// 4.2 420 "#version 410 core"
|
||||
// 4.3 430 "#version 430 core"
|
||||
// ES 2.0 100 "#version 100" = WebGL 1.0
|
||||
// ES 3.0 300 "#version 300 es" = WebGL 2.0
|
||||
//----------------------------------------
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_opengl3.h"
|
||||
#include <stdio.h>
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
|
||||
#include <stddef.h> // intptr_t
|
||||
#else
|
||||
#include <stdint.h> // intptr_t
|
||||
#endif
|
||||
#if defined(__APPLE__)
|
||||
#include <TargetConditionals.h>
|
||||
#endif
|
||||
|
||||
// Clang warnings with -Weverything
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast
|
||||
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||||
#endif
|
||||
|
||||
// GL includes
|
||||
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
||||
#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV))
|
||||
#include <OpenGLES/ES2/gl.h> // Use GL ES 2
|
||||
#else
|
||||
#include <GLES2/gl2.h> // Use GL ES 2
|
||||
#endif
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
#ifndef GL_GLEXT_PROTOTYPES
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#endif
|
||||
#include <GLES2/gl2ext.h>
|
||||
#endif
|
||||
#elif defined(IMGUI_IMPL_OPENGL_ES3)
|
||||
#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV))
|
||||
#include <OpenGLES/ES3/gl.h> // Use GL ES 3
|
||||
#else
|
||||
#include <GLES3/gl3.h> // Use GL ES 3
|
||||
#endif
|
||||
#elif !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM)
|
||||
// Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers.
|
||||
// Helper libraries are often used for this purpose! Here we are using our own minimal custom loader based on gl3w.
|
||||
// In the rest of your app/engine, you can use another loader of your choice (gl3w, glew, glad, glbinding, glext, glLoadGen, etc.).
|
||||
// If you happen to be developing a new feature for this backend (imgui_impl_opengl3.cpp):
|
||||
// - You may need to regenerate imgui_impl_opengl3_loader.h to add new symbols. See https://github.com/dearimgui/gl3w_stripped
|
||||
// - You can temporarily use an unstripped version. See https://github.com/dearimgui/gl3w_stripped/releases
|
||||
// Changes to this backend using new APIs should be accompanied by a regenerated stripped loader version.
|
||||
#define IMGL3W_IMPL
|
||||
#include "imgui_impl_opengl3_loader.h"
|
||||
#endif
|
||||
|
||||
// Vertex arrays are not supported on ES2/WebGL1 unless Emscripten which uses an extension
|
||||
#ifndef IMGUI_IMPL_OPENGL_ES2
|
||||
#define IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
#define IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
|
||||
#define glBindVertexArray glBindVertexArrayOES
|
||||
#define glGenVertexArrays glGenVertexArraysOES
|
||||
#define glDeleteVertexArrays glDeleteVertexArraysOES
|
||||
#define GL_VERTEX_ARRAY_BINDING GL_VERTEX_ARRAY_BINDING_OES
|
||||
#endif
|
||||
|
||||
// Desktop GL 2.0+ has glPolygonMode() which GL ES and WebGL don't have.
|
||||
#ifdef GL_POLYGON_MODE
|
||||
#define IMGUI_IMPL_HAS_POLYGON_MODE
|
||||
#endif
|
||||
|
||||
// Desktop GL 3.2+ has glDrawElementsBaseVertex() which GL ES and WebGL don't have.
|
||||
#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && defined(GL_VERSION_3_2)
|
||||
#define IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
|
||||
#endif
|
||||
|
||||
// Desktop GL 3.3+ has glBindSampler()
|
||||
#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && defined(GL_VERSION_3_3)
|
||||
#define IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
||||
#endif
|
||||
|
||||
// Desktop GL 3.1+ has GL_PRIMITIVE_RESTART state
|
||||
#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && defined(GL_VERSION_3_1)
|
||||
#define IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
|
||||
#endif
|
||||
|
||||
// Desktop GL use extension detection
|
||||
#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3)
|
||||
#define IMGUI_IMPL_OPENGL_MAY_HAVE_EXTENSIONS
|
||||
#endif
|
||||
|
||||
// [Debugging]
|
||||
//#define IMGUI_IMPL_OPENGL_DEBUG
|
||||
#ifdef IMGUI_IMPL_OPENGL_DEBUG
|
||||
#include <stdio.h>
|
||||
#define GL_CALL(_CALL) do { _CALL; GLenum gl_err = glGetError(); if (gl_err != 0) fprintf(stderr, "GL error 0x%x returned from '%s'.\n", gl_err, #_CALL); } while (0) // Call with error check
|
||||
#else
|
||||
#define GL_CALL(_CALL) _CALL // Call without error check
|
||||
#endif
|
||||
|
||||
// OpenGL Data
|
||||
struct ImGui_ImplOpenGL3_Data
|
||||
{
|
||||
GLuint GlVersion; // Extracted at runtime using GL_MAJOR_VERSION, GL_MINOR_VERSION queries (e.g. 320 for GL 3.2)
|
||||
char GlslVersionString[32]; // Specified by user or detected based on compile time GL settings.
|
||||
GLuint FontTexture;
|
||||
GLuint ShaderHandle;
|
||||
GLint AttribLocationTex; // Uniforms location
|
||||
GLint AttribLocationProjMtx;
|
||||
GLuint AttribLocationVtxPos; // Vertex attributes location
|
||||
GLuint AttribLocationVtxUV;
|
||||
GLuint AttribLocationVtxColor;
|
||||
unsigned int VboHandle, ElementsHandle;
|
||||
GLsizeiptr VertexBufferSize;
|
||||
GLsizeiptr IndexBufferSize;
|
||||
bool HasClipOrigin;
|
||||
bool UseBufferSubData;
|
||||
|
||||
ImGui_ImplOpenGL3_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
|
||||
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
||||
static ImGui_ImplOpenGL3_Data* ImGui_ImplOpenGL3_GetBackendData()
|
||||
{
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplOpenGL3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
// OpenGL vertex attribute state (for ES 1.0 and ES 2.0 only)
|
||||
#ifndef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
|
||||
struct ImGui_ImplOpenGL3_VtxAttribState
|
||||
{
|
||||
GLint Enabled, Size, Type, Normalized, Stride;
|
||||
GLvoid* Ptr;
|
||||
|
||||
void GetState(GLint index)
|
||||
{
|
||||
glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &Enabled);
|
||||
glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_SIZE, &Size);
|
||||
glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_TYPE, &Type);
|
||||
glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &Normalized);
|
||||
glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &Stride);
|
||||
glGetVertexAttribPointerv(index, GL_VERTEX_ATTRIB_ARRAY_POINTER, &Ptr);
|
||||
}
|
||||
void SetState(GLint index)
|
||||
{
|
||||
glVertexAttribPointer(index, Size, Type, (GLboolean)Normalized, Stride, Ptr);
|
||||
if (Enabled) glEnableVertexAttribArray(index); else glDisableVertexAttribArray(index);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
// Functions
|
||||
bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||
|
||||
// Initialize our loader
|
||||
#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM)
|
||||
if (imgl3wInit() != 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to initialize OpenGL loader!\n");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Setup backend capabilities flags
|
||||
ImGui_ImplOpenGL3_Data* bd = IM_NEW(ImGui_ImplOpenGL3_Data)();
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_opengl3";
|
||||
|
||||
// Query for GL version (e.g. 320 for GL 3.2)
|
||||
#if !defined(IMGUI_IMPL_OPENGL_ES2)
|
||||
GLint major = 0;
|
||||
GLint minor = 0;
|
||||
glGetIntegerv(GL_MAJOR_VERSION, &major);
|
||||
glGetIntegerv(GL_MINOR_VERSION, &minor);
|
||||
if (major == 0 && minor == 0)
|
||||
{
|
||||
// Query GL_VERSION in desktop GL 2.x, the string will start with "<major>.<minor>"
|
||||
const char* gl_version = (const char*)glGetString(GL_VERSION);
|
||||
sscanf(gl_version, "%d.%d", &major, &minor);
|
||||
}
|
||||
bd->GlVersion = (GLuint)(major * 100 + minor * 10);
|
||||
|
||||
bd->UseBufferSubData = false;
|
||||
/*
|
||||
// Query vendor to enable glBufferSubData kludge
|
||||
#ifdef _WIN32
|
||||
if (const char* vendor = (const char*)glGetString(GL_VENDOR))
|
||||
if (strncmp(vendor, "Intel", 5) == 0)
|
||||
bd->UseBufferSubData = true;
|
||||
#endif
|
||||
*/
|
||||
#else
|
||||
bd->GlVersion = 200; // GLES 2
|
||||
#endif
|
||||
|
||||
#ifdef IMGUI_IMPL_OPENGL_DEBUG
|
||||
printf("GL_MAJOR_VERSION = %d\nGL_MINOR_VERSION = %d\nGL_VENDOR = '%s'\nGL_RENDERER = '%s'\n", major, minor, (const char*)glGetString(GL_VENDOR), (const char*)glGetString(GL_RENDERER)); // [DEBUG]
|
||||
#endif
|
||||
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
|
||||
if (bd->GlVersion >= 320)
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
#endif
|
||||
|
||||
// Store GLSL version string so we can refer to it later in case we recreate shaders.
|
||||
// Note: GLSL version is NOT the same as GL version. Leave this to nullptr if unsure.
|
||||
if (glsl_version == nullptr)
|
||||
{
|
||||
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
||||
glsl_version = "#version 100";
|
||||
#elif defined(IMGUI_IMPL_OPENGL_ES3)
|
||||
glsl_version = "#version 300 es";
|
||||
#elif defined(__APPLE__)
|
||||
glsl_version = "#version 150";
|
||||
#else
|
||||
glsl_version = "#version 130";
|
||||
#endif
|
||||
}
|
||||
IM_ASSERT((int)strlen(glsl_version) + 2 < IM_ARRAYSIZE(bd->GlslVersionString));
|
||||
strcpy(bd->GlslVersionString, glsl_version);
|
||||
strcat(bd->GlslVersionString, "\n");
|
||||
|
||||
// Make an arbitrary GL call (we don't actually need the result)
|
||||
// IF YOU GET A CRASH HERE: it probably means the OpenGL function loader didn't do its job. Let us know!
|
||||
GLint current_texture;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture);
|
||||
|
||||
// Detect extensions we support
|
||||
bd->HasClipOrigin = (bd->GlVersion >= 450);
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_EXTENSIONS
|
||||
GLint num_extensions = 0;
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
|
||||
for (GLint i = 0; i < num_extensions; i++)
|
||||
{
|
||||
const char* extension = (const char*)glGetStringi(GL_EXTENSIONS, i);
|
||||
if (extension != nullptr && strcmp(extension, "GL_ARB_clip_control") == 0)
|
||||
bd->HasClipOrigin = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplOpenGL3_Shutdown()
|
||||
{
|
||||
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplOpenGL3_DestroyDeviceObjects();
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
void ImGui_ImplOpenGL3_NewFrame()
|
||||
{
|
||||
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplOpenGL3_Init()?");
|
||||
|
||||
if (!bd->ShaderHandle)
|
||||
ImGui_ImplOpenGL3_CreateDeviceObjects();
|
||||
}
|
||||
|
||||
static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height, GLuint vertex_array_object)
|
||||
{
|
||||
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
||||
|
||||
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
|
||||
if (bd->GlVersion >= 310)
|
||||
glDisable(GL_PRIMITIVE_RESTART);
|
||||
#endif
|
||||
#ifdef IMGUI_IMPL_HAS_POLYGON_MODE
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
#endif
|
||||
|
||||
// Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT)
|
||||
#if defined(GL_CLIP_ORIGIN)
|
||||
bool clip_origin_lower_left = true;
|
||||
if (bd->HasClipOrigin)
|
||||
{
|
||||
GLenum current_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)¤t_clip_origin);
|
||||
if (current_clip_origin == GL_UPPER_LEFT)
|
||||
clip_origin_lower_left = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Setup viewport, orthographic projection matrix
|
||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
||||
GL_CALL(glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height));
|
||||
float L = draw_data->DisplayPos.x;
|
||||
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
||||
float T = draw_data->DisplayPos.y;
|
||||
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
|
||||
#if defined(GL_CLIP_ORIGIN)
|
||||
if (!clip_origin_lower_left) { float tmp = T; T = B; B = tmp; } // Swap top and bottom if origin is upper left
|
||||
#endif
|
||||
const float ortho_projection[4][4] =
|
||||
{
|
||||
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, -1.0f, 0.0f },
|
||||
{ (R+L)/(L-R), (T+B)/(B-T), 0.0f, 1.0f },
|
||||
};
|
||||
glUseProgram(bd->ShaderHandle);
|
||||
glUniform1i(bd->AttribLocationTex, 0);
|
||||
glUniformMatrix4fv(bd->AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
|
||||
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
||||
if (bd->GlVersion >= 330)
|
||||
glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise.
|
||||
#endif
|
||||
|
||||
(void)vertex_array_object;
|
||||
#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
|
||||
glBindVertexArray(vertex_array_object);
|
||||
#endif
|
||||
|
||||
// Bind vertex/index buffers and setup attributes for ImDrawVert
|
||||
GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, bd->VboHandle));
|
||||
GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bd->ElementsHandle));
|
||||
GL_CALL(glEnableVertexAttribArray(bd->AttribLocationVtxPos));
|
||||
GL_CALL(glEnableVertexAttribArray(bd->AttribLocationVtxUV));
|
||||
GL_CALL(glEnableVertexAttribArray(bd->AttribLocationVtxColor));
|
||||
GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos)));
|
||||
GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv)));
|
||||
GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col)));
|
||||
}
|
||||
|
||||
// OpenGL3 Render function.
|
||||
// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly.
|
||||
// This is in order to be able to run within an OpenGL engine that doesn't do so.
|
||||
void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
{
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
if (fb_width <= 0 || fb_height <= 0)
|
||||
return;
|
||||
|
||||
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
||||
|
||||
// Backup GL state
|
||||
GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
GLuint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*)&last_program);
|
||||
GLuint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*)&last_texture);
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
||||
GLuint last_sampler; if (bd->GlVersion >= 330) { glGetIntegerv(GL_SAMPLER_BINDING, (GLint*)&last_sampler); } else { last_sampler = 0; }
|
||||
#endif
|
||||
GLuint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&last_array_buffer);
|
||||
#ifndef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
|
||||
// This is part of VAO on OpenGL 3.0+ and OpenGL ES 3.0+.
|
||||
GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer);
|
||||
ImGui_ImplOpenGL3_VtxAttribState last_vtx_attrib_state_pos; last_vtx_attrib_state_pos.GetState(bd->AttribLocationVtxPos);
|
||||
ImGui_ImplOpenGL3_VtxAttribState last_vtx_attrib_state_uv; last_vtx_attrib_state_uv.GetState(bd->AttribLocationVtxUV);
|
||||
ImGui_ImplOpenGL3_VtxAttribState last_vtx_attrib_state_color; last_vtx_attrib_state_color.GetState(bd->AttribLocationVtxColor);
|
||||
#endif
|
||||
#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
|
||||
GLuint last_vertex_array_object; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, (GLint*)&last_vertex_array_object);
|
||||
#endif
|
||||
#ifdef IMGUI_IMPL_HAS_POLYGON_MODE
|
||||
GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
|
||||
#endif
|
||||
GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
|
||||
GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
|
||||
GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&last_blend_src_rgb);
|
||||
GLenum last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, (GLint*)&last_blend_dst_rgb);
|
||||
GLenum last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint*)&last_blend_src_alpha);
|
||||
GLenum last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint*)&last_blend_dst_alpha);
|
||||
GLenum last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint*)&last_blend_equation_rgb);
|
||||
GLenum last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint*)&last_blend_equation_alpha);
|
||||
GLboolean last_enable_blend = glIsEnabled(GL_BLEND);
|
||||
GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE);
|
||||
GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST);
|
||||
GLboolean last_enable_stencil_test = glIsEnabled(GL_STENCIL_TEST);
|
||||
GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
|
||||
GLboolean last_enable_primitive_restart = (bd->GlVersion >= 310) ? glIsEnabled(GL_PRIMITIVE_RESTART) : GL_FALSE;
|
||||
#endif
|
||||
|
||||
// Setup desired GL state
|
||||
// Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. VAO are not shared among GL contexts)
|
||||
// The renderer would actually work without any VAO bound, but then our VertexAttrib calls would overwrite the default one currently bound.
|
||||
GLuint vertex_array_object = 0;
|
||||
#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
|
||||
GL_CALL(glGenVertexArrays(1, &vertex_array_object));
|
||||
#endif
|
||||
ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object);
|
||||
|
||||
// Will project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
||||
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
|
||||
|
||||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
|
||||
// Upload vertex/index buffers
|
||||
// - OpenGL drivers are in a very sorry state nowadays....
|
||||
// During 2021 we attempted to switch from glBufferData() to orphaning+glBufferSubData() following reports
|
||||
// of leaks on Intel GPU when using multi-viewports on Windows.
|
||||
// - After this we kept hearing of various display corruptions issues. We started disabling on non-Intel GPU, but issues still got reported on Intel.
|
||||
// - We are now back to using exclusively glBufferData(). So bd->UseBufferSubData IS ALWAYS FALSE in this code.
|
||||
// We are keeping the old code path for a while in case people finding new issues may want to test the bd->UseBufferSubData path.
|
||||
// - See https://github.com/ocornut/imgui/issues/4468 and please report any corruption issues.
|
||||
const GLsizeiptr vtx_buffer_size = (GLsizeiptr)cmd_list->VtxBuffer.Size * (int)sizeof(ImDrawVert);
|
||||
const GLsizeiptr idx_buffer_size = (GLsizeiptr)cmd_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx);
|
||||
if (bd->UseBufferSubData)
|
||||
{
|
||||
if (bd->VertexBufferSize < vtx_buffer_size)
|
||||
{
|
||||
bd->VertexBufferSize = vtx_buffer_size;
|
||||
GL_CALL(glBufferData(GL_ARRAY_BUFFER, bd->VertexBufferSize, nullptr, GL_STREAM_DRAW));
|
||||
}
|
||||
if (bd->IndexBufferSize < idx_buffer_size)
|
||||
{
|
||||
bd->IndexBufferSize = idx_buffer_size;
|
||||
GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, bd->IndexBufferSize, nullptr, GL_STREAM_DRAW));
|
||||
}
|
||||
GL_CALL(glBufferSubData(GL_ARRAY_BUFFER, 0, vtx_buffer_size, (const GLvoid*)cmd_list->VtxBuffer.Data));
|
||||
GL_CALL(glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, idx_buffer_size, (const GLvoid*)cmd_list->IdxBuffer.Data));
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_CALL(glBufferData(GL_ARRAY_BUFFER, vtx_buffer_size, (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW));
|
||||
GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_size, (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW));
|
||||
}
|
||||
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback != nullptr)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
// Apply scissor/clipping rectangle (Y is inverted in OpenGL)
|
||||
GL_CALL(glScissor((int)clip_min.x, (int)((float)fb_height - clip_max.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y)));
|
||||
|
||||
// Bind texture, Draw
|
||||
GL_CALL(glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID()));
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
|
||||
if (bd->GlVersion >= 320)
|
||||
GL_CALL(glDrawElementsBaseVertex(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)), (GLint)pcmd->VtxOffset));
|
||||
else
|
||||
#endif
|
||||
GL_CALL(glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy the temporary VAO
|
||||
#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
|
||||
GL_CALL(glDeleteVertexArrays(1, &vertex_array_object));
|
||||
#endif
|
||||
|
||||
// Restore modified GL state
|
||||
glUseProgram(last_program);
|
||||
glBindTexture(GL_TEXTURE_2D, last_texture);
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
||||
if (bd->GlVersion >= 330)
|
||||
glBindSampler(0, last_sampler);
|
||||
#endif
|
||||
glActiveTexture(last_active_texture);
|
||||
#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
|
||||
glBindVertexArray(last_vertex_array_object);
|
||||
#endif
|
||||
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
|
||||
#ifndef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer);
|
||||
last_vtx_attrib_state_pos.SetState(bd->AttribLocationVtxPos);
|
||||
last_vtx_attrib_state_uv.SetState(bd->AttribLocationVtxUV);
|
||||
last_vtx_attrib_state_color.SetState(bd->AttribLocationVtxColor);
|
||||
#endif
|
||||
glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha);
|
||||
glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha);
|
||||
if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND);
|
||||
if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE);
|
||||
if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
|
||||
if (last_enable_stencil_test) glEnable(GL_STENCIL_TEST); else glDisable(GL_STENCIL_TEST);
|
||||
if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST);
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
|
||||
if (bd->GlVersion >= 310) { if (last_enable_primitive_restart) glEnable(GL_PRIMITIVE_RESTART); else glDisable(GL_PRIMITIVE_RESTART); }
|
||||
#endif
|
||||
|
||||
#ifdef IMGUI_IMPL_HAS_POLYGON_MODE
|
||||
glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]);
|
||||
#endif
|
||||
glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]);
|
||||
glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]);
|
||||
(void)bd; // Not all compilation paths use this
|
||||
}
|
||||
|
||||
bool ImGui_ImplOpenGL3_CreateFontsTexture()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
||||
|
||||
// Build texture atlas
|
||||
unsigned char* pixels;
|
||||
int width, height;
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.
|
||||
|
||||
// Upload texture to graphics system
|
||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||
GLint last_texture;
|
||||
GL_CALL(glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture));
|
||||
GL_CALL(glGenTextures(1, &bd->FontTexture));
|
||||
GL_CALL(glBindTexture(GL_TEXTURE_2D, bd->FontTexture));
|
||||
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||
#ifdef GL_UNPACK_ROW_LENGTH // Not on WebGL/ES
|
||||
GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
|
||||
#endif
|
||||
GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
|
||||
|
||||
// Store our identifier
|
||||
io.Fonts->SetTexID((ImTextureID)(intptr_t)bd->FontTexture);
|
||||
|
||||
// Restore state
|
||||
GL_CALL(glBindTexture(GL_TEXTURE_2D, last_texture));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplOpenGL3_DestroyFontsTexture()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
||||
if (bd->FontTexture)
|
||||
{
|
||||
glDeleteTextures(1, &bd->FontTexture);
|
||||
io.Fonts->SetTexID(0);
|
||||
bd->FontTexture = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// If you get an error please report on github. You may try different GL context version or GLSL version. See GL<>GLSL version table at the top of this file.
|
||||
static bool CheckShader(GLuint handle, const char* desc)
|
||||
{
|
||||
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
||||
GLint status = 0, log_length = 0;
|
||||
glGetShaderiv(handle, GL_COMPILE_STATUS, &status);
|
||||
glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &log_length);
|
||||
if ((GLboolean)status == GL_FALSE)
|
||||
fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile %s! With GLSL: %s\n", desc, bd->GlslVersionString);
|
||||
if (log_length > 1)
|
||||
{
|
||||
ImVector<char> buf;
|
||||
buf.resize((int)(log_length + 1));
|
||||
glGetShaderInfoLog(handle, log_length, nullptr, (GLchar*)buf.begin());
|
||||
fprintf(stderr, "%s\n", buf.begin());
|
||||
}
|
||||
return (GLboolean)status == GL_TRUE;
|
||||
}
|
||||
|
||||
// If you get an error please report on GitHub. You may try different GL context version or GLSL version.
|
||||
static bool CheckProgram(GLuint handle, const char* desc)
|
||||
{
|
||||
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
||||
GLint status = 0, log_length = 0;
|
||||
glGetProgramiv(handle, GL_LINK_STATUS, &status);
|
||||
glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &log_length);
|
||||
if ((GLboolean)status == GL_FALSE)
|
||||
fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to link %s! With GLSL %s\n", desc, bd->GlslVersionString);
|
||||
if (log_length > 1)
|
||||
{
|
||||
ImVector<char> buf;
|
||||
buf.resize((int)(log_length + 1));
|
||||
glGetProgramInfoLog(handle, log_length, nullptr, (GLchar*)buf.begin());
|
||||
fprintf(stderr, "%s\n", buf.begin());
|
||||
}
|
||||
return (GLboolean)status == GL_TRUE;
|
||||
}
|
||||
|
||||
bool ImGui_ImplOpenGL3_CreateDeviceObjects()
|
||||
{
|
||||
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
||||
|
||||
// Backup GL state
|
||||
GLint last_texture, last_array_buffer;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
||||
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
|
||||
#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
|
||||
GLint last_vertex_array;
|
||||
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
|
||||
#endif
|
||||
|
||||
// Parse GLSL version string
|
||||
int glsl_version = 130;
|
||||
sscanf(bd->GlslVersionString, "#version %d", &glsl_version);
|
||||
|
||||
const GLchar* vertex_shader_glsl_120 =
|
||||
"uniform mat4 ProjMtx;\n"
|
||||
"attribute vec2 Position;\n"
|
||||
"attribute vec2 UV;\n"
|
||||
"attribute vec4 Color;\n"
|
||||
"varying vec2 Frag_UV;\n"
|
||||
"varying vec4 Frag_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" Frag_UV = UV;\n"
|
||||
" Frag_Color = Color;\n"
|
||||
" gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
|
||||
"}\n";
|
||||
|
||||
const GLchar* vertex_shader_glsl_130 =
|
||||
"uniform mat4 ProjMtx;\n"
|
||||
"in vec2 Position;\n"
|
||||
"in vec2 UV;\n"
|
||||
"in vec4 Color;\n"
|
||||
"out vec2 Frag_UV;\n"
|
||||
"out vec4 Frag_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" Frag_UV = UV;\n"
|
||||
" Frag_Color = Color;\n"
|
||||
" gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
|
||||
"}\n";
|
||||
|
||||
const GLchar* vertex_shader_glsl_300_es =
|
||||
"precision highp float;\n"
|
||||
"layout (location = 0) in vec2 Position;\n"
|
||||
"layout (location = 1) in vec2 UV;\n"
|
||||
"layout (location = 2) in vec4 Color;\n"
|
||||
"uniform mat4 ProjMtx;\n"
|
||||
"out vec2 Frag_UV;\n"
|
||||
"out vec4 Frag_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" Frag_UV = UV;\n"
|
||||
" Frag_Color = Color;\n"
|
||||
" gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
|
||||
"}\n";
|
||||
|
||||
const GLchar* vertex_shader_glsl_410_core =
|
||||
"layout (location = 0) in vec2 Position;\n"
|
||||
"layout (location = 1) in vec2 UV;\n"
|
||||
"layout (location = 2) in vec4 Color;\n"
|
||||
"uniform mat4 ProjMtx;\n"
|
||||
"out vec2 Frag_UV;\n"
|
||||
"out vec4 Frag_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" Frag_UV = UV;\n"
|
||||
" Frag_Color = Color;\n"
|
||||
" gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
|
||||
"}\n";
|
||||
|
||||
const GLchar* fragment_shader_glsl_120 =
|
||||
"#ifdef GL_ES\n"
|
||||
" precision mediump float;\n"
|
||||
"#endif\n"
|
||||
"uniform sampler2D Texture;\n"
|
||||
"varying vec2 Frag_UV;\n"
|
||||
"varying vec4 Frag_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);\n"
|
||||
"}\n";
|
||||
|
||||
const GLchar* fragment_shader_glsl_130 =
|
||||
"uniform sampler2D Texture;\n"
|
||||
"in vec2 Frag_UV;\n"
|
||||
"in vec4 Frag_Color;\n"
|
||||
"out vec4 Out_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
|
||||
"}\n";
|
||||
|
||||
const GLchar* fragment_shader_glsl_300_es =
|
||||
"precision mediump float;\n"
|
||||
"uniform sampler2D Texture;\n"
|
||||
"in vec2 Frag_UV;\n"
|
||||
"in vec4 Frag_Color;\n"
|
||||
"layout (location = 0) out vec4 Out_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
|
||||
"}\n";
|
||||
|
||||
const GLchar* fragment_shader_glsl_410_core =
|
||||
"in vec2 Frag_UV;\n"
|
||||
"in vec4 Frag_Color;\n"
|
||||
"uniform sampler2D Texture;\n"
|
||||
"layout (location = 0) out vec4 Out_Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
|
||||
"}\n";
|
||||
|
||||
// Select shaders matching our GLSL versions
|
||||
const GLchar* vertex_shader = nullptr;
|
||||
const GLchar* fragment_shader = nullptr;
|
||||
if (glsl_version < 130)
|
||||
{
|
||||
vertex_shader = vertex_shader_glsl_120;
|
||||
fragment_shader = fragment_shader_glsl_120;
|
||||
}
|
||||
else if (glsl_version >= 410)
|
||||
{
|
||||
vertex_shader = vertex_shader_glsl_410_core;
|
||||
fragment_shader = fragment_shader_glsl_410_core;
|
||||
}
|
||||
else if (glsl_version == 300)
|
||||
{
|
||||
vertex_shader = vertex_shader_glsl_300_es;
|
||||
fragment_shader = fragment_shader_glsl_300_es;
|
||||
}
|
||||
else
|
||||
{
|
||||
vertex_shader = vertex_shader_glsl_130;
|
||||
fragment_shader = fragment_shader_glsl_130;
|
||||
}
|
||||
|
||||
// Create shaders
|
||||
const GLchar* vertex_shader_with_version[2] = { bd->GlslVersionString, vertex_shader };
|
||||
GLuint vert_handle = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vert_handle, 2, vertex_shader_with_version, nullptr);
|
||||
glCompileShader(vert_handle);
|
||||
CheckShader(vert_handle, "vertex shader");
|
||||
|
||||
const GLchar* fragment_shader_with_version[2] = { bd->GlslVersionString, fragment_shader };
|
||||
GLuint frag_handle = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(frag_handle, 2, fragment_shader_with_version, nullptr);
|
||||
glCompileShader(frag_handle);
|
||||
CheckShader(frag_handle, "fragment shader");
|
||||
|
||||
// Link
|
||||
bd->ShaderHandle = glCreateProgram();
|
||||
glAttachShader(bd->ShaderHandle, vert_handle);
|
||||
glAttachShader(bd->ShaderHandle, frag_handle);
|
||||
glLinkProgram(bd->ShaderHandle);
|
||||
CheckProgram(bd->ShaderHandle, "shader program");
|
||||
|
||||
glDetachShader(bd->ShaderHandle, vert_handle);
|
||||
glDetachShader(bd->ShaderHandle, frag_handle);
|
||||
glDeleteShader(vert_handle);
|
||||
glDeleteShader(frag_handle);
|
||||
|
||||
bd->AttribLocationTex = glGetUniformLocation(bd->ShaderHandle, "Texture");
|
||||
bd->AttribLocationProjMtx = glGetUniformLocation(bd->ShaderHandle, "ProjMtx");
|
||||
bd->AttribLocationVtxPos = (GLuint)glGetAttribLocation(bd->ShaderHandle, "Position");
|
||||
bd->AttribLocationVtxUV = (GLuint)glGetAttribLocation(bd->ShaderHandle, "UV");
|
||||
bd->AttribLocationVtxColor = (GLuint)glGetAttribLocation(bd->ShaderHandle, "Color");
|
||||
|
||||
// Create buffers
|
||||
glGenBuffers(1, &bd->VboHandle);
|
||||
glGenBuffers(1, &bd->ElementsHandle);
|
||||
|
||||
ImGui_ImplOpenGL3_CreateFontsTexture();
|
||||
|
||||
// Restore modified GL state
|
||||
glBindTexture(GL_TEXTURE_2D, last_texture);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
|
||||
#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
|
||||
glBindVertexArray(last_vertex_array);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplOpenGL3_DestroyDeviceObjects()
|
||||
{
|
||||
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
||||
if (bd->VboHandle) { glDeleteBuffers(1, &bd->VboHandle); bd->VboHandle = 0; }
|
||||
if (bd->ElementsHandle) { glDeleteBuffers(1, &bd->ElementsHandle); bd->ElementsHandle = 0; }
|
||||
if (bd->ShaderHandle) { glDeleteProgram(bd->ShaderHandle); bd->ShaderHandle = 0; }
|
||||
ImGui_ImplOpenGL3_DestroyFontsTexture();
|
||||
}
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
55
Framework/external/embree/tutorials/common/imgui/backends/imgui_impl_opengl3.h
vendored
Normal file
55
Framework/external/embree/tutorials/common/imgui/backends/imgui_impl_opengl3.h
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
// dear imgui: Renderer Backend for modern OpenGL with shaders / programmatic pipeline
|
||||
// - Desktop GL: 2.x 3.x 4.x
|
||||
// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0)
|
||||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [x] Renderer: Desktop GL only: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
// About GLSL version:
|
||||
// The 'glsl_version' initialization parameter should be nullptr (default) or a "#version XXX" string.
|
||||
// On computer platform the GLSL version default to "#version 130". On OpenGL ES 3 platform it defaults to "#version 300 es"
|
||||
// Only override if your GL version doesn't handle this GLSL version. See GLSL version table at the top of imgui_impl_opengl3.cpp.
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
|
||||
// Backend API
|
||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = nullptr);
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL3_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data);
|
||||
|
||||
// (Optional) Called by Init/NewFrame/Shutdown
|
||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateFontsTexture();
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyFontsTexture();
|
||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
|
||||
|
||||
// Specific OpenGL ES versions
|
||||
//#define IMGUI_IMPL_OPENGL_ES2 // Auto-detected on Emscripten
|
||||
//#define IMGUI_IMPL_OPENGL_ES3 // Auto-detected on iOS/Android
|
||||
|
||||
// You can explicitly select GLES2 or GLES3 API by using one of the '#define IMGUI_IMPL_OPENGL_LOADER_XXX' in imconfig.h or compiler command-line.
|
||||
#if !defined(IMGUI_IMPL_OPENGL_ES2) \
|
||||
&& !defined(IMGUI_IMPL_OPENGL_ES3)
|
||||
|
||||
// Try to detect GLES on matching platforms
|
||||
#if defined(__APPLE__)
|
||||
#include <TargetConditionals.h>
|
||||
#endif
|
||||
#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) || (defined(__ANDROID__))
|
||||
#define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es"
|
||||
#elif defined(__EMSCRIPTEN__) || defined(__amigaos4__)
|
||||
#define IMGUI_IMPL_OPENGL_ES2 // Emscripten -> GL ES 2, "#version 100"
|
||||
#else
|
||||
// Otherwise imgui_impl_opengl3_loader.h will be used.
|
||||
#endif
|
||||
|
||||
#endif
|
||||
794
Framework/external/embree/tutorials/common/imgui/backends/imgui_impl_opengl3_loader.h
vendored
Normal file
794
Framework/external/embree/tutorials/common/imgui/backends/imgui_impl_opengl3_loader.h
vendored
Normal file
|
|
@ -0,0 +1,794 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// About imgui_impl_opengl3_loader.h:
|
||||
//
|
||||
// We embed our own OpenGL loader to not require user to provide their own or to have to use ours,
|
||||
// which proved to be endless problems for users.
|
||||
// Our loader is custom-generated, based on gl3w but automatically filtered to only include
|
||||
// enums/functions that we use in our imgui_impl_opengl3.cpp source file in order to be small.
|
||||
//
|
||||
// YOU SHOULD NOT NEED TO INCLUDE/USE THIS DIRECTLY. THIS IS USED BY imgui_impl_opengl3.cpp ONLY.
|
||||
// THE REST OF YOUR APP SHOULD USE A DIFFERENT GL LOADER: ANY GL LOADER OF YOUR CHOICE.
|
||||
//
|
||||
// IF YOU GET BUILD ERRORS IN THIS FILE (commonly macro redefinitions or function redefinitions):
|
||||
// IT LIKELY MEANS THAT YOU ARE BUILDING 'imgui_impl_opengl3.cpp' OR INCUDING 'imgui_impl_opengl3_loader.h'
|
||||
// IN THE SAME COMPILATION UNIT AS ONE OF YOUR FILE WHICH IS USING A THIRD-PARTY OPENGL LOADER.
|
||||
// (e.g. COULD HAPPEN IF YOU ARE DOING A UNITY/JUMBO BUILD, OR INCLUDING .CPP FILES FROM OTHERS)
|
||||
// YOU SHOULD NOT BUILD BOTH IN THE SAME COMPILATION UNIT.
|
||||
// BUT IF YOU REALLY WANT TO, you can '#define IMGUI_IMPL_OPENGL_LOADER_CUSTOM' and imgui_impl_opengl3.cpp
|
||||
// WILL NOT BE USING OUR LOADER, AND INSTEAD EXPECT ANOTHER/YOUR LOADER TO BE AVAILABLE IN THE COMPILATION UNIT.
|
||||
//
|
||||
// Regenerate with:
|
||||
// python gl3w_gen.py --output ../imgui/backends/imgui_impl_opengl3_loader.h --ref ../imgui/backends/imgui_impl_opengl3.cpp ./extra_symbols.txt
|
||||
//
|
||||
// More info:
|
||||
// https://github.com/dearimgui/gl3w_stripped
|
||||
// https://github.com/ocornut/imgui/issues/4445
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* This file was generated with gl3w_gen.py, part of imgl3w
|
||||
* (hosted at https://github.com/dearimgui/gl3w_stripped)
|
||||
*
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __gl3w_h_
|
||||
#define __gl3w_h_
|
||||
|
||||
// Adapted from KHR/khrplatform.h to avoid including entire file.
|
||||
#ifndef __khrplatform_h_
|
||||
typedef float khronos_float_t;
|
||||
typedef signed char khronos_int8_t;
|
||||
typedef unsigned char khronos_uint8_t;
|
||||
typedef signed short int khronos_int16_t;
|
||||
typedef unsigned short int khronos_uint16_t;
|
||||
#ifdef _WIN64
|
||||
typedef signed long long int khronos_intptr_t;
|
||||
typedef signed long long int khronos_ssize_t;
|
||||
#else
|
||||
typedef signed long int khronos_intptr_t;
|
||||
typedef signed long int khronos_ssize_t;
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
typedef signed __int64 khronos_int64_t;
|
||||
typedef unsigned __int64 khronos_uint64_t;
|
||||
#elif (defined(__clang__) || defined(__GNUC__)) && (__cplusplus < 201100)
|
||||
#include <stdint.h>
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#else
|
||||
typedef signed long long khronos_int64_t;
|
||||
typedef unsigned long long khronos_uint64_t;
|
||||
#endif
|
||||
#endif // __khrplatform_h_
|
||||
|
||||
#ifndef __gl_glcorearb_h_
|
||||
#define __gl_glcorearb_h_ 1
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
** Copyright 2013-2020 The Khronos Group Inc.
|
||||
** SPDX-License-Identifier: MIT
|
||||
**
|
||||
** This header is generated from the Khronos OpenGL / OpenGL ES XML
|
||||
** API Registry. The current version of the Registry, generator scripts
|
||||
** used to make the header, and the header can be found at
|
||||
** https://github.com/KhronosGroup/OpenGL-Registry
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#ifndef APIENTRY
|
||||
#define APIENTRY
|
||||
#endif
|
||||
#ifndef APIENTRYP
|
||||
#define APIENTRYP APIENTRY *
|
||||
#endif
|
||||
#ifndef GLAPI
|
||||
#define GLAPI extern
|
||||
#endif
|
||||
/* glcorearb.h is for use with OpenGL core profile implementations.
|
||||
** It should should be placed in the same directory as gl.h and
|
||||
** included as <GL/glcorearb.h>.
|
||||
**
|
||||
** glcorearb.h includes only APIs in the latest OpenGL core profile
|
||||
** implementation together with APIs in newer ARB extensions which
|
||||
** can be supported by the core profile. It does not, and never will
|
||||
** include functionality removed from the core profile, such as
|
||||
** fixed-function vertex and fragment processing.
|
||||
**
|
||||
** Do not #include both <GL/glcorearb.h> and either of <GL/gl.h> or
|
||||
** <GL/glext.h> in the same source file.
|
||||
*/
|
||||
/* Generated C header for:
|
||||
* API: gl
|
||||
* Profile: core
|
||||
* Versions considered: .*
|
||||
* Versions emitted: .*
|
||||
* Default extensions included: glcore
|
||||
* Additional extensions included: _nomatch_^
|
||||
* Extensions removed: _nomatch_^
|
||||
*/
|
||||
#ifndef GL_VERSION_1_0
|
||||
typedef void GLvoid;
|
||||
typedef unsigned int GLenum;
|
||||
|
||||
typedef khronos_float_t GLfloat;
|
||||
typedef int GLint;
|
||||
typedef int GLsizei;
|
||||
typedef unsigned int GLbitfield;
|
||||
typedef double GLdouble;
|
||||
typedef unsigned int GLuint;
|
||||
typedef unsigned char GLboolean;
|
||||
typedef khronos_uint8_t GLubyte;
|
||||
#define GL_COLOR_BUFFER_BIT 0x00004000
|
||||
#define GL_FALSE 0
|
||||
#define GL_TRUE 1
|
||||
#define GL_TRIANGLES 0x0004
|
||||
#define GL_ONE 1
|
||||
#define GL_SRC_ALPHA 0x0302
|
||||
#define GL_ONE_MINUS_SRC_ALPHA 0x0303
|
||||
#define GL_FRONT_AND_BACK 0x0408
|
||||
#define GL_POLYGON_MODE 0x0B40
|
||||
#define GL_CULL_FACE 0x0B44
|
||||
#define GL_DEPTH_TEST 0x0B71
|
||||
#define GL_STENCIL_TEST 0x0B90
|
||||
#define GL_VIEWPORT 0x0BA2
|
||||
#define GL_BLEND 0x0BE2
|
||||
#define GL_SCISSOR_BOX 0x0C10
|
||||
#define GL_SCISSOR_TEST 0x0C11
|
||||
#define GL_UNPACK_ROW_LENGTH 0x0CF2
|
||||
#define GL_PACK_ALIGNMENT 0x0D05
|
||||
#define GL_TEXTURE_2D 0x0DE1
|
||||
#define GL_UNSIGNED_BYTE 0x1401
|
||||
#define GL_UNSIGNED_SHORT 0x1403
|
||||
#define GL_UNSIGNED_INT 0x1405
|
||||
#define GL_FLOAT 0x1406
|
||||
#define GL_RGBA 0x1908
|
||||
#define GL_FILL 0x1B02
|
||||
#define GL_VENDOR 0x1F00
|
||||
#define GL_RENDERER 0x1F01
|
||||
#define GL_VERSION 0x1F02
|
||||
#define GL_EXTENSIONS 0x1F03
|
||||
#define GL_LINEAR 0x2601
|
||||
#define GL_TEXTURE_MAG_FILTER 0x2800
|
||||
#define GL_TEXTURE_MIN_FILTER 0x2801
|
||||
typedef void (APIENTRYP PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode);
|
||||
typedef void (APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
|
||||
typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
|
||||
typedef void (APIENTRYP PFNGLCLEARPROC) (GLbitfield mask);
|
||||
typedef void (APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
||||
typedef void (APIENTRYP PFNGLDISABLEPROC) (GLenum cap);
|
||||
typedef void (APIENTRYP PFNGLENABLEPROC) (GLenum cap);
|
||||
typedef void (APIENTRYP PFNGLFLUSHPROC) (void);
|
||||
typedef void (APIENTRYP PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param);
|
||||
typedef void (APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
|
||||
typedef GLenum (APIENTRYP PFNGLGETERRORPROC) (void);
|
||||
typedef void (APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *data);
|
||||
typedef const GLubyte *(APIENTRYP PFNGLGETSTRINGPROC) (GLenum name);
|
||||
typedef GLboolean (APIENTRYP PFNGLISENABLEDPROC) (GLenum cap);
|
||||
typedef void (APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glPolygonMode (GLenum face, GLenum mode);
|
||||
GLAPI void APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
GLAPI void APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param);
|
||||
GLAPI void APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
|
||||
GLAPI void APIENTRY glClear (GLbitfield mask);
|
||||
GLAPI void APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
||||
GLAPI void APIENTRY glDisable (GLenum cap);
|
||||
GLAPI void APIENTRY glEnable (GLenum cap);
|
||||
GLAPI void APIENTRY glFlush (void);
|
||||
GLAPI void APIENTRY glPixelStorei (GLenum pname, GLint param);
|
||||
GLAPI void APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
|
||||
GLAPI GLenum APIENTRY glGetError (void);
|
||||
GLAPI void APIENTRY glGetIntegerv (GLenum pname, GLint *data);
|
||||
GLAPI const GLubyte *APIENTRY glGetString (GLenum name);
|
||||
GLAPI GLboolean APIENTRY glIsEnabled (GLenum cap);
|
||||
GLAPI void APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
#endif
|
||||
#endif /* GL_VERSION_1_0 */
|
||||
#ifndef GL_VERSION_1_1
|
||||
typedef khronos_float_t GLclampf;
|
||||
typedef double GLclampd;
|
||||
#define GL_TEXTURE_BINDING_2D 0x8069
|
||||
typedef void (APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices);
|
||||
typedef void (APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);
|
||||
typedef void (APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures);
|
||||
typedef void (APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices);
|
||||
GLAPI void APIENTRY glBindTexture (GLenum target, GLuint texture);
|
||||
GLAPI void APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures);
|
||||
GLAPI void APIENTRY glGenTextures (GLsizei n, GLuint *textures);
|
||||
#endif
|
||||
#endif /* GL_VERSION_1_1 */
|
||||
#ifndef GL_VERSION_1_3
|
||||
#define GL_TEXTURE0 0x84C0
|
||||
#define GL_ACTIVE_TEXTURE 0x84E0
|
||||
typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glActiveTexture (GLenum texture);
|
||||
#endif
|
||||
#endif /* GL_VERSION_1_3 */
|
||||
#ifndef GL_VERSION_1_4
|
||||
#define GL_BLEND_DST_RGB 0x80C8
|
||||
#define GL_BLEND_SRC_RGB 0x80C9
|
||||
#define GL_BLEND_DST_ALPHA 0x80CA
|
||||
#define GL_BLEND_SRC_ALPHA 0x80CB
|
||||
#define GL_FUNC_ADD 0x8006
|
||||
typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
|
||||
typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
|
||||
GLAPI void APIENTRY glBlendEquation (GLenum mode);
|
||||
#endif
|
||||
#endif /* GL_VERSION_1_4 */
|
||||
#ifndef GL_VERSION_1_5
|
||||
typedef khronos_ssize_t GLsizeiptr;
|
||||
typedef khronos_intptr_t GLintptr;
|
||||
#define GL_ARRAY_BUFFER 0x8892
|
||||
#define GL_ELEMENT_ARRAY_BUFFER 0x8893
|
||||
#define GL_ARRAY_BUFFER_BINDING 0x8894
|
||||
#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
|
||||
#define GL_STREAM_DRAW 0x88E0
|
||||
typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
|
||||
typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);
|
||||
typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
|
||||
typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
|
||||
typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glBindBuffer (GLenum target, GLuint buffer);
|
||||
GLAPI void APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers);
|
||||
GLAPI void APIENTRY glGenBuffers (GLsizei n, GLuint *buffers);
|
||||
GLAPI void APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
|
||||
GLAPI void APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
|
||||
#endif
|
||||
#endif /* GL_VERSION_1_5 */
|
||||
#ifndef GL_VERSION_2_0
|
||||
typedef char GLchar;
|
||||
typedef khronos_int16_t GLshort;
|
||||
typedef khronos_int8_t GLbyte;
|
||||
typedef khronos_uint16_t GLushort;
|
||||
#define GL_BLEND_EQUATION_RGB 0x8009
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
|
||||
#define GL_BLEND_EQUATION_ALPHA 0x883D
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
|
||||
#define GL_FRAGMENT_SHADER 0x8B30
|
||||
#define GL_VERTEX_SHADER 0x8B31
|
||||
#define GL_COMPILE_STATUS 0x8B81
|
||||
#define GL_LINK_STATUS 0x8B82
|
||||
#define GL_INFO_LOG_LENGTH 0x8B84
|
||||
#define GL_CURRENT_PROGRAM 0x8B8D
|
||||
#define GL_UPPER_LEFT 0x8CA2
|
||||
typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha);
|
||||
typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
|
||||
typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader);
|
||||
typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void);
|
||||
typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type);
|
||||
typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program);
|
||||
typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader);
|
||||
typedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader);
|
||||
typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index);
|
||||
typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
|
||||
typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name);
|
||||
typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params);
|
||||
typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
|
||||
typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
|
||||
typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
|
||||
typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name);
|
||||
typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params);
|
||||
typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer);
|
||||
typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);
|
||||
typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
|
||||
typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program);
|
||||
typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
|
||||
typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
|
||||
typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha);
|
||||
GLAPI void APIENTRY glAttachShader (GLuint program, GLuint shader);
|
||||
GLAPI void APIENTRY glCompileShader (GLuint shader);
|
||||
GLAPI GLuint APIENTRY glCreateProgram (void);
|
||||
GLAPI GLuint APIENTRY glCreateShader (GLenum type);
|
||||
GLAPI void APIENTRY glDeleteProgram (GLuint program);
|
||||
GLAPI void APIENTRY glDeleteShader (GLuint shader);
|
||||
GLAPI void APIENTRY glDetachShader (GLuint program, GLuint shader);
|
||||
GLAPI void APIENTRY glDisableVertexAttribArray (GLuint index);
|
||||
GLAPI void APIENTRY glEnableVertexAttribArray (GLuint index);
|
||||
GLAPI GLint APIENTRY glGetAttribLocation (GLuint program, const GLchar *name);
|
||||
GLAPI void APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params);
|
||||
GLAPI void APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
|
||||
GLAPI void APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params);
|
||||
GLAPI void APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
|
||||
GLAPI GLint APIENTRY glGetUniformLocation (GLuint program, const GLchar *name);
|
||||
GLAPI void APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params);
|
||||
GLAPI void APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer);
|
||||
GLAPI void APIENTRY glLinkProgram (GLuint program);
|
||||
GLAPI void APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
|
||||
GLAPI void APIENTRY glUseProgram (GLuint program);
|
||||
GLAPI void APIENTRY glUniform1i (GLint location, GLint v0);
|
||||
GLAPI void APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
|
||||
GLAPI void APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
|
||||
#endif
|
||||
#endif /* GL_VERSION_2_0 */
|
||||
#ifndef GL_VERSION_3_0
|
||||
typedef khronos_uint16_t GLhalf;
|
||||
#define GL_MAJOR_VERSION 0x821B
|
||||
#define GL_MINOR_VERSION 0x821C
|
||||
#define GL_NUM_EXTENSIONS 0x821D
|
||||
#define GL_FRAMEBUFFER_SRGB 0x8DB9
|
||||
#define GL_VERTEX_ARRAY_BINDING 0x85B5
|
||||
typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data);
|
||||
typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data);
|
||||
typedef const GLubyte *(APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index);
|
||||
typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array);
|
||||
typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays);
|
||||
typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI const GLubyte *APIENTRY glGetStringi (GLenum name, GLuint index);
|
||||
GLAPI void APIENTRY glBindVertexArray (GLuint array);
|
||||
GLAPI void APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays);
|
||||
GLAPI void APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays);
|
||||
#endif
|
||||
#endif /* GL_VERSION_3_0 */
|
||||
#ifndef GL_VERSION_3_1
|
||||
#define GL_VERSION_3_1 1
|
||||
#define GL_PRIMITIVE_RESTART 0x8F9D
|
||||
#endif /* GL_VERSION_3_1 */
|
||||
#ifndef GL_VERSION_3_2
|
||||
#define GL_VERSION_3_2 1
|
||||
typedef struct __GLsync *GLsync;
|
||||
typedef khronos_uint64_t GLuint64;
|
||||
typedef khronos_int64_t GLint64;
|
||||
typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
|
||||
typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
|
||||
#endif
|
||||
#endif /* GL_VERSION_3_2 */
|
||||
#ifndef GL_VERSION_3_3
|
||||
#define GL_VERSION_3_3 1
|
||||
#define GL_SAMPLER_BINDING 0x8919
|
||||
typedef void (APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glBindSampler (GLuint unit, GLuint sampler);
|
||||
#endif
|
||||
#endif /* GL_VERSION_3_3 */
|
||||
#ifndef GL_VERSION_4_1
|
||||
typedef void (APIENTRYP PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat *data);
|
||||
typedef void (APIENTRYP PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble *data);
|
||||
#endif /* GL_VERSION_4_1 */
|
||||
#ifndef GL_VERSION_4_3
|
||||
typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
|
||||
#endif /* GL_VERSION_4_3 */
|
||||
#ifndef GL_VERSION_4_5
|
||||
#define GL_CLIP_ORIGIN 0x935C
|
||||
typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKI_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint *param);
|
||||
typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKI64_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint64 *param);
|
||||
#endif /* GL_VERSION_4_5 */
|
||||
#ifndef GL_ARB_bindless_texture
|
||||
typedef khronos_uint64_t GLuint64EXT;
|
||||
#endif /* GL_ARB_bindless_texture */
|
||||
#ifndef GL_ARB_cl_event
|
||||
struct _cl_context;
|
||||
struct _cl_event;
|
||||
#endif /* GL_ARB_cl_event */
|
||||
#ifndef GL_ARB_clip_control
|
||||
#define GL_ARB_clip_control 1
|
||||
#endif /* GL_ARB_clip_control */
|
||||
#ifndef GL_ARB_debug_output
|
||||
typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
|
||||
#endif /* GL_ARB_debug_output */
|
||||
#ifndef GL_EXT_EGL_image_storage
|
||||
typedef void *GLeglImageOES;
|
||||
#endif /* GL_EXT_EGL_image_storage */
|
||||
#ifndef GL_EXT_direct_state_access
|
||||
typedef void (APIENTRYP PFNGLGETFLOATI_VEXTPROC) (GLenum pname, GLuint index, GLfloat *params);
|
||||
typedef void (APIENTRYP PFNGLGETDOUBLEI_VEXTPROC) (GLenum pname, GLuint index, GLdouble *params);
|
||||
typedef void (APIENTRYP PFNGLGETPOINTERI_VEXTPROC) (GLenum pname, GLuint index, void **params);
|
||||
typedef void (APIENTRYP PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint *param);
|
||||
typedef void (APIENTRYP PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, void **param);
|
||||
#endif /* GL_EXT_direct_state_access */
|
||||
#ifndef GL_NV_draw_vulkan_image
|
||||
typedef void (APIENTRY *GLVULKANPROCNV)(void);
|
||||
#endif /* GL_NV_draw_vulkan_image */
|
||||
#ifndef GL_NV_gpu_shader5
|
||||
typedef khronos_int64_t GLint64EXT;
|
||||
#endif /* GL_NV_gpu_shader5 */
|
||||
#ifndef GL_NV_vertex_buffer_unified_memory
|
||||
typedef void (APIENTRYP PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT *result);
|
||||
#endif /* GL_NV_vertex_buffer_unified_memory */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef GL3W_API
|
||||
#define GL3W_API
|
||||
#endif
|
||||
|
||||
#ifndef __gl_h_
|
||||
#define __gl_h_
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define GL3W_OK 0
|
||||
#define GL3W_ERROR_INIT -1
|
||||
#define GL3W_ERROR_LIBRARY_OPEN -2
|
||||
#define GL3W_ERROR_OPENGL_VERSION -3
|
||||
|
||||
typedef void (*GL3WglProc)(void);
|
||||
typedef GL3WglProc (*GL3WGetProcAddressProc)(const char *proc);
|
||||
|
||||
/* gl3w api */
|
||||
GL3W_API int imgl3wInit(void);
|
||||
GL3W_API int imgl3wInit2(GL3WGetProcAddressProc proc);
|
||||
GL3W_API int imgl3wIsSupported(int major, int minor);
|
||||
GL3W_API GL3WglProc imgl3wGetProcAddress(const char *proc);
|
||||
|
||||
/* gl3w internal state */
|
||||
union GL3WProcs {
|
||||
GL3WglProc ptr[58];
|
||||
struct {
|
||||
PFNGLACTIVETEXTUREPROC ActiveTexture;
|
||||
PFNGLATTACHSHADERPROC AttachShader;
|
||||
PFNGLBINDBUFFERPROC BindBuffer;
|
||||
PFNGLBINDSAMPLERPROC BindSampler;
|
||||
PFNGLBINDTEXTUREPROC BindTexture;
|
||||
PFNGLBINDVERTEXARRAYPROC BindVertexArray;
|
||||
PFNGLBLENDEQUATIONPROC BlendEquation;
|
||||
PFNGLBLENDEQUATIONSEPARATEPROC BlendEquationSeparate;
|
||||
PFNGLBLENDFUNCSEPARATEPROC BlendFuncSeparate;
|
||||
PFNGLBUFFERDATAPROC BufferData;
|
||||
PFNGLBUFFERSUBDATAPROC BufferSubData;
|
||||
PFNGLCLEARPROC Clear;
|
||||
PFNGLCLEARCOLORPROC ClearColor;
|
||||
PFNGLCOMPILESHADERPROC CompileShader;
|
||||
PFNGLCREATEPROGRAMPROC CreateProgram;
|
||||
PFNGLCREATESHADERPROC CreateShader;
|
||||
PFNGLDELETEBUFFERSPROC DeleteBuffers;
|
||||
PFNGLDELETEPROGRAMPROC DeleteProgram;
|
||||
PFNGLDELETESHADERPROC DeleteShader;
|
||||
PFNGLDELETETEXTURESPROC DeleteTextures;
|
||||
PFNGLDELETEVERTEXARRAYSPROC DeleteVertexArrays;
|
||||
PFNGLDETACHSHADERPROC DetachShader;
|
||||
PFNGLDISABLEPROC Disable;
|
||||
PFNGLDISABLEVERTEXATTRIBARRAYPROC DisableVertexAttribArray;
|
||||
PFNGLDRAWELEMENTSPROC DrawElements;
|
||||
PFNGLDRAWELEMENTSBASEVERTEXPROC DrawElementsBaseVertex;
|
||||
PFNGLENABLEPROC Enable;
|
||||
PFNGLENABLEVERTEXATTRIBARRAYPROC EnableVertexAttribArray;
|
||||
PFNGLFLUSHPROC Flush;
|
||||
PFNGLGENBUFFERSPROC GenBuffers;
|
||||
PFNGLGENTEXTURESPROC GenTextures;
|
||||
PFNGLGENVERTEXARRAYSPROC GenVertexArrays;
|
||||
PFNGLGETATTRIBLOCATIONPROC GetAttribLocation;
|
||||
PFNGLGETERRORPROC GetError;
|
||||
PFNGLGETINTEGERVPROC GetIntegerv;
|
||||
PFNGLGETPROGRAMINFOLOGPROC GetProgramInfoLog;
|
||||
PFNGLGETPROGRAMIVPROC GetProgramiv;
|
||||
PFNGLGETSHADERINFOLOGPROC GetShaderInfoLog;
|
||||
PFNGLGETSHADERIVPROC GetShaderiv;
|
||||
PFNGLGETSTRINGPROC GetString;
|
||||
PFNGLGETSTRINGIPROC GetStringi;
|
||||
PFNGLGETUNIFORMLOCATIONPROC GetUniformLocation;
|
||||
PFNGLGETVERTEXATTRIBPOINTERVPROC GetVertexAttribPointerv;
|
||||
PFNGLGETVERTEXATTRIBIVPROC GetVertexAttribiv;
|
||||
PFNGLISENABLEDPROC IsEnabled;
|
||||
PFNGLLINKPROGRAMPROC LinkProgram;
|
||||
PFNGLPIXELSTOREIPROC PixelStorei;
|
||||
PFNGLPOLYGONMODEPROC PolygonMode;
|
||||
PFNGLREADPIXELSPROC ReadPixels;
|
||||
PFNGLSCISSORPROC Scissor;
|
||||
PFNGLSHADERSOURCEPROC ShaderSource;
|
||||
PFNGLTEXIMAGE2DPROC TexImage2D;
|
||||
PFNGLTEXPARAMETERIPROC TexParameteri;
|
||||
PFNGLUNIFORM1IPROC Uniform1i;
|
||||
PFNGLUNIFORMMATRIX4FVPROC UniformMatrix4fv;
|
||||
PFNGLUSEPROGRAMPROC UseProgram;
|
||||
PFNGLVERTEXATTRIBPOINTERPROC VertexAttribPointer;
|
||||
PFNGLVIEWPORTPROC Viewport;
|
||||
} gl;
|
||||
};
|
||||
|
||||
GL3W_API extern union GL3WProcs imgl3wProcs;
|
||||
|
||||
/* OpenGL functions */
|
||||
#define glActiveTexture imgl3wProcs.gl.ActiveTexture
|
||||
#define glAttachShader imgl3wProcs.gl.AttachShader
|
||||
#define glBindBuffer imgl3wProcs.gl.BindBuffer
|
||||
#define glBindSampler imgl3wProcs.gl.BindSampler
|
||||
#define glBindTexture imgl3wProcs.gl.BindTexture
|
||||
#define glBindVertexArray imgl3wProcs.gl.BindVertexArray
|
||||
#define glBlendEquation imgl3wProcs.gl.BlendEquation
|
||||
#define glBlendEquationSeparate imgl3wProcs.gl.BlendEquationSeparate
|
||||
#define glBlendFuncSeparate imgl3wProcs.gl.BlendFuncSeparate
|
||||
#define glBufferData imgl3wProcs.gl.BufferData
|
||||
#define glBufferSubData imgl3wProcs.gl.BufferSubData
|
||||
#define glClear imgl3wProcs.gl.Clear
|
||||
#define glClearColor imgl3wProcs.gl.ClearColor
|
||||
#define glCompileShader imgl3wProcs.gl.CompileShader
|
||||
#define glCreateProgram imgl3wProcs.gl.CreateProgram
|
||||
#define glCreateShader imgl3wProcs.gl.CreateShader
|
||||
#define glDeleteBuffers imgl3wProcs.gl.DeleteBuffers
|
||||
#define glDeleteProgram imgl3wProcs.gl.DeleteProgram
|
||||
#define glDeleteShader imgl3wProcs.gl.DeleteShader
|
||||
#define glDeleteTextures imgl3wProcs.gl.DeleteTextures
|
||||
#define glDeleteVertexArrays imgl3wProcs.gl.DeleteVertexArrays
|
||||
#define glDetachShader imgl3wProcs.gl.DetachShader
|
||||
#define glDisable imgl3wProcs.gl.Disable
|
||||
#define glDisableVertexAttribArray imgl3wProcs.gl.DisableVertexAttribArray
|
||||
#define glDrawElements imgl3wProcs.gl.DrawElements
|
||||
#define glDrawElementsBaseVertex imgl3wProcs.gl.DrawElementsBaseVertex
|
||||
#define glEnable imgl3wProcs.gl.Enable
|
||||
#define glEnableVertexAttribArray imgl3wProcs.gl.EnableVertexAttribArray
|
||||
#define glFlush imgl3wProcs.gl.Flush
|
||||
#define glGenBuffers imgl3wProcs.gl.GenBuffers
|
||||
#define glGenTextures imgl3wProcs.gl.GenTextures
|
||||
#define glGenVertexArrays imgl3wProcs.gl.GenVertexArrays
|
||||
#define glGetAttribLocation imgl3wProcs.gl.GetAttribLocation
|
||||
#define glGetError imgl3wProcs.gl.GetError
|
||||
#define glGetIntegerv imgl3wProcs.gl.GetIntegerv
|
||||
#define glGetProgramInfoLog imgl3wProcs.gl.GetProgramInfoLog
|
||||
#define glGetProgramiv imgl3wProcs.gl.GetProgramiv
|
||||
#define glGetShaderInfoLog imgl3wProcs.gl.GetShaderInfoLog
|
||||
#define glGetShaderiv imgl3wProcs.gl.GetShaderiv
|
||||
#define glGetString imgl3wProcs.gl.GetString
|
||||
#define glGetStringi imgl3wProcs.gl.GetStringi
|
||||
#define glGetUniformLocation imgl3wProcs.gl.GetUniformLocation
|
||||
#define glGetVertexAttribPointerv imgl3wProcs.gl.GetVertexAttribPointerv
|
||||
#define glGetVertexAttribiv imgl3wProcs.gl.GetVertexAttribiv
|
||||
#define glIsEnabled imgl3wProcs.gl.IsEnabled
|
||||
#define glLinkProgram imgl3wProcs.gl.LinkProgram
|
||||
#define glPixelStorei imgl3wProcs.gl.PixelStorei
|
||||
#define glPolygonMode imgl3wProcs.gl.PolygonMode
|
||||
#define glReadPixels imgl3wProcs.gl.ReadPixels
|
||||
#define glScissor imgl3wProcs.gl.Scissor
|
||||
#define glShaderSource imgl3wProcs.gl.ShaderSource
|
||||
#define glTexImage2D imgl3wProcs.gl.TexImage2D
|
||||
#define glTexParameteri imgl3wProcs.gl.TexParameteri
|
||||
#define glUniform1i imgl3wProcs.gl.Uniform1i
|
||||
#define glUniformMatrix4fv imgl3wProcs.gl.UniformMatrix4fv
|
||||
#define glUseProgram imgl3wProcs.gl.UseProgram
|
||||
#define glVertexAttribPointer imgl3wProcs.gl.VertexAttribPointer
|
||||
#define glViewport imgl3wProcs.gl.Viewport
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef IMGL3W_IMPL
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
#if defined(_WIN32)
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
static HMODULE libgl;
|
||||
typedef PROC(__stdcall* GL3WglGetProcAddr)(LPCSTR);
|
||||
static GL3WglGetProcAddr wgl_get_proc_address;
|
||||
|
||||
static int open_libgl(void)
|
||||
{
|
||||
libgl = LoadLibraryExA("opengl32.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (!libgl)
|
||||
return GL3W_ERROR_LIBRARY_OPEN;
|
||||
wgl_get_proc_address = (GL3WglGetProcAddr)GetProcAddress(libgl, "wglGetProcAddress");
|
||||
return GL3W_OK;
|
||||
}
|
||||
|
||||
static void close_libgl(void) { FreeLibrary(libgl); }
|
||||
static GL3WglProc get_proc(const char *proc)
|
||||
{
|
||||
GL3WglProc res;
|
||||
res = (GL3WglProc)wgl_get_proc_address(proc);
|
||||
if (!res)
|
||||
res = (GL3WglProc)GetProcAddress(libgl, proc);
|
||||
return res;
|
||||
}
|
||||
#elif defined(__APPLE__)
|
||||
#include <dlfcn.h>
|
||||
|
||||
static void *libgl;
|
||||
static int open_libgl(void)
|
||||
{
|
||||
libgl = dlopen("/System/Library/Frameworks/OpenGL.framework/OpenGL", RTLD_LAZY | RTLD_LOCAL);
|
||||
if (!libgl)
|
||||
return GL3W_ERROR_LIBRARY_OPEN;
|
||||
return GL3W_OK;
|
||||
}
|
||||
|
||||
static void close_libgl(void) { dlclose(libgl); }
|
||||
|
||||
static GL3WglProc get_proc(const char *proc)
|
||||
{
|
||||
GL3WglProc res;
|
||||
*(void **)(&res) = dlsym(libgl, proc);
|
||||
return res;
|
||||
}
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
|
||||
static void *libgl;
|
||||
static GL3WglProc (*glx_get_proc_address)(const GLubyte *);
|
||||
|
||||
static int open_libgl(void)
|
||||
{
|
||||
libgl = dlopen("libGL.so.1", RTLD_LAZY | RTLD_LOCAL);
|
||||
if (!libgl)
|
||||
return GL3W_ERROR_LIBRARY_OPEN;
|
||||
*(void **)(&glx_get_proc_address) = dlsym(libgl, "glXGetProcAddressARB");
|
||||
return GL3W_OK;
|
||||
}
|
||||
|
||||
static void close_libgl(void) { dlclose(libgl); }
|
||||
|
||||
static GL3WglProc get_proc(const char *proc)
|
||||
{
|
||||
GL3WglProc res;
|
||||
res = glx_get_proc_address((const GLubyte *)proc);
|
||||
if (!res)
|
||||
*(void **)(&res) = dlsym(libgl, proc);
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct { int major, minor; } version;
|
||||
|
||||
static int parse_version(void)
|
||||
{
|
||||
if (!glGetIntegerv)
|
||||
return GL3W_ERROR_INIT;
|
||||
glGetIntegerv(GL_MAJOR_VERSION, &version.major);
|
||||
glGetIntegerv(GL_MINOR_VERSION, &version.minor);
|
||||
if (version.major < 3)
|
||||
return GL3W_ERROR_OPENGL_VERSION;
|
||||
return GL3W_OK;
|
||||
}
|
||||
|
||||
static void load_procs(GL3WGetProcAddressProc proc);
|
||||
|
||||
int imgl3wInit(void)
|
||||
{
|
||||
int res = open_libgl();
|
||||
if (res)
|
||||
return res;
|
||||
atexit(close_libgl);
|
||||
return imgl3wInit2(get_proc);
|
||||
}
|
||||
|
||||
int imgl3wInit2(GL3WGetProcAddressProc proc)
|
||||
{
|
||||
load_procs(proc);
|
||||
return parse_version();
|
||||
}
|
||||
|
||||
int imgl3wIsSupported(int major, int minor)
|
||||
{
|
||||
if (major < 3)
|
||||
return 0;
|
||||
if (version.major == major)
|
||||
return version.minor >= minor;
|
||||
return version.major >= major;
|
||||
}
|
||||
|
||||
GL3WglProc imgl3wGetProcAddress(const char *proc) { return get_proc(proc); }
|
||||
|
||||
static const char *proc_names[] = {
|
||||
"glActiveTexture",
|
||||
"glAttachShader",
|
||||
"glBindBuffer",
|
||||
"glBindSampler",
|
||||
"glBindTexture",
|
||||
"glBindVertexArray",
|
||||
"glBlendEquation",
|
||||
"glBlendEquationSeparate",
|
||||
"glBlendFuncSeparate",
|
||||
"glBufferData",
|
||||
"glBufferSubData",
|
||||
"glClear",
|
||||
"glClearColor",
|
||||
"glCompileShader",
|
||||
"glCreateProgram",
|
||||
"glCreateShader",
|
||||
"glDeleteBuffers",
|
||||
"glDeleteProgram",
|
||||
"glDeleteShader",
|
||||
"glDeleteTextures",
|
||||
"glDeleteVertexArrays",
|
||||
"glDetachShader",
|
||||
"glDisable",
|
||||
"glDisableVertexAttribArray",
|
||||
"glDrawElements",
|
||||
"glDrawElementsBaseVertex",
|
||||
"glEnable",
|
||||
"glEnableVertexAttribArray",
|
||||
"glFlush",
|
||||
"glGenBuffers",
|
||||
"glGenTextures",
|
||||
"glGenVertexArrays",
|
||||
"glGetAttribLocation",
|
||||
"glGetError",
|
||||
"glGetIntegerv",
|
||||
"glGetProgramInfoLog",
|
||||
"glGetProgramiv",
|
||||
"glGetShaderInfoLog",
|
||||
"glGetShaderiv",
|
||||
"glGetString",
|
||||
"glGetStringi",
|
||||
"glGetUniformLocation",
|
||||
"glGetVertexAttribPointerv",
|
||||
"glGetVertexAttribiv",
|
||||
"glIsEnabled",
|
||||
"glLinkProgram",
|
||||
"glPixelStorei",
|
||||
"glPolygonMode",
|
||||
"glReadPixels",
|
||||
"glScissor",
|
||||
"glShaderSource",
|
||||
"glTexImage2D",
|
||||
"glTexParameteri",
|
||||
"glUniform1i",
|
||||
"glUniformMatrix4fv",
|
||||
"glUseProgram",
|
||||
"glVertexAttribPointer",
|
||||
"glViewport",
|
||||
};
|
||||
|
||||
GL3W_API union GL3WProcs imgl3wProcs;
|
||||
|
||||
static void load_procs(GL3WGetProcAddressProc proc)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < ARRAY_SIZE(proc_names); i++)
|
||||
imgl3wProcs.ptr[i] = proc(proc_names[i]);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
120
Framework/external/embree/tutorials/common/imgui/imconfig.h
vendored
Normal file
120
Framework/external/embree/tutorials/common/imgui/imconfig.h
vendored
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// COMPILE-TIME OPTIONS FOR DEAR IMGUI
|
||||
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
|
||||
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
// A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/rebased branch with your modifications to it)
|
||||
// B) or '#define IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add directives in your own file without touching this template.
|
||||
//-----------------------------------------------------------------------------
|
||||
// You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp
|
||||
// files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
|
||||
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
|
||||
// Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
//---- Define assertion handler. Defaults to calling assert().
|
||||
// If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement.
|
||||
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
|
||||
//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
|
||||
|
||||
//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows
|
||||
// Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility.
|
||||
// DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions()
|
||||
// for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details.
|
||||
//#define IMGUI_API __declspec( dllexport )
|
||||
//#define IMGUI_API __declspec( dllimport )
|
||||
|
||||
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names.
|
||||
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
//#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87: disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This will be folded into IMGUI_DISABLE_OBSOLETE_FUNCTIONS in a few versions.
|
||||
|
||||
//---- Disable all of Dear ImGui or don't implement standard windows/tools.
|
||||
// It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp.
|
||||
//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
|
||||
//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty.
|
||||
//#define IMGUI_DISABLE_DEBUG_TOOLS // Disable metrics/debugger and other debug tools: ShowMetricsWindow(), ShowDebugLogWindow() and ShowStackToolWindow() will be empty (this was called IMGUI_DISABLE_METRICS_WINDOW before 1.88).
|
||||
|
||||
//---- Don't implement some functions to reduce linkage requirements.
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a)
|
||||
//#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW)
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a)
|
||||
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime).
|
||||
//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default).
|
||||
//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf)
|
||||
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
|
||||
//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
|
||||
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
|
||||
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
|
||||
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
|
||||
|
||||
//---- Include imgui_user.h at the end of imgui.h as a convenience
|
||||
//#define IMGUI_INCLUDE_IMGUI_USER_H
|
||||
|
||||
//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
|
||||
//#define IMGUI_USE_BGRA_PACKED_COLOR
|
||||
|
||||
//---- Use 32-bit for ImWchar (default is 16-bit) to support unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
|
||||
//#define IMGUI_USE_WCHAR32
|
||||
|
||||
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
|
||||
// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
|
||||
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
|
||||
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
|
||||
//#define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if enabled
|
||||
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
|
||||
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
|
||||
|
||||
//---- Use stb_sprintf.h for a faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
|
||||
// Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by stb_sprintf.h.
|
||||
//#define IMGUI_USE_STB_SPRINTF
|
||||
|
||||
//---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
|
||||
// Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided).
|
||||
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
|
||||
//#define IMGUI_ENABLE_FREETYPE
|
||||
|
||||
//---- Use stb_truetype to build and rasterize the font atlas (default)
|
||||
// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
|
||||
//#define IMGUI_ENABLE_STB_TRUETYPE
|
||||
|
||||
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
|
||||
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
|
||||
/*
|
||||
#define IM_VEC2_CLASS_EXTRA \
|
||||
constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \
|
||||
operator MyVec2() const { return MyVec2(x,y); }
|
||||
|
||||
#define IM_VEC4_CLASS_EXTRA \
|
||||
constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \
|
||||
operator MyVec4() const { return MyVec4(x,y,z,w); }
|
||||
*/
|
||||
|
||||
//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
|
||||
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
|
||||
// Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
|
||||
// Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
|
||||
//#define ImDrawIdx unsigned int
|
||||
|
||||
//---- Override ImDrawCallback signature (will need to modify renderer backends accordingly)
|
||||
//struct ImDrawList;
|
||||
//struct ImDrawCmd;
|
||||
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
|
||||
//#define ImDrawCallback MyImDrawCallback
|
||||
|
||||
//---- Debug Tools: Macro to break in Debugger
|
||||
// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
|
||||
//#define IM_DEBUG_BREAK IM_ASSERT(0)
|
||||
//#define IM_DEBUG_BREAK __debugbreak()
|
||||
|
||||
//---- Debug Tools: Enable slower asserts
|
||||
//#define IMGUI_DEBUG_PARANOID
|
||||
|
||||
//---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
|
||||
/*
|
||||
namespace ImGui
|
||||
{
|
||||
void MyFunction(const char* name, const MyMatrix44& v);
|
||||
}
|
||||
*/
|
||||
14238
Framework/external/embree/tutorials/common/imgui/imgui.cpp
vendored
Normal file
14238
Framework/external/embree/tutorials/common/imgui/imgui.cpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
3078
Framework/external/embree/tutorials/common/imgui/imgui.h
vendored
Normal file
3078
Framework/external/embree/tutorials/common/imgui/imgui.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
4167
Framework/external/embree/tutorials/common/imgui/imgui_draw.cpp
vendored
Normal file
4167
Framework/external/embree/tutorials/common/imgui/imgui_draw.cpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
3228
Framework/external/embree/tutorials/common/imgui/imgui_internal.h
vendored
Normal file
3228
Framework/external/embree/tutorials/common/imgui/imgui_internal.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
4084
Framework/external/embree/tutorials/common/imgui/imgui_tables.cpp
vendored
Normal file
4084
Framework/external/embree/tutorials/common/imgui/imgui_tables.cpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
8416
Framework/external/embree/tutorials/common/imgui/imgui_widgets.cpp
vendored
Normal file
8416
Framework/external/embree/tutorials/common/imgui/imgui_widgets.cpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
627
Framework/external/embree/tutorials/common/imgui/imstb_rectpack.h
vendored
Normal file
627
Framework/external/embree/tutorials/common/imgui/imstb_rectpack.h
vendored
Normal file
|
|
@ -0,0 +1,627 @@
|
|||
// [DEAR IMGUI]
|
||||
// This is a slightly modified version of stb_rect_pack.h 1.01.
|
||||
// Grep for [DEAR IMGUI] to find the changes.
|
||||
//
|
||||
// stb_rect_pack.h - v1.01 - public domain - rectangle packing
|
||||
// Sean Barrett 2014
|
||||
//
|
||||
// Useful for e.g. packing rectangular textures into an atlas.
|
||||
// Does not do rotation.
|
||||
//
|
||||
// Before #including,
|
||||
//
|
||||
// #define STB_RECT_PACK_IMPLEMENTATION
|
||||
//
|
||||
// in the file that you want to have the implementation.
|
||||
//
|
||||
// Not necessarily the awesomest packing method, but better than
|
||||
// the totally naive one in stb_truetype (which is primarily what
|
||||
// this is meant to replace).
|
||||
//
|
||||
// Has only had a few tests run, may have issues.
|
||||
//
|
||||
// More docs to come.
|
||||
//
|
||||
// No memory allocations; uses qsort() and assert() from stdlib.
|
||||
// Can override those by defining STBRP_SORT and STBRP_ASSERT.
|
||||
//
|
||||
// This library currently uses the Skyline Bottom-Left algorithm.
|
||||
//
|
||||
// Please note: better rectangle packers are welcome! Please
|
||||
// implement them to the same API, but with a different init
|
||||
// function.
|
||||
//
|
||||
// Credits
|
||||
//
|
||||
// Library
|
||||
// Sean Barrett
|
||||
// Minor features
|
||||
// Martins Mozeiko
|
||||
// github:IntellectualKitty
|
||||
//
|
||||
// Bugfixes / warning fixes
|
||||
// Jeremy Jaussaud
|
||||
// Fabian Giesen
|
||||
//
|
||||
// Version history:
|
||||
//
|
||||
// 1.01 (2021-07-11) always use large rect mode, expose STBRP__MAXVAL in public section
|
||||
// 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles
|
||||
// 0.99 (2019-02-07) warning fixes
|
||||
// 0.11 (2017-03-03) return packing success/fail result
|
||||
// 0.10 (2016-10-25) remove cast-away-const to avoid warnings
|
||||
// 0.09 (2016-08-27) fix compiler warnings
|
||||
// 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0)
|
||||
// 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0)
|
||||
// 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
|
||||
// 0.05: added STBRP_ASSERT to allow replacing assert
|
||||
// 0.04: fixed minor bug in STBRP_LARGE_RECTS support
|
||||
// 0.01: initial release
|
||||
//
|
||||
// LICENSE
|
||||
//
|
||||
// See end of file for license information.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// INCLUDE SECTION
|
||||
//
|
||||
|
||||
#ifndef STB_INCLUDE_STB_RECT_PACK_H
|
||||
#define STB_INCLUDE_STB_RECT_PACK_H
|
||||
|
||||
#define STB_RECT_PACK_VERSION 1
|
||||
|
||||
#ifdef STBRP_STATIC
|
||||
#define STBRP_DEF static
|
||||
#else
|
||||
#define STBRP_DEF extern
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct stbrp_context stbrp_context;
|
||||
typedef struct stbrp_node stbrp_node;
|
||||
typedef struct stbrp_rect stbrp_rect;
|
||||
|
||||
typedef int stbrp_coord;
|
||||
|
||||
#define STBRP__MAXVAL 0x7fffffff
|
||||
// Mostly for internal use, but this is the maximum supported coordinate value.
|
||||
|
||||
STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
|
||||
// Assign packed locations to rectangles. The rectangles are of type
|
||||
// 'stbrp_rect' defined below, stored in the array 'rects', and there
|
||||
// are 'num_rects' many of them.
|
||||
//
|
||||
// Rectangles which are successfully packed have the 'was_packed' flag
|
||||
// set to a non-zero value and 'x' and 'y' store the minimum location
|
||||
// on each axis (i.e. bottom-left in cartesian coordinates, top-left
|
||||
// if you imagine y increasing downwards). Rectangles which do not fit
|
||||
// have the 'was_packed' flag set to 0.
|
||||
//
|
||||
// You should not try to access the 'rects' array from another thread
|
||||
// while this function is running, as the function temporarily reorders
|
||||
// the array while it executes.
|
||||
//
|
||||
// To pack into another rectangle, you need to call stbrp_init_target
|
||||
// again. To continue packing into the same rectangle, you can call
|
||||
// this function again. Calling this multiple times with multiple rect
|
||||
// arrays will probably produce worse packing results than calling it
|
||||
// a single time with the full rectangle array, but the option is
|
||||
// available.
|
||||
//
|
||||
// The function returns 1 if all of the rectangles were successfully
|
||||
// packed and 0 otherwise.
|
||||
|
||||
struct stbrp_rect
|
||||
{
|
||||
// reserved for your use:
|
||||
int id;
|
||||
|
||||
// input:
|
||||
stbrp_coord w, h;
|
||||
|
||||
// output:
|
||||
stbrp_coord x, y;
|
||||
int was_packed; // non-zero if valid packing
|
||||
|
||||
}; // 16 bytes, nominally
|
||||
|
||||
|
||||
STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
|
||||
// Initialize a rectangle packer to:
|
||||
// pack a rectangle that is 'width' by 'height' in dimensions
|
||||
// using temporary storage provided by the array 'nodes', which is 'num_nodes' long
|
||||
//
|
||||
// You must call this function every time you start packing into a new target.
|
||||
//
|
||||
// There is no "shutdown" function. The 'nodes' memory must stay valid for
|
||||
// the following stbrp_pack_rects() call (or calls), but can be freed after
|
||||
// the call (or calls) finish.
|
||||
//
|
||||
// Note: to guarantee best results, either:
|
||||
// 1. make sure 'num_nodes' >= 'width'
|
||||
// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
|
||||
//
|
||||
// If you don't do either of the above things, widths will be quantized to multiples
|
||||
// of small integers to guarantee the algorithm doesn't run out of temporary storage.
|
||||
//
|
||||
// If you do #2, then the non-quantized algorithm will be used, but the algorithm
|
||||
// may run out of temporary storage and be unable to pack some rectangles.
|
||||
|
||||
STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
|
||||
// Optionally call this function after init but before doing any packing to
|
||||
// change the handling of the out-of-temp-memory scenario, described above.
|
||||
// If you call init again, this will be reset to the default (false).
|
||||
|
||||
|
||||
STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
|
||||
// Optionally select which packing heuristic the library should use. Different
|
||||
// heuristics will produce better/worse results for different data sets.
|
||||
// If you call init again, this will be reset to the default.
|
||||
|
||||
enum
|
||||
{
|
||||
STBRP_HEURISTIC_Skyline_default=0,
|
||||
STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
|
||||
STBRP_HEURISTIC_Skyline_BF_sortHeight
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// the details of the following structures don't matter to you, but they must
|
||||
// be visible so you can handle the memory allocations for them
|
||||
|
||||
struct stbrp_node
|
||||
{
|
||||
stbrp_coord x,y;
|
||||
stbrp_node *next;
|
||||
};
|
||||
|
||||
struct stbrp_context
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
int align;
|
||||
int init_mode;
|
||||
int heuristic;
|
||||
int num_nodes;
|
||||
stbrp_node *active_head;
|
||||
stbrp_node *free_head;
|
||||
stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPLEMENTATION SECTION
|
||||
//
|
||||
|
||||
#ifdef STB_RECT_PACK_IMPLEMENTATION
|
||||
#ifndef STBRP_SORT
|
||||
#include <stdlib.h>
|
||||
#define STBRP_SORT qsort
|
||||
#endif
|
||||
|
||||
#ifndef STBRP_ASSERT
|
||||
#include <assert.h>
|
||||
#define STBRP_ASSERT assert
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define STBRP__NOTUSED(v) (void)(v)
|
||||
#define STBRP__CDECL __cdecl
|
||||
#else
|
||||
#define STBRP__NOTUSED(v) (void)sizeof(v)
|
||||
#define STBRP__CDECL
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
STBRP__INIT_skyline = 1
|
||||
};
|
||||
|
||||
STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
|
||||
{
|
||||
switch (context->init_mode) {
|
||||
case STBRP__INIT_skyline:
|
||||
STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
|
||||
context->heuristic = heuristic;
|
||||
break;
|
||||
default:
|
||||
STBRP_ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
|
||||
{
|
||||
if (allow_out_of_mem)
|
||||
// if it's ok to run out of memory, then don't bother aligning them;
|
||||
// this gives better packing, but may fail due to OOM (even though
|
||||
// the rectangles easily fit). @TODO a smarter approach would be to only
|
||||
// quantize once we've hit OOM, then we could get rid of this parameter.
|
||||
context->align = 1;
|
||||
else {
|
||||
// if it's not ok to run out of memory, then quantize the widths
|
||||
// so that num_nodes is always enough nodes.
|
||||
//
|
||||
// I.e. num_nodes * align >= width
|
||||
// align >= width / num_nodes
|
||||
// align = ceil(width/num_nodes)
|
||||
|
||||
context->align = (context->width + context->num_nodes-1) / context->num_nodes;
|
||||
}
|
||||
}
|
||||
|
||||
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < num_nodes-1; ++i)
|
||||
nodes[i].next = &nodes[i+1];
|
||||
nodes[i].next = NULL;
|
||||
context->init_mode = STBRP__INIT_skyline;
|
||||
context->heuristic = STBRP_HEURISTIC_Skyline_default;
|
||||
context->free_head = &nodes[0];
|
||||
context->active_head = &context->extra[0];
|
||||
context->width = width;
|
||||
context->height = height;
|
||||
context->num_nodes = num_nodes;
|
||||
stbrp_setup_allow_out_of_mem(context, 0);
|
||||
|
||||
// node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly)
|
||||
context->extra[0].x = 0;
|
||||
context->extra[0].y = 0;
|
||||
context->extra[0].next = &context->extra[1];
|
||||
context->extra[1].x = (stbrp_coord) width;
|
||||
context->extra[1].y = (1<<30);
|
||||
context->extra[1].next = NULL;
|
||||
}
|
||||
|
||||
// find minimum y position if it starts at x1
|
||||
static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste)
|
||||
{
|
||||
stbrp_node *node = first;
|
||||
int x1 = x0 + width;
|
||||
int min_y, visited_width, waste_area;
|
||||
|
||||
STBRP__NOTUSED(c);
|
||||
|
||||
STBRP_ASSERT(first->x <= x0);
|
||||
|
||||
#if 0
|
||||
// skip in case we're past the node
|
||||
while (node->next->x <= x0)
|
||||
++node;
|
||||
#else
|
||||
STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency
|
||||
#endif
|
||||
|
||||
STBRP_ASSERT(node->x <= x0);
|
||||
|
||||
min_y = 0;
|
||||
waste_area = 0;
|
||||
visited_width = 0;
|
||||
while (node->x < x1) {
|
||||
if (node->y > min_y) {
|
||||
// raise min_y higher.
|
||||
// we've accounted for all waste up to min_y,
|
||||
// but we'll now add more waste for everything we've visted
|
||||
waste_area += visited_width * (node->y - min_y);
|
||||
min_y = node->y;
|
||||
// the first time through, visited_width might be reduced
|
||||
if (node->x < x0)
|
||||
visited_width += node->next->x - x0;
|
||||
else
|
||||
visited_width += node->next->x - node->x;
|
||||
} else {
|
||||
// add waste area
|
||||
int under_width = node->next->x - node->x;
|
||||
if (under_width + visited_width > width)
|
||||
under_width = width - visited_width;
|
||||
waste_area += under_width * (min_y - node->y);
|
||||
visited_width += under_width;
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
*pwaste = waste_area;
|
||||
return min_y;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x,y;
|
||||
stbrp_node **prev_link;
|
||||
} stbrp__findresult;
|
||||
|
||||
static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height)
|
||||
{
|
||||
int best_waste = (1<<30), best_x, best_y = (1 << 30);
|
||||
stbrp__findresult fr;
|
||||
stbrp_node **prev, *node, *tail, **best = NULL;
|
||||
|
||||
// align to multiple of c->align
|
||||
width = (width + c->align - 1);
|
||||
width -= width % c->align;
|
||||
STBRP_ASSERT(width % c->align == 0);
|
||||
|
||||
// if it can't possibly fit, bail immediately
|
||||
if (width > c->width || height > c->height) {
|
||||
fr.prev_link = NULL;
|
||||
fr.x = fr.y = 0;
|
||||
return fr;
|
||||
}
|
||||
|
||||
node = c->active_head;
|
||||
prev = &c->active_head;
|
||||
while (node->x + width <= c->width) {
|
||||
int y,waste;
|
||||
y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
|
||||
if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL
|
||||
// bottom left
|
||||
if (y < best_y) {
|
||||
best_y = y;
|
||||
best = prev;
|
||||
}
|
||||
} else {
|
||||
// best-fit
|
||||
if (y + height <= c->height) {
|
||||
// can only use it if it first vertically
|
||||
if (y < best_y || (y == best_y && waste < best_waste)) {
|
||||
best_y = y;
|
||||
best_waste = waste;
|
||||
best = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
prev = &node->next;
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
best_x = (best == NULL) ? 0 : (*best)->x;
|
||||
|
||||
// if doing best-fit (BF), we also have to try aligning right edge to each node position
|
||||
//
|
||||
// e.g, if fitting
|
||||
//
|
||||
// ____________________
|
||||
// |____________________|
|
||||
//
|
||||
// into
|
||||
//
|
||||
// | |
|
||||
// | ____________|
|
||||
// |____________|
|
||||
//
|
||||
// then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned
|
||||
//
|
||||
// This makes BF take about 2x the time
|
||||
|
||||
if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
|
||||
tail = c->active_head;
|
||||
node = c->active_head;
|
||||
prev = &c->active_head;
|
||||
// find first node that's admissible
|
||||
while (tail->x < width)
|
||||
tail = tail->next;
|
||||
while (tail) {
|
||||
int xpos = tail->x - width;
|
||||
int y,waste;
|
||||
STBRP_ASSERT(xpos >= 0);
|
||||
// find the left position that matches this
|
||||
while (node->next->x <= xpos) {
|
||||
prev = &node->next;
|
||||
node = node->next;
|
||||
}
|
||||
STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
|
||||
y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
|
||||
if (y + height <= c->height) {
|
||||
if (y <= best_y) {
|
||||
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
|
||||
best_x = xpos;
|
||||
//STBRP_ASSERT(y <= best_y); [DEAR IMGUI]
|
||||
best_y = y;
|
||||
best_waste = waste;
|
||||
best = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
tail = tail->next;
|
||||
}
|
||||
}
|
||||
|
||||
fr.prev_link = best;
|
||||
fr.x = best_x;
|
||||
fr.y = best_y;
|
||||
return fr;
|
||||
}
|
||||
|
||||
static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
|
||||
{
|
||||
// find best position according to heuristic
|
||||
stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
|
||||
stbrp_node *node, *cur;
|
||||
|
||||
// bail if:
|
||||
// 1. it failed
|
||||
// 2. the best node doesn't fit (we don't always check this)
|
||||
// 3. we're out of memory
|
||||
if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
|
||||
res.prev_link = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
// on success, create new node
|
||||
node = context->free_head;
|
||||
node->x = (stbrp_coord) res.x;
|
||||
node->y = (stbrp_coord) (res.y + height);
|
||||
|
||||
context->free_head = node->next;
|
||||
|
||||
// insert the new node into the right starting point, and
|
||||
// let 'cur' point to the remaining nodes needing to be
|
||||
// stiched back in
|
||||
|
||||
cur = *res.prev_link;
|
||||
if (cur->x < res.x) {
|
||||
// preserve the existing one, so start testing with the next one
|
||||
stbrp_node *next = cur->next;
|
||||
cur->next = node;
|
||||
cur = next;
|
||||
} else {
|
||||
*res.prev_link = node;
|
||||
}
|
||||
|
||||
// from here, traverse cur and free the nodes, until we get to one
|
||||
// that shouldn't be freed
|
||||
while (cur->next && cur->next->x <= res.x + width) {
|
||||
stbrp_node *next = cur->next;
|
||||
// move the current node to the free list
|
||||
cur->next = context->free_head;
|
||||
context->free_head = cur;
|
||||
cur = next;
|
||||
}
|
||||
|
||||
// stitch the list back in
|
||||
node->next = cur;
|
||||
|
||||
if (cur->x < res.x + width)
|
||||
cur->x = (stbrp_coord) (res.x + width);
|
||||
|
||||
#ifdef _DEBUG
|
||||
cur = context->active_head;
|
||||
while (cur->x < context->width) {
|
||||
STBRP_ASSERT(cur->x < cur->next->x);
|
||||
cur = cur->next;
|
||||
}
|
||||
STBRP_ASSERT(cur->next == NULL);
|
||||
|
||||
{
|
||||
int count=0;
|
||||
cur = context->active_head;
|
||||
while (cur) {
|
||||
cur = cur->next;
|
||||
++count;
|
||||
}
|
||||
cur = context->free_head;
|
||||
while (cur) {
|
||||
cur = cur->next;
|
||||
++count;
|
||||
}
|
||||
STBRP_ASSERT(count == context->num_nodes+2);
|
||||
}
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
|
||||
{
|
||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||
const stbrp_rect *q = (const stbrp_rect *) b;
|
||||
if (p->h > q->h)
|
||||
return -1;
|
||||
if (p->h < q->h)
|
||||
return 1;
|
||||
return (p->w > q->w) ? -1 : (p->w < q->w);
|
||||
}
|
||||
|
||||
static int STBRP__CDECL rect_original_order(const void *a, const void *b)
|
||||
{
|
||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||
const stbrp_rect *q = (const stbrp_rect *) b;
|
||||
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
|
||||
}
|
||||
|
||||
STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
|
||||
{
|
||||
int i, all_rects_packed = 1;
|
||||
|
||||
// we use the 'was_packed' field internally to allow sorting/unsorting
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
rects[i].was_packed = i;
|
||||
}
|
||||
|
||||
// sort according to heuristic
|
||||
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
|
||||
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
if (rects[i].w == 0 || rects[i].h == 0) {
|
||||
rects[i].x = rects[i].y = 0; // empty rect needs no space
|
||||
} else {
|
||||
stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
|
||||
if (fr.prev_link) {
|
||||
rects[i].x = (stbrp_coord) fr.x;
|
||||
rects[i].y = (stbrp_coord) fr.y;
|
||||
} else {
|
||||
rects[i].x = rects[i].y = STBRP__MAXVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unsort
|
||||
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
|
||||
|
||||
// set was_packed flags and all_rects_packed status
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
|
||||
if (!rects[i].was_packed)
|
||||
all_rects_packed = 0;
|
||||
}
|
||||
|
||||
// return the all_rects_packed status
|
||||
return all_rects_packed;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
This software is available under 2 licenses -- choose whichever you prefer.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE A - MIT License
|
||||
Copyright (c) 2017 Sean Barrett
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
||||
This is free and unencumbered software released into the public domain.
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||
software, either in source code form or as a compiled binary, for any purpose,
|
||||
commercial or non-commercial, and by any means.
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||
software dedicate any and all copyright interest in the software to the public
|
||||
domain. We make this dedication for the benefit of the public at large and to
|
||||
the detriment of our heirs and successors. We intend this dedication to be an
|
||||
overt act of relinquishment in perpetuity of all present and future rights to
|
||||
this software under copyright law.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
1447
Framework/external/embree/tutorials/common/imgui/imstb_textedit.h
vendored
Normal file
1447
Framework/external/embree/tutorials/common/imgui/imstb_textedit.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
5085
Framework/external/embree/tutorials/common/imgui/imstb_truetype.h
vendored
Normal file
5085
Framework/external/embree/tutorials/common/imgui/imstb_truetype.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
44
Framework/external/embree/tutorials/common/lights/CMakeLists.txt
vendored
Normal file
44
Framework/external/embree/tutorials/common/lights/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
## Copyright 2009-2021 Intel Corporation
|
||||
## SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
ADD_LIBRARY(lights STATIC
|
||||
light.cpp
|
||||
ambient_light.cpp
|
||||
directional_light.cpp
|
||||
point_light.cpp
|
||||
quad_light.cpp
|
||||
spot_light.cpp
|
||||
)
|
||||
TARGET_LINK_LIBRARIES(lights sys math)
|
||||
SET_PROPERTY(TARGET lights PROPERTY FOLDER tutorials/common)
|
||||
SET_PROPERTY(TARGET lights APPEND PROPERTY COMPILE_FLAGS " ${FLAGS_LOWEST}")
|
||||
|
||||
IF (EMBREE_SYCL_SUPPORT)
|
||||
ADD_LIBRARY(lights_sycl STATIC
|
||||
light.cpp
|
||||
ambient_light.cpp
|
||||
directional_light.cpp
|
||||
point_light.cpp
|
||||
quad_light.cpp
|
||||
spot_light.cpp
|
||||
)
|
||||
TARGET_LINK_LIBRARIES(lights_sycl sys math)
|
||||
SET_PROPERTY(TARGET lights_sycl PROPERTY FOLDER tutorials/common)
|
||||
SET_PROPERTY(TARGET lights_sycl APPEND PROPERTY COMPILE_FLAGS " ${FLAGS_LOWEST} ${CMAKE_CXX_FLAGS_SYCL}")
|
||||
TARGET_COMPILE_DEFINITIONS(lights_sycl PUBLIC EMBREE_SYCL_TUTORIAL)
|
||||
ENDIF()
|
||||
|
||||
IF (EMBREE_ISPC_SUPPORT)
|
||||
ADD_ISPC_LIBRARY(lights_ispc STATIC
|
||||
light.ispc
|
||||
ambient_light.ispc
|
||||
directional_light.ispc
|
||||
point_light.ispc
|
||||
quad_light.ispc
|
||||
spot_light.ispc
|
||||
)
|
||||
TARGET_LINK_LIBRARIES(lights_ispc sys math)
|
||||
SET_TARGET_PROPERTIES(lights_ispc PROPERTIES LINKER_LANGUAGE CXX)
|
||||
SET_PROPERTY(TARGET lights_ispc PROPERTY FOLDER tutorials/common)
|
||||
SET_PROPERTY(TARGET lights_ispc APPEND PROPERTY COMPILE_FLAGS " ${FLAGS_LOWEST}")
|
||||
ENDIF()
|
||||
84
Framework/external/embree/tutorials/common/lights/ambient_light.cpp
vendored
Normal file
84
Framework/external/embree/tutorials/common/lights/ambient_light.cpp
vendored
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "light.h"
|
||||
#include "../math/sampling.h"
|
||||
#include "../math/linearspace.h"
|
||||
|
||||
namespace embree {
|
||||
|
||||
struct AmbientLight
|
||||
{
|
||||
Light super; //!< inherited light fields
|
||||
|
||||
Vec3fa radiance; //!< RGB color and intensity of light
|
||||
};
|
||||
|
||||
|
||||
// Implementation
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// XXX importance sampling is only done into the positive hemisphere
|
||||
// ==> poor support for translucent materials
|
||||
SYCL_EXTERNAL Light_SampleRes AmbientLight_sample(const Light* super,
|
||||
const DifferentialGeometry& dg,
|
||||
const Vec2f& s)
|
||||
{
|
||||
AmbientLight* self = (AmbientLight*)super;
|
||||
Light_SampleRes res;
|
||||
|
||||
const Vec3fa localDir = cosineSampleHemisphere(s);
|
||||
res.dir = frame(dg.Ns) * localDir;
|
||||
res.pdf = cosineSampleHemispherePDF(localDir);
|
||||
res.dist = inf;
|
||||
res.weight = self->radiance * rcp(res.pdf);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
SYCL_EXTERNAL Light_EvalRes AmbientLight_eval(const Light* super,
|
||||
const DifferentialGeometry& dg,
|
||||
const Vec3fa& dir)
|
||||
{
|
||||
AmbientLight* self = (AmbientLight*)super;
|
||||
Light_EvalRes res;
|
||||
|
||||
res.value = self->radiance;
|
||||
res.dist = inf;
|
||||
res.pdf = cosineSampleHemispherePDF(max(dot(dg.Ns, dir), 0.f));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void AmbientLight_Constructor(AmbientLight* self,
|
||||
const Vec3fa& radiance)
|
||||
{
|
||||
Light_Constructor(&self->super);
|
||||
self->radiance = radiance;
|
||||
//self->super.sample = GET_FUNCTION_POINTER(AmbientLight_sample);
|
||||
//self->super.eval = GET_FUNCTION_POINTER(AmbientLight_eval);
|
||||
self->super.type = LIGHT_AMBIENT;
|
||||
}
|
||||
|
||||
|
||||
// Exports (called from C++)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! Create an ispc-side AmbientLight object
|
||||
extern "C" void *AmbientLight_create()
|
||||
{
|
||||
AmbientLight* self = (AmbientLight*) alignedUSMMalloc(sizeof(AmbientLight),16);
|
||||
AmbientLight_Constructor(self, Vec3fa(1.f));
|
||||
return self;
|
||||
}
|
||||
|
||||
//! Set the parameters of an ispc-side AmbientLight object
|
||||
extern "C" void AmbientLight_set(void* super,
|
||||
const Vec3fa& radiance)
|
||||
{
|
||||
AmbientLight* self = (AmbientLight*)super;
|
||||
self->radiance = radiance;
|
||||
}
|
||||
|
||||
} // namespace embree
|
||||
16
Framework/external/embree/tutorials/common/lights/ambient_light.h
vendored
Normal file
16
Framework/external/embree/tutorials/common/lights/ambient_light.h
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../math/vec.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
extern "C" void* AmbientLight_create();
|
||||
|
||||
extern "C" void AmbientLight_set(void* super,
|
||||
const Vec3fa& radiance);
|
||||
|
||||
extern "C" void Light_destroy(Light* light);
|
||||
}
|
||||
80
Framework/external/embree/tutorials/common/lights/ambient_light.ispc
vendored
Normal file
80
Framework/external/embree/tutorials/common/lights/ambient_light.ispc
vendored
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "light.isph"
|
||||
#include "../math/sampling.isph"
|
||||
#include "../math/linearspace.isph"
|
||||
|
||||
struct AmbientLight
|
||||
{
|
||||
Light super; //!< inherited light fields
|
||||
|
||||
Vec3f radiance; //!< RGB color and intensity of light
|
||||
};
|
||||
|
||||
|
||||
// Implementation
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// XXX importance sampling is only done into the positive hemisphere
|
||||
// ==> poor support for translucent materials
|
||||
SYCL_EXTERNAL Light_SampleRes AmbientLight_sample(const uniform Light* uniform super,
|
||||
const DifferentialGeometry& dg,
|
||||
const Vec2f& s)
|
||||
{
|
||||
uniform AmbientLight* uniform self = (uniform AmbientLight* uniform)super;
|
||||
Light_SampleRes res;
|
||||
|
||||
const Vec3f localDir = cosineSampleHemisphere(s);
|
||||
res.dir = frame(dg.Ns) * localDir;
|
||||
res.pdf = cosineSampleHemispherePDF(localDir);
|
||||
res.dist = inf;
|
||||
res.weight = self->radiance * rcp(res.pdf);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
SYCL_EXTERNAL Light_EvalRes AmbientLight_eval(const uniform Light* uniform super,
|
||||
const DifferentialGeometry& dg,
|
||||
const Vec3f& dir)
|
||||
{
|
||||
uniform AmbientLight* uniform self = (uniform AmbientLight* uniform)super;
|
||||
Light_EvalRes res;
|
||||
|
||||
res.value = self->radiance;
|
||||
res.dist = inf;
|
||||
res.pdf = cosineSampleHemispherePDF(max(dot(dg.Ns, dir), 0.f));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void AmbientLight_Constructor(uniform AmbientLight* uniform self,
|
||||
const uniform Vec3f& radiance)
|
||||
{
|
||||
Light_Constructor(&self->super);
|
||||
self->radiance = radiance;
|
||||
//self->super.sample = GET_FUNCTION_POINTER(AmbientLight_sample);
|
||||
//self->super.eval = GET_FUNCTION_POINTER(AmbientLight_eval);
|
||||
self->super.type = LIGHT_AMBIENT;
|
||||
}
|
||||
|
||||
|
||||
// Exports (called from C++)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! Create an ispc-side AmbientLight object
|
||||
export void *uniform AmbientLight_create()
|
||||
{
|
||||
uniform AmbientLight* uniform self = uniform new uniform AmbientLight;
|
||||
AmbientLight_Constructor(self, make_Vec3f(1.f));
|
||||
return self;
|
||||
}
|
||||
|
||||
//! Set the parameters of an ispc-side AmbientLight object
|
||||
export void AmbientLight_set(void* uniform super,
|
||||
const uniform Vec3f& radiance)
|
||||
{
|
||||
uniform AmbientLight* uniform self = (uniform AmbientLight* uniform)super;
|
||||
self->radiance = radiance;
|
||||
}
|
||||
95
Framework/external/embree/tutorials/common/lights/directional_light.cpp
vendored
Normal file
95
Framework/external/embree/tutorials/common/lights/directional_light.cpp
vendored
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "light.h"
|
||||
#include "../math/sampling.h"
|
||||
#include "../math/linearspace.h"
|
||||
|
||||
namespace embree {
|
||||
|
||||
struct DirectionalLight
|
||||
{
|
||||
Light super; //!< inherited light fields
|
||||
|
||||
LinearSpace3fa frame; //!< coordinate frame, with vz == direction *towards* the light source
|
||||
Vec3fa radiance; //!< RGB color and intensity of light
|
||||
float cosAngle; //!< Angular limit of the cone light in an easier to use form: cosine of the half angle in radians
|
||||
float pdf; //!< Probability to sample a direction to the light
|
||||
};
|
||||
|
||||
// for very small cones treat as singular light, because float precision is not good enough
|
||||
#define COS_ANGLE_MAX 0.99999988f
|
||||
|
||||
|
||||
// Implementation
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SYCL_EXTERNAL Light_SampleRes DirectionalLight_sample(const Light* super,
|
||||
const DifferentialGeometry& dg,
|
||||
const Vec2f& s)
|
||||
{
|
||||
const DirectionalLight* self = (DirectionalLight*)super;
|
||||
Light_SampleRes res;
|
||||
|
||||
res.dir = self->frame.vz;
|
||||
res.dist = inf;
|
||||
res.pdf = self->pdf;
|
||||
|
||||
if (self->cosAngle < COS_ANGLE_MAX)
|
||||
res.dir = self->frame * uniformSampleCone(self->cosAngle, s);
|
||||
|
||||
res.weight = self->radiance; // *pdf/pdf cancel
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
SYCL_EXTERNAL Light_EvalRes DirectionalLight_eval(const Light* super,
|
||||
const DifferentialGeometry&,
|
||||
const Vec3fa& dir)
|
||||
{
|
||||
DirectionalLight* self = (DirectionalLight*)super;
|
||||
Light_EvalRes res;
|
||||
res.dist = inf;
|
||||
|
||||
if (self->cosAngle < COS_ANGLE_MAX && dot(self->frame.vz, dir) > self->cosAngle) {
|
||||
res.value = self->radiance * self->pdf;
|
||||
res.pdf = self->pdf;
|
||||
} else {
|
||||
res.value = Vec3fa(0.f);
|
||||
res.pdf = 0.f;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
// Exports (called from C++)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! Set the parameters of an ispc-side DirectionalLight object
|
||||
extern "C" void DirectionalLight_set(void* super,
|
||||
const Vec3fa& direction,
|
||||
const Vec3fa& radiance,
|
||||
float cosAngle)
|
||||
{
|
||||
DirectionalLight* self = (DirectionalLight*)super;
|
||||
self->frame = frame(direction);
|
||||
self->radiance = radiance;
|
||||
self->cosAngle = cosAngle;
|
||||
self->pdf = cosAngle < COS_ANGLE_MAX ? uniformSampleConePDF(cosAngle) : inf;
|
||||
}
|
||||
|
||||
//! Create an ispc-side DirectionalLight object
|
||||
extern "C" void* DirectionalLight_create()
|
||||
{
|
||||
DirectionalLight* self = (DirectionalLight*) alignedUSMMalloc(sizeof(DirectionalLight),16);
|
||||
Light_Constructor(&self->super);
|
||||
//self->super.sample = GET_FUNCTION_POINTER(DirectionalLight_sample);
|
||||
//self->super.eval = GET_FUNCTION_POINTER(DirectionalLight_eval);
|
||||
self->super.type = LIGHT_DIRECTIONAL;
|
||||
|
||||
DirectionalLight_set(self, Vec3fa(0.f, 0.f, 1.f), Vec3fa(1.f), 1.f);
|
||||
return self;
|
||||
}
|
||||
|
||||
} // namespace embree
|
||||
16
Framework/external/embree/tutorials/common/lights/directional_light.h
vendored
Normal file
16
Framework/external/embree/tutorials/common/lights/directional_light.h
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../math/vec.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
extern "C" void* DirectionalLight_create();
|
||||
|
||||
extern "C" void DirectionalLight_set(void* super,
|
||||
const Vec3fa& direction,
|
||||
const Vec3fa& radiance,
|
||||
float cosAngle);
|
||||
}
|
||||
91
Framework/external/embree/tutorials/common/lights/directional_light.ispc
vendored
Normal file
91
Framework/external/embree/tutorials/common/lights/directional_light.ispc
vendored
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "light.isph"
|
||||
#include "../math/sampling.isph"
|
||||
#include "../math/linearspace.isph"
|
||||
|
||||
struct DirectionalLight
|
||||
{
|
||||
Light super; //!< inherited light fields
|
||||
|
||||
LinearSpace3f frame; //!< coordinate frame, with vz == direction *towards* the light source
|
||||
Vec3f radiance; //!< RGB color and intensity of light
|
||||
float cosAngle; //!< Angular limit of the cone light in an easier to use form: cosine of the half angle in radians
|
||||
float pdf; //!< Probability to sample a direction to the light
|
||||
};
|
||||
|
||||
// for very small cones treat as singular light, because float precision is not good enough
|
||||
#define COS_ANGLE_MAX 0.99999988f
|
||||
|
||||
|
||||
// Implementation
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SYCL_EXTERNAL Light_SampleRes DirectionalLight_sample(const uniform Light* uniform super,
|
||||
const DifferentialGeometry& dg,
|
||||
const Vec2f& s)
|
||||
{
|
||||
const DirectionalLight* uniform self = (DirectionalLight* uniform)super;
|
||||
Light_SampleRes res;
|
||||
|
||||
res.dir = self->frame.vz;
|
||||
res.dist = inf;
|
||||
res.pdf = self->pdf;
|
||||
|
||||
if (self->cosAngle < COS_ANGLE_MAX)
|
||||
res.dir = self->frame * uniformSampleCone(self->cosAngle, s);
|
||||
|
||||
res.weight = self->radiance; // *pdf/pdf cancel
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
SYCL_EXTERNAL Light_EvalRes DirectionalLight_eval(const uniform Light* uniform super,
|
||||
const DifferentialGeometry&,
|
||||
const Vec3f& dir)
|
||||
{
|
||||
uniform DirectionalLight* uniform self = (uniform DirectionalLight* uniform)super;
|
||||
Light_EvalRes res;
|
||||
res.dist = inf;
|
||||
|
||||
if (self->cosAngle < COS_ANGLE_MAX && dot(self->frame.vz, dir) > self->cosAngle) {
|
||||
res.value = self->radiance * self->pdf;
|
||||
res.pdf = self->pdf;
|
||||
} else {
|
||||
res.value = make_Vec3f(0.f);
|
||||
res.pdf = 0.f;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
// Exports (called from C++)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! Set the parameters of an ispc-side DirectionalLight object
|
||||
export void DirectionalLight_set(void* uniform super,
|
||||
const uniform Vec3f& direction,
|
||||
const uniform Vec3f& radiance,
|
||||
uniform float cosAngle)
|
||||
{
|
||||
uniform DirectionalLight* uniform self = (uniform DirectionalLight* uniform)super;
|
||||
self->frame = frame(direction);
|
||||
self->radiance = radiance;
|
||||
self->cosAngle = cosAngle;
|
||||
self->pdf = cosAngle < COS_ANGLE_MAX ? uniformSampleConePDF(cosAngle) : inf;
|
||||
}
|
||||
|
||||
//! Create an ispc-side DirectionalLight object
|
||||
export void* uniform DirectionalLight_create()
|
||||
{
|
||||
uniform DirectionalLight* uniform self = uniform new uniform DirectionalLight;
|
||||
Light_Constructor(&self->super);
|
||||
//self->super.sample = GET_FUNCTION_POINTER(DirectionalLight_sample);
|
||||
//self->super.eval = GET_FUNCTION_POINTER(DirectionalLight_eval);
|
||||
self->super.type = LIGHT_DIRECTIONAL;
|
||||
|
||||
DirectionalLight_set(self, make_Vec3f(0.f, 0.f, 1.f), make_Vec3f(1.f), 1.f);
|
||||
return self;
|
||||
}
|
||||
26
Framework/external/embree/tutorials/common/lights/light.cpp
vendored
Normal file
26
Framework/external/embree/tutorials/common/lights/light.cpp
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "light.h"
|
||||
|
||||
namespace embree {
|
||||
|
||||
SYCL_EXTERNAL Light_EvalRes Light_eval(const Light* uniform,
|
||||
const DifferentialGeometry&,
|
||||
const Vec3fa&)
|
||||
{
|
||||
Light_EvalRes res;
|
||||
res.value = Vec3fa(0.f);
|
||||
res.dist = inf;
|
||||
res.pdf = 0.f;
|
||||
return res;
|
||||
}
|
||||
|
||||
extern "C" void Light_destroy(Light* light)
|
||||
{
|
||||
alignedUSMFree(light);
|
||||
}
|
||||
|
||||
extern "C" void dummy() {} // just to avoid linker warning under MacOSX
|
||||
|
||||
} // namespace embree
|
||||
67
Framework/external/embree/tutorials/common/lights/light.h
vendored
Normal file
67
Framework/external/embree/tutorials/common/lights/light.h
vendored
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../device_default.h"
|
||||
#include "../core/differential_geometry.h"
|
||||
|
||||
namespace embree {
|
||||
|
||||
struct Light;
|
||||
|
||||
enum TutorialLightType
|
||||
{
|
||||
LIGHT_AMBIENT,
|
||||
LIGHT_POINT,
|
||||
LIGHT_DIRECTIONAL,
|
||||
LIGHT_SPOT,
|
||||
LIGHT_DISTANT,
|
||||
LIGHT_TRIANGLE,
|
||||
LIGHT_QUAD,
|
||||
};
|
||||
|
||||
struct Light_SampleRes
|
||||
{
|
||||
Vec3fa weight; //!< radiance that arrives at the given point divided by pdf
|
||||
Vec3fa dir; //!< direction towards the light source
|
||||
float dist; //!< largest valid t_far value for a shadow ray
|
||||
float pdf; //!< probability density that this sample was taken
|
||||
};
|
||||
|
||||
//! compute the weighted radiance at a point caused by a sample on the light source
|
||||
// by convention, giving (0, 0) as "random" numbers should sample the "center"
|
||||
// of the light source (used by the raytracing renderers such as the OBJ renderer)
|
||||
typedef Light_SampleRes (*Light_SampleFunc)(const Light* self,
|
||||
const DifferentialGeometry& dg, /*! point to generate the sample for >*/
|
||||
const Vec2f& s); /*! random numbers to generate the sample >*/
|
||||
|
||||
|
||||
struct Light_EvalRes
|
||||
{
|
||||
Vec3fa value; //!< radiance that arrives at the given point (not weighted by pdf)
|
||||
float dist;
|
||||
float pdf; //!< probability density that the direction would have been sampled
|
||||
};
|
||||
|
||||
//! compute the radiance, distance and pdf caused by the light source (pointed to by the given direction)
|
||||
typedef Light_EvalRes (*Light_EvalFunc)(const Light* self,
|
||||
const DifferentialGeometry& dg, /*! point to evaluate illumination for >*/
|
||||
const Vec3fa& dir); /*! direction towards the light source >*/
|
||||
|
||||
|
||||
struct Light
|
||||
{
|
||||
//Light_SampleFunc sample;
|
||||
//Light_EvalFunc eval;
|
||||
TutorialLightType type;
|
||||
};
|
||||
|
||||
SYCL_EXTERNAL Light_EvalRes Light_eval(const Light* self, const DifferentialGeometry& dg, const Vec3fa& dir);
|
||||
|
||||
inline void Light_Constructor(Light* self)
|
||||
{
|
||||
//self->eval = GET_FUNCTION_POINTER(Light_eval);
|
||||
}
|
||||
|
||||
} // namespace embree
|
||||
22
Framework/external/embree/tutorials/common/lights/light.ispc
vendored
Normal file
22
Framework/external/embree/tutorials/common/lights/light.ispc
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "light.isph"
|
||||
|
||||
SYCL_EXTERNAL Light_EvalRes Light_eval(const uniform Light* uniform,
|
||||
const DifferentialGeometry&,
|
||||
const Vec3f&)
|
||||
{
|
||||
Light_EvalRes res;
|
||||
res.value = make_Vec3f(0.f);
|
||||
res.dist = inf;
|
||||
res.pdf = 0.f;
|
||||
return res;
|
||||
}
|
||||
|
||||
export void Light_destroy(Light* uniform light)
|
||||
{
|
||||
delete light;
|
||||
}
|
||||
|
||||
export void dummy() {} // just to avoid linker warning under MacOSX
|
||||
63
Framework/external/embree/tutorials/common/lights/light.isph
vendored
Normal file
63
Framework/external/embree/tutorials/common/lights/light.isph
vendored
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../device_default.isph"
|
||||
#include "../core/differential_geometry.isph"
|
||||
|
||||
struct Light;
|
||||
|
||||
enum TutorialLightType
|
||||
{
|
||||
LIGHT_AMBIENT,
|
||||
LIGHT_POINT,
|
||||
LIGHT_DIRECTIONAL,
|
||||
LIGHT_SPOT,
|
||||
LIGHT_DISTANT,
|
||||
LIGHT_TRIANGLE,
|
||||
LIGHT_QUAD,
|
||||
};
|
||||
|
||||
struct Light_SampleRes
|
||||
{
|
||||
Vec3f weight; //!< radiance that arrives at the given point divided by pdf
|
||||
Vec3f dir; //!< direction towards the light source
|
||||
float dist; //!< largest valid t_far value for a shadow ray
|
||||
float pdf; //!< probability density that this sample was taken
|
||||
};
|
||||
|
||||
//! compute the weighted radiance at a point caused by a sample on the light source
|
||||
// by convention, giving (0, 0) as "random" numbers should sample the "center"
|
||||
// of the light source (used by the raytracing renderers such as the OBJ renderer)
|
||||
typedef Light_SampleRes (*Light_SampleFunc)(const uniform Light* uniform self,
|
||||
const DifferentialGeometry& dg, /*! point to generate the sample for >*/
|
||||
const Vec2f& s); /*! random numbers to generate the sample >*/
|
||||
|
||||
|
||||
struct Light_EvalRes
|
||||
{
|
||||
Vec3f value; //!< radiance that arrives at the given point (not weighted by pdf)
|
||||
float dist;
|
||||
float pdf; //!< probability density that the direction would have been sampled
|
||||
};
|
||||
|
||||
//! compute the radiance, distance and pdf caused by the light source (pointed to by the given direction)
|
||||
typedef Light_EvalRes (*Light_EvalFunc)(const uniform Light* uniform self,
|
||||
const DifferentialGeometry& dg, /*! point to evaluate illumination for >*/
|
||||
const Vec3f& dir); /*! direction towards the light source >*/
|
||||
|
||||
|
||||
struct Light
|
||||
{
|
||||
//Light_SampleFunc sample;
|
||||
//Light_EvalFunc eval;
|
||||
TutorialLightType type;
|
||||
};
|
||||
|
||||
SYCL_EXTERNAL Light_EvalRes Light_eval(const uniform Light* uniform self, const DifferentialGeometry& dg, const Vec3f& dir);
|
||||
|
||||
inline void Light_Constructor(uniform Light* uniform self)
|
||||
{
|
||||
//self->eval = GET_FUNCTION_POINTER(Light_eval);
|
||||
}
|
||||
134
Framework/external/embree/tutorials/common/lights/point_light.cpp
vendored
Normal file
134
Framework/external/embree/tutorials/common/lights/point_light.cpp
vendored
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "light.h"
|
||||
#include "../math/sampling.h"
|
||||
#include "../math/linearspace.h"
|
||||
|
||||
namespace embree {
|
||||
|
||||
struct PointLight
|
||||
{
|
||||
Light super; //!< inherited light fields
|
||||
|
||||
Vec3fa position; //!< light position
|
||||
Vec3fa power; //!< RGB color and intensity of light
|
||||
float radius; //!< defines the size of the SphereLight
|
||||
};
|
||||
|
||||
|
||||
// Implementation
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SYCL_EXTERNAL Light_SampleRes PointLight_sample(const Light* super,
|
||||
const DifferentialGeometry& dg,
|
||||
const Vec2f& s)
|
||||
{
|
||||
const PointLight* self = (PointLight*)super;
|
||||
Light_SampleRes res;
|
||||
|
||||
// extant light vector from the hit point
|
||||
const Vec3fa dir = self->position - dg.P;
|
||||
const float dist2 = dot(dir, dir);
|
||||
const float invdist = rsqrt(dist2);
|
||||
|
||||
// normalized light vector
|
||||
res.dir = dir * invdist;
|
||||
res.dist = dist2 * invdist;
|
||||
|
||||
res.pdf = inf; // per default we always take this res
|
||||
|
||||
// convert from power to radiance by attenuating by distance^2
|
||||
res.weight = self->power * sqr(invdist);
|
||||
const float sinTheta = self->radius * invdist;
|
||||
|
||||
if ((self->radius > 0.f) & (sinTheta > 0.005f)) {
|
||||
// res surface of sphere as seen by hit point -> cone of directions
|
||||
// for very small cones treat as point light, because float precision is not good enough
|
||||
if (sinTheta < 1.f) {
|
||||
const float cosTheta = sqrt(1.f - sinTheta * sinTheta);
|
||||
const Vec3fa localDir = uniformSampleCone(cosTheta, s);
|
||||
res.dir = frame(res.dir) * localDir;
|
||||
res.pdf = uniformSampleConePDF(cosTheta);
|
||||
const float c = localDir.z;
|
||||
res.dist = c*res.dist - sqrt(sqr(self->radius) - (1.f - c*c) * dist2);
|
||||
// TODO scale radiance by actual distance
|
||||
} else { // inside sphere
|
||||
const Vec3fa localDir = cosineSampleHemisphere(s);
|
||||
res.dir = frame(dg.Ns) * localDir;
|
||||
res.pdf = cosineSampleHemispherePDF(localDir);
|
||||
// TODO:
|
||||
res.weight = self->power * rcp(sqr(self->radius));
|
||||
res.dist = self->radius;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
SYCL_EXTERNAL Light_EvalRes PointLight_eval(const Light* super,
|
||||
const DifferentialGeometry& dg,
|
||||
const Vec3fa& dir)
|
||||
{
|
||||
const PointLight* self = (PointLight*)super;
|
||||
Light_EvalRes res;
|
||||
res.value = Vec3fa(0.f);
|
||||
res.dist = inf;
|
||||
res.pdf = 0.f;
|
||||
|
||||
if (self->radius > 0.f) {
|
||||
const Vec3fa A = self->position - dg.P;
|
||||
const float a = dot(dir, dir);
|
||||
const float b = 2.f * dot(dir, A);
|
||||
const float centerDist2 = dot(A, A);
|
||||
const float c = centerDist2 - sqr(self->radius);
|
||||
const float radical = sqr(b) - 4.f*a*c;
|
||||
|
||||
if (radical > 0.f) {
|
||||
const float t_near = (b - sqrt(radical)) / (2.f*a);
|
||||
const float t_far = (b + sqrt(radical)) / (2.f*a);
|
||||
|
||||
if (t_far > 0.0f) {
|
||||
// TODO: handle interior case
|
||||
res.dist = t_near;
|
||||
const float sinTheta2 = sqr(self->radius) * rcp(centerDist2);
|
||||
const float cosTheta = sqrt(1.f - sinTheta2);
|
||||
res.pdf = uniformSampleConePDF(cosTheta);
|
||||
const float invdist = rcp(t_near);
|
||||
res.value = self->power * res.pdf * sqr(invdist);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// Exports (called from C++)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! Set the parameters of an ispc-side PointLight object
|
||||
extern "C" void PointLight_set(void* super,
|
||||
const Vec3fa& position,
|
||||
const Vec3fa& power,
|
||||
float radius)
|
||||
{
|
||||
PointLight* self = (PointLight*)super;
|
||||
self->position = position;
|
||||
self->power = power;
|
||||
self->radius = radius;
|
||||
}
|
||||
|
||||
//! Create an ispc-side PointLight object
|
||||
extern "C" void* PointLight_create()
|
||||
{
|
||||
PointLight* self = (PointLight*) alignedUSMMalloc(sizeof(PointLight),16);
|
||||
Light_Constructor(&self->super);
|
||||
//self->super.sample = GET_FUNCTION_POINTER(PointLight_sample);
|
||||
//self->super.eval = GET_FUNCTION_POINTER(PointLight_eval);
|
||||
self->super.type = LIGHT_POINT;
|
||||
|
||||
PointLight_set(self, Vec3fa(0.f), Vec3fa(1.f), 0.f);
|
||||
return self;
|
||||
}
|
||||
|
||||
} // namespace embree
|
||||
16
Framework/external/embree/tutorials/common/lights/point_light.h
vendored
Normal file
16
Framework/external/embree/tutorials/common/lights/point_light.h
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../math/vec.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
extern "C" void* PointLight_create();
|
||||
|
||||
extern "C" void PointLight_set(void* super,
|
||||
const Vec3fa& position,
|
||||
const Vec3fa& power,
|
||||
float radius);
|
||||
}
|
||||
130
Framework/external/embree/tutorials/common/lights/point_light.ispc
vendored
Normal file
130
Framework/external/embree/tutorials/common/lights/point_light.ispc
vendored
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "light.isph"
|
||||
#include "../math/sampling.isph"
|
||||
#include "../math/linearspace.isph"
|
||||
|
||||
struct PointLight
|
||||
{
|
||||
Light super; //!< inherited light fields
|
||||
|
||||
Vec3f position; //!< light position
|
||||
Vec3f power; //!< RGB color and intensity of light
|
||||
float radius; //!< defines the size of the SphereLight
|
||||
};
|
||||
|
||||
|
||||
// Implementation
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SYCL_EXTERNAL Light_SampleRes PointLight_sample(const uniform Light* uniform super,
|
||||
const DifferentialGeometry& dg,
|
||||
const Vec2f& s)
|
||||
{
|
||||
const PointLight* uniform self = (PointLight* uniform)super;
|
||||
Light_SampleRes res;
|
||||
|
||||
// extant light vector from the hit point
|
||||
const Vec3f dir = self->position - dg.P;
|
||||
const float dist2 = dot(dir, dir);
|
||||
const float invdist = rsqrt(dist2);
|
||||
|
||||
// normalized light vector
|
||||
res.dir = dir * invdist;
|
||||
res.dist = dist2 * invdist;
|
||||
|
||||
res.pdf = inf; // per default we always take this res
|
||||
|
||||
// convert from power to radiance by attenuating by distance^2
|
||||
res.weight = self->power * sqr(invdist);
|
||||
const float sinTheta = self->radius * invdist;
|
||||
|
||||
if ((self->radius > 0.f) & (sinTheta > 0.005f)) {
|
||||
// res surface of sphere as seen by hit point -> cone of directions
|
||||
// for very small cones treat as point light, because float precision is not good enough
|
||||
if (sinTheta < 1.f) {
|
||||
const float cosTheta = sqrt(1.f - sinTheta * sinTheta);
|
||||
const Vec3f localDir = uniformSampleCone(cosTheta, s);
|
||||
res.dir = frame(res.dir) * localDir;
|
||||
res.pdf = uniformSampleConePDF(cosTheta);
|
||||
const float c = localDir.z;
|
||||
res.dist = c*res.dist - sqrt(sqr(self->radius) - (1.f - c*c) * dist2);
|
||||
// TODO scale radiance by actual distance
|
||||
} else { // inside sphere
|
||||
const Vec3f localDir = cosineSampleHemisphere(s);
|
||||
res.dir = frame(dg.Ns) * localDir;
|
||||
res.pdf = cosineSampleHemispherePDF(localDir);
|
||||
// TODO:
|
||||
res.weight = self->power * rcp(sqr(self->radius));
|
||||
res.dist = self->radius;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
SYCL_EXTERNAL Light_EvalRes PointLight_eval(const uniform Light* uniform super,
|
||||
const DifferentialGeometry& dg,
|
||||
const Vec3f& dir)
|
||||
{
|
||||
const PointLight* uniform self = (PointLight* uniform)super;
|
||||
Light_EvalRes res;
|
||||
res.value = make_Vec3f(0.f);
|
||||
res.dist = inf;
|
||||
res.pdf = 0.f;
|
||||
|
||||
if (self->radius > 0.f) {
|
||||
const Vec3f A = self->position - dg.P;
|
||||
const float a = dot(dir, dir);
|
||||
const float b = 2.f * dot(dir, A);
|
||||
const float centerDist2 = dot(A, A);
|
||||
const float c = centerDist2 - sqr(self->radius);
|
||||
const float radical = sqr(b) - 4.f*a*c;
|
||||
|
||||
if (radical > 0.f) {
|
||||
const float t_near = (b - sqrt(radical)) / (2.f*a);
|
||||
const float t_far = (b + sqrt(radical)) / (2.f*a);
|
||||
|
||||
if (t_far > 0.0f) {
|
||||
// TODO: handle interior case
|
||||
res.dist = t_near;
|
||||
const float sinTheta2 = sqr(self->radius) * rcp(centerDist2);
|
||||
const float cosTheta = sqrt(1.f - sinTheta2);
|
||||
res.pdf = uniformSampleConePDF(cosTheta);
|
||||
const float invdist = rcp(t_near);
|
||||
res.value = self->power * res.pdf * sqr(invdist);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// Exports (called from C++)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! Set the parameters of an ispc-side PointLight object
|
||||
export void PointLight_set(void* uniform super,
|
||||
const uniform Vec3f& position,
|
||||
const uniform Vec3f& power,
|
||||
uniform float radius)
|
||||
{
|
||||
uniform PointLight* uniform self = (uniform PointLight* uniform)super;
|
||||
self->position = position;
|
||||
self->power = power;
|
||||
self->radius = radius;
|
||||
}
|
||||
|
||||
//! Create an ispc-side PointLight object
|
||||
export void* uniform PointLight_create()
|
||||
{
|
||||
uniform PointLight* uniform self = uniform new uniform PointLight;
|
||||
Light_Constructor(&self->super);
|
||||
//self->super.sample = GET_FUNCTION_POINTER(PointLight_sample);
|
||||
//self->super.eval = GET_FUNCTION_POINTER(PointLight_eval);
|
||||
self->super.type = LIGHT_POINT;
|
||||
|
||||
PointLight_set(self, make_Vec3f(0.f), make_Vec3f(1.f), 0.f);
|
||||
return self;
|
||||
}
|
||||
106
Framework/external/embree/tutorials/common/lights/quad_light.cpp
vendored
Normal file
106
Framework/external/embree/tutorials/common/lights/quad_light.cpp
vendored
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "light.h"
|
||||
|
||||
namespace embree {
|
||||
|
||||
struct QuadLight
|
||||
{
|
||||
Light super; //!< inherited light fields
|
||||
|
||||
Vec3fa position; //!< world-space corner position of the light
|
||||
Vec3fa edge1; //!< vectors to adjacent corners
|
||||
Vec3fa edge2; //!< vectors to adjacent corners
|
||||
Vec3fa radiance; //!< RGB color and intensity of the QuadLight
|
||||
|
||||
Vec3fa nnormal; //!< negated normal, the direction that the QuadLight is not emitting; normalized
|
||||
float ppdf; // probability to sample point on light = 1/area
|
||||
};
|
||||
|
||||
|
||||
// Implementation
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SYCL_EXTERNAL Light_SampleRes QuadLight_sample(const Light* super,
|
||||
const DifferentialGeometry& dg,
|
||||
const Vec2f& s)
|
||||
{
|
||||
const QuadLight* self = (QuadLight*)super;
|
||||
Light_SampleRes res;
|
||||
|
||||
// res position on light with density ppdf = 1/area
|
||||
// TODO: use solid angle sampling
|
||||
const Vec3fa pos = self->position + self->edge1 * s.x + self->edge2 * s.y;
|
||||
|
||||
// extant light vector from the hit point
|
||||
const Vec3fa dir = pos - dg.P;
|
||||
const float dist = length(dir);
|
||||
|
||||
// normalized light vector
|
||||
res.dir = dir / dist;
|
||||
res.dist = dist;
|
||||
|
||||
// convert to pdf wrt. solid angle
|
||||
const float cosd = dot(self->nnormal, res.dir);
|
||||
res.pdf = self->ppdf * (dist * dist) / abs(cosd);
|
||||
|
||||
// emit only to one side
|
||||
res.weight = cosd > 0.f ? self->radiance * rcp(res.pdf) : Vec3fa(0.f);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
SYCL_EXTERNAL Light_EvalRes QuadLight_eval(const Light* super,
|
||||
const DifferentialGeometry& dg,
|
||||
const Vec3fa& dir)
|
||||
|
||||
{
|
||||
Light_EvalRes res;
|
||||
res.value = Vec3fa(0,0,0);
|
||||
res.dist = inf;
|
||||
res.pdf = 0.f;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
// Exports (called from C++)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! Set the parameters of an ispc-side QuadLight object
|
||||
extern "C" void QuadLight_set(void* super,
|
||||
const Vec3fa& position,
|
||||
const Vec3fa& edge2,
|
||||
const Vec3fa& edge1,
|
||||
const Vec3fa& radiance)
|
||||
{
|
||||
QuadLight* self = (QuadLight*)super;
|
||||
self->position = position;
|
||||
self->edge1 = edge1;
|
||||
self->edge2 = edge2;
|
||||
self->radiance = radiance;
|
||||
|
||||
const Vec3fa ndirection = cross(edge2, edge1);
|
||||
self->ppdf = rcp(length(ndirection));
|
||||
self->nnormal = ndirection * self->ppdf;
|
||||
}
|
||||
|
||||
//! Create an ispc-side QuadLight object
|
||||
extern "C" void* QuadLight_create()
|
||||
{
|
||||
QuadLight* self = (QuadLight*) alignedUSMMalloc(sizeof(QuadLight),16);
|
||||
|
||||
Light_Constructor(&self->super);
|
||||
//self->super.sample = GET_FUNCTION_POINTER(QuadLight_sample);
|
||||
self->super.type = LIGHT_QUAD;
|
||||
|
||||
QuadLight_set(self,
|
||||
Vec3fa(0.f),
|
||||
Vec3fa(1.f, 0.f, 0.f),
|
||||
Vec3fa(0.f, 1.f, 0.f),
|
||||
Vec3fa(1.f));
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
} // namespace embree
|
||||
18
Framework/external/embree/tutorials/common/lights/quad_light.h
vendored
Normal file
18
Framework/external/embree/tutorials/common/lights/quad_light.h
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../math/vec.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
extern "C" void* QuadLight_create();
|
||||
|
||||
extern "C" void QuadLight_set(void* super,
|
||||
const Vec3fa& position,
|
||||
const Vec3fa& edge2,
|
||||
const Vec3fa& edge1,
|
||||
const Vec3fa& radiance);
|
||||
}
|
||||
|
||||
102
Framework/external/embree/tutorials/common/lights/quad_light.ispc
vendored
Normal file
102
Framework/external/embree/tutorials/common/lights/quad_light.ispc
vendored
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "light.isph"
|
||||
|
||||
struct QuadLight
|
||||
{
|
||||
Light super; //!< inherited light fields
|
||||
|
||||
Vec3f position; //!< world-space corner position of the light
|
||||
Vec3f edge1; //!< vectors to adjacent corners
|
||||
Vec3f edge2; //!< vectors to adjacent corners
|
||||
Vec3f radiance; //!< RGB color and intensity of the QuadLight
|
||||
|
||||
Vec3f nnormal; //!< negated normal, the direction that the QuadLight is not emitting; normalized
|
||||
float ppdf; // probability to sample point on light = 1/area
|
||||
};
|
||||
|
||||
|
||||
// Implementation
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SYCL_EXTERNAL Light_SampleRes QuadLight_sample(const uniform Light* uniform super,
|
||||
const DifferentialGeometry& dg,
|
||||
const Vec2f& s)
|
||||
{
|
||||
const QuadLight* uniform self = (QuadLight* uniform)super;
|
||||
Light_SampleRes res;
|
||||
|
||||
// res position on light with density ppdf = 1/area
|
||||
// TODO: use solid angle sampling
|
||||
const Vec3f pos = self->position + self->edge1 * s.x + self->edge2 * s.y;
|
||||
|
||||
// extant light vector from the hit point
|
||||
const Vec3f dir = pos - dg.P;
|
||||
const float dist = length(dir);
|
||||
|
||||
// normalized light vector
|
||||
res.dir = dir / dist;
|
||||
res.dist = dist;
|
||||
|
||||
// convert to pdf wrt. solid angle
|
||||
const float cosd = dot(self->nnormal, res.dir);
|
||||
res.pdf = self->ppdf * (dist * dist) / abs(cosd);
|
||||
|
||||
// emit only to one side
|
||||
res.weight = cosd > 0.f ? self->radiance * rcp(res.pdf) : make_Vec3f(0.f);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
SYCL_EXTERNAL Light_EvalRes QuadLight_eval(const uniform Light* uniform super,
|
||||
const DifferentialGeometry& dg,
|
||||
const Vec3f& dir)
|
||||
|
||||
{
|
||||
Light_EvalRes res;
|
||||
res.value = make_Vec3f(0,0,0);
|
||||
res.dist = inf;
|
||||
res.pdf = 0.f;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
// Exports (called from C++)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! Set the parameters of an ispc-side QuadLight object
|
||||
export void QuadLight_set(void* uniform super,
|
||||
const uniform Vec3f& position,
|
||||
const uniform Vec3f& edge2,
|
||||
const uniform Vec3f& edge1,
|
||||
const uniform Vec3f& radiance)
|
||||
{
|
||||
uniform QuadLight* uniform self = (uniform QuadLight* uniform)super;
|
||||
self->position = position;
|
||||
self->edge1 = edge1;
|
||||
self->edge2 = edge2;
|
||||
self->radiance = radiance;
|
||||
|
||||
const uniform Vec3f ndirection = cross(edge2, edge1);
|
||||
self->ppdf = rcp(length(ndirection));
|
||||
self->nnormal = ndirection * self->ppdf;
|
||||
}
|
||||
|
||||
//! Create an ispc-side QuadLight object
|
||||
export void* uniform QuadLight_create()
|
||||
{
|
||||
uniform QuadLight* uniform self = uniform new uniform QuadLight;
|
||||
|
||||
Light_Constructor(&self->super);
|
||||
//self->super.sample = GET_FUNCTION_POINTER(QuadLight_sample);
|
||||
self->super.type = LIGHT_QUAD;
|
||||
|
||||
QuadLight_set(self,
|
||||
make_Vec3f(0.f),
|
||||
make_Vec3f(1.f, 0.f, 0.f),
|
||||
make_Vec3f(0.f, 1.f, 0.f),
|
||||
make_Vec3f(1.f));
|
||||
|
||||
return self;
|
||||
}
|
||||
139
Framework/external/embree/tutorials/common/lights/spot_light.cpp
vendored
Normal file
139
Framework/external/embree/tutorials/common/lights/spot_light.cpp
vendored
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "light.h"
|
||||
#include "../math/sampling.h"
|
||||
#include "../math/linearspace.h"
|
||||
|
||||
namespace embree {
|
||||
|
||||
struct SpotLight
|
||||
{
|
||||
Light super; //!< inherited light fields
|
||||
|
||||
Vec3fa position; //!< Position of the SpotLight
|
||||
LinearSpace3fa frame; //!< coordinate frame, with vz == direction that the SpotLight is emitting
|
||||
Vec3fa power; //!< RGB color and intensity of the SpotLight
|
||||
float cosAngleMax; //!< Angular limit of the spot in an easier to use form: cosine of the half angle in radians
|
||||
float cosAngleScale; //!< 1/(cos(border of the penumbra area) - cosAngleMax); positive
|
||||
float radius; //!< defines the size of the (extended) SpotLight
|
||||
float diskPdf; //!< pdf of disk with radius
|
||||
};
|
||||
|
||||
|
||||
// Implementation
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SYCL_EXTERNAL Light_SampleRes SpotLight_sample(const Light* super,
|
||||
const DifferentialGeometry& dg,
|
||||
const Vec2f& s)
|
||||
{
|
||||
const SpotLight* self = (SpotLight*)super;
|
||||
Light_SampleRes res;
|
||||
|
||||
// extant light vector from the hit point
|
||||
res.dir = self->position - dg.P;
|
||||
|
||||
if (self->radius > 0.0f)
|
||||
res.dir = self->frame * uniformSampleDisk(self->radius, s) + res.dir;
|
||||
|
||||
const float dist2 = dot(res.dir, res.dir);
|
||||
const float invdist = rsqrt(dist2);
|
||||
|
||||
// normalized light vector
|
||||
res.dir = res.dir * invdist;
|
||||
res.dist = dist2 * invdist;
|
||||
|
||||
// cosine of the negated light direction and light vector.
|
||||
const float cosAngle = -dot(self->frame.vz, res.dir);
|
||||
const float angularAttenuation = clamp((cosAngle - self->cosAngleMax) * self->cosAngleScale);
|
||||
|
||||
if (self->radius > 0.0f)
|
||||
res.pdf = self->diskPdf * dist2 * abs(cosAngle);
|
||||
else
|
||||
res.pdf = inf; // we always take this res
|
||||
|
||||
// convert from power to radiance by attenuating by distance^2; attenuate by angle
|
||||
res.weight = self->power * (sqr(invdist) * angularAttenuation);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
SYCL_EXTERNAL Light_EvalRes SpotLight_eval(const Light* super,
|
||||
const DifferentialGeometry& dg,
|
||||
const Vec3fa& dir)
|
||||
{
|
||||
const SpotLight* self = (SpotLight*)super;
|
||||
Light_EvalRes res;
|
||||
res.value = Vec3fa(0.0f);
|
||||
res.dist = inf;
|
||||
res.pdf = 0.0f;
|
||||
|
||||
if (self->radius > 0.0f) {
|
||||
// intersect disk
|
||||
const float cosAngle = -dot(dir, self->frame.vz);
|
||||
if (cosAngle > self->cosAngleMax) { // inside illuminated cone?
|
||||
const Vec3fa vp = dg.P - self->position;
|
||||
const float dp = dot(vp, self->frame.vz);
|
||||
if (dp > 0.0f) { // in front of light?
|
||||
const float t = dp*rcp(cosAngle);
|
||||
const Vec3fa vd = vp + t * dir;
|
||||
if (dot(vd, vd) < sqr(self->radius)) { // inside disk?
|
||||
const float angularAttenuation = min((cosAngle - self->cosAngleMax) * self->cosAngleScale, 1.f);
|
||||
const float pdf = self->diskPdf * cosAngle;
|
||||
res.value = self->power * (angularAttenuation * pdf); // *sqr(t)/sqr(t) cancels
|
||||
res.dist = t;
|
||||
res.pdf = pdf * sqr(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
// Exports (called from C++)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! Set the parameters of an ispc-side SpotLight object
|
||||
extern "C" void SpotLight_set(void* super,
|
||||
const Vec3fa& position,
|
||||
const Vec3fa& direction,
|
||||
const Vec3fa& power,
|
||||
float cosAngleMax,
|
||||
float cosAngleScale,
|
||||
float radius)
|
||||
{
|
||||
SpotLight* self = (SpotLight*)super;
|
||||
self->position = position;
|
||||
self->frame = frame(direction);
|
||||
self->power = power;
|
||||
self->cosAngleMax = cosAngleMax;
|
||||
self->cosAngleScale = cosAngleScale;
|
||||
self->radius = radius;
|
||||
self->diskPdf = uniformSampleDiskPDF(radius);
|
||||
}
|
||||
|
||||
//! Create an ispc-side SpotLight object
|
||||
extern "C" void* SpotLight_create()
|
||||
{
|
||||
SpotLight* self = (SpotLight*) alignedUSMMalloc(sizeof(SpotLight),16);
|
||||
|
||||
Light_Constructor(&self->super);
|
||||
//self->super.sample = GET_FUNCTION_POINTER(SpotLight_sample);
|
||||
//self->super.eval = GET_FUNCTION_POINTER(SpotLight_eval);
|
||||
self->super.type = LIGHT_SPOT;
|
||||
|
||||
SpotLight_set(self,
|
||||
Vec3fa(0.f),
|
||||
Vec3fa(0.f, 0.f, 1.f),
|
||||
Vec3fa(1.f),
|
||||
0.f,
|
||||
100.f,
|
||||
0.f);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
} // namespace embree
|
||||
19
Framework/external/embree/tutorials/common/lights/spot_light.h
vendored
Normal file
19
Framework/external/embree/tutorials/common/lights/spot_light.h
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../math/vec.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
extern "C" void* SpotLight_create();
|
||||
|
||||
extern "C" void SpotLight_set(void* super,
|
||||
const Vec3fa& position,
|
||||
const Vec3fa& direction,
|
||||
const Vec3fa& power,
|
||||
float cosAngleMax,
|
||||
float cosAngleScale,
|
||||
float radius);
|
||||
}
|
||||
135
Framework/external/embree/tutorials/common/lights/spot_light.ispc
vendored
Normal file
135
Framework/external/embree/tutorials/common/lights/spot_light.ispc
vendored
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "light.isph"
|
||||
#include "../math/sampling.isph"
|
||||
#include "../math/linearspace.isph"
|
||||
|
||||
struct SpotLight
|
||||
{
|
||||
Light super; //!< inherited light fields
|
||||
|
||||
Vec3f position; //!< Position of the SpotLight
|
||||
LinearSpace3f frame; //!< coordinate frame, with vz == direction that the SpotLight is emitting
|
||||
Vec3f power; //!< RGB color and intensity of the SpotLight
|
||||
float cosAngleMax; //!< Angular limit of the spot in an easier to use form: cosine of the half angle in radians
|
||||
float cosAngleScale; //!< 1/(cos(border of the penumbra area) - cosAngleMax); positive
|
||||
float radius; //!< defines the size of the (extended) SpotLight
|
||||
float diskPdf; //!< pdf of disk with radius
|
||||
};
|
||||
|
||||
|
||||
// Implementation
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SYCL_EXTERNAL Light_SampleRes SpotLight_sample(const uniform Light* uniform super,
|
||||
const DifferentialGeometry& dg,
|
||||
const Vec2f& s)
|
||||
{
|
||||
const SpotLight* uniform self = (SpotLight* uniform)super;
|
||||
Light_SampleRes res;
|
||||
|
||||
// extant light vector from the hit point
|
||||
res.dir = self->position - dg.P;
|
||||
|
||||
if (self->radius > 0.0f)
|
||||
res.dir = self->frame * uniformSampleDisk(self->radius, s) + res.dir;
|
||||
|
||||
const float dist2 = dot(res.dir, res.dir);
|
||||
const float invdist = rsqrt(dist2);
|
||||
|
||||
// normalized light vector
|
||||
res.dir = res.dir * invdist;
|
||||
res.dist = dist2 * invdist;
|
||||
|
||||
// cosine of the negated light direction and light vector.
|
||||
const float cosAngle = -dot(self->frame.vz, res.dir);
|
||||
const float angularAttenuation = clamp((cosAngle - self->cosAngleMax) * self->cosAngleScale);
|
||||
|
||||
if (self->radius > 0.0f)
|
||||
res.pdf = self->diskPdf * dist2 * abs(cosAngle);
|
||||
else
|
||||
res.pdf = inf; // we always take this res
|
||||
|
||||
// convert from power to radiance by attenuating by distance^2; attenuate by angle
|
||||
res.weight = self->power * (sqr(invdist) * angularAttenuation);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
SYCL_EXTERNAL Light_EvalRes SpotLight_eval(const uniform Light* uniform super,
|
||||
const DifferentialGeometry& dg,
|
||||
const Vec3f& dir)
|
||||
{
|
||||
const SpotLight* uniform self = (SpotLight* uniform)super;
|
||||
Light_EvalRes res;
|
||||
res.value = make_Vec3f(0.0f);
|
||||
res.dist = inf;
|
||||
res.pdf = 0.0f;
|
||||
|
||||
if (self->radius > 0.0f) {
|
||||
// intersect disk
|
||||
const float cosAngle = -dot(dir, self->frame.vz);
|
||||
if (cosAngle > self->cosAngleMax) { // inside illuminated cone?
|
||||
const Vec3f vp = dg.P - self->position;
|
||||
const float dp = dot(vp, self->frame.vz);
|
||||
if (dp > 0.0f) { // in front of light?
|
||||
const float t = dp*rcp(cosAngle);
|
||||
const Vec3f vd = vp + t * dir;
|
||||
if (dot(vd, vd) < sqr(self->radius)) { // inside disk?
|
||||
const float angularAttenuation = min((cosAngle - self->cosAngleMax) * self->cosAngleScale, 1.f);
|
||||
const float pdf = self->diskPdf * cosAngle;
|
||||
res.value = self->power * (angularAttenuation * pdf); // *sqr(t)/sqr(t) cancels
|
||||
res.dist = t;
|
||||
res.pdf = pdf * sqr(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
// Exports (called from C++)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! Set the parameters of an ispc-side SpotLight object
|
||||
export void SpotLight_set(void* uniform super,
|
||||
const uniform Vec3f& position,
|
||||
const uniform Vec3f& direction,
|
||||
const uniform Vec3f& power,
|
||||
uniform float cosAngleMax,
|
||||
uniform float cosAngleScale,
|
||||
uniform float radius)
|
||||
{
|
||||
uniform SpotLight* uniform self = (uniform SpotLight* uniform)super;
|
||||
self->position = position;
|
||||
self->frame = frame(direction);
|
||||
self->power = power;
|
||||
self->cosAngleMax = cosAngleMax;
|
||||
self->cosAngleScale = cosAngleScale;
|
||||
self->radius = radius;
|
||||
self->diskPdf = uniformSampleDiskPDF(radius);
|
||||
}
|
||||
|
||||
//! Create an ispc-side SpotLight object
|
||||
export void* uniform SpotLight_create()
|
||||
{
|
||||
uniform SpotLight* uniform self = uniform new uniform SpotLight;
|
||||
|
||||
Light_Constructor(&self->super);
|
||||
//self->super.sample = GET_FUNCTION_POINTER(SpotLight_sample);
|
||||
//self->super.eval = GET_FUNCTION_POINTER(SpotLight_eval);
|
||||
self->super.type = LIGHT_SPOT;
|
||||
|
||||
SpotLight_set(self,
|
||||
make_Vec3f(0.f),
|
||||
make_Vec3f(0.f, 0.f, 1.f),
|
||||
make_Vec3f(1.f),
|
||||
0.f,
|
||||
100.f,
|
||||
0.f);
|
||||
|
||||
return self;
|
||||
}
|
||||
12
Framework/external/embree/tutorials/common/math/affinespace.h
vendored
Normal file
12
Framework/external/embree/tutorials/common/math/affinespace.h
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../../common/math/affinespace.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
__forceinline bool eq (const AffineSpace3fa& a, const AffineSpace3fa& b) { return a == b; }
|
||||
}
|
||||
|
||||
135
Framework/external/embree/tutorials/common/math/affinespace.isph
vendored
Normal file
135
Framework/external/embree/tutorials/common/math/affinespace.isph
vendored
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "linearspace.isph"
|
||||
|
||||
struct AffineSpace3f
|
||||
{
|
||||
LinearSpace3f l;
|
||||
Vec3f p;
|
||||
};
|
||||
|
||||
struct AffineSpace3fa
|
||||
{
|
||||
LinearSpace3fa l;
|
||||
Vec3fa p;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Constructors
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline uniform AffineSpace3f make_AffineSpace3f(const uniform LinearSpace3f l) {
|
||||
uniform AffineSpace3f xfm; xfm.l = l; xfm.p = make_Vec3f(0,0,0); return xfm;
|
||||
}
|
||||
inline varying AffineSpace3f make_AffineSpace3f(const varying LinearSpace3f l) {
|
||||
varying AffineSpace3f xfm; xfm.l = l; xfm.p = make_Vec3f(0,0,0); return xfm;
|
||||
}
|
||||
inline uniform AffineSpace3f make_AffineSpace3f(const uniform LinearSpace3f l, const uniform Vec3f p) {
|
||||
uniform AffineSpace3f xfm; xfm.l = l; xfm.p = p; return xfm;
|
||||
}
|
||||
inline varying AffineSpace3f make_AffineSpace3f(const varying LinearSpace3f l, const varying Vec3f p) {
|
||||
varying AffineSpace3f xfm; xfm.l = l; xfm.p = p; return xfm;
|
||||
}
|
||||
|
||||
inline uniform AffineSpace3f make_AffineSpace3f(const uniform AffineSpace3fa l) {
|
||||
uniform AffineSpace3f xfm; xfm.l = make_LinearSpace3f(l.l); xfm.p = make_Vec3f(l.p); return xfm;
|
||||
}
|
||||
|
||||
inline varying AffineSpace3f make_AffineSpace3f(const varying AffineSpace3fa l) {
|
||||
varying AffineSpace3f xfm; xfm.l = make_LinearSpace3f(l.l); xfm.p = make_Vec3f(l.p); return xfm;
|
||||
}
|
||||
|
||||
inline uniform AffineSpace3f make_AffineSpace3f(const uniform Vec3f x, const uniform Vec3f y, const uniform Vec3f z, const uniform Vec3f p) {
|
||||
uniform AffineSpace3f xfm; xfm.l.vx = x; xfm.l.vy = y; xfm.l.vz = z; xfm.p = p; return xfm;
|
||||
}
|
||||
inline varying AffineSpace3f make_AffineSpace3f(const varying Vec3f x, const varying Vec3f y, const varying Vec3f z, const varying Vec3f p) {
|
||||
varying AffineSpace3f xfm; xfm.l.vx = x; xfm.l.vy = y; xfm.l.vz = z; xfm.p = p; return xfm;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline uniform AffineSpace3f neg(const uniform AffineSpace3f a) { return make_AffineSpace3f(neg(a.l),neg(a.p)); }
|
||||
inline varying AffineSpace3f neg(const varying AffineSpace3f a) { return make_AffineSpace3f(neg(a.l),neg(a.p)); }
|
||||
|
||||
inline uniform AffineSpace3f rcp( const uniform AffineSpace3f a) { uniform LinearSpace3f il = rcp(a.l); return make_AffineSpace3f(il,neg(il*a.p)); }
|
||||
inline varying AffineSpace3f rcp( const varying AffineSpace3f a) { varying LinearSpace3f il = rcp(a.l); return make_AffineSpace3f(il,neg(il*a.p)); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline uniform AffineSpace3f operator+(const uniform AffineSpace3f a, const uniform AffineSpace3f b) { return make_AffineSpace3f(a.l+b.l, a.p+b.p); }
|
||||
inline varying AffineSpace3f operator+(const varying AffineSpace3f a, const varying AffineSpace3f b) { return make_AffineSpace3f(a.l+b.l, a.p+b.p); }
|
||||
|
||||
inline uniform AffineSpace3f operator-(const uniform AffineSpace3f a, const uniform AffineSpace3f b) { return make_AffineSpace3f(a.l-b.l, a.p-b.p); }
|
||||
inline varying AffineSpace3f operator-(const varying AffineSpace3f a, const varying AffineSpace3f b) { return make_AffineSpace3f(a.l-b.l, a.p-b.p); }
|
||||
|
||||
inline uniform AffineSpace3f operator*( const uniform float a, const uniform AffineSpace3f b ) { return make_AffineSpace3f(a*b.l,a*b.p); }
|
||||
inline uniform AffineSpace3f operator*( const uniform AffineSpace3f a, const uniform float b ) { return make_AffineSpace3f(a.l*b,a.p*b); }
|
||||
inline uniform AffineSpace3f operator*( const uniform AffineSpace3f a, const uniform AffineSpace3f b ) { return make_AffineSpace3f(a.l*b.l,a.l*b.p+a.p); }
|
||||
|
||||
inline varying AffineSpace3f operator*( const varying float a, const varying AffineSpace3f b ) { return make_AffineSpace3f(a*b.l,a*b.p); }
|
||||
inline varying AffineSpace3f operator*( const varying AffineSpace3f a, const varying float b ) { return make_AffineSpace3f(a.l*b,a.p*b); }
|
||||
inline varying AffineSpace3f operator*( const varying AffineSpace3f a, const varying AffineSpace3f b ) { return make_AffineSpace3f(a.l*b.l,a.l*b.p + a.p); }
|
||||
|
||||
inline varying AffineSpace3f operator*( const varying float a, const uniform AffineSpace3f b ) { return make_AffineSpace3f(a*b.l,a*b.p); }
|
||||
inline varying AffineSpace3f operator*( const uniform AffineSpace3f a, const varying float b ) { return make_AffineSpace3f(a.l*b,a.p*b); }
|
||||
|
||||
inline uniform Vec3f xfmPoint (const uniform AffineSpace3f a, const uniform Vec3f v) { return xfmVector(a.l,v)+a.p; }
|
||||
inline varying Vec3f xfmPoint (const uniform AffineSpace3f a, const varying Vec3f v) { return xfmVector(a.l,v)+a.p; }
|
||||
inline varying Vec3f xfmPoint (const varying AffineSpace3f a, const varying Vec3f v) { return xfmVector(a.l,v)+a.p; }
|
||||
|
||||
inline uniform Vec3f xfmVector(const uniform AffineSpace3f a, const uniform Vec3f v) { return xfmVector(a.l,v); }
|
||||
inline varying Vec3f xfmVector(const uniform AffineSpace3f a, const varying Vec3f v) { return xfmVector(a.l,v); }
|
||||
inline varying Vec3f xfmVector(const varying AffineSpace3f a, const varying Vec3f v) { return xfmVector(a.l,v); }
|
||||
|
||||
inline uniform Vec3f xfmNormal(const uniform AffineSpace3f a, const uniform Vec3f v) { return xfmNormal(a.l,v); }
|
||||
inline varying Vec3f xfmNormal(const uniform AffineSpace3f a, const varying Vec3f v) { return xfmNormal(a.l,v); }
|
||||
inline varying Vec3f xfmNormal(const varying AffineSpace3f a, const varying Vec3f v) { return xfmNormal(a.l,v); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Comparison Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline uniform bool eq(const uniform AffineSpace3f a, const uniform AffineSpace3f b) { return eq(a.l,b.l) & eq(a.p,b.p); }
|
||||
inline varying bool eq(const varying AffineSpace3f a, const varying AffineSpace3f b) { return eq(a.l,b.l) & eq(a.p,b.p); }
|
||||
|
||||
inline uniform bool ne(const uniform AffineSpace3f a, const uniform AffineSpace3f b) { return ne(a.l,b.l) | ne(a.p,b.p); }
|
||||
inline varying bool ne(const varying AffineSpace3f a, const varying AffineSpace3f b) { return ne(a.l,b.l) | ne(a.p,b.p); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Interpolation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline uniform AffineSpace3f lerp(uniform float factor, const uniform AffineSpace3f& a, const uniform AffineSpace3f& b) {
|
||||
return make_AffineSpace3f(lerp(factor, a.l, b.l), lerp(factor, a.p, b.p));
|
||||
}
|
||||
|
||||
inline varying AffineSpace3f lerp(varying float factor, const uniform AffineSpace3f& a, const uniform AffineSpace3f& b) {
|
||||
return make_AffineSpace3f(lerp(factor, a.l, b.l), lerp(factor, a.p, b.p));
|
||||
}
|
||||
|
||||
/*! return scale matrix */
|
||||
inline uniform AffineSpace3f make_AffineSpace3f_scale(const uniform Vec3f& s) {
|
||||
return make_AffineSpace3f(make_LinearSpace3f_scale(s));
|
||||
}
|
||||
|
||||
/*! return translation matrix */
|
||||
inline uniform AffineSpace3f make_AffineSpace3f_translate(const uniform Vec3f& p) {
|
||||
return make_AffineSpace3f(make_Vec3f(1,0,0),make_Vec3f(0,1,0),make_Vec3f(0,0,1),p);
|
||||
}
|
||||
|
||||
/*! return translation matrix */
|
||||
inline AffineSpace3f make_AffineSpace3f_translate(const Vec3f& p) {
|
||||
return make_AffineSpace3f(make_Vec3f(1,0,0),make_Vec3f(0,1,0),make_Vec3f(0,0,1),p);
|
||||
}
|
||||
|
||||
/*! return matrix for rotation around arbitrary axis and point */
|
||||
inline uniform AffineSpace3f make_AffineSpace3f_rotate (const uniform Vec3f& p, const uniform Vec3f& u, const uniform float& r) {
|
||||
return (make_AffineSpace3f_translate(+p) * make_AffineSpace3f(make_LinearSpace3f_rotate(u,r))) * make_AffineSpace3f_translate(neg(p));
|
||||
}
|
||||
56
Framework/external/embree/tutorials/common/math/closest_point.h
vendored
Normal file
56
Framework/external/embree/tutorials/common/math/closest_point.h
vendored
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../math/vec.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
Vec3fa closestPointTriangle(Vec3fa const& p, Vec3fa const& a, Vec3fa const& b, Vec3fa const& c)
|
||||
{
|
||||
const Vec3fa ab = b - a;
|
||||
const Vec3fa ac = c - a;
|
||||
const Vec3fa ap = p - a;
|
||||
|
||||
const float d1 = dot(ab, ap);
|
||||
const float d2 = dot(ac, ap);
|
||||
if (d1 <= 0.f && d2 <= 0.f) return a;
|
||||
|
||||
const Vec3fa bp = p - b;
|
||||
const float d3 = dot(ab, bp);
|
||||
const float d4 = dot(ac, bp);
|
||||
if (d3 >= 0.f && d4 <= d3) return b;
|
||||
|
||||
const Vec3fa cp = p - c;
|
||||
const float d5 = dot(ab, cp);
|
||||
const float d6 = dot(ac, cp);
|
||||
if (d6 >= 0.f && d5 <= d6) return c;
|
||||
|
||||
const float vc = d1 * d4 - d3 * d2;
|
||||
if (vc <= 0.f && d1 >= 0.f && d3 <= 0.f)
|
||||
{
|
||||
const float v = d1 / (d1 - d3);
|
||||
return a + v * ab;
|
||||
}
|
||||
|
||||
const float vb = d5 * d2 - d1 * d6;
|
||||
if (vb <= 0.f && d2 >= 0.f && d6 <= 0.f)
|
||||
{
|
||||
const float v = d2 / (d2 - d6);
|
||||
return a + v * ac;
|
||||
}
|
||||
|
||||
const float va = d3 * d6 - d5 * d4;
|
||||
if (va <= 0.f && (d4 - d3) >= 0.f && (d5 - d6) >= 0.f)
|
||||
{
|
||||
const float v = (d4 - d3) / ((d4 - d3) + (d5 - d6));
|
||||
return b + v * (c - b);
|
||||
}
|
||||
|
||||
const float denom = 1.f / (va + vb + vc);
|
||||
const float v = vb * denom;
|
||||
const float w = vc * denom;
|
||||
return a + v * ab + w * ac;
|
||||
}
|
||||
}
|
||||
100
Framework/external/embree/tutorials/common/math/closest_point.isph
vendored
Normal file
100
Framework/external/embree/tutorials/common/math/closest_point.isph
vendored
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../math/vec.isph"
|
||||
|
||||
Vec3f closestPointTriangle(Vec3f const& p, Vec3f const& a, Vec3f const& b, Vec3f const& c)
|
||||
{
|
||||
const Vec3f ab = b - a;
|
||||
const Vec3f ac = c - a;
|
||||
const Vec3f ap = p - a;
|
||||
|
||||
const float d1 = dot(ab, ap);
|
||||
const float d2 = dot(ac, ap);
|
||||
if (d1 <= 0.f && d2 <= 0.f) return a;
|
||||
|
||||
const Vec3f bp = p - b;
|
||||
const float d3 = dot(ab, bp);
|
||||
const float d4 = dot(ac, bp);
|
||||
if (d3 >= 0.f && d4 <= d3) return b;
|
||||
|
||||
const Vec3f cp = p - c;
|
||||
const float d5 = dot(ab, cp);
|
||||
const float d6 = dot(ac, cp);
|
||||
if (d6 >= 0.f && d5 <= d6) return c;
|
||||
|
||||
const float vc = d1 * d4 - d3 * d2;
|
||||
if (vc <= 0.f && d1 >= 0.f && d3 <= 0.f)
|
||||
{
|
||||
const float v = d1 / (d1 - d3);
|
||||
return a + v * ab;
|
||||
}
|
||||
|
||||
const float vb = d5 * d2 - d1 * d6;
|
||||
if (vb <= 0.f && d2 >= 0.f && d6 <= 0.f)
|
||||
{
|
||||
const float v = d2 / (d2 - d6);
|
||||
return a + v * ac;
|
||||
}
|
||||
|
||||
const float va = d3 * d6 - d5 * d4;
|
||||
if (va <= 0.f && (d4 - d3) >= 0.f && (d5 - d6) >= 0.f)
|
||||
{
|
||||
const float v = (d4 - d3) / ((d4 - d3) + (d5 - d6));
|
||||
return b + v * (c - b);
|
||||
}
|
||||
|
||||
const float denom = 1.f / (va + vb + vc);
|
||||
const float v = vb * denom;
|
||||
const float w = vc * denom;
|
||||
return a + v * ab + w * ac;
|
||||
}
|
||||
|
||||
uniform Vec3f closestPointTriangle(uniform Vec3f& p, uniform Vec3f& a, uniform Vec3f& b, uniform Vec3f& c)
|
||||
{
|
||||
const uniform Vec3f ab = b - a;
|
||||
const uniform Vec3f ac = c - a;
|
||||
const uniform Vec3f ap = p - a;
|
||||
|
||||
const uniform float d1 = dot(ab, ap);
|
||||
const uniform float d2 = dot(ac, ap);
|
||||
if (d1 <= 0.f && d2 <= 0.f) return a;
|
||||
|
||||
const uniform Vec3f bp = p - b;
|
||||
const uniform float d3 = dot(ab, bp);
|
||||
const uniform float d4 = dot(ac, bp);
|
||||
if (d3 >= 0.f && d4 <= d3) return b;
|
||||
|
||||
const uniform Vec3f cp = p - c;
|
||||
const uniform float d5 = dot(ab, cp);
|
||||
const uniform float d6 = dot(ac, cp);
|
||||
if (d6 >= 0.f && d5 <= d6) return c;
|
||||
|
||||
const uniform float vc = d1 * d4 - d3 * d2;
|
||||
if (vc <= 0.f && d1 >= 0.f && d3 <= 0.f)
|
||||
{
|
||||
const uniform float v = d1 / (d1 - d3);
|
||||
return a + v * ab;
|
||||
}
|
||||
|
||||
const uniform float vb = d5 * d2 - d1 * d6;
|
||||
if (vb <= 0.f && d2 >= 0.f && d6 <= 0.f)
|
||||
{
|
||||
const uniform float v = d2 / (d2 - d6);
|
||||
return a + v * ac;
|
||||
}
|
||||
|
||||
const uniform float va = d3 * d6 - d5 * d4;
|
||||
if (va <= 0.f && (d4 - d3) >= 0.f && (d5 - d6) >= 0.f)
|
||||
{
|
||||
const uniform float v = (d4 - d3) / ((d4 - d3) + (d5 - d6));
|
||||
return b + v * (c - b);
|
||||
}
|
||||
|
||||
const uniform float denom = 1.f / (va + vb + vc);
|
||||
const uniform float v = vb * denom;
|
||||
const uniform float w = vc * denom;
|
||||
return a + v * ab + w * ac;
|
||||
}
|
||||
7
Framework/external/embree/tutorials/common/math/linearspace.h
vendored
Normal file
7
Framework/external/embree/tutorials/common/math/linearspace.h
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../../common/math/linearspace3.h"
|
||||
|
||||
314
Framework/external/embree/tutorials/common/math/linearspace.isph
vendored
Normal file
314
Framework/external/embree/tutorials/common/math/linearspace.isph
vendored
Normal file
|
|
@ -0,0 +1,314 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vec.isph"
|
||||
#include "quaternion.isph"
|
||||
|
||||
struct LinearSpace3f
|
||||
{
|
||||
Vec3f vx;
|
||||
Vec3f vy;
|
||||
Vec3f vz;
|
||||
};
|
||||
|
||||
struct LinearSpace3fa
|
||||
{
|
||||
Vec3fa vx;
|
||||
Vec3fa vy;
|
||||
Vec3fa vz;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Constructors
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline uniform LinearSpace3f make_LinearSpace3f(const uniform Vec3f &x, const uniform Vec3f &y, const uniform Vec3f &z) {
|
||||
uniform LinearSpace3f l; l.vx = x; l.vy = y; l.vz = z; return l;
|
||||
}
|
||||
|
||||
inline varying LinearSpace3f make_LinearSpace3f(const varying Vec3f &x, const varying Vec3f &y, const varying Vec3f &z) {
|
||||
varying LinearSpace3f l; l.vx = x; l.vy = y; l.vz = z; return l;
|
||||
}
|
||||
|
||||
inline uniform LinearSpace3f make_LinearSpace3f(const uniform LinearSpace3fa &s) {
|
||||
uniform LinearSpace3f l; l.vx = make_Vec3f(s.vx); l.vy = make_Vec3f(s.vy); l.vz = make_Vec3f(s.vz); return l;
|
||||
}
|
||||
|
||||
inline varying LinearSpace3f make_LinearSpace3f(const varying LinearSpace3fa &s) {
|
||||
varying LinearSpace3f l; l.vx = make_Vec3f(s.vx); l.vy = make_Vec3f(s.vy); l.vz = make_Vec3f(s.vz); return l;
|
||||
}
|
||||
|
||||
/*! construction from quaternion */
|
||||
inline uniform LinearSpace3f make_LinearSpace3f(const uniform Quaternion3f& q)
|
||||
{
|
||||
uniform LinearSpace3f l;
|
||||
l.vx = make_Vec3f(q.r*q.r + q.i*q.i - q.j*q.j - q.k*q.k, 2.0f*(q.i*q.j + q.r*q.k), 2.0f*(q.i*q.k - q.r*q.j));
|
||||
l.vy = make_Vec3f(2.0f*(q.i*q.j - q.r*q.k), (q.r*q.r - q.i*q.i + q.j*q.j - q.k*q.k), 2.0f*(q.j*q.k + q.r*q.i));
|
||||
l.vz = make_Vec3f(2.0f*(q.i*q.k + q.r*q.j), 2.0f*(q.j*q.k - q.r*q.i), q.r*q.r - q.i*q.i - q.j*q.j + q.k*q.k);
|
||||
return l;
|
||||
}
|
||||
|
||||
inline varying LinearSpace3f make_LinearSpace3f(const varying Quaternion3f& q)
|
||||
{
|
||||
LinearSpace3f l;
|
||||
l.vx = make_Vec3f(q.r*q.r + q.i*q.i - q.j*q.j - q.k*q.k, 2.0f*(q.i*q.j + q.r*q.k), 2.0f*(q.i*q.k - q.r*q.j));
|
||||
l.vy = make_Vec3f(2.0f*(q.i*q.j - q.r*q.k), (q.r*q.r - q.i*q.i + q.j*q.j - q.k*q.k), 2.0f*(q.j*q.k + q.r*q.i));
|
||||
l.vz = make_Vec3f(2.0f*(q.i*q.k + q.r*q.j), 2.0f*(q.j*q.k - q.r*q.i), q.r*q.r - q.i*q.i - q.j*q.j + q.k*q.k);
|
||||
return l;
|
||||
}
|
||||
|
||||
inline uniform LinearSpace3f make_LinearSpace3f_identity()
|
||||
{
|
||||
return make_LinearSpace3f(make_Vec3f(1.f,0.f,0.f),
|
||||
make_Vec3f(0.f,1.f,0.f),
|
||||
make_Vec3f(0.f,0.f,1.f));
|
||||
}
|
||||
|
||||
/*! return scale matrix */
|
||||
inline uniform LinearSpace3f make_LinearSpace3f_scale(const uniform Vec3f& s)
|
||||
{
|
||||
return make_LinearSpace3f( make_Vec3f( s.x, 0.0f, 0.0f),
|
||||
make_Vec3f(0.0f, s.y, 0.0f),
|
||||
make_Vec3f(0.0f, 0.0f, s.z));
|
||||
}
|
||||
|
||||
/*! return matrix for rotation around arbitrary axis */
|
||||
inline uniform LinearSpace3f make_LinearSpace3f_rotate(const uniform Vec3f& _u, const uniform float& r)
|
||||
{
|
||||
uniform Vec3f u = normalize(_u);
|
||||
uniform float s = sin(r), c = cos(r);
|
||||
return make_LinearSpace3f(make_Vec3f(u.x*u.x+(1-u.x*u.x)*c, u.x*u.y*(1-c)+u.z*s, u.x*u.z*(1-c)-u.y*s),
|
||||
make_Vec3f(u.x*u.y*(1-c)-u.z*s, u.y*u.y+(1-u.y*u.y)*c, u.y*u.z*(1-c)+u.x*s),
|
||||
make_Vec3f(u.x*u.z*(1-c)+u.y*s, u.y*u.z*(1-c)-u.x*s, u.z*u.z+(1-u.z*u.z)*c));
|
||||
}
|
||||
|
||||
/*! return matrix for rotation around arbitrary axis */
|
||||
inline varying LinearSpace3f make_LinearSpace3f_rotate(const varying Vec3f& _u, const varying float& r)
|
||||
{
|
||||
varying Vec3f u = normalize(_u);
|
||||
varying float s = sin(r), c = cos(r);
|
||||
return make_LinearSpace3f(make_Vec3f(u.x*u.x+(1-u.x*u.x)*c, u.x*u.y*(1-c)+u.z*s, u.x*u.z*(1-c)-u.y*s),
|
||||
make_Vec3f(u.x*u.y*(1-c)-u.z*s, u.y*u.y+(1-u.y*u.y)*c, u.y*u.z*(1-c)+u.x*s),
|
||||
make_Vec3f(u.x*u.z*(1-c)+u.y*s, u.y*u.z*(1-c)-u.x*s, u.z*u.z+(1-u.z*u.z)*c));
|
||||
}
|
||||
|
||||
/*! return matrix for rotation around arbitrary axis */
|
||||
inline varying LinearSpace3f make_LinearSpace3f_rotate(const uniform Vec3f& _u, const varying float& r)
|
||||
{
|
||||
varying Vec3f u = normalize(_u);
|
||||
varying float s = sin(r), c = cos(r);
|
||||
return make_LinearSpace3f(make_Vec3f(u.x*u.x+(1-u.x*u.x)*c, u.x*u.y*(1-c)+u.z*s, u.x*u.z*(1-c)-u.y*s),
|
||||
make_Vec3f(u.x*u.y*(1-c)-u.z*s, u.y*u.y+(1-u.y*u.y)*c, u.y*u.z*(1-c)+u.x*s),
|
||||
make_Vec3f(u.x*u.z*(1-c)+u.y*s, u.y*u.z*(1-c)-u.x*s, u.z*u.z+(1-u.z*u.z)*c));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline uniform LinearSpace3f neg(const uniform LinearSpace3f &l) { return make_LinearSpace3f(neg(l.vx),neg(l.vy),neg(l.vz)); }
|
||||
inline varying LinearSpace3f neg(const varying LinearSpace3f &l) { return make_LinearSpace3f(neg(l.vx),neg(l.vy),neg(l.vz)); }
|
||||
|
||||
/*! compute the determinant of the matrix */
|
||||
inline uniform float det(const uniform LinearSpace3f &l) { return dot(l.vx,cross(l.vy,l.vz)); }
|
||||
inline varying float det(const varying LinearSpace3f &l) { return dot(l.vx,cross(l.vy,l.vz)); }
|
||||
|
||||
/*! compute transposed matrix */
|
||||
inline uniform LinearSpace3f transposed(const uniform LinearSpace3f &l) {
|
||||
return make_LinearSpace3f(make_Vec3f(l.vx.x,l.vy.x,l.vz.x),
|
||||
make_Vec3f(l.vx.y,l.vy.y,l.vz.y),
|
||||
make_Vec3f(l.vx.z,l.vy.z,l.vz.z));
|
||||
}
|
||||
inline varying LinearSpace3f transposed(const varying LinearSpace3f &l) {
|
||||
return make_LinearSpace3f(make_Vec3f(l.vx.x,l.vy.x,l.vz.x),
|
||||
make_Vec3f(l.vx.y,l.vy.y,l.vz.y),
|
||||
make_Vec3f(l.vx.z,l.vy.z,l.vz.z));
|
||||
}
|
||||
|
||||
/*! compute adjoint matrix */
|
||||
inline uniform LinearSpace3f adjoint(const uniform LinearSpace3f &l) {
|
||||
return transposed(make_LinearSpace3f(cross(l.vy,l.vz),cross(l.vz,l.vx),cross(l.vx,l.vy)));
|
||||
}
|
||||
inline varying LinearSpace3f adjoint(const varying LinearSpace3f &l) {
|
||||
return transposed(make_LinearSpace3f(cross(l.vy,l.vz),cross(l.vz,l.vx),cross(l.vx,l.vy)));
|
||||
}
|
||||
|
||||
/*! calculates orthogonal coordinate frame with z-Vector pointing towards N */
|
||||
inline uniform LinearSpace3f frame(const uniform Vec3f &N)
|
||||
{
|
||||
const uniform Vec3f dx0 = make_Vec3f(0.0f,N.z,-N.y);
|
||||
const uniform Vec3f dx1 = make_Vec3f(-N.z,0.0f,N.x);
|
||||
const uniform Vec3f dx = normalize(dot(dx0,dx0) > dot(dx1,dx1) ? dx0 : dx1);
|
||||
const uniform Vec3f dy = normalize(cross(N,dx));
|
||||
return make_LinearSpace3f(dx,dy,N);
|
||||
}
|
||||
|
||||
inline varying LinearSpace3f frame(const varying Vec3f &N)
|
||||
{
|
||||
const varying Vec3f dx0 = make_Vec3f(0.0f,N.z,-N.y);
|
||||
const varying Vec3f dx1 = make_Vec3f(-N.z,0.0f,N.x);
|
||||
const varying Vec3f dx = normalize(dot(dx0,dx0) > dot(dx1,dx1) ? dx0 : dx1);
|
||||
const varying Vec3f dy = normalize(cross(N,dx));
|
||||
return make_LinearSpace3f(dx,dy,N);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline uniform LinearSpace3f operator+(const uniform LinearSpace3f &a, const uniform LinearSpace3f &b) { return make_LinearSpace3f(a.vx+b.vx, a.vy+b.vy, a.vz+b.vz); }
|
||||
inline varying LinearSpace3f operator+(const varying LinearSpace3f &a, const varying LinearSpace3f &b) { return make_LinearSpace3f(a.vx+b.vx, a.vy+b.vy, a.vz+b.vz); }
|
||||
|
||||
inline uniform LinearSpace3f operator-(const uniform LinearSpace3f &a, const uniform LinearSpace3f &b) { return make_LinearSpace3f(a.vx-b.vx, a.vy-b.vy, a.vz-b.vz); }
|
||||
inline varying LinearSpace3f operator-(const varying LinearSpace3f &a, const varying LinearSpace3f &b) { return make_LinearSpace3f(a.vx-b.vx, a.vy-b.vy, a.vz-b.vz); }
|
||||
|
||||
inline uniform Vec3f operator*(const uniform LinearSpace3f &l, const uniform Vec3f &v) { return v.x*l.vx + v.y*l.vy + v.z*l.vz; }
|
||||
inline varying Vec3f operator*(const uniform LinearSpace3f &l, const varying Vec3f &v) { return v.x*l.vx + v.y*l.vy + v.z*l.vz; }
|
||||
inline varying Vec3f operator*(const varying LinearSpace3f &l, const varying Vec3f &v) { return v.x*l.vx + v.y*l.vy + v.z*l.vz; }
|
||||
|
||||
inline uniform LinearSpace3f operator*(const uniform float &a, const uniform LinearSpace3f &b) { return make_LinearSpace3f(a*b.vx, a*b.vy, a*b.vz); }
|
||||
inline uniform LinearSpace3f operator*(const uniform LinearSpace3f &a, const uniform float &b) { return make_LinearSpace3f(a.vx*b, a.vy*b, a.vz*b); }
|
||||
inline uniform LinearSpace3f operator*(const uniform LinearSpace3f &a, const uniform LinearSpace3f &b) { return make_LinearSpace3f(a*b.vx, a*b.vy, a*b.vz); }
|
||||
|
||||
inline varying LinearSpace3f operator*(const varying float &a, const varying LinearSpace3f &b) { return make_LinearSpace3f(a*b.vx, a*b.vy, a*b.vz); }
|
||||
inline varying LinearSpace3f operator*(const varying LinearSpace3f &a, const varying float &b) { return make_LinearSpace3f(a.vx*b, a.vy*b, a.vz*b); }
|
||||
inline varying LinearSpace3f operator*(const varying LinearSpace3f &a, const varying LinearSpace3f &b) { return make_LinearSpace3f(a*b.vx, a*b.vy, a*b.vz); }
|
||||
|
||||
inline varying LinearSpace3f operator*(const varying float &a, const uniform LinearSpace3f &b) { return make_LinearSpace3f(a*b.vx, a*b.vy, a*b.vz); }
|
||||
inline varying LinearSpace3f operator*(const uniform LinearSpace3f &a, const varying float &b) { return make_LinearSpace3f(a.vx*b, a.vy*b, a.vz*b); }
|
||||
|
||||
inline uniform Vec3f xfmVector(const uniform LinearSpace3f l, const uniform Vec3f v) { return v.x*l.vx + v.y*l.vy + v.z*l.vz; }
|
||||
inline varying Vec3f xfmVector(const uniform LinearSpace3f l, const varying Vec3f v) { return v.x*l.vx + v.y*l.vy + v.z*l.vz; }
|
||||
inline varying Vec3f xfmVector(const varying LinearSpace3f l, const varying Vec3f v) { return v.x*l.vx + v.y*l.vy + v.z*l.vz; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Comparison Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline uniform bool eq(const uniform LinearSpace3f &a, const uniform LinearSpace3f &b) { return eq(a.vx,b.vx) & eq(a.vy,b.vy) & eq(a.vz,b.vz); }
|
||||
inline varying bool eq(const varying LinearSpace3f &a, const varying LinearSpace3f &b) { return eq(a.vx,b.vx) & eq(a.vy,b.vy) & eq(a.vz,b.vz); }
|
||||
|
||||
inline uniform bool ne(const uniform LinearSpace3f &a, const uniform LinearSpace3f &b) { return ne(a.vx,b.vx) | ne(a.vy,b.vy) | ne(a.vz,b.vz); }
|
||||
inline varying bool ne(const varying LinearSpace3f &a, const varying LinearSpace3f &b) { return ne(a.vx,b.vx) | ne(a.vy,b.vy) | ne(a.vz,b.vz); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*! compute inverse matrix */
|
||||
inline uniform LinearSpace3f rcp(const uniform LinearSpace3f &l) { return rcp(det(l))*adjoint(l); }
|
||||
inline varying LinearSpace3f rcp(const varying LinearSpace3f &l) { return rcp(det(l))*adjoint(l); }
|
||||
|
||||
inline uniform Vec3f xfmNormal(const uniform LinearSpace3f l, const uniform Vec3f v) { return xfmVector(transposed(rcp(l)),v); }
|
||||
inline varying Vec3f xfmNormal(const uniform LinearSpace3f l, const varying Vec3f v) { return xfmVector(transposed(rcp(l)),v); }
|
||||
inline varying Vec3f xfmNormal(const varying LinearSpace3f l, const varying Vec3f v) { return xfmVector(transposed(rcp(l)),v); }
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Interpolation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline uniform LinearSpace3f lerp(uniform float factor, const uniform LinearSpace3f& a, const uniform LinearSpace3f& b) {
|
||||
return make_LinearSpace3f(lerp(factor, a.vx, b.vx), lerp(factor, a.vy, b.vy), lerp(factor, a.vz, b.vz));
|
||||
}
|
||||
|
||||
inline varying LinearSpace3f lerp(varying float factor, const uniform LinearSpace3f& a, const uniform LinearSpace3f& b) {
|
||||
return make_LinearSpace3f(lerp(factor, a.vx, b.vx), lerp(factor, a.vy, b.vy), lerp(factor, a.vz, b.vz));
|
||||
}
|
||||
|
||||
inline varying LinearSpace3f lerp(varying float factor, const varying LinearSpace3f& a, const varying LinearSpace3f& b) {
|
||||
return make_LinearSpace3f(lerp(factor, a.vx, b.vx), lerp(factor, a.vy, b.vy), lerp(factor, a.vz, b.vz));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Norms
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline uniform float norm_1(const uniform LinearSpace3f& l)
|
||||
{
|
||||
uniform float sum = 0;
|
||||
sum += reduce_add(abs(l.vx));
|
||||
sum += reduce_add(abs(l.vy));
|
||||
sum += reduce_add(abs(l.vz));
|
||||
return sum / 9.f;
|
||||
}
|
||||
|
||||
inline uniform Quaternion3f make_Quaternion3f(const uniform LinearSpace3f & l)
|
||||
{
|
||||
uniform Quaternion3f q;
|
||||
const uniform float tr = l.vx.x + l.vy.y + l.vz.z;
|
||||
if (tr > 0)
|
||||
{
|
||||
const uniform float S = sqrt(tr+1.0) * 2;
|
||||
q.r = 0.25 * S;
|
||||
q.i = (l.vy.z - l.vz.y) / S;
|
||||
q.j = (l.vz.x - l.vx.z) / S;
|
||||
q.k = (l.vx.y - l.vy.x) / S;
|
||||
}
|
||||
else if ((l.vx.x > l.vy.y)&(l.vx.x > l.vz.z))
|
||||
{
|
||||
const uniform float S = sqrt(1.0 + l.vx.x - l.vy.y - l.vz.z) * 2;
|
||||
q.r = (l.vy.z - l.vz.y) / S;
|
||||
q.i = 0.25 * S;
|
||||
q.j = (l.vy.x + l.vx.y) / S;
|
||||
q.k = (l.vz.x + l.vx.z) / S;
|
||||
}
|
||||
else if (l.vy.y > l.vz.z)
|
||||
{
|
||||
const uniform float S = sqrt(1.0 + l.vy.y - l.vx.x - l.vz.z) * 2;
|
||||
q.r = (l.vz.x - l.vx.z) / S;
|
||||
q.i = (l.vy.x + l.vx.y) / S;
|
||||
q.j = 0.25 * S;
|
||||
q.k = (l.vz.y + l.vy.z) / S;
|
||||
}
|
||||
else
|
||||
{
|
||||
const uniform float S = sqrt(1.0 + l.vz.z - l.vx.x - l.vy.y) * 2;
|
||||
q.r = (l.vx.y - l.vy.x) / S;
|
||||
q.i = (l.vz.x + l.vx.z) / S;
|
||||
q.j = (l.vz.y + l.vy.z) / S;
|
||||
q.k = 0.25 * S;
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
inline varying Quaternion3f make_Quaternion3f(const varying LinearSpace3f & l)
|
||||
{
|
||||
Quaternion3f q;
|
||||
const float tr = l.vx.x + l.vy.y + l.vz.z;
|
||||
if (tr > 0)
|
||||
{
|
||||
const float S = sqrt(tr+1.0) * 2;
|
||||
q.r = 0.25 * S;
|
||||
q.i = (l.vy.z - l.vz.y) / S;
|
||||
q.j = (l.vz.x - l.vx.z) / S;
|
||||
q.k = (l.vx.y - l.vy.x) / S;
|
||||
}
|
||||
else if ((l.vx.x > l.vy.y)&(l.vx.x > l.vz.z))
|
||||
{
|
||||
const float S = sqrt(1.0 + l.vx.x - l.vy.y - l.vz.z) * 2;
|
||||
q.r = (l.vy.z - l.vz.y) / S;
|
||||
q.i = 0.25 * S;
|
||||
q.j = (l.vy.x + l.vx.y) / S;
|
||||
q.k = (l.vz.x + l.vx.z) / S;
|
||||
}
|
||||
else if (l.vy.y > l.vz.z)
|
||||
{
|
||||
const float S = sqrt(1.0 + l.vy.y - l.vx.x - l.vz.z) * 2;
|
||||
q.r = (l.vz.x - l.vx.z) / S;
|
||||
q.i = (l.vy.x + l.vx.y) / S;
|
||||
q.j = 0.25 * S;
|
||||
q.k = (l.vz.y + l.vy.z) / S;
|
||||
}
|
||||
else
|
||||
{
|
||||
const float S = sqrt(1.0 + l.vz.z - l.vx.x - l.vy.y) * 2;
|
||||
q.r = (l.vx.y - l.vy.x) / S;
|
||||
q.i = (l.vz.x + l.vx.z) / S;
|
||||
q.j = (l.vz.y + l.vy.z) / S;
|
||||
q.k = 0.25 * S;
|
||||
}
|
||||
return q;
|
||||
}
|
||||
6
Framework/external/embree/tutorials/common/math/math.h
vendored
Normal file
6
Framework/external/embree/tutorials/common/math/math.h
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../../common/math/emath.h"
|
||||
184
Framework/external/embree/tutorials/common/math/math.isph
vendored
Normal file
184
Framework/external/embree/tutorials/common/math/math.isph
vendored
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../common.isph"
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Constants
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
#define inf (1e100f)
|
||||
#define pos_inf (1e100f)
|
||||
#define neg_inf (-1e100f)
|
||||
|
||||
#define M_PI 3.14159265358979323846f
|
||||
#define pi 3.14159265358979323846f
|
||||
#define two_pi 6.283185307179586232f
|
||||
#define four_pi 12.566370614359172464f
|
||||
|
||||
#define one_over_pi 0.31830988618379069122f
|
||||
#define one_over_two_pi 0.15915494309189534561f
|
||||
#define one_over_four_pi 0.079577471545947672804f
|
||||
#define one_over_two_pi_sqr 0.050660591821168885722f
|
||||
|
||||
/*! c-style reciprocal. required since ispc 1.7 due to type changes in this version */
|
||||
inline float rcpf(const float f) { return rcp(f); }
|
||||
/*! c-style reciprocal. required since ispc 1.7 due to type changes in this version */
|
||||
inline uniform float rcpf(const uniform float f) { return rcp(f); }
|
||||
|
||||
/*! c-style square root. */
|
||||
inline float sqrtf(const float f) { return sqrt(f); }
|
||||
/*! c-style square root */
|
||||
inline uniform float sqrtf(const uniform float f) { return sqrt(f); }
|
||||
|
||||
/*! c-style reciprocal square root. */
|
||||
inline float rsqrtf(const float f) { return rsqrt(f); }
|
||||
/*! c-style reciprocal square root */
|
||||
inline uniform float rsqrtf(const uniform float f) { return rsqrt(f); }
|
||||
|
||||
/*! square. */
|
||||
inline float sqr(const float f) { return f*f; }
|
||||
/*! square. */
|
||||
inline uniform float sqr(const uniform float f) { return f*f; }
|
||||
/*! c-style square. */
|
||||
inline float sqrf(const float f) { return f*f; }
|
||||
/*! c-style square */
|
||||
inline uniform float sqrf(const uniform float f) { return f*f; }
|
||||
|
||||
/*! c-style pow function. */
|
||||
inline float powf(const float a, const float b) { return pow(a,b); }
|
||||
/*! c-style pow function */
|
||||
inline uniform float powf(const uniform float a, const uniform float b) { return pow(a,b); }
|
||||
|
||||
|
||||
/*! c-style cos. */
|
||||
inline float cosf(const float f) { return cos(f); }
|
||||
/*! c-style cos */
|
||||
inline uniform float cosf(const uniform float f) { return cos(f); }
|
||||
|
||||
/*! c-style sin. */
|
||||
inline float sinf(const float f) { return sin(f); }
|
||||
/*! c-style sin */
|
||||
inline uniform float sinf(const uniform float f) { return sin(f); }
|
||||
|
||||
/*! c-style exp. */
|
||||
inline float expf(const float f) { return exp(f); }
|
||||
/*! c-style exp */
|
||||
inline uniform float expf(const uniform float f) { return exp(f); }
|
||||
|
||||
/*! c-style log. */
|
||||
inline float logf(const float f) { return log(f); }
|
||||
/*! c-style log */
|
||||
inline uniform float logf(const uniform float f) { return log(f); }
|
||||
|
||||
/*! c-style abs. */
|
||||
inline float absf(const float f) { return abs(f); }
|
||||
/*! c-style abs */
|
||||
inline uniform float absf(const uniform float f) { return abs(f); }
|
||||
|
||||
|
||||
// inline float clamp(const float f) { return max(min(1.f,f),0.f); }
|
||||
|
||||
inline uniform float rcp_safe(uniform float f) { return rcpf((abs(f) < 1e-8f) ? 1e-8f : f); }
|
||||
inline varying float rcp_safe(varying float f) { return rcpf((abs(f) < 1e-8f) ? 1e-8f : f); }
|
||||
|
||||
inline uniform float sqrt_safe(uniform float f) { return sqrt(max(f, 0.0f)); }
|
||||
inline varying float sqrt_safe(varying float f) { return sqrt(max(f, 0.0f)); }
|
||||
|
||||
inline uniform float clamp (const uniform float v) { return max(0.0f,min(v,1.0f)); }
|
||||
inline varying float clamp (const varying float v) { return max(0.0f,min(v,1.0f)); }
|
||||
|
||||
inline uniform float clamp (const uniform float v, const uniform float lower, const uniform float upper) { return max(lower,min(v,upper)); }
|
||||
inline varying float clamp (const varying float v, const varying float lower, const varying float upper) { return max(lower,min(v,upper)); }
|
||||
|
||||
inline uniform int clamp (const uniform int v, const uniform int lower, const uniform int upper) { return max(lower,min(v,upper)); }
|
||||
inline varying int clamp (const varying int v, const varying int lower, const varying int upper) { return max(lower,min(v,upper)); }
|
||||
|
||||
inline uniform float frac(const uniform float x) { return x - floor(x); }
|
||||
inline varying float frac(const varying float x) { return x - floor(x); }
|
||||
|
||||
inline uniform float deg2rad (const uniform float x) { return x * 1.74532925199432957692e-2f; }
|
||||
inline varying float deg2rad (const varying float x) { return x * 1.74532925199432957692e-2f; }
|
||||
|
||||
inline uniform float rad2deg (const uniform float x) { return x * 5.72957795130823208768e1f; }
|
||||
inline varying float rad2deg (const varying float x) { return x * 5.72957795130823208768e1f; }
|
||||
|
||||
inline float cos2sin(const float f) { return sqrt(max(0.f, 1.f - sqr(f))); }
|
||||
inline float sin2cos(const float f) { return cos2sin(f); }
|
||||
|
||||
inline uniform float nextafter(const uniform float a, const uniform float b)
|
||||
{
|
||||
//! Match the behavior of the C99 math.h function.
|
||||
if (a == b) return(b);
|
||||
|
||||
//! We will compute the smallest representable floating increment or decrement around 'a'.
|
||||
uniform float delta = (b > a) ? 1.0f : -1.0f;
|
||||
|
||||
//! Iteratively compute the positive or negative increment.
|
||||
while (a + 0.5f * delta != a) delta *= 0.5f;
|
||||
|
||||
//! Return the smallest number greater than 'a' or the largest number smaller than 'a'.
|
||||
return(a + delta);
|
||||
}
|
||||
|
||||
#define __define_lerp(TYPE) \
|
||||
inline TYPE lerp(float factor, TYPE a, TYPE b) \
|
||||
{ \
|
||||
return (1-factor)* a + factor * b; \
|
||||
} \
|
||||
inline uniform TYPE lerp(uniform float factor, uniform TYPE a, uniform TYPE b) \
|
||||
{ \
|
||||
return (1-factor)* a + factor * b; \
|
||||
}
|
||||
|
||||
|
||||
__define_lerp(int8)
|
||||
__define_lerp(int32)
|
||||
__define_lerp(float)
|
||||
__define_lerp(uint8)
|
||||
__define_lerp(uint32)
|
||||
|
||||
#undef __define_lerp
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// min4/max4, for all types
|
||||
// ------------------------------------------------------------------
|
||||
#define __define_op4T(MM,TYPE) \
|
||||
inline uniform TYPE MM##4(uniform TYPE a, uniform TYPE b, \
|
||||
uniform TYPE c, uniform TYPE d) \
|
||||
{ \
|
||||
return MM(a, MM(b, MM(c, d))); \
|
||||
} \
|
||||
inline varying TYPE MM##4(varying TYPE a, varying TYPE b, \
|
||||
varying TYPE c, varying TYPE d) \
|
||||
{ \
|
||||
return MM(a, MM(b, MM(c, d))); \
|
||||
}
|
||||
|
||||
#define __define_op4(MM) \
|
||||
__define_op4T(MM,int8) \
|
||||
__define_op4T(MM,int32) \
|
||||
__define_op4T(MM,uint8) \
|
||||
__define_op4T(MM,uint32) \
|
||||
__define_op4T(MM,float) \
|
||||
__define_op4T(MM,double)
|
||||
|
||||
__define_op4(min)
|
||||
__define_op4(max)
|
||||
|
||||
#undef __define_op4T
|
||||
#undef __define_op4
|
||||
|
||||
#define SIMILAR_EPSILON .00001f
|
||||
inline float similar(float a, float b)
|
||||
{
|
||||
return absf(a - b) <= SIMILAR_EPSILON;
|
||||
}
|
||||
|
||||
inline uniform float similar(uniform float a, uniform float b)
|
||||
{
|
||||
return absf(a - b) <= SIMILAR_EPSILON;
|
||||
}
|
||||
#undef SIMILAR_EPSILON
|
||||
7
Framework/external/embree/tutorials/common/math/quaternion.h
vendored
Normal file
7
Framework/external/embree/tutorials/common/math/quaternion.h
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../../common/math/quaternion.h"
|
||||
|
||||
124
Framework/external/embree/tutorials/common/math/quaternion.isph
vendored
Normal file
124
Framework/external/embree/tutorials/common/math/quaternion.isph
vendored
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vec.isph"
|
||||
|
||||
struct Quaternion3f
|
||||
{
|
||||
float r, i, j, k;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Constructors
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline uniform Quaternion3f make_Quaternion3f(const uniform Vec4f& v) {
|
||||
uniform Quaternion3f q; q.r = v.x; q.i = v.y; q.j = v.z; q.k = v.w; return q;
|
||||
}
|
||||
inline varying Quaternion3f make_Quaternion3f(const varying Vec4f& v) {
|
||||
Quaternion3f q; q.r = v.x; q.i = v.y; q.j = v.z; q.k = v.w; return q;
|
||||
}
|
||||
|
||||
/*! return quaternion for rotation around arbitrary axis */
|
||||
inline varying Quaternion3f make_Quaternion3f_rotate(const varying Vec3f& u, const varying float r) {
|
||||
Quaternion3f q;
|
||||
Vec3f uu = sin(0.5*r)*normalize(u);
|
||||
|
||||
q.r = cos(0.5*r);
|
||||
q.i = uu.x;
|
||||
q.j = uu.y;
|
||||
q.k = uu.z;
|
||||
return q;
|
||||
}
|
||||
|
||||
/*! return quaternion for rotation around arbitrary axis */
|
||||
inline uniform Quaternion3f make_Quaternion3f_rotate(const uniform Vec3f& u, const uniform float r) {
|
||||
uniform Quaternion3f q;
|
||||
uniform Vec3f uu = sin(0.5*r)*normalize(u);
|
||||
|
||||
q.r = cos(0.5*r);
|
||||
q.i = uu.x;
|
||||
q.j = uu.y;
|
||||
q.k = uu.z;
|
||||
return q;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
inline uniform Quaternion3f operator*(const uniform float a, const uniform Quaternion3f& q) { return make_Quaternion3f(a * make_Vec4f(q.r, q.i, q.j, q.k)); }
|
||||
inline uniform Quaternion3f operator*(const uniform Quaternion3f& q, const uniform float a) { return make_Quaternion3f(a * make_Vec4f(q.r, q.i, q.j, q.k)); }
|
||||
inline varying Quaternion3f operator*(const varying float a, const uniform Quaternion3f& q) { return make_Quaternion3f(a * make_Vec4f(q.r, q.i, q.j, q.k)); }
|
||||
inline varying Quaternion3f operator*(const uniform Quaternion3f& q, const varying float a) { return make_Quaternion3f(a * make_Vec4f(q.r, q.i, q.j, q.k)); }
|
||||
inline varying Quaternion3f operator*(const varying float a, const varying Quaternion3f& q) { return make_Quaternion3f(a * make_Vec4f(q.r, q.i, q.j, q.k)); }
|
||||
inline varying Quaternion3f operator*(const varying Quaternion3f& q, const varying float a) { return make_Quaternion3f(a * make_Vec4f(q.r, q.i, q.j, q.k)); }
|
||||
inline uniform Quaternion3f operator+(const uniform Quaternion3f& q0, const uniform Quaternion3f& q1) { return make_Quaternion3f(make_Vec4f(q0.r+q1.r, q0.i+q1.i, q0.j+q1.j, q0.k+q1.k)); }
|
||||
inline uniform Quaternion3f operator-(const uniform Quaternion3f& q0, const uniform Quaternion3f& q1) { return make_Quaternion3f(make_Vec4f(q0.r-q1.r, q0.i-q1.i, q0.j-q1.j, q0.k-q1.k)); }
|
||||
inline varying Quaternion3f operator+(const varying Quaternion3f& q0, const varying Quaternion3f& q1) { return make_Quaternion3f(make_Vec4f(q0.r+q1.r, q0.i+q1.i, q0.j+q1.j, q0.k+q1.k)); }
|
||||
inline varying Quaternion3f operator-(const varying Quaternion3f& q0, const varying Quaternion3f& q1) { return make_Quaternion3f(make_Vec4f(q0.r-q1.r, q0.i-q1.i, q0.j-q1.j, q0.k-q1.k)); }
|
||||
|
||||
inline uniform float dot(const uniform Quaternion3f& q0, const uniform Quaternion3f& q1) { return q0.r*q1.r + q0.i*q1.i + q0.j*q1.j + q0.k*q1.k; }
|
||||
inline varying float dot(const varying Quaternion3f& q0, const varying Quaternion3f& q1) { return q0.r*q1.r + q0.i*q1.i + q0.j*q1.j + q0.k*q1.k; }
|
||||
inline uniform Quaternion3f normalize(const uniform Quaternion3f& q) { uniform const float len = sqrt(dot(q, q)); return make_Quaternion3f(make_Vec4f(q.r/len, q.i/len, q.j/len, q.k/len)); }
|
||||
inline varying Quaternion3f normalize(const varying Quaternion3f& q) { varying const float len = sqrt(dot(q, q)); return make_Quaternion3f(make_Vec4f(q.r/len, q.i/len, q.j/len, q.k/len)); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Comparison Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Interpolation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline uniform Quaternion3f lerp(const uniform factor, const uniform Quaternion3f& a, const uniform Quaternion3f& b) {
|
||||
return make_Quaternion3f(lerp(factor, make_Vec4f(a.r, a.i, a.j, a.k), make_Vec4f(b.r, b.i, b.j, b.k)));
|
||||
}
|
||||
|
||||
inline varying Quaternion3f lerp(const varying factor, const uniform Quaternion3f& a, const uniform Quaternion3f& b) {
|
||||
return make_Quaternion3f(lerp(factor, make_Vec4f(a.r, a.i, a.j, a.k), make_Vec4f(b.r, b.i, b.j, b.k)));
|
||||
}
|
||||
|
||||
inline uniform Quaternion3f slerp(const uniform float factor, const uniform Quaternion3f& q1, const uniform Quaternion3f& q2)
|
||||
{
|
||||
uniform const float cosTheta = dot(q1, q2);
|
||||
if (cosTheta > .9995f)
|
||||
return normalize((1 - factor) * q1 + factor * q2);
|
||||
else {
|
||||
uniform const float theta = acos(clamp(cosTheta, -1.f, 1.f));
|
||||
uniform const float thetap = theta * factor;
|
||||
uniform Quaternion3f qperp = normalize(q2 - q1 * cosTheta);
|
||||
return q1 * cos(thetap) + qperp * sin(thetap);
|
||||
}
|
||||
}
|
||||
|
||||
inline varying Quaternion3f slerp(const varying float factor, const uniform Quaternion3f& q1, const uniform Quaternion3f& q2)
|
||||
{
|
||||
uniform const float cosTheta = dot(q1, q2);
|
||||
if (cosTheta > .9995f)
|
||||
return normalize((1 - factor) * q1 + factor * q2);
|
||||
else {
|
||||
const float theta = acos(clamp(cosTheta, -1.f, 1.f));
|
||||
const float thetap = theta * factor;
|
||||
Quaternion3f qperp = normalize(q2 - q1 * cosTheta);
|
||||
return q1 * cos(thetap) + qperp * sin(thetap);
|
||||
}
|
||||
}
|
||||
|
||||
inline varying Quaternion3f slerp(const varying float factor, const varying Quaternion3f& q1, const varying Quaternion3f& q2)
|
||||
{
|
||||
const float cosTheta = dot(q1, q2);
|
||||
if (cosTheta > .9995f)
|
||||
return normalize((1 - factor) * q1 + factor * q2);
|
||||
else {
|
||||
const float theta = acos(clamp(cosTheta, -1.f, 1.f));
|
||||
const float thetap = theta * factor;
|
||||
Quaternion3f qperp = normalize(q2 - q1 * cosTheta);
|
||||
return q1 * cos(thetap) + qperp * sin(thetap);
|
||||
}
|
||||
}
|
||||
114
Framework/external/embree/tutorials/common/math/random_sampler.h
vendored
Normal file
114
Framework/external/embree/tutorials/common/math/random_sampler.h
vendored
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../math/vec.h"
|
||||
|
||||
namespace embree {
|
||||
|
||||
struct RandomSampler
|
||||
{
|
||||
unsigned int s;
|
||||
};
|
||||
|
||||
__forceinline unsigned int MurmurHash3_mix(unsigned int hash, unsigned int k)
|
||||
{
|
||||
const unsigned int c1 = 0xcc9e2d51;
|
||||
const unsigned int c2 = 0x1b873593;
|
||||
const unsigned int r1 = 15;
|
||||
const unsigned int r2 = 13;
|
||||
const unsigned int m = 5;
|
||||
const unsigned int n = 0xe6546b64;
|
||||
|
||||
k *= c1;
|
||||
k = (k << r1) | (k >> (32 - r1));
|
||||
k *= c2;
|
||||
|
||||
hash ^= k;
|
||||
hash = ((hash << r2) | (hash >> (32 - r2))) * m + n;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
__forceinline unsigned int MurmurHash3_finalize(unsigned int hash)
|
||||
{
|
||||
hash ^= hash >> 16;
|
||||
hash *= 0x85ebca6b;
|
||||
hash ^= hash >> 13;
|
||||
hash *= 0xc2b2ae35;
|
||||
hash ^= hash >> 16;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
__forceinline unsigned int LCG_next(unsigned int value)
|
||||
{
|
||||
const unsigned int m = 1664525;
|
||||
const unsigned int n = 1013904223;
|
||||
|
||||
return value * m + n;
|
||||
}
|
||||
|
||||
__forceinline void RandomSampler_init(RandomSampler& self, int id)
|
||||
{
|
||||
unsigned int hash = 0;
|
||||
hash = MurmurHash3_mix(hash, id);
|
||||
hash = MurmurHash3_finalize(hash);
|
||||
|
||||
self.s = hash;
|
||||
}
|
||||
|
||||
__forceinline void RandomSampler_init(RandomSampler& self, int pixelId, int sampleId)
|
||||
{
|
||||
unsigned int hash = 0;
|
||||
hash = MurmurHash3_mix(hash, pixelId);
|
||||
hash = MurmurHash3_mix(hash, sampleId);
|
||||
hash = MurmurHash3_finalize(hash);
|
||||
|
||||
self.s = hash;
|
||||
}
|
||||
|
||||
__forceinline void RandomSampler_init(RandomSampler& self, int x, int y, int sampleId)
|
||||
{
|
||||
RandomSampler_init(self, x | (y << 16), sampleId);
|
||||
}
|
||||
|
||||
__forceinline int RandomSampler_getInt(RandomSampler& self) {
|
||||
self.s = LCG_next(self.s); return self.s >> 1;
|
||||
}
|
||||
|
||||
__forceinline unsigned int RandomSampler_getUInt(RandomSampler& self) {
|
||||
self.s = LCG_next(self.s); return self.s;
|
||||
}
|
||||
|
||||
__forceinline float RandomSampler_getFloat(RandomSampler& self) {
|
||||
return (float)RandomSampler_getInt(self) * 4.656612873077392578125e-10f;
|
||||
}
|
||||
|
||||
__forceinline float RandomSampler_get1D(RandomSampler& self) {
|
||||
return RandomSampler_getFloat(self);
|
||||
}
|
||||
|
||||
__forceinline Vec2f RandomSampler_get2D(RandomSampler& self)
|
||||
{
|
||||
const float u = RandomSampler_get1D(self);
|
||||
const float v = RandomSampler_get1D(self);
|
||||
return Vec2f(u,v);
|
||||
}
|
||||
|
||||
__forceinline Vec3fa RandomSampler_get3D(RandomSampler& self)
|
||||
{
|
||||
/*
|
||||
const float u = RandomSampler_get1D(self);
|
||||
const float v = RandomSampler_get1D(self);
|
||||
const float w = RandomSampler_get1D(self);
|
||||
return Vec3fa(u,v,w);
|
||||
*/
|
||||
const int u = RandomSampler_getUInt(self);
|
||||
const int v = RandomSampler_getUInt(self);
|
||||
const int w = RandomSampler_getUInt(self);
|
||||
return Vec3fa(srl(Vec3ia(u,v,w), 1)) * 4.656612873077392578125e-10f;
|
||||
}
|
||||
|
||||
} // namespace embree
|
||||
104
Framework/external/embree/tutorials/common/math/random_sampler.isph
vendored
Normal file
104
Framework/external/embree/tutorials/common/math/random_sampler.isph
vendored
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../math/vec.isph"
|
||||
|
||||
struct RandomSampler
|
||||
{
|
||||
unsigned int s;
|
||||
};
|
||||
|
||||
inline unsigned int MurmurHash3_mix(unsigned int hash, unsigned int k)
|
||||
{
|
||||
const unsigned int c1 = 0xcc9e2d51;
|
||||
const unsigned int c2 = 0x1b873593;
|
||||
const unsigned int r1 = 15;
|
||||
const unsigned int r2 = 13;
|
||||
const unsigned int m = 5;
|
||||
const unsigned int n = 0xe6546b64;
|
||||
|
||||
k *= c1;
|
||||
k = (k << r1) | (k >> (32 - r1));
|
||||
k *= c2;
|
||||
|
||||
hash ^= k;
|
||||
hash = ((hash << r2) | (hash >> (32 - r2))) * m + n;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
inline unsigned int MurmurHash3_finalize(unsigned int hash)
|
||||
{
|
||||
hash ^= hash >> 16;
|
||||
hash *= 0x85ebca6b;
|
||||
hash ^= hash >> 13;
|
||||
hash *= 0xc2b2ae35;
|
||||
hash ^= hash >> 16;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
inline unsigned int LCG_next(unsigned int value)
|
||||
{
|
||||
const unsigned int m = 1664525;
|
||||
const unsigned int n = 1013904223;
|
||||
|
||||
return value * m + n;
|
||||
}
|
||||
|
||||
inline void RandomSampler_init(RandomSampler& self, int id)
|
||||
{
|
||||
unsigned int hash = 0;
|
||||
hash = MurmurHash3_mix(hash, id);
|
||||
hash = MurmurHash3_finalize(hash);
|
||||
|
||||
self.s = hash;
|
||||
}
|
||||
|
||||
inline void RandomSampler_init(RandomSampler& self, int pixelId, int sampleId)
|
||||
{
|
||||
unsigned int hash = 0;
|
||||
hash = MurmurHash3_mix(hash, pixelId);
|
||||
hash = MurmurHash3_mix(hash, sampleId);
|
||||
hash = MurmurHash3_finalize(hash);
|
||||
|
||||
self.s = hash;
|
||||
}
|
||||
|
||||
inline void RandomSampler_init(RandomSampler& self, int x, int y, int sampleId)
|
||||
{
|
||||
RandomSampler_init(self, x | (y << 16), sampleId);
|
||||
}
|
||||
|
||||
inline int RandomSampler_getInt(RandomSampler& self) {
|
||||
self.s = LCG_next(self.s); return self.s >> 1;
|
||||
}
|
||||
|
||||
inline unsigned int RandomSampler_getUInt(RandomSampler& self) {
|
||||
self.s = LCG_next(self.s); return self.s;
|
||||
}
|
||||
|
||||
inline float RandomSampler_getFloat(RandomSampler& self) {
|
||||
return (float)RandomSampler_getInt(self) * 4.656612873077392578125e-10f;
|
||||
}
|
||||
|
||||
inline float RandomSampler_get1D(RandomSampler& self) {
|
||||
return RandomSampler_getFloat(self);
|
||||
}
|
||||
|
||||
inline Vec2f RandomSampler_get2D(RandomSampler& self)
|
||||
{
|
||||
const float u = RandomSampler_get1D(self);
|
||||
const float v = RandomSampler_get1D(self);
|
||||
return make_Vec2f(u,v);
|
||||
}
|
||||
|
||||
inline Vec3fa RandomSampler_get3D(RandomSampler& self)
|
||||
{
|
||||
const float u = RandomSampler_get1D(self);
|
||||
const float v = RandomSampler_get1D(self);
|
||||
const float w = RandomSampler_get1D(self);
|
||||
return make_Vec3fa(u,v,w);
|
||||
}
|
||||
159
Framework/external/embree/tutorials/common/math/sampling.h
vendored
Normal file
159
Framework/external/embree/tutorials/common/math/sampling.h
vendored
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
/*! \brief utility library containing sampling functions */
|
||||
|
||||
// convention is to return the sample (Vec3fa) generated from given Vec2f 's'ample as last parameter
|
||||
// sampling functions often come in pairs: sample and pdf (needed later for MIS)
|
||||
// good reference is "Total Compendium" by Philip Dutre http://people.cs.kuleuven.be/~philip.dutre/GI/
|
||||
|
||||
#include "../math/vec.h"
|
||||
#include "../math/linearspace.h"
|
||||
|
||||
namespace embree {
|
||||
|
||||
struct Sample3f
|
||||
{
|
||||
Vec3fa v;
|
||||
float pdf;
|
||||
};
|
||||
|
||||
inline Sample3f make_Sample3f(const Vec3fa& v, const float pdf) {
|
||||
Sample3f s; s.v = v; s.pdf = pdf; return s;
|
||||
}
|
||||
|
||||
#if defined(ISPC)
|
||||
inline Sample3f make_Sample3f(const Vec3fa& v, const float pdf) {
|
||||
Sample3f s; s.v = v; s.pdf = pdf; return s;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline Vec3fa cartesian(const float phi, const float sinTheta, const float cosTheta)
|
||||
{
|
||||
const float sinPhi = sinf(phi);
|
||||
const float cosPhi = cosf(phi);
|
||||
//sincosf(phi, &sinPhi, &cosPhi);
|
||||
return Vec3fa(cosPhi * sinTheta,
|
||||
sinPhi * sinTheta,
|
||||
cosTheta);
|
||||
}
|
||||
|
||||
inline Vec3fa cartesian(const float phi, const float cosTheta)
|
||||
{
|
||||
return cartesian(phi, cos2sin(cosTheta), cosTheta);
|
||||
}
|
||||
|
||||
|
||||
/// cosine-weighted sampling of hemisphere oriented along the +z-axis
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline Vec3fa cosineSampleHemisphere(const Vec2f s)
|
||||
{
|
||||
const float phi = 2.0f * float(M_PI) * s.x;
|
||||
const float cosTheta = sqrt(s.y);
|
||||
const float sinTheta = sqrt(1.0f - s.y);
|
||||
return cartesian(phi, sinTheta, cosTheta);
|
||||
}
|
||||
|
||||
inline float cosineSampleHemispherePDF(const Vec3fa &dir)
|
||||
{
|
||||
return dir.z / float(M_PI);
|
||||
}
|
||||
|
||||
inline float cosineSampleHemispherePDF(float cosTheta)
|
||||
{
|
||||
return cosTheta / float(M_PI);
|
||||
}
|
||||
|
||||
/*! Cosine weighted hemisphere sampling. Up direction is provided as argument. */
|
||||
inline Sample3f cosineSampleHemisphere(const float u, const float v, const Vec3fa& N)
|
||||
{
|
||||
Vec3fa localDir = cosineSampleHemisphere(Vec2f(u,v));
|
||||
Sample3f s;
|
||||
s.v = frame(N) * localDir;
|
||||
s.pdf = cosineSampleHemispherePDF(localDir);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// power cosine-weighted sampling of hemisphere oriented along the +z-axis
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline Vec3fa powerCosineSampleHemisphere(const float n, const Vec2f &s)
|
||||
{
|
||||
const float phi =float(two_pi) * s.x;
|
||||
const float cosTheta = pow(s.y, 1.0f / (n + 1.0f));
|
||||
return cartesian(phi, cosTheta);
|
||||
}
|
||||
|
||||
inline float powerCosineSampleHemispherePDF(const float cosTheta, const float n) // TODO: order of arguments
|
||||
{
|
||||
return (n + 1.0f) * (0.5f / float(M_PI)) * pow(cosTheta, n);
|
||||
}
|
||||
|
||||
inline float powerCosineSampleHemispherePDF(const Vec3fa& dir, const float n) // TODO: order of arguments
|
||||
{
|
||||
return (n + 1.0f) * (0.5f / float(M_PI)) * pow(dir.z, n);
|
||||
}
|
||||
|
||||
/// sampling of cone of directions oriented along the +z-axis
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline Vec3fa uniformSampleCone(const float cosAngle, const Vec2f &s)
|
||||
{
|
||||
const float phi =float(two_pi) * s.x;
|
||||
const float cosTheta = 1.0f - s.y * (1.0f - cosAngle);
|
||||
return cartesian(phi, cosTheta);
|
||||
}
|
||||
|
||||
inline float uniformSampleConePDF(const float cosAngle)
|
||||
{
|
||||
return rcp(float(two_pi)*(1.0f - cosAngle));
|
||||
}
|
||||
|
||||
inline float _uniformSampleConePDF(const float cosAngle)
|
||||
{
|
||||
return rcp(float(two_pi)*(1.0f - cosAngle));
|
||||
}
|
||||
|
||||
|
||||
/// sampling of disk
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline Vec3fa uniformSampleDisk(const float radius, const Vec2f &s)
|
||||
{
|
||||
const float r = sqrtf(s.x) * radius;
|
||||
const float phi =float(two_pi) * s.y;
|
||||
const float sinPhi = sinf(phi);
|
||||
const float cosPhi = cosf(phi);
|
||||
//sincosf(phi, &sinPhi, &cosPhi);
|
||||
return Vec3fa(r * cosPhi, r * sinPhi, 0.f);
|
||||
}
|
||||
|
||||
inline float uniformSampleDiskPDF(const float radius)
|
||||
{
|
||||
return rcp(float(M_PI) * sqr(radius));
|
||||
}
|
||||
|
||||
inline float _uniformSampleDiskPDF(const float radius)
|
||||
{
|
||||
return rcp(float(M_PI) * sqr(radius));
|
||||
}
|
||||
|
||||
|
||||
/// sampling of triangle abc
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline Vec3fa uniformSampleTriangle(const Vec3fa &a, const Vec3fa &b, const Vec3fa &c, const Vec2f &s)
|
||||
{
|
||||
const float su = sqrtf(s.x);
|
||||
return c + (1.0f - su) * (a-c) + (s.y*su) * (b-c);
|
||||
}
|
||||
|
||||
inline float uniformSampleTrianglePDF(const Vec3fa &a, const Vec3fa &b, const Vec3fa &c)
|
||||
{
|
||||
return 2.0f * rcp(abs(length(cross(a-c, b-c))));
|
||||
}
|
||||
|
||||
} // namespace embree
|
||||
155
Framework/external/embree/tutorials/common/math/sampling.isph
vendored
Normal file
155
Framework/external/embree/tutorials/common/math/sampling.isph
vendored
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
/*! \brief utility library containing sampling functions */
|
||||
|
||||
// convention is to return the sample (Vec3f) generated from given Vec2f 's'ample as last parameter
|
||||
// sampling functions often come in pairs: sample and pdf (needed later for MIS)
|
||||
// good reference is "Total Compendium" by Philip Dutre http://people.cs.kuleuven.be/~philip.dutre/GI/
|
||||
|
||||
#include "../math/vec.isph"
|
||||
#include "../math/linearspace.isph"
|
||||
|
||||
struct Sample3f
|
||||
{
|
||||
Vec3f v;
|
||||
float pdf;
|
||||
};
|
||||
|
||||
inline uniform Sample3f make_Sample3f(const uniform Vec3f& v, const uniform float pdf) {
|
||||
uniform Sample3f s; s.v = v; s.pdf = pdf; return s;
|
||||
}
|
||||
|
||||
#if defined(ISPC)
|
||||
inline Sample3f make_Sample3f(const Vec3f& v, const float pdf) {
|
||||
Sample3f s; s.v = v; s.pdf = pdf; return s;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline Vec3f cartesian(const float phi, const float sinTheta, const float cosTheta)
|
||||
{
|
||||
const float sinPhi = sinf(phi);
|
||||
const float cosPhi = cosf(phi);
|
||||
//sincos(phi, &sinPhi, &cosPhi);
|
||||
return make_Vec3f(cosPhi * sinTheta,
|
||||
sinPhi * sinTheta,
|
||||
cosTheta);
|
||||
}
|
||||
|
||||
inline Vec3f cartesian(const float phi, const float cosTheta)
|
||||
{
|
||||
return cartesian(phi, cos2sin(cosTheta), cosTheta);
|
||||
}
|
||||
|
||||
|
||||
/// cosine-weighted sampling of hemisphere oriented along the +z-axis
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline Vec3f cosineSampleHemisphere(const Vec2f s)
|
||||
{
|
||||
const float phi = 2.0f * M_PI * s.x;
|
||||
const float cosTheta = sqrt(s.y);
|
||||
const float sinTheta = sqrt(1.0f - s.y);
|
||||
return cartesian(phi, sinTheta, cosTheta);
|
||||
}
|
||||
|
||||
inline float cosineSampleHemispherePDF(const Vec3f &dir)
|
||||
{
|
||||
return dir.z / M_PI;
|
||||
}
|
||||
|
||||
inline float cosineSampleHemispherePDF(float cosTheta)
|
||||
{
|
||||
return cosTheta / M_PI;
|
||||
}
|
||||
|
||||
/*! Cosine weighted hemisphere sampling. Up direction is provided as argument. */
|
||||
inline Sample3f cosineSampleHemisphere(const float u, const float v, const Vec3f& N)
|
||||
{
|
||||
Vec3f localDir = cosineSampleHemisphere(make_Vec2f(u,v));
|
||||
Sample3f s;
|
||||
s.v = frame(N) * localDir;
|
||||
s.pdf = cosineSampleHemispherePDF(localDir);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// power cosine-weighted sampling of hemisphere oriented along the +z-axis
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline Vec3f powerCosineSampleHemisphere(const float n, const Vec2f &s)
|
||||
{
|
||||
const float phi = two_pi * s.x;
|
||||
const float cosTheta = pow(s.y, 1.0f / (n + 1.0f));
|
||||
return cartesian(phi, cosTheta);
|
||||
}
|
||||
|
||||
inline float powerCosineSampleHemispherePDF(const float cosTheta, const float n) // TODO: order of arguments
|
||||
{
|
||||
return (n + 1.0f) * (0.5f / M_PI) * pow(cosTheta, n);
|
||||
}
|
||||
|
||||
inline float powerCosineSampleHemispherePDF(const Vec3f& dir, const float n) // TODO: order of arguments
|
||||
{
|
||||
return (n + 1.0f) * (0.5f / M_PI) * pow(dir.z, n);
|
||||
}
|
||||
|
||||
/// uniform sampling of cone of directions oriented along the +z-axis
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline Vec3f uniformSampleCone(const float cosAngle, const Vec2f &s)
|
||||
{
|
||||
const float phi = two_pi * s.x;
|
||||
const float cosTheta = 1.0f - s.y * (1.0f - cosAngle);
|
||||
return cartesian(phi, cosTheta);
|
||||
}
|
||||
|
||||
inline float uniformSampleConePDF(const float cosAngle)
|
||||
{
|
||||
return rcp(two_pi*(1.0f - cosAngle));
|
||||
}
|
||||
|
||||
inline uniform float uniformSampleConePDF(const uniform float cosAngle)
|
||||
{
|
||||
return rcp(two_pi*(1.0f - cosAngle));
|
||||
}
|
||||
|
||||
|
||||
/// uniform sampling of disk
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline Vec3f uniformSampleDisk(const float radius, const Vec2f &s)
|
||||
{
|
||||
const float r = sqrtf(s.x) * radius;
|
||||
const float phi = two_pi * s.y;
|
||||
const float sinPhi = sinf(phi);
|
||||
const float cosPhi = cosf(phi);
|
||||
//sincos(phi, &sinPhi, &cosPhi);
|
||||
return make_Vec3f(r * cosPhi, r * sinPhi, 0.f);
|
||||
}
|
||||
|
||||
inline float uniformSampleDiskPDF(const float radius)
|
||||
{
|
||||
return rcp(M_PI * sqr(radius));
|
||||
}
|
||||
|
||||
inline uniform float uniformSampleDiskPDF(const uniform float radius)
|
||||
{
|
||||
return rcp(M_PI * sqr(radius));
|
||||
}
|
||||
|
||||
|
||||
/// uniform sampling of triangle abc
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline Vec3f uniformSampleTriangle(const Vec3f &a, const Vec3f &b, const Vec3f &c, const Vec2f &s)
|
||||
{
|
||||
const float su = sqrtf(s.x);
|
||||
return c + (1.0f - su) * (a-c) + (s.y*su) * (b-c);
|
||||
}
|
||||
|
||||
inline float uniformSampleTrianglePDF(const Vec3f &a, const Vec3f &b, const Vec3f &c)
|
||||
{
|
||||
return 2.0f * rcp(abs(length(cross(a-c, b-c))));
|
||||
}
|
||||
87
Framework/external/embree/tutorials/common/math/vec.h
vendored
Normal file
87
Framework/external/embree/tutorials/common/math/vec.h
vendored
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../../common/math/vec2.h"
|
||||
#include "../../../common/math/vec3.h"
|
||||
#include "../../../common/math/vec4.h"
|
||||
|
||||
namespace embree {
|
||||
|
||||
__forceinline Vec3f neg(const Vec3f& a ) { return -a; }
|
||||
__forceinline Vec3fa neg(const Vec3fa& a) { return -a; }
|
||||
__forceinline bool eq (const Vec3fa& a, const Vec3fa& b) { return a == b; }
|
||||
__forceinline bool ne (const Vec3fa& a, const Vec3fa& b) { return a != b; }
|
||||
|
||||
// FIXME: change order of lerp arguments, then remove this function
|
||||
template<typename V>
|
||||
__forceinline V lerpr(float t, const V& v0, const V& v1) {
|
||||
return (1.0f-t)*v0 + t*v1;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------
|
||||
// sRGB conversion functions
|
||||
// -------------------------------------------------------
|
||||
#define APPROXIMATE_SRGB
|
||||
|
||||
inline float linear_to_srgb(const float f)
|
||||
{
|
||||
const float c = max(f, 0.f);
|
||||
#ifdef APPROXIMATE_SRGB
|
||||
return pow(c, 1.f/2.2f);
|
||||
#else
|
||||
return c <= 0.0031308f ? 12.92f*c : pow(c, 1.f/2.4f)*1.055f - 0.055f;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline Vec4f linear_to_srgba(const Vec4f c)
|
||||
{
|
||||
return Vec4f(linear_to_srgb(c.x),
|
||||
linear_to_srgb(c.y),
|
||||
linear_to_srgb(c.z),
|
||||
max(c.w, 0.f)); // alpha is never gamma-corrected
|
||||
}
|
||||
|
||||
inline uint32_t linear_to_srgba8(const Vec4f c)
|
||||
{
|
||||
#if 1
|
||||
Vec4f l = 255.f * min(linear_to_srgba(c), Vec4f(1.f));
|
||||
return
|
||||
((uint32_t)l.x << 0) |
|
||||
((uint32_t)l.y << 8) |
|
||||
((uint32_t)l.z << 16) |
|
||||
((uint32_t)l.w << 24);
|
||||
#else
|
||||
// TODO use ISPC's float_to_srgb8 once it is fixed (issue #1198)
|
||||
return
|
||||
(float_to_srgb8(c.x) << 0) |
|
||||
(float_to_srgb8(c.y) << 8) |
|
||||
(float_to_srgb8(c.z) << 16) |
|
||||
((uint32_t)clamp(c.w, 0.f, 1.f) << 24); // alpha is never gamma-corrected
|
||||
#endif
|
||||
}
|
||||
|
||||
inline float srgb_to_linear(const float f)
|
||||
{
|
||||
const float c = max(f, 0.f);
|
||||
#ifdef APPROXIMATE_SRGB
|
||||
return pow(c, 2.2f);
|
||||
#else
|
||||
return c <= 0.04045f ? c/12.92f : pow((c + 0.055f)/1.055f, 2.4f);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline Vec4f srgba_to_linear(const Vec4f c)
|
||||
{
|
||||
return Vec4f(srgb_to_linear(c.x),
|
||||
srgb_to_linear(c.y),
|
||||
srgb_to_linear(c.z),
|
||||
max(c.w, 0.f)); // alpha is never gamma-corrected
|
||||
}
|
||||
|
||||
// TODO implement srgba8_to_linear with a 256 entry LUT
|
||||
|
||||
#undef APPROXIMATE_SRGB
|
||||
|
||||
} // namespace embree
|
||||
986
Framework/external/embree/tutorials/common/math/vec.isph
vendored
Normal file
986
Framework/external/embree/tutorials/common/math/vec.isph
vendored
Normal file
|
|
@ -0,0 +1,986 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "math.isph"
|
||||
|
||||
#define __define_ispc_vector2(TYPE,ABB) \
|
||||
struct Vec2##ABB { \
|
||||
TYPE x; TYPE y; \
|
||||
}; \
|
||||
|
||||
#define __define_ispc_vector3(TYPE,ABB) \
|
||||
struct Vec3##ABB { \
|
||||
TYPE x,y,z; \
|
||||
}; \
|
||||
struct Vec3##ABB##a { \
|
||||
TYPE x,y,z,w; \
|
||||
}; \
|
||||
|
||||
#define __define_ispc_vector4(TYPE,ABB) \
|
||||
struct Vec4##ABB { \
|
||||
TYPE x,y,z,w; \
|
||||
}; \
|
||||
|
||||
__define_ispc_vector2(int,i);
|
||||
__define_ispc_vector2(unsigned int,ui);
|
||||
__define_ispc_vector2(unsigned int8,uc);
|
||||
__define_ispc_vector2(float,f);
|
||||
|
||||
__define_ispc_vector3(int,i);
|
||||
__define_ispc_vector3(unsigned int,ui);
|
||||
__define_ispc_vector3(unsigned int8,uc);
|
||||
__define_ispc_vector3(float,f);
|
||||
|
||||
__define_ispc_vector4(int,i);
|
||||
__define_ispc_vector4(unsigned int,ui);
|
||||
__define_ispc_vector4(unsigned int8,uc);
|
||||
__define_ispc_vector4(float,f);
|
||||
|
||||
#undef __define_ispc_vector2
|
||||
#undef __define_ispc_vector3
|
||||
#undef __define_ispc_vector4
|
||||
|
||||
|
||||
|
||||
|
||||
/*! defines all constructors "make_Vec2[T]" for 2-vector type */
|
||||
#define __define_ispc_constructors2(UV,TYPE,ABB,ITYPE,IABB) \
|
||||
inline UV Vec2##ABB make_Vec2##ABB(const UV ITYPE x, \
|
||||
const UV ITYPE y) \
|
||||
{ \
|
||||
UV Vec2##ABB ret; \
|
||||
ret.x = x; \
|
||||
ret.y = y; \
|
||||
return ret; \
|
||||
} \
|
||||
inline UV Vec2##ABB make_Vec2##ABB(const UV ITYPE x) \
|
||||
{ \
|
||||
UV Vec2##ABB ret; \
|
||||
ret.x = x; \
|
||||
ret.y = x; \
|
||||
return ret; \
|
||||
} \
|
||||
|
||||
/*! defines all constructors "make_Vec3[T]" and "make_Vec3[T]a" for
|
||||
3-vector type */
|
||||
#define __define_ispc_constructors3(UV,TYPE,ABB,ITYPE,IABB) \
|
||||
inline UV Vec3##ABB make_Vec3##ABB(const UV ITYPE x) \
|
||||
{ \
|
||||
UV Vec3##ABB ret; \
|
||||
ret.x = x; \
|
||||
ret.y = x; \
|
||||
ret.z = x; \
|
||||
return ret; \
|
||||
} \
|
||||
inline UV Vec3##ABB make_Vec3##ABB(const UV Vec3##IABB v) \
|
||||
{ \
|
||||
UV Vec3##ABB ret; \
|
||||
ret.x = v.x; \
|
||||
ret.y = v.y; \
|
||||
ret.z = v.z; \
|
||||
return ret; \
|
||||
} \
|
||||
inline UV Vec3##ABB make_Vec3##ABB(const UV Vec3##IABB##a v) \
|
||||
{ \
|
||||
UV Vec3##ABB ret; \
|
||||
ret.x = v.x; \
|
||||
ret.y = v.y; \
|
||||
ret.z = v.z; \
|
||||
return ret; \
|
||||
} \
|
||||
inline UV Vec3##ABB make_Vec3##ABB(const UV ITYPE x, \
|
||||
const UV ITYPE y, \
|
||||
const UV ITYPE z) \
|
||||
{ \
|
||||
UV Vec3##ABB ret; \
|
||||
ret.x = x; \
|
||||
ret.y = y; \
|
||||
ret.z = z; \
|
||||
return ret; \
|
||||
} \
|
||||
inline UV Vec3##ABB make_Vec3##ABB(const UV Vec4##IABB v) \
|
||||
{ \
|
||||
UV Vec3##ABB ret; \
|
||||
ret.x = v.x; \
|
||||
ret.y = v.y; \
|
||||
ret.z = v.z; \
|
||||
return ret; \
|
||||
} \
|
||||
/* the '3a' variants */ \
|
||||
inline UV Vec3##ABB##a make_Vec3##ABB##a(const UV ITYPE x) \
|
||||
{ \
|
||||
UV Vec3##ABB##a ret; \
|
||||
ret.x = x; \
|
||||
ret.y = x; \
|
||||
ret.z = x; \
|
||||
ret.w = 0; \
|
||||
return ret; \
|
||||
} \
|
||||
inline UV Vec3##ABB##a make_Vec3##ABB##a(const UV Vec3##IABB &v) \
|
||||
{ \
|
||||
UV Vec3##ABB##a ret; \
|
||||
ret.x = v.x; \
|
||||
ret.y = v.y; \
|
||||
ret.z = v.z; \
|
||||
ret.w = 0; \
|
||||
return ret; \
|
||||
} \
|
||||
inline UV Vec3##ABB##a make_Vec3##ABB##a(const UV Vec3##IABB##a v) \
|
||||
{ \
|
||||
UV Vec3##ABB##a ret; \
|
||||
ret.x = v.x; \
|
||||
ret.y = v.y; \
|
||||
ret.z = v.z; \
|
||||
ret.w = v.w; \
|
||||
return ret; \
|
||||
} \
|
||||
inline UV Vec3##ABB##a make_Vec3##ABB##a(const UV ITYPE x, \
|
||||
const UV ITYPE y, \
|
||||
const UV ITYPE z) \
|
||||
{ \
|
||||
UV Vec3##ABB##a ret; \
|
||||
ret.x = x; \
|
||||
ret.y = y; \
|
||||
ret.z = z; \
|
||||
ret.w = 0; \
|
||||
return ret; \
|
||||
} \
|
||||
inline UV Vec3##ABB##a make_Vec3##ABB##a(const UV ITYPE x, \
|
||||
const UV ITYPE y, \
|
||||
const UV ITYPE z, \
|
||||
const UV ITYPE w) \
|
||||
{ \
|
||||
UV Vec3##ABB##a ret; \
|
||||
ret.x = x; \
|
||||
ret.y = y; \
|
||||
ret.z = z; \
|
||||
ret.w = w; \
|
||||
return ret; \
|
||||
} \
|
||||
inline UV Vec3##ABB##a make_Vec3##ABB##a(const UV Vec3##IABB &v, \
|
||||
const UV ITYPE w) \
|
||||
{ \
|
||||
UV Vec3##ABB##a ret; \
|
||||
ret.x = v.x; \
|
||||
ret.y = v.y; \
|
||||
ret.z = v.z; \
|
||||
ret.w = w; \
|
||||
return ret; \
|
||||
} \
|
||||
inline UV Vec3##ABB##a make_Vec3##ABB##a(const UV Vec4##IABB v) \
|
||||
{ \
|
||||
UV Vec3##ABB##a ret; \
|
||||
ret.x = v.x; \
|
||||
ret.y = v.y; \
|
||||
ret.z = v.z; \
|
||||
ret.w = v.w; \
|
||||
return ret; \
|
||||
} \
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*! defines all constructors "make_Vec4[T]" for 4-vector type */
|
||||
#define __define_ispc_constructors4(UV,TYPE,ABB,ITYPE,IABB) \
|
||||
/*! construct Vec4 from a single scalar */ \
|
||||
inline UV Vec4##ABB make_Vec4##ABB(const UV ITYPE f) \
|
||||
{ \
|
||||
UV Vec4##ABB ret; \
|
||||
ret.x = f; \
|
||||
ret.y = f; \
|
||||
ret.z = f; \
|
||||
ret.w = f; \
|
||||
return ret; \
|
||||
} \
|
||||
/*! construct Vec4 from a 4 scalars */ \
|
||||
inline UV Vec4##ABB make_Vec4##ABB(const UV ITYPE x, \
|
||||
const UV ITYPE y, \
|
||||
const UV ITYPE z, \
|
||||
const UV ITYPE w) \
|
||||
{ \
|
||||
UV Vec4##ABB ret; \
|
||||
ret.x = x; \
|
||||
ret.y = y; \
|
||||
ret.z = z; \
|
||||
ret.w = w; \
|
||||
return ret; \
|
||||
} \
|
||||
/*! construct Vec4 from another Vec4 (of another type) */ \
|
||||
inline UV Vec4##ABB make_Vec4##ABB(const UV Vec4##IABB v) \
|
||||
{ \
|
||||
UV Vec4##ABB ret; \
|
||||
ret.x = v.x; \
|
||||
ret.y = v.y; \
|
||||
ret.z = v.z; \
|
||||
ret.w = v.w; \
|
||||
return ret; \
|
||||
} \
|
||||
|
||||
|
||||
#define __define_ispc_lift_constructors4(UV,TYPE,ABB) \
|
||||
/*! lift Vec4 from Vec3; fill in with 0es */ \
|
||||
inline UV Vec4##ABB make_Vec4##ABB(const UV Vec3##ABB v) \
|
||||
{ \
|
||||
UV Vec4##ABB ret; \
|
||||
ret.x = (TYPE)v.x; \
|
||||
ret.y = (TYPE)v.y; \
|
||||
ret.z = (TYPE)v.z; \
|
||||
ret.w = (TYPE)0; \
|
||||
return ret; \
|
||||
} \
|
||||
|
||||
#define __define_ispc_constructors_uv_t(UV,OTYPE,OABB,ITYPE,IABB) \
|
||||
__define_ispc_constructors2(UV,OTYPE,OABB,ITYPE,IABB) \
|
||||
__define_ispc_constructors3(UV,OTYPE,OABB,ITYPE,IABB) \
|
||||
__define_ispc_constructors4(UV,OTYPE,OABB,ITYPE,IABB) \
|
||||
|
||||
#define __define_ispc_constructors_uv(UV,TYPE,ABB) \
|
||||
__define_ispc_constructors_uv_t(UV,TYPE,ABB,int,i) \
|
||||
__define_ispc_constructors_uv_t(UV,TYPE,ABB,unsigned int,ui) \
|
||||
__define_ispc_constructors_uv_t(UV,TYPE,ABB,unsigned int8,uc) \
|
||||
__define_ispc_constructors_uv_t(UV,TYPE,ABB,float,f) \
|
||||
__define_ispc_lift_constructors4(UV,TYPE,ABB) \
|
||||
|
||||
#define __define_ispc_constructors(UV) \
|
||||
__define_ispc_constructors_uv(UV,unsigned int,ui) \
|
||||
__define_ispc_constructors_uv(UV,unsigned int8,uc) \
|
||||
__define_ispc_constructors_uv(UV,int,i) \
|
||||
__define_ispc_constructors_uv(UV,float,f) \
|
||||
|
||||
__define_ispc_constructors(uniform);
|
||||
__define_ispc_constructors(varying);
|
||||
|
||||
#undef __define_ispc_constructors2
|
||||
#undef __define_ispc_constructors3
|
||||
#undef __define_ispc_constructors3a
|
||||
#undef __define_ispc_constructors4
|
||||
#undef __define_ispc_lift_constructors4
|
||||
#undef __define_ispc_constructors_uv
|
||||
#undef __define_ispc_constructors
|
||||
|
||||
|
||||
// =======================================================
|
||||
// define 'lifted' binary operators (min/max/...)
|
||||
|
||||
#define __lift_binaryFct(FCT,T) \
|
||||
/* ********************************************************* */ \
|
||||
/* ---- Vec2 ---- */ \
|
||||
/* ********************************************************* */ \
|
||||
/* uniform Vec2 FCT(uniform Vec2, uniform Vec2) */ \
|
||||
inline uniform Vec2##T FCT(const uniform Vec2##T a, \
|
||||
const uniform Vec2##T b) \
|
||||
{ return make_Vec2##T(FCT(a.x,b.x),FCT(a.y,b.y)); } \
|
||||
/* Vec2 FCT(Vec2, Vec2) */ \
|
||||
inline varying Vec2##T FCT(const varying Vec2##T a, \
|
||||
const varying Vec2##T b) \
|
||||
{ return make_Vec2##T(FCT(a.x,b.x),FCT(a.y,b.y)); } \
|
||||
/* Vec2 FCT(Vec2, uniform Vec2) */ \
|
||||
inline varying Vec2##T FCT(const varying Vec2##T a, \
|
||||
const uniform Vec2##T b) \
|
||||
{ return make_Vec2##T(FCT(a.x,b.x),FCT(a.y,b.y)); } \
|
||||
/* Vec2 FCT(uniform Vec2, Vec2) */ \
|
||||
inline varying Vec2##T FCT(const uniform Vec2##T a, \
|
||||
const varying Vec2##T b) \
|
||||
{ return make_Vec2##T(FCT(a.x,b.x),FCT(a.y,b.y)); } \
|
||||
\
|
||||
/* ********************************************************* */ \
|
||||
/* ---- Vec3 ---- */ \
|
||||
/* ********************************************************* */ \
|
||||
/* uniform Vec3 FCT(uniform Vec3, uniform Vec3) */ \
|
||||
inline uniform Vec3##T FCT(const uniform Vec3##T a, \
|
||||
const uniform Vec3##T b) \
|
||||
{ return make_Vec3##T(FCT(a.x,b.x),FCT(a.y,b.y),FCT(a.z,b.z)); } \
|
||||
/* Vec3 FCT(Vec3, Vec3) */ \
|
||||
inline varying Vec3##T FCT(const varying Vec3##T a, \
|
||||
const varying Vec3##T b) \
|
||||
{ return make_Vec3##T(FCT(a.x,b.x),FCT(a.y,b.y),FCT(a.z,b.z)); } \
|
||||
/* Vec3 FCT(uniformVec3, Vec3) */ \
|
||||
inline varying Vec3##T FCT(const uniform Vec3##T a, \
|
||||
const varying Vec3##T b) \
|
||||
{ return make_Vec3##T(FCT(a.x,b.x),FCT(a.y,b.y),FCT(a.z,b.z)); } \
|
||||
/* Vec3 FCT(Vec3, uniformVec3) */ \
|
||||
inline varying Vec3##T FCT(const varying Vec3##T a, \
|
||||
const uniform Vec3##T b) \
|
||||
{ return make_Vec3##T(FCT(a.x,b.x),FCT(a.y,b.y),FCT(a.z,b.z)); } \
|
||||
\
|
||||
/* ********************************************************* */ \
|
||||
/* ---- Vec3a (from 3a and 3a) ---- */ \
|
||||
/* ********************************************************* */ \
|
||||
/* uniform Vec3a FCT(uniform Vec3a, uniform Vec3a) */ \
|
||||
inline uniform Vec3##T##a FCT(const uniform Vec3##T##a a, \
|
||||
const uniform Vec3##T##a b) \
|
||||
{ return make_Vec3##T##a(FCT(a.x,b.x),FCT(a.y,b.y),FCT(a.z,b.z),FCT(a.w,b.w)); } \
|
||||
/* Vec3a FCT(Vec3a, Vec3a) */ \
|
||||
inline varying Vec3##T##a FCT(const varying Vec3##T##a a, \
|
||||
const varying Vec3##T##a b) \
|
||||
{ return make_Vec3##T##a(FCT(a.x,b.x),FCT(a.y,b.y),FCT(a.z,b.z),FCT(a.w,b.w)); } \
|
||||
\
|
||||
/* ********************************************************* */ \
|
||||
/* ---- Vec3a (from 3 and 3a) ---- */ \
|
||||
/* ********************************************************* */ \
|
||||
/* uniform Vec3a FCT(uniform Vec3a, uniform Vec3a) */ \
|
||||
inline uniform Vec3##T##a FCT(const uniform Vec3##T a, \
|
||||
const uniform Vec3##T##a b) \
|
||||
{ return make_Vec3##T##a(FCT(a.x,b.x),FCT(a.y,b.y),FCT(a.z,b.z)); } \
|
||||
/* Vec3a FCT(Vec3a, Vec3a) */ \
|
||||
inline varying Vec3##T##a FCT(const varying Vec3##T a, \
|
||||
const varying Vec3##T##a b) \
|
||||
{ return make_Vec3##T##a(FCT(a.x,b.x),FCT(a.y,b.y),FCT(a.z,b.z)); } \
|
||||
\
|
||||
/* ********************************************************* */ \
|
||||
/* ---- Vec3a (from 3a and 3) ---- */ \
|
||||
/* ********************************************************* */ \
|
||||
/* uniform Vec3a FCT(uniform Vec3a, uniform Vec3a) */ \
|
||||
inline uniform Vec3##T##a FCT(const uniform Vec3##T##a a, \
|
||||
const uniform Vec3##T b) \
|
||||
{ return make_Vec3##T##a(FCT(a.x,b.x),FCT(a.y,b.y),FCT(a.z,b.z)); } \
|
||||
/* Vec3a FCT(Vec3a, Vec3a) */ \
|
||||
inline varying Vec3##T##a FCT(const varying Vec3##T##a a, \
|
||||
const varying Vec3##T b) \
|
||||
{ return make_Vec3##T##a(FCT(a.x,b.x),FCT(a.y,b.y),FCT(a.z,b.z)); } \
|
||||
\
|
||||
/* ********************************************************* */ \
|
||||
/* ---- Vec4 ---- */ \
|
||||
/* ********************************************************* */ \
|
||||
/* uniform Vec4 FCT(uniform Vec4, uniform Vec4) */ \
|
||||
inline uniform Vec4##T FCT(const uniform Vec4##T a, \
|
||||
const uniform Vec4##T b) \
|
||||
{ return make_Vec4##T(FCT(a.x,b.x),FCT(a.y,b.y), \
|
||||
FCT(a.z,b.z),FCT(a.w,b.w)); } \
|
||||
/* Vec4 FCT(Vec4, Vec4) */ \
|
||||
inline varying Vec4##T FCT(const varying Vec4##T a, \
|
||||
const varying Vec4##T b) \
|
||||
{ return make_Vec4##T(FCT(a.x,b.x),FCT(a.y,b.y), \
|
||||
FCT(a.z,b.z),FCT(a.w,b.w)); } \
|
||||
|
||||
__lift_binaryFct(min,f)
|
||||
__lift_binaryFct(max,f)
|
||||
__lift_binaryFct(min,i)
|
||||
__lift_binaryFct(max,i)
|
||||
__lift_binaryFct(min,ui)
|
||||
__lift_binaryFct(max,ui)
|
||||
|
||||
#undef __lift_binaryFct
|
||||
|
||||
// =======================================================
|
||||
|
||||
// for now, let's implement those manually - should eventually do those via a macro!
|
||||
|
||||
inline uniform Vec3f neg(const uniform Vec3f v)
|
||||
{ return make_Vec3f(-v.x,-v.y,-v.z); }
|
||||
inline Vec3f neg(const Vec3f v)
|
||||
{ return make_Vec3f(-v.x,-v.y,-v.z); }
|
||||
inline uniform Vec3f negate(const uniform Vec3f &a)
|
||||
{ return(make_Vec3f(-a.x, -a.y, -a.z)); }
|
||||
inline varying Vec3f negate(const varying Vec3f &a)
|
||||
{ return(make_Vec3f(-a.x, -a.y, -a.z)); }
|
||||
|
||||
|
||||
#define __define_binary_operator_typed(opname,op,abb,type) \
|
||||
/* Vec2##abb */ \
|
||||
inline uniform Vec2##abb opname (const uniform Vec2##abb a, \
|
||||
const uniform Vec2##abb b) { \
|
||||
return make_Vec2##abb(a.x op b.x, a.y op b.y); \
|
||||
} \
|
||||
inline Vec2##abb opname (const Vec2##abb a, const Vec2##abb b) { \
|
||||
return make_Vec2##abb(a.x op b.x, a.y op b.y); \
|
||||
} \
|
||||
inline uniform Vec2##abb opname (const uniform Vec2##abb a, \
|
||||
const uniform type b) { \
|
||||
return make_Vec2##abb(a.x op b, a.y op b); \
|
||||
} \
|
||||
inline Vec2##abb opname (const Vec2##abb a, const type b) { \
|
||||
return make_Vec2##abb(a.x op b, a.y op b); \
|
||||
} \
|
||||
inline uniform Vec2##abb opname (const uniform type a, \
|
||||
const uniform Vec2##abb b) { \
|
||||
return make_Vec2##abb(a op b.x, a op b.y); \
|
||||
} \
|
||||
inline Vec2##abb opname (const type a, const Vec2##abb b) { \
|
||||
return make_Vec2##abb(a op b.x, a op b.y); \
|
||||
} \
|
||||
/* Vec3##abb */ \
|
||||
inline uniform Vec3##abb opname (const uniform Vec3##abb a, \
|
||||
const uniform Vec3##abb b) { \
|
||||
return make_Vec3##abb(a.x op b.x, a.y op b.y, a.z op b.z); \
|
||||
} \
|
||||
inline Vec3##abb opname (const Vec3##abb a, const Vec3##abb b) { \
|
||||
return make_Vec3##abb(a.x op b.x, a.y op b.y, a.z op b.z); \
|
||||
} \
|
||||
inline uniform Vec3##abb opname (const uniform Vec3##abb a, \
|
||||
const uniform type b) { \
|
||||
return make_Vec3##abb(a.x op b, a.y op b, a.z op b); \
|
||||
} \
|
||||
inline Vec3##abb opname (const Vec3##abb a, const type b) { \
|
||||
return make_Vec3##abb(a.x op b, a.y op b, a.z op b); \
|
||||
} \
|
||||
inline uniform Vec3##abb opname (const uniform type a, \
|
||||
const uniform Vec3##abb b) { \
|
||||
return make_Vec3##abb(a op b.x, a op b.y, a op b.z); \
|
||||
} \
|
||||
inline Vec3##abb opname (const type a, const Vec3##abb b) { \
|
||||
return make_Vec3##abb(a op b.x, a op b.y, a op b.z); \
|
||||
} \
|
||||
/* Vec3##abb##a */ \
|
||||
inline uniform Vec3##abb##a opname (const uniform Vec3##abb##a a, \
|
||||
const uniform Vec3##abb##a b) { \
|
||||
return make_Vec3##abb##a(a.x op b.x, a.y op b.y, a.z op b.z, a.w op b.w); \
|
||||
} \
|
||||
inline Vec3##abb##a opname (const Vec3##abb##a a, const Vec3##abb##a b) { \
|
||||
return make_Vec3##abb##a(a.x op b.x, a.y op b.y, a.z op b.z, a.w op b.w); \
|
||||
} \
|
||||
inline uniform Vec3##abb##a opname (const uniform Vec3##abb##a a, \
|
||||
const uniform type b) { \
|
||||
return make_Vec3##abb##a(a.x op b, a.y op b, a.z op b, a.w op b); \
|
||||
} \
|
||||
inline Vec3##abb##a opname (const Vec3##abb##a a, const type b) { \
|
||||
return make_Vec3##abb##a(a.x op b, a.y op b, a.z op b, a.w op b); \
|
||||
} \
|
||||
inline uniform Vec3##abb##a opname (const uniform type a, \
|
||||
const uniform Vec3##abb##a b) { \
|
||||
return make_Vec3##abb##a(a op b.x, a op b.y, a op b.z, a op b.w); \
|
||||
} \
|
||||
inline Vec3##abb##a opname (const type a, const Vec3##abb##a b) { \
|
||||
return make_Vec3##abb##a(a op b.x, a op b.y, a op b.z, a op b.w); \
|
||||
} \
|
||||
/* Vec4##abb */ \
|
||||
inline uniform Vec4##abb opname (const uniform Vec4##abb a, \
|
||||
const uniform Vec4##abb b) { \
|
||||
return make_Vec4##abb(a.x op b.x, a.y op b.y, a.z op b.z, a.w op b.w); \
|
||||
} \
|
||||
inline Vec4##abb opname (const Vec4##abb a, const Vec4##abb b) { \
|
||||
return make_Vec4##abb(a.x op b.x, a.y op b.y, a.z op b.z, a.w op b.w); \
|
||||
} \
|
||||
inline uniform Vec4##abb opname (const uniform Vec4##abb a, \
|
||||
const uniform type b) { \
|
||||
return make_Vec4##abb(a.x op b, a.y op b, a.z op b, a.w op b); \
|
||||
} \
|
||||
inline Vec4##abb opname (const Vec4##abb a, const type b) { \
|
||||
return make_Vec4##abb(a.x op b, a.y op b, a.z op b, a.w op b); \
|
||||
} \
|
||||
inline uniform Vec4##abb opname (const uniform type a, \
|
||||
const uniform Vec4##abb b) { \
|
||||
return make_Vec4##abb(a op b.x, a op b.y, a op b.z, a op b.w); \
|
||||
} \
|
||||
inline Vec4##abb opname (const type a, const Vec4##abb b) { \
|
||||
return make_Vec4##abb(a op b.x, a op b.y, a op b.z, a op b.w); \
|
||||
}
|
||||
|
||||
#define __define_binary_operator(opname,op) \
|
||||
__define_binary_operator_typed(opname,op,f,float) \
|
||||
__define_binary_operator_typed(opname,op,i,int32) \
|
||||
__define_binary_operator_typed(opname,op,ui,uint32)
|
||||
|
||||
|
||||
// define 'regular' operators
|
||||
__define_binary_operator( operator+, + );
|
||||
__define_binary_operator( operator-, - );
|
||||
__define_binary_operator( operator*, * );
|
||||
__define_binary_operator( operator/, / );
|
||||
|
||||
// define old functional operators as used in the embree path tracer, deprecated
|
||||
__define_binary_operator( add, + );
|
||||
__define_binary_operator( sub, - );
|
||||
__define_binary_operator( mul, * );
|
||||
|
||||
#undef __define_binary_operator
|
||||
|
||||
inline float reduce_mul(const Vec3f v)
|
||||
{ return v.x * v.y * v.z; }
|
||||
inline uniform float reduce_mul(const uniform Vec3f v)
|
||||
{ return v.x * v.y * v.z; }
|
||||
|
||||
inline float reduce_max(const Vec3f v)
|
||||
{ return max(max(v.x,v.y),v.z); }
|
||||
|
||||
inline float reduce_add(const Vec3f v)
|
||||
{ return v.x+v.y+v.z; }
|
||||
|
||||
inline uniform float reduce_add(const uniform Vec3f v)
|
||||
{ return v.x+v.y+v.z; }
|
||||
|
||||
inline float reduce_avg(const Vec3f v)
|
||||
{ return (v.x+v.y+v.z)*(1.0f/3.0f); }
|
||||
|
||||
inline float luminance(const Vec3f& c)
|
||||
{ return 0.212671f*c.x + 0.715160f*c.y + 0.072169f*c.z; }
|
||||
|
||||
inline uniform bool eq(const uniform Vec2f a, const uniform Vec2f b)
|
||||
{ return a.x==b.x && a.y==b.y; }
|
||||
inline bool eq(const Vec2f a, const Vec2f b)
|
||||
{ return a.x==b.x & a.y==b.y; }
|
||||
inline uniform bool eq(const uniform Vec3f a, const uniform Vec3f b)
|
||||
{ return a.x==b.x && a.y==b.y && a.z==b.z; }
|
||||
inline bool eq(const Vec3f a, const Vec3f b)
|
||||
{ return a.x==b.x & a.y==b.y & a.z==b.z; }
|
||||
inline uniform bool eq(const uniform Vec3fa a, const uniform Vec3fa b)
|
||||
{ return a.x==b.x && a.y==b.y && a.z==b.z; }
|
||||
inline bool eq(const Vec3fa a, const Vec3fa b)
|
||||
{ return a.x==b.x & a.y==b.y & a.z==b.z; }
|
||||
|
||||
inline uniform bool ne(const uniform Vec2f a, const uniform Vec2f b)
|
||||
{ return !eq(a,b); }
|
||||
inline bool ne(const Vec2f a, const Vec2f b)
|
||||
{ return !eq(a,b); }
|
||||
inline uniform bool ne(const uniform Vec3f a, const uniform Vec3f b)
|
||||
{ return !eq(a,b); }
|
||||
inline bool ne(const Vec3f a, const Vec3f b)
|
||||
{ return !eq(a,b); }
|
||||
inline uniform bool ne(const uniform Vec3fa a, const uniform Vec3fa b)
|
||||
{ return !eq(a,b); }
|
||||
inline bool ne(const Vec3fa a, const Vec3fa b)
|
||||
{ return !eq(a,b); }
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// dot product
|
||||
// ------------------------------------------------------------------
|
||||
/*! computes 3D dot product for *all-uniform* Vec3fs */
|
||||
inline uniform float dot(const uniform Vec3f a, const uniform Vec3f b)
|
||||
{ return a.x*b.x+a.y*b.y+a.z*b.z; }
|
||||
/*! computes 3D dot product for Vec3fs that produce varying results */
|
||||
inline float dot(const Vec3f a, const Vec3f b)
|
||||
{ return a.x*b.x+a.y*b.y+a.z*b.z; }
|
||||
|
||||
inline uniform float length(const uniform Vec3f a) { return sqrtf(dot(a,a)); }
|
||||
inline varying float length(const varying Vec3f a) { return sqrtf(dot(a,a)); }
|
||||
|
||||
inline uniform float distance(const uniform Vec3f a, const uniform Vec3f b) { return length(a - b); }
|
||||
inline varying float distance(const varying Vec3f a, const varying Vec3f b) { return length(a - b); }
|
||||
|
||||
|
||||
inline uniform float dot(const uniform Vec3fa a, const uniform Vec3fa b) { return a.x*b.x+a.y*b.y+a.z*b.z; }
|
||||
inline varying float dot(const varying Vec3fa a, const varying Vec3fa b) { return a.x*b.x+a.y*b.y+a.z*b.z; }
|
||||
|
||||
inline uniform float length(const uniform Vec3fa a) { return sqrtf(dot(a,a)); }
|
||||
inline varying float length(const varying Vec3fa a) { return sqrtf(dot(a,a)); }
|
||||
|
||||
inline uniform float distance(const uniform Vec3fa a, const uniform Vec3fa b) { return length(a - b); }
|
||||
inline varying float distance(const varying Vec3fa a, const varying Vec3fa b) { return length(a - b); }
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// cross product
|
||||
// ------------------------------------------------------------------
|
||||
/*! computes 3D cross product for *all-uniform* Vec3fs */
|
||||
inline uniform Vec3f cross(const uniform Vec3f &a, const uniform Vec3f &b)
|
||||
{ return make_Vec3f(a.y*b.z-a.z*b.y,
|
||||
a.z*b.x-a.x*b.z,
|
||||
a.x*b.y-a.y*b.x); }
|
||||
/*! computes 3D cross product for Vec3fs that produce varying results */
|
||||
inline Vec3f cross(const Vec3f &a, const Vec3f &b)
|
||||
{ return make_Vec3f(a.y*b.z-a.z*b.y,
|
||||
a.z*b.x-a.x*b.z,
|
||||
a.x*b.y-a.y*b.x); }
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// normalize
|
||||
// ------------------------------------------------------------------
|
||||
/*! compute and return normalized version of uniform Vec3f passed to this fct */
|
||||
inline uniform Vec3f normalize(const uniform Vec3f &v)
|
||||
{ return v * (1.f/sqrt(dot(v,v))); }
|
||||
/*! compute and return normalized version of varying Vec3f passed to this fct */
|
||||
inline Vec3f normalize(const Vec3f v)
|
||||
{ return v * (1.f/sqrt(dot(v,v))); }
|
||||
/*! compute and return normalized version of varying Vec3f passed to this fct */
|
||||
inline Vec3f normalize(const Vec3f v, float &len)
|
||||
{ len = sqrtf(dot(v,v)); return v * rcpf(len); }
|
||||
|
||||
inline Vec3f safe_normalize(const Vec3f v)
|
||||
{ return v * (1.f/sqrt(max(1e-6f,dot(v,v)))); }
|
||||
|
||||
/*! differentiated normalization */
|
||||
inline varying Vec3f dnormalize(const varying Vec3f& p, const varying Vec3f& dp)
|
||||
{
|
||||
const float pp = dot(p,p);
|
||||
const float pdp = dot(p,dp);
|
||||
return (pp*dp-pdp*p)*rcp(pp)*rsqrt(pp);
|
||||
}
|
||||
|
||||
|
||||
inline uniform Vec3fa normalize(const uniform Vec3fa &v) { return v * (1.f/sqrt(dot(v,v))); }
|
||||
inline varying Vec3fa normalize(const varying Vec3fa v) { return v * (1.f/sqrt(dot(v,v))); }
|
||||
|
||||
inline varying Vec3fa dnormalize(const varying Vec3fa& p, const varying Vec3fa& dp)
|
||||
{
|
||||
const float pp = dot(p,p);
|
||||
const float pdp = dot(p,dp);
|
||||
return (pp*dp-pdp*p)*rcp(pp)*rsqrt(pp);
|
||||
}
|
||||
|
||||
|
||||
#define __lift_unary_fct(F) \
|
||||
inline uniform Vec2f F(const uniform Vec2f v) \
|
||||
{ return make_Vec2f(F(v.x),F(v.y)); } \
|
||||
inline Vec2f F(const Vec2f v) \
|
||||
{ return make_Vec2f(F(v.x),F(v.y)); } \
|
||||
inline uniform Vec3f F(const uniform Vec3f v) \
|
||||
{ return make_Vec3f(F(v.x),F(v.y),F(v.z)); } \
|
||||
inline Vec3f F(const Vec3f v) \
|
||||
{ return make_Vec3f(F(v.x),F(v.y),F(v.z)); } \
|
||||
inline uniform Vec3fa F(const uniform Vec3fa v) \
|
||||
{ return make_Vec3fa(F(v.x),F(v.y),F(v.z),F(v.w)); } \
|
||||
inline Vec3fa F(const Vec3fa v) \
|
||||
{ return make_Vec3fa(F(v.x),F(v.y),F(v.z),F(v.w)); } \
|
||||
inline uniform Vec4f F(const uniform Vec4f v) \
|
||||
{ return make_Vec4f(F(v.x),F(v.y),F(v.z),F(v.w)); } \
|
||||
inline Vec4f F(const Vec4f v) \
|
||||
{ return make_Vec4f(F(v.x),F(v.y),F(v.z),F(v.w)); }
|
||||
|
||||
__lift_unary_fct(absf)
|
||||
__lift_unary_fct(rcpf)
|
||||
__lift_unary_fct(expf)
|
||||
__lift_unary_fct(logf)
|
||||
|
||||
__lift_unary_fct(floor)
|
||||
__lift_unary_fct(abs)
|
||||
__lift_unary_fct(rcp)
|
||||
__lift_unary_fct(exp)
|
||||
__lift_unary_fct(frac)
|
||||
__lift_unary_fct(sqr)
|
||||
|
||||
#undef __lift_unary_fct
|
||||
|
||||
/*! make RGBA from RGB */
|
||||
inline Vec4f make_Vec4f(const Vec3f rgb, const float a)
|
||||
{ return make_Vec4f(rgb.x,rgb.y,rgb.z,a); }
|
||||
|
||||
/*! make RGBA from RGB */
|
||||
inline uniform Vec4f make_Vec4f(const uniform Vec3f rgb, const uniform float a)
|
||||
{ return make_Vec4f(rgb.x,rgb.y,rgb.z,a); }
|
||||
|
||||
// // ------------------------------------------------------------------
|
||||
// // vector functions (abs,rcp,...):
|
||||
// // ------------------------------------------------------------------
|
||||
// /*! return vector of absolute values of input vector */
|
||||
// inline uniform Vec3f abs(const uniform Vec3f v)
|
||||
// { return make_Vec3f(abs(v.x),abs(v.y),abs(v.z)); }
|
||||
// /*! return vector of absolute values of input vector */
|
||||
// inline Vec3f abs(const Vec3f v)
|
||||
// { return make_Vec3f(abs(v.x),abs(v.y),abs(v.z)); }
|
||||
// /*! return vector of reciprocals of input vector */
|
||||
// inline uniform Vec3f rcp(const uniform Vec3f v)
|
||||
// { return make_Vec3f(rcp(v.x),rcp(v.y),rcp(v.z)); }
|
||||
// /*! return vector of reciprocals of input vector */
|
||||
// inline Vec3f rcp(const Vec3f v)
|
||||
// { return make_Vec3f(rcp(v.x),rcp(v.y),rcp(v.z)); }
|
||||
|
||||
#define __define_lerp2(ABB) \
|
||||
inline uniform Vec2##ABB lerp(uniform float factor, const uniform Vec2##ABB a, const uniform Vec2##ABB b) \
|
||||
{ \
|
||||
return make_Vec2##ABB(lerp(factor, a.x, b.x), lerp(factor, a.y, b.y)); \
|
||||
} \
|
||||
inline Vec2##ABB lerp(float factor, const Vec2##ABB a, const Vec2##ABB b) \
|
||||
{ \
|
||||
return make_Vec2##ABB(lerp(factor, a.x, b.x), lerp(factor, a.y, b.y)); \
|
||||
}
|
||||
|
||||
#define __define_lerp3(ABB) \
|
||||
inline uniform Vec3##ABB lerp(uniform float factor, const uniform Vec3##ABB a, const uniform Vec3##ABB b) \
|
||||
{ \
|
||||
return make_Vec3##ABB(lerp(factor, a.x, b.x), lerp(factor, a.y, b.y), lerp(factor, a.z, b.z)); \
|
||||
} \
|
||||
inline Vec3##ABB lerp(float factor, const Vec3##ABB a, const Vec3##ABB b) \
|
||||
{ \
|
||||
return make_Vec3##ABB(lerp(factor, a.x, b.x), lerp(factor, a.y, b.y), lerp(factor, a.z, b.z)); \
|
||||
} \
|
||||
|
||||
#define __define_lerp3a(ABB) \
|
||||
inline uniform Vec3##ABB##a lerp(uniform float factor, const uniform Vec3##ABB##a a, const uniform Vec3##ABB##a b) \
|
||||
{ \
|
||||
return make_Vec3##ABB##a(lerp(factor, a.x, b.x), lerp(factor, a.y, b.y), lerp(factor, a.z, b.z), lerp(factor, a.w, b.w)); \
|
||||
} \
|
||||
inline Vec3##ABB##a lerp(float factor, const Vec3##ABB##a a, const Vec3##ABB##a b) \
|
||||
{ \
|
||||
return make_Vec3##ABB##a(lerp(factor, a.x, b.x), lerp(factor, a.y, b.y), lerp(factor, a.z, b.z), lerp(factor, a.w, b.w)); \
|
||||
}
|
||||
|
||||
#define __define_lerp4(ABB) \
|
||||
inline uniform Vec4##ABB lerp(uniform float factor, const uniform Vec4##ABB a, const uniform Vec4##ABB b) \
|
||||
{ \
|
||||
return make_Vec4##ABB(lerp(factor, a.x, b.x), lerp(factor, a.y, b.y), lerp(factor, a.z, b.z), lerp(factor, a.w, b.w)); \
|
||||
} \
|
||||
inline Vec4##ABB lerp(float factor, const Vec4##ABB a, const Vec4##ABB b) \
|
||||
{ \
|
||||
return make_Vec4##ABB(lerp(factor, a.x, b.x), lerp(factor, a.y, b.y), lerp(factor, a.z, b.z), lerp(factor, a.w, b.w)); \
|
||||
}
|
||||
|
||||
__define_lerp2(f)
|
||||
__define_lerp2(i)
|
||||
__define_lerp2(ui)
|
||||
__define_lerp2(uc)
|
||||
__define_lerp3(f)
|
||||
__define_lerp3(i)
|
||||
__define_lerp3(ui)
|
||||
__define_lerp3(uc)
|
||||
//__define_lerp3a(i)
|
||||
//__define_lerp3a(ui)
|
||||
//__define_lerp3a(uc)
|
||||
__define_lerp4(f)
|
||||
__define_lerp4(i)
|
||||
__define_lerp4(ui)
|
||||
__define_lerp4(uc)
|
||||
|
||||
#undef __define_lerp2
|
||||
#undef __define_lerp3
|
||||
#undef __define_lerp4
|
||||
|
||||
inline Vec2i make_Vec2i(const Vec2f &a)
|
||||
{ return make_Vec2i((int)a.x, (int)a.y); }
|
||||
|
||||
inline Vec2i integer_cast(const Vec2f &a)
|
||||
{ return make_Vec2i(a); }
|
||||
|
||||
inline Vec2f clamp(const Vec2f &a, const uniform Vec2f &b, const uniform Vec2f &c)
|
||||
{ return(make_Vec2f(clamp(a.x, b.x, c.x), clamp(a.y, b.y, c.y))); }
|
||||
|
||||
|
||||
inline uniform Vec3i operator*(const uniform Vec3i &a, const uniform int b)
|
||||
{ return(make_Vec3i(a.x * b, a.y * b, a.z * b)); }
|
||||
|
||||
inline uniform Vec3i operator+(const uniform Vec3i &a, const uniform Vec3i &b)
|
||||
{ return(make_Vec3i(a.x + b.x, a.y + b.y, a.z + b.z)); }
|
||||
|
||||
inline Vec3i operator+(const varying Vec3i &a, const varying Vec3i &b)
|
||||
{ return(make_Vec3i(a.x + b.x, a.y + b.y, a.z + b.z)); }
|
||||
|
||||
// Workaround for compiler bug.
|
||||
inline Vec3i operator+(const uniform Vec3i &a, const varying Vec3i &b)
|
||||
{ return(make_Vec3i(a.x + b.x, a.y + b.y, a.z + b.z)); }
|
||||
|
||||
inline Vec3i operator+(const varying Vec3i &a, const varying int32 b)
|
||||
{ return(make_Vec3i(a.x + b, a.y + b, a.z + b)); }
|
||||
|
||||
inline uniform Vec3i operator+(const uniform Vec3i &a, const uniform int b)
|
||||
{ return(make_Vec3i(a.x + b, a.y + b, a.z + b)); }
|
||||
|
||||
inline uniform Vec3i operator-(const uniform Vec3i &a, const uniform int b)
|
||||
{ return(make_Vec3i(a.x - b, a.y - b, a.z - b)); }
|
||||
|
||||
inline Vec3i operator-(const varying Vec3i &a, const uniform Vec3i &b)
|
||||
{ return(make_Vec3i(a.x - b.x, a.y - b.y, a.z - b.z)); }
|
||||
|
||||
inline Vec3i operator-(const varying Vec3i &a, const varying Vec3i &b)
|
||||
{ return(make_Vec3i(a.x - b.x, a.y - b.y, a.z - b.z)); }
|
||||
|
||||
inline Vec3i operator-(const varying Vec3i &a, const varying int32 b)
|
||||
{ return(make_Vec3i(a.x - b, a.y - b, a.z - b)); }
|
||||
|
||||
inline uniform Vec3i operator/(const uniform Vec3i &a, const uniform int b)
|
||||
{ return(make_Vec3i(a.x / b, a.y / b, a.z / b)); }
|
||||
|
||||
inline Vec3f float_cast(const Vec3i &a)
|
||||
{ return make_Vec3f(a); }
|
||||
|
||||
inline Vec3i integer_cast(const Vec3f &a)
|
||||
{ return make_Vec3i(a); }
|
||||
|
||||
inline Vec3i operator>>(const Vec3i &a, const int b)
|
||||
{ return(make_Vec3i(a.x >> b, a.y >> b, a.z >> b)); }
|
||||
|
||||
inline Vec3i operator<<(const Vec3i &a, const int b)
|
||||
{ return(make_Vec3i(a.x << b, a.y << b, a.z << b)); }
|
||||
|
||||
inline Vec3i bitwise_AND(const Vec3i &a, const int b)
|
||||
{ return(make_Vec3i(a.x & b, a.y & b, a.z &b)); }
|
||||
|
||||
inline Vec3f powf(const Vec3f v, const float f)
|
||||
{ return make_Vec3f(powf(v.x,f),powf(v.y,f),powf(v.z,f)); }
|
||||
|
||||
inline uniform Vec3f powf(const uniform Vec3f v, const uniform float f)
|
||||
{ return make_Vec3f(powf(v.x,f),powf(v.y,f),powf(v.z,f)); }
|
||||
|
||||
inline Vec3f clamp(const Vec3f &a, const uniform Vec3f &b, const uniform Vec3f &c)
|
||||
{ return(make_Vec3f(clamp(a.x, b.x, c.x), clamp(a.y, b.y, c.y), clamp(a.z, b.z, c.z))); }
|
||||
|
||||
inline Vec3f clamp(const Vec3f &a, const Vec3f &b, const Vec3f &c)
|
||||
{ return(make_Vec3f(clamp(a.x, b.x, c.x), clamp(a.y, b.y, c.y), clamp(a.z, b.z, c.z))); }
|
||||
|
||||
inline Vec3i clamp(const Vec3i &a, const uniform Vec3i &b, const uniform Vec3i &c)
|
||||
{ return(make_Vec3i(clamp(a.x, b.x, c.x), clamp(a.y, b.y, c.y), clamp(a.z, b.z, c.z))); }
|
||||
|
||||
//! The next machine representable number from 'a' in the direction of 'b'.
|
||||
inline uniform Vec3f nextafter(const uniform Vec3i &a, const uniform Vec3i &b)
|
||||
{ return(make_Vec3f(nextafter(a.x, b.x), nextafter(a.y, b.y), nextafter(a.z, b.z))); }
|
||||
|
||||
inline varying float reduce_min(const varying Vec3f &a)
|
||||
{ return min(min(a.x, a.y), a.z); }
|
||||
|
||||
inline uniform float reduce_min(const uniform Vec3f &a)
|
||||
{ return min(min(a.x, a.y), a.z); }
|
||||
|
||||
inline uniform float reduce_min(const uniform Vec3i &a)
|
||||
{ return min(min(a.x, a.y), a.z); }
|
||||
|
||||
inline varying float reduce_min(const varying Vec3i &a)
|
||||
{ return min(min(a.x, a.y), a.z); }
|
||||
|
||||
inline varying float reduce_min(const varying Vec4f &a)
|
||||
{ return min(min(a.x, a.y), min(a.z, a.w)); }
|
||||
|
||||
inline uniform float reduce_min(const uniform Vec4f &a)
|
||||
{ return min(min(a.x, a.y), min(a.z, a.w)); }
|
||||
|
||||
inline uniform float reduce_max(const uniform Vec3i &a)
|
||||
{ return max(max(a.x, a.y), a.z); }
|
||||
|
||||
inline varying float reduce_max(const varying Vec3i &a)
|
||||
{ return max(max(a.x, a.y), a.z); }
|
||||
|
||||
inline varying float reduce_max(const varying Vec3f &a)
|
||||
{ return max(max(a.x, a.y), a.z); }
|
||||
|
||||
inline uniform float reduce_max(const uniform Vec3f &a)
|
||||
{ return max(max(a.x, a.y), a.z); }
|
||||
|
||||
inline varying float reduce_max(const varying Vec4f &a)
|
||||
{ return max(max(a.x, a.y), max(a.z, a.w)); }
|
||||
|
||||
inline uniform float reduce_max(const uniform Vec4f &a)
|
||||
{ return max(max(a.x, a.y), max(a.z, a.w)); }
|
||||
|
||||
inline uniform float reduce_add(const uniform Vec3f &a)
|
||||
{ return a.x+a.y+a.z; }
|
||||
|
||||
inline uniform float reduce_avg(const uniform Vec3f &a)
|
||||
{ return reduce_add(a)*(1.0f/3.0f); }
|
||||
|
||||
inline uniform float luminance(const uniform Vec3f& c)
|
||||
{ return 0.212671f*c.x + 0.715160f*c.y + 0.072169f*c.z; }
|
||||
|
||||
inline varying Vec3f pow(const varying Vec3f &a, const varying float b)
|
||||
{ return make_Vec3f(pow(a.x, b), pow(a.y, b), pow(a.z, b)); }
|
||||
|
||||
inline varying Vec4f pow(const varying Vec4f &a, const varying float b)
|
||||
{ return make_Vec4f(pow(a.x, b), pow(a.y, b), pow(a.z, b), pow(a.w, b)); }
|
||||
|
||||
inline uniform bool isnan(uniform Vec3f v)
|
||||
{ return isnan(v.x+v.y+v.z); }
|
||||
|
||||
inline bool isnan(Vec3f v)
|
||||
{ return isnan(v.x+v.y+v.z); }
|
||||
|
||||
inline uniform bool isnan(uniform Vec3fa v)
|
||||
{ return isnan(v.x+v.y+v.z); }
|
||||
|
||||
inline bool isnan(Vec3fa v)
|
||||
{ return isnan(v.x+v.y+v.z); }
|
||||
|
||||
typedef Vec3fa Vec3ff;
|
||||
typedef Vec3f Vec3f_;
|
||||
|
||||
inline uniform Vec3f make_Vec3f_(uniform float w) { uniform Vec3f r; r.x = w; r.y = w; r.z = w; return r; }
|
||||
inline varying Vec3f make_Vec3f_(varying float w) { varying Vec3f r; r.x = w; r.y = w; r.z = w; return r; }
|
||||
|
||||
inline uniform Vec3f make_Vec3f_(uniform Vec3f v) { uniform Vec3f r; r.x = v.x; r.y = v.y; r.z = v.z; return r; }
|
||||
inline varying Vec3f make_Vec3f_(varying Vec3f v) { varying Vec3f r; r.x = v.x; r.y = v.y; r.z = v.z; return r; }
|
||||
|
||||
inline uniform Vec3f make_Vec3f_(uniform Vec3fa v) { uniform Vec3f r; r.x = v.x; r.y = v.y; r.z = v.z; return r; }
|
||||
inline varying Vec3f make_Vec3f_(varying Vec3fa v) { varying Vec3f r; r.x = v.x; r.y = v.y; r.z = v.z; return r; }
|
||||
|
||||
inline uniform Vec3ff make_Vec3ff(uniform float w) { uniform Vec3ff r; r.x = w; r.y = w; r.z = w; r.w = w; return r; }
|
||||
inline varying Vec3ff make_Vec3ff(varying float w) { varying Vec3ff r; r.x = w; r.y = w; r.z = w; r.w = w; return r; }
|
||||
|
||||
inline uniform Vec3ff make_Vec3ff(uniform Vec3f v) { uniform Vec3ff r; r.x = v.x; r.y = v.y; r.z = v.z; r.w = 0.0f; return r; }
|
||||
inline varying Vec3ff make_Vec3ff(varying Vec3f v) { varying Vec3ff r; r.x = v.x; r.y = v.y; r.z = v.z; r.w = 0.0f; return r; }
|
||||
|
||||
inline uniform Vec3ff make_Vec3ff(uniform Vec3fa v) { uniform Vec3ff r; r.x = v.x; r.y = v.y; r.z = v.z; r.w = 0.0f; return r; }
|
||||
inline varying Vec3ff make_Vec3ff(varying Vec3fa v) { varying Vec3ff r; r.x = v.x; r.y = v.y; r.z = v.z; r.w = 0.0f; return r; }
|
||||
|
||||
inline uniform Vec3ff make_Vec3ff(uniform Vec3f v, uniform float w) { uniform Vec3ff r; r.x = v.x; r.y = v.y; r.z = v.z; r.w = w; return r; }
|
||||
inline varying Vec3ff make_Vec3ff(varying Vec3f v, varying float w) { varying Vec3ff r; r.x = v.x; r.y = v.y; r.z = v.z; r.w = w; return r; }
|
||||
|
||||
inline uniform Vec3ff make_Vec3ff(uniform Vec3fa v, uniform float w) { uniform Vec3ff r; r.x = v.x; r.y = v.y; r.z = v.z; r.w = w; return r; }
|
||||
inline varying Vec3ff make_Vec3ff(varying Vec3fa v, varying float w) { varying Vec3ff r; r.x = v.x; r.y = v.y; r.z = v.z; r.w = w; return r; }
|
||||
|
||||
inline uniform Vec3ff make_Vec3ff(uniform float x, uniform float y, uniform float z, uniform float w) { uniform Vec3ff r; r.x = x; r.y = y; r.z = z; r.w = w; return r; }
|
||||
inline varying Vec3ff make_Vec3ff(varying float x, varying float y, varying float z, varying float w) { varying Vec3ff r; r.x = x; r.y = y; r.z = z; r.w = w; return r; }
|
||||
|
||||
inline void out(uniform Vec3f v) { print("(%,%,%)",v.x,v.y,v.z); }
|
||||
inline void out(Vec3f v) { print("\n(%\n %\n %)",v.x,v.y,v.z); }
|
||||
inline void out(uniform Vec3i v) { print("(%,%,%)",v.x,v.y,v.z); }
|
||||
inline void out(Vec3i v) { print("\n(%\n %\n %)",v.x,v.y,v.z); }
|
||||
|
||||
|
||||
// -------------------------------------------------------
|
||||
// set/get functions for vectors
|
||||
// should eventually get moved to macros so they work for all types
|
||||
// -------------------------------------------------------
|
||||
|
||||
/*! set vector 'v's value in dimension 'd' to 'f' */
|
||||
inline void set(uniform Vec3f &v, const uniform uint32 dim, const uniform float f)
|
||||
{ (&v.x)[dim] = f; }
|
||||
|
||||
/*! get vector 'v's value in dimension 'd' */
|
||||
inline uniform float get(const uniform Vec3f &v, const uniform uint32 dim)
|
||||
{ return (&v.x)[dim]; }
|
||||
inline float get(const Vec3f &v, const uniform uint32 dim)
|
||||
{ return (&v.x)[dim]; }
|
||||
|
||||
|
||||
// -------------------------------------------------------
|
||||
// sRGB conversion functions
|
||||
// -------------------------------------------------------
|
||||
#define APPROXIMATE_SRGB
|
||||
|
||||
inline float linear_to_srgb(const float f)
|
||||
{
|
||||
const float c = max(f, 0.f);
|
||||
#ifdef APPROXIMATE_SRGB
|
||||
return pow(c, 1.f/2.2f);
|
||||
#else
|
||||
return c <= 0.0031308f ? 12.92f*c : pow(c, 1.f/2.4f)*1.055f - 0.055f;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline Vec4f linear_to_srgba(const Vec4f c)
|
||||
{
|
||||
return make_Vec4f(linear_to_srgb(c.x),
|
||||
linear_to_srgb(c.y),
|
||||
linear_to_srgb(c.z),
|
||||
max(c.w, 0.f)); // alpha is never gamma-corrected
|
||||
}
|
||||
|
||||
inline uint32 linear_to_srgba8(const Vec4f c)
|
||||
{
|
||||
#if 1
|
||||
Vec4f l = 255.f * min(linear_to_srgba(c), make_Vec4f(1.f));
|
||||
return
|
||||
((uint32)l.x << 0) |
|
||||
((uint32)l.y << 8) |
|
||||
((uint32)l.z << 16) |
|
||||
((uint32)l.w << 24);
|
||||
#else
|
||||
// TODO use ISPC's float_to_srgb8 once it is fixed (issue #1198)
|
||||
return
|
||||
(float_to_srgb8(c.x) << 0) |
|
||||
(float_to_srgb8(c.y) << 8) |
|
||||
(float_to_srgb8(c.z) << 16) |
|
||||
((uint32)clamp(c.w, 0.f, 1.f) << 24); // alpha is never gamma-corrected
|
||||
#endif
|
||||
}
|
||||
|
||||
inline float srgb_to_linear(const float f)
|
||||
{
|
||||
const float c = max(f, 0.f);
|
||||
#ifdef APPROXIMATE_SRGB
|
||||
return pow(c, 2.2f);
|
||||
#else
|
||||
return c <= 0.04045f ? c/12.92f : pow((c + 0.055f)/1.055f, 2.4f);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline Vec4f srgba_to_linear(const Vec4f c)
|
||||
{
|
||||
return make_Vec4f(srgb_to_linear(c.x),
|
||||
srgb_to_linear(c.y),
|
||||
srgb_to_linear(c.z),
|
||||
max(c.w, 0.f)); // alpha is never gamma-corrected
|
||||
}
|
||||
|
||||
// TODO implement srgba8_to_linear with a 256 entry LUT
|
||||
|
||||
#undef APPROXIMATE_SRGB
|
||||
17
Framework/external/embree/tutorials/common/scenegraph/CMakeLists.txt
vendored
Normal file
17
Framework/external/embree/tutorials/common/scenegraph/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
## Copyright 2009-2021 Intel Corporation
|
||||
## SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
ADD_LIBRARY(scenegraph STATIC
|
||||
xml_parser.cpp
|
||||
xml_loader.cpp
|
||||
xml_writer.cpp
|
||||
obj_loader.cpp
|
||||
ply_loader.cpp
|
||||
corona_loader.cpp
|
||||
texture.cpp
|
||||
scenegraph.cpp
|
||||
geometry_creation.cpp)
|
||||
|
||||
TARGET_LINK_LIBRARIES(scenegraph sys math lexers image embree)
|
||||
SET_PROPERTY(TARGET scenegraph PROPERTY FOLDER tutorials/common)
|
||||
SET_PROPERTY(TARGET scenegraph APPEND PROPERTY COMPILE_FLAGS " ${FLAGS_LOWEST}")
|
||||
299
Framework/external/embree/tutorials/common/scenegraph/corona_loader.cpp
vendored
Normal file
299
Framework/external/embree/tutorials/common/scenegraph/corona_loader.cpp
vendored
Normal file
|
|
@ -0,0 +1,299 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "corona_loader.h"
|
||||
#include "xml_parser.h"
|
||||
#include "obj_loader.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
class CoronaLoader
|
||||
{
|
||||
public:
|
||||
|
||||
static Ref<SceneGraph::Node> load(const FileName& fileName, const AffineSpace3fa& space);
|
||||
CoronaLoader(const FileName& fileName, const AffineSpace3fa& space);
|
||||
|
||||
private:
|
||||
template<typename T> T load(const Ref<XML>& xml) { assert(false); return T(zero); }
|
||||
Ref<SceneGraph::MaterialNode> loadMaterial(const Ref<XML>& xml);
|
||||
void loadMaterialDefinition(const Ref<XML>& xml);
|
||||
std::shared_ptr<Texture> loadMap(const Ref<XML>& xml);
|
||||
void loadMapDefinition(const Ref<XML>& xml);
|
||||
Ref<SceneGraph::Node> loadMaterialLibrary(const FileName& fileName);
|
||||
Ref<SceneGraph::Node> loadObject(const Ref<XML>& xml);
|
||||
std::pair<Ref<SceneGraph::MaterialNode>, avector<AffineSpace3fa> > loadInstances(const Ref<XML>& xml);
|
||||
Ref<SceneGraph::Node> loadGroupNode(const Ref<XML>& xml);
|
||||
Ref<SceneGraph::Node> loadNode(const Ref<XML>& xml);
|
||||
|
||||
private:
|
||||
FileName path;
|
||||
std::map<std::string,Ref<SceneGraph::MaterialNode> > materialMap;
|
||||
std::map<std::string,std::shared_ptr<Texture>> textureMap;
|
||||
std::map<std::string,std::shared_ptr<Texture>> textureFileMap;
|
||||
public:
|
||||
Ref<SceneGraph::Node> root;
|
||||
};
|
||||
|
||||
template<> FileName CoronaLoader::load<FileName>(const Ref<XML>& xml)
|
||||
{
|
||||
if (xml->body.size() != 1) THROW_RUNTIME_ERROR(xml->loc.str()+": wrong FileName body");
|
||||
return xml->body[0].Identifier();
|
||||
}
|
||||
|
||||
template<> std::string CoronaLoader::load<std::string>(const Ref<XML>& xml)
|
||||
{
|
||||
if (xml->body.size() != 1) THROW_RUNTIME_ERROR(xml->loc.str()+": wrong string body");
|
||||
return xml->body[0].Identifier();
|
||||
}
|
||||
|
||||
template<> int CoronaLoader::load<int>(const Ref<XML>& xml) {
|
||||
if (xml->body.size() < 1) THROW_RUNTIME_ERROR(xml->loc.str()+": wrong int body");
|
||||
return xml->body[0].Int();
|
||||
}
|
||||
|
||||
template<> float CoronaLoader::load<float>(const Ref<XML>& xml) {
|
||||
if (xml->body.size() < 1) THROW_RUNTIME_ERROR(xml->loc.str()+": wrong float body");
|
||||
return xml->body[0].Float();
|
||||
}
|
||||
|
||||
template<> Vec3f CoronaLoader::load<Vec3f>(const Ref<XML>& xml) {
|
||||
if (xml->body.size() < 3) THROW_RUNTIME_ERROR(xml->loc.str()+": wrong float3 body");
|
||||
return Vec3f(xml->body[0].Float(),xml->body[1].Float(),xml->body[2].Float());
|
||||
}
|
||||
|
||||
template<> Vec3fa CoronaLoader::load<Vec3fa>(const Ref<XML>& xml) {
|
||||
if (xml->body.size() < 3) THROW_RUNTIME_ERROR(xml->loc.str()+": wrong float3 body");
|
||||
return Vec3fa(xml->body[0].Float(),xml->body[1].Float(),xml->body[2].Float());
|
||||
}
|
||||
|
||||
template<> AffineSpace3fa CoronaLoader::load<AffineSpace3fa>(const Ref<XML>& xml)
|
||||
{
|
||||
if (xml->body.size() != 12) THROW_RUNTIME_ERROR(xml->loc.str()+": wrong AffineSpace body");
|
||||
return AffineSpace3fa(LinearSpace3fa(xml->body[0].Float(),xml->body[1].Float(),xml->body[ 2].Float(),
|
||||
xml->body[4].Float(),xml->body[5].Float(),xml->body[ 6].Float(),
|
||||
xml->body[8].Float(),xml->body[9].Float(),xml->body[10].Float()),
|
||||
Vec3fa(xml->body[3].Float(),xml->body[7].Float(),xml->body[11].Float()));
|
||||
}
|
||||
|
||||
Ref<SceneGraph::MaterialNode> CoronaLoader::loadMaterial(const Ref<XML>& xml)
|
||||
{
|
||||
if (xml->name != "material")
|
||||
THROW_RUNTIME_ERROR(xml->loc.str()+": invalid material: "+xml->name);
|
||||
|
||||
/* native material */
|
||||
if (xml->parm("class") == "Native")
|
||||
{
|
||||
/* we convert into an OBJ material */
|
||||
Ref<OBJMaterial> objmaterial = new OBJMaterial;
|
||||
for (auto& child : xml->children)
|
||||
{
|
||||
if (child->name == "diffuse") {
|
||||
objmaterial->Kd = load<Vec3fa>(child);
|
||||
if (child->children.size() && child->children[0]->name == "map")
|
||||
objmaterial->_map_Kd = loadMap(child->children[0]);
|
||||
}
|
||||
else if (child->name == "reflect") {
|
||||
objmaterial->Ks = load<Vec3fa>(child->child("color"));
|
||||
objmaterial->Ni = load<float >(child->child("ior"));
|
||||
objmaterial->Ns = load<float >(child->child("glossiness"));
|
||||
}
|
||||
else if (child->name == "translucency") {
|
||||
objmaterial->Kt = load<Vec3fa>(child->child("color"));
|
||||
}
|
||||
else if (child->name == "opacity") {
|
||||
objmaterial->d = load<Vec3fa>(child).x;
|
||||
if (child->children.size() && child->children[0]->name == "map")
|
||||
objmaterial->_map_d = loadMap(child->children[0]);
|
||||
}
|
||||
}
|
||||
return objmaterial.dynamicCast<SceneGraph::MaterialNode>();
|
||||
}
|
||||
|
||||
/* reference by name */
|
||||
else if (xml->parm("class") == "Reference")
|
||||
{
|
||||
const std::string name = load<std::string>(xml);
|
||||
return materialMap[name];
|
||||
}
|
||||
|
||||
/* else return default material */
|
||||
else
|
||||
return new OBJMaterial;
|
||||
}
|
||||
|
||||
void CoronaLoader::loadMaterialDefinition(const Ref<XML>& xml)
|
||||
{
|
||||
if (xml->name != "materialDefinition")
|
||||
THROW_RUNTIME_ERROR(xml->loc.str()+": invalid material definition: "+xml->name);
|
||||
if (xml->children.size() != 1)
|
||||
THROW_RUNTIME_ERROR(xml->loc.str()+": invalid material definition");
|
||||
|
||||
const std::string name = xml->parm("name");
|
||||
materialMap[name] = loadMaterial(xml->children[0]);
|
||||
}
|
||||
|
||||
std::shared_ptr<Texture> CoronaLoader::loadMap(const Ref<XML>& xml)
|
||||
{
|
||||
/* process map node */
|
||||
if (xml->name == "map")
|
||||
{
|
||||
std::string mapClass = xml->parm("class");
|
||||
|
||||
/* load textures */
|
||||
if (mapClass == "Texture")
|
||||
{
|
||||
const FileName src = load<FileName>(xml->child("image"));
|
||||
|
||||
/* load images only once */
|
||||
if (textureFileMap.find(src) != textureFileMap.end())
|
||||
return textureFileMap[src];
|
||||
|
||||
try {
|
||||
return Texture::load(path+src);
|
||||
} catch (const std::runtime_error& e) {
|
||||
std::cerr << "failed to load " << path+src << ": " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
else if (mapClass == "Reference") {
|
||||
const std::string name = load<std::string>(xml);
|
||||
return textureMap[name];
|
||||
}
|
||||
}
|
||||
|
||||
/* recurse into every unknown node to find some texture */
|
||||
for (auto& child : xml->children) {
|
||||
std::shared_ptr<Texture> texture = loadMap(child);
|
||||
if (texture) return texture;
|
||||
}
|
||||
return std::shared_ptr<Texture>();
|
||||
}
|
||||
|
||||
void CoronaLoader::loadMapDefinition(const Ref<XML>& xml)
|
||||
{
|
||||
if (xml->name != "mapDefinition")
|
||||
THROW_RUNTIME_ERROR(xml->loc.str()+": invalid map definition: "+xml->name);
|
||||
if (xml->children.size() != 1)
|
||||
THROW_RUNTIME_ERROR(xml->loc.str()+": invalid map definition");
|
||||
|
||||
const std::string name = xml->parm("name");
|
||||
std::shared_ptr<Texture> texture = loadMap(xml->children[0]);
|
||||
if (texture) textureMap[name] = texture;
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> CoronaLoader::loadMaterialLibrary(const FileName& fileName)
|
||||
{
|
||||
Ref<XML> xml = parseXML(path+fileName,"/.-",false);
|
||||
if (xml->name != "mtlLib")
|
||||
THROW_RUNTIME_ERROR(xml->loc.str()+": invalid material library");
|
||||
|
||||
for (auto& child : xml->children)
|
||||
{
|
||||
if (child->name == "materialDefinition") {
|
||||
loadMaterialDefinition(child);
|
||||
}
|
||||
else if (child->name == "mapDefinition")
|
||||
loadMapDefinition(child);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> CoronaLoader::loadObject(const Ref<XML>& xml)
|
||||
{
|
||||
if (xml->name != "object")
|
||||
THROW_RUNTIME_ERROR(xml->loc.str()+": invalid object node");
|
||||
if (xml->parm("class") != "file")
|
||||
THROW_RUNTIME_ERROR(xml->loc.str()+": invalid object class");
|
||||
const FileName fileName = load<FileName>(xml);
|
||||
return SceneGraph::load(path+fileName);
|
||||
}
|
||||
|
||||
std::pair<Ref<SceneGraph::MaterialNode>, avector<AffineSpace3fa> > CoronaLoader::loadInstances(const Ref<XML>& xml)
|
||||
{
|
||||
if (xml->name != "instance")
|
||||
THROW_RUNTIME_ERROR(xml->loc.str()+": invalid instance node");
|
||||
|
||||
/* create default material */
|
||||
Ref<SceneGraph::MaterialNode> material = new OBJMaterial;
|
||||
|
||||
avector<AffineSpace3fa> xfms;
|
||||
for (size_t i=0; i<xml->children.size(); i++)
|
||||
{
|
||||
Ref<XML> child = xml->children[i];
|
||||
if (child->name == "material" ) material = loadMaterial(child);
|
||||
else if (child->name == "transform") xfms.push_back(load<AffineSpace3fa>(child));
|
||||
else THROW_RUNTIME_ERROR(child->loc.str()+": unknown node: "+child->name);
|
||||
}
|
||||
|
||||
return std::make_pair(material,xfms);
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> CoronaLoader::loadGroupNode(const Ref<XML>& xml)
|
||||
{
|
||||
if (xml->children.size() < 1)
|
||||
THROW_RUNTIME_ERROR(xml->loc.str()+": invalid group node");
|
||||
|
||||
/* load instances */
|
||||
auto p = loadInstances(xml->children[0]);
|
||||
Ref<SceneGraph::MaterialNode> material = p.first;
|
||||
avector<AffineSpace3fa>& xfms = p.second;
|
||||
|
||||
/* load meshes */
|
||||
Ref<SceneGraph::GroupNode> objects = new SceneGraph::GroupNode;
|
||||
for (size_t i=1; i<xml->children.size(); i++)
|
||||
objects->add(loadObject(xml->children[i]));
|
||||
|
||||
/* force material */
|
||||
objects->setMaterial(material);
|
||||
|
||||
/* create instances */
|
||||
Ref<SceneGraph::GroupNode> instances = new SceneGraph::GroupNode;
|
||||
for (size_t i=0; i<xfms.size(); i++)
|
||||
instances->add(new SceneGraph::TransformNode(xfms[i],objects.cast<SceneGraph::Node>()));
|
||||
|
||||
return instances.cast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> CoronaLoader::loadNode(const Ref<XML>& xml)
|
||||
{
|
||||
if (xml->name == "conffile" ) return nullptr;
|
||||
else if (xml->name == "mtllib" ) return loadMaterialLibrary(load<FileName>(xml));
|
||||
else if (xml->name == "camera" ) return nullptr;
|
||||
else if (xml->name == "environment" ) return nullptr;
|
||||
else if (xml->name == "geometryGroup") return loadGroupNode(xml);
|
||||
else if (xml->name == "renderElement") return nullptr;
|
||||
else THROW_RUNTIME_ERROR(xml->loc.str()+": unknown tag: "+xml->name);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> CoronaLoader::load(const FileName& fileName, const AffineSpace3fa& space) {
|
||||
CoronaLoader loader(fileName,space); return loader.root;
|
||||
}
|
||||
|
||||
CoronaLoader::CoronaLoader(const FileName& fileName, const AffineSpace3fa& space)
|
||||
{
|
||||
path = fileName.path();
|
||||
Ref<XML> xml = parseXML(fileName,"/.-",false);
|
||||
if (xml->name == "scene")
|
||||
{
|
||||
Ref<SceneGraph::GroupNode> group = new SceneGraph::GroupNode;
|
||||
for (size_t i=0; i<xml->children.size(); i++) {
|
||||
group->add(loadNode(xml->children[i]));
|
||||
}
|
||||
root = group.cast<SceneGraph::Node>();
|
||||
}
|
||||
else
|
||||
THROW_RUNTIME_ERROR(xml->loc.str()+": invalid scene tag");
|
||||
|
||||
if (space == AffineSpace3fa(one))
|
||||
return;
|
||||
|
||||
root = new SceneGraph::TransformNode(space,root);
|
||||
}
|
||||
|
||||
/*! read from disk */
|
||||
Ref<SceneGraph::Node> SceneGraph::loadCorona(const FileName& fileName, const AffineSpace3fa& space) {
|
||||
return CoronaLoader::load(fileName,space);
|
||||
}
|
||||
}
|
||||
14
Framework/external/embree/tutorials/common/scenegraph/corona_loader.h
vendored
Normal file
14
Framework/external/embree/tutorials/common/scenegraph/corona_loader.h
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "scenegraph.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace SceneGraph
|
||||
{
|
||||
Ref<SceneGraph::Node> loadCorona(const FileName& fileName, const AffineSpace3fa& space = one);
|
||||
}
|
||||
}
|
||||
693
Framework/external/embree/tutorials/common/scenegraph/geometry_creation.cpp
vendored
Normal file
693
Framework/external/embree/tutorials/common/scenegraph/geometry_creation.cpp
vendored
Normal file
|
|
@ -0,0 +1,693 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "geometry_creation.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
Ref<SceneGraph::Node> SceneGraph::createTrianglePlane (const Vec3fa& p0, const Vec3fa& dx, const Vec3fa& dy, size_t width, size_t height, Ref<MaterialNode> material)
|
||||
{
|
||||
Ref<SceneGraph::TriangleMeshNode> mesh = new SceneGraph::TriangleMeshNode(material,BBox1f(0,1),1);
|
||||
mesh->positions[0].resize((width+1)*(height+1));
|
||||
mesh->triangles.resize(2*width*height);
|
||||
|
||||
for (size_t y=0; y<=height; y++) {
|
||||
for (size_t x=0; x<=width; x++) {
|
||||
Vec3fa p = p0+float(x)/float(width)*dx+float(y)/float(height)*dy;
|
||||
size_t i = y*(width+1)+x;
|
||||
mesh->positions[0][i].x = p.x;
|
||||
mesh->positions[0][i].y = p.y;
|
||||
mesh->positions[0][i].z = p.z;
|
||||
}
|
||||
}
|
||||
for (size_t y=0; y<height; y++) {
|
||||
for (size_t x=0; x<width; x++) {
|
||||
size_t i = 2*y*width+2*x;
|
||||
size_t p00 = (y+0)*(width+1)+(x+0);
|
||||
size_t p01 = (y+0)*(width+1)+(x+1);
|
||||
size_t p10 = (y+1)*(width+1)+(x+0);
|
||||
size_t p11 = (y+1)*(width+1)+(x+1);
|
||||
mesh->triangles[i+0].v0 = unsigned(p00); mesh->triangles[i+0].v1 = unsigned(p01); mesh->triangles[i+0].v2 = unsigned(p10);
|
||||
mesh->triangles[i+1].v0 = unsigned(p11); mesh->triangles[i+1].v1 = unsigned(p10); mesh->triangles[i+1].v2 = unsigned(p01);
|
||||
}
|
||||
}
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createQuadPlane (const Vec3fa& p0, const Vec3fa& dx, const Vec3fa& dy, size_t width, size_t height, Ref<MaterialNode> material)
|
||||
{
|
||||
Ref<SceneGraph::QuadMeshNode> mesh = new SceneGraph::QuadMeshNode(material,BBox1f(0,1),1);
|
||||
mesh->positions[0].resize((width+1)*(height+1));
|
||||
mesh->quads.resize(width*height);
|
||||
|
||||
for (size_t y=0; y<=height; y++) {
|
||||
for (size_t x=0; x<=width; x++) {
|
||||
Vec3fa p = p0+float(x)/float(width)*dx+float(y)/float(height)*dy;
|
||||
size_t i = y*(width+1)+x;
|
||||
mesh->positions[0][i].x = p.x;
|
||||
mesh->positions[0][i].y = p.y;
|
||||
mesh->positions[0][i].z = p.z;
|
||||
}
|
||||
}
|
||||
for (size_t y=0; y<height; y++) {
|
||||
for (size_t x=0; x<width; x++) {
|
||||
size_t i = y*width+x;
|
||||
size_t p00 = (y+0)*(width+1)+(x+0);
|
||||
size_t p01 = (y+0)*(width+1)+(x+1);
|
||||
size_t p10 = (y+1)*(width+1)+(x+0);
|
||||
size_t p11 = (y+1)*(width+1)+(x+1);
|
||||
mesh->quads[i].v0 = unsigned(p00);
|
||||
mesh->quads[i].v1 = unsigned(p01);
|
||||
mesh->quads[i].v2 = unsigned(p11);
|
||||
mesh->quads[i].v3 = unsigned(p10);
|
||||
}
|
||||
}
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createGridPlane (const Vec3fa& p0, const Vec3fa& dx, const Vec3fa& dy, size_t width, size_t height, Ref<MaterialNode> material)
|
||||
{
|
||||
Ref<SceneGraph::GridMeshNode> mesh = new SceneGraph::GridMeshNode(material,BBox1f(0,1),1);
|
||||
mesh->positions[0].resize((width+1)*(height+1));
|
||||
mesh->grids.push_back(SceneGraph::GridMeshNode::Grid(0,(unsigned)width+1,(unsigned)width+1,(unsigned)height+1));
|
||||
|
||||
for (size_t y=0; y<=height; y++) {
|
||||
for (size_t x=0; x<=width; x++) {
|
||||
Vec3fa p = p0+float(x)/float(width)*dx+float(y)/float(height)*dy;
|
||||
size_t i = y*(width+1)+x;
|
||||
mesh->positions[0][i].x = p.x;
|
||||
mesh->positions[0][i].y = p.y;
|
||||
mesh->positions[0][i].z = p.z;
|
||||
}
|
||||
}
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createSubdivPlane (const Vec3fa& p0, const Vec3fa& dx, const Vec3fa& dy, size_t width, size_t height, float tessellationRate, Ref<MaterialNode> material)
|
||||
{
|
||||
Ref<SceneGraph::SubdivMeshNode> mesh = new SceneGraph::SubdivMeshNode(material,BBox1f(0,1),1);
|
||||
mesh->tessellationRate = tessellationRate;
|
||||
mesh->positions[0].resize((width+1)*(height+1));
|
||||
mesh->position_indices.resize(4*width*height);
|
||||
mesh->verticesPerFace.resize(width*height);
|
||||
|
||||
for (size_t y=0; y<=height; y++) {
|
||||
for (size_t x=0; x<=width; x++) {
|
||||
Vec3fa p = p0+float(x)/float(width)*dx+float(y)/float(height)*dy;
|
||||
size_t i = y*(width+1)+x;
|
||||
mesh->positions[0][i].x = p.x;
|
||||
mesh->positions[0][i].y = p.y;
|
||||
mesh->positions[0][i].z = p.z;
|
||||
}
|
||||
}
|
||||
for (size_t y=0; y<height; y++) {
|
||||
for (size_t x=0; x<width; x++) {
|
||||
size_t i = y*width+x;
|
||||
size_t p00 = (y+0)*(width+1)+(x+0);
|
||||
size_t p01 = (y+0)*(width+1)+(x+1);
|
||||
size_t p10 = (y+1)*(width+1)+(x+0);
|
||||
size_t p11 = (y+1)*(width+1)+(x+1);
|
||||
mesh->position_indices[4*i+0] = unsigned(p00);
|
||||
mesh->position_indices[4*i+1] = unsigned(p01);
|
||||
mesh->position_indices[4*i+2] = unsigned(p11);
|
||||
mesh->position_indices[4*i+3] = unsigned(p10);
|
||||
mesh->verticesPerFace[i] = 4;
|
||||
}
|
||||
}
|
||||
mesh->position_subdiv_mode = RTC_SUBDIVISION_MODE_PIN_CORNERS;
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createTriangleSphere (const Vec3fa& center, const float radius, size_t N, Ref<MaterialNode> material)
|
||||
{
|
||||
unsigned numPhi = unsigned(N);
|
||||
unsigned numTheta = 2*numPhi;
|
||||
unsigned numVertices = numTheta*(numPhi+1);
|
||||
Ref<SceneGraph::TriangleMeshNode> mesh = new SceneGraph::TriangleMeshNode(material,BBox1f(0,1),1);
|
||||
mesh->positions[0].resize(numVertices);
|
||||
|
||||
/* create sphere geometry */
|
||||
const float rcpNumTheta = rcp(float(numTheta));
|
||||
const float rcpNumPhi = rcp(float(numPhi));
|
||||
for (unsigned int phi=0; phi<=numPhi; phi++)
|
||||
{
|
||||
for (unsigned int theta=0; theta<numTheta; theta++)
|
||||
{
|
||||
const float phif = phi*float(pi)*rcpNumPhi;
|
||||
const float thetaf = theta*2.0f*float(pi)*rcpNumTheta;
|
||||
mesh->positions[0][phi*numTheta+theta].x = center.x + radius*sin(phif)*sin(thetaf);
|
||||
mesh->positions[0][phi*numTheta+theta].y = center.y + radius*cos(phif);
|
||||
mesh->positions[0][phi*numTheta+theta].z = center.z + radius*sin(phif)*cos(thetaf);
|
||||
}
|
||||
if (phi == 0) continue;
|
||||
|
||||
if (phi == 1)
|
||||
{
|
||||
for (unsigned int theta=1; theta<=numTheta; theta++)
|
||||
{
|
||||
unsigned int p00 = numTheta-1;
|
||||
unsigned int p10 = phi*numTheta+theta-1;
|
||||
unsigned int p11 = phi*numTheta+theta%numTheta;
|
||||
mesh->triangles.push_back(TriangleMeshNode::Triangle(p10,p00,p11));
|
||||
}
|
||||
}
|
||||
else if (phi == numPhi)
|
||||
{
|
||||
for (unsigned int theta=1; theta<=numTheta; theta++)
|
||||
{
|
||||
unsigned int p00 = (phi-1)*numTheta+theta-1;
|
||||
unsigned int p01 = (phi-1)*numTheta+theta%numTheta;
|
||||
unsigned int p10 = numPhi*numTheta;
|
||||
mesh->triangles.push_back(TriangleMeshNode::Triangle(p10,p00,p01));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned int theta=1; theta<=numTheta; theta++)
|
||||
{
|
||||
unsigned int p00 = (phi-1)*numTheta+theta-1;
|
||||
unsigned int p01 = (phi-1)*numTheta+theta%numTheta;
|
||||
unsigned int p10 = phi*numTheta+theta-1;
|
||||
unsigned int p11 = phi*numTheta+theta%numTheta;
|
||||
mesh->triangles.push_back(TriangleMeshNode::Triangle(p10,p00,p11));
|
||||
mesh->triangles.push_back(TriangleMeshNode::Triangle(p01,p11,p00));
|
||||
}
|
||||
}
|
||||
}
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createQuadSphere (const Vec3fa& center, const float radius, size_t N, Ref<MaterialNode> material)
|
||||
{
|
||||
unsigned numPhi = unsigned(N);
|
||||
unsigned numTheta = 2*numPhi;
|
||||
unsigned numVertices = numTheta*(numPhi+1);
|
||||
Ref<SceneGraph::QuadMeshNode> mesh = new SceneGraph::QuadMeshNode(material,BBox1f(0,1),1);
|
||||
mesh->positions[0].resize(numVertices);
|
||||
|
||||
/* create sphere geometry */
|
||||
const float rcpNumTheta = rcp(float(numTheta));
|
||||
const float rcpNumPhi = rcp(float(numPhi));
|
||||
for (unsigned int phi=0; phi<=numPhi; phi++)
|
||||
{
|
||||
for (unsigned int theta=0; theta<numTheta; theta++)
|
||||
{
|
||||
const float phif = phi*float(pi)*rcpNumPhi;
|
||||
const float thetaf = theta*2.0f*float(pi)*rcpNumTheta;
|
||||
mesh->positions[0][phi*numTheta+theta].x = center.x + radius*sin(phif)*sin(thetaf);
|
||||
mesh->positions[0][phi*numTheta+theta].y = center.y + radius*cos(phif);
|
||||
mesh->positions[0][phi*numTheta+theta].z = center.z + radius*sin(phif)*cos(thetaf);
|
||||
}
|
||||
if (phi == 0) continue;
|
||||
|
||||
if (phi == 1)
|
||||
{
|
||||
for (unsigned int theta=1; theta<=numTheta; theta++)
|
||||
{
|
||||
unsigned int p00 = numTheta-1;
|
||||
unsigned int p10 = phi*numTheta+theta-1;
|
||||
unsigned int p11 = phi*numTheta+theta%numTheta;
|
||||
mesh->quads.push_back(QuadMeshNode::Quad(p10,p00,p11,p11));
|
||||
}
|
||||
}
|
||||
else if (phi == numPhi)
|
||||
{
|
||||
for (unsigned int theta=1; theta<=numTheta; theta++)
|
||||
{
|
||||
unsigned int p00 = (phi-1)*numTheta+theta-1;
|
||||
unsigned int p01 = (phi-1)*numTheta+theta%numTheta;
|
||||
unsigned int p10 = numPhi*numTheta;
|
||||
mesh->quads.push_back(QuadMeshNode::Quad(p10,p00,p01,p01));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned int theta=1; theta<=numTheta; theta++)
|
||||
{
|
||||
unsigned int p00 = (phi-1)*numTheta+theta-1;
|
||||
unsigned int p01 = (phi-1)*numTheta+theta%numTheta;
|
||||
unsigned int p10 = phi*numTheta+theta-1;
|
||||
unsigned int p11 = phi*numTheta+theta%numTheta;
|
||||
mesh->quads.push_back(QuadMeshNode::Quad(p10,p00,p01,p11));
|
||||
}
|
||||
}
|
||||
}
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createGridSphere (const Vec3fa& center, const float radius, size_t N, Ref<MaterialNode> material)
|
||||
{
|
||||
size_t grid_size = (N+1)*(N+1);
|
||||
Ref<SceneGraph::GridMeshNode> mesh = new SceneGraph::GridMeshNode(material,BBox1f(0,1),1);
|
||||
mesh->positions[0].resize(grid_size*6);
|
||||
|
||||
for (size_t i=0; i<6; i++)
|
||||
{
|
||||
mesh->grids.push_back(SceneGraph::GridMeshNode::Grid(unsigned(i*grid_size),unsigned(N+1),unsigned(N+1),unsigned(N+1)));
|
||||
Vec3fa p0, dx, dy;
|
||||
switch (i) {
|
||||
case 0: p0 = Vec3fa(-0.5f,-0.5f,-0.5f); dx = Vec3fa(+1,0, 0); dy = Vec3fa(0,1,0); break;
|
||||
case 1: p0 = Vec3fa(+0.5f,-0.5f,-0.5f); dx = Vec3fa( 0,0,+1); dy = Vec3fa(0,1,0); break;
|
||||
case 2: p0 = Vec3fa(+0.5f,-0.5f,+0.5f); dx = Vec3fa(-1,0, 0); dy = Vec3fa(0,1,0); break;
|
||||
case 3: p0 = Vec3fa(-0.5f,-0.5f,+0.5f); dx = Vec3fa( 0,0,-1); dy = Vec3fa(0,1,0); break;
|
||||
case 4: p0 = Vec3fa(-0.5f,-0.5f,-0.5f); dx = Vec3fa( 0,0,+1); dy = Vec3fa(1,0,0); break;
|
||||
case 5: p0 = Vec3fa(-0.5f,+0.5f,-0.5f); dx = Vec3fa( 1,0, 0); dy = Vec3fa(0,0,1); break;
|
||||
default: assert(false);
|
||||
}
|
||||
|
||||
for (size_t y=0; y<=N; y++) {
|
||||
for (size_t x=0; x<=N; x++) {
|
||||
size_t j = i*grid_size + y*(N+1) + x;
|
||||
Vec3fa p = p0+float(x)/float(N)*dx+float(y)/float(N)*dy;
|
||||
mesh->positions[0][j] = center + radius*normalize(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createSubdivSphere (const Vec3fa& center, const float radius, size_t N, float tessellationRate, Ref<MaterialNode> material)
|
||||
{
|
||||
unsigned numPhi = unsigned(N);
|
||||
unsigned numTheta = 2*numPhi;
|
||||
unsigned numVertices = numTheta*(numPhi+1);
|
||||
Ref<SceneGraph::SubdivMeshNode> mesh = new SceneGraph::SubdivMeshNode(material,BBox1f(0,1),1);
|
||||
mesh->tessellationRate = tessellationRate;
|
||||
mesh->positions[0].resize(numVertices);
|
||||
|
||||
/* create sphere geometry */
|
||||
const float rcpNumTheta = rcp((float)numTheta);
|
||||
const float rcpNumPhi = rcp((float)numPhi);
|
||||
for (unsigned int phi=0; phi<=numPhi; phi++)
|
||||
{
|
||||
for (unsigned int theta=0; theta<numTheta; theta++)
|
||||
{
|
||||
const float phif = phi*float(pi)*rcpNumPhi;
|
||||
const float thetaf = theta*2.0f*float(pi)*rcpNumTheta;
|
||||
mesh->positions[0][phi*numTheta+theta].x = center.x + radius*sin(phif)*sin(thetaf);
|
||||
mesh->positions[0][phi*numTheta+theta].y = center.y + radius*cos(phif);
|
||||
mesh->positions[0][phi*numTheta+theta].z = center.z + radius*sin(phif)*cos(thetaf);
|
||||
}
|
||||
if (phi == 0) continue;
|
||||
|
||||
if (phi == 1)
|
||||
{
|
||||
for (unsigned int theta=1; theta<=numTheta; theta++)
|
||||
{
|
||||
unsigned int p00 = numTheta-1;
|
||||
unsigned int p10 = phi*numTheta+theta-1;
|
||||
unsigned int p11 = phi*numTheta+theta%numTheta;
|
||||
mesh->verticesPerFace.push_back(3);
|
||||
mesh->position_indices.push_back(p10);
|
||||
mesh->position_indices.push_back(p00);
|
||||
mesh->position_indices.push_back(p11);
|
||||
}
|
||||
}
|
||||
else if (phi == numPhi)
|
||||
{
|
||||
for (unsigned int theta=1; theta<=numTheta; theta++)
|
||||
{
|
||||
unsigned int p00 = (phi-1)*numTheta+theta-1;
|
||||
unsigned int p01 = (phi-1)*numTheta+theta%numTheta;
|
||||
unsigned int p10 = numPhi*numTheta;
|
||||
mesh->verticesPerFace.push_back(3);
|
||||
mesh->position_indices.push_back(p10);
|
||||
mesh->position_indices.push_back(p00);
|
||||
mesh->position_indices.push_back(p01);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned int theta=1; theta<=numTheta; theta++)
|
||||
{
|
||||
unsigned int p00 = (phi-1)*numTheta+theta-1;
|
||||
unsigned int p01 = (phi-1)*numTheta+theta%numTheta;
|
||||
unsigned int p10 = phi*numTheta+theta-1;
|
||||
unsigned int p11 = phi*numTheta+theta%numTheta;
|
||||
mesh->verticesPerFace.push_back(4);
|
||||
mesh->position_indices.push_back(p10);
|
||||
mesh->position_indices.push_back(p00);
|
||||
mesh->position_indices.push_back(p01);
|
||||
mesh->position_indices.push_back(p11);
|
||||
}
|
||||
}
|
||||
}
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createSphereShapedHair(const Vec3fa& center, const float radius, Ref<MaterialNode> material)
|
||||
{
|
||||
Ref<SceneGraph::HairSetNode> mesh = new SceneGraph::HairSetNode(RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE,material,BBox1f(0,1),1);
|
||||
mesh->hairs.push_back(SceneGraph::HairSetNode::Hair(0,0));
|
||||
mesh->positions[0].push_back(Vec3ff(center+Vec3fa(-radius,0,0),radius));
|
||||
mesh->positions[0].push_back(Vec3ff(center+Vec3fa(0,0,0),radius));
|
||||
mesh->positions[0].push_back(Vec3ff(center+Vec3fa(0,0,0),radius));
|
||||
mesh->positions[0].push_back(Vec3ff(center+Vec3fa(+radius,0,0),radius));
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createSphere (const Vec3fa& center, const float radius, Ref<MaterialNode> material)
|
||||
{
|
||||
RTCGeometryType type = RTC_GEOMETRY_TYPE_SPHERE_POINT;
|
||||
Ref<SceneGraph::PointSetNode> mesh = new SceneGraph::PointSetNode(type, material, BBox1f(0,1), 1);
|
||||
mesh->positions[0].resize(1);
|
||||
mesh->positions[0][0].x = center.x;
|
||||
mesh->positions[0][0].y = center.y;
|
||||
mesh->positions[0][0].z = center.z;
|
||||
mesh->positions[0][0].w = radius;
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createPointSphere (const Vec3fa& center, const float radius, const float pointRadius,
|
||||
size_t N, PointSubtype subtype, Ref<MaterialNode> material)
|
||||
{
|
||||
unsigned numPhi = unsigned(N);
|
||||
unsigned numTheta = 2 * numPhi;
|
||||
unsigned numVertices = numTheta * (numPhi + 1);
|
||||
|
||||
RTCGeometryType type;
|
||||
switch (subtype) {
|
||||
case SPHERE:
|
||||
type = RTC_GEOMETRY_TYPE_SPHERE_POINT;
|
||||
break;
|
||||
case DISC:
|
||||
type = RTC_GEOMETRY_TYPE_DISC_POINT;
|
||||
break;
|
||||
case ORIENTED_DISC:
|
||||
type = RTC_GEOMETRY_TYPE_ORIENTED_DISC_POINT;
|
||||
break;
|
||||
}
|
||||
|
||||
Ref<SceneGraph::PointSetNode> mesh = new SceneGraph::PointSetNode(type, material, BBox1f(0,1), 1);
|
||||
mesh->positions[0].resize(numVertices);
|
||||
if (subtype == ORIENTED_DISC) {
|
||||
mesh->normals.push_back(avector<Vec3fa>());
|
||||
mesh->normals[0].resize(numVertices);
|
||||
}
|
||||
|
||||
/* create sphere geometry */
|
||||
const float rcpNumTheta = rcp(float(numTheta));
|
||||
const float rcpNumPhi = rcp(float(numPhi));
|
||||
for (unsigned int phi = 0; phi <= numPhi; phi++)
|
||||
{
|
||||
for (unsigned int theta = 0; theta < numTheta; theta++)
|
||||
{
|
||||
const float phif = phi * float(pi) * rcpNumPhi;
|
||||
const float thetaf = theta * 2.0f * float(pi) * rcpNumTheta;
|
||||
mesh->positions[0][phi * numTheta + theta].x = center.x + radius * sin(phif) * sin(thetaf);
|
||||
mesh->positions[0][phi * numTheta + theta].y = center.y + radius * cos(phif);
|
||||
mesh->positions[0][phi * numTheta + theta].z = center.z + radius * sin(phif) * cos(thetaf);
|
||||
mesh->positions[0][phi * numTheta + theta].w = pointRadius;
|
||||
if (subtype == ORIENTED_DISC)
|
||||
mesh->normals[0][phi * numTheta + theta] =
|
||||
normalize(mesh->positions[0][phi * numTheta + theta] - center);
|
||||
}
|
||||
}
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createHairyPlane (int hash, const Vec3fa& pos, const Vec3fa& dx, const Vec3fa& dy, const float len, const float r, size_t numHairs, CurveSubtype subtype, Ref<MaterialNode> material)
|
||||
{
|
||||
RandomSampler sampler;
|
||||
RandomSampler_init(sampler,hash);
|
||||
|
||||
RTCGeometryType type = (subtype == ROUND_CURVE) ? RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE : RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE;
|
||||
Ref<SceneGraph::HairSetNode> mesh = new SceneGraph::HairSetNode(type,material,BBox1f(0,1),1);
|
||||
|
||||
if (numHairs == 1) {
|
||||
const Vec3fa p0 = pos;
|
||||
const Vec3fa p1 = p0 + len*Vec3fa(1,0,0);
|
||||
const Vec3fa p2 = p0 + len*Vec3fa(0,1,1);
|
||||
const Vec3fa p3 = p0 + len*Vec3fa(0,1,0);
|
||||
mesh->hairs.push_back(HairSetNode::Hair(0,0));
|
||||
mesh->positions[0].push_back(Vec3ff(p0,r));
|
||||
mesh->positions[0].push_back(Vec3ff(p1,r));
|
||||
mesh->positions[0].push_back(Vec3ff(p2,r));
|
||||
mesh->positions[0].push_back(Vec3ff(p3,r));
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Vec3fa dz = cross(dx,dy);
|
||||
for (size_t i=0; i<numHairs; i++)
|
||||
{
|
||||
const Vec3fa p0 = pos + RandomSampler_getFloat(sampler)*dx + RandomSampler_getFloat(sampler)*dy;
|
||||
const Vec3fa p1 = p0 + len*normalize(dx);
|
||||
const Vec3fa p2 = p0 + len*(normalize(dz)+normalize(dy));
|
||||
const Vec3fa p3 = p0 + len*normalize(dz);
|
||||
mesh->hairs.push_back(HairSetNode::Hair(unsigned(4*i),unsigned(i)));
|
||||
mesh->positions[0].push_back(Vec3ff(p0,r));
|
||||
mesh->positions[0].push_back(Vec3ff(p1,r));
|
||||
mesh->positions[0].push_back(Vec3ff(p2,r));
|
||||
mesh->positions[0].push_back(Vec3ff(p3,r));
|
||||
}
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createGarbageTriangleMesh (int hash, size_t numTriangles, bool mblur, Ref<MaterialNode> material)
|
||||
{
|
||||
RandomSampler sampler;
|
||||
RandomSampler_init(sampler,hash);
|
||||
Ref<SceneGraph::TriangleMeshNode> mesh = new SceneGraph::TriangleMeshNode(material,BBox1f(0,1),mblur?2:1);
|
||||
|
||||
mesh->triangles.resize(numTriangles);
|
||||
for (size_t i=0; i<numTriangles; i++) {
|
||||
const unsigned v0 = (RandomSampler_getInt(sampler) % 32 == 0) ? RandomSampler_getUInt(sampler) : unsigned(3*i+0);
|
||||
const unsigned v1 = (RandomSampler_getInt(sampler) % 32 == 0) ? RandomSampler_getUInt(sampler) : unsigned(3*i+1);
|
||||
const unsigned v2 = (RandomSampler_getInt(sampler) % 32 == 0) ? RandomSampler_getUInt(sampler) : unsigned(3*i+2);
|
||||
mesh->triangles[i] = TriangleMeshNode::Triangle(v0,v1,v2);
|
||||
}
|
||||
|
||||
mesh->positions[0].resize(3*numTriangles);
|
||||
for (size_t i=0; i<3*numTriangles; i++) {
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float w = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[0][i] = Vec3ff(x,y,z,w);
|
||||
}
|
||||
|
||||
if (mblur)
|
||||
{
|
||||
mesh->positions[1].resize(3*numTriangles);
|
||||
for (size_t i=0; i<3*numTriangles; i++) {
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float w = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[1][i] = Vec3ff(x,y,z,w);
|
||||
}
|
||||
}
|
||||
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createGarbageQuadMesh (int hash, size_t numQuads, bool mblur, Ref<MaterialNode> material)
|
||||
{
|
||||
RandomSampler sampler;
|
||||
RandomSampler_init(sampler,hash);
|
||||
Ref<SceneGraph::QuadMeshNode> mesh = new SceneGraph::QuadMeshNode(material,BBox1f(0,1),mblur?2:1);
|
||||
|
||||
mesh->quads.resize(numQuads);
|
||||
for (size_t i=0; i<numQuads; i++) {
|
||||
const unsigned v0 = (RandomSampler_getInt(sampler) % 32 == 0) ? RandomSampler_getUInt(sampler) : unsigned(4*i+0);
|
||||
const unsigned v1 = (RandomSampler_getInt(sampler) % 32 == 0) ? RandomSampler_getUInt(sampler) : unsigned(4*i+1);
|
||||
const unsigned v2 = (RandomSampler_getInt(sampler) % 32 == 0) ? RandomSampler_getUInt(sampler) : unsigned(4*i+2);
|
||||
const unsigned v3 = (RandomSampler_getInt(sampler) % 32 == 0) ? RandomSampler_getUInt(sampler) : unsigned(4*i+3);
|
||||
mesh->quads[i] = QuadMeshNode::Quad(v0,v1,v2,v3);
|
||||
}
|
||||
|
||||
mesh->positions[0].resize(4*numQuads);
|
||||
for (size_t i=0; i<4*numQuads; i++) {
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float w = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[0][i] = Vec3fa(Vec3ff(x,y,z,w));
|
||||
}
|
||||
|
||||
if (mblur)
|
||||
{
|
||||
mesh->positions[1].resize(4*numQuads);
|
||||
for (size_t i=0; i<4*numQuads; i++) {
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float w = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[1][i] = Vec3fa(Vec3ff(x,y,z,w));
|
||||
}
|
||||
}
|
||||
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createGarbageGridMesh (int hash, size_t numGrids, bool mblur, Ref<MaterialNode> material)
|
||||
{
|
||||
RandomSampler sampler;
|
||||
RandomSampler_init(sampler,hash);
|
||||
Ref<SceneGraph::GridMeshNode> mesh = new SceneGraph::GridMeshNode(material,BBox1f(0,1),mblur?2:1);
|
||||
|
||||
mesh->grids.resize(numGrids);
|
||||
for (size_t i=0; i<numGrids; i++) {
|
||||
const unsigned v0 = (RandomSampler_getInt(sampler) % 32 == 0) ? RandomSampler_getUInt(sampler) : unsigned(4*i+0);
|
||||
mesh->grids[i] = GridMeshNode::Grid(v0,2,2,2);
|
||||
}
|
||||
|
||||
mesh->positions[0].resize(4*numGrids);
|
||||
for (size_t i=0; i<4*numGrids; i++) {
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float w = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[0][i] = Vec3fa(Vec3ff(x,y,z,w));
|
||||
}
|
||||
|
||||
if (mblur)
|
||||
{
|
||||
mesh->positions[1].resize(4*numGrids);
|
||||
for (size_t i=0; i<4*numGrids; i++) {
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float w = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[1][i] = Vec3fa(Vec3ff(x,y,z,w));
|
||||
}
|
||||
}
|
||||
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createGarbageLineSegments (int hash, size_t numLineSegments, bool mblur, Ref<MaterialNode> material)
|
||||
{
|
||||
RandomSampler sampler;
|
||||
RandomSampler_init(sampler,hash);
|
||||
Ref<SceneGraph::HairSetNode> mesh = new SceneGraph::HairSetNode(RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE,material,BBox1f(0,1),mblur?2:1);
|
||||
|
||||
mesh->hairs.resize(numLineSegments);
|
||||
for (size_t i=0; i<numLineSegments; i++) {
|
||||
mesh->hairs[i].vertex = (RandomSampler_getInt(sampler) % 32 == 0) ? RandomSampler_getUInt(sampler) : unsigned(2*i);
|
||||
mesh->hairs[i].id = 0;
|
||||
}
|
||||
|
||||
mesh->positions[0].resize(2*numLineSegments);
|
||||
for (size_t i=0; i<2*numLineSegments; i++) {
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float r = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[0][i] = Vec3ff(x,y,z,r);
|
||||
}
|
||||
|
||||
if (mblur)
|
||||
{
|
||||
mesh->positions[1].resize(2*numLineSegments);
|
||||
for (size_t i=0; i<2*numLineSegments; i++) {
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float r = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[1][i] = Vec3ff(x,y,z,r);
|
||||
}
|
||||
}
|
||||
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createGarbageHair (int hash, size_t numHairs, bool mblur, Ref<MaterialNode> material)
|
||||
{
|
||||
RandomSampler sampler;
|
||||
RandomSampler_init(sampler,hash);
|
||||
Ref<SceneGraph::HairSetNode> mesh = new SceneGraph::HairSetNode(RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE,material,BBox1f(0,1),mblur?2:1);
|
||||
|
||||
mesh->hairs.resize(numHairs);
|
||||
for (size_t i=0; i<numHairs; i++) {
|
||||
const unsigned v0 = (RandomSampler_getInt(sampler) % 32 == 0) ? RandomSampler_getUInt(sampler) : unsigned(4*i);
|
||||
mesh->hairs[i] = HairSetNode::Hair(v0,0);
|
||||
}
|
||||
|
||||
mesh->positions[0].resize(4*numHairs);
|
||||
for (size_t i=0; i<4*numHairs; i++) {
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float r = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[0][i] = Vec3ff(x,y,z,r);
|
||||
}
|
||||
|
||||
if (mblur)
|
||||
{
|
||||
mesh->positions[1].resize(4*numHairs);
|
||||
for (size_t i=0; i<4*numHairs; i++) {
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float r = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[1][i] = Vec3ff(x,y,z,r);
|
||||
}
|
||||
}
|
||||
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createGarbageSubdivMesh (int hash, size_t numFaces, bool mblur, Ref<MaterialNode> material)
|
||||
{
|
||||
RandomSampler sampler;
|
||||
RandomSampler_init(sampler,hash);
|
||||
Ref<SceneGraph::SubdivMeshNode> mesh = new SceneGraph::SubdivMeshNode(material,BBox1f(0,1),mblur?2:1);
|
||||
|
||||
for (size_t i=0; i<numFaces; i++)
|
||||
{
|
||||
const unsigned f = RandomSampler_getInt(sampler) % 20;
|
||||
mesh->verticesPerFace.push_back(f);
|
||||
for (size_t j=0; j<f; j++)
|
||||
{
|
||||
mesh->position_indices.push_back((RandomSampler_getInt(sampler) % 32 == 0) ? RandomSampler_getUInt(sampler) : unsigned(mesh->numPositions()));
|
||||
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float w = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[0].push_back(Vec3fa(Vec3ff(x,y,z,w)));
|
||||
|
||||
if (mblur)
|
||||
{
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float w = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[1].push_back(Vec3fa(Vec3ff(x,y,z,w)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
|
||||
|
||||
Ref<SceneGraph::Node> SceneGraph::createGarbagePointSet(int hash, size_t numPoints, bool mblur, Ref<MaterialNode> material)
|
||||
{
|
||||
RandomSampler sampler;
|
||||
RandomSampler_init(sampler,hash);
|
||||
|
||||
Ref<SceneGraph::PointSetNode> mesh = new SceneGraph::PointSetNode(RTC_GEOMETRY_TYPE_SPHERE_POINT, material,BBox1f(0,1),mblur?2:1);
|
||||
|
||||
for (size_t i = 0; i < numPoints; i++)
|
||||
{
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float r = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[0].push_back(Vec3ff(x, y, z, r));
|
||||
|
||||
if (mblur)
|
||||
{
|
||||
const float x = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float y = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float z = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
const float r = cast_i2f(RandomSampler_getUInt(sampler));
|
||||
mesh->positions[1].push_back(Vec3ff(x, y, z, r));
|
||||
}
|
||||
}
|
||||
|
||||
return mesh.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
}
|
||||
35
Framework/external/embree/tutorials/common/scenegraph/geometry_creation.h
vendored
Normal file
35
Framework/external/embree/tutorials/common/scenegraph/geometry_creation.h
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "scenegraph.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace SceneGraph
|
||||
{
|
||||
Ref<Node> createTrianglePlane (const Vec3fa& p0, const Vec3fa& dx, const Vec3fa& dy, size_t width, size_t height, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createQuadPlane (const Vec3fa& p0, const Vec3fa& dx, const Vec3fa& dy, size_t width, size_t height, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createGridPlane (const Vec3fa& p0, const Vec3fa& dx, const Vec3fa& dy, size_t width, size_t height, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createSubdivPlane (const Vec3fa& p0, const Vec3fa& dx, const Vec3fa& dy, size_t width, size_t height, float tessellationRate, Ref<MaterialNode> material = nullptr);
|
||||
|
||||
Ref<Node> createSphere (const Vec3fa& center, const float radius, Ref<MaterialNode> materiall = nullptr);
|
||||
Ref<Node> createTriangleSphere(const Vec3fa& center, const float radius, size_t numPhi, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createQuadSphere (const Vec3fa& center, const float radius, size_t numPhi, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createGridSphere (const Vec3fa& center, const float radius, size_t size, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createSubdivSphere (const Vec3fa& center, const float radius, size_t numPhi, float tessellationRate, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createSphereShapedHair(const Vec3fa& center, const float radius, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createPointSphere (const Vec3fa& center, const float radius, const float pointRadius, size_t numPhi, PointSubtype subtype, Ref<MaterialNode> materiall = nullptr);
|
||||
|
||||
Ref<Node> createHairyPlane (int hash, const Vec3fa& pos, const Vec3fa& dx, const Vec3fa& dy, const float len, const float r, size_t numHairs, CurveSubtype subtype, Ref<MaterialNode> material = nullptr);
|
||||
|
||||
Ref<Node> createGarbageTriangleMesh (int hash, size_t numTriangles, bool mblur, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createGarbageQuadMesh (int hash, size_t numQuads, bool mblur, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createGarbageGridMesh (int hash, size_t numGrids, bool mblur, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createGarbageHair (int hash, size_t numHairs, bool mblur, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createGarbageLineSegments (int hash, size_t numLineSegments, bool mblur, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createGarbageSubdivMesh (int hash, size_t numFaces, bool mblur, Ref<MaterialNode> material = nullptr);
|
||||
Ref<Node> createGarbagePointSet(int hash, size_t numPoints, bool mblur, Ref<MaterialNode> material = nullptr);
|
||||
}
|
||||
}
|
||||
199
Framework/external/embree/tutorials/common/scenegraph/lights.h
vendored
Normal file
199
Framework/external/embree/tutorials/common/scenegraph/lights.h
vendored
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../default.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace SceneGraph
|
||||
{
|
||||
enum LightType
|
||||
{
|
||||
LIGHT_AMBIENT,
|
||||
LIGHT_POINT,
|
||||
LIGHT_DIRECTIONAL,
|
||||
LIGHT_SPOT,
|
||||
LIGHT_DISTANT,
|
||||
LIGHT_TRIANGLE,
|
||||
LIGHT_QUAD,
|
||||
};
|
||||
|
||||
class Light
|
||||
{
|
||||
ALIGNED_CLASS_(16)
|
||||
|
||||
public:
|
||||
Light(LightType type) : type(type) {}
|
||||
|
||||
LightType getType() const { return type; }
|
||||
|
||||
private:
|
||||
LightType type;
|
||||
};
|
||||
|
||||
class AmbientLight : public Light
|
||||
{
|
||||
public:
|
||||
AmbientLight (const Vec3fa& L)
|
||||
: Light(LIGHT_AMBIENT), L(L) {}
|
||||
|
||||
AmbientLight transform(const AffineSpace3fa& space) const {
|
||||
return AmbientLight(L);
|
||||
}
|
||||
|
||||
static AmbientLight lerp(const AmbientLight& light0, const AmbientLight& light1, const float f) {
|
||||
return AmbientLight(embree::lerp(light0.L,light1.L,f));
|
||||
}
|
||||
|
||||
public:
|
||||
Vec3fa L; //!< radiance of ambient light
|
||||
};
|
||||
|
||||
class PointLight : public Light
|
||||
{
|
||||
public:
|
||||
PointLight (const Vec3fa& P, const Vec3fa& I)
|
||||
: Light(LIGHT_POINT), P(P), I(I) {}
|
||||
|
||||
PointLight transform(const AffineSpace3fa& space) const {
|
||||
return PointLight(xfmPoint(space,P),I);
|
||||
}
|
||||
|
||||
static PointLight lerp(const PointLight& light0, const PointLight& light1, const float f)
|
||||
{
|
||||
return PointLight(embree::lerp(light0.P,light1.P,f),
|
||||
embree::lerp(light0.I,light1.I,f));
|
||||
}
|
||||
|
||||
public:
|
||||
Vec3fa P; //!< position of point light
|
||||
Vec3fa I; //!< radiant intensity of point light
|
||||
};
|
||||
|
||||
class DirectionalLight : public Light
|
||||
{
|
||||
public:
|
||||
DirectionalLight (const Vec3fa& D, const Vec3fa& E)
|
||||
: Light(LIGHT_DIRECTIONAL), D(D), E(E) {}
|
||||
|
||||
DirectionalLight transform(const AffineSpace3fa& space) const {
|
||||
return DirectionalLight(xfmVector(space,D),E);
|
||||
}
|
||||
|
||||
static DirectionalLight lerp(const DirectionalLight& light0, const DirectionalLight& light1, const float f)
|
||||
{
|
||||
return DirectionalLight(embree::lerp(light0.D,light1.D,f),
|
||||
embree::lerp(light0.E,light1.E,f));
|
||||
}
|
||||
|
||||
public:
|
||||
Vec3fa D; //!< Light direction
|
||||
Vec3fa E; //!< Irradiance (W/m^2)
|
||||
};
|
||||
|
||||
class SpotLight : public Light
|
||||
{
|
||||
public:
|
||||
SpotLight (const Vec3fa& P, const Vec3fa& D, const Vec3fa& I, float angleMin, float angleMax)
|
||||
: Light(LIGHT_SPOT), P(P), D(D), I(I), angleMin(angleMin), angleMax(angleMax) {}
|
||||
|
||||
SpotLight transform(const AffineSpace3fa& space) const {
|
||||
return SpotLight(xfmPoint(space,P),xfmVector(space,D),I,angleMin,angleMax);
|
||||
}
|
||||
|
||||
static SpotLight lerp(const SpotLight& light0, const SpotLight& light1, const float f)
|
||||
{
|
||||
return SpotLight(embree::lerp(light0.P,light1.P,f),
|
||||
embree::lerp(light0.D,light1.D,f),
|
||||
embree::lerp(light0.I,light1.I,f),
|
||||
embree::lerp(light0.angleMin,light1.angleMin,f),
|
||||
embree::lerp(light0.angleMax,light1.angleMax,f));
|
||||
}
|
||||
|
||||
public:
|
||||
Vec3fa P; //!< Position of the spot light
|
||||
Vec3fa D; //!< Light direction of the spot light
|
||||
Vec3fa I; //!< Radiant intensity (W/sr)
|
||||
float angleMin, angleMax; //!< Linear falloff region
|
||||
};
|
||||
|
||||
class DistantLight : public Light
|
||||
{
|
||||
public:
|
||||
DistantLight (const Vec3fa& D, const Vec3fa& L, const float halfAngle)
|
||||
: Light(LIGHT_DISTANT), D(D), L(L), halfAngle(halfAngle), radHalfAngle(deg2rad(halfAngle)), cosHalfAngle(cos(deg2rad(halfAngle))) {}
|
||||
|
||||
DistantLight transform(const AffineSpace3fa& space) const {
|
||||
return DistantLight(xfmVector(space,D),L,halfAngle);
|
||||
}
|
||||
|
||||
static DistantLight lerp(const DistantLight& light0, const DistantLight& light1, const float f)
|
||||
{
|
||||
return DistantLight(embree::lerp(light0.D,light1.D,f),
|
||||
embree::lerp(light0.L,light1.L,f),
|
||||
embree::lerp(light0.halfAngle,light1.halfAngle,f));
|
||||
}
|
||||
|
||||
public:
|
||||
Vec3fa D; //!< Light direction
|
||||
Vec3fa L; //!< Radiance (W/(m^2*sr))
|
||||
float halfAngle; //!< Half illumination angle
|
||||
float radHalfAngle; //!< Half illumination angle in radians
|
||||
float cosHalfAngle; //!< Cosine of half illumination angle
|
||||
};
|
||||
|
||||
class TriangleLight : public Light
|
||||
{
|
||||
public:
|
||||
TriangleLight (const Vec3fa& v0, const Vec3fa& v1, const Vec3fa& v2, const Vec3fa& L)
|
||||
: Light(LIGHT_TRIANGLE), v0(v0), v1(v1), v2(v2), L(L) {}
|
||||
|
||||
TriangleLight transform(const AffineSpace3fa& space) const {
|
||||
return TriangleLight(xfmPoint(space,v0),xfmPoint(space,v1),xfmPoint(space,v2),L);
|
||||
}
|
||||
|
||||
static TriangleLight lerp(const TriangleLight& light0, const TriangleLight& light1, const float f)
|
||||
{
|
||||
return TriangleLight(embree::lerp(light0.v0,light1.v0,f),
|
||||
embree::lerp(light0.v1,light1.v1,f),
|
||||
embree::lerp(light0.v2,light1.v2,f),
|
||||
embree::lerp(light0.L,light1.L,f));
|
||||
}
|
||||
|
||||
public:
|
||||
Vec3fa v0;
|
||||
Vec3fa v1;
|
||||
Vec3fa v2;
|
||||
Vec3fa L;
|
||||
};
|
||||
|
||||
class QuadLight : public Light
|
||||
{
|
||||
public:
|
||||
QuadLight (const Vec3fa& v0, const Vec3fa& v1, const Vec3fa& v2, const Vec3fa& v3, const Vec3fa& L)
|
||||
: Light(LIGHT_QUAD), v0(v0), v1(v1), v2(v2), v3(v3), L(L) {}
|
||||
|
||||
QuadLight transform(const AffineSpace3fa& space) const {
|
||||
return QuadLight(xfmPoint(space,v0),xfmPoint(space,v1),xfmPoint(space,v2),xfmPoint(space,v3),L);
|
||||
}
|
||||
|
||||
static QuadLight lerp(const QuadLight& light0, const QuadLight& light1, const float f)
|
||||
{
|
||||
return QuadLight(embree::lerp(light0.v0,light1.v0,f),
|
||||
embree::lerp(light0.v1,light1.v1,f),
|
||||
embree::lerp(light0.v2,light1.v2,f),
|
||||
embree::lerp(light0.v3,light1.v3,f),
|
||||
embree::lerp(light0.L,light1.L,f));
|
||||
}
|
||||
|
||||
public:
|
||||
Vec3fa v0;
|
||||
Vec3fa v1;
|
||||
Vec3fa v2;
|
||||
Vec3fa v3;
|
||||
Vec3fa L;
|
||||
};
|
||||
}
|
||||
}
|
||||
260
Framework/external/embree/tutorials/common/scenegraph/materials.h
vendored
Normal file
260
Framework/external/embree/tutorials/common/scenegraph/materials.h
vendored
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#if defined (CPPTUTORIAL) && !defined(_MATERIALS_H_CPPTUTORIAL) || !defined(_MATERIALS_H_)
|
||||
|
||||
#if defined (CPPTUTORIAL)
|
||||
#define _MATERIALS_H_CPPTUTORIAL
|
||||
#else
|
||||
#define _MATERIALS_H_
|
||||
#endif
|
||||
|
||||
//#pragma once
|
||||
|
||||
#if !defined(ISPC)
|
||||
#include "texture.h"
|
||||
#include "scenegraph.h"
|
||||
#endif
|
||||
|
||||
#if !defined(ISPC)
|
||||
namespace embree
|
||||
{
|
||||
#endif
|
||||
|
||||
#if defined(ISPC) || defined(CPPTUTORIAL)
|
||||
#define MATERIAL_BASE_CLASS
|
||||
#define PREFIX(x) ISPC##x
|
||||
#else
|
||||
#define MATERIAL_BASE_CLASS : public SceneGraph::MaterialNode
|
||||
#define PREFIX(x) x
|
||||
#endif
|
||||
|
||||
#if !defined(CPPTUTORIAL)
|
||||
enum MaterialType
|
||||
{
|
||||
MATERIAL_OBJ,
|
||||
MATERIAL_THIN_DIELECTRIC,
|
||||
MATERIAL_METAL,
|
||||
MATERIAL_VELVET,
|
||||
MATERIAL_DIELECTRIC,
|
||||
MATERIAL_METALLIC_PAINT,
|
||||
MATERIAL_MATTE,
|
||||
MATERIAL_MIRROR,
|
||||
MATERIAL_REFLECTIVE_METAL,
|
||||
MATERIAL_HAIR
|
||||
};
|
||||
#endif
|
||||
|
||||
struct PREFIX(Material)
|
||||
{
|
||||
#if !defined(ISPC) && !defined(CPPTUTORIAL)
|
||||
Material (MaterialType type)
|
||||
: type(type) {}
|
||||
#endif
|
||||
#if !defined(ISPC)
|
||||
__aligned(16)
|
||||
#endif
|
||||
int type;
|
||||
int align[3];
|
||||
};
|
||||
|
||||
struct PREFIX(MatteMaterial) MATERIAL_BASE_CLASS
|
||||
{
|
||||
#if !defined(ISPC) && !defined(CPPTUTORIAL)
|
||||
MatteMaterial (const Vec3fa& reflectance)
|
||||
: base(MATERIAL_MATTE), reflectance(reflectance) {}
|
||||
virtual Material* material() { return &base; }
|
||||
#endif
|
||||
|
||||
PREFIX(Material) base;
|
||||
Vec3fa reflectance;
|
||||
};
|
||||
|
||||
struct PREFIX(MirrorMaterial) MATERIAL_BASE_CLASS
|
||||
{
|
||||
#if !defined(ISPC) && !defined(CPPTUTORIAL)
|
||||
MirrorMaterial (const Vec3fa& reflectance)
|
||||
: base(MATERIAL_MIRROR), reflectance(reflectance) {}
|
||||
virtual Material* material() { return &base; }
|
||||
#endif
|
||||
|
||||
PREFIX(Material) base;
|
||||
Vec3fa reflectance;
|
||||
};
|
||||
|
||||
struct PREFIX(ThinDielectricMaterial) MATERIAL_BASE_CLASS
|
||||
{
|
||||
#if !defined(ISPC) && !defined(CPPTUTORIAL)
|
||||
ThinDielectricMaterial (const Vec3fa& transmission, const float eta, const float thickness)
|
||||
: base(MATERIAL_THIN_DIELECTRIC), transmission(transmission), transmissionFactor(log(transmission)*thickness), eta(eta), thickness(thickness) {}
|
||||
virtual Material* material() { return &base; }
|
||||
#endif
|
||||
|
||||
PREFIX(Material) base;
|
||||
Vec3fa transmission;
|
||||
Vec3fa transmissionFactor;
|
||||
float eta;
|
||||
float thickness;
|
||||
};
|
||||
|
||||
struct PREFIX(OBJMaterial) MATERIAL_BASE_CLASS
|
||||
{
|
||||
#if !defined(ISPC) && !defined(CPPTUTORIAL)
|
||||
OBJMaterial (const std::string name = "")
|
||||
: SceneGraph::MaterialNode(name), base(MATERIAL_OBJ), illum(0), d(1.f), Ns(1.f), Ni(1.f), Ka(0.f), Kd(1.f), Ks(0.f), Kt(1.0f),
|
||||
map_d(nullptr), map_Ka(nullptr), map_Kd(nullptr), map_Ks(nullptr), map_Kt(nullptr), map_Ns(nullptr), map_Displ(nullptr) {}
|
||||
|
||||
OBJMaterial (float d, const Vec3fa& Kd, const Vec3fa& Ks, const float Ns, const std::string name = "")
|
||||
: base(MATERIAL_OBJ), illum(0), d(d), Ns(Ns), Ni(1.f), Ka(0.f), Kd(Kd), Ks(Ks), Kt(1.0f),
|
||||
map_d(nullptr), map_Ka(nullptr), map_Kd(nullptr), map_Ks(nullptr), map_Kt(nullptr), map_Ns(nullptr), map_Displ(nullptr) {}
|
||||
|
||||
OBJMaterial (float d, const std::shared_ptr<Texture> map_d,
|
||||
const Vec3fa& Ka, const std::shared_ptr<Texture> map_Ka,
|
||||
const Vec3fa& Kd, const std::shared_ptr<Texture> map_Kd,
|
||||
const Vec3fa& Ks, const std::shared_ptr<Texture> map_Ks,
|
||||
const Vec3fa& Kt, const std::shared_ptr<Texture> map_Kt,
|
||||
const float Ns, const std::shared_ptr<Texture> map_Ns,
|
||||
const std::shared_ptr<Texture> map_Displ)
|
||||
: base(MATERIAL_OBJ), illum(0), d(d), Ns(Ns), Ni(1.f), Ka(Ka), Kd(Kd), Ks(Ks), Kt(Kt),
|
||||
map_d(nullptr), map_Ka(nullptr), map_Kd(nullptr), map_Ks(nullptr), map_Kt(nullptr), map_Ns(nullptr), map_Displ(nullptr),
|
||||
_map_d(map_d), _map_Ka(map_Ka), _map_Kd(map_Kd), _map_Ks(map_Ks), _map_Kt(map_Kt), _map_Ns(map_Ns), _map_Displ(map_Displ) {}
|
||||
|
||||
virtual Material* material()
|
||||
{
|
||||
map_d = _map_d.get();
|
||||
map_Ka = _map_Ka.get();
|
||||
map_Kd = _map_Kd.get();
|
||||
map_Ks = _map_Ks.get();
|
||||
map_Kt = _map_Kt.get();
|
||||
map_Ns = _map_Ns.get();
|
||||
map_Displ = _map_Displ.get();
|
||||
return &base;
|
||||
}
|
||||
|
||||
~OBJMaterial() { // FIXME: destructor never called
|
||||
}
|
||||
#endif
|
||||
|
||||
PREFIX(Material) base;
|
||||
int illum; /*< illumination model */
|
||||
float d; /*< dissolve factor, 1=opaque, 0=transparent */
|
||||
float Ns; /*< specular exponent */
|
||||
float Ni; /*< optical density for the surface (index of refraction) */
|
||||
|
||||
Vec3fa Ka; /*< ambient reflectivity */
|
||||
Vec3fa Kd; /*< diffuse reflectivity */
|
||||
Vec3fa Ks; /*< specular reflectivity */
|
||||
Vec3fa Kt; /*< transmission filter */
|
||||
|
||||
const Texture* map_d; /*< d texture */
|
||||
const Texture* map_Ka; /*< Ka texture */
|
||||
const Texture* map_Kd; /*< Kd texture */
|
||||
const Texture* map_Ks; /*< Ks texture */
|
||||
const Texture* map_Kt; /*< Kt texture */
|
||||
const Texture* map_Ns; /*< Ns texture */
|
||||
const Texture* map_Displ; /*< Displ texture */
|
||||
|
||||
#if !defined(ISPC) && !defined(CPPTUTORIAL)
|
||||
std::shared_ptr<Texture> _map_d; /*< d texture */
|
||||
std::shared_ptr<Texture> _map_Ka; /*< Ka texture */
|
||||
std::shared_ptr<Texture> _map_Kd; /*< Kd texture */
|
||||
std::shared_ptr<Texture> _map_Ks; /*< Ks texture */
|
||||
std::shared_ptr<Texture> _map_Kt; /*< Kt texture */
|
||||
std::shared_ptr<Texture> _map_Ns; /*< Ns texture */
|
||||
std::shared_ptr<Texture> _map_Displ; /*< Displ texture */
|
||||
#endif
|
||||
};
|
||||
|
||||
struct PREFIX(MetalMaterial) MATERIAL_BASE_CLASS
|
||||
{
|
||||
#if !defined(ISPC) && !defined(CPPTUTORIAL)
|
||||
MetalMaterial (const Vec3fa& reflectance, const Vec3fa& eta, const Vec3fa& k)
|
||||
: base(MATERIAL_REFLECTIVE_METAL), reflectance(reflectance), eta(eta), k(k), roughness(0.0f) {}
|
||||
|
||||
MetalMaterial (const Vec3fa& reflectance, const Vec3fa& eta, const Vec3fa& k, const float roughness)
|
||||
: base(MATERIAL_METAL), reflectance(reflectance), eta(eta), k(k), roughness(roughness) {}
|
||||
|
||||
virtual Material* material() { return &base; }
|
||||
#endif
|
||||
|
||||
PREFIX(Material) base;
|
||||
Vec3fa reflectance;
|
||||
Vec3fa eta;
|
||||
Vec3fa k;
|
||||
float roughness;
|
||||
};
|
||||
|
||||
typedef PREFIX(MetalMaterial) PREFIX(ReflectiveMetalMaterial);
|
||||
|
||||
struct PREFIX(VelvetMaterial) MATERIAL_BASE_CLASS
|
||||
{
|
||||
#if !defined(ISPC) && !defined(CPPTUTORIAL)
|
||||
VelvetMaterial (const Vec3fa& reflectance, const float backScattering, const Vec3fa& horizonScatteringColor, const float horizonScatteringFallOff)
|
||||
: base(MATERIAL_VELVET), reflectance(reflectance), horizonScatteringColor(horizonScatteringColor), backScattering(backScattering), horizonScatteringFallOff(horizonScatteringFallOff) {}
|
||||
|
||||
virtual Material* material() { return &base; }
|
||||
#endif
|
||||
|
||||
PREFIX(Material) base;
|
||||
Vec3fa reflectance;
|
||||
Vec3fa horizonScatteringColor;
|
||||
float backScattering;
|
||||
float horizonScatteringFallOff;
|
||||
};
|
||||
|
||||
struct PREFIX(DielectricMaterial) MATERIAL_BASE_CLASS
|
||||
{
|
||||
#if !defined(ISPC) && !defined(CPPTUTORIAL)
|
||||
DielectricMaterial (const Vec3fa& transmissionOutside, const Vec3fa& transmissionInside, const float etaOutside, const float etaInside)
|
||||
: base(MATERIAL_DIELECTRIC), transmissionOutside(transmissionOutside), transmissionInside(transmissionInside), etaOutside(etaOutside), etaInside(etaInside) {}
|
||||
|
||||
virtual Material* material() { return &base; }
|
||||
#endif
|
||||
|
||||
PREFIX(Material) base;
|
||||
Vec3fa transmissionOutside;
|
||||
Vec3fa transmissionInside;
|
||||
float etaOutside;
|
||||
float etaInside;
|
||||
};
|
||||
|
||||
struct PREFIX(MetallicPaintMaterial) MATERIAL_BASE_CLASS
|
||||
{
|
||||
#if !defined(ISPC) && !defined(CPPTUTORIAL)
|
||||
MetallicPaintMaterial (const Vec3fa& shadeColor, const Vec3fa& glitterColor, float glitterSpread, float eta)
|
||||
: base(MATERIAL_METALLIC_PAINT), shadeColor(shadeColor), glitterColor(glitterColor), glitterSpread(glitterSpread), eta(eta) {}
|
||||
|
||||
virtual Material* material() { return &base; }
|
||||
#endif
|
||||
|
||||
PREFIX(Material) base;
|
||||
Vec3fa shadeColor;
|
||||
Vec3fa glitterColor;
|
||||
float glitterSpread;
|
||||
float eta;
|
||||
};
|
||||
|
||||
struct PREFIX(HairMaterial) MATERIAL_BASE_CLASS
|
||||
{
|
||||
#if !defined(ISPC) && !defined(CPPTUTORIAL)
|
||||
HairMaterial (const Vec3fa& Kr, const Vec3fa& Kt, float nx, float ny)
|
||||
: base(MATERIAL_HAIR), Kr(Kr), Kt(Kt), nx(nx), ny(ny) {}
|
||||
|
||||
virtual Material* material() { return &base; }
|
||||
#endif
|
||||
|
||||
PREFIX(Material) base;
|
||||
Vec3fa Kr;
|
||||
Vec3fa Kt;
|
||||
float nx;
|
||||
float ny;
|
||||
};
|
||||
|
||||
#undef MATERIAL_BASE_CLASS
|
||||
#undef PREFIX
|
||||
|
||||
#if !defined(ISPC)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
652
Framework/external/embree/tutorials/common/scenegraph/obj_loader.cpp
vendored
Normal file
652
Framework/external/embree/tutorials/common/scenegraph/obj_loader.cpp
vendored
Normal file
|
|
@ -0,0 +1,652 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "obj_loader.h"
|
||||
#include "texture.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
/*! Three-index vertex, indexing start at 0, -1 means invalid vertex. */
|
||||
struct Vertex {
|
||||
unsigned int v, vt, vn;
|
||||
Vertex() {};
|
||||
Vertex(unsigned int v) : v(v), vt(v), vn(v) {};
|
||||
Vertex(unsigned int v, unsigned int vt, unsigned int vn) : v(v), vt(vt), vn(vn) {};
|
||||
};
|
||||
|
||||
struct Crease {
|
||||
float w;
|
||||
unsigned int a, b;
|
||||
Crease() : w(0), a(-1), b(-1) {};
|
||||
Crease(float w, unsigned int a, unsigned int b) : w(w), a(a), b(b) {};
|
||||
};
|
||||
|
||||
static inline bool operator < ( const Vertex& a, const Vertex& b ) {
|
||||
if (a.v != b.v) return a.v < b.v;
|
||||
if (a.vn != b.vn) return a.vn < b.vn;
|
||||
if (a.vt != b.vt) return a.vt < b.vt;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*! Fill space at the end of the token with 0s. */
|
||||
static inline const char* trimEnd(const char* token)
|
||||
{
|
||||
if (*token == 0) return token;
|
||||
char* pe = (char*) token;
|
||||
while (*pe) pe++;
|
||||
pe--;
|
||||
while ((*pe == ' ' || *pe == '\t' || *pe == '\r') && pe >= token) *pe-- = 0;
|
||||
return token;
|
||||
}
|
||||
|
||||
/*! Determine if character is a separator. */
|
||||
static inline bool isSep(const char c) {
|
||||
return (c == ' ') || (c == '\t');
|
||||
}
|
||||
|
||||
/*! Parse separator. */
|
||||
static inline const char* parseSep(const char*& token) {
|
||||
size_t sep = strspn(token, " \t");
|
||||
if (!sep) THROW_RUNTIME_ERROR("separator expected");
|
||||
return token+=sep;
|
||||
}
|
||||
|
||||
/*! Parse optional separator. */
|
||||
static inline const char* parseSepOpt(const char*& token) {
|
||||
return token+=strspn(token, " \t");
|
||||
}
|
||||
|
||||
/*! Read float from a string. */
|
||||
static inline float getFloat(const char*& token) {
|
||||
token += strspn(token, " \t");
|
||||
float n = (float)atof(token);
|
||||
token += strcspn(token, " \t\r");
|
||||
return n;
|
||||
}
|
||||
|
||||
/*! Read int from a string. */
|
||||
static inline int getInt(const char*& token) {
|
||||
token += strspn(token, " \t");
|
||||
int n = atoi(token);
|
||||
token += strcspn(token, " \t\r");
|
||||
return n;
|
||||
}
|
||||
|
||||
/*! Read Vec2f from a string. */
|
||||
static inline Vec2f getVec2f(const char*& token) {
|
||||
float x = getFloat(token);
|
||||
float y = getFloat(token);
|
||||
return Vec2f(x,y);
|
||||
}
|
||||
|
||||
/*! Read Vec3f from a string. */
|
||||
static inline Vec3f getVec3f(const char*& token) {
|
||||
float x = getFloat(token);
|
||||
token += strspn(token, " \t");
|
||||
if (*token == 0) return Vec3f(x);
|
||||
float y = getFloat(token);
|
||||
float z = getFloat(token);
|
||||
return Vec3f(x,y,z);
|
||||
}
|
||||
|
||||
/*! Read Vec3fa from a string. */
|
||||
static inline Vec3fa getVec3fa(const char*& token) {
|
||||
float x = getFloat(token);
|
||||
token += strspn(token, " \t");
|
||||
if (*token == 0) return Vec3f(x);
|
||||
float y = getFloat(token);
|
||||
float z = getFloat(token);
|
||||
return Vec3fa(x,y,z);
|
||||
}
|
||||
|
||||
class OBJLoader
|
||||
{
|
||||
public:
|
||||
|
||||
/*! Constructor. */
|
||||
OBJLoader(const FileName& fileName, const bool subdivMode, const bool combineIntoSingleObject);
|
||||
|
||||
/*! output model */
|
||||
Ref<SceneGraph::GroupNode> group;
|
||||
|
||||
private:
|
||||
|
||||
/*! file to load */
|
||||
FileName path;
|
||||
|
||||
/*! load only quads and ignore triangles */
|
||||
bool subdivMode;
|
||||
|
||||
/*! Geometry buffer. */
|
||||
avector<Vec3fa> v;
|
||||
avector<Vec3fa> vn;
|
||||
std::vector<Vec2f> vt;
|
||||
std::vector<Crease> ec;
|
||||
|
||||
std::vector<std::vector<Vertex> > curGroup;
|
||||
std::vector<avector<Vec3ff> > curGroupHair;
|
||||
|
||||
/*! Material handling. */
|
||||
std::string curMaterialName;
|
||||
Ref<SceneGraph::MaterialNode> curMaterial;
|
||||
std::map<std::string, Ref<SceneGraph::MaterialNode> > material;
|
||||
std::map<std::string, std::shared_ptr<Texture>> textureMap;
|
||||
|
||||
private:
|
||||
void loadMTL(const FileName& fileName);
|
||||
unsigned int fix_v (int index);
|
||||
unsigned int fix_vt(int index);
|
||||
unsigned int fix_vn(int index);
|
||||
void flushFaceGroup();
|
||||
void flushTriGroup();
|
||||
void flushHairGroup();
|
||||
Vertex getUInt3(const char*& token);
|
||||
uint32_t getVertex(std::map<Vertex,uint32_t>& vertexMap, Ref<SceneGraph::TriangleMeshNode> mesh, const Vertex& i);
|
||||
std::shared_ptr<Texture> loadTexture(const FileName& fname);
|
||||
};
|
||||
|
||||
OBJLoader::OBJLoader(const FileName &fileName, const bool subdivMode, const bool combineIntoSingleObject)
|
||||
: group(new SceneGraph::GroupNode), path(fileName.path()), subdivMode(subdivMode)
|
||||
{
|
||||
/* open file */
|
||||
std::ifstream cin;
|
||||
cin.open(fileName.c_str());
|
||||
if (!cin.is_open()) {
|
||||
THROW_RUNTIME_ERROR("cannot open " + fileName.str());
|
||||
return;
|
||||
}
|
||||
|
||||
/* generate default material */
|
||||
Ref<SceneGraph::MaterialNode> defaultMaterial = new OBJMaterial("default");
|
||||
curMaterialName = "default";
|
||||
curMaterial = defaultMaterial;
|
||||
|
||||
while (cin.peek() != -1)
|
||||
{
|
||||
/* load next multiline */
|
||||
std::string line; std::getline(cin,line);
|
||||
while (!line.empty() && line[line.size()-1] == '\\') {
|
||||
line[line.size()-1] = ' ';
|
||||
std::string next_line; std::getline(cin,next_line);
|
||||
if (next_line.empty()) break;
|
||||
line += next_line;
|
||||
}
|
||||
const char* token = trimEnd(line.c_str() + strspn(line.c_str(), " \t"));
|
||||
if (token[0] == 0) continue;
|
||||
|
||||
/*! parse position */
|
||||
if (token[0] == 'v' && isSep(token[1])) {
|
||||
v.push_back(getVec3f(token += 2)); continue;
|
||||
}
|
||||
|
||||
/* parse normal */
|
||||
if (token[0] == 'v' && token[1] == 'n' && isSep(token[2])) {
|
||||
vn.push_back(getVec3f(token += 3));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* parse texcoord */
|
||||
if (token[0] == 'v' && token[1] == 't' && isSep(token[2])) { vt.push_back(getVec2f(token += 3)); continue; }
|
||||
|
||||
/*! parse face */
|
||||
if (token[0] == 'f' && isSep(token[1]))
|
||||
{
|
||||
parseSep(token += 1);
|
||||
|
||||
std::vector<Vertex> face;
|
||||
while (token[0]) {
|
||||
Vertex vtx = getUInt3(token);
|
||||
face.push_back(vtx);
|
||||
parseSepOpt(token);
|
||||
}
|
||||
curGroup.push_back(face);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*! parse corona hair */
|
||||
if (!strncmp(token,"hair",4) && isSep(token[4]))
|
||||
{
|
||||
parseSep(token += 4);
|
||||
bool plane = !strncmp(token,"plane",5) && isSep(token[5]);
|
||||
if (plane) {
|
||||
parseSep(token += 5);
|
||||
}
|
||||
else if (!strncmp(token,"cylinder",8) && isSep(token[8])) {
|
||||
parseSep(token += 8);
|
||||
}
|
||||
else continue;
|
||||
|
||||
unsigned int N = getInt(token);
|
||||
avector<Vec3ff> hair;
|
||||
for (unsigned int i=0; i<3*N+1; i++) {
|
||||
hair.push_back((Vec3ff)getVec3fa(token));
|
||||
}
|
||||
|
||||
for (unsigned int i=0; i<N+1; i++)
|
||||
{
|
||||
float r = getFloat(token);
|
||||
MAYBE_UNUSED float t = (float)getInt(token);
|
||||
if (i != 0) hair[3*i-1].w = r;
|
||||
hair[3*i+0].w = r;
|
||||
if (i != N) hair[3*i+1].w = r;
|
||||
}
|
||||
curGroupHair.push_back(hair);
|
||||
}
|
||||
|
||||
/*! parse edge crease */
|
||||
if (token[0] == 'e' && token[1] == 'c' && isSep(token[2]))
|
||||
{
|
||||
parseSep(token += 2);
|
||||
float w = getFloat(token);
|
||||
parseSepOpt(token);
|
||||
unsigned int a = fix_v(getInt(token));
|
||||
parseSepOpt(token);
|
||||
unsigned int b = fix_v(getInt(token));
|
||||
parseSepOpt(token);
|
||||
ec.push_back(Crease(w, a, b));
|
||||
continue;
|
||||
}
|
||||
|
||||
/*! use material */
|
||||
if (!strncmp(token, "usemtl", 6) && isSep(token[6]))
|
||||
{
|
||||
if (!combineIntoSingleObject) flushFaceGroup();
|
||||
std::string name(parseSep(token += 6));
|
||||
if (material.find(name) == material.end()) {
|
||||
curMaterial = defaultMaterial;
|
||||
curMaterialName = "default";
|
||||
}
|
||||
else {
|
||||
curMaterial = material[name];
|
||||
curMaterialName = name;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* load material library */
|
||||
if (!strncmp(token, "mtllib", 6) && isSep(token[6])) {
|
||||
loadMTL(path + std::string(parseSep(token += 6)));
|
||||
continue;
|
||||
}
|
||||
|
||||
// ignore unknown stuff
|
||||
}
|
||||
flushFaceGroup();
|
||||
|
||||
cin.close();
|
||||
}
|
||||
|
||||
struct ExtObjMaterial
|
||||
{
|
||||
public:
|
||||
|
||||
enum Type { NONE, MATTE, GLASS, METAL, METALLIC_PAINT };
|
||||
|
||||
Ref<SceneGraph::MaterialNode> select() const
|
||||
{
|
||||
std::shared_ptr<Texture> nulltex;
|
||||
if (type == NONE) {
|
||||
return new OBJMaterial(d,map_d,Ka,map_Ka,Kd,map_Kd,Ks,map_Ks,Kt,map_Kt,Ns,map_Ns,map_Displ);
|
||||
} else if (type == MATTE) {
|
||||
if (coat_eta != 1.0f) return new MetallicPaintMaterial (Kd,zero,0.0f,eta.x);
|
||||
else return new OBJMaterial(1.0f,nulltex,zero,nulltex,Kd,map_Kd,Ks,nulltex,zero,nulltex,1.0f/(1E-6f+roughness),nulltex,nulltex);
|
||||
} else if (type == GLASS) {
|
||||
return new ThinDielectricMaterial(Vec3fa(1.0f),eta.x,0.1f);
|
||||
} else if (type == METAL) {
|
||||
if (roughness == 0.0f) {
|
||||
if (eta == Vec3fa(1.0f) && k == Vec3fa(0.0f)) return new MirrorMaterial(Kd);
|
||||
else return new MetalMaterial(Kd,eta,k);
|
||||
}
|
||||
else return new MetalMaterial(Kd,eta,k,roughness);
|
||||
} else if (type == METALLIC_PAINT) {
|
||||
return new MetallicPaintMaterial (Kd,Ks,0.0f,coat_eta);
|
||||
}
|
||||
return new MatteMaterial(Vec3fa(0.5f));
|
||||
}
|
||||
|
||||
public:
|
||||
Type type = NONE;
|
||||
|
||||
int illum = 0; /*< illumination model */
|
||||
float d = 1.0f; /*< dissolve factor, 1=opaque, 0=transparent */
|
||||
float Ns = 1.0f; /*< specular exponent */
|
||||
float Ni = 1.0f; /*< optical density for the surface (index of refraction) */
|
||||
|
||||
Vec3fa Ka = zero; /*< ambient reflectivity */
|
||||
Vec3fa Kd = one; /*< diffuse reflectivity */
|
||||
Vec3fa Ks = zero; /*< specular reflectivity */
|
||||
Vec3fa Kt = zero; /*< transmission filter */
|
||||
|
||||
std::shared_ptr<Texture> map_d; /*< d texture */
|
||||
std::shared_ptr<Texture> map_Ka; /*< Ka texture */
|
||||
std::shared_ptr<Texture> map_Kd; /*< Kd texture */
|
||||
std::shared_ptr<Texture> map_Ks; /*< Ks texture */
|
||||
std::shared_ptr<Texture> map_Kt; /*< Kt texture */
|
||||
std::shared_ptr<Texture> map_Ns; /*< Ns texture */
|
||||
std::shared_ptr<Texture> map_Displ; /*< Displ texture */
|
||||
|
||||
float roughness = zero;
|
||||
std::shared_ptr<Texture> roughnessMap;
|
||||
float coat_eta = one;
|
||||
float coat_roughness = zero;
|
||||
std::shared_ptr<Texture> coat_roughnessMap;
|
||||
float bump = zero;
|
||||
Vec3f eta = Vec3f(1.4f);
|
||||
Vec3f k = Vec3f(3.0f);
|
||||
};
|
||||
|
||||
std::shared_ptr<Texture> OBJLoader::loadTexture(const FileName& fname)
|
||||
{
|
||||
if (textureMap.find(fname.str()) != textureMap.end())
|
||||
return textureMap[fname.str()];
|
||||
|
||||
return std::shared_ptr<Texture>(Texture::load(path+fname));
|
||||
}
|
||||
|
||||
/* load material file */
|
||||
void OBJLoader::loadMTL(const FileName &fileName)
|
||||
{
|
||||
std::ifstream cin;
|
||||
cin.open(fileName.c_str());
|
||||
if (!cin.is_open()) {
|
||||
std::cerr << "cannot open " << fileName.str() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string name;
|
||||
ExtObjMaterial cur;
|
||||
|
||||
while (cin.peek() != -1)
|
||||
{
|
||||
/* load next multiline */
|
||||
std::string line; std::getline(cin,line);
|
||||
while (!line.empty() && line[line.size()-1] == '\\') {
|
||||
line[line.size()-1] = ' ';
|
||||
std::string next_line; std::getline(cin,next_line);
|
||||
if (next_line.empty()) break;
|
||||
line += next_line;
|
||||
}
|
||||
const char* token = trimEnd(line.c_str() + strspn(line.c_str(), " \t"));
|
||||
|
||||
if (token[0] == 0 ) continue; // ignore empty lines
|
||||
if (token[0] == '#') continue; // ignore comments
|
||||
|
||||
if (!strncmp(token, "newmtl", 6))
|
||||
{
|
||||
if (name != "") {
|
||||
material[name] = cur.select();
|
||||
material[name]->name = name;
|
||||
}
|
||||
|
||||
parseSep(token+=6);
|
||||
name = token;
|
||||
cur = ExtObjMaterial();
|
||||
continue;
|
||||
}
|
||||
if (name == "") THROW_RUNTIME_ERROR("invalid material file: newmtl expected first");
|
||||
|
||||
try
|
||||
{
|
||||
if (!strncmp(token, "illum", 5)) { parseSep(token += 5); continue; }
|
||||
|
||||
if (!strncmp(token, "d", 1)) { parseSep(token += 1); cur.d = getFloat(token); continue; }
|
||||
if (!strncmp(token, "Ns", 2)) { parseSep(token += 2); cur.Ns = getFloat(token); continue; }
|
||||
if (!strncmp(token, "Ni", 2)) { parseSep(token += 2); cur.Ni = getFloat(token); continue; }
|
||||
|
||||
if (!strncmp(token, "map_d", 5) || !strncmp(token, "d_map", 5)) {
|
||||
parseSep(token += 5);
|
||||
cur.map_d = loadTexture(FileName(token));
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(token, "map_Ka", 6) || !strncmp(token, "Ka_map", 6)) {
|
||||
parseSep(token += 6);
|
||||
cur.map_Ka = loadTexture(FileName(token));
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(token, "map_Kd", 6) || !strncmp(token, "Kd_map", 6)) {
|
||||
parseSep(token += 6);
|
||||
cur.map_Kd = loadTexture(FileName(token));
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(token, "map_Ks", 6) || !strncmp(token, "Ks_map", 6)) {
|
||||
parseSep(token += 6);
|
||||
cur.map_Ks = loadTexture(FileName(token));
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(token, "map_Kt", 6) || !strncmp(token, "Kt_map", 6)) {
|
||||
parseSep(token += 6);
|
||||
cur.map_Kt = loadTexture(FileName(token));
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(token, "map_Tf", 6) || !strncmp(token, "Tf_map", 6)) {
|
||||
parseSep(token += 6);
|
||||
cur.map_Kt = loadTexture(FileName(token));
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(token, "map_Ns", 6) || !strncmp(token, "Ns_map", 6)) {
|
||||
parseSep(token += 6);
|
||||
cur.map_Ns = loadTexture(FileName(token));
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(token, "map_Displ", 9) || !strncmp(token, "Displ_map", 9)) {
|
||||
parseSep(token += 9);
|
||||
cur.map_Displ = loadTexture(FileName(token));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strncmp(token, "Ka", 2)) { parseSep(token += 2); cur.Ka = getVec3f(token); continue; }
|
||||
if (!strncmp(token, "Kd", 2)) { parseSep(token += 2); cur.Kd = getVec3f(token); continue; }
|
||||
if (!strncmp(token, "Ks", 2)) { parseSep(token += 2); cur.Ks = getVec3f(token); continue; }
|
||||
if (!strncmp(token, "Kt", 2)) { parseSep(token += 2); cur.Kt = getVec3f(token); continue; }
|
||||
if (!strncmp(token, "Tf", 2)) { parseSep(token += 2); cur.Kt = getVec3f(token); continue; }
|
||||
|
||||
/* extended OBJ */
|
||||
if (!strncmp(token, "type", 4)) {
|
||||
parseSep(token += 4); std::string type = token;
|
||||
if (type == "matte") cur.type = ExtObjMaterial::MATTE;
|
||||
else if (type == "glass") cur.type = ExtObjMaterial::GLASS;
|
||||
else if (type == "metal") cur.type = ExtObjMaterial::METAL;
|
||||
else if (type == "metallicPaint") cur.type = ExtObjMaterial::METALLIC_PAINT;
|
||||
else if (type == "principled") cur.type = ExtObjMaterial::NONE;
|
||||
else if (type == "luminous") cur.type = ExtObjMaterial::NONE;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* OSPRay principled material extensions */
|
||||
if (!strncmp(token, "baseColor", 9)) { parseSep(token += 9); cur.Kd = getVec3f(token); continue; }
|
||||
if (!strncmp(token, "ior", 3)) { parseSep(token += 3); cur.Ni = getFloat(token); continue; }
|
||||
if (!strncmp(token, "map_baseColor", 13)) { parseSep(token += 13); cur.map_Kd = loadTexture(FileName(token)); continue; }
|
||||
if (!strncmp(token, "map_specular", 12)) { parseSep(token += 12); cur.map_Ks = loadTexture(FileName(token)); continue; }
|
||||
if (!strncmp(token, "map_normal.scale", 16)) { parseSep(token += 16); continue; }
|
||||
if (!strncmp(token, "map_normal", 10)) { parseSep(token += 10); cur.map_Displ = loadTexture(FileName(token)); continue; }
|
||||
if (!strncmp(token, "transmissionColor",17)) { parseSep(token += 17); cur.Kt = getVec3f(token); continue; }
|
||||
if (!strncmp(token, "transmission", 12)) { parseSep(token += 12); cur.Kt = Vec3f(getFloat(token)); continue; }
|
||||
|
||||
if (!strncmp(token, "roughnessMap", 12)) { parseSep(token += 12); cur.roughnessMap = loadTexture(FileName(token)); continue; }
|
||||
if (!strncmp(token, "roughness", 9)) { parseSep(token += 9); cur.roughness = getFloat(token); cur.Ns = 1.0f/(cur.roughness+1E-6f); continue; }
|
||||
if (!strncmp(token, "colorMap", 8)) { parseSep(token += 8); cur.map_Kd = loadTexture(FileName(token)); continue; }
|
||||
if (!strncmp(token, "color", 5)) { parseSep(token += 5); cur.Kd = getVec3f(token); continue; }
|
||||
if (!strncmp(token, "coat.color", 10)) { parseSep(token += 10); cur.Kd = getVec3f(token); continue; }
|
||||
if (!strncmp(token, "coat.eta", 8)) { parseSep(token += 8); cur.coat_eta = getFloat(token); continue; }
|
||||
if (!strncmp(token, "coat.roughnessMap",17)) { parseSep(token += 17); cur.coat_roughnessMap = loadTexture(FileName(token)); continue; }
|
||||
if (!strncmp(token, "coat.roughness", 14)) { parseSep(token += 14); cur.coat_roughness = getFloat(token); continue; }
|
||||
if (!strncmp(token, "bumpMap", 7)) { parseSep(token += 7); cur.map_Displ = loadTexture(FileName(token)); continue; }
|
||||
if (!strncmp(token, "bump", 4)) { parseSep(token += 4); cur.bump = getFloat(token); continue; }
|
||||
if (!strncmp(token, "eta", 3)) { parseSep(token += 3); cur.eta = getVec3f(token); continue; }
|
||||
if (!strncmp(token, "k", 1)) { parseSep(token += 1); cur.k = getVec3f(token); continue; }
|
||||
}
|
||||
catch (const std::runtime_error& e) {
|
||||
std::cerr << "Error: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (name != "") {
|
||||
material[name] = cur.select();
|
||||
material[name]->name = name;
|
||||
}
|
||||
|
||||
cin.close();
|
||||
}
|
||||
|
||||
/*! handles relative indices and starts indexing from 0 */
|
||||
unsigned int OBJLoader::fix_v (int index) { return (index > 0 ? index - 1 : (index == 0 ? 0 : (int) v .size() + index)); }
|
||||
unsigned int OBJLoader::fix_vt(int index) { return (index > 0 ? index - 1 : (index == 0 ? 0 : (int) vt.size() + index)); }
|
||||
unsigned int OBJLoader::fix_vn(int index) { return (index > 0 ? index - 1 : (index == 0 ? 0 : (int) vn.size() + index)); }
|
||||
|
||||
/*! Parse differently formatted triplets like: n0, n0/n1/n2, n0//n2, n0/n1. */
|
||||
/*! All indices are converted to C-style (from 0). Missing entries are assigned -1. */
|
||||
Vertex OBJLoader::getUInt3(const char*& token)
|
||||
{
|
||||
Vertex v(-1);
|
||||
v.v = fix_v(atoi(token));
|
||||
token += strcspn(token, "/ \t\r");
|
||||
if (token[0] != '/') return(v);
|
||||
token++;
|
||||
|
||||
// it is i//n
|
||||
if (token[0] == '/') {
|
||||
token++;
|
||||
v.vn = fix_vn(atoi(token));
|
||||
token += strcspn(token, " \t\r");
|
||||
return(v);
|
||||
}
|
||||
|
||||
// it is i/t/n or i/t
|
||||
v.vt = fix_vt(atoi(token));
|
||||
token += strcspn(token, "/ \t\r");
|
||||
if (token[0] != '/') return(v);
|
||||
token++;
|
||||
|
||||
// it is i/t/n
|
||||
v.vn = fix_vn(atoi(token));
|
||||
token += strcspn(token, " \t\r");
|
||||
return(v);
|
||||
}
|
||||
|
||||
uint32_t OBJLoader::getVertex(std::map<Vertex,uint32_t>& vertexMap, Ref<SceneGraph::TriangleMeshNode> mesh, const Vertex& i)
|
||||
{
|
||||
const std::map<Vertex, uint32_t>::iterator& entry = vertexMap.find(i);
|
||||
if (entry != vertexMap.end()) return(entry->second);
|
||||
|
||||
if (i.v >= v.size()) std::cout << "WARNING: corrupted OBJ file" << std::endl;
|
||||
else mesh->positions[0].push_back(v[i.v]);
|
||||
|
||||
if (i.vn != -1) {
|
||||
while (mesh->normals[0].size() < mesh->positions[0].size()) mesh->normals[0].push_back(zero); // some vertices might not had a normal
|
||||
|
||||
if (i.vn >= vn.size()) std::cout << "WARNING: corrupted OBJ file" << std::endl;
|
||||
else mesh->normals[0][mesh->positions[0].size()-1] = vn[i.vn];
|
||||
}
|
||||
if (i.vt != -1) {
|
||||
while (mesh->texcoords.size() < mesh->positions[0].size()) mesh->texcoords.push_back(zero); // some vertices might not had a texture coordinate
|
||||
|
||||
if (i.vt >= vt.size()) std::cout << "WARNING: corrupted OBJ file" << std::endl;
|
||||
else mesh->texcoords[mesh->positions[0].size()-1] = vt[i.vt];
|
||||
}
|
||||
return (vertexMap[i] = (unsigned int)(mesh->positions[0].size()) - 1);
|
||||
}
|
||||
|
||||
void OBJLoader::flushFaceGroup()
|
||||
{
|
||||
flushTriGroup();
|
||||
flushHairGroup();
|
||||
}
|
||||
|
||||
/*! end current facegroup and append to mesh */
|
||||
void OBJLoader::flushTriGroup()
|
||||
{
|
||||
if (curGroup.empty()) return;
|
||||
|
||||
if (subdivMode)
|
||||
{
|
||||
Ref<SceneGraph::SubdivMeshNode> mesh = new SceneGraph::SubdivMeshNode(curMaterial,BBox1f(0,1),1);
|
||||
mesh->normals.resize(1);
|
||||
group->add(mesh.cast<SceneGraph::Node>());
|
||||
|
||||
for (size_t i=0; i<v.size(); i++) mesh->positions[0].push_back(v[i]);
|
||||
for (size_t i=0; i<vn.size(); i++) mesh->normals[0].push_back(vn[i]);
|
||||
for (size_t i=0; i<vt.size(); i++) mesh->texcoords.push_back(vt[i]);
|
||||
|
||||
for (size_t i=0; i<ec.size(); ++i) {
|
||||
assert(((size_t)ec[i].a < v.size()) && ((size_t)ec[i].b < v.size()));
|
||||
mesh->edge_creases.push_back(Vec2i(ec[i].a, ec[i].b));
|
||||
mesh->edge_crease_weights.push_back(ec[i].w);
|
||||
}
|
||||
|
||||
for (size_t j=0; j<curGroup.size(); j++)
|
||||
{
|
||||
const std::vector<Vertex>& face = curGroup[j];
|
||||
mesh->verticesPerFace.push_back(int(face.size()));
|
||||
for (size_t i=0; i<face.size(); i++)
|
||||
mesh->position_indices.push_back(face[i].v);
|
||||
}
|
||||
if (mesh->normals[0].size() == 0)
|
||||
mesh->normals.clear();
|
||||
mesh->verify();
|
||||
}
|
||||
else
|
||||
{
|
||||
Ref<SceneGraph::TriangleMeshNode> mesh = new SceneGraph::TriangleMeshNode(curMaterial,BBox1f(0,1),1);
|
||||
mesh->normals.resize(1);
|
||||
group->add(mesh.cast<SceneGraph::Node>());
|
||||
// merge three indices into one
|
||||
std::map<Vertex, uint32_t> vertexMap;
|
||||
for (size_t j=0; j<curGroup.size(); j++)
|
||||
{
|
||||
/* iterate over all faces */
|
||||
const std::vector<Vertex>& face = curGroup[j];
|
||||
|
||||
/* triangulate the face with a triangle fan */
|
||||
Vertex i0 = face[0], i1 = Vertex(-1), i2 = face[1];
|
||||
for (size_t k=2; k < face.size(); k++)
|
||||
{
|
||||
i1 = i2; i2 = face[k];
|
||||
uint32_t v0,v1,v2;
|
||||
v0 = getVertex(vertexMap, mesh, i0);
|
||||
v1 = getVertex(vertexMap, mesh, i1);
|
||||
v2 = getVertex(vertexMap, mesh, i2);
|
||||
assert(v0 < mesh->numVertices());
|
||||
assert(v1 < mesh->numVertices());
|
||||
assert(v2 < mesh->numVertices());
|
||||
mesh->triangles.push_back(SceneGraph::TriangleMeshNode::Triangle(v0,v1,v2));
|
||||
}
|
||||
}
|
||||
/* there may be vertices without normals or texture coordinates, thus we have to make these arrays the same size here */
|
||||
if (mesh->normals[0].size()) while (mesh->normals[0].size() < mesh->numVertices()) mesh->normals[0].push_back(zero);
|
||||
if (mesh->texcoords.size()) while (mesh->texcoords.size() < mesh->numVertices()) mesh->texcoords.push_back(zero);
|
||||
|
||||
if (mesh->normals[0].size() == 0)
|
||||
mesh->normals.clear();
|
||||
mesh->verify();
|
||||
}
|
||||
|
||||
curGroup.clear();
|
||||
ec.clear();
|
||||
}
|
||||
|
||||
void OBJLoader::flushHairGroup()
|
||||
{
|
||||
if (curGroupHair.empty()) return;
|
||||
|
||||
avector<Vec3ff> vertices;
|
||||
std::vector<SceneGraph::HairSetNode::Hair> curves;
|
||||
|
||||
for (size_t i=0; i<curGroupHair.size(); i++) {
|
||||
for (size_t j=0; j<curGroupHair[i].size(); j++) {
|
||||
if (j%3 == 0) curves.push_back(SceneGraph::HairSetNode::Hair((unsigned int)vertices.size(),(unsigned int)i));
|
||||
vertices.push_back(curGroupHair[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
Ref<SceneGraph::HairSetNode> mesh = new SceneGraph::HairSetNode(vertices,curves,curMaterial,RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE);
|
||||
group->add(mesh.cast<SceneGraph::Node>());
|
||||
mesh->verify();
|
||||
curGroupHair.clear();
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> loadOBJ(const FileName& fileName, const bool subdivMode, const bool combineIntoSingleObject) {
|
||||
OBJLoader loader(fileName,subdivMode,combineIntoSingleObject);
|
||||
return loader.group.cast<SceneGraph::Node>();
|
||||
}
|
||||
}
|
||||
|
||||
13
Framework/external/embree/tutorials/common/scenegraph/obj_loader.h
vendored
Normal file
13
Framework/external/embree/tutorials/common/scenegraph/obj_loader.h
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "scenegraph.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
Ref<SceneGraph::Node> loadOBJ(const FileName& fileName,
|
||||
const bool subdivMode = false,
|
||||
const bool combineIntoSingleObject = false);
|
||||
}
|
||||
332
Framework/external/embree/tutorials/common/scenegraph/ply_loader.cpp
vendored
Normal file
332
Framework/external/embree/tutorials/common/scenegraph/ply_loader.cpp
vendored
Normal file
|
|
@ -0,0 +1,332 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "ply_loader.h"
|
||||
#include <list>
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace SceneGraph
|
||||
{
|
||||
/*! PLY type */
|
||||
struct Type {
|
||||
enum Tag { PTY_CHAR, PTY_UCHAR, PTY_SHORT, PTY_USHORT, PTY_INT, PTY_UINT, PTY_FLOAT, PTY_DOUBLE, PTY_LIST, PTY_NONE } ty, index, data;
|
||||
Type() : ty(PTY_NONE), index(PTY_NONE), data(PTY_NONE) {}
|
||||
Type(Tag ty) : ty(ty), index(PTY_NONE), data(PTY_NONE) {}
|
||||
Type(Tag ty, Tag index, Tag data) : ty(ty), index(index), data(data) {}
|
||||
};
|
||||
|
||||
/*! an element stored in the PLY file, such as vertex, face, etc. */
|
||||
struct Element {
|
||||
std::string name;
|
||||
size_t size; /// number of data items of the element
|
||||
std::vector<std::string> properties; /// list of all properties of the element (e.g. x, y, z) (not strictly necessary)
|
||||
std::map<std::string,Type> type; /// mapping of property name to type
|
||||
std::map<std::string,std::vector<float> > data; /// data array properties (all represented as floats)
|
||||
std::map<std::string,std::vector<std::vector<size_t> > > list; /// list properties (integer lists supported only)
|
||||
};
|
||||
|
||||
/*! mesh structure that reflects the PLY file format */
|
||||
struct Mesh {
|
||||
std::vector<std::string> order; /// order of all elements in file (not strictly necessary)
|
||||
std::map<std::string,Element> elements; /// all elements of the file, e.g. vertex, face, ...
|
||||
};
|
||||
|
||||
/* returns the size of a type in bytes */
|
||||
size_t sizeOfType(Type::Tag ty)
|
||||
{
|
||||
switch (ty) {
|
||||
case Type::PTY_CHAR : return 1;
|
||||
case Type::PTY_UCHAR : return 1;
|
||||
case Type::PTY_SHORT : return 2;
|
||||
case Type::PTY_USHORT : return 2;
|
||||
case Type::PTY_INT : return 4;
|
||||
case Type::PTY_UINT : return 4;
|
||||
case Type::PTY_FLOAT : return 4;
|
||||
case Type::PTY_DOUBLE : return 8;
|
||||
default : throw std::runtime_error("invalid type");
|
||||
}
|
||||
}
|
||||
|
||||
/* compute the type of a string */
|
||||
Type::Tag typeTagOfString(const std::string& ty) {
|
||||
if (ty == "char") return Type::PTY_CHAR;
|
||||
if (ty == "int8") return Type::PTY_CHAR;
|
||||
if (ty == "uchar") return Type::PTY_UCHAR;
|
||||
if (ty == "uint8") return Type::PTY_UCHAR;
|
||||
if (ty == "short") return Type::PTY_SHORT;
|
||||
if (ty == "int16") return Type::PTY_SHORT;
|
||||
if (ty == "ushort") return Type::PTY_USHORT;
|
||||
if (ty == "uint16") return Type::PTY_USHORT;
|
||||
if (ty == "int") return Type::PTY_INT;
|
||||
if (ty == "int32") return Type::PTY_INT;
|
||||
if (ty == "uint") return Type::PTY_UINT;
|
||||
if (ty == "uint32") return Type::PTY_UINT;
|
||||
if (ty == "float") return Type::PTY_FLOAT;
|
||||
if (ty == "float32") return Type::PTY_FLOAT;
|
||||
if (ty == "double") return Type::PTY_DOUBLE;
|
||||
throw std::runtime_error("invalid type " + ty);
|
||||
return Type::PTY_NONE;
|
||||
}
|
||||
|
||||
/* compute the type of a string */
|
||||
std::string stringOfTypeTag(Type::Tag ty) {
|
||||
if (ty == Type::PTY_CHAR) return "char";
|
||||
if (ty == Type::PTY_UCHAR) return "uchar";
|
||||
if (ty == Type::PTY_SHORT) return "short";
|
||||
if (ty == Type::PTY_USHORT) return "ushort";
|
||||
if (ty == Type::PTY_INT) return "int";
|
||||
if (ty == Type::PTY_UINT) return "uint";
|
||||
if (ty == Type::PTY_FLOAT) return "float";
|
||||
if (ty == Type::PTY_DOUBLE) return "double";
|
||||
if (ty == Type::PTY_LIST) return "list";
|
||||
throw std::runtime_error("invalid type");
|
||||
return "";
|
||||
}
|
||||
|
||||
/* compute the type of a string */
|
||||
std::string stringOfType(Type ty) {
|
||||
if (ty.ty == Type::PTY_LIST) return "list " + stringOfTypeTag(ty.index) + " " + stringOfTypeTag(ty.data);
|
||||
else return stringOfTypeTag(ty.ty);
|
||||
}
|
||||
|
||||
/* PLY parser class */
|
||||
struct PlyParser
|
||||
{
|
||||
std::fstream fs;
|
||||
Mesh mesh;
|
||||
Ref<SceneGraph::Node> scene;
|
||||
|
||||
/* storage format of data in file */
|
||||
enum Format { ASCII, BINARY_BIG_ENDIAN, BINARY_LITTLE_ENDIAN } format;
|
||||
|
||||
/* constructor parses the input stream */
|
||||
PlyParser(const FileName& fileName) : format(ASCII)
|
||||
{
|
||||
/* open file */
|
||||
fs.open (fileName.c_str(), std::fstream::in | std::fstream::binary);
|
||||
if (!fs.is_open()) throw std::runtime_error("cannot open file : " + fileName.str());
|
||||
|
||||
/* check for file signature */
|
||||
std::string signature; getline(fs,signature);
|
||||
if (signature != "ply") throw std::runtime_error("invalid PLY file signature: " + signature);
|
||||
|
||||
/* read header */
|
||||
std::list<std::string> header;
|
||||
while (true) {
|
||||
std::string line; getline(fs,line);
|
||||
if (line == "end_header") break;
|
||||
if (line.find_first_of('#') == 0) continue;
|
||||
if (line == "") continue;
|
||||
header.push_back(line);
|
||||
}
|
||||
|
||||
/* parse header */
|
||||
parseHeader(header);
|
||||
|
||||
/* now parse all elements */
|
||||
for (std::vector<std::string>::iterator i = mesh.order.begin(); i!=mesh.order.end(); i++)
|
||||
parseElementData(mesh.elements[*i]);
|
||||
|
||||
/* create triangle mesh */
|
||||
scene = import();
|
||||
}
|
||||
|
||||
/* parse the PLY header */
|
||||
void parseHeader(std::list<std::string>& header)
|
||||
{
|
||||
while (!header.empty())
|
||||
{
|
||||
std::stringstream line(header.front());
|
||||
header.pop_front();
|
||||
|
||||
std::string tag; line >> tag;
|
||||
|
||||
/* ignore comments */
|
||||
if (tag == "comment") {
|
||||
}
|
||||
|
||||
/* parse format */
|
||||
else if (tag == "format")
|
||||
{
|
||||
std::string fmt; line >> fmt;
|
||||
if (fmt == "ascii") format = ASCII;
|
||||
else if (fmt == "binary_big_endian") format = BINARY_BIG_ENDIAN;
|
||||
else if (fmt == "binary_little_endian") format = BINARY_LITTLE_ENDIAN;
|
||||
else throw std::runtime_error("invalid PLY file format: " + fmt);
|
||||
std::string version; line >> version;
|
||||
if (version != "1.0") throw std::runtime_error("invalid PLY file version: " + version);
|
||||
}
|
||||
|
||||
/* parse end of header tag */
|
||||
else if (tag == "end_header")
|
||||
break;
|
||||
|
||||
/* parse elements */
|
||||
else if (tag == "element") parseElementDescr(line,header);
|
||||
|
||||
/* report unknown tags */
|
||||
else throw std::runtime_error("unknown tag in PLY file: " + tag);
|
||||
}
|
||||
}
|
||||
|
||||
/* parses a PLY element description */
|
||||
void parseElementDescr(std::stringstream& cin, std::list<std::string>& header)
|
||||
{
|
||||
Element elt;
|
||||
std::string name; cin >> name;
|
||||
size_t num; cin >> num;
|
||||
mesh.order.push_back(name);
|
||||
elt.name = name;
|
||||
elt.size = num;
|
||||
|
||||
/* parse all properties */
|
||||
while (!header.empty())
|
||||
{
|
||||
std::stringstream line(header.front());
|
||||
std::string tag; line >> tag;
|
||||
if (tag != "property") break;
|
||||
header.pop_front();
|
||||
|
||||
Type ty = parseType(line);
|
||||
std::string name; line >> name;
|
||||
elt.type[name] = ty;
|
||||
elt.properties.push_back(name);
|
||||
}
|
||||
|
||||
mesh.elements[name] = elt;
|
||||
}
|
||||
|
||||
/* parses a PLY type */
|
||||
Type parseType(std::stringstream& cin)
|
||||
{
|
||||
std::string ty; cin >> ty;
|
||||
if (ty == "list") {
|
||||
std::string ty0; cin >> ty0;
|
||||
std::string ty1; cin >> ty1;
|
||||
return Type(Type::PTY_LIST,typeTagOfString(ty0),typeTagOfString(ty1));
|
||||
} else return Type(typeTagOfString(ty));
|
||||
}
|
||||
|
||||
/* parses data of a PLY element */
|
||||
void parseElementData(Element& elt)
|
||||
{
|
||||
/* allocate data for all properties */
|
||||
for (std::vector<std::string>::iterator i=elt.properties.begin(); i!=elt.properties.end(); i++) {
|
||||
if (elt.type[*i].ty == Type::PTY_LIST) elt.list[*i] = std::vector<std::vector<size_t> >();
|
||||
else elt.data[*i] = std::vector<float>();
|
||||
}
|
||||
|
||||
/* parse all elements */
|
||||
for (size_t e=0; e<elt.size; e++)
|
||||
{
|
||||
/* load all properties of the element */
|
||||
for (std::vector<std::string>::iterator i=elt.properties.begin(); i!=elt.properties.end(); i++) {
|
||||
Type ty = elt.type[*i];
|
||||
if (ty.ty == Type::PTY_LIST) loadPropertyList(elt.list[*i],ty.index,ty.data);
|
||||
else loadPropertyData(elt.data[*i],ty.ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* load bytes from file and take care of little and big endian encoding */
|
||||
void readBytes(void* dst, int num) {
|
||||
if (format == BINARY_LITTLE_ENDIAN) fs.read((char*)dst,num);
|
||||
else if (format == BINARY_BIG_ENDIAN) for (int i=0; i<num; i++) fs.read((char*)dst+num-i-1,1);
|
||||
else throw std::runtime_error("internal error on PLY loader");
|
||||
}
|
||||
|
||||
int read_ascii_int () { int i; fs >> i; return i; }
|
||||
float read_ascii_float() { float f; fs >> f; return f; }
|
||||
signed char read_char () { if (format == ASCII) return read_ascii_int(); signed char r = 0; readBytes(&r,1); return r; }
|
||||
unsigned char read_uchar () { if (format == ASCII) return read_ascii_int(); unsigned char r = 0; readBytes(&r,1); return r; }
|
||||
signed short read_short () { if (format == ASCII) return read_ascii_int(); signed short r = 0; readBytes(&r,2); return r; }
|
||||
unsigned short read_ushort() { if (format == ASCII) return read_ascii_int(); unsigned short r = 0; readBytes(&r,2); return r; }
|
||||
signed int read_int () { if (format == ASCII) return read_ascii_int(); signed int r = 0; readBytes(&r,4); return r; }
|
||||
unsigned int read_uint () { if (format == ASCII) return read_ascii_int(); unsigned int r = 0; readBytes(&r,4); return r; }
|
||||
float read_float () { if (format == ASCII) return read_ascii_float(); float r = 0; readBytes(&r,4); return r; }
|
||||
double read_double() { if (format == ASCII) return read_ascii_float(); double r = 0; readBytes(&r,8); return r; }
|
||||
|
||||
/* load an integer type */
|
||||
size_t loadInteger(Type::Tag ty)
|
||||
{
|
||||
switch (ty) {
|
||||
case Type::PTY_CHAR : return read_char(); break;
|
||||
case Type::PTY_UCHAR : return read_uchar(); break;
|
||||
case Type::PTY_SHORT : return read_short(); break;
|
||||
case Type::PTY_USHORT : return read_ushort(); break;
|
||||
case Type::PTY_INT : return read_int(); break;
|
||||
case Type::PTY_UINT : return read_uint(); break;
|
||||
default : throw std::runtime_error("invalid type"); return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* load a list */
|
||||
void loadPropertyList(std::vector<std::vector<size_t> >& vec,Type::Tag index_ty,Type::Tag data_ty)
|
||||
{
|
||||
std::vector<size_t> lst;
|
||||
size_t num = loadInteger(index_ty);
|
||||
for (size_t i=0; i<num; i++) lst.push_back(loadInteger(data_ty));
|
||||
vec.push_back(lst);
|
||||
}
|
||||
|
||||
/* load a data element */
|
||||
void loadPropertyData(std::vector<float>& vec, Type::Tag ty)
|
||||
{
|
||||
switch (ty) {
|
||||
case Type::PTY_CHAR : vec.push_back(float(read_char())); break;
|
||||
case Type::PTY_UCHAR : vec.push_back(float(read_uchar())); break;
|
||||
case Type::PTY_SHORT : vec.push_back(float(read_short())); break;
|
||||
case Type::PTY_USHORT : vec.push_back(float(read_ushort())); break;
|
||||
case Type::PTY_INT : vec.push_back(float(read_int())); break;
|
||||
case Type::PTY_UINT : vec.push_back(float(read_uint())); break;
|
||||
case Type::PTY_FLOAT : vec.push_back(float(read_float())); break;
|
||||
case Type::PTY_DOUBLE : vec.push_back(float(read_double())); break;
|
||||
default : throw std::runtime_error("invalid type");
|
||||
}
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> import()
|
||||
{
|
||||
Ref<SceneGraph::MaterialNode> material = new OBJMaterial;
|
||||
Ref<SceneGraph::TriangleMeshNode> mesh_o = new SceneGraph::TriangleMeshNode(material,BBox1f(0,1),1);
|
||||
|
||||
/* convert all vertices */
|
||||
const Element& vertices = mesh.elements.at("vertex");
|
||||
const std::vector<float>& posx = vertices.data.at("x");
|
||||
const std::vector<float>& posy = vertices.data.at("y");
|
||||
const std::vector<float>& posz = vertices.data.at("z");
|
||||
|
||||
mesh_o->positions[0].resize(vertices.size);
|
||||
for (size_t i=0; i<vertices.size; i++) {
|
||||
mesh_o->positions[0][i].x = posx[i];
|
||||
mesh_o->positions[0][i].y = posy[i];
|
||||
mesh_o->positions[0][i].z = posz[i];
|
||||
}
|
||||
|
||||
/* convert all faces */
|
||||
const Element& faces = mesh.elements.at("face");
|
||||
const std::vector<std::vector<size_t> >& polygons = faces.list.at("vertex_indices");
|
||||
|
||||
for (size_t j=0; j<polygons.size(); j++)
|
||||
{
|
||||
const std::vector<size_t>& face = polygons[j];
|
||||
if (face.size() < 3) continue;
|
||||
|
||||
/* triangulate the face with a triangle fan */
|
||||
size_t i0 = face[0], i1 = 0, i2 = face[1];
|
||||
for (size_t k=2; k<face.size(); k++) {
|
||||
i1 = i2; i2 = face[k];
|
||||
mesh_o->triangles.push_back(SceneGraph::TriangleMeshNode::Triangle((unsigned int)i0, (unsigned int)i1, (unsigned int)i2));
|
||||
}
|
||||
}
|
||||
return mesh_o.dynamicCast<SceneGraph::Node>();
|
||||
}
|
||||
};
|
||||
|
||||
Ref<Node> loadPLY(const FileName& fileName) {
|
||||
return PlyParser(fileName).scene;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
14
Framework/external/embree/tutorials/common/scenegraph/ply_loader.h
vendored
Normal file
14
Framework/external/embree/tutorials/common/scenegraph/ply_loader.h
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "scenegraph.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace SceneGraph
|
||||
{
|
||||
Ref<Node> loadPLY(const FileName& fileName);
|
||||
}
|
||||
}
|
||||
2129
Framework/external/embree/tutorials/common/scenegraph/scenegraph.cpp
vendored
Normal file
2129
Framework/external/embree/tutorials/common/scenegraph/scenegraph.cpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
1660
Framework/external/embree/tutorials/common/scenegraph/scenegraph.h
vendored
Normal file
1660
Framework/external/embree/tutorials/common/scenegraph/scenegraph.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
91
Framework/external/embree/tutorials/common/scenegraph/texture.cpp
vendored
Normal file
91
Framework/external/embree/tutorials/common/scenegraph/texture.cpp
vendored
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "texture.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
bool isPowerOf2 (unsigned int x)
|
||||
{
|
||||
while (((x % 2) == 0) && x > 1)
|
||||
x /= 2;
|
||||
return (x == 1);
|
||||
}
|
||||
|
||||
static std::map<std::string,std::shared_ptr<Texture>> texture_cache;
|
||||
|
||||
void Texture::clearTextureCache() {
|
||||
texture_cache.clear();
|
||||
}
|
||||
|
||||
Texture::Texture ()
|
||||
: width(-1), height(-1), format(INVALID), bytesPerTexel(0), width_mask(0), height_mask(0), data(nullptr) {}
|
||||
|
||||
Texture::Texture(Ref<Image> img, const std::string fileName)
|
||||
: width(unsigned(img->width)), height(unsigned(img->height)), format(RGBA8), bytesPerTexel(4), width_mask(0), height_mask(0), data(nullptr), fileName(fileName)
|
||||
{
|
||||
width_mask = isPowerOf2(width) ? width-1 : 0;
|
||||
height_mask = isPowerOf2(height) ? height-1 : 0;
|
||||
|
||||
data = alignedUSMMalloc(4*width*height,16);
|
||||
img->convertToRGBA8((unsigned char*)data);
|
||||
}
|
||||
|
||||
Texture::Texture (unsigned width, unsigned height, const Format format, const char* in)
|
||||
: width(width), height(height), format(format), bytesPerTexel(getFormatBytesPerTexel(format)), width_mask(0), height_mask(0), data(nullptr)
|
||||
{
|
||||
width_mask = isPowerOf2(width) ? width-1 : 0;
|
||||
height_mask = isPowerOf2(height) ? height-1 : 0;
|
||||
|
||||
data = alignedUSMMalloc(bytesPerTexel*width*height,16);
|
||||
if (in) {
|
||||
for (size_t i=0; i<bytesPerTexel*width*height; i++)
|
||||
((char*)data)[i] = in[i];
|
||||
}
|
||||
else {
|
||||
memset(data,0 ,bytesPerTexel*width*height);
|
||||
}
|
||||
}
|
||||
|
||||
Texture::~Texture () {
|
||||
alignedUSMFree(data);
|
||||
}
|
||||
|
||||
const char* Texture::format_to_string(const Format format)
|
||||
{
|
||||
switch (format) {
|
||||
case RGBA8 : return "RGBA8";
|
||||
case RGB8 : return "RGB8";
|
||||
case FLOAT32: return "FLOAT32";
|
||||
default : THROW_RUNTIME_ERROR("invalid texture format");
|
||||
}
|
||||
}
|
||||
|
||||
Texture::Format Texture::string_to_format(const std::string& str)
|
||||
{
|
||||
if (str == "RGBA8") return RGBA8;
|
||||
else if (str == "RGB8") return RGB8;
|
||||
else if (str == "FLOAT32") return FLOAT32;
|
||||
else THROW_RUNTIME_ERROR("invalid texture format string");
|
||||
}
|
||||
|
||||
unsigned Texture::getFormatBytesPerTexel(const Format format)
|
||||
{
|
||||
switch (format) {
|
||||
case RGBA8 : return 4;
|
||||
case RGB8 : return 3;
|
||||
case FLOAT32: return 4;
|
||||
default : THROW_RUNTIME_ERROR("invalid texture format");
|
||||
}
|
||||
}
|
||||
|
||||
/*! read png texture from disk */
|
||||
std::shared_ptr<Texture> Texture::load(const FileName& fileName)
|
||||
{
|
||||
if (texture_cache.find(fileName.str()) != texture_cache.end())
|
||||
return texture_cache[fileName.str()];
|
||||
|
||||
std::shared_ptr<Texture> tex(new Texture(loadImage(fileName),fileName));
|
||||
return texture_cache[fileName.str()] = tex;
|
||||
}
|
||||
}
|
||||
71
Framework/external/embree/tutorials/common/scenegraph/texture.h
vendored
Normal file
71
Framework/external/embree/tutorials/common/scenegraph/texture.h
vendored
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(ISPC)
|
||||
|
||||
enum TEXTURE_FORMAT {
|
||||
Texture_RGBA8 = 1,
|
||||
Texture_RGB8 = 2,
|
||||
Texture_FLOAT32 = 3,
|
||||
};
|
||||
|
||||
struct Texture {
|
||||
int width;
|
||||
int height;
|
||||
int format;
|
||||
int bytesPerTexel;
|
||||
int width_mask;
|
||||
int height_mask;
|
||||
void* data;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#include "../default.h"
|
||||
#include "../image/image.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
struct Texture // FIXME: should be derived from SceneGraph::Node
|
||||
{
|
||||
ALIGNED_STRUCT_USM_(16);
|
||||
|
||||
enum Format {
|
||||
INVALID = 0,
|
||||
RGBA8 = 1,
|
||||
RGB8 = 2,
|
||||
FLOAT32 = 3,
|
||||
};
|
||||
|
||||
public:
|
||||
Texture ();
|
||||
Texture (Ref<Image> image, const std::string fileName);
|
||||
Texture (unsigned width, unsigned height, const Format format, const char* in = nullptr);
|
||||
~Texture ();
|
||||
|
||||
private:
|
||||
Texture (const Texture& other) DELETED; // do not implement
|
||||
Texture& operator= (const Texture& other) DELETED; // do not implement
|
||||
|
||||
public:
|
||||
static const char* format_to_string(const Format format);
|
||||
static Format string_to_format(const std::string& str);
|
||||
static unsigned getFormatBytesPerTexel(const Format format);
|
||||
|
||||
static std::shared_ptr<Texture> load(const FileName& fileName);
|
||||
static void clearTextureCache();
|
||||
|
||||
public:
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
Format format;
|
||||
unsigned bytesPerTexel;
|
||||
unsigned width_mask;
|
||||
unsigned height_mask;
|
||||
void* data;
|
||||
std::string fileName;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
2019
Framework/external/embree/tutorials/common/scenegraph/xml_loader.cpp
vendored
Normal file
2019
Framework/external/embree/tutorials/common/scenegraph/xml_loader.cpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
15
Framework/external/embree/tutorials/common/scenegraph/xml_loader.h
vendored
Normal file
15
Framework/external/embree/tutorials/common/scenegraph/xml_loader.h
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "scenegraph.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace SceneGraph
|
||||
{
|
||||
Ref<Node> loadXML(const FileName& fileName, const AffineSpace3fa& space = one);
|
||||
}
|
||||
}
|
||||
|
||||
196
Framework/external/embree/tutorials/common/scenegraph/xml_parser.cpp
vendored
Normal file
196
Framework/external/embree/tutorials/common/scenegraph/xml_parser.cpp
vendored
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "xml_parser.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace embree
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// XML Input
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*! parse a list of XML comments */
|
||||
void parseComments(Ref<Stream<Token> >& cin)
|
||||
{
|
||||
while (cin->peek() == Token::Sym("<!--")) {
|
||||
cin->drop();
|
||||
while (cin->peek() != Token::Sym("-->")) {
|
||||
if (cin->peek() == Token::Eof())
|
||||
THROW_RUNTIME_ERROR(cin->get().Location().str()+": --> expected");
|
||||
cin->drop();
|
||||
}
|
||||
cin->drop();
|
||||
}
|
||||
}
|
||||
|
||||
/*! parse XML parameter */
|
||||
void parseParm(Ref<Stream<Token> >& cin, std::map<std::string,std::string>& parms)
|
||||
{
|
||||
std::string name = cin->get().Identifier();
|
||||
if (cin->get() != Token::Sym("=")) THROW_RUNTIME_ERROR(cin->unget().Location().str()+": symbol \"=\" expected");
|
||||
parms[name] = cin->get().String();
|
||||
}
|
||||
|
||||
/*! parse XML header */
|
||||
Ref<XML> parseHeader(Ref<Stream<Token> >& cin)
|
||||
{
|
||||
Ref<XML> xml = new XML;
|
||||
if (cin->get() != Token::Sym("<?")) THROW_RUNTIME_ERROR(cin->unget().Location().str()+": wrong XML header");
|
||||
xml->name = cin->get().Identifier();
|
||||
parseComments(cin);
|
||||
while (cin->peek() != Token::Sym("?>")) {
|
||||
parseParm(cin,xml->parms);
|
||||
parseComments(cin);
|
||||
}
|
||||
cin->drop();
|
||||
return xml;
|
||||
}
|
||||
|
||||
/*! parse XML tag */
|
||||
Ref<XML> parseXML(Ref<Stream<Token> >& cin, size_t depth)
|
||||
{
|
||||
if (depth > 1024)
|
||||
THROW_RUNTIME_ERROR(cin->peek().Location().str()+": maximal nesting depth reached");
|
||||
|
||||
Ref<XML> xml = new XML;
|
||||
xml->loc = cin->peek().Location();
|
||||
|
||||
/* parse tag opening */
|
||||
if (cin->get() != Token::Sym("<")) THROW_RUNTIME_ERROR(cin->unget().Location().str()+": tag expected");
|
||||
|
||||
xml->name = cin->get().Identifier();
|
||||
parseComments(cin);
|
||||
while (cin->peek() != Token::Sym("/>") && cin->peek() != Token::Sym(">")) {
|
||||
parseParm(cin,xml->parms);
|
||||
parseComments(cin);
|
||||
}
|
||||
if (cin->peek() == Token::Sym("/>")) {
|
||||
cin->drop();
|
||||
return xml;
|
||||
}
|
||||
cin->drop();
|
||||
|
||||
/* parse body token list */
|
||||
parseComments(cin);
|
||||
while (cin->peek() != Token::Sym("<") && cin->peek() != Token::Sym("</")) {
|
||||
xml->body.push_back(cin->get());
|
||||
parseComments(cin);
|
||||
}
|
||||
|
||||
/* the body also contains children */
|
||||
if (cin->peek() == Token::Sym("<")) {
|
||||
while (cin->peek() != Token::Sym("</")) {
|
||||
xml->children.push_back(parseXML(cin,depth+1));
|
||||
parseComments(cin);
|
||||
}
|
||||
}
|
||||
|
||||
/* parse tag closing */
|
||||
if (cin->get() != Token::Sym("</") ) THROW_RUNTIME_ERROR(cin->unget().Location().str()+": symbol \"</\" expected");
|
||||
if (cin->get() != Token::Id(xml->name)) THROW_RUNTIME_ERROR(cin->unget().Location().str()+": closing "+xml->name+" expected");
|
||||
if (cin->get() != Token::Sym(">") ) THROW_RUNTIME_ERROR(cin->unget().Location().str()+": symbol \">\" expected");
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
/* load XML from token stream */
|
||||
Ref<XML> parseXML(Ref<Stream<int> > chars, std::string id, bool hasHeader = true, bool hasTail = false)
|
||||
{
|
||||
/* create lexer for XML file */
|
||||
std::vector<std::string> symbols;
|
||||
symbols.push_back("<!--");
|
||||
symbols.push_back("-->");
|
||||
symbols.push_back("<?");
|
||||
symbols.push_back("?>");
|
||||
symbols.push_back("</");
|
||||
symbols.push_back("/>");
|
||||
symbols.push_back("<");
|
||||
symbols.push_back(">");
|
||||
symbols.push_back("=");
|
||||
Ref<Stream<Token> > cin = new TokenStream(chars,TokenStream::alpha + TokenStream::ALPHA + "_" + id, TokenStream::separators, symbols);
|
||||
|
||||
if (hasHeader) parseHeader(cin);
|
||||
parseComments(cin);
|
||||
Ref<XML> xml = parseXML(cin,0);
|
||||
parseComments(cin);
|
||||
|
||||
if (!hasTail)
|
||||
if (cin->peek() != Token::Eof()) THROW_RUNTIME_ERROR(cin->peek().Location().str()+": end of file expected");
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
/*! load XML file from stream */
|
||||
std::istream& operator>>(std::istream& cin, Ref<XML>& xml) {
|
||||
xml = parseXML(new StdStream(cin),"",false,true);
|
||||
return cin;
|
||||
}
|
||||
|
||||
/*! load XML file from disk */
|
||||
Ref<XML> parseXML(const FileName& fileName, std::string id, bool hasHeader) {
|
||||
return parseXML(new FileStream(fileName),id,hasHeader,false);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// XML Output
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/* indent to some hierarchy level using spaces */
|
||||
void indent(std::ostream& cout, size_t depth) {
|
||||
for (size_t i=0; i<2*depth; i++) cout << " ";
|
||||
}
|
||||
|
||||
/* store XML to a stream */
|
||||
std::ostream& emitXML(std::ostream& cout, const Ref<XML>& xml, size_t depth = 0)
|
||||
{
|
||||
/* print header */
|
||||
if (depth == 0) cout << "<?xml version=\"1.0\"?>" << std::endl << std::endl;
|
||||
|
||||
/* print tag opening */
|
||||
indent(cout,depth); cout << "<" << xml->name;
|
||||
for (std::map<std::string,std::string>::const_iterator i=xml->parms.begin(); i!=xml->parms.end(); i++)
|
||||
cout << " " << i->first << "=" << "\"" << i->second << "\"";
|
||||
if (xml->children.size() == 0 && xml->body.size() == 0) {
|
||||
cout << "/>" << std::endl;
|
||||
return cout;
|
||||
}
|
||||
cout << ">";
|
||||
|
||||
bool compact = xml->body.size() < 16 && xml->children.size() == 0;
|
||||
if (!compact) cout << std::endl;
|
||||
|
||||
/* print token list */
|
||||
if (xml->body.size()) {
|
||||
if (!compact) indent(cout,depth+1);
|
||||
for (size_t i=0; i<xml->body.size(); i++)
|
||||
cout << xml->body[i] << (i!=xml->body.size()-1?" ":"");
|
||||
if (!compact) cout << std::endl;
|
||||
}
|
||||
|
||||
/* print children */
|
||||
for (size_t i=0; i<xml->children.size(); i++)
|
||||
emitXML(cout,xml->children[i],depth+1);
|
||||
|
||||
/* print tag closing */
|
||||
if (!compact) indent(cout,depth);
|
||||
return cout << "</" << xml->name << ">" << std::endl;
|
||||
}
|
||||
|
||||
/* store XML to stream */
|
||||
std::ostream& operator<<(std::ostream& cout, const Ref<XML>& xml) {
|
||||
return emitXML(cout,xml);
|
||||
}
|
||||
|
||||
/*! store XML to disk */
|
||||
void emitXML(const FileName& fileName, const Ref<XML>& xml)
|
||||
{
|
||||
std::ofstream cout(fileName.c_str());
|
||||
if (!cout.is_open()) THROW_RUNTIME_ERROR("cannot open file " + fileName.str() + " for writing");
|
||||
emitXML(cout,xml);
|
||||
cout.close();
|
||||
}
|
||||
}
|
||||
127
Framework/external/embree/tutorials/common/scenegraph/xml_parser.h
vendored
Normal file
127
Framework/external/embree/tutorials/common/scenegraph/xml_parser.h
vendored
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../default.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
/* an XML node */
|
||||
class XML : public RefCount
|
||||
{
|
||||
public:
|
||||
XML (const std::string& name = "") : name(name) {}
|
||||
|
||||
/*! returns number of children of XML node */
|
||||
size_t size() const { return children.size(); }
|
||||
|
||||
/*! checks if child with specified node tag exists */
|
||||
bool hasChild(const std::string& childID) const
|
||||
{
|
||||
for (size_t i=0; i<children.size(); i++)
|
||||
if (children[i]->name == childID) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*! returns a parameter of the XML node */
|
||||
std::string parm(const std::string& parmID) const {
|
||||
std::map<std::string,std::string>::const_iterator i = parms.find(parmID);
|
||||
if (i == parms.end()) return ""; else return i->second;
|
||||
}
|
||||
|
||||
Vec2f parm_Vec2f(const std::string& parmID) const {
|
||||
std::map<std::string,std::string>::const_iterator i = parms.find(parmID);
|
||||
if (i == parms.end()) THROW_RUNTIME_ERROR (loc.str()+": XML node has no parameter \"" + parmID + "\"");
|
||||
return string_to_Vec2f(i->second);
|
||||
}
|
||||
|
||||
Vec3fa parm_Vec3fa(const std::string& parmID) const {
|
||||
std::map<std::string,std::string>::const_iterator i = parms.find(parmID);
|
||||
if (i == parms.end()) THROW_RUNTIME_ERROR (loc.str()+": XML node has no parameter \"" + parmID + "\"");
|
||||
return Vec3fa(string_to_Vec3f(i->second));
|
||||
}
|
||||
|
||||
float parm_float(const std::string& parmID) const {
|
||||
std::map<std::string,std::string>::const_iterator i = parms.find(parmID);
|
||||
if (i == parms.end()) THROW_RUNTIME_ERROR (loc.str()+": XML node has no parameter \"" + parmID + "\"");
|
||||
return std::stof(i->second);
|
||||
}
|
||||
|
||||
/*! returns the nth child */
|
||||
const Ref<XML> child(const size_t id) const
|
||||
{
|
||||
if (id >= children.size())
|
||||
THROW_RUNTIME_ERROR (loc.str()+": XML node has no child \"" + toString(id) + "\"");
|
||||
return children[id];
|
||||
}
|
||||
|
||||
/*! returns child by node tag */
|
||||
const Ref<XML> child(const std::string& childID) const
|
||||
{
|
||||
for (size_t i=0; i<children.size(); i++)
|
||||
if (children[i]->name == childID) return children[i];
|
||||
THROW_RUNTIME_ERROR (loc.str()+": XML node has no child \"" + childID + "\"");
|
||||
}
|
||||
|
||||
/*! returns child by node tag without failing */
|
||||
const Ref<XML> childOpt(const std::string& childID) const
|
||||
{
|
||||
for (size_t i=0; i<children.size(); i++)
|
||||
if (children[i]->name == childID) return children[i];
|
||||
return null;
|
||||
}
|
||||
|
||||
/*! adds a new parameter to the node */
|
||||
Ref<XML> add(const std::string& name, const std::string& val) {
|
||||
parms[name] = val;
|
||||
return this;
|
||||
}
|
||||
|
||||
/*! adds a new child */
|
||||
Ref<XML> add(const Ref<XML>& xml) {
|
||||
children.push_back(xml);
|
||||
return this;
|
||||
}
|
||||
|
||||
/*! adds new data tokens to the body of the node */
|
||||
Ref<XML> add(const Token& tok) {
|
||||
body.push_back(tok);
|
||||
return this;
|
||||
}
|
||||
|
||||
/*! compares two XML nodes */
|
||||
friend bool operator ==( const Ref<XML>& a, const Ref<XML>& b ) {
|
||||
return a->name == b->name && a->parms == b->parms && a->children == b->children && a->body == b->body;
|
||||
}
|
||||
|
||||
/*! orders two XML nodes */
|
||||
friend bool operator <( const Ref<XML>& a, const Ref<XML>& b ) {
|
||||
if (a->name != b->name ) return a->name < b->name;
|
||||
if (a->parms != b->parms ) return a->parms < b->parms;
|
||||
if (a->children != b->children) return a->children < b->children;
|
||||
if (a->body != b->body ) return a->body < b->body;
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
ParseLocation loc;
|
||||
std::string name;
|
||||
std::map<std::string,std::string> parms;
|
||||
std::vector<Ref<XML> > children;
|
||||
std::vector<Token> body;
|
||||
};
|
||||
|
||||
/*! load XML file from stream */
|
||||
std::istream& operator>>(std::istream& cin, Ref<XML>& xml);
|
||||
|
||||
/*! load XML file from disk */
|
||||
Ref<XML> parseXML(const FileName& fileName, std::string id = "", bool hasHeader = true);
|
||||
|
||||
/* store XML to stream */
|
||||
std::ostream& operator<<(std::ostream& cout, const Ref<XML>& xml);
|
||||
|
||||
/*! store XML to disk */
|
||||
void emitXML(const FileName& fileName, const Ref<XML>& xml);
|
||||
}
|
||||
|
||||
798
Framework/external/embree/tutorials/common/scenegraph/xml_writer.cpp
vendored
Normal file
798
Framework/external/embree/tutorials/common/scenegraph/xml_writer.cpp
vendored
Normal file
|
|
@ -0,0 +1,798 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "xml_writer.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
class XMLWriter
|
||||
{
|
||||
public:
|
||||
|
||||
XMLWriter(Ref<SceneGraph::Node> root, const FileName& fileName, bool embedTextures, bool referenceMaterials, bool binaryFormat);
|
||||
|
||||
public:
|
||||
void tab();
|
||||
void open(std::string str);
|
||||
void open(std::string str, size_t id);
|
||||
void open(std::string str, size_t id, std::string name);
|
||||
void close(std::string str);
|
||||
|
||||
void store(const char* name, const char* str);
|
||||
void store(const char* name, const float& v);
|
||||
void store(const char* name, const Vec3fa& v);
|
||||
|
||||
void store_array_elt(const int& v);
|
||||
void store_array_elt(const Vec2f& v);
|
||||
void store_array_elt(const Vec3f& v);
|
||||
void store_array_elt(const Vec3fa& v);
|
||||
void store_array_elt(const Vec3ff& v);
|
||||
void store_array_elt(const SceneGraph::TriangleMeshNode::Triangle& v);
|
||||
void store_array_elt(const SceneGraph::QuadMeshNode::Quad& v);
|
||||
|
||||
template<typename T> void store_array_text (const char* name, const std::vector<T>& vec);
|
||||
template<typename T> void store_array_binary(const char* name, const std::vector<T>& vec);
|
||||
template<typename T> void store (const char* name, const std::vector<T>& vec);
|
||||
|
||||
void store_array_text (const char* name, const avector<Vec3fa>& vec);
|
||||
void store_array_binary(const char* name, const avector<Vec3fa>& vec);
|
||||
void store (const char* name, const avector<Vec3fa>& vec);
|
||||
|
||||
void store_array_text (const char* name, const avector<Vec3ff>& vec);
|
||||
void store_array_binary(const char* name, const avector<Vec3ff>& vec);
|
||||
void store (const char* name, const avector<Vec3ff>& vec);
|
||||
|
||||
void store_parm(const char* name, const float& v);
|
||||
void store_parm(const char* name, const Vec3fa& v);
|
||||
void store_parm(const char* name, const std::shared_ptr<Texture> tex);
|
||||
void store(const char* name, const AffineSpace3fa& space);
|
||||
|
||||
void store(const SceneGraph::PointLight& light, ssize_t id);
|
||||
void store(const SceneGraph::SpotLight& light, ssize_t id);
|
||||
void store(const SceneGraph::DirectionalLight& light, ssize_t id);
|
||||
void store(const SceneGraph::DistantLight& light, ssize_t id);
|
||||
void store(const SceneGraph::AmbientLight& light, ssize_t id);
|
||||
void store(const SceneGraph::TriangleLight& light, ssize_t id);
|
||||
void store(const SceneGraph::QuadLight& light, ssize_t id);
|
||||
void store(Ref<SceneGraph::LightNode> light, ssize_t id);
|
||||
void store(Ref<SceneGraph::AnimatedLightNode> light, ssize_t id);
|
||||
|
||||
void store(Ref<MatteMaterial> material, ssize_t id);
|
||||
void store(Ref<MirrorMaterial> material, ssize_t id);
|
||||
void store(Ref<ThinDielectricMaterial> material, ssize_t id);
|
||||
void store(Ref<OBJMaterial> material, ssize_t id);
|
||||
void store(Ref<MetalMaterial> material, ssize_t id);
|
||||
void store(Ref<VelvetMaterial> material, ssize_t id);
|
||||
void store(Ref<DielectricMaterial> material, ssize_t id);
|
||||
void store(Ref<MetallicPaintMaterial> material, ssize_t id);
|
||||
void store(Ref<HairMaterial> material, ssize_t id);
|
||||
void store(Ref<SceneGraph::MaterialNode> material);
|
||||
|
||||
void store(Ref<SceneGraph::TriangleMeshNode> mesh, ssize_t id);
|
||||
void store(Ref<SceneGraph::QuadMeshNode> mesh, ssize_t id);
|
||||
void store(Ref<SceneGraph::SubdivMeshNode> mesh, ssize_t id);
|
||||
void store(Ref<SceneGraph::HairSetNode> hair, ssize_t id);
|
||||
|
||||
void store(Ref<SceneGraph::PerspectiveCameraNode> camera, ssize_t id);
|
||||
void store(Ref<SceneGraph::AnimatedPerspectiveCameraNode> camera, ssize_t id);
|
||||
void store(Ref<SceneGraph::TransformNode> node, ssize_t id);
|
||||
void store(std::vector<Ref<SceneGraph::TransformNode>> nodes);
|
||||
void store(Ref<SceneGraph::GroupNode> group, ssize_t id);
|
||||
void store(Ref<SceneGraph::Node> node);
|
||||
|
||||
private:
|
||||
std::fstream xml; //!< .xml file for writing XML data
|
||||
std::fstream bin; //!< .bin file for writing binary data
|
||||
|
||||
private:
|
||||
size_t ident;
|
||||
size_t currentNodeID;
|
||||
std::map<Ref<SceneGraph::Node>, size_t> nodeMap;
|
||||
std::map<std::shared_ptr<Texture>, size_t> textureMap; // FIXME: use Ref<Texture>
|
||||
bool embedTextures;
|
||||
bool referenceMaterials;
|
||||
bool binaryFormat;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// Storing of objects to XML file
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void XMLWriter::tab()
|
||||
{
|
||||
for (size_t i=0; i<ident; i++)
|
||||
xml << " ";
|
||||
}
|
||||
|
||||
void XMLWriter::open(std::string str)
|
||||
{
|
||||
tab(); xml << "<" << str << ">" << std::endl;
|
||||
ident+=2;
|
||||
}
|
||||
|
||||
void XMLWriter::open(std::string str, size_t id)
|
||||
{
|
||||
tab(); xml << "<" << str << " id=\"" << id << "\">" << std::endl;
|
||||
ident+=2;
|
||||
}
|
||||
|
||||
void XMLWriter::open(std::string str, size_t id, std::string name)
|
||||
{
|
||||
tab(); xml << "<" << str << " id=\"" << id << "\" name=\"" << name << "\">" << std::endl;
|
||||
ident+=2;
|
||||
}
|
||||
|
||||
void XMLWriter::close(std::string str)
|
||||
{
|
||||
assert(ident>=2);
|
||||
ident-=2;
|
||||
tab(); xml << "</" << str << ">" << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store(const char* name, const char* str) {
|
||||
tab(); xml << "<" << name << ">\"" << str << "\"</" << name << ">" << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store(const char* name, const float& v) {
|
||||
tab(); xml << "<" << name << ">" << v << "</" << name << ">" << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store(const char* name, const Vec3fa& v) {
|
||||
tab(); xml << "<" << name << ">" << v.x << " " << v.y << " " << v.z << "</" << name << ">" << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store_array_elt(const int& v) {
|
||||
xml << v << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store_array_elt(const Vec2f& v) {
|
||||
xml << v.x << " " << v.y << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store_array_elt(const Vec3f& v) {
|
||||
xml << v.x << " " << v.y << " " << v.z << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store_array_elt(const Vec3fa& v) {
|
||||
xml << v.x << " " << v.y << " " << v.z << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store_array_elt(const Vec3ff& v) {
|
||||
xml << v.x << " " << v.y << " " << v.z << " " << v.w << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store_array_elt(const SceneGraph::TriangleMeshNode::Triangle& v) {
|
||||
xml << v.v0 << " " << v.v1 << " " << v.v2 << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store_array_elt(const SceneGraph::QuadMeshNode::Quad& v) {
|
||||
xml << v.v0 << " " << v.v1 << " " << v.v2 << " " << v.v3 << std::endl;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void XMLWriter::store_array_text(const char* name, const std::vector<T>& vec)
|
||||
{
|
||||
open(name);
|
||||
for (size_t i=0; i<vec.size(); i++) {
|
||||
tab(); store_array_elt(vec[i]);
|
||||
}
|
||||
close(name);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void XMLWriter::store_array_binary(const char* name, const std::vector<T>& vec)
|
||||
{
|
||||
std::streampos offset = bin.tellg();
|
||||
tab(); xml << "<" << name << " ofs=\"" << offset << "\" size=\"" << vec.size() << "\"/>" << std::endl;
|
||||
if (vec.size()) bin.write((char*)vec.data(),vec.size()*sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void XMLWriter::store(const char* name, const std::vector<T>& vec)
|
||||
{
|
||||
if (binaryFormat) store_array_binary(name,vec);
|
||||
else store_array_text (name,vec);
|
||||
}
|
||||
|
||||
void XMLWriter::store_array_text(const char* name, const avector<Vec3fa>& vec)
|
||||
{
|
||||
open(name);
|
||||
for (size_t i=0; i<vec.size(); i++) {
|
||||
tab(); store_array_elt(vec[i]);
|
||||
}
|
||||
close(name);
|
||||
}
|
||||
|
||||
void XMLWriter::store_array_binary(const char* name, const avector<Vec3fa>& vec)
|
||||
{
|
||||
std::streampos offset = bin.tellg();
|
||||
tab(); xml << "<" << name << " ofs=\"" << offset << "\" size=\"" << vec.size() << "\"/>" << std::endl;
|
||||
for (size_t i=0; i<vec.size(); i++) bin.write((char*)&vec[i],sizeof(Vec3f));
|
||||
}
|
||||
|
||||
void XMLWriter::store(const char* name, const avector<Vec3fa>& vec)
|
||||
{
|
||||
if (binaryFormat) store_array_binary(name,vec);
|
||||
else store_array_text (name,vec);
|
||||
}
|
||||
|
||||
void XMLWriter::store_array_text(const char* name, const avector<Vec3ff>& vec)
|
||||
{
|
||||
open(name);
|
||||
for (size_t i=0; i<vec.size(); i++) {
|
||||
tab(); store_array_elt(vec[i]);
|
||||
}
|
||||
close(name);
|
||||
}
|
||||
|
||||
void XMLWriter::store_array_binary(const char* name, const avector<Vec3ff>& vec)
|
||||
{
|
||||
std::streampos offset = bin.tellg();
|
||||
tab(); xml << "<" << name << " ofs=\"" << offset << "\" size=\"" << vec.size() << "\"/>" << std::endl;
|
||||
for (size_t i=0; i<vec.size(); i++) bin.write((char*)&vec[i],sizeof(Vec3ff));
|
||||
}
|
||||
|
||||
void XMLWriter::store(const char* name, const avector<Vec3ff>& vec)
|
||||
{
|
||||
if (binaryFormat) store_array_binary(name,vec);
|
||||
else store_array_text (name,vec);
|
||||
}
|
||||
|
||||
void XMLWriter::store_parm(const char* name, const float& v) {
|
||||
tab(); xml << "<float name=\"" << name << "\">" << v << "</float>" << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store_parm(const char* name, const Vec3fa& v) {
|
||||
tab(); xml << "<float3 name=\"" << name << "\">" << v.x << " " << v.y << " " << v.z << "</float3>" << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store_parm(const char* name, const std::shared_ptr<Texture> tex)
|
||||
{
|
||||
if (tex == nullptr) return;
|
||||
|
||||
if (textureMap.find(tex) != textureMap.end()) {
|
||||
tab(); xml << "<texture3d name=\"" << name << "\" id=\"" << textureMap[tex] << "\"/>" << std::endl;
|
||||
} else if (embedTextures) {
|
||||
std::streampos offset = bin.tellg();
|
||||
bin.write((char*)tex->data,tex->width*tex->height*tex->bytesPerTexel);
|
||||
const size_t id = textureMap[tex] = currentNodeID++;
|
||||
tab(); xml << "<texture3d name=\"" << name << "\" id=\"" << id << "\" ofs=\"" << offset
|
||||
<< "\" width=\"" << tex->width << "\" height=\"" << tex->height
|
||||
<< "\" format=\"" << Texture::format_to_string(tex->format) << "\"/>" << std::endl;
|
||||
}
|
||||
else {
|
||||
const size_t id = textureMap[tex] = currentNodeID++;
|
||||
tab(); xml << "<texture3d name=\"" << name << "\" id=\"" << id << "\" src=\"" << tex->fileName << "\"/>" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void XMLWriter::store(const char* name, const AffineSpace3fa& space)
|
||||
{
|
||||
tab(); xml << "<" << name << ">" << std::endl;
|
||||
tab(); xml << " " << space.l.vx.x << " " << space.l.vy.x << " " << space.l.vz.x << " " << space.p.x << std::endl;
|
||||
tab(); xml << " " << space.l.vx.y << " " << space.l.vy.y << " " << space.l.vz.y << " " << space.p.y << std::endl;
|
||||
tab(); xml << " " << space.l.vx.z << " " << space.l.vy.z << " " << space.l.vz.z << " " << space.p.z << std::endl;
|
||||
tab(); xml << "</" << name << ">" << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store(const SceneGraph::PointLight& light, ssize_t id)
|
||||
{
|
||||
open("PointLight",id);
|
||||
store("AffineSpace",AffineSpace3fa::translate(light.P));
|
||||
store("I",light.I);
|
||||
close("PointLight");
|
||||
}
|
||||
|
||||
void XMLWriter::store(const SceneGraph::SpotLight& light, ssize_t id)
|
||||
{
|
||||
open("SpotLight",id);
|
||||
store("AffineSpace",AffineSpace3fa(frame(light.D),light.P));
|
||||
store("I",light.I);
|
||||
store("angleMin",light.angleMin);
|
||||
store("angleMax",light.angleMax);
|
||||
close("SpotLight");
|
||||
}
|
||||
|
||||
void XMLWriter::store(const SceneGraph::DirectionalLight& light, ssize_t id)
|
||||
{
|
||||
open("DirectionalLight",id);
|
||||
store("AffineSpace",frame(light.D));
|
||||
store("E",light.E);
|
||||
close("DirectionalLight");
|
||||
}
|
||||
|
||||
void XMLWriter::store(const SceneGraph::DistantLight& light, ssize_t id)
|
||||
{
|
||||
open("DistantLight",id);
|
||||
store("AffineSpace",frame(light.D));
|
||||
store("L",light.L);
|
||||
store("halfAngle",light.halfAngle);
|
||||
close("DistantLight");
|
||||
}
|
||||
|
||||
void XMLWriter::store(const SceneGraph::AmbientLight& light, ssize_t id)
|
||||
{
|
||||
open("AmbientLight");
|
||||
store("L",light.L);
|
||||
close("AmbientLight");
|
||||
}
|
||||
|
||||
void XMLWriter::store(const SceneGraph::TriangleLight& light, ssize_t id)
|
||||
{
|
||||
open("TriangleLight",id);
|
||||
const Vec3fa dx = light.v0-light.v2;
|
||||
const Vec3fa dy = light.v1-light.v2;
|
||||
const Vec3fa dz = cross(dx,dy);
|
||||
const Vec3fa p = light.v2;
|
||||
store("AffineSpace",AffineSpace3fa(dx,dy,dz,p));
|
||||
store("L",light.L);
|
||||
close("TriangleLight");
|
||||
}
|
||||
|
||||
void XMLWriter::store(const SceneGraph::QuadLight& light, ssize_t id)
|
||||
{
|
||||
open("QuadLight",id);
|
||||
const Vec3fa dx = light.v3-light.v0;
|
||||
const Vec3fa dy = light.v1-light.v0;
|
||||
const Vec3fa dz = cross(dx,dy);
|
||||
const Vec3fa p = light.v2;
|
||||
store("AffineSpace",AffineSpace3fa(dx,dy,dz,p));
|
||||
store("L",light.L);
|
||||
close("QuadLight");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<SceneGraph::LightNode> node, ssize_t id)
|
||||
{
|
||||
if (auto light = node.dynamicCast<SceneGraph::LightNodeImpl<SceneGraph::AmbientLight>>())
|
||||
store(light->light,id);
|
||||
else if (auto light = node.dynamicCast<SceneGraph::LightNodeImpl<SceneGraph::PointLight>>())
|
||||
store(light->light,id);
|
||||
else if (auto light = node.dynamicCast<SceneGraph::LightNodeImpl<SceneGraph::DirectionalLight>>())
|
||||
store(light->light,id);
|
||||
else if (auto light = node.dynamicCast<SceneGraph::LightNodeImpl<SceneGraph::SpotLight>>())
|
||||
store(light->light,id);
|
||||
else if (auto light = node.dynamicCast<SceneGraph::LightNodeImpl<SceneGraph::DistantLight>>())
|
||||
store(light->light,id);
|
||||
else if (auto light = node.dynamicCast<SceneGraph::LightNodeImpl<SceneGraph::TriangleLight>>())
|
||||
store(light->light,id);
|
||||
else if (auto light = node.dynamicCast<SceneGraph::LightNodeImpl<SceneGraph::QuadLight>>())
|
||||
store(light->light,id);
|
||||
else
|
||||
throw std::runtime_error("unsupported light");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<SceneGraph::AnimatedLightNode> node, ssize_t id)
|
||||
{
|
||||
open(std::string("AnimatedLight ")+
|
||||
"time_range=\""+std::to_string(node->time_range.lower)+" "+std::to_string(node->time_range.upper)+"\"");
|
||||
|
||||
for (size_t i=0; i<node->lights.size(); i++)
|
||||
store(node->lights[i].dynamicCast<SceneGraph::Node>());
|
||||
|
||||
close("AnimatedLight");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<MatteMaterial> material, ssize_t id)
|
||||
{
|
||||
open("material",id,material->name);
|
||||
store("code","Matte");
|
||||
open("parameters");
|
||||
store_parm("reflectance",material->reflectance);
|
||||
close("parameters");
|
||||
close("material");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<MirrorMaterial> material, ssize_t id)
|
||||
{
|
||||
open("material",id,material->name);
|
||||
store("code","Mirror");
|
||||
open("parameters");
|
||||
store_parm("reflectance",material->reflectance);
|
||||
close("parameters");
|
||||
close("material");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<ThinDielectricMaterial> material, ssize_t id)
|
||||
{
|
||||
open("material",id,material->name);
|
||||
store("code","ThinDielectric");
|
||||
open("parameters");
|
||||
store_parm("transmission",material->transmission);
|
||||
store_parm("eta",material->eta);
|
||||
store_parm("thickness",material->thickness);
|
||||
close("parameters");
|
||||
close("material");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<OBJMaterial> material, ssize_t id)
|
||||
{
|
||||
open("material",id,material->name);
|
||||
store("code","OBJ");
|
||||
open("parameters");
|
||||
store_parm("d",material->d);
|
||||
store_parm("Ka",material->Ka);
|
||||
store_parm("Kd",material->Kd);
|
||||
store_parm("Ks",material->Ks);
|
||||
store_parm("Kt",material->Kt);
|
||||
store_parm("Ns",material->Ns);
|
||||
store_parm("Ni",material->Ni);
|
||||
store_parm("map_d",material->_map_d);
|
||||
store_parm("map_Kd",material->_map_Kd);
|
||||
store_parm("map_Ks",material->_map_Ks);
|
||||
store_parm("map_Ns",material->_map_Ns);
|
||||
store_parm("map_Displ",material->_map_Displ);
|
||||
close("parameters");
|
||||
close("material");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<MetalMaterial> material, ssize_t id)
|
||||
{
|
||||
open("material",id,material->name);
|
||||
store("code","Metal");
|
||||
open("parameters");
|
||||
store_parm("reflectance",material->reflectance);
|
||||
store_parm("eta",material->eta);
|
||||
store_parm("k",material->k);
|
||||
store_parm("roughness",material->roughness);
|
||||
close("parameters");
|
||||
close("material");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<VelvetMaterial> material, ssize_t id)
|
||||
{
|
||||
open("material",id,material->name);
|
||||
store("code","Velvet");
|
||||
open("parameters");
|
||||
store_parm("reflectance",material->reflectance);
|
||||
store_parm("backScattering",material->backScattering);
|
||||
store_parm("horizonScatteringColor",material->horizonScatteringColor);
|
||||
store_parm("horizonScatteringFallOff",material->horizonScatteringFallOff);
|
||||
close("parameters");
|
||||
close("material");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<DielectricMaterial> material, ssize_t id)
|
||||
{
|
||||
open("material",id,material->name);
|
||||
store("code","Dielectric");
|
||||
open("parameters");
|
||||
store_parm("transmissionOutside",material->transmissionOutside);
|
||||
store_parm("transmission",material->transmissionInside);
|
||||
store_parm("etaOutside",material->etaOutside);
|
||||
store_parm("etaInside",material->etaInside);
|
||||
close("parameters");
|
||||
close("material");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<MetallicPaintMaterial> material, ssize_t id)
|
||||
{
|
||||
open("material",id,material->name);
|
||||
store("code","MetallicPaint");
|
||||
open("parameters");
|
||||
store_parm("shadeColor",material->shadeColor);
|
||||
store_parm("glitterColor",material->glitterColor);
|
||||
store_parm("glitterSpread",material->glitterSpread);
|
||||
store_parm("eta",material->eta);
|
||||
close("parameters");
|
||||
close("material");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<HairMaterial> material, ssize_t id)
|
||||
{
|
||||
open("material",id,material->name);
|
||||
store("code","Hair");
|
||||
open("parameters");
|
||||
store_parm("Kr",material->Kr);
|
||||
store_parm("Kt",material->Kt);
|
||||
store_parm("nx",material->nx);
|
||||
store_parm("ny",material->ny);
|
||||
close("parameters");
|
||||
close("material");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<SceneGraph::MaterialNode> mnode)
|
||||
{
|
||||
/* let materials reference by their name, allows separate bindings of materials */
|
||||
if (referenceMaterials) {
|
||||
tab(); xml << "<material id=\""+mnode->name+"\"/>" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
Ref<SceneGraph::Node> node = mnode.dynamicCast<SceneGraph::Node>();
|
||||
if (nodeMap.find(node) != nodeMap.end()) {
|
||||
tab(); xml << "<material id=\"" << nodeMap[node] << "\"/>" << std::endl;
|
||||
return;
|
||||
}
|
||||
const ssize_t id = nodeMap[node] = currentNodeID++;
|
||||
|
||||
if (Ref<OBJMaterial> m = mnode.dynamicCast<OBJMaterial>()) store(m,id);
|
||||
else if (Ref<ThinDielectricMaterial> m = mnode.dynamicCast<ThinDielectricMaterial>()) store(m,id);
|
||||
else if (Ref<MetalMaterial> m = mnode.dynamicCast<MetalMaterial>()) store(m,id);
|
||||
else if (Ref<VelvetMaterial> m = mnode.dynamicCast<VelvetMaterial>()) store(m,id);
|
||||
else if (Ref<DielectricMaterial> m = mnode.dynamicCast<DielectricMaterial>()) store(m,id);
|
||||
else if (Ref<MetallicPaintMaterial> m = mnode.dynamicCast<MetallicPaintMaterial>()) store(m,id);
|
||||
else if (Ref<MatteMaterial> m = mnode.dynamicCast<MatteMaterial>()) store(m,id);
|
||||
else if (Ref<MirrorMaterial> m = mnode.dynamicCast<MirrorMaterial>()) store(m,id);
|
||||
else if (Ref<ReflectiveMetalMaterial> m = mnode.dynamicCast<ReflectiveMetalMaterial>()) store(m,id);
|
||||
else if (Ref<HairMaterial> m = mnode.dynamicCast<HairMaterial>()) store(m,id);
|
||||
else throw std::runtime_error("unsupported material");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<SceneGraph::TriangleMeshNode> mesh, ssize_t id)
|
||||
{
|
||||
open("TriangleMesh",id);
|
||||
store(mesh->material);
|
||||
|
||||
if (mesh->numTimeSteps() != 1) open("animated_positions");
|
||||
for (const auto& p : mesh->positions) store("positions",p);
|
||||
if (mesh->numTimeSteps() != 1) close("animated_positions");
|
||||
|
||||
if (mesh->numTimeSteps() != 1) open("animated_normals");
|
||||
for (const auto& p : mesh->normals) store("normals",p);
|
||||
if (mesh->numTimeSteps() != 1) close("animated_normals");
|
||||
|
||||
store("texcoords",mesh->texcoords);
|
||||
store("triangles",mesh->triangles);
|
||||
close("TriangleMesh");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<SceneGraph::QuadMeshNode> mesh, ssize_t id)
|
||||
{
|
||||
open("QuadMesh",id);
|
||||
store(mesh->material);
|
||||
|
||||
if (mesh->numTimeSteps() != 1) open("animated_positions");
|
||||
for (const auto& p : mesh->positions) store("positions",p);
|
||||
if (mesh->numTimeSteps() != 1) close("animated_positions");
|
||||
|
||||
if (mesh->numTimeSteps() != 1) open("animated_normals");
|
||||
for (const auto& p : mesh->normals) store("normals",p);
|
||||
if (mesh->numTimeSteps() != 1) close("animated_normals");
|
||||
|
||||
store("texcoords",mesh->texcoords);
|
||||
store("indices",mesh->quads);
|
||||
close("QuadMesh");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<SceneGraph::SubdivMeshNode> mesh, ssize_t id)
|
||||
{
|
||||
open("SubdivisionMesh",id);
|
||||
store(mesh->material);
|
||||
|
||||
if (mesh->numTimeSteps() != 1) open("animated_positions");
|
||||
for (const auto& p : mesh->positions) store("positions",p);
|
||||
if (mesh->numTimeSteps() != 1) close("animated_positions");
|
||||
|
||||
if (mesh->numTimeSteps() != 1) open("animated_normals");
|
||||
for (const auto& p : mesh->normals) store("normals",p);
|
||||
if (mesh->numTimeSteps() != 1) close("animated_normals");
|
||||
|
||||
store("texcoords",mesh->texcoords);
|
||||
store("position_indices",mesh->position_indices);
|
||||
store("normal_indices",mesh->normal_indices);
|
||||
store("texcoord_indices",mesh->texcoord_indices);
|
||||
store("faces",mesh->verticesPerFace);
|
||||
store("holes",mesh->holes);
|
||||
store("edge_creases",mesh->edge_creases);
|
||||
store("edge_crease_weights",mesh->edge_crease_weights);
|
||||
store("vertex_creases",mesh->vertex_creases);
|
||||
store("vertex_crease_weights",mesh->vertex_crease_weights);
|
||||
close("SubdivisionMesh");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<SceneGraph::HairSetNode> mesh, ssize_t id)
|
||||
{
|
||||
std::string str_type = "";
|
||||
std::string str_subtype = "";
|
||||
|
||||
switch (mesh->type) {
|
||||
case RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE:
|
||||
str_type = "linear";
|
||||
str_subtype = "flat";
|
||||
break;
|
||||
|
||||
case RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE:
|
||||
str_type = "bezier";
|
||||
str_subtype = "round";
|
||||
break;
|
||||
|
||||
case RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE:
|
||||
str_type = "bezier";
|
||||
str_subtype = "flat";
|
||||
break;
|
||||
|
||||
case RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BEZIER_CURVE:
|
||||
str_type = "bezier";
|
||||
str_subtype = "oriented";
|
||||
break;
|
||||
|
||||
case RTC_GEOMETRY_TYPE_ROUND_BSPLINE_CURVE:
|
||||
str_type = "bspline";
|
||||
str_subtype = "round";
|
||||
break;
|
||||
|
||||
case RTC_GEOMETRY_TYPE_FLAT_BSPLINE_CURVE:
|
||||
str_type = "bspline";
|
||||
str_subtype = "flat";
|
||||
break;
|
||||
|
||||
case RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BSPLINE_CURVE:
|
||||
str_type = "bspline";
|
||||
str_subtype = "oriented";
|
||||
break;
|
||||
|
||||
default:
|
||||
throw std::runtime_error("invalid curve type");
|
||||
}
|
||||
|
||||
std::vector<int> indices(mesh->hairs.size());
|
||||
std::vector<int> hairid(mesh->hairs.size());
|
||||
for (size_t i=0; i<mesh->hairs.size(); i++) {
|
||||
indices[i] = mesh->hairs[i].vertex;
|
||||
hairid[i] = mesh->hairs[i].id;
|
||||
}
|
||||
|
||||
open("Curves type=\""+str_subtype+"\" basis=\""+str_type+"\"",id);
|
||||
store(mesh->material);
|
||||
if (mesh->numTimeSteps() != 1) open("animated_positions");
|
||||
for (const auto& p : mesh->positions) store("positions",p);
|
||||
if (mesh->numTimeSteps() != 1) close("animated_positions");
|
||||
if (mesh->normals.size()) {
|
||||
if (mesh->numTimeSteps() != 1) open("animated_normals");
|
||||
for (const auto& p : mesh->normals) store("normals",p);
|
||||
if (mesh->numTimeSteps() != 1) close("animated_normals");
|
||||
}
|
||||
store("indices",indices);
|
||||
store("hairid",hairid);
|
||||
close("Curves");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<SceneGraph::PerspectiveCameraNode> camera, ssize_t id)
|
||||
{
|
||||
tab();
|
||||
xml << "<PerspectiveCamera " <<
|
||||
"id=\"" << id << "\" " <<
|
||||
"name=\"" << camera->name << "\" " <<
|
||||
"from=\"" << camera->data.from.x << " " << camera->data.from.y << " " << camera->data.from.z << "\" " <<
|
||||
"to=\"" << camera->data.to.x << " " << camera->data.to.y << " " << camera->data.to.z << "\" " <<
|
||||
"up=\"" << camera->data.up.x << " " << camera->data.up.y << " " << camera->data.up.z << "\" " <<
|
||||
"fov=\"" << camera->data.fov << "\" " << "/>" << std::endl;
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<SceneGraph::AnimatedPerspectiveCameraNode> camera, ssize_t id)
|
||||
{
|
||||
open(std::string("AnimatedPerspectiveCamera ")+
|
||||
"name=\"" + camera->name + "\" "
|
||||
"time_range=\""+std::to_string(camera->time_range.lower)+" "+std::to_string(camera->time_range.upper)+"\"");
|
||||
|
||||
for (size_t i=0; i<camera->size(); i++)
|
||||
store(camera->cameras[i].dynamicCast<SceneGraph::Node>());
|
||||
|
||||
close("AnimatedPerspectiveCamera");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<SceneGraph::TransformNode> node, ssize_t id)
|
||||
{
|
||||
if (node->spaces.size() == 1)
|
||||
{
|
||||
open("Transform",id);
|
||||
store("AffineSpace",node->spaces[0]);
|
||||
store(node->child);
|
||||
close("Transform");
|
||||
}
|
||||
else
|
||||
{
|
||||
open("TransformAnimation",id);
|
||||
for (size_t i=0; i<node->spaces.size(); i++)
|
||||
store("AffineSpace",node->spaces[i]);
|
||||
store(node->child);
|
||||
close("TransformAnimation");
|
||||
}
|
||||
}
|
||||
|
||||
void XMLWriter::store(std::vector<Ref<SceneGraph::TransformNode>> nodes)
|
||||
{
|
||||
if (nodes.size() == 0)
|
||||
return;
|
||||
|
||||
if (nodes.size() == 1) {
|
||||
store(nodes[0].dynamicCast<SceneGraph::Node>());
|
||||
return;
|
||||
}
|
||||
|
||||
open("MultiTransform");
|
||||
std::streampos offset = bin.tellg();
|
||||
tab(); xml << "<AffineSpace3f ofs=\"" << offset << "\" size=\"" << nodes.size() << "\"/>" << std::endl;
|
||||
for (size_t i=0; i<nodes.size(); i++) {
|
||||
assert(nodes[i]->spaces.size() == 1);
|
||||
assert(nodes[i]->child == nodes[0]->child);
|
||||
bin.write((char*)&nodes[i]->spaces[0].l.vx,sizeof(Vec3f));
|
||||
bin.write((char*)&nodes[i]->spaces[0].l.vy,sizeof(Vec3f));
|
||||
bin.write((char*)&nodes[i]->spaces[0].l.vz,sizeof(Vec3f));
|
||||
bin.write((char*)&nodes[i]->spaces[0].p,sizeof(Vec3f));
|
||||
}
|
||||
store(nodes[0]->child);
|
||||
close("MultiTransform");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<SceneGraph::GroupNode> group, ssize_t id)
|
||||
{
|
||||
open("Group",id);
|
||||
|
||||
std::map<Ref<SceneGraph::Node>,std::vector<Ref<SceneGraph::TransformNode>>> object_to_transform_map;
|
||||
for (size_t i=0; i<group->children.size(); i++)
|
||||
{
|
||||
/* compress transformation of the same object into MultiTransform nodes if possible */
|
||||
if (Ref<SceneGraph::TransformNode> xfmNode = group->children[i].dynamicCast<SceneGraph::TransformNode>())
|
||||
{
|
||||
/* we can only compress non-animated transform nodes and only ones that are referenced once */
|
||||
if (xfmNode->spaces.size() == 1 && xfmNode->indegree == 1)
|
||||
{
|
||||
Ref<SceneGraph::Node> child = xfmNode->child;
|
||||
if (object_to_transform_map.find(child) == object_to_transform_map.end()) {
|
||||
object_to_transform_map[child] = std::vector<Ref<SceneGraph::TransformNode>>();
|
||||
}
|
||||
object_to_transform_map[child].push_back(xfmNode);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
store(group->children[i]);
|
||||
}
|
||||
|
||||
/* store all compressed transform nodes */
|
||||
for (auto& i : object_to_transform_map)
|
||||
store(i.second);
|
||||
|
||||
close("Group");
|
||||
}
|
||||
|
||||
void XMLWriter::store(Ref<SceneGraph::Node> node)
|
||||
{
|
||||
if (nodeMap.find(node) != nodeMap.end()) {
|
||||
tab(); xml << "<ref id=\"" << nodeMap[node] << "\"/>" << std::endl; return;
|
||||
}
|
||||
|
||||
const ssize_t id = nodeMap[node] = currentNodeID++;
|
||||
if (node->fileName != "") {
|
||||
tab(); xml << "<extern id=\"" << id << "\" src=\"" << node->fileName << "\"/>" << std::endl; return;
|
||||
}
|
||||
|
||||
if (Ref<SceneGraph::AnimatedLightNode> cnode = node.dynamicCast<SceneGraph::AnimatedLightNode>()) store(cnode,id);
|
||||
else if (Ref<SceneGraph::LightNode> cnode = node.dynamicCast<SceneGraph::LightNode>()) store(cnode,id);
|
||||
//else if (Ref<SceneGraph::MaterialNode> cnode = node.dynamicCast<SceneGraph::MaterialNode>()) store(cnode,id);
|
||||
else if (Ref<SceneGraph::TriangleMeshNode> cnode = node.dynamicCast<SceneGraph::TriangleMeshNode>()) store(cnode,id);
|
||||
else if (Ref<SceneGraph::QuadMeshNode> cnode = node.dynamicCast<SceneGraph::QuadMeshNode>()) store(cnode,id);
|
||||
else if (Ref<SceneGraph::SubdivMeshNode> cnode = node.dynamicCast<SceneGraph::SubdivMeshNode>()) store(cnode,id);
|
||||
else if (Ref<SceneGraph::HairSetNode> cnode = node.dynamicCast<SceneGraph::HairSetNode>()) store(cnode,id);
|
||||
else if (Ref<SceneGraph::AnimatedPerspectiveCameraNode> cnode = node.dynamicCast<SceneGraph::AnimatedPerspectiveCameraNode>()) store(cnode,id);
|
||||
else if (Ref<SceneGraph::PerspectiveCameraNode> cnode = node.dynamicCast<SceneGraph::PerspectiveCameraNode>()) store(cnode,id);
|
||||
else if (Ref<SceneGraph::TransformNode> cnode = node.dynamicCast<SceneGraph::TransformNode>()) store(cnode,id);
|
||||
else if (Ref<SceneGraph::GroupNode> cnode = node.dynamicCast<SceneGraph::GroupNode>()) store(cnode,id);
|
||||
else throw std::runtime_error("unknown node type");
|
||||
}
|
||||
|
||||
XMLWriter::XMLWriter(Ref<SceneGraph::Node> root, const FileName& fileName, bool embedTextures, bool referenceMaterials, bool binaryFormat)
|
||||
: ident(0), currentNodeID(0), embedTextures(embedTextures), referenceMaterials(referenceMaterials), binaryFormat(binaryFormat)
|
||||
{
|
||||
xml.exceptions (std::fstream::failbit | std::fstream::badbit);
|
||||
xml.open (fileName, std::fstream::out);
|
||||
|
||||
if (binaryFormat)
|
||||
{
|
||||
const FileName binFileName = fileName.addExt(".bin");
|
||||
bin.exceptions (std::fstream::failbit | std::fstream::badbit);
|
||||
bin.open (binFileName, std::fstream::out | std::fstream::binary);
|
||||
}
|
||||
|
||||
xml << "<?xml version=\"1.0\"?>" << std::endl;
|
||||
root->calculateInDegree();
|
||||
open("scene");
|
||||
store(root);
|
||||
close("scene");
|
||||
root->resetInDegree();
|
||||
}
|
||||
|
||||
void SceneGraph::storeXML(Ref<SceneGraph::Node> root, const FileName& fileName, bool embedTextures, bool referenceMaterials, bool binaryFormat) {
|
||||
XMLWriter(root,fileName,embedTextures,referenceMaterials,binaryFormat);
|
||||
}
|
||||
}
|
||||
15
Framework/external/embree/tutorials/common/scenegraph/xml_writer.h
vendored
Normal file
15
Framework/external/embree/tutorials/common/scenegraph/xml_writer.h
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright 2009-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "scenegraph.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace SceneGraph
|
||||
{
|
||||
void storeXML(Ref<SceneGraph::Node> root, const FileName& fileName, bool embedTextures, bool referenceMaterials, bool binaryFormat);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue