mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2025-01-08 07:40:17 +00:00
Release 1.2.0
This commit is contained in:
commit
846eaf141d
@ -142,6 +142,13 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANGCC)
|
||||
# HBR uses the offsetof macro on a templated struct, which appears
|
||||
# to spurriously set off this warning in both gccc and Clang
|
||||
list(APPEND OSD_COMPILER_FLAGS -Wno-invalid-offsetof)
|
||||
|
||||
# HBR uses unions as an optimization for its memory allocation.
|
||||
# Type casting between union members breaks strict aliasing rules from
|
||||
# gcc 4.4.1 versions onwards. We disable the warning but keep aliasing
|
||||
# optimization.
|
||||
list(APPEND OSD_COMPILER_FLAGS -Wno-strict-aliasing)
|
||||
|
||||
|
||||
# FAR and OSD have templated virtual function implementations that trigger
|
||||
# a lot of hidden virtual function overloads (some of them spurrious).
|
||||
@ -422,7 +429,7 @@ if(PYTHONINTERP_FOUND AND SWIG_FOUND)
|
||||
endif()
|
||||
else()
|
||||
message(WARNING
|
||||
"Python / Swig not found : pythong bindings and examples will no be "
|
||||
"Python / Swig not found : python bindings and examples will not be "
|
||||
"available. If you do have Python and Swig installed and see this "
|
||||
"message, please check the default FindPython.cmake module."
|
||||
)
|
||||
|
@ -59,9 +59,9 @@ if( OPENGL_FOUND AND (GLEW_FOUND AND GLFW_FOUND) OR (APPLE AND GLFW_FOUND))
|
||||
add_subdirectory(glViewer)
|
||||
add_subdirectory(glBatchViewer)
|
||||
add_subdirectory(simpleCpu)
|
||||
#add_subdirectory(evalTest)
|
||||
# add_subdirectory(evalTest)
|
||||
add_subdirectory(limitEval)
|
||||
if(NOT APPLE)
|
||||
if(OPENGL_4_3_FOUND)
|
||||
# the paintTest example requires GL functionality not available on OSX
|
||||
add_subdirectory(paintTest)
|
||||
endif()
|
||||
@ -99,8 +99,8 @@ endif()
|
||||
|
||||
# XXXX manuelk : turning off the maya plugin examples for now
|
||||
if(MAYA_FOUND AND (NOT APPLE))
|
||||
add_subdirectory(mayaViewer)
|
||||
# add_subdirectory(mayaViewer)
|
||||
if(PTEX_FOUND)
|
||||
add_subdirectory(mayaPtexViewer)
|
||||
# add_subdirectory(mayaPtexViewer)
|
||||
endif()
|
||||
endif()
|
||||
|
47
examples/dxViewer/dxviewer.cpp
Normal file → Executable file
47
examples/dxViewer/dxviewer.cpp
Normal file → Executable file
@ -601,7 +601,7 @@ enum Effect {
|
||||
kPoint = 6,
|
||||
};
|
||||
|
||||
typedef std::pair<OpenSubdiv::OsdPatchDescriptor,Effect> EffectDesc;
|
||||
typedef std::pair<OpenSubdiv::OsdDrawContext::PatchDescriptor, Effect> EffectDesc;
|
||||
|
||||
class EffectDrawRegistry : public OpenSubdiv::OsdD3D11DrawRegistry<EffectDesc> {
|
||||
|
||||
@ -631,17 +631,16 @@ EffectDrawRegistry::_CreateDrawSourceConfig(
|
||||
sconfig->commonShader.AddDefine("OSD_ENABLE_SCREENSPACE_TESSELLATION");
|
||||
|
||||
bool smoothNormals = false;
|
||||
if (desc.first.type != OpenSubdiv::kNonPatch) {
|
||||
|
||||
if (desc.first.GetType() == OpenSubdiv::FarPatchTables::QUADS ||
|
||||
desc.first.GetType() == OpenSubdiv::FarPatchTables::TRIANGLES) {
|
||||
sconfig->vertexShader.source = shaderSource;
|
||||
sconfig->vertexShader.target = "vs_5_0";
|
||||
sconfig->vertexShader.entry = "vs_main";
|
||||
} else {
|
||||
if (effect == kQuadWire) effect = kTriWire;
|
||||
if (effect == kQuadFill) effect = kTriFill;
|
||||
if (effect == kQuadLine) effect = kTriLine;
|
||||
smoothNormals = true;
|
||||
|
||||
} else {
|
||||
sconfig->vertexShader.source = shaderSource;
|
||||
sconfig->vertexShader.target = "vs_5_0";
|
||||
sconfig->vertexShader.entry = "vs_main";
|
||||
}
|
||||
assert(sconfig);
|
||||
|
||||
@ -742,9 +741,9 @@ GetEffect()
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void
|
||||
bindProgram(Effect effect, OpenSubdiv::OsdPatchArray const & patch)
|
||||
bindProgram(Effect effect, OpenSubdiv::OsdDrawContext::PatchArray const & patch)
|
||||
{
|
||||
EffectDesc effectDesc(patch.desc, effect);
|
||||
EffectDesc effectDesc(patch.GetDescriptor(), effect);
|
||||
|
||||
// input layout
|
||||
const D3D11_INPUT_ELEMENT_DESC hInElementDesc[] = {
|
||||
@ -826,8 +825,8 @@ bindProgram(Effect effect, OpenSubdiv::OsdPatchArray const & patch)
|
||||
Tessellation * pData = ( Tessellation* )MappedResource.pData;
|
||||
|
||||
pData->TessLevel = static_cast<float>(1 << g_tessLevel);
|
||||
pData->GregoryQuadOffsetBase = patch.gregoryQuadOffsetBase;
|
||||
pData->LevelBase = patch.levelBase;
|
||||
pData->GregoryQuadOffsetBase = patch.GetQuadOffsetIndex();
|
||||
pData->LevelBase = patch.GetPatchIndex();
|
||||
|
||||
g_pd3dDeviceContext->Unmap( g_pcbTessellation, 0 );
|
||||
}
|
||||
@ -856,9 +855,9 @@ bindProgram(Effect effect, OpenSubdiv::OsdPatchArray const & patch)
|
||||
if (g_mesh->GetDrawContext()->quadOffsetBufferSRV) {
|
||||
g_pd3dDeviceContext->HSSetShaderResources(2, 1, &g_mesh->GetDrawContext()->quadOffsetBufferSRV);
|
||||
}
|
||||
if (g_mesh->GetDrawContext()->patchLevelBufferSRV) {
|
||||
g_pd3dDeviceContext->HSSetShaderResources(3, 1, &g_mesh->GetDrawContext()->patchLevelBufferSRV);
|
||||
g_pd3dDeviceContext->DSSetShaderResources(3, 1, &g_mesh->GetDrawContext()->patchLevelBufferSRV);
|
||||
if (g_mesh->GetDrawContext()->ptexCoordinateBufferSRV) {
|
||||
g_pd3dDeviceContext->HSSetShaderResources(3, 1, &g_mesh->GetDrawContext()->ptexCoordinateBufferSRV);
|
||||
g_pd3dDeviceContext->DSSetShaderResources(3, 1, &g_mesh->GetDrawContext()->ptexCoordinateBufferSRV);
|
||||
}
|
||||
}
|
||||
|
||||
@ -882,35 +881,37 @@ display()
|
||||
UINT hOffsets = 0;
|
||||
g_pd3dDeviceContext->IASetVertexBuffers(0, 1, &buffer, &hStrides, &hOffsets);
|
||||
|
||||
OpenSubdiv::OsdPatchArrayVector const & patches = g_mesh->GetDrawContext()->patchArrays;
|
||||
OpenSubdiv::OsdDrawContext::PatchArrayVector const & patches = g_mesh->GetDrawContext()->patchArrays;
|
||||
|
||||
g_pd3dDeviceContext->IASetIndexBuffer(g_mesh->GetDrawContext()->patchIndexBuffer, DXGI_FORMAT_R32_UINT, 0);
|
||||
|
||||
// cv drawing
|
||||
#if 0
|
||||
if (g_drawPatchCVs) {
|
||||
|
||||
bindProgram(kPoint, OpenSubdiv::OsdPatchArray());
|
||||
bindProgram(kPoint, OpenSubdiv::OsdDrawContext::PatchArray());
|
||||
|
||||
g_pd3dDeviceContext->IASetPrimitiveTopology(
|
||||
D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||
|
||||
for (int i=0; i<(int)patches.size(); ++i) {
|
||||
OpenSubdiv::OsdPatchArray const & patch = patches[i];
|
||||
OpenSubdiv::OsdDrawContext::PatchArray const & patch = patches[i];
|
||||
|
||||
g_pd3dDeviceContext->DrawIndexed(patch.numIndices,
|
||||
patch.firstIndex, 0);
|
||||
g_pd3dDeviceContext->DrawIndexed(patch.GetNumIndices(),
|
||||
patch.GetVertIndex(), 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// patch drawing
|
||||
for (int i=0; i<(int)patches.size(); ++i) {
|
||||
OpenSubdiv::OsdPatchArray const & patch = patches[i];
|
||||
OpenSubdiv::OsdDrawContext::PatchArray const & patch = patches[i];
|
||||
|
||||
D3D11_PRIMITIVE_TOPOLOGY topology;
|
||||
|
||||
if (g_mesh->GetDrawContext()->IsAdaptive()) {
|
||||
|
||||
switch (patch.desc.GetPatchSize()) {
|
||||
switch (patch.GetDescriptor().GetNumControlVertices()) {
|
||||
case 4:
|
||||
topology = D3D11_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST;
|
||||
break;
|
||||
@ -941,7 +942,7 @@ display()
|
||||
g_pd3dDeviceContext->IASetPrimitiveTopology(topology);
|
||||
|
||||
g_pd3dDeviceContext->DrawIndexed(
|
||||
patch.numIndices, patch.firstIndex, 0);
|
||||
patch.GetNumIndices(), patch.GetVertIndex(), 0);
|
||||
}
|
||||
|
||||
if (g_hud->IsVisible()) {
|
||||
|
@ -100,6 +100,9 @@ endforeach()
|
||||
|
||||
_add_glfw_executable(glBatchViewer
|
||||
viewer.cpp
|
||||
delegate.cpp
|
||||
effect.cpp
|
||||
effectRegistry.cpp
|
||||
../common/font_image.cpp
|
||||
../common/hud.cpp
|
||||
../common/gl_hud.cpp
|
||||
|
219
examples/glBatchViewer/delegate.cpp
Normal file
219
examples/glBatchViewer/delegate.cpp
Normal file
@ -0,0 +1,219 @@
|
||||
//
|
||||
// Copyright (C) Pixar. All rights reserved.
|
||||
//
|
||||
// This license governs use of the accompanying software. If you
|
||||
// use the software, you accept this license. If you do not accept
|
||||
// the license, do not use the software.
|
||||
//
|
||||
// 1. Definitions
|
||||
// The terms "reproduce," "reproduction," "derivative works," and
|
||||
// "distribution" have the same meaning here as under U.S.
|
||||
// copyright law. A "contribution" is the original software, or
|
||||
// any additions or changes to the software.
|
||||
// A "contributor" is any person or entity that distributes its
|
||||
// contribution under this license.
|
||||
// "Licensed patents" are a contributor's patent claims that read
|
||||
// directly on its contribution.
|
||||
//
|
||||
// 2. Grant of Rights
|
||||
// (A) Copyright Grant- Subject to the terms of this license,
|
||||
// including the license conditions and limitations in section 3,
|
||||
// each contributor grants you a non-exclusive, worldwide,
|
||||
// royalty-free copyright license to reproduce its contribution,
|
||||
// prepare derivative works of its contribution, and distribute
|
||||
// its contribution or any derivative works that you create.
|
||||
// (B) Patent Grant- Subject to the terms of this license,
|
||||
// including the license conditions and limitations in section 3,
|
||||
// each contributor grants you a non-exclusive, worldwide,
|
||||
// royalty-free license under its licensed patents to make, have
|
||||
// made, use, sell, offer for sale, import, and/or otherwise
|
||||
// dispose of its contribution in the software or derivative works
|
||||
// of the contribution in the software.
|
||||
//
|
||||
// 3. Conditions and Limitations
|
||||
// (A) No Trademark License- This license does not grant you
|
||||
// rights to use any contributor's name, logo, or trademarks.
|
||||
// (B) If you bring a patent claim against any contributor over
|
||||
// patents that you claim are infringed by the software, your
|
||||
// patent license from such contributor to the software ends
|
||||
// automatically.
|
||||
// (C) If you distribute any portion of the software, you must
|
||||
// retain all copyright, patent, trademark, and attribution
|
||||
// notices that are present in the software.
|
||||
// (D) If you distribute any portion of the software in source
|
||||
// code form, you may do so only under this license by including a
|
||||
// complete copy of this license with your distribution. If you
|
||||
// distribute any portion of the software in compiled or object
|
||||
// code form, you may only do so under a license that complies
|
||||
// with this license.
|
||||
// (E) The software is licensed "as-is." You bear the risk of
|
||||
// using it. The contributors give no express warranties,
|
||||
// guarantees or conditions. You may have additional consumer
|
||||
// rights under your local laws which this license cannot change.
|
||||
// To the extent permitted under your local laws, the contributors
|
||||
// exclude the implied warranties of merchantability, fitness for
|
||||
// a particular purpose and non-infringement.
|
||||
//
|
||||
#if defined(__APPLE__)
|
||||
#include "TargetConditionals.h"
|
||||
#if TARGET_OS_IPHONE or TARGET_IPHONE_SIMULATOR
|
||||
#include <OpenGLES/ES2/gl.h>
|
||||
#else
|
||||
#include <OpenGL/gl3.h>
|
||||
#endif
|
||||
#elif defined(ANDROID)
|
||||
#include <GLES2/gl2.h>
|
||||
#else
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <GL/glew.h>
|
||||
#endif
|
||||
|
||||
#include "delegate.h"
|
||||
|
||||
MyDrawContext::MyDrawContext() {
|
||||
glGenVertexArrays(1, &_vao);
|
||||
}
|
||||
|
||||
MyDrawContext::~MyDrawContext() {
|
||||
glDeleteVertexArrays(1, &_vao);
|
||||
}
|
||||
|
||||
MyDrawContext*
|
||||
MyDrawContext::Create(OpenSubdiv::FarMesh<OpenSubdiv::OsdVertex> const *farMesh, bool requireFVarData)
|
||||
{
|
||||
MyDrawContext *instance = new MyDrawContext();
|
||||
|
||||
OpenSubdiv::FarPatchTables const * patchTables = farMesh->GetPatchTables();
|
||||
|
||||
if (patchTables) {
|
||||
return Create(patchTables, requireFVarData);
|
||||
}
|
||||
|
||||
delete instance;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MyDrawContext*
|
||||
MyDrawContext::Create(OpenSubdiv::FarPatchTables const *patchTables, bool requireFVarData)
|
||||
{
|
||||
MyDrawContext * result = new MyDrawContext();
|
||||
|
||||
if (patchTables) {
|
||||
if (result->create(patchTables, 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
|
||||
// glBindVertexArray(batch->vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, batch->BindVertexBuffer());
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, drawContext->patchIndexBuffer);
|
||||
|
||||
// vertex attrib
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof (GLfloat) * 3, 0);
|
||||
|
||||
// bind other builtin texture buffers
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, drawContext->vertexTextureBuffer);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, drawContext->vertexValenceTextureBuffer);
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, drawContext->quadOffsetTextureBuffer);
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, drawContext->ptexCoordinateTextureBuffer);
|
||||
}
|
||||
if (effect != _currentEffect) {
|
||||
_currentEffect = effect;
|
||||
|
||||
// bind effect
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MyDrawDelegate::Unbind(OpenSubdiv::OsdUtilMeshBatchBase<MyDrawContext> *batch, EffectHandle const &effect) {
|
||||
// does nothing
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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->levelBaseUniform, 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 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);
|
||||
}
|
112
examples/glBatchViewer/delegate.h
Normal file
112
examples/glBatchViewer/delegate.h
Normal file
@ -0,0 +1,112 @@
|
||||
//
|
||||
// Copyright (C) Pixar. All rights reserved.
|
||||
//
|
||||
// This license governs use of the accompanying software. If you
|
||||
// use the software, you accept this license. If you do not accept
|
||||
// the license, do not use the software.
|
||||
//
|
||||
// 1. Definitions
|
||||
// The terms "reproduce," "reproduction," "derivative works," and
|
||||
// "distribution" have the same meaning here as under U.S.
|
||||
// copyright law. A "contribution" is the original software, or
|
||||
// any additions or changes to the software.
|
||||
// A "contributor" is any person or entity that distributes its
|
||||
// contribution under this license.
|
||||
// "Licensed patents" are a contributor's patent claims that read
|
||||
// directly on its contribution.
|
||||
//
|
||||
// 2. Grant of Rights
|
||||
// (A) Copyright Grant- Subject to the terms of this license,
|
||||
// including the license conditions and limitations in section 3,
|
||||
// each contributor grants you a non-exclusive, worldwide,
|
||||
// royalty-free copyright license to reproduce its contribution,
|
||||
// prepare derivative works of its contribution, and distribute
|
||||
// its contribution or any derivative works that you create.
|
||||
// (B) Patent Grant- Subject to the terms of this license,
|
||||
// including the license conditions and limitations in section 3,
|
||||
// each contributor grants you a non-exclusive, worldwide,
|
||||
// royalty-free license under its licensed patents to make, have
|
||||
// made, use, sell, offer for sale, import, and/or otherwise
|
||||
// dispose of its contribution in the software or derivative works
|
||||
// of the contribution in the software.
|
||||
//
|
||||
// 3. Conditions and Limitations
|
||||
// (A) No Trademark License- This license does not grant you
|
||||
// rights to use any contributor's name, logo, or trademarks.
|
||||
// (B) If you bring a patent claim against any contributor over
|
||||
// patents that you claim are infringed by the software, your
|
||||
// patent license from such contributor to the software ends
|
||||
// automatically.
|
||||
// (C) If you distribute any portion of the software, you must
|
||||
// retain all copyright, patent, trademark, and attribution
|
||||
// notices that are present in the software.
|
||||
// (D) If you distribute any portion of the software in source
|
||||
// code form, you may do so only under this license by including a
|
||||
// complete copy of this license with your distribution. If you
|
||||
// distribute any portion of the software in compiled or object
|
||||
// code form, you may only do so under a license that complies
|
||||
// with this license.
|
||||
// (E) The software is licensed "as-is." You bear the risk of
|
||||
// using it. The contributors give no express warranties,
|
||||
// guarantees or conditions. You may have additional consumer
|
||||
// rights under your local laws which this license cannot change.
|
||||
// To the extent permitted under your local laws, the contributors
|
||||
// exclude the implied warranties of merchantability, fitness for
|
||||
// a particular purpose and non-infringement.
|
||||
//
|
||||
#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::FarMesh<OpenSubdiv::OsdVertex> const *farMesh,
|
||||
bool requireFVarData=false);
|
||||
|
||||
static MyDrawContext *Create(OpenSubdiv::FarPatchTables const *patchTables,
|
||||
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 */
|
227
examples/glBatchViewer/effect.cpp
Normal file
227
examples/glBatchViewer/effect.cpp
Normal file
@ -0,0 +1,227 @@
|
||||
//
|
||||
// Copyright (C) Pixar. All rights reserved.
|
||||
//
|
||||
// This license governs use of the accompanying software. If you
|
||||
// use the software, you accept this license. If you do not accept
|
||||
// the license, do not use the software.
|
||||
//
|
||||
// 1. Definitions
|
||||
// The terms "reproduce," "reproduction," "derivative works," and
|
||||
// "distribution" have the same meaning here as under U.S.
|
||||
// copyright law. A "contribution" is the original software, or
|
||||
// any additions or changes to the software.
|
||||
// A "contributor" is any person or entity that distributes its
|
||||
// contribution under this license.
|
||||
// "Licensed patents" are a contributor's patent claims that read
|
||||
// directly on its contribution.
|
||||
//
|
||||
// 2. Grant of Rights
|
||||
// (A) Copyright Grant- Subject to the terms of this license,
|
||||
// including the license conditions and limitations in section 3,
|
||||
// each contributor grants you a non-exclusive, worldwide,
|
||||
// royalty-free copyright license to reproduce its contribution,
|
||||
// prepare derivative works of its contribution, and distribute
|
||||
// its contribution or any derivative works that you create.
|
||||
// (B) Patent Grant- Subject to the terms of this license,
|
||||
// including the license conditions and limitations in section 3,
|
||||
// each contributor grants you a non-exclusive, worldwide,
|
||||
// royalty-free license under its licensed patents to make, have
|
||||
// made, use, sell, offer for sale, import, and/or otherwise
|
||||
// dispose of its contribution in the software or derivative works
|
||||
// of the contribution in the software.
|
||||
//
|
||||
// 3. Conditions and Limitations
|
||||
// (A) No Trademark License- This license does not grant you
|
||||
// rights to use any contributor's name, logo, or trademarks.
|
||||
// (B) If you bring a patent claim against any contributor over
|
||||
// patents that you claim are infringed by the software, your
|
||||
// patent license from such contributor to the software ends
|
||||
// automatically.
|
||||
// (C) If you distribute any portion of the software, you must
|
||||
// retain all copyright, patent, trademark, and attribution
|
||||
// notices that are present in the software.
|
||||
// (D) If you distribute any portion of the software in source
|
||||
// code form, you may do so only under this license by including a
|
||||
// complete copy of this license with your distribution. If you
|
||||
// distribute any portion of the software in compiled or object
|
||||
// code form, you may only do so under a license that complies
|
||||
// with this license.
|
||||
// (E) The software is licensed "as-is." You bear the risk of
|
||||
// using it. The contributors give no express warranties,
|
||||
// guarantees or conditions. You may have additional consumer
|
||||
// rights under your local laws which this license cannot change.
|
||||
// To the extent permitted under your local laws, the contributors
|
||||
// exclude the implied warranties of merchantability, fitness for
|
||||
// a particular purpose and non-infringement.
|
||||
//
|
||||
#if defined(__APPLE__)
|
||||
#include "TargetConditionals.h"
|
||||
#if TARGET_OS_IPHONE or TARGET_IPHONE_SIMULATOR
|
||||
#include <OpenGLES/ES2/gl.h>
|
||||
#else
|
||||
#include <OpenGL/gl3.h>
|
||||
#endif
|
||||
#elif defined(ANDROID)
|
||||
#include <GLES2/gl2.h>
|
||||
#else
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <GL/glew.h>
|
||||
#endif
|
||||
|
||||
#include "effect.h"
|
||||
#include "../common/simple_math.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)
|
||||
int patchType = desc.GetType();
|
||||
int patchPattern = desc.GetPattern();
|
||||
|
||||
GLint program = config->program;
|
||||
GLint diffuseColor = config->diffuseColorUniform;
|
||||
|
||||
if (displayPatchColor) {
|
||||
GLfloat patchColor[11][4] = {
|
||||
{ 1.0f, 1.0f, 1.0f, 1.0f }, // NON_PATCH
|
||||
{ 1.0f, 1.0f, 1.0f, 1.0f }, // POINTS
|
||||
{ 1.0f, 1.0f, 1.0f, 1.0f }, // LINES
|
||||
{ 1.0f, 1.0f, 1.0f, 1.0f }, // QUADS
|
||||
{ 1.0f, 1.0f, 1.0f, 1.0f }, // TRIANGLES
|
||||
{ 1.0f, 1.0f, 1.0f, 1.0f }, // LOOP
|
||||
{ 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
|
||||
};
|
||||
GLfloat regularTransitionColor[6][4] = {
|
||||
{ 1.0f, 1.0f, 1.0f, 1.0f }, // NON_TRANSITION
|
||||
{ 0.0f, 1.0f, 1.0f, 1.0f }, // PATTERN0
|
||||
{ 0.0f, 0.5f, 1.0f, 1.0f }, // PATTERN1
|
||||
{ 0.0f, 0.5f, 0.5f, 1.0f }, // PATTERN2
|
||||
{ 0.5f, 0.0f, 1.0f, 1.0f }, // PATTERN3
|
||||
{ 1.0f, 0.5f, 1.0f, 1.0f }, // PATTERN4
|
||||
};
|
||||
|
||||
if (patchPattern == OpenSubdiv::FarPatchTables::NON_TRANSITION) {
|
||||
glProgramUniform4fv(program, diffuseColor, 1, patchColor[patchType]);
|
||||
} else {
|
||||
if (patchType == OpenSubdiv::FarPatchTables::REGULAR) {
|
||||
glProgramUniform4fv(program, diffuseColor, 1, regularTransitionColor[patchPattern]);
|
||||
} else if (patchType == OpenSubdiv::FarPatchTables::BOUNDARY) {
|
||||
glProgramUniform4f(program, diffuseColor, 0, 0, 0.5f, 1);
|
||||
} else if (patchType == OpenSubdiv::FarPatchTables::CORNER) {
|
||||
glProgramUniform4f(program, diffuseColor, 0, 0, 0.5f, 1);
|
||||
} else {
|
||||
glProgramUniform4f(program, diffuseColor, 0.4f, 0.4f, 0.8f, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
142
examples/glBatchViewer/effect.h
Normal file
142
examples/glBatchViewer/effect.h
Normal file
@ -0,0 +1,142 @@
|
||||
//
|
||||
// Copyright (C) Pixar. All rights reserved.
|
||||
//
|
||||
// This license governs use of the accompanying software. If you
|
||||
// use the software, you accept this license. If you do not accept
|
||||
// the license, do not use the software.
|
||||
//
|
||||
// 1. Definitions
|
||||
// The terms "reproduce," "reproduction," "derivative works," and
|
||||
// "distribution" have the same meaning here as under U.S.
|
||||
// copyright law. A "contribution" is the original software, or
|
||||
// any additions or changes to the software.
|
||||
// A "contributor" is any person or entity that distributes its
|
||||
// contribution under this license.
|
||||
// "Licensed patents" are a contributor's patent claims that read
|
||||
// directly on its contribution.
|
||||
//
|
||||
// 2. Grant of Rights
|
||||
// (A) Copyright Grant- Subject to the terms of this license,
|
||||
// including the license conditions and limitations in section 3,
|
||||
// each contributor grants you a non-exclusive, worldwide,
|
||||
// royalty-free copyright license to reproduce its contribution,
|
||||
// prepare derivative works of its contribution, and distribute
|
||||
// its contribution or any derivative works that you create.
|
||||
// (B) Patent Grant- Subject to the terms of this license,
|
||||
// including the license conditions and limitations in section 3,
|
||||
// each contributor grants you a non-exclusive, worldwide,
|
||||
// royalty-free license under its licensed patents to make, have
|
||||
// made, use, sell, offer for sale, import, and/or otherwise
|
||||
// dispose of its contribution in the software or derivative works
|
||||
// of the contribution in the software.
|
||||
//
|
||||
// 3. Conditions and Limitations
|
||||
// (A) No Trademark License- This license does not grant you
|
||||
// rights to use any contributor's name, logo, or trademarks.
|
||||
// (B) If you bring a patent claim against any contributor over
|
||||
// patents that you claim are infringed by the software, your
|
||||
// patent license from such contributor to the software ends
|
||||
// automatically.
|
||||
// (C) If you distribute any portion of the software, you must
|
||||
// retain all copyright, patent, trademark, and attribution
|
||||
// notices that are present in the software.
|
||||
// (D) If you distribute any portion of the software in source
|
||||
// code form, you may do so only under this license by including a
|
||||
// complete copy of this license with your distribution. If you
|
||||
// distribute any portion of the software in compiled or object
|
||||
// code form, you may only do so under a license that complies
|
||||
// with this license.
|
||||
// (E) The software is licensed "as-is." You bear the risk of
|
||||
// using it. The contributors give no express warranties,
|
||||
// guarantees or conditions. You may have additional consumer
|
||||
// rights under your local laws which this license cannot change.
|
||||
// To the extent permitted under your local laws, the contributors
|
||||
// exclude the implied warranties of merchantability, fitness for
|
||||
// a particular purpose and non-infringement.
|
||||
//
|
||||
#ifndef EFFECT_H
|
||||
#define EFFECT_H
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include "TargetConditionals.h"
|
||||
#if TARGET_OS_IPHONE or TARGET_IPHONE_SIMULATOR
|
||||
#include <OpenGLES/ES2/gl.h>
|
||||
#else
|
||||
#include <OpenGL/gl3.h>
|
||||
#endif
|
||||
#elif defined(ANDROID)
|
||||
#include <GLES2/gl2.h>
|
||||
#else
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
#include <osd/glDrawRegistry.h>
|
||||
|
||||
union EffectDesc {
|
||||
public:
|
||||
struct {
|
||||
unsigned int wire:2;
|
||||
unsigned int screenSpaceTess:1;
|
||||
};
|
||||
int value;
|
||||
|
||||
bool operator < (const EffectDesc &e) const {
|
||||
return value < e.value;
|
||||
}
|
||||
|
||||
int GetWire() const { return wire; }
|
||||
bool GetScreenSpaceTess() const { return screenSpaceTess; }
|
||||
};
|
||||
|
||||
struct MyDrawConfig : public OpenSubdiv::OsdGLDrawConfig {
|
||||
|
||||
MyDrawConfig() :
|
||||
diffuseColorUniform(-1) {}
|
||||
virtual ~MyDrawConfig() {}
|
||||
|
||||
GLint diffuseColorUniform;
|
||||
};
|
||||
|
||||
class MyEffect { // formerly EffectHandle
|
||||
public:
|
||||
MyEffect() : displayPatchColor(false), screenSpaceTess(false), wire(0) {}
|
||||
|
||||
EffectDesc GetEffectDescriptor() const {
|
||||
EffectDesc desc;
|
||||
|
||||
desc.value = 0;
|
||||
desc.wire = wire;
|
||||
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
|
||||
(wire == other.wire);
|
||||
}
|
||||
bool operator != (const MyEffect &other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
enum {
|
||||
kWire, kFill, kLine
|
||||
};
|
||||
|
||||
bool displayPatchColor; // runtime switchable
|
||||
bool screenSpaceTess; // need recompile (should be considered in effect descriptor)
|
||||
int wire; // need recompile
|
||||
};
|
||||
|
||||
|
||||
#endif /* EFFECT_H */
|
193
examples/glBatchViewer/effectRegistry.cpp
Normal file
193
examples/glBatchViewer/effectRegistry.cpp
Normal file
@ -0,0 +1,193 @@
|
||||
//
|
||||
// Copyright (C) Pixar. All rights reserved.
|
||||
//
|
||||
// This license governs use of the accompanying software. If you
|
||||
// use the software, you accept this license. If you do not accept
|
||||
// the license, do not use the software.
|
||||
//
|
||||
// 1. Definitions
|
||||
// The terms "reproduce," "reproduction," "derivative works," and
|
||||
// "distribution" have the same meaning here as under U.S.
|
||||
// copyright law. A "contribution" is the original software, or
|
||||
// any additions or changes to the software.
|
||||
// A "contributor" is any person or entity that distributes its
|
||||
// contribution under this license.
|
||||
// "Licensed patents" are a contributor's patent claims that read
|
||||
// directly on its contribution.
|
||||
//
|
||||
// 2. Grant of Rights
|
||||
// (A) Copyright Grant- Subject to the terms of this license,
|
||||
// including the license conditions and limitations in section 3,
|
||||
// each contributor grants you a non-exclusive, worldwide,
|
||||
// royalty-free copyright license to reproduce its contribution,
|
||||
// prepare derivative works of its contribution, and distribute
|
||||
// its contribution or any derivative works that you create.
|
||||
// (B) Patent Grant- Subject to the terms of this license,
|
||||
// including the license conditions and limitations in section 3,
|
||||
// each contributor grants you a non-exclusive, worldwide,
|
||||
// royalty-free license under its licensed patents to make, have
|
||||
// made, use, sell, offer for sale, import, and/or otherwise
|
||||
// dispose of its contribution in the software or derivative works
|
||||
// of the contribution in the software.
|
||||
//
|
||||
// 3. Conditions and Limitations
|
||||
// (A) No Trademark License- This license does not grant you
|
||||
// rights to use any contributor's name, logo, or trademarks.
|
||||
// (B) If you bring a patent claim against any contributor over
|
||||
// patents that you claim are infringed by the software, your
|
||||
// patent license from such contributor to the software ends
|
||||
// automatically.
|
||||
// (C) If you distribute any portion of the software, you must
|
||||
// retain all copyright, patent, trademark, and attribution
|
||||
// notices that are present in the software.
|
||||
// (D) If you distribute any portion of the software in source
|
||||
// code form, you may do so only under this license by including a
|
||||
// complete copy of this license with your distribution. If you
|
||||
// distribute any portion of the software in compiled or object
|
||||
// code form, you may only do so under a license that complies
|
||||
// with this license.
|
||||
// (E) The software is licensed "as-is." You bear the risk of
|
||||
// using it. The contributors give no express warranties,
|
||||
// guarantees or conditions. You may have additional consumer
|
||||
// rights under your local laws which this license cannot change.
|
||||
// To the extent permitted under your local laws, the contributors
|
||||
// exclude the implied warranties of merchantability, fitness for
|
||||
// a particular purpose and non-infringement.
|
||||
//
|
||||
#if defined(__APPLE__)
|
||||
#include "TargetConditionals.h"
|
||||
#if TARGET_OS_IPHONE or TARGET_IPHONE_SIMULATOR
|
||||
#include <OpenGLES/ES2/gl.h>
|
||||
#else
|
||||
#include <OpenGL/gl3.h>
|
||||
#endif
|
||||
#elif defined(ANDROID)
|
||||
#include <GLES2/gl2.h>
|
||||
#else
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <GL/glew.h>
|
||||
#endif
|
||||
|
||||
#include "effectRegistry.h"
|
||||
|
||||
static const char *shaderSource =
|
||||
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
|
||||
#include "shader.inc"
|
||||
#else
|
||||
#include "shader_gl3.inc"
|
||||
#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) {
|
||||
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) {
|
||||
sconfig->geometryShader.AddDefine("PRIM_QUAD");
|
||||
sconfig->fragmentShader.AddDefine("PRIM_QUAD");
|
||||
} else {
|
||||
sconfig->geometryShader.AddDefine("PRIM_TRI");
|
||||
sconfig->fragmentShader.AddDefine("PRIM_TRI");
|
||||
}
|
||||
|
||||
int wire = effectDesc.GetWire();
|
||||
|
||||
if (wire == MyEffect::kWire) {
|
||||
sconfig->geometryShader.AddDefine("GEOMETRY_OUT_WIRE");
|
||||
sconfig->fragmentShader.AddDefine("GEOMETRY_OUT_WIRE");
|
||||
} else if (wire == MyEffect::kFill) {
|
||||
sconfig->geometryShader.AddDefine("GEOMETRY_OUT_FILL");
|
||||
sconfig->fragmentShader.AddDefine("GEOMETRY_OUT_FILL");
|
||||
} else if (wire == MyEffect::kLine) {
|
||||
sconfig->geometryShader.AddDefine("GEOMETRY_OUT_LINE");
|
||||
sconfig->fragmentShader.AddDefine("GEOMETRY_OUT_LINE");
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// g_gregoryQuadOffsetBaseMap[program] = glGetUniformLocation(program, "GregoryQuadOffsetBase");
|
||||
// g_levelBaseMap[program] = glGetUniformLocation(program, "LevelBase");
|
||||
|
||||
// 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, "g_VertexBuffer")) != -1) {
|
||||
glProgramUniform1i(program, loc, 0); // GL_TEXTURE0
|
||||
}
|
||||
if ((loc = glGetUniformLocation(program, "g_ValenceBuffer")) != -1) {
|
||||
glProgramUniform1i(program, loc, 1); // GL_TEXTURE1
|
||||
}
|
||||
if ((loc = glGetUniformLocation(program, "g_QuadOffsetBuffer")) != -1) {
|
||||
glProgramUniform1i(program, loc, 2); // GL_TEXTURE2
|
||||
}
|
||||
if ((loc = glGetUniformLocation(program, "g_ptexIndicesBuffer")) != -1) {
|
||||
glProgramUniform1i(program, loc, 3); // GL_TEXTURE3
|
||||
}
|
||||
#endif
|
||||
|
||||
config->diffuseColorUniform = glGetUniformLocation(program, "diffuseColor");
|
||||
|
||||
return config;
|
||||
}
|
@ -54,58 +54,26 @@
|
||||
// exclude the implied warranties of merchantability, fitness for
|
||||
// a particular purpose and non-infringement.
|
||||
//
|
||||
#ifndef EFFECT_REGISTRY_H
|
||||
#define EFFECT_REGISTRY_H
|
||||
|
||||
#ifndef OSD_SORTED_DRAW_CONTEXT_H
|
||||
#define OSD_SORTED_DRAW_CONTEXT_H
|
||||
#include <osd/glDrawRegistry.h>
|
||||
#include "effect.h"
|
||||
|
||||
#include "../version.h"
|
||||
#include "../far/patchTables.h"
|
||||
#include "../osd/patch.h"
|
||||
typedef std::pair<OpenSubdiv::OsdDrawContext::PatchDescriptor, EffectDesc> FullEffectDesc; // name!
|
||||
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <map>
|
||||
class MyEffectRegistry : public OpenSubdiv::OsdGLDrawRegistry<FullEffectDesc, MyDrawConfig> {
|
||||
typedef OpenSubdiv::OsdGLDrawRegistry<FullEffectDesc, MyDrawConfig> BaseClass;
|
||||
|
||||
namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
protected:
|
||||
virtual ConfigType *_CreateDrawConfig(DescType const & desc, SourceConfigType const * sconfig);
|
||||
virtual SourceConfigType *_CreateDrawSourceConfig(DescType const & desc);
|
||||
|
||||
struct OsdPatchDrawRange {
|
||||
OsdPatchDrawRange(int first, int count) :
|
||||
firstIndex(first), numIndices(count) {}
|
||||
int firstIndex;
|
||||
int numIndices;
|
||||
};
|
||||
|
||||
typedef std::vector<OsdPatchDrawRange> OsdPatchDrawRangeVector;
|
||||
|
||||
class OsdSortedDrawContext {
|
||||
public:
|
||||
// multi-prim draw methods
|
||||
enum Fidelity { // XXX: better name?
|
||||
kInvisible,
|
||||
kLow,
|
||||
kHigh
|
||||
};
|
||||
|
||||
OsdSortedDrawContext(FarPatchCountVector const &patchCounts, OsdPatchArrayVector const &patchArrays);
|
||||
|
||||
void SetPrimFidelity(int primIndex, Fidelity f); // XXX: better name?
|
||||
|
||||
OsdPatchDrawRangeVector const & GetPatchDrawRanges(OsdPatchDescriptor desc);
|
||||
|
||||
private:
|
||||
void _ComputePatchDrawRanges();
|
||||
|
||||
FarPatchCountVector _patchCounts;
|
||||
OsdPatchArrayVector _patchArrays;
|
||||
std::map<OsdPatchDescriptor, OsdPatchDrawRangeVector> _patchDrawRanges;
|
||||
std::vector<unsigned char> _primFidelity;
|
||||
bool _patchDrawRangesDirty;
|
||||
ConfigType * GetDrawConfig(EffectDesc effectDesc, OpenSubdiv::OsdDrawContext::PatchDescriptor desc) {
|
||||
return BaseClass::GetDrawConfig(FullEffectDesc(desc, effectDesc));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
using namespace OPENSUBDIV_VERSION;
|
||||
|
||||
} // end namespace OpenSubdiv
|
||||
|
||||
#endif /* OSD_SORTED_DRAW_CONTEXT_H */
|
||||
#endif /* EFFECT_REGISTRY_H */
|
195
examples/glBatchViewer/shapes.h
Normal file
195
examples/glBatchViewer/shapes.h
Normal file
@ -0,0 +1,195 @@
|
||||
//
|
||||
// Copyright (C) Pixar. All rights reserved.
|
||||
//
|
||||
// This license governs use of the accompanying software. If you
|
||||
// use the software, you accept this license. If you do not accept
|
||||
// the license, do not use the software.
|
||||
//
|
||||
// 1. Definitions
|
||||
// The terms "reproduce," "reproduction," "derivative works," and
|
||||
// "distribution" have the same meaning here as under U.S.
|
||||
// copyright law. A "contribution" is the original software, or
|
||||
// any additions or changes to the software.
|
||||
// A "contributor" is any person or entity that distributes its
|
||||
// contribution under this license.
|
||||
// "Licensed patents" are a contributor's patent claims that read
|
||||
// directly on its contribution.
|
||||
//
|
||||
// 2. Grant of Rights
|
||||
// (A) Copyright Grant- Subject to the terms of this license,
|
||||
// including the license conditions and limitations in section 3,
|
||||
// each contributor grants you a non-exclusive, worldwide,
|
||||
// royalty-free copyright license to reproduce its contribution,
|
||||
// prepare derivative works of its contribution, and distribute
|
||||
// its contribution or any derivative works that you create.
|
||||
// (B) Patent Grant- Subject to the terms of this license,
|
||||
// including the license conditions and limitations in section 3,
|
||||
// each contributor grants you a non-exclusive, worldwide,
|
||||
// royalty-free license under its licensed patents to make, have
|
||||
// made, use, sell, offer for sale, import, and/or otherwise
|
||||
// dispose of its contribution in the software or derivative works
|
||||
// of the contribution in the software.
|
||||
//
|
||||
// 3. Conditions and Limitations
|
||||
// (A) No Trademark License- This license does not grant you
|
||||
// rights to use any contributor's name, logo, or trademarks.
|
||||
// (B) If you bring a patent claim against any contributor over
|
||||
// patents that you claim are infringed by the software, your
|
||||
// patent license from such contributor to the software ends
|
||||
// automatically.
|
||||
// (C) If you distribute any portion of the software, you must
|
||||
// retain all copyright, patent, trademark, and attribution
|
||||
// notices that are present in the software.
|
||||
// (D) If you distribute any portion of the software in source
|
||||
// code form, you may do so only under this license by including a
|
||||
// complete copy of this license with your distribution. If you
|
||||
// distribute any portion of the software in compiled or object
|
||||
// code form, you may only do so under a license that complies
|
||||
// with this license.
|
||||
// (E) The software is licensed "as-is." You bear the risk of
|
||||
// using it. The contributors give no express warranties,
|
||||
// guarantees or conditions. You may have additional consumer
|
||||
// rights under your local laws which this license cannot change.
|
||||
// To the extent permitted under your local laws, the contributors
|
||||
// exclude the implied warranties of merchantability, fitness for
|
||||
// a particular purpose and non-infringement.
|
||||
//
|
||||
|
||||
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
@ -906,7 +906,7 @@ enum Effect {
|
||||
kPoint = 6,
|
||||
};
|
||||
|
||||
typedef std::pair<OpenSubdiv::OsdPatchDescriptor,Effect> EffectDesc;
|
||||
typedef std::pair<OpenSubdiv::OsdDrawContext::PatchDescriptor, Effect> EffectDesc;
|
||||
|
||||
class EffectDrawRegistry : public OpenSubdiv::OsdGLDrawRegistry<EffectDesc> {
|
||||
|
||||
@ -935,17 +935,16 @@ EffectDrawRegistry::_CreateDrawSourceConfig(DescType const & desc)
|
||||
const char *glslVersion = "#version 330\n";
|
||||
#endif
|
||||
|
||||
if (desc.first.type != OpenSubdiv::kNonPatch) {
|
||||
|
||||
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 {
|
||||
if (effect == kQuadWire) effect = kTriWire;
|
||||
if (effect == kQuadFill) effect = kTriFill;
|
||||
if (effect == kQuadLine) effect = kTriLine;
|
||||
sconfig->geometryShader.AddDefine("SMOOTH_NORMALS");
|
||||
|
||||
} else {
|
||||
sconfig->vertexShader.source = shaderSource;
|
||||
sconfig->vertexShader.version = glslVersion;
|
||||
sconfig->vertexShader.AddDefine("VERTEX_SHADER");
|
||||
}
|
||||
assert(sconfig);
|
||||
|
||||
@ -1041,7 +1040,7 @@ EffectDrawRegistry::_CreateDrawConfig(
|
||||
if ((loc = glGetUniformLocation(config->program, "g_QuadOffsetBuffer")) != -1) {
|
||||
glUniform1i(loc, 2); // GL_TEXTURE2
|
||||
}
|
||||
if ((loc = glGetUniformLocation(config->program, "g_patchLevelBuffer")) != -1) {
|
||||
if ((loc = glGetUniformLocation(config->program, "g_ptexIndicesBuffer")) != -1) {
|
||||
glUniform1i(loc, 3); // GL_TEXTURE3
|
||||
}
|
||||
#else
|
||||
@ -1054,7 +1053,7 @@ EffectDrawRegistry::_CreateDrawConfig(
|
||||
if ((loc = glGetUniformLocation(config->program, "g_QuadOffsetBuffer")) != -1) {
|
||||
glProgramUniform1i(config->program, loc, 2); // GL_TEXTURE2
|
||||
}
|
||||
if ((loc = glGetUniformLocation(config->program, "g_patchLevelBuffer")) != -1) {
|
||||
if ((loc = glGetUniformLocation(config->program, "g_ptexIndicesBuffer")) != -1) {
|
||||
glProgramUniform1i(config->program, loc, 3); // GL_TEXTURE3
|
||||
}
|
||||
#endif
|
||||
@ -1076,9 +1075,9 @@ GetEffect()
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static GLuint
|
||||
bindProgram(Effect effect, OpenSubdiv::OsdPatchArray const & patch)
|
||||
bindProgram(Effect effect, OpenSubdiv::OsdDrawContext::PatchArray const & patch)
|
||||
{
|
||||
EffectDesc effectDesc(patch.desc, effect);
|
||||
EffectDesc effectDesc(patch.GetDescriptor(), effect);
|
||||
EffectDrawRegistry::ConfigType *
|
||||
config = effectRegistry.GetDrawConfig(effectDesc);
|
||||
|
||||
@ -1166,10 +1165,10 @@ bindProgram(Effect effect, OpenSubdiv::OsdPatchArray const & patch)
|
||||
glBindTexture(GL_TEXTURE_BUFFER,
|
||||
g_mesh->GetDrawContext()->quadOffsetTextureBuffer);
|
||||
}
|
||||
if (g_mesh->GetDrawContext()->patchLevelTextureBuffer) {
|
||||
if (g_mesh->GetDrawContext()->ptexCoordinateTextureBuffer) {
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_BUFFER,
|
||||
g_mesh->GetDrawContext()->patchLevelTextureBuffer);
|
||||
g_mesh->GetDrawContext()->ptexCoordinateTextureBuffer);
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
@ -1207,64 +1206,61 @@ display() {
|
||||
|
||||
glBindVertexArray(g_vao);
|
||||
|
||||
OpenSubdiv::OsdPatchArrayVector const & patches = g_mesh->GetDrawContext()->patchArrays;
|
||||
OpenSubdiv::OsdDrawContext::PatchArrayVector const & patches = g_mesh->GetDrawContext()->patchArrays;
|
||||
|
||||
// cv drawing
|
||||
/*
|
||||
if (g_drawPatchCVs) {
|
||||
glPointSize(3.0);
|
||||
|
||||
bindProgram(kPoint, OpenSubdiv::OsdPatchArray());
|
||||
bindProgram(kPoint, OpenSubdiv::FarPatchTables::PatchArray());
|
||||
|
||||
for (int i=0; i<(int)patches.size(); ++i) {
|
||||
OpenSubdiv::OsdPatchArray const & patch = patches[i];
|
||||
OpenSubdiv::FarPatchTables::PatchArray const & patch = patches[i];
|
||||
|
||||
glDrawElements(GL_POINTS,
|
||||
patch.numIndices, GL_UNSIGNED_INT,
|
||||
(void *)(patch.firstIndex * sizeof(unsigned int)));
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// patch drawing
|
||||
int patchTypeCount[9]; // enum OsdPatchType (osd/drawCountext.h)
|
||||
int transitionPatchTypeCount[3][5][4];
|
||||
memset(patchTypeCount, 0, sizeof(patchTypeCount));
|
||||
memset(transitionPatchTypeCount, 0, sizeof(transitionPatchTypeCount));
|
||||
int patchCount[11][6][4]; // [Type][Pattern][Rotation] (see far/patchTables.h)
|
||||
memset(patchCount, 0, sizeof(patchCount));
|
||||
|
||||
// primitive counting
|
||||
glBeginQuery(GL_PRIMITIVES_GENERATED, g_primQuery);
|
||||
|
||||
for (int i=0; i<(int)patches.size(); ++i) {
|
||||
OpenSubdiv::OsdPatchArray const & patch = patches[i];
|
||||
OpenSubdiv::OsdDrawContext::PatchArray const & patch = patches[i];
|
||||
|
||||
OpenSubdiv::OsdPatchType patchType = patch.desc.type;
|
||||
int patchPattern = patch.desc.pattern;
|
||||
int patchRotation = patch.desc.rotation;
|
||||
OpenSubdiv::OsdDrawContext::PatchDescriptor desc = patch.GetDescriptor();
|
||||
OpenSubdiv::FarPatchTables::Type patchType = desc.GetType();
|
||||
int patchPattern = desc.GetPattern();
|
||||
int patchRotation = desc.GetRotation();
|
||||
int subPatch = desc.GetSubPatch();
|
||||
|
||||
if (patch.desc.subpatch == 0) {
|
||||
if (patchType == OpenSubdiv::kTransitionRegular)
|
||||
transitionPatchTypeCount[0][patchPattern][patchRotation] += patch.numIndices / patch.desc.GetPatchSize();
|
||||
else if (patchType == OpenSubdiv::kTransitionBoundary)
|
||||
transitionPatchTypeCount[1][patchPattern][patchRotation] += patch.numIndices / patch.desc.GetPatchSize();
|
||||
else if (patchType == OpenSubdiv::kTransitionBoundary)
|
||||
transitionPatchTypeCount[2][patchPattern][patchRotation] += patch.numIndices / patch.desc.GetPatchSize();
|
||||
else
|
||||
patchTypeCount[patchType] += patch.numIndices / patch.desc.GetPatchSize();
|
||||
if (subPatch == 0) {
|
||||
patchCount[patchType][patchPattern][patchRotation] += patch.GetNumPatches();
|
||||
}
|
||||
|
||||
GLenum primType;
|
||||
|
||||
if (g_mesh->GetDrawContext()->IsAdaptive()) {
|
||||
switch(patchType) {
|
||||
case OpenSubdiv::FarPatchTables::QUADS:
|
||||
primType = GL_LINES_ADJACENCY;
|
||||
break;
|
||||
case OpenSubdiv::FarPatchTables::TRIANGLES:
|
||||
primType = GL_TRIANGLES;
|
||||
break;
|
||||
default:
|
||||
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
|
||||
primType = GL_PATCHES;
|
||||
glPatchParameteri(GL_PATCH_VERTICES, patch.desc.GetPatchSize());
|
||||
glPatchParameteri(GL_PATCH_VERTICES, desc.GetNumControlVertices());
|
||||
#else
|
||||
primType = GL_POINTS;
|
||||
#endif
|
||||
|
||||
} else {
|
||||
if (g_scheme == kLoop) {
|
||||
primType = GL_TRIANGLES;
|
||||
} else {
|
||||
primType = GL_LINES_ADJACENCY; // GL_QUADS is deprecated
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
|
||||
@ -1272,24 +1268,29 @@ display() {
|
||||
|
||||
GLuint diffuseColor = glGetUniformLocation(program, "diffuseColor");
|
||||
if (g_displayPatchColor) {
|
||||
switch(patchType) {
|
||||
case OpenSubdiv::kRegular:
|
||||
if (patchPattern == OpenSubdiv::FarPatchTables::NON_TRANSITION) {
|
||||
switch(patchType) {
|
||||
case OpenSubdiv::FarPatchTables::REGULAR:
|
||||
glProgramUniform4f(program, diffuseColor, 1.0f, 1.0f, 1.0f, 1);
|
||||
break;
|
||||
case OpenSubdiv::kBoundary:
|
||||
case OpenSubdiv::FarPatchTables::BOUNDARY:
|
||||
glProgramUniform4f(program, diffuseColor, 0.8f, 0.0f, 0.0f, 1);
|
||||
break;
|
||||
case OpenSubdiv::kCorner:
|
||||
case OpenSubdiv::FarPatchTables::CORNER:
|
||||
glProgramUniform4f(program, diffuseColor, 0, 1.0, 0, 1);
|
||||
break;
|
||||
case OpenSubdiv::kGregory:
|
||||
case OpenSubdiv::FarPatchTables::GREGORY:
|
||||
glProgramUniform4f(program, diffuseColor, 1.0f, 1.0f, 0.0f, 1);
|
||||
break;
|
||||
case OpenSubdiv::kBoundaryGregory:
|
||||
case OpenSubdiv::FarPatchTables::GREGORY_BOUNDARY:
|
||||
glProgramUniform4f(program, diffuseColor, 1.0f, 0.5f, 0.0f, 1);
|
||||
break;
|
||||
case OpenSubdiv::kTransitionRegular:
|
||||
switch (patchPattern) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else { // patchPattern != NON_TRANSITION
|
||||
if (patchType == OpenSubdiv::FarPatchTables::REGULAR) {
|
||||
switch (patchPattern-1) {
|
||||
case 0:
|
||||
glProgramUniform4f(program, diffuseColor, 0, 1.0f, 1.0f, 1);
|
||||
break;
|
||||
@ -1306,25 +1307,22 @@ display() {
|
||||
glProgramUniform4f(program, diffuseColor, 1.0f, 0.5f, 1.0f, 1);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case OpenSubdiv::kTransitionBoundary: {
|
||||
float p = patchPattern * 0.2f;
|
||||
glProgramUniform4f(program, diffuseColor, 0.0f, p, 0.75f, 1);
|
||||
} break;
|
||||
case OpenSubdiv::kTransitionCorner:
|
||||
} else if (patchType == OpenSubdiv::FarPatchTables::BOUNDARY) {
|
||||
float p = (patchPattern-1) * 0.2f;
|
||||
glProgramUniform4f(program, diffuseColor, 0.0f, p, 0.75f, 1);
|
||||
} else if (patchType == OpenSubdiv::FarPatchTables::CORNER) {
|
||||
glProgramUniform4f(program, diffuseColor, 0.25f, 0.25f, 0.25f, 1);
|
||||
break;
|
||||
default:
|
||||
} else {
|
||||
glProgramUniform4f(program, diffuseColor, 0.4f, 0.4f, 0.8f, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
glProgramUniform4f(program, diffuseColor, 0.4f, 0.4f, 0.8f, 1);
|
||||
}
|
||||
GLuint uniformGregoryQuadOffset = glGetUniformLocation(program, "GregoryQuadOffsetBase");
|
||||
GLuint uniformLevelBase = glGetUniformLocation(program, "LevelBase");
|
||||
glProgramUniform1i(program, uniformGregoryQuadOffset, patch.gregoryQuadOffsetBase);
|
||||
glProgramUniform1i(program, uniformLevelBase, patch.levelBase);
|
||||
glProgramUniform1i(program, uniformGregoryQuadOffset, patch.GetQuadOffsetIndex());
|
||||
glProgramUniform1i(program, uniformLevelBase, patch.GetPatchIndex());
|
||||
#else
|
||||
bindProgram(GetEffect(), patch);
|
||||
#endif
|
||||
@ -1332,9 +1330,9 @@ display() {
|
||||
if (g_wire == 0) {
|
||||
glDisable(GL_CULL_FACE);
|
||||
}
|
||||
glDrawElements(primType,
|
||||
patch.numIndices, GL_UNSIGNED_INT,
|
||||
(void *)(patch.firstIndex * sizeof(unsigned int)));
|
||||
|
||||
glDrawElements(primType, patch.GetNumIndices(), GL_UNSIGNED_INT,
|
||||
(void *)(patch.GetVertIndex() * sizeof(unsigned int)));
|
||||
if (g_wire == 0) {
|
||||
glEnable(GL_CULL_FACE);
|
||||
}
|
||||
@ -1372,35 +1370,35 @@ display() {
|
||||
|
||||
int x = -280;
|
||||
g_hud.DrawString(x, -360, "NonPatch : %d",
|
||||
patchTypeCount[OpenSubdiv::kNonPatch]);
|
||||
patchCount[OpenSubdiv::FarPatchTables::QUADS][0][0]);
|
||||
g_hud.DrawString(x, -340, "Regular : %d",
|
||||
patchTypeCount[OpenSubdiv::kRegular]);
|
||||
patchCount[OpenSubdiv::FarPatchTables::REGULAR][0][0]);
|
||||
g_hud.DrawString(x, -320, "Boundary : %d",
|
||||
patchTypeCount[OpenSubdiv::kBoundary]);
|
||||
patchCount[OpenSubdiv::FarPatchTables::BOUNDARY][0][0]);
|
||||
g_hud.DrawString(x, -300, "Corner : %d",
|
||||
patchTypeCount[OpenSubdiv::kCorner]);
|
||||
patchCount[OpenSubdiv::FarPatchTables::CORNER][0][0]);
|
||||
g_hud.DrawString(x, -280, "Gregory : %d",
|
||||
patchTypeCount[OpenSubdiv::kGregory]);
|
||||
patchCount[OpenSubdiv::FarPatchTables::GREGORY][0][0]);
|
||||
g_hud.DrawString(x, -260, "Boundary Gregory : %d",
|
||||
patchTypeCount[OpenSubdiv::kBoundaryGregory]);
|
||||
patchCount[OpenSubdiv::FarPatchTables::GREGORY_BOUNDARY][0][0]);
|
||||
g_hud.DrawString(x, -240, "Trans. Regular : %d %d %d %d %d",
|
||||
transitionPatchTypeCount[0][0][0],
|
||||
transitionPatchTypeCount[0][1][0],
|
||||
transitionPatchTypeCount[0][2][0],
|
||||
transitionPatchTypeCount[0][3][0],
|
||||
transitionPatchTypeCount[0][4][0]);
|
||||
patchCount[OpenSubdiv::FarPatchTables::REGULAR][OpenSubdiv::FarPatchTables::PATTERN0][0],
|
||||
patchCount[OpenSubdiv::FarPatchTables::REGULAR][OpenSubdiv::FarPatchTables::PATTERN1][0],
|
||||
patchCount[OpenSubdiv::FarPatchTables::REGULAR][OpenSubdiv::FarPatchTables::PATTERN2][0],
|
||||
patchCount[OpenSubdiv::FarPatchTables::REGULAR][OpenSubdiv::FarPatchTables::PATTERN3][0],
|
||||
patchCount[OpenSubdiv::FarPatchTables::REGULAR][OpenSubdiv::FarPatchTables::PATTERN4][0]);
|
||||
for (int i=0; i < 5; i++)
|
||||
g_hud.DrawString(x, -220+i*20, "Trans. Boundary%d : %d %d %d %d", i,
|
||||
transitionPatchTypeCount[1][i][0],
|
||||
transitionPatchTypeCount[1][i][1],
|
||||
transitionPatchTypeCount[1][i][2],
|
||||
transitionPatchTypeCount[1][i][3]);
|
||||
patchCount[OpenSubdiv::FarPatchTables::BOUNDARY][i+1][0],
|
||||
patchCount[OpenSubdiv::FarPatchTables::BOUNDARY][i+1][1],
|
||||
patchCount[OpenSubdiv::FarPatchTables::BOUNDARY][i+1][2],
|
||||
patchCount[OpenSubdiv::FarPatchTables::BOUNDARY][i+1][3]);
|
||||
for (int i=0; i < 5; i++)
|
||||
g_hud.DrawString(x, -100+i*20, "Trans. Corner%d : %d %d %d %d", i,
|
||||
transitionPatchTypeCount[2][i][0],
|
||||
transitionPatchTypeCount[2][i][1],
|
||||
transitionPatchTypeCount[2][i][2],
|
||||
transitionPatchTypeCount[2][i][3]);
|
||||
patchCount[OpenSubdiv::FarPatchTables::CORNER][i+1][0],
|
||||
patchCount[OpenSubdiv::FarPatchTables::CORNER][i+1][1],
|
||||
patchCount[OpenSubdiv::FarPatchTables::CORNER][i+1][2],
|
||||
patchCount[OpenSubdiv::FarPatchTables::CORNER][i+1][3]);
|
||||
|
||||
g_hud.DrawString(10, -180, "Tess level : %d", g_tessLevel);
|
||||
g_hud.DrawString(10, -160, "Primitives : %d", numPrimsGenerated);
|
||||
|
@ -469,7 +469,7 @@ createOsdMesh( const std::string &shape, int level, Scheme scheme=kCatmark ) {
|
||||
OsdFarMeshFactory factory( hmesh, level, /*adaptive*/ true);
|
||||
|
||||
delete g_fmesh;
|
||||
g_fmesh = factory.Create( /*ptex*/ true, /*fvar*/ false);
|
||||
g_fmesh = factory.Create(/*fvar*/ false);
|
||||
|
||||
int nverts = g_fmesh->GetNumVertices();
|
||||
|
||||
|
@ -495,7 +495,7 @@ union Effect {
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::pair<OpenSubdiv::OsdPatchDescriptor,Effect> EffectDesc;
|
||||
typedef std::pair<OpenSubdiv::OsdDrawContext::PatchDescriptor,Effect> EffectDesc;
|
||||
|
||||
class EffectDrawRegistry : public OpenSubdiv::OsdGLDrawRegistry<EffectDesc> {
|
||||
|
||||
@ -602,11 +602,8 @@ EffectDrawRegistry::_CreateDrawConfig(
|
||||
if ((loc = glGetUniformLocation(config->program, "g_QuadOffsetBuffer")) != -1) {
|
||||
glProgramUniform1i(config->program, loc, 2); // GL_TEXTURE2
|
||||
}
|
||||
if ((loc = glGetUniformLocation(config->program, "g_patchLevelBuffer")) != -1) {
|
||||
glProgramUniform1i(config->program, loc, 3); // GL_TEXTURE3
|
||||
}
|
||||
if ((loc = glGetUniformLocation(config->program, "g_ptexIndicesBuffer")) != -1) {
|
||||
glProgramUniform1i(config->program, loc, 4); // GL_TEXTURE4
|
||||
glProgramUniform1i(config->program, loc, 3); // GL_TEXTURE3
|
||||
}
|
||||
|
||||
return config;
|
||||
@ -616,9 +613,9 @@ EffectDrawRegistry effectRegistry;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static GLuint
|
||||
bindProgram(Effect effect, OpenSubdiv::OsdPatchArray const & patch)
|
||||
bindProgram(Effect effect, OpenSubdiv::OsdDrawContext::PatchArray const & patch)
|
||||
{
|
||||
EffectDesc effectDesc(patch.desc, effect);
|
||||
EffectDesc effectDesc(patch.GetDescriptor(), effect);
|
||||
EffectDrawRegistry::ConfigType *
|
||||
config = effectRegistry.GetDrawConfig(effectDesc);
|
||||
|
||||
@ -776,13 +773,8 @@ display() {
|
||||
glBindTexture(GL_TEXTURE_BUFFER,
|
||||
g_mesh->GetDrawContext()->quadOffsetTextureBuffer);
|
||||
}
|
||||
if (g_mesh->GetDrawContext()->patchLevelTextureBuffer) {
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_BUFFER,
|
||||
g_mesh->GetDrawContext()->patchLevelTextureBuffer);
|
||||
}
|
||||
if (g_mesh->GetDrawContext()->ptexCoordinateTextureBuffer) {
|
||||
glActiveTexture(GL_TEXTURE4);
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_BUFFER,
|
||||
g_mesh->GetDrawContext()->ptexCoordinateTextureBuffer);
|
||||
}
|
||||
@ -795,14 +787,15 @@ display() {
|
||||
|
||||
glBindVertexArray(g_vao);
|
||||
|
||||
OpenSubdiv::OsdPatchArrayVector const & patches = g_mesh->GetDrawContext()->patchArrays;
|
||||
OpenSubdiv::OsdDrawContext::PatchArrayVector const & patches = g_mesh->GetDrawContext()->patchArrays;
|
||||
|
||||
// patch drawing
|
||||
for (int i=0; i<(int)patches.size(); ++i) {
|
||||
OpenSubdiv::OsdPatchArray const & patch = patches[i];
|
||||
OpenSubdiv::OsdDrawContext::PatchArray const & patch = patches[i];
|
||||
OpenSubdiv::OsdDrawContext::PatchDescriptor desc = patch.GetDescriptor();
|
||||
|
||||
GLenum primType = GL_PATCHES;
|
||||
glPatchParameteri(GL_PATCH_VERTICES, patch.desc.GetPatchSize());
|
||||
glPatchParameteri(GL_PATCH_VERTICES, desc.GetNumControlVertices());
|
||||
|
||||
Effect effect;
|
||||
effect.color = g_displayColor;
|
||||
@ -816,15 +809,15 @@ display() {
|
||||
|
||||
GLuint uniformGregoryQuadOffset = glGetUniformLocation(program, "GregoryQuadOffsetBase");
|
||||
GLuint uniformLevelBase = glGetUniformLocation(program, "LevelBase");
|
||||
glProgramUniform1i(program, uniformGregoryQuadOffset, patch.gregoryQuadOffsetBase);
|
||||
glProgramUniform1i(program, uniformLevelBase, patch.levelBase);
|
||||
glProgramUniform1i(program, uniformGregoryQuadOffset, patch.GetQuadOffsetIndex());
|
||||
glProgramUniform1i(program, uniformLevelBase, patch.GetPatchIndex());
|
||||
|
||||
if (g_wire == 0) {
|
||||
glDisable(GL_CULL_FACE);
|
||||
}
|
||||
glDrawElements(primType,
|
||||
patch.numIndices, GL_UNSIGNED_INT,
|
||||
(void *)(patch.firstIndex * sizeof(unsigned int)));
|
||||
patch.GetNumIndices(), GL_UNSIGNED_INT,
|
||||
(void *)(patch.GetVertIndex() * sizeof(unsigned int)));
|
||||
if (g_wire == 0) {
|
||||
glEnable(GL_CULL_FACE);
|
||||
}
|
||||
@ -948,13 +941,8 @@ drawStroke(int x, int y)
|
||||
glBindTexture(GL_TEXTURE_BUFFER,
|
||||
g_mesh->GetDrawContext()->quadOffsetTextureBuffer);
|
||||
}
|
||||
if (g_mesh->GetDrawContext()->patchLevelTextureBuffer) {
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_BUFFER,
|
||||
g_mesh->GetDrawContext()->patchLevelTextureBuffer);
|
||||
}
|
||||
if (g_mesh->GetDrawContext()->ptexCoordinateTextureBuffer) {
|
||||
glActiveTexture(GL_TEXTURE4);
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_BUFFER,
|
||||
g_mesh->GetDrawContext()->ptexCoordinateTextureBuffer);
|
||||
}
|
||||
@ -966,14 +954,15 @@ drawStroke(int x, int y)
|
||||
|
||||
glBindVertexArray(g_vao);
|
||||
|
||||
OpenSubdiv::OsdPatchArrayVector const & patches = g_mesh->GetDrawContext()->patchArrays;
|
||||
OpenSubdiv::OsdDrawContext::PatchArrayVector const & patches = g_mesh->GetDrawContext()->patchArrays;
|
||||
|
||||
// patch drawing
|
||||
for (int i=0; i<(int)patches.size(); ++i) {
|
||||
OpenSubdiv::OsdPatchArray const & patch = patches[i];
|
||||
OpenSubdiv::OsdDrawContext::PatchArray const & patch = patches[i];
|
||||
OpenSubdiv::OsdDrawContext::PatchDescriptor desc = patch.GetDescriptor();
|
||||
|
||||
GLenum primType = GL_PATCHES;
|
||||
glPatchParameteri(GL_PATCH_VERTICES, patch.desc.GetPatchSize());
|
||||
glPatchParameteri(GL_PATCH_VERTICES, desc.GetNumControlVertices());
|
||||
|
||||
Effect effect;
|
||||
effect.color = 0;
|
||||
@ -984,12 +973,12 @@ drawStroke(int x, int y)
|
||||
GLuint program = bindProgram(effect, patch);
|
||||
GLuint uniformGregoryQuadOffset = glGetUniformLocation(program, "GregoryQuadOffsetBase");
|
||||
GLuint uniformLevelBase = glGetUniformLocation(program, "LevelBase");
|
||||
glProgramUniform1i(program, uniformGregoryQuadOffset, patch.gregoryQuadOffsetBase);
|
||||
glProgramUniform1i(program, uniformLevelBase, patch.levelBase);
|
||||
glProgramUniform1i(program, uniformGregoryQuadOffset, patch.GetQuadOffsetIndex());
|
||||
glProgramUniform1i(program, uniformLevelBase, patch.GetPatchIndex());
|
||||
|
||||
glDrawElements(primType,
|
||||
patch.numIndices, GL_UNSIGNED_INT,
|
||||
(void *)(patch.firstIndex * sizeof(unsigned int)));
|
||||
patch.GetNumIndices(), GL_UNSIGNED_INT,
|
||||
(void *)(patch.GetVertIndex() * sizeof(unsigned int)));
|
||||
}
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
@ -59,7 +59,6 @@
|
||||
//--------------------------------------------------------------
|
||||
// Common
|
||||
//--------------------------------------------------------------
|
||||
uniform isamplerBuffer g_ptexIndicesBuffer;
|
||||
uniform int nonAdaptiveLevel;
|
||||
uniform float displacementScale = 1.0;
|
||||
uniform float bumpScale = 1.0;
|
||||
|
@ -699,7 +699,7 @@ union Effect {
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::pair<OpenSubdiv::OsdPatchDescriptor, Effect> EffectDesc;
|
||||
typedef std::pair<OpenSubdiv::OsdDrawContext::PatchDescriptor, Effect> EffectDesc;
|
||||
|
||||
class EffectDrawRegistry : public OpenSubdiv::OsdGLDrawRegistry<EffectDesc> {
|
||||
|
||||
@ -732,16 +732,7 @@ EffectDrawRegistry::_CreateDrawSourceConfig(DescType const & desc)
|
||||
#endif
|
||||
|
||||
bool quad = true;
|
||||
if (desc.first.type != OpenSubdiv::kNonPatch) {
|
||||
|
||||
quad = false;
|
||||
sconfig->tessEvalShader.source = g_shaderSource + sconfig->tessEvalShader.source;
|
||||
sconfig->tessEvalShader.version = glslVersion;
|
||||
if (effect.displacement and (not effect.normal))
|
||||
sconfig->geometryShader.AddDefine("FLAT_NORMALS");
|
||||
if (effect.displacement)
|
||||
sconfig->tessEvalShader.AddDefine("USE_PTEX_DISPLACEMENT");
|
||||
} else {
|
||||
if (desc.first.GetType() == OpenSubdiv::FarPatchTables::QUADS) {
|
||||
sconfig->vertexShader.source = g_shaderSource;
|
||||
sconfig->vertexShader.version = glslVersion;
|
||||
sconfig->vertexShader.AddDefine("VERTEX_SHADER");
|
||||
@ -749,6 +740,14 @@ EffectDrawRegistry::_CreateDrawSourceConfig(DescType const & desc)
|
||||
sconfig->geometryShader.AddDefine("USE_PTEX_DISPLACEMENT");
|
||||
sconfig->geometryShader.AddDefine("FLAT_NORMALS");
|
||||
}
|
||||
} else {
|
||||
quad = false;
|
||||
sconfig->tessEvalShader.source = g_shaderSource + sconfig->tessEvalShader.source;
|
||||
sconfig->tessEvalShader.version = glslVersion;
|
||||
if (effect.displacement and (not effect.normal))
|
||||
sconfig->geometryShader.AddDefine("FLAT_NORMALS");
|
||||
if (effect.displacement)
|
||||
sconfig->tessEvalShader.AddDefine("USE_PTEX_DISPLACEMENT");
|
||||
}
|
||||
assert(sconfig);
|
||||
|
||||
@ -829,11 +828,8 @@ EffectDrawRegistry::_CreateDrawConfig(
|
||||
if ((loc = glGetUniformLocation(config->program, "g_QuadOffsetBuffer")) != -1) {
|
||||
glProgramUniform1i(config->program, loc, 2); // GL_TEXTURE2
|
||||
}
|
||||
if ((loc = glGetUniformLocation(config->program, "g_patchLevelBuffer")) != -1) {
|
||||
glProgramUniform1i(config->program, loc, 3); // GL_TEXTURE3
|
||||
}
|
||||
if ((loc = glGetUniformLocation(config->program, "g_ptexIndicesBuffer")) != -1) {
|
||||
glProgramUniform1i(config->program, loc, 4); // GL_TEXTURE4
|
||||
glProgramUniform1i(config->program, loc, 3); // GL_TEXTURE3
|
||||
}
|
||||
#else
|
||||
glUseProgram(config->program);
|
||||
@ -846,11 +842,8 @@ EffectDrawRegistry::_CreateDrawConfig(
|
||||
if ((loc = glGetUniformLocation(config->program, "g_QuadOffsetBuffer")) != -1) {
|
||||
glUniform1i(loc, 2); // GL_TEXTURE2
|
||||
}
|
||||
if ((loc = glGetUniformLocation(config->program, "g_patchLevelBuffer")) != -1) {
|
||||
glUniform1i(loc, 3); // GL_TEXTURE3
|
||||
}
|
||||
if ((loc = glGetUniformLocation(config->program, "g_ptexIndicesBuffer")) != -1) {
|
||||
glUniform1i(loc, 4); // GL_TEXTURE4
|
||||
glUniform1i(loc, 4); // GL_TEXTURE3
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -860,11 +853,9 @@ EffectDrawRegistry::_CreateDrawConfig(
|
||||
EffectDrawRegistry effectRegistry;
|
||||
|
||||
EffectDrawRegistry::ConfigType *
|
||||
getInstance(Effect effect, OpenSubdiv::OsdPatchDescriptor const & patchDesc) {
|
||||
getInstance(Effect effect, OpenSubdiv::OsdDrawContext::PatchDescriptor const & patchDesc) {
|
||||
|
||||
EffectDesc desc;
|
||||
desc.first = patchDesc;
|
||||
desc.second = effect;
|
||||
EffectDesc desc(patchDesc, effect);
|
||||
|
||||
EffectDrawRegistry::ConfigType * config =
|
||||
effectRegistry.GetDrawConfig(desc);
|
||||
@ -966,7 +957,7 @@ createOsdMesh(int level, int kernel) {
|
||||
#endif
|
||||
#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK
|
||||
} else if(kernel == kGLSL) {
|
||||
if (not g_glslComputeController) {
|
||||
if (not g_glslTransformFeedbackComputeController) {
|
||||
g_glslTransformFeedbackComputeController = new OpenSubdiv::OsdGLSLTransformFeedbackComputeController();
|
||||
}
|
||||
g_mesh = new OpenSubdiv::OsdMesh<OpenSubdiv::OsdGLVertexBuffer,
|
||||
@ -1244,9 +1235,9 @@ applyImageShader() {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static GLuint
|
||||
bindProgram(Effect effect, OpenSubdiv::OsdPatchArray const & patch)
|
||||
bindProgram(Effect effect, OpenSubdiv::OsdDrawContext::PatchArray const & patch)
|
||||
{
|
||||
OpenSubdiv::OsdPatchDescriptor const & desc = patch.desc;
|
||||
OpenSubdiv::OsdDrawContext::PatchDescriptor const & desc = patch.GetDescriptor();
|
||||
|
||||
EffectDrawRegistry::ConfigType *
|
||||
config = getInstance(effect, desc);
|
||||
@ -1390,70 +1381,58 @@ drawModel() {
|
||||
g_mesh->BindVertexBuffer();
|
||||
#endif
|
||||
|
||||
OpenSubdiv::OsdPatchArrayVector const & patches = g_mesh->GetDrawContext()->patchArrays;
|
||||
GLenum primType = GL_LINES_ADJACENCY;
|
||||
|
||||
OpenSubdiv::OsdDrawContext::PatchArrayVector const & patches = g_mesh->GetDrawContext()->patchArrays;
|
||||
glBindVertexArray(g_vao);
|
||||
|
||||
// patch drawing
|
||||
for (int i=0; i<(int)patches.size(); ++i) {
|
||||
OpenSubdiv::OsdPatchArray const & patch = patches[i];
|
||||
OpenSubdiv::OsdDrawContext::PatchArray const & patch = patches[i];
|
||||
|
||||
OpenSubdiv::OsdDrawContext::PatchDescriptor desc = patch.GetDescriptor();
|
||||
OpenSubdiv::FarPatchTables::Type patchType = desc.GetType();
|
||||
int patchPattern = desc.GetPattern() - 1;
|
||||
|
||||
GLenum primType;
|
||||
switch(patchType) {
|
||||
case OpenSubdiv::FarPatchTables::QUADS:
|
||||
primType = GL_LINES_ADJACENCY;
|
||||
break;
|
||||
case OpenSubdiv::FarPatchTables::TRIANGLES:
|
||||
primType = GL_TRIANGLES;
|
||||
break;
|
||||
default:
|
||||
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
|
||||
OpenSubdiv::OsdPatchType patchType = patch.desc.type;
|
||||
int patchPattern = patch.desc.pattern;
|
||||
//int patchRotation = patch.desc.rotation;
|
||||
|
||||
if (g_mesh->GetDrawContext()->IsAdaptive()) {
|
||||
|
||||
primType = GL_PATCHES;
|
||||
glPatchParameteri(GL_PATCH_VERTICES, patch.desc.GetPatchSize());
|
||||
|
||||
if (g_mesh->GetDrawContext()->vertexTextureBuffer) {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_BUFFER,
|
||||
g_mesh->GetDrawContext()->vertexTextureBuffer);
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, bVertex);
|
||||
}
|
||||
|
||||
if (g_mesh->GetDrawContext()->vertexValenceTextureBuffer) {
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_BUFFER,
|
||||
g_mesh->GetDrawContext()->vertexValenceTextureBuffer);
|
||||
}
|
||||
|
||||
if (g_mesh->GetDrawContext()->quadOffsetTextureBuffer) {
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_BUFFER,
|
||||
g_mesh->GetDrawContext()->quadOffsetTextureBuffer);
|
||||
}
|
||||
if (g_mesh->GetDrawContext()->patchLevelTextureBuffer) {
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_BUFFER,
|
||||
g_mesh->GetDrawContext()->patchLevelTextureBuffer);
|
||||
}
|
||||
if (g_mesh->GetDrawContext()->ptexCoordinateTextureBuffer) {
|
||||
glActiveTexture(GL_TEXTURE4);
|
||||
glBindTexture(GL_TEXTURE_BUFFER,
|
||||
g_mesh->GetDrawContext()->ptexCoordinateTextureBuffer);
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
} else {
|
||||
if (g_mesh->GetDrawContext()->ptexCoordinateTextureBuffer) {
|
||||
glActiveTexture(GL_TEXTURE4);
|
||||
glBindTexture(GL_TEXTURE_BUFFER,
|
||||
g_mesh->GetDrawContext()->ptexCoordinateTextureBuffer);
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
glPatchParameteri(GL_PATCH_VERTICES, desc.GetNumControlVertices());
|
||||
#else
|
||||
primType = GL_POINTS;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (g_mesh->GetDrawContext()->vertexTextureBuffer) {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_BUFFER,
|
||||
g_mesh->GetDrawContext()->vertexTextureBuffer);
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, bVertex);
|
||||
}
|
||||
|
||||
if (g_mesh->GetDrawContext()->vertexValenceTextureBuffer) {
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_BUFFER,
|
||||
g_mesh->GetDrawContext()->vertexValenceTextureBuffer);
|
||||
}
|
||||
|
||||
if (g_mesh->GetDrawContext()->quadOffsetTextureBuffer) {
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_BUFFER,
|
||||
g_mesh->GetDrawContext()->quadOffsetTextureBuffer);
|
||||
}
|
||||
if (g_mesh->GetDrawContext()->ptexCoordinateTextureBuffer) {
|
||||
glActiveTexture(GL_TEXTURE4);
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_BUFFER,
|
||||
g_mesh->GetDrawContext()->ptexCoordinateTextureBuffer);
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
#endif
|
||||
|
||||
Effect effect;
|
||||
effect.value = 0;
|
||||
@ -1488,50 +1467,40 @@ drawModel() {
|
||||
#if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0)
|
||||
GLuint overrideColorEnable = glGetUniformLocation(program, "overrideColorEnable");
|
||||
GLuint overrideColor = glGetUniformLocation(program, "overrideColor");
|
||||
switch(patchType) {
|
||||
case OpenSubdiv::kRegular:
|
||||
glProgramUniform4f(program, overrideColor, 1.0f, 1.0f, 1.0f, 1);
|
||||
break;
|
||||
case OpenSubdiv::kBoundary:
|
||||
glProgramUniform4f(program, overrideColor, 0.8f, 0.0f, 0.0f, 1);
|
||||
break;
|
||||
case OpenSubdiv::kCorner:
|
||||
glProgramUniform4f(program, overrideColor, 0, 1.0, 0, 1);
|
||||
break;
|
||||
case OpenSubdiv::kGregory:
|
||||
glProgramUniform4f(program, overrideColor, 1.0f, 1.0f, 0.0f, 1);
|
||||
break;
|
||||
case OpenSubdiv::kBoundaryGregory:
|
||||
glProgramUniform4f(program, overrideColor, 1.0f, 0.5f, 0.0f, 1);
|
||||
break;
|
||||
case OpenSubdiv::kTransitionRegular:
|
||||
switch (patchPattern) {
|
||||
case 0:
|
||||
glProgramUniform4f(program, overrideColor, 0, 1.0f, 1.0f, 1);
|
||||
break;
|
||||
case 1:
|
||||
glProgramUniform4f(program, overrideColor, 0, 0.5f, 1.0f, 1);
|
||||
break;
|
||||
case 2:
|
||||
glProgramUniform4f(program, overrideColor, 0, 0.5f, 0.5f, 1);
|
||||
break;
|
||||
case 3:
|
||||
glProgramUniform4f(program, overrideColor, 0.5f, 0, 1.0f, 1);
|
||||
break;
|
||||
case 4:
|
||||
glProgramUniform4f(program, overrideColor, 1.0f, 0.5f, 1.0f, 1);
|
||||
break;
|
||||
|
||||
GLfloat patchColor[10][4] = {
|
||||
{ 1.0f, 1.0f, 1.0f, 1.0f }, // NON_PATCH
|
||||
{ 1.0f, 1.0f, 1.0f, 1.0f }, // POLYGON
|
||||
{ 1.0f, 1.0f, 1.0f, 1.0f }, // QUADS
|
||||
{ 1.0f, 1.0f, 1.0f, 1.0f }, // TRIANGLES
|
||||
{ 1.0f, 1.0f, 1.0f, 1.0f }, // LOOP
|
||||
{ 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
|
||||
};
|
||||
GLfloat regularTransitionColor[6][4] = {
|
||||
{ 1.0f, 1.0f, 1.0f, 1.0f }, // NON_TRANSITION
|
||||
{ 0.0f, 1.0f, 1.0f, 1.0f }, // PATTERN0
|
||||
{ 0.0f, 0.5f, 1.0f, 1.0f }, // PATTERN1
|
||||
{ 0.0f, 0.5f, 0.5f, 1.0f }, // PATTERN2
|
||||
{ 0.5f, 0.0f, 1.0f, 1.0f }, // PATTERN3
|
||||
{ 1.0f, 0.5f, 1.0f, 1.0f }, // PATTERN4
|
||||
};
|
||||
|
||||
if (patchPattern == OpenSubdiv::FarPatchTables::NON_TRANSITION) {
|
||||
glProgramUniform4fv(program, overrideColor, 1, patchColor[patchType]);
|
||||
} else {
|
||||
if (patchType == OpenSubdiv::FarPatchTables::REGULAR) {
|
||||
glProgramUniform4fv(program, overrideColor, 1, regularTransitionColor[patchPattern]);
|
||||
} else if (patchType == OpenSubdiv::FarPatchTables::BOUNDARY) {
|
||||
glProgramUniform4f(program, overrideColor, 0, 0, 0.5f, 1);
|
||||
} else if (patchType == OpenSubdiv::FarPatchTables::CORNER) {
|
||||
glProgramUniform4f(program, overrideColor, 0, 0, 0.5f, 1);
|
||||
} else {
|
||||
glProgramUniform4f(program, overrideColor, 0.4f, 0.4f, 0.8f, 1);
|
||||
}
|
||||
break;
|
||||
case OpenSubdiv::kTransitionBoundary:
|
||||
glProgramUniform4f(program, overrideColor, 0, 0, 0.5f, 1);
|
||||
break;
|
||||
case OpenSubdiv::kTransitionCorner:
|
||||
glProgramUniform4f(program, overrideColor, 0, 0, 0.5f, 1);
|
||||
break;
|
||||
default:
|
||||
glProgramUniform4f(program, overrideColor, 0.4f, 0.4f, 0.8f, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (g_displayPatchColor or g_wire == 2) {
|
||||
@ -1548,12 +1517,12 @@ drawModel() {
|
||||
GLuint uniformGregoryQuadOffset = glGetUniformLocation(program, "GregoryQuadOffsetBase");
|
||||
GLuint uniformLevelBase = glGetUniformLocation(program, "LevelBase");
|
||||
|
||||
glProgramUniform1i(program, uniformGregoryQuadOffset, patch.gregoryQuadOffsetBase);
|
||||
glProgramUniform1i(program, uniformLevelBase, patch.levelBase);
|
||||
glProgramUniform1i(program, uniformGregoryQuadOffset, patch.GetQuadOffsetIndex());
|
||||
glProgramUniform1i(program, uniformLevelBase, patch.GetPatchIndex());
|
||||
|
||||
glDrawElements(primType,
|
||||
patch.numIndices, GL_UNSIGNED_INT,
|
||||
(void *)(patch.firstIndex * sizeof(unsigned int)));
|
||||
patch.GetNumIndices(), GL_UNSIGNED_INT,
|
||||
(void *)(patch.GetVertIndex() * sizeof(unsigned int)));
|
||||
if (g_wire == 0) {
|
||||
glEnable(GL_CULL_FACE);
|
||||
}
|
||||
|
@ -385,7 +385,8 @@ createOsdContext(int level)
|
||||
g_farmesh->GetNumVertices());
|
||||
|
||||
g_drawContext =
|
||||
OpenSubdiv::OsdGLDrawContext::Create(g_farmesh, g_vertexBuffer);
|
||||
OpenSubdiv::OsdGLDrawContext::Create(g_farmesh->GetPatchTables(), false);
|
||||
g_drawContext->UpdateVertexTexture(g_vertexBuffer);
|
||||
|
||||
//
|
||||
// Setup camera positioning based on object bounds. This really has nothing
|
||||
@ -544,16 +545,16 @@ display()
|
||||
//
|
||||
glBindBuffer(GL_ARRAY_BUFFER, g_vertexBuffer->BindVBO());
|
||||
|
||||
OpenSubdiv::OsdPatchArrayVector const & patches = g_drawContext->patchArrays;
|
||||
OpenSubdiv::OsdDrawContext::PatchArrayVector const & patches = g_drawContext->patchArrays;
|
||||
for (int i=0; i<(int)patches.size(); ++i) {
|
||||
OpenSubdiv::OsdPatchArray const & patch = patches[i];
|
||||
OpenSubdiv::OsdDrawContext::PatchArray const & patch = patches[i];
|
||||
|
||||
//
|
||||
// Bind the solid shaded program and draw elements based on the buffer contents
|
||||
//
|
||||
bindProgram(g_quadFillProgram);
|
||||
|
||||
glDrawElements(GL_LINES_ADJACENCY, patch.numIndices,
|
||||
glDrawElements(GL_LINES_ADJACENCY, patch.GetNumIndices(),
|
||||
GL_UNSIGNED_INT, NULL);
|
||||
|
||||
//
|
||||
@ -562,7 +563,7 @@ display()
|
||||
bindProgram(g_quadLineProgram);
|
||||
glUniform4f(glGetUniformLocation(g_quadLineProgram, "fragColor"),
|
||||
0, 0, 0.5, 1);
|
||||
glDrawElements(GL_LINES_ADJACENCY, patch.numIndices,
|
||||
glDrawElements(GL_LINES_ADJACENCY, patch.GetNumIndices(),
|
||||
GL_UNSIGNED_INT, NULL);
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,8 @@ add_subdirectory(far)
|
||||
|
||||
add_subdirectory(osd)
|
||||
|
||||
add_subdirectory(osdutil)
|
||||
|
||||
install( FILES version.h
|
||||
DESTINATION include/
|
||||
PERMISSIONS OWNER_READ GROUP_READ WORLD_READ )
|
||||
|
@ -68,6 +68,7 @@ set(PUBLIC_HEADER_FILES
|
||||
meshFactory.h
|
||||
mesh.h
|
||||
multiMeshFactory.h
|
||||
patchParam.h
|
||||
patchTables.h
|
||||
patchTablesFactory.h
|
||||
subdivisionTables.h
|
||||
|
@ -128,20 +128,24 @@ public:
|
||||
///
|
||||
/// @param vertexOffset XXXX
|
||||
///
|
||||
/// @param meshIndex XXXX
|
||||
///
|
||||
FarKernelBatch( KernelType kernelType,
|
||||
int level,
|
||||
int tableIndex,
|
||||
int start,
|
||||
int end,
|
||||
int tableOffset,
|
||||
int vertexOffset) :
|
||||
int vertexOffset,
|
||||
int meshIndex=0) :
|
||||
_kernelType(kernelType),
|
||||
_level(level),
|
||||
_tableIndex(tableIndex),
|
||||
_start(start),
|
||||
_end(end),
|
||||
_tableOffset(tableOffset),
|
||||
_vertexOffset(vertexOffset) {
|
||||
_vertexOffset(vertexOffset),
|
||||
_meshIndex(meshIndex) {
|
||||
}
|
||||
|
||||
/// Returns the type of kernel to apply to the vertices in the batch.
|
||||
@ -210,6 +214,12 @@ public:
|
||||
return & _vertexOffset;
|
||||
}
|
||||
|
||||
|
||||
/// Returns the mesh index (used in batching)
|
||||
int GetMeshIndex() const {
|
||||
return _meshIndex;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class FarKernelBatchFactory;
|
||||
template <class X, class Y> friend class FarMultiMeshFactory;
|
||||
@ -221,6 +231,7 @@ private:
|
||||
int _end;
|
||||
int _tableOffset;
|
||||
int _vertexOffset;
|
||||
int _meshIndex;
|
||||
};
|
||||
|
||||
typedef std::vector<FarKernelBatch> FarKernelBatchVector;
|
||||
|
@ -114,7 +114,7 @@ FarLoopSubdivisionTablesFactory<T,U>::Create( FarMeshFactory<T,U> * meshFactory,
|
||||
result->_E_W.resize(tablesFactory.GetNumEdgeVerticesTotal(maxlevel)*2);
|
||||
|
||||
result->_V_ITa.resize((tablesFactory.GetNumVertexVerticesTotal(maxlevel)
|
||||
- tablesFactory.GetNumVertexVerticesTotal(0))*5); // subtract corase cage vertices
|
||||
- tablesFactory.GetNumVertexVerticesTotal(0))*5); // subtract coarse cage vertices
|
||||
result->_V_IT.resize(tablesFactory.GetVertVertsValenceSum());
|
||||
result->_V_W.resize(tablesFactory.GetNumVertexVerticesTotal(maxlevel)
|
||||
- tablesFactory.GetNumVertexVerticesTotal(0));
|
||||
|
@ -87,6 +87,12 @@ public:
|
||||
/// Returns the subdivision method
|
||||
FarSubdivisionTables<U> const * GetSubdivisionTables() const { return _subdivisionTables; }
|
||||
|
||||
/// Returns patch tables
|
||||
FarPatchTables const * GetPatchTables() const { return _patchTables; }
|
||||
|
||||
/// Returns the total number of vertices in the mesh across across all depths
|
||||
int GetNumVertices() const { return GetSubdivisionTables()->GetNumVertices(); }
|
||||
|
||||
/// Returns the list of vertices in the mesh (from subdiv level 0 to N)
|
||||
std::vector<U> & GetVertices() { return _vertices; }
|
||||
|
||||
@ -96,35 +102,17 @@ public:
|
||||
///
|
||||
U & GetVertex(int index) { return _vertices[index]; }
|
||||
|
||||
/// Returns the list of indices of the vertices of the faces in the mesh
|
||||
std::vector<int> const & GetFaceVertices(int level) const;
|
||||
|
||||
/// Returns the ptex coordinates for each face at a given level. The coordinates
|
||||
/// are stored as : (int) faceindex / (ushort) u_index / (ushort) v_index
|
||||
std::vector<FarPtexCoord> const & GetPtexCoordinates(int level) const;
|
||||
|
||||
/// Returns the fvar data for each face at a given level. The data
|
||||
/// is stored as a run of totalFVarWidth floats per-vertex per-face
|
||||
/// e.g.: for UV data it has the structure of float[p][4][2] where
|
||||
/// p=primitiveID and totalFVarWidth=2:
|
||||
/// [ [ uv uv uv uv ] [ uv uv uv uv ] [ ... ] ]
|
||||
/// prim 0 prim 1
|
||||
std::vector<float> const & GetFVarData(int level) const;
|
||||
|
||||
/// Returns the width of the interleaved face-varying data
|
||||
int GetTotalFVarWidth() const { return _totalFVarWidth; }
|
||||
|
||||
/// Returns patch tables
|
||||
FarPatchTables const * GetPatchTables() const { return _patchTables; }
|
||||
|
||||
/// Returns vertex edit tables
|
||||
FarVertexEditTables<U> const * GetVertexEdit() const { return _vertexEditTables; }
|
||||
|
||||
/// Returns the total number of vertices in the mesh across across all depths
|
||||
int GetNumVertices() const { return (int)(_vertices.size()); }
|
||||
int GetNumPtexFaces() const { return _numPtexFaces; }
|
||||
|
||||
/// True if the mesh tables support the feature-adaptive mode.
|
||||
bool SupportsFeatureAdaptive() const { return _patchTables!=NULL; }
|
||||
bool IsFeatureAdaptive() const { return _patchTables->IsFeatureAdaptive(); }
|
||||
|
||||
/// Returns an ordered vector of batches of compute kernels. The kernels
|
||||
/// describe the sequence of computations required to apply the subdivision
|
||||
@ -158,15 +146,9 @@ private:
|
||||
// list of vertices (up to N levels of subdivision)
|
||||
std::vector<U> _vertices;
|
||||
|
||||
// list of vertex indices for each face
|
||||
std::vector< std::vector<int> > _faceverts;
|
||||
int _totalFVarWidth; // width of the face-varying data
|
||||
|
||||
// ptex coordinates for each face
|
||||
std::vector< std::vector<FarPtexCoord> > _ptexcoordinates;
|
||||
|
||||
// fvar data for each face
|
||||
std::vector< std::vector<float> > _fvarData;
|
||||
int _totalFVarWidth; // from hbrMesh
|
||||
int _numPtexFaces;
|
||||
};
|
||||
|
||||
template <class U>
|
||||
@ -177,27 +159,6 @@ FarMesh<U>::~FarMesh()
|
||||
delete _vertexEditTables;
|
||||
}
|
||||
|
||||
template <class U> std::vector<int> const &
|
||||
FarMesh<U>::GetFaceVertices(int level) const {
|
||||
if ( (level>=0) and (level<(int)_faceverts.size()) )
|
||||
return _faceverts[level];
|
||||
return _faceverts[0];
|
||||
}
|
||||
|
||||
template <class U> std::vector<FarPtexCoord> const &
|
||||
FarMesh<U>::GetPtexCoordinates(int level) const {
|
||||
if ( (level>=0) and (level<(int)_faceverts.size()) )
|
||||
return _ptexcoordinates[level];
|
||||
return _ptexcoordinates[0];
|
||||
}
|
||||
|
||||
template <class U> std::vector<float> const &
|
||||
FarMesh<U>::GetFVarData(int level) const {
|
||||
if ( (level>=0) and (level<(int)_faceverts.size()) )
|
||||
return _fvarData[level];
|
||||
return _fvarData[0];
|
||||
}
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
using namespace OPENSUBDIV_VERSION;
|
||||
|
||||
|
@ -118,14 +118,11 @@ public:
|
||||
|
||||
/// Create a table-based mesh representation
|
||||
///
|
||||
/// @param requirePtexCoordinate create a ptex coordinate table
|
||||
///
|
||||
/// @param requireFVarData create a face-varying table
|
||||
///
|
||||
/// @return a pointer to the FarMesh created
|
||||
///
|
||||
FarMesh<U> * Create( bool requirePtexCoordinate=false, // XXX yuck.
|
||||
bool requireFVarData=false );
|
||||
FarMesh<U> * Create( bool requireFVarData=false ); // XXX yuck.
|
||||
|
||||
/// Computes the minimum number of adaptive feature isolation levels required
|
||||
/// in order for the limit surface to be an accurate representation of the
|
||||
@ -184,6 +181,7 @@ private:
|
||||
friend class FarLoopSubdivisionTablesFactory<T,U>;
|
||||
friend class FarSubdivisionTablesFactory<T,U>;
|
||||
friend class FarVertexEditTablesFactory<T,U>;
|
||||
friend class FarPatchTablesFactory<T>;
|
||||
|
||||
// Non-copyable, so these are not implemented:
|
||||
FarMeshFactory( FarMeshFactory const & );
|
||||
@ -215,23 +213,17 @@ private:
|
||||
// Calls Hbr to refines the neighbors of v
|
||||
static void refineVertexNeighbors(HbrVertex<T> * v);
|
||||
|
||||
// Densely refine the Hbr mesh
|
||||
// Uniformly refine the Hbr mesh
|
||||
static void refine( HbrMesh<T> * mesh, int maxlevel );
|
||||
|
||||
// Adaptively refine the Hbr mesh
|
||||
int refineAdaptive( HbrMesh<T> * mesh, int maxIsolate );
|
||||
|
||||
// Generates local sub-face coordinates for Ptex textures
|
||||
void generatePtexCoordinates( std::vector<FarPtexCoord> & vec, int level );
|
||||
|
||||
// Generates local sub-face face-varying UV coordinates
|
||||
void generateFVarData( std::vector<float> & vec, int level );
|
||||
|
||||
// Generates non-adaptive quad topology
|
||||
// XXXX manuelk we should introduce an equivalent to FarPatchTables for
|
||||
// non-adaptive stuff
|
||||
void generateQuadsTopology( std::vector<int> & vec, int level );
|
||||
|
||||
typedef std::vector<std::vector< HbrFace<T> *> > FacesList;
|
||||
|
||||
// Returns sorted vectors of HbrFace<T> pointers sorted by level
|
||||
FacesList const & GetFaceList() const { return _facesList; }
|
||||
|
||||
private:
|
||||
HbrMesh<T> * _hbrMesh;
|
||||
|
||||
@ -241,14 +233,14 @@ private:
|
||||
_numVertices,
|
||||
_numCoarseVertices,
|
||||
_numFaces,
|
||||
_maxValence;
|
||||
_maxValence,
|
||||
_numPtexFaces;
|
||||
|
||||
// remapping table to translate vertex ID's between Hbr indices and the
|
||||
// order of the same vertices in the tables
|
||||
std::vector<int> _remapTable;
|
||||
|
||||
// list of faces sorted by level
|
||||
std::vector<std::vector< HbrFace<T> *> > _facesList;
|
||||
FacesList _facesList;
|
||||
};
|
||||
|
||||
template <class T, class U>
|
||||
@ -305,6 +297,8 @@ FarMeshFactory<T,U>::refine( HbrMesh<T> * mesh, int maxlevel ) {
|
||||
// faces that have already been refined.
|
||||
firstface = nfaces;
|
||||
}
|
||||
|
||||
mesh->SetSubdivisionMethod(HbrMesh<T>::k_SubdivisionMethodUniform);
|
||||
}
|
||||
|
||||
// Scan the faces of a mesh and compute the max level of subdivision required
|
||||
@ -496,12 +490,12 @@ FarMeshFactory<T,U>::refineAdaptive( HbrMesh<T> * mesh, int maxIsolate ) {
|
||||
// Quad-faces with 2 non-consecutive boundaries need to be flagged
|
||||
// as "non-patch"
|
||||
//
|
||||
// O ******** O ******** O ******** O
|
||||
// * | | * *** boundary edge
|
||||
// * | needs | *
|
||||
// * | flag | * --- regular edge
|
||||
// * | | *
|
||||
// O ******** O ******** O ******** O
|
||||
// o ........ o ........ o ........ o
|
||||
// . | | . ... b.undary edge
|
||||
// . | needs | .
|
||||
// . | flag | . --- regular edge
|
||||
// . | | .
|
||||
// o ........ o ........ o ........ o
|
||||
//
|
||||
if ( e->IsBoundary() and (not f->_adaptiveFlags.isTagged) and nv==4 ) {
|
||||
if (e->GetPrev() and (not e->GetPrev()->IsBoundary()) and
|
||||
@ -585,6 +579,9 @@ FarMeshFactory<T,U>::refineAdaptive( HbrMesh<T> * mesh, int maxIsolate ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mesh->SetSubdivisionMethod(HbrMesh<T>::k_SubdivisionMethodFeatureAdaptive);
|
||||
|
||||
return maxlevel-1;
|
||||
}
|
||||
|
||||
@ -600,9 +597,11 @@ FarMeshFactory<T,U>::FarMeshFactory( HbrMesh<T> * mesh, int maxlevel, bool adapt
|
||||
_numCoarseVertices(-1),
|
||||
_numFaces(-1),
|
||||
_maxValence(4),
|
||||
_numPtexFaces(-1),
|
||||
_facesList(maxlevel+1)
|
||||
{
|
||||
_numCoarseVertices = mesh->GetNumVertices();
|
||||
_numPtexFaces = getNumPtexFaces(mesh);
|
||||
|
||||
// Subdivide the Hbr mesh up to maxlevel.
|
||||
//
|
||||
@ -620,7 +619,6 @@ FarMeshFactory<T,U>::FarMeshFactory( HbrMesh<T> * mesh, int maxlevel, bool adapt
|
||||
if (not adaptive) {
|
||||
|
||||
// Populate the face lists
|
||||
|
||||
int fsize=0;
|
||||
for (int i=0; i<_numFaces; ++i) {
|
||||
HbrFace<T> * f = mesh->GetFace(i);
|
||||
@ -657,29 +655,6 @@ FarMeshFactory<T,U>::isLoop(HbrMesh<T> const * mesh) {
|
||||
return typeid(*(mesh->GetSubdivision()))==typeid(HbrLoopSubdivision<T>);
|
||||
}
|
||||
|
||||
template <class T, class U> void
|
||||
FarMeshFactory<T,U>::generateQuadsTopology( std::vector<int> & vec, int level ) {
|
||||
|
||||
assert( GetHbrMesh() );
|
||||
|
||||
int nv=-1;
|
||||
if ( isCatmark(GetHbrMesh()) or isBilinear(GetHbrMesh()) )
|
||||
nv=4;
|
||||
else if ( isLoop(GetHbrMesh()) )
|
||||
nv=3;
|
||||
|
||||
assert(nv>0);
|
||||
|
||||
vec.resize( nv * _facesList[level].size(), -1 );
|
||||
|
||||
for (int i=0; i<(int)_facesList[level].size(); ++i) {
|
||||
HbrFace<T> * f = _facesList[level][i];
|
||||
assert( f and f->GetNumVertices()==nv);
|
||||
for (int j=0; j<f->GetNumVertices(); ++j)
|
||||
vec[nv*i+j]=_remapTable[f->GetVertex(j)->GetID()];
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class U> void
|
||||
copyVertex( T & dest, U const & src ) {
|
||||
}
|
||||
@ -689,10 +664,23 @@ copyVertex( T & dest, T const & src ) {
|
||||
dest = src;
|
||||
}
|
||||
|
||||
template <class T> int
|
||||
getNumPtexFaces(HbrMesh<T> const * hmesh) {
|
||||
|
||||
HbrFace<T> * lastface = hmesh->GetFace(hmesh->GetNumFaces()-1);
|
||||
assert(lastface);
|
||||
|
||||
int result = lastface->GetPtexIndex();
|
||||
|
||||
result += (hmesh->GetSubdivision()->FaceIsExtraordinary(hmesh, lastface) ?
|
||||
lastface->GetNumVertices() : 1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Computes per-face or per-patch local ptex texture coordinates.
|
||||
template <class T> FarPtexCoord *
|
||||
computePtexCoordinate(HbrFace<T> const *f, FarPtexCoord *coord) {
|
||||
template <class T> FarPatchParam *
|
||||
computePatchParam(HbrFace<T> const *f, FarPatchParam *coord) {
|
||||
|
||||
short u,v;
|
||||
unsigned short ofs = 1;
|
||||
@ -735,29 +723,6 @@ computePtexCoordinate(HbrFace<T> const *f, FarPtexCoord *coord) {
|
||||
return ++coord;
|
||||
}
|
||||
|
||||
// This currently only supports the Catmark / Bilinear schemes. Loop
|
||||
template <class T, class U> void
|
||||
FarMeshFactory<T,U>::generatePtexCoordinates( std::vector<FarPtexCoord> & vec, int level ) {
|
||||
|
||||
assert( _hbrMesh );
|
||||
|
||||
if (_facesList[0].empty() or _facesList[level][0]->GetPtexIndex() == -1)
|
||||
return;
|
||||
|
||||
vec.resize( _facesList[level].size() );
|
||||
|
||||
FarPtexCoord * p = &vec[0];
|
||||
|
||||
for (int i=0; i<(int)_facesList[level].size(); ++i) {
|
||||
|
||||
HbrFace<T> const * f = _facesList[level][i];
|
||||
assert(f);
|
||||
|
||||
p = computePtexCoordinate(f, p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class T> float *
|
||||
computeFVarData(HbrFace<T> const *f, const int width, float *coord, bool isAdaptive) {
|
||||
|
||||
@ -798,34 +763,8 @@ computeFVarData(HbrFace<T> const *f, const int width, float *coord, bool isAdapt
|
||||
return coord;
|
||||
}
|
||||
|
||||
// This currently only supports the Catmark / Bilinear schemes. Loop
|
||||
template <class T, class U> void
|
||||
FarMeshFactory<T,U>::generateFVarData( std::vector<float> & vec, int level ) {
|
||||
|
||||
assert( _hbrMesh );
|
||||
|
||||
if (_facesList[0].empty())
|
||||
return;
|
||||
|
||||
// initialize coordinate vector: numFaces*4verts*numFVarDatumPerVert
|
||||
int totalFVarWidth = _hbrMesh->GetTotalFVarWidth();
|
||||
vec.resize( _facesList[level].size()*4 * totalFVarWidth, -1.0 );
|
||||
|
||||
// pointer will be advanced through vector as we go through faces
|
||||
float *p = &vec[0];
|
||||
|
||||
for (int i=0; i<(int)_facesList[level].size(); ++i) {
|
||||
|
||||
HbrFace<T> const * f = _facesList[level][i];
|
||||
assert(f);
|
||||
|
||||
p = computeFVarData(f, totalFVarWidth, p, /*isAdaptive=*/false);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class U> FarMesh<U> *
|
||||
FarMeshFactory<T,U>::Create( bool requirePtexCoordinate, // XXX yuck.
|
||||
bool requireFVarData ) {
|
||||
FarMeshFactory<T,U>::Create( bool requireFVarData ) {
|
||||
|
||||
assert( GetHbrMesh() );
|
||||
|
||||
@ -847,12 +786,11 @@ FarMeshFactory<T,U>::Create( bool requirePtexCoordinate, // XXX yuck.
|
||||
|
||||
// If the vertex classes aren't place-holders, copy the data of the coarse
|
||||
// vertices into the vertex buffer.
|
||||
result->_vertices.resize( _numVertices );
|
||||
if (sizeof(U)>1) {
|
||||
result->_vertices.resize( _numVertices );
|
||||
for (int i=0; i<GetNumCoarseVertices(); ++i)
|
||||
copyVertex(result->_vertices[i], GetHbrMesh()->GetVertex(i)->GetData());
|
||||
}
|
||||
|
||||
|
||||
// Create the element indices tables (patches for adaptive, quads for non-adaptive)
|
||||
if (isAdaptive()) {
|
||||
@ -860,37 +798,19 @@ FarMeshFactory<T,U>::Create( bool requirePtexCoordinate, // XXX yuck.
|
||||
FarPatchTablesFactory<T> factory(GetHbrMesh(), _numFaces, _remapTable);
|
||||
|
||||
// XXXX: currently PatchGregory shader supports up to 29 valence
|
||||
result->_patchTables = factory.Create(GetMaxLevel()+1, _maxValence, requirePtexCoordinate,
|
||||
requireFVarData);
|
||||
assert( result->_patchTables );
|
||||
|
||||
if (requireFVarData) {
|
||||
result->_totalFVarWidth = _hbrMesh->GetTotalFVarWidth();
|
||||
}
|
||||
result->_patchTables = factory.Create(GetMaxLevel()+1, _maxValence, requireFVarData);
|
||||
|
||||
} else {
|
||||
|
||||
// XXXX : we should let the client control what to copy, most of this may be irrelevant
|
||||
result->_faceverts.resize(GetMaxLevel()+1);
|
||||
for (int l=1; l<=GetMaxLevel(); ++l)
|
||||
generateQuadsTopology(result->_faceverts[l], l);
|
||||
|
||||
if (requirePtexCoordinate) {
|
||||
// Generate Ptex coordinates
|
||||
result->_ptexcoordinates.resize(GetMaxLevel()+1);
|
||||
for (int l=1; l<=GetMaxLevel(); ++l)
|
||||
generatePtexCoordinates(result->_ptexcoordinates[l], l);
|
||||
}
|
||||
|
||||
if (requireFVarData) {
|
||||
// Generate fvar data
|
||||
result->_totalFVarWidth = _hbrMesh->GetTotalFVarWidth();
|
||||
result->_fvarData.resize(GetMaxLevel()+1);
|
||||
for (int l=1; l<=GetMaxLevel(); ++l)
|
||||
generateFVarData(result->_fvarData[l], l);
|
||||
}
|
||||
result->_patchTables = FarPatchTablesFactory<T>::Create(GetHbrMesh(), _facesList, _remapTable, -1, requireFVarData );
|
||||
}
|
||||
assert( result->_patchTables );
|
||||
|
||||
result->_numPtexFaces = _numPtexFaces;
|
||||
|
||||
if (requireFVarData) {
|
||||
result->_totalFVarWidth = _hbrMesh->GetTotalFVarWidth();
|
||||
}
|
||||
|
||||
// Create VertexEditTables if necessary
|
||||
if (GetHbrMesh()->HasVertexEdits()) {
|
||||
result->_vertexEditTables = FarVertexEditTablesFactory<T,U>::Create( this, result, &result->_batches, GetMaxLevel() );
|
||||
|
@ -96,6 +96,10 @@ public:
|
||||
///
|
||||
FarMesh<U> * Create(std::vector<FarMesh<U> const *> const &meshes);
|
||||
|
||||
std::vector<FarPatchTables::PatchArrayVector> const & GetMultiPatchArrays() {
|
||||
return _multiPatchArrays;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// splice subdivision tables
|
||||
@ -104,14 +108,22 @@ private:
|
||||
// splice patch tables
|
||||
FarPatchTables * splicePatchTables(FarMeshVector const &meshes);
|
||||
|
||||
// splice quad indices
|
||||
void spliceQuads(FarMesh<U> *result, FarMeshVector const &meshes);
|
||||
// splice patch array
|
||||
FarPatchTables::PTable::iterator splicePatch(FarPatchTables::Descriptor desc,
|
||||
FarMeshVector const &meshes,
|
||||
FarPatchTables::PatchArrayVector &result,
|
||||
FarPatchTables::PTable::iterator dstIndexIt,
|
||||
int *voffset, int *poffset, int *qoffset,
|
||||
std::vector<int> const &vertexOffsets);
|
||||
|
||||
// splice hierarchical edit tables
|
||||
FarVertexEditTables<U> * spliceVertexEditTables(FarMesh<U> *farmesh, FarMeshVector const &meshes);
|
||||
|
||||
int _maxlevel;
|
||||
int _maxvalence;
|
||||
|
||||
// patch arrays for each mesh
|
||||
std::vector<FarPatchTables::PatchArrayVector> _multiPatchArrays;
|
||||
};
|
||||
|
||||
|
||||
@ -152,21 +164,20 @@ FarMultiMeshFactory<T, U>::Create(std::vector<FarMesh<U> const *> const &meshes)
|
||||
result->_subdivisionTables = spliceSubdivisionTables(result, meshes);
|
||||
|
||||
// splice patch/quad index tables
|
||||
if ( adaptive ) {
|
||||
result->_patchTables = splicePatchTables(meshes);
|
||||
} else {
|
||||
spliceQuads(result, meshes);
|
||||
}
|
||||
result->_patchTables = splicePatchTables(meshes);
|
||||
|
||||
// splice vertex edit tables
|
||||
result->_vertexEditTables = spliceVertexEditTables(result, meshes);
|
||||
|
||||
// count total num vertices
|
||||
int numVertices = 0;
|
||||
// count total num vertices, numptex faces
|
||||
int numVertices = 0, numPtexFaces = 0;
|
||||
for (size_t i = 0; i < meshes.size(); ++i) {
|
||||
numVertices += meshes[i]->GetNumVertices();
|
||||
numPtexFaces += meshes[i]->GetNumPtexFaces();
|
||||
}
|
||||
result->_vertices.resize(numVertices);
|
||||
result->_numPtexFaces = numPtexFaces;
|
||||
result->_totalFVarWidth = 0; // XXX: fvar for multimesh hasn't been implemented yet.
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -177,6 +188,22 @@ copyWithOffset(IT dst_iterator, V const &src, int offset) {
|
||||
std::bind2nd(std::plus<typename V::value_type>(), offset));
|
||||
}
|
||||
|
||||
template <typename V, typename IT> static IT
|
||||
copyWithOffset(IT dst_iterator, V const &src, int start, int count, int offset) {
|
||||
return std::transform(src.begin()+start, src.begin()+start+count, dst_iterator,
|
||||
std::bind2nd(std::plus<typename V::value_type>(), offset));
|
||||
}
|
||||
|
||||
template <typename V, typename IT> static IT
|
||||
copyWithPtexFaceOffset(IT dst_iterator, V const &src, int start, int count, int offset) {
|
||||
for (typename V::const_iterator it = src.begin()+start; it != src.begin()+start+count; ++it) {
|
||||
typename V::value_type ptexCoord = *it;
|
||||
ptexCoord.faceIndex += offset;
|
||||
*dst_iterator++ = ptexCoord;
|
||||
}
|
||||
return dst_iterator;
|
||||
}
|
||||
|
||||
template <typename V, typename IT> static IT
|
||||
copyWithOffsetF_ITa(IT dst_iterator, V const &src, int offset) {
|
||||
for (typename V::const_iterator it = src.begin(); it != src.end();) {
|
||||
@ -382,24 +409,63 @@ FarMultiMeshFactory<T, U>::spliceSubdivisionTables(FarMesh<U> *farMesh, FarMeshV
|
||||
}
|
||||
editTableIndexOffset += meshes[i]->_vertexEditTables ? meshes[i]->_vertexEditTables->GetNumBatches() : 0;
|
||||
}
|
||||
|
||||
// count verts offsets
|
||||
result->_vertsOffsets.resize(_maxlevel+2);
|
||||
for (size_t i = 0; i < meshes.size(); ++i) {
|
||||
FarSubdivisionTables<U> const * tables = meshes[i]->GetSubdivisionTables();
|
||||
for (size_t j = 0; j < tables->_vertsOffsets.size(); ++j) {
|
||||
result->_vertsOffsets[j] += tables->_vertsOffsets[j];
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class T, class U> void
|
||||
FarMultiMeshFactory<T, U>::spliceQuads(FarMesh<U> *result, FarMeshVector const &meshes) {
|
||||
template <class T, class U> FarPatchTables::PTable::iterator
|
||||
FarMultiMeshFactory<T, U>::splicePatch(FarPatchTables::Descriptor desc,
|
||||
FarMeshVector const &meshes,
|
||||
FarPatchTables::PatchArrayVector &result,
|
||||
FarPatchTables::PTable::iterator dstIndexIt,
|
||||
int *voffset, int *poffset, int *qoffset,
|
||||
std::vector<int> const &vertexOffsets)
|
||||
{
|
||||
for (size_t i = 0; i < meshes.size(); ++i) {
|
||||
FarPatchTables const *patchTables = meshes[i]->GetPatchTables();
|
||||
FarPatchTables::PatchArray const *srcPatchArray = patchTables->GetPatchArray(desc);
|
||||
if (not srcPatchArray) continue;
|
||||
|
||||
result->_faceverts.clear();
|
||||
result->_faceverts.resize(_maxlevel+1);
|
||||
// create new patcharray with offset
|
||||
int vindex = srcPatchArray->GetVertIndex();
|
||||
int npatch = srcPatchArray->GetNumPatches();
|
||||
int nvertex = npatch * desc.GetNumControlVertices();
|
||||
|
||||
// apply vertex offset and concatenate quad indices
|
||||
for (int l = 0; l <= _maxlevel; ++l) {
|
||||
int vertexOffset = 0;
|
||||
for (size_t i = 0; i < meshes.size(); ++i) {
|
||||
copyWithOffset(std::back_inserter(result->_faceverts[l]),
|
||||
meshes[i]->_faceverts[l], vertexOffset);
|
||||
vertexOffset += meshes[i]->GetNumVertices();
|
||||
}
|
||||
FarPatchTables::PatchArray patchArray(desc,
|
||||
*voffset,
|
||||
*poffset,
|
||||
npatch,
|
||||
*qoffset);
|
||||
// append patch array
|
||||
result.push_back(patchArray);
|
||||
|
||||
// also store into multiPatchArrays, will be used for partial drawing
|
||||
// XXX: can be stored as indices. revisit here later
|
||||
_multiPatchArrays[i].push_back(patchArray);
|
||||
|
||||
// increment offset
|
||||
*voffset += nvertex;
|
||||
*poffset += npatch;
|
||||
*qoffset += (desc.GetType() == FarPatchTables::GREGORY ||
|
||||
desc.GetType() == FarPatchTables::GREGORY_BOUNDARY) ? npatch * 4 : 0;
|
||||
|
||||
// copy index arrays [vindex, vindex+nvertex]
|
||||
dstIndexIt = copyWithOffset(dstIndexIt,
|
||||
patchTables->GetPatchTable(),
|
||||
vindex,
|
||||
nvertex,
|
||||
vertexOffsets[i]);
|
||||
}
|
||||
return dstIndexIt;
|
||||
}
|
||||
|
||||
template <class T, class U> FarPatchTables *
|
||||
@ -411,11 +477,15 @@ FarMultiMeshFactory<T, U>::splicePatchTables(FarMeshVector const &meshes) {
|
||||
int total_quadOffset1 = 0;
|
||||
|
||||
std::vector<int> vertexOffsets;
|
||||
std::vector<int> gregoryQuadOffsets;
|
||||
std::vector<int> numGregoryPatches;
|
||||
int vertexOffset = 0;
|
||||
int maxValence = 0;
|
||||
int numTotalIndices = 0;
|
||||
|
||||
result->_patchCounts.reserve(meshes.size());
|
||||
FarPatchCount totalCount;
|
||||
//result->_patchCounts.reserve(meshes.size());
|
||||
//FarPatchCount totalCount;
|
||||
typedef FarPatchTables::Descriptor Descriptor;
|
||||
|
||||
// count how many patches exist on each mesh
|
||||
for (size_t i = 0; i < meshes.size(); ++i) {
|
||||
@ -425,110 +495,43 @@ FarMultiMeshFactory<T, U>::splicePatchTables(FarMeshVector const &meshes) {
|
||||
vertexOffsets.push_back(vertexOffset);
|
||||
vertexOffset += meshes[i]->GetNumVertices();
|
||||
|
||||
// accum patch counts. assuming given patch table has one element
|
||||
const FarPatchCount &patchCount = ptables->GetPatchCounts()[0];
|
||||
result->_patchCounts.push_back(patchCount);
|
||||
totalCount.Append(patchCount);
|
||||
|
||||
// need to align maxvalence with the highest value
|
||||
maxValence = std::max(maxValence, ptables->_maxValence);
|
||||
total_quadOffset0 += (int)ptables->_full._G_IT.first.size();
|
||||
total_quadOffset1 += (int)ptables->_full._G_B_IT.first.size();
|
||||
|
||||
FarPatchTables::PatchArray const *gregory = ptables->GetPatchArray(Descriptor(FarPatchTables::GREGORY, FarPatchTables::NON_TRANSITION, /*rot*/ 0));
|
||||
FarPatchTables::PatchArray const *gregoryBoundary = ptables->GetPatchArray(Descriptor(FarPatchTables::GREGORY_BOUNDARY, FarPatchTables::NON_TRANSITION, /*rot*/ 0));
|
||||
|
||||
int nGregory = gregory ? gregory->GetNumPatches() : 0;
|
||||
int nGregoryBoundary = gregoryBoundary ? gregoryBoundary->GetNumPatches() : 0;
|
||||
total_quadOffset0 += nGregory * 4;
|
||||
total_quadOffset1 += nGregoryBoundary * 4;
|
||||
numGregoryPatches.push_back(nGregory);
|
||||
gregoryQuadOffsets.push_back(total_quadOffset0);
|
||||
|
||||
numTotalIndices += ptables->GetNumControlVertices();
|
||||
}
|
||||
|
||||
// Allocate full patches
|
||||
result->_full._R_IT.first.resize(totalCount.regular*16);
|
||||
result->_full._R_IT.second.resize(totalCount.regular);
|
||||
result->_full._B_IT.first.resize(totalCount.boundary*12);
|
||||
result->_full._B_IT.second.resize(totalCount.boundary);
|
||||
result->_full._C_IT.first.resize(totalCount.corner*9);
|
||||
result->_full._C_IT.second.resize(totalCount.corner);
|
||||
result->_full._G_IT.first.resize(totalCount.gregory*4);
|
||||
result->_full._G_IT.second.resize(totalCount.gregory);
|
||||
result->_full._G_B_IT.first.resize(totalCount.boundaryGregory*4);
|
||||
result->_full._G_B_IT.second.resize(totalCount.boundaryGregory);
|
||||
result->_patches.resize(numTotalIndices);
|
||||
|
||||
// Allocate transition Patches
|
||||
for (int i=0; i<5; ++i) {
|
||||
result->_transition[i]._R_IT.first.resize(totalCount.transitionRegular[i]*16);
|
||||
result->_transition[i]._R_IT.second.resize(totalCount.transitionRegular[i]);
|
||||
for (int j=0; j<4; ++j) {
|
||||
result->_transition[i]._B_IT[j].first.resize(totalCount.transitionBoundary[i][j]*12);
|
||||
result->_transition[i]._B_IT[j].second.resize(totalCount.transitionBoundary[i][j]);
|
||||
result->_transition[i]._C_IT[j].first.resize(totalCount.transitionCorner[i][j]*9);
|
||||
result->_transition[i]._C_IT[j].second.resize(totalCount.transitionCorner[i][j]);
|
||||
}
|
||||
}
|
||||
// Allocate vertex valence table, quad offset table
|
||||
if ((result->_full._G_IT.first.size() + result->_full._G_B_IT.first.size()) > 0) {
|
||||
if (total_quadOffset0 + total_quadOffset1 > 0) {
|
||||
result->_vertexValenceTable.resize((2*maxValence+1) * vertexOffset);
|
||||
result->_quadOffsetTable.resize(total_quadOffset0 + total_quadOffset1);
|
||||
}
|
||||
|
||||
typedef struct IndexIterators {
|
||||
std::vector<unsigned int>::iterator R_P, B_P[4], C_P[4], G_P[2];
|
||||
} IndexIterator;
|
||||
// splice tables
|
||||
// assuming input farmeshes have dense patchtables
|
||||
|
||||
typedef struct LevelIterators {
|
||||
std::vector<unsigned char>::iterator R_P, B_P[4], C_P[4], G_P[2];
|
||||
} LevelIterator;
|
||||
IndexIterator full, transition[5];
|
||||
LevelIterator fullLv, transitionLv[5];
|
||||
_multiPatchArrays.resize(meshes.size());
|
||||
|
||||
// prepare destination iterators
|
||||
full.R_P = result->_full._R_IT.first.begin();
|
||||
full.B_P[0] = result->_full._B_IT.first.begin();
|
||||
full.C_P[0] = result->_full._C_IT.first.begin();
|
||||
full.G_P[0] = result->_full._G_IT.first.begin();
|
||||
full.G_P[1] = result->_full._G_B_IT.first.begin();
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
transition[i].R_P = result->_transition[i]._R_IT.first.begin();
|
||||
for (int j = 0 ; j < 4; ++j) {
|
||||
transition[i].B_P[j] = result->_transition[i]._B_IT[j].first.begin();
|
||||
transition[i].C_P[j] = result->_transition[i]._C_IT[j].first.begin();
|
||||
}
|
||||
}
|
||||
fullLv.R_P = result->_full._R_IT.second.begin();
|
||||
fullLv.B_P[0] = result->_full._B_IT.second.begin();
|
||||
fullLv.C_P[0] = result->_full._C_IT.second.begin();
|
||||
fullLv.G_P[0] = result->_full._G_IT.second.begin();
|
||||
fullLv.G_P[1] = result->_full._G_B_IT.second.begin();
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
transitionLv[i].R_P = result->_transition[i]._R_IT.second.begin();
|
||||
for (int j = 0 ; j < 4; ++j) {
|
||||
transitionLv[i].B_P[j] = result->_transition[i]._B_IT[j].second.begin();
|
||||
transitionLv[i].C_P[j] = result->_transition[i]._C_IT[j].second.begin();
|
||||
}
|
||||
}
|
||||
int voffset = 0, poffset = 0, qoffset = 0;
|
||||
FarPatchTables::PTable::iterator dstIndexIt = result->_patches.begin();
|
||||
|
||||
// merge tables with vertex index offset
|
||||
for (size_t i = 0; i < meshes.size(); ++i) {
|
||||
const FarPatchTables *ptables = meshes[i]->GetPatchTables();
|
||||
int vertexOffset = vertexOffsets[i];
|
||||
|
||||
full.R_P = copyWithOffset(full.R_P, ptables->_full._R_IT.first, vertexOffset);
|
||||
full.B_P[0] = copyWithOffset(full.B_P[0], ptables->_full._B_IT.first, vertexOffset);
|
||||
full.C_P[0] = copyWithOffset(full.C_P[0], ptables->_full._C_IT.first, vertexOffset);
|
||||
full.G_P[0] = copyWithOffset(full.G_P[0], ptables->_full._G_IT.first, vertexOffset);
|
||||
full.G_P[1] = copyWithOffset(full.G_P[1], ptables->_full._G_B_IT.first, vertexOffset);
|
||||
|
||||
fullLv.R_P = copyWithOffset(fullLv.R_P, ptables->_full._R_IT.second, 0);
|
||||
fullLv.B_P[0] = copyWithOffset(fullLv.B_P[0], ptables->_full._B_IT.second, 0);
|
||||
fullLv.C_P[0] = copyWithOffset(fullLv.C_P[0], ptables->_full._C_IT.second, 0);
|
||||
fullLv.G_P[0] = copyWithOffset(fullLv.G_P[0], ptables->_full._G_IT.second, 0);
|
||||
fullLv.G_P[1] = copyWithOffset(fullLv.G_P[1], ptables->_full._G_B_IT.second, 0);
|
||||
|
||||
for (int t = 0; t < 5; ++t) {
|
||||
transition[t].R_P = copyWithOffset(transition[t].R_P, ptables->_transition[t]._R_IT.first, vertexOffset);
|
||||
transitionLv[t].R_P = copyWithOffset(transitionLv[t].R_P, ptables->_transition[t]._R_IT.second, 0);
|
||||
|
||||
for (int r = 0; r < 4; ++r) {
|
||||
transition[t].B_P[r] = copyWithOffset(transition[t].B_P[r], ptables->_transition[t]._B_IT[r].first, vertexOffset);
|
||||
transition[t].C_P[r] = copyWithOffset(transition[t].C_P[r], ptables->_transition[t]._C_IT[r].first, vertexOffset);
|
||||
transitionLv[t].B_P[r] = copyWithOffset(transitionLv[t].B_P[r], ptables->_transition[t]._B_IT[r].second, 0);
|
||||
transitionLv[t].C_P[r] = copyWithOffset(transitionLv[t].C_P[r], ptables->_transition[t]._C_IT[r].second, 0);
|
||||
}
|
||||
}
|
||||
// splice patches : iterate from POINTS
|
||||
for (FarPatchTables::Descriptor::iterator it(FarPatchTables::Descriptor(FarPatchTables::POINTS, FarPatchTables::NON_TRANSITION, 0));
|
||||
it != FarPatchTables::Descriptor::end(); ++it) {
|
||||
dstIndexIt = splicePatch(*it, meshes, result->_patchArrays, dstIndexIt, &voffset, &poffset, &qoffset, vertexOffsets);
|
||||
}
|
||||
|
||||
// merge vertexvalence and quadoffset tables
|
||||
@ -542,17 +545,45 @@ FarMultiMeshFactory<T, U>::splicePatchTables(FarMeshVector const &meshes) {
|
||||
// merge vertex valence
|
||||
// note: some prims may not have vertex valence table, but still need a space
|
||||
// in order to fill following prim's data at appropriate location.
|
||||
copyWithOffsetVertexValence(VV_IT, ptables->_vertexValenceTable, ptables->_maxValence, maxValence, vertexOffsets[i]);
|
||||
copyWithOffsetVertexValence(VV_IT,
|
||||
ptables->_vertexValenceTable,
|
||||
ptables->_maxValence,
|
||||
maxValence,
|
||||
vertexOffsets[i]);
|
||||
|
||||
VV_IT += meshes[i]->GetNumVertices() * (2 * maxValence + 1);
|
||||
|
||||
// merge quad offsets
|
||||
int nGregoryQuads = (int)ptables->_full._G_IT.first.size();
|
||||
Q0_IT = std::copy(ptables->_quadOffsetTable.begin(),
|
||||
ptables->_quadOffsetTable.begin()+nGregoryQuads,
|
||||
Q0_IT);
|
||||
Q1_IT = std::copy(ptables->_quadOffsetTable.begin()+nGregoryQuads,
|
||||
ptables->_quadOffsetTable.end(),
|
||||
Q1_IT);
|
||||
// int nGregoryQuads = (int)ptables->_full._G_IT.first.size();
|
||||
int nGregoryQuads = numGregoryPatches[i] * 4;
|
||||
if (nGregoryQuads > 0) {
|
||||
Q0_IT = std::copy(ptables->_quadOffsetTable.begin(),
|
||||
ptables->_quadOffsetTable.begin()+nGregoryQuads,
|
||||
Q0_IT);
|
||||
}
|
||||
if (nGregoryQuads < (int)ptables->_quadOffsetTable.size()) {
|
||||
Q1_IT = std::copy(ptables->_quadOffsetTable.begin()+nGregoryQuads,
|
||||
ptables->_quadOffsetTable.end(),
|
||||
Q1_IT);
|
||||
}
|
||||
}
|
||||
|
||||
// merge ptexCoord table
|
||||
for (FarPatchTables::Descriptor::iterator it(FarPatchTables::Descriptor(FarPatchTables::POINTS, FarPatchTables::NON_TRANSITION, 0));
|
||||
it != FarPatchTables::Descriptor::end(); ++it) {
|
||||
int ptexFaceOffset = 0;
|
||||
for (size_t i = 0; i < meshes.size(); ++i) {
|
||||
FarPatchTables const *ptables = meshes[i]->GetPatchTables();
|
||||
FarPatchTables::PatchArray const *parray = ptables->GetPatchArray(*it);
|
||||
if (not parray) continue;
|
||||
|
||||
copyWithPtexFaceOffset(std::back_inserter(result->_paramTable),
|
||||
ptables->_paramTable,
|
||||
parray->GetPatchIndex(),
|
||||
parray->GetNumPatches(), ptexFaceOffset);
|
||||
|
||||
ptexFaceOffset += meshes[i]->GetNumPtexFaces();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
157
opensubdiv/far/patchParam.h
Normal file
157
opensubdiv/far/patchParam.h
Normal file
@ -0,0 +1,157 @@
|
||||
//
|
||||
// Copyright (C) Pixar. All rights reserved.
|
||||
//
|
||||
// This license governs use of the accompanying software. If you
|
||||
// use the software, you accept this license. If you do not accept
|
||||
// the license, do not use the software.
|
||||
//
|
||||
// 1. Definitions
|
||||
// The terms "reproduce," "reproduction," "derivative works," and
|
||||
// "distribution" have the same meaning here as under U.S.
|
||||
// copyright law. A "contribution" is the original software, or
|
||||
// any additions or changes to the software.
|
||||
// A "contributor" is any person or entity that distributes its
|
||||
// contribution under this license.
|
||||
// "Licensed patents" are a contributor's patent claims that read
|
||||
// directly on its contribution.
|
||||
//
|
||||
// 2. Grant of Rights
|
||||
// (A) Copyright Grant- Subject to the terms of this license,
|
||||
// including the license conditions and limitations in section 3,
|
||||
// each contributor grants you a non-exclusive, worldwide,
|
||||
// royalty-free copyright license to reproduce its contribution,
|
||||
// prepare derivative works of its contribution, and distribute
|
||||
// its contribution or any derivative works that you create.
|
||||
// (B) Patent Grant- Subject to the terms of this license,
|
||||
// including the license conditions and limitations in section 3,
|
||||
// each contributor grants you a non-exclusive, worldwide,
|
||||
// royalty-free license under its licensed patents to make, have
|
||||
// made, use, sell, offer for sale, import, and/or otherwise
|
||||
// dispose of its contribution in the software or derivative works
|
||||
// of the contribution in the software.
|
||||
//
|
||||
// 3. Conditions and Limitations
|
||||
// (A) No Trademark License- This license does not grant you
|
||||
// rights to use any contributor's name, logo, or trademarks.
|
||||
// (B) If you bring a patent claim against any contributor over
|
||||
// patents that you claim are infringed by the software, your
|
||||
// patent license from such contributor to the software ends
|
||||
// automatically.
|
||||
// (C) If you distribute any portion of the software, you must
|
||||
// retain all copyright, patent, trademark, and attribution
|
||||
// notices that are present in the software.
|
||||
// (D) If you distribute any portion of the software in source
|
||||
// code form, you may do so only under this license by including a
|
||||
// complete copy of this license with your distribution. If you
|
||||
// distribute any portion of the software in compiled or object
|
||||
// code form, you may only do so under a license that complies
|
||||
// with this license.
|
||||
// (E) The software is licensed "as-is." You bear the risk of
|
||||
// using it. The contributors give no express warranties,
|
||||
// guarantees or conditions. You may have additional consumer
|
||||
// rights under your local laws which this license cannot change.
|
||||
// To the extent permitted under your local laws, the contributors
|
||||
// exclude the implied warranties of merchantability, fitness for
|
||||
// a particular purpose and non-infringement.
|
||||
//
|
||||
|
||||
#ifndef FAR_PATCH_PARAM_H
|
||||
#define FAR_PATCH_PARAM_H
|
||||
|
||||
namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
/// \brief Local patch parameterization descriptor
|
||||
///
|
||||
/// Coarse mesh faces are split into sets of patches in both uniform and feature
|
||||
/// adaptive modes. In order to maintain local patch parameterization, it is
|
||||
/// necessary to retain some information, such as level of subdivision, face-
|
||||
/// winding status... This parameterization is directly applicable to ptex textures,
|
||||
/// but has to be remapped to a specific layout for uv textures.
|
||||
///
|
||||
/// Bitfield layout :
|
||||
///
|
||||
/// level:4 - the subdivision level of the patch
|
||||
/// nonquad:1; - whether the patch is the child of a non-quad face
|
||||
/// rotation:2; - patch rotations necessary to match CCW face-winding
|
||||
/// v:10; - log2 value of u parameter at first patch corner
|
||||
/// u:10; - log2 value of v parameter at first patch corner
|
||||
/// reserved1:5; - padding
|
||||
///
|
||||
/// Note : the bitfield is not expanded in the struct due to differences in how
|
||||
/// GPU & CPU compilers pack bit-fields and endian-ness.
|
||||
///
|
||||
struct FarPatchParam {
|
||||
unsigned int faceIndex:32; // Ptex face index
|
||||
|
||||
struct BitField {
|
||||
unsigned int field:32;
|
||||
|
||||
/// Sets the values of the bit fields
|
||||
///
|
||||
/// @param u value of the u parameter for the first corner of the face
|
||||
/// @param v value of the v parameter for the first corner of the face
|
||||
///
|
||||
/// @param rots rotations required to reproduce CCW face-winding
|
||||
/// @param depth subdivision level of the patch
|
||||
/// @param nonquad true if the root face is not a quad
|
||||
///
|
||||
void Set( short u, short v, unsigned char rots, unsigned char depth, bool nonquad ) {
|
||||
field = (u << 17) |
|
||||
(v << 7) |
|
||||
(rots << 5) |
|
||||
((nonquad ? 1:0) << 4) |
|
||||
(nonquad ? depth+1 : depth);
|
||||
}
|
||||
|
||||
/// Returns the log2 value of the u parameter at the top left corner of
|
||||
/// the patch
|
||||
unsigned short GetU() const { return (field >> 17) & 0x3ff; }
|
||||
|
||||
/// Returns the log2 value of the v parameter at the top left corner of
|
||||
/// the patch
|
||||
unsigned short GetV() const { return (field >> 7) & 0x3ff; }
|
||||
|
||||
/// Returns the rotation of the patch (the number of CCW parameter winding)
|
||||
unsigned char GetRotation() const { return (field >> 5) & 0x3; }
|
||||
|
||||
/// True if the parent coarse face is a non-quad
|
||||
bool NonQuadRoot() const { return (field >> 4) & 0x1; }
|
||||
|
||||
/// Returns the level of subdivision of the patch
|
||||
unsigned char GetDepth() const { return (field & 0xf); }
|
||||
|
||||
/// Resets the values to 0
|
||||
void Clear() { field = 0; }
|
||||
|
||||
} bitField;
|
||||
|
||||
/// Sets the values of the bit fields
|
||||
///
|
||||
/// @param faceid ptex face index
|
||||
///
|
||||
/// @param u value of the u parameter for the first corner of the face
|
||||
/// @param v value of the v parameter for the first corner of the face
|
||||
///
|
||||
/// @param rots rotations required to reproduce CCW face-winding
|
||||
/// @param depth subdivision level of the patch
|
||||
/// @param nonquad true if the root face is not a quad
|
||||
///
|
||||
void Set( unsigned int faceid, short u, short v, unsigned char rots, unsigned char depth, bool nonquad ) {
|
||||
faceIndex = faceid;
|
||||
bitField.Set(u,v,rots,depth,nonquad);
|
||||
}
|
||||
|
||||
/// Resets everything to 0
|
||||
void Clear() {
|
||||
faceIndex = 0;
|
||||
bitField.Clear();
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
using namespace OPENSUBDIV_VERSION;
|
||||
|
||||
} // end namespace OpenSubdiv
|
||||
|
||||
#endif /* FAR_PATCH_PARAM */
|
@ -60,139 +60,16 @@
|
||||
|
||||
#include "../version.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "../far/patchParam.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
/// \brief Flattened ptex coordinates indexing system
|
||||
///
|
||||
/// Bitfield layout :
|
||||
///
|
||||
/// level:4 - the subdivision level of the patch
|
||||
/// nonquad:1; - whether the patch is the child of a non-quad face
|
||||
/// rotation:2; - patch rotations necessary to match CCW face-winding
|
||||
/// v:10; - log2 value of u parameter at first patch corner
|
||||
/// u:10; - log2 value of v parameter at first patch corner
|
||||
/// reserved1:5; - padding
|
||||
///
|
||||
/// Note : the bitfield is not expanded in the struct due to differences in how
|
||||
/// GPU & CPU compilers pack bit-fields and endian-ness.
|
||||
///
|
||||
struct FarPtexCoord {
|
||||
unsigned int faceIndex:32; // Ptex face index
|
||||
|
||||
struct BitField {
|
||||
unsigned int field:32;
|
||||
|
||||
/// Sets the values of the bit fields
|
||||
///
|
||||
/// @param u value of the u parameter for the first corner of the face
|
||||
/// @param v value of the v parameter for the first corner of the face
|
||||
///
|
||||
/// @param rots rotations required to reproduce CCW face-winding
|
||||
/// @param depth subdivision level of the patch
|
||||
/// @param nonquad true if the root face is not a quad
|
||||
///
|
||||
void Set( short u, short v, unsigned char rots, unsigned char depth, bool nonquad ) {
|
||||
field = (u << 17) |
|
||||
(v << 7) |
|
||||
(rots << 5) |
|
||||
((nonquad ? 1:0) << 4) |
|
||||
(nonquad ? depth+1 : depth);
|
||||
}
|
||||
|
||||
/// Returns the log2 value of the u parameter at the top left corner of
|
||||
/// the patch
|
||||
unsigned short GetU() const { return (field >> 17) & 0x3ff; }
|
||||
|
||||
/// Returns the log2 value of the v parameter at the top left corner of
|
||||
/// the patch
|
||||
unsigned short GetV() const { return (field >> 7) & 0x3ff; }
|
||||
|
||||
/// Returns the rotation of the patch (the number of CCW parameter winding)
|
||||
unsigned char GetRotation() const { return (field >> 5) & 0x3; }
|
||||
|
||||
/// True if the parent coarse face is a non-quad
|
||||
bool NonQuadRoot() const { return (field >> 4) & 0x1; }
|
||||
|
||||
/// Returns the level of subdivision of the patch
|
||||
unsigned char GetDepth() const { return (field & 0xf); }
|
||||
|
||||
/// Resets the values to 0
|
||||
void Clear() { field = 0; }
|
||||
|
||||
} bitField;
|
||||
|
||||
/// Sets the values of the bit fields
|
||||
///
|
||||
/// @param faceid ptex face index
|
||||
///
|
||||
/// @param u value of the u parameter for the first corner of the face
|
||||
/// @param v value of the v parameter for the first corner of the face
|
||||
///
|
||||
/// @param rots rotations required to reproduce CCW face-winding
|
||||
/// @param depth subdivision level of the patch
|
||||
/// @param nonquad true if the root face is not a quad
|
||||
///
|
||||
void Set( unsigned int faceid, short u, short v, unsigned char rots, unsigned char depth, bool nonquad ) {
|
||||
faceIndex = faceid;
|
||||
bitField.Set(u,v,rots,depth,nonquad);
|
||||
}
|
||||
|
||||
/// Resets everything to 0
|
||||
void Clear() {
|
||||
faceIndex = 0;
|
||||
bitField.Clear();
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Indices for multi-mesh patch arrays
|
||||
// XXXX manuelk : we should probably derive FarMultiPatchTables for multi-meshes
|
||||
struct FarPatchCount {
|
||||
int nonPatch; // reserved for uniform and loop
|
||||
int regular;
|
||||
int boundary;
|
||||
int corner;
|
||||
int gregory;
|
||||
int boundaryGregory;
|
||||
int transitionRegular[5];
|
||||
int transitionBoundary[5][4];
|
||||
int transitionCorner[5][4];
|
||||
|
||||
/// Constructor.
|
||||
FarPatchCount() {
|
||||
nonPatch = regular = boundary = corner = gregory = boundaryGregory = 0;
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
transitionRegular[i] = 0;
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
transitionBoundary[i][j] = 0;
|
||||
transitionCorner[i][j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds the indices from another patchTable.
|
||||
void Append(FarPatchCount const &p) {
|
||||
nonPatch += p.nonPatch;
|
||||
regular += p.regular;
|
||||
boundary += p.boundary;
|
||||
corner += p.corner;
|
||||
gregory += p.gregory;
|
||||
boundaryGregory += p.boundaryGregory;
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
transitionRegular[i] += p.transitionRegular[i];
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
transitionBoundary[i][j] += p.transitionBoundary[i][j];
|
||||
transitionCorner[i][j] += p.transitionCorner[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<FarPatchCount> FarPatchCountVector;
|
||||
|
||||
/// \brief Container for patch vertex indices tables
|
||||
///
|
||||
/// FarPatchTables contain the lists of vertices for each patch of an adaptive
|
||||
@ -201,50 +78,379 @@ typedef std::vector<FarPatchCount> FarPatchCountVector;
|
||||
class FarPatchTables {
|
||||
|
||||
public:
|
||||
/// Patch table : (vert indices, patch level) pairs
|
||||
typedef std::pair<std::vector<unsigned int>,
|
||||
std::vector<unsigned char> > PTable;
|
||||
|
||||
typedef std::vector<int> VertexValenceTable;
|
||||
typedef std::vector<unsigned int> PTable;
|
||||
typedef std::vector<int> VertexValenceTable;
|
||||
typedef std::vector<unsigned int> QuadOffsetTable;
|
||||
typedef std::vector<FarPatchParam> PatchParamTable;
|
||||
typedef std::vector<float> FVarDataTable;
|
||||
|
||||
typedef std::vector<unsigned int> QuadOffsetTable;
|
||||
enum Type {
|
||||
NON_PATCH = 0, // undefined
|
||||
|
||||
POINTS, // points (useful for cage drawing)
|
||||
LINES, // lines (useful for cage drawing)
|
||||
|
||||
QUADS, // bilinear quads-only patches
|
||||
TRIANGLES, // bilinear triangles-only mesh
|
||||
|
||||
LOOP, // Loop patch (unsupported)
|
||||
|
||||
typedef std::vector<FarPtexCoord> PtexCoordinateTable;
|
||||
REGULAR, // feature-adaptive bicubic patches
|
||||
BOUNDARY,
|
||||
CORNER,
|
||||
GREGORY,
|
||||
GREGORY_BOUNDARY
|
||||
};
|
||||
|
||||
typedef std::vector<float> FVarDataTable;
|
||||
enum TransitionPattern {
|
||||
NON_TRANSITION = 0,
|
||||
PATTERN0,
|
||||
PATTERN1,
|
||||
PATTERN2,
|
||||
PATTERN3,
|
||||
PATTERN4,
|
||||
};
|
||||
|
||||
/// \brief Describes the type of a patch
|
||||
///
|
||||
/// Uniquely identifies all the types of patches in a mesh :
|
||||
///
|
||||
/// * Raw polygon meshes are identified as POLYGONS and can contain faces
|
||||
/// with arbitrary number of vertices
|
||||
///
|
||||
/// * Uniformly subdivided meshes contain bilinear patches of either QUADS
|
||||
/// or TRIANGLES
|
||||
///
|
||||
/// * Adaptively subdivided meshes contain bicubic patches of types REGULAR,
|
||||
/// BOUNDARY, CORNER, GREGORY, GREGORY_BOUNDARY. These bicubic patches are
|
||||
/// also further distinguished by a transition pattern as well as a rotational
|
||||
/// orientation.
|
||||
///
|
||||
/// An iterator class is provided as a convenience to enumerate over the set
|
||||
/// of valid feature adaptive patch descriptors.
|
||||
///
|
||||
class Descriptor {
|
||||
|
||||
public:
|
||||
/// Default constructor.
|
||||
Descriptor() :
|
||||
_type(NON_PATCH), _pattern(NON_TRANSITION), _rotation(0) {}
|
||||
|
||||
/// Constructor
|
||||
Descriptor(int type, int pattern, unsigned char rotation) :
|
||||
_type(type), _pattern(pattern), _rotation(rotation) { }
|
||||
|
||||
/// Copy Constructor
|
||||
Descriptor( Descriptor const & d ) :
|
||||
_type(d.GetType()), _pattern(d.GetPattern()), _rotation(d.GetRotation()) { }
|
||||
|
||||
/// Returns the type of the patch
|
||||
Type GetType() const {
|
||||
return (Type)_type;
|
||||
}
|
||||
|
||||
/// Returns the transition pattern of the patch if any (5 types)
|
||||
TransitionPattern GetPattern() const {
|
||||
return (TransitionPattern)_pattern;
|
||||
}
|
||||
|
||||
/// Returns the rotation of the patch (4 rotations)
|
||||
unsigned char GetRotation() const {
|
||||
return _rotation;
|
||||
}
|
||||
|
||||
/// Returns the number of control vertices expected for a patch of the
|
||||
/// type described
|
||||
static short GetNumControlVertices( Type t );
|
||||
|
||||
/// Returns the number of control vertices expected for a patch of the
|
||||
/// type described
|
||||
short GetNumControlVertices() const {
|
||||
return GetNumControlVertices( this->GetType() );
|
||||
}
|
||||
|
||||
/// Iterates through the patches in the following preset order
|
||||
///
|
||||
/// NON_TRANSITION ( REGULAR
|
||||
/// BOUNDARY
|
||||
/// CORNER
|
||||
/// GREGORY
|
||||
/// GREGORY_BOUNDARY )
|
||||
///
|
||||
/// PATTERN0 ( REGULAR
|
||||
/// BOUNDARY ROT0 ROT1 ROT2 ROT3
|
||||
/// CORNER ROT0 ROT1 ROT2 ROT3 )
|
||||
///
|
||||
/// PATTERN1 ( REGULAR
|
||||
/// BOUNDARY ROT0 ROT1 ROT2 ROT3
|
||||
/// CORNER ROT0 ROT1 ROT2 ROT3 )
|
||||
/// ...
|
||||
///
|
||||
/// NON_TRANSITION NON_PATCH ROT0 (end)
|
||||
///
|
||||
Descriptor & operator ++ ();
|
||||
|
||||
/// Allows ordering of patches by type
|
||||
bool operator < ( Descriptor const other ) const;
|
||||
|
||||
/// True if the descriptors are identical
|
||||
bool operator == ( Descriptor const other ) const;
|
||||
|
||||
/// Descriptor Iterator
|
||||
class iterator;
|
||||
|
||||
/// Returns an iterator to the first type of patch (REGULAR NON_TRANSITION ROT0)
|
||||
static iterator begin() {
|
||||
return iterator( Descriptor(REGULAR, NON_TRANSITION, 0) );
|
||||
}
|
||||
|
||||
/// Returns an iterator to the end of the list of patch types (NON_PATCH)
|
||||
static iterator end() {
|
||||
return iterator( Descriptor() );
|
||||
}
|
||||
|
||||
private:
|
||||
template <class T> friend class FarPatchTablesFactory;
|
||||
friend class iterator;
|
||||
|
||||
unsigned int _type:4;
|
||||
unsigned int _pattern:3;
|
||||
unsigned int _rotation:2;
|
||||
};
|
||||
|
||||
|
||||
/// Returns a FarTable containing the vertex indices for all the Full Regular patches
|
||||
PTable const & GetFullRegularPatches() const { return _full._R_IT; }
|
||||
/// \brief Descriptor iterator class
|
||||
class Descriptor::iterator {
|
||||
public:
|
||||
/// Constructor
|
||||
iterator() {}
|
||||
|
||||
/// Returns a FarTable containing the vertex indices for all the Full Boundary patches
|
||||
PTable const & GetFullBoundaryPatches() const { return _full._B_IT; }
|
||||
/// Copy Constructor
|
||||
iterator(Descriptor desc) : pos(desc) { }
|
||||
|
||||
/// Iteration increment operator
|
||||
iterator & operator ++ () { ++pos; return *this; }
|
||||
|
||||
/// True of the two descriptors are identical
|
||||
bool operator == ( iterator const & other ) const { return (pos==other.pos); }
|
||||
|
||||
/// Returns a FarTable containing the vertex indices for all the Full Corner patches
|
||||
PTable const & GetFullCornerPatches() const { return _full._C_IT; }
|
||||
/// True if the two descriptors are different
|
||||
bool operator != ( iterator const & other ) const { return not (*this==other); }
|
||||
|
||||
/// Dereferencing operator
|
||||
Descriptor * operator -> () { return &pos; }
|
||||
|
||||
/// Dereferencing operator
|
||||
Descriptor & operator * () { return pos; }
|
||||
|
||||
/// Returns a FarTable containing the vertex indices for all the Full Gregory Regular patches
|
||||
PTable const & GetFullGregoryPatches() const { return _full._G_IT; }
|
||||
private:
|
||||
Descriptor pos;
|
||||
};
|
||||
|
||||
/// Returns a FarTable containing the vertex indices for all the Full Gregory Boundary patches
|
||||
PTable const & GetFullBoundaryGregoryPatches() const { return _full._G_B_IT; }
|
||||
|
||||
/// \brief Describes an array of patches of the same type
|
||||
class PatchArray {
|
||||
|
||||
public:
|
||||
/// Constructor.
|
||||
///
|
||||
/// @param desc descriptor information for the patches in
|
||||
/// the array
|
||||
///
|
||||
/// @param vertIndex absolute index to the first control vertex
|
||||
/// of the first patch in the PTable
|
||||
///
|
||||
/// @param patchIndex absolute index of the first patch in the
|
||||
/// array
|
||||
///
|
||||
/// @param npatches number of patches in the array
|
||||
///
|
||||
/// @param quadOffsetIndex absolute index of the first quad offset
|
||||
/// entry
|
||||
///
|
||||
PatchArray( Descriptor desc, unsigned int vertIndex, unsigned int patchIndex, unsigned int npatches, unsigned int quadOffsetIndex ) :
|
||||
_desc(desc), _range(vertIndex, patchIndex, npatches, quadOffsetIndex) { }
|
||||
|
||||
/// Returns a patch descriptor defining the type of patches in the array
|
||||
Descriptor GetDescriptor() const {
|
||||
return _desc;
|
||||
}
|
||||
|
||||
/// \brief Describes the range of patches in a PatchArray
|
||||
struct ArrayRange {
|
||||
|
||||
/// Constructor
|
||||
///
|
||||
/// @param vertIndex absolute index to the first control vertex
|
||||
/// of the first patch in the PTable
|
||||
///
|
||||
/// @param patchIndex absolute index of the first patch in the
|
||||
/// array
|
||||
///
|
||||
/// @param npatches number of patches in the array
|
||||
///
|
||||
/// @param quadOffsetIndex absolute index of the first quad offset
|
||||
/// entry
|
||||
///
|
||||
ArrayRange( unsigned int vertIndex, unsigned int patchIndex, unsigned int npatches, unsigned int quadOffsetIndex ) :
|
||||
vertIndex(vertIndex), patchIndex(patchIndex), npatches(npatches), quadOffsetIndex(quadOffsetIndex) { }
|
||||
|
||||
unsigned int vertIndex, // absolute index to the first control vertex of the first patch in the PTable
|
||||
patchIndex, // absolute index of the first patch in the array
|
||||
npatches, // number of patches in the array
|
||||
quadOffsetIndex; // absolute index of the first quad offset entry
|
||||
};
|
||||
|
||||
/// Returns a array range struct
|
||||
ArrayRange const & GetArrayRange() const {
|
||||
return _range;
|
||||
}
|
||||
|
||||
/// Returns the index of the first control vertex of the first patch
|
||||
/// of this array in the global PTable
|
||||
unsigned int GetVertIndex() const {
|
||||
return _range.vertIndex;
|
||||
}
|
||||
|
||||
/// Returns the global index of the first patch in this array (Used to
|
||||
/// access param / fvar table data)
|
||||
unsigned int GetPatchIndex() const {
|
||||
return _range.patchIndex;
|
||||
}
|
||||
|
||||
/// Returns the number of patches in the array
|
||||
unsigned int GetNumPatches() const {
|
||||
return _range.npatches;
|
||||
}
|
||||
|
||||
unsigned int GetQuadOffsetIndex() const {
|
||||
return _range.quadOffsetIndex;
|
||||
}
|
||||
|
||||
private:
|
||||
template <class T> friend class FarPatchTablesFactory;
|
||||
|
||||
Descriptor _desc; // type of patches in the array
|
||||
|
||||
ArrayRange _range; // index locators in the array
|
||||
};
|
||||
|
||||
typedef std::vector<PatchArray> PatchArrayVector;
|
||||
|
||||
|
||||
/// Unique patch identifier within a PatchArrayVector
|
||||
struct PatchHandle {
|
||||
|
||||
unsigned int array, // OsdPatchArray containing the patch
|
||||
vertexOffset, // Offset to the first CV of the patch
|
||||
serialIndex; // Serialized Index of the patch
|
||||
};
|
||||
|
||||
|
||||
/// \brief Maps sub-patches to coarse faces
|
||||
class PatchMap {
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
PatchMap( FarPatchTables const & patchTables );
|
||||
|
||||
/// \brief Returns the number and list of patch indices for a given face.
|
||||
///
|
||||
/// PatchMaps map coarse faces to their childrn feature adaptive patches.
|
||||
/// Coarse faces are indexed using their ptex face ID to resolve parametric
|
||||
/// ambiguity on non-quad faces. Note : this "map" is actually a vector, so
|
||||
/// queries are O(1) order.
|
||||
///
|
||||
/// @param faceid the face index to search for
|
||||
///
|
||||
/// @param npatches the number of children patches found for the faceid
|
||||
///
|
||||
/// @param patches a set of pointers to the individual patch handles
|
||||
///
|
||||
bool GetChildPatchesHandles( int faceid, int * npatches, PatchHandle const ** patches ) const;
|
||||
|
||||
private:
|
||||
typedef std::multimap<unsigned int, PatchHandle> MultiMap;
|
||||
|
||||
// Patch handle allowing location of individual patch data inside patch
|
||||
// arrays or in serialized form
|
||||
std::vector<PatchHandle> _handles;
|
||||
|
||||
// offset to the first handle of the child patches for each coarse face
|
||||
std::vector<unsigned int> _offsets;
|
||||
};
|
||||
|
||||
/// Constructor
|
||||
///
|
||||
/// @param patchArrays Vector of descriptors and ranges for arrays of patches
|
||||
///
|
||||
/// @param patches Indices of the control vertices of the patches
|
||||
///
|
||||
/// @param vertexValences Vertex valance table
|
||||
///
|
||||
/// @param quadOffsets Quad offset table
|
||||
///
|
||||
/// @param patchParams Local patch parameterization
|
||||
///
|
||||
/// @param fvarData Face varying data table
|
||||
///
|
||||
/// @param maxValence Highest vertex valence allowed in the mesh
|
||||
///
|
||||
FarPatchTables(PatchArrayVector const & patchArrays,
|
||||
PTable const & patches,
|
||||
VertexValenceTable const * vertexValences,
|
||||
QuadOffsetTable const * quadOffsets,
|
||||
PatchParamTable const * patchParams,
|
||||
FVarDataTable const * fvarData,
|
||||
int maxValence);
|
||||
|
||||
/// Get the table of patch control vertices
|
||||
PTable const & GetPatchTable() const { return _patches; }
|
||||
|
||||
/// Returns a pointer to the array of patches matching the descriptor
|
||||
PatchArray const * GetPatchArray( Descriptor desc ) const {
|
||||
return const_cast<FarPatchTables *>(this)->findPatchArray( desc );
|
||||
}
|
||||
|
||||
/// Returns all arrays of patches
|
||||
PatchArrayVector const & GetPatchArrayVector() const {
|
||||
return _patchArrays;
|
||||
}
|
||||
|
||||
/// Returns a pointer to the vertex indices of uniformly subdivided faces
|
||||
///
|
||||
/// @param level the level of subdivision of the faces
|
||||
///
|
||||
/// @return a pointer to the first vertex index or NULL if the mesh
|
||||
/// is not uniformly subdivided or the level cannot be found.
|
||||
///
|
||||
unsigned int const * GetFaceVertices(int level) const;
|
||||
|
||||
/// Returns the number of faces in a uniformly subdivided mesh at a given level
|
||||
///
|
||||
/// @param level the level of subdivision of the faces
|
||||
///
|
||||
/// @return the number of faces in the mesh given the subdivision level
|
||||
/// or -1 if the mesh is not uniform or the level incorrect.
|
||||
///
|
||||
int GetNumFaces(int level) const;
|
||||
|
||||
/// Returns a vertex valence table used by Gregory patches
|
||||
VertexValenceTable const & GetVertexValenceTable() const { return _vertexValenceTable; }
|
||||
|
||||
/// Returns a quad offsets table used by Gregory patches
|
||||
QuadOffsetTable const & GetQuadOffsetTable() const { return _quadOffsetTable; }
|
||||
|
||||
/// Returns a PatchParamTable for each type of patch
|
||||
PatchParamTable const & GetPatchParamTable() const { return _paramTable; }
|
||||
|
||||
/// Returns a FarTable containing the vertex indices for all the Transition Regular patches
|
||||
PTable const & GetTransitionRegularPatches(unsigned char pattern) const { return _transition[pattern]._R_IT; }
|
||||
|
||||
/// Returns a FarTable containing the vertex indices for all the Transition Boundary patches
|
||||
PTable const & GetTransitionBoundaryPatches(unsigned char pattern, unsigned char rot) const { return _transition[pattern]._B_IT[rot]; }
|
||||
|
||||
/// Returns a FarTable containing the vertex indices for all the Transition Corner patches
|
||||
PTable const & GetTransitionCornerPatches(unsigned char pattern, unsigned char rot) const { return _transition[pattern]._C_IT[rot]; }
|
||||
|
||||
/// Returns an FVarDataTable for each type of patch
|
||||
/// The data is stored as a run of totalFVarWidth floats per-vertex per-face
|
||||
/// e.g.: for UV data it has the structure of float[p][4][2] where
|
||||
/// p=primitiveID and totalFVarWidth=2:
|
||||
/// [ [ uv uv uv uv ] [ uv uv uv uv ] [ ... ] ]
|
||||
/// prim 0 prim 1
|
||||
FVarDataTable const & GetFVarDataTable() const { return _fvarTable; }
|
||||
|
||||
/// Ringsize of Regular Patches in table.
|
||||
static int GetRegularPatchRingsize() { return 16; }
|
||||
@ -258,161 +464,298 @@ public:
|
||||
/// Ringsize of Gregory (and Gregory Boundary) Patches in table.
|
||||
static int GetGregoryPatchRingsize() { return 4; }
|
||||
|
||||
|
||||
/// Returns a PtexCoordinateTable for each type of patch
|
||||
PtexCoordinateTable const & GetFullRegularPtexCoordinates() const { return _full._R_PTX; }
|
||||
|
||||
PtexCoordinateTable const & GetFullBoundaryPtexCoordinates() const { return _full._B_PTX; }
|
||||
|
||||
PtexCoordinateTable const & GetFullCornerPtexCoordinates() const { return _full._C_PTX; }
|
||||
|
||||
PtexCoordinateTable const & GetFullGregoryPtexCoordinates() const { return _full._G_PTX; }
|
||||
|
||||
PtexCoordinateTable const & GetFullBoundaryGregoryPtexCoordinates() const { return _full._G_B_PTX; }
|
||||
|
||||
PtexCoordinateTable const & GetTransitionRegularPtexCoordinates(unsigned char pattern) const { return _transition[pattern]._R_PTX; }
|
||||
|
||||
PtexCoordinateTable const & GetTransitionBoundaryPtexCoordinates(unsigned char pattern, unsigned char rot) const { return _transition[pattern]._B_PTX[rot]; }
|
||||
|
||||
PtexCoordinateTable const & GetTransitionCornerPtexCoordinates(unsigned char pattern, unsigned char rot) const { return _transition[pattern]._C_PTX[rot]; }
|
||||
|
||||
/// Returns an FVarDataTable for each type of patch
|
||||
FVarDataTable const & GetFullRegularFVarData() const { return _full._R_FVD; }
|
||||
|
||||
FVarDataTable const & GetFullBoundaryFVarData() const { return _full._B_FVD; }
|
||||
|
||||
FVarDataTable const & GetFullCornerFVarData() const { return _full._C_FVD; }
|
||||
|
||||
FVarDataTable const & GetFullGregoryFVarData() const { return _full._G_FVD; }
|
||||
|
||||
FVarDataTable const & GetFullBoundaryGregoryFVarData() const { return _full._G_B_FVD; }
|
||||
|
||||
FVarDataTable const & GetTransitionRegularFVarData(unsigned char pattern) const { return _transition[pattern]._R_FVD; }
|
||||
|
||||
FVarDataTable const & GetTransitionBoundaryFVarData(unsigned char pattern, unsigned char rot) const { return _transition[pattern]._B_FVD[rot]; }
|
||||
|
||||
FVarDataTable const & GetTransitionCornerFVarData(unsigned char pattern, unsigned char rot) const { return _transition[pattern]._C_FVD[rot]; }
|
||||
|
||||
/// Returns the total number of patches stored in the tables
|
||||
size_t GetNumPatches() const;
|
||||
int GetNumPatches() const;
|
||||
|
||||
/// Returns the total number of control vertex indices in the tables
|
||||
size_t GetNumControlVertices() const;
|
||||
int GetNumControlVertices() const;
|
||||
|
||||
/// Returns max vertex valence
|
||||
int GetMaxValence() const { return _maxValence; }
|
||||
|
||||
/// Returns PatchCounts
|
||||
FarPatchCountVector const & GetPatchCounts() const { return _patchCounts; }
|
||||
|
||||
|
||||
/// True if the patches are of feature adaptive types
|
||||
bool IsFeatureAdaptive() const;
|
||||
|
||||
private:
|
||||
|
||||
template <class T> friend class FarPatchTablesFactory;
|
||||
template <class T, class U> friend class FarMultiMeshFactory;
|
||||
|
||||
// Returns the array of patches of type "desc", or NULL if there aren't any in the primitive
|
||||
PatchArray * findPatchArray( Descriptor desc );
|
||||
|
||||
// Private constructor
|
||||
FarPatchTables( int maxvalence ) : _maxValence(maxvalence) { }
|
||||
|
||||
// FarTables for full / end patches
|
||||
struct Patches {
|
||||
PTable _R_IT, // regular patches vertex indices table
|
||||
_B_IT, // boundary
|
||||
_C_IT, // corner
|
||||
_G_IT, // gregory
|
||||
_G_B_IT; // gregory
|
||||
|
||||
PtexCoordinateTable _R_PTX, // regular patches ptex indices table
|
||||
_B_PTX,
|
||||
_C_PTX,
|
||||
_G_PTX,
|
||||
_G_B_PTX;
|
||||
|
||||
FVarDataTable _R_FVD, // regular patches face-varying indices table
|
||||
_B_FVD,
|
||||
_C_FVD,
|
||||
_G_FVD,
|
||||
_G_B_FVD;
|
||||
};
|
||||
|
||||
// FarTables for transition patches
|
||||
struct TPatches {
|
||||
PTable _R_IT, // regular patches
|
||||
_B_IT[4], // boundary patches (4 rotations)
|
||||
_C_IT[4]; // corner patches (4 rotations)
|
||||
|
||||
PtexCoordinateTable _R_PTX,
|
||||
_B_PTX[4],
|
||||
_C_PTX[4];
|
||||
|
||||
FVarDataTable _R_FVD,
|
||||
_B_FVD[4],
|
||||
_C_FVD[4];
|
||||
};
|
||||
|
||||
Patches _full; // full patches tables
|
||||
PatchArrayVector _patchArrays; // Vector of descriptors for arrays of patches
|
||||
|
||||
TPatches _transition[5]; // transition patches tables
|
||||
PTable _patches; // Indices of the control vertices of the patches
|
||||
|
||||
// XXXX manuelk : Greg. patch tables need to be localized to Gregory CVs only.
|
||||
VertexValenceTable _vertexValenceTable; // vertex valence table (for Gregory patches)
|
||||
|
||||
QuadOffsetTable _quadOffsetTable; // quad offsets table (for Gregory patches)
|
||||
|
||||
PatchParamTable _paramTable;
|
||||
|
||||
// vertex valence table (for Gregory patches)
|
||||
VertexValenceTable _vertexValenceTable;
|
||||
|
||||
// quad offsets table (for Gregory patches)
|
||||
QuadOffsetTable _quadOffsetTable;
|
||||
FVarDataTable _fvarTable;
|
||||
|
||||
// highest vertex valence allowed in the mesh (used for Gregory
|
||||
// vertexValance & quadOffset talbes)
|
||||
// vertexValance & quadOffset tables)
|
||||
int _maxValence;
|
||||
|
||||
// vector of counters for aggregated patch tables used by multi-meshes
|
||||
FarPatchCountVector _patchCounts;
|
||||
};
|
||||
|
||||
// Returns the total number of patches stored in the tables
|
||||
inline size_t
|
||||
FarPatchTables::GetNumPatches() const {
|
||||
// Constructor
|
||||
inline
|
||||
FarPatchTables::FarPatchTables(PatchArrayVector const & patchArrays,
|
||||
PTable const & patches,
|
||||
VertexValenceTable const * vertexValences,
|
||||
QuadOffsetTable const * quadOffsets,
|
||||
PatchParamTable const * patchParams,
|
||||
FVarDataTable const * fvarData,
|
||||
int maxValence) :
|
||||
_patchArrays(patchArrays),
|
||||
_patches(patches),
|
||||
_maxValence(maxValence) {
|
||||
|
||||
// We can use directly the size of the levels table ("second") because
|
||||
// there is 1 value per patch
|
||||
size_t count = _full._R_IT.second.size() +
|
||||
_full._B_IT.second.size() +
|
||||
_full._C_IT.second.size() +
|
||||
_full._G_IT.second.size() +
|
||||
_full._G_B_IT.second.size();
|
||||
// copy other tables if exist
|
||||
if (vertexValences)
|
||||
_vertexValenceTable = *vertexValences;
|
||||
if (quadOffsets)
|
||||
_quadOffsetTable = *quadOffsets;
|
||||
if (patchParams)
|
||||
_paramTable = *patchParams;
|
||||
if (fvarData)
|
||||
_fvarTable = *fvarData;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
count += _transition[i]._R_IT.second.size();
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
count += _transition[i]._B_IT[j].second.size()+
|
||||
_transition[i]._C_IT[j].second.size();
|
||||
inline bool
|
||||
FarPatchTables::IsFeatureAdaptive() const {
|
||||
return ((not _vertexValenceTable.empty()) and (not _quadOffsetTable.empty()));
|
||||
}
|
||||
|
||||
// Returns the number of control vertices expected for a patch of this type
|
||||
inline short
|
||||
FarPatchTables::Descriptor::GetNumControlVertices( FarPatchTables::Type type ) {
|
||||
switch (type) {
|
||||
case REGULAR : return FarPatchTables::GetRegularPatchRingsize();
|
||||
case QUADS : return 4;
|
||||
case GREGORY :
|
||||
case GREGORY_BOUNDARY : return FarPatchTables::GetGregoryPatchRingsize();
|
||||
case BOUNDARY : return FarPatchTables::GetBoundaryPatchRingsize();
|
||||
case CORNER : return FarPatchTables::GetCornerPatchRingsize();
|
||||
case TRIANGLES : return 3;
|
||||
case LINES : return 2;
|
||||
case POINTS : return 1;
|
||||
default : return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Iterates in order through the patch types, patterns and rotation in a preset order
|
||||
inline FarPatchTables::Descriptor &
|
||||
FarPatchTables::Descriptor::operator ++ () {
|
||||
|
||||
if (GetPattern()==NON_TRANSITION) {
|
||||
if (GetType()==GREGORY_BOUNDARY) {
|
||||
_type=REGULAR;
|
||||
++_pattern;
|
||||
} else
|
||||
++_type;
|
||||
} else {
|
||||
|
||||
switch (GetType()) {
|
||||
case REGULAR : ++_type;
|
||||
_rotation=0;
|
||||
break;
|
||||
|
||||
case BOUNDARY : if (GetRotation()==3) {
|
||||
++_type;
|
||||
_rotation=0;
|
||||
} else {
|
||||
++_rotation;
|
||||
}; break;
|
||||
|
||||
case CORNER : if (GetRotation()==3) {
|
||||
if (GetPattern()!=PATTERN4) {
|
||||
_type=REGULAR;
|
||||
_rotation=0;
|
||||
++_pattern;
|
||||
} else {
|
||||
*this = Descriptor();
|
||||
}
|
||||
} else {
|
||||
++_rotation;
|
||||
}; break;
|
||||
|
||||
case NON_PATCH : break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
return count;
|
||||
// Constructor
|
||||
inline
|
||||
FarPatchTables::PatchMap::PatchMap( FarPatchTables const & patchTables ) {
|
||||
|
||||
// Create a PatchHandle for each patch in the primitive
|
||||
|
||||
int npatches = (int)patchTables.GetNumPatches();
|
||||
_handles.reserve(npatches);
|
||||
|
||||
FarPatchTables::PatchArrayVector const & patchArrays =
|
||||
patchTables.GetPatchArrayVector();
|
||||
|
||||
FarPatchTables::PatchParamTable const & paramTable =
|
||||
patchTables.GetPatchParamTable();
|
||||
assert( not paramTable.empty() );
|
||||
|
||||
int nfaces =0;
|
||||
MultiMap mmap;
|
||||
|
||||
for (int arrayid = 0; arrayid < (int)patchArrays.size(); ++arrayid) {
|
||||
|
||||
FarPatchTables::PatchArray const & pa = patchArrays[arrayid];
|
||||
|
||||
int ringsize = pa.GetDescriptor().GetNumControlVertices();
|
||||
|
||||
for (unsigned int j=0; j < pa.GetNumPatches(); ++j) {
|
||||
|
||||
int faceId = paramTable[pa.GetPatchIndex()+j].faceIndex;
|
||||
|
||||
PatchHandle handle = { arrayid, j*ringsize, (unsigned int)mmap.size() };
|
||||
|
||||
mmap.insert( std::pair<unsigned int, PatchHandle>(faceId, handle));
|
||||
|
||||
nfaces = std::max(nfaces, faceId);
|
||||
}
|
||||
}
|
||||
++nfaces;
|
||||
|
||||
_handles.resize( mmap.size() );
|
||||
_offsets.reserve( nfaces );
|
||||
_offsets.push_back(0);
|
||||
|
||||
// Serialize the multi-map
|
||||
|
||||
unsigned int handlesIdx = 0, faceId=mmap.begin()->first;
|
||||
|
||||
for (MultiMap::const_iterator it=mmap.begin(); it!=mmap.end(); ++it, ++handlesIdx) {
|
||||
|
||||
assert(it->first >= faceId);
|
||||
|
||||
if (it->first != faceId) {
|
||||
|
||||
faceId = it->first;
|
||||
|
||||
// position the offset marker to the new face
|
||||
_offsets.push_back( handlesIdx );
|
||||
}
|
||||
|
||||
// copy the patch id into the table
|
||||
_handles[handlesIdx] = it->second;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the number and list of patch indices for a given face.
|
||||
inline bool
|
||||
FarPatchTables::PatchMap::GetChildPatchesHandles( int faceid, int * npatches, PatchHandle const ** patches ) const {
|
||||
|
||||
if (_handles.empty() or _offsets.empty() or (faceid>=(int)_offsets.size()))
|
||||
return false;
|
||||
|
||||
*npatches = (faceid==(int)_offsets.size()-1 ?
|
||||
(unsigned int)_handles.size()-1 : _offsets[faceid+1]) - _offsets[faceid] + 1;
|
||||
|
||||
*patches = &_handles[ _offsets[faceid] ];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns a pointer to the vertex indices of uniformly subdivided faces
|
||||
inline unsigned int const *
|
||||
FarPatchTables::GetFaceVertices(int level) const {
|
||||
|
||||
if (IsFeatureAdaptive())
|
||||
return NULL;
|
||||
|
||||
PatchArrayVector const & parrays = GetPatchArrayVector();
|
||||
|
||||
if ( (level-1) < (int)parrays.size() ) {
|
||||
return &GetPatchTable()[ parrays[level-1].GetVertIndex() ];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Returns the number of faces in a uniformly subdivided mesh at a given level
|
||||
inline int
|
||||
FarPatchTables::GetNumFaces(int level) const {
|
||||
|
||||
if (IsFeatureAdaptive())
|
||||
return -1;
|
||||
|
||||
PatchArrayVector const & parrays = GetPatchArrayVector();
|
||||
|
||||
if ( (level-1) < (int)parrays.size() ) {
|
||||
return parrays[level-1].GetNumPatches();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Allows ordering of patches by type
|
||||
inline bool
|
||||
FarPatchTables::Descriptor::operator < ( Descriptor const other ) const {
|
||||
return _pattern < other._pattern or ((_pattern == other._pattern) and
|
||||
(_type < other._type or ((_type == other._type) and
|
||||
(_rotation < other._rotation))));
|
||||
}
|
||||
|
||||
// True if the descriptors are identical
|
||||
inline bool
|
||||
FarPatchTables::Descriptor::operator == ( Descriptor const other ) const {
|
||||
return _pattern == other._pattern and
|
||||
_type == other._type and
|
||||
_rotation == other._rotation;
|
||||
}
|
||||
|
||||
// Returns a pointer to the array of patches matching the descriptor
|
||||
inline FarPatchTables::PatchArray *
|
||||
FarPatchTables::findPatchArray( FarPatchTables::Descriptor desc ) {
|
||||
|
||||
for (int i=0; i<(int)_patchArrays.size(); ++i) {
|
||||
if (_patchArrays[i].GetDescriptor()==desc)
|
||||
return &_patchArrays[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Returns the total number of patches stored in the tables
|
||||
inline int
|
||||
FarPatchTables::GetNumPatches() const {
|
||||
|
||||
int result=0;
|
||||
for (int i=0; i<(int)_patchArrays.size(); ++i) {
|
||||
result += _patchArrays[i].GetNumPatches();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns the total number of control vertex indices in the tables
|
||||
inline size_t
|
||||
inline int
|
||||
FarPatchTables::GetNumControlVertices() const {
|
||||
|
||||
// The "first" table of a PTable contains the vertex indices of each
|
||||
// patch, so we can directly use those to tally our count.
|
||||
size_t count = _full._R_IT.first.size() +
|
||||
_full._B_IT.first.size() +
|
||||
_full._C_IT.first.size() +
|
||||
_full._G_IT.first.size() +
|
||||
_full._G_B_IT.first.size();
|
||||
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
count += _transition[i]._R_IT.first.size();
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
count += _transition[i]._B_IT[j].first.size()+
|
||||
_transition[i]._C_IT[j].first.size();
|
||||
}
|
||||
int result=0;
|
||||
for (int i=0; i<(int)_patchArrays.size(); ++i) {
|
||||
result += _patchArrays[i].GetDescriptor().GetNumControlVertices() *
|
||||
_patchArrays[i].GetNumPatches();
|
||||
}
|
||||
|
||||
return count;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -76,34 +76,60 @@ template <class T> class FarPatchTablesFactory {
|
||||
|
||||
protected:
|
||||
template <class X, class Y> friend class FarMeshFactory;
|
||||
|
||||
/// Factory constructor
|
||||
|
||||
/// Factory constructor for feature-adaptive meshes
|
||||
///
|
||||
/// @param mesh Hbr mesh to generate tables for
|
||||
/// @param mesh Hbr mesh to generate tables for
|
||||
///
|
||||
/// @param nfaces Number of faces in the mesh (cached for speed)
|
||||
/// @param nfaces Number of faces in the mesh (cached for speed)
|
||||
///
|
||||
/// @param remapTable Vertex remapping table generated by FarMeshFactory
|
||||
/// @param remapTable Vertex remapping table generated by FarMeshFactory
|
||||
///
|
||||
FarPatchTablesFactory( HbrMesh<T> const * mesh, int nfaces, std::vector<int> const & remapTable );
|
||||
|
||||
/// Returns a FarPatchTables instance
|
||||
/// Returns a feature-adaptive FarPatchTables instance
|
||||
///
|
||||
/// @param maxlevel Highest level of refinement processed
|
||||
/// @param maxlevel Highest level of refinement processed
|
||||
///
|
||||
/// @param maxvalence Maximum vertex valence in the mesh
|
||||
/// @param maxvalence Maximum vertex valence in the mesh
|
||||
///
|
||||
/// @param requirePtexCoordinate Flag for generating ptex coordinate
|
||||
/// @param requireFVarData Flag for generating face-varying data
|
||||
///
|
||||
/// @param requireFVarData Flag for generating face-varying data
|
||||
/// @return A new instance of FarPatchTables
|
||||
///
|
||||
/// @return a new instance of FarPatchTables
|
||||
///
|
||||
FarPatchTables * Create( int maxlevel, int maxvalence, bool requirePtexCoordinate=false,
|
||||
bool requireFVarData=false );
|
||||
FarPatchTables * Create( int maxlevel, int maxvalence, bool requireFVarData=false );
|
||||
|
||||
|
||||
typedef std::vector<std::vector< HbrFace<T> *> > FacesList;
|
||||
|
||||
/// Factory constructor for uniform meshes
|
||||
///
|
||||
/// @param mesh Hbr mesh to generate tables for
|
||||
///
|
||||
/// @param flist Vectors of pointers to HbrFace<T> for each level
|
||||
/// of subdivision
|
||||
///
|
||||
/// @param requireFVarData Flag for generating face-varying data
|
||||
///
|
||||
/// @param firstLevel First level of subdivision to use when building the
|
||||
/// PatchArrayVector (default -1 means only generate
|
||||
/// a single patch array for the highest level of
|
||||
/// subdivision)
|
||||
///
|
||||
/// @param remapTable Vertex remapping table generated by FarMeshFactory
|
||||
///
|
||||
/// @return A new instance of FarPatchTables
|
||||
///
|
||||
static FarPatchTables * Create( HbrMesh<T> const * mesh,
|
||||
FacesList const & flist,
|
||||
std::vector<int> const & remapTable,
|
||||
int firstLevel=-1,
|
||||
bool requireFVarData=false );
|
||||
|
||||
private:
|
||||
|
||||
typedef FarPatchTables::Descriptor Descriptor;
|
||||
|
||||
// Returns true if one of v's neighboring faces has vertices carrying the tag "wasTagged"
|
||||
static bool vertexHasTaggedNeighbors(HbrVertex<T> * v);
|
||||
|
||||
@ -119,13 +145,22 @@ private:
|
||||
// Populates the Gregory patch quad offsets table
|
||||
static void getQuadOffsets( HbrFace<T> * f, unsigned int * result );
|
||||
|
||||
// Iterates through the faces of an HbrMesh and tags the _adaptiveFlags on faces and vertices
|
||||
void tagAdaptivePatches( HbrMesh<T> const * mesh, int nfaces );
|
||||
|
||||
// Hbr mesh accessor
|
||||
HbrMesh<T> const * getMesh() const { return _mesh; }
|
||||
|
||||
// Number of faces in the Hbr mesh (cached for speed)
|
||||
int getNumFaces() const { return _nfaces; }
|
||||
|
||||
// The number of patch arrays in the mesh
|
||||
int getNumPatchArrays() const;
|
||||
|
||||
// Reserves tables based on the contents of the PatchArrayVector
|
||||
static void allocateTables( FarPatchTables * tables, int fvarwidth );
|
||||
|
||||
// A convenience container for the different types of feature adaptive patches
|
||||
template<class TYPE> struct PatchTypes {
|
||||
TYPE R, // regular patch
|
||||
B[4], // boundary patch (4 rotations)
|
||||
@ -133,17 +168,28 @@ private:
|
||||
G[2]; // gregory patch (boundary & corner)
|
||||
|
||||
PatchTypes() { memset(this, 0, sizeof(PatchTypes<TYPE>)); }
|
||||
|
||||
// Returns the number of patches based on the patch type in the descriptor
|
||||
TYPE & getValue( FarPatchTables::Descriptor desc );
|
||||
|
||||
// Counts the number of arrays required to store each type of patch used
|
||||
// in the primitive
|
||||
int getNumPatchArrays() const;
|
||||
};
|
||||
|
||||
typedef PatchTypes<unsigned int*> IndexPointers;
|
||||
typedef PatchTypes<unsigned char*> LevelPointers;
|
||||
typedef PatchTypes<FarPtexCoord *> PtexPointers;
|
||||
typedef PatchTypes<float *> FVarPointers;
|
||||
typedef PatchTypes<int> Counters;
|
||||
typedef PatchTypes<unsigned int*> CVPointers;
|
||||
typedef PatchTypes<FarPatchParam *> ParamPointers;
|
||||
typedef PatchTypes<float *> FVarPointers;
|
||||
typedef PatchTypes<int> Counter;
|
||||
|
||||
|
||||
Counters _fullCtr, // counters for full patches
|
||||
_transitionCtr[5]; // counters for transition patches
|
||||
// Creates a PatchArray and appends it to a vector and keeps track of both
|
||||
// vertex and patch offsets
|
||||
void pushPatchArray( FarPatchTables::Descriptor desc,
|
||||
FarPatchTables::PatchArrayVector & parray,
|
||||
Counter & counter,
|
||||
int * voffset, int * poffset, int * qoffset );
|
||||
|
||||
Counter _patchCtr[6]; // counters for full and transition patches
|
||||
|
||||
HbrMesh<T> const * _mesh;
|
||||
|
||||
@ -153,6 +199,8 @@ private:
|
||||
int _nfaces;
|
||||
};
|
||||
|
||||
// True if the surrounding faces are "tagged" (unsupported feature : watertight
|
||||
// critical patches)
|
||||
template <class T> bool
|
||||
FarPatchTablesFactory<T>::vertexHasTaggedNeighbors(HbrVertex<T> * v) {
|
||||
|
||||
@ -201,7 +249,90 @@ FarPatchTablesFactory<T>::computeCornerPatchRotation( HbrFace<T> * f ) {
|
||||
return rot;
|
||||
}
|
||||
|
||||
// Reserves tables based on the contents of the PatchArrayVector
|
||||
template <class T> void
|
||||
FarPatchTablesFactory<T>::allocateTables( FarPatchTables * tables, int fvarwidth ) {
|
||||
|
||||
int nverts = tables->GetNumControlVertices(),
|
||||
npatches = tables->GetNumPatches();
|
||||
|
||||
if (nverts==0 or npatches==0)
|
||||
return;
|
||||
|
||||
tables->_patches.resize( nverts );
|
||||
|
||||
tables->_paramTable.resize( npatches );
|
||||
|
||||
if (fvarwidth>0) {
|
||||
tables->_fvarTable.resize( npatches * 4 * fvarwidth );
|
||||
}
|
||||
}
|
||||
|
||||
// Uniform mesh factory (static function because it requires no cached state)
|
||||
template <class T> FarPatchTables *
|
||||
FarPatchTablesFactory<T>::Create( HbrMesh<T> const * mesh, FacesList const & flist, std::vector<int> const & remapTable, int firstLevel, bool requireFVarData ) {
|
||||
|
||||
if (flist.size()<2)
|
||||
return 0;
|
||||
|
||||
FarPatchTables * result = new FarPatchTables(0);
|
||||
|
||||
bool isLoop = FarMeshFactory<T,T>::isLoop(mesh);
|
||||
|
||||
int nv = isLoop ? 3 : 4;
|
||||
|
||||
int firstArray = firstLevel > -1 ? firstLevel : (int)flist.size()-1;
|
||||
|
||||
// Populate the patch array descriptors
|
||||
|
||||
FarPatchTables::PatchArrayVector & parray = result->_patchArrays;
|
||||
parray.reserve( (int)flist.size() - firstArray );
|
||||
|
||||
Descriptor desc( isLoop ? FarPatchTables::TRIANGLES : FarPatchTables::QUADS, FarPatchTables::NON_TRANSITION, 0 );
|
||||
|
||||
for (int i=1, poffset=0, voffset=0; i<(int)flist.size(); ++i) {
|
||||
|
||||
int nfaces = (int)flist[i].size();
|
||||
|
||||
if (i>=firstArray) {
|
||||
parray.push_back( FarPatchTables::PatchArray(desc, voffset, poffset, nfaces, 0 ) );
|
||||
|
||||
voffset += nfaces * nv;
|
||||
poffset += nfaces;
|
||||
}
|
||||
}
|
||||
|
||||
int fvarwidth = requireFVarData ? mesh->GetTotalFVarWidth() : 0;
|
||||
|
||||
// Populate the patch / param / fvar tables
|
||||
|
||||
allocateTables( result, fvarwidth );
|
||||
|
||||
unsigned int * iptr = &result->_patches[0];
|
||||
FarPatchParam * pptr = &result->_paramTable[0];
|
||||
float * fptr = requireFVarData ? &result->_fvarTable[0] : 0;
|
||||
|
||||
for (int level=firstArray; level<(int)flist.size(); ++level) {
|
||||
|
||||
for (int i=0; i<(int)flist[level].size(); ++i) {
|
||||
HbrFace<T> * f = flist[level][i];
|
||||
assert( f and f->GetNumVertices()==nv);
|
||||
|
||||
for (int j=0; j<f->GetNumVertices(); ++j) {
|
||||
*iptr++ = remapTable[f->GetVertex(j)->GetID()];
|
||||
}
|
||||
|
||||
pptr = computePatchParam(f, pptr);
|
||||
|
||||
if (requireFVarData)
|
||||
fptr = computeFVarData(f, fvarwidth, fptr, /*isAdaptive=*/false);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Feature adaptive mesh factory
|
||||
template <class T>
|
||||
FarPatchTablesFactory<T>::FarPatchTablesFactory( HbrMesh<T> const * mesh, int nfaces, std::vector<int> const & remapTable ) :
|
||||
_mesh(mesh),
|
||||
@ -343,17 +474,17 @@ FarPatchTablesFactory<T>::FarPatchTablesFactory( HbrMesh<T> const * mesh, int nf
|
||||
switch (boundaryVerts) {
|
||||
|
||||
case 0 : { // Regular patch
|
||||
_fullCtr.R++;
|
||||
_patchCtr[0].R++;
|
||||
} break;
|
||||
|
||||
case 2 : { // Boundary patch
|
||||
f->_adaptiveFlags.rots=computeBoundaryPatchRotation(f);
|
||||
_fullCtr.B[0]++;
|
||||
_patchCtr[0].B[0]++;
|
||||
} break;
|
||||
|
||||
case 3 : { // Corner patch
|
||||
f->_adaptiveFlags.rots=computeCornerPatchRotation(f);
|
||||
_fullCtr.C[0]++;
|
||||
_patchCtr[0].C[0]++;
|
||||
} break;
|
||||
|
||||
default : break;
|
||||
@ -366,12 +497,12 @@ FarPatchTablesFactory<T>::FarPatchTablesFactory( HbrMesh<T> const * mesh, int nf
|
||||
switch (boundaryVerts) {
|
||||
|
||||
case 0 : { // Regular Gregory patch
|
||||
_fullCtr.G[0]++;
|
||||
_patchCtr[0].G[0]++;
|
||||
} break;
|
||||
|
||||
|
||||
default : { // Boundary Gregory patch
|
||||
_fullCtr.G[1]++;
|
||||
_patchCtr[0].G[1]++;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
@ -432,7 +563,7 @@ FarPatchTablesFactory<T>::FarPatchTablesFactory( HbrMesh<T> const * mesh, int nf
|
||||
switch (boundaryVerts) {
|
||||
|
||||
case 0 : { // regular patch
|
||||
_transitionCtr[tidx].R++;
|
||||
_patchCtr[tidx+1].R++;
|
||||
} break;
|
||||
|
||||
case 2 : { // boundary patch
|
||||
@ -442,7 +573,7 @@ FarPatchTablesFactory<T>::FarPatchTablesFactory( HbrMesh<T> const * mesh, int nf
|
||||
|
||||
f->_adaptiveFlags.rots=rot; // override the transition rotation
|
||||
|
||||
_transitionCtr[tidx].B[f->_adaptiveFlags.brots]++;
|
||||
_patchCtr[tidx+1].B[f->_adaptiveFlags.brots]++;
|
||||
} break;
|
||||
|
||||
case 3 : { // corner patch
|
||||
@ -452,7 +583,7 @@ FarPatchTablesFactory<T>::FarPatchTablesFactory( HbrMesh<T> const * mesh, int nf
|
||||
|
||||
f->_adaptiveFlags.rots=rot; // override the transition rotation
|
||||
|
||||
_transitionCtr[tidx].C[f->_adaptiveFlags.brots]++;
|
||||
_patchCtr[tidx+1].C[f->_adaptiveFlags.brots]++;
|
||||
} break;
|
||||
|
||||
default : assert(0); break;
|
||||
@ -465,165 +596,124 @@ FarPatchTablesFactory<T>::FarPatchTablesFactory( HbrMesh<T> const * mesh, int nf
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
template <class TYPE> TYPE &
|
||||
FarPatchTablesFactory<T>::PatchTypes<TYPE>::getValue( FarPatchTables::Descriptor desc ) {
|
||||
switch (desc.GetType()) {
|
||||
case FarPatchTables::REGULAR : return R;
|
||||
case FarPatchTables::BOUNDARY : return B[desc.GetRotation()];
|
||||
case FarPatchTables::CORNER : return C[desc.GetRotation()];
|
||||
case FarPatchTables::GREGORY : return G[0];
|
||||
case FarPatchTables::GREGORY_BOUNDARY : return G[1];
|
||||
default : assert(0);
|
||||
}
|
||||
// can't be reached (suppress compiler warning)
|
||||
return R;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
template <class TYPE> int
|
||||
FarPatchTablesFactory<T>::PatchTypes<TYPE>::getNumPatchArrays() const {
|
||||
|
||||
int result=0;
|
||||
|
||||
if (R) ++result;
|
||||
for (int i=0; i<4; ++i) {
|
||||
if (B[i]) ++result;
|
||||
if (C[i]) ++result;
|
||||
if ((i<2) and G[i]) ++result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class T> int
|
||||
FarPatchTablesFactory<T>::getNumPatchArrays() const {
|
||||
|
||||
int result = 0;
|
||||
|
||||
for (int i=0; i<6; ++i)
|
||||
result += _patchCtr[i].getNumPatchArrays();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class T> void
|
||||
FarPatchTablesFactory<T>::pushPatchArray( FarPatchTables::Descriptor desc,
|
||||
FarPatchTables::PatchArrayVector & parray,
|
||||
typename FarPatchTablesFactory<T>::Counter & counter,
|
||||
int * voffset, int * poffset, int * qoffset ) {
|
||||
|
||||
int npatches = counter.getValue( desc );
|
||||
|
||||
if (npatches>0) {
|
||||
parray.push_back( FarPatchTables::PatchArray(desc, *voffset, *poffset, npatches, *qoffset) );
|
||||
|
||||
*voffset += npatches * desc.GetNumControlVertices();
|
||||
*poffset += npatches;
|
||||
*qoffset += (desc.GetType() == FarPatchTables::GREGORY) ? npatches * 4 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T> FarPatchTables *
|
||||
FarPatchTablesFactory<T>::Create( int maxlevel, int maxvalence, bool requirePtexCoordinate,
|
||||
bool requireFVarData ) {
|
||||
FarPatchTablesFactory<T>::Create( int maxlevel, int maxvalence, bool requireFVarData ) {
|
||||
|
||||
static const unsigned int remapRegular [16] = {5,6,10,9,4,0,1,2,3,7,11,15,14,13,12,8};
|
||||
static const unsigned int remapRegularBoundary[12] = {1,2,6,5,0,3,7,11,10,9,8,4};
|
||||
static const unsigned int remapRegularCorner [ 9] = {1,2,5,4,0,8,7,6,3};
|
||||
|
||||
assert(getMesh() and getNumFaces()>0);
|
||||
|
||||
FarPatchTables * result = new FarPatchTables(maxvalence);
|
||||
|
||||
static const unsigned int remapRegular [16] = {5,6,10,9,4,0,1,2,3,7,11,15,14,13,12,8};
|
||||
static const unsigned int remapRegularBoundary[12] = {1,2,6,5,0,3,7,11,10,9,8,4};
|
||||
static const unsigned int remapRegularCorner [ 9] = {1,2,5,4,0,8,7,6,3};
|
||||
// Populate the patch array descriptors
|
||||
FarPatchTables::PatchArrayVector & parray = result->_patchArrays;
|
||||
parray.reserve( getNumPatchArrays() );
|
||||
|
||||
IndexPointers fptrs, tptrs[5];
|
||||
LevelPointers fptrsLv, tptrsLv[5];
|
||||
PtexPointers fptrsPtx, tptrsPtx[5];
|
||||
FVarPointers fptrsFvd, tptrsFvd[5];
|
||||
int voffset=0, poffset=0, qoffset=0;
|
||||
|
||||
// Allocate all index tables
|
||||
|
||||
// Full Patches
|
||||
result->_full._R_IT.first.resize(_fullCtr.R*16);
|
||||
result->_full._R_IT.second.resize(_fullCtr.R);
|
||||
fptrs.R = result->_full._R_IT.first.empty() ? 0 : &result->_full._R_IT.first[0];
|
||||
fptrsLv.R = result->_full._R_IT.second.empty() ? 0 : &result->_full._R_IT.second[0];
|
||||
for (Descriptor::iterator it=Descriptor::begin(); it!=Descriptor::end(); ++it) {
|
||||
pushPatchArray( *it, parray, _patchCtr[it->GetPattern()], &voffset, &poffset, &qoffset );
|
||||
}
|
||||
|
||||
// Full Boundary Patches
|
||||
result->_full._B_IT.first.resize(_fullCtr.B[0]*12);
|
||||
result->_full._B_IT.second.resize(_fullCtr.B[0]);
|
||||
fptrs.B[0] = result->_full._B_IT.first.empty() ? 0 : &result->_full._B_IT.first[0];
|
||||
fptrsLv.B[0] = result->_full._B_IT.second.empty() ? 0 : &result->_full._B_IT.second[0];
|
||||
int fvarwidth = requireFVarData ? getMesh()->GetTotalFVarWidth() : 0;
|
||||
|
||||
allocateTables( result, fvarwidth );
|
||||
|
||||
// Full Corner Patches
|
||||
result->_full._C_IT.first.resize(_fullCtr.C[0]*9);
|
||||
result->_full._C_IT.second.resize(_fullCtr.C[0]);
|
||||
fptrs.C[0] = result->_full._C_IT.first.empty() ? 0 : &result->_full._C_IT.first[0];
|
||||
fptrsLv.C[0] = result->_full._C_IT.second.empty() ? 0 : &result->_full._C_IT.second[0];
|
||||
|
||||
// Full Gregory patches
|
||||
result->_full._G_IT.first.resize(_fullCtr.G[0]*4);
|
||||
result->_full._G_IT.second.resize(_fullCtr.G[0]);
|
||||
fptrs.G[0] = result->_full._G_IT.first.empty() ? 0 : &result->_full._G_IT.first[0];
|
||||
fptrsLv.G[0] = result->_full._G_IT.second.empty() ? 0 : &result->_full._G_IT.second[0];
|
||||
|
||||
// Full Gregory Boundary patches
|
||||
result->_full._G_B_IT.first.resize(_fullCtr.G[1]*4);
|
||||
result->_full._G_B_IT.second.resize(_fullCtr.G[1]);
|
||||
fptrs.G[1] = result->_full._G_B_IT.first.empty() ? 0 : &result->_full._G_B_IT.first[0];
|
||||
fptrsLv.G[1] = result->_full._G_B_IT.second.empty() ? 0 : &result->_full._G_B_IT.second[0];
|
||||
|
||||
// Quad-offsets tables (for Gregory patches)
|
||||
FarPatchTables::QuadOffsetTable quad_G_C0;
|
||||
quad_G_C0.resize(_fullCtr.G[0]*4);
|
||||
FarPatchTables::QuadOffsetTable quad_G_C0; // Quad-offsets tables (for Gregory patches)
|
||||
quad_G_C0.resize(_patchCtr[0].G[0]*4);
|
||||
|
||||
FarPatchTables::QuadOffsetTable quad_G_C1;
|
||||
quad_G_C1.resize(_fullCtr.G[1]*4);
|
||||
quad_G_C1.resize(_patchCtr[0].G[1]*4);
|
||||
|
||||
FarPatchTables::QuadOffsetTable::value_type *quad_G_C0_P = quad_G_C0.empty() ? 0 : &quad_G_C0[0];
|
||||
FarPatchTables::QuadOffsetTable::value_type *quad_G_C1_P = quad_G_C1.empty() ? 0 : &quad_G_C1[0];
|
||||
|
||||
// Transition Patches
|
||||
for (int i=0; i<5; ++i) {
|
||||
|
||||
result->_transition[i]._R_IT.first.resize(_transitionCtr[i].R*16);
|
||||
result->_transition[i]._R_IT.second.resize(_transitionCtr[i].R);
|
||||
tptrs[i].R = result->_transition[i]._R_IT.first.empty() ? 0 : &result->_transition[i]._R_IT.first[0];
|
||||
tptrsLv[i].R = result->_transition[i]._R_IT.second.empty() ? 0 : &result->_transition[i]._R_IT.second[0];
|
||||
// Setup convenience pointers at the beginning of each patch array for each
|
||||
// table (patches, ptex, fvar)
|
||||
CVPointers iptrs[6];
|
||||
ParamPointers pptrs[6];
|
||||
FVarPointers fptrs[6];
|
||||
|
||||
for (int j=0; j<4; ++j) {
|
||||
for (Descriptor::iterator it=Descriptor::begin(); it!=Descriptor::end(); ++it) {
|
||||
|
||||
FarPatchTables::PatchArray * pa = result->findPatchArray(*it);
|
||||
|
||||
result->_transition[i]._B_IT[j].first.resize(_transitionCtr[i].B[j]*12);
|
||||
result->_transition[i]._B_IT[j].second.resize(_transitionCtr[i].B[j]);
|
||||
tptrs[i].B[j] = result->_transition[i]._B_IT[j].first.empty() ? 0 : &result->_transition[i]._B_IT[j].first[0];
|
||||
tptrsLv[i].B[j] = result->_transition[i]._B_IT[j].second.empty() ? 0 : &result->_transition[i]._B_IT[j].second[0];
|
||||
if (not pa)
|
||||
continue;
|
||||
|
||||
result->_transition[i]._C_IT[j].first.resize(_transitionCtr[i].C[j]*9);
|
||||
result->_transition[i]._C_IT[j].second.resize(_transitionCtr[i].C[j]);
|
||||
tptrs[i].C[j] = result->_transition[i]._C_IT[j].first.empty() ? 0 : &result->_transition[i]._C_IT[j].first[0];
|
||||
tptrsLv[i].C[j] = result->_transition[i]._C_IT[j].second.empty() ? 0 : &result->_transition[i]._C_IT[j].second[0];
|
||||
}
|
||||
iptrs[(int)pa->GetDescriptor().GetPattern()].getValue( *it ) = &result->_patches[pa->GetVertIndex()];
|
||||
pptrs[(int)pa->GetDescriptor().GetPattern()].getValue( *it ) = &result->_paramTable[pa->GetPatchIndex()];
|
||||
if (requireFVarData)
|
||||
fptrs[(int)pa->GetDescriptor().GetPattern()].getValue( *it ) = &result->_fvarTable[pa->GetPatchIndex() * 4 * fvarwidth];
|
||||
}
|
||||
|
||||
// Allocate ptex coordinate table if necessary
|
||||
if (requirePtexCoordinate) {
|
||||
result->_full._R_PTX.resize(_fullCtr.R);
|
||||
fptrsPtx.R = result->_full._R_PTX.empty() ? 0 : &result->_full._R_PTX[0];
|
||||
|
||||
result->_full._B_PTX.resize(_fullCtr.B[0]);
|
||||
fptrsPtx.B[0] = result->_full._B_PTX.empty() ? 0 : &result->_full._B_PTX[0];
|
||||
|
||||
result->_full._C_PTX.resize(_fullCtr.C[0]);
|
||||
fptrsPtx.C[0] = result->_full._C_PTX.empty() ? 0 : &result->_full._C_PTX[0];
|
||||
|
||||
result->_full._G_PTX.resize(_fullCtr.G[0]);
|
||||
fptrsPtx.G[0] = result->_full._G_PTX.empty() ? 0 : &result->_full._G_PTX[0];
|
||||
|
||||
result->_full._G_B_PTX.resize(_fullCtr.G[1]);
|
||||
fptrsPtx.G[1] = result->_full._G_B_PTX.empty() ? 0 : &result->_full._G_B_PTX[0];
|
||||
|
||||
for (int i=0; i < 5; ++i) {
|
||||
result->_transition[i]._R_PTX.resize(_transitionCtr[i].R);
|
||||
tptrsPtx[i].R = result->_transition[i]._R_PTX.empty() ? 0 : &result->_transition[i]._R_PTX[0];
|
||||
|
||||
for (int j=0; j < 4; ++j) {
|
||||
result->_transition[i]._B_PTX[j].resize(_transitionCtr[i].B[j]);
|
||||
tptrsPtx[i].B[j] = result->_transition[i]._B_PTX[j].empty() ? 0 : &result->_transition[i]._B_PTX[j][0];
|
||||
|
||||
result->_transition[i]._C_PTX[j].resize(_transitionCtr[i].C[j]);
|
||||
tptrsPtx[i].C[j] = result->_transition[i]._C_PTX[j].empty() ? 0 : &result->_transition[i]._C_PTX[j][0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate face-varying data table if necessary
|
||||
if (requireFVarData) {
|
||||
int width = 4*getMesh()->GetTotalFVarWidth();
|
||||
result->_full._R_FVD.resize(_fullCtr.R*width);
|
||||
fptrsFvd.R = result->_full._R_FVD.empty() ? 0 : &result->_full._R_FVD[0];
|
||||
|
||||
result->_full._B_FVD.resize(_fullCtr.B[0]*width);
|
||||
fptrsFvd.B[0] = result->_full._B_FVD.empty() ? 0 : &result->_full._B_FVD[0];
|
||||
|
||||
result->_full._C_FVD.resize(_fullCtr.C[0]*width);
|
||||
fptrsFvd.C[0] = result->_full._C_FVD.empty() ? 0 : &result->_full._C_FVD[0];
|
||||
|
||||
result->_full._G_FVD.resize(_fullCtr.G[0]*width);
|
||||
fptrsFvd.G[0] = result->_full._G_FVD.empty() ? 0 : &result->_full._G_FVD[0];
|
||||
|
||||
result->_full._G_B_FVD.resize(_fullCtr.G[1]*width);
|
||||
fptrsFvd.G[1] = result->_full._G_B_FVD.empty() ? 0 : &result->_full._G_B_FVD[0];
|
||||
|
||||
for (int i=0; i < 5; ++i) {
|
||||
result->_transition[i]._R_FVD.resize(_transitionCtr[i].R*width);
|
||||
tptrsFvd[i].R = result->_transition[i]._R_FVD.empty() ? 0 : &result->_transition[i]._R_FVD[0];
|
||||
|
||||
for (int j=0; j < 4; ++j) {
|
||||
result->_transition[i]._B_FVD[j].resize(_transitionCtr[i].B[j]*width);
|
||||
tptrsFvd[i].B[j] = result->_transition[i]._B_FVD[j].empty() ? 0 : &result->_transition[i]._B_FVD[j][0];
|
||||
|
||||
result->_transition[i]._C_FVD[j].resize(_transitionCtr[i].C[j]*width);
|
||||
tptrsFvd[i].C[j] = result->_transition[i]._C_FVD[j].empty() ? 0 : &result->_transition[i]._C_FVD[j][0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int currentDepth = 0;
|
||||
|
||||
int fvarWidth = getMesh()->GetTotalFVarWidth();
|
||||
|
||||
|
||||
// Populate patch index tables with vertex indices
|
||||
for (int i=0; i<getNumFaces(); ++i) {
|
||||
|
||||
HbrFace<T> * f = getMesh()->GetFace(i);
|
||||
|
||||
int depth = f->GetDepth();
|
||||
if (depth!=currentDepth) {
|
||||
assert(depth==currentDepth+1);
|
||||
currentDepth = depth;
|
||||
}
|
||||
|
||||
|
||||
if (not f->isTransitionPatch() ) {
|
||||
|
||||
// Full / End patches
|
||||
@ -633,29 +723,26 @@ FarPatchTablesFactory<T>::Create( int maxlevel, int maxvalence, bool requirePtex
|
||||
|
||||
switch (f->_adaptiveFlags.bverts) {
|
||||
case 0 : { // Regular Patch (16 CVs)
|
||||
getOneRing(f, 16, remapRegular, fptrs.R);
|
||||
fptrs.R+=16;
|
||||
*fptrsLv.R++ = depth;
|
||||
fptrsPtx.R = computePtexCoordinate(f, fptrsPtx.R);
|
||||
fptrsFvd.R = computeFVarData(f, fvarWidth, fptrsFvd.R, /*isAdaptive=*/true);
|
||||
getOneRing(f, 16, remapRegular, iptrs[0].R);
|
||||
iptrs[0].R+=16;
|
||||
pptrs[0].R = computePatchParam(f, pptrs[0].R);
|
||||
fptrs[0].R = computeFVarData(f, fvarwidth, fptrs[0].R, /*isAdaptive=*/true);
|
||||
} break;
|
||||
|
||||
case 2 : { // Boundary Patch (12 CVs)
|
||||
f->_adaptiveFlags.brots = (f->_adaptiveFlags.rots+1)%4;
|
||||
getOneRing(f, 12, remapRegularBoundary, fptrs.B[0]);
|
||||
fptrs.B[0]+=12;
|
||||
*fptrsLv.B[0]++ = depth;
|
||||
fptrsPtx.B[0] = computePtexCoordinate(f, fptrsPtx.B[0]);
|
||||
fptrsFvd.B[0] = computeFVarData(f, fvarWidth, fptrsFvd.B[0], /*isAdaptive=*/true);
|
||||
getOneRing(f, 12, remapRegularBoundary, iptrs[0].B[0]);
|
||||
iptrs[0].B[0]+=12;
|
||||
pptrs[0].B[0] = computePatchParam(f, pptrs[0].B[0]);
|
||||
fptrs[0].B[0] = computeFVarData(f, fvarwidth, fptrs[0].B[0], /*isAdaptive=*/true);
|
||||
} break;
|
||||
|
||||
case 3 : { // Corner Patch (9 CVs)
|
||||
f->_adaptiveFlags.brots = (f->_adaptiveFlags.rots+1)%4;
|
||||
getOneRing(f, 9, remapRegularCorner, fptrs.C[0]);
|
||||
fptrs.C[0]+=9;
|
||||
*fptrsLv.C[0]++ = depth;
|
||||
fptrsPtx.C[0] = computePtexCoordinate(f, fptrsPtx.C[0]);
|
||||
fptrsFvd.C[0] = computeFVarData(f, fvarWidth, fptrsFvd.C[0], /*isAdaptive=*/true);
|
||||
getOneRing(f, 9, remapRegularCorner, iptrs[0].C[0]);
|
||||
iptrs[0].C[0]+=9;
|
||||
pptrs[0].C[0] = computePatchParam(f, pptrs[0].C[0]);
|
||||
fptrs[0].C[0] = computeFVarData(f, fvarwidth, fptrs[0].C[0], /*isAdaptive=*/true);
|
||||
} break;
|
||||
|
||||
default : assert(0);
|
||||
@ -667,24 +754,22 @@ FarPatchTablesFactory<T>::Create( int maxlevel, int maxvalence, bool requirePtex
|
||||
|
||||
// Gregory Regular Patch (4 CVs + quad-offsets / valence tables)
|
||||
for (int j=0; j<4; ++j)
|
||||
fptrs.G[0][j] = _remapTable[f->GetVertex(j)->GetID()];
|
||||
fptrs.G[0]+=4;
|
||||
*fptrsLv.G[0]++ = depth;
|
||||
iptrs[0].G[0][j] = _remapTable[f->GetVertex(j)->GetID()];
|
||||
iptrs[0].G[0]+=4;
|
||||
getQuadOffsets(f, quad_G_C0_P);
|
||||
quad_G_C0_P += 4;
|
||||
fptrsPtx.G[0] = computePtexCoordinate(f, fptrsPtx.G[0]);
|
||||
fptrsFvd.G[0] = computeFVarData(f, fvarWidth, fptrsFvd.G[0], /*isAdaptive=*/true);
|
||||
pptrs[0].G[0] = computePatchParam(f, pptrs[0].G[0]);
|
||||
fptrs[0].G[0] = computeFVarData(f, fvarwidth, fptrs[0].G[0], /*isAdaptive=*/true);
|
||||
} else {
|
||||
|
||||
// Gregory Boundary Patch (4 CVs + quad-offsets / valence tables)
|
||||
for (int j=0; j<4; ++j)
|
||||
fptrs.G[1][j] = _remapTable[f->GetVertex(j)->GetID()];
|
||||
fptrs.G[1]+=4;
|
||||
*fptrsLv.G[1]++ = depth;
|
||||
iptrs[0].G[1][j] = _remapTable[f->GetVertex(j)->GetID()];
|
||||
iptrs[0].G[1]+=4;
|
||||
getQuadOffsets(f, quad_G_C1_P);
|
||||
quad_G_C1_P += 4;
|
||||
fptrsPtx.G[1] = computePtexCoordinate(f, fptrsPtx.G[1]);
|
||||
fptrsFvd.G[1] = computeFVarData(f, fvarWidth, fptrsFvd.G[1], /*isAdaptive=*/true);
|
||||
pptrs[0].G[1] = computePatchParam(f, pptrs[0].G[1]);
|
||||
fptrs[0].G[1] = computeFVarData(f, fvarwidth, fptrs[0].G[1], /*isAdaptive=*/true);
|
||||
}
|
||||
} else {
|
||||
// XXXX manuelk - end patches here
|
||||
@ -695,34 +780,33 @@ FarPatchTablesFactory<T>::Create( int maxlevel, int maxvalence, bool requirePtex
|
||||
|
||||
int tcase = f->_adaptiveFlags.transitionType;
|
||||
assert( tcase>=HbrFace<T>::kTransition0 and tcase<=HbrFace<T>::kTransition4 );
|
||||
++tcase; // TransitionPattern begin with NON_TRANSITION
|
||||
|
||||
if (not f->_adaptiveFlags.isExtraordinary and f->_adaptiveFlags.bverts!=1) {
|
||||
|
||||
switch (f->_adaptiveFlags.bverts) {
|
||||
case 0 : { // Regular Transition Patch (16 CVs)
|
||||
getOneRing(f, 16, remapRegular, tptrs[tcase].R);
|
||||
tptrs[tcase].R+=16;
|
||||
*tptrsLv[tcase].R++ = depth;
|
||||
tptrsPtx[tcase].R = computePtexCoordinate(f, tptrsPtx[tcase].R);
|
||||
tptrsFvd[tcase].R = computeFVarData(f, fvarWidth, tptrsFvd[tcase].R, /*isAdaptive=*/true);
|
||||
getOneRing(f, 16, remapRegular, iptrs[tcase].R);
|
||||
|
||||
iptrs[tcase].R+=16;
|
||||
pptrs[tcase].R = computePatchParam(f, pptrs[tcase].R);
|
||||
fptrs[tcase].R = computeFVarData(f, fvarwidth, fptrs[tcase].R, /*isAdaptive=*/true);
|
||||
} break;
|
||||
|
||||
case 2 : { // Boundary Transition Patch (12 CVs)
|
||||
unsigned rot = f->_adaptiveFlags.brots;
|
||||
getOneRing(f, 12, remapRegularBoundary, tptrs[tcase].B[rot]);
|
||||
tptrs[tcase].B[rot]+=12;
|
||||
*tptrsLv[tcase].B[rot]++ = depth;
|
||||
tptrsPtx[tcase].B[rot] = computePtexCoordinate(f, tptrsPtx[tcase].B[rot]);
|
||||
tptrsFvd[tcase].B[rot] = computeFVarData(f, fvarWidth, tptrsFvd[tcase].B[rot], /*isAdaptive=*/true);
|
||||
getOneRing(f, 12, remapRegularBoundary, iptrs[tcase].B[rot]);
|
||||
iptrs[tcase].B[rot]+=12;
|
||||
pptrs[tcase].B[rot] = computePatchParam(f, pptrs[tcase].B[rot]);
|
||||
fptrs[tcase].B[rot] = computeFVarData(f, fvarwidth, fptrs[tcase].B[rot], /*isAdaptive=*/true);
|
||||
} break;
|
||||
|
||||
case 3 : { // Corner Transition Patch (9 CVs)
|
||||
unsigned rot = f->_adaptiveFlags.brots;
|
||||
getOneRing(f, 9, remapRegularCorner, tptrs[tcase].C[rot]);
|
||||
tptrs[tcase].C[rot]+=9;
|
||||
*tptrsLv[tcase].C[rot]++ = depth;
|
||||
tptrsPtx[tcase].C[rot] = computePtexCoordinate(f, tptrsPtx[tcase].C[rot]);
|
||||
tptrsFvd[tcase].C[rot] = computeFVarData(f, fvarWidth, tptrsFvd[tcase].C[rot], /*isAdaptive=*/true);
|
||||
getOneRing(f, 9, remapRegularCorner, iptrs[tcase].C[rot]);
|
||||
iptrs[tcase].C[rot]+=9;
|
||||
pptrs[tcase].C[rot] = computePatchParam(f, pptrs[tcase].C[rot]);
|
||||
fptrs[tcase].C[rot] = computeFVarData(f, fvarwidth, fptrs[tcase].C[rot], /*isAdaptive=*/true);
|
||||
} break;
|
||||
}
|
||||
} else
|
||||
@ -730,9 +814,9 @@ FarPatchTablesFactory<T>::Create( int maxlevel, int maxvalence, bool requirePtex
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Build Gregory patches vertex valence indices table
|
||||
if ((_fullCtr.G[0] > 0) or (_fullCtr.G[1] > 0)) {
|
||||
if ((_patchCtr[0].G[0] > 0) or (_patchCtr[0].G[1] > 0)) {
|
||||
|
||||
// MAX_VALENCE is a property of hardware shaders and needs to be matched in OSD
|
||||
const int perVertexValenceSize = 2*maxvalence + 1;
|
||||
@ -745,7 +829,7 @@ FarPatchTablesFactory<T>::Create( int maxlevel, int maxvalence, bool requirePtex
|
||||
class GatherNeighborsOperator : public HbrVertexOperator<T> {
|
||||
public:
|
||||
HbrVertex<T> * center;
|
||||
FarPatchTables::VertexValenceTable & table;
|
||||
FarPatchTables::VertexValenceTable & table;
|
||||
int offset, valence;
|
||||
std::vector<int> const & remap;
|
||||
|
||||
@ -754,16 +838,16 @@ FarPatchTablesFactory<T>::Create( int maxlevel, int maxvalence, bool requirePtex
|
||||
|
||||
// Operator iterates over neighbor vertices of v and accumulates
|
||||
// pairs of indices the neighbor and diagonal vertices
|
||||
//
|
||||
//
|
||||
// Regular case
|
||||
// Boundary case
|
||||
// Boundary case
|
||||
// o ------- o D3 o
|
||||
// D0 N0 | |
|
||||
// | | o ------- o D2 o
|
||||
// | | D0 N0 | |
|
||||
// | | | |
|
||||
// o ------- o ------- o | |
|
||||
// N1 | V | N3 | |
|
||||
// N1 | V | N3 | |
|
||||
// | | o ------- o ------- o
|
||||
// | | N1 V N2
|
||||
// | |
|
||||
@ -771,9 +855,9 @@ FarPatchTablesFactory<T>::Create( int maxlevel, int maxvalence, bool requirePtex
|
||||
// D1 N2 D2
|
||||
//
|
||||
virtual void operator() (HbrVertex<T> &v) {
|
||||
|
||||
|
||||
table[offset++] = remap[v.GetID()];
|
||||
|
||||
|
||||
HbrVertex<T> * diagonal=&v;
|
||||
|
||||
HbrHalfedge<T> * e = center->GetEdge(&v);
|
||||
@ -784,9 +868,9 @@ FarPatchTablesFactory<T>::Create( int maxlevel, int maxvalence, bool requirePtex
|
||||
//else {
|
||||
// diagonal = v.GetQEONext( center );
|
||||
//}
|
||||
|
||||
|
||||
table[offset++] = remap[diagonal->GetID()];
|
||||
|
||||
|
||||
++valence;
|
||||
}
|
||||
};
|
||||
@ -796,11 +880,11 @@ FarPatchTablesFactory<T>::Create( int maxlevel, int maxvalence, bool requirePtex
|
||||
|
||||
int outputVertexID = _remapTable[v->GetID()];
|
||||
int offset = outputVertexID * perVertexValenceSize;
|
||||
|
||||
|
||||
// feature adaptive refinement can generate un-connected face-vertices
|
||||
// that have a valence of 0
|
||||
if (not v->IsConnected()) {
|
||||
assert( v->GetParentFace() );
|
||||
assert( v->GetParentFace() );
|
||||
table[offset] = 0;
|
||||
continue;
|
||||
}
|
||||
@ -809,10 +893,10 @@ FarPatchTablesFactory<T>::Create( int maxlevel, int maxvalence, bool requirePtex
|
||||
// is gathered by the operator (see note below)
|
||||
GatherNeighborsOperator op( table, offset+1, v, _remapTable );
|
||||
v->ApplyOperatorSurroundingVertices( op );
|
||||
|
||||
|
||||
// Valence sign bit used to mark boundary vertices
|
||||
table[offset] = v->OnBoundary() ? -op.valence : op.valence;
|
||||
|
||||
|
||||
// Note : some topologies can cause v to be singular at certain
|
||||
// levels of adaptive refinement, which prevents us from using
|
||||
// the GetValence() function. Fortunately, the GatherNeighbors
|
||||
@ -822,28 +906,11 @@ FarPatchTablesFactory<T>::Create( int maxlevel, int maxvalence, bool requirePtex
|
||||
} else {
|
||||
result->_vertexValenceTable.clear();
|
||||
}
|
||||
|
||||
// Combine quad offset buffers
|
||||
result->_quadOffsetTable.resize((_fullCtr.G[0]+_fullCtr.G[1])*4);
|
||||
std::copy(quad_G_C0.begin(), quad_G_C0.end(), result->_quadOffsetTable.begin());
|
||||
std::copy(quad_G_C1.begin(), quad_G_C1.end(), result->_quadOffsetTable.begin()+_fullCtr.G[0]*4);
|
||||
|
||||
// Set patch counts
|
||||
FarPatchCount patchCount;
|
||||
patchCount.nonPatch = 0;
|
||||
patchCount.regular = (int)result->_full._R_IT.first.size()/16;
|
||||
patchCount.boundary = (int)result->_full._B_IT.first.size()/12;
|
||||
patchCount.corner = (int)result->_full._C_IT.first.size()/9;
|
||||
patchCount.gregory = (int)result->_full._G_IT.first.size()/4;
|
||||
patchCount.boundaryGregory = (int)result->_full._G_B_IT.first.size()/4;
|
||||
for (int j=0; j<5; ++j) {
|
||||
patchCount.transitionRegular[j] = (int)result->_transition[j]._R_IT.first.size()/16;
|
||||
for (int k=0; k<4; ++k) {
|
||||
patchCount.transitionBoundary[j][k] = (int)result->_transition[j]._B_IT[k].first.size()/12;
|
||||
patchCount.transitionCorner[j][k] = (int)result->_transition[j]._C_IT[k].first.size()/9;
|
||||
}
|
||||
}
|
||||
result->_patchCounts.push_back(patchCount);
|
||||
// Combine quad offset buffers
|
||||
result->_quadOffsetTable.resize((_patchCtr[0].G[0]+_patchCtr[0].G[1])*4);
|
||||
std::copy(quad_G_C0.begin(), quad_G_C0.end(), result->_quadOffsetTable.begin());
|
||||
std::copy(quad_G_C1.begin(), quad_G_C1.end(), result->_quadOffsetTable.begin()+_patchCtr[0].G[0]*4);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -99,9 +99,6 @@ template <class U> class FarSubdivisionTables {
|
||||
|
||||
public:
|
||||
enum TableType {
|
||||
F_ITa, // face-vertices adjacency indexing table
|
||||
F_IT, // face-vertices indexing table
|
||||
|
||||
E_IT, // edge-vertices adjacency indexing table
|
||||
E_W, // edge-vertices weights
|
||||
|
||||
@ -109,6 +106,9 @@ public:
|
||||
V_IT, // vertex-vertices indexing table
|
||||
V_W, // vertex-vertices weights
|
||||
|
||||
F_ITa, // face-vertices adjacency indexing table
|
||||
F_IT, // face-vertices indexing table
|
||||
|
||||
TABLE_TYPES_COUNT // number of different types of tables
|
||||
};
|
||||
|
||||
@ -128,10 +128,14 @@ public:
|
||||
/// represented by this set of FarCatmarkSubdivisionTables
|
||||
int GetFirstVertexOffset( int level ) const;
|
||||
|
||||
/// Number of vertices at a given level
|
||||
/// Returns the total number of vertex adressed by the tables (this is the
|
||||
/// length that a vertex buffer object should be allocating
|
||||
int GetNumVertices( ) const;
|
||||
|
||||
/// Returns the number of vertices at a given level
|
||||
int GetNumVertices( int level ) const;
|
||||
|
||||
/// Total number of vertices at a given level
|
||||
/// Returns the summation of the number of vertices up to a given level
|
||||
int GetNumVerticesTotal( int level ) const;
|
||||
|
||||
/// Indexing tables accessors
|
||||
@ -197,6 +201,17 @@ FarSubdivisionTables<U>::GetFirstVertexOffset( int level ) const {
|
||||
return _vertsOffsets[level];
|
||||
}
|
||||
|
||||
template <class U> int
|
||||
FarSubdivisionTables<U>::GetNumVertices( ) const {
|
||||
if (_vertsOffsets.empty()) {
|
||||
return 0;
|
||||
} else {
|
||||
// _vertsOffsets contains an extra offset at the end that is the position
|
||||
// of the first vertex 1 level above that of the tables
|
||||
return *_vertsOffsets.rbegin();
|
||||
}
|
||||
}
|
||||
|
||||
template <class U> int
|
||||
FarSubdivisionTables<U>::GetNumVertices( int level ) const {
|
||||
assert(level>=0 and level<((int)_vertsOffsets.size()-1));
|
||||
|
@ -1,4 +1,6 @@
|
||||
//
|
||||
// Copyright (C) Pixar. All rights reserved.
|
||||
//
|
||||
// This license governs use of the accompanying software. If you
|
||||
// use the software, you accept this license. If you do not accept
|
||||
// the license, do not use the software.
|
||||
|
@ -460,6 +460,19 @@ private:
|
||||
// Faces which are transient
|
||||
std::vector<HbrFace<T>*> m_transientFaces;
|
||||
|
||||
#ifdef HBR_ADAPTIVE
|
||||
public:
|
||||
enum SubdivisionMethod {
|
||||
k_SubdivisionMethodNone,
|
||||
k_SubdivisionMethodUniform,
|
||||
k_SubdivisionMethodFeatureAdaptive
|
||||
};
|
||||
void SetSubdivisionMethod(SubdivisionMethod method) { _subdivisionMethod=method; }
|
||||
SubdivisionMethod GetSubdivisionMethod() const { return _subdivisionMethod; }
|
||||
|
||||
private:
|
||||
SubdivisionMethod _subdivisionMethod;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
|
@ -87,7 +87,6 @@ set(CPU_SOURCE_FILES
|
||||
evalLimitContext.cpp
|
||||
drawContext.cpp
|
||||
drawRegistry.cpp
|
||||
sortedDrawContext.cpp
|
||||
)
|
||||
|
||||
set(GPU_SOURCE_FILES
|
||||
@ -118,8 +117,6 @@ set(PUBLIC_HEADER_FILES
|
||||
nonCopyable.h
|
||||
drawContext.h
|
||||
drawRegistry.h
|
||||
patch.h
|
||||
sortedDrawContext.h
|
||||
vertex.h
|
||||
vertexDescriptor.h
|
||||
)
|
||||
|
@ -133,7 +133,7 @@ OsdCLHEditTable::GetPrimvarWidth() const {
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
OsdCLComputeContext::OsdCLComputeContext(FarMesh<OsdVertex> *farMesh,
|
||||
OsdCLComputeContext::OsdCLComputeContext(FarMesh<OsdVertex> const *farMesh,
|
||||
cl_context clContext)
|
||||
: _clQueue(NULL), _kernelBundle(NULL) {
|
||||
|
||||
@ -232,7 +232,7 @@ OsdCLComputeContext::GetCommandQueue() const {
|
||||
}
|
||||
|
||||
OsdCLComputeContext *
|
||||
OsdCLComputeContext::Create(FarMesh<OsdVertex> *farmesh, cl_context clContext) {
|
||||
OsdCLComputeContext::Create(FarMesh<OsdVertex> const *farmesh, cl_context clContext) {
|
||||
|
||||
return new OsdCLComputeContext(farmesh, clContext);
|
||||
}
|
||||
|
@ -134,9 +134,11 @@ class OsdCLComputeContext : public OsdNonCopyable<OsdCLComputeContext> {
|
||||
public:
|
||||
/// Creates an OsdCLComputeContext instance
|
||||
///
|
||||
/// @param farmesh the FarMesh used for this Context.
|
||||
/// @param farmesh the FarMesh used for this Context.
|
||||
///
|
||||
static OsdCLComputeContext * Create(FarMesh<OsdVertex> *farmesh,
|
||||
/// @param clContext a valid active OpenCL context
|
||||
///
|
||||
static OsdCLComputeContext * Create(FarMesh<OsdVertex> const *farmesh,
|
||||
cl_context clContext);
|
||||
|
||||
/// Destructor
|
||||
@ -146,9 +148,11 @@ public:
|
||||
/// that data buffers are properly inter-operated between Contexts and
|
||||
/// Controllers operating across multiple devices.
|
||||
///
|
||||
/// @param a buffer containing vertex-interpolated primvar data
|
||||
/// @param vertex a buffer containing vertex-interpolated primvar data
|
||||
///
|
||||
/// @param a buffer containing varying-interpolated primvar data
|
||||
/// @param varying a buffer containing varying-interpolated primvar data
|
||||
///
|
||||
/// @param clQueue OpenCL command queue associated with the primvar data
|
||||
///
|
||||
template<class VERTEX_BUFFER, class VARYING_BUFFER>
|
||||
void Bind(VERTEX_BUFFER *vertex, VARYING_BUFFER *varying, cl_command_queue clQueue) {
|
||||
@ -197,7 +201,7 @@ public:
|
||||
void SetCommandQueue(cl_command_queue queue);
|
||||
|
||||
protected:
|
||||
explicit OsdCLComputeContext(FarMesh<OsdVertex> *farMesh,
|
||||
explicit OsdCLComputeContext(FarMesh<OsdVertex> const *farMesh,
|
||||
cl_context clContext);
|
||||
|
||||
private:
|
||||
|
@ -149,6 +149,12 @@ public:
|
||||
/// Waits until all running subdivision kernels finish.
|
||||
void Synchronize();
|
||||
|
||||
/// Returns CL context
|
||||
cl_context GetContext() const { return _clContext; }
|
||||
|
||||
/// Returns CL command queue
|
||||
cl_command_queue GetCommandQueue() const { return _clQueue; }
|
||||
|
||||
protected:
|
||||
friend class FarDispatcher;
|
||||
|
||||
|
@ -68,24 +68,27 @@
|
||||
namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
///
|
||||
/// \brief Concrete vertex buffer class for OpenCL subvision and DirectX
|
||||
/// drawing.
|
||||
///
|
||||
/// OsdD3D11VertexBuffer implements OsdCLVertexBufferInterface and
|
||||
/// OsdD3D11VertexBufferInterface.
|
||||
/// An instance of this buffer class can be passed to
|
||||
/// OsdD3D11ComputeController.
|
||||
///
|
||||
/// An instance of this buffer class can be passed to OsdD3D11ComputeController.
|
||||
///
|
||||
class OsdCLD3D11VertexBuffer {
|
||||
public:
|
||||
/// Creator. Returns NULL if error.
|
||||
static OsdCLD3D11VertexBuffer * Create(int numElements, int numVertices,
|
||||
static OsdCLD3D11VertexBuffer * Create(int numElements,
|
||||
int numVertices,
|
||||
cl_context clContext,
|
||||
ID3D11Device *device);
|
||||
|
||||
/// Destructor.
|
||||
virtual ~OsdCLD3D11VertexBuffer();
|
||||
|
||||
/// This method is meant to be used in client code in order to provide
|
||||
/// coarse vertices data to Osd.
|
||||
/// This method is meant to be used in client code in order to provide coarse
|
||||
/// vertices data to Osd.
|
||||
void UpdateData(const float *src, int startVertex, int numVertices, cl_command_queue clQueue);
|
||||
|
||||
/// Returns how many elements defined in this vertex buffer.
|
||||
@ -102,8 +105,10 @@ public:
|
||||
|
||||
protected:
|
||||
/// Constructor.
|
||||
OsdCLD3D11VertexBuffer(int numElements, int numVertices,
|
||||
cl_context clContext, ID3D11Device *device);
|
||||
OsdCLD3D11VertexBuffer(int numElements,
|
||||
int numVertices,
|
||||
cl_context clContext,
|
||||
ID3D11Device *device);
|
||||
|
||||
/// Allocates this buffer and registers as a cl resource.
|
||||
/// Returns true if success.
|
||||
|
@ -68,22 +68,27 @@
|
||||
namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
///
|
||||
/// \brief Concrete vertex buffer class for OpenCL subvision and OpenGL drawing.
|
||||
///
|
||||
/// OsdCLGLVertexBuffer implements OsdCLVertexBufferInterface and
|
||||
/// OsdGLVertexBufferInterface.
|
||||
/// The buffer interop between OpenCL and GL is handled
|
||||
/// automatically when a client calls BindCLBuffer and BindVBO methods.
|
||||
///
|
||||
/// The buffer interop between OpenCL and GL is handled automatically when a
|
||||
/// client calls BindCLBuffer and BindVBO methods.
|
||||
///
|
||||
class OsdCLGLVertexBuffer {
|
||||
public:
|
||||
/// Creator. Returns NULL if error.
|
||||
static OsdCLGLVertexBuffer * Create(int numElements, int numVertices,
|
||||
static OsdCLGLVertexBuffer * Create(int numElements,
|
||||
int numVertices,
|
||||
cl_context clContext);
|
||||
|
||||
/// Destructor.
|
||||
~OsdCLGLVertexBuffer();
|
||||
|
||||
/// This method is meant to be used in client code in order to provide
|
||||
/// coarse vertices data to Osd.
|
||||
/// This method is meant to be used in client code in order to provide coarse
|
||||
/// vertices data to Osd.
|
||||
void UpdateData(const float *src, int startVertex, int numVertices, cl_command_queue clQueue);
|
||||
|
||||
/// Returns how many elements defined in this vertex buffer.
|
||||
|
@ -140,8 +140,7 @@ OsdCLKernelBundle::Compile(cl_context clContext,
|
||||
|
||||
cl_int ciErrNum;
|
||||
|
||||
_numVertexElements = numVertexElements;
|
||||
_numVaryingElements = numVaryingElements;
|
||||
_vdesc.Set( numVertexElements, numVaryingElements );
|
||||
|
||||
char constantDefine[256];
|
||||
snprintf(constantDefine, sizeof(constantDefine),
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include "../version.h"
|
||||
|
||||
#include "../osd/nonCopyable.h"
|
||||
#include "../osd/vertexDescriptor.h"
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <OpenCL/opencl.h>
|
||||
@ -72,6 +73,7 @@ namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
class OsdCLKernelBundle : OsdNonCopyable<OsdCLKernelBundle> {
|
||||
|
||||
public:
|
||||
OsdCLKernelBundle();
|
||||
~OsdCLKernelBundle();
|
||||
@ -100,14 +102,17 @@ public:
|
||||
cl_kernel GetVertexEditAdd() const { return _clVertexEditAdd; }
|
||||
|
||||
struct Match {
|
||||
Match(int numVertexElements, int numVaryingElements) :
|
||||
_numVertexElements(numVertexElements),
|
||||
_numVaryingElements(numVaryingElements) {}
|
||||
bool operator() (const OsdCLKernelBundle *kernel) {
|
||||
return (kernel->_numVertexElements == _numVertexElements
|
||||
&& kernel->_numVaryingElements == _numVaryingElements);
|
||||
|
||||
/// Constructor
|
||||
Match(int numVertexElements, int numVaryingElements)
|
||||
: vdesc(numVertexElements, numVaryingElements) {
|
||||
}
|
||||
int _numVertexElements, _numVaryingElements;
|
||||
|
||||
bool operator() (OsdCLKernelBundle const *kernel) {
|
||||
return vdesc == kernel->_vdesc;
|
||||
}
|
||||
|
||||
OsdVertexDescriptor vdesc;
|
||||
};
|
||||
|
||||
friend struct Match;
|
||||
@ -126,8 +131,7 @@ protected:
|
||||
_clLoopVertexB,
|
||||
_clVertexEditAdd;
|
||||
|
||||
int _numVertexElements,
|
||||
_numVaryingElements;
|
||||
OsdVertexDescriptor _vdesc;
|
||||
};
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
|
@ -68,21 +68,23 @@
|
||||
namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
///
|
||||
/// \brief Concrete vertex buffer class for OpenCL subvision.
|
||||
/// OsdCLVertexBuffer implements OsdCLVertexBufferInterface. An instance
|
||||
/// of this buffer class can be passed to OsdCLComputeController
|
||||
///
|
||||
/// OsdCLVertexBuffer implements OsdCLVertexBufferInterface. An instance of this
|
||||
/// buffer class can be passed to OsdCLComputeController
|
||||
///
|
||||
class OsdCLVertexBuffer {
|
||||
|
||||
public:
|
||||
/// Creator. Returns NULL if error.
|
||||
static OsdCLVertexBuffer * Create(int numElements, int numVertices,
|
||||
cl_context clContext);
|
||||
static OsdCLVertexBuffer * Create(int numElements, int numVertices, cl_context clContext);
|
||||
|
||||
/// Destructor.
|
||||
~OsdCLVertexBuffer();
|
||||
|
||||
/// This method is meant to be used in client code in order to provide
|
||||
/// coarse vertices data to Osd.
|
||||
/// This method is meant to be used in client code in order to provide coarse
|
||||
/// vertices data to Osd.
|
||||
void UpdateData(const float *src, int startVertex, int numVertices, cl_command_queue clQueue);
|
||||
|
||||
/// Returns how many elements defined in this vertex buffer.
|
||||
|
@ -137,7 +137,7 @@ OsdCpuHEditTable::GetPrimvarWidth() const {
|
||||
return _primvarWidth;
|
||||
}
|
||||
|
||||
OsdCpuComputeContext::OsdCpuComputeContext(FarMesh<OsdVertex> *farMesh) {
|
||||
OsdCpuComputeContext::OsdCpuComputeContext(FarMesh<OsdVertex> const *farMesh) {
|
||||
|
||||
FarSubdivisionTables<OsdVertex> const * farTables =
|
||||
farMesh->GetSubdivisionTables();
|
||||
@ -168,7 +168,6 @@ OsdCpuComputeContext::OsdCpuComputeContext(FarMesh<OsdVertex> *farMesh) {
|
||||
_editTables.push_back(new OsdCpuHEditTable(edit));
|
||||
}
|
||||
}
|
||||
_vdesc = 0;
|
||||
_currentVertexBuffer = 0;
|
||||
_currentVaryingBuffer = 0;
|
||||
}
|
||||
@ -181,7 +180,6 @@ OsdCpuComputeContext::~OsdCpuComputeContext() {
|
||||
for (size_t i = 0; i < _editTables.size(); ++i) {
|
||||
delete _editTables[i];
|
||||
}
|
||||
if (_vdesc) delete _vdesc;
|
||||
}
|
||||
|
||||
const OsdCpuTable *
|
||||
@ -190,12 +188,6 @@ OsdCpuComputeContext::GetTable(int tableIndex) const {
|
||||
return _tables[tableIndex];
|
||||
}
|
||||
|
||||
OsdVertexDescriptor *
|
||||
OsdCpuComputeContext::GetVertexDescriptor() const {
|
||||
|
||||
return _vdesc;
|
||||
}
|
||||
|
||||
int
|
||||
OsdCpuComputeContext::GetNumEditTables() const {
|
||||
|
||||
@ -221,7 +213,7 @@ OsdCpuComputeContext::GetCurrentVaryingBuffer() const {
|
||||
}
|
||||
|
||||
OsdCpuComputeContext *
|
||||
OsdCpuComputeContext::Create(FarMesh<OsdVertex> *farmesh) {
|
||||
OsdCpuComputeContext::Create(FarMesh<OsdVertex> const *farmesh) {
|
||||
|
||||
return new OsdCpuComputeContext(farmesh);
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ public:
|
||||
///
|
||||
/// @param farmesh the FarMesh used for this Context.
|
||||
///
|
||||
static OsdCpuComputeContext * Create(FarMesh<OsdVertex> *farmesh);
|
||||
static OsdCpuComputeContext * Create(FarMesh<OsdVertex> const *farmesh);
|
||||
|
||||
/// Destructor
|
||||
virtual ~OsdCpuComputeContext();
|
||||
@ -140,9 +140,9 @@ public:
|
||||
/// that data buffers are properly inter-operated between Contexts and
|
||||
/// Controllers operating across multiple devices.
|
||||
///
|
||||
/// @param a buffer containing vertex-interpolated primvar data
|
||||
/// @param vertex a buffer containing vertex-interpolated primvar data
|
||||
///
|
||||
/// @param a buffer containing varying-interpolated primvar data
|
||||
/// @param varying a buffer containing varying-interpolated primvar data
|
||||
///
|
||||
template<class VERTEX_BUFFER, class VARYING_BUFFER>
|
||||
void Bind(VERTEX_BUFFER *vertex, VARYING_BUFFER *varying) {
|
||||
@ -152,16 +152,14 @@ public:
|
||||
|
||||
int numVertexElements = vertex ? vertex->GetNumElements() : 0;
|
||||
int numVaryingElements = varying ? varying->GetNumElements() : 0;
|
||||
_vdesc = new OsdVertexDescriptor(numVertexElements, numVaryingElements);
|
||||
_vdesc.Set(numVertexElements, numVaryingElements);
|
||||
}
|
||||
|
||||
/// Unbinds any previously bound vertex and varying data buffers.
|
||||
void Unbind() {
|
||||
_currentVertexBuffer = 0;
|
||||
_currentVaryingBuffer = 0;
|
||||
|
||||
delete _vdesc;
|
||||
_vdesc = 0;
|
||||
_vdesc.Reset();
|
||||
}
|
||||
|
||||
/// Returns one of the vertex refinement tables.
|
||||
@ -174,7 +172,9 @@ public:
|
||||
///
|
||||
/// @return a descriptor for the format of the vertex data currently bound
|
||||
///
|
||||
OsdVertexDescriptor * GetVertexDescriptor() const;
|
||||
OsdVertexDescriptor const & GetVertexDescriptor() const {
|
||||
return _vdesc;
|
||||
}
|
||||
|
||||
/// Returns the number of hierarchical edit tables
|
||||
int GetNumEditTables() const;
|
||||
@ -192,7 +192,7 @@ public:
|
||||
float * GetCurrentVaryingBuffer() const;
|
||||
|
||||
protected:
|
||||
explicit OsdCpuComputeContext(FarMesh<OsdVertex> *farMesh);
|
||||
explicit OsdCpuComputeContext(FarMesh<OsdVertex> const *farMesh);
|
||||
|
||||
private:
|
||||
std::vector<OsdCpuTable*> _tables;
|
||||
@ -201,7 +201,7 @@ private:
|
||||
float *_currentVertexBuffer,
|
||||
*_currentVaryingBuffer;
|
||||
|
||||
OsdVertexDescriptor *_vdesc;
|
||||
OsdVertexDescriptor _vdesc;
|
||||
};
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
|
@ -66,21 +66,26 @@ struct ID3D11DeviceContext;
|
||||
namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
///
|
||||
/// \brief Concrete vertex buffer class for Cpu subvision and DirectX drawing.
|
||||
///
|
||||
/// OsdCpuD3D11VertexBuffer implements OsdCpuVertexBufferInterface and
|
||||
/// OsdD3D11VertexBufferInterface.
|
||||
///
|
||||
/// An instance of this buffer class can be passed to OsdCpuComputeController.
|
||||
///
|
||||
class OsdCpuD3D11VertexBuffer {
|
||||
public:
|
||||
/// Creator. Returns NULL if error.
|
||||
static OsdCpuD3D11VertexBuffer * Create(int numElements, int numVertices,
|
||||
static OsdCpuD3D11VertexBuffer * Create(int numElements,
|
||||
int numVertices,
|
||||
ID3D11Device *device);
|
||||
|
||||
/// Destructor.
|
||||
virtual ~OsdCpuD3D11VertexBuffer();
|
||||
|
||||
/// This method is meant to be used in client code in order to provide
|
||||
/// coarse vertices data to Osd.
|
||||
/// This method is meant to be used in client code in order to provide coarse
|
||||
/// vertices data to Osd.
|
||||
void UpdateData(const float *src, int startVertex, int numVertices, void *param);
|
||||
|
||||
/// Returns how many elements defined in this vertex buffer.
|
||||
@ -97,7 +102,8 @@ public:
|
||||
|
||||
protected:
|
||||
/// Constructor.
|
||||
OsdCpuD3D11VertexBuffer(int numElements, int numVertices,
|
||||
OsdCpuD3D11VertexBuffer(int numElements,
|
||||
int numVertices,
|
||||
ID3D11Device *device);
|
||||
|
||||
bool allocate(ID3D11Device *device);
|
||||
|
@ -84,95 +84,44 @@ OsdCpuEvalLimitContext::OsdCpuEvalLimitContext(FarMesh<OsdVertex> const * farmes
|
||||
FarPatchTables const * patchTables = farmesh->GetPatchTables();
|
||||
assert(patchTables);
|
||||
|
||||
_patchMap = new OsdCpuEvalLimitContext::PatchMap( *patchTables );
|
||||
// copy the data from the FarTables
|
||||
_patches = patchTables->GetPatchTable();
|
||||
|
||||
size_t npatches = patchTables->GetNumPatches(),
|
||||
nvertices = patchTables->GetNumControlVertices();
|
||||
|
||||
_patchArrays.reserve(npatches);
|
||||
|
||||
_patchBitFields.reserve(npatches);
|
||||
_patchArrays = patchTables->GetPatchArrayVector();
|
||||
|
||||
_patchBuffer.reserve(nvertices);
|
||||
|
||||
|
||||
// Full regular patches
|
||||
_AppendPatchArray(OsdPatchDescriptor(kRegular, 0, 0, 0, 0),
|
||||
patchTables->GetFullRegularPatches(),
|
||||
patchTables->GetFullRegularPtexCoordinates());
|
||||
|
||||
_AppendPatchArray(OsdPatchDescriptor(kBoundary, 0, 0, 0, 0),
|
||||
patchTables->GetFullBoundaryPatches(),
|
||||
patchTables->GetFullBoundaryPtexCoordinates());
|
||||
|
||||
_AppendPatchArray(OsdPatchDescriptor(kCorner, 0, 0, 0, 0),
|
||||
patchTables->GetFullCornerPatches(),
|
||||
patchTables->GetFullCornerPtexCoordinates());
|
||||
|
||||
_AppendPatchArray(OsdPatchDescriptor(kGregory, 0, 0, patchTables->GetMaxValence(), 0),
|
||||
patchTables->GetFullGregoryPatches(),
|
||||
patchTables->GetFullGregoryPtexCoordinates());
|
||||
|
||||
_AppendPatchArray(OsdPatchDescriptor(kBoundaryGregory, 0, 0, patchTables->GetMaxValence(), 0),
|
||||
patchTables->GetFullBoundaryGregoryPatches(),
|
||||
patchTables->GetFullBoundaryGregoryPtexCoordinates());
|
||||
|
||||
_vertexValenceBuffer = patchTables->GetVertexValenceTable();
|
||||
_quadOffsetBuffer = patchTables->GetQuadOffsetTable();
|
||||
|
||||
// Transition patches
|
||||
for (int p=0; p<5; ++p) {
|
||||
|
||||
_AppendPatchArray(OsdPatchDescriptor(kTransitionRegular, p, 0, 0, 0),
|
||||
patchTables->GetTransitionRegularPatches(p),
|
||||
patchTables->GetTransitionRegularPtexCoordinates(p));
|
||||
_quadOffsetBuffer = patchTables->GetQuadOffsetTable();
|
||||
|
||||
// Copy the bitfields, the faceId will be the key to our map
|
||||
int npatches = patchTables->GetNumPatches();
|
||||
|
||||
_patchBitFields.reserve(npatches);
|
||||
|
||||
for (int r=0; r<4; ++r) {
|
||||
_AppendPatchArray(OsdPatchDescriptor(kTransitionBoundary, p, r, 0, 0),
|
||||
patchTables->GetTransitionBoundaryPatches(p, r),
|
||||
patchTables->GetTransitionBoundaryPtexCoordinates(p, r));
|
||||
FarPatchTables::PatchParamTable const & ptxTable =
|
||||
patchTables->GetPatchParamTable();
|
||||
|
||||
_AppendPatchArray(OsdPatchDescriptor(kTransitionCorner, p, r, 0, 0),
|
||||
patchTables->GetTransitionCornerPatches(p, r),
|
||||
patchTables->GetTransitionCornerPtexCoordinates(p, r));
|
||||
if ( not ptxTable.empty() ) {
|
||||
|
||||
FarPatchParam const * pptr = &ptxTable[0];
|
||||
|
||||
for (int arrayId = 0; arrayId < (int)_patchArrays.size(); ++arrayId) {
|
||||
|
||||
FarPatchTables::PatchArray const & pa = _patchArrays[arrayId];
|
||||
|
||||
for (unsigned int j=0; j < pa.GetNumPatches(); ++j) {
|
||||
_patchBitFields.push_back( pptr++->bitField );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_patchMap = new FarPatchTables::PatchMap( *patchTables );
|
||||
}
|
||||
|
||||
OsdCpuEvalLimitContext::~OsdCpuEvalLimitContext() {
|
||||
delete _patchMap;
|
||||
}
|
||||
|
||||
int
|
||||
OsdCpuEvalLimitContext::_AppendPatchArray(
|
||||
OsdPatchDescriptor const & desc,
|
||||
FarPatchTables::PTable const & pTable,
|
||||
FarPatchTables::PtexCoordinateTable const & ptxTable )
|
||||
{
|
||||
if (pTable.first.empty() or ptxTable.empty())
|
||||
return 0;
|
||||
|
||||
OsdPatchArray array;
|
||||
array.desc = desc;
|
||||
array.firstIndex = (int)_patchBuffer.size();
|
||||
array.numIndices = (int)pTable.first.size();
|
||||
array.gregoryQuadOffsetBase = 0;
|
||||
//array.gregoryVertexValenceBase = gregoryQuadOffsetBase;
|
||||
|
||||
// copy patch array descriptor
|
||||
_patchArrays.push_back(array);
|
||||
|
||||
// copy patches bitfields
|
||||
for (int i=0; i<(int)ptxTable.size(); ++i) {
|
||||
_patchBitFields.push_back( ptxTable[i].bitField );
|
||||
}
|
||||
|
||||
// copy control vertices indices
|
||||
_patchBuffer.insert( _patchBuffer.end(), pTable.first.begin(), pTable.first.end());
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
} // end namespace OpenSubdiv
|
||||
|
@ -61,6 +61,7 @@
|
||||
|
||||
#include "../osd/evalLimitContext.h"
|
||||
#include "../osd/vertexDescriptor.h"
|
||||
#include "../far/patchTables.h"
|
||||
|
||||
#include <map>
|
||||
#include <stdio.h>
|
||||
@ -147,18 +148,18 @@ public:
|
||||
}
|
||||
|
||||
/// Returns the vector of patch arrays
|
||||
const OsdPatchArrayVector & GetPatchArrayVector() const {
|
||||
const FarPatchTables::PatchArrayVector & GetPatchArrayVector() const {
|
||||
return _patchArrays;
|
||||
}
|
||||
|
||||
/// Returns the vector of per-patch parametric data
|
||||
const std::vector<FarPtexCoord::BitField> & GetPatchBitFields() const {
|
||||
const std::vector<FarPatchParam::BitField> & GetPatchBitFields() const {
|
||||
return _patchBitFields;
|
||||
}
|
||||
|
||||
/// The ordered array of control vertex indices for all the patches
|
||||
const std::vector<unsigned int> & GetControlVertices() const {
|
||||
return _patchBuffer;
|
||||
return _patches;
|
||||
}
|
||||
|
||||
/// XXXX
|
||||
@ -170,154 +171,8 @@ public:
|
||||
return &_quadOffsetBuffer[0];
|
||||
}
|
||||
|
||||
/// Maps coarse-face ptex coordinates to children patches
|
||||
struct PatchMap {
|
||||
public:
|
||||
|
||||
|
||||
/// \brief Returns the number and list of patch indices for a given face.
|
||||
///
|
||||
/// PatchMaps map coarse faces to their childrn feature adaptive patches.
|
||||
/// Coarse faces are indexed using their ptex face ID to resolve parametric
|
||||
/// ambiguity on non-quad faces. Note : this "map" is actually a vector, so
|
||||
/// queries are O(1) order.
|
||||
///
|
||||
/// @param faceid the ptex face index to search for
|
||||
///
|
||||
/// @param npatches the number of children patches found for the faceid
|
||||
///
|
||||
/// @param patches a set of pointers to the individual patch handles
|
||||
///
|
||||
bool GetChildPatchesHandles( int faceid, int * npatches, OsdPatchHandle const ** patches ) const {
|
||||
|
||||
if (_handles.empty() or _offsets.empty() or (faceid>=(int)_offsets.size()))
|
||||
return false;
|
||||
|
||||
*npatches = (faceid==(int)_offsets.size()-1 ? (unsigned int)_handles.size()-1 : _offsets[faceid+1]) - _offsets[faceid] + 1;
|
||||
|
||||
*patches = &_handles[ _offsets[faceid] ];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
friend class OsdCpuEvalLimitContext;
|
||||
|
||||
typedef std::multimap<unsigned int, OsdPatchHandle> MultiMap;
|
||||
|
||||
// Inserts the patches from the array into the multimap
|
||||
int _AddPatchArray( int arrayid, int ringsize,
|
||||
FarPatchTables::PtexCoordinateTable const & ptxtable,
|
||||
int & nfaces, MultiMap & mmap ) {
|
||||
|
||||
if (ptxtable.empty())
|
||||
return 0;
|
||||
|
||||
for (int i=0; i<(int)ptxtable.size(); ++i) {
|
||||
|
||||
int faceId = ptxtable[i].faceIndex;
|
||||
|
||||
OsdPatchHandle handle = { arrayid, i*ringsize, (unsigned int)mmap.size() };
|
||||
|
||||
mmap.insert( std::pair<unsigned int, OsdPatchHandle>(faceId, handle) );
|
||||
|
||||
nfaces = std::max(nfaces, faceId);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Constructor
|
||||
PatchMap( FarPatchTables const & patchTables ) {
|
||||
|
||||
int npatches = (int)patchTables.GetNumPatches();
|
||||
|
||||
_handles.reserve(npatches);
|
||||
|
||||
MultiMap mmap;
|
||||
|
||||
// Insert all the patch arrays into the map
|
||||
int arrayId=0, nfaces=0;
|
||||
|
||||
arrayId+=_AddPatchArray( arrayId,
|
||||
patchTables.GetRegularPatchRingsize(),
|
||||
patchTables.GetFullRegularPtexCoordinates(),
|
||||
nfaces, mmap );
|
||||
|
||||
arrayId+=_AddPatchArray( arrayId,
|
||||
patchTables.GetBoundaryPatchRingsize(),
|
||||
patchTables.GetFullBoundaryPtexCoordinates(),
|
||||
nfaces, mmap );
|
||||
|
||||
arrayId+=_AddPatchArray( arrayId,
|
||||
patchTables.GetCornerPatchRingsize(),
|
||||
patchTables.GetFullCornerPtexCoordinates(),
|
||||
nfaces, mmap );
|
||||
|
||||
arrayId+=_AddPatchArray( arrayId,
|
||||
patchTables.GetGregoryPatchRingsize(),
|
||||
patchTables.GetFullGregoryPtexCoordinates(),
|
||||
nfaces, mmap );
|
||||
|
||||
for (unsigned char pattern=0; pattern<5; ++pattern) {
|
||||
|
||||
arrayId+=_AddPatchArray( arrayId,
|
||||
patchTables.GetRegularPatchRingsize(),
|
||||
patchTables.GetTransitionRegularPtexCoordinates(pattern),
|
||||
nfaces, mmap );
|
||||
|
||||
for (unsigned char rot=0; rot<4; ++rot) {
|
||||
|
||||
arrayId+=_AddPatchArray( arrayId,
|
||||
patchTables.GetBoundaryPatchRingsize(),
|
||||
patchTables.GetTransitionBoundaryPtexCoordinates(pattern, rot),
|
||||
nfaces, mmap );
|
||||
|
||||
arrayId+=_AddPatchArray( arrayId,
|
||||
patchTables.GetCornerPatchRingsize(),
|
||||
patchTables.GetTransitionCornerPtexCoordinates(pattern, rot),
|
||||
nfaces, mmap );
|
||||
}
|
||||
}
|
||||
|
||||
++nfaces;
|
||||
|
||||
_handles.resize( mmap.size() );
|
||||
|
||||
_offsets.reserve( nfaces );
|
||||
_offsets.push_back(0);
|
||||
|
||||
unsigned int handlesIdx = 0, faceId=mmap.begin()->first;
|
||||
|
||||
// Serialize the multi-map
|
||||
for (MultiMap::const_iterator it=mmap.begin(); it!=mmap.end(); ++it, ++handlesIdx) {
|
||||
|
||||
assert(it->first >= faceId);
|
||||
|
||||
if (it->first != faceId) {
|
||||
|
||||
faceId = it->first;
|
||||
|
||||
// position the offset marker to the new face
|
||||
_offsets.push_back( handlesIdx );
|
||||
}
|
||||
|
||||
// copy the patch id into the table
|
||||
_handles[handlesIdx] = it->second;
|
||||
}
|
||||
}
|
||||
|
||||
// Patch handle allowing location of individual patch data inside patch
|
||||
// arrays or in serialized form
|
||||
std::vector<OsdPatchHandle> _handles;
|
||||
|
||||
// offset to the first handle of the child patches for each coarse face
|
||||
std::vector<unsigned int> _offsets;
|
||||
};
|
||||
|
||||
/// Returns a map object that can connect a faceId to a list of children patches
|
||||
const PatchMap * GetPatchesMap() const {
|
||||
const FarPatchTables::PatchMap * GetPatchesMap() const {
|
||||
return _patchMap;
|
||||
}
|
||||
|
||||
@ -326,21 +181,15 @@ protected:
|
||||
|
||||
private:
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
int _AppendPatchArray( OsdPatchDescriptor const & desc,
|
||||
FarPatchTables::PTable const & pT,
|
||||
FarPatchTables::PtexCoordinateTable const & ptxT );
|
||||
|
||||
|
||||
// Topology data for a mesh
|
||||
OsdPatchArrayVector _patchArrays; // patch descriptor for each patch in the mesh
|
||||
std::vector<FarPtexCoord::BitField> _patchBitFields; // per-patch parametric info
|
||||
std::vector<unsigned int> _patchBuffer; // list of control vertices
|
||||
FarPatchTables::PatchArrayVector _patchArrays; // patch descriptor for each patch in the mesh
|
||||
FarPatchTables::PTable _patches; // patch control vertices
|
||||
std::vector<FarPatchParam::BitField> _patchBitFields; // per-patch parametric info
|
||||
|
||||
std::vector<int> _vertexValenceBuffer; // extra Gregory patch data buffers
|
||||
std::vector<unsigned int> _quadOffsetBuffer;
|
||||
FarPatchTables::VertexValenceTable _vertexValenceBuffer; // extra Gregory patch data buffers
|
||||
FarPatchTables::QuadOffsetTable _quadOffsetBuffer;
|
||||
|
||||
PatchMap * _patchMap;
|
||||
FarPatchTables::PatchMap * _patchMap; // map of the sub-patches given a face index
|
||||
|
||||
OsdVertexBufferDescriptor _inDesc,
|
||||
_outDesc;
|
||||
|
@ -57,6 +57,7 @@
|
||||
|
||||
#include "../osd/cpuEvalLimitController.h"
|
||||
#include "../osd/cpuEvalLimitKernel.h"
|
||||
#include "../far/patchTables.h"
|
||||
|
||||
namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
@ -72,13 +73,12 @@ int
|
||||
OsdCpuEvalLimitController::_EvalLimitSample( OpenSubdiv::OsdEvalCoords const & coords,
|
||||
OsdCpuEvalLimitContext const *context,
|
||||
unsigned int index ) {
|
||||
|
||||
|
||||
int npatches=0;
|
||||
OsdPatchHandle const * patchHandles;
|
||||
FarPatchTables::PatchHandle const * patchHandles;
|
||||
|
||||
// Get the list of all children patches of the face described in coords
|
||||
if (not context->GetPatchesMap()->GetChildPatchesHandles( coords.face, &npatches, &patchHandles))
|
||||
if (not context->GetPatchesMap()->GetChildPatchesHandles(coords.face, &npatches, &patchHandles))
|
||||
return 0;
|
||||
|
||||
// Position lookup pointers at the indexed vertex
|
||||
@ -89,9 +89,9 @@ OsdCpuEvalLimitController::_EvalLimitSample( OpenSubdiv::OsdEvalCoords const & c
|
||||
|
||||
for (int i=0; i<npatches; ++i) {
|
||||
|
||||
OsdPatchHandle const & handle = patchHandles[i];
|
||||
FarPatchTables::PatchHandle const & handle = patchHandles[i];
|
||||
|
||||
FarPtexCoord::BitField bits = context->GetPatchBitFields()[ handle.serialIndex ];
|
||||
FarPatchParam::BitField bits = context->GetPatchBitFields()[ handle.serialIndex ];
|
||||
|
||||
float frac = 1.0f / float( 1 << bits.GetDepth() );
|
||||
|
||||
@ -106,9 +106,9 @@ OsdCpuEvalLimitController::_EvalLimitSample( OpenSubdiv::OsdEvalCoords const & c
|
||||
|
||||
assert( handle.array < context->GetPatchArrayVector().size() );
|
||||
|
||||
OsdPatchArray const & parray = context->GetPatchArrayVector()[ handle.array ];
|
||||
FarPatchTables::PatchArray const & parray = context->GetPatchArrayVector()[ handle.array ];
|
||||
|
||||
unsigned int const * cvs = &context->GetControlVertices()[ parray.firstIndex + handle.vertexOffset ];
|
||||
unsigned int const * cvs = &context->GetControlVertices()[ parray.GetVertIndex() + handle.vertexOffset ];
|
||||
|
||||
// normalize u,v coordinates
|
||||
float u = (coords.u - pu) / frac,
|
||||
@ -116,57 +116,49 @@ OsdCpuEvalLimitController::_EvalLimitSample( OpenSubdiv::OsdEvalCoords const & c
|
||||
|
||||
assert( (u>=0.0f) and (u<=1.0f) and (v>=0.0f) and (v<=1.0f) );
|
||||
|
||||
typedef FarPatchTables::Descriptor PD;
|
||||
|
||||
// Rotate u,v to compensate for transition pattern orientation
|
||||
if ( parray.GetDescriptor().GetPattern()!=FarPatchTables::NON_TRANSITION ) {
|
||||
switch( bits.GetRotation() ) {
|
||||
case 0 : break;
|
||||
case 1 : { float tmp=v; v=1.0f-u; u=tmp; } break;
|
||||
case 2 : { u=1.0f-u; v=1.0f-v; } break;
|
||||
case 3 : { float tmp=u; u=1.0f-v; v=tmp; } break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Based on patch type - go execute interpolation
|
||||
switch( parray.desc.type ) {
|
||||
switch( parray.GetDescriptor().GetType() ) {
|
||||
|
||||
case kRegular :
|
||||
evalBSpline( v, u, cvs,
|
||||
context->GetInputDesc(),
|
||||
inQ,
|
||||
context->GetOutputDesc(),
|
||||
outQ, outdQu, outdQv); return 1;
|
||||
|
||||
case kBoundary : return 0;
|
||||
|
||||
case kCorner : return 0;
|
||||
|
||||
case kGregory : /*evalGregory(v, u, cvs,
|
||||
unsigned int const * quadOffsetBuffer,
|
||||
int maxValence,
|
||||
unsigned int const * vertexIndices,
|
||||
OsdVertexBufferDescriptor const & inDesc,
|
||||
float const * inQ,
|
||||
OsdVertexBufferDescriptor const & outDesc,
|
||||
float * outQ,
|
||||
float * outDQU,
|
||||
float * outDQV );*/ return 0;
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
case kBoundaryGregory : return 0;
|
||||
|
||||
|
||||
case kTransitionRegular :
|
||||
switch( bits.GetRotation() ) {
|
||||
case 0 : break;
|
||||
case 1 : { float tmp=v; v=1.0f-u; u=tmp; } break;
|
||||
case 2 : { u=1.0f-u; v=1.0f-v; } break;
|
||||
case 3 : { float tmp=u; u=1.0f-v; v=tmp; } break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
evalBSpline( v, u, cvs,
|
||||
context->GetInputDesc(),
|
||||
inQ,
|
||||
context->GetOutputDesc(),
|
||||
outQ, outdQu, outdQv); return 1;
|
||||
|
||||
case kTransitionBoundary: return 0;
|
||||
|
||||
case kTransitionCorner : return 0;
|
||||
case FarPatchTables::REGULAR : {
|
||||
evalBSpline( v, u, cvs,
|
||||
context->GetInputDesc(),
|
||||
inQ,
|
||||
context->GetOutputDesc(),
|
||||
outQ, outdQu, outdQv);
|
||||
return 1; }
|
||||
|
||||
case FarPatchTables::BOUNDARY : { return 0; }
|
||||
|
||||
case FarPatchTables::CORNER : { return 0; }
|
||||
|
||||
|
||||
case FarPatchTables::GREGORY : { /*evalGregory(v, u, cvs,
|
||||
unsigned int const * quadOffsetBuffer,
|
||||
int maxValence,
|
||||
unsigned int const * vertexIndices,
|
||||
OsdVertexBufferDescriptor const & inDesc,
|
||||
float const * inQ,
|
||||
OsdVertexBufferDescriptor const & outDesc,
|
||||
float * outQ,
|
||||
float * outDQU,
|
||||
float * outDQV );*/
|
||||
return 0; }
|
||||
|
||||
case FarPatchTables::GREGORY_BOUNDARY : { return 0; }
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
|
@ -54,7 +54,6 @@
|
||||
// exclude the implied warranties of merchantability, fitness for
|
||||
// a particular purpose and non-infringement.
|
||||
//
|
||||
|
||||
#ifndef OSD_CPU_EVAL_LIMIT_CONTROLLER_H
|
||||
#define OSD_CPU_EVAL_LIMIT_CONTROLLER_H
|
||||
|
||||
|
@ -54,7 +54,6 @@
|
||||
// exclude the implied warranties of merchantability, fitness for
|
||||
// a particular purpose and non-infringement.
|
||||
//
|
||||
|
||||
#ifndef OSD_CPU_EVAL_LIMIT_KERNEL_H
|
||||
#define OSD_CPU_EVAL_LIMIT_KERNEL_H
|
||||
|
||||
|
@ -54,7 +54,6 @@
|
||||
// exclude the implied warranties of merchantability, fitness for
|
||||
// a particular purpose and non-infringement.
|
||||
//
|
||||
|
||||
#ifndef OSD_CPU_GL_VERTEX_BUFFER_H
|
||||
#define OSD_CPU_GL_VERTEX_BUFFER_H
|
||||
|
||||
@ -79,11 +78,15 @@
|
||||
namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
///
|
||||
/// \brief Concrete vertex buffer class for cpu subvision and OpenGL drawing.
|
||||
///
|
||||
/// OsdCpuGLVertexBuffer implements OsdCpuVertexBufferInterface and
|
||||
/// OsdGLVertexBufferInterface.
|
||||
/// The buffer interop between Cpu and GL is handled
|
||||
/// automatically when a client calls BindCpuBuffer and BindVBO methods.
|
||||
///
|
||||
/// The buffer interop between Cpu and GL is handled automatically when a
|
||||
/// client calls BindCpuBuffer and BindVBO methods.
|
||||
///
|
||||
class OsdCpuGLVertexBuffer {
|
||||
public:
|
||||
/// Creator. Returns NULL if error.
|
||||
@ -92,8 +95,8 @@ public:
|
||||
/// Destructor.
|
||||
~OsdCpuGLVertexBuffer();
|
||||
|
||||
/// This method is meant to be used in client code in order to provide
|
||||
/// coarse vertices data to Osd.
|
||||
/// This method is meant to be used in client code in order to provide coarse
|
||||
/// vertices data to Osd.
|
||||
void UpdateData(const float *src, int startVertex, int numVertices);
|
||||
|
||||
/// Returns how many elements defined in this vertex buffer.
|
||||
|
@ -64,7 +64,7 @@ namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
void OsdCpuComputeFace(
|
||||
const OsdVertexDescriptor *vdesc, float * vertex, float * varying,
|
||||
OsdVertexDescriptor const &vdesc, float * vertex, float * varying,
|
||||
const int *F_IT, const int *F_ITa, int vertexOffset, int tableOffset,
|
||||
int start, int end) {
|
||||
|
||||
@ -77,19 +77,19 @@ void OsdCpuComputeFace(
|
||||
// XXX: should use local vertex struct variable instead of
|
||||
// accumulating directly into global memory.
|
||||
int dstIndex = i + vertexOffset - tableOffset;
|
||||
vdesc->Clear(vertex, varying, dstIndex);
|
||||
vdesc.Clear(vertex, varying, dstIndex);
|
||||
|
||||
for (int j = 0; j < n; ++j) {
|
||||
int index = F_IT[h+j];
|
||||
vdesc->AddWithWeight(vertex, dstIndex, index, weight);
|
||||
vdesc->AddVaryingWithWeight(varying, dstIndex, index, weight);
|
||||
vdesc.AddWithWeight(vertex, dstIndex, index, weight);
|
||||
vdesc.AddVaryingWithWeight(varying, dstIndex, index, weight);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void OsdCpuComputeEdge(
|
||||
const OsdVertexDescriptor *vdesc, float *vertex, float *varying,
|
||||
OsdVertexDescriptor const &vdesc, float *vertex, float *varying,
|
||||
const int *E_IT, const float *E_W, int vertexOffset, int tableOffset,
|
||||
int start, int end) {
|
||||
|
||||
@ -102,25 +102,25 @@ void OsdCpuComputeEdge(
|
||||
float vertWeight = E_W[i*2+0];
|
||||
|
||||
int dstIndex = i + vertexOffset - tableOffset;
|
||||
vdesc->Clear(vertex, varying, dstIndex);
|
||||
vdesc.Clear(vertex, varying, dstIndex);
|
||||
|
||||
vdesc->AddWithWeight(vertex, dstIndex, eidx0, vertWeight);
|
||||
vdesc->AddWithWeight(vertex, dstIndex, eidx1, vertWeight);
|
||||
vdesc.AddWithWeight(vertex, dstIndex, eidx0, vertWeight);
|
||||
vdesc.AddWithWeight(vertex, dstIndex, eidx1, vertWeight);
|
||||
|
||||
if (eidx2 != -1) {
|
||||
float faceWeight = E_W[i*2+1];
|
||||
|
||||
vdesc->AddWithWeight(vertex, dstIndex, eidx2, faceWeight);
|
||||
vdesc->AddWithWeight(vertex, dstIndex, eidx3, faceWeight);
|
||||
vdesc.AddWithWeight(vertex, dstIndex, eidx2, faceWeight);
|
||||
vdesc.AddWithWeight(vertex, dstIndex, eidx3, faceWeight);
|
||||
}
|
||||
|
||||
vdesc->AddVaryingWithWeight(varying, dstIndex, eidx0, 0.5f);
|
||||
vdesc->AddVaryingWithWeight(varying, dstIndex, eidx1, 0.5f);
|
||||
vdesc.AddVaryingWithWeight(varying, dstIndex, eidx0, 0.5f);
|
||||
vdesc.AddVaryingWithWeight(varying, dstIndex, eidx1, 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
void OsdCpuComputeVertexA(
|
||||
const OsdVertexDescriptor *vdesc, float *vertex, float *varying,
|
||||
OsdVertexDescriptor const &vdesc, float *vertex, float *varying,
|
||||
const int *V_ITa, const float *V_W, int vertexOffset, int tableOffset,
|
||||
int start, int end, int pass) {
|
||||
|
||||
@ -141,23 +141,23 @@ void OsdCpuComputeVertexA(
|
||||
int dstIndex = i + vertexOffset - tableOffset;
|
||||
|
||||
if (not pass)
|
||||
vdesc->Clear(vertex, varying, dstIndex);
|
||||
vdesc.Clear(vertex, varying, dstIndex);
|
||||
|
||||
if (eidx0 == -1 || (pass == 0 && (n == -1))) {
|
||||
vdesc->AddWithWeight(vertex, dstIndex, p, weight);
|
||||
vdesc.AddWithWeight(vertex, dstIndex, p, weight);
|
||||
} else {
|
||||
vdesc->AddWithWeight(vertex, dstIndex, p, weight * 0.75f);
|
||||
vdesc->AddWithWeight(vertex, dstIndex, eidx0, weight * 0.125f);
|
||||
vdesc->AddWithWeight(vertex, dstIndex, eidx1, weight * 0.125f);
|
||||
vdesc.AddWithWeight(vertex, dstIndex, p, weight * 0.75f);
|
||||
vdesc.AddWithWeight(vertex, dstIndex, eidx0, weight * 0.125f);
|
||||
vdesc.AddWithWeight(vertex, dstIndex, eidx1, weight * 0.125f);
|
||||
}
|
||||
|
||||
if (not pass)
|
||||
vdesc->AddVaryingWithWeight(varying, dstIndex, p, 1.0f);
|
||||
vdesc.AddVaryingWithWeight(varying, dstIndex, p, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void OsdCpuComputeVertexB(
|
||||
const OsdVertexDescriptor *vdesc, float *vertex, float *varying,
|
||||
OsdVertexDescriptor const &vdesc, float *vertex, float *varying,
|
||||
const int *V_ITa, const int *V_IT, const float *V_W,
|
||||
int vertexOffset, int tableOffset, int start, int end) {
|
||||
|
||||
@ -171,20 +171,20 @@ void OsdCpuComputeVertexB(
|
||||
float wv = (n-2.0f) * n * wp;
|
||||
|
||||
int dstIndex = i + vertexOffset - tableOffset;
|
||||
vdesc->Clear(vertex, varying, dstIndex);
|
||||
vdesc.Clear(vertex, varying, dstIndex);
|
||||
|
||||
vdesc->AddWithWeight(vertex, dstIndex, p, weight * wv);
|
||||
vdesc.AddWithWeight(vertex, dstIndex, p, weight * wv);
|
||||
|
||||
for (int j = 0; j < n; ++j) {
|
||||
vdesc->AddWithWeight(vertex, dstIndex, V_IT[h+j*2], weight * wp);
|
||||
vdesc->AddWithWeight(vertex, dstIndex, V_IT[h+j*2+1], weight * wp);
|
||||
vdesc.AddWithWeight(vertex, dstIndex, V_IT[h+j*2], weight * wp);
|
||||
vdesc.AddWithWeight(vertex, dstIndex, V_IT[h+j*2+1], weight * wp);
|
||||
}
|
||||
vdesc->AddVaryingWithWeight(varying, dstIndex, p, 1.0f);
|
||||
vdesc.AddVaryingWithWeight(varying, dstIndex, p, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void OsdCpuComputeLoopVertexB(
|
||||
const OsdVertexDescriptor *vdesc, float *vertex, float *varying,
|
||||
OsdVertexDescriptor const &vdesc, float *vertex, float *varying,
|
||||
const int *V_ITa, const int *V_IT, const float *V_W,
|
||||
int vertexOffset, int tableOffset, int start, int end) {
|
||||
|
||||
@ -200,19 +200,19 @@ void OsdCpuComputeLoopVertexB(
|
||||
beta = (0.625f - beta) * wp;
|
||||
|
||||
int dstIndex = i + vertexOffset - tableOffset;
|
||||
vdesc->Clear(vertex, varying, dstIndex);
|
||||
vdesc.Clear(vertex, varying, dstIndex);
|
||||
|
||||
vdesc->AddWithWeight(vertex, dstIndex, p, weight * (1.0f - (beta * n)));
|
||||
vdesc.AddWithWeight(vertex, dstIndex, p, weight * (1.0f - (beta * n)));
|
||||
|
||||
for (int j = 0; j < n; ++j)
|
||||
vdesc->AddWithWeight(vertex, dstIndex, V_IT[h+j], weight * beta);
|
||||
vdesc.AddWithWeight(vertex, dstIndex, V_IT[h+j], weight * beta);
|
||||
|
||||
vdesc->AddVaryingWithWeight(varying, dstIndex, p, 1.0f);
|
||||
vdesc.AddVaryingWithWeight(varying, dstIndex, p, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void OsdCpuComputeBilinearEdge(
|
||||
const OsdVertexDescriptor *vdesc, float *vertex, float *varying,
|
||||
OsdVertexDescriptor const &vdesc, float *vertex, float *varying,
|
||||
const int *E_IT, int vertexOffset, int tableOffset, int start, int end) {
|
||||
|
||||
for (int i = start + tableOffset; i < end + tableOffset; i++) {
|
||||
@ -220,58 +220,58 @@ void OsdCpuComputeBilinearEdge(
|
||||
int eidx1 = E_IT[2*i+1];
|
||||
|
||||
int dstIndex = i + vertexOffset - tableOffset;
|
||||
vdesc->Clear(vertex, varying, dstIndex);
|
||||
vdesc.Clear(vertex, varying, dstIndex);
|
||||
|
||||
vdesc->AddWithWeight(vertex, dstIndex, eidx0, 0.5f);
|
||||
vdesc->AddWithWeight(vertex, dstIndex, eidx1, 0.5f);
|
||||
vdesc.AddWithWeight(vertex, dstIndex, eidx0, 0.5f);
|
||||
vdesc.AddWithWeight(vertex, dstIndex, eidx1, 0.5f);
|
||||
|
||||
vdesc->AddVaryingWithWeight(varying, dstIndex, eidx0, 0.5f);
|
||||
vdesc->AddVaryingWithWeight(varying, dstIndex, eidx1, 0.5f);
|
||||
vdesc.AddVaryingWithWeight(varying, dstIndex, eidx0, 0.5f);
|
||||
vdesc.AddVaryingWithWeight(varying, dstIndex, eidx1, 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
void OsdCpuComputeBilinearVertex(
|
||||
const OsdVertexDescriptor *vdesc, float *vertex, float *varying,
|
||||
OsdVertexDescriptor const &vdesc, float *vertex, float *varying,
|
||||
const int *V_ITa, int vertexOffset, int tableOffset, int start, int end) {
|
||||
|
||||
for (int i = start + tableOffset; i < end + tableOffset; i++) {
|
||||
int p = V_ITa[i];
|
||||
|
||||
int dstIndex = i + vertexOffset - tableOffset;
|
||||
vdesc->Clear(vertex, varying, dstIndex);
|
||||
vdesc.Clear(vertex, varying, dstIndex);
|
||||
|
||||
vdesc->AddWithWeight(vertex, dstIndex, p, 1.0f);
|
||||
vdesc->AddVaryingWithWeight(varying, dstIndex, p, 1.0f);
|
||||
vdesc.AddWithWeight(vertex, dstIndex, p, 1.0f);
|
||||
vdesc.AddVaryingWithWeight(varying, dstIndex, p, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void OsdCpuEditVertexAdd(
|
||||
const OsdVertexDescriptor *vdesc, float *vertex,
|
||||
OsdVertexDescriptor const &vdesc, float *vertex,
|
||||
int primVarOffset, int primVarWidth, int vertexOffset, int tableOffset,
|
||||
int start, int end,
|
||||
const unsigned int *editIndices, const float *editValues) {
|
||||
|
||||
for (int i = start+tableOffset; i < end+tableOffset; i++) {
|
||||
vdesc->ApplyVertexEditAdd(vertex,
|
||||
primVarOffset,
|
||||
primVarWidth,
|
||||
editIndices[i] + vertexOffset,
|
||||
&editValues[i*primVarWidth]);
|
||||
vdesc.ApplyVertexEditAdd(vertex,
|
||||
primVarOffset,
|
||||
primVarWidth,
|
||||
editIndices[i] + vertexOffset,
|
||||
&editValues[i*primVarWidth]);
|
||||
}
|
||||
}
|
||||
|
||||
void OsdCpuEditVertexSet(
|
||||
const OsdVertexDescriptor *vdesc, float *vertex,
|
||||
OsdVertexDescriptor const &vdesc, float *vertex,
|
||||
int primVarOffset, int primVarWidth, int vertexOffset, int tableOffset,
|
||||
int start, int end,
|
||||
const unsigned int *editIndices, const float *editValues) {
|
||||
|
||||
for (int i = start+tableOffset; i < end+tableOffset; i++) {
|
||||
vdesc->ApplyVertexEditSet(vertex,
|
||||
primVarOffset,
|
||||
primVarWidth,
|
||||
editIndices[i] + vertexOffset,
|
||||
&editValues[i*primVarWidth]);
|
||||
vdesc.ApplyVertexEditSet(vertex,
|
||||
primVarOffset,
|
||||
primVarWidth,
|
||||
editIndices[i] + vertexOffset,
|
||||
&editValues[i*primVarWidth]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,6 @@
|
||||
// exclude the implied warranties of merchantability, fitness for
|
||||
// a particular purpose and non-infringement.
|
||||
//
|
||||
|
||||
#ifndef OSD_CPU_KERNEL_H
|
||||
#define OSD_CPU_KERNEL_H
|
||||
|
||||
@ -66,57 +65,57 @@ namespace OPENSUBDIV_VERSION {
|
||||
|
||||
struct OsdVertexDescriptor;
|
||||
|
||||
void OsdCpuComputeFace(const OsdVertexDescriptor *vdesc,
|
||||
void OsdCpuComputeFace(OsdVertexDescriptor const &vdesc,
|
||||
float * vertex, float * varying,
|
||||
const int *F_IT, const int *F_ITa,
|
||||
int vertexOffset, int tableOffset,
|
||||
int start, int end);
|
||||
|
||||
void OsdCpuComputeEdge(const OsdVertexDescriptor *vdesc,
|
||||
void OsdCpuComputeEdge(OsdVertexDescriptor const &vdesc,
|
||||
float *vertex, float * varying,
|
||||
const int *E_IT, const float *E_ITa,
|
||||
int vertexOffset, int tableOffset,
|
||||
int start, int end);
|
||||
|
||||
void OsdCpuComputeVertexA(const OsdVertexDescriptor *vdesc,
|
||||
void OsdCpuComputeVertexA(OsdVertexDescriptor const &vdesc,
|
||||
float *vertex, float * varying,
|
||||
const int *V_ITa, const float *V_IT,
|
||||
int vertexOffset, int tableOffset,
|
||||
int start, int end, int pass);
|
||||
|
||||
void OsdCpuComputeVertexB(const OsdVertexDescriptor *vdesc,
|
||||
void OsdCpuComputeVertexB(OsdVertexDescriptor const &vdesc,
|
||||
float *vertex, float * varying,
|
||||
const int *V_ITa, const int *V_IT, const float *V_W,
|
||||
int vertexOffset, int tableOffset,
|
||||
int start, int end);
|
||||
|
||||
void OsdCpuComputeLoopVertexB(const OsdVertexDescriptor *vdesc,
|
||||
void OsdCpuComputeLoopVertexB(OsdVertexDescriptor const &vdesc,
|
||||
float *vertex, float * varying,
|
||||
const int *V_ITa, const int *V_IT,
|
||||
const float *V_W,
|
||||
int vertexOffset, int tableOffset,
|
||||
int start, int end);
|
||||
|
||||
void OsdCpuComputeBilinearEdge(const OsdVertexDescriptor *vdesc,
|
||||
void OsdCpuComputeBilinearEdge(OsdVertexDescriptor const &vdesc,
|
||||
float *vertex, float * varying,
|
||||
const int *E_IT,
|
||||
int vertexOffset, int tableOffset,
|
||||
int start, int end);
|
||||
|
||||
void OsdCpuComputeBilinearVertex(const OsdVertexDescriptor *vdesc,
|
||||
void OsdCpuComputeBilinearVertex(OsdVertexDescriptor const &vdesc,
|
||||
float *vertex, float * varying,
|
||||
const int *V_ITa,
|
||||
int vertexOffset, int tableOffset,
|
||||
int start, int end);
|
||||
|
||||
void OsdCpuEditVertexAdd(const OsdVertexDescriptor *vdesc, float *vertex,
|
||||
void OsdCpuEditVertexAdd(OsdVertexDescriptor const &vdesc, float *vertex,
|
||||
int primVarOffset, int primVarWidth,
|
||||
int vertexOffset, int tableOffset,
|
||||
int start, int end,
|
||||
const unsigned int *editIndices,
|
||||
const float *editValues);
|
||||
|
||||
void OsdCpuEditVertexSet(const OsdVertexDescriptor *vdesc, float *vertex,
|
||||
void OsdCpuEditVertexSet(OsdVertexDescriptor const &vdesc, float *vertex,
|
||||
int primVarOffset, int primVarWidth,
|
||||
int vertexOffset, int tableOffset,
|
||||
int start, int end,
|
||||
|
@ -75,8 +75,8 @@ public:
|
||||
/// Destructor.
|
||||
~OsdCpuVertexBuffer();
|
||||
|
||||
/// This method is meant to be used in client code in order to provide
|
||||
/// coarse vertices data to Osd.
|
||||
/// This method is meant to be used in client code in order to provide coarse
|
||||
/// vertices data to Osd.
|
||||
void UpdateData(const float *src, int startVertex, int numVertices);
|
||||
|
||||
/// Returns how many elements defined in this vertex buffer.
|
||||
|
@ -128,7 +128,7 @@ OsdCudaHEditTable::GetPrimvarWidth() const {
|
||||
return _primvarWidth;
|
||||
}
|
||||
|
||||
OsdCudaComputeContext::OsdCudaComputeContext(FarMesh<OsdVertex> *farMesh) {
|
||||
OsdCudaComputeContext::OsdCudaComputeContext(FarMesh<OsdVertex> const *farMesh) {
|
||||
|
||||
FarSubdivisionTables<OsdVertex> const * farTables =
|
||||
farMesh->GetSubdivisionTables();
|
||||
@ -201,20 +201,8 @@ OsdCudaComputeContext::GetCurrentVaryingBuffer() const {
|
||||
return _currentVaryingBuffer;
|
||||
}
|
||||
|
||||
int
|
||||
OsdCudaComputeContext::GetCurrentVertexNumElements() const {
|
||||
|
||||
return _numVertexElements;
|
||||
}
|
||||
|
||||
int
|
||||
OsdCudaComputeContext::GetCurrentVaryingNumElements() const {
|
||||
|
||||
return _numVaryingElements;
|
||||
}
|
||||
|
||||
OsdCudaComputeContext *
|
||||
OsdCudaComputeContext::Create(FarMesh<OsdVertex> *farmesh) {
|
||||
OsdCudaComputeContext::Create(FarMesh<OsdVertex> const *farmesh) {
|
||||
|
||||
return new OsdCudaComputeContext(farmesh);
|
||||
}
|
||||
|
@ -61,6 +61,7 @@
|
||||
|
||||
#include "../far/vertexEditTables.h"
|
||||
#include "../osd/vertex.h"
|
||||
#include "../osd/vertexDescriptor.h"
|
||||
#include "../osd/nonCopyable.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -128,7 +129,7 @@ public:
|
||||
///
|
||||
/// @param farmesh the FarMesh used for this Context.
|
||||
///
|
||||
static OsdCudaComputeContext * Create(FarMesh<OsdVertex> *farmesh);
|
||||
static OsdCudaComputeContext * Create(FarMesh<OsdVertex> const *farmesh);
|
||||
|
||||
/// Destructor
|
||||
virtual ~OsdCudaComputeContext();
|
||||
@ -137,27 +138,27 @@ public:
|
||||
/// that data buffers are properly inter-operated between Contexts and
|
||||
/// Controllers operating across multiple devices.
|
||||
///
|
||||
/// @param a buffer containing vertex-interpolated primvar data
|
||||
/// @param vertex a buffer containing vertex-interpolated primvar data
|
||||
///
|
||||
/// @param a buffer containing varying-interpolated primvar data
|
||||
/// @param varying a buffer containing varying-interpolated primvar data
|
||||
///
|
||||
template<class VERTEX_BUFFER, class VARYING_BUFFER>
|
||||
void Bind(VERTEX_BUFFER *vertex, VARYING_BUFFER *varying) {
|
||||
|
||||
if (vertex) {
|
||||
_currentVertexBuffer = static_cast<float*>(vertex->BindCudaBuffer());
|
||||
_numVertexElements = vertex->GetNumElements();
|
||||
_vdesc.numVertexElements = vertex->GetNumElements();
|
||||
} else {
|
||||
_currentVertexBuffer = 0;
|
||||
_numVertexElements = 0;
|
||||
_vdesc.numVertexElements = 0;
|
||||
}
|
||||
|
||||
if (varying) {
|
||||
_currentVaryingBuffer = static_cast<float*>(varying->BindCudaBuffer());
|
||||
_numVertexElements = varying->GetNumElements();
|
||||
_vdesc.numVertexElements = varying->GetNumElements();
|
||||
} else {
|
||||
_currentVaryingBuffer = 0;
|
||||
_numVaryingElements = 0;
|
||||
_vdesc.numVaryingElements = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -185,14 +186,20 @@ public:
|
||||
/// Returns a pointer to the vertex-interpolated data
|
||||
float * GetCurrentVertexBuffer() const;
|
||||
|
||||
/// Returns a pointer to the varying-interpolated data
|
||||
float * GetCurrentVaryingBuffer() const;
|
||||
|
||||
int GetCurrentVertexNumElements() const;
|
||||
/// Returns an OsdVertexDescriptor if vertex buffers have been bound.
|
||||
///
|
||||
/// @return a descriptor for the format of the vertex data currently bound
|
||||
///
|
||||
OsdVertexDescriptor const & GetVertexDescriptor() const {
|
||||
return _vdesc;
|
||||
}
|
||||
|
||||
int GetCurrentVaryingNumElements() const;
|
||||
|
||||
protected:
|
||||
explicit OsdCudaComputeContext(FarMesh<OsdVertex> *farMesh);
|
||||
explicit OsdCudaComputeContext(FarMesh<OsdVertex> const *farMesh);
|
||||
|
||||
private:
|
||||
std::vector<OsdCudaTable*> _tables;
|
||||
@ -202,7 +209,7 @@ private:
|
||||
float *_currentVertexBuffer, // cuda buffers
|
||||
*_currentVaryingBuffer;
|
||||
|
||||
int _numVertexElements, _numVaryingElements;
|
||||
OsdVertexDescriptor _vdesc;
|
||||
};
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
|
@ -129,8 +129,8 @@ OsdCudaComputeController::ApplyBilinearFaceVerticesKernel(
|
||||
OsdCudaComputeFace(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetCurrentVaryingBuffer(),
|
||||
context->GetCurrentVertexNumElements()-3,
|
||||
context->GetCurrentVaryingNumElements(),
|
||||
context->GetVertexDescriptor().numVertexElements-3,
|
||||
context->GetVertexDescriptor().numVaryingElements,
|
||||
static_cast<int*>(F_IT->GetCudaMemory()),
|
||||
static_cast<int*>(F_ITa->GetCudaMemory()),
|
||||
batch.GetVertexOffset(), batch.GetTableOffset(), batch.GetStart(), batch.GetEnd());
|
||||
@ -150,8 +150,8 @@ OsdCudaComputeController::ApplyBilinearEdgeVerticesKernel(
|
||||
OsdCudaComputeBilinearEdge(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetCurrentVaryingBuffer(),
|
||||
context->GetCurrentVertexNumElements()-3,
|
||||
context->GetCurrentVaryingNumElements(),
|
||||
context->GetVertexDescriptor().numVertexElements-3,
|
||||
context->GetVertexDescriptor().numVaryingElements,
|
||||
static_cast<int*>(E_IT->GetCudaMemory()),
|
||||
batch.GetVertexOffset(), batch.GetTableOffset(), batch.GetStart(), batch.GetEnd());
|
||||
}
|
||||
@ -170,8 +170,8 @@ OsdCudaComputeController::ApplyBilinearVertexVerticesKernel(
|
||||
OsdCudaComputeBilinearVertex(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetCurrentVaryingBuffer(),
|
||||
context->GetCurrentVertexNumElements()-3,
|
||||
context->GetCurrentVaryingNumElements(),
|
||||
context->GetVertexDescriptor().numVertexElements-3,
|
||||
context->GetVertexDescriptor().numVaryingElements,
|
||||
static_cast<int*>(V_ITa->GetCudaMemory()),
|
||||
batch.GetVertexOffset(), batch.GetTableOffset(), batch.GetStart(), batch.GetEnd());
|
||||
}
|
||||
@ -192,8 +192,8 @@ OsdCudaComputeController::ApplyCatmarkFaceVerticesKernel(
|
||||
OsdCudaComputeFace(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetCurrentVaryingBuffer(),
|
||||
context->GetCurrentVertexNumElements()-3,
|
||||
context->GetCurrentVaryingNumElements(),
|
||||
context->GetVertexDescriptor().numVertexElements-3,
|
||||
context->GetVertexDescriptor().numVaryingElements,
|
||||
static_cast<int*>(F_IT->GetCudaMemory()),
|
||||
static_cast<int*>(F_ITa->GetCudaMemory()),
|
||||
batch.GetVertexOffset(), batch.GetTableOffset(), batch.GetStart(), batch.GetEnd());
|
||||
@ -215,8 +215,8 @@ OsdCudaComputeController::ApplyCatmarkEdgeVerticesKernel(
|
||||
OsdCudaComputeEdge(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetCurrentVaryingBuffer(),
|
||||
context->GetCurrentVertexNumElements()-3,
|
||||
context->GetCurrentVaryingNumElements(),
|
||||
context->GetVertexDescriptor().numVertexElements-3,
|
||||
context->GetVertexDescriptor().numVaryingElements,
|
||||
static_cast<int*>(E_IT->GetCudaMemory()),
|
||||
static_cast<float*>(E_W->GetCudaMemory()),
|
||||
batch.GetVertexOffset(), batch.GetTableOffset(), batch.GetStart(), batch.GetEnd());
|
||||
@ -240,8 +240,8 @@ OsdCudaComputeController::ApplyCatmarkVertexVerticesKernelB(
|
||||
OsdCudaComputeVertexB(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetCurrentVaryingBuffer(),
|
||||
context->GetCurrentVertexNumElements()-3,
|
||||
context->GetCurrentVaryingNumElements(),
|
||||
context->GetVertexDescriptor().numVertexElements-3,
|
||||
context->GetVertexDescriptor().numVaryingElements,
|
||||
static_cast<int*>(V_ITa->GetCudaMemory()),
|
||||
static_cast<int*>(V_IT->GetCudaMemory()),
|
||||
static_cast<float*>(V_W->GetCudaMemory()),
|
||||
@ -264,8 +264,8 @@ OsdCudaComputeController::ApplyCatmarkVertexVerticesKernelA1(
|
||||
OsdCudaComputeVertexA(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetCurrentVaryingBuffer(),
|
||||
context->GetCurrentVertexNumElements()-3,
|
||||
context->GetCurrentVaryingNumElements(),
|
||||
context->GetVertexDescriptor().numVertexElements-3,
|
||||
context->GetVertexDescriptor().numVaryingElements,
|
||||
static_cast<int*>(V_ITa->GetCudaMemory()),
|
||||
static_cast<float*>(V_W->GetCudaMemory()),
|
||||
batch.GetVertexOffset(), batch.GetTableOffset(), batch.GetStart(), batch.GetEnd(), false);
|
||||
@ -287,8 +287,8 @@ OsdCudaComputeController::ApplyCatmarkVertexVerticesKernelA2(
|
||||
OsdCudaComputeVertexA(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetCurrentVaryingBuffer(),
|
||||
context->GetCurrentVertexNumElements()-3,
|
||||
context->GetCurrentVaryingNumElements(),
|
||||
context->GetVertexDescriptor().numVertexElements-3,
|
||||
context->GetVertexDescriptor().numVaryingElements,
|
||||
static_cast<int*>(V_ITa->GetCudaMemory()),
|
||||
static_cast<float*>(V_W->GetCudaMemory()),
|
||||
batch.GetVertexOffset(), batch.GetTableOffset(), batch.GetStart(), batch.GetEnd(), true);
|
||||
@ -310,8 +310,8 @@ OsdCudaComputeController::ApplyLoopEdgeVerticesKernel(
|
||||
OsdCudaComputeEdge(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetCurrentVaryingBuffer(),
|
||||
context->GetCurrentVertexNumElements()-3,
|
||||
context->GetCurrentVaryingNumElements(),
|
||||
context->GetVertexDescriptor().numVertexElements-3,
|
||||
context->GetVertexDescriptor().numVaryingElements,
|
||||
static_cast<int*>(E_IT->GetCudaMemory()),
|
||||
static_cast<float*>(E_W->GetCudaMemory()),
|
||||
batch.GetVertexOffset(), batch.GetTableOffset(), batch.GetStart(), batch.GetEnd());
|
||||
@ -335,8 +335,8 @@ OsdCudaComputeController::ApplyLoopVertexVerticesKernelB(
|
||||
OsdCudaComputeLoopVertexB(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetCurrentVaryingBuffer(),
|
||||
context->GetCurrentVertexNumElements()-3,
|
||||
context->GetCurrentVaryingNumElements(),
|
||||
context->GetVertexDescriptor().numVertexElements-3,
|
||||
context->GetVertexDescriptor().numVaryingElements,
|
||||
static_cast<int*>(V_ITa->GetCudaMemory()),
|
||||
static_cast<int*>(V_IT->GetCudaMemory()),
|
||||
static_cast<float*>(V_W->GetCudaMemory()),
|
||||
@ -359,8 +359,8 @@ OsdCudaComputeController::ApplyLoopVertexVerticesKernelA1(
|
||||
OsdCudaComputeVertexA(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetCurrentVaryingBuffer(),
|
||||
context->GetCurrentVertexNumElements()-3,
|
||||
context->GetCurrentVaryingNumElements(),
|
||||
context->GetVertexDescriptor().numVertexElements-3,
|
||||
context->GetVertexDescriptor().numVaryingElements,
|
||||
static_cast<int*>(V_ITa->GetCudaMemory()),
|
||||
static_cast<float*>(V_W->GetCudaMemory()),
|
||||
batch.GetVertexOffset(), batch.GetTableOffset(), batch.GetStart(), batch.GetEnd(), false);
|
||||
@ -382,8 +382,8 @@ OsdCudaComputeController::ApplyLoopVertexVerticesKernelA2(
|
||||
OsdCudaComputeVertexA(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetCurrentVaryingBuffer(),
|
||||
context->GetCurrentVertexNumElements()-3,
|
||||
context->GetCurrentVaryingNumElements(),
|
||||
context->GetVertexDescriptor().numVertexElements-3,
|
||||
context->GetVertexDescriptor().numVaryingElements,
|
||||
static_cast<int*>(V_ITa->GetCudaMemory()),
|
||||
static_cast<float*>(V_W->GetCudaMemory()),
|
||||
batch.GetVertexOffset(), batch.GetTableOffset(), batch.GetStart(), batch.GetEnd(), true);
|
||||
@ -406,7 +406,7 @@ OsdCudaComputeController::ApplyVertexEdits(
|
||||
if (edit->GetOperation() == FarVertexEdit::Add) {
|
||||
OsdCudaEditVertexAdd(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetCurrentVertexNumElements()-3,
|
||||
context->GetVertexDescriptor().numVertexElements-3,
|
||||
edit->GetPrimvarOffset(),
|
||||
edit->GetPrimvarWidth(),
|
||||
batch.GetVertexOffset(),
|
||||
|
@ -68,15 +68,26 @@ struct ID3D11DeviceContext;
|
||||
namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
/// \brief Concrete vertex buffer class for cuda subvision and D3D11 drawing.
|
||||
///
|
||||
/// OsdCudaD3D11VertexBuffer implements OsdCudaVertexBufferInterface and
|
||||
/// OsdD3D11VertexBufferInterface.
|
||||
///
|
||||
/// The buffer interop between Cuda and D3D is handled automatically when a
|
||||
/// client calls BindCudaBuffer and BindVBO methods.
|
||||
///
|
||||
class OsdCudaD3D11VertexBuffer {
|
||||
public:
|
||||
/// Creator. Returns NULL if error.
|
||||
static OsdCudaD3D11VertexBuffer * Create(int numElements, int numVertices,
|
||||
static OsdCudaD3D11VertexBuffer * Create(int numElements,
|
||||
int numVertices,
|
||||
ID3D11Device *device);
|
||||
|
||||
/// Destructor.
|
||||
virtual ~OsdCudaD3D11VertexBuffer();
|
||||
|
||||
/// This method is meant to be used in client code in order to provide coarse
|
||||
/// vertices data to Osd.
|
||||
void UpdateData(const float *src, int startVertex, int numVertices, void *param);
|
||||
|
||||
/// Returns how many elements defined in this vertex buffer.
|
||||
@ -94,7 +105,8 @@ public:
|
||||
|
||||
protected:
|
||||
/// Constructor.
|
||||
OsdCudaD3D11VertexBuffer(int numElements, int numVertices,
|
||||
OsdCudaD3D11VertexBuffer(int numElements,
|
||||
int numVertices,
|
||||
ID3D11Device *device);
|
||||
|
||||
bool allocate(ID3D11Device *device);
|
||||
|
@ -63,10 +63,13 @@ namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
/// \brief Concrete vertex buffer class for cuda subvision and OpenGL drawing.
|
||||
///
|
||||
/// OsdCudaGLVertexBuffer implements OsdCudaVertexBufferInterface and
|
||||
/// OsdGLVertexBufferInterface.
|
||||
/// The buffer interop between Cuda and GL is handled
|
||||
/// automatically when a client calls BindCudaBuffer and BindVBO methods.
|
||||
///
|
||||
/// The buffer interop between Cuda and GL is handled automatically when a
|
||||
/// client calls BindCudaBuffer and BindVBO methods.
|
||||
///
|
||||
class OsdCudaGLVertexBuffer {
|
||||
public:
|
||||
/// Creator. Returns NULL if error.
|
||||
@ -75,8 +78,8 @@ public:
|
||||
/// Destructor.
|
||||
~OsdCudaGLVertexBuffer();
|
||||
|
||||
/// This method is meant to be used in client code in order to provide
|
||||
/// coarse vertices data to Osd.
|
||||
/// This method is meant to be used in client code in order to provide coarse
|
||||
/// vertices data to Osd.
|
||||
void UpdateData(const float *src, int startVertex, int numVertices);
|
||||
|
||||
/// Returns how many elements defined in this vertex buffer.
|
||||
|
@ -63,8 +63,10 @@ namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
/// \brief Concrete vertex buffer class for Cuda subvision.
|
||||
///
|
||||
/// OsdCudaVertexBuffer implements OsdCudaVertexBufferInterface.
|
||||
/// An instance of this buffer class can be passed to OsdCudaComputeController
|
||||
///
|
||||
class OsdCudaVertexBuffer {
|
||||
|
||||
public:
|
||||
@ -74,8 +76,8 @@ public:
|
||||
/// Destructor.
|
||||
~OsdCudaVertexBuffer();
|
||||
|
||||
/// This method is meant to be used in client code in order to provide
|
||||
/// coarse vertices data to Osd.
|
||||
/// This method is meant to be used in client code in order to provide coarse
|
||||
/// vertices data to Osd.
|
||||
void UpdateData(const float *src, int startVertex, int numVertices);
|
||||
|
||||
/// Returns how many elements defined in this vertex buffer.
|
||||
|
@ -178,7 +178,7 @@ OsdD3D11ComputeHEditTable::GetPrimvarWidth() const {
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
OsdD3D11ComputeContext::OsdD3D11ComputeContext(
|
||||
FarMesh<OsdVertex> *farMesh, ID3D11DeviceContext *deviceContext)
|
||||
FarMesh<OsdVertex> const *farMesh, ID3D11DeviceContext *deviceContext)
|
||||
: _deviceContext(deviceContext),
|
||||
_currentVertexBufferUAV(0), _currentVaryingBufferUAV(0) {
|
||||
|
||||
@ -258,18 +258,6 @@ OsdD3D11ComputeContext::GetCurrentVaryingBufferUAV() const {
|
||||
return _currentVaryingBufferUAV;
|
||||
}
|
||||
|
||||
int
|
||||
OsdD3D11ComputeContext::GetNumCurrentVertexElements() const {
|
||||
|
||||
return _numVertexElements;
|
||||
}
|
||||
|
||||
int
|
||||
OsdD3D11ComputeContext::GetNumCurrentVaryingElements() const {
|
||||
|
||||
return _numVaryingElements;
|
||||
}
|
||||
|
||||
OsdD3D11ComputeKernelBundle *
|
||||
OsdD3D11ComputeContext::GetKernelBundle() const {
|
||||
|
||||
@ -294,7 +282,7 @@ OsdD3D11ComputeContext::SetDeviceContext(ID3D11DeviceContext *deviceContext) {
|
||||
}
|
||||
|
||||
OsdD3D11ComputeContext *
|
||||
OsdD3D11ComputeContext::Create(FarMesh<OsdVertex> *farmesh, ID3D11DeviceContext *deviceContext) {
|
||||
OsdD3D11ComputeContext::Create(FarMesh<OsdVertex> const *farmesh, ID3D11DeviceContext *deviceContext) {
|
||||
|
||||
return new OsdD3D11ComputeContext(farmesh, deviceContext);
|
||||
}
|
||||
|
@ -61,6 +61,7 @@
|
||||
|
||||
#include "../far/vertexEditTables.h"
|
||||
#include "../osd/vertex.h"
|
||||
#include "../osd/vertexDescriptor.h"
|
||||
#include "../osd/nonCopyable.h"
|
||||
|
||||
#include <D3D11.h>
|
||||
@ -137,7 +138,7 @@ public:
|
||||
///
|
||||
/// @param farmesh the FarMesh used for this Context.
|
||||
///
|
||||
static OsdD3D11ComputeContext * Create(FarMesh<OsdVertex> *farmesh,
|
||||
static OsdD3D11ComputeContext * Create(FarMesh<OsdVertex> const *farmesh,
|
||||
ID3D11DeviceContext *deviceContext);
|
||||
|
||||
/// Destructor
|
||||
@ -157,8 +158,8 @@ public:
|
||||
_currentVertexBufferUAV = vertex ? vertex->BindD3D11UAV(_deviceContext) : 0;
|
||||
_currentVaryingBufferUAV = varying ? varying->BindD3D11UAV(_deviceContext) : 0;
|
||||
|
||||
_numVertexElements = vertex ? vertex->GetNumElements() : 0;
|
||||
_numVaryingElements = varying ? varying->GetNumElements() : 0;
|
||||
_vdesc.numVertexElements = vertex ? vertex->GetNumElements() : 0;
|
||||
_vdesc.numVaryingElements = varying ? varying->GetNumElements() : 0;
|
||||
|
||||
bindShaderStorageBuffers();
|
||||
}
|
||||
@ -192,9 +193,13 @@ public:
|
||||
/// Returns a handle to the varying-interpolated buffer
|
||||
ID3D11UnorderedAccessView * GetCurrentVaryingBufferUAV() const;
|
||||
|
||||
int GetNumCurrentVertexElements() const;
|
||||
|
||||
int GetNumCurrentVaryingElements() const;
|
||||
/// Returns an OsdVertexDescriptor if vertex buffers have been bound.
|
||||
///
|
||||
/// @return a descriptor for the format of the vertex data currently bound
|
||||
///
|
||||
OsdVertexDescriptor const & GetVertexDescriptor() const {
|
||||
return _vdesc;
|
||||
}
|
||||
|
||||
OsdD3D11ComputeKernelBundle * GetKernelBundle() const;
|
||||
|
||||
@ -209,7 +214,7 @@ public:
|
||||
void UnbindEditShaderStorageBuffers();
|
||||
|
||||
protected:
|
||||
explicit OsdD3D11ComputeContext(FarMesh<OsdVertex> *farMesh, ID3D11DeviceContext *deviceContext);
|
||||
explicit OsdD3D11ComputeContext(FarMesh<OsdVertex> const *farMesh, ID3D11DeviceContext *deviceContext);
|
||||
|
||||
void bindShaderStorageBuffers();
|
||||
|
||||
@ -221,8 +226,7 @@ private:
|
||||
|
||||
ID3D11DeviceContext *_deviceContext;
|
||||
|
||||
int _numVertexElements;
|
||||
int _numVaryingElements;
|
||||
OsdVertexDescriptor _vdesc;
|
||||
|
||||
ID3D11UnorderedAccessView * _currentVertexBufferUAV,
|
||||
* _currentVaryingBufferUAV;
|
||||
|
249
opensubdiv/osd/d3d11DrawContext.cpp
Normal file → Executable file
249
opensubdiv/osd/d3d11DrawContext.cpp
Normal file → Executable file
@ -70,9 +70,7 @@ OsdD3D11DrawContext::OsdD3D11DrawContext() :
|
||||
vertexValenceBuffer(NULL),
|
||||
vertexValenceBufferSRV(NULL),
|
||||
quadOffsetBuffer(NULL),
|
||||
quadOffsetBufferSRV(NULL),
|
||||
patchLevelBuffer(NULL),
|
||||
patchLevelBufferSRV(NULL)
|
||||
quadOffsetBufferSRV(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
@ -88,67 +86,39 @@ OsdD3D11DrawContext::~OsdD3D11DrawContext()
|
||||
if (vertexValenceBufferSRV) vertexValenceBufferSRV->Release();
|
||||
if (quadOffsetBuffer) quadOffsetBuffer->Release();
|
||||
if (quadOffsetBufferSRV) quadOffsetBufferSRV->Release();
|
||||
if (patchLevelBuffer) patchLevelBuffer->Release();
|
||||
if (patchLevelBufferSRV) patchLevelBufferSRV->Release();
|
||||
};
|
||||
|
||||
bool
|
||||
OsdD3D11DrawContext::allocate(FarMesh<OsdVertex> *farMesh,
|
||||
ID3D11Buffer *vertexBuffer,
|
||||
int numElements,
|
||||
ID3D11DeviceContext *pd3d11DeviceContext,
|
||||
bool requirePtexCoordinates,
|
||||
bool requireFVarData)
|
||||
OsdD3D11DrawContext *
|
||||
OsdD3D11DrawContext::Create(FarPatchTables const *patchTables,
|
||||
ID3D11DeviceContext *pd3d11DeviceContext,
|
||||
bool requireFVarData)
|
||||
{
|
||||
OsdD3D11DrawContext * result = new OsdD3D11DrawContext();
|
||||
if (result->create(patchTables, pd3d11DeviceContext, requireFVarData))
|
||||
return result;
|
||||
|
||||
delete result;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
OsdD3D11DrawContext::create(FarPatchTables const *patchTables,
|
||||
ID3D11DeviceContext *pd3d11DeviceContext,
|
||||
bool requireFVarData)
|
||||
{
|
||||
// adaptive patches
|
||||
_isAdaptive = true;
|
||||
|
||||
ID3D11Device *pd3d11Device = NULL;
|
||||
pd3d11DeviceContext->GetDevice(&pd3d11Device);
|
||||
assert(pd3d11Device);
|
||||
|
||||
FarPatchTables const * patchTables = farMesh->GetPatchTables();
|
||||
ConvertPatchArrays(patchTables->GetPatchArrayVector(), patchArrays, patchTables->GetMaxValence(), 0);
|
||||
|
||||
if (not patchTables) {
|
||||
// uniform patches
|
||||
isAdaptive = false;
|
||||
|
||||
// XXX: farmesh should have FarDensePatchTable for dense mesh indices.
|
||||
// instead of GetFaceVertices().
|
||||
const FarSubdivisionTables<OsdVertex> *tables = farMesh->GetSubdivisionTables();
|
||||
int level = tables->GetMaxLevel();
|
||||
const std::vector<int> &indices = farMesh->GetFaceVertices(level-1);
|
||||
|
||||
int numIndices = (int)indices.size();
|
||||
|
||||
// Allocate and fill index buffer.
|
||||
D3D11_BUFFER_DESC bd;
|
||||
bd.ByteWidth = numIndices * sizeof(int);
|
||||
bd.Usage = D3D11_USAGE_DEFAULT;
|
||||
bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||
bd.CPUAccessFlags = 0;
|
||||
bd.MiscFlags = 0;
|
||||
bd.StructureByteStride = sizeof(int);
|
||||
D3D11_SUBRESOURCE_DATA initData;
|
||||
initData.pSysMem = &indices[0];
|
||||
HRESULT hr = pd3d11Device->CreateBuffer(&bd, &initData, &patchIndexBuffer);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OsdPatchArray array;
|
||||
array.desc.type = kNonPatch;
|
||||
array.desc.loop = dynamic_cast<const FarLoopSubdivisionTables<OsdVertex>*>(tables) != NULL;
|
||||
array.firstIndex = 0;
|
||||
array.numIndices = numIndices;
|
||||
|
||||
patchArrays.push_back(array);
|
||||
return true;
|
||||
}
|
||||
|
||||
// adaptive patches
|
||||
isAdaptive = true;
|
||||
|
||||
int totalPatchIndices = (int)patchTables->GetNumControlVertices();
|
||||
|
||||
int totalPatchLevels = (int)patchTables->GetNumPatches();
|
||||
FarPatchTables::PTable const & ptables = patchTables->GetPatchTable();
|
||||
FarPatchTables::PatchParamTable const & ptexCoordTables = patchTables->GetPatchParamTable();
|
||||
int totalPatchIndices = (int)ptables.size();
|
||||
int totalPatches = (int)ptexCoordTables.size();
|
||||
|
||||
// Allocate and fill index buffer.
|
||||
D3D11_BUFFER_DESC bd;
|
||||
@ -169,108 +139,42 @@ OsdD3D11DrawContext::allocate(FarMesh<OsdVertex> *farMesh,
|
||||
return false;
|
||||
}
|
||||
unsigned int * indexBuffer = (unsigned int *) mappedResource.pData;
|
||||
memcpy(indexBuffer, &ptables[0], totalPatchIndices * sizeof(unsigned int));
|
||||
|
||||
bd.ByteWidth = totalPatchLevels * sizeof(unsigned int);
|
||||
pd3d11DeviceContext->Unmap(patchIndexBuffer, 0);
|
||||
|
||||
// create ptex coordinate buffer
|
||||
bd.ByteWidth = totalPatches * sizeof(unsigned int);
|
||||
bd.Usage = D3D11_USAGE_DYNAMIC;
|
||||
bd.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
bd.MiscFlags = 0;
|
||||
bd.StructureByteStride = sizeof(unsigned int);
|
||||
hr = pd3d11Device->CreateBuffer(&bd, NULL, &patchLevelBuffer);
|
||||
hr = pd3d11Device->CreateBuffer(&bd, NULL, &ptexCoordinateBuffer);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvd;
|
||||
ZeroMemory(&srvd, sizeof(srvd));
|
||||
srvd.Format = DXGI_FORMAT_R32_SINT;
|
||||
srvd.Format = DXGI_FORMAT_R32_UINT; // XXX: this should be DXGI_FORMAT_R32G32_UINT?
|
||||
srvd.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
|
||||
srvd.Buffer.FirstElement = 0;
|
||||
srvd.Buffer.NumElements = totalPatchLevels;
|
||||
hr = pd3d11Device->CreateShaderResourceView(patchLevelBuffer, &srvd, &patchLevelBufferSRV);
|
||||
srvd.Buffer.NumElements = totalPatches;
|
||||
hr = pd3d11Device->CreateShaderResourceView(ptexCoordinateBuffer, &srvd, &ptexCoordinateBufferSRV);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = pd3d11DeviceContext->Map(patchLevelBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
|
||||
hr = pd3d11DeviceContext->Map(ptexCoordinateBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
unsigned int * levelBuffer = (unsigned int *) mappedResource.pData;
|
||||
unsigned int * ptexBuffer = (unsigned int *) mappedResource.pData;
|
||||
memcpy(ptexBuffer, &ptexCoordTables[0], totalPatches * sizeof(FarPatchParam));
|
||||
pd3d11DeviceContext->Unmap(ptexCoordinateBuffer, 0);
|
||||
|
||||
int indexBase = 0;
|
||||
int levelBase = 0;
|
||||
int maxValence = patchTables->GetMaxValence();
|
||||
|
||||
_AppendPatchArray(indexBuffer, &indexBase,
|
||||
levelBuffer, &levelBase,
|
||||
patchTables->GetFullRegularPatches(),
|
||||
patchTables->GetFullRegularPtexCoordinates(),
|
||||
patchTables->GetFullRegularFVarData(),
|
||||
farMesh->GetTotalFVarWidth(),
|
||||
OsdPatchDescriptor(kRegular, 0, 0, 0, 0), 0);
|
||||
_AppendPatchArray(indexBuffer, &indexBase,
|
||||
levelBuffer, &levelBase,
|
||||
patchTables->GetFullBoundaryPatches(),
|
||||
patchTables->GetFullBoundaryPtexCoordinates(),
|
||||
patchTables->GetFullBoundaryFVarData(),
|
||||
farMesh->GetTotalFVarWidth(),
|
||||
OsdPatchDescriptor(kBoundary, 0, 0, 0, 0), 0);
|
||||
_AppendPatchArray(indexBuffer, &indexBase,
|
||||
levelBuffer, &levelBase,
|
||||
patchTables->GetFullCornerPatches(),
|
||||
patchTables->GetFullCornerPtexCoordinates(),
|
||||
patchTables->GetFullCornerFVarData(),
|
||||
farMesh->GetTotalFVarWidth(),
|
||||
OsdPatchDescriptor(kCorner, 0, 0, 0, 0), 0);
|
||||
_AppendPatchArray(indexBuffer, &indexBase,
|
||||
levelBuffer, &levelBase,
|
||||
patchTables->GetFullGregoryPatches(),
|
||||
patchTables->GetFullGregoryPtexCoordinates(),
|
||||
patchTables->GetFullGregoryFVarData(),
|
||||
farMesh->GetTotalFVarWidth(),
|
||||
OsdPatchDescriptor(kGregory, 0, 0,
|
||||
maxValence, numElements), 0);
|
||||
_AppendPatchArray(indexBuffer, &indexBase,
|
||||
levelBuffer, &levelBase,
|
||||
patchTables->GetFullBoundaryGregoryPatches(),
|
||||
patchTables->GetFullBoundaryGregoryPtexCoordinates(),
|
||||
patchTables->GetFullBoundaryGregoryFVarData(),
|
||||
farMesh->GetTotalFVarWidth(),
|
||||
OsdPatchDescriptor(kBoundaryGregory, 0, 0,
|
||||
maxValence, numElements),
|
||||
(int)patchTables->GetFullGregoryPatches().first.size());
|
||||
|
||||
for (int p=0; p<5; ++p) {
|
||||
_AppendPatchArray(indexBuffer, &indexBase,
|
||||
levelBuffer, &levelBase,
|
||||
patchTables->GetTransitionRegularPatches(p),
|
||||
patchTables->GetTransitionRegularPtexCoordinates(p),
|
||||
patchTables->GetTransitionRegularFVarData(p),
|
||||
farMesh->GetTotalFVarWidth(),
|
||||
OsdPatchDescriptor(kTransitionRegular, p, 0, 0, 0), 0);
|
||||
for (int r=0; r<4; ++r) {
|
||||
_AppendPatchArray(indexBuffer, &indexBase,
|
||||
levelBuffer, &levelBase,
|
||||
patchTables->GetTransitionBoundaryPatches(p, r),
|
||||
patchTables->GetTransitionBoundaryPtexCoordinates(p, r),
|
||||
patchTables->GetTransitionBoundaryFVarData(p, r),
|
||||
farMesh->GetTotalFVarWidth(),
|
||||
OsdPatchDescriptor(kTransitionBoundary, p, r, 0, 0), 0);
|
||||
_AppendPatchArray(indexBuffer, &indexBase,
|
||||
levelBuffer, &levelBase,
|
||||
patchTables->GetTransitionCornerPatches(p, r),
|
||||
patchTables->GetTransitionCornerPtexCoordinates(p, r),
|
||||
patchTables->GetTransitionCornerFVarData(p, r),
|
||||
farMesh->GetTotalFVarWidth(),
|
||||
OsdPatchDescriptor(kTransitionCorner, p, r, 0, 0), 0);
|
||||
}
|
||||
}
|
||||
|
||||
pd3d11DeviceContext->Unmap(patchIndexBuffer, 0);
|
||||
pd3d11DeviceContext->Unmap(patchLevelBuffer, 0);
|
||||
|
||||
// allocate and initialize additional buffer data
|
||||
// create vertex valence buffer and vertex texture
|
||||
FarPatchTables::VertexValenceTable const &
|
||||
valenceTable = patchTables->GetVertexValenceTable();
|
||||
|
||||
@ -299,16 +203,6 @@ OsdD3D11DrawContext::allocate(FarMesh<OsdVertex> *farMesh,
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ZeroMemory(&srvd, sizeof(srvd));
|
||||
srvd.Format = DXGI_FORMAT_R32_FLOAT;
|
||||
srvd.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
|
||||
srvd.Buffer.FirstElement = 0;
|
||||
srvd.Buffer.NumElements = 6 * farMesh->GetNumVertices(); // XXX: dyu
|
||||
hr = pd3d11Device->CreateShaderResourceView(vertexBuffer, &srvd, &vertexBufferSRV);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
FarPatchTables::QuadOffsetTable const &
|
||||
@ -344,51 +238,36 @@ OsdD3D11DrawContext::allocate(FarMesh<OsdVertex> *farMesh,
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
OsdD3D11DrawContext::_AppendPatchArray(
|
||||
unsigned int *indexBuffer, int *indexBase,
|
||||
unsigned int *levelBuffer, int *levelBase,
|
||||
FarPatchTables::PTable const & ptable,
|
||||
FarPatchTables::PtexCoordinateTable const & ptexTable,
|
||||
FarPatchTables::FVarDataTable const & fvarTable, int fvarDataWidth,
|
||||
OsdPatchDescriptor const & desc,
|
||||
int gregoryQuadOffsetBase)
|
||||
OsdD3D11DrawContext::updateVertexTexture(ID3D11Buffer *vbo,
|
||||
ID3D11DeviceContext *pd3d11DeviceContext,
|
||||
int numVertices,
|
||||
int numVertexElements)
|
||||
{
|
||||
if (ptable.first.empty()) {
|
||||
ID3D11Device *pd3d11Device = NULL;
|
||||
pd3d11DeviceContext->GetDevice(&pd3d11Device);
|
||||
assert(pd3d11Device);
|
||||
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvd;
|
||||
ZeroMemory(&srvd, sizeof(srvd));
|
||||
srvd.Format = DXGI_FORMAT_R32_FLOAT;
|
||||
srvd.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
|
||||
srvd.Buffer.FirstElement = 0;
|
||||
srvd.Buffer.NumElements = numVertices * numVertexElements;
|
||||
HRESULT hr = pd3d11Device->CreateShaderResourceView(vbo, &srvd, &vertexBufferSRV);
|
||||
if (FAILED(hr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
OsdPatchArray array;
|
||||
array.desc = desc;
|
||||
array.firstIndex = *indexBase;
|
||||
array.numIndices = (int)ptable.first.size();
|
||||
array.levelBase = *levelBase;
|
||||
array.gregoryQuadOffsetBase = gregoryQuadOffsetBase;
|
||||
|
||||
int numSubPatches = 1;
|
||||
if (desc.type == OpenSubdiv::kTransitionRegular or
|
||||
desc.type == OpenSubdiv::kTransitionBoundary or
|
||||
desc.type == OpenSubdiv::kTransitionCorner) {
|
||||
int subPatchCounts[] = { 3, 4, 4, 4, 2 };
|
||||
numSubPatches = subPatchCounts[desc.pattern];
|
||||
}
|
||||
|
||||
for (int subpatch = 0; subpatch < numSubPatches; ++subpatch) {
|
||||
array.desc.subpatch = subpatch;
|
||||
patchArrays.push_back(array);
|
||||
// XXX: consider moving this proc to base class
|
||||
// updating num elements in descriptor with new vbo specs
|
||||
for (int i = 0; i < (int)patchArrays.size(); ++i) {
|
||||
PatchArray &parray = patchArrays[i];
|
||||
PatchDescriptor desc = parray.GetDescriptor();
|
||||
desc.SetNumElements(numVertexElements);
|
||||
parray.SetDescriptor(desc);
|
||||
}
|
||||
|
||||
memcpy(indexBuffer + array.firstIndex,
|
||||
&ptable.first[0], array.numIndices * sizeof(unsigned int));
|
||||
*indexBase += array.numIndices;
|
||||
|
||||
int numElements = array.numIndices/array.desc.GetPatchSize();
|
||||
assert(numElements == (int)ptable.second.size());
|
||||
|
||||
memcpy(levelBuffer + array.levelBase,
|
||||
&ptable.second[0], numElements * sizeof(unsigned char));
|
||||
|
||||
*levelBase += numElements;
|
||||
}
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
|
92
opensubdiv/osd/d3d11DrawContext.h
Normal file → Executable file
92
opensubdiv/osd/d3d11DrawContext.h
Normal file → Executable file
@ -48,6 +48,12 @@
|
||||
// with this license.
|
||||
// (E) The software is licensed "as-is." You bear the risk of
|
||||
// using it. The contributors give no express warranties,
|
||||
// guarantees or conditions. You may have additional consumer
|
||||
// rights under your local laws which this license cannot change.
|
||||
// To the extent permitted under your local laws, the contributors
|
||||
// exclude the implied warranties of merchantability, fitness for
|
||||
// a particular purpose and non-infringement.
|
||||
//
|
||||
#ifndef OSD_D3D11L_DRAW_CONTEXT_H
|
||||
#define OSD_D3D11L_DRAW_CONTEXT_H
|
||||
|
||||
@ -73,39 +79,55 @@ struct ID3D11DeviceContext;
|
||||
namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
/// \brief D3D11 specialized DrawContext class
|
||||
///
|
||||
/// OsdD3D11DrawContext implements the OSD drawing interface with Microsoft(c)
|
||||
/// DirectX D3D11 API.
|
||||
/// Some functionality may be disabled depending on compile and run-time driver
|
||||
/// support.
|
||||
///
|
||||
/// Contexts interface the serialized topological data pertaining to the
|
||||
/// geometric primitives with the capabilities of the selected discrete
|
||||
/// compute device.
|
||||
///
|
||||
class OsdD3D11DrawContext : public OsdDrawContext {
|
||||
public:
|
||||
typedef ID3D11Buffer * VertexBufferBinding;
|
||||
|
||||
OsdD3D11DrawContext();
|
||||
virtual ~OsdD3D11DrawContext();
|
||||
|
||||
template<class VERTEX_BUFFER>
|
||||
static OsdD3D11DrawContext *
|
||||
Create(FarMesh<OsdVertex> *farMesh,
|
||||
VERTEX_BUFFER *vertexBuffer,
|
||||
ID3D11DeviceContext *pd3d11DeviceContext,
|
||||
bool requirePtexCoordinates = false,
|
||||
bool requireFVarData = false) {
|
||||
|
||||
if (not vertexBuffer)
|
||||
return NULL;
|
||||
/// \brienf Create an OsdD3D11DrawContext from FarPatchTables
|
||||
///
|
||||
/// @param patchTables a valid set of FarPatchTables
|
||||
///
|
||||
/// @param pd3d11DeviceContext a device context
|
||||
///
|
||||
/// @param requireFVarData set to true to enable face-varying data to be
|
||||
/// carried over from the Far data structures.
|
||||
///
|
||||
///
|
||||
static OsdD3D11DrawContext *Create(FarPatchTables const *patchTables,
|
||||
ID3D11DeviceContext *pd3d11DeviceContext,
|
||||
bool requireFVarData=false);
|
||||
|
||||
OsdD3D11DrawContext * instance = new OsdD3D11DrawContext();
|
||||
if (instance->allocate(farMesh,
|
||||
vertexBuffer->BindD3D11Buffer(pd3d11DeviceContext),
|
||||
vertexBuffer->GetNumElements(),
|
||||
pd3d11DeviceContext,
|
||||
requirePtexCoordinates,
|
||||
requireFVarData)) return instance;
|
||||
delete instance;
|
||||
return NULL;
|
||||
/// Set vbo as a vertex texture (for gregory patch drawing)
|
||||
///
|
||||
/// @param vbo the vertex buffer object to update
|
||||
///
|
||||
/// @param pd3d11DeviceContext a device context
|
||||
///
|
||||
template<class VERTEX_BUFFER>
|
||||
void UpdateVertexTexture(VERTEX_BUFFER *vbo, ID3D11DeviceContext *pd3d11DeviceContext) {
|
||||
updateVertexTexture(vbo->BindD3D11Buffer(pd3d11DeviceContext),
|
||||
pd3d11DeviceContext,
|
||||
vbo->GetNumVertices(),
|
||||
vbo->GetNumElements());
|
||||
}
|
||||
|
||||
ID3D11Buffer *patchIndexBuffer;
|
||||
|
||||
ID3D11Buffer *ptexCoordinateBuffer;
|
||||
ID3D11Buffer *ptexCoordinateBufferSRV;
|
||||
ID3D11ShaderResourceView *ptexCoordinateBufferSRV;
|
||||
ID3D11Buffer *fvarDataBuffer;
|
||||
ID3D11Buffer *fvarDataBufferSRV;
|
||||
|
||||
@ -114,25 +136,21 @@ public:
|
||||
ID3D11ShaderResourceView *vertexValenceBufferSRV;
|
||||
ID3D11Buffer *quadOffsetBuffer;
|
||||
ID3D11ShaderResourceView *quadOffsetBufferSRV;
|
||||
ID3D11Buffer *patchLevelBuffer;
|
||||
ID3D11ShaderResourceView *patchLevelBufferSRV;
|
||||
|
||||
private:
|
||||
bool allocate(FarMesh<OsdVertex> *farmesh,
|
||||
ID3D11Buffer *vertexBuffer,
|
||||
int numElements,
|
||||
ID3D11DeviceContext *pd3d11DeviceContext,
|
||||
bool requirePtexCoordinates,
|
||||
bool requireFVarData);
|
||||
OsdD3D11DrawContext();
|
||||
|
||||
void _AppendPatchArray(
|
||||
unsigned int *indexBuffer, int *indexBase,
|
||||
unsigned int *levelBuffer, int *levelBase,
|
||||
FarPatchTables::PTable const & ptable,
|
||||
FarPatchTables::PtexCoordinateTable const & ptexTable,
|
||||
FarPatchTables::FVarDataTable const & fvarTable, int fvarDataWidth,
|
||||
OsdPatchDescriptor const & desc,
|
||||
int gregoryQuadOffsetBase);
|
||||
// allocate buffers from patchTables
|
||||
bool create(FarPatchTables const *patchTables,
|
||||
ID3D11DeviceContext *pd3d11DeviceContext,
|
||||
bool requireFVarData);
|
||||
|
||||
void updateVertexTexture(ID3D11Buffer *vbo,
|
||||
ID3D11DeviceContext *pd3d11DeviceContext,
|
||||
int numVertices,
|
||||
int numElements);
|
||||
|
||||
int _numVertices;
|
||||
};
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
|
@ -95,102 +95,107 @@ OsdD3D11DrawRegistryBase::~OsdD3D11DrawRegistryBase() {}
|
||||
|
||||
OsdD3D11DrawSourceConfig *
|
||||
OsdD3D11DrawRegistryBase::_CreateDrawSourceConfig(
|
||||
OsdPatchDescriptor const & desc, ID3D11Device * pd3dDevice)
|
||||
OsdDrawContext::PatchDescriptor const & desc, ID3D11Device * pd3dDevice)
|
||||
{
|
||||
OsdD3D11DrawSourceConfig * sconfig = _NewDrawSourceConfig();
|
||||
|
||||
sconfig->commonShader.source = commonShaderSource;
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << (int)desc.maxValence;
|
||||
ss << (int)desc.GetMaxValence();
|
||||
sconfig->commonShader.AddDefine("OSD_MAX_VALENCE", ss.str());
|
||||
ss.str("");
|
||||
ss << (int)desc.numElements;
|
||||
ss << (int)desc.GetNumElements();
|
||||
sconfig->commonShader.AddDefine("OSD_NUM_ELEMENTS", ss.str());
|
||||
}
|
||||
|
||||
switch (desc.type) {
|
||||
case kNonPatch:
|
||||
sconfig->vertexShader.source = regularShaderSource;
|
||||
sconfig->vertexShader.target = "vs_5_0";
|
||||
sconfig->vertexShader.entry = "vs_main";
|
||||
sconfig->pixelShader.source = regularShaderSource;
|
||||
sconfig->pixelShader.target = "ps_5_0";
|
||||
sconfig->pixelShader.entry = "ps_main";
|
||||
break;
|
||||
case kRegular:
|
||||
sconfig->vertexShader.source = regularShaderSource;
|
||||
sconfig->vertexShader.target = "vs_5_0";
|
||||
sconfig->vertexShader.entry = "vs_main_patches";
|
||||
sconfig->hullShader.source = regularShaderSource;
|
||||
sconfig->hullShader.target = "hs_5_0";
|
||||
sconfig->hullShader.entry = "hs_main_patches";
|
||||
sconfig->domainShader.source = regularShaderSource;
|
||||
sconfig->domainShader.target = "ds_5_0";
|
||||
sconfig->domainShader.entry = "ds_main_patches";
|
||||
sconfig->pixelShader.source = regularShaderSource;
|
||||
sconfig->pixelShader.target = "ps_5_0";
|
||||
sconfig->pixelShader.entry = "ps_main";
|
||||
break;
|
||||
case kBoundary:
|
||||
sconfig->vertexShader.source = boundaryShaderSource;
|
||||
sconfig->vertexShader.target = "vs_5_0";
|
||||
sconfig->vertexShader.entry = "vs_main_patches";
|
||||
sconfig->hullShader.source = boundaryShaderSource;
|
||||
sconfig->hullShader.target = "hs_5_0";
|
||||
sconfig->hullShader.entry = "hs_main_patches";
|
||||
sconfig->domainShader.source = boundaryShaderSource;
|
||||
sconfig->domainShader.target = "ds_5_0";
|
||||
sconfig->domainShader.entry = "ds_main_patches";
|
||||
sconfig->pixelShader.source = boundaryShaderSource;
|
||||
sconfig->pixelShader.target = "ps_5_0";
|
||||
sconfig->pixelShader.entry = "ps_main";
|
||||
break;
|
||||
case kCorner:
|
||||
sconfig->vertexShader.source = cornerShaderSource;
|
||||
sconfig->vertexShader.target = "vs_5_0";
|
||||
sconfig->vertexShader.entry = "vs_main_patches";
|
||||
sconfig->hullShader.source = cornerShaderSource;
|
||||
sconfig->hullShader.target = "hs_5_0";
|
||||
sconfig->hullShader.entry = "hs_main_patches";
|
||||
sconfig->domainShader.source = cornerShaderSource;
|
||||
sconfig->domainShader.target = "ds_5_0";
|
||||
sconfig->domainShader.entry = "ds_main_patches";
|
||||
sconfig->pixelShader.source = cornerShaderSource;
|
||||
sconfig->pixelShader.target = "ps_5_0";
|
||||
sconfig->pixelShader.entry = "ps_main";
|
||||
break;
|
||||
case kGregory:
|
||||
sconfig->vertexShader.source = gregoryShaderSource;
|
||||
sconfig->vertexShader.target = "vs_5_0";
|
||||
sconfig->vertexShader.entry = "vs_main_patches";
|
||||
sconfig->hullShader.source = gregoryShaderSource;
|
||||
sconfig->hullShader.target = "hs_5_0";
|
||||
sconfig->hullShader.entry = "hs_main_patches";
|
||||
sconfig->domainShader.source = gregoryShaderSource;
|
||||
sconfig->domainShader.target = "ds_5_0";
|
||||
sconfig->domainShader.entry = "ds_main_patches";
|
||||
sconfig->pixelShader.source = gregoryShaderSource;
|
||||
sconfig->pixelShader.target = "ps_5_0";
|
||||
sconfig->pixelShader.entry = "ps_main";
|
||||
break;
|
||||
case kBoundaryGregory:
|
||||
sconfig->vertexShader.source = boundaryGregoryShaderSource;
|
||||
sconfig->vertexShader.target = "vs_5_0";
|
||||
sconfig->vertexShader.entry = "vs_main_patches";
|
||||
sconfig->hullShader.source = boundaryGregoryShaderSource;
|
||||
sconfig->hullShader.target = "hs_5_0";
|
||||
sconfig->hullShader.entry = "hs_main_patches";
|
||||
sconfig->domainShader.source = boundaryGregoryShaderSource;
|
||||
sconfig->domainShader.target = "ds_5_0";
|
||||
sconfig->domainShader.entry = "ds_main_patches";
|
||||
sconfig->pixelShader.source = boundaryGregoryShaderSource;
|
||||
sconfig->pixelShader.target = "ps_5_0";
|
||||
sconfig->pixelShader.entry = "ps_main";
|
||||
break;
|
||||
case kTransitionRegular:
|
||||
case kTransitionBoundary:
|
||||
case kTransitionCorner:
|
||||
if (desc.GetPattern() == FarPatchTables::NON_TRANSITION) {
|
||||
switch (desc.GetType()) {
|
||||
case FarPatchTables::QUADS:
|
||||
case FarPatchTables::TRIANGLES:
|
||||
sconfig->vertexShader.source = regularShaderSource;
|
||||
sconfig->vertexShader.target = "vs_5_0";
|
||||
sconfig->vertexShader.entry = "vs_main";
|
||||
sconfig->pixelShader.source = regularShaderSource;
|
||||
sconfig->pixelShader.target = "ps_5_0";
|
||||
sconfig->pixelShader.entry = "ps_main";
|
||||
break;
|
||||
case FarPatchTables::REGULAR:
|
||||
sconfig->vertexShader.source = regularShaderSource;
|
||||
sconfig->vertexShader.target = "vs_5_0";
|
||||
sconfig->vertexShader.entry = "vs_main_patches";
|
||||
sconfig->hullShader.source = regularShaderSource;
|
||||
sconfig->hullShader.target = "hs_5_0";
|
||||
sconfig->hullShader.entry = "hs_main_patches";
|
||||
sconfig->domainShader.source = regularShaderSource;
|
||||
sconfig->domainShader.target = "ds_5_0";
|
||||
sconfig->domainShader.entry = "ds_main_patches";
|
||||
sconfig->pixelShader.source = regularShaderSource;
|
||||
sconfig->pixelShader.target = "ps_5_0";
|
||||
sconfig->pixelShader.entry = "ps_main";
|
||||
break;
|
||||
case FarPatchTables::BOUNDARY:
|
||||
sconfig->vertexShader.source = boundaryShaderSource;
|
||||
sconfig->vertexShader.target = "vs_5_0";
|
||||
sconfig->vertexShader.entry = "vs_main_patches";
|
||||
sconfig->hullShader.source = boundaryShaderSource;
|
||||
sconfig->hullShader.target = "hs_5_0";
|
||||
sconfig->hullShader.entry = "hs_main_patches";
|
||||
sconfig->domainShader.source = boundaryShaderSource;
|
||||
sconfig->domainShader.target = "ds_5_0";
|
||||
sconfig->domainShader.entry = "ds_main_patches";
|
||||
sconfig->pixelShader.source = boundaryShaderSource;
|
||||
sconfig->pixelShader.target = "ps_5_0";
|
||||
sconfig->pixelShader.entry = "ps_main";
|
||||
break;
|
||||
case FarPatchTables::CORNER:
|
||||
sconfig->vertexShader.source = cornerShaderSource;
|
||||
sconfig->vertexShader.target = "vs_5_0";
|
||||
sconfig->vertexShader.entry = "vs_main_patches";
|
||||
sconfig->hullShader.source = cornerShaderSource;
|
||||
sconfig->hullShader.target = "hs_5_0";
|
||||
sconfig->hullShader.entry = "hs_main_patches";
|
||||
sconfig->domainShader.source = cornerShaderSource;
|
||||
sconfig->domainShader.target = "ds_5_0";
|
||||
sconfig->domainShader.entry = "ds_main_patches";
|
||||
sconfig->pixelShader.source = cornerShaderSource;
|
||||
sconfig->pixelShader.target = "ps_5_0";
|
||||
sconfig->pixelShader.entry = "ps_main";
|
||||
break;
|
||||
case FarPatchTables::GREGORY:
|
||||
sconfig->vertexShader.source = gregoryShaderSource;
|
||||
sconfig->vertexShader.target = "vs_5_0";
|
||||
sconfig->vertexShader.entry = "vs_main_patches";
|
||||
sconfig->hullShader.source = gregoryShaderSource;
|
||||
sconfig->hullShader.target = "hs_5_0";
|
||||
sconfig->hullShader.entry = "hs_main_patches";
|
||||
sconfig->domainShader.source = gregoryShaderSource;
|
||||
sconfig->domainShader.target = "ds_5_0";
|
||||
sconfig->domainShader.entry = "ds_main_patches";
|
||||
sconfig->pixelShader.source = gregoryShaderSource;
|
||||
sconfig->pixelShader.target = "ps_5_0";
|
||||
sconfig->pixelShader.entry = "ps_main";
|
||||
break;
|
||||
case FarPatchTables::GREGORY_BOUNDARY:
|
||||
sconfig->vertexShader.source = boundaryGregoryShaderSource;
|
||||
sconfig->vertexShader.target = "vs_5_0";
|
||||
sconfig->vertexShader.entry = "vs_main_patches";
|
||||
sconfig->hullShader.source = boundaryGregoryShaderSource;
|
||||
sconfig->hullShader.target = "hs_5_0";
|
||||
sconfig->hullShader.entry = "hs_main_patches";
|
||||
sconfig->domainShader.source = boundaryGregoryShaderSource;
|
||||
sconfig->domainShader.target = "ds_5_0";
|
||||
sconfig->domainShader.entry = "ds_main_patches";
|
||||
sconfig->pixelShader.source = boundaryGregoryShaderSource;
|
||||
sconfig->pixelShader.target = "ps_5_0";
|
||||
sconfig->pixelShader.entry = "ps_main";
|
||||
break;
|
||||
default:
|
||||
delete sconfig;
|
||||
sconfig = NULL;
|
||||
break;
|
||||
}
|
||||
} else { // pattern != NON_TRANSITION
|
||||
sconfig->vertexShader.source = transitionShaderSource;
|
||||
sconfig->vertexShader.target = "vs_5_0";
|
||||
sconfig->vertexShader.entry = "vs_main_patches";
|
||||
@ -203,32 +208,26 @@ OsdD3D11DrawRegistryBase::_CreateDrawSourceConfig(
|
||||
sconfig->pixelShader.source = transitionShaderSource;
|
||||
sconfig->pixelShader.target = "ps_5_0";
|
||||
sconfig->pixelShader.entry = "ps_main";
|
||||
{
|
||||
int pattern = desc.pattern;
|
||||
int rotation = desc.rotation;
|
||||
int subpatch = desc.subpatch;
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << "CASE" << pattern << subpatch;
|
||||
sconfig->hullShader.AddDefine(ss.str());
|
||||
sconfig->domainShader.AddDefine(ss.str());
|
||||
int pattern = desc.GetPattern() - 1;
|
||||
int rotation = desc.GetRotation();
|
||||
int subpatch = desc.GetSubPatch();
|
||||
|
||||
ss.str("");
|
||||
ss << rotation;
|
||||
sconfig->hullShader.AddDefine("ROTATE", ss.str());
|
||||
sconfig->domainShader.AddDefine("ROTATE", ss.str());
|
||||
}
|
||||
if (desc.type == kTransitionBoundary) {
|
||||
std::ostringstream ss;
|
||||
ss << "CASE" << pattern << subpatch;
|
||||
sconfig->hullShader.AddDefine(ss.str());
|
||||
sconfig->domainShader.AddDefine(ss.str());
|
||||
|
||||
ss.str("");
|
||||
ss << rotation;
|
||||
sconfig->hullShader.AddDefine("ROTATE", ss.str());
|
||||
sconfig->domainShader.AddDefine("ROTATE", ss.str());
|
||||
|
||||
if (desc.GetType() == FarPatchTables::BOUNDARY) {
|
||||
sconfig->hullShader.AddDefine("BOUNDARY");
|
||||
} else if (desc.type == kTransitionCorner) {
|
||||
} else if (desc.GetType() == FarPatchTables::CORNER) {
|
||||
sconfig->hullShader.AddDefine("CORNER");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// error
|
||||
delete sconfig;
|
||||
sconfig = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
return sconfig;
|
||||
|
@ -48,6 +48,12 @@
|
||||
// with this license.
|
||||
// (E) The software is licensed "as-is." You bear the risk of
|
||||
// using it. The contributors give no express warranties,
|
||||
// guarantees or conditions. You may have additional consumer
|
||||
// rights under your local laws which this license cannot change.
|
||||
// To the extent permitted under your local laws, the contributors
|
||||
// exclude the implied warranties of merchantability, fitness for
|
||||
// a particular purpose and non-infringement.
|
||||
//
|
||||
#ifndef OSD_D3D11_DRAW_REGISTRY_H
|
||||
#define OSD_D3D11_DRAW_REGISTRY_H
|
||||
|
||||
@ -101,7 +107,7 @@ struct OsdD3D11DrawSourceConfig {
|
||||
|
||||
class OsdD3D11DrawRegistryBase {
|
||||
public:
|
||||
typedef OsdPatchDescriptor DescType;
|
||||
typedef OsdDrawContext::PatchDescriptor DescType;
|
||||
typedef OsdD3D11DrawConfig ConfigType;
|
||||
typedef OsdD3D11DrawSourceConfig SourceConfigType;
|
||||
|
||||
@ -122,7 +128,7 @@ protected:
|
||||
_CreateDrawSourceConfig(DescType const & desc, ID3D11Device * pd3dDevice);
|
||||
};
|
||||
|
||||
template <class DESC_TYPE = OsdPatchDescriptor,
|
||||
template <class DESC_TYPE = OsdDrawContext::PatchDescriptor,
|
||||
class CONFIG_TYPE = OsdD3D11DrawConfig,
|
||||
class SOURCE_CONFIG_TYPE = OsdD3D11DrawSourceConfig >
|
||||
class OsdD3D11DrawRegistry : public OsdD3D11DrawRegistryBase {
|
||||
@ -134,7 +140,6 @@ public:
|
||||
typedef SOURCE_CONFIG_TYPE SourceConfigType;
|
||||
|
||||
typedef std::map<DescType, ConfigType *> ConfigMap;
|
||||
typedef std::map<DescType, SourceConfigType *> SourceConfigMap;
|
||||
|
||||
public:
|
||||
virtual ~OsdD3D11DrawRegistry() {
|
||||
@ -147,11 +152,6 @@ public:
|
||||
delete i->second;
|
||||
}
|
||||
_configMap.clear();
|
||||
for (typename SourceConfigMap::iterator
|
||||
i = _sourceConfigMap.begin(); i != _sourceConfigMap.end(); ++i) {
|
||||
delete i->second;
|
||||
}
|
||||
_sourceConfigMap.clear();
|
||||
}
|
||||
|
||||
// fetch shader config
|
||||
@ -167,7 +167,7 @@ public:
|
||||
} else {
|
||||
ConfigType * config =
|
||||
_CreateDrawConfig(desc,
|
||||
GetDrawSourceConfig(desc, pd3dDevice),
|
||||
_CreateDrawSourceConfig(desc, pd3dDevice),
|
||||
pd3dDevice,
|
||||
ppInputLayout,
|
||||
pInputElementDescs, numInputElements);
|
||||
@ -176,19 +176,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// fetch text and related defines for patch descriptor
|
||||
SourceConfigType *
|
||||
GetDrawSourceConfig(DescType const & desc, ID3D11Device * pd3dDevice) {
|
||||
typename SourceConfigMap::iterator it = _sourceConfigMap.find(desc);
|
||||
if (it != _sourceConfigMap.end()) {
|
||||
return it->second;
|
||||
} else {
|
||||
SourceConfigType * sconfig = _CreateDrawSourceConfig(desc, pd3dDevice);
|
||||
_sourceConfigMap[desc] = sconfig;
|
||||
return sconfig;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ConfigType * _NewDrawConfig() { return new ConfigType(); }
|
||||
virtual ConfigType *
|
||||
@ -205,7 +192,6 @@ protected:
|
||||
|
||||
private:
|
||||
ConfigMap _configMap;
|
||||
SourceConfigMap _sourceConfigMap;
|
||||
};
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
|
@ -115,8 +115,7 @@ bool
|
||||
OsdD3D11ComputeKernelBundle::Compile(int numVertexElements,
|
||||
int numVaryingElements) {
|
||||
|
||||
_numVertexElements = numVertexElements;
|
||||
_numVaryingElements = numVaryingElements;
|
||||
_vdesc.Set( numVertexElements, numVaryingElements );
|
||||
|
||||
DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
|
||||
#ifdef _DEBUG
|
||||
|
@ -54,13 +54,13 @@
|
||||
// exclude the implied warranties of merchantability, fitness for
|
||||
// a particular purpose and non-infringement.
|
||||
//
|
||||
|
||||
#ifndef OSD_D3D11_COMPUTE_KERNEL_BUNDLE_H
|
||||
#define OSD_D3D11_COMPUTE_KERNEL_BUNDLE_H
|
||||
|
||||
#include "../version.h"
|
||||
|
||||
#include "../osd/nonCopyable.h"
|
||||
#include "../osd/vertexDescriptor.h"
|
||||
|
||||
struct ID3D11Buffer;
|
||||
struct ID3D11ClassInstance;
|
||||
@ -71,95 +71,100 @@ struct ID3D11DeviceContext;
|
||||
namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
class OsdD3D11ComputeKernelBundle
|
||||
: OsdNonCopyable<OsdD3D11ComputeKernelBundle> {
|
||||
public:
|
||||
OsdD3D11ComputeKernelBundle(ID3D11DeviceContext *deviceContext);
|
||||
~OsdD3D11ComputeKernelBundle();
|
||||
class OsdD3D11ComputeKernelBundle : OsdNonCopyable<OsdD3D11ComputeKernelBundle> {
|
||||
|
||||
bool Compile(int numVertexElements, int numVaryingElements);
|
||||
public:
|
||||
/// Constructor
|
||||
OsdD3D11ComputeKernelBundle(ID3D11DeviceContext *deviceContext);
|
||||
|
||||
/// Destructor
|
||||
~OsdD3D11ComputeKernelBundle();
|
||||
|
||||
void ApplyBilinearFaceVerticesKernel(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
bool Compile(int numVertexElements, int numVaryingElements);
|
||||
|
||||
void ApplyBilinearEdgeVerticesKernel(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyBilinearFaceVerticesKernel(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void ApplyBilinearVertexVerticesKernel(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyBilinearEdgeVerticesKernel(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void ApplyCatmarkFaceVerticesKernel(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyBilinearVertexVerticesKernel(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void ApplyCatmarkEdgeVerticesKernel(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyCatmarkFaceVerticesKernel(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void ApplyCatmarkVertexVerticesKernelB(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyCatmarkEdgeVerticesKernel(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void ApplyCatmarkVertexVerticesKernelA(
|
||||
int vertexOffset, int tableOffset, int start, int end, bool pass);
|
||||
void ApplyCatmarkVertexVerticesKernelB(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void ApplyLoopEdgeVerticesKernel(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyCatmarkVertexVerticesKernelA(
|
||||
int vertexOffset, int tableOffset, int start, int end, bool pass);
|
||||
|
||||
void ApplyLoopVertexVerticesKernelB(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyLoopEdgeVerticesKernel(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void ApplyLoopVertexVerticesKernelA(
|
||||
int vertexOffset, int tableOffset, int start, int end, bool pass);
|
||||
void ApplyLoopVertexVerticesKernelB(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void ApplyEditAdd(int primvarOffset, int primvarWidth,
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyLoopVertexVerticesKernelA(
|
||||
int vertexOffset, int tableOffset, int start, int end, bool pass);
|
||||
|
||||
struct Match {
|
||||
Match(int numVertexElements, int numVaryingElements) :
|
||||
_numVertexElements(numVertexElements),
|
||||
_numVaryingElements(numVaryingElements) {}
|
||||
bool operator() (const OsdD3D11ComputeKernelBundle *kernel) {
|
||||
return (kernel->_numVertexElements == _numVertexElements
|
||||
&& kernel->_numVaryingElements == _numVaryingElements);
|
||||
}
|
||||
int _numVertexElements, _numVaryingElements;
|
||||
};
|
||||
void ApplyEditAdd(int primvarOffset, int primvarWidth,
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
friend struct Match;
|
||||
struct Match {
|
||||
|
||||
protected:
|
||||
struct KernelCB;
|
||||
void dispatchCompute(ID3D11ClassInstance * kernel, KernelCB const & args);
|
||||
/// Constructor
|
||||
Match(int numVertexElements, int numVaryingElements)
|
||||
: vdesc(numVertexElements, numVaryingElements) {
|
||||
}
|
||||
|
||||
ID3D11DeviceContext * _deviceContext;
|
||||
bool operator() (OsdD3D11ComputeKernelBundle const *kernel) {
|
||||
return vdesc == kernel->_vdesc;
|
||||
}
|
||||
|
||||
ID3D11ComputeShader * _computeShader;
|
||||
ID3D11ClassLinkage * _classLinkage;
|
||||
|
||||
// constant buffer
|
||||
ID3D11Buffer * _kernelCB;
|
||||
|
||||
// general face-vertex kernel (all schemes)
|
||||
ID3D11ClassInstance * _kernelComputeFace;
|
||||
// edge-vertex kernel (catmark + loop schemes)
|
||||
ID3D11ClassInstance * _kernelComputeEdge;
|
||||
// edge-vertex kernel (bilinear scheme)
|
||||
ID3D11ClassInstance * _kernelComputeBilinearEdge;
|
||||
// vertex-vertex kernel (bilinear scheme)
|
||||
ID3D11ClassInstance * _kernelComputeVertex;
|
||||
// vertex-vertex kernel A (catmark + loop schemes)
|
||||
ID3D11ClassInstance * _kernelComputeVertexA;
|
||||
// vertex-vertex kernel B (catmark scheme)
|
||||
ID3D11ClassInstance * _kernelComputeCatmarkVertexB;
|
||||
// vertex-vertex kernel B (loop scheme)
|
||||
ID3D11ClassInstance * _kernelComputeLoopVertexB;
|
||||
// hedit kernel (add)
|
||||
ID3D11ClassInstance * _kernelEditAdd;
|
||||
|
||||
int _numVertexElements,
|
||||
_numVaryingElements;
|
||||
|
||||
int _workGroupSize;
|
||||
OsdVertexDescriptor vdesc;
|
||||
};
|
||||
|
||||
friend struct Match;
|
||||
|
||||
protected:
|
||||
struct KernelCB;
|
||||
void dispatchCompute(ID3D11ClassInstance * kernel, KernelCB const & args);
|
||||
|
||||
ID3D11DeviceContext * _deviceContext;
|
||||
|
||||
ID3D11ComputeShader * _computeShader;
|
||||
ID3D11ClassLinkage * _classLinkage;
|
||||
|
||||
|
||||
ID3D11Buffer * _kernelCB; // constant buffer
|
||||
|
||||
|
||||
ID3D11ClassInstance * _kernelComputeFace; // general face-vertex kernel (all schemes)
|
||||
|
||||
ID3D11ClassInstance * _kernelComputeEdge; // edge-vertex kernel (catmark + loop schemes)
|
||||
|
||||
ID3D11ClassInstance * _kernelComputeBilinearEdge; // edge-vertex kernel (bilinear scheme)
|
||||
|
||||
ID3D11ClassInstance * _kernelComputeVertex; // vertex-vertex kernel (bilinear scheme)
|
||||
|
||||
ID3D11ClassInstance * _kernelComputeVertexA; // vertex-vertex kernel A (catmark + loop schemes)
|
||||
|
||||
ID3D11ClassInstance * _kernelComputeCatmarkVertexB; // vertex-vertex kernel B (catmark scheme)
|
||||
|
||||
ID3D11ClassInstance * _kernelComputeLoopVertexB; // vertex-vertex kernel B (loop scheme)
|
||||
|
||||
ID3D11ClassInstance * _kernelEditAdd; // hedit kernel (add)
|
||||
|
||||
int _workGroupSize;
|
||||
|
||||
OsdVertexDescriptor _vdesc;
|
||||
};
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
using namespace OPENSUBDIV_VERSION;
|
||||
|
||||
|
16
opensubdiv/osd/d3d11Mesh.h
Normal file → Executable file
16
opensubdiv/osd/d3d11Mesh.h
Normal file → Executable file
@ -54,7 +54,6 @@
|
||||
// exclude the implied warranties of merchantability, fitness for
|
||||
// a particular purpose and non-infringement.
|
||||
//
|
||||
|
||||
#ifndef OSD_D3D11MESH_H
|
||||
#define OSD_D3D11MESH_H
|
||||
|
||||
@ -94,8 +93,7 @@ public:
|
||||
_pd3d11DeviceContext(d3d11DeviceContext)
|
||||
{
|
||||
FarMeshFactory<OsdVertex> meshFactory(hmesh, level, bits.test(MeshAdaptive));
|
||||
_farMesh = meshFactory.Create(bits.test(MeshPtexData),
|
||||
bits.test(MeshFVarData));
|
||||
_farMesh = meshFactory.Create(bits.test(MeshFVarData));
|
||||
|
||||
ID3D11Device * pd3d11Device;
|
||||
_pd3d11DeviceContext->GetDevice(&pd3d11Device);
|
||||
@ -103,10 +101,11 @@ public:
|
||||
int numVertices = _farMesh->GetNumVertices();
|
||||
_vertexBuffer = VertexBuffer::Create(numElements, numVertices, pd3d11Device);
|
||||
_computeContext = ComputeContext::Create(_farMesh);
|
||||
_drawContext = DrawContext::Create(_farMesh, _vertexBuffer,
|
||||
_drawContext = DrawContext::Create(_farMesh->GetPatchTables(),
|
||||
_pd3d11DeviceContext,
|
||||
bits.test(MeshPtexData),
|
||||
bits.test(MeshFVarData));
|
||||
assert(_drawContext);
|
||||
_drawContext->UpdateVertexTexture(_vertexBuffer, _pd3d11DeviceContext);
|
||||
}
|
||||
|
||||
virtual ~OsdMesh() {
|
||||
@ -168,8 +167,7 @@ public:
|
||||
_pd3d11DeviceContext(d3d11DeviceContext)
|
||||
{
|
||||
FarMeshFactory<OsdVertex> meshFactory(hmesh, level, bits.test(MeshAdaptive));
|
||||
_farMesh = meshFactory.Create(bits.test(MeshPtexData),
|
||||
bits.test(MeshFVarData));
|
||||
_farMesh = meshFactory.Create(bits.test(MeshFVarData));
|
||||
|
||||
ID3D11Device * pd3d11Device;
|
||||
_pd3d11DeviceContext->GetDevice(&pd3d11Device);
|
||||
@ -177,10 +175,10 @@ public:
|
||||
int numVertices = _farMesh->GetNumVertices();
|
||||
_vertexBuffer = VertexBuffer::Create(numElements, numVertices, pd3d11Device);
|
||||
_computeContext = ComputeContext::Create(_farMesh, _pd3d11DeviceContext);
|
||||
_drawContext = DrawContext::Create(_farMesh, _vertexBuffer,
|
||||
_drawContext = DrawContext::Create(_farMesh->GetPatchTables(),
|
||||
_pd3d11DeviceContext,
|
||||
bits.test(MeshPtexData),
|
||||
bits.test(MeshFVarData));
|
||||
_drawContext->UpdateVertexTexture(_vertexBuffer, _pd3d11DeviceContext);
|
||||
}
|
||||
|
||||
virtual ~OsdMesh() {
|
||||
|
@ -67,20 +67,24 @@ struct ID3D11UnorderedAccessView;
|
||||
namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
///
|
||||
/// \brief Concrete vertex buffer class for DirectX subvision and DirectX drawing.
|
||||
///
|
||||
/// OsdD3D11VertexBuffer implements OsdD3D11VertexBufferInterface. An instance
|
||||
/// of this buffer class can be passed to OsdD3D11ComputeController.
|
||||
///
|
||||
class OsdD3D11VertexBuffer {
|
||||
public:
|
||||
/// Creator. Returns NULL if error.
|
||||
static OsdD3D11VertexBuffer * Create(int numElements, int numVertices,
|
||||
static OsdD3D11VertexBuffer * Create(int numElements,
|
||||
int numVertices,
|
||||
ID3D11Device *device);
|
||||
|
||||
/// Destructor.
|
||||
virtual ~OsdD3D11VertexBuffer();
|
||||
|
||||
/// This method is meant to be used in client code in order to provide
|
||||
/// coarse vertices data to Osd.
|
||||
/// This method is meant to be used in client code in order to provide coarse
|
||||
/// vertices data to Osd.
|
||||
void UpdateData(const float *src, int startVertex, int numVertices, void *param);
|
||||
|
||||
/// Returns how many elements defined in this vertex buffer.
|
||||
@ -91,11 +95,15 @@ public:
|
||||
|
||||
/// Returns the D3D11 buffer object.
|
||||
ID3D11Buffer *BindD3D11Buffer(ID3D11DeviceContext *deviceContext);
|
||||
|
||||
/// Returns the D3D11 UAV
|
||||
ID3D11UnorderedAccessView *BindD3D11UAV(ID3D11DeviceContext *deviceContext);
|
||||
|
||||
protected:
|
||||
/// Constructor.
|
||||
OsdD3D11VertexBuffer(int numElements, int numVertices, ID3D11Device *device);
|
||||
OsdD3D11VertexBuffer(int numElements,
|
||||
int numVertices,
|
||||
ID3D11Device *device);
|
||||
|
||||
// Allocates D3D11 buffer
|
||||
bool allocate(ID3D11Device *device);
|
||||
|
@ -54,19 +54,86 @@
|
||||
namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
bool operator< (OsdPatchDescriptor const & a,
|
||||
OsdPatchDescriptor const & b)
|
||||
{
|
||||
return a.type < b.type or ((a.type == b.type) and
|
||||
(a.pattern < b.pattern or ((a.pattern == b.pattern) and
|
||||
(a.rotation < b.rotation or ((a.rotation == b.rotation) and
|
||||
(a.subpatch < b.subpatch or ((a.subpatch == b.subpatch) and
|
||||
(a.maxValence < b.maxValence or ((a.maxValence == b.maxValence) and
|
||||
(a.numElements < b.numElements))))))))));
|
||||
}
|
||||
|
||||
OsdDrawContext::~OsdDrawContext() {}
|
||||
|
||||
void
|
||||
OsdDrawContext::ConvertPatchArrays(FarPatchTables::PatchArrayVector const &farPatchArrays,
|
||||
OsdDrawContext::PatchArrayVector &osdPatchArrays,
|
||||
int maxValence, int numElements)
|
||||
{
|
||||
// create patch arrays for drawing (while duplicating subpatches for transition patch arrays)
|
||||
static int subPatchCounts[] = { 1, 3, 4, 4, 4, 2 }; // number of subpatches for patterns
|
||||
|
||||
int numTotalPatchArrays = 0;
|
||||
for (int i = 0; i < (int)farPatchArrays.size(); ++i) {
|
||||
FarPatchTables::TransitionPattern pattern = farPatchArrays[i].GetDescriptor().GetPattern();
|
||||
numTotalPatchArrays += subPatchCounts[(int)pattern];
|
||||
}
|
||||
|
||||
// allocate drawing patch arrays
|
||||
osdPatchArrays.clear();
|
||||
osdPatchArrays.reserve(numTotalPatchArrays);
|
||||
|
||||
for (int i = 0; i < (int)farPatchArrays.size(); ++i) {
|
||||
FarPatchTables::TransitionPattern pattern = farPatchArrays[i].GetDescriptor().GetPattern();
|
||||
int numSubPatches = subPatchCounts[(int)pattern];
|
||||
|
||||
FarPatchTables::PatchArray const &parray = farPatchArrays[i];
|
||||
FarPatchTables::Descriptor srcDesc = parray.GetDescriptor();
|
||||
|
||||
for (int j = 0; j < numSubPatches; ++j) {
|
||||
PatchDescriptor desc(srcDesc, maxValence, j, numElements);
|
||||
|
||||
osdPatchArrays.push_back(PatchArray(desc, parray.GetArrayRange()));
|
||||
}
|
||||
}
|
||||
/*
|
||||
#if defined(GL_ES_VERSION_2_0)
|
||||
// XXX: farmesh should have FarDensePatchTable for dense mesh indices.
|
||||
// instead of GetFaceVertices().
|
||||
const FarSubdivisionTables<OsdVertex> *tables = farMesh->GetSubdivisionTables();
|
||||
int level = tables->GetMaxLevel();
|
||||
const std::vector<int> &indices = farMesh->GetFaceVertices(level-1);
|
||||
|
||||
int numIndices = (int)indices.size();
|
||||
|
||||
// Allocate and fill index buffer.
|
||||
glGenBuffers(1, &patchIndexBuffer);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, patchIndexBuffer);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
|
||||
numIndices * sizeof(unsigned int), &(indices[0]), GL_STATIC_DRAW);
|
||||
|
||||
|
||||
// OpenGLES 2 supports only triangle topologies for filled
|
||||
// primitives i.e. not QUADS or PATCHES or LINES_ADJACENCY
|
||||
// For the convenience of clients build build a triangles
|
||||
// index buffer by splitting quads.
|
||||
int numQuads = indices.size() / 4;
|
||||
int numTrisIndices = numQuads * 6;
|
||||
|
||||
std::vector<short> trisIndices;
|
||||
trisIndices.reserve(numTrisIndices);
|
||||
for (int i=0; i<numQuads; ++i) {
|
||||
const int * quad = &indices[i*4];
|
||||
trisIndices.push_back(short(quad[0]));
|
||||
trisIndices.push_back(short(quad[1]));
|
||||
trisIndices.push_back(short(quad[2]));
|
||||
|
||||
trisIndices.push_back(short(quad[2]));
|
||||
trisIndices.push_back(short(quad[3]));
|
||||
trisIndices.push_back(short(quad[0]));
|
||||
}
|
||||
|
||||
// Allocate and fill triangles index buffer.
|
||||
glGenBuffers(1, &patchTrianglesIndexBuffer);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, patchTrianglesIndexBuffer);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
|
||||
numTrisIndices * sizeof(short), &(trisIndices[0]), GL_STATIC_DRAW);
|
||||
#endif
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
} // end namespace OpenSubdiv
|
||||
|
||||
|
@ -54,12 +54,11 @@
|
||||
// exclude the implied warranties of merchantability, fitness for
|
||||
// a particular purpose and non-infringement.
|
||||
//
|
||||
|
||||
#ifndef OSD_DRAW_CONTEXT_H
|
||||
#define OSD_DRAW_CONTEXT_H
|
||||
|
||||
#include "../version.h"
|
||||
#include "../osd/patch.h"
|
||||
#include "../far/patchTables.h"
|
||||
|
||||
#include <utility>
|
||||
#include <string>
|
||||
@ -67,18 +66,212 @@
|
||||
namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
/// \brief Base DrawContext class
|
||||
///
|
||||
/// OsdDrawContext derives several sub-classes with API specific functionality
|
||||
/// (GL, D3D11, ...).
|
||||
///
|
||||
/// Current specificiation GPU hardware tessellation limitations require transition
|
||||
/// patches to be split-up into several triangular bi-cubic sub-patches.
|
||||
/// OsdDrawContext processes FarPatchArrays from FarPatchTables and generates the
|
||||
/// additional sets of sub-patches.
|
||||
///
|
||||
/// Contexts interface the serialized topological data pertaining to the
|
||||
/// geometric primitives with the capabilities of the selected discrete
|
||||
/// compute device.
|
||||
///
|
||||
class OsdDrawContext {
|
||||
|
||||
public:
|
||||
OsdDrawContext() : isAdaptive(false) {}
|
||||
|
||||
class PatchDescriptor {
|
||||
public:
|
||||
/// Constructor
|
||||
///
|
||||
/// @param farDesc Patch type descriptor
|
||||
///
|
||||
/// @param maxValence Highest vertex valence in the primitive
|
||||
///
|
||||
/// @param subPatch Index of the triangulated sub-patch for the given
|
||||
/// transition pattern. Transition patches need to be
|
||||
/// split into multiple sub-patches in order to be
|
||||
/// rendered with hardware tessellation.
|
||||
///
|
||||
/// @param numElements The size of the vertex and varying data per-vertex
|
||||
/// (in floats)
|
||||
///
|
||||
PatchDescriptor(FarPatchTables::Descriptor farDesc, unsigned char maxValence,
|
||||
unsigned char subPatch, unsigned char numElements) :
|
||||
_farDesc(farDesc), _maxValence(maxValence), _subPatch(subPatch), _numElements(numElements) { }
|
||||
|
||||
|
||||
/// Returns the type of the patch
|
||||
FarPatchTables::Type GetType() const {
|
||||
return _farDesc.GetType();
|
||||
}
|
||||
|
||||
/// Returns the transition pattern of the patch if any (5 types)
|
||||
FarPatchTables::TransitionPattern GetPattern() const {
|
||||
return _farDesc.GetPattern();
|
||||
}
|
||||
|
||||
/// Returns the rotation of the patch (4 rotations)
|
||||
unsigned char GetRotation() const {
|
||||
return _farDesc.GetRotation();
|
||||
}
|
||||
|
||||
/// Returns the number of control vertices expected for a patch of the
|
||||
/// type described
|
||||
int GetNumControlVertices() const {
|
||||
return _farDesc.GetNumControlVertices();
|
||||
}
|
||||
|
||||
/// Returns the max valence
|
||||
int GetMaxValence() const {
|
||||
return _maxValence;
|
||||
}
|
||||
|
||||
/// Returns the subpatch id
|
||||
int GetSubPatch() const {
|
||||
return _subPatch;
|
||||
}
|
||||
|
||||
/// Returns the number of vertex elements
|
||||
int GetNumElements() const {
|
||||
return _numElements;
|
||||
}
|
||||
|
||||
/// Set the number of vertex elements
|
||||
void SetNumElements(int numElements) {
|
||||
_numElements = numElements;
|
||||
}
|
||||
|
||||
/// Allows ordering of patches by type
|
||||
bool operator < ( PatchDescriptor const other ) const;
|
||||
|
||||
/// True if the descriptors are identical
|
||||
bool operator == ( PatchDescriptor const other ) const;
|
||||
|
||||
private:
|
||||
FarPatchTables::Descriptor _farDesc;
|
||||
unsigned char _maxValence;
|
||||
unsigned char _subPatch;
|
||||
unsigned char _numElements;
|
||||
};
|
||||
|
||||
class PatchArray {
|
||||
public:
|
||||
/// Constructor
|
||||
///
|
||||
/// @param desc Patch descriptor defines the type, pattern, rotation of
|
||||
/// the patches in the array
|
||||
///
|
||||
/// @param range The range of vertex indices
|
||||
///
|
||||
PatchArray(PatchDescriptor desc, FarPatchTables::PatchArray::ArrayRange const & range) :
|
||||
_desc(desc), _range(range) { }
|
||||
|
||||
/// Returns a patch descriptor defining the type of patches in the array
|
||||
PatchDescriptor GetDescriptor() const {
|
||||
return _desc;
|
||||
}
|
||||
|
||||
/// Update a patch descriptor
|
||||
void SetDescriptor(PatchDescriptor desc) {
|
||||
_desc = desc;
|
||||
}
|
||||
|
||||
/// Returns a array range struct
|
||||
FarPatchTables::PatchArray::ArrayRange const & GetArrayRange() const {
|
||||
return _range;
|
||||
}
|
||||
|
||||
/// Returns the index of the first control vertex of the first patch
|
||||
/// of this array in the global PTable
|
||||
unsigned int GetVertIndex() const {
|
||||
return _range.vertIndex;
|
||||
}
|
||||
|
||||
/// Returns the global index of the first patch in this array (Used to
|
||||
/// access ptex / fvar table data)
|
||||
unsigned int GetPatchIndex() const {
|
||||
return _range.patchIndex;
|
||||
}
|
||||
|
||||
/// Returns the number of patches in the array
|
||||
unsigned int GetNumPatches() const {
|
||||
return _range.npatches;
|
||||
}
|
||||
|
||||
/// Returns the number of patch indices in the array
|
||||
unsigned int GetNumIndices() const {
|
||||
return _range.npatches * _desc.GetNumControlVertices();
|
||||
}
|
||||
|
||||
/// Returns the offset of quad offset table
|
||||
unsigned int GetQuadOffsetIndex() const {
|
||||
return _range.quadOffsetIndex;
|
||||
}
|
||||
|
||||
/// Set num patches (used at batch glomming)
|
||||
void SetNumPatches(int npatches) {
|
||||
_range.npatches = npatches;
|
||||
}
|
||||
|
||||
private:
|
||||
PatchDescriptor _desc;
|
||||
FarPatchTables::PatchArray::ArrayRange _range;
|
||||
};
|
||||
|
||||
typedef std::vector<PatchArray> PatchArrayVector;
|
||||
|
||||
/// Constructor
|
||||
OsdDrawContext() : _isAdaptive(false) {}
|
||||
|
||||
/// Descrtuctor
|
||||
virtual ~OsdDrawContext();
|
||||
|
||||
bool IsAdaptive() const { return isAdaptive; }
|
||||
/// Returns true if the primitive attached to the context uses feature adaptive
|
||||
/// subdivision
|
||||
bool IsAdaptive() const { return _isAdaptive; }
|
||||
|
||||
OsdPatchArrayVector patchArrays;
|
||||
bool isAdaptive;
|
||||
// processes FarPatchArrays and inserts requisite sub-patches for the arrays
|
||||
// containing transition patches
|
||||
static void ConvertPatchArrays(FarPatchTables::PatchArrayVector const &farPatchArrays,
|
||||
OsdDrawContext::PatchArrayVector &osdPatchArrays,
|
||||
int maxValence, int numElements);
|
||||
|
||||
public:
|
||||
// XXXX: move to private member
|
||||
PatchArrayVector patchArrays;
|
||||
|
||||
protected:
|
||||
|
||||
bool _isAdaptive;
|
||||
};
|
||||
|
||||
// Allows ordering of patches by type
|
||||
inline bool
|
||||
OsdDrawContext::PatchDescriptor::operator < ( PatchDescriptor const other ) const
|
||||
{
|
||||
return _farDesc < other._farDesc or (_farDesc == other._farDesc and
|
||||
(_subPatch < other._subPatch or ((_subPatch == other._subPatch) and
|
||||
(_maxValence < other._maxValence or ((_maxValence == other._maxValence) and
|
||||
(_numElements < other._numElements))))));
|
||||
}
|
||||
|
||||
// True if the descriptors are identical
|
||||
inline bool
|
||||
OsdDrawContext::PatchDescriptor::operator == ( PatchDescriptor const other ) const
|
||||
{
|
||||
return _farDesc == other._farDesc and
|
||||
_subPatch == other._subPatch and
|
||||
_maxValence == other._maxValence and
|
||||
_numElements == other._numElements;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
using namespace OPENSUBDIV_VERSION;
|
||||
|
||||
|
@ -48,7 +48,12 @@
|
||||
// with this license.
|
||||
// (E) The software is licensed "as-is." You bear the risk of
|
||||
// using it. The contributors give no express warranties,
|
||||
|
||||
// guarantees or conditions. You may have additional consumer
|
||||
// rights under your local laws which this license cannot change.
|
||||
// To the extent permitted under your local laws, the contributors
|
||||
// exclude the implied warranties of merchantability, fitness for
|
||||
// a particular purpose and non-infringement.
|
||||
//
|
||||
#ifndef OSD_DRAW_REGISTRY_H
|
||||
#define OSD_DRAW_REGISTRY_H
|
||||
|
||||
|
@ -63,9 +63,7 @@ namespace OPENSUBDIV_VERSION {
|
||||
|
||||
OsdEvalLimitContext::OsdEvalLimitContext(FarMesh<OsdVertex> const * farmesh) {
|
||||
|
||||
_adaptive = farmesh->SupportsFeatureAdaptive();
|
||||
|
||||
|
||||
_adaptive = farmesh->GetPatchTables()->IsFeatureAdaptive();
|
||||
}
|
||||
|
||||
OsdEvalLimitContext::~OsdEvalLimitContext() {
|
||||
|
@ -62,7 +62,6 @@
|
||||
#include "../far/mesh.h"
|
||||
|
||||
#include "../osd/nonCopyable.h"
|
||||
#include "../osd/patch.h"
|
||||
#include "../osd/vertex.h"
|
||||
|
||||
namespace OpenSubdiv {
|
||||
|
@ -68,7 +68,7 @@ const int GCD_WORK_STRIDE = 32;
|
||||
|
||||
|
||||
void OsdGcdComputeFace(
|
||||
const OsdVertexDescriptor *vdesc, float * vertex, float * varying,
|
||||
OsdVertexDescriptor const &vdesc, float * vertex, float * varying,
|
||||
const int *F_IT, const int *F_ITa,
|
||||
int vertexOffset, int tableOffset, int start, int end,
|
||||
dispatch_queue_t gcdq) {
|
||||
@ -88,7 +88,7 @@ void OsdGcdComputeFace(
|
||||
}
|
||||
|
||||
void OsdGcdComputeEdge(
|
||||
const OsdVertexDescriptor *vdesc, float *vertex, float *varying,
|
||||
OsdVertexDescriptor const &vdesc, float * vertex, float * varying,
|
||||
const int *E_IT, const float *E_W,
|
||||
int vertexOffset, int tableOffset, int start, int end,
|
||||
dispatch_queue_t gcdq) {
|
||||
@ -108,7 +108,7 @@ void OsdGcdComputeEdge(
|
||||
}
|
||||
|
||||
void OsdGcdComputeVertexA(
|
||||
const OsdVertexDescriptor *vdesc, float *vertex, float *varying,
|
||||
OsdVertexDescriptor const &vdesc, float * vertex, float * varying,
|
||||
const int *V_ITa, const float *V_W,
|
||||
int vertexOffset, int tableOffset, int start, int end, int pass,
|
||||
dispatch_queue_t gcdq) {
|
||||
@ -128,7 +128,7 @@ void OsdGcdComputeVertexA(
|
||||
}
|
||||
|
||||
void OsdGcdComputeVertexB(
|
||||
const OsdVertexDescriptor *vdesc, float *vertex, float *varying,
|
||||
OsdVertexDescriptor const &vdesc, float * vertex, float * varying,
|
||||
const int *V_ITa, const int *V_IT, const float *V_W,
|
||||
int vertexOffset, int tableOffset, int start, int end,
|
||||
dispatch_queue_t gcdq) {
|
||||
@ -148,7 +148,7 @@ void OsdGcdComputeVertexB(
|
||||
}
|
||||
|
||||
void OsdGcdComputeLoopVertexB(
|
||||
const OsdVertexDescriptor *vdesc, float *vertex, float *varying,
|
||||
OsdVertexDescriptor const &vdesc, float * vertex, float * varying,
|
||||
const int *V_ITa, const int *V_IT, const float *V_W,
|
||||
int vertexOffset, int tableOffset, int start, int end,
|
||||
dispatch_queue_t gcdq) {
|
||||
@ -166,19 +166,19 @@ void OsdGcdComputeLoopVertexB(
|
||||
beta = (0.625f - beta) * wp;
|
||||
|
||||
int dstIndex = vertexOffset + i - tableOffset;
|
||||
vdesc->Clear(vertex, varying, dstIndex);
|
||||
vdesc.Clear(vertex, varying, dstIndex);
|
||||
|
||||
vdesc->AddWithWeight(vertex, dstIndex, p, weight * (1.0f - (beta * n)));
|
||||
vdesc.AddWithWeight(vertex, dstIndex, p, weight * (1.0f - (beta * n)));
|
||||
|
||||
for (int j = 0; j < n; ++j)
|
||||
vdesc->AddWithWeight(vertex, dstIndex, V_IT[h+j], weight * beta);
|
||||
vdesc.AddWithWeight(vertex, dstIndex, V_IT[h+j], weight * beta);
|
||||
|
||||
vdesc->AddVaryingWithWeight(varying, dstIndex, p, 1.0f);
|
||||
vdesc.AddVaryingWithWeight(varying, dstIndex, p, 1.0f);
|
||||
});
|
||||
}
|
||||
|
||||
void OsdGcdComputeBilinearEdge(
|
||||
const OsdVertexDescriptor *vdesc, float *vertex, float *varying,
|
||||
OsdVertexDescriptor const &vdesc, float * vertex, float * varying,
|
||||
const int *E_IT,
|
||||
int vertexOffset, int tableOffset, int start, int end,
|
||||
dispatch_queue_t gcdq) {
|
||||
@ -189,18 +189,18 @@ void OsdGcdComputeBilinearEdge(
|
||||
int eidx1 = E_IT[2*i+1];
|
||||
|
||||
int dstIndex = vertexOffset + i - tableOffset;
|
||||
vdesc->Clear(vertex, varying, dstIndex);
|
||||
vdesc.Clear(vertex, varying, dstIndex);
|
||||
|
||||
vdesc->AddWithWeight(vertex, dstIndex, eidx0, 0.5f);
|
||||
vdesc->AddWithWeight(vertex, dstIndex, eidx1, 0.5f);
|
||||
vdesc.AddWithWeight(vertex, dstIndex, eidx0, 0.5f);
|
||||
vdesc.AddWithWeight(vertex, dstIndex, eidx1, 0.5f);
|
||||
|
||||
vdesc->AddVaryingWithWeight(varying, dstIndex, eidx0, 0.5f);
|
||||
vdesc->AddVaryingWithWeight(varying, dstIndex, eidx1, 0.5f);
|
||||
vdesc.AddVaryingWithWeight(varying, dstIndex, eidx0, 0.5f);
|
||||
vdesc.AddVaryingWithWeight(varying, dstIndex, eidx1, 0.5f);
|
||||
});
|
||||
}
|
||||
|
||||
void OsdGcdComputeBilinearVertex(
|
||||
const OsdVertexDescriptor *vdesc, float *vertex, float *varying,
|
||||
OsdVertexDescriptor const &vdesc, float * vertex, float * varying,
|
||||
const int *V_ITa,
|
||||
int vertexOffset, int tableOffset, int start, int end,
|
||||
dispatch_queue_t gcdq) {
|
||||
@ -210,15 +210,15 @@ void OsdGcdComputeBilinearVertex(
|
||||
int p = V_ITa[i];
|
||||
|
||||
int dstIndex = vertexOffset + i - tableOffset;
|
||||
vdesc->Clear(vertex, varying, dstIndex);
|
||||
vdesc.Clear(vertex, varying, dstIndex);
|
||||
|
||||
vdesc->AddWithWeight(vertex, dstIndex, p, 1.0f);
|
||||
vdesc->AddVaryingWithWeight(varying, dstIndex, p, 1.0f);
|
||||
vdesc.AddWithWeight(vertex, dstIndex, p, 1.0f);
|
||||
vdesc.AddVaryingWithWeight(varying, dstIndex, p, 1.0f);
|
||||
});
|
||||
}
|
||||
|
||||
void OsdGcdEditVertexAdd(
|
||||
const OsdVertexDescriptor *vdesc, float *vertex,
|
||||
OsdVertexDescriptor const &vdesc, float * vertex,
|
||||
int primVarOffset, int primVarWidth,
|
||||
int vertexOffset, int tableOffset,
|
||||
int start, int end,
|
||||
@ -228,14 +228,14 @@ void OsdGcdEditVertexAdd(
|
||||
int vertexCount = end - start;
|
||||
dispatch_apply(vertexCount, gcdq, ^(size_t blockIdx){
|
||||
int i = start + blockIdx + tableOffset;
|
||||
vdesc->ApplyVertexEditAdd(vertex, primVarOffset, primVarWidth,
|
||||
vdesc.ApplyVertexEditAdd(vertex, primVarOffset, primVarWidth,
|
||||
editIndices[i] + vertexOffset,
|
||||
&editValues[i*primVarWidth]);
|
||||
});
|
||||
}
|
||||
|
||||
void OsdGcdEditVertexSet(
|
||||
const OsdVertexDescriptor *vdesc, float *vertex,
|
||||
OsdVertexDescriptor const &vdesc, float * vertex,
|
||||
int primVarOffset, int primVarWidth,
|
||||
int vertexOffset, int tableOffset,
|
||||
int start, int end,
|
||||
@ -245,7 +245,7 @@ void OsdGcdEditVertexSet(
|
||||
int vertexCount = end - start;
|
||||
dispatch_apply(vertexCount, gcdq, ^(size_t blockIdx){
|
||||
int i = start + blockIdx + tableOffset;
|
||||
vdesc->ApplyVertexEditSet(vertex, primVarOffset, primVarWidth,
|
||||
vdesc.ApplyVertexEditSet(vertex, primVarOffset, primVarWidth,
|
||||
editIndices[i] + vertexOffset,
|
||||
&editValues[i*primVarWidth]);
|
||||
});
|
||||
|
@ -65,35 +65,35 @@ namespace OPENSUBDIV_VERSION {
|
||||
|
||||
struct OsdVertexDescriptor;
|
||||
|
||||
void OsdGcdComputeFace(const OsdVertexDescriptor *vdesc,
|
||||
void OsdGcdComputeFace(OsdVertexDescriptor const &vdesc,
|
||||
float * vertex, float * varying,
|
||||
const int *F_IT, const int *F_ITa,
|
||||
int vertexOffset, int tableOffset,
|
||||
int start, int end,
|
||||
dispatch_queue_t gcdq);
|
||||
|
||||
void OsdGcdComputeEdge(const OsdVertexDescriptor *vdesc,
|
||||
void OsdGcdComputeEdge(OsdVertexDescriptor const &vdesc,
|
||||
float *vertex, float * varying,
|
||||
const int *E_IT, const float *E_ITa,
|
||||
int vertexOffset, int tableOffset,
|
||||
int start, int end,
|
||||
dispatch_queue_t gcdq);
|
||||
|
||||
void OsdGcdComputeVertexA(const OsdVertexDescriptor *vdesc,
|
||||
void OsdGcdComputeVertexA(OsdVertexDescriptor const &vdesc,
|
||||
float *vertex, float * varying,
|
||||
const int *V_ITa, const float *V_IT,
|
||||
int vertexOffset, int tableOffset,
|
||||
int start, int end, int pass,
|
||||
dispatch_queue_t gcdq);
|
||||
|
||||
void OsdGcdComputeVertexB(const OsdVertexDescriptor *vdesc,
|
||||
void OsdGcdComputeVertexB(OsdVertexDescriptor const &vdesc,
|
||||
float *vertex, float * varying,
|
||||
const int *V_ITa, const int *V_IT, const float *V_W,
|
||||
int vertexOffset, int tableOffset,
|
||||
int start, int end,
|
||||
dispatch_queue_t gcdq);
|
||||
|
||||
void OsdGcdComputeLoopVertexB(const OsdVertexDescriptor *vdesc,
|
||||
void OsdGcdComputeLoopVertexB(OsdVertexDescriptor const &vdesc,
|
||||
float *vertex, float * varying,
|
||||
const int *V_ITa, const int *V_IT,
|
||||
const float *V_W,
|
||||
@ -101,28 +101,28 @@ void OsdGcdComputeLoopVertexB(const OsdVertexDescriptor *vdesc,
|
||||
int start, int end,
|
||||
dispatch_queue_t gcdq);
|
||||
|
||||
void OsdGcdComputeBilinearEdge(const OsdVertexDescriptor *vdesc,
|
||||
void OsdGcdComputeBilinearEdge(OsdVertexDescriptor const &vdesc,
|
||||
float *vertex, float * varying,
|
||||
const int *E_IT,
|
||||
int vertexOffset, int tableOffset,
|
||||
int start, int end,
|
||||
dispatch_queue_t gcdq);
|
||||
|
||||
void OsdGcdComputeBilinearVertex(const OsdVertexDescriptor *vdesc,
|
||||
void OsdGcdComputeBilinearVertex(OsdVertexDescriptor const &vdesc,
|
||||
float *vertex, float * varying,
|
||||
const int *V_ITa,
|
||||
int vertexOffset, int tableOffset,
|
||||
int start, int end,
|
||||
dispatch_queue_t gcdq);
|
||||
|
||||
void OsdGcdEditVertexAdd(const OsdVertexDescriptor *vdesc, float *vertex,
|
||||
void OsdGcdEditVertexAdd(OsdVertexDescriptor const &vdesc, float *vertex,
|
||||
int primVarOffset, int primVarWidth,
|
||||
int vertexOffset, int tableOffset,
|
||||
int start, int end,
|
||||
const unsigned int *editIndices, const float *editValues,
|
||||
dispatch_queue_t gcdq);
|
||||
|
||||
void OsdGcdEditVertexSet(const OsdVertexDescriptor *vdesc, float *vertex,
|
||||
void OsdGcdEditVertexSet(OsdVertexDescriptor const &vdesc, float *vertex,
|
||||
int primVarOffset, int primVarWidth,
|
||||
int vertexOffset, int tableOffset,
|
||||
int start, int end,
|
||||
|
@ -75,8 +75,7 @@ namespace OPENSUBDIV_VERSION {
|
||||
|
||||
OsdGLDrawContext::OsdGLDrawContext() :
|
||||
patchIndexBuffer(0), ptexCoordinateTextureBuffer(0), fvarDataTextureBuffer(0),
|
||||
vertexTextureBuffer(0), vertexValenceTextureBuffer(0), quadOffsetTextureBuffer(0),
|
||||
patchLevelTextureBuffer(0)
|
||||
vertexTextureBuffer(0), vertexValenceTextureBuffer(0), quadOffsetTextureBuffer(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -86,7 +85,6 @@ OsdGLDrawContext::~OsdGLDrawContext()
|
||||
glDeleteTextures(1, &vertexTextureBuffer);
|
||||
glDeleteTextures(1, &vertexValenceTextureBuffer);
|
||||
glDeleteTextures(1, &quadOffsetTextureBuffer);
|
||||
glDeleteTextures(1, &patchLevelTextureBuffer);
|
||||
glDeleteTextures(1, &ptexCoordinateTextureBuffer);
|
||||
glDeleteTextures(1, &fvarDataTextureBuffer);
|
||||
}
|
||||
@ -104,19 +102,64 @@ OsdGLDrawContext::SupportsAdaptiveTessellation()
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
OsdGLDrawContext::allocate(FarMesh<OsdVertex> *farMesh,
|
||||
GLuint vbo,
|
||||
int numElements,
|
||||
bool requirePtexCoordinates,
|
||||
bool requireFVarData)
|
||||
template <typename T> static GLuint
|
||||
createTextureBuffer(T const &data, GLint format, int offset=0)
|
||||
{
|
||||
FarPatchTables const * patchTables = farMesh->GetPatchTables();
|
||||
GLuint buffer = 0, texture = 0;
|
||||
|
||||
if (not patchTables) {
|
||||
// uniform patches
|
||||
isAdaptive = false;
|
||||
#if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1)
|
||||
glGenTextures(1, &texture);
|
||||
glGenBuffers(1, &buffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, (data.size()-offset) * sizeof(typename T::value_type),
|
||||
&data[offset], GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
glBindTexture(GL_TEXTURE_BUFFER, texture);
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, format, buffer);
|
||||
glDeleteBuffers(1, &buffer);
|
||||
#endif
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
OsdGLDrawContext *
|
||||
OsdGLDrawContext::Create(FarPatchTables const * patchTables, bool requireFVarData) {
|
||||
|
||||
if (patchTables) {
|
||||
|
||||
OsdGLDrawContext * result = new OsdGLDrawContext();
|
||||
|
||||
if (result->create(patchTables, requireFVarData)) {
|
||||
return result;
|
||||
} else {
|
||||
delete result;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
OsdGLDrawContext::create(FarPatchTables const * patchTables, bool requireFVarData) {
|
||||
|
||||
assert(patchTables);
|
||||
|
||||
_isAdaptive = patchTables->IsFeatureAdaptive();
|
||||
|
||||
// Process PTable
|
||||
FarPatchTables::PTable const & ptables = patchTables->GetPatchTable();
|
||||
|
||||
glGenBuffers(1, &patchIndexBuffer);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, patchIndexBuffer);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
|
||||
ptables.size() * sizeof(unsigned int), &ptables[0], GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
OsdDrawContext::ConvertPatchArrays(patchTables->GetPatchArrayVector(),
|
||||
patchArrays, patchTables->GetMaxValence(), 0);
|
||||
|
||||
/*
|
||||
#if defined(GL_ES_VERSION_2_0)
|
||||
// XXX: farmesh should have FarDensePatchTable for dense mesh indices.
|
||||
// instead of GetFaceVertices().
|
||||
const FarSubdivisionTables<OsdVertex> *tables = farMesh->GetSubdivisionTables();
|
||||
@ -131,7 +174,7 @@ OsdGLDrawContext::allocate(FarMesh<OsdVertex> *farMesh,
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
|
||||
numIndices * sizeof(unsigned int), &(indices[0]), GL_STATIC_DRAW);
|
||||
|
||||
#if defined(GL_ES_VERSION_2_0)
|
||||
|
||||
// OpenGLES 2 supports only triangle topologies for filled
|
||||
// primitives i.e. not QUADS or PATCHES or LINES_ADJACENCY
|
||||
// For the convenience of clients build build a triangles
|
||||
@ -158,317 +201,67 @@ OsdGLDrawContext::allocate(FarMesh<OsdVertex> *farMesh,
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
|
||||
numTrisIndices * sizeof(short), &(trisIndices[0]), GL_STATIC_DRAW);
|
||||
#endif
|
||||
|
||||
OsdPatchArray array;
|
||||
array.desc.type = kNonPatch;
|
||||
array.desc.loop = dynamic_cast<const FarLoopSubdivisionTables<OsdVertex>*>(tables) != NULL;
|
||||
array.firstIndex = 0;
|
||||
array.numIndices = numIndices;
|
||||
|
||||
patchArrays.push_back(array);
|
||||
|
||||
// Allocate ptex coordinate buffer if requested (for non-adaptive)
|
||||
if (requirePtexCoordinates) {
|
||||
#if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1)
|
||||
GLuint ptexCoordinateBuffer = 0;
|
||||
glGenTextures(1, &ptexCoordinateTextureBuffer);
|
||||
glGenBuffers(1, &ptexCoordinateBuffer);
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, ptexCoordinateBuffer);
|
||||
|
||||
const std::vector<FarPtexCoord> &ptexCoordinates =
|
||||
farMesh->GetPtexCoordinates(level-1);
|
||||
int size = (int)ptexCoordinates.size() * sizeof(FarPtexCoord);
|
||||
|
||||
glBufferData(GL_TEXTURE_BUFFER, size, &(ptexCoordinates[0]), GL_STATIC_DRAW);
|
||||
|
||||
glBindTexture(GL_TEXTURE_BUFFER, ptexCoordinateTextureBuffer);
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32I, ptexCoordinateBuffer);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, 0);
|
||||
glDeleteBuffers(1, &ptexCoordinateBuffer);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
// Allocate fvar data buffer if requested (for non-adaptive)
|
||||
if (requireFVarData) {
|
||||
#if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1)
|
||||
GLuint fvarDataBuffer = 0;
|
||||
glGenTextures(1, &fvarDataTextureBuffer);
|
||||
glGenBuffers(1, &fvarDataBuffer);
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, fvarDataBuffer);
|
||||
|
||||
const std::vector<float> &fvarData = farMesh->GetFVarData(level-1);
|
||||
int size = (int)fvarData.size() * sizeof(float);
|
||||
|
||||
glBufferData(GL_TEXTURE_BUFFER, size, &(fvarData[0]), GL_STATIC_DRAW);
|
||||
|
||||
glBindTexture(GL_TEXTURE_BUFFER, fvarDataTextureBuffer);
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, fvarDataBuffer);
|
||||
glDeleteBuffers(1, &fvarDataBuffer);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// adaptive patches
|
||||
isAdaptive = true;
|
||||
|
||||
size_t totalPatchIndices = patchTables->GetNumControlVertices();
|
||||
*/
|
||||
|
||||
size_t totalPatchLevels = patchTables->GetNumPatches();
|
||||
|
||||
// Allocate and fill index buffer.
|
||||
glGenBuffers(1, &patchIndexBuffer);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, patchIndexBuffer);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
|
||||
totalPatchIndices * sizeof(unsigned int), NULL, GL_STATIC_DRAW);
|
||||
|
||||
#if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1)
|
||||
GLuint patchLevelBuffer = 0;
|
||||
glGenBuffers(1, &patchLevelBuffer);
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, patchLevelBuffer);
|
||||
glBufferData(GL_TEXTURE_BUFFER,
|
||||
totalPatchLevels * sizeof(unsigned char), NULL, GL_STATIC_DRAW);
|
||||
#endif
|
||||
|
||||
// Allocate ptex coordinate buffer if requested
|
||||
GLuint ptexCoordinateBuffer = 0;
|
||||
if (requirePtexCoordinates) {
|
||||
#if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1)
|
||||
glGenTextures(1, &ptexCoordinateTextureBuffer);
|
||||
glGenBuffers(1, &ptexCoordinateBuffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, ptexCoordinateBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
totalPatchLevels * sizeof(FarPtexCoord), NULL, GL_STATIC_DRAW);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Allocate fvar data buffer if requested
|
||||
GLuint fvarDataBuffer = 0;
|
||||
if (requireFVarData) {
|
||||
#if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1)
|
||||
glGenTextures(1, &fvarDataTextureBuffer);
|
||||
glGenBuffers(1, &fvarDataBuffer);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, fvarDataBuffer);
|
||||
glBufferData(GL_UNIFORM_BUFFER,
|
||||
totalPatchLevels * sizeof(float) * farMesh->GetTotalFVarWidth()*4, NULL, GL_STATIC_DRAW);
|
||||
#endif
|
||||
}
|
||||
|
||||
int indexBase = 0;
|
||||
int levelBase = 0;
|
||||
int maxValence = patchTables->GetMaxValence();
|
||||
|
||||
_AppendPatchArray(&indexBase, &levelBase,
|
||||
patchTables->GetFullRegularPatches(),
|
||||
patchTables->GetFullRegularPtexCoordinates(),
|
||||
patchTables->GetFullRegularFVarData(),
|
||||
farMesh->GetTotalFVarWidth(),
|
||||
OsdPatchDescriptor(kRegular, 0, 0, 0, 0), 0);
|
||||
_AppendPatchArray(&indexBase, &levelBase,
|
||||
patchTables->GetFullBoundaryPatches(),
|
||||
patchTables->GetFullBoundaryPtexCoordinates(),
|
||||
patchTables->GetFullBoundaryFVarData(),
|
||||
farMesh->GetTotalFVarWidth(),
|
||||
OsdPatchDescriptor(kBoundary, 0, 0, 0, 0), 0);
|
||||
_AppendPatchArray(&indexBase, &levelBase,
|
||||
patchTables->GetFullCornerPatches(),
|
||||
patchTables->GetFullCornerPtexCoordinates(),
|
||||
patchTables->GetFullCornerFVarData(),
|
||||
farMesh->GetTotalFVarWidth(),
|
||||
OsdPatchDescriptor(kCorner, 0, 0, 0, 0), 0);
|
||||
_AppendPatchArray(&indexBase, &levelBase,
|
||||
patchTables->GetFullGregoryPatches(),
|
||||
patchTables->GetFullGregoryPtexCoordinates(),
|
||||
patchTables->GetFullGregoryFVarData(),
|
||||
farMesh->GetTotalFVarWidth(),
|
||||
OsdPatchDescriptor(kGregory, 0, 0,
|
||||
static_cast<unsigned char>(maxValence), static_cast<unsigned char>(numElements)),
|
||||
0);
|
||||
_AppendPatchArray(&indexBase, &levelBase,
|
||||
patchTables->GetFullBoundaryGregoryPatches(),
|
||||
patchTables->GetFullBoundaryGregoryPtexCoordinates(),
|
||||
patchTables->GetFullBoundaryGregoryFVarData(),
|
||||
farMesh->GetTotalFVarWidth(),
|
||||
OsdPatchDescriptor(kBoundaryGregory, 0, 0,
|
||||
static_cast<unsigned char>(maxValence), static_cast<unsigned char>(numElements)),
|
||||
(int)patchTables->GetFullGregoryPatches().first.size());
|
||||
|
||||
for (unsigned char p=0; p<5; ++p) {
|
||||
_AppendPatchArray(&indexBase, &levelBase,
|
||||
patchTables->GetTransitionRegularPatches(p),
|
||||
patchTables->GetTransitionRegularPtexCoordinates(p),
|
||||
patchTables->GetTransitionRegularFVarData(p),
|
||||
farMesh->GetTotalFVarWidth(),
|
||||
OsdPatchDescriptor(kTransitionRegular, p, 0, 0, 0), 0);
|
||||
for (unsigned char r=0; r<4; ++r) {
|
||||
_AppendPatchArray(&indexBase, &levelBase,
|
||||
patchTables->GetTransitionBoundaryPatches(p, r),
|
||||
patchTables->GetTransitionBoundaryPtexCoordinates(p, r),
|
||||
patchTables->GetTransitionBoundaryFVarData(p, r),
|
||||
farMesh->GetTotalFVarWidth(),
|
||||
OsdPatchDescriptor(kTransitionBoundary, p, r, 0, 0), 0);
|
||||
_AppendPatchArray(&indexBase, &levelBase,
|
||||
patchTables->GetTransitionCornerPatches(p, r),
|
||||
patchTables->GetTransitionCornerPtexCoordinates(p, r),
|
||||
patchTables->GetTransitionCornerFVarData(p, r),
|
||||
farMesh->GetTotalFVarWidth(),
|
||||
OsdPatchDescriptor(kTransitionCorner, p, r, 0, 0), 0);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1)
|
||||
// finalize level texture buffer
|
||||
glGenTextures(1, &patchLevelTextureBuffer);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, patchLevelTextureBuffer);
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_R8I, patchLevelBuffer);
|
||||
glDeleteBuffers(1, &patchLevelBuffer);
|
||||
|
||||
// finalize ptex coordinate texture buffer
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
if (requirePtexCoordinates) {
|
||||
glBindTexture(GL_TEXTURE_BUFFER, ptexCoordinateTextureBuffer);
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32I, ptexCoordinateBuffer);
|
||||
glDeleteBuffers(1, &ptexCoordinateBuffer);
|
||||
}
|
||||
// finalize fvar data texture buffer
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
if (requireFVarData) {
|
||||
glBindTexture(GL_TEXTURE_BUFFER, fvarDataTextureBuffer);
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, fvarDataBuffer);
|
||||
glDeleteBuffers(1, &fvarDataBuffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
#if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1)
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, 0);
|
||||
#endif
|
||||
|
||||
// allocate and initialize additional buffer data
|
||||
|
||||
// create vertex valence buffer and vertex texture
|
||||
FarPatchTables::VertexValenceTable const &
|
||||
valenceTable = patchTables->GetVertexValenceTable();
|
||||
|
||||
if (not valenceTable.empty()) {
|
||||
#if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1)
|
||||
GLuint buffer = 0;
|
||||
glGenBuffers(1, &buffer);
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, buffer);
|
||||
glBufferData(GL_TEXTURE_BUFFER,
|
||||
valenceTable.size() * sizeof(unsigned int),
|
||||
&valenceTable[0], GL_STATIC_DRAW);
|
||||
|
||||
glGenTextures(1, &vertexValenceTextureBuffer);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, vertexValenceTextureBuffer);
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32I, buffer);
|
||||
glDeleteBuffers(1, &buffer);
|
||||
vertexValenceTextureBuffer = createTextureBuffer(valenceTable, GL_R32I);
|
||||
|
||||
// also create vertex texture buffer (will be updated in UpdateVertexTexture())
|
||||
glGenTextures(1, &vertexTextureBuffer);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, vertexTextureBuffer);
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, vbo);
|
||||
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// create quad offset table buffer
|
||||
FarPatchTables::QuadOffsetTable const &
|
||||
quadOffsetTable = patchTables->GetQuadOffsetTable();
|
||||
|
||||
if (not quadOffsetTable.empty()) {
|
||||
#if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1)
|
||||
GLuint buffer = 0;
|
||||
glGenBuffers(1, &buffer);
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, buffer);
|
||||
glBufferData(GL_TEXTURE_BUFFER,
|
||||
quadOffsetTable.size() * sizeof(unsigned int),
|
||||
&quadOffsetTable[0], GL_STATIC_DRAW);
|
||||
if (not quadOffsetTable.empty())
|
||||
quadOffsetTextureBuffer = createTextureBuffer(quadOffsetTable, GL_R32I);
|
||||
|
||||
glGenTextures(1, &quadOffsetTextureBuffer);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, quadOffsetTextureBuffer);
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32I, buffer);
|
||||
glDeleteBuffers(1, &buffer);
|
||||
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, 0);
|
||||
#endif
|
||||
}
|
||||
// create ptex coordinate buffer
|
||||
FarPatchTables::PatchParamTable const &
|
||||
ptexCoordTables = patchTables->GetPatchParamTable();
|
||||
|
||||
if (not ptexCoordTables.empty())
|
||||
ptexCoordinateTextureBuffer = createTextureBuffer(ptexCoordTables, GL_RG32I);
|
||||
|
||||
|
||||
// create fvar data buffer if requested
|
||||
FarPatchTables::FVarDataTable const &
|
||||
fvarTables = patchTables->GetFVarDataTable();
|
||||
|
||||
if (requireFVarData and not fvarTables.empty())
|
||||
fvarDataTextureBuffer = createTextureBuffer(fvarTables, GL_R32F);
|
||||
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
OsdGLDrawContext::_AppendPatchArray(
|
||||
int *indexBase, int *levelBase,
|
||||
FarPatchTables::PTable const & ptable,
|
||||
FarPatchTables::PtexCoordinateTable const & ptexTable,
|
||||
FarPatchTables::FVarDataTable const & fvarTable, int fvarDataWidth,
|
||||
OsdPatchDescriptor const & desc, int gregoryQuadOffsetBase)
|
||||
OsdGLDrawContext::updateVertexTexture(GLuint vbo, int numVertexElements)
|
||||
{
|
||||
if (ptable.first.empty()) {
|
||||
return;
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_BUFFER, vertexTextureBuffer);
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, vbo);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, 0);
|
||||
|
||||
OsdPatchArray array;
|
||||
array.desc = desc;
|
||||
array.firstIndex = *indexBase;
|
||||
array.numIndices = (int)ptable.first.size();
|
||||
array.levelBase = *levelBase;
|
||||
array.gregoryQuadOffsetBase = gregoryQuadOffsetBase;
|
||||
|
||||
int numSubPatches = 1;
|
||||
if (desc.type == OpenSubdiv::kTransitionRegular or
|
||||
desc.type == OpenSubdiv::kTransitionBoundary or
|
||||
desc.type == OpenSubdiv::kTransitionCorner) {
|
||||
static int subPatchCounts[] = { 3, 4, 4, 4, 2 };
|
||||
numSubPatches = subPatchCounts[desc.pattern];
|
||||
}
|
||||
|
||||
for (int subpatch = 0; subpatch < numSubPatches; ++subpatch) {
|
||||
array.desc.subpatch = subpatch;
|
||||
patchArrays.push_back(array);
|
||||
}
|
||||
|
||||
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER,
|
||||
array.firstIndex * sizeof(unsigned int),
|
||||
array.numIndices * sizeof(unsigned int),
|
||||
&ptable.first[0]);
|
||||
*indexBase += array.numIndices;
|
||||
|
||||
#if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1)
|
||||
int numElements = array.numIndices/array.desc.GetPatchSize();
|
||||
assert(numElements == (int)ptable.second.size());
|
||||
glBufferSubData(GL_TEXTURE_BUFFER,
|
||||
array.levelBase * sizeof(unsigned char),
|
||||
numElements * sizeof(unsigned char),
|
||||
&ptable.second[0]);
|
||||
*levelBase += numElements;
|
||||
#endif
|
||||
|
||||
if (ptexCoordinateTextureBuffer) {
|
||||
#if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1)
|
||||
assert((int)ptexTable.size() == numElements);
|
||||
|
||||
// populate ptex coordinates
|
||||
glBufferSubData(GL_ARRAY_BUFFER,
|
||||
array.levelBase * sizeof(FarPtexCoord),
|
||||
(int)ptexTable.size() * sizeof(FarPtexCoord),
|
||||
&ptexTable[0]);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (fvarDataTextureBuffer) {
|
||||
#if defined(GL_ARB_texture_buffer_object) || defined(GL_VERSION_3_1)
|
||||
assert((int)fvarTable.size()/(fvarDataWidth*4) == numElements);
|
||||
|
||||
// populate fvar data
|
||||
glBufferSubData(GL_UNIFORM_BUFFER,
|
||||
array.levelBase * sizeof(float) * fvarDataWidth*4,
|
||||
(int)fvarTable.size() * sizeof(float),
|
||||
&fvarTable[0]);
|
||||
#endif
|
||||
// XXX: consider moving this proc to base class
|
||||
// updating num elements in descriptor with new vbo specs
|
||||
for (int i = 0; i < (int)patchArrays.size(); ++i) {
|
||||
PatchArray &parray = patchArrays[i];
|
||||
PatchDescriptor desc = parray.GetDescriptor();
|
||||
desc.SetNumElements(numVertexElements);
|
||||
parray.SetDescriptor(desc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
} // end namespace OpenSubdiv
|
||||
|
@ -48,6 +48,12 @@
|
||||
// with this license.
|
||||
// (E) The software is licensed "as-is." You bear the risk of
|
||||
// using it. The contributors give no express warranties,
|
||||
// guarantees or conditions. You may have additional consumer
|
||||
// rights under your local laws which this license cannot change.
|
||||
// To the extent permitted under your local laws, the contributors
|
||||
// exclude the implied warranties of merchantability, fitness for
|
||||
// a particular purpose and non-infringement.
|
||||
//
|
||||
#ifndef OSD_GL_DRAW_CONTEXT_H
|
||||
#define OSD_GL_DRAW_CONTEXT_H
|
||||
|
||||
@ -79,33 +85,43 @@
|
||||
namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
/// \brief OpenGL specialized DrawContext class
|
||||
///
|
||||
/// OsdGLDrawContext implements the OSD drawing interface with the OpenGL API.
|
||||
/// Some functionality may be disabled depending on compile and run-time driver
|
||||
/// support.
|
||||
///
|
||||
/// Contexts interface the serialized topological data pertaining to the
|
||||
/// geometric primitives with the capabilities of the selected discrete
|
||||
/// compute device.
|
||||
///
|
||||
class OsdGLDrawContext : public OsdDrawContext {
|
||||
public:
|
||||
typedef GLuint VertexBufferBinding;
|
||||
|
||||
OsdGLDrawContext();
|
||||
virtual ~OsdGLDrawContext();
|
||||
|
||||
/// \brief Create an OsdGLDraContext from FarPatchTables
|
||||
///
|
||||
/// @param patchTables a valid set of FarPatchTables
|
||||
///
|
||||
/// @param requireFVarData set to true to enable face-varying data to be
|
||||
/// carried over from the Far data structures.
|
||||
///
|
||||
static OsdGLDrawContext * Create(FarPatchTables const * patchTables, bool requireFVarData);
|
||||
|
||||
/// Set vbo as a vertex texture (for gregory patch drawing)
|
||||
///
|
||||
/// @param vbo the vertex buffer object to update
|
||||
///
|
||||
template<class VERTEX_BUFFER>
|
||||
static OsdGLDrawContext *
|
||||
Create(FarMesh<OsdVertex> *farMesh,
|
||||
VERTEX_BUFFER *vertexBuffer,
|
||||
bool requirePtexCoordinates=false,
|
||||
bool requireFVarData=false) {
|
||||
|
||||
if (not vertexBuffer)
|
||||
return NULL;
|
||||
|
||||
OsdGLDrawContext * instance = new OsdGLDrawContext();
|
||||
if (instance->allocate(farMesh,
|
||||
vertexBuffer->BindVBO(),
|
||||
vertexBuffer->GetNumElements(),
|
||||
requirePtexCoordinates,
|
||||
requireFVarData)) return instance;
|
||||
delete instance;
|
||||
return NULL;
|
||||
void UpdateVertexTexture(VERTEX_BUFFER *vbo) {
|
||||
updateVertexTexture(vbo->BindVBO(), vbo->GetNumElements());
|
||||
}
|
||||
|
||||
/// true if the GL version detected supports shader tessellation
|
||||
static bool SupportsAdaptiveTessellation();
|
||||
|
||||
GLuint patchIndexBuffer;
|
||||
|
||||
#if defined(GL_ES_VERSION_2_0)
|
||||
@ -118,24 +134,14 @@ public:
|
||||
GLuint vertexTextureBuffer;
|
||||
GLuint vertexValenceTextureBuffer;
|
||||
GLuint quadOffsetTextureBuffer;
|
||||
GLuint patchLevelTextureBuffer;
|
||||
|
||||
/// true if the GL version detected supports shader tessellation
|
||||
static bool SupportsAdaptiveTessellation();
|
||||
protected:
|
||||
OsdGLDrawContext();
|
||||
|
||||
private:
|
||||
bool allocate(FarMesh<OsdVertex> *farMesh,
|
||||
GLuint vbo, int numElements,
|
||||
bool requirePtexCoordinates,
|
||||
bool requireFVarData);
|
||||
// allocate buffers from patchTables
|
||||
bool create(FarPatchTables const *patchTables, bool requireFVarData);
|
||||
|
||||
void _AppendPatchArray(
|
||||
int *indexBase, int *levelBase,
|
||||
FarPatchTables::PTable const & ptable,
|
||||
FarPatchTables::PtexCoordinateTable const & ptexTable,
|
||||
FarPatchTables::FVarDataTable const & fvarTable, int fvarDataWidth,
|
||||
OsdPatchDescriptor const & desc,
|
||||
int gregoryQuadOffsetBase);
|
||||
void updateVertexTexture(GLuint vbo, int numElements);
|
||||
};
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
|
@ -105,7 +105,7 @@ static const char *transitionShaderSource =
|
||||
OsdGLDrawRegistryBase::~OsdGLDrawRegistryBase() {}
|
||||
|
||||
OsdGLDrawSourceConfig *
|
||||
OsdGLDrawRegistryBase::_CreateDrawSourceConfig(OsdPatchDescriptor const & desc)
|
||||
OsdGLDrawRegistryBase::_CreateDrawSourceConfig(OsdDrawContext::PatchDescriptor const & desc)
|
||||
{
|
||||
OsdGLDrawSourceConfig * sconfig = _NewDrawSourceConfig();
|
||||
|
||||
@ -113,95 +113,101 @@ OsdGLDrawRegistryBase::_CreateDrawSourceConfig(OsdPatchDescriptor const & desc)
|
||||
sconfig->commonShader.source = commonShaderSource;
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << (int)desc.maxValence;
|
||||
ss << (int)desc.GetMaxValence();
|
||||
sconfig->commonShader.AddDefine("OSD_MAX_VALENCE", ss.str());
|
||||
ss.str("");
|
||||
ss << (int)desc.numElements;
|
||||
ss << (int)desc.GetNumElements();
|
||||
sconfig->commonShader.AddDefine("OSD_NUM_ELEMENTS", ss.str());
|
||||
}
|
||||
|
||||
switch (desc.type) {
|
||||
case kNonPatch:
|
||||
sconfig->vertexShader.source = regularShaderSource;
|
||||
sconfig->vertexShader.version = "#version 410\n";
|
||||
sconfig->vertexShader.AddDefine("VERTEX_SHADER");
|
||||
sconfig->fragmentShader.source = regularShaderSource;
|
||||
sconfig->fragmentShader.AddDefine("FRAGMENT_SHADER");
|
||||
sconfig->fragmentShader.version = "#version 410\n";
|
||||
break;
|
||||
case kRegular:
|
||||
sconfig->vertexShader.source = regularShaderSource;
|
||||
sconfig->vertexShader.version = "#version 410\n";
|
||||
sconfig->vertexShader.AddDefine("PATCH_VERTEX_SHADER");
|
||||
sconfig->tessControlShader.source = regularShaderSource;
|
||||
sconfig->tessControlShader.version = "#version 410\n";
|
||||
sconfig->tessControlShader.AddDefine("PATCH_TESS_CONTROL_REGULAR_SHADER");
|
||||
sconfig->tessEvalShader.source = regularShaderSource;
|
||||
sconfig->tessEvalShader.version = "#version 410\n";
|
||||
sconfig->tessEvalShader.AddDefine("PATCH_TESS_EVAL_REGULAR_SHADER");
|
||||
sconfig->fragmentShader.source = regularShaderSource;
|
||||
sconfig->fragmentShader.version = "#version 410\n";
|
||||
sconfig->fragmentShader.AddDefine("FRAGMENT_SHADER");
|
||||
break;
|
||||
case kBoundary:
|
||||
sconfig->vertexShader.source = boundaryShaderSource;
|
||||
sconfig->vertexShader.version = "#version 410\n";
|
||||
sconfig->vertexShader.AddDefine("PATCH_VERTEX_SHADER");
|
||||
sconfig->tessControlShader.source = boundaryShaderSource;
|
||||
sconfig->tessControlShader.version = "#version 410\n";
|
||||
sconfig->tessControlShader.AddDefine("PATCH_TESS_CONTROL_BOUNDARY_SHADER");
|
||||
sconfig->tessEvalShader.source = boundaryShaderSource;
|
||||
sconfig->tessEvalShader.version = "#version 410\n";
|
||||
sconfig->tessEvalShader.AddDefine("PATCH_TESS_EVAL_BOUNDARY_SHADER");
|
||||
sconfig->fragmentShader.source = boundaryShaderSource;
|
||||
sconfig->fragmentShader.version = "#version 410\n";
|
||||
sconfig->fragmentShader.AddDefine("FRAGMENT_SHADER");
|
||||
break;
|
||||
case kCorner:
|
||||
sconfig->vertexShader.source = cornerShaderSource;
|
||||
sconfig->vertexShader.version = "#version 410\n";
|
||||
sconfig->vertexShader.AddDefine("PATCH_VERTEX_SHADER");
|
||||
sconfig->tessControlShader.source = cornerShaderSource;
|
||||
sconfig->tessControlShader.version = "#version 410\n";
|
||||
sconfig->tessControlShader.AddDefine("PATCH_TESS_CONTROL_CORNER_SHADER");
|
||||
sconfig->tessEvalShader.source = cornerShaderSource;
|
||||
sconfig->tessEvalShader.version = "#version 410\n";
|
||||
sconfig->tessEvalShader.AddDefine("PATCH_TESS_EVAL_CORNER_SHADER");
|
||||
sconfig->fragmentShader.source = cornerShaderSource;
|
||||
sconfig->fragmentShader.version = "#version 410\n";
|
||||
sconfig->fragmentShader.AddDefine("FRAGMENT_SHADER");
|
||||
break;
|
||||
case kGregory:
|
||||
sconfig->vertexShader.source = gregoryShaderSource;
|
||||
sconfig->vertexShader.version = "#version 410\n";
|
||||
sconfig->vertexShader.AddDefine("PATCH_VERTEX_GREGORY_SHADER");
|
||||
sconfig->tessControlShader.source = gregoryShaderSource;
|
||||
sconfig->tessControlShader.version = "#version 410\n";
|
||||
sconfig->tessControlShader.AddDefine("PATCH_TESS_CONTROL_GREGORY_SHADER");
|
||||
sconfig->tessEvalShader.source = gregoryShaderSource;
|
||||
sconfig->tessEvalShader.version = "#version 410\n";
|
||||
sconfig->tessEvalShader.AddDefine("PATCH_TESS_EVAL_GREGORY_SHADER");
|
||||
sconfig->fragmentShader.source = gregoryShaderSource;
|
||||
sconfig->fragmentShader.version = "#version 410\n";
|
||||
sconfig->fragmentShader.AddDefine("FRAGMENT_SHADER");
|
||||
break;
|
||||
case kBoundaryGregory:
|
||||
sconfig->vertexShader.source = boundaryGregoryShaderSource;
|
||||
sconfig->vertexShader.version = "#version 410\n";
|
||||
sconfig->vertexShader.AddDefine("PATCH_VERTEX_BOUNDARY_GREGORY_SHADER");
|
||||
sconfig->tessControlShader.source = boundaryGregoryShaderSource;
|
||||
sconfig->tessControlShader.version = "#version 410\n";
|
||||
sconfig->tessControlShader.AddDefine("PATCH_TESS_CONTROL_BOUNDARY_GREGORY_SHADER");
|
||||
sconfig->tessEvalShader.source = boundaryGregoryShaderSource;
|
||||
sconfig->tessEvalShader.version = "#version 410\n";
|
||||
sconfig->tessEvalShader.AddDefine("PATCH_TESS_EVAL_BOUNDARY_GREGORY_SHADER");
|
||||
sconfig->fragmentShader.source = boundaryGregoryShaderSource;
|
||||
sconfig->fragmentShader.version = "#version 410\n";
|
||||
sconfig->fragmentShader.AddDefine("FRAGMENT_SHADER");
|
||||
break;
|
||||
case kTransitionRegular:
|
||||
case kTransitionBoundary:
|
||||
case kTransitionCorner:
|
||||
if (desc.GetPattern() == FarPatchTables::NON_TRANSITION) {
|
||||
switch (desc.GetType()) {
|
||||
case FarPatchTables::QUADS:
|
||||
case FarPatchTables::TRIANGLES:
|
||||
sconfig->vertexShader.source = regularShaderSource;
|
||||
sconfig->vertexShader.version = "#version 410\n";
|
||||
sconfig->vertexShader.AddDefine("VERTEX_SHADER");
|
||||
sconfig->fragmentShader.source = regularShaderSource;
|
||||
sconfig->fragmentShader.AddDefine("FRAGMENT_SHADER");
|
||||
sconfig->fragmentShader.version = "#version 410\n";
|
||||
break;
|
||||
case FarPatchTables::REGULAR:
|
||||
sconfig->vertexShader.source = regularShaderSource;
|
||||
sconfig->vertexShader.version = "#version 410\n";
|
||||
sconfig->vertexShader.AddDefine("PATCH_VERTEX_SHADER");
|
||||
sconfig->tessControlShader.source = regularShaderSource;
|
||||
sconfig->tessControlShader.version = "#version 410\n";
|
||||
sconfig->tessControlShader.AddDefine("PATCH_TESS_CONTROL_REGULAR_SHADER");
|
||||
sconfig->tessEvalShader.source = regularShaderSource;
|
||||
sconfig->tessEvalShader.version = "#version 410\n";
|
||||
sconfig->tessEvalShader.AddDefine("PATCH_TESS_EVAL_REGULAR_SHADER");
|
||||
sconfig->fragmentShader.source = regularShaderSource;
|
||||
sconfig->fragmentShader.version = "#version 410\n";
|
||||
sconfig->fragmentShader.AddDefine("FRAGMENT_SHADER");
|
||||
break;
|
||||
case FarPatchTables::BOUNDARY:
|
||||
sconfig->vertexShader.source = boundaryShaderSource;
|
||||
sconfig->vertexShader.version = "#version 410\n";
|
||||
sconfig->vertexShader.AddDefine("PATCH_VERTEX_SHADER");
|
||||
sconfig->tessControlShader.source = boundaryShaderSource;
|
||||
sconfig->tessControlShader.version = "#version 410\n";
|
||||
sconfig->tessControlShader.AddDefine("PATCH_TESS_CONTROL_BOUNDARY_SHADER");
|
||||
sconfig->tessEvalShader.source = boundaryShaderSource;
|
||||
sconfig->tessEvalShader.version = "#version 410\n";
|
||||
sconfig->tessEvalShader.AddDefine("PATCH_TESS_EVAL_BOUNDARY_SHADER");
|
||||
sconfig->fragmentShader.source = boundaryShaderSource;
|
||||
sconfig->fragmentShader.version = "#version 410\n";
|
||||
sconfig->fragmentShader.AddDefine("FRAGMENT_SHADER");
|
||||
break;
|
||||
case FarPatchTables::CORNER:
|
||||
sconfig->vertexShader.source = cornerShaderSource;
|
||||
sconfig->vertexShader.version = "#version 410\n";
|
||||
sconfig->vertexShader.AddDefine("PATCH_VERTEX_SHADER");
|
||||
sconfig->tessControlShader.source = cornerShaderSource;
|
||||
sconfig->tessControlShader.version = "#version 410\n";
|
||||
sconfig->tessControlShader.AddDefine("PATCH_TESS_CONTROL_CORNER_SHADER");
|
||||
sconfig->tessEvalShader.source = cornerShaderSource;
|
||||
sconfig->tessEvalShader.version = "#version 410\n";
|
||||
sconfig->tessEvalShader.AddDefine("PATCH_TESS_EVAL_CORNER_SHADER");
|
||||
sconfig->fragmentShader.source = cornerShaderSource;
|
||||
sconfig->fragmentShader.version = "#version 410\n";
|
||||
sconfig->fragmentShader.AddDefine("FRAGMENT_SHADER");
|
||||
break;
|
||||
case FarPatchTables::GREGORY:
|
||||
sconfig->vertexShader.source = gregoryShaderSource;
|
||||
sconfig->vertexShader.version = "#version 410\n";
|
||||
sconfig->vertexShader.AddDefine("PATCH_VERTEX_GREGORY_SHADER");
|
||||
sconfig->tessControlShader.source = gregoryShaderSource;
|
||||
sconfig->tessControlShader.version = "#version 410\n";
|
||||
sconfig->tessControlShader.AddDefine("PATCH_TESS_CONTROL_GREGORY_SHADER");
|
||||
sconfig->tessEvalShader.source = gregoryShaderSource;
|
||||
sconfig->tessEvalShader.version = "#version 410\n";
|
||||
sconfig->tessEvalShader.AddDefine("PATCH_TESS_EVAL_GREGORY_SHADER");
|
||||
sconfig->fragmentShader.source = gregoryShaderSource;
|
||||
sconfig->fragmentShader.version = "#version 410\n";
|
||||
sconfig->fragmentShader.AddDefine("FRAGMENT_SHADER");
|
||||
break;
|
||||
case FarPatchTables::GREGORY_BOUNDARY:
|
||||
sconfig->vertexShader.source = boundaryGregoryShaderSource;
|
||||
sconfig->vertexShader.version = "#version 410\n";
|
||||
sconfig->vertexShader.AddDefine("PATCH_VERTEX_BOUNDARY_GREGORY_SHADER");
|
||||
sconfig->tessControlShader.source = boundaryGregoryShaderSource;
|
||||
sconfig->tessControlShader.version = "#version 410\n";
|
||||
sconfig->tessControlShader.AddDefine("PATCH_TESS_CONTROL_BOUNDARY_GREGORY_SHADER");
|
||||
sconfig->tessEvalShader.source = boundaryGregoryShaderSource;
|
||||
sconfig->tessEvalShader.version = "#version 410\n";
|
||||
sconfig->tessEvalShader.AddDefine("PATCH_TESS_EVAL_BOUNDARY_GREGORY_SHADER");
|
||||
sconfig->fragmentShader.source = boundaryGregoryShaderSource;
|
||||
sconfig->fragmentShader.version = "#version 410\n";
|
||||
sconfig->fragmentShader.AddDefine("FRAGMENT_SHADER");
|
||||
break;
|
||||
default:
|
||||
// error
|
||||
delete sconfig;
|
||||
sconfig = NULL;
|
||||
break;
|
||||
}
|
||||
} else { // pattern != NON_TRANSITION
|
||||
sconfig->vertexShader.source = transitionShaderSource;
|
||||
sconfig->vertexShader.version = "#version 410\n";
|
||||
sconfig->vertexShader.AddDefine("PATCH_VERTEX_SHADER");
|
||||
@ -214,32 +220,26 @@ OsdGLDrawRegistryBase::_CreateDrawSourceConfig(OsdPatchDescriptor const & desc)
|
||||
sconfig->fragmentShader.source = transitionShaderSource;
|
||||
sconfig->fragmentShader.version = "#version 410\n";
|
||||
sconfig->fragmentShader.AddDefine("FRAGMENT_SHADER");
|
||||
{
|
||||
int pattern = desc.pattern;
|
||||
int rotation = desc.rotation;
|
||||
int subpatch = desc.subpatch;
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << "CASE" << pattern << subpatch;
|
||||
sconfig->tessControlShader.AddDefine(ss.str());
|
||||
sconfig->tessEvalShader.AddDefine(ss.str());
|
||||
int pattern = desc.GetPattern() - 1;
|
||||
int rotation = desc.GetRotation();
|
||||
int subpatch = desc.GetSubPatch();
|
||||
|
||||
ss.str("");
|
||||
ss << rotation;
|
||||
sconfig->tessControlShader.AddDefine("ROTATE", ss.str());
|
||||
sconfig->tessEvalShader.AddDefine("ROTATE", ss.str());
|
||||
}
|
||||
if (desc.type == kTransitionBoundary) {
|
||||
std::ostringstream ss;
|
||||
ss << "CASE" << pattern << subpatch;
|
||||
sconfig->tessControlShader.AddDefine(ss.str());
|
||||
sconfig->tessEvalShader.AddDefine(ss.str());
|
||||
|
||||
ss.str("");
|
||||
ss << rotation;
|
||||
sconfig->tessControlShader.AddDefine("ROTATE", ss.str());
|
||||
sconfig->tessEvalShader.AddDefine("ROTATE", ss.str());
|
||||
|
||||
if (desc.GetType() == FarPatchTables::BOUNDARY) {
|
||||
sconfig->tessControlShader.AddDefine("BOUNDARY");
|
||||
} else if (desc.type == kTransitionCorner) {
|
||||
} else if (desc.GetType() == FarPatchTables::CORNER) {
|
||||
sconfig->tessControlShader.AddDefine("CORNER");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// error
|
||||
delete sconfig;
|
||||
sconfig = NULL;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -293,7 +293,7 @@ _CompileShader(
|
||||
|
||||
OsdGLDrawConfig *
|
||||
OsdGLDrawRegistryBase::_CreateDrawConfig(
|
||||
OsdPatchDescriptor const & desc,
|
||||
OsdDrawContext::PatchDescriptor const & desc,
|
||||
OsdGLDrawSourceConfig const * sconfig)
|
||||
{
|
||||
assert(sconfig);
|
||||
@ -363,6 +363,8 @@ OsdGLDrawRegistryBase::_CreateDrawConfig(
|
||||
}
|
||||
|
||||
config->program = program;
|
||||
config->levelBaseUniform = glGetUniformLocation(program, "LevelBase");
|
||||
config->gregoryQuadOffsetBaseUniform = glGetUniformLocation(program, "GregoryQuadOffsetBase");
|
||||
|
||||
return config;
|
||||
}
|
||||
|
@ -48,7 +48,12 @@
|
||||
// with this license.
|
||||
// (E) The software is licensed "as-is." You bear the risk of
|
||||
// using it. The contributors give no express warranties,
|
||||
|
||||
// guarantees or conditions. You may have additional consumer
|
||||
// rights under your local laws which this license cannot change.
|
||||
// To the extent permitted under your local laws, the contributors
|
||||
// exclude the implied warranties of merchantability, fitness for
|
||||
// a particular purpose and non-infringement.
|
||||
//
|
||||
#ifndef OSD_GL_DRAW_REGISTRY_H
|
||||
#define OSD_GL_DRAW_REGISTRY_H
|
||||
|
||||
@ -80,10 +85,15 @@ namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
struct OsdGLDrawConfig : public OsdDrawConfig {
|
||||
OsdGLDrawConfig() : program(0) {}
|
||||
OsdGLDrawConfig() :
|
||||
program(0),
|
||||
levelBaseUniform(-1),
|
||||
gregoryQuadOffsetBaseUniform(-1) {}
|
||||
virtual ~OsdGLDrawConfig();
|
||||
|
||||
GLuint program;
|
||||
GLint levelBaseUniform;
|
||||
GLint gregoryQuadOffsetBaseUniform;
|
||||
};
|
||||
|
||||
struct OsdGLDrawSourceConfig : public OsdDrawSourceConfig {
|
||||
@ -99,7 +109,7 @@ struct OsdGLDrawSourceConfig : public OsdDrawSourceConfig {
|
||||
|
||||
class OsdGLDrawRegistryBase {
|
||||
public:
|
||||
typedef OsdPatchDescriptor DescType;
|
||||
typedef OsdDrawContext::PatchDescriptor DescType;
|
||||
typedef OsdGLDrawConfig ConfigType;
|
||||
typedef OsdGLDrawSourceConfig SourceConfigType;
|
||||
|
||||
@ -116,7 +126,7 @@ protected:
|
||||
_CreateDrawSourceConfig(DescType const & desc);
|
||||
};
|
||||
|
||||
template <class DESC_TYPE = OsdPatchDescriptor,
|
||||
template <class DESC_TYPE = OsdDrawContext::PatchDescriptor,
|
||||
class CONFIG_TYPE = OsdGLDrawConfig,
|
||||
class SOURCE_CONFIG_TYPE = OsdGLDrawSourceConfig >
|
||||
class OsdGLDrawRegistry : public OsdGLDrawRegistryBase {
|
||||
@ -128,7 +138,6 @@ public:
|
||||
typedef SOURCE_CONFIG_TYPE SourceConfigType;
|
||||
|
||||
typedef std::map<DescType, ConfigType *> ConfigMap;
|
||||
typedef std::map<DescType, SourceConfigType *> SourceConfigMap;
|
||||
|
||||
public:
|
||||
virtual ~OsdGLDrawRegistry() {
|
||||
@ -141,11 +150,6 @@ public:
|
||||
delete i->second;
|
||||
}
|
||||
_configMap.clear();
|
||||
for (typename SourceConfigMap::iterator
|
||||
i = _sourceConfigMap.begin(); i != _sourceConfigMap.end(); ++i) {
|
||||
delete i->second;
|
||||
}
|
||||
_sourceConfigMap.clear();
|
||||
}
|
||||
|
||||
// fetch shader config
|
||||
@ -156,25 +160,12 @@ public:
|
||||
return it->second;
|
||||
} else {
|
||||
ConfigType * config =
|
||||
_CreateDrawConfig(desc, GetDrawSourceConfig(desc));
|
||||
_CreateDrawConfig(desc, _CreateDrawSourceConfig(desc));
|
||||
_configMap[desc] = config;
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
||||
// fetch text and related defines for patch descriptor
|
||||
SourceConfigType *
|
||||
GetDrawSourceConfig(DescType const & desc) {
|
||||
typename SourceConfigMap::iterator it = _sourceConfigMap.find(desc);
|
||||
if (it != _sourceConfigMap.end()) {
|
||||
return it->second;
|
||||
} else {
|
||||
SourceConfigType * sconfig = _CreateDrawSourceConfig(desc);
|
||||
_sourceConfigMap[desc] = sconfig;
|
||||
return sconfig;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ConfigType * _NewDrawConfig() { return new ConfigType(); }
|
||||
virtual ConfigType *
|
||||
@ -187,7 +178,6 @@ protected:
|
||||
|
||||
private:
|
||||
ConfigMap _configMap;
|
||||
SourceConfigMap _sourceConfigMap;
|
||||
};
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
|
@ -54,7 +54,6 @@
|
||||
// exclude the implied warranties of merchantability, fitness for
|
||||
// a particular purpose and non-infringement.
|
||||
//
|
||||
|
||||
#ifndef OSD_GL_MESH_H
|
||||
#define OSD_GL_MESH_H
|
||||
|
||||
@ -99,15 +98,13 @@ public:
|
||||
_drawContext(0)
|
||||
{
|
||||
FarMeshFactory<OsdVertex> meshFactory(hmesh, level, bits.test(MeshAdaptive));
|
||||
_farMesh = meshFactory.Create(bits.test(MeshPtexData),
|
||||
bits.test(MeshFVarData));
|
||||
_farMesh = meshFactory.Create(bits.test(MeshFVarData));
|
||||
|
||||
int numVertices = _farMesh->GetNumVertices();
|
||||
_vertexBuffer = VertexBuffer::Create(numElements, numVertices);
|
||||
_computeContext = ComputeContext::Create(_farMesh);
|
||||
_drawContext = DrawContext::Create(_farMesh, _vertexBuffer,
|
||||
bits.test(MeshPtexData),
|
||||
bits.test(MeshFVarData));
|
||||
_drawContext = DrawContext::Create(_farMesh->GetPatchTables(), bits.test(MeshFVarData));
|
||||
_drawContext->UpdateVertexTexture(_vertexBuffer);
|
||||
}
|
||||
|
||||
virtual ~OsdMesh() {
|
||||
@ -171,15 +168,13 @@ public:
|
||||
_clQueue(clQueue)
|
||||
{
|
||||
FarMeshFactory<OsdVertex> meshFactory(hmesh, level, bits.test(MeshAdaptive));
|
||||
_farMesh = meshFactory.Create(bits.test(MeshPtexData),
|
||||
bits.test(MeshFVarData));
|
||||
_farMesh = meshFactory.Create(bits.test(MeshFVarData));
|
||||
|
||||
int numVertices = _farMesh->GetNumVertices();
|
||||
_vertexBuffer = VertexBuffer::Create(numElements, numVertices, _clContext);
|
||||
_computeContext = ComputeContext::Create(_farMesh, _clContext);
|
||||
_drawContext = DrawContext::Create(_farMesh, _vertexBuffer,
|
||||
bits.test(MeshPtexData),
|
||||
bits.test(MeshFVarData));
|
||||
_drawContext = DrawContext::Create(_farMesh->GetPatchTables(), bits.test(MeshFVarData));
|
||||
_drawContext->UpdateVertexTexture(_vertexBuffer);
|
||||
}
|
||||
|
||||
virtual ~OsdMesh() {
|
||||
|
@ -103,7 +103,7 @@ OsdGLVertexBuffer::UpdateData(const float *src, int startVertex, int numVertices
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
int size = numVertices * _numElements * sizeof(float);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, startVertex * _numElements, size, src);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, startVertex * _numElements * sizeof(float), size, src);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
|
@ -78,10 +78,13 @@
|
||||
namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
///
|
||||
/// \brief Concrete vertex buffer class for GLSL subvision and OpenGL drawing.
|
||||
///
|
||||
/// OsdGLVertexBuffer implements OsdGLVertexBufferInterface. An instance
|
||||
/// of this buffer class can be passed to OsdGLComputeController
|
||||
/// and OsdGLDrawController
|
||||
///
|
||||
class OsdGLVertexBuffer {
|
||||
public:
|
||||
/// Creator. Returns NULL if error.
|
||||
@ -90,8 +93,8 @@ public:
|
||||
/// Destructor.
|
||||
~OsdGLVertexBuffer();
|
||||
|
||||
/// This method is meant to be used in client code in order to provide
|
||||
/// coarse vertices data to Osd.
|
||||
/// This method is meant to be used in client code in order to provide coarse
|
||||
/// vertices data to Osd.
|
||||
void UpdateData(const float *src, int startVertex, int numVertices);
|
||||
|
||||
/// Returns how many elements defined in this vertex buffer.
|
||||
|
@ -157,7 +157,7 @@ OsdGLSLComputeHEditTable::GetPrimvarWidth() const {
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
OsdGLSLComputeContext::OsdGLSLComputeContext(
|
||||
FarMesh<OsdVertex> *farMesh)
|
||||
FarMesh<OsdVertex> const *farMesh)
|
||||
: _vertexTexture(0), _varyingTexture(0) {
|
||||
|
||||
FarSubdivisionTables<OsdVertex> const * farTables =
|
||||
@ -238,18 +238,6 @@ OsdGLSLComputeContext::GetCurrentVaryingBuffer() const {
|
||||
return _currentVaryingBuffer;
|
||||
}
|
||||
|
||||
int
|
||||
OsdGLSLComputeContext::GetNumCurrentVertexElements() const {
|
||||
|
||||
return _numVertexElements;
|
||||
}
|
||||
|
||||
int
|
||||
OsdGLSLComputeContext::GetNumCurrentVaryingElements() const {
|
||||
|
||||
return _numVaryingElements;
|
||||
}
|
||||
|
||||
OsdGLSLComputeKernelBundle *
|
||||
OsdGLSLComputeContext::GetKernelBundle() const {
|
||||
|
||||
@ -264,7 +252,7 @@ OsdGLSLComputeContext::SetKernelBundle(
|
||||
}
|
||||
|
||||
OsdGLSLComputeContext *
|
||||
OsdGLSLComputeContext::Create(FarMesh<OsdVertex> *farmesh) {
|
||||
OsdGLSLComputeContext::Create(FarMesh<OsdVertex> const *farmesh) {
|
||||
|
||||
return new OsdGLSLComputeContext(farmesh);
|
||||
}
|
||||
|
@ -77,6 +77,7 @@
|
||||
|
||||
#include "../far/vertexEditTables.h"
|
||||
#include "../osd/vertex.h"
|
||||
#include "../osd/vertexDescriptor.h"
|
||||
#include "../osd/nonCopyable.h"
|
||||
|
||||
#include <vector>
|
||||
@ -142,12 +143,13 @@ private:
|
||||
/// compute device.
|
||||
///
|
||||
class OsdGLSLComputeContext {
|
||||
|
||||
public:
|
||||
/// Creates an OsdGLSLComputeContext instance
|
||||
///
|
||||
/// @param farmesh the FarMesh used for this Context.
|
||||
///
|
||||
static OsdGLSLComputeContext * Create(FarMesh<OsdVertex> *farmesh);
|
||||
static OsdGLSLComputeContext * Create(FarMesh<OsdVertex> const *farmesh);
|
||||
|
||||
/// Destructor
|
||||
virtual ~OsdGLSLComputeContext();
|
||||
@ -156,9 +158,9 @@ public:
|
||||
/// that data buffers are properly inter-operated between Contexts and
|
||||
/// Controllers operating across multiple devices.
|
||||
///
|
||||
/// @param a buffer containing vertex-interpolated primvar data
|
||||
/// @param vertex a buffer containing vertex-interpolated primvar data
|
||||
///
|
||||
/// @param a buffer containing varying-interpolated primvar data
|
||||
/// @param varying a buffer containing varying-interpolated primvar data
|
||||
///
|
||||
template<class VERTEX_BUFFER, class VARYING_BUFFER>
|
||||
void Bind(VERTEX_BUFFER *vertex, VARYING_BUFFER *varying) {
|
||||
@ -166,8 +168,8 @@ public:
|
||||
_currentVertexBuffer = vertex ? vertex->BindVBO() : 0;
|
||||
_currentVaryingBuffer = varying ? varying->BindVBO() : 0;
|
||||
|
||||
_numVertexElements = vertex ? vertex->GetNumElements() : 0;
|
||||
_numVaryingElements = varying ? varying->GetNumElements() : 0;
|
||||
_vdesc.numVertexElements = vertex ? vertex->GetNumElements() : 0;
|
||||
_vdesc.numVaryingElements = varying ? varying->GetNumElements() : 0;
|
||||
|
||||
bindShaderStorageBuffers();
|
||||
}
|
||||
@ -201,9 +203,13 @@ public:
|
||||
/// Returns a handle to the varying-interpolated buffer
|
||||
GLuint GetCurrentVaryingBuffer() const;
|
||||
|
||||
int GetNumCurrentVertexElements() const;
|
||||
|
||||
int GetNumCurrentVaryingElements() const;
|
||||
/// Returns an OsdVertexDescriptor if vertex buffers have been bound.
|
||||
///
|
||||
/// @return a descriptor for the format of the vertex data currently bound
|
||||
///
|
||||
OsdVertexDescriptor const & GetVertexDescriptor() const {
|
||||
return _vdesc;
|
||||
}
|
||||
|
||||
OsdGLSLComputeKernelBundle * GetKernelBundle() const;
|
||||
|
||||
@ -236,7 +242,7 @@ public:
|
||||
void UnbindEditShaderStorageBuffers();
|
||||
|
||||
protected:
|
||||
explicit OsdGLSLComputeContext(FarMesh<OsdVertex> *farMesh);
|
||||
explicit OsdGLSLComputeContext(FarMesh<OsdVertex> const *farMesh);
|
||||
|
||||
void bindShaderStorageBuffers();
|
||||
|
||||
@ -249,8 +255,7 @@ private:
|
||||
GLuint _vertexTexture,
|
||||
_varyingTexture;
|
||||
|
||||
int _numVertexElements,
|
||||
_numVaryingElements;
|
||||
OsdVertexDescriptor _vdesc;
|
||||
|
||||
GLuint _currentVertexBuffer,
|
||||
_currentVaryingBuffer;
|
||||
|
@ -95,11 +95,9 @@ OsdGLSLComputeKernelBundle::~OsdGLSLComputeKernelBundle() {
|
||||
}
|
||||
|
||||
bool
|
||||
OsdGLSLComputeKernelBundle::Compile(int numVertexElements,
|
||||
int numVaryingElements) {
|
||||
OsdGLSLComputeKernelBundle::Compile(int numVertexElements, int numVaryingElements) {
|
||||
|
||||
_numVertexElements = numVertexElements;
|
||||
_numVaryingElements = numVaryingElements;
|
||||
_vdesc.Set(numVertexElements, numVaryingElements );
|
||||
|
||||
if (_program) {
|
||||
glDeleteProgram(_program);
|
||||
|
@ -54,7 +54,6 @@
|
||||
// exclude the implied warranties of merchantability, fitness for
|
||||
// a particular purpose and non-infringement.
|
||||
//
|
||||
|
||||
#ifndef OSD_GLSL_COMPUTE_KERNEL_BUNDLE_H
|
||||
#define OSD_GLSL_COMPUTE_KERNEL_BUNDLE_H
|
||||
|
||||
@ -75,113 +74,116 @@
|
||||
#endif
|
||||
|
||||
#include "../version.h"
|
||||
#include "../far/subdivisionTables.h"
|
||||
#include "../osd/nonCopyable.h"
|
||||
#include "../osd/vertex.h"
|
||||
#include "../far/subdivisionTables.h"
|
||||
#include "../osd/vertexDescriptor.h"
|
||||
|
||||
|
||||
namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
class OsdGLSLComputeKernelBundle
|
||||
: OsdNonCopyable<OsdGLSLComputeKernelBundle> {
|
||||
public:
|
||||
OsdGLSLComputeKernelBundle();
|
||||
~OsdGLSLComputeKernelBundle();
|
||||
class OsdGLSLComputeKernelBundle : OsdNonCopyable<OsdGLSLComputeKernelBundle> {
|
||||
public:
|
||||
OsdGLSLComputeKernelBundle();
|
||||
~OsdGLSLComputeKernelBundle();
|
||||
|
||||
bool Compile(int numVertexElements, int numVaryingElements);
|
||||
bool Compile(int numVertexElements, int numVaryingElements);
|
||||
|
||||
void ApplyBilinearFaceVerticesKernel(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyBilinearFaceVerticesKernel(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void ApplyBilinearEdgeVerticesKernel(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyBilinearEdgeVerticesKernel(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void ApplyBilinearVertexVerticesKernel(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyBilinearVertexVerticesKernel(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void ApplyCatmarkFaceVerticesKernel(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyCatmarkFaceVerticesKernel(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void ApplyCatmarkEdgeVerticesKernel(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyCatmarkEdgeVerticesKernel(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void ApplyCatmarkVertexVerticesKernelB(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyCatmarkVertexVerticesKernelB(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void ApplyCatmarkVertexVerticesKernelA(
|
||||
int vertexOffset, int tableOffset, int start, int end, bool pass);
|
||||
void ApplyCatmarkVertexVerticesKernelA(
|
||||
int vertexOffset, int tableOffset, int start, int end, bool pass);
|
||||
|
||||
void ApplyLoopEdgeVerticesKernel(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyLoopEdgeVerticesKernel(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void ApplyLoopVertexVerticesKernelB(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyLoopVertexVerticesKernelB(
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void ApplyLoopVertexVerticesKernelA(
|
||||
int vertexOffset, int tableOffset, int start, int end, bool pass);
|
||||
void ApplyLoopVertexVerticesKernelA(
|
||||
int vertexOffset, int tableOffset, int start, int end, bool pass);
|
||||
|
||||
void ApplyEditAdd(int primvarOffset, int primvarWidth,
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyEditAdd(int primvarOffset, int primvarWidth,
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void UseProgram() const;
|
||||
void UseProgram() const;
|
||||
|
||||
GLuint GetTableUniformLocation(int tableIndex) const {
|
||||
return _tableUniforms[tableIndex];
|
||||
GLuint GetTableUniformLocation(int tableIndex) const {
|
||||
return _tableUniforms[tableIndex];
|
||||
}
|
||||
|
||||
struct Match {
|
||||
|
||||
/// Constructor
|
||||
Match(int numVertexElements, int numVaryingElements)
|
||||
: vdesc(numVertexElements, numVaryingElements) {
|
||||
}
|
||||
|
||||
struct Match {
|
||||
Match(int numVertexElements, int numVaryingElements) :
|
||||
_numVertexElements(numVertexElements),
|
||||
_numVaryingElements(numVaryingElements) {}
|
||||
bool operator() (const OsdGLSLComputeKernelBundle *kernel) {
|
||||
return (kernel->_numVertexElements == _numVertexElements
|
||||
&& kernel->_numVaryingElements == _numVaryingElements);
|
||||
}
|
||||
int _numVertexElements, _numVaryingElements;
|
||||
};
|
||||
bool operator() (OsdGLSLComputeKernelBundle const *kernel) {
|
||||
return vdesc == kernel->_vdesc;
|
||||
}
|
||||
|
||||
friend struct Match;
|
||||
|
||||
protected:
|
||||
void dispatchCompute(int vertexOffset, int tableOffset, int start, int end) const;
|
||||
|
||||
GLuint _program;
|
||||
|
||||
// uniform locations for compute
|
||||
GLuint _tableUniforms[FarSubdivisionTables<OsdVertex>::TABLE_TYPES_COUNT];
|
||||
GLuint _uniformVertexPass;
|
||||
GLuint _uniformVertexOffset;
|
||||
GLuint _uniformTableOffset;
|
||||
GLuint _uniformIndexStart;
|
||||
GLuint _uniformIndexEnd;
|
||||
|
||||
// uniform locations for vertex edit
|
||||
GLuint _uniformEditPrimVarOffset;
|
||||
GLuint _uniformEditPrimVarWidth;
|
||||
|
||||
// general face-vertex kernel (all schemes)
|
||||
GLuint _subComputeFace;
|
||||
// edge-vertex kernel (catmark + loop schemes)
|
||||
GLuint _subComputeEdge;
|
||||
// edge-vertex kernel (bilinear scheme)
|
||||
GLuint _subComputeBilinearEdge;
|
||||
// vertex-vertex kernel (bilinear scheme)
|
||||
GLuint _subComputeVertex;
|
||||
// vertex-vertex kernel A (catmark + loop schemes)
|
||||
GLuint _subComputeVertexA;
|
||||
// vertex-vertex kernel B (catmark scheme)
|
||||
GLuint _subComputeCatmarkVertexB;
|
||||
// vertex-vertex kernel B (loop scheme)
|
||||
GLuint _subComputeLoopVertexB;
|
||||
// hedit kernel (add)
|
||||
GLuint _subEditAdd;
|
||||
|
||||
int _numVertexElements,
|
||||
_numVaryingElements;
|
||||
|
||||
int _workGroupSize;
|
||||
OsdVertexDescriptor vdesc;
|
||||
};
|
||||
|
||||
friend struct Match;
|
||||
|
||||
protected:
|
||||
void dispatchCompute(int vertexOffset, int tableOffset, int start, int end) const;
|
||||
|
||||
GLuint _program;
|
||||
|
||||
// uniform locations for compute
|
||||
GLuint _tableUniforms[FarSubdivisionTables<OsdVertex>::TABLE_TYPES_COUNT];
|
||||
GLuint _uniformVertexPass;
|
||||
GLuint _uniformVertexOffset;
|
||||
GLuint _uniformTableOffset;
|
||||
GLuint _uniformIndexStart;
|
||||
GLuint _uniformIndexEnd;
|
||||
|
||||
// uniform locations for vertex edit
|
||||
GLuint _uniformEditPrimVarOffset;
|
||||
GLuint _uniformEditPrimVarWidth;
|
||||
|
||||
|
||||
GLuint _subComputeFace; // general face-vertex kernel (all schemes)
|
||||
|
||||
GLuint _subComputeEdge; // edge-vertex kernel (catmark + loop schemes)
|
||||
|
||||
GLuint _subComputeBilinearEdge; // edge-vertex kernel (bilinear scheme)
|
||||
|
||||
GLuint _subComputeVertex; // vertex-vertex kernel (bilinear scheme)
|
||||
|
||||
GLuint _subComputeVertexA; // vertex-vertex kernel A (catmark + loop schemes)
|
||||
|
||||
GLuint _subComputeCatmarkVertexB; // vertex-vertex kernel B (catmark scheme)
|
||||
|
||||
GLuint _subComputeLoopVertexB; // vertex-vertex kernel B (loop scheme)
|
||||
|
||||
GLuint _subEditAdd; // hedit kernel (add)
|
||||
|
||||
int _workGroupSize;
|
||||
|
||||
OsdVertexDescriptor _vdesc;
|
||||
};
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
using namespace OPENSUBDIV_VERSION;
|
||||
|
||||
|
@ -94,9 +94,6 @@ out block {
|
||||
ControlVertex v;
|
||||
} output[];
|
||||
|
||||
uniform isamplerBuffer g_patchLevelBuffer;
|
||||
OSD_DECLARE_PTEX_INDICES_BUFFER;
|
||||
|
||||
#define ID gl_InvocationID
|
||||
|
||||
void main()
|
||||
@ -122,7 +119,7 @@ void main()
|
||||
|
||||
output[ID].v.position = vec4(pos, 1.0);
|
||||
|
||||
int patchLevel = texelFetchBuffer(g_patchLevelBuffer, gl_PrimitiveID + LevelBase).x;
|
||||
int patchLevel = GetPatchLevel();
|
||||
// +0.5 to avoid interpolation error of integer value
|
||||
output[ID].v.patchCoord = vec4(0, 0,
|
||||
patchLevel+0.5,
|
||||
|
@ -273,9 +273,6 @@ out block {
|
||||
GregEvalVertex v;
|
||||
} output[];
|
||||
|
||||
uniform isamplerBuffer g_patchLevelBuffer;
|
||||
OSD_DECLARE_PTEX_INDICES_BUFFER;
|
||||
|
||||
#define ID gl_InvocationID
|
||||
|
||||
void main()
|
||||
@ -402,7 +399,7 @@ void main()
|
||||
output[ID].v.Fp = Fp;
|
||||
output[ID].v.Fm = Fm;
|
||||
|
||||
int patchLevel = texelFetchBuffer(g_patchLevelBuffer, gl_PrimitiveID + LevelBase).x;
|
||||
int patchLevel = GetPatchLevel();
|
||||
output[ID].v.patchCoord = vec4(0, 0,
|
||||
patchLevel+0.5f,
|
||||
gl_PrimitiveID+LevelBase+0.5f);
|
||||
|
@ -163,9 +163,14 @@ float TessAdaptive(vec3 p0, vec3 p1, int patchLevel)
|
||||
#define OSD_DISPLACEMENT_CALLBACK
|
||||
#endif
|
||||
|
||||
#ifdef USE_PTEX_COORD
|
||||
uniform isamplerBuffer g_ptexIndicesBuffer;
|
||||
|
||||
#define OSD_DECLARE_PTEX_INDICES_BUFFER uniform isamplerBuffer g_ptexIndicesBuffer;
|
||||
int GetPatchLevel()
|
||||
{
|
||||
ivec2 ptexIndex = texelFetchBuffer(g_ptexIndicesBuffer,
|
||||
gl_PrimitiveID + LevelBase).xy;
|
||||
return (ptexIndex.y & 0xf);
|
||||
}
|
||||
|
||||
#define OSD_COMPUTE_PTEX_COORD_TESSCONTROL_SHADER \
|
||||
{ \
|
||||
@ -207,13 +212,6 @@ float TessAdaptive(vec3 p0, vec3 p1, int patchLevel)
|
||||
} \
|
||||
}
|
||||
|
||||
#else
|
||||
#define OSD_DECLARE_PTEX_INDICES_BUFFER
|
||||
#define OSD_COMPUTE_PTEX_COORD_TESSCONTROL_SHADER
|
||||
#define OSD_COMPUTE_PTEX_COORD_TESSEVAL_SHADER
|
||||
#define OSD_COMPUTE_PTEX_COMPATIBLE_TANGENT(ROTATE)
|
||||
#endif // USE_PTEX_COORD
|
||||
|
||||
#ifdef OSD_ENABLE_PATCH_CULL
|
||||
|
||||
#define OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(P) \
|
||||
|
@ -94,9 +94,6 @@ out block {
|
||||
ControlVertex v;
|
||||
} output[];
|
||||
|
||||
uniform isamplerBuffer g_patchLevelBuffer;
|
||||
OSD_DECLARE_PTEX_INDICES_BUFFER;
|
||||
|
||||
#define ID gl_InvocationID
|
||||
|
||||
void main()
|
||||
@ -120,7 +117,7 @@ void main()
|
||||
|
||||
output[ID].v.position = vec4(pos, 1.0);
|
||||
|
||||
int patchLevel = texelFetchBuffer(g_patchLevelBuffer, gl_PrimitiveID + LevelBase).x;
|
||||
int patchLevel = GetPatchLevel();
|
||||
// +0.5 to avoid interpolation error of integer value
|
||||
output[ID].v.patchCoord = vec4(0, 0,
|
||||
patchLevel+0.5,
|
||||
|
@ -168,9 +168,6 @@ out block {
|
||||
GregEvalVertex v;
|
||||
} output[];
|
||||
|
||||
uniform isamplerBuffer g_patchLevelBuffer;
|
||||
OSD_DECLARE_PTEX_INDICES_BUFFER;
|
||||
|
||||
#define ID gl_InvocationID
|
||||
|
||||
void main()
|
||||
@ -237,7 +234,7 @@ void main()
|
||||
output[ID].v.Fp = Fp;
|
||||
output[ID].v.Fm = Fm;
|
||||
|
||||
int patchLevel = texelFetchBuffer(g_patchLevelBuffer, gl_PrimitiveID + LevelBase).x;
|
||||
int patchLevel = GetPatchLevel();
|
||||
output[ID].v.patchCoord = vec4(0, 0,
|
||||
patchLevel+0.5,
|
||||
gl_PrimitiveID+LevelBase+0.5);
|
||||
|
@ -96,9 +96,6 @@ out block {
|
||||
ControlVertex v;
|
||||
} output[];
|
||||
|
||||
uniform isamplerBuffer g_patchLevelBuffer;
|
||||
OSD_DECLARE_PTEX_INDICES_BUFFER;
|
||||
|
||||
#define ID gl_InvocationID
|
||||
|
||||
void main()
|
||||
@ -124,7 +121,8 @@ void main()
|
||||
|
||||
output[ID].v.position = vec4(pos, 1.0);
|
||||
|
||||
int patchLevel = texelFetchBuffer(g_patchLevelBuffer, gl_PrimitiveID + LevelBase).x;
|
||||
int patchLevel = GetPatchLevel();
|
||||
|
||||
// +0.5 to avoid interpolation error of integer value
|
||||
output[ID].v.patchCoord = vec4(0, 0,
|
||||
patchLevel+0.5,
|
||||
|
@ -110,9 +110,6 @@ out block {
|
||||
ControlVertex v;
|
||||
} output[];
|
||||
|
||||
uniform isamplerBuffer g_patchLevelBuffer;
|
||||
OSD_DECLARE_PTEX_INDICES_BUFFER;
|
||||
|
||||
#define ID gl_InvocationID
|
||||
|
||||
void main()
|
||||
@ -180,7 +177,7 @@ void main()
|
||||
|
||||
output[ID].v.position = vec4(pos, 1.0);
|
||||
|
||||
int patchLevel = texelFetchBuffer(g_patchLevelBuffer, gl_PrimitiveID + LevelBase).x;
|
||||
int patchLevel = GetPatchLevel();
|
||||
output[ID].v.patchCoord = vec4(0, 0,
|
||||
patchLevel+0.5,
|
||||
gl_PrimitiveID+LevelBase+0.5);
|
||||
|
@ -164,7 +164,7 @@ OsdGLSLTransformFeedbackHEditTable::GetPrimvarWidth() const {
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
OsdGLSLTransformFeedbackComputeContext::OsdGLSLTransformFeedbackComputeContext(
|
||||
FarMesh<OsdVertex> *farMesh) :
|
||||
FarMesh<OsdVertex> const *farMesh) :
|
||||
_vertexTexture(0), _varyingTexture(0) {
|
||||
|
||||
FarSubdivisionTables<OsdVertex> const * farTables =
|
||||
@ -243,18 +243,6 @@ OsdGLSLTransformFeedbackComputeContext::GetCurrentVaryingBuffer() const {
|
||||
return _currentVaryingBuffer;
|
||||
}
|
||||
|
||||
int
|
||||
OsdGLSLTransformFeedbackComputeContext::GetNumCurrentVertexElements() const {
|
||||
|
||||
return _numVertexElements;
|
||||
}
|
||||
|
||||
int
|
||||
OsdGLSLTransformFeedbackComputeContext::GetNumCurrentVaryingElements() const {
|
||||
|
||||
return _numVaryingElements;
|
||||
}
|
||||
|
||||
OsdGLSLTransformFeedbackKernelBundle *
|
||||
OsdGLSLTransformFeedbackComputeContext::GetKernelBundle() const {
|
||||
|
||||
@ -268,7 +256,7 @@ OsdGLSLTransformFeedbackComputeContext::SetKernelBundle(OsdGLSLTransformFeedback
|
||||
}
|
||||
|
||||
OsdGLSLTransformFeedbackComputeContext *
|
||||
OsdGLSLTransformFeedbackComputeContext::Create(FarMesh<OsdVertex> *farmesh) {
|
||||
OsdGLSLTransformFeedbackComputeContext::Create(FarMesh<OsdVertex> const *farmesh) {
|
||||
|
||||
return new OsdGLSLTransformFeedbackComputeContext(farmesh);
|
||||
}
|
||||
|
@ -77,6 +77,7 @@
|
||||
|
||||
#include "../far/vertexEditTables.h"
|
||||
#include "../osd/vertex.h"
|
||||
#include "../osd/vertexDescriptor.h"
|
||||
#include "../osd/nonCopyable.h"
|
||||
|
||||
#include <vector>
|
||||
@ -145,7 +146,7 @@ public:
|
||||
///
|
||||
/// @param farmesh the FarMesh used for this Context.
|
||||
///
|
||||
static OsdGLSLTransformFeedbackComputeContext * Create(FarMesh<OsdVertex> *farmesh);
|
||||
static OsdGLSLTransformFeedbackComputeContext * Create(FarMesh<OsdVertex> const *farmesh);
|
||||
|
||||
/// Destructor
|
||||
virtual ~OsdGLSLTransformFeedbackComputeContext();
|
||||
@ -154,9 +155,9 @@ public:
|
||||
/// that data buffers are properly inter-operated between Contexts and
|
||||
/// Controllers operating across multiple devices.
|
||||
///
|
||||
/// @param a buffer containing vertex-interpolated primvar data
|
||||
/// @param vertex a buffer containing vertex-interpolated primvar data
|
||||
///
|
||||
/// @param a buffer containing varying-interpolated primvar data
|
||||
/// @param varying a buffer containing varying-interpolated primvar data
|
||||
///
|
||||
template<class VERTEX_BUFFER, class VARYING_BUFFER>
|
||||
void Bind(VERTEX_BUFFER *vertex, VARYING_BUFFER *varying) {
|
||||
@ -164,8 +165,8 @@ public:
|
||||
_currentVertexBuffer = vertex ? vertex->BindVBO() : 0;
|
||||
_currentVaryingBuffer = varying ? varying->BindVBO() : 0;
|
||||
|
||||
_numVertexElements = vertex ? vertex->GetNumElements() : 0;
|
||||
_numVaryingElements = varying ? varying->GetNumElements() : 0;
|
||||
_vdesc.numVertexElements = vertex ? vertex->GetNumElements() : 0;
|
||||
_vdesc.numVaryingElements = varying ? varying->GetNumElements() : 0;
|
||||
|
||||
bindTextures();
|
||||
}
|
||||
@ -198,9 +199,13 @@ public:
|
||||
/// Returns a handle to the varying-interpolated buffer
|
||||
GLuint GetCurrentVaryingBuffer() const;
|
||||
|
||||
int GetNumCurrentVertexElements() const;
|
||||
|
||||
int GetNumCurrentVaryingElements() const;
|
||||
/// Returns an OsdVertexDescriptor if vertex buffers have been bound.
|
||||
///
|
||||
/// @return a descriptor for the format of the vertex data currently bound
|
||||
///
|
||||
OsdVertexDescriptor const & GetVertexDescriptor() const {
|
||||
return _vdesc;
|
||||
}
|
||||
|
||||
OsdGLSLTransformFeedbackKernelBundle * GetKernelBundle() const;
|
||||
|
||||
@ -211,7 +216,7 @@ public:
|
||||
void UnbindEditTextures();
|
||||
|
||||
protected:
|
||||
explicit OsdGLSLTransformFeedbackComputeContext(FarMesh<OsdVertex> *farMesh);
|
||||
explicit OsdGLSLTransformFeedbackComputeContext(FarMesh<OsdVertex> const *farMesh);
|
||||
|
||||
void bindTexture(GLuint sampler, GLuint texture, int unit);
|
||||
|
||||
@ -228,8 +233,7 @@ private:
|
||||
GLuint _vertexTexture,
|
||||
_varyingTexture;
|
||||
|
||||
int _numVertexElements,
|
||||
_numVaryingElements;
|
||||
OsdVertexDescriptor _vdesc;
|
||||
|
||||
GLuint _currentVertexBuffer,
|
||||
_currentVaryingBuffer;
|
||||
|
@ -119,9 +119,9 @@ OsdGLSLTransformFeedbackComputeController::ApplyBilinearFaceVerticesKernel(
|
||||
|
||||
kernelBundle->ApplyBilinearFaceVerticesKernel(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetNumCurrentVertexElements(),
|
||||
context->GetVertexDescriptor().numVertexElements,
|
||||
context->GetCurrentVaryingBuffer(),
|
||||
context->GetNumCurrentVaryingElements(),
|
||||
context->GetVertexDescriptor().numVaryingElements,
|
||||
batch.GetVertexOffset(), batch.GetTableOffset(), batch.GetStart(), batch.GetEnd());
|
||||
}
|
||||
|
||||
@ -137,9 +137,9 @@ OsdGLSLTransformFeedbackComputeController::ApplyBilinearEdgeVerticesKernel(
|
||||
|
||||
kernelBundle->ApplyBilinearEdgeVerticesKernel(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetNumCurrentVertexElements(),
|
||||
context->GetVertexDescriptor().numVertexElements,
|
||||
context->GetCurrentVaryingBuffer(),
|
||||
context->GetNumCurrentVaryingElements(),
|
||||
context->GetVertexDescriptor().numVaryingElements,
|
||||
batch.GetVertexOffset(), batch.GetTableOffset(), batch.GetStart(), batch.GetEnd());
|
||||
}
|
||||
|
||||
@ -155,9 +155,9 @@ OsdGLSLTransformFeedbackComputeController::ApplyBilinearVertexVerticesKernel(
|
||||
|
||||
kernelBundle->ApplyBilinearVertexVerticesKernel(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetNumCurrentVertexElements(),
|
||||
context->GetVertexDescriptor().numVertexElements,
|
||||
context->GetCurrentVaryingBuffer(),
|
||||
context->GetNumCurrentVaryingElements(),
|
||||
context->GetVertexDescriptor().numVaryingElements,
|
||||
batch.GetVertexOffset(), batch.GetTableOffset(), batch.GetStart(), batch.GetEnd());
|
||||
}
|
||||
|
||||
@ -173,9 +173,9 @@ OsdGLSLTransformFeedbackComputeController::ApplyCatmarkFaceVerticesKernel(
|
||||
|
||||
kernelBundle->ApplyCatmarkFaceVerticesKernel(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetNumCurrentVertexElements(),
|
||||
context->GetVertexDescriptor().numVertexElements,
|
||||
context->GetCurrentVaryingBuffer(),
|
||||
context->GetNumCurrentVaryingElements(),
|
||||
context->GetVertexDescriptor().numVaryingElements,
|
||||
batch.GetVertexOffset(), batch.GetTableOffset(), batch.GetStart(), batch.GetEnd());
|
||||
}
|
||||
|
||||
@ -193,9 +193,9 @@ OsdGLSLTransformFeedbackComputeController::ApplyCatmarkEdgeVerticesKernel(
|
||||
|
||||
kernelBundle->ApplyCatmarkEdgeVerticesKernel(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetNumCurrentVertexElements(),
|
||||
context->GetVertexDescriptor().numVertexElements,
|
||||
context->GetCurrentVaryingBuffer(),
|
||||
context->GetNumCurrentVaryingElements(),
|
||||
context->GetVertexDescriptor().numVaryingElements,
|
||||
batch.GetVertexOffset(), batch.GetTableOffset(), batch.GetStart(), batch.GetEnd());
|
||||
}
|
||||
|
||||
@ -211,9 +211,9 @@ OsdGLSLTransformFeedbackComputeController::ApplyCatmarkVertexVerticesKernelB(
|
||||
|
||||
kernelBundle->ApplyCatmarkVertexVerticesKernelB(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetNumCurrentVertexElements(),
|
||||
context->GetVertexDescriptor().numVertexElements,
|
||||
context->GetCurrentVaryingBuffer(),
|
||||
context->GetNumCurrentVaryingElements(),
|
||||
context->GetVertexDescriptor().numVaryingElements,
|
||||
batch.GetVertexOffset(), batch.GetTableOffset(), batch.GetStart(), batch.GetEnd());
|
||||
}
|
||||
|
||||
@ -229,9 +229,9 @@ OsdGLSLTransformFeedbackComputeController::ApplyCatmarkVertexVerticesKernelA1(
|
||||
|
||||
kernelBundle->ApplyCatmarkVertexVerticesKernelA(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetNumCurrentVertexElements(),
|
||||
context->GetVertexDescriptor().numVertexElements,
|
||||
context->GetCurrentVaryingBuffer(),
|
||||
context->GetNumCurrentVaryingElements(),
|
||||
context->GetVertexDescriptor().numVaryingElements,
|
||||
batch.GetVertexOffset(), batch.GetTableOffset(), batch.GetStart(), batch.GetEnd(), false);
|
||||
}
|
||||
|
||||
@ -247,9 +247,9 @@ OsdGLSLTransformFeedbackComputeController::ApplyCatmarkVertexVerticesKernelA2(
|
||||
|
||||
kernelBundle->ApplyCatmarkVertexVerticesKernelA(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetNumCurrentVertexElements(),
|
||||
context->GetVertexDescriptor().numVertexElements,
|
||||
context->GetCurrentVaryingBuffer(),
|
||||
context->GetNumCurrentVaryingElements(),
|
||||
context->GetVertexDescriptor().numVaryingElements,
|
||||
batch.GetVertexOffset(), batch.GetTableOffset(), batch.GetStart(), batch.GetEnd(), true);
|
||||
}
|
||||
|
||||
@ -265,9 +265,9 @@ OsdGLSLTransformFeedbackComputeController::ApplyLoopEdgeVerticesKernel(
|
||||
|
||||
kernelBundle->ApplyLoopEdgeVerticesKernel(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetNumCurrentVertexElements(),
|
||||
context->GetVertexDescriptor().numVertexElements,
|
||||
context->GetCurrentVaryingBuffer(),
|
||||
context->GetNumCurrentVaryingElements(),
|
||||
context->GetVertexDescriptor().numVaryingElements,
|
||||
batch.GetVertexOffset(), batch.GetTableOffset(), batch.GetStart(), batch.GetEnd());
|
||||
}
|
||||
|
||||
@ -283,9 +283,9 @@ OsdGLSLTransformFeedbackComputeController::ApplyLoopVertexVerticesKernelB(
|
||||
|
||||
kernelBundle->ApplyLoopVertexVerticesKernelB(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetNumCurrentVertexElements(),
|
||||
context->GetVertexDescriptor().numVertexElements,
|
||||
context->GetCurrentVaryingBuffer(),
|
||||
context->GetNumCurrentVaryingElements(),
|
||||
context->GetVertexDescriptor().numVaryingElements,
|
||||
batch.GetVertexOffset(), batch.GetTableOffset(), batch.GetStart(), batch.GetEnd());
|
||||
}
|
||||
|
||||
@ -301,9 +301,9 @@ OsdGLSLTransformFeedbackComputeController::ApplyLoopVertexVerticesKernelA1(
|
||||
|
||||
kernelBundle->ApplyLoopVertexVerticesKernelA(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetNumCurrentVertexElements(),
|
||||
context->GetVertexDescriptor().numVertexElements,
|
||||
context->GetCurrentVaryingBuffer(),
|
||||
context->GetNumCurrentVaryingElements(),
|
||||
context->GetVertexDescriptor().numVaryingElements,
|
||||
batch.GetVertexOffset(), batch.GetTableOffset(), batch.GetStart(), batch.GetEnd(), false);
|
||||
}
|
||||
|
||||
@ -319,9 +319,9 @@ OsdGLSLTransformFeedbackComputeController::ApplyLoopVertexVerticesKernelA2(
|
||||
|
||||
kernelBundle->ApplyLoopVertexVerticesKernelA(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetNumCurrentVertexElements(),
|
||||
context->GetVertexDescriptor().numVertexElements,
|
||||
context->GetCurrentVaryingBuffer(),
|
||||
context->GetNumCurrentVaryingElements(),
|
||||
context->GetVertexDescriptor().numVaryingElements,
|
||||
batch.GetVertexOffset(), batch.GetTableOffset(), batch.GetStart(), batch.GetEnd(), true);
|
||||
}
|
||||
|
||||
@ -346,9 +346,9 @@ OsdGLSLTransformFeedbackComputeController::ApplyVertexEdits(
|
||||
if (edit->GetOperation() == FarVertexEdit::Add) {
|
||||
kernelBundle->ApplyEditAdd(
|
||||
context->GetCurrentVertexBuffer(),
|
||||
context->GetNumCurrentVertexElements(),
|
||||
context->GetVertexDescriptor().numVertexElements,
|
||||
context->GetCurrentVaryingBuffer(),
|
||||
context->GetNumCurrentVaryingElements(),
|
||||
context->GetVertexDescriptor().numVaryingElements,
|
||||
primvarOffset, primvarWidth,
|
||||
batch.GetVertexOffset(), batch.GetTableOffset(), batch.GetStart(), batch.GetEnd());
|
||||
} else {
|
||||
|
@ -108,8 +108,8 @@ OsdGLSLTransformFeedbackKernelBundle::Compile(int numVertexElements, int numVary
|
||||
|
||||
assert(numVertexElements >= 3); // at least xyz required (for performance reason)
|
||||
|
||||
_numVertexElements = numVertexElements;
|
||||
_numVaryingElements = numVaryingElements;
|
||||
_vdesc.Set(numVertexElements, numVaryingElements);
|
||||
|
||||
_program = glCreateProgram();
|
||||
|
||||
GLuint shader = glCreateShader(GL_VERTEX_SHADER);
|
||||
|
@ -76,156 +76,160 @@
|
||||
#include "../version.h"
|
||||
#include "../osd/nonCopyable.h"
|
||||
#include "../osd/vertex.h"
|
||||
#include "../osd/vertexDescriptor.h"
|
||||
#include "../far/subdivisionTables.h"
|
||||
|
||||
namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
class OsdGLSLTransformFeedbackKernelBundle
|
||||
: OsdNonCopyable<OsdGLSLTransformFeedbackKernelBundle> {
|
||||
public:
|
||||
OsdGLSLTransformFeedbackKernelBundle();
|
||||
~OsdGLSLTransformFeedbackKernelBundle();
|
||||
class OsdGLSLTransformFeedbackKernelBundle : OsdNonCopyable<OsdGLSLTransformFeedbackKernelBundle> {
|
||||
public:
|
||||
/// Constructor
|
||||
OsdGLSLTransformFeedbackKernelBundle();
|
||||
|
||||
~OsdGLSLTransformFeedbackKernelBundle();
|
||||
|
||||
bool Compile(int numVertexElements, int numVaryingElements);
|
||||
bool Compile(int numVertexElements, int numVaryingElements);
|
||||
|
||||
void ApplyBilinearFaceVerticesKernel(
|
||||
GLuint vertexBuffer, int numVertexElements,
|
||||
GLuint varyingBuffer, int numVaryingElements,
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyBilinearFaceVerticesKernel(
|
||||
GLuint vertexBuffer, int numVertexElements,
|
||||
GLuint varyingBuffer, int numVaryingElements,
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void ApplyBilinearEdgeVerticesKernel(
|
||||
GLuint vertexBuffer, int numVertexElements,
|
||||
GLuint varyingBuffer, int numVaryingElements,
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyBilinearEdgeVerticesKernel(
|
||||
GLuint vertexBuffer, int numVertexElements,
|
||||
GLuint varyingBuffer, int numVaryingElements,
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void ApplyBilinearVertexVerticesKernel(
|
||||
GLuint vertexBuffer, int numVertexElements,
|
||||
GLuint varyingBuffer, int numVaryingElements,
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyBilinearVertexVerticesKernel(
|
||||
GLuint vertexBuffer, int numVertexElements,
|
||||
GLuint varyingBuffer, int numVaryingElements,
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void ApplyCatmarkFaceVerticesKernel(
|
||||
GLuint vertexBuffer, int numVertexElements,
|
||||
GLuint varyingBuffer, int numVaryingElements,
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyCatmarkFaceVerticesKernel(
|
||||
GLuint vertexBuffer, int numVertexElements,
|
||||
GLuint varyingBuffer, int numVaryingElements,
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void ApplyCatmarkEdgeVerticesKernel(
|
||||
GLuint vertexBuffer, int numVertexElements,
|
||||
GLuint varyingBuffer, int numVaryingElements,
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyCatmarkEdgeVerticesKernel(
|
||||
GLuint vertexBuffer, int numVertexElements,
|
||||
GLuint varyingBuffer, int numVaryingElements,
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void ApplyCatmarkVertexVerticesKernelB(
|
||||
GLuint vertexBuffer, int numVertexElements,
|
||||
GLuint varyingBuffer, int numVaryingElements,
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyCatmarkVertexVerticesKernelB(
|
||||
GLuint vertexBuffer, int numVertexElements,
|
||||
GLuint varyingBuffer, int numVaryingElements,
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void ApplyCatmarkVertexVerticesKernelA(
|
||||
GLuint vertexBuffer, int numVertexElements,
|
||||
GLuint varyingBuffer, int numVaryingElements,
|
||||
int vertexOffset, int tableOffset, int start, int end, bool pass);
|
||||
void ApplyCatmarkVertexVerticesKernelA(
|
||||
GLuint vertexBuffer, int numVertexElements,
|
||||
GLuint varyingBuffer, int numVaryingElements,
|
||||
int vertexOffset, int tableOffset, int start, int end, bool pass);
|
||||
|
||||
void ApplyLoopEdgeVerticesKernel(
|
||||
GLuint vertexBuffer, int numVertexElements,
|
||||
GLuint varyingBuffer, int numVaryingElements,
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyLoopEdgeVerticesKernel(
|
||||
GLuint vertexBuffer, int numVertexElements,
|
||||
GLuint varyingBuffer, int numVaryingElements,
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void ApplyLoopVertexVerticesKernelB(
|
||||
GLuint vertexBuffer, int numVertexElements,
|
||||
GLuint varyingBuffer, int numVaryingElements,
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyLoopVertexVerticesKernelB(
|
||||
GLuint vertexBuffer, int numVertexElements,
|
||||
GLuint varyingBuffer, int numVaryingElements,
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void ApplyLoopVertexVerticesKernelA(
|
||||
GLuint vertexBuffer, int numVertexElements,
|
||||
GLuint varyingBuffer, int numVaryingElements,
|
||||
int vertexOffset, int tableOffset, int start, int end, bool pass);
|
||||
void ApplyLoopVertexVerticesKernelA(
|
||||
GLuint vertexBuffer, int numVertexElements,
|
||||
GLuint varyingBuffer, int numVaryingElements,
|
||||
int vertexOffset, int tableOffset, int start, int end, bool pass);
|
||||
|
||||
void ApplyEditAdd(
|
||||
GLuint vertexBuffer, int numVertexElements,
|
||||
GLuint varyingBuffer, int numVaryingElements,
|
||||
int primvarOffset, int primvarWidth,
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
void ApplyEditAdd(
|
||||
GLuint vertexBuffer, int numVertexElements,
|
||||
GLuint varyingBuffer, int numVaryingElements,
|
||||
int primvarOffset, int primvarWidth,
|
||||
int vertexOffset, int tableOffset, int start, int end);
|
||||
|
||||
void UseProgram() const;
|
||||
void UseProgram() const;
|
||||
|
||||
GLuint GetTableUniformLocation(int tableIndex) const {
|
||||
return _uniformTables[tableIndex];
|
||||
}
|
||||
GLuint GetVertexUniformLocation() const {
|
||||
return _uniformVertexBuffer;
|
||||
}
|
||||
GLuint GetVaryingUniformLocation() const {
|
||||
return _uniformVaryingBuffer;
|
||||
}
|
||||
GLuint GetEditIndicesUniformLocation() const {
|
||||
return _uniformEditIndices;
|
||||
}
|
||||
GLuint GetEditValuesUniformLocation() const {
|
||||
return _uniformEditValues;
|
||||
}
|
||||
GLuint GetVertexBufferImageUniformLocation() const {
|
||||
return _uniformVertexBufferImage;
|
||||
GLuint GetTableUniformLocation(int tableIndex) const {
|
||||
return _uniformTables[tableIndex];
|
||||
}
|
||||
GLuint GetVertexUniformLocation() const {
|
||||
return _uniformVertexBuffer;
|
||||
}
|
||||
GLuint GetVaryingUniformLocation() const {
|
||||
return _uniformVaryingBuffer;
|
||||
}
|
||||
GLuint GetEditIndicesUniformLocation() const {
|
||||
return _uniformEditIndices;
|
||||
}
|
||||
GLuint GetEditValuesUniformLocation() const {
|
||||
return _uniformEditValues;
|
||||
}
|
||||
GLuint GetVertexBufferImageUniformLocation() const {
|
||||
return _uniformVertexBufferImage;
|
||||
}
|
||||
|
||||
struct Match {
|
||||
|
||||
/// Constructor
|
||||
Match(int numVertexElements, int numVaryingElements)
|
||||
: vdesc(numVertexElements, numVaryingElements) {
|
||||
}
|
||||
|
||||
struct Match {
|
||||
Match(int numVertexElements, int numVaryingElements) :
|
||||
_numVertexElements(numVertexElements),
|
||||
_numVaryingElements(numVaryingElements) {}
|
||||
bool operator() (const OsdGLSLTransformFeedbackKernelBundle *kernel) {
|
||||
return (kernel->_numVertexElements == _numVertexElements
|
||||
&& kernel->_numVaryingElements == _numVaryingElements);
|
||||
}
|
||||
int _numVertexElements, _numVaryingElements;
|
||||
};
|
||||
bool operator() (OsdGLSLTransformFeedbackKernelBundle const *kernel) {
|
||||
return vdesc == kernel->_vdesc;
|
||||
}
|
||||
|
||||
friend struct Match;
|
||||
|
||||
protected:
|
||||
void transformGpuBufferData(
|
||||
GLuint vertexBuffer, int numVertexElements,
|
||||
GLuint varyingBuffer, int numVaryingElements,
|
||||
int vertexOffset, int tableOffset, int start, int end) const;
|
||||
|
||||
GLuint _program;
|
||||
|
||||
// uniform locations
|
||||
GLuint _uniformTables[FarSubdivisionTables<OsdVertex>::TABLE_TYPES_COUNT];
|
||||
GLuint _uniformVertexPass;
|
||||
GLuint _uniformVertexOffset;
|
||||
GLuint _uniformTableOffset;
|
||||
GLuint _uniformIndexStart;
|
||||
|
||||
GLuint _uniformVertexBuffer;
|
||||
GLuint _uniformVaryingBuffer;
|
||||
|
||||
GLuint _uniformEditPrimVarOffset;
|
||||
GLuint _uniformEditPrimVarWidth;
|
||||
|
||||
GLuint _uniformEditIndices;
|
||||
GLuint _uniformEditValues;
|
||||
GLuint _uniformVertexBufferImage;
|
||||
|
||||
// subroutines
|
||||
// general face-vertex kernel (all schemes)
|
||||
GLuint _subComputeFace;
|
||||
// edge-vertex kernel (catmark + loop schemes)
|
||||
GLuint _subComputeEdge;
|
||||
// edge-vertex kernel (bilinear scheme)
|
||||
GLuint _subComputeBilinearEdge;
|
||||
// vertex-vertex kernel (bilinear scheme)
|
||||
GLuint _subComputeVertex;
|
||||
// vertex-vertex kernel A (catmark + loop schemes)
|
||||
GLuint _subComputeVertexA;
|
||||
// vertex-vertex kernel B (catmark scheme)
|
||||
GLuint _subComputeCatmarkVertexB;
|
||||
// vertex-vertex kernel B (loop scheme)
|
||||
GLuint _subComputeLoopVertexB;
|
||||
// hedit kernel (add)
|
||||
GLuint _subEditAdd;
|
||||
|
||||
int _numVertexElements,
|
||||
_numVaryingElements;
|
||||
OsdVertexDescriptor vdesc;
|
||||
};
|
||||
|
||||
friend struct Match;
|
||||
|
||||
protected:
|
||||
void transformGpuBufferData(
|
||||
GLuint vertexBuffer, int numVertexElements,
|
||||
GLuint varyingBuffer, int numVaryingElements,
|
||||
int vertexOffset, int tableOffset, int start, int end) const;
|
||||
|
||||
GLuint _program;
|
||||
|
||||
// uniform locations
|
||||
GLuint _uniformTables[FarSubdivisionTables<OsdVertex>::TABLE_TYPES_COUNT];
|
||||
GLuint _uniformVertexPass;
|
||||
GLuint _uniformVertexOffset;
|
||||
GLuint _uniformTableOffset;
|
||||
GLuint _uniformIndexStart;
|
||||
|
||||
GLuint _uniformVertexBuffer;
|
||||
GLuint _uniformVaryingBuffer;
|
||||
|
||||
GLuint _uniformEditPrimVarOffset;
|
||||
GLuint _uniformEditPrimVarWidth;
|
||||
|
||||
GLuint _uniformEditIndices;
|
||||
GLuint _uniformEditValues;
|
||||
GLuint _uniformVertexBufferImage;
|
||||
|
||||
// subroutines
|
||||
|
||||
GLuint _subComputeFace; // general face-vertex kernel (all schemes)
|
||||
|
||||
GLuint _subComputeEdge; // edge-vertex kernel (catmark + loop schemes)
|
||||
|
||||
GLuint _subComputeBilinearEdge; // edge-vertex kernel (bilinear scheme)
|
||||
|
||||
GLuint _subComputeVertex; // vertex-vertex kernel (bilinear scheme)
|
||||
|
||||
GLuint _subComputeVertexA; // vertex-vertex kernel A (catmark + loop schemes)
|
||||
|
||||
GLuint _subComputeCatmarkVertexB;// vertex-vertex kernel B (catmark scheme)
|
||||
|
||||
GLuint _subComputeLoopVertexB; // vertex-vertex kernel B (loop scheme)
|
||||
|
||||
GLuint _subEditAdd; // hedit kernel (add)
|
||||
|
||||
OsdVertexDescriptor _vdesc;
|
||||
};
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
using namespace OPENSUBDIV_VERSION;
|
||||
|
||||
|
@ -102,15 +102,12 @@ void vs_main_patches( in InputVertex input,
|
||||
// Patches.HullRegular
|
||||
//----------------------------------------------------------
|
||||
|
||||
Buffer<int> g_patchLevelBuffer : register( t3 );
|
||||
OSD_DECLARE_PTEX_INDICES_BUFFER;
|
||||
|
||||
HS_CONSTANT_FUNC_OUT HSConstFunc(
|
||||
InputPatch<HullVertex, 12> patch,
|
||||
uint primitiveID : SV_PrimitiveID)
|
||||
{
|
||||
HS_CONSTANT_FUNC_OUT output;
|
||||
int patchLevel = g_patchLevelBuffer[primitiveID + LevelBase];
|
||||
int patchLevel = GetPatchLevel(primitiveID);
|
||||
|
||||
OSD_PATCH_CULL(12);
|
||||
|
||||
@ -169,7 +166,7 @@ HullVertex hs_main_patches(
|
||||
HullVertex output;
|
||||
output.position = float4(pos, 1.0);
|
||||
|
||||
int patchLevel = g_patchLevelBuffer[primitiveID + LevelBase];
|
||||
int patchLevel = GetPatchLevel(primitiveID);
|
||||
// +0.5 to avoid interpolation error of integer value
|
||||
output.patchCoord = float4(0, 0,
|
||||
patchLevel+0.5,
|
||||
|
@ -281,15 +281,13 @@ void vs_main_patches( in InputVertex input,
|
||||
//----------------------------------------------------------
|
||||
|
||||
Buffer<int> g_QuadOffsetBuffer : register( t2 );
|
||||
Buffer<int> g_patchLevelBuffer : register( t3 );
|
||||
OSD_DECLARE_PTEX_INDICES_BUFFER;
|
||||
|
||||
HS_CONSTANT_FUNC_OUT HSConstFunc(
|
||||
InputPatch<GregHullVertex, 4> patch,
|
||||
uint primitiveID : SV_PrimitiveID)
|
||||
{
|
||||
HS_CONSTANT_FUNC_OUT output;
|
||||
int patchLevel = g_patchLevelBuffer[primitiveID + LevelBase];
|
||||
int patchLevel = GetPatchLevel(primitiveID);
|
||||
|
||||
OSD_PATCH_CULL(4);
|
||||
|
||||
@ -450,7 +448,7 @@ GregDomainVertex hs_main_patches(
|
||||
output.Fp = Fp;
|
||||
output.Fm = Fm;
|
||||
|
||||
int patchLevel = g_patchLevelBuffer[primitiveID + LevelBase];
|
||||
int patchLevel = GetPatchLevel(primitiveID);
|
||||
output.patchCoord = float4(0, 0,
|
||||
patchLevel+0.5f,
|
||||
primitiveID+LevelBase+0.5f);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user