Landing 3.0.0.alpha
Sync'ing the 'dev' branch with the 'feature_3.0dev' branch at commit 68c6d11fc36761ae1a5e6cdc3457be16f2e9704a The branch 'feature_3.0dev' is now locked and preserved for historical purposes.
118
CMakeLists.txt
@ -36,6 +36,18 @@ else()
|
||||
message(FATAL_ERROR, "Cannot locate opensubdiv/version.h in CMAKE_SOURCE_DIR")
|
||||
endif()
|
||||
|
||||
# Evaluate 'soname' from OSD version
|
||||
|
||||
# replace '_' with '.'
|
||||
string(REGEX REPLACE "(_)" "." OSD_SONAME ${OpenSubdiv_VERSION})
|
||||
|
||||
# remove starting 'v' character
|
||||
string(REGEX REPLACE "^v" "" OSD_SONAME ${OSD_SONAME})
|
||||
|
||||
add_definitions(
|
||||
-DOPENSUBDIV_VERSION_STRING="${OSD_SONAME}"
|
||||
)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
message(STATUS "Compiling ${CMAKE_PROJECT_NAME} version ${OpenSubdiv_VERSION}")
|
||||
@ -121,12 +133,12 @@ SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
|
||||
set(OSD_COMPILER_FLAGS)
|
||||
|
||||
# Disable spurious warnings in gcc builds and clang
|
||||
# Disable spurrious warnings in gcc builds and clang
|
||||
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANGCC OR CMAKE_COMPILER_IS_ICC )
|
||||
|
||||
# Turn on all warnings
|
||||
if(CMAKE_COMPILER_IS_ICC)
|
||||
list(APPEND OSD_COMPILER_FLAGS -w3 -wd1418 -wd981 -wd383 -wd193)
|
||||
list(APPEND OSD_COMPILER_FLAGS -w2 -wd1572 -wd1418 -wd981 -wd383 -wd193 -wd444)
|
||||
else()
|
||||
list(APPEND OSD_COMPILER_FLAGS -Wall -Wextra)
|
||||
endif()
|
||||
@ -218,6 +230,9 @@ elseif(MSVC)
|
||||
/W3 # Use warning level recommended for production purposes.
|
||||
/WX # Treat all compiler warnings as errors.
|
||||
|
||||
# warning C4005: macro redefinition
|
||||
/wd4005
|
||||
|
||||
# these warnings are being triggered from inside VC's header files
|
||||
# warning C4350: behavior change: 'member1' called instead of 'member2'
|
||||
/wd4350
|
||||
@ -275,8 +290,8 @@ option(MAYA_LOCATION "Path to Maya" "")
|
||||
|
||||
option(NO_LIB "Disable the opensubdiv libs build (caveat emptor)" OFF)
|
||||
option(NO_EXAMPLES "Disable examples build" OFF)
|
||||
option(NO_TUTORIALS "Disable tutorials build" OFF)
|
||||
option(NO_REGRESSION "Disable regression tests build" OFF)
|
||||
option(NO_PYTHON "Disable Python SWIG build" OFF)
|
||||
option(NO_MAYA "Disable Maya plugin build" OFF)
|
||||
option(NO_PTEX "Disable PTex support" OFF)
|
||||
option(NO_DOC "Disable documentation build" OFF)
|
||||
@ -285,8 +300,7 @@ option(NO_TBB "Disable TBB backend" OFF)
|
||||
option(NO_CUDA "Disable CUDA backend" OFF)
|
||||
option(NO_OPENCL "Disable OpenCL backend" OFF)
|
||||
option(NO_CLEW "Disable CLEW wrapper library" OFF)
|
||||
option(NO_GCD "Disable GrandCentralDispatch backend" OFF)
|
||||
option(NO_NEON "Disable NEON backend" OFF)
|
||||
option(NO_OPENGL "Disable OpenGL support")
|
||||
|
||||
# Check for dependencies
|
||||
if(NOT NO_OMP)
|
||||
@ -295,13 +309,15 @@ endif()
|
||||
if(NOT NO_TBB)
|
||||
find_package(TBB 4.0)
|
||||
endif()
|
||||
find_package(OpenGL)
|
||||
if (NOT NO_OPENGL)
|
||||
find_package(OpenGL)
|
||||
endif()
|
||||
find_package(OpenGLES)
|
||||
if(NOT NO_OPENCL)
|
||||
if(NOT NO_CLEW)
|
||||
find_package(CLEW)
|
||||
endif()
|
||||
if(NOT CLEW_FOUND)
|
||||
if (NOT CLEW_FOUND)
|
||||
find_package(OpenCL 1.1)
|
||||
else()
|
||||
set(OPENCL_FOUND TRUE)
|
||||
@ -311,15 +327,11 @@ if(NOT NO_CUDA)
|
||||
find_package(CUDA 4.0)
|
||||
endif()
|
||||
if(NOT ANDROID AND NOT IOS)
|
||||
find_package(GLFW 2.7.0)
|
||||
find_package(GLFW 3.0.0)
|
||||
endif()
|
||||
if(NOT NO_PTEX)
|
||||
find_package(PTex 2.0)
|
||||
endif()
|
||||
find_package(PythonInterp 2.6)
|
||||
find_package(SWIG 1.3.40)
|
||||
find_package(Doxygen 1.8.4)
|
||||
find_package(Docutils 0.6)
|
||||
if (OPENGL_FOUND AND NOT IOS)
|
||||
if (APPLE)
|
||||
find_package(GLEW)
|
||||
@ -332,30 +344,21 @@ if (WIN32)
|
||||
find_package(DXSDK)
|
||||
endif()
|
||||
|
||||
if (NOT NO_GCD AND APPLE)
|
||||
set(GCD_FOUND 1)
|
||||
endif()
|
||||
|
||||
if (NOT NO_NEON AND ANDROID)
|
||||
set(NEON_FOUND 1)
|
||||
endif()
|
||||
|
||||
if (NOT NO_MAYA)
|
||||
find_package(Maya 201200)
|
||||
endif()
|
||||
|
||||
if (NOT NO_DOC)
|
||||
find_package(Doxygen 1.8.4)
|
||||
find_package(Docutils 0.6)
|
||||
else()
|
||||
set(DOXYGEN_EXECUTABLE )
|
||||
endif()
|
||||
|
||||
# Warn about missing dependencies that will cause parts of OpenSubdiv to be
|
||||
# disabled. Also, add preprocessor defines that can be used in the source
|
||||
# code to determine if a specific dependency is present or not.
|
||||
|
||||
if(GCD_FOUND)
|
||||
add_definitions( -DOPENSUBDIV_HAS_GCD )
|
||||
endif()
|
||||
|
||||
if(NEON_FOUND)
|
||||
add_definitions(-DLOCAL_ARM_MODE=arm -DLOCAL_ARM_NEON=true -mfpu=neon)
|
||||
endif()
|
||||
|
||||
if(OPENMP_FOUND)
|
||||
add_definitions(
|
||||
-DOPENSUBDIV_HAS_OPENMP
|
||||
@ -403,11 +406,13 @@ if(GLEW_FOUND AND OPENGL_4_2_FOUND)
|
||||
-DOPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK
|
||||
)
|
||||
else()
|
||||
message(WARNING
|
||||
"OpenGL 4.2 was not found : support for GLSL transform feedback kernels "
|
||||
"will be disabled in Osd. If you have an OpenGL SDK installed "
|
||||
"(version 4.2 or above), please refer to the FindOpenGL.cmake "
|
||||
"shared module in your cmake installation.")
|
||||
if (NOT NO_OPENGL)
|
||||
message(WARNING
|
||||
"OpenGL 4.2 was not found : support for GLSL transform feedback kernels "
|
||||
"will be disabled in Osd. If you have an OpenGL SDK installed "
|
||||
"(version 4.2 or above), please refer to the FindOpenGL.cmake "
|
||||
"shared module in your cmake installation.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# note : (GLSL compute shader kernels require GL 4.3)
|
||||
@ -416,11 +421,13 @@ if(GLEW_FOUND AND OPENGL_4_3_FOUND)
|
||||
-DOPENSUBDIV_HAS_GLSL_COMPUTE
|
||||
)
|
||||
else()
|
||||
message(WARNING
|
||||
"OpenGL 4.3 was not found : support for GLSL compute shader kernels "
|
||||
"will be disabled in Osd. If you have an OpenGL SDK installed "
|
||||
"(version 4.3 or above), please refer to the FindOpenGL.cmake "
|
||||
"shared module in your cmake installation.")
|
||||
if (NOT NO_OPENGL)
|
||||
message(WARNING
|
||||
"OpenGL 4.3 was not found : support for GLSL compute shader kernels "
|
||||
"will be disabled in Osd. If you have an OpenGL SDK installed "
|
||||
"(version 4.3 or above), please refer to the FindOpenGL.cmake "
|
||||
"shared module in your cmake installation.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(OPENGLES_FOUND)
|
||||
@ -443,8 +450,8 @@ if(OPENCL_FOUND)
|
||||
if (NOT NO_CLEW)
|
||||
message(WARNING
|
||||
"OpenCL was found, but CLEW was not. "
|
||||
"Building with OpenCL support enabled, but the build "
|
||||
"wouldn't be portable on systems without OpenCL installed.")
|
||||
"Building with OpenCL support enabled, but the built binary "
|
||||
"will not be portable to systems without OpenCL installed.")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
@ -584,23 +591,20 @@ function(_stringify src_files varname)
|
||||
|
||||
foreach(src_file ${src_files})
|
||||
|
||||
string(REGEX REPLACE ".*[.](.*)" "\\1" extension "${src_file}")
|
||||
string(REGEX REPLACE ".*[.](.*)" "\\1" extension "${src_file}")
|
||||
|
||||
if(NOT ${extension} STREQUAL "cu")
|
||||
string(REGEX REPLACE "(.*)[.].*" "\\1.gen.h" inc_file "${src_file}")
|
||||
list(APPEND inc_files "${CMAKE_CURRENT_BINARY_DIR}/${inc_file}")
|
||||
|
||||
string(REGEX REPLACE "(.*)[.].*" "\\1.gen.h" inc_file "${src_file}")
|
||||
list(APPEND inc_files "${inc_file}")
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${inc_file}"
|
||||
COMMAND
|
||||
stringify "${CMAKE_CURRENT_SOURCE_DIR}/${src_file}" "${CMAKE_CURRENT_BINARY_DIR}/${inc_file}"
|
||||
DEPENDS
|
||||
stringify "${CMAKE_CURRENT_SOURCE_DIR}/${src_file}"
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${inc_file}"
|
||||
COMMAND
|
||||
stringify "${CMAKE_CURRENT_SOURCE_DIR}/${src_file}" "${CMAKE_CURRENT_BINARY_DIR}/${inc_file}"
|
||||
DEPENDS
|
||||
stringify "${CMAKE_CURRENT_SOURCE_DIR}/${src_file}"
|
||||
)
|
||||
|
||||
endif()
|
||||
endforeach()
|
||||
set(${varname} ${inc_files} PARENT_SCOPE)
|
||||
endfunction()
|
||||
@ -670,7 +674,7 @@ endmacro()
|
||||
|
||||
add_subdirectory(opensubdiv)
|
||||
|
||||
if (NOT NO_REGRESSION AND NOT ANDROID AND NOT IOS) # XXXdyu
|
||||
if (NOT ANDROID AND NOT IOS) # XXXdyu
|
||||
add_subdirectory(regression)
|
||||
endif()
|
||||
|
||||
@ -678,8 +682,8 @@ if (NOT NO_EXAMPLES)
|
||||
add_subdirectory(examples)
|
||||
endif()
|
||||
|
||||
if (NOT NO_PYTHON)
|
||||
add_subdirectory(python)
|
||||
if (NOT NO_TUTORIALS)
|
||||
add_subdirectory(tutorials)
|
||||
endif()
|
||||
|
||||
if (NOT NO_DOC)
|
||||
|
11
NOTICE.txt
@ -2,8 +2,9 @@
|
||||
Copyright 2013 Pixar
|
||||
All rights reserved.
|
||||
|
||||
This product includes software developed at
|
||||
Pixar (http://www.pixar.com/).
|
||||
Autodesk, Inc. (http://www.autodesk.com/).
|
||||
Google, Inc. (http://www.google.com/).
|
||||
DigitalFish (http://digitalfish.com/).
|
||||
This product includes software developed at:
|
||||
Pixar (http://www.pixar.com/).
|
||||
Dreamworks Animation (http://www.dreamworksanimation.com/)
|
||||
Autodesk, Inc. (http://www.autodesk.com/).
|
||||
Google, Inc. (http://www.google.com/).
|
||||
DigitalFish (http://digitalfish.com/).
|
||||
|
11
README.md
@ -8,6 +8,11 @@ Feel free to use it and let us know what you think.
|
||||
|
||||
For more details about OpenSubdiv, see [Pixar Graphics Technologies](http://graphics.pixar.com).
|
||||
|
||||
# 3.0 ALPHA Release
|
||||
|
||||
The OpenSubdiv 3.0 release is still early in its development cycle. As such, all APIs, code examples and documentation are subject to change at any time, without notice or backward compatibility with existing code. Please consult the [release notes](http://graphics.pixar.com/opensubdiv/docs_3x_alpha/intro.html) for more details about the features and improvements contained in this new release.
|
||||
|
||||
The 3.0 Beta release is tentatively scheduled for late Q4 2014.
|
||||
|
||||
## Git Flow
|
||||
|
||||
@ -31,6 +36,7 @@ Required:
|
||||
Optional:
|
||||
* [GLEW](http://sourceforge.net/projects/glew/) (Windows/Linux only)
|
||||
* [CUDA](http://developer.nvidia.com/category/zone/cuda-zone)
|
||||
* [TBB] (https://www.threadingbuildingblocks.org/)
|
||||
* [OpenCL](http://www.khronos.org/opencl/)
|
||||
* [GLFW](http://www.glfw.org/)
|
||||
* [Ptex](https://github.com/wdas/ptex)
|
||||
@ -56,16 +62,17 @@ Optional:
|
||||
|
||||
-DNO_LIB=1 // disable the opensubdiv libs build (caveat emptor)
|
||||
-DNO_EXAMPLES=1 // disable examples build
|
||||
-DNO_TUTORIALS=1 // disable tutorials build
|
||||
-DNO_REGRESSION=1 // disable regression tests build
|
||||
-DNO_PYTHON=1 // disable Python SWIG build
|
||||
-DNO_MAYA=1 // disable Maya plugin build
|
||||
-DNO_PTEX=1 // disable PTex support
|
||||
-DNO_DOC=1 // disable documentation build
|
||||
-DNO_OMP=1 // disable OpenMP
|
||||
-DNO_TBB=1 // disable TBB
|
||||
-DNO_CUDA=1 // disable CUDA
|
||||
-DNO_OPENCL=1 // disable OpenCL
|
||||
-DNO_OPENGL=1 // disable OpenGL
|
||||
-DNO_CLEW=1 // disable CLEW wrapper library
|
||||
-DNO_GCD=1 // disable GrandCentralDispatch on OSX
|
||||
````
|
||||
|
||||
The paths to Maya, Ptex, GLFW, and GLEW can also be specified through the
|
||||
|
@ -33,7 +33,8 @@
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
if (WIN32)
|
||||
find_path( GLEW_INCLUDE_DIR
|
||||
|
||||
find_path(GLEW_INCLUDE_DIR
|
||||
NAMES
|
||||
GL/glew.h
|
||||
PATHS
|
||||
@ -41,9 +42,15 @@ if (WIN32)
|
||||
"$ENV{GLEW_LOCATION}/include"
|
||||
"$ENV{PROGRAMFILES}/GLEW/include"
|
||||
"${PROJECT_SOURCE_DIR}/extern/glew/include"
|
||||
DOC "The directory where GL/glew.h resides" )
|
||||
DOC "The directory where GL/glew.h resides" )
|
||||
|
||||
find_library( GLEW_LIBRARY
|
||||
if ("${CMAKE_GENERATOR}" MATCHES "[Ww]in64")
|
||||
set(ARCH x64)
|
||||
else()
|
||||
set(ARCH x86)
|
||||
endif()
|
||||
|
||||
find_library(GLEW_LIBRARY
|
||||
NAMES
|
||||
glew GLEW glew32s glew32
|
||||
PATHS
|
||||
@ -52,7 +59,9 @@ if (WIN32)
|
||||
"$ENV{PROGRAMFILES}/GLEW/lib"
|
||||
"${PROJECT_SOURCE_DIR}/extern/glew/bin"
|
||||
"${PROJECT_SOURCE_DIR}/extern/glew/lib"
|
||||
DOC "The GLEW library")
|
||||
PATH_SUFFIXES
|
||||
Release/${ARCH}
|
||||
DOC "The GLEW library")
|
||||
endif ()
|
||||
|
||||
if (${CMAKE_HOST_UNIX})
|
||||
|
@ -56,6 +56,7 @@ if(APPLE)
|
||||
HINTS
|
||||
"${MAYA_LOCATION}"
|
||||
"$ENV{MAYA_LOCATION}"
|
||||
"/Applications/Autodesk/maya2015/Maya.app/Contents"
|
||||
"/Applications/Autodesk/maya2014/Maya.app/Contents"
|
||||
"/Applications/Autodesk/maya2013.5/Maya.app/Contents"
|
||||
"/Applications/Autodesk/maya2013/Maya.app/Contents"
|
||||
@ -82,6 +83,8 @@ if(UNIX)
|
||||
HINTS
|
||||
"${MAYA_LOCATION}"
|
||||
"$ENV{MAYA_LOCATION}"
|
||||
"/usr/autodesk/maya2015-x64"
|
||||
"/usr/autodesk/maya2014-x64"
|
||||
"/usr/autodesk/maya2013-x64"
|
||||
"/usr/autodesk/maya2012.17-x64"
|
||||
"/usr/autodesk/maya2012-x64"
|
||||
@ -107,6 +110,10 @@ if(WIN32)
|
||||
HINTS
|
||||
"${MAYA_LOCATION}"
|
||||
"$ENV{MAYA_LOCATION}"
|
||||
"C:/Program Files/Autodesk/Maya2015.5-x64"
|
||||
"C:/Program Files/Autodesk/Maya2015.5"
|
||||
"C:/Program Files/Autodesk/Maya2014.5-x64"
|
||||
"C:/Program Files/Autodesk/Maya2014.5"
|
||||
"C:/Program Files/Autodesk/Maya2013.5-x64"
|
||||
"C:/Program Files/Autodesk/Maya2013.5"
|
||||
"C:/Program Files (x86)/Autodesk/Maya2013.5"
|
||||
|
@ -54,6 +54,7 @@ else()
|
||||
|
||||
endif()
|
||||
|
||||
find_package(PythonInterp 2.6)
|
||||
|
||||
# ReST - HTML documentation
|
||||
if (DOCUTILS_FOUND AND PYTHONINTERP_FOUND)
|
||||
@ -68,27 +69,48 @@ if (DOCUTILS_FOUND AND PYTHONINTERP_FOUND)
|
||||
cmake_build.rst
|
||||
code_examples.rst
|
||||
dxviewer.rst
|
||||
dxptexviewer.rst
|
||||
far_overview.rst
|
||||
getting_started.rst
|
||||
glviewer.rst
|
||||
glevallimit.rst
|
||||
glfvarviewer.rst
|
||||
glpainttest.rst
|
||||
glptexviewer.rst
|
||||
glsharetopology.rst
|
||||
glstencilviewer.rst
|
||||
glbatchviewer.rst
|
||||
glviewer.rst
|
||||
hbr_overview.rst
|
||||
intro.rst
|
||||
limiteval.rst
|
||||
maya_osdpolysmooth.rst
|
||||
osd_overview.rst
|
||||
painttest.rst
|
||||
ptexviewer.rst
|
||||
release_notes.rst
|
||||
release_notes_2x.rst
|
||||
sdc_overview.rst
|
||||
subdivision_surfaces.rst
|
||||
tutorials.rst
|
||||
using_osd.rst
|
||||
using_osd_compile.rst
|
||||
using_osd_hbr.rst
|
||||
using_osd_textures.rst
|
||||
uvviewer.rst
|
||||
vtr_overview.rst
|
||||
)
|
||||
|
||||
|
||||
# Configure release number in RST template file
|
||||
|
||||
# Replace '_' with '.'
|
||||
string(REGEX REPLACE "(_)" "." RELEASE_STRING ${OpenSubdiv_VERSION})
|
||||
|
||||
# Remove starting 'v' character
|
||||
string(REGEX REPLACE "^v" "" RELEASE_STRING ${RELEASE_STRING})
|
||||
|
||||
# Format API version string
|
||||
set(RELEASE_STRING "Release ${RELEASE_STRING}")
|
||||
|
||||
# Replace string in navigation bar
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/rst_template.txt"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/rst_template.txt" )
|
||||
|
||||
# process rst markup files
|
||||
foreach(src ${RST_FILES})
|
||||
get_filename_component(BASENAME ${src} NAME_WE)
|
||||
@ -107,7 +129,7 @@ if (DOCUTILS_FOUND AND PYTHONINTERP_FOUND)
|
||||
--no-xml-declaration
|
||||
--initial-header-level=3
|
||||
--strip-comments
|
||||
--template="${CMAKE_CURRENT_SOURCE_DIR}/rst_template.txt"
|
||||
--template="${CMAKE_CURRENT_BINARY_DIR}/rst_template.txt"
|
||||
--stylesheet=css/rst.css
|
||||
--link-stylesheet
|
||||
"${infile}" "${outfile}"
|
||||
|
@ -31,9 +31,6 @@ Additional Resources
|
||||
|
||||
----
|
||||
|
||||
Tutorials
|
||||
=========
|
||||
|
||||
Links
|
||||
=====
|
||||
|
||||
@ -46,8 +43,8 @@ Links
|
||||
Videos
|
||||
======
|
||||
|
||||
**Feature Adaptive GPU Rendering of Catmull-Clark Subdivision Surfaces (2012)**
|
||||
*******************************************************************************
|
||||
Feature Adaptive GPU Rendering of Catmull-Clark Subdivision Surfaces (2012)
|
||||
***************************************************************************
|
||||
|
||||
.. raw:: html
|
||||
|
||||
@ -55,8 +52,8 @@ Videos
|
||||
<iframe width="640" height="360" src="http://www.youtube.com/embed/uogAzQoVdNU" frameborder="0" allowfullscreen></iframe>
|
||||
</center>
|
||||
|
||||
**Open Subdivision Technology Review (2012)**
|
||||
*********************************************
|
||||
Open Subdivision Technology Review (2012)
|
||||
*****************************************
|
||||
|
||||
.. raw:: html
|
||||
|
||||
@ -66,8 +63,8 @@ Videos
|
||||
|
||||
First public demonstration of OpenSubdiv at Siggraph 2012.
|
||||
|
||||
**Autodesk User Group At Anaheim (2013)**
|
||||
*****************************************
|
||||
Autodesk User Group At Anaheim (2013)
|
||||
*************************************
|
||||
|
||||
.. raw:: html
|
||||
|
||||
@ -77,8 +74,8 @@ First public demonstration of OpenSubdiv at Siggraph 2012.
|
||||
|
||||
Bill Polson, Director of Industry Strategy at Pixar Animation Studios
|
||||
|
||||
**Why Model with Subdivisions (2013)**
|
||||
**************************************
|
||||
Why Model with Subdivisions (2013)
|
||||
**********************************
|
||||
|
||||
.. raw:: html
|
||||
|
||||
@ -88,8 +85,8 @@ Bill Polson, Director of Industry Strategy at Pixar Animation Studios
|
||||
|
||||
Ivo Kos, Modelling Technical Director at Pixar Animation Studios
|
||||
|
||||
**Meet the Experts: The OpenSubdiv Project (2013)**
|
||||
***************************************************
|
||||
Meet the Experts: The OpenSubdiv Project (2013)
|
||||
***********************************************
|
||||
|
||||
.. raw:: html
|
||||
|
||||
|
@ -33,7 +33,7 @@ API Overview
|
||||
Architecture Overview
|
||||
=====================
|
||||
|
||||
Because the OpenSubdiv software is intended to run on a variete of computing
|
||||
Because the OpenSubdiv software is intended to run on a variety of computing
|
||||
resources, the API architecture has to accomodate a fairly complex matrix of
|
||||
interoperations. In order to achieve the requisite flexibility, the code structure
|
||||
is both layered and modular.
|
||||
@ -53,57 +53,64 @@ processing costs of any given feature that is not used.
|
||||
|
||||
----
|
||||
|
||||
Layers
|
||||
======
|
||||
API Layers
|
||||
==========
|
||||
|
||||
From a top-down point of view, OpenSubdiv is comprised of 3 layers : **Hbr**,
|
||||
**Far** and **Osd**.
|
||||
From a top-down point of view, OpenSubdiv is comprised of several layers, some
|
||||
public, and some private.
|
||||
|
||||
.. image:: images/api_layers.png
|
||||
Layers list in descending order:
|
||||
|
||||
The color groupings indicate inter-layer functional dependencies:
|
||||
* **Osd** (OpenSubdiv)
|
||||
* **Far** (Feature Adaptive Representation)
|
||||
* **Vtr** (Vectorized Topological Representation)
|
||||
* **Sdc** (Subdivision Core)
|
||||
|
||||
* Osd depends on Far, but not on Hbr
|
||||
* Far depends on Hbr
|
||||
* Hbr has no dependencies
|
||||
Client mesh data enters the API through the Far layer. Typically, results will
|
||||
be collected from the Osd layer. However, it is therefore possible to use
|
||||
functionality from Far without introducing any dependency on Osd.
|
||||
|
||||
It is therefore possible to use functionality from Hbr without introducing any
|
||||
dependency on either Far or Osd.
|
||||
Although there are several entry-points to provide topology and primitive variable
|
||||
data to OpenSubdiv, eventually everything must pass through the private Vtr and Sdc
|
||||
representations for topological analysis.
|
||||
|
||||
----
|
||||
See `Using the Right Tools`_ for more in-depth coverage.
|
||||
|
||||
Representation vs. Implementation Layers
|
||||
****************************************
|
||||
|
||||
One of the core performance goals of our subdivision algorithms is to leverage
|
||||
interactive performance out of massively parallel code execution wherever
|
||||
possible. In order to support a large diversity of discrete compute devices through
|
||||
multiple dedicated SDKs, it is critical to distill the computations into the
|
||||
smallest and simplest kernels possible. These can in turn be safely ported and
|
||||
optimized for each of the hardware platforms.
|
||||
|
||||
.. image:: images/api_representations.png
|
||||
|
||||
This separation of general purpose against hardware-specific code is translated into
|
||||
two types of layers : the **implementation** layer against the **representation**
|
||||
layers.
|
||||
|
||||
----
|
||||
|
||||
Data Flows
|
||||
**********
|
||||
|
||||
Data flows are mostly 1-directional, from top to bottom as a number of algorithms
|
||||
are preparing the coarse mesh data to be refined and passing their results to
|
||||
the next element in the processing chain.
|
||||
|
||||
.. image:: images/api_data_flow.png
|
||||
.. image:: images/api_layers_3_0.png
|
||||
:align: center
|
||||
|
||||
----
|
||||
|
||||
Representation vs. Implementation Layers
|
||||
========================================
|
||||
|
||||
One of the core performance goals of our subdivision algorithms is to leverage
|
||||
interactive performance out of massively parallel code execution wherever
|
||||
possible. In order to support a large diversity of compute architectures
|
||||
it is critical to stream the geometric data to the compute kernels in the
|
||||
most optimal way.
|
||||
|
||||
Data structures that are efficient for topology analysis during the pre-computation
|
||||
stage are not very good candidates for parallel processing. Our layered structure
|
||||
reflects this requirement: topology analysis and other pre-computation tasks are
|
||||
delegated to "representation" layers, while the actual execution of computations
|
||||
has been moved to an "implementation" layer.
|
||||
|
||||
.. image:: images/api_representations.png
|
||||
|
||||
**Representation** layers are for general purpose algorithms and differenciated by
|
||||
the requirements placed on data represenation. See `Multiple Representations`_ for
|
||||
more details.
|
||||
|
||||
The **Implementation** layer contains hardware and API-specific implementations.
|
||||
In order to minimize code redundancy and bugs, we strive to reduce device-specific
|
||||
computation logic to the most simplistic expression possible (in many cases as
|
||||
simple as series of multiply-ads).
|
||||
|
||||
----
|
||||
|
||||
Multiple Representations
|
||||
************************
|
||||
========================
|
||||
|
||||
The coarse mesh of a subdivision surface is represented by a collection of
|
||||
components that maintain relationships to each other.
|
||||
@ -126,14 +133,14 @@ the very description of these connections (dependencies) between vertices.
|
||||
:align: center
|
||||
|
||||
This is why OpenSubdiv provides specific representations for mesh data:
|
||||
- Hbr is a half-edge relational representation
|
||||
- Far is a serialized representation
|
||||
- Vtr is a vectorized topology-only representation
|
||||
- Far is a feature adaptive serialized representation
|
||||
|
||||
A typical workflow would be to manipulate the topology in authoring applications,
|
||||
maybe using Hbr meshes for common editing operations. Once the topology of the mesh
|
||||
has stabilized, it is processed into a serialized form that can then be evaluated
|
||||
at interactive framerates. The serialized form is embodied by Far, which can then
|
||||
be migrated by the device-specific functions in Osd.
|
||||
maybe using Hbr or a similar relational representation for common editing operations.
|
||||
Once the topology of the mesh has stabilized, it is processed into a serialized form
|
||||
that can then be evaluated at interactive framerates. The serialized form is
|
||||
embodied by Far, which can then be migrated by device-specific functions in Osd.
|
||||
|
||||
.. image:: images/api_workflows.png
|
||||
:align: center
|
||||
@ -153,10 +160,56 @@ architecture:
|
||||
|
||||
.. image:: images/osd_layers.png
|
||||
|
||||
Hbr serves both as an advanced topological description and the custodian of the
|
||||
Catmull-Clark (and Loop) subdivision rules. Far is then used to leverage these
|
||||
rules in order to produce serialized topological tables.
|
||||
Vtr serves both as a private, efficient, intermediate topological description and
|
||||
as the custodian of the Catmull-Clark (and Loop) subdivision rules. Far is used to
|
||||
leverage these rules in order to produce serialized topological tables.
|
||||
|
||||
The remaining computations have been reduced to extremely simple forms of
|
||||
interpolation, which can be dispatched to a variety of discrete computation
|
||||
platforms.
|
||||
|
||||
----
|
||||
|
||||
Using the Right Tools
|
||||
=====================
|
||||
|
||||
OpenSubdiv's tiered interface offers a lot flexibility to make your application
|
||||
both fast and robust. Because navigating through the large collection of classes and
|
||||
features can be challenging, here is a flow-chart that should help sketch
|
||||
the broad lines of going about using subdivisions in your application.
|
||||
|
||||
General client application requirements:
|
||||
|
||||
+----------------------+-------------------------------------------------------+
|
||||
| Surface Limit | For some applications, a polygonal approximation of |
|
||||
| | the smooth surface is enough. Others require |
|
||||
| | C :sup:`2` continuous differentiable bi-cubic patches |
|
||||
| | (ex: deformable displacement mapping, smooth normals |
|
||||
| | and semi-sharp creases...) |
|
||||
+----------------------+-------------------------------------------------------+
|
||||
| Deforming Surface | Applications such as off-line image renderers often |
|
||||
| | process a single frame at a time. Others, such as |
|
||||
| | interactive games need to evaluate deforming |
|
||||
| | character surface every frame. Because we can amortize|
|
||||
| | many computations if the topology of the mesh does not|
|
||||
| | change, OpenSubdiv provides 'stencil tables' in order |
|
||||
| | to leverage subdivision refinement into a |
|
||||
| | pre-computation step. |
|
||||
+----------------------+-------------------------------------------------------+
|
||||
| Multi-threading | OpenSubdiv also provides dedicated interfaces to |
|
||||
| | leverage parallelism on a wide variety of platforms |
|
||||
| | and API standards, including both CPUs and GPUs. |
|
||||
+----------------------+-------------------------------------------------------+
|
||||
| GPU Draw | If the application requires interactive drawing on |
|
||||
| | screen, OpenSubdiv provides several back-end |
|
||||
| | implementations, including D3D11 and OpenGL. These |
|
||||
| | back-ends provide full support for programmable |
|
||||
| | shading. |
|
||||
+----------------------+-------------------------------------------------------+
|
||||
|
||||
Flow-chart:
|
||||
|
||||
.. image:: images/osd_flow.png
|
||||
:align: center
|
||||
:target: images/osd_flow.png
|
||||
|
||||
|
@ -46,9 +46,10 @@ process using platform independent configuration files in order to generate
|
||||
makefiles and workspaces that are native to the platform of choice.
|
||||
|
||||
The process involves the following steps:
|
||||
1. Locate & build the requisite dependencies
|
||||
2. Configure & run CMake to generate Makefiles / MSVC solution / XCode project
|
||||
3. Run the build from make / MSVC / XCode
|
||||
|
||||
#. Locate & build the requisite dependencies
|
||||
#. Configure & run CMake to generate Makefiles / MSVC solution / XCode project
|
||||
#. Run the build from make / MSVC / XCode
|
||||
|
||||
----
|
||||
|
||||
@ -116,8 +117,8 @@ The following configuration arguments can be passed to the cmake command line.
|
||||
|
||||
-DNO_LIB=1 // disable the opensubdiv libs build (caveat emptor)
|
||||
-DNO_EXAMPLES=1 // disable examples build
|
||||
-DNO_TUTORIALS=1 // disable tutorials build
|
||||
-DNO_REGRESSION=1 // disable regression tests build
|
||||
-DNO_PYTHON=1 // disable Python SWIG build
|
||||
-DNO_MAYA=1 // disable Maya plugin build
|
||||
-DNO_PTEX=1 // disable PTex support
|
||||
-DNO_DOC=1 // disable documentation build
|
||||
@ -125,21 +126,18 @@ The following configuration arguments can be passed to the cmake command line.
|
||||
-DNO_TBB=1 // disable TBB
|
||||
-DNO_CUDA=1 // disable CUDA
|
||||
-DNO_OPENCL=1 // disable OpenCL
|
||||
-DNO_OPENGL=1 // disable OpenGL
|
||||
-DNO_CLEW=1 // disable CLEW wrapper library
|
||||
-DNO_GCD=1 // disable GrandCentralDispatch on OSX
|
||||
|
||||
Environment Variables
|
||||
_____________________
|
||||
|
||||
The paths to Maya, Ptex, GLFW, and GLEW can also be specified through the
|
||||
following environment variables:
|
||||
The paths to Maya, Ptex, GLFW, GLEW and other dependencies can also be specified
|
||||
through the following environment variables:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
MAYA_LOCATION
|
||||
PTEX_LOCATION
|
||||
GLFW_LOCATION
|
||||
GLEW_LOCATION
|
||||
MAYA_LOCATION, PTEX_LOCATION, GLFW_LOCATION, GLEW_LOCATION
|
||||
|
||||
Automated Script
|
||||
________________
|
||||
|
@ -38,39 +38,26 @@ of the software.
|
||||
:widths: 50 50
|
||||
|
||||
* - | `glViewer <glviewer.html>`_
|
||||
| `glBatchViewer <glbatchviewer.html>`_
|
||||
| `glStencilViewer <glstencilviewer.html>`_
|
||||
- | `limitEval <limiteval.html>`_
|
||||
| `paintTest <painttest.html>`_
|
||||
| `ptexViewer <ptexviewer.html>`_
|
||||
| `uvViewer <uvviewer.html>`_
|
||||
| `glPtexViewer <glptexviewer.html>`_
|
||||
| `glEvalLimit <glevallimit.html>`_
|
||||
- | `glStencilViewer <glstencilviewer.html>`_
|
||||
| `glPaintTest <glpainttest.html>`_
|
||||
| `glShareTopology <glsharetopology.html>`_
|
||||
| `glFVarViewer <glfvarviewer.html>`_
|
||||
|
||||
.. list-table:: **DirectX examples**
|
||||
:class: quickref
|
||||
:widths: 50 50
|
||||
|
||||
* - | `dxViewer <dxviewer.html>`_
|
||||
- |
|
||||
- | `dxPtexViewer <dxptexviewer.html>`_
|
||||
|
||||
.. list-table:: **Plugin examples**
|
||||
:class: quickref
|
||||
:widths: 50 50
|
||||
:widths: 50
|
||||
|
||||
* - | `osdPolySmooth <maya_osdpolysmooth.html>`_
|
||||
| `mayaViewer <mayaviewer.html>`_
|
||||
- | `mayaPtexViewer <mayaptexviewer.html>`_
|
||||
|
||||
|
|
||||
|
||||
.. container:: notebox
|
||||
|
||||
**Note:**
|
||||
the mayaViewer and mayaPtexViewer plugins are currently unsupported and they
|
||||
may fail to compile or work with current versions of OpenSubdiv. These were
|
||||
originally written for the sole purpose of live demonstrations and the code
|
||||
is provided only as an implementation example.
|
||||
|
||||
|
|
||||
|
||||
----
|
||||
|
||||
|
@ -52,7 +52,7 @@
|
||||
}
|
||||
.coursewareBackground ul li {
|
||||
padding-left: 6px!important;
|
||||
list-style-type:square!important;
|
||||
list-style-type:disc!important;
|
||||
}
|
||||
.coursewareBackground h1, .coursewareBackground h2, .coursewareBackground h1 a, .coursewareBackground h2 a {
|
||||
padding-bottom:10px;
|
||||
|
@ -466,6 +466,10 @@ code {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.quickLinks {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
div.navigation {
|
||||
position:fixed;
|
||||
width:245px;
|
||||
@ -482,6 +486,8 @@ div.navigation {
|
||||
|
||||
div.navigation ul {
|
||||
list-style-image: url('../images/toggler0.gif');
|
||||
margin-left: 0px;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
div.navigation a:link,
|
||||
|
117
documentation/dxptexviewer.rst
Normal file
@ -0,0 +1,117 @@
|
||||
..
|
||||
Copyright 2013 Pixar
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "Apache License")
|
||||
with the following modification; you may not use this file except in
|
||||
compliance with the Apache License and the following modification to it:
|
||||
Section 6. Trademarks. is deleted and replaced with:
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor
|
||||
and its affiliates, except as required to comply with Section 4(c) of
|
||||
the License and to reproduce the content of the NOTICE file.
|
||||
|
||||
You may obtain a copy of the Apache License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the Apache License with the above modification is
|
||||
distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the Apache License for the specific
|
||||
language governing permissions and limitations under the Apache License.
|
||||
|
||||
|
||||
dxPtexViewer
|
||||
------------
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:backlinks: none
|
||||
|
||||
SYNOPSIS
|
||||
========
|
||||
|
||||
.. parsed-literal::
|
||||
:class: codefhead
|
||||
|
||||
**dxPtexViewer**
|
||||
[**-e** *environment map*]
|
||||
[**-d** *HDR diffuse map*]
|
||||
[**-s** *HDR specular map*]
|
||||
[**-y**]
|
||||
[**--disp** *displacement scale*]
|
||||
[**-l** *isolation level*]
|
||||
*ptex color file*
|
||||
*ptex displacement file*
|
||||
*ptex occlusion file*
|
||||
*ptex specular file*
|
||||
*objfile(s)*
|
||||
|
||||
DESCRIPTION
|
||||
===========
|
||||
|
||||
``dxPtexViewer`` is a stand-alone application that showcases advanced HDR shading
|
||||
with color, displacement, occlusion and specular ptex maps. Multiple controls
|
||||
are available to experiment with the algorithms.
|
||||
|
||||
.. include:: under_development.rst
|
||||
|
||||
|
||||
OPTIONS
|
||||
=======
|
||||
|
||||
**-e** *environment map*
|
||||
A low dynamic range spherical environment map used as a background. Ideally,
|
||||
a color-normalized version of the HDR light probe.
|
||||
|
||||
**-d** *HDR diffuse map*
|
||||
An HDR file containing a diffuse environment map (typically they are low
|
||||
resolution blurry hemispherical convolutions of the environment light probe).
|
||||
|
||||
**-s** *environment map*
|
||||
An HDR file containing a specular environment map.
|
||||
|
||||
**--disp** *displacement scale*
|
||||
A scalar multiplier for the shader displacement values.
|
||||
|
||||
**-y**
|
||||
Swap Z-up geometry to Y-UP.
|
||||
|
||||
**-l** *isolation level*
|
||||
Select the desired isolation level of adaptive feature isolation. This can be
|
||||
useful when trying to load large pieces of geometry.
|
||||
|
||||
*ptex color file*
|
||||
A ptex file containing RGB channels read as material albedo color.
|
||||
|
||||
*ptex displacement file*
|
||||
A single-channel ptex file (preferrably float precision) containing the
|
||||
displacement values.
|
||||
|
||||
*ptex occlusion file*
|
||||
A single-channel ptex file (preferrably 8 bits precision) containing a
|
||||
pre-computed ambient occlusion signal.
|
||||
|
||||
*ptex specular file*
|
||||
A single-channel ptex file (preferrably 8 bits precision) applied to modulate
|
||||
the specular reflectance of the material
|
||||
|
||||
*objfile(s)*
|
||||
A sequence of obj files used as an animation loop (the topology has to match
|
||||
the data contained in all the ptex files !)
|
||||
|
||||
|
||||
Keyboard Controls
|
||||
=================
|
||||
|
||||
.. code:: c++
|
||||
|
||||
q : quit
|
||||
esc : hide GUI
|
||||
f : fit frame
|
||||
+/- : increase / decrese tessellation rate
|
||||
|
||||
|
||||
|
||||
.. include:: examples_see_also.rst
|
@ -44,12 +44,16 @@ DESCRIPTION
|
||||
uniform and feature adaptive subdivision schemes to a collection of geometric
|
||||
shapes. Multiple controls are available to experiment with the algorithms.
|
||||
|
||||
.. image:: images/dxviewer.png
|
||||
:width: 400px
|
||||
:align: center
|
||||
:target: images/dxviewer.png
|
||||
|
||||
.. container:: impnotip
|
||||
|
||||
* **Note:**
|
||||
|
||||
dxViewer requires Microsoft's DirectX 11 SDK
|
||||
dxViewer requires Microsoft's DirectX D3D11 SDK
|
||||
|
||||
OPTIONS
|
||||
=======
|
||||
@ -62,16 +66,5 @@ OPTIONS
|
||||
Number of repetitions of the animtion loop (default=0 is infinite)
|
||||
|
||||
|
||||
SEE ALSO
|
||||
========
|
||||
|
||||
`Code Examples <code_examples.html>`__, \
|
||||
`glViewer <glviewer.html>`__, \
|
||||
`glBatchViewer <glbatchviewer.html>`__, \
|
||||
`glStencilViewer <glstencilviewer.html>`__, \
|
||||
`ptexViewer <ptexviewer.html>`__, \
|
||||
`paintTest <painttest.html>`__, \
|
||||
`limitEval <limiteval.html>`__, \
|
||||
`dxViewer <dxviewer.html>`__, \
|
||||
`uvViewer <uvviewer.html>`__, \
|
||||
|
||||
.. include:: examples_see_also.rst
|
||||
|
14
documentation/examples_see_also.rst
Normal file
@ -0,0 +1,14 @@
|
||||
SEE ALSO
|
||||
========
|
||||
|
||||
Other `examples <code_examples.html>`__ \ :
|
||||
`glViewer <glviewer.html>`__, \
|
||||
`glShareTopology <glsharetopology.html>`__, \
|
||||
`glStencilViewer <glstencilviewer.html>`__, \
|
||||
`glPtexViewer <glptexviewer.html>`__, \
|
||||
`glEvalLimit <glevallimit.html>`__, \
|
||||
`glFVarViewer <glfvarviewer.html>`__, \
|
||||
`dxViewer <dxviewer.html>`__, \
|
||||
`dxPtexViewer <dxptexviewer.html>`__, \
|
||||
`mayaPolySmooth <maya_osdpolysmooth.html>`__, \
|
||||
|
@ -29,60 +29,185 @@ FAR Overview
|
||||
:local:
|
||||
:backlinks: none
|
||||
|
||||
.. image:: images/api_layers_3_0.png
|
||||
:width: 100px
|
||||
:target: images/api_layers_3_0.png
|
||||
|
||||
Feature Adaptive Representation (Far)
|
||||
=====================================
|
||||
|
||||
Far is a serialized topoloigcal data representation.Far uses hbr to create and
|
||||
cache fast run time data structures for table driven subdivision of vertices and
|
||||
cubic patches for limit surface evaluation. `Feature-adaptive <subdivision_surfaces.html#feature-adaptive-subdivision>`__
|
||||
refinement logic is used to adaptively refine coarse topology near features like
|
||||
extraordinary vertices and creases in order to make the topology amenable to
|
||||
cubic patch evaluation. Far is also a generic, templated algorithmic base API
|
||||
that clients in higher levels instantiate and use by providing an implementation
|
||||
of a vertex class. It supports these subdivision schemes:
|
||||
The *Far* API layer is the central interface that processes client-supplied
|
||||
geometry and turns it into a `serialized data representation
|
||||
<api_overview.html#multiple-representations>`__ ready for parallel processing.
|
||||
|
||||
Factories & Tables
|
||||
==================
|
||||
First, *Far* provides the tools to refine subidivision topology
|
||||
(`Far::TopologyRefiner <#far-topologyrefiner>`__). Topology refinement can be
|
||||
either uniform or sparse, where extraordinary features are automatically
|
||||
isolated (see `feature adaptive subdivision <subdivision_surfaces.html#feature-adaptive-subdivision>`__).
|
||||
|
||||
Subdivision Tables
|
||||
==================
|
||||
As a geometry representation, *Far* also provides a set of *"Tables"* classes.
|
||||
These tables are designed to be static containers for the refined topology
|
||||
data, after it has been serialized and factorized. This represnetation is
|
||||
embodied in the `Far::PatchTables <#far-patchtables>`__ and the
|
||||
`Far::StencilTables <#far-patchtables>`__ classes.
|
||||
|
||||
Patch Tables
|
||||
============
|
||||
*Far* is also a fully featured API. Typically *Far* tabular data is targetted at
|
||||
*Osd*, where it can be processed by an implementation optimized for a specific
|
||||
hardware. However, for client-code that does not require a dedicated
|
||||
implementation, *Far* itself provides a fully-featured single-threaded
|
||||
implementation of subdivision interpolation algorithms, both discrete and at
|
||||
the limit.
|
||||
|
||||
Refining Topology
|
||||
=================
|
||||
|
||||
Stencil Tables
|
||||
==============
|
||||
The *Far* topology classes present a public interface for the refinement
|
||||
functionality provided in *Vtr*, either directly within Far or indirectly
|
||||
eventually though *Osd*. The two main topology refinement classes are as
|
||||
follows:
|
||||
|
||||
+-------------------------------+---------------------------------------------------+
|
||||
| TopologyRefiner | A class encapsulating the topology of a refined |
|
||||
| | mesh. |
|
||||
+-------------------------------+---------------------------------------------------+
|
||||
| TopologyRefinerFactory<MESH> | A factory class template specialized by users (in |
|
||||
| | terms of their mesh class) to construct |
|
||||
| | TopologyRefiner as quickly as possible. |
|
||||
+-------------------------------+---------------------------------------------------+
|
||||
|
||||
Stencils are the most direct method of evaluation of specific locations on the
|
||||
limit of a subdivision surface starting from the coarse vertices of the control
|
||||
cage.
|
||||
These classes are the least well defined of the API, but given they provide the
|
||||
public interface to all of the improvements proposed, they potentially warrant
|
||||
the most attention. Far::TopologyRefiner is purely topological and it is the
|
||||
backbone used to construct or be associated with the other table classes in Far.
|
||||
|
||||
.. image:: images/far_stencil0.png
|
||||
.. container:: notebox
|
||||
|
||||
**Alpha Issues**
|
||||
|
||||
Interface issues needing attention:
|
||||
|
||||
* TopologyRefiner::Refine() needs more options (bundled in struct)
|
||||
* TopologyRefiner::Interpolate() methods need revisiting
|
||||
* considering simplifying TopologyRefiner interface overall -- may expose
|
||||
TopologyLevel for public inspection
|
||||
* specialization of TopologyRefinerFactory<MESH> needs more work
|
||||
|
||||
Far::TopologyRefiner
|
||||
********************
|
||||
|
||||
TopologyRefiner is the building block for many other useful classes in
|
||||
OpenSubdiv, but its purpose is more specific. It is intended to store the
|
||||
topology of an arbitrarily refined subdivision hierarchy to support the
|
||||
construction of `stencil tables <#patch-tables>`__, `patch tables
|
||||
<#patch-tables>`__, etc.
|
||||
|
||||
Aside from public access to topology, *TopologyRefiner::Refine(...)* is
|
||||
internally where simple specifications of refinement (currently uniform or
|
||||
feature-adaptive with a level argument) will be translated into refinement
|
||||
operations within Vtr. Feature-adaptive refinement is a special case of
|
||||
*"sparse"* or *"selective"* refinement, and so the feature-adaptive logic
|
||||
exists internal to TopologyRefiner and translates the feature-analysis into a
|
||||
simpler topological specification of refinement to Vtr.
|
||||
|
||||
.. image:: images/topology_refiner.png
|
||||
:align: center
|
||||
|
||||
Sample Location
|
||||
***************
|
||||
The longer term intent is that the public Refine(...) operation eventually be
|
||||
overloaded to allow clients more selective control of refinement. While
|
||||
TopologyRefiner is a purely topological class, and so free of any definitions
|
||||
of vertex data, the public inteface has been extended to include templated
|
||||
functors that allow clients to interpolate primitive variable data.
|
||||
|
||||
Each stencil is associated with a singular parametric location on the coarse
|
||||
mesh. The paramatric location is defined as face location and local [0.0 - 1.0]
|
||||
(u,v) triplet:
|
||||
Far::TopologyRefinerFactory
|
||||
***************************
|
||||
|
||||
In the case of a non-coarse quad face, the parametric sub-face quadrant needs to
|
||||
be identified. This can be done either explicitly or implicitly by using the
|
||||
unique ptex face indices for instance.
|
||||
Consistent with other classes in Far instances of TopologyRefiner are created
|
||||
by a factory class -- in this case Far::TopologyRefinerFactory. This class
|
||||
is an important entry point for clients its task is to map/convert data in a
|
||||
client's mesh into the internal `Vtr <vtr_overview.html>`__ representation as
|
||||
quickly as possible.
|
||||
|
||||
.. image:: images/far_stencil6.png
|
||||
The TopologyRefinerFactory class is a class template parameterized by and
|
||||
specialized for the client's mesh class, i.e. TopologyRefinerFactory<MESH>.
|
||||
Since a client' mesh representation knows best how to identify the topological
|
||||
neighborhoods required, no generic implementation would provide the most
|
||||
direct means of conversion possible, and so we rely on specialization. For
|
||||
situations where mesh data is not defined in a boundary representation, a
|
||||
simple container for raw mesh data is provided along with a Factory
|
||||
specialized to construct TopologyRefiners from it.
|
||||
|
||||
So there are two ways to create TopologyRefiners:
|
||||
|
||||
* use the existing TopologyRefinerFactory<TopologyDescriptor> with a
|
||||
populated instance of TopologyDescriptor
|
||||
* specialize TopologyRefinerFactory<class MESH> for more efficient
|
||||
conversion
|
||||
|
||||
XXXX <insert blurb about Descriptor>
|
||||
|
||||
Specialization of TopologyRefinerFactory<class MESH> should be done with care
|
||||
as the goal here is to maximize the performance of the conversion and so
|
||||
minimize overhead due to runtime validation. The template provides the
|
||||
high-level construction of the required topology vectors of the underlying
|
||||
Vtr, with the requirement that two methods will be specialized with the
|
||||
following purpose:
|
||||
|
||||
* specify the sizes of topological data so that vectors can be pre-allocated
|
||||
* assign the topological data to the newly allocated vectors
|
||||
|
||||
As noted above, the assumption here is that the client's boundary-rep knows best
|
||||
how to retrieve the data that we require most efficiently. After the factory class
|
||||
gathers sizing information and allocates appropriate memory, the factory provides
|
||||
the client with locations of the appropriate tables to be populated (using the
|
||||
same `Array <vtr_overview.html#arry-type>`__ classes and interface used to access
|
||||
the tables). The client is expected to load a complete topological description
|
||||
along with additional optional data, i.e.:
|
||||
|
||||
* the six topological relations required by Vtr, oriented when manifold
|
||||
* sharpness values for edges and/or vertices (optional)
|
||||
* additional tags related to the components, e.g. holes (optional)
|
||||
* values-per-face for face-varying channels (optional)
|
||||
|
||||
While there is plenty of opportunity for user error here, that is no different
|
||||
from any other conversion process. Given that Far controls the construction
|
||||
process through the Factory class, we do have ample opportunity to insert
|
||||
runtime validation, and to vary that level of validation at any time on an
|
||||
instance of the Factory.
|
||||
|
||||
A common base class has been created for the factory class, i.e.:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
template <class MESH>
|
||||
class TopologyRefinerFactory : public TopologyRefinerFactoryBase
|
||||
|
||||
both to provide common code independent of <MESH> and also potentially to
|
||||
protect core code from unwanted specialization.
|
||||
|
||||
Far::PatchTables
|
||||
================
|
||||
|
||||
.. include:: under_development.rst
|
||||
|
||||
|
||||
Far::StencilTables
|
||||
==================
|
||||
|
||||
.. include:: under_development.rst
|
||||
|
||||
The base container for stencil data is the StencilTables class. As with most
|
||||
other Far entities, it has an associated StencilTablesFactory that requires
|
||||
a TopologyRefiner:
|
||||
|
||||
.. image:: images/far_stencil5.png
|
||||
:align: center
|
||||
|
||||
|
||||
Principles
|
||||
**********
|
||||
|
||||
Iterative subdivision algorithms such as the one used in `FarSubdivisionTables <#subdivision-tables>`__
|
||||
converge towards the limit surface by sucessively refining the vertices of the
|
||||
coarse control cage.
|
||||
Iterative subdivision algorithms such as the one used in `SubdivisionTables
|
||||
<#subdivision-tables>`__ converge towards the limit surface by sucessively
|
||||
refining the vertices of the coarse control cage.
|
||||
|
||||
.. image:: images/far_stencil4.png
|
||||
:align: center
|
||||
@ -114,48 +239,33 @@ control cage only around extraordinary locations, and otherwise reverting to fas
|
||||
bi-cubic bspline patch evaluation. The use of bi-cubic patches also allows the
|
||||
accumulation of analytical derivatives.
|
||||
|
||||
API Architecture
|
||||
****************
|
||||
Limit Stencils
|
||||
**************
|
||||
|
||||
The base container for stencil data is the FarStencilTables class. As with most
|
||||
other Far entities, it has an associated FarStencilTablesFactory that requires
|
||||
an HbrMesh:
|
||||
Limit stencils are the most direct method of evaluation of specific locations on
|
||||
the limit of a subdivision surface starting from the coarse vertices of the
|
||||
control cage.
|
||||
|
||||
.. image:: images/far_stencil5.png
|
||||
.. image:: images/far_stencil0.png
|
||||
:align: center
|
||||
|
||||
Assuming a properly qualified HbrMesh:
|
||||
|
||||
.. code:: c++
|
||||
Sample Location
|
||||
***************
|
||||
|
||||
HMesh<OpenSubdiv::FarStencilFactoryVertex> * mesh;
|
||||
Each stencil is associated with a singular parametric location on the coarse
|
||||
mesh. The paramatric location is defined as face location and local [0.0 - 1.0]
|
||||
(u,v) triplet:
|
||||
|
||||
FarStencilTables controlStencils;
|
||||
In the case of a non-coarse quad face, the parametric sub-face quadrant needs to
|
||||
be identified. This can be done either explicitly or implicitly by using the
|
||||
unique ptex face indices for instance.
|
||||
|
||||
OpenSubdiv::FarStencilTablesFactory<> factory(mesh);
|
||||
.. image:: images/far_stencil6.png
|
||||
:align: center
|
||||
|
||||
for (int i=0; i<nfaces; ++i) {
|
||||
|
||||
HFace * f = mesh->GetFace(i);
|
||||
|
||||
int nv = f->GetNumVertices();
|
||||
|
||||
if (nv!=4) {
|
||||
|
||||
// if the face is not a quad, we have to iterate over sub-quad(rants)
|
||||
for (int j=0; j<f->GetNumVertices(); ++j) {
|
||||
|
||||
factory.SetCurrentFace(i,j);
|
||||
|
||||
factory.AppendStencils( &controlStencils, nsamples/nv, u, v, reflevel );
|
||||
}
|
||||
} else {
|
||||
|
||||
factory.SetCurrentFace(i);
|
||||
|
||||
factory.AppendStencils( &controlStencils, g_nsamples, u, v, reflevel );
|
||||
}
|
||||
}
|
||||
Code example
|
||||
************
|
||||
|
||||
When the control vertices (controlPoints) move in space, the limit locations can
|
||||
be very efficiently recomputed simply by applying the blending weights to the
|
||||
|
@ -80,6 +80,11 @@ Our active development branch is named *dev* : all new features and buf fixes sh
|
||||
be submitted to this branch. The changes submitted to the dev branch are periodically
|
||||
patched to the 'master' branch as new versions are released.
|
||||
|
||||
.. image:: images/gitflow.jpg
|
||||
:align: center
|
||||
:target: images/gitflow.jpg
|
||||
|
||||
|
||||
Checking out branches
|
||||
_____________________
|
||||
|
||||
@ -142,32 +147,25 @@ Code Overview
|
||||
|
||||
The OpenSubdiv code base contains the following main areas:
|
||||
|
||||
**./opensubdiv/**
|
||||
|
||||
The main subdivision APIs : Hbr, Far and Osd.
|
||||
|
||||
|
||||
**./regression/**
|
||||
|
||||
Standalone regression tests and baseline data to help maintain the integrity of
|
||||
our APIs. If GPU SDKs are detected, some tests will attempt to run computations
|
||||
on those GPUs.
|
||||
|
||||
**./examples/**
|
||||
|
||||
A small collection of standalone applications that illustrate how to deploy the
|
||||
various features and optimizations of the OpenSubdiv APIs. The GL-based examples
|
||||
rely on the cross-platform GLFW API for interactive window management, while the
|
||||
DirectX ones are OS-native.
|
||||
|
||||
**./python/**
|
||||
|
||||
Python-SWIG bindings for a minimal uniform refinement wrapper
|
||||
|
||||
**./documentation/**
|
||||
|
||||
The reStructuredText source files along with python scripts that generate the HTML
|
||||
documentation site.
|
||||
+----------------------+---------------------------------------------------------------------------------------+
|
||||
| Directory | Contents |
|
||||
+======================+=======================================================================================+
|
||||
| **./opensubdiv/** | The main subdivision APIs : Sdc, Vtr, Far and Osd. |
|
||||
+----------------------+---------------------------------------------------------------------------------------+
|
||||
| **./examples/** | A small collection of standalone applications that illustrate how to deploy the +
|
||||
| | various features and optimizations of the OpenSubdiv APIs. The GL-based examples |
|
||||
| | rely on the cross-platform GLFW API for interactive window management, while the |
|
||||
| | DirectX ones are OS-native. |
|
||||
+----------------------+---------------------------------------------------------------------------------------+
|
||||
| **./tutorials/** | Tutorials showing how to manipulate the APIs of OpenSubdiv. |
|
||||
+----------------------+---------------------------------------------------------------------------------------+
|
||||
| **./documentation/** | The reStructuredText source files along with python scripts that generate the HTML |
|
||||
| | documentation site. |
|
||||
+----------------------+---------------------------------------------------------------------------------------+
|
||||
| **./regression/** | Standalone regression tests and baseline data to help maintain the integrity of |
|
||||
| | our APIs. If GPU SDKs are detected, some tests will attempt to run computations |
|
||||
| | on those GPUs. |
|
||||
+----------------------+---------------------------------------------------------------------------------------+
|
||||
|
||||
----
|
||||
|
||||
|
@ -22,8 +22,8 @@
|
||||
language governing permissions and limitations under the Apache License.
|
||||
|
||||
|
||||
limitEval
|
||||
---------
|
||||
glEvalLimit
|
||||
-----------
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
@ -40,7 +40,7 @@ SYNOPSIS
|
||||
DESCRIPTION
|
||||
===========
|
||||
|
||||
``limitEval`` is a stand-alone application that showcases the limit surface
|
||||
``glEvalLimit`` is a stand-alone application that showcases the limit surface
|
||||
Eval module. On the given shape, random samples are generated in local u,v space.
|
||||
Vertex, varying and face-varying data is then computed on the surface limit and
|
||||
displayed as colors. Multiple controls are available to experiment with the algorithms.
|
||||
@ -57,14 +57,4 @@ OPTIONS
|
||||
Launches the application in full-screen mode (if is supported by GLFW on the
|
||||
OS)
|
||||
|
||||
SEE ALSO
|
||||
========
|
||||
|
||||
`Code Examples <code_examples.html>`__, \
|
||||
`glViewer <glviewer.html>`__, \
|
||||
`glBatchViewer <glbatchviewer.html>`__, \
|
||||
`ptexViewer <ptexviewer.html>`__, \
|
||||
`paintTest <painttest.html>`__, \
|
||||
`limitEval <limiteval.html>`__, \
|
||||
`dxViewer <dxviewer.html>`__, \
|
||||
|
||||
.. include:: examples_see_also.rst
|
@ -22,8 +22,8 @@
|
||||
language governing permissions and limitations under the Apache License.
|
||||
|
||||
|
||||
uvViewer
|
||||
--------
|
||||
glFVarViewer
|
||||
------------
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
@ -32,12 +32,12 @@ uvViewer
|
||||
SYNOPSIS
|
||||
========
|
||||
|
||||
**uvViewer** [**-d** *isolation level*] [**-c** *animation loops*] [**-f**] *objfile(s)*
|
||||
**glFVarViewer** [**-d** *isolation level*] [**-c** *animation loops*] [**-f**] *objfile(s)*
|
||||
|
||||
DESCRIPTION
|
||||
===========
|
||||
|
||||
``uvViewer`` is a stand-alone application that allows the inspection of
|
||||
``glFVarViewer`` is a stand-alone application that allows the inspection of
|
||||
face-varying data interpolation. The window displays 2 views:
|
||||
|
||||
* left side: regular 3D view of the model, with a procedural (u,v) texture
|
||||
@ -65,14 +65,5 @@ OPTIONS
|
||||
Launches the application in full-screen mode (if is supported by GLFW on the
|
||||
OS)
|
||||
|
||||
SEE ALSO
|
||||
========
|
||||
|
||||
`Code Examples <code_examples.html>`__, \
|
||||
`glBatchViewer <glbatchviewer.html>`__, \
|
||||
`glStencilViewer <glstencilviewer.html>`__, \
|
||||
`ptexViewer <ptexviewer.html>`__, \
|
||||
`paintTest <painttest.html>`__, \
|
||||
`limitEval <limiteval.html>`__, \
|
||||
`dxViewer <dxviewer.html>`__, \
|
||||
|
||||
.. include:: examples_see_also.rst
|
@ -22,8 +22,8 @@
|
||||
language governing permissions and limitations under the Apache License.
|
||||
|
||||
|
||||
paintTest
|
||||
---------
|
||||
glPaintTest
|
||||
-----------
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
@ -35,16 +35,15 @@ SYNOPSIS
|
||||
.. parsed-literal::
|
||||
:class: codefhead
|
||||
|
||||
**paintTest**
|
||||
**glPaintTest**
|
||||
[**-f**]
|
||||
*objfile(s)*
|
||||
|
||||
DESCRIPTION
|
||||
===========
|
||||
|
||||
``ptexViewer`` is a stand-alone application that showcases advanced HDR shading
|
||||
with color, displacement, occlusion and specular ptex maps. Multiple controls
|
||||
are available to experiment with the algorithms.
|
||||
``glPaintTest`` is a small stand-alone application showing the potential of
|
||||
using GPU limit tessellation for painting and sculpting applications.
|
||||
|
||||
.. image:: images/painttest.jpg
|
||||
:width: 400px
|
||||
@ -72,15 +71,4 @@ Keyboard Controls
|
||||
d : use texture as displacement
|
||||
|
||||
|
||||
SEE ALSO
|
||||
========
|
||||
|
||||
`Code Examples <code_examples.html>`__, \
|
||||
`glViewer <glviewer.html>`__, \
|
||||
`glBatchViewer <glbatchviewer.html>`__, \
|
||||
`glStencilViewer <glstencilviewer.html>`__, \
|
||||
`ptexViewer <ptexviewer.html>`__, \
|
||||
`limitEval <limiteval.html>`__, \
|
||||
`dxViewer <dxviewer.html>`__, \
|
||||
|
||||
|
||||
.. include:: examples_see_also.rst
|
@ -22,8 +22,8 @@
|
||||
language governing permissions and limitations under the Apache License.
|
||||
|
||||
|
||||
ptexViewer
|
||||
----------
|
||||
glPtexViewer
|
||||
------------
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
@ -35,7 +35,7 @@ SYNOPSIS
|
||||
.. parsed-literal::
|
||||
:class: codefhead
|
||||
|
||||
**ptexViewer**
|
||||
**glPtexViewer**
|
||||
[**-e** *environment map*]
|
||||
[**-d** *HDR diffuse map*]
|
||||
[**-s** *HDR specular map*]
|
||||
@ -54,7 +54,7 @@ SYNOPSIS
|
||||
DESCRIPTION
|
||||
===========
|
||||
|
||||
``ptexViewer`` is a stand-alone application that showcases advanced HDR shading
|
||||
``glPtexViewer`` is a stand-alone application that showcases advanced HDR shading
|
||||
with color, displacement, occlusion and specular ptex maps. Multiple controls
|
||||
are available to experiment with the algorithms.
|
||||
|
||||
@ -122,20 +122,14 @@ Keyboard Controls
|
||||
|
||||
.. code:: c++
|
||||
|
||||
e : draw normals
|
||||
g : toggle ptex texel guttering
|
||||
q : quit
|
||||
esc : hide GUI
|
||||
x : save screenshot
|
||||
f : fit frame
|
||||
+/- : increase / decrese tessellation rate
|
||||
r : reload and re-compile the shader files
|
||||
e : draw normals
|
||||
|
||||
|
||||
SEE ALSO
|
||||
========
|
||||
|
||||
`Code Examples <code_examples.html>`__, \
|
||||
`glViewer <glviewer.html>`__, \
|
||||
`glBatchViewer <glbatchviewer.html>`__, \
|
||||
`glStencilViewer <glstencilviewer.html>`__, \
|
||||
`paintTest <painttest.html>`__, \
|
||||
`limitEval <limiteval.html>`__, \
|
||||
`dxViewer <dxviewer.html>`__, \
|
||||
`uvViewer <uvviewer.html>`__, \
|
||||
|
||||
.. include:: examples_see_also.rst
|
58
documentation/glsharetopology.rst
Normal file
@ -0,0 +1,58 @@
|
||||
..
|
||||
Copyright 2013 Pixar
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "Apache License")
|
||||
with the following modification; you may not use this file except in
|
||||
compliance with the Apache License and the following modification to it:
|
||||
Section 6. Trademarks. is deleted and replaced with:
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor
|
||||
and its affiliates, except as required to comply with Section 4(c) of
|
||||
the License and to reproduce the content of the NOTICE file.
|
||||
|
||||
You may obtain a copy of the Apache License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the Apache License with the above modification is
|
||||
distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the Apache License for the specific
|
||||
language governing permissions and limitations under the Apache License.
|
||||
|
||||
|
||||
glShareTopology
|
||||
---------------
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:backlinks: none
|
||||
|
||||
SYNOPSIS
|
||||
========
|
||||
|
||||
.. parsed-literal::
|
||||
:class: codefhead
|
||||
|
||||
**glShareTopology** [**-d** *isolation level*] *objfile(s)*
|
||||
|
||||
DESCRIPTION
|
||||
===========
|
||||
|
||||
``glShareTopology`` is a stand-alone application that showcases the implementation of topology
|
||||
instancing across Compute contexts. Multiple controls are available to experiment with the algorithms.
|
||||
|
||||
.. image:: images/glsharetopology.png
|
||||
:width: 400px
|
||||
:align: center
|
||||
:target: images/glsharetopology.png
|
||||
|
||||
OPTIONS
|
||||
=======
|
||||
|
||||
**-d** *isolation level*
|
||||
Select the desired isolation level of adaptive feature isolation. This can be
|
||||
useful when trying to load large pieces of geometry.
|
||||
|
||||
.. include:: examples_see_also.rst
|
@ -60,15 +60,4 @@ OPTIONS
|
||||
Launches the application in full-screen mode (if is supported by GLFW on the
|
||||
OS)
|
||||
|
||||
SEE ALSO
|
||||
========
|
||||
|
||||
`Code Examples <code_examples.html>`__, \
|
||||
`glViewer <glviewer.html>`__, \
|
||||
`glBatchViewer <glbatchviewer.html>`__, \
|
||||
`ptexViewer <ptexviewer.html>`__, \
|
||||
`paintTest <painttest.html>`__, \
|
||||
`limitEval <limiteval.html>`__, \
|
||||
`dxViewer <dxviewer.html>`__, \
|
||||
`uvViewer <uvviewer.html>`__, \
|
||||
|
||||
.. include:: examples_see_also.rst
|
||||
|
@ -35,7 +35,12 @@ SYNOPSIS
|
||||
.. parsed-literal::
|
||||
:class: codefhead
|
||||
|
||||
**glViewer** [**-d** *isolation level*] [**-c** *animation loops*] [**-f**] *objfile(s)*
|
||||
**glViewer**
|
||||
[**-d** *isolation level*]
|
||||
[**-c** *animation loops*]
|
||||
[**-f**]
|
||||
[**-axis**]
|
||||
*objfile(s)*
|
||||
|
||||
DESCRIPTION
|
||||
===========
|
||||
@ -63,15 +68,11 @@ OPTIONS
|
||||
Launches the application in full-screen mode (if is supported by GLFW on the
|
||||
OS)
|
||||
|
||||
SEE ALSO
|
||||
========
|
||||
**-axis**
|
||||
Swap Y-up / Z-up axis when loading obj files
|
||||
|
||||
`Code Examples <code_examples.html>`__, \
|
||||
`glBatchViewer <glbatchviewer.html>`__, \
|
||||
`glStencilViewer <glstencilviewer.html>`__, \
|
||||
`ptexViewer <ptexviewer.html>`__, \
|
||||
`paintTest <painttest.html>`__, \
|
||||
`limitEval <limiteval.html>`__, \
|
||||
`dxViewer <dxviewer.html>`__, \
|
||||
`uvViewer <uvviewer.html>`__, \
|
||||
*objfile(s)*
|
||||
A sequence of obj files used as an animation loop (the topology has to match
|
||||
the data contained in all the ptex files !)
|
||||
|
||||
.. include:: examples_see_also.rst
|
||||
|
@ -41,6 +41,19 @@ vertices and edges.
|
||||
|
||||
Hbr is also the lowest-level subdivision library in Pixar's `Photorealistic RenderMan`.
|
||||
|
||||
.. container:: notebox
|
||||
|
||||
**Note**
|
||||
|
||||
As of OpenSubdiv 3.0, all **Hbr** dependencies have been removed from the
|
||||
core APIs (**Sdc**, **Vtr**, **Far**, **Osd**). The legacy source code of
|
||||
**Hbr** is provided purely for regression and legacy purposes. If your code
|
||||
is currently depending on Hbr functionaliy, we recommend migrating to the
|
||||
newer APIs as we cannot guarantee that this code will be maintained in
|
||||
future releases.
|
||||
For more information see the `3.0 release notes <release_notes.html>`_
|
||||
|
||||
|
||||
----
|
||||
|
||||
Half-edge Data Structure
|
||||
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 19 KiB |
BIN
documentation/images/api_layers_3_0.png
Normal file
After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 7.9 KiB |
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 10 KiB |
BIN
documentation/images/construction.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
documentation/images/dxviewer.png
Normal file
After Width: | Height: | Size: 192 KiB |
BIN
documentation/images/far_tutorial_0.0.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
documentation/images/far_tutorial_1.0.png
Normal file
After Width: | Height: | Size: 59 KiB |
BIN
documentation/images/far_tutorial_3.0.png
Normal file
After Width: | Height: | Size: 99 KiB |
BIN
documentation/images/gitflow.jpg
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
documentation/images/glsharetopology.png
Normal file
After Width: | Height: | Size: 110 KiB |
BIN
documentation/images/hbr_tutorial_2.0.png
Normal file
After Width: | Height: | Size: 45 KiB |
BIN
documentation/images/osd_flow.png
Normal file
After Width: | Height: | Size: 138 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
BIN
documentation/images/osd_splash.png
Normal file
After Width: | Height: | Size: 289 KiB |
BIN
documentation/images/topology_refiner.png
Normal file
After Width: | Height: | Size: 40 KiB |
BIN
documentation/images/vtr_refinement.1.png
Normal file
After Width: | Height: | Size: 18 KiB |
@ -69,10 +69,9 @@ a character of 30,000 polygons to the second level of subdivision (500,000 polyg
|
||||
Being able to perform the same operation in less than 3ms allows the user to interact
|
||||
with the smooth, accurate limit surface at all times.
|
||||
|
||||
.. image:: images/efficient_subdivision.png
|
||||
:height: 400px
|
||||
.. image:: images/osd_splash.png
|
||||
:align: center
|
||||
:target: images/efficient_subdivision.png
|
||||
:target: images/osd_splash.png
|
||||
|
||||
|
||||
|
||||
|
@ -100,14 +100,5 @@ fvarBoundaryMethod, fvarPropagateCorners, smoothTriangles, creaseMethod,
|
||||
| - Chaikin: Improves the appearance of multiedge creases with varying weight | | | |
|
||||
+-----------------------------------------------------------------------------------------+------+----------+------------------------------------+
|
||||
|
||||
SEE ALSO
|
||||
========
|
||||
|
||||
`Code Examples <code_examples.html>`__, \
|
||||
`glBatchViewer <glbatchviewer.html>`__, \
|
||||
`glStencilViewer <glstencilviewer.html>`__, \
|
||||
`ptexViewer <ptexviewer.html>`__, \
|
||||
`paintTest <painttest.html>`__, \
|
||||
`limitEval <limiteval.html>`__, \
|
||||
`dxViewer <dxviewer.html>`__, \
|
||||
`uvViewer <uvviewer.html>`__, \
|
||||
.. include:: examples_see_also.rst
|
||||
|
@ -33,13 +33,16 @@
|
||||
<div class="quickLinks">
|
||||
<ul>
|
||||
<li><a href="intro.html">Introduction</a></li>
|
||||
<li><a href="getting_started.html">Getting Started</a></li>
|
||||
<li><a href="cmake_build.html">Building OpenSubdiv</a></li>
|
||||
<li><a href="code_examples.html">Code Examples</a></li>
|
||||
<ul>
|
||||
<li><a href="getting_started.html">Getting Started</a></li>
|
||||
<li><a href="cmake_build.html">Building OpenSubdiv</a></li>
|
||||
<li><a href="code_examples.html">Code Examples</a></li>
|
||||
</ul>
|
||||
<p></p>
|
||||
<li><a href="subdivision_surfaces.html">Subdivision Surfaces</a>
|
||||
<ul>
|
||||
<li><a href="subdivision_surfaces.html#introduction">Introduction</a></li>
|
||||
<li><a href="subdivision_surfaces.html#manifold-geometry">Topology</a></li>
|
||||
<li><a href="subdivision_surfaces.html#arbitrary-topology">Topology</a></li>
|
||||
<li><a href="subdivision_surfaces.html#boundary-interpolation-rules">Boundary Interpolation</a></li>
|
||||
<li><a href="subdivision_surfaces.html#semi-sharp-creases">Semi-Sharp Creases</a></li>
|
||||
<li><a href="subdivision_surfaces.html#hierarchical-edits">Hierarchical Edits</a></li>
|
||||
@ -47,35 +50,42 @@
|
||||
<li><a href="subdivision_surfaces.html#feature-adaptive-subdivision">Feature Adaptive</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="api_overview.html">APIs Overview</a>
|
||||
<ul>
|
||||
<li><a href="hbr_overview.html">Hbr</a></li>
|
||||
<li><a href="far_overview.html">Far</a></li>
|
||||
<ul>
|
||||
<li><a href="far_overview.html#subdivision-tables">Subdivision Tables</a></li>
|
||||
<li><a href="far_overview.html#patch-tables">Patch Tables</a></li>
|
||||
<li><a href="far_overview.html#stencil-tables">Stencil Tables</a></li>
|
||||
</ul>
|
||||
<li><a href="osd_overview.html">Osd</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="using_osd.html">Using OpenSubdiv</a>
|
||||
<p></p>
|
||||
<li><a href="using_osd.html">OpenSubdiv</a>
|
||||
<ul>
|
||||
<li><a href="api_overview.html">API Overview</a>
|
||||
<li><a href="osd_overview.html">Osd</a></li>
|
||||
<li><a href="far_overview.html">Far</a></li>
|
||||
<ul>
|
||||
<li><a href="far_overview.html#topology-refiner">Topology Refiner</a></li>
|
||||
<li><a href="far_overview.html#stencil-tables">Stencil Tables</a></li>
|
||||
<li><a href="far_overview.html#patch-tables">Patch Tables</a></li>
|
||||
</ul>
|
||||
<li><a href="vtr_overview.html">Vtr</a></li>
|
||||
<li><a href="sdc_overview.html">Sdc</a></li>
|
||||
</li>
|
||||
<p></p>
|
||||
<li><a href="tutorials.html">Tutorials</a>
|
||||
<li><a href="using_osd_compile.html#compiling-linking">Compiling & Linking</a></li>
|
||||
<li><a href="using_osd_hbr.html">Manipulating Topology</a></li>
|
||||
<li><a href="using_osd.html">Writing Shaders</a></li>
|
||||
<li><a href="">Writing Shaders</a></li>
|
||||
<li><a href="using_osd_textures.html">Textures</a></li>
|
||||
<li><a href="using_osd.html">Primitive Batching</a></li>
|
||||
<p></p>
|
||||
<li><a href="hbr_overview.html">(Hbr)</a></li>
|
||||
<ul>
|
||||
<li><a href="using_osd_hbr.html">(Using Hbr)</a></li>
|
||||
</ul>
|
||||
</ul>
|
||||
</li>
|
||||
<p></p>
|
||||
<li><a href="additional_resources.html">Additional Resources</a>
|
||||
<ul>
|
||||
<li><a href="http://graphics.pixar.com/opensubdiv/forum.html">Forum</a>
|
||||
<li><a href="additional_resources.html#links">Links</a>
|
||||
<li><a href="additional_resources.html#tutorials">Tutorials</a>
|
||||
<li><a href="additional_resources.html#videos">Videos</a>
|
||||
</ul>
|
||||
<p></p>
|
||||
<li><a href="release_notes.html">Release Notes</a>
|
||||
<p></p>
|
||||
<li><a href="doxy_html/index.html" target="_blank">Doxygen</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -29,11 +29,15 @@ OSD Overview
|
||||
:local:
|
||||
:backlinks: none
|
||||
|
||||
.. image:: images/api_layers_3_0.png
|
||||
:width: 100px
|
||||
:target: images/api_layers_3_0.png
|
||||
|
||||
OpenSubdiv (Osd)
|
||||
================
|
||||
|
||||
**Osd** contains client-level code that uses *Far* to create concrete instances of
|
||||
meshes. These meshes use precomputed tables from *Hbr* to perform table-driven
|
||||
meshes. These meshes use precomputed tables from *Far* to perform table-driven
|
||||
subdivision steps with a variety of massively parallel computational backend
|
||||
technologies. **Osd** supports both `uniform subdivision <subdivision_surfaces.html#uniform-subdivision>`__
|
||||
and `adaptive refinement <subdivision_surfaces.html#feature-adaptive-subdivision>`__
|
||||
@ -66,8 +70,8 @@ modules : **Compute**, **Draw** and **Eval**.
|
||||
The modules are designed so that the data being manipulated can be shared and
|
||||
interoperated between modules (although not all paths are possible).
|
||||
|
||||
These modules are identified by their name spaces (**OsdRefine**, **OsdDraw**,
|
||||
**OsdEval**) and encapsulate atomic functationality. The vertex data is carried
|
||||
These modules are identified by their name spaces (**Compute**, **Draw**,
|
||||
**Eval**) and encapsulate atomic functationality. The vertex data is carried
|
||||
in interoperable buffers that can be exchanged between modules.
|
||||
|
||||
The typical use pattern is to pose the coarse vertices of a mesh for a given frame.
|
||||
@ -131,18 +135,17 @@ illustrates the matrix of back-end APIs supported for each module.
|
||||
.. image:: images/osd_backends.png
|
||||
:align: center
|
||||
|
||||
Since the **Compute** module performs mostly specialized interpolation computations,
|
||||
most GP-GPU and multi-core APIs can be deployed. If the end-goal is to draw the
|
||||
surface on screen, it can be very beneficial to move as much of these computations
|
||||
to the same GPU device in order to minimize data transfers.
|
||||
Since the **Compute** module performs mostly specialized interpolation
|
||||
computations, most GP-GPU and multi-core APIs can be deployed. If the end-goal
|
||||
is to draw the surface on screen, it can be very beneficial to move as much of
|
||||
these computations to the same GPU device in order to minimize data transfers.
|
||||
|
||||
For instance: pairing a CUDA **Compute** back-end to an OpenGL **Draw** backend
|
||||
could be a good choice on hardware and OS that supports both. Similarly, a
|
||||
DX11 HLSL-Compute **Compute** back-end can be paired effectively with a DX11
|
||||
HLSL-Shading **Draw** back-end. Some pairings however are not possible, as there
|
||||
may be no data inter-operation paths available (ex: transferring DX11 compute SRVs
|
||||
to GL texture buffers).
|
||||
|
||||
could be a good choice on hardware and OS that supports both. Similarly, a DX11
|
||||
HLSL-Compute **Compute** back-end can be paired effectively with a DX11
|
||||
HLSL-Shading **Draw** back-end. Some pairings however are not possible, as
|
||||
there may be no data inter-operation paths available (ex: transferring DX11
|
||||
compute SRVs to GL texture buffers).
|
||||
----
|
||||
|
||||
Contexts & Controllers
|
||||
@ -193,11 +196,11 @@ CUDA **Compute** module and an OpenGL **Draw** module.
|
||||
.. image:: images/osd_controllers_example1.png
|
||||
:align: center
|
||||
|
||||
The client code will construct an OsdCudaComputeController and OsdCudaComputeContext
|
||||
for the **Compute** stage, along with an OsdGLDrawController and an OsdGLDrawContext.
|
||||
|
||||
The critical components are the vertex buffers, which must be of type OsdCudaGLVertexBuffer.
|
||||
The Contexts and Controllers classes all are specializations of a templated *"Bind"*
|
||||
function which will leverage API specific code responsible for the inter-operation
|
||||
of the data between the API-specific back-ends.
|
||||
The client code will construct a CudaComputeController and CudaComputeContext
|
||||
for the **Compute** stage, along with an GLDrawController and a GLDrawContext.
|
||||
|
||||
The critical components are the vertex buffers, which must be of type
|
||||
CudaGLVertexBuffer. The Contexts and Controllers classes all are
|
||||
specializations of a templated *"Bind"* function which will leverage API
|
||||
specific code responsible for the inter-operation of the data between the
|
||||
API-specific back-ends.
|
||||
|
@ -31,554 +31,253 @@ Release Notes
|
||||
|
||||
----
|
||||
|
||||
Release 2.6.0
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- Add subdivision kernels for ARM NEON
|
||||
- Add OsdUtilVertexSplit which creates a vertex-varying data table by duplicating
|
||||
vertices in a `FarMesh`
|
||||
- Add basic functions to work with FV data via evaluator API
|
||||
|
||||
**Changes**
|
||||
- Added Catmark restricted vertex compute kernels that optimize for vertices
|
||||
with no semi-sharp creases
|
||||
- Fix accessor omissions in osd/mesh.h
|
||||
- Add support for different subdivision schemes for OsdUtilMesh
|
||||
|
||||
**Bug Fixes**
|
||||
- Fix crashes when using rather low-end cards like Intel ones
|
||||
- Fix a bug in the creation of an edge-vertex kernel batch
|
||||
- Fix mismatch in declaration and usage of OsdCudaComputeRestrictedVertexA
|
||||
- Fix a bug in the vertex order for restricted Catmark vertex-vertex kernel batches
|
||||
- Fix a bug in FarCatmarkSubdivisionTablesFactory that prevented the
|
||||
CATMARK_QUAD_FACE_VERTEX kernel from being selected for subdivision
|
||||
level 2 or greater.
|
||||
- Fix a bug in OsdUtilVertexSplit that occurs when getting the address of
|
||||
the end of a std::vector
|
||||
- Fix error in createCLBuffer that occurs when the buffer size is zero
|
||||
- Fix a bug in the CUDA computeRestrictedEdge kernel
|
||||
- Fix duplicate variables with identical name
|
||||
- Fix osdutil build errors
|
||||
- Fix cmake diagnostic messsage
|
||||
|
||||
Release 2.5.1
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- Add CATMARK_QUAD_FACE_VERTEX and CATMARK_TRI_QUAD_FACE_VERTEX compute kernels
|
||||
optimization that takes advantage of all-quads or all-triange-and-quads meshes
|
||||
|
||||
**Bug Fixes**
|
||||
- Fix a compiler error in the GLSL Transform Feedback kernels on OS X
|
||||
- Fix boundary interpolation in osdutil
|
||||
- Fix bilinear stencil tangent computions
|
||||
|
||||
Release 2.5.0
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- Add ability to generate triangle patches for a uniformly subdivided mesh
|
||||
- Add new example 'topologySharing'
|
||||
- Add interleaved buffer mode in glViewer
|
||||
- Add GLSL compute kernel to glBatchViewer
|
||||
- Add TBB compute kernel to glBatchViewer
|
||||
- Add a PullDown widget to our HUD in examples/common
|
||||
- GUI updates & cosmetic changes to GL example code
|
||||
- Adding a programmable image shader to gl_hud
|
||||
- Code cleanup for GLFrameBuffer in examples/common
|
||||
- Implement C-API accessor to evaluator topology (osdutil)
|
||||
- Add command line option to CMake's options
|
||||
- Add a CMake option to disable OpenCL
|
||||
- Add a FindCLEW.cmake module in anticipation of using CLEW as a dependency
|
||||
- Integrate CLEW into osd library and examples
|
||||
|
||||
**Changes**
|
||||
- Change interleaved buffer support in OsdCompute:
|
||||
- Removed OsdVertexDescriptor and replaced with OsdVertexBufferDescriptor
|
||||
- Reorganize ComputeContext and ComputeController.
|
||||
- Reorganize EvalStencilContext and EvalStencilController
|
||||
Moved transient states (current vertex buffer etc) to controller
|
||||
- Reorganize EvalLimitContext and EvalLimitController
|
||||
Moved transient states (current vertex buffer etc) to controller
|
||||
- Fix adaptive isolation of sharp corner vertices
|
||||
- Fix incorrect FarMeshFactory logic for isolating multiple corner vertices in corner patches
|
||||
- Change EvalLimit Gregory patch kernels to the large weights table to accomodate higher valences
|
||||
- Fix calculation of screen space LOD tess factors for transition corner patches.
|
||||
- Add a public constructor to OsdMesh
|
||||
- Decrease compiler warning thresholds and fix outstanding warnings
|
||||
- Make PTex support optional
|
||||
- Add a NO_MAYA flag to CMakeLists to disable all Autodesk Maya dependencies in the build
|
||||
- Document NO_MAYA command line option
|
||||
|
||||
**Bug Fixes**
|
||||
- Fix mistakenly deleted memory barrier in glsl OsdCompute kernel.
|
||||
- Fix shape_utils genRIB function to use streams correctly.
|
||||
- Temporary workaround for the synchronization bug of glsl compute kernel
|
||||
- Fix Hud display for higher DPI (MBP retina)
|
||||
- Fix Hud (d3d11)
|
||||
- Fix examples to use GL timer query to measure the GPU draw timing more precisely
|
||||
- Fix glViewer: stop updating during freeze.
|
||||
- Fix file permissions on farPatchTablesFactory.h
|
||||
- Fix some meory leaks in adaptive evaluator (osdutil)
|
||||
- Fix OsdUtilAdaptiveEvaluator concurrency issue
|
||||
- Fix OsdUtilRefiner incorrect "Invalid size of patch array" error reporting.
|
||||
- Fix OsdUtilPatchPartitioner failure for triangle patches
|
||||
- Fixes a bug that causes OsdUtilPatchPartitioner to fail to rebuild the face-varying
|
||||
data table correctly for triangle patches.
|
||||
- Add missing third parameter to templated OsdDrawContext usage (osdutil/batch.h)
|
||||
- Return success status from openSubdiv_finishEvaluatorDescr() (osdutil)
|
||||
- Remove debugging std::cout calls (osdutil)
|
||||
- Build errors & warnings:
|
||||
- Fix OSX Core Profile build (GLFrameBuffer)
|
||||
- Fix ptexViewer build error on OSX
|
||||
- Fix framebuffer shader compiling for OSX
|
||||
- Reordering includes to address a compile error on OSX/glew environment
|
||||
- Fix compilation errors with CLEW enabled
|
||||
- Fix icc build problems
|
||||
- Fix compiler warnings in OsdClVertexBuffer
|
||||
- Fix compilation error on windows+msvc2013
|
||||
- Fix build warnings/errors with VS2010 Pro
|
||||
- Fix Windows build warning in FarPatchTablesFactory
|
||||
- Fix doxygen generation errors
|
||||
|
||||
|
||||
Release 2.4.1
|
||||
=============
|
||||
|
||||
**Changes**
|
||||
- Add correct OpenSubdiv namespace begin/end blocks.
|
||||
|
||||
**Bug Fixes**
|
||||
- Compile osdutil with -fPIC for correct linking.
|
||||
- Fix a bug of OsdUtilMeshBatch, the varying buffer isn't computed with CL kernels
|
||||
- Fix FindGLFW.cmake to use the %GLFW_LOCATION% environment variable in Windows
|
||||
- Fix Draw contexts do not fully initialize patch arrays
|
||||
|
||||
Release 2.4.0
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- Adding functionality to store uniform face-varying data across multiple levels of subdivision
|
||||
- Add OsdUtilPatchPartitioner.
|
||||
It splits patcharray into subsets so that clients can draw partial surfaces
|
||||
for both adaptive and uniform.
|
||||
|
||||
**Changes**
|
||||
- Remove FarMesh dependency from Osd*Context.
|
||||
- Use DSA APIs for GL buffer update (if available).
|
||||
- Refactor Far API
|
||||
- replace void- of all kernel applications with CONTEXT template parameter.
|
||||
It eliminates many static_casts from void- for both far and osd classes.
|
||||
- move the big switch-cases of far default kernel launches out of Refine so
|
||||
that osd controllers can arbitrary mix default kernels and custom kernels.
|
||||
- change FarKernelBatch::kernelType from enum to int, clients can add
|
||||
custom kernel types.
|
||||
- remove a back-pointer to farmesh from subdivision table.
|
||||
- untemplate all subdivision table classes and template their compute methods
|
||||
instead. Those methods take a typed vertex storage.
|
||||
- remove an unused argument FarMesh from the constructor of subdivision
|
||||
table factories.
|
||||
- Refactor FarSubdivisionTables.
|
||||
Delete scheme specialized subdivision tables. The base class FarSubdivisionTables
|
||||
already has all tables, so we just need scheme enum to identify which scheme
|
||||
the subdivision tables belong to. This brings a lot of code cleanups around far
|
||||
factory classes.
|
||||
- Move FarMultiMeshFactory to OsdUtil.
|
||||
- Move table splicing functions of FarMultiMeshFactory into factories
|
||||
- Change PxOsdUtil prefix to final OsdUtil prefix.
|
||||
- Improve error reporting in osdutil refinement classes, and fix a build issue
|
||||
|
||||
**Bug Fixes**
|
||||
- Fix another multi mesh splicing bug of face varying data.
|
||||
- Make CMake path variables more robust
|
||||
- Fixing a crash on Marvericks w/glew
|
||||
- Update dxViewer example documentation
|
||||
- Fix wrong logic in openSubdiv_setEvaluatorCoarsePositions
|
||||
- Remove debug print from adaptive evaluator's initialization
|
||||
|
||||
Release 2.3.5
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- Add the ability to read obj files to the dxViewer example
|
||||
- Add screen-capture function to ptexViewer
|
||||
- Update documention for Xcode builds
|
||||
- Add documentation (boundary interpolation rules and face-varying boundary interpolation rules)
|
||||
|
||||
**Changes**
|
||||
- Refactoring FarPatchTables and FarPatchTablesFactory
|
||||
- Move GL vertex buffer VBO buffer allocation out of allocate() and into BindVBO()
|
||||
- Enable uvViewer on OS X now that Mavericks is released.
|
||||
- Replacing un-necessary dynamic_cast with reinterpret_cast within FarDispatcher
|
||||
- Minor code cleanup of FarMeshFactory
|
||||
- Remove address space qualifiers from OpenCL kernel functions
|
||||
- Fix OpenCL initialization to be slightly more robust
|
||||
- Add OpenCL header include paths where necessary
|
||||
- Add 'static' specifiers for non-kernel CL funcs at program scope
|
||||
- Add stddef.h to python/osd/osdshim.i
|
||||
- Modify ptexViewer and uvViewer shaders to address some portability issues
|
||||
|
||||
**Bug Fixes**
|
||||
- Fix Gregory Boundary patch buffer overrun
|
||||
- Fix black texels when the resolution of a ptex face is less than 4
|
||||
- Fix a splicing bug in FarMultiMeshFactory
|
||||
- Fix a build error when using older versions of GLFW
|
||||
- Fix build warnings (optimized)
|
||||
- Fix FindTBB.cmake
|
||||
- Fix FindMaya.cmake
|
||||
- Fix glViewer support for GLSL compute
|
||||
- Fix ptexViewer: enable specular pass in both IBL and point lighting
|
||||
- Fix Zlib include in ptexViewer
|
||||
- Fix ptexViewer shader errors.
|
||||
- Fix osdPolySmooth Maya plugin
|
||||
- Fix UV merging in osdPolySmooth code example
|
||||
- Add cleanup function to osdPolySmooth Maya plugin
|
||||
- Fix Maya OsdPolySmooth node component output
|
||||
- Fix GLSL array instantiation syntax for glStencilViewer
|
||||
- Fix examples to run correctly on high DPI displays with GLFW 3
|
||||
|
||||
Release 2.3.4
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- Adding CPU/OMP/TBB Context / Controller pairs for CPU evaluation of smooth normals
|
||||
- Added adaptiveEvaluator class inspired by Sergey's work in blender (OsdUtil)
|
||||
|
||||
**Changes**
|
||||
- Changed the HUD to ignore mouse clicks when not visible.
|
||||
- Updates for blender development (OsdUtil)
|
||||
- Add C compatible API to access the adaptiveEvaluator class from non-C++ (OsdUtil)
|
||||
- Update license headers to apache (OsdUtil)
|
||||
- CMake build improvement : make osd a cmake object library & remove compiling redundancies
|
||||
- Improve stringification of shaders & kernels in CMake build
|
||||
|
||||
**Bug Fixes**
|
||||
- Fixed iOS build
|
||||
- Fixed VS2010 warnings/errors.
|
||||
- Fix OsdCpuEvalLimitKernel
|
||||
- Fix maxvalence calculation in FarMeshFactory
|
||||
- Fix FarStencilFactory control stencil caching
|
||||
- Removing assert for high-valence vertices running off limit tangent pre-computed table.
|
||||
- Fix degenerate stencil limit tangent code path.
|
||||
- Fix unused variable build warnings (gcc 4.8.2 - Fedora 19)
|
||||
- Fix build warning from osdutil/adaptiveEvaluator.cpp
|
||||
|
||||
Release 2.3.3
|
||||
=============
|
||||
|
||||
**Changes**
|
||||
- Modify Far remapping of singular vertices to point to their source vertex.
|
||||
- Refactoring Ptex Mipmap and Analytic Displacement code
|
||||
- Adding some documentation for Chaikin crease rule
|
||||
- Misc. improvements to PxOsdUtilsMesh
|
||||
- Adding recommended isolation output to OsdPolySmooth node
|
||||
|
||||
**Bug Fixes**
|
||||
- Adding an error check on version parsing of main CMakeLists
|
||||
- Fix regex in FindMaya.cmake that breaks with recent versions of Maya
|
||||
- Fix crashes induced by typeid
|
||||
- Fixed VS2010 build warning
|
||||
- Fix build break in hbr_regression
|
||||
- Fix incorrect capitalization in GL ptexViewer shader.glsl
|
||||
- Fix OSX build: add stdlib.h include
|
||||
|
||||
Release 2.3.2
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- Adding control cage drawing to ptexViewer
|
||||
- Adding Maya osdPolySmooth plugin into OpenSubdiv examples.
|
||||
|
||||
**Changes**
|
||||
- Removing some glGetError checks that are causing problems for Autodesk
|
||||
- D3D11DrawRegistry returns the common shader config for all non-tess patcharrays.
|
||||
- Updates to simple cpu osdutil classes
|
||||
|
||||
**Bug Fixes**
|
||||
- Fix Hbr Chaikin crease rule
|
||||
- Fix Chaikin tag parsing
|
||||
- Fix return value of allocate function for OsdCPUGLVertxBuffer
|
||||
- Fixed GLSL shader portability.
|
||||
- Fix FindGLFW.cmake for GLFW 3.03 on OSX
|
||||
- Fixed compiler warnings.
|
||||
- Fixed VS2010 build errors
|
||||
- Fixed WIN32 build error when no DXSDK installed.
|
||||
- Fix OSX build: stdlib.h needs to be included in glPtexMipmapTexture.h
|
||||
- Fix for crash in new mesh/refiner code in OsdUtil
|
||||
|
||||
|
||||
Release 2.3.1
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- Add DX11 version of ptex mipmap loader
|
||||
- Add DX11 ptex viewer (work in progress)
|
||||
- Add DX11 fractional partitioning, normal derivatives computation
|
||||
- Add memory usage controls to Ptex loader
|
||||
- Add face-varying boundary interpolation parsing to shape_utils
|
||||
- Add simple HbrMesh and FarMesh wrapper classes to osdutil
|
||||
|
||||
**Changes**
|
||||
- Amend language of attribution file 'NOTICE.txt'
|
||||
- Optimize a bit of ptex mipmap lookup.
|
||||
- Show ptex memory usage in GL and DX11 ptexViewers
|
||||
- Improve ptex guttering
|
||||
- Addding some video links to our collection of external resources
|
||||
|
||||
**Bug Fixes**
|
||||
- Fix edge-only face-varying interpolation
|
||||
- Fix Far to handle disconnected vertices in an Hbr mesh
|
||||
- Fixed ptex cache resource release sequence
|
||||
- Fix build symbol conflict in Far
|
||||
- Fix patch parambuffer generation in OsdD3D11DrawContext
|
||||
- Fix a minor osdutil build warning (seen with gcc 4.8.1)
|
||||
- Fix VS2010 build errors
|
||||
|
||||
Release 2.3.0
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- Added Analytical displacement mapping ('Analytic Displacement Mapping using
|
||||
Hardware Tessellation; Niessner and Loop [TOG 2013])
|
||||
- Added a new ptex mipmap loader
|
||||
- Added face varying macros for loop subdivision
|
||||
- Added the uvViewer example to see how face varying interpolation rule works
|
||||
- Added a slider component and cleanup hud code.
|
||||
|
||||
**Changes**
|
||||
- Adding license & attribution files, improved language of the code headers
|
||||
- Install documentation into the Filesystem Hierarchy Standard location
|
||||
- Set GLFW_OPENGL_FORWARD_COMPAT on Mac OS to make samples work on that platform
|
||||
- Added surface normal mode & mipmap to ptxViewer
|
||||
|
||||
**Bug Fixes**
|
||||
- Fix a bug of bad fvar splicing for loop surface.
|
||||
- Fix incorrect bilinear limit tangents in FarStencilTablesFactory
|
||||
- Fix boundary interpolation rules doc
|
||||
- Added an error check on updating cuda buffer
|
||||
- Fix face varying rendering on loop surface
|
||||
- Fixed glBatchViewer build for GLFW 2.x
|
||||
- Expand search paths for FindGLFW.cmake for Debian and other Linux architectures
|
||||
- Fix CMake executable builds for ICC
|
||||
- Fix bhr baseline regression, so reference files are real OBJ's
|
||||
- Fixed clKernelBundle.cpp to build on Android.
|
||||
- Fix misc build warings
|
||||
|
||||
Release 2.2.0
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- Added subdivision stencil functionality (Far & OsdEval)
|
||||
|
||||
**Bug Fixes**
|
||||
- Fix D3D11DrawContext to check for NULL pointers
|
||||
- Fix cpuEvalLimitController crash bug
|
||||
- Fixed search path suffixes for ICC libs
|
||||
- Fixed invalid initialization of glslTransformFeedback kernel.
|
||||
|
||||
Release 2.1.0
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- Added TBB Compute back-end on Linux (contribution from Sheng Fu)
|
||||
- Added support for ICC compiler (still Beta)
|
||||
|
||||
**Changes**
|
||||
- Added constructor to OsdMesh with a FarMesh * as input
|
||||
- Modify CMake to name and sym-link DSO's based on Linux ABI versioning spec
|
||||
- Added command line input to DX11 viewer
|
||||
- FarMultiMesh can splice uniform and adaptive meshes together.
|
||||
|
||||
**Bug Fixes**
|
||||
- Fix FarMultiMesh splicing
|
||||
- Removed unnecessary cudaThreadSynchronize calls.
|
||||
- Fix glViewer overlapping HUD menus
|
||||
- Fix facevarying rendering in glBatchViewer
|
||||
- Fix build of GLSL transform feedback kernels
|
||||
- Fix 'Getting Started' documentation
|
||||
|
||||
|
||||
Release 2.0.1
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- New CLA files to reflect Apache 2.0 licensing
|
||||
|
||||
**Changes**
|
||||
- Move all public headers to include/opensubdiv/...
|
||||
- Adding Osd documentation based on Siggraph slides
|
||||
|
||||
**Bug Fixes**
|
||||
- Fix incorrect transition pattern 3 in GLSL / HLSL shaders
|
||||
- Fix CMake build to not link GPU-based libraries into libosdCPU
|
||||
- Fix support for GLEW on OSX
|
||||
- Fix GLFW Xrandr & xf86vmode dependency paths for X11 based systems
|
||||
- Fix HUD display overlaps in code examples
|
||||
- Fix FindGLEW.cmake to be aware of multiarch on linux systems
|
||||
- Fix some hard-coded include paths in CMake build
|
||||
|
||||
|
||||
Release 2.0.0
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- New CMake build flags: NO_LIB, NO_CUDA, NO_PYTHON)
|
||||
|
||||
**Changes**
|
||||
- OpenSubdiv is now under Apache 2.0 license
|
||||
- HbrHalfedge and HbrFVarData copy constructors are now private
|
||||
- Documentation style matched to graphics.pixar.com + new content
|
||||
- Add an animation freeze button to ptexViewer
|
||||
- Variable name changes for better readability across all example
|
||||
shader code
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Fix incorrect patch generation for patches with 2 non-consecutive boundary edges
|
||||
- Fix "undefined gl_PrimitiveID" shader build errors
|
||||
- Fix for shader macro "OSD_DISPLACEMENT_CALLBACK"
|
||||
- Fix out-of-bounds std::vector access in FarPatchTablesFactory
|
||||
|
||||
----
|
||||
|
||||
Release 1.2.4
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
|
||||
- Adding support for fractional tessellation of patches
|
||||
- Adding a much needed API documention system based on Docutils RST markup
|
||||
- Adding support for face-varying interpolation in GLSL APIs
|
||||
- Adding varying data buffers to OsdMesh
|
||||
- Adding accessors to the vertex buffers in OsdGlMesh
|
||||
- Adding face-varying data to regression shapes
|
||||
|
||||
**Changes**
|
||||
|
||||
- Cleanup of common bicubic patch shader code (GLSL / HLSL) for portability
|
||||
(ATI / OSX drivers)
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Fix FarVertexEditTablesFactory to insert properly vertex edit batches
|
||||
(fixes incorrect hierarchical hole in regression shape)
|
||||
- Fix FarPatchMap quadtree to not drop top-level non-quad faces
|
||||
- Fix Gregory patches bug with incorrect max-valence
|
||||
- Fix FarPatchTables::GetNumFaces() and FarPatchTables::GetFaceVertices()
|
||||
functions to return the correct values
|
||||
- Fix face indexing GLSL code (ptex works on non-quads again)
|
||||
- Fix face-varying data splicing in FarMultiMeshFactory
|
||||
- Fix ptex face indexing in FarMultiMeshFactory
|
||||
- Fix glew #include to not break builds
|
||||
- Fix Clang / ICC build failures with FarPatchTables
|
||||
- Fix build and example code to work with GFLW 3.0+
|
||||
- Fix cmake to have ptex dynamically linked in OSX
|
||||
|
||||
----
|
||||
|
||||
Release 1.2.3
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
|
||||
- Adding Varying and Face-Varying data interpolation to EvalLimit
|
||||
|
||||
**Changes**
|
||||
|
||||
- EvalLimit API refactor : the EvalContext now has dedicated structs to track all
|
||||
the vertex, varying and face-varying data streams. Also renamed some "buffers"
|
||||
into "tables" to maintain code consistency
|
||||
- EvalLimit optimization : switch serial indexing to a quad-tree based search
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Face-varying data bug fixes : making sure the data is carried around appropriately
|
||||
Fixes for OpenCL use with the new batching APIs
|
||||
- GLSL general shader code cleanup & fixes for better portability
|
||||
- GLSL Tranform Feedback initialization fix
|
||||
- Critical fix for FarMultiMesh batching (indexing was incorrect)
|
||||
- Fix osdutil CL implementation (protect #includes on systems with no OpenCL SDK
|
||||
installed)
|
||||
- Fix face-varying interpolation on adaptive patches
|
||||
- FarPatchTables : fix IsFeatureAdaptive() to return the correct answer
|
||||
- Fix Far factories to handle the absence of face-varying data correctly.
|
||||
- Many GLSL shader code style fixes which should help with ATI / OSX shader compiling
|
||||
|
||||
----
|
||||
|
||||
Release 1.2.2
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
|
||||
- Introducing the EvalLimit API : the Eval module aims at providing support for
|
||||
computational tasks that are not related to drawing the surfaces. The EvalLimit
|
||||
sub-module provides an API that enables client code to evaluate primitive variables
|
||||
on the limit surface.
|
||||
|
||||
.. image:: images/evalLimit_hedit0.jpg
|
||||
:height: 300px
|
||||
:align: center
|
||||
:target: images/evalLimit_hedit0.jpg
|
||||
|
||||
- Osd<xxx>ComputeController : minor optimization. Added early exit to Refine method
|
||||
to avoid unnecessary interop.
|
||||
|
||||
**Changes**
|
||||
|
||||
- OsdGLDawContext : minor API change. Protecting some member variables and adding
|
||||
const accessors
|
||||
- OsdError : minor API refactor, added Warning functions.
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Fix Ptex bug : prevent corner texel guttering code to from going into infinite
|
||||
loops
|
||||
- Adding the ability for a FarMeshFactory to construct patchTables starting from
|
||||
'firstLevel' in uniform subdivision mode
|
||||
- Consolidating the color coding of bicubic patch types through all our our code
|
||||
examples (this is used mostly as a debugging tool)
|
||||
- Fixing some MSVC++ build warnings
|
||||
- Update to the outdated README.md
|
||||
|
||||
----
|
||||
|
||||
Release 1.2.1
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
|
||||
- Added CUDA runtime error checking
|
||||
|
||||
----
|
||||
|
||||
Release 1.2.0
|
||||
=============
|
||||
|
||||
**Changes**
|
||||
|
||||
- Major Far refactor around patchTables to introduce the draw batching API
|
||||
- Renaming osd_util to osdutil
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Fix GLSL transform feedback initialization bug in ptexViewer
|
||||
- Minor bug & typo fixes
|
||||
|
||||
----
|
||||
|
||||
Release 1.1.0
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
|
||||
- release initiated because of the switch to Git Flow
|
||||
|
||||
----
|
||||
|
||||
Release 1.0.0
|
||||
=============
|
||||
|
||||
Oringal release:
|
||||
|
||||
General 3.x RoadMap
|
||||
===================
|
||||
|
||||
Within the 3.x release cycle we would like to address first and foremost many of
|
||||
the issues related to scaling the application of subdivision surfaces to large
|
||||
amounts of primitives within typical graphics pipelines.
|
||||
|
||||
Enabling workflows at larger scales will require improvements on several fronts:
|
||||
|
||||
* Handle more primitives, but with fewer overheads:
|
||||
|
||||
* Reduce Compute kernel launches using stencils instead of subdivision tables
|
||||
* Reduce Draw calls by addressing the combinatorial explosion of tessellation
|
||||
shaders
|
||||
* Provide back-ends for next-gen APIs (D3D12, Mantle, Metal, GL 5.x)
|
||||
|
||||
* More semi-sharp creases: feature isolation needs to become much more efficient to
|
||||
allow for complete creative freedom in using the feature.
|
||||
* Faster topology analysis
|
||||
|
||||
|
||||
Release 3.0
|
||||
===========
|
||||
|
||||
OpenSubdiv 3.0 represents a landmark release with very profound changes to the
|
||||
core algorithms. While providing faster, more efficient, and more flexible
|
||||
subdivision code remains our principal goal, OpenSubdiv 3.0 introduces many
|
||||
improvements that constitute a fairly radical departures from our previous
|
||||
code releases.
|
||||
|
||||
Improved performance
|
||||
********************
|
||||
|
||||
OpenSubdiv 3.0 introduces new data structures and algorithms that greatly
|
||||
enhance performance over previous versions. The 3.0 release focuses mostly on
|
||||
the CPU side, and should provide "out-of-the-box" speed-ups close to an order
|
||||
of magnitude for topology refinement and analysis (both uniform and adaptive).
|
||||
|
||||
On the GPU side, the replacement of subdivision tables with stencils allows
|
||||
us to remove several bottlenecks in the Compute area that can yield as much as
|
||||
4x faster interpolation on CUDA platforms. At the same time, stencils also
|
||||
reduce the dozens of kernel launches required per primitive to a single one (this
|
||||
was a known issue on certain mobile platforms). Compute calls batching is now
|
||||
trivial.
|
||||
|
||||
New topology entry-points
|
||||
*************************
|
||||
|
||||
OpenSubdiv 3.0 introduces several new entry-points for client topology. Previous
|
||||
releases force client applications to define and populate instances of an Hbr
|
||||
half-edge topology representation. For many applications, this representation is
|
||||
both redundant and inefficient.
|
||||
|
||||
OpenSubdiv 3.0 introduces a new *intermediate* topological representation, named
|
||||
**Vtr** (Vectorized Topology Representation). The topological relationships held
|
||||
by Vtr can populated using either a high-level interface where simplicity has
|
||||
been emphasized, or a lower-level interface for enhanced efficiency (still under
|
||||
construction). Vtr is much more efficient for the kinds of topological analysis
|
||||
required by Far and additionally is more flexible in that it supports the
|
||||
specification of non-manifold topology.
|
||||
|
||||
As a result, Hbr is no longer a core API of OpenSubdiv. While the code is marked
|
||||
as deprecated, it will remain in the source distribution for legacy and
|
||||
regression purposes.
|
||||
|
||||
The documentation for Vtr can be found `here <vtr_overview.html>`__
|
||||
|
||||
New treatment of face-varying data
|
||||
**********************************
|
||||
|
||||
With Hbr no longer the entry point for clients, OpenSubdiv 3.0 provides a new
|
||||
interface to face-varying data. Previous versions required FVar data to be
|
||||
assigned by value to the vertex for each face, and whether or not the set of
|
||||
values around a vertex was continuous was determined by comparing these values
|
||||
later. In some cases this could result in two values that were not meant to be
|
||||
shared being "welded" together.
|
||||
|
||||
Face-varying data is now specified topologically. Just as the vertex topology
|
||||
is defined from a set of vertices and integer references to these vertices for
|
||||
the vertex of each face, face-varying topology is defined from a set of values
|
||||
and integer references to these values for the vertex of each face. So if
|
||||
values are to be considered distinct around a vertex, they are given distinct
|
||||
indices and no comparison of values is ever performed.
|
||||
|
||||
This ensures that OpenSubdiv's face-varying topology matches what is specified
|
||||
in common geometry container formats like Obj or Alembic. It also allows for
|
||||
more efficient processing of face-varying values during refinement, and so the
|
||||
cost of interpolating a set of face-varying data should now be little more than
|
||||
the cost of interpolating a similar set of vertex data (depending on the number
|
||||
of distinct face-varying values versus the number of vertices).
|
||||
|
||||
Subdivision Core (Sdc)
|
||||
**********************
|
||||
|
||||
In consideration of the existing representations (Hbr and Vtr), all low-level
|
||||
details fundamental to subdivision and the specific subdivision schemes has been
|
||||
factored into a new low-level layer (the lowest) called Sdc. This layer
|
||||
encapsulates the full set of applicable options, the formulae required to
|
||||
support semi-sharp creasing, the formulae for the refinement masks of each
|
||||
subdivision scheme, etc.
|
||||
|
||||
Sdc provides the low-level nuts and bolts to provide a subdivision
|
||||
implementation consistent with OpenSubdiv. It is used internally by Vtr but
|
||||
can also provide clients with an existing implementation of their own with the
|
||||
details to make that implementation consistent with OpenSubdiv.
|
||||
|
||||
The documentation for Sdc can be found `here <sdc_overview.html>`__
|
||||
|
||||
Changes to the Subdivision Specification
|
||||
****************************************
|
||||
|
||||
The refactoring of OpenSubdiv 3.0 data representations presents a unique
|
||||
opportunity to revisit some corners of the subdivision specification and
|
||||
remove or update some legacy features.
|
||||
|
||||
Interpolation Rules
|
||||
+++++++++++++++++++
|
||||
|
||||
Since the various options are now presented through a new API (Sdc rather than
|
||||
Hbr), based on the history of some of these options and input from interested
|
||||
parties, the following changes are being investigated:
|
||||
|
||||
* the creasing method 'Normal' has been renamed 'Uniform'
|
||||
* considering renaming the Sdc 'boundary interpolation' enum and its choices
|
||||
* same as above for the 'face varying boundary interpolation' enum in Sdc
|
||||
|
||||
In these cases, features are not being removed but simply re-expressed in what
|
||||
is hoped to be a clearer interface.
|
||||
|
||||
Hierarchical Edits
|
||||
++++++++++++++++++
|
||||
|
||||
Currently Hierarchical Edits have been marked as "extended specification" and
|
||||
support for hierarchical features has been removed from the 3.0 release. This
|
||||
decision allows for great simplifications of many areas of the subdivision
|
||||
algorithms. If we can identify legitimate use cases for hierarchical tags, we
|
||||
will consider re-implementing them in future releases, as time and resources
|
||||
allow.
|
||||
|
||||
Introducing Stencil Tables
|
||||
**************************
|
||||
|
||||
OpenSubdiv 3.0 replaces the serialized subdivision tables with factorized stencil
|
||||
tables. Subdivision tables as implemented in 2.x releases still contain a fairly
|
||||
large amount of data inter-dependencies which incur penalties for using more
|
||||
fences or kernel launches. Most of these dependencies have now been factorized
|
||||
away in the pre-computation stage, yielding *stencil tables* instead.
|
||||
|
||||
Stencils remove all data dependencies and simplify all the computations into a
|
||||
single trivial kernel. This simplification results in a faster pre-computation
|
||||
stage, faster execution on GPU, and fewer driver overheads. The new stencil
|
||||
tables Compute back-end is supported on all the same platforms as previous
|
||||
releases.
|
||||
|
||||
New Source-Code Style
|
||||
*********************
|
||||
|
||||
OpenSubdiv 3.0 replaces naming prefixes with C++ namespaces for all API layers,
|
||||
bringing the source style more in line with contemporary and specifications
|
||||
(mostly inspired from the `Google C++ Style Guide
|
||||
<http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml>`__).
|
||||
|
||||
The large-scale changes introduced in this release generally breaks
|
||||
compatibility with existing client-code. This gives us the opportunity to
|
||||
effect some much needed updates to our code-style guidelines and general
|
||||
conventions, throughout the entire OpenSubdiv code-base. We are hoping to
|
||||
drastically improve the quality, consistency and readability of the source
|
||||
code.
|
||||
|
||||
Alpha Release Notes
|
||||
===================
|
||||
|
||||
Our intentions as open-source developers is to give as much access to our code,
|
||||
as early as possible, because we value and welcome the feedback from the
|
||||
community.
|
||||
|
||||
The 'alpha' release moniker means to us that our code is still far from being
|
||||
finalized. Although we are now close from being feature complete, our
|
||||
public-facing interfaces are still subject to change. Therefore, we do not
|
||||
recommend this version of OpenSubdiv be used in client applications until both
|
||||
features and interfaces have been finalized in an official 'Beta' Release.
|
||||
|
||||
.. container:: notebox
|
||||
|
||||
**Alpha Issues**
|
||||
|
||||
The following is a short list of features and issues that are still in
|
||||
development or are likely to change during the alpha cycle:
|
||||
|
||||
#. Support for Loop and Bilinear schemes (consistent with 2.x):
|
||||
Currently only the Catmull-Clark subdivision scheme is supported.
|
||||
Parity of support with 2.x versions for the Loop and Bilinear schemes
|
||||
will be re-established before Beta release.
|
||||
|
||||
#. Refactor Far::TopologyRefiner interpolation functions:
|
||||
Templated interpolation methods such as Interpolate<T>(),
|
||||
InterpolateFaceVarying<T>(), Limit<T>() are not finalized yet. Both
|
||||
the methods prototypes as well the interface required for T are
|
||||
likely to change before Beta release.
|
||||
|
||||
#. Face-varying interpolation rules:
|
||||
Currently, all 4 legacy modes of face-varying interpolation are
|
||||
supported for *interior* vertices, but not for *boundary* vertices.
|
||||
Work is currently underway to match and extend Hbr's boundary
|
||||
interpolation rules as implemented in 2.x. The new code will need
|
||||
to be tested and validated.
|
||||
|
||||
#. Limit Masks:
|
||||
Currently, Sdc generates weighted masks to interpolate *vertex* and
|
||||
*face-varying* primvar data between subdivision levels. We want to
|
||||
add functionality to evaluate closed-form evaluation of weight masks
|
||||
to interpolate primvar data at the limit.
|
||||
|
||||
#. Implement arbitrary and discrete limit stencils:
|
||||
Subdivision tables have been replaced with discrete vertex stencils.
|
||||
We would like to add functionality for stencils that push these
|
||||
vertices to the limit, as well as generate stencils for arbitrary
|
||||
locations on the limit surface (a feature currently available in
|
||||
2.x). This work is contingent on the implementation of limit masks.
|
||||
|
||||
#. Tagging and recognition of faces as Holes:
|
||||
A solution for tagging faces as *"holes"* needs to be implemented to
|
||||
match functionality from 2.x releases.
|
||||
|
||||
#. Topology entry-point API:
|
||||
The *advanced* topology entry point interface in
|
||||
Far::TopologyRefinerFactory is not final yet. Some protected
|
||||
accessors are likely to be renamed, added or removed before Beta
|
||||
release.
|
||||
|
||||
#. *"Chaikin"* Rule:
|
||||
The current implementation of the *Chaikin* rule shows small
|
||||
numerical differences with results obtained from Hbr in 2.x releases.
|
||||
Considering that the feature is rarely used and that the current
|
||||
implementation is likely the more correct one, we are considering
|
||||
declaring the current implementation as *the standard*. We will
|
||||
review input from the community on this matter during Alpha and Beta
|
||||
release cycles.
|
||||
|
||||
#. Code Style & Refactoring:
|
||||
While the bulk of code refactoring is mostly in place, we are still
|
||||
tweaking some of the finer details. Further changes to code styling
|
||||
and conventions should be expected throughout the Alpha release
|
||||
cycle.
|
||||
|
||||
|
||||
Release 2.x
|
||||
===========
|
||||
|
||||
`Previous releases <release_notes_2x.html>`_
|
||||
|
584
documentation/release_notes_2x.rst
Normal file
@ -0,0 +1,584 @@
|
||||
..
|
||||
Copyright 2013 Pixar
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "Apache License")
|
||||
with the following modification; you may not use this file except in
|
||||
compliance with the Apache License and the following modification to it:
|
||||
Section 6. Trademarks. is deleted and replaced with:
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor
|
||||
and its affiliates, except as required to comply with Section 4(c) of
|
||||
the License and to reproduce the content of the NOTICE file.
|
||||
|
||||
You may obtain a copy of the Apache License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the Apache License with the above modification is
|
||||
distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the Apache License for the specific
|
||||
language governing permissions and limitations under the Apache License.
|
||||
|
||||
|
||||
Release Notes
|
||||
-------------
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:backlinks: none
|
||||
|
||||
----
|
||||
|
||||
Release 2.6.0
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- Add subdivision kernels for ARM NEON
|
||||
- Add OsdUtilVertexSplit which creates a vertex-varying data table by duplicating
|
||||
vertices in a `FarMesh`
|
||||
- Add basic functions to work with FV data via evaluator API
|
||||
|
||||
**Changes**
|
||||
- Added Catmark restricted vertex compute kernels that optimize for vertices
|
||||
with no semi-sharp creases
|
||||
- Fix accessor omissions in osd/mesh.h
|
||||
- Add support for different subdivision schemes for OsdUtilMesh
|
||||
|
||||
**Bug Fixes**
|
||||
- Fix crashes when using rather low-end cards like Intel ones
|
||||
- Fix a bug in the creation of an edge-vertex kernel batch
|
||||
- Fix mismatch in declaration and usage of OsdCudaComputeRestrictedVertexA
|
||||
- Fix a bug in the vertex order for restricted Catmark vertex-vertex kernel batches
|
||||
- Fix a bug in FarCatmarkSubdivisionTablesFactory that prevented the
|
||||
CATMARK_QUAD_FACE_VERTEX kernel from being selected for subdivision
|
||||
level 2 or greater.
|
||||
- Fix a bug in OsdUtilVertexSplit that occurs when getting the address of
|
||||
the end of a std::vector
|
||||
- Fix error in createCLBuffer that occurs when the buffer size is zero
|
||||
- Fix a bug in the CUDA computeRestrictedEdge kernel
|
||||
- Fix duplicate variables with identical name
|
||||
- Fix osdutil build errors
|
||||
- Fix cmake diagnostic messsage
|
||||
|
||||
Release 2.5.1
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- Add CATMARK_QUAD_FACE_VERTEX and CATMARK_TRI_QUAD_FACE_VERTEX compute kernels
|
||||
optimization that takes advantage of all-quads or all-triange-and-quads meshes
|
||||
|
||||
**Bug Fixes**
|
||||
- Fix a compiler error in the GLSL Transform Feedback kernels on OS X
|
||||
- Fix boundary interpolation in osdutil
|
||||
- Fix bilinear stencil tangent computions
|
||||
|
||||
Release 2.5.0
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- Add ability to generate triangle patches for a uniformly subdivided mesh
|
||||
- Add new example 'topologySharing'
|
||||
- Add interleaved buffer mode in glViewer
|
||||
- Add GLSL compute kernel to glBatchViewer
|
||||
- Add TBB compute kernel to glBatchViewer
|
||||
- Add a PullDown widget to our HUD in examples/common
|
||||
- GUI updates & cosmetic changes to GL example code
|
||||
- Adding a programmable image shader to gl_hud
|
||||
- Code cleanup for GLFrameBuffer in examples/common
|
||||
- Implement C-API accessor to evaluator topology (osdutil)
|
||||
- Add command line option to CMake's options
|
||||
- Add a CMake option to disable OpenCL
|
||||
- Add a FindCLEW.cmake module in anticipation of using CLEW as a dependency
|
||||
- Integrate CLEW into osd library and examples
|
||||
|
||||
**Changes**
|
||||
- Change interleaved buffer support in OsdCompute:
|
||||
- Removed OsdVertexDescriptor and replaced with OsdVertexBufferDescriptor
|
||||
- Reorganize ComputeContext and ComputeController.
|
||||
- Reorganize EvalStencilContext and EvalStencilController
|
||||
Moved transient states (current vertex buffer etc) to controller
|
||||
- Reorganize EvalLimitContext and EvalLimitController
|
||||
Moved transient states (current vertex buffer etc) to controller
|
||||
- Fix adaptive isolation of sharp corner vertices
|
||||
- Fix incorrect FarMeshFactory logic for isolating multiple corner vertices in corner patches
|
||||
- Change EvalLimit Gregory patch kernels to the large weights table to accomodate higher valences
|
||||
- Fix calculation of screen space LOD tess factors for transition corner patches.
|
||||
- Add a public constructor to OsdMesh
|
||||
- Decrease compiler warning thresholds and fix outstanding warnings
|
||||
- Make PTex support optional
|
||||
- Add a NO_MAYA flag to CMakeLists to disable all Autodesk Maya dependencies in the build
|
||||
- Document NO_MAYA command line option
|
||||
|
||||
**Bug Fixes**
|
||||
- Fix mistakenly deleted memory barrier in glsl OsdCompute kernel.
|
||||
- Fix shape_utils genRIB function to use streams correctly.
|
||||
- Temporary workaround for the synchronization bug of glsl compute kernel
|
||||
- Fix Hud display for higher DPI (MBP retina)
|
||||
- Fix Hud (d3d11)
|
||||
- Fix examples to use GL timer query to measure the GPU draw timing more precisely
|
||||
- Fix glViewer: stop updating during freeze.
|
||||
- Fix file permissions on farPatchTablesFactory.h
|
||||
- Fix some meory leaks in adaptive evaluator (osdutil)
|
||||
- Fix OsdUtilAdaptiveEvaluator concurrency issue
|
||||
- Fix OsdUtilRefiner incorrect "Invalid size of patch array" error reporting.
|
||||
- Fix OsdUtilPatchPartitioner failure for triangle patches
|
||||
- Fixes a bug that causes OsdUtilPatchPartitioner to fail to rebuild the face-varying
|
||||
data table correctly for triangle patches.
|
||||
- Add missing third parameter to templated OsdDrawContext usage (osdutil/batch.h)
|
||||
- Return success status from openSubdiv_finishEvaluatorDescr() (osdutil)
|
||||
- Remove debugging std::cout calls (osdutil)
|
||||
- Build errors & warnings:
|
||||
- Fix OSX Core Profile build (GLFrameBuffer)
|
||||
- Fix ptexViewer build error on OSX
|
||||
- Fix framebuffer shader compiling for OSX
|
||||
- Reordering includes to address a compile error on OSX/glew environment
|
||||
- Fix compilation errors with CLEW enabled
|
||||
- Fix icc build problems
|
||||
- Fix compiler warnings in OsdClVertexBuffer
|
||||
- Fix compilation error on windows+msvc2013
|
||||
- Fix build warnings/errors with VS2010 Pro
|
||||
- Fix Windows build warning in FarPatchTablesFactory
|
||||
- Fix doxygen generation errors
|
||||
|
||||
|
||||
Release 2.4.1
|
||||
=============
|
||||
|
||||
**Changes**
|
||||
- Add correct OpenSubdiv namespace begin/end blocks.
|
||||
|
||||
**Bug Fixes**
|
||||
- Compile osdutil with -fPIC for correct linking.
|
||||
- Fix a bug of OsdUtilMeshBatch, the varying buffer isn't computed with CL kernels
|
||||
- Fix FindGLFW.cmake to use the %GLFW_LOCATION% environment variable in Windows
|
||||
- Fix Draw contexts do not fully initialize patch arrays
|
||||
|
||||
Release 2.4.0
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- Adding functionality to store uniform face-varying data across multiple levels of subdivision
|
||||
- Add OsdUtilPatchPartitioner.
|
||||
It splits patcharray into subsets so that clients can draw partial surfaces
|
||||
for both adaptive and uniform.
|
||||
|
||||
**Changes**
|
||||
- Remove FarMesh dependency from Osd*Context.
|
||||
- Use DSA APIs for GL buffer update (if available).
|
||||
- Refactor Far API
|
||||
- replace void- of all kernel applications with CONTEXT template parameter.
|
||||
It eliminates many static_casts from void- for both far and osd classes.
|
||||
- move the big switch-cases of far default kernel launches out of Refine so
|
||||
that osd controllers can arbitrary mix default kernels and custom kernels.
|
||||
- change FarKernelBatch::kernelType from enum to int, clients can add
|
||||
custom kernel types.
|
||||
- remove a back-pointer to farmesh from subdivision table.
|
||||
- untemplate all subdivision table classes and template their compute methods
|
||||
instead. Those methods take a typed vertex storage.
|
||||
- remove an unused argument FarMesh from the constructor of subdivision
|
||||
table factories.
|
||||
- Refactor FarSubdivisionTables.
|
||||
Delete scheme specialized subdivision tables. The base class FarSubdivisionTables
|
||||
already has all tables, so we just need scheme enum to identify which scheme
|
||||
the subdivision tables belong to. This brings a lot of code cleanups around far
|
||||
factory classes.
|
||||
- Move FarMultiMeshFactory to OsdUtil.
|
||||
- Move table splicing functions of FarMultiMeshFactory into factories
|
||||
- Change PxOsdUtil prefix to final OsdUtil prefix.
|
||||
- Improve error reporting in osdutil refinement classes, and fix a build issue
|
||||
|
||||
**Bug Fixes**
|
||||
- Fix another multi mesh splicing bug of face varying data.
|
||||
- Make CMake path variables more robust
|
||||
- Fixing a crash on Marvericks w/glew
|
||||
- Update dxViewer example documentation
|
||||
- Fix wrong logic in openSubdiv_setEvaluatorCoarsePositions
|
||||
- Remove debug print from adaptive evaluator's initialization
|
||||
|
||||
Release 2.3.5
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- Add the ability to read obj files to the dxViewer example
|
||||
- Add screen-capture function to ptexViewer
|
||||
- Update documention for Xcode builds
|
||||
- Add documentation (boundary interpolation rules and face-varying boundary interpolation rules)
|
||||
|
||||
**Changes**
|
||||
- Refactoring FarPatchTables and FarPatchTablesFactory
|
||||
- Move GL vertex buffer VBO buffer allocation out of allocate() and into BindVBO()
|
||||
- Enable uvViewer on OS X now that Mavericks is released.
|
||||
- Replacing un-necessary dynamic_cast with reinterpret_cast within FarDispatcher
|
||||
- Minor code cleanup of FarMeshFactory
|
||||
- Remove address space qualifiers from OpenCL kernel functions
|
||||
- Fix OpenCL initialization to be slightly more robust
|
||||
- Add OpenCL header include paths where necessary
|
||||
- Add 'static' specifiers for non-kernel CL funcs at program scope
|
||||
- Add stddef.h to python/osd/osdshim.i
|
||||
- Modify ptexViewer and uvViewer shaders to address some portability issues
|
||||
|
||||
**Bug Fixes**
|
||||
- Fix Gregory Boundary patch buffer overrun
|
||||
- Fix black texels when the resolution of a ptex face is less than 4
|
||||
- Fix a splicing bug in FarMultiMeshFactory
|
||||
- Fix a build error when using older versions of GLFW
|
||||
- Fix build warnings (optimized)
|
||||
- Fix FindTBB.cmake
|
||||
- Fix FindMaya.cmake
|
||||
- Fix glViewer support for GLSL compute
|
||||
- Fix ptexViewer: enable specular pass in both IBL and point lighting
|
||||
- Fix Zlib include in ptexViewer
|
||||
- Fix ptexViewer shader errors.
|
||||
- Fix osdPolySmooth Maya plugin
|
||||
- Fix UV merging in osdPolySmooth code example
|
||||
- Add cleanup function to osdPolySmooth Maya plugin
|
||||
- Fix Maya OsdPolySmooth node component output
|
||||
- Fix GLSL array instantiation syntax for glStencilViewer
|
||||
- Fix examples to run correctly on high DPI displays with GLFW 3
|
||||
|
||||
Release 2.3.4
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- Adding CPU/OMP/TBB Context / Controller pairs for CPU evaluation of smooth normals
|
||||
- Added adaptiveEvaluator class inspired by Sergey's work in blender (OsdUtil)
|
||||
|
||||
**Changes**
|
||||
- Changed the HUD to ignore mouse clicks when not visible.
|
||||
- Updates for blender development (OsdUtil)
|
||||
- Add C compatible API to access the adaptiveEvaluator class from non-C++ (OsdUtil)
|
||||
- Update license headers to apache (OsdUtil)
|
||||
- CMake build improvement : make osd a cmake object library & remove compiling redundancies
|
||||
- Improve stringification of shaders & kernels in CMake build
|
||||
|
||||
**Bug Fixes**
|
||||
- Fixed iOS build
|
||||
- Fixed VS2010 warnings/errors.
|
||||
- Fix OsdCpuEvalLimitKernel
|
||||
- Fix maxvalence calculation in FarMeshFactory
|
||||
- Fix FarStencilFactory control stencil caching
|
||||
- Removing assert for high-valence vertices running off limit tangent pre-computed table.
|
||||
- Fix degenerate stencil limit tangent code path.
|
||||
- Fix unused variable build warnings (gcc 4.8.2 - Fedora 19)
|
||||
- Fix build warning from osdutil/adaptiveEvaluator.cpp
|
||||
|
||||
Release 2.3.3
|
||||
=============
|
||||
|
||||
**Changes**
|
||||
- Modify Far remapping of singular vertices to point to their source vertex.
|
||||
- Refactoring Ptex Mipmap and Analytic Displacement code
|
||||
- Adding some documentation for Chaikin crease rule
|
||||
- Misc. improvements to PxOsdUtilsMesh
|
||||
- Adding recommended isolation output to OsdPolySmooth node
|
||||
|
||||
**Bug Fixes**
|
||||
- Adding an error check on version parsing of main CMakeLists
|
||||
- Fix regex in FindMaya.cmake that breaks with recent versions of Maya
|
||||
- Fix crashes induced by typeid
|
||||
- Fixed VS2010 build warning
|
||||
- Fix build break in hbr_regression
|
||||
- Fix incorrect capitalization in GL ptexViewer shader.glsl
|
||||
- Fix OSX build: add stdlib.h include
|
||||
|
||||
Release 2.3.2
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- Adding control cage drawing to ptexViewer
|
||||
- Adding Maya osdPolySmooth plugin into OpenSubdiv examples.
|
||||
|
||||
**Changes**
|
||||
- Removing some glGetError checks that are causing problems for Autodesk
|
||||
- D3D11DrawRegistry returns the common shader config for all non-tess patcharrays.
|
||||
- Updates to simple cpu osdutil classes
|
||||
|
||||
**Bug Fixes**
|
||||
- Fix Hbr Chaikin crease rule
|
||||
- Fix Chaikin tag parsing
|
||||
- Fix return value of allocate function for OsdCPUGLVertxBuffer
|
||||
- Fixed GLSL shader portability.
|
||||
- Fix FindGLFW.cmake for GLFW 3.03 on OSX
|
||||
- Fixed compiler warnings.
|
||||
- Fixed VS2010 build errors
|
||||
- Fixed WIN32 build error when no DXSDK installed.
|
||||
- Fix OSX build: stdlib.h needs to be included in glPtexMipmapTexture.h
|
||||
- Fix for crash in new mesh/refiner code in OsdUtil
|
||||
|
||||
|
||||
Release 2.3.1
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- Add DX11 version of ptex mipmap loader
|
||||
- Add DX11 ptex viewer (work in progress)
|
||||
- Add DX11 fractional partitioning, normal derivatives computation
|
||||
- Add memory usage controls to Ptex loader
|
||||
- Add face-varying boundary interpolation parsing to shape_utils
|
||||
- Add simple HbrMesh and FarMesh wrapper classes to osdutil
|
||||
|
||||
**Changes**
|
||||
- Amend language of attribution file 'NOTICE.txt'
|
||||
- Optimize a bit of ptex mipmap lookup.
|
||||
- Show ptex memory usage in GL and DX11 ptexViewers
|
||||
- Improve ptex guttering
|
||||
- Addding some video links to our collection of external resources
|
||||
|
||||
**Bug Fixes**
|
||||
- Fix edge-only face-varying interpolation
|
||||
- Fix Far to handle disconnected vertices in an Hbr mesh
|
||||
- Fixed ptex cache resource release sequence
|
||||
- Fix build symbol conflict in Far
|
||||
- Fix patch parambuffer generation in OsdD3D11DrawContext
|
||||
- Fix a minor osdutil build warning (seen with gcc 4.8.1)
|
||||
- Fix VS2010 build errors
|
||||
|
||||
Release 2.3.0
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- Added Analytical displacement mapping ('Analytic Displacement Mapping using
|
||||
Hardware Tessellation; Niessner and Loop [TOG 2013])
|
||||
- Added a new ptex mipmap loader
|
||||
- Added face varying macros for loop subdivision
|
||||
- Added the uvViewer example to see how face varying interpolation rule works
|
||||
- Added a slider component and cleanup hud code.
|
||||
|
||||
**Changes**
|
||||
- Adding license & attribution files, improved language of the code headers
|
||||
- Install documentation into the Filesystem Hierarchy Standard location
|
||||
- Set GLFW_OPENGL_FORWARD_COMPAT on Mac OS to make samples work on that platform
|
||||
- Added surface normal mode & mipmap to ptxViewer
|
||||
|
||||
**Bug Fixes**
|
||||
- Fix a bug of bad fvar splicing for loop surface.
|
||||
- Fix incorrect bilinear limit tangents in FarStencilTablesFactory
|
||||
- Fix boundary interpolation rules doc
|
||||
- Added an error check on updating cuda buffer
|
||||
- Fix face varying rendering on loop surface
|
||||
- Fixed glBatchViewer build for GLFW 2.x
|
||||
- Expand search paths for FindGLFW.cmake for Debian and other Linux architectures
|
||||
- Fix CMake executable builds for ICC
|
||||
- Fix bhr baseline regression, so reference files are real OBJ's
|
||||
- Fixed clKernelBundle.cpp to build on Android.
|
||||
- Fix misc build warings
|
||||
|
||||
Release 2.2.0
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- Added subdivision stencil functionality (Far & OsdEval)
|
||||
|
||||
**Bug Fixes**
|
||||
- Fix D3D11DrawContext to check for NULL pointers
|
||||
- Fix cpuEvalLimitController crash bug
|
||||
- Fixed search path suffixes for ICC libs
|
||||
- Fixed invalid initialization of glslTransformFeedback kernel.
|
||||
|
||||
Release 2.1.0
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- Added TBB Compute back-end on Linux (contribution from Sheng Fu)
|
||||
- Added support for ICC compiler (still Beta)
|
||||
|
||||
**Changes**
|
||||
- Added constructor to OsdMesh with a FarMesh * as input
|
||||
- Modify CMake to name and sym-link DSO's based on Linux ABI versioning spec
|
||||
- Added command line input to DX11 viewer
|
||||
- FarMultiMesh can splice uniform and adaptive meshes together.
|
||||
|
||||
**Bug Fixes**
|
||||
- Fix FarMultiMesh splicing
|
||||
- Removed unnecessary cudaThreadSynchronize calls.
|
||||
- Fix glViewer overlapping HUD menus
|
||||
- Fix facevarying rendering in glBatchViewer
|
||||
- Fix build of GLSL transform feedback kernels
|
||||
- Fix 'Getting Started' documentation
|
||||
|
||||
|
||||
Release 2.0.1
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- New CLA files to reflect Apache 2.0 licensing
|
||||
|
||||
**Changes**
|
||||
- Move all public headers to include/opensubdiv/...
|
||||
- Adding Osd documentation based on Siggraph slides
|
||||
|
||||
**Bug Fixes**
|
||||
- Fix incorrect transition pattern 3 in GLSL / HLSL shaders
|
||||
- Fix CMake build to not link GPU-based libraries into libosdCPU
|
||||
- Fix support for GLEW on OSX
|
||||
- Fix GLFW Xrandr & xf86vmode dependency paths for X11 based systems
|
||||
- Fix HUD display overlaps in code examples
|
||||
- Fix FindGLEW.cmake to be aware of multiarch on linux systems
|
||||
- Fix some hard-coded include paths in CMake build
|
||||
|
||||
|
||||
Release 2.0.0
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
- New CMake build flags: NO_LIB, NO_CUDA, NO_PYTHON)
|
||||
|
||||
**Changes**
|
||||
- OpenSubdiv is now under Apache 2.0 license
|
||||
- HbrHalfedge and HbrFVarData copy constructors are now private
|
||||
- Documentation style matched to graphics.pixar.com + new content
|
||||
- Add an animation freeze button to ptexViewer
|
||||
- Variable name changes for better readability across all example
|
||||
shader code
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Fix incorrect patch generation for patches with 2 non-consecutive boundary edges
|
||||
- Fix "undefined gl_PrimitiveID" shader build errors
|
||||
- Fix for shader macro "OSD_DISPLACEMENT_CALLBACK"
|
||||
- Fix out-of-bounds std::vector access in FarPatchTablesFactory
|
||||
|
||||
----
|
||||
|
||||
Release 1.2.4
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
|
||||
- Adding support for fractional tessellation of patches
|
||||
- Adding a much needed API documention system based on Docutils RST markup
|
||||
- Adding support for face-varying interpolation in GLSL APIs
|
||||
- Adding varying data buffers to OsdMesh
|
||||
- Adding accessors to the vertex buffers in OsdGlMesh
|
||||
- Adding face-varying data to regression shapes
|
||||
|
||||
**Changes**
|
||||
|
||||
- Cleanup of common bicubic patch shader code (GLSL / HLSL) for portability
|
||||
(ATI / OSX drivers)
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Fix FarVertexEditTablesFactory to insert properly vertex edit batches
|
||||
(fixes incorrect hierarchical hole in regression shape)
|
||||
- Fix FarPatchMap quadtree to not drop top-level non-quad faces
|
||||
- Fix Gregory patches bug with incorrect max-valence
|
||||
- Fix FarPatchTables::GetNumFaces() and FarPatchTables::GetFaceVertices()
|
||||
functions to return the correct values
|
||||
- Fix face indexing GLSL code (ptex works on non-quads again)
|
||||
- Fix face-varying data splicing in FarMultiMeshFactory
|
||||
- Fix ptex face indexing in FarMultiMeshFactory
|
||||
- Fix glew #include to not break builds
|
||||
- Fix Clang / ICC build failures with FarPatchTables
|
||||
- Fix build and example code to work with GFLW 3.0+
|
||||
- Fix cmake to have ptex dynamically linked in OSX
|
||||
|
||||
----
|
||||
|
||||
Release 1.2.3
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
|
||||
- Adding Varying and Face-Varying data interpolation to EvalLimit
|
||||
|
||||
**Changes**
|
||||
|
||||
- EvalLimit API refactor : the EvalContext now has dedicated structs to track all
|
||||
the vertex, varying and face-varying data streams. Also renamed some "buffers"
|
||||
into "tables" to maintain code consistency
|
||||
- EvalLimit optimization : switch serial indexing to a quad-tree based search
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Face-varying data bug fixes : making sure the data is carried around appropriately
|
||||
Fixes for OpenCL use with the new batching APIs
|
||||
- GLSL general shader code cleanup & fixes for better portability
|
||||
- GLSL Tranform Feedback initialization fix
|
||||
- Critical fix for FarMultiMesh batching (indexing was incorrect)
|
||||
- Fix osdutil CL implementation (protect #includes on systems with no OpenCL SDK
|
||||
installed)
|
||||
- Fix face-varying interpolation on adaptive patches
|
||||
- FarPatchTables : fix IsFeatureAdaptive() to return the correct answer
|
||||
- Fix Far factories to handle the absence of face-varying data correctly.
|
||||
- Many GLSL shader code style fixes which should help with ATI / OSX shader compiling
|
||||
|
||||
----
|
||||
|
||||
Release 1.2.2
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
|
||||
- Introducing the EvalLimit API : the Eval module aims at providing support for
|
||||
computational tasks that are not related to drawing the surfaces. The EvalLimit
|
||||
sub-module provides an API that enables client code to evaluate primitive variables
|
||||
on the limit surface.
|
||||
|
||||
.. image:: images/evalLimit_hedit0.jpg
|
||||
:height: 300px
|
||||
:align: center
|
||||
:target: images/evalLimit_hedit0.jpg
|
||||
|
||||
- Osd<xxx>ComputeController : minor optimization. Added early exit to Refine method
|
||||
to avoid unnecessary interop.
|
||||
|
||||
**Changes**
|
||||
|
||||
- OsdGLDawContext : minor API change. Protecting some member variables and adding
|
||||
const accessors
|
||||
- OsdError : minor API refactor, added Warning functions.
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Fix Ptex bug : prevent corner texel guttering code to from going into infinite
|
||||
loops
|
||||
- Adding the ability for a FarMeshFactory to construct patchTables starting from
|
||||
'firstLevel' in uniform subdivision mode
|
||||
- Consolidating the color coding of bicubic patch types through all our our code
|
||||
examples (this is used mostly as a debugging tool)
|
||||
- Fixing some MSVC++ build warnings
|
||||
- Update to the outdated README.md
|
||||
|
||||
----
|
||||
|
||||
Release 1.2.1
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
|
||||
- Added CUDA runtime error checking
|
||||
|
||||
----
|
||||
|
||||
Release 1.2.0
|
||||
=============
|
||||
|
||||
**Changes**
|
||||
|
||||
- Major Far refactor around patchTables to introduce the draw batching API
|
||||
- Renaming osd_util to osdutil
|
||||
|
||||
**Bug Fixes**
|
||||
|
||||
- Fix GLSL transform feedback initialization bug in ptexViewer
|
||||
- Minor bug & typo fixes
|
||||
|
||||
----
|
||||
|
||||
Release 1.1.0
|
||||
=============
|
||||
|
||||
**New Features**
|
||||
|
||||
- release initiated because of the switch to Git Flow
|
||||
|
||||
----
|
||||
|
||||
Release 1.0.0
|
||||
=============
|
||||
|
||||
Oringal release:
|
||||
|
@ -32,6 +32,11 @@ ul.creatorFooterNav {
|
||||
</div>
|
||||
|
||||
<!-- TOP NAVIGATION MENU -->
|
||||
<ul class="creatorMainNav floatLeft" id="menu">
|
||||
<li class="creatorMainNav">
|
||||
<a href="release_notes.html">${RELEASE_STRING}</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="creatorMainNav floatRight" id="menu">
|
||||
<li class="" id="navbarId-23704">
|
||||
<a href="intro.html">User Docs</a>
|
||||
|
357
documentation/sdc_overview.rst
Normal file
@ -0,0 +1,357 @@
|
||||
..
|
||||
Copyright 2013 Pixar
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "Apache License")
|
||||
with the following modification; you may not use this file except in
|
||||
compliance with the Apache License and the following modification to it:
|
||||
Section 6. Trademarks. is deleted and replaced with:
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor
|
||||
and its affiliates, except as required to comply with Section 4(c) of
|
||||
the License and to reproduce the content of the NOTICE file.
|
||||
|
||||
You may obtain a copy of the Apache License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the Apache License with the above modification is
|
||||
distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the Apache License for the specific
|
||||
language governing permissions and limitations under the Apache License.
|
||||
|
||||
|
||||
Sdc Overview
|
||||
------------
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:backlinks: none
|
||||
|
||||
.. image:: images/api_layers_3_0.png
|
||||
:width: 100px
|
||||
:target: images/api_layers_3_0.png
|
||||
|
||||
Subdivision Core (Sdc)
|
||||
======================
|
||||
|
||||
Sdc is the lowest level layer in OpenSubdiv. Its intent is to separate
|
||||
the core subdivision details from any particular representation of a mesh
|
||||
(it was previously bound to Hbr) to facilate other classes both internal
|
||||
and external to OpenSubdiv generating consistent results.
|
||||
|
||||
The functionality can be divided roughly into three sections:
|
||||
|
||||
* types, traits and options for the supported subdivision schemes
|
||||
* computations required to support semi-sharp creasing
|
||||
* computing mask weights for subdivided vertices for all schemes
|
||||
|
||||
Overall the approach taken was to extract the functionality at as low a
|
||||
level as possible. In some cases they are not far from being simple global
|
||||
functions. The intent was to start at a low level and build any higher
|
||||
level functionality as needed. What exists now is functional for ongoing
|
||||
development and anticipated needs within OpenSubdiv for the near future.
|
||||
|
||||
Its also worth noting that the intent of Sdc is to provide the building
|
||||
blocks for OpenSubdiv and its clients to efficiently process the specific
|
||||
set of subdivision schemes that are supported. It is not intended to be
|
||||
a general framework for defining customized subdivision schemes.
|
||||
|
||||
|
||||
.. container:: notebox
|
||||
|
||||
**Alpha Issues**
|
||||
|
||||
Warnings of change:
|
||||
|
||||
* note change in creasing method from *"Normal"* to *"Uniform"* and
|
||||
related use of *"Uniform"*
|
||||
* all boundary interpolation choices in *Sdc::Options* are subject to change
|
||||
|
||||
Other changes under consideration:
|
||||
|
||||
* *<MASK>* face-weights to support face-centers and/or original vertices
|
||||
* merging *Sdc::TypeTraits<T>* into *Sdc::Scheme<T>* as static methods
|
||||
* static initialization of creasing constants (for smooth and
|
||||
infinitely sharp)
|
||||
* how to document template paremeter interfaces, e.g. *<MASK>*,
|
||||
*<FACE>*, etc.?
|
||||
|
||||
|
||||
Types, Traits and Options
|
||||
=========================
|
||||
|
||||
The most basic type is the enum *Sdc::Type* that identifies the fixed set of
|
||||
subdivision schemes supported by OpenSubdiv: *Bilinear*, *Catmark* and *Loop*.
|
||||
With this alone, we intend to avoid all dynamic casting issues related to the
|
||||
scheme by simply adding members to the associated subclasses for inspection.
|
||||
In addition to the type enum itself, a class defining a set of
|
||||
*TypeTraits<Type TYPE>* for each scheme is provided along with the required
|
||||
specializations for each scheme.
|
||||
|
||||
The second contribution is the collection of all variations in one place that can
|
||||
be applied to the subdivision schemes, i.e. the boundary interpolation rules,
|
||||
creasing method, edge subdivision choices, etc. The fact that these are all
|
||||
declared in one place alone should help clients see the full set of variations
|
||||
that are possible.
|
||||
|
||||
A simple Options struct (a set of bitfields) aggregates all of these variations
|
||||
into a single object (the equivalent of an integer in this case) that are passed
|
||||
around to other Sdc classes and/or methods and are expected to be used at a higher
|
||||
level both within OpenSubdiv and externally. By aggregating the options and
|
||||
passing them around as a group, it allows us to extend the set easily in future
|
||||
without the need to rewire a lot of interfaces to accomodate the new choice.
|
||||
Clients can enables new choices at the highest level and be assured that they will
|
||||
propagate to the lowest level where they are relevant.
|
||||
|
||||
|
||||
Creasing support
|
||||
================
|
||||
|
||||
Since the computations involved in the support of semi-sharp creasing are
|
||||
independent of the subdivision scheme, the goal in Sdc was to encapsulate all
|
||||
related creasing functionality in a similarly independent manner. Computations
|
||||
involving sharpness values are also much less dependent on topology -- there
|
||||
are vertices and edges with sharpness values, but knowledge of faces or boundary
|
||||
edges is not required -- so the complexity of topological neighborhoods required
|
||||
for more scheme-specific functionality is arguably not necessary here.
|
||||
|
||||
Creasing computations have been provided as methods defined on a Crease class
|
||||
that is constructed with a set of Options. Its methods typically take sharpness
|
||||
values as inputs and compute one or a corresponding set of new sharpness values
|
||||
as a result. For the "Uniform" creasing method (previously known as *"Normal"*),
|
||||
the computations may be so trivial as to question whether such an interface is
|
||||
worth it, but for "Chaikin" or other schemes in future that are non-trivial, the
|
||||
benefits should be clear. Functionality is divided between both uniform and
|
||||
non-uniform, so clients have some control over avoiding unnecessary overhead,
|
||||
e.g. non-uniform computations typically require neighboring sharpness values
|
||||
around a vertex, while uniform does not.
|
||||
|
||||
Also included as part of the Crease class is the Rule enum -- this indicates if
|
||||
a vertex is Smooth, Crease, Dart or Corner (referred to as the "mask" in Hbr)
|
||||
and is a function of the sharpness values at and around a vertex. Knowing the
|
||||
Rule for a vertex can accelerate mask queries, and the Rule can often be
|
||||
inferred based on the origin of a vertex (e.g. it originated from the middle of
|
||||
a face, was the child of a Smooth vertex, etc.).
|
||||
|
||||
Methods are defined for the Crease class to:
|
||||
|
||||
* subdivide edge and vertex sharpness values
|
||||
* determine the Rule for a vertex based on incident sharpness values
|
||||
* determine the transitional weight between two sets of sharpness values
|
||||
|
||||
Being all low-level and working directly on sharpness values, it is a client's
|
||||
responsibility to coordinate the application of any hierarchical crease edits
|
||||
with their computations.
|
||||
|
||||
Similarly, in keeping with this as a low-level interface, values are passed as
|
||||
primitive arrays. This follows the trend in OpenSubdiv of dealing with data of
|
||||
various kinds (e.g. weights, component indices, now sharpness values, etc.) in
|
||||
small contiguous sets of values. In most internal cases we can refer to a set
|
||||
of values or gather what will typically be a small number of values on the stack
|
||||
for temporary use.
|
||||
|
||||
|
||||
Scheme-specific support
|
||||
=======================
|
||||
|
||||
While the TypeTraits class provides traits for each subdivision scheme supported
|
||||
by OpenSubdiv (i.e. *Bilinear*, *Catmark* and *Loop*), the Scheme class
|
||||
provides methods for computing the various sets of weights used to compute new
|
||||
vertices resulting from subdivision. The collection of weights used to compute
|
||||
a single vertex at a new subdivision level is typically referred to as a
|
||||
*"mask"*. The primary purpose of the Scheme class is to provide such masks in a
|
||||
manner both general and efficient.
|
||||
|
||||
Each subdivision scheme has its own values for its masks, and each are provided
|
||||
as specializations of the template class *Scheme<Type TYPE>*. The intent is to
|
||||
minimize the amount of code specific to each scheme.
|
||||
|
||||
The computation of mask weights for subdivided vertices is the most significant
|
||||
contribution of Sdc. The use of semi-sharp creasing with each
|
||||
non-linear subdivision scheme complicates what are otherwise simple
|
||||
masks detemined solely by the topology, and packaging that functionality to
|
||||
achieve both the generality and efficiency desired has been a challenge.
|
||||
|
||||
Mask queries are defined in the *Scheme* class template, which has
|
||||
specializations for each of the supported subdivision schemes. Mask queries
|
||||
are defined in terms of interfaces for two template parameters: the first
|
||||
defining the topological neighborhood of a vertex, and a second defining a
|
||||
container in which to gather the individual weights:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
template <typename FACE, typename MASK>
|
||||
void ComputeFaceVertexMask(FACE const& faceNeighborhood, MASK& faceVertexMask, ...) const;
|
||||
|
||||
Each mask query is expected to call methods defined for the **FACE**, **EDGE** or
|
||||
**VERTEX** classes to obtain the information they require ; typically these
|
||||
methods are simple queries about the topology and associated sharpness values.
|
||||
Clients are free to use their own mesh representations to gather the requested
|
||||
information as quickly as possible, or to cache some subset as member variables
|
||||
for immediate inline retrieval.
|
||||
|
||||
In general, the set of weights for a subdivided vertex is dependent on the following:
|
||||
|
||||
* the topology around the parent component from which the vertex originates
|
||||
* the type of subdivision *Rule* applicable to the parent component
|
||||
* the type of subdivision *Rule* applicable to the new child vertex
|
||||
* a transitional weight blending the effect between differing parent and child rules
|
||||
|
||||
This seems fairly straight-forward, until we look at some of the dependencies involved:
|
||||
|
||||
* the parent *Rule* requires the sharpness values at and around the parent component
|
||||
* the child *Rule* requires the subdivided sharpness values at and around the new
|
||||
child vertex (though it can sometimes be trivially inferred from the parent)
|
||||
* the transitional weight between differing rules requires all parent and child
|
||||
sharpness values
|
||||
|
||||
Clearly the sharpness values are inspected multiple times and so it pays to have
|
||||
them available for retrieval. Computing them on an as-needed basis may be simple
|
||||
for uniform creasing, but a non-uniform creasing method requires traversing
|
||||
topological neighborhoods, and that in addition to the computation itself can be
|
||||
costly.
|
||||
|
||||
The point here is that it is potentially unreasonable to expect to evaluate the
|
||||
mask weights completely independent of any other consideration. Expecting and
|
||||
encouraging the client to have subdivided sharpness values first, for use in more
|
||||
than one place, is therefore recommended.
|
||||
|
||||
The complexity of the general case above is also unnecessary for most vertices.
|
||||
Any client using Sdc typically has more information about the nature of the vertex
|
||||
being subdivided and much of this can be avoided -- particularly for the smooth
|
||||
interior case that often dominates. More on that in the details of the Scheme classes.
|
||||
|
||||
Given that most of the complexity has been moved into the template parameters for
|
||||
the mask queries, the Scheme class remains fairly simple. Like the Crease class,
|
||||
it is instantiated with a set of Options to avoid them cluttering the interface.
|
||||
It is currently little more than three methods for the mask queries for each vertex
|
||||
type. The set of masks may need to be extended in future to include limit masks
|
||||
and (potentially) masks for face-varying data sets (whose neighborhoods may vary in
|
||||
their definition).
|
||||
|
||||
The mask queries have been written in a way that greatly simplifies the
|
||||
specializations required for each scheme. The generic implementation for both
|
||||
the edge-vertex and vertex-vertex masks take care of all of the creasing logic,
|
||||
requiring only a small set of specific masks to be assigned for each Scheme:
|
||||
smooth and crease masks for an edge-vertex, and smooth, crease and corner masks
|
||||
for a vertex-vertex. Other than the *Bilinear* case, which will specialize the
|
||||
mask queries to trivialize them for linear interpolation, the specializations
|
||||
for each *Scheme* should only require defining this set of masks -- and with
|
||||
two of them common (edge-vertex crease and vertex-vertex corner) the Catmark
|
||||
scheme only needs to define three.
|
||||
|
||||
|
||||
The <FACE>, <EDGE> and <VERTEX> interfaces
|
||||
******************************************
|
||||
|
||||
Mask queries require an interface to a topological neighborhood, currently
|
||||
labeled **FACE**, **EDGE** and **VERTEX**. This naming potentially implies more
|
||||
generality than intended as such classes are only expected to provide the
|
||||
methods required of the mask queries to compute its associated weights. While
|
||||
all methods must be defined, some may rarely be invoked, and the client has
|
||||
considerable flexibility in the implementation of these: they can defer some
|
||||
evaluations lazily until required, or be pro-active and cache information in
|
||||
member variables for immediate access.
|
||||
|
||||
An approach discussed in the past has alluded to iterator classes that clients
|
||||
would write to traverse their meshes. The mask queries would then be parameterized
|
||||
in terms of a more general and generic mesh component that would make use of more
|
||||
general traversal iterators. The advantage here is the iterators are written once,
|
||||
then traversal is left to the query and only what is necessary is gathered. The
|
||||
disadvantages are that clients are forced to write these to do anything, getting
|
||||
them correct and efficient may not be trivial (or possible in some cases), and that
|
||||
the same data (e.g. subdivided sharpness) may be gathered or computed multiple
|
||||
times for different purposes.
|
||||
|
||||
The other extreme was to gather everything possible required at once, but that is
|
||||
objectionable. The approach taken here provides a reasonable compromise between
|
||||
the two. The mask queries ask for exactly what they want, and the provided classes
|
||||
are expected to deliver it as efficiently as possible. In some cases the client
|
||||
may already be storing it in a more accessible form and general topological
|
||||
iteration can be avoided.
|
||||
|
||||
The information requested of these classes in the three mask queries is as follows:
|
||||
|
||||
For **FACE**:
|
||||
* the number of incident vertices
|
||||
|
||||
For **EDGE**:
|
||||
* the number of incident faces
|
||||
* the sharpness value of the parent edge
|
||||
* the sharpness values of the two child edges
|
||||
* the number of vertices per incident face
|
||||
|
||||
For **VERTEX**:
|
||||
* the number of incident faces
|
||||
* the number of incident edges
|
||||
* the sharpness value of the parent vertex
|
||||
* the sharpness values for each incident parent edge
|
||||
* the sharpness value of the child vertex
|
||||
* the sharpness values for each incident child edge
|
||||
|
||||
The latter should not be surprising given the dependencies noted above. There
|
||||
are also a few more to consider for future use, e.g. whether the **EDGE** or
|
||||
**VERTEX** is manifold or not. In most cases additional information can be
|
||||
provided to the mask queries (i.e. pre-determined Rules) and most of the child
|
||||
sharpness values are not necessary. The most demanding situation is a
|
||||
fractional crease that decays to zero -- in which case all parent and child
|
||||
sharpness values in the neighborhood are required to determine the proper
|
||||
transitional weight.
|
||||
|
||||
|
||||
The <MASK> interface
|
||||
********************
|
||||
|
||||
Methods dealing with the collections of weights defining a mask are typically
|
||||
parameterized by a *MASK* template parameter that contains the weights. The set of
|
||||
mask weights is currently divided into vertex-weights, edge-weights and
|
||||
face-weights -- consistent with previous usage in OpenSubdiv and providing some
|
||||
useful correllation between the full set of weights and topology. The
|
||||
vertex-weights refer to parent vertices incident the parent component from which a
|
||||
vertex originated, the edge-weights the vertices opposite incident edges of the
|
||||
parent, and the face-weights the center of indicent parent faces. Note the latter
|
||||
is **NOT** in terms of vertices of the parent but potentially vertices in the child
|
||||
originating from faces of the parent. This has been done historically in
|
||||
OpenSubdiv but is finding less use -- particularly when it comes to providing
|
||||
greater support for the Loop scheme -- and is a point needing attention.
|
||||
|
||||
So the mask queries require the following capabilities:
|
||||
|
||||
* assign the number of vertex, edge and/or face weights
|
||||
* retrieve the number of vertex, edge and/or face weights
|
||||
* assign individual vertex, edge and/or face weights by index
|
||||
* retrieve individual vertex, edge and/or face weights by index
|
||||
|
||||
through a set of methods required of all *MASK* classes. Since the maximum
|
||||
number of weights is typically known based on the topology, usage within Vtr,
|
||||
*Far* or *Hbr* is expected to simply define buffers on the stack or in
|
||||
pre-allocated tables to be partitioned into the three sets of weights on
|
||||
construction of a *MASK* and then populated by the mask queries.
|
||||
|
||||
A potentially useful side-effect of this is that the client can define their
|
||||
weights to be stored in either single or double-precision. With that
|
||||
possibility in mind, care was taken within the mask queries to make use of a
|
||||
declared type in the *MASK* interface (*MASK::Weight*) for intermediate
|
||||
calculations. Having support for double-precision masks in *Sdc* does enable it
|
||||
at higher levels in OpenSubdiv if later desired, and that support is made
|
||||
almost trivial with *MASK* being generic.
|
||||
|
||||
It is important to remember here that these masks are being defined consistent
|
||||
with existing usage within OpenSubdiv: both *Hbr* and the subdivision tables
|
||||
generated by *Far*. As noted above, the "face weights" correspond to the
|
||||
centers of incident faces, i.e. vertices on the same level as the vertex for
|
||||
which the mask is being computed, and not relative to vertices in the parent
|
||||
level as with the other sets of weights. It is true that the weights can be
|
||||
translated into a set in terms solely of parent vertices, but in the general
|
||||
case (i.e. *Catmark* subdivision with non-quads in the base mesh) this requires
|
||||
additional topological association. In general we would need N-3 weights for
|
||||
the N-3 vertices between the two incident edges, where N is the number of
|
||||
vertices of each face (typically 4 even at level 0). Perhaps such a
|
||||
translation method could be provided on the mask class, with an optional
|
||||
indication of the incident face topology for the irregular cases. The *Loop*
|
||||
scheme does not have *"face weights"*, for a vertex-vertex mask, but for an
|
||||
edge-vertex mask it does require weights associated with the faces incident the
|
||||
edge -- either the vertex opposite the edge for each triangle, or its center
|
||||
(which has no other use for Loop).
|
@ -41,10 +41,11 @@ bicubic patches such as BSplines or NURBS.
|
||||
:align: center
|
||||
:height: 200
|
||||
|
||||
However, while they do provide a reliable smooth limit surface definition, bicubic
|
||||
patch surfaces are limited to 2-dimensional topologies, which only describes a
|
||||
very small fraction of real-world shapes. This fundamental parametric limitation
|
||||
requires authoring tools to implementat at least the following functionalities:
|
||||
However, while they do provide a reliable smooth limit surface definition,
|
||||
bi-cubic patch surfaces are limited to 2-dimensional topologies, which only
|
||||
describes a very small fraction of real-world shapes. This fundamental
|
||||
parametric limitation requires authoring tools to implement at least the
|
||||
following functionalities:
|
||||
|
||||
- smooth trimming
|
||||
- seams stitching
|
||||
@ -61,15 +62,16 @@ therefore are not constrained by these difficulties.
|
||||
Arbitrary Topology
|
||||
==================
|
||||
|
||||
A subdivision surface, like a parametric surface, is described by its control mesh
|
||||
of points. The surface itself can approximate or interpolate this control mesh
|
||||
while being piecewise smooth. But where polygonal surfaces require large numbers
|
||||
of data points to approximate being smooth, a subdivision surface is smooth -
|
||||
meaning that polygonal artifacts are never present, no matter how the surface
|
||||
animates or how closely it is viewed.
|
||||
A subdivision surface, like a parametric surface, is described by its control
|
||||
mesh of points. The surface itself can approximate or interpolate this control
|
||||
mesh while being piecewise smooth. But where polygonal surfaces require large
|
||||
numbers of data points to approximate being smooth, a subdivision surface is
|
||||
smooth - meaning that polygonal artifacts are never present, no matter how the
|
||||
surface animates or how closely it is viewed.
|
||||
|
||||
Ordinary cubic B-spline surfaces are rectangular grids of tensor-product patches.
|
||||
Subdivision surfaces generalize these to control grids with arbitrary connectivity.
|
||||
Ordinary cubic B-spline surfaces are rectangular grids of tensor-product
|
||||
patches. Subdivision surfaces generalize these to control grids with arbitrary
|
||||
connectivity.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
@ -120,16 +122,17 @@ A vertex is disconnected from any edge and face.
|
||||
:align: center
|
||||
:target: images/nonmanifold_vert.png
|
||||
|
||||
This case is fairly trivial: there is no possible way to exact a limit surface here,
|
||||
so the vertex simply has to be flagged as non-contributing, or discarded gracefully.
|
||||
This case is fairly trivial: there is no possible way to exact a limit surface
|
||||
here, so the vertex simply has to be flagged as non-contributing, or discarded
|
||||
gracefully.
|
||||
|
||||
----
|
||||
|
||||
Boundary Interpolation Rules
|
||||
============================
|
||||
|
||||
Boundary interpolation rules control how boundary face edges and facevarying data
|
||||
are interpolated.
|
||||
Boundary interpolation rules control how boundary face edges and face-varying
|
||||
data are interpolated.
|
||||
|
||||
Vertex Data
|
||||
***********
|
||||
@ -158,25 +161,25 @@ On a quad example:
|
||||
:target: images/vertex_boundary.png
|
||||
|
||||
|
||||
Facevarying Data
|
||||
****************
|
||||
Face-varying Data
|
||||
*****************
|
||||
|
||||
The following rule sets can be applied to facevarying data interpolation:
|
||||
The following rule sets can be applied to face-varying data interpolation:
|
||||
|
||||
+--------+----------------------------------------------------------+
|
||||
| Mode | Behavior |
|
||||
+========+==========================================================+
|
||||
| 0 | Bilinear interpolation (no smoothing) |
|
||||
| 0 | Bi-linear interpolation (no smoothing) |
|
||||
+--------+----------------------------------------------------------+
|
||||
| 1 | Smooth UV |
|
||||
| | |
|
||||
| | |
|
||||
+--------+----------------------------------------------------------+
|
||||
| 2 | Same as (1) but does not infer the presence of corners |
|
||||
| | where two facevarying edges meet at a single faceA |
|
||||
| | where two face-varying edges meet at a single faceA |
|
||||
| | |
|
||||
+--------+----------------------------------------------------------+
|
||||
| 3 | Smooths facevarying values only near vertices that are |
|
||||
| 3 | Smooth face-varying values only near vertices that are |
|
||||
| | not at a discontinuous boundary; all vertices on a |
|
||||
| | discontinuous boundary are subdivided with a sharp rule |
|
||||
| | (interpolated through). |
|
||||
@ -193,32 +196,32 @@ Unwrapped cube example:
|
||||
Propagate Corners
|
||||
+++++++++++++++++
|
||||
|
||||
Facevarying interpolation mode 2 (*EdgeAndCorner*) can further be modified by the
|
||||
application of the *Propagate Corner* flag.
|
||||
Face-varying interpolation mode 2 (*EdgeAndCorner*) can further be modified by
|
||||
the application of the *Propagate Corner* flag.
|
||||
|
||||
----
|
||||
|
||||
Semi-Sharp Creases
|
||||
==================
|
||||
|
||||
It is possible to modify the subdivision rules to create piecewise smooth surfaces
|
||||
containing infinitely sharp features such as creases and corners. As a special
|
||||
case, surfaces can be made to interpolate their boundaries by tagging their boundary
|
||||
edges as sharp.
|
||||
It is possible to modify the subdivision rules to create piecewise smooth
|
||||
surfaces containing infinitely sharp features such as creases and corners. As a
|
||||
special case, surfaces can be made to interpolate their boundaries by tagging
|
||||
their boundary edges as sharp.
|
||||
|
||||
However, we've recognized that real world surfaces never really have infinitely
|
||||
sharp edges, especially when viewed sufficiently close. To this end, we've added
|
||||
the notion of semi-sharp creases, i.e. rounded creases of controllable sharpness.
|
||||
These allow you to create features that are more akin to fillets and blends. As
|
||||
you tag edges and edge chains as creases, you also supply a sharpness value that
|
||||
ranges from 0-10, with sharpness values >=10 treated as infinitely sharp.
|
||||
|
||||
It should be noted that infinitely sharp creases are really tangent discontinuities
|
||||
in the surface, implying that the geometric normals are also discontinuous there.
|
||||
Therefore, displacing along the normal will likely tear apart the surface along
|
||||
the crease. If you really want to displace a surface at a crease, it may be better
|
||||
to make the crease semi-sharp.
|
||||
sharp edges, especially when viewed sufficiently close. To this end, we've
|
||||
added the notion of semi-sharp creases, i.e. rounded creases of controllable
|
||||
sharpness. These allow you to create features that are more akin to fillets and
|
||||
blends. As you tag edges and edge chains as creases, you also supply a
|
||||
sharpness value that ranges from 0-10, with sharpness values >=10 treated as
|
||||
infinitely sharp.
|
||||
|
||||
It should be noted that infinitely sharp creases are really tangent
|
||||
discontinuities in the surface, implying that the geometric normals are also
|
||||
discontinuous there. Therefore, displacing along the normal will likely tear
|
||||
apart the surface along the crease. If you really want to displace a surface at
|
||||
a crease, it may be better to make the crease semi-sharp.
|
||||
|
||||
.. image:: images/gtruck.jpg
|
||||
:align: center
|
||||
@ -231,7 +234,7 @@ Chaikin Rule
|
||||
============
|
||||
|
||||
Chaikin's curve subdivision algorithm improves the appearance of multi-edge
|
||||
semi-sharp creases with vayring weights. The Chaikin rule interpolates the
|
||||
semi-sharp creases with varying weights. The Chaikin rule interpolates the
|
||||
sharpness of incident edges.
|
||||
|
||||
.. image:: images/chaikin.png
|
||||
@ -243,19 +246,21 @@ sharpness of incident edges.
|
||||
Hierarchical Edits
|
||||
==================
|
||||
|
||||
To understand the hierarchical aspect of subdivision, we realize that subdivision
|
||||
itself leads to a natural hierarchy: after the first level of subdivision, each
|
||||
face in a subdivision mesh subdivides to four quads (in the Catmull-Clark scheme),
|
||||
or four triangles (in the Loop scheme). This creates a parent and child relationship
|
||||
between the original face and the resulting four subdivided faces, which in turn
|
||||
leads to a hierarchy of subdivision as each child in turn subdivides. A hierarchical
|
||||
edit is an edit made to any one of the faces, edges, or vertices that arise anywhere
|
||||
during subdivision. Normally these subdivision components inherit values from their
|
||||
parents based on a set of subdivision rules that depend on the subdivision scheme.
|
||||
To understand the hierarchical aspect of subdivision, we realize that
|
||||
subdivision itself leads to a natural hierarchy: after the first level of
|
||||
subdivision, each face in a subdivision mesh subdivides to four quads (in the
|
||||
Catmull-Clark scheme), or four triangles (in the Loop scheme). This creates a
|
||||
parent and child relationship between the original face and the resulting four
|
||||
subdivided faces, which in turn leads to a hierarchy of subdivision as each
|
||||
child in turn subdivides. A hierarchical edit is an edit made to any one of the
|
||||
faces, edges, or vertices that arise anywhere during subdivision. Normally
|
||||
these subdivision components inherit values from their parents based on a set
|
||||
of subdivision rules that depend on the subdivision scheme.
|
||||
|
||||
A hierarchical edit overrides these values. This allows for a compact specification
|
||||
of localized detail on a subdivision surface, without having to express information
|
||||
about the rest of the subdivision surface at the same level of detail.
|
||||
A hierarchical edit overrides these values. This allows for a compact
|
||||
specification of localized detail on a subdivision surface, without having to
|
||||
express information about the rest of the subdivision surface at the same level
|
||||
of detail.
|
||||
|
||||
.. image:: images/hedit_example1.png
|
||||
:align: center
|
||||
@ -267,15 +272,15 @@ about the rest of the subdivision surface at the same level of detail.
|
||||
Hierarchical Edits Paths
|
||||
************************
|
||||
|
||||
In order to perform a hierarchical edit, we need to be able to name the subdivision
|
||||
component we are interested in, no matter where it may occur in the subdivision
|
||||
hierarchy. This leads us to a hierarchical path specification for faces, since
|
||||
once we have a face we can navigate to an incident edge or vertex by association.
|
||||
We note that in a subdivision mesh, a face always has incident vertices, which are
|
||||
labelled (in relation to the face) with an integer index starting at zero and in
|
||||
consecutive order according to the usual winding rules for subdivision surfaces.
|
||||
Faces also have incident edges, and these are labelled according to the origin
|
||||
vertex of the edge.
|
||||
In order to perform a hierarchical edit, we need to be able to name the
|
||||
subdivision component we are interested in, no matter where it may occur in the
|
||||
subdivision hierarchy. This leads us to a hierarchical path specification for
|
||||
faces, since once we have a face we can navigate to an incident edge or vertex
|
||||
by association. We note that in a subdivision mesh, a face always has incident
|
||||
vertices, which are labelled (in relation to the face) with an integer index
|
||||
starting at zero and in consecutive order according to the usual winding rules
|
||||
for subdivision surfaces. Faces also have incident edges, and these are
|
||||
labelled according to the origin vertex of the edge.
|
||||
|
||||
.. image:: images/face_winding.png
|
||||
:align: center
|
||||
@ -285,53 +290,55 @@ vertex of the edge.
|
||||
.. role:: green
|
||||
.. role:: blue
|
||||
|
||||
In this diagram, the indices of the vertices of the base face are marked in :red:`red`;
|
||||
so on the left we have an extraordinary Catmull-Clark face with five vertices
|
||||
(labeled :red:`0-4`) and on the right we have a regular Catmull-Clark face with four
|
||||
vertices (labelled :red:`0-3`). The indices of the child faces are :blue:`blue`; note that in
|
||||
both the extraordinary and regular cases, the child faces are indexed the same
|
||||
way, i.e. the subface labeled :blue:`n` has one incident vertex that is the result of the
|
||||
subdivision of the parent vertex also labeled :red:`n` in the parent face. Specifically,
|
||||
we note that the subface :blue:`1` in both the regular and extraordinary face is nearest
|
||||
to the vertex labelled :red:`1` in the parent.
|
||||
In this diagram, the indices of the vertices of the base face are marked in
|
||||
:red:`red`; so on the left we have an extraordinary Catmull-Clark face with
|
||||
five vertices (labeled :red:`0-4`) and on the right we have a regular
|
||||
Catmull-Clark face with four vertices (labelled :red:`0-3`). The indices of the
|
||||
child faces are :blue:`blue`; note that in both the extraordinary and regular
|
||||
cases, the child faces are indexed the same way, i.e. the sub-face labeled
|
||||
:blue:`n` has one incident vertex that is the result of the subdivision of the
|
||||
parent vertex also labeled :red:`n` in the parent face. Specifically, we note
|
||||
that the sub-face :blue:`1` in both the regular and extraordinary face is
|
||||
nearest to the vertex labelled :red:`1` in the parent.
|
||||
|
||||
The indices of the vertices of the child faces are labeled :green:`green`, and
|
||||
this is where the difference lies between the extraordinary and regular case;
|
||||
in the extraordinary case, vertex to vertex subdivision always results in a vertex
|
||||
labeled :green:`0`, while in the regular case, vertex to vertex subdivision
|
||||
assigns the same index to the child vertex. Again, specifically, we note that the
|
||||
parent vertex indexed :red:`1` in the extraordinary case has a child vertex :green:`0`,
|
||||
while in the regular case the parent vertex indexed :red:`1` actually has a child
|
||||
vertex that is indexed :green:`1`. Note that this indexing scheme was chosen to
|
||||
maintain the property that the vertex labeled 0 always has the lowest u/v
|
||||
parametric value on the face.
|
||||
in the extraordinary case, vertex to vertex subdivision always results in a
|
||||
vertex labeled :green:`0`, while in the regular case, vertex to vertex
|
||||
subdivision assigns the same index to the child vertex. Again, specifically, we
|
||||
note that the parent vertex indexed :red:`1` in the extraordinary case has a
|
||||
child vertex :green:`0`, while in the regular case the parent vertex indexed
|
||||
:red:`1` actually has a child vertex that is indexed :green:`1`. Note that this
|
||||
indexing scheme was chosen to maintain the property that the vertex labeled 0
|
||||
always has the lowest u/v parametric value on the face.
|
||||
|
||||
.. image:: images/hedit_path.gif
|
||||
:align: center
|
||||
:target: images/hedit_path.gif
|
||||
|
||||
By appending a vertex index to a face index, we can create a vertex path
|
||||
specification. For example, (:blue:`655` :green:`2` :red:`3` 0) specifies the 1st.
|
||||
vertex of the :red:`3` rd. child face of the :green:`2` nd. child face of the of
|
||||
the :blue:`655` th. face of the subdivision mesh.
|
||||
specification. For example, (:blue:`655` :green:`2` :red:`3` 0) specifies the
|
||||
1st. vertex of the :red:`3` rd. child face of the :green:`2` nd. child face of
|
||||
the of the :blue:`655` th. face of the subdivision mesh.
|
||||
|
||||
----
|
||||
|
||||
Vertex Edits
|
||||
************
|
||||
|
||||
Vertex hierarchical edits can modify the value or the sharpness of primitive variables for vertices
|
||||
and sub-vertices anywhere in the subdivision hierarchy.
|
||||
Vertex hierarchical edits can modify the value or the sharpness of primitive
|
||||
variables for vertices and sub-vertices anywhere in the subdivision hierarchy.
|
||||
|
||||
.. image:: images/hedit_example1.png
|
||||
:align: center
|
||||
:height: 300
|
||||
:target: images/hedit_example1.png
|
||||
|
||||
The edits are performed using either an "add" or a "set" operator. "set" indicates the primitive
|
||||
variable value or sharpness is to be set directly to the values specified. "add" adds a value to the
|
||||
normal result computed via standard subdivision rules. In other words, this operation allows value
|
||||
offsets to be applied to the mesh at any level of the hierarchy.
|
||||
The edits are performed using either an "add" or a "set" operator. "set"
|
||||
indicates the primitive variable value or sharpness is to be set directly to
|
||||
the values specified. "add" adds a value to the normal result computed via
|
||||
standard subdivision rules. In other words, this operation allows value offsets
|
||||
to be applied to the mesh at any level of the hierarchy.
|
||||
|
||||
.. image:: images/hedit_example2.png
|
||||
:align: center
|
||||
@ -356,15 +363,17 @@ and sub-edges anywhere in the subdivision hierarchy.
|
||||
Face Edits
|
||||
**********
|
||||
|
||||
Face hierarchical edits can modify several properties of faces and sub-faces anywhere in the
|
||||
subdivision hierarchy.
|
||||
Face hierarchical edits can modify several properties of faces and sub-faces
|
||||
anywhere in the subdivision hierarchy.
|
||||
|
||||
Modifiable properties include:
|
||||
* The "set" or "add" operators modify the value of primitive variables associated with faces.
|
||||
* The "hole" operation introduces holes (missing faces) into the subdivision mesh at any
|
||||
level in the subdivision hierarchy. The faces will be deleted, and none of their children
|
||||
will appear (you cannot "unhole" a face if any ancestor is a "hole"). This operation takes
|
||||
no float or string arguments.
|
||||
|
||||
* The "set" or "add" operators modify the value of primitive variables
|
||||
associated with faces.
|
||||
* The "hole" operation introduces holes (missing faces) into the subdivision
|
||||
mesh at any level in the subdivision hierarchy. The faces will be deleted,
|
||||
and none of their children will appear (you cannot "unhole" a face if any
|
||||
ancestor is a "hole"). This operation takes no float or string arguments.
|
||||
|
||||
.. image:: images/hedit_example5.png
|
||||
:align: center
|
||||
@ -377,7 +386,8 @@ Modifiable properties include:
|
||||
Limitations
|
||||
***********
|
||||
|
||||
XXXX
|
||||
.. include:: under_development.rst
|
||||
|
||||
|
||||
----
|
||||
|
||||
@ -417,7 +427,7 @@ Main features comparison:
|
||||
| Uniform | Feature Adaptive |
|
||||
+=======================================================+========================================================+
|
||||
| | |
|
||||
| * Bilinear approximation | * Bicubic limit patches |
|
||||
| * Bi-linear approximation | * Bi-cubic limit patches |
|
||||
| * No tangents / no normals | * Analytical tangents / normals |
|
||||
| * No smooth shading around creases | |
|
||||
| * No animated displacements | |
|
||||
|
138
documentation/tutorials.rst
Normal file
@ -0,0 +1,138 @@
|
||||
..
|
||||
Copyright 2013 Pixar
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "Apache License")
|
||||
with the following modification; you may not use this file except in
|
||||
compliance with the Apache License and the following modification to it:
|
||||
Section 6. Trademarks. is deleted and replaced with:
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor
|
||||
and its affiliates, except as required to comply with Section 4(c) of
|
||||
the License and to reproduce the content of the NOTICE file.
|
||||
|
||||
You may obtain a copy of the Apache License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the Apache License with the above modification is
|
||||
distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the Apache License for the specific
|
||||
language governing permissions and limitations under the Apache License.
|
||||
|
||||
|
||||
Tutorials
|
||||
---------
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:backlinks: none
|
||||
|
||||
----
|
||||
|
||||
The tutorial source code can be found in the `github.com repository
|
||||
<https://github.com/PixarAnimationStudios/OpenSubdiv/tree/master/tutorials>`__
|
||||
or in your local ``<repository root>/turorials``.
|
||||
|
||||
----
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<style> .line {text-align:justify;} </style>
|
||||
|
||||
----
|
||||
|
||||
.. |far_tut_0| image:: images/far_tutorial_0.0.png
|
||||
:width: 100px
|
||||
:target: images/far_tutorial_0.0.png
|
||||
|
||||
.. |far_tut_1| image:: images/far_tutorial_1.0.png
|
||||
:width: 100px
|
||||
:target: images/far_tutorial_1.0.png
|
||||
|
||||
.. |far_tut_3| image:: images/far_tutorial_3.0.png
|
||||
:width: 100px
|
||||
:target: images/far_tutorial_3.0.png
|
||||
|
||||
.. list-table:: **Far Tutorials**
|
||||
:class: quickref
|
||||
:widths: 50 50
|
||||
|
||||
* - | **Tutorial 0**
|
||||
| This tutorial presents in a very succint way the requisite steps to
|
||||
instantiate a Far mesh from simple topological data.
|
||||
| |far_tut_0|
|
||||
|
|
||||
| **Tutorial 1**
|
||||
| This tutorial shows how to interface a high-level topology representation
|
||||
with Far for better efficiency. In tutorial 0, we showed how to instantiate
|
||||
topology from a simple face-vertex list. Here we will show how to take
|
||||
advantage of more complex data structures.
|
||||
|
|
||||
| **Tutorial 2**
|
||||
| Building on tutorial 0, this example shows how to instantiate a simple mesh,
|
||||
refine it uniformly and then interpolate both 'vertex' and 'varying' primvar
|
||||
data.
|
||||
| |far_tut_1|
|
||||
|
|
||||
- | **Tutorial 3**
|
||||
| Building on tutorial 0, this example shows how to instantiate a simple mesh,
|
||||
refine it uniformly and then interpolate both 'vertex' and 'face-varying'
|
||||
primvar data.
|
||||
The resulting interpolated data is output as an 'obj' file, with the
|
||||
'face-varying' data recorded in the uv texture layout.
|
||||
| |far_tut_3|
|
||||
|
|
||||
| **Tutorial 4**
|
||||
| This tutorial shows how to create and manipulate FarStencilTables. We use the
|
||||
factorized stencils to interpolate vertex primvar data buffers.
|
||||
|
|
||||
| **Tutorial 5**
|
||||
| This tutorial shows how to create and manipulate both 'vertex' and 'varying'
|
||||
FarStencilTables to interpolate 2 primvar data buffers: vertex positions and
|
||||
vertex colors.
|
||||
|
|
||||
|
||||
----
|
||||
|
||||
.. list-table:: **Osd Tutorials**
|
||||
:class: quickref
|
||||
:widths: 50 50
|
||||
|
||||
* - | **Tutorial 0**
|
||||
| This tutorial demonstrates the manipulation of Osd 'Compute' 'Contexts' and
|
||||
'Controllers'.
|
||||
|
|
||||
- |
|
||||
|
||||
.. |hbr_tut_2| image:: images/hbr_tutorial_2.0.png
|
||||
:width: 100px
|
||||
:target: images/hbr_tutorial_2.0.png
|
||||
|
||||
.. list-table:: **Hbr Tutorials**
|
||||
:class: quickref
|
||||
:widths: 50 50
|
||||
|
||||
* - | **Tutorial 0**
|
||||
| This tutorial presents, in a very succint way, the requisite steps to
|
||||
instantiate an Hbr mesh from simple topological data.
|
||||
|
|
||||
| **Tutorial 1**
|
||||
| This tutorial shows how to safely create Hbr meshes from arbitrary topology.
|
||||
Because Hbr is a half-edge data structure, it cannot represeent non-manifold
|
||||
topology. Ensuring that the geometry used is manifold is a requirement to use
|
||||
Hbr safely. This tutorial presents some simple tests to detect inappropriate
|
||||
topology.
|
||||
|
|
||||
- | **Tutorial 2**
|
||||
| This tutorial shows how to subdivide uniformly a simple Hbr mesh. We are
|
||||
building upon previous turtorials and assuming a fully instantiated mesh:
|
||||
we start with an HbrMesh pointer initialized from the same pyramid shape
|
||||
used in hbr_tutorial_0. We then apply the Refine() function sequentially
|
||||
to all the faces in the mesh to generate several levels of uniform
|
||||
subdivision. The resulting data is then dumped to the terminal in Wavefront
|
||||
OBJ format for inspection.
|
||||
| |hbr_tut_2|
|
||||
|
|
||||
|
10
documentation/under_development.rst
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
.. container:: notebox
|
||||
|
||||
Content under development....
|
||||
|
||||
.. image:: images/construction.png
|
||||
:align: center
|
||||
:height: 100
|
||||
|
||||
|
@ -29,22 +29,35 @@ Using OpenSubdiv
|
||||
:local:
|
||||
:backlinks: none
|
||||
|
||||
.. image:: images/barb_1.jpg
|
||||
:width: 400px
|
||||
.. image:: images/osd_splash.png
|
||||
:align: center
|
||||
:target: images/osd_splash.png
|
||||
|
||||
Using OpenSubdiv
|
||||
================
|
||||
OpenSubdiv APIs
|
||||
===============
|
||||
|
||||
.. list-table:: **OpenGL examples**
|
||||
.. list-table:: **APIs Overview**
|
||||
:class: quickref
|
||||
:widths: 50 50
|
||||
|
||||
* - | `Overview <api_overview.html>`_
|
||||
- | `Osd API <osd_overview.html>`_
|
||||
| `Far API <far_overview.html>`_
|
||||
| `Vtr API <vtr_overview.html>`_
|
||||
| `Sdc API <sdc_overview.html>`_
|
||||
|
|
||||
|
||||
|
||||
|
||||
Coding With OpenSubdiv
|
||||
======================
|
||||
|
||||
.. list-table:: **General Topics**
|
||||
:class: quickref
|
||||
:widths: 50 50
|
||||
|
||||
* - | `Compiling & Linking <using_osd_compile.html>`_
|
||||
| `Textures <using_osd_textures.html>`_
|
||||
- | `Manipulating Topology <using_osd_hbr.html>`_
|
||||
|
||||
|
|
||||
|
||||
|
||||
| `Tutorials <tutorials.html>`_
|
||||
- | Writing Shaders
|
||||
| `Textures (UV & Ptex) <using_osd_textures.html>`_
|
||||
|
||||
|
@ -32,6 +32,19 @@ Using Hbr
|
||||
|
||||
----
|
||||
|
||||
.. container:: notebox
|
||||
|
||||
**Note**
|
||||
|
||||
As of OpenSubdiv 3.0, all **Hbr** dependencies have been removed from the
|
||||
core APIs (**Sdc**, **Vtr**, **Far**, **Osd**). The legacy source code of
|
||||
**Hbr** is provided purely for regression and legacy purposes. If your code
|
||||
is currently depending on Hbr functionaliy, we recommend migrating to the
|
||||
newer APIs as we cannot guarantee that this code will be maintained in
|
||||
future releases.
|
||||
For more information see the `3.0 release notes <release_notes.html>`_
|
||||
|
||||
|
||||
Vertex Template API
|
||||
===================
|
||||
|
||||
@ -100,29 +113,25 @@ does not support arbitrary variables or varying interpolation.
|
||||
|
||||
In some cases, if only topological analysis is required, the class can be left un-implemented.
|
||||
Far and Osd for instance store vertex data in serialized interleaved vectors. Here
|
||||
is the OsdVertex class for reference:
|
||||
is the Osd::Vertex class for reference:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
class OsdVertex {
|
||||
class Vertex {
|
||||
public:
|
||||
OsdVertex() {}
|
||||
Vertex() {}
|
||||
|
||||
OsdVertex(int index) {}
|
||||
Vertex(int /* index */) {}
|
||||
|
||||
OsdVertex(OsdVertex const & src) {}
|
||||
Vertex(Vertex const & /* src */) {}
|
||||
|
||||
void AddWithWeight(OsdVertex const & i, float weight, void * = 0) {}
|
||||
void AddWithWeight(Vertex const & /* i */, float /* weight */, void * = 0) {}
|
||||
|
||||
void AddVaryingWithWeight(const OsdVertex & i, float weight, void * = 0) {}
|
||||
void AddVaryingWithWeight(const Vertex & /* i */, float /* weight */, void * = 0) {}
|
||||
|
||||
void Clear(void * = 0) {}
|
||||
|
||||
void ApplyVertexEdit(HbrVertexEdit<OsdVertex> const &) { }
|
||||
|
||||
void ApplyVertexEdit(FarVertexEdit const &) { }
|
||||
|
||||
void ApplyMovingVertexEdit(HbrMovingVertexEdit<OsdVertex> const &) { }
|
||||
};
|
||||
|
||||
|
||||
|
@ -37,7 +37,6 @@ Ptex Face Indices
|
||||
:align: center
|
||||
:target: images/ptex_coarse.png
|
||||
|
||||
|
||||
Non-quad topology
|
||||
_________________
|
||||
|
||||
@ -48,3 +47,6 @@ _________________
|
||||
|
||||
Filtering
|
||||
_________
|
||||
|
||||
.. include:: under_development.rst
|
||||
|
||||
|
238
documentation/vtr_overview.rst
Normal file
@ -0,0 +1,238 @@
|
||||
..
|
||||
Copyright 2013 Pixar
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "Apache License")
|
||||
with the following modification; you may not use this file except in
|
||||
compliance with the Apache License and the following modification to it:
|
||||
Section 6. Trademarks. is deleted and replaced with:
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor
|
||||
and its affiliates, except as required to comply with Section 4(c) of
|
||||
the License and to reproduce the content of the NOTICE file.
|
||||
|
||||
You may obtain a copy of the Apache License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the Apache License with the above modification is
|
||||
distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the Apache License for the specific
|
||||
language governing permissions and limitations under the Apache License.
|
||||
|
||||
|
||||
Vtr Overview
|
||||
------------
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:backlinks: none
|
||||
|
||||
.. image:: images/api_layers_3_0.png
|
||||
:width: 100px
|
||||
:target: images/api_layers_3_0.png
|
||||
|
||||
Vectorized Topology Representation (Vtr)
|
||||
========================================
|
||||
|
||||
*Vtr* consists of a suite of classes that collectively provide an intermediate
|
||||
representation of topology that supports efficient refinement. *Vtr* is
|
||||
intended for internal use only and is currently accessed through the *Far*
|
||||
layer by the `Far::TopologyRefiner <far_overview.html>`__, which assembles
|
||||
these *Vtr* classes to meet the topological and refinement needs of the *Far*
|
||||
layer.
|
||||
|
||||
*Vtr* is vectorized in that its topological data is stored more as a collection of
|
||||
vectors of primitive elements rather than as the faces, vertices and edges that
|
||||
make up many other topological representations. It is essentially a
|
||||
structure-of-arrays (SOA) approach to topology in contrast to the more common
|
||||
array-of-structures pattern found in many other topological representations.
|
||||
Vtr's use of vectors allows it to be fairly efficient in its use of memory and
|
||||
similarly efficient to refine, but the topology is fixed once defined.
|
||||
|
||||
*Vtr* classes are purely topological. They are even more independent of the
|
||||
representation of vertices, faces, etc. than Hbr in that they are not even
|
||||
parameterized by an interface to such components. So the same set of Vtr
|
||||
objects can eventually be used to serve more than one representation of these
|
||||
components. The primary requirement is that a mesh be expressable as an
|
||||
indexable set (i.e. a vector or array) of vertices, edges and faces. The index
|
||||
of a component uniquely identifies it and properties are retrieved by referring
|
||||
to it by index.
|
||||
|
||||
The two primary classes in *Vtr* consist of:
|
||||
|
||||
* `Vtr::Level <#vtrlevel>`__ - a class representing complete vertex topology
|
||||
for a level
|
||||
* `Vtr::Refinement <#vtrrefinement>`__ - a class mapping a parent *Vtr::Level*
|
||||
to a child level
|
||||
|
||||
Others exist to represent the following:
|
||||
|
||||
* selection and appropriate tagging of components for sparse refinement
|
||||
* divergence of face-varying topology from the vertex topology
|
||||
* mapping between face-varying topology at successive levels
|
||||
* common low-level utilities, e.g. simple array classes
|
||||
|
||||
Contents along with current issues being addressed. More details may be
|
||||
provided in the headers themselves.
|
||||
|
||||
|
||||
.. container:: notebox
|
||||
|
||||
**Alpha Issues**
|
||||
|
||||
Being intended for internal use, any changes to *Vtr* should not impact public
|
||||
interfaces. Regardless, its worth noting some of the work planned:
|
||||
|
||||
* support for tri-split refinement required by Loop subdivision
|
||||
* addition of more per-component tags to propogate with refinement
|
||||
(e.g. holes, etc.)
|
||||
* encapsulation of any scheme-specific code into classes specific to the
|
||||
schemes
|
||||
* potential nesting of FVar classes within *Level* and *Refinement*
|
||||
* potential specializations for regular *Levels* and *Refinements*
|
||||
|
||||
Priority will be given to satisfying functional needs.
|
||||
|
||||
|
||||
Vtr::Level
|
||||
==========
|
||||
|
||||
*Vtr::Level* is a complete topological description of a subdivision level, with the
|
||||
topological relations, sharpness values and component tags all stored in
|
||||
vectors (literally std::vectors, but easily changed via typedefs). There are no
|
||||
classes or objects for the mesh component types (i.e. faces, edges and
|
||||
vertices) but simply an integer index to identify each. It can be viewed as a
|
||||
structure-of-arrays representation of the topology: any property related to a
|
||||
particular component is stored in an array and accessible using the index
|
||||
identifying that component. So with no classes the for the components, its
|
||||
difficult to say what constitutes a "vertex" or a "face": they are each the sum
|
||||
of all the fields scattered amongst the many vectors included.
|
||||
|
||||
*Level* represents a single level of a potential hierarchy and is capable of
|
||||
representing the complete base mesh. There are no members that relate data in
|
||||
one level to any other, either below or above. As such, any *Level* can be
|
||||
used as the base level for a new subdivision hierarchy (potentially more than
|
||||
one). All relationships between separate levels are maintained in the
|
||||
`Vtr::Refinement <#vtrrefinement>`__ class.
|
||||
|
||||
Topological Relationships
|
||||
*************************
|
||||
|
||||
*Level* requires the definition of and associations between a fixed set of
|
||||
indexable components for all three component types, i.e. an explicit edge list
|
||||
in addition to the expected set of vertices and faces. There are no explicit
|
||||
component objects in the representation, only an integer index (*Vtr::Index*)
|
||||
identifying each component within the set and data associated with that
|
||||
component in the various vectors.
|
||||
|
||||
The topology is stored as six sets of incident relations between the components:
|
||||
two each for the two other component types incident each component type, i.e.:
|
||||
|
||||
* for each face, its incident vertices and incident edges
|
||||
* for each edge, its incident vertices and incident faces
|
||||
* for each vertex, its incident edges and incident faces
|
||||
|
||||
The collection of incidence relations is a vectorized variation of AIF (the
|
||||
"Adjacency and Incidence Framework"). The set of these six incidence relations
|
||||
is not minimal (only four are required, but that set excludes the most desired
|
||||
face-vertex relation) but all six are kept and maintained to facilitate faster
|
||||
refinement. While the sizes of several vectors are directly proportional to the
|
||||
number of vertices, edges or faces to which the data is associated, the sizes
|
||||
of some of the vectors for these relations is more cumulative and so additional
|
||||
vectors of offsets is required (typical of the face-vertex list commonly used
|
||||
as the minimal definition of mesh topology).
|
||||
|
||||
Vectors for the sharpness values associated with crease edges and corner
|
||||
vertices are included (and so sized according to the number of edges and
|
||||
vertices), along with additional tags for the components that may be helpful to
|
||||
refinement (i.e. the type of subdivision Rule associated with each vertex).
|
||||
|
||||
A *Level* is really just a container for data in a subdivision level, and so
|
||||
its public methods are primarily to access that data. Modification of the data
|
||||
is protected and only made available to classes that are intended to construct
|
||||
*Levels*: currently the *Far* factory class that is responsible for building the
|
||||
base level, and the `Vtr::Refinement <#vtrrefinement>`__ class that constructs
|
||||
subsequent levels during refinement.
|
||||
|
||||
Memory Efficiency
|
||||
*****************
|
||||
|
||||
One of the advantages in storing data in what is essentially a
|
||||
structure-of-arrays, rather than the array-of-structures more typical of
|
||||
topological representations, is that we can be more selective about memory
|
||||
usage in some cases. Particularly in the case of uniform refinement, when the
|
||||
data in subsequent levels is typically 4x its predecessor, we can minimize what
|
||||
we either generate or keep around at each level. For instance, if only a
|
||||
face-list is required at the finest level, we only need to generate one of the
|
||||
six topological relations: the vertices incident each face. When we do keep
|
||||
*Levels* around in memory (as is the case with the `Far::TopologyRefiner
|
||||
<far_overview.html>`__) we do have do have the opportunity to prune what is not
|
||||
strictly necessary after the refinement. Just as with construction, whatever
|
||||
classes are privileged to construct a *Level* are likely those that will be
|
||||
privileged to prune its contents when needed.
|
||||
|
||||
|
||||
Vtr::Refinement
|
||||
===============
|
||||
|
||||
While `Vtr::Level <#vtrlevel>`__ contains the topology for a subdivision level,
|
||||
*Vtr::Refinement* is responsible for creating a new level via refinement of an
|
||||
existing one, and for maintaining the relationships between the components in
|
||||
the parent and child levels. So a simplified view of a subdivision hierarchy
|
||||
with *Vtr* is a set of *Levels* with a *Refinement* between each
|
||||
successive pair.
|
||||
|
||||
.. image:: images/vtr_refinement.1.png
|
||||
:align: center
|
||||
:target: images/vtr_refinement.1.png
|
||||
|
||||
|
||||
*Refinement* is a friend of *Level* and will populate a child level from
|
||||
a parent given a set of refinement parameters. Aside from parameters related
|
||||
to data or depth, there are two kinds of refinement supported: uniform and
|
||||
sparse. The latter sparse refinement requires selection of an arbitrary set of
|
||||
components -- any dependent or *"neighboring"* components that are required for
|
||||
the limit will be automatically included. So feature-adaptive refinement is
|
||||
just one form of this selective sparse refinement, the criteria being the
|
||||
topological features of interest (creases and extra-ordinary vertices). The
|
||||
intent is to eventually provide more flexibility to facilitate the refinement
|
||||
of particular regions of interest or more dynamic/adaptive needs.
|
||||
|
||||
Parent-child and child-parent relationships
|
||||
*******************************************
|
||||
|
||||
While *Refinement* populates a new child *Level* as part of its refinement
|
||||
operation, it also accumulates the relationships between the parent and child
|
||||
level (and as with *Level*, this data is stored in vectors indexable by the
|
||||
components).
|
||||
|
||||
The associations between components in the two levels was initially only
|
||||
uni-directional: child components were associated with incident components
|
||||
of a parent component based on the parent components topology, so we had a
|
||||
parent-to-child mapping (one to many). Storing the reverse child-to-parent
|
||||
mapping was avoided to reduce memory (particularly in the case of uniform
|
||||
refinement) as it often was not necessary, but a growing need for it,
|
||||
particularly in the case of sparse feature-adaptive refinement, lead to it
|
||||
being included.
|
||||
|
||||
Data flexibility
|
||||
****************
|
||||
|
||||
One of the advantages of the structure-of-arrays representation in both
|
||||
*Level* and *Refinement* is that we can make more dynamic choices about what
|
||||
type of data we choose to allocate and use based on needs. For instance, we can
|
||||
choose between maintaining the parent-child or child-parent mapping in
|
||||
*Refinement*, or both if needed, and we can remove one if no longer
|
||||
necessary. An active example of this is uniform refinement: if we only require
|
||||
the face-vertex list at the finest subdivision level, there is no need to
|
||||
generate a complete topological description of that level (as would be required
|
||||
of more traditional representations), and given that level is 4x the magnitude
|
||||
of its parent, the savings are considerable.
|
||||
|
||||
Currently there is nothing specific to a subdivision scheme in the refinement
|
||||
other than the type of topological splitting to apply. The refinement does
|
||||
subdivide sharpness values for creasing, but that too is independent of scheme.
|
||||
Tags were added to the base level that are propagated through the refinement
|
||||
and these too are dependent on the scheme, but are applied externally.
|
@ -23,80 +23,77 @@
|
||||
#
|
||||
|
||||
|
||||
add_subdirectory(common)
|
||||
|
||||
if( OPENGL_FOUND AND (GLEW_FOUND AND GLFW_FOUND) OR (APPLE AND GLFW_FOUND))
|
||||
if (NOT NO_OPENGL)
|
||||
if (OPENGL_FOUND AND (GLEW_FOUND AND GLFW_FOUND) OR (APPLE AND GLFW_FOUND))
|
||||
|
||||
# optional dependency - enables screenshots in some examples
|
||||
find_package(PNG)
|
||||
if (PNG_FOUND)
|
||||
include_directories("${PNG_INCLUDE_DIRS}")
|
||||
list(APPEND PLATFORM_LIBRARIES "${PNG_LIBRARIES}")
|
||||
add_definitions(-DOPENSUBDIV_HAS_PNG)
|
||||
# optional dependency - enables screenshots in some examples
|
||||
find_package(PNG)
|
||||
if (PNG_FOUND)
|
||||
include_directories("${PNG_INCLUDE_DIRS}")
|
||||
list(APPEND PLATFORM_LIBRARIES "${PNG_LIBRARIES}")
|
||||
add_definitions(-DOPENSUBDIV_HAS_PNG)
|
||||
endif()
|
||||
|
||||
|
||||
add_subdirectory(glViewer)
|
||||
add_subdirectory(glEvalLimit)
|
||||
add_subdirectory(glShareTopology)
|
||||
add_subdirectory(glFVarViewer)
|
||||
#add_subdirectory(glStencilViewer)
|
||||
|
||||
if (CMAKE_COMPILER_IS_CLANGCC)
|
||||
# This code is intended for debugging only
|
||||
# and currently only compiles with Clang.
|
||||
add_subdirectory(vtrViewer)
|
||||
endif()
|
||||
|
||||
if (OPENGL_4_3_FOUND AND (NOT APPLE))
|
||||
add_subdirectory(glPaintTest)
|
||||
endif()
|
||||
|
||||
if (PTEX_FOUND)
|
||||
add_subdirectory(glPtexViewer)
|
||||
endif()
|
||||
|
||||
else()
|
||||
|
||||
set(MISSING "")
|
||||
|
||||
if (NOT OPENGL_FOUND)
|
||||
list(APPEND MISSING OpenGL)
|
||||
endif()
|
||||
|
||||
if (NOT GLEW_FOUND)
|
||||
list(APPEND MISSING glew)
|
||||
endif()
|
||||
|
||||
if (NOT GLFW_FOUND)
|
||||
list(APPEND MISSING glfw)
|
||||
endif()
|
||||
|
||||
message(WARNING
|
||||
"The following libraries could not be found : ${MISSING}. "
|
||||
"The glViewer and ptexViewer examples will not be available. "
|
||||
"If you have these libraries installed, please specify their "
|
||||
"path to cmake (through the GLEW_LOCATION and GLFW_LOCATION "
|
||||
"command line arguments or environment variables)."
|
||||
)
|
||||
endif()
|
||||
|
||||
add_subdirectory(common)
|
||||
|
||||
add_subdirectory(glViewer)
|
||||
add_subdirectory(glBatchViewer)
|
||||
add_subdirectory(glStencilViewer)
|
||||
add_subdirectory(simpleCpu)
|
||||
add_subdirectory(limitEval)
|
||||
add_subdirectory(tessellateObjFile)
|
||||
add_subdirectory(uvViewer)
|
||||
add_subdirectory(facePartition)
|
||||
add_subdirectory(topologySharing)
|
||||
|
||||
if(OPENGL_4_3_FOUND AND (NOT APPLE))
|
||||
add_subdirectory(paintTest)
|
||||
endif()
|
||||
|
||||
if(PTEX_FOUND)
|
||||
add_subdirectory(ptexViewer)
|
||||
endif()
|
||||
|
||||
else()
|
||||
|
||||
set(MISSING "")
|
||||
|
||||
if (NOT OPENGL_FOUND)
|
||||
list(APPEND MISSING OpenGL)
|
||||
endif()
|
||||
|
||||
if (NOT GLEW_FOUND)
|
||||
list(APPEND MISSING glew)
|
||||
endif()
|
||||
|
||||
if (NOT GLFW_FOUND)
|
||||
list(APPEND MISSING glfw)
|
||||
endif()
|
||||
|
||||
message(WARNING
|
||||
"The following libraries could not be found : ${MISSING}. "
|
||||
"The glViewer and ptexViewer examples will not be available. "
|
||||
"If you have these libraries installed, please specify their "
|
||||
"path to cmake (through the GLEW_LOCATION and GLFW_LOCATION "
|
||||
"command line arguments or environment variables)."
|
||||
)
|
||||
endif()
|
||||
|
||||
if(DXSDK_FOUND)
|
||||
if (DXSDK_FOUND)
|
||||
|
||||
add_subdirectory(dxViewer)
|
||||
|
||||
if(PTEX_FOUND)
|
||||
if (PTEX_FOUND)
|
||||
add_subdirectory(dxPtexViewer)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
if(MAYA_FOUND AND (NOT NO_MAYA))
|
||||
add_subdirectory(osdPolySmooth)
|
||||
|
||||
# manuelk: the following plugins are disabled until further notice
|
||||
|
||||
#add_subdirectory(mayaViewer)
|
||||
#if(PTEX_FOUND)
|
||||
#add_subdirectory(mayaPtexViewer)
|
||||
#endif()
|
||||
if (MAYA_FOUND AND (NOT NO_MAYA))
|
||||
add_subdirectory(mayaPolySmooth)
|
||||
endif()
|
||||
|
@ -31,6 +31,7 @@ set(EXAMPLES_COMMON_SOURCE_FILES
|
||||
font_image.cpp
|
||||
hdr_reader.cpp
|
||||
hud.cpp
|
||||
objAnim.cpp
|
||||
patchColors.cpp
|
||||
)
|
||||
|
||||
@ -40,6 +41,7 @@ set(EXAMPLES_COMMON_HEADER_FILES
|
||||
font_image.h
|
||||
hdr_reader.h
|
||||
hud.h
|
||||
objAnim.h
|
||||
patchColors.h
|
||||
simple_math.h
|
||||
stopwatch.h
|
||||
|
@ -105,6 +105,8 @@ static bool initCL(cl_context *clContext, cl_command_queue *clQueue)
|
||||
#endif
|
||||
delete[] clPlatformIDs;
|
||||
|
||||
int clDeviceUsed = 0;
|
||||
|
||||
#if defined(__APPLE__)
|
||||
*clContext = clCreateContext(props, 0, NULL, clLogMessagesToStdoutAPPLE, NULL, &ciErrNum);
|
||||
if (ciErrNum != CL_SUCCESS) {
|
||||
@ -122,16 +124,64 @@ static bool initCL(cl_context *clContext, cl_command_queue *clQueue)
|
||||
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);
|
||||
#else
|
||||
|
||||
// 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) {
|
||||
printf("No sharable devices.\n");
|
||||
printf("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);
|
||||
|
||||
*clContext = clCreateContext(props, numDevices, clDevices, NULL, NULL, &ciErrNum);
|
||||
#define GL_SHARING_EXTENSION "cl_khr_gl_sharing"
|
||||
|
||||
// find a device that supports sharing with GL (SLI / X-fire configurations)
|
||||
bool sharingSupported=false;
|
||||
for (int i=0; i<(int)numDevices; ++i) {
|
||||
|
||||
size_t extensionSize;
|
||||
ciErrNum = clGetDeviceInfo(clDevices[i], CL_DEVICE_EXTENSIONS, 0, NULL, &extensionSize );
|
||||
if (ciErrNum != CL_SUCCESS) {
|
||||
printf("Error %d in clGetDeviceInfo\n", ciErrNum);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (extensionSize>0) {
|
||||
char* extensions = (char*)malloc(extensionSize);
|
||||
ciErrNum = clGetDeviceInfo(clDevices[i], CL_DEVICE_EXTENSIONS, extensionSize, extensions, &extensionSize);
|
||||
if (ciErrNum != CL_SUCCESS) {
|
||||
printf("Error %d in clGetDeviceInfo\n", ciErrNum);
|
||||
return false;
|
||||
}
|
||||
std::string stdDevString(extensions);
|
||||
free(extensions);
|
||||
size_t szOldPos = 0, szSpacePos = stdDevString.find(' ', szOldPos); // extensions string is space delimited
|
||||
while (szSpacePos != stdDevString.npos) {
|
||||
if (strcmp(GL_SHARING_EXTENSION,
|
||||
stdDevString.substr(szOldPos, szSpacePos - szOldPos).c_str())==0) {
|
||||
clDeviceUsed = i;
|
||||
sharingSupported = true;
|
||||
break;
|
||||
}
|
||||
do {
|
||||
szOldPos = szSpacePos + 1;
|
||||
szSpacePos = stdDevString.find(' ', szOldPos);
|
||||
} while (szSpacePos == szOldPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (not sharingSupported) {
|
||||
printf("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) {
|
||||
printf("Error %d in clCreateContext\n", ciErrNum);
|
||||
delete[] clDevices;
|
||||
@ -139,7 +189,7 @@ static bool initCL(cl_context *clContext, cl_command_queue *clQueue)
|
||||
}
|
||||
#endif
|
||||
|
||||
*clQueue = clCreateCommandQueue(*clContext, clDevices[0], 0, &ciErrNum);
|
||||
*clQueue = clCreateCommandQueue(*clContext, clDevices[clDeviceUsed], 0, &ciErrNum);
|
||||
delete[] clDevices;
|
||||
if (ciErrNum != CL_SUCCESS) {
|
||||
printf("Error %d in clCreateCommandQueue\n", ciErrNum);
|
||||
|
@ -86,9 +86,9 @@ D3D11hud::~D3D11hud()
|
||||
}
|
||||
|
||||
void
|
||||
D3D11hud::Init(int width, int height)
|
||||
D3D11hud::Init(int width, int height, int frameBufferWidth, int frameBufferHeight)
|
||||
{
|
||||
Hud::Init(width, height, width, height);
|
||||
Hud::Init(width, height, frameBufferWidth, frameBufferHeight);
|
||||
|
||||
ID3D11Device *device = NULL;
|
||||
_deviceContext->GetDevice(&device);
|
||||
@ -190,9 +190,9 @@ D3D11hud::Init(int width, int height)
|
||||
}
|
||||
|
||||
void
|
||||
D3D11hud::Rebuild(int width, int height)
|
||||
D3D11hud::Rebuild(int width, int height, int framebufferWidth, int framebufferHeight)
|
||||
{
|
||||
Hud::Rebuild(width, height, width, height);
|
||||
Hud::Rebuild(width, height, framebufferWidth, framebufferHeight);
|
||||
|
||||
SAFE_RELEASE(_staticVbo);
|
||||
|
||||
|
@ -34,9 +34,18 @@ public:
|
||||
D3D11hud(ID3D11DeviceContext *deviceContext);
|
||||
~D3D11hud();
|
||||
|
||||
virtual void Init(int width, int height);
|
||||
void Init(int width, int height) {
|
||||
Init(width, height, width, height);
|
||||
}
|
||||
|
||||
virtual void Rebuild(int width, int 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();
|
||||
|
||||
|
@ -188,7 +188,7 @@ GLFrameBuffer::compileProgram(char const * src, char const * defines) {
|
||||
if (colorMap != -1)
|
||||
glUniform1i(colorMap, 0); // GL_TEXTURE0
|
||||
|
||||
GLint normalMap = glGetUniformLocation(program, "normalMap");
|
||||
GLint colorMap = glGetUniformLocation(program, "normalMap");
|
||||
if (normalMap != -1)
|
||||
glUniform1i(normalMap, 1); // GL_TEXTURE1
|
||||
|
||||
|
@ -33,7 +33,6 @@ class GLhud;
|
||||
class GLFrameBuffer {
|
||||
|
||||
public:
|
||||
|
||||
GLFrameBuffer();
|
||||
|
||||
int GetWidth() const {
|
||||
|
@ -250,4 +250,3 @@ GLhud::Flush()
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,10 @@ public:
|
||||
return _frameBuffer;
|
||||
}
|
||||
|
||||
GLuint GetFontTexture() const {
|
||||
return _fontTexture;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
@ -98,11 +98,11 @@ unsigned char *loadHdr(const char *filename, HdrInfo *info, bool convertToFloat)
|
||||
for (int i = 1; i < n; ++i) {
|
||||
if (buffer[i] == 'X') {
|
||||
if (not (info->flag & HDR_Y_MAJOR)) info->flag |= HDR_X_MAJOR;
|
||||
info->flag |= (buffer[i-1] == '-') ? HDR_X_DEC : 0;
|
||||
info->flag |= (char)((buffer[i-1] == '-') ? HDR_X_DEC : 0);
|
||||
info->width = atoi(&buffer[i+1]);
|
||||
} else if (buffer[i] == 'Y') {
|
||||
if (not (info->flag & HDR_X_MAJOR)) info->flag |= HDR_Y_MAJOR;
|
||||
info->flag |= (buffer[i-1] == '-') ? HDR_Y_DEC : 0;
|
||||
info->flag |= (char)((buffer[i-1] == '-') ? HDR_Y_DEC : 0);
|
||||
info->height = atoi(&buffer[i+1]);
|
||||
}
|
||||
}
|
||||
|
@ -425,7 +425,7 @@ Hud::drawString(std::vector<float> &vboSource,
|
||||
int x, int y, float r, float g, float b, const char *c)
|
||||
{
|
||||
while (*c) {
|
||||
char ch = (*c) & 0x7f;
|
||||
char ch = (char)((*c) & 0x7f);
|
||||
x = drawChar(vboSource, x, y, r, g, b, ch);
|
||||
c++;
|
||||
}
|
||||
@ -488,7 +488,7 @@ Hud::Rebuild(int width, int height, int framebufferWidth, int framebufferHeight)
|
||||
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, ' ');
|
||||
x = drawChar(_staticVboSource, x, y, 1, 1, 1, FONT_RADIO_BUTTON_OFF);
|
||||
drawString(_staticVboSource, x, y, .5f, .5f, .5f, it->label.c_str());
|
||||
}
|
||||
}
|
||||
@ -567,7 +567,7 @@ Hud::Flush()
|
||||
}
|
||||
|
||||
if (_requiresRebuildStatic)
|
||||
Rebuild(_windowWidth, _windowHeight, _framebufferWidth, _framebufferHeight);
|
||||
this->Rebuild(_windowWidth, _windowHeight, _framebufferWidth, _framebufferHeight);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
149
examples/common/objAnim.cpp
Normal file
@ -0,0 +1,149 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "Apache License")
|
||||
// with the following modification; you may not use this file except in
|
||||
// compliance with the Apache License and the following modification to it:
|
||||
// Section 6. Trademarks. is deleted and replaced with:
|
||||
//
|
||||
// 6. Trademarks. This License does not grant permission to use the trade
|
||||
// names, trademarks, service marks, or product names of the Licensor
|
||||
// and its affiliates, except as required to comply with Section 4(c) of
|
||||
// the License and to reproduce the content of the NOTICE file.
|
||||
//
|
||||
// You may obtain a copy of the Apache License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the Apache License with the above modification is
|
||||
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the Apache License for the specific
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
|
||||
#include "objAnim.h"
|
||||
|
||||
#include <../regression/common/shape_utils.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <cmath>
|
||||
#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() or (not _shape)) {
|
||||
//printf("Error: InterpolatePositions on unfit ObjAnim instance\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int nkeys = GetNumKeyframes(),
|
||||
nverts = GetShape()->GetNumVertices();
|
||||
|
||||
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, bool axis) {
|
||||
|
||||
ObjAnim * anim=0;
|
||||
|
||||
Shape const * shape = 0;
|
||||
|
||||
if (not objFiles.empty()) {
|
||||
|
||||
anim = new ObjAnim;
|
||||
|
||||
anim->_positions.reserve(objFiles.size());
|
||||
|
||||
for (int i = 0; i < (int)objFiles.size(); ++i) {
|
||||
|
||||
if (not 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(), kCatmark, axis);
|
||||
|
||||
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;
|
||||
}
|
@ -22,44 +22,45 @@
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#ifndef OBJ_ANIM_H
|
||||
#define OBJ_ANIM_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace shim {
|
||||
struct Shape;
|
||||
|
||||
typedef std::vector<unsigned char> Buffer;
|
||||
class ObjAnim {
|
||||
|
||||
enum DataType {
|
||||
invalid,
|
||||
int8,
|
||||
uint8,
|
||||
int16,
|
||||
uint16,
|
||||
int32,
|
||||
uint32,
|
||||
int64,
|
||||
uint64,
|
||||
int128,
|
||||
uint128,
|
||||
int256,
|
||||
uint256,
|
||||
float16,
|
||||
float32,
|
||||
float64,
|
||||
float80,
|
||||
float96,
|
||||
float128,
|
||||
};
|
||||
public:
|
||||
|
||||
struct HomogeneousBuffer {
|
||||
shim::Buffer Buffer;
|
||||
shim::DataType Type;
|
||||
};
|
||||
// Factory function
|
||||
static ObjAnim const * Create(std::vector<char const *> objFiles, bool axis=true);
|
||||
|
||||
typedef std::vector<shim::DataType> Layout;
|
||||
// Destructor
|
||||
~ObjAnim();
|
||||
|
||||
struct HeterogeneousBuffer {
|
||||
shim::Buffer Buffer;
|
||||
shim::Layout Layout;
|
||||
};
|
||||
}
|
||||
// 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
|
@ -24,38 +24,50 @@
|
||||
|
||||
#include "patchColors.h"
|
||||
|
||||
float const * getAdaptivePatchColor(OpenSubdiv::OsdDrawContext::PatchDescriptor const & desc) {
|
||||
static float _colors[4][5][4] = {{{1.0f, 1.0f, 1.0f, 1.0f}, // regular
|
||||
{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
|
||||
|
||||
static float _colors[4][5][4] = {{{1.0f, 1.0f, 1.0f, 1.0f}, // regular
|
||||
{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
|
||||
{{0.0f, 1.0f, 1.0f, 1.0f}, // regular pattern 0
|
||||
{0.0f, 0.5f, 1.0f, 1.0f}, // regular pattern 1
|
||||
{0.0f, 0.5f, 0.5f, 1.0f}, // regular pattern 2
|
||||
{0.5f, 0.0f, 1.0f, 1.0f}, // regular pattern 3
|
||||
{1.0f, 0.5f, 1.0f, 1.0f}}, // regular pattern 4
|
||||
|
||||
{{0.0f, 1.0f, 1.0f, 1.0f}, // regular pattern 0
|
||||
{0.0f, 0.5f, 1.0f, 1.0f}, // regular pattern 1
|
||||
{0.0f, 0.5f, 0.5f, 1.0f}, // regular pattern 2
|
||||
{0.5f, 0.0f, 1.0f, 1.0f}, // regular pattern 3
|
||||
{1.0f, 0.5f, 1.0f, 1.0f}}, // regular pattern 4
|
||||
{{0.0f, 0.0f, 0.75f, 1.0f}, // boundary pattern 0
|
||||
{0.0f, 0.2f, 0.75f, 1.0f}, // boundary pattern 1
|
||||
{0.0f, 0.4f, 0.75f, 1.0f}, // boundary pattern 2
|
||||
{0.0f, 0.6f, 0.75f, 1.0f}, // boundary pattern 3
|
||||
{0.0f, 0.8f, 0.75f, 1.0f}}, // boundary pattern 4
|
||||
|
||||
{{0.0f, 0.0f, 0.75f, 1.0f}, // boundary pattern 0
|
||||
{0.0f, 0.2f, 0.75f, 1.0f}, // boundary pattern 1
|
||||
{0.0f, 0.4f, 0.75f, 1.0f}, // boundary pattern 2
|
||||
{0.0f, 0.6f, 0.75f, 1.0f}, // boundary pattern 3
|
||||
{0.0f, 0.8f, 0.75f, 1.0f}}, // boundary pattern 4
|
||||
{{0.25f, 0.25f, 0.25f, 1.0f}, // corner pattern 0
|
||||
{0.25f, 0.25f, 0.25f, 1.0f}, // corner pattern 1
|
||||
{0.25f, 0.25f, 0.25f, 1.0f}, // corner pattern 2
|
||||
{0.25f, 0.25f, 0.25f, 1.0f}, // corner pattern 3
|
||||
{0.25f, 0.25f, 0.25f, 1.0f}}}; // corner pattern 4
|
||||
|
||||
{{0.25f, 0.25f, 0.25f, 1.0f}, // corner pattern 0
|
||||
{0.25f, 0.25f, 0.25f, 1.0f}, // corner pattern 1
|
||||
{0.25f, 0.25f, 0.25f, 1.0f}, // corner pattern 2
|
||||
{0.25f, 0.25f, 0.25f, 1.0f}, // corner pattern 3
|
||||
{0.25f, 0.25f, 0.25f, 1.0f}}}; // corner pattern 4
|
||||
typedef OpenSubdiv::Far::PatchTables FarPatchTables;
|
||||
|
||||
typedef OpenSubdiv::FarPatchTables FPT;
|
||||
|
||||
if (desc.GetPattern()==FPT::NON_TRANSITION) {
|
||||
return _colors[0][(int)(desc.GetType()-FPT::REGULAR)];
|
||||
float const *
|
||||
getAdaptivePatchColor(FarPatchTables::Descriptor const & desc) {
|
||||
|
||||
if (desc.GetPattern()==FarPatchTables::NON_TRANSITION) {
|
||||
return _colors[0][(int)(desc.GetType()-FarPatchTables::REGULAR)];
|
||||
} else {
|
||||
return _colors[(int)(desc.GetType()-FPT::REGULAR)+1][(int)desc.GetPattern()-1];
|
||||
return _colors[(int)(desc.GetType()-FarPatchTables::REGULAR)+1][(int)desc.GetPattern()-1];
|
||||
}
|
||||
}
|
||||
|
||||
float const *
|
||||
getAdaptivePatchColor(OpenSubdiv::Osd::DrawContext::PatchDescriptor const & desc) {
|
||||
|
||||
if (desc.GetPattern()==FarPatchTables::NON_TRANSITION) {
|
||||
return _colors[0][(int)(desc.GetType()-FarPatchTables::REGULAR)];
|
||||
} else {
|
||||
return _colors[(int)(desc.GetType()-FarPatchTables::REGULAR)+1][(int)desc.GetPattern()-1];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,8 +27,12 @@
|
||||
|
||||
#include <osd/drawContext.h>
|
||||
|
||||
#include <far/patchTables.h>
|
||||
|
||||
// returns a unique color for each type of feature-adaptive patches
|
||||
float const * getAdaptivePatchColor(OpenSubdiv::OsdDrawContext::PatchDescriptor const & desc);
|
||||
float const * getAdaptivePatchColor(OpenSubdiv::Osd::DrawContext::PatchDescriptor const & desc);
|
||||
|
||||
float const * getAdaptivePatchColor(OpenSubdiv::Far::PatchTables::Descriptor const & desc);
|
||||
|
||||
|
||||
#endif /* COMMON_PATCH_COLORS_H */
|
||||
|
@ -143,7 +143,7 @@ inverseMatrix(float *d, const float *m) {
|
||||
|
||||
float det = m[0] * d[0] + m[1] * d[4] + m[2] * d[8] + m[3] * d[12];
|
||||
|
||||
if (det == 0) return;
|
||||
if (det == 0.0f) return;
|
||||
det = 1.0f / det;
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
@ -154,7 +154,7 @@ 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 / tan(r*0.5f);
|
||||
float t = 1.0f / tanf(r*0.5f);
|
||||
m[0] = t/aspect;
|
||||
m[1] = m[2] = m[3] = 0.0;
|
||||
m[4] = 0.0;
|
||||
@ -205,8 +205,8 @@ inline void
|
||||
rotate(float *m, float angle, float x, float y, float z)
|
||||
{
|
||||
float r = 2 * (float) M_PI * angle/360.0f;
|
||||
float c = cos(r);
|
||||
float s = sin(r);
|
||||
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;
|
||||
|
@ -38,6 +38,8 @@ class Stopwatch {
|
||||
public:
|
||||
|
||||
#ifndef _WINDOWS
|
||||
Stopwatch() : _totalElapsed(0) { }
|
||||
|
||||
void Start() {
|
||||
struct timeval l_rtime;
|
||||
gettimeofday(&l_rtime,0);
|
||||
@ -60,7 +62,7 @@ public:
|
||||
return _totalElapsed;
|
||||
}
|
||||
#else
|
||||
Stopwatch() {
|
||||
Stopwatch() : _totalElapsed(0) {
|
||||
QueryPerformanceFrequency(&_frequency);
|
||||
}
|
||||
|
||||
|
@ -53,6 +53,7 @@ _add_possibly_cuda_executable(dxPtexViewer WIN32
|
||||
"${SOURCE_FILES}"
|
||||
"${SHADER_FILES}"
|
||||
"${INC_FILES}"
|
||||
$<TARGET_OBJECTS:regression_common_obj>
|
||||
$<TARGET_OBJECTS:examples_common_obj>
|
||||
)
|
||||
|
||||
|
@ -34,11 +34,11 @@
|
||||
#include <osd/cpuD3D11VertexBuffer.h>
|
||||
#include <osd/cpuComputeContext.h>
|
||||
#include <osd/cpuComputeController.h>
|
||||
OpenSubdiv::OsdCpuComputeController * g_cpuComputeController = NULL;
|
||||
OpenSubdiv::Osd::CpuComputeController * g_cpuComputeController = NULL;
|
||||
|
||||
#ifdef OPENSUBDIV_HAS_OPENMP
|
||||
#include <osd/ompComputeController.h>
|
||||
OpenSubdiv::OsdOmpComputeController * g_ompComputeController = NULL;
|
||||
OpenSubdiv::Osd::OmpComputeController * g_ompComputeController = NULL;
|
||||
#endif
|
||||
|
||||
#undef OPENSUBDIV_HAS_OPENCL // XXX: dyu OpenCL D3D11 interop needs work...
|
||||
@ -51,7 +51,7 @@ OpenSubdiv::OsdCpuComputeController * g_cpuComputeController = NULL;
|
||||
|
||||
cl_context g_clContext;
|
||||
cl_command_queue g_clQueue;
|
||||
OpenSubdiv::OsdCLComputeController * g_clComputeController = NULL;
|
||||
OpenSubdiv::Osd::CLComputeController * g_clComputeController = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef OPENSUBDIV_HAS_CUDA
|
||||
@ -63,24 +63,24 @@ OpenSubdiv::OsdCpuComputeController * g_cpuComputeController = NULL;
|
||||
#include <cuda_d3d11_interop.h>
|
||||
|
||||
bool g_cudaInitialized = false;
|
||||
OpenSubdiv::OsdCudaComputeController * g_cudaComputeController = NULL;
|
||||
OpenSubdiv::Osd::CudaComputeController * g_cudaComputeController = NULL;
|
||||
#endif
|
||||
|
||||
#include <osd/d3d11VertexBuffer.h>
|
||||
#include <osd/d3d11ComputeContext.h>
|
||||
#include <osd/d3d11ComputeController.h>
|
||||
OpenSubdiv::OsdD3D11ComputeController * g_d3d11ComputeController = NULL;
|
||||
OpenSubdiv::Osd::D3D11ComputeController * g_d3d11ComputeController = NULL;
|
||||
|
||||
#include <osd/d3d11Mesh.h>
|
||||
OpenSubdiv::OsdD3D11MeshInterface *g_mesh;
|
||||
OpenSubdiv::Osd::D3D11MeshInterface *g_mesh;
|
||||
|
||||
#include "Ptexture.h"
|
||||
#include "PtexUtils.h"
|
||||
|
||||
#include <common/vtr_utils.h>
|
||||
#include "../common/stopwatch.h"
|
||||
#include "../common/simple_math.h"
|
||||
#include "../common/d3d11_hud.h"
|
||||
#include "../../regression/common/shape_utils.h"
|
||||
|
||||
static const char *g_shaderSource =
|
||||
#include "shader.gen.h"
|
||||
@ -90,16 +90,13 @@ static const char *g_shaderSource =
|
||||
#include <cfloat>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
|
||||
|
||||
typedef OpenSubdiv::HbrMesh<OpenSubdiv::OsdVertex> OsdHbrMesh;
|
||||
typedef OpenSubdiv::HbrVertex<OpenSubdiv::OsdVertex> OsdHbrVertex;
|
||||
typedef OpenSubdiv::HbrFace<OpenSubdiv::OsdVertex> OsdHbrFace;
|
||||
typedef OpenSubdiv::HbrHalfedge<OpenSubdiv::OsdVertex> OsdHbrHalfedge;
|
||||
|
||||
enum KernelType { kCPU = 0,
|
||||
kOPENMP = 1,
|
||||
kCUDA = 2,
|
||||
@ -220,10 +217,10 @@ float g_animTime = 0;
|
||||
std::vector<float> g_positions,
|
||||
g_normals;
|
||||
|
||||
OpenSubdiv::OsdD3D11PtexMipmapTexture * g_osdPTexImage = 0;
|
||||
OpenSubdiv::OsdD3D11PtexMipmapTexture * g_osdPTexDisplacement = 0;
|
||||
OpenSubdiv::OsdD3D11PtexMipmapTexture * g_osdPTexOcclusion = 0;
|
||||
OpenSubdiv::OsdD3D11PtexMipmapTexture * g_osdPTexSpecular = 0;
|
||||
OpenSubdiv::Osd::D3D11PtexMipmapTexture * g_osdPTexImage = 0;
|
||||
OpenSubdiv::Osd::D3D11PtexMipmapTexture * g_osdPTexDisplacement = 0;
|
||||
OpenSubdiv::Osd::D3D11PtexMipmapTexture * g_osdPTexOcclusion = 0;
|
||||
OpenSubdiv::Osd::D3D11PtexMipmapTexture * g_osdPTexSpecular = 0;
|
||||
const char * g_ptexColorFilename;
|
||||
|
||||
ID3D11Device * g_pd3dDevice = NULL;
|
||||
@ -245,24 +242,28 @@ bool g_bDone = false;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
calcNormals(OsdHbrMesh * mesh, std::vector<float> const & pos, std::vector<float> & result ) {
|
||||
calcNormals(OpenSubdiv::Far::TopologyRefiner * refiner,
|
||||
std::vector<float> const & pos, std::vector<float> & result ) {
|
||||
|
||||
typedef OpenSubdiv::Far::IndexArray IndexArray;
|
||||
|
||||
// calc normal vectors
|
||||
int nverts = (int)pos.size()/3;
|
||||
int nverts = refiner->GetNumVertices(0),
|
||||
nfaces = refiner->GetNumFaces(0);
|
||||
|
||||
int nfaces = mesh->GetNumCoarseFaces();
|
||||
for (int i = 0; i < nfaces; ++i) {
|
||||
OsdHbrFace * f = mesh->GetFace(i);
|
||||
for (int face = 0; face < nfaces; ++face) {
|
||||
|
||||
float const * p0 = &pos[f->GetVertex(0)->GetID()*3],
|
||||
* p1 = &pos[f->GetVertex(1)->GetID()*3],
|
||||
* p2 = &pos[f->GetVertex(2)->GetID()*3];
|
||||
IndexArray fverts = refiner->GetFaceVertices(0, face);
|
||||
|
||||
float const * p0 = &pos[fverts[0]*3],
|
||||
* p1 = &pos[fverts[1]*3],
|
||||
* p2 = &pos[fverts[2]*3];
|
||||
|
||||
float n[3];
|
||||
cross(n, p0, p1, p2);
|
||||
|
||||
for (int j = 0; j < f->GetNumVertices(); j++) {
|
||||
int idx = f->GetVertex(j)->GetID() * 3;
|
||||
for (int vert = 0; vert < fverts.size(); ++vert) {
|
||||
int idx = fverts[vert] * 3;
|
||||
result[idx ] += n[0];
|
||||
result[idx+1] += n[1];
|
||||
result[idx+2] += n[2];
|
||||
@ -318,45 +319,56 @@ updateGeom() {
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
static void
|
||||
fitFrame()
|
||||
{
|
||||
fitFrame() {
|
||||
g_pan[0] = g_pan[1] = 0;
|
||||
g_dolly = g_size;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
template <class T>
|
||||
OpenSubdiv::HbrMesh<T> * createPTexGeo(PtexTexture * r)
|
||||
{
|
||||
PtexMetaData* meta = r->getMetaData();
|
||||
if (meta->numKeys() < 3) return NULL;
|
||||
Shape *
|
||||
createPTexGeo(PtexTexture * r) {
|
||||
|
||||
const float* vp;
|
||||
const int *vi, *vc;
|
||||
PtexMetaData* meta = r->getMetaData();
|
||||
|
||||
if (meta->numKeys() < 3) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
float const * vp;
|
||||
int const *vi, *vc;
|
||||
int nvp, nvi, nvc;
|
||||
|
||||
meta->getValue("PtexFaceVertCounts", vc, nvc);
|
||||
if (nvc == 0)
|
||||
if (nvc == 0) {
|
||||
return NULL;
|
||||
|
||||
}
|
||||
meta->getValue("PtexVertPositions", vp, nvp);
|
||||
if (nvp == 0)
|
||||
if (nvp == 0) {
|
||||
return NULL;
|
||||
|
||||
}
|
||||
meta->getValue("PtexFaceVertIndices", vi, nvi);
|
||||
if (nvi == 0)
|
||||
if (nvi == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static OpenSubdiv::HbrCatmarkSubdivision<T> _catmark;
|
||||
static OpenSubdiv::HbrBilinearSubdivision<T> _bilinear;
|
||||
OpenSubdiv::HbrMesh<T> * mesh;
|
||||
if (g_scheme == 0)
|
||||
mesh = new OpenSubdiv::HbrMesh<T>(&_catmark);
|
||||
else
|
||||
mesh = new OpenSubdiv::HbrMesh<T>(&_bilinear);
|
||||
Shape * shape = new Shape;
|
||||
|
||||
g_positions.clear();
|
||||
g_positions.reserve(nvp);
|
||||
shape->scheme = kCatmark;
|
||||
|
||||
shape->verts.resize(nvp);
|
||||
for (int i=0; i<nvp; ++i) {
|
||||
shape->verts[i] = vp[i];
|
||||
}
|
||||
|
||||
shape->nvertsPerFace.resize(nvc);
|
||||
for (int i=0; i<nvc; ++i) {
|
||||
shape->nvertsPerFace[i] = vc[i];
|
||||
}
|
||||
|
||||
shape->faceverts.resize(nvi);
|
||||
for (int i=0; i<nvi; ++i) {
|
||||
shape->faceverts[i] = vi[i];
|
||||
}
|
||||
|
||||
// compute model bounding
|
||||
float min[3] = {vp[0], vp[1], vp[2]};
|
||||
@ -364,37 +376,18 @@ OpenSubdiv::HbrMesh<T> * createPTexGeo(PtexTexture * r)
|
||||
for (int i = 0; i < nvp/3; ++i) {
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
float v = vp[i*3+j];
|
||||
g_positions.push_back(v);
|
||||
min[j] = std::min(min[j], v);
|
||||
max[j] = std::max(max[j], v);
|
||||
}
|
||||
mesh->NewVertex(i, T());
|
||||
}
|
||||
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
g_center[j] = (min[j] + max[j]) * 0.5f;
|
||||
g_size += (max[j]-min[j])*(max[j]-min[j]);
|
||||
}
|
||||
g_size = sqrtf(g_size);
|
||||
|
||||
const int *fv = vi;
|
||||
for (int i = 0, ptxidx = 0; i < nvc; ++i) {
|
||||
int nv = vc[i];
|
||||
OpenSubdiv::HbrFace<T> * face = mesh->NewFace(nv, (int *)fv, 0);
|
||||
|
||||
face->SetPtexIndex(ptxidx);
|
||||
if (nv != 4)
|
||||
ptxidx += nv;
|
||||
else
|
||||
ptxidx++;
|
||||
|
||||
fv += nv;
|
||||
}
|
||||
mesh->SetInterpolateBoundaryMethod(OpenSubdiv::HbrMesh<T>::k_InterpolateBoundaryEdgeOnly);
|
||||
// set creases here
|
||||
// applyTags<T>( mesh, sh );
|
||||
mesh->Finish();
|
||||
|
||||
return mesh;
|
||||
return shape;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -437,10 +430,10 @@ union Effect {
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::pair<OpenSubdiv::OsdDrawContext::PatchDescriptor, Effect> EffectDesc;
|
||||
typedef std::pair<OpenSubdiv::Osd::DrawContext::PatchDescriptor, Effect> EffectDesc;
|
||||
|
||||
|
||||
class EffectDrawRegistry : public OpenSubdiv::OsdD3D11DrawRegistry<EffectDesc> {
|
||||
class EffectDrawRegistry : public OpenSubdiv::Osd::D3D11DrawRegistry<EffectDesc> {
|
||||
|
||||
protected:
|
||||
virtual ConfigType *
|
||||
@ -474,8 +467,8 @@ EffectDrawRegistry::_CreateDrawSourceConfig(DescType const & desc, ID3D11Device
|
||||
sconfig->commonShader.AddDefine("OSD_FRACTIONAL_ODD_SPACING");
|
||||
|
||||
bool quad = true;
|
||||
if (desc.first.GetType() == OpenSubdiv::FarPatchTables::QUADS ||
|
||||
desc.first.GetType() == OpenSubdiv::FarPatchTables::TRIANGLES) {
|
||||
if (desc.first.GetType() == OpenSubdiv::Far::PatchTables::QUADS ||
|
||||
desc.first.GetType() == OpenSubdiv::Far::PatchTables::TRIANGLES) {
|
||||
sconfig->vertexShader.source = g_shaderSource;
|
||||
sconfig->vertexShader.target = "vs_5_0";
|
||||
sconfig->vertexShader.entry = "vs_main";
|
||||
@ -598,8 +591,8 @@ EffectDrawRegistry::_CreateDrawConfig(
|
||||
ID3D11Device * pd3dDevice,
|
||||
ID3D11InputLayout ** ppInputLayout,
|
||||
D3D11_INPUT_ELEMENT_DESC const * pInputElementDescs,
|
||||
int numInputElements)
|
||||
{
|
||||
int numInputElements) {
|
||||
|
||||
ConfigType * config = BaseRegistry::_CreateDrawConfig(desc.first, sconfig,
|
||||
pd3dDevice, ppInputLayout, pInputElementDescs, numInputElements);
|
||||
assert(config);
|
||||
@ -610,9 +603,9 @@ EffectDrawRegistry::_CreateDrawConfig(
|
||||
EffectDrawRegistry effectRegistry;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
OpenSubdiv::OsdD3D11PtexMipmapTexture *
|
||||
createPtex(const char *filename)
|
||||
{
|
||||
OpenSubdiv::Osd::D3D11PtexMipmapTexture *
|
||||
createPtex(const char *filename) {
|
||||
|
||||
Ptex::String ptexError;
|
||||
printf("Loading ptex : %s\n", filename);
|
||||
|
||||
@ -630,8 +623,8 @@ createPtex(const char *filename)
|
||||
printf("Error in reading %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
OpenSubdiv::OsdD3D11PtexMipmapTexture *osdPtex =
|
||||
OpenSubdiv::OsdD3D11PtexMipmapTexture::Create(g_pd3dDeviceContext,
|
||||
OpenSubdiv::Osd::D3D11PtexMipmapTexture *osdPtex =
|
||||
OpenSubdiv::Osd::D3D11PtexMipmapTexture::Create(g_pd3dDeviceContext,
|
||||
ptex, g_maxMipmapLevels);
|
||||
|
||||
ptex->release();
|
||||
@ -643,9 +636,9 @@ createPtex(const char *filename)
|
||||
return osdPtex;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
createOsdMesh(int level, int kernel)
|
||||
{
|
||||
createOsdMesh(int level, int kernel) {
|
||||
Ptex::String ptexError;
|
||||
PtexTexture *ptexColor = PtexTexture::open(g_ptexColorFilename, ptexError, true);
|
||||
if (ptexColor == NULL) {
|
||||
@ -654,11 +647,37 @@ createOsdMesh(int level, int kernel)
|
||||
}
|
||||
|
||||
// generate Hbr representation from ptex
|
||||
OsdHbrMesh * hmesh = createPTexGeo<OpenSubdiv::OsdVertex>(ptexColor);
|
||||
if (hmesh == NULL) return;
|
||||
Shape * shape = createPTexGeo(ptexColor);
|
||||
if (not shape) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_positions=shape->verts;
|
||||
|
||||
typedef OpenSubdiv::Far::IndexArray IndexArray;
|
||||
|
||||
// create Vtr mesh (topology)
|
||||
OpenSubdiv::Sdc::Type sdctype = GetSdcType(*shape);
|
||||
OpenSubdiv::Sdc::Options sdcoptions = GetSdcOptions(*shape);
|
||||
|
||||
OpenSubdiv::Far::TopologyRefiner * refiner =
|
||||
OpenSubdiv::Far::TopologyRefinerFactory<Shape>::Create(sdctype, sdcoptions, *shape);
|
||||
|
||||
// save coarse topology (used for coarse mesh drawing)
|
||||
|
||||
// create cage edge index
|
||||
int nedges = refiner->GetNumEdges(0);
|
||||
std::vector<int> edgeIndices(nedges*2);
|
||||
for(int i=0; i<nedges; ++i) {
|
||||
IndexArray verts = refiner->GetEdgeVertices(0, i);
|
||||
edgeIndices[i*2 ]=verts[0];
|
||||
edgeIndices[i*2+1]=verts[1];
|
||||
}
|
||||
|
||||
delete shape;
|
||||
|
||||
g_normals.resize(g_positions.size(), 0.0f);
|
||||
calcNormals(hmesh, g_positions, g_normals);
|
||||
calcNormals(refiner, g_positions, g_normals);
|
||||
|
||||
delete g_mesh;
|
||||
g_mesh = NULL;
|
||||
@ -666,35 +685,35 @@ createOsdMesh(int level, int kernel)
|
||||
// Adaptive refinement currently supported only for catmull-clark scheme
|
||||
bool doAdaptive = (g_adaptive != 0 and g_scheme == 0);
|
||||
|
||||
OpenSubdiv::OsdMeshBitset bits;
|
||||
bits.set(OpenSubdiv::MeshAdaptive, doAdaptive);
|
||||
bits.set(OpenSubdiv::MeshPtexData, true);
|
||||
OpenSubdiv::Osd::MeshBitset bits;
|
||||
bits.set(OpenSubdiv::Osd::MeshAdaptive, doAdaptive);
|
||||
bits.set(OpenSubdiv::Osd::MeshPtexData, true);
|
||||
|
||||
int numVertexElements = 6; //g_adaptive ? 3 : 6;
|
||||
int numVaryingElements = 0;
|
||||
|
||||
if (kernel == kCPU) {
|
||||
if (not g_cpuComputeController) {
|
||||
g_cpuComputeController = new OpenSubdiv::OsdCpuComputeController();
|
||||
g_cpuComputeController = new OpenSubdiv::Osd::CpuComputeController();
|
||||
}
|
||||
g_mesh = new OpenSubdiv::OsdMesh<OpenSubdiv::OsdCpuD3D11VertexBuffer,
|
||||
OpenSubdiv::OsdCpuComputeController,
|
||||
OpenSubdiv::OsdD3D11DrawContext>(
|
||||
g_mesh = new OpenSubdiv::Osd::Mesh<OpenSubdiv::Osd::CpuD3D11VertexBuffer,
|
||||
OpenSubdiv::Osd::CpuComputeController,
|
||||
OpenSubdiv::Osd::D3D11DrawContext>(
|
||||
g_cpuComputeController,
|
||||
hmesh,
|
||||
refiner,
|
||||
numVertexElements,
|
||||
numVaryingElements,
|
||||
level, bits, g_pd3dDeviceContext);
|
||||
#ifdef OPENSUBDIV_HAS_OPENMP
|
||||
} else if (kernel == kOPENMP) {
|
||||
if (not g_ompComputeController) {
|
||||
g_ompComputeController = new OpenSubdiv::OsdOmpComputeController();
|
||||
g_ompComputeController = new OpenSubdiv::Osd::OmpComputeController();
|
||||
}
|
||||
g_mesh = new OpenSubdiv::OsdMesh<OpenSubdiv::OsdCpuD3D11VertexBuffer,
|
||||
OpenSubdiv::OsdOmpComputeController,
|
||||
OpenSubdiv::OsdD3D11DrawContext>(
|
||||
g_mesh = new OpenSubdiv::Osd::Mesh<OpenSubdiv::Osd::CpuD3D11VertexBuffer,
|
||||
OpenSubdiv::Osd::OmpComputeController,
|
||||
OpenSubdiv::Osd::D3D11DrawContext>(
|
||||
g_ompComputeController,
|
||||
hmesh,
|
||||
refiner,
|
||||
numVertexElements,
|
||||
numVaryingElements,
|
||||
level, bits, g_pd3dDeviceContext);
|
||||
@ -702,13 +721,13 @@ createOsdMesh(int level, int kernel)
|
||||
#ifdef OPENSUBDIV_HAS_OPENCL
|
||||
} else if (kernel == kCL) {
|
||||
if (not g_clComputeController) {
|
||||
g_clComputeController = new OpenSubdiv::OsdCLComputeController(g_clContext, g_clQueue);
|
||||
g_clComputeController = new OpenSubdiv::Osd::CLComputeController(g_clContext, g_clQueue);
|
||||
}
|
||||
g_mesh = new OpenSubdiv::OsdMesh<OpenSubdiv::OsdCLD3D11VertexBuffer,
|
||||
OpenSubdiv::OsdCLComputeController,
|
||||
OpenSubdiv::OsdD3D11DrawContext>(
|
||||
g_mesh = new OpenSubdiv::Osd::Mesh<OpenSubdiv::Osd::CLD3D11VertexBuffer,
|
||||
OpenSubdiv::Osd::CLComputeController,
|
||||
OpenSubdiv::Osd::D3D11DrawContext>(
|
||||
g_clComputeController,
|
||||
hmesh,
|
||||
refiner,
|
||||
numVertexElements,
|
||||
numVaryingElements,
|
||||
level, bits, g_pd3dDeviceContext);
|
||||
@ -716,26 +735,26 @@ createOsdMesh(int level, int kernel)
|
||||
#ifdef OPENSUBDIV_HAS_CUDA
|
||||
} else if (kernel == kCUDA) {
|
||||
if (not g_cudaComputeController) {
|
||||
g_cudaComputeController = new OpenSubdiv::OsdCudaComputeController();
|
||||
g_cudaComputeController = new OpenSubdiv::Osd::CudaComputeController();
|
||||
}
|
||||
g_mesh = new OpenSubdiv::OsdMesh<OpenSubdiv::OsdCudaD3D11VertexBuffer,
|
||||
OpenSubdiv::OsdCudaComputeController,
|
||||
OpenSubdiv::OsdD3D11DrawContext>(
|
||||
g_mesh = new OpenSubdiv::Osd::Mesh<OpenSubdiv::OsdCudaD3D11VertexBuffer,
|
||||
OpenSubdiv::Osd::CudaComputeController,
|
||||
OpenSubdiv::Osd::D3D11DrawContext>(
|
||||
g_cudaComputeController,
|
||||
hmesh,
|
||||
refiner,
|
||||
numVertexElements,
|
||||
numVaryingElements,
|
||||
level, bits, g_pd3dDeviceContext);
|
||||
#endif
|
||||
} else if (g_kernel == kDirectCompute) {
|
||||
if (not g_d3d11ComputeController) {
|
||||
g_d3d11ComputeController = new OpenSubdiv::OsdD3D11ComputeController(g_pd3dDeviceContext);
|
||||
g_d3d11ComputeController = new OpenSubdiv::Osd::D3D11ComputeController(g_pd3dDeviceContext);
|
||||
}
|
||||
g_mesh = new OpenSubdiv::OsdMesh<OpenSubdiv::OsdD3D11VertexBuffer,
|
||||
OpenSubdiv::OsdD3D11ComputeController,
|
||||
OpenSubdiv::OsdD3D11DrawContext>(
|
||||
g_mesh = new OpenSubdiv::Osd::Mesh<OpenSubdiv::Osd::D3D11VertexBuffer,
|
||||
OpenSubdiv::Osd::D3D11ComputeController,
|
||||
OpenSubdiv::Osd::D3D11DrawContext>(
|
||||
g_d3d11ComputeController,
|
||||
hmesh,
|
||||
refiner,
|
||||
numVertexElements,
|
||||
numVaryingElements,
|
||||
level, bits, g_pd3dDeviceContext);
|
||||
@ -743,16 +762,13 @@ createOsdMesh(int level, int kernel)
|
||||
printf("Unsupported kernel %s\n", getKernelName(kernel));
|
||||
}
|
||||
|
||||
// Hbr mesh can be deleted
|
||||
delete hmesh;
|
||||
|
||||
updateGeom();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
bindProgram(Effect effect, OpenSubdiv::OsdDrawContext::PatchArray const & patch)
|
||||
{
|
||||
bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patch) {
|
||||
|
||||
EffectDesc effectDesc(patch.GetDescriptor(), effect);
|
||||
|
||||
// input layout
|
||||
@ -923,9 +939,10 @@ bindProgram(Effect effect, OpenSubdiv::OsdDrawContext::PatchArray const & patch)
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
drawModel()
|
||||
{
|
||||
drawModel() {
|
||||
|
||||
ID3D11Buffer *buffer = g_mesh->BindVertexBuffer();
|
||||
assert(buffer);
|
||||
|
||||
@ -933,18 +950,18 @@ drawModel()
|
||||
UINT hOffsets = 0;
|
||||
g_pd3dDeviceContext->IASetVertexBuffers(0, 1, &buffer, &hStrides, &hOffsets);
|
||||
|
||||
OpenSubdiv::OsdDrawContext::PatchArrayVector const & patches =
|
||||
g_mesh->GetDrawContext()->patchArrays;
|
||||
OpenSubdiv::Osd::DrawContext::PatchArrayVector const & patches =
|
||||
g_mesh->GetDrawContext()->GetPatchArrays();
|
||||
|
||||
g_pd3dDeviceContext->IASetIndexBuffer(g_mesh->GetDrawContext()->patchIndexBuffer,
|
||||
DXGI_FORMAT_R32_UINT, 0);
|
||||
|
||||
// patch drawing
|
||||
for (int i = 0; i < (int)patches.size(); ++i) {
|
||||
OpenSubdiv::OsdDrawContext::PatchArray const & patch = patches[i];
|
||||
OpenSubdiv::Osd::DrawContext::PatchArray const & patch = patches[i];
|
||||
|
||||
D3D11_PRIMITIVE_TOPOLOGY topology;
|
||||
// if (patch.GetDescriptor().GetType() != OpenSubdiv::FarPatchTables::REGULAR) continue;
|
||||
// if (patch.GetDescriptor().GetType() != OpenSubdiv::Far::PatchTables::REGULAR) continue;
|
||||
|
||||
if (g_mesh->GetDrawContext()->IsAdaptive()) {
|
||||
switch (patch.GetDescriptor().GetNumControlVertices()) {
|
||||
@ -999,8 +1016,8 @@ drawModel()
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
display()
|
||||
{
|
||||
display() {
|
||||
|
||||
float color[4] = {0.006f, 0.006f, 0.006f, 1.0f};
|
||||
g_pd3dDeviceContext->ClearRenderTargetView(g_pSwapChainRTV, color);
|
||||
|
||||
@ -1139,14 +1156,13 @@ keyboard(char key) {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
callbackWireframe(int b)
|
||||
{
|
||||
callbackWireframe(int b) {
|
||||
g_wire = b;
|
||||
}
|
||||
|
||||
static void
|
||||
callbackKernel(int k)
|
||||
{
|
||||
callbackKernel(int k) {
|
||||
|
||||
g_kernel = k;
|
||||
|
||||
#ifdef OPENSUBDIV_HAS_OPENCL
|
||||
@ -1168,36 +1184,30 @@ callbackKernel(int k)
|
||||
}
|
||||
|
||||
static void
|
||||
callbackScheme(int s)
|
||||
{
|
||||
callbackScheme(int s) {
|
||||
g_scheme = s;
|
||||
createOsdMesh(g_level, g_kernel);
|
||||
}
|
||||
static void
|
||||
callbackLevel(int l)
|
||||
{
|
||||
callbackLevel(int l) {
|
||||
g_level = l;
|
||||
createOsdMesh(g_level, g_kernel);
|
||||
}
|
||||
static void
|
||||
callbackColor(int c)
|
||||
{
|
||||
callbackColor(int c) {
|
||||
g_color = c;
|
||||
}
|
||||
static void
|
||||
callbackDisplacement(int d)
|
||||
{
|
||||
callbackDisplacement(int d) {
|
||||
g_displacement = d;
|
||||
}
|
||||
static void
|
||||
callbackNormal(int n)
|
||||
{
|
||||
callbackNormal(int n) {
|
||||
g_normal = n;
|
||||
}
|
||||
|
||||
static void
|
||||
callbackCheckBox(bool checked, int button)
|
||||
{
|
||||
callbackCheckBox(bool checked, int button) {
|
||||
bool rebuild = false;
|
||||
|
||||
switch (button) {
|
||||
@ -1240,8 +1250,7 @@ callbackCheckBox(bool checked, int button)
|
||||
}
|
||||
|
||||
static void
|
||||
callbackSlider(float value, int data)
|
||||
{
|
||||
callbackSlider(float value, int data) {
|
||||
switch (data) {
|
||||
case 0:
|
||||
g_mipmapBias = value;
|
||||
@ -1253,8 +1262,7 @@ callbackSlider(float value, int data)
|
||||
}
|
||||
|
||||
static void
|
||||
initHUD()
|
||||
{
|
||||
initHUD() {
|
||||
g_hud = new D3D11hud(g_pd3dDeviceContext);
|
||||
g_hud->Init(g_width, g_height);
|
||||
|
||||
@ -1375,8 +1383,8 @@ initHUD()
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static bool
|
||||
initD3D11(HWND hWnd)
|
||||
{
|
||||
initD3D11(HWND hWnd) {
|
||||
|
||||
D3D_DRIVER_TYPE driverTypes[] = {
|
||||
D3D_DRIVER_TYPE_HARDWARE,
|
||||
D3D_DRIVER_TYPE_WARP,
|
||||
@ -1487,8 +1495,8 @@ initD3D11(HWND hWnd)
|
||||
}
|
||||
|
||||
static bool
|
||||
updateRenderTarget(HWND hWnd)
|
||||
{
|
||||
updateRenderTarget(HWND hWnd) {
|
||||
|
||||
RECT rc;
|
||||
GetClientRect(hWnd, &rc);
|
||||
UINT width = rc.right - rc.left;
|
||||
@ -1565,8 +1573,8 @@ updateRenderTarget(HWND hWnd)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
callbackError(OpenSubdiv::OsdErrorType err, const char *message)
|
||||
{
|
||||
callbackError(OpenSubdiv::Osd::ErrorType err, const char *message) {
|
||||
|
||||
std::ostringstream s;
|
||||
s << "OsdError: " << err << "\n";
|
||||
s << message;
|
||||
@ -1575,8 +1583,8 @@ callbackError(OpenSubdiv::OsdErrorType err, const char *message)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static LRESULT WINAPI
|
||||
msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case WM_KEYDOWN:
|
||||
@ -1614,8 +1622,8 @@ msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
}
|
||||
|
||||
static std::vector<std::string>
|
||||
tokenize(std::string const & src)
|
||||
{
|
||||
tokenize(std::string const & src) {
|
||||
|
||||
std::vector<std::string> result;
|
||||
|
||||
std::stringstream input(src);
|
||||
@ -1627,8 +1635,8 @@ tokenize(std::string const & src)
|
||||
}
|
||||
|
||||
int WINAPI
|
||||
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
|
||||
{
|
||||
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {
|
||||
|
||||
// register window class
|
||||
TCHAR szWindowClass[] = "OPENSUBDIV_EXAMPLE";
|
||||
WNDCLASS wcex;
|
||||
@ -1648,8 +1656,10 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmd
|
||||
RECT rect = { 0, 0, g_width, g_height };
|
||||
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
|
||||
|
||||
static const char windowTitle[] = "OpenSubdiv dxPtexViewer " OPENSUBDIV_VERSION_STRING;
|
||||
|
||||
HWND hWnd = CreateWindow(szWindowClass,
|
||||
"OpenSubdiv DirectX Ptex Viewer",
|
||||
windowTitle,
|
||||
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
@ -1698,7 +1708,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmd
|
||||
}
|
||||
}
|
||||
|
||||
OsdSetErrorCallback(callbackError);
|
||||
OpenSubdiv::Osd::SetErrorCallback(callbackError);
|
||||
|
||||
g_ptexColorFilename = colorFilename;
|
||||
if (g_ptexColorFilename == NULL) {
|
||||
|
@ -51,6 +51,7 @@ _add_possibly_cuda_executable(dxViewer WIN32
|
||||
"${SOURCE_FILES}"
|
||||
"${SHADER_FILES}"
|
||||
"${INC_FILES}"
|
||||
$<TARGET_OBJECTS:regression_common_obj>
|
||||
$<TARGET_OBJECTS:examples_common_obj>
|
||||
)
|
||||
|
||||
|
151
examples/dxViewer/init_shapes.h
Normal file
@ -0,0 +1,151 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "Apache License")
|
||||
// with the following modification; you may not use this file except in
|
||||
// compliance with the Apache License and the following modification to it:
|
||||
// Section 6. Trademarks. is deleted and replaced with:
|
||||
//
|
||||
// 6. Trademarks. This License does not grant permission to use the trade
|
||||
// names, trademarks, service marks, or product names of the Licensor
|
||||
// and its affiliates, except as required to comply with Section 4(c) of
|
||||
// the License and to reproduce the content of the NOTICE file.
|
||||
//
|
||||
// You may obtain a copy of the Apache License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the Apache License with the above modification is
|
||||
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the Apache License for the specific
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
|
||||
#include <common/shape_utils.h>
|
||||
|
||||
struct ShapeDesc {
|
||||
|
||||
ShapeDesc(char const * iname, std::string const & idata, Scheme ischeme) :
|
||||
name(iname), data(idata), scheme(ischeme) { }
|
||||
|
||||
std::string name,
|
||||
data;
|
||||
Scheme scheme;
|
||||
};
|
||||
|
||||
static std::vector<ShapeDesc> g_defaultShapes;
|
||||
|
||||
#include <shapes/catmark_bishop.h>
|
||||
#include <shapes/catmark_car.h>
|
||||
#include <shapes/catmark_chaikin0.h>
|
||||
#include <shapes/catmark_chaikin1.h>
|
||||
#include <shapes/catmark_cube_corner0.h>
|
||||
#include <shapes/catmark_cube_corner1.h>
|
||||
#include <shapes/catmark_cube_corner2.h>
|
||||
#include <shapes/catmark_cube_corner3.h>
|
||||
#include <shapes/catmark_cube_corner4.h>
|
||||
#include <shapes/catmark_cube_creases0.h>
|
||||
#include <shapes/catmark_cube_creases1.h>
|
||||
#include <shapes/catmark_cube.h>
|
||||
#include <shapes/catmark_dart_edgecorner.h>
|
||||
#include <shapes/catmark_dart_edgeonly.h>
|
||||
#include <shapes/catmark_edgecorner.h>
|
||||
#include <shapes/catmark_edgeonly.h>
|
||||
#include <shapes/catmark_fan.h>
|
||||
#include <shapes/catmark_flap.h>
|
||||
#include <shapes/catmark_flap2.h>
|
||||
#include <shapes/catmark_gregory_test1.h>
|
||||
#include <shapes/catmark_gregory_test2.h>
|
||||
#include <shapes/catmark_gregory_test3.h>
|
||||
#include <shapes/catmark_gregory_test4.h>
|
||||
#include <shapes/catmark_gregory_test5.h>
|
||||
#include <shapes/catmark_helmet.h>
|
||||
#include <shapes/catmark_hole_test1.h>
|
||||
#include <shapes/catmark_hole_test2.h>
|
||||
#include <shapes/catmark_pawn.h>
|
||||
#include <shapes/catmark_pyramid_creases0.h>
|
||||
#include <shapes/catmark_pyramid_creases1.h>
|
||||
#include <shapes/catmark_pyramid.h>
|
||||
#include <shapes/catmark_rook.h>
|
||||
#include <shapes/catmark_square_hedit0.h>
|
||||
#include <shapes/catmark_square_hedit1.h>
|
||||
#include <shapes/catmark_square_hedit2.h>
|
||||
#include <shapes/catmark_square_hedit3.h>
|
||||
#include <shapes/catmark_tent_creases0.h>
|
||||
#include <shapes/catmark_tent_creases1.h>
|
||||
#include <shapes/catmark_tent.h>
|
||||
#include <shapes/catmark_torus.h>
|
||||
#include <shapes/catmark_torus_creases0.h>
|
||||
|
||||
#include <shapes/loop_cube_creases0.h>
|
||||
#include <shapes/loop_cube_creases1.h>
|
||||
#include <shapes/loop_cube.h>
|
||||
#include <shapes/loop_icosahedron.h>
|
||||
#include <shapes/loop_saddle_edgecorner.h>
|
||||
#include <shapes/loop_saddle_edgeonly.h>
|
||||
#include <shapes/loop_triangle_edgecorner.h>
|
||||
#include <shapes/loop_triangle_edgeonly.h>
|
||||
#include <shapes/loop_chaikin0.h>
|
||||
#include <shapes/loop_chaikin1.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void initShapes() {
|
||||
// g_defaultShapes.push_back( ShapeDesc("bilinear_cube", bilinear_cube, kBilinear) );
|
||||
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube_corner0", catmark_cube_corner0, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube_corner1", catmark_cube_corner1, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube_corner2", catmark_cube_corner2, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube_corner3", catmark_cube_corner3, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube_corner4", catmark_cube_corner4, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube_creases0", catmark_cube_creases0, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube_creases1", catmark_cube_creases1, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube", catmark_cube, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_dart_edgecorner", catmark_dart_edgecorner, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_dart_edgeonly", catmark_dart_edgeonly, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_edgecorner", catmark_edgecorner, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_edgeonly", catmark_edgeonly, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_chaikin0", catmark_chaikin0, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_chaikin1", catmark_chaikin1, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_fan", catmark_fan, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_flap", catmark_flap, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_flap2", catmark_flap2, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_gregory_test1", catmark_gregory_test1, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_gregory_test2", catmark_gregory_test2, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_gregory_test3", catmark_gregory_test3, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_gregory_test4", catmark_gregory_test4, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_gregory_test5", catmark_gregory_test5, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_hole_test1", catmark_hole_test1, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_hole_test2", catmark_hole_test2, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_pyramid_creases0", catmark_pyramid_creases0, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_pyramid_creases1", catmark_pyramid_creases1, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_pyramid", catmark_pyramid, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_tent_creases0", catmark_tent_creases0, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_tent_creases1", catmark_tent_creases1 , kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_tent", catmark_tent, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_torus", catmark_torus, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_torus_creases0", catmark_torus_creases0, kCatmark ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("catmark_square_hedit0", catmark_square_hedit0, kCatmark ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("catmark_square_hedit1", catmark_square_hedit1, kCatmark ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("catmark_square_hedit2", catmark_square_hedit2, kCatmark ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("catmark_square_hedit3", catmark_square_hedit3, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_bishop", catmark_bishop, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_car", catmark_car, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_helmet", catmark_helmet, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_pawn", catmark_pawn, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_rook", catmark_rook, kCatmark ) );
|
||||
|
||||
// g_defaultShapes.push_back( ShapeDesc("bilinear_cube", bilinear_cube, kBilinear ) );
|
||||
|
||||
// g_defaultShapes.push_back( ShapeDesc("loop_cube_creases0", loop_cube_creases0, kLoop ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("loop_cube_creases1", loop_cube_creases1, kLoop ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("loop_cube", loop_cube, kLoop ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("loop_icosahedron", loop_icosahedron, kLoop ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("loop_saddle_edgecorner", loop_saddle_edgecorner, kLoop ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("loop_saddle_edgeonly", loop_saddle_edgeonly, kLoop ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("loop_triangle_edgecorner", loop_triangle_edgecorner, kLoop ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("loop_triangle_edgeonly", loop_triangle_edgeonly, kLoop ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("loop_chaikin0", loop_chaikin0, kLoop ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("loop_chaikin1", loop_chaikin1, kLoop ) );
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
@ -267,12 +267,17 @@ cbuffer Lighting : register( b2 ) {
|
||||
LightSource lightSource[NUM_LIGHTS];
|
||||
};
|
||||
|
||||
|
||||
cbuffer Material : register( b3 ){
|
||||
float4 materialColor;
|
||||
}
|
||||
|
||||
float4
|
||||
lighting(float3 Peye, float3 Neye)
|
||||
{
|
||||
float4 color = float4(0.0, 0.0, 0.0, 0.0);
|
||||
//float4 material = float4(0.4, 0.4, 0.8, 1);
|
||||
float4 material = float4(0.13, 0.13, 0.61, 1); // sRGB (gamma 2.2)
|
||||
//float4 material = float4(0.13, 0.13, 0.61, 1); // sRGB (gamma 2.2)
|
||||
|
||||
for (int i = 0; i < NUM_LIGHTS; ++i) {
|
||||
|
||||
@ -287,8 +292,8 @@ lighting(float3 Peye, float3 Neye)
|
||||
float d = max(0.0, dot(n, l));
|
||||
float s = pow(max(0.0, dot(n, h)), 500.0f);
|
||||
|
||||
color += lightSource[i].ambient * material
|
||||
+ d * lightSource[i].diffuse * material
|
||||
color += lightSource[i].ambient * materialColor
|
||||
+ d * lightSource[i].diffuse * materialColor
|
||||
+ s * lightSource[i].specular;
|
||||
}
|
||||
|
||||
|
@ -1,69 +0,0 @@
|
||||
#
|
||||
# Copyright 2014 Pixar
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "Apache License")
|
||||
# with the following modification; you may not use this file except in
|
||||
# compliance with the Apache License and the following modification to it:
|
||||
# Section 6. Trademarks. is deleted and replaced with:
|
||||
#
|
||||
# 6. Trademarks. This License does not grant permission to use the trade
|
||||
# names, trademarks, service marks, or product names of the Licensor
|
||||
# and its affiliates, except as required to comply with Section 4(c) of
|
||||
# the License and to reproduce the content of the NOTICE file.
|
||||
#
|
||||
# You may obtain a copy of the Apache License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the Apache License with the above modification is
|
||||
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the Apache License for the specific
|
||||
# language governing permissions and limitations under the Apache License.
|
||||
#
|
||||
|
||||
# *** facePartition ***
|
||||
|
||||
set(SHADER_FILES
|
||||
shader.glsl
|
||||
)
|
||||
|
||||
list(APPEND PLATFORM_LIBRARIES
|
||||
"${OSD_LINK_TARGET}"
|
||||
"${OPENGL_LIBRARY}"
|
||||
"${GLFW_LIBRARIES}"
|
||||
)
|
||||
|
||||
include_directories(
|
||||
"${PROJECT_SOURCE_DIR}/opensubdiv"
|
||||
"${PROJECT_SOURCE_DIR}/regression"
|
||||
"${GLFW_INCLUDE_DIR}"
|
||||
)
|
||||
|
||||
if ( GLEW_FOUND )
|
||||
include_directories("${GLEW_INCLUDE_DIR}")
|
||||
list(APPEND PLATFORM_LIBRARIES "${GLEW_LIBRARY}")
|
||||
endif()
|
||||
|
||||
if( OPENCL_FOUND )
|
||||
include_directories("${OPENCL_INCLUDE_DIRS}")
|
||||
endif()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
_stringify("${SHADER_FILES}" INC_FILES)
|
||||
|
||||
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
_add_glfw_executable(facePartition
|
||||
viewer.cpp
|
||||
"${SHADER_FILES}"
|
||||
"${INC_FILES}"
|
||||
$<TARGET_OBJECTS:examples_common_obj>
|
||||
)
|
||||
|
||||
target_link_libraries(facePartition
|
||||
${PLATFORM_LIBRARIES}
|
||||
)
|
||||
|
||||
install(TARGETS facePartition DESTINATION "${CMAKE_BINDIR_BASE}")
|
@ -1,331 +0,0 @@
|
||||
//
|
||||
// Copyright 2014 Pixar
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "Apache License")
|
||||
// with the following modification; you may not use this file except in
|
||||
// compliance with the Apache License and the following modification to it:
|
||||
// Section 6. Trademarks. is deleted and replaced with:
|
||||
//
|
||||
// 6. Trademarks. This License does not grant permission to use the trade
|
||||
// names, trademarks, service marks, or product names of the Licensor
|
||||
// and its affiliates, except as required to comply with Section 4(c) of
|
||||
// the License and to reproduce the content of the NOTICE file.
|
||||
//
|
||||
// You may obtain a copy of the Apache License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the Apache License with the above modification is
|
||||
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the Apache License for the specific
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Uniforms / Uniform Blocks
|
||||
//--------------------------------------------------------------
|
||||
|
||||
layout(std140) uniform Transform {
|
||||
mat4 ModelViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 ModelViewProjectionMatrix;
|
||||
};
|
||||
|
||||
layout(std140) uniform Tessellation {
|
||||
float TessLevel;
|
||||
};
|
||||
|
||||
uniform int GregoryQuadOffsetBase;
|
||||
uniform int PrimitiveIdBase;
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Osd external functions
|
||||
//--------------------------------------------------------------
|
||||
|
||||
mat4 OsdModelViewMatrix()
|
||||
{
|
||||
return ModelViewMatrix;
|
||||
}
|
||||
mat4 OsdProjectionMatrix()
|
||||
{
|
||||
return ProjectionMatrix;
|
||||
}
|
||||
mat4 OsdModelViewProjectionMatrix()
|
||||
{
|
||||
return ModelViewProjectionMatrix;
|
||||
}
|
||||
float OsdTessLevel()
|
||||
{
|
||||
return TessLevel;
|
||||
}
|
||||
int OsdGregoryQuadOffsetBase()
|
||||
{
|
||||
return GregoryQuadOffsetBase;
|
||||
}
|
||||
int OsdPrimitiveIdBase()
|
||||
{
|
||||
return PrimitiveIdBase;
|
||||
}
|
||||
int OsdBaseVertex()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Vertex Shader
|
||||
//--------------------------------------------------------------
|
||||
#ifdef VERTEX_SHADER
|
||||
|
||||
layout (location=0) in vec4 position;
|
||||
|
||||
out block {
|
||||
OutputVertex v;
|
||||
} outpt;
|
||||
|
||||
void main()
|
||||
{
|
||||
outpt.v.position = ModelViewMatrix * position;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Geometry Shader
|
||||
//--------------------------------------------------------------
|
||||
#ifdef GEOMETRY_SHADER
|
||||
|
||||
#ifdef PRIM_QUAD
|
||||
|
||||
layout(lines_adjacency) in;
|
||||
|
||||
#define EDGE_VERTS 4
|
||||
|
||||
#endif // PRIM_QUAD
|
||||
|
||||
#ifdef PRIM_TRI
|
||||
|
||||
layout(triangles) in;
|
||||
|
||||
#define EDGE_VERTS 3
|
||||
|
||||
#endif // PRIM_TRI
|
||||
|
||||
|
||||
layout(triangle_strip, max_vertices = EDGE_VERTS) out;
|
||||
in block {
|
||||
OutputVertex v;
|
||||
} inpt[EDGE_VERTS];
|
||||
|
||||
out block {
|
||||
OutputVertex v;
|
||||
noperspective out vec4 edgeDistance;
|
||||
} outpt;
|
||||
|
||||
void emit(int index, vec3 normal)
|
||||
{
|
||||
outpt.v.position = inpt[index].v.position;
|
||||
#ifdef SMOOTH_NORMALS
|
||||
outpt.v.normal = inpt[index].v.normal;
|
||||
#else
|
||||
outpt.v.normal = normal;
|
||||
#endif
|
||||
|
||||
gl_Position = ProjectionMatrix * inpt[index].v.position;
|
||||
EmitVertex();
|
||||
}
|
||||
|
||||
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
|
||||
const float VIEWPORT_SCALE = 1024.0; // XXXdyu
|
||||
|
||||
float edgeDistance(vec4 p, vec4 p0, vec4 p1)
|
||||
{
|
||||
return VIEWPORT_SCALE *
|
||||
abs((p.x - p0.x) * (p1.y - p0.y) -
|
||||
(p.y - p0.y) * (p1.x - p0.x)) / length(p1.xy - p0.xy);
|
||||
}
|
||||
|
||||
void emit(int index, vec3 normal, vec4 edgeVerts[EDGE_VERTS])
|
||||
{
|
||||
outpt.edgeDistance[0] =
|
||||
edgeDistance(edgeVerts[index], edgeVerts[0], edgeVerts[1]);
|
||||
outpt.edgeDistance[1] =
|
||||
edgeDistance(edgeVerts[index], edgeVerts[1], edgeVerts[2]);
|
||||
#ifdef PRIM_TRI
|
||||
outpt.edgeDistance[2] =
|
||||
edgeDistance(edgeVerts[index], edgeVerts[2], edgeVerts[0]);
|
||||
#endif
|
||||
#ifdef PRIM_QUAD
|
||||
outpt.edgeDistance[2] =
|
||||
edgeDistance(edgeVerts[index], edgeVerts[2], edgeVerts[3]);
|
||||
outpt.edgeDistance[3] =
|
||||
edgeDistance(edgeVerts[index], edgeVerts[3], edgeVerts[0]);
|
||||
#endif
|
||||
|
||||
emit(index, normal);
|
||||
}
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_PrimitiveID = gl_PrimitiveIDIn;
|
||||
|
||||
#ifdef PRIM_QUAD
|
||||
vec3 A = (inpt[0].v.position - inpt[1].v.position).xyz;
|
||||
vec3 B = (inpt[3].v.position - inpt[1].v.position).xyz;
|
||||
vec3 C = (inpt[2].v.position - inpt[1].v.position).xyz;
|
||||
vec3 n0 = normalize(cross(B, A));
|
||||
|
||||
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
|
||||
vec4 edgeVerts[EDGE_VERTS];
|
||||
edgeVerts[0] = ProjectionMatrix * inpt[0].v.position;
|
||||
edgeVerts[1] = ProjectionMatrix * inpt[1].v.position;
|
||||
edgeVerts[2] = ProjectionMatrix * inpt[2].v.position;
|
||||
edgeVerts[3] = ProjectionMatrix * inpt[3].v.position;
|
||||
|
||||
edgeVerts[0].xy /= edgeVerts[0].w;
|
||||
edgeVerts[1].xy /= edgeVerts[1].w;
|
||||
edgeVerts[2].xy /= edgeVerts[2].w;
|
||||
edgeVerts[3].xy /= edgeVerts[3].w;
|
||||
|
||||
emit(0, n0, edgeVerts);
|
||||
emit(1, n0, edgeVerts);
|
||||
emit(3, n0, edgeVerts);
|
||||
emit(2, n0, edgeVerts);
|
||||
#else
|
||||
emit(0, n0);
|
||||
emit(1, n0);
|
||||
emit(3, n0);
|
||||
emit(2, n0);
|
||||
#endif
|
||||
#endif // PRIM_QUAD
|
||||
|
||||
#ifdef PRIM_TRI
|
||||
vec3 A = (inpt[1].v.position - inpt[0].v.position).xyz;
|
||||
vec3 B = (inpt[2].v.position - inpt[0].v.position).xyz;
|
||||
vec3 n0 = normalize(cross(B, A));
|
||||
|
||||
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
|
||||
vec4 edgeVerts[EDGE_VERTS];
|
||||
edgeVerts[0] = ProjectionMatrix * inpt[0].v.position;
|
||||
edgeVerts[1] = ProjectionMatrix * inpt[1].v.position;
|
||||
edgeVerts[2] = ProjectionMatrix * inpt[2].v.position;
|
||||
|
||||
edgeVerts[0].xy /= edgeVerts[0].w;
|
||||
edgeVerts[1].xy /= edgeVerts[1].w;
|
||||
edgeVerts[2].xy /= edgeVerts[2].w;
|
||||
|
||||
emit(0, n0, edgeVerts);
|
||||
emit(1, n0, edgeVerts);
|
||||
emit(2, n0, edgeVerts);
|
||||
#else
|
||||
emit(0, n0);
|
||||
emit(1, n0);
|
||||
emit(2, n0);
|
||||
#endif
|
||||
#endif // PRIM_TRI
|
||||
|
||||
EndPrimitive();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Fragment Shader
|
||||
//--------------------------------------------------------------
|
||||
#ifdef FRAGMENT_SHADER
|
||||
|
||||
in block {
|
||||
OutputVertex v;
|
||||
noperspective in vec4 edgeDistance;
|
||||
} inpt;
|
||||
|
||||
out vec4 outColor;
|
||||
|
||||
#define NUM_LIGHTS 2
|
||||
|
||||
struct LightSource {
|
||||
vec4 position;
|
||||
vec4 ambient;
|
||||
vec4 diffuse;
|
||||
vec4 specular;
|
||||
};
|
||||
|
||||
layout(std140) uniform Lighting {
|
||||
LightSource lightSource[NUM_LIGHTS];
|
||||
};
|
||||
|
||||
uniform vec4 diffuseColor = vec4(1);
|
||||
uniform vec4 ambientColor = vec4(1);
|
||||
|
||||
vec4
|
||||
lighting(vec4 diffuse, vec3 Peye, vec3 Neye)
|
||||
{
|
||||
vec4 color = vec4(0);
|
||||
|
||||
for (int i = 0; i < NUM_LIGHTS; ++i) {
|
||||
|
||||
vec4 Plight = lightSource[i].position;
|
||||
|
||||
vec3 l = (Plight.w == 0.0)
|
||||
? normalize(Plight.xyz) : normalize(Plight.xyz - Peye);
|
||||
|
||||
vec3 n = normalize(Neye);
|
||||
vec3 h = normalize(l + vec3(0,0,1)); // directional viewer
|
||||
|
||||
float d = max(0.0, dot(n, l));
|
||||
float s = pow(max(0.0, dot(n, h)), 500.0f);
|
||||
|
||||
color += lightSource[i].ambient * ambientColor
|
||||
+ d * lightSource[i].diffuse * diffuse
|
||||
+ s * lightSource[i].specular;
|
||||
}
|
||||
|
||||
color.a = 1;
|
||||
return color;
|
||||
}
|
||||
|
||||
vec4
|
||||
edgeColor(vec4 Cfill, vec4 edgeDistance)
|
||||
{
|
||||
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
|
||||
#ifdef PRIM_TRI
|
||||
float d =
|
||||
min(inpt.edgeDistance[0], min(inpt.edgeDistance[1], inpt.edgeDistance[2]));
|
||||
#endif
|
||||
#ifdef PRIM_QUAD
|
||||
float d =
|
||||
min(min(inpt.edgeDistance[0], inpt.edgeDistance[1]),
|
||||
min(inpt.edgeDistance[2], inpt.edgeDistance[3]));
|
||||
#endif
|
||||
vec4 Cedge = vec4(1.0, 1.0, 0.0, 1.0);
|
||||
float p = exp2(-2 * d * d);
|
||||
|
||||
#if defined(GEOMETRY_OUT_WIRE)
|
||||
if (p < 0.25) discard;
|
||||
#endif
|
||||
|
||||
Cfill.rgb = mix(Cfill.rgb, Cedge.rgb, p);
|
||||
#endif
|
||||
return Cfill;
|
||||
}
|
||||
|
||||
#if defined(PRIM_QUAD) || defined(PRIM_TRI)
|
||||
void
|
||||
main()
|
||||
{
|
||||
vec3 N = (gl_FrontFacing ? inpt.v.normal : -inpt.v.normal);
|
||||
|
||||
vec4 color = diffuseColor;
|
||||
|
||||
vec4 Cf = lighting(color, inpt.v.position.xyz, N);
|
||||
|
||||
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
|
||||
Cf = edgeColor(Cf, inpt.edgeDistance);
|
||||
#endif
|
||||
|
||||
outColor = Cf;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,172 +0,0 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "Apache License")
|
||||
// with the following modification; you may not use this file except in
|
||||
// compliance with the Apache License and the following modification to it:
|
||||
// Section 6. Trademarks. is deleted and replaced with:
|
||||
//
|
||||
// 6. Trademarks. This License does not grant permission to use the trade
|
||||
// names, trademarks, service marks, or product names of the Licensor
|
||||
// and its affiliates, except as required to comply with Section 4(c) of
|
||||
// the License and to reproduce the content of the NOTICE file.
|
||||
//
|
||||
// You may obtain a copy of the Apache License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the Apache License with the above modification is
|
||||
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the Apache License for the specific
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
|
||||
#include "delegate.h"
|
||||
|
||||
#include <osd/opengl.h>
|
||||
|
||||
MyDrawContext::MyDrawContext() {
|
||||
glGenVertexArrays(1, &_vao);
|
||||
}
|
||||
|
||||
MyDrawContext::~MyDrawContext() {
|
||||
glDeleteVertexArrays(1, &_vao);
|
||||
}
|
||||
|
||||
MyDrawContext*
|
||||
MyDrawContext::Create(OpenSubdiv::FarPatchTables const *patchTables, int numVertexElements, bool requireFVarData)
|
||||
{
|
||||
MyDrawContext * result = new MyDrawContext();
|
||||
|
||||
if (patchTables) {
|
||||
if (result->create(patchTables, numVertexElements, requireFVarData)) {
|
||||
return result;
|
||||
} else {
|
||||
delete result;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
MyDrawDelegate::Bind(OpenSubdiv::OsdUtilMeshBatchBase<MyDrawContext> *batch, EffectHandle const &effect) {
|
||||
|
||||
if (batch != _currentBatch) {
|
||||
// bind batch
|
||||
_currentBatch = batch;
|
||||
MyDrawContext *drawContext = batch->GetDrawContext();
|
||||
|
||||
// bind vao
|
||||
glBindVertexArray(drawContext->GetVertexArray());
|
||||
|
||||
// bind vbo state
|
||||
glBindBuffer(GL_ARRAY_BUFFER, batch->BindVertexBuffer());
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, drawContext->GetPatchIndexBuffer());
|
||||
|
||||
// vertex attrib
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof (GLfloat) * 3, 0);
|
||||
|
||||
if (effect->displayStyle == kVaryingColor) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, batch->BindVaryingBuffer());
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof (GLfloat) * 3, 0);
|
||||
}
|
||||
|
||||
// bind other builtin texture buffers
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, drawContext->GetVertexTextureBuffer());
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, drawContext->GetVertexValenceTextureBuffer());
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, drawContext->GetQuadOffsetsTextureBuffer());
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, drawContext->GetPatchParamTextureBuffer());
|
||||
|
||||
if (drawContext->GetFvarDataTextureBuffer()) {
|
||||
glActiveTexture(GL_TEXTURE4);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, drawContext->GetFvarDataTextureBuffer());
|
||||
}
|
||||
}
|
||||
if (effect != _currentEffect) {
|
||||
_currentEffect = effect;
|
||||
|
||||
// bind effect
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MyDrawDelegate::Unbind(OpenSubdiv::OsdUtilMeshBatchBase<MyDrawContext> * /* batch */, EffectHandle const &/* effect */) {
|
||||
}
|
||||
|
||||
void
|
||||
MyDrawDelegate::Begin() {
|
||||
_currentBatch = NULL;
|
||||
_currentEffect = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
MyDrawDelegate::End() {
|
||||
_currentBatch = NULL;
|
||||
_currentEffect = NULL;
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
}
|
||||
|
||||
void
|
||||
MyDrawDelegate::DrawElements(OpenSubdiv::OsdDrawContext::PatchArray const &patchArray) {
|
||||
|
||||
// bind patchType-wise effect state
|
||||
// can be skipped (if config is not changed)
|
||||
MyDrawConfig *config = GetDrawConfig(_currentEffect, patchArray.GetDescriptor());
|
||||
|
||||
GLuint program = config->program;
|
||||
|
||||
if (true /* if config is different from previous call */) {
|
||||
glUseProgram(program);
|
||||
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
|
||||
glPatchParameteri(GL_PATCH_VERTICES, patchArray.GetDescriptor().GetNumControlVertices());
|
||||
#endif
|
||||
// bind patchArray state and draw
|
||||
}
|
||||
|
||||
// apply patch color
|
||||
_currentEffect->BindDrawConfig(config, patchArray.GetDescriptor());
|
||||
|
||||
glUniform1i(config->primitiveIdBaseUniform, patchArray.GetPatchIndex());
|
||||
if (patchArray.GetDescriptor().GetType() == OpenSubdiv::FarPatchTables::GREGORY ||
|
||||
patchArray.GetDescriptor().GetType() == OpenSubdiv::FarPatchTables::GREGORY_BOUNDARY){
|
||||
glUniform1i(config->gregoryQuadOffsetBaseUniform, patchArray.GetQuadOffsetIndex());
|
||||
}
|
||||
|
||||
if (patchArray.GetDescriptor().GetType() == OpenSubdiv::FarPatchTables::QUADS) {
|
||||
glDrawElements(GL_LINES_ADJACENCY, patchArray.GetNumIndices(), GL_UNSIGNED_INT,
|
||||
(void*)(patchArray.GetVertIndex()*sizeof(GLuint)));
|
||||
} else if (patchArray.GetDescriptor().GetType() == OpenSubdiv::FarPatchTables::TRIANGLES) {
|
||||
glDrawElements(GL_TRIANGLES, patchArray.GetNumIndices(), GL_UNSIGNED_INT,
|
||||
(void*)(patchArray.GetVertIndex()*sizeof(GLuint)));
|
||||
} else {
|
||||
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
|
||||
glDrawElements(GL_PATCHES, patchArray.GetNumIndices(), GL_UNSIGNED_INT,
|
||||
(void*)(patchArray.GetVertIndex()*sizeof(GLuint)));
|
||||
#endif
|
||||
}
|
||||
_numDrawCalls++;
|
||||
}
|
||||
|
||||
bool
|
||||
MyDrawDelegate::IsCombinable(EffectHandle const &a, EffectHandle const &b) const {
|
||||
return a == b;
|
||||
}
|
||||
|
||||
MyDrawConfig *
|
||||
MyDrawDelegate::GetDrawConfig(EffectHandle &effect, OpenSubdiv::OsdDrawContext::PatchDescriptor desc) {
|
||||
|
||||
return _effectRegistry.GetDrawConfig(effect->GetEffectDescriptor(), desc);
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "Apache License")
|
||||
// with the following modification; you may not use this file except in
|
||||
// compliance with the Apache License and the following modification to it:
|
||||
// Section 6. Trademarks. is deleted and replaced with:
|
||||
//
|
||||
// 6. Trademarks. This License does not grant permission to use the trade
|
||||
// names, trademarks, service marks, or product names of the Licensor
|
||||
// and its affiliates, except as required to comply with Section 4(c) of
|
||||
// the License and to reproduce the content of the NOTICE file.
|
||||
//
|
||||
// You may obtain a copy of the Apache License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the Apache License with the above modification is
|
||||
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the Apache License for the specific
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
|
||||
#ifndef DELEGATE_H
|
||||
#define DELEGATE_H
|
||||
|
||||
#include <osd/cpuGLVertexBuffer.h>
|
||||
#include <osd/glDrawContext.h>
|
||||
#include <osd/glDrawRegistry.h>
|
||||
#include <osdutil/batch.h>
|
||||
|
||||
#include "effect.h"
|
||||
#include "effectRegistry.h"
|
||||
|
||||
class MyDrawContext : public OpenSubdiv::OsdGLDrawContext {
|
||||
public:
|
||||
virtual ~MyDrawContext();
|
||||
|
||||
static MyDrawContext *Create(OpenSubdiv::FarPatchTables const *patchTables,
|
||||
int numVertexElements,
|
||||
bool requireFVarData=false);
|
||||
|
||||
GLuint GetVertexArray() const { return _vao; }
|
||||
|
||||
private:
|
||||
MyDrawContext();
|
||||
|
||||
GLuint _vao;
|
||||
};
|
||||
|
||||
class MyDrawDelegate {
|
||||
public:
|
||||
typedef MyEffect * EffectHandle;
|
||||
|
||||
void Bind(OpenSubdiv::OsdUtilMeshBatchBase<MyDrawContext> *batch, EffectHandle const &effect);
|
||||
void Unbind(OpenSubdiv::OsdUtilMeshBatchBase<MyDrawContext> *batch, EffectHandle const &effect);
|
||||
|
||||
void Begin();
|
||||
void End();
|
||||
|
||||
void DrawElements(OpenSubdiv::OsdDrawContext::PatchArray const &patchArray);
|
||||
|
||||
bool IsCombinable(EffectHandle const &a, EffectHandle const &b) const;
|
||||
|
||||
void ResetNumDrawCalls() { _numDrawCalls = 0; }
|
||||
int GetNumDrawCalls() const { return _numDrawCalls; }
|
||||
|
||||
private:
|
||||
MyDrawConfig *GetDrawConfig(EffectHandle &effect, OpenSubdiv::OsdDrawContext::PatchDescriptor desc);
|
||||
|
||||
MyEffectRegistry _effectRegistry;
|
||||
int _numDrawCalls;
|
||||
OpenSubdiv::OsdUtilMeshBatchBase<MyDrawContext> *_currentBatch;
|
||||
EffectHandle _currentEffect;
|
||||
};
|
||||
|
||||
#endif /* DELEGATE_H */
|
@ -1,153 +0,0 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "Apache License")
|
||||
// with the following modification; you may not use this file except in
|
||||
// compliance with the Apache License and the following modification to it:
|
||||
// Section 6. Trademarks. is deleted and replaced with:
|
||||
//
|
||||
// 6. Trademarks. This License does not grant permission to use the trade
|
||||
// names, trademarks, service marks, or product names of the Licensor
|
||||
// and its affiliates, except as required to comply with Section 4(c) of
|
||||
// the License and to reproduce the content of the NOTICE file.
|
||||
//
|
||||
// You may obtain a copy of the Apache License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the Apache License with the above modification is
|
||||
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the Apache License for the specific
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
|
||||
#include "effect.h"
|
||||
|
||||
#include "../common/simple_math.h"
|
||||
#include "../common/patchColors.h"
|
||||
|
||||
#include <osd/opengl.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
GLuint g_transformUB = 0,
|
||||
g_tessellationUB = 0,
|
||||
g_lightingUB = 0;
|
||||
|
||||
GLuint g_transformBinding = 0;
|
||||
GLuint g_tessellationBinding = 1;
|
||||
GLuint g_lightingBinding = 3;
|
||||
|
||||
|
||||
void
|
||||
MyEffect::SetMatrix(const float *modelview, const float *projection) {
|
||||
float mvp[16];
|
||||
multMatrix(mvp, modelview, projection);
|
||||
|
||||
struct Transform {
|
||||
float ModelViewMatrix[16];
|
||||
float ProjectionMatrix[16];
|
||||
float ModelViewProjectionMatrix[16];
|
||||
} transformData;
|
||||
memcpy(transformData.ModelViewMatrix, modelview, sizeof(float)*16);
|
||||
memcpy(transformData.ProjectionMatrix, projection, sizeof(float)*16);
|
||||
memcpy(transformData.ModelViewProjectionMatrix, mvp, sizeof(float)*16);
|
||||
|
||||
// set transform
|
||||
if (! g_transformUB) {
|
||||
glGenBuffers(1, &g_transformUB);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, g_transformUB);
|
||||
glBufferData(GL_UNIFORM_BUFFER,
|
||||
sizeof(transformData), NULL, GL_STATIC_DRAW);
|
||||
};
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, g_transformUB);
|
||||
glBufferSubData(GL_UNIFORM_BUFFER,
|
||||
0, sizeof(transformData), &transformData);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, g_transformBinding, g_transformUB);
|
||||
}
|
||||
|
||||
void
|
||||
MyEffect::SetTessLevel(float tessLevel) {
|
||||
|
||||
struct Tessellation {
|
||||
float TessLevel;
|
||||
} tessellationData;
|
||||
tessellationData.TessLevel = tessLevel;
|
||||
|
||||
if (! g_tessellationUB) {
|
||||
glGenBuffers(1, &g_tessellationUB);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, g_tessellationUB);
|
||||
glBufferData(GL_UNIFORM_BUFFER,
|
||||
sizeof(tessellationData), NULL, GL_STATIC_DRAW);
|
||||
};
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, g_tessellationUB);
|
||||
glBufferSubData(GL_UNIFORM_BUFFER,
|
||||
0, sizeof(tessellationData), &tessellationData);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, g_tessellationBinding, g_tessellationUB);
|
||||
}
|
||||
|
||||
void
|
||||
MyEffect::SetLighting() {
|
||||
|
||||
struct Lighting {
|
||||
struct Light {
|
||||
float position[4];
|
||||
float ambient[4];
|
||||
float diffuse[4];
|
||||
float specular[4];
|
||||
} lightSource[2];
|
||||
} lightingData = {
|
||||
{{ { 0.5, 0.2f, 1.0f, 0.0f },
|
||||
{ 0.1f, 0.1f, 0.1f, 1.0f },
|
||||
{ 0.7f, 0.7f, 0.7f, 1.0f },
|
||||
{ 0.8f, 0.8f, 0.8f, 1.0f } },
|
||||
|
||||
{ { -0.8f, 0.4f, -1.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 1.0f },
|
||||
{ 0.5f, 0.5f, 0.5f, 1.0f },
|
||||
{ 0.8f, 0.8f, 0.8f, 1.0f } }}
|
||||
};
|
||||
|
||||
if (! g_lightingUB) {
|
||||
glGenBuffers(1, &g_lightingUB);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, g_lightingUB);
|
||||
glBufferData(GL_UNIFORM_BUFFER,
|
||||
sizeof(lightingData), NULL, GL_STATIC_DRAW);
|
||||
};
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, g_lightingUB);
|
||||
glBufferSubData(GL_UNIFORM_BUFFER,
|
||||
0, sizeof(lightingData), &lightingData);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, g_lightingBinding, g_lightingUB);
|
||||
}
|
||||
|
||||
void
|
||||
MyEffect::BindDrawConfig(MyDrawConfig *config, OpenSubdiv::OsdDrawContext::PatchDescriptor desc) {
|
||||
|
||||
// bind uniforms
|
||||
|
||||
// currently, these are used only in conjunction with tessellation shaders
|
||||
#if defined(GL_EXT_direct_state_access) || defined(GL_VERSION_4_1)
|
||||
|
||||
GLint program = config->program;
|
||||
GLint diffuseColor = config->diffuseColorUniform;
|
||||
|
||||
if (displayPatchColor) {
|
||||
if (desc.GetType() == OpenSubdiv::FarPatchTables::QUADS or
|
||||
desc.GetType() == OpenSubdiv::FarPatchTables::TRIANGLES) {
|
||||
glProgramUniform4f(program, diffuseColor, 0.4f, 0.4f, 0.8f, 1);
|
||||
} else {
|
||||
const float *color = getAdaptivePatchColor( desc );
|
||||
glProgramUniform4f(program, diffuseColor, color[0], color[1], color[2], color[3]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1,101 +0,0 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "Apache License")
|
||||
// with the following modification; you may not use this file except in
|
||||
// compliance with the Apache License and the following modification to it:
|
||||
// Section 6. Trademarks. is deleted and replaced with:
|
||||
//
|
||||
// 6. Trademarks. This License does not grant permission to use the trade
|
||||
// names, trademarks, service marks, or product names of the Licensor
|
||||
// and its affiliates, except as required to comply with Section 4(c) of
|
||||
// the License and to reproduce the content of the NOTICE file.
|
||||
//
|
||||
// You may obtain a copy of the Apache License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the Apache License with the above modification is
|
||||
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the Apache License for the specific
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
|
||||
#ifndef EFFECT_H
|
||||
#define EFFECT_H
|
||||
|
||||
#include <osd/glDrawRegistry.h>
|
||||
|
||||
#include <osd/opengl.h>
|
||||
|
||||
enum DisplayTyle { kWire = 0,
|
||||
kShaded,
|
||||
kWireShaded,
|
||||
kVaryingColor,
|
||||
kFaceVaryingColor };
|
||||
|
||||
union EffectDesc {
|
||||
public:
|
||||
struct {
|
||||
unsigned int displayStyle:3;
|
||||
unsigned int screenSpaceTess:1;
|
||||
};
|
||||
int value;
|
||||
|
||||
bool operator < (const EffectDesc &e) const {
|
||||
return value < e.value;
|
||||
}
|
||||
|
||||
int GetDisplayStyle() const { return displayStyle; }
|
||||
bool GetScreenSpaceTess() const { return screenSpaceTess; }
|
||||
};
|
||||
|
||||
struct MyDrawConfig : public OpenSubdiv::OsdGLDrawConfig {
|
||||
|
||||
MyDrawConfig() :
|
||||
diffuseColorUniform(-1) {}
|
||||
virtual ~MyDrawConfig() {}
|
||||
|
||||
GLint diffuseColorUniform;
|
||||
|
||||
GLint gregoryQuadOffsetBaseUniform;
|
||||
GLint primitiveIdBaseUniform;
|
||||
};
|
||||
|
||||
class MyEffect { // formerly EffectHandle
|
||||
public:
|
||||
MyEffect() : displayPatchColor(false), screenSpaceTess(false), displayStyle(kWire) {}
|
||||
|
||||
EffectDesc GetEffectDescriptor() const {
|
||||
EffectDesc desc;
|
||||
|
||||
desc.value = 0;
|
||||
desc.displayStyle = displayStyle;
|
||||
desc.screenSpaceTess = screenSpaceTess;
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
void BindDrawConfig(MyDrawConfig *config, OpenSubdiv::OsdDrawContext::PatchDescriptor desc);
|
||||
|
||||
void SetMatrix(const float *modelview, const float *projection);
|
||||
void SetTessLevel(float tessLevel);
|
||||
void SetLighting();
|
||||
|
||||
bool operator == (const MyEffect &other) const {
|
||||
return (displayPatchColor == other.displayPatchColor) and
|
||||
(screenSpaceTess == other.screenSpaceTess) and
|
||||
(displayStyle == other.displayStyle);
|
||||
}
|
||||
bool operator != (const MyEffect &other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
bool displayPatchColor; // runtime switchable
|
||||
bool screenSpaceTess; // need recompile (should be considered in effect descriptor)
|
||||
int displayStyle; // need recompile
|
||||
};
|
||||
|
||||
|
||||
#endif /* EFFECT_H */
|
@ -1,176 +0,0 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "Apache License")
|
||||
// with the following modification; you may not use this file except in
|
||||
// compliance with the Apache License and the following modification to it:
|
||||
// Section 6. Trademarks. is deleted and replaced with:
|
||||
//
|
||||
// 6. Trademarks. This License does not grant permission to use the trade
|
||||
// names, trademarks, service marks, or product names of the Licensor
|
||||
// and its affiliates, except as required to comply with Section 4(c) of
|
||||
// the License and to reproduce the content of the NOTICE file.
|
||||
//
|
||||
// You may obtain a copy of the Apache License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the Apache License with the above modification is
|
||||
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the Apache License for the specific
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
|
||||
#include "effectRegistry.h"
|
||||
|
||||
#include <osd/opengl.h>
|
||||
|
||||
static const char *shaderSource =
|
||||
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
|
||||
#include "shader.gen.h"
|
||||
#else
|
||||
#include "shader_gl3.gen.h"
|
||||
#endif
|
||||
;
|
||||
|
||||
|
||||
MyEffectRegistry::SourceConfigType *
|
||||
MyEffectRegistry::_CreateDrawSourceConfig(DescType const & desc) {
|
||||
|
||||
SourceConfigType * sconfig =
|
||||
BaseRegistry::_CreateDrawSourceConfig(desc.first);
|
||||
assert(sconfig);
|
||||
|
||||
EffectDesc effectDesc = desc.second;
|
||||
|
||||
if (effectDesc.GetScreenSpaceTess()) {
|
||||
sconfig->commonShader.AddDefine("OSD_ENABLE_PATCH_CULL");
|
||||
sconfig->commonShader.AddDefine("OSD_ENABLE_SCREENSPACE_TESSELLATION");
|
||||
}
|
||||
|
||||
const char *glslVersion = "#version 400\n";
|
||||
if (desc.first.GetType() == OpenSubdiv::FarPatchTables::QUADS or
|
||||
desc.first.GetType() == OpenSubdiv::FarPatchTables::TRIANGLES) {
|
||||
sconfig->vertexShader.source = shaderSource;
|
||||
sconfig->vertexShader.version = glslVersion;
|
||||
sconfig->vertexShader.AddDefine("VERTEX_SHADER");
|
||||
} else {
|
||||
sconfig->geometryShader.AddDefine("SMOOTH_NORMALS");
|
||||
}
|
||||
|
||||
sconfig->geometryShader.source = shaderSource;
|
||||
sconfig->geometryShader.version = glslVersion;
|
||||
sconfig->geometryShader.AddDefine("GEOMETRY_SHADER");
|
||||
|
||||
sconfig->fragmentShader.source = shaderSource;
|
||||
sconfig->fragmentShader.version = glslVersion;
|
||||
sconfig->fragmentShader.AddDefine("FRAGMENT_SHADER");
|
||||
|
||||
if (desc.first.GetType() == OpenSubdiv::FarPatchTables::QUADS) {
|
||||
// uniform catmark, bilinear
|
||||
sconfig->geometryShader.AddDefine("PRIM_QUAD");
|
||||
sconfig->fragmentShader.AddDefine("PRIM_QUAD");
|
||||
sconfig->commonShader.AddDefine("UNIFORM_SUBDIVISION");
|
||||
} else if (desc.first.GetType() == OpenSubdiv::FarPatchTables::TRIANGLES) {
|
||||
// uniform loop
|
||||
sconfig->geometryShader.AddDefine("PRIM_TRI");
|
||||
sconfig->fragmentShader.AddDefine("PRIM_TRI");
|
||||
sconfig->commonShader.AddDefine("LOOP");
|
||||
sconfig->commonShader.AddDefine("UNIFORM_SUBDIVISION");
|
||||
} else {
|
||||
// adaptive
|
||||
sconfig->vertexShader.source = shaderSource + sconfig->vertexShader.source;
|
||||
sconfig->tessControlShader.source = shaderSource + sconfig->tessControlShader.source;
|
||||
sconfig->tessEvalShader.source = shaderSource + sconfig->tessEvalShader.source;
|
||||
|
||||
sconfig->geometryShader.AddDefine("PRIM_TRI");
|
||||
sconfig->fragmentShader.AddDefine("PRIM_TRI");
|
||||
}
|
||||
|
||||
int displayStyle = effectDesc.GetDisplayStyle();
|
||||
switch (displayStyle) {
|
||||
case kWire:
|
||||
sconfig->commonShader.AddDefine("GEOMETRY_OUT_WIRE");
|
||||
break;
|
||||
case kWireShaded:
|
||||
sconfig->commonShader.AddDefine("GEOMETRY_OUT_LINE");
|
||||
break;
|
||||
case kShaded:
|
||||
sconfig->commonShader.AddDefine("GEOMETRY_OUT_FILL");
|
||||
break;
|
||||
case kVaryingColor:
|
||||
sconfig->commonShader.AddDefine("VARYING_COLOR");
|
||||
sconfig->commonShader.AddDefine("GEOMETRY_OUT_FILL");
|
||||
break;
|
||||
case kFaceVaryingColor:
|
||||
sconfig->commonShader.AddDefine("OSD_FVAR_WIDTH", "2");
|
||||
sconfig->commonShader.AddDefine("FACEVARYING_COLOR");
|
||||
sconfig->commonShader.AddDefine("GEOMETRY_OUT_FILL");
|
||||
break;
|
||||
}
|
||||
|
||||
return sconfig;
|
||||
|
||||
}
|
||||
|
||||
MyEffectRegistry::ConfigType *
|
||||
MyEffectRegistry::_CreateDrawConfig(DescType const & desc, SourceConfigType const * sconfig) {
|
||||
|
||||
// XXX: make sure is this downcast correct
|
||||
ConfigType * config = (ConfigType *)BaseRegistry::_CreateDrawConfig(desc.first, sconfig);
|
||||
assert(config);
|
||||
|
||||
GLuint uboIndex;
|
||||
GLuint program = config->program;
|
||||
|
||||
GLuint g_transformBinding = 0,
|
||||
g_tessellationBinding = 0,
|
||||
g_lightingBinding = 0;
|
||||
|
||||
// XXXdyu can use layout(binding=) with GLSL 4.20 and beyond
|
||||
g_transformBinding = 0;
|
||||
uboIndex = glGetUniformBlockIndex(program, "Transform");
|
||||
if (uboIndex != GL_INVALID_INDEX)
|
||||
glUniformBlockBinding(program, uboIndex, g_transformBinding);
|
||||
|
||||
g_tessellationBinding = 1;
|
||||
uboIndex = glGetUniformBlockIndex(program, "Tessellation");
|
||||
if (uboIndex != GL_INVALID_INDEX)
|
||||
glUniformBlockBinding(program, uboIndex, g_tessellationBinding);
|
||||
|
||||
g_lightingBinding = 3;
|
||||
uboIndex = glGetUniformBlockIndex(program, "Lighting");
|
||||
if (uboIndex != GL_INVALID_INDEX)
|
||||
glUniformBlockBinding(program, uboIndex, g_lightingBinding);
|
||||
|
||||
// currently, these are used only in conjunction with tessellation shaders
|
||||
#if defined(GL_EXT_direct_state_access) || defined(GL_VERSION_4_1)
|
||||
GLint loc;
|
||||
if ((loc = glGetUniformLocation(program, "OsdVertexBuffer")) != -1) {
|
||||
glProgramUniform1i(program, loc, 0); // GL_TEXTURE0
|
||||
}
|
||||
if ((loc = glGetUniformLocation(program, "OsdValenceBuffer")) != -1) {
|
||||
glProgramUniform1i(program, loc, 1); // GL_TEXTURE1
|
||||
}
|
||||
if ((loc = glGetUniformLocation(program, "OsdQuadOffsetBuffer")) != -1) {
|
||||
glProgramUniform1i(program, loc, 2); // GL_TEXTURE2
|
||||
}
|
||||
if ((loc = glGetUniformLocation(program, "OsdPatchParamBuffer")) != -1) {
|
||||
glProgramUniform1i(program, loc, 3); // GL_TEXTURE3
|
||||
}
|
||||
if ((loc = glGetUniformLocation(program, "OsdFVarDataBuffer")) != -1) {
|
||||
glProgramUniform1i(program, loc, 4); // GL_TEXTURE4
|
||||
}
|
||||
#endif
|
||||
|
||||
config->diffuseColorUniform = glGetUniformLocation(program, "diffuseColor");
|
||||
|
||||
config->gregoryQuadOffsetBaseUniform =
|
||||
glGetUniformLocation(program, "GregoryQuadOffsetBase");
|
||||
|
||||
config->primitiveIdBaseUniform =
|
||||
glGetUniformLocation(program, "PrimitiveIdBase");
|
||||
|
||||
return config;
|
||||
}
|
@ -1,400 +0,0 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "Apache License")
|
||||
// with the following modification; you may not use this file except in
|
||||
// compliance with the Apache License and the following modification to it:
|
||||
// Section 6. Trademarks. is deleted and replaced with:
|
||||
//
|
||||
// 6. Trademarks. This License does not grant permission to use the trade
|
||||
// names, trademarks, service marks, or product names of the Licensor
|
||||
// and its affiliates, except as required to comply with Section 4(c) of
|
||||
// the License and to reproduce the content of the NOTICE file.
|
||||
//
|
||||
// You may obtain a copy of the Apache License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the Apache License with the above modification is
|
||||
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the Apache License for the specific
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
|
||||
#if defined(VARYING_COLOR) || defined(FACEVARYING_COLOR)
|
||||
#undef OSD_USER_VARYING_DECLARE
|
||||
#define OSD_USER_VARYING_DECLARE \
|
||||
vec3 color;
|
||||
|
||||
#undef OSD_USER_VARYING_ATTRIBUTE_DECLARE
|
||||
#define OSD_USER_VARYING_ATTRIBUTE_DECLARE \
|
||||
layout(location = 1) in vec3 color;
|
||||
|
||||
#undef OSD_USER_VARYING_PER_VERTEX
|
||||
#define OSD_USER_VARYING_PER_VERTEX() \
|
||||
outpt.color = color
|
||||
|
||||
#undef OSD_USER_VARYING_PER_CONTROL_POINT
|
||||
#define OSD_USER_VARYING_PER_CONTROL_POINT(ID_OUT, ID_IN) \
|
||||
outpt[ID_OUT].color = inpt[ID_IN].color
|
||||
|
||||
#undef OSD_USER_VARYING_PER_EVAL_POINT
|
||||
#define OSD_USER_VARYING_PER_EVAL_POINT(UV, a, b, c, d) \
|
||||
outpt.color = \
|
||||
mix(mix(inpt[a].color, inpt[b].color, UV.x), \
|
||||
mix(inpt[c].color, inpt[d].color, UV.x), UV.y)
|
||||
|
||||
#else
|
||||
#define OSD_USER_VARYING_DECLARE
|
||||
#define OSD_USER_VARYING_ATTRIBUTE_DECLARE
|
||||
#define OSD_USER_VARYING_PER_VERTEX()
|
||||
#define OSD_USER_VARYING_PER_CONTROL_POINT(ID_OUT, ID_IN)
|
||||
#define OSD_USER_VARYING_PER_EVAL_POINT(UV, a, b, c, d)
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Uniforms / Uniform Blocks
|
||||
//--------------------------------------------------------------
|
||||
|
||||
layout(std140) uniform Transform {
|
||||
mat4 ModelViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 ModelViewProjectionMatrix;
|
||||
mat4 ModelViewInverseMatrix;
|
||||
};
|
||||
|
||||
layout(std140) uniform Tessellation {
|
||||
float TessLevel;
|
||||
};
|
||||
|
||||
uniform int GregoryQuadOffsetBase;
|
||||
uniform int PrimitiveIdBase;
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Osd external functions
|
||||
//--------------------------------------------------------------
|
||||
|
||||
mat4 OsdModelViewMatrix()
|
||||
{
|
||||
return ModelViewMatrix;
|
||||
}
|
||||
mat4 OsdProjectionMatrix()
|
||||
{
|
||||
return ProjectionMatrix;
|
||||
}
|
||||
mat4 OsdModelViewProjectionMatrix()
|
||||
{
|
||||
return ModelViewProjectionMatrix;
|
||||
}
|
||||
float OsdTessLevel()
|
||||
{
|
||||
return TessLevel;
|
||||
}
|
||||
int OsdGregoryQuadOffsetBase()
|
||||
{
|
||||
return GregoryQuadOffsetBase;
|
||||
}
|
||||
int OsdPrimitiveIdBase()
|
||||
{
|
||||
return PrimitiveIdBase;
|
||||
}
|
||||
int OsdBaseVertex()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Vertex Shader
|
||||
//--------------------------------------------------------------
|
||||
#ifdef VERTEX_SHADER
|
||||
|
||||
layout (location=0) in vec4 position;
|
||||
OSD_USER_VARYING_ATTRIBUTE_DECLARE
|
||||
|
||||
out block {
|
||||
OutputVertex v;
|
||||
OSD_USER_VARYING_DECLARE
|
||||
} outpt;
|
||||
|
||||
void main()
|
||||
{
|
||||
outpt.v.position = ModelViewMatrix * position;
|
||||
OSD_USER_VARYING_PER_VERTEX();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Geometry Shader
|
||||
//--------------------------------------------------------------
|
||||
#ifdef GEOMETRY_SHADER
|
||||
|
||||
#ifdef PRIM_QUAD
|
||||
|
||||
layout(lines_adjacency) in;
|
||||
|
||||
#define EDGE_VERTS 4
|
||||
|
||||
#endif // PRIM_QUAD
|
||||
|
||||
#ifdef PRIM_TRI
|
||||
|
||||
layout(triangles) in;
|
||||
|
||||
#define EDGE_VERTS 3
|
||||
|
||||
#endif // PRIM_TRI
|
||||
|
||||
|
||||
uniform samplerBuffer g_uvFVarBuffer;
|
||||
|
||||
layout(triangle_strip, max_vertices = EDGE_VERTS) out;
|
||||
in block {
|
||||
OutputVertex v;
|
||||
OSD_USER_VARYING_DECLARE
|
||||
} inpt[EDGE_VERTS];
|
||||
|
||||
out block {
|
||||
OutputVertex v;
|
||||
noperspective out vec4 edgeDistance;
|
||||
OSD_USER_VARYING_DECLARE
|
||||
} outpt;
|
||||
|
||||
void emit(int index, vec3 normal)
|
||||
{
|
||||
outpt.v.position = inpt[index].v.position;
|
||||
#ifdef SMOOTH_NORMALS
|
||||
outpt.v.normal = inpt[index].v.normal;
|
||||
#else
|
||||
outpt.v.normal = normal;
|
||||
#endif
|
||||
|
||||
#ifdef VARYING_COLOR
|
||||
outpt.color = inpt[index].color;
|
||||
#endif
|
||||
|
||||
#ifdef FACEVARYING_COLOR
|
||||
#ifdef LOOP // ----- scheme : LOOP
|
||||
vec2 uv;
|
||||
OSD_COMPUTE_FACE_VARYING_TRI_2(uv, /*fvarOffste=*/0, index);
|
||||
|
||||
#else // ----- scheme : CATMARK / BILINEAR
|
||||
|
||||
#ifdef UNIFORM_SUBDIVISION
|
||||
vec2 quadst[4] = vec2[](vec2(0,0), vec2(1,0), vec2(1,1), vec2(0,1));
|
||||
vec2 st = quadst[index];
|
||||
#else
|
||||
vec2 st = inpt[index].v.tessCoord;
|
||||
#endif
|
||||
vec2 uv;
|
||||
OSD_COMPUTE_FACE_VARYING_2(uv, /*fvarOffset=*/0, st);
|
||||
#endif // ------ scheme
|
||||
outpt.color = vec3(uv.s, uv.t, 0);
|
||||
#endif
|
||||
|
||||
gl_Position = ProjectionMatrix * inpt[index].v.position;
|
||||
EmitVertex();
|
||||
}
|
||||
|
||||
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
|
||||
const float VIEWPORT_SCALE = 1024.0; // XXXdyu
|
||||
|
||||
float edgeDistance(vec4 p, vec4 p0, vec4 p1)
|
||||
{
|
||||
return VIEWPORT_SCALE *
|
||||
abs((p.x - p0.x) * (p1.y - p0.y) -
|
||||
(p.y - p0.y) * (p1.x - p0.x)) / length(p1.xy - p0.xy);
|
||||
}
|
||||
|
||||
void emit(int index, vec3 normal, vec4 edgeVerts[EDGE_VERTS])
|
||||
{
|
||||
outpt.edgeDistance[0] =
|
||||
edgeDistance(edgeVerts[index], edgeVerts[0], edgeVerts[1]);
|
||||
outpt.edgeDistance[1] =
|
||||
edgeDistance(edgeVerts[index], edgeVerts[1], edgeVerts[2]);
|
||||
#ifdef PRIM_TRI
|
||||
outpt.edgeDistance[2] =
|
||||
edgeDistance(edgeVerts[index], edgeVerts[2], edgeVerts[0]);
|
||||
#endif
|
||||
#ifdef PRIM_QUAD
|
||||
outpt.edgeDistance[2] =
|
||||
edgeDistance(edgeVerts[index], edgeVerts[2], edgeVerts[3]);
|
||||
outpt.edgeDistance[3] =
|
||||
edgeDistance(edgeVerts[index], edgeVerts[3], edgeVerts[0]);
|
||||
#endif
|
||||
|
||||
emit(index, normal);
|
||||
}
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_PrimitiveID = gl_PrimitiveIDIn;
|
||||
|
||||
#ifdef PRIM_QUAD
|
||||
vec3 A = (inpt[0].v.position - inpt[1].v.position).xyz;
|
||||
vec3 B = (inpt[3].v.position - inpt[1].v.position).xyz;
|
||||
vec3 C = (inpt[2].v.position - inpt[1].v.position).xyz;
|
||||
vec3 n0 = normalize(cross(B, A));
|
||||
|
||||
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
|
||||
vec4 edgeVerts[EDGE_VERTS];
|
||||
edgeVerts[0] = ProjectionMatrix * inpt[0].v.position;
|
||||
edgeVerts[1] = ProjectionMatrix * inpt[1].v.position;
|
||||
edgeVerts[2] = ProjectionMatrix * inpt[2].v.position;
|
||||
edgeVerts[3] = ProjectionMatrix * inpt[3].v.position;
|
||||
|
||||
edgeVerts[0].xy /= edgeVerts[0].w;
|
||||
edgeVerts[1].xy /= edgeVerts[1].w;
|
||||
edgeVerts[2].xy /= edgeVerts[2].w;
|
||||
edgeVerts[3].xy /= edgeVerts[3].w;
|
||||
|
||||
emit(0, n0, edgeVerts);
|
||||
emit(1, n0, edgeVerts);
|
||||
emit(3, n0, edgeVerts);
|
||||
emit(2, n0, edgeVerts);
|
||||
#else
|
||||
emit(0, n0);
|
||||
emit(1, n0);
|
||||
emit(3, n0);
|
||||
emit(2, n0);
|
||||
#endif
|
||||
#endif // PRIM_QUAD
|
||||
|
||||
#ifdef PRIM_TRI
|
||||
vec3 A = (inpt[1].v.position - inpt[0].v.position).xyz;
|
||||
vec3 B = (inpt[2].v.position - inpt[0].v.position).xyz;
|
||||
vec3 n0 = normalize(cross(B, A));
|
||||
|
||||
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
|
||||
vec4 edgeVerts[EDGE_VERTS];
|
||||
edgeVerts[0] = ProjectionMatrix * inpt[0].v.position;
|
||||
edgeVerts[1] = ProjectionMatrix * inpt[1].v.position;
|
||||
edgeVerts[2] = ProjectionMatrix * inpt[2].v.position;
|
||||
|
||||
edgeVerts[0].xy /= edgeVerts[0].w;
|
||||
edgeVerts[1].xy /= edgeVerts[1].w;
|
||||
edgeVerts[2].xy /= edgeVerts[2].w;
|
||||
|
||||
emit(0, n0, edgeVerts);
|
||||
emit(1, n0, edgeVerts);
|
||||
emit(2, n0, edgeVerts);
|
||||
#else
|
||||
emit(0, n0);
|
||||
emit(1, n0);
|
||||
emit(2, n0);
|
||||
#endif
|
||||
#endif // PRIM_TRI
|
||||
|
||||
EndPrimitive();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Fragment Shader
|
||||
//--------------------------------------------------------------
|
||||
#ifdef FRAGMENT_SHADER
|
||||
|
||||
in block {
|
||||
OutputVertex v;
|
||||
noperspective in vec4 edgeDistance;
|
||||
OSD_USER_VARYING_DECLARE
|
||||
} inpt;
|
||||
|
||||
out vec4 outColor;
|
||||
|
||||
#define NUM_LIGHTS 2
|
||||
|
||||
struct LightSource {
|
||||
vec4 position;
|
||||
vec4 ambient;
|
||||
vec4 diffuse;
|
||||
vec4 specular;
|
||||
};
|
||||
|
||||
layout(std140) uniform Lighting {
|
||||
LightSource lightSource[NUM_LIGHTS];
|
||||
};
|
||||
|
||||
uniform vec4 diffuseColor = vec4(1);
|
||||
uniform vec4 ambientColor = vec4(1);
|
||||
|
||||
vec4
|
||||
lighting(vec4 diffuse, vec3 Peye, vec3 Neye)
|
||||
{
|
||||
vec4 color = vec4(0);
|
||||
|
||||
for (int i = 0; i < NUM_LIGHTS; ++i) {
|
||||
|
||||
vec4 Plight = lightSource[i].position;
|
||||
|
||||
vec3 l = (Plight.w == 0.0)
|
||||
? normalize(Plight.xyz) : normalize(Plight.xyz - Peye);
|
||||
|
||||
vec3 n = normalize(Neye);
|
||||
vec3 h = normalize(l + vec3(0,0,1)); // directional viewer
|
||||
|
||||
float d = max(0.0, dot(n, l));
|
||||
float s = pow(max(0.0, dot(n, h)), 500.0f);
|
||||
|
||||
color += lightSource[i].ambient * diffuse * ambientColor
|
||||
+ d * lightSource[i].diffuse * diffuse
|
||||
+ s * lightSource[i].specular;
|
||||
}
|
||||
|
||||
color.a = 1;
|
||||
return color;
|
||||
}
|
||||
|
||||
vec4
|
||||
edgeColor(vec4 Cfill, vec4 edgeDistance)
|
||||
{
|
||||
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
|
||||
#ifdef PRIM_TRI
|
||||
float d =
|
||||
min(inpt.edgeDistance[0], min(inpt.edgeDistance[1], inpt.edgeDistance[2]));
|
||||
#endif
|
||||
#ifdef PRIM_QUAD
|
||||
float d =
|
||||
min(min(inpt.edgeDistance[0], inpt.edgeDistance[1]),
|
||||
min(inpt.edgeDistance[2], inpt.edgeDistance[3]));
|
||||
#endif
|
||||
vec4 Cedge = vec4(1.0, 1.0, 0.0, 1.0);
|
||||
float p = exp2(-2 * d * d);
|
||||
|
||||
#if defined(GEOMETRY_OUT_WIRE)
|
||||
if (p < 0.25) discard;
|
||||
#endif
|
||||
|
||||
Cfill.rgb = mix(Cfill.rgb, Cedge.rgb, p);
|
||||
#endif
|
||||
return Cfill;
|
||||
}
|
||||
|
||||
#if defined(PRIM_QUAD) || defined(PRIM_TRI)
|
||||
void
|
||||
main()
|
||||
{
|
||||
vec3 N = (gl_FrontFacing ? inpt.v.normal : -inpt.v.normal);
|
||||
|
||||
#if defined(VARYING_COLOR)
|
||||
vec4 color = vec4(inpt.color, 1);
|
||||
#elif defined(FACEVARYING_COLOR)
|
||||
vec4 color = vec4(inpt.color.rg, int(floor(20*inpt.color.r)+floor(20*inpt.color.g))&1, 1);
|
||||
#else
|
||||
vec4 color = diffuseColor;
|
||||
#endif
|
||||
|
||||
vec4 Cf = lighting(color, inpt.v.position.xyz, N);
|
||||
|
||||
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
|
||||
Cf = edgeColor(Cf, inpt.edgeDistance);
|
||||
#endif
|
||||
|
||||
outColor = Cf;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,310 +0,0 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "Apache License")
|
||||
// with the following modification; you may not use this file except in
|
||||
// compliance with the Apache License and the following modification to it:
|
||||
// Section 6. Trademarks. is deleted and replaced with:
|
||||
//
|
||||
// 6. Trademarks. This License does not grant permission to use the trade
|
||||
// names, trademarks, service marks, or product names of the Licensor
|
||||
// and its affiliates, except as required to comply with Section 4(c) of
|
||||
// the License and to reproduce the content of the NOTICE file.
|
||||
//
|
||||
// You may obtain a copy of the Apache License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the Apache License with the above modification is
|
||||
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the Apache License for the specific
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
|
||||
layout(std140) uniform Transform {
|
||||
mat4 ModelViewMatrix;
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 ModelViewProjectionMatrix;
|
||||
mat4 ModelViewInverseMatrix;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Vertex Shader
|
||||
//--------------------------------------------------------------
|
||||
#ifdef VERTEX_SHADER
|
||||
|
||||
layout (location=0) in vec4 position;
|
||||
layout (location=1) in vec3 normal;
|
||||
|
||||
out vec4 vPosition;
|
||||
out vec3 vNormal;
|
||||
|
||||
void main()
|
||||
{
|
||||
vPosition = ModelViewMatrix * position;
|
||||
vNormal = (ModelViewMatrix * vec4(normal, 0.0)).xyz;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Geometry Shader
|
||||
//--------------------------------------------------------------
|
||||
#ifdef GEOMETRY_SHADER
|
||||
|
||||
#ifdef PRIM_QUAD
|
||||
|
||||
layout(lines_adjacency) in;
|
||||
|
||||
layout(triangle_strip, max_vertices = 4) out;
|
||||
|
||||
#define EDGE_VERTS 4
|
||||
|
||||
in vec4 vPosition[4];
|
||||
in vec3 vNormal[4];
|
||||
|
||||
#endif // PRIM_QUAD
|
||||
|
||||
#ifdef PRIM_TRI
|
||||
|
||||
layout(triangles) in;
|
||||
|
||||
layout(triangle_strip, max_vertices = 3) out;
|
||||
|
||||
#define EDGE_VERTS 3
|
||||
|
||||
in vec4 vPosition[3];
|
||||
in vec3 vNormal[3];
|
||||
|
||||
#endif // PRIM_TRI
|
||||
|
||||
#ifdef PRIM_POINT
|
||||
|
||||
layout(points) in;
|
||||
layout(points, max_vertices = 1) out;
|
||||
|
||||
in vec4 vPosition[1];
|
||||
in vec3 vNormal[1];
|
||||
|
||||
#endif // PRIM_POINT
|
||||
|
||||
out vec4 gPosition;
|
||||
out vec3 gNormal;
|
||||
noperspective out vec4 gEdgeDistance;
|
||||
|
||||
void emit(int index, vec3 normal)
|
||||
{
|
||||
gPosition = vPosition[index];
|
||||
#ifdef SMOOTH_NORMALS
|
||||
gNormal = vNormal[index];
|
||||
#else
|
||||
gNormal = normal;
|
||||
#endif
|
||||
gl_Position = ProjectionMatrix * vPosition[index];
|
||||
EmitVertex();
|
||||
}
|
||||
|
||||
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
|
||||
const float VIEWPORT_SCALE = 1024.0; // XXXdyu
|
||||
|
||||
float edgeDistance(vec4 p, vec4 p0, vec4 p1)
|
||||
{
|
||||
return VIEWPORT_SCALE *
|
||||
abs((p.x - p0.x) * (p1.y - p0.y) -
|
||||
(p.y - p0.y) * (p1.x - p0.x)) / length(p1.xy - p0.xy);
|
||||
}
|
||||
|
||||
void emit(int index, vec3 normal, vec4 edgeVerts[EDGE_VERTS])
|
||||
{
|
||||
gEdgeDistance[0] =
|
||||
edgeDistance(edgeVerts[index], edgeVerts[0], edgeVerts[1]);
|
||||
gEdgeDistance[1] =
|
||||
edgeDistance(edgeVerts[index], edgeVerts[1], edgeVerts[2]);
|
||||
#ifdef PRIM_TRI
|
||||
gEdgeDistance[2] =
|
||||
edgeDistance(edgeVerts[index], edgeVerts[2], edgeVerts[0]);
|
||||
#endif
|
||||
#ifdef PRIM_QUAD
|
||||
gEdgeDistance[2] =
|
||||
edgeDistance(edgeVerts[index], edgeVerts[2], edgeVerts[3]);
|
||||
gEdgeDistance[3] =
|
||||
edgeDistance(edgeVerts[index], edgeVerts[3], edgeVerts[0]);
|
||||
#endif
|
||||
|
||||
emit(index, normal);
|
||||
}
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_PrimitiveID = gl_PrimitiveIDIn;
|
||||
|
||||
#ifdef PRIM_POINT
|
||||
emit(0, vec3(0));
|
||||
#endif
|
||||
|
||||
#ifdef PRIM_QUAD
|
||||
vec3 A = (vPosition[0] - vPosition[1]).xyz;
|
||||
vec3 B = (vPosition[3] - vPosition[1]).xyz;
|
||||
vec3 C = (vPosition[2] - vPosition[1]).xyz;
|
||||
vec3 n0 = normalize(cross(B, A));
|
||||
|
||||
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
|
||||
vec4 edgeVerts[EDGE_VERTS];
|
||||
edgeVerts[0] = ProjectionMatrix * vPosition[0];
|
||||
edgeVerts[1] = ProjectionMatrix * vPosition[1];
|
||||
edgeVerts[2] = ProjectionMatrix * vPosition[2];
|
||||
edgeVerts[3] = ProjectionMatrix * vPosition[3];
|
||||
|
||||
edgeVerts[0].xy /= edgeVerts[0].w;
|
||||
edgeVerts[1].xy /= edgeVerts[1].w;
|
||||
edgeVerts[2].xy /= edgeVerts[2].w;
|
||||
edgeVerts[3].xy /= edgeVerts[3].w;
|
||||
|
||||
emit(0, n0, edgeVerts);
|
||||
emit(1, n0, edgeVerts);
|
||||
emit(3, n0, edgeVerts);
|
||||
emit(2, n0, edgeVerts);
|
||||
#else
|
||||
emit(0, n0);
|
||||
emit(1, n0);
|
||||
emit(3, n0);
|
||||
emit(2, n0);
|
||||
#endif
|
||||
#endif // PRIM_QUAD
|
||||
|
||||
#ifdef PRIM_TRI
|
||||
vec3 A = (vPosition[1] - vPosition[0]).xyz;
|
||||
vec3 B = (vPosition[2] - vPosition[0]).xyz;
|
||||
vec3 n0 = normalize(cross(B, A));
|
||||
|
||||
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
|
||||
vec4 edgeVerts[EDGE_VERTS];
|
||||
edgeVerts[0] = ProjectionMatrix * vPosition[0];
|
||||
edgeVerts[1] = ProjectionMatrix * vPosition[1];
|
||||
edgeVerts[2] = ProjectionMatrix * vPosition[2];
|
||||
|
||||
edgeVerts[0].xy /= edgeVerts[0].w;
|
||||
edgeVerts[1].xy /= edgeVerts[1].w;
|
||||
edgeVerts[2].xy /= edgeVerts[2].w;
|
||||
|
||||
emit(0, n0, edgeVerts);
|
||||
emit(1, n0, edgeVerts);
|
||||
emit(2, n0, edgeVerts);
|
||||
#else
|
||||
emit(0, n0);
|
||||
emit(1, n0);
|
||||
emit(2, n0);
|
||||
#endif
|
||||
#endif // PRIM_TRI
|
||||
|
||||
EndPrimitive();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Fragment Shader
|
||||
//--------------------------------------------------------------
|
||||
#ifdef FRAGMENT_SHADER
|
||||
|
||||
in vec4 gPosition;
|
||||
in vec3 gNormal;
|
||||
noperspective in vec4 gEdgeDistance;
|
||||
|
||||
out vec4 outColor;
|
||||
|
||||
#define NUM_LIGHTS 2
|
||||
|
||||
struct LightSource {
|
||||
vec4 position;
|
||||
vec4 ambient;
|
||||
vec4 diffuse;
|
||||
vec4 specular;
|
||||
};
|
||||
|
||||
layout(std140) uniform Lighting {
|
||||
LightSource lightSource[NUM_LIGHTS];
|
||||
};
|
||||
|
||||
uniform vec4 diffuseColor = vec4(1);
|
||||
uniform vec4 ambientColor = vec4(1);
|
||||
|
||||
vec4
|
||||
lighting(vec3 Peye, vec3 Neye)
|
||||
{
|
||||
vec4 color = vec4(0);
|
||||
|
||||
for (int i = 0; i < NUM_LIGHTS; ++i) {
|
||||
|
||||
vec4 Plight = lightSource[i].position;
|
||||
|
||||
vec3 l = (Plight.w == 0.0)
|
||||
? normalize(Plight.xyz) : normalize(Plight.xyz - Peye);
|
||||
|
||||
vec3 n = normalize(Neye);
|
||||
vec3 h = normalize(l + vec3(0,0,1)); // directional viewer
|
||||
|
||||
float d = max(0.0, dot(n, l));
|
||||
float s = pow(max(0.0, dot(n, h)), 500.0f);
|
||||
|
||||
color += lightSource[i].ambient * ambientColor
|
||||
+ d * lightSource[i].diffuse * diffuseColor
|
||||
+ s * lightSource[i].specular;
|
||||
}
|
||||
|
||||
color.a = 1;
|
||||
return color;
|
||||
}
|
||||
|
||||
#ifdef PRIM_POINT
|
||||
uniform vec4 fragColor;
|
||||
void
|
||||
main()
|
||||
{
|
||||
outColor = fragColor;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec4
|
||||
edgeColor(vec4 Cfill, vec4 edgeDistance)
|
||||
{
|
||||
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
|
||||
#ifdef PRIM_TRI
|
||||
float d =
|
||||
min(gEdgeDistance[0], min(gEdgeDistance[1], gEdgeDistance[2]));
|
||||
#endif
|
||||
#ifdef PRIM_QUAD
|
||||
float d =
|
||||
min(min(gEdgeDistance[0], gEdgeDistance[1]),
|
||||
min(gEdgeDistance[2], gEdgeDistance[3]));
|
||||
#endif
|
||||
vec4 Cedge = vec4(1.0, 1.0, 0.0, 1.0);
|
||||
float p = exp2(-2 * d * d);
|
||||
|
||||
#if defined(GEOMETRY_OUT_WIRE)
|
||||
if (p < 0.25) discard;
|
||||
#endif
|
||||
|
||||
Cfill.rgb = mix(Cfill.rgb, Cedge.rgb, p);
|
||||
#endif
|
||||
return Cfill;
|
||||
}
|
||||
|
||||
#if defined(PRIM_QUAD) || defined(PRIM_TRI)
|
||||
void
|
||||
main()
|
||||
{
|
||||
vec3 N = (gl_FrontFacing ? gNormal : -gNormal);
|
||||
vec4 Cf = lighting(gPosition.xyz, N);
|
||||
|
||||
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
|
||||
Cf = edgeColor(Cf, gEdgeDistance);
|
||||
#endif
|
||||
|
||||
outColor = Cf;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,162 +0,0 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "Apache License")
|
||||
// with the following modification; you may not use this file except in
|
||||
// compliance with the Apache License and the following modification to it:
|
||||
// Section 6. Trademarks. is deleted and replaced with:
|
||||
//
|
||||
// 6. Trademarks. This License does not grant permission to use the trade
|
||||
// names, trademarks, service marks, or product names of the Licensor
|
||||
// and its affiliates, except as required to comply with Section 4(c) of
|
||||
// the License and to reproduce the content of the NOTICE file.
|
||||
//
|
||||
// You may obtain a copy of the Apache License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the Apache License with the above modification is
|
||||
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the Apache License for the specific
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
|
||||
void initializeShapes( ) {
|
||||
|
||||
#include <shapes/catmark_cube_corner0.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_cube_corner0, "catmark_cube_corner0", kCatmark));
|
||||
|
||||
#include <shapes/catmark_cube_corner1.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_cube_corner1, "catmark_cube_corner1", kCatmark));
|
||||
|
||||
#include <shapes/catmark_cube_corner2.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_cube_corner2, "catmark_cube_corner2", kCatmark));
|
||||
|
||||
#include <shapes/catmark_cube_corner3.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_cube_corner3, "catmark_cube_corner3", kCatmark));
|
||||
|
||||
#include <shapes/catmark_cube_corner4.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_cube_corner4, "catmark_cube_corner4", kCatmark));
|
||||
|
||||
#include <shapes/catmark_cube_creases0.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_cube_creases0, "catmark_cube_creases0", kCatmark));
|
||||
|
||||
#include <shapes/catmark_cube_creases1.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_cube_creases1, "catmark_cube_creases1", kCatmark));
|
||||
|
||||
#include <shapes/catmark_cube.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_cube, "catmark_cube", kCatmark));
|
||||
|
||||
#include <shapes/catmark_dart_edgecorner.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_dart_edgecorner, "catmark_dart_edgecorner", kCatmark));
|
||||
|
||||
#include <shapes/catmark_dart_edgeonly.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_dart_edgeonly, "catmark_dart_edgeonly", kCatmark));
|
||||
|
||||
#include <shapes/catmark_edgecorner.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_edgecorner ,"catmark_edgecorner", kCatmark));
|
||||
|
||||
#include <shapes/catmark_edgeonly.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_edgeonly, "catmark_edgeonly", kCatmark));
|
||||
|
||||
#include <shapes/catmark_gregory_test1.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_gregory_test1, "catmark_gregory_test1", kCatmark));
|
||||
|
||||
#include <shapes/catmark_gregory_test2.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_gregory_test2, "catmark_gregory_test2", kCatmark));
|
||||
|
||||
#include <shapes/catmark_gregory_test3.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_gregory_test3, "catmark_gregory_test3", kCatmark));
|
||||
|
||||
#include <shapes/catmark_gregory_test4.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_gregory_test4, "catmark_gregory_test4", kCatmark));
|
||||
|
||||
#include <shapes/catmark_pyramid_creases0.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_pyramid_creases0, "catmark_pyramid_creases0", kCatmark));
|
||||
|
||||
#include <shapes/catmark_pyramid_creases1.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_pyramid_creases1, "catmark_pyramid_creases1", kCatmark));
|
||||
|
||||
#include <shapes/catmark_pyramid.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_pyramid, "catmark_pyramid", kCatmark));
|
||||
|
||||
#include <shapes/catmark_tent_creases0.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_tent_creases0, "catmark_tent_creases0", kCatmark));
|
||||
|
||||
#include <shapes/catmark_tent_creases1.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_tent_creases1, "catmark_tent_creases1", kCatmark));
|
||||
|
||||
#include <shapes/catmark_tent.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_tent, "catmark_tent", kCatmark));
|
||||
|
||||
#include <shapes/catmark_torus.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_torus, "catmark_torus", kCatmark));
|
||||
|
||||
#include <shapes/catmark_torus_creases0.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_torus_creases0, "catmark_torus_creases0", kCatmark));
|
||||
|
||||
#include <shapes/catmark_square_hedit0.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_square_hedit0, "catmark_square_hedit0", kCatmark));
|
||||
|
||||
#include <shapes/catmark_square_hedit1.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_square_hedit1, "catmark_square_hedit1", kCatmark));
|
||||
|
||||
#include <shapes/catmark_square_hedit2.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_square_hedit2, "catmark_square_hedit2", kCatmark));
|
||||
|
||||
#include <shapes/catmark_square_hedit3.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_square_hedit3, "catmark_square_hedit3", kCatmark));
|
||||
|
||||
|
||||
|
||||
//#ifndef WIN32 // exceeds max string literal (65535 chars)
|
||||
//#include <shapes/catmark_bishop.h>
|
||||
// g_defaultShapes.push_back(SimpleShape(catmark_bishop, "catmark_bishop", kCatmark));
|
||||
//#endif
|
||||
|
||||
#ifndef WIN32 // exceeds max string literal (65535 chars)
|
||||
#include <shapes/catmark_car.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_car, "catmark_car", kCatmark));
|
||||
#endif
|
||||
|
||||
#include <shapes/catmark_helmet.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_helmet, "catmark_helmet", kCatmark));
|
||||
|
||||
#include <shapes/catmark_pawn.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_pawn, "catmark_pawn", kCatmark));
|
||||
|
||||
#ifndef WIN32 // exceeds max string literal (65535 chars)
|
||||
#include <shapes/catmark_rook.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_rook, "catmark_rook", kCatmark));
|
||||
#endif
|
||||
|
||||
|
||||
#include <shapes/bilinear_cube.h>
|
||||
g_defaultShapes.push_back(SimpleShape(bilinear_cube, "bilinear_cube", kBilinear));
|
||||
|
||||
|
||||
#include <shapes/loop_cube_creases0.h>
|
||||
g_defaultShapes.push_back(SimpleShape(loop_cube_creases0, "loop_cube_creases0", kLoop));
|
||||
|
||||
#include <shapes/loop_cube_creases1.h>
|
||||
g_defaultShapes.push_back(SimpleShape(loop_cube_creases1, "loop_cube_creases1", kLoop));
|
||||
|
||||
#include <shapes/loop_cube.h>
|
||||
g_defaultShapes.push_back(SimpleShape(loop_cube, "loop_cube", kLoop));
|
||||
|
||||
#include <shapes/loop_icosahedron.h>
|
||||
g_defaultShapes.push_back(SimpleShape(loop_icosahedron, "loop_icosahedron", kLoop));
|
||||
|
||||
#include <shapes/loop_saddle_edgecorner.h>
|
||||
g_defaultShapes.push_back(SimpleShape(loop_saddle_edgecorner, "loop_saddle_edgecorner", kLoop));
|
||||
|
||||
#include <shapes/loop_saddle_edgeonly.h>
|
||||
g_defaultShapes.push_back(SimpleShape(loop_saddle_edgeonly, "loop_saddle_edgeonly", kLoop));
|
||||
|
||||
#include <shapes/loop_triangle_edgecorner.h>
|
||||
g_defaultShapes.push_back(SimpleShape(loop_triangle_edgecorner, "loop_triangle_edgecorner", kLoop));
|
||||
|
||||
#include <shapes/loop_triangle_edgeonly.h>
|
||||
g_defaultShapes.push_back(SimpleShape(loop_triangle_edgeonly, "loop_triangle_edgeonly", kLoop));
|
||||
}
|
@ -44,14 +44,15 @@ if( OPENCL_FOUND )
|
||||
include_directories("${OPENCL_INCLUDE_DIRS}")
|
||||
endif()
|
||||
|
||||
_add_glfw_executable(limitEval
|
||||
main.cpp
|
||||
_add_glfw_executable(glEvalLimit
|
||||
glEvalLimit.cpp
|
||||
"${INC_FILES}"
|
||||
$<TARGET_OBJECTS:regression_common_obj>
|
||||
$<TARGET_OBJECTS:examples_common_obj>
|
||||
)
|
||||
|
||||
target_link_libraries(limitEval
|
||||
target_link_libraries(glEvalLimit
|
||||
${PLATFORM_LIBRARIES}
|
||||
)
|
||||
|
||||
install(TARGETS limitEval DESTINATION "${CMAKE_BINDIR_BASE}")
|
||||
install(TARGETS glEvalLimit DESTINATION "${CMAKE_BINDIR_BASE}")
|
@ -38,13 +38,9 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_VERSION_3)
|
||||
#include <GLFW/glfw3.h>
|
||||
GLFWwindow* g_window=0;
|
||||
GLFWmonitor* g_primary=0;
|
||||
#else
|
||||
#include <GL/glfw.h>
|
||||
#endif
|
||||
#include <GLFW/glfw3.h>
|
||||
GLFWwindow* g_window=0;
|
||||
GLFWmonitor* g_primary=0;
|
||||
|
||||
#include <osd/cpuComputeContext.h>
|
||||
#include <osd/cpuComputeController.h>
|
||||
@ -57,13 +53,16 @@
|
||||
#include <osd/mesh.h>
|
||||
#include <osd/vertex.h>
|
||||
|
||||
#include <common/shape_utils.h>
|
||||
#include <common/vtr_utils.h>
|
||||
#include "../common/stopwatch.h"
|
||||
#include "../common/simple_math.h"
|
||||
#include "../common/gl_hud.h"
|
||||
|
||||
#include "init_shapes.h"
|
||||
|
||||
#include <cfloat>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
@ -75,28 +74,6 @@
|
||||
using namespace OpenSubdiv;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
typedef HbrMesh<OsdVertex> OsdHbrMesh;
|
||||
typedef HbrVertex<OsdVertex> OsdHbrVertex;
|
||||
typedef HbrFace<OsdVertex> OsdHbrFace;
|
||||
typedef HbrHalfedge<OsdVertex> OsdHbrHalfedge;
|
||||
|
||||
typedef FarMesh<OsdVertex> OsdFarMesh;
|
||||
typedef FarMeshFactory<OsdVertex> OsdFarMeshFactory;
|
||||
typedef FarSubdivisionTables OsdFarMeshSubdivision;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
struct SimpleShape {
|
||||
std::string name;
|
||||
Scheme scheme;
|
||||
std::string data;
|
||||
|
||||
SimpleShape() { }
|
||||
SimpleShape( std::string const & idata, char const * iname, Scheme ischeme )
|
||||
: name(iname), scheme(ischeme), data(idata) { }
|
||||
};
|
||||
|
||||
std::vector<SimpleShape> g_defaultShapes;
|
||||
|
||||
std::vector<float> g_orgPositions,
|
||||
g_positions,
|
||||
g_varyingColors;
|
||||
@ -149,107 +126,6 @@ float g_evalTime = 0;
|
||||
float g_computeTime = 0;
|
||||
Stopwatch g_fpsTimer;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
initializeShapes( ) {
|
||||
|
||||
#include <shapes/catmark_cube_corner0.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_cube_corner0, "catmark_cube_corner0", kCatmark));
|
||||
|
||||
#include <shapes/catmark_cube_corner1.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_cube_corner1, "catmark_cube_corner1", kCatmark));
|
||||
|
||||
#include <shapes/catmark_cube_corner2.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_cube_corner2, "catmark_cube_corner2", kCatmark));
|
||||
|
||||
#include <shapes/catmark_cube_corner3.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_cube_corner3, "catmark_cube_corner3", kCatmark));
|
||||
|
||||
#include <shapes/catmark_cube_corner4.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_cube_corner4, "catmark_cube_corner4", kCatmark));
|
||||
|
||||
#include <shapes/catmark_cube_creases0.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_cube_creases0, "catmark_cube_creases0", kCatmark));
|
||||
|
||||
#include <shapes/catmark_cube_creases1.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_cube_creases1, "catmark_cube_creases1", kCatmark));
|
||||
|
||||
#include <shapes/catmark_cube.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_cube, "catmark_cube", kCatmark));
|
||||
|
||||
#include <shapes/catmark_dart_edgecorner.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_dart_edgecorner, "catmark_dart_edgecorner", kCatmark));
|
||||
|
||||
#include <shapes/catmark_dart_edgeonly.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_dart_edgeonly, "catmark_dart_edgeonly", kCatmark));
|
||||
|
||||
#include <shapes/catmark_edgecorner.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_edgecorner ,"catmark_edgecorner", kCatmark));
|
||||
|
||||
#include <shapes/catmark_edgeonly.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_edgeonly, "catmark_edgeonly", kCatmark));
|
||||
|
||||
#include <shapes/catmark_gregory_test1.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_gregory_test1, "catmark_gregory_test1", kCatmark));
|
||||
|
||||
#include <shapes/catmark_gregory_test2.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_gregory_test2, "catmark_gregory_test2", kCatmark));
|
||||
|
||||
#include <shapes/catmark_gregory_test3.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_gregory_test3, "catmark_gregory_test3", kCatmark));
|
||||
|
||||
#include <shapes/catmark_gregory_test4.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_gregory_test4, "catmark_gregory_test4", kCatmark));
|
||||
|
||||
#include <shapes/catmark_hole_test1.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_hole_test1, "catmark_hole_test1", kCatmark));
|
||||
|
||||
#include <shapes/catmark_hole_test2.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_hole_test2, "catmark_hole_test2", kCatmark));
|
||||
|
||||
#include <shapes/catmark_pyramid_creases0.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_pyramid_creases0, "catmark_pyramid_creases0", kCatmark));
|
||||
|
||||
#include <shapes/catmark_pyramid_creases1.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_pyramid_creases1, "catmark_pyramid_creases1", kCatmark));
|
||||
|
||||
#include <shapes/catmark_pyramid.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_pyramid, "catmark_pyramid", kCatmark));
|
||||
|
||||
#include <shapes/catmark_tent_creases0.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_tent_creases0, "catmark_tent_creases0", kCatmark));
|
||||
|
||||
#include <shapes/catmark_tent_creases1.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_tent_creases1, "catmark_tent_creases1", kCatmark));
|
||||
|
||||
#include <shapes/catmark_tent.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_tent, "catmark_tent", kCatmark));
|
||||
|
||||
#include <shapes/catmark_torus.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_torus, "catmark_torus", kCatmark));
|
||||
|
||||
#include <shapes/catmark_torus_creases0.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_torus_creases0, "catmark_torus_creases0", kCatmark));
|
||||
|
||||
#include <shapes/catmark_square_hedit0.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_square_hedit0, "catmark_square_hedit0", kCatmark));
|
||||
|
||||
#include <shapes/catmark_square_hedit1.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_square_hedit1, "catmark_square_hedit1", kCatmark));
|
||||
|
||||
#include <shapes/catmark_square_hedit2.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_square_hedit2, "catmark_square_hedit2", kCatmark));
|
||||
|
||||
#include <shapes/catmark_square_hedit3.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_square_hedit3, "catmark_square_hedit3", kCatmark));
|
||||
|
||||
#include <shapes/catmark_square_hedit4.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_square_hedit4, "catmark_square_hedit4", kCatmark));
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int g_nsamples=1000,
|
||||
g_nsamplesFound=0;
|
||||
@ -264,11 +140,11 @@ GLhud g_hud;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static int
|
||||
createRandomSamples( int nfaces, int nsamples, std::vector<OsdEvalCoords> & coords ) {
|
||||
createRandomSamples( int nfaces, int nsamples, std::vector<Osd::EvalCoords> & coords ) {
|
||||
|
||||
coords.resize(nfaces * nsamples);
|
||||
|
||||
OsdEvalCoords * coord = &coords[0];
|
||||
Osd::EvalCoords * coord = &coords[0];
|
||||
|
||||
// large Pell prime number
|
||||
srand( static_cast<int>(2147483647) );
|
||||
@ -287,7 +163,7 @@ createRandomSamples( int nfaces, int nsamples, std::vector<OsdEvalCoords> & coor
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static int
|
||||
createRandomVaryingColors( int nverts, std::vector<float> & colors ) {
|
||||
createRandomVaryingColors(int nverts, std::vector<float> & colors) {
|
||||
|
||||
colors.resize( nverts * 3 );
|
||||
|
||||
@ -305,72 +181,72 @@ createRandomVaryingColors( int nverts, std::vector<float> & colors ) {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
createCoarseMesh( OsdHbrMesh * const hmesh, int nfaces ) {
|
||||
// save coarse topology (used for coarse mesh drawing)
|
||||
g_coarseEdges.clear();
|
||||
g_coarseEdgeSharpness.clear();
|
||||
g_coarseVertexSharpness.clear();
|
||||
createCoarseMesh(OpenSubdiv::Far::TopologyRefiner const & refiner) {
|
||||
|
||||
for(int i=0; i<nfaces; ++i) {
|
||||
OsdHbrFace *face = hmesh->GetFace(i);
|
||||
int nv = face->GetNumVertices();
|
||||
for(int j=0; j<nv; ++j) {
|
||||
g_coarseEdges.push_back(face->GetVertex(j)->GetID());
|
||||
g_coarseEdges.push_back(face->GetVertex((j+1)%nv)->GetID());
|
||||
g_coarseEdgeSharpness.push_back(face->GetEdge(j)->GetSharpness());
|
||||
}
|
||||
typedef OpenSubdiv::Far::IndexArray IndexArray;
|
||||
|
||||
// save coarse topology (used for coarse mesh drawing)
|
||||
int nedges = refiner.GetNumEdges(0),
|
||||
nverts = refiner.GetNumVertices(0);
|
||||
|
||||
g_coarseEdges.resize(nedges*2);
|
||||
g_coarseEdgeSharpness.resize(nedges);
|
||||
g_coarseVertexSharpness.resize(nverts);
|
||||
|
||||
for(int i=0; i<nedges; ++i) {
|
||||
IndexArray verts = refiner.GetEdgeVertices(0, i);
|
||||
g_coarseEdges[i*2 ]=verts[0];
|
||||
g_coarseEdges[i*2+1]=verts[1];
|
||||
g_coarseEdgeSharpness[i]=refiner.GetEdgeSharpness(0, i);
|
||||
}
|
||||
int nv = hmesh->GetNumVertices();
|
||||
for(int i=0; i<nv; ++i) {
|
||||
g_coarseVertexSharpness.push_back(hmesh->GetVertex(i)->GetSharpness());
|
||||
|
||||
for(int i=0; i<nverts; ++i) {
|
||||
g_coarseVertexSharpness[i]=refiner.GetVertexSharpness(0, i);
|
||||
}
|
||||
|
||||
// assign a randomly generated color for each vertex ofthe mesh
|
||||
createRandomVaryingColors(nv, g_varyingColors);
|
||||
createRandomVaryingColors(nverts, g_varyingColors);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static int
|
||||
getNumPtexFaces( OsdHbrMesh const * hmesh, int nfaces ) {
|
||||
|
||||
OsdHbrFace * lastface = hmesh->GetFace( nfaces-1 );
|
||||
assert(lastface);
|
||||
|
||||
int result = lastface->GetPtexIndex();
|
||||
|
||||
result += (hmesh->GetSubdivision()->FaceIsExtraordinary(hmesh, lastface) ?
|
||||
lastface->GetNumVertices() : 1);
|
||||
getNumPtexFaces(OpenSubdiv::Far::TopologyRefiner const & refiner) {
|
||||
|
||||
int result = 0;
|
||||
for (int face=0; face<refiner.GetNumFaces(0); ++face) {
|
||||
OpenSubdiv::Far::IndexArray fverts = refiner.GetFaceVertices(0, face);
|
||||
result += fverts.size()==4 ? 1 : fverts.size();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
OsdCpuVertexBuffer * g_vertexData=0,
|
||||
Osd::CpuVertexBuffer * g_vertexData=0,
|
||||
* g_varyingData=0;
|
||||
|
||||
OsdCpuComputeContext * g_computeCtx = 0;
|
||||
Osd::CpuComputeContext * g_computeCtx = 0;
|
||||
|
||||
OsdCpuComputeController g_computeCtrl;
|
||||
Osd::CpuComputeController g_computeCtrl;
|
||||
|
||||
OsdCpuEvalLimitContext * g_evalCtx = 0;
|
||||
Far::KernelBatchVector g_kernelBatches;
|
||||
|
||||
OsdCpuEvalLimitController g_evalCtrl;
|
||||
Osd::CpuEvalLimitContext * g_evalCtx = 0;
|
||||
|
||||
OsdVertexBufferDescriptor g_idesc( /*offset*/ 0, /*legnth*/ 3, /*stride*/ 3 ),
|
||||
Osd::CpuEvalLimitController g_evalCtrl;
|
||||
|
||||
Osd::VertexBufferDescriptor g_idesc( /*offset*/ 0, /*legnth*/ 3, /*stride*/ 3 ),
|
||||
g_odesc( /*offset*/ 0, /*legnth*/ 3, /*stride*/ 6 ),
|
||||
g_vdesc( /*offset*/ 3, /*legnth*/ 3, /*stride*/ 6 ),
|
||||
g_fvidesc( /*offset*/ 0, /*legnth*/ 2, /*stride*/ 2 ),
|
||||
g_fvodesc( /*offset*/ 3, /*legnth*/ 2, /*stride*/ 6 );
|
||||
|
||||
std::vector<OsdEvalCoords> g_coords;
|
||||
std::vector<Osd::EvalCoords> g_coords;
|
||||
|
||||
OsdCpuGLVertexBuffer * g_Q=0,
|
||||
Osd::CpuGLVertexBuffer * g_Q=0,
|
||||
* g_dQu=0,
|
||||
* g_dQv=0;
|
||||
|
||||
OsdFarMesh * g_fmesh=0;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
updateGeom() {
|
||||
@ -397,7 +273,7 @@ updateGeom() {
|
||||
|
||||
g_vertexData->UpdateData( &g_positions[0], 0, nverts);
|
||||
|
||||
g_computeCtrl.Refine( g_computeCtx, g_fmesh->GetKernelBatches(), g_vertexData, g_varyingData );
|
||||
g_computeCtrl.Compute(g_computeCtx, g_kernelBatches, g_vertexData, g_varyingData);
|
||||
|
||||
s.Stop();
|
||||
g_computeTime = float(s.GetElapsed() * 1000.0f);
|
||||
@ -417,7 +293,7 @@ updateGeom() {
|
||||
switch (g_drawMode) {
|
||||
case kVARYING : g_evalCtrl.BindVaryingBuffers( g_idesc, g_varyingData, g_vdesc, g_Q ); break;
|
||||
|
||||
case kFACEVARYING : g_evalCtrl.BindFacevaryingBuffers( g_fvidesc, g_fvodesc, g_Q ); break;
|
||||
case kFACEVARYING : //g_evalCtrl.BindFacevaryingBuffers( g_fvidesc, g_fvodesc, g_Q ); break;
|
||||
|
||||
case kUV :
|
||||
|
||||
@ -472,65 +348,90 @@ updateGeom() {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
createOsdMesh( const std::string &shape, int level, Scheme scheme=kCatmark ) {
|
||||
createOsdMesh(ShapeDesc const & shapeDesc, int level) {
|
||||
|
||||
// Create HBR mesh
|
||||
OsdHbrMesh * hmesh = simpleHbr<OsdVertex>(shape.c_str(), scheme, g_orgPositions, true);
|
||||
|
||||
Shape * shape = Shape::parseObj(shapeDesc.data.c_str(), shapeDesc.scheme);
|
||||
|
||||
// create Vtr mesh (topology)
|
||||
OpenSubdiv::Sdc::Type sdctype = GetSdcType(*shape);
|
||||
OpenSubdiv::Sdc::Options sdcoptions = GetSdcOptions(*shape);
|
||||
|
||||
OpenSubdiv::Far::TopologyRefiner * refiner =
|
||||
OpenSubdiv::Far::TopologyRefinerFactory<Shape>::Create(sdctype, sdcoptions, *shape);
|
||||
|
||||
g_orgPositions=shape->verts;
|
||||
g_positions.resize(g_orgPositions.size(),0.0f);
|
||||
|
||||
int nfaces = hmesh->GetNumFaces(),
|
||||
nptexfaces = getNumPtexFaces(hmesh, nfaces);
|
||||
delete shape;
|
||||
|
||||
// Generate sample locations
|
||||
int nsamples = createRandomSamples( nptexfaces, g_nsamples, g_coords );
|
||||
int nptexfaces = getNumPtexFaces(*refiner),
|
||||
nsamples = createRandomSamples( nptexfaces, g_nsamples, g_coords ),
|
||||
nverts = 0;
|
||||
|
||||
createCoarseMesh(hmesh, nfaces);
|
||||
createCoarseMesh(*refiner);
|
||||
|
||||
// Create FAR mesh
|
||||
OsdFarMeshFactory factory( hmesh, level, /*adaptive*/ true);
|
||||
{
|
||||
refiner->RefineAdaptive(level);
|
||||
|
||||
delete g_fmesh;
|
||||
g_fmesh = factory.Create(/*fvar*/ true);
|
||||
nverts = refiner->GetNumVerticesTotal();
|
||||
|
||||
int nverts = g_fmesh->GetNumVertices();
|
||||
Far::StencilTablesFactory::Options options;
|
||||
options.generateOffsets=true;
|
||||
options.generateAllLevels=true;
|
||||
|
||||
// Generate stencil tables
|
||||
Far::StencilTables const * vertexStencils =
|
||||
Far::StencilTablesFactory::Create(*refiner, options);
|
||||
|
||||
options.interpolationMode = Far::StencilTablesFactory::INTERPOLATE_VARYING;
|
||||
Far::StencilTables const * varyingStencils =
|
||||
Far::StencilTablesFactory::Create(*refiner, options);
|
||||
|
||||
g_kernelBatches.clear();
|
||||
g_kernelBatches.push_back(Far::StencilTablesFactory::Create(*vertexStencils));
|
||||
|
||||
|
||||
// Generate adaptive patch tables
|
||||
Far::PatchTables const * patchTables =
|
||||
Far::PatchTablesFactory::Create(*refiner);
|
||||
|
||||
// Create v-buffer & populate w/ positions
|
||||
delete g_vertexData;
|
||||
g_vertexData = OsdCpuVertexBuffer::Create(3, nverts);
|
||||
// Create a Compute context, used to "pose" the vertices
|
||||
delete g_computeCtx;
|
||||
g_computeCtx = Osd::CpuComputeContext::Create(vertexStencils, varyingStencils);
|
||||
|
||||
// Create primvar v-buffer & populate w/ colors or (u,v) data
|
||||
delete g_varyingData; g_varyingData = 0;
|
||||
if (g_drawMode==kVARYING) {
|
||||
g_varyingData = OsdCpuVertexBuffer::Create(3, nverts);
|
||||
g_varyingData->UpdateData( &g_varyingColors[0], 0, nverts);
|
||||
// Create a limit Eval context
|
||||
delete g_evalCtx;
|
||||
g_evalCtx = Osd::CpuEvalLimitContext::Create(*patchTables);
|
||||
}
|
||||
|
||||
// Create a Compute context, used to "pose" the vertices
|
||||
delete g_computeCtx;
|
||||
g_computeCtx = OsdCpuComputeContext::Create(g_fmesh->GetSubdivisionTables(), g_fmesh->GetVertexEditTables());
|
||||
delete refiner;
|
||||
|
||||
g_computeCtrl.Refine( g_computeCtx, g_fmesh->GetKernelBatches(), g_vertexData, g_varyingData );
|
||||
{ // Create vertex data buffer & populate w/ positions
|
||||
delete g_vertexData;
|
||||
g_vertexData = Osd::CpuVertexBuffer::Create(3, nverts);
|
||||
|
||||
// Create primvar v-buffer & populate w/ colors or (u,v) data
|
||||
delete g_varyingData; g_varyingData = 0;
|
||||
if (g_drawMode==kVARYING) {
|
||||
g_varyingData = Osd::CpuVertexBuffer::Create(3, nverts);
|
||||
g_varyingData->UpdateData( &g_varyingColors[0], 0, nverts);
|
||||
}
|
||||
|
||||
// Create output data buffers
|
||||
delete g_Q;
|
||||
g_Q = Osd::CpuGLVertexBuffer::Create(6,nsamples);
|
||||
memset( g_Q->BindCpuBuffer(), 0, nsamples*6*sizeof(float));
|
||||
|
||||
// Create eval context & data buffers
|
||||
delete g_evalCtx;
|
||||
g_evalCtx = OsdCpuEvalLimitContext::Create(g_fmesh->GetPatchTables(), /*requireFVarData*/ true);
|
||||
delete g_dQu;
|
||||
g_dQu = Osd::CpuGLVertexBuffer::Create(6,nsamples);
|
||||
memset( g_dQu->BindCpuBuffer(), 0, nsamples*6*sizeof(float));
|
||||
|
||||
delete g_Q;
|
||||
g_Q = OsdCpuGLVertexBuffer::Create(6,nsamples);
|
||||
memset( g_Q->BindCpuBuffer(), 0, nsamples*6*sizeof(float));
|
||||
delete g_dQv;
|
||||
g_dQv = Osd::CpuGLVertexBuffer::Create(6,nsamples);
|
||||
memset( g_dQv->BindCpuBuffer(), 0, nsamples*6*sizeof(float));
|
||||
|
||||
delete g_dQu;
|
||||
g_dQu = OsdCpuGLVertexBuffer::Create(6,nsamples);
|
||||
memset( g_dQu->BindCpuBuffer(), 0, nsamples*6*sizeof(float));
|
||||
|
||||
delete g_dQv;
|
||||
g_dQv = OsdCpuGLVertexBuffer::Create(6,nsamples);
|
||||
memset( g_dQv->BindCpuBuffer(), 0, nsamples*6*sizeof(float));
|
||||
}
|
||||
|
||||
updateGeom();
|
||||
|
||||
@ -766,7 +667,7 @@ drawSamples() {
|
||||
glBindVertexArray(g_samplesVAO);
|
||||
|
||||
glPointSize(1.0f);
|
||||
glDrawArrays( GL_POINTS, 0, (int)g_coords.size());
|
||||
glDrawArrays(GL_POINTS, 0, (int)g_coords.size());
|
||||
glPointSize(1.0f);
|
||||
|
||||
glBindVertexArray(0);
|
||||
@ -853,12 +754,9 @@ idle() {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
#if GLFW_VERSION_MAJOR>=3
|
||||
motion(GLFWwindow *, double dx, double dy) {
|
||||
|
||||
int x=(int)dx, y=(int)dy;
|
||||
#else
|
||||
motion(int x, int y) {
|
||||
#endif
|
||||
|
||||
if (g_mbutton[0] && !g_mbutton[1] && !g_mbutton[2]) {
|
||||
// orbit
|
||||
@ -881,11 +779,7 @@ motion(int x, int y) {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
#if GLFW_VERSION_MAJOR>=3
|
||||
mouse(GLFWwindow *, int button, int state, int /* mods */) {
|
||||
#else
|
||||
mouse(int button, int state) {
|
||||
#endif
|
||||
|
||||
if (button == 0 && state == GLFW_PRESS && g_hud.MouseClick(g_prev_x, g_prev_y))
|
||||
return;
|
||||
@ -897,34 +791,23 @@ mouse(int button, int state) {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
#if GLFW_VERSION_MAJOR>=3
|
||||
reshape(GLFWwindow *, int width, int height) {
|
||||
#else
|
||||
reshape(int width, int height) {
|
||||
#endif
|
||||
|
||||
g_width = width;
|
||||
g_height = height;
|
||||
|
||||
int windowWidth = g_width, windowHeight = g_height;
|
||||
#if GLFW_VERSION_MAJOR>=3
|
||||
|
||||
// window size might not match framebuffer size on a high DPI display
|
||||
glfwGetWindowSize(g_window, &windowWidth, &windowHeight);
|
||||
#endif
|
||||
|
||||
g_hud.Rebuild(windowWidth, windowHeight);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#if GLFW_VERSION_MAJOR>=3
|
||||
void windowClose(GLFWwindow*) {
|
||||
g_running = false;
|
||||
}
|
||||
#else
|
||||
int windowClose() {
|
||||
g_running = false;
|
||||
return GL_TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
@ -934,17 +817,12 @@ setSamples(bool add)
|
||||
|
||||
g_nsamples = std::max(0, g_nsamples);
|
||||
|
||||
createOsdMesh( g_defaultShapes[g_currentShape].data, g_level, g_defaultShapes[ g_currentShape ].scheme );
|
||||
createOsdMesh(g_defaultShapes[g_currentShape], g_level);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
#if GLFW_VERSION_MAJOR>=3
|
||||
keyboard(GLFWwindow *, int key, int /* scancode */, int event, int /* mods */) {
|
||||
#else
|
||||
#define GLFW_KEY_ESCAPE GLFW_KEY_ESC
|
||||
keyboard(int key, int event) {
|
||||
#endif
|
||||
|
||||
if (event == GLFW_RELEASE) return;
|
||||
if (g_hud.KeyDown(tolower(key))) return;
|
||||
@ -962,7 +840,7 @@ keyboard(int key, int event) {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
callbackError(OpenSubdiv::OsdErrorType err, const char *message)
|
||||
callbackError(OpenSubdiv::Osd::ErrorType err, const char *message)
|
||||
{
|
||||
printf("OsdError: %d\n", err);
|
||||
printf("%s", message);
|
||||
@ -979,8 +857,7 @@ callbackModel(int m)
|
||||
m = (int)g_defaultShapes.size() - 1;
|
||||
|
||||
g_currentShape = m;
|
||||
|
||||
createOsdMesh( g_defaultShapes[m].data, g_level, g_defaultShapes[ g_currentShape ].scheme );
|
||||
createOsdMesh(g_defaultShapes[g_currentShape], g_level);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -988,7 +865,7 @@ static void
|
||||
callbackLevel(int l)
|
||||
{
|
||||
g_level = l;
|
||||
createOsdMesh( g_defaultShapes[g_currentShape].data, g_level, g_defaultShapes[ g_currentShape ].scheme );
|
||||
createOsdMesh(g_defaultShapes[g_currentShape], g_level);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -1024,7 +901,7 @@ static void
|
||||
callbackDisplayVaryingColors(int mode)
|
||||
{
|
||||
g_drawMode = mode;
|
||||
createOsdMesh( g_defaultShapes[g_currentShape].data, g_level, g_defaultShapes[ g_currentShape ].scheme );
|
||||
createOsdMesh(g_defaultShapes[g_currentShape], g_level);
|
||||
}
|
||||
|
||||
|
||||
@ -1033,10 +910,10 @@ static void
|
||||
initHUD()
|
||||
{
|
||||
int windowWidth = g_width, windowHeight = g_height;
|
||||
#if GLFW_VERSION_MAJOR>=3
|
||||
|
||||
// window size might not match framebuffer size on a high DPI display
|
||||
glfwGetWindowSize(g_window, &windowWidth, &windowHeight);
|
||||
#endif
|
||||
|
||||
g_hud.Init(windowWidth, windowHeight);
|
||||
|
||||
g_hud.AddCheckBox("Cage Edges (H)", true, 10, 10, callbackDisplayCageEdges, 0, 'h');
|
||||
@ -1093,11 +970,9 @@ uninitGL() {
|
||||
static void
|
||||
setGLCoreProfile()
|
||||
{
|
||||
#if GLFW_VERSION_MAJOR>=3
|
||||
#define glfwOpenWindowHint glfwWindowHint
|
||||
#define GLFW_OPENGL_VERSION_MAJOR GLFW_CONTEXT_VERSION_MAJOR
|
||||
#define GLFW_OPENGL_VERSION_MINOR GLFW_CONTEXT_VERSION_MINOR
|
||||
#endif
|
||||
|
||||
glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
#if not defined(__APPLE__)
|
||||
@ -1126,29 +1001,28 @@ int main(int argc, char **argv) {
|
||||
ss << ifs.rdbuf();
|
||||
ifs.close();
|
||||
str = ss.str();
|
||||
g_defaultShapes.push_back(SimpleShape(str.c_str(), argv[1], kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc(str.c_str(), argv[1], kCatmark));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OsdSetErrorCallback(callbackError);
|
||||
Osd::SetErrorCallback(callbackError);
|
||||
|
||||
|
||||
initializeShapes();
|
||||
initShapes();
|
||||
|
||||
if (not glfwInit()) {
|
||||
printf("Failed to initialize GLFW\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const char windowTitle[] = "OpenSubdiv evalViewer";
|
||||
static const char windowTitle[] = "OpenSubdiv glEvalLimit " OPENSUBDIV_VERSION_STRING;
|
||||
|
||||
#define CORE_PROFILE
|
||||
#ifdef CORE_PROFILE
|
||||
setGLCoreProfile();
|
||||
#endif
|
||||
|
||||
#if GLFW_VERSION_MAJOR>=3
|
||||
if (fullscreen) {
|
||||
|
||||
g_primary = glfwGetPrimaryMonitor();
|
||||
@ -1186,20 +1060,6 @@ int main(int argc, char **argv) {
|
||||
glfwSetCursorPosCallback(g_window, motion);
|
||||
glfwSetMouseButtonCallback(g_window, mouse);
|
||||
glfwSetWindowCloseCallback(g_window, windowClose);
|
||||
#else
|
||||
if (glfwOpenWindow(g_width, g_height, 8, 8, 8, 8, 24, 8,
|
||||
fullscreen ? GLFW_FULLSCREEN : GLFW_WINDOW) == GL_FALSE) {
|
||||
printf("Failed to open window.\n");
|
||||
glfwTerminate();
|
||||
return 1;
|
||||
}
|
||||
glfwSetWindowTitle(windowTitle);
|
||||
glfwSetKeyCallback(keyboard);
|
||||
glfwSetMousePosCallback(motion);
|
||||
glfwSetMouseButtonCallback(mouse);
|
||||
glfwSetWindowSizeCallback(reshape);
|
||||
glfwSetWindowCloseCallback(windowClose);
|
||||
#endif
|
||||
|
||||
#if defined(OSD_USES_GLEW)
|
||||
#ifdef CORE_PROFILE
|
||||
@ -1233,12 +1093,8 @@ int main(int argc, char **argv) {
|
||||
idle();
|
||||
display();
|
||||
|
||||
#if GLFW_VERSION_MAJOR>=3
|
||||
glfwPollEvents();
|
||||
glfwSwapBuffers(g_window);
|
||||
#else
|
||||
glfwSwapBuffers();
|
||||
#endif
|
||||
|
||||
glFinish();
|
||||
}
|
125
examples/glEvalLimit/init_shapes.h
Normal file
@ -0,0 +1,125 @@
|
||||
//
|
||||
// Copyright 2013 Pixar
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "Apache License")
|
||||
// with the following modification; you may not use this file except in
|
||||
// compliance with the Apache License and the following modification to it:
|
||||
// Section 6. Trademarks. is deleted and replaced with:
|
||||
//
|
||||
// 6. Trademarks. This License does not grant permission to use the trade
|
||||
// names, trademarks, service marks, or product names of the Licensor
|
||||
// and its affiliates, except as required to comply with Section 4(c) of
|
||||
// the License and to reproduce the content of the NOTICE file.
|
||||
//
|
||||
// You may obtain a copy of the Apache License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the Apache License with the above modification is
|
||||
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the Apache License for the specific
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
|
||||
#include <common/shape_utils.h>
|
||||
|
||||
struct ShapeDesc {
|
||||
|
||||
ShapeDesc(char const * iname, std::string const & idata, Scheme ischeme) :
|
||||
name(iname), data(idata), scheme(ischeme) { }
|
||||
|
||||
std::string name,
|
||||
data;
|
||||
Scheme scheme;
|
||||
};
|
||||
|
||||
static std::vector<ShapeDesc> g_defaultShapes;
|
||||
|
||||
#include <shapes/catmark_bishop.h>
|
||||
#include <shapes/catmark_car.h>
|
||||
#include <shapes/catmark_chaikin0.h>
|
||||
#include <shapes/catmark_chaikin1.h>
|
||||
#include <shapes/catmark_cube_corner0.h>
|
||||
#include <shapes/catmark_cube_corner1.h>
|
||||
#include <shapes/catmark_cube_corner2.h>
|
||||
#include <shapes/catmark_cube_corner3.h>
|
||||
#include <shapes/catmark_cube_corner4.h>
|
||||
#include <shapes/catmark_cube_creases0.h>
|
||||
#include <shapes/catmark_cube_creases1.h>
|
||||
#include <shapes/catmark_cube.h>
|
||||
#include <shapes/catmark_dart_edgecorner.h>
|
||||
#include <shapes/catmark_dart_edgeonly.h>
|
||||
#include <shapes/catmark_edgecorner.h>
|
||||
#include <shapes/catmark_edgeonly.h>
|
||||
#include <shapes/catmark_fan.h>
|
||||
#include <shapes/catmark_flap.h>
|
||||
#include <shapes/catmark_flap2.h>
|
||||
#include <shapes/catmark_gregory_test1.h>
|
||||
#include <shapes/catmark_gregory_test2.h>
|
||||
#include <shapes/catmark_gregory_test3.h>
|
||||
#include <shapes/catmark_gregory_test4.h>
|
||||
#include <shapes/catmark_helmet.h>
|
||||
#include <shapes/catmark_hole_test1.h>
|
||||
#include <shapes/catmark_hole_test2.h>
|
||||
#include <shapes/catmark_pawn.h>
|
||||
#include <shapes/catmark_pyramid_creases0.h>
|
||||
#include <shapes/catmark_pyramid_creases1.h>
|
||||
#include <shapes/catmark_pyramid.h>
|
||||
#include <shapes/catmark_rook.h>
|
||||
#include <shapes/catmark_square_hedit0.h>
|
||||
#include <shapes/catmark_square_hedit1.h>
|
||||
#include <shapes/catmark_square_hedit2.h>
|
||||
#include <shapes/catmark_square_hedit3.h>
|
||||
#include <shapes/catmark_tent_creases0.h>
|
||||
#include <shapes/catmark_tent_creases1.h>
|
||||
#include <shapes/catmark_tent.h>
|
||||
#include <shapes/catmark_torus.h>
|
||||
#include <shapes/catmark_torus_creases0.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void initShapes() {
|
||||
// g_defaultShapes.push_back( ShapeDesc("bilinear_cube", bilinear_cube, kBilinear) );
|
||||
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube_corner0", catmark_cube_corner0, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube_corner1", catmark_cube_corner1, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube_corner2", catmark_cube_corner2, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube_corner3", catmark_cube_corner3, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube_corner4", catmark_cube_corner4, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube_creases0", catmark_cube_creases0, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube_creases1", catmark_cube_creases1, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_cube", catmark_cube, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_dart_edgecorner", catmark_dart_edgecorner, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_dart_edgeonly", catmark_dart_edgeonly, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_edgecorner", catmark_edgecorner, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_edgeonly", catmark_edgeonly, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_chaikin0", catmark_chaikin0, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_chaikin1", catmark_chaikin1, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_fan", catmark_fan, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_flap", catmark_flap, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_flap2", catmark_flap2, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_gregory_test1", catmark_gregory_test1, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_gregory_test2", catmark_gregory_test2, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_gregory_test3", catmark_gregory_test3, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_gregory_test4", catmark_gregory_test4, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_hole_test1", catmark_hole_test1, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_hole_test2", catmark_hole_test2, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_pyramid_creases0", catmark_pyramid_creases0, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_pyramid_creases1", catmark_pyramid_creases1, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_pyramid", catmark_pyramid, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_tent_creases0", catmark_tent_creases0, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_tent_creases1", catmark_tent_creases1 , kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_tent", catmark_tent, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_torus", catmark_torus, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_torus_creases0", catmark_torus_creases0, kCatmark ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("catmark_square_hedit0", catmark_square_hedit0, kCatmark ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("catmark_square_hedit1", catmark_square_hedit1, kCatmark ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("catmark_square_hedit2", catmark_square_hedit2, kCatmark ) );
|
||||
// g_defaultShapes.push_back( ShapeDesc("catmark_square_hedit3", catmark_square_hedit3, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_bishop", catmark_bishop, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_car", catmark_car, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_helmet", catmark_helmet, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_pawn", catmark_pawn, kCatmark ) );
|
||||
g_defaultShapes.push_back( ShapeDesc("catmark_rook", catmark_rook, kCatmark ) );
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
@ -55,15 +55,17 @@ _stringify("${SHADER_FILES}" INC_FILES)
|
||||
|
||||
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
_add_glfw_executable(uvViewer
|
||||
viewer.cpp
|
||||
_add_glfw_executable(glFVarViewer
|
||||
glFVarViewer.cpp
|
||||
"${SHADER_FILES}"
|
||||
"${INC_FILES}"
|
||||
$<TARGET_OBJECTS:regression_common_obj>
|
||||
$<TARGET_OBJECTS:regression_vtr_utils_obj>
|
||||
$<TARGET_OBJECTS:examples_common_obj>
|
||||
)
|
||||
|
||||
target_link_libraries(uvViewer
|
||||
target_link_libraries(glFVarViewer
|
||||
${PLATFORM_LIBRARIES}
|
||||
)
|
||||
|
||||
install(TARGETS uvViewer DESTINATION "${CMAKE_BINDIR_BASE}")
|
||||
install(TARGETS glFVarViewer DESTINATION "${CMAKE_BINDIR_BASE}")
|
@ -38,13 +38,9 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_VERSION_3)
|
||||
#include <GLFW/glfw3.h>
|
||||
GLFWwindow* g_window = 0;
|
||||
GLFWmonitor* g_primary = 0;
|
||||
#else
|
||||
#include <GL/glfw.h>
|
||||
#endif
|
||||
#include <GLFW/glfw3.h>
|
||||
GLFWwindow* g_window = 0;
|
||||
GLFWmonitor* g_primary = 0;
|
||||
|
||||
#include <osd/error.h>
|
||||
#include <osd/vertex.h>
|
||||
@ -54,12 +50,12 @@
|
||||
#include <osd/cpuGLVertexBuffer.h>
|
||||
#include <osd/cpuComputeContext.h>
|
||||
#include <osd/cpuComputeController.h>
|
||||
OpenSubdiv::OsdCpuComputeController *g_cpuComputeController = NULL;
|
||||
OpenSubdiv::Osd::CpuComputeController *g_cpuComputeController = NULL;
|
||||
|
||||
#include <osd/glMesh.h>
|
||||
OpenSubdiv::OsdGLMeshInterface *g_mesh = NULL;
|
||||
OpenSubdiv::Osd::GLMeshInterface *g_mesh = NULL;
|
||||
|
||||
#include <common/shape_utils.h>
|
||||
#include <common/vtr_utils.h>
|
||||
#include "../common/stopwatch.h"
|
||||
#include "../common/simple_math.h"
|
||||
#include "../common/gl_hud.h"
|
||||
@ -80,32 +76,18 @@ static const char *shaderSource =
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
typedef OpenSubdiv::HbrMesh<OpenSubdiv::OsdVertex> OsdHbrMesh;
|
||||
typedef OpenSubdiv::HbrVertex<OpenSubdiv::OsdVertex> OsdHbrVertex;
|
||||
typedef OpenSubdiv::HbrFace<OpenSubdiv::OsdVertex> OsdHbrFace;
|
||||
typedef OpenSubdiv::HbrHalfedge<OpenSubdiv::OsdVertex> OsdHbrHalfedge;
|
||||
|
||||
enum DisplayStyle { kWire = 0,
|
||||
kShaded,
|
||||
kWireShaded };
|
||||
|
||||
struct SimpleShape {
|
||||
std::string name;
|
||||
Scheme scheme;
|
||||
std::string data;
|
||||
|
||||
SimpleShape() { }
|
||||
SimpleShape(std::string const & idata, char const * iname, Scheme ischeme)
|
||||
: name(iname), scheme(ischeme), data(idata) { }
|
||||
};
|
||||
|
||||
std::vector<SimpleShape> g_defaultShapes;
|
||||
|
||||
int g_currentShape = 0;
|
||||
|
||||
int g_frame = 0,
|
||||
g_repeatCount = 0;
|
||||
int g_fvarBoundary = OsdHbrMesh::k_InterpolateBoundaryEdgeOnly;
|
||||
|
||||
OpenSubdiv::Sdc::Options::FVarBoundaryInterpolation g_fvarBoundary =
|
||||
OpenSubdiv::Sdc::Options::FVAR_BOUNDARY_BILINEAR;
|
||||
|
||||
int g_fvarPropagateCorners = 0;
|
||||
|
||||
// GUI variables
|
||||
@ -169,8 +151,7 @@ std::vector<int> g_coarseEdges;
|
||||
std::vector<float> g_coarseEdgeSharpness;
|
||||
std::vector<float> g_coarseVertexSharpness;
|
||||
|
||||
struct Program
|
||||
{
|
||||
struct Program {
|
||||
GLuint program;
|
||||
GLuint uniformModelViewProjectionMatrix;
|
||||
GLuint attrPosition;
|
||||
@ -179,8 +160,8 @@ struct Program
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static GLuint
|
||||
compileShader(GLenum shaderType, const char *source)
|
||||
{
|
||||
compileShader(GLenum shaderType, const char *source) {
|
||||
|
||||
GLuint shader = glCreateShader(shaderType);
|
||||
glShaderSource(shader, 1, &source, NULL);
|
||||
glCompileShader(shader);
|
||||
@ -188,8 +169,8 @@ compileShader(GLenum shaderType, const char *source)
|
||||
}
|
||||
|
||||
static bool
|
||||
linkDefaultProgram()
|
||||
{
|
||||
linkDefaultProgram() {
|
||||
|
||||
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
|
||||
#define GLSL_VERSION_DEFINE "#version 400\n"
|
||||
#else
|
||||
@ -247,179 +228,50 @@ linkDefaultProgram()
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
initializeShapes()
|
||||
{
|
||||
#include <shapes/catmark_cube_corner0.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_cube_corner0, "catmark_cube_corner0", kCatmark));
|
||||
|
||||
#include <shapes/catmark_cube_corner1.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_cube_corner1, "catmark_cube_corner1", kCatmark));
|
||||
#include "init_shapes.h"
|
||||
|
||||
#include <shapes/catmark_cube_corner2.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_cube_corner2, "catmark_cube_corner2", kCatmark));
|
||||
|
||||
#include <shapes/catmark_cube_corner3.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_cube_corner3, "catmark_cube_corner3", kCatmark));
|
||||
|
||||
#include <shapes/catmark_cube_corner4.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_cube_corner4, "catmark_cube_corner4", kCatmark));
|
||||
|
||||
#include <shapes/catmark_cube_creases0.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_cube_creases0, "catmark_cube_creases0", kCatmark));
|
||||
|
||||
#include <shapes/catmark_cube_creases1.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_cube_creases1, "catmark_cube_creases1", kCatmark));
|
||||
|
||||
#include <shapes/catmark_cube.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_cube, "catmark_cube", kCatmark));
|
||||
|
||||
#include <shapes/catmark_dart_edgecorner.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_dart_edgecorner, "catmark_dart_edgecorner", kCatmark));
|
||||
|
||||
#include <shapes/catmark_dart_edgeonly.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_dart_edgeonly, "catmark_dart_edgeonly", kCatmark));
|
||||
|
||||
#include <shapes/catmark_edgecorner.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_edgecorner, "catmark_edgecorner", kCatmark));
|
||||
|
||||
#include <shapes/catmark_edgeonly.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_edgeonly, "catmark_edgeonly", kCatmark));
|
||||
|
||||
#include <shapes/catmark_gregory_test1.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_gregory_test1, "catmark_gregory_test1", kCatmark));
|
||||
|
||||
#include <shapes/catmark_gregory_test2.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_gregory_test2, "catmark_gregory_test2", kCatmark));
|
||||
|
||||
#include <shapes/catmark_gregory_test3.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_gregory_test3, "catmark_gregory_test3", kCatmark));
|
||||
|
||||
#include <shapes/catmark_gregory_test4.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_gregory_test4, "catmark_gregory_test4", kCatmark));
|
||||
|
||||
#include <shapes/catmark_hole_test1.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_hole_test1, "catmark_hole_test1", kCatmark));
|
||||
|
||||
#include <shapes/catmark_hole_test2.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_hole_test2, "catmark_hole_test2", kCatmark));
|
||||
|
||||
#include <shapes/catmark_pyramid_creases0.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_pyramid_creases0, "catmark_pyramid_creases0", kCatmark));
|
||||
|
||||
#include <shapes/catmark_pyramid_creases1.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_pyramid_creases1, "catmark_pyramid_creases1", kCatmark));
|
||||
|
||||
#include <shapes/catmark_pyramid.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_pyramid, "catmark_pyramid", kCatmark));
|
||||
|
||||
#include <shapes/catmark_tent_creases0.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_tent_creases0, "catmark_tent_creases0", kCatmark));
|
||||
|
||||
#include <shapes/catmark_tent_creases1.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_tent_creases1, "catmark_tent_creases1", kCatmark));
|
||||
|
||||
#include <shapes/catmark_tent.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_tent, "catmark_tent", kCatmark));
|
||||
|
||||
#include <shapes/catmark_torus.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_torus, "catmark_torus", kCatmark));
|
||||
|
||||
#include <shapes/catmark_torus_creases0.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_torus_creases0, "catmark_torus_creases0", kCatmark));
|
||||
|
||||
#include <shapes/catmark_square_hedit0.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_square_hedit0, "catmark_square_hedit0", kCatmark));
|
||||
|
||||
#include <shapes/catmark_square_hedit1.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_square_hedit1, "catmark_square_hedit1", kCatmark));
|
||||
|
||||
#include <shapes/catmark_square_hedit2.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_square_hedit2, "catmark_square_hedit2", kCatmark));
|
||||
|
||||
#include <shapes/catmark_square_hedit3.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_square_hedit3, "catmark_square_hedit3", kCatmark));
|
||||
|
||||
#include <shapes/catmark_square_hedit4.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_square_hedit4, "catmark_square_hedit4", kCatmark));
|
||||
|
||||
#include <shapes/catmark_bishop.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_bishop, "catmark_bishop", kCatmark));
|
||||
|
||||
#include <shapes/catmark_car.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_car, "catmark_car", kCatmark));
|
||||
|
||||
#include <shapes/catmark_helmet.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_helmet, "catmark_helmet", kCatmark));
|
||||
|
||||
#include <shapes/catmark_pawn.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_pawn, "catmark_pawn", kCatmark));
|
||||
|
||||
#include <shapes/catmark_rook.h>
|
||||
g_defaultShapes.push_back(SimpleShape(catmark_rook, "catmark_rook", kCatmark));
|
||||
|
||||
#include <shapes/bilinear_cube.h>
|
||||
g_defaultShapes.push_back(SimpleShape(bilinear_cube, "bilinear_cube", kBilinear));
|
||||
|
||||
|
||||
#include <shapes/loop_cube_creases0.h>
|
||||
g_defaultShapes.push_back(SimpleShape(loop_cube_creases0, "loop_cube_creases0", kLoop));
|
||||
|
||||
#include <shapes/loop_cube_creases1.h>
|
||||
g_defaultShapes.push_back(SimpleShape(loop_cube_creases1, "loop_cube_creases1", kLoop));
|
||||
|
||||
#include <shapes/loop_cube.h>
|
||||
g_defaultShapes.push_back(SimpleShape(loop_cube, "loop_cube", kLoop));
|
||||
|
||||
#include <shapes/loop_icosahedron.h>
|
||||
g_defaultShapes.push_back(SimpleShape(loop_icosahedron, "loop_icosahedron", kLoop));
|
||||
|
||||
#include <shapes/loop_saddle_edgecorner.h>
|
||||
g_defaultShapes.push_back(SimpleShape(loop_saddle_edgecorner, "loop_saddle_edgecorner", kLoop));
|
||||
|
||||
#include <shapes/loop_saddle_edgeonly.h>
|
||||
g_defaultShapes.push_back(SimpleShape(loop_saddle_edgeonly, "loop_saddle_edgeonly", kLoop));
|
||||
|
||||
#include <shapes/loop_triangle_edgecorner.h>
|
||||
g_defaultShapes.push_back(SimpleShape(loop_triangle_edgecorner, "loop_triangle_edgecorner", kLoop));
|
||||
|
||||
#include <shapes/loop_triangle_edgeonly.h>
|
||||
g_defaultShapes.push_back(SimpleShape(loop_triangle_edgeonly, "loop_triangle_edgeonly", kLoop));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
calcNormals(OsdHbrMesh * mesh, std::vector<float> const & pos, std::vector<float> & result)
|
||||
{
|
||||
calcNormals(OpenSubdiv::Far::TopologyRefiner const & refiner,
|
||||
std::vector<float> const & pos, std::vector<float> & normals) {
|
||||
|
||||
typedef OpenSubdiv::Far::IndexArray IndexArray;
|
||||
|
||||
// calc normal vectors
|
||||
int nverts = (int)pos.size()/3;
|
||||
|
||||
int nfaces = mesh->GetNumCoarseFaces();
|
||||
for (int i = 0; i < nfaces; ++i) {
|
||||
OsdHbrFace * f = mesh->GetFace(i);
|
||||
int nfaces = refiner.GetNumFaces(0);
|
||||
for (int face = 0; face < nfaces; ++face) {
|
||||
|
||||
float const * p0 = &pos[f->GetVertex(0)->GetID()*3],
|
||||
* p1 = &pos[f->GetVertex(1)->GetID()*3],
|
||||
* p2 = &pos[f->GetVertex(2)->GetID()*3];
|
||||
IndexArray fverts = refiner.GetFaceVertices(0, face);
|
||||
|
||||
assert(fverts.size()>=2);
|
||||
|
||||
float const * p0 = &pos[fverts[0]*3],
|
||||
* p1 = &pos[fverts[1]*3],
|
||||
* p2 = &pos[fverts[2]*3];
|
||||
|
||||
float n[3];
|
||||
cross(n, p0, p1, p2);
|
||||
|
||||
for (int j = 0; j < f->GetNumVertices(); j++) {
|
||||
int idx = f->GetVertex(j)->GetID() * 3;
|
||||
result[idx ] += n[0];
|
||||
result[idx+1] += n[1];
|
||||
result[idx+2] += n[2];
|
||||
for (int j = 0; j < fverts.size(); j++) {
|
||||
int idx = fverts[j] * 3;
|
||||
normals[idx ] += n[0];
|
||||
normals[idx+1] += n[1];
|
||||
normals[idx+2] += n[2];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < nverts; ++i)
|
||||
normalize(&result[i*3]);
|
||||
normalize(&normals[i*3]);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
updateGeom()
|
||||
{
|
||||
updateGeom() {
|
||||
|
||||
int nverts = (int)g_orgPositions.size() / 3;
|
||||
|
||||
std::vector<float> vertex;
|
||||
@ -456,69 +308,80 @@ updateGeom()
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
createOsdMesh(const std::string &shape, int level, Scheme scheme = kCatmark)
|
||||
{
|
||||
// generate Hbr representation from "obj" description
|
||||
OsdHbrMesh * hmesh = simpleHbr<OpenSubdiv::OsdVertex>(shape.c_str(),
|
||||
scheme,
|
||||
g_orgPositions,
|
||||
/*fvar*/ true);
|
||||
createOsdMesh(ShapeDesc const & shapeDesc, int level, Scheme scheme = kCatmark) {
|
||||
|
||||
g_normals.resize(g_orgPositions.size(), 0.0f);
|
||||
g_positions.resize(g_orgPositions.size(), 0.0f);
|
||||
calcNormals(hmesh, g_orgPositions, g_normals);
|
||||
typedef OpenSubdiv::Far::IndexArray IndexArray;
|
||||
|
||||
Shape * shape = Shape::parseObj(shapeDesc.data.c_str(), shapeDesc.scheme);
|
||||
|
||||
// create Vtr mesh (topology)
|
||||
OpenSubdiv::Sdc::Type sdctype = GetSdcType(*shape);
|
||||
OpenSubdiv::Sdc::Options sdcoptions = GetSdcOptions(*shape);
|
||||
|
||||
sdcoptions.SetFVarBoundaryInterpolation(g_fvarBoundary);
|
||||
|
||||
OpenSubdiv::Far::TopologyRefiner * refiner =
|
||||
OpenSubdiv::Far::TopologyRefinerFactory<Shape>::Create(sdctype, sdcoptions, *shape);
|
||||
|
||||
// save coarse topology (used for coarse mesh drawing)
|
||||
g_coarseEdges.clear();
|
||||
g_coarseEdgeSharpness.clear();
|
||||
g_coarseVertexSharpness.clear();
|
||||
int nf = hmesh->GetNumFaces();
|
||||
for (int i = 0; i < nf; ++i) {
|
||||
OsdHbrFace *face = hmesh->GetFace(i);
|
||||
int nv = face->GetNumVertices();
|
||||
for (int j = 0; j < nv; ++j) {
|
||||
g_coarseEdges.push_back(face->GetVertex(j)->GetID());
|
||||
g_coarseEdges.push_back(face->GetVertex((j+1)%nv)->GetID());
|
||||
g_coarseEdgeSharpness.push_back(face->GetEdge(j)->GetSharpness());
|
||||
}
|
||||
}
|
||||
int nv = hmesh->GetNumVertices();
|
||||
for (int i = 0; i < nv; ++i) {
|
||||
g_coarseVertexSharpness.push_back(hmesh->GetVertex(i)->GetSharpness());
|
||||
int nedges = refiner->GetNumEdges(0),
|
||||
nverts = refiner->GetNumVertices(0);
|
||||
|
||||
g_coarseEdges.resize(nedges*2);
|
||||
g_coarseEdgeSharpness.resize(nedges);
|
||||
g_coarseVertexSharpness.resize(nverts);
|
||||
|
||||
for(int i=0; i<nedges; ++i) {
|
||||
IndexArray verts = refiner->GetEdgeVertices(0, i);
|
||||
g_coarseEdges[i*2 ]=verts[0];
|
||||
g_coarseEdges[i*2+1]=verts[1];
|
||||
g_coarseEdgeSharpness[i]=refiner->GetEdgeSharpness(0, i);
|
||||
}
|
||||
|
||||
hmesh->SetFVarInterpolateBoundaryMethod((OsdHbrMesh::InterpolateBoundaryMethod)g_fvarBoundary);
|
||||
hmesh->SetFVarPropagateCorners(g_fvarPropagateCorners != 0);
|
||||
for(int i=0; i<nverts; ++i) {
|
||||
g_coarseVertexSharpness[i]=refiner->GetVertexSharpness(0, i);
|
||||
}
|
||||
|
||||
delete g_mesh;
|
||||
g_mesh = NULL;
|
||||
g_orgPositions=shape->verts;
|
||||
g_normals.resize(g_orgPositions.size(), 0.0f);
|
||||
calcNormals(*refiner, g_orgPositions, g_normals);
|
||||
|
||||
g_positions.resize(g_orgPositions.size(),0.0f);
|
||||
|
||||
g_scheme = scheme;
|
||||
|
||||
// Adaptive refinement currently supported only for catmull-clark scheme
|
||||
bool doAdaptive = (g_adaptive != 0 and g_scheme == kCatmark);
|
||||
bool doAdaptive = (g_adaptive!=0 and g_scheme==kCatmark);
|
||||
|
||||
OpenSubdiv::OsdMeshBitset bits;
|
||||
bits.set(OpenSubdiv::MeshAdaptive, doAdaptive);
|
||||
bits.set(OpenSubdiv::MeshFVarData, 1);
|
||||
OpenSubdiv::Osd::MeshBitset bits;
|
||||
bits.set(OpenSubdiv::Osd::MeshAdaptive, doAdaptive);
|
||||
bits.set(OpenSubdiv::Osd::MeshFVarData, 1);
|
||||
|
||||
int numVertexElements = 3;
|
||||
int numVaryingElements = 0;
|
||||
|
||||
if (not g_cpuComputeController) {
|
||||
g_cpuComputeController = new OpenSubdiv::OsdCpuComputeController();
|
||||
g_cpuComputeController = new OpenSubdiv::Osd::CpuComputeController();
|
||||
}
|
||||
g_mesh = new OpenSubdiv::OsdMesh<OpenSubdiv::OsdCpuGLVertexBuffer,
|
||||
OpenSubdiv::OsdCpuComputeController,
|
||||
OpenSubdiv::OsdGLDrawContext>(
|
||||
|
||||
delete g_mesh;
|
||||
|
||||
g_mesh = new OpenSubdiv::Osd::Mesh<OpenSubdiv::Osd::CpuGLVertexBuffer,
|
||||
OpenSubdiv::Osd::CpuComputeController,
|
||||
OpenSubdiv::Osd::GLDrawContext>(
|
||||
g_cpuComputeController,
|
||||
hmesh,
|
||||
refiner,
|
||||
numVertexElements,
|
||||
numVaryingElements,
|
||||
level, bits);
|
||||
|
||||
// Hbr mesh can be deleted
|
||||
delete hmesh;
|
||||
std::vector<float> fvarData;
|
||||
|
||||
InterpolateFVarData(*refiner, *shape, fvarData);
|
||||
|
||||
g_mesh->SetFVarDataChannel(shape->GetFVarWidth(), fvarData);
|
||||
|
||||
delete shape;
|
||||
|
||||
// compute model bounding
|
||||
float min[3] = { FLT_MAX, FLT_MAX, FLT_MAX};
|
||||
@ -553,8 +416,8 @@ createOsdMesh(const std::string &shape, int level, Scheme scheme = kCatmark)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
fitFrame()
|
||||
{
|
||||
fitFrame() {
|
||||
|
||||
g_pan[0] = g_pan[1] = 0;
|
||||
g_dolly = g_size;
|
||||
g_uvPan[0] = g_uvPan[1] = 0;
|
||||
@ -563,8 +426,8 @@ fitFrame()
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static inline void
|
||||
setSharpnessColor(float s, float *r, float *g, float *b)
|
||||
{
|
||||
setSharpnessColor(float s, float *r, float *g, float *b) {
|
||||
|
||||
// 0.0 2.0 4.0
|
||||
// green --- yellow --- red
|
||||
*r = std::min(1.0f, s * 0.5f);
|
||||
@ -573,8 +436,8 @@ setSharpnessColor(float s, float *r, float *g, float *b)
|
||||
}
|
||||
|
||||
static void
|
||||
drawCageEdges()
|
||||
{
|
||||
drawCageEdges() {
|
||||
|
||||
glUseProgram(g_defaultProgram.program);
|
||||
glUniformMatrix4fv(g_defaultProgram.uniformModelViewProjectionMatrix,
|
||||
1, GL_FALSE, g_transformData.ModelViewProjectionMatrix);
|
||||
@ -614,8 +477,8 @@ drawCageEdges()
|
||||
}
|
||||
|
||||
static void
|
||||
drawCageVertices()
|
||||
{
|
||||
drawCageVertices() {
|
||||
|
||||
glUseProgram(g_defaultProgram.program);
|
||||
glUniformMatrix4fv(g_defaultProgram.uniformModelViewProjectionMatrix,
|
||||
1, GL_FALSE, g_transformData.ModelViewProjectionMatrix);
|
||||
@ -657,8 +520,8 @@ drawCageVertices()
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
union Effect
|
||||
{
|
||||
union Effect {
|
||||
|
||||
Effect(int displayStyle_, int uvDraw_) : value(0) {
|
||||
displayStyle = displayStyle_;
|
||||
uvDraw = uvDraw_;
|
||||
@ -675,10 +538,10 @@ union Effect
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::pair<OpenSubdiv::OsdDrawContext::PatchDescriptor, Effect> EffectDesc;
|
||||
typedef std::pair<OpenSubdiv::Osd::DrawContext::PatchDescriptor, Effect> EffectDesc;
|
||||
|
||||
class EffectDrawRegistry : public OpenSubdiv::Osd::GLDrawRegistry<EffectDesc> {
|
||||
|
||||
class EffectDrawRegistry : public OpenSubdiv::OsdGLDrawRegistry<EffectDesc>
|
||||
{
|
||||
protected:
|
||||
virtual ConfigType *
|
||||
_CreateDrawConfig(DescType const & desc, SourceConfigType const * sconfig);
|
||||
@ -688,8 +551,8 @@ class EffectDrawRegistry : public OpenSubdiv::OsdGLDrawRegistry<EffectDesc>
|
||||
};
|
||||
|
||||
EffectDrawRegistry::SourceConfigType *
|
||||
EffectDrawRegistry::_CreateDrawSourceConfig(DescType const & desc)
|
||||
{
|
||||
EffectDrawRegistry::_CreateDrawSourceConfig(DescType const & desc) {
|
||||
|
||||
Effect effect = desc.second;
|
||||
|
||||
SourceConfigType * sconfig =
|
||||
@ -703,8 +566,8 @@ EffectDrawRegistry::_CreateDrawSourceConfig(DescType const & desc)
|
||||
const char *glslVersion = "#version 330\n";
|
||||
#endif
|
||||
|
||||
if (desc.first.GetType() == OpenSubdiv::FarPatchTables::QUADS or
|
||||
desc.first.GetType() == OpenSubdiv::FarPatchTables::TRIANGLES) {
|
||||
if (desc.first.GetType() == OpenSubdiv::Far::PatchTables::QUADS or
|
||||
desc.first.GetType() == OpenSubdiv::Far::PatchTables::TRIANGLES) {
|
||||
sconfig->vertexShader.source = shaderSource;
|
||||
sconfig->vertexShader.version = glslVersion;
|
||||
sconfig->vertexShader.AddDefine("VERTEX_SHADER");
|
||||
@ -723,12 +586,12 @@ EffectDrawRegistry::_CreateDrawSourceConfig(DescType const & desc)
|
||||
sconfig->commonShader.AddDefine("OSD_FVAR_WIDTH", "2");
|
||||
|
||||
|
||||
if (desc.first.GetType() == OpenSubdiv::FarPatchTables::QUADS) {
|
||||
if (desc.first.GetType() == OpenSubdiv::Far::PatchTables::QUADS) {
|
||||
// uniform catmark, bilinear
|
||||
sconfig->geometryShader.AddDefine("PRIM_QUAD");
|
||||
sconfig->fragmentShader.AddDefine("PRIM_QUAD");
|
||||
sconfig->commonShader.AddDefine("UNIFORM_SUBDIVISION");
|
||||
} else if (desc.first.GetType() == OpenSubdiv::FarPatchTables::TRIANGLES) {
|
||||
} else if (desc.first.GetType() == OpenSubdiv::Far::PatchTables::TRIANGLES) {
|
||||
// uniform loop
|
||||
sconfig->geometryShader.AddDefine("PRIM_TRI");
|
||||
sconfig->fragmentShader.AddDefine("PRIM_TRI");
|
||||
@ -767,8 +630,8 @@ EffectDrawRegistry::_CreateDrawSourceConfig(DescType const & desc)
|
||||
EffectDrawRegistry::ConfigType *
|
||||
EffectDrawRegistry::_CreateDrawConfig(
|
||||
DescType const & desc,
|
||||
SourceConfigType const * sconfig)
|
||||
{
|
||||
SourceConfigType const * sconfig) {
|
||||
|
||||
ConfigType * config = BaseRegistry::_CreateDrawConfig(desc.first, sconfig);
|
||||
assert(config);
|
||||
|
||||
@ -827,15 +690,15 @@ EffectDrawRegistry::_CreateDrawConfig(
|
||||
EffectDrawRegistry effectRegistry;
|
||||
|
||||
static Effect
|
||||
GetEffect(bool uvDraw = false)
|
||||
{
|
||||
GetEffect(bool uvDraw = false) {
|
||||
|
||||
return Effect(g_displayStyle, uvDraw);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static GLuint
|
||||
bindProgram(Effect effect, OpenSubdiv::OsdDrawContext::PatchArray const & patch)
|
||||
{
|
||||
bindProgram(Effect effect, OpenSubdiv::Osd::DrawContext::PatchArray const & patch) {
|
||||
|
||||
EffectDesc effectDesc(patch.GetDescriptor(), effect);
|
||||
EffectDrawRegistry::ConfigType *
|
||||
config = effectRegistry.GetDrawConfig(effectDesc);
|
||||
@ -910,8 +773,8 @@ bindProgram(Effect effect, OpenSubdiv::OsdDrawContext::PatchArray const & patch)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
display()
|
||||
{
|
||||
display() {
|
||||
|
||||
Stopwatch s;
|
||||
s.Start();
|
||||
|
||||
@ -944,26 +807,26 @@ display()
|
||||
|
||||
glBindVertexArray(g_vao);
|
||||
|
||||
OpenSubdiv::OsdDrawContext::PatchArrayVector const & patches =
|
||||
g_mesh->GetDrawContext()->patchArrays;
|
||||
OpenSubdiv::Osd::DrawContext::PatchArrayVector const & patches =
|
||||
g_mesh->GetDrawContext()->GetPatchArrays();
|
||||
|
||||
if (g_displayStyle == kWire)
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
// patch drawing
|
||||
for (int i = 0; i < (int)patches.size(); ++i) {
|
||||
OpenSubdiv::OsdDrawContext::PatchArray const & patch = patches[i];
|
||||
OpenSubdiv::Osd::DrawContext::PatchArray const & patch = patches[i];
|
||||
|
||||
OpenSubdiv::OsdDrawContext::PatchDescriptor desc = patch.GetDescriptor();
|
||||
OpenSubdiv::FarPatchTables::Type patchType = desc.GetType();
|
||||
OpenSubdiv::Osd::DrawContext::PatchDescriptor desc = patch.GetDescriptor();
|
||||
OpenSubdiv::Far::PatchTables::Type patchType = desc.GetType();
|
||||
|
||||
GLenum primType;
|
||||
|
||||
switch (patchType) {
|
||||
case OpenSubdiv::FarPatchTables::QUADS:
|
||||
case OpenSubdiv::Far::PatchTables::QUADS:
|
||||
primType = GL_LINES_ADJACENCY;
|
||||
break;
|
||||
case OpenSubdiv::FarPatchTables::TRIANGLES:
|
||||
case OpenSubdiv::Far::PatchTables::TRIANGLES:
|
||||
primType = GL_TRIANGLES;
|
||||
break;
|
||||
default:
|
||||
@ -1017,18 +880,18 @@ display()
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
|
||||
for (int i = 0; i < (int)patches.size(); ++i) {
|
||||
OpenSubdiv::OsdDrawContext::PatchArray const & patch = patches[i];
|
||||
OpenSubdiv::Osd::DrawContext::PatchArray const & patch = patches[i];
|
||||
|
||||
OpenSubdiv::OsdDrawContext::PatchDescriptor desc = patch.GetDescriptor();
|
||||
OpenSubdiv::FarPatchTables::Type patchType = desc.GetType();
|
||||
OpenSubdiv::Osd::DrawContext::PatchDescriptor desc = patch.GetDescriptor();
|
||||
OpenSubdiv::Far::PatchTables::Type patchType = desc.GetType();
|
||||
|
||||
GLenum primType;
|
||||
|
||||
switch (patchType) {
|
||||
case OpenSubdiv::FarPatchTables::QUADS:
|
||||
case OpenSubdiv::Far::PatchTables::QUADS:
|
||||
primType = GL_LINES_ADJACENCY;
|
||||
break;
|
||||
case OpenSubdiv::FarPatchTables::TRIANGLES:
|
||||
case OpenSubdiv::Far::PatchTables::TRIANGLES:
|
||||
primType = GL_TRIANGLES;
|
||||
break;
|
||||
default:
|
||||
@ -1078,14 +941,9 @@ display()
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
#if GLFW_VERSION_MAJOR >= 3
|
||||
motion(GLFWwindow *, double dx, double dy)
|
||||
{
|
||||
motion(GLFWwindow *, double dx, double dy) {
|
||||
int x=(int)dx, y=(int)dy;
|
||||
#else
|
||||
motion(int x, int y)
|
||||
{
|
||||
#endif
|
||||
|
||||
if (g_mouseUvView) {
|
||||
if (!g_mbutton[0] && !g_mbutton[1] && g_mbutton[2]) {
|
||||
// pan
|
||||
@ -1120,12 +978,8 @@ motion(int x, int y)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
#if GLFW_VERSION_MAJOR >= 3
|
||||
mouse(GLFWwindow *, int button, int state, int /* mods */)
|
||||
#else
|
||||
mouse(int button, int state)
|
||||
#endif
|
||||
{
|
||||
mouse(GLFWwindow *, int button, int state, int /* mods */) {
|
||||
|
||||
if (button == 0 && state == GLFW_PRESS && g_hud.MouseClick(g_prev_x, g_prev_y))
|
||||
return;
|
||||
|
||||
@ -1138,8 +992,8 @@ mouse(int button, int state)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
uninitGL()
|
||||
{
|
||||
uninitGL() {
|
||||
|
||||
glDeleteBuffers(1, &g_cageVertexVBO);
|
||||
glDeleteBuffers(1, &g_cageEdgeVBO);
|
||||
glDeleteVertexArrays(1, &g_vao);
|
||||
@ -1154,36 +1008,24 @@ uninitGL()
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
#if GLFW_VERSION_MAJOR >= 3
|
||||
reshape(GLFWwindow *, int width, int height)
|
||||
#else
|
||||
reshape(int width, int height)
|
||||
#endif
|
||||
{
|
||||
reshape(GLFWwindow *, int width, int height) {
|
||||
|
||||
g_width = width;
|
||||
g_height = height;
|
||||
|
||||
int windowWidth = g_width, windowHeight = g_height;
|
||||
#if GLFW_VERSION_MAJOR>=3
|
||||
|
||||
// window size might not match framebuffer size on a high DPI display
|
||||
glfwGetWindowSize(g_window, &windowWidth, &windowHeight);
|
||||
#endif
|
||||
|
||||
g_hud.Rebuild(windowWidth, windowHeight);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
#if GLFW_VERSION_MAJOR >= 3
|
||||
void windowClose(GLFWwindow*)
|
||||
{
|
||||
void windowClose(GLFWwindow*) {
|
||||
|
||||
g_running = false;
|
||||
}
|
||||
#else
|
||||
int windowClose()
|
||||
{
|
||||
g_running = false;
|
||||
return GL_TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
@ -1193,13 +1035,8 @@ toggleFullScreen() {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
#if GLFW_VERSION_MAJOR >= 3
|
||||
keyboard(GLFWwindow *, int key, int /* scancode */, int event, int /* mods */)
|
||||
#else
|
||||
#define GLFW_KEY_ESCAPE GLFW_KEY_ESC
|
||||
keyboard(int key, int event)
|
||||
#endif
|
||||
{
|
||||
keyboard(GLFWwindow *, int key, int /* scancode */, int event, int /* mods */) {
|
||||
|
||||
if (event == GLFW_RELEASE) return;
|
||||
if (g_hud.KeyDown(tolower(key))) return;
|
||||
|
||||
@ -1216,65 +1053,72 @@ keyboard(int key, int event)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
rebuildOsdMesh()
|
||||
{
|
||||
createOsdMesh(g_defaultShapes[g_currentShape].data,
|
||||
rebuildOsdMesh() {
|
||||
|
||||
createOsdMesh(g_defaultShapes[g_currentShape],
|
||||
g_level,
|
||||
g_defaultShapes[g_currentShape].scheme);
|
||||
}
|
||||
|
||||
static void
|
||||
callbackDisplayStyle(int b)
|
||||
{
|
||||
callbackDisplayStyle(int b) {
|
||||
|
||||
g_displayStyle = b;
|
||||
}
|
||||
|
||||
static void
|
||||
callbackLevel(int l)
|
||||
{
|
||||
callbackLevel(int l) {
|
||||
|
||||
g_level = l;
|
||||
rebuildOsdMesh();
|
||||
}
|
||||
|
||||
static void
|
||||
callbackModel(int m)
|
||||
{
|
||||
callbackModel(int m) {
|
||||
|
||||
int maxShapes = static_cast<int>(g_defaultShapes.size());
|
||||
g_currentShape = std::max(0, std::min(m, maxShapes-1));
|
||||
rebuildOsdMesh();
|
||||
}
|
||||
|
||||
static void
|
||||
callbackAdaptive(bool checked, int /* a */)
|
||||
{
|
||||
if (OpenSubdiv::OsdGLDrawContext::SupportsAdaptiveTessellation()) {
|
||||
callbackAdaptive(bool checked, int /* a */) {
|
||||
|
||||
if (OpenSubdiv::Osd::GLDrawContext::SupportsAdaptiveTessellation()) {
|
||||
g_adaptive = checked;
|
||||
rebuildOsdMesh();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
callbackBoundary(int b)
|
||||
{
|
||||
g_fvarBoundary = b;
|
||||
callbackBoundary(int b) {
|
||||
|
||||
typedef OpenSubdiv::Sdc::Options SdcOptions;
|
||||
|
||||
switch (b) {
|
||||
case 0 : g_fvarBoundary = SdcOptions::FVAR_BOUNDARY_BILINEAR; break;
|
||||
case 1 : g_fvarBoundary = SdcOptions::FVAR_BOUNDARY_EDGE_ONLY; break;
|
||||
case 2 : g_fvarBoundary = SdcOptions::FVAR_BOUNDARY_EDGE_AND_CORNER; break;
|
||||
case 3 : g_fvarBoundary = SdcOptions::FVAR_BOUNDARY_ALWAYS_SHARP; break;
|
||||
}
|
||||
rebuildOsdMesh();
|
||||
}
|
||||
|
||||
static void
|
||||
callbackPropagateCorners(bool b, int /* button */)
|
||||
{
|
||||
callbackPropagateCorners(bool b, int /* button */) {
|
||||
|
||||
g_fvarPropagateCorners = b;
|
||||
rebuildOsdMesh();
|
||||
}
|
||||
|
||||
static void
|
||||
initHUD()
|
||||
{
|
||||
initHUD() {
|
||||
|
||||
int windowWidth = g_width, windowHeight = g_height;
|
||||
#if GLFW_VERSION_MAJOR>=3
|
||||
|
||||
// window size might not match framebuffer size on a high DPI display
|
||||
glfwGetWindowSize(g_window, &windowWidth, &windowHeight);
|
||||
#endif
|
||||
|
||||
g_hud.Init(windowWidth, windowHeight);
|
||||
|
||||
int shading_pulldown = g_hud.AddPullDown("Shading (W)", 300, 10, 250, callbackDisplayStyle, 'w');
|
||||
@ -1282,7 +1126,7 @@ initHUD()
|
||||
g_hud.AddPullDownButton(shading_pulldown, "Shaded", kShaded, g_displayStyle==kShaded);
|
||||
g_hud.AddPullDownButton(shading_pulldown, "Wire+Shaded", kWireShaded, g_displayStyle==kWireShaded);
|
||||
|
||||
if (OpenSubdiv::OsdGLDrawContext::SupportsAdaptiveTessellation())
|
||||
if (OpenSubdiv::Osd::GLDrawContext::SupportsAdaptiveTessellation())
|
||||
g_hud.AddCheckBox("Adaptive (`)", g_adaptive != 0, 10, 250, callbackAdaptive, 0, '`');
|
||||
|
||||
for (int i = 1; i < 11; ++i) {
|
||||
@ -1291,18 +1135,20 @@ initHUD()
|
||||
g_hud.AddRadioButton(3, level, i == 2, 10, 270 + i*20, callbackLevel, i, '0'+(i%10));
|
||||
}
|
||||
|
||||
typedef OpenSubdiv::Sdc::Options SdcOptions;
|
||||
|
||||
g_hud.AddRadioButton(2, "Boundary none (B)",
|
||||
g_fvarBoundary == OsdHbrMesh::k_InterpolateBoundaryNone,
|
||||
10, 10, callbackBoundary, OsdHbrMesh::k_InterpolateBoundaryNone, 'b');
|
||||
g_fvarBoundary == SdcOptions::FVAR_BOUNDARY_BILINEAR,
|
||||
10, 10, callbackBoundary, SdcOptions::FVAR_BOUNDARY_BILINEAR, 'b');
|
||||
g_hud.AddRadioButton(2, "Boundary edge only",
|
||||
g_fvarBoundary == OsdHbrMesh::k_InterpolateBoundaryEdgeOnly,
|
||||
10, 30, callbackBoundary, OsdHbrMesh::k_InterpolateBoundaryEdgeOnly, 'b');
|
||||
g_fvarBoundary == SdcOptions::FVAR_BOUNDARY_EDGE_ONLY,
|
||||
10, 30, callbackBoundary, SdcOptions::FVAR_BOUNDARY_EDGE_ONLY, 'b');
|
||||
g_hud.AddRadioButton(2, "Boundary edge and corners",
|
||||
g_fvarBoundary == OsdHbrMesh::k_InterpolateBoundaryEdgeAndCorner,
|
||||
10, 50, callbackBoundary, OsdHbrMesh::k_InterpolateBoundaryEdgeAndCorner, 'b');
|
||||
g_fvarBoundary == SdcOptions::FVAR_BOUNDARY_EDGE_AND_CORNER,
|
||||
10, 50, callbackBoundary, SdcOptions::FVAR_BOUNDARY_EDGE_AND_CORNER, 'b');
|
||||
g_hud.AddRadioButton(2, "Boundary always sharp",
|
||||
g_fvarBoundary == OsdHbrMesh::k_InterpolateBoundaryAlwaysSharp,
|
||||
10, 70, callbackBoundary, OsdHbrMesh::k_InterpolateBoundaryAlwaysSharp, 'b');
|
||||
g_fvarBoundary == SdcOptions::FVAR_BOUNDARY_ALWAYS_SHARP,
|
||||
10, 70, callbackBoundary, SdcOptions::FVAR_BOUNDARY_ALWAYS_SHARP, 'b');
|
||||
|
||||
g_hud.AddCheckBox("Propagate corners (C)", g_fvarPropagateCorners != 0,
|
||||
10, 110, callbackPropagateCorners, 0, 'c');
|
||||
@ -1315,8 +1161,8 @@ initHUD()
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
initGL()
|
||||
{
|
||||
initGL() {
|
||||
|
||||
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
@ -1332,8 +1178,8 @@ initGL()
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
idle()
|
||||
{
|
||||
idle() {
|
||||
|
||||
if (not g_freeze)
|
||||
g_frame++;
|
||||
|
||||
@ -1345,21 +1191,19 @@ idle()
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
callbackError(OpenSubdiv::OsdErrorType err, const char *message)
|
||||
{
|
||||
callbackError(OpenSubdiv::Osd::ErrorType err, const char *message) {
|
||||
|
||||
printf("OsdError: %d\n", err);
|
||||
printf("%s", message);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
setGLCoreProfile()
|
||||
{
|
||||
#if GLFW_VERSION_MAJOR >= 3
|
||||
setGLCoreProfile() {
|
||||
|
||||
#define glfwOpenWindowHint glfwWindowHint
|
||||
#define GLFW_OPENGL_VERSION_MAJOR GLFW_CONTEXT_VERSION_MAJOR
|
||||
#define GLFW_OPENGL_VERSION_MINOR GLFW_CONTEXT_VERSION_MINOR
|
||||
#endif
|
||||
|
||||
glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
#if not defined(__APPLE__)
|
||||
@ -1373,8 +1217,8 @@ setGLCoreProfile()
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
int main(int argc, char ** argv) {
|
||||
|
||||
bool fullscreen = false;
|
||||
std::string str;
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
@ -1391,26 +1235,27 @@ int main(int argc, char ** argv)
|
||||
ss << ifs.rdbuf();
|
||||
ifs.close();
|
||||
str = ss.str();
|
||||
g_defaultShapes.push_back(SimpleShape(str.c_str(), argv[1], kCatmark));
|
||||
g_defaultShapes.push_back(ShapeDesc(argv[1], str.c_str(), kCatmark));
|
||||
}
|
||||
}
|
||||
}
|
||||
initializeShapes();
|
||||
OsdSetErrorCallback(callbackError);
|
||||
|
||||
initShapes();
|
||||
|
||||
OpenSubdiv::Osd::SetErrorCallback(callbackError);
|
||||
|
||||
if (not glfwInit()) {
|
||||
printf("Failed to initialize GLFW\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const char windowTitle[] = "OpenSubdiv UV Viewer";
|
||||
static const char windowTitle[] = "OpenSubdiv glFVarViewer " OPENSUBDIV_VERSION_STRING;
|
||||
|
||||
#define CORE_PROFILE
|
||||
#ifdef CORE_PROFILE
|
||||
setGLCoreProfile();
|
||||
#endif
|
||||
|
||||
#if GLFW_VERSION_MAJOR >= 3
|
||||
if (fullscreen) {
|
||||
g_primary = glfwGetPrimaryMonitor();
|
||||
|
||||
@ -1447,20 +1292,6 @@ int main(int argc, char ** argv)
|
||||
glfwSetCursorPosCallback(g_window, motion);
|
||||
glfwSetMouseButtonCallback(g_window, mouse);
|
||||
glfwSetWindowCloseCallback(g_window, windowClose);
|
||||
#else
|
||||
if (glfwOpenWindow(g_width, g_height, 8, 8, 8, 8, 24, 8,
|
||||
fullscreen ? GLFW_FULLSCREEN : GLFW_WINDOW) == GL_FALSE) {
|
||||
printf("Failed to open window.\n");
|
||||
glfwTerminate();
|
||||
return 1;
|
||||
}
|
||||
glfwSetWindowTitle(windowTitle);
|
||||
glfwSetKeyCallback(keyboard);
|
||||
glfwSetMousePosCallback(motion);
|
||||
glfwSetMouseButtonCallback(mouse);
|
||||
glfwSetWindowSizeCallback(reshape);
|
||||
glfwSetWindowCloseCallback(windowClose);
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(OSD_USES_GLEW)
|
||||
@ -1490,12 +1321,8 @@ int main(int argc, char ** argv)
|
||||
idle();
|
||||
display();
|
||||
|
||||
#if GLFW_VERSION_MAJOR >= 3
|
||||
glfwPollEvents();
|
||||
glfwSwapBuffers(g_window);
|
||||
#else
|
||||
glfwSwapBuffers();
|
||||
#endif
|
||||
|
||||
glFinish();
|
||||
}
|