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.
This commit is contained in:
manuelk 2014-09-05 15:07:46 -07:00
parent 281c42c22c
commit c399655dcc
461 changed files with 42500 additions and 79227 deletions

View File

@ -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)

View File

@ -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/).

View File

@ -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

View File

@ -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})

View File

@ -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"

View File

@ -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}"

View File

@ -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

View File

@ -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

View File

@ -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
________________

View File

@ -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.
|
----

File diff suppressed because it is too large Load Diff

View File

@ -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;

View File

@ -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,

Binary file not shown.

View 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

View File

@ -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

View 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>`__, \

View File

@ -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

View File

@ -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. |
+----------------------+---------------------------------------------------------------------------------------+
----

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View 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

View File

@ -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

View File

@ -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

View File

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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.

View File

@ -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>`_

View 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:

View File

@ -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>

View 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).

View File

@ -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
View 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|
|

View File

@ -0,0 +1,10 @@
.. container:: notebox
Content under development....
.. image:: images/construction.png
:align: center
:height: 100

View File

@ -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>`_

View File

@ -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 &) { }
};

View File

@ -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

View 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.

View File

@ -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()

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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();

View File

@ -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

View File

@ -33,7 +33,6 @@ class GLhud;
class GLFrameBuffer {
public:
GLFrameBuffer();
int GetWidth() const {

View File

@ -250,4 +250,3 @@ GLhud::Flush()
return true;
}

View File

@ -64,6 +64,10 @@ public:
return _frameBuffer;
}
GLuint GetFontTexture() const {
return _fontTexture;
}
private:

View File

@ -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]);
}
}

View File

@ -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
View 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;
}

View File

@ -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

View File

@ -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];
}
}

View File

@ -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 */

View File

@ -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;

View File

@ -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);
}

View File

@ -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>
)

View File

@ -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) {

View File

@ -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>
)

File diff suppressed because it is too large Load Diff

View 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 ) );
}
//------------------------------------------------------------------------------

View File

@ -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;
}

View File

@ -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}")

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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);
}

View File

@ -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 */

View File

@ -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
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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));
}

File diff suppressed because it is too large Load Diff

View File

@ -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}")

View File

@ -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();
}

View 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 ) );
}
//------------------------------------------------------------------------------

View File

@ -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}")

View File

@ -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();
}

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