Add Chromium-only Blender WebEngine parity work
This commit is contained in:
220
blender-5.2.0/extern/opensubdiv-source/examples/common/CMakeLists.txt
vendored
Normal file
220
blender-5.2.0/extern/opensubdiv-source/examples/common/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,220 @@
|
||||
#
|
||||
# Copyright 2013 Pixar
|
||||
#
|
||||
# Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
# https://opensubdiv.org/license.
|
||||
#
|
||||
|
||||
set(EXAMPLES_COMMON_SOURCE_FILES
|
||||
font_image.cpp
|
||||
hdr_reader.cpp
|
||||
hud.cpp
|
||||
objAnim.cpp
|
||||
patchColors.cpp
|
||||
viewerArgsUtils.cpp
|
||||
)
|
||||
|
||||
set(EXAMPLES_COMMON_HEADER_FILES
|
||||
font_image.h
|
||||
hdr_reader.h
|
||||
hud.h
|
||||
objAnim.h
|
||||
patchColors.h
|
||||
shaderCache.h
|
||||
simple_math.h
|
||||
stb_image_write.h
|
||||
stopwatch.h
|
||||
viewerArgsUtils.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
"${OPENSUBDIV_INCLUDE_DIR}"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||
)
|
||||
|
||||
if(OPENCL_FOUND)
|
||||
include_directories("${OPENCL_INCLUDE_DIRS}")
|
||||
|
||||
list(APPEND EXAMPLES_COMMON_SOURCE_FILES
|
||||
clDeviceContext.cpp
|
||||
)
|
||||
list(APPEND EXAMPLES_COMMON_HEADER_FILES
|
||||
clDeviceContext.h
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CUDA_FOUND)
|
||||
include_directories("${CUDA_INCLUDE_DIRS}")
|
||||
|
||||
list(APPEND EXAMPLES_COMMON_SOURCE_FILES
|
||||
cudaDeviceContext.cpp
|
||||
)
|
||||
list(APPEND EXAMPLES_COMMON_HEADER_FILES
|
||||
cudaDeviceContext.h
|
||||
)
|
||||
endif()
|
||||
|
||||
if(DEFINED OPENGL_LOADER_INCLUDE_DIRS)
|
||||
include_directories(${OPENGL_LOADER_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
if(OPENGL_FOUND AND GLFW_FOUND)
|
||||
|
||||
list(APPEND EXAMPLES_COMMON_GL_SOURCE_FILES
|
||||
glControlMeshDisplay.cpp
|
||||
glHud.cpp
|
||||
glUtils.cpp
|
||||
glShaderCache.cpp
|
||||
)
|
||||
|
||||
list(APPEND EXAMPLES_COMMON_GL_HEADER_FILES
|
||||
glControlMeshDisplay.h
|
||||
glHud.h
|
||||
glUtils.h
|
||||
glShaderCache.h
|
||||
)
|
||||
|
||||
if (GLFW_FOUND)
|
||||
include_directories("${GLFW_INCLUDE_DIR}")
|
||||
endif()
|
||||
|
||||
add_library(examples_common_gl_obj
|
||||
OBJECT
|
||||
${EXAMPLES_COMMON_SOURCE_FILES}
|
||||
${EXAMPLES_COMMON_HEADER_FILES}
|
||||
${EXAMPLES_COMMON_GL_SOURCE_FILES}
|
||||
${EXAMPLES_COMMON_GL_HEADER_FILES}
|
||||
)
|
||||
|
||||
set_target_properties(examples_common_gl_obj
|
||||
PROPERTIES
|
||||
FOLDER "examples"
|
||||
)
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
if(DXSDK_FOUND)
|
||||
|
||||
list(APPEND EXAMPLES_COMMON_DX11_SOURCE_FILES
|
||||
d3d11ControlMeshDisplay.cpp
|
||||
d3d11Hud.cpp
|
||||
d3d11Utils.cpp
|
||||
d3d11ShaderCache.cpp
|
||||
)
|
||||
|
||||
list(APPEND EXAMPLES_COMMON_DX11_HEADER_FILES
|
||||
d3d11ControlMeshDisplay.h
|
||||
d3d11Hud.h
|
||||
d3d11Utils.h
|
||||
d3d11ShaderCache.h
|
||||
)
|
||||
|
||||
include_directories("${DXSDK_INCLUDE_DIR}")
|
||||
|
||||
add_library(examples_common_dx11_obj
|
||||
OBJECT
|
||||
${EXAMPLES_COMMON_SOURCE_FILES}
|
||||
${EXAMPLES_COMMON_HEADER_FILES}
|
||||
${EXAMPLES_COMMON_DX11_SOURCE_FILES}
|
||||
${EXAMPLES_COMMON_DX11_HEADER_FILES}
|
||||
)
|
||||
|
||||
set_target_properties(examples_common_dx11_obj
|
||||
PROPERTIES
|
||||
FOLDER "examples"
|
||||
)
|
||||
|
||||
endif()
|
||||
|
||||
if(METAL_FOUND)
|
||||
include_directories("${METAL_INCLUDE_DIR}")
|
||||
list(APPEND EXAMPLES_COMMON_MTL_SOURCE_FILES
|
||||
mtlControlMeshDisplay.mm
|
||||
mtlUtils.mm
|
||||
mtlHud.mm
|
||||
)
|
||||
list(APPEND EXAMPLES_COMMON_MTL_HEADER_FILES
|
||||
mtlControlMeshDisplay.h
|
||||
mtlUtils.h
|
||||
mtlHud.h
|
||||
)
|
||||
|
||||
add_library(examples_common_mtl_obj
|
||||
OBJECT
|
||||
${EXAMPLES_COMMON_SOURCE_FILES}
|
||||
${EXAMPLES_COMMON_HEADER_FILES}
|
||||
${EXAMPLES_COMMON_MTL_SOURCE_FILES}
|
||||
${EXAMPLES_COMMON_MTL_HEADER_FILES}
|
||||
)
|
||||
|
||||
set_target_properties(examples_common_mtl_obj
|
||||
PROPERTIES
|
||||
FOLDER "examples"
|
||||
)
|
||||
|
||||
endif()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
if( PTEX_FOUND )
|
||||
list(APPEND EXAMPLES_COMMON_PTEX_HEADER_FILES
|
||||
ptexMipmapTextureLoader.h
|
||||
)
|
||||
list(APPEND EXAMPLES_COMMON_PTEX_SOURCE_FILES
|
||||
ptexMipmapTextureLoader.cpp
|
||||
)
|
||||
if( OPENGL_FOUND )
|
||||
list(APPEND EXAMPLES_COMMON_PTEX_SOURCE_FILES
|
||||
glPtexMipmapTexture.cpp
|
||||
)
|
||||
list(APPEND EXAMPLES_COMMON_PTEX_HEADER_FILES
|
||||
glPtexMipmapTexture.h
|
||||
)
|
||||
endif()
|
||||
if( DXSDK_FOUND )
|
||||
list(APPEND EXAMPLES_COMMON_PTEX_SOURCE_FILES
|
||||
d3d11PtexMipmapTexture.cpp
|
||||
)
|
||||
list(APPEND EXAMPLES_COMMON_PTEX_HEADER_FILES
|
||||
d3d11PtexMipmapTexture.h
|
||||
)
|
||||
endif()
|
||||
if( METAL_FOUND )
|
||||
list(APPEND EXAMPLES_COMMON_PTEX_SOURCE_FILES
|
||||
mtlPtexMipmapTexture.mm
|
||||
)
|
||||
list(APPEND EXAMPLES_COMMON_PTEX_HEADER_FILES
|
||||
mtlPtexMipmapTexture.h
|
||||
)
|
||||
endif()
|
||||
|
||||
set(EXAMPLES_COMMON_PTEX_SHADER_FILES
|
||||
glslPtexCommon.glsl
|
||||
hlslPtexCommon.hlsl
|
||||
mtlPtexCommon.metal
|
||||
)
|
||||
|
||||
set(EXAMPLES_COMMON_PTEX_INC_FILES )
|
||||
if(EXAMPLES_COMMON_PTEX_SHADER_FILES)
|
||||
osd_stringify("${EXAMPLES_COMMON_PTEX_SHADER_FILES}"
|
||||
EXAMPLES_COMMON_PTEX_INC_FILES)
|
||||
|
||||
source_group("Shaders" FILES ${EXAMPLES_COMMON_PTEX_SHADER_FILES})
|
||||
source_group("Inc" FILES ${EXAMPLES_COMMON_PTEX_INC_FILES})
|
||||
endif()
|
||||
|
||||
include_directories( "${PTEX_INCLUDE_DIR}" )
|
||||
|
||||
add_library(examples_common_ptex_obj
|
||||
OBJECT
|
||||
${EXAMPLES_COMMON_PTEX_SOURCE_FILES}
|
||||
${EXAMPLES_COMMON_PTEX_HEADER_FILES}
|
||||
${EXAMPLES_COMMON_PTEX_INC_FILES}
|
||||
)
|
||||
|
||||
set_target_properties(examples_common_ptex_obj
|
||||
PROPERTIES
|
||||
FOLDER "examples"
|
||||
)
|
||||
|
||||
endif()
|
||||
348
blender-5.2.0/extern/opensubdiv-source/examples/common/clDeviceContext.cpp
vendored
Normal file
348
blender-5.2.0/extern/opensubdiv-source/examples/common/clDeviceContext.cpp
vendored
Normal file
@@ -0,0 +1,348 @@
|
||||
//
|
||||
// Copyright 2015 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#define CL_USE_DEPRECATED_OPENCL_2_0_APIS
|
||||
|
||||
#include "clDeviceContext.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#elif defined(__APPLE__)
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#include <OpenGL/CGLCurrent.h>
|
||||
#else
|
||||
#include <GL/glx.h>
|
||||
#endif
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#if defined(OPENSUBDIV_HAS_DX11SDK)
|
||||
#include <D3D11.h>
|
||||
|
||||
#if defined(OPENSUBDIV_HAS_CL_D3D11_H)
|
||||
#include <CL/cl_d3d11.h>
|
||||
#elif defined(OPENSUBDIV_HAS_CL_D3D11_EXT_H)
|
||||
#include <CL/cl_d3d11_ext.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define message(...) // fprintf(stderr, __VA_ARGS__)
|
||||
#define error(...) fprintf(stderr, __VA_ARGS__)
|
||||
|
||||
// returns the first found platform.
|
||||
//
|
||||
static cl_platform_id
|
||||
findPlatform() {
|
||||
cl_uint numPlatforms;
|
||||
cl_int ciErrNum = clGetPlatformIDs(0, NULL, &numPlatforms);
|
||||
|
||||
if (ciErrNum != CL_SUCCESS) {
|
||||
error("Error %d in clGetPlatformIDs call.\n", ciErrNum);
|
||||
return NULL;
|
||||
}
|
||||
if (numPlatforms == 0) {
|
||||
error("No OpenCL platform found.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cl_platform_id *clPlatformIDs = new cl_platform_id[numPlatforms];
|
||||
ciErrNum = clGetPlatformIDs(numPlatforms, clPlatformIDs, NULL);
|
||||
char chBuffer[1024];
|
||||
for (cl_uint i = 0; i < numPlatforms; ++i) {
|
||||
ciErrNum = clGetPlatformInfo(clPlatformIDs[i], CL_PLATFORM_NAME,
|
||||
1024, chBuffer,NULL);
|
||||
if (ciErrNum == CL_SUCCESS) {
|
||||
cl_platform_id platformId = clPlatformIDs[i];
|
||||
delete[] clPlatformIDs;
|
||||
return platformId;
|
||||
}
|
||||
}
|
||||
delete[] clPlatformIDs;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// returns the device in clDevices which supports the extension.
|
||||
//
|
||||
static int
|
||||
findExtensionSupportedDevice(cl_device_id *clDevices,
|
||||
int numDevices,
|
||||
const char *extensionName) {
|
||||
// find a device that supports sharing with GL/D3D11
|
||||
// (SLI / X-fire configurations)
|
||||
cl_int ciErrNum;
|
||||
|
||||
for (int i = 0; i < numDevices; ++i) {
|
||||
// get extensions string size
|
||||
size_t extensionSize;
|
||||
ciErrNum = clGetDeviceInfo(clDevices[i],
|
||||
CL_DEVICE_EXTENSIONS, 0, NULL,
|
||||
&extensionSize );
|
||||
|
||||
if (ciErrNum != CL_SUCCESS) {
|
||||
error("Error %d in clGetDeviceInfo\n", ciErrNum);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (extensionSize>0) {
|
||||
// get extensions string
|
||||
char *extensions = new char[extensionSize];
|
||||
ciErrNum = clGetDeviceInfo(clDevices[i], CL_DEVICE_EXTENSIONS,
|
||||
extensionSize, extensions,
|
||||
&extensionSize);
|
||||
if (ciErrNum != CL_SUCCESS) {
|
||||
error("Error %d in clGetDeviceInfo\n", ciErrNum);
|
||||
delete[] extensions;
|
||||
continue;
|
||||
}
|
||||
std::string extString(extensions);
|
||||
delete[] extensions;
|
||||
|
||||
// parse string. This is a bit deficient since the extensions
|
||||
// string is space separated.
|
||||
//
|
||||
// The actual string would be "cl_khr_d3d11_sharing"
|
||||
// or "cl_nv_d3d11_sharing"
|
||||
if (extString.find(extensionName) != std::string::npos) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
CLDeviceContext::CLDeviceContext() :
|
||||
_clContext(NULL), _clCommandQueue(NULL) {
|
||||
}
|
||||
|
||||
CLDeviceContext::~CLDeviceContext() {
|
||||
|
||||
if (_clCommandQueue)
|
||||
clReleaseCommandQueue(_clCommandQueue);
|
||||
if (_clContext)
|
||||
clReleaseContext(_clContext);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
bool
|
||||
CLDeviceContext::HAS_CL_VERSION_1_1 () {
|
||||
|
||||
#ifdef OPENSUBDIV_HAS_CLEW
|
||||
static bool clewInitialized = false;
|
||||
static bool clewLoadSuccess;
|
||||
if (!clewInitialized) {
|
||||
clewInitialized = true;
|
||||
clewLoadSuccess = clewInit() == CLEW_SUCCESS;
|
||||
if (!clewLoadSuccess) {
|
||||
error("Loading OpenCL failed.\n");
|
||||
}
|
||||
}
|
||||
return clewLoadSuccess;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CLDeviceContext::Initialize() {
|
||||
|
||||
#ifdef OPENSUBDIV_HAS_CLEW
|
||||
if (!clGetPlatformIDs) {
|
||||
error("Error clGetPlatformIDs function not bound.\n");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
cl_int ciErrNum;
|
||||
cl_platform_id cpPlatform = findPlatform();
|
||||
|
||||
#if defined(_WIN32)
|
||||
cl_context_properties props[] = {
|
||||
CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(),
|
||||
CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(),
|
||||
CL_CONTEXT_PLATFORM, (cl_context_properties)cpPlatform,
|
||||
0
|
||||
};
|
||||
#elif defined(__APPLE__)
|
||||
CGLContextObj kCGLContext = CGLGetCurrentContext();
|
||||
CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext);
|
||||
cl_context_properties props[] = {
|
||||
CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)kCGLShareGroup,
|
||||
0
|
||||
};
|
||||
#else
|
||||
cl_context_properties props[] = {
|
||||
CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(),
|
||||
CL_GLX_DISPLAY_KHR, (cl_context_properties)glXGetCurrentDisplay(),
|
||||
CL_CONTEXT_PLATFORM, (cl_context_properties)cpPlatform,
|
||||
0
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
_clContext = clCreateContext(props, 0, NULL, clLogMessagesToStdoutAPPLE,
|
||||
NULL, &ciErrNum);
|
||||
if (ciErrNum != CL_SUCCESS) {
|
||||
error("Error %d in clCreateContext\n", ciErrNum);
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t devicesSize = 0;
|
||||
clGetGLContextInfoAPPLE(_clContext, kCGLContext,
|
||||
CL_CGL_DEVICES_FOR_SUPPORTED_VIRTUAL_SCREENS_APPLE,
|
||||
0, NULL, &devicesSize);
|
||||
int numDevices = int(devicesSize / sizeof(cl_device_id));
|
||||
if (numDevices == 0) {
|
||||
error("No sharable devices.\n");
|
||||
return false;
|
||||
}
|
||||
cl_device_id *clDevices = new cl_device_id[numDevices];
|
||||
clGetGLContextInfoAPPLE(_clContext, kCGLContext,
|
||||
CL_CGL_DEVICES_FOR_SUPPORTED_VIRTUAL_SCREENS_APPLE,
|
||||
numDevices * sizeof(cl_device_id), clDevices, NULL);
|
||||
int clDeviceUsed = 0;
|
||||
|
||||
if (ciErrNum != CL_SUCCESS) {
|
||||
error("Error %d in clCreateContext\n", ciErrNum);
|
||||
delete[] clDevices;
|
||||
return false;
|
||||
}
|
||||
|
||||
_clCommandQueue = clCreateCommandQueue(
|
||||
_clContext, clDevices[clDeviceUsed], 0, &ciErrNum);
|
||||
delete[] clDevices;
|
||||
if (ciErrNum != CL_SUCCESS) {
|
||||
error("Error %d in clCreateCommandQueue\n", ciErrNum);
|
||||
return false;
|
||||
}
|
||||
#else // not __APPLE__
|
||||
|
||||
// get the number of GPU devices available to the platform
|
||||
cl_uint numDevices = 0;
|
||||
clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU, 0, NULL, &numDevices);
|
||||
if (numDevices == 0) {
|
||||
error("No CL GPU device found.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// create the device list
|
||||
cl_device_id *clDevices = new cl_device_id[numDevices];
|
||||
clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU, numDevices, clDevices, NULL);
|
||||
|
||||
const char *extension = "cl_khr_gl_sharing";
|
||||
int clDeviceUsed = findExtensionSupportedDevice(clDevices, numDevices,
|
||||
extension);
|
||||
|
||||
if (clDeviceUsed < 0) {
|
||||
error("No device found that supports CL/GL context sharing\n");
|
||||
delete[] clDevices;
|
||||
return false;
|
||||
}
|
||||
|
||||
_clContext = clCreateContext(props, 1, &clDevices[clDeviceUsed],
|
||||
NULL, NULL, &ciErrNum);
|
||||
|
||||
if (ciErrNum != CL_SUCCESS) {
|
||||
error("Error %d in clCreateContext\n", ciErrNum);
|
||||
delete[] clDevices;
|
||||
return false;
|
||||
}
|
||||
|
||||
_clCommandQueue = clCreateCommandQueueWithProperties(
|
||||
_clContext, clDevices[clDeviceUsed], NULL, &ciErrNum);
|
||||
delete[] clDevices;
|
||||
if (ciErrNum != CL_SUCCESS) {
|
||||
error("Error %d in clCreateCommandQueueWithProperties\n", ciErrNum);
|
||||
return false;
|
||||
}
|
||||
#endif // not __APPLE__
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
bool
|
||||
CLD3D11DeviceContext::Initialize(ID3D11DeviceContext *d3dDeviceContext) {
|
||||
|
||||
#if defined(OPENSUBDIV_HAS_DX11SDK) && \
|
||||
(defined(OPENSUBDIV_HAS_CL_D3D11_H) || defined(OPENSUBDIV_HAS_CL_D3D11_EXT_H))
|
||||
|
||||
_d3dDeviceContext = d3dDeviceContext;
|
||||
|
||||
cl_int ciErrNum;
|
||||
cl_platform_id cpPlatform = findPlatform();
|
||||
|
||||
ID3D11Device *device;
|
||||
d3dDeviceContext->GetDevice(&device);
|
||||
|
||||
#if defined(OPENSUBDIV_HAS_CL_D3D11_H)
|
||||
cl_context_properties props[] = {
|
||||
CL_CONTEXT_D3D11_DEVICE_KHR, (cl_context_properties)device,
|
||||
CL_CONTEXT_PLATFORM, (cl_context_properties)cpPlatform,
|
||||
0
|
||||
};
|
||||
#elif defined(OPENSUBDIV_HAS_CL_D3D11_EXT_H)
|
||||
cl_context_properties props[] = {
|
||||
CL_CONTEXT_D3D11_DEVICE_NV, (cl_context_properties)device,
|
||||
CL_CONTEXT_PLATFORM, (cl_context_properties)cpPlatform,
|
||||
0
|
||||
};
|
||||
#endif
|
||||
|
||||
// get the number of GPU devices available to the platform
|
||||
cl_uint numDevices = 0;
|
||||
clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU, 0, NULL, &numDevices);
|
||||
if (numDevices == 0) {
|
||||
error("No CL GPU device found.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// create the device list
|
||||
cl_device_id *clDevices = new cl_device_id[numDevices];
|
||||
clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU, numDevices, clDevices, NULL);
|
||||
|
||||
// we're cheating a little bit.
|
||||
// try to find both cl_khr_d3d11_sharing and cl_nv_d3d11_sharing.
|
||||
const char *extension = "_d3d11_sharing";
|
||||
int clDeviceUsed = findExtensionSupportedDevice(clDevices, numDevices,
|
||||
extension);
|
||||
|
||||
if (clDeviceUsed < 0) {
|
||||
error("No device found that supports CL/D3D11 context sharing\n");
|
||||
delete[] clDevices;
|
||||
return false;
|
||||
}
|
||||
|
||||
_clContext = clCreateContext(props, 1, &clDevices[clDeviceUsed],
|
||||
NULL, NULL, &ciErrNum);
|
||||
if (ciErrNum != CL_SUCCESS) {
|
||||
error("Error %d in clCreateContext\n", ciErrNum);
|
||||
delete[] clDevices;
|
||||
return false;
|
||||
}
|
||||
|
||||
_clCommandQueue = clCreateCommandQueueWithProperties(
|
||||
_clContext, clDevices[clDeviceUsed], NULL, &ciErrNum);
|
||||
delete[] clDevices;
|
||||
if (ciErrNum != CL_SUCCESS) {
|
||||
error("Error %d in clCreateCommandQueueWithProperties\n", ciErrNum);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
(void)d3dDeviceContext; // unused
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
53
blender-5.2.0/extern/opensubdiv-source/examples/common/clDeviceContext.h
vendored
Normal file
53
blender-5.2.0/extern/opensubdiv-source/examples/common/clDeviceContext.h
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// Copyright 2015 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef OSD_EXAMPLES_COMMON_CL_DEVICE_CONTEXT_H
|
||||
#define OSD_EXAMPLES_COMMON_CL_DEVICE_CONTEXT_H
|
||||
|
||||
#include <opensubdiv/osd/opencl.h>
|
||||
|
||||
class CLDeviceContext {
|
||||
public:
|
||||
CLDeviceContext();
|
||||
~CLDeviceContext();
|
||||
|
||||
static bool HAS_CL_VERSION_1_1 ();
|
||||
|
||||
bool Initialize();
|
||||
|
||||
bool IsInitialized() const {
|
||||
return (_clContext != NULL);
|
||||
}
|
||||
|
||||
cl_context GetContext() const {
|
||||
return _clContext;
|
||||
}
|
||||
cl_command_queue GetCommandQueue() const {
|
||||
return _clCommandQueue;
|
||||
}
|
||||
|
||||
protected:
|
||||
cl_context _clContext;
|
||||
cl_command_queue _clCommandQueue;
|
||||
};
|
||||
|
||||
struct ID3D11DeviceContext;
|
||||
|
||||
class CLD3D11DeviceContext : public CLDeviceContext {
|
||||
public:
|
||||
bool Initialize(ID3D11DeviceContext *deviceContext);
|
||||
|
||||
ID3D11DeviceContext *GetDeviceContext() const {
|
||||
return _d3dDeviceContext;
|
||||
}
|
||||
|
||||
private:
|
||||
ID3D11DeviceContext *_d3dDeviceContext;
|
||||
};
|
||||
|
||||
|
||||
#endif // OSD_EXAMPLES_COMMON_CL_DEVICE_CONTEXT_H
|
||||
137
blender-5.2.0/extern/opensubdiv-source/examples/common/cudaDeviceContext.cpp
vendored
Normal file
137
blender-5.2.0/extern/opensubdiv-source/examples/common/cudaDeviceContext.cpp
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
//
|
||||
// Copyright 2015 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#include "cudaDeviceContext.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#elif defined(__APPLE__)
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#else
|
||||
#include <X11/Xlib.h>
|
||||
#include <GL/glx.h>
|
||||
#endif
|
||||
|
||||
#include <cstdio>
|
||||
#include <cuda.h>
|
||||
#include <cuda_runtime_api.h>
|
||||
#include <cuda_gl_interop.h>
|
||||
|
||||
#if defined(OPENSUBDIV_HAS_DX11SDK)
|
||||
#include <cuda_d3d11_interop.h>
|
||||
#endif
|
||||
|
||||
#define message(fmt, ...)
|
||||
//#define message(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
|
||||
#define error(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
#if CUDA_VERSION < 5000
|
||||
static int _GetCudaDeviceForCurrentGLContext()
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
|
||||
return 0;
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
return 0;
|
||||
|
||||
#else // X11
|
||||
// If we don't have a current GL context, then choose the device which
|
||||
// matches the current X11 screen number.
|
||||
Display * display = glXGetCurrentDisplay();
|
||||
if (!display) {
|
||||
display = XOpenDisplay(NULL);
|
||||
if (display) {
|
||||
int screen = DefaultScreen(display);
|
||||
XCloseDisplay(display);
|
||||
message("CUDA init using device for default screen: %d\n", screen);
|
||||
return screen;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We can't use the new interop API, so use the device
|
||||
// corresponding to the screen number of the current GL context.
|
||||
int screen = DefaultScreen(display);
|
||||
message("CUDA init using device for screen: %d\n", screen);
|
||||
return screen;
|
||||
#endif // X11
|
||||
}
|
||||
|
||||
#else // CUDA_VERSION >= 50000 -----------------------------------------
|
||||
static int _GetCudaDeviceForCurrentGLContext()
|
||||
{
|
||||
// Find and use the CUDA device for the current GL context
|
||||
unsigned int interopDeviceCount = 0;
|
||||
int interopDevices[1];
|
||||
cudaError_t status = cudaGLGetDevices(&interopDeviceCount, interopDevices,
|
||||
1, cudaGLDeviceListCurrentFrame);
|
||||
if (status == cudaErrorNoDevice || interopDeviceCount != 1) {
|
||||
message("CUDA no interop devices found.\n");
|
||||
return 0;
|
||||
}
|
||||
int device = interopDevices[0];
|
||||
|
||||
#if defined(_WIN32)
|
||||
return device;
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
return device;
|
||||
|
||||
#else // X11
|
||||
Display * display = glXGetCurrentDisplay();
|
||||
int screen = DefaultScreen(display);
|
||||
if (device != screen) {
|
||||
error("The CUDA interop device (%d) does not match "
|
||||
"the screen used by the current GL context (%d), "
|
||||
"which may cause slow performance on systems "
|
||||
"with multiple GPU devices.", device, screen);
|
||||
}
|
||||
message("CUDA init using device for current GL context: %d\n", device);
|
||||
return device;
|
||||
#endif
|
||||
}
|
||||
#endif // CUDA_VERSION -----------------------------------------------
|
||||
|
||||
CudaDeviceContext::CudaDeviceContext() :
|
||||
_initialized(false) {
|
||||
}
|
||||
|
||||
CudaDeviceContext::~CudaDeviceContext() {
|
||||
cudaDeviceReset();
|
||||
}
|
||||
|
||||
bool
|
||||
CudaDeviceContext::Initialize() {
|
||||
|
||||
// see if any cuda device is available.
|
||||
int deviceCount = 0;
|
||||
cudaGetDeviceCount(&deviceCount);
|
||||
message("CUDA device count: %d\n", deviceCount);
|
||||
if (deviceCount <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cudaGLSetGLDevice(_GetCudaDeviceForCurrentGLContext());
|
||||
_initialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CudaDeviceContext::Initialize(ID3D11Device *device) {
|
||||
|
||||
#if defined(OPENSUBDIV_HAS_DX11SDK)
|
||||
cudaD3D11SetDirect3DDevice(device);
|
||||
return true;
|
||||
#else
|
||||
(void)device; // unused
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
33
blender-5.2.0/extern/opensubdiv-source/examples/common/cudaDeviceContext.h
vendored
Normal file
33
blender-5.2.0/extern/opensubdiv-source/examples/common/cudaDeviceContext.h
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef OSD_EXAMPLES_COMMON_CUDA_DEVICE_CONTEXT_H
|
||||
#define OSD_EXAMPLES_COMMON_CUDA_DEVICE_CONTEXT_H
|
||||
|
||||
struct ID3D11Device;
|
||||
|
||||
class CudaDeviceContext {
|
||||
public:
|
||||
CudaDeviceContext();
|
||||
~CudaDeviceContext();
|
||||
|
||||
/// Initialize cuda device from the current GL context
|
||||
bool Initialize();
|
||||
|
||||
/// Initialize cuda device from the ID3D11Device
|
||||
bool Initialize(ID3D11Device *device);
|
||||
|
||||
/// Returns true if the cuda device has already been initialized
|
||||
bool IsInitialized() const {
|
||||
return _initialized;
|
||||
}
|
||||
|
||||
private:
|
||||
bool _initialized;
|
||||
};
|
||||
|
||||
#endif // OSD_EXAMPLES_COMMON_CUDA_DEVICE_CONTEXT_H
|
||||
251
blender-5.2.0/extern/opensubdiv-source/examples/common/d3d11ControlMeshDisplay.cpp
vendored
Normal file
251
blender-5.2.0/extern/opensubdiv-source/examples/common/d3d11ControlMeshDisplay.cpp
vendored
Normal file
@@ -0,0 +1,251 @@
|
||||
//
|
||||
// Copyright 2015 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#include "d3d11ControlMeshDisplay.h"
|
||||
#include "../common/d3d11Utils.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
|
||||
|
||||
static const char *s_VS =
|
||||
"cbuffer cbPerFrame : register( b0 ) { matrix g_mViewProjection; }; \n"
|
||||
"struct vertexIn { float3 pos : POSITION0; float sharpness : COLOR0; }; \n"
|
||||
"struct vertexOut { float4 pos : SV_POSITION; float sharpness : COLOR0; }; \n"
|
||||
"vertexOut vs_main(vertexIn IN) { \n"
|
||||
" vertexOut vout; \n"
|
||||
" vout.pos = mul(g_mViewProjection, float4(IN.pos, 1)); \n"
|
||||
" vout.sharpness = IN.sharpness; \n"
|
||||
" return vout; \n"
|
||||
"} \n";
|
||||
|
||||
static const char *s_PS =
|
||||
"struct pixelIn { float4 pos : SV_POSITION; float sharpness : COLOR0; }; \n"
|
||||
"Buffer<float> edgeSharpness : register(t0); \n"
|
||||
"float4 sharpnessToColor(float s) { \n"
|
||||
" // 0.0 2.0 4.0 \n"
|
||||
" // green --- yellow --- red \n"
|
||||
" return float4(min(1, s * 0.5), \n"
|
||||
" min(1, 2 - s * 0.5), \n"
|
||||
" 0, 1); \n"
|
||||
"} \n"
|
||||
"float4 ps_main(pixelIn IN, uint primitiveID : SV_PrimitiveID) \n"
|
||||
" : SV_Target { \n"
|
||||
" float sharpness = edgeSharpness[primitiveID]; \n"
|
||||
" return sharpnessToColor(sharpness); \n"
|
||||
"} \n";
|
||||
|
||||
namespace {
|
||||
struct CB_CONTROL_MESH_DISPLAY
|
||||
{
|
||||
float mViewProjection[16];
|
||||
};
|
||||
};
|
||||
|
||||
D3D11ControlMeshDisplay::D3D11ControlMeshDisplay(
|
||||
ID3D11DeviceContext *deviceContext) :
|
||||
_displayEdges(true), _displayVertices(false),
|
||||
_deviceContext(deviceContext), _inputLayout(0), _vertexShader(0),
|
||||
_pixelShader(0), _rasterizerState(0), _constantBuffer(0),
|
||||
_edgeSharpnessSRV(0), _edgeSharpness(0), _edgeIndices(0),
|
||||
_numEdges(0), _numPoints(0) {
|
||||
}
|
||||
|
||||
D3D11ControlMeshDisplay::~D3D11ControlMeshDisplay() {
|
||||
SAFE_RELEASE(_inputLayout);
|
||||
SAFE_RELEASE(_vertexShader);
|
||||
SAFE_RELEASE(_pixelShader);
|
||||
SAFE_RELEASE(_rasterizerState);
|
||||
SAFE_RELEASE(_constantBuffer);
|
||||
SAFE_RELEASE(_edgeSharpness);
|
||||
SAFE_RELEASE(_edgeSharpnessSRV);
|
||||
SAFE_RELEASE(_edgeIndices);
|
||||
}
|
||||
|
||||
bool
|
||||
D3D11ControlMeshDisplay::createProgram() {
|
||||
ID3D11Device *device = NULL;
|
||||
_deviceContext->GetDevice(&device);
|
||||
|
||||
ID3DBlob* pVSBlob;
|
||||
ID3DBlob* pPSBlob;
|
||||
pVSBlob = D3D11Utils::CompileShader(s_VS, "vs_main", "vs_4_0");
|
||||
pPSBlob = D3D11Utils::CompileShader(s_PS, "ps_main", "ps_4_0");
|
||||
assert(pVSBlob);
|
||||
assert(pPSBlob);
|
||||
|
||||
D3D11_INPUT_ELEMENT_DESC inputElementDesc[] = {
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,
|
||||
D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 0, DXGI_FORMAT_R32_FLOAT, 0, sizeof(float)*3,
|
||||
D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
};
|
||||
device->CreateInputLayout(inputElementDesc, ARRAYSIZE(inputElementDesc),
|
||||
pVSBlob->GetBufferPointer(),
|
||||
pVSBlob->GetBufferSize(),
|
||||
&_inputLayout);
|
||||
assert(_inputLayout);
|
||||
|
||||
device->CreateVertexShader(pVSBlob->GetBufferPointer(),
|
||||
pVSBlob->GetBufferSize(),
|
||||
NULL, &_vertexShader);
|
||||
assert(_vertexShader);
|
||||
|
||||
device->CreatePixelShader(pPSBlob->GetBufferPointer(),
|
||||
pPSBlob->GetBufferSize(),
|
||||
NULL, &_pixelShader);
|
||||
assert(_pixelShader);
|
||||
|
||||
D3D11_RASTERIZER_DESC rasDesc;
|
||||
rasDesc.FillMode = D3D11_FILL_SOLID;
|
||||
rasDesc.CullMode = D3D11_CULL_NONE;
|
||||
rasDesc.FrontCounterClockwise = FALSE;
|
||||
rasDesc.DepthBias = 0;
|
||||
rasDesc.DepthBiasClamp = 0;
|
||||
rasDesc.SlopeScaledDepthBias = 0.0f;
|
||||
rasDesc.DepthClipEnable = FALSE;
|
||||
rasDesc.ScissorEnable = FALSE;
|
||||
rasDesc.MultisampleEnable = FALSE;
|
||||
rasDesc.AntialiasedLineEnable = FALSE;
|
||||
device->CreateRasterizerState(&rasDesc, &_rasterizerState);
|
||||
assert(_rasterizerState);
|
||||
|
||||
// constant buffer
|
||||
D3D11_BUFFER_DESC cbDesc;
|
||||
cbDesc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
cbDesc.MiscFlags = 0;
|
||||
cbDesc.ByteWidth = sizeof(CB_CONTROL_MESH_DISPLAY);
|
||||
|
||||
device->CreateBuffer(&cbDesc, NULL, &_constantBuffer);
|
||||
assert(_constantBuffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
D3D11ControlMeshDisplay::Draw(ID3D11Buffer *buffer, int stride,
|
||||
const float *modelViewProjectionMatrix) {
|
||||
|
||||
if (_displayEdges == false && _displayVertices == false) return;
|
||||
|
||||
if (_vertexShader == NULL) createProgram();
|
||||
if (_vertexShader == NULL) return;
|
||||
|
||||
UINT hStrides = stride*sizeof(float);
|
||||
UINT hOffsets = 0;
|
||||
_deviceContext->IASetVertexBuffers(0, 1, &buffer, &hStrides, &hOffsets);
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE MappedResource;
|
||||
_deviceContext->Map(_constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource);
|
||||
CB_CONTROL_MESH_DISPLAY * pData = (CB_CONTROL_MESH_DISPLAY *)MappedResource.pData;
|
||||
memcpy(pData->mViewProjection, modelViewProjectionMatrix, sizeof(float) * 16);
|
||||
_deviceContext->Unmap(_constantBuffer, 0);
|
||||
|
||||
_deviceContext->IASetInputLayout(_inputLayout);
|
||||
_deviceContext->VSSetShader(_vertexShader, NULL, 0);
|
||||
_deviceContext->HSSetShader(NULL, NULL, 0);
|
||||
_deviceContext->DSSetShader(NULL, NULL, 0);
|
||||
_deviceContext->GSSetShader(NULL, NULL, 0);
|
||||
_deviceContext->PSSetShaderResources(0, 1, &_edgeSharpnessSRV);
|
||||
_deviceContext->PSSetShader(_pixelShader, NULL, 0);
|
||||
_deviceContext->RSSetState(_rasterizerState);
|
||||
_deviceContext->VSSetConstantBuffers(0, 1, &_constantBuffer);
|
||||
|
||||
if (_displayEdges) {
|
||||
_deviceContext->IASetIndexBuffer(_edgeIndices, DXGI_FORMAT_R32_UINT, 0);
|
||||
_deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
|
||||
_deviceContext->DrawIndexed(_numEdges * 2, 0, 0);
|
||||
}
|
||||
if (_displayVertices) {
|
||||
// TODO: need geometry shader to draw bigger points
|
||||
_deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||
_deviceContext->Draw(_numPoints, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
D3D11ControlMeshDisplay::SetTopology(
|
||||
OpenSubdiv::Far::TopologyLevel const &level) {
|
||||
int nEdges = level.GetNumEdges();
|
||||
int nVerts = level.GetNumVertices();
|
||||
|
||||
std::vector<int> edgeIndices;
|
||||
std::vector<float> edgeSharpnesses;
|
||||
std::vector<float> vertSharpnesses;
|
||||
|
||||
edgeIndices.reserve(nEdges * 2);
|
||||
edgeSharpnesses.reserve(nEdges);
|
||||
vertSharpnesses.reserve(nVerts);
|
||||
|
||||
for (int i = 0; i < nEdges; ++i) {
|
||||
OpenSubdiv::Far::ConstIndexArray verts = level.GetEdgeVertices(i);
|
||||
edgeIndices.push_back(verts[0]);
|
||||
edgeIndices.push_back(verts[1]);
|
||||
edgeSharpnesses.push_back(level.GetEdgeSharpness(i));
|
||||
}
|
||||
|
||||
for (int i = 0; i < nVerts; ++i) {
|
||||
vertSharpnesses.push_back(level.GetVertexSharpness(i));
|
||||
}
|
||||
|
||||
_numEdges = nEdges;
|
||||
_numPoints = nVerts;
|
||||
|
||||
ID3D11Device *device = NULL;
|
||||
_deviceContext->GetDevice(&device);
|
||||
|
||||
SAFE_RELEASE(_edgeIndices);
|
||||
// create edge index buffer
|
||||
D3D11_BUFFER_DESC bufferDesc;
|
||||
ZeroMemory(&bufferDesc, sizeof(bufferDesc));
|
||||
bufferDesc.ByteWidth = (int)edgeIndices.size() * sizeof(int);
|
||||
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
|
||||
bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||
bufferDesc.CPUAccessFlags = 0;
|
||||
bufferDesc.MiscFlags = 0;
|
||||
bufferDesc.StructureByteStride = sizeof(int);
|
||||
|
||||
D3D11_SUBRESOURCE_DATA subData;
|
||||
ZeroMemory(&subData, sizeof(subData));
|
||||
subData.pSysMem = &edgeIndices[0];
|
||||
subData.SysMemPitch = 0;
|
||||
subData.SysMemSlicePitch = 0;
|
||||
|
||||
HRESULT hr = device->CreateBuffer(&bufferDesc, &subData, &_edgeIndices);
|
||||
assert(_edgeIndices);
|
||||
|
||||
// edge sharpness
|
||||
SAFE_RELEASE(_edgeSharpness);
|
||||
SAFE_RELEASE(_edgeSharpnessSRV);
|
||||
ZeroMemory(&bufferDesc, sizeof(bufferDesc));
|
||||
bufferDesc.ByteWidth = (int)edgeSharpnesses.size() * sizeof(float);
|
||||
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
|
||||
bufferDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
bufferDesc.CPUAccessFlags = 0;
|
||||
bufferDesc.MiscFlags = 0;
|
||||
bufferDesc.StructureByteStride = sizeof(float);
|
||||
|
||||
ZeroMemory(&subData, sizeof(subData));
|
||||
subData.pSysMem = &edgeSharpnesses[0];
|
||||
subData.SysMemPitch = 0;
|
||||
subData.SysMemSlicePitch = 0;
|
||||
|
||||
hr = device->CreateBuffer(&bufferDesc, &subData, &_edgeSharpness);
|
||||
assert(_edgeSharpness);
|
||||
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||
ZeroMemory(&srvDesc, sizeof(srvDesc));
|
||||
srvDesc.Format = DXGI_FORMAT_R32_FLOAT;
|
||||
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
|
||||
srvDesc.Buffer.NumElements = _numEdges;
|
||||
hr = device->CreateShaderResourceView(_edgeSharpness, &srvDesc, &_edgeSharpnessSRV);
|
||||
assert(_edgeSharpnessSRV);
|
||||
}
|
||||
|
||||
48
blender-5.2.0/extern/opensubdiv-source/examples/common/d3d11ControlMeshDisplay.h
vendored
Normal file
48
blender-5.2.0/extern/opensubdiv-source/examples/common/d3d11ControlMeshDisplay.h
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
//
|
||||
// Copyright 2015 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef OPENSUBDIV_EXAMPLES_D3D11_CONTROL_MESH_DISPLAY_H
|
||||
#define OPENSUBDIV_EXAMPLES_D3D11_CONTROL_MESH_DISPLAY_H
|
||||
|
||||
#include <d3d11.h>
|
||||
#include <opensubdiv/far/topologyLevel.h>
|
||||
|
||||
class D3D11ControlMeshDisplay {
|
||||
public:
|
||||
D3D11ControlMeshDisplay(ID3D11DeviceContext *deviceContext);
|
||||
~D3D11ControlMeshDisplay();
|
||||
|
||||
void Draw(ID3D11Buffer *buffer, int stride,
|
||||
const float *modelViewProjectionMatrix);
|
||||
|
||||
void SetTopology(OpenSubdiv::Far::TopologyLevel const &level);
|
||||
|
||||
bool GetEdgesDisplay() const { return _displayEdges; }
|
||||
void SetEdgesDisplay(bool display) { _displayEdges = display; }
|
||||
bool GetVerticesDisplay() const { return _displayVertices; }
|
||||
void SetVerticesDisplay(bool display) { _displayVertices = display; }
|
||||
|
||||
private:
|
||||
bool createProgram();
|
||||
|
||||
bool _displayEdges;
|
||||
bool _displayVertices;
|
||||
|
||||
ID3D11DeviceContext *_deviceContext;
|
||||
ID3D11InputLayout *_inputLayout;
|
||||
ID3D11VertexShader *_vertexShader;
|
||||
ID3D11PixelShader *_pixelShader;
|
||||
ID3D11RasterizerState *_rasterizerState;
|
||||
ID3D11Buffer *_constantBuffer;
|
||||
ID3D11ShaderResourceView *_edgeSharpnessSRV;
|
||||
ID3D11Buffer *_edgeSharpness;
|
||||
ID3D11Buffer *_edgeIndices;
|
||||
|
||||
int _numEdges, _numPoints;
|
||||
};
|
||||
|
||||
#endif // OPENSUBDIV_EXAMPLES_D3D11_CONTROL_MESH_DISPLAY_H
|
||||
266
blender-5.2.0/extern/opensubdiv-source/examples/common/d3d11Hud.cpp
vendored
Normal file
266
blender-5.2.0/extern/opensubdiv-source/examples/common/d3d11Hud.cpp
vendored
Normal file
@@ -0,0 +1,266 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#include <D3D11.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <cassert>
|
||||
#include "d3d11Hud.h"
|
||||
#include "d3d11Utils.h"
|
||||
#include "font_image.h"
|
||||
#include "../common/simple_math.h"
|
||||
|
||||
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
|
||||
|
||||
static const char *s_VS =
|
||||
"cbuffer cbPerFrame : register( b0 )\n"
|
||||
"{\n"
|
||||
" matrix g_mViewProjection;\n"
|
||||
"};\n"
|
||||
"struct vertexIn { float2 pos : POSITION0; float3 color : COLOR0; float2 uv : TEXCOORD0; };\n"
|
||||
"struct vertexOut { float4 pos : SV_POSITION; float4 color : COLOR0; float2 uv : TEXCOORD0; };\n"
|
||||
"vertexOut vs_main(vertexIn IN) {\n"
|
||||
" vertexOut vout;\n"
|
||||
" vout.pos = mul(float4(IN.pos.x, IN.pos.y, 0, 1), g_mViewProjection);\n"
|
||||
" vout.color = float4(IN.color, 1);\n"
|
||||
" vout.uv = IN.uv;\n"
|
||||
" return vout;\n"
|
||||
"}";
|
||||
|
||||
static const char *s_PS =
|
||||
"struct pixelIn { float4 pos : SV_POSITION; float4 color : COLOR0; float2 uv : TEXCOORD0; };\n"
|
||||
"Texture2D tx : register(t0); \n"
|
||||
"SamplerState sm : register(s0); \n"
|
||||
"float4 ps_main(pixelIn IN) : SV_Target {\n"
|
||||
" float4 c = tx.Sample(sm, IN.uv);\n"
|
||||
" if( c.a == 0.0 ) \n"
|
||||
" discard;\n"
|
||||
" return IN.color * c;\n"
|
||||
"}";
|
||||
|
||||
struct CB_HUD_PROJECTION
|
||||
{
|
||||
float mViewProjection[16];
|
||||
};
|
||||
|
||||
D3D11hud::D3D11hud(ID3D11DeviceContext *deviceContext)
|
||||
: _deviceContext(deviceContext),
|
||||
_vbo(0), _staticVbo(0), _fontTexture(0), _inputLayout(0),
|
||||
_shaderResourceView(0), _samplerState(0), _vertexShader(0),
|
||||
_pixelShader(0), _rasterizerState(0)
|
||||
{
|
||||
}
|
||||
|
||||
D3D11hud::~D3D11hud()
|
||||
{
|
||||
SAFE_RELEASE(_vbo);
|
||||
SAFE_RELEASE(_staticVbo);
|
||||
SAFE_RELEASE(_fontTexture);
|
||||
SAFE_RELEASE(_inputLayout);
|
||||
SAFE_RELEASE(_shaderResourceView);
|
||||
SAFE_RELEASE(_samplerState);
|
||||
SAFE_RELEASE(_vertexShader);
|
||||
SAFE_RELEASE(_pixelShader);
|
||||
SAFE_RELEASE(_rasterizerState);
|
||||
}
|
||||
|
||||
void
|
||||
D3D11hud::Init(int width, int height, int frameBufferWidth, int frameBufferHeight)
|
||||
{
|
||||
Hud::Init(width, height, frameBufferWidth, frameBufferHeight);
|
||||
|
||||
ID3D11Device *device = NULL;
|
||||
_deviceContext->GetDevice(&device);
|
||||
|
||||
// define font texture
|
||||
D3D11_TEXTURE2D_DESC texDesc;
|
||||
texDesc.Width = FONT_TEXTURE_WIDTH;
|
||||
texDesc.Height = FONT_TEXTURE_HEIGHT;
|
||||
texDesc.MipLevels = 1;
|
||||
texDesc.ArraySize = 1;
|
||||
texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
texDesc.SampleDesc.Count = 1;
|
||||
texDesc.SampleDesc.Quality = 0;
|
||||
texDesc.Usage = D3D11_USAGE_DEFAULT;
|
||||
texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
texDesc.CPUAccessFlags = 0;
|
||||
texDesc.MiscFlags = 0;
|
||||
|
||||
D3D11_SUBRESOURCE_DATA subData;
|
||||
subData.pSysMem = font_image;
|
||||
subData.SysMemPitch = FONT_TEXTURE_WIDTH*4;
|
||||
subData.SysMemSlicePitch = FONT_TEXTURE_WIDTH*FONT_TEXTURE_HEIGHT*4;
|
||||
|
||||
HRESULT hr = device->CreateTexture2D(&texDesc, &subData, &_fontTexture);
|
||||
assert(_fontTexture);
|
||||
|
||||
// shader resource view
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||
ZeroMemory(&srvDesc, sizeof(srvDesc));
|
||||
srvDesc.Format = texDesc.Format;
|
||||
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
srvDesc.Texture2D.MostDetailedMip = 0;
|
||||
srvDesc.Texture2D.MipLevels = texDesc.MipLevels;
|
||||
device->CreateShaderResourceView(_fontTexture, &srvDesc, &_shaderResourceView);
|
||||
assert(_shaderResourceView);
|
||||
|
||||
D3D11_SAMPLER_DESC samplerDesc;
|
||||
ZeroMemory(&samplerDesc, sizeof(samplerDesc));
|
||||
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
||||
samplerDesc.AddressU = samplerDesc.AddressV = samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
samplerDesc.MaxAnisotropy = 1;
|
||||
samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
|
||||
samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
|
||||
device->CreateSamplerState(&samplerDesc, &_samplerState);
|
||||
assert(_samplerState);
|
||||
|
||||
ID3DBlob* pVSBlob;
|
||||
ID3DBlob* pPSBlob;
|
||||
pVSBlob = D3D11Utils::CompileShader(s_VS, "vs_main", "vs_4_0");
|
||||
pPSBlob = D3D11Utils::CompileShader(s_PS, "ps_main", "ps_4_0");
|
||||
assert(pVSBlob);
|
||||
assert(pPSBlob);
|
||||
|
||||
D3D11_INPUT_ELEMENT_DESC inputElementDesc[] = {
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, sizeof(float)*2, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, sizeof(float)*5, D3D11_INPUT_PER_VERTEX_DATA, 0 }
|
||||
};
|
||||
device->CreateInputLayout(inputElementDesc, ARRAYSIZE(inputElementDesc),
|
||||
pVSBlob->GetBufferPointer(),
|
||||
pVSBlob->GetBufferSize(),
|
||||
&_inputLayout);
|
||||
assert(_inputLayout);
|
||||
|
||||
device->CreateVertexShader(pVSBlob->GetBufferPointer(),
|
||||
pVSBlob->GetBufferSize(),
|
||||
NULL, &_vertexShader);
|
||||
assert(_vertexShader);
|
||||
|
||||
device->CreatePixelShader(pPSBlob->GetBufferPointer(),
|
||||
pPSBlob->GetBufferSize(),
|
||||
NULL, &_pixelShader);
|
||||
assert(_pixelShader);
|
||||
|
||||
D3D11_RASTERIZER_DESC rasDesc;
|
||||
rasDesc.FillMode = D3D11_FILL_SOLID;
|
||||
rasDesc.CullMode = D3D11_CULL_NONE;
|
||||
rasDesc.FrontCounterClockwise = FALSE;
|
||||
rasDesc.DepthBias = 0;
|
||||
rasDesc.DepthBiasClamp = 0;
|
||||
rasDesc.SlopeScaledDepthBias = 0.0f;
|
||||
rasDesc.DepthClipEnable = FALSE;
|
||||
rasDesc.ScissorEnable = FALSE;
|
||||
rasDesc.MultisampleEnable = FALSE;
|
||||
rasDesc.AntialiasedLineEnable = FALSE;
|
||||
device->CreateRasterizerState(&rasDesc, &_rasterizerState);
|
||||
assert(_rasterizerState);
|
||||
|
||||
// constant buffer
|
||||
D3D11_BUFFER_DESC cbDesc;
|
||||
cbDesc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
cbDesc.MiscFlags = 0;
|
||||
cbDesc.ByteWidth = sizeof(CB_HUD_PROJECTION);
|
||||
|
||||
device->CreateBuffer(&cbDesc, NULL, &_constantBuffer);
|
||||
assert(_constantBuffer);
|
||||
}
|
||||
|
||||
void
|
||||
D3D11hud::Rebuild(int width, int height, int framebufferWidth, int framebufferHeight)
|
||||
{
|
||||
Hud::Rebuild(width, height, framebufferWidth, framebufferHeight);
|
||||
|
||||
SAFE_RELEASE(_staticVbo);
|
||||
|
||||
int size = (int)getStaticVboSource().size();
|
||||
if (size) {
|
||||
D3D11_BUFFER_DESC bufferDesc;
|
||||
bufferDesc.ByteWidth = size * sizeof(float);
|
||||
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
|
||||
bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||
bufferDesc.CPUAccessFlags = 0;
|
||||
bufferDesc.MiscFlags = 0;
|
||||
bufferDesc.StructureByteStride = 4*sizeof(float);
|
||||
|
||||
D3D11_SUBRESOURCE_DATA subData;
|
||||
subData.pSysMem = &getStaticVboSource()[0];
|
||||
subData.SysMemPitch = 0;
|
||||
subData.SysMemSlicePitch = 0;
|
||||
|
||||
ID3D11Device *device = NULL;
|
||||
_deviceContext->GetDevice(&device);
|
||||
HRESULT hr = device->CreateBuffer(&bufferDesc, &subData, &_staticVbo);
|
||||
assert(_staticVbo);
|
||||
_staticVboCount = size / 7;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
D3D11hud::Flush()
|
||||
{
|
||||
if (!Hud::Flush())
|
||||
return false;
|
||||
|
||||
// update dynamic text
|
||||
D3D11_BUFFER_DESC bufferDesc;
|
||||
bufferDesc.ByteWidth = (int)getVboSource().size() * sizeof(float);
|
||||
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
|
||||
bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||
bufferDesc.CPUAccessFlags = 0;
|
||||
bufferDesc.MiscFlags = 0;
|
||||
bufferDesc.StructureByteStride = 4*sizeof(float);
|
||||
|
||||
D3D11_SUBRESOURCE_DATA subData;
|
||||
subData.pSysMem = &getVboSource()[0];
|
||||
subData.SysMemPitch = 0;
|
||||
subData.SysMemSlicePitch = 0;
|
||||
|
||||
SAFE_RELEASE(_vbo);
|
||||
|
||||
ID3D11Device *device = NULL;
|
||||
_deviceContext->GetDevice(&device);
|
||||
HRESULT hr = device->CreateBuffer(&bufferDesc, &subData, &_vbo);
|
||||
assert(_vbo);
|
||||
int numVertices = (int)getVboSource().size()/7; /* (x, y, r, g, b, u, v) = 7*/
|
||||
|
||||
// reserved space of the vector remains for the next frame.
|
||||
getVboSource().clear();
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE MappedResource;
|
||||
_deviceContext->Map(_constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource);
|
||||
CB_HUD_PROJECTION * pData = (CB_HUD_PROJECTION *)MappedResource.pData;
|
||||
|
||||
ortho(pData->mViewProjection, 0, 0, (float)GetWidth(), (float)GetHeight());
|
||||
transpose(pData->mViewProjection);
|
||||
|
||||
_deviceContext->Unmap( _constantBuffer, 0 );
|
||||
|
||||
// setup graphics pipeline
|
||||
_deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
_deviceContext->IASetInputLayout(_inputLayout);
|
||||
_deviceContext->VSSetShader(_vertexShader, NULL, 0);
|
||||
_deviceContext->HSSetShader(NULL, NULL, 0);
|
||||
_deviceContext->DSSetShader(NULL, NULL, 0);
|
||||
_deviceContext->GSSetShader(NULL, NULL, 0);
|
||||
_deviceContext->PSSetShader(_pixelShader, NULL, 0);
|
||||
_deviceContext->PSSetShaderResources(0, 1, &_shaderResourceView);
|
||||
_deviceContext->PSSetSamplers(0, 1, &_samplerState);
|
||||
_deviceContext->RSSetState(_rasterizerState);
|
||||
_deviceContext->VSSetConstantBuffers(0, 1, &_constantBuffer);
|
||||
|
||||
UINT strides = 7*sizeof(float);
|
||||
UINT offsets = 0;
|
||||
_deviceContext->IASetVertexBuffers(0, 1, &_vbo, &strides, &offsets);
|
||||
_deviceContext->Draw(numVertices, 0);
|
||||
_deviceContext->IASetVertexBuffers(0, 1, &_staticVbo, &strides, &offsets);
|
||||
_deviceContext->Draw(_staticVboCount, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
50
blender-5.2.0/extern/opensubdiv-source/examples/common/d3d11Hud.h
vendored
Normal file
50
blender-5.2.0/extern/opensubdiv-source/examples/common/d3d11Hud.h
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef OPENSUBDIV_EXAMPLES_D3D11_HUD_H
|
||||
#define OPENSUBDIV_EXAMPLES_D3D11_HUD_H
|
||||
|
||||
#include <D3D11.h>
|
||||
#include "hud.h"
|
||||
|
||||
class D3D11hud : public Hud
|
||||
{
|
||||
public:
|
||||
D3D11hud(ID3D11DeviceContext *deviceContext);
|
||||
~D3D11hud();
|
||||
|
||||
void Init(int width, int height) {
|
||||
Init(width, height, width, height);
|
||||
}
|
||||
|
||||
void Rebuild(int width, int height) {
|
||||
Rebuild(width, height, width, height);
|
||||
}
|
||||
|
||||
virtual void Init(int width, int height, int framebufferWidth, int framebufferHeight);
|
||||
|
||||
virtual void Rebuild(int width, int height,
|
||||
int framebufferWidth, int framebufferHeight);
|
||||
|
||||
virtual bool Flush();
|
||||
|
||||
private:
|
||||
ID3D11DeviceContext *_deviceContext;
|
||||
ID3D11Buffer *_vbo;
|
||||
ID3D11Buffer *_staticVbo;
|
||||
ID3D11Texture2D *_fontTexture;
|
||||
ID3D11InputLayout *_inputLayout;
|
||||
ID3D11ShaderResourceView *_shaderResourceView;
|
||||
ID3D11SamplerState *_samplerState;
|
||||
ID3D11VertexShader *_vertexShader;
|
||||
ID3D11PixelShader *_pixelShader;
|
||||
ID3D11RasterizerState *_rasterizerState;
|
||||
ID3D11Buffer* _constantBuffer;
|
||||
int _staticVboCount;
|
||||
};
|
||||
|
||||
#endif // OPENSUBDIV_EXAMPLES_D3D11_HUD_H
|
||||
215
blender-5.2.0/extern/opensubdiv-source/examples/common/d3d11PtexMipmapTexture.cpp
vendored
Normal file
215
blender-5.2.0/extern/opensubdiv-source/examples/common/d3d11PtexMipmapTexture.cpp
vendored
Normal file
@@ -0,0 +1,215 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#include "d3d11PtexMipmapTexture.h"
|
||||
#include "ptexMipmapTextureLoader.h"
|
||||
#include <opensubdiv/far/error.h> // XXX: to be replaced
|
||||
|
||||
#include <D3D11.h>
|
||||
#include <cassert>
|
||||
|
||||
D3D11PtexMipmapTexture::D3D11PtexMipmapTexture()
|
||||
: _width(0), _height(0), _depth(0),
|
||||
_layout(0), _texels(0),
|
||||
_layoutSRV(0), _texelsSRV(0),
|
||||
_memoryUsage(0)
|
||||
{
|
||||
}
|
||||
|
||||
D3D11PtexMipmapTexture::~D3D11PtexMipmapTexture()
|
||||
{
|
||||
if (_layout) _layout->Release();
|
||||
if (_layoutSRV) _layoutSRV->Release();
|
||||
|
||||
if (_texels) _texels->Release();
|
||||
if (_texelsSRV) _texelsSRV->Release();
|
||||
}
|
||||
|
||||
/*static*/
|
||||
const char *
|
||||
D3D11PtexMipmapTexture::GetShaderSource()
|
||||
{
|
||||
static const char *ptexShaderSource =
|
||||
#include "hlslPtexCommon.gen.h"
|
||||
;
|
||||
return ptexShaderSource;
|
||||
}
|
||||
|
||||
static ID3D11Buffer *
|
||||
genTextureBuffer(ID3D11DeviceContext *deviceContext, int size, void const * data) {
|
||||
|
||||
D3D11_BUFFER_DESC hBufferDesc;
|
||||
hBufferDesc.ByteWidth = size;
|
||||
hBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
hBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_SHADER_RESOURCE;
|
||||
hBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
hBufferDesc.MiscFlags = 0;
|
||||
hBufferDesc.StructureByteStride = sizeof(float);
|
||||
|
||||
HRESULT hr;
|
||||
ID3D11Buffer *buffer;
|
||||
ID3D11Device *device;
|
||||
deviceContext->GetDevice(&device);
|
||||
hr = device->CreateBuffer(&hBufferDesc, NULL, &buffer);
|
||||
if (FAILED(hr)) {
|
||||
OpenSubdiv::Far::Error(OpenSubdiv::Far::FAR_RUNTIME_ERROR,
|
||||
"Fail in CreateBuffer\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE resource;
|
||||
hr = deviceContext->Map(buffer, 0,
|
||||
D3D11_MAP_WRITE_DISCARD, 0, &resource);
|
||||
if (FAILED(hr)) {
|
||||
OpenSubdiv::Far::Error(OpenSubdiv::Far::FAR_RUNTIME_ERROR,
|
||||
"Fail in Map buffer\n");
|
||||
buffer->Release();
|
||||
return 0;
|
||||
}
|
||||
memcpy(resource.pData, data, size);
|
||||
deviceContext->Unmap(buffer, 0);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
D3D11PtexMipmapTexture *
|
||||
D3D11PtexMipmapTexture::Create(ID3D11DeviceContext *deviceContext,
|
||||
PtexTexture * reader,
|
||||
int maxLevels,
|
||||
size_t targetMemory) {
|
||||
|
||||
D3D11PtexMipmapTexture * result = NULL;
|
||||
|
||||
int maxNumPages = D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
|
||||
|
||||
// Read the ptex data and pack the texels
|
||||
bool padAlpha = reader->numChannels()==3 && reader->dataType()!=Ptex::dt_float;
|
||||
|
||||
PtexMipmapTextureLoader loader(reader,
|
||||
maxNumPages,
|
||||
maxLevels,
|
||||
targetMemory,
|
||||
true, // seamlessMipmap
|
||||
padAlpha);
|
||||
|
||||
int numChannels = reader->numChannels() + padAlpha,
|
||||
numFaces = loader.GetNumFaces();
|
||||
|
||||
ID3D11Buffer *layout = genTextureBuffer(deviceContext,
|
||||
numFaces * 6 * sizeof(short),
|
||||
loader.GetLayoutBuffer());
|
||||
if (!layout) return NULL;
|
||||
|
||||
DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
|
||||
int bpp = 0;
|
||||
switch (reader->dataType()) {
|
||||
case Ptex::dt_uint16:
|
||||
switch (numChannels) {
|
||||
case 1: format = DXGI_FORMAT_R16_UINT; break;
|
||||
case 2: format = DXGI_FORMAT_R16G16_UINT; break;
|
||||
case 3: assert(false); break;
|
||||
case 4: format = DXGI_FORMAT_R16G16B16A16_UINT; break;
|
||||
}
|
||||
bpp = numChannels * 2;
|
||||
break;
|
||||
case Ptex::dt_float:
|
||||
switch (numChannels) {
|
||||
case 1: format = DXGI_FORMAT_R32_FLOAT; break;
|
||||
case 2: format = DXGI_FORMAT_R32G32_FLOAT; break;
|
||||
case 3: format = DXGI_FORMAT_R32G32B32_FLOAT; break;
|
||||
case 4: format = DXGI_FORMAT_R32G32B32A32_FLOAT; break;
|
||||
}
|
||||
bpp = numChannels * 4;
|
||||
break;
|
||||
case Ptex::dt_half:
|
||||
switch (numChannels) {
|
||||
case 1: format = DXGI_FORMAT_R16_FLOAT; break;
|
||||
case 2: format = DXGI_FORMAT_R16G16_FLOAT; break;
|
||||
case 3: assert(false); break;
|
||||
case 4: format = DXGI_FORMAT_R16G16B16A16_FLOAT; break;
|
||||
}
|
||||
bpp = numChannels * 2;
|
||||
break;
|
||||
default:
|
||||
switch (numChannels) {
|
||||
case 1: format = DXGI_FORMAT_R8_UNORM; break;
|
||||
case 2: format = DXGI_FORMAT_R8G8_UNORM; break;
|
||||
case 3: assert(false); break;
|
||||
case 4: format = DXGI_FORMAT_R8G8B8A8_UNORM; break;
|
||||
}
|
||||
bpp = numChannels;
|
||||
break;
|
||||
}
|
||||
|
||||
// actual texels texture array
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
desc.Width = loader.GetPageWidth();
|
||||
desc.Height = loader.GetPageHeight();
|
||||
desc.MipLevels = 1;
|
||||
desc.ArraySize = loader.GetNumPages();
|
||||
desc.Format = format;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
desc.CPUAccessFlags = 0;
|
||||
desc.MiscFlags = 0;
|
||||
|
||||
D3D11_SUBRESOURCE_DATA *initData = new D3D11_SUBRESOURCE_DATA[desc.ArraySize];
|
||||
int pageStride = loader.GetPageWidth()*loader.GetPageHeight() * bpp;
|
||||
for (unsigned int i = 0; i < desc.ArraySize; ++i) {
|
||||
initData[i].pSysMem = loader.GetTexelBuffer() + i * pageStride;
|
||||
initData[i].SysMemPitch = loader.GetPageWidth() * bpp;
|
||||
initData[i].SysMemSlicePitch = pageStride;
|
||||
}
|
||||
|
||||
ID3D11Device *device;
|
||||
ID3D11Texture2D *texels;
|
||||
deviceContext->GetDevice(&device);
|
||||
HRESULT hr = device->CreateTexture2D(&desc, initData, &texels);
|
||||
if (FAILED(hr)) return NULL;
|
||||
|
||||
delete[] initData;
|
||||
|
||||
// create SRV
|
||||
ID3D11ShaderResourceView *layoutSRV;
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvd;
|
||||
ZeroMemory(&srvd, sizeof(srvd));
|
||||
srvd.Format = DXGI_FORMAT_R16_UINT;
|
||||
srvd.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
|
||||
srvd.Buffer.FirstElement = 0;
|
||||
srvd.Buffer.NumElements = numFaces * 6;
|
||||
hr = device->CreateShaderResourceView(layout, &srvd, &layoutSRV);
|
||||
if (FAILED(hr)) return NULL;
|
||||
|
||||
ID3D11ShaderResourceView *texelsSRV;
|
||||
ZeroMemory(&srvd, sizeof(srvd));
|
||||
srvd.Format = format;
|
||||
srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
|
||||
srvd.Texture2DArray.MipLevels = 1;
|
||||
srvd.Texture2DArray.ArraySize = desc.ArraySize;
|
||||
hr = device->CreateShaderResourceView(texels, &srvd, &texelsSRV);
|
||||
if (FAILED(hr)) return NULL;
|
||||
|
||||
|
||||
result = new D3D11PtexMipmapTexture;
|
||||
|
||||
result->_width = loader.GetPageWidth();
|
||||
result->_height = loader.GetPageHeight();
|
||||
result->_depth = loader.GetNumPages();
|
||||
|
||||
result->_format = format;
|
||||
|
||||
result->_layout = layout;
|
||||
result->_texels = texels;
|
||||
|
||||
result->_layoutSRV = layoutSRV;
|
||||
result->_texelsSRV = texelsSRV;
|
||||
result->_memoryUsage = loader.GetMemoryUsage();
|
||||
|
||||
return result;
|
||||
}
|
||||
63
blender-5.2.0/extern/opensubdiv-source/examples/common/d3d11PtexMipmapTexture.h
vendored
Normal file
63
blender-5.2.0/extern/opensubdiv-source/examples/common/d3d11PtexMipmapTexture.h
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef OPENSUBDIV_EXAMPLES_D3D11_PTEX_MIPMAP_TEXTURE_H
|
||||
#define OPENSUBDIV_EXAMPLES_D3D11_PTEX_MIPMAP_TEXTURE_H
|
||||
|
||||
#include <opensubdiv/osd/nonCopyable.h>
|
||||
|
||||
#include <Ptexture.h>
|
||||
|
||||
struct ID3D11Buffer;
|
||||
struct ID3D11Texture2D;
|
||||
struct ID3D11DeviceContext;
|
||||
struct ID3D11ShaderResourceView;
|
||||
|
||||
class D3D11PtexMipmapTexture : OpenSubdiv::Osd::NonCopyable<D3D11PtexMipmapTexture> {
|
||||
public:
|
||||
static D3D11PtexMipmapTexture * Create(ID3D11DeviceContext *deviceContext,
|
||||
PtexTexture * reader,
|
||||
int maxLevels=10,
|
||||
size_t targetMemory=0);
|
||||
|
||||
/// Returns GLSL shader snippet to fetch ptex
|
||||
static const char *GetShaderSource();
|
||||
|
||||
/// Returns the texture buffer containing the layout of the ptex faces
|
||||
/// in the texels texture array.
|
||||
ID3D11Buffer *GetLayoutTextureBuffer() const { return _layout; }
|
||||
|
||||
ID3D11ShaderResourceView **GetLayoutSRV() { return &_layoutSRV; }
|
||||
|
||||
/// Returns the texels texture array.
|
||||
ID3D11Texture2D *GetTexelsTexture() const { return _texels; }
|
||||
|
||||
ID3D11ShaderResourceView **GetTexelsSRV() { return &_texelsSRV; }
|
||||
|
||||
/// Returns the amount of allocated memory (in byte)
|
||||
size_t GetMemoryUsage() const { return _memoryUsage; }
|
||||
|
||||
~D3D11PtexMipmapTexture();
|
||||
|
||||
private:
|
||||
D3D11PtexMipmapTexture();
|
||||
|
||||
int _width, // width / height / depth of the 3D texel buffer
|
||||
_height,
|
||||
_depth;
|
||||
|
||||
int _format; // texel color format
|
||||
|
||||
ID3D11Buffer *_layout; // per-face lookup table
|
||||
ID3D11Texture2D *_texels; // texel data
|
||||
ID3D11ShaderResourceView *_layoutSRV;
|
||||
ID3D11ShaderResourceView *_texelsSRV;
|
||||
|
||||
size_t _memoryUsage; // total amount of memory used (estimate)
|
||||
};
|
||||
|
||||
#endif // OPENSUBDIV_EXAMPLES_D3D11_PTEX_TEXTURE_H
|
||||
169
blender-5.2.0/extern/opensubdiv-source/examples/common/d3d11ShaderCache.cpp
vendored
Normal file
169
blender-5.2.0/extern/opensubdiv-source/examples/common/d3d11ShaderCache.cpp
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
//
|
||||
// Copyright 2015 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#include "d3d11ShaderCache.h"
|
||||
|
||||
#include <D3D11.h>
|
||||
#include <D3Dcompiler.h>
|
||||
|
||||
#include <opensubdiv/far/error.h>
|
||||
|
||||
D3D11DrawConfig::D3D11DrawConfig()
|
||||
: _vertexShader(NULL), _hullShader(NULL), _domainShader(NULL),
|
||||
_geometryShader(NULL), _pixelShader(NULL) {
|
||||
}
|
||||
|
||||
D3D11DrawConfig::~D3D11DrawConfig() {
|
||||
if (_vertexShader) _vertexShader->Release();
|
||||
if (_hullShader) _hullShader->Release();
|
||||
if (_domainShader) _domainShader->Release();
|
||||
if (_geometryShader) _geometryShader->Release();
|
||||
if (_pixelShader) _pixelShader->Release();
|
||||
}
|
||||
|
||||
static ID3DBlob *
|
||||
_CompileShader(std::string const &target,
|
||||
std::string const &entry,
|
||||
std::string const &shaderSource) {
|
||||
DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
|
||||
#ifdef _DEBUG
|
||||
dwShaderFlags |= D3DCOMPILE_DEBUG;
|
||||
#endif
|
||||
|
||||
ID3DBlob* pBlob = NULL;
|
||||
ID3DBlob* pBlobError = NULL;
|
||||
|
||||
HRESULT hr = D3DCompile(shaderSource.c_str(), shaderSource.size(),
|
||||
NULL, NULL, NULL,
|
||||
entry.c_str(), target.c_str(),
|
||||
dwShaderFlags, 0, &pBlob, &pBlobError);
|
||||
if (FAILED(hr)) {
|
||||
if ( pBlobError != NULL ) {
|
||||
OpenSubdiv::Far::Error(OpenSubdiv::Far::FAR_RUNTIME_ERROR,
|
||||
"Error compiling HLSL shader: %s\n",
|
||||
(CHAR*)pBlobError->GetBufferPointer());
|
||||
pBlobError->Release();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pBlob;
|
||||
}
|
||||
|
||||
bool
|
||||
D3D11DrawConfig::CompileVertexShader(const std::string &target,
|
||||
const std::string &entry,
|
||||
const std::string &source,
|
||||
ID3D11InputLayout ** ppInputLayout,
|
||||
D3D11_INPUT_ELEMENT_DESC const * pInputElementDescs,
|
||||
int numInputElements,
|
||||
ID3D11Device * pd3dDevice) {
|
||||
ID3DBlob * pBlob = NULL;
|
||||
pBlob = _CompileShader(target, entry, source);
|
||||
|
||||
HRESULT hr = pd3dDevice->CreateVertexShader(pBlob->GetBufferPointer(),
|
||||
pBlob->GetBufferSize(),
|
||||
NULL,
|
||||
&_vertexShader);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ppInputLayout && !*ppInputLayout) {
|
||||
hr = pd3dDevice->CreateInputLayout(
|
||||
pInputElementDescs, numInputElements,
|
||||
pBlob->GetBufferPointer(),
|
||||
pBlob->GetBufferSize(), ppInputLayout);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (pBlob) pBlob->Release();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
D3D11DrawConfig::CompileHullShader(const std::string &target,
|
||||
const std::string &entry,
|
||||
const std::string &source,
|
||||
ID3D11Device * pd3dDevice) {
|
||||
ID3DBlob * pBlob = NULL;
|
||||
pBlob = _CompileShader(target, entry, source);
|
||||
|
||||
HRESULT hr = pd3dDevice->CreateHullShader(pBlob->GetBufferPointer(),
|
||||
pBlob->GetBufferSize(),
|
||||
NULL,
|
||||
&_hullShader);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
if (pBlob) pBlob->Release();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
D3D11DrawConfig::CompileDomainShader(const std::string &target,
|
||||
const std::string &entry,
|
||||
const std::string &source,
|
||||
ID3D11Device * pd3dDevice) {
|
||||
ID3DBlob * pBlob = NULL;
|
||||
pBlob = _CompileShader(target, entry, source);
|
||||
|
||||
HRESULT hr = pd3dDevice->CreateDomainShader(pBlob->GetBufferPointer(),
|
||||
pBlob->GetBufferSize(),
|
||||
NULL,
|
||||
&_domainShader);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
if (pBlob) pBlob->Release();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
D3D11DrawConfig::CompileGeometryShader(const std::string &target,
|
||||
const std::string &entry,
|
||||
const std::string &source,
|
||||
ID3D11Device * pd3dDevice) {
|
||||
ID3DBlob * pBlob = NULL;
|
||||
pBlob = _CompileShader(target, entry, source);
|
||||
|
||||
HRESULT hr = pd3dDevice->CreateGeometryShader(pBlob->GetBufferPointer(),
|
||||
pBlob->GetBufferSize(),
|
||||
NULL,
|
||||
&_geometryShader);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
if (pBlob) pBlob->Release();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
D3D11DrawConfig::CompilePixelShader(const std::string &target,
|
||||
const std::string &entry,
|
||||
const std::string &source,
|
||||
ID3D11Device * pd3dDevice) {
|
||||
ID3DBlob * pBlob = NULL;
|
||||
pBlob = _CompileShader(target, entry, source);
|
||||
|
||||
HRESULT hr = pd3dDevice->CreatePixelShader(pBlob->GetBufferPointer(),
|
||||
pBlob->GetBufferSize(),
|
||||
NULL,
|
||||
&_pixelShader);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
if (pBlob) pBlob->Release();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
76
blender-5.2.0/extern/opensubdiv-source/examples/common/d3d11ShaderCache.h
vendored
Normal file
76
blender-5.2.0/extern/opensubdiv-source/examples/common/d3d11ShaderCache.h
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
//
|
||||
// Copyright 2015 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef OPENSUBDIV_EXAMPLES_D3D11_SHADER_CACHE_H
|
||||
#define OPENSUBDIV_EXAMPLES_D3D11_SHADER_CACHE_H
|
||||
|
||||
#include <string>
|
||||
#include "./shaderCache.h"
|
||||
|
||||
struct ID3D11VertexShader;
|
||||
struct ID3D11HullShader;
|
||||
struct ID3D11DomainShader;
|
||||
struct ID3D11GeometryShader;
|
||||
struct ID3D11PixelShader;
|
||||
struct ID3D11Device;
|
||||
struct ID3D11InputLayout;
|
||||
struct D3D11_INPUT_ELEMENT_DESC;
|
||||
|
||||
class D3D11DrawConfig {
|
||||
public:
|
||||
D3D11DrawConfig();
|
||||
~D3D11DrawConfig();
|
||||
|
||||
bool CompileVertexShader(const std::string &target,
|
||||
const std::string &entry,
|
||||
const std::string &source,
|
||||
ID3D11InputLayout ** ppInputLayout,
|
||||
D3D11_INPUT_ELEMENT_DESC const *pInputElementDescs,
|
||||
int numInputElements,
|
||||
ID3D11Device * pd3dDevice);
|
||||
bool CompileHullShader(const std::string &target,
|
||||
const std::string &entry,
|
||||
const std::string &source,
|
||||
ID3D11Device * pd3dDevice);
|
||||
bool CompileDomainShader(const std::string &target,
|
||||
const std::string &entry,
|
||||
const std::string &source,
|
||||
ID3D11Device * pd3dDevice);
|
||||
bool CompileGeometryShader(const std::string &target,
|
||||
const std::string &entry,
|
||||
const std::string &source,
|
||||
ID3D11Device * pd3dDevice);
|
||||
bool CompilePixelShader(const std::string &target,
|
||||
const std::string &entry,
|
||||
const std::string &source,
|
||||
ID3D11Device * pd3dDevice);
|
||||
|
||||
ID3D11VertexShader *GetVertexShader() const { return _vertexShader; }
|
||||
ID3D11HullShader *GetHullShader() const { return _hullShader; }
|
||||
ID3D11DomainShader *GetDomainShader() const { return _domainShader; }
|
||||
ID3D11GeometryShader *GetGeometryShader() const { return _geometryShader; }
|
||||
ID3D11PixelShader *GetPixelShader() const { return _pixelShader; }
|
||||
|
||||
private:
|
||||
ID3D11VertexShader *_vertexShader;
|
||||
ID3D11HullShader *_hullShader;
|
||||
ID3D11DomainShader *_domainShader;
|
||||
ID3D11GeometryShader *_geometryShader;
|
||||
ID3D11PixelShader *_pixelShader;
|
||||
};
|
||||
|
||||
// workaround for template alias
|
||||
#if 0
|
||||
template <typename DESC_TYPE>
|
||||
using D3D11ShaderCache = ShaderCacheT<DESC_TYPE, D3D11DrawConfig>;
|
||||
#else
|
||||
template <typename DESC_TYPE>
|
||||
class D3D11ShaderCache : public ShaderCacheT<DESC_TYPE, D3D11DrawConfig> {
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // OPENSUBDIV_EXAMPLES_D3D11_SHADER_CACHE_H
|
||||
37
blender-5.2.0/extern/opensubdiv-source/examples/common/d3d11Utils.cpp
vendored
Normal file
37
blender-5.2.0/extern/opensubdiv-source/examples/common/d3d11Utils.cpp
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#include "d3d11Utils.h"
|
||||
#include <D3DCompiler.h>
|
||||
|
||||
namespace D3D11Utils {
|
||||
|
||||
ID3DBlob *
|
||||
CompileShader(const char *src, const char *entry, const char *spec) {
|
||||
DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
|
||||
#if defined(DEBUG) || defined(_DEBUG)
|
||||
dwShaderFlags |= D3DCOMPILE_DEBUG;
|
||||
#endif
|
||||
|
||||
ID3DBlob *pErrorBlob;
|
||||
ID3DBlob *pBlob;
|
||||
HRESULT hr = D3DCompile(src, strlen(src),
|
||||
NULL,NULL,NULL, entry, spec,
|
||||
dwShaderFlags, 0, &pBlob, &pErrorBlob);
|
||||
if (FAILED(hr)) {
|
||||
if (pErrorBlob) {
|
||||
OutputDebugStringA((char*)pErrorBlob->GetBufferPointer());
|
||||
pErrorBlob->Release();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
if (pErrorBlob)
|
||||
pErrorBlob->Release();
|
||||
return pBlob;
|
||||
}
|
||||
|
||||
} // D3D11Utils
|
||||
19
blender-5.2.0/extern/opensubdiv-source/examples/common/d3d11Utils.h
vendored
Normal file
19
blender-5.2.0/extern/opensubdiv-source/examples/common/d3d11Utils.h
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef OPENSUBDIV_EXAMPLES_D3D11_COMPILE_H
|
||||
#define OPENSUBDIV_EXAMPLES_D3D11_COMPILE_H
|
||||
|
||||
#include <D3DCompiler.h>
|
||||
|
||||
namespace D3D11Utils {
|
||||
|
||||
ID3DBlob *CompileShader(const char *src, const char *entry, const char *spec);
|
||||
|
||||
}
|
||||
|
||||
#endif // OPENSUBDIV_EXAMPLES_D3D11_COMPILE_H
|
||||
91
blender-5.2.0/extern/opensubdiv-source/examples/common/export_obj.py
vendored
Normal file
91
blender-5.2.0/extern/opensubdiv-source/examples/common/export_obj.py
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
#
|
||||
# Copyright 2013 Pixar
|
||||
#
|
||||
Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
https://opensubdiv.org/license.
|
||||
#
|
||||
|
||||
import maya.OpenMaya as OpenMaya
|
||||
|
||||
selectionList = OpenMaya.MSelectionList()
|
||||
OpenMaya.MGlobal.getActiveSelectionList(selectionList)
|
||||
|
||||
path = OpenMaya.MDagPath()
|
||||
selectionList.getDagPath(0, path)
|
||||
|
||||
meshFn = OpenMaya.MFnMesh(path)
|
||||
|
||||
points = OpenMaya.MPointArray()
|
||||
normals = OpenMaya.MFloatVectorArray()
|
||||
u = OpenMaya.MFloatArray()
|
||||
v = OpenMaya.MFloatArray()
|
||||
meshFn.getPoints(points)
|
||||
meshFn.getVertexNormals(True, normals);
|
||||
meshFn.getUVs(u, v, "map1")
|
||||
vertexCount = OpenMaya.MIntArray()
|
||||
vertexList = OpenMaya.MIntArray()
|
||||
meshFn.getVertices(vertexCount, vertexList)
|
||||
edgeIds = OpenMaya.MUintArray()
|
||||
edgeCreaseData = OpenMaya.MDoubleArray()
|
||||
vtxIds = OpenMaya.MUintArray()
|
||||
vtxCreaseData = OpenMaya.MDoubleArray()
|
||||
try:
|
||||
meshFn.getCreaseEdges(edgeIds, edgeCreaseData)
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
meshFn.getCreaseVertices(vtxIds, vtxCreaseData)
|
||||
except:
|
||||
pass
|
||||
|
||||
f = open('out.obj', 'w')
|
||||
|
||||
for i in range(0,points.length()):
|
||||
f.write('v %f %f %f\n' % (points[i].x, points[i].y, points[i].z))
|
||||
|
||||
for i in range(0,u.length()):
|
||||
f.write('vt %f %f \n' % (u[i], v[i]))
|
||||
|
||||
for i in range(0,normals.length()):
|
||||
f.write('vn %f %f %f\n' % (normals[i].x, normals[i].y, normals[i].z))
|
||||
|
||||
f.write('s off\n')
|
||||
|
||||
vindex = 0
|
||||
for i in range(0,vertexCount.length()):
|
||||
f.write('f')
|
||||
for j in range(0, vertexCount[i]):
|
||||
v = vertexList[vindex] + 1
|
||||
|
||||
sutil = OpenMaya.MScriptUtil()
|
||||
sutil.createFromInt(0)
|
||||
uvptr = sutil.asIntPtr()
|
||||
meshFn.getPolygonUVid(i, j, uvptr, 'map1')
|
||||
uv = sutil.getInt(uvptr) + 1
|
||||
|
||||
f.write(' %d/%d/%d' % (v, uv, v))
|
||||
vindex = vindex+1
|
||||
f.write('\n')
|
||||
|
||||
if vtxIds.length() > 0:
|
||||
f.write('t corner %d/%d/0' % (vtxIds.length(), vtxIds.length()))
|
||||
for i in range(0,vtxIds.length()):
|
||||
f.write(' %d' % vtxIds[i])
|
||||
for i in range(0,vtxCreaseData.length()):
|
||||
f.write(' %f' % vtxCreaseData[i])
|
||||
f.write('\n')
|
||||
|
||||
for i in range(0, edgeIds.length()):
|
||||
edgeIt = OpenMaya.MItMeshEdge(path)
|
||||
dummy = OpenMaya.MScriptUtil().asIntPtr()
|
||||
edgeIt.setIndex(edgeIds[i], dummy)
|
||||
faceList = OpenMaya.MIntArray()
|
||||
edgeIt.getConnectedFaces(faceList)
|
||||
vid0 = edgeIt.index(0)
|
||||
vid1 = edgeIt.index(1)
|
||||
|
||||
f.write('t crease 2/1/0 %d %d %f\n' % (vid0, vid1, edgeCreaseData[i]))
|
||||
|
||||
|
||||
f.close()
|
||||
|
||||
BIN
blender-5.2.0/extern/opensubdiv-source/examples/common/font.png
vendored
Normal file
BIN
blender-5.2.0/extern/opensubdiv-source/examples/common/font.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.1 KiB |
4105
blender-5.2.0/extern/opensubdiv-source/examples/common/font_image.cpp
vendored
Normal file
4105
blender-5.2.0/extern/opensubdiv-source/examples/common/font_image.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
30
blender-5.2.0/extern/opensubdiv-source/examples/common/font_image.h
vendored
Normal file
30
blender-5.2.0/extern/opensubdiv-source/examples/common/font_image.h
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef FONT_IMAGE_H
|
||||
#define FONT_IMAGE_H
|
||||
|
||||
#define FONT_TEXTURE_WIDTH 128
|
||||
#define FONT_TEXTURE_HEIGHT 128
|
||||
#define FONT_TEXTURE_COLUMNS 16
|
||||
#define FONT_TEXTURE_ROWS 8
|
||||
#define FONT_CHAR_WIDTH (FONT_TEXTURE_WIDTH/FONT_TEXTURE_COLUMNS)
|
||||
#define FONT_CHAR_HEIGHT (FONT_TEXTURE_HEIGHT/FONT_TEXTURE_ROWS)
|
||||
#define FONT_CHECK_BOX_OFF 0x2
|
||||
#define FONT_CHECK_BOX_ON 0x3
|
||||
#define FONT_RADIO_BUTTON_OFF 0x4
|
||||
#define FONT_RADIO_BUTTON_ON 0x5
|
||||
#define FONT_SLIDER_LEFT 0x10
|
||||
#define FONT_SLIDER_MIDDLE 0x11
|
||||
#define FONT_SLIDER_RIGHT 0x12
|
||||
#define FONT_SLIDER_CURSOR 0x13
|
||||
#define FONT_ARROW_RIGHT 0x14
|
||||
#define FONT_ARROW_DOWN 0x15
|
||||
|
||||
extern unsigned char font_image[];
|
||||
|
||||
#endif // FONT_IMAGE_H
|
||||
213
blender-5.2.0/extern/opensubdiv-source/examples/common/glControlMeshDisplay.cpp
vendored
Normal file
213
blender-5.2.0/extern/opensubdiv-source/examples/common/glControlMeshDisplay.cpp
vendored
Normal file
@@ -0,0 +1,213 @@
|
||||
//
|
||||
// Copyright 2015 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#include "glLoader.h"
|
||||
|
||||
#include "glControlMeshDisplay.h"
|
||||
#include "glUtils.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
GLControlMeshDisplay::GLControlMeshDisplay() :
|
||||
_displayEdges(true), _displayVertices(false),
|
||||
_program(0), _vao(0),
|
||||
_vertSharpness(0), _edgeSharpnessTexture(0), _edgeIndices(0),
|
||||
_numEdges(0), _numPoints(0) {
|
||||
}
|
||||
|
||||
GLControlMeshDisplay::~GLControlMeshDisplay() {
|
||||
if (_program) glDeleteProgram(_program);
|
||||
if (_vertSharpness) glDeleteBuffers(1, &_vertSharpness);
|
||||
if (_edgeSharpnessTexture) glDeleteTextures(1, &_edgeSharpnessTexture);
|
||||
if (_edgeIndices) glDeleteBuffers(1, &_edgeIndices);
|
||||
if (_vao) glDeleteVertexArrays(1, &_vao);
|
||||
}
|
||||
|
||||
bool
|
||||
GLControlMeshDisplay::createProgram() {
|
||||
if (_program != 0) glDeleteProgram(_program);
|
||||
|
||||
const std::string glsl_version = GLUtils::GetShaderVersionInclude();
|
||||
|
||||
static const std::string vsSrc =
|
||||
glsl_version +
|
||||
"in vec3 position; \n"
|
||||
"in float vertSharpness; \n"
|
||||
"out float sharpness; \n"
|
||||
"uniform mat4 mvpMatrix; \n"
|
||||
"void main() { \n"
|
||||
" sharpness = vertSharpness; \n"
|
||||
" gl_Position = mvpMatrix * vec4(position, 1); \n"
|
||||
"} \n";
|
||||
|
||||
static const std::string fsSrc =
|
||||
glsl_version +
|
||||
"in float sharpness; \n"
|
||||
"out vec4 color; \n"
|
||||
"uniform int drawMode = 0; \n"
|
||||
"uniform samplerBuffer edgeSharpness; \n"
|
||||
"vec4 sharpnessToColor(float s) { \n"
|
||||
" // 0.0 2.0 4.0 \n"
|
||||
" // green --- yellow --- red \n"
|
||||
" return vec4(min(1, s * 0.5), \n"
|
||||
" min(1, 2 - s * 0.5), \n"
|
||||
" 0, 1); \n"
|
||||
"} \n"
|
||||
"void main() { \n"
|
||||
" float sharp = sharpness; \n"
|
||||
" if (drawMode == 1) { \n"
|
||||
" sharp = texelFetch(edgeSharpness, gl_PrimitiveID).x; \n"
|
||||
" } \n"
|
||||
" color = sharpnessToColor(sharp); \n"
|
||||
"} \n";
|
||||
|
||||
GLuint vertexShader =
|
||||
GLUtils::CompileShader(GL_VERTEX_SHADER, vsSrc.c_str());
|
||||
GLuint fragmentShader =
|
||||
GLUtils::CompileShader(GL_FRAGMENT_SHADER, fsSrc.c_str());
|
||||
|
||||
_program = glCreateProgram();
|
||||
glAttachShader(_program, vertexShader);
|
||||
glAttachShader(_program, fragmentShader);
|
||||
glLinkProgram(_program);
|
||||
|
||||
GLint status;
|
||||
glGetProgramiv(_program, GL_LINK_STATUS, &status);
|
||||
if (status == GL_FALSE) {
|
||||
GLint infoLogLength;
|
||||
glGetProgramiv(_program, GL_INFO_LOG_LENGTH, &infoLogLength);
|
||||
char *infoLog = new char[infoLogLength];
|
||||
glGetProgramInfoLog(_program, infoLogLength, NULL, infoLog);
|
||||
printf("%s\n", infoLog);
|
||||
delete[] infoLog;
|
||||
exit(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
_uniformMvpMatrix =
|
||||
glGetUniformLocation(_program, "mvpMatrix");
|
||||
_uniformDrawMode =
|
||||
glGetUniformLocation(_program, "drawMode");
|
||||
_uniformEdgeSharpness =
|
||||
glGetUniformLocation(_program, "edgeSharpness");
|
||||
|
||||
_attrPosition = glGetAttribLocation(_program, "position");
|
||||
_attrVertSharpness = glGetAttribLocation(_program, "vertSharpness");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
GLControlMeshDisplay::Draw(GLuint vbo, GLint stride,
|
||||
const float *modelViewProjectionMatrix) {
|
||||
if (_program == 0) {
|
||||
createProgram();
|
||||
if (_program == 0) return;
|
||||
}
|
||||
|
||||
if (_vao == 0) {
|
||||
glGenVertexArrays(1, &_vao);
|
||||
}
|
||||
glBindVertexArray(_vao);
|
||||
|
||||
glUseProgram(_program);
|
||||
|
||||
glUniformMatrix4fv(_uniformMvpMatrix,
|
||||
1, GL_FALSE, modelViewProjectionMatrix);
|
||||
glUniform1i(_uniformEdgeSharpness, 0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, _edgeSharpnessTexture);
|
||||
|
||||
// bind vbo to points
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
glVertexAttribPointer(_attrPosition, 3, GL_FLOAT, GL_FALSE, stride, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vertSharpness);
|
||||
glVertexAttribPointer(_attrVertSharpness, 1, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
|
||||
glPointSize(10.0);
|
||||
|
||||
// draw edges
|
||||
if (_displayEdges) {
|
||||
glUniform1i(_uniformDrawMode, 1);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _edgeIndices);
|
||||
glDrawElements(GL_LINES, _numEdges*2, GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
|
||||
// draw vertices
|
||||
if (_displayVertices) {
|
||||
glUniform1i(_uniformDrawMode, 0);
|
||||
glDrawArrays(GL_POINTS, 0, _numPoints);
|
||||
}
|
||||
|
||||
glPointSize(1.0f);
|
||||
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
void
|
||||
GLControlMeshDisplay::SetTopology(OpenSubdiv::Far::TopologyLevel const &level) {
|
||||
int nEdges = level.GetNumEdges();
|
||||
int nVerts = level.GetNumVertices();
|
||||
|
||||
std::vector<int> edgeIndices;
|
||||
std::vector<float> edgeSharpnesses;
|
||||
std::vector<float> vertSharpnesses;
|
||||
|
||||
edgeIndices.reserve(nEdges * 2);
|
||||
edgeSharpnesses.reserve(nEdges);
|
||||
vertSharpnesses.reserve(nVerts);
|
||||
|
||||
for (int i = 0; i < nEdges; ++i) {
|
||||
OpenSubdiv::Far::ConstIndexArray verts = level.GetEdgeVertices(i);
|
||||
edgeIndices.push_back(verts[0]);
|
||||
edgeIndices.push_back(verts[1]);
|
||||
edgeSharpnesses.push_back(level.GetEdgeSharpness(i));
|
||||
}
|
||||
|
||||
for (int i = 0; i < nVerts; ++i) {
|
||||
vertSharpnesses.push_back(level.GetVertexSharpness(i));
|
||||
}
|
||||
|
||||
if (_vertSharpness == 0) glGenBuffers(1, &_vertSharpness);
|
||||
if (_edgeIndices == 0) glGenBuffers(1, &_edgeIndices);
|
||||
if (_edgeSharpnessTexture == 0) glGenTextures(1, &_edgeSharpnessTexture);
|
||||
GLuint buffer = 0;
|
||||
glGenBuffers(1, &buffer);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vertSharpness);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*nVerts,
|
||||
&vertSharpnesses[0], GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _edgeIndices);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(int)*nEdges*2,
|
||||
&edgeIndices[0], GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*nEdges,
|
||||
&edgeSharpnesses[0], GL_STATIC_DRAW);
|
||||
|
||||
glBindTexture(GL_TEXTURE_BUFFER, _edgeSharpnessTexture);
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, buffer);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
glDeleteBuffers(1, &buffer);
|
||||
|
||||
_numEdges = nEdges;
|
||||
_numPoints = nVerts;
|
||||
}
|
||||
|
||||
51
blender-5.2.0/extern/opensubdiv-source/examples/common/glControlMeshDisplay.h
vendored
Normal file
51
blender-5.2.0/extern/opensubdiv-source/examples/common/glControlMeshDisplay.h
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// Copyright 2015 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef OPENSUBDIV_EXAMPLES_GL_CONTROL_MESH_DISPLAY_H
|
||||
#define OPENSUBDIV_EXAMPLES_GL_CONTROL_MESH_DISPLAY_H
|
||||
|
||||
#include "glLoader.h"
|
||||
|
||||
#include <opensubdiv/far/topologyLevel.h>
|
||||
|
||||
class GLControlMeshDisplay {
|
||||
public:
|
||||
GLControlMeshDisplay();
|
||||
~GLControlMeshDisplay();
|
||||
|
||||
void Draw(GLuint pointsVBO, GLint stride,
|
||||
const float *modelViewProjectionMatrix);
|
||||
|
||||
void SetTopology(OpenSubdiv::Far::TopologyLevel const &level);
|
||||
|
||||
bool GetEdgesDisplay() const { return _displayEdges; }
|
||||
void SetEdgesDisplay(bool display) { _displayEdges = display; }
|
||||
bool GetVerticesDisplay() const { return _displayVertices; }
|
||||
void SetVerticesDisplay(bool display) { _displayVertices = display; }
|
||||
|
||||
private:
|
||||
bool createProgram();
|
||||
|
||||
bool _displayEdges;
|
||||
bool _displayVertices;
|
||||
|
||||
GLuint _program;
|
||||
GLuint _uniformMvpMatrix;
|
||||
GLuint _uniformDrawMode;
|
||||
GLuint _uniformEdgeSharpness;
|
||||
GLuint _attrPosition;
|
||||
GLuint _attrVertSharpness;
|
||||
|
||||
GLuint _vao;
|
||||
GLuint _vertSharpness;
|
||||
GLuint _edgeSharpnessTexture;
|
||||
GLuint _edgeIndices;
|
||||
|
||||
int _numEdges, _numPoints;
|
||||
};
|
||||
|
||||
#endif // OPENSUBDIV_EXAMPLES_GL_CONTROL_MESH_DISPLAY_H
|
||||
295
blender-5.2.0/extern/opensubdiv-source/examples/common/glHud.cpp
vendored
Normal file
295
blender-5.2.0/extern/opensubdiv-source/examples/common/glHud.cpp
vendored
Normal file
@@ -0,0 +1,295 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#include "glLoader.h"
|
||||
|
||||
#include "glHud.h"
|
||||
#include "glUtils.h"
|
||||
|
||||
#include "font_image.h"
|
||||
#include "simple_math.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
static const char *s_VS =
|
||||
#if defined(GL_VERSION_3_1)
|
||||
"#version 150\n"
|
||||
"in vec2 position;\n"
|
||||
"in vec3 color;\n"
|
||||
"in vec2 uv;\n"
|
||||
"out vec4 fragColor;\n"
|
||||
"out vec2 fragUV;\n"
|
||||
"uniform mat4 ModelViewProjectionMatrix;\n"
|
||||
"void main() {\n"
|
||||
" fragColor = vec4(color, 1);\n"
|
||||
" fragUV = uv;\n"
|
||||
" gl_Position = ModelViewProjectionMatrix * "
|
||||
" vec4(position.x, position.y, 0, 1);\n"
|
||||
"}\n";
|
||||
#else
|
||||
"attribute vec2 position;\n"
|
||||
"attribute vec3 color;\n"
|
||||
"attribute vec2 uv;\n"
|
||||
"varying vec4 fragColor;\n"
|
||||
"varying vec2 fragUV;\n"
|
||||
"uniform mat4 ModelViewProjectionMatrix;\n"
|
||||
"void main() {\n"
|
||||
" fragColor = vec4(color, 1);\n"
|
||||
" fragUV = uv;\n"
|
||||
" gl_Position = ModelViewProjectionMatrix * "
|
||||
" vec4(position.x, position.y, 0, 1);\n"
|
||||
"}\n";
|
||||
#endif
|
||||
|
||||
static const char *s_FS =
|
||||
#if defined(GL_VERSION_3_1)
|
||||
"#version 150\n"
|
||||
"in vec4 fragColor;\n"
|
||||
"in vec2 fragUV;\n"
|
||||
"out vec4 color;\n"
|
||||
"uniform sampler2D fontTexture;\n"
|
||||
"void main() {\n"
|
||||
" vec4 c = texture(fontTexture, fragUV);\n"
|
||||
" if (c.a == 0.0) discard;\n"
|
||||
" color = c*fragColor;\n"
|
||||
"}\n";
|
||||
#else
|
||||
"varying vec4 fragColor;\n"
|
||||
"varying vec2 fragUV;\n"
|
||||
"uniform sampler2D fontTexture;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vec4 c = texture2D(fontTexture, fragUV);\n"
|
||||
" if (c.a == 0.0) discard;\n"
|
||||
" gl_FragColor = c*fragColor;\n"
|
||||
"}\n";
|
||||
#endif
|
||||
|
||||
static const char *s_BG_VS =
|
||||
#if defined(GL_VERSION_3_1)
|
||||
"#version 150\n"
|
||||
"out vec2 uv;\n"
|
||||
"void main() {\n"
|
||||
" vec4 pos[4] = vec4[] (vec4(-1,-1,0,1), vec4(1,-1,0,1), \n"
|
||||
" vec4(-1,1,0,1), vec4(1,1,0,1)); \n"
|
||||
" uv = pos[gl_VertexID].xy;\n"
|
||||
" gl_Position = pos[gl_VertexID];\n"
|
||||
"}\n";
|
||||
#else
|
||||
"varying vec2 uv;\n"
|
||||
"void main() {\n"
|
||||
" vec4 pos[4] = vec4[] (vec4(-1,-1,0,1), vec4(1,-1,0,1), \n"
|
||||
" vec4(-1,1,0,1), vec4(1,1,0,1)); \n"
|
||||
" uv = pos[gl_VertexID].xy;\n"
|
||||
" gl_Position = pos[gl_VertexID];\n"
|
||||
"}\n";
|
||||
#endif
|
||||
|
||||
static const char *s_BG_FS =
|
||||
#if defined(GL_VERSION_3_1)
|
||||
"#version 150\n"
|
||||
"in vec2 uv;\n"
|
||||
"out vec4 color;\n"
|
||||
"void main() {\n"
|
||||
" color = vec4(mix(0.1, 0.5, sin((uv.y*0.5+0.5)*3.14159)));\n"
|
||||
" color.a = 1.0;\n"
|
||||
"}\n";
|
||||
#else
|
||||
"varying vec2 uv;\n"
|
||||
"void main() {\n"
|
||||
" gl_FragColor = vec4(mix(0.1, 0.5, sin((uv.y*0.5+0.5)*3.14159)));\n"
|
||||
" gl_FragColor.a = 1.0;\n"
|
||||
"}\n";
|
||||
#endif
|
||||
|
||||
GLhud::GLhud() : _fontTexture(0), _vbo(0), _staticVbo(0),
|
||||
_vao(0), _staticVao(0), _program(0),
|
||||
_aPosition(0), _aColor(0), _aUV(0), _bgProgram(0) {
|
||||
}
|
||||
|
||||
GLhud::~GLhud() {
|
||||
if (_program)
|
||||
glDeleteProgram(_program);
|
||||
if (_fontTexture)
|
||||
glDeleteTextures(1, &_fontTexture);
|
||||
if (_vbo)
|
||||
glDeleteBuffers(1, &_vbo);
|
||||
if (_staticVbo)
|
||||
glDeleteBuffers(1, &_staticVbo);
|
||||
if (_vao)
|
||||
glDeleteVertexArrays(1, &_vao);
|
||||
if (_staticVao)
|
||||
glDeleteVertexArrays(1, &_staticVao);
|
||||
if (_bgVao)
|
||||
glDeleteVertexArrays(1, &_bgVao);
|
||||
if (_bgProgram)
|
||||
glDeleteProgram(_bgProgram);
|
||||
}
|
||||
|
||||
void
|
||||
GLhud::Init(int width, int height, int frameBufferWidth, int frameBufferHeight) {
|
||||
Hud::Init(width, height, frameBufferWidth, frameBufferHeight);
|
||||
|
||||
glGenTextures(1, &_fontTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, _fontTexture);
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
|
||||
FONT_TEXTURE_WIDTH, FONT_TEXTURE_HEIGHT,
|
||||
0, GL_RGBA, GL_UNSIGNED_BYTE, font_image);
|
||||
|
||||
glGenBuffers(1, &_vbo);
|
||||
glGenBuffers(1, &_staticVbo);
|
||||
|
||||
glGenVertexArrays(1, &_vao);
|
||||
glGenVertexArrays(1, &_staticVao);
|
||||
glGenVertexArrays(1, &_bgVao);
|
||||
|
||||
GLuint vertexShader = GLUtils::CompileShader(GL_VERTEX_SHADER, s_VS);
|
||||
GLuint fragmentShader = GLUtils::CompileShader(GL_FRAGMENT_SHADER, s_FS);
|
||||
|
||||
_program = glCreateProgram();
|
||||
glAttachShader(_program, vertexShader);
|
||||
glAttachShader(_program, fragmentShader);
|
||||
|
||||
glLinkProgram(_program);
|
||||
|
||||
glDeleteShader(vertexShader);
|
||||
glDeleteShader(fragmentShader);
|
||||
|
||||
GLint status;
|
||||
glGetProgramiv(_program, GL_LINK_STATUS, &status);
|
||||
if (status == GL_FALSE) {
|
||||
GLint infoLogLength;
|
||||
glGetProgramiv(_program, GL_INFO_LOG_LENGTH, &infoLogLength);
|
||||
char *infoLog = new char[infoLogLength];
|
||||
glGetProgramInfoLog(_program, infoLogLength, NULL, infoLog);
|
||||
printf("%s\n", infoLog);
|
||||
delete[] infoLog;
|
||||
}
|
||||
|
||||
_mvpMatrix = glGetUniformLocation(_program, "ModelViewProjectionMatrix");
|
||||
_aPosition = glGetAttribLocation(_program, "position");
|
||||
_aColor = glGetAttribLocation(_program, "color");
|
||||
_aUV = glGetAttribLocation(_program, "uv");
|
||||
|
||||
glBindVertexArray(_vao);
|
||||
glEnableVertexAttribArray(_aPosition);
|
||||
glEnableVertexAttribArray(_aColor);
|
||||
glEnableVertexAttribArray(_aUV);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
glVertexAttribPointer(_aPosition, 2, GL_FLOAT, GL_FALSE,
|
||||
sizeof(GLfloat)*7, (void*)0);
|
||||
glVertexAttribPointer(_aColor, 3, GL_FLOAT, GL_FALSE,
|
||||
sizeof(GLfloat)*7, (void*)(sizeof(GLfloat)*2));
|
||||
glVertexAttribPointer(_aUV, 2, GL_FLOAT, GL_FALSE,
|
||||
sizeof(GLfloat)*7, (void*)(sizeof(GLfloat)*5));
|
||||
|
||||
glBindVertexArray(_staticVao);
|
||||
glEnableVertexAttribArray(_aPosition);
|
||||
glEnableVertexAttribArray(_aColor);
|
||||
glEnableVertexAttribArray(_aUV);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _staticVbo);
|
||||
glVertexAttribPointer(_aPosition, 2, GL_FLOAT, GL_FALSE,
|
||||
sizeof(GLfloat)*7, (void*)0);
|
||||
glVertexAttribPointer(_aColor, 3, GL_FLOAT, GL_FALSE,
|
||||
sizeof(GLfloat)*7, (void*)(sizeof(GLfloat)*2));
|
||||
glVertexAttribPointer(_aUV, 2, GL_FLOAT, GL_FALSE,
|
||||
sizeof(GLfloat)*7, (void*)(sizeof(GLfloat)*5));
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
// ------ create bg program
|
||||
vertexShader = GLUtils::CompileShader(GL_VERTEX_SHADER, s_BG_VS);
|
||||
fragmentShader = GLUtils::CompileShader(GL_FRAGMENT_SHADER, s_BG_FS);
|
||||
|
||||
_bgProgram = glCreateProgram();
|
||||
glAttachShader(_bgProgram, vertexShader);
|
||||
glAttachShader(_bgProgram, fragmentShader);
|
||||
|
||||
glLinkProgram(_bgProgram);
|
||||
|
||||
GLUtils::CheckGLErrors("GLhud::Init");
|
||||
}
|
||||
|
||||
void
|
||||
GLhud::Rebuild(int width, int height,
|
||||
int framebufferWidth, int framebufferHeight) {
|
||||
Hud::Rebuild(width, height, framebufferWidth, framebufferHeight);
|
||||
|
||||
if (! _staticVbo)
|
||||
return;
|
||||
|
||||
_staticVboSize = (int)getStaticVboSource().size();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _staticVbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, _staticVboSize * sizeof(float),
|
||||
&getStaticVboSource()[0], GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
bool
|
||||
GLhud::Flush() {
|
||||
if (!Hud::Flush())
|
||||
return false;
|
||||
|
||||
// update dynamic text
|
||||
glBindVertexArray(_vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, getVboSource().size() * sizeof(float),
|
||||
&getVboSource()[0], GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
// (x, y, r, g, b, u, v) = 7
|
||||
int numVertices = (int)getVboSource().size()/7;
|
||||
|
||||
// reserved space of the vector remains for the next frame.
|
||||
getVboSource().clear();
|
||||
glUseProgram(_program);
|
||||
float proj[16];
|
||||
ortho(proj, 0, 0, float(GetWidth()), float(GetHeight()));
|
||||
glUniformMatrix4fv(_mvpMatrix, 1, GL_FALSE, proj);
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, _fontTexture);
|
||||
|
||||
glBindVertexArray(_vao);
|
||||
glDrawArrays(GL_TRIANGLES, 0, numVertices);
|
||||
|
||||
glBindVertexArray(_staticVao);
|
||||
glDrawArrays(GL_TRIANGLES, 0, _staticVboSize/7);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
GLhud::FillBackground() {
|
||||
glUseProgram(_bgProgram);
|
||||
glBindVertexArray(_bgVao);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
glUseProgram(0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
46
blender-5.2.0/extern/opensubdiv-source/examples/common/glHud.h
vendored
Normal file
46
blender-5.2.0/extern/opensubdiv-source/examples/common/glHud.h
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef OPENSUBDIV_EXAMPLES_GL_HUD_H
|
||||
#define OPENSUBDIV_EXAMPLES_GL_HUD_H
|
||||
|
||||
#include "glLoader.h"
|
||||
|
||||
#include "hud.h"
|
||||
|
||||
class GLhud : public Hud {
|
||||
|
||||
public:
|
||||
GLhud();
|
||||
~GLhud();
|
||||
|
||||
virtual void Init(int width, int height, int framebufferWidth, int framebufferHeight);
|
||||
|
||||
virtual void Rebuild(int width, int height,
|
||||
int framebufferWidth, int framebufferHeight);
|
||||
|
||||
virtual bool Flush();
|
||||
|
||||
GLuint GetFontTexture() const {
|
||||
return _fontTexture;
|
||||
}
|
||||
|
||||
void FillBackground();
|
||||
|
||||
private:
|
||||
GLuint _fontTexture;
|
||||
GLuint _vbo, _staticVbo;
|
||||
GLuint _vao, _staticVao, _bgVao;
|
||||
int _staticVboSize;
|
||||
|
||||
GLint _program;
|
||||
GLint _mvpMatrix;
|
||||
GLint _aPosition, _aColor, _aUV;
|
||||
GLint _bgProgram;
|
||||
};
|
||||
|
||||
#endif // OPENSUBDIV_EXAMPLES_GL_HUD_H
|
||||
143
blender-5.2.0/extern/opensubdiv-source/examples/common/glPtexMipmapTexture.cpp
vendored
Normal file
143
blender-5.2.0/extern/opensubdiv-source/examples/common/glPtexMipmapTexture.cpp
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#include "glLoader.h"
|
||||
|
||||
#include "glPtexMipmapTexture.h"
|
||||
#include "ptexMipmapTextureLoader.h"
|
||||
|
||||
GLPtexMipmapTexture::GLPtexMipmapTexture()
|
||||
: _width(0), _height(0), _depth(0), _layout(0), _texels(0), _memoryUsage(0)
|
||||
{
|
||||
}
|
||||
|
||||
GLPtexMipmapTexture::~GLPtexMipmapTexture()
|
||||
{
|
||||
if (glIsTexture(_layout))
|
||||
glDeleteTextures(1, &_layout);
|
||||
|
||||
if (glIsTexture(_texels))
|
||||
glDeleteTextures(1, &_texels);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
const char *
|
||||
GLPtexMipmapTexture::GetShaderSource()
|
||||
{
|
||||
static const char *ptexShaderSource =
|
||||
#include "glslPtexCommon.gen.h"
|
||||
;
|
||||
return ptexShaderSource;
|
||||
}
|
||||
|
||||
static GLuint
|
||||
genTextureBuffer(GLenum format, GLsizeiptr size, GLvoid const * data)
|
||||
{
|
||||
GLuint buffer = 0;
|
||||
GLuint result = 0;
|
||||
|
||||
#if defined(GL_ARB_direct_state_access)
|
||||
if (OSD_OPENGL_HAS(ARB_direct_state_access)) {
|
||||
glCreateBuffers(1, &buffer);
|
||||
glNamedBufferData(buffer, size, data, GL_STATIC_DRAW);
|
||||
glCreateTextures(GL_TEXTURE_BUFFER, 1, &result);
|
||||
glTextureBuffer(result, format, buffer);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
glGenBuffers(1, &buffer);
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, buffer);
|
||||
glBufferData(GL_TEXTURE_BUFFER, size, data, GL_STATIC_DRAW);
|
||||
|
||||
glGenTextures(1, & result);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, result);
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, format, buffer);
|
||||
|
||||
// need to reset texture binding before deleting the source buffer.
|
||||
glBindTexture(GL_TEXTURE_BUFFER, 0);
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, 0);
|
||||
}
|
||||
|
||||
glDeleteBuffers(1, &buffer);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
GLPtexMipmapTexture *
|
||||
GLPtexMipmapTexture::Create(PtexTexture * reader,
|
||||
int maxLevels,
|
||||
size_t targetMemory)
|
||||
{
|
||||
GLPtexMipmapTexture * result = NULL;
|
||||
|
||||
GLint maxNumPages = 0;
|
||||
glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxNumPages);
|
||||
|
||||
// Read the ptexture data and pack the texels
|
||||
PtexMipmapTextureLoader loader(reader,
|
||||
maxNumPages,
|
||||
maxLevels,
|
||||
targetMemory);
|
||||
|
||||
// Setup GPU memory
|
||||
int numFaces = loader.GetNumFaces();
|
||||
|
||||
GLuint layout = genTextureBuffer(GL_R16I,
|
||||
numFaces * 6 * sizeof(GLshort),
|
||||
loader.GetLayoutBuffer());
|
||||
|
||||
GLenum format, type;
|
||||
switch (reader->dataType()) {
|
||||
case Ptex::dt_uint16 : type = GL_UNSIGNED_SHORT; break;
|
||||
case Ptex::dt_float : type = GL_FLOAT; break;
|
||||
case Ptex::dt_half : type = GL_HALF_FLOAT; break;
|
||||
default : type = GL_UNSIGNED_BYTE; break;
|
||||
}
|
||||
|
||||
switch (reader->numChannels()) {
|
||||
case 1 : format = GL_RED; break;
|
||||
case 2 : format = GL_RG; break;
|
||||
case 3 : format = GL_RGB; break;
|
||||
case 4 : format = GL_RGBA; break;
|
||||
default: format = GL_RED; break;
|
||||
}
|
||||
|
||||
// actual texels texture array
|
||||
GLuint texels;
|
||||
glGenTextures(1, &texels);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, texels);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0,
|
||||
(type == GL_FLOAT) ? GL_RGBA32F : GL_RGBA,
|
||||
loader.GetPageWidth(),
|
||||
loader.GetPageHeight(),
|
||||
loader.GetNumPages(),
|
||||
0, format, type,
|
||||
loader.GetTexelBuffer());
|
||||
|
||||
// loader.ClearBuffers();
|
||||
|
||||
// Return the Osd Ptexture object
|
||||
result = new GLPtexMipmapTexture;
|
||||
|
||||
result->_width = loader.GetPageWidth();
|
||||
result->_height = loader.GetPageHeight();
|
||||
result->_depth = loader.GetNumPages();
|
||||
|
||||
result->_format = format;
|
||||
|
||||
result->_layout = layout;
|
||||
result->_texels = texels;
|
||||
result->_memoryUsage = loader.GetMemoryUsage();
|
||||
|
||||
return result;
|
||||
}
|
||||
54
blender-5.2.0/extern/opensubdiv-source/examples/common/glPtexMipmapTexture.h
vendored
Normal file
54
blender-5.2.0/extern/opensubdiv-source/examples/common/glPtexMipmapTexture.h
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef OPENSUBDIV_EXAMPLES_GL_PTEX_MIPMAP_TEXTURE_H
|
||||
#define OPENSUBDIV_EXAMPLES_GL_PTEX_MIPMAP_TEXTURE_H
|
||||
|
||||
#include "glLoader.h"
|
||||
|
||||
#include <opensubdiv/osd/nonCopyable.h>
|
||||
|
||||
#include <Ptexture.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
class GLPtexMipmapTexture : OpenSubdiv::Osd::NonCopyable<GLPtexMipmapTexture> {
|
||||
public:
|
||||
static GLPtexMipmapTexture * Create(PtexTexture * reader,
|
||||
int maxLevels=-1,
|
||||
size_t targetMemory=0);
|
||||
|
||||
/// Returns GLSL shader snippet to fetch ptex
|
||||
static const char *GetShaderSource();
|
||||
|
||||
/// Returns the texture buffer containing the layout of the ptex faces
|
||||
/// in the texels texture array.
|
||||
GLuint GetLayoutTextureBuffer() const { return _layout; }
|
||||
|
||||
/// Returns the texels texture array.
|
||||
GLuint GetTexelsTexture() const { return _texels; }
|
||||
|
||||
/// Returns the amount of allocated memory (in bytes)
|
||||
size_t GetMemoryUsage() const { return _memoryUsage; }
|
||||
|
||||
~GLPtexMipmapTexture();
|
||||
|
||||
private:
|
||||
GLPtexMipmapTexture();
|
||||
|
||||
GLsizei _width, // width / height / depth of the 3D texel buffer
|
||||
_height,
|
||||
_depth;
|
||||
|
||||
GLint _format; // texel color format
|
||||
|
||||
GLuint _layout, // per-face lookup table
|
||||
_texels; // texel data
|
||||
|
||||
size_t _memoryUsage; // total amount of memory used (estimate)
|
||||
};
|
||||
|
||||
#endif // OPENSUBDIV_EXAMPLES_GL_PTEX_MIPMAP_TEXTURE_H
|
||||
91
blender-5.2.0/extern/opensubdiv-source/examples/common/glShaderCache.cpp
vendored
Normal file
91
blender-5.2.0/extern/opensubdiv-source/examples/common/glShaderCache.cpp
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
//
|
||||
// Copyright 2015 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#include "glLoader.h"
|
||||
|
||||
#include "glShaderCache.h"
|
||||
#include "glUtils.h"
|
||||
|
||||
#include <vector>
|
||||
#include <opensubdiv/far/error.h>
|
||||
|
||||
GLDrawConfig::GLDrawConfig(const std::string &version)
|
||||
: _version(version), _numShaders(0) {
|
||||
_program = glCreateProgram();
|
||||
}
|
||||
|
||||
|
||||
GLDrawConfig::~GLDrawConfig() {
|
||||
if (_program)
|
||||
glDeleteProgram(_program);
|
||||
}
|
||||
|
||||
bool
|
||||
GLDrawConfig::CompileAndAttachShader(GLenum shaderType,
|
||||
const std::string &source) {
|
||||
|
||||
|
||||
GLuint shader = glCreateShader(shaderType);
|
||||
|
||||
#if 0
|
||||
const char *sources[2];
|
||||
sources[0] = _version.c_str();
|
||||
sources[1] = source.c_str();
|
||||
#endif
|
||||
|
||||
std::string sources = _version + source;
|
||||
|
||||
const char *src = sources.c_str();
|
||||
|
||||
glShaderSource(shader, 1, &src, NULL);
|
||||
glCompileShader(shader);
|
||||
|
||||
GLint status;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
||||
if (status == GL_FALSE) {
|
||||
GLint infoLogLength;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
|
||||
char * infoLog = new char[infoLogLength];
|
||||
glGetShaderInfoLog(shader, infoLogLength, NULL, infoLog);
|
||||
OpenSubdiv::Far::Error(OpenSubdiv::Far::FAR_RUNTIME_ERROR,
|
||||
"Error compiling GLSL shader: %s\n",
|
||||
infoLog);
|
||||
delete[] infoLog;
|
||||
return false;
|
||||
}
|
||||
|
||||
glAttachShader(_program, shader);
|
||||
++_numShaders;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GLDrawConfig::Link() {
|
||||
glLinkProgram(_program);
|
||||
|
||||
std::vector<GLuint> shaders(_numShaders);
|
||||
GLsizei count = 0;
|
||||
glGetAttachedShaders(_program, _numShaders, &count, &shaders[0]);
|
||||
for (int i = 0; i < (int)count; ++i) {
|
||||
glDeleteShader(shaders[i]);
|
||||
}
|
||||
|
||||
GLint status;
|
||||
glGetProgramiv(_program, GL_LINK_STATUS, &status );
|
||||
if (status == GL_FALSE) {
|
||||
GLint infoLogLength;
|
||||
glGetProgramiv(_program, GL_INFO_LOG_LENGTH, &infoLogLength);
|
||||
char * infoLog = new char[infoLogLength];
|
||||
glGetProgramInfoLog(_program, infoLogLength, NULL, infoLog);
|
||||
OpenSubdiv::Far::Error(OpenSubdiv::Far::FAR_RUNTIME_ERROR,
|
||||
"Error linking GLSL program: %s\n", infoLog);
|
||||
delete[] infoLog;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
46
blender-5.2.0/extern/opensubdiv-source/examples/common/glShaderCache.h
vendored
Normal file
46
blender-5.2.0/extern/opensubdiv-source/examples/common/glShaderCache.h
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// Copyright 2015 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef OPENSUBDIV_EXAMPLES_GL_SHADER_CACHE_H
|
||||
#define OPENSUBDIV_EXAMPLES_GL_SHADER_CACHE_H
|
||||
|
||||
#include "glLoader.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "./shaderCache.h"
|
||||
|
||||
class GLDrawConfig {
|
||||
public:
|
||||
explicit GLDrawConfig(const std::string &version);
|
||||
~GLDrawConfig();
|
||||
|
||||
bool CompileAndAttachShader(GLenum shaderType, const std::string &source);
|
||||
bool Link();
|
||||
|
||||
GLuint GetProgram() const {
|
||||
return _program;
|
||||
}
|
||||
|
||||
private:
|
||||
GLuint _program;
|
||||
std::string _version;
|
||||
int _numShaders;
|
||||
};
|
||||
|
||||
// workaround for template alias
|
||||
#if 0
|
||||
template <typename DESC_TYPE>
|
||||
using GLShaderCache = ShaderCacheT<DESC_TYPE, GLDrawConfig>;
|
||||
#else
|
||||
template <typename DESC_TYPE>
|
||||
class GLShaderCache : public ShaderCacheT<DESC_TYPE, GLDrawConfig> {
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#endif // OPENSUBDIV_EXAMPLES_GL_SHADER_CACHE_H
|
||||
282
blender-5.2.0/extern/opensubdiv-source/examples/common/glUtils.cpp
vendored
Normal file
282
blender-5.2.0/extern/opensubdiv-source/examples/common/glUtils.cpp
vendored
Normal file
@@ -0,0 +1,282 @@
|
||||
//
|
||||
// Copyright 2015 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#include "glLoader.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
#include "glUtils.h"
|
||||
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION 1
|
||||
#include "stb_image_write.h"
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#if _MSC_VER
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
namespace GLUtils {
|
||||
|
||||
void InitializeGL()
|
||||
{
|
||||
OpenSubdiv::internal::GLLoader::applicationInitializeGL();
|
||||
}
|
||||
|
||||
static void
|
||||
_argParseBool(bool *ret, const char *lbl, int i, int argc, char **argv)
|
||||
{
|
||||
if (i < argc-1) {
|
||||
if (!strcmp(argv[i+1], "on")) {
|
||||
*ret = true;
|
||||
} else if (!strcmp(argv[i+1], "off")) {
|
||||
*ret = false;
|
||||
} else {
|
||||
fprintf(stderr, "Unknown setting for %s: %s\n", lbl, argv[i+1]);
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"Please specify \"on\" or \"off\" for %s.\n", lbl);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SetMinimumGLVersion(int argc, char ** argv) {
|
||||
|
||||
#if defined(__APPLE__)
|
||||
// Here 3.2 is the minimum GL version supported, GLFW will allocate a
|
||||
// higher version if possible. This works on OS X, but instead limits
|
||||
// the version to 3.2 on Linux. On Linux & Windows, specifying no
|
||||
// version hint should use the highest version available.
|
||||
//
|
||||
// http://www.glfw.org/faq.html#how-do-i-create-an-opengl-30-context
|
||||
// http://www.glfw.org/faq.html#what-versions-of-opengl-are-supported-by-glfw
|
||||
bool coreProfile = true;
|
||||
bool forwardCompat = true;
|
||||
bool versionSet = true;
|
||||
int major = 3;
|
||||
int minor = 2;
|
||||
#else
|
||||
bool coreProfile = false;
|
||||
bool forwardCompat = false;
|
||||
bool versionSet = false;
|
||||
int major = 4;
|
||||
int minor = 2;
|
||||
#endif
|
||||
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
|
||||
if (!strcmp(argv[i], "-glCoreProfile")) {
|
||||
_argParseBool(&coreProfile, argv[i], i, argc, argv);
|
||||
}
|
||||
if (!strcmp(argv[i], "-glForwardCompat")) {
|
||||
_argParseBool(&forwardCompat, argv[i], i, argc, argv);
|
||||
}
|
||||
if (!strcmp(argv[i], "-glVersion")) {
|
||||
if (i < argc-1) {
|
||||
char *versionStr = argv[i+1];
|
||||
size_t len = strlen(versionStr);
|
||||
if (len == 3 && versionStr[1] == '.' &&
|
||||
versionStr[0] >= '0' && versionStr[0] <= '9' &&
|
||||
versionStr[2] >= '0' && versionStr[2] <= '9') {
|
||||
|
||||
major = versionStr[0] - '0';
|
||||
minor = versionStr[2] - '0';
|
||||
versionSet = true;
|
||||
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"Invalid version number: %s, please specify a number "
|
||||
"in the format M.n, e.g., -glVersion 4.2.\n",
|
||||
versionStr);
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"Please specify a version number for glVersion "
|
||||
"in the form M.n, e.g., -glVersion 4.2.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (coreProfile) {
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
}
|
||||
|
||||
if (forwardCompat) {
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||
}
|
||||
|
||||
if (versionSet) {
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, major);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, minor);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PrintGLVersion() {
|
||||
std::cout << glGetString(GL_VENDOR) << "\n";
|
||||
std::cout << glGetString(GL_RENDERER) << "\n";
|
||||
std::cout << glGetString(GL_VERSION) << "\n";
|
||||
|
||||
int i = -1;
|
||||
std::cout << "Init OpenGL ";
|
||||
glGetIntegerv(GL_MAJOR_VERSION, &i);
|
||||
std::cout << i << ".";
|
||||
glGetIntegerv(GL_MINOR_VERSION, &i);
|
||||
std::cout << i << "\n";
|
||||
|
||||
CheckGLErrors("PrintGLVersion");
|
||||
}
|
||||
|
||||
void
|
||||
CheckGLErrors(std::string const & where) {
|
||||
GLuint err;
|
||||
while ((err = glGetError()) != GL_NO_ERROR) {
|
||||
std::cerr << "GL error: "
|
||||
<< (where.empty() ? "" : where + " ")
|
||||
<< err << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
GLuint
|
||||
CompileShader(GLenum shaderType, const char *source) {
|
||||
GLuint shader = glCreateShader(shaderType);
|
||||
glShaderSource(shader, 1, &source, NULL);
|
||||
glCompileShader(shader);
|
||||
|
||||
GLint status;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
||||
if (status == GL_FALSE) {
|
||||
GLchar emsg[40960];
|
||||
glGetShaderInfoLog(shader, sizeof(emsg), 0, emsg);
|
||||
fprintf(stderr, "Error compiling GLSL shader: %s\n", emsg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
void
|
||||
WriteScreenshot(int width, int height) {
|
||||
|
||||
std::vector<unsigned char> data(width*height*4 /*RGBA*/);
|
||||
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
|
||||
|
||||
static int counter=0;
|
||||
char fname[64];
|
||||
snprintf(fname, 64, "screenshot.%d.png", counter++);
|
||||
|
||||
// flip vertical
|
||||
stbi_write_png(fname, width, height, 4, &data[width*4*(height-1)], -width*4);
|
||||
|
||||
fprintf(stdout, "Saved %s\n", fname);
|
||||
}
|
||||
|
||||
void GetMajorMinorVersion(int *major, int *minor){
|
||||
const GLubyte *ver = glGetString(GL_SHADING_LANGUAGE_VERSION);
|
||||
if (!ver){
|
||||
*major = -1;
|
||||
*minor = -1;
|
||||
}
|
||||
else{
|
||||
std::stringstream ss;
|
||||
ss << std::string(ver, ver + 1) << " " << std::string(ver + 2, ver + 3);
|
||||
ss >> *major;
|
||||
ss >> *minor;
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
GetShaderVersion(){
|
||||
std::string shader_version;
|
||||
int major, minor;
|
||||
GetMajorMinorVersion(&major, &minor);
|
||||
int version_number = major * 10 + minor;
|
||||
switch (version_number){
|
||||
case 20:
|
||||
shader_version = "110";
|
||||
break;
|
||||
case 21:
|
||||
shader_version = "120";
|
||||
break;
|
||||
case 30:
|
||||
shader_version = "130";
|
||||
break;
|
||||
case 31:
|
||||
shader_version = "140";
|
||||
break;
|
||||
case 32:
|
||||
shader_version = "150";
|
||||
break;
|
||||
default:
|
||||
std::stringstream ss;
|
||||
ss << version_number;
|
||||
shader_version = ss.str() + "0";
|
||||
break;
|
||||
}
|
||||
return shader_version;
|
||||
}
|
||||
|
||||
// Generates the version definition needed by the glsl shaders based on the
|
||||
// opengl string
|
||||
std::string GetShaderVersionInclude(){
|
||||
return "#version " + GetShaderVersion() + "\n";
|
||||
}
|
||||
|
||||
bool SupportsAdaptiveTessellation() {
|
||||
#if defined(GL_VERSION_4_0)
|
||||
if (OSD_OPENGL_HAS(VERSION_4_0)) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#if defined(GL_ARB_tessellation_shader)
|
||||
if (OSD_OPENGL_HAS(ARB_tessellation_shader)) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GL_ARBSeparateShaderObjectsOrGL_VERSION_4_1() {
|
||||
#if defined(GL_VERSION_4_1)
|
||||
if (OSD_OPENGL_HAS(VERSION_4_1)) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#if defined(GL_ARB_separate_shader_objects)
|
||||
if (OSD_OPENGL_HAS(ARB_separate_shader_objects)) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GL_ARBComputeShaderOrGL_VERSION_4_3() {
|
||||
#if defined(GL_VERSION_4_3)
|
||||
if (OSD_OPENGL_HAS(VERSION_4_3)) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#if defined(GL_ARB_compute_shader)
|
||||
if (OSD_OPENGL_HAS(ARB_compute_shader)) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
#undef IS_SUPPORTED
|
||||
|
||||
} // namespace GLUtils
|
||||
51
blender-5.2.0/extern/opensubdiv-source/examples/common/glUtils.h
vendored
Normal file
51
blender-5.2.0/extern/opensubdiv-source/examples/common/glUtils.h
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// Copyright 2015 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef OPENSUBDIV_EXAMPLES_GL_UTILS_H
|
||||
#define OPENSUBDIV_EXAMPLES_GL_UTILS_H
|
||||
|
||||
#include "glLoader.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
namespace GLUtils {
|
||||
|
||||
void InitializeGL();
|
||||
|
||||
void SetMinimumGLVersion(int argc=0, char **argv=NULL);
|
||||
|
||||
void PrintGLVersion();
|
||||
|
||||
void CheckGLErrors(std::string const & where = "");
|
||||
|
||||
GLuint CompileShader(GLenum shaderType, const char *source);
|
||||
|
||||
void WriteScreenshot(int width, int height);
|
||||
|
||||
bool SupportsAdaptiveTessellation();
|
||||
|
||||
// Helper function that parses the opengl version string, retrieving the
|
||||
// major and minor version from it.
|
||||
void GetMajorMinorVersion(int *major, int *minor);
|
||||
|
||||
// Gets the shader version based on the current opengl version and returns
|
||||
// it in a string form.
|
||||
std::string GetShaderVersion();
|
||||
|
||||
std::string GetShaderVersionInclude();
|
||||
|
||||
bool GL_ARBSeparateShaderObjectsOrGL_VERSION_4_1();
|
||||
|
||||
bool GL_ARBComputeShaderOrGL_VERSION_4_3();
|
||||
|
||||
};
|
||||
|
||||
#endif // OPENSUBDIV_EXAMPLES_GL_UTILS_H
|
||||
|
||||
|
||||
337
blender-5.2.0/extern/opensubdiv-source/examples/common/glslPtexCommon.glsl
vendored
Normal file
337
blender-5.2.0/extern/opensubdiv-source/examples/common/glslPtexCommon.glsl
vendored
Normal file
@@ -0,0 +1,337 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
//----------------------------------------------------------
|
||||
// Ptex.Common
|
||||
//----------------------------------------------------------
|
||||
|
||||
struct PtexPacking {
|
||||
int page;
|
||||
int nMipmap;
|
||||
int uOffset;
|
||||
int vOffset;
|
||||
int adjSizeDiffs[4];
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
PtexPacking getPtexPacking(isamplerBuffer packings, int faceID)
|
||||
{
|
||||
PtexPacking packing;
|
||||
packing.page = texelFetch(packings, faceID*6).x;
|
||||
packing.nMipmap = texelFetch(packings, faceID*6+1).x;
|
||||
packing.uOffset = texelFetch(packings, faceID*6+2).x;
|
||||
packing.vOffset = texelFetch(packings, faceID*6+3).x;
|
||||
int wh = texelFetch(packings, faceID*6+5).x;
|
||||
packing.width = 1 << (wh >> 8);
|
||||
packing.height = 1 << (wh & 0xff);
|
||||
|
||||
int adjSizeDiffs = texelFetch(packings, faceID*6+4).x;
|
||||
packing.adjSizeDiffs[0] = (adjSizeDiffs >> 12) & 0xf;
|
||||
packing.adjSizeDiffs[1] = (adjSizeDiffs >> 8) & 0xf;
|
||||
packing.adjSizeDiffs[2] = (adjSizeDiffs >> 4) & 0xf;
|
||||
packing.adjSizeDiffs[3] = (adjSizeDiffs >> 0) & 0xf;
|
||||
|
||||
return packing;
|
||||
}
|
||||
|
||||
int computeMipmapOffsetU(int w, int level)
|
||||
{
|
||||
int width = 1 << w;
|
||||
int m = (0x55555555 & (width | (width-1))) << (w&1);
|
||||
int x = ~((1 << (w -((level-1)&~1))) - 1);
|
||||
return (m & x) + ((level+1)&~1);
|
||||
}
|
||||
|
||||
int computeMipmapOffsetV(int h, int level)
|
||||
{
|
||||
int height = 1 << h;
|
||||
int m = (0x55555555 & (height-1)) << ((h+1)&1);;
|
||||
int x = ~((1 << (h - (level&~1))) - 1 );
|
||||
return (m & x) + (level&~1);
|
||||
}
|
||||
|
||||
PtexPacking getPtexPacking(isamplerBuffer packings, int faceID, int level)
|
||||
{
|
||||
PtexPacking packing;
|
||||
packing.page = texelFetch(packings, faceID*6).x;
|
||||
packing.nMipmap = texelFetch(packings, faceID*6+1).x;
|
||||
packing.uOffset = texelFetch(packings, faceID*6+2).x;
|
||||
packing.vOffset = texelFetch(packings, faceID*6+3).x;
|
||||
int sizeDiffs = texelFetch(packings, faceID*6+4).x;
|
||||
int wh = texelFetch(packings, faceID*6+5).x;
|
||||
int w = wh >> 8;
|
||||
int h = wh & 0xff;
|
||||
|
||||
// clamp max level
|
||||
level = min(level, packing.nMipmap);
|
||||
|
||||
packing.uOffset += computeMipmapOffsetU(w, level);
|
||||
packing.vOffset += computeMipmapOffsetV(h, level);
|
||||
packing.width = 1 << (w-level);
|
||||
packing.height = 1 << (h-level);
|
||||
|
||||
return packing;
|
||||
}
|
||||
|
||||
void evalQuadraticBSpline(float u, out float B[3], out float BU[3])
|
||||
{
|
||||
B[0] = 0.5 * (u*u - 2.0*u + 1);
|
||||
B[1] = 0.5 + u - u*u;
|
||||
B[2] = 0.5 * u*u;
|
||||
|
||||
BU[0] = u - 1.0;
|
||||
BU[1] = 1 - 2 * u;
|
||||
BU[2] = u;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Non-Mipmap Lookups
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
vec4 PtexLookupNearest(vec4 patchCoord,
|
||||
sampler2DArray data,
|
||||
isamplerBuffer packings)
|
||||
{
|
||||
vec2 uv = clamp(patchCoord.xy, vec2(0), vec2(1));
|
||||
int faceID = int(patchCoord.w);
|
||||
PtexPacking ppack = getPtexPacking(packings, faceID);
|
||||
vec2 coords = vec2(uv.x * ppack.width + ppack.uOffset,
|
||||
uv.y * ppack.height + ppack.vOffset);
|
||||
return texelFetch(data, ivec3(int(coords.x), int(coords.y), ppack.page), 0);
|
||||
}
|
||||
|
||||
vec4 PtexLookupNearest(vec4 patchCoord,
|
||||
int level,
|
||||
sampler2DArray data,
|
||||
isamplerBuffer packings)
|
||||
{
|
||||
vec2 uv = clamp(patchCoord.xy, vec2(0), vec2(1));
|
||||
int faceID = int(patchCoord.w);
|
||||
PtexPacking ppack = getPtexPacking(packings, faceID, level);
|
||||
vec2 coords = vec2(uv.x * ppack.width + ppack.uOffset,
|
||||
uv.y * ppack.height + ppack.vOffset);
|
||||
return texelFetch(data, ivec3(int(coords.x), int(coords.y), ppack.page), 0);
|
||||
}
|
||||
|
||||
vec4 PtexLookupFast(vec4 patchCoord,
|
||||
sampler2DArray data,
|
||||
isamplerBuffer packings)
|
||||
{
|
||||
vec2 uv = clamp(patchCoord.xy, vec2(0), vec2(1));
|
||||
int faceID = int(patchCoord.w);
|
||||
PtexPacking ppack = getPtexPacking(packings, faceID);
|
||||
|
||||
ivec3 size = textureSize(data, 0);
|
||||
vec2 coords = vec2((uv.x * ppack.width + ppack.uOffset)/size.x,
|
||||
(uv.y * ppack.height + ppack.vOffset)/size.y);
|
||||
return texture(data, vec3(coords.x, coords.y, ppack.page));
|
||||
}
|
||||
|
||||
vec4 PtexLookupFast(vec4 patchCoord,
|
||||
int level,
|
||||
sampler2DArray data,
|
||||
isamplerBuffer packings)
|
||||
{
|
||||
vec2 uv = clamp(patchCoord.xy, vec2(0), vec2(1));
|
||||
int faceID = int(patchCoord.w);
|
||||
PtexPacking ppack = getPtexPacking(packings, faceID, level);
|
||||
|
||||
ivec3 size = textureSize(data, 0);
|
||||
vec2 coords = vec2((uv.x * ppack.width + ppack.uOffset)/size.x,
|
||||
(uv.y * ppack.height + ppack.vOffset)/size.y);
|
||||
return texture(data, vec3(coords.x, coords.y, ppack.page));
|
||||
}
|
||||
|
||||
vec4 PtexLookup(vec4 patchCoord,
|
||||
int level,
|
||||
sampler2DArray data,
|
||||
isamplerBuffer packings)
|
||||
{
|
||||
vec2 uv = clamp(patchCoord.xy, vec2(0), vec2(1));
|
||||
int faceID = int(patchCoord.w);
|
||||
PtexPacking ppack = getPtexPacking(packings, faceID, level);
|
||||
|
||||
vec2 coords = vec2(uv.x * ppack.width + ppack.uOffset,
|
||||
uv.y * ppack.height + ppack.vOffset);
|
||||
|
||||
coords -= vec2(0.5, 0.5);
|
||||
|
||||
int c0X = int(floor(coords.x));
|
||||
int c1X = int(ceil(coords.x));
|
||||
int c0Y = int(floor(coords.y));
|
||||
int c1Y = int(ceil(coords.y));
|
||||
|
||||
float t = coords.x - float(c0X);
|
||||
float s = coords.y - float(c0Y);
|
||||
|
||||
vec4 d0 = texelFetch(data, ivec3(c0X, c0Y, ppack.page), 0);
|
||||
vec4 d1 = texelFetch(data, ivec3(c0X, c1Y, ppack.page), 0);
|
||||
vec4 d2 = texelFetch(data, ivec3(c1X, c0Y, ppack.page), 0);
|
||||
vec4 d3 = texelFetch(data, ivec3(c1X, c1Y, ppack.page), 0);
|
||||
|
||||
vec4 result = (1-t) * ((1-s)*d0 + s*d1) + t * ((1-s)*d2 + s*d3);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
vec4 PtexLookupQuadratic(out vec4 du,
|
||||
out vec4 dv,
|
||||
vec4 patchCoord,
|
||||
int level,
|
||||
sampler2DArray data,
|
||||
isamplerBuffer packings)
|
||||
{
|
||||
vec2 uv = clamp(patchCoord.xy, vec2(0), vec2(1));
|
||||
int faceID = int(patchCoord.w);
|
||||
PtexPacking ppack = getPtexPacking(packings, faceID, level);
|
||||
|
||||
vec2 coords = vec2(uv.x * ppack.width + ppack.uOffset,
|
||||
uv.y * ppack.height + ppack.vOffset);
|
||||
|
||||
coords -= vec2(0.5, 0.5);
|
||||
|
||||
int cX = int(round(coords.x));
|
||||
int cY = int(round(coords.y));
|
||||
|
||||
float x = 0.5 - (float(cX) - coords.x);
|
||||
float y = 0.5 - (float(cY) - coords.y);
|
||||
|
||||
vec4 d[9];
|
||||
d[0] = texelFetch(data, ivec3(cX-1, cY-1, ppack.page), 0);
|
||||
d[1] = texelFetch(data, ivec3(cX-1, cY-0, ppack.page), 0);
|
||||
d[2] = texelFetch(data, ivec3(cX-1, cY+1, ppack.page), 0);
|
||||
d[3] = texelFetch(data, ivec3(cX-0, cY-1, ppack.page), 0);
|
||||
d[4] = texelFetch(data, ivec3(cX-0, cY-0, ppack.page), 0);
|
||||
d[5] = texelFetch(data, ivec3(cX-0, cY+1, ppack.page), 0);
|
||||
d[6] = texelFetch(data, ivec3(cX+1, cY-1, ppack.page), 0);
|
||||
d[7] = texelFetch(data, ivec3(cX+1, cY-0, ppack.page), 0);
|
||||
d[8] = texelFetch(data, ivec3(cX+1, cY+1, ppack.page), 0);
|
||||
|
||||
float B[3], D[3];
|
||||
vec4 BUCP[3] = vec4[3](vec4(0,0,0,0), vec4(0,0,0,0), vec4(0,0,0,0)),
|
||||
DUCP[3] = vec4[3](vec4(0,0,0,0), vec4(0,0,0,0), vec4(0,0,0,0));
|
||||
evalQuadraticBSpline(y, B, D);
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
vec4 A = d[i*3+j];
|
||||
BUCP[i] += A * B[j];
|
||||
DUCP[i] += A * D[j];
|
||||
}
|
||||
}
|
||||
|
||||
evalQuadraticBSpline(x, B, D);
|
||||
|
||||
vec4 result = vec4(0);
|
||||
du = vec4(0);
|
||||
dv = vec4(0);
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
result += B[i] * BUCP[i];
|
||||
du += D[i] * BUCP[i];
|
||||
dv += B[i] * DUCP[i];
|
||||
}
|
||||
|
||||
du *= ppack.width;
|
||||
dv *= ppack.height;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// MipMap Lookups
|
||||
// ----------------------------------------------------------------------------
|
||||
vec4 PtexMipmapLookupNearest(vec4 patchCoord,
|
||||
float level,
|
||||
sampler2DArray data,
|
||||
isamplerBuffer packings)
|
||||
{
|
||||
#if defined(SEAMLESS_MIPMAP)
|
||||
// diff level
|
||||
int faceID = int(patchCoord.w);
|
||||
vec2 uv = patchCoord.xy;
|
||||
PtexPacking packing = getPtexPacking(packings, faceID);
|
||||
level += mix(mix(packing.adjSizeDiffs[0], packing.adjSizeDiffs[1], uv.x),
|
||||
mix(packing.adjSizeDiffs[3], packing.adjSizeDiffs[2], uv.x),
|
||||
uv.y);
|
||||
#endif
|
||||
|
||||
int levelm = int(floor(level));
|
||||
int levelp = int(ceil(level));
|
||||
float t = level - float(levelm);
|
||||
|
||||
vec4 result = (1-t) * PtexLookupNearest(patchCoord, levelm, data, packings)
|
||||
+ t * PtexLookupNearest(patchCoord, levelp, data, packings);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
vec4 PtexMipmapLookup(vec4 patchCoord,
|
||||
float level,
|
||||
sampler2DArray data,
|
||||
isamplerBuffer packings)
|
||||
{
|
||||
#if defined(SEAMLESS_MIPMAP)
|
||||
// diff level
|
||||
int faceID = int(patchCoord.w);
|
||||
vec2 uv = patchCoord.xy;
|
||||
PtexPacking packing = getPtexPacking(packings, faceID);
|
||||
level += mix(mix(packing.adjSizeDiffs[0], packing.adjSizeDiffs[1], uv.x),
|
||||
mix(packing.adjSizeDiffs[3], packing.adjSizeDiffs[2], uv.x),
|
||||
uv.y);
|
||||
#endif
|
||||
|
||||
int levelm = int(floor(level));
|
||||
int levelp = int(ceil(level));
|
||||
float t = level - float(levelm);
|
||||
|
||||
vec4 result = (1-t) * PtexLookup(patchCoord, levelm, data, packings)
|
||||
+ t * PtexLookup(patchCoord, levelp, data, packings);
|
||||
return result;
|
||||
}
|
||||
|
||||
vec4 PtexMipmapLookupQuadratic(out vec4 du,
|
||||
out vec4 dv,
|
||||
vec4 patchCoord,
|
||||
float level,
|
||||
sampler2DArray data,
|
||||
isamplerBuffer packings)
|
||||
{
|
||||
#if defined(SEAMLESS_MIPMAP)
|
||||
// diff level
|
||||
int faceID = int(patchCoord.w);
|
||||
vec2 uv = patchCoord.xy;
|
||||
PtexPacking packing = getPtexPacking(packings, faceID);
|
||||
level += mix(mix(packing.adjSizeDiffs[0], packing.adjSizeDiffs[1], uv.x),
|
||||
mix(packing.adjSizeDiffs[3], packing.adjSizeDiffs[2], uv.x),
|
||||
uv.y);
|
||||
#endif
|
||||
|
||||
int levelm = int(floor(level));
|
||||
int levelp = int(ceil(level));
|
||||
float t = level - float(levelm);
|
||||
|
||||
vec4 du0, du1, dv0, dv1;
|
||||
vec4 r0 = PtexLookupQuadratic(du0, dv0, patchCoord, levelm, data, packings);
|
||||
vec4 r1 = PtexLookupQuadratic(du1, dv1, patchCoord, levelp, data, packings);
|
||||
|
||||
vec4 result = mix(r0, r1, t);
|
||||
du = mix(du0, du1, t);
|
||||
dv = mix(dv0, dv1, t);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
vec4 PtexMipmapLookupQuadratic(vec4 patchCoord,
|
||||
float level,
|
||||
sampler2DArray data,
|
||||
isamplerBuffer packings)
|
||||
{
|
||||
vec4 du, dv;
|
||||
return PtexMipmapLookupQuadratic(du, dv, patchCoord, level, data, packings);
|
||||
}
|
||||
|
||||
148
blender-5.2.0/extern/opensubdiv-source/examples/common/hdr_reader.cpp
vendored
Normal file
148
blender-5.2.0/extern/opensubdiv-source/examples/common/hdr_reader.cpp
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "hdr_reader.h"
|
||||
|
||||
static bool
|
||||
readLine(unsigned char *line, int length, FILE *fp)
|
||||
{
|
||||
// 2, 2, width (this reader only reads newer format)
|
||||
if (getc(fp) != 2) return false;
|
||||
if (getc(fp) != 2) return false;
|
||||
int w0 = getc(fp);
|
||||
int w1 = getc(fp);
|
||||
if ((w0 << 8 | w1) != length) return false;
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int x = 0; x < length;) {
|
||||
int c = getc(fp);
|
||||
if (c > 128) {
|
||||
// runlength
|
||||
c &= 127;
|
||||
unsigned char value = (unsigned char)getc(fp);
|
||||
while (c--) {
|
||||
line[x*4+i] = value;
|
||||
x++;
|
||||
}
|
||||
} else {
|
||||
// non- runlength
|
||||
while (c--) {
|
||||
unsigned char value = (unsigned char)getc(fp);
|
||||
line[x*4+i] = value;
|
||||
x++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned char *loadHdr(const char *filename, HdrInfo *info, bool convertToFloat)
|
||||
{
|
||||
FILE *fp = fopen(filename, "rb");
|
||||
if (fp == NULL) return NULL;
|
||||
|
||||
memset(info, 0, sizeof(HdrInfo));
|
||||
info->exposure = 1.0;
|
||||
|
||||
unsigned char *dst=NULL, *line=NULL, *d=NULL;
|
||||
float *fd=NULL;
|
||||
|
||||
const int MAXLINE = 1024;
|
||||
char buffer[MAXLINE];
|
||||
|
||||
// read header
|
||||
while(true) {
|
||||
if (! fgets(buffer, MAXLINE, fp)) goto error;
|
||||
if (buffer[0] == '\n') break;
|
||||
if (buffer[0] == '\r' && buffer[0] == '\n') break;
|
||||
if (strncmp(buffer, "#?", 2) == 0) {
|
||||
strncpy(info->magic, buffer+2, 64);
|
||||
} else if (strncmp(buffer, "FORMAT=", 7) == 0) {
|
||||
strncpy(info->format, buffer+7, 64);
|
||||
}
|
||||
}
|
||||
// if (strncmp(info->magic, "RADIANCE", 8)) goto error;
|
||||
if (strncmp(info->format, "32-bit_rle_rgbe", 15)) goto error;
|
||||
|
||||
// resolution
|
||||
if (! fgets(buffer, MAXLINE, fp)) goto error;
|
||||
{
|
||||
int n = (int)strlen(buffer);
|
||||
for (int i = 1; i < n; ++i) {
|
||||
if (buffer[i] == 'X') {
|
||||
if (! (info->flag & HDR_Y_MAJOR)) info->flag |= HDR_X_MAJOR;
|
||||
info->flag |= (char)((buffer[i-1] == '-') ? HDR_X_DEC : 0);
|
||||
info->width = atoi(&buffer[i+1]);
|
||||
} else if (buffer[i] == 'Y') {
|
||||
if (! (info->flag & HDR_X_MAJOR)) info->flag |= HDR_Y_MAJOR;
|
||||
info->flag |= (char)((buffer[i-1] == '-') ? HDR_Y_DEC : 0);
|
||||
info->height = atoi(&buffer[i+1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (info->width <= 0 || info->height <= 0) goto error;
|
||||
|
||||
if (info->flag & HDR_Y_MAJOR) {
|
||||
info->scanLength = info->width;
|
||||
info->scanWidth = info->height;
|
||||
} else {
|
||||
info->scanLength = info->height;
|
||||
info->scanWidth = info->width;
|
||||
}
|
||||
|
||||
// read body
|
||||
if (convertToFloat) {
|
||||
dst = (unsigned char *)malloc(info->width * info->height * 4 * sizeof(float));
|
||||
fd = (float*)dst;
|
||||
} else {
|
||||
dst = (unsigned char *)malloc(info->width * info->height * 4);
|
||||
d = dst;
|
||||
}
|
||||
line = (unsigned char *)malloc(info->scanLength*4);
|
||||
|
||||
for (int y = info->scanWidth-1; y >= 0; --y) {
|
||||
if (! readLine(line, info->scanLength, fp)) goto error;
|
||||
for (int x = 0; x < info->scanLength; ++x) {
|
||||
if (convertToFloat) {
|
||||
float scale = powf(2.0f, float(line[x*4+3] - 128))/255.0f;
|
||||
*fd++ = line[x*4 ]*scale;
|
||||
*fd++ = line[x*4+1]*scale;
|
||||
*fd++ = line[x*4+2]*scale;
|
||||
*fd++ = 1.0;
|
||||
} else {
|
||||
*d++ = line[x*4 ];
|
||||
*d++ = line[x*4+1];
|
||||
*d++ = line[x*4+2];
|
||||
*d++ = line[x*4+3];
|
||||
}
|
||||
}
|
||||
}
|
||||
free(line);
|
||||
fclose(fp);
|
||||
|
||||
return dst;
|
||||
|
||||
error:
|
||||
printf("Error in reading %s\n", filename);
|
||||
if(dst) free(dst);
|
||||
if(line) free(line);
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
int main(int argc, char *argv[]) {
|
||||
HdrInfo info;
|
||||
loadHdr(argv[1], &info);
|
||||
}
|
||||
*/
|
||||
25
blender-5.2.0/extern/opensubdiv-source/examples/common/hdr_reader.h
vendored
Normal file
25
blender-5.2.0/extern/opensubdiv-source/examples/common/hdr_reader.h
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#define HDR_X_MAJOR (1 << 0)
|
||||
#define HDR_Y_MAJOR (1 << 1)
|
||||
#define HDR_X_DEC (1 << 2)
|
||||
#define HDR_Y_DEC (1 << 3)
|
||||
|
||||
struct HdrInfo
|
||||
{
|
||||
char magic[64];
|
||||
char format[64];
|
||||
double exposure;
|
||||
int width;
|
||||
int height;
|
||||
char flag;
|
||||
int scanLength;
|
||||
int scanWidth;
|
||||
};
|
||||
|
||||
extern unsigned char *loadHdr(const char *filename, HdrInfo *info, bool convertToFloat);
|
||||
309
blender-5.2.0/extern/opensubdiv-source/examples/common/hlslPtexCommon.hlsl
vendored
Normal file
309
blender-5.2.0/extern/opensubdiv-source/examples/common/hlslPtexCommon.hlsl
vendored
Normal file
@@ -0,0 +1,309 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
//----------------------------------------------------------
|
||||
// Ptex.Common
|
||||
//----------------------------------------------------------
|
||||
|
||||
struct PtexPacking {
|
||||
int page;
|
||||
int nMipmap;
|
||||
int uOffset;
|
||||
int vOffset;
|
||||
int adjSizeDiffs[4];
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
PtexPacking getPtexPacking(Buffer<uint> packings, int faceID)
|
||||
{
|
||||
PtexPacking packing;
|
||||
packing.page = packings[faceID*6+0].x;
|
||||
packing.nMipmap = packings[faceID*6+1].x;
|
||||
packing.uOffset = packings[faceID*6+2].x;
|
||||
packing.vOffset = packings[faceID*6+3].x;
|
||||
int wh = packings[faceID*6+5].x;
|
||||
packing.width = 1 << (wh >> 8);
|
||||
packing.height = 1 << (wh & 0xff);
|
||||
|
||||
int adjSizeDiffs = packings[faceID*6+4].x;
|
||||
packing.adjSizeDiffs[0] = (adjSizeDiffs >> 12) & 0xf;
|
||||
packing.adjSizeDiffs[1] = (adjSizeDiffs >> 8) & 0xf;
|
||||
packing.adjSizeDiffs[2] = (adjSizeDiffs >> 4) & 0xf;
|
||||
packing.adjSizeDiffs[3] = (adjSizeDiffs >> 0) & 0xf;
|
||||
|
||||
return packing;
|
||||
}
|
||||
|
||||
int computeMipmapOffsetU(int w, int level)
|
||||
{
|
||||
int width = 1 << w;
|
||||
int m = (0x55555555 & (width | (width-1))) << (w&1);
|
||||
int x = ~((1 << (w -((level-1)&~1))) - 1);
|
||||
return (m & x) + ((level+1)&~1);
|
||||
}
|
||||
|
||||
int computeMipmapOffsetV(int h, int level)
|
||||
{
|
||||
int height = 1 << h;
|
||||
int m = (0x55555555 & (height-1)) << ((h+1)&1);;
|
||||
int x = ~((1 << (h - (level&~1))) - 1 );
|
||||
return (m & x) + (level&~1);
|
||||
}
|
||||
|
||||
PtexPacking getPtexPacking(Buffer<uint> packings, int faceID, int level)
|
||||
{
|
||||
PtexPacking packing;
|
||||
packing.page = packings[faceID*6+0].x;
|
||||
packing.nMipmap = packings[faceID*6+1].x;
|
||||
packing.uOffset = packings[faceID*6+2].x;
|
||||
packing.vOffset = packings[faceID*6+3].x;
|
||||
//int sizeDiffs = packings[faceID*6+4].x;
|
||||
int wh = packings[faceID*6+5].x;
|
||||
int w = wh >> 8;
|
||||
int h = wh & 0xff;
|
||||
|
||||
// clamp max level
|
||||
level = min(level, packing.nMipmap);
|
||||
|
||||
packing.uOffset += computeMipmapOffsetU(w, level);
|
||||
packing.vOffset += computeMipmapOffsetV(h, level);
|
||||
packing.width = 1 << (w-level);
|
||||
packing.height = 1 << (h-level);
|
||||
|
||||
return packing;
|
||||
}
|
||||
|
||||
void evalQuadraticBSpline(float u, out float B[3], out float BU[3])
|
||||
{
|
||||
B[0] = 0.5 * (u*u - 2.0*u + 1);
|
||||
B[1] = 0.5 + u - u*u;
|
||||
B[2] = 0.5 * u*u;
|
||||
|
||||
BU[0] = u - 1.0;
|
||||
BU[1] = 1 - 2 * u;
|
||||
BU[2] = u;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Non-Mipmap Lookups
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
float4 PtexLookupNearest(float4 patchCoord,
|
||||
Texture2DArray data,
|
||||
Buffer<uint> packings)
|
||||
{
|
||||
float2 uv = clamp(patchCoord.xy, float2(0,0), float2(1,1));
|
||||
int faceID = int(patchCoord.w);
|
||||
PtexPacking ppack = getPtexPacking(packings, faceID);
|
||||
float2 coords = float2(uv.x * ppack.width + ppack.uOffset,
|
||||
uv.y * ppack.height + ppack.vOffset);
|
||||
return data[int3(int(coords.x), int(coords.y), ppack.page)];
|
||||
}
|
||||
|
||||
float4 PtexLookupNearest(float4 patchCoord,
|
||||
int level,
|
||||
Texture2DArray data,
|
||||
Buffer<uint> packings)
|
||||
{
|
||||
float2 uv = clamp(patchCoord.xy, float2(0,0), float2(1,1));
|
||||
int faceID = int(patchCoord.w);
|
||||
PtexPacking ppack = getPtexPacking(packings, faceID, level);
|
||||
float2 coords = float2(uv.x * ppack.width + ppack.uOffset,
|
||||
uv.y * ppack.height + ppack.vOffset);
|
||||
return data[int3(int(coords.x), int(coords.y), ppack.page)];
|
||||
}
|
||||
|
||||
float4 PtexLookup(float4 patchCoord,
|
||||
int level,
|
||||
Texture2DArray data,
|
||||
Buffer<uint> packings)
|
||||
{
|
||||
float2 uv = clamp(patchCoord.xy, float2(0,0), float2(1,1));
|
||||
int faceID = int(patchCoord.w);
|
||||
PtexPacking ppack = getPtexPacking(packings, faceID, level);
|
||||
|
||||
float2 coords = float2(uv.x * ppack.width + ppack.uOffset,
|
||||
uv.y * ppack.height + ppack.vOffset);
|
||||
|
||||
coords -= float2(0.5, 0.5);
|
||||
|
||||
int c0X = int(floor(coords.x));
|
||||
int c1X = int(ceil(coords.x));
|
||||
int c0Y = int(floor(coords.y));
|
||||
int c1Y = int(ceil(coords.y));
|
||||
|
||||
float t = coords.x - float(c0X);
|
||||
float s = coords.y - float(c0Y);
|
||||
|
||||
float4 d0 = data[int3(c0X, c0Y, ppack.page)];
|
||||
float4 d1 = data[int3(c0X, c1Y, ppack.page)];
|
||||
float4 d2 = data[int3(c1X, c0Y, ppack.page)];
|
||||
float4 d3 = data[int3(c1X, c1Y, ppack.page)];
|
||||
|
||||
float4 result = (1-t) * ((1-s)*d0 + s*d1) + t * ((1-s)*d2 + s*d3);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
float4 PtexLookupQuadratic(out float4 du,
|
||||
out float4 dv,
|
||||
float4 patchCoord,
|
||||
int level,
|
||||
Texture2DArray data,
|
||||
Buffer<uint> packings)
|
||||
{
|
||||
float2 uv = clamp(patchCoord.xy, float2(0,0), float2(1,1));
|
||||
int faceID = int(patchCoord.w);
|
||||
PtexPacking ppack = getPtexPacking(packings, faceID, level);
|
||||
|
||||
float2 coords = float2(uv.x * ppack.width + ppack.uOffset,
|
||||
uv.y * ppack.height + ppack.vOffset);
|
||||
|
||||
coords -= float2(0.5, 0.5);
|
||||
|
||||
int cX = int(round(coords.x));
|
||||
int cY = int(round(coords.y));
|
||||
|
||||
float x = 0.5 - (float(cX) - coords.x);
|
||||
float y = 0.5 - (float(cY) - coords.y);
|
||||
|
||||
float4 d[9];
|
||||
d[0] = data[int3(cX-1, cY-1, ppack.page)];
|
||||
d[1] = data[int3(cX-1, cY-0, ppack.page)];
|
||||
d[2] = data[int3(cX-1, cY+1, ppack.page)];
|
||||
d[3] = data[int3(cX-0, cY-1, ppack.page)];
|
||||
d[4] = data[int3(cX-0, cY-0, ppack.page)];
|
||||
d[5] = data[int3(cX-0, cY+1, ppack.page)];
|
||||
d[6] = data[int3(cX+1, cY-1, ppack.page)];
|
||||
d[7] = data[int3(cX+1, cY-0, ppack.page)];
|
||||
d[8] = data[int3(cX+1, cY+1, ppack.page)];
|
||||
|
||||
float B[3], D[3];
|
||||
float4 BUCP[3] = {float4(0,0,0,0), float4(0,0,0,0), float4(0,0,0,0)},
|
||||
DUCP[3] = {float4(0,0,0,0), float4(0,0,0,0), float4(0,0,0,0)};
|
||||
|
||||
evalQuadraticBSpline(y, B, D);
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
float4 A = d[i*3+j];
|
||||
BUCP[i] += A * B[j];
|
||||
DUCP[i] += A * D[j];
|
||||
}
|
||||
}
|
||||
|
||||
evalQuadraticBSpline(x, B, D);
|
||||
|
||||
float4 result = float4(0, 0, 0, 0);
|
||||
du = float4(0, 0, 0, 0);
|
||||
dv = float4(0, 0, 0, 0);
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
result += B[i] * BUCP[i];
|
||||
du += D[i] * BUCP[i];
|
||||
dv += B[i] * DUCP[i];
|
||||
}
|
||||
|
||||
du *= ppack.width;
|
||||
dv *= ppack.height;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// MipMap Lookups
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
float4 PtexMipmapLookupNearest(float4 patchCoord,
|
||||
int level,
|
||||
Texture2DArray data,
|
||||
Buffer<uint> packings)
|
||||
{
|
||||
#if defined(SEAMLESS_MIPMAP)
|
||||
// diff level
|
||||
int faceID = int(patchCoord.w);
|
||||
float2 uv = patchCoord.xy;
|
||||
PtexPacking packing = getPtexPacking(packings, faceID);
|
||||
level += lerp(lerp(packing.adjSizeDiffs[0], packing.adjSizeDiffs[1], uv.x),
|
||||
lerp(packing.adjSizeDiffs[3], packing.adjSizeDiffs[2], uv.x),
|
||||
uv.y);
|
||||
#endif
|
||||
|
||||
int levelm = int(floor(level));
|
||||
int levelp = int(ceil(level));
|
||||
float t = level - float(levelm);
|
||||
|
||||
float4 result = (1-t) * PtexLookupNearest(patchCoord, levelm, data, packings)
|
||||
+ t * PtexLookupNearest(patchCoord, levelp, data, packings);
|
||||
return result;
|
||||
}
|
||||
|
||||
float4 PtexMipmapLookup(float4 patchCoord,
|
||||
float level,
|
||||
Texture2DArray data,
|
||||
Buffer<uint> packings)
|
||||
{
|
||||
#if defined(SEAMLESS_MIPMAP)
|
||||
// diff level
|
||||
int faceID = int(patchCoord.w);
|
||||
float2 uv = patchCoord.xy;
|
||||
PtexPacking packing = getPtexPacking(packings, faceID);
|
||||
level += lerp(lerp(packing.adjSizeDiffs[0], packing.adjSizeDiffs[1], uv.x),
|
||||
lerp(packing.adjSizeDiffs[3], packing.adjSizeDiffs[2], uv.x),
|
||||
uv.y);
|
||||
#endif
|
||||
|
||||
int levelm = int(floor(level));
|
||||
int levelp = int(ceil(level));
|
||||
float t = level - float(levelm);
|
||||
|
||||
float4 result = (1-t) * PtexLookup(patchCoord, levelm, data, packings)
|
||||
+ t * PtexLookup(patchCoord, levelp, data, packings);
|
||||
return result;
|
||||
}
|
||||
|
||||
float4 PtexMipmapLookupQuadratic(out float4 du,
|
||||
out float4 dv,
|
||||
float4 patchCoord,
|
||||
float level,
|
||||
Texture2DArray data,
|
||||
Buffer<uint> packings)
|
||||
{
|
||||
#if defined(SEAMLESS_MIPMAP)
|
||||
// diff level
|
||||
int faceID = int(patchCoord.w);
|
||||
float2 uv = patchCoord.xy;
|
||||
PtexPacking packing = getPtexPacking(packings, faceID);
|
||||
level += lerp(lerp(packing.adjSizeDiffs[0], packing.adjSizeDiffs[1], uv.x),
|
||||
lerp(packing.adjSizeDiffs[3], packing.adjSizeDiffs[2], uv.x),
|
||||
uv.y);
|
||||
#endif
|
||||
|
||||
int levelm = int(floor(level));
|
||||
int levelp = int(ceil(level));
|
||||
float t = level - float(levelm);
|
||||
|
||||
float4 du0, du1, dv0, dv1;
|
||||
float4 r0 = PtexLookupQuadratic(du0, dv0, patchCoord, levelm, data, packings);
|
||||
float4 r1 = PtexLookupQuadratic(du1, dv1, patchCoord, levelp, data, packings);
|
||||
|
||||
float4 result = lerp(r0, r1, t);
|
||||
du = lerp(du0, du1, t);
|
||||
dv = lerp(dv0, dv1, t);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
float4 PtexMipmapLookupQuadratic(float4 patchCoord,
|
||||
float level,
|
||||
Texture2DArray data,
|
||||
Buffer<uint> packings)
|
||||
{
|
||||
float4 du, dv;
|
||||
return PtexMipmapLookupQuadratic(du, dv, patchCoord, level, data, packings);
|
||||
}
|
||||
|
||||
589
blender-5.2.0/extern/opensubdiv-source/examples/common/hud.cpp
vendored
Normal file
589
blender-5.2.0/extern/opensubdiv-source/examples/common/hud.cpp
vendored
Normal file
@@ -0,0 +1,589 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include "hud.h"
|
||||
#include "font_image.h"
|
||||
|
||||
#if _MSC_VER
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
Hud::Hud() : _visible(true), _windowWidth(0), _windowHeight(0),
|
||||
_framebufferWidth(0), _framebufferHeight(0),
|
||||
_requiresRebuildStatic(true)
|
||||
{
|
||||
_capturedSlider = -1;
|
||||
}
|
||||
|
||||
Hud::~Hud()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Hud::Init(int width, int height, int framebufferWidth, int framebufferHeight)
|
||||
{
|
||||
_windowWidth = width;
|
||||
_windowHeight = height;
|
||||
_framebufferWidth = framebufferWidth;
|
||||
_framebufferHeight = framebufferHeight;
|
||||
}
|
||||
|
||||
int
|
||||
Hud::GetWidth() const
|
||||
{
|
||||
return _windowWidth;
|
||||
}
|
||||
|
||||
int
|
||||
Hud::GetHeight() const
|
||||
{
|
||||
return _windowHeight;
|
||||
}
|
||||
|
||||
void
|
||||
Hud::Clear()
|
||||
{
|
||||
_radioButtons.clear();
|
||||
_checkBoxes.clear();
|
||||
_sliders.clear();
|
||||
_vboSource.clear();
|
||||
_requiresRebuildStatic = true;
|
||||
}
|
||||
|
||||
bool
|
||||
Hud::KeyDown(int key)
|
||||
{
|
||||
for (std::vector<RadioButton>::iterator it = _radioButtons.begin();
|
||||
it != _radioButtons.end(); ++it) {
|
||||
if (key == it->shortcut) {
|
||||
int nextLocalIndex = it->localIndex;
|
||||
if (it->sharedShortcut) {
|
||||
// find checked radio button in this group
|
||||
int maxLocalIndex = 0;
|
||||
for (std::vector<RadioButton>::iterator it2 = _radioButtons.begin();
|
||||
it2 != _radioButtons.end(); ++it2) {
|
||||
|
||||
if (it2->group == it->group) {
|
||||
maxLocalIndex = std::max(maxLocalIndex, it2->localIndex);
|
||||
if (it2->checked) {
|
||||
nextLocalIndex = it2->localIndex+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nextLocalIndex > maxLocalIndex) nextLocalIndex = 0;
|
||||
}
|
||||
for (std::vector<RadioButton>::iterator it2 = _radioButtons.begin();
|
||||
it2 != _radioButtons.end(); ++it2) {
|
||||
if (it2->group == it->group) {
|
||||
if (it2->localIndex == nextLocalIndex) {
|
||||
it2->checked = true;
|
||||
it2->callback(it2->callbackData);
|
||||
} else {
|
||||
it2->checked = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
_requiresRebuildStatic = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (std::vector<CheckBox>::iterator it = _checkBoxes.begin();
|
||||
it != _checkBoxes.end(); ++it) {
|
||||
|
||||
if (key == it->shortcut) {
|
||||
it->checked = !it->checked;
|
||||
it->callback(it->checked, it->callbackData);
|
||||
_requiresRebuildStatic = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (std::vector<PullDown>::iterator it = _pulldowns.begin();
|
||||
it != _pulldowns.end(); ++it) {
|
||||
if (key==it->shortcut) {
|
||||
// cycle through selections
|
||||
++it->selected;
|
||||
if (it->selected>=(int)it->labels.size()) {
|
||||
it->selected=0;
|
||||
}
|
||||
it->callback(it->values[it->selected]);
|
||||
_requiresRebuildStatic = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Hud::MouseClick(int x, int y)
|
||||
{
|
||||
if (!IsVisible()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (std::vector<RadioButton>::iterator it = _radioButtons.begin();
|
||||
it != _radioButtons.end(); ++it) {
|
||||
if (hitTest(*it, x, y)) {
|
||||
for (std::vector<RadioButton>::iterator it2 = _radioButtons.begin();
|
||||
it2 != _radioButtons.end(); ++it2) {
|
||||
|
||||
if (it2->group == it->group && it != it2) it2->checked = false;
|
||||
}
|
||||
it->checked = true;
|
||||
it->callback(it->callbackData);
|
||||
_requiresRebuildStatic = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (std::vector<CheckBox>::iterator it = _checkBoxes.begin();
|
||||
it != _checkBoxes.end(); ++it) {
|
||||
if (hitTest(*it, x, y)) {
|
||||
it->checked = !it->checked;
|
||||
it->callback(it->checked, it->callbackData);
|
||||
_requiresRebuildStatic = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (std::vector<Slider>::iterator it = _sliders.begin();
|
||||
it != _sliders.end(); ++it) {
|
||||
if (hitTest(*it, x, y)) {
|
||||
int bx = 0, by = 0;
|
||||
getWindowPos(*it, &bx, &by);
|
||||
it->SetValue(((x-bx-FONT_CHAR_WIDTH/2)/float(it->w))*(it->max - it->min) + it->min);
|
||||
it->callback(it->value, it->callbackData);
|
||||
_capturedSlider = (int)(it - _sliders.begin());
|
||||
_requiresRebuildStatic = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (std::vector<PullDown>::iterator it = _pulldowns.begin();
|
||||
it != _pulldowns.end(); ++it) {
|
||||
if (hitTest(*it, x, y)) {
|
||||
if (! it->open) {
|
||||
it->h = FONT_CHAR_HEIGHT;
|
||||
it->h *= (int)it->labels.size();
|
||||
it->open=true;
|
||||
} else {
|
||||
int label_width = (3+(int)it->label.size()) * FONT_CHAR_WIDTH;
|
||||
int bx = 0, by = 0;
|
||||
getWindowPos(*it, &bx, &by);
|
||||
if (x > (bx+label_width)) {
|
||||
int sel = it->selected;
|
||||
it->SetSelected((y-by)/FONT_CHAR_HEIGHT);
|
||||
if (it->selected!=sel) {
|
||||
it->callback(it->values[it->selected]);
|
||||
}
|
||||
} else {
|
||||
it->open=! it->open;
|
||||
}
|
||||
}
|
||||
_requiresRebuildStatic = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
Hud::MouseMotion(int x, int /* y */)
|
||||
{
|
||||
if (_capturedSlider != -1) {
|
||||
std::vector<Slider>::iterator it = _sliders.begin() + _capturedSlider;
|
||||
|
||||
int bx = it->x > 0 ? it->x : _windowWidth + it->x;
|
||||
it->SetValue(((x-bx-FONT_CHAR_WIDTH/2)/float(it->w))*(it->max - it->min) + it->min);
|
||||
it->callback(it->value, it->callbackData);
|
||||
_requiresRebuildStatic = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Hud::MouseCapture() const
|
||||
{
|
||||
return _capturedSlider != -1;
|
||||
}
|
||||
|
||||
void
|
||||
Hud::MouseRelease()
|
||||
{
|
||||
_capturedSlider = -1;
|
||||
}
|
||||
|
||||
void
|
||||
Hud::AddLabel(const char *label, int x, int y)
|
||||
{
|
||||
Item l;
|
||||
l.label = label;
|
||||
l.x = x;
|
||||
l.y = y;
|
||||
|
||||
_labels.push_back(l);
|
||||
_requiresRebuildStatic = true;
|
||||
}
|
||||
|
||||
void
|
||||
Hud::AddCheckBox(const char *label, bool checked, int x, int y,
|
||||
CheckBoxCallback callback, int data, int shortcut)
|
||||
{
|
||||
CheckBox cb;
|
||||
cb.label = label;
|
||||
cb.checked = checked;
|
||||
cb.x = x;
|
||||
cb.y = y;
|
||||
cb.w = (int)(strlen(label)+1) * FONT_CHAR_WIDTH;
|
||||
cb.h = FONT_CHAR_HEIGHT;
|
||||
cb.callback = callback;
|
||||
cb.callbackData = data;
|
||||
cb.shortcut = shortcut;
|
||||
|
||||
_checkBoxes.push_back(cb);
|
||||
_requiresRebuildStatic = true;
|
||||
}
|
||||
|
||||
void
|
||||
Hud::AddRadioButton(int group, const char *label, bool checked, int x, int y,
|
||||
RadioButtonCallback callback, int data, int shortcut)
|
||||
{
|
||||
RadioButton rb;
|
||||
rb.group = group;
|
||||
rb.label = label;
|
||||
rb.checked = checked;
|
||||
rb.x = x;
|
||||
rb.y = y;
|
||||
rb.w = (int)(strlen(label)+1) * FONT_CHAR_WIDTH;
|
||||
rb.h = FONT_CHAR_HEIGHT;
|
||||
rb.callback = callback;
|
||||
rb.callbackData = data;
|
||||
rb.shortcut = shortcut;
|
||||
rb.sharedShortcut = false;
|
||||
rb.localIndex = 0;
|
||||
|
||||
for (std::vector<RadioButton>::iterator it = _radioButtons.begin();
|
||||
it != _radioButtons.end(); ++it) {
|
||||
if (it->group == group) {
|
||||
rb.localIndex = it->localIndex+1;
|
||||
if (it->shortcut == shortcut) {
|
||||
it->sharedShortcut = true;
|
||||
rb.sharedShortcut = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_radioButtons.push_back(rb);
|
||||
_requiresRebuildStatic = true;
|
||||
}
|
||||
|
||||
void
|
||||
Hud::AddSlider(const char *label, float min, float max, float value,
|
||||
int x, int y, int width, bool intStep, SliderCallback callback, int data)
|
||||
{
|
||||
Slider slider;
|
||||
slider.label = label;
|
||||
slider.x = x;
|
||||
slider.y = y;
|
||||
slider.w = width * FONT_CHAR_WIDTH;
|
||||
slider.h = FONT_CHAR_HEIGHT * 2;
|
||||
slider.min = min;
|
||||
slider.max = max;
|
||||
slider.value = value;
|
||||
slider.callback = callback;
|
||||
slider.callbackData = data;
|
||||
slider.intStep = intStep;
|
||||
|
||||
_sliders.push_back(slider);
|
||||
_requiresRebuildStatic = true;
|
||||
}
|
||||
|
||||
int
|
||||
Hud::AddPullDown(const char *label, int x, int y, int width,
|
||||
PullDownCallback callback, int shortcut)
|
||||
{
|
||||
|
||||
PullDown pd;
|
||||
pd.label = label;
|
||||
pd.x = x;
|
||||
pd.y = y;
|
||||
pd.w = width;
|
||||
pd.h = FONT_CHAR_HEIGHT;
|
||||
pd.open = false;
|
||||
pd.selected = 0;
|
||||
pd.callback = callback;
|
||||
pd.shortcut = shortcut;
|
||||
|
||||
_pulldowns.push_back(pd);
|
||||
_requiresRebuildStatic = true;
|
||||
|
||||
return (int)_pulldowns.size()-1;
|
||||
}
|
||||
|
||||
void
|
||||
Hud::AddPullDownButton(int handle, const char *label, int value, bool checked)
|
||||
{
|
||||
if (handle < (int)_pulldowns.size()) {
|
||||
|
||||
PullDown & pulldown = _pulldowns[handle];
|
||||
|
||||
pulldown.labels.push_back(label);
|
||||
pulldown.values.push_back(value);
|
||||
if (checked) {
|
||||
pulldown.selected = (int)pulldown.labels.size()-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
Hud::drawChar(std::vector<float> &vboSource,
|
||||
int x, int y, float r, float g, float b, char ch)
|
||||
{
|
||||
const float w = 1.0f/FONT_TEXTURE_COLUMNS;
|
||||
const float h = 1.0f/FONT_TEXTURE_ROWS;
|
||||
|
||||
float u = (ch%FONT_TEXTURE_COLUMNS)/(float)FONT_TEXTURE_COLUMNS;
|
||||
float v = (ch/FONT_TEXTURE_COLUMNS)/(float)FONT_TEXTURE_ROWS;
|
||||
|
||||
vboSource.push_back(float(x));
|
||||
vboSource.push_back(float(y));
|
||||
vboSource.push_back(r);
|
||||
vboSource.push_back(g);
|
||||
vboSource.push_back(b);
|
||||
vboSource.push_back(u);
|
||||
vboSource.push_back(v);
|
||||
|
||||
vboSource.push_back(float(x));
|
||||
vboSource.push_back(float(y+FONT_CHAR_HEIGHT));
|
||||
vboSource.push_back(r);
|
||||
vboSource.push_back(g);
|
||||
vboSource.push_back(b);
|
||||
vboSource.push_back(u);
|
||||
vboSource.push_back(v+h);
|
||||
|
||||
vboSource.push_back(float(x+FONT_CHAR_WIDTH));
|
||||
vboSource.push_back(float(y));
|
||||
vboSource.push_back(r);
|
||||
vboSource.push_back(g);
|
||||
vboSource.push_back(b);
|
||||
vboSource.push_back(u+w);
|
||||
vboSource.push_back(v);
|
||||
|
||||
vboSource.push_back(float(x+FONT_CHAR_WIDTH));
|
||||
vboSource.push_back(float(y));
|
||||
vboSource.push_back(r);
|
||||
vboSource.push_back(g);
|
||||
vboSource.push_back(b);
|
||||
vboSource.push_back(u+w);
|
||||
vboSource.push_back(v);
|
||||
|
||||
vboSource.push_back(float(x));
|
||||
vboSource.push_back(float(y+FONT_CHAR_HEIGHT));
|
||||
vboSource.push_back(r);
|
||||
vboSource.push_back(g);
|
||||
vboSource.push_back(b);
|
||||
vboSource.push_back(u);
|
||||
vboSource.push_back(v+h);
|
||||
|
||||
vboSource.push_back(float(x+FONT_CHAR_WIDTH));
|
||||
vboSource.push_back(float(y+FONT_CHAR_HEIGHT));
|
||||
vboSource.push_back(r);
|
||||
vboSource.push_back(g);
|
||||
vboSource.push_back(b);
|
||||
vboSource.push_back(u+w);
|
||||
vboSource.push_back(v+h);
|
||||
|
||||
return x + FONT_CHAR_WIDTH;
|
||||
}
|
||||
|
||||
int
|
||||
Hud::drawString(std::vector<float> &vboSource,
|
||||
int x, int y, float r, float g, float b, const char *c)
|
||||
{
|
||||
while (*c) {
|
||||
char ch = (char)((*c) & 0x7f);
|
||||
x = drawChar(vboSource, x, y, r, g, b, ch);
|
||||
c++;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
void
|
||||
Hud::DrawString(int x, int y, const char *fmt, ...)
|
||||
{
|
||||
char buf[1024];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
x = x > 0 ? x : _windowWidth + x;
|
||||
y = y > 0 ? y : _windowHeight + y;
|
||||
|
||||
drawString(_vboSource, x, y, 1, 1, 1, buf);
|
||||
}
|
||||
|
||||
void
|
||||
Hud::DrawString(int x, int y, float r, float g, float b, const char *fmt, ...)
|
||||
{
|
||||
char buf[1024];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
x = x > 0 ? x : _windowWidth + x;
|
||||
y = y > 0 ? y : _windowHeight + y;
|
||||
|
||||
drawString(_vboSource, x, y, r, g, b, buf);
|
||||
}
|
||||
|
||||
void
|
||||
Hud::Rebuild(int width, int height, int framebufferWidth, int framebufferHeight)
|
||||
{
|
||||
_requiresRebuildStatic = false;
|
||||
_windowWidth = width;
|
||||
_windowHeight = height;
|
||||
_framebufferWidth = framebufferWidth;
|
||||
_framebufferHeight = framebufferHeight;
|
||||
|
||||
_staticVboSource.clear();
|
||||
|
||||
int x, y;
|
||||
// add UI elements
|
||||
for (std::vector<Item>::const_iterator it = _labels.begin();
|
||||
it != _labels.end(); ++it) {
|
||||
getWindowPos(*it, &x, &y);
|
||||
drawString(_staticVboSource, x, y, 1, 1, 1, it->label.c_str());
|
||||
}
|
||||
// draw radio buttons
|
||||
for (std::vector<RadioButton>::const_iterator it = _radioButtons.begin();
|
||||
it != _radioButtons.end(); ++it) {
|
||||
getWindowPos(*it, &x, &y);
|
||||
if (it->checked) {
|
||||
x = drawChar(_staticVboSource, x, y, 1, 1, 1, FONT_RADIO_BUTTON_ON);
|
||||
drawString(_staticVboSource, x, y, 1, 1, 0, it->label.c_str());
|
||||
} else {
|
||||
x = drawChar(_staticVboSource, x, y, 1, 1, 1, FONT_RADIO_BUTTON_OFF);
|
||||
drawString(_staticVboSource, x, y, .5f, .5f, .5f, it->label.c_str());
|
||||
}
|
||||
}
|
||||
// draw checkboxes
|
||||
for (std::vector<CheckBox>::const_iterator it = _checkBoxes.begin();
|
||||
it != _checkBoxes.end(); ++it) {
|
||||
getWindowPos(*it, &x, &y);
|
||||
if (it->checked) {
|
||||
x = drawChar(_staticVboSource, x, y, 1, 1, 1, FONT_CHECK_BOX_ON);
|
||||
drawString(_staticVboSource, x, y, 1, 1, 0, it->label.c_str());
|
||||
} else {
|
||||
x = drawChar(_staticVboSource, x, y, 1, 1, 1, FONT_CHECK_BOX_OFF);
|
||||
drawString(_staticVboSource, x, y, .5f, .5f, .5f, it->label.c_str());
|
||||
}
|
||||
}
|
||||
// draw sliders
|
||||
for (std::vector<Slider>::const_iterator it = _sliders.begin();
|
||||
it != _sliders.end(); ++it) {
|
||||
getWindowPos(*it, &x, &y);
|
||||
int sx = x;
|
||||
x = drawString(_staticVboSource, x, y, 1, 1, 1, it->label.c_str());
|
||||
char value[16];
|
||||
if (it->intStep) {
|
||||
snprintf(value, 16, " : %d", (int)it->value);
|
||||
} else {
|
||||
snprintf(value, 16, " : %.2f", it->value);
|
||||
}
|
||||
drawString(_staticVboSource, x, y, 1, 1, 1, value);
|
||||
|
||||
// new line
|
||||
y += FONT_CHAR_HEIGHT;
|
||||
x = sx;
|
||||
|
||||
x = drawChar(_staticVboSource, x, y, 1, 1, 1, FONT_SLIDER_LEFT);
|
||||
int nw = it->w / FONT_CHAR_WIDTH;
|
||||
for (int i = 1; i < nw; ++i) {
|
||||
x = drawChar(_staticVboSource, x, y, 1, 1, 1, FONT_SLIDER_MIDDLE);
|
||||
}
|
||||
drawChar(_staticVboSource, x, y, 1, 1, 1, FONT_SLIDER_RIGHT);
|
||||
int pos = int(((it->value-it->min)/(it->max-it->min))*float(it->w));
|
||||
drawChar(_staticVboSource, sx+pos, y, 1, 1, 0, FONT_SLIDER_CURSOR);
|
||||
}
|
||||
// draw pulldowns
|
||||
for (std::vector<PullDown>::const_iterator it = _pulldowns.begin();
|
||||
it != _pulldowns.end(); ++it) {
|
||||
getWindowPos(*it, &x, &y);
|
||||
|
||||
x = drawString(_staticVboSource, x, y, .5f, .5f, .5f, it->label.c_str());
|
||||
x += FONT_CHAR_WIDTH;
|
||||
|
||||
if (it->open) {
|
||||
x = drawChar(_staticVboSource, x, y, 1, 1, 0, FONT_ARROW_DOWN);
|
||||
x += FONT_CHAR_WIDTH;
|
||||
for (int i=0; i<(int)it->labels.size(); ++i, y+=FONT_CHAR_HEIGHT) {
|
||||
if (i==it->selected) {
|
||||
drawString(_staticVboSource, x, y, 1, 1, 0, it->labels[i]);
|
||||
} else {
|
||||
drawString(_staticVboSource, x, y, 0.5f, 0.5f, 0.5f, it->labels[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
x = drawChar(_staticVboSource, x, y, .5f, .5f, .5f, FONT_ARROW_RIGHT);
|
||||
x += FONT_CHAR_WIDTH;
|
||||
drawString(_staticVboSource, x, y, 1, 1, 0, it->labels[it->selected]);
|
||||
}
|
||||
}
|
||||
|
||||
// draw the character cells corresponding to the logo
|
||||
drawString(_staticVboSource, _windowWidth-128, _windowHeight-44, .5, .5, .5,
|
||||
"\x06\x07\x08\x09");
|
||||
drawString(_staticVboSource, _windowWidth-128, _windowHeight-28, .5, .5, .5,
|
||||
"\x16\x17\x18\x19");
|
||||
drawString(_staticVboSource, _windowWidth-92, _windowHeight-36, .5, .5, .5,
|
||||
"\x0a\x0b\x0c\x0d");
|
||||
drawString(_staticVboSource, _windowWidth-58, _windowHeight-36, .5, .5, .5,
|
||||
"\x1a\x1b\x1c\x1d\x1e\x1f");
|
||||
}
|
||||
|
||||
bool
|
||||
Hud::Flush()
|
||||
{
|
||||
if (!_visible) {
|
||||
_vboSource.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_requiresRebuildStatic)
|
||||
this->Rebuild(_windowWidth, _windowHeight, _framebufferWidth, _framebufferHeight);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Hud::IsVisible() const
|
||||
{
|
||||
return _visible;
|
||||
}
|
||||
|
||||
void
|
||||
Hud::SetVisible(bool visible)
|
||||
{
|
||||
_visible = visible;
|
||||
}
|
||||
|
||||
std::vector<float> &
|
||||
Hud::getVboSource()
|
||||
{
|
||||
return _vboSource;
|
||||
}
|
||||
|
||||
std::vector<float> &
|
||||
Hud::getStaticVboSource()
|
||||
{
|
||||
return _staticVboSource;
|
||||
}
|
||||
189
blender-5.2.0/extern/opensubdiv-source/examples/common/hud.h
vendored
Normal file
189
blender-5.2.0/extern/opensubdiv-source/examples/common/hud.h
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef HUD_H
|
||||
#define HUD_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdarg>
|
||||
#include <math.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define OSD_HUD_USE_FUNCTION_POINTERS (__cplusplus <= 199711L)
|
||||
|
||||
#if !OSD_HUD_USE_FUNCTION_POINTERS
|
||||
#include <functional>
|
||||
#endif
|
||||
|
||||
#include "hud.h"
|
||||
|
||||
class Hud
|
||||
{
|
||||
public:
|
||||
#if OSD_HUD_USE_FUNCTION_POINTERS
|
||||
typedef void (*RadioButtonCallback)(int c);
|
||||
typedef void (*CheckBoxCallback)(bool checked, int data);
|
||||
typedef void (*SliderCallback)(float value, int data);
|
||||
typedef void (*PullDownCallback)(int value);
|
||||
#else
|
||||
typedef std::function<void(int)> RadioButtonCallback;
|
||||
typedef std::function<void(bool,int)> CheckBoxCallback;
|
||||
typedef std::function<void(float, int)> SliderCallback;
|
||||
typedef std::function<void(int)> PullDownCallback;
|
||||
#endif
|
||||
|
||||
Hud();
|
||||
virtual ~Hud();
|
||||
|
||||
virtual void Init(int width, int height, int framebufferWidth, int framebufferHeight);
|
||||
|
||||
virtual void Rebuild(int width, int height,
|
||||
int framebufferWidth, int framebufferHeight);
|
||||
|
||||
virtual bool Flush();
|
||||
|
||||
bool IsVisible() const;
|
||||
|
||||
void SetVisible(bool visible);
|
||||
|
||||
void DrawString(int x, int y, const char *fmt, ...);
|
||||
|
||||
void DrawString(int x, int y, float r, float g, float b, const char *fmt, ...);
|
||||
|
||||
void Clear();
|
||||
|
||||
void AddLabel(const char *label, int x, int y);
|
||||
|
||||
void AddRadioButton(int group, const char *label, bool checked, int x, int y,
|
||||
RadioButtonCallback callback=0, int data=0, int shortcut=0);
|
||||
|
||||
void AddCheckBox(const char *label, bool checked, int x, int y,
|
||||
CheckBoxCallback callback=0, int data=0, int shortcut=0);
|
||||
|
||||
void AddSlider(const char *label, float min, float max, float value,
|
||||
int x, int y, int width, bool intStep,
|
||||
SliderCallback callback=0, int data=0);
|
||||
|
||||
int AddPullDown(const char *label, int x, int y, int width,
|
||||
PullDownCallback callback=0, int shortcut=0);
|
||||
|
||||
void AddPullDownButton(int handle, const char *label, int value, bool checked=false);
|
||||
|
||||
bool KeyDown(int key);
|
||||
|
||||
bool MouseClick(int x, int y);
|
||||
|
||||
bool MouseCapture() const;
|
||||
|
||||
void MouseRelease();
|
||||
|
||||
void MouseMotion(int x, int y);
|
||||
|
||||
int GetWidth() const;
|
||||
|
||||
int GetHeight() const;
|
||||
|
||||
protected:
|
||||
struct Item {
|
||||
|
||||
int x, y, w, h;
|
||||
std::string label;
|
||||
};
|
||||
|
||||
struct RadioButton : public Item {
|
||||
|
||||
int group;
|
||||
int localIndex;
|
||||
bool checked;
|
||||
int shortcut;
|
||||
bool sharedShortcut;
|
||||
RadioButtonCallback callback;
|
||||
int callbackData;
|
||||
};
|
||||
|
||||
struct CheckBox : public Item {
|
||||
|
||||
bool checked;
|
||||
CheckBoxCallback callback;
|
||||
int callbackData;
|
||||
int shortcut;
|
||||
};
|
||||
|
||||
struct Slider : public Item {
|
||||
|
||||
float min, max;
|
||||
float value;
|
||||
SliderCallback callback;
|
||||
int callbackData;
|
||||
bool intStep;
|
||||
|
||||
void SetValue(float v) {
|
||||
v = std::max(std::min(v, max), min);
|
||||
if (intStep) {
|
||||
// MSVC 2010 does not have std::round() or roundf()
|
||||
v = v>0.0f ? floorf(v+0.5f) : ceilf(v-0.5f);
|
||||
}
|
||||
value = v;
|
||||
}
|
||||
};
|
||||
|
||||
struct PullDown : public Item {
|
||||
|
||||
bool open;
|
||||
int selected;
|
||||
std::vector<char const *> labels;
|
||||
std::vector<int> values;
|
||||
int shortcut;
|
||||
PullDownCallback callback;
|
||||
|
||||
void SetSelected(int idx) {
|
||||
if (idx>=0 && idx<(int)labels.size()) {
|
||||
selected=idx;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static int drawString(std::vector<float> &vboSource, int x, int y,
|
||||
float r, float g, float b, const char *c);
|
||||
|
||||
static int drawChar(std::vector<float> &vboSource, int x, int y,
|
||||
float r, float g, float b, char ch);
|
||||
|
||||
bool hitTest(Item const &item, int x, int y) const {
|
||||
int ix = item.x > 0 ? item.x : _windowWidth + item.x;
|
||||
int iy = item.y > 0 ? item.y : _windowHeight + item.y;
|
||||
return (x >= ix &&
|
||||
y >= iy &&
|
||||
x <= (ix + item.w) &&
|
||||
y <= (iy + item.h));
|
||||
}
|
||||
|
||||
void getWindowPos(Item const &item, int *x, int *y) const {
|
||||
*x = item.x > 0 ? item.x : _windowWidth + item.x;
|
||||
*y = item.y > 0 ? item.y : _windowHeight + item.y;
|
||||
}
|
||||
|
||||
std::vector<float> & getVboSource();
|
||||
std::vector<float> & getStaticVboSource();
|
||||
|
||||
private:
|
||||
|
||||
bool _visible;
|
||||
std::vector<float> _vboSource, _staticVboSource;
|
||||
int _windowWidth, _windowHeight;
|
||||
int _framebufferWidth, _framebufferHeight;
|
||||
bool _requiresRebuildStatic;
|
||||
std::vector<Item> _labels;
|
||||
std::vector<RadioButton> _radioButtons;
|
||||
std::vector<CheckBox> _checkBoxes;
|
||||
std::vector<Slider> _sliders;
|
||||
std::vector<PullDown> _pulldowns;
|
||||
int _capturedSlider;
|
||||
};
|
||||
|
||||
#endif // HUD_H
|
||||
45
blender-5.2.0/extern/opensubdiv-source/examples/common/mtlControlMeshDisplay.h
vendored
Normal file
45
blender-5.2.0/extern/opensubdiv-source/examples/common/mtlControlMeshDisplay.h
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// Copyright 2015 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef OPENSUBDIV_EXAMPLES_MTL_CONTROL_MESH_DISPLAY_H
|
||||
#define OPENSUBDIV_EXAMPLES_MTL_CONTROL_MESH_DISPLAY_H
|
||||
|
||||
#include <Metal/Metal.h>
|
||||
#include <opensubdiv/far/topologyLevel.h>
|
||||
|
||||
class MTLControlMeshDisplay {
|
||||
public:
|
||||
MTLControlMeshDisplay(id<MTLDevice> device, MTLRenderPipelineDescriptor* pipelineDescriptor);
|
||||
~MTLControlMeshDisplay() = default;
|
||||
|
||||
void Draw(id<MTLRenderCommandEncoder> encoder,
|
||||
id<MTLBuffer> vertexBuffer,
|
||||
const float *modelViewProjectionMatrix);
|
||||
|
||||
void SetTopology(OpenSubdiv::Far::TopologyLevel const &level);
|
||||
|
||||
bool GetEdgesDisplay() const { return _displayEdges; }
|
||||
void SetEdgesDisplay(bool display) { _displayEdges = display; }
|
||||
bool GetVerticesDisplay() const { return _displayVertices; }
|
||||
void SetVerticesDisplay(bool display) { _displayVertices = display; }
|
||||
|
||||
private:
|
||||
bool createProgram(MTLRenderPipelineDescriptor* pipelineDescriptor);
|
||||
|
||||
id<MTLDevice> _device;
|
||||
|
||||
bool _displayEdges;
|
||||
bool _displayVertices;
|
||||
|
||||
int _numEdges, _numPoints;
|
||||
id<MTLRenderPipelineState> _renderPipelineState;
|
||||
id<MTLBuffer> _vertexSharpnessBuffer;
|
||||
id<MTLBuffer> _edgeSharpnessBuffer;
|
||||
id<MTLBuffer> _edgeIndicesBuffer;
|
||||
};
|
||||
|
||||
#endif // OPENSUBDIV_EXAMPLES_MTL_CONTROL_MESH_DISPLAY_H
|
||||
150
blender-5.2.0/extern/opensubdiv-source/examples/common/mtlControlMeshDisplay.mm
vendored
Normal file
150
blender-5.2.0/extern/opensubdiv-source/examples/common/mtlControlMeshDisplay.mm
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#include "mtlControlMeshDisplay.h"
|
||||
#include <cassert>
|
||||
#include "mtlUtils.h"
|
||||
|
||||
static const char* s_Shader = R"(
|
||||
#include <metal_stdlib>
|
||||
using namespace metal;
|
||||
|
||||
float4 sharpnessToColor(float s) {
|
||||
// 0.0 2.0 4.0
|
||||
// green --- yellow --- red
|
||||
return float4(min(1.0, s * 0.5),
|
||||
min(1.0, 2.0 - s * 0.5),
|
||||
0.0, 1.0);
|
||||
}
|
||||
|
||||
struct DrawData
|
||||
{
|
||||
float4x4 ModelViewProjectionMatrix;
|
||||
};
|
||||
|
||||
struct VertexData
|
||||
{
|
||||
float3 position [[attribute(0)]];
|
||||
float sharpness [[attribute(1)]];
|
||||
};
|
||||
|
||||
struct FragmentData
|
||||
{
|
||||
float4 position [[position]];
|
||||
float4 color;
|
||||
};
|
||||
|
||||
vertex FragmentData vs_main(VertexData in [[stage_in]],
|
||||
const constant DrawData& drawData [[buffer(2)]]
|
||||
)
|
||||
{
|
||||
FragmentData out;
|
||||
out.position = drawData.ModelViewProjectionMatrix * float4(in.position, 1.0);
|
||||
out.color = sharpnessToColor(in.sharpness);
|
||||
return out;
|
||||
}
|
||||
|
||||
fragment float4 fs_main(FragmentData in [[stage_in]])
|
||||
{
|
||||
return in.color;
|
||||
}
|
||||
)";
|
||||
|
||||
MTLControlMeshDisplay::MTLControlMeshDisplay(id<MTLDevice> device, MTLRenderPipelineDescriptor* pipelineDescriptor)
|
||||
: _device(device), _displayEdges(false), _displayVertices(false), _numEdges(0), _numPoints(0) {
|
||||
const auto result = createProgram(pipelineDescriptor);
|
||||
assert(result && "Failed to create program for MTLControlMeshDisplay");
|
||||
}
|
||||
|
||||
void MTLControlMeshDisplay::SetTopology(OpenSubdiv::Far::TopologyLevel const &level) {
|
||||
using namespace OpenSubdiv;
|
||||
|
||||
_numEdges = level.GetNumEdges();
|
||||
_numPoints = level.GetNumVertices();
|
||||
|
||||
std::vector<int> edgeIndices;
|
||||
std::vector<float> edgeSharpness;
|
||||
std::vector<float> vertSharpness;
|
||||
|
||||
edgeIndices.reserve(_numEdges * 2);
|
||||
edgeSharpness.reserve(_numEdges);
|
||||
vertSharpness.reserve(_numPoints);
|
||||
|
||||
for(int i = 0; i < _numEdges; i++) {
|
||||
const auto verts = level.GetEdgeVertices(i);
|
||||
edgeIndices.emplace_back(verts[0]);
|
||||
edgeIndices.emplace_back(verts[1]);
|
||||
edgeSharpness.emplace_back(level.GetEdgeSharpness(i));
|
||||
}
|
||||
|
||||
for(int i = 0; i < _numPoints; i++) {
|
||||
vertSharpness.emplace_back(level.GetVertexSharpness(i));
|
||||
}
|
||||
|
||||
_edgeIndicesBuffer = Osd::MTLNewBufferFromVector(_device, edgeIndices);
|
||||
_edgeSharpnessBuffer = Osd::MTLNewBufferFromVector(_device, edgeSharpness);
|
||||
_vertexSharpnessBuffer = Osd::MTLNewBufferFromVector(_device, vertSharpness);
|
||||
}
|
||||
|
||||
bool MTLControlMeshDisplay::createProgram(MTLRenderPipelineDescriptor* _pipelineDescriptor) {
|
||||
const auto options = [MTLCompileOptions new];
|
||||
NSError* error = nil;
|
||||
|
||||
const auto library = [_device newLibraryWithSource:@(s_Shader) options:options error:&error];
|
||||
if(!library) {
|
||||
printf("Failed to create library for MTLControlMeshDisplay\n%s\n", error ? [[error localizedDescription] UTF8String] : "");
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto vertexFunction = [library newFunctionWithName:@"vs_main"];
|
||||
const auto fragmentFunction = [library newFunctionWithName:@"fs_main"];
|
||||
|
||||
MTLRenderPipelineDescriptor* pipelineDescriptor = [_pipelineDescriptor copy];
|
||||
pipelineDescriptor.vertexFunction = vertexFunction;
|
||||
pipelineDescriptor.fragmentFunction = fragmentFunction;
|
||||
const auto vertexDescriptor = pipelineDescriptor.vertexDescriptor;
|
||||
vertexDescriptor.layouts[1].stride = sizeof(float) * 6;
|
||||
vertexDescriptor.layouts[1].stepFunction = MTLVertexStepFunctionPerVertex;
|
||||
vertexDescriptor.layouts[1].stepRate = 1;
|
||||
vertexDescriptor.attributes[1].bufferIndex = 1;
|
||||
vertexDescriptor.attributes[1].offset = 0;
|
||||
vertexDescriptor.attributes[1].format = MTLVertexFormatFloat3;
|
||||
|
||||
_renderPipelineState = [_device newRenderPipelineStateWithDescriptor:pipelineDescriptor error:&error];
|
||||
|
||||
if(!_renderPipelineState) {
|
||||
printf("Failed to create render pipeline state for MTLControlMeshDisplay\n%s\n", error ? [[error localizedDescription] UTF8String] : "");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void MTLControlMeshDisplay::Draw(id<MTLRenderCommandEncoder> encoder,
|
||||
id<MTLBuffer> vertexBuffer,
|
||||
const float *modelViewProjectionMatrix) {
|
||||
[encoder setRenderPipelineState: _renderPipelineState];
|
||||
[encoder setVertexBuffer:vertexBuffer offset:0 atIndex:0];
|
||||
[encoder setVertexBytes:modelViewProjectionMatrix length: sizeof(float) * 16 atIndex:2];
|
||||
|
||||
if(_displayEdges) {
|
||||
[encoder setVertexBuffer:_edgeSharpnessBuffer offset:0 atIndex:1];
|
||||
[encoder drawIndexedPrimitives:MTLPrimitiveTypeLine
|
||||
indexCount:_numEdges * 2
|
||||
indexType:MTLIndexTypeUInt32
|
||||
indexBuffer:_edgeIndicesBuffer
|
||||
indexBufferOffset:0
|
||||
instanceCount:1
|
||||
baseVertex:0
|
||||
baseInstance:0];
|
||||
}
|
||||
|
||||
if(_displayVertices) {
|
||||
[encoder setVertexBuffer:_vertexSharpnessBuffer offset:0 atIndex:1];
|
||||
[encoder drawPrimitives:MTLPrimitiveTypePoint
|
||||
vertexStart:0
|
||||
vertexCount:_numPoints];
|
||||
}
|
||||
}
|
||||
55
blender-5.2.0/extern/opensubdiv-source/examples/common/mtlHud.h
vendored
Normal file
55
blender-5.2.0/extern/opensubdiv-source/examples/common/mtlHud.h
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// Copyright 2016 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef OPENSUBDIV_EXAMPLES_MTL_HUD_H
|
||||
#define OPENSUBDIV_EXAMPLES_MTL_HUD_H
|
||||
|
||||
@protocol MTLTexture;
|
||||
@protocol MTLBuffer;
|
||||
@protocol MTLRenderCommandEncoder;
|
||||
@protocol MTLRenderPipelineState;
|
||||
@protocol MTLDevice;
|
||||
@class MTLRenderPipelineDescriptor;
|
||||
@class MTLDepthStencilDescriptor;
|
||||
|
||||
#include "hud.h"
|
||||
#include "mtlUtils.h"
|
||||
|
||||
class MTLhud : public Hud {
|
||||
|
||||
public:
|
||||
MTLhud();
|
||||
~MTLhud();
|
||||
|
||||
virtual void Init(id<MTLDevice> device, MTLRenderPipelineDescriptor* parentPipelineDescriptor, MTLDepthStencilDescriptor* depthStencilStateDescriptor,
|
||||
int width, int height, int framebufferWidth, int framebufferHeight);
|
||||
|
||||
virtual void Rebuild(int width, int height,
|
||||
int framebufferWidth, int framebufferHeight);
|
||||
|
||||
virtual bool Flush(id<MTLRenderCommandEncoder> encoder);
|
||||
|
||||
id<MTLTexture> GetFontTexture() const {
|
||||
return _fontTexture;
|
||||
}
|
||||
|
||||
void FillBackground(id<MTLRenderCommandEncoder> encoder);
|
||||
|
||||
float UIScale = 1.0f;
|
||||
|
||||
private:
|
||||
id<MTLDevice> _device;
|
||||
id<MTLTexture> _fontTexture;
|
||||
OpenSubdiv::OPENSUBDIV_VERSION::Osd::MTLRingBuffer<float, 1> _staticBuffer;
|
||||
OpenSubdiv::OPENSUBDIV_VERSION::Osd::MTLRingBuffer<float, 3> _dynamicBuffer;
|
||||
|
||||
id<MTLRenderPipelineState> _fgPipelineState, _bgPipelineState;
|
||||
id<MTLDepthStencilState> _depthStencilState;
|
||||
};
|
||||
|
||||
|
||||
#endif //OPENSUBDIV_EXAMPLES_MTL_HUD_H
|
||||
191
blender-5.2.0/extern/opensubdiv-source/examples/common/mtlHud.mm
vendored
Normal file
191
blender-5.2.0/extern/opensubdiv-source/examples/common/mtlHud.mm
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
//
|
||||
// Copyright 2016 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#include "mtlHud.h"
|
||||
#include "font_image.h"
|
||||
#include "simple_math.h"
|
||||
#include <Metal/Metal.h>
|
||||
|
||||
static const char* shaderSource = R"(
|
||||
#include <metal_stdlib>
|
||||
using namespace metal;
|
||||
|
||||
struct VertexInput {
|
||||
float2 position [[attribute(0)]];
|
||||
float3 color [[attribute(1)]];
|
||||
float2 uv [[attribute(2)]];
|
||||
};
|
||||
|
||||
struct VertexOutput {
|
||||
float4 position [[position]];
|
||||
float4 color;
|
||||
float2 uv;
|
||||
};
|
||||
|
||||
|
||||
|
||||
vertex VertexOutput fg_vertex(
|
||||
VertexInput in [[stage_in]],
|
||||
constant const float4x4& ModelViewProjectionMatrix [[buffer(1)]],
|
||||
constant const float& UIScale [[buffer(2)]]
|
||||
) {
|
||||
VertexOutput out;
|
||||
|
||||
out.position = ModelViewProjectionMatrix * float4(in.position * UIScale, 0, 1);
|
||||
out.color = float4(in.color, 1);
|
||||
out.uv = in.uv;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
fragment float4 fg_fragment(
|
||||
VertexOutput in [[stage_in]],
|
||||
texture2d<float, access::sample> fontTexture [[texture(0)]]
|
||||
) {
|
||||
|
||||
constexpr sampler s = sampler(coord::normalized, address::clamp_to_zero, filter::nearest);
|
||||
auto c = fontTexture.sample(s, in.uv);
|
||||
if(c.a == 0)
|
||||
discard_fragment();
|
||||
|
||||
return c * in.color;
|
||||
}
|
||||
|
||||
constant float4 bgVertices[] = {
|
||||
{-1, 1, 0, 1},
|
||||
{1, 1, 0, 1},
|
||||
{-1, -1, 0, 1},
|
||||
{1, -1, 0, 1}
|
||||
};
|
||||
|
||||
vertex VertexOutput bg_vertex(uint vertex_id [[vertex_id]]) {
|
||||
VertexOutput out;
|
||||
|
||||
out.position = bgVertices[vertex_id];
|
||||
out.uv = bgVertices[vertex_id].xy * 0.5 + 0.5 * 3.14159;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
fragment float4 bg_fragment(VertexOutput in [[stage_in]]) {
|
||||
return float4(float3(mix(0.1, 0.5, sin(in.uv.y))), 1);
|
||||
}
|
||||
|
||||
)";
|
||||
|
||||
|
||||
MTLhud::MTLhud() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
MTLhud::~MTLhud() {
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
MTLhud::Init(id<MTLDevice> device, MTLRenderPipelineDescriptor* parentPipelineDescriptor, MTLDepthStencilDescriptor* depthStencilStateDescriptor, int width, int height, int framebufferWidth, int framebufferHeight) {
|
||||
Hud::Init(width, height, framebufferWidth, framebufferHeight);
|
||||
|
||||
@autoreleasepool {
|
||||
_device = device;
|
||||
const auto textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm width:FONT_TEXTURE_WIDTH height:FONT_TEXTURE_HEIGHT mipmapped:false];
|
||||
_fontTexture = [_device newTextureWithDescriptor:textureDescriptor];
|
||||
[_fontTexture replaceRegion: { {0, 0, 0}, {FONT_TEXTURE_WIDTH, FONT_TEXTURE_HEIGHT, 1} } mipmapLevel:0 withBytes:font_image bytesPerRow:4 * FONT_TEXTURE_WIDTH];
|
||||
|
||||
NSError* err = nil;
|
||||
const auto library = [_device newLibraryWithSource:@(shaderSource) options:nil error:&err];
|
||||
assert(err == nil);
|
||||
|
||||
const auto renderPipelineDescriptor = (MTLRenderPipelineDescriptor*)[parentPipelineDescriptor copy];
|
||||
renderPipelineDescriptor.vertexFunction = [library newFunctionWithName:@"bg_vertex"];
|
||||
renderPipelineDescriptor.fragmentFunction = [library newFunctionWithName:@"bg_fragment"];
|
||||
|
||||
_bgPipelineState = [_device newRenderPipelineStateWithDescriptor:renderPipelineDescriptor error:&err];
|
||||
|
||||
renderPipelineDescriptor.vertexFunction = [library newFunctionWithName:@"fg_vertex"];
|
||||
renderPipelineDescriptor.fragmentFunction = [library newFunctionWithName:@"fg_fragment"];
|
||||
const auto vertexDescriptor = renderPipelineDescriptor.vertexDescriptor;
|
||||
|
||||
vertexDescriptor.layouts[0].stride = sizeof(float) * 7;
|
||||
vertexDescriptor.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex;
|
||||
vertexDescriptor.layouts[0].stepRate = 1;
|
||||
|
||||
vertexDescriptor.attributes[0].offset = 0;
|
||||
vertexDescriptor.attributes[0].format = MTLVertexFormatFloat2;
|
||||
vertexDescriptor.attributes[0].bufferIndex = 0;
|
||||
|
||||
vertexDescriptor.attributes[1].offset = sizeof(float) * 2;
|
||||
vertexDescriptor.attributes[1].format = MTLVertexFormatFloat3;
|
||||
vertexDescriptor.attributes[1].bufferIndex = 0;
|
||||
|
||||
vertexDescriptor.attributes[2].offset = sizeof(float) * 5;
|
||||
vertexDescriptor.attributes[2].format = MTLVertexFormatFloat2;
|
||||
vertexDescriptor.attributes[2].bufferIndex = 0;
|
||||
|
||||
_fgPipelineState = [_device newRenderPipelineStateWithDescriptor:renderPipelineDescriptor error:&err];
|
||||
|
||||
_depthStencilState = [_device newDepthStencilStateWithDescriptor:depthStencilStateDescriptor];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
MTLhud::Rebuild(int width, int height, int framebufferWidth, int framebufferHeight) {
|
||||
Hud::Rebuild(width, height, framebufferWidth, framebufferHeight);
|
||||
|
||||
_staticBuffer.alloc(_device, getStaticVboSource().size(), @"MTLhud static buffer");
|
||||
std::copy(getStaticVboSource().begin(), getStaticVboSource().end(), _staticBuffer.data());
|
||||
_staticBuffer.markModified();
|
||||
}
|
||||
|
||||
bool
|
||||
MTLhud::Flush(id<MTLRenderCommandEncoder> encoder) {
|
||||
if(!Hud::Flush())
|
||||
return false;
|
||||
|
||||
if(_dynamicBuffer.buffer().length < sizeof(float) * getVboSource().size()) {
|
||||
_dynamicBuffer.alloc(_device, getVboSource().size(), @"MTLhud dynamic buffer");
|
||||
} else {
|
||||
_dynamicBuffer.next();
|
||||
}
|
||||
|
||||
std::copy(getVboSource().begin(), getVboSource().end(), _dynamicBuffer.data());
|
||||
_dynamicBuffer.markModified();
|
||||
const auto numVertices = getVboSource().size() / 7;
|
||||
getVboSource().clear();
|
||||
|
||||
float proj[16];
|
||||
ortho(proj, 0, 0, float(GetWidth()), float(GetHeight()));
|
||||
|
||||
[encoder setVertexBuffer: _dynamicBuffer.buffer() offset:0 atIndex:0];
|
||||
[encoder setRenderPipelineState: _fgPipelineState];
|
||||
[encoder setDepthStencilState: _depthStencilState];
|
||||
[encoder setVertexBytes: proj length: sizeof(proj) atIndex:1];
|
||||
[encoder setVertexBytes: &UIScale length:sizeof(UIScale) atIndex:2];
|
||||
[encoder setFragmentTexture: _fontTexture atIndex:0];
|
||||
|
||||
if(numVertices > 0) {
|
||||
[encoder setVertexBuffer:_dynamicBuffer.buffer() offset:0 atIndex:0];
|
||||
[encoder drawPrimitives: MTLPrimitiveTypeTriangle vertexStart:0 vertexCount: numVertices];
|
||||
}
|
||||
|
||||
auto numStaticVertices = [_staticBuffer.buffer() length] / (7 * sizeof(float));
|
||||
if(numStaticVertices > 0) {
|
||||
[encoder setVertexBuffer:_staticBuffer.buffer() offset:0 atIndex:0];
|
||||
[encoder drawPrimitives: MTLPrimitiveTypeTriangle vertexStart:0 vertexCount: numStaticVertices];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
MTLhud::FillBackground(id<MTLRenderCommandEncoder> encoder) {
|
||||
[encoder setRenderPipelineState: _bgPipelineState];
|
||||
[encoder setDepthStencilState: _depthStencilState];
|
||||
[encoder drawPrimitives: MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount: 4];
|
||||
}
|
||||
366
blender-5.2.0/extern/opensubdiv-source/examples/common/mtlPtexCommon.metal
vendored
Normal file
366
blender-5.2.0/extern/opensubdiv-source/examples/common/mtlPtexCommon.metal
vendored
Normal file
@@ -0,0 +1,366 @@
|
||||
#line 0 "examples/common/mtlPtexCommon.metal"
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
//----------------------------------------------------------
|
||||
// Ptex.Common
|
||||
//----------------------------------------------------------
|
||||
|
||||
template<typename T>
|
||||
T lerp(T x, T y, float a)
|
||||
{
|
||||
return x + (y - x) * a;
|
||||
}
|
||||
|
||||
template<>
|
||||
int lerp<int>(int x, int y, float a)
|
||||
{
|
||||
return x + (y - x) * a;
|
||||
}
|
||||
|
||||
struct PtexPacking {
|
||||
int page;
|
||||
int nMipmap;
|
||||
int uOffset;
|
||||
int vOffset;
|
||||
int adjSizeDiffs[4];
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
PtexPacking getPtexPacking(device ushort* packings, int faceID)
|
||||
{
|
||||
PtexPacking packing;
|
||||
packing.page = packings[faceID*6+0];
|
||||
packing.nMipmap = packings[faceID*6+1];
|
||||
packing.uOffset = packings[faceID*6+2];
|
||||
packing.vOffset = packings[faceID*6+3];
|
||||
int wh = packings[faceID*6+5];
|
||||
packing.width = 1 << (wh >> 8);
|
||||
packing.height = 1 << (wh & 0xff);
|
||||
|
||||
int adjSizeDiffs = packings[faceID*6+4];
|
||||
packing.adjSizeDiffs[0] = (adjSizeDiffs >> 12) & 0xf;
|
||||
packing.adjSizeDiffs[1] = (adjSizeDiffs >> 8) & 0xf;
|
||||
packing.adjSizeDiffs[2] = (adjSizeDiffs >> 4) & 0xf;
|
||||
packing.adjSizeDiffs[3] = (adjSizeDiffs >> 0) & 0xf;
|
||||
|
||||
return packing;
|
||||
}
|
||||
|
||||
int computeMipmapOffsetU(int w, int level)
|
||||
{
|
||||
int width = 1 << w;
|
||||
int m = (0x55555555 & (width | (width-1))) << (w&1);
|
||||
int x = ~((1 << (w -((level-1)&~1))) - 1);
|
||||
return (m & x) + ((level+1)&~1);
|
||||
}
|
||||
|
||||
int computeMipmapOffsetV(int h, int level)
|
||||
{
|
||||
int height = 1 << h;
|
||||
int m = (0x55555555 & (height-1)) << ((h+1)&1);;
|
||||
int x = ~((1 << (h - (level&~1))) - 1 );
|
||||
return (m & x) + (level&~1);
|
||||
}
|
||||
|
||||
PtexPacking getPtexPacking(device ushort* packings, int faceID, int level)
|
||||
{
|
||||
PtexPacking packing;
|
||||
packing.page = packings[faceID*6+0];
|
||||
packing.nMipmap = packings[faceID*6+1];
|
||||
packing.uOffset = packings[faceID*6+2];
|
||||
packing.vOffset = packings[faceID*6+3];
|
||||
//int sizeDiffs = packings[faceID*6+4];
|
||||
int wh = packings[faceID*6+5];
|
||||
int w = wh >> 8;
|
||||
int h = wh & 0xff;
|
||||
|
||||
// clamp max level
|
||||
level = min(level, packing.nMipmap);
|
||||
|
||||
packing.uOffset += computeMipmapOffsetU(w, level);
|
||||
packing.vOffset += computeMipmapOffsetV(h, level);
|
||||
packing.width = 1 << (w-level);
|
||||
packing.height = 1 << (h-level);
|
||||
|
||||
return packing;
|
||||
}
|
||||
|
||||
void evalQuadraticBSpline(float u, thread float3& B, thread float3& BU)
|
||||
{
|
||||
B[0] = 0.5 * (u*u - 2.0*u + 1);
|
||||
B[1] = 0.5 + u - u*u;
|
||||
B[2] = 0.5 * u*u;
|
||||
|
||||
BU[0] = u - 1.0;
|
||||
BU[1] = 1 - 2 * u;
|
||||
BU[2] = u;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Non-Mipmap Lookups
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
template<typename Texture>
|
||||
auto PtexLookupNearest(float4 patchCoord,
|
||||
Texture data,
|
||||
device ushort* packings) -> decltype(data.read(uint2(), int()))
|
||||
{
|
||||
float2 uv = clamp(patchCoord.xy, float2(0,0), float2(1,1));
|
||||
int faceID = int(patchCoord.w);
|
||||
PtexPacking ppack = getPtexPacking(packings, faceID);
|
||||
float2 coords = float2(uv.x * ppack.width + ppack.uOffset,
|
||||
uv.y * ppack.height + ppack.vOffset);
|
||||
return float4(data.read(uint2(coords.x, coords.y), ppack.page));
|
||||
}
|
||||
|
||||
template<typename Texture>
|
||||
auto PtexLookupNearest(float4 patchCoord,
|
||||
int level,
|
||||
Texture data,
|
||||
device ushort* packings) -> decltype(data.read(uint2(), int()))
|
||||
{
|
||||
float2 uv = clamp(patchCoord.xy, float2(0,0), float2(1,1));
|
||||
int faceID = int(patchCoord.w);
|
||||
PtexPacking ppack = getPtexPacking(packings, faceID, level);
|
||||
float2 coords = float2(uv.x * ppack.width + ppack.uOffset,
|
||||
uv.y * ppack.height + ppack.vOffset);
|
||||
return float4(data.read(uint2(coords.x, coords.y), ppack.page));
|
||||
}
|
||||
|
||||
|
||||
template<typename Texture>
|
||||
auto PtexLookupFast(float4 patchCoord,
|
||||
Texture data,
|
||||
device ushort* packings) -> decltype(data.sample(sampler(), float2(), int()))
|
||||
{
|
||||
constexpr sampler smp(coord::normalized, address::clamp_to_edge, filter::linear);
|
||||
|
||||
float2 uv = clamp(patchCoord.xy, float2(0), float2(1));
|
||||
int faceID = int(patchCoord.w);
|
||||
PtexPacking ppack = getPtexPacking(packings, faceID);
|
||||
float2 coords = float2((uv.x * ppack.width + ppack.uOffset),
|
||||
(uv.y * ppack.height + ppack.vOffset)) / float2(data.get_width(), data.get_height());
|
||||
return data.sample(smp, coords, ppack.page);
|
||||
}
|
||||
|
||||
|
||||
template<typename Texture>
|
||||
auto PtexLookupFast(float4 patchCoord,
|
||||
float level,
|
||||
Texture data,
|
||||
device ushort* packings) -> decltype(data.sample(sampler(), float2(), int(), bias(level)))
|
||||
{
|
||||
constexpr sampler smp(coord::normalized, address::clamp_to_edge, filter::linear);
|
||||
|
||||
float2 uv = clamp(patchCoord.xy, float2(0), float2(1));
|
||||
int faceID = int(patchCoord.w);
|
||||
PtexPacking ppack = getPtexPacking(packings, faceID, level);
|
||||
float2 coords = float2((uv.x * ppack.width + ppack.uOffset),
|
||||
(uv.y * ppack.height + ppack.vOffset)) / float2(data.get_width(), data.get_height());
|
||||
|
||||
return data.sample(smp, coords, ppack.page, bias(level));
|
||||
}
|
||||
|
||||
template<typename Texture>
|
||||
auto PtexLookup(float4 patchCoord,
|
||||
int level,
|
||||
Texture data,
|
||||
device ushort* packings) -> decltype(data.read(uint2(), int()))
|
||||
{
|
||||
float2 uv = clamp(patchCoord.xy, float2(0,0), float2(1,1));
|
||||
int faceID = int(patchCoord.w);
|
||||
PtexPacking ppack = getPtexPacking(packings, faceID, level);
|
||||
|
||||
float2 coords = float2(uv.x * ppack.width + ppack.uOffset,
|
||||
uv.y * ppack.height + ppack.vOffset);
|
||||
|
||||
coords -= float2(0.5, 0.5);
|
||||
|
||||
int c0X = int(floor(coords.x));
|
||||
int c1X = int(ceil(coords.x));
|
||||
int c0Y = int(floor(coords.y));
|
||||
int c1Y = int(ceil(coords.y));
|
||||
|
||||
float t = coords.x - float(c0X);
|
||||
float s = coords.y - float(c0Y);
|
||||
|
||||
const auto d0 = float4(data.read(uint2(c0X, c0Y), ppack.page));
|
||||
const auto d1 = float4(data.read(uint2(c0X, c1Y), ppack.page));
|
||||
const auto d2 = float4(data.read(uint2(c1X, c0Y), ppack.page));
|
||||
const auto d3 = float4(data.read(uint2(c1X, c1Y), ppack.page));
|
||||
|
||||
const auto result = (1.0f-t) * ((1.0f-s)*d0 + s*d1) + t * ((1.0f-s)*d2 + s*d3);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Texture>
|
||||
auto PtexLookupQuadratic(thread float4& du,
|
||||
thread float4& dv,
|
||||
float4 patchCoord,
|
||||
int level,
|
||||
Texture data,
|
||||
device ushort* packings) -> decltype(data.read(uint2(), int()))
|
||||
{
|
||||
using dataType = decltype(data.read(uint2(), int()));
|
||||
|
||||
float2 uv = clamp(patchCoord.xy, float2(0,0), float2(1,1));
|
||||
int faceID = int(patchCoord.w);
|
||||
PtexPacking ppack = getPtexPacking(packings, faceID, level);
|
||||
|
||||
float2 coords = float2(uv.x * ppack.width + ppack.uOffset,
|
||||
uv.y * ppack.height + ppack.vOffset);
|
||||
|
||||
coords -= float2(0.5, 0.5);
|
||||
|
||||
int cX = int(round(coords.x));
|
||||
int cY = int(round(coords.y));
|
||||
|
||||
float x = 0.5 - (float(cX) - coords.x);
|
||||
float y = 0.5 - (float(cY) - coords.y);
|
||||
|
||||
dataType d[9];
|
||||
d[0] = data.read(uint2(cX-1, cY-1), ppack.page);
|
||||
d[1] = data.read(uint2(cX-1, cY-0), ppack.page);
|
||||
d[2] = data.read(uint2(cX-1, cY+1), ppack.page);
|
||||
d[3] = data.read(uint2(cX-0, cY-1), ppack.page);
|
||||
d[4] = data.read(uint2(cX-0, cY-0), ppack.page);
|
||||
d[5] = data.read(uint2(cX-0, cY+1), ppack.page);
|
||||
d[6] = data.read(uint2(cX+1, cY-1), ppack.page);
|
||||
d[7] = data.read(uint2(cX+1, cY-0), ppack.page);
|
||||
d[8] = data.read(uint2(cX+1, cY+1), ppack.page);
|
||||
|
||||
float3 B, D;
|
||||
dataType BUCP[3] = {dataType(0), dataType(0), dataType(0)},
|
||||
DUCP[3] = {dataType(0), dataType(0), dataType(0)};
|
||||
|
||||
evalQuadraticBSpline(y, B, D);
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
float4 A = d[i*3+j];
|
||||
BUCP[i] += A * B[j];
|
||||
DUCP[i] += A * D[j];
|
||||
}
|
||||
}
|
||||
|
||||
evalQuadraticBSpline(x, B, D);
|
||||
|
||||
dataType result = dataType(0);
|
||||
du = dataType(0);
|
||||
dv = dataType(0);
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
result += B[i] * BUCP[i];
|
||||
du += D[i] * BUCP[i];
|
||||
dv += B[i] * DUCP[i];
|
||||
}
|
||||
|
||||
du *= ppack.width;
|
||||
dv *= ppack.height;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// MipMap Lookups
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
template<typename Texture>
|
||||
auto PtexMipmapLookupNearest(float4 patchCoord,
|
||||
float level,
|
||||
Texture data,
|
||||
device ushort* packings) -> decltype(PtexLookupNearest(patchCoord, int(), data, packings))
|
||||
{
|
||||
#if SEAMLESS_MIPMAP
|
||||
// diff level
|
||||
int faceID = int(patchCoord.w);
|
||||
float2 uv = patchCoord.xy;
|
||||
PtexPacking packing = getPtexPacking(packings, faceID);
|
||||
level += lerp(lerp(packing.adjSizeDiffs[0], packing.adjSizeDiffs[1], uv.x),
|
||||
lerp(packing.adjSizeDiffs[3], packing.adjSizeDiffs[2], uv.x),
|
||||
uv.y);
|
||||
#endif
|
||||
|
||||
int levelm = int(floor(level));
|
||||
int levelp = int(ceil(level));
|
||||
float t = level - float(levelm);
|
||||
|
||||
const auto result = (1-t) * PtexLookupNearest(patchCoord, levelm, data, packings)
|
||||
+ t * PtexLookupNearest(patchCoord, levelp, data, packings);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Texture>
|
||||
auto PtexMipmapLookup(float4 patchCoord,
|
||||
float level,
|
||||
Texture data,
|
||||
device ushort* packings) -> decltype(PtexLookup(patchCoord, int(), data, packings))
|
||||
{
|
||||
#if SEAMLESS_MIPMAP
|
||||
// diff level
|
||||
int faceID = int(patchCoord.w);
|
||||
float2 uv = patchCoord.xy;
|
||||
PtexPacking packing = getPtexPacking(packings, faceID);
|
||||
level += lerp(lerp(packing.adjSizeDiffs[0], packing.adjSizeDiffs[1], uv.x),
|
||||
lerp(packing.adjSizeDiffs[3], packing.adjSizeDiffs[2], uv.x),
|
||||
uv.y);
|
||||
#endif
|
||||
|
||||
int levelm = int(floor(level));
|
||||
int levelp = int(ceil(level));
|
||||
float t = level - float(levelm);
|
||||
|
||||
const auto result = (1-t) * PtexLookup(patchCoord, levelm, data, packings)
|
||||
+ t * PtexLookup(patchCoord, levelp, data, packings);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Texture>
|
||||
auto PtexMipmapLookupQuadratic(thread float4& du,
|
||||
thread float4& dv,
|
||||
float4 patchCoord,
|
||||
float level,
|
||||
Texture data,
|
||||
device ushort* packings) -> decltype(PtexLookupQuadratic(du, dv, patchCoord, int(), data, packings))
|
||||
{
|
||||
using dataType = decltype(PtexLookupQuadratic(du, dv, patchCoord, int(), data, packings));
|
||||
#if SEAMLESS_MIPMAP
|
||||
// diff level
|
||||
int faceID = int(patchCoord.w);
|
||||
float2 uv = patchCoord.xy;
|
||||
PtexPacking packing = getPtexPacking(packings, faceID);
|
||||
level += lerp(lerp(packing.adjSizeDiffs[0], packing.adjSizeDiffs[1], uv.x),
|
||||
lerp(packing.adjSizeDiffs[3], packing.adjSizeDiffs[2], uv.x),
|
||||
uv.y);
|
||||
#endif
|
||||
|
||||
int levelm = int(floor(level));
|
||||
int levelp = int(ceil(level));
|
||||
float t = level - float(levelm);
|
||||
|
||||
float4 du0, du1, dv0, dv1;
|
||||
const auto r0 = PtexLookupQuadratic(du0, dv0, patchCoord, levelm, data, packings);
|
||||
const auto r1 = PtexLookupQuadratic(du1, dv1, patchCoord, levelp, data, packings);
|
||||
|
||||
const auto result = lerp(r0, r1, t);
|
||||
du = lerp(du0, du1, t);
|
||||
dv = lerp(dv0, dv1, t);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Texture>
|
||||
auto PtexMipmapLookupQuadratic(float4 patchCoord,
|
||||
float level,
|
||||
Texture data,
|
||||
device ushort* packings) -> decltype(data.read(uint2(), int())) //decltype(PtexMipmapLookupQuadratic(float4(), float4(), patchCoord, level, packings)) //Not using the correct decltpye due to the need for thread& types
|
||||
{
|
||||
float4 du, dv;
|
||||
return PtexMipmapLookupQuadratic(du, dv, patchCoord, level, data, packings);
|
||||
}
|
||||
41
blender-5.2.0/extern/opensubdiv-source/examples/common/mtlPtexMipmapTexture.h
vendored
Normal file
41
blender-5.2.0/extern/opensubdiv-source/examples/common/mtlPtexMipmapTexture.h
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef OPENSUBDIV_EXAMPLES_MTL_PTEX_MIPMAP_TEXTURE_H
|
||||
#define OPENSUBDIV_EXAMPLES_MTL_PTEX_MIPMAP_TEXTURE_H
|
||||
|
||||
#include <opensubdiv/osd/mtlCommon.h>
|
||||
#include <opensubdiv/osd/nonCopyable.h>
|
||||
#include <Ptexture.h>
|
||||
|
||||
|
||||
@protocol MTLBuffer;
|
||||
@protocol MTLTexture;
|
||||
@class MTLTextureDescriptor;
|
||||
|
||||
class MTLPtexMipmapTexture : OpenSubdiv::Osd::NonCopyable<MTLPtexMipmapTexture> {
|
||||
public:
|
||||
static MTLPtexMipmapTexture * Create(OpenSubdiv::Osd::MTLContext * deviceContext,
|
||||
PtexTexture * reader,
|
||||
int maxLevels = 10);
|
||||
|
||||
|
||||
static const char* GetShaderSource();
|
||||
|
||||
id<MTLBuffer> GetLayoutBuffer() const { return _layout; }
|
||||
id<MTLTexture> GetTexelsTexture() const { return _texels; }
|
||||
|
||||
private:
|
||||
MTLPtexMipmapTexture();
|
||||
|
||||
id<MTLBuffer> _layout;
|
||||
id<MTLTexture> _texels;
|
||||
|
||||
MTLTextureDescriptor* _textureDescriptor;
|
||||
};
|
||||
|
||||
#endif // OPENSUBDIV_EXAMPLES_MTL_PTEX_TEXTURE_H
|
||||
114
blender-5.2.0/extern/opensubdiv-source/examples/common/mtlPtexMipmapTexture.mm
vendored
Normal file
114
blender-5.2.0/extern/opensubdiv-source/examples/common/mtlPtexMipmapTexture.mm
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#include "mtlPtexMipmapTexture.h"
|
||||
#include "ptexMipmapTextureLoader.h"
|
||||
#include <opensubdiv/far/error.h>
|
||||
#include <Metal/Metal.h>
|
||||
#include <cassert>
|
||||
|
||||
#include "mtlUtils.h"
|
||||
|
||||
using namespace OpenSubdiv;
|
||||
|
||||
MTLPtexMipmapTexture::MTLPtexMipmapTexture() :
|
||||
_layout(nil), _texels(nil), _textureDescriptor(nil) {
|
||||
}
|
||||
|
||||
const char* MTLPtexMipmapTexture::GetShaderSource() {
|
||||
static const char* shaderSource =
|
||||
#include "mtlPtexCommon.gen.h"
|
||||
;
|
||||
return shaderSource;
|
||||
}
|
||||
|
||||
MTLPtexMipmapTexture * MTLPtexMipmapTexture::Create(Osd::MTLContext *deviceContext, PtexTexture *reader, int maxLevels) {
|
||||
const auto maxNumPages = 2048;
|
||||
|
||||
size_t targetMemory = 0;
|
||||
|
||||
// Read the ptex data and pack the texels
|
||||
bool padAlpha = reader->numChannels()==3;
|
||||
|
||||
PtexMipmapTextureLoader loader(reader,
|
||||
maxNumPages,
|
||||
maxLevels,
|
||||
targetMemory,
|
||||
true/*seemlessMipmap*/,
|
||||
padAlpha);
|
||||
const auto numFaces = loader.GetNumFaces();
|
||||
|
||||
const auto layoutBuffer = [deviceContext->device newBufferWithBytes:loader.GetLayoutBuffer() length:numFaces * 6 * sizeof(short) options:Osd::MTLDefaultStorageMode];
|
||||
|
||||
const auto textureDescriptor = [MTLTextureDescriptor new];
|
||||
int bpp = 0;
|
||||
textureDescriptor.pixelFormat = [&]() {
|
||||
const auto numChannels = reader->numChannels() + padAlpha;
|
||||
switch(reader->dataType()) {
|
||||
case Ptex::dt_uint16:
|
||||
bpp = sizeof(short) * numChannels;
|
||||
switch(numChannels) {
|
||||
case 1: return MTLPixelFormatR16Unorm;
|
||||
case 2: return MTLPixelFormatRG16Unorm;
|
||||
case 3: assert("RGB16Uint not supported"); break;
|
||||
case 4: return MTLPixelFormatRGBA16Unorm;
|
||||
}
|
||||
case Ptex::dt_float:
|
||||
bpp = sizeof(float) * numChannels;
|
||||
switch(numChannels) {
|
||||
case 1: return MTLPixelFormatR32Float;
|
||||
case 2: return MTLPixelFormatRG32Float;
|
||||
case 3: assert("RGB32Float not supported"); break;
|
||||
case 4: return MTLPixelFormatRGBA32Float;
|
||||
}
|
||||
case Ptex::dt_half:
|
||||
bpp = sizeof(short) * numChannels;
|
||||
switch(numChannels) {
|
||||
case 1: return MTLPixelFormatR16Float;
|
||||
case 2: return MTLPixelFormatRG16Float;
|
||||
case 3: assert("RGB16Float not supported"); break;
|
||||
case 4: return MTLPixelFormatRGBA16Float;
|
||||
}
|
||||
default:
|
||||
bpp = numChannels;
|
||||
switch(numChannels) {
|
||||
case 1: return MTLPixelFormatR8Unorm;
|
||||
case 2: return MTLPixelFormatRG8Unorm;
|
||||
case 3: assert("RGB8Unorm not supported"); break;
|
||||
case 4: return MTLPixelFormatRGBA8Unorm;
|
||||
}
|
||||
}
|
||||
return MTLPixelFormatInvalid;
|
||||
}();
|
||||
textureDescriptor.width = loader.GetPageWidth();
|
||||
textureDescriptor.height = loader.GetPageHeight();
|
||||
textureDescriptor.arrayLength = loader.GetNumPages();
|
||||
textureDescriptor.mipmapLevelCount = 1;
|
||||
textureDescriptor.usage = MTLTextureUsageShaderRead;
|
||||
textureDescriptor.textureType = MTLTextureType2DArray;
|
||||
|
||||
const auto texelsTexture = [deviceContext->device newTextureWithDescriptor:textureDescriptor];
|
||||
if(!texelsTexture)
|
||||
return nullptr;
|
||||
|
||||
auto result = new MTLPtexMipmapTexture();
|
||||
result->_textureDescriptor = textureDescriptor;
|
||||
result->_layout = layoutBuffer;
|
||||
result->_texels = texelsTexture;
|
||||
|
||||
MTLRegion replaceRegion = MTLRegionMake2D(0, 0, loader.GetPageWidth(), loader.GetPageHeight());
|
||||
const auto bytesPerRow = loader.GetPageWidth() * bpp;
|
||||
const auto bytesPerImage = bytesPerRow * loader.GetPageHeight();
|
||||
for(auto i = 0; i < loader.GetNumPages(); i++) {
|
||||
[texelsTexture replaceRegion:replaceRegion mipmapLevel:0 slice:i
|
||||
withBytes:loader.GetTexelBuffer() + i * bytesPerImage bytesPerRow:bytesPerRow bytesPerImage:bytesPerImage];
|
||||
}
|
||||
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
104
blender-5.2.0/extern/opensubdiv-source/examples/common/mtlUtils.h
vendored
Normal file
104
blender-5.2.0/extern/opensubdiv-source/examples/common/mtlUtils.h
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
//
|
||||
// Copyright 2015 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef OPENSUBDIV_EXAMPLES_MTL_UTILS_H
|
||||
#define OPENSUBDIV_EXAMPLES_MTL_UTILS_H
|
||||
|
||||
#include <Metal/Metal.h>
|
||||
#include <cstring>
|
||||
#include <TargetConditionals.h>
|
||||
#include <vector>
|
||||
|
||||
namespace OpenSubdiv { namespace OPENSUBDIV_VERSION { namespace Osd {
|
||||
#if TARGET_OS_EMBEDDED
|
||||
constexpr auto MTLDefaultStorageMode = MTLResourceStorageModeShared;
|
||||
#else
|
||||
constexpr auto MTLDefaultStorageMode = MTLResourceStorageModeManaged;
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
id<MTLBuffer> MTLNewBufferFromVector(id<MTLDevice> device, const std::vector<T>& vec) {
|
||||
const auto typeSize = sizeof(T);
|
||||
const auto bufferSize = typeSize * vec.size();
|
||||
return [device newBufferWithBytes:vec.data() length:bufferSize options:MTLDefaultStorageMode];
|
||||
}
|
||||
|
||||
template<typename DataType, size_t RingLength>
|
||||
class MTLRingBuffer {
|
||||
private:
|
||||
id<MTLBuffer> _buffers[RingLength];
|
||||
uint _bufferIndex;
|
||||
|
||||
public:
|
||||
template<typename SizedType = DataType>
|
||||
MTLRingBuffer(id<MTLDevice> device, size_t count, NSString* label, MTLResourceOptions options = MTLDefaultStorageMode) {
|
||||
alloc<SizedType>(device, count, options, label);
|
||||
}
|
||||
|
||||
MTLRingBuffer() {
|
||||
for(uint i = 0; i < RingLength; i++) {
|
||||
_buffers[i] = nil;
|
||||
}
|
||||
_bufferIndex = 0;
|
||||
}
|
||||
|
||||
void markModified() const {
|
||||
#if !TARGET_OS_EMBEDDED
|
||||
const auto bufferLength = [buffer() length];
|
||||
[buffer() didModifyRange: NSMakeRange(0, bufferLength)];
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename SizedType = DataType>
|
||||
void alloc(id<MTLDevice> device, size_t count, NSString* label, MTLResourceOptions options = MTLDefaultStorageMode) {
|
||||
if(count) {
|
||||
for(uint i = 0; i < RingLength; i++) {
|
||||
_buffers[i] = [device newBufferWithLength: count * sizeof(SizedType) options:options];
|
||||
_buffers[i].label = label;
|
||||
_bufferIndex = i;
|
||||
|
||||
if((options & MTLResourceStorageModePrivate) == 0)
|
||||
{
|
||||
memset(data(), 0, count * sizeof(SizedType));
|
||||
markModified();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(uint i = 0; i < RingLength; i++) {
|
||||
_buffers[i] = nil;
|
||||
}
|
||||
}
|
||||
_bufferIndex = 0;
|
||||
}
|
||||
|
||||
id<MTLBuffer> buffer() const {
|
||||
return _buffers[_bufferIndex];
|
||||
}
|
||||
|
||||
DataType* data() const {
|
||||
return reinterpret_cast<DataType*>([buffer() contents]);
|
||||
}
|
||||
|
||||
void next() {
|
||||
_bufferIndex = (_bufferIndex + 1) % RingLength;
|
||||
}
|
||||
|
||||
operator id<MTLBuffer>() const {
|
||||
return buffer();
|
||||
}
|
||||
|
||||
DataType* operator->() const {
|
||||
return data();
|
||||
}
|
||||
|
||||
DataType& operator[](int idx) const {
|
||||
return (data())[idx];
|
||||
}
|
||||
};
|
||||
|
||||
#endif // OPENSUBDIV_EXAMPLES_MTL_UTILS_H
|
||||
} } using namespace OPENSUBDIV_VERSION; }
|
||||
8
blender-5.2.0/extern/opensubdiv-source/examples/common/mtlUtils.mm
vendored
Normal file
8
blender-5.2.0/extern/opensubdiv-source/examples/common/mtlUtils.mm
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#include "mtlUtils.h"
|
||||
145
blender-5.2.0/extern/opensubdiv-source/examples/common/objAnim.cpp
vendored
Normal file
145
blender-5.2.0/extern/opensubdiv-source/examples/common/objAnim.cpp
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#include "objAnim.h"
|
||||
#include "../../regression/common/shape_utils.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include <sstream>
|
||||
ObjAnim::ObjAnim() : _shape(0) {
|
||||
}
|
||||
|
||||
ObjAnim::~ObjAnim() {
|
||||
|
||||
delete _shape;
|
||||
}
|
||||
|
||||
void
|
||||
ObjAnim::InterpolatePositions(float time, float * positions, int stride) const {
|
||||
|
||||
assert(positions);
|
||||
|
||||
if ( _positions.empty() || (! _shape)) {
|
||||
//printf("Error: InterpolatePositions on unfit ObjAnim instance\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int nkeys = GetNumKeyframes(),
|
||||
nverts = GetShape()->GetNumVertices();
|
||||
|
||||
assert(nkeys>0);
|
||||
|
||||
if (nkeys==1) {
|
||||
// nothing to interpolate - just copy the coarse verts positions
|
||||
float const * vert = &_positions[0][0];
|
||||
for (int i = 0; i <nverts; ++i) {
|
||||
memcpy( positions, vert, sizeof(float)*3);
|
||||
positions += stride;
|
||||
vert += 3;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const float fps = 24.0f;
|
||||
|
||||
float p = fmodf(time * fps, (float)nkeys);
|
||||
|
||||
int key = (int)p;
|
||||
|
||||
float b = p - key;
|
||||
|
||||
for (int i = 0; i <nverts; ++i) {
|
||||
|
||||
for (int j=0; j<3; ++j) {
|
||||
|
||||
float p0 = _positions[ key ][i*3+j];
|
||||
float p1 = _positions[(key+1)%nkeys][i*3+j];
|
||||
|
||||
positions[i*stride + j] = p0*(1-b) + p1*b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ObjAnim const *
|
||||
ObjAnim::Create(std::vector<char const *> objFiles, Scheme scheme, bool isLeftHanded) {
|
||||
|
||||
ObjAnim * anim=0;
|
||||
|
||||
Shape const * shape = 0;
|
||||
|
||||
if (! objFiles.empty()) {
|
||||
|
||||
anim = new ObjAnim;
|
||||
|
||||
anim->_positions.reserve(objFiles.size());
|
||||
|
||||
for (int i = 0; i < (int)objFiles.size(); ++i) {
|
||||
|
||||
if (! objFiles[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::ifstream ifs(objFiles[i]);
|
||||
|
||||
if (ifs) {
|
||||
|
||||
std::stringstream ss;
|
||||
ss << ifs.rdbuf();
|
||||
ifs.close();
|
||||
|
||||
printf("Reading %s\r", objFiles[i]);
|
||||
fflush(stdout);
|
||||
std::string str = ss.str();
|
||||
|
||||
shape = Shape::parseObj(str.c_str(), scheme, isLeftHanded);
|
||||
|
||||
if (i==0) {
|
||||
|
||||
anim->_shape = shape;
|
||||
anim->_positions.push_back(shape->verts);
|
||||
} else {
|
||||
|
||||
if (shape->verts.size() != anim->_shape->verts.size()) {
|
||||
printf("Error: vertex count doesn't match (%s)\n", objFiles[i]);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (shape->nvertsPerFace.size() != anim->_shape->nvertsPerFace.size()) {
|
||||
printf("Error: face vertex count array doesn't match (%s)\n", objFiles[i]);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (shape->faceverts.size() != anim->_shape->faceverts.size()) {
|
||||
printf("Error: face vertices array doesn't match (%s)\n", objFiles[i]);
|
||||
goto error;
|
||||
}
|
||||
|
||||
anim->_positions.push_back(shape->verts);
|
||||
delete shape;
|
||||
}
|
||||
|
||||
} else {
|
||||
printf("Error in reading %s\n", objFiles[i]);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return anim;
|
||||
|
||||
error:
|
||||
delete shape;
|
||||
delete anim;
|
||||
return 0;
|
||||
}
|
||||
50
blender-5.2.0/extern/opensubdiv-source/examples/common/objAnim.h
vendored
Normal file
50
blender-5.2.0/extern/opensubdiv-source/examples/common/objAnim.h
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef OBJ_ANIM_H
|
||||
#define OBJ_ANIM_H
|
||||
|
||||
#include "../../regression/common/shape_utils.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class ObjAnim {
|
||||
|
||||
public:
|
||||
|
||||
// Factory function
|
||||
static ObjAnim const * Create(std::vector<char const *> objFiles,
|
||||
Scheme scheme, bool isLeftHanded=false);
|
||||
|
||||
// Destructor
|
||||
~ObjAnim();
|
||||
|
||||
// Populates 'positions' with the interpolated vertex data for a given
|
||||
// time.
|
||||
void InterpolatePositions(float time, float * positions, int stride) const;
|
||||
|
||||
// Number of key-frames in the animation
|
||||
int GetNumKeyframes() const {
|
||||
return (int)_positions.size();
|
||||
}
|
||||
|
||||
// Returns the full 'Shape'
|
||||
Shape const * GetShape() const {
|
||||
return _shape;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
ObjAnim();
|
||||
|
||||
Shape const * _shape;
|
||||
|
||||
std::vector<std::vector<float> > _positions;
|
||||
};
|
||||
|
||||
#endif // OBJ_ANIM_H
|
||||
25
blender-5.2.0/extern/opensubdiv-source/examples/common/patchColors.cpp
vendored
Normal file
25
blender-5.2.0/extern/opensubdiv-source/examples/common/patchColors.cpp
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#include "patchColors.h"
|
||||
|
||||
static float _colors[7][4] = {{1.0f, 1.0f, 1.0f, 1.0f}, // regular
|
||||
{1.0f, 0.5f, 0.5f, 1.0f}, // single crease
|
||||
{0.8f, 0.0f, 0.0f, 1.0f}, // boundary
|
||||
{0.0f, 1.0f, 0.0f, 1.0f}, // corner
|
||||
{1.0f, 1.0f, 0.0f, 1.0f}, // gregory
|
||||
{1.0f, 0.5f, 0.0f, 1.0f}, // gregory boundary
|
||||
{1.0f, 0.7f, 0.3f, 1.0f}}; // gregory basis
|
||||
|
||||
typedef OpenSubdiv::Far::PatchDescriptor Descriptor;
|
||||
|
||||
float const *
|
||||
getAdaptivePatchColor(Descriptor const & desc) {
|
||||
|
||||
return _colors[(int)(desc.GetType()-Descriptor::REGULAR)];
|
||||
}
|
||||
|
||||
17
blender-5.2.0/extern/opensubdiv-source/examples/common/patchColors.h
vendored
Normal file
17
blender-5.2.0/extern/opensubdiv-source/examples/common/patchColors.h
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef OPENSUBDIV_EXAMPLES_COMMON_PATCH_COLORS_H
|
||||
#define OPENSUBDIV_EXAMPLES_COMMON_PATCH_COLORS_H
|
||||
|
||||
#include <opensubdiv/far/patchTable.h>
|
||||
|
||||
// returns a unique color for each type of feature-adaptive patches
|
||||
float const * getAdaptivePatchColor(OpenSubdiv::Far::PatchDescriptor const & desc);
|
||||
|
||||
|
||||
#endif /* OPENSUBDIV_EXAMPLES_COMMON_PATCH_COLORS_H */
|
||||
1023
blender-5.2.0/extern/opensubdiv-source/examples/common/ptexMipmapTextureLoader.cpp
vendored
Normal file
1023
blender-5.2.0/extern/opensubdiv-source/examples/common/ptexMipmapTextureLoader.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
139
blender-5.2.0/extern/opensubdiv-source/examples/common/ptexMipmapTextureLoader.h
vendored
Normal file
139
blender-5.2.0/extern/opensubdiv-source/examples/common/ptexMipmapTextureLoader.h
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef OPENSUBDIV_EXAMPLES_PTEX_MIPMAP_TEXTURE_LOADER_H
|
||||
#define OPENSUBDIV_EXAMPLES_PTEX_MIPMAP_TEXTURE_LOADER_H
|
||||
|
||||
#include <Ptexture.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
|
||||
class PtexMipmapTextureLoader {
|
||||
public:
|
||||
PtexMipmapTextureLoader(PtexTexture *ptex,
|
||||
int maxNumPages,
|
||||
int maxLevels = -1,
|
||||
size_t targetMemory = 0,
|
||||
bool seamlessMipmap = true,
|
||||
bool padAlpha = false);
|
||||
|
||||
~PtexMipmapTextureLoader();
|
||||
|
||||
const unsigned char * GetLayoutBuffer() const {
|
||||
return _layoutBuffer;
|
||||
}
|
||||
const unsigned char * GetTexelBuffer() const {
|
||||
return _texelBuffer;
|
||||
}
|
||||
int GetNumFaces() const {
|
||||
return (int)_blocks.size();
|
||||
}
|
||||
int GetNumPages() const {
|
||||
return (int)_pages.size();
|
||||
}
|
||||
int GetPageWidth() const {
|
||||
return _pageWidth;
|
||||
}
|
||||
int GetPageHeight() const {
|
||||
return _pageHeight;
|
||||
}
|
||||
size_t GetMemoryUsage() const {
|
||||
return _memoryUsage;
|
||||
}
|
||||
|
||||
/*
|
||||
block : atomic texture unit
|
||||
XXX: face of 128x128 or more (64kb~) texels should be considered separately
|
||||
using ARB_sparse_texture...?
|
||||
|
||||
. : per-face texels for each mipmap level
|
||||
x : guttering pixel
|
||||
|
||||
xxxxxxxxxxxxxx
|
||||
x........xx..x 2x2
|
||||
x........xx..x
|
||||
x........xxxxx
|
||||
x..8x8...xxxxxxx
|
||||
x........xx....x
|
||||
x........xx....x 4x4
|
||||
x........xx....x
|
||||
x........xx....x
|
||||
xxxxxxxxxxxxxxxx
|
||||
|
||||
For each face (w*h), texels with guttering and mipmap is stored into
|
||||
(w+2+w/2+2)*(h+2) area as above.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
Ptex loader
|
||||
|
||||
Texels buffer : the packed texels
|
||||
|
||||
*/
|
||||
|
||||
private:
|
||||
struct Block {
|
||||
int index; // ptex index
|
||||
int nMipmaps;
|
||||
uint16_t u, v; // top-left texel offset
|
||||
uint16_t width, height; // texel dimension (includes mipmap)
|
||||
uint16_t adjSizeDiffs; // maximum tile size difference around each vertices
|
||||
int8_t ulog2, vlog2; // texel dimension log2 (original tile)
|
||||
|
||||
void Generate(PtexMipmapTextureLoader *loader, PtexTexture *ptex,
|
||||
unsigned char *destination,
|
||||
int bpp, int width, int maxLevels);
|
||||
|
||||
void SetSize(unsigned char ulog2_, unsigned char vlog2_, bool mipmap);
|
||||
|
||||
int GetNumTexels() const {
|
||||
return width*height;
|
||||
}
|
||||
|
||||
void guttering(PtexMipmapTextureLoader *loader, PtexTexture *ptex,
|
||||
int level, int width, int height,
|
||||
unsigned char *pptr, int bpp, int stride);
|
||||
|
||||
static bool sort(const Block *a, const Block *b) {
|
||||
return (a->height > b->height) ||
|
||||
((a->height == b->height) && (a->width > b->width));
|
||||
}
|
||||
};
|
||||
|
||||
struct Page;
|
||||
class CornerIterator;
|
||||
|
||||
void generateBuffers();
|
||||
void optimizePacking(int maxNumPages, size_t targetMemory);
|
||||
int getLevelDiff(int face, int edge);
|
||||
bool getCornerPixel(float *resultPixel, int numchannels,
|
||||
int face, int edge, int8_t res);
|
||||
void sampleNeighbor(unsigned char *border,
|
||||
int face, int edge, int length, int bpp);
|
||||
int resampleBorder(int face, int edgeId, unsigned char *result,
|
||||
int dstLength, int bpp,
|
||||
float srcStart = 0.0f, float srcEnd = 1.0f);
|
||||
void addAlphaChannel();
|
||||
|
||||
std::vector<Block> _blocks;
|
||||
std::vector<Page *> _pages;
|
||||
|
||||
PtexTexture *_ptex;
|
||||
int _maxLevels;
|
||||
int _bpp;
|
||||
int _pageWidth, _pageHeight;
|
||||
|
||||
unsigned char *_texelBuffer;
|
||||
unsigned char *_layoutBuffer;
|
||||
|
||||
size_t _memoryUsage;
|
||||
};
|
||||
|
||||
#endif // OPENSUBDIV_EXAMPLES_PTEX_MIPMAP_TEXTURE_LOADER_H
|
||||
53
blender-5.2.0/extern/opensubdiv-source/examples/common/shaderCache.h
vendored
Normal file
53
blender-5.2.0/extern/opensubdiv-source/examples/common/shaderCache.h
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// Copyright 2015 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef OPENSUBDIV_EXAMPLES_SHADER_CACHE_H
|
||||
#define OPENSUBDIV_EXAMPLES_SHADER_CACHE_H
|
||||
|
||||
#include <map>
|
||||
|
||||
template <typename DESC_TYPE, typename CONFIG_TYPE>
|
||||
class ShaderCacheT {
|
||||
public:
|
||||
typedef DESC_TYPE DescType;
|
||||
typedef CONFIG_TYPE ConfigType;
|
||||
typedef std::map<DescType, ConfigType *> ConfigMap;
|
||||
|
||||
virtual ~ShaderCacheT() {
|
||||
Reset();
|
||||
}
|
||||
|
||||
void Reset() {
|
||||
for (typename ConfigMap::iterator it = _configMap.begin();
|
||||
it != _configMap.end(); ++it) {
|
||||
delete it->second;
|
||||
}
|
||||
_configMap.clear();
|
||||
}
|
||||
|
||||
// fetch shader config
|
||||
ConfigType * GetDrawConfig(DescType const & desc) {
|
||||
typename ConfigMap::iterator it = _configMap.find(desc);
|
||||
if (it != _configMap.end()) {
|
||||
return it->second;
|
||||
} else {
|
||||
ConfigType * config = CreateDrawConfig(desc);
|
||||
if (config) {
|
||||
_configMap[desc] = config;
|
||||
}
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
||||
virtual ConfigType *CreateDrawConfig(DescType const &desc) = 0;
|
||||
|
||||
private:
|
||||
ConfigMap _configMap;
|
||||
};
|
||||
|
||||
|
||||
#endif // OPENSUBDIV_EXAMPLES_SHADER_CACHE_H
|
||||
269
blender-5.2.0/extern/opensubdiv-source/examples/common/simple_math.h
vendored
Normal file
269
blender-5.2.0/extern/opensubdiv-source/examples/common/simple_math.h
vendored
Normal file
@@ -0,0 +1,269 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef SIMPLE_MATH_H
|
||||
#define SIMPLE_MATH_H
|
||||
|
||||
#include <cmath>
|
||||
|
||||
inline void
|
||||
cross(float *n, const float *v1, const float *v2) {
|
||||
n[0] = v1[1]*v2[2]-v1[2]*v2[1];
|
||||
n[1] = v1[2]*v2[0]-v1[0]*v2[2];
|
||||
n[2] = v1[0]*v2[1]-v1[1]*v2[0];
|
||||
}
|
||||
|
||||
inline void
|
||||
cross(float *n, const float *p0, const float *p1, const float *p2) {
|
||||
|
||||
float a[3] = { p1[0]-p0[0], p1[1]-p0[1], p1[2]-p0[2] };
|
||||
float b[3] = { p2[0]-p0[0], p2[1]-p0[1], p2[2]-p0[2] };
|
||||
n[0] = a[1]*b[2]-a[2]*b[1];
|
||||
n[1] = a[2]*b[0]-a[0]*b[2];
|
||||
n[2] = a[0]*b[1]-a[1]*b[0];
|
||||
|
||||
float rn = 1.0f/sqrtf(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);
|
||||
n[0] *= rn;
|
||||
n[1] *= rn;
|
||||
n[2] *= rn;
|
||||
}
|
||||
|
||||
inline void
|
||||
normalize(float * p) {
|
||||
|
||||
float dist = sqrtf( p[0]*p[0] + p[1]*p[1] + p[2]*p[2] );
|
||||
p[0]/=dist;
|
||||
p[1]/=dist;
|
||||
p[2]/=dist;
|
||||
}
|
||||
|
||||
inline void
|
||||
multMatrix(float *d, const float *a, const float *b) {
|
||||
|
||||
for (int i=0; i<4; ++i)
|
||||
{
|
||||
for (int j=0; j<4; ++j)
|
||||
{
|
||||
d[i*4 + j] =
|
||||
a[i*4 + 0] * b[0*4 + j] +
|
||||
a[i*4 + 1] * b[1*4 + j] +
|
||||
a[i*4 + 2] * b[2*4 + j] +
|
||||
a[i*4 + 3] * b[3*4 + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
inverseMatrix(float *d, const float *m) {
|
||||
|
||||
d[0] = m[ 5]*m[10]*m[15] - m[ 5]*m[11]*m[14] -
|
||||
m[ 9]*m[ 6]*m[15] + m[ 9]*m[ 7]*m[14] +
|
||||
m[13]*m[ 6]*m[11] - m[13]*m[ 7]*m[10];
|
||||
|
||||
d[1] = -m[ 1]*m[10]*m[15] + m[ 1]*m[11]*m[14] +
|
||||
m[ 9]*m[ 2]*m[15] - m[ 9]*m[ 3]*m[14] -
|
||||
m[13]*m[ 2]*m[11] + m[13]*m[ 3]*m[10];
|
||||
|
||||
d[2] = m[ 1]*m[ 6]*m[15] - m[ 1]*m[ 7]*m[14] -
|
||||
m[ 5]*m[ 2]*m[15] + m[ 5]*m[ 3]*m[14] +
|
||||
m[13]*m[ 2]*m[ 7] - m[13]*m[ 3]*m[ 6];
|
||||
|
||||
d[3] = -m[ 1]*m[ 6]*m[11] + m[ 1]*m[ 7]*m[10] +
|
||||
m[ 5]*m[ 2]*m[11] - m[ 5]*m[ 3]*m[10] -
|
||||
m[ 9]*m[ 2]*m[ 7] + m[ 9]*m[ 3]*m[ 6];
|
||||
|
||||
d[4] = -m[ 4]*m[10]*m[15] + m[ 4]*m[11]*m[14] +
|
||||
m[ 8]*m[ 6]*m[15] - m[ 8]*m[ 7]*m[14] -
|
||||
m[12]*m[ 6]*m[11] + m[12]*m[ 7]*m[10];
|
||||
|
||||
d[5] = m[ 0]*m[10]*m[15] - m[ 0]*m[11]*m[14] -
|
||||
m[ 8]*m[ 2]*m[15] + m[ 8]*m[ 3]*m[14] +
|
||||
m[12]*m[ 2]*m[11] - m[12]*m[ 3]*m[10];
|
||||
|
||||
d[6] = -m[ 0]*m[ 6]*m[15] + m[ 0]*m[ 7]*m[14] +
|
||||
m[ 4]*m[ 2]*m[15] - m[ 4]*m[ 3]*m[14] -
|
||||
m[12]*m[ 2]*m[ 7] + m[12]*m[ 3]*m[ 6];
|
||||
|
||||
d[7] = m[ 0]*m[ 6]*m[11] - m[ 0]*m[ 7]*m[10] -
|
||||
m[ 4]*m[ 2]*m[11] + m[ 4]*m[ 3]*m[10] +
|
||||
m[ 8]*m[ 2]*m[ 7] - m[ 8]*m[ 3]*m[ 6];
|
||||
|
||||
d[8] = m[ 4]*m[ 9]*m[15] - m[ 4]*m[11]*m[13] -
|
||||
m[ 8]*m[ 5]*m[15] + m[ 8]*m[ 7]*m[13] +
|
||||
m[12]*m[ 5]*m[11] - m[12]*m[ 7]*m[ 9];
|
||||
|
||||
d[9] = -m[ 0]*m[ 9]*m[15] + m[ 0]*m[11]*m[13] +
|
||||
m[ 8]*m[ 1]*m[15] - m[ 8]*m[ 3]*m[13] -
|
||||
m[12]*m[ 1]*m[11] + m[12]*m[ 3]*m[ 9];
|
||||
|
||||
d[10] = m[ 0]*m[ 5]*m[15] - m[ 0]*m[ 7]*m[13] -
|
||||
m[ 4]*m[ 1]*m[15] + m[ 4]*m[ 3]*m[13] +
|
||||
m[12]*m[ 1]*m[ 7] - m[12]*m[ 3]*m[ 5];
|
||||
|
||||
d[11] = -m[ 0]*m[ 5]*m[11] + m[ 0]*m[ 7]*m[ 9] +
|
||||
m[ 4]*m[ 1]*m[11] - m[ 4]*m[ 3]*m[ 9] -
|
||||
m[ 8]*m[ 1]*m[ 7] + m[ 8]*m[ 3]*m[ 5];
|
||||
|
||||
d[12] = -m[ 4]*m[ 9]*m[14] + m[ 4]*m[10]*m[13] +
|
||||
m[ 8]*m[ 5]*m[14] - m[ 8]*m[ 6]*m[13] -
|
||||
m[12]*m[ 5]*m[10] + m[12]*m[ 6]*m[ 9];
|
||||
|
||||
d[13] = m[ 0]*m[ 9]*m[14] - m[ 0]*m[10]*m[13] -
|
||||
m[ 8]*m[ 1]*m[14] + m[ 8]*m[ 2]*m[13] +
|
||||
m[12]*m[ 1]*m[10] - m[12]*m[ 2]*m[ 9];
|
||||
|
||||
d[14] = -m[ 0]*m[ 5]*m[14] + m[ 0]*m[ 6]*m[13] +
|
||||
m[ 4]*m[ 1]*m[14] - m[ 4]*m[ 2]*m[13] -
|
||||
m[12]*m[ 1]*m[ 6] + m[12]*m[ 2]*m[ 5];
|
||||
|
||||
d[15] = m[ 0]*m[ 5]*m[10] - m[ 0]*m[ 6]*m[ 9] -
|
||||
m[ 4]*m[ 1]*m[10] + m[ 4]*m[ 2]*m[ 9] +
|
||||
m[ 8]*m[ 1]*m[ 6] - m[ 8]*m[ 2]*m[ 5];
|
||||
|
||||
float det = m[0] * d[0] + m[1] * d[4] + m[2] * d[8] + m[3] * d[12];
|
||||
|
||||
if (det == 0.0f) return;
|
||||
det = 1.0f / det;
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
d[i] = d[i] * det;
|
||||
}
|
||||
|
||||
inline void
|
||||
perspective(float *m, float fovy, float aspect, float znear, float zfar)
|
||||
{
|
||||
float r = 2 * (float)M_PI * fovy / 360.0F;
|
||||
float t = 1.0f / tanf(r*0.5f);
|
||||
m[0] = t/aspect;
|
||||
m[1] = m[2] = m[3] = 0.0;
|
||||
m[4] = 0.0;
|
||||
m[5] = t;
|
||||
m[6] = m[7] = 0.0;
|
||||
m[8] = m[9] = 0.0;
|
||||
m[10] = (zfar + znear) / (znear - zfar);
|
||||
m[11] = -1;
|
||||
m[12] = m[13] = 0.0;
|
||||
m[14] = (2*zfar*znear)/(znear - zfar);
|
||||
m[15] = 0.0;
|
||||
}
|
||||
|
||||
inline void
|
||||
identity(float *m)
|
||||
{
|
||||
m[0] = 1; m[1] = 0; m[2] = 0; m[3] = 0;
|
||||
m[4] = 0; m[5] = 1; m[6] = 0; m[7] = 0;
|
||||
m[8] = 0; m[9] = 0; m[10] = 1; m[11] = 0;
|
||||
m[12] = 0; m[13] = 0; m[14] = 0; m[15] = 1;
|
||||
}
|
||||
|
||||
inline void
|
||||
translate(float *m, float x, float y, float z)
|
||||
{
|
||||
float t[16];
|
||||
identity(t);
|
||||
t[12] = x;
|
||||
t[13] = y;
|
||||
t[14] = z;
|
||||
float o[16];
|
||||
for(int i = 0; i < 16; i++) o[i] = m[i];
|
||||
multMatrix(m, t, o);
|
||||
}
|
||||
|
||||
inline void
|
||||
ortho(float *m, float left, float top, float right, float bottom)
|
||||
{
|
||||
identity(m);
|
||||
m[0] = 2.0f / (right - left);
|
||||
m[5] = 2.0f / (top - bottom);
|
||||
m[10] = -1;
|
||||
m[12] = -(right+left)/(right-left);
|
||||
m[13] = -(top+bottom)/(top-bottom);
|
||||
}
|
||||
|
||||
inline void
|
||||
rotate(float *m, float angle, float x, float y, float z)
|
||||
{
|
||||
float r = 2 * (float) M_PI * angle/360.0f;
|
||||
float c = cosf(r);
|
||||
float s = sinf(r);
|
||||
float t[16];
|
||||
t[0] = x*x*(1-c)+c;
|
||||
t[1] = y*x*(1-c)+z*s;
|
||||
t[2] = x*z*(1-c)-y*s;
|
||||
t[3] = 0;
|
||||
t[4] = x*y*(1-c)-z*s;
|
||||
t[5] = y*y*(1-c)+c;
|
||||
t[6] = y*z*(1-c)+x*s;
|
||||
t[7] = 0;
|
||||
t[8] = x*z*(1-c)+y*s;
|
||||
t[9] = y*z*(1-c)-x*s;
|
||||
t[10] = z*z*(1-c)+c;
|
||||
t[11] = 0;
|
||||
t[12] = t[13] = t[14] = 0;
|
||||
t[15] = 1;
|
||||
float o[16];
|
||||
for(int i = 0; i < 16; i++) o[i] = m[i];
|
||||
multMatrix(m, t, o);
|
||||
}
|
||||
|
||||
inline void
|
||||
scale(float *m, float sx, float sy, float sz)
|
||||
{
|
||||
float t[16];
|
||||
identity(t);
|
||||
t[0] = sx;
|
||||
t[5] = sy;
|
||||
t[10] = sz;
|
||||
float o[16];
|
||||
for(int i = 0; i < 16; i++) o[i] = m[i];
|
||||
multMatrix(m, t, o);
|
||||
}
|
||||
|
||||
inline void
|
||||
transpose(float *m)
|
||||
{
|
||||
std::swap(m[1], m[4]);
|
||||
std::swap(m[2], m[8]);
|
||||
std::swap(m[3], m[12]);
|
||||
std::swap(m[6], m[9]);
|
||||
std::swap(m[7], m[13]);
|
||||
std::swap(m[11],m[14]);
|
||||
}
|
||||
|
||||
inline void
|
||||
apply(float *v, const float *m)
|
||||
{
|
||||
float r[4];
|
||||
r[0] = v[0] * m[0] + v[1] * m[4] + v[2] * m[8] + v[3] * m[12];
|
||||
r[1] = v[0] * m[1] + v[1] * m[5] + v[2] * m[9] + v[3] * m[13];
|
||||
r[2] = v[0] * m[2] + v[1] * m[6] + v[2] * m[10] + v[3] * m[14];
|
||||
r[3] = v[0] * m[3] + v[1] * m[7] + v[2] * m[11] + v[3] * m[15];
|
||||
v[0] = r[0];
|
||||
v[1] = r[1];
|
||||
v[2] = r[2];
|
||||
v[3] = r[3];
|
||||
}
|
||||
|
||||
inline void
|
||||
pickMatrix(float *m, float x, float y, float width, float height, const int *viewport)
|
||||
{
|
||||
float sx, sy;
|
||||
float tx, ty;
|
||||
|
||||
sx = viewport[2] / width;
|
||||
sy = viewport[3] / height;
|
||||
tx = (viewport[2] + 2.0f * (viewport[0] - x)) / width;
|
||||
ty = (viewport[3] + 2.0f * (viewport[1] - y)) / height;
|
||||
|
||||
identity(m);
|
||||
m[0] = sx;
|
||||
m[5] = sy;
|
||||
m[12] = tx;
|
||||
m[13] = ty;
|
||||
}
|
||||
|
||||
#endif // SIMPLE_MATH_H
|
||||
697
blender-5.2.0/extern/opensubdiv-source/examples/common/stb_image_write.h
vendored
Normal file
697
blender-5.2.0/extern/opensubdiv-source/examples/common/stb_image_write.h
vendored
Normal file
@@ -0,0 +1,697 @@
|
||||
/* stb_image_write - v0.97 - public domain - http://nothings.org/stb/stb_image_write.h
|
||||
writes out PNG/BMP/TGA images to C stdio - Sean Barrett 2010
|
||||
no warranty implied; use at your own risk
|
||||
|
||||
|
||||
Before #including,
|
||||
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
|
||||
in the file that you want to have the implementation.
|
||||
|
||||
|
||||
Will probably not work correctly with strict-aliasing optimizations.
|
||||
|
||||
ABOUT:
|
||||
|
||||
This header file is a library for writing images to C stdio. It could be
|
||||
adapted to write to memory or a general streaming interface; let me know.
|
||||
|
||||
The PNG output is not optimal; it is 20-50% larger than the file
|
||||
written by a decent optimizing implementation. This library is designed
|
||||
for source code compactness and simplicity, not optimal image file size
|
||||
or run-time performance.
|
||||
|
||||
USAGE:
|
||||
|
||||
There are four functions, one for each image file format:
|
||||
|
||||
int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
|
||||
int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
|
||||
int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
|
||||
int stbi_write_hdr(char const *filename, int w, int h, int comp, const void *data);
|
||||
|
||||
Each function returns 0 on failure and non-0 on success.
|
||||
|
||||
The functions create an image file defined by the parameters. The image
|
||||
is a rectangle of pixels stored from left-to-right, top-to-bottom.
|
||||
Each pixel contains 'comp' channels of data stored interleaved with 8-bits
|
||||
per channel, in the following order: 1=Y, 2=YA, 3=RGB, 4=RGBA. (Y is
|
||||
monochrome color.) The rectangle is 'w' pixels wide and 'h' pixels tall.
|
||||
The *data pointer points to the first byte of the top-left-most pixel.
|
||||
For PNG, "stride_in_bytes" is the distance in bytes from the first byte of
|
||||
a row of pixels to the first byte of the next row of pixels.
|
||||
|
||||
PNG creates output files with the same number of components as the input.
|
||||
The BMP format expands Y to RGB in the file format and does not
|
||||
output alpha.
|
||||
|
||||
PNG supports writing rectangles of data even when the bytes storing rows of
|
||||
data are not consecutive in memory (e.g. sub-rectangles of a larger image),
|
||||
by supplying the stride between the beginning of adjacent rows. The other
|
||||
formats do not. (Thus you cannot write a native-format BMP through the BMP
|
||||
writer, both because it is in BGR order and because it may have padding
|
||||
at the end of the line.)
|
||||
|
||||
HDR expects linear float data. Since the format is always 32-bit rgb(e)
|
||||
data, alpha (if provided) is discarded, and for monochrome data it is
|
||||
replicated across all three channels.
|
||||
|
||||
CREDITS:
|
||||
|
||||
PNG/BMP/TGA
|
||||
Sean Barrett
|
||||
HDR
|
||||
Baldur Karlsson
|
||||
TGA monochrome:
|
||||
Jean-Sebastien Guay
|
||||
Bugfixes:
|
||||
Chribba@github
|
||||
*/
|
||||
|
||||
#ifndef INCLUDE_STB_IMAGE_WRITE_H
|
||||
#define INCLUDE_STB_IMAGE_WRITE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
|
||||
extern int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
|
||||
extern int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
|
||||
extern int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif//INCLUDE_STB_IMAGE_WRITE_H
|
||||
|
||||
#ifdef STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
typedef unsigned int stbiw_uint32;
|
||||
typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1];
|
||||
|
||||
static void writefv(FILE *f, const char *fmt, va_list v)
|
||||
{
|
||||
while (*fmt) {
|
||||
switch (*fmt++) {
|
||||
case ' ': break;
|
||||
case '1': { unsigned char x = (unsigned char) va_arg(v, int); fputc(x,f); break; }
|
||||
case '2': { int x = va_arg(v,int); unsigned char b[2];
|
||||
b[0] = (unsigned char) x; b[1] = (unsigned char) (x>>8);
|
||||
fwrite(b,2,1,f); break; }
|
||||
case '4': { stbiw_uint32 x = va_arg(v,int); unsigned char b[4];
|
||||
b[0]=(unsigned char)x; b[1]=(unsigned char)(x>>8);
|
||||
b[2]=(unsigned char)(x>>16); b[3]=(unsigned char)(x>>24);
|
||||
fwrite(b,4,1,f); break; }
|
||||
default:
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void write3(FILE *f, unsigned char a, unsigned char b, unsigned char c)
|
||||
{
|
||||
unsigned char arr[3];
|
||||
arr[0] = a, arr[1] = b, arr[2] = c;
|
||||
fwrite(arr, 3, 1, f);
|
||||
}
|
||||
|
||||
static void write_pixels(FILE *f, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad, int expand_mono)
|
||||
{
|
||||
unsigned char bg[3] = { 255, 0, 255}, px[3];
|
||||
stbiw_uint32 zero = 0;
|
||||
int i,j,k, j_end;
|
||||
|
||||
if (y <= 0)
|
||||
return;
|
||||
|
||||
if (vdir < 0)
|
||||
j_end = -1, j = y-1;
|
||||
else
|
||||
j_end = y, j = 0;
|
||||
|
||||
for (; j != j_end; j += vdir) {
|
||||
for (i=0; i < x; ++i) {
|
||||
unsigned char *d = (unsigned char *) data + (j*x+i)*comp;
|
||||
if (write_alpha < 0)
|
||||
fwrite(&d[comp-1], 1, 1, f);
|
||||
switch (comp) {
|
||||
case 1: fwrite(d, 1, 1, f);
|
||||
break;
|
||||
case 2: if (expand_mono)
|
||||
write3(f, d[0],d[0],d[0]); // monochrome bmp
|
||||
else
|
||||
fwrite(d, 1, 1, f); // monochrome TGA
|
||||
break;
|
||||
case 4:
|
||||
if (!write_alpha) {
|
||||
// composite against pink background
|
||||
for (k=0; k < 3; ++k)
|
||||
px[k] = bg[k] + ((d[k] - bg[k]) * d[3])/255;
|
||||
write3(f, px[1-rgb_dir],px[1],px[1+rgb_dir]);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case 3:
|
||||
write3(f, d[1-rgb_dir],d[1],d[1+rgb_dir]);
|
||||
break;
|
||||
}
|
||||
if (write_alpha > 0)
|
||||
fwrite(&d[comp-1], 1, 1, f);
|
||||
}
|
||||
fwrite(&zero,scanline_pad,1,f);
|
||||
}
|
||||
}
|
||||
|
||||
static int outfile(char const *filename, int rgb_dir, int vdir, int x, int y, int comp, int expand_mono, void *data, int alpha, int pad, const char *fmt, ...)
|
||||
{
|
||||
FILE *f;
|
||||
if (y < 0 || x < 0) return 0;
|
||||
f = fopen(filename, "wb");
|
||||
if (f) {
|
||||
va_list v;
|
||||
va_start(v, fmt);
|
||||
writefv(f, fmt, v);
|
||||
va_end(v);
|
||||
write_pixels(f,rgb_dir,vdir,x,y,comp,data,alpha,pad,expand_mono);
|
||||
fclose(f);
|
||||
}
|
||||
return f != NULL;
|
||||
}
|
||||
|
||||
int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data)
|
||||
{
|
||||
int pad = (-x*3) & 3;
|
||||
return outfile(filename,-1,-1,x,y,comp,1,(void *) data,0,pad,
|
||||
"11 4 22 4" "4 44 22 444444",
|
||||
'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header
|
||||
40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header
|
||||
}
|
||||
|
||||
int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data)
|
||||
{
|
||||
int has_alpha = (comp == 2 || comp == 4);
|
||||
int colorbytes = has_alpha ? comp-1 : comp;
|
||||
int format = colorbytes < 2 ? 3 : 2; // 3 color channels (RGB/RGBA) = 2, 1 color channel (Y/YA) = 3
|
||||
return outfile(filename, -1,-1, x, y, comp, 0, (void *) data, has_alpha, 0,
|
||||
"111 221 2222 11", 0,0,format, 0,0,0, 0,0,x,y, (colorbytes+has_alpha)*8, has_alpha*8);
|
||||
}
|
||||
|
||||
// *************************************************************************************************
|
||||
// Radiance RGBE HDR writer
|
||||
// by Baldur Karlsson
|
||||
#define stbiw__max(a, b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
|
||||
{
|
||||
int exponent;
|
||||
float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2]));
|
||||
|
||||
if (maxcomp < 1e-32) {
|
||||
rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0;
|
||||
} else {
|
||||
float normalize = (float) frexp(maxcomp, &exponent) * 256.0f/maxcomp;
|
||||
|
||||
rgbe[0] = (unsigned char)(linear[0] * normalize);
|
||||
rgbe[1] = (unsigned char)(linear[1] * normalize);
|
||||
rgbe[2] = (unsigned char)(linear[2] * normalize);
|
||||
rgbe[3] = (unsigned char)(exponent + 128);
|
||||
}
|
||||
}
|
||||
|
||||
void stbiw__write_run_data(FILE *f, int length, unsigned char databyte)
|
||||
{
|
||||
unsigned char lengthbyte = (unsigned char) (length+128);
|
||||
assert(length+128 <= 255);
|
||||
fwrite(&lengthbyte, 1, 1, f);
|
||||
fwrite(&databyte, 1, 1, f);
|
||||
}
|
||||
|
||||
void stbiw__write_dump_data(FILE *f, int length, unsigned char *data)
|
||||
{
|
||||
unsigned char lengthbyte = (unsigned char )(length & 0xff);
|
||||
assert(length <= 128); // inconsistent with spec but consistent with official code
|
||||
fwrite(&lengthbyte, 1, 1, f);
|
||||
fwrite(data, length, 1, f);
|
||||
}
|
||||
|
||||
void stbiw__write_hdr_scanline(FILE *f, int width, int comp, unsigned char *scratch, const float *scanline)
|
||||
{
|
||||
unsigned char scanlineheader[4] = { 2, 2, 0, 0 };
|
||||
unsigned char rgbe[4];
|
||||
float linear[3] = {0.0, 0.0, 0.0};
|
||||
int x;
|
||||
|
||||
scanlineheader[2] = (width&0xff00)>>8;
|
||||
scanlineheader[3] = (width&0x00ff);
|
||||
|
||||
/* skip RLE for images too small or large */
|
||||
if (width < 8 || width >= 32768) {
|
||||
for (x=0; x < width; x++) {
|
||||
switch (comp) {
|
||||
case 4: /* fallthrough */
|
||||
case 3: linear[2] = scanline[x*comp + 2];
|
||||
linear[1] = scanline[x*comp + 1];
|
||||
linear[0] = scanline[x*comp + 0];
|
||||
break;
|
||||
case 2: /* fallthrough */
|
||||
case 1: linear[0] = linear[1] = linear[2] = scanline[x*comp + 0];
|
||||
break;
|
||||
}
|
||||
stbiw__linear_to_rgbe(rgbe, linear);
|
||||
fwrite(rgbe, 4, 1, f);
|
||||
}
|
||||
} else {
|
||||
int c,r;
|
||||
/* encode into scratch buffer */
|
||||
for (x=0; x < width; x++) {
|
||||
switch(comp) {
|
||||
case 4: /* fallthrough */
|
||||
case 3: linear[2] = scanline[x*comp + 2];
|
||||
linear[1] = scanline[x*comp + 1];
|
||||
linear[0] = scanline[x*comp + 0];
|
||||
break;
|
||||
case 2: /* fallthrough */
|
||||
case 1: linear[0] = linear[1] = linear[2] = scanline[x*comp + 0];
|
||||
break;
|
||||
}
|
||||
stbiw__linear_to_rgbe(rgbe, linear);
|
||||
scratch[x + width*0] = rgbe[0];
|
||||
scratch[x + width*1] = rgbe[1];
|
||||
scratch[x + width*2] = rgbe[2];
|
||||
scratch[x + width*3] = rgbe[3];
|
||||
}
|
||||
|
||||
fwrite(scanlineheader, 4, 1, f);
|
||||
|
||||
/* RLE each component separately */
|
||||
for (c=0; c < 4; c++) {
|
||||
unsigned char *comp = &scratch[width*c];
|
||||
|
||||
x = 0;
|
||||
while (x < width) {
|
||||
// find first run
|
||||
r = x;
|
||||
while (r+2 < width) {
|
||||
if (comp[r] == comp[r+1] && comp[r] == comp[r+2])
|
||||
break;
|
||||
++r;
|
||||
}
|
||||
if (r+2 >= width)
|
||||
r = width;
|
||||
// dump up to first run
|
||||
while (x < r) {
|
||||
int len = r-x;
|
||||
if (len > 128) len = 128;
|
||||
stbiw__write_dump_data(f, len, &comp[x]);
|
||||
x += len;
|
||||
}
|
||||
// if there's a run, output it
|
||||
if (r+2 < width) { // same test as what we break out of in search loop, so only true if we break'd
|
||||
// find next byte after run
|
||||
while (r < width && comp[r] == comp[x])
|
||||
++r;
|
||||
// output run up to r
|
||||
while (x < r) {
|
||||
int len = r-x;
|
||||
if (len > 127) len = 127;
|
||||
stbiw__write_run_data(f, len, comp[x]);
|
||||
x += len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data)
|
||||
{
|
||||
int i;
|
||||
FILE *f;
|
||||
if (y <= 0 || x <= 0 || data == NULL) return 0;
|
||||
f = fopen(filename, "wb");
|
||||
if (f) {
|
||||
/* Each component is stored separately. Allocate scratch space for full output scanline. */
|
||||
unsigned char *scratch = (unsigned char *) malloc(x*4);
|
||||
fprintf(f, "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n" );
|
||||
fprintf(f, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n" , y, x);
|
||||
for(i=0; i < y; i++)
|
||||
stbiw__write_hdr_scanline(f, x, comp, scratch, data + comp*i*x);
|
||||
free(scratch);
|
||||
fclose(f);
|
||||
}
|
||||
return f != NULL;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
// PNG
|
||||
|
||||
// stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size()
|
||||
#define stbiw__sbraw(a) ((int *) (a) - 2)
|
||||
#define stbiw__sbm(a) stbiw__sbraw(a)[0]
|
||||
#define stbiw__sbn(a) stbiw__sbraw(a)[1]
|
||||
|
||||
#define stbiw__sbneedgrow(a,n) ((a)==0 || stbiw__sbn(a)+n >= stbiw__sbm(a))
|
||||
#define stbiw__sbmaybegrow(a,n) (stbiw__sbneedgrow(a,(n)) ? stbiw__sbgrow(a,n) : 0)
|
||||
#define stbiw__sbgrow(a,n) stbiw__sbgrowf((void **) &(a), (n), sizeof(*(a)))
|
||||
|
||||
#define stbiw__sbpush(a, v) (stbiw__sbmaybegrow(a,1), (a)[stbiw__sbn(a)++] = (v))
|
||||
#define stbiw__sbcount(a) ((a) ? stbiw__sbn(a) : 0)
|
||||
#define stbiw__sbfree(a) ((a) ? free(stbiw__sbraw(a)),0 : 0)
|
||||
|
||||
static void *stbiw__sbgrowf(void **arr, int increment, int itemsize)
|
||||
{
|
||||
int m = *arr ? 2*stbiw__sbm(*arr)+increment : increment+1;
|
||||
void *p = realloc(*arr ? stbiw__sbraw(*arr) : 0, itemsize * m + sizeof(int)*2);
|
||||
assert(p);
|
||||
if (p) {
|
||||
if (!*arr) ((int *) p)[1] = 0;
|
||||
*arr = (void *) ((int *) p + 2);
|
||||
stbiw__sbm(*arr) = m;
|
||||
}
|
||||
return *arr;
|
||||
}
|
||||
|
||||
static unsigned char *stbiw__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount)
|
||||
{
|
||||
while (*bitcount >= 8) {
|
||||
stbiw__sbpush(data, (unsigned char) *bitbuffer);
|
||||
*bitbuffer >>= 8;
|
||||
*bitcount -= 8;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
static int stbiw__zlib_bitrev(int code, int codebits)
|
||||
{
|
||||
int res=0;
|
||||
while (codebits--) {
|
||||
res = (res << 1) | (code & 1);
|
||||
code >>= 1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static unsigned int stbiw__zlib_countm(unsigned char *a, unsigned char *b, int limit)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i < limit && i < 258; ++i)
|
||||
if (a[i] != b[i]) break;
|
||||
return i;
|
||||
}
|
||||
|
||||
static unsigned int stbiw__zhash(unsigned char *data)
|
||||
{
|
||||
stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16);
|
||||
hash ^= hash << 3;
|
||||
hash += hash >> 5;
|
||||
hash ^= hash << 4;
|
||||
hash += hash >> 17;
|
||||
hash ^= hash << 25;
|
||||
hash += hash >> 6;
|
||||
return hash;
|
||||
}
|
||||
|
||||
#define stbiw__zlib_flush() (out = stbiw__zlib_flushf(out, &bitbuf, &bitcount))
|
||||
#define stbiw__zlib_add(code,codebits) \
|
||||
(bitbuf |= (code) << bitcount, bitcount += (codebits), stbiw__zlib_flush())
|
||||
#define stbiw__zlib_huffa(b,c) stbiw__zlib_add(stbiw__zlib_bitrev(b,c),c)
|
||||
// default huffman tables
|
||||
#define stbiw__zlib_huff1(n) stbiw__zlib_huffa(0x30 + (n), 8)
|
||||
#define stbiw__zlib_huff2(n) stbiw__zlib_huffa(0x190 + (n)-144, 9)
|
||||
#define stbiw__zlib_huff3(n) stbiw__zlib_huffa(0 + (n)-256,7)
|
||||
#define stbiw__zlib_huff4(n) stbiw__zlib_huffa(0xc0 + (n)-280,8)
|
||||
#define stbiw__zlib_huff(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : (n) <= 255 ? stbiw__zlib_huff2(n) : (n) <= 279 ? stbiw__zlib_huff3(n) : stbiw__zlib_huff4(n))
|
||||
#define stbiw__zlib_huffb(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : stbiw__zlib_huff2(n))
|
||||
|
||||
#define stbiw__ZHASH 16384
|
||||
|
||||
unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
|
||||
{
|
||||
static unsigned short lengthc[] = { 3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258, 259 };
|
||||
static unsigned char lengtheb[]= { 0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 };
|
||||
static unsigned short distc[] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577, 32768 };
|
||||
static unsigned char disteb[] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 };
|
||||
unsigned int bitbuf=0;
|
||||
int i,j, bitcount=0;
|
||||
unsigned char *out = NULL;
|
||||
unsigned char **hash_table[stbiw__ZHASH]; // 64KB on the stack!
|
||||
if (quality < 5) quality = 5;
|
||||
|
||||
stbiw__sbpush(out, 0x78); // DEFLATE 32K window
|
||||
stbiw__sbpush(out, 0x5e); // FLEVEL = 1
|
||||
stbiw__zlib_add(1,1); // BFINAL = 1
|
||||
stbiw__zlib_add(1,2); // BTYPE = 1 -- fixed huffman
|
||||
|
||||
for (i=0; i < stbiw__ZHASH; ++i)
|
||||
hash_table[i] = NULL;
|
||||
|
||||
i=0;
|
||||
while (i < data_len-3) {
|
||||
// hash next 3 bytes of data to be compressed
|
||||
int h = stbiw__zhash(data+i)&(stbiw__ZHASH-1), best=3;
|
||||
unsigned char *bestloc = 0;
|
||||
unsigned char **hlist = hash_table[h];
|
||||
int n = stbiw__sbcount(hlist);
|
||||
for (j=0; j < n; ++j) {
|
||||
if (hlist[j]-data > i-32768) { // if entry lies within window
|
||||
int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i);
|
||||
if (d >= best) best=d,bestloc=hlist[j];
|
||||
}
|
||||
}
|
||||
// when hash table entry is too long, delete half the entries
|
||||
if (hash_table[h] && stbiw__sbn(hash_table[h]) == 2*quality) {
|
||||
memcpy(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality);
|
||||
stbiw__sbn(hash_table[h]) = quality;
|
||||
}
|
||||
stbiw__sbpush(hash_table[h],data+i);
|
||||
|
||||
if (bestloc) {
|
||||
// "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal
|
||||
h = stbiw__zhash(data+i+1)&(stbiw__ZHASH-1);
|
||||
hlist = hash_table[h];
|
||||
n = stbiw__sbcount(hlist);
|
||||
for (j=0; j < n; ++j) {
|
||||
if (hlist[j]-data > i-32767) {
|
||||
int e = stbiw__zlib_countm(hlist[j], data+i+1, data_len-i-1);
|
||||
if (e > best) { // if next match is better, bail on current match
|
||||
bestloc = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bestloc) {
|
||||
int d = (int) (data+i - bestloc); // distance back
|
||||
assert(d <= 32767 && best <= 258);
|
||||
for (j=0; best > lengthc[j+1]-1; ++j);
|
||||
stbiw__zlib_huff(j+257);
|
||||
if (lengtheb[j]) stbiw__zlib_add(best - lengthc[j], lengtheb[j]);
|
||||
for (j=0; d > distc[j+1]-1; ++j);
|
||||
stbiw__zlib_add(stbiw__zlib_bitrev(j,5),5);
|
||||
if (disteb[j]) stbiw__zlib_add(d - distc[j], disteb[j]);
|
||||
i += best;
|
||||
} else {
|
||||
stbiw__zlib_huffb(data[i]);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
// write out final bytes
|
||||
for (;i < data_len; ++i)
|
||||
stbiw__zlib_huffb(data[i]);
|
||||
stbiw__zlib_huff(256); // end of block
|
||||
// pad with 0 bits to byte boundary
|
||||
while (bitcount)
|
||||
stbiw__zlib_add(0,1);
|
||||
|
||||
for (i=0; i < stbiw__ZHASH; ++i)
|
||||
(void) stbiw__sbfree(hash_table[i]);
|
||||
|
||||
{
|
||||
// compute adler32 on input
|
||||
unsigned int i=0, s1=1, s2=0, blocklen = data_len % 5552;
|
||||
int j=0;
|
||||
while (j < data_len) {
|
||||
for (i=0; i < blocklen; ++i) s1 += data[j+i], s2 += s1;
|
||||
s1 %= 65521, s2 %= 65521;
|
||||
j += blocklen;
|
||||
blocklen = 5552;
|
||||
}
|
||||
stbiw__sbpush(out, (unsigned char) (s2 >> 8));
|
||||
stbiw__sbpush(out, (unsigned char) s2);
|
||||
stbiw__sbpush(out, (unsigned char) (s1 >> 8));
|
||||
stbiw__sbpush(out, (unsigned char) s1);
|
||||
}
|
||||
*out_len = stbiw__sbn(out);
|
||||
// make returned pointer freeable
|
||||
memmove(stbiw__sbraw(out), out, *out_len);
|
||||
return (unsigned char *) stbiw__sbraw(out);
|
||||
}
|
||||
|
||||
unsigned int stbiw__crc32(unsigned char *buffer, int len)
|
||||
{
|
||||
static unsigned int crc_table[256];
|
||||
unsigned int crc = ~0u;
|
||||
int i,j;
|
||||
if (crc_table[1] == 0)
|
||||
for(i=0; i < 256; i++)
|
||||
for (crc_table[i]=i, j=0; j < 8; ++j)
|
||||
crc_table[i] = (crc_table[i] >> 1) ^ (crc_table[i] & 1 ? 0xedb88320 : 0);
|
||||
for (i=0; i < len; ++i)
|
||||
crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
#define stbiw__wpng4(o,a,b,c,d) ((o)[0]=(unsigned char)(a),(o)[1]=(unsigned char)(b),(o)[2]=(unsigned char)(c),(o)[3]=(unsigned char)(d),(o)+=4)
|
||||
#define stbiw__wp32(data,v) stbiw__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v));
|
||||
#define stbiw__wptag(data,s) stbiw__wpng4(data, s[0],s[1],s[2],s[3])
|
||||
|
||||
static void stbiw__wpcrc(unsigned char **data, int len)
|
||||
{
|
||||
unsigned int crc = stbiw__crc32(*data - len - 4, len+4);
|
||||
stbiw__wp32(*data, crc);
|
||||
}
|
||||
|
||||
static unsigned char stbiw__paeth(int a, int b, int c)
|
||||
{
|
||||
int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c);
|
||||
if (pa <= pb && pa <= pc) return (unsigned char) a;
|
||||
if (pb <= pc) return (unsigned char) b;
|
||||
return (unsigned char) c;
|
||||
}
|
||||
|
||||
unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
|
||||
{
|
||||
int ctype[5] = { -1, 0, 4, 2, 6 };
|
||||
unsigned char sig[8] = { 137,80,78,71,13,10,26,10 };
|
||||
unsigned char *out,*o, *filt, *zlib;
|
||||
signed char *line_buffer;
|
||||
int i,j,k,p,zlen;
|
||||
|
||||
if (stride_bytes == 0)
|
||||
stride_bytes = x * n;
|
||||
|
||||
filt = (unsigned char *) malloc((x*n+1) * y); if (!filt) return 0;
|
||||
line_buffer = (signed char *) malloc(x * n); if (!line_buffer) { free(filt); return 0; }
|
||||
for (j=0; j < y; ++j) {
|
||||
static int mapping[] = { 0,1,2,3,4 };
|
||||
static int firstmap[] = { 0,1,0,5,6 };
|
||||
int *mymap = j ? mapping : firstmap;
|
||||
int best = 0, bestval = 0x7fffffff;
|
||||
for (p=0; p < 2; ++p) {
|
||||
for (k= p?best:0; k < 5; ++k) {
|
||||
int type = mymap[k],est=0;
|
||||
unsigned char *z = pixels + stride_bytes*j;
|
||||
for (i=0; i < n; ++i)
|
||||
switch (type) {
|
||||
case 0: line_buffer[i] = z[i]; break;
|
||||
case 1: line_buffer[i] = z[i]; break;
|
||||
case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
|
||||
case 3: line_buffer[i] = z[i] - (z[i-stride_bytes]>>1); break;
|
||||
case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-stride_bytes],0)); break;
|
||||
case 5: line_buffer[i] = z[i]; break;
|
||||
case 6: line_buffer[i] = z[i]; break;
|
||||
}
|
||||
for (i=n; i < x*n; ++i) {
|
||||
switch (type) {
|
||||
case 0: line_buffer[i] = z[i]; break;
|
||||
case 1: line_buffer[i] = z[i] - z[i-n]; break;
|
||||
case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
|
||||
case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-stride_bytes])>>1); break;
|
||||
case 4: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n]); break;
|
||||
case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break;
|
||||
case 6: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break;
|
||||
}
|
||||
}
|
||||
if (p) break;
|
||||
for (i=0; i < x*n; ++i)
|
||||
est += abs((signed char) line_buffer[i]);
|
||||
if (est < bestval) { bestval = est; best = k; }
|
||||
}
|
||||
}
|
||||
// when we get here, best contains the filter type, and line_buffer contains the data
|
||||
filt[j*(x*n+1)] = (unsigned char) best;
|
||||
memcpy(filt+j*(x*n+1)+1, line_buffer, x*n);
|
||||
}
|
||||
free(line_buffer);
|
||||
zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, 8); // increase 8 to get smaller but use more memory
|
||||
free(filt);
|
||||
if (!zlib) return 0;
|
||||
|
||||
// each tag requires 12 bytes of overhead
|
||||
out = (unsigned char *) malloc(8 + 12+13 + 12+zlen + 12);
|
||||
if (!out) return 0;
|
||||
*out_len = 8 + 12+13 + 12+zlen + 12;
|
||||
|
||||
o=out;
|
||||
memcpy(o,sig,8); o+= 8;
|
||||
stbiw__wp32(o, 13); // header length
|
||||
stbiw__wptag(o, "IHDR");
|
||||
stbiw__wp32(o, x);
|
||||
stbiw__wp32(o, y);
|
||||
*o++ = 8;
|
||||
*o++ = (unsigned char) ctype[n];
|
||||
*o++ = 0;
|
||||
*o++ = 0;
|
||||
*o++ = 0;
|
||||
stbiw__wpcrc(&o,13);
|
||||
|
||||
stbiw__wp32(o, zlen);
|
||||
stbiw__wptag(o, "IDAT");
|
||||
memcpy(o, zlib, zlen); o += zlen; free(zlib);
|
||||
stbiw__wpcrc(&o, zlen);
|
||||
|
||||
stbiw__wp32(o,0);
|
||||
stbiw__wptag(o, "IEND");
|
||||
stbiw__wpcrc(&o,0);
|
||||
|
||||
assert(o == out + *out_len);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes)
|
||||
{
|
||||
FILE *f;
|
||||
int len;
|
||||
unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len);
|
||||
if (!png) return 0;
|
||||
f = fopen(filename, "wb");
|
||||
if (!f) { free(png); return 0; }
|
||||
fwrite(png, 1, len, f);
|
||||
fclose(f);
|
||||
free(png);
|
||||
return 1;
|
||||
}
|
||||
#endif // STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
|
||||
/* Revision history
|
||||
|
||||
0.97 (2015-01-18)
|
||||
fixed HDR asserts, rewrote HDR rle logic
|
||||
0.96 (2015-01-17)
|
||||
add HDR output
|
||||
fix monochrome BMP
|
||||
0.95 (2014-08-17)
|
||||
add monochrome TGA output
|
||||
0.94 (2014-05-31)
|
||||
rename private functions to avoid conflicts with stb_image.h
|
||||
0.93 (2014-05-27)
|
||||
warning fixes
|
||||
0.92 (2010-08-01)
|
||||
casts to unsigned char to fix warnings
|
||||
0.91 (2010-07-17)
|
||||
first public release
|
||||
0.90 first internal release
|
||||
*/
|
||||
90
blender-5.2.0/extern/opensubdiv-source/examples/common/stopwatch.h
vendored
Normal file
90
blender-5.2.0/extern/opensubdiv-source/examples/common/stopwatch.h
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef STOPWATCH_H
|
||||
#define STOPWATCH_H
|
||||
|
||||
#if (_WIN32)
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
class Stopwatch {
|
||||
|
||||
public:
|
||||
|
||||
#ifndef _WIN32
|
||||
Stopwatch() : _totalElapsed(0) { }
|
||||
|
||||
void Start() {
|
||||
struct timeval l_rtime;
|
||||
gettimeofday(&l_rtime,0);
|
||||
_elapsed = (double)l_rtime.tv_sec + (double)l_rtime.tv_usec/1000000.0;
|
||||
}
|
||||
|
||||
void Stop() {
|
||||
struct timeval l_rtime;
|
||||
|
||||
gettimeofday(&l_rtime,0);
|
||||
_elapsed = ((double)l_rtime.tv_sec + (double)l_rtime.tv_usec/1000000.0)
|
||||
- _elapsed;
|
||||
_totalElapsed += _elapsed;
|
||||
}
|
||||
|
||||
double GetElapsed() const {
|
||||
return _elapsed;
|
||||
}
|
||||
|
||||
double GetTotalElapsed() const {
|
||||
return _totalElapsed;
|
||||
}
|
||||
#else
|
||||
Stopwatch() : _totalElapsed(0) {
|
||||
QueryPerformanceFrequency(&_frequency);
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
QueryPerformanceCounter(&_time);
|
||||
}
|
||||
|
||||
void Stop()
|
||||
{
|
||||
LARGE_INTEGER currentTime;
|
||||
QueryPerformanceCounter(¤tTime);
|
||||
_elapsed = currentTime.QuadPart - _time.QuadPart;
|
||||
_totalElapsed+=_elapsed;
|
||||
}
|
||||
|
||||
double GetElapsed() const {
|
||||
return (double) _elapsed / _frequency.QuadPart;
|
||||
}
|
||||
|
||||
double GetTotalElapsed() const {
|
||||
return (double) _totalElapsed / _frequency.QuadPart;
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
#ifndef _WIN32
|
||||
double _elapsed;
|
||||
double _totalElapsed;
|
||||
#else
|
||||
LARGE_INTEGER _time;
|
||||
LARGE_INTEGER _frequency;
|
||||
__int64 _elapsed;
|
||||
__int64 _totalElapsed;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif /* STOPWATCH_H */
|
||||
|
||||
75
blender-5.2.0/extern/opensubdiv-source/examples/common/viewerArgsUtils.cpp
vendored
Normal file
75
blender-5.2.0/extern/opensubdiv-source/examples/common/viewerArgsUtils.cpp
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// Copyright 2019 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#include "../common/viewerArgsUtils.h"
|
||||
|
||||
#include "../../regression/common/arg_utils.h"
|
||||
#include "../../regression/common/shape_utils.h"
|
||||
#include "../common/objAnim.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
namespace ViewerArgsUtils {
|
||||
|
||||
const ObjAnim *
|
||||
PopulateAnimShapes(const ArgOptions &args,
|
||||
std::vector<ShapeDesc> *defaultShapes)
|
||||
{
|
||||
if (args.GetObjFiles().empty())
|
||||
return NULL;
|
||||
|
||||
const ObjAnim *objAnim = ObjAnim::Create(args.GetObjFiles(),
|
||||
args.GetDefaultScheme());
|
||||
|
||||
if (objAnim && defaultShapes) {
|
||||
defaultShapes->push_back(ShapeDesc(args.GetObjFiles()[0], "",
|
||||
args.GetDefaultScheme()));
|
||||
}
|
||||
|
||||
return objAnim;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
PopulateShapes(const ArgOptions &args,
|
||||
std::vector<ShapeDesc> *defaultShapes)
|
||||
{
|
||||
if (defaultShapes) {
|
||||
args.AppendObjShapes(*defaultShapes, true /* print warnings */);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PopulateShapesOrAnimShapes(
|
||||
const ArgOptions &args,
|
||||
std::vector<ShapeDesc> *defaultShapes,
|
||||
const ObjAnim **objAnim)
|
||||
{
|
||||
if (!defaultShapes)
|
||||
return;
|
||||
|
||||
if (args.GetObjFiles().empty())
|
||||
return;
|
||||
|
||||
if (args.GetObjsAreAnim()) {
|
||||
|
||||
if (!objAnim) {
|
||||
printf("Warning: animations of objs are unsupported in this "
|
||||
"viewer.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
*objAnim = PopulateAnimShapes(args, defaultShapes);
|
||||
|
||||
} else {
|
||||
|
||||
PopulateShapes(args, defaultShapes);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
41
blender-5.2.0/extern/opensubdiv-source/examples/common/viewerArgsUtils.h
vendored
Normal file
41
blender-5.2.0/extern/opensubdiv-source/examples/common/viewerArgsUtils.h
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// Copyright 2019 Pixar
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef VIEWER_ARGS_UTILS_H
|
||||
#define VIEWER_ARGS_UTILS_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
class ArgOptions;
|
||||
struct ShapeDesc;
|
||||
class ObjAnim;
|
||||
|
||||
namespace ViewerArgsUtils {
|
||||
|
||||
// From the list of obj files in args, populates the
|
||||
// defaultShapes vector, treating the objs as an animated series, returning
|
||||
// an ObjAnim object.
|
||||
const ObjAnim *PopulateAnimShapes(const ArgOptions &args,
|
||||
std::vector<ShapeDesc> *defaultShapes = 0);
|
||||
|
||||
// From the list of obj files in args, populates the
|
||||
// defaultShapes vector.
|
||||
void PopulateShapes(const ArgOptions &args,
|
||||
std::vector<ShapeDesc> *defaultShapes);
|
||||
|
||||
// From the list of obj files in args, populates the
|
||||
// defaultShapes vector and the objAnim object if animated objs have
|
||||
// been specified in args.
|
||||
void PopulateShapesOrAnimShapes(
|
||||
const ArgOptions &args,
|
||||
std::vector<ShapeDesc> *defaultShapes,
|
||||
const ObjAnim **objAnim);
|
||||
|
||||
|
||||
} // namespace ViewerArgsUtils
|
||||
|
||||
#endif // VIEWER_ARGS_UTILS_H
|
||||
Reference in New Issue
Block a user